mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-02 07:43:51 +00:00
fix(movement): multi-segment path interpolation, waypoint parsing & terrain Z clamping
Add proper waypoint support to entity movement: - Parse intermediate waypoints from MonsterMove packets in both WotLK and Vanilla paths. Uncompressed paths store absolute float3 waypoints; compressed paths decode TrinityCore's packed uint32 deltas (11-bit signed x/y, 10-bit signed z, ×0.25 scale, waypoint = midpoint − delta) with correct 2's-complement sign extension. - Entity::startMoveAlongPath() interpolates along cumulative-distance- proportional segments instead of a single straight line. - MovementHandler builds the full path (start → waypoints → destination) in canonical coords and dispatches to startMoveAlongPath() when waypoints are present. - Snap entity x/y/z to moveEnd in the dead-reckoning overrun phase before starting a new movement, preventing visible teleports when the renderer was showing the entity at its destination. - Clamp creature and player entity Z to the terrain surface via TerrainManager::getHeightAt() during active movement. Idle entities keep their server-authoritative Z to avoid breaking flight masters, elevator riders, etc. Signed-off-by: Pavel Okhlopkov <pavel.okhlopkov@flant.com>
This commit is contained in:
parent
e07983b7f6
commit
5b47d034c5
5 changed files with 182 additions and 19 deletions
|
|
@ -1756,6 +1756,17 @@ void Application::update(float deltaTime) {
|
|||
inOverrun ? entity->getLatestZ() : entity->getZ());
|
||||
glm::vec3 renderPos = core::coords::canonicalToRender(canonical);
|
||||
|
||||
// Clamp creature Z to terrain surface during movement interpolation.
|
||||
// The server sends single-segment moves and expects the client to place
|
||||
// creatures on the ground. Only clamp while actively moving — idle
|
||||
// creatures keep their server-authoritative Z (flight masters, etc.).
|
||||
if (entity->isActivelyMoving() && renderer->getTerrainManager()) {
|
||||
auto terrainZ = renderer->getTerrainManager()->getHeightAt(renderPos.x, renderPos.y);
|
||||
if (terrainZ.has_value()) {
|
||||
renderPos.z = terrainZ.value();
|
||||
}
|
||||
}
|
||||
|
||||
// Visual collision guard: keep hostile melee units from rendering inside the
|
||||
// player's model while attacking. This is client-side only (no server position change).
|
||||
// Only check for creatures within 8 units (melee range) — saves expensive
|
||||
|
|
@ -1959,6 +1970,14 @@ void Application::update(float deltaTime) {
|
|||
inOverrun ? entity->getLatestZ() : entity->getZ());
|
||||
glm::vec3 renderPos = core::coords::canonicalToRender(canonical);
|
||||
|
||||
// Clamp other players' Z to terrain surface during movement
|
||||
if (entity->isActivelyMoving() && renderer->getTerrainManager()) {
|
||||
auto terrainZ = renderer->getTerrainManager()->getHeightAt(renderPos.x, renderPos.y);
|
||||
if (terrainZ.has_value()) {
|
||||
renderPos.z = terrainZ.value();
|
||||
}
|
||||
}
|
||||
|
||||
auto posIt = _pCreatureRenderPosCache.find(guid);
|
||||
if (posIt == _pCreatureRenderPosCache.end()) {
|
||||
charRenderer->setInstancePosition(instanceId, renderPos);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue