Exemple #1
0
        public void ReturnEmptyGrid_GivenInitialEmptyGrid()
        {
            var grid       = new EmptyGrid();
            var returnGrid = grid.Tick();

            returnGrid.Should().Be(new EmptyGrid());
        }
Exemple #2
0
 public NodeGrid(ref EmptyGrid map)
 {
     values = new Node[map.width, map.height];
     CreateNodeMapFromEmptyGrid(ref map);
     width  = map.width;
     height = map.height;
 }
Exemple #3
0
    // public static SavedData LoadDataBinary()
    public static EmptyGrid LoadDataBinary()
    {
        string folderName    = "Saves";
        string fileName      = "data";
        string fileExtension = ".sav";

        string pathToData = System.IO.Path.Combine(Application.dataPath, folderName);

        pathToData = System.IO.Path.Combine(pathToData, fileName + fileExtension);

        if (System.IO.File.Exists(pathToData))
        {
            System.IO.FileStream loadFileStream = System.IO.File.OpenRead(pathToData);

            System.Runtime.Serialization.Formatters.Binary.BinaryFormatter binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();

            ///SavedData data = (PlayerData)binaryFormatter.Deserialize(saveFileStream);

            Cell[,] data = (Cell[, ])binaryFormatter.Deserialize(loadFileStream);
            loadFileStream.Close();
            /// return data;
            ///
            EmptyGrid map = new EmptyGrid(data, data.GetLength(0), data.GetLength(1));

            return(map);
        }
        else
        {
            Debug.LogError("Can't find file with such name: " + pathToData);
            return(null);
        }
    }
Exemple #4
0
    public static Mesh GenerateDiscreteTerrainMesh(DiscreteTerrainSettings terrainSettings)
    {
        EmptyGrid cellMap   = GridGenerator.GenerateEmptyGrid(terrainSettings.tileMapSettings);
        HeightMap heightMap = HeightMapGenerator.GenerateHeightMap(terrainSettings.heightMapSettings, new Vector2(0, 0), terrainSettings.tileMapSettings.mapWidth, terrainSettings.tileMapSettings.mapHeight);

        if (terrainSettings.useHeightLayers)
        {
            TerrainHeightLayersGenerator.SeparateTerrainOnLayers(ref cellMap, ref terrainSettings.tileMapSettings, ref heightMap, ref terrainSettings.heightLayersSettings);
        }

        switch (terrainSettings.terrainMeshType)
        {
        case GridType.Square:
            return(DiscreteVoxelMeshGenerator.GenerateTerrainMesh(cellMap, terrainSettings.tileMapSettings, heightMap, terrainSettings.heightLayersSettings));

        case GridType.PointyHex:
            return(DiscreteSolidPointyHexMeshGenerator.GenerateTerrainMesh(cellMap, terrainSettings.tileMapSettings, heightMap, terrainSettings.heightLayersSettings));

        default:
            Debug.LogError("Terrain underlying grid type hasn't set up.");
            break;
        }

        return(new Mesh());
    }
    public static EmptyGrid CreateOuterWalls(EmptyGrid map)
    {
        Cell[,] mapWithWalls = new Cell[map.width + 2, map.height + 2];

        int x = 0, y = 0;

        for (y = 0; y < map.height; y++)
        {
            for (x = 0; x < map.width; x++)
            {
                mapWithWalls[x + 1, y + 1] = map.values[x, y];
            }
        }

        x = 0;
        for (y = 0; y < map.height + 2; y++)
        {
            mapWithWalls[x, y]             = new Cell(false, CellType.OuterWall, Color.blue, '@');
            mapWithWalls[map.width + 1, y] = new Cell(false, CellType.OuterWall, Color.blue, '@');
        }

        y = 0;
        for (x = 0; x < map.width + 2; x++)
        {
            mapWithWalls[x, y] = new Cell(false, CellType.OuterWall, Color.blue, '@');
            mapWithWalls[x, map.height + 1] = new Cell(false, CellType.OuterWall, Color.blue, '@');
        }

        map.values = mapWithWalls;
        map.width  = map.width + 2;
        map.height = map.height + 2;

        return(map);
    }
