Skip to content

feat: Add configurable Answer Sound offset and player menu toggle#52

Merged
clansty merged 6 commits intoMuNET-OSS:mainfrom
AdemJensen:move_answer_sound_modify
Sep 6, 2025
Merged

feat: Add configurable Answer Sound offset and player menu toggle#52
clansty merged 6 commits intoMuNET-OSS:mainfrom
AdemJensen:move_answer_sound_modify

Conversation

@AdemJensen
Copy link
Copy Markdown
Contributor

@AdemJensen AdemJensen commented Sep 1, 2025

Background

Previously, the Answer Sound offset adjustment could only be performed in-game by players. However, since answer offset issues are often a machine-wide problem rather than a player-specific one, this approach was inconvenient and repetitive.

Changes

New configuration option:
Added a global answer sound offset setting in the configuration file, allowing machine owners to directly adjust the Answer Sound offset for the entire machine.

Menu toggle:
Introduced a switch for the in-game configuration menu that lets the machine owner decide whether players are allowed to access and change the offset setting during gameplay.

## 由 Sourcery 总结

引入了一个全局答题音效偏移配置,支持可选的游戏内调整,并更新了计时逻辑以结合机器范围和用户特定的设置。

新功能:
- 在配置文件中为 1P 和 2P 添加全局答题音效偏移设置
- 引入一个 DisplayInGameConfig 开关,以启用或禁用游戏内偏移调整入口

改进:
- 重构音效计时计算,以结合全局机器偏移和用户特定偏移
- 根据新开关条件性地注册游戏内设置入口
- 改进日志记录,以报告有效偏移及其来源
Original summary in English

Summary by Sourcery

Introduce a global answer sound offset configuration with optional in-game adjustment and update the timing logic to combine machine-wide and per-user settings.

New Features:

  • Add global answer sound offset settings for 1P and 2P in the configuration file
  • Introduce a DisplayInGameConfig toggle to enable or disable the in-game offset adjustment entry

Enhancements:

  • Refactor sound timing calculations to combine global machine offset with user-specific offset
  • Conditionally register the in-game settings entry based on the new toggle
  • Improve logging to report both the effective offset and its sources

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai bot commented Sep 1, 2025

审阅者指南

通过添加新的配置条目并集中菜单注册、日志记录和播放计时中的偏移逻辑,引入了全局机器范围的应答声音偏移和一个可选的游戏内切换功能。

新应答声音偏移配置的实体关系图

