public override string ToString() { // Initialize a stringbuilder StringBuilder sb = new StringBuilder(); // For each row of the map for (int iRow = 0; iRow < Height; iRow++) { // For each column of the map for (int iColumn = 0; iColumn < Width; iColumn++) { // Retrieve the data MapLocationData data = _mapLocationData[iColumn][iRow]; // Are there items here? if (data.Items.Count != 0) { // Draw the first item's character ItemInfo info = ItemInfo.GetItemInfo(data.Items[0]); sb.Append(info.Character); } else { // Draw the terrain character sb.Append(TerrainFactory.TerrainToChar(_mapLocationData[iColumn][iRow].Terrain)); } } // Write CRLF to advance to next line sb.Append("\r\n"); } return(sb.ToString()); }
//////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> Inserts a single read row into the map. </summary> /// /// <remarks> Darrellp, 9/16/2011. </remarks> /// /// <param name="map"> The map to modify. </param> /// <param name="currentLine"> The current line read from the stream. </param> /// <param name="iRow"> The row to modify. </param> //////////////////////////////////////////////////////////////////////////////////////////////////// private static void InsertRow(IMap map, string currentLine, int iRow) { // For each character in the read line for (int iCol = 0; iCol < Math.Min(map.Width, currentLine.Length); iCol++) { // Produce the data for that character TerrainType terrain = TerrainFactory.ProduceTerrain(currentLine[iCol]); Item item = ItemInfo.NewItemFromChar(currentLine[iCol]); List <Item> items = item == null ? null : new List <Item> { item }; MapLocationData data = new MapLocationData(terrain, items); // and place it in the map map[iCol, iRow] = data; } }
//////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> Converts this object to a generic room with no exits. </summary> /// /// <remarks> Darrellp, 9/26/2011. </remarks> /// /// <returns> This object as a GenericRoom. </returns> //////////////////////////////////////////////////////////////////////////////////////////////////// internal GenericRoom ToGeneric() { char[][] layout = new char[Width][]; char floorChar = TerrainFactory.TerrainToChar(TerrainType.Floor); for (int iColumn = 0; iColumn < Width; iColumn++) { layout[iColumn] = new char[Height]; for (int iRow = 0; iRow < Height; iRow++) { bool fBorder = iRow == 0 || iRow == Height - 1 || iColumn == 0 || iColumn == Width - 1; if (!fBorder) { layout[iColumn][iRow] = floorChar; } } } return(new GenericRoom(layout, Location, new List <GenericRoom>())); }
//////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> Excavate a straight corridor run either vertically or horizontally. </summary> /// /// <remarks> /// Excavates from (startParallel, perpindicular) to (endParallel, perpindicular) inclusive if /// fVertical. If not fVertical, swap coordinates. start and end parallel coordinates do not /// have to be in numerical order. This is a unidirectional function but, as usual, names are /// named as though dir was vertical. Darrellp, 9/19/2011. /// </remarks> /// /// <param name="map"> The map to be excavated. </param> /// <param name="column"> The perpindicular coordinate. </param> /// <param name="endRow1"> The starting parallel coordinate. </param> /// <param name="endRow2"> The ending parallel coordinate. </param> /// <param name="groom"> The room being prepared for this corridor. </param> /// <param name="dir"> The direction of the corridor. </param> //////////////////////////////////////////////////////////////////////////////////////////////////// private static void ExcavateCorridorRun(IRoomsMap map, int column, int endRow1, int endRow2, GenericRoom groom, Dir dir) { // We work with small and large coords rather than start and end int startRow = Math.Min(endRow1, endRow2); int endRow = Math.Max(endRow1, endRow2); char floorChar = TerrainFactory.TerrainToChar(TerrainType.Floor); // Create the starting location MapCoordinates currentLocation = MapCoordinates.CreateUndirectional(startRow, column, dir); // For each row in the run for (int iRow = startRow; iRow <= endRow; iRow++) { // Place our terrain currentLocation[dir] = iRow; map[currentLocation].Terrain = TerrainType.Floor; groom[currentLocation] = floorChar; } }
//////////////////////////////////////////////////////////////////////////////////////////////////// /// <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)); }