mirror of
https://github.com/mangosfour/server.git
synced 2025-12-16 13:37:00 +00:00
[11446] Reimplement corpse enter to instance.
* Resurrect player _before_ enter to instance with corpse * In case corpse in more deep instance teleport to corpse instance inner entrance. * If by some reason player can't enter to corpse instance it will just resurrected before entrance. Original patch and research done by Den.
This commit is contained in:
parent
6d28c7dfd0
commit
605fb79847
4 changed files with 65 additions and 69 deletions
|
|
@ -194,38 +194,6 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player)
|
||||||
return false;
|
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
|
// TODO: move this to a map dependent location
|
||||||
/*if(i_data && i_data->IsEncounterInProgress())
|
/*if(i_data && i_data->IsEncounterInProgress())
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -745,51 +745,90 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data)
|
||||||
if (!at)
|
if (!at)
|
||||||
return;
|
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 missingItem = false;
|
||||||
bool missingLevel = false;
|
bool missingLevel = false;
|
||||||
bool missingQuest = 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;
|
missingLevel = true;
|
||||||
|
|
||||||
// must have one or the other, report the first one that's missing
|
// 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)))
|
(!at->requiredItem2 || !GetPlayer()->HasItemCount(at->requiredItem2, 1)))
|
||||||
missingItem = true;
|
missingItem = true;
|
||||||
}
|
}
|
||||||
else if(at->requiredItem2 && !GetPlayer()->HasItemCount(at->requiredItem2, 1))
|
else if (at->requiredItem2 && !pl->HasItemCount(at->requiredItem2, 1))
|
||||||
missingItem = true;
|
missingItem = true;
|
||||||
|
|
||||||
MapEntry const* mapEntry = sMapStore.LookupEntry(at->target_mapId);
|
bool isRegularTargetMap = !targetMapEntry->IsDungeon() || pl->GetDifficulty(targetMapEntry->IsRaid()) == REGULAR_DIFFICULTY;
|
||||||
if(!mapEntry)
|
|
||||||
return;
|
|
||||||
|
|
||||||
bool isRegularTargetMap = !mapEntry->IsDungeon() || GetPlayer()->GetDifficulty(mapEntry->IsRaid()) == REGULAR_DIFFICULTY;
|
|
||||||
|
|
||||||
if (!isRegularTargetMap)
|
if (!isRegularTargetMap)
|
||||||
{
|
{
|
||||||
if (at->heroicKey)
|
if (at->heroicKey)
|
||||||
{
|
{
|
||||||
if(!GetPlayer()->HasItemCount(at->heroicKey, 1) &&
|
if (!pl->HasItemCount(at->heroicKey, 1) &&
|
||||||
(!at->heroicKey2 || !GetPlayer()->HasItemCount(at->heroicKey2, 1)))
|
(!at->heroicKey2 || !pl->HasItemCount(at->heroicKey2, 1)))
|
||||||
missingItem = true;
|
missingItem = true;
|
||||||
}
|
}
|
||||||
else if(at->heroicKey2 && !GetPlayer()->HasItemCount(at->heroicKey2, 1))
|
else if (at->heroicKey2 && !pl->HasItemCount(at->heroicKey2, 1))
|
||||||
missingItem = true;
|
missingItem = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isRegularTargetMap)
|
if (!isRegularTargetMap)
|
||||||
{
|
{
|
||||||
if (at->requiredQuestHeroic && !GetPlayer()->GetQuestRewardStatus(at->requiredQuestHeroic))
|
if (at->requiredQuestHeroic && !pl->GetQuestRewardStatus(at->requiredQuestHeroic))
|
||||||
missingQuest = true;
|
missingQuest = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (at->requiredQuest && !GetPlayer()->GetQuestRewardStatus(at->requiredQuest))
|
if (at->requiredQuest && !pl->GetQuestRewardStatus(at->requiredQuest))
|
||||||
missingQuest = true;
|
missingQuest = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -798,13 +837,13 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data)
|
||||||
// hack for "Opening of the Dark Portal"
|
// 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());
|
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;
|
return;
|
||||||
// hack for TBC heroics
|
// 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);
|
SendAreaTriggerMessage(GetMangosString(LANG_LEVEL_MINREQUIRED), at->requiredLevel);
|
||||||
else
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -169,17 +169,6 @@ void WorldSession::HandleMoveWorldportAckOpcode()
|
||||||
GetPlayer()->m_taxi.ClearTaxiDestinations();
|
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)
|
if (mInstance)
|
||||||
{
|
{
|
||||||
Difficulty diff = GetPlayer()->GetDifficulty(mEntry->IsRaid());
|
Difficulty diff = GetPlayer()->GetDifficulty(mEntry->IsRaid());
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "11445"
|
#define REVISION_NR "11446"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue