Fix invisible fall-velocity buildup during Deeprun tram rides

Z is intentionally locked to the tram deck while riding (the tunnel has
no real floor), but CameraController's own gravity/jump physics kept
running underneath that lock every frame since grounded never went
true on a moving M2 deck. verticalVelocity silently grew toward
terminal velocity for the whole ride and unleashed all at once the
instant the lock released at disembark, clipping the player through
the floor at "a weird angle." It also explains why jump appeared to
do nothing while riding, since canJump requires a recent grounded
frame that a tram ride never produces.

Added CameraController::suppressVerticalPhysics() (zeroes
verticalVelocity, forces grounded true) and call it every frame the
Deeprun tram Z-lock is active.
This commit is contained in:
Josh Anderson
2026-07-10 10:11:38 -05:00
parent a461e7b8f3
commit ccb97331a9
2 changed files with 21 additions and 0 deletions

View File

@@ -82,6 +82,16 @@ public:
bool isGrounded() const { return grounded; }
bool isJumping() const { return !grounded && verticalVelocity > 0.0f; }
bool isFalling() const { return !grounded && verticalVelocity <= 0.0f; }
// Call every frame while riding a transport that forces Z to a locked value
// externally (e.g. the Deeprun Tram, which has no real floor mid-tunnel).
// Without this, gravity keeps integrating verticalVelocity every frame since
// grounded never goes true on a moving M2 deck, even though the position
// itself is being overwritten and looks static - the huge fall speed that
// silently built up over the whole ride would then unleash all at once the
// instant the external Z lock releases at disembark, clipping the player
// through the floor.
void suppressVerticalPhysics() { verticalVelocity = 0.0f; grounded = true; }
bool isJumpKeyPressed() const { return jumpBufferTimer > 0.0f; }
bool isSprinting() const;
bool isMovingForward() const { return moveForwardActive; }

View File

@@ -1655,6 +1655,17 @@ void Application::update(float deltaTime) {
}
}
}
// Z is fully locked for the Deeprun tram (see below), so
// CameraController's own gravity integration never sees a
// grounded frame and silently accumulates fall velocity the
// entire ride - reported live as clipping through the world
// "at a weird angle" right after disembarking, and as being
// unable to jump while riding (coyote time never has a
// grounded frame to key off). Suppress it every frame the
// lock is active so nothing is queued up to unleash later.
if (isDeeprunTram && renderer->getCameraController()) {
renderer->getCameraController()->suppressVerticalPhysics();
}
// Thunder Bluff lifts have real floor at both ends of their travel,
// so letting Z track physics while airborne (jumping) is recoverable -
// the player lands back on the platform. The Deeprun Tram tunnel has