[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:
megamage
2009-03-24 17:42:22 -06:00
parent 941e5b9dbd
commit 1c6c199f5d
3 changed files with 53 additions and 65 deletions
+53 -36
View File
@@ -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)
-27
View File
@@ -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())
-2
View File
@@ -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);