From 2881af0bfc7009f48d86ff844c708ad2b17c9744 Mon Sep 17 00:00:00 2001 From: Erik Date: Mon, 17 Aug 2026 02:10:35 +0200 Subject: [PATCH] =?UTF-8?q?docs:=20file=20#413=20=E2=80=94=20House=20tab?= =?UTF-8?q?=20content=20(RuntimeHouseState=20owner=20+=206=20Display*=20bu?= =?UTF-8?q?ilders)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precise scope note for the remainder of the House tab wire, per the task's pre-authorized fallback: RuntimeHouseState owner integration, DisplayPurchaseTimeText's port (the one builder simple enough to have landed this session but deferred for time), and the other six Display* line builders (only exercisable once a house is actually owned). Co-Authored-By: Claude Fable 5 --- docs/ISSUES.md | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/docs/ISSUES.md b/docs/ISSUES.md index c300f8dd..7dd8084a 100644 --- a/docs/ISSUES.md +++ b/docs/ISSUES.md @@ -24,6 +24,89 @@ What does NOT go here: - Every session: scan OPEN issues at start; promote/close anything we touched during the session before ending. - Promoting to a Phase: mark as `DONE (promoted to Phase X)` + commit SHA where the Phase entry landed. +## #413 — House tab shows no content (owned-house display, seven Display* line builders unported) + +**Status:** OPEN (filed 2026-08-17, Batch C — overnight hover/UI round, Map/House +toolbar panel). + +**What's shipped.** The Map/House panel (host `0x2100006E` slot `0x1000018C`, +`RetailPanelCatalog.MapHouse = 16`) is fully mounted with a working Map tab +(date/time, coordinates, player/house markers, 53 town hotspots with retail +tooltips) and a House tab that mounts correctly with its authored ListBox +(`0x100001E6`) and row template — but the ListBox is genuinely EMPTY, matching +retail's own `gmHouseUI::PostInit @0x004a2710` (it never calls `Update`/ +`DisplayHouseData`; the box only populates after a server notice arrives). +The full wire *parsing* groundwork also shipped: outbound HouseQuery +(`0x021E`, `WorldSession.SendHouseQuery`) and inbound parsers for all four +House opcodes (`GameEvents.ParseHouseData`/`ParseHouseStatus`/ +`ParseUpdateRentTime`/`ParseUpdateRentPayment`, wired into +`GameEventWiring.WireAll` as optional delegate holes) — all tested +(`HouseEventsTests`, `GameEventWiringTests.WireAll_HouseFamily_ReachesTheirCallbacks`). + +**What's missing — three pieces, all deliberately deferred (the task's own +pre-authorized fallback: "land the default-content tab + the enum/parser +groundwork, and file the remainder as a precise ISSUES entry"):** + +1. **A `RuntimeHouseState` owner.** The wire delegate holes exist but nothing + consumes them yet — no session-scoped state class holds the parsed + `HouseData`/`HouseStatus`/rent fields, and `HousePageController.Bindings.Lines`/ + `OnShown` are unwired defaults (`() => Array.Empty()`, no-op). + Sizing note: a FULL `GameRuntime`-integrated owner (the + `RuntimeTradeState` precedent — construction-transaction `Fault()` + injection point, `GameRuntimeConstructionPoint` enum entry, disposal + ordering, convergence tracking at 2-3 sites) is a substantial standalone + undertaking; judged disproportionate to add alongside the completed Map + tab in one session. A lighter read-only mirror (closer to + `FriendsState`/`SquelchState`'s weight, no full owner ceremony) may be + the right shape — evaluate against the codebase's "single canonical + owner" architecture before choosing. + +2. **`gmHouseUI::DisplayPurchaseTimeText @0x004a3110`'s port** — the ONE + builder decomp-confirmed simple enough to land (no `m_pHouseData` early + return; reads the LOCAL PLAYER's own `PropertyInt.HousePurchaseTimestamp` + (`= 199` decimal, confirmed already in `src/AcDream.Core/Properties/PropertyInt.cs:356`) + and `HouseSystem::HasPurchaseWaitPeriodExpired(timestamp) = + (Timer::get_real_time() - timestamp) > 0x278d00` — clean, no FPU noise, + `0x278d00` = 2,592,000 s = 30 days, the house-abandon cooldown). Two fully + recovered literal strings for the expired case: `"You may buy another + house immediately."` (no house owned) / `"...after you abandon this + one."` (owns a house) — these are what a fresh test character (no + `HousePurchaseTimestamp` set, i.e. `0`) would show once queried, since + `HasPurchaseWaitPeriodExpired(0)` is trivially true. The NOT-expired + branch's future-dated wait message uses a `strftime` format string + (`data_7ab7ec`) and a suffix (`". This restriction does not appl…"`) + that BN truncates and this session did not attempt to recover further — + port the expired branch first, mark the not-expired branch's suffix text + as inferred-pending-verification if ported later. + +3. **The other six `Display*` line builders** (`DisplayBuyPayment`, + `DisplayRentPayment`, `DisplayBuyTime`, `DisplayRentTimes`, + `DisplayLocation`, `DisplayWarningText` — all called from + `gmHouseUI::DisplayHouseData @0x004a3380`). Each is dozens-to-a-few-hundred + lines of heavily FPU/string-mangled BN pseudo-C (PStringBase sprintf + chains, `HousePaymentList` iteration, `IsPaidInFull`/ + `ConstructRentWarningMessage`-style formatting) — genuinely sized as its + own session, and only exercisable once a test character actually owns a + house (not true of `+Acdream` today). `DisplayLocation` is the exception: + its own logic is clean (`GetHouseLocation` → `LandDefs::gid_to_lcoord` → + the SAME `(v-0x400)*0.1+0.5` transform the Map tab already ports via + `RadarCoordinates`) but its output STRING format is BN-mangled the same + way the Map tab's coordinate readout was — reuse whatever resolution + that gets if/when #413's map coordinate format string is independently + recovered. + +**Reference:** `docs/research/2026-08-17-map-house-recon.md` (the full +citation set: addresses, ACE cross-references, the two ACE writer stubs for +UpdateRentTime/UpdateRentPayment). `src/AcDream.App/UI/Layout/HousePageController.cs`, +`src/AcDream.Core.Net/Messages/GameEvents.cs` (House parsers), +`src/AcDream.Core.Net/GameEventWiring.cs` (delegate holes). + +**Acceptance test once closed:** the House tab, on a fresh `+Acdream` connect +with no owned house, shows "You may buy another house immediately." after +the tab is opened (client sends `HouseQuery`, ACE replies `HouseStatus`, +`RuntimeHouseState` clears `m_pHouseData`-equivalent, `DisplayPurchaseTimeText`'s +expired/no-house branch fires). + ## #412 — Options panel Config tab content escapes the window frame (footer mid-panel, rows drawing below the window's bottom edge) **Status:** DONE 2026-08-16/17 (overnight hover/UI round, Batch A bug 2).