Beispiel #1
0
        public static Block[,,] GenerateTile(int tileHeight, int tileWidth, int tileDepth, Tile tile)
        {
            if (!initialized)
            {
                InitializeMaterials();
            }

            int tileX = tile.tileX;
            int tileY = tile.tileY;

            Block[,,] blocks = new Block[tileHeight, tileWidth, tileDepth];
            float[,] depth1  = Simplex.Noise.Calc2D(tileWidth, tileHeight, 0.001f);
            float[,] depth2  = Simplex.Noise.Calc2D(tileWidth, tileHeight, 0.01f);
            float[,] depth3  = Simplex.Noise.Calc2D(tileWidth, tileHeight, 0.05f);
            float[,] depth4  = Simplex.Noise.Calc2D(tileWidth, tileHeight, 0.1f);

            int offsetX = tile.tileX * Map.TILE_WIDTH;
            int offsetY = tile.tileY * Map.TILE_HEIGHT;

            for (byte i = 0; i < tileDepth; i++)
            {
                for (byte j = 0; j < tileHeight; j++)
                {
                    int blockDepth1 = (int)Math.Round((depth1[i, j] / 512) * Map.TILE_DEPTH);
                    int blockDepth2 = (int)Math.Round((depth2[i, j] / 1024) * Map.TILE_DEPTH);
                    int blockDepth3 = (int)Math.Round((depth3[i, j] / 2048) * Map.TILE_DEPTH);
                    int blockDepth4 = (int)Math.Round((depth4[i, j] / 4096) * Map.TILE_DEPTH);
                    int blockDepth  = (blockDepth1 + blockDepth2 + blockDepth3 + blockDepth4) + 20;

                    for (byte k = 0; k < tileWidth; k++)
                    {
                        if (k < blockDepth)
                        {
                            blocks[i, j, k] = new BlockSolid(materialDirt);
                        }
                        else if (i == 50 && j > 97)
                        //else if (k < WATER_LEVEL)
                        {
                            int worldCol = tile.tileX * Map.TILE_WIDTH + i;
                            int worldRow = tile.tileY * Map.TILE_HEIGHT + j;

                            BlockLiquid newBlock = new BlockLiquid(materialWater, worldCol, worldRow, k);
                            blocks[i, j, k] = newBlock;
                        }
                        else
                        {
                            blocks[i, j, k] = new BlockEmpty();
                        }
                    }
                }
            }

            return(blocks);
        }
Beispiel #2
0
        private List <BlockLiquid> GetAvailableNeighbors()
        {
            List <BlockLiquid> neighbors = new List <BlockLiquid>();

            int[,] positionsToCheck =
            {
                { worldCol + 1, worldRow,     depth },
                { worldCol - 1, worldRow,     depth },
                { worldCol,     worldRow + 1, depth },
                { worldCol,     worldRow - 1, depth },
            };

            for (int i = 0; i < positionsToCheck.GetLength(0); i++)
            {
                // First, get the block
                Block neighbor = Map.GetInstance().GetBlockAt(
                    positionsToCheck[i, 0],
                    positionsToCheck[i, 1],
                    positionsToCheck[i, 2]
                    );

                // We'll need this later
                BlockLiquid neighborLiquid;

                // If there's an empty block, put an empty liquid block there
                BlockEmpty neighborEmpty = neighbor as BlockEmpty;
                if (neighborEmpty != null)
                {
                    neighborLiquid = new BlockLiquid(
                        material,
                        positionsToCheck[i, 0],
                        positionsToCheck[i, 1],
                        (byte)positionsToCheck[i, 2],
                        0);

                    neighborLiquid.SetSelfInTile();

                    neighbors.Add(neighborLiquid);
                }
                else if (neighbor is BlockLiquid)
                {
                    //TODO: DO

                    /*neighborLiquid = (BlockLiquid)neighbor;
                     * neighbors.Add(neighborLiquid);*/
                }
            }

            return(neighbors);
        }
Beispiel #3
0
        public override void Update(GameTime gameTime)
        {
            // When there is no liquid left, there's no point in keeping the block around
            if (quantity == 0)
            {
                tile.SetBlock(col, row, depth, new BlockEmpty());
                return;
            }

            // Check for an valid neighbor below
            if (depth > 0)
            {
                // Empty neighbor below, we can just move down directly
                Block neighborBelow = Map.GetInstance().GetBlockAt(worldCol, worldRow, depth - 1);
                if (neighborBelow is BlockEmpty)
                {
                    tile.SetBlock(col, row, depth, new BlockEmpty());

                    BlockLiquid newBlockBelow = new BlockLiquid(material, worldCol, worldRow, (byte)(depth - 1), quantity);
                    newBlockBelow.SetSelfInTile();

                    quantity = 0;
                    return;
                }

                // Liquid below, transfer what we can
                if (neighborBelow is BlockLiquid)
                {
                    BlockLiquid liquidNeighborBelow = (BlockLiquid)neighborBelow;
                    byte        freeSpaceBelow      = (byte)(byte.MaxValue - liquidNeighborBelow.quantity);

                    if (freeSpaceBelow > 0)
                    {
                        if (quantity <= freeSpaceBelow)
                        {
                            tile.SetBlock(col, row, depth, new BlockEmpty());
                            liquidNeighborBelow.quantity += quantity;
                        }
                        else
                        {
                            quantity -= freeSpaceBelow;
                            AddToUpdateQueue();
                            liquidNeighborBelow.quantity += freeSpaceBelow;
                        }

                        liquidNeighborBelow.AddToUpdateQueue();
                    }
                }
            }

            if (quantity == 1)
            {
                quantity = 0;
                tile.SetBlock(col, row, depth, new BlockEmpty());
            }

            /*if (quantity < 3)
             * {
             *  return;
             * }*/

            // If we reach this point, it means there is still water in this block
            // Try to spread to sides
            List <BlockLiquid> spreadBlocks = GetAvailableNeighbors();

            if (spreadBlocks.Count == 0)
            {
                return;
            }

            spreadBlocks.Add(this);

            int totalQuantity = 0;

            foreach (BlockLiquid block in spreadBlocks)
            {
                totalQuantity += block.quantity;
            }

            byte averageQuantity = (byte)(totalQuantity / spreadBlocks.Count);
            int  rest            = totalQuantity % spreadBlocks.Count;

            foreach (BlockLiquid block in spreadBlocks)
            {
                if (Math.Abs(quantity - averageQuantity) <= 1)
                {
                    return;
                }

                block.quantity = averageQuantity;
                if (rest > 0 && block.quantity < byte.MaxValue)
                {
                    rest--;
                    block.quantity++;
                }
                block.AddToUpdateQueue();
            }
        }