// 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); } } } } }