void FillHole(SquareCell cell, Vector3 v1) { SquareCell eastNeighbor = cell.GetNeighbor(SquareDirection.E); SquareCell northNeighbor = cell.GetNeighbor(SquareDirection.N); SquareCell northEastNeighbor = null; if (northNeighbor == null || eastNeighbor == null) { return; } northEastNeighbor = cell.GetNeighbor(SquareDirection.N).GetNeighbor(SquareDirection.E); Vector3 bridgeN = SquareMetrics.GetBridge(SquareDirection.N); Vector3 n = v1 + bridgeN; Vector3 bridgeE = SquareMetrics.GetBridge(SquareDirection.E); Vector3 e = v1 + bridgeE; Vector3 ne = v1 + bridgeN + bridgeE; Color northColor, eastColor, northEastColor; northColor = eastColor = northEastColor = cell.Color; if (northNeighbor != null) { n.y = northNeighbor.transform.localPosition.y; northColor = northNeighbor.Color; } if (eastNeighbor != null) { e.y = eastNeighbor.transform.localPosition.y; eastColor = eastNeighbor.Color; } if (northEastNeighbor != null) { ne.y = northEastNeighbor.transform.localPosition.y; northEastColor = northEastNeighbor.Color; } Vector3 center = v1 + 0.5f * (bridgeN + bridgeE); center.y = (Mathf.Max(v1.y, e.y, n.y, ne.y) + Mathf.Min(v1.y, e.y, n.y, ne.y)) / 2f; Color blendColor = GetBlendColor(cell.Color, northColor, eastColor, northEastColor); // Triangle vertices should be clockwise // First Triangle to add will be v1, n, center AddTriangle(v1, n, center); AddTriangleColor(cell.Color, northColor, blendColor); // Second will be v1, center, e AddTriangle(v1, center, e); AddTriangleColor(cell.Color, blendColor, eastColor); // Third will be n, ne, center AddTriangle(n, ne, center); AddTriangleColor(northColor, northEastColor, blendColor); // Last is ne, e, center AddTriangle(ne, e, center); AddTriangleColor(northEastColor, eastColor, blendColor); }
public void ConnectWithNeighbours() { for (int i = 0; i < 8; i += 2) { if (parentCell.HasRoadThroughEdge((GridDirection)i) && parentCell.GetNeighbor((GridDirection)i).roadNetwork.nodes.Count > 0) { ConnectWithNeigbour(parentCell.GetNeighbor((GridDirection)i), (GridDirection)i); } } }
public void AddRoad() { SquareCell randomRoad = townRoads[Random.Range(0, townRoads.Count)]; GridDirection randomDirection = (GridDirection)(Random.Range(0, 3) * 2); SquareCell randomNeighbour = randomRoad.GetNeighbor(randomDirection); if (randomNeighbour && randomNeighbour.UrbanLevel == 0 && !townRoads.Contains(randomNeighbour)) { randomRoad.AddRoad(randomDirection); randomNeighbour.AddRoad(randomDirection.Opposite()); townRoads.Add(randomNeighbour); } }
public void MakeBuilding() { SquareCell randomRoad = townRoads[Random.Range(0, townRoads.Count)]; GridDirection randomDirection = (GridDirection)(Random.Range(0, 3) * 2); SquareCell randomNeighbour = randomRoad.GetNeighbor(randomDirection); if (randomNeighbour && !randomNeighbour.HasRoads) { randomNeighbour.UrbanLevel++; if (!townBuildings.Contains(randomNeighbour)) { townBuildings.Add(randomNeighbour); } } }
private void BuildBridge(SquareDirection direction, SquareCell cell, Vector3 v1, Vector3 v2) { SquareCell neighbor = cell.GetNeighbor(direction); if (neighbor == null) { return; } Vector3 bridge = SquareMetrics.GetBridge(direction); Vector3 v3 = v1 + bridge; Vector3 v4 = v2 + bridge; v3.y = v4.y = neighbor.transform.localPosition.y; AddQuad(v1, v2, v3, v4); AddQuadColor(cell.Color, neighbor.Color); }
void AddCliffEdge(SquareCell cell, GridDirection direction) { GridDirection prev = direction.Previous(); GridDirection next = direction.Next(); GridDirection prevN = prev.Previous2(); GridDirection nextN = next.Next2(); SquareCell neighbor = cell.GetNeighbor(direction); if (neighbor != null) { Vector3 c0 = new Vector3(cell.coordinates.X, 0, cell.coordinates.Z) + GridMetrics.GetEdge(prev) + Vector3.up * (int)cell.GridElevations[prev] * GridMetrics.elevationStep; Vector3 c1 = new Vector3(cell.coordinates.X, 0, cell.coordinates.Z) + GridMetrics.GetEdge(next) + Vector3.up * (int)cell.GridElevations[next] * GridMetrics.elevationStep; Vector3 n0 = new Vector3(neighbor.coordinates.X, 0, neighbor.coordinates.Z) + GridMetrics.GetEdge(prevN) + Vector3.up * (int)neighbor.GridElevations[prevN] * GridMetrics.elevationStep; Vector3 n1 = new Vector3(neighbor.coordinates.X, 0, neighbor.coordinates.Z) + GridMetrics.GetEdge(nextN) + Vector3.up * (int)neighbor.GridElevations[nextN] * GridMetrics.elevationStep; if (c0 != n0 && c1 != n1) { if (c0.y > n0.y && n1.y > c1.y) // if edges cross heights along edge X { Vector2 cross = CrossingPoint(c1.y - c0.y, n1.y - n0.y, c0.y, n0.y); Vector3 worldCross = new Vector3(cell.coordinates.X, 0, cell.coordinates.Z) + GridMetrics.GetEdge(direction.Previous()) + (cross.x * 2 * GridMetrics.GetEdge(direction.Next2())) + new Vector3(0, cross.y, 0); terrain.AddTriangle(worldCross, c0, n0); terrain.AddTriangleColor(Color.cyan); terrain.AddTriangle(worldCross, n1, c1); terrain.AddTriangleColor(Color.green); } else if (c0.y > n0.y && c1.y > n1.y) // if one edge is always above the other { terrain.AddQuad(c0, n0, n1, c1); terrain.AddQuadColor(retainingWallColor); } } else if (c0.y > n0.y) { terrain.AddTriangle(c0, n0, c1); terrain.AddTriangleColor(retainingWallColor); } else if (c1.y > n1.y) { terrain.AddTriangle(c0, n1, c1); terrain.AddTriangleColor(retainingWallColor); } } }
public void SetupFoundations(SquareCell origin) { List <SquareCell> foundationList = new List <SquareCell>(); height = origin.GetMaxElevation(); owner = origin.Town; SquareCell tempCellx = origin; SquareCell tempCelly = origin; for (int x = 0; x < width; x++) { tempCelly = tempCellx; for (int y = 0; y < depth; y++) { foundationList.Add(tempCelly); tempCelly = tempCelly.GetNeighbor(GridDirection.N); } tempCellx = tempCellx.GetNeighbor(GridDirection.E); } Foundations = foundationList.ToArray(); }
void TriangulateWithRiver( GridDirection direction, SquareCell cell, Vector3 centre, Vector3 v0, Vector3 v1, Vector3 v2, Vector3 v3, float v ) { GridDirection flowDirection; bool reversed = cell.HasIncomingRiver[(int)direction]; if (cell.HasOutgoingRiver[(int)direction]) { flowDirection = direction; } else if (reversed) { flowDirection = direction.Opposite(); } else { if (cell.HasIncomingRiver[(int)direction.Next2()] && cell.HasOutgoingRiver[(int)direction.Previous2()]) { flowDirection = direction.Previous2(); } else if (cell.HasOutgoingRiver[(int)direction.Next2()] && cell.HasIncomingRiver[(int)direction.Previous2()]) { flowDirection = direction.Next2(); } else { flowDirection = direction.Opposite(); } } TriangulateRiverTri(centre, v0, v3, cell.RiverSurfaceY, reversed, direction, flowDirection); SquareCell neighbor = cell.GetNeighbor(direction); if (neighbor && cell.HasRiverThroughEdge(direction)) { TriangulateRiverQuad(v3, v0, v1, v2, cell.RiverSurfaceY, neighbor.RiverSurfaceY, 0.8f, reversed); } }
void EditCell(SquareCell cell, Vector3 hitpoint) { if (activeMode == EditMode.color) { cell.Tile = activeTileMaterial.GetClone; } else if (activeMode == EditMode.elevation) { GridDirection vertex = squareGrid.GetVertex(hitpoint); if (Input.GetMouseButton(0) && (stopWatch.ElapsedMilliseconds > 500f || freshClick)) { cell.ChangeVertexElevation(vertex, 1); if (!allowCliffs) { if (cell.GetNeighbor(vertex)) { cell.GetNeighbor(vertex).ChangeVertexElevation(vertex.Opposite(), 1); } if (cell.GetNeighbor(vertex.Next())) { cell.GetNeighbor(vertex.Next()).ChangeVertexElevation(vertex.Previous2(), 1); } if (cell.GetNeighbor(vertex.Previous())) { cell.GetNeighbor(vertex.Previous()).ChangeVertexElevation(vertex.Next2(), 1); } } stopWatch.Reset(); stopWatch.Start(); } if (Input.GetMouseButton(1) && (stopWatch.ElapsedMilliseconds > 500f || freshClick)) { cell.ChangeVertexElevation(vertex, -1); if (!allowCliffs) { if (cell.GetNeighbor(vertex)) { cell.GetNeighbor(vertex).ChangeVertexElevation(vertex.Opposite(), -1); } if (cell.GetNeighbor(vertex.Next())) { cell.GetNeighbor(vertex.Next()).ChangeVertexElevation(vertex.Previous2(), -1); } if (cell.GetNeighbor(vertex.Previous())) { cell.GetNeighbor(vertex.Previous()).ChangeVertexElevation(vertex.Next2(), -1); } } stopWatch.Reset(); stopWatch.Start(); } } else if (activeMode == EditMode.rivers) { if (Input.GetMouseButton(1)) { cell.RemoveRivers(); Explosion(cell); } else if (isDrag) { SquareCell otherCell = cell.GetNeighbor(dragDirection.Opposite()); // work with brushes if (otherCell) { otherCell.SetOutgoingRiver(dragDirection); } } } else if (activeMode == EditMode.roads) { float fracX = hitpoint.x - Mathf.Floor(hitpoint.x); float fracZ = hitpoint.z - Mathf.Floor(hitpoint.z); if (fracX > 0.25f && fracX < 0.75f || fracZ > 0.25f && fracZ < 0.75f) { GridDirection edge = squareGrid.GetEdge(hitpoint); if (Input.GetMouseButton(1)) { cell.RemoveRoad(edge); Explosion(cell); } else { cell.AddRoad(edge); } } } else if (activeMode == EditMode.water_level) { if (Input.GetMouseButton(0) && freshClick) { cell.WaterLevel++; } else if (Input.GetMouseButton(1) && freshClick) { cell.WaterLevel--; } } else if (activeMode == EditMode.building) { if (Input.GetMouseButton(0) && freshClick) { cell.UrbanLevel++; } if (Input.GetMouseButton(1) && freshClick) { cell.UrbanLevel = 0; Explosion(cell); } } else if (activeMode == EditMode.trees) { if (Input.GetMouseButton(0) && freshClick) { cell.PlantLevel++; } if (Input.GetMouseButton(1) && freshClick) { cell.PlantLevel = 0; Explosion(cell); } } else if (activeMode == EditMode.rocks) { if (Input.GetMouseButton(0) && freshClick) { cell.ScenaryObject = 1; } if (Input.GetMouseButton(1) && freshClick) { cell.ScenaryObject = 0; Explosion(cell); } } else if (activeMode == EditMode.mast) { if (Input.GetMouseButton(0) && freshClick) { cell.ScenaryObject = 2; } if (Input.GetMouseButton(1) && freshClick) { cell.ScenaryObject = 0; Explosion(cell); } } else if (activeMode == EditMode.lighthouse) { if (Input.GetMouseButton(0) && freshClick) { cell.ScenaryObject = 3; } if (Input.GetMouseButton(1) && freshClick) { cell.ScenaryObject = 0; Explosion(cell); } } else if (activeMode == EditMode.industry) { if (Input.GetMouseButton(0) && freshClick) { cell.Industry = (int)activeIndustry + 1; } if (Input.GetMouseButton(1) && freshClick) { cell.Industry = 0; Explosion(cell); } } else if (activeMode == EditMode.town) { if (cell.Town == null) { GameObject town = Instantiate(townPrefab); TownManager manager = town.GetComponent <TownManager>(); town.transform.position = GridCoordinates.ToPosition(cell.coordinates) + new Vector3(0, cell.CentreElevation * GridMetrics.elevationStep, 0); manager.Init(cell); cell.Town = manager; } } }
void AddColors(SquareCell cell, GridDirection direction) { SquareCell prevNeighbor = cell.GetNeighbor(direction.Previous()) ?? cell; SquareCell neighbor = cell.GetNeighbor(direction) ?? cell; SquareCell nextNeighbor = cell.GetNeighbor(direction.Next()) ?? cell; SquareCell next2Neighbor = cell.GetNeighbor(direction.Next2()) ?? cell; SquareCell next3Neighbor = cell.GetNeighbor(direction.Next3()) ?? cell; Color previousMix = (GetColor(prevNeighbor, cell) + cell.Color) / 2f; Color neighborMix = (GetColor(neighbor, cell) + cell.Color + GetColor(prevNeighbor, cell) + GetColor(nextNeighbor, cell)) / 4f; Color nextMix = (GetColor(nextNeighbor, cell) + cell.Color) / 2f; Color nextNeighborMix = (GetColor(nextNeighbor, cell) + cell.Color + GetColor(next2Neighbor, cell) + GetColor(next3Neighbor, cell)) / 4f; Color next2Mix = (GetColor(next3Neighbor, cell) + cell.Color) / 2f; if (cell.HasRiver) { if (cell.HasRiverThroughEdge(direction.Previous())) { terrain.AddTriangleColor(cell.Color); } if (cell.HasRiverThroughEdge(direction.Next())) { terrain.AddTriangleColor(cell.Color); } terrain.AddTriangleColor(cell.Color); terrain.AddTriangleColor(cell.Color); } else { terrain.AddTriangleColor(cell.Color); } if (cell.HasRiverThroughEdge(direction.Next())) { terrain.AddQuadColor(cell.Color, nextMix, nextMix, cell.Color); terrain.AddQuadColor(cell.Color, nextMix, nextMix, cell.Color); } else { terrain.AddQuadColor(cell.Color, nextMix, nextMix, cell.Color); } // next Edge if (cell.HasRiverThroughEdge(direction.Previous())) { terrain.AddQuadColor(cell.Color, cell.Color, previousMix, previousMix); terrain.AddQuadColor(cell.Color, cell.Color, previousMix, previousMix); } else { terrain.AddQuadColor(cell.Color, cell.Color, previousMix, previousMix); } // previous Edge if (cell.HasRiverThroughEdge(direction)) { } else { terrain.AddQuadColor(cell.Color, previousMix, neighborMix, nextMix); } // direction Corner if (cell.HasRiverThroughEdge(direction.Next2())) { } else { terrain.AddQuadColor(cell.Color, nextMix, nextNeighborMix, next2Mix); } // next Corner }
void AddHalfCell(SquareCell cell, GridDirection direction, Vector3 centre, Vector3 v0, Vector3 v1, Vector3 v2, Vector3 va, Vector3 vb, Vector3 vc, Vector3 vd, Vector3 vx, Vector3 vy, Vector3 vz) { Vector3 riverbed = centre + Vector3.up * (cell.CentreElevation + GridMetrics.streamBedElevationOffset) * GridMetrics.elevationStep; Vector3 midSolidEdgePrev = centre + GridMetrics.GetSolidEdge(direction.Previous()) + Vector3.up * (cell.CentreElevation + GridMetrics.streamBedElevationOffset) * GridMetrics.elevationStep; Vector3 midSolidEdgeNext = centre + GridMetrics.GetSolidEdge(direction.Next()) + Vector3.up * (cell.CentreElevation + GridMetrics.streamBedElevationOffset) * GridMetrics.elevationStep; SquareCell neighborPrev = cell.GetNeighbor(direction.Previous()) ?? cell; SquareCell neighborNext = cell.GetNeighbor(direction.Next()) ?? cell; Vector3 midEdgePrev = centre + GridMetrics.GetEdge(direction.Previous()) + Vector3.up * ((cell.CentreElevation + neighborPrev.CentreElevation) / 2 + GridMetrics.streamBedElevationOffset) * GridMetrics.elevationStep; Vector3 midEdgeNext = centre + GridMetrics.GetEdge(direction.Next()) + Vector3.up * ((cell.CentreElevation + neighborNext.CentreElevation) / 2 + GridMetrics.streamBedElevationOffset) * GridMetrics.elevationStep; if (cell.HasRiver) { if (cell.HasRiverThroughEdge(direction.Previous())) { terrain.AddTriangle(v0, midSolidEdgePrev, riverbed); // split tri into two tris terrain.AddTriangle(midSolidEdgePrev, v1, riverbed); } else { terrain.AddTriangle(v0, v1, riverbed); } // edge with no river if (cell.HasRiverThroughEdge(direction.Next())) { terrain.AddTriangle(v1, midSolidEdgeNext, riverbed); // split tri into two tris terrain.AddTriangle(midSolidEdgeNext, v2, riverbed); } else { terrain.AddTriangle(v1, v2, riverbed); } // edge with no river } else { terrain.AddTriangle(v0, v1, v2); } if (cell.HasRiverThroughEdge(direction.Next())) { terrain.AddQuad(v1, va, midEdgeNext, midSolidEdgeNext); terrain.AddQuad(midSolidEdgeNext, midEdgeNext, vb, v2); } else { terrain.AddQuad(v1, va, vb, v2); } // top Edge if (cell.HasRiverThroughEdge(direction.Previous())) { terrain.AddQuad(v1, midSolidEdgePrev, midEdgePrev, vd); terrain.AddQuad(midSolidEdgePrev, v0, vc, midEdgePrev); } else { terrain.AddQuad(v1, v0, vc, vd); } // left Edge if (cell.HasRiverThroughEdge(direction)) { } else { terrain.AddQuad(v1, vd, vx, va); } // direction edge if (cell.HasRiverThroughEdge(direction.Next2())) { } else { terrain.AddQuad(v2, vb, vy, vz); } // clockwise edge AddColors(cell, direction); if (cell.HasRoadThroughEdge(direction.Next())) { midEdgeNext = centre + GridMetrics.GetEdge(direction.Next()) + Vector3.up * ((int)cell.GridElevations[direction] + (int)cell.GridElevations[direction.Next2()]) / 2 * GridMetrics.elevationStep; midSolidEdgeNext = centre + GridMetrics.GetSolidEdge(direction.Next()) + Vector3.up * ((int)cell.GridElevations[direction] + (int)cell.GridElevations[direction.Next2()]) / 2 * GridMetrics.elevationStep; TriangulateRoadSegment(v1, midSolidEdgeNext, v2, va, midEdgeNext, vb); } if (cell.HasRoadThroughEdge(direction.Previous())) { midEdgePrev = centre + GridMetrics.GetEdge(direction.Previous()) + Vector3.up * ((int)cell.GridElevations[direction] + (int)cell.GridElevations[direction.Previous2()]) / 2 * GridMetrics.elevationStep; midSolidEdgePrev = centre + GridMetrics.GetSolidEdge(direction.Previous()) + Vector3.up * ((int)cell.GridElevations[direction] + (int)cell.GridElevations[direction.Previous2()]) / 2 * GridMetrics.elevationStep; TriangulateRoadSegment(v0, midSolidEdgePrev, v1, vc, midEdgePrev, vd); } }
void AddWaterForSquare(SquareCell cell, Vector3 centre) { centre.y = cell.WaterSurfaceY; Vector3 c0 = centre + GridMetrics.GetEdge(GridDirection.SW); Vector3 c1 = centre + GridMetrics.GetEdge(GridDirection.NW); Vector3 c2 = centre + GridMetrics.GetEdge(GridDirection.NE); Vector3 c3 = centre + GridMetrics.GetEdge(GridDirection.SE); if (cell.IsFullyUnderwater) { water.AddQuad(c0, c1, c2, c3); } else if (cell.IsPartUnderwater) { float v0 = 0f, v1 = 0f, v2 = 0f, v3 = 0f; if (cell.GetNeighbor(GridDirection.N) && !cell.GetNeighbor(GridDirection.N).IsUnderwater) { v1 = 1f; v2 = 1f; } if (cell.GetNeighbor(GridDirection.NE) && !cell.GetNeighbor(GridDirection.NE).IsUnderwater) { v2 = 1f; } if (cell.GetNeighbor(GridDirection.E) && !cell.GetNeighbor(GridDirection.E).IsUnderwater) { v2 = 1f; v3 = 1f; } if (cell.GetNeighbor(GridDirection.SE) && !cell.GetNeighbor(GridDirection.SE).IsUnderwater) { v3 = 1f; } if (cell.GetNeighbor(GridDirection.S) && !cell.GetNeighbor(GridDirection.S).IsUnderwater) { v3 = 1f; v0 = 1f; } if (cell.GetNeighbor(GridDirection.SW) && !cell.GetNeighbor(GridDirection.SW).IsUnderwater) { v0 = 1f; } if (cell.GetNeighbor(GridDirection.W) && !cell.GetNeighbor(GridDirection.W).IsUnderwater) { v0 = 1f; v1 = 1f; } if (cell.GetNeighbor(GridDirection.NW) && !cell.GetNeighbor(GridDirection.NW).IsUnderwater) { v1 = 1f; } waterShore.AddQuad(c0, c1, c2, c3); waterShore.AddQuadV(v0, v1, v2, v3); } }