diff --git a/src/AcDream.Core/Physics/PhysicsEngine.cs b/src/AcDream.Core/Physics/PhysicsEngine.cs index 33d03db..08f062a 100644 --- a/src/AcDream.Core/Physics/PhysicsEngine.cs +++ b/src/AcDream.Core/Physics/PhysicsEngine.cs @@ -915,7 +915,12 @@ public sealed class PhysicsEngine resolveResult = new ResolveResult( sp.CheckPos, - ResolveCellId(sp.GlobalSphere[0].Origin, sphereRadius, sp.CheckCellId), + // Phase W Stage 1: return the transition's SWEPT cell (retail SetPositionInternal + // reads sphere_path.curr_cell), not a static re-derive from the resting origin. + // ValidateTransition advances sp.CurCellId only on accepted moves / reverts on + // blocks, so push-back or standing still cannot flip it. SetCurrAndReturn keeps the + // W2a CellGraph.CurrCell write the render root consumes. + SetCurrAndReturn(sp.CurCellId), onGround, collisionNormalValid, collisionNormal); @@ -934,7 +939,9 @@ public sealed class PhysicsEngine uint partialCellId = sp.CheckCellId != 0 ? sp.CheckCellId : cellId; resolveResult = new ResolveResult( sp.CheckPos, - ResolveCellId(sp.GlobalSphere[0].Origin, sphereRadius, partialCellId), + // Phase W Stage 1: prefer the swept cell; fall back to partialCellId only when + // sp.CurCellId is zero (transition never advanced — teleport or physics reset). + SetCurrAndReturn(sp.CurCellId != 0 ? sp.CurCellId : partialCellId), partialOnGround, collisionNormalValid, collisionNormal);