Skip to content

Handling for music_play_instrument_mastery condition type - #563

Merged
AngeloTadeucci merged 1 commit into
MS2Community:masterfrom
Tandashi:fix/#484/music-mastery-trophies
Aug 30, 2025
Merged

Handling for music_play_instrument_mastery condition type#563
AngeloTadeucci merged 1 commit into
MS2Community:masterfrom
Tandashi:fix/#484/music-mastery-trophies

Conversation

@Tandashi

@Tandashi Tandashi commented Aug 27, 2025

Copy link
Copy Markdown
Contributor

Overview

Handling of mastery updates has been changed to properly update the music_play_instrument_mastery.
This now enables the following Trophies to work properly:

Furthermore the /player mastery exp command has been updated to now add exp rather then set the mastery value to the specified exp value as this causes issues for trophy tracking and is now more inline with the actual description.

Additionally the RewardGrade for Trophies has been miscalculated if they had no reward but had more additional grades that needed completing. Previously the RewardGrade had been increased past the actual Grade of the Trophy to mark it as completed. This was only correct for trophies that did not have additional Grades like e.g. music performance trophies causing the UI to skip to the next Grade (VII) for display although V was only completed and VI is still in progress.

Closes: #484
Refs: #33

Video

2025-08-27_10-57-11.mp4

Summary by CodeRabbit

  • New Features

    • Added support for evaluating music instrument mastery in conditions (enables related quests/achievements).
  • Bug Fixes

    • Mastery EXP now accumulates correctly instead of overwriting progress.
    • Achievement rewards no longer skip ahead when a grade lacks a reward; trophy display and final-grade completion behave correctly.
  • Refactor

    • Mastery update logic streamlined with improved, type-specific handling and enhanced debug logging.

@coderabbitai

coderabbitai Bot commented Aug 27, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Implements delta-based mastery updates with per-type handlers, adds music-instrument mastery condition checks, adjusts achievement reward-grade progression when rewards are missing, and replaces the single MasteryExp admin command with nested addexp/setexp commands.

Changes

Cohort / File(s) Summary
Mastery manager refactor
Maple2.Server.Game/Manager/MasteryManager.cs
Reworks mastery set flow to compute deltaLevel/deltaExp, adds Serilog debug logging, and delegates changes to new helpers for level increases/decreases and exp gains. Special-cases Music (music_play_grade, music_play_instrument_mastery) and Fishing (fisher_grade).
Condition checks update
Maple2.Server.Game/Util/ConditionUtil.cs
Adds support for ConditionType.music_play_instrument_mastery in both CheckCode and CheckTarget numeric/range evaluation paths.
Achievement reward-grade flow
Maple2.Server.Game/Manager/AchievementManager.cs
When a grade has no reward but further grades exist, clamps/adjusts Achievement.RewardGrade to not advance past the current grade; only auto-advances when on the final grade without reward.
Admin/player commands
Maple2.Server.Game/Commands/PlayerCommand.cs
Replaces original MasteryExp command with nested mastery addexp and mastery setexp subcommands; addexp increments session mastery value, setexp assigns it. Error handling/exit codes preserved.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor ServerProcess
  participant MasteryManager
  participant ConditionUtil
  participant AchievementManager
  participant DB

  ServerProcess->>MasteryManager: set(masterType, startLevel,startValue,currentLevel,value,meta)
  MasteryManager->>MasteryManager: compute deltaLevel, deltaExp
  alt deltaLevel > 0
    MasteryManager->>DB: update level counters (music_play_grade / fisher_grade / mastery_grade)
  else deltaLevel < 0
    MasteryManager->>DB: set_mastery_grade (decrease)
  end
  alt deltaExp > 0
    MasteryManager->>DB: update exp counters (music_play_instrument_mastery for Music)
  end
  MasteryManager->>ConditionUtil: evaluate music_play_instrument_mastery (if relevant)
  ConditionUtil-->>MasteryManager: condition result
  MasteryManager->>AchievementManager: notify potential achievement/trophy
  AchievementManager->>DB: check grade reward
  alt reward exists
    AchievementManager->>ServerProcess: grant reward
  else no reward & hasMoreGrades
    AchievementManager->>DB: clamp RewardGrade ≤ currentGrade and return
  else last grade
    AchievementManager->>DB: advance RewardGrade and return
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

