예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
		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);
        }
예제 #5
0
 public void SetNeighbour(NeighbourDirection direction, TerrainTile tile)
 {
     Neighbours[(int)direction] = tile;
     tile.Neighbours[(int)direction.Opposite()] = this;
 }
예제 #6
0
 public TerrainTile GetNeighbour(NeighbourDirection direction)
 {
     return(Neighbours[(int)direction]);
 }
예제 #7
0
 void Triangulate(NeighbourDirection direction, TerrainTile tile)
 {
     Vector3 center = tile.TileTopCenter;
 }
예제 #8
0
 public Square QueryNeighbour(NeighbourDirection direction)
 {
     return(Chessboard.Instance.GetNeighbourSquare(Id, direction));
 }
예제 #9
0
 public static NeighbourDirection Opposite(this NeighbourDirection direction)
 {
     return((int)direction < 4 ? (direction + 4) : (direction - 4));
 }
예제 #10
0
 public void SetNeighbour(NeighbourDirection direction, Node node)
 {
     Neighbours[(int)direction] = node;
     node.Neighbours[(int)direction.Opposite()] = this;
 }
예제 #11
0
 public Node GetNeighbour(NeighbourDirection direction)
 {
     return(Neighbours[(int)direction]);
 }