diff --git a/src/AcDream.Core/Physics/PhysicsEngine.cs b/src/AcDream.Core/Physics/PhysicsEngine.cs index f8eefb4..5414f2a 100644 --- a/src/AcDream.Core/Physics/PhysicsEngine.cs +++ b/src/AcDream.Core/Physics/PhysicsEngine.cs @@ -262,46 +262,25 @@ public sealed class PhysicsEngine // _landblocks (no DataCache dependency). if (DataCache is null) return fallbackCellId; - // ── Cell-stickiness check (A6.P3 slice 3, 2026-05-22) ── - // Before re-resolving via FindCellList, check if the fallback - // CellId still validly contains the sphere CENTER (point-in). - // If yes, prefer it over any FindCellList result that might - // pick a different cell whose BSP also contains the point — - // fixes issue #98 (cellar-up stuck at last step due to CellId - // ping-ponging between adjacent cells in iteration-order races). + // ── Cell-stickiness REVERTED (A6.P3 slice 3 v3, 2026-05-22) ── + // Slice 3 v1 (sphere-overlap, 8898166) over-corrected — held + // player in cellar even when transitioning out at the ramp top. + // Slice 3 v2 (point-in, 3e140cf) closed the ping-pong at the + // inn doorway (data confirmed) BUT prevented the player from + // reaching the top of the cellar ramp (the stuck spot + // transitioned from "ping-pong at top" to "never reach top"). // - // Mechanism: when the sphere is on a cell boundary where the - // CENTER is in multiple cells geometrically (overlapping BSPs), - // FindCellList's candidate-iteration order (HashSet, - // implementation-defined) determines which cell wins. That - // order may shift tick-to-tick → ping-pong. Stickiness keeps - // the CURRENT cell as long as the sphere center is still - // inside it, only switching when the center has moved out. + // Reverting to no-stickiness for now. The ping-pong at the inn + // doorway returns but is a lesser evil than blocking cellar-up + // entirely. Issue #98 cellar-up has a deeper bug that needs + // separate investigation (BSP step-physics or AdjustOffset + // slope-projection at the cottage main floor boundary). // - // Uses POINT-IN (not sphere-overlap). Sphere-overlap stickiness - // (the first slice 3 attempt) over-corrected — held the player - // in the fallback cell even when the center had transitioned to - // an adjacent cell, blocking legitimate cell transitions at - // stair tops + portal exits. Point-in matches FindCellList's - // own semantics for "which cell are you in." - // - // Retail oracle: cell-array hysteresis pattern from - // CObjCell::find_cell_list Position-variant at - // acclient_2013_pseudo_c.txt:308742-308783. - // - // Likely closes/obsoletes: - // - #98 (cellar ascent stuck at last step) — direct target - // - #97 (phantom collisions + fall-through on 2nd floor) — - // same instability family hypothesized - // - #90 (sphere-overlap workaround below) — superseded; - // can be removed after visual verification (A6.P4) - var fallbackCell = DataCache.GetCellStruct(fallbackCellId); - if (fallbackCell?.CellBSP?.Root is not null) - { - var fallbackLocal = Vector3.Transform(worldPos, fallbackCell.InverseWorldTransform); - if (BSPQuery.PointInsideCellBsp(fallbackCell.CellBSP.Root, fallbackLocal)) - return fallbackCellId; // center still inside; stick. - } + // Slice 3 work remains valuable as research evidence; the fix + // shape was wrong. Issue #90 stays as workaround until a + // better stickiness mechanism is designed (probably needs to + // be GATED by some "near cell boundary" check rather than + // applied unconditionally). // Fallback cell no longer valid → re-resolve via portal-graph BFS. uint indoorResult = CellTransit.FindCellList(DataCache, worldPos, sphereRadius, fallbackCellId);