From bf60f8f5c6939f50cbe79644587921337c7b63eb Mon Sep 17 00:00:00 2001 From: Yehonal Date: Thu, 16 Nov 2017 00:13:54 +0000 Subject: [PATCH] Add summoner information to TeleportTo function and created OnBeforeTeleport hook --- src/game/Entities/Player/Player.cpp | 13 ++++++++----- src/game/Entities/Player/Player.h | 8 ++++---- src/game/Handlers/MovementHandler.cpp | 2 +- src/game/Scripting/ScriptMgr.cpp | 10 ++++++++++ src/game/Scripting/ScriptMgr.h | 4 ++++ src/scripts/Commands/cs_misc.cpp | 10 +++++----- 6 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/game/Entities/Player/Player.cpp b/src/game/Entities/Player/Player.cpp index e24bae9fe..cb3a97219 100644 --- a/src/game/Entities/Player/Player.cpp +++ b/src/game/Entities/Player/Player.cpp @@ -2189,8 +2189,8 @@ void Player::SendTeleportAckPacket() GetSession()->SendPacket(&data); } -bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options) -{ +bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options /*= 0*/, Unit *target /*= nullptr*/) +{ if (!MapManager::IsValidMapCoord(mapid, x, y, z, orientation)) { sLog->outError("TeleportTo: invalid map (%d) or invalid coordinates (X: %f, Y: %f, Z: %f, O: %f) given when teleporting player (GUID: %u, name: %s, map: %d, X: %f, Y: %f, Z: %f, O: %f).", @@ -2288,6 +2288,9 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati if (duel && GetMapId() != mapid && GetMap()->GetGameObject(GetUInt64Value(PLAYER_DUEL_ARBITER))) DuelComplete(DUEL_FLED); + if (!sScriptMgr->OnBeforePlayerTeleport(this, mapid, x, y, z, orientation, options, target)) + return false; + if (GetMapId() == mapid) { //lets reset far teleport flag if it wasn't reset during chained teleports @@ -23622,8 +23625,8 @@ void Player::UpdateForQuestWorldObjects() GetSession()->SendPacket(&packet); } -void Player::SummonIfPossible(bool agree) -{ +void Player::SummonIfPossible(bool agree, uint32 summoner_guid) +{ if (!agree) { m_summon_expire = 0; @@ -23643,7 +23646,7 @@ void Player::SummonIfPossible(bool agree) UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS, 1); - TeleportTo(m_summon_mapid, m_summon_x, m_summon_y, m_summon_z, GetOrientation()); + TeleportTo(m_summon_mapid, m_summon_x, m_summon_y, m_summon_z, GetOrientation(), 0, ObjectAccessor::FindPlayer(summoner_guid)); } void Player::RemoveItemDurations(Item* item) diff --git a/src/game/Entities/Player/Player.h b/src/game/Entities/Player/Player.h index a0f3ec042..3e879bf1e 100644 --- a/src/game/Entities/Player/Player.h +++ b/src/game/Entities/Player/Player.h @@ -1096,10 +1096,10 @@ class Player : public Unit, public GridObject SetFloatValue(UNIT_FIELD_COMBATREACH, scale * DEFAULT_COMBAT_REACH); } - bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options = 0); - bool TeleportTo(WorldLocation const &loc, uint32 options = 0) + bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options = 0, Unit *target = nullptr); + bool TeleportTo(WorldLocation const &loc, uint32 options = 0, Unit *target = nullptr) { - return TeleportTo(loc.GetMapId(), loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ(), loc.GetOrientation(), options); + return TeleportTo(loc.GetMapId(), loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ(), loc.GetOrientation(), options, target); } bool TeleportToEntryPoint(); @@ -1114,7 +1114,7 @@ class Player : public Unit, public GridObject } bool IsSummonAsSpectator() const { return m_summon_asSpectator && m_summon_expire >= time(NULL); } void SetSummonAsSpectator(bool on) { m_summon_asSpectator = on; } - void SummonIfPossible(bool agree); + void SummonIfPossible(bool agree, uint32 summoner_guid); time_t GetSummonExpireTimer() const { return m_summon_expire; } bool Create(uint32 guidlow, CharacterCreateInfo* createInfo); diff --git a/src/game/Handlers/MovementHandler.cpp b/src/game/Handlers/MovementHandler.cpp index 11a574b35..8d435b303 100644 --- a/src/game/Handlers/MovementHandler.cpp +++ b/src/game/Handlers/MovementHandler.cpp @@ -721,5 +721,5 @@ void WorldSession::HandleSummonResponseOpcode(WorldPacket& recvData) agree = false; } _player->SetSummonAsSpectator(false); - _player->SummonIfPossible(agree); + _player->SummonIfPossible(agree, summoner_guid); } diff --git a/src/game/Scripting/ScriptMgr.cpp b/src/game/Scripting/ScriptMgr.cpp index bb2f05f3b..eacb9e34c 100644 --- a/src/game/Scripting/ScriptMgr.cpp +++ b/src/game/Scripting/ScriptMgr.cpp @@ -1308,6 +1308,16 @@ void ScriptMgr::OnPlayerUpdateArea(Player* player, uint32 oldArea, uint32 newAre FOREACH_SCRIPT(PlayerScript)->OnUpdateArea(player, oldArea, newArea); } +bool ScriptMgr::OnBeforePlayerTeleport(Player* player, uint32 mapid, float x, float y, float z, float orientation, uint32 options, Unit *target) +{ + bool ret=true; + FOR_SCRIPTS_RET(PlayerScript, itr, end, ret) // return true by default if not scripts + if (!itr->second->OnBeforeTeleport(player, mapid, x, y, z, orientation, options, target)) + ret=false; // we change ret value only when scripts return false + + return ret; +} + void ScriptMgr::OnPlayerUpdateFaction(Player* player) { FOREACH_SCRIPT(PlayerScript)->OnUpdateFaction(player); diff --git a/src/game/Scripting/ScriptMgr.h b/src/game/Scripting/ScriptMgr.h index f99c3cc8e..7d4cfa0a1 100644 --- a/src/game/Scripting/ScriptMgr.h +++ b/src/game/Scripting/ScriptMgr.h @@ -848,6 +848,9 @@ class PlayerScript : public ScriptObject // Called when a player changes to a new map (after moving to new map) virtual void OnMapChanged(Player* /*player*/) { } + // Called before a player is being teleported to new coords + virtual bool OnBeforeTeleport(Player* /*player*/, uint32 /*mapid*/, float /*x*/, float /*y*/, float /*z*/, float /*orientation*/, uint32 /*options*/, Unit* /*target*/) { return true; } + // Called when team/faction is set on player virtual void OnUpdateFaction(Player* /*player*/) { } @@ -1221,6 +1224,7 @@ class ScriptMgr void OnPlayerBindToInstance(Player* player, Difficulty difficulty, uint32 mapid, bool permanent); void OnPlayerUpdateZone(Player* player, uint32 newZone, uint32 newArea); void OnPlayerUpdateArea(Player* player, uint32 oldArea, uint32 newArea); + bool OnBeforePlayerTeleport(Player* player, uint32 mapid, float x, float y, float z, float orientation, uint32 options, Unit *target); void OnPlayerUpdateFaction(Player* player); void OnPlayerAddToBattleground(Player* player, Battleground* bg); void OnPlayerRemoveFromBattleground(Player* player, Battleground* bg); diff --git a/src/scripts/Commands/cs_misc.cpp b/src/scripts/Commands/cs_misc.cpp index 5a3540468..268248f5b 100644 --- a/src/scripts/Commands/cs_misc.cpp +++ b/src/scripts/Commands/cs_misc.cpp @@ -612,8 +612,8 @@ public: else _player->SaveRecallPosition(); - _player->TeleportTo(target->GetMapId(), target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()+0.25f, _player->GetOrientation(), TELE_TO_GM_MODE); - _player->SetPhaseMask(target->GetPhaseMask() | 1, false); + if (_player->TeleportTo(target->GetMapId(), target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()+0.25f, _player->GetOrientation(), TELE_TO_GM_MODE, target)) + _player->SetPhaseMask(target->GetPhaseMask() | 1, false); } else { @@ -734,8 +734,8 @@ public: // before GM float x, y, z; handler->GetSession()->GetPlayer()->GetClosePoint(x, y, z, target->GetObjectSize()); - target->TeleportTo(handler->GetSession()->GetPlayer()->GetMapId(), x, y, z, target->GetOrientation()); - target->SetPhaseMask(handler->GetSession()->GetPlayer()->GetPhaseMask(), false); + if (target->TeleportTo(handler->GetSession()->GetPlayer()->GetMapId(), x, y, z, target->GetOrientation(), 0, handler->GetSession()->GetPlayer())) + target->SetPhaseMask(handler->GetSession()->GetPlayer()->GetPhaseMask(), false); } else { @@ -845,7 +845,7 @@ public: // before GM float x, y, z; handler->GetSession()->GetPlayer()->GetClosePoint(x, y, z, player->GetObjectSize()); - player->TeleportTo(handler->GetSession()->GetPlayer()->GetMapId(), x, y, z, player->GetOrientation()); + player->TeleportTo(handler->GetSession()->GetPlayer()->GetMapId(), x, y, z, player->GetOrientation(), 0, handler->GetSession()->GetPlayer()); } return true;