private void PlaceTraps() { DungeonBiomeData biomeData = Game.instance.currentDungeonData.biomeData; // Collect regions with shared trap IDs Dictionary <int, List <Vector2Int> > regions = new Dictionary <int, List <Vector2Int> >(); for (int x = 0; x < mDungeon.width; ++x) { for (int y = 0; y < mDungeon.height; ++y) { RandomDungeonTileData td = mDungeon.Data(x, y); if (td.trap >= 0) { List <Vector2Int> positions = null; bool exists = regions.TryGetValue(td.trap, out positions); if (!exists) { positions = new List <Vector2Int>(); regions.Add(td.trap, positions); } positions.Add(new Vector2Int(x, y)); } } } // Try to place the traps // Traps may have requirements - ie: they may require certain region sizes // They may also conditionally take up 1 or all spaces of a region // todo bdsowers - break traps apart into traps & spawners so that traps // aren't responsible for spawning themselves, which is awkward... // Now generate traps, filling the respective regions (where still possible) // Find all the trap generators List <PlacedTrap> trapPlacerPrefabs = new List <PlacedTrap>(); int maxTrapPrefabsToConsider = MaxTrapsToConsider(biomeData); for (int i = 0; i < maxTrapPrefabsToConsider; ++i) { string prefabName = biomeData.trapPrefabs[i]; GameObject prefab = PrefabManager.instance.PrefabByName(prefabName); PlacedTrap trapPlacer = prefab.GetComponent <PlacedTrap>(); if (trapPlacer != null) { trapPlacerPrefabs.Add(prefab.GetComponent <PlacedTrap>()); } else { Debug.LogError("Unplaceable trap in biome: " + prefabName); } } List <PlacedTrap> potentialTraps = new List <PlacedTrap>(); foreach (KeyValuePair <int, List <Vector2Int> > pair in regions) { int prob = 15; if (Game.instance.quirkRegistry.IsQuirkActive <TrapQueenQuirk>()) { prob = 75; } if (Random.Range(0, 100) > prob) { continue; } potentialTraps.Clear(); potentialTraps.AddRange(trapPlacerPrefabs); bool trapPlaced = false; while (!trapPlaced && potentialTraps.Count > 0) { PlacedTrap trap = potentialTraps.Sample(); if (trap.CanSpawn(pair.Value)) { trap.Spawn(pair.Value, this); trapPlaced = true; } else { potentialTraps.Remove(trap); } } } }
private void GenerateEnvironmentFromDungeon(RandomDungeon dungeon) { DungeonBiomeData biomeData = Game.instance.currentDungeonData.biomeData; for (int x = 0; x < dungeon.width; ++x) { for (int y = 0; y < dungeon.height; ++y) { RandomDungeonTileData tileData = dungeon.Data(x, y); if (dungeon.TileType(x, y) >= 'A' && dungeon.TileType(x, y) <= 'Z') { HandleCheatTile(tileData, x, y, biomeData); } else if (dungeon.TileType(x, y) == RandomDungeonTileData.EMPTY_TILE) { mCollisionMap.MarkSpace(x, y, -1); } else if (dungeon.TileType(x, y) == RandomDungeonTileData.WALL_TILE) { // In the space level, we actually have requirements for what wall tiles // can be placed where; otherwise we get weird decoration clipping if (Game.instance.currentDungeonData.dungeonNum == 3) { bool hasForwardTile = (y + 1 < dungeon.height); char forwardTile = hasForwardTile ? dungeon.TileType(x, y + 1) : RandomDungeonTileData.EMPTY_TILE; if (forwardTile != RandomDungeonTileData.WALKABLE_TILE && forwardTile != RandomDungeonTileData.EXIT_TILE && forwardTile != RandomDungeonTileData.EMPTY_TILE) { int wall = Random.Range(0, 2); PlaceMapPrefab(biomeData.wallPrefabs[wall], x, y, WALKABLEMAP_STATIC_MARK); } else { PlaceMapPrefab(biomeData.wallPrefabs.Sample(), x, y, WALKABLEMAP_STATIC_MARK); } } else { PlaceMapPrefab(biomeData.wallPrefabs.Sample(), x, y, WALKABLEMAP_STATIC_MARK); } } else if (dungeon.TileType(x, y) == RandomDungeonTileData.WALKABLE_TILE || dungeon.TileType(x, y) == RandomDungeonTileData.EXIT_TILE || dungeon.TileType(x, y) == AVATAR_POSITION) { PlaceMapPrefab(biomeData.floorPrefabs.Sample(), x, y, -1, 0, true); } else if (dungeon.TileType(x, y) == SHOP_PEDESTAL) { PlaceMapPrefab(biomeData.floorPrefabs[0], x, y).GetComponent <RevealWhenAvatarIsClose>().allowScaleVariation = false;; PlaceMapPrefab(biomeData.shopPedestablPrefab, x, y, WALKABLEMAP_STATIC_MARK).GetComponent <RevealWhenAvatarIsClose>().allowScaleVariation = false; GameObject buyableItem = PlaceMapPrefab(RandomItem(), x, y); buyableItem.transform.localPosition += Vector3.up * 0.3f; GameObject activationPlate = PlaceMapPrefab("ActivationPlate", x, y + 1); PlaceSurroundingActivationPlates(x, y, null, null, null, buyableItem.GetComponent <Item>()); } else if (dungeon.TileType(x, y) == SHOP_KEEPER) { PlaceMapPrefab(biomeData.floorPrefabs[0], x, y); GameObject shopKeeper = PlaceMapPrefab("ShopKeep", x, y, WALKABLEMAP_USE_PREFAB_MARK, 0.5f); PlaceSurroundingActivationPlates(x, y, "shopkeep_talk", null, shopKeeper); if (Game.instance.isShopKeeperEnemy) { Game.instance.MakeShopKeeperEnemy(); } } else if (dungeon.TileType(x, y) == PRESET_ENEMY) { PlaceMapPrefab(biomeData.floorPrefabs[0], x, y); PlaceEnemy(CurrentDungeonFloorData(), new Vector2Int(x, y)); } if (tileData.chest == 2) { PlaceChest(new Vector2Int(x, y)); } else if (tileData.chest == 1) { bool generateShrine = (Random.Range(0, 100) < 50); if (generateShrine) { Debug.Log("A special room has spawned including a shrine."); PlaceShrine(new Vector2Int(x, y)); } else { Debug.Log("A special room has spawned including a chest."); PlaceChest(new Vector2Int(x, y)); } } } } }