diff --git a/src/AcDream.Core/Physics/TransitionTypes.cs b/src/AcDream.Core/Physics/TransitionTypes.cs index 7eb99fb..ad6d9e7 100644 --- a/src/AcDream.Core/Physics/TransitionTypes.cs +++ b/src/AcDream.Core/Physics/TransitionTypes.cs @@ -657,8 +657,14 @@ public sealed class Transition foreach (var obj in _nearbyObjs) { // Broad-phase: can the moving sphere reach this object? - float distToCurr = Vector3.Distance(currPos, obj.Position); - float maxReach = sphereRadius + obj.Radius + movement.Length() + 1f; + // Use horizontal distance for cylinders (Z extent is checked separately). + Vector3 deltaToCurr = currPos - obj.Position; + float distToCurr; + if (obj.CollisionType == ShadowCollisionType.Cylinder) + distToCurr = MathF.Sqrt(deltaToCurr.X * deltaToCurr.X + deltaToCurr.Y * deltaToCurr.Y); + else + distToCurr = deltaToCurr.Length(); + float maxReach = sphereRadius + obj.Radius + movement.Length() + 2f; if (distToCurr > maxReach) continue; @@ -755,14 +761,13 @@ public sealed class Transition if (bestT >= float.MaxValue) { - // Debug: log nearby objects that didn't trigger collision - if (_debugMissCounter++ % 120 == 0) + if (_debugMissCounter++ % 120 == 0 && _nearbyObjs.Count > 0) { foreach (var obj in _nearbyObjs) { float d = Vector3.Distance(checkPos, obj.Position); - if (d < 3f) - Console.WriteLine($"NEAR: obj {obj.EntityId:X8} gfx={obj.GfxObjId:X8} type={obj.CollisionType} dist={d:F2} r={obj.Radius:F2} cylH={obj.CylHeight:F2} pos={obj.Position}"); + float hd = MathF.Sqrt((checkPos.X-obj.Position.X)*(checkPos.X-obj.Position.X)+(checkPos.Y-obj.Position.Y)*(checkPos.Y-obj.Position.Y)); + Console.WriteLine($"MISS: eid={obj.EntityId:X8} gfx={obj.GfxObjId:X8} type={obj.CollisionType} dist={d:F2} hdist={hd:F2} r={obj.Radius:F2} cylH={obj.CylHeight:F1} playerZ={checkPos.Z:F1} objZ={obj.Position.Z:F1} player=({checkPos.X:F1},{checkPos.Y:F1}) obj=({obj.Position.X:F1},{obj.Position.Y:F1})"); } } return TransitionState.OK;