public static void UnsafeAddHall(LocRay4 locRay, GridPlan floorPlan, IPermissiveRoomGen hallGen, ComponentCollection components) { floorPlan.SetHall(locRay, hallGen, components.Clone()); GenContextDebug.DebugProgress("Hall"); if (floorPlan.GetRoomPlan(locRay.Loc) == null || floorPlan.GetRoomPlan(locRay.Traverse(1)) == null) { floorPlan.Clear(); throw new InvalidOperationException("Can't create a hall without rooms to connect!"); } }
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); } }
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 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); } }
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 override void ApplyToPath(IRandom rand, GridPlan floorPlan) { List <LocRay4> endBranches = new List <LocRay4>(); for (int ii = 0; ii < floorPlan.RoomCount; ii++) { GridRoomPlan roomPlan = floorPlan.GetRoomPlan(ii); if (!BaseRoomFilter.PassesAllFilters(roomPlan, this.Filters)) { continue; } if (roomPlan.Bounds.Size == new Loc(1)) { List <int> adjacents = floorPlan.GetAdjacentRooms(ii); if (adjacents.Count == 1) { endBranches.Add(new LocRay4(roomPlan.Bounds.Start)); } } } List <List <LocRay4> > candBranchPoints = new List <List <LocRay4> >(); for (int nn = 0; nn < endBranches.Count; nn++) { LocRay4 chosenBranch = endBranches[nn]; while (chosenBranch.Loc != new Loc(-1)) { List <LocRay4> connectors = new List <LocRay4>(); List <LocRay4> candBonds = new List <LocRay4>(); foreach (Dir4 dir in DirExt.VALID_DIR4) { if (dir != chosenBranch.Dir) { if (floorPlan.GetHall(new LocRay4(chosenBranch.Loc, dir)) != null) { connectors.Add(new LocRay4(chosenBranch.Loc, dir)); } else { Loc loc = chosenBranch.Loc + dir.GetLoc(); if (Collision.InBounds(floorPlan.GridWidth, floorPlan.GridHeight, loc) && floorPlan.GetRoomIndex(loc) > -1) { candBonds.Add(new LocRay4(chosenBranch.Loc, dir)); } } } } if (connectors.Count == 1) { if (candBonds.Count > 0) { candBranchPoints.Add(candBonds); chosenBranch = new LocRay4(new Loc(-1)); } else { chosenBranch = new LocRay4(connectors[0].Traverse(1), connectors[0].Dir.Reverse()); } } else { chosenBranch = new LocRay4(new Loc(-1)); } } } // compute a goal amount of terminals to connect // this computation ignores the fact that some terminals may be impossible var randBin = new RandBinomial(candBranchPoints.Count, this.ConnectPercent); int connectionsLeft = randBin.Pick(rand); while (candBranchPoints.Count > 0 && connectionsLeft > 0) { // choose random point to connect int randIndex = rand.Next(candBranchPoints.Count); List <LocRay4> candBonds = candBranchPoints[randIndex]; LocRay4 chosenDir = candBonds[rand.Next(candBonds.Count)]; // connect floorPlan.SetHall(chosenDir, this.GenericHalls.Pick(rand), this.HallComponents); candBranchPoints.RemoveAt(randIndex); GenContextDebug.DebugProgress("Connected Branch"); connectionsLeft--; // check to see if connection destination was also a candidate, // counting this as a double if so for (int ii = candBranchPoints.Count - 1; ii >= 0; ii--) { if (candBranchPoints[ii][0].Loc == chosenDir.Traverse(1)) { candBranchPoints.RemoveAt(ii); connectionsLeft--; } } } }
public void PlaceOrientedHall(Axis4 axis, int scalar, int orth, int scalarDiff, GridPlan floorPlan, PermissiveRoomGen <T> hallGen) { Loc loc = this.GapAxis.CreateLoc(scalar, orth); floorPlan.SetHall(new LocRay4(loc, axis.GetDir(scalarDiff)), hallGen, this.HallComponents.Clone()); }