Beispiel #1
0
 protected static void ApplyGenSteps(T map, StablePriorityQueue <Priority, IGenStep> queue)
 {
     while (queue.Count > 0)
     {
         IGenStep postProc = queue.Dequeue();
         GenContextDebug.StepIn(postProc.ToString());
         postProc.Apply(map);
         GenContextDebug.StepOut();
     }
 }
Beispiel #2
0
        public void DrawOnMap(ITiledGenContext map)
        {
            GenContextDebug.StepIn("Main Rooms");
            for (int ii = 0; ii < this.Rooms.Count; ii++)
            {
                // take in the broad fulfillables from adjacent rooms that have not yet drawn
                IFloorRoomPlan plan = this.Rooms[ii];
                foreach (RoomHallIndex adj in plan.Adjacents)
                {
                    if (adj.IsHall || adj.Index > ii)
                    {
                        IRoomGen adjacentGen = this.GetRoomHall(adj).RoomGen;
                        plan.RoomGen.ReceiveFulfillableBorder(adjacentGen, GetDirAdjacent(plan.RoomGen, adjacentGen));
                    }
                }

                plan.RoomGen.DrawOnMap(map);
                this.TransferBorderToAdjacents(new RoomHallIndex(ii, false));
                GenContextDebug.DebugProgress("Draw Room");
            }

            GenContextDebug.StepOut();

            GenContextDebug.StepIn("Connecting Halls");
            for (int ii = 0; ii < this.Halls.Count; ii++)
            {
                // take in the broad fulfillables from adjacent rooms that have not yet drawn
                IFloorRoomPlan plan = this.Halls[ii];
                foreach (RoomHallIndex adj in plan.Adjacents)
                {
                    if (adj.IsHall && adj.Index > ii)
                    {
                        IRoomGen adjacentGen = this.GetRoomHall(adj).RoomGen;
                        plan.RoomGen.ReceiveFulfillableBorder(adjacentGen, GetDirAdjacent(plan.RoomGen, adjacentGen));
                    }
                }

                plan.RoomGen.DrawOnMap(map);
                this.TransferBorderToAdjacents(new RoomHallIndex(ii, true));
                GenContextDebug.DebugProgress("Draw Hall");
            }

            GenContextDebug.StepOut();
        }
Beispiel #3
0
        public override void ApplyToPath(IRandom rand, GridPlan floorPlan)
        {
            if (floorPlan.GridWidth < 3 || floorPlan.GridHeight < 3)
            {
                throw new InvalidOperationException("Not enough room to create path.");
            }

            int maxRooms = (2 * floorPlan.GridWidth) + (2 * floorPlan.GridHeight) - 4;
            int roomOpen = maxRooms * this.CircleRoomRatio.Pick(rand) / 100;
            int paths    = this.Paths.Pick(rand);

            if (roomOpen < 1 && paths < 1)
            {
                roomOpen = 1;
            }

            GenContextDebug.StepIn("Outer Circle");

            // draw the top and bottom
            for (int xx = 0; xx < floorPlan.GridWidth; xx++)
            {
                this.RollOpenRoom(rand, floorPlan, new Loc(xx, 0), ref roomOpen, ref maxRooms);
                GenContextDebug.DebugProgress("Room");
                this.RollOpenRoom(rand, floorPlan, new Loc(xx, floorPlan.GridHeight - 1), ref roomOpen, ref maxRooms);
                GenContextDebug.DebugProgress("Room");
                if (xx > 0)
                {
                    floorPlan.SetHall(new LocRay4(new Loc(xx, 0), Dir4.Left), this.GenericHalls.Pick(rand), this.HallComponents.Clone());
                    GenContextDebug.DebugProgress("Hall");
                    floorPlan.SetHall(new LocRay4(new Loc(xx, floorPlan.GridHeight - 1), Dir4.Left), this.GenericHalls.Pick(rand), this.HallComponents.Clone());
                    GenContextDebug.DebugProgress("Hall");
                }
            }

            // draw the left and right (excluding the top and bottom)
            for (int yy = 0; yy < floorPlan.GridHeight; yy++)
            {
                // exclude the top and bottom
                if (yy > 0 && yy < floorPlan.GridHeight - 1)
                {
                    this.RollOpenRoom(rand, floorPlan, new Loc(0, yy), ref roomOpen, ref maxRooms);
                    GenContextDebug.DebugProgress("Room");
                    this.RollOpenRoom(rand, floorPlan, new Loc(floorPlan.GridWidth - 1, yy), ref roomOpen, ref maxRooms);
                    GenContextDebug.DebugProgress("Room");
                }

                if (yy > 0)
                {
                    floorPlan.SetHall(new LocRay4(new Loc(0, yy), Dir4.Up), this.GenericHalls.Pick(rand), this.HallComponents.Clone());
                    GenContextDebug.DebugProgress("Hall");
                    floorPlan.SetHall(new LocRay4(new Loc(floorPlan.GridWidth - 1, yy), Dir4.Up), this.GenericHalls.Pick(rand), this.HallComponents.Clone());
                    GenContextDebug.DebugProgress("Hall");
                }
            }

            GenContextDebug.StepOut();

            GenContextDebug.StepIn("Inner Paths");

            Rect innerRect = new Rect(1, 1, floorPlan.GridWidth - 2, floorPlan.GridHeight - 2);

            // create inner paths
            for (int pathsMade = 0; pathsMade < paths; pathsMade++)
            {
                GenContextDebug.StepIn($"Path {pathsMade}");

                Dir4 startDir = DirExt.VALID_DIR4.ElementAt(rand.Next(DirExt.DIR4_COUNT));
                int  x        = rand.Next(innerRect.Start.X, innerRect.End.X);
                int  y        = rand.Next(innerRect.Start.Y, innerRect.End.Y);
                switch (startDir)
                {
                case Dir4.Down:
                    y = 0;
                    break;

                case Dir4.Left:
                    x = floorPlan.GridWidth - 1;
                    break;

                case Dir4.Up:
                    y = floorPlan.GridHeight - 1;
                    break;

                case Dir4.Right:
                    x = 0;
                    break;

                case Dir4.None:
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(startDir), "Invalid enum value.");
                }

                Loc  wanderer   = new Loc(x, y);
                Dir4 prevDir    = Dir4.None; // direction of movement
                int  pathLength = (startDir.ToAxis() == Axis4.Vert) ? innerRect.Height : innerRect.Width;
                for (int currentLength = 0; currentLength < pathLength; currentLength++)
                {
                    Dir4 chosenDir = startDir;

                    // avoid this block the first time
                    if (currentLength > 0)
                    {
                        List <Dir4> dirs = new List <Dir4>();
                        foreach (Dir4 dir in DirExt.VALID_DIR4)
                        {
                            // do not backtrack
                            if (dir == prevDir)
                            {
                                continue;
                            }

                            // do not hit edge
                            if (!Collision.InBounds(innerRect, wanderer + dir.GetLoc()))
                            {
                                continue;
                            }
                            dirs.Add(dir);
                        }

                        chosenDir = dirs[rand.Next(dirs.Count)];
                    }

                    Loc dest = wanderer + chosenDir.GetLoc();

                    GridRoomPlan existingRoom = floorPlan.GetRoomPlan(dest);
                    if (existingRoom == null)
                    {
                        if (currentLength == pathLength - 1) // only the end room can be a non-hall
                        {
                            floorPlan.AddRoom(dest, this.GenericRooms.Pick(rand), this.RoomComponents.Clone());
                        }
                        else
                        {
                            floorPlan.AddRoom(dest, this.GetDefaultGen(), this.HallComponents.Clone(), true);
                        }
                        GenContextDebug.DebugProgress("Room");
                    }
                    else if (existingRoom.PreferHall)
                    {
                        if (currentLength == pathLength - 1)
                        {
                            // override the hall room
                            existingRoom.RoomGen    = this.GenericRooms.Pick(rand).Copy();
                            existingRoom.PreferHall = false;
                        }
                    }

                    floorPlan.SetHall(new LocRay4(wanderer, chosenDir), this.GenericHalls.Pick(rand), this.HallComponents.Clone());
                    GenContextDebug.DebugProgress("Hall");

                    wanderer = dest;
                    prevDir  = chosenDir.Reverse();
                }

                GenContextDebug.StepOut();
            }

            GenContextDebug.StepOut();
        }
