diff options
author | Treeston <treeston.mmoc@gmail.com> | 2015-12-31 19:51:07 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2016-03-21 19:41:28 +0100 |
commit | 7422557d03b3cbb5b00a39b16c52f879c2f31fdd (patch) | |
tree | c379a50a7ba112b8a4f5149f6c89973939a8675d /src/server/game/Handlers/MiscHandler.cpp | |
parent | 96ca739a0b0d2b34a28fbac0593e076fb3c42f1b (diff) |
Merge pull request #16110 from Treeston/3.3.5-instancerevive
Game/Maps: Clean up instance zone-in handling
(cherry picked from commit eb3dc8a4f064d89b78248a511bcf67f805ea3314)
Diffstat (limited to 'src/server/game/Handlers/MiscHandler.cpp')
-rw-r--r-- | src/server/game/Handlers/MiscHandler.cpp | 63 |
1 files changed, 62 insertions, 1 deletions
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index b94b4ce838e..a9db9d52572 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -534,8 +534,69 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPackets::Misc::AreaTrigger& pack 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->ID, TRANSFER_ABORT_DIFFICULTY, player->GetDifficultyID(entry)); + break; + case Map::CANNOT_ENTER_NOT_IN_RAID: + TC_LOG_DEBUG("maps", "MAP: Player '%s' must be in a raid group to enter map %d", player->GetName().c_str(), at->target_mapId); + player->SendRaidGroupOnlyMessage(RAID_GROUP_ERR_ONLY, 0); + reviveAtTrigger = true; + break; + case Map::CANNOT_ENTER_CORPSE_IN_DIFFERENT_INSTANCE: + player->GetSession()->SendPacket(WorldPackets::Misc::AreaTriggerNoCorpse().Write()); + 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->MapName_lang; + 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()) |