示例#1
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);
    }
    /********************
    * 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);
                    }
                }
            }
        }
    }