예제 #1
0
    public Price GetRewardPerTurnOfType(HexEdgeType hexEdgeType)
    {
        foreach (var priceConfiguration in RewardPerTurnConfigurations)
        {
            if (priceConfiguration.HexEdgeType == hexEdgeType)
            {
                return(priceConfiguration.Price);
            }
        }

        throw new NotImplementedException();
    }
예제 #2
0
    public int GetChanceForType(HexEdgeType hexEdgeType)
    {
        foreach (var edgeTypeChance in EdgeTypeChances)
        {
            if (edgeTypeChance.HexEdgeType == hexEdgeType)
            {
                return(edgeTypeChance.Chance);
            }
        }

        throw new NotImplementedException();
    }
예제 #3
0
    private void Flood(HexCell cell, bool OceanWater, bool LakeWater)
    {
        cell.SetTerrain(new Terrain(0, true, 1, TerrainType.OceanWater, 0));
        cell.Elevation = 0;

        List <HexCell> frontier = new List <HexCell>();

        frontier.Add(cell);
        while (frontier.Count > 0)
        {
            HexCell current = frontier[0];
            frontier.RemoveAt(0);
            for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++)
            {
                //cells ignored
                HexCell neighbor = current.GetNeighbor(d);

                if (neighbor == null || neighbor.IsUnderwater)
                {
                    continue;
                }
                float x = UnityEngine.Random.Range(0.0f, 1.0f);
                if (LakeWater)
                {
                    if (x <= lakeWaterChance)
                    {
                        frontier.Add(neighbor);
                        neighbor.SetTerrain(new Terrain(0, true, 1, TerrainType.LakeWater, 0));
                        neighbor.Elevation = 0;
                    }
                }
                HexEdgeType edgeType = current.GetEdgeType(neighbor);
                if (edgeType == HexEdgeType.Cliff)
                {
                    continue;
                }

                if (neighbor.Elevation <= 1)
                {
                    if (OceanWater)
                    {
                        if (x <= oceanWaterChance)
                        {
                            frontier.Add(neighbor);
                            neighbor.SetTerrain(new Terrain(0, true, 1, TerrainType.OceanWater, 0));
                            neighbor.Elevation = 0;
                        }
                    }
                }
            }
        }
    }
예제 #4
0
    void TriangulateCorner(
        Vector3 bottom, HexCell bottomCell,
        Vector3 left, HexCell leftCell,
        Vector3 right, HexCell rightCell)
    {
        HexEdgeType leftEdgeType  = bottomCell.GetEdgeType(leftCell);
        HexEdgeType rightEdgeType = bottomCell.GetEdgeType(rightCell);

        if (leftEdgeType == HexEdgeType.Slope)
        {
            if (rightEdgeType == HexEdgeType.Slope)
            {
                TriangulateCornerTerraces(bottom, bottomCell, left, leftCell, right, rightCell);
            }
            else if (rightEdgeType == HexEdgeType.Flat)
            {
                TriangulateCornerTerraces(left, leftCell, right, rightCell, bottom, bottomCell);
            }
            else
            {
                TriangulateCornerTerracesCliff(bottom, bottomCell, left, leftCell, right, rightCell);
            }
        }
        else if (rightEdgeType == HexEdgeType.Slope)
        {
            if (leftEdgeType == HexEdgeType.Flat)
            {
                TriangulateCornerTerraces(right, rightCell, bottom, bottomCell, left, leftCell);
            }
            else
            {
                TriangulateCornerTerraces(bottom, bottomCell, left, leftCell, right, rightCell);
            }
        }
        else if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope)
        {
            if (leftCell.Elevation < rightCell.Elevation)
            {
                TriangulateCornerCliffTerraces(right, rightCell, bottom, bottomCell, left, leftCell);
            }
            else
            {
                TriangulateCornerTerracesCliff(left, leftCell, right, rightCell, bottom, bottomCell);
            }
        }
        else
        {
            terrain.AddTriangle(bottom, left, right);
            terrain.AddTriangleColor(bottomCell.Color, leftCell.Color, rightCell.Color);
        }
        features.AddWall(bottom, bottomCell, left, leftCell, right, rightCell);
    }
예제 #5
0
    private void TriangulateCorner(Vector3 bottom, HexCell bottomCell, Vector3 left, HexCell leftCell, Vector3 right,
                                   HexCell rightCell)
    {
        HexEdgeType leftEdgeType  = bottomCell.GetEdgeType(leftCell);
        HexEdgeType rightEdgeType = bottomCell.GetEdgeType(rightCell);

        if (leftEdgeType == HexEdgeType.SLOPE)
        {
            if (rightEdgeType == HexEdgeType.SLOPE)
            {
                TriangulateCornerTerraces(bottom, bottomCell, left, leftCell, right, rightCell);
            }
            else if (rightEdgeType == HexEdgeType.FLAT)
            {
                TriangulateCornerTerraces(left, leftCell, right, rightCell, bottom, bottomCell);
            }
            else
            {
                TriangulateCornerTerracesCliff(bottom, bottomCell, left, leftCell, right, rightCell);
            }
        }
        else if (rightEdgeType == HexEdgeType.SLOPE)
        {
            if (leftEdgeType == HexEdgeType.FLAT)
            {
                TriangulateCornerTerraces(right, rightCell, bottom, bottomCell, left, leftCell);
            }
            else
            {
                TriangulateCornerCliffTerraces(bottom, bottomCell, left, leftCell, right, rightCell);
            }
        }
        else if (leftCell.GetEdgeType(rightCell) == HexEdgeType.SLOPE)
        {
            if (leftCell.Elevation < rightCell.Elevation)
            {
                TriangulateCornerCliffTerraces(right, rightCell, bottom, bottomCell, left, leftCell);
            }
            else
            {
                TriangulateCornerTerracesCliff(left, leftCell, right, rightCell, bottom, bottomCell);
            }
        }
        else
        {
            AddTriangle(bottom, left, right);
            AddTriangleColor(bottomCell.color, leftCell.color, rightCell.color);
        }
    }
예제 #6
0
    //添加连接三角形并阶梯化
    void TriangulateCorner(Vector3 bottom, HexCell bottomCell, Vector3 left, HexCell leftCell, Vector3 right, HexCell rightCell)
    {
        //AddTriangle(bottom, left, right);
        //AddTriangleColor(bottomCell.Color, leftCell.Color, rightCell.Color);
        //bottom最低,然后以顺时针排列
        //注意考虑渲染顶点顺时针排列
        HexEdgeType leftEdgeType  = bottomCell.GetEdgeType(leftCell);
        HexEdgeType rightEdgeType = bottomCell.GetEdgeType(rightCell);

        if (leftEdgeType == HexEdgeType.Flat && rightEdgeType == HexEdgeType.Flat)
        {
            TriangulateCornerNoTerraces(bottom, bottomCell, left, leftCell, right, rightCell);
            //AddTriangle(bottom, left, right);
            //AddTriangleColor(bottomCell.Color, leftCell.Color, rightCell.Color);
        }
        else if (leftEdgeType == HexEdgeType.Flat && rightEdgeType == HexEdgeType.Slope)
        {
            TriangulateCornerFlatWithSlope(bottom, bottomCell, left, leftCell, right, rightCell);
        }
        else if (leftEdgeType == HexEdgeType.Slope && rightEdgeType == HexEdgeType.Flat)
        {
            TriangulateCornerFlatWithSlope(right, rightCell, bottom, bottomCell, left, leftCell);
        }
        else if (leftEdgeType == HexEdgeType.Flat && rightEdgeType == HexEdgeType.Cliff)
        {
            TriangulateCornerNoTerraces(bottom, bottomCell, left, leftCell, right, rightCell);
        }
        else if (leftEdgeType == HexEdgeType.Cliff && rightEdgeType == HexEdgeType.Flat)
        {
            TriangulateCornerNoTerraces(right, rightCell, bottom, bottomCell, left, leftCell);
        }
        else if (leftEdgeType == HexEdgeType.Slope && rightEdgeType == HexEdgeType.Slope)
        {
            TriangulateCornerSlopeWithSlope(bottom, bottomCell, left, leftCell, right, rightCell);
        }
        else if (leftEdgeType == HexEdgeType.Slope && rightEdgeType == HexEdgeType.Cliff)
        {
            TriangulateSlopeWithCliff(bottom, bottomCell, left, leftCell, right, rightCell);
        }
        else if (leftEdgeType == HexEdgeType.Cliff && rightEdgeType == HexEdgeType.Slope)
        {
            TriangulateSlopeWithCliff(bottom, bottomCell, left, leftCell, right, rightCell);
        }
        else if (leftEdgeType == HexEdgeType.Cliff && rightEdgeType == HexEdgeType.Cliff)
        {
            TriangulateCornerNoTerraces(bottom, bottomCell, left, leftCell, right, rightCell);
        }
    }
