diff --git a/AquaMai.Mods/UX/OneKeyRetrySkip.cs b/AquaMai.Mods/UX/OneKeyRetrySkip.cs index 80748521..c1ae8e39 100644 --- a/AquaMai.Mods/UX/OneKeyRetrySkip.cs +++ b/AquaMai.Mods/UX/OneKeyRetrySkip.cs @@ -29,8 +29,20 @@ public class OneKeyRetrySkip [ConfigEntry("跳关长按")] public static readonly bool skipLongPress = true; + [ConfigEntry( + name: "仅自由模式可重开", + en: "Only allow retry in Freedom Mode while time remains.", + zh: "仅在自由模式且时间未耗尽时允许一键重试,跳过不受影响")] + public static readonly bool allowRetryOnlyInFreedomMode = false; + private static bool dirty = false; + private static bool IsRetryAllowed() + { + if (!allowRetryOnlyInFreedomMode) return true; + return GameManager.IsFreedomMode && GameManager.GetFreedomModeMSec() > 0; + } + [HarmonyPostfix] [HarmonyPatch(typeof(GameProcess), "OnStart")] public static void PostGameProcessStart() @@ -63,7 +75,8 @@ public static void PostGameProcessUpdate(GameProcess __instance, Message[] ____m traverse.Method("SetRelease").GetValue(); } - else if (KeyListener.GetKeyDownOrLongPress(retryKey, retryLongPress) && GameInfo.GameVersion >= 23000) + else if (KeyListener.GetKeyDownOrLongPress(retryKey, retryLongPress) && GameInfo.GameVersion >= 23000 && + IsRetryAllowed()) { #if DEBUG MelonLogger.Msg("[OneKeyRetrySkip] Retry key pressed."); diff --git a/AquaMai.Mods/UX/PracticeMode/Libs/PractiseModeUI.cs b/AquaMai.Mods/UX/PracticeMode/Libs/PractiseModeUI.cs index a4f23d97..2bd00d4a 100644 --- a/AquaMai.Mods/UX/PracticeMode/Libs/PractiseModeUI.cs +++ b/AquaMai.Mods/UX/PracticeMode/Libs/PractiseModeUI.cs @@ -98,11 +98,7 @@ public void Update() } else if (InputManager.GetTouchPanelAreaDown(InputManager.TouchPanelArea.B8) || InputManager.GetTouchPanelAreaDown(InputManager.TouchPanelArea.B1)) { - DebugFeature.Pause = !DebugFeature.Pause; - if (!DebugFeature.Pause) - { - PracticeMode.Seek(0); - } + PracticeMode.TogglePause(); } else if (InputManager.GetTouchPanelAreaDown(InputManager.TouchPanelArea.B7) && PracticeMode.repeatStart == -1) { diff --git a/AquaMai.Mods/UX/PracticeMode/PracticeMode.cs b/AquaMai.Mods/UX/PracticeMode/PracticeMode.cs index afc310d3..90c3de79 100644 --- a/AquaMai.Mods/UX/PracticeMode/PracticeMode.cs +++ b/AquaMai.Mods/UX/PracticeMode/PracticeMode.cs @@ -36,6 +36,12 @@ public class PracticeMode [ConfigEntry] public static readonly bool longPress = false; + [ConfigEntry( + name: "仅自由模式可用", + en: "Only allow Practice Mode in Freedom Mode while time remains.", + zh: "仅在自由模式且时间未耗尽时允许使用练习模式")] + public static readonly bool onlyInFreedomMode = false; + public static double repeatStart = -1; public static double repeatEnd = -1; public static float speed = 1; @@ -43,6 +49,20 @@ public class PracticeMode private static List movie; private static GameCtrl[] gameCtrl = new GameCtrl[2]; public static bool keepNoteSpeed = false; + + private static void ClearPracticeEffects() + { + // 清除练习模式的所有效果。涉及的效果有五种:UI界面、循环、速度保持、速度、暂停。 + if (ui != null) + { + UnityEngine.Object.Destroy(ui); + ui = null; + } + if (repeatStart >= 0 || repeatEnd >= 0) ClearRepeat(); + keepNoteSpeed = false; + if (speed != 1f) SpeedReset(); + if (DebugFeature.Pause) TogglePause(); + } public static void SetRepeatEnd(double time) { @@ -67,6 +87,15 @@ public static void ClearRepeat() repeatEnd = -1; } + public static void TogglePause() + { + DebugFeature.Pause = !DebugFeature.Pause; + if (!DebugFeature.Pause) + { + Seek(0); + } + } + public static void GameCtrlResetOptionSpeed() { foreach (var g in gameCtrl) @@ -169,6 +198,8 @@ public static double CurrentPlayMsec public static PracticeModeUI ui; + private static long prevFreedomModeMSec = -1; // 上一帧时,自由模式的剩余秒数 + [HarmonyPatch] public class PatchNoteSpeed { @@ -192,7 +223,9 @@ public static void GameProcessPostStart() repeatStart = -1; repeatEnd = -1; speed = 1; + keepNoteSpeed = false; ui = null; + prevFreedomModeMSec = GameManager.IsFreedomMode ? GameManager.GetFreedomModeMSec() : -1; } [HarmonyPatch(typeof(GameProcess), "OnRelease")] @@ -202,7 +235,9 @@ public static void GameProcessPostRelease() repeatStart = -1; repeatEnd = -1; speed = 1; + keepNoteSpeed = false; ui = null; + prevFreedomModeMSec = -1; } [HarmonyPatch(typeof(GameCtrl), "Initialize")] @@ -228,10 +263,19 @@ public static void OnGenericProcessUpdate(GenericMonitor[] ____monitors) [HarmonyPostfix] public static void GameProcessPostUpdate(GameProcess __instance, GameMonitor[] ____monitors) { - if (KeyListener.GetKeyDownOrLongPress(key, longPress) && ui is null) + if (KeyListener.GetKeyDownOrLongPress(key, longPress) && ui is null && + (!onlyInFreedomMode || (GameManager.IsFreedomMode && GameManager.GetFreedomModeMSec() > 0))) // onlyInFreedomMode=true情况,则额外检查是否在练习模式内、且时间有剩余,如果不满足则不开启UI。 { ui = ____monitors[0].gameObject.AddComponent(); } + + if (onlyInFreedomMode && GameManager.IsFreedomMode) + { + var currentFreedomModeMSec = GameManager.GetFreedomModeMSec(); + if (prevFreedomModeMSec > 0 && currentFreedomModeMSec <= 0) + ClearPracticeEffects(); // 如果这一帧内、练习模式的时间刚好归零了:则清空练习模式的一切效果。 + prevFreedomModeMSec = currentFreedomModeMSec; + } if (repeatStart >= 0 && repeatEnd >= 0) {