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

@ -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()
{