Esempio n. 1
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);
        }