Exemplo n.º 1
0
 public Chunk this[int chunkX, int chunkZ]
 {
     get
     {
         Chunk chunk;
         int   packedCoords = UniversalCoords.FromChunkToPackedChunk(chunkX, chunkZ);
         Chunks.TryGetValue(packedCoords, out chunk);
         return(chunk);
     }
     private set
     {
         int packedCoords = UniversalCoords.FromChunkToPackedChunk(chunkX, chunkZ);
         Chunks.AddOrUpdate(packedCoords, value, (key, oldValue) => value);
     }
 }
Exemplo n.º 2
0
        public static void SpawnMobs(WorldManager world, bool spawnHostileMobs, bool spawnPeacefulMobs)
        {
            Client[]      authClients     = world.Server.GetAuthenticatedClients() as Client[];
            var           players         = authClients.Where(c => c.Owner.World == world).Select(c => c.Owner).ToArray();
            HashSet <int> chunksToSpawnIn = new HashSet <int>();

            #region Get a list of all chunks within 8 chunks of any players
            foreach (var player in players)
            {
                UniversalCoords coord = UniversalCoords.FromAbsWorld(player.Position);

                for (int x = -MaxSpawnDistance; x <= MaxSpawnDistance; x++)
                {
                    for (int z = -MaxSpawnDistance; z <= MaxSpawnDistance; z++)
                    {
                        chunksToSpawnIn.Add(UniversalCoords.FromChunkToPackedChunk(coord.ChunkX + x, coord.ChunkZ + z));
                    }
                }
            }
            #endregion

            // Get a list of Mob entities outside of the loop so we only get it once
            Mob[] mobEntities = world.GetEntities().Where(e => e is Mob).Select((e) => e as Mob).ToArray();

            // TODO: need to use Biome to get the list of mob types available for each category
            // TODO: make the maximum count of mobs per category configurable
            if (spawnHostileMobs)
            {
                DoSpawn(world, chunksToSpawnIn, mobEntities, Monsters, MaxMonsters);
            }
            if (spawnPeacefulMobs)
            {
                DoSpawn(world, chunksToSpawnIn, mobEntities, Creatures, MaxCreatures);
                DoSpawn(world, chunksToSpawnIn, mobEntities, WaterCreatures, MaxWaterCreatures, true);
            }
        }
Exemplo n.º 3
0
        public void UpdateChunks(int radius, CancellationToken token, bool sync, bool remove)
        {
            int chunkX = (int)(Math.Floor(Position.X)) >> 4;
            int chunkZ = (int)(Math.Floor(Position.Z)) >> 4;

            Dictionary <int, int> nearbyChunks = new Dictionary <int, int>();

            MapChunkBulkPacket chunkPacket = null;

            if (sync)
            {
                chunkPacket = new MapChunkBulkPacket();
            }

            for (int x = chunkX - radius; x <= chunkX + radius; ++x)
            {
                for (int z = chunkZ - radius; z <= chunkZ + radius; ++z)
                {
                    if (token.IsCancellationRequested)
                    {
                        return;
                    }

                    int packedChunk = UniversalCoords.FromChunkToPackedChunk(x, z);

                    nearbyChunks.Add(packedChunk, packedChunk);

                    if (!LoadedChunks.ContainsKey(packedChunk))
                    {
                        Chunk chunk;
                        if (sync)
                        {
                            chunk = World.GetChunkFromChunkSync(x, z, true, true) as Chunk;
                        }
                        else
                        {
                            chunk = World.GetChunkFromChunkAsync(x, z, Client, true, true) as Chunk;
                        }

                        LoadedChunks.TryAdd(packedChunk, chunk);

                        if (chunk == null)
                        {
                            continue;
                        }

                        if (chunk.LightToRecalculate)
                        {
#if PROFILE
                            Stopwatch watch = new Stopwatch();
                            watch.Start();

                            chunk.RecalculateSky();

                            watch.Stop();

                            World.Logger.Log(LogLevel.Info, "Skylight recalc: {0}", watch.ElapsedMilliseconds);
#else
                            chunk.RecalculateSky();
#endif
                        }

                        chunk.AddClient(Client);
                        if (!sync)
                        {
                            _client.SendChunk(chunk);
                        }
                        else
                        {
                            chunkPacket.ChunksToSend.Add(chunk);
                        }
                    }
                }
            }

            if (sync)
            {
                _client.Send_Sync_Packet(chunkPacket);
            }

            if (remove)
            {
                foreach (int c in LoadedChunks.Keys.Where(c => !nearbyChunks.ContainsKey(c)))
                {
                    if (token.IsCancellationRequested)
                    {
                        return;
                    }
                    Chunk chunk;
                    LoadedChunks.TryRemove(c, out chunk);


                    if (chunk != null)
                    {
                        chunk.RemoveClient(_client);
                    }
                }
            }
        }