feat(chat): Phase J Tier 1+2 - @ verb prefix, /retell, /framerate, /loc
Three-tier rollout per the 2026-04-25 retail @help dump showing the full ACE command surface. Tier 1 + most of Tier 2 in one commit. TIER 1 - @ as / equivalent ACE accepts both / and @ as verb prefixes (per its own help text: "Note: You may substitute a forward slash (/) for the at symbol (@)."). ChatInputParser now normalises @ to / for the verb-match phase and re-enters parsing. Critical: for verbs we don't recognise (@acehelp, @tele, @die, @version, @loc-on-server, @nonsense, ...), the original @ is kept in the message text so ACE's CommandManager intercepts the message server-side. If we substituted / there too, ACE would treat it as plain Talk and broadcast it. Result: @a hi / @tell Bob hi / @help / @clear / @reply / @retell all route exactly like their / counterparts. @acehelp / @tele / @version / @die etc. pass through to the server intact. TIER 2 - client-only commands - /retell <msg> (also @retell): resend to the last person you tell'd. Mirrors retail @retell. ChatVM tracks LastOutgoingTellTarget on each OnSelfSent(Tell, ...) entry — SenderGuid==0 distinguishes outgoing echo from inbound whispers, same way LastIncomingTellSender already worked. ChatInputParser takes a new optional lastOutgoingTellTarget param. - /framerate (also @framerate): prints "Framerate: 144.2 FPS" into chat. Wired via a new ChatVM.FpsProvider Func<float> callback set by GameWindow at construction (closes over _lastFps). Falls back to "(provider unavailable)" if no callback is wired (tests / pre-live). - /loc (also @loc): prints "Location: (123.4, 567.8, 60.0)" into chat. Wired via ChatVM.PositionProvider Func<Vector3> closing over GetDebugPlayerPosition() in GameWindow. ACE has a server- side @loc too; client wins here (instantaneous + uses the local interpolated position). ChatPanel.TryHandleClientCommand grew @ aliases for /help /clear /framerate /loc and the new EqAny helper for case-insensitive multi-string matching. Help text rewritten to reference the / <-> @ equivalence and point at @acehelp / @acecommands for ACE's full command list. TIER 3 - automatic (no code) Most retail @-commands (@allegiance motd, @afk, @die, @lifestone, @corpse, @marketplace, @pkarena, @emote/@emotes, @fillcomps, @permit, @consent, @squelch, @unsquelch, @messagetypes, @age, @birth, @day, @endurance, @pklite, @version, @filter, @unfilter, @loadfile, @log, @marketplace, ...) are server-side ACE commands. Tier 1's passthrough takes care of them automatically — they arrive via Talk, ACE recognises the @ and intercepts, replies via SystemChat (which our 0xF7E0 wiring renders as [System] lines). DEFERRED - @saveui / @loadui / @lockui: ImGui layout save/load, ~1 hr standalone task. Filed for follow-up. - @title <text>: rename chat window. ImGui window-id complications. - Toggle-style @framerate (FPS overlay on/off): print-once is simpler and matches retail's most-common usage. 30 new tests: - ChatInputParserAtPrefixTests: 11 covering @-prefix recognition, unknown-@ passthrough, /retell and @retell. - ChatVMRetellAndProvidersTests: 8 covering LastOutgoingTellTarget tracking, FpsProvider/PositionProvider callbacks, no-provider fallback. - ChatPanelInputTests: +3 (/framerate, @loc, @acehelp passthrough). Solution total: 1063 green (243 Core.Net + 160 UI + 660 Core), 0 warnings. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
3501194083
commit
a316d6359c
7 changed files with 497 additions and 22 deletions
|
|
@ -917,7 +917,15 @@ public sealed class GameWindow : IDisposable
|
|||
// ChatPanel: reads the tail of the shared ChatLog. No GUID
|
||||
// dependency — works pre-login (empty) and post-login (live
|
||||
// tail of received speech/tells/channels/system msgs).
|
||||
var chatVm = new AcDream.UI.Abstractions.Panels.Chat.ChatVM(Chat);
|
||||
// FpsProvider + PositionProvider plumb the runtime state
|
||||
// the client-side /framerate and /loc commands need; the
|
||||
// panel asks the VM, the VM asks GameWindow via these
|
||||
// delegates, no panel-vs-renderer-vs-state coupling.
|
||||
var chatVm = new AcDream.UI.Abstractions.Panels.Chat.ChatVM(Chat)
|
||||
{
|
||||
FpsProvider = () => (float)_lastFps,
|
||||
PositionProvider = () => GetDebugPlayerPosition(),
|
||||
};
|
||||
_panelHost.Register(
|
||||
new AcDream.UI.Abstractions.Panels.Chat.ChatPanel(chatVm));
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue