void RepositionColonists() { var checkInterval = 15; var radius = 7f; var radiusSquared = (int)(radius * radius); map.mapPawns .FreeHumanlikesSpawnedOfFaction(Faction.OfPlayer) .Where(colonist => colonist.IsHashIntervalTick(checkInterval) && RepositionCondition(colonist)) .Do(pawn => { var pos = pawn.Position; var zombiesNearby = Tools.GetCircle(radius).Select(vec => pos + vec) .Where(vec => vec.InBounds(map) && avoidGrid.GetCosts()[vec.x + vec.z * map.Size.x] >= 3000) .SelectMany(vec => map.thingGrid.ThingsListAtFast(vec).OfType <Zombie>()) .Where(zombie => zombie.Downed == false); var maxDistance = 0; var safeDestination = IntVec3.Invalid; map.floodFiller.FloodFill(pos, delegate(IntVec3 vec) { if (!vec.Walkable(map)) { return(false); } if ((float)vec.DistanceToSquared(pos) > radiusSquared) { return(false); } if (map.thingGrid.ThingAt <Zombie>(vec)?.Downed ?? true == false) { return(false); } if (vec.GetEdifice(map) is Building_Door building_Door && !building_Door.CanPhysicallyPass(pawn)) { return(false); } return(!PawnUtility.AnyPawnBlockingPathAt(vec, pawn, true, false)); }, delegate(IntVec3 vec) { var distance = zombiesNearby.Select(zombie => (vec - zombie.Position).LengthHorizontalSquared).Sum(); if (distance > maxDistance) { maxDistance = distance; safeDestination = vec; } return(false); }); if (safeDestination.IsValid) { var newJob = new Job(JobDefOf.Goto, safeDestination) { playerForced = true }; pawn.jobs.StartJob(newJob, JobCondition.InterruptForced, null, false, true, null, null); } }); }
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 static Predicate <IntVec3> SpotValidator(Map map, Predicate <IntVec3> cellValidator) { return(cell => { var count = 0; var vecs = Tools.GetCircle(Constants.SPAWN_INCIDENT_RADIUS).ToList(); foreach (var vec in vecs) { if (cellValidator(cell + vec)) { if (++count >= Constants.MIN_ZOMBIE_SPAWN_CELL_COUNT) { break; } } } return count >= Constants.MIN_ZOMBIE_SPAWN_CELL_COUNT; }); }
public override bool TryExecute(IncidentParms parms) { if (GenDate.DaysPassedFloat < ZombieSettings.Values.daysBeforeZombiesCome) { return(false); } var map = (Map)parms.target; var zombieCount = (int)(zombieCountFactor * ZombieSettings.Values.baseNumberOfZombiesinEvent) + 1; zombieCount *= Math.Max(1, map.mapPawns.FreeColonists.Count()); var spotValidator = SpotValidator(map); IntVec3 spot = IntVec3.Invalid; string headline = ""; string text = ""; for (int counter = 1; counter <= 10; counter++) { if (ZombieSettings.Values.spawnHowType == SpawnHowType.AllOverTheMap) { RCellFinder.TryFindRandomSpotJustOutsideColony(Tools.CenterOfInterest(map), map, null, out spot, spotValidator); headline = "LetterLabelZombiesRisingNearYourBase".Translate(); text = "ZombiesRisingNearYourBase".Translate(); } else { RCellFinder.TryFindRandomPawnEntryCell(out spot, map, 0.5f, spotValidator); headline = "LetterLabelZombiesRising".Translate(); text = "ZombiesRising".Translate(); } if (spot.IsValid) { break; } } if (spot.IsValid == false) { return(false); } var cellValidator = Tools.ZombieSpawnLocator(map); while (zombieCount > 0) { Tools.GetCircle(Constants.SPAWN_INCIDENT_RADIUS) .Select(vec => spot + vec) .Where(vec => cellValidator(vec)) .InRandomOrder() .Take(zombieCount) .Do(cell => { Tools.generator.SpawnZombieAt(map, cell); zombieCount--; }); } var location = new GlobalTargetInfo(spot, map); Find.LetterStack.ReceiveLetter(headline, text, LetterDefOf.BadUrgent, location); SoundDef.Named("ZombiesRising").PlayOneShotOnCamera(null); return(true); }
public static bool TryExecute(Map map, int incidentSize) { var spotValidator = SpotValidator(map); var spot = IntVec3.Invalid; var headline = ""; var text = ""; for (var counter = 1; counter <= 10; counter++) { if (ZombieSettings.Values.spawnHowType == SpawnHowType.AllOverTheMap) { var tickManager = map.GetComponent <TickManager>(); var center = tickManager != null ? tickManager.centerOfInterest : IntVec3.Invalid; if (center.IsValid == false) { center = Tools.CenterOfInterest(map); } RCellFinder.TryFindRandomSpotJustOutsideColony(center, map, null, out spot, spotValidator); headline = "LetterLabelZombiesRisingNearYourBase".Translate(); text = "ZombiesRisingNearYourBase".Translate(); } else { RCellFinder.TryFindRandomPawnEntryCell(out spot, map, 0.5f, spotValidator); headline = "LetterLabelZombiesRising".Translate(); text = "ZombiesRising".Translate(); } if (spot.IsValid) { break; } } if (spot.IsValid == false) { return(false); } var cellValidator = Tools.ZombieSpawnLocator(map, true); while (incidentSize > 0) { Tools.GetCircle(Constants.SPAWN_INCIDENT_RADIUS) .Select(vec => spot + vec) .Where(vec => cellValidator(vec)) .InRandomOrder() .Take(incidentSize) .Do(cell => { Tools.generator.SpawnZombieAt(map, cell, true); incidentSize--; }); } var location = new GlobalTargetInfo(spot, map); Find.LetterStack.ReceiveLetter(headline, text, LetterDefOf.BadUrgent, location); if (Constants.USE_SOUND) { SoundDef.Named("ZombiesRising").PlayOneShotOnCamera(null); } return(true); }