// 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);
    }
Exemple #2
0
    VirtualRoom CreateRoom(VirtualMap map, RoomGenerator roomGenerator, BSPTreeNode node, CellLocation starting_location)
    {
        // Get the maximum bounds
        BSPTreeNodeBounds bounds = node.areaBounds;
        int range_x = bounds.max_x - bounds.min_x;
        int range_y = bounds.max_y - bounds.min_y;

        // Cannot create a room if the area is empty!
        if (range_x == 0 || range_y == 0)
        {
            Debug.LogWarning("Room size too small to be created! " + range_x + "," + range_y);
            return(null);
        }

        // Choose a random size for the room
        int min_size_x = Mathf.Max(1, Mathf.FloorToInt(range_x * roomSizeMinRange));
        int max_size_x = Mathf.Max(1, Mathf.CeilToInt(range_x * roomSizeMaxRange));
        int min_size_y = Mathf.Max(1, Mathf.FloorToInt(range_y * roomSizeMinRange));
        int max_size_y = Mathf.Max(1, Mathf.CeilToInt(range_y * roomSizeMaxRange));

        // Compute size
        int size_x = DungeonGenerator.Random.Instance.Next(min_size_x, max_size_x);
        int size_y = DungeonGenerator.Random.Instance.Next(min_size_y, max_size_y);

        // Compute start
        int start_x, start_y;

        start_x = bounds.min_x + DungeonGenerator.Random.Instance.Next(range_x - size_x);
        start_y = bounds.min_y + DungeonGenerator.Random.Instance.Next(range_y - size_y);

        // If the starting location is inside these bounds, we must force it to create the room on it
        if (starting_location.isValid() && bounds.Contain(starting_location))
        {
            //Debug.Log("YES IN");
            int x = starting_location.x / 2;
            int y = starting_location.y / 2;

            //Debug.Log("Start bounds: " + (new BSPTreeNodeBounds(start_x, start_y, start_x + size_x, start_y + size_y)).ToString());

            // Make sure the start includes this, or decrease it
            if (x < start_x)
            {
                start_x = x;
            }
            if (y < start_y)
            {
                start_y = y;
            }

            //Debug.Log(y);
            //Debug.Log(start_y + size_y);

            // Make sure the end includes thid, or increase it
            if (x + 1 >= start_x + size_x)
            {
                size_x = x + 1 - start_x;
            }
            if (y + 1 >= start_y + size_y)
            {
                size_y = y + 1 - start_y;
            }

            //Debug.Log("End bounds: " + (new BSPTreeNodeBounds(start_x, start_y, start_x + size_x, start_y + size_y)).ToString());
        }

        //Debug.Log("MIN " + min_size_x + " MAX " + max_size_x + " SIZE " + size_x);

        //Debug.Log("SPACE " + " [" + node.areaBounds.min_x + "," + node.areaBounds.max_x + "] [" + node.areaBounds.min_y + "," + node.areaBounds.max_y + "]");

        //Debug.Log("delta_low " + delta_low + " delta_high " + delta_high);

        //Debug.Log("CREATING ROOM: " + start_x + " + " + size_x + "   ||   " + start_y + " + " + size_y);

        node.roomBounds = new BSPTreeNodeBounds(start_x, start_y, start_x + size_x, start_y + size_y);

        // Start and end must be converted to whole-map sizes (not just floors)
        start_x = start_x * 2 + 1;
        start_y = start_y * 2 + 1;

        return(roomGenerator.CreateRoom(map, size_x, size_y, start_x, start_y));
    }
    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 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;
                }
            }
        }
    }