[7533] Redirect movement packet in proper way to controlled target. Author: VladimirMangos
* In creature case ignore fall/etc damage
* In player case apply fall damage/etc to controlled player, apply other movement effect to it also.
--HG--
branch : trunk
This commit is contained in:
@@ -192,6 +192,9 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
|
|||||||
if (!Trinity::IsValidMapCoord(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o))
|
if (!Trinity::IsValidMapCoord(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Unit *mover = _player->m_mover;
|
||||||
|
Player *plMover = mover->GetTypeId()==TYPEID_PLAYER ? (Player*)mover : NULL;
|
||||||
|
|
||||||
/* handle special cases */
|
/* handle special cases */
|
||||||
if (movementInfo.flags & MOVEMENTFLAG_ONTRANSPORT)
|
if (movementInfo.flags & MOVEMENTFLAG_ONTRANSPORT)
|
||||||
{
|
{
|
||||||
@@ -205,24 +208,24 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// if we boarded a transport, add us to it
|
// if we boarded a transport, add us to it
|
||||||
if (!GetPlayer()->m_transport)
|
if (plMover && plMover->m_transport)
|
||||||
{
|
{
|
||||||
// elevators also cause the client to send MOVEMENTFLAG_ONTRANSPORT - just unmount if the guid can be found in the transport list
|
// elevators also cause the client to send MOVEMENTFLAG_ONTRANSPORT - just unmount if the guid can be found in the transport list
|
||||||
for (MapManager::TransportSet::iterator iter = MapManager::Instance().m_Transports.begin(); iter != MapManager::Instance().m_Transports.end(); ++iter)
|
for (MapManager::TransportSet::iterator iter = MapManager::Instance().m_Transports.begin(); iter != MapManager::Instance().m_Transports.end(); ++iter)
|
||||||
{
|
{
|
||||||
if ((*iter)->GetGUID() == movementInfo.t_guid)
|
if ((*iter)->GetGUID() == movementInfo.t_guid)
|
||||||
{
|
{
|
||||||
GetPlayer()->m_transport = (*iter);
|
plMover->m_transport = (*iter);
|
||||||
(*iter)->AddPassenger(GetPlayer());
|
(*iter)->AddPassenger(plMover);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (GetPlayer()->m_transport) // if we were on a transport, leave
|
else if (plMover && plMover->m_transport) // if we were on a transport, leave
|
||||||
{
|
{
|
||||||
GetPlayer()->m_transport->RemovePassenger(GetPlayer());
|
plMover->m_transport->RemovePassenger(plMover);
|
||||||
GetPlayer()->m_transport = NULL;
|
plMover->m_transport = NULL;
|
||||||
movementInfo.t_x = 0.0f;
|
movementInfo.t_x = 0.0f;
|
||||||
movementInfo.t_y = 0.0f;
|
movementInfo.t_y = 0.0f;
|
||||||
movementInfo.t_z = 0.0f;
|
movementInfo.t_z = 0.0f;
|
||||||
@@ -232,54 +235,68 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
|
|||||||
}
|
}
|
||||||
|
|
||||||
// fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map).
|
// fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map).
|
||||||
if (opcode == MSG_MOVE_FALL_LAND && !GetPlayer()->isInFlight())
|
if (opcode == MSG_MOVE_FALL_LAND && plMover && !plMover->isInFlight())
|
||||||
GetPlayer()->HandleFall(movementInfo);
|
plMover->HandleFall(movementInfo);
|
||||||
|
|
||||||
if(((movementInfo.flags & MOVEMENTFLAG_SWIMMING) != 0) != GetPlayer()->IsInWater())
|
if (plMover && ((movementInfo.flags & MOVEMENTFLAG_SWIMMING) != 0) != plMover->IsInWater())
|
||||||
{
|
{
|
||||||
// now client not include swimming flag in case jumping under water
|
// now client not include swimming flag in case jumping under water
|
||||||
GetPlayer()->SetInWater( !GetPlayer()->IsInWater() || GetPlayer()->GetBaseMap()->IsUnderWater(movementInfo.x, movementInfo.y, movementInfo.z) );
|
plMover->SetInWater( !plMover->IsInWater() || plMover->GetBaseMap()->IsUnderWater(movementInfo.x, movementInfo.y, movementInfo.z) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*----------------------*/
|
/*----------------------*/
|
||||||
|
|
||||||
/* process position-change */
|
/* process position-change */
|
||||||
Unit *mover = _player->m_mover;
|
|
||||||
recv_data.put<uint32>(6, getMSTime()); // fix time, offset flags(4) + unk(2)
|
recv_data.put<uint32>(6, getMSTime()); // fix time, offset flags(4) + unk(2)
|
||||||
WorldPacket data(recv_data.GetOpcode(), (mover->GetPackGUID().size()+recv_data.size()));
|
WorldPacket data(recv_data.GetOpcode(), (mover->GetPackGUID().size()+recv_data.size()));
|
||||||
data.append(mover->GetPackGUID()); // use mover guid
|
data.append(mover->GetPackGUID()); // use mover guid
|
||||||
data.append(recv_data.contents(), recv_data.size());
|
data.append(recv_data.contents(), recv_data.size());
|
||||||
GetPlayer()->SendMessageToSet(&data, false);
|
GetPlayer()->SendMessageToSet(&data, false);
|
||||||
|
|
||||||
if(!_player->GetCharmGUID()) // nothing is charmed
|
if(plMover) // nothing is charmed, or player charmed
|
||||||
{
|
{
|
||||||
_player->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
|
plMover->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
|
||||||
_player->m_movementInfo = movementInfo;
|
plMover->m_movementInfo = movementInfo;
|
||||||
_player->SetUnitMovementFlags(movementInfo.flags);
|
plMover->SetUnitMovementFlags(movementInfo.flags);
|
||||||
}
|
|
||||||
else
|
plMover->UpdateFallInformationIfNeed(movementInfo,recv_data.GetOpcode());
|
||||||
{
|
|
||||||
if(mover->GetTypeId() != TYPEID_PLAYER) // unit, creature, pet, vehicle...
|
if(plMover->isMovingOrTurning())
|
||||||
|
plMover->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||||
|
|
||||||
|
if(movementInfo.z < -500.0f)
|
||||||
{
|
{
|
||||||
if(Map *map = mover->GetMap())
|
if(plMover->InBattleGround()
|
||||||
map->CreatureRelocation((Creature*)mover, movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
|
&& plMover->GetBattleGround()
|
||||||
mover->SetUnitMovementFlags(movementInfo.flags);
|
&& plMover->GetBattleGround()->HandlePlayerUnderMap(_player))
|
||||||
}
|
{
|
||||||
else // player
|
// do nothing, the handle already did if returned true
|
||||||
{
|
}
|
||||||
((Player*)mover)->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
|
else
|
||||||
((Player*)mover)->m_movementInfo = movementInfo;
|
{
|
||||||
((Player*)mover)->SetUnitMovementFlags(movementInfo.flags);
|
// NOTE: this is actually called many times while falling
|
||||||
|
// even after the player has been teleported away
|
||||||
|
// TODO: discard movement packets after the player is rooted
|
||||||
|
if(plMover->isAlive())
|
||||||
|
{
|
||||||
|
plMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, GetPlayer()->GetMaxHealth());
|
||||||
|
// change the death state to CORPSE to prevent the death timer from
|
||||||
|
// starting in the next player update
|
||||||
|
plMover->KillPlayer();
|
||||||
|
plMover->BuildPlayerRepop();
|
||||||
|
}
|
||||||
|
|
||||||
|
// cancel the death timer here if started
|
||||||
|
plMover->RepopAtGraveyard();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else // creature charmed
|
||||||
GetPlayer()->UpdateFallInformationIfNeed(movementInfo,MSG_MOVE_FALL_LAND);
|
{
|
||||||
|
if(Map *map = mover->GetMap())
|
||||||
if(GetPlayer()->isMovingOrTurning())
|
map->CreatureRelocation((Creature*)mover, movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
|
||||||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
mover->SetUnitMovementFlags(movementInfo.flags);
|
||||||
|
}
|
||||||
if(movementInfo.z < -500.0f)
|
|
||||||
GetPlayer()->HandleFallUnderMap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data)
|
void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data)
|
||||||
|
|||||||
@@ -20048,33 +20048,6 @@ bool ItemPosCount::isContainedIn(ItemPosCountVec const& vec) const
|
|||||||
//-------------TRINITY---------------
|
//-------------TRINITY---------------
|
||||||
//***********************************
|
//***********************************
|
||||||
|
|
||||||
void Player::HandleFallUnderMap()
|
|
||||||
{
|
|
||||||
if(InBattleGround()
|
|
||||||
&& GetBattleGround()
|
|
||||||
&& GetBattleGround()->HandlePlayerUnderMap(this))
|
|
||||||
{
|
|
||||||
// do nothing, the handle already did if returned true
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// NOTE: this is actually called many times while falling
|
|
||||||
// even after the player has been teleported away
|
|
||||||
// TODO: discard movement packets after the player is rooted
|
|
||||||
if(isAlive())
|
|
||||||
{
|
|
||||||
EnvironmentalDamage(DAMAGE_FALL_TO_VOID, GetMaxHealth());
|
|
||||||
// change the death state to CORPSE to prevent the death timer from
|
|
||||||
// starting in the next player update
|
|
||||||
KillPlayer();
|
|
||||||
BuildPlayerRepop();
|
|
||||||
}
|
|
||||||
|
|
||||||
// cancel the death timer here if started
|
|
||||||
RepopAtGraveyard();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Player::StopCastingBindSight()
|
void Player::StopCastingBindSight()
|
||||||
{
|
{
|
||||||
if(WorldObject* target = GetViewpoint())
|
if(WorldObject* target = GetViewpoint())
|
||||||
|
|||||||
@@ -1975,8 +1975,6 @@ class TRINITY_DLL_SPEC Player : public Unit
|
|||||||
bool IsFlying() const { return HasUnitMovementFlag(MOVEMENTFLAG_FLYING); }
|
bool IsFlying() const { return HasUnitMovementFlag(MOVEMENTFLAG_FLYING); }
|
||||||
bool IsAllowUseFlyMountsHere() const;
|
bool IsAllowUseFlyMountsHere() const;
|
||||||
|
|
||||||
void HandleFallUnderMap();
|
|
||||||
|
|
||||||
void SetClientControl(Unit* target, uint8 allowMove);
|
void SetClientControl(Unit* target, uint8 allowMove);
|
||||||
|
|
||||||
void EnterVehicle(Vehicle *vehicle);
|
void EnterVehicle(Vehicle *vehicle);
|
||||||
|
|||||||
Reference in New Issue
Block a user