feat(net): Map/House panel — slice 4a, House wire parsing groundwork
Adds the outbound HouseQuery action (0x021E, ClientCommandRequests. BuildHouseQuery / WorldSession.SendHouseQuery — ACE GameActionHouseQuery. Handle reads no payload) and inbound parsers for all four House wire opcodes GameEventType already defined (0x0225-0x0228, gmHouseUI::PostInit's registered notice handlers): GameEvents.ParseHouseData (BuyTime/RentTime/ Type/MaintenanceFree/Buy list/Rent list/Position — the Position field reuses CreateObject.ServerPosition's existing 32-byte Cell+Pos.XYZ+ Rotation.WXYZ shape rather than a new type), ParseHouseStatus (WeenieError u32), ParseUpdateRentTime, ParseUpdateRentPayment. Wire shapes verified against ACE's HouseDataExtensions/HousePaymentExtensions (references/ACE/ Source/ACE.Server/Network/Structure/HouseData.cs, HousePayment.cs) — noted that ACE's own UpdateRentTime/UpdateRentPayment writers are stubs (always 0u / always an empty list), captured as such rather than assumed live. GameEventWiring.WireAll gets four new optional delegate holes (onHouseData/onHouseStatus/onHouseUpdateRentTime/onHouseUpdateRentPayment) following the exact trade-family precedent — registered only when non-null, every existing caller compiles unchanged. This is the "enum/parser groundwork" half of Slice 4's pre-authorized fallback. NOT included (filed as an ISSUES entry): a RuntimeHouseState GameRuntime owner (construction-transaction ceremony, fault-injection points, disposal/convergence tracking — the same weight as RuntimeTradeState's integration, judged disproportionate for tonight alongside the completed Map tab), HousePageController's real Lines/ OnShown wiring, the DisplayPurchaseTimeText port, and the six other Display* line builders. The House tab currently mounts with genuinely empty content, matching retail's own PostInit (verified via MapHousePanelSlotProbeTests' live-DAT probe, not assumed). 9 new HouseEventsTests (parser round-trips + truncation), 1 new GameEventWiringTests case (all four opcodes reach their callbacks). Core.Net.Tests: 1004/1004 passed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
6b0fa4ff0d
commit
dd6c7e09f0
6 changed files with 381 additions and 1 deletions
|
|
@ -124,7 +124,14 @@ public static class GameEventWiring
|
|||
Action<uint /*whoDeclined*/>? onTradeDecline = null,
|
||||
Action<uint /*whoReset*/>? onTradeReset = null,
|
||||
Action<GameEvents.TradeFailure>? onTradeFailure = null,
|
||||
Action? onTradeClearAcceptance = null)
|
||||
Action? onTradeClearAcceptance = null,
|
||||
// House panel (Batch C, Map/House toolbar panel, 2026-08-17): the
|
||||
// same Runtime-owned delegate-hole shape as trade above —
|
||||
// RuntimeHouseState (or a lighter equivalent) is the consumer.
|
||||
Action<GameEvents.HouseData>? onHouseData = null,
|
||||
Action<uint /*weenieError*/>? onHouseStatus = null,
|
||||
Action<uint /*rentTime*/>? onHouseUpdateRentTime = null,
|
||||
Action<IReadOnlyList<GameEvents.HousePayment>>? onHouseUpdateRentPayment = null)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(dispatcher);
|
||||
ArgumentNullException.ThrowIfNull(items);
|
||||
|
|
@ -402,6 +409,43 @@ public static class GameEventWiring
|
|||
onTradeClearAcceptance());
|
||||
}
|
||||
|
||||
// ── House panel (0x0225–0x0228) ───────────────────────────
|
||||
// Batch C (Map/House toolbar panel, 2026-08-17). gmHouseUI::
|
||||
// PostInit registers all four; consumers are optional so every
|
||||
// existing caller compiles unchanged.
|
||||
if (onHouseData is not null)
|
||||
{
|
||||
registrar.Register(GameEventType.HouseData, e =>
|
||||
{
|
||||
var p = GameEvents.ParseHouseData(e.Payload.Span);
|
||||
if (p is not null) onHouseData(p.Value);
|
||||
});
|
||||
}
|
||||
if (onHouseStatus is not null)
|
||||
{
|
||||
registrar.Register(GameEventType.HouseStatus, e =>
|
||||
{
|
||||
var p = GameEvents.ParseHouseStatus(e.Payload.Span);
|
||||
if (p is not null) onHouseStatus(p.Value);
|
||||
});
|
||||
}
|
||||
if (onHouseUpdateRentTime is not null)
|
||||
{
|
||||
registrar.Register(GameEventType.UpdateRentTime, e =>
|
||||
{
|
||||
var p = GameEvents.ParseUpdateRentTime(e.Payload.Span);
|
||||
if (p is not null) onHouseUpdateRentTime(p.Value);
|
||||
});
|
||||
}
|
||||
if (onHouseUpdateRentPayment is not null)
|
||||
{
|
||||
registrar.Register(GameEventType.UpdateRentPayment, e =>
|
||||
{
|
||||
var p = GameEvents.ParseUpdateRentPayment(e.Payload.Span);
|
||||
if (p is not null) onHouseUpdateRentPayment(p);
|
||||
});
|
||||
}
|
||||
|
||||
if (onConfirmationRequest is not null)
|
||||
{
|
||||
registrar.Register(GameEventType.CharacterConfirmationRequest, e =>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue