Пример #1
0
        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
            }
        }
Пример #2
0
        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);
        }
Пример #4
0
        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);
            });
        }
Пример #5
0
        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;
                    }
                    }
                }
            }
        }
Пример #6
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);
                }
            }
        }
Пример #7
0
        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);
            }
        }
Пример #8
0
        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
            }
        }
Пример #9
0
        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);
            }
        }
Пример #10
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())
            {
                ;
            }
        }