aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorModoX <moardox@gmail.com>2023-07-21 18:55:20 +0200
committerGitHub <noreply@github.com>2023-07-21 18:55:20 +0200
commit4e7508db7b70b2b79ee1fc77a1899d08173ffc62 (patch)
treec9a2f50c6654be7d0b90974132fe8b69bc187ffa
parent5069f0e3a7a5feeab1b9540433ac7bd8bd9e0927 (diff)
Core/AreaTriggers: Teleport to current instance entrance when entering instances via areatrigger entity (#29115)
-rw-r--r--src/server/game/Entities/AreaTrigger/AreaTrigger.cpp9
-rw-r--r--src/server/game/Entities/Player/Player.cpp27
-rw-r--r--src/server/game/Entities/Player/Player.h2
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp25
4 files changed, 40 insertions, 23 deletions
diff --git a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp
index fb5e3f67e49..82716129e28 100644
--- a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp
+++ b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp
@@ -842,8 +842,17 @@ void AreaTrigger::DoActions(Unit* unit)
case AREATRIGGER_ACTION_TELEPORT:
{
if (WorldSafeLocsEntry const* safeLoc = sObjectMgr->GetWorldSafeLoc(action.Param))
+ {
if (Player* player = caster->ToPlayer())
+ {
+ if (player->GetMapId() != safeLoc->Loc.GetMapId())
+ {
+ if (WorldSafeLocsEntry const* instanceEntrance = player->GetInstanceEntrance(safeLoc->Loc.GetMapId()))
+ safeLoc = instanceEntrance;
+ }
player->TeleportTo(safeLoc->Loc);
+ }
+ }
break;
}
default:
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 1ce8798ec1a..ef02af2c52e 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -19541,6 +19541,33 @@ void Player::AddInstanceEnterTime(uint32 instanceId, time_t enterTime)
_instanceResetTimes.insert(InstanceTimeMap::value_type(instanceId, enterTime + HOUR));
}
+WorldSafeLocsEntry const* Player::GetInstanceEntrance(uint32 targetMapId)
+{
+ WorldSafeLocsEntry const* entranceLocation = nullptr;
+ MapEntry const* mapEntry = sMapStore.AssertEntry(targetMapId);
+
+ if (mapEntry->Instanceable())
+ {
+ // Check if we can contact the instancescript of the instance for an updated entrance location
+ if (uint32 targetInstanceId = sMapMgr->FindInstanceIdForPlayer(targetMapId, this))
+ if (Map* map = sMapMgr->FindMap(targetMapId, targetInstanceId))
+ if (InstanceMap* instanceMap = map->ToInstanceMap())
+ if (InstanceScript* instanceScript = instanceMap->GetInstanceScript())
+ entranceLocation = sObjectMgr->GetWorldSafeLoc(instanceScript->GetEntranceLocation());
+
+ // Finally check with the instancesave for an entrance location if we did not get a valid one from the instancescript
+ if (!entranceLocation)
+ {
+ Group* group = GetGroup();
+ Difficulty difficulty = group ? group->GetDifficultyID(mapEntry) : GetDifficultyID(mapEntry);
+ ObjectGuid instanceOwnerGuid = group ? group->GetRecentInstanceOwner(targetMapId) : GetGUID();
+ if (InstanceLock const* instanceLock = sInstanceLockMgr.FindActiveInstanceLock(instanceOwnerGuid, { mapEntry, sDB2Manager.GetDownscaledMapDifficultyData(targetMapId, difficulty) }))
+ entranceLocation = sObjectMgr->GetWorldSafeLoc(instanceLock->GetData()->EntranceWorldSafeLocId);
+ }
+ }
+ return entranceLocation;
+}
+
bool Player::_LoadHomeBind(PreparedQueryResult result)
{
PlayerInfo const* info = sObjectMgr->GetPlayerInfo(GetRace(), GetClass());
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index a46e9b05aa6..46820e470ea 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -65,6 +65,7 @@ struct TalentEntry;
struct TrainerSpell;
struct TransferAbortParams;
struct VendorItem;
+struct WorldSafeLocsEntry;
class AELootResult;
class Bag;
@@ -2608,6 +2609,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
bool CheckInstanceValidity(bool /*isLogin*/);
bool CheckInstanceCount(uint32 instanceId) const;
void AddInstanceEnterTime(uint32 instanceId, time_t enterTime);
+ WorldSafeLocsEntry const* GetInstanceEntrance(uint32 targetMapId);
// last used pet number (for BG's)
uint32 GetLastPetNumber() const { return m_lastpetnumber; }
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index 8318adb5a00..76b8dc60a92 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -675,29 +675,8 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPackets::AreaTrigger::AreaTrigge
if (!teleported)
{
- WorldSafeLocsEntry const* entranceLocation = nullptr;
- MapEntry const* mapEntry = sMapStore.AssertEntry(at->target_mapId);
- if (mapEntry->Instanceable())
- {
- // Check if we can contact the instancescript of the instance for an updated entrance location
- if (uint32 targetInstanceId = sMapMgr->FindInstanceIdForPlayer(at->target_mapId, _player))
- if (Map* map = sMapMgr->FindMap(at->target_mapId, targetInstanceId))
- if (InstanceMap* instanceMap = map->ToInstanceMap())
- if (InstanceScript* instanceScript = instanceMap->GetInstanceScript())
- entranceLocation = sObjectMgr->GetWorldSafeLoc(instanceScript->GetEntranceLocation());
-
- // Finally check with the instancesave for an entrance location if we did not get a valid one from the instancescript
- if (!entranceLocation)
- {
- Group* group = player->GetGroup();
- Difficulty difficulty = group ? group->GetDifficultyID(mapEntry) : player->GetDifficultyID(mapEntry);
- ObjectGuid instanceOwnerGuid = group ? group->GetRecentInstanceOwner(at->target_mapId) : player->GetGUID();
- if (InstanceLock const* instanceLock = sInstanceLockMgr.FindActiveInstanceLock(instanceOwnerGuid, { mapEntry, sDB2Manager.GetDownscaledMapDifficultyData(at->target_mapId, difficulty) }))
- entranceLocation = sObjectMgr->GetWorldSafeLoc(instanceLock->GetData()->EntranceWorldSafeLocId);
- }
- }
-
- if (entranceLocation)
+ WorldSafeLocsEntry const* entranceLocation = player->GetInstanceEntrance(at->target_mapId);
+ if (entranceLocation && player->GetMapId() != at->target_mapId)
player->TeleportTo(entranceLocation->Loc, TELE_TO_NOT_LEAVE_TRANSPORT);
else
player->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, at->target_Orientation, TELE_TO_NOT_LEAVE_TRANSPORT);