public TileAStarPathFinding(ITerrainGenerator terrainGenerator, TerrainGenerator.TerrainType terrainType)
 {
     _terrainGenerator = terrainGenerator;
     TerrainType       = terrainType;
 }
 public NeededSpace(NeededSpace neededSpace, Vector3Int offset)
 {
     _usedCoordinate = new Vector3Int(neededSpace.UsedCoordinate.x + offset.x,
                                      neededSpace.UsedCoordinate.y + offset.y, neededSpace.UsedCoordinate.z + offset.z);
     _terrainType = neededSpace.TerrainType;
 }
    public static ThreadsafePlaceable FindForrestPosition(IPlacementController placementController,
                                                          ITerrainGenerator terrainGenerator, ThreadsafePlaceable placeable, float[,] values)
    {
        while (!terrainGenerator.IsReady(placeable.Position))
        {
            Thread.Sleep(50);
        }

        List <NeededSpace> coastNeededSpace = new List <NeededSpace>
        {
            new NeededSpace(Vector3Int.zero, TerrainGenerator.TerrainType.Coast)
        };
        List <NeededSpace> flatLandNeededSpace = new List <NeededSpace>
        {
            new NeededSpace(Vector3Int.zero, TerrainGenerator.TerrainType.Flatland)
        };
        List <NeededSpace> hillNeededSpace = new List <NeededSpace>
        {
            new NeededSpace(Vector3Int.zero, TerrainGenerator.TerrainType.Hill)
        };
        List <NeededSpace> mountainNeededSpace = new List <NeededSpace>
        {
            new NeededSpace(Vector3Int.zero, TerrainGenerator.TerrainType.Mountain)
        };
        float limit = 0.1f;

        for (int x = 0; x < values.GetLength(0) - 3; x++)
        {
            for (int y = 0; y < values.GetLength(1) - 3; y++)
            {
                Vector3Int relativePosition =
                    new Vector3Int(x - values.GetLength(0) / 2 + 1, 0, y - values.GetLength(1) / 2 + 1);
                Vector3 absolutePosition = relativePosition + placeable.Position;
                bool    isThreshold      = (values[x, y] > limit - 0.05f && values[x, y] < limit + 0.05f);
                if (!isThreshold)
                {
                    continue;
                }

                TerrainGenerator.TerrainType terrainType = terrainGenerator.GetTerrainType(absolutePosition.x, absolutePosition.z);
                bool isPlaceable = false;
                switch (terrainType)
                {
                case TerrainGenerator.TerrainType.Flatland:
                    isPlaceable = placementController.IsPlaceable(absolutePosition, flatLandNeededSpace);
                    break;

                case TerrainGenerator.TerrainType.Coast:
                    isPlaceable = placementController.IsPlaceable(absolutePosition, coastNeededSpace);
                    break;

                case TerrainGenerator.TerrainType.Hill:
                    isPlaceable = placementController.IsPlaceable(absolutePosition, hillNeededSpace);
                    break;

                case TerrainGenerator.TerrainType.Mountain:
                    isPlaceable = placementController.IsPlaceable(absolutePosition, mountainNeededSpace);
                    break;
                }
                if (!isPlaceable)
                {
                    continue;
                }
                placeable.NeededSpaces.Add(new ProceduralNeededSpace(relativePosition, terrainType, values[x, y]));
            }
        }

        return(placeable);
    }
    [SerializeField] private TerrainGenerator.TerrainType _terrainType = TerrainGenerator.TerrainType.Flatland; // The suitable ground type

    public NeededSpace(Vector3Int usedCoordinate, TerrainGenerator.TerrainType terrainType)
    {
        this._usedCoordinate = usedCoordinate;
        this._terrainType    = terrainType;
    }