public static void Postfix(EntityAlive __instance)
        {
            String strSpawnGroup = "";
            EntityClass entityClass = EntityClass.list[__instance.entityClass];
            if (entityClass.Properties.Values.ContainsKey("SpawnOnDeath"))
            {
                // Spawn location
                Vector3i blockPos = default(Vector3i);
                blockPos.x = (int)__instance.position.x;
                blockPos.y = (int)__instance.position.y;
                blockPos.z = (int)__instance.position.z;


                // <property name="SpawnOnDeath" value="EnemyAnimalsForest" />
                strSpawnGroup = entityClass.Properties.Values["SpawnOnDeath"];

                int classID = 0;
                // try to spawn from a group
                Entity entity = EntityFactory.CreateEntity(EntityGroups.GetRandomFromGroup(strSpawnGroup, ref classID), __instance.position);
                if (entity != null)
                {
                    __instance.world.SetBlockRPC(blockPos, BlockValue.Air);
                    GameManager.Instance.World.SpawnEntityInWorld(entity);
                    return;
                }

                // If no group, then assume its an entity
                int entityID = EntityClass.FromString(strSpawnGroup);
                entity = EntityFactory.CreateEntity(entityID, __instance.position);
                if(entity != null)
                {
                    GameManager.Instance.World.SpawnEntityInWorld(entity);
                }
            }
        }
Beispiel #2
0
    public void SpawnFromGroup(string strEntityGroup, EntityPlayer player)
    {
        int EntityID = 0;

        // If the group is set, then use it.
        if (string.IsNullOrEmpty(strEntityGroup))
        {
            return;
        }

        EntityID = EntityGroups.GetRandomFromGroup(strEntityGroup);
        if (EntityID == -1)
        {
            return; // failed
        }
        Entity NewEntity = EntityFactory.CreateEntity(EntityID, player.position, player.rotation);

        if (NewEntity)
        {
            NewEntity.SetSpawnerSource(EnumSpawnerSource.StaticSpawner);
            GameManager.Instance.World.SpawnEntityInWorld(NewEntity);
            if (NewEntity is EntityAliveSDX)
            {
                LocalPlayerUI uiforPlayer = LocalPlayerUI.GetUIForPlayer(player as EntityPlayerLocal);
                uiforPlayer.windowManager.Open("JoinInformation", true, false, true);
                //(NewEntity as EntityAliveSDX).SetOwner(player as EntityPlayerLocal);
            }
        }
        else
        {
            Debug.Log(" Could not Spawn NPC for: " + player.EntityName + " : " + player.entityId);
        }
    }
    public override void Execute(MinEventParams _params)
    {
        for (int j = 0; j < this.targets.Count; j++)
        {
            EntityAliveSDX entity = this.targets[j] as EntityAliveSDX;
            if (entity)
            {
                int EntityID = entity.entityClass;

                // If the group is set, then use it.
                if (!string.IsNullOrEmpty(this.strSpawnGroup))
                {
                    EntityID = EntityGroups.GetRandomFromGroup(this.strSpawnGroup);
                }

                Entity NewEntity = EntityFactory.CreateEntity(EntityID, entity.position, entity.rotation);
                if (NewEntity)
                {
                    NewEntity.SetSpawnerSource(EnumSpawnerSource.StaticSpawner);
                    GameManager.Instance.World.SpawnEntityInWorld(NewEntity);
                    Debug.Log("An entity was created: " + NewEntity.ToString());
                    if (NewEntity is EntityAliveSDX)
                    {
                        Debug.Log("Setting Mother ID to Baby: " + entity.entityId + " for " + NewEntity.entityId);
                        (NewEntity as EntityAliveSDX).Buffs.SetCustomVar("Mother", entity.entityId, true);
                    }
                }
                else
                {
                    Debug.Log(" Could not Spawn baby for: " + entity.EntityName + " : " + entity.entityId);
                }
            }
        }
    }
    /**
     * Spawns a number of entities around a given position.
     */

    public static void SpawnEntitiesAroundPosition(string _entityGroupName, Vector3 _pos, int _minRange, int _maxRange, int count, Entity target = null)
    {
        Vector3 spawnPoint;
        int     lastEntityId = 0;

        for (int i = 0; i < count; i += 1)
        {
            if (!GameManager.Instance.World.GetRandomSpawnPositionMinMaxToPosition(_pos, _minRange, _maxRange, 1, false, out spawnPoint))
            {
                continue;
            }

            int nextEntityId = EntityGroups.GetRandomFromGroup(_entityGroupName, ref lastEntityId);
            if (nextEntityId == 0)
            {
                continue;
            }

            Entity entity = EntityFactory.CreateEntity(nextEntityId, spawnPoint);

            if (entity == null)
            {
                continue;
            }

            entity.SetSpawnerSource(EnumSpawnerSource.Dynamic);
            GameManager.Instance.World.SpawnEntityInWorld(entity);
        }
    }
    public void CheckForSpawn(WorldBase _world, int _clrIdx, Vector3i _blockPos, BlockValue _blockValue)
    {
        if (string.IsNullOrEmpty(SpawnGroup))
        {
            Debug.Log("Spawner does not have a SpawnGroup property set: " + this.GetBlockName());
            return;
        }

        if (_blockValue.meta2 == 0)
        {
            int    ClassID   = 0;
            int    EntityID  = EntityGroups.GetRandomFromGroup(this.SpawnGroup, ref ClassID);
            Entity NewEntity = EntityFactory.CreateEntity(EntityID, _blockPos.ToVector3() + Vector3.up) as Entity;
            if (NewEntity)
            {
                NewEntity.SetSpawnerSource(EnumSpawnerSource.Dynamic);
                GameManager.Instance.World.SpawnEntityInWorld(NewEntity);
                if (Task == "Stay")
                {
                    EntityUtilities.SetCurrentOrder(NewEntity.entityId, EntityUtilities.Orders.Stay);
                }
                if (Task == "Patrol")
                {
                    EntityUtilities.SetCurrentOrder(NewEntity.entityId, EntityUtilities.Orders.Patrol);
                }
                if (Task == "Wander")
                {
                    EntityUtilities.SetCurrentOrder(NewEntity.entityId, EntityUtilities.Orders.Wander);
                }

                _blockValue.meta2 = (byte)1;
                _world.SetBlockRPC(_clrIdx, _blockPos, _blockValue);
            }
        }
    }
Beispiel #6
0
        public int GetZombieClass(World world, Chunk chunk, int x, int y, PRNG prng)
        {
            ChunkAreaBiomeSpawnData spawnData = chunk.GetChunkBiomeSpawnData();

            if (spawnData == null)
            {
#if DEBUG
                Log.Out("No biome spawn data present");
#endif
                return(-1);
            }

            var biomeData = world.Biomes.GetBiome(spawnData.biomeId);
            if (biomeData == null)
            {
#if DEBUG
                Log.Out("No biome data for biome id {0}", spawnData.biomeId);
#endif
                return(-1);
            }

            BiomeSpawnEntityGroupList biomeSpawnEntityGroupList = list[biomeData.m_sBiomeName];
            if (biomeSpawnEntityGroupList == null)
            {
#if DEBUG
                Log.Out("No biome spawn group specified for {0}", biomeData.m_sBiomeName);
#endif
                return(-1);
            }

            var numGroups = biomeSpawnEntityGroupList.list.Count;
            if (numGroups == 0)
            {
#if DEBUG
                Log.Out("No biome spawn group is empty for {0}", biomeData.m_sBiomeName);
#endif
                return(-1);
            }

            var dayTime = world.IsDaytime() ? EDaytime.Day : EDaytime.Night;
            for (int i = 0; i < 5; i++)
            {
                int pickIndex = prng.Get(0, numGroups);

                var pick = biomeSpawnEntityGroupList.list[pickIndex];
                if (pick.daytime == EDaytime.Any || pick.daytime == dayTime)
                {
                    int lastClassId = -1;
                    return(EntityGroups.GetRandomFromGroup(pick.entityGroupRefName, ref lastClassId));
                }
            }

            return(-1);
        }
