feat(battlenode): attack resolves on engine state via view-untangle (M-HC-4a)
Drive ATTACK frames through the headless receive conductor and assert on engine board state (node-native harness). Two cases: follower -> enemy leader (leader life drops by atk, attacker spent) and a lethal follower-vs-follower trade (both removed). ATTACK opcode confirmed = 10 (NetworkBattleDefine.PlayActionType). Headless view-untangle (no Engine logic edits; drift clean): - IBattlePlayerView.AttackSelectControl -> non-null HeadlessAttackSelectControl (no-op RegisterAttackPair/ResetCardAfterAttack); IsCardTranslatable left to base. - IBattleCardView.CardInfo -> backing card via BuildInfo (so IsCardTranslatable reads authentic IsClass); class/null view ctors now chain : base(buildInfo). - IBattleCardView._inPlayFrameEffect -> non-null no-op control. - Seed Certification.viewer_id headless so the IsRecovery target parse (vid != UserViewerID) does not throw inside SavedataManager and silently drop the parsed targetList. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -53,6 +53,11 @@ namespace Wizard.Battle.View
|
||||
// interface here with no-op members (the leaf PlayerClassBattleCardView inherits them).
|
||||
public abstract class ClassBattleCardViewBase : BattleCardView, IClassBattleCardView
|
||||
{
|
||||
// HEADLESS-FIX (M-HC-4a): forward the BuildInfo to the BattleCardView base so a class (leader)
|
||||
// view's CardInfo resolves to its backing card — the receive ATTACK path reads CardInfo.IsClass
|
||||
// (true for a leader) via AttackSelectControl.IsCardTranslatable when an attack targets the leader.
|
||||
protected ClassBattleCardViewBase() { }
|
||||
protected ClassBattleCardViewBase(BuildInfo buildInfo) : base(buildInfo) { }
|
||||
public virtual Wizard.Battle.Player.ClassCharacter.IClassCharacter ClassCharacter => null;
|
||||
public virtual void StartOutFrame() { }
|
||||
public virtual void StartIntoFrame() { }
|
||||
@@ -60,7 +65,7 @@ namespace Wizard.Battle.View
|
||||
public virtual bool GetCurrentClipIsName(global::ClassCharaPrm.MotionType motionType) => false;
|
||||
public virtual void ClearSpineObject() { }
|
||||
}
|
||||
public class NullBattleCardView : BattleCardView { public NullBattleCardView() { } public NullBattleCardView(BuildInfo buildInfo) { } public static void ReleaseSharedDummy() { } }
|
||||
public class NullBattleCardView : BattleCardView { public NullBattleCardView() { } public NullBattleCardView(BuildInfo buildInfo) : base(buildInfo) { } public static void ReleaseSharedDummy() { } } // HEADLESS-FIX (M-HC-4a): chain BuildInfo so a null-view card's CardInfo still resolves
|
||||
|
||||
// The decomp NullClassBattleCardView is `: NullBattleCardView, IClassBattleCardView, IBattleCardView`;
|
||||
// base-clause recovery kept only the base class. IBattleCardView is satisfied via the BattleCardView
|
||||
|
||||
Reference in New Issue
Block a user