private void PlaceWallMimics(Action <Dungeon, RoomHandler> orig, Dungeon dungeon, RoomHandler roomHandler) { // Used for debug read out information int NorthWallCount = 0; int SouthWallCount = 0; int EastWallCount = 0; int WestWallCount = 0; int WallMimicsPlaced = 0; int iterations = 0; if (ExpandTheGungeon.LogoEnabled && GameManager.Instance.CurrentLevelOverrideState != GameManager.LevelOverrideState.FOYER) { ExpandTheGungeon.LogoEnabled = false; } if (ExpandTheGungeon.GameManagerHook == null) { if (ExpandStats.debugMode) { Debug.Log("[ExpandTheGungeon] Installing GameManager.Awake Hook...."); } ExpandTheGungeon.GameManagerHook = new Hook( typeof(GameManager).GetMethod("Awake", BindingFlags.NonPublic | BindingFlags.Instance), typeof(ExpandTheGungeon).GetMethod("GameManager_Awake", BindingFlags.NonPublic | BindingFlags.Instance), typeof(GameManager) ); } ExpandStaticReferenceManager.ClearStaticPerLevelData(); ExpandStaticReferenceManager.PopulateLists(); try { int currentFloor = GameManager.Instance.CurrentFloor; int numWallMimicsForFloor = MetaInjectionData.GetNumWallMimicsForFloor(dungeon.tileIndices.tilesetId); GameManager.LevelOverrideState levelOverrideState = GameManager.Instance.CurrentLevelOverrideState; if (levelOverrideState != GameManager.LevelOverrideState.NONE | levelOverrideState == GameManager.LevelOverrideState.TUTORIAL) { if (ExpandStats.debugMode) { ETGModConsole.Log("[DEBUG] This floor has been excluded from having Wall Mimics", false); } return; } if (ExpandStats.debugMode) { ETGModConsole.Log("[DEBUG] Current Floor: " + currentFloor, false); ETGModConsole.Log("[DEBUG] Wall Mimics assigned by RewardManager: " + numWallMimicsForFloor, false); } SetupSecretDoorDestinations(dungeon); if (currentFloor < 4) { PlaceGlitchElevator(dungeon); } ExpandJunkEnemySpawneer m_ExpandJunkEnemySpawneer = new ExpandJunkEnemySpawneer(); m_ExpandJunkEnemySpawneer.PlaceRandomJunkEnemies(dungeon, roomHandler); m_ExpandJunkEnemySpawneer = null; if (dungeon.IsGlitchDungeon) { ETGMod.AIActor.OnPreStart = (Action <AIActor>)Delegate.Combine(ETGMod.AIActor.OnPreStart, new Action <AIActor>(EnemyModRandomizer)); } else { ETGMod.AIActor.OnPreStart = (Action <AIActor>)Delegate.Remove(ETGMod.AIActor.OnPreStart, new Action <AIActor>(EnemyModRandomizer)); } ExpandPlaceCorruptTiles m_CorruptTilePlayer = new ExpandPlaceCorruptTiles(); m_CorruptTilePlayer.PlaceCorruptTiles(dungeon); m_CorruptTilePlayer = null; ExpandFloorDecorator FloorDecorator = new ExpandFloorDecorator(); FloorDecorator.PlaceFloorDecoration(dungeon); FloorDecorator = null; if (numWallMimicsForFloor <= 0) { if (ExpandStats.debugMode) { ETGModConsole.Log("[DEBUG] There will be no Wall Mimics assigned to this floor.", false); } return; } if (levelOverrideState == GameManager.LevelOverrideState.RESOURCEFUL_RAT) { if (ExpandStats.debugMode) { ETGModConsole.Log("[DEBUG] The Resourceful Rat Maze has been excluded from having wall mimics.", false); } return; } if (ExpandStats.debugMode) { ETGModConsole.Log("[DEBUG] Wall Mimics Assigned to Floor: " + numWallMimicsForFloor, false); } List <int> roomList = Enumerable.Range(0, dungeon.data.rooms.Count).ToList(); roomList = roomList.Shuffle(); if (roomHandler != null) { roomList = new List <int>(new int[] { dungeon.data.rooms.IndexOf(roomHandler) }); } List <Tuple <IntVector2, DungeonData.Direction> > validWalls = new List <Tuple <IntVector2, DungeonData.Direction> >(); List <AIActor> enemiesList = new List <AIActor>(); while (iterations < roomList.Count && WallMimicsPlaced < numWallMimicsForFloor) { RoomHandler currentRoom = dungeon.data.rooms[roomList[iterations]]; if (!currentRoom.IsShop) { if (!currentRoom.area.IsProceduralRoom || currentRoom.area.proceduralCells == null) { if (currentRoom.area.PrototypeRoomCategory != PrototypeDungeonRoom.RoomCategory.BOSS || !BraveUtility.RandomBool()) { if (!currentRoom.GetRoomName().StartsWith("DraGunRoom") && !currentRoom.IsMaintenanceRoom() && !BannedWallMimicRoomList.Contains(currentRoom.GetRoomName().ToLower())) { if (currentRoom.connectedRooms != null) { for (int i = 0; i < currentRoom.connectedRooms.Count; i++) { if (currentRoom.connectedRooms[i] == null || currentRoom.connectedRooms[i].area.PrototypeRoomCategory == PrototypeDungeonRoom.RoomCategory.BOSS) { } } } if (roomHandler == null) { bool MaxMimicCountReached = false; currentRoom.GetActiveEnemies(RoomHandler.ActiveEnemyType.All, ref enemiesList); for (int j = 0; j < enemiesList.Count; j++) { AIActor aiactor = enemiesList[j]; if (aiactor && aiactor.EnemyGuid == GameManager.Instance.RewardManager.WallMimicChances.EnemyGuid) { MaxMimicCountReached = true; break; } } if (MaxMimicCountReached) { goto IL_EXIT; } } validWalls.Clear(); for (int Width = -1; Width <= currentRoom.area.dimensions.x; Width++) { for (int Height = -1; Height <= currentRoom.area.dimensions.y; Height++) { int X = currentRoom.area.basePosition.x + Width; int Y = currentRoom.area.basePosition.y + Height; if (dungeon.data.isWall(X, Y) && X % 4 == 0 && Y % 4 == 0) { int WallCount = 0; if (!dungeon.data.isWall(X - 1, Y + 2) && !dungeon.data.isWall(X, Y + 2) && !dungeon.data.isWall(X + 1, Y + 2) && !dungeon.data.isWall(X + 2, Y + 2) && !dungeon.data.isWall(X - 1, Y + 1) && !dungeon.data.isWall(X, Y + 1) && !dungeon.data.isWall(X + 1, Y + 1) && !dungeon.data.isWall(X + 2, Y + 1) && dungeon.data.isWall(X - 1, Y) && dungeon.data.isWall(X, Y) && dungeon.data.isWall(X + 1, Y) && dungeon.data.isWall(X + 2, Y) && dungeon.data.isWall(X - 1, Y - 1) && dungeon.data.isWall(X, Y - 1) && dungeon.data.isWall(X + 1, Y - 1) && dungeon.data.isWall(X + 2, Y - 1) && !dungeon.data.isPlainEmptyCell(X - 1, Y - 3) && !dungeon.data.isPlainEmptyCell(X, Y - 3) && !dungeon.data.isPlainEmptyCell(X + 1, Y - 3) && !dungeon.data.isPlainEmptyCell(X + 2, Y - 3)) { validWalls.Add(Tuple.Create(new IntVector2(X, Y), DungeonData.Direction.NORTH)); WallCount++; SouthWallCount++; } else if (dungeon.data.isWall(X - 1, Y + 2) && dungeon.data.isWall(X, Y + 2) && dungeon.data.isWall(X + 1, Y + 2) && dungeon.data.isWall(X + 2, Y + 2) && dungeon.data.isWall(X - 1, Y + 1) && dungeon.data.isWall(X, Y + 1) && dungeon.data.isWall(X + 1, Y + 1) && dungeon.data.isWall(X + 2, Y + 1) && dungeon.data.isWall(X - 1, Y) && dungeon.data.isWall(X, Y) && dungeon.data.isWall(X + 1, Y) && dungeon.data.isWall(X + 2, Y) && dungeon.data.isPlainEmptyCell(X, Y - 1) && dungeon.data.isPlainEmptyCell(X + 1, Y - 1) && !dungeon.data.isPlainEmptyCell(X, Y + 4) && !dungeon.data.isPlainEmptyCell(X + 1, Y + 4)) { validWalls.Add(Tuple.Create(new IntVector2(X, Y), DungeonData.Direction.SOUTH)); WallCount++; NorthWallCount++; } else if (dungeon.data.isWall(X, Y + 2) && dungeon.data.isWall(X, Y + 1) && dungeon.data.isWall(X - 1, Y) && dungeon.data.isWall(X, Y - 1) && dungeon.data.isWall(X, Y - 2) && !dungeon.data.isPlainEmptyCell(X - 2, Y + 2) && !dungeon.data.isPlainEmptyCell(X - 2, Y + 1) && !dungeon.data.isPlainEmptyCell(X - 2, Y) && dungeon.data.isPlainEmptyCell(X + 1, Y) && dungeon.data.isPlainEmptyCell(X + 1, Y - 1) && !dungeon.data.isPlainEmptyCell(X - 2, Y - 1) && !dungeon.data.isPlainEmptyCell(X - 2, Y - 2)) { validWalls.Add(Tuple.Create(new IntVector2(X, Y), DungeonData.Direction.EAST)); WallCount++; WestWallCount++; } else if (dungeon.data.isWall(X, Y + 2) && dungeon.data.isWall(X, Y + 1) && dungeon.data.isWall(X + 1, Y) && dungeon.data.isWall(X, Y - 1) && dungeon.data.isWall(X, Y - 2) && !dungeon.data.isPlainEmptyCell(X + 2, Y + 2) && !dungeon.data.isPlainEmptyCell(X + 2, Y + 1) && !dungeon.data.isPlainEmptyCell(X + 2, Y) && dungeon.data.isPlainEmptyCell(X - 1, Y) && dungeon.data.isPlainEmptyCell(X - 1, Y - 1) && !dungeon.data.isPlainEmptyCell(X + 2, Y - 1) && !dungeon.data.isPlainEmptyCell(X + 2, Y - 2)) { validWalls.Add(Tuple.Create(new IntVector2(X - 1, Y), DungeonData.Direction.WEST)); WallCount++; EastWallCount++; } if (WallCount > 0) { bool flag2 = true; int XPadding = -5; while (XPadding <= 5 && flag2) { int YPadding = -5; while (YPadding <= 5 && flag2) { int x = X + XPadding; int y = Y + YPadding; if (dungeon.data.CheckInBoundsAndValid(x, y)) { CellData cellData = dungeon.data[x, y]; if (cellData != null) { if (cellData.type == CellType.PIT || cellData.diagonalWallType != DiagonalWallType.NONE) { flag2 = false; } } } YPadding++; } XPadding++; } if (!flag2) { while (WallCount > 0) { validWalls.RemoveAt(validWalls.Count - 1); WallCount--; } } } } } } if (roomHandler == null) { if (validWalls.Count > 0) { Tuple <IntVector2, DungeonData.Direction> WallCell = BraveUtility.RandomElement(validWalls); IntVector2 Position = WallCell.First; DungeonData.Direction Direction = WallCell.Second; if (Direction != DungeonData.Direction.WEST) { currentRoom.RuntimeStampCellComplex(Position.x, Position.y, CellType.FLOOR, DiagonalWallType.NONE); } if (Direction != DungeonData.Direction.EAST) { currentRoom.RuntimeStampCellComplex(Position.x + 1, Position.y, CellType.FLOOR, DiagonalWallType.NONE); } AIActor orLoadByGuid = EnemyDatabase.GetOrLoadByGuid(GameManager.Instance.RewardManager.WallMimicChances.EnemyGuid); AIActor.Spawn(orLoadByGuid, Position, currentRoom, true, AIActor.AwakenAnimationType.Default, true); validWalls.Remove(WallCell); WallMimicsPlaced++; } } } } } } IL_EXIT: iterations++; } if (WallMimicsPlaced > 0) { PhysicsEngine.Instance.ClearAllCachedTiles(); if (ExpandStats.debugMode) { ETGModConsole.Log("[DEBUG] Number of Valid North Wall Mimics locations: " + NorthWallCount, false); ETGModConsole.Log("[DEBUG] Number of Valid South Wall Mimics locations: " + SouthWallCount, false); ETGModConsole.Log("[DEBUG] Number of Valid East Wall Mimics locations: " + EastWallCount, false); ETGModConsole.Log("[DEBUG] Number of Valid West Wall Mimics locations: " + WestWallCount, false); ETGModConsole.Log("[DEBUG] Number of Wall Mimics succesfully placed: " + WallMimicsPlaced, false); } } } catch (Exception ex) { if (ExpandStats.debugMode) { ETGModConsole.Log("[DEBUG] Exception occured in Dungeon.PlaceWallMimics!"); } Debug.Log("Exception caught in Dungeon.PlaceWallMimics!"); Debug.LogException(ex); if (WallMimicsPlaced > 0) { PhysicsEngine.Instance.ClearAllCachedTiles(); if (ExpandStats.debugMode) { ETGModConsole.Log("[DEBUG] Number of Valid North Wall Mimics locations: " + NorthWallCount, false); ETGModConsole.Log("[DEBUG] Number of Valid South Wall Mimics locations: " + SouthWallCount, false); ETGModConsole.Log("[DEBUG] Number of Valid East Wall Mimics locations: " + EastWallCount, false); ETGModConsole.Log("[DEBUG] Number of Valid West Wall Mimics locations: " + WestWallCount, false); ETGModConsole.Log("[DEBUG] Number of Wall Mimics succesfully placed: " + WallMimicsPlaced, false); } } } }
public void PlaceWallMimics(Action <Dungeon, RoomHandler> orig, Dungeon dungeon, RoomHandler roomHandler) { int WallMimicsPlaced = 0; int WallMimicsPerRoom = 1; int numWallMimicsForFloor = MetaInjectionData.GetNumWallMimicsForFloor(dungeon.tileIndices.tilesetId); int currentFloor = GameManager.Instance.CurrentFloor; if (roomHandler != null) { goto IL_SKIP; } if (ExpandTheGungeon.LogoEnabled && GameManager.Instance.CurrentLevelOverrideState != GameManager.LevelOverrideState.FOYER) { ExpandTheGungeon.LogoEnabled = false; } if (GameManager.Instance.CurrentLevelOverrideState == GameManager.LevelOverrideState.FOYER) { ExpandSettings.phobosElevatorHasBeenUsed = false; ExpandSettings.elevatorHasBeenUsed = false; } ExpandStaticReferenceManager.PopulateLists(); GameManager.LevelOverrideState levelOverrideState = GameManager.Instance.CurrentLevelOverrideState; if (ExpandSettings.debugMode) { ETGModConsole.Log("[DEBUG] Current Floor: " + currentFloor, false); } try { if (ExpandTheGungeon.GameManagerHook == null) { if (ExpandSettings.debugMode) { Debug.Log("[ExpandTheGungeon] Installing GameManager.Awake Hook...."); } ExpandTheGungeon.GameManagerHook = new Hook( typeof(GameManager).GetMethod("Awake", BindingFlags.NonPublic | BindingFlags.Instance), typeof(ExpandTheGungeon).GetMethod("GameManager_Awake", BindingFlags.NonPublic | BindingFlags.Instance), typeof(GameManager) ); } if (ExpandSettings.debugMode) { ETGModConsole.Log("[DEBUG] Number of Wall Mimics RewardManager wants to spawn: " + numWallMimicsForFloor, false); } if (levelOverrideState != GameManager.LevelOverrideState.NONE | levelOverrideState == GameManager.LevelOverrideState.TUTORIAL | levelOverrideState == GameManager.LevelOverrideState.FOYER | dungeon.tileIndices.tilesetId == GlobalDungeonData.ValidTilesets.RATGEON) { if (ExpandSettings.debugMode) { ETGModConsole.Log("[DEBUG] This floor has been excluded from having Wall Mimics", false); } if (ExpandSettings.debugMode && dungeon.tileIndices.tilesetId == GlobalDungeonData.ValidTilesets.RATGEON) { ETGModConsole.Log("[DEBUG] The Resourceful Rat Maze/tileset has been excluded from having wall mimics and other floor mods!", false); } return; } if (dungeon.data == null | dungeon.data.rooms.Count <= 0) { if (ExpandSettings.debugMode) { ETGModConsole.Log("Dungeon has no rooms or Dungeon.data is null! This is super abnormal!", false); } return; } PlaceGlitchElevator(dungeon, currentFloor); ExpandJunkEnemySpawneer.PlaceRandomJunkEnemies(dungeon, roomHandler); if (ExpandSettings.EnableExpandedGlitchFloors) { if (dungeon.IsGlitchDungeon) { ETGMod.AIActor.OnPreStart = (Action <AIActor>)Delegate.Combine(ETGMod.AIActor.OnPreStart, new Action <AIActor>(EnemyModRandomizer)); } else { ETGMod.AIActor.OnPreStart = (Action <AIActor>)Delegate.Remove(ETGMod.AIActor.OnPreStart, new Action <AIActor>(EnemyModRandomizer)); } ExpandPlaceCorruptTiles.PlaceCorruptTiles(dungeon); } ExpandFloorDecorator.PlaceFloorDecoration(dungeon); if (PlayerHasCorruptedJunk) { CorruptRandomRooms(dungeon, currentFloor); } } catch (Exception ex) { if (ExpandSettings.debugMode) { ETGModConsole.Log("[DEBUG] Exception caught in early setup code for ExpandMain.ExpandPlaceWallMimics!"); } Debug.Log("Exception caught in early setup code for ExpandMain.ExpandPlaceWallMimics!"); Debug.LogException(ex); } if (numWallMimicsForFloor <= 0 && !PlayerHasWallMimicItem) { if (ExpandSettings.debugMode) { ETGModConsole.Log("[DEBUG] There will be no Wall Mimics for this floor.", false); } PhysicsEngine.Instance.ClearAllCachedTiles(); return; } IL_SKIP: if (roomHandler != null) { if (ExpandSettings.debugMode) { ETGModConsole.Log("[DEBUG] Wall Mimics Assigned to specific room: " + numWallMimicsForFloor, false); } if (SpawnWallMimic(dungeon, roomHandler) == 0) { if (ExpandSettings.debugMode) { ETGModConsole.Log("[DEBUG] Failed to find valid locations for a Wall Mimic in room: " + numWallMimicsForFloor + "!", false); } } } else { List <RoomHandler> RoomList = new List <RoomHandler>(); foreach (RoomHandler room in dungeon.data.rooms) { if (room.area != null && !room.IsShop && !room.PrecludeTilemapDrawing && !string.IsNullOrEmpty(room.GetRoomName()) && room.area.PrototypeRoomCategory != PrototypeDungeonRoom.RoomCategory.SECRET) { if (!room.area.IsProceduralRoom || room.area.proceduralCells == null) { if (room.area.PrototypeRoomCategory != PrototypeDungeonRoom.RoomCategory.BOSS || !BraveUtility.RandomBool()) { if (!room.GetRoomName().StartsWith("DraGunRoom") && !room.IsMaintenanceRoom() && !BannedWallMimicRoomList.Contains(room.GetRoomName().ToLower())) { RoomList.Add(room); } } } } } int ValidRooms = RoomList.Count; int RoomsChecked = 0; if (PlayerHasWallMimicItem) { switch (dungeon.tileIndices.tilesetId) { case GlobalDungeonData.ValidTilesets.CATHEDRALGEON: WallMimicsPerRoom = 2; break; case GlobalDungeonData.ValidTilesets.BELLYGEON: WallMimicsPerRoom = 2; break; case GlobalDungeonData.ValidTilesets.CATACOMBGEON: WallMimicsPerRoom = 2; break; case GlobalDungeonData.ValidTilesets.OFFICEGEON: WallMimicsPerRoom = 2; break; case GlobalDungeonData.ValidTilesets.WESTGEON: WallMimicsPerRoom = 2; break; case GlobalDungeonData.ValidTilesets.FORGEGEON: WallMimicsPerRoom = 2; break; case GlobalDungeonData.ValidTilesets.HELLGEON: WallMimicsPerRoom = 3; break; default: WallMimicsPerRoom = 1; break; } numWallMimicsForFloor = (ValidRooms * WallMimicsPerRoom); if (ExpandSettings.debugMode) { ETGModConsole.Log("[DEBUG] Wall Mimics assigned by Cursed Bricks: " + (ValidRooms * WallMimicsPerRoom), false); } } IL_CHECKNEXTROOM: if (WallMimicsPlaced >= numWallMimicsForFloor | RoomList.Count <= 0 | RoomsChecked >= ValidRooms) { if (ExpandSettings.debugMode) { ETGModConsole.Log("[DEBUG] All valid rooms for Wall Mimics have been checked. Placement complete."); ETGModConsole.Log("[DEBUG] Wall Mimics Succewsfully Placed: " + WallMimicsPlaced); } PhysicsEngine.Instance.ClearAllCachedTiles(); return; } if (RoomList.Count > 1) { RoomList = RoomList.Shuffle(); } RoomHandler CurrentRoom = BraveUtility.RandomElement(RoomList); RoomList.Remove(CurrentRoom); RoomsChecked++; WallMimicsPlaced += SpawnWallMimic(dungeon, CurrentRoom, WallMimicsPerRoom); if (RoomsChecked < ValidRooms && WallMimicsPlaced < numWallMimicsForFloor) { goto IL_CHECKNEXTROOM; } } if (ExpandSettings.debugMode) { ETGModConsole.Log("[DEBUG] All valid rooms for Wall Mimics have been checked. Placement complete."); ETGModConsole.Log("[DEBUG] Wall Mimics Succewsfully Placed: " + WallMimicsPlaced); } PhysicsEngine.Instance.ClearAllCachedTiles(); }