Exemple #6
0
    public static EmptyGrid ImportJSON(string folderName, string fileName, string fileExtension)
    {
        folderName    = "SavedMaps";
        fileName      = "jsonMap";
        fileExtension = ".json";

        string pathToJSON = System.IO.Path.Combine(Application.dataPath, folderName);

        pathToJSON = System.IO.Path.Combine(pathToJSON, fileName + fileExtension);

        if (System.IO.File.Exists(pathToJSON))
        {
            // Open the file to read from.
            string jsonData = System.IO.File.ReadAllText(pathToJSON);

            EmptyGridWrapJSON cellMapWrapped = JsonUtility.FromJson <EmptyGridWrapJSON>(jsonData);

            EmptyGrid map = cellMapWrapped.Unwrap();

            return(map);
        }
        else
        {
            Debug.LogError("Can't find file with such name: " + pathToJSON);
            return(null);
        }
    }
    public static Mesh GenerateTerrainMesh(EmptyGrid map, TileMapSettings settings, HeightMap heightMap, TerrainHeightLayers heightLayersSettings = null)
    {
        mesh      = new Mesh();
        vertices  = new List <Vector3>();
        triangles = new List <int>();
        colors    = new List <Color>();

        Vector2 bottomLeft;

        if (settings.isCentered)
        {
            bottomLeft = new Vector2(-map.width, -map.height) * settings.cellScale + new Vector2(settings.mapOffsetX, -settings.mapOffsetZ);
        }
        else
        {
            bottomLeft = new Vector2(settings.mapOffsetX, -settings.mapOffsetZ);
        }

        Debug.DrawRay(new Vector3(bottomLeft.x, 0.0f, bottomLeft.y), Vector3.up * 5.0f, Color.red, 0.5f);

        //vertices = new Vector3[(map.width + 1) * (map.height + 1)];
        //uv = new Vector2[vertices.Length];
        //triangles = new int[map.width * map.height * 6]; //6 = 2 triangles * 3 vertices
        //colors = new Color[vertices.Length];

        if (heightLayersSettings != null)
        {
            TerrainHeightLayersGenerator.SeparateTerrainOnLayers(map, settings, heightMap, heightLayersSettings);
        }

        // * 0.5f because it's cube
        float   cellScale    = settings.cellScale * 2;
        Vector3 vertexOffset = Vector3.one * settings.cellScale;

        for (int y = 0; y < map.height; y++)
        {
            for (int x = 0; x < map.width; x++)
            {
                Vector3 cellOffset = new Vector3(x * cellScale, 0.0f, y * cellScale) + new Vector3(bottomLeft.x, 0.0f, bottomLeft.y);
                Vector3 spawnPoint = cellOffset + vertexOffset;

                spawnPoint.y += heightMap.values[x, y];

                CreateCube(spawnPoint, settings.cellScale, x, y, map, heightMap);
                Debug.DrawRay(spawnPoint, Vector3.up * 3.0f, Color.green, 0.5f);
            }
        }

        mesh.name      = "Discrete Voxel Terrain Mesh";
        mesh.vertices  = vertices.ToArray();
        mesh.triangles = triangles.ToArray();
        mesh.colors    = colors.ToArray();

        mesh.RecalculateNormals();

        return(mesh);
    }
    public static EmptyGrid ProcessMap(EmptyGrid map, BinarySpacePartitioningSettings settings)
    {
        // Random Generator
        Random.State initialState = Random.state;
        if (settings.useFixedSeed)
        {
            Random.InitState(settings.seed.GetHashCode());
        }
        else
        {
            Random.InitState(Time.time.ToString().GetHashCode());
        }

        // Set root
        BSPLeaf root = new BSPLeaf(0, 0, map.width - 1, map.height - 1);

        // Space Partition
        root.Split(ref settings);

        // Get terminal leaves
        List <BSPLeaf> list = new List <BSPLeaf>();

        root.GetLeaves(ref list);

        List <Vector2> midpoints = new List <Vector2>();

        // Recursive Division
        if (settings.useOnlyRecursiveDivision)
        {
            // Fill initial
            for (int y = 0; y < map.height; y++)
            {
                for (int x = 0; x < map.width; x++)
                {
                    map.values[x, y] = Cell.CreateCell(CellType.Floor);
                }
            }
            DrawBSPRoom(ref map.values, ref midpoints, ref settings, root);
        }
        else
        {
            // Room placement on map
            foreach (BSPLeaf leaf in list)
            {
                DrawRectangularRoom(ref map.values, ref midpoints, ref settings, leaf);
            }
        }

        if (settings.hasCleanup)
        {
            CleanUpRoomPlacement(ref map.values, ref map.width, ref map.height);
        }

        Random.state = initialState;

        return(map);
    }
    public static EmptyGrid ProcessMap(EmptyGrid map, RandomWormsSettings settings)
    {
        // Process Map
        //RandomWorms.map = new bool[width, height];
        //InitialFillMap();
        //FillMapWithFloor();

        FillMap(ref map.values, CellType.Floor, CellType.Wall);

        return(map);
    }
    public static Mesh GenerateTerrainMesh(EmptyGrid map, TileMapSettings settings, HeightMap heightMap, TerrainHeightLayers heightLayersSettings = null)
    {
        mesh      = new Mesh();
        vertices  = new List <Vector3>();
        triangles = new List <int>();
        colors    = new List <Color>();

        Vector2 bottomLeft;

        /// FIX CENTERED (vertexOffest breaks centre)
        if (settings.isCentered)
        {
            bottomLeft = new Vector2(-map.width * settings.cellScale * (PointyHexTileData.innerRadius * 2f) * 0.5f,
                                     -((map.height - 1) * (PointyHexTileData.outerRadius * 1.5f) + 0.5f * PointyHexTileData.outerRadius) * settings.cellScale * 0.5f)
                         + new Vector2(settings.mapOffsetX, -settings.mapOffsetZ);
        }
        else
        {
            bottomLeft = new Vector2(settings.mapOffsetX, -settings.mapOffsetZ);
        }

        Debug.DrawRay(new Vector3(bottomLeft.x, 0.0f, bottomLeft.y), Vector3.up * 5.0f, Color.red, 0.5f);

        Vector3 vertexOffset = new Vector3(PointyHexTileData.innerRadius, 1.0f, PointyHexTileData.outerRadius) * settings.cellScale;

        if (heightLayersSettings != null)
        {
            TerrainHeightLayersGenerator.SeparateTerrainOnLayers(map, settings, heightMap, heightLayersSettings);
        }

        for (int z = 0; z < map.height; z++)
        {
            for (int x = 0; x < map.width; x++)
            {
                Vector3 cellOffset = new Vector3((x + z * 0.5f - z / 2) * (PointyHexTileData.innerRadius * 2f) * settings.cellScale, 0.0f, z * (PointyHexTileData.outerRadius * 1.5f) * settings.cellScale)
                                     + new Vector3(bottomLeft.x, 0.0f, bottomLeft.y);

                Vector3 spawnPos = cellOffset + vertexOffset;

                spawnPos.y += heightMap.values[x, z];

                CreateSolidHex(spawnPos, settings.cellScale, x, z, map, heightMap);
                Debug.DrawRay(spawnPos, Vector3.up * 3.0f, Color.green, 0.5f);
            }
        }

        mesh.name      = "Discrete Solid PointyHex Terrain Mesh";
        mesh.vertices  = vertices.ToArray();
        mesh.triangles = triangles.ToArray();
        mesh.colors    = colors.ToArray();
        mesh.RecalculateNormals();

        return(mesh);
    }
