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);
        }
示例#3
0
        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;
        }