Skip to content

Commit e881e18

Browse files
committed
Fire PLAYER_STARTED_MOVING for both-mouse-button run
Holding both mouse buttons to run forward never fired PLAYER_STARTED_MOVING. Ghidra trace of the input button handler (FUN_00514840) shows that gesture drives the forward move directly at the movement layer (FUN_005103e0) and explicitly clears the autorun bit on the both-button press — so it sets none of the INPUT_FLAGS_MOVING_ANY bits the mover-detection reads. (The Offsets.h comment claiming the both-button combo sets autorun was wrong; corrected.) Detect it from the bit combo instead: both INPUT_FLAG_MOUSELOOK (RMB) and INPUT_FLAG_FREE_LOOK (LMB) held means the engine is mouse-steering the character forward. ORed into `moving`. Composes cleanly with the TURNING/LOOKING latches (unchanged).
1 parent ba45204 commit e881e18

2 files changed

Lines changed: 25 additions & 8 deletions

File tree

src/Offsets.h

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3379,13 +3379,19 @@ enum Offsets {
33793379
// Bits 4-7 — WASD movement-key state. Each `MoveForwardStart`
33803380
// / `StrafeLeftStart` / etc. pushes one of these as the bit
33813381
// mask into the engine's button-press handler. Bit `0x1000` is
3382-
// the autorun-active flag (set by `ToggleAutoRun` and the
3383-
// both-mouse-buttons combo). `INPUT_FLAGS_MOVING_ANY` is the
3384-
// engine's own "is the user currently inputting translational
3385-
// movement" mask, used to drive `PLAYER_STARTED_MOVING` —
3386-
// matches modern's "STOPPED fires on key release, even
3387-
// mid-air" semantics because no physics/airborne bit is
3388-
// involved.
3382+
// the autorun-active flag (set by `ToggleAutoRun`).
3383+
// `INPUT_FLAGS_MOVING_ANY` is the engine's own "is the user
3384+
// currently inputting translational movement via keys/autorun"
3385+
// mask, used to drive `PLAYER_STARTED_MOVING` — matches modern's
3386+
// "STOPPED fires on key release, even mid-air" semantics because
3387+
// no physics/airborne bit is involved.
3388+
//
3389+
// NOTE: the "hold both mouse buttons to run forward" gesture is
3390+
// NOT in this mask. The button handler (`FUN_00514840`) drives
3391+
// that forward move directly via `FUN_005103e0` and explicitly
3392+
// *clears* the autorun bit when both buttons go down. Detect it
3393+
// from `INPUT_FLAG_MOUSELOOK & INPUT_FLAG_FREE_LOOK` both held
3394+
// instead — see `Player::InputEvents`.
33893395
INPUT_FLAG_MOVE_FORWARD = 0x10,
33903396
INPUT_FLAG_MOVE_BACKWARD = 0x20,
33913397
INPUT_FLAG_STRAFE_LEFT = 0x40,

src/player/InputEvents.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,21 @@ void OnWorldTick() {
111111

112112
const uint32_t flags = *reinterpret_cast<const uint32_t *>(
113113
ctrl + Offsets::OFF_UI_INPUT_FLAGS);
114-
const bool moving = (flags & Offsets::INPUT_FLAGS_MOVING_ANY) != 0;
115114
const bool freeLookHeld = (flags & Offsets::INPUT_FLAG_FREE_LOOK) != 0;
116115
const bool mouselookHeld = (flags & Offsets::INPUT_FLAG_MOUSELOOK) != 0;
117116

117+
// MOVING — translational input. The WASD / autorun keys set the
118+
// INPUT_FLAGS_MOVING_ANY bits directly. The "hold both mouse
119+
// buttons to run forward" gesture does NOT: the engine drives that
120+
// forward move at the movement layer (FUN_005103e0 from the button
121+
// handler) and actually *clears* the autorun bit on the both-button
122+
// press, so no MOVING_ANY bit is ever set. Detect it from the
123+
// bit combo instead — both mouselook (RMB) and free-look (LMB)
124+
// held means the engine is mouse-steering the character forward.
125+
const bool mouseSteerMoving = mouselookHeld && freeLookHeld;
126+
const bool moving =
127+
(flags & Offsets::INPUT_FLAGS_MOVING_ANY) != 0 || mouseSteerMoving;
128+
118129
// TURNING — latched bit-AND-rotation signal:
119130
// STARTED fires when mouselook bit is held AND the body yaw
120131
// changes (the first actual drag after pressing RMB).

0 commit comments

Comments
 (0)