示例#1
0
        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())
            {
                ;
            }
        }