Beispiel #1
0
        static IEnumerator SpawnEventProcess(Map map, int incidentSize, IntVec3 spot, Predicate <IntVec3> cellValidator, bool ignoreLimit)
        {
            var zombiesSpawning = 0;
            var counter         = 1;
            var tickManager     = map.GetComponent <TickManager>();

            while (incidentSize > 0 && (ignoreLimit || tickManager.CanHaveMoreZombies()) && counter <= 10)
            {
                var cells = Tools.GetCircle(Constants.SPAWN_INCIDENT_RADIUS)
                            .Select(vec => spot + vec)
                            .Where(vec => cellValidator(vec))
                            .InRandomOrder()
                            .Take(incidentSize)
                            .ToList();
                yield return(null);

                foreach (var cell in cells)
                {
                    ZombieGenerator.SpawnZombie(cell, map, ZombieGenerator.ZombieType.Random, (zombie) => { tickManager.allZombiesCached.Add(zombie); });
                    incidentSize--;
                    zombiesSpawning++;
                    yield return(null);
                }
                counter++;
            }

            if (zombiesSpawning > 3)
            {
                var headline = "LetterLabelZombiesRising".Translate();
                var text     = "ZombiesRising".Translate();
                if (ZombieSettings.Values.spawnHowType == SpawnHowType.AllOverTheMap)
                {
                    headline = "LetterLabelZombiesRisingNearYourBase".Translate();
                    text     = "ZombiesRisingNearYourBase".Translate();
                }

                var location = new GlobalTargetInfo(spot, map);
                Find.LetterStack.ReceiveLetter(headline, text, LetterDefOf.ThreatSmall, location);

                var isSubstantialZombieCount = zombiesSpawning > Tools.CapableColonists(map) * 4;
                if (isSubstantialZombieCount && Constants.USE_SOUND && Prefs.VolumeAmbient > 0f)
                {
                    SoundDef.Named("ZombiesRising").PlayOneShotOnCamera(null);
                }
            }
        }
        public int GetMaxZombieCount()
        {
            if (map == null || map.mapPawns == null)
            {
                return(0);
            }
            if (Constants.DEBUG_MAX_ZOMBIE_COUNT >= 0)
            {
                return(Constants.DEBUG_MAX_ZOMBIE_COUNT);
            }
            var colonists = Tools.CapableColonists(map);
            var perColonistZombieCount = GenMath.LerpDouble(0f, 4f, 5, 30, (float)Math.Min(4, Math.Sqrt(colonists)));
            var colonistMultiplier     = Math.Sqrt(colonists) * 2;
            var baseStrengthFactor     = GenMath.LerpDouble(0, 1000, 1f, 4f, Math.Min(1000, currentColonyPoints));
            var difficultyMultiplier   = Find.Storyteller.difficulty.threatScale;
            var count = (int)(perColonistZombieCount * colonistMultiplier * baseStrengthFactor * difficultyMultiplier);

            return(Math.Min(ZombieSettings.Values.maximumNumberOfZombies, count));
        }
        public static int ZombiesForNewIncident(Map map)
        {
            var tickManager = map.GetComponent <TickManager>();
            var info        = tickManager.incidentInfo;
            var ticksNow    = GenTicks.TicksAbs;

            ZRdebug.capableColonists        = Tools.CapableColonists(map);
            ZRdebug.daysBeforeZombies       = ZombieSettings.Values.daysBeforeZombiesCome;
            ZRdebug.totalColonistCount      = map.mapPawns.FreeHumanlikesSpawnedOfFaction(Faction.OfPlayer).Count();
            ZRdebug.minimumCapableColonists = (ZRdebug.totalColonistCount + 1) / 3;
            ZRdebug.daysPassed                 = GenDate.DaysPassedFloat;
            ZRdebug.spawnMode                  = ZombieSettings.Values.spawnWhenType.ToString();
            ZRdebug.storytellerDifficulty      = Find.Storyteller.difficulty.difficulty;
            ZRdebug.currentZombieCount         = tickManager.AllZombies().Count();
            ZRdebug.numberOfZombiesPerColonist = ZombieSettings.Values.baseNumberOfZombiesinEvent;
            ZRdebug.maxBaseLevelZombies        = tickManager.GetMaxZombieCount();
            ZRdebug.extendedCount              = 0;
            ZRdebug.maxNumberOfZombies         = ZombieSettings.Values.maximumNumberOfZombies;
            ZRdebug.maxAdditionalZombies       = 0;
            ZRdebug.calculatedZombies          = 0;
            ZRdebug.incidentSize               = 0;
            ZRdebug.rampUpDays                 = GenMath.LerpDouble(1, 5, 40, 0, Math.Max(1, ZRdebug.storytellerDifficulty));
            ZRdebug.scaleFactor                = Tools.Boxed(GenMath.LerpDouble(ZRdebug.daysBeforeZombies, ZRdebug.daysBeforeZombies + ZRdebug.rampUpDays, 0.2f, 1f, ZRdebug.daysPassed), 0.2f, 1f);
            ZRdebug.dayStretchFactor           = 0;
            ZRdebug.deltaDays                  = 0;
            ZRdebug.skipReason                 = "";

            // zombie free days
            if (ZRdebug.daysPassed <= ZRdebug.daysBeforeZombies)
            {
                ZRdebug.skipReason = "waiting for zombies";
                return(0);
            }

            // outside night period
            if (ZombieSettings.Values.spawnWhenType == SpawnWhenType.WhenDark)
            {
                var hour = GenLocalDate.HourOfDay(map);
                if (hour < 12)
                {
                    hour += 24;
                }

                if (hour < Constants.HOUR_START_OF_NIGHT || hour > Constants.HOUR_END_OF_NIGHT)
                {
                    ZRdebug.skipReason = "outside night period";
                    return(0);
                }
            }

            // too few capable colonists (only in difficulty lower than Intense)
            if (ZRdebug.storytellerDifficulty < DifficultyDefOf.Hard.difficulty)
            {
                if (ZRdebug.capableColonists <= ZRdebug.minimumCapableColonists)
                {
                    ZRdebug.skipReason = "too few capable colonists";
                    return(0);
                }
            }

            // not yet time for next incident
            if (ticksNow < info.NextIncident)
            {
                ZRdebug.skipReason = "wait " + (info.NextIncident - ticksNow).ToStringTicksToPeriod();
                return(0);
            }

            // too little new zombies
            if (Rand.Chance(1f / 24f) && Find.Storyteller.difficulty.allowBigThreats)
            {
                ZRdebug.extendedCount = ZRdebug.maxNumberOfZombies - ZRdebug.maxBaseLevelZombies;
                if (ZRdebug.extendedCount > 0)
                {
                    ZRdebug.extendedCount        = Rand.RangeInclusive(0, ZRdebug.extendedCount);
                    ZRdebug.maxBaseLevelZombies += ZRdebug.extendedCount;
                }
            }
            ZRdebug.maxAdditionalZombies = Math.Max(0, ZRdebug.maxBaseLevelZombies - ZRdebug.currentZombieCount);
            ZRdebug.calculatedZombies    = ZRdebug.capableColonists * ZRdebug.numberOfZombiesPerColonist;
            ZRdebug.incidentSize         = Math.Min(ZRdebug.maxAdditionalZombies, ZRdebug.calculatedZombies);
            if (ZRdebug.incidentSize == 0)
            {
                ZRdebug.skipReason = "empty incident";
                return(0);
            }

            // ramp it up
            ZRdebug.scaleFactor *= (0.75f + Rand.Value / 2f);
            ZRdebug.scaleFactor  = Tools.Boxed(ZRdebug.scaleFactor, 0f, 1f);
            ZRdebug.incidentSize = Math.Max(1, (int)(ZRdebug.incidentSize * ZRdebug.scaleFactor + 0.5f));

            // success
            ZRdebug.dayStretchFactor = 1f + ZRdebug.incidentSize / 150f;
            ZRdebug.deltaDays        = Rand.Range(1.5f * ZRdebug.dayStretchFactor, 4f * ZRdebug.dayStretchFactor);
            info.Update(ZRdebug.deltaDays);
            ZRdebug.skipReason = "-";
            return(ZRdebug.incidentSize);
        }
