private static void Save() { InputController temp = Manager.controller.Clone(); //+1 speedrun tool, -5 buffered inputs temp.ReverseFrames(4); Engine.Scene.OnEndOfFrame += () => { if (StateManager.Instance.SaveState()) { savedController = temp; Manager.controller = savedController.Clone(); /* * List<VirtualInput> inputs = (List<VirtualInput>) * typeof(MInput).GetField("VirtualInputs", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null); * foreach (VirtualInput input in inputs) { * if (input is VirtualButton) * savedBuffers.Add((float)input.GetPrivateField("bufferCounter")); * } */ routine = new Coroutine(LoadStateRoutine()); } }; }
public static bool TryExecuteCommand(InputController state, string line, int studioLine) { try { if (char.IsLetter(line[0])) { string[] args = Split(line); string commandType = args[0] + "Command"; MethodInfo method = typeof(InputCommands).GetMethod(commandType, BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.IgnoreCase); if (method == null) { return(false); } string[] commandArgs = new string[args.Length - 1]; for (int i = 1; i < args.Length; i++) { commandArgs[i - 1] = args[i]; } TASCommandAttribute attribute = (TASCommandAttribute)method.GetCustomAttribute(typeof(TASCommandAttribute)); if (!(Manager.enforceLegal && attribute.illegalInMaingame)) { if (attribute.executeAtStart) { return((bool)method.Invoke(null, new object[] { state, commandArgs, studioLine })); } else { Action commandCall = () => method.Invoke(null, new object[] { commandArgs }); state.inputs.Add(new InputRecord(commandCall)); } } } return(false); } catch { return(false); } }
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(); }
private static void EnforceLegalCommand(InputController state, string[] args, int studioLine) { Manager.enforceLegal = true; }
private static void UnsafeCommand(InputController state, string[] args, int studioLine) { Manager.allowUnsafeInput = true; }