Assessment against linked issues

Objective Addressed Explanation
Award Music Performance trophies on mastery level up (#484)
Trigger achievement conditions for music instrument mastery (#484)
Ensure achievement reward-grade progression aligns with current grade for music-related trophies (#484)

Assessment against linked issues: Out-of-scope changes

Code Change Explanation
Change Mastery admin command to nested addexp/setexp (Maple2.Server.Game/Commands/PlayerCommand.cs) Admin tooling change not required by #484 (trophy awarding); unrelated to the bug objective.
Special-case Fishing grade updates (Maple2.Server.Game/Manager/MasteryManager.cs) Fishing-specific grade handling is not mentioned in #484 (which targets music performance trophies).

Possibly related PRs

Suggested reviewers

  • Zintixx
  • AngeloTadeucci

Poem

A carrot chord beneath the moon,
My paws tap out a jaunty tune.
Grades jump up and trophies gleam,
Strings and hops achieve the dream.
Hop, strum, hooray — rewards redeemed. 🥕🎻

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Maple2.Server.Game/Manager/AchievementManager.cs (1)

136-140: Condition type mismatch: hero_achieve vs hero_achieve_grade

RankUp sends ConditionType.hero_achieve, but ConditionUtil handles hero_achieve_grade. This likely prevents those conditions from ever matching.

-            session.ConditionUpdate(ConditionType.hero_achieve, codeLong: achievement.Id, targetLong: achievement.CurrentGrade);
+            session.ConditionUpdate(ConditionType.hero_achieve_grade, codeLong: achievement.Id, targetLong: achievement.CurrentGrade);

If hero_achieve is expected elsewhere, alternatively add handling for hero_achieve in ConditionUtil.

🧹 Nitpick comments (5)
Maple2.Server.Game/Util/ConditionUtil.cs (1)

239-254: Target check for instrument mastery should not be unconditional true

Right now, CheckTarget returns true for music_play_instrument_mastery regardless of target parameters, which could accept unintended updates if metadata ever supplies target filters. Align it with the nearby music-play conditions that honor target.Integers/Range.

Proposed change: move music_play_instrument_mastery into the block that validates target.Range/target.Integers and remove it from the unconditional-true block.

@@
-            case ConditionType.skill:
-            case ConditionType.music_play_instrument_time:
-            case ConditionType.music_play_score:
-            case ConditionType.music_play_ensemble_in:
+            case ConditionType.skill:
+            case ConditionType.music_play_instrument_time:
+            case ConditionType.music_play_score:
+            case ConditionType.music_play_ensemble_in:
+            case ConditionType.music_play_instrument_mastery:
                 if (target.Range != null && target.Range.Value.Min >= longValue &&
                     target.Range.Value.Max <= longValue) {
                     return true;
                 }
 
                 if (target.Integers != null && target.Integers.Contains((int) longValue)) {
                     return true;
                 }
                 break;
@@
-            case ConditionType.music_play_grade:
-            case ConditionType.music_play_ensemble:
-            case ConditionType.music_play_instrument_mastery:
+            case ConditionType.music_play_grade:
+            case ConditionType.music_play_ensemble:
                 return true;

Also applies to: 275-276

Maple2.Server.Game/Manager/AchievementManager.cs (1)

169-177: Use a more precise “has more grades” check

Comparing count to CurrentGrade assumes contiguous grade keys starting at 1. Safer to compare against the max grade key.

-        bool hasMoreGrades = achievement.Metadata.Grades.Count > achievement.CurrentGrade;
+        int maxGradeKey = achievement.Metadata.Grades.Keys.Max();
+        bool hasMoreGrades = achievement.CurrentGrade < maxGradeKey;
Maple2.Server.Game/Commands/PlayerCommand.cs (1)

37-45: Update help text and validate positive EXP

The command now adds EXP; reflect that in descriptions and guard against non-positive input to avoid no-op/confusion.

-            public MasteryExpCommand(GameSession session) : base("exp", "Set player mastery experience.") {
+            public MasteryExpCommand(GameSession session) : base("exp", "Add player mastery experience.") {
@@
-                var exp = new Argument<int>("exp", "Experience points to add.");
+                var exp = new Argument<int>("exp", "Experience points to add (positive).");

Add minimal validation near the handler:

-            private void Handle(InvocationContext ctx, MasteryType masteryType, int exp) {
+            private void Handle(InvocationContext ctx, MasteryType masteryType, int exp) {
                 try {
+                    if (exp <= 0) {
+                        ctx.Console.Error.WriteLine("exp must be a positive integer.");
+                        ctx.ExitCode = 1;
+                        return;
+                    }
                     session.Mastery[masteryType] = session.Mastery[masteryType] + exp;
Maple2.Server.Game/Manager/MasteryManager.cs (2)

108-120: Propagate multi-level jumps to mastery_grade

Default branch increments mastery_grade by 1 even if multiple levels were gained. Use counter: deltaLevel for accuracy.

-            default:
-                session.ConditionUpdate(ConditionType.mastery_grade, codeLong: (int) type);
+            default:
+                session.ConditionUpdate(ConditionType.mastery_grade, counter: deltaLevel, codeLong: (int) type);
                 return;

138-145: Skip zero/negative EXP deltas and avoid category 0 emissions

Prevent no-op traffic and avoid sending category 0 (unknown instrument), which could misclassify progress.

-    private void HandleMasteryExpIncrease(MasteryType type, int deltaExp) {
+    private void HandleMasteryExpIncrease(MasteryType type, int deltaExp) {
+        if (deltaExp <= 0) return;
         switch (type) {
             case MasteryType.Music:
-                session.ConditionUpdate(ConditionType.music_play_instrument_mastery, counter: deltaExp, codeLong: session.Instrument?.Value.Category ?? 0);
+                var category = session.Instrument?.Value.Category ?? 0;
+                if (category > 0) {
+                    session.ConditionUpdate(ConditionType.music_play_instrument_mastery, counter: deltaExp, codeLong: category);
+                }
                 return;
             default:
                 return;
         }
     }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 6dbc50a and 1cc95c1.

📒 Files selected for processing (4)
  • Maple2.Server.Game/Commands/PlayerCommand.cs (1 hunks)
  • Maple2.Server.Game/Manager/AchievementManager.cs (1 hunks)
  • Maple2.Server.Game/Manager/MasteryManager.cs (2 hunks)
  • Maple2.Server.Game/Util/ConditionUtil.cs (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
Maple2.Server.Game/Commands/PlayerCommand.cs (1)
Maple2.Model/Game/User/Mastery.cs (1)
  • Mastery (7-35)
Maple2.Server.Game/Manager/MasteryManager.cs (1)
Maple2.Server.Game/Session/GameSession.cs (1)
  • ConditionUpdate (551-554)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build
  • GitHub Check: build
🔇 Additional comments (3)
Maple2.Server.Game/Util/ConditionUtil.cs (1)

113-131: Good addition: code-side filtering for instrument mastery

Adding music_play_instrument_mastery to the code-based range/integer checks is correct and aligns with how fisher_grade et al. are handled.

Maple2.Server.Game/Manager/AchievementManager.cs (1)

169-177: Fix prevents RewardGrade from leapfrogging CurrentGrade when no reward exists

The hasMoreGrades guard and capped increment resolve the UI-grade skip. Looks good.

Maple2.Server.Game/Commands/PlayerCommand.cs (1)

50-51: Correct: switch to additive mastery EXP

Changing to additive semantics matches the command’s intent and avoids overwriting progress.

Comment thread Maple2.Server.Game/Manager/MasteryManager.cs

private void Handle(InvocationContext ctx, MasteryType masteryType, int exp) {
try {
session.Mastery[masteryType] = exp;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

if its a set command we shouldn't add.

@Tandashi Tandashi Aug 28, 2025

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Will change the description of the subcommand. Did forget to do that as the exp positional argument description already describes it as add.

Furthermore adding would be more inline with the other commands e.g. /home as it has exp and setexp subcommands.

If you'd like I can also introduce a setexp subcommand for the mastery command as well.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

i think would be better to introduce a subcommand like setexp/addexp

Comment thread Maple2.Server.Game/Manager/MasteryManager.cs
Comment on lines +88 to +93
if (deltaLevel > 0) {
HandleMasteryLevelIncrease(type, currentLevel, deltaLevel);
}
if (startLevel > currentLevel) {
session.ConditionUpdate(ConditionType.set_mastery_grade, codeLong: (int) type);
if (type == MasteryType.Music) {
session.ConditionUpdate(ConditionType.music_play_grade);
}

if (deltaLevel < 0) {
HandleMasteryLevelDecrease(type);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

agreed with tade that I don't think we need to make the HandleMasteryLevelIncrease/Decrease be their own functions with only 1 use.

small nit but this should be an else if statement

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah might have been a bit of premature optimization from my part. Will change that to be a singular function instead once I am back home on Saturday/Sunday :)

Handling of mastery updates has been changed to properly update the `music_play_instrument_mastery`.
This now enables the following Trophies to work properly:
- https://handbook.tadeucci.dev/trophies/23100142
- https://handbook.tadeucci.dev/trophies/23100143
- https://handbook.tadeucci.dev/trophies/23100144
- https://handbook.tadeucci.dev/trophies/23100168
- https://handbook.tadeucci.dev/trophies/23100169
- https://handbook.tadeucci.dev/trophies/23100170
- https://handbook.tadeucci.dev/trophies/23100178
- https://handbook.tadeucci.dev/trophies/23100179
- https://handbook.tadeucci.dev/trophies/23100180
- https://handbook.tadeucci.dev/trophies/23100197
- https://handbook.tadeucci.dev/trophies/23100198
- https://handbook.tadeucci.dev/trophies/23100199
- https://handbook.tadeucci.dev/trophies/23100224
- https://handbook.tadeucci.dev/trophies/23100225
- https://handbook.tadeucci.dev/trophies/23100226
- https://handbook.tadeucci.dev/trophies/23100232
- https://handbook.tadeucci.dev/trophies/23100233
- https://handbook.tadeucci.dev/trophies/23100234
- https://handbook.tadeucci.dev/trophies/23100235
- https://handbook.tadeucci.dev/trophies/23100236
- https://handbook.tadeucci.dev/trophies/23100237
- https://handbook.tadeucci.dev/trophies/23100254
- https://handbook.tadeucci.dev/trophies/23100255
- https://handbook.tadeucci.dev/trophies/23100256
- https://handbook.tadeucci.dev/trophies/23100277
- https://handbook.tadeucci.dev/trophies/23100278
- https://handbook.tadeucci.dev/trophies/23100310
- https://handbook.tadeucci.dev/trophies/23100311
- https://handbook.tadeucci.dev/trophies/23100353
- https://handbook.tadeucci.dev/trophies/23100354
- https://handbook.tadeucci.dev/trophies/23100355
- https://handbook.tadeucci.dev/trophies/23100410
- https://handbook.tadeucci.dev/trophies/23100411
- https://handbook.tadeucci.dev/trophies/23100412
- https://handbook.tadeucci.dev/trophies/23100413

Furthermore the `/player mastery exp` command has been updated to now add exp rather then set the
mastery value to the specified exp value as this causes issues for trophy tracking and is now more inline
with the actual description.

Additionally the `RewardGrade` for Trophies has been miscalculated if they had no reward but had more
additional grades that needed completing. Previously the `RewardGrade` had been increased past the
actual `Grade` of the Trophy to mark it as completed. This was only correct for trophies that did not
have additional `Grades` like e.g. music performance trophies causing the UI to skip to the next
`Grade` for display.

Refs: MS2Community#484
@Tandashi
Tandashi force-pushed the fix/#484/music-mastery-trophies branch from 1cc95c1 to 77a6879 Compare August 30, 2025 11:28

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
Maple2.Server.Game/Commands/PlayerCommand.cs (1)

101-106: NRE risk when requested level is below the first reward threshold.

FirstOrDefault(...) can return default KVP; accessing .Value.Value will throw.

- exp = masteryRewardMetadata.OrderByDescending(mastery => mastery.Key).FirstOrDefault(mastery => level >= mastery.Key).Value.Value;
+ var kvp = masteryRewardMetadata
+     .OrderByDescending(m => m.Key)
+     .FirstOrDefault(m => level >= m.Key);
+ exp = kvp.Equals(default(KeyValuePair<int, MasteryRewardTable.Entry>)) ? 0 : kvp.Value.Value;

Also consider validating “level” against table min/max and emitting a friendly error when out of range.

Maple2.Server.Game/Manager/MasteryManager.cs (1)

41-81: Indexer forbids decreases; negative delta paths are dead code.

Math.Clamp(value, current, max) prevents lowering mastery, so deltaLevel < 0 never occurs. If decreases should be possible (admin fixes, rollbacks), expose an absolute setter and compute deltas against the requested value before clamping.

- set {
+ set {
+     // Consider: if a privileged "absolute" path is required, delegate here to a SetAbsolute(...) that clamps [0..max].

Also update callers (setexp/level) to use the absolute path when intended.

♻️ Duplicate comments (2)
Maple2.Server.Game/Commands/PlayerCommand.cs (1)

30-33: Splitting exp into addexp and setexp is the right call.

Matches prior review direction and avoids ambiguity.

Maple2.Server.Game/Manager/MasteryManager.cs (1)

84-90: Delta level overcounts when startValue == 0 (false level-up).

Remove the +1; this generates spurious level-ups (e.g., 0→0). Also skip processing when no actual change.

- int deltaLevel = currentLevel - startLevel + (startValue == 0 ? 1 : 0);
- int deltaExp = value - startValue;
+ int deltaLevel = currentLevel - startLevel;
+ int deltaExp = value - startValue;
+ if (deltaLevel == 0 && deltaExp <= 0) {
+     return;
+ }
🧹 Nitpick comments (4)
Maple2.Server.Game/Commands/PlayerCommand.cs (2)

29-33: Rename command description to reflect multiple subcommands.

“Set player mastery.” is misleading now that we have addexp and setexp. Suggest “Manage player mastery.”

-        public MasteryCommand(GameSession session) : base("mastery", "Set player mastery.") {
+        public MasteryCommand(GameSession session) : base("mastery", "Manage player mastery.") {

35-58: Minor duplication in addexp/setexp handlers.

Both blocks share argument wiring and try/catch patterns. Optional: factor a small helper to reduce duplication.

Also applies to: 60-73

Maple2.Server.Game/Manager/MasteryManager.cs (2)

130-137: Avoid no-op condition updates.

Guard HandleMasteryExpIncrease with deltaExp > 0 to reduce noise.

- private void HandleMasteryExpIncrease(MasteryType type, int deltaExp) {
+ private void HandleMasteryExpIncrease(MasteryType type, int deltaExp) {
+     if (deltaExp <= 0) return;

94-101: Comment nit: fix grammar.

“The type of mastery whos level...” -> “whose level...”

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 1cc95c1 and 77a6879.

📒 Files selected for processing (4)
  • Maple2.Server.Game/Commands/PlayerCommand.cs (2 hunks)
  • Maple2.Server.Game/Manager/AchievementManager.cs (1 hunks)
  • Maple2.Server.Game/Manager/MasteryManager.cs (2 hunks)
  • Maple2.Server.Game/Util/ConditionUtil.cs (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • Maple2.Server.Game/Manager/AchievementManager.cs
🧰 Additional context used
🧬 Code graph analysis (2)
Maple2.Server.Game/Commands/PlayerCommand.cs (2)
Maple2.Server.Game/Session/GameSession.cs (3)
  • GameSession (36-852)
  • GameSession (114-124)
  • GameSession (742-742)
Maple2.Model/Game/User/Mastery.cs (1)
  • Mastery (7-35)
Maple2.Server.Game/Manager/MasteryManager.cs (1)
Maple2.Server.Game/Session/GameSession.cs (1)
  • ConditionUpdate (551-554)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build
  • GitHub Check: build
🔇 Additional comments (4)
Maple2.Server.Game/Util/ConditionUtil.cs (2)

113-132: Correctly routes music_play_instrument_mastery through numeric code checks.

Adding to the numeric code path aligns with using codeLong = instrument category. Looks good.


275-330: Verify achievement metadata for music_play_instrument_mastery
No JSON/CSV/XML metadata entries for this condition were found—manually confirm that any achievement definitions for music_play_instrument_mastery use the integer Code (category) and Value (threshold) fields for gating, and do not rely on Target.

Maple2.Server.Game/Manager/MasteryManager.cs (2)

111-121: Music/fishing/other grade updates look correct.

Mappings to fisher_grade, music_play_grade, and mastery_grade are consistent with ConditionUtil dispatch.


132-135: Verify music_play_instrument_mastery achievements handle codeLong = 0
Confirm no achievement definitions for music_play_instrument_mastery filter on non-zero Codes, since session.Instrument may be null (category 0) and admin awards would otherwise skip progress.

Comment on lines +49 to +57
private void Handle(InvocationContext ctx, MasteryType masteryType, int exp) {
try {
session.Mastery[masteryType] = session.Mastery[masteryType] + exp;
ctx.ExitCode = 0;
} catch (SystemException ex) {
ctx.Console.Error.WriteLine(ex.Message);
ctx.ExitCode = 1;
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

⚠️ Potential issue

setexp cannot decrease mastery due to clamping in MasteryManager indexer.

Both addexp and setexp route through session.Mastery[...] which clamps to [current..max]; setexp cannot lower EXP/level, contrary to “Set” semantics. Provide an absolute setter or an override path for admin commands.

- session.Mastery[masteryType] = exp;
+ // Introduce an absolute setter on MasteryManager that clamps [0..max] and allows decreases:
+ // session.Mastery.SetAbsolute(masteryType, exp);

If you prefer to keep the indexer strict, inject a bool allowDecrease into the indexer (default false) and use it only from admin commands.

Also applies to: 74-82

🤖 Prompt for AI Agents
In Maple2.Server.Game/Commands/PlayerCommand.cs around lines 49-57 (and also
apply same change to 74-82): setexp currently uses session.Mastery[...] which
clamps increases only and so cannot lower mastery; change the admin command to
call an absolute setter on the MasteryManager (or add an optional bool
allowDecrease=false parameter to the MasteryManager indexer) and pass true from
admin commands so the value is applied without clamping; update the admin paths
to use the new setter/override and keep the default clamping behavior for normal
gameplay.

@AngeloTadeucci
AngeloTadeucci merged commit f9713ff into MS2Community:master Aug 30, 2025
4 checks passed
@Tandashi
Tandashi deleted the fix/#484/music-mastery-trophies branch August 30, 2025 20:48
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.

Music Performance Trophies not given on mastery level up

3 participants