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