From f24fc7c643d846e3ea5c0f6a97122862290df066 Mon Sep 17 00:00:00 2001 From: gamer147 Date: Mon, 1 Jun 2026 14:49:52 -0400 Subject: [PATCH] feat(battle-node): BuildOpponentTurnEnd builder for v1.1 turn loop Pairs with BuildOpponentTurnStart. Wire shape from prod capture (turnState=0, resultCode=1). Single test locks uri, ViewerId, Cat, and body shape. --- SVSim.BattleNode/Lifecycle/ScriptedLifecycle.cs | 9 +++++++++ .../BattleNode/Lifecycle/ScriptedLifecycleTests.cs | 13 +++++++++++++ 2 files changed, 22 insertions(+) diff --git a/SVSim.BattleNode/Lifecycle/ScriptedLifecycle.cs b/SVSim.BattleNode/Lifecycle/ScriptedLifecycle.cs index 801d90b..d8ec94c 100644 --- a/SVSim.BattleNode/Lifecycle/ScriptedLifecycle.cs +++ b/SVSim.BattleNode/Lifecycle/ScriptedLifecycle.cs @@ -107,6 +107,15 @@ public static class ScriptedLifecycle EnvelopeForPush(NetworkBattleUri.TurnStart, new OpponentTurnStartBody(Spin: ScriptedProfiles.OpponentTurnStartSpin)); + /// + /// Server-pushed TurnEnd transition that closes the opponent's turn and hands control + /// back to the player. Paired with in the v1.1 loop. + /// Wire shape from prod capture battle-traffic_tk2_regular.ndjson L18: + /// {"uri":"TurnEnd","turnState":0,"resultCode":1,"playSeq":N}. + /// + public static MsgEnvelope BuildOpponentTurnEnd() => + EnvelopeForPush(NetworkBattleUri.TurnEnd, new TurnEndBody(TurnState: 0)); + private static IReadOnlyList BuildPosIdxList(IReadOnlyList hand) { var list = new List(hand.Count); diff --git a/SVSim.UnitTests/BattleNode/Lifecycle/ScriptedLifecycleTests.cs b/SVSim.UnitTests/BattleNode/Lifecycle/ScriptedLifecycleTests.cs index f78257a..c4c3881 100644 --- a/SVSim.UnitTests/BattleNode/Lifecycle/ScriptedLifecycleTests.cs +++ b/SVSim.UnitTests/BattleNode/Lifecycle/ScriptedLifecycleTests.cs @@ -153,6 +153,19 @@ public class ScriptedLifecycleTests Assert.That(body.Spin, Is.EqualTo(100)); } + [Test] + public void BuildOpponentTurnEnd_emits_TurnEnd_uri_with_turn_state_zero() + { + var env = ScriptedLifecycle.BuildOpponentTurnEnd(); + + Assert.That(env.Uri, Is.EqualTo(NetworkBattleUri.TurnEnd)); + Assert.That(env.ViewerId, Is.EqualTo(ScriptedLifecycle.FakeOpponentViewerId)); + Assert.That(env.Cat, Is.EqualTo(EmitCategory.Battle)); + var body = (TurnEndBody)env.Body; + Assert.That(body.TurnState, Is.EqualTo(0)); + Assert.That(body.ResultCode, Is.EqualTo(1)); + } + private static MatchContext FixtureCtx(IReadOnlyList? deck = null) => new( SelfDeckCardIds: deck ?? Enumerable.Range(1, 30).Select(i => 100_011_010L).ToList(), ClassId: "1", CharaId: "1", CardMasterName: "card_master_node_10015",