示例#1
0
        // Set the river tile at the given corner position (and wrapped
        // positions if necessary)
        protected virtual void SetRiverTile(int x, int y, RiverTile tile)
        {
            currentRiverMap.SetTile(new Vector3Int(x, y, 0), tile);

            // If the river is on a wrapping edge, place the same river tile on
            // the opposite side
            bool wrapX =
                parameters.WrapX && (x == 0 || x == parameters.Width);
            bool wrapY =
                parameters.WrapY && (y == 0 || y == parameters.Height);

            if (wrapX)
            {
                // Horizontally
                currentRiverMap.SetTile(
                    new Vector3Int(parameters.Width - x, y, 0), tile);
            }
            if (wrapY)
            {
                // Vertically
                currentRiverMap.SetTile(
                    new Vector3Int(x, parameters.Height - y, 0), tile);
            }
            if (wrapX && wrapY)
            {
                // Corner wrapping in both dimensions
                currentRiverMap.SetTile(
                    new Vector3Int(parameters.Width - x,
                                   parameters.Height - y, 0), tile);
            }
        }
示例#2
0
        // Place rivers on the map
        protected virtual void GenerateRivers()
        {
            // In non-wrapping dimensions, there are more corners than tiles
            int cornersWidth = parameters.Width;

            if (!parameters.WrapX)
            {
                cornersWidth++;
            }
            int cornersHeight = parameters.Height;

            if (!parameters.WrapY)
            {
                cornersHeight++;
            }

            // Check all tile corners
            for (int i = 0; i < cornersHeight; i++)
            {
                for (int j = 0; j < cornersWidth; j++)
                {
                    // Try to get the river tile at the corner
                    RiverTile currentCorner =
                        currentRiverMap.GetTile <RiverTile>(
                            new Vector3Int(j, i, 0));
                    // Skip if there is already a river here or if next to
                    // ocean
                    if (currentCorner || CornerAtOcean(j, i))
                    {
                        continue;
                    }

                    // Certain probability of starting river
                    if (Random.value < RiverProbability(j, i))
                    {
                        ContinueRiver(j, i, 0);
                    }
                }
            }
        }
示例#3
0
        // Place a river at the given corner, then determine the next corner in
        // the river and, if necessary, call this function for that corner
        // prevDirection is the direction that the previous corner is in
        protected virtual void ContinueRiver(
            int x, int y, RiverTile.Directions prevDirection)
        {
            // Create the new river tile and set its connection to the previous
            // one
            RiverTile newTile = ScriptableObject.CreateInstance <RiverTile>();

            newTile.Parameters  = parameters;
            newTile.LandTilemap = currentMap;
            newTile.Connections = prevDirection;

            // Stop if reached ocean
            if (!CornerAtOcean(x, y))
            {
                // Next river tile is down the steepest downslope
                int nextX, nextY;
                SteepestSlope(x, y, out nextX, out nextY);

                // Stop if there is no downslope
                if (nextX != -1 && nextY != -1)
                {
                    // Try to get existing river tile at next position
                    RiverTile nextCorner = currentRiverMap.GetTile <RiverTile>(
                        new Vector3Int(nextX, nextY, 0));

                    // Check direction of next river tile
                    // Left
                    if (nextX < x)
                    {
                        // Set connection to the next river tile
                        newTile.Connections |= RiverTile.Directions.Left;
                        // If next river tile already exists, set its
                        // connection to the current tile and stop
                        if (nextCorner)
                        {
                            nextCorner.Connections |=
                                RiverTile.Directions.Right;
                        }
                        // Recursively continue river generation
                        else
                        {
                            ContinueRiver(
                                nextX, nextY, RiverTile.Directions.Right);
                        }
                    }
                    // Right
                    else if (nextX > x)
                    {
                        newTile.Connections |= RiverTile.Directions.Right;
                        if (nextCorner)
                        {
                            nextCorner.Connections |=
                                RiverTile.Directions.Left;
                        }
                        else
                        {
                            ContinueRiver(
                                nextX, nextY, RiverTile.Directions.Left);
                        }
                    }
                    // Up
                    else if (nextY > y)
                    {
                        newTile.Connections |= RiverTile.Directions.Up;
                        if (nextCorner)
                        {
                            nextCorner.Connections |=
                                RiverTile.Directions.Down;
                        }
                        else
                        {
                            ContinueRiver(
                                nextX, nextY, RiverTile.Directions.Down);
                        }
                    }
                    // Down
                    else if (nextY < y)
                    {
                        newTile.Connections |= RiverTile.Directions.Down;
                        if (nextCorner)
                        {
                            nextCorner.Connections |=
                                RiverTile.Directions.Up;
                        }
                        else
                        {
                            ContinueRiver(
                                nextX, nextY, RiverTile.Directions.Up);
                        }
                    }
                    // Replace next corner with updated connections
                    if (nextCorner)
                    {
                        SetRiverTile(nextX, nextY, null);
                        SetRiverTile(nextX, nextY, nextCorner);
                    }
                }
            }

            SetRiverTile(x, y, newTile);
        }