public virtual bool PlaceAtLocation(IntVector2 location) { Location = location; if (location != null) { hexCell = GridManager.instance.GetHexCell(location); if (hexCell != null) { transform.position = hexCell.transform.position; hexCell.placedPlaceable = this; return true; } } else { if (hexCell != null) { if (hexCell.placedPlaceable == this) { hexCell.placedPlaceable = null; } hexCell = null; } } return false; }
public override bool PlaceAtLocation(IntVector2 location) { Location = location; if (location != null) { hexCell = GridManager.instance.GetHexCell(location); leftBelow = GridManager.instance.GetHexCell(location+HexMetrics.GetGridOffset(HexMetrics.Direction.LeftDown)); centerBelow = GridManager.instance.GetHexCell(location+HexMetrics.GetGridOffset(HexMetrics.Direction.Down)); rightBelow = GridManager.instance.GetHexCell(location+HexMetrics.GetGridOffset(HexMetrics.Direction.RightDown)); if (hexCell != null && leftBelow != null && centerBelow != null && rightBelow != null) { foreach (HexCell hc in new HexCell [4] {hexCell, leftBelow, centerBelow, rightBelow}) { if (hc.placedPlaceable != null) { return false; } } transform.position = hexCell.transform.position; foreach (HexCell hc in new HexCell [4] {hexCell, leftBelow, centerBelow, rightBelow}) { hc.placedPlaceable = this; } return true; } } else { if (hexCell != null && leftBelow != null && centerBelow != null && rightBelow != null) { // if (hexCell.placedPlaceable == this) // { // hexCell.placedPlaceable = null; // } foreach (HexCell hc in new HexCell [4] {hexCell, leftBelow, centerBelow, rightBelow}) { if (hc.placedPlaceable == this) { hc.placedPlaceable = null; } } hexCell = null; leftBelow = null; centerBelow = null; rightBelow = null; } } return false; }
private void Triangulate(HexCell cell) { Vector3 center = cell.transform.localPosition; for(int i = 0; i < 6; i++) { AddTriangle( center, center + HexMetrics.corners[i], center + HexMetrics.corners[i + 1] ); } }
protected void PlaceOverLocation(IntVector2 location) { if (location != null) { hexCell = GridManager.instance.GetHexCell(location); if (hexCell) { transform.position = hexCell.transform.position; } } }
public void TriangulateCells(HexCell[] cells) { _hexMesh.Clear(); _vertices.Clear(); _tris.Clear(); for(int i = 0; i < cells.Length; i++) { Triangulate(cells[i]); } _hexMesh.vertices = _vertices.ToArray(); _hexMesh.triangles = _tris.ToArray(); _hexMesh.RecalculateNormals(); }
public void Triangulate(HexCell[] cells) { hexMesh.Clear(); vertices.Clear(); colors.Clear(); triangles.Clear(); for (int i = 0; i < cells.Length; i++) { Triangulate(cells[i]); } hexMesh.vertices = vertices.ToArray(); hexMesh.colors = colors.ToArray(); hexMesh.triangles = triangles.ToArray(); hexMesh.RecalculateNormals(); meshCollider.sharedMesh = hexMesh; }
public bool IsValidDestination(HexCell cell) { return(cell.TerrainType != HexTerrainTypes.Lake && !cell.Unit); }
public static Optional <Path> FindPath(MapPawn mapPawn) { HexCell start = mapPawn.Location; HexCell dest = mapPawn.Destination; // For node n, cameFrom[n] is the node immediately preceding it on the cheapest path from start // to n currently known. Dictionary <HexCell, PathNode> cameFrom = MapPool <HexCell, PathNode> .GLGet(); // For node n, gScore[n] is the cost of the cheapest path from start to n currently known. Dictionary <HexCell, int> gScore = MapPool <HexCell, int> .GLGet(); gScore[start] = 0; // For node n, fScore[n] = gScore[n] + h(n). fScore[n] represents our current best guess as to // how short a path from start to finish can be if it goes through n. int startFScore = Heuristic(start, dest); // The set of discovered nodes that may need to be (re-)expanded. PriorityQueue <HexCell> openSet = ObjectPool <PriorityQueue <HexCell> > .GLGet(); openSet.Add(start, startFScore); // The set of nodes for which a shortest path has already been found HashSet <HexCell> closedSet = HashSetPool <HexCell> .GLGet(); while (!openSet.IsEmpty()) { HexCell current = (HexCell)openSet.Poll(); // Explicit cast because we know this can never be null if (current == dest) { ObjectPool <PriorityQueue <HexCell> > .GLRestore(openSet); MapPool <HexCell, int> .GLRestore(gScore); HashSetPool <HexCell> .GLRestore(closedSet); return(ReconstructPath(cameFrom, current)); } closedSet.Add(current); for (HexDirection dir = HexDirection.NE; dir <= HexDirection.NW; dir++) { HexCell neighbor = current.GetNeighbor(dir); if (neighbor == null || closedSet.Contains(neighbor)) { continue; // Dont waste time with already evaluated nodes } if (!mapPawn.CanTransverse(current, neighbor, dir)) { continue; // We cannot go there } int transversalCost = mapPawn.TransversalCost(current, neighbor); int tentative_gScore = gScore[current] + transversalCost; int neighbor_gScore = gScore.ContainsKey(neighbor) ? gScore[neighbor] : int.MaxValue; if (tentative_gScore < neighbor_gScore) { cameFrom[neighbor] = new PathNode(current, transversalCost); gScore[neighbor] = tentative_gScore; int fScore = tentative_gScore + Heuristic(neighbor, dest); if (!openSet.Update(neighbor, fScore)) { openSet.Add(neighbor, fScore); } } } } // Open set is empty but goal was never reached ObjectPool <PriorityQueue <HexCell> > .GLRestore(openSet); MapPool <HexCell, PathNode> .GLRestore(cameFrom); MapPool <HexCell, int> .GLRestore(gScore); HashSetPool <HexCell> .GLRestore(closedSet); return(null); }
private static int Heuristic(HexCell current, HexCell destination) { return(current.Coordinates.DistanceTo(destination.Coordinates)); }
void TriangulateCornerCliffTerraces(Vector3 begin, HexCell beginCell, Vector3 left, HexCell leftCell, Vector3 right, HexCell rightCell) { float b = 1f / (leftCell.Elevation - beginCell.Elevation); if (b < 0.0f) { b = -b; } Vector3 boundary = Vector3.Lerp(HexMetrics.Perturb(begin), HexMetrics.Perturb(left), b); Color boundaryColor = Color.Lerp(beginCell.Color, leftCell.Color, b); TriangulateBoundaryTriangle(right, rightCell, begin, beginCell, boundary, boundaryColor); if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope) { TriangulateBoundaryTriangle(left, leftCell, right, rightCell, boundary, boundaryColor); } else { terrain.AddTriangleUnperturbed(HexMetrics.Perturb(left), HexMetrics.Perturb(right), boundary); terrain.AddTriangleColor(leftCell.Color, rightCell.Color, boundaryColor); } }
void TriangulateConnection(HexDirection direction, HexCell cell, EdgeVertices e1) { HexCell neighbor = cell.GetNeighbor(direction); if (neighbor == null) { return; } Vector3 bridge = HexMetrics.GetBridge(direction); bridge.y = neighbor.Position.y - cell.Position.y; EdgeVertices e2 = new EdgeVertices(e1.v1 + bridge, e1.v5 + bridge); if (cell.HasRiverThroughEdge(direction)) { e2.v3.y = neighbor.StreamBedY; TriangulateRiverQuad( e1.v2, e1.v4, e2.v2, e2.v4, cell.RiverSurfaceY, neighbor.RiverSurfaceY, 0.8f, cell.HasIncomingRiver && cell.IncomingRiver == direction ); } if (cell.GetEdgeType(direction) == HexEdgeType.Slope) { TriangulateEdgeTerraces( e1, cell, e2, neighbor, cell.HasRoadThroughEdge(direction) ); } else { TriangulateEdgeStrip( e1, cell.Color, e2, neighbor.Color, cell.HasRoadThroughEdge(direction) ); } HexCell nextNeighbor = cell.GetNeighbor(direction.Next()); if (direction <= HexDirection.E && nextNeighbor != null) { Vector3 v5 = e1.v5 + HexMetrics.GetBridge(direction.Next()); v5.y = nextNeighbor.Position.y; if (cell.Elevation <= neighbor.Elevation) { if (cell.Elevation <= nextNeighbor.Elevation) { TriangulateCorner( e1.v5, cell, e2.v5, neighbor, v5, nextNeighbor ); } else { TriangulateCorner( v5, nextNeighbor, e1.v5, cell, e2.v5, neighbor ); } } else if (neighbor.Elevation <= nextNeighbor.Elevation) { TriangulateCorner( e2.v5, neighbor, v5, nextNeighbor, e1.v5, cell ); } else { TriangulateCorner( v5, nextNeighbor, e1.v5, cell, e2.v5, neighbor ); } } }
void EditCell(HexCell cell) { cell.color = activeColor; cell.Elevation = activeElevation; hexGrid.Refresh(); }
void TriangulateConnection( HexDirection direction, HexCell cell, Vector3 v1, Vector3 v2 ) { HexCell neighbor = cell.GetNeighbor(direction); if (neighbor == null) { return; } Vector3 bridge = HexMetrics.GetBridge(direction); Vector3 v3 = v1 + bridge; Vector3 v4 = v2 + bridge; v3.y = v4.y = neighbor.Elevation * HexMetrics.elevationStep; if (cell.GetEdgeType(direction) == HexEdgeType.Slope) { TriangulateEdgeTerraces(v1, v2, cell, v3, v4, neighbor); } else { AddQuad(v1, v2, v3, v4); AddQuadColor(cell.color, neighbor.color); } HexCell nextNeighbor = cell.GetNeighbor(direction.Next()); if (direction <= HexDirection.E && nextNeighbor != null) { Vector3 v5 = v2 + HexMetrics.GetBridge(direction.Next()); v5.y = nextNeighbor.Elevation * HexMetrics.elevationStep; if (cell.Elevation <= neighbor.Elevation) { if (cell.Elevation <= nextNeighbor.Elevation) { TriangulateCorner(v2, cell, v4, neighbor, v5, nextNeighbor); } else { TriangulateCorner(v5, nextNeighbor, v2, cell, v4, neighbor); } } else if (neighbor.Elevation <= nextNeighbor.Elevation) { TriangulateCorner(v4, neighbor, v5, nextNeighbor, v2, cell); } else { TriangulateCorner(v5, nextNeighbor, v2, cell, v4, neighbor); } } }
/// <summary> /// Edits the cell. /// </summary> /// <param name="cell">Cell.</param> void EditCell(HexCell cell) { cell.Color = activeColor; cell.moveCost = cell.level [newIndex]; }
void TriangulateEdgeTerraces( Vector3 beginLeft, Vector3 beginRight, HexCell beginCell, Vector3 endLeft, Vector3 endRight, HexCell endCell ) { Vector3 v3 = HexMetrics.TerraceLerp(beginLeft, endLeft, 1); Vector3 v4 = HexMetrics.TerraceLerp(beginRight, endRight, 1); Color c2 = HexMetrics.TerraceLerp(beginCell.color, endCell.color, 1); AddQuad(beginLeft, beginRight, v3, v4); AddQuadColor(beginCell.color, c2); for (int i = 2; i < HexMetrics.terraceSteps; i++) { Vector3 v1 = v3; Vector3 v2 = v4; Color c1 = c2; v3 = HexMetrics.TerraceLerp(beginLeft, endLeft, i); v4 = HexMetrics.TerraceLerp(beginRight, endRight, i); c2 = HexMetrics.TerraceLerp(beginCell.color, endCell.color, i); AddQuad(v1, v2, v3, v4); AddQuadColor(c1, c2); } AddQuad(v3, v4, endLeft, endRight); AddQuadColor(c2, endCell.color); }
void TriangulateCornerTerracesCliff( Vector3 begin, HexCell beginCell, Vector3 left, HexCell leftCell, Vector3 right, HexCell rightCell ) { float b = 1f / (rightCell.Elevation - beginCell.Elevation); if (b < 0) { b = -b; } Vector3 boundary = Vector3.Lerp(begin, right, b); Color boundaryColor = Color.Lerp(beginCell.color, rightCell.color, b); TriangulateBoundaryTriangle( begin, beginCell, left, leftCell, boundary, boundaryColor ); if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope) { TriangulateBoundaryTriangle( left, leftCell, right, rightCell, boundary, boundaryColor ); } else { AddTriangle(left, right, boundary); AddTriangleColor(leftCell.color, rightCell.color, boundaryColor); } }
void TriangulateCornerTerraces( Vector3 begin, HexCell beginCell, Vector3 left, HexCell leftCell, Vector3 right, HexCell rightCell ) { Vector3 v3 = HexMetrics.TerraceLerp(begin, left, 1); Vector3 v4 = HexMetrics.TerraceLerp(begin, right, 1); Color c3 = HexMetrics.TerraceLerp(beginCell.color, leftCell.color, 1); Color c4 = HexMetrics.TerraceLerp(beginCell.color, rightCell.color, 1); AddTriangle(begin, v3, v4); AddTriangleColor(beginCell.color, c3, c4); for (int i = 2; i < HexMetrics.terraceSteps; i++) { Vector3 v1 = v3; Vector3 v2 = v4; Color c1 = c3; Color c2 = c4; v3 = HexMetrics.TerraceLerp(begin, left, i); v4 = HexMetrics.TerraceLerp(begin, right, i); c3 = HexMetrics.TerraceLerp(beginCell.color, leftCell.color, i); c4 = HexMetrics.TerraceLerp(beginCell.color, rightCell.color, i); AddQuad(v1, v2, v3, v4); AddQuadColor(c1, c2, c3, c4); } AddQuad(v3, v4, left, right); AddQuadColor(c3, c4, leftCell.color, rightCell.color); }
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); } }
public void SetNeighbor(HexDirection direction, HexCell cell) { neighbors[(int)direction] = cell; cell.neighbors[(int)direction.Opposite()] = this; }
public bool AskCreateUnit(UrbanCity city, int actorInfoId) { HexCell cellCenter = GameRoomManager.Instance.HexmapHelper.GetCell(city.CellIndex);// 城市中心地块 return(AskCreateUnit(cellCenter, actorInfoId)); }
bool IsValidRiverDestination(HexCell neighbor) { return(neighbor && ( elevation >= neighbor.elevation || waterLevel == neighbor.elevation )); }
void TriangulateBoundaryTriangle( Vector3 begin, HexCell beginCell, Vector3 left, HexCell leftCell, Vector3 boundary, Color boundaryColor ) { Vector3 v2 = HexMetrics.TerraceLerp(begin, left, 1); Color c2 = HexMetrics.TerraceLerp(beginCell.color, leftCell.color, 1); AddTriangle(begin, v2, boundary); AddTriangleColor(beginCell.color, c2, boundaryColor); for (int i = 2; i < HexMetrics.terraceSteps; i++) { Vector3 v1 = v2; Color c1 = c2; v2 = HexMetrics.TerraceLerp(begin, left, i); c2 = HexMetrics.TerraceLerp(beginCell.color, leftCell.color, i); AddTriangle(v1, v2, boundary); AddTriangleColor(c1, c2, boundaryColor); } AddTriangle(v2, left, boundary); AddTriangleColor(c2, leftCell.color, boundaryColor); }
void Triangulate(HexDirection direction, HexCell cell) { Vector3 center = cell.transform.localPosition; Vector3 v1 = center + HexMetrics.GetFirstSolidCorner(direction); Vector3 v2 = center + HexMetrics.GetSecondSolidCorner(direction); AddTriangle(center, v1, v2); AddTriangleColor(cell.color); if (direction <= HexDirection.SE) { TriangulateConnection(direction, cell, v1, v2); } }
public void EvolveClimate(HexCell hexCell) { ClimateData climateData = m_climateData[hexCell.CellIndex]; if (hexCell.IsUnderwater) { climateData.moisture = 1f; climateData.clouds += Evaporation; } else { float evaporation = climateData.moisture * EvaporationFactor; climateData.moisture -= evaporation; climateData.clouds += evaporation; } float precipitation = climateData.clouds * PrecipitationFactor; climateData.clouds -= precipitation; climateData.moisture += precipitation; float cloudMaximum = 1f - hexCell.ViewElevation / (ElevationMaximum + 1f); if (climateData.clouds > cloudMaximum) { climateData.moisture += climateData.clouds - cloudMaximum; climateData.clouds = cloudMaximum; } float perCellFactor = (1f / 6f); HexDirection mainDispersalDirection = WindDirection.Opposite(); float cloudDispersion = climateData.clouds * (1f / (5f + WindStrength)); float runoff = climateData.moisture * RunoffFactor * perCellFactor; float seepage = climateData.moisture * SeepageFactor * perCellFactor; for (HexDirection dir = HexDirection.NE; dir <= HexDirection.NW; dir++) { HexCell neighbor = hexCell.GetNeighbour(dir); if (neighbor == null) { continue; } ClimateData neighbourClimateData = m_nextClimateData[neighbor.CellIndex]; if (dir == mainDispersalDirection) { neighbourClimateData.clouds += cloudDispersion * WindStrength; } else { neighbourClimateData.clouds += cloudDispersion; } int elevationDelta = neighbor.ViewElevation - hexCell.ViewElevation; if (elevationDelta < 0) { climateData.moisture -= runoff; neighbourClimateData.moisture += runoff; } else if (elevationDelta == 0) { climateData.moisture -= seepage; neighbourClimateData.moisture += seepage; } m_nextClimateData[neighbor.CellIndex] = neighbourClimateData; } ClimateData nextCellClimateData = m_nextClimateData[hexCell.CellIndex]; nextCellClimateData.moisture += climateData.moisture; nextCellClimateData.moisture = Mathf.Min(1f, nextCellClimateData.moisture); m_nextClimateData[hexCell.CellIndex] = nextCellClimateData; m_climateData[hexCell.CellIndex] = new ClimateData(); }
public void UpdateRoot(Pawn pawn, HexCell oldCell, HexCell newCell) { pawn.currentCell = newCell; newCell.pawn = pawn; oldCell.pawn = null; }
public void CreateRivers() { List <HexCell> riverOrigins = ListPool <HexCell> .Get(); foreach (HexCell hexCell in HexGrid.GetHexCells()) { if (hexCell.IsUnderwater) { continue; } ClimateData climateData = m_climateData[hexCell.CellIndex]; float data = climateData.moisture * (float)(hexCell.Elevation - WaterLevel) / (ElevationMaximum - WaterLevel); if (data > 0.75f) { riverOrigins.Add(hexCell); riverOrigins.Add(hexCell); } if (data > 0.5f) { riverOrigins.Add(hexCell); } if (data > 0.25f) { riverOrigins.Add(hexCell); } } int riverBudget = Mathf.RoundToInt(m_numLandCells * RiverPercentage * 0.01f); while (riverBudget > 0 && riverOrigins.Count > 0) { int index = Random.Range(0, riverOrigins.Count); HexCell origin = riverOrigins[index]; riverOrigins.RemoveAt(index); if (!origin.HasRiver) { bool isValidOrigin = true; for (HexDirection dir = HexDirection.NE; dir <= HexDirection.NW; dir++) { HexCell neighbour = origin.GetNeighbour(dir); if (neighbour != null && (neighbour.HasRiver || neighbour.IsUnderwater)) { isValidOrigin = false; break; } } if (isValidOrigin) { riverBudget -= CreateRiver(origin); } } } if (riverBudget > 0) { Debug.LogWarning("Failed to use up river budget"); } ListPool <HexCell> .Return(riverOrigins); }
void TriangulateRoadAdjacentToRiver(HexDirection direction, HexCell cell, Vector3 center, EdgeVertices e) { bool hasRoadThroughEdge = cell.HasRoadThroughEdge(direction); bool previousHasRiver = cell.HasRiverThroughEdge(direction.Previous()); bool nextHasRiver = cell.HasRiverThroughEdge(direction.Next()); Vector2 interpolators = GetRoadInterpolators(direction, cell); Vector3 roadCenter = center; if (cell.HasRiverBeginOrEnd) { roadCenter += HexMetrics.GetSolidEdgeMiddle(cell.RiverBeginOrEndDirection.Opposite()) * (1f / 3f); } else if (cell.IncomingRiver == cell.OutgoingRiver.Opposite()) { Vector3 corner; if (previousHasRiver) { if (!hasRoadThroughEdge && !cell.HasRoadThroughEdge(direction.Next())) { return; } corner = HexMetrics.GetSecondSolidCorner(direction); } else { if (!hasRoadThroughEdge && !cell.HasRoadThroughEdge(direction.Previous())) { return; } corner = HexMetrics.GetFirstSolidCorner(direction); } roadCenter += corner * 0.5f; center += corner * 0.25f; } else if (cell.IncomingRiver == cell.OutgoingRiver.Previous()) { roadCenter -= HexMetrics.GetSecondCorner(cell.IncomingRiver) * 0.2f; } else if (cell.IncomingRiver == cell.OutgoingRiver.Next()) { roadCenter -= HexMetrics.GetFirstCorner(cell.IncomingRiver) * 0.2f; } else if (previousHasRiver && nextHasRiver) { if (!hasRoadThroughEdge) { return; } Vector3 offset = HexMetrics.GetSolidEdgeMiddle(direction) * HexMetrics.innerToOuter; roadCenter += offset * 0.7f; center += offset * 0.5f; } else { HexDirection middle; if (previousHasRiver) { middle = direction.Next(); } else if (nextHasRiver) { middle = direction.Previous(); } else { middle = direction; } if (!cell.HasRoadThroughEdge(middle) && !cell.HasRoadThroughEdge(middle.Previous()) && !cell.HasRoadThroughEdge(middle.Next())) { return; } roadCenter += HexMetrics.GetSolidEdgeMiddle(middle) * 0.25f; } Vector3 mL = Vector3.Lerp(roadCenter, e.v1, interpolators.x); Vector3 mR = Vector3.Lerp(roadCenter, e.v5, interpolators.y); TriangulateRoad(roadCenter, mL, mR, e, hasRoadThroughEdge); if (previousHasRiver) { TriangulateRoadEdge(roadCenter, center, mL); } if (nextHasRiver) { TriangulateRoadEdge(roadCenter, mR, center); } }
public int CreateRiver(HexCell riverOrigin) { int length = 0; HexCell hexCell = riverOrigin; HexDirection direction = HexDirection.NE; int minNeighbourElevation = int.MaxValue; while (!hexCell.IsUnderwater) { m_flowDirections.Clear(); for (HexDirection dir = HexDirection.NE; dir <= HexDirection.NW; dir++) { HexCell neighbour = hexCell.GetNeighbour(dir); if (neighbour == null) { continue; } if (neighbour.Elevation < minNeighbourElevation) { minNeighbourElevation = neighbour.Elevation; } if (neighbour == riverOrigin || neighbour.HasIncomingRiver) { continue; } int delta = neighbour.Elevation - hexCell.Elevation; if (delta > 0) { continue; } if (neighbour.HasOutgoingRiver) { hexCell.SetOutgoingRiver(dir); return(length); } if (length == 1 || (dir != direction.Next2() && dir != direction.Previous2())) { m_flowDirections.Add(dir); } // weight dowhills if (delta < 0) { m_flowDirections.Add(dir); m_flowDirections.Add(dir); m_flowDirections.Add(dir); } m_flowDirections.Add(dir); } if (m_flowDirections.Count == 0) { if (length == 1) { return(0); } if (minNeighbourElevation >= hexCell.Elevation) { hexCell.WaterLevel = minNeighbourElevation; if (minNeighbourElevation == hexCell.Elevation) { hexCell.Elevation = minNeighbourElevation - 1; } } break; } direction = m_flowDirections[Random.Range(0, m_flowDirections.Count)]; hexCell.SetOutgoingRiver(direction); length += 1; if (minNeighbourElevation >= hexCell.Elevation && Random.value < ExtraLakeProability) { hexCell.WaterLevel = hexCell.Elevation; hexCell.Elevation--; } hexCell = hexCell.GetNeighbour(direction); } return(length); }
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 Update() { if (!EventSystem.current.IsPointerOverGameObject()) { if (HexGameController.myTurn && !myUnit.isTraveling) { DoPathfinding(); if (Input.GetMouseButtonDown(1)) { DoMove(); } } else { currentCell = null; } } if (Input.GetKeyDown("space")) { myUnit.Jump(); photonView.RPC("GetJump", RpcTarget.Others, true); } // center camera to myUnit position if (Input.GetKeyDown(KeyCode.C)) { HexMapCamera.SetPosition(myUnit.Location); } // toggle camera following if (Input.GetKeyDown(KeyCode.V)) { following = !following; if (following) { HexMapCamera.SetPosition(myUnit.Location); switchToFollowing = true; } } // move camera if (switchToFollowing) { if (HexMapCamera.GetLocalPosition() == myUnit.transform.localPosition) { switchToFollowing = false; } } else if (following) { HexMapCamera.SetPosition(myUnit.transform.localPosition, true); } else { HexMapCamera.Move(); } // networking if (otherUnit) { if (UnitInfo.newPath) { DoMove(UnitInfo.Path); UnitInfo.newPath = false; } if (UnitInfo.Jump) { otherUnit.Jump(); UnitInfo.Jump = false; } } }
public bool CanSpawnAt(Hex hex) { HexCell cell = cells.ContainsKey(hex.ToString()) ? cells[hex.ToString()] : null; return(cell && !cell.occupied); }
public void RefreshTerrain(HexCell cell) { cellTextureData[cell.Index].a = (byte)cell.TerrainTypeIndex; enabled = true; }
public PathNode(HexCell location, int costTo) { this.location = location; this.costTo = costTo; }
public void RefreshVisibility(HexCell cell) { cellTextureData[cell.Index].r = cell.IsVisible ? (byte)255 : (byte)0; enabled = true; }
void EditCell(HexCell cell) { if (cell) { if (activeTerrainTypeIndex >= 0) { cell.TerrainTypeIndex = activeTerrainTypeIndex; } if (applyElevation) { cell.Elevation = activeElevation; } if (applyWaterLevel) { cell.WaterLevel = activeWaterLevel; } if (applySpecialIndex) { cell.SpecialIndex = activeSpecialIndex; } if (applyUrbanLevel) { cell.UrbanLevel = activeUrbanLevel; } if (applyFarmLevel) { cell.FarmLevel = activeFarmLevel; } if (applyPlantLevel) { cell.PlantLevel = activePlantLevel; } if (riverMode == OptionalToggle.No) { cell.RemoveRiver(); } if (roadMode == OptionalToggle.No) { cell.RemoveRoads(); } if (walledMode != OptionalToggle.Ignore) { cell.Walled = walledMode == OptionalToggle.Yes; } if (isDrag) { HexCell otherCell = cell.GetNeighbor(dragDirection.Opposite()); if (otherCell) { if (riverMode == OptionalToggle.Yes) { otherCell.SetOutgoingRiver(dragDirection); } if (roadMode == OptionalToggle.Yes) { otherCell.AddRoad(dragDirection); } } } } }
public virtual void Use(HexCell cell) { throw new NotImplementedException(); }
public Boolean CanAttack(HexCell targetCell) { return(_availableMoves.ContainsKey(targetCell) && _availableMoves[targetCell].CanAttack); }
/// <summary> /// Instantiates the Hex prefabs, assigning them their positions in relation to each other. /// Assigns the neighbors of each hex in relation to each side (E.g. NE,SW, W, E, SE, NW). /// Also responsible for attaching a Text label on top of each Hex displaying its location. /// Adds the cell to its appropriate chunk /// </summary> /// <param name="x"> X Column value for the Hex </param> /// <param name="z"> Z Column value for the Hex </param> /// <param name="i"> Index for cells </param> void CreateCell(int x, int z, int i) { Vector3 position; position.x = (x + z * 0.5f - z / 2) * HexMetrics.innerDiameter; position.y = 0f; position.z = z * (HexMetrics.outerRadius * 1.5f); HexCell cell = cells[i] = Instantiate <HexCell>(cellPrefab); cell.transform.localPosition = position; cell.coordinates = HexCoordinates.FromOffsetCoordinates(x, z); cell.Index = i; cell.ColumnIndex = x / HexMetrics.chunkSizeX; cell.ShaderData = cellShaderData; if (wrapping) { cell.Explorable = z > 0 && z < cellCountZ - 1; } else { cell.Explorable = x > 0 && z > 0 && x < cellCountX - 1 && z < cellCountZ - 1; } if (x > 0) { cell.SetNeighbor(HexDirection.W, cells[i - 1]); if (wrapping && x == cellCountX - 1) { cell.SetNeighbor(HexDirection.E, cells[i - x]); } } if (z > 0) { if ((z & 1) == 0) { cell.SetNeighbor(HexDirection.SE, cells[i - cellCountX]); if (x > 0) { cell.SetNeighbor(HexDirection.SW, cells[i - cellCountX - 1]); } else if (wrapping) { cell.SetNeighbor(HexDirection.SW, cells[i - 1]); } } else { cell.SetNeighbor(HexDirection.SW, cells[i - cellCountX]); if (x < cellCountX - 1) { cell.SetNeighbor(HexDirection.SE, cells[i - cellCountX + 1]); } else if (wrapping) { cell.SetNeighbor( HexDirection.SE, cells[i - cellCountX * 2 + 1] ); } } } Text label = Instantiate <Text>(cellLabelPrefab); label.rectTransform.anchoredPosition = new Vector2(position.x, position.z); cell.uiRect = label.rectTransform; cell.Elevation = 0; AddCellToChunk(x, z, cell); }
public HexEdgeType GetEdgeType(HexCell otherCell) { return(HexMetrics.GetEdgeType( elevation, otherCell.elevation )); }
/// <summary> /// Used for finding the most optimal path to reaching an end point by comparing distances and hazards that lead to that point. /// It weights each hex based on it distance value and its position being closer to the end point. /// The hexes with the most progress in these categories get assessed first to minimize the amount of loops of the method. /// Once it finds the end hex, it works backwards with hexes remembering which way they came to work to the origin point. /// Edit. Now assigns how many turns it would take to get there based on distance a unit can move. /// </summary> /// <param name="fromCell"> Origin hex </param> /// <param name="toCell"> Destination hex </param> /// <returns> Creates path towards end destination </returns> bool Search(HexCell fromCell, HexCell toCell, HexUnit unit) { int speed = unit.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 neighbour = current.GetNeighbor(d); if (neighbour == null || neighbour.SearchPhase > searchFrontierPhase) { continue; } if (!unit.IsValidDestination(neighbour)) { continue; } int moveCost = unit.GetMoveCost(current, neighbour, d); if (moveCost < 0) { continue; } int distance = current.Distance + moveCost; int turn = (distance - 1) / speed; if (turn > currentTurn) { distance = turn * speed + moveCost; } if (neighbour.SearchPhase < searchFrontierPhase) { neighbour.Distance = distance; neighbour.SearchPhase = searchFrontierPhase; neighbour.PathFrom = current; neighbour.SearchHeuristic = neighbour.coordinates.DistanceTo(toCell.coordinates); searchFrontier.Enqueue(neighbour); } else if (distance < neighbour.Distance) { int oldPriority = neighbour.SearchPriority; neighbour.Distance = distance; neighbour.PathFrom = current; searchFrontier.Change(neighbour, oldPriority); } } } return(false); }
// TODO: ekki nota ? public void ChangeMoveCost(HexCell cell) { cell.moveCost = cell.level[cell.index]; }
public void AddWall(Vector3 c1, HexCell cell1, Vector3 c2, HexCell cell2, Vector3 c3, HexCell cell3) { if (cell1.Walled) { if (cell2.Walled) { if (!cell3.Walled) { AddWallSegment(c3, cell3, c1, cell1, c2, cell2); } } else if (cell3.Walled) { AddWallSegment(c2, cell2, c3, cell3, c1, cell1); } else { AddWallSegment(c1, cell1, c2, cell2, c3, cell3); } } else if (cell2.Walled) { if (cell3.Walled) { AddWallSegment(c1, cell1, c2, cell2, c3, cell3); } else { AddWallSegment(c2, cell2, c3, cell3, c1, cell1); } } else if (cell3.Walled) { AddWallSegment(c3, cell3, c1, cell1, c2, cell2); } }
/// <summary> /// Gets all hex cells in a given range from a specified point. /// </summary> /// <param name="fromCell"> Starting cell </param> /// <param name="range"> How many hexes from the origin it will search in a circle </param> /// <returns> List of Hex cells in a radius from the center hex </returns> List <HexCell> GetVisibleCells(HexCell fromCell, int range) { List <HexCell> visibleCells = ListPool <HexCell> .Get(); searchFrontierPhase += 2; if (searchFrontier == null) { searchFrontier = new HexCellPriorityQueue(); } else { searchFrontier.Clear(); } range += fromCell.ViewElevation; fromCell.SearchPhase = searchFrontierPhase; fromCell.Distance = 0; HexCoordinates fromCoordinates = fromCell.coordinates; searchFrontier.Enqueue(fromCell); while (searchFrontier.Count > 0) { HexCell current = searchFrontier.Dequeue(); current.SearchPhase += 1; visibleCells.Add(current); for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++) { HexCell neighbour = current.GetNeighbor(d); if (neighbour == null || neighbour.SearchPhase > searchFrontierPhase || !neighbour.Explorable) { continue; } int distance = current.Distance + 1; if (distance + neighbour.ViewElevation > range || distance > fromCoordinates.DistanceTo(neighbour.coordinates)) { continue; } if (neighbour.SearchPhase < searchFrontierPhase) { neighbour.Distance = distance; neighbour.SearchPhase = searchFrontierPhase; neighbour.SearchHeuristic = 0; searchFrontier.Enqueue(neighbour); } else if (distance < neighbour.Distance) { int oldPriority = neighbour.SearchPriority; neighbour.Distance = distance; searchFrontier.Change(neighbour, oldPriority); } } } return(visibleCells); }
void Triangulate(HexCell cell) { for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++) { Triangulate(d, cell); } }