Fix /unstuckgy hang by skipping WMO floor search

Add CameraController::teleportTo() that directly places the player at
the target position without the expensive floor-search loop in reset().
The loop does hundreds of WMO collision checks which hangs in cities.
This commit is contained in:
Kelsi 2026-02-08 15:13:55 -08:00
parent eb92a71b71
commit 8fee55f99f
3 changed files with 29 additions and 2 deletions

View file

@ -42,6 +42,7 @@ public:
}
void reset();
void teleportTo(const glm::vec3& pos);
void setOnlineMode(bool online) { onlineMode = online; }
void startIntroPan(float durationSec = 2.8f, float orbitDegrees = 140.0f);
bool isIntroActive() const { return introActive; }

View file

@ -627,9 +627,8 @@ void Application::setupUICallbacks() {
}
glm::vec3 safePos = core::coords::canonicalToRender(safeCanonical);
*ft = safePos;
cc->setDefaultSpawn(safePos, cc->getYaw(), cc->getPitch());
cc->reset();
cc->teleportTo(safePos);
});
// Bind point update (innkeeper)

View file

@ -1287,6 +1287,33 @@ void CameraController::reset() {
LOG_INFO("Camera reset to default position");
}
void CameraController::teleportTo(const glm::vec3& pos) {
if (!camera) return;
verticalVelocity = 0.0f;
grounded = true;
swimming = false;
lastGroundZ = pos.z;
if (thirdPerson && followTarget) {
*followTarget = pos;
camera->setRotation(yaw, pitch);
glm::vec3 forward3D = camera->getForward();
float mountedOffset = mounted_ ? mountHeightOffset_ : 0.0f;
glm::vec3 pivot = pos + glm::vec3(0.0f, 0.0f, PIVOT_HEIGHT + mountedOffset);
glm::vec3 camDir = -forward3D;
glm::vec3 camPos = pivot + camDir * currentDistance;
smoothedCamPos = camPos;
camera->setPosition(camPos);
} else {
glm::vec3 camPos = pos + glm::vec3(0.0f, 0.0f, eyeHeight);
smoothedCamPos = camPos;
camera->setPosition(camPos);
}
LOG_INFO("Teleported to (", pos.x, ", ", pos.y, ", ", pos.z, ")");
}
void CameraController::processMouseWheel(float delta) {
// Adjust user's target distance (collision may limit actual distance)
userTargetDistance -= delta * 2.0f; // 2.0 units per scroll notch