예제 #7
0
    public int GetMoveCost(HexCell fromCell, HexCell toCell, HexDirection direction)
    {
        HexEdgeType edgeType = fromCell.GetEdgeType(toCell);

        if (edgeType == HexEdgeType.Cliff)
        {
            return(-1);
        }

        int moveCost;

        moveCost = edgeType == HexEdgeType.Flat ? 1 : 2;

        moveCost += toCell.terrainType.GetMoveCost();

        return(moveCost);
    }
예제 #8
0
    public Resource GetResources(HexEdgeType hexEdgeType)
    {
        switch (hexEdgeType)
        {
        case HexEdgeType.Wood:
            return(Wood);

        case HexEdgeType.Stone:
            return(Stone);

        case HexEdgeType.Gold:
            return(Gold);

        case HexEdgeType.Food:
            return(Food);
        }

        throw new NotImplementedException();
    }
예제 #9
0
    void TriangulateCorner(Vector3 bottom, HexCell bottomCell,
                           Vector3 left, HexCell leftCell,
                           Vector3 right, HexCell rightCell)
    {
        HexEdgeType leftEdgeType  = bottomCell.GetEdgeType(leftCell);
        HexEdgeType rightEdgeType = bottomCell.GetEdgeType(rightCell);

        if (leftEdgeType == HexEdgeType.Slope)
        {
            if (rightEdgeType == HexEdgeType.Slope)
            {
                TriangulateCornerTerraces(
                    bottom, bottomCell, left, leftCell, right, rightCell
                    );
                return;
            }
            if (rightEdgeType == HexEdgeType.Flat)
            {
                TriangulateCornerTerraces(
                    left, leftCell, right, rightCell, bottom, bottomCell
                    );
                return;
            }
            TriangulateCornerTerracesCliff(
                bottom, bottomCell, left, leftCell, right, rightCell
                );
            return;
        }
        if (rightEdgeType == HexEdgeType.Slope)
        {
            if (leftEdgeType == HexEdgeType.Flat)
            {
                TriangulateCornerTerraces(
                    right, rightCell, bottom, bottomCell, left, leftCell
                    );
                return;
            }
        }

        AddTriangle(bottom, left, right);
        AddTriangleColor(bottomCell.color, leftCell.color, rightCell.color);
    }
예제 #10
0
    public int GetMoveCost(HexCell fromCell, HexCell toCell, HexDirection dir)
    {
        HexEdgeType edgeType        = fromCell.GetEdgeType(toCell);
        bool        roadThroughEdge = fromCell.HasRoadThroughEdge(dir);

        if (toCell.IsUnderwater || toCell.HexUnit != null)
        {
            return(-1);
        }

        if (edgeType == HexEdgeType.Cliff)
        {
            return(-1);
        }

        if (!roadThroughEdge && fromCell.Walled != toCell.Walled)
        {
            return(-1);
        }

        int moveCost = 1;

        // fast travel via roads.
        if (roadThroughEdge)
        {
            moveCost = 1;
        }
        else
        {
            moveCost  = edgeType == HexEdgeType.Flat ? 5 : 10;
            moveCost += toCell.UrbanDensityLevel;
            moveCost += toCell.FarmDensityLevel;
            moveCost += toCell.PlantDensityLevel;
        }
        return(moveCost);
    }
        /* Triangulate Corner */
        private void TriangulateCorner(Vector3 bottom, HexCell bottomCell, Vector3 left, HexCell leftCell, Vector3 right, HexCell rightCell)
        {
            HexEdgeType leftEdgeType  = bottomCell.GetEdgeType(leftCell);
            HexEdgeType rightEdgeType = bottomCell.GetEdgeType(rightCell);

            if (leftEdgeType == HexEdgeType.Slope)
            {
                if (rightEdgeType == HexEdgeType.Slope)
                {
                    TriangulateCornerTerraces(bottom, bottomCell, left, leftCell, right, rightCell);
                }
                else if (rightEdgeType == HexEdgeType.Flat)
                {
                    TriangulateCornerTerraces(left, leftCell, right, rightCell, bottom, bottomCell);
                    return;
                }

                else
                {
                    TriangulateCornerTerracesCliff(bottom, bottomCell, left, leftCell, right, rightCell);
                }
            }
            else if (rightEdgeType == HexEdgeType.Slope)
            {
                if (leftEdgeType == HexEdgeType.Flat)
                {
                    TriangulateCornerTerraces(right, rightCell, bottom, bottomCell, left, leftCell);
                }
                else
                {
                    TriangulateCornerCliffTerraces(bottom, bottomCell, left, leftCell, right, rightCell);
                }
            }
            else if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope)
            {
                if (leftCell.Elevation < rightCell.Elevation)
                {
                    TriangulateCornerCliffTerraces(right, rightCell, bottom, bottomCell, left, leftCell);
                }
                else
                {
                    TriangulateCornerTerracesCliff(left, leftCell, right, rightCell, bottom, bottomCell);
                }
            }
            else
            {
                if (HexMeshUtility.UseTextures)
                {
                    m_terrainMesh.AddTriangleColor(m_red, m_green, m_blue);

                    Vector3 types;
                    types.x = bottomCell.TerrainTypeIndex;
                    types.y = leftCell.TerrainTypeIndex;
                    types.z = rightCell.TerrainTypeIndex;
                    m_terrainMesh.AddTriangleTerrainTypes(types);
                }
                else
                {
                    m_terrainMesh.AddTriangleColor(bottomCell.Color, leftCell.Color, rightCell.Color);
                }

                m_terrainMesh.AddTriangle(bottom, left, right);
            }
        }
예제 #12
0
    /// <summary>
    /// 阶梯化矩形连接区域
    /// </summary>
    /// <param name="beginLeft">cell到neighbor连接区域的第一个起点</param>
    /// <param name="beginRight">cell到neighbor连接区域的第二个起点</param>
    /// <param name="beginCell">cell自身实例,用于获取颜色</param>
    /// <param name="endLeft">连接区域 连接到的neighbor的第一个终点</param>
    /// <param name="endRight">连接区域 连接到的neighbor的第二个终点</param>
    /// <param name="endCell">连接到的neighbor实例,用于获取颜色</param>
    //private void TriangulateEdgeTerraces(
    //Vector3 beginLeft, Vector3 beginRight, HexCell beginCell,
    //Vector3 endLeft, Vector3 endRight, HexCell endCell)
    //{
    //    //这里先生成阶梯的第一个矩形面片。通过给定插值来计算出矩形面片的另外两个顶点
    //    Vector3 v4 = HexMetrics.TerraceLerp(beginLeft, endLeft, 1);
    //    Vector3 v5 = HexMetrics.TerraceLerp(beginRight, endRight, 1);
    //    Color c2 = HexMetrics.TerraceLerp(beginCell.Color, endCell.Color, 1);

    //    AddQuad(beginLeft, beginRight, v4, v5);
    //    AddQuadColor(beginCell.Color, c2);

    //    //阶梯的其他矩形面片,可以通过循环来生成
    //    //旧的矩形面片终点V3 V4,就是新面片的起点 V1 V2
    //    //然后再利用插值计算新面片的终点即可
    //    //颜色计算同理
    //    for (int i = 2; i < HexMetrics.terraceSteps; i++)
    //    {
    //        Vector3 v1 = v4;
    //        Vector3 v2 = v5;
    //        Color c1 = c2;
    //        v4 = HexMetrics.TerraceLerp(beginLeft, endLeft, i);
    //        v5 = HexMetrics.TerraceLerp(beginRight, endRight, i);
    //        c2 = HexMetrics.TerraceLerp(beginCell.Color, endCell.Color, i);
    //        AddQuad(v1, v2, v4, v5);
    //        AddQuadColor(c1, c2);
    //    }

    //    //连接阶梯的剩余区域
    //    AddQuad(v4, v5, endLeft, endRight);
    //    AddQuadColor(c2, endCell.Color);
    //}

    /// <summary>
    /// 构建三角形连接区域的方法
    /// 判断相邻3个cell高低的工作,在TriangulateConnection方法中实现了,这里只负责创建连接区域
    /// 注意,TriangulateConnection方法只是对入参的顺序做了调整,但是并没有告知3个cell之间相对的连接类型
    /// 所以要在这个方法中对连接类型进行判断,这样才能决三角形连接区域定用什么方式进行三角剖分
    /// </summary>
    /// <param name="bottom">bottom cell的坐标</param>
    /// <param name="bottomCell">bottom cell的实例</param>
    /// <param name="left">left cell的坐标</param>
    /// <param name="leftCell">left cell的实例</param>
    /// <param name="right">right cell的坐标</param>
    /// <param name="rightCell">right cell的实例</param>
    private void TriangulateCorner(Vector3 bottom, HexCell bottomCell, Vector3 left, HexCell leftCell, Vector3 right, HexCell rightCell)
    {
        //这里先获取Left和Right两个cell,相较于Bottom cell的高度类型,这样才能决定怎样做三角剖分
        HexEdgeType leftEdgeType  = bottomCell.GetEdgeType(leftCell);
        HexEdgeType rightEdgeType = bottomCell.GetEdgeType(rightCell);

        //这里通过获取的Left和Right 相较于Bottom的连接类型进行判断,具体三个cell的高度关系
        //判断完成后,直接调用对应的方法构建三角形连接区域,而不使用之前通用的方法构建
        if (leftEdgeType == HexEdgeType.Slope)
        {
            //这是SSF类型正常情况,即2个cell高度为1,一个cell高度为0
            if (rightEdgeType == HexEdgeType.Slope)
            {
                //这里判断为SSF类型
                TriangulateCornerTerraces(bottom, bottomCell, left, leftCell, right, rightCell);
            }

            //SSF变体1 即2个cell高度为0,一个cell高度为1,且高度为1的cell在左侧
            else if (rightEdgeType == HexEdgeType.Flat)
            {
                TriangulateCornerTerraces(left, leftCell, right, rightCell, bottom, bottomCell);
            }
            else
            {
                //Slope-Cliff连接类型
                //bottom最低,left比bottom高1,right比bottom高1及以上
                TriangulateCornerTerracesCliff(bottom, bottomCell, left, leftCell, right, rightCell);
            }
        }

        else if (rightEdgeType == HexEdgeType.Slope)
        {
            //SSF变体2 即2个cell高度为0,一个cell高度为1,且高度为1的cell在右侧
            if (leftEdgeType == HexEdgeType.Flat)
            {
                TriangulateCornerTerraces(right, rightCell, bottom, bottomCell, left, leftCell);
            }
            else
            {
                //Slope-Cliff连接 镜像 类型
                //bottom最低,right比bottom高1,left比right高1及以上
                TriangulateCornerCliffTerraces(bottom, bottomCell, left, leftCell, right, rightCell);
            }
        }

        //bottom最低,与left和right高差都大于1,并且left和right高差为1,称为 CCS类型
        //如果left比right高1,那么就是CCSL,反之right比left高1,那就是CCSR
        else if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope)
        {
            //CCSR
            if (leftCell.Elevation < rightCell.Elevation)
            {
                TriangulateCornerCliffTerraces(right, rightCell, bottom, bottomCell, left, leftCell);
            }
            //CCSL
            else
            {
                TriangulateCornerTerracesCliff(left, leftCell, right, rightCell, bottom, bottomCell);
            }
        }
        else
        {
            //这里先使用旧的方法来构建三角形连接区域,也就是没有阶梯化的那种
            //经过连接类型判断后,这个方法就会被代替掉
            AddTriangle(bottom, left, right);
            AddTriangleColor(bottomCell.Color, leftCell.Color, rightCell.Color);
        }
    }
예제 #13
0
    public void ShowPossibleMovement(HexCell location, HexCell currentCell, int speed)
    {
        reachCalculated = false;
        for (int i = 0; i < cells.Length; i++)
        {
            cells[i].Distance = int.MaxValue;
        }

        reachableCells.Clear();
        List <HexCell> frontier = ListPool <HexCell> .Get();

        currentCell.Distance = 0;
        frontier.Add(currentCell);

        while (frontier.Count > 0)
        {
            HexCell current = frontier[0];
            frontier.RemoveAt(0);
            for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++)
            {
                HexCell neighbor = current.GetNeighbor(d);

                if (neighbor == null || neighbor.Distance != int.MaxValue)
                {
                    continue;
                }

                if (neighbor.IsUnderwater || neighbor.Unit /*&& player cannot walk on water*/)
                {
                    continue;
                }

                HexEdgeType edgeType = current.GetEdgeType(neighbor);
                if (edgeType == HexEdgeType.Cliff /*&& player cannot fly*/)
                {
                    continue;
                }

                int moveCost;
                if (current.HasRoadThroughEdge(d))
                {
                    moveCost = 1;
                }
                else if (current.Walled != neighbor.Walled)
                {
                    continue;
                }
                else
                {
                    moveCost  = edgeType == HexEdgeType.Flat ? 3 : 5;
                    moveCost += (neighbor.UrbanLevel + neighbor.FarmLevel + neighbor.PlantLevel) / 2;
                }

                int distance = current.Distance + moveCost;

                if (neighbor.Distance == int.MaxValue)
                {
                    neighbor.Distance = distance;
                }
                else if (distance < neighbor.Distance)
                {
                    neighbor.Distance = distance;
                }
                if (neighbor.Distance <= speed)
                {
                    frontier.Add(neighbor);
                    frontier.Sort((x, y) => x.Distance.CompareTo(y.Distance));
                    reachableCells.Add(neighbor);
                }
            }

            reachCalculated = true;
            foreach (HexCell c in reachableCells)
            {
                c.EnableHighlight(Color.green);
            }
        }
        ListPool <HexCell> .Add(frontier);

        frontier = null;
    }
    /// <summary>
    /// Given the bottom, left and right cell of the tripple connection triangle identify the edge case and build the
    /// geometry.
    /// </summary>
    void TriangulateCorner(Vector3 bottom, HexCell bottomCell, Vector3 left, HexCell leftCell, Vector3 right, HexCell rightCell)
    {
        HexEdgeType leftEdgeType  = bottomCell.GetEdgeType(leftCell);
        HexEdgeType rightEdgeType = bottomCell.GetEdgeType(rightCell);

        if (leftEdgeType == HexEdgeType.Slope)
        {
            if (rightEdgeType == HexEdgeType.Slope)               // SSF
            {
                TriangulateCornerTerraces(
                    bottom, bottomCell, left, leftCell, right, rightCell
                    );
            }
            else if (rightEdgeType == HexEdgeType.Flat)               // SFS
            {
                TriangulateCornerTerraces(
                    left, leftCell, right, rightCell, bottom, bottomCell
                    );
            }
            else
            {
                TriangulateCornerTerracesCliff(                 // SCS and SCC
                    bottom, bottomCell, left, leftCell, right, rightCell
                    );
            }
        }
        else if (rightEdgeType == HexEdgeType.Slope)
        {
            if (leftEdgeType == HexEdgeType.Flat)               // FSS
            {
                TriangulateCornerTerraces(
                    right, rightCell, bottom, bottomCell, left, leftCell
                    );
            }
            else               // CSS & CSC
            {
                TriangulateCornerCliffTerraces(
                    bottom, bottomCell, left, leftCell, right, rightCell
                    );
            }
        }
        else if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope)           // CCSR & CCSL
        {
            if (leftCell.Elevation < rightCell.Elevation)
            {
                TriangulateCornerCliffTerraces(
                    right, rightCell, bottom, bottomCell, left, leftCell
                    );
            }
            else
            {
                TriangulateCornerTerracesCliff(
                    left, leftCell, right, rightCell, bottom, bottomCell
                    );
            }
        }
        else                                          // Simple triangle takes care of FFF, CCF, CCCR, and CCCL
        {
            Terrain.AddTriangle(bottom, left, right); // Geometry
            // Cell data
            Vector3 indices;
            indices.x = bottomCell.Index;
            indices.y = leftCell.Index;
            indices.z = rightCell.Index;
            Terrain.AddTriangleCellData(indices, weights1, weights2, weights3);
        }

        // * If necessary feature manager creates a wall connection in this corner
        Features.AddWall(bottom, bottomCell, left, leftCell, right, rightCell);
    }
