Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AquaMai.Mods/UX/PracticeMode/Libs/PractiseModeUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ public void Update()
else if (InputManager.GetTouchPanelAreaDown(InputManager.TouchPanelArea.E4))
{
PracticeMode.keepNoteSpeed = !PracticeMode.keepNoteSpeed;
PracticeMode.gameCtrl?.ResetOptionSpeed();
PracticeMode.GameCtrlResetOptionSpeed();
}
else if (
InputManager.GetTouchPanelAreaDown(InputManager.TouchPanelArea.A1) ||
Expand Down
34 changes: 25 additions & 9 deletions AquaMai.Mods/UX/PracticeMode/PracticeMode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ public class PracticeMode
public static double repeatEnd = -1;
public static float speed = 1;
private static CriAtomExPlayer player;
private static MovieMaterialMai2 movie;
public static GameCtrl gameCtrl;
private static List<MovieMaterialMai2> movie;
private static GameCtrl[] gameCtrl = new GameCtrl[2];
public static bool keepNoteSpeed = false;

public static void SetRepeatEnd(double time)
Expand All @@ -67,14 +67,26 @@ public static void ClearRepeat()
repeatEnd = -1;
}

public static void GameCtrlResetOptionSpeed()
{
foreach (var g in gameCtrl)
{
try
{
g?.ResetOptionSpeed();
}
catch (NullReferenceException) {} // 忽略即可,因为SBGA的代码在ResetOptionSpeed内部没有做null检查,单刷的时候对2P那侧这个函数必定会抛NPE
}
Comment on lines +72 to +79

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

使用 try-catch 来处理预期的 NullReferenceException 虽然可行,但通常不推荐将异常用于控制流。一个更清晰且性能更好的方法是,在调用 ResetOptionSpeed 之前,检查玩家是否真的在游戏中。您可以使用 GameManager.IsEntry(g.MonitorIndex) 来进行此检查。这样可以避免捕获异常,使代码意图更明确。

        foreach (var g in gameCtrl)
        {
            if (g != null && GameManager.IsEntry(g.MonitorIndex))
            {
                g.ResetOptionSpeed();
            }
        }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我懒了,反正我的注释清楚且明确,而且这个函数的调用频率很低(只在SetSpeed的一瞬间调用,而不是定期调用)。所以我不想改了。

}

public static void SetSpeed()
{
player.SetPitch((float)(1200 * Math.Log(speed, 2)));
// player.SetDspTimeStretchRatio(1 / speed);
player.UpdateAll();

movie.player.SetSpeed(speed);
gameCtrl?.ResetOptionSpeed();
movie?.ForEach(m => m.player?.SetSpeed(speed));
GameCtrlResetOptionSpeed();
}

private static IEnumerator SetSpeedCoroutineInner()
Expand Down Expand Up @@ -195,7 +207,7 @@ public static void GameProcessPostRelease()
[HarmonyPostfix]
public static void GameCtrlPostInitialize(GameCtrl __instance)
{
gameCtrl = __instance;
gameCtrl[__instance.MonitorIndex] =__instance;
}

# if DEBUG
Expand Down Expand Up @@ -304,8 +316,12 @@ public static void SoundCtrlPostInitialize(SoundCtrl.InitParam param, Dictionary

[HarmonyPatch(typeof(MovieController), "Awake")]
[HarmonyPostfix]
public static void MovieControllerPostAwake(MovieMaterialMai2 ____moviePlayers)
public static void MovieControllerPostAwake(object ____moviePlayers)
{
movie = ____moviePlayers;
// 1.55以上,_moviePlayers是List<MovieMaterialMai2>;1.50以下,___moviePlayers是MovieMaterialMai2。
// 所以这里用object承接,再根据object的类型做具体处理
if (____moviePlayers is List<MovieMaterialMai2> mList) movie = mList;
else if (____moviePlayers is MovieMaterialMai2 m) movie = new([m]);
else MelonLogger.Error("[PracticeMode] MovieControllerPostAwake: [BUG] 收到的____moviePlayers参数不正确");
}
}
}