From 27cb6d5a304e7848431922dbe52557a8cc0eea4a Mon Sep 17 00:00:00 2001 From: Starrah Date: Sat, 30 May 2026 17:00:20 +0800 Subject: [PATCH 1/4] =?UTF-8?q?[+][OneKeyRetryEnd]=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E4=B8=80=E4=B8=AA=E9=80=89=E9=A1=B9=EF=BC=8C=E5=BC=80=E5=90=AF?= =?UTF-8?q?=E5=90=8E=EF=BC=8C=E5=8F=AA=E6=9C=89=E8=87=AA=E7=94=B1=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F=E4=B8=94=E6=97=B6=E9=97=B4=E6=9C=AA=E8=80=97=E5=B0=BD?= =?UTF-8?q?=E6=97=B6=E6=89=8D=E5=85=81=E8=AE=B8=E4=B8=80=E9=94=AE=E9=87=8D?= =?UTF-8?q?=E5=BC=80=E3=80=82=20=E9=80=82=E9=85=8D=E4=BA=8E=E7=AA=9D?= =?UTF-8?q?=E7=9A=84=E9=9C=80=E6=B1=82=EF=BC=8C=E9=98=B2=E6=AD=A2=E5=88=A9?= =?UTF-8?q?=E7=94=A8=E4=B8=80=E9=94=AE=E9=87=8D=E5=BC=80=E2=80=9C=E9=9C=B8?= =?UTF-8?q?=E6=9C=BA=E2=80=9D=E7=9A=84=E6=83=85=E5=86=B5=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AquaMai.Mods/UX/OneKeyRetrySkip.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) 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."); From a87b293c6438c048111f2f93a6daa71b1e73bb31 Mon Sep 17 00:00:00 2001 From: Starrah Date: Sun, 31 May 2026 00:03:55 +0800 Subject: [PATCH 2/4] =?UTF-8?q?[R][PracticeMode]=20=E4=BB=8EUI=E5=B1=82?= =?UTF-8?q?=E6=8A=8A=E5=BC=80=E5=85=B3=E6=9A=82=E5=81=9C=E7=9A=84=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=EF=BC=8C=E6=8A=BD=E5=8F=96=E5=87=BA=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E6=9D=A5=EF=BC=8C=E4=BB=A5=E4=BE=BF=E8=B0=83?= =?UTF-8?q?=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AquaMai.Mods/UX/PracticeMode/Libs/PractiseModeUI.cs | 6 +----- AquaMai.Mods/UX/PracticeMode/PracticeMode.cs | 9 +++++++++ 2 files changed, 10 insertions(+), 5 deletions(-) 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..3bf10524 100644 --- a/AquaMai.Mods/UX/PracticeMode/PracticeMode.cs +++ b/AquaMai.Mods/UX/PracticeMode/PracticeMode.cs @@ -67,6 +67,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) From 9ca359505e676a11dc6fc1510d2a4a1371ccd315 Mon Sep 17 00:00:00 2001 From: Starrah Date: Sun, 31 May 2026 00:22:07 +0800 Subject: [PATCH 3/4] =?UTF-8?q?[+][PracticeMode]=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E4=B8=80=E4=B8=AA=E9=80=89=E9=A1=B9=EF=BC=8C=E5=BC=80=E5=90=AF?= =?UTF-8?q?=E5=90=8E=EF=BC=8C=E5=8F=AA=E6=9C=89=E8=87=AA=E7=94=B1=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F=E4=B8=94=E6=97=B6=E9=97=B4=E6=9C=AA=E8=80=97=E5=B0=BD?= =?UTF-8?q?=E6=97=B6=E6=89=8D=E5=85=81=E8=AE=B8=E4=BD=BF=E7=94=A8=E7=BB=83?= =?UTF-8?q?=E4=B9=A0=E6=A8=A1=E5=BC=8F=EF=BC=8C=E4=B8=94=E6=97=B6=E9=97=B4?= =?UTF-8?q?=E8=80=97=E5=B0=BD=E6=97=B6=E4=BC=9A=E5=BC=BA=E5=88=B6=E6=B8=85?= =?UTF-8?q?=E9=99=A4=E7=BB=83=E4=B9=A0=E6=A8=A1=E5=BC=8F=E7=9A=84=E4=B8=80?= =?UTF-8?q?=E5=88=87=E6=95=88=E6=9E=9C=E3=80=82=20=E9=80=82=E9=85=8D?= =?UTF-8?q?=E4=BA=8E=E7=AA=9D=E7=9A=84=E9=9C=80=E6=B1=82=EF=BC=8C=E9=98=B2?= =?UTF-8?q?=E6=AD=A2=E5=88=A9=E7=94=A8=E7=BB=83=E4=B9=A0=E6=A8=A1=E5=BC=8F?= =?UTF-8?q?=E2=80=9C=E9=9C=B8=E6=9C=BA=E2=80=9D=E7=9A=84=E6=83=85=E5=86=B5?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AquaMai.Mods/UX/PracticeMode/PracticeMode.cs | 35 +++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/AquaMai.Mods/UX/PracticeMode/PracticeMode.cs b/AquaMai.Mods/UX/PracticeMode/PracticeMode.cs index 3bf10524..e190fcfe 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,19 @@ 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(); + if (speed != 1f) SpeedReset(); + if (DebugFeature.Pause) TogglePause(); + } public static void SetRepeatEnd(double time) { @@ -178,6 +197,8 @@ public static double CurrentPlayMsec public static PracticeModeUI ui; + private static long prevFreedomModeMSec = -1; // 上一帧时,自由模式的剩余秒数 + [HarmonyPatch] public class PatchNoteSpeed { @@ -201,7 +222,9 @@ public static void GameProcessPostStart() repeatStart = -1; repeatEnd = -1; speed = 1; + keepNoteSpeed = false; ui = null; + if (GameManager.IsFreedomMode) prevFreedomModeMSec = GameManager.GetFreedomModeMSec(); } [HarmonyPatch(typeof(GameProcess), "OnRelease")] @@ -211,6 +234,7 @@ public static void GameProcessPostRelease() repeatStart = -1; repeatEnd = -1; speed = 1; + keepNoteSpeed = false; ui = null; } @@ -237,10 +261,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) { From 332210b6aaebf258e72f2dbc2b3bac16749fddd9 Mon Sep 17 00:00:00 2001 From: Starrah Date: Sun, 31 May 2026 00:50:00 +0800 Subject: [PATCH 4/4] fix --- AquaMai.Mods/UX/PracticeMode/PracticeMode.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/AquaMai.Mods/UX/PracticeMode/PracticeMode.cs b/AquaMai.Mods/UX/PracticeMode/PracticeMode.cs index e190fcfe..90c3de79 100644 --- a/AquaMai.Mods/UX/PracticeMode/PracticeMode.cs +++ b/AquaMai.Mods/UX/PracticeMode/PracticeMode.cs @@ -52,13 +52,14 @@ public class PracticeMode private static void ClearPracticeEffects() { - // 清除练习模式的所有效果。涉及的效果有四种:UI界面、循环、速度、暂停。 + // 清除练习模式的所有效果。涉及的效果有五种: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(); } @@ -224,7 +225,7 @@ public static void GameProcessPostStart() speed = 1; keepNoteSpeed = false; ui = null; - if (GameManager.IsFreedomMode) prevFreedomModeMSec = GameManager.GetFreedomModeMSec(); + prevFreedomModeMSec = GameManager.IsFreedomMode ? GameManager.GetFreedomModeMSec() : -1; } [HarmonyPatch(typeof(GameProcess), "OnRelease")] @@ -236,6 +237,7 @@ public static void GameProcessPostRelease() speed = 1; keepNoteSpeed = false; ui = null; + prevFreedomModeMSec = -1; } [HarmonyPatch(typeof(GameCtrl), "Initialize")]