aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Handlers
diff options
context:
space:
mode:
authorTreeston <treeston.mmoc@gmail.com>2015-12-31 19:51:07 +0100
committerTreeston <treeston.mmoc@gmail.com>2015-12-31 19:51:07 +0100
commiteb3dc8a4f064d89b78248a511bcf67f805ea3314 (patch)
treeb22127216ef2ecb748ff817d0f293748bb263938 /src/server/game/Handlers
parent082eeda7fef26928090d42d1632e0dce1dfe5ab0 (diff)
parent43fa7d48a5650c71f74098f3398cf5aca89c3837 (diff)
Merge pull request #16110 from Treeston/3.3.5-instancerevive
Game/Maps: Clean up instance zone-in handling
Diffstat (limited to 'src/server/game/Handlers')
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp71
-rw-r--r--src/server/game/Handlers/MovementHandler.cpp19
2 files changed, 82 insertions, 8 deletions
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index 6dcd3242a6c..345202dc329 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -866,8 +866,77 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket& recvData)
bool teleported = false;
if (player->GetMapId() != at->target_mapId)
{
- if (!sMapMgr->CanPlayerEnter(at->target_mapId, player, false))
+ if (Map::EnterState denyReason = sMapMgr->PlayerCannotEnter(at->target_mapId, player, false))
+ {
+ bool reviveAtTrigger = false; // should we revive the player if he is trying to enter the correct instance?
+ switch (denyReason)
+ {
+ case Map::CANNOT_ENTER_NO_ENTRY:
+ TC_LOG_DEBUG("maps", "MAP: Player '%s' attempted to enter map with id %d which has no entry", player->GetName().c_str(), at->target_mapId);
+ break;
+ case Map::CANNOT_ENTER_UNINSTANCED_DUNGEON:
+ TC_LOG_DEBUG("maps", "MAP: Player '%s' attempted to enter dungeon map %d but no instance template was found", player->GetName().c_str(), at->target_mapId);
+ break;
+ case Map::CANNOT_ENTER_DIFFICULTY_UNAVAILABLE:
+ TC_LOG_DEBUG("maps", "MAP: Player '%s' attempted to enter instance map %d but the requested difficulty was not found", player->GetName().c_str(), at->target_mapId);
+ if (MapEntry const* entry = sMapStore.LookupEntry(at->target_mapId))
+ player->SendTransferAborted(entry->MapID, TRANSFER_ABORT_DIFFICULTY, player->GetDifficulty(entry->IsRaid()));
+ break;
+ case Map::CANNOT_ENTER_NOT_IN_RAID:
+ if (MapEntry const* entry = sMapStore.LookupEntry(at->target_mapId))
+ {
+ char const* mapName = entry->name[player->GetSession()->GetSessionDbcLocale()];
+ TC_LOG_DEBUG("maps", "MAP: Player '%s' must be in a raid group to enter instance '%s'", player->GetName().c_str(), mapName);
+ // probably there must be special opcode, because client has this string constant in GlobalStrings.lua
+ player->GetSession()->SendAreaTriggerMessage(player->GetSession()->GetTrinityString(LANG_INSTANCE_RAID_GROUP_ONLY), mapName);
+ }
+ reviveAtTrigger = true;
+ break;
+ case Map::CANNOT_ENTER_CORPSE_IN_DIFFERENT_INSTANCE:
+ {
+ WorldPacket data(SMSG_CORPSE_NOT_IN_INSTANCE);
+ player->GetSession()->SendPacket(&data);
+ TC_LOG_DEBUG("maps", "MAP: Player '%s' does not have a corpse in instance map %d and cannot enter", player->GetName().c_str(), at->target_mapId);
+ break;
+ }
+ case Map::CANNOT_ENTER_INSTANCE_BIND_MISMATCH:
+ if (MapEntry const* entry = sMapStore.LookupEntry(at->target_mapId))
+ {
+ char const* mapName = entry->name[player->GetSession()->GetSessionDbcLocale()];
+ TC_LOG_DEBUG("maps", "MAP: Player '%s' cannot enter instance map '%s' because their permanent bind is incompatible with their group's", player->GetName().c_str(), mapName);
+ // is there a special opcode for this?
+ // @todo figure out how to get player localized difficulty string (e.g. "10 player", "Heroic" etc)
+ ChatHandler(player->GetSession()).PSendSysMessage(player->GetSession()->GetTrinityString(LANG_INSTANCE_BIND_MISMATCH), mapName);
+ }
+ reviveAtTrigger = true;
+ break;
+ case Map::CANNOT_ENTER_TOO_MANY_INSTANCES:
+ player->SendTransferAborted(at->target_mapId, TRANSFER_ABORT_TOO_MANY_INSTANCES);
+ TC_LOG_DEBUG("maps", "MAP: Player '%s' cannot enter instance map %d because he has exceeded the maximum number of instances per hour.", player->GetName().c_str(), at->target_mapId);
+ reviveAtTrigger = true;
+ break;
+ case Map::CANNOT_ENTER_MAX_PLAYERS:
+ player->SendTransferAborted(at->target_mapId, TRANSFER_ABORT_MAX_PLAYERS);
+ reviveAtTrigger = true;
+ break;
+ case Map::CANNOT_ENTER_ZONE_IN_COMBAT:
+ player->SendTransferAborted(at->target_mapId, TRANSFER_ABORT_ZONE_IN_COMBAT);
+ reviveAtTrigger = true;
+ break;
+ default:
+ break;
+ }
+
+ if (reviveAtTrigger) // check if the player is touching the areatrigger leading to the map his corpse is on
+ if (!player->IsAlive() && player->HasCorpse())
+ if (player->GetCorpseLocation().GetMapId() == at->target_mapId)
+ {
+ player->ResurrectPlayer(0.5f);
+ player->SpawnCorpseBones();
+ }
+
return;
+ }
if (Group* group = player->GetGroup())
if (group->isLFGGroup() && player->GetMap()->IsDungeon())
diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp
index 84816bf3f33..33a50fad1f5 100644
--- a/src/server/game/Handlers/MovementHandler.cpp
+++ b/src/server/game/Handlers/MovementHandler.cpp
@@ -75,9 +75,9 @@ void WorldSession::HandleMoveWorldportAckOpcode()
}
// relocate the player to the teleport destination
- // the CanEnter checks are done in TeleporTo but conditions may change
+ // the CannotEnter checks are done in TeleporTo but conditions may change
// while the player is in transit, for example the map may get full
- if (!newMap || !newMap->CanEnter(GetPlayer()))
+ if (!newMap || newMap->CannotEnter(GetPlayer()))
{
TC_LOG_ERROR("network", "Map %d (%s) could not be created for player %d (%s), porting player to homebind", loc.GetMapId(), newMap ? newMap->GetMapName() : "Unknown", GetPlayer()->GetGUID().GetCounter(), GetPlayer()->GetName().c_str());
GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation());
@@ -142,19 +142,18 @@ void WorldSession::HandleMoveWorldportAckOpcode()
}
// resurrect character at enter into instance where his corpse exist after add to map
- Corpse* corpse = GetPlayer()->GetMap()->GetCorpseByPlayer(GetPlayer()->GetGUID());
- if (corpse && corpse->GetType() != CORPSE_BONES)
- {
- if (mEntry->IsDungeon())
+
+ if (mEntry->IsDungeon() && !GetPlayer()->IsAlive())
+ if (GetPlayer()->GetCorpseLocation().GetMapId() == mEntry->MapID)
{
GetPlayer()->ResurrectPlayer(0.5f, false);
GetPlayer()->SpawnCorpseBones();
}
- }
bool allowMount = !mEntry->IsDungeon() || mEntry->IsBattlegroundOrArena();
if (mInstance)
{
+ // check if this instance has a reset time and send it to player if so
Difficulty diff = GetPlayer()->GetDifficulty(mEntry->IsRaid());
if (MapDifficulty const* mapDiff = GetMapDifficultyData(mEntry->MapID, diff))
{
@@ -167,6 +166,12 @@ void WorldSession::HandleMoveWorldportAckOpcode()
}
}
}
+
+ // check if instance is valid
+ if (!GetPlayer()->CheckInstanceValidity(false))
+ GetPlayer()->m_InstanceValid = false;
+
+ // instance mounting is handled in InstanceTemplate
allowMount = mInstance->AllowMount;
}