mirror of
https://github.com/liyunfan1223/azerothcore-wotlk.git
synced 2026-08-08 15:58:04 +00:00
fix(Core/Graveyards): rework the graveyard selection logic to allow l… (#8022)
This commit is contained in:
@@ -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');
|
||||||
@@ -107,14 +107,15 @@ GraveyardStruct const* Graveyard::GetClosestGraveyard(Player* player, TeamId tea
|
|||||||
float y = loc.GetPositionY();
|
float y = loc.GetPositionY();
|
||||||
float z = loc.GetPositionZ();
|
float z = loc.GetPositionZ();
|
||||||
|
|
||||||
// search for zone associated closest graveyard
|
uint32 zoneId = 0;
|
||||||
uint32 zoneId = player->GetZoneId();
|
uint32 areaId = 0;
|
||||||
|
player->GetZoneAndAreaId(zoneId, areaId);
|
||||||
|
|
||||||
if (!zoneId)
|
if (!zoneId && !areaId)
|
||||||
{
|
{
|
||||||
if (z > -500)
|
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);
|
return GetDefaultGraveyard(teamId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -126,7 +127,26 @@ GraveyardStruct const* Graveyard::GetClosestGraveyard(Player* player, TeamId tea
|
|||||||
// then check faction
|
// then check faction
|
||||||
// if mapId != graveyard.mapId (ghost in instance) and search any graveyard associated
|
// if mapId != graveyard.mapId (ghost in instance) and search any graveyard associated
|
||||||
// then check faction
|
// 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);
|
MapEntry const* map = sMapStore.LookupEntry(mapId);
|
||||||
|
|
||||||
// not need to check validity of map object; MapId _MUST_ be valid here
|
// 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)
|
for (; range.first != range.second; ++range.first)
|
||||||
{
|
{
|
||||||
GraveyardData const& data = range.first->second;
|
GraveyardData const& graveyardLink = range.first->second;
|
||||||
GraveyardStruct const* entry = sGraveyard->GetGraveyard(data.safeLocId);
|
GraveyardStruct const* entry = sGraveyard->GetGraveyard(graveyardLink.safeLocId);
|
||||||
if (!entry)
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip enemy faction graveyard
|
// Skip enemy faction graveyard.
|
||||||
// team == 0 case can be at call from .neargrave
|
if (!graveyardLink.IsNeutralOrFriendlyToTeam(teamId))
|
||||||
if (data.teamId != TEAM_NEUTRAL && teamId != TEAM_NEUTRAL && data.teamId != teamId)
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Skip Archerus graveyards if the player isn't a Death Knight.
|
// Skip Archerus graveyards if the player isn't a Death Knight.
|
||||||
enum DeathKnightGraveyards
|
enum DeathKnightGraveyards
|
||||||
@@ -173,7 +194,7 @@ GraveyardStruct const* Graveyard::GetClosestGraveyard(Player* player, TeamId tea
|
|||||||
GRAVEYARD_ARCHERUS = 1405
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -373,12 +394,6 @@ void Graveyard::LoadGraveyardZones()
|
|||||||
continue;
|
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)
|
if (team != 0 && team != HORDE && team != ALLIANCE)
|
||||||
{
|
{
|
||||||
LOG_ERROR("sql.sql", "Table `graveyard_zone` has a record for non player faction (%u), skipped.", team);
|
LOG_ERROR("sql.sql", "Table `graveyard_zone` has a record for non player faction (%u), skipped.", team);
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ struct GraveyardData
|
|||||||
{
|
{
|
||||||
uint32 safeLocId;
|
uint32 safeLocId;
|
||||||
TeamId teamId;
|
TeamId teamId;
|
||||||
|
|
||||||
|
[[nodiscard]] bool IsNeutralOrFriendlyToTeam(TeamId playerTeamId) const { return teamId == TEAM_NEUTRAL || playerTeamId == TEAM_NEUTRAL || teamId == playerTeamId; }
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::multimap<uint32, GraveyardData> WGGraveyardContainer;
|
typedef std::multimap<uint32, GraveyardData> WGGraveyardContainer;
|
||||||
|
|||||||
Reference in New Issue
Block a user