fix(Core/Graveyards): rework the graveyard selection logic to allow l… (#8022)

This commit is contained in:
Skjalf
2021-10-13 15:07:19 -03:00
committed by GitHub
parent 92a7f8b5bd
commit 747a2a4f0e
3 changed files with 40 additions and 18 deletions

View File

@@ -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');

View File

@@ -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);

View File

@@ -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<uint32, GraveyardData> WGGraveyardContainer;