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:
parent
9958458318
commit
2215c76c7e
22 changed files with 1265 additions and 46 deletions
|
|
@ -223,6 +223,40 @@ public class KeyBindingsJsonTests
|
|||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LoadOrDefault_migratesV2CombatPressBindingToHold()
|
||||
{
|
||||
var path = TempFile();
|
||||
try
|
||||
{
|
||||
const string json = """
|
||||
{
|
||||
"version": 2,
|
||||
"actions": {
|
||||
"CombatHighAttack": [
|
||||
{ "key": "F7" }
|
||||
]
|
||||
}
|
||||
}
|
||||
""";
|
||||
File.WriteAllText(path, json);
|
||||
|
||||
var loaded = KeyBindings.LoadOrDefault(path);
|
||||
|
||||
Assert.Equal(InputAction.CombatHighAttack,
|
||||
loaded.Find(
|
||||
new KeyChord(Key.F7, ModifierMask.None),
|
||||
ActivationType.Hold)?.Action);
|
||||
Assert.Null(loaded.Find(
|
||||
new KeyChord(Key.F7, ModifierMask.None),
|
||||
ActivationType.Press));
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (File.Exists(path)) File.Delete(path);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LoadOrDefault_unknown_action_name_skipped_silently()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -108,6 +108,19 @@ public class KeyBindingsRetailTests
|
|||
Assert.Equal(InputAction.EscapeKey, hit!.Value.Action);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(Key.Delete, InputAction.CombatLowAttack)]
|
||||
[InlineData(Key.End, InputAction.CombatMediumAttack)]
|
||||
[InlineData(Key.PageDown, InputAction.CombatHighAttack)]
|
||||
public void CombatAttackHeightBindings_EmitHoldTransitions(Key key, InputAction action)
|
||||
{
|
||||
var b = KeyBindings.RetailDefaults();
|
||||
|
||||
var hit = b.Find(new KeyChord(key, ModifierMask.None), ActivationType.Hold);
|
||||
|
||||
Assert.Equal(action, hit?.Action);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void QuickSlot_5_bareUsesAndCtrlSelects()
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue