From 268a2b952c8b9e411985499bfb62b32054f06850 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sat, 11 Apr 2009 09:43:33 +0400 Subject: [PATCH] [7648] Resolve problems with expected fall damage at near teleport. Move near teleport landing code to WorldSession::HandleMoveTeleportAck. This make Player::TeleportTo code working in same way for both far/near teleports. Move mSemaphoreTeleport from WorldObject to Player and merge with DoNotMove (using 2 fields for far/near teleport flag). Skip movement packets until landing confirmation for near teleport from client. --- src/game/Level1.cpp | 2 +- src/game/MiscHandler.cpp | 16 ----------- src/game/MovementHandler.cpp | 64 ++++++++++++++++++++++++++++++++++++------ src/game/Object.cpp | 3 +- src/game/Object.h | 4 --- src/game/Player.cpp | 67 +++++++++----------------------------------- src/game/Player.h | 28 +++++++++--------- src/game/WorldSession.cpp | 2 +- src/shared/revision_nr.h | 2 +- 9 files changed, 87 insertions(+), 101 deletions(-) diff --git a/src/game/Level1.cpp b/src/game/Level1.cpp index 30efd646..d98c0fe8 100644 --- a/src/game/Level1.cpp +++ b/src/game/Level1.cpp @@ -362,7 +362,7 @@ bool ChatHandler::HandleNamegoCommand(const char* args) if (HasLowerSecurity(chr, 0)) return false; - if(chr->IsBeingTeleported()==true) + if(chr->IsBeingTeleported()) { PSendSysMessage(LANG_IS_TELEPORTED, nameLink.c_str()); SetSentErrorMessage(true); diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp index 6d6b4f02..59097b3c 100644 --- a/src/game/MiscHandler.cpp +++ b/src/game/MiscHandler.cpp @@ -1121,22 +1121,6 @@ void WorldSession::HandleMoveRootAck(WorldPacket&/* recv_data*/) */ } -void WorldSession::HandleMoveTeleportAck(WorldPacket&/* recv_data*/) -{ - /* - CHECK_PACKET_SIZE(recv_data,8+4); - - sLog.outDebug("MSG_MOVE_TELEPORT_ACK"); - uint64 guid; - uint32 flags, time; - - recv_data >> guid; - recv_data >> flags >> time; - DEBUG_LOG("Guid " I64FMTD,guid); - DEBUG_LOG("Flags %u, time %u",flags, time/IN_MILISECONDS); - */ -} - void WorldSession::HandleSetActionBar(WorldPacket& recv_data) { CHECK_PACKET_SIZE(recv_data,1); diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp index 6cb6d521..9018bfb7 100644 --- a/src/game/MovementHandler.cpp +++ b/src/game/MovementHandler.cpp @@ -39,6 +39,10 @@ void WorldSession::HandleMoveWorldportAckOpcode( WorldPacket & /*recv_data*/ ) void WorldSession::HandleMoveWorldportAckOpcode() { + // ignore unexpected far teleports + if(!GetPlayer()->IsBeingTeleportedFar()) + return; + // get the teleport destination WorldLocation &loc = GetPlayer()->GetTeleportDest(); @@ -57,7 +61,7 @@ void WorldSession::HandleMoveWorldportAckOpcode() if(GetPlayer()->m_InstanceValid == false && !mInstance) GetPlayer()->m_InstanceValid = true; - GetPlayer()->SetSemaphoreTeleport(false); + GetPlayer()->SetSemaphoreTeleportFar(false); // relocate the player to the teleport destination GetPlayer()->SetMapId(loc.mapid); @@ -77,7 +81,6 @@ void WorldSession::HandleMoveWorldportAckOpcode() { sLog.outDebug("WORLD: teleport of player %s (%d) to location %d,%f,%f,%f,%f failed", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow(), loc.mapid, loc.x, loc.y, loc.z, loc.o); // teleport the player home - GetPlayer()->SetDontMove(false); if(!GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation())) { // the player must always be able to teleport home @@ -114,7 +117,6 @@ void WorldSession::HandleMoveWorldportAckOpcode() if(!_player->InBattleGround()) { // short preparations to continue flight - GetPlayer()->SetDontMove(false); FlightPathMovementGenerator* flight = (FlightPathMovementGenerator*)(GetPlayer()->GetMotionMaster()->top()); flight->Initialize(*GetPlayer()); return; @@ -156,8 +158,52 @@ void WorldSession::HandleMoveWorldportAckOpcode() // resummon pet GetPlayer()->ResummonPetTemporaryUnSummonedIfAny(); +} + +void WorldSession::HandleMoveTeleportAck(WorldPacket& recv_data) +{ + CHECK_PACKET_SIZE(recv_data,8+4); + + sLog.outDebug("MSG_MOVE_TELEPORT_ACK"); + uint64 guid; + uint32 flags, time; + + recv_data >> guid; + recv_data >> flags >> time; + DEBUG_LOG("Guid " I64FMTD,guid); + DEBUG_LOG("Flags %u, time %u",flags, time/IN_MILISECONDS); + + Unit *mover = _player->m_mover; + Player *plMover = mover->GetTypeId()==TYPEID_PLAYER ? (Player*)mover : NULL; + + if(!plMover || !plMover->IsBeingTeleportedNear()) + return; + + if(guid != plMover->GetGUID()) + return; - GetPlayer()->SetDontMove(false); + plMover->SetSemaphoreTeleportNear(false); + + uint32 old_zone = plMover->GetZoneId(); + + WorldLocation const& dest = plMover->GetTeleportDest(); + + plMover->SetPosition(dest.x, dest.y, dest.z, dest.o, true); + + uint32 newzone, newarea; + plMover->GetZoneAndAreaId(newzone,newarea); + plMover->UpdateZone(newzone,newarea); + + // new zone + if(old_zone != newzone) + { + // honorless target + if(plMover->pvpInfo.inHostileArea) + plMover->CastSpell(plMover, 2479, true); + } + + // resummon pet + GetPlayer()->ResummonPetTemporaryUnSummonedIfAny(); } void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) @@ -165,7 +211,11 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) uint32 opcode = recv_data.GetOpcode(); sLog.outDebug("WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(opcode), opcode, opcode); - if(GetPlayer()->GetDontMove()) + Unit *mover = _player->m_mover; + Player *plMover = mover->GetTypeId()==TYPEID_PLAYER ? (Player*)mover : NULL; + + // ignore, waiting processing in WorldSession::HandleMoveWorldportAckOpcode and WorldSession::HandleMoveTeleportAck + if(plMover && plMover->IsBeingTeleported()) return; /* extract packet */ @@ -183,9 +233,6 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) if (!MaNGOS::IsValidMapCoord(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o)) return; - Unit *mover = _player->m_mover; - Player *plMover = mover->GetTypeId()==TYPEID_PLAYER ? (Player*)mover : NULL; - /* handle special cases */ if (movementInfo.flags & MOVEMENTFLAG_ONTRANSPORT) { @@ -249,7 +296,6 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) plMover->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o); plMover->m_movementInfo = movementInfo; plMover->SetUnitMovementFlags(movementInfo.flags); - plMover->UpdateFallInformationIfNeed(movementInfo,recv_data.GetOpcode()); if(plMover->isMovingOrTurning()) diff --git a/src/game/Object.cpp b/src/game/Object.cpp index 4cfff237..d511dc4e 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -1025,8 +1025,7 @@ bool Object::PrintIndexError(uint32 index, bool set) const WorldObject::WorldObject() : m_mapId(0), m_InstanceId(0), m_phaseMask(PHASEMASK_NORMAL), - m_positionX(0.0f), m_positionY(0.0f), m_positionZ(0.0f), m_orientation(0.0f), - mSemaphoreTeleport(false) + m_positionX(0.0f), m_positionY(0.0f), m_positionZ(0.0f), m_orientation(0.0f) { } diff --git a/src/game/Object.h b/src/game/Object.h index 35c0b429..6cc6d267 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -445,8 +445,6 @@ class MANGOS_DLL_SPEC WorldObject : public Object virtual void SendMessageToSetInRange(WorldPacket *data, float dist, bool self); void BuildHeartBeatMsg( WorldPacket *data ) const; void BuildTeleportAckMsg( WorldPacket *data, float x, float y, float z, float ang) const; - bool IsBeingTeleported() { return mSemaphoreTeleport; } - void SetSemaphoreTeleport(bool semphsetting) { mSemaphoreTeleport = semphsetting; } void MonsterSay(const char* text, uint32 language, uint64 TargetGuid); void MonsterYell(const char* text, uint32 language, uint64 TargetGuid); @@ -494,7 +492,5 @@ class MANGOS_DLL_SPEC WorldObject : public Object float m_positionY; float m_positionZ; float m_orientation; - - bool mSemaphoreTeleport; }; #endif diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 7d77c282..42f4ddba 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -335,7 +335,8 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputa m_atLoginFlags = AT_LOGIN_NONE; - m_dontMove = false; + mSemaphoreTeleport_Near = false; + mSemaphoreTeleport_Far = false; pTrader = 0; ClearTrade(); @@ -1590,8 +1591,6 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati m_movementInfo.t_time = 0; } - SetSemaphoreTeleport(true); - // The player was ported to another map and looses the duel immediately. // We have to perform this check before the teleport, otherwise the // ObjectAccessor won't find the flag. @@ -1607,25 +1606,6 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati if ((GetMapId() == mapid) && (!m_transport)) { - // prepare zone change detect - uint32 old_zone = GetZoneId(); - - // near teleport - if(!GetSession()->PlayerLogout()) - { - WorldPacket data; - BuildTeleportAckMsg(&data, x, y, z, orientation); - GetSession()->SendPacket(&data); - SetPosition( x, y, z, orientation, true); - } - else - // this will be used instead of the current location in SaveToDB - m_teleport_dest = WorldLocation(mapid, x, y, z, orientation); - - SetFallInformation(0, z); - - //BuildHeartBeatMsg(&data); - //SendMessageToSet(&data, true); if (!(options & TELE_TO_NOT_UNSUMMON_PET)) { //same map, only remove pet if out of range for new position @@ -1636,30 +1616,19 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati if(!(options & TELE_TO_NOT_LEAVE_COMBAT)) CombatStop(); - if (!(options & TELE_TO_NOT_UNSUMMON_PET)) - { - // resummon pet - if (pet) - ResummonPetTemporaryUnSummonedIfAny(); - } - - uint32 newzone, newarea; - GetZoneAndAreaId(newzone,newarea); + // this will be used instead of the current location in SaveToDB + m_teleport_dest = WorldLocation(mapid, x, y, z, orientation); + SetFallInformation(0, z); + // code for finish transfer called in WorldSession::HandleMovementOpcodes() + // at client packet MSG_MOVE_TELEPORT_ACK + SetSemaphoreTeleportNear(true); + // near teleport, triggering send MSG_MOVE_TELEPORT_ACK from client at landing if(!GetSession()->PlayerLogout()) { - // don't reset teleport semaphore while logging out, otherwise m_teleport_dest won't be used in Player::SaveToDB - SetSemaphoreTeleport(false); - - UpdateZone(newzone,newarea); - } - - // new zone - if(old_zone != newzone) - { - // honorless target - if(pvpInfo.inHostileArea) - CastSpell(this, 2479, true); + WorldPacket data; + BuildTeleportAckMsg(&data, x, y, z, orientation); + GetSession()->SendPacket(&data); } } else @@ -1671,10 +1640,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati // Check enter rights before map getting to avoid creating instance copy for player // this check not dependent from map instance copy and same for all instance copies of selected map if (!MapManager::Instance().CanPlayerEnter(mapid, this)) - { - SetSemaphoreTeleport(false); return false; - } // If the map is not created, assume it is possible to enter it. // It will be created in the WorldPortAck. @@ -1759,10 +1725,8 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CHANGE_MAP | AURA_INTERRUPT_FLAG_MOVE | AURA_INTERRUPT_FLAG_TURNING); // move packet sent by client always after far teleport - // SetPosition(final_x, final_y, final_z, final_o, true); - SetDontMove(true); - // code for finish transfer to new map called in WorldSession::HandleMoveWorldportAckOpcode at client packet + SetSemaphoreTeleportFar(true); } else return false; @@ -5394,11 +5358,6 @@ void Player::removeActionButton(uint8 button) sLog.outDetail( "Action Button '%u' Removed from Player '%u'", button, GetGUIDLow() ); } -void Player::SetDontMove(bool dontMove) -{ - m_dontMove = dontMove; -} - bool Player::SetPosition(float x, float y, float z, float orientation, bool teleport) { // prevent crash when a bad coord is sent by the client diff --git a/src/game/Player.h b/src/game/Player.h index abc3f6ce..c3f4cdbe 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1653,8 +1653,12 @@ class MANGOS_DLL_SPEC Player : public Unit bool HasSkill(uint32 skill) const; void learnSkillRewardedSpells(uint32 id, uint32 value); - void SetDontMove(bool dontMove); - bool GetDontMove() const { return m_dontMove; } + WorldLocation& GetTeleportDest() { return m_teleport_dest; } + bool IsBeingTeleported() const { return mSemaphoreTeleport_Near || mSemaphoreTeleport_Far; } + bool IsBeingTeleportedNear() const { return mSemaphoreTeleport_Near; } + bool IsBeingTeleportedFar() const { return mSemaphoreTeleport_Far; } + void SetSemaphoreTeleportNear(bool semphsetting) { mSemaphoreTeleport_Near = semphsetting; } + void SetSemaphoreTeleportFar(bool semphsetting) { mSemaphoreTeleport_Far = semphsetting; } void CheckExploreSystem(void); @@ -2032,8 +2036,6 @@ class MANGOS_DLL_SPEC Player : public Unit bool isAllowedToLoot(Creature* creature); - WorldLocation& GetTeleportDest() { return m_teleport_dest; } - DeclinedName const* GetDeclinedNames() const { return m_declinedname; } uint8 GetRunesState() const { return m_runes->runeState; } uint8 GetBaseRune(uint8 index) const { return m_runes->runes[index].BaseRune; } @@ -2201,8 +2203,6 @@ class MANGOS_DLL_SPEC Player : public Unit typedef std::list JoinedChannelsList; JoinedChannelsList m_channels; - bool m_dontMove; - int m_cinematic; Player *pTrader; @@ -2268,10 +2268,6 @@ class MANGOS_DLL_SPEC Player : public Unit uint32 m_groupUpdateMask; uint64 m_auraUpdateMask; - // Temporarily removed pet cache - uint32 m_temporaryUnsummonedPetNumber; - uint32 m_oldpetspell; - uint64 m_miniPet; GuardianPetList m_guardianPets; @@ -2282,9 +2278,6 @@ class MANGOS_DLL_SPEC Player : public Unit float m_summon_y; float m_summon_z; - // Far Teleport - WorldLocation m_teleport_dest; - DeclinedName *m_declinedname; Runes *m_runes; private: @@ -2309,6 +2302,15 @@ class MANGOS_DLL_SPEC Player : public Unit uint8 m_MirrorTimerFlagsLast; bool m_isInWater; + // Current teleport data + WorldLocation m_teleport_dest; + bool mSemaphoreTeleport_Near; + bool mSemaphoreTeleport_Far; + + // Temporary removed pet cache + uint32 m_temporaryUnsummonedPetNumber; + uint32 m_oldpetspell; + AchievementMgr m_achievementMgr; ReputationMgr m_reputationMgr; }; diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp index a2c9ad09..da88c8e7 100644 --- a/src/game/WorldSession.cpp +++ b/src/game/WorldSession.cpp @@ -236,7 +236,7 @@ bool WorldSession::Update(uint32 /*diff*/) void WorldSession::LogoutPlayer(bool Save) { // finish pending transfers before starting the logout - while(_player && _player->IsBeingTeleported()) + while(_player && _player->IsBeingTeleportedFar()) HandleMoveWorldportAckOpcode(); m_playerLogout = true; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index aec65563..3945420d 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7647" + #define REVISION_NR "7648" #endif // __REVISION_NR_H__ -- 2.11.4.GIT