diff --git a/src/game/MapManager.cpp b/src/game/MapManager.cpp index cece28f3a..1b9d9b76b 100644 --- a/src/game/MapManager.cpp +++ b/src/game/MapManager.cpp @@ -194,38 +194,6 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player) return false; } - if (!player->isAlive()) - { - if(Corpse *corpse = player->GetCorpse()) - { - // let enter in ghost mode in instance that connected to inner instance with corpse - uint32 instance_map = corpse->GetMapId(); - do - { - if(instance_map==mapid) - break; - - InstanceTemplate const* instance = ObjectMgr::GetInstanceTemplate(instance_map); - instance_map = instance ? instance->parent : 0; - } - while (instance_map); - - if (!instance_map) - { - WorldPacket data(SMSG_AREA_TRIGGER_NO_CORPSE); - player->GetSession()->SendPacket(&data); - - DEBUG_LOG("MAP: Player '%s' doesn't has a corpse in instance '%s' and can't enter", player->GetName(), mapName); - return false; - } - DEBUG_LOG("MAP: Player '%s' has corpse in instance '%s' and can enter", player->GetName(), mapName); - } - else - { - DEBUG_LOG("Map::CanEnter - player '%s' is dead but doesn't have a corpse!", player->GetName()); - } - } - // TODO: move this to a map dependent location /*if(i_data && i_data->IsEncounterInProgress()) { diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp index a5b87627e..8405f1a42 100644 --- a/src/game/MiscHandler.cpp +++ b/src/game/MiscHandler.cpp @@ -714,7 +714,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data) return; uint32 quest_id = sObjectMgr.GetQuestForAreaTrigger( Trigger_ID ); - if( quest_id && pl->isAlive() && pl->IsActiveQuest(quest_id) ) + if ( quest_id && pl->isAlive() && pl->IsActiveQuest(quest_id) ) { Quest const* pQuest = sObjectMgr.GetQuestTemplate(quest_id); if( pQuest ) @@ -725,7 +725,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data) } // enter to tavern, not overwrite city rest - if(sObjectMgr.IsTavernAreaTrigger(Trigger_ID)) + if (sObjectMgr.IsTavernAreaTrigger(Trigger_ID)) { // set resting flag we are in the inn if (pl->GetRestType() != REST_TYPE_IN_CITY) @@ -733,7 +733,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data) return; } - if(pl->InBattleGround()) + if (pl->InBattleGround()) { if (BattleGround* bg = pl->GetBattleGround()) bg->HandleAreaTrigger(pl, Trigger_ID); @@ -742,69 +742,108 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data) // NULL if all values default (non teleport trigger) AreaTrigger const* at = sObjectMgr.GetAreaTrigger(Trigger_ID); - if(!at) + if (!at) return; - if(!GetPlayer()->isGameMaster()) + MapEntry const* targetMapEntry = sMapStore.LookupEntry(at->target_mapId); + if (!targetMapEntry) + return; + + if (!pl->isGameMaster()) { + // ghost resurrected at enter attempt to dungeon with corpse (including fail enter cases) + if (!pl->isAlive() && targetMapEntry->IsDungeon()) + { + int32 corpseMapId = 0; + if (Corpse *corpse = pl->GetCorpse()) + corpseMapId = corpse->GetMapId(); + + // check back way from corpse to entrance + uint32 instance_map = corpseMapId; + do + { + // most often fast case + if (instance_map==targetMapEntry->MapID) + break; + + InstanceTemplate const* instance = ObjectMgr::GetInstanceTemplate(instance_map); + instance_map = instance ? instance->parent : 0; + } + while (instance_map); + + // corpse not in dungeon or some linked deep dungeons + if (!instance_map) + { + WorldPacket data(SMSG_AREA_TRIGGER_NO_CORPSE); + pl->GetSession()->SendPacket(&data); + return; + } + + // need find areatrigger to inner dungeon for landing point + if (at->target_mapId != corpseMapId) + if (AreaTrigger const* corpseAt = sObjectMgr.GetMapEntranceTrigger(corpseMapId)) + at = corpseAt; + + // now we can resurrect player, and then check teleport requirements + pl->ResurrectPlayer(0.5f); + pl->SpawnCorpseBones(); + } + + // check trigger requirements bool missingItem = false; bool missingLevel = false; bool missingQuest = false; - if(GetPlayer()->getLevel() < at->requiredLevel && !sWorld.getConfig(CONFIG_BOOL_INSTANCE_IGNORE_LEVEL)) + if (pl->getLevel() < at->requiredLevel && !sWorld.getConfig(CONFIG_BOOL_INSTANCE_IGNORE_LEVEL)) missingLevel = true; // must have one or the other, report the first one that's missing - if(at->requiredItem) + if (at->requiredItem) { - if(!GetPlayer()->HasItemCount(at->requiredItem, 1) && + if (!pl->HasItemCount(at->requiredItem, 1) && (!at->requiredItem2 || !GetPlayer()->HasItemCount(at->requiredItem2, 1))) missingItem = true; } - else if(at->requiredItem2 && !GetPlayer()->HasItemCount(at->requiredItem2, 1)) + else if (at->requiredItem2 && !pl->HasItemCount(at->requiredItem2, 1)) missingItem = true; - MapEntry const* mapEntry = sMapStore.LookupEntry(at->target_mapId); - if(!mapEntry) - return; - - bool isRegularTargetMap = !mapEntry->IsDungeon() || GetPlayer()->GetDifficulty(mapEntry->IsRaid()) == REGULAR_DIFFICULTY; + bool isRegularTargetMap = !targetMapEntry->IsDungeon() || pl->GetDifficulty(targetMapEntry->IsRaid()) == REGULAR_DIFFICULTY; if (!isRegularTargetMap) { - if(at->heroicKey) + if (at->heroicKey) { - if(!GetPlayer()->HasItemCount(at->heroicKey, 1) && - (!at->heroicKey2 || !GetPlayer()->HasItemCount(at->heroicKey2, 1))) + if (!pl->HasItemCount(at->heroicKey, 1) && + (!at->heroicKey2 || !pl->HasItemCount(at->heroicKey2, 1))) missingItem = true; } - else if(at->heroicKey2 && !GetPlayer()->HasItemCount(at->heroicKey2, 1)) + else if (at->heroicKey2 && !pl->HasItemCount(at->heroicKey2, 1)) missingItem = true; } if (!isRegularTargetMap) { - if (at->requiredQuestHeroic && !GetPlayer()->GetQuestRewardStatus(at->requiredQuestHeroic)) + if (at->requiredQuestHeroic && !pl->GetQuestRewardStatus(at->requiredQuestHeroic)) missingQuest = true; } else { - if (at->requiredQuest && !GetPlayer()->GetQuestRewardStatus(at->requiredQuest)) + if (at->requiredQuest && !pl->GetQuestRewardStatus(at->requiredQuest)) missingQuest = true; } - if(missingItem || missingLevel || missingQuest) + if (missingItem || missingLevel || missingQuest) { // hack for "Opening of the Dark Portal" - if(missingQuest && at->target_mapId == 269) + if (missingQuest && at->target_mapId == 269) SendAreaTriggerMessage("%s", at->requiredFailedText.c_str()); - else if(missingQuest && mapEntry->IsContinent())// do not report anything for quest areatriggers + else if (missingQuest && targetMapEntry->IsContinent())// do not report anything for quest areatriggers return; // hack for TBC heroics - else if(missingLevel && !mapEntry->IsRaid() && GetPlayer()->GetDifficulty(false) == DUNGEON_DIFFICULTY_HEROIC && mapEntry->addon == 1) + else if (missingLevel && !targetMapEntry->IsRaid() && GetPlayer()->GetDifficulty(false) == DUNGEON_DIFFICULTY_HEROIC && targetMapEntry->addon == 1) SendAreaTriggerMessage(GetMangosString(LANG_LEVEL_MINREQUIRED), at->requiredLevel); else - GetPlayer()->SendTransferAborted(at->target_mapId, TRANSFER_ABORT_DIFFICULTY, GetPlayer()->GetDifficulty(mapEntry->IsRaid())); + pl->SendTransferAborted(at->target_mapId, TRANSFER_ABORT_DIFFICULTY, pl->GetDifficulty(targetMapEntry->IsRaid())); return; } } diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp index 7ecd4bdbb..ea77930c7 100644 --- a/src/game/MovementHandler.cpp +++ b/src/game/MovementHandler.cpp @@ -169,17 +169,6 @@ void WorldSession::HandleMoveWorldportAckOpcode() GetPlayer()->m_taxi.ClearTaxiDestinations(); } - // resurrect character at enter into instance where his corpse exist after add to map - Corpse *corpse = GetPlayer()->GetCorpse(); - if (corpse && corpse->GetType() != CORPSE_BONES && corpse->GetMapId() == GetPlayer()->GetMapId()) - { - if( mEntry->IsDungeon() ) - { - GetPlayer()->ResurrectPlayer(0.5f); - GetPlayer()->SpawnCorpseBones(); - } - } - if (mInstance) { Difficulty diff = GetPlayer()->GetDifficulty(mEntry->IsRaid()); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 463715536..745dc02c9 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "11445" + #define REVISION_NR "11446" #endif // __REVISION_NR_H__