public void OpenDoor(VirtualMap map, CellLocation start_floor_loc, CellLocation end_floor_loc, CellLocation passage_loc, VirtualMap.DirectionType direction)
    {
        map.GetCell(passage_loc).Type        = VirtualCell.CellType.Door;
        map.GetCell(passage_loc).Orientation = direction;

        // We also connect the cells
        map.ConnectCells(start_floor_loc, end_floor_loc);
    }
    // The first pass will fill the tilemap intersection cells, so that it can be used similarly to the standard map interpreter
    private void PerformTilemapConversion(VirtualMap map, VirtualMap[] maps, int storey)
    {
        VirtualCell conversion_cell;

        VirtualCell[,] output_cells = new VirtualCell[map.Width, map.Height];

        for (int i = 0; i < map.Width; i++)
        {
            for (int j = 0; j < map.Height; j++)
            {
                CellLocation loc = new CellLocation(i, j);
                conversion_cell = VirtualCell.Copy(map.GetCell(loc));
                ConvertTileIntersections(map, conversion_cell);
                output_cells[i, j] = conversion_cell;
            }
        }

        // We can now override the initial map!
        for (int i = 0; i < map.Width; i++)
        {
            for (int j = 0; j < map.Height; j++)
            {
                map.SetCell(i, j, output_cells[i, j]);
            }
        }
    }
    /********************
    * Door creation
    ********************/
    // Create doors for a given room
    public void CreateDoors_Post(VirtualMap map, VirtualRoom r)
    {
        List <CellLocation> borderFloors = new List <CellLocation> ();

        // Examine borderFloors, create a list of border floors
        for (int i = 0; i < r.Width; i++)
        {
            for (int j = 0; j < r.Height; j++)
            {
                if (i == 0 || j == 0 || i == r.Width - 1 || j == r.Height - 1)
                {
                    CellLocation l = new CellLocation(r.leftCorner.x + 2 * i, r.leftCorner.y + 2 * j);
                    borderFloors.Add(l);
                }
            }
        }

        // Create doors close to the borders, where wall passages are
        CellLocation target_passage;

        foreach (CellLocation l in borderFloors)
        {
            foreach (VirtualMap.DirectionType dir in map.directions)
            {
                target_passage = map.GetNeighbourCellLocation(l, dir);
                if (map.GetCell(target_passage).IsWall())
                {
                    CheckDoorCreation(map, r, l, dir);
                }
            }
        }
    }
    /* DEPRECATED
     * public void CreateDoorPassages_Post(VirtualMap map)
     * {
     *  if (map.HasRooms())
     *  {
     *      RoomGenerator roomG = new RoomGenerator();
     *      roomG.doorsDensityModifier = doorsDensityModifier;
     *      foreach (VirtualRoom r in map.rooms) roomG.CreateDoors_Post(map, r);
     *  }
     *  }*/

    public void CreateRocks(VirtualMap map)
    {
        foreach (CellLocation c in map.visitedCells)
        {
            if (map.IsSurroundedByWalls(c))
            {
                map.GetCell((int)c.x, (int)c.y).Type = VirtualCell.CellType.Rock;
            }
        }
    }
    // The second pass will update the different tiles as needed
    private void PerformSpecificConversions(VirtualMap map, VirtualMap[] maps, int storey)
    {
        VirtualCell conversion_cell;

        VirtualCell[,] output_cells = new VirtualCell[map.Width, map.Height];

        for (int i = 0; i < map.Width; i++)
        {
            for (int j = 0; j < map.Height; j++)
            {
                CellLocation loc = new CellLocation(i, j);
                conversion_cell = VirtualCell.Copy(map.GetCell(loc));

                if (conversion_cell.IsFloor())
                {
                    ConvertFloor(map, conversion_cell);
                }
                else if (conversion_cell.IsDoor())
                {
                    ConvertDoor(map, conversion_cell);
                }
                else if (conversion_cell.IsWall())
                {
                    // All walls are rocks here
                    ConvertRock(map, conversion_cell);
                }
                else if (conversion_cell.IsNone())
                {
                    // All nones are rocks here
                    ConvertRock(map, conversion_cell);
                }
                else if (conversion_cell.IsRock())
                {
                    // All is rock!
                    ConvertRock(map, conversion_cell);
                }

                // Final pass on orientation randomization
                CheckOrientationRandomization(map, conversion_cell);

                // We save it in the initial map
                output_cells[i, j] = conversion_cell;
            }
        }

        // We can now override the initial map!
        for (int i = 0; i < map.Width; i++)
        {
            for (int j = 0; j < map.Height; j++)
            {
                map.SetCell(i, j, output_cells[i, j]);
            }
        }
    }
    public void ConvertDoor(VirtualMap map, VirtualCell conversion_cell)
    {
        if (conversion_cell.IsDoor())
        {
            if (!behaviour.drawDoors)
            {
                conversion_cell.Type = VirtualCell.CellType.EmptyPassage;
            }
            else
            {
                CellLocation prev_loc = map.GetNeighbourCellLocation(conversion_cell.location, conversion_cell.Orientation);
                CellLocation next_loc = map.GetNeighbourCellLocation(conversion_cell.location, map.GetDirectionOpposite(conversion_cell.Orientation));
//				Debug.Log (prev_loc);
//				Debug.Log (next_loc);
//				Debug.Log (map.GetCell(prev_loc).IsRoomFloor());
//				Debug.Log (map.GetCell(next_loc).IsRoomFloor());
                if (map.GetCell(prev_loc).IsRoomFloor() && map.GetCell(next_loc).IsRoomFloor())
                {
                    conversion_cell.Type = VirtualCell.CellType.RoomDoor;
                }
            }
        }
    }
    private bool CheckInsideRoomTile(VirtualMap map, CellLocation loc)
    {
        CellLocation[] neigh_locs      = map.GetAllNeighbours(loc);
        int            countRoomFloors = 0;

        foreach (CellLocation nl in neigh_locs)
        {
            if (!map.LocationIsOutsideBounds(nl) &&
                map.GetCell(nl).IsRoomFloor())
            {
                countRoomFloors++;
            }
        }
        return(countRoomFloors == 4);
    }
    // Various
    protected void ConvertWallOrientation(VirtualMap map, VirtualCell conversion_cell)
    {
        // Fix orientation of walls so that they follow the floors orientation
        conversion_cell.Orientation = VirtualMap.DirectionType.North;
        CellLocation neigh_loc = map.GetNeighbourCellLocation(conversion_cell.location, VirtualMap.DirectionType.North);

        if (!map.LocationIsOutsideBounds(neigh_loc))
        {
            VirtualCell neigh_cell = map.GetCell(neigh_loc);
            if (neigh_cell.IsNone())
            {
                conversion_cell.Orientation = VirtualMap.DirectionType.East;
            }
        }
    }
 /*****************
 * Building
 *****************/
 override public void BuildMaps(VirtualMap[] maps)
 {
     // We build what we have defined in the virtual maps
     for (int storey = 0; storey < maps.Length; storey++)
     {
         VirtualMap map = maps[storey];
         for (int i = 0; i < map.Width; i++)
         {
             for (int j = 0; j < map.Height; j++)
             {
                 CellLocation loc  = new CellLocation(i, j);
                 VirtualCell  cell = map.GetCell(loc);
                 BuildObjectsOfCell(map, cell, storey);
             }
         }
     }
 }
