mirror of
https://github.com/mangosfour/server.git
synced 2025-12-25 13:37:02 +00:00
[12207] Rewrite Checks required when entering a map
Expected way from now on is: - Test if a map can be entered with Player::GetAreaTriggerLockStatus - IF this doesn't return AREA_LOCKSTATUS_OK, and if wanted, send the fail-message with Player::SendTransferAbortedByLockStatus function. Please feedback any hidden problems! Signed-off-by: Schmoozerd <schmoozerd@scriptdev2.com>
This commit is contained in:
parent
824aa5429e
commit
f432438665
11 changed files with 120 additions and 193 deletions
|
|
@ -1687,7 +1687,7 @@ void Player::SendTeleportPacket(float oldX, float oldY, float oldZ, float oldO)
|
|||
SendDirectMessage(&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*/, AreaTrigger const* at /*=NULL*/)
|
||||
{
|
||||
orientation = NormalizeOrientation(orientation);
|
||||
|
||||
|
|
@ -1707,24 +1707,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
|
|||
if (!InBattleGround() && mEntry->IsBattleGroundOrArena())
|
||||
return false;
|
||||
|
||||
// client without expansion support
|
||||
if (GetSession()->Expansion() < mEntry->Expansion())
|
||||
{
|
||||
DEBUG_LOG("Player %s using client without required expansion tried teleport to non accessible map %u", GetName(), mapid);
|
||||
|
||||
if (GetTransport())
|
||||
RepopAtGraveyard(); // teleport to near graveyard if on transport, looks blizz like :)
|
||||
|
||||
SendTransferAborted(mapid, TRANSFER_ABORT_INSUF_EXPAN_LVL, mEntry->Expansion());
|
||||
|
||||
return false; // normal client can't teleport to this map...
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG("Player %s is being teleported to map %u", GetName(), mapid);
|
||||
}
|
||||
|
||||
if (Group* grp = GetGroup())
|
||||
if (Group* grp = GetGroup()) // TODO: Verify that this is correct place
|
||||
grp->SetPlayerMap(GetObjectGuid(), mapid);
|
||||
|
||||
// if we were on a transport, leave
|
||||
|
|
@ -1746,8 +1729,20 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
|
|||
m_movementInfo.SetMovementFlags(MOVEFLAG_NONE);
|
||||
DisableSpline();
|
||||
|
||||
if ((GetMapId() == mapid) && (!m_transport))
|
||||
if ((GetMapId() == mapid) && (!m_transport)) // TODO the !m_transport might have unexpected effects when teleporting from transport to other place on same map
|
||||
{
|
||||
// If we are teleported by an areatrigger, check the requirements
|
||||
if (at)
|
||||
{
|
||||
uint32 miscRequirement = 0;
|
||||
AreaLockStatus lockStatus = GetAreaTriggerLockStatus(at, GetDifficulty(mEntry->IsRaid()), miscRequirement);
|
||||
if (lockStatus != AREA_LOCKSTATUS_OK)
|
||||
{
|
||||
SendTransferAbortedByLockStatus(mEntry, lockStatus, miscRequirement);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// lets reset far teleport flag if it wasn't reset during chained teleports
|
||||
SetSemaphoreTeleportFar(false);
|
||||
// setup delayed teleport flag
|
||||
|
|
@ -1796,15 +1791,19 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
|
|||
// check if we can enter before stopping combat / removing pet / totems / interrupting spells
|
||||
|
||||
// Check enter rights before map getting to avoid creating instance copy for player
|
||||
// this check not dependent from map instance copy and same for all instance copies of selected map
|
||||
if (!sMapMgr.CanPlayerEnter(mapid, this))
|
||||
uint32 miscRequirement = 0;
|
||||
AreaLockStatus lockStatus = GetAreaTriggerLockStatus(at ? at : sObjectMgr.GetMapEntranceTrigger(mapid), GetDifficulty(mEntry->IsRaid()), miscRequirement);
|
||||
if (lockStatus != AREA_LOCKSTATUS_OK)
|
||||
{
|
||||
SendTransferAbortedByLockStatus(mEntry, lockStatus, miscRequirement);
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the map is not created, assume it is possible to enter it.
|
||||
// It will be created in the WorldPortAck.
|
||||
DungeonPersistentState* state = GetBoundInstanceSaveForSelfOrGroup(mapid);
|
||||
Map* map = sMapMgr.FindMap(mapid, state ? state->GetInstanceId() : 0);
|
||||
if (!map || map->CanEnter(this))
|
||||
if (!map || map->CanEnter(this))
|
||||
{
|
||||
// lets reset near teleport flag if it wasn't reset during chained teleports
|
||||
SetSemaphoreTeleportNear(false);
|
||||
|
|
@ -1925,7 +1924,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
|
|||
SendSavedInstances();
|
||||
}
|
||||
}
|
||||
else
|
||||
else // !map->CanEnter(this)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -20181,14 +20180,66 @@ void Player::SendUpdateToOutOfRangeGroupMembers()
|
|||
pet->ResetAuraUpdateMask();
|
||||
}
|
||||
|
||||
void Player::SendTransferAborted(uint32 mapid, uint8 reason, uint8 arg)
|
||||
void Player::SendTransferAbortedByLockStatus(MapEntry const* mapEntry, AreaLockStatus lockStatus, uint32 miscRequirement)
|
||||
{
|
||||
WorldPacket data(SMSG_TRANSFER_ABORTED, 4 + 2);
|
||||
data << uint32(mapid);
|
||||
data << uint8(reason); // transfer abort reason
|
||||
data << uint8(arg);
|
||||
MANGOS_ASSERT(mapEntry);
|
||||
|
||||
GetSession()->SendPacket(&data);
|
||||
DEBUG_LOG("SendTransferAbortedByLockStatus: Called for %s on map %u, LockAreaStatus %u, miscRequirement %u)", GetGuidStr().c_str(), mapEntry->MapID, lockStatus, miscRequirement);
|
||||
|
||||
switch (lockStatus)
|
||||
{
|
||||
case AREA_LOCKSTATUS_TOO_LOW_LEVEL:
|
||||
GetSession()->SendAreaTriggerMessage(GetSession()->GetMangosString(LANG_LEVEL_MINREQUIRED), miscRequirement);
|
||||
break;
|
||||
case AREA_LOCKSTATUS_ZONE_IN_COMBAT:
|
||||
GetSession()->SendTransferAborted(mapEntry->MapID, TRANSFER_ABORT_ZONE_IN_COMBAT);
|
||||
break;
|
||||
case AREA_LOCKSTATUS_INSTANCE_IS_FULL:
|
||||
GetSession()->SendTransferAborted(mapEntry->MapID, TRANSFER_ABORT_MAX_PLAYERS);
|
||||
break;
|
||||
case AREA_LOCKSTATUS_QUEST_NOT_COMPLETED:
|
||||
if (mapEntry->MapID == 269) // Exception for Black Morass
|
||||
{
|
||||
GetSession()->SendAreaTriggerMessage(GetSession()->GetMangosString(LANG_TELEREQ_QUEST_BLACK_MORASS));
|
||||
break;
|
||||
}
|
||||
else if (mapEntry->IsContinent()) // do not report anything for quest areatrigge
|
||||
{
|
||||
DEBUG_LOG("SendTransferAbortedByLockStatus: LockAreaStatus %u, do not teleport, no message sent (mapId %u)", lockStatus, mapEntry->MapID);
|
||||
break;
|
||||
}
|
||||
// No break here!
|
||||
case AREA_LOCKSTATUS_MISSING_ITEM:
|
||||
GetSession()->SendTransferAborted(mapEntry->MapID, TRANSFER_ABORT_DIFFICULTY, GetDifficulty(mapEntry->IsRaid()));
|
||||
break;
|
||||
case AREA_LOCKSTATUS_MISSING_DIFFICULTY:
|
||||
{
|
||||
Difficulty difficulty = GetDifficulty(mapEntry->IsRaid());
|
||||
GetSession()->SendTransferAborted(mapEntry->MapID, TRANSFER_ABORT_DIFFICULTY, difficulty > RAID_DIFFICULTY_10MAN_HEROIC ? RAID_DIFFICULTY_10MAN_HEROIC : difficulty);
|
||||
break;
|
||||
}
|
||||
case AREA_LOCKSTATUS_INSUFFICIENT_EXPANSION:
|
||||
if (GetTransport())
|
||||
RepopAtGraveyard();
|
||||
GetSession()->SendTransferAborted(mapEntry->MapID, TRANSFER_ABORT_INSUF_EXPAN_LVL, miscRequirement);
|
||||
break;
|
||||
case AREA_LOCKSTATUS_NOT_ALLOWED:
|
||||
GetSession()->SendTransferAborted(mapEntry->MapID, TRANSFER_ABORT_MAP_NOT_ALLOWED);
|
||||
break;
|
||||
case AREA_LOCKSTATUS_RAID_LOCKED:
|
||||
GetSession()->SendTransferAborted(mapEntry->MapID, TRANSFER_ABORT_NEED_GROUP);
|
||||
break;
|
||||
case AREA_LOCKSTATUS_UNKNOWN_ERROR:
|
||||
GetSession()->SendTransferAborted(mapEntry->MapID, TRANSFER_ABORT_ERROR);
|
||||
break;
|
||||
case AREA_LOCKSTATUS_OK:
|
||||
sLog.outError("SendTransferAbortedByLockStatus: LockAreaStatus AREA_LOCKSTATUS_OK received for %s (mapId %u)", GetGuidStr().c_str(), mapEntry->MapID);
|
||||
MANGOS_ASSERT(false);
|
||||
break;
|
||||
default:
|
||||
sLog.outError("SendTransfertAbortedByLockstatus: unhandled LockAreaStatus %u, when %s attempts to enter in map %u", lockStatus, GetGuidStr().c_str(), mapEntry->MapID);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Player::SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint32 time)
|
||||
|
|
@ -23626,8 +23677,3 @@ AreaLockStatus Player::GetAreaTriggerLockStatus(AreaTrigger const* at, Difficult
|
|||
|
||||
return AREA_LOCKSTATUS_OK;
|
||||
};
|
||||
|
||||
AreaLockStatus Player::GetAreaLockStatus(uint32 mapId, Difficulty difficulty, uint32& miscRequirement)
|
||||
{
|
||||
return GetAreaTriggerLockStatus(sObjectMgr.GetMapEntranceTrigger(mapId), difficulty, miscRequirement);
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue