Пример #1
0
        /// <summary>
        /// Applied before UpdateState runs.
        /// </summary>
        internal static bool Prefix(OvercrowdingMonitor.Instance smi)
        {
            var  prefabID    = smi.GetComponent <KPrefabID>();
            bool overcrowded = CheckOvercrowding(smi, prefabID, out bool confined,
                                                 out bool cramped);
            bool wasConfined    = prefabID.HasAnyTags_AssumeLaundered(ref CONFINED);
            bool wasCramped     = prefabID.HasAnyTags_AssumeLaundered(ref CRAMPED);
            bool wasOvercrowded = prefabID.HasAnyTags_AssumeLaundered(ref OVERCROWDED);

            if (wasCramped != cramped || wasConfined != confined || wasOvercrowded !=
                overcrowded)
            {
                // Status has actually changed
                var effects = smi.GetComponent <Effects>();
                prefabID.SetTag(GameTags.Creatures.Confined, confined);
                prefabID.SetTag(GameTags.Creatures.Overcrowded, overcrowded);
                prefabID.SetTag(GameTags.Creatures.Expecting, cramped);
                if (confined)
                {
                    effects.Add(OvercrowdingMonitor.stuckEffect, false);
                    effects.Remove(OvercrowdingMonitor.overcrowdedEffect);
                    effects.Remove(OvercrowdingMonitor.futureOvercrowdedEffect);
                }
                else
                {
                    effects.Remove(OvercrowdingMonitor.stuckEffect);
                    if (overcrowded)
                    {
                        effects.Add(OvercrowdingMonitor.overcrowdedEffect, false);
                    }
                    else
                    {
                        effects.Remove(OvercrowdingMonitor.overcrowdedEffect);
                    }
                    if (cramped)
                    {
                        effects.Add(OvercrowdingMonitor.futureOvercrowdedEffect, false);
                    }
                    else
                    {
                        effects.Remove(OvercrowdingMonitor.futureOvercrowdedEffect);
                    }
                }
            }
            return(false);
        }
Пример #2
0
        /// <summary>
        /// A faster Overcrowded, Cramped, and Confined check that also updates the current
        /// room.
        /// </summary>
        /// <param name="smi">The overcrowding monitor to update.</param>
        /// <param name="prefabID">The critter to be updated.</param>
        /// <param name="confined">Will be true if the critter is now Confined.</param>
        /// <param name="cramped">Will be true if the critter is now Cramped.</param>
        /// <returns>true if the critter is now Overcrowded.</returns>
        private static bool CheckOvercrowding(OvercrowdingMonitor.Instance smi,
                                              KPrefabID prefabID, out bool confined, out bool cramped)
        {
            var  room          = UpdateRoom(smi, prefabID);
            int  requiredSpace = smi.def.spaceRequiredPerCreature;
            bool overcrowded;

            // Share some checks for simplicity
            if (requiredSpace < 1)
            {
                confined    = false;
                overcrowded = false;
                cramped     = false;
            }
            else
            {
                var fishMonitor = smi.GetSMI <FishOvercrowdingMonitor.Instance>();
                int eggs = 0, critters = 0;
                // Voles/burrowed Hatches cannot be confined, otherwise check for either
                // no room (stuck in wall) or tiny room < 1 critter space
                confined = !prefabID.HasAnyTags_AssumeLaundered(ref IMMUNE_CONFINEMENT) &&
                           (room == null || room.numCells < requiredSpace);
                if (room != null)
                {
                    eggs     = room.eggs.Count;
                    critters = room.creatures.Count;
                }
                if (fishMonitor != null)
                {
                    int fishCount = fishMonitor.fishCount;
                    overcrowded = fishCount > 0 && fishMonitor.cellCount < requiredSpace *
                                  fishCount;
                }
                else
                {
                    overcrowded = room != null && critters > 1 && room.numCells <
                                  requiredSpace * critters;
                }
                cramped = room != null && eggs > 0 && room.numCells < (eggs + critters) *
                          requiredSpace;
            }
            return(overcrowded);
        }
Пример #3
0
        /// <summary>
        /// A version of OvercrowdingMonitor.UpdateCavity that updates the correct rooms.
        /// </summary>
        /// <param name="smi">The overcrowding monitor to update.</param>
        /// <param name="prefabID">The critter to be updated.</param>
        /// <returns>The new room of the critter.</returns>
        private static CavityInfo UpdateRoom(OvercrowdingMonitor.Instance smi,
                                             KPrefabID prefabID)
        {
            CavityInfo room = smi.cavity, newRoom;
            bool       background = FastTrackOptions.Instance.BackgroundRoomRebuild;
            int        cell       = Grid.PosToCell(smi.transform.position);

            if (background)
            {
                newRoom = GamePatches.BackgroundRoomProber.Instance.GetCavityForCell(cell);
            }
            else
            {
                newRoom = Game.Instance.roomProber.GetCavityForCell(cell);
            }
            prefabID.UpdateTagBits();
            if (newRoom != room)
            {
                bool isEgg = prefabID.HasAnyTags_AssumeLaundered(ref EGG), light =
                    smi.GetComponent <Light2D>() != null;
                // Currently no rooms (checked I Love Slicksters, Butcher Stations, and Rooms
                // Expanded) use the WILDANIMAL criterion, so only light emitting critters
                // would need to actually update the rooms.
                if (room != null)
                {
                    if (isEgg)
                    {
                        room.eggs.Remove(prefabID);
                    }
                    else
                    {
                        room.creatures.Remove(prefabID);
                    }
                    if (light)
                    {
                        if (background)
                        {
                            GamePatches.BackgroundRoomProber.Instance.UpdateRoom(room);
                        }
                        else
                        {
                            Game.Instance.roomProber.UpdateRoom(room);
                        }
                    }
                }
                smi.cavity = newRoom;
                if (newRoom != null)
                {
                    if (isEgg)
                    {
                        newRoom.eggs.Add(prefabID);
                    }
                    else
                    {
                        newRoom.creatures.Add(prefabID);
                    }
                    if (light)
                    {
                        if (background)
                        {
                            GamePatches.BackgroundRoomProber.Instance.UpdateRoom(newRoom);
                        }
                        else
                        {
                            Game.Instance.roomProber.UpdateRoom(newRoom);
                        }
                    }
                }
            }
            return(newRoom);
        }