Example #10
0
    // Control if we can open a door in the given direction. Open it if possible
    private bool CheckDoorCreation(VirtualMap map, VirtualRoom r, CellLocation start_floor_loc, VirtualMap.DirectionType direction)
    {
        bool         result        = false;
        CellLocation end_floor_loc = map.GetTargetLocation(start_floor_loc, direction);
        CellLocation passage       = map.GetNeighbourCellLocation(start_floor_loc, direction);

        // We get the ending floor and check its validity
        if (end_floor_loc.isValid() && !map.GetCell(end_floor_loc).IsRock())
        {
            // We check whether we are connecting to another room
            if (map.roomCells.Contains(end_floor_loc))
            {
                // Check if we skip creating the door
                if (DungeonGenerator.Random.Instance.Next(0, 100) > doorsDensityModifier && // We do not skip if we request more doors than needed
                    r.IsAlreadyConnectedToARoomAt(end_floor_loc, map))       // We skip if we are already connected
                {
                    return(result);
                }

                OpenRoomDoor(map, r, start_floor_loc, end_floor_loc, passage, direction);
            }
            else
            {
                // We need one door for each corridor segment that has been separated out by this room
                //		To do that, we also create a door if the ending floor is a dead end, effectively getting rid of the dead end
                //		Also, we create if the ending floor is a rock (i.e. 4 walls), which can happen if this room blocks out single floor cells!

                // We check if we need to skip
                if (CheckSkipDoorToCorridor(map, r, end_floor_loc))
                {
                    return(result);
                }

                // Debug.Log("Room " + r + " CREATING TO " + passage);

                OpenCorridorDoor(map, r, start_floor_loc, end_floor_loc, passage, direction);
            }

            result = true;
        }
        return(result);
    }
