Add WoW-style footsteps and improve third-person movement/collision

This commit is contained in:
Kelsi 2026-02-03 14:55:32 -08:00
parent 54dc27c2ec
commit dfb1f3cfdc
11 changed files with 724 additions and 85 deletions

View file

@ -122,12 +122,16 @@ private:
bool enabled = true;
bool sitting = false;
bool xKeyWasDown = false;
bool rKeyWasDown = false;
bool runPace = false;
// Movement state tracking (for sending opcodes on state change)
bool wasMovingForward = false;
bool wasMovingBackward = false;
bool wasStrafingLeft = false;
bool wasStrafingRight = false;
bool wasTurningLeft = false;
bool wasTurningRight = false;
bool wasJumping = false;
bool wasFalling = false;
@ -136,10 +140,11 @@ private:
// Movement speeds
bool useWoWSpeed = false;
static constexpr float WOW_RUN_SPEED = 14.0f; // Normal run (WASD)
static constexpr float WOW_SPRINT_SPEED = 28.0f; // Sprint (hold Shift)
static constexpr float WOW_WALK_SPEED = 5.0f; // Walk (hold Ctrl)
static constexpr float WOW_BACK_SPEED = 9.0f; // Backpedal
static constexpr float WOW_RUN_SPEED = 7.0f; // Normal run (WotLK)
static constexpr float WOW_SPRINT_SPEED = 10.5f; // Optional fast mode (not default WoW behavior)
static constexpr float WOW_WALK_SPEED = 2.5f; // Walk
static constexpr float WOW_BACK_SPEED = 4.5f; // Backpedal
static constexpr float WOW_TURN_SPEED = 180.0f; // Keyboard turn deg/sec
static constexpr float WOW_GRAVITY = -19.29f;
static constexpr float WOW_JUMP_VELOCITY = 7.96f;

View file

@ -63,6 +63,7 @@ public:
void setActiveGeosets(uint32_t instanceId, const std::unordered_set<uint16_t>& geosets);
void setInstanceVisible(uint32_t instanceId, bool visible);
void removeInstance(uint32_t instanceId);
bool getAnimationState(uint32_t instanceId, uint32_t& animationId, float& animationTimeMs, float& animationDurationMs) const;
/** Attach a weapon model to a character instance at the given attachment point. */
bool attachWeapon(uint32_t charInstanceId, uint32_t attachmentId,

View file

@ -8,7 +8,7 @@
namespace wowee {
namespace core { class Window; }
namespace game { class World; class ZoneManager; }
namespace audio { class MusicManager; }
namespace audio { class MusicManager; class FootstepManager; enum class FootstepSurface : uint8_t; }
namespace pipeline { class AssetManager; }
namespace rendering {
@ -142,6 +142,7 @@ private:
std::unique_ptr<M2Renderer> m2Renderer;
std::unique_ptr<Minimap> minimap;
std::unique_ptr<audio::MusicManager> musicManager;
std::unique_ptr<audio::FootstepManager> footstepManager;
std::unique_ptr<game::ZoneManager> zoneManager;
pipeline::AssetManager* cachedAssetManager = nullptr;
@ -157,6 +158,9 @@ private:
enum class CharAnimState { IDLE, WALK, RUN, JUMP_START, JUMP_MID, JUMP_END, SIT_DOWN, SITTING, EMOTE, SWIM_IDLE, SWIM };
CharAnimState charAnimState = CharAnimState::IDLE;
void updateCharacterAnimation();
bool isFootstepAnimationState() const;
bool shouldTriggerFootstepEvent(uint32_t animationId, float animationTimeMs, float animationDurationMs);
audio::FootstepSurface resolveFootstepSurface() const;
// Emote state
bool emoteActive = false;
@ -166,6 +170,11 @@ private:
// Target facing
const glm::vec3* targetPosition = nullptr;
// Footstep event tracking (animation-driven)
uint32_t footstepLastAnimationId = 0;
float footstepLastNormTime = 0.0f;
bool footstepNormInitialized = false;
bool terrainEnabled = true;
bool terrainLoaded = false;
};

View file

@ -172,6 +172,12 @@ public:
*/
std::optional<float> getHeightAt(float glX, float glY) const;
/**
* Get dominant terrain texture name at a GL position.
* Returns empty if terrain is not loaded at that position.
*/
std::optional<std::string> getDominantTextureAt(float glX, float glY) const;
/**
* Get statistics
*/