Core/Movement: Make it possible to get exact player position in scripts triggered directly by player movement (#29824)

Examples: PlayerScript on death by falling, AuraScript remove by interrupt flags (turning on vehicle, landing)
(cherry picked from commit a3ada797fdb1577f93b74b1daea688dc5bb89347)
This commit is contained in:
Mykhailo Redko
2026-08-01 21:41:03 +02:00
committed by Shauren
parent 36a5de288d
commit a62ad24490
3 changed files with 20 additions and 20 deletions
+5 -5
View File
@@ -27451,10 +27451,10 @@ void Player::SetFallInformation(uint32 time, float z)
m_lastFallZ = z; m_lastFallZ = z;
} }
void Player::HandleFall(MovementInfo const& movementInfo) void Player::HandleFall()
{ {
// calculate total z distance of the fall // calculate total z distance of the fall
float z_diff = m_lastFallZ - movementInfo.pos.GetPositionZ(); float z_diff = m_lastFallZ - m_movementInfo.pos.GetPositionZ();
//TC_LOG_DEBUG("misc", "zDiff = {}", z_diff); //TC_LOG_DEBUG("misc", "zDiff = {}", z_diff);
//Players with low fall distance, Feather Fall or physical immunity (charges used) are ignored //Players with low fall distance, Feather Fall or physical immunity (charges used) are ignored
@@ -27475,8 +27475,8 @@ void Player::HandleFall(MovementInfo const& movementInfo)
if (GetCommandStatus(CHEAT_GOD)) if (GetCommandStatus(CHEAT_GOD))
damage = 0; damage = 0;
float height = movementInfo.pos.m_positionZ; float height = m_movementInfo.pos.m_positionZ;
UpdateGroundPositionZ(movementInfo.pos.m_positionX, movementInfo.pos.m_positionY, height); UpdateGroundPositionZ(m_movementInfo.pos.m_positionX, m_movementInfo.pos.m_positionY, height);
damage *= GetTotalAuraMultiplier(SPELL_AURA_MODIFY_FALL_DAMAGE_PCT); damage *= GetTotalAuraMultiplier(SPELL_AURA_MODIFY_FALL_DAMAGE_PCT);
@@ -27499,7 +27499,7 @@ void Player::HandleFall(MovementInfo const& movementInfo)
} }
//Z given by moveinfo, LastZ, FallTime, WaterZ, MapZ, Damage, Safefall reduction //Z given by moveinfo, LastZ, FallTime, WaterZ, MapZ, Damage, Safefall reduction
TC_LOG_DEBUG("entities.player.falldamage", "FALLDAMAGE z={} sz={} pZ={} FallTime={} mZ={} damage={} SF={}\nPlayer debug info:\n{}", movementInfo.pos.GetPositionZ(), height, GetPositionZ(), movementInfo.jump.fallTime, height, damage, safe_fall, GetDebugInfo()); TC_LOG_DEBUG("entities.player.falldamage", "FALLDAMAGE z={} sz={} pZ={} FallTime={} mZ={} damage={} SF={}\nPlayer debug info:\n{}", m_movementInfo.pos.GetPositionZ(), height, GetPositionZ(), m_movementInfo.jump.fallTime, height, damage, safe_fall, GetDebugInfo());
} }
} }
} }
+1 -1
View File
@@ -2667,7 +2667,7 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player>
// only changed for direct client control (possess, vehicle etc.), not stuff you control using pet commands // only changed for direct client control (possess, vehicle etc.), not stuff you control using pet commands
WorldObject* m_seer; WorldObject* m_seer;
void SetFallInformation(uint32 time, float z); void SetFallInformation(uint32 time, float z);
void HandleFall(MovementInfo const& movementInfo); void HandleFall();
void SetClientControl(Unit* target, bool allowMove); void SetClientControl(Unit* target, bool allowMove);
+14 -14
View File
@@ -542,20 +542,6 @@ void WorldSession::HandleMovementOpcode(OpcodeClient opcode, MovementInfo& movem
else if (plrMover && plrMover->GetTransport()) // if we were on a transport, leave else if (plrMover && plrMover->GetTransport()) // if we were on a transport, leave
plrMover->GetTransport()->RemovePassenger(plrMover); plrMover->GetTransport()->RemovePassenger(plrMover);
// fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map).
if (opcode == CMSG_MOVE_FALL_LAND && plrMover && !plrMover->IsInFlight())
plrMover->HandleFall(movementInfo);
// interrupt parachutes upon falling or landing in water
if (opcode == CMSG_MOVE_FALL_LAND || opcode == CMSG_MOVE_START_SWIM || opcode == CMSG_MOVE_SET_FLY)
mover->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::LandingOrFlight); // Parachutes
if (opcode == CMSG_MOVE_SET_FLY || opcode == CMSG_MOVE_SET_ADV_FLY)
{
_player->UnsummonPetTemporaryIfAny(); // always do the pet removal on current client activeplayer only
_player->UnsummonBattlePetTemporaryIfAny(true);
}
/* process position-change */ /* process position-change */
movementInfo.guid = mover->GetGUID(); movementInfo.guid = mover->GetGUID();
movementInfo.time = AdjustClientMovementTime(movementInfo.time); movementInfo.time = AdjustClientMovementTime(movementInfo.time);
@@ -584,6 +570,20 @@ void WorldSession::HandleMovementOpcode(OpcodeClient opcode, MovementInfo& movem
moveUpdate.Status = &mover->m_movementInfo; moveUpdate.Status = &mover->m_movementInfo;
mover->SendMessageToSet(moveUpdate.Write(), _player); mover->SendMessageToSet(moveUpdate.Write(), _player);
// fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map).
if (opcode == CMSG_MOVE_FALL_LAND && plrMover && !plrMover->IsInFlight())
plrMover->HandleFall();
// interrupt parachutes upon falling or landing in water
if (opcode == CMSG_MOVE_FALL_LAND || opcode == CMSG_MOVE_START_SWIM)
mover->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::LandingOrFlight); // Parachutes
if (opcode == CMSG_MOVE_SET_FLY || opcode == CMSG_MOVE_SET_ADV_FLY)
{
_player->UnsummonPetTemporaryIfAny(); // always do the pet removal on current client activeplayer only
_player->UnsummonBattlePetTemporaryIfAny(true);
}
if (plrMover) // nothing is charmed, or player charmed if (plrMover) // nothing is charmed, or player charmed
{ {
if (plrMover->IsSitState() && (movementInfo.flags & (MOVEMENTFLAG_MASK_MOVING | MOVEMENTFLAG_MASK_TURNING))) if (plrMover->IsSitState() && (movementInfo.flags & (MOVEMENTFLAG_MASK_MOVING | MOVEMENTFLAG_MASK_TURNING)))