Beispiel #1
0
    public HexEdge GetHexDirectionPrevious2Edge(
        Hex hex,
        HexDirections direction
        )
    {
        List <HexEdge> edges = GetOutEdgesList(hex);

        if (edges != null && edges.Count > 0)
        {
            foreach (HexEdge currentEdge in edges)
            {
                if (currentEdge.Direction == direction.PreviousClockwise2())
                {
                    return(currentEdge);
                }
            }
        }

        return(null);
    }
Beispiel #2
0
    private TerrainTriangulationData TriangulateTerrainAdjacentToRiver(
        Hex source,
        HexDirections direction,
        TerrainTriangulationData triangulationData,
        Dictionary <HexDirections, bool> roadEdges,
        HexRiverData riverData,
        float hexOuterRadius,
        int wrapSize,
        MapMeshChunkLayer terrain,
        FeatureContainer features
        )
    {
        if (riverData.HasRiverInDirection(direction.NextClockwise()))
        {
/* If the direction has a river on either side, it has a slight curve.
 * The center vertex of river-adjacent triangle needs to be moved toward
 * the edge so they don't overlap the river.
 */
//            if (hex.HasRiverThroughEdge(direction.Previous())) {
            if (
                riverData.HasRiverInDirection(direction.PreviousClockwise())
                )
            {
                triangulationData.terrainCenter += HexagonPoint.GetSolidEdgeMiddle(
                    direction,
                    hexOuterRadius
                    ) * (HexagonConstants.INNER_TO_OUTER_RATIO * 0.5f);
            }

/* If the hex has a river through the previous previous direction,
 * it has a river flowing through the hex. Move the center vertex
 * of the river-adjacent triangle so that it does not overlap the river.
 */
            else if (
                riverData.HasRiverInDirection(
                    direction.PreviousClockwise2()
                    )
                )
            {
                triangulationData.terrainCenter +=
                    HexagonPoint.GetFirstSolidCorner(
                        direction,
                        hexOuterRadius
                        ) * 0.25f;
            }
        }

/* Second case of straight-river-adjacent triangle. Need to move center
 * so it doesn't overlap the river.
 */
        else if (
            riverData.HasRiverInDirection(direction.PreviousClockwise()) &&
            riverData.HasRiverInDirection(direction.NextClockwise2())
            )
        {
            triangulationData.terrainCenter += HexagonPoint.GetSecondSolidCorner(
                direction,
                hexOuterRadius
                ) * 0.25f;
        }

        EdgeVertices middle = new EdgeVertices(
            Vector3.Lerp(
                triangulationData.terrainCenter,
                triangulationData.centerEdgeVertices.vertex1,
                0.5f
                ),
            Vector3.Lerp(
                triangulationData.terrainCenter,
                triangulationData.centerEdgeVertices.vertex5,
                0.5f
                )
            );

        TriangulateEdgeStripTerrain(
            middle,
            _weights1,
            source.Index,
            triangulationData.centerEdgeVertices,
            _weights1,
            source.Index,
            hexOuterRadius,
            wrapSize,
            terrain
            );

        TriangulateEdgeFan(
            triangulationData.terrainCenter,
            middle,
            source.Index,
            hexOuterRadius,
            wrapSize,
            terrain
            );

        if (!source.IsUnderwater && roadEdges[direction])
        {
            features.AddFeature(
                source,
                (
                    triangulationData.terrainCenter +
                    triangulationData.centerEdgeVertices.vertex1 +
                    triangulationData.centerEdgeVertices.vertex5
                ) * (1f / 3f),
                hexOuterRadius,
                wrapSize
                );
        }

        return(triangulationData);
    }
        public Hex Step(
            HexAdjacencyGraph adjacencyGraph,
            ref RiverDigraph riverDigraph,
            float extraLakeProbability,
            float hexOuterRadius,
            int waterLevel
            )
        {
            if (RiverHead.IsUnderwater)
            {
                return(null);
            }

            int minNeighborElevation  = int.MaxValue;
            int minNeighborWaterLevel = int.MaxValue;

            List <HexDirections> flowDirections = new List <HexDirections>();
            HexDirections        direction      = HexDirections.Northeast;

            for (
                HexDirections directionCandidate = HexDirections.Northeast;
                directionCandidate <= HexDirections.Northwest;
                directionCandidate++
                )
            {
                Hex neighborInDirection =
                    adjacencyGraph.TryGetNeighborInDirection(
                        RiverHead,
                        directionCandidate
                        );

                if (!neighborInDirection || River.Contains(neighborInDirection))
                {
                    continue;
                }

                if (neighborInDirection.elevation < minNeighborElevation)
                {
                    minNeighborElevation  = neighborInDirection.elevation;
                    minNeighborWaterLevel = neighborInDirection.WaterLevel;
                }

                // If the direction points to the river origin, or to a
                // neighbor which already has an incoming river, continue.
                if (
                    neighborInDirection == RiverHead ||
                    riverDigraph.HasIncomingRiver(neighborInDirection)
                    )
                {
                    continue;
                }

                int delta =
                    neighborInDirection.elevation - RiverHead.elevation;

                // If the elevation in the given direction is positive,
                // continue.
                if (delta > 0)
                {
                    continue;
                }

                // If the direction points away from the river origin and
                // any neighbors which already have an incoming river, and
                // the elevation in the given direction is negative or
                // zero, and the neighbor has an outgoing river, branch
                // river in this direction.
                if (
                    riverDigraph.HasOutgoingRiver(neighborInDirection)
                    )
                {
                    SetOutgoingRiver(
                        RiverHead,
                        neighborInDirection,
                        directionCandidate,
                        ref riverDigraph
                        );

                    River.Add(neighborInDirection);
                    return(neighborInDirection);
                }

                // If the direction points away from the river origin and
                // any neighbors which already have an incoming river, and
                // the elevation in the given direction is not positive,
                // and the neighbor does not have an outgoing river in the
                // given direction...

                // If the direction is a decline, make the probability for
                // the branch 4 / 5.
                if (delta < 0)
                {
                    flowDirections.Add(directionCandidate);
                    flowDirections.Add(directionCandidate);
                    flowDirections.Add(directionCandidate);
                }

                // If the rivers local length is 1, and the direction does
                // not result in a slight river bend, but rather a straight
                // river or a corner river, make the probability of the
                // branch 2 / 5
                if (
                    River.Count == 1 ||
                    (directionCandidate != direction.NextClockwise2() &&
                     directionCandidate != direction.PreviousClockwise2())
                    )
                {
                    flowDirections.Add(directionCandidate);
                }

                flowDirections.Add(directionCandidate);
            }

            // If there are no candidates for branching the river...
            if (flowDirections.Count == 0)
            {
                // If the river contains only the river origin...
                if (River.Count == 1)
                {
                    // Do nothing and return null
                    return(null);
                }

                // If the hex is surrounded by hexes at a higher elevation,
                // set the water level of the hex to the minium elevation
                // of all neighbors.
                if (minNeighborElevation >= RiverHead.elevation)
                {
                    RiverHead.WaterLevel = RiverHead.elevation;

                    // If the hex is of equal elevation to a neighbor with
                    // a minimum elevation, lower the current hexes
                    // elevation to one below the minimum elevation of all
                    // of its neighbors so that it becomes a small lake
                    // that the river feeds into, and then break out of the
                    // while statement terminating the river in a lake
                    // rather than into the ocean.
                    if (minNeighborElevation == RiverHead.elevation)
                    {
                        RiverHead.SetElevation(
                            minNeighborElevation - 1,
                            hexOuterRadius,
                            _hexMap.WrapSize
                            );
                    }
                }

                return(null);
            }

            direction = flowDirections[
                Random.Range(0, flowDirections.Count)
                        ];

            Hex neighborInRandomDirection =
                adjacencyGraph.TryGetNeighborInDirection(
                    RiverHead,
                    direction
                    );

            SetOutgoingRiver(
                RiverHead,
                neighborInRandomDirection,
                direction,
                ref riverDigraph
                );

            // If the hex is lower than the minimum elevation of its
            // neighbors assign a lake based on a specified probability.
            if (
                minNeighborElevation >= RiverHead.elevation &&
                Random.value < extraLakeProbability
                )
            {
                RiverHead.WaterLevel = RiverHead.elevation;

                RiverHead.SetElevation(
                    minNeighborElevation - 1,
                    hexOuterRadius,
                    _hexMap.WrapSize
                    );
            }

            River.Add(neighborInRandomDirection);
            return(neighborInRandomDirection);
        }