private static void ExportInfo(InputFrame inputFrame)
        {
            InputController controller = Manager.Controller;
            string          output;

            if (Engine.Scene is Level level)
            {
                Player player = level.Tracker.GetEntity <Player>();
                if (player == null)
                {
                    return;
                }

                string time  = GameInfo.GetChapterTime(level);
                string pos   = player.ToSimplePositionString(CelesteTasModuleSettings.MaxDecimals);
                string speed = player.Speed.ToSimpleString(Settings.SpeedDecimals);

                int    dashCooldown = (int)GameInfo.GetDashCooldownTimer(player);
                string statuses     = GameInfo.GetStatuses(level, player, dashCooldown);

                output = string.Join("\t",
                                     inputFrame.Line + 1, $"{controller.CurrentFrameInInput}/{inputFrame}", controller.CurrentFrameInTas, time, pos, speed,
                                     PlayerStates.GetStateName(player.StateMachine.State),
                                     statuses);

                foreach (string typeName in trackedEntities.Keys)
                {
                    List <Entity> entities = trackedEntities[typeName].Invoke();
                    if (entities == null)
                    {
                        continue;
                    }

                    foreach (Entity entity in entities)
                    {
                        output += $"\t{typeName}: {entity.ToSimplePositionString(Settings.CustomInfoDecimals)}";
                    }
                }

                if (InfoCustom.Parse() is { } customInfo&& customInfo.IsNotEmpty())
                {
                    output += $"\t{customInfo.ReplaceLineBreak(" ")}";
                }

                if (InfoWatchEntity.GetWatchingEntitiesInfo("\t", true) is { } watchInfo&& watchInfo.IsNotEmpty())
                {
                    output += $"\t{watchInfo}";
                }
            }
            else
            {
                string sceneName;
                if (Engine.Scene is Overworld overworld)
                {
                    sceneName = $"Overworld {(overworld.Current ?? overworld.Next).GetType().Name}";
                }
                else
                {
                    sceneName = Engine.Scene.GetType().Name;
                }

                output = string.Join("\t", inputFrame.Line + 1, $"{controller.CurrentFrameInInput}/{inputFrame}", controller.CurrentFrameInTas,
                                     sceneName);
            }

            streamWriter.WriteLine(output);
            streamWriter.Flush();
        }
Пример #2
0
        public static void Update(bool updateVel = false)
        {
            if (Engine.Scene is Level level)
            {
                Player player = level.Tracker.GetEntity <Player>();
                if (player != null)
                {
                    string        pos   = GetAdjustedPos(player, out string exactPos);
                    string        speed = GetAdjustedSpeed(player.Speed, out string exactSpeed);
                    Vector2Double diff  = player.GetMoreExactPosition(false) - LastPos;
                    if (!Frozen && updateVel)
                    {
                        LastDiff = diff;
                    }
                    else
                    {
                        diff = LastDiff;
                    }

                    if (TasSettings.SpeedUnit == SpeedUnit.PixelPerSecond)
                    {
                        diff *= FramesPerRealSecond;
                    }

                    string velocity = GetAdjustedVelocity(diff, out string exactVelocity);

                    string polarVel = $"Fly:   {diff.Length():F2}, {diff.Angle():F5}°";

                    string analog = string.Empty;
                    if (Manager.Running && Manager.Controller.Previous is { } inputFrame&& inputFrame.HasActions(Actions.Feather))
                    {
                        Vector2 angleVector2 = inputFrame.AngleVector2;
                        analog =
                            $"Analog: {angleVector2.X:F5}, {angleVector2.Y:F5}, {GetAngle(new Vector2(angleVector2.X, -angleVector2.Y)):F5}°";
                    }

                    string retainedSpeed = GetAdjustedRetainedSpeed(player, out string exactRetainedSpeed);

                    string liftBoost = GetAdjustedLiftBoost(player, out string exactLiftBoost);

                    string miscStats = $"Stamina: {player.Stamina:0} "
                                       + (WallJumpCheck(player, 1) ? "Wall-R " : string.Empty)
                                       + (WallJumpCheck(player, -1) ? "Wall-L " : string.Empty)
                                       + PlayerStates.GetStateName(player.StateMachine.State);

                    int dashCooldown = DashCooldownTimer(player).ToFloorFrames();

                    PlayerSeeker playerSeeker = level.Tracker.GetEntity <PlayerSeeker>();
                    if (playerSeeker != null)
                    {
                        pos   = GetAdjustedPos(playerSeeker, out exactPos);
                        speed = GetAdjustedSpeed(PlayerSeekerSpeed(playerSeeker), out exactSpeed);
                        diff  = playerSeeker.GetMoreExactPosition(false) - LastPlayerSeekerPos;
                        if (!Frozen && updateVel)
                        {
                            LastPlayerSeekerDiff = diff;
                        }
                        else
                        {
                            diff = LastPlayerSeekerDiff;
                        }

                        if (TasSettings.SpeedUnit == SpeedUnit.PixelPerSecond)
                        {
                            diff *= FramesPerRealSecond;
                        }

                        velocity = GetAdjustedVelocity(diff, out exactVelocity);

                        polarVel     = $"Chase: {diff.Length():F2}, {diff.Angle():F5}°";
                        dashCooldown = PlayerSeekerDashTimer(playerSeeker).ToCeilingFrames();
                    }

                    string statuses = GetStatuses(level, player, dashCooldown);

                    string   timers = string.Empty;
                    Follower firstRedBerryFollower = player.Leader.Followers.Find(follower => follower.Entity is Strawberry {
                        Golden: false
                    });
        public static void Update(bool updateVel = false)
        {
            if (Engine.Scene is Level level)
            {
                Player player      = level.Tracker.GetEntity <Player>();
                long   chapterTime = level.Session.Time;
                if (player != null)
                {
                    StringBuilder stringBuilder = new();
                    string        pos           = GetAdjustedPos(player.Position, player.PositionRemainder);
                    string        speed         = GetAdjustedSpeed(player.Speed);
                    Vector2Double diff          = (player.GetMoreExactPosition() - LastPos) * FramesPerSecond;
                    string        velocity      = GetAdjustedVelocity(diff);
                    if (!Frozen && updateVel)
                    {
                        LastVel = velocity;
                    }
                    else
                    {
                        velocity = LastVel;
                    }

                    string polarVel = $"Fly:   {diff.Length():F2}, {diff.Angle():F5}°";

                    string analog = string.Empty;
                    if (Manager.Running && Manager.Controller.Previous is { } inputFrame&& inputFrame.HasActions(Actions.Feather))
                    {
                        Vector2 angleVector2 = inputFrame.AngleVector2;
                        analog =
                            $"Analog: {angleVector2.X:F5}, {angleVector2.Y:F5}, {Manager.GetAngle(new Vector2(angleVector2.X, -angleVector2.Y)):F5}°";
                    }

                    string retainedSpeed = string.Empty;
                    if (PlayerRetainedSpeedTimer(player) is float retainedSpeedTimer and > 0f)
                    {
                        retainedSpeed = $"Retained: {PlayerRetainedSpeed(player):F2} ({retainedSpeedTimer.ToCeilingFrames()})";
                    }

                    string liftBoost = string.Empty;
                    if (PlayerLiftBoost(player) is var liftBoostVector2 && liftBoostVector2 != Vector2.Zero)
                    {
                        liftBoost =
                            $"LiftBoost: {liftBoostVector2.X:F2}, {liftBoostVector2.Y:F2} ({ActorLiftSpeedTimer(player).ToCeilingFrames()})";
                    }

                    string miscStats = $"Stamina: {player.Stamina:0} "
                                       + (WallJumpCheck(player, 1) ? "Wall-R " : string.Empty)
                                       + (WallJumpCheck(player, -1) ? "Wall-L " : string.Empty)
                                       + PlayerStates.GetStateName(player.StateMachine.State);

                    int dashCooldown = DashCooldownTimer(player).ToFloorFrames();

                    PlayerSeeker playerSeeker = level.Tracker.GetEntity <PlayerSeeker>();
                    if (playerSeeker != null)
                    {
                        pos      = GetAdjustedPos(playerSeeker.Position, playerSeeker.PositionRemainder);
                        speed    = GetAdjustedSpeed(PlayerSeekerSpeed(playerSeeker));
                        diff     = (playerSeeker.GetMoreExactPosition() - LastPlayerSeekerPos) * FramesPerSecond;
                        velocity = GetAdjustedVelocity(diff);
                        if (!Frozen && updateVel)
                        {
                            LastPlayerSeekerVel = velocity;
                        }
                        else
                        {
                            velocity = LastPlayerSeekerVel;
                        }

                        polarVel     = $"Chase: {diff.Length():F2}, {diff.Angle():F5}°";
                        dashCooldown = PlayerSeekerDashTimer(playerSeeker).ToCeilingFrames();
                    }

                    string statuses = (dashCooldown <= 0 && player.Dashes > 0 ? "CanDash " : string.Empty)
                                      + (player.LoseShards ? "Ground " : string.Empty)
                                      + (!player.LoseShards && JumpGraceTimer(player).ToFloorFrames() is int coyote and > 0
                                          ? $"Coyote({coyote}) "
                                          : string.Empty);

                    string noControlFrames = transitionFrames > 0 ? $"({transitionFrames})" : string.Empty;
                    float  unpauseTimer    = LevelUnpauseTimer?.Invoke(level) ?? 0f;
                    if (unpauseTimer > 0f)
                    {
                        noControlFrames = $"({unpauseTimer.ToCeilingFrames()})";
                    }

                    statuses = (Engine.FreezeTimer > 0f ? $"Frozen({Engine.FreezeTimer.ToCeilingFrames()}) " : string.Empty)
                               + (player.InControl && !level.Transitioning && unpauseTimer <= 0f ? statuses : $"NoControl{noControlFrames} ")
                               + (player.Dead ? "Dead " : string.Empty)
                               + (level.InCutscene ? "Cutscene " : string.Empty)
                               + (AdditionalStatusInfo ?? string.Empty);

                    if (player.Holding == null &&
                        level.Tracker.GetComponents <Holdable>().Any(holdable => ((Holdable)holdable).Check(player)))
                    {
                        statuses += "Grab ";
                    }

                    string   timers = string.Empty;
                    Follower firstRedBerryFollower = player.Leader.Followers.Find(follower => follower.Entity is Strawberry {
                        Golden: false
                    });