Beispiel #7
0
        private static void SpawnForEntity(int targetEntityId, IDictionary <string, string> settings)
        {
            // todo: delay between spawns based on command settings

            var entities = GameManager.Instance.World.Entities.dict;

            if (!entities.ContainsKey(targetEntityId))
            {
                Log.Out($"{Config.ModPrefix} Player not found: {targetEntityId}");

                return;
            }

            var targetEntity = entities[targetEntityId];

            if (targetEntity == null)
            {
                Log.Out($"{Config.ModPrefix}Target entity was not found in world");

                return;
            }

            //if player is dead turn off spawner if set with end_on_death flag (default == true)
            if (targetEntity.IsDead() && (!settings.ContainsKey("end_on_death") || settings["end_on_death"] == "true"))
            {
                settings["enabled"] = "false";

                return;
            }

            if (!settings.TryGetValue("group", out var groupName))
            {
                groupName = "ZombiesAll";
            }

            if (!EntityGroups.list.ContainsKey(groupName))
            {
                Log.Out($"{Config.ModPrefix}Entity group not found {groupName}");

                return;
            }

            var classId = EntityGroups.GetRandomFromGroup(groupName);

            if (!EntityClass.list.ContainsKey(classId))
            {
                Log.Out($"{Config.ModPrefix}Entity class not found {classId}");

                return;
            }

            EntitySpawner.SpawnQueue.Enqueue(GetSpawnForTarget(settings, targetEntity, classId));
        }
    public override void Execute(MinEventParams _params)
    {
        if (!SingletonMonoBehaviour <ConnectionManager> .Instance.IsServer)
        {
            return;
        }

        for (int j = 0; j < this.targets.Count; j++)
        {
            Debug.Log("SpawnBabySDX()");
            EntityAlive entity = this.targets[j] as EntityAlive;
            if (entity)
            {
                Debug.Log("SpawnBabySDX(): Is an EntityAlive");
                int EntityID = entity.entityClass;

                // If the group is set, then use it.
                if (!string.IsNullOrEmpty(this.strSpawnGroup))
                {
                    int ClassID = 0;
                    EntityID = EntityGroups.GetRandomFromGroup(this.strSpawnGroup, ref ClassID);
                }
                Vector3 transformPos;
                entity.world.GetRandomSpawnPositionMinMaxToPosition(entity.position, 2, 6, 2, true, out transformPos, false);

                Entity NewEntity = EntityFactory.CreateEntity(EntityID, transformPos, entity.rotation) as Entity;
                if (NewEntity)
                {
                    NewEntity.SetSpawnerSource(EnumSpawnerSource.StaticSpawner);
                    GameManager.Instance.World.SpawnEntityInWorld(NewEntity);
                    Debug.Log("An entity was created: " + NewEntity.ToString());
                    if (NewEntity is EntityAlive)
                    {
                        Debug.Log("Setting " + this.strCvar + " ID to: " + entity.entityId + " for " + NewEntity.entityId);
                        (NewEntity as EntityAlive).Buffs.SetCustomVar(strCvar, entity.entityId, true);
                    }
                }
                else
                {
                    Debug.Log(" Could not Spawn baby for: " + entity.name + " : " + entity.entityId);
                }
            }
            else
            {
                Debug.Log("SpawnBabySDX(): Not an EntityAlive");
            }
        }
    }
Beispiel #9
0
    public void SpawnFromGroup(String strGroup, int Count)
    {
        int EntityID = -1;

        for (int x = 0; x < this.MaxSpawn; x++)
        {
            // Verify that it's an entity group or individual entity.. just in case.
            if (EntityGroups.list.ContainsKey(strGroup))
            {
                DisplayLog(" Spawning from : " + strGroup);
                EntityID = EntityGroups.GetRandomFromGroup(strGroup);
                SpawnEntity(EntityID, false);
            }
            else
            {
                SpawnEntity(EntityClass.FromString(strGroup), false);
            }
        }
    }