예제 #15
0
        private bool Search(HexCell fromCell, HexCell toCell, int speed)
        {
            searchFrontierPhase += 2;
            if (searchFrontier == null)
            {
                searchFrontier = new PriorityQueue <HexCell>((x, y) => x.SearchPriority.CompareTo(y.SearchPriority));
            }
            else
            {
                searchFrontier.Clear();
            }

            fromCell.SearchPhase = searchFrontierPhase;
            fromCell.Distance    = 0;
            searchFrontier.Enqueue(fromCell);
            while (searchFrontier.Count > 0)
            {
                HexCell current = searchFrontier.Dequeue();
                current.SearchPhase += 1;
                if (current == toCell)
                {
                    return(true);
                }

                int currentTurn = (current.Distance - 1) / speed;

                for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++)
                {
                    HexCell neighbor = current.GetNeighbor(d);
                    if (neighbor == null || neighbor.SearchPhase > searchFrontierPhase)
                    {
                        continue;
                    }
                    if (neighbor.IsUnderwater || neighbor.Unit)
                    {
                        continue;
                    }
                    HexEdgeType edgeType = current.GetEdgeType(neighbor);
                    if (edgeType == HexEdgeType.Cliff)
                    {
                        continue;
                    }

                    int moveCost;
                    if (current.HasRoadThroughEdge(d))
                    {
                        moveCost = 1;
                    }
                    else if (current.Walled != neighbor.Walled)
                    {
                        continue;
                    }
                    else
                    {
                        moveCost  = edgeType == HexEdgeType.Flat ? 5 : 10;
                        moveCost += neighbor.UrbanLevel + neighbor.FarmLevel + neighbor.PlantLevel;
                    }

                    int distance = current.Distance + moveCost;
                    int turn     = (distance - 1) / speed;
                    if (turn > currentTurn)
                    {
                        distance = turn * speed + moveCost;
                    }

                    if (neighbor.SearchPhase < searchFrontierPhase)
                    {
                        neighbor.SearchPhase     = searchFrontierPhase;
                        neighbor.Distance        = distance;
                        neighbor.PathFrom        = current;
                        neighbor.SearchHeuristic = neighbor.coordinates.DistanceTo(toCell.coordinates);
                        searchFrontier.Enqueue(neighbor);
                    }
                    else if (distance < neighbor.Distance)
                    {
                        neighbor.Distance = distance;
                        searchFrontier.Change(neighbor);
                    }
                }
            }
            return(false);
        }
예제 #16
0
    /// <summary>
    /// 角落三角面
    /// 固定顺时针顺序,即底-左-右
    /// </summary>
    /// <param name="bottom"></param>
    /// <param name="bottomCell"></param>
    /// <param name="left"></param>
    /// <param name="leftCell"></param>
    /// <param name="right"></param>
    /// <param name="rightCell"></param>
    void TriangulateCorner(
        Vector3 bottom, HexCell bottomCell,
        Vector3 left, HexCell leftCell,
        Vector3 right, HexCell rightCell
        )
    {
        HexEdgeType leftEdgeType  = bottomCell.GetEdgeType(leftCell);
        HexEdgeType rightEdgeType = bottomCell.GetEdgeType(rightCell);

        if (leftEdgeType == HexEdgeType.Slope)
        {
            if (rightEdgeType == HexEdgeType.Slope)
            {
                //三角形样式的梯田,一个点在下,两个点在上的梯田样式
                TriangulateCornerTerraces(
                    bottom, bottomCell, left, leftCell, right, rightCell
                    );
            }
            else if (rightEdgeType == HexEdgeType.Flat)
            {
                //三角形样式的梯田,一个点在上,两个点在下的梯田样式
                TriangulateCornerTerraces(
                    left, leftCell, right, rightCell, bottom, bottomCell
                    );
            }
            else
            {
                //梯田悬崖是角落
                TriangulateCornerTerracesCliff(
                    bottom, bottomCell, left, leftCell, right, rightCell
                    );
            }
        }
        else if (rightEdgeType == HexEdgeType.Slope)
        {
            if (leftEdgeType == HexEdgeType.Flat)
            {
                TriangulateCornerTerraces(
                    right, rightCell, bottom, bottomCell, left, leftCell
                    );
            }
            else
            {
                //悬崖梯田是角落
                TriangulateCornerCliffTerraces(
                    bottom, bottomCell, left, leftCell, right, rightCell
                    );
            }
        }
        else if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope)
        {
            if (leftCell.Elevation < rightCell.Elevation)
            {
                //悬崖梯田是角落
                TriangulateCornerCliffTerraces(
                    right, rightCell, bottom, bottomCell, left, leftCell
                    );
            }
            else
            {
                TriangulateCornerTerracesCliff(
                    left, leftCell, right, rightCell, bottom, bottomCell
                    );
            }
        }
        else
        {
            //高度全相同,即一个三角面完成
            terrain.AddTriangle(bottom, left, right);
            terrain.AddTriangleColor(bottomCell.Color, leftCell.Color, rightCell.Color);
        }
    }
예제 #17
0
    void TriangulateCorner(Vector3 bottom, HexCell bottomCell, Vector3 left, HexCell leftCell, Vector3 right, HexCell rightCell)
    {
        //find edge types of neighboring edges
        HexEdgeType leftEdgeType  = bottomCell.GetEdgeType(leftCell);
        HexEdgeType rightEdgeType = bottomCell.GetEdgeType(rightCell);

        if (leftEdgeType == HexEdgeType.Slope)
        {
            if (rightEdgeType == HexEdgeType.Slope)
            {
                // Slope, Slope Flat
                TriangulateCornerTerraces(bottom, bottomCell, left, leftCell, right, rightCell);
            }
            else if (rightEdgeType == HexEdgeType.Flat)
            {
                //Slope, Flat, Slope
                TriangulateCornerTerraces(left, leftCell, right, rightCell, bottom, bottomCell);
            }
            else
            {
                TriangulateCornerTerracesCliff(bottom, bottomCell, left, leftCell, right, rightCell);
            }
        }
        else if (rightEdgeType == HexEdgeType.Slope)
        {
            if (leftEdgeType == HexEdgeType.Flat)
            {
                // Flat, Slope, Slope
                TriangulateCornerTerraces(right, rightCell, bottom, bottomCell, left, leftCell);
            }
            else
            {
                TriangulateCornerCliffTerraces(bottom, bottomCell, left, leftCell, right, rightCell);
            }
        }
        else if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope)
        {
            if (leftCell.Elevation < rightCell.Elevation)
            {
                // Cliff, Cliff, Slope Right
                TriangulateCornerCliffTerraces(right, rightCell, bottom, bottomCell, left, leftCell);
            }
            else
            {
                // Cliff, Cliff, Slope Left
                TriangulateCornerTerracesCliff(left, leftCell, right, rightCell, bottom, bottomCell);
            }
        }
        else
        {
            // FFF, CCF, CCCR, and CCCL
            terrain.AddTriangle(bottom, left, right);
            terrain.AddTriangleColor(color1, color2, color3);

            Vector3 types;
            types.x = bottomCell.TerrainTypeIndex;
            types.y = leftCell.TerrainTypeIndex;
            types.z = rightCell.TerrainTypeIndex;
            terrain.AddTriangleTerrainTypes(types);
        }
        //features.AddWall(bottom, bottomCell, left, leftCell, right, rightCell);
    }