erDiagram
    CONFIGURATION ||--o{ PLAYER : "has"
    CONFIGURATION {
        bool DisplayInGameConfig
        float MoveValue_1P
        float MoveValue_2P
    }
    PLAYER {
        float userSettings
    }
    CONFIGURATION ||--o{ GAME_SETTINGS : "controls"
    GAME_SETTINGS {
        bool DisplayInGameConfig
    }
Loading

更新的 MoveAnswerSound 配置和逻辑的类图

classDiagram
    class MoveAnswerSound {
        +static bool DisplayInGameConfig
        +static float MoveValue_1P
        +static float MoveValue_2P
        -static float[] userSettings
        -static IPersistentStorage storage
        +static float GetCabinSettingsValue(uint monitorIndex)
        +static float GetSettingsValue(uint monitorIndex)
        +static float GetSettingsValue(int monitorIndex)
        +static void OnBeforePatch()
        +int Sort
        +string Name
        +string Description
        +void LoadSettings()
        +void PreUpdateControl(GameObject ____NoteRoot, GameCtrl __instance)
    }
    MoveAnswerSound --> IPersistentStorage
    MoveAnswerSound --> PlayerPrefsStorage
    MoveAnswerSound --> GameSettingsManager
    MoveAnswerSound --> UserDataManager
    MoveAnswerSound --> MelonLogger
    MoveAnswerSound --> NotesManager
    MoveAnswerSound --> GameSingleCueCtrl
Loading

文件级更改

更改 详细信息 文件
添加全局偏移设置和切换配置条目
  • 引入 DisplayInGameConfig 布尔值以启用/禁用每个玩家的调整
  • 定义 MoveValue_1P 和 MoveValue_2P 浮点数用于机器范围的偏移
  • 更新 ConfigSection 元数据
AquaMai.Mods/Utils/MoveAnswerSound.cs
将偏移计算集中到辅助方法中
  • 添加 GetCabinSettingsValue 以读取每个显示器的机器设置
  • 实现 GetSettingsValue 重载以结合机器和用户偏移
  • 将直接算术运算替换为对这些辅助方法的调用
AquaMai.Mods/Utils/MoveAnswerSound.cs
根据切换条件注册游戏内设置
  • 将 GameSettingsManager.RegisterSetting 调用包装在 DisplayInGameConfig 检查中
AquaMai.Mods/Utils/MoveAnswerSound.cs
增强启动日志记录以反映组合或禁用的偏移量
  • 当游戏内配置启用时,记录完整的计算
  • 当禁用时,记录禁用状态和机器设置
AquaMai.Mods/Utils/MoveAnswerSound.cs
更新播放计时以使用集中设置
  • 替换 PreUpdateControl 中硬编码的 33ms 和 userSettings 引用
  • 对应答头和尾计时都使用 GetSettingsValue
AquaMai.Mods/Utils/MoveAnswerSound.cs

提示和命令

与 Sourcery 互动

  • 触发新审阅: 在拉取请求上评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的审阅评论。
  • 从审阅评论生成 GitHub issue: 通过回复 Sourcery 的评论,请求 Sourcery 从审阅评论创建 issue。您也可以回复审阅评论并带上 @sourcery-ai issue 来创建 issue。
  • 生成拉取请求标题: 随时在拉取请求标题的任何位置写入 @sourcery-ai 以生成标题。您也可以在拉取请求上评论 @sourcery-ai title 以随时(重新)生成标题。
  • 生成拉取请求摘要: 随时在拉取请求正文的任何位置写入 @sourcery-ai summary,以便在您想要的位置生成 PR 摘要。您也可以在拉取请求上评论 @sourcery-ai summary 以随时(重新)生成摘要。
  • 生成审阅者指南: 在拉取请求上评论 @sourcery-ai guide 以随时(重新)生成审阅者指南。
  • 解决所有 Sourcery 评论: 在拉取请求上评论 @sourcery-ai resolve 以解决所有 Sourcery 评论。如果您已处理所有评论并且不想再看到它们,这会很有用。
  • 驳回所有 Sourcery 审阅: 在拉取请求上评论 @sourcery-ai dismiss 以驳回所有现有 Sourcery 审阅。如果您想重新开始新的审阅,这尤其有用——别忘了评论 @sourcery-ai review 来触发新的审阅!

自定义您的体验

访问您的 仪表板 以:

  • 启用或禁用审阅功能,例如 Sourcery 生成的拉取请求摘要、审阅者指南等。
  • 更改审阅语言。
  • 添加、删除或编辑自定义审阅说明。
  • 调整其他审阅设置。

获取帮助

Original review guide in English

Reviewer's Guide

Introduces a global machine-wide answer sound offset and an optional in-game toggle by adding new config entries and centralizing offset logic across menu registration, logging, and playback timing.

Entity relationship diagram for new answer sound offset configuration

erDiagram
    CONFIGURATION ||--o{ PLAYER : "has"
    CONFIGURATION {
        bool DisplayInGameConfig
        float MoveValue_1P
        float MoveValue_2P
    }
    PLAYER {
        float userSettings
    }
    CONFIGURATION ||--o{ GAME_SETTINGS : "controls"
    GAME_SETTINGS {
        bool DisplayInGameConfig
    }
Loading

Class diagram for updated MoveAnswerSound configuration and logic

classDiagram
    class MoveAnswerSound {
        +static bool DisplayInGameConfig
        +static float MoveValue_1P
        +static float MoveValue_2P
        -static float[] userSettings
        -static IPersistentStorage storage
        +static float GetCabinSettingsValue(uint monitorIndex)
        +static float GetSettingsValue(uint monitorIndex)
        +static float GetSettingsValue(int monitorIndex)
        +static void OnBeforePatch()
        +int Sort
        +string Name
        +string Description
        +void LoadSettings()
        +void PreUpdateControl(GameObject ____NoteRoot, GameCtrl __instance)
    }
    MoveAnswerSound --> IPersistentStorage
    MoveAnswerSound --> PlayerPrefsStorage
    MoveAnswerSound --> GameSettingsManager
    MoveAnswerSound --> UserDataManager
    MoveAnswerSound --> MelonLogger
    MoveAnswerSound --> NotesManager
    MoveAnswerSound --> GameSingleCueCtrl
Loading

File-Level Changes

Change Details Files
Add global offset settings and toggle config entries
  • Introduce DisplayInGameConfig boolean to enable/disable per-player adjustments
  • Define MoveValue_1P and MoveValue_2P floats for machine-wide offsets
  • Update ConfigSection metadata
AquaMai.Mods/Utils/MoveAnswerSound.cs
Centralize offset calculation into helper methods
  • Add GetCabinSettingsValue to read machine setting per monitor
  • Implement GetSettingsValue overloads to combine machine and user offsets
  • Replace direct arithmetic with calls to these helpers
AquaMai.Mods/Utils/MoveAnswerSound.cs
Conditionally register in-game setting based on toggle
  • Wrap GameSettingsManager.RegisterSetting call in DisplayInGameConfig check
AquaMai.Mods/Utils/MoveAnswerSound.cs
Enhance startup logging to reflect combined or disabled offsets
  • Log full calculation when in-game config is enabled
  • Log disabled state and machine setting when disabled
AquaMai.Mods/Utils/MoveAnswerSound.cs
Update playback timing to use centralized settings
  • Replace hard-coded 33ms and userSettings references in PreUpdateControl
  • Use GetSettingsValue for both answer head and tail timing
AquaMai.Mods/Utils/MoveAnswerSound.cs

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@AdemJensen AdemJensen changed the title Move answer sound modify Add configurable Answer Sound offset and player menu toggle Sep 1, 2025
Copy link
Copy Markdown

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

你好 - 我已审查了你的更改,它们看起来很棒!

AI 代理提示
请处理此代码审查中的评论:
## 独立评论

### 评论 1
<location> `AquaMai.Mods/Utils/MoveAnswerSound.cs:51` </location>
<code_context>
+        return DisplayInGameConfig ? userSettings[monitorIndex] + moveValue : moveValue;
+    }
+    
+    private static float GetSettingsValue(int monitorIndex) => GetSettingsValue((uint)monitorIndex);
+
     #region 设置界面注入
</code_context>

<issue_to_address>
将 int 转换为 uint 可能会掩盖负值。

将负的 monitorIndex 转换为 uint 可能会导致越界访问。在转换之前,请验证 monitorIndex 为非负数。
</issue_to_address>

### 评论 2
<location> `AquaMai.Mods/Utils/MoveAnswerSound.cs:34` </location>
<code_context>
+    [ConfigEntry(
+        en: "Answer sound move value in ms, this value will be combined with user's setting in game. Increase this value to make the answer sound appear later, vice versa.",
+        zh: "正解音偏移量,单位为毫秒,此设定值会与用户游戏内的设置相加。增大这个值将会使正解音出现得更晚,反之则更早。")]
+    private static readonly float MoveValue_1P = 33f;
+    
+    [ConfigEntry(
</code_context>

<issue_to_address>
考虑将每个玩家的常量和逻辑整合到一个数组和方法中,以减少代码重复和分支。

以下是将每个玩家的常量和重载合并到一个数组+方法中,并统一日志记录到一个模板的一种方法。这保持了完全相同的行为,但分支/重复大大减少:

```csharp
// replace two fields + GetCabinSettingsValue + int-overload
private static readonly float[] CabinOffsets = { 33f, 33f };

// single entry point
private static float GetSettingsValue(int idx)
{
    var cabin = CabinOffsets[idx];
    var user  = DisplayInGameConfig ? userSettings[idx] : 0f;
    return cabin + user;
}
```

然后将你的双分支日志记录器替换为单行:

```csharp
for (uint i = 0; i < 2; i++)
{
    // … load userSettings[i] as before …
    MelonLogger.Msg(
        $"玩家 {i} 的移动正解音设置为 {GetSettingsValue((int)i)} ms "
      + $"(游戏内: {userSettings[i]} ms, 机台: {CabinOffsets[i]} ms)"
      + (DisplayInGameConfig ? "" : ",游戏内设置已禁用"));
}
```

最后,在你的音符播放补丁中,只需调用 `GetSettingsValue(__instance.MonitorIndex)`,而不是重复减法逻辑。这消除了额外的重载、方法和分支,同时保留了所有功能。
</issue_to_address>

Sourcery 对开源免费 - 如果您喜欢我们的评论,请考虑分享它们 ✨
帮助我更有用!请点击每个评论上的 👍 或 👎,我将使用这些反馈来改进你的评论。
Original comment in English

Hey there - I've reviewed your changes and they look great!

Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments

### Comment 1
<location> `AquaMai.Mods/Utils/MoveAnswerSound.cs:51` </location>
<code_context>
+        return DisplayInGameConfig ? userSettings[monitorIndex] + moveValue : moveValue;
+    }
+    
+    private static float GetSettingsValue(int monitorIndex) => GetSettingsValue((uint)monitorIndex);
+
     #region 设置界面注入
</code_context>

<issue_to_address>
Casting int to uint may mask negative values.

Casting a negative monitorIndex to uint can lead to out-of-bounds access. Please validate monitorIndex is non-negative before casting.
</issue_to_address>

### Comment 2
<location> `AquaMai.Mods/Utils/MoveAnswerSound.cs:34` </location>
<code_context>
+    [ConfigEntry(
+        en: "Answer sound move value in ms, this value will be combined with user's setting in game. Increase this value to make the answer sound appear later, vice versa.",
+        zh: "正解音偏移量,单位为毫秒,此设定值会与用户游戏内的设置相加。增大这个值将会使正解音出现得更晚,反之则更早。")]
+    private static readonly float MoveValue_1P = 33f;
+    
+    [ConfigEntry(
</code_context>

<issue_to_address>
Consider consolidating per-player constants and logic into a single array and method to reduce code duplication and branching.

Here’s one way to collapse the per-player constants and overloads into a single array + method, and unify your logging into one template.  This keeps exactly the same behavior but with much less branching/duplication:

```csharp
// replace two fields + GetCabinSettingsValue + int-overload
private static readonly float[] CabinOffsets = { 33f, 33f };

// single entry point
private static float GetSettingsValue(int idx)
{
    var cabin = CabinOffsets[idx];
    var user  = DisplayInGameConfig ? userSettings[idx] : 0f;
    return cabin + user;
}
```

Then replace your two-branch logger with a single line:

```csharp
for (uint i = 0; i < 2; i++)
{
    // … load userSettings[i] as before …
    MelonLogger.Msg(
        $"玩家 {i} 的移动正解音设置为 {GetSettingsValue((int)i)} ms "
      + $"(游戏内: {userSettings[i]} ms, 机台: {CabinOffsets[i]} ms)"
      + (DisplayInGameConfig ? "" : ",游戏内设置已禁用"));
}
```

Finally, in your note-playback patch just call `GetSettingsValue(__instance.MonitorIndex)` instead of duplicating the subtraction logic. This removes the extra overloads, methods, and branches while preserving all functionality.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@AdemJensen AdemJensen changed the title Add configurable Answer Sound offset and player menu toggle feat: Add configurable Answer Sound offset and player menu toggle Sep 1, 2025
@AdemJensen
Copy link
Copy Markdown
Contributor Author

@clansty 牢大,能帮我 merge 一下吗?我没权限

@clansty
Copy link
Copy Markdown
Member

clansty commented Sep 6, 2025

忘了,对不起

@clansty clansty merged commit eb82f1f into MuNET-OSS:main Sep 6, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants