From fab83a1867947cdbead9c37f6f4228ca3add61c6 Mon Sep 17 00:00:00 2001 From: Jakob Hellermann Date: Wed, 25 Sep 2024 21:35:44 +0200 Subject: [PATCH] feat: fill in wakeup frames if possible when creating a new file --- .../CommunicationAdapterCeleste.cs | 10 +++++++ .../Communication/GameData.cs | 28 +++++++++++++++++++ .../CommunicationAdapterStudio.cs | 4 +++ .../Communication/CommunicationWrapper.cs | 7 +++++ Studio/CelesteStudio/Studio.cs | 19 ++++++++----- StudioCommunication/LevelData.cs | 9 ++++++ StudioCommunication/MessageID.cs | 1 + 7 files changed, 71 insertions(+), 7 deletions(-) create mode 100644 StudioCommunication/LevelData.cs diff --git a/CelesteTAS-EverestInterop/Communication/CommunicationAdapterCeleste.cs b/CelesteTAS-EverestInterop/Communication/CommunicationAdapterCeleste.cs index f781f731..ea83e372 100644 --- a/CelesteTAS-EverestInterop/Communication/CommunicationAdapterCeleste.cs +++ b/CelesteTAS-EverestInterop/Communication/CommunicationAdapterCeleste.cs @@ -132,6 +132,12 @@ protected override void HandleMessage(MessageID messageId, BinaryReader reader) gameData = meta.GetHash(commandArgs, filePath, fileLine); break; + case GameDataType.LevelInfo: + gameData = new LevelInfo { + ModUrl = GameData.GetModUrl(), + WakeupTime = GameData.GetWakeupTime(), + }; + break; default: gameData = null; @@ -163,6 +169,10 @@ protected override void HandleMessage(MessageID messageId, BinaryReader reader) case GameDataType.CommandHash: writer.Write((int)gameData!); break; + + case GameDataType.LevelInfo: + writer.WriteObject((LevelInfo)gameData!); + break; } LogVerbose($"Sent message GameDataResponse: {gameDataType} = '{gameData}'"); }); diff --git a/CelesteTAS-EverestInterop/Communication/GameData.cs b/CelesteTAS-EverestInterop/Communication/GameData.cs index 5d93b988..7bf53f8d 100644 --- a/CelesteTAS-EverestInterop/Communication/GameData.cs +++ b/CelesteTAS-EverestInterop/Communication/GameData.cs @@ -177,6 +177,34 @@ public static string GetModUrl() { return string.Empty; } + public static int? GetWakeupTime() { + if (Engine.Scene is not Level level) { + return null; + } + + AreaData areaData = AreaData.Get(level); + + int? wakeupTime = areaData.IntroType switch { + // Player.IntroTypes.Transition => expr, + Player.IntroTypes.Respawn => 36, + // Player.IntroTypes.WalkInRight => expr, + // Player.IntroTypes.WalkInLeft => expr, + // Player.IntroTypes.Jump => expr, + Player.IntroTypes.WakeUp => 190, + // Player.IntroTypes.Fall => expr, + // Player.IntroTypes.TempleMirrorVoid => expr, + Player.IntroTypes.None => null, + // Player.IntroTypes.ThinkForABit => expr, + _ => null, + }; + + if (wakeupTime == null) { + $"Couldn't determine wakeup time for intro type '{areaData.IntroType}'".Log(LogLevel.Warn); + } + + return wakeupTime; + } + public static GameState? GetGameState() { if (Engine.Scene is not Level level) { return null; diff --git a/Studio/CelesteStudio/Communication/CommunicationAdapterStudio.cs b/Studio/CelesteStudio/Communication/CommunicationAdapterStudio.cs index 065c1009..d0659336 100644 --- a/Studio/CelesteStudio/Communication/CommunicationAdapterStudio.cs +++ b/Studio/CelesteStudio/Communication/CommunicationAdapterStudio.cs @@ -102,6 +102,10 @@ protected override void HandleMessage(MessageID messageId, BinaryReader reader) case GameDataType.CommandHash: gameData[gameDataType] = reader.ReadInt32(); break; + + case GameDataType.LevelInfo: + gameData[gameDataType] = reader.ReadObject(); + break; } gameDataPending[gameDataType] = false; diff --git a/Studio/CelesteStudio/Communication/CommunicationWrapper.cs b/Studio/CelesteStudio/Communication/CommunicationWrapper.cs index 41c22069..93c43a61 100644 --- a/Studio/CelesteStudio/Communication/CommunicationWrapper.cs +++ b/Studio/CelesteStudio/Communication/CommunicationWrapper.cs @@ -192,6 +192,13 @@ public static string GetExactGameInfo() { return (string?)comm!.RequestGameData(GameDataType.ExactGameInfo).Result ?? string.Empty; } + public static LevelInfo? GetLevelInfo() { + if (!Connected) { + return null; + } + + return (LevelInfo?)comm!.RequestGameData(GameDataType.LevelInfo).Result; + } // The hashcode is stored instead of the actual key, since it is used as an identifier in responses from Celeste private static readonly Dictionary Entries, bool Done)> autoCompleteEntryCache = []; diff --git a/Studio/CelesteStudio/Studio.cs b/Studio/CelesteStudio/Studio.cs index be8fec7f..58bf7491 100644 --- a/Studio/CelesteStudio/Studio.cs +++ b/Studio/CelesteStudio/Studio.cs @@ -363,16 +363,21 @@ private void OnNewFile() { if (!ShouldDiscardChanges()) return; + string simpleConsoleCommand = CommunicationWrapper.GetConsoleCommand(simple: true); + CommunicationWrapper.GetModURL(); + LevelInfo? levelInfo = CommunicationWrapper.GetLevelInfo(); + string initText = $"RecordCount: 1{Document.NewLine}"; - if (CommunicationWrapper.Connected) { - if (CommunicationWrapper.GetConsoleCommand(simple: true) is var simpleConsoleCommand && !string.IsNullOrWhiteSpace(simpleConsoleCommand)) { - initText += $"{Document.NewLine}{simpleConsoleCommand}{Document.NewLine} 1{Document.NewLine}"; - if (CommunicationWrapper.GetModURL() is var modUrl && !string.IsNullOrWhiteSpace(modUrl)) { - initText = modUrl + initText; - } - } + if (levelInfo != null && !string.IsNullOrWhiteSpace(levelInfo?.ModUrl)) { + initText = levelInfo?.ModUrl + initText; + } + if (!string.IsNullOrWhiteSpace(simpleConsoleCommand)) { + initText += $"{Document.NewLine}{simpleConsoleCommand}{Document.NewLine} 1{Document.NewLine}"; } initText += $"{Document.NewLine}#Start{Document.NewLine}"; + if (levelInfo?.WakeupTime is { } wakeupTime) { + initText += wakeupTime.ToString().PadLeft(ActionLine.MaxFramesDigits) + Document.NewLine; + } File.WriteAllText(Document.ScratchFile, initText); OpenFile(Document.ScratchFile); diff --git a/StudioCommunication/LevelData.cs b/StudioCommunication/LevelData.cs new file mode 100644 index 00000000..731eecd2 --- /dev/null +++ b/StudioCommunication/LevelData.cs @@ -0,0 +1,9 @@ +using MemoryPack; + +namespace StudioCommunication; + +[MemoryPackable] +public partial record struct LevelInfo { + public int? WakeupTime; + public string ModUrl; +} diff --git a/StudioCommunication/MessageID.cs b/StudioCommunication/MessageID.cs index b447bded..3800cbfa 100644 --- a/StudioCommunication/MessageID.cs +++ b/StudioCommunication/MessageID.cs @@ -80,6 +80,7 @@ public enum GameDataType : byte { RawInfo, GameState, CommandHash, + LevelInfo, } public enum RecordingFailedReason : byte {