//////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> Excavate bend. </summary> /// /// <remarks> /// "Perpindicular" here refers to the coordinate perpindicular to the orientation of the two /// rooms. If the rooms are oriented vertically then perpindicular refers to the horizontal (x) /// coordinate wo that startPerpindicular is the starting column. If they're oriented vertically, /// startPerpindicular is the starting row. Parallel refers to the coordinate parallel to the /// orientation. Bend is always in the perpindicular coordinate. Unidirectional but named as /// though dir was vertical. Darrellp, 9/18/2011. /// </remarks> /// /// <param name="map"> The map to be excavated. </param> /// <param name="startColumn"> The start perpindicular. </param> /// <param name="endColumn"> The end perpindicular. </param> /// <param name="startRow"> The start parallel. </param> /// <param name="endRow"> The end parallel. </param> /// <param name="bend"> The bend coordinate. </param> /// <param name="groom"> The room being prepared for this corridor. </param> /// <param name="dir"> The direction the bend is supposed to run. </param> //////////////////////////////////////////////////////////////////////////////////////////////////// private static void ExcavateBend(IRoomsMap map, int startColumn, int endColumn, int startRow, int endRow, int bend, GenericRoom groom, Dir dir) { Dir otherDir = MapCoordinates.OtherDirection(dir); // Create corridor to the bend ExcavateCorridorRun(map, startColumn, startRow, bend, groom, dir); // Create the cross corridor at the bend ExcavateCorridorRun(map, bend, startColumn, endColumn, groom, otherDir); // Create the corridor from the bend to the destination ExcavateCorridorRun(map, endColumn, bend, endRow, groom, dir); }
//////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> Excavate between connected rooms in a grid connection. </summary> /// /// <remarks> Variables named from the perspective that dir is vertical Darrellp, 9/19/2011. </remarks> /// /// <param name="map"> The map to be excavated. </param> /// <param name="dir"> The direction the merge will take place in. </param> /// <param name="topEntrance"> The small coordinate entrance. </param> /// <param name="bottomEntrance"> The large coordinate entrance. </param> /// <param name="groom"> The room being prepared for this corridor. </param> //////////////////////////////////////////////////////////////////////////////////////////////////// private void CreateBend(IRoomsMap map, Dir dir, MapCoordinates topEntrance, MapCoordinates bottomEntrance, GenericRoom groom) { // locals Dir otherDir = MapCoordinates.OtherDirection(dir); int startRow = topEntrance[dir]; int endRow = bottomEntrance[dir]; int startColumn = topEntrance[otherDir]; int endColumn = bottomEntrance[otherDir]; // Determine bend location int bendRow = _rnd.Next(startRow + 1, endRow); // Excavate the bend between the two rooms ExcavateBend(map, startColumn, endColumn, startRow, endRow, bendRow, groom, dir); }
//////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> Merge two rooms. </summary> /// /// <remarks> Named as though dir was vertical. Darrellp, 9/22/2011. </remarks> /// /// <param name="topRoomsGridLocation"> The location of the top room in the grid. </param> /// <param name="dir"> The direction of the merge. </param> //////////////////////////////////////////////////////////////////////////////////////////////////// private void MergeTwoRooms(MapCoordinates topRoomsGridLocation, Dir dir) { // Get grid coordinates of the other room MapCoordinates bottomRoomsGridLocation = topRoomsGridLocation.NextLarger(dir); Dir otherDir = MapCoordinates.OtherDirection(dir); // Retrieve both rooms RectangularRoom topRoom = RoomAt(topRoomsGridLocation); RectangularRoom bottomRoom = RoomAt(bottomRoomsGridLocation); // Are the rooms unmergable? if (!CheckMergeForOverlap(topRoom, bottomRoom, otherDir)) { // Return and don't merge them - use normal corridors return; } // Remove their generic counterparts _mapRoomToGenericRooms.Remove(topRoom); _mapRoomToGenericRooms.Remove(bottomRoom); // Get their current coordinates, etc. int topRoomsBottom = topRoom.LargeCoord(dir); int topRoomsTop = topRoom.SmallCoord(dir); int bottomRoomsTop = bottomRoom.SmallCoord(dir); int bottomRoomsHeight = bottomRoom.Size(dir); int topRoomsWidth = topRoom.Size(otherDir); int bottomRoomsWidth = bottomRoom.Size(otherDir); // Pick a random spot between the rooms to merge them // This will be the new inside coord of the small coordinate room int mergeRow = _rnd.Next(topRoomsBottom, bottomRoomsTop); // Determine all the new coordinates int topRoomsNewHeight = mergeRow - topRoomsTop + 1; int bottomRoomsNewHeight = bottomRoomsTop - mergeRow + bottomRoomsHeight - 1; MapCoordinates bottomRoomsLocation = bottomRoom.Location; bottomRoomsLocation[dir] = mergeRow + 1; // Create our new expanded rooms RectangularRoom roomTopNew = RectangularRoom.CreateUndirectional( topRoom.Location, topRoomsNewHeight, topRoomsWidth, topRoomsGridLocation[dir], topRoomsGridLocation[otherDir], dir); RectangularRoom roomBottomNew = RectangularRoom.CreateUndirectional( bottomRoomsLocation, bottomRoomsNewHeight, bottomRoomsWidth, bottomRoomsGridLocation[dir], bottomRoomsGridLocation[otherDir], dir); // Install the new rooms SetRoomAt(topRoomsGridLocation, roomTopNew); SetRoomAt(bottomRoomsGridLocation, roomBottomNew); // Create the new generic rooms // We don't create the single merged generic room until we excavate because we don't know // the layout until then. _mapRoomToGenericRooms[roomTopNew] = roomTopNew.ToGeneric(); _mapRoomToGenericRooms[roomBottomNew] = roomBottomNew.ToGeneric(); // Mark this in our merges structure _merges.Connect(topRoomsGridLocation, bottomRoomsGridLocation); }
//////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> Excavate a merge between two rooms. </summary> /// /// <remarks> /// Names are named as though dir was vertical and dirOther horizontal. Darrellp, 9/22/2011. /// </remarks> /// /// <param name="map"> The map. </param> /// <param name="topRoom"> The top room. </param> /// <param name="bottomRoom"> The bottom room. </param> /// <param name="dir"> The dir. </param> //////////////////////////////////////////////////////////////////////////////////////////////////// private void ExcavateMerge(IRoomsMap map, RectangularRoom topRoom, RectangularRoom bottomRoom, Dir dir) { // Get the opposite direction Dir dirOther = MapCoordinates.OtherDirection(dir); // Are the rooms unmergable? if (!CheckOverlap(topRoom, bottomRoom, dirOther)) { // Should have caught this in MergeTwoRooms - throw exception throw new RogueException("Non-overlapping rooms made it to ExcavateMerge"); } // Get the appropriate coordinates int topRoomsLeft = topRoom.Location[dirOther]; int topRoomsRight = topRoomsLeft + topRoom.Size(dirOther) - 1; int bottomRoomsLeft = bottomRoom.Location[dirOther]; int bottomRoomsRight = bottomRoomsLeft + bottomRoom.Size(dirOther) - 1; // Get the high and low points of the overlap int overlapLeft = Math.Max(topRoomsLeft, bottomRoomsLeft) + 1; int overlapRight = Math.Min(topRoomsRight, bottomRoomsRight) - 1; // Create our new merged generic room GenericRoom groomTop = _mapRoomToGenericRooms[topRoom]; GenericRoom groomBottom = _mapRoomToGenericRooms[bottomRoom]; groomTop.CombineWith(groomBottom); // For each column in the grid foreach (RectangularRoom[] roomColumn in _rooms) { // For each row in the grid for (int iRow = 0; iRow < _rooms[0].Length; iRow++) { // Get the rect room at that spot RectangularRoom room = roomColumn[iRow]; // Is it mapped to our defunct bottom room? if (_mapRoomToGenericRooms[room] == groomBottom) { // Map it to our shiny new top room _mapRoomToGenericRooms[room] = groomTop; } } } // Get the location we're going to start the clearing at int topRoomsBottom = topRoom.Location[dir] + topRoom.Size(dir) - 1; MapCoordinates currentLocation = MapCoordinates.CreateUndirectional(topRoomsBottom, overlapLeft, dir); char floorChar = TerrainFactory.TerrainToChar(TerrainType.Floor); // For each spot along the overlap for (int iCol = overlapLeft; iCol <= overlapRight; iCol++) { // Clear out the two walls of the abutting rooms currentLocation[dirOther] = iCol; map[currentLocation].Terrain = TerrainType.Floor; groomTop[currentLocation] = floorChar; currentLocation[dir] = topRoomsBottom + 1; map[currentLocation].Terrain = TerrainType.Floor; groomTop[currentLocation] = floorChar; currentLocation[dir] = topRoomsBottom; } Debug.Assert(groomBottom == groomTop || !_mapRoomToGenericRooms.ContainsValue(groomBottom)); }