private List <PreciseTileChecker> GetRegionTiles(int x, int y)
    {
        List <PreciseTileChecker> caveTiles = new List <PreciseTileChecker>();

        int[,] mapFlags = new int[row, col];

        Queue <PreciseTileChecker> queue = new Queue <PreciseTileChecker>();

        queue.Enqueue(new PreciseTileChecker(x, y));
        while (queue.Count > 0)
        {
            PreciseTileChecker tile = queue.Dequeue();

            if (mapTiles[col * x + y].AutoTileID > (int)TilePiece.EMPTY && mapTiles[col * x + y] != null)
            {
                caveTiles.Add(tile);
                for (var r = tile.tileX - 1; r <= tile.tileX + 1; r++)
                {
                    for (var c = tile.tileY - 1; c <= tile.tileY + 1; c++)
                    {
                        if (IsInMapRange(r, c) && (c == tile.tileY || r == tile.tileX))
                        {
                            if (mapFlags[r, c] == 0 && mapLayout[r, c] == 1)
                            {
                                mapFlags[r, c] = 1;
                                queue.Enqueue(new PreciseTileChecker(r, c));
                            }
                        }
                    }
                }
            }
        }

        return(caveTiles);
    }
    private List <PreciseTileChecker> GetPassageTiles(PreciseTileChecker from, PreciseTileChecker to)
    {
        List <PreciseTileChecker> line = new List <PreciseTileChecker>();

        int  x        = from.tileX;
        int  y        = from.tileY;
        int  dx       = to.tileX - from.tileX;
        int  dy       = to.tileY - from.tileY;
        bool inverted = false;
        int  step     = Math.Sign(dx);
        int  gradient = Math.Sign(dy);
        int  longest  = Mathf.Abs(dx);
        int  shortest = Mathf.Abs(dy);

        if (longest < shortest)
        {
            inverted = true;
            longest  = Mathf.Abs(dy);
            shortest = Mathf.Abs(dx);
            step     = Math.Sign(dy);
            gradient = Math.Sign(dx);
        }

        int gradientAcc = longest / 2;

        for (var i = 0; i < longest; i++)
        {
            line.Add(new PreciseTileChecker(x, y));

            if (inverted)
            {
                y += step;
            }
            else
            {
                x += step;
            }

            gradientAcc += shortest;

            if (gradientAcc >= longest)
            {
                if (inverted)
                {
                    x += gradient;
                }
                else
                {
                    y += gradient;
                }

                gradientAcc -= longest;
            }
            //Debug.Log("X = " + x + " Y = " + y);
        }
        return(line);
    }
    } // <3

    private void CreatePath(Cavern caveA, Cavern caveB, PreciseTileChecker tileA, PreciseTileChecker tileB)
    {
        Cavern.ConnectCaves(caveA, caveB);
        //Debug.Log("Tile A ID:" + mapTiles[col * tileA.tileX + tileA.tileY].TileID + " Tile B ID:" + mapTiles[col * tileB.tileX + tileB.tileY].TileID);
        //Debug.Log("Tile A X:" + tileA.tileX + " Tile A Y:" + tileA.tileY + " Tile B X:" + tileB.tileX + " Tile B Y:" + tileB.tileY);
        //Debug.Log("Begin Line");
        List <PreciseTileChecker> line = GetPassageTiles(tileA, tileB);

        foreach (PreciseTileChecker t in line)
        {
            //Debug.Log("Tile X: " + t.tileX + " Tile Y: " + t.tileY + " Tile ID: " + (col * t.tileX + t.tileY));
            DrawPassage(t, 1);
        }
        //Debug.Log("End Line");
    }
 private void DrawPassage(PreciseTileChecker t, int r)
 {
     for (var x = -r; x <= r; x++)
     {
         for (var y = -r; y <= r; y++)
         {
             //Debug.Log("Attempting to draw passage");
             if (x * x + y * y <= r * r)
             {
                 //Debug.Log("Drawing passage");
                 int drawX = t.tileX + x;
                 int drawY = t.tileY + y;
                 if (IsInMapRange(drawX, drawY))
                 {
                     mapLayout[drawX, drawY] = 1;
                 }
             }
         }
     }
 }
    private void addItems(int doors, int chests)
    {
        List <PreciseTileChecker> renderedTiles = new List <PreciseTileChecker>();

        for (var x = 0; x < row; x++)
        {
            for (var y = 0; y < col; y++)
            {
                if (mapTiles[col * x + y].AutoTileID > 0)
                {
                    renderedTiles.Add(new PreciseTileChecker(x, y));
                }
            }
        }

        for (var d = 0; d < doors; d++)
        {
            PreciseTileChecker tile = renderedTiles[UnityEngine.Random.Range(0, renderedTiles.Count)];
            if (d == 0)
            {
                if (MapMaker.Instance.floor != 1)
                {
                    mapTiles[col * tile.tileX + tile.tileY].AutoTileID = (int)TilePiece.MONSTER;
                }
            }
            else
            {
                mapTiles[col * tile.tileX + tile.tileY].AutoTileID = (int)TilePiece.TREE;
            }
            renderedTiles.Remove(tile);
        }

        for (var c = 0; c < chests; c++)
        {
            PreciseTileChecker tile = renderedTiles[UnityEngine.Random.Range(0, renderedTiles.Count)];
            mapTiles[col * tile.tileX + tile.tileY].AutoTileID = (int)TilePiece.CASTLE;
            renderedTiles.Remove(tile);
        }
    }
    private void ConnectCaverns(List <Cavern> Caves, bool forceAccessibilityFromMain = false)
    {
        List <Cavern> caveListA = new List <Cavern>();
        List <Cavern> caveListB = new List <Cavern>();

        if (forceAccessibilityFromMain)
        {
            foreach (Cavern cave in Caves)
            {
                if (cave.isAccessibleFromMainCavern)
                {
                    caveListB.Add(cave);
                }
                else
                {
                    caveListA.Add(cave);
                }
            }
        }
        else
        {
            caveListA = Caves;
            caveListB = Caves;
        }
        int closestDistance          = 0;
        PreciseTileChecker bestTileA = new PreciseTileChecker();
        PreciseTileChecker bestTileB = new PreciseTileChecker();
        Cavern             bestCaveA = new Cavern();
        Cavern             bestCaveB = new Cavern();

        bool connectonFound = false;

        foreach (Cavern caveA in caveListA)
        {
            if (!forceAccessibilityFromMain)
            {
                connectonFound = false;
                if (caveA.connectedCaverns.Count > 0)
                {
                    continue;
                }
            }

            foreach (Cavern caveB in caveListB)
            {
                if (caveA == caveB || caveA.IsConnected(caveB))
                {
                    continue;
                }

                for (int tileIndexA = 0; tileIndexA < caveA.edges.Count; tileIndexA++)
                {
                    for (int tileIndexB = 0; tileIndexB < caveB.edges.Count; tileIndexB++)
                    {
                        PreciseTileChecker tileA = caveA.edges[tileIndexA];
                        PreciseTileChecker tileB = caveB.edges[tileIndexB];

                        int distance = (int)(Mathf.Pow((tileA.tileX - tileB.tileX), 2) + Mathf.Pow((tileA.tileY - tileB.tileY), 2));

                        if (distance < closestDistance || !connectonFound)
                        {
                            closestDistance = distance;
                            connectonFound  = true;
                            bestTileA       = tileA;
                            bestTileB       = tileB;
                            bestCaveA       = caveA;
                            bestCaveB       = caveB;
                        }
                    }
                }
            }

            if (connectonFound && !forceAccessibilityFromMain)
            {
                CreatePath(bestCaveA, bestCaveB, bestTileA, bestTileB);
            }
        }

        if (connectonFound && forceAccessibilityFromMain)
        {
            CreatePath(bestCaveA, bestCaveB, bestTileA, bestTileB);
            ConnectCaverns(Caves, true);
        }

        if (!forceAccessibilityFromMain)
        {
            ConnectCaverns(Caves, true);
        }
    } // <3