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); }
// 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); }
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); }
private IEnumerator ScoopPlayerToSafety() { PlayerController m_owner = m_aiActor.CompanionOwner; RoomHandler currentRoom = m_owner.CurrentRoom; if (currentRoom.area.PrototypeRoomNormalSubcategory != PrototypeDungeonRoom.RoomNormalSubCategory.TRAP) { m_aiActor.aiAnimator.PlayUntilCancelled("idle", false, null, -1f, false); yield break; } bool hasFoundExit = false; float maxDistance = float.MinValue; // This whole thing has been converted to Vector2 to avoid player being embeded into walls by failsafe teleport system (and to prevent Raccoon from doing this too) Vector2 mostDistantExit = new Vector2(-1, -1); for (int i = 0; i < currentRoom.connectedRooms.Count; i++) { PrototypeRoomExit exitConnectedToRoom = currentRoom.GetExitConnectedToRoom(currentRoom.connectedRooms[i]); if (exitConnectedToRoom != null) { IntVector2 a = exitConnectedToRoom.GetExitAttachPoint() - IntVector2.One; Vector2 exitVector = (a + currentRoom.area.basePosition + DungeonData.GetIntVector2FromDirection(exitConnectedToRoom.exitDirection)).ToVector2(); // These adjustements should in most cases result in the Raccoon dropping the player near the exit and not inside the exit which can cause issues sometimes. if (exitConnectedToRoom.exitDirection == DungeonData.Direction.WEST) { exitVector += new Vector2(2, 0.8f); } if (exitConnectedToRoom.exitDirection == DungeonData.Direction.EAST) { exitVector -= new Vector2(2.4f, 0); exitVector += new Vector2(0, 0.8f); } if (exitConnectedToRoom.exitDirection == DungeonData.Direction.NORTH) { exitVector -= new Vector2(0, 2.4f); exitVector += new Vector2(0.8f, 0); } if (exitConnectedToRoom.exitDirection == DungeonData.Direction.SOUTH) { exitVector += new Vector2(0.8f, 2.4f); } hasFoundExit = true; float num = Vector2.Distance(m_owner.CenterPosition, exitVector); if (num > maxDistance) { maxDistance = num; mostDistantExit = exitVector; } } } yield return(null); if (!hasFoundExit) { yield break; } // If Raccoon gets stuck or gives up trying to path to exit, this will be set to true and checked later. bool hasFailed = false; CompanionFollowPlayerBehavior followBehavior = m_aiActor.behaviorSpeculator.MovementBehaviors[0] as CompanionFollowPlayerBehavior; followBehavior.TemporarilyDisabled = true; m_aiActor.PathableTiles = (CellTypes.FLOOR | CellTypes.PIT); m_aiActor.ClearPath(); m_owner.SetInputOverride("raccoon"); m_owner.IsEthereal = true; m_owner.healthHaver.IsVulnerable = false; float cachedSpeed = m_aiActor.MovementSpeed; yield return(new WaitForSeconds(1f)); m_aiActor.MovementSpeed = 4f; m_pathingTimeoutTimer2 = 120f; yield return(null); m_aiActor.aiAnimator.PlayUntilCancelled("raccoon_move", false, null, -1f, false); m_aiActor.PathfindToPosition(m_owner.transform.position + new Vector3(1f, 0.1f), null, true, null, null, null, false); // Add another timer. If player is close to south walls, Raccoon can't get into position. // If this happens he'll grab the player from the closest point he could get to and continue. while (!m_aiActor.PathComplete) { DecrementTimer(ref m_pathingTimeoutTimer2, false); if (m_pathingTimeoutTimer2 <= 0) { m_aiActor.ClearPath(); break; } yield return(null); } m_aiActor.sprite.SpriteChanged += UpdatePlayerPosition; m_aiActor.aiAnimator.PlayUntilFinished("grab", false, null, -1f, false); yield return(null); Transform attachPoint = m_aiActor.transform.Find("carry"); while (m_aiActor.aiAnimator.IsPlaying("grab")) { Vector2 preferredPrimaryPosition = attachPoint.position.XY() + (m_owner.transform.position.XY() - m_owner.sprite.WorldBottomCenter) + new Vector2(0f, -0.125f); m_owner.transform.position = preferredPrimaryPosition; m_owner.specRigidbody.Reinitialize(); yield return(null); } m_owner.SetIsFlying(true, "raccoon", true, false); m_aiActor.MovementSpeed = 12f; m_aiActor.ClearPath(); m_aiActor.PathfindToPosition(mostDistantExit, null, true, null, null, null, false); m_aiActor.aiAnimator.PlayUntilCancelled("carry", true, null, -1f, false); // Set timeout. If Raccoon gets stuck or for some reason won't let go of the player, he'll be forced to end this operation. m_pathingTimeoutTimer = 280f; yield return(null); while (!m_aiActor.PathComplete) { if (!hasFailed && !m_aiActor.Path.WillReachFinalGoal) { hasFailed = true; } DecrementTimer(ref m_pathingTimeoutTimer, false); if (m_pathingTimeoutTimer <= 0) { hasFailed = true; break; } if (m_owner && m_owner.transform.position.XY() != null) { Vector2 v = attachPoint.position.XY() + (m_owner.transform.position.XY() - m_owner.sprite.WorldBottomCenter) + new Vector2(0f, -0.125f); m_owner.transform.position = v; m_owner.specRigidbody.Reinitialize(); } else { m_aiActor.ClearPath(); hasFailed = true; break; } yield return(null); } yield return(new WaitForSeconds(0.8f)); m_aiActor.sprite.SpriteChanged -= UpdatePlayerPosition; m_aiActor.MovementSpeed = cachedSpeed; yield return(null); // If Raccoon gets stuck or Raccoon gives up due to pathing fail, we'll use a graceful teleport to the intended exit with screen // fade instead of just dropping the player where ever the Racoon gave up at or leaving the player in limbo forever like the original // code would have done. (don't want Raccoon giving up and dropping player over a pit or near trap obstacle either. This is a no no! :P ) if (hasFailed) { Pixelator.Instance.FadeToBlack(1f, false, 0f); yield return(new WaitForSeconds(1.1f)); m_owner.WarpToPointAndBringCoopPartner(mostDistantExit, false, true); yield return(new WaitForSeconds(0.1f)); Pixelator.Instance.FadeToBlack(1f, true, 0f); yield return(new WaitForSeconds(1f)); } m_owner.healthHaver.IsVulnerable = true; m_owner.SetIsFlying(false, "raccoon", true, false); m_owner.ClearInputOverride("raccoon"); m_owner.IsEthereal = false; yield return(null); m_aiActor.PathableTiles = CellTypes.FLOOR; followBehavior.TemporarilyDisabled = false; m_aiActor.aiAnimator.PlayUntilCancelled("idle", false, null, -1f, false); m_pathingTimeoutTimer = 0f; m_pathingTimeoutTimer2 = 0f; yield break; }