private void Triangulate(TerrainTile tile) { for (NeighbourDirection d = NeighbourDirection.TopLeft; d <= NeighbourDirection.Right; d++) { Triangulate(d, tile); } if (tile.Elevation >= (int)TileType.Mud && !tile.HasFeature) { _features.AddFeature(tile, tile.TileTopCenter); } PathfindingGrid.UpdateNode(tile); }
private int SinkTerrain(int chunkSize, int budget) { _searchFrontierPhase++; TerrainTile firstTile = GetRandomTile(); firstTile.SearchPhase = _searchFrontierPhase; firstTile.Distance = 0; firstTile.SearchHeuristic = 0; _searchFrontier.Enqueue(firstTile); int sink = UnityEngine.Random.value < highRiseProbability ? 2 : 1; int size = 0; while (size < chunkSize && _searchFrontier.Count > 0) { TerrainTile current = _searchFrontier.Dequeue(); float originalElevation = current.Elevation; float newElevation = originalElevation - sink; if (newElevation > WorldConstants.MaxElevation) { continue; } current.Elevation = newElevation; if (originalElevation >= (int)TileType.Mud && current.Elevation < (int)TileType.Mud) { budget++; } size++; for (NeighbourDirection d = NeighbourDirection.TopLeft; d <= NeighbourDirection.Right; d++) { TerrainTile neighbour = current.GetNeighbour(d); if (neighbour && neighbour.SearchPhase < _searchFrontierPhase) { neighbour.SearchPhase = _searchFrontierPhase; neighbour.Distance = neighbour.DistanceTo(firstTile); neighbour.SearchHeuristic = UnityEngine.Random.value < JitterProbability ? 1 : 0; _searchFrontier.Enqueue(neighbour); } } } _searchFrontier.Clear(); return(budget); }
private static Tile GetNeighbour(int x, int y, Tile[,] tiles2D, NeighbourDirection neighbourDirection) { Tile result = null; switch (neighbourDirection) { case NeighbourDirection.UP: if (y > 0) { result = tiles2D[y - 1, x]; } break; case NeighbourDirection.UPRIGHT: if (y > 0 && x < 4) { result = tiles2D[y - 1, x + 1]; } break; case NeighbourDirection.RIGHT: if (x < 4) { result = tiles2D[y, x + 1]; } break; case NeighbourDirection.DOWN: if (y < 4) { result = tiles2D[y + 1, x]; } break; case NeighbourDirection.DOWNLEFT: if (y < 4 && x > 0) { result = tiles2D[y + 1, x - 1]; } break; case NeighbourDirection.LEFT: if (x > 0) { result = tiles2D[y, x - 1]; } break; } return result; }
/// <summary> /// Finds the available neighbours, depending on the logical location of this satellite, in the provided direction. /// </summary> /// <param name="direction">The direction for which the neighbour is searched for. Can be Up, Down, Left and Right.</param> /// <returns>The Satellite neighbour in the specified direction.</returns> private Satellite FindNeighbour(NeighbourDirection direction) { Satellite neighbour = null; if (direction == NeighbourDirection.Up) { neighbour = _constellation[_thisSatellite.SatPosition.OrbitNumber][(_thisSatellite.SatPosition.SatNumber + 1) % _conf.NumberOfSatellitesPerOrbit]; } if (direction == NeighbourDirection.Down) { neighbour = _constellation[_thisSatellite.SatPosition.OrbitNumber][(_thisSatellite.SatPosition.SatNumber + _conf.NumberOfSatellitesPerOrbit - 1) % _conf.NumberOfSatellitesPerOrbit]; } var hemisphere = CoordinateHelper.CalcHemisphere(_thisSatellite.Location); if (direction == NeighbourDirection.Right && _conf.NumberOfOrbits > 1) { var neighbourOrbitRight = 0; var rightCrossSeamOrbit = 0; if (hemisphere == CoordinateHelper.Hemisphere.NorthEast || hemisphere == CoordinateHelper.Hemisphere.SouthEast) //If this satellite is in the eastern hemisphere { neighbourOrbitRight = (_thisSatellite.SatPosition.OrbitNumber + 1) % _conf.NumberOfOrbits; //Calculate number of next orbit rightCrossSeamOrbit = _conf.MinimumOrbitNumber; if (neighbourOrbitRight > 0) //If orbit to my right is NOT across the seam { neighbour = _constellation[neighbourOrbitRight][_thisSatellite.SatPosition.SatNumber]; //My right neighbour is my initial neighbour } } else if (hemisphere == CoordinateHelper.Hemisphere.NorthWest || hemisphere == CoordinateHelper.Hemisphere.SouthWest) //If this satellite is in the western hemisphere (mirrored constellation) { neighbourOrbitRight = (_thisSatellite.SatPosition.OrbitNumber + (_conf.NumberOfOrbits - 1)) % _conf.NumberOfOrbits; //Calculate number of next orbit rightCrossSeamOrbit = _conf.MaximumOrbitNumber; if (neighbourOrbitRight < _conf.MaximumOrbitNumber) //If orbit to my right is NOT across the seam { neighbour = _constellation[neighbourOrbitRight][_thisSatellite.SatPosition.SatNumber]; } } //If my orbit is the last one, i.e. right neighbour is crossing the seam AND cross-seam communication is enabled (otherwise this satellite has no right neighbour right now) if (neighbourOrbitRight == rightCrossSeamOrbit && _conf.CrossSeamCommunicationEnabled) { var ticks = _thisSatellite.LogicalPosition.SatNumber - _thisSatellite.SatPosition.SatNumber; if (ticks < 0) //How many ticks since original position { ticks = _conf.NumberOfSatellitesPerOrbit - Math.Abs(_thisSatellite.LogicalPosition.SatNumber - _thisSatellite.SatPosition.SatNumber); //10 } //Original neighbour position var initNb = (_conf.NumberOfSatellitesPerOrbit - _thisSatellite.SatPosition.SatNumber - (_conf.NumberOfSatellitesPerOrbit / 2)) % _conf.NumberOfSatellitesPerOrbit; if (initNb < 0) { initNb = _conf.NumberOfSatellitesPerOrbit - Math.Abs(initNb); } //Current neighbour var newNb = initNb - (ticks * 2) % _conf.NumberOfSatellitesPerOrbit; //Each "tick" shifts cross-seam neighbours by 2 if (newNb < 0) { newNb = _conf.NumberOfSatellitesPerOrbit - Math.Abs(newNb); } neighbour = _constellation[neighbourOrbitRight][newNb]; } } if (direction == NeighbourDirection.Left && _conf.NumberOfOrbits > 1) { var neighbourOrbitLeft = 0; var leftCrossSeamOrbit = 0; if (hemisphere == CoordinateHelper.Hemisphere.NorthEast || hemisphere == CoordinateHelper.Hemisphere.SouthEast) //If this satellite is in the eastern hemisphere { neighbourOrbitLeft = (_thisSatellite.SatPosition.OrbitNumber + _conf.NumberOfOrbits - 1) % _conf.NumberOfOrbits; //Calculate number of next orbit leftCrossSeamOrbit = _conf.MaximumOrbitNumber; if (neighbourOrbitLeft != leftCrossSeamOrbit) //If orbit to my right is NOT across the seam { neighbour = _constellation[neighbourOrbitLeft][_thisSatellite.SatPosition.SatNumber]; //My right neighbour is my initial neighbour } } else if (hemisphere == CoordinateHelper.Hemisphere.NorthWest || hemisphere == CoordinateHelper.Hemisphere.SouthWest) //If this satellite is in the western hemisphere (mirrored constellation) { neighbourOrbitLeft = (_thisSatellite.SatPosition.OrbitNumber + 1) % _conf.NumberOfOrbits; //Calculate number of next orbit leftCrossSeamOrbit = _conf.MinimumOrbitNumber; if (neighbourOrbitLeft != leftCrossSeamOrbit) //If orbit to my right is NOT across the seam { neighbour = _constellation[neighbourOrbitLeft][_thisSatellite.SatPosition.SatNumber]; } } //If my orbit is the last one, i.e. right neighbour is crossing the seam AND cross-seam communication is enabled (otherwise this satellite has no right neighbour right now) if (neighbourOrbitLeft == leftCrossSeamOrbit && _conf.CrossSeamCommunicationEnabled) { var ticks = _thisSatellite.LogicalPosition.SatNumber - _thisSatellite.SatPosition.SatNumber; if (ticks < 0) //How many ticks since original position { ticks = _conf.NumberOfSatellitesPerOrbit - Math.Abs(_thisSatellite.LogicalPosition.SatNumber - _thisSatellite.SatPosition.SatNumber); } //Original neighbour position var initNb = (_conf.NumberOfSatellitesPerOrbit - _thisSatellite.SatPosition.SatNumber - (_conf.NumberOfSatellitesPerOrbit / 2)) % _conf.NumberOfSatellitesPerOrbit; if (initNb < 0) { initNb = _conf.NumberOfSatellitesPerOrbit - Math.Abs(initNb); } //Current neighbour var newNb = initNb - (ticks * 2) % _conf.NumberOfSatellitesPerOrbit; if (newNb < 0) { newNb = _conf.NumberOfSatellitesPerOrbit - Math.Abs(newNb); } neighbour = _constellation[neighbourOrbitLeft][newNb]; } } return(neighbour); }
public void SetNeighbour(NeighbourDirection direction, TerrainTile tile) { Neighbours[(int)direction] = tile; tile.Neighbours[(int)direction.Opposite()] = this; }
public TerrainTile GetNeighbour(NeighbourDirection direction) { return(Neighbours[(int)direction]); }
void Triangulate(NeighbourDirection direction, TerrainTile tile) { Vector3 center = tile.TileTopCenter; }
public Square QueryNeighbour(NeighbourDirection direction) { return(Chessboard.Instance.GetNeighbourSquare(Id, direction)); }
public static NeighbourDirection Opposite(this NeighbourDirection direction) { return((int)direction < 4 ? (direction + 4) : (direction - 4)); }
public void SetNeighbour(NeighbourDirection direction, Node node) { Neighbours[(int)direction] = node; node.Neighbours[(int)direction.Opposite()] = this; }
public Node GetNeighbour(NeighbourDirection direction) { return(Neighbours[(int)direction]); }