feat(ui): port retail dialog factory lifecycle
Replace the single mutable confirmation service with retail's property-backed DialogFactory model: fresh DAT roots, context ids, queue groups, priority preemption, callback/close-notice ordering, and context cancellation. Route /die, server confirmation aborts, and guarded item use through focused semantic owners. Co-Authored-By: Codex <codex@openai.com>
This commit is contained in:
parent
43f7c7807c
commit
66bdae7a83
22 changed files with 1442 additions and 220 deletions
91
src/AcDream.App/UI/GameplayConfirmationController.cs
Normal file
91
src/AcDream.App/UI/GameplayConfirmationController.cs
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
using AcDream.App.UI.Layout;
|
||||
using AcDream.Core.Net.Messages;
|
||||
|
||||
namespace AcDream.App.UI;
|
||||
|
||||
/// <summary>
|
||||
/// Ports the server-driven confirmation ownership in
|
||||
/// <c>gmGamePlayUI @ 0x004E9D70..0x004E9EB6</c>. The dialog factory broadcasts
|
||||
/// completion; this semantic owner retains the server type/context and sends the
|
||||
/// matching confirmation response.
|
||||
/// </summary>
|
||||
public sealed class GameplayConfirmationController : IDisposable
|
||||
{
|
||||
private readonly RetailDialogFactory _dialogs;
|
||||
private readonly Action<uint, uint, bool> _sendResponse;
|
||||
private uint _dialogContext;
|
||||
private uint _serverType;
|
||||
private uint _serverContext;
|
||||
private bool _disposed;
|
||||
|
||||
public GameplayConfirmationController(
|
||||
RetailDialogFactory dialogs,
|
||||
Action<uint, uint, bool> sendResponse)
|
||||
{
|
||||
_dialogs = dialogs ?? throw new ArgumentNullException(nameof(dialogs));
|
||||
_sendResponse = sendResponse ?? throw new ArgumentNullException(nameof(sendResponse));
|
||||
_dialogs.DialogClosed += OnDialogClosed;
|
||||
}
|
||||
|
||||
public uint ActiveDialogContext => _dialogContext;
|
||||
|
||||
public bool HandleRequest(GameEvents.CharacterConfirmationRequest request)
|
||||
{
|
||||
// ClientUISystem::Handle_Character__ConfirmationRequest @ 0x005640A0
|
||||
// routes types 2/3/5/6 to handlers that append " Continue?"; the generic
|
||||
// type-7 YesNo request preserves the server text verbatim. Types 1 and 4
|
||||
// have allegiance/fellowship semantic owners but use the same response
|
||||
// tuple, so this controller retains that tuple until those panels exist.
|
||||
// Each retail RecvNotice_* handler stores the tuple before calling the
|
||||
// shared maker, including the already-open case.
|
||||
_serverType = request.Type;
|
||||
_serverContext = request.ContextId;
|
||||
|
||||
// gmGamePlayUI::MakeGameplayConfirmationDialog @ 0x004EB890 refuses a
|
||||
// second gameplay confirmation while its context is non-zero.
|
||||
if (_dialogContext != 0u)
|
||||
return false;
|
||||
|
||||
string message = request.Type is 2u or 3u or 5u or 6u
|
||||
? request.Message + " Continue?"
|
||||
: request.Message;
|
||||
var data = RetailDialogData.Confirmation(message)
|
||||
.Set(RetailDialogProperty.ElementAttribute40, true);
|
||||
_dialogContext = _dialogs.MakeDialog(data);
|
||||
return _dialogContext != 0u;
|
||||
}
|
||||
|
||||
public bool HandleDone(GameEvents.CharacterConfirmationDone done)
|
||||
{
|
||||
// gmGamePlayUI::RecvNotice_AbortConfirmationRequest @ 0x004E9D70
|
||||
// matches both server fields before closing the local dialog context.
|
||||
if (_dialogContext == 0u
|
||||
|| done.Type != _serverType
|
||||
|| done.ContextId != _serverContext)
|
||||
return false;
|
||||
return _dialogs.CloseDialog(_dialogContext);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_disposed) return;
|
||||
_disposed = true;
|
||||
_dialogs.DialogClosed -= OnDialogClosed;
|
||||
}
|
||||
|
||||
private void OnDialogClosed(uint context, RetailDialogData data)
|
||||
{
|
||||
if (context != _dialogContext
|
||||
|| data.GetUInt32(RetailDialogProperty.Type) !=
|
||||
(uint)RetailDialogType.Confirmation)
|
||||
return;
|
||||
|
||||
bool accepted = data.GetBoolean(RetailDialogProperty.ConfirmationResult);
|
||||
// gmGamePlayUI::CloseGameplayConfirmationDialog @ 0x004E9E80 sends
|
||||
// before clearing its retained server/dialog context fields.
|
||||
_sendResponse(_serverType, _serverContext, accepted);
|
||||
_dialogContext = 0u;
|
||||
_serverType = 0u;
|
||||
_serverContext = 0u;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue