Пример #1
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>	Adds an exit to the room hooked to another generic room. </summary>
        ///
        /// <remarks>	Darrellp, 9/28/2011. </remarks>
        ///
        /// <param name="groom">	The room to be joined to this one. </param>
        /// <param name="location">	The location the exit to groom will be. </param>
        ///
        /// <returns>	The character allocated for the new exit. </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        internal char AddExit(GenericRoom groom, MapCoordinates location)
        {
            char exitChar = (char)('a' + Exits.Count);

            Exits.Add(groom);
            this[location]    = exitChar;
            ExitMap[location] = groom;
            return(exitChar);
        }
Пример #2
0
 private static void AssignTilesInRoom(IRoomsMap map, GenericRoom groom)
 {
     // Is this room being newly added to the map?
     if (map.Rooms.Add(groom))
     {
         // For each tile in the room
         foreach (var tileLocation in groom.Tiles)
         {
             // Assign the room to that tile
             map[tileLocation].Room = groom;
         }
     }
 }
Пример #3
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>	Updates the rooms connected to groom to point to us. </summary>
        ///
        /// <remarks>	Darrellp, 9/28/2011. </remarks>
        ///
        /// <param name="groom">	The room whose connected rooms are to be joined to this one. </param>
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        private void UpdateConnectedRoomsToPointToUs(GenericRoom groom)
        {
            // For each exit in the old room
            foreach (var exitInfo in groom.ExitMap)
            {
                // Get the room on the other side
                MapCoordinates location      = exitInfo.Key;
                GenericRoom    groomExitedTo = exitInfo.Value;
                int            indexToUs     = groomExitedTo[location] - 'a';

                // and point it back to us
                groomExitedTo.Exits[indexToUs] = this;
            }
        }
Пример #4
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>	Excavates between two rooms. </summary>
        ///
        /// <remarks>	Variables named from the perspective of dir being vertical.  Darrellp, 9/18/2011. </remarks>
        ///
        /// <param name="map">			The map to be excavated. </param>
        /// <param name="roomTop">		The first room. </param>
        /// <param name="roomBottom">	The second room. </param>
        /// <param name="dir">			The direction to excavate in. </param>
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        private void ExcavateCorridor(IRoomsMap map, RectangularRoom roomTop, RectangularRoom roomBottom, Dir dir)
        {
            // Locals
            MapCoordinates bottomEntrance, topEntrance;

            // Get the entrances to each room
            GetEntrances(roomTop, roomBottom, dir, out topEntrance, out bottomEntrance);

            // Allocate the generic room
            int             genericWidth    = Math.Abs(topEntrance.Column - bottomEntrance.Column) + 1;
            int             genericHeight   = Math.Abs(topEntrance.Row - bottomEntrance.Row) + 1;
            int             genericLeft     = Math.Min(topEntrance.Column, bottomEntrance.Column);
            int             genericBottom   = Math.Min(topEntrance.Row, bottomEntrance.Row);
            MapCoordinates  genericLocation = new MapCoordinates(genericLeft, genericBottom);
            GenericCorridor corridor        = new GenericCorridor(genericWidth, genericHeight, genericLocation);

            // Excavate a connection between the two rooms
            CreateBend(map, dir, topEntrance, bottomEntrance, corridor);

            // Put the exits in the appropriate generic rooms
            GenericRoom groomTop    = _mapRoomToGenericRooms[roomTop];
            GenericRoom groomBottom = _mapRoomToGenericRooms[roomBottom];

            corridor.AddExit(groomTop, topEntrance);
            corridor.AddExit(groomBottom, bottomEntrance);
            groomTop.AddExit(corridor, topEntrance);
            groomBottom.AddExit(corridor, bottomEntrance);


            // Should we put a door in the top room?
            if (_rnd.Next(100) < _pctDoorChance)
            {
                // Place the door
                map[topEntrance].Terrain = TerrainType.Door;
            }

            // Should we put a door in the bottom room?
            if (_rnd.Next(100) < _pctDoorChance)
            {
                // Place the door
                map[bottomEntrance].Terrain = TerrainType.Door;
            }
        }
Пример #5
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>	Combine two generic rooms </summary>
        ///
        /// <remarks>	Darrellp, 9/27/2011. </remarks>
        ///
        /// <param name="groom">	The room to be joined to this one. </param>
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        internal void CombineWith(GenericRoom groom)
        {
            // Clone into a temporary room
            GenericRoom roomTemp = new GenericRoom(Layout, Location, Exits);

            // Get the new and old locations, sizes
            int newLeft   = Math.Min(Left, groom.Left);
            int newRight  = Math.Max(Right, groom.Right);
            int newTop    = Math.Min(Top, groom.Top);
            int newBottom = Math.Max(Bottom, groom.Bottom);
            int newHeight = newBottom - newTop + 1;
            int newWidth  = newRight - newLeft + 1;

            // Set our new location
            Location = new MapCoordinates(newLeft, newTop);

            // Clear our exits
            // They'll come back in from the cloned room
            Exits = new List <GenericRoom>();

            // Allocate a new layout array
            Layout = new char[newWidth][];

            // For each column
            for (int iColumn = 0; iColumn < newWidth; iColumn++)
            {
                // Allocate the column
                Layout[iColumn] = new char[newHeight];
            }

            // Move the clone's data into ourself
            TransferTerrain(roomTemp);

            // Move the other room's data into ourself
            TransferTerrain(groom);

            // Update pointers for any rooms which connected to groom
            UpdateConnectedRoomsToPointToUs(groom);

            // Set up our exit map
            MapExitsToRooms();
        }
Пример #6
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>	Transfer terrain. </summary>
        ///
        /// <remarks>	This only affects the _layout field.  Darrellp, 9/27/2011. </remarks>
        ///
        /// <param name="groom">		The room to be joined to this one. </param>
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        private void TransferTerrain(GenericRoom groom)
        {
            // Locals
            int mapColumn;
            int localColumn;

            // For each original column
            for (localColumn = 0, mapColumn = groom.Left; localColumn < groom.Width; localColumn++, mapColumn++)
            {
                // More locals
                int mapRow;
                int localRow;

                // For each original row
                for (localRow = 0, mapRow = groom.Top; localRow < groom.Height; localRow++, mapRow++)
                {
                    // Get the terrain for this location
                    char character = groom.Layout[localColumn][localRow];

                    // Is this an exit?
                    if (character >= 'a' && character <= 'z')
                    {
                        // Add it to our list of exits
                        int         iRoom         = (char)(character - 'a');
                        GenericRoom groomExitedTo = groom.Exits[iRoom];
                        character = AddExit(groomExitedTo, new MapCoordinates(mapColumn, mapRow));
                    }

                    // Is it non-null?
                    if (character != '\0')
                    {
                        // Place the new terrain
                        this[mapColumn, mapRow] = character;
                    }
                }
            }
        }
Пример #7
0
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 /// <summary>	Adds a room to our room list. </summary>
 ///
 /// <remarks>	Darrellp, 10/6/2011. </remarks>
 ///
 /// <param name="groom">	The generic room to be added. </param>
 ///
 /// <returns>	true if the room has already been added, false if it hasn't. </returns>
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 public bool AddRoom(GenericRoom groom)
 {
     return(Rooms.Add(groom));
 }
Пример #8
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <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);
        }
Пример #9
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <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);
        }
Пример #10
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <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;
            }
        }
Пример #11
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <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));
        }