Example #11
0
    void DrawConnections(VirtualCell input_cell, List <CellLocation> unvisited_locations, PhysicalMap physicalMap, VirtualMap virtualMap, int max_distance)
    {
        unvisited_locations.Remove(input_cell.location);
        Vector3 input_pos = physicalMap.GetRealWorldPosition(input_cell.location, virtualMap.storey_number);

        //Debug.Log("Has connected cells: " + start_cell.connectedCells.Count);
        foreach (CellLocation connected_cell_location in input_cell.connectedCells)
        {
            //Debug.Log(connected_cell_location);
            Vector3 end_pos = physicalMap.GetRealWorldPosition(connected_cell_location, virtualMap.storey_number);
            //Debug.Log(input_cell.distance_from_root * 1f / virtualMap.GetMaximumDistance());
            Color col = Color.Lerp(Color.red, Color.green, input_cell.distance_from_root * 1f / max_distance);
            Handles.color = col;
            Handles.DrawLine(input_pos, end_pos);
            if (unvisited_locations.Contains(connected_cell_location))
            {
                DrawConnections(virtualMap.GetCell(connected_cell_location), unvisited_locations, physicalMap, virtualMap, max_distance);
            }
        }
    }
    public void ConvertDirectionalRoomColumn(VirtualMap map, VirtualCell conversion_cell)
    {
        CellLocation l = conversion_cell.location;

        if (behaviour.useDirectionalFloors)
        {
            CellLocation[] border_neighs;

            bool considerDoorsAsWalls = true;

            // Count how many border neighbours are room walls
            int    countWallNeighs = 0;
            bool[] validIndices    = new bool[4];

            // This was a 'tile', check neigh walls
            border_neighs = map.GetAllNeighbours(l);
            for (int i = 0; i < border_neighs.Length; i++)
            {
                CellLocation other_l = border_neighs[i];
                if (!map.LocationIsOutsideBounds(other_l)
                    &&
                    (((behaviour.isolateDirectionalWallsForRooms && map.GetCell(other_l).IsRoomWall()) ||
                      (!behaviour.isolateDirectionalWallsForRooms && map.GetCell(other_l).IsWall())) ||
                     (considerDoorsAsWalls && map.GetCell(other_l).IsDoor())) &&
                    !map.IsPassageRemovable(other_l)      // Make sure the wall is not being removed!
                    )
                {
                    //Debug.Log(l + " -  " + other_l + " " + map.GetCell(other_l).Type);
                    countWallNeighs++;
                    validIndices[i] = true;
                }
            }


            // Define the adbvanced tiles
            //Debug.Log ("Cell " + l + " has neigh walls " + countWallNeighs);
            if (countWallNeighs == 0)
            {
                conversion_cell.Type = VirtualCell.CellType.RoomWallO;
            }
            else if (countWallNeighs == 1)
            {
                conversion_cell.Type = VirtualCell.CellType.RoomWallU;
            }
            else if (countWallNeighs == 2)
            {
                // Wall I
                conversion_cell.Type = VirtualCell.CellType.RoomWallI;
                //Debug.Log("SETTING " + l + " TO I");
                for (int i = 0; i < 4; i++)
                {
                    if (validIndices[i])
                    {
                        conversion_cell.Orientation = map.directions[(int)Mathf.Repeat(i + 1, 4)];
                        break;
                    }
                }

                // Wall L
                for (int i = 0; i < 4; i++)
                {
                    if (validIndices[i] && validIndices[(int)Mathf.Repeat(i + 1, 4)])
                    {
                        // This and the next are valid: left turn (we consider all of them to be left turns(
                        conversion_cell.Orientation = map.directions[(int)Mathf.Repeat(i + 3, 4)];
                        conversion_cell.Type        = VirtualCell.CellType.RoomWallL;
                        break;
                    }
                }
            }
            else if (countWallNeighs == 3)
            {
                conversion_cell.Type = VirtualCell.CellType.RoomWallT;
                for (int i = 0; i < 4; i++)
                {
                    if (validIndices[(int)Mathf.Repeat(i - 1, 4)] && validIndices[i] && validIndices[(int)Mathf.Repeat(i + 1, 4)])
                    {
                        conversion_cell.Orientation = map.directions[(int)Mathf.Repeat(i + 1, 4)];
                        break;
                    }
                }
            }
            else if (countWallNeighs == 4)
            {
                conversion_cell.Type = VirtualCell.CellType.RoomWallX;
            }
        }
    }
    private void PerformSpecificConversions(VirtualMap map, VirtualMap[] maps, int storey)
    {
        VirtualCell conversion_cell;

        VirtualCell[,] output_cells = new VirtualCell[map.Width, map.Height];

        // Modify the virtual map as needed
        for (int i = 0; i < map.Width; i++)
        {
            for (int j = 0; j < map.Height; j++)
            {
                CellLocation loc = new CellLocation(i, j);
                conversion_cell = VirtualCell.Copy(map.GetCell(loc));

                if (conversion_cell.IsFloor())
                {
                    ConvertFloor(map, conversion_cell);
                }
                else if (conversion_cell.IsDoor())
                {
                    ConvertDoor(map, conversion_cell);

                    bool renderWall = CheckWallRendering(map, conversion_cell);
                    if (renderWall)
                    {
                        ConvertWallOrientation(map, conversion_cell);
                    }
                }
                else if (conversion_cell.IsWall() || conversion_cell.IsEmpty())
                {
                    bool isPerimeter = ConvertPerimeterWall(map, conversion_cell);
                    if (!isPerimeter)
                    {
                        bool renderWall = CheckWallRendering(map, conversion_cell);
                        if (renderWall)
                        {
                            ConvertWallOrientation(map, conversion_cell);
                        }
                    }
                }
                else if (conversion_cell.IsNone())
                {
                    // 'None' cells may be converted to columns
                    ConvertColumn(map, conversion_cell, true);
                    ConvertPerimeterColumn(map, conversion_cell);
                }
                else if (conversion_cell.IsRock())
                {
                    // We may draw rocks
                    ConvertRock(map, conversion_cell);
                }

                // Final pass on orientation randomization
                CheckOrientationRandomization(map, conversion_cell);

                // We save the cell in the initial map
                output_cells[i, j] = conversion_cell;
            }
        }

        // We can now override the initial map!
        for (int i = 0; i < map.Width; i++)
        {
            for (int j = 0; j < map.Height; j++)
            {
                map.SetCell(i, j, output_cells[i, j]);
            }
        }

        // Additional modifications, per-storey
        // WE DO NOT HAVE ANYTHING HERE FOR NOW
    }
