mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
fix: stand-up-on-move and nameplate position tracking
Camera controller / sitting: - Any movement key (WASD/QE/Space) pressed while sitting now clears the sitting flag immediately, matching WoW's sit-to-stand-on-move behaviour - Added StandUpCallback: when the player stands up via local input the callback fires setStandState(0) → CMSG_STAND_STATE_CHANGE(STAND) so the server releases the sit lock and restores normal movement - Fixes character getting stuck in sit state after accidentally right-clicking a chair GO in Goldshire Inn (or similar) Nameplates: - Use getRenderPositionForGuid() (renderer visual position) as primary source for nameplate anchor, falling back to entity X/Y/Z only when no render instance exists yet; keeps health bars in sync with the rendered model instead of the parallel entity interpolator
This commit is contained in:
parent
48d15fc653
commit
564a286282
4 changed files with 34 additions and 8 deletions
|
|
@ -90,6 +90,11 @@ public:
|
|||
// Movement callback for sending opcodes to server
|
||||
using MovementCallback = std::function<void(uint32_t opcode)>;
|
||||
void setMovementCallback(MovementCallback cb) { movementCallback = std::move(cb); }
|
||||
|
||||
// Callback invoked when the player stands up via local input (space/X/movement key
|
||||
// while server-sitting), so the caller can send CMSG_STAND_STATE_CHANGE(0).
|
||||
using StandUpCallback = std::function<void()>;
|
||||
void setStandUpCallback(StandUpCallback cb) { standUpCallback_ = std::move(cb); }
|
||||
void setUseWoWSpeed(bool use) { useWoWSpeed = use; }
|
||||
void setRunSpeedOverride(float speed) { runSpeedOverride_ = speed; }
|
||||
void setWalkSpeedOverride(float speed) { walkSpeedOverride_ = speed; }
|
||||
|
|
@ -265,6 +270,7 @@ private:
|
|||
|
||||
// Movement callback
|
||||
MovementCallback movementCallback;
|
||||
StandUpCallback standUpCallback_;
|
||||
|
||||
// Movement speeds
|
||||
bool useWoWSpeed = false;
|
||||
|
|
|
|||
|
|
@ -628,6 +628,11 @@ void Application::setState(AppState newState) {
|
|||
gameHandler->sendMovement(static_cast<game::Opcode>(opcode));
|
||||
}
|
||||
});
|
||||
cc->setStandUpCallback([this]() {
|
||||
if (gameHandler) {
|
||||
gameHandler->setStandState(0); // CMSG_STAND_STATE_CHANGE(STAND)
|
||||
}
|
||||
});
|
||||
cc->setUseWoWSpeed(true);
|
||||
}
|
||||
if (gameHandler) {
|
||||
|
|
|
|||
|
|
@ -369,6 +369,7 @@ void CameraController::update(float deltaTime) {
|
|||
|
||||
// Toggle sit/crouch with X key (edge-triggered) — only when UI doesn't want keyboard
|
||||
// Blocked while mounted
|
||||
bool prevSitting = sitting;
|
||||
bool xDown = !uiWantsKeyboard && input.isKeyPressed(SDL_SCANCODE_X);
|
||||
if (xDown && !xKeyWasDown && !mounted_) {
|
||||
sitting = !sitting;
|
||||
|
|
@ -376,6 +377,21 @@ void CameraController::update(float deltaTime) {
|
|||
if (mounted_) sitting = false;
|
||||
xKeyWasDown = xDown;
|
||||
|
||||
// Stand up on any movement key or jump while sitting (WoW behaviour)
|
||||
if (!uiWantsKeyboard && sitting && !movementSuppressed) {
|
||||
bool anyMoveKey =
|
||||
input.isKeyPressed(SDL_SCANCODE_W) || input.isKeyPressed(SDL_SCANCODE_S) ||
|
||||
input.isKeyPressed(SDL_SCANCODE_A) || input.isKeyPressed(SDL_SCANCODE_D) ||
|
||||
input.isKeyPressed(SDL_SCANCODE_Q) || input.isKeyPressed(SDL_SCANCODE_E) ||
|
||||
input.isKeyPressed(SDL_SCANCODE_SPACE);
|
||||
if (anyMoveKey) sitting = false;
|
||||
}
|
||||
|
||||
// Notify server when the player stands up via local input
|
||||
if (prevSitting && !sitting && standUpCallback_) {
|
||||
standUpCallback_();
|
||||
}
|
||||
|
||||
// Update eye height based on crouch state (smooth transition)
|
||||
float targetEyeHeight = sitting ? CROUCH_EYE_HEIGHT : STAND_EYE_HEIGHT;
|
||||
float heightLerpSpeed = 10.0f * deltaTime;
|
||||
|
|
@ -389,11 +405,6 @@ void CameraController::update(float deltaTime) {
|
|||
if (nowStrafeLeft) movement += right;
|
||||
if (nowStrafeRight) movement -= right;
|
||||
|
||||
// Stand up if jumping while crouched
|
||||
if (!uiWantsKeyboard && sitting && input.isKeyPressed(SDL_SCANCODE_SPACE)) {
|
||||
sitting = false;
|
||||
}
|
||||
|
||||
// Third-person orbit camera mode
|
||||
if (thirdPerson && followTarget) {
|
||||
// Move the follow target (character position) instead of the camera
|
||||
|
|
|
|||
|
|
@ -5108,9 +5108,13 @@ void GameScreen::renderNameplates(game::GameHandler& gameHandler) {
|
|||
// Player nameplates are always shown; NPC nameplates respect the V-key toggle
|
||||
if (!isPlayer && !showNameplates_) continue;
|
||||
|
||||
// Convert canonical WoW position → render space, raise to head height
|
||||
glm::vec3 renderPos = core::coords::canonicalToRender(
|
||||
glm::vec3(unit->getX(), unit->getY(), unit->getZ()));
|
||||
// Prefer the renderer's actual instance position so the nameplate tracks the
|
||||
// rendered model exactly (avoids drift from the parallel entity interpolator).
|
||||
glm::vec3 renderPos;
|
||||
if (!core::Application::getInstance().getRenderPositionForGuid(guid, renderPos)) {
|
||||
renderPos = core::coords::canonicalToRender(
|
||||
glm::vec3(unit->getX(), unit->getY(), unit->getZ()));
|
||||
}
|
||||
renderPos.z += 2.3f;
|
||||
|
||||
// Cull distance: target or other players up to 40 units; NPC others up to 20 units
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue