diff --git a/docs/research/2026-05-21-a6-p3-slice1-retail-mech-b-research.md b/docs/research/2026-05-21-a6-p3-slice1-retail-mech-b-research.md index 73af9f4..6ca5c54 100644 --- a/docs/research/2026-05-21-a6-p3-slice1-retail-mech-b-research.md +++ b/docs/research/2026-05-21-a6-p3-slice1-retail-mech-b-research.md @@ -16,25 +16,25 @@ Retail decomp at `acclient_2013_pseudo_c.txt` lines 309573–309593 (address // 0052c130 enum TransitionState __thiscall CEnvCell::find_env_collisions( // class CEnvCell const* this, class CTransition* arg2) { - // [309573] Check entry restrictions (object ethereal? door closed? etc.) + // Check entry restrictions (object ethereal? door closed? etc.) enum TransitionState result = CObjCell::check_entry_restrictions(this, arg2); if (result == OK_TS) { - // [309575] Clear obstruction-ethereal so BSP collision is live. + // 0052c144 Clear obstruction-ethereal so BSP collision is live. arg2->sphere_path.obstruction_ethereal = 0; if (this->structure->physics_bsp != 0) { - // [309578] Project sphere into cell-local space. + // 0052c169 Project sphere into cell-local space. SPHEREPATH::cache_localspace_sphere(&arg2->sphere_path, &this->pos, 1f); - // [309580] Run BSP: INITIAL_PLACEMENT → placement_insert path; + // 0052c175 Run BSP: INITIAL_PLACEMENT → placement_insert path; // all other insert_types → find_collisions path. if (arg2->sphere_path.insert_type != INITIAL_PLACEMENT_INSERT) result = BSPTREE::find_collisions(this->structure->physics_bsp, arg2, 1f); else result = BSPTREE::placement_insert(this->structure->physics_bsp, arg2); - // [309585] On collision with environment (non-Contact objects only). + // 0052c1a5 On collision with environment (non-Contact objects only). if (result != OK_TS && (arg2->object_info.state & 1) == 0) arg2->collision_info.collided_with_environment = 1; } @@ -55,11 +55,10 @@ synthesis path anywhere in this function. **Function:** `CTransition::validate_transition` **Retail address:** `0050aa70` -**Decomp line range:** `acclient_2013_pseudo_c.txt` lines 272540–272700 -**Identified via:** The awk step above returned: `272530 CTransition::check_collisions`, -meaning the most recent function header before line 272540 was -`CTransition::check_collisions` at line 272530. The `validate_transition` -function header appears at line 272538 (`0050aa70`). +**Decomp line range:** `acclient_2013_pseudo_c.txt` lines 272547–272700 +**Identified via:** The `validate_transition` function header appears at line +272547 (`0050aa70`). Line 272538 is inside the preceding +`CTransition::check_collisions` function. The LKCP-restore block runs at lines 272565–272582 (addresses `0050aaed`–`0050ab4c`). @@ -189,6 +188,8 @@ else oi.State &= ~ObjectInfoState.OnWalkable; ``` +> **Note:** `SetContactPlane` also re-latches `LastKnownContactPlane`, `LastKnownContactPlaneCellId`, and `LastKnownContactPlaneIsWater` (TransitionTypes.cs:258-261). Passing LKCP as the source means the re-latch is a no-op on those fields — functionally safe, but worth knowing if you later decide to inline the writes instead of using `SetContactPlane`. + **Note on the LKCP-update strategy divergence (Gap 3):** Retail's `validate_transition` at `0050acff` does `last_known_contact_plane_valid = contact_plane_valid` unconditionally — this means when contact is invalid and stays invalid, LKCP is @@ -256,7 +257,7 @@ slice 1. ## References - `acclient_2013_pseudo_c.txt` lines 309570–309595 (`CEnvCell::find_env_collisions`) -- `acclient_2013_pseudo_c.txt` lines 272538–272700 (`CTransition::validate_transition`) +- `acclient_2013_pseudo_c.txt` lines 272547–272700 (`CTransition::validate_transition`) - `src/AcDream.Core/Physics/TransitionTypes.cs` lines 2751–2873 (`ValidateTransition`) - `src/AcDream.Core/Physics/TransitionTypes.cs` lines 1514–1777 (`FindEnvCollisions`) - `src/AcDream.Core/Physics/PhysicsEngine.cs` lines 640–692 (`RunTransitionResolve`)