Example #14
0
    void OnSceneGUI()
    {
        if (showDebugCoordinates || showDebugConnections)
        {
            PhysicalMap  physicalMap = this.targetInstance.GetPhysicalMap();
            VirtualMap[] virtualMaps = this.targetInstance.GetVirtualMaps();
            if (this.targetInstance.HasGeneratedDungeon())
            {
                if (physicalMap != null && virtualMaps.Length > 0)
                {
                    GUIStyle guiStyle = new GUIStyle();

                    if (showDebugCoordinates)
                    {
                        for (int i = 0; i < virtualMaps.Length; i++)
                        {
                            foreach (VirtualCell c in virtualMaps[i].GetAllCells())
                            {
                                Vector3 p = physicalMap.GetRealWorldPosition(c.location, i);
                                if (c.location.x % 2 == 1 && c.location.y % 2 == 1)
                                {
                                    guiStyle.normal.textColor = Color.yellow;
                                    int actual_x = (c.location.x - 1) / 2;
                                    int actual_y = (c.location.y - 1) / 2;
                                    Handles.Label(p, c.location.x + "," + c.location.y + "\n(" + actual_x + "," + actual_y + ")", guiStyle);
                                }
                                else
                                {
                                    guiStyle.normal.textColor = Color.white;
                                    Handles.Label(p, c.location.x + "," + c.location.y, guiStyle);
                                }
                            }
                        }
                    }

                    if (showDebugConnections)
                    {
                        for (int i = 0; i < virtualMaps.Length; i++)
                        {
                            VirtualMap          virtualMap          = virtualMaps[i];
                            List <CellLocation> unvisited_locations = new List <CellLocation>(virtualMap.WalkableLocations);
                            //Debug.Log("Starting from " + start_location);
                            int max_distance = virtualMap.GetMaximumDistance();

                            int stop_iter = 0;
                            while (unvisited_locations.Count > 0)
                            {
                                CellLocation start_location = unvisited_locations[0]; // We start from a walkable cell (doesn't matter which one)
                                VirtualCell  start_cell     = virtualMap.GetCell(start_location);

                                DrawConnections(start_cell, unvisited_locations, physicalMap, virtualMap, max_distance);

                                stop_iter++;
                                if (stop_iter == 100)
                                {
                                    DaedalusDebugUtils.Assert(false, "Looping in show debug connectsion!");
                                    break; // ERROR HERE!
                                }
                            }
                        }
                    }

                    // TEST path check
                    //VirtualMap test_virtualMap = virtualMaps[0];
                    //List<CellLocation> test_unvisited_locations = new List<CellLocation>(test_virtualMap.WalkableLocations);
                    //test_virtualMap.ExistsPathBetweenLocations(test_unvisited_locations[0], test_unvisited_locations[test_unvisited_locations.Count - 1]);
                }
            }
        }
    }
    // This will convert 'None' cells to columns where necessary.
    protected bool ConvertColumn(VirtualMap map, VirtualCell conversion_cell, bool mayBeDirectional = true)
    {
        CellLocation l = conversion_cell.location;
        //Debug.Log(l);
        bool isRoomColumn     = false;
        bool isCorridorColumn = false;
        bool isPassageColumn  = false;
        bool createColumn     = true;

        if (map.IsColumnRemovable(l, behaviour.drawWallCorners, behaviour.createColumnsInRooms))
        {
            //Debug.Log(conversion_cell.location + " Is removable!");
            createColumn = false;
        }
        else
        {
            //Debug.Log(conversion_cell.location + " Is not removable!");

            // We check all neighs to determine what type of column this is
            foreach (VirtualMap.DirectionType dir in map.directions)
            {
                CellLocation neigh_loc = map.GetNeighbourCellLocation(l, dir);
                if (!map.LocationIsOutsideBounds(neigh_loc))
                {
                    VirtualCell neigh_cell = map.GetCell(neigh_loc);

                    //Debug.Log("CHECK " + neigh_cell.location + " TYPE " + neigh_cell.Type);

                    if (neigh_cell.IsDoor())
                    {
                        conversion_cell.Type = VirtualCell.CellType.PassageColumn;
                        isPassageColumn      = true;
                        break;
                    }
                    else if (!isRoomColumn && neigh_cell.IsCorridorWall())
                    {
                        conversion_cell.Type = VirtualCell.CellType.CorridorColumn;
                        isCorridorColumn     = true;
                        // Do not break, as we need to check all the other walls to be sure
                    }
                    else if (neigh_cell.IsRoomWall())
                    {
                        conversion_cell.Type = VirtualCell.CellType.RoomColumn;
                        isRoomColumn         = true;
                        // Do not break, as we need to check all the other walls to be sure
                    }
                }
            }
        }

        // This may be surrounded by floors!
        if (createColumn &&
            (!isRoomColumn && !isCorridorColumn && !isPassageColumn))
        {
            if (map.IsInRoom(l))
            {
                if (behaviour.createColumnsInRooms)
                {
                    conversion_cell.Type = VirtualCell.CellType.InsideRoomColumn;
                }
                else
                {
                    conversion_cell.Type = VirtualCell.CellType.RoomFloorInside;
                }
            }
            else
            {
                // NOT IN ROOM: THIS IS EITHER SURROUNDED BY ROCKS OR BY CORRIDORS!!
                // We check all neighbours to make sure

                /*foreach(VirtualMap.DirectionType dir in map.directions){
                 *      CellLocation neigh_loc = map.GetNeighbourCellLocationOfSameType(l,dir);
                 *      if (!map.LocationIsOutsideBounds(neigh_loc)){
                 *              VirtualCell neigh_cell = map.GetCell(neigh_loc);
                 * }*/
                conversion_cell.Type = VirtualCell.CellType.CorridorColumn;
            }
            //Debug.Log("ROOM COL? " + conversion_cell.Type);
        }


        // Directional column
        if (createColumn)
        {
            ConvertDirectionalColumn(map, conversion_cell, mayBeDirectional);
        }

        // If the column is not created, we disable it
        if (!createColumn)
        {
            conversion_cell.Type = VirtualCell.CellType.None;
        }

        return(createColumn);
    }
