private void RollOpenRoom(IRandom rand, GridPlan floorPlan, Loc loc, ref int roomOpen, ref int maxRooms) { if (RollRatio(rand, ref roomOpen, ref maxRooms)) { floorPlan.AddRoom(loc, this.GenericRooms.Pick(rand), this.RoomComponents.Clone()); } else { floorPlan.AddRoom(loc, this.GetDefaultGen(), this.HallComponents.Clone(), true); } }
public static void SafeAddHall(LocRay4 locRay, GridPlan floorPlan, IPermissiveRoomGen hallGen, IRoomGen roomGen, bool preferHall = false) { floorPlan.SetHall(locRay, hallGen); if (floorPlan.GetRoomPlan(locRay.Loc) == null) { floorPlan.AddRoom(locRay.Loc, roomGen, false, preferHall); } Loc dest = locRay.Traverse(1); if (floorPlan.GetRoomPlan(dest) == null) { floorPlan.AddRoom(dest, roomGen, false, preferHall); } }
public static void SafeAddHall(LocRay4 locRay, GridPlan floorPlan, IPermissiveRoomGen hallGen, IRoomGen roomGen, ComponentCollection roomComponents, ComponentCollection hallComponents, bool preferHall = false) { floorPlan.SetHall(locRay, hallGen, hallComponents.Clone()); ComponentCollection collection = preferHall ? hallComponents : roomComponents; if (floorPlan.GetRoomPlan(locRay.Loc) == null) { floorPlan.AddRoom(locRay.Loc, roomGen, collection.Clone(), preferHall); } Loc dest = locRay.Traverse(1); if (floorPlan.GetRoomPlan(dest) == null) { floorPlan.AddRoom(dest, roomGen, collection.Clone(), preferHall); } }
protected bool ExpandPath(IRandom rand, GridPlan floorPlan, bool branch) { LocRay4 chosenRay = this.ChooseRoomExpansion(rand, floorPlan, branch); if (chosenRay.Dir == Dir4.None) { return(false); } floorPlan.SetHall(chosenRay, this.GenericHalls.Pick(rand)); floorPlan.AddRoom(chosenRay.Traverse(1), this.GenericRooms.Pick(rand)); GenContextDebug.DebugProgress(branch ? "Branched Path" : "Extended Path"); return(true); }
public override void ApplyToPath(IRandom rand, GridPlan floorPlan) { if (floorPlan.GridWidth != this.SpecificVHalls.Length || floorPlan.GridWidth - 1 != this.SpecificHHalls.Length || floorPlan.GridHeight - 1 != this.SpecificVHalls[0].Length || floorPlan.GridHeight != this.SpecificHHalls[0].Length) { throw new InvalidOperationException("Incorrect hall path sizes."); } foreach (var chosenRoom in this.SpecificRooms) { floorPlan.AddRoom(chosenRoom.Bounds, chosenRoom.RoomGen, chosenRoom.Components.Clone(), chosenRoom.PreferHall); GenContextDebug.DebugProgress("Room"); } // place halls for (int x = 0; x < this.SpecificVHalls.Length; x++) { for (int y = 0; y < this.SpecificHHalls[0].Length; y++) { if (x > 0) { if (this.SpecificHHalls[x - 1][y] != null) { UnsafeAddHall(new LocRay4(new Loc(x, y), Dir4.Left), floorPlan, this.SpecificHHalls[x - 1][y], this.HallComponents); } } if (y > 0) { if (this.SpecificVHalls[x][y - 1] != null) { UnsafeAddHall(new LocRay4(new Loc(x, y), Dir4.Up), floorPlan, this.SpecificVHalls[x][y - 1], this.HallComponents); } } } } }
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(); }
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(); }
public virtual void CreateErrorPath(IRandom rand, GridPlan floorPlan) { floorPlan.Clear(); floorPlan.AddRoom(new Loc(0, 0), this.GetDefaultGen()); }
public override void ApplyToPath(IRandom rand, GridPlan floorPlan) { for (int ii = 0; ii < 10; ii++) { // always clear before trying floorPlan.Clear(); int roomsToOpen = floorPlan.GridWidth * floorPlan.GridHeight * this.RoomRatio.Pick(rand) / 100; if (roomsToOpen < 1) { roomsToOpen = 1; } int addBranch = this.BranchRatio.Pick(rand); int roomsLeft = roomsToOpen; Loc sourceRoom = new Loc(rand.Next(floorPlan.GridWidth), rand.Next(floorPlan.GridHeight)); // randomly determine start room floorPlan.AddRoom(sourceRoom, this.GenericRooms.Pick(rand)); GenContextDebug.DebugProgress("Start Room"); roomsLeft--; int pendingBranch = 0; while (roomsLeft > 0) { bool terminalSuccess = this.ExpandPath(rand, floorPlan, false); bool branchSuccess = false; if (terminalSuccess) { roomsLeft--; if (floorPlan.RoomCount > 2) { pendingBranch += addBranch; } } else if (this.NoForcedBranches) { break; } else { pendingBranch = 100; } while (pendingBranch >= 100 && roomsLeft > 0) { branchSuccess = this.ExpandPath(rand, floorPlan, true); if (!branchSuccess) { break; } pendingBranch -= 100; roomsLeft--; } if (!terminalSuccess && !branchSuccess) { break; } } if (roomsLeft <= 0) { break; } } }
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(); }