feat(ui): port retail gameplay indicator bar
Promote all seven LayoutDesc 0x21000071 controls to retained buttons, drive link quality, effects, Vitae, and burden from live state, and route Character Information plus end-session confirmation through the shared UI owners. Keep network timing in WorldSession and pin retail thresholds, flash cadence, authored states, and action routing with focused conformance tests. Release build and all 5,807 tests pass with five intentional skips. Connected visual gate pending. Co-authored-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
parent
06016014bc
commit
52c529be86
15 changed files with 857 additions and 204 deletions
|
|
@ -8,6 +8,7 @@ using AcDream.App.UI.Layout;
|
|||
using AcDream.App.UI.Testing;
|
||||
using AcDream.Core.Combat;
|
||||
using AcDream.Core.Items;
|
||||
using AcDream.Core.Net;
|
||||
using AcDream.Core.Net.Messages;
|
||||
using AcDream.Core.Selection;
|
||||
using AcDream.Core.Spells;
|
||||
|
|
@ -73,6 +74,15 @@ public sealed record FpsRuntimeBindings(
|
|||
Func<double> DegradeMultiplier,
|
||||
Func<bool> IsVisible);
|
||||
|
||||
public sealed record IndicatorRuntimeBindings(
|
||||
Spellbook Spellbook,
|
||||
ClientObjectTable Objects,
|
||||
Func<uint> PlayerGuid,
|
||||
Func<int?> Strength,
|
||||
Func<LinkStatusSnapshot> LinkStatus,
|
||||
Func<double> CurrentTime,
|
||||
Action EndCharacterSession);
|
||||
|
||||
public sealed record ToolbarRuntimeBindings(
|
||||
ClientObjectTable Objects,
|
||||
Func<IReadOnlyList<ShortcutEntry>> Shortcuts,
|
||||
|
|
@ -142,6 +152,7 @@ public sealed record RetailUiRuntimeBindings(
|
|||
MagicRuntimeBindings Magic,
|
||||
JumpPowerbarRuntimeBindings JumpPowerbar,
|
||||
FpsRuntimeBindings Fps,
|
||||
IndicatorRuntimeBindings Indicators,
|
||||
ToolbarRuntimeBindings Toolbar,
|
||||
CharacterRuntimeBindings Character,
|
||||
InventoryRuntimeBindings Inventory,
|
||||
|
|
@ -234,7 +245,7 @@ public sealed class RetailUiRuntime : IDisposable
|
|||
public SpellbookWindowController? SpellbookWindowController { get; private set; }
|
||||
public EffectsUiController? PositiveEffectsController { get; private set; }
|
||||
public EffectsUiController? NegativeEffectsController { get; private set; }
|
||||
public EffectsIndicatorController? EffectsIndicatorController { get; private set; }
|
||||
public IndicatorBarController? IndicatorBarController { get; private set; }
|
||||
public JumpPowerbarController? JumpPowerbarController { get; private set; }
|
||||
public RetailFpsController? FpsController { get; private set; }
|
||||
public SelectedObjectController? SelectedObjectController { get; private set; }
|
||||
|
|
@ -263,6 +274,7 @@ public sealed class RetailUiRuntime : IDisposable
|
|||
SpellcastingUiController?.Tick();
|
||||
PositiveEffectsController?.Tick();
|
||||
NegativeEffectsController?.Tick();
|
||||
IndicatorBarController?.Tick();
|
||||
JumpPowerbarController?.Tick();
|
||||
SelectedObjectController?.Tick(deltaSeconds);
|
||||
DialogFactory?.Tick();
|
||||
|
|
@ -894,24 +906,32 @@ public sealed class RetailUiRuntime : IDisposable
|
|||
|
||||
private void MountIndicators()
|
||||
{
|
||||
ImportedLayout? layout = Import(EffectsIndicatorController.LayoutId);
|
||||
ImportedLayout? layout = Import(IndicatorBarController.LayoutId);
|
||||
if (layout is null)
|
||||
{
|
||||
Console.WriteLine("[M3] effects indicators: LayoutDesc 0x21000071 not found.");
|
||||
Console.WriteLine("[UI] indicator bar: LayoutDesc 0x21000071 not found.");
|
||||
return;
|
||||
}
|
||||
|
||||
EffectsIndicatorController? controller = Layout.EffectsIndicatorController.Bind(
|
||||
IndicatorRuntimeBindings b = _bindings.Indicators;
|
||||
IndicatorBarController? controller = Layout.IndicatorBarController.Bind(
|
||||
layout,
|
||||
_bindings.Magic.Spellbook,
|
||||
panelId => _panelUi.TogglePanel(panelId));
|
||||
new IndicatorBarBindings(
|
||||
b.Spellbook,
|
||||
b.Objects,
|
||||
b.PlayerGuid,
|
||||
b.Strength,
|
||||
b.LinkStatus,
|
||||
b.CurrentTime,
|
||||
panelId => _panelUi.TogglePanel(panelId),
|
||||
RequestEndCharacterSession));
|
||||
if (controller is null)
|
||||
{
|
||||
Console.WriteLine("[M3] effects indicators: authored Helpful/Harmful buttons missing.");
|
||||
Console.WriteLine("[UI] indicator bar: one or more authored controls are missing.");
|
||||
return;
|
||||
}
|
||||
|
||||
EffectsIndicatorController = controller;
|
||||
IndicatorBarController = controller;
|
||||
RetailWindowFrame.Mount(
|
||||
Host.Root,
|
||||
layout.Root,
|
||||
|
|
@ -930,7 +950,26 @@ public sealed class RetailUiRuntime : IDisposable
|
|||
ContentClickThrough = false,
|
||||
Controller = controller,
|
||||
});
|
||||
Console.WriteLine("[M3] retail Helpful/Harmful effect indicators from LayoutDesc 0x21000071.");
|
||||
Console.WriteLine("[UI] retail seven-control indicator bar from LayoutDesc 0x21000071.");
|
||||
}
|
||||
|
||||
private void RequestEndCharacterSession()
|
||||
{
|
||||
const string fallback = "Are you sure you want to end this character session?";
|
||||
string message;
|
||||
lock (_bindings.Assets.DatLock)
|
||||
{
|
||||
message = new DatStringResolver(_bindings.Assets.Dats).Resolve(
|
||||
0x23000001u,
|
||||
DatStringResolver.ComputeHash("ID_Client_EndCharacterSessionConfirm"))
|
||||
?? fallback;
|
||||
}
|
||||
|
||||
ShowConfirmation(message, accepted =>
|
||||
{
|
||||
if (accepted)
|
||||
_bindings.Indicators.EndCharacterSession();
|
||||
});
|
||||
}
|
||||
|
||||
private void MountJumpPowerbar()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue