private void GenerateNextRoom(string roomType, bool randomRoom = true)
    {
        LevelDatabase.RoomData room;

        if (randomRoom)
        {
            int openingIndex = 1 << Helpers.Rand(3);
            if (lastRoomData != null)
            {
                if (lastRoomData.index == 1 << 0)
                {
                    openingIndex = 1 << Helpers.RandParam(1, 2);
                }
                else if (lastRoomData.index == 1 << 1)
                {
                    openingIndex = 1 << Helpers.RandParam(0, 2);
                }
                else if (lastRoomData.index == 1 << 2)
                {
                    openingIndex = 1 << Helpers.RandParam(0, 1);
                }
            }

            room = LevelDatabase.I.GetRandomRoom(roomType, openingIndex);
        }
        else
        {
            room = LevelDatabase.I.GetOnlyRoom(roomType);
        }

        var roomView = new RoomView();

        roomView.startY    = -currentYPos;
        roomView.index     = roomIndex++;     //Debug only
        roomView.tileTable = new TileView[room.width, room.height];

        bool[, ] decalPositionsFreeTable = new bool[room.width, room.height];
        List <Vector2Int> decalPositionsFreeList = new List <Vector2Int>();

        for (int i = 0; i < room.width; i++)
        {
            bool topCheckOn = false;
            if (lastRoomData != null)
            {
                topCheckOn = lastRoomData.data[i, 0] == TileID.Empty;
            }

            for (int j = room.height - 1; j >= 0; j--)
            {
                if (topCheckOn)
                {
                    if (room.data[i, j] == TileID.Wall)
                    {
                        continue;
                    }
                    else
                    {
                        topCheckOn = false;
                    }
                }

                var pos = new Vector3(i, -currentYPos + j);

                if (room.data[i, j] > TileID.Empty)
                {
                    var      prefab = floorPrefab;
                    TileView tile   = null;

                    bool flipGraphics = false;
                    if (room.data[i, j] == TileID.StatueL)
                    {
                        prefab = statuePrefab;
                    }
                    if (room.data[i, j] == TileID.StatueR)
                    {
                        flipGraphics = true;
                        prefab       = statuePrefab;
                    }
                    else if (i == 0 ||  i == room.width - 1)
                    {
                        prefab = wallPrefab;
                    }

                    tile = Instantiate(prefab, pos, Quaternion.identity);
                    roomView.tileTable[i, j] = tile;
                    tile.posX      = i;
                    tile.posY      = j;
                    tile.roomIndex = roomView.index;

                    if (flipGraphics)
                    {
                        tile.FlipGraphics();
                    }
                }
                else if (i > 0 && i < room.width - 1 && j > 0 && j < room.height - 1)
                {
                    decalPositionsFreeTable[i, j] = true;
                    decalPositionsFreeList.Add(new Vector2Int(i, j));
                }
            }
        }

        //Add decals
        int decalAmount = Helpers.Rand(minDecalPerRoom, maxDecalPerRoom);

        for (int i = 0; i < decalAmount; i++)
        {
            if (decalPositionsFreeList.Count == 0)
            {
                break;
            }

            var position = Helpers.RandRemove(decalPositionsFreeList);
            decalPositionsFreeTable[position.x, position.y] = false;

            bool canAddBigDecal = true, canAddHugeDecal = true;

            foreach (var pos in bigDecalPositions)
            {
                int x = position.x + pos.x, y = position.y + pos.y;

                if (room.data[x, y] != TileID.Empty || !decalPositionsFreeTable[x, y])
                {
                    canAddBigDecal  = false;
                    canAddHugeDecal = false;
                    break;
                }
            }

            if (canAddBigDecal)
            {
                foreach (var pos in hugeDecalPositions)
                {
                    int x = position.x + pos.x, y = position.y + pos.y;

                    if (room.data[x, y] != TileID.Empty || !decalPositionsFreeTable[x, y])
                    {
                        canAddHugeDecal = false;
                        break;
                    }
                }
            }

            if (canAddHugeDecal && Helpers.RandPercent(40))
            {
                var decal = Instantiate(decalPrefab, (Vector2)position + Vector2.up * roomView.startY, Quaternion.identity) as SpriteRenderer;
                decal.sprite = Helpers.Rand(hugeDecals);

                foreach (var pos in hugeDecalPositions)
                {
                    int x = position.x + pos.x, y = position.y + pos.y;
                    decalPositionsFreeTable[x, y] = false;

                    for (int j = 0; j < decalPositionsFreeList.Count; j++)
                    {                     //Ugly hack
                        if (decalPositionsFreeList[j].x == x && decalPositionsFreeList[j].y == y)
                        {
                            decalPositionsFreeList.RemoveAt(j);
                        }
                    }
                }
            }
            else
            if (canAddBigDecal)
            {
                var decal = Instantiate(decalPrefab, (Vector2)position + Vector2.up * roomView.startY, Quaternion.identity) as SpriteRenderer;
                decal.sprite = Helpers.Rand(bigDecals);

                foreach (var pos in bigDecalPositions)
                {
                    int x = position.x + pos.x, y = position.y + pos.y;
                    decalPositionsFreeTable[x, y] = false;

                    for (int j = 0; j < decalPositionsFreeList.Count; j++)
                    {                     //Ugly hack
                        if (decalPositionsFreeList[j].x == x && decalPositionsFreeList[j].y == y)
                        {
                            decalPositionsFreeList.RemoveAt(j);
                        }
                    }
                }
            }
            else
            {
                if (smallDecals.Length == 0)
                {                 //Try again in different position
                    i--;
                    continue;
                }

                var decal = Instantiate(decalPrefab, (Vector2)position + Vector2.up * roomView.startY, Quaternion.identity) as SpriteRenderer;
                decal.sprite = Helpers.Rand(smallDecals);
            }
        }

        //Steal top row from last room view.... Ugly as heck!
        if (rooms.Count > 0)
        {
            var upperRoom = rooms[rooms.Count - 1];
            for (int i = 1; i < upperRoom.width - 1; i++)
            {
                var upperTile = upperRoom.tileTable[i, 0];

                if (upperTile != null)
                {
                    upperRoom.tileTable[i, 0] = null;
                    roomView.tileTable[i, roomView.height - 1] = upperTile;

                    upperTile.posY      = roomView.height - 1;
                    upperTile.roomIndex = roomView.index;
                }
            }
        }

        //Set falling speeds
        if (rooms.Count >= 3)
        {
            for (int i = rooms.Count - 3; i < rooms.Count; i++)
            {
                rooms[i].SetFalling(3 - (i - (rooms.Count - 3)));
            }
        }

        currentYPos += room.height - 1;
        lastRoomData = room;
        rooms.Add(roomView);

        roomCount++;

        if (roomCount % 3 == 0)
        {
            Instantiate(BG, BG.transform.position + (Vector3.down * 13 * Mathf.Floor(roomCount / 3f)), Quaternion.identity);
        }
    }