Beispiel #4
0
        /// <summary>
        /// Generates the position and size of each room and hall, and places it in the specified IFloorPlanGenContext.
        /// </summary>
        /// <param name="map"></param>
        public void PlaceRoomsOnFloor(IFloorPlanGenContext map)
        {
            // decide on room sizes
            for (int ii = 0; ii < this.ArrayRooms.Count; ii++)
            {
                this.ChooseRoomBounds(map.Rand, ii);
            }

            // decide on halls; write to RoomSideReqs
            for (int xx = 0; xx < this.VHalls.Length; xx++)
            {
                for (int yy = 0; yy < this.VHalls[xx].Length; yy++)
                {
                    this.ChooseHallBounds(map.Rand, xx, yy, true);
                }
            }

            for (int xx = 0; xx < this.HHalls.Length; xx++)
            {
                for (int yy = 0; yy < this.HHalls[xx].Length; yy++)
                {
                    this.ChooseHallBounds(map.Rand, xx, yy, false);
                }
            }

            GenContextDebug.StepIn("Main Rooms");

            List <RoomHallIndex> roomToHall = new List <RoomHallIndex>();

            foreach (var plan in this.ArrayRooms)
            {
                if (plan.PreferHall)
                {
                    roomToHall.Add(new RoomHallIndex(map.RoomPlan.HallCount, true));
                    map.RoomPlan.AddHall((IPermissiveRoomGen)plan.RoomGen, plan.Components);
                    GenContextDebug.DebugProgress("Add Hall Room");
                }
                else
                {
                    roomToHall.Add(new RoomHallIndex(map.RoomPlan.RoomCount, false));
                    map.RoomPlan.AddRoom(plan.RoomGen, plan.Components);
                    GenContextDebug.DebugProgress("Added Room");
                }
            }

            GenContextDebug.StepOut();

            GenContextDebug.StepIn("Connecting Halls");

            for (int xx = 0; xx < this.VHalls.Length; xx++)
            {
                for (int yy = 0; yy < this.VHalls[xx].Length; yy++)
                {
                    GridHallGroup hallGroup = this.VHalls[xx][yy];
                    for (int ii = 0; ii < hallGroup.HallParts.Count; ii++)
                    {
                        List <RoomHallIndex> adj = new List <RoomHallIndex>();
                        if (ii == 0)
                        {
                            int upRoom = this.Rooms[xx][yy];
                            if (upRoom > -1)
                            {
                                adj.Add(roomToHall[upRoom]);
                            }
                        }
                        else
                        {
                            adj.Add(new RoomHallIndex(map.RoomPlan.HallCount - 1, true));
                        }

                        if (ii == hallGroup.HallParts.Count - 1)
                        {
                            int downRoom = this.Rooms[xx][yy + 1];
                            if (downRoom > -1)
                            {
                                adj.Add(roomToHall[downRoom]);
                            }
                        }

                        map.RoomPlan.AddHall(hallGroup.HallParts[ii].RoomGen, hallGroup.HallParts[ii].Components, adj.ToArray());
                        GenContextDebug.DebugProgress("Add Hall");
                    }
                }
            }

            for (int xx = 0; xx < this.HHalls.Length; xx++)
            {
                for (int yy = 0; yy < this.HHalls[xx].Length; yy++)
                {
                    GridHallGroup hallGroup = this.HHalls[xx][yy];

                    for (int ii = 0; ii < hallGroup.HallParts.Count; ii++)
                    {
                        List <RoomHallIndex> adj = new List <RoomHallIndex>();
                        if (ii == 0)
                        {
                            int leftRoom = this.Rooms[xx][yy];
                            if (leftRoom > -1)
                            {
                                adj.Add(roomToHall[leftRoom]);
                            }
                        }
                        else
                        {
                            adj.Add(new RoomHallIndex(map.RoomPlan.HallCount - 1, true));
                        }

                        if (ii == hallGroup.HallParts.Count - 1)
                        {
                            int rightRoom = this.Rooms[xx + 1][yy];
                            if (rightRoom > -1)
                            {
                                adj.Add(roomToHall[rightRoom]);
                            }
                        }

                        map.RoomPlan.AddHall(hallGroup.HallParts[ii].RoomGen, hallGroup.HallParts[ii].Components, adj.ToArray());
                        GenContextDebug.DebugProgress("Add Hall");
                    }
                }
            }

            GenContextDebug.StepOut();
        }
Beispiel #5
0
        public override void ApplyToPath(IRandom rand, GridPlan floorPlan)
        {
            if (floorPlan.GridWidth < 3 || floorPlan.GridHeight < 3)
            {
                throw new InvalidOperationException("Not enough room to create path.");
            }

            int roomMax  = (2 * (floorPlan.GridWidth - 2)) + (2 * (floorPlan.GridHeight - 2));
            int roomOpen = roomMax * this.RoomRatio / 100;

            if (roomOpen < 1)
            {
                roomOpen = 1;
            }

            GenContextDebug.StepIn("Inner Grid");

            // set hallrooms in middle of grid and open hallways between them
            for (int x = 1; x < floorPlan.GridWidth - 1; x++)
            {
                for (int y = 1; y < floorPlan.GridHeight - 1; y++)
                {
                    floorPlan.AddRoom(new Loc(x, y), this.GetDefaultGen(), false, true);

                    if (x > 1)
                    {
                        floorPlan.SetHall(new LocRay4(new Loc(x, y), Dir4.Left), this.GenericHalls.Pick(rand));
                    }
                    if (y > 1)
                    {
                        floorPlan.SetHall(new LocRay4(new Loc(x, y), Dir4.Up), this.GenericHalls.Pick(rand));
                    }

                    GenContextDebug.DebugProgress("Room");
                }
            }

            GenContextDebug.StepOut();

            GenContextDebug.StepIn("Outer Rooms");

            // open random rooms on all sides
            for (int x = 1; x < floorPlan.GridWidth - 1; x++)
            {
                if (RollRatio(rand, ref roomOpen, ref roomMax))
                {
                    floorPlan.AddRoom(new Loc(x, 0), this.GenericRooms.Pick(rand));
                    floorPlan.SetHall(new LocRay4(new Loc(x, 0), Dir4.Down), this.GenericHalls.Pick(rand));
                    GenContextDebug.DebugProgress("Room");
                }

                if (RollRatio(rand, ref roomOpen, ref roomMax))
                {
                    floorPlan.AddRoom(new Loc(x, floorPlan.GridHeight - 1), this.GenericRooms.Pick(rand));
                    floorPlan.SetHall(new LocRay4(new Loc(x, floorPlan.GridHeight - 1), Dir4.Up), this.GenericHalls.Pick(rand));
                    GenContextDebug.DebugProgress("Room");
                }
            }

            for (int y = 1; y < floorPlan.GridHeight - 1; y++)
            {
                if (RollRatio(rand, ref roomOpen, ref roomMax))
                {
                    floorPlan.AddRoom(new Loc(0, y), this.GenericRooms.Pick(rand));
                    floorPlan.SetHall(new LocRay4(new Loc(0, y), Dir4.Right), this.GenericHalls.Pick(rand));
                    GenContextDebug.DebugProgress("Room");
                }

                if (RollRatio(rand, ref roomOpen, ref roomMax))
                {
                    floorPlan.AddRoom(new Loc(floorPlan.GridWidth - 1, y), this.GenericRooms.Pick(rand));
                    floorPlan.SetHall(new LocRay4(new Loc(floorPlan.GridWidth - 1, y), Dir4.Left), this.GenericHalls.Pick(rand));
                    GenContextDebug.DebugProgress("Room");
                }
            }

            GenContextDebug.StepOut();

            GenContextDebug.StepIn("Extra Halls");

            // get all halls eligible to be opened
            List <Loc> hHallSites = new List <Loc>();
            List <Loc> vHallSites = new List <Loc>();

            for (int x = 1; x < floorPlan.GridWidth; x++)
            {
                if (floorPlan.GetRoomPlan(new Loc(x, 0)) != null || floorPlan.GetRoomPlan(new Loc(x - 1, 0)) != null)
                {
                    hHallSites.Add(new Loc(x, 0));
                }
                if (floorPlan.GetRoomPlan(new Loc(x, floorPlan.GridHeight - 1)) != null || floorPlan.GetRoomPlan(new Loc(x - 1, floorPlan.GridHeight - 1)) != null)
                {
                    hHallSites.Add(new Loc(x, floorPlan.GridHeight - 1));
                }
            }

            for (int y = 1; y < floorPlan.GridHeight; y++)
            {
                if (floorPlan.GetRoomPlan(new Loc(0, y)) != null || floorPlan.GetRoomPlan(new Loc(0, y - 1)) != null)
                {
                    vHallSites.Add(new Loc(0, y));
                }
                if (floorPlan.GetRoomPlan(new Loc(floorPlan.GridWidth - 1, y)) != null || floorPlan.GetRoomPlan(new Loc(floorPlan.GridWidth - 1, y - 1)) != null)
                {
                    vHallSites.Add(new Loc(floorPlan.GridWidth - 1, y));
                }
            }

            int halls       = hHallSites.Count + vHallSites.Count;
            int placedHalls = halls * this.HallRatio / 100;

            // place the halls
            for (int ii = 0; ii < hHallSites.Count; ii++)
            {
                if (rand.Next() % halls < placedHalls)
                {
                    SafeAddHall(new LocRay4(hHallSites[ii], Dir4.Left), floorPlan, this.GenericHalls.Pick(rand), this.GenericRooms.Pick(rand));
                    GenContextDebug.DebugProgress("Hall");
                    placedHalls--;
                }

                halls--;
            }

            for (int ii = 0; ii < vHallSites.Count; ii++)
            {
                if (rand.Next() % halls < placedHalls)
                {
                    SafeAddHall(new LocRay4(vHallSites[ii], Dir4.Up), floorPlan, this.GenericHalls.Pick(rand), this.GenericRooms.Pick(rand));
                    GenContextDebug.DebugProgress("Hall");
                    placedHalls--;
                }

                halls--;
            }

            GenContextDebug.StepOut();
        }
Beispiel #6
0
        public override void ApplyToPath(IRandom rand, GridPlan floorPlan)
        {
            // open rooms on both sides
            Loc gridSize = new Loc(floorPlan.GridWidth, floorPlan.GridHeight);
            int scalar   = gridSize.GetScalar(this.GapAxis);
            int orth     = gridSize.GetScalar(this.GapAxis.Orth());

            if (scalar < 2 || orth < 1)
            {
                throw new InvalidOperationException("Not enough room to create path.");
            }

            GenContextDebug.StepIn("Initial Rooms");

            for (int ii = 0; ii < orth; ii++)
            {
                // place the rooms at the edge
                floorPlan.AddRoom(this.GapAxis.CreateLoc(0, ii), this.GenericRooms.Pick(rand), this.RoomComponents.Clone());
                GenContextDebug.DebugProgress("Room");
                floorPlan.AddRoom(this.GapAxis.CreateLoc(scalar - 1, ii), this.GenericRooms.Pick(rand), this.RoomComponents.Clone());
                GenContextDebug.DebugProgress("Room");

                if (scalar > 2)
                {
                    // place hall rooms
                    Loc loc  = this.GapAxis.CreateLoc(1, ii);
                    Loc size = this.GapAxis.CreateLoc(scalar - 2, 1);
                    floorPlan.AddRoom(new Rect(loc, size), this.GetDefaultGen(), this.HallComponents.Clone(), true);
                    GenContextDebug.DebugProgress("Mid Room");
                }
            }

            GenContextDebug.StepOut();

            GenContextDebug.StepIn("Connecting Sides");

            // halls connecting two tiers of the same side
            bool[][] connections = new bool[orth - 1][];
            for (int ii = 0; ii < orth - 1; ii++)
            {
                connections[ii] = new bool[2];
            }

            // add crosses
            for (int ii = 0; ii < orth - 1; ii++)
            {
                if (rand.Next(2) == 0)
                {
                    connections[ii][0] = true;
                }
                else
                {
                    connections[ii][1] = true;
                }
            }

            // paint hallways
            for (int ii = 0; ii < orth; ii++)
            {
                // place the halls at the sides
                if (ii < orth - 1)
                {
                    if (connections[ii][0])
                    {
                        this.PlaceOrientedHall(this.GapAxis.Orth(), 0, ii, 1, floorPlan, this.GenericHalls.Pick(rand));
                        GenContextDebug.DebugProgress("Side Connection");
                    }

                    if (connections[ii][1])
                    {
                        this.PlaceOrientedHall(this.GapAxis.Orth(), scalar - 1, ii, 1, floorPlan, this.GenericHalls.Pick(rand));
                        GenContextDebug.DebugProgress("Side Connection");
                    }
                }

                // place halls to bridge the gap
                this.PlaceOrientedHall(this.GapAxis, 0, ii, 1, floorPlan, this.GenericHalls.Pick(rand));
                if (scalar > 2)
                {
                    this.PlaceOrientedHall(this.GapAxis, scalar - 1, ii, -1, floorPlan, this.GenericHalls.Pick(rand));
                }
                GenContextDebug.DebugProgress("Bridge");
            }

            GenContextDebug.StepOut();
        }