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()) { ; } }