Example #16
0
    public VirtualRoom CreateRoom(VirtualMap map, int width, int height, VirtualRoom r)
    {
        // Check if we have enough space for a room
        if (r.leftCorner == new CellLocation(-1, -1))
        {
            return(null);
        }
        else
        {
            //Debug.Log ("Creating a room: w:"+width +" H:"+height +" starting_location:"+r.leftCorner);
            for (int i = 0; i < r.Width; i++)
            {
                for (int j = 0; j < r.Height; j++)
                {
                    CellLocation l = new CellLocation(r.leftCorner.x + 2 * i, r.leftCorner.y + 2 * j);
                    // We create the room starting from the lower left floor

                    //Debug.Log("LOC: " + l);

                    // Do not add to this room's cells if it already belongs to another room
                    if (usedLocations.Contains(l))
                    {
//							Debug.Log (l + " already belongs to a room!");
                        continue;
                    }

                    VirtualCell passageCell;

                    // Set top passage to empty
                    passageCell = map.GetCell(l.x, l.y + 1);
                    if (!passageCell.IsRoomWall())                      // May belong to another room already
                    {
                        passageCell.Type = VirtualCell.CellType.EmptyPassage;
                        if (l.y + 2 <= r.leftCorner.y + 2 * (r.Height - 1))
                        {
                            map.ConnectCells(l, new CellLocation(l.x, l.y + 2));
                            //Debug.Log("EMPTY: " + l + " TO TOP");
                        }
                    }

                    // Set right passage to empty
                    passageCell = map.GetCell(l.x + 1, l.y);
                    if (!passageCell.IsRoomWall())                      // May belong to another room already
                    {
                        passageCell.Type = VirtualCell.CellType.EmptyPassage;
                        if (l.x + 2 <= r.leftCorner.x + 2 * (r.Width - 1))
                        {
                            map.ConnectCells(l, new CellLocation(l.x + 2, l.y));
                            //Debug.Log("EMPTY: " + l + " TO RIGHT");
                        }
                    }

                    // Other passages are potentially walls
                    if (i == r.Width - 1)
                    {
                        map.GetCell(l.x + 1, l.y).Type = VirtualCell.CellType.RoomWall;
                        CellLocation floor_l = new CellLocation(l.x + 2, l.y);
                        if (!map.LocationIsOutsideBounds(floor_l))
                        {
                            map.DisconnectCells(l, floor_l);
                        }
                        //Debug.Log("WALL RIGHT: " + map.GetCell(l.x + 1, l.y).starting_location);
                    }
                    if (i == 0)
                    {
                        map.GetCell(l.x - 1, l.y).Type = VirtualCell.CellType.RoomWall;
                        CellLocation floor_l = new CellLocation(l.x - 2, l.y);
                        if (!map.LocationIsOutsideBounds(floor_l))
                        {
                            map.DisconnectCells(l, floor_l);
                        }
                        //Debug.Log("WALL LEFT: " + map.GetCell(l.x - 1, l.y).starting_location);
                    }
                    if (j == r.Height - 1)
                    {
                        map.GetCell(l.x, l.y + 1).Type = VirtualCell.CellType.RoomWall;
                        CellLocation floor_l = new CellLocation(l.x, l.y + 2);
                        if (!map.LocationIsOutsideBounds(floor_l))
                        {
                            map.DisconnectCells(l, floor_l);
                        }
                        //Debug.Log("WALL TOP: " + map.GetCell(l.x, l.y + 1).starting_location);
                    }
                    if (j == 0)
                    {
                        map.GetCell(l.x, l.y - 1).Type = VirtualCell.CellType.RoomWall;
                        CellLocation floor_l = new CellLocation(l.x, l.y - 2);
                        if (!map.LocationIsOutsideBounds(floor_l))
                        {
                            map.DisconnectCells(l, floor_l);
                        }
                        //Debug.Log("WALL BOT: " + map.GetCell(l.x, l.y - 1).starting_location);
                    }

                    map.AddRoomCell(l);

                    r.cells.Add(l);
                    usedLocations.Add(l);
                }
            }
        }
        return(r);
    }
    // The second pass will update the different tiles as needed
    private void PerformSpecificConversions(VirtualMap map, VirtualMap[] maps, int storey)
    {
        VirtualCell conversion_cell;

        VirtualCell[,] output_cells = new VirtualCell[map.Width, map.Height];

        for (int i = 0; i < map.Width; i++)
        {
            for (int j = 0; j < map.Height; j++)
            {
                CellLocation loc = new CellLocation(i, j);
                conversion_cell = VirtualCell.Copy(map.GetCell(loc));
                //Debug.Log("CHECKING " + conversion_cell);

                if (conversion_cell.IsFloor())
                {
                    ConvertFloor(map, conversion_cell);
                }
                else if (conversion_cell.IsDoor())
                {
                    ConvertDoor(map, conversion_cell);

                    CheckWallRendering(map, conversion_cell);
//					if (renderWall) ConvertFixedWallOrientation(map,conversion_cell);

                    AddFillingFloors(map, conversion_cell);
                }
                else if (conversion_cell.IsWall())
                {
                    bool isPerimeter = ConvertWall(map, conversion_cell);

                    bool renderWall = CheckWallRendering(map, conversion_cell);
                    if (renderWall)
                    {
                        if (!isPerimeter || (isPerimeter && !behaviour.orientPerimeter))
                        {
                            ConvertFixedWallOrientation(map, conversion_cell);
                        }
                    }
                    else
                    {
                        ConvertRock(map, conversion_cell);                      // May be a rock
                    }
                    AddFillingFloors(map, conversion_cell);
                }
                else if (conversion_cell.IsNone())
                {
                    //Debug.Log("NONE CELL " + conversion_cell);
                    // 'None' cells are usually converted to columns
                    bool isColumn    = ConvertColumn(map, conversion_cell);
                    bool isPerimeter = ConvertPerimeterColumn(map, conversion_cell);
                    ConvertFixedWallOrientation(map, conversion_cell);                          // Also columns need to be orientated correctly

                    // If not a column, check what this is
                    if (!isColumn && !isPerimeter)
                    {
                        // Usually a rock
                        ConvertRock(map, conversion_cell);
                    }

                    bool isActuallyFloor = false;
                    // Also, an inside-room tile may be transformed into a floor
                    if (!isPerimeter)
                    {
                        if (conversion_cell.IsFloor()) //CheckRoom(map,conversion_cell.location)){
                        //Debug.Log("INSIDE!");
                        {
                            AddToCorrectRoom(map, conversion_cell.location);
                            conversion_cell.Type = VirtualCell.CellType.RoomFloor;
                            ConvertFloor(map, conversion_cell);
                            isActuallyFloor = true;
                        }
                    }

                    if (!isActuallyFloor)
                    {
                        AddFillingFloors(map, conversion_cell);
                    }
                }
                else if (conversion_cell.IsRock())
                {
                    // We may draw rocks
                    ConvertRock(map, conversion_cell);

                    AddFillingFloors(map, conversion_cell);
                }


                // Final pass on orientation randomization
                CheckOrientationRandomization(map, conversion_cell);

                // We save it in the initial map
                output_cells[i, j] = conversion_cell;
            }
        }

        // We can now override the initial map!
        for (int i = 0; i < map.Width; i++)
        {
            for (int j = 0; j < map.Height; j++)
            {
                map.SetCell(i, j, output_cells[i, j]);
            }
        }
    }
    protected void ConvertFake3DEffect(VirtualMap map, VirtualCell conversion_cell)
    {
        CellLocation below_loc = map.GetNeighbourCellLocation(conversion_cell.location, VirtualMap.DirectionType.South);

        if ((conversion_cell.IsColumn() || conversion_cell.IsWall()))
        {
            // If we have a wall below and this is a wall, we transform this to a special wall
            bool        isAbove    = false;
            VirtualCell below_cell = null;
            if (!map.LocationIsOutsideBounds(below_loc))
            {
                below_cell = map.GetCell(below_loc);
                if (below_cell.IsColumn() || below_cell.IsWall() || below_cell.IsRock())
                {
                    isAbove = true;
                }
                else
                {
                    isAbove = false;
                }
            }
            else
            {
                isAbove = true;
            }

            if (isAbove)
            {
                if (conversion_cell.IsRoom())
                {
                    conversion_cell.Type = VirtualCell.CellType.Fake3D_Room_WallAbove;
                }
                else
                {
                    conversion_cell.Type = VirtualCell.CellType.Fake3D_Corridor_WallAbove;
                }
            }
            else
            {
                if (conversion_cell.IsRoom())
                {
                    conversion_cell.Type = VirtualCell.CellType.Fake3D_Room_WallFront;

//					// Also, we add this to make sure the doors work correctly
//					if (below_cell.IsDoor()){
//						conversion_cell.AddCellInstance(VirtualCell.CellType.DoorHorizontalTop,below_cell.Orientation);
//					}
                }
                else
                {
                    conversion_cell.Type = VirtualCell.CellType.Fake3D_Corridor_WallFront;
                }
            }

            conversion_cell.Orientation = VirtualMap.DirectionType.West;             // Force orientation
        }
        else if (conversion_cell.IsDoor())
        {
            if (conversion_cell.IsHorizontal())
            {
                conversion_cell.Type = VirtualCell.CellType.DoorHorizontalBottom;
            }
            else
            {
                conversion_cell.Type = VirtualCell.CellType.DoorVertical;
            }
        }
    }
    /********************
    * Door creation
    ********************/
    public void CreateDoors(VirtualMap map, VirtualRoom r, RoomGenerator roomGenerator)
    {
        // Create a list of border floors (close to the borders of the room)
        List <CellLocation> borderFloors = new List <CellLocation>();

        for (int i = 0; i < r.Width; i++)
        {
            for (int j = 0; j < r.Height; j++)
            {
                if (i == 0 || j == 0 || i == r.Width - 1 || j == r.Height - 1)
                {
                    CellLocation l = new CellLocation(r.leftCorner.x + 2 * i, r.leftCorner.y + 2 * j);
                    borderFloors.Add(l);
                }
            }
        }

        // For each border floor, check if we are connecting to something on the other side
        List <CellLocation>             outsideBorderFloors = new List <CellLocation>();
        List <CellLocation>             insideBorderFloors  = new List <CellLocation>();
        List <VirtualMap.DirectionType> borderDirections    = new List <VirtualMap.DirectionType>();

        CellLocation target_passage;
        CellLocation target_floor;

        foreach (CellLocation l in borderFloors)
        {
            foreach (VirtualMap.DirectionType dir in map.directions)
            {
                target_passage = map.GetNeighbourCellLocation(l, dir);
                target_floor   = map.GetTargetLocation(l, dir);
                if (!map.LocationIsOutsideBounds(target_floor) &&
                    map.GetCell(target_passage).IsWall() &&
                    !map.IsSurroundedByWalls(target_floor))
                {
                    outsideBorderFloors.Add(target_floor);
                    insideBorderFloors.Add(l);
                    borderDirections.Add(dir);
                }
            }
        }

        // We now create a door for each outside border floor, making sure to avoid re-creating doors if the floors are already connected
        List <CellLocation> unremovedFloors = new List <CellLocation>(outsideBorderFloors);

        for (int i = 0; i < outsideBorderFloors.Count; i++)
        {
            CellLocation l = outsideBorderFloors[i];
            // If not already removed (but we may not skip if we request more doors than needed)
            if (unremovedFloors.Contains(l) || DungeonGenerator.Random.Instance.Next(0, 100) < doorsDensityModifier)
            {
                CreateDoor(map, r, roomGenerator, insideBorderFloors[i], l, borderDirections[i]);
                unremovedFloors.Remove(l);

                // We also remove the other connected cells
                for (int j = unremovedFloors.Count - 1; j >= 0; j--)
                {
                    CellLocation other_l    = unremovedFloors[j];
                    bool         existsPath = map.ExistsPathBetweenLocations(l, other_l);
                    if (existsPath)
                    {
                        unremovedFloors.Remove(other_l);
                    }
                }
            }
        }
    }
    public void ConvertDirectionalCorridorFloor(VirtualMap map, VirtualCell conversion_cell)
    {
        CellLocation l = conversion_cell.location;

        if (behaviour.useDirectionalFloors)
        {
            if (conversion_cell.IsCorridorFloor())
            {
                // Count how many border neighbours are non-walls
                int    countFloorNeighs = 0;
                bool[] validIndices     = new bool[4];

                if (conversion_cell.IsTile())
                {
                    // This was a tile, check neigh walls
                    CellLocation[] border_neighs = map.GetAllNeighbours(l);
                    for (int i = 0; i < border_neighs.Length; i++)
                    {
                        CellLocation other_l = border_neighs[i];
                        if (!map.LocationIsOutsideBounds(other_l) && other_l.isValid() && !(map.GetCell(other_l).IsWall()))                             // TODO: Maybe isValid is not needed!
                        {
                            countFloorNeighs++;
                            validIndices[i] = true;
                        }
                    }
                }
                else
                {
                    // This was a border, check neigh floors instead
                    CellLocation[] floor_neighs = map.GetAllNeighbours(l);
                    for (int i = 0; i < floor_neighs.Length; i++)
                    {
                        CellLocation other_l = floor_neighs[i];
                        if (!map.LocationIsOutsideBounds(other_l) && other_l.isValid() && map.GetCell(other_l).IsFloor())                                       // TODO: Maybe isValid is not needed!
                        {
                            countFloorNeighs++;
                            validIndices[i] = true;
                        }
                    }
                }

                // Define the adbvanced floors
                if (countFloorNeighs == 1)
                {
                    conversion_cell.Type = VirtualCell.CellType.CorridorFloorU;
                    for (int i = 0; i < 4; i++)
                    {
                        if (validIndices[i])
                        {
                            conversion_cell.Orientation = map.directions[(int)Mathf.Repeat(i + 3, 4)];
                            break;
                        }
                    }
                }
                else if (countFloorNeighs == 2)
                {
                    // Corridor I
                    conversion_cell.Type = VirtualCell.CellType.CorridorFloorI;
                    for (int i = 0; i < 4; i++)
                    {
                        if (validIndices[i])
                        {
                            conversion_cell.Orientation = map.directions[(int)Mathf.Repeat(i + 1, 4)];
                            break;
                        }
                    }

                    // Corridor L
                    for (int i = 0; i < 4; i++)
                    {
                        if (validIndices[i] && validIndices[(int)Mathf.Repeat(i + 1, 4)])
                        {
                            // This and the next are valid: left turn (we consider all of them to be left turns(
                            conversion_cell.Orientation = map.directions[(int)Mathf.Repeat(i + 3, 4)];
                            conversion_cell.Type        = VirtualCell.CellType.CorridorFloorL;
                            break;
                        }
                    }
                }
                else if (countFloorNeighs == 3)
                {
                    conversion_cell.Type = VirtualCell.CellType.CorridorFloorT;
                    for (int i = 0; i < 4; i++)
                    {
                        if (validIndices[(int)Mathf.Repeat(i - 1, 4)] && validIndices[i] && validIndices[(int)Mathf.Repeat(i + 1, 4)])
                        {
                            // This, the one before and the next are valid: T cross (with this being the middle road)
                            conversion_cell.Orientation = map.directions[(int)Mathf.Repeat(i + 1, 4)];
                            break;
                        }
                    }
                }
                else if (countFloorNeighs == 4)
                {
                    conversion_cell.Type = VirtualCell.CellType.CorridorFloorX;
                }
            }
        }
    }
    protected void AddStairsToRooms(VirtualMap currentMap, VirtualMap[] maps, int storey)
    {
        if (storey == 0)
        {
            return;                      // Do not add at the first one! We'll add stairs from top to bottom.
        }
        bool allowStairsCloseToDoors = false;

//		Debug.Log ("CHECKING STAIRS FOR STOREY " + storey);
        // Stairs are added if we have two consecutive floors both at storey i and i+1
        foreach (CellLocation l in currentMap.roomCells)
        {
            VirtualCell cell_here = currentMap.GetCell(l);

            if (cell_here.location == currentMap.end || cell_here.location == currentMap.start)
            {
                continue;                                                                                               // Not on the start/end cells
            }
            foreach (VirtualMap.DirectionType direction in currentMap.directions)
            {
                CellLocation next_l = currentMap.GetNeighbourCellLocationAtStep(l, direction, this.TileSeparationSteps);
                if (currentMap.LocationIsOutsideBounds(next_l))
                {
                    continue;
                }
                if (next_l == currentMap.end || next_l == currentMap.start)
                {
                    continue;                                                                           // Not on the start/end cells
                }
                VirtualCell cell_next = currentMap.GetCell(next_l);
//				Debug.Log ("Cell here: " + cell_here.starting_location + " is " + cell_here.Type + " and next: " + cell_next.starting_location + " is " + cell_next.Type);

                if (VirtualCell.IsRoomFloor(cell_here.Type) && VirtualCell.IsRoomFloor(cell_next.Type))
                {
                    if (!currentMap.CellsAreInTheSameRoom(cell_here.location, cell_next.location))
                    {
                        continue;
                    }
                    // Two consecutive floors! Check the below map as well
//				    Debug.Log ("DOUBLE FLOORS! " + storey);
                    if (!allowStairsCloseToDoors && (currentMap.HasAdjacentDoor(cell_here.location) || currentMap.HasAdjacentDoor(cell_next.location)))
                    {
                        continue;
                    }

                    VirtualMap belowMap = maps[storey - 1];
                    if (belowMap.GetCell(l).IsRoomFloor() && belowMap.GetCell(next_l).IsRoomFloor())
                    {
                        if (l == belowMap.end || l == belowMap.start)
                        {
                            continue;                                                                   // Not on the start/end cells
                        }
                        if (next_l == belowMap.end || next_l == belowMap.start)
                        {
                            continue;                                                                                   // Not on the start/end cells
                        }
                        if (!belowMap.CellsAreInTheSameRoom(cell_here.location, cell_next.location))
                        {
                            continue;
                        }
                        // Also below! This is a two-tile stair! Update the map!

                        if (!allowStairsCloseToDoors && (currentMap.HasAdjacentDoor(cell_here.location) || currentMap.HasAdjacentDoor(cell_next.location)))
                        {
                            continue;
                        }

                        // We place the stair below
                        belowMap.GetCell(l).AddCellInstance(VirtualCell.CellType.Ladder2, direction);

                        // We remove any ceiling below
                        belowMap.GetCell(l).RemoveCellInstancesOfTypesInSelection(SelectionObjectType.Ceilings);
                        belowMap.GetCell(next_l).RemoveCellInstancesOfTypesInSelection(SelectionObjectType.Ceilings);

                        // We override the current map by removing its floors
                        currentMap.GetCell(l).RemoveCellInstancesOfTypesInSelection(SelectionObjectType.Floors);
                        currentMap.GetCell(next_l).RemoveCellInstancesOfTypesInSelection(SelectionObjectType.Floors);

                        nStairs++;
                        if (nStairs > 0)
                        {
                            return;                                      // At most one stair
                        }
                    }
                }
            }
        }
    }
    public void ConvertDirectionalRoomFloor(VirtualMap map, VirtualCell conversion_cell)
    {
        CellLocation l = conversion_cell.location;

        if (behaviour.useDirectionalFloors)
        {
            if (conversion_cell.IsRoomFloor())
            {
                CellLocation[] border_neighs;
                CellLocation[] floor_neighs;

                bool considerDoorsAsWalls = true;

                // Count how many border neighbours are non-walls
                int    countFloorNeighs = 0;
                bool[] validIndices     = new bool[4];

                if (conversion_cell.IsTile())
                {
                    // This was a tile, check neigh walls
                    border_neighs = map.GetAllNeighbours(l);
                    for (int i = 0; i < border_neighs.Length; i++)
                    {
                        CellLocation other_l = border_neighs[i];
                        if (!map.LocationIsOutsideBounds(other_l) && other_l.isValid() &&
                            !(map.GetCell(other_l).IsWall()) &&
                            !(considerDoorsAsWalls && map.GetCell(other_l).IsDoor())
                            )
                        {
                            countFloorNeighs++;
                            validIndices[i] = true;
                        }
                    }
                }
                else
                {
                    // This was a border, check neigh floors instead
                    floor_neighs = map.GetAllNeighbours(l);
                    //					Debug.Log ("From " + l);None

                    for (int i = 0; i < floor_neighs.Length; i++)
                    {
                        CellLocation other_l = floor_neighs[i];
                        //						Debug.Log ("At " + other_l + " is " + map.GetCell(other_l).Type);
                        bool insideRoomTile = CheckInsideRoomTile(map, other_l);                        // We need this to be checked now, or we cannot know if a tile is inside a room reliably
                        if (!map.LocationIsOutsideBounds(other_l) && other_l.isValid() &&
                            (map.GetCell(other_l).IsFloor() ||                       //|| map.GetCell(other_l).IsNone()
                             map.GetCell(other_l).IsInsideRoomColumn() ||                       // Treat inside room columns as floors here
                             insideRoomTile
//						 || map.GetCell(other_l).IsNone()
                            ))
                        {
                            countFloorNeighs++;
                            validIndices[i] = true;
                        }
                    }
                }


                // Define the adbvanced floors
                //	Debug.Log (countFloorNeighs);
                if (countFloorNeighs == 2)
                {
                    bool adjacentFloors = false;

                    // This is a room corner
                    for (int i = 0; i < 4; i++)
                    {
                        if (validIndices[i] && validIndices[(int)Mathf.Repeat(i + 1, 4)])
                        {
                            conversion_cell.Orientation = map.directions[(int)Mathf.Repeat(i + 3, 4)];
                            adjacentFloors = true;
                            break;
                        }
                    }

                    if (adjacentFloors)
                    {
                        conversion_cell.Type = VirtualCell.CellType.RoomFloorCorner;
                    }
                    else
                    {
                        conversion_cell.Type = VirtualCell.CellType.RoomFloorInside;
                    }
                }
                else if (countFloorNeighs == 3)
                {
                    conversion_cell.Type = VirtualCell.CellType.RoomFloorBorder;
                    for (int i = 0; i < 4; i++)
                    {
                        if (validIndices[(int)Mathf.Repeat(i - 1, 4)] && validIndices[i] && validIndices[(int)Mathf.Repeat(i + 1, 4)])
                        {
                            conversion_cell.Orientation = map.directions[(int)Mathf.Repeat(i + 2, 4)];
                            break;
                        }
                    }
                }
                else if (countFloorNeighs == 4)
                {
                    conversion_cell.Type = VirtualCell.CellType.RoomFloorInside;
                }
                else
                {
                    // Wrong number of floor neighs, may happen if we have too small rooms. We always use the INSIDE one, then.
                    conversion_cell.Type = VirtualCell.CellType.RoomFloorInside;
                }
            }
        }
    }
    public void ConvertDirectionalCorridorColumn(VirtualMap map, VirtualCell conversion_cell)
    {
        CellLocation l = conversion_cell.location;

        if (behaviour.useDirectionalFloors)
        {
            // Count how many border neighbours are walls
            int    countWallNeighs = 0;
            bool[] validIndices    = new bool[4];

            // This was a 'tile', check neigh walls
            CellLocation[] border_neighs = map.GetAllNeighbours(l);
            for (int i = 0; i < border_neighs.Length; i++)
            {
                CellLocation other_l = border_neighs[i];
                if (!map.LocationIsOutsideBounds(other_l) // && other_l.isValid()
                    )                                     // TODO: Maybe isValid is not needed!
                {
                    VirtualCell other_cell = map.GetCell(other_l);
                    if (other_cell.IsWall() && !map.IsPassageRemovable(other_cell.location))
                    {
                        countWallNeighs++;
                        validIndices[i] = true;
                    }
                }
            }

            // Define the advanced tile to use
            // TODO: merge this with the one for directional floors somehow!
            if (countWallNeighs == 0)
            {
                conversion_cell.Type = VirtualCell.CellType.CorridorWallO;
            }
            else if (countWallNeighs == 1)
            {
                conversion_cell.Type = VirtualCell.CellType.CorridorWallU;
                for (int i = 0; i < 4; i++)
                {
                    if (validIndices[i])
                    {
                        conversion_cell.Orientation = map.directions[(int)Mathf.Repeat(i + 3, 4)];
                        break;
                    }
                }
            }
            else if (countWallNeighs == 2)
            {
                // Corridor I
                conversion_cell.Type = VirtualCell.CellType.CorridorWallI;
                for (int i = 0; i < 4; i++)
                {
                    if (validIndices[i])
                    {
                        conversion_cell.Orientation = map.directions[(int)Mathf.Repeat(i + 1, 4)];
                        break;
                    }
                }

                // Corridor L
                for (int i = 0; i < 4; i++)
                {
                    if (validIndices[i] && validIndices[(int)Mathf.Repeat(i + 1, 4)])
                    {
                        // This and the next are valid: left turn (we consider all of them to be left turns(
                        conversion_cell.Orientation = map.directions[(int)Mathf.Repeat(i + 3, 4)];
                        conversion_cell.Type        = VirtualCell.CellType.CorridorWallL;
                        break;
                    }
                }
            }
            else if (countWallNeighs == 3)
            {
                conversion_cell.Type = VirtualCell.CellType.CorridorWallT;
                for (int i = 0; i < 4; i++)
                {
                    if (validIndices[(int)Mathf.Repeat(i - 1, 4)] && validIndices[i] && validIndices[(int)Mathf.Repeat(i + 1, 4)])
                    {
                        // This, the one before and the next are valid: T cross (with this being the middle road)
                        conversion_cell.Orientation = map.directions[(int)Mathf.Repeat(i + 1, 4)];
                        break;
                    }
                }
            }
            else if (countWallNeighs == 4)
            {
                conversion_cell.Type = VirtualCell.CellType.CorridorWallX;
            }
        }
    }