Beispiel #10
0
    // Token: 0x060000AA RID: 170 RVA: 0x00007618 File Offset: 0x00006618
    public override int DamageEntity(DamageSource _damageSource, int _strength, bool _criticalHit, float _impulseScale)
    {
        this.MarkToUnload();
        int result;

        if (this.world.IsRemote())
        {
            Debug.Log("World is remote, not spawning.");
            result = 1;
        }
        else
        {
            if (this.particleOnDeath != null && this.particleOnDeath.Length > 0)
            {
                EntityClass entityClass = EntityClass.list[this.entityClass];
                this.AddParticle(entityClass);
            }
            if (this.isGameMessageOnDeath())
            {
                GameManager.Instance.GameMessage(EnumGameMessages.EntityWasKilled, this, this.entityThatKilledMe);
            }
            int    classID = 0;
            Entity entity  = EntityFactory.CreateEntity(EntityGroups.GetRandomFromGroup("santaspawn", ref classID), this.position);
            if (entity == null)
            {
                Debug.Log("No bad santa spawn");
                result = 1;
            }
            else
            {
                Vector3i blockPos = default(Vector3i);
                blockPos.x = (int)this.position.x;
                blockPos.y = (int)this.position.y;
                blockPos.z = (int)this.position.z;
                this.world.SetBlockRPC(blockPos, BlockValue.Air);
                entity.SetSpawnerSource(EnumSpawnerSource.StaticSpawner);
                GameManager.Instance.World.SpawnEntityInWorld(entity);
                result = 0;
            }
        }
        return(result);
    }
        public static void Postfix(EntityAlive __instance)
        {
            String      strSpawnGroup = "";
            EntityClass entityClass   = EntityClass.list[__instance.entityClass];

            if (entityClass.Properties.Values.ContainsKey("SpawnOnDeath"))
            {
                // <property name="SpawnOnDeath" value="EnemyAnimalsForest" />
                strSpawnGroup = entityClass.Properties.Values["SpawnOnDeath"];

                int    classID = 0;
                Entity entity  = EntityFactory.CreateEntity(EntityGroups.GetRandomFromGroup(strSpawnGroup, ref classID), __instance.position);
                if (entity != null)
                {
                    Vector3i blockPos = default(Vector3i);
                    blockPos.x = (int)__instance.position.x;
                    blockPos.y = (int)__instance.position.y;
                    blockPos.z = (int)__instance.position.z;
                    __instance.world.SetBlockRPC(blockPos, BlockValue.Air);
                    entity.SetSpawnerSource(EnumSpawnerSource.StaticSpawner);
                    GameManager.Instance.World.SpawnEntityInWorld(entity);
                }
            }
        }
    private void Update()
    {
        if (GameTimer.Instance.ticks <= NextTick)
        {
            return;
        }

        NextTick = GameTimer.Instance.ticks + TickRate;

        if (GameManager.Instance.IsPaused())
        {
            return;
        }

        var world = GameManager.Instance.World;

        if (world == null)
        {
            return;
        }

        BlockValue = world.GetBlock(0, Position);

        //block is no longer our spawner block, remove the script
        if (BlockValue.type != SpawnerType)
        {
            KillScript();

            return;
        }

        var  spawnNeeded   = false;
        uint numberSpawned = 0;

        if (CheckRadius > 0 && (NumberToSpawn > 0 || RadiationArea > 0) && MaxSpawn > 0 && CheckArea > 0)
        {
            foreach (var player in world.Players.list)
            {
                if (player == null || !player.IsAlive() || !player.IsSpawned())
                {
                    continue;
                }

                var distance = Vector3.Distance(player.position, Positionf);

                if (RadiationArea > 0 && RadiationArea >= distance)
                {
                    DoBuffsAndRadiation(player);
                }

                if (NumberToSpawn > 0 && CheckRadius >= distance && !Stopped())
                {
                    spawnNeeded = true;
                }
            }

            if (!Stopped())
            {
                foreach (var entity in world.Entities.list.OfType <EntityEnemy>())
                {
                    if (!entity.IsAlive())
                    {
                        continue;
                    }

                    if (Vector3.Distance(entity.position, Positionf) <= CheckArea)
                    {
                        numberSpawned++;
                    }
                }
            }
        }

        if (GameTimer.Instance.ticks <= NextSpawn)
        {
            return;
        }

        NextSpawn = NextTick;

        if (spawnNeeded && numberSpawned < MaxSpawn)
        {
            if (MaxSpawn - numberSpawned < NumberToSpawn)
            {
                NumberToSpawn = MaxSpawn - numberSpawned;
            }

            var areaSize = new Vector3(SpawnArea, SpawnArea, SpawnArea);

            for (var i = 0; i < NumberToSpawn; ++i)
            {
                int x;
                int y;
                int z;
                if (!world.FindRandomSpawnPointNearPosition(Position.ToVector3(), 15, out x, out y, out z, areaSize, true, false))
                {
                    continue;
                }

                int ClassID     = 0;
                var entityId    = EntityGroups.GetRandomFromGroup(EntityGroup, ref ClassID);
                var spawnEntity = EntityFactory.CreateEntity(entityId, new Vector3(x, y, z));
                spawnEntity.SetSpawnerSource(EnumSpawnerSource.StaticSpawner, 0, EntityGroup);
                world.SpawnEntityInWorld(spawnEntity);

                if (NumberToPauseCounter > 0)
                {
                    NumberToPauseCounter--;
                }
            }
        }

        if (NumberToPauseCounter > 0 || PauseTime == 0)
        {
            return;
        }

        NumberToPauseCounter = NumberToPause;

        NextSpawn = GameTimer.Instance.ticks + PauseTime;

        if (PauseTimeMinutes >= 999)
        {
            BlockValue.meta2 = (byte)(BlockValue.meta2 | (1 << 1));
            GameManager.Instance.World.SetBlockRPC(Position, BlockValue);
        }

        Alzheimer();
    }
