acdream/src/AcDream.App
Erik 22020ef2c4 feat(chat): Campaign CH slice CH6b — floating chat windows 1-4
Mounts retail's four floating chat windows as always-resident, born-hidden
children per gmGamePlayUI::SetupChildren @0x004E9EC0, all sharing LayoutDesc
0x2100005B (window ids 0x10000505/0x1000050E/0x1000050F/0x10000510). New
FloatingChatWindowController (AcDream.App/UI/Layout) binds each window's own
widget tree — built fresh per instance from one shared imported ElementInfo
— reusing ChatWindowController's word-wrap + retail color-carry algorithm via
the extracted ChatTranscriptRenderer instead of duplicating it. A floaty
window has no talk-focus menu (research doc §2.2), so its entry field always
sends on Say; the mismatch against retail's possible shared-channel behavior
is UNVERIFIED and filed as #369/AP-188.

Runtime owns the per-window filter/open state: ChatWindowState (new,
AcDream.Core.Chat) seeds retail's exact PostInit defaults per window
(window 1 0x0000101C Speech/Tell/DirectSend/Emote, window 2 0x00040C00
Social/SocialSend/Allegiance, window 3 0x00080000 Fellowship, window 4
0x78000000 Turbine General/Trade/LFG/Roleplay) and implements the full
ShouldDisplay(windowId, targetWindowId, logTextType) display predicate from
ChatInterface::RecvNotice_DisplayFinalStringInfo @0x004F4640. It lives on
RuntimeCommunicationState.ChatWindows so every host borrows the same
instance. The main window's filter (0xFBFFFFFF, "no user filter") never
actually gates anything because its own explicit-address branch already
covers every broadcast line — that's why UpdateFromPlayerModule early-returns
for window 0 in retail, ported here by construction rather than a special
case.

Keybind wiring: InputAction.ToggleFloatingChatWindow1..4 and their
KeyBindings.RetailDefaults() chords already existed since Phase K.1c
(unwired until now). The MetaKeys table confirms retail's default is Alt+1
through Alt+4 (index 3 = bit 0x00000004, cross-checked against the same
file's Alt+A/D strafe and Alt+Enter/Tab/F4 rows). Routes through
GameplayInputCommandController -> RetainedGameplayWindowCommands ->
RetailUiRuntime.ToggleFloatingChatWindow -> the generic UiHost.ToggleWindow,
whose visibility-change event is the single chokepoint that syncs
ChatWindowState.SetOpen and mirrors the main window's 1-4 indicator button
regardless of what changed a window's visibility (keybind, close button, or
a restored layout).

A direct decomp read of gmMainChatUI::ListenToElementMessage @0x004CDA80 —
the only function in the whole binary that branches on a click message —
settles what the research doc had left as a hedge: it handles exactly
0x1000046f (max/min) and the talk-focus menu's selection message, with NO
case for 0x10000522-0x10000525. The four indicator buttons are PURE
one-directional mirrors in retail; clicking them does nothing.
ChatWindowController.SetIndicatorOpen ports this with no OnClick at all.
Corrected research doc §1.4 accordingly.

Persistence is local-only (register row AP-187; the retail 0x1000008C
GameplayOptions wire remains deferred to CH6f): window geometry and
open/visible state ride the existing generic RetailWindowLayoutPersistence
path for free once each window registers under its own WindowNames entry;
the four filter masks get a dedicated ChatSettings round-trip
(ChatWindow1Filter..ChatWindow4Filter, defaulting to the retail PostInit
constants) loaded at mount and saved alongside SaveLayout().

Tests: ChatWindowStateTests (defaults, TypeIsActive, the full display-rule
matrix, toggle/reset, revision counter), FloatingChatWindowControllerTests
(bind smoke tests against a synthetic 0x2100005B tree, per-window filter
routing, filter-change cache invalidation, fixed-Say submit), new
ChatWindowController.SetIndicatorOpen tests (Highlight/Normal state,
cross-window isolation, range validation), GameplayInputCommandController
routing for the four toggle actions, and a SettingsStore filter round-trip.
Full Release suite: 12,392 passed / 4 skipped / 0 failed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 12:10:20 +02:00
..
Audio feat(audio): Ctrl+M instant mute + inn-chatter investigation closed as server content 2026-08-09 14:09:24 +02:00
Combat fix(combat): #298 — admit player targets to melee/missile attack and the camera 2026-08-03 21:29:15 +02:00
Composition feat(chat): Campaign CH slice CH6b — floating chat windows 1-4 2026-08-10 12:10:20 +02:00
Diagnostics feat(render): Vulkan campaign V11 step 3 — drop the GL packages and shaders 2026-07-29 02:58:15 +02:00
Input feat(chat): Campaign CH slice CH6b — floating chat windows 1-4 2026-08-10 12:10:20 +02:00
Interaction fix(vendor): evidence-based pass — max-first stack ceiling; the local player resolves never-animated MoveTo targets 2026-08-08 17:17:04 +02:00
Net fix(chat): CH4 re-review fixes — dialog-queue reentrancy, settings option-bit chokepoint 2026-08-09 22:24:43 +02:00
Physics refactor(physics): hoist the live-entity collision builder to Runtime (#330 groundwork) 2026-08-07 01:49:13 +02:00
Platform feat(render): Vulkan campaign V11 step 2 — delete the OpenGL backend 2026-07-29 02:19:53 +02:00
Plugins Revert "Campaign V slice V4a" - it lost world multisampling 2026-07-27 18:29:28 +02:00
Rendering fix(chat): Campaign CH user-gate round 2 -- portal notice rerouted to SpewBox, verbatim /help extraction, jump-in-air evidence 2026-08-10 08:40:24 +02:00
Runtime feat(chat): Campaign CH slice CH3 — side-channel membership, wire, and echo parity 2026-08-09 19:39:44 +02:00
Settings fix(chat): CH3 review fixes — phantom UN-9, allegiance-broadcast echo, /a legacy fallback 2026-08-09 20:24:29 +02:00
Spells Revert "Campaign V slice V4a" - it lost world multisampling 2026-07-27 18:29:28 +02:00
Streaming fix(audio): portal cues fire on the sequencer's sound events, not the tunnel visuals 2026-08-09 08:22:48 +02:00
UI feat(chat): Campaign CH slice CH6b — floating chat windows 1-4 2026-08-10 12:10:20 +02:00
Update feat(audio): Campaign A slice A5 — retail's region ambient soundscape 2026-08-08 22:53:41 +02:00
World feat(audio): Campaign A slice A4 — the interface sound bus 2026-08-08 22:22:09 +02:00
AcDream.App.csproj feat(render): Vulkan campaign V11 step 3 — drop the GL packages and shaders 2026-07-29 02:58:15 +02:00
GlobalUsings.cs Revert "Campaign V slice V4a" - it lost world multisampling 2026-07-27 18:29:28 +02:00
Program.cs feat(render): Campaign V slice V11 commit 1 - delete ImGui, Studio, and the DevTools frontend 2026-07-28 23:56:04 +02:00
RuntimeOptions.cs feat(render): Vulkan campaign V11 step 2 — delete the OpenGL backend 2026-07-29 02:19:53 +02:00