public override void ApplyToPath(IRandom rand, GridPlan floorPlan) { // choose certain rooms in the list to be special rooms // special rooms are required; so make sure they don't overlap List <int> room_indices = new List <int>(); for (int ii = 0; ii < floorPlan.RoomCount; ii++) { GridRoomPlan plan = floorPlan.GetRoomPlan(ii); if (!plan.Immutable && !plan.CountsAsHall()) { room_indices.Add(ii); } } if (room_indices.Count > 0) { int ind = rand.Next(room_indices.Count); GridRoomPlan plan = floorPlan.GetRoomPlan(room_indices[ind]); plan.RoomGen = this.Rooms.Pick(rand).Copy(); plan.Immutable = true; room_indices.RemoveAt(ind); GenContextDebug.DebugProgress("Set Special Room"); } }
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)); GenContextDebug.DebugProgress("Hall"); floorPlan.SetHall(new LocRay4(new Loc(xx, floorPlan.GridHeight - 1), Dir4.Left), this.GenericHalls.Pick(rand)); 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)); GenContextDebug.DebugProgress("Hall"); floorPlan.SetHall(new LocRay4(new Loc(floorPlan.GridWidth - 1, yy), Dir4.Up), this.GenericHalls.Pick(rand)); 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)); } else { floorPlan.AddRoom(dest, this.GetDefaultGen(), false, true); } GenContextDebug.DebugProgress("Room"); } else if (existingRoom.CountsAsHall()) { 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)); GenContextDebug.DebugProgress("Hall"); wanderer = dest; prevDir = chosenDir.Reverse(); } GenContextDebug.StepOut(); } GenContextDebug.StepOut(); }