예제 #18
0
    void TriangulateCorner(
        Vector3 bottom, HexCell bottomCell,
        Vector3 left, HexCell leftCell,
        Vector3 right, HexCell rightCell
        )
    {
        // 顶点顺序为底部->左边->右边
        HexEdgeType leftEdgeType  = bottomCell.GetEdgeType(leftCell);
        HexEdgeType rightEdgeType = bottomCell.GetEdgeType(rightCell);

        // 根据边类型绘制角落
        if (leftEdgeType == HexEdgeType.Slope)
        {
            // SSF
            if (rightEdgeType == HexEdgeType.Slope)
            {
                TriangulateCornerTerraces(
                    bottom, bottomCell, left, leftCell, right, rightCell
                    );
            }
            // SFS
            else if (rightEdgeType == HexEdgeType.Flat)
            {
                TriangulateCornerTerraces(
                    left, leftCell, right, rightCell, bottom, bottomCell
                    );
            }
            // SCS和SCC
            else
            {
                TriangulateCornerTerracesCliff(
                    bottom, bottomCell, left, leftCell, right, rightCell
                    );
            }
        }
        else if (rightEdgeType == HexEdgeType.Slope)
        {
            // FSS
            if (leftEdgeType == HexEdgeType.Flat)
            {
                TriangulateCornerTerraces(
                    right, rightCell, bottom, bottomCell, left, leftCell
                    );
            }
            // CSS和CSC
            else
            {
                TriangulateCornerCliffTerraces(
                    bottom, bottomCell, left, leftCell, right, rightCell
                    );
            }
        }
        // CCSR和CCSL,悬崖悬崖斜坡,只剩下这种情况需要产生梯田
        else if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope)
        {
            if (leftCell.Elevation < rightCell.Elevation)
            {
                TriangulateCornerCliffTerraces(
                    right, rightCell, bottom, bottomCell, left, leftCell
                    );
            }
            else
            {
                TriangulateCornerTerracesCliff(
                    left, leftCell, right, rightCell, bottom, bottomCell
                    );
            }
        }
        else
        {
            AddTriangle(bottom, left, right);
            AddTriangleColor(bottomCell.Color, leftCell.Color, rightCell.Color);
        }
    }
예제 #19
0
    public static Corner Build(HexCell begin, HexCell left, HexCell right, HexDirection leftDirection)
    {
        Vector3 beginCorner = begin.Position + HexMetrics.GetSecondSolidCorner(leftDirection);
        Vector3 leftCorner  = left.Position + HexMetrics.GetFirstSolidCorner(leftDirection.Opposite());
        Vector3 rightCorner = right.Position + HexMetrics.GetSecondSolidCorner(leftDirection.Previous2());

        HexEdgeType leftEdgeType  = HexMetrics.GetEdgeType(begin.Elevation, left.Elevation);
        HexEdgeType rightEdgeType = HexMetrics.GetEdgeType(begin.Elevation, right.Elevation);
        HexEdgeType endEdgeType   = HexMetrics.GetEdgeType(left.Elevation, right.Elevation);

        Corner corner;

        if (leftEdgeType == HexEdgeType.Slope)
        {
            if (rightEdgeType == HexEdgeType.Slope)
            {
                corner = new TerracesCorner(
                    beginCorner, leftCorner, rightCorner,
                    begin, left, right
                    );
            }
            else if (rightEdgeType == HexEdgeType.Flat)
            {
                corner = new TerracesCorner(
                    leftCorner, rightCorner, beginCorner,
                    left, right, begin
                    );
            }
            else
            {
                corner = new TerraceCliffCorner(
                    beginCorner, leftCorner, rightCorner,
                    begin, left, right
                    );
            }
        }
        else if (rightEdgeType == HexEdgeType.Slope)
        {
            if (leftEdgeType == HexEdgeType.Flat)
            {
                corner = new TerracesCorner(
                    rightCorner, beginCorner, leftCorner,
                    right, begin, left
                    );
            }
            else
            {
                corner = new CliffTerraceCorner(
                    beginCorner, leftCorner, rightCorner,
                    begin, left, right
                    );
            }
        }
        else if (endEdgeType == HexEdgeType.Slope)
        {
            if (left.Elevation < right.Elevation)
            {
                corner = new CliffTerraceCorner(
                    rightCorner, beginCorner, leftCorner,
                    right, begin, left
                    );
            }
            else
            {
                corner = new TerraceCliffCorner(
                    leftCorner, rightCorner, beginCorner,
                    left, right, begin
                    );
            }
        }
        else
        {
            corner = new FlatCorner(
                beginCorner, leftCorner, rightCorner,
                begin, left, right
                );
        }

        return(corner);
    }
예제 #20
0
    private void TriangulateCorner(
        Vector3 bottom, HexCell bottomCell,
        Vector3 left, HexCell leftCell,
        Vector3 right, HexCell rightCell
        )
    {
        HexEdgeType leftEdgeType  = bottomCell.GetEdgeType(leftCell);
        HexEdgeType rightEdgeType = bottomCell.GetEdgeType(rightCell);

        if (leftEdgeType == HexEdgeType.Slope)
        {
            switch (rightEdgeType)
            {
            case HexEdgeType.Slope:
                TriangulateCornerTerraces(
                    bottom, bottomCell, left, leftCell, right, rightCell
                    );
                break;

            case HexEdgeType.Flat:
                TriangulateCornerTerraces(
                    left, leftCell, right, rightCell, bottom, bottomCell
                    );
                break;

            case HexEdgeType.Cliff:
                TriangulateCornerTerracesCliff(
                    bottom, bottomCell, left, leftCell, right, rightCell
                    );
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
        else if (rightEdgeType == HexEdgeType.Slope)
        {
            if (leftEdgeType == HexEdgeType.Flat)
            {
                TriangulateCornerTerraces(
                    right, rightCell, bottom, bottomCell, left, leftCell
                    );
            }
            else
            {
                TriangulateCornerCliffTerraces(
                    bottom, bottomCell, left, leftCell, right, rightCell
                    );
            }
        }
        else if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope)
        {
            if (leftCell.Elevation < rightCell.Elevation)
            {
                TriangulateCornerCliffTerraces(
                    right, rightCell, bottom, bottomCell, left, leftCell
                    );
            }
            else
            {
                TriangulateCornerTerracesCliff(
                    left, leftCell, right, rightCell, bottom, bottomCell
                    );
            }
        }
        else
        {
            AddTriangle(bottom, left, right);
            AddTriangleColor(bottomCell.Color, leftCell.Color, rightCell.Color);
        }
    }
예제 #21
0
    bool Search(HexCell_Script fromCell, HexCell_Script toCell, int speed)
    {
        searchFrontierPhase += 2;

        if (searchFrontier == null)
        {
            searchFrontier = new HexCellPriorityQueue();
        }
        else
        {
            searchFrontier.Clear();
        }



        //WaitForSeconds delay = new WaitForSeconds(1 / 60f);
        fromCell.SearchPhase = searchFrontierPhase;
        fromCell.Distance    = 0;
        searchFrontier.Enqueue(fromCell);
        while (searchFrontier.Count > 0)
        {
            //yield return delay;
            HexCell_Script current = searchFrontier.Dequeue();
            current.SearchPhase += 1;

            if (current.SearchPhase == 10000)
            {
                Debug.LogError("Could not find Path after 10000 searches!");
                return(false);
            }

            if (current == toCell)
            {
                return(true);
            }


            int currentTurn = (current.Distance - 1) / speed;

            for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++)
            {
                HexCell_Script neighbor = current.GetNeighbor(d);
                if (neighbor == null ||
                    neighbor.SearchPhase > searchFrontierPhase)
                {
                    continue;
                }
                if (neighbor.IsUnderwater || neighbor.Unit)
                {
                    continue;
                }


                HexEdgeType edgeType = current.GetEdgeType(neighbor);
                if (edgeType == HexEdgeType.Cliff)
                {
                    continue;
                }


                int moveCost;
                if (current.HasRoadThroughEdge(d))
                {
                    moveCost = 1;
                }
                else if (current.Walled != neighbor.Walled)
                {
                    continue;
                }
                else
                {
                    moveCost  = edgeType == HexEdgeType.Flat ? 5 : 10;
                    moveCost += neighbor.UrbanLevel + neighbor.FarmLevel + neighbor.PlantLevel;
                }

                int distance = current.Distance + moveCost;
                int turn     = distance / speed;
                if (turn > currentTurn)
                {
                    distance = turn * speed + moveCost;
                }

                if (neighbor.SearchPhase < searchFrontierPhase)
                {
                    neighbor.SearchPhase = searchFrontierPhase;
                    neighbor.Distance    = distance;
                    //neighbor.SetLabel(turn.ToString());
                    neighbor.PathFrom        = current;
                    neighbor.SearchHeuristic = neighbor.coordinates.DistanceTo(toCell.coordinates);
                    searchFrontier.Enqueue(neighbor);
                }
                else if (distance < neighbor.Distance)
                {
                    int oldPriority = neighbor.SearchPriority;
                    neighbor.Distance = distance;
                    //neighbor.SetLabel(turn.ToString());
                    neighbor.PathFrom = current;
                    searchFrontier.Change(neighbor, oldPriority);
                }

                //searchFrontier.Sort((x, y) => x.SearchPriority.CompareTo(y.SearchPriority));
            }
        }
        return(false);
    }
