feat(mission): wire class_level_up emits from every XP-granting controller
Every _xp.GrantAsync callsite now conditionally emits class_level_up:{class}
when the returned BattleXpGrantResult.LeveledUp is true. Six callsites total:
- PracticeController.Finish
- RankBattleController.FinishInternal
- FreeBattleController.Finish
- ArenaTwoPickBattleController.Finish (LeveledUp + ClassId routed via
BattleFinishResultDto — controller-side signals, not on wire)
- ArenaColosseumBattleController (missed in the original wire-up survey;
colosseum-battle XP now also fires the level-up event when applicable)
- StoryController.Finish (LeveledUp + ClassId routed via new
StoryFinishOutcome wrapper, mirroring the TK2 RunFinishOutcome pattern)
Story's IStoryService.FinishAsync now returns StoryFinishOutcome instead of
FinishResponse directly. Test callsites updated to unwrap .Response.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,8 @@ namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses.ArenaTwoPick;
|
||||
/// What the battle controller needs from the service to build the standard battle-finish
|
||||
/// envelope (class XP delta + post-state, spot points before/add/after, battle_result echo).
|
||||
/// Achieved-info is built by the controller from IMissionAssembler.
|
||||
/// <see cref="LeveledUp"/> and <see cref="ClassId"/> are controller-side signals for the
|
||||
/// class_level_up mission emit and are not serialized to the wire.
|
||||
/// </summary>
|
||||
public class BattleFinishResultDto
|
||||
{
|
||||
@@ -14,4 +16,6 @@ public class BattleFinishResultDto
|
||||
public int BeforeSpotPoint { get; set; }
|
||||
public int AddSpotPoint { get; set; }
|
||||
public int AfterSpotPoint { get; set; }
|
||||
public bool LeveledUp { get; set; }
|
||||
public int ClassId { get; set; }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Story;
|
||||
|
||||
/// <summary>
|
||||
/// What <c>IStoryService.FinishAsync</c> returns to <c>StoryController.Finish</c>.
|
||||
/// <see cref="Response"/> is the wire payload; <see cref="LeveledUp"/> and
|
||||
/// <see cref="ClassId"/> are controller-side signals for the class_level_up mission emit
|
||||
/// and are never serialized. <see cref="ClassId"/> is nullable because skip-shape finishes
|
||||
/// (no class chosen) don't grant XP and therefore can't level anything up.
|
||||
/// </summary>
|
||||
public sealed record StoryFinishOutcome(FinishResponse Response, bool LeveledUp, int? ClassId);
|
||||
Reference in New Issue
Block a user