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