feat(combat): port retail basic combat bar

Mount authored gmCombatUI, share one press/hold/release request state machine across DAT buttons and keybindings, and recover the exact 1.0s/0.8s power timing from matching retail x86. The same timer fixes jump charge, while ready-stance, response queueing, auto-repeat, layout binding, migration, and conformance coverage keep behavior architectural rather than panel-local.

Co-Authored-By: Codex <codex@openai.com>
This commit is contained in:
Erik 2026-07-11 14:03:28 +02:00
parent 9958458318
commit 2215c76c7e
22 changed files with 1265 additions and 46 deletions

View file

@ -94,6 +94,24 @@ public sealed class CombatInputPlannerTests
Assert.Equal(expected, CombatInputPlanner.SupportsTargetedAttack(mode));
}
[Theory]
[InlineData(CombatMode.Melee, 0x8000003Du, 0u, true)]
[InlineData(CombatMode.Missile, 0x8000003Fu, CombatInputPlanner.ReadyForwardCommand, true)]
[InlineData(CombatMode.Missile, 0x80000041u, CombatInputPlanner.ReadyForwardCommand, true)]
[InlineData(CombatMode.Missile, 0x8000003Du, CombatInputPlanner.ReadyForwardCommand, false)]
[InlineData(CombatMode.Missile, 0x8000003Fu, 0x41000006u, false)]
[InlineData(CombatMode.NonCombat, 0x8000003Du, CombatInputPlanner.ReadyForwardCommand, false)]
public void PlayerInReadyPositionForAttack_MatchesRetailAttackBranch(
CombatMode mode,
uint style,
uint forward,
bool expected)
{
Assert.Equal(
expected,
CombatInputPlanner.PlayerInReadyPositionForAttack(mode, style, forward));
}
private static ClientObject Equipped(
EquipMask location,
ItemType type,