internal void UpdateChunks(bool block = false) { var newChunks = new HashSet <Coordinates2D>(); var toLoad = new List <Tuple <Coordinates2D, IChunk> >(); Profiler.Start("client.new-chunks"); for (int x = -ChunkRadius; x < ChunkRadius; x++) { for (int z = -ChunkRadius; z < ChunkRadius; z++) { var coords = new Coordinates2D( ((int)Entity.Position.X >> 4) + x, ((int)Entity.Position.Z >> 4) + z); newChunks.Add(coords); if (!LoadedChunks.Contains(coords)) { toLoad.Add(new Tuple <Coordinates2D, IChunk>( coords, World.GetChunk(coords, generate: block))); } } } Profiler.Done(); var encode = new Action(() => { Profiler.Start("client.encode-chunks"); foreach (var tup in toLoad) { var coords = tup.Item1; var chunk = tup.Item2; if (chunk == null) { chunk = World.GetChunk(coords); } chunk.LastAccessed = DateTime.UtcNow; LoadChunk(chunk); } Profiler.Done(); }); if (block) { encode(); } else { Task.Factory.StartNew(encode); } Profiler.Start("client.old-chunks"); LoadedChunks.IntersectWith(newChunks); Profiler.Done(); Profiler.Start("client.update-entities"); ((EntityManager)Server.GetEntityManagerForWorld(World)).UpdateClientEntities(this); Profiler.Done(); }
internal void LoadChunk(Coordinates2D position) { var chunk = World.GetChunk(position); QueuePacket(new ChunkPreamblePacket(chunk.Coordinates.X, chunk.Coordinates.Z)); QueuePacket(CreatePacket(chunk)); LoadedChunks.Add(position); foreach (var kvp in chunk.TileEntities) { var coords = kvp.Key; var descriptor = new BlockDescriptor { Coordinates = coords + new Coordinates3D(chunk.X, 0, chunk.Z), Metadata = chunk.GetMetadata(coords), ID = chunk.GetBlockID(coords), BlockLight = chunk.GetBlockLight(coords), SkyLight = chunk.GetSkyLight(coords) }; var provider = Server.BlockRepository.GetBlockProvider(descriptor.ID); provider.TileEntityLoadedForClient(descriptor, World, kvp.Value, this); } }
internal void UnloadChunk(Coordinates2D position) { QueuePacket(new ChunkPreamblePacket(position.X, position.Z, false)); LoadedChunks.Remove(position); }