void TriangulateWithRiverBeginOrEnd(HexDirection direction, HexCell_Script cell, Vector3 center, EdgeVertices e) { EdgeVertices m = new EdgeVertices(Vector3.Lerp(center, e.v1, 0.5f), Vector3.Lerp(center, e.v5, 0.5f)); m.v3.y = e.v3.y; TriangulateEdgeStrip(m, color1, cell.TerrainTypeIndex, e, color1, cell.TerrainTypeIndex); TriangulateEdgeFan(center, m, cell.TerrainTypeIndex); if (!cell.IsUnderwater) { bool reversed = cell.HasIncomingRiver; TriangulateRiverQuad(m.v2, m.v4, e.v2, e.v4, reversed, cell.RiverSurfaceY, 0.6f); center.y = m.v2.y = m.v4.y = cell.RiverSurfaceY; rivers.AddTriangle(center, m.v2, m.v4); if (reversed) { rivers.AddTriangleUV(new Vector2(0.5f, 0.4f), new Vector2(1f, 0.2f), new Vector2(0f, 0.2f)); } else { rivers.AddTriangleUV(new Vector2(0.5f, 0.4f), new Vector2(0f, 0.6f), new Vector2(1f, 0.6f)); } } }
public void AddCell(int index, HexCell_Script cell) { cells[index] = cell; cell.chunk = this; cell.transform.SetParent(transform, false); cell.uiRect.SetParent(gridCanvas.transform, false); }
void TriangulateCornerCliffTerraces(Vector3 begin, HexCell_Script beginCell, Vector3 left, HexCell_Script leftCell, Vector3 right, HexCell_Script rightCell) { float b = 1f / (leftCell.Elevation - beginCell.Elevation); if (b < 0) { b = -b; } Vector3 boundary = Vector3.Lerp(HexMetrics_Script.Perturb(begin), HexMetrics_Script.Perturb(left), b); Color boundaryColor = Color.Lerp(color1, color2, b); Vector3 types; types.x = beginCell.TerrainTypeIndex; types.y = beginCell.TerrainTypeIndex; types.z = beginCell.TerrainTypeIndex; TriangulateBoundaryTriangle(right, color3, begin, color1, boundary, boundaryColor, types); if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope) { TriangulateBoundaryTriangle(left, color2, right, color3, boundary, boundaryColor, types); } else { terrain.AddTriangleUnperturbed(HexMetrics_Script.Perturb(left), HexMetrics_Script.Perturb(right), boundary); //Search for Rand Error terrain.AddTriangleColor(color2, color3, boundaryColor); terrain.AddTriangleTerrainTypes(types); } }
void HandleInput() { HexCell_Script currentCell = GetCellUnderCursor(); if (currentCell) { if (previousCell && previousCell != currentCell) { ValidateDrag(currentCell); } else { isDrag = false; } EditCells(currentCell); previousCell = currentCell; isDrag = true; } else { previousCell = null; } }
void TriangulateOpenWater(HexDirection direction, HexCell_Script cell, HexCell_Script neighbor, Vector3 center) { Vector3 c1 = center + HexMetrics_Script.GetFirstWaterCorner(direction); Vector3 c2 = center + HexMetrics_Script.GetSecondWaterCorner(direction); water.AddTriangle(center, c1, c2); if (direction <= HexDirection.SE && neighbor != null) { Vector3 bridge = HexMetrics_Script.GetWaterBridge(direction); Vector3 e1 = c1 + bridge; Vector3 e2 = c2 + bridge; water.AddQuad(c1, c2, e1, e2); if (direction <= HexDirection.E) { HexCell_Script nextNeighbor = cell.GetNeighbor(direction.Next()); if (nextNeighbor == null || !nextNeighbor.IsUnderwater) { return; } water.AddTriangle(c2, e2, c2 + HexMetrics_Script.GetWaterBridge(direction.Next())); } } }
public void AddUnit(HexUnit_Script unit, HexCell_Script location, float orientation) { units.Add(unit); unit.transform.SetParent(transform, false); unit.Location = location; unit.Orientation = orientation; }
void TriangulateAdjacentToRiver(HexDirection direction, HexCell_Script cell, Vector3 center, EdgeVertices e) { if (cell.HasRoads) { TriangulateRoadAdjacentToRiver(direction, cell, center, e); } if (cell.HasRiverThroughEdge(direction.Next())) { if (cell.HasRiverThroughEdge(direction.Previous())) { center += HexMetrics_Script.GetSolidEdgeMiddle(direction) * (HexMetrics_Script.innerToOuter * 0.5f); } else if (cell.HasRiverThroughEdge(direction.Previous2())) { center += HexMetrics_Script.GetFirstSolidCorner(direction) * 0.25f; } } else if (cell.HasRiverThroughEdge(direction.Previous()) && cell.HasRiverThroughEdge(direction.Next2())) { center += HexMetrics_Script.GetSecondSolidCorner(direction) * 0.25f; } EdgeVertices m = new EdgeVertices(Vector3.Lerp(center, e.v1, 0.5f), Vector3.Lerp(center, e.v5, 0.5f)); TriangulateEdgeStrip(m, color1, cell.TerrainTypeIndex, e, color1, cell.TerrainTypeIndex); TriangulateEdgeFan(center, m, cell.TerrainTypeIndex); if (!cell.IsUnderwater && !cell.HasRoadThroughEdge(direction)) { features.AddFeature(cell, (center + e.v1 + e.v5) * (1f / 3f)); } }
public void SetOutgoingRiver(HexDirection direction) { if (HasOutgoingRiver && outgoingRiver == direction) { return; } HexCell_Script neighbor = GetNeighbor(direction); if (!IsValidRiverDestination(neighbor)) { return; } RemoveOutgoingRiver(); if (hasIncomingRiver && incomingRiver == direction) { RemoveIncomingRiver(); } hasOutgoingRiver = true; outgoingRiver = direction; specialIndex = 0; //RefreshSelfOnly(); neighbor.RemoveIncomingRiver(); neighbor.hasIncomingRiver = true; neighbor.incomingRiver = direction.Opposite(); neighbor.specialIndex = 0; //neighbor.RefreshSelfOnly(); SetRoad((int)direction, false); }
void CreateUnit() { HexCell_Script cell = GetCellUnderCursor(); if (cell && !cell.Unit) { hexGrid.AddUnit(Instantiate(HexUnit_Script.unitPrefab), cell, Random.Range(0f, 360f)); } }
void ErodeLand() { List <HexCell_Script> erodibleCells = ListPool <HexCell_Script> .Get(); for (int i = 0; i < cellCount; i++) { HexCell_Script cell = grid.GetCell(i); if (IsErodible(cell)) { erodibleCells.Add(cell); } } int targetErodibleCount = (int)(erodibleCells.Count * (100 - erosionPercentage) * 0.01f); while (erodibleCells.Count > targetErodibleCount) { int index = Random.Range(0, erodibleCells.Count); HexCell_Script cell = erodibleCells[index]; HexCell_Script targetCell = GetErosionTarget(cell); cell.Elevation--; targetCell.Elevation++; if (!IsErodible(cell)) { erodibleCells[index] = erodibleCells[erodibleCells.Count - 1]; erodibleCells.RemoveAt(erodibleCells.Count - 1); } for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++) { HexCell_Script neigbor = cell.GetNeighbor(d); if (neigbor && neigbor.Elevation == cell.Elevation + 2 && !erodibleCells.Contains(neigbor)) { erodibleCells.Add(neigbor); } } if (IsErodible(targetCell) && !erodibleCells.Contains(targetCell)) { erodibleCells.Add(targetCell); } for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++) { HexCell_Script neighbor = targetCell.GetNeighbor(d); if (neighbor && neighbor != cell && !IsErodible(neighbor) && neighbor.Elevation == targetCell.Elevation + 1) { erodibleCells.Remove(neighbor); } } } ListPool <HexCell_Script> .Add(erodibleCells); }
void DestroyUnit() { HexCell_Script cell = GetCellUnderCursor(); if (cell && cell.Unit) { hexGrid.RemoveUnit(cell.Unit); } }
public void AddSpecialFeature(HexCell_Script cell, Vector3 position) { Transform instance = Instantiate(specials[cell.SpecialIndex - 1]); instance.localPosition = HexMetrics_Script.Perturb(position); HexHash hash = HexMetrics_Script.SampleHashGrid(position); instance.localRotation = Quaternion.Euler(0f, 360f * hash.e, 0f); instance.SetParent(container, false); }
void AddCellToChunk(int x, int z, HexCell_Script cell) { int chunkX = x / HexMetrics_Script.chunkSizeX; int chunkZ = z / HexMetrics_Script.chunkSizeZ; HexGridChunk_Script chunk = chunks[chunkX + chunkZ * chunkCountX]; int localX = x - chunkX * HexMetrics_Script.chunkSizeX; int localZ = z - chunkZ * HexMetrics_Script.chunkSizeZ; chunk.AddCell(localX + localZ * HexMetrics_Script.chunkSizeX, cell); }
void SetTerrainType() { for (int i = 0; i < cellCount; i++) { HexCell_Script cell = grid.GetCell(i); if (!cell.IsUnderwater) { cell.TerrainTypeIndex = cell.Elevation - cell.WaterLevel; } } }
bool UpdateCurrentCell() { HexCell_Script cell = grid.GetCell(Camera.main.ScreenPointToRay(Input.mousePosition)); if (cell != currentCell) { currentCell = cell; return(true); } return(false); }
//public void Refresh() //{ // hexMesh.Triangulate(cells); //} void CreateCell(int x, int z, int i) { Vector3 position; position.x = (x + z * 0.5f - z / 2) * (HexMetrics_Script.innerRadius * 2f); position.y = 0f; position.z = z * (HexMetrics_Script.outerRadius * 1.5f); HexCell_Script cell = cells[i] = Instantiate <HexCell_Script>(cellPrefab); //cell.transform.SetParent(transform, false); cell.transform.localPosition = position; cell.coordinates = HexCoordinates.FromOffsetCoordinates(x, z); //cell.Color = defaultColor; if (x > 0) { cell.SetNeighbor(HexDirection.W, cells[i - 1]); } 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 { cell.SetNeighbor(HexDirection.SW, cells[i - cellCountX]); if (x < cellCountX - 1) { cell.SetNeighbor(HexDirection.SE, cells[i - cellCountX + 1]); } } } Text label = Instantiate <Text>(cellLabelPrefab); //label.rectTransform.SetParent(gridCanvas.transform, false); label.rectTransform.anchoredPosition = new Vector2(position.x, position.z); //label.text = cell.coordinates.ToStringOnSeparateLines(); cell.uiRect = label.rectTransform; cell.Elevation = 0; AddCellToChunk(x, z, cell); //Test cell.DisableHighlight(); }
public void AddFeature(HexCell_Script cell, Vector3 position) { if (cell.IsSpecial) { return; } HexHash hash = HexMetrics_Script.SampleHashGrid(position); //if (hash.a >= cell.UrbanLevel*0.25f) // return; //Transform instance = Instantiate(urbanPrefabs[cell.UrbanLevel-1]); Transform prefab = PickPrefab(urbanPrefabs, cell.UrbanLevel, hash.a, hash.d); Transform otherprefab = PickPrefab(farmPrefabs, cell.FarmLevel, hash.b, hash.d); float usedHash = hash.a; if (prefab) { if (otherprefab && hash.b < hash.a) { prefab = otherprefab; usedHash = hash.b; } } else if (otherprefab) { prefab = otherprefab; usedHash = hash.b; } otherprefab = PickPrefab(plantPrefabs, cell.PlantLevel, hash.c, hash.d); if (prefab) { if (otherprefab && hash.c < usedHash) { prefab = otherprefab; } } else if (otherprefab) { prefab = otherprefab; } else { return; } Transform instance = Instantiate(prefab); position.y += instance.localScale.y * 0.5f; instance.localPosition = HexMetrics_Script.Perturb(position); instance.localRotation = Quaternion.Euler(0f, 360f * hash.e, 0f); instance.SetParent(container, false); }
void TriangulateWithoutRiver(HexDirection direction, HexCell_Script cell, Vector3 center, EdgeVertices e) { TriangulateEdgeFan(center, e, cell.TerrainTypeIndex); if (cell.HasRoads) { Vector2 interpolators = GetRoadInterpolators(direction, cell); TriangulateRoad(center, Vector3.Lerp(center, e.v1, interpolators.x), Vector3.Lerp(center, e.v5, interpolators.y), e, cell.HasRoadThroughEdge(direction)); } }
void ValidateDrag(HexCell_Script currentCell) { for (dragDirection = HexDirection.NE; dragDirection <= HexDirection.NW; dragDirection++) { if (previousCell.GetNeighbor(dragDirection) == currentCell) { isDrag = true; return; } } isDrag = false; }
public HexCell_Script Dequeue() { count--; for (; minimum < list.Count; minimum++) { HexCell_Script cell = list[minimum]; if (cell != null) { list[minimum] = cell.NextWithSamePriority; return(cell); } } return(null); }
public void RemoveIncomingRiver() { if (!hasIncomingRiver) { return; } hasIncomingRiver = false; RefreshSelfOnly(); HexCell_Script neighbor = GetNeighbor(incomingRiver); neighbor.hasOutgoingRiver = false; neighbor.RefreshSelfOnly(); }
bool IsErodible(HexCell_Script cell) { int erodibleElevation = cell.Elevation - 2; for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++) { HexCell_Script neighbor = cell.GetNeighbor(d); if (neighbor && neighbor.Elevation <= erodibleElevation) { return(true); } } return(false); }
int RaiseTerrain(int chunkSize, int budget, MapRegion region) { searchFrontierPhase++; HexCell_Script firstCell = GetRandomCell(region); firstCell.SearchPhase = searchFrontierPhase; firstCell.Distance = 0; firstCell.SearchHeuristic = 0; searchFrontier.Enqueue(firstCell); HexCoordinates center = firstCell.coordinates; int rise = Random.value < highRiseProbability ? 2 : 1; int size = 0; while (size < chunkSize && searchFrontier.Count > 0) { HexCell_Script current = searchFrontier.Dequeue(); int originalElevation = current.Elevation; int newElevation = originalElevation + rise; if (newElevation > elevationMaximum) { continue; } current.Elevation = newElevation; if (originalElevation < waterLevel && newElevation >= waterLevel && --budget == 0) { break; } size++; for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++) { HexCell_Script neighbor = current.GetNeighbor(d); if (neighbor && neighbor.SearchPhase < searchFrontierPhase) { neighbor.SearchPhase = searchFrontierPhase; neighbor.Distance = neighbor.coordinates.DistanceTo(center); neighbor.SearchHeuristic = Random.value < jitterProbabitlity ? 1 : 0;; searchFrontier.Enqueue(neighbor); } } } searchFrontier.Clear(); return(budget); }
public void FindPath(HexCell_Script fromCell, HexCell_Script toCell, int speed) { //StopAllCoroutines(); //StartCoroutine(Search(fromCell,toCell,speed)); System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); sw.Start(); ClearPath(); currentPathFrom = fromCell; currentPathTo = toCell; currenPathExists = Search(fromCell, toCell, speed); ShowPath(speed); sw.Stop(); Debug.Log(sw.ElapsedMilliseconds); }
void AddWallSegment(Vector3 pivot, HexCell_Script pivotCell, Vector3 left, HexCell_Script leftCell, Vector3 right, HexCell_Script rightCell) { if (pivotCell.IsUnderwater) { return; } bool hasLeftWall = !leftCell.IsUnderwater && pivotCell.GetEdgeType(leftCell) != HexEdgeType.Cliff; bool hasRightWall = !rightCell.IsUnderwater && pivotCell.GetEdgeType(rightCell) != HexEdgeType.Cliff; if (hasLeftWall) { if (hasRightWall) { bool hasTower = false; if (leftCell.Elevation == rightCell.Elevation) { HexHash hash = HexMetrics_Script.SampleHashGrid((pivot + left + right) * (1f / 3f)); hasTower = hash.e < HexMetrics_Script.wallTowerTreshold; } AddWallSegment(pivot, left, pivot, right, hasTower); } else if (leftCell.Elevation < rightCell.Elevation) { AddWallWedge(pivot, left, right); } else { AddWallCap(pivot, left); } } else if (hasRightWall) { if (rightCell.Elevation < leftCell.Elevation) { AddWallWedge(right, pivot, left); } else { AddWallCap(right, pivot); } } }
Vector2 GetRoadInterpolators(HexDirection direction, HexCell_Script cell) { Vector2 interpolators; if (cell.HasRoadThroughEdge(direction)) { interpolators.x = interpolators.y = 0.5f; } else { interpolators.x = cell.HasRoadThroughEdge(direction.Previous()) ? 0.5f : 0.25f; interpolators.y = cell.HasRoadThroughEdge(direction.Next()) ? 0.5f : 0.25f; } return(interpolators); }
void Triangulate(HexCell_Script cell) { for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++) { Triangulate(d, cell); } if (!cell.IsUnderwater && !cell.HasRiver && !cell.HasRoads) { features.AddFeature(cell, cell.Position); } if (!cell.IsUnderwater && cell.IsSpecial) { features.AddSpecialFeature(cell, cell.Position); } }
void TriangulateWater(HexDirection direction, HexCell_Script cell, Vector3 center) { center.y = cell.WaterSurfaceY; HexCell_Script neighbor = cell.GetNeighbor(direction); if (neighbor != null && !neighbor.IsUnderwater) { TriangulateWaterShore(direction, cell, neighbor, center); } else { TriangulateOpenWater(direction, cell, neighbor, center); } }
void TriangulateWaterShore(HexDirection direction, HexCell_Script cell, HexCell_Script neighbor, Vector3 center) { EdgeVertices e1 = new EdgeVertices(center + HexMetrics_Script.GetFirstWaterCorner(direction), center + HexMetrics_Script.GetSecondWaterCorner(direction)); water.AddTriangle(center, e1.v1, e1.v2); water.AddTriangle(center, e1.v2, e1.v3); water.AddTriangle(center, e1.v3, e1.v4); water.AddTriangle(center, e1.v4, e1.v5); Vector3 center2 = neighbor.Position; center2.y = center.y; EdgeVertices e2 = new EdgeVertices(center2 + HexMetrics_Script.GetSecondSolidCorner(direction.Opposite()), center2 + HexMetrics_Script.GetFirstSolidCorner(direction.Opposite())); if (cell.HasRiverThroughEdge(direction)) { TriangulateEstuary(e1, e2, cell.IncomingRiver == direction); } else { waterShore.AddQuad(e1.v1, e1.v2, e2.v1, e2.v2); waterShore.AddQuad(e1.v2, e1.v3, e2.v2, e2.v3); waterShore.AddQuad(e1.v3, e1.v4, e2.v3, e2.v4); waterShore.AddQuad(e1.v4, e1.v5, e2.v4, e2.v5); waterShore.AddQuadUV(0f, 0f, 0f, 1f); waterShore.AddQuadUV(0f, 0f, 0f, 1f); waterShore.AddQuadUV(0f, 0f, 0f, 1f); waterShore.AddQuadUV(0f, 0f, 0f, 1f); } HexCell_Script nextNeighbor = cell.GetNeighbor(direction.Next()); if (nextNeighbor != null) { Vector3 v3 = nextNeighbor.Position + (nextNeighbor.IsUnderwater ? HexMetrics_Script.GetFirstWaterCorner(direction.Previous()) : HexMetrics_Script.GetFirstSolidCorner(direction.Previous())); v3.y = center.y; waterShore.AddTriangle(e1.v5, e2.v5, v3); waterShore.AddTriangleUV( new Vector2(0f, 0f), new Vector2(0f, 1f), new Vector2(0f, nextNeighbor.IsUnderwater?0f:1f)); } }
public void Enqueue(HexCell_Script cell) { count++; int priority = cell.SearchPriority; if (priority < minimum) { minimum = priority; } while (priority >= list.Count) { list.Add(null); } cell.NextWithSamePriority = list[priority]; list[priority] = cell; }