public void TestInitialize()
        {
            packetReceiver = new ChunkAwarePacketReceiver(loadedChunks);

            Int3 loadedBatchId   = LargeWorldStreamer.main.GetContainingBatch(loadedActionPosition);
            Int3 unloadedBatchId = LargeWorldStreamer.main.GetContainingBatch(unloadedActionPosition);

            loadedChunk   = new Chunk(loadedBatchId, 3);
            unloadedChunk = new Chunk(unloadedBatchId, 3);

            loadedChunks.Add(loadedChunk);
        }
Beispiel #2
0
        private void CreateTerrainForReadyChunks()
        {
            var anyTerrainCreated = false;

            var chunks = ChunksBeingGenerated.ToList();

            foreach (var chunk in chunks)
            {
                if (chunk.Value.IsHeightmapReady())
                {
                    ChunksBeingGenerated.Remove(chunk.Key);
                    LoadedChunks.Add(chunk.Key, chunk.Value);

                    chunk.Value.CreateTerrain();

                    anyTerrainCreated = true;
                    if (OnChunkGenerated != null)
                    {
                        OnChunkGenerated.Invoke(ChunksBeingGenerated.Count);
                    }

                    SetChunkNeighborhood(chunk.Value);
                }
            }

            if (anyTerrainCreated)
            {
                UpdateAllChunkNeighbors();
            }
        }
Beispiel #3
0
        internal void LoadChunk(IChunk chunk)
        {
            QueuePacket(new ChunkPreamblePacket(chunk.Coordinates.X, chunk.Coordinates.Z));
            QueuePacket(CreatePacket(chunk));
            Server.Scheduler.ScheduleEvent("client.finalize-chunks", this,
                                           TimeSpan.Zero, server =>
            {
                return;

                LoadedChunks.Add(chunk.Coordinates);
                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);
                }
            });
        }
Beispiel #4
0
        private static void UpdateToMesh()
        {
            if (CreationQueue.Count < 1)
            {
                return;
            }

            // Max chunk per frame counter
            int counter = 0;

            foreach (Vector2 chunkPos in CreationQueue.ToList())
            {
                if (counter > MAX_CHUNKS_PER_FRAME)
                {
                    return;
                }

                if (IsChunkLoaded(chunkPos))
                {
                    continue;
                }

                Chunk newChunk = new Chunk((int)chunkPos.X, (int)chunkPos.Y);

                LoadedChunks.Add(chunkPos, newChunk);
                CreationQueue.Remove(chunkPos);
                counter++;
            }
        }
    private void LoadInSingleChunk(ChunkData data)
    {
        Debug.BeginDeepProfile("chunk_load");
        //Initiate chunk
        Vec2i chunk = new Vec2i(data.X, data.Z);

        if (LoadedChunks.ContainsKey(chunk))
        {
            return;
        }
        GameObject chunkObject = Instantiate(ResourceManager.ChunkPrefab);

        chunkObject.transform.parent = transform;
        chunkObject.name             = "Chunk " + chunk;

        //LoadedChunk loadedChunk = chunkObject.AddComponent<LoadedChunk>();
        LoadedChunk loadedChunk = chunkObject.GetComponent <LoadedChunk>();

        ChunkData[] neigh = { GetChunk(chunk.x, chunk.z + 1), GetChunk(chunk.x + 1, chunk.z + 1), GetChunk(chunk.x + 1, chunk.z) };

        //ChunkData[] neigh = { null, null, null };


        loadedChunk.SetChunkData(data, neigh);

        LoadedChunks.Add(chunk, loadedChunk);

        GameManager.EntityManager.LoadChunk(World.ChunkBases[chunk.x, chunk.z], chunk);
        Debug.EndDeepProfile("chunk_load");
    }
Beispiel #6
0
        /// <summary>
        /// Loads the given chunk on the client.
        /// </summary>
        public virtual void LoadChunk(Coordinates2D position)
        {
            var chunk = Entity.World.GetChunk(position);

            SendPacket(ChunkHelper.CreatePacket(chunk));
            // TODO: Tile entities
            foreach (var entity in chunk.TileEntities)
            {
                // ...
            }
            LoadedChunks.Add(position);
        }
Beispiel #7
0
        private IEnumerator WaitAndAddChunk(Int3 batchId, int level)
        {
            yield return(new WaitForSeconds(0.5f));

            Chunk chunk = new Chunk(batchId, level);

            if (!loadedChunks.Contains(chunk))
            {
                loadedChunks.Add(chunk);
                added.Add(chunk);
                chunkAwarePacketReceiver.ChunkLoaded(chunk);
            }
        }
Beispiel #8
0
        public void LoadChunk(CubeCoordinates chunkCoordinates)
        {
            var gotChunk = GetChunkAt(chunkCoordinates);

            if (gotChunk != null)
            {
                LoadedChunks.Add(gotChunk);
            }
            else
            {
                LoadedChunks.Add(new CubeChunk(chunkCoordinates));                 // TODO: ForceGetChunkAt
            }
        }
Beispiel #9
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="chunks"></param>
        public void AddChunks(IEnumerable <Chunk> chunks)
        {
            // DEBUG: Remove for final build
            int count = 0;

            foreach (var chunk in chunks)
            {
                LoadedChunks.Add(chunk.Position, chunk);
                KnownChunks.Add(chunk.Position);
                ++count;
            }

            Debug.Log($"[World] - AddChunks(IEnumerable<Chunk>) \nChunks.Length: {count}");
        }
Beispiel #10
0
        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);
            }
        }
Beispiel #11
0
        public void Load(Chunk item, Transform parent)
        {
            if (!GeneratedChunks.ContainsID(item.ID) || LoadedChunks.Contains(item))
            {
                return;
            }

            LoadedChunks.Add(item);

            var chunkObj = new GameObject("Chunk:" + item.IDStr);

            item.Object      = GameObject.Instantiate(chunkObj, parent);
            item.Object.name = item.Object.name.Substring(0, item.Object.name.Length - 7);

            if (GameSystem.TileSelected && item.Contains(GameSystem.SelectedTile))
            {
                GameObject selector = VisualContainer.CreateObject("ui:selector", GameSystem.SelectedTile, 1.1f, item.Object.transform);
                item.Objects.Add(selector);
            }

            foreach (var block in item.Blocks)
            {
                if (!item.Contains(block.Location))
                {
                    Debug.Log(string.Format("Attempting to load Block {0},{1} into Chunk {2} has failed.", block.Location.X.ToString(), block.Location.Y.ToString(), item.IDStr));
                }

                GameObject obj = VisualContainer.CreateObject(block.Tile.Type.IdName, block.Location, 0, item.Object.transform);
                item.Objects.Add(obj);

                if (block.Overlay.Type != ObjectID.ENV.VOID)
                {
                    GameObject overlayObj = VisualContainer.CreateObject(block.Overlay.Type.IdName, block.Location, 0.1f, item.Object.transform);
                    item.Objects.Add(overlayObj);
                }
            }

            GameObject.Destroy(chunkObj);
        }
    /// <summary>
    /// Main chunk update function.
    /// If the player is in a subworld, all chunks are loaded and this function is skipped.
    /// Otherwise, we check if the player has moved chunk. If they have, we call <see cref="LoadedChunks"/> on a thread,
    /// which initiated the loading or LOD change for all required chunks
    /// </summary>
    private void Update()
    {
        if (InSubworld)
        {
            return;
        }
        Debug.BeginDeepProfile("CRUpdate");
        Vec2i playerChunk = World.GetChunkPosition(Player.Position);
        bool  forceLoad   = false;

        if (LoadedChunksCentre == null)
        {
            forceLoad = true;
        }
        //if we are far (for example, teleporting) then no chunks will be kept, and so we can unload all
        //require a force load
        else if (playerChunk.QuickDistance(LoadedChunksCentre) > LoadChunkRadius * LoadChunkRadius * 2)
        {
            LoadedChunksCentre = null;
            UnloadAllChunks();
            forceLoad = true;
        }
        //if the players current chunk is different to their last chunk, we update
        if (playerChunk != LoadedChunksCentre)
        {
            //If we are currently running a thread on this, we force stop the thread
            //TODO - check if this is safe?
            if (ChunkUpdateThread != null && ChunkUpdateThread.IsAlive)
            {
                ChunkUpdateThread.Abort();
            }
            //We start a thread to load the chunks
            Debug.BeginDeepProfile("ChunkThreadStart");
            ChunkUpdateThread = new Thread(() => LoadChunks(new Vec2i(playerChunk.x, playerChunk.z), LoadChunkRadius, forceLoad));
            ChunkUpdateThread.Start();
            Debug.EndDeepProfile("ChunkThreadStart");
            //LoadChunks(new Vec2i(playerChunk.x, playerChunk.z), LoadChunkRadius, forceLoad);
        }

        //We create a listto hold onto loaded chunks, this allows us to be thread safe
        List <KeyValuePair <Vec2i, LoadedChunk2> > loadedToAdd = new List <KeyValuePair <Vec2i, LoadedChunk2> >();

        //We unload all un-required chunks
        lock (LoadedChunksLock)
        {
            if (ToUnloadChunks.Count > 0)
            {
                foreach (Vec2i v in ToUnloadChunks)
                {
                    UnloadChunk(v);
                }
                ToUnloadChunks.Clear();
            }
        }
        //We get all chunks
        lock (ToGetLoadedChunksLOCK)
        {
            if (ToGetLoadedChunks.Count > 0)
            {
                Debug.Log(ToGetLoadedChunks.Count + " chunks to gen");
                foreach (KeyValuePair <ChunkData, int> kvp in ToGetLoadedChunks)
                {
                    Debug.Log("In the loop...");
                    //Get free object instance and add to list of chunks
                    loadedToAdd.Add(new KeyValuePair <Vec2i, LoadedChunk2>(kvp.Key.Position, ChunkLoader.GetLoadedChunk(kvp.Key, kvp.Value)));
                    EntityManager.Instance?.LoadChunk(kvp.Key.Position);

                    //LoadedChunks.Add(kvp.Key.Position, ChunkLoader.GetLoadedChunk(kvp.Key, kvp.Value));
                }
                ToGetLoadedChunks.Clear();
            }
        }
        lock (LoadedChunksLock)
        {
            foreach (KeyValuePair <Vec2i, LoadedChunk2> kvp in loadedToAdd)
            {
                LoadedChunks.Add(kvp.Key, kvp.Value);
            }
        }

        /*
         * lock (ToGetLoadedChunksLOCK)
         * {
         *  if(ToGetLoadedChunks.Count > 0)
         *  {
         *      foreach(KeyValuePair<ChunkData, int> kvp in ToGetLoadedChunks)
         *      {
         *          //Get free object instance and add to list of chunks
         *          LoadedChunks.Add(kvp.Key.Position, ChunkLoader.GetLoadedChunk(kvp.Key, kvp.Value));
         *      }
         *      ToGetLoadedChunks.Clear();
         *  }
         * }
         */
        Debug.EndDeepProfile("CRUpdate");
    }
Beispiel #13
0
        public override void SetBlock(int x, int y, int z, Block block, bool update, bool lowPriority)
        {
            var chunkInWorld = ChunkInWorld(x, y, z);
            var blockInChunk = BlockInChunk(x, y, z);

            if (LoadedChunks.TryGetValue(chunkInWorld, out var chunk))
            {
                if (chunk.GetBlock(blockInChunk) == block.Id)
                {
                    return;
                }
                chunk.SetBlock(blockInChunk, block.Id);
            }
            else
            {
                chunk = new Chunk(this, chunkInWorld);
                chunk.SetBlock(blockInChunk, block.Id);
                lock (LoadedChunks)
                {
                    LoadedChunks.Add(chunkInWorld, chunk);
                }
            }

            if (!update)
            {
                return;
            }

            var pos = new Vector3i(x, y, z);

            lock (_queuedLightUpdates)
            {
                if (!_queuedLightUpdates.Contains(pos))
                {
                    _queuedLightUpdates.Enqueue(pos);
                }
            }

            if (blockInChunk.X == 0)
            {
                QueueChunkUpdate(chunkInWorld + new Vector3i(-1, 0, 0), lowPriority);
            }
            else if (blockInChunk.X == Chunk.Size - 1)
            {
                QueueChunkUpdate(chunkInWorld + new Vector3i(+1, 0, 0), lowPriority);
            }
            if (blockInChunk.Y == 0)
            {
                QueueChunkUpdate(chunkInWorld + new Vector3i(0, -1, 0), lowPriority);
            }
            else if (blockInChunk.Y == Chunk.Size - 1)
            {
                QueueChunkUpdate(chunkInWorld + new Vector3i(0, +1, 0), lowPriority);
            }
            if (blockInChunk.Z == 0)
            {
                QueueChunkUpdate(chunkInWorld + new Vector3i(0, 0, -1), lowPriority);
            }
            else if (blockInChunk.Z == Chunk.Size - 1)
            {
                QueueChunkUpdate(chunkInWorld + new Vector3i(0, 0, +1), lowPriority);
            }
            QueueChunkUpdate(chunk, lowPriority);
        }
Beispiel #14
0
        public override void Update()
        {
            if (_unloaded)
            {
                return;
            }

            //Update entities
            foreach (var playerEntity in PlayerEntities)
            {
                playerEntity.Update();
            }
            foreach (var entity in Entities)
            {
                entity.Update();
            }

            lock (_chunksReadyToRemove)
            {
                while (_chunksReadyToRemove.Count > 0)
                {
                    var chunkPos = _chunksReadyToRemove.First();

                    if (LoadedChunks.TryGetValue(chunkPos, out var chunk))
                    {
                        lock (LoadedChunks)
                        {
                            LoadedChunks.Remove(chunkPos);
                        }
                        _populatedChunks.Remove(chunkPos);
                        chunk.Dispose();
                    }

                    _chunksReadyToRemove.Remove(chunkPos);
                }
            }

            lock (_chunksReadyToAdd)
            {
                while (_chunksReadyToAdd.Count > 0)
                {
                    var entry = _chunksReadyToAdd.First();
                    lock (LoadedChunks)
                    {
                        if (!LoadedChunks.ContainsKey(entry.Key))
                        {
                            LoadedChunks.Add(entry.Key, new Chunk(entry.Value));
                        }
                        else
                        {
                            Logger.Error("Chunk has already been loaded! " + entry.Key);
                        }
                    }
                    _populatedChunks.Add(entry.Key);
                    _chunksReadyToAdd.Remove(entry.Key);
                }
            }

            while (_chunksReadyToUploadHp.Count > 0)
            {
                lock (_chunksReadyToUploadHp)
                {
                    _chunksReadyToUploadHp.Dequeue().Upload();
                }
            }

            while (_chunksReadyToUploadLp.Count > 0)
            {
                lock (_chunksReadyToUploadLp)
                {
                    _chunksReadyToUploadLp.Dequeue().Upload();
                }
            }
        }