예제 #22
0
    void TriangulatePoint(Vector3 bot, HexCell botCell, Vector3 left, HexCell leftCell, Vector3 right, HexCell rightCell)
    {
        HexEdgeType leftEdgeType  = botCell.GetEdgeType(leftCell);
        HexEdgeType rightEdgeType = botCell.GetEdgeType(rightCell);

        if (leftEdgeType == HexEdgeType.Slope)
        {
            if (rightEdgeType == HexEdgeType.Slope)
            {
                // B<L && B<R && L=R
                TriangulatePointTerraces(bot, botCell, left, leftCell, right, rightCell);
                return;
            }


            else if (rightEdgeType == HexEdgeType.Flat)
            {
                // B<L && B=R && L>R
                TriangulatePointTerraces(left, leftCell, right, rightCell, bot, botCell);
                return;
            }

            // B<L && B<<R && L<R
            TriangulatePointTerracesCliff(bot, botCell, left, leftCell, right, rightCell);
            return;
        }

        else if (rightEdgeType == HexEdgeType.Slope)
        {
            if (leftEdgeType == HexEdgeType.Flat)
            {
                // B=L && B<R && L<R
                TriangulatePointTerraces(right, rightCell, bot, botCell, left, leftCell);
                return;
            }

            // B<<L && B<R && L>R
            TriangulatePointCliffTerraces(bot, botCell, left, leftCell, right, rightCell);
            return;
        }

        else if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope)
        {
            if (leftCell.Elevation < rightCell.Elevation)
            {
                TriangulatePointCliffTerraces(right, rightCell, bot, botCell, left, leftCell);
            }
            else
            {
                TriangulatePointTerracesCliff(left, leftCell, right, rightCell, bot, botCell);
            }

            return;
        }

        // B=L && R=L && L=R, ALL FLAT
        terrain.AddTriangle(bot, left, right);
        Vector3 indices;

        indices.x = botCell.Index;
        indices.y = leftCell.Index;
        indices.z = rightCell.Index;
        terrain.AddTriangleCellData(indices, weights1, weights2, weights3);
    }
예제 #23
0
    bool Search(HexCell fromCell, HexCell toCell, int speed)
    {
        // Debug.Log(specificUIOption.WaterMoving + " In grid");
        searchFrontierPhase += 2;
        if (searchFrontier == null)
        {
            searchFrontier = new HexCellPriorityQueue();
        }
        else
        {
            searchFrontier.Clear();
        }

        fromCell.SearchPhase = searchFrontierPhase;
        fromCell.Distance    = 0;
        searchFrontier.Enqueue(fromCell);
        while (searchFrontier.Count > 0)
        {
            HexCell current = searchFrontier.Dequeue();
            current.SearchPhase += 1;

            if (current == toCell)
            {
                return(true);
            }

            int currentTurn = (current.Distance - 1) / speed;

            for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++)
            {
                HexCell neighbor = current.GetNeighbor(d);
                // gameUI.gameObject.AddComponent<HexGameUI>();

                if (neighbor == null || neighbor.SearchPhase > searchFrontierPhase)
                {
                    continue;
                }

                if (!gameManager.WaterMoving)
                {
                    if (neighbor.IsUnderwater || neighbor.Unit)
                    {
                        continue;
                    }
                }

                HexEdgeType edgeType = current.GetEdgeType(neighbor);
                if (edgeType == HexEdgeType.Cliff)
                {
                    continue;
                }


                int moveCost;

                if (current.HasRoadThroughEdge(d))
                {
                    moveCost = 1;
                }
                else if (current.Walled != neighbor.Walled)
                {
                    continue;
                }
                else
                {
                    moveCost  = edgeType == HexEdgeType.Flat ? 1 : 2;
                    moveCost += neighbor.UrbanLevel + neighbor.FarmLevel + neighbor.PlantLevel;
                }

                int distance = current.Distance + moveCost;
                int turn     = (distance - 1) / speed;

                if (turn == 0)
                {
                    // current.EnableValidation(Color.green);
                }

                if (turn > currentTurn)
                {
                    distance = turn * speed + moveCost;
                }

                if (neighbor.SearchPhase < searchFrontierPhase)
                {
                    neighbor.SearchPhase     = searchFrontierPhase;
                    neighbor.Distance        = distance;
                    neighbor.PathFrom        = current;
                    neighbor.SearchHeuristic = neighbor.coordinates.DistanceTo(toCell.coordinates);
                    searchFrontier.Enqueue(neighbor);
                }
                else if (distance < neighbor.Distance)
                {
                    int oldPriority = neighbor.SearchPriority;
                    neighbor.Distance = distance;
                    neighbor.PathFrom = current;
                    searchFrontier.Change(neighbor, oldPriority);
                }
            }
        }
        return(false);
    }
예제 #24
0
    void TriangulateCorner(
        Vector3 bottom, HexCell bottomCell,
        Vector3 left, HexCell leftCell,
        Vector3 right, HexCell rightCell
        )
    {
        HexEdgeType leftEdgeType  = bottomCell.GetEdgeType(leftCell);
        HexEdgeType rightEdgeType = bottomCell.GetEdgeType(rightCell);

        if (leftEdgeType == HexEdgeType.Slope)
        {
            if (rightEdgeType == HexEdgeType.Slope)
            {
                TriangulateCornerTerraces(
                    bottom, bottomCell, left, leftCell, right, rightCell
                    );
            }
            //如果右边缘是平坦的,那么我们必须从左开始而不是从底部开始倾斜。
            else if (rightEdgeType == HexEdgeType.Flat)
            {
                TriangulateCornerTerraces(
                    left, leftCell, right, rightCell, bottom, bottomCell
                    );
            }
            else
            {
                TriangulateCornerTerracesCliff(
                    bottom, bottomCell, left, leftCell, right, rightCell
                    );
            }
            return;
        }

        //如果左边缘是平坦的,那么我们必须从右开始。
        if (rightEdgeType == HexEdgeType.Slope)
        {
            if (leftEdgeType == HexEdgeType.Flat)
            {
                TriangulateCornerTerraces(
                    right, rightCell, bottom, bottomCell, left, leftCell
                    );
            }
            else
            {
                TriangulateCornerCliffTerraces(
                    bottom, bottomCell, left, leftCell, right, rightCell
                    );
            }
            return;
        }
        //底部单元格的两侧都有悬崖的情况
        if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope)
        {
            if (leftCell.Elevation < rightCell.Elevation)
            {
                TriangulateCornerCliffTerraces(
                    right, rightCell, bottom, bottomCell, left, leftCell
                    );
            }
            else
            {
                TriangulateCornerTerracesCliff(
                    left, leftCell, right, rightCell, bottom, bottomCell
                    );
            }
        }
        else
        {
            AddTriangle(bottom, left, right);
            AddTriangleColor(bottomCell.Color, leftCell.Color, rightCell.Color);
        }
    }
