feat(ui): House tab ownership text — DisplayPurchaseTimeText + RuntimeHouseState
Derived the mechanism from the decomp before writing code: neither gmHouseUI::PostInit @0x004a2710 nor gmMapUI::PostInit @0x004a1c70 sends a HouseQuery, and six of gmHouseUI's seven Display* builders early-return on m_pHouseData == 0. The only text a houseless character's House tab shows is gmHouseUI::DisplayPurchaseTimeText @0x004a3110's expired branch (it doesn't gate on m_pHouseData) — the local player's PropertyInt.HousePurchaseTimestamp plus HouseSystem::HasPurchaseWaitPeriodExpired renders exactly "You may buy another house immediately." for a fresh character. Exhaustive search of the 2013 EoR decomp, ACE, and the live DAT found zero support for a second "You do not currently own a house." line the task brief described — this commit ports what the decomp actually shows. Ships: - RuntimeHouseState: a minimal (no disposal, no construction-transaction Fault() point) Runtime owner per ISSUES #413's own sizing note, wired through GameEventWiring's existing HouseData/HouseStatus delegate holes, LiveSessionEventRouter, and GameRuntime.HouseOwner. Participates in RuntimeGenerationReset (new House stage) since a fresh login must not show a stale character's house state. - HousePageController.Bindings.Lines/OnShown wired to real data; OnShown fires WorldSession.SendHouseQuery() on tab-open (AD-107: an acdream trigger, not a ported retail call site — filed in the divergence register). - Fixed a real bug found along the way: HousePageController.Bind never wired UiTemplateListBox.TemplateResolver, so no row could ever render regardless of Lines content. Now reuses the Map tab's generic hotspot resolver. Live-verified against a real local ACE server and the +Acdream character (--session-config auto-select + a UI automation script): screenshot and structural UI-tree dump both confirm the House tab renders exactly "You may buy another house immediately." Graceful logout confirmed both launches. ISSUES #413 narrowed to its one remaining piece: the six owned-house-only Display* builders (DisplayBuyPayment/RentPayment/BuyTime/RentTimes/ Location/WarningText), unexercisable without a test character that owns a house. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
eb6f3bd8c8
commit
06512f0957
13 changed files with 601 additions and 99 deletions
|
|
@ -60,15 +60,24 @@ public enum RuntimeGenerationResetStage
|
|||
/// beside its fellowship/allegiance precedents.
|
||||
/// </summary>
|
||||
Trade = 14,
|
||||
BeginEntityRetirement = 15,
|
||||
RetireEntities = 16,
|
||||
DrainHostProjection = 17,
|
||||
CompleteCanonicalEntities = 18,
|
||||
CompleteHostProjection = 19,
|
||||
ChatIdentity = 20,
|
||||
PlayerSnapshots = 21,
|
||||
PlayerIdentity = 22,
|
||||
Complete = 23,
|
||||
/// <summary>
|
||||
/// Batch C (Map/House toolbar panel, 2026-08-17): the House tab's
|
||||
/// query result is session-scoped like fellowship/allegiance/trade
|
||||
/// above — a fresh login must not show a previous character's house
|
||||
/// data. See <see cref="RuntimeHouseState"/>'s class doc for why this
|
||||
/// owner is lighter-weight than its three siblings (no disposal, no
|
||||
/// construction-transaction Fault() point).
|
||||
/// </summary>
|
||||
House = 15,
|
||||
BeginEntityRetirement = 16,
|
||||
RetireEntities = 17,
|
||||
DrainHostProjection = 18,
|
||||
CompleteCanonicalEntities = 19,
|
||||
CompleteHostProjection = 20,
|
||||
ChatIdentity = 21,
|
||||
PlayerSnapshots = 22,
|
||||
PlayerIdentity = 23,
|
||||
Complete = 24,
|
||||
}
|
||||
|
||||
public readonly record struct RuntimeGenerationResetSnapshot(
|
||||
|
|
@ -119,6 +128,7 @@ public sealed class RuntimeGenerationReset
|
|||
private readonly RuntimeFellowshipState _fellowship;
|
||||
private readonly RuntimeAllegianceState _allegiance;
|
||||
private readonly RuntimeTradeState _trade;
|
||||
private readonly RuntimeHouseState _house;
|
||||
private ResetState? _state;
|
||||
private RuntimeGenerationToken _lastCompletedGeneration;
|
||||
private bool _hasCompletedGeneration;
|
||||
|
|
@ -136,7 +146,8 @@ public sealed class RuntimeGenerationReset
|
|||
RuntimeLocalPlayerIdentityState identity,
|
||||
RuntimeFellowshipState fellowship,
|
||||
RuntimeAllegianceState allegiance,
|
||||
RuntimeTradeState trade)
|
||||
RuntimeTradeState trade,
|
||||
RuntimeHouseState house)
|
||||
{
|
||||
_transit = transit ?? throw new ArgumentNullException(nameof(transit));
|
||||
_communication = communication
|
||||
|
|
@ -157,6 +168,7 @@ public sealed class RuntimeGenerationReset
|
|||
_allegiance = allegiance
|
||||
?? throw new ArgumentNullException(nameof(allegiance));
|
||||
_trade = trade ?? throw new ArgumentNullException(nameof(trade));
|
||||
_house = house ?? throw new ArgumentNullException(nameof(house));
|
||||
}
|
||||
|
||||
public RuntimeGenerationToken? ActiveRetiringGeneration =>
|
||||
|
|
@ -333,6 +345,9 @@ public sealed class RuntimeGenerationReset
|
|||
case RuntimeGenerationResetStage.Trade:
|
||||
Advance(state, _trade.Clear);
|
||||
break;
|
||||
case RuntimeGenerationResetStage.House:
|
||||
Advance(state, _house.ResetSession);
|
||||
break;
|
||||
case RuntimeGenerationResetStage.BeginEntityRetirement:
|
||||
_ = _entityObjects.BeginSessionClear();
|
||||
state.Retirements = _entityObjects
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue