public Price GetRewardPerTurnOfType(HexEdgeType hexEdgeType) { foreach (var priceConfiguration in RewardPerTurnConfigurations) { if (priceConfiguration.HexEdgeType == hexEdgeType) { return(priceConfiguration.Price); } } throw new NotImplementedException(); }
public int GetChanceForType(HexEdgeType hexEdgeType) { foreach (var edgeTypeChance in EdgeTypeChances) { if (edgeTypeChance.HexEdgeType == hexEdgeType) { return(edgeTypeChance.Chance); } } throw new NotImplementedException(); }
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; } } } } } }
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); }
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); } }
//添加连接三角形并阶梯化 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); } }
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); }
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(); }
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); }
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); } }
/// <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); } }
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); }
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); }
/// <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); } }
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); }
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); } }
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); }
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); } }
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); }
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); }
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); }
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); } }
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); }
/// <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); }
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); }
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); } } } }
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); } }