예제 #25
0
파일: HexGrid.cs 프로젝트: guccang/HexMap
    bool Search(HexCell fromCell, HexCell toCell, int speed)
    {
        searchFrontierPhase += 2;
        if (searchFrontier == null)
        {
            searchFrontier = new HexCellPriorityQueue();
        }
        else
        {
            searchFrontier.Clear();
        }

        fromCell.SearchPhase = searchFrontierPhase;
        fromCell.Distance    = 0;
        searchFrontier.Enqueue(fromCell);
        while (searchFrontier.Count > 0)
        {
            HexCell current = searchFrontier.Dequeue();
            current.SearchPhase += 1;

            if (current == toCell)
            {
                return(true);
            }

            int currentTurn = (current.Distance - 1) / speed;

            for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++)
            {
                HexCell neighbor = current.GetNeighbor(d);
                if (
                    neighbor == null ||
                    neighbor.SearchPhase > searchFrontierPhase
                    )
                {
                    continue;
                }
                if (neighbor.IsUnderwater || neighbor.Unit)
                {
                    continue;
                }
                if (neighbor.HasRiver && !neighbor.HasRoads)
                {
                    continue;
                }

                HexEdgeType edgeType = current.GetEdgeType(neighbor);
                // modify by ztj
                // 移动力足够大的情况下悬崖也可以上去
                //if (edgeType == HexEdgeType.Cliff) {
                //	continue;
                //}
                float moveCost;
                if (current.HasRoadThroughEdge(d))
                {
                    moveCost = 1;
                }
                else if (current.Walled != neighbor.Walled)
                {
                    continue;
                }
                else
                {
                    //moveCost = edgeType == HexEdgeType.Flat ? 5 : 10;
                    moveCost  = MoveCost_Elevation[(int)edgeType];
                    moveCost += MoveCost_Terrain[current.TerrainTypeIndex];
                    //moveCost += neighbor.UrbanLevel + neighbor.FarmLevel + neighbor.PlantLevel;
                    moveCost += MoveCost_Building[neighbor.UrbanLevel] + MoveCost_Building[neighbor.FarmLevel] +
                                MoveCost_Building[neighbor.PlantLevel];
                }

                int distance = current.Distance + (int)moveCost;
                int turn     = (distance - 1) / speed;
                if (turn > currentTurn)
                {
                    distance = turn * speed + (int)moveCost;
                }

                if (neighbor.SearchPhase < searchFrontierPhase)
                {
                    neighbor.SearchPhase     = searchFrontierPhase;
                    neighbor.Distance        = distance;
                    neighbor.PathFrom        = current;
                    neighbor.SearchHeuristic =
                        neighbor.coordinates.DistanceTo(toCell.coordinates);
                    searchFrontier.Enqueue(neighbor);
                }
                else if (distance < neighbor.Distance)
                {
                    int oldPriority = neighbor.SearchPriority;
                    neighbor.Distance = distance;
                    neighbor.PathFrom = current;
                    searchFrontier.Change(neighbor, oldPriority);
                }
            }
        }
        return(false);
    }
예제 #26
0
    /// <summary>
    /// A*寻路
    /// </summary>
    /// <param name="fromCell"></param>
    /// <param name="toCell"></param>
    /// <returns></returns>
    bool Search(HexCell fromCell, HexCell toCell, int speed)
    {
        searchFrontierPhase += 2;
        if (searchFrontier == null)
        {
            searchFrontier = new HexCellPriorityQueue();
        }
        else
        {
            searchFrontier.Clear();
        }

        //        for (int i = 0; i < cells.Length; i++)
        //        {
        //            //cells[i].Distance = int.MaxValue;
        //            cells[i].SetLabel(null);
        //            cells[i].DisableHighlight();
        //        }
        //
        //        fromCell.EnableHighlight(Color.blue);

        fromCell.SearchPhase = searchFrontierPhase;

        //toCell.EnableHighlight(Color.red);

        fromCell.Distance = 0;

        searchFrontier.Enqueue(fromCell);

        while (searchFrontier.Count > 0)
        {
            HexCell current = searchFrontier.Dequeue();
            //每当一个cell被检索过之后,格子的搜索阶段+1
            current.SearchPhase += 1;
            ///搜索到目标位置不再搜索
            if (current == toCell)
            {
                return(true);
                //下边这些可以在搜索完成之后,另外一个方法调用
                //                while (current != fromCell)
                //                {
                //                    int turn = current.Distance / speed;
                //                    current.SetLabel(turn.ToString());
                //                    current.EnableHighlight(Color.white);
                //                    current = current.PathFrom;
                //                }
                //                toCell.EnableHighlight(Color.red);
                //                break;
            }

            //当前的回合数(逻辑强相关)
            int currentTurn = (current.Distance - 1) / speed;

            for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++)
            {
                HexCell neighbor = current.GetNeighbor(d);

                //这里可以根据搜索是否完成,避免重复计算
                if (neighbor == null || neighbor.SearchPhase > searchFrontierPhase)
                {
                    continue;
                }

                if (neighbor.IsUnderwater || neighbor.hexUnit)
                {
                    continue;
                }

                //取到当前链接类型
                HexEdgeType edgeType = current.GetEdgeType(neighbor);
                if (current.GetEdgeType(neighbor) == HexEdgeType.Cliff)
                {
                    continue;
                }

                //int distance = current.Distance;
                //移动所消耗的行动力
                int moveCost;

                //如果是有道路的情况距离为1
                if (current.HasRoadThroughEdge(d))
                {
                    moveCost = 1;
                }
                else
                {
                    //如果不是平摊的链接,距离为10
                    moveCost = edgeType == HexEdgeType.Flat ? 5 : 10;
                    //加入场景内环境的因素导致距离的问题(游戏逻辑强相关)
                    moveCost += neighbor.UrbanLevel + neighbor.FarmLevel +
                                neighbor.PlantLevel;
                }

                int distance = current.Distance + moveCost;

                //需要行动多少个回合
                int turn = (distance - 1) / speed;

                if (turn > currentTurn)
                {
                    distance = turn * speed + moveCost;
                }

                //如果没有被检测过的邻居添加到队里中
                //if (neighbor.Distance == int.MaxValue) {
                //如果是搜索阶段小于当前的搜索阶段,这样搜索可以在初始化的时候不再初始化每个cell的初始距离
                if (neighbor.SearchPhase < searchFrontierPhase)
                {
                    neighbor.Distance    = distance;
                    neighbor.SearchPhase = searchFrontierPhase;
                    //                    neighbor.SetLabel(turn.ToString());
                    neighbor.PathFrom        = current;
                    neighbor.SearchHeuristic =
                        neighbor.coordinates.DistanceTo(toCell.coordinates);
                    searchFrontier.Enqueue(neighbor);
                }
                else if (distance < neighbor.Distance)
                {
                    int oldPriority = neighbor.SearchPriority;
                    neighbor.Distance = distance;
                    //                    neighbor.SetLabel(turn.ToString());
                    neighbor.PathFrom = current;
                    searchFrontier.Change(neighbor, oldPriority);
                }
            }
        }

        return(false);
    }
예제 #27
0
        void TriangulateCorner(
            Vector3 bottom, HexCell bottomCell,
            Vector3 left, HexCell leftCell,
            Vector3 right, HexCell rightCell)
        {
            HexEdgeType leftEdgeType  = bottomCell.GetEdgeType(leftCell);
            HexEdgeType rightCellType = bottomCell.GetEdgeType(rightCell);

            if (leftEdgeType == HexEdgeType.Slope)
            {
                if (rightCellType == HexEdgeType.Slope)
                {
                    TriangulateCornerTerraces(bottom, bottomCell, left, leftCell, right, rightCell);
                }
                else if (rightCellType == HexEdgeType.Flat)
                {
                    TriangulateCornerTerraces(left, leftCell, right, rightCell, bottom, bottomCell);
                }
                else
                {
                    TriangulateCornerTerracesCliff(
                        bottom, bottomCell, left, leftCell, right, rightCell);
                }
            }
            else if (rightCellType == HexEdgeType.Slope)
            {
                if (leftEdgeType == HexEdgeType.Flat)
                {
                    TriangulateCornerTerraces(right, rightCell, bottom, bottomCell, left, leftCell);
                }
                else
                {
                    TriangulateCornerCliffTerraces(
                        bottom, bottomCell, left, leftCell, right, rightCell);
                }
            }
            else if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope)
            {
                if (leftCell.elevation < rightCell.elevation)
                {
                    TriangulateCornerCliffTerraces(
                        right, rightCell, bottom, bottomCell, left, leftCell);
                }
                else
                {
                    TriangulateCornerTerracesCliff(
                        left, leftCell, right, rightCell, bottom, bottomCell);
                }
            }
            else
            {
                terrain.AddTriangle(bottom, left, right);
                terrain.AddTriangleColor(color1, color2, color3);
                Vector3 types;
                types.x = bottomCell.terrainTypeIndex;
                types.y = leftCell.terrainTypeIndex;
                types.z = rightCell.terrainTypeIndex;
                terrain.AddTriangleTerrainTypes(types);
            }
            features.AddWall(bottom, bottomCell, left, leftCell, right, rightCell);
        }
