Ejemplo n.º 1
0
        /// <summary>
        /// If a new chunk was loaded (and the chunk contains acutal data) this chunk
        /// will be embedded into a new dynamic chunk. After this, for all relevant layers,
        /// there tiles and items will be loaded and set to be displayed. For all elements
        /// zDepth will be calculated relative to the current reference layer.
        /// </summary>
        /// <param name="sender">the object that informed about the event</param>
        /// <param name="chunk">the new chunk that was loaded</param>
        private void OnChunkLoaded(object sender, Chunk chunk)
        {
            if (chunk == null)
            {
                return;
            }

            var dynamicChunk = new DynamicChunk(spritePool);

            loadedChunks.Add(chunk, dynamicChunk);

            var applicableLayerIndices = GetApplicableLayerIndices(chunk.Layers);

            for (int xy = 0; xy < chunk.Map.Length; xy++)
            {
                int x = xy / Constants.Map.Chunksize + chunk.Origin[0];
                int y = xy % Constants.Map.Chunksize + chunk.Origin[1];

                foreach (int layerIndex in applicableLayerIndices)
                {
                    UncompressTileId(chunk.Map[xy][layerIndex], out var tileId, out var overlayId);

                    int layer = chunk.Layers[layerIndex];

                    int xPos   = x + layer * 3;
                    int yPos   = -y + layer * 3;
                    int zDepth = (referenceLayer - layer) * 2;

                    if (tileId > 0)
                    {
                        tilemap.SetTile(new Vector3Int(
                                            xPos,
                                            yPos,
                                            zDepth), tiles[tileId]);
                    }

                    zDepth--;

                    if (overlayId > 0)
                    {
                        tilemap.SetTile(new Vector3Int(
                                            xPos,
                                            yPos,
                                            zDepth), tiles[overlayId]);
                    }

                    var tilePosition = new Vector3i(x, y, layer);

                    if (!chunk.Items.TryGetValue(tilePosition, out var items))
                    {
                        continue;
                    }

                    LoadItemStack(items, new Vector3((xPos - yPos) * (38f / 76f) - (1f / 76f),
                                                     (xPos + yPos) * (19f / 76f) + 0.25f, zDepth - ((y - x) / 20000f) - 0.3f),
                                  tilePosition, dynamicChunk);
                }
            }
        }
 //Keep track of chunks that need their meshes rebuilt
 void AddChunkToUpdate(DynamicChunk chunk)
 {
     if (chunk != null)
     {
         if (!chunksToUpdate.Contains(chunk))
         {
             chunksToUpdate.Add(chunk);
         }
     }
 }
    DynamicChunk GenerateNewChunk(float chunkX, float chunkY, float chunkZ)
    {
        float[,,] chunkData = new float[chunkSize, chunkHeight, chunkSize];

        FillData(ref chunkData, (int)chunkX, (int)chunkY, (int)chunkZ);

        GameObject chunk = new GameObject("Chunk" + chunkX + "," + chunkY + "," + chunkZ,
                                          typeof(DynamicChunk), typeof(MeshFilter), typeof(MeshRenderer), typeof(MeshCollider));

        chunk.transform.position = new Vector3(chunkX, chunkY, chunkZ);
        chunk.transform.parent   = this.transform;
        DynamicChunk dc = chunk.GetComponent <DynamicChunk>();

        dc.Initialize(chunkData, chunkSize, chunkHeight, defaultMaterial, this);
        return(dc);
    }
    //Used to change the density value at a specific data point
    void ModDensityAt(int x, int y, int z, float value)
    {
        int relativeX = (int)(x - worldStartPosition.x);
        int relativeZ = (int)(z - worldStartPosition.z);

        DynamicChunk chunk = GetChunkContaining(x, z);

        if (chunk != null)
        {
            int chunkOffsetX = (int)(x - worldStartPosition.x) % chunkSize;
            int chunkOffsetZ = (int)(z - worldStartPosition.z) % chunkSize;

            if (chunkOffsetX >= 0 && chunkOffsetX < chunkSize &&
                y >= 0 && y < chunkHeight &&
                chunkOffsetZ >= 0 && chunkOffsetZ < chunkSize)
            {
                float currentValue = chunk.GetValue(chunkOffsetX, y, chunkOffsetZ);
                chunk.SetValue(chunkOffsetX, y, chunkOffsetZ, Mathf.Max(-1, Mathf.Min(currentValue + value, 1)));
                AddChunkToUpdate(chunk);

                //Check surrounding chunks for data changes.
                DynamicChunk neighborChunk;
                if (chunkOffsetX == 0)
                {
                    neighborChunk = GetChunkContaining(x - chunkSize, z);
                    AddChunkToUpdate(neighborChunk);
                }
                if (chunkOffsetZ == 0)
                {
                    neighborChunk = GetChunkContaining(x, z - chunkSize);
                    AddChunkToUpdate(neighborChunk);
                }

                if (chunkOffsetX == chunkSize)
                {
                    neighborChunk = GetChunkContaining(x + chunkSize, z);
                    AddChunkToUpdate(neighborChunk);
                }
                if (chunkOffsetZ == chunkSize)
                {
                    neighborChunk = GetChunkContaining(x, z + chunkSize);
                    AddChunkToUpdate(neighborChunk);
                }
            }
        }
    }
Ejemplo n.º 5
0
        /// <summary>
        /// Loads an array of items to be displayed.
        /// Will apply offset, initialize animated or variant items,
        /// scale and height-level. Loaded items will be in the order of the array.
        /// </summary>
        /// <param name="items">The array of items</param>
        /// <param name="screenPosition">The origin screenposition to display the items</param>
        /// <param name="tilePosition">The corresponding tileposition to the screenpostion</param>
        /// <param name="chunk">The dynamic chunk in charge of the item sprites</param>
        private void LoadItemStack(MapObject[] items, Vector3 screenPosition, Vector3i tilePosition, DynamicChunk chunk)
        {
            foreach (var item in items)
            {
                var unitySprite = spritePool.Get();
                var itemBase    = itemBases[item.BaseId];

                Sprite  sprite;
                float[] offset;
                if (itemBase is SimpleObjectBase simpleBase)
                {
                    sprite = sprites[simpleBase.SpriteId];
                    offset = simpleBase.Offset;
                }
                else
                {
                    var variantBase = (VariantObjectBase)itemBase;

                    var spriteId = SetupMultiFrameItem(variantBase, tilePosition.x, tilePosition.y, unitySprite);

                    sprite = sprites[spriteId];
                    offset = variantBase.GetOffset(spriteId);
                }

                unitySprite.sprite = sprite;

                unitySprite.transform.position = new Vector3(
                    screenPosition.x - sprite.bounds.extents.x + offset[0],
                    screenPosition.y + offset[1] + chunk.GetHeightLevel(tilePosition),
                    screenPosition.z
                    );

                SetupItemScale(tilePosition.x, tilePosition.y, itemBase.SizeVariance, unitySprite);

                unitySprite.gameObject.SetActive(true);

                if (itemBase.Height > 0f)
                {
                    chunk.IncreaseHeightLevel(tilePosition, itemBase.Height);
                }
                chunk.RegisterItem(unitySprite);

                screenPosition.z -= 0.000001f;
            }
        }