Exemple #11
0
 public void CreateNodeMapFromEmptyGrid(ref EmptyGrid map)
 {
     for (int z = 0; z < map.height; z++)
     {
         for (int x = 0; x < map.width; x++)
         {
             //Debug.Log(map.values[x, z].cellType + " " + x + " " + z);
             values[x, z] = Node.CreateNode(map.values[x, z].cellType, x, z);
             //Debug.Log(values[x, z] + " " + x + " " + z);
         }
     }
 }
    private static void CreateCube(Vector3 cubePosition, float scale, int x, int z, EmptyGrid map)
    {
        Color faceColor = map.values[x, z].cellMapColor;

        for (int i = 0; i < 6; i++)
        {
            if (map.GetNeighbour(x, z, (Direction)i).cellType == CellType.Empty || map.GetNeighbour(x, z, (Direction)i).cellType == CellType.Floor)
            {
                CreateFace((Direction)i, scale, cubePosition);
                ColorizeFace(faceColor);
            }
        }
    }
Exemple #13
0
    public static void ExportJSON(EmptyGrid map)
    {
        string folderName    = "SavedMaps";
        string fileName      = "jsonMap";
        string fileExtension = ".json";

        string pathToJSON = System.IO.Path.Combine(Application.dataPath, folderName);

        Debug.Log("The path is: " + pathToJSON);

        if (!System.IO.Directory.Exists(pathToJSON))
        {
            System.IO.Directory.CreateDirectory(pathToJSON);
            Debug.Log("Directory was created: " + pathToJSON);
        }

        pathToJSON = System.IO.Path.Combine(pathToJSON, fileName + fileExtension);
        Debug.Log("Current path is: " + pathToJSON);

        string jsonData = JsonUtility.ToJson(new EmptyGridWrapJSON(map));

        /// Works only with primitives
        //System.Buffer.BlockCopy(map.values, 0, flatArray, 0, System.Buffer.ByteLength(map.values));

        //Cell[] flatArray = new Cell[map.width * map.height];
        //int i = 0;
        //for (int z = 0; z < map.height; z++)
        //{
        //    for (int x = 0; x < map.width; x++)
        //    {
        //        flatArray[i] = map.values[x, z];
        //        i++;
        //    }
        //}
        //string jsonData = JsonHelper.ToJson(flatArray);

        Debug.Log(jsonData);

        //using (System.IO.StreamWriter streamWriter = System.IO.File.CreateText(pathToJSON))
        //{
        //    streamWriter.Write(jsonData);
        //    streamWriter.Close();
        //}

        System.IO.File.WriteAllText(pathToJSON, jsonData);

#if UNITY_EDITOR
        UnityEditor.AssetDatabase.ImportAsset(pathToJSON, UnityEditor.ImportAssetOptions.Default);
#endif
    }
