diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 2af1cd7ca..fe43768f4 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -480,6 +480,7 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputa m_DelayedOperations = 0; m_bCanDelayTeleport = false; m_bHasDelayedTeleport = false; + m_bHasBeenAliveAtDelayedTeleport = true; // overwrite always at setup teleport data, so not used infact m_teleport_options = 0; m_trade = NULL; @@ -1474,9 +1475,7 @@ void Player::Update( uint32 p_time ) RemovePet(pet, PET_SAVE_NOT_IN_SLOT, true); } - //we should execute delayed teleports only for alive(!) players - //because we don't want player's ghost teleported from graveyard - if(IsHasDelayedTeleport() && isAlive()) + if (IsHasDelayedTeleport()) TeleportTo(m_teleport_dest, m_teleport_options); } @@ -1775,10 +1774,9 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati //lets reset far teleport flag if it wasn't reset during chained teleports SetSemaphoreTeleportFar(false); //setup delayed teleport flag - SetDelayedTeleportFlag(IsCanDelayTeleport()); //if teleport spell is casted in Unit::Update() func //then we need to delay it until update process will be finished - if(IsHasDelayedTeleport()) + if (SetDelayedTeleportFlagIfCan()) { SetSemaphoreTeleportNear(true); //lets save teleport destination for player @@ -1794,7 +1792,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati UnsummonPetTemporaryIfAny(); } - if(!(options & TELE_TO_NOT_LEAVE_COMBAT)) + if (!(options & TELE_TO_NOT_LEAVE_COMBAT)) CombatStop(); // this will be used instead of the current location in SaveToDB @@ -1831,10 +1829,9 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati //lets reset near teleport flag if it wasn't reset during chained teleports SetSemaphoreTeleportNear(false); //setup delayed teleport flag - SetDelayedTeleportFlag(IsCanDelayTeleport()); //if teleport spell is casted in Unit::Update() func //then we need to delay it until update process will be finished - if(IsHasDelayedTeleport()) + if (SetDelayedTeleportFlagIfCan()) { SetSemaphoreTeleportFar(true); //lets save teleport destination for player @@ -1850,7 +1847,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati ResetContestedPvP(); // remove player from battleground on far teleport (when changing maps) - if(BattleGround const* bg = GetBattleGround()) + if (BattleGround const* bg = GetBattleGround()) { // Note: at battleground join battleground id set before teleport // and we already will found "current" battleground @@ -1868,14 +1865,14 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati // stop spellcasting // not attempt interrupt teleportation spell at caster teleport - if(!(options & TELE_TO_SPELL)) - if(IsNonMeleeSpellCasted(true)) + if (!(options & TELE_TO_SPELL)) + if (IsNonMeleeSpellCasted(true)) InterruptNonMeleeSpells(true); //remove auras before removing from map... RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CHANGE_MAP | AURA_INTERRUPT_FLAG_MOVE | AURA_INTERRUPT_FLAG_TURNING); - if(!GetSession()->PlayerLogout()) + if (!GetSession()->PlayerLogout()) { // send transfer packets WorldPacket data(SMSG_TRANSFER_PENDING, (4+4+4)); @@ -1909,7 +1906,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati } // remove from old map now - if(oldmap) + if (oldmap) oldmap->Remove(this, false); // new final coordinates @@ -1918,7 +1915,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati float final_z = z; float final_o = orientation; - if(m_transport) + if (m_transport) { final_x += m_movementInfo.GetTransportPos()->x; final_y += m_movementInfo.GetTransportPos()->y; @@ -13538,10 +13535,6 @@ void Player::IncompleteQuest( uint32 quest_id ) void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver, bool announce ) { - //this THING should be here to protect code from quest, which cast on player far teleport as a reward - //should work fine, cause far teleport will be executed in Player::Update() - SetCanDelayTeleport(true); - uint32 quest_id = pQuest->GetQuestId(); for (int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i ) @@ -13693,9 +13686,6 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver if (!HasAura(itr->second->spellId, EFFECT_INDEX_0)) CastSpell(this,itr->second->spellId,true); } - - //lets remove flag for delayed teleports - SetCanDelayTeleport(false); } void Player::FailQuest(uint32 questId) diff --git a/src/game/Player.h b/src/game/Player.h index 942d68fdd..548d4645f 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -2593,14 +2593,24 @@ class MANGOS_DLL_SPEC Player : public Unit int32 CalculateReputationGain(uint32 creatureOrQuestLevel, int32 rep, int32 faction, bool for_quest); void AdjustQuestReqItemCount( Quest const* pQuest, QuestStatusData& questStatusData ); - bool IsCanDelayTeleport() const { return m_bCanDelayTeleport; } void SetCanDelayTeleport(bool setting) { m_bCanDelayTeleport = setting; } - bool IsHasDelayedTeleport() const { return m_bHasDelayedTeleport; } - void SetDelayedTeleportFlag(bool setting) { m_bHasDelayedTeleport = setting; } + bool IsHasDelayedTeleport() const + { + // we should not execute delayed teleports for now dead players but has been alive at teleport + // because we don't want player's ghost teleported from graveyard + return m_bHasDelayedTeleport && (isAlive() || !m_bHasBeenAliveAtDelayedTeleport); + } + + bool SetDelayedTeleportFlagIfCan() + { + m_bHasDelayedTeleport = m_bCanDelayTeleport; + m_bHasBeenAliveAtDelayedTeleport = isAlive(); + return m_bHasDelayedTeleport; + } void ScheduleDelayedOperation(uint32 operation) { - if(operation < DELAYED_END) + if (operation < DELAYED_END) m_DelayedOperations |= operation; } @@ -2634,6 +2644,7 @@ class MANGOS_DLL_SPEC Player : public Unit uint32 m_DelayedOperations; bool m_bCanDelayTeleport; bool m_bHasDelayedTeleport; + bool m_bHasBeenAliveAtDelayedTeleport; uint32 m_DetectInvTimer; diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp index 4bc0aa7d1..8a8b3831d 100644 --- a/src/game/WorldSession.cpp +++ b/src/game/WorldSession.cpp @@ -876,7 +876,7 @@ void WorldSession::ExecuteOpcode( OpcodeHandler const& opHandle, WorldPacket* pa //we should execute delayed teleports only for alive(!) players //because we don't want player's ghost teleported from graveyard - if (_player->IsHasDelayedTeleport() && _player->isAlive()) + if (_player->IsHasDelayedTeleport()) _player->TeleportTo(_player->m_teleport_dest, _player->m_teleport_options); } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index b8493141b..2e194d857 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 "10079" + #define REVISION_NR "10080" #endif // __REVISION_NR_H__