From 747a2a4f0edfb69c7fe34e6cdf3d37195be833d2 Mon Sep 17 00:00:00 2001 From: Skjalf <47818697+Nyeriah@users.noreply.github.com> Date: Wed, 13 Oct 2021 15:07:19 -0300 Subject: [PATCH] =?UTF-8?q?fix(Core/Graveyards):=20rework=20the=20graveyar?= =?UTF-8?q?d=20selection=20logic=20to=20allow=20l=E2=80=A6=20(#8022)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../rev_1632245299092353800.sql | 5 ++ src/server/game/Misc/GameGraveyard.cpp | 51 ++++++++++++------- src/server/game/Misc/GameGraveyard.h | 2 + 3 files changed, 40 insertions(+), 18 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1632245299092353800.sql diff --git a/data/sql/updates/pending_db_world/rev_1632245299092353800.sql b/data/sql/updates/pending_db_world/rev_1632245299092353800.sql new file mode 100644 index 000000000..08fb9a9df --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1632245299092353800.sql @@ -0,0 +1,5 @@ +INSERT INTO `version_db_world` (`sql_rev`) VALUES ('1632245299092353800'); + +DELETE FROM `graveyard_zone` WHERE `ID` = 101 AND `GhostZone` = 135; +INSERT INTO `graveyard_zone` (`ID`, `GhostZone`, `Faction`, `Comment`) VALUES +(101, 135, 469, 'Frostmane Hold, Kharanos GY - Dun Morogh'); diff --git a/src/server/game/Misc/GameGraveyard.cpp b/src/server/game/Misc/GameGraveyard.cpp index 26da4f052..1cca11a8d 100644 --- a/src/server/game/Misc/GameGraveyard.cpp +++ b/src/server/game/Misc/GameGraveyard.cpp @@ -107,14 +107,15 @@ GraveyardStruct const* Graveyard::GetClosestGraveyard(Player* player, TeamId tea float y = loc.GetPositionY(); float z = loc.GetPositionZ(); - // search for zone associated closest graveyard - uint32 zoneId = player->GetZoneId(); + uint32 zoneId = 0; + uint32 areaId = 0; + player->GetZoneAndAreaId(zoneId, areaId); - if (!zoneId) + if (!zoneId && !areaId) { 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", "GetClosestGraveyard: unable to find zoneId and areaId for map %u coords (%f, %f, %f)", mapId, x, y, z); return GetDefaultGraveyard(teamId); } } @@ -126,7 +127,26 @@ GraveyardStruct const* Graveyard::GetClosestGraveyard(Player* player, TeamId tea // then check faction // if mapId != graveyard.mapId (ghost in instance) and search any graveyard associated // then check faction - GraveyardMapBounds range = GraveyardStore.equal_range(zoneId); + + // Fetch the graveyards linked to the areaId first, presumably the closer ones. + GraveyardMapBounds range = GraveyardStore.equal_range(areaId); + + // No graveyards linked to the area, search zone. + if (range.first == range.second) + { + range = GraveyardStore.equal_range(zoneId); + } + else // Found a graveyard linked to the area, check if it's a valid one. + { + GraveyardData const& graveyardLink = range.first->second; + + if (!graveyardLink.IsNeutralOrFriendlyToTeam(teamId)) + { + // Not a friendly or neutral graveyard, search zone. + range = GraveyardStore.equal_range(zoneId); + } + } + MapEntry const* map = sMapStore.LookupEntry(mapId); // not need to check validity of map object; MapId _MUST_ be valid here @@ -153,18 +173,19 @@ GraveyardStruct const* Graveyard::GetClosestGraveyard(Player* player, TeamId tea for (; range.first != range.second; ++range.first) { - GraveyardData const& data = range.first->second; - GraveyardStruct const* entry = sGraveyard->GetGraveyard(data.safeLocId); + GraveyardData const& graveyardLink = range.first->second; + GraveyardStruct const* entry = sGraveyard->GetGraveyard(graveyardLink.safeLocId); if (!entry) { - LOG_ERROR("sql.sql", "Table `graveyard_zone` has record for not existing `game_graveyard` table %u, skipped.", data.safeLocId); + LOG_ERROR("sql.sql", "Table `graveyard_zone` has record for not existing `game_graveyard` table %u, skipped.", graveyardLink.safeLocId); continue; } - // skip enemy faction graveyard - // team == 0 case can be at call from .neargrave - if (data.teamId != TEAM_NEUTRAL && teamId != TEAM_NEUTRAL && data.teamId != teamId) + // Skip enemy faction graveyard. + if (!graveyardLink.IsNeutralOrFriendlyToTeam(teamId)) + { continue; + } // Skip Archerus graveyards if the player isn't a Death Knight. enum DeathKnightGraveyards @@ -173,7 +194,7 @@ GraveyardStruct const* Graveyard::GetClosestGraveyard(Player* player, TeamId tea GRAVEYARD_ARCHERUS = 1405 }; - if (player->getClass() != CLASS_DEATH_KNIGHT && (data.safeLocId == GRAVEYARD_EBON_HOLD || data.safeLocId == GRAVEYARD_ARCHERUS)) + if (player->getClass() != CLASS_DEATH_KNIGHT && (graveyardLink.safeLocId == GRAVEYARD_EBON_HOLD || graveyardLink.safeLocId == GRAVEYARD_ARCHERUS)) { continue; } @@ -373,12 +394,6 @@ void Graveyard::LoadGraveyardZones() continue; } - if (areaEntry->zone != 0) - { - LOG_ERROR("sql.sql", "Table `graveyard_zone` has a record for subzone id (%u) instead of zone, skipped.", zoneId); - continue; - } - if (team != 0 && team != HORDE && team != ALLIANCE) { LOG_ERROR("sql.sql", "Table `graveyard_zone` has a record for non player faction (%u), skipped.", team); diff --git a/src/server/game/Misc/GameGraveyard.h b/src/server/game/Misc/GameGraveyard.h index 6992a0bd2..35092818b 100644 --- a/src/server/game/Misc/GameGraveyard.h +++ b/src/server/game/Misc/GameGraveyard.h @@ -39,6 +39,8 @@ struct GraveyardData { uint32 safeLocId; TeamId teamId; + + [[nodiscard]] bool IsNeutralOrFriendlyToTeam(TeamId playerTeamId) const { return teamId == TEAM_NEUTRAL || playerTeamId == TEAM_NEUTRAL || teamId == playerTeamId; } }; typedef std::multimap WGGraveyardContainer;