Beispiel #13
0
        bool CreateZombie(ZombieAgent zombie, PlayerZone zone)
        {
            if (!CanSpawnActiveZombie())
            {
                return(false);
            }

            var   world = GameManager.Instance.World;
            Chunk chunk = (Chunk)world.GetChunkSync(World.toChunkXZ(Mathf.FloorToInt(zombie.pos.x)), 0, World.toChunkXZ(Mathf.FloorToInt(zombie.pos.z)));

            if (chunk == null)
            {
#if DEBUG
                Log.Out("[WalkerSim] Chunk not loaded at {0} {1}", zombie.pos, zombie.pos.z);
#endif
                return(false);
            }

            int height = world.GetTerrainHeight(Mathf.FloorToInt(zombie.pos.x), Mathf.FloorToInt(zombie.pos.z));

            Vector3 spawnPos = new Vector3(zombie.pos.x, height + 1.0f, zombie.pos.z);
            if (!CanZombieSpawnAt(spawnPos))
            {
#if DEBUG
                Log.Out("[WalkerSim] Unable to spawn zombie at {0}, CanMobsSpawnAtPos failed", spawnPos);
#endif
                return(false);
            }

            if (zombie.classId == -1)
            {
                zombie.classId = _biomeData.GetZombieClass(world, chunk, (int)spawnPos.x, (int)spawnPos.z, _prng);
                if (zombie.classId == -1)
                {
                    int lastClassId = -1;
                    zombie.classId = EntityGroups.GetRandomFromGroup("ZombiesAll", ref lastClassId);
#if DEBUG
                    Log.Out("Used fallback for zombie class!");
#endif
                }
            }

            EntityZombie zombieEnt = EntityFactory.CreateEntity(zombie.classId, spawnPos) as EntityZombie;
            if (zombieEnt == null)
            {
#if DEBUG
                Log.Error("[WalkerSim] Unable to create zombie entity!, Entity Id: {0}, Pos: {1}", zombie.classId, spawnPos);
#endif
                return(false);
            }

            zombieEnt.bIsChunkObserver = true;

            // TODO: Figure out a better way to make them walk towards something.
            if (true)
            {
                // Send zombie towards a random position in the zone.
                Vector3 targetPos = GetRandomZonePos(zone);
                if (targetPos == Vector3.zero)
                {
                    zombieEnt.SetInvestigatePosition(zone.center, 6000, false);
                }
                else
                {
                    zombieEnt.SetInvestigatePosition(targetPos, 6000, false);
                }
            }

            // If the zombie was previously damaged take health to this one.
            if (zombie.health != -1)
            {
                zombieEnt.Health = zombie.health;
            }
            else
            {
                zombie.health = zombieEnt.Health;
            }

            zombieEnt.IsHordeZombie = true;
            zombieEnt.IsBloodMoon   = _state.IsBloodMoon;

            zombieEnt.SetSpawnerSource(EnumSpawnerSource.StaticSpawner);

            world.SpawnEntityInWorld(zombieEnt);

            zombie.entityId    = zombieEnt.entityId;
            zombie.currentZone = zone;
            zombie.lifeTime    = world.GetWorldTime();

            zone.numZombies++;

#if DEBUG
            Log.Out("[WalkerSim] Spawned zombie {0} at {1}", zombieEnt, spawnPos);
#endif
            lock (_activeZombies)
            {
                _activeZombies.Add(zombie);
            }

            return(true);
        }
Beispiel #14
0
        public override void Process()
        {
            if (Params.Count == 0)
            {
                SendOutput(GetHelp());

                return;
            }

            switch (Params[0])
            {
            case "horde":
            {
                if (!GetPos(out var position))
                {
                    return;
                }
                if (!GetGroup(out var groupName))
                {
                    return;
                }
                if (!GetCount(out var count))
                {
                    return;
                }
                if (!GetMinMax(out var min, out var max))
                {
                    return;
                }
                if (!GetSpawnPos(position, out var targetPos))
                {
                    return;
                }

                //todo: refine method to ensure unique id
                var spawnerId = DateTime.UtcNow.Ticks;

                for (var i = 0; i < count; i++)
                {
                    var classId = EntityGroups.GetRandomFromGroup(groupName);
                    if (!EntityClass.list.ContainsKey(classId))
                    {
                        SendOutput($"Entity class not found '{classId}', from group '{groupName}'");

                        return;
                    }

                    var spawn = new Spawn
                    {
                        EntityClassId = classId,
                        SpawnerId     = spawnerId,
                        SpawnPos      = position,
                        TargetPos     = targetPos,
                        MinRange      = min,
                        MaxRange      = max
                    };

                    EntitySpawner.SpawnQueue.Enqueue(spawn);
                }
                SendOutput($"Spawning horde of {count} around {position.x} {position.y} {position.z}");
                if (targetPos != position)
                {
                    SendOutput($"Moving towards {targetPos.x} {targetPos.y} {targetPos.z}");
                }

                return;
            }

            case "entity":
            {
                if (Params.Count != 2 && Params.Count != 5)
                {
                    SendOutput("Spawn entity requires an entity class name");

                    return;
                }
                if (!GetPos(out var position))
                {
                    return;
                }
                if (!GetMinMax(out var min, out var max))
                {
                    return;
                }
                if (!GetSpawnPos(position, out var targetPos))
                {
                    return;
                }

                //todo: refine method to ensure unique id
                var spawnerId = DateTime.UtcNow.Ticks;

                var classId = Params[1].GetHashCode();

                if (!EntityClass.list.ContainsKey(classId))
                {
                    SendOutput($"Entity class not found '{Params[1]}'");

                    return;
                }

                var spawn = new Spawn
                {
                    EntityClassId = classId,
                    SpawnerId     = spawnerId,
                    SpawnPos      = position,
                    TargetPos     = position,
                    MinRange      = min,
                    MaxRange      = max
                };

                EntitySpawner.SpawnQueue.Enqueue(spawn);

                SendOutput($"Spawning entity {Params[1]} around {position.x} {position.y} {position.z}");
                if (targetPos != position)
                {
                    SendOutput($"Moving towards {targetPos.x} {targetPos.y} {targetPos.z}");
                }

                return;
            }

            case "item":
            {
                if (!GetPos(out var position))
                {
                    return;
                }
                if (!GetItemValue(out var item))
                {
                    return;
                }
                if (!GetCount(out var count, 1))
                {
                    return;
                }
                if (!GetMinMax(out var min, out var max, "qual"))
                {
                    return;
                }

                if (item == null || item.type == ItemValue.None.type)
                {
                    SendOutput("Item class not found'");

                    return;
                }

                var itemValue = new ItemValue(item.type, true);

                var quality = UnityEngine.Random.Range(min, max);
                if (ItemClass.list[itemValue.type].HasParts)
                {
                    count = 1;
                    for (var i = 0; i < itemValue.Parts.Length; i++)
                    {
                        var item2 = itemValue.Parts[i];
                        item2.Quality      = quality;
                        itemValue.Parts[i] = item2;
                    }
                }
                else if (itemValue.HasQuality)
                {
                    count             = 1;
                    itemValue.Quality = quality;
                }

                var itemStack = new ItemStack(itemValue, count);
                GameManager.Instance.ItemDropServer(itemStack, position, Vector3.zero);

                SendOutput($"Spawning {count}x {itemValue.ItemClass.Name} at {position.x} {position.y} {position.z}");

                return;
            }

            default:
                SendOutput($"Unknown Sub Command {Params[0]}");
                SendOutput(GetHelp());

                return;
            }
        }
