From 5f8f854794b3bbaf5ecb11bb11d27c3fec09557c Mon Sep 17 00:00:00 2001 From: Shauren Date: Mon, 9 Jan 2023 11:22:58 +0100 Subject: [PATCH] Core/Players: Allow teleporting to a specific instance id --- src/server/game/Entities/Player/Player.cpp | 18 +++++++++++++----- src/server/game/Entities/Player/Player.h | 16 ++++++++++++---- src/server/game/Handlers/MovementHandler.cpp | 4 +++- src/server/scripts/Commands/cs_group.cpp | 2 +- src/server/scripts/Commands/cs_misc.cpp | 4 ++-- 5 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index c44c2f889e..37cef1d533 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -312,6 +312,9 @@ Player::Player(WorldSession* session): Unit(true) // Player summoning m_summon_expire = 0; + m_summon_instanceId = 0; + + m_recall_instanceId = 0; m_seer = this; @@ -1416,7 +1419,7 @@ uint8 Player::GetChatTag() const return tag; } -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*/, Optional instanceId /*= {}*/) { if (!MapManager::IsValidMapCoord(mapid, x, y, z, orientation)) { @@ -1481,7 +1484,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati if (duel && GetMapId() != mapid && GetMap()->GetGameObject(GetGuidValue(PLAYER_DUEL_ARBITER))) DuelComplete(DUEL_FLED); - if (GetMapId() == mapid) + if (GetMapId() == mapid && (!instanceId || GetInstanceId() == instanceId)) { //lets reset far teleport flag if it wasn't reset during chained teleport SetSemaphoreTeleportFar(false); @@ -1494,6 +1497,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati SetSemaphoreTeleportNear(true); //lets save teleport destination for player m_teleport_dest = WorldLocation(mapid, x, y, z, orientation); + m_teleport_instanceId = {}; m_teleport_options = options; return true; } @@ -1510,6 +1514,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati // this will be used instead of the current location in SaveToDB m_teleport_dest = WorldLocation(mapid, x, y, z, orientation); + m_teleport_instanceId = {}; m_teleport_options = options; SetFallInformation(0, GetPositionZ()); @@ -1571,6 +1576,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati SetSemaphoreTeleportFar(true); //lets save teleport destination for player m_teleport_dest = WorldLocation(mapid, x, y, z, orientation); + m_teleport_instanceId = instanceId; m_teleport_options = options; return true; } @@ -1639,6 +1645,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati PurgeAndApplyPendingMovementChanges(false); m_teleport_dest = WorldLocation(mapid, x, y, z, orientation); + m_teleport_instanceId = instanceId; m_teleport_options = options; SetFallInformation(0, GetPositionZ()); // if the player is saved before worldportack (at logout for example) @@ -1662,9 +1669,9 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati return true; } -bool Player::TeleportTo(WorldLocation const& loc, uint32 options /*= 0*/) +bool Player::TeleportTo(WorldLocation const& loc, uint32 options /*= 0*/, Optional instanceId /*= {}*/) { - 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, instanceId); } bool Player::TeleportToBGEntryPoint() @@ -23735,6 +23742,7 @@ void Player::SendSummonRequestFrom(Unit* summoner) m_summon_expire = GameTime::GetGameTime() + MAX_PLAYER_SUMMON_DELAY; m_summon_location.WorldRelocate(*summoner); + m_summon_instanceId = summoner->GetInstanceId(); WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4); data << uint64(summoner->GetGUID()); // summoner guid @@ -23772,7 +23780,7 @@ void Player::SummonIfPossible(bool agree) UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS, 1); RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::Summon); - TeleportTo(m_summon_location); + TeleportTo(m_summon_location, 0, m_summon_instanceId); } void Player::RemoveItemDurations(Item* item) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index f1d3f01834..192f34dee9 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1029,8 +1029,8 @@ class TC_GAME_API Player : public Unit, public GridObject void SetObjectScale(float scale) override; - 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, Optional instanceId = {}); + bool TeleportTo(WorldLocation const& loc, uint32 options = 0, Optional instanceId = {}); bool TeleportToBGEntryPoint(); bool HasSummonPending() const; @@ -1917,6 +1917,7 @@ class TC_GAME_API Player : public Unit, public GridObject void SetSkillPermBonus(uint8 pos, uint16 value); WorldLocation& GetTeleportDest() { return m_teleport_dest; } + Optional GetTeleportDestInstanceId() const { return m_teleport_instanceId; } bool IsBeingTeleported() const { return mSemaphoreTeleport_Near || mSemaphoreTeleport_Far; } bool IsBeingTeleportedNear() const { return mSemaphoreTeleport_Near; } bool IsBeingTeleportedFar() const { return mSemaphoreTeleport_Far; } @@ -2161,8 +2162,12 @@ class TC_GAME_API Player : public Unit, public GridObject uint32 GetSaveTimer() const { return m_nextSave; } void SetSaveTimer(uint32 timer) { m_nextSave = timer; } - void SaveRecallPosition() { m_recall_location.WorldRelocate(*this); } - void Recall() { TeleportTo(m_recall_location); } + void SaveRecallPosition() + { + m_recall_location.WorldRelocate(*this); + m_recall_instanceId = GetInstanceId(); + } + void Recall() { TeleportTo(m_recall_location, 0, m_recall_instanceId); } void SetHomebind(WorldLocation const& loc, uint32 areaId); void SendBindPointUpdate() const; @@ -2650,9 +2655,11 @@ class TC_GAME_API Player : public Unit, public GridObject // Player summoning time_t m_summon_expire; WorldLocation m_summon_location; + uint32 m_summon_instanceId; // Recall position WorldLocation m_recall_location; + uint32 m_recall_instanceId; DeclinedName* m_declinedname; Runes* m_runes; @@ -2715,6 +2722,7 @@ class TC_GAME_API Player : public Unit, public GridObject // Current teleport data WorldLocation m_teleport_dest; + Optional m_teleport_instanceId; uint32 m_teleport_options; bool mSemaphoreTeleport_Near; bool mSemaphoreTeleport_Far; diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index c4d8e784c3..13f87af91a 100644 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -77,7 +77,9 @@ void WorldSession::HandleMoveWorldportAck() GetPlayer()->m_InstanceValid = true; Map* oldMap = GetPlayer()->GetMap(); - Map* newMap = sMapMgr->CreateMap(loc.GetMapId(), GetPlayer()); + Map* newMap = GetPlayer()->GetTeleportDestInstanceId() ? + sMapMgr->FindMap(loc.GetMapId(), *GetPlayer()->GetTeleportDestInstanceId()) : + sMapMgr->CreateMap(loc.GetMapId(), GetPlayer()); MovementInfo::TransportInfo transportInfo = GetPlayer()->m_movementInfo.transport; if (TransportBase* transport = GetPlayer()->GetTransport()) diff --git a/src/server/scripts/Commands/cs_group.cpp b/src/server/scripts/Commands/cs_group.cpp index 44479266b7..f5ed94dd74 100644 --- a/src/server/scripts/Commands/cs_group.cpp +++ b/src/server/scripts/Commands/cs_group.cpp @@ -155,7 +155,7 @@ public: // before GM float x, y, z; gmPlayer->GetClosePoint(x, y, z, player->GetCombatReach()); - player->TeleportTo(gmPlayer->GetMapId(), x, y, z, player->GetOrientation()); + player->TeleportTo(gmPlayer->GetMapId(), x, y, z, player->GetOrientation(), 0, gmPlayer->GetInstanceId()); } return true; diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 67c2ae9860..eaadef0172 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -461,7 +461,7 @@ public: float x, y, z; target->GetContactPoint(_player, x, y, z); - _player->TeleportTo(target->GetMapId(), x, y, z, _player->GetAngle(target), TELE_TO_GM_MODE); + _player->TeleportTo(target->GetMapId(), x, y, z, _player->GetAngle(target), TELE_TO_GM_MODE, target->GetInstanceId()); PhasingHandler::InheritPhaseShift(_player, target); _player->UpdateObjectVisibility(); } @@ -592,7 +592,7 @@ public: // before GM float x, y, z; _player->GetPosition(x, y, z); - target->TeleportTo(_player->GetMapId(), x, y, z, target->GetOrientation()); + target->TeleportTo(_player->GetMapId(), x, y, z, target->GetOrientation(), 0, map->GetInstanceId()); PhasingHandler::InheritPhaseShift(target, handler->GetSession()->GetPlayer()); target->UpdateObjectVisibility(); }