public override void ApplyToPath(IRandom rand, FloorPlan floorPlan) { //attempt 10 times for (int kk = 0; kk < 10; kk++) { //add the boss room FloorPathBranch <T> .ListPathBranchExpansion?expandBossResult = this.ChooseRoomExpansion(rand, floorPlan); if (!expandBossResult.HasValue) { continue; } var bossExpansion = expandBossResult.Value; RoomHallIndex from = bossExpansion.From; if (bossExpansion.Hall != null) { floorPlan.AddHall(bossExpansion.Hall, this.BossHallComponents.Clone(), from); from = new RoomHallIndex(floorPlan.HallCount - 1, true); } floorPlan.AddRoom(bossExpansion.Room, this.BossComponents.Clone(), from); RoomHallIndex bossFrom = new RoomHallIndex(floorPlan.RoomCount - 1, false); GenContextDebug.DebugProgress("Extended with Boss Room"); //now, attempt to add the treasure room and remove the previous rooms if failed FloorPathBranch <T> .ListPathBranchExpansion?expansionResult = FloorPathBranch <T> .ChooseRoomExpansion(this.PrepareTreasureRoom, 100, rand, floorPlan, new List <RoomHallIndex>() { bossFrom }); if (!expansionResult.HasValue) { //remove the previously added boss room and hall floorPlan.EraseRoomHall(bossFrom); floorPlan.EraseRoomHall(from); continue; } var vaultExpansion = expansionResult.Value; if (vaultExpansion.Hall != null) { floorPlan.AddHall(vaultExpansion.Hall, this.VaultHallComponents.Clone(), bossFrom); bossFrom = new RoomHallIndex(floorPlan.HallCount - 1, true); } floorPlan.AddRoom(vaultExpansion.Room, this.VaultComponents.Clone(), bossFrom); GenContextDebug.DebugProgress("Extended with Treasure Room"); return; } }
public override void Apply(T map) { Grid.LocTest checkBlock = (Loc testLoc) => { return(!map.Tiles[testLoc.X][testLoc.Y].TileEquivalent(map.RoomTerrain) || map.HasTileEffect(testLoc)); }; //choose a room to put the chest in //do not choose a room that would cause disconnection of the floor List <int> possibleRooms = new List <int>(); for (int ii = 0; ii < map.RoomPlan.RoomCount; ii++) { FloorRoomPlan testPlan = map.RoomPlan.GetRoomPlan(ii); //if (map.RoomPlan.IsChokePoint(new RoomHallIndex(ii, false))) // continue; if (!BaseRoomFilter.PassesAllFilters(testPlan, this.Filters)) { continue; } //also do not choose a room that contains the end stairs IViewPlaceableGenContext <MapGenExit> exitMap = (IViewPlaceableGenContext <MapGenExit>)map; if (Collision.InBounds(testPlan.RoomGen.Draw, exitMap.GetLoc(0))) { continue; } possibleRooms.Add(ii); } if (possibleRooms.Count == 0) { return; } List <Loc> freeTiles = new List <Loc>(); IRoomGen room = null; while (possibleRooms.Count > 0) { int chosenRoom = map.Rand.Next(possibleRooms.Count); room = map.RoomPlan.GetRoom(possibleRooms[chosenRoom]); //get all places that the chest is eligible freeTiles = Grid.FindTilesInBox(room.Draw.Start, room.Draw.Size, (Loc testLoc) => { if (map.Tiles[testLoc.X][testLoc.Y].TileEquivalent(map.RoomTerrain) && !map.HasTileEffect(testLoc) && map.Tiles[testLoc.X][testLoc.Y + 1].TileEquivalent(map.RoomTerrain) && !map.HasTileEffect(new Loc(testLoc.X, testLoc.Y + 1)) && !map.PostProcGrid[testLoc.X][testLoc.Y].Status[(int)PostProcType.Panel] && !map.PostProcGrid[testLoc.X][testLoc.Y].Status[(int)PostProcType.Item]) { if (Grid.GetForkDirs(testLoc, checkBlock, checkBlock).Count < 2) { foreach (MapItem item in map.Items) { if (item.TileLoc == testLoc) { return(false); } } foreach (Team team in map.AllyTeams) { foreach (Character testChar in team.EnumerateChars()) { if (testChar.CharLoc == testLoc) { return(false); } } } foreach (Team team in map.MapTeams) { foreach (Character testChar in team.EnumerateChars()) { if (testChar.CharLoc == testLoc) { return(false); } } } return(true); } } return(false); }); if (freeTiles.Count > 0) { break; } possibleRooms.RemoveAt(chosenRoom); } //can't find any free tile in any room, return if (freeTiles.Count == 0) { return; } if (!ItemThemes.CanPick) { return; } //choose which item theme to work with ItemTheme chosenItemTheme = ItemThemes.Pick(map.Rand); //the item spawn list in this class dictates the items available for spawning //it will be queried for items that match the theme selected List <MapItem> chosenItems = chosenItemTheme.GenerateItems(map, Items); if (chosenItems.Count == 0) { return; } int randIndex = map.Rand.Next(freeTiles.Count); Loc loc = freeTiles[randIndex]; EffectTile spawnedChest = new EffectTile(37, true); if (Ambush && MobThemes.CanPick) { spawnedChest.Danger = true; //the mob theme will be selected randomly MobTheme chosenMobTheme = MobThemes.Pick(map.Rand); //the mobs in this class are the ones that would be available when the game wants to spawn things outside of the floor's spawn list //it will be queried for monsters that match the theme provided List <MobSpawn> chosenMobs = chosenMobTheme.GenerateMobs(map, Mobs); MobSpawnState mobSpawn = new MobSpawnState(); foreach (MobSpawn mob in chosenMobs) { MobSpawn copyMob = mob.Copy(); if (map.Rand.Next(ALT_COLOR_ODDS) == 0) { copyMob.BaseForm.Skin = 1; } mobSpawn.Spawns.Add(copyMob); } spawnedChest.TileStates.Set(mobSpawn); } ItemSpawnState itemSpawn = new ItemSpawnState(); itemSpawn.Spawns = chosenItems; spawnedChest.TileStates.Set(itemSpawn); Rect wallBounds = new Rect(room.Draw.X - 1, room.Draw.Y - 1, room.Draw.Size.X + 2, room.Draw.Size.Y + 2); spawnedChest.TileStates.Set(new BoundsState(wallBounds)); ((IPlaceableGenContext <EffectTile>)map).PlaceItem(loc, spawnedChest); map.PostProcGrid[loc.X][loc.Y].Status[(int)PostProcType.Panel] = true; map.PostProcGrid[loc.X][loc.Y].Status[(int)PostProcType.Item] = true; GenContextDebug.DebugProgress("Placed Chest"); }
public override void ApplyToPath(IRandom rand, GridPlan floorPlan) { int gapLength = Vertical ? floorPlan.GridHeight : floorPlan.GridWidth; int sideLength = Vertical ? floorPlan.GridWidth : floorPlan.GridHeight; if (gapLength < 3 || sideLength < 2) { CreateErrorPath(rand, floorPlan); return; } //add the body int chosenTier = FromCorners ? (rand.Next(2) * gapLength - 1) : rand.Next(1, gapLength - 1); RoomGen <T> roomGen = GiantHallGen.Pick(rand); if (roomGen == null) { roomGen = GenericRooms.Pick(rand); } floorPlan.AddRoom(new Rect(Vertical ? 0 : chosenTier, Vertical ? chosenTier : 0, Vertical ? sideLength : 1, Vertical ? 1 : sideLength), roomGen, this.LargeRoomComponents.Clone()); GenContextDebug.DebugProgress("Center Room"); //add the legs for (int ii = 0; ii < sideLength; ii++) { if (chosenTier > 0) { if (rand.Next(100) < LegPercent) { int roomTier = rand.Next(0, chosenTier); floorPlan.AddRoom(new Loc(Vertical ? ii : roomTier, Vertical ? roomTier : ii), GenericRooms.Pick(rand), this.RoomComponents.Clone()); for (int jj = roomTier; jj < chosenTier; jj++) { SafeAddHall(new LocRay4(new Loc(Vertical ? ii : jj, Vertical ? jj : ii), Vertical ? Dir4.Down : Dir4.Right), floorPlan, GenericHalls.Pick(rand), GetDefaultGen(), this.RoomComponents, this.HallComponents, true); } GenContextDebug.DebugProgress("Add Leg"); int hasRoom = -1; for (int jj = ii - 1; jj >= 0; jj--) { if (floorPlan.GetRoomPlan(new Loc(Vertical ? jj : roomTier, Vertical ? roomTier : jj)) != null) { hasRoom = jj; break; } } if (ii > 0 && hasRoom > -1) { if (rand.Next(100) < ConnectPercent) { for (int jj = ii; jj > hasRoom; jj--) { SafeAddHall(new LocRay4(new Loc(Vertical ? jj : roomTier, Vertical ? roomTier : jj), Vertical ? Dir4.Left : Dir4.Up), floorPlan, GenericHalls.Pick(rand), GetDefaultGen(), this.RoomComponents, this.HallComponents, true); GenContextDebug.DebugProgress("Connect Leg"); } } } } } if (chosenTier < gapLength - 1) { if (rand.Next(100) < LegPercent) { int roomTier = rand.Next(chosenTier + 1, gapLength); floorPlan.AddRoom(new Loc(Vertical ? ii : roomTier, Vertical ? roomTier : ii), GenericRooms.Pick(rand), this.RoomComponents.Clone()); for (int jj = chosenTier; jj < roomTier; jj++) { SafeAddHall(new LocRay4(new Loc(Vertical ? ii : jj, Vertical ? jj : ii), Vertical ? Dir4.Down : Dir4.Right), floorPlan, GenericHalls.Pick(rand), GetDefaultGen(), this.RoomComponents, this.HallComponents, true); } GenContextDebug.DebugProgress("Add Leg"); int hasRoom = -1; for (int jj = ii - 1; jj >= 0; jj--) { if (floorPlan.GetRoomPlan(new Loc(Vertical ? jj : roomTier, Vertical ? roomTier : jj)) != null) { hasRoom = jj; break; } } if (ii > 0 && hasRoom > -1) { if (rand.Next(100) < ConnectPercent) { for (int jj = ii; jj > hasRoom; jj--) { SafeAddHall(new LocRay4(new Loc(Vertical ? jj : roomTier, Vertical ? roomTier : jj), Vertical ? Dir4.Left : Dir4.Up), floorPlan, GenericHalls.Pick(rand), GetDefaultGen(), this.RoomComponents, this.HallComponents, true); GenContextDebug.DebugProgress("Connect Leg"); } } } } } } }