Exemple #14
0
 public static EmptyGrid ProcessMap(EmptyGrid map, RandomWalkSettings settings)
 {
     // Random Generator
     Random.State initialState = Random.state;
     if (settings.useFixedSeed)
     {
         Random.InitState(settings.seed.GetHashCode());
     }
     else
     {
         Random.InitState(Time.time.ToString().GetHashCode());
     }
     map.values   = RandomWalk.TransformBoolToCell(RandomWalk.GetCarvedMap(map.width, map.height, settings), CellType.Floor, CellType.Wall);
     Random.state = initialState;
     return(map);
 }
    public void Wrap(EmptyGrid grid)
    {
        this.width  = grid.width;
        this.height = grid.height;

        this.values = new Cell[grid.width * grid.height];
        int i = 0;

        for (int z = 0; z < grid.height; z++)
        {
            for (int x = 0; x < grid.width; x++)
            {
                this.values[i] = grid.values[x, z];
                i++;
            }
        }
    }
Exemple #16
0
    public static void SaveDataBinary(EmptyGrid map)
    {
        string folderName    = "Saves";
        string fileName      = "data";
        string fileExtension = ".sav";

        string pathToTXT = System.IO.Path.Combine(Application.dataPath, folderName);

        Debug.Log("The path is: " + pathToTXT);

        if (!System.IO.Directory.Exists(pathToTXT))
        {
            System.IO.Directory.CreateDirectory(pathToTXT);
            Debug.Log("Directory was created: " + pathToTXT);
        }

        pathToTXT = System.IO.Path.Combine(pathToTXT, fileName + fileExtension);
        Debug.Log("Current path is: " + pathToTXT);

        using (System.IO.FileStream saveFileStream = System.IO.File.OpenWrite(pathToTXT))
        {
            System.Runtime.Serialization.Formatters.Binary.BinaryFormatter binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
            /// then - get and prepare data method, but I skipped it
            ///
            /// [System.Serializable]
            /// public class SavedData {
            /// public int[] stats;
            /// public SavedData(PlayerData data)
            /// { stats = new int[2];
            /// stats[0] = data.health;
            /// stats[1] = data.level; } };
            ///
            /// here
            /// SavedData data = new SavedData(GatherAllData()); // or CollectData or StoreData
            ///
            /// binaryFormatter.Serialize(saveFileStream, data);

            binaryFormatter.Serialize(saveFileStream, map.values);

            saveFileStream.Close();
        }

#if UNITY_EDITOR
        UnityEditor.AssetDatabase.ImportAsset(pathToTXT, UnityEditor.ImportAssetOptions.Default);
#endif
    }
    private static void CreateCube(Vector3 cubePosition, float scale, int x, int z, EmptyGrid map, HeightMap heightMap)
    {
        Color faceColor = map.values[x, z].cellMapColor;

        for (int i = 0; i < 6; i++)
        {
            //if (map.GetNeighbour(x, z, (Direction)i).cellType == CellType.Empty && heightMap.GetNeighbour(x, z, (Direction)i) < heightMap.values[x, z] || map.GetNeighbour(x, z, (Direction)i).cellType == CellType.Floor ||
            //    (map.GetNeighbour(x, z, (Direction)i).cellType == CellType.Wall && heightMap.GetNeighbour(x, z, (Direction)i) < heightMap.values[x, z])
            //    )
            if (map.GetNeighbour(x, z, (Direction)i, GridType.PointyHex).cellType == CellType.Empty || map.GetNeighbour(x, z, (Direction)i, GridType.PointyHex).cellType == CellType.Floor ||
                ((map.GetNeighbour(x, z, (Direction)i, GridType.PointyHex).cellType != CellType.Empty && map.GetNeighbour(x, z, (Direction)i, GridType.PointyHex).cellType != CellType.Floor) && heightMap.GetNeighbour(x, z, (Direction)i, GridType.PointyHex) < heightMap.values[x, z] - epsilon)
                )
            {
                CreateFace((Direction)i, scale, cubePosition);
                ColorizeFace(faceColor);
            }
        }
    }
Exemple #18
0
    public static void ExportText(EmptyGrid map)
    {
        string folderName = "SavedMaps";

        string fileName = "textMap";

        string fileExtension = ".txt";

        string pathToTXT = System.IO.Path.Combine(Application.dataPath, folderName);

        Debug.Log("The path is: " + pathToTXT);

        if (!System.IO.Directory.Exists(pathToTXT))
        {
            System.IO.Directory.CreateDirectory(pathToTXT);
            Debug.Log("Directory was created: " + pathToTXT);
        }

        pathToTXT = System.IO.Path.Combine(pathToTXT, fileName + fileExtension);

        Debug.Log("Current path is: " + pathToTXT);

        // Этот метод эквивалентен методу FileStream(String, FileMode, FileAccess, FileShare) перегрузку конструктора с режимом файл OpenOrCreate, права доступа, заданные Write, и задайте режима общего доступа None.
        System.IO.FileStream   saveFileStream = System.IO.File.OpenWrite(pathToTXT);
        System.IO.StreamWriter streamWriter   = new System.IO.StreamWriter(saveFileStream);

        for (int z = 0; z < map.height; z++)
        {
            for (int x = 0; x < map.width; x++)
            {
                streamWriter.Write(map.values[x, z].cellMapChar);
            }
            streamWriter.WriteLine();
        }

        streamWriter.Close();
        saveFileStream.Close();

#if UNITY_EDITOR
        //UnityEditor.AssetDatabase.Refresh(UnityEditor.ImportAssetOptions.Default);
        UnityEditor.AssetDatabase.ImportAsset(pathToTXT, UnityEditor.ImportAssetOptions.Default);
#endif
    }
    public EmptyGridWrapJSON(EmptyGrid grid)
    {
        this.width  = grid.width;
        this.height = grid.height;

        // Convert to flat array
        this.values = new Cell[grid.width * grid.height];
        int i = 0;

        for (int z = 0; z < grid.height; z++)
        {
            for (int x = 0; x < grid.width; x++)
            {
                this.values[i] = grid.values[x, z];
                i++;
            }
        }

        this.type = grid.type;
    }
    public static EmptyGrid SeparateTerrainOnLayers(EmptyGrid map, TileMapSettings settings, HeightMap heightMap, TerrainHeightLayers heightLayers)
    {
        for (int z = 0; z < map.height; z++)
        {
            for (int x = 0; x < map.width; x++)
            {
                float heightPercent = Mathf.InverseLerp(heightMap.minValue, heightMap.maxValue, heightMap.values[x, z]);

                for (int i = 0; i < heightLayers.layers.Length; i++)
                {
                    if (heightPercent <= heightLayers.layers[i].startingHeight)
                    {
                        map.values[x, z]       = Cell.CreateCell(heightLayers.layers[i].cellType);
                        heightMap.values[x, z] = heightLayers.layers[i].startingHeight;
                        break;
                    }
                }
            }
        }
        return(map);
    }
    public static EmptyGrid ProcessMap(EmptyGrid map, RandomRoomWithCorridorSettings settings)
    {
        // Random Generator
        Random.State initialState = Random.state;
        if (settings.useFixedSeed)
        {
            Random.InitState(settings.seed.GetHashCode());
        }
        else
        {
            Random.InitState(Time.time.ToString().GetHashCode());
        }

        List <Corridor> corridorsList = new List <Corridor>();

        // Generate random rooms
        List <Room> roomList = GenerateRandomRooms(ref corridorsList, ref map.width, ref map.height, ref settings);

        // Random room placement on map
        for (int i = 0; i < roomList.Count; i++)
        {
            Room room = roomList[i];
            DrawRectangularRoom(ref map.values, room);
        }
        for (int i = 0; i < corridorsList.Count; i++)
        {
            BresenhamLine(ref map.values, corridorsList[i].startPoint.x, corridorsList[i].startPoint.z, corridorsList[i].endPoint.x, corridorsList[i].endPoint.z, corridorsList[i].direction);
        }

        // Connect floor tiles that are between single wall
        if (settings.hasCleanup)
        {
            CleanUpRoomPlacement(ref map.values, ref map.width, ref map.height);
        }

        Random.state = initialState;

        return(map);
    }
    public static EmptyGrid ProcessMap(EmptyGrid map, GridMapFromPrefabsSettings settings)
    {
        //int mapSeed = 925;
        //int mapSeed = 573;
        Random.State initialState = Random.state;
        if (settings.useFixedSeed)
        {
            Random.InitState(settings.seed.GetHashCode());
        }
        else
        {
            Random.InitState(Time.time.ToString().GetHashCode());
        }

        InitializeAndGenerateMap(ref settings);

        ConvertPrefabMapToCellMap(ref map.values, ref settings);

        Random.state = initialState;

        return(map);
    }
Exemple #23
0
    //    -- To shuffle an array a of n elements(indices 0..n-1):
    //for i from 0 to n−2 do
    //     j ← random integer such that i ≤ j < n
    //     exchange a[i] and a[j]

    //To initialize an array a of n elements to a randomly shuffled copy of source, both 0 - based:
    //for i from 0 to n − 1 do
    //    j ← random integer such that 0 ≤ j ≤ i
    //    if j ≠ i
    //        a[i] ← a[j]
    //    a[j] ← source[i]

    ///"inside-out" algorithm realisation
    ///

    public static EmptyGrid ProcessMap(EmptyGrid map, FisherYatesShuffleSettings settings)
    {
        List <Coordinate> coords = new List <Coordinate>(map.height * map.width);

        for (int y = 0; y < map.height; y++)
        {
            for (int x = 0; x < map.width; x++)
            {
                coords.Add(new Coordinate(x, y));
            }
        }
        Queue <Coordinate> shuffledCoords = new Queue <Coordinate>(Shuffle <Coordinate>(coords.ToArray(), settings.seed));

        int totalObstaclesCount = 0;
        int maxObstaclesCount   = (int)(map.width * map.height * settings.obstaclesFillingPercentage);

        //for (int i = 0; i < maxObstaclesCount; i++)
        while (totalObstaclesCount < maxObstaclesCount)
        {
            Coordinate coord = shuffledCoords.Dequeue();
            shuffledCoords.Enqueue(coord);

            if (coord != settings.spawnPoint)
            {
                map.values[coord.x, coord.z].cellType     = CellType.Wall;
                map.values[coord.x, coord.z].cellMapColor = Color.red;
                map.values[coord.x, coord.z].isWalkable   = false;
                map.values[coord.x, coord.z].cellMapChar  = '#';
                totalObstaclesCount++;
            }
            else
            {
                continue;
            }
        }

        return(map);
    }
Exemple #24
0
    public static EmptyGrid ProcessMap(EmptyGrid map, GameOfLifeSettings settings)
    {
        // Random Generator
        Random.State initialState = Random.state;
        if (settings.useFixedSeed)
        {
            Random.InitState(settings.seed.GetHashCode());
        }
        else
        {
            Random.InitState(Time.time.ToString().GetHashCode());
        }

        // Get map mask
        //bool[,] mask = GameOfLife.ProcessMap(map.width, map.height, settings);
        // Fill with cells
        //for (int z = 0; z < map.height; z++)
        //{
        //    for (int x = 0; x < map.width; x++)
        //    {
        //        if (mask[x, z])
        //        {
        //            map.values[x, z] = Cell.CreateCell(CellType.Wall);
        //        }
        //        else
        //        {
        //            map.values[x, z] = Cell.CreateCell(CellType.Floor);
        //        }
        //    }
        //}

        map.values = GameOfLife.TransformBoolToCell(GameOfLife.ProcessMap(map.width, map.height, settings), CellType.Wall, CellType.Floor);

        Random.state = initialState;
        return(map);
    }
    public static Mesh GenerateGridMesh(EmptyGrid map, TileMapSettings settings)
    {
        mesh = new Mesh();
        //Mesh mesh = new Mesh();
        vertices  = new List <Vector3>();
        triangles = new List <int>();
        colors    = new List <Color>();

        Vector2 bottomLeft;

        /// FIX CENTERED (vertexOffest breaks centre)
        if (settings.isCentered)
        {
            bottomLeft = new Vector2(-map.width * settings.cellScale * (PointyHexTileData.innerRadius * 2f) * 0.5f,
                                     -((map.height - 1) * (PointyHexTileData.outerRadius * 1.5f) + 0.5f * PointyHexTileData.outerRadius) * settings.cellScale * 0.5f)
                         + new Vector2(settings.mapOffsetX, -settings.mapOffsetZ);
        }
        else
        {
            bottomLeft = new Vector2(settings.mapOffsetX, -settings.mapOffsetZ);
        }

        Debug.DrawRay(new Vector3(bottomLeft.x, 0.0f, bottomLeft.y), Vector3.up * 5.0f, Color.red, 0.5f);

        Vector3 vertexOffset = new Vector3(PointyHexTileData.innerRadius, 1.0f, PointyHexTileData.outerRadius) * settings.cellScale;

        for (int z = 0; z < map.height; z++)
        {
            for (int x = 0; x < map.width; x++)
            {
                Vector3 cellOffset = new Vector3((x + z * 0.5f - z / 2) * (PointyHexTileData.innerRadius * 2f) * settings.cellScale, 0.0f, z * (PointyHexTileData.outerRadius * 1.5f) * settings.cellScale)
                                     + new Vector3(bottomLeft.x, 0.0f, bottomLeft.y);

                Vector3 spawnPos = cellOffset + vertexOffset;

                if (!settings.showWallsOnly)
                {
                    if (map.values[x, z].cellType == CellType.Empty || map.values[x, z].cellType == CellType.Floor)
                    {
                        int verticesCount;
                        CreateFace(Direction.Up, settings.cellScale, spawnPos + 2 * Vector3.down * settings.cellScale, out verticesCount);
                        ColorizeFace(map.values[x, z].cellMapColor, verticesCount);
                        continue;
                    }
                }
                else
                {
                    if (map.values[x, z].cellType == CellType.Empty || map.values[x, z].cellType == CellType.Floor)
                    {
                        continue;
                    }
                }

                CreateSolidHex(spawnPos, settings.cellScale, x, z, map);
                Debug.DrawRay(spawnPos, Vector3.up * 3.0f, Color.green, 0.5f);
            }
        }

        mesh.name      = "Discrete Solid PointyHex Mesh";
        mesh.vertices  = vertices.ToArray();
        mesh.triangles = triangles.ToArray();
        mesh.colors    = colors.ToArray();
        mesh.RecalculateNormals();

        return(mesh);
    }
    private static void CreateSolidHex(Vector3 hexPosition, float scale, int x, int z, EmptyGrid map)
    {
        Color faceColor = map.values[x, z].cellMapColor;

        foreach (var direction in SolidPointyHexagonData.PossibleDirections())
        {
            if (map.GetNeighbour(x, z, direction, GridType.PointyHex).cellType == CellType.Empty || map.GetNeighbour(x, z, direction, GridType.PointyHex).cellType == CellType.Floor)
            {
                int verticesCount;
                CreateFace(direction, scale, hexPosition, out verticesCount);
                ColorizeFace(faceColor, verticesCount);
            }
        }
    }
    private static void CreateSolidHex(Vector3 hexPosition, float scale, int x, int z, EmptyGrid map, HeightMap heightMap)
    {
        Color faceColor = map.values[x, z].cellMapColor;

        foreach (var direction in SolidPointyHexagonData.PossibleDirections())
        {
            //CellType neighbourType = map.GetNeighbour(x, z, direction, GridType.PointyHex).cellType;
            //if (neighbourType == CellType.Empty || neighbourType == CellType.Floor ||
            //    (neighbourType == CellType.Wall && heightMap.GetNeighbour(x, z, direction, GridType.PointyHex) < heightMap.values[x, z])
            //    )

            if (map.GetNeighbour(x, z, direction, GridType.PointyHex).cellType == CellType.Empty || map.GetNeighbour(x, z, direction, GridType.PointyHex).cellType == CellType.Floor ||
                ((map.GetNeighbour(x, z, direction, GridType.PointyHex).cellType != CellType.Empty && map.GetNeighbour(x, z, direction, GridType.PointyHex).cellType != CellType.Floor) && heightMap.GetNeighbour(x, z, direction, GridType.PointyHex) < heightMap.values[x, z] - epsilon)
                )
            {
                int verticesCount;
                CreateFace(direction, scale, hexPosition, out verticesCount);
                ColorizeFace(faceColor, verticesCount);
            }
        }
    }
    public static Mesh GenerateGridMesh(EmptyGrid map, TileMapSettings settings)
    {
        mesh = new Mesh();
        //Mesh mesh = new Mesh();
        vertices  = new List <Vector3>();
        triangles = new List <int>();
        colors    = new List <Color>();

        Vector2 bottomLeft;

        if (settings.isCentered)
        {
            bottomLeft = new Vector2(-map.width, -map.height) * settings.cellScale * 0.5f + new Vector2(settings.mapOffsetX, -settings.mapOffsetZ);
        }
        else
        {
            bottomLeft = new Vector2(settings.mapOffsetX, -settings.mapOffsetZ);
        }

        Debug.DrawRay(new Vector3(bottomLeft.x, 0.0f, bottomLeft.y), Vector3.up * 5.0f, Color.red, 0.5f);

        //vertices = new Vector3[(map.width + 1) * (map.height + 1)];
        //uv = new Vector2[vertices.Length];
        //triangles = new int[map.width * map.height * 6]; //6 = 2 triangles * 3 vertices
        //colors = new Color[vertices.Length];

        //Vector3[] vertices = new Vector3[(map.width + 1) * (map.height + 1)];
        //Vector2[] uv = new Vector2[vertices.Length];
        //int[] triangles = new int[map.width * map.height * 6]; //6 = 2 triangles * 3 vertices
        //Color[] colors = new Color[vertices.Length];

        // * 0.5f because it's cube
        float vertexOffset = settings.cellScale * 0.5f;

        int vert = 0;
        int tri  = 0;

        for (int y = 0; y < map.height; y++)
        {
            for (int x = 0; x < map.width; x++)
            {
                Vector3 cellOffset = new Vector3(x * settings.cellScale, 0.0f, y * settings.cellScale) + new Vector3(bottomLeft.x, 0.0f, bottomLeft.y);

                if (!settings.showWallsOnly)
                {
                    if (map.values[x, y].cellType == CellType.Empty || map.values[x, y].cellType == CellType.Floor)
                    {
                        CreateFace(Direction.Up, vertexOffset, cellOffset + (Vector3.forward + Vector3.right) * vertexOffset + Vector3.down * settings.cellScale);
                        ColorizeFace(map.values[x, y].cellMapColor);
                        continue;
                    }
                }
                else
                {
                    if (map.values[x, y].cellType == CellType.Empty || map.values[x, y].cellType == CellType.Floor)
                    {
                        continue;
                    }
                }

                CreateCube(cellOffset + (Vector3.forward + Vector3.right) * vertexOffset, vertexOffset, x, y, map);
                Debug.DrawRay(cellOffset + (Vector3.forward + Vector3.right) * vertexOffset, Vector3.up * 3.0f, Color.green, 0.5f);
            }
        }

        mesh.name      = "Discrete Voxel Mesh";
        mesh.vertices  = vertices.ToArray();
        mesh.triangles = triangles.ToArray();
        mesh.colors    = colors.ToArray();
        //mesh.vertices = vertices;
        //mesh.uv = uv;
        //mesh.triangles = triangles;
        //mesh.colors = colors;
        mesh.RecalculateNormals();

        return(mesh);
    }
    public static EmptyGrid ProcessMap(EmptyGrid map, SettlingRoomsSettings settings)
    {
        settlingRooms.FillCellMap(ref map.values, CellType.Wall, CellType.Floor);

        return(map);
    }
    public static EmptyGrid ProcessMap(EmptyGrid map, RandomRoomPlacementSettings settings)
    {
        // Random Generator
        Random.State initialState = Random.state;
        if (settings.useFixedSeed)
        {
            Random.InitState(settings.seed.GetHashCode());
        }
        else
        {
            Random.InitState(Time.time.ToString().GetHashCode());
        }
        //! Added
        if (settings.isRoomsConnected)
        {
            map.FillWholeGrid(CellType.Empty);
        }

        // Generate random rooms
        List <Room> roomList = GenerateRandomRooms(ref map.width, ref map.height, ref settings);

        // Random room placement on map
        foreach (Room room in roomList)
        {
            //Debug.Log("I'm inside " + room.boundsInt.xMin + " " + room.boundsInt.xMax + " " + room.boundsInt.zMin + " " + room.boundsInt.zMax);
            DrawRectangularRoom(ref map.values, room);
        }

        //! Added
        if (settings.isRoomsConnected)
        {
            List <Line> lines = new List <Line>();
            /// MST
            for (int i = 0; i < roomList.Count - 1; i++)
            {
                int   minIndex    = -1;
                float minDistance = float.MaxValue;
                for (int j = i + 1; j < roomList.Count; j++)
                {
                    //if (j == i)
                    //{
                    //    continue;
                    //}
                    float distance = UnityUtilities.Distances.GetManhattanDistance(roomList[i].Midpoint, roomList[j].Midpoint);
                    if (distance < minDistance)
                    {
                        minIndex    = j;
                        minDistance = distance;
                    }
                }
                Line line = new Line(roomList[i].Midpoint, roomList[minIndex].Midpoint);
                lines.Add(line);
            }

            NodeGrid    nodeGrid    = new NodeGrid(ref map);
            Pathfinding pathfinding = new Pathfinding();

            foreach (var item in lines)
            {
                List <Node> path = pathfinding.FindPath(nodeGrid.values[item.start.x, item.start.y], nodeGrid.values[item.end.x, item.end.y], ref nodeGrid, false, true, false);
                foreach (var node in path)
                {
                    map.values[node.x, node.z] = Cell.CreateCell(CellType.Floor);
                    for (int z = node.z - 1; z <= node.z + 1; z++)
                    {
                        for (int x = node.x - 1; x <= node.x + 1; x++)
                        {
                            if (!nodeGrid.IsOutside(x, z) || (x != z && x != node.x))
                            {
                                if (map.values[x, z].cellType == CellType.Empty)
                                {
                                    map.values[x, z] = Cell.CreateCell(CellType.Wall);
                                }
                            }
                        }
                    }
                }
            }
        }
        ////////List<Corridor> corridors = new List<Corridor>();
        ////////foreach (var room in roomList)
        ////////{
        ////////    map.values[room.CenterX, room.CenterZ] = Cell.CreateCell(CellType.OuterWall);
        ////////}
        ////////// Connect rooms
        ////////while (roomList.Count > 1)
        ////////{
        ////////    Room room = roomList[Random.Range(0, roomList.Count)];
        ////////    roomList.Remove(room);
        ////////    Room room2 = roomList[Random.Range(0, roomList.Count)];
        ////////    roomList.Remove(room2);
        ////////    Corridor corridor = new Corridor(room.GetCenter(), room2.GetCenter(), Direction.Nowhere);
        ////////    //if (Random.value < 0.2f)
        ////////    //{
        ////////        if (Random.value < 0.5f)
        ////////        {
        ////////            roomList.Add(room);
        ////////        }
        ////////        else
        ////////        {
        ////////            roomList.Add(room2);
        ////////        }
        ////////    //}
        ////////    corridors.Add(corridor);
        ////////}
        ////////for (int i = 0; i < corridors.Count; i++)
        ////////{
        ////////    //DrawVerticalCorridor(ref map.values, corridors[i], CellType.Wall, CellType.OuterWall);
        ////////    //DrawHorizontalCorridor(ref map.values, corridors[i], CellType.Wall, CellType.OuterWall);
        ////////}

        // Connect floor tiles that are between single wall
        if (settings.hasCleanup)
        {
            CleanUpRoomPlacement(ref map.values, ref map.width, ref map.height);
        }

        Random.state = initialState;

        return(map);
    }