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 Apply(T map) { if (!ItemThemes.CanPick) { return; } if (!MobThemes.CanPick) { return; } Rect bounds = new Rect(0, 0, map.Width, map.Height); //determine the number of free tiles to put items on; trim the maximum item spawn accordingly (maximum <= 1/2 of free tiles) //determine the number of free tiles to put mobs on; trim the maximum mob spawn accordingly (maximum <= 1/2 of free tiles) List <Loc> itemTiles = new List <Loc>(); int mobSpace = 0; for (int x = bounds.X; x < bounds.X + bounds.Size.X; x++) { for (int y = bounds.Y; y < bounds.Y + bounds.Size.Y; y++) { Loc testLoc = new Loc(x, y); if (!map.TileBlocked(testLoc)) { if (!map.HasTileEffect(new Loc(x, y)) && !map.PostProcGrid[x][y].Status[(int)PostProcType.Panel] && !map.PostProcGrid[x][y].Status[(int)PostProcType.Item]) { bool hasItem = false; foreach (MapItem item in map.Items) { if (item.TileLoc == testLoc) { hasItem = true; break; } } if (!hasItem) { itemTiles.Add(testLoc); } } bool hasMob = false; foreach (Team team in map.AllyTeams) { foreach (Character testChar in team.EnumerateChars()) { if (testChar.CharLoc == testLoc) { hasMob = true; break; } } } foreach (Team team in map.MapTeams) { foreach (Character testChar in team.EnumerateChars()) { if (testChar.CharLoc == testLoc) { hasMob = true; break; } } } if (!hasMob) { mobSpace++; } } } } //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); //place the items for (int ii = 0; ii < chosenItems.Count; ii++) { if (itemTiles.Count > 0) { MapItem item = new MapItem(chosenItems[ii]); int randIndex = map.Rand.Next(itemTiles.Count); ((IPlaceableGenContext <MapItem>)map).PlaceItem(itemTiles[randIndex], item); itemTiles.RemoveAt(randIndex); } } //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); //cover the room in a check that holds all of the monsters, and covers the room's bounds CheckIntrudeBoundsEvent check = new CheckIntrudeBoundsEvent(); check.Bounds = bounds; { RevealAllEvent reveal = new RevealAllEvent(); check.Effects.Add(reveal); GiveMapStatusSingleEvent statusEvent = new GiveMapStatusSingleEvent(30, 0); check.Effects.Add(statusEvent); MonsterHouseMapEvent house = new MonsterHouseMapEvent(); house.Bounds = bounds; foreach (MobSpawn mob in chosenMobs) { MobSpawn copyMob = mob.Copy(); if (map.Rand.Next(ALT_COLOR_ODDS) == 0) { copyMob.BaseForm.Skin = 1; } house.Mobs.Add(copyMob); } check.Effects.Add(house); } AddIntrudeStep(map, check); }