Beispiel #15
0
        // This method is a modified version of vanilla, doing the same checks and balances. However, we do use the player position a bit more, and we change which biome spawning group we
        // will use, when below the terrain.
        public static void SpawnUpdate(string _spawnerName, bool _bSpawnEnemyEntities, ChunkAreaBiomeSpawnData _chunkBiomeSpawnData, ref List <Entity> spawnNearList, ref int lastClassId)
        {
            if (_chunkBiomeSpawnData == null)
            {
                return;
            }
            if (_bSpawnEnemyEntities)
            {
                if (GameStats.GetInt(EnumGameStats.EnemyCount) >= GamePrefs.GetInt(EnumGamePrefs.MaxSpawnedZombies))
                {
                    _bSpawnEnemyEntities = false;
                }
                else if (GameManager.Instance.World.aiDirector.BloodMoonComponent.BloodMoonActive)
                {
                    _bSpawnEnemyEntities = false;
                }
            }
            if (!_bSpawnEnemyEntities && GameStats.GetInt(EnumGameStats.AnimalCount) >= GamePrefs.GetInt(EnumGamePrefs.MaxSpawnedAnimals))
            {
                return;
            }
            bool flag = false;
            List <EntityPlayer> players = GameManager.Instance.World.GetPlayers();

            // Player Position.
            Vector3 position = Vector3.zero;
            Rect    rect     = new Rect(1, 1, 1, 1);

            for (int i = 0; i < players.Count; i++)
            {
                if (players[i].Spawned)
                {
                    position = players[i].GetPosition();
                    rect     = new Rect(position.x - 40f, position.z - 40f, 80f, 20f);
                    if (rect.Overlaps(_chunkBiomeSpawnData.area))
                    {
                        flag = true;
                        break;
                    }
                }
            }

            // No valid player position.
            if (position == Vector3.zero)
            {
                return;
            }

            // Don't allow above ground spawning.
            Vector3i playerPosition = new Vector3i(position);
            float    offSet         = GameManager.Instance.World.GetTerrainHeight(playerPosition.x, playerPosition.z);

            if (offSet <= playerPosition.y)
            {
                return;
            }

            int     minDistance = _bSpawnEnemyEntities ? 28 : 48;
            int     maxDistance = _bSpawnEnemyEntities ? 54 : 70;
            Vector3 vector;

            if (!flag || !FindRandomSpawnPointNearPositionUnderground(rect, minDistance, maxDistance, false, out vector, playerPosition))
            {
                return;
            }

            // Mob is above terrain; ignore.
            if (vector.y > offSet)
            {
                return;
            }


            BiomeDefinition biome = GameManager.Instance.World.Biomes.GetBiome(_chunkBiomeSpawnData.biomeId);

            if (biome == null)
            {
                return;
            }

            // Customize which spawning.xml entry to we want to use for spawns.
            String CaveType = "Cave";
            // Search for the biome_Cave spawn group. If not found, load the generic Cave one.
            BiomeSpawnEntityGroupList biomeSpawnEntityGroupList = BiomeSpawningClass.list[biome.m_sBiomeName + "_Cave"];

            if (biomeSpawnEntityGroupList == null)
            {
                biomeSpawnEntityGroupList = BiomeSpawningClass.list["Cave"];
            }
            // if we are below 30, look for the biome specific deep cave, then deep cave if its not set.
            if (vector.y < 30)
            {
                CaveType = "DeepCave";
                biomeSpawnEntityGroupList = BiomeSpawningClass.list[biome.m_sBiomeName + "_DeepCave"];
                if (biomeSpawnEntityGroupList == null)
                {
                    biomeSpawnEntityGroupList = BiomeSpawningClass.list["DeepCave"];
                }
            }
            if (biomeSpawnEntityGroupList == null)
            {
                return;
            }

            EDaytime   edaytime        = GameManager.Instance.World.IsDaytime() ? EDaytime.Day : EDaytime.Night;
            GameRandom gameRandom      = GameManager.Instance.World.GetGameRandom();
            string     entityGroupName = null;
            int        num             = -1;
            int        num2            = gameRandom.RandomRange(biomeSpawnEntityGroupList.list.Count);
            int        j = 0;

            while (j < 5)
            {
                BiomeSpawnEntityGroupData biomeSpawnEntityGroupData = biomeSpawnEntityGroupList.list[num2];
                if (biomeSpawnEntityGroupData.daytime == EDaytime.Any || biomeSpawnEntityGroupData.daytime == edaytime)
                {
                    bool flag2 = EntityGroups.IsEnemyGroup(biomeSpawnEntityGroupData.entityGroupRefName);
                    if (!flag2 || _bSpawnEnemyEntities)
                    {
                        int num3 = biomeSpawnEntityGroupData.maxCount;
                        if (flag2)
                        {
                            num3 = EntitySpawner.ModifySpawnCountByGameDifficulty(num3);
                        }
                        entityGroupName = biomeSpawnEntityGroupData.entityGroupRefName + "_" + biomeSpawnEntityGroupData.daytime.ToStringCached <EDaytime>() + "_" + CaveType;
                        ulong respawnLockedUntilWorldTime = _chunkBiomeSpawnData.GetRespawnLockedUntilWorldTime(entityGroupName);
                        if (respawnLockedUntilWorldTime <= 0UL || GameManager.Instance.World.worldTime >= respawnLockedUntilWorldTime)
                        {
                            if (respawnLockedUntilWorldTime > 0UL)
                            {
                                _chunkBiomeSpawnData.ClearRespawnLocked(entityGroupName);
                            }
                            if (_chunkBiomeSpawnData.GetEntitiesSpawned(entityGroupName) < num3)
                            {
                                num = num2;
                                break;
                            }
                        }
                    }
                }
                j++;
                num2 = (num2 + 1) % biomeSpawnEntityGroupList.list.Count;
            }
            if (num < 0)
            {
                //Debug.Log("max spawn reached: " + entityGroupName);
                return;
            }
            Bounds bb = new Bounds(vector, new Vector3(4f, 2.5f, 4f));

            GameManager.Instance.World.GetEntitiesInBounds(typeof(Entity), bb, spawnNearList);
            int count = spawnNearList.Count;

            spawnNearList.Clear();
            if (count > 0)
            {
                //Debug.Log("Spawn Count is maxed for ");
                return;
            }
            BiomeSpawnEntityGroupData biomeSpawnEntityGroupData2 = biomeSpawnEntityGroupList.list[num];
            int   randomFromGroup = EntityGroups.GetRandomFromGroup(biomeSpawnEntityGroupData2.entityGroupRefName, ref lastClassId, null);
            float spawnDeadChance = biomeSpawnEntityGroupData2.spawnDeadChance;

            _chunkBiomeSpawnData.IncEntitiesSpawned(entityGroupName);
            Entity entity = EntityFactory.CreateEntity(randomFromGroup, vector);

            entity.SetSpawnerSource(EnumSpawnerSource.Dynamic, _chunkBiomeSpawnData.chunk.Key, entityGroupName);
            EntityAlive myEntity = entity as EntityAlive;

            if (myEntity)
            {
                myEntity.SetSleeper();
            }

            // Debug.Log("Spawning: " + myEntity.entityId + " " + vector );
            GameManager.Instance.World.SpawnEntityInWorld(entity);


            if (spawnDeadChance > 0f && gameRandom.RandomFloat < spawnDeadChance)
            {
                entity.Kill(DamageResponse.New(true));
            }
            GameManager.Instance.World.DebugAddSpawnedEntity(entity);
        }