fix(physics): AP-129 review fix - port CanMoveInto/IsAllowedIn, stop failing closed
Campaign P Slice P4 Opus review verdict: FIX-FIRST. RestrictionObjPrevalenceInspectionTests
(commit 3b5e0992) found 103,766 of 729,888 installed EnvCells (1,293 landblocks -
the whole housing estate) carry a baked RestrictionObj. The AP-71 gate's
unconditional fail-closed default (CanMoveInto unmodeled) would have locked
every apartment/cottage/villa interior for every player, including its own
owner - a live regression, not the "inert in dev content" the original
register row assumed.
Ports ACCWeenieObject::CanMoveInto (0x0058da40, pc:407982-408056) and
RestrictionDB::IsAllowedIn (0x005ae8f0, pc:444493-444516) verbatim into
ObjectInfo.CheckEntryRestrictions:
- owner_iid == 0 or == mover's own guid -> admit (open/owner)
- no RestrictionDB (retail _db == 0, i.e. never authored or not yet
received) -> admit
- present RestrictionDB -> IsAllowedIn: open-to-public flag, OR mover
shares the house's allegiance monarch, OR mover's own guid is a
guest-table member
- unresolved restriction object -> fails CLOSED, exactly retail's own
fallback when GetObjectA can't resolve it (pc:704-716)
Wire feed (Core.Net):
- CreateObject.cs: HouseOwner (WeenieHeaderFlag 0x02000000), HouseRestrictions
(0x04000000), and Monarch (0x40) PWD-tail fields were parsed-and-skipped;
now captured. Also fixes the HouseRestrictions PHashTable header
misconception: the wire is ONE packed u32 (low 24 bits = entry count),
not a separate count(u16)+numBuckets(u16) pair - verified against
Chorizite's RestrictionDB.generated.cs. The old skip's byte-count
happened to match for realistic guest-list sizes, but a future
numBuckets value >255 would have corrupted the parse; now correct
regardless.
- GameEvents.cs/GameEventWiring.cs: new House_UpdateRestrictions (0x0248)
parser + wiring - retail's live guest-list refresh, whole-unit replace.
No-ops if the house object hasn't arrived via CreateObject yet.
- ClientObject/WeenieData/ClientObjectTable: HouseOwnerId, MonarchId,
Restrictions (new HouseRestrictionRecord) fields + merge-preserving
Ingest + targeted UpdateHouseRestrictions.
Physics wiring:
- PhysicsEngine gains an Objects (ClientObjectTable?) property, mirroring
the existing DataCache pattern - acdream's GetObjectA equivalent, used
ONLY by the entry-restriction gate.
- RuntimeEntityObjectLifetime wires Physics.Engine.Objects = Objects in
all three constructors, right alongside the table's own construction -
the same canonical table every other subsystem borrows from, never a
second one. This is the production fix: without it the gate still fails
closed on every restricted cell (unresolvable object), so the wiring is
load-bearing, not cosmetic.
Register: AP-129 narrowed (not retired) to the genuine remaining residual -
House_UpdateRestrictions' Sequence byte isn't used for staleness/reordering
rejection (low-probability, self-correcting), and outdoor CLandCell
restriction (a separate DAT structure) remains unported and unaffected by
this fix.
Tests: 15 new/updated in Ap71EntryRestrictionGateTests.cs (resolved-unowned
admits, owner admits, present-list-excluded blocks, present-list-included
admits, open-to-public admits, shared-allegiance-monarch admits, unresolved
blocks via null and via an empty table, plus two new end-to-end
PhysicsEngine.Objects-wired scenarios); 2 new CreateObject parser tests +
2 new GameEventWiring tests for the wire feed.
AcDream.Core.Tests: 4049 passed, 2 skipped, 0 failed.
AcDream.Core.Net.Tests: 761 passed, 0 skipped, 0 failed.
Complete solution suite: 9,961 total, 9,956 passed, 5 skipped, 0 failed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
dc0468cc2b
commit
7a0f836af5
15 changed files with 704 additions and 81 deletions
|
|
@ -267,6 +267,31 @@ public sealed class ClientObject
|
|||
/// the base object name.
|
||||
/// </summary>
|
||||
public uint? MaterialType { get; set; }
|
||||
/// <summary>
|
||||
/// AP-129 (Campaign P Slice P4 review fix): retail <c>PublicWeenieDesc
|
||||
/// ._house_owner_iid</c>. Present only on a house/dwelling restriction
|
||||
/// object (wire <c>WeenieHeaderFlag.Owner</c>, 0x02000000). Zero or a
|
||||
/// match against the mover's own id admits regardless of the guest list.
|
||||
/// </summary>
|
||||
public uint? HouseOwnerId { get; set; }
|
||||
/// <summary>
|
||||
/// AP-129 (Campaign P Slice P4 review fix): retail <c>PublicWeenieDesc
|
||||
/// ._monarch_iid</c> (wire <c>WeenieHeaderFlag.Monarch</c>, 0x40) — this
|
||||
/// object's OWN allegiance monarch. Present on any weenie, not just house
|
||||
/// objects; a player's own value is what <c>RestrictionDB::IsAllowedIn</c>
|
||||
/// compares against a house's <see cref="HouseRestrictionRecord.AllegianceMonarchId"/>.
|
||||
/// </summary>
|
||||
public uint? MonarchId { get; set; }
|
||||
/// <summary>
|
||||
/// AP-129 (Campaign P Slice P4 review fix): retail <c>PublicWeenieDesc
|
||||
/// ._db</c> (<c>RestrictionDB*</c>) — the house's own guest/ban list.
|
||||
/// Null means retail's <c>_db == 0</c> ("no list", i.e. open) OR simply
|
||||
/// that neither a CreateObject HouseRestrictions field nor a live
|
||||
/// <c>House_UpdateRestrictions (0x0248)</c> has arrived yet for this
|
||||
/// object — acdream cannot distinguish the two, and both resolve to
|
||||
/// the same retail-faithful "allow" default.
|
||||
/// </summary>
|
||||
public HouseRestrictionRecord? Restrictions { get; set; }
|
||||
public PropertyBundle Properties { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -332,7 +357,14 @@ public readonly record struct WeenieData(
|
|||
double? CooldownDuration = null,
|
||||
uint? HookItemTypes = null,
|
||||
uint? HookType = null,
|
||||
uint? MaterialType = null);
|
||||
uint? MaterialType = null,
|
||||
// AP-129 (Campaign P Slice P4 review fix): house-restriction PWD tail
|
||||
// fields. Restrictions is null-preserving (a CreateObject that doesn't
|
||||
// carry HouseRestrictions this time must not clobber a value fed
|
||||
// separately by a live House_UpdateRestrictions event).
|
||||
uint? HouseOwnerId = null,
|
||||
uint? MonarchId = null,
|
||||
HouseRestrictionRecord? Restrictions = null);
|
||||
|
||||
/// <summary>
|
||||
/// Retail ITEM_USEABLE helpers (acclient.h:6478, ItemUses::* at 0x004fccd0).
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue