public void Update() { if (m_WasKicked) { if (GetAbsoluteParentRoom() == null) { m_WasKicked = false; willDefinitelyExplode = true; SelfDestructOnKick(); } FlippableCover m_Table = GetComponent <FlippableCover>(); if (m_Table) { if (m_Table.IsBroken) { m_WasKicked = false; willDefinitelyExplode = true; SelfDestructOnKick(); } } } if (m_shouldDisplayOutline) { int num; DungeonData.Direction inverseDirection = DungeonData.GetInverseDirection(DungeonData.GetDirectionFromIntVector2(GetFlipDirection(m_lastInteractingPlayer.specRigidbody, out num))); if (inverseDirection != m_lastOutlineDirection || sprite.spriteId != m_lastSpriteId) { SpriteOutlineManager.RemoveOutlineFromSprite(sprite, false); SpriteOutlineManager.AddSingleOutlineToSprite <tk2dSprite>(sprite, DungeonData.GetIntVector2FromDirection(inverseDirection), Color.white, 0.25f, 0f); } m_lastOutlineDirection = inverseDirection; m_lastSpriteId = sprite.spriteId; } if (leavesGoopTrail && specRigidbody.Velocity.magnitude > 0.1f) { m_goopElapsed += BraveTime.DeltaTime; if (m_goopElapsed > goopFrequency) { m_goopElapsed -= BraveTime.DeltaTime; if (m_goopManager == null) { m_goopManager = DeadlyDeadlyGoopManager.GetGoopManagerForGoopType(goopType); } m_goopManager.AddGoopCircle(sprite.WorldCenter, goopRadius + 0.1f, -1, false, -1); } if (AllowTopWallTraversal && GameManager.Instance.Dungeon.data.CheckInBoundsAndValid(sprite.WorldCenter.ToIntVector2(VectorConversions.Floor)) && GameManager.Instance.Dungeon.data[sprite.WorldCenter.ToIntVector2(VectorConversions.Floor)].IsFireplaceCell) { MinorBreakable component = GetComponent <MinorBreakable>(); if (component && !component.IsBroken) { component.Break(Vector2.zero); GameStatsManager.Instance.SetFlag(GungeonFlags.FLAG_ROLLED_BARREL_INTO_FIREPLACE, true); } } } }
private IEnumerator HandleExpand(FlippableCover target) { string TableName = target.gameObject.name; yield return(new WaitForSeconds(0.15f)); if (target && target.specRigidbody) { AkSoundEngine.PostEvent("Play_WPN_woodbeam_extend_01", gameObject); target.specRigidbody.CanBePushed = false; // Vector3 SpriteOffset = target.transform.position; DungeonData.Direction DirectionFlipped = target.DirectionFlipped; // SpriteOffset -= new Vector3(1.4f, 1.6f, 0); // target.transform.position = SpriteOffset; yield return(null); // if (target.specRigidbody) { target.specRigidbody.CanBePushed = false; } float elapsed = 0f; Vector2 scaleAmount = new Vector2(TableScaleAmount, TableScaleAmount); if (!target) { yield break; } Vector2 startScale = target.transform.localScale; while (elapsed < TableExpandSpeed) { if (!target) { yield break; } elapsed += BraveTime.DeltaTime; target.transform.localScale = Vector2.Lerp(startScale, scaleAmount, (elapsed * TableExpandSpeed)); /*if (DirectionFlipped == DungeonData.Direction.EAST && TableName.ToLower().Contains("horizontal")) { * target.transform.position -= new Vector3(0.04f, 0.02f, 0); * } else { * target.transform.position -= new Vector3(0.02f, 0.02f, 0); * }*/ if (target.sprite) { target.sprite.UpdateZDepth(); } if (target.specRigidbody) { target.specRigidbody.UpdateCollidersOnRotation = true; target.specRigidbody.UpdateCollidersOnScale = true; target.specRigidbody.RegenerateColliders = true; // target.specRigidbody.UpdateColliderPositions(); target.specRigidbody.Reinitialize(); } yield return(null); } } yield break; }
public void ConfigureOnPlacement(RoomHandler room) { Vector2 vector = transform.position.XY() + new Vector2(specRigidbody.GroundPixelCollider.ManualOffsetX / 16f, specRigidbody.GroundPixelCollider.ManualOffsetY / 16f); Vector2 vector2 = vector.ToIntVector2(VectorConversions.Round).ToVector2(); transform.position += (vector2 - vector).ToVector3ZUp(); pos1 = vector2.ToIntVector2(VectorConversions.Floor); pos2 = pos1 + IntVector2.Right; m_facingDirection = GetFacingDirection(pos1, pos2); if (m_facingDirection == DungeonData.Direction.WEST) { pos1 = pos2; m_startingPos = transform.position + new Vector3(1f, 0f); } else if (m_facingDirection == DungeonData.Direction.EAST) { pos2 = pos1; m_startingPos = transform.position; } else { m_startingPos = transform.position + new Vector3(0.5f, 0f); } try { CellData cellData = GameManager.Instance.Dungeon.data[pos1]; CellData cellData2 = GameManager.Instance.Dungeon.data[pos2]; cellData.isSecretRoomCell = true; cellData2.isSecretRoomCell = true; cellData.forceDisallowGoop = true; cellData2.forceDisallowGoop = true; cellData.cellVisualData.preventFloorStamping = true; cellData2.cellVisualData.preventFloorStamping = true; cellData.isWallMimicHideout = true; cellData2.isWallMimicHideout = true; if (m_facingDirection == DungeonData.Direction.WEST || m_facingDirection == DungeonData.Direction.EAST) { GameManager.Instance.Dungeon.data[pos1 + IntVector2.Up].isSecretRoomCell = true; } } catch (Exception ex) { Debug.Log("[DEBUG] Warning: Exception caught during ChaosWallMimicManager.ConfigureOnPlacement!\nLikely due to Wall Mimic spawning in an area besides a normal Wall Mimic Hideout!"); Debug.LogException(ex); m_failedWallConfigure = true; } m_configured = true; }
public static void AddExit(PrototypeDungeonRoom room, Vector2 location, DungeonData.Direction direction) { if (room.exitData == null) { room.exitData = new PrototypeRoomExitData(); } if (room.exitData.exits == null) { room.exitData.exits = new List <PrototypeRoomExit>(); } PrototypeRoomExit exit = new PrototypeRoomExit(direction, location); exit.exitType = PrototypeRoomExit.ExitType.NO_RESTRICTION; Vector2 margin = (direction == DungeonData.Direction.EAST || direction == DungeonData.Direction.WEST) ? new Vector2(0, 1) : new Vector2(1, 0); exit.containedCells.Add(location + margin); room.exitData.exits.Add(exit); }
public ChaosKickableObject() { rollSpeed = 6f; rollAnimations = null; goopFrequency = 0.05f; goopRadius = 1f; breakTimerLength = 3f; RollingDestroysSafely = false; triggersBreakTimer = false; AllowTopWallTraversal = true; explodesOnKick = true; willDefinitelyExplode = false; spawnObjectOnSelfDestruct = false; useDefaultExplosion = false; hasRollingAnimations = false; RollingBreakAnim = "red_barrel_break"; m_lastOutlineDirection = (DungeonData.Direction)(-1); m_objectSpawned = false; TableExplosionData = EnemyDatabase.GetOrLoadByGuid("4d37ce3d666b4ddda8039929225b7ede").gameObject.GetComponent <ExplodeOnDeath>().explosionData; }
public ExpandKickableObject() { rollSpeed = 6f; rollAnimations = null; goopFrequency = 0.05f; goopRadius = 1f; breakTimerLength = 3f; RollingDestroysSafely = false; triggersBreakTimer = false; AllowTopWallTraversal = true; explodesOnKick = true; willDefinitelyExplode = false; spawnObjectOnSelfDestruct = false; useDefaultExplosion = false; hasRollingAnimations = false; RollingBreakAnim = "red_barrel_break"; m_lastOutlineDirection = (DungeonData.Direction)(-1); m_objectSpawned = false; TableExplosionData = ExpandUtility.GenerateExplosionData(); m_WasKicked = false; }
// Token: 0x0600004D RID: 77 RVA: 0x00004550 File Offset: 0x00002750 public static void AddExit(PrototypeDungeonRoom room, Vector2 location, DungeonData.Direction direction) { bool flag = room.exitData == null; if (flag) { room.exitData = new PrototypeRoomExitData(); } bool flag2 = room.exitData.exits == null; if (flag2) { room.exitData.exits = new List <PrototypeRoomExit>(); } PrototypeRoomExit prototypeRoomExit = new PrototypeRoomExit(direction, location); prototypeRoomExit.exitType = PrototypeRoomExit.ExitType.NO_RESTRICTION; Vector2 b = (direction == DungeonData.Direction.EAST || direction == DungeonData.Direction.WEST) ? new Vector2(0f, 1f) : new Vector2(1f, 0f); prototypeRoomExit.containedCells.Add(location + b); room.exitData.exits.Add(prototypeRoomExit); }
private void ClearOutlines() { m_lastOutlineDirection = (DungeonData.Direction)(-1); m_lastSpriteId = -1; SpriteOutlineManager.RemoveOutlineFromSprite(sprite, false); }
// Token: 0x0600003E RID: 62 RVA: 0x00003B70 File Offset: 0x00001D70 public static void ApplyRoomData(PrototypeDungeonRoom room, RoomFactory.RoomData roomData) { bool flag = roomData.exitPositions != null; if (flag) { for (int i = 0; i < roomData.exitPositions.Length; i++) { DungeonData.Direction direction = (DungeonData.Direction)Enum.Parse(typeof(DungeonData.Direction), roomData.exitDirections[i].ToUpper()); RoomFactory.AddExit(room, roomData.exitPositions[i], direction); } } else { RoomFactory.AddExit(room, new Vector2((float)(room.Width / 2), (float)room.Height), DungeonData.Direction.NORTH); RoomFactory.AddExit(room, new Vector2((float)(room.Width / 2), 0f), DungeonData.Direction.SOUTH); RoomFactory.AddExit(room, new Vector2((float)room.Width, (float)(room.Height / 2)), DungeonData.Direction.EAST); RoomFactory.AddExit(room, new Vector2(0f, (float)(room.Height / 2)), DungeonData.Direction.WEST); } bool flag2 = roomData.enemyPositions != null; if (flag2) { for (int j = 0; j < roomData.enemyPositions.Length; j++) { RoomFactory.AddEnemyToRoom(room, roomData.enemyPositions[j], roomData.enemyGUIDs[j], roomData.enemyReinforcementLayers[j]); } } bool flag3 = roomData.placeablePositions != null; if (flag3) { for (int k = 0; k < roomData.placeablePositions.Length; k++) { RoomFactory.AddPlaceableToRoom(room, roomData.placeablePositions[k], roomData.placeableGUIDs[k]); } } bool flag4 = roomData.floors != null; if (flag4) { foreach (string val in roomData.floors) { room.prerequisites.Add(new DungeonPrerequisite { prerequisiteType = DungeonPrerequisite.PrerequisiteType.TILESET, requiredTileset = Tools.GetEnumValue <GlobalDungeonData.ValidTilesets>(val) }); } } bool flag5 = !string.IsNullOrEmpty(roomData.category); if (flag5) { room.category = Tools.GetEnumValue <PrototypeDungeonRoom.RoomCategory>(roomData.category); } bool flag6 = !string.IsNullOrEmpty(roomData.normalSubCategory); if (flag6) { room.subCategoryNormal = Tools.GetEnumValue <PrototypeDungeonRoom.RoomNormalSubCategory>(roomData.normalSubCategory); } bool flag7 = !string.IsNullOrEmpty(roomData.bossSubCategory); if (flag7) { room.subCategoryBoss = Tools.GetEnumValue <PrototypeDungeonRoom.RoomBossSubCategory>(roomData.bossSubCategory); } bool flag8 = !string.IsNullOrEmpty(roomData.specialSubCatergory); if (flag8) { room.subCategorySpecial = Tools.GetEnumValue <PrototypeDungeonRoom.RoomSpecialSubCategory>(roomData.specialSubCatergory); } }
public static void AddExitToRoom(PrototypeDungeonRoom room, Vector2 ExitLocation, DungeonData.Direction ExitDirection, PrototypeRoomExit.ExitType ExitType = PrototypeRoomExit.ExitType.NO_RESTRICTION, PrototypeRoomExit.ExitGroup ExitGroup = PrototypeRoomExit.ExitGroup.A, bool ContainsDoor = true, int ExitLength = 3, int exitSize = 2, DungeonPlaceable overrideDoorObject = null) { if (room == null) { return; } if (room.exitData == null) { room.exitData = new PrototypeRoomExitData(); room.exitData.exits = new List <PrototypeRoomExit>(); } if (room.exitData.exits == null) { room.exitData.exits = new List <PrototypeRoomExit>(); } PrototypeRoomExit m_NewExit = new PrototypeRoomExit(ExitDirection, ExitLocation) { exitDirection = ExitDirection, exitType = ExitType, exitGroup = ExitGroup, containsDoor = ContainsDoor, exitLength = ExitLength, containedCells = new List <Vector2>(), }; if (ExitDirection == DungeonData.Direction.WEST | ExitDirection == DungeonData.Direction.EAST) { if (exitSize > 2) { m_NewExit.containedCells.Add(ExitLocation); m_NewExit.containedCells.Add(ExitLocation + new Vector2(0, 1)); for (int i = 2; i < exitSize; i++) { m_NewExit.containedCells.Add(ExitLocation + new Vector2(0, i)); } } else { m_NewExit.containedCells.Add(ExitLocation); m_NewExit.containedCells.Add(ExitLocation + new Vector2(0, 1)); } } else { if (exitSize > 2) { m_NewExit.containedCells.Add(ExitLocation); m_NewExit.containedCells.Add(ExitLocation + new Vector2(1, 0)); for (int i = 2; i < exitSize; i++) { m_NewExit.containedCells.Add(ExitLocation + new Vector2(i, 0)); } } else { m_NewExit.containedCells.Add(ExitLocation); m_NewExit.containedCells.Add(ExitLocation + new Vector2(1, 0)); } } if (overrideDoorObject) { m_NewExit.specifiedDoor = overrideDoorObject; } room.exitData.exits.Add(m_NewExit); }
public static void ApplyRoomData(PrototypeDungeonRoom room, RoomData roomData, bool setRoomCategory, bool autoAssignToFloor, bool assignDecorationProperties, float?Weight) { // Tools.Print("Building Exits..."); if (roomData.exitPositions != null) { for (int i = 0; i < roomData.exitPositions.Length; i++) { DungeonData.Direction dir = (DungeonData.Direction)Enum.Parse(typeof(DungeonData.Direction), roomData.exitDirections[i].ToUpper()); AddExit(room, roomData.exitPositions[i], dir); } } else { AddExit(room, new Vector2(room.Width / 2, room.Height), DungeonData.Direction.NORTH); AddExit(room, new Vector2(room.Width / 2, 0), DungeonData.Direction.SOUTH); AddExit(room, new Vector2(room.Width, room.Height / 2), DungeonData.Direction.EAST); AddExit(room, new Vector2(0, room.Height / 2), DungeonData.Direction.WEST); } // Tools.Print("Adding Enemies..."); if (roomData.enemyPositions != null) { for (int i = 0; i < roomData.enemyPositions.Length; i++) { AddEnemyToRoom(room, roomData.enemyPositions[i], roomData.enemyGUIDs[i], roomData.enemyReinforcementLayers[i], roomData.randomizeEnemyPositions); } } // Tools.Print("Adding Objects..."); if (roomData.placeablePositions != null) { for (int i = 0; i < roomData.placeablePositions.Length; i++) { AddPlaceableToRoom(room, roomData.placeablePositions[i], roomData.placeableGUIDs[i]); } } if (setRoomCategory | autoAssignToFloor) { // Set categories if (!string.IsNullOrEmpty(roomData.category)) { room.category = GetRoomCategory(roomData.category); } if (!string.IsNullOrEmpty(roomData.normalSubCategory)) { room.subCategoryNormal = GetRoomNormalSubCategory(roomData.normalSubCategory); } if (!string.IsNullOrEmpty(roomData.bossSubCategory)) { room.subCategoryBoss = GetRoomBossSubCategory(roomData.bossSubCategory); } if (!string.IsNullOrEmpty(roomData.specialSubCategory)) { room.subCategorySpecial = GetRoomSpecialSubCategory(roomData.specialSubCategory); } } if (autoAssignToFloor && roomData.floors != null) { if (!Weight.HasValue) { if (room.category == PrototypeDungeonRoom.RoomCategory.SECRET) { Weight = 15; // Normal secret rooms have weight of 15. } else { Weight = 1; } } if (room.category == PrototypeDungeonRoom.RoomCategory.SECRET) { // Secret rooms are generally shared across all floors via a specific room table. // Room Editor doesn't currently set this for secret rooms room.OverrideMusicState = DungeonFloorMusicController.DungeonMusicState.CALM; CakeMod.ModPrefabs.SecretRoomTable.includedRooms.elements.Add(CakeMod.ModRoomPrefabs.GenerateWeightedRoom(room, Weight.Value)); } else { foreach (string floor in roomData.floors) { AssignRoomToFloorRoomTable(room, GetTileSet(floor), Weight); } /*ExpandPrefabs.CustomRoomTableSecretGlitchFloor.includedRooms.elements.Add(ExpandRoomPrefabs.GenerateWeightedRoom(room, Weight.Value)); * ExpandPrefabs.CustomRoomTable.includedRooms.elements.Add(ExpandRoomPrefabs.GenerateWeightedRoom(room, Weight.Value)); * ExpandPrefabs.CustomRoomTable2.includedRooms.elements.Add(ExpandRoomPrefabs.GenerateWeightedRoom(room, Weight.Value));*/ } } if (assignDecorationProperties) { room.allowFloorDecoration = roomData.doFloorDecoration; room.allowWallDecoration = roomData.doWallDecoration; room.usesProceduralLighting = roomData.doLighting; } }
public int SpawnWallMimic(Dungeon dungeon, RoomHandler currentRoom, int WallMimicsPerRoom = 1) { int SouthWallCount = 0; int NorthWallCount = 0; int WestWallCount = 0; int EastWallCount = 0; int WallMimicsPlaced = 0; int loopCount = 0; List <Tuple <IntVector2, DungeonData.Direction> > validWalls = new List <Tuple <IntVector2, DungeonData.Direction> >(); try { 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 && dungeon.data[new IntVector2(X, Y)].parentRoom != null && dungeon.data[new IntVector2(X, Y)].parentRoom == currentRoom) { // if (dungeon.data.isWall(X, Y) && X % 4 == 0 && Y % 4 == 0) { if (dungeon.data.isWall(X, Y) && X % 4 == 0 && Y % 4 == 0 && dungeon.data.GetAbsoluteRoomFromPosition(new IntVector2(X, Y)) != null && dungeon.data.GetAbsoluteRoomFromPosition(new IntVector2(X, Y)) == currentRoom) { 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 WallStillValid = true; int XPadding = -5; while (XPadding <= 5 && WallStillValid) { int YPadding = -5; while (YPadding <= 5 && WallStillValid) { 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) { WallStillValid = false; } if (cellData.type == CellType.PIT | cellData.diagonalWallType != DiagonalWallType.NONE) { WallStillValid = false; } } } YPadding++; } XPadding++; } if (!WallStillValid) { while (WallCount > 0) { validWalls.RemoveAt(validWalls.Count - 1); WallCount--; } } } } } } if (validWalls.Count <= 0) { if (ExpandSettings.debugMode) { ETGModConsole.Log("[DEBUG] No valid locations found for room: " + currentRoom.GetRoomName() + " while attempting Wall Mimic placement!", false); } return(0); } while (loopCount < WallMimicsPerRoom && validWalls.Count > 0) { 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 WallMimic = AIActor.Spawn(orLoadByGuid, Position, currentRoom, true, AIActor.AwakenAnimationType.Default, true); if (PlayerHasWallMimicItem) { if (WallMimic && WallMimic.GetComponent <ExpandWallMimicManager>()) { ExpandWallMimicManager wallMimicController = WallMimic.gameObject.GetComponent <ExpandWallMimicManager>(); if (wallMimicController) { wallMimicController.CursedBrickMode = true; } } } validWalls.Remove(WallCell); WallMimicsPlaced++; } loopCount++; } } catch (Exception ex) { if (ExpandSettings.debugMode) { ETGModConsole.Log("[DEBUG] Exception while trying to place WallMimic(s) in room: " + currentRoom.GetRoomName(), false); Debug.LogException(ex); } return(WallMimicsPlaced); } if (WallMimicsPlaced > 0) { if (ExpandSettings.debugMode) { ETGModConsole.Log("[DEBUG] Wall Mimic(s) succesfully placed in room: " + currentRoom.GetRoomName(), false); 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 in room: " + WallMimicsPlaced, false); } return(WallMimicsPlaced); } else { ETGModConsole.Log("[DEBUG] No valid location found for room: " + currentRoom.GetRoomName() + " while attempting Wall Mimic placement!", false); return(0); } }
private HashSet <IntVector2> GetCeilingTileSet(IntVector2 pos1, IntVector2 pos2, DungeonData.Direction facingDirection) { IntVector2 intVector; IntVector2 intVector2; if (facingDirection == DungeonData.Direction.NORTH) { intVector = pos1 + new IntVector2(-1, 0); intVector2 = pos2 + new IntVector2(1, 1); } else if (facingDirection == DungeonData.Direction.SOUTH) { intVector = pos1 + new IntVector2(-1, 2); intVector2 = pos2 + new IntVector2(1, 3); } else if (facingDirection == DungeonData.Direction.EAST) { intVector = pos1 + new IntVector2(-1, 0); intVector2 = pos2 + new IntVector2(0, 3); } else { if (facingDirection != DungeonData.Direction.WEST) { return(null); } intVector = pos1 + new IntVector2(0, 0); intVector2 = pos2 + new IntVector2(1, 3); } HashSet <IntVector2> hashSet = new HashSet <IntVector2>(); for (int i = intVector.x; i <= intVector2.x; i++) { for (int j = intVector.y; j <= intVector2.y; j++) { IntVector2 item = new IntVector2(i, j); hashSet.Add(item); } } return(hashSet); }
private IEnumerator BecomeMimic() { if (m_hands == null) { StartCoroutine(DoIntro()); } if (!ChaosConsole.WallMimicsUseRewardManager) { m_ChaosModeActive = true; } if (m_GlitchModeActive) { m_ItemDropOdds += 0.2f; m_FriendlyMimicOdds += 0.2f; } m_isHidden = false; SpeculativeRigidbody specRigidbody = this.specRigidbody; specRigidbody.OnRigidbodyCollision = (SpeculativeRigidbody.OnRigidbodyCollisionDelegate)Delegate.Remove(specRigidbody.OnRigidbodyCollision, new SpeculativeRigidbody.OnRigidbodyCollisionDelegate(HandleRigidbodyCollision)); SpeculativeRigidbody specRigidbody2 = this.specRigidbody; specRigidbody2.OnBeamCollision = (SpeculativeRigidbody.OnBeamCollisionDelegate)Delegate.Remove(specRigidbody2.OnBeamCollision, new SpeculativeRigidbody.OnBeamCollisionDelegate(HandleBeamCollision)); AIAnimator tongueAnimator = aiAnimator.ChildAnimator; tongueAnimator.renderer.enabled = true; tongueAnimator.spriteAnimator.enabled = true; AIAnimator spitAnimator = tongueAnimator.ChildAnimator; spitAnimator.renderer.enabled = true; spitAnimator.spriteAnimator.enabled = true; tongueAnimator.PlayUntilFinished("spawn", false, null, -1f, false); float delay = tongueAnimator.CurrentClipLength; float timer = 0f; bool hasPlayedVFX = false; while (timer < delay) { yield return(null); timer += BraveTime.DeltaTime; if (!hasPlayedVFX && delay - timer < 0.1f) { hasPlayedVFX = true; if (WallDisappearVFX) { Vector2 zero = Vector2.zero; Vector2 zero2 = Vector2.zero; DungeonData.Direction facingDirection = m_facingDirection; if (facingDirection != DungeonData.Direction.SOUTH) { if (facingDirection != DungeonData.Direction.EAST) { if (facingDirection == DungeonData.Direction.WEST) { zero = new Vector2(0f, -1f); zero2 = new Vector2(0f, 1f); } } else { zero = new Vector2(0f, -1f); zero2 = new Vector2(0f, 1f); } } else { zero = new Vector2(0f, -1f); zero2 = new Vector2(0f, 1f); } Vector2 min = Vector2.Min(pos1.ToVector2(), pos2.ToVector2()) + zero; Vector2 max = Vector2.Max(pos1.ToVector2(), pos2.ToVector2()) + new Vector2(1f, 1f) + zero2; for (int i = 0; i < 5; i++) { Vector2 v = BraveUtility.RandomVector2(min, max, new Vector2(0.25f, 0.25f)) + new Vector2(0f, 1f); GameObject gameObject = SpawnManager.SpawnVFX(WallDisappearVFX, v, Quaternion.identity); tk2dBaseSprite tk2dBaseSprite = (!gameObject) ? null : gameObject.GetComponent <tk2dBaseSprite>(); if (tk2dBaseSprite) { tk2dBaseSprite.HeightOffGround = 8f; tk2dBaseSprite.UpdateZDepth(); } } } } } if (!m_failedWallConfigure && m_GlitchModeActive) { if (aiActor.ParentRoom != null && GlitchEnemyList != null && GlitchEnemyList.Count > 0 && UnityEngine.Random.value <= m_spawnGitchEnemyOdds) { float RandomIntervalFloat = UnityEngine.Random.Range(0.02f, 0.06f); float RandomDispFloat = UnityEngine.Random.Range(0.1f, 0.16f); float RandomDispIntensityFloat = UnityEngine.Random.Range(0.1f, 0.4f); float RandomColorProbFloat = UnityEngine.Random.Range(0.05f, 0.2f); float RandomColorIntensityFloat = UnityEngine.Random.Range(0.1f, 0.25f); int count2 = this.specRigidbody.PixelColliders.Count; this.specRigidbody.PixelColliders.RemoveAt(count2 - 1); this.specRigidbody.PixelColliders.RemoveAt(count2 - 2); StaticReferenceManager.AllShadowSystemDepthHavers.Remove(m_fakeWall.transform); Destroy(m_fakeWall); Destroy(m_fakeCeiling); Vector3 targetPosForSpawn = m_startingPos + DungeonData.GetIntVector2FromDirection(m_facingDirection).ToVector3(); while (timer < delay) { aiAnimator.LockFacingDirection = true; aiAnimator.FacingDirection = DungeonData.GetAngleFromDirection(m_facingDirection); yield return(null); timer += BraveTime.DeltaTime; transform.position = Vector3.Lerp(m_startingPos, targetPosForSpawn, Mathf.InverseLerp(0.42f, 0.58f, timer)); this.specRigidbody.Reinitialize(); } yield return(null); Vector3 FinalSpawnLocation = transform.position; Vector3 VFXExplosionLocation = transform.position; Vector2 VFXExplosionSource = Vector2.zero; DungeonData.Direction CurrentDirection = m_facingDirection; if (CurrentDirection == DungeonData.Direction.WEST) { FinalSpawnLocation += new Vector3(2.5f, 3.5f); VFXExplosionLocation += new Vector3(3.5f, 3.5f); VFXExplosionSource = new Vector2(1, 0); } else if (CurrentDirection == DungeonData.Direction.EAST) { FinalSpawnLocation += new Vector3(4f, 3.5f); VFXExplosionLocation += new Vector3(3f, 3.5f); } else if (CurrentDirection == DungeonData.Direction.NORTH) { FinalSpawnLocation += new Vector3(3.5f, 4f); VFXExplosionLocation += new Vector3(3.5f, 3f); VFXExplosionSource = new Vector2(0, 1); } else if (CurrentDirection == DungeonData.Direction.SOUTH) { FinalSpawnLocation += new Vector3(3.5f, 1.5f); VFXExplosionLocation += new Vector3(3.5f, 2.5f); } yield return(null); string SelectedEnemy = BraveUtility.RandomElement(GlitchEnemyList); ExplosionData wallMimicExplosionData = new ExplosionData(); wallMimicExplosionData.CopyFrom(GameManager.Instance.Dungeon.sharedSettingsPrefab.DefaultExplosionData); wallMimicExplosionData.damage = 0f; wallMimicExplosionData.force /= 1.6f; if (SelectedEnemy != "RATCORPSE") { Exploder.Explode(VFXExplosionLocation, wallMimicExplosionData, VFXExplosionSource, ignoreQueues: true, damageTypes: CoreDamageTypes.None); GameObject SpawnVFXObject = Instantiate((GameObject)ResourceCache.Acquire("Global VFX/VFX_Item_Spawn_Poof")); tk2dBaseSprite SpawnVFXObjectComponent = SpawnVFXObject.GetComponent <tk2dBaseSprite>(); SpawnVFXObjectComponent.PlaceAtPositionByAnchor(FinalSpawnLocation + new Vector3(0f, 0.5f, 0f), tk2dBaseSprite.Anchor.MiddleCenter); SpawnVFXObjectComponent.HeightOffGround = 1f; SpawnVFXObjectComponent.UpdateZDepth(); AIActor glitchActor = AIActor.Spawn(EnemyDatabase.GetOrLoadByGuid(SelectedEnemy), FinalSpawnLocation, aiActor.ParentRoom, true, AIActor.AwakenAnimationType.Awaken, true); /*if (aiActor.ParentRoom != null && !aiActor.ParentRoom.IsSealed && !glitchActor.IgnoreForRoomClear) { * if (GameManager.Instance.PrimaryPlayer.CurrentRoom == aiActor.ParentRoom && aiActor.ParentRoom.EverHadEnemies) { * aiActor.ParentRoom.SealRoom(); * } * }*/ PickupObject.ItemQuality targetGlitchEnemyItemQuality = (UnityEngine.Random.value >= 0.2f) ? ((!BraveUtility.RandomBool()) ? PickupObject.ItemQuality.C : PickupObject.ItemQuality.D) : PickupObject.ItemQuality.B; GenericLootTable glitchEnemyLootTable = (!BraveUtility.RandomBool()) ? GameManager.Instance.RewardManager.GunsLootTable : GameManager.Instance.RewardManager.ItemsLootTable; PickupObject glitchEnemyItem = LootEngine.GetItemOfTypeAndQuality <PickupObject>(targetGlitchEnemyItemQuality, glitchEnemyLootTable, false); /*if (BraveUtility.RandomBool()) { * ChaosUtility.MakeCompanion(glitchActor); * } else { * ChaosShaders.Instance.ApplyGlitchShader(glitchActor, glitchActor.sprite, true, RandomIntervalFloat, RandomDispFloat, RandomDispIntensityFloat, RandomColorProbFloat, RandomColorIntensityFloat); * }*/ ChaosShaders.Instance.ApplyGlitchShader(glitchActor, glitchActor.sprite, true, RandomIntervalFloat, RandomDispFloat, RandomDispIntensityFloat, RandomColorProbFloat, RandomColorIntensityFloat); if (glitchEnemyItem) { glitchActor.AdditionalSafeItemDrops.Add(glitchEnemyItem); } } else { Exploder.Explode(VFXExplosionLocation, wallMimicExplosionData, VFXExplosionSource, ignoreQueues: true, damageTypes: CoreDamageTypes.None); GameObject SpawnVFXObject = Instantiate((GameObject)ResourceCache.Acquire("Global VFX/VFX_Item_Spawn_Poof")); tk2dBaseSprite SpawnVFXObjectComponent = SpawnVFXObject.GetComponent <tk2dBaseSprite>(); SpawnVFXObjectComponent.PlaceAtPositionByAnchor(FinalSpawnLocation + new Vector3(0f, 0.5f, 0f), tk2dBaseSprite.Anchor.MiddleCenter); SpawnVFXObjectComponent.HeightOffGround = 1f; SpawnVFXObjectComponent.UpdateZDepth(); GameObject spawnedRatCorpseObject = Instantiate(ChaosPrefabs.RatCorpseNPC, FinalSpawnLocation, Quaternion.identity); TalkDoerLite talkdoerComponent = spawnedRatCorpseObject.GetComponent <TalkDoerLite>(); talkdoerComponent.transform.position.XY().GetAbsoluteRoom().RegisterInteractable(talkdoerComponent); talkdoerComponent.transform.position.XY().GetAbsoluteRoom().TransferInteractableOwnershipToDungeon(talkdoerComponent); talkdoerComponent.playmakerFsm.SetState("Set Mode"); ChaosUtility.AddHealthHaver(talkdoerComponent.gameObject, 60, flashesOnDamage: false, exploderSpawnsItem: true); } yield return(null); Destroy(aiActor.gameObject); yield break; } } PickupObject.ItemQuality targetQuality = (UnityEngine.Random.value >= 0.2f) ? ((!BraveUtility.RandomBool()) ? PickupObject.ItemQuality.C : PickupObject.ItemQuality.D) : PickupObject.ItemQuality.B; GenericLootTable lootTable = (!BraveUtility.RandomBool()) ? GameManager.Instance.RewardManager.GunsLootTable : GameManager.Instance.RewardManager.ItemsLootTable; PickupObject item = LootEngine.GetItemOfTypeAndQuality <PickupObject>(targetQuality, lootTable, false); if (item) { if (m_ChaosModeActive) { if (UnityEngine.Random.value <= m_ItemDropOdds) { aiActor.AdditionalSafeItemDrops.Add(item); } else { aiActor.AdditionalSafeItemDrops.Add(PickupObjectDatabase.GetById(70)); if (BraveUtility.RandomBool()) { aiActor.AdditionalSafeItemDrops.Add(PickupObjectDatabase.GetById(70)); } if (m_GlitchModeActive) { aiActor.AdditionalSafeItemDrops.Add(PickupObjectDatabase.GetById(70)); } } if (UnityEngine.Random.value <= m_FriendlyMimicOdds) { m_isFriendlyMimic = true; } } else { aiActor.AdditionalSafeItemDrops.Add(item); } } else { if (m_ChaosModeActive && UnityEngine.Random.value <= m_FriendlyMimicOdds) { m_isFriendlyMimic = true; } } aiActor.enabled = true; behaviorSpeculator.enabled = true; if (aiActor.ParentRoom != null && aiActor.ParentRoom.IsSealed && !m_isFriendlyMimic) { aiActor.IgnoreForRoomClear = false; } // if (m_isFriendlyMimic) { ChaosUtility.MakeCompanion(aiActor); } if (m_isFriendlyMimic) { aiActor.ApplyEffect(GameManager.Instance.Dungeon.sharedSettingsPrefab.DefaultPermanentCharmEffect, 1f, null); } if (!m_failedWallConfigure) { int count = this.specRigidbody.PixelColliders.Count; for (int j = 0; j < count - 2; j++) { this.specRigidbody.PixelColliders[j].Enabled = true; } this.specRigidbody.PixelColliders.RemoveAt(count - 1); this.specRigidbody.PixelColliders.RemoveAt(count - 2); StaticReferenceManager.AllShadowSystemDepthHavers.Remove(m_fakeWall.transform); Destroy(m_fakeWall); Destroy(m_fakeCeiling); } else { int count = this.specRigidbody.PixelColliders.Count; for (int j = 0; j < count; j++) { this.specRigidbody.PixelColliders[j].Enabled = true; } } for (int k = 0; k < m_hands.Length; k++) { m_hands[k].gameObject.SetActive(true); } aiActor.ToggleRenderers(true); if (aiShooter) { aiShooter.ToggleGunAndHandRenderers(true, "ChaosWallMimicController"); } aiActor.IsGone = false; healthHaver.IsVulnerable = true; aiActor.State = AIActor.ActorState.Normal; for (int l = 0; l < m_hands.Length; l++) { m_hands[l].gameObject.SetActive(false); } m_isFinished = true; delay = 0.58f; timer = 0f; Vector3 targetPos = m_startingPos + DungeonData.GetIntVector2FromDirection(m_facingDirection).ToVector3(); while (timer < delay) { aiAnimator.LockFacingDirection = true; aiAnimator.FacingDirection = DungeonData.GetAngleFromDirection(m_facingDirection); yield return(null); timer += BraveTime.DeltaTime; transform.position = Vector3.Lerp(m_startingPos, targetPos, Mathf.InverseLerp(0.42f, 0.58f, timer)); this.specRigidbody.Reinitialize(); } aiAnimator.LockFacingDirection = false; knockbackDoer.SetImmobile(false, "ChaosWallMimicController"); aiActor.CollisionDamage = 0.5f; aiActor.CollisionKnockbackStrength = m_collisionKnockbackStrength; yield break; }
private void ChaosPlaceWallMimics(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; try { int currentFloor = GameManager.Instance.CurrentFloor; int numWallMimicsForFloor = MetaInjectionData.GetNumWallMimicsForFloor(dungeon.tileIndices.tilesetId); GameManager.LevelOverrideState levelOverrideState = GameManager.Instance.CurrentLevelOverrideState; // Set Max Wall Mimic values based on each floor. Secret floors and Tutorial are always -1 and will keep default values. SetStats(dungeon, currentFloor, PlayerStats.GetTotalCurse(), PlayerStats.GetTotalCoolness()); if (!ChaosConsole.WallMimicsUseRewardManager) { numWallMimicsForFloor = ChaosConsole.MaxWallMimicsForFloor; } if (ChaosConsole.debugMimicFlag) { ETGModConsole.Log("[DEBUG] Current Floor: " + currentFloor, false); ETGModConsole.Log("[DEBUG] Wall Mimics assigned by RewardManager: " + numWallMimicsForFloor, false); } if (ChaosConsole.WallMimicsUseRewardManager) { ChaosConsole.MaxWallMimicsPerRoom = 1; ChaosConsole.MaxWallMimicsForFloor = numWallMimicsForFloor; } if (ChaosConsole.isHardMode | ChaosConsole.isUltraMode) { if (currentFloor == 1) { PlaceTeleporter(dungeon); } PlaceGlitchElevator(dungeon); } if (ChaosConsole.isUltraMode) { if (levelOverrideState == GameManager.LevelOverrideState.RESOURCEFUL_RAT | levelOverrideState == GameManager.LevelOverrideState.TUTORIAL | levelOverrideState != GameManager.LevelOverrideState.NONE) { if (ChaosConsole.debugMimicFlag) { ETGModConsole.Log("[DEBUG] This floor has been excluded from having additional pits.", false); } } else { ChaosPitRandomizer.Instance.PlaceRandomPits(dungeon, roomHandler, currentFloor); } } if (currentFloor == 4 && ChaosConsole.allowGlitchFloor) { PlaceSecretRatGrate(dungeon); } // Wall Mimics will not be placed glitch floors. if (ChaosGlitchMod.isGlitchFloor | dungeon.IsGlitchDungeon) { return; } if (ChaosConsole.MaxWallMimicsForFloor <= 0) { if (ChaosConsole.debugMimicFlag) { ETGModConsole.Log("[DEBUG] There will be no Wall Mimics assigned to this floor.", false); } return; } if (levelOverrideState != GameManager.LevelOverrideState.NONE | levelOverrideState == GameManager.LevelOverrideState.TUTORIAL) { if (ChaosConsole.debugMimicFlag) { ETGModConsole.Log("[DEBUG] This floor has been excluded from having Wall Mimics", false); } return; } if (!ChaosConsole.WallMimicsUseRewardManager && levelOverrideState == GameManager.LevelOverrideState.RESOURCEFUL_RAT) { if (ChaosConsole.debugMimicFlag) { ETGModConsole.Log("[DEBUG] The Resourceful Rat Maze has been excluded from having wall mimics.", false); } return; } if (ChaosConsole.debugMimicFlag) { ETGModConsole.Log("[DEBUG] Wall Mimics Per Room: " + ChaosConsole.MaxWallMimicsPerRoom, false); ETGModConsole.Log("[DEBUG] Max Wall Mimic assigned to floor if RewardManager overridden: " + ChaosConsole.MaxWallMimicsForFloor, 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 || !ChaosConsole.WallMimicsUseRewardManager) { if (!currentRoom.area.IsProceduralRoom || currentRoom.area.proceduralCells == null) { if (currentRoom.area.PrototypeRoomCategory != PrototypeDungeonRoom.RoomCategory.BOSS || (PlayerStats.GetTotalCurse() >= 5 && !BraveUtility.RandomBool())) { if (!currentRoom.GetRoomName().StartsWith("DraGunRoom") && !currentRoom.IsMaintenanceRoom()) { 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 && ChaosConsole.WallMimicsUseRewardManager) { 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) { int loopCount = 0; while (loopCount < ChaosConsole.MaxWallMimicsPerRoom) { // if (!ChaosConsole.WallMimicsUseRewardManager) { if (WallMimicsPlaced >= ChaosConsole.MaxWallMimicsForFloor) { break; } } 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++; } ++loopCount; } } } } } } IL_EXIT: iterations++; } if (WallMimicsPlaced > 0) { PhysicsEngine.Instance.ClearAllCachedTiles(); if (ChaosConsole.debugMimicFlag) { 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 (ChaosConsole.DebugExceptions) { 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 (ChaosConsole.debugMimicFlag) { 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); } } } }
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 static void ApplyRoomData(PrototypeDungeonRoom room, RoomData roomData) { if (roomData.exitPositions != null) { for (int i = 0; i < roomData.exitPositions.Length; i++) { DungeonData.Direction dir = (DungeonData.Direction)Enum.Parse(typeof(DungeonData.Direction), roomData.exitDirections[i].ToUpper()); AddExit(room, roomData.exitPositions[i], dir); } } else { AddExit(room, new Vector2(room.Width / 2, room.Height), DungeonData.Direction.NORTH); AddExit(room, new Vector2(room.Width / 2, 0), DungeonData.Direction.SOUTH); AddExit(room, new Vector2(room.Width, room.Height / 2), DungeonData.Direction.EAST); AddExit(room, new Vector2(0, room.Height / 2), DungeonData.Direction.WEST); } if (roomData.enemyPositions != null) { for (int i = 0; i < roomData.enemyPositions.Length; i++) { AddEnemyToRoom(room, roomData.enemyPositions[i], roomData.enemyGUIDs[i], roomData.enemyReinforcementLayers[i]); } } if (roomData.placeablePositions != null) { for (int i = 0; i < roomData.placeablePositions.Length; i++) { AddPlaceableToRoom(room, roomData.placeablePositions[i], roomData.placeableGUIDs[i]); } } if (roomData.floors != null) { foreach (var floor in roomData.floors) { room.prerequisites.Add(new DungeonPrerequisite() { prerequisiteType = DungeonPrerequisite.PrerequisiteType.TILESET, requiredTileset = Tools.GetEnumValue <GlobalDungeonData.ValidTilesets>(floor) }); } } //Set categories if (!string.IsNullOrEmpty(roomData.category)) { room.category = Tools.GetEnumValue <PrototypeDungeonRoom.RoomCategory>(roomData.category); } if (!string.IsNullOrEmpty(roomData.normalSubCategory)) { room.subCategoryNormal = Tools.GetEnumValue <PrototypeDungeonRoom.RoomNormalSubCategory>(roomData.normalSubCategory); } if (!string.IsNullOrEmpty(roomData.bossSubCategory)) { room.subCategoryBoss = Tools.GetEnumValue <PrototypeDungeonRoom.RoomBossSubCategory>(roomData.bossSubCategory); } if (!string.IsNullOrEmpty(roomData.specialSubCatergory)) { room.subCategorySpecial = Tools.GetEnumValue <PrototypeDungeonRoom.RoomSpecialSubCategory>(roomData.specialSubCatergory); } }
public bool HasDoor(DungeonData.Direction dir) { return((roomShapeFlag & (1 << (int)dir)) == (1 << (int)dir)); }