Core/AreaTriggers: Teleport to current instance entrance when entering instances via areatrigger entity (#29115)

This commit is contained in:
ModoX
2023-07-21 18:55:20 +02:00
committed by GitHub
parent 5069f0e3a7
commit 4e7508db7b
4 changed files with 40 additions and 23 deletions

View File

@@ -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:

View File

@@ -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());

View File

@@ -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; }

View File

@@ -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);