diff --git a/include/rendering/camera_controller.hpp b/include/rendering/camera_controller.hpp index eabbe81c..3337a755 100644 --- a/include/rendering/camera_controller.hpp +++ b/include/rendering/camera_controller.hpp @@ -256,6 +256,8 @@ private: bool wasTurningRight = false; bool wasJumping = false; bool wasFalling = false; + bool wasAscending_ = false; // Space held while flyingActive_ + bool wasDescending_ = false; // X held while flyingActive_ bool moveForwardActive = false; bool moveBackwardActive = false; bool strafeLeftActive = false; diff --git a/src/game/game_handler.cpp b/src/game/game_handler.cpp index 74656907..c1f65f18 100644 --- a/src/game/game_handler.cpp +++ b/src/game/game_handler.cpp @@ -7329,6 +7329,17 @@ void GameHandler::sendMovement(Opcode opcode) { case Opcode::MSG_MOVE_HEARTBEAT: // No flag changes — just sends current position break; + case Opcode::MSG_MOVE_START_ASCEND: + movementInfo.flags |= static_cast(MovementFlags::ASCENDING); + break; + case Opcode::MSG_MOVE_STOP_ASCEND: + // Clears ascending (and descending) — one stop opcode for both directions + movementInfo.flags &= ~static_cast(MovementFlags::ASCENDING); + break; + case Opcode::MSG_MOVE_START_DESCEND: + // Descending: no separate flag; clear ASCENDING so they don't conflict + movementInfo.flags &= ~static_cast(MovementFlags::ASCENDING); + break; default: break; } diff --git a/src/rendering/camera_controller.cpp b/src/rendering/camera_controller.cpp index ff6205aa..cfa6120a 100644 --- a/src/rendering/camera_controller.cpp +++ b/src/rendering/camera_controller.cpp @@ -217,6 +217,7 @@ void CameraController::update(float deltaTime) { bool shiftDown = !uiWantsKeyboard && (input.isKeyPressed(SDL_SCANCODE_LSHIFT) || input.isKeyPressed(SDL_SCANCODE_RSHIFT)); bool ctrlDown = !uiWantsKeyboard && (input.isKeyPressed(SDL_SCANCODE_LCTRL) || input.isKeyPressed(SDL_SCANCODE_RCTRL)); bool nowJump = !uiWantsKeyboard && !sitting && !movementSuppressed && input.isKeyJustPressed(SDL_SCANCODE_SPACE); + bool spaceDown = !uiWantsKeyboard && !sitting && !movementSuppressed && input.isKeyPressed(SDL_SCANCODE_SPACE); // Idle camera: any input resets the timer; timeout triggers a slow orbit pan bool anyInput = leftMouseDown || rightMouseDown || keyW || keyS || keyA || keyD || keyQ || keyE || nowJump; @@ -1795,6 +1796,35 @@ void CameraController::update(float deltaTime) { } } + // Flight ascend/descend transitions (Space = ascend, X = descend while mounted+flying) + if (movementCallback && !externalFollow_) { + const bool nowAscending = flyingActive_ && spaceDown; + const bool nowDescending = flyingActive_ && xDown && mounted_; + + if (flyingActive_) { + if (nowAscending && !wasAscending_) { + movementCallback(static_cast(game::Opcode::MSG_MOVE_START_ASCEND)); + } else if (!nowAscending && wasAscending_) { + movementCallback(static_cast(game::Opcode::MSG_MOVE_STOP_ASCEND)); + } + if (nowDescending && !wasDescending_) { + movementCallback(static_cast(game::Opcode::MSG_MOVE_START_DESCEND)); + } else if (!nowDescending && wasDescending_) { + // No separate STOP_DESCEND opcode; STOP_ASCEND ends all vertical movement + movementCallback(static_cast(game::Opcode::MSG_MOVE_STOP_ASCEND)); + } + } else { + // Left flight mode: clear any lingering vertical movement states + if (wasAscending_) { + movementCallback(static_cast(game::Opcode::MSG_MOVE_STOP_ASCEND)); + } else if (wasDescending_) { + movementCallback(static_cast(game::Opcode::MSG_MOVE_STOP_ASCEND)); + } + } + wasAscending_ = nowAscending; + wasDescending_ = nowDescending; + } + // Update previous-frame state wasSwimming = swimming; wasMovingForward = nowForward;