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

@ -451,6 +451,47 @@ public class DatWidgetFactoryTests
Assert.Equal(gold, t.DefaultColor);
}
[Fact]
public void HorizontalScrollbar_PreservesNestedCombatMeterFillSprite()
{
var track = new ElementInfo { Id = 4, Type = 3, Width = 507, Height = 14 };
track.StateMedia[""] = (0x06001919u, 1);
track.States[UiStateInfo.DirectStateId] = new UiStateInfo
{ Id = UiStateInfo.DirectStateId, Image = new UiImageMedia(0x06001919u, 1) };
var thumb = new ElementInfo { Id = 1, Type = 1, Width = 12, Height = 14 };
thumb.StateMedia[""] = (0x06001923u, 1);
thumb.States[UiStateInfo.DirectStateId] = new UiStateInfo
{ Id = UiStateInfo.DirectStateId, Image = new UiImageMedia(0x06001923u, 1) };
var fill = new ElementInfo { Id = 2, Type = 3, Width = 507, Height = 14 };
fill.StateMedia[""] = (0x06001200u, 1);
fill.States[UiStateInfo.DirectStateId] = new UiStateInfo
{ Id = UiStateInfo.DirectStateId, Image = new UiImageMedia(0x06001200u, 1) };
var meter = new ElementInfo
{
Id = CombatUiController.PowerControlId + 1,
Type = 7,
Width = 507,
Height = 14,
Children = [fill],
};
var info = new ElementInfo
{
Id = CombatUiController.PowerControlId,
Type = 11,
Width = 507,
Height = 14,
Children = [track, meter, thumb],
};
var bar = Assert.IsType<UiScrollbar>(
DatWidgetFactory.Create(info, NoTex, null));
Assert.True(bar.Horizontal);
Assert.Equal(0x06001919u, bar.TrackSprite);
Assert.Equal(0x06001923u, bar.ThumbSprite);
Assert.Equal(0x06001200u, bar.ScalarFillSprite);
}
private static ElementInfo TextInfo(params (uint Id, UiPropertyValue Value)[] properties)
{
var info = new ElementInfo { Id = 0x10000016u, Type = 12, Width = 100, Height = 20 };