예제 #28
0
    IEnumerator Search(HexCell fromCell, HexCell toCell)
    {
        if (searchFrontier == null)
        {
            searchFrontier = new HexCellPriorityQueue();
        }
        else
        {
            searchFrontier.Clear();
        }

        for (int i = 0; i < cells.Length; i++)
        {
            cells[i].Distance = int.MaxValue;
            cells[i].DisableHighlight();
        }
        fromCell.EnableHighlight(Color.blue);
        toCell.EnableHighlight(Color.red);

        WaitForSeconds delay = new WaitForSeconds(1 / 60f);

        fromCell.Distance = 0;
        searchFrontier.Enqueue(fromCell);
        while (searchFrontier.Count > 0)
        {
            yield return(delay);

            HexCell current = searchFrontier.Dequeue();

            if (current == toCell)
            {
                current = current.PathFrom;
                while (current != fromCell)
                {
                    current.EnableHighlight(Color.white);
                    current = current.PathFrom;
                }
                break;
            }

            for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++)
            {
                HexCell neighbor = current.GetNeighbor(d);
                if (neighbor == null)
                {
                    continue;
                }
                if (neighbor.IsUnderwater)
                {
                    continue;
                }
                HexEdgeType edgeType = current.GetEdgeType(neighbor);
                if (edgeType == HexEdgeType.Cliff)
                {
                    continue;
                }
                int distance = current.Distance;
                if (current.HasRoadThroughEdge(d))
                {
                    distance += 1;
                }
                else if (current.Walled != neighbor.Walled)
                {
                    continue;
                }
                else
                {
                    distance += edgeType == HexEdgeType.Flat ? 5 : 10;
                    distance += neighbor.UrbanLevel + neighbor.FarmLevel +
                                neighbor.PlantLevel;
                }
                if (neighbor.Distance == int.MaxValue)
                {
                    neighbor.Distance        = distance;
                    neighbor.PathFrom        = current;
                    neighbor.SearchHeuristic =
                        neighbor.coordinates.DistanceTo(toCell.coordinates);
                    searchFrontier.Enqueue(neighbor);
                }
                else if (distance < neighbor.Distance)
                {
                    int oldPriority = neighbor.SearchPriority;
                    neighbor.Distance = distance;
                    neighbor.PathFrom = current;
                    searchFrontier.Change(neighbor, oldPriority);
                }
            }
        }
    }
예제 #29
0
    void TriangulateCorner(
        Vector3 bottom, HexCell bottomCell,
        Vector3 left, HexCell leftCell,
        Vector3 right, HexCell rightCell
        )
    {
        HexEdgeType leftEdgeType  = bottomCell.GetEdgeType(leftCell);
        HexEdgeType rightEdgeType = bottomCell.GetEdgeType(rightCell);

        if (leftEdgeType == HexEdgeType.Slope)
        {
            if (rightEdgeType == HexEdgeType.Slope)
            {
                TriangulateCornerTerraces(
                    bottom, bottomCell, left, leftCell, right, rightCell
                    );
            }
            else if (rightEdgeType == HexEdgeType.Flat)
            {
                TriangulateCornerTerraces(
                    left, leftCell, right, rightCell, bottom, bottomCell
                    );
            }
            else
            {
                TriangulateCornerTerracesCliff(
                    bottom, bottomCell, left, leftCell, right, rightCell
                    );
            }
        }
        else if (rightEdgeType == HexEdgeType.Slope)
        {
            if (leftEdgeType == HexEdgeType.Flat)
            {
                TriangulateCornerTerraces(
                    right, rightCell, bottom, bottomCell, left, leftCell
                    );
            }
            else
            {
                TriangulateCornerCliffTerraces(
                    bottom, bottomCell, left, leftCell, right, rightCell
                    );
            }
        }
        else if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope)
        {
            if (leftCell.Elevation < rightCell.Elevation)
            {
                TriangulateCornerCliffTerraces(
                    right, rightCell, bottom, bottomCell, left, leftCell
                    );
            }
            else
            {
                TriangulateCornerTerracesCliff(
                    left, leftCell, right, rightCell, bottom, bottomCell
                    );
            }
        }
        else
        {
            terrain.AddTriangle(bottom, left, right);
            Vector3 indices;
            indices.x = bottomCell.Index;
            indices.y = leftCell.Index;
            indices.z = rightCell.Index;
            terrain.AddTriangleCellData(indices, weights1, weights2, weights3);

            //terrain.AddTriangleColor(
            //             weights1, weights2, weights3
            //         );
            //         Vector3 types;
            //         types.x = bottomCell.TerrainTypeIndex;
            //         types.y = leftCell.TerrainTypeIndex;
            //         types.z = rightCell.TerrainTypeIndex;
            //         terrain.AddTriangleTerrainTypes(types);
        }

        features.AddWall(bottom, bottomCell, left, leftCell, right, rightCell);
    }
    void TriangulateCorner(
        Vector3 bottom, HexCell bottomCell,
        Vector3 left, HexCell leftCell,
        Vector3 right, HexCell rightCell
        )
    {
        HexEdgeType leftEdgeType  = bottomCell.GetEdgeType(leftCell);
        HexEdgeType rightEdgeType = bottomCell.GetEdgeType(rightCell);


        if (leftEdgeType == HexEdgeType.Slope)
        {
            if (rightEdgeType == HexEdgeType.Slope)
            {
                TriangulateCornerTerraces(
                    bottom, bottomCell, left, leftCell, right, rightCell
                    );

                /*Debug.Log("TriangulateCorner start");
                 * Debug.Log("bottom::" + bottomCell.coordinates.ToStringOnSeparateLines());
                 * Debug.Log("left::" + leftCell.coordinates.ToStringOnSeparateLines());
                 * Debug.Log("right::" + rightCell.coordinates.ToStringOnSeparateLines());
                 * Debug.Log("TriangulateCorner end");*/
            }
            else if (rightEdgeType == HexEdgeType.Flat)
            {
                TriangulateCornerTerraces(
                    left, leftCell, right, rightCell, bottom, bottomCell
                    );
            }
            else
            {
                TriangulateCornerTerracesCliff(
                    bottom, bottomCell, left, leftCell, right, rightCell
                    );
            }
        }
        else if (rightEdgeType == HexEdgeType.Slope)
        {
            if (leftEdgeType == HexEdgeType.Flat)
            {
                TriangulateCornerTerraces(
                    right, rightCell, bottom, bottomCell, left, leftCell
                    );
            }
            else
            {
                TriangulateCornerCliffTerraces(
                    bottom, bottomCell, left, leftCell, right, rightCell
                    );
            }
        }
        else if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope)
        {
            if (leftCell.Elevation < rightCell.Elevation)
            {
                TriangulateCornerCliffTerraces(
                    right, rightCell, bottom, bottomCell, left, leftCell
                    );
            }
            else
            {
                TriangulateCornerTerracesCliff(
                    left, leftCell, right, rightCell, bottom, bottomCell
                    );
            }
        }
        else
        {
            terrain.AddTriangle(bottom, left, right);
            terrain.AddTriangleColor(color1, color2, color3);

            Vector3 types;
            types.x = (float)bottomCell.TerrainType;
            types.y = (float)leftCell.TerrainType;
            types.z = (float)rightCell.TerrainType;
            terrain.AddTriangleTerrainTypes(types);
        }
    }