From 29c94e5455846bf69a3009ad4ea16e973fa64437 Mon Sep 17 00:00:00 2001 From: Skjalf <47818697+Nyeriah@users.noreply.github.com> Date: Thu, 7 Oct 2021 08:07:23 -0300 Subject: [PATCH] =?UTF-8?q?fix(Core/Graveyard):=20prevent=20non-death=20kn?= =?UTF-8?q?ights=20from=20getting=20ported=20to=E2=80=A6=20(#8206)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../game/Battlegrounds/Battleground.cpp | 2 +- src/server/game/Entities/Player/Player.cpp | 4 +-- src/server/game/Handlers/MovementHandler.cpp | 2 +- src/server/game/Handlers/NPCHandler.cpp | 11 +++--- src/server/game/Misc/GameGraveyard.cpp | 36 +++++++++++++++---- src/server/game/Misc/GameGraveyard.h | 3 +- src/server/scripts/Commands/cs_misc.cpp | 2 +- 7 files changed, 41 insertions(+), 19 deletions(-) diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index e0c87caaf..5441cb1a1 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -1998,7 +1998,7 @@ void Battleground::SetBgRaid(TeamId teamId, Group* bg_raid) GraveyardStruct const* Battleground::GetClosestGraveyard(Player* player) { - return sGraveyard->GetClosestGraveyard(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), player->GetBgTeamId()); + return sGraveyard->GetClosestGraveyard(player, player->GetBgTeamId()); } void Battleground::StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index f0a82c347..c20c2d59c 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -4782,7 +4782,7 @@ void Player::RepopAtGraveyard() if (sBattlefieldMgr->GetBattlefieldToZoneId(GetZoneId())) ClosestGrave = sBattlefieldMgr->GetBattlefieldToZoneId(GetZoneId())->GetClosestGraveyard(this); else - ClosestGrave = sGraveyard->GetClosestGraveyard(GetPositionX(), GetPositionY(), GetPositionZ(), GetMapId(), GetTeamId()); + ClosestGrave = sGraveyard->GetClosestGraveyard(this, GetTeamId()); } // stop countdown until repop @@ -10502,7 +10502,7 @@ void Player::SetEntryPoint() if (GetMap()->IsDungeon()) { - if (const GraveyardStruct* entry = sGraveyard->GetClosestGraveyard(GetPositionX(), GetPositionY(), GetPositionZ(), GetMapId(), GetTeamId())) + if (const GraveyardStruct* entry = sGraveyard->GetClosestGraveyard(this, GetTeamId())) m_entryPointData.joinPos = WorldLocation(entry->Map, entry->x, entry->y, entry->z, 0.0f); } else if (!GetMap()->IsBattlegroundOrArena()) diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index 27f7e5a11..eec83688c 100644 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -573,7 +573,7 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvData) } else if (!plrMover->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IS_OUT_OF_BOUNDS)) { - GraveyardStruct const* grave = sGraveyard->GetClosestGraveyard(plrMover->GetPositionX(), plrMover->GetPositionY(), plrMover->GetPositionZ(), plrMover->GetMapId(), plrMover->GetTeamId()); + GraveyardStruct const* grave = sGraveyard->GetClosestGraveyard(plrMover, plrMover->GetTeamId()); if (grave) { plrMover->TeleportTo(grave->Map, grave->x, grave->y, grave->z, plrMover->GetOrientation()); diff --git a/src/server/game/Handlers/NPCHandler.cpp b/src/server/game/Handlers/NPCHandler.cpp index 54c7881de..5a20c357a 100644 --- a/src/server/game/Handlers/NPCHandler.cpp +++ b/src/server/game/Handlers/NPCHandler.cpp @@ -421,12 +421,9 @@ void WorldSession::SendSpiritResurrect() // get corpse nearest graveyard GraveyardStruct const* corpseGrave = nullptr; - WorldLocation corpseLocation = _player->GetCorpseLocation(); - if (_player->HasCorpse()) - { - corpseGrave = sGraveyard->GetClosestGraveyard(corpseLocation.GetPositionX(), corpseLocation.GetPositionY(), - corpseLocation.GetPositionZ(), corpseLocation.GetMapId(), _player->GetTeamId()); - } + + // Search for any graveyards near the player's corpse. + corpseGrave = sGraveyard->GetClosestGraveyard(_player, _player->GetTeamId(), _player->HasCorpse()); // now can spawn bones _player->SpawnCorpseBones(); @@ -434,7 +431,7 @@ void WorldSession::SendSpiritResurrect() // teleport to nearest from corpse graveyard, if different from nearest to player ghost if (corpseGrave) { - GraveyardStruct const* ghostGrave = sGraveyard->GetClosestGraveyard(_player->GetPositionX(), _player->GetPositionY(), _player->GetPositionZ(), _player->GetMapId(), _player->GetTeamId()); + GraveyardStruct const* ghostGrave = sGraveyard->GetClosestGraveyard(_player, _player->GetTeamId()); if (corpseGrave != ghostGrave) _player->TeleportTo(corpseGrave->Map, corpseGrave->x, corpseGrave->y, corpseGrave->z, _player->GetOrientation()); diff --git a/src/server/game/Misc/GameGraveyard.cpp b/src/server/game/Misc/GameGraveyard.cpp index d7426ab6c..26da4f052 100644 --- a/src/server/game/Misc/GameGraveyard.cpp +++ b/src/server/game/Misc/GameGraveyard.cpp @@ -93,16 +93,28 @@ GraveyardStruct const* Graveyard::GetDefaultGraveyard(TeamId teamId) return sGraveyard->GetGraveyard(teamId == TEAM_HORDE ? HORDE_GRAVEYARD : ALLIANCE_GRAVEYARD); } -GraveyardStruct const* Graveyard::GetClosestGraveyard(float x, float y, float z, uint32 MapId, TeamId teamId) +GraveyardStruct const* Graveyard::GetClosestGraveyard(Player* player, TeamId teamId, bool nearCorpse) { + WorldLocation loc = player->GetWorldLocation(); + + if (nearCorpse) + { + loc = player->GetCorpseLocation(); + } + + uint32 mapId = loc.GetMapId(); + float x = loc.GetPositionX(); + float y = loc.GetPositionY(); + float z = loc.GetPositionZ(); + // search for zone associated closest graveyard - uint32 zoneId = sMapMgr->GetZoneId(PHASEMASK_NORMAL, MapId, x, y, z); + uint32 zoneId = player->GetZoneId(); if (!zoneId) { if (z > -500) { - LOG_ERROR("sql.sql", "ZoneId not found for map %u coords (%f, %f, %f)", MapId, x, y, z); + LOG_ERROR("sql.sql", "ZoneId not found for map %u coords (%f, %f, %f)", mapId, x, y, z); return GetDefaultGraveyard(teamId); } } @@ -115,7 +127,7 @@ GraveyardStruct const* Graveyard::GetClosestGraveyard(float x, float y, float z, // if mapId != graveyard.mapId (ghost in instance) and search any graveyard associated // then check faction GraveyardMapBounds range = GraveyardStore.equal_range(zoneId); - MapEntry const* map = sMapStore.LookupEntry(MapId); + MapEntry const* map = sMapStore.LookupEntry(mapId); // not need to check validity of map object; MapId _MUST_ be valid here if (range.first == range.second && !map->IsBattlegroundOrArena()) @@ -137,7 +149,7 @@ GraveyardStruct const* Graveyard::GetClosestGraveyard(float x, float y, float z, // some where other GraveyardStruct const* entryFar = nullptr; - MapEntry const* mapEntry = sMapStore.LookupEntry(MapId); + MapEntry const* mapEntry = sMapStore.LookupEntry(mapId); for (; range.first != range.second; ++range.first) { @@ -154,8 +166,20 @@ GraveyardStruct const* Graveyard::GetClosestGraveyard(float x, float y, float z, if (data.teamId != TEAM_NEUTRAL && teamId != TEAM_NEUTRAL && data.teamId != teamId) continue; + // Skip Archerus graveyards if the player isn't a Death Knight. + enum DeathKnightGraveyards + { + GRAVEYARD_EBON_HOLD = 1369, + GRAVEYARD_ARCHERUS = 1405 + }; + + if (player->getClass() != CLASS_DEATH_KNIGHT && (data.safeLocId == GRAVEYARD_EBON_HOLD || data.safeLocId == GRAVEYARD_ARCHERUS)) + { + continue; + } + // find now nearest graveyard at other map - if (MapId != entry->Map) + if (mapId != entry->Map) { // if find graveyard at different map from where entrance placed (or no entrance data), use any first if (!mapEntry diff --git a/src/server/game/Misc/GameGraveyard.h b/src/server/game/Misc/GameGraveyard.h index be1d46f9e..6992a0bd2 100644 --- a/src/server/game/Misc/GameGraveyard.h +++ b/src/server/game/Misc/GameGraveyard.h @@ -19,6 +19,7 @@ #define _GAMEGRAVEYARD_H_ #include "Common.h" +#include "Player.h" #include "SharedDefines.h" #include #include @@ -54,7 +55,7 @@ public: GraveyardStruct const* GetGraveyard(uint32 ID) const; GraveyardStruct const* GetGraveyard(const std::string& name) const; GraveyardStruct const* GetDefaultGraveyard(TeamId teamId); - GraveyardStruct const* GetClosestGraveyard(float x, float y, float z, uint32 MapId, TeamId teamId); + GraveyardStruct const* GetClosestGraveyard(Player* player, TeamId teamId, bool nearCorpse = false); GraveyardData const* FindGraveyardData(uint32 id, uint32 zone); GraveyardContainer const& GetGraveyardData() const { return _graveyardStore; } bool AddGraveyardLink(uint32 id, uint32 zoneId, TeamId teamId, bool persist = true); diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 6263d46d7..8e7c3b46e 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -1377,7 +1377,7 @@ public: Player* player = handler->GetSession()->GetPlayer(); uint32 zone_id = player->GetZoneId(); - GraveyardStruct const* graveyard = sGraveyard->GetClosestGraveyard(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), teamId); + GraveyardStruct const* graveyard = sGraveyard->GetClosestGraveyard(player, teamId); if (graveyard) {