Beispiel #4
0
        public static bool ZombiesForNewIncident(TickManager tickManager)
        {
            var info = tickManager.incidentInfo;

            if (info == null)
            {
                return(false);
            }

            if (tickManager.incidentInfo == null)
            {
                tickManager.incidentInfo = new IncidentInfo();
            }
            if (tickManager.incidentInfo.parameters == null)
            {
                tickManager.incidentInfo.parameters = new IncidentParameters();
            }
            var parameters = tickManager.incidentInfo.parameters;

            parameters.capableColonists        = Tools.CapableColonists(tickManager.map);
            parameters.daysBeforeZombies       = ZombieSettings.Values.daysBeforeZombiesCome;
            parameters.totalColonistCount      = tickManager.map.mapPawns.FreeHumanlikesSpawnedOfFaction(Faction.OfPlayer).Count();
            parameters.minimumCapableColonists = (parameters.totalColonistCount + 1) / 3;
            parameters.daysPassed                 = GenDate.DaysPassedFloat;
            parameters.spawnMode                  = ZombieSettings.Values.spawnWhenType.ToString();
            parameters.storytellerDifficulty      = Tools.StoryTellerDifficulty;
            parameters.currentZombieCount         = tickManager.AllZombies().Count();
            parameters.numberOfZombiesPerColonist = ZombieSettings.Values.baseNumberOfZombiesinEvent;
            parameters.colonyMultiplier           = ZombieSettings.Values.colonyMultiplier;
            parameters.maxBaseLevelZombies        = tickManager.GetMaxZombieCount() + ZombieGenerator.ZombiesSpawning;
            parameters.extendedCount              = 0;
            parameters.maxNumberOfZombies         = ZombieSettings.Values.maximumNumberOfZombies;
            parameters.maxAdditionalZombies       = 0;
            parameters.calculatedZombies          = 0;
            parameters.incidentSize               = 0;
            parameters.rampUpDays                 = GenMath.LerpDouble(1, 5, 40, 0, Math.Max(1, Tools.StoryTellerDifficulty));
            //parameters.scaleFactor = Tools.Boxed(GenMath.LerpDouble(parameters.daysBeforeZombies, parameters.daysBeforeZombies + parameters.rampUpDays, 0.2f, 1f, GenDate.DaysPassedFloat), 0.2f, 1f);
            //parameters.daysStretched = 0;
            parameters.deltaDays  = 0;
            parameters.skipReason = "-";

            // zombie free days
            if (parameters.daysPassed <= parameters.daysBeforeZombies)
            {
                parameters.skipReason = "waiting for zombies";
                return(false);
            }

            // outside night period
            if (ZombieSettings.Values.spawnWhenType == SpawnWhenType.WhenDark)
            {
                var hour = GenLocalDate.HourOfDay(tickManager.map);
                if (hour < 12)
                {
                    hour += 24;
                }

                if (hour < Constants.HOUR_START_OF_NIGHT || hour > Constants.HOUR_END_OF_NIGHT)
                {
                    parameters.skipReason = "outside night period";
                    return(false);
                }
            }

            // too few capable colonists (only in difficulty lower than Intense)
            if (parameters.storytellerDifficulty < DifficultyDefOf.Rough.difficulty)
            {
                if (parameters.capableColonists < parameters.minimumCapableColonists)
                {
                    parameters.skipReason = "too few capable colonists";
                    return(false);
                }
            }

            if (parameters.daysStretched == 0)
            {
                var stretchFactor = 1f + parameters.incidentSize / 150f;
                parameters.daysStretched = Rand.Range(1.5f * stretchFactor, 4f * stretchFactor);
            }
            parameters.deltaDays = parameters.daysStretched + ZombieSettings.Values.extraDaysBetweenEvents;

            // not yet time for next incident
            var ticksNow          = GenTicks.TicksAbs;
            var ticksNextIncident = tickManager.incidentInfo.NextIncident();

            if (ticksNow < ticksNextIncident)
            {
                parameters.skipReason = "wait " + (ticksNextIncident - ticksNow).ToStringTicksToPeriod();
                return(false);
            }

            // too little new zombies
            if (Rand.Chance(1f / 24f) && Find.Storyteller.difficulty.allowBigThreats)
            {
                parameters.extendedCount = parameters.maxNumberOfZombies - parameters.maxBaseLevelZombies;
                if (parameters.extendedCount > 0)
                {
                    parameters.extendedCount        = Rand.RangeInclusive(0, parameters.extendedCount);
                    parameters.maxBaseLevelZombies += parameters.extendedCount;
                }
            }
            parameters.maxAdditionalZombies = Math.Max(0, parameters.maxBaseLevelZombies - parameters.currentZombieCount);
            parameters.calculatedZombies    = (int)(parameters.capableColonists * parameters.numberOfZombiesPerColonist * parameters.colonyMultiplier);
            parameters.incidentSize         = Math.Min(parameters.maxAdditionalZombies, parameters.calculatedZombies);
            if (parameters.incidentSize == 0)
            {
                parameters.skipReason = "empty incident";
                return(false);
            }

            // ramp it up
            if (parameters.scaleFactor == 0)
            {
                parameters.scaleFactor = Tools.Boxed(GenMath.LerpDouble(parameters.daysBeforeZombies, parameters.daysBeforeZombies + parameters.rampUpDays, 0.2f, 1f, GenDate.DaysPassedFloat), 0.2f, 1f);
            }
            parameters.scaleFactor *= (0.75f + Rand.Value / 2f);
            parameters.scaleFactor  = Tools.Boxed(parameters.scaleFactor, 0f, 1f);
            parameters.incidentSize = Math.Max(1, (int)(parameters.incidentSize * parameters.scaleFactor + 0.5f));

            // success
            var stretchFactor2 = 1f + parameters.incidentSize / 150f;

            parameters.daysStretched = Rand.Range(1.5f * stretchFactor2, 4f * stretchFactor2);
            parameters.deltaDays     = parameters.daysStretched + ZombieSettings.Values.extraDaysBetweenEvents;
            tickManager.incidentInfo.Update();
            return(true);
        }