feat(battlenode): evolve resolves on engine state via view-untangle (M-HC-4b)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,7 @@ using NetworkBattleDefine = engine::NetworkBattleDefine;
|
||||
using BattleManagerBase = engine::BattleManagerBase;
|
||||
using BattlePlayerBase = engine::BattlePlayerBase;
|
||||
using BattleCardBase = engine::BattleCardBase;
|
||||
using UnitBattleCard = engine::UnitBattleCard;
|
||||
using ClassBattleCardBase = engine::ClassBattleCardBase;
|
||||
using CardCreatorBase = engine::CardCreatorBase;
|
||||
using CostAddModifier = engine::CostAddModifier;
|
||||
@@ -92,6 +93,16 @@ internal sealed class SessionBattleEngine
|
||||
player.IsSelfTurn = true;
|
||||
enemy.IsSelfTurn = false;
|
||||
|
||||
// Seat the evolve points + evolve-wait-turn counters exactly as the real match-load's
|
||||
// SetupInitialGameState -> SetupEvolCount does (BattleManagerBase.cs:1115/1132). The headless
|
||||
// Setup builds the seats by hand and never runs SetupInitialGameState, so without this both seats'
|
||||
// CurrentEpCount/EvolveWaitTurnCount stay at their field defaults (0/0) and CanEvolution always
|
||||
// fails (CurrentEpCount - GetEp() < 0). doesPlayerGoFirst == false here: seat A (BattlePlayer) is
|
||||
// the SECOND player (IsFirst defaults false; seat A's turn-1 draws 2), so it gets SECOND_PLAYER_EP
|
||||
// (3) + EvolveWaitTurnCount 4, and seat B (BattleEnemy, first) gets FIRST_PLAYER_EP (2) +
|
||||
// EvolveWaitTurnCount 5. TurnEvolveControl (run on each TurnStart receive) counts the wait down.
|
||||
mgr.SetupEvolCount(doesPlayerGoFirst: false);
|
||||
|
||||
InitLeaderLife(mgr); // a 0-life leader reads as game-over and silently blocks plays
|
||||
InitCardTemplates(mgr); // play/draw resolution touches the (no-op) card view layer
|
||||
InitHeadlessViews(mgr); // turn/play cycle dereferences UI-container + emotion refs
|
||||
@@ -201,6 +212,25 @@ internal sealed class SessionBattleEngine
|
||||
public bool InPlayCardAttackable(bool playerSeat, int boardPos) =>
|
||||
Seat(playerSeat).ClassAndInPlayCardList[boardPos + 1].Attackable;
|
||||
|
||||
/// <summary>True once the in-play follower at <paramref name="boardPos"/> (0-based, leader excluded)
|
||||
/// has evolved (<see cref="UnitBattleCard.IsEvolution"/>, set true inside the engine's own
|
||||
/// <c>UnitBattleCard.Evolution</c> mutation). Only <see cref="UnitBattleCard"/> followers carry the
|
||||
/// flag; a non-follower (or the leader) reads false. The evolve test's decisive engine-state assertion
|
||||
/// (M-HC-4b).</summary>
|
||||
public bool IsEvolved(bool playerSeat, int boardPos) =>
|
||||
(Seat(playerSeat).ClassAndInPlayCardList[boardPos + 1] as UnitBattleCard)?.IsEvolution ?? false;
|
||||
|
||||
/// <summary>The seat's current evolve-point count (<see cref="BattlePlayerBase.CurrentEpCount"/>). An
|
||||
/// evolve spends one EP, so the evolve test asserts this decrements by 1. EP is granted at setup by
|
||||
/// the engine's <c>SetupEvolCount</c> (2 for the game-first seat, 3 for the second) and unlocks once
|
||||
/// <c>EvolveWaitTurnCount</c> has counted down (M-HC-4b).</summary>
|
||||
public int Ep(bool playerSeat) => Seat(playerSeat).CurrentEpCount;
|
||||
|
||||
/// <summary>Turns remaining until <paramref name="playerSeat"/> may evolve
|
||||
/// (<see cref="BattlePlayerBase.EvolveWaitTurnCount"/>); 0 means evolve is unlocked. Lets a test ramp to
|
||||
/// the evolve-enabled turn deterministically (M-HC-4b).</summary>
|
||||
public int EvolveWaitTurnCount(bool playerSeat) => Seat(playerSeat).EvolveWaitTurnCount;
|
||||
|
||||
/// <summary>The engine-RESOLVED play-time cost of the card whose engine <c>Index</c> == <paramref name="idx"/>
|
||||
/// on <paramref name="playerSeat"/> (M-HC-3a). This is the discounted cost the play actually paid —
|
||||
/// spellboost reduction, board-dependent modifiers and all — read straight off the engine, so the
|
||||
|
||||
Reference in New Issue
Block a user