public VariableGraphic customBodyGraphic; // not saved public override void ExposeData() { base.ExposeData(); Scribe_Values.Look(ref state, "zstate"); Scribe_Values.Look(ref raging, "raging"); Scribe_Values.Look(ref wanderDestination, "wanderDestination"); Scribe_Values.Look(ref rubbleTicks, "rubbleTicks"); Scribe_Values.Look(ref rubbleCounter, "rubbleCounter"); Scribe_Collections.Look(ref rubbles, "rubbles", LookMode.Deep); Scribe_Values.Look(ref wasColonist, "wasColonist"); if (Scribe.mode == LoadSaveMode.PostLoadInit) { // fix for old zombies not having correct leaner // if ((Drawer.leaner is ZombieLeaner) == false) { Drawer.leaner = new ZombieLeaner(this); } ZombieGenerator.AssignNewCustomGraphics(this); } if (Scribe.mode == LoadSaveMode.ResolvingCrossRefs) { var idx = ageTracker.CurLifeStageIndex; // trigger calculations } }
public void DequeuAndSpawnZombies() { var result = Tools.generator.TryGetNextGeneratedZombie(map); if (result == null) { return; } if (ZombieCount() >= GetMaxZombieCount()) { return; } if (Tools.IsValidSpawnLocation(result.cell, result.map) == false) { return; } var existingZombies = result.map.thingGrid.ThingsListAtFast(result.cell).OfType <Zombie>(); if (existingZombies.Any(zombie => zombie.state == ZombieState.Emerging)) { Tools.generator.RequeueZombie(result); return; } ZombieGenerator.FinalizeZombieGeneration(result.zombie); GenPlace.TryPlaceThing(result.zombie, result.cell, result.map, ThingPlaceMode.Direct); result.map.GetGrid().ChangeZombieCount(result.cell, 1); }
public void ConvertToZombie() { var pos = pawn.Position; var map = pawn.Map; var rot = pawn.Rotation; var zombie = ZombieGenerator.GeneratePawn(); zombie.Name = pawn.Name; zombie.gender = pawn.gender; var apparelToTransfer = new List <Apparel>(); pawn.apparel.WornApparelInDrawOrder.Do(apparel => { Apparel newApparel; if (pawn.apparel.TryDrop(apparel, out newApparel)) { apparelToTransfer.Add(newApparel); } }); zombie.ageTracker.AgeBiologicalTicks = pawn.ageTracker.AgeBiologicalTicks; zombie.ageTracker.AgeChronologicalTicks = pawn.ageTracker.AgeChronologicalTicks; zombie.ageTracker.BirthAbsTicks = pawn.ageTracker.BirthAbsTicks; zombie.story.childhood = pawn.story.childhood; zombie.story.adulthood = pawn.story.adulthood; zombie.story.melanin = pawn.story.melanin; zombie.story.crownType = pawn.story.crownType; zombie.story.hairDef = pawn.story.hairDef; zombie.story.bodyType = pawn.story.bodyType; var zTweener = Traverse.Create(zombie.Drawer.tweener); var pTweener = Traverse.Create(pawn.Drawer.tweener); zTweener.Field("tweenedPos").SetValue(pTweener.Field("tweenedPos").GetValue()); zTweener.Field("lastDrawFrame").SetValue(pTweener.Field("lastDrawFrame").GetValue()); zTweener.Field("lastTickSpringPos").SetValue(pTweener.Field("lastTickSpringPos").GetValue()); ZombieGenerator.AssignNewCustomGraphics(zombie); ZombieGenerator.FinalizeZombieGeneration(zombie); GenPlace.TryPlaceThing(zombie, pos, map, ThingPlaceMode.Direct, null); map.GetGrid().ChangeZombieCount(pos, 1); pawn.Kill(null); pawn.Corpse.Destroy(); apparelToTransfer.ForEach(apparel => zombie.apparel.Wear(apparel)); zombie.Rotation = rot; zombie.rubbleCounter = Constants.RUBBLE_AMOUNT; zombie.state = ZombieState.Wandering; zombie.wasColonist = true; string text = "ColonistBecameAZombieDesc".Translate(new object[] { zombie.NameStringShort }); Find.LetterStack.ReceiveLetter("ColonistBecameAZombieLabel".Translate(), text, LetterDefOf.BadUrgent, zombie); }
private void SpawnZombie(ZombieGenerator.ZombieType type, bool appearDirectly) { ZombieGenerator.SpawnZombie(UI.MouseCell(), Find.CurrentMap, type, (zombie) => { if (appearDirectly) { zombie.rubbleCounter = Constants.RUBBLE_AMOUNT; zombie.state = ZombieState.Wandering; } zombie.Rotation = Rot4.South; var tickManager = Find.CurrentMap.GetComponent <TickManager>(); tickManager.allZombiesCached.Add(zombie); }); }
public void IncreaseZombiePopulation() { if (GenDate.DaysPassedFloat < ZombieSettings.Values.daysBeforeZombiesCome) { return; } if (ZombieSettings.Values.spawnWhenType == SpawnWhenType.InEventsOnly) { return; } if (populationSpawnCounter-- < 0) { populationSpawnCounter = (int)GenMath.LerpDouble(0, 1000, 300, 20, Math.Max(100, Math.Min(1000, currentColonyPoints))); if (CanHaveMoreZombies()) { switch (ZombieSettings.Values.spawnHowType) { case SpawnHowType.AllOverTheMap: { var cell = CellFinderLoose.RandomCellWith(Tools.ZombieSpawnLocator(map), map, 4); if (cell.IsValid) { ZombieGenerator.SpawnZombie(cell, map, ZombieGenerator.ZombieType.Random, (zombie) => { allZombiesCached.Add(zombie); }); } return; } case SpawnHowType.FromTheEdges: { if (CellFinder.TryFindRandomEdgeCellWith(Tools.ZombieSpawnLocator(map), map, CellFinder.EdgeRoadChance_Neutral, out var cell)) { ZombieGenerator.SpawnZombie(cell, map, ZombieGenerator.ZombieType.Random, (zombie) => { allZombiesCached.Add(zombie); }); } return; } default: { Log.Error("Unknown spawn type " + ZombieSettings.Values.spawnHowType); return; } } } } }
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 VariableGraphic customBodyGraphic; // not saved public override void ExposeData() { base.ExposeData(); Scribe_Values.Look(ref state, "zstate"); Scribe_Values.Look(ref wanderDestination, "wanderDestination"); Scribe_Values.Look(ref rubbleTicks, "rubbleTicks"); Scribe_Values.Look(ref rubbleCounter, "rubbleCounter"); Scribe_Collections.Look(ref rubbles, "rubbles", LookMode.Deep); Scribe_Values.Look(ref wasColonist, "wasColonist"); if (Scribe.mode == LoadSaveMode.PostLoadInit) { // fix for old zombies not having correct leaner if ((Drawer.leaner is ZombieLeaner) == false) { Drawer.leaner = new ZombieLeaner(this); } ZombieGenerator.AssignNewCustomGraphics(this); } }
public override void ExposeData() { base.ExposeData(); var wasColonist = wasMapPawnBefore; Scribe_Values.Look(ref state, "zstate"); Scribe_Values.Look(ref raging, "raging"); Scribe_Values.Look(ref wanderDestination, "wanderDestination"); Scribe_Values.Look(ref rubbleTicks, "rubbleTicks"); Scribe_Values.Look(ref rubbleCounter, "rubbleCounter"); Scribe_Collections.Look(ref rubbles, "rubbles", LookMode.Deep); Scribe_Values.Look(ref wasColonist, "wasColonist"); Scribe_Values.Look(ref wasMapPawnBefore, "wasMapPawnBefore"); Scribe_Values.Look(ref bombWillGoOff, "bombWillGoOff"); Scribe_Values.Look(ref bombTickingInterval, "bombTickingInterval"); Scribe_Values.Look(ref isToxicSplasher, "toxicSplasher"); Scribe_Values.Look(ref isMiner, "isMiner"); Scribe_Values.Look(ref hasTankyShield, "tankyShield"); Scribe_Values.Look(ref hasTankyHelmet, "tankyHelmet"); Scribe_Values.Look(ref hasTankySuit, "tankySuit"); Scribe_Values.Look(ref healCounter, "healCounter"); wasMapPawnBefore |= wasColonist; if (Scribe.mode == LoadSaveMode.PostLoadInit) { UpgradeOldZombieData(); ZombieGenerator.FixGlowingEyeOffset(this); if (ZombieSettings.Values.useCustomTextures) { needsGraphics = true; // make custom textures in renderer } } if (Scribe.mode == LoadSaveMode.ResolvingCrossRefs) { var idx = ageTracker.CurLifeStageIndex; // trigger calculations } }
public void DequeuAndSpawnZombies() { if (dequeedSpawnCounter-- < 0) { dequeedSpawnCounter = Rand.Range(10, 51); var result = Tools.generator.TryGetNextGeneratedZombie(map); if (result == null) { return; } if (result.isEvent == false && ZombieCount() >= GetMaxZombieCount()) { Tools.generator.RequeueZombie(result); return; } // TODO: if zombie cannot spawn at location, we are wasting it here. // to solve this, we need to find a better location and only if we find // none, we can discard it // if (Tools.IsValidSpawnLocation(result.cell, result.map) == false) { return; } var existingZombies = result.map.thingGrid.ThingsListAtFast(result.cell).OfType <Zombie>(); if (existingZombies.Any(zombie => zombie.state == ZombieState.Emerging)) { Tools.generator.RequeueZombie(result); return; } ZombieGenerator.FinalizeZombieGeneration(result.zombie); GenPlace.TryPlaceThing(result.zombie, result.cell, result.map, ThingPlaceMode.Direct); } }
public static void ConvertToZombie(ThingWithComps thing, bool force = false) { var pawn = thing is Corpse corpse ? corpse.InnerPawn : thing as Pawn; if (pawn == null || pawn.RaceProps.Humanlike == false) { return; } // clear zombie hediffs to avoid triggering this convert method again // var pawnName = pawn.Name; if (force == false && (pawn.health == null || pawnName == emptyName)) { return; } pawn.Name = emptyName; var pos = thing is IThingHolder?ThingOwnerUtility.GetRootPosition(thing as IThingHolder) : thing.Position; var map = thing is IThingHolder?ThingOwnerUtility.GetRootMap(thing as IThingHolder) : thing.Map; var tickManager = map.GetComponent <TickManager>(); var rot = pawn.Rotation; var wasInGround = thing.Map == null; if (map == null && thing.Destroyed == false) { thing.Destroy(); return; } var it = ZombieGenerator.SpawnZombieIterativ(pos, map, ZombieGenerator.ZombieType.Normal, (Zombie zombie) => { zombie.Name = pawnName; zombie.gender = pawn.gender; if (zombie.ageTracker != null && pawn.ageTracker != null) { zombie.ageTracker.AgeBiologicalTicks = pawn.ageTracker.AgeBiologicalTicks; zombie.ageTracker.AgeChronologicalTicks = pawn.ageTracker.AgeChronologicalTicks; zombie.ageTracker.BirthAbsTicks = pawn.ageTracker.BirthAbsTicks; } if (zombie.story != null && pawn.story != null) { zombie.story.childhood = pawn.story.childhood; zombie.story.adulthood = pawn.story.adulthood; zombie.story.melanin = pawn.story.melanin; zombie.story.crownType = pawn.story.crownType; zombie.story.hairDef = pawn.story.hairDef; zombie.story.bodyType = pawn.story.bodyType; } // redo because we changed stuff if (ZombieSettings.Values.useCustomTextures) { var it2 = ZombieGenerator.AssignNewGraphics(zombie); while (it2.MoveNext()) { ; } } var zTweener = Traverse.Create(zombie.Drawer.tweener); var pTweener = Traverse.Create(pawn.Drawer.tweener); new[] { "tweenedPos", "lastDrawFrame", "lastTickSpringPos" } .Do(field => zTweener.Field(field).SetValue(pTweener.Field(field).GetValue())); zombie.Rotation = rot; if (wasInGround == false) { zombie.rubbleCounter = Constants.RUBBLE_AMOUNT; zombie.state = ZombieState.Wandering; } zombie.wasMapPawnBefore = true; if (zombie.apparel != null && pawn.apparel != null) { zombie.apparel.DestroyAll(); pawn.apparel.WornApparel.ForEach(apparel => { if (pawn.apparel.TryDrop(apparel, out var newApparel)) { zombie.apparel.Wear(newApparel); newApparel.SetForbidden(false, false); newApparel.HitPoints = 1; var compQuality = newApparel.TryGetComp <CompQuality>(); if (compQuality != null) { compQuality.SetQuality(QualityCategory.Awful, ArtGenerationContext.Colony); } zombie.apparel.Notify_ApparelAdded(newApparel); } }); } if (thing is Corpse) { if (thing.Destroyed == false) { thing.Destroy(); } } else { var previousProgramState = Current.ProgramState; Current.ProgramState = ProgramState.Entry; pawn.Kill(null); Current.ProgramState = previousProgramState; Find.ColonistBar.MarkColonistsDirty(); if (pawn.Corpse != null && pawn.Corpse.Destroyed == false) { pawn.Corpse.Destroy(); } } tickManager.allZombiesCached.Add(zombie); var label = "BecameAZombieLabel".Translate(); var text = "BecameAZombieDesc".SafeTranslate(new object[] { pawnName.ToStringShort }); Find.LetterStack.ReceiveLetter(label, text, LetterDefOf.ThreatBig, zombie); }); while (it.MoveNext()) { ; } }