Core/Graveyards: Drop Faction column and replace it with conditions

Port From (https://github.com/TrinityCore/TrinityCore/commit/c1df555e1691d788918845f95252358f25e54bb5)
This commit is contained in:
hondacrx
2023-06-13 04:20:54 -04:00
parent 2a12697cb2
commit 31ffbf3512
18 changed files with 131 additions and 123 deletions
+1 -1
View File
@@ -557,7 +557,7 @@ namespace Game.BattleFields
return null;
}
public WorldSafeLocsEntry GetClosestGraveYard(Player player)
public WorldSafeLocsEntry GetClosestGraveyard(Player player)
{
BfGraveyard closestGY = null;
float maxdist = -1;
+2 -2
View File
@@ -1714,9 +1714,9 @@ namespace Game.BattleGrounds
m_BgRaids[GetTeamIndexByTeamId(team)] = bg_raid;
}
public virtual WorldSafeLocsEntry GetClosestGraveYard(Player player)
public virtual WorldSafeLocsEntry GetClosestGraveyard(Player player)
{
return Global.ObjectMgr.GetClosestGraveYard(player, GetPlayerTeam(player.GetGUID()), player);
return Global.ObjectMgr.GetClosestGraveyard(player, GetPlayerTeam(player.GetGUID()), player);
}
public override void TriggerGameEvent(uint gameEventId, WorldObject source = null, WorldObject target = null)
@@ -614,7 +614,7 @@ namespace Game.BattleGrounds.Zones
base.EndBattleground(winner);
}
public override WorldSafeLocsEntry GetClosestGraveYard(Player player)
public override WorldSafeLocsEntry GetClosestGraveyard(Player player)
{
int teamIndex = GetTeamIndexByTeamId(GetPlayerTeam(player.GetGUID()));
@@ -766,10 +766,10 @@ namespace Game.BattleGrounds.Zones
if (!BgCreatures[Point].IsEmpty())
DelCreature(Point);
WorldSafeLocsEntry sg = Global.ObjectMgr.GetWorldSafeLoc(EotSMisc.m_CapturingPointTypes[Point].GraveYardId);
WorldSafeLocsEntry sg = Global.ObjectMgr.GetWorldSafeLoc(EotSMisc.m_CapturingPointTypes[Point].GraveyardId);
if (sg == null || !AddSpiritGuide(Point, sg.Loc.GetPositionX(), sg.Loc.GetPositionY(), sg.Loc.GetPositionZ(), 3.124139f, GetTeamIndexByTeamId(Team)))
Log.outError(LogFilter.Battleground, "BatteGroundEY: Failed to spawn spirit guide. point: {0}, team: {1}, graveyard_id: {2}",
Point, Team, EotSMisc.m_CapturingPointTypes[Point].GraveYardId);
Point, Team, EotSMisc.m_CapturingPointTypes[Point].GraveyardId);
// SpawnBGCreature(Point, RESPAWN_IMMEDIATELY);
@@ -847,7 +847,7 @@ namespace Game.BattleGrounds.Zones
return true;
}
public override WorldSafeLocsEntry GetClosestGraveYard(Player player)
public override WorldSafeLocsEntry GetClosestGraveyard(Player player)
{
uint g_id;
Team team = GetPlayerTeam(player.GetGUID());
@@ -881,9 +881,9 @@ namespace Game.BattleGrounds.Zones
{
if (m_PointOwnedByTeam[i] == team && m_PointState[i] == EotSPointState.UnderControl)
{
entry = Global.ObjectMgr.GetWorldSafeLoc(EotSMisc.m_CapturingPointTypes[i].GraveYardId);
entry = Global.ObjectMgr.GetWorldSafeLoc(EotSMisc.m_CapturingPointTypes[i].GraveyardId);
if (entry == null)
Log.outError(LogFilter.Battleground, "BattlegroundEY: Graveyard {0} could not be found.", EotSMisc.m_CapturingPointTypes[i].GraveYardId);
Log.outError(LogFilter.Battleground, "BattlegroundEY: Graveyard {0} could not be found.", EotSMisc.m_CapturingPointTypes[i].GraveyardId);
else
{
distance = (entry.Loc.GetPositionX() - plr_x) * (entry.Loc.GetPositionX() - plr_x) + (entry.Loc.GetPositionY() - plr_y) * (entry.Loc.GetPositionY() - plr_y) + (entry.Loc.GetPositionZ() - plr_z) * (entry.Loc.GetPositionZ() - plr_z);
@@ -1011,14 +1011,14 @@ namespace Game.BattleGrounds.Zones
struct BattlegroundEYCapturingPointStruct
{
public BattlegroundEYCapturingPointStruct(int _DespawnNeutralObjectType, int _SpawnObjectTypeAlliance, uint _MessageIdAlliance, int _SpawnObjectTypeHorde, uint _MessageIdHorde, uint _GraveYardId)
public BattlegroundEYCapturingPointStruct(int _DespawnNeutralObjectType, int _SpawnObjectTypeAlliance, uint _MessageIdAlliance, int _SpawnObjectTypeHorde, uint _MessageIdHorde, uint _GraveyardId)
{
DespawnNeutralObjectType = _DespawnNeutralObjectType;
SpawnObjectTypeAlliance = _SpawnObjectTypeAlliance;
MessageIdAlliance = _MessageIdAlliance;
SpawnObjectTypeHorde = _SpawnObjectTypeHorde;
MessageIdHorde = _MessageIdHorde;
GraveYardId = _GraveYardId;
GraveyardId = _GraveyardId;
}
public int DespawnNeutralObjectType;
@@ -1026,7 +1026,7 @@ namespace Game.BattleGrounds.Zones
public uint MessageIdAlliance;
public int SpawnObjectTypeHorde;
public uint MessageIdHorde;
public uint GraveYardId;
public uint GraveyardId;
}
struct EotSMisc
@@ -640,7 +640,7 @@ namespace Game.BattleGrounds.Zones
{
}
public override WorldSafeLocsEntry GetClosestGraveYard(Player player)
public override WorldSafeLocsEntry GetClosestGraveyard(Player player)
{
uint safeloc;
@@ -797,7 +797,7 @@ namespace Game.BattleGrounds.Zones
return true;
}
public override WorldSafeLocsEntry GetClosestGraveYard(Player player)
public override WorldSafeLocsEntry GetClosestGraveyard(Player player)
{
//if status in progress, it returns main graveyards with spiritguides
//else it will return the graveyard in the flagroom - this is especially good
+3 -3
View File
@@ -684,14 +684,14 @@ namespace Game.Chat
{
Battleground bg = player.GetBattleground();
if (bg)
nearestLoc = bg.GetClosestGraveYard(player);
nearestLoc = bg.GetClosestGraveyard(player);
else
{
BattleField bf = Global.BattleFieldMgr.GetBattlefieldToZoneId(player.GetMap(), player.GetZoneId());
if (bf != null)
nearestLoc = bf.GetClosestGraveYard(player);
nearestLoc = bf.GetClosestGraveyard(player);
else
nearestLoc = Global.ObjectMgr.GetClosestGraveYard(player, player.GetTeam(), player);
nearestLoc = Global.ObjectMgr.GetClosestGraveyard(player, player.GetTeam(), player);
}
}
else
+3 -5
View File
@@ -790,7 +790,7 @@ namespace Game.Chat
return false;
}
if (Global.ObjectMgr.AddGraveYardLink(graveyardId, zoneId, team))
if (Global.ObjectMgr.AddGraveyardLink(graveyardId, zoneId, team, true))
handler.SendSysMessage(CypherStrings.CommandGraveyardlinked, graveyardId, zoneId);
else
handler.SendSysMessage(CypherStrings.CommandGraveyardalrlinked, graveyardId, zoneId);
@@ -1060,20 +1060,18 @@ namespace Game.Chat
Player player = handler.GetSession().GetPlayer();
uint zoneId = player.GetZoneId();
WorldSafeLocsEntry graveyard = Global.ObjectMgr.GetClosestGraveYard(player, team, null);
WorldSafeLocsEntry graveyard = Global.ObjectMgr.GetClosestGraveyard(player, team, null);
if (graveyard != null)
{
uint graveyardId = graveyard.Id;
GraveYardData data = Global.ObjectMgr.FindGraveYardData(graveyardId, zoneId);
GraveyardData data = Global.ObjectMgr.FindGraveyardData(graveyardId, zoneId);
if (data == null)
{
handler.SendSysMessage(CypherStrings.CommandGraveyarderror, graveyardId);
return false;
}
team = (Team)data.team;
string team_name = handler.GetCypherString(CypherStrings.CommandGraveyardNoteam);
if (team == 0)
+19 -2
View File
@@ -148,6 +148,7 @@ namespace Game
sourceType == ConditionSourceType.SmartEvent ||
sourceType == ConditionSourceType.NpcVendor ||
sourceType == ConditionSourceType.Phase ||
sourceType == ConditionSourceType.Graveyard ||
sourceType == ConditionSourceType.AreaTrigger ||
sourceType == ConditionSourceType.TrainerSpell ||
sourceType == ConditionSourceType.ObjectIdVisibility;
@@ -561,6 +562,9 @@ namespace Game
case ConditionSourceType.Phase:
valid = AddToPhases(cond);
break;
case ConditionSourceType.Graveyard:
valid = AddToGraveyardData(cond);
break;
case ConditionSourceType.AreaTrigger:
areaTriggerConditionContainerStorage.Add(Tuple.Create(cond.SourceGroup, cond.SourceEntry != 0), cond);
++count;
@@ -807,6 +811,19 @@ namespace Game
return false;
}
bool AddToGraveyardData(Condition cond)
{
GraveyardData graveyard = Global.ObjectMgr.FindGraveyardData((uint)cond.SourceEntry, cond.SourceGroup);
if (graveyard != null)
{
graveyard.Conditions.Add(cond);
return true;
}
Log.outError(LogFilter.Sql, $"{cond}, Graveyard {cond.SourceEntry} does not have ghostzone {cond.SourceGroup}.");
return false;
}
bool IsSourceTypeValid(Condition cond)
{
switch (cond.SourceType)
@@ -1176,9 +1193,9 @@ namespace Game
case ConditionSourceType.SmartEvent:
break;
case ConditionSourceType.Graveyard:
if (Global.ObjectMgr.GetWorldSafeLoc((uint)cond.SourceEntry) == null)
if (Global.ObjectMgr.FindGraveyardData((uint)cond.SourceEntry, cond.SourceGroup) == null)
{
Log.outError(LogFilter.Sql, $"{cond.ToString()} SourceEntry in `condition` table, does not exist in WorldSafeLocs.db2, ignoring.");
Log.outError(LogFilter.Sql, $"{cond.ToString()} SourceEntry in `condition` table, does not exist in `graveyard_zone`, ignoring.");
return false;
}
break;
+1 -1
View File
@@ -632,7 +632,7 @@ namespace Game.Entities
if (!ok)
{
WorldSafeLocsEntry loc = Global.ObjectMgr.GetDefaultGraveYard(GetTeam());
WorldSafeLocsEntry loc = Global.ObjectMgr.GetDefaultGraveyard(GetTeam());
if (loc == null && GetRace() == Race.PandarenNeutral)
loc = Global.ObjectMgr.GetWorldSafeLoc(3295); // The Wandering Isle, Starting Area GY
+1 -1
View File
@@ -562,7 +562,7 @@ namespace Game.Entities
// If map is dungeon find linked graveyard
if (GetMap().IsDungeon())
{
WorldSafeLocsEntry entry = Global.ObjectMgr.GetClosestGraveYard(this, GetTeam(), this);
WorldSafeLocsEntry entry = Global.ObjectMgr.GetClosestGraveyard(this, GetTeam(), this);
if (entry != null)
m_bgData.joinPos = entry.Loc;
else
+3 -3
View File
@@ -4211,14 +4211,14 @@ namespace Game.Entities
// Special handle for Battlegroundmaps
Battleground bg = GetBattleground();
if (bg)
ClosestGrave = bg.GetClosestGraveYard(this);
ClosestGrave = bg.GetClosestGraveyard(this);
else
{
BattleField bf = BattleFieldMgr.GetBattlefieldToZoneId(GetMap(), GetZoneId());
if (bf != null)
ClosestGrave = bf.GetClosestGraveYard(this);
ClosestGrave = bf.GetClosestGraveyard(this);
else
ClosestGrave = ObjectMgr.GetClosestGraveYard(this, GetTeam(), this);
ClosestGrave = ObjectMgr.GetClosestGraveyard(this, GetTeam(), this);
}
// stop countdown until repop
+72 -85
View File
@@ -754,10 +754,10 @@ namespace Game
{
uint oldMSTime = Time.GetMSTime();
GraveYardStorage.Clear(); // need for reload case
GraveyardStorage.Clear(); // need for reload case
// 0 1 2
SQLResult result = DB.World.Query("SELECT ID, GhostZone, faction FROM graveyard_zone");
// 0 1
SQLResult result = DB.World.Query("SELECT ID, GhostZone FROM graveyard_zone");
if (result.IsEmpty())
{
@@ -769,10 +769,8 @@ namespace Game
do
{
++count;
uint safeLocId = result.Read<uint>(0);
uint zoneId = result.Read<uint>(1);
Team team = (Team)result.Read<uint>(2);
WorldSafeLocsEntry entry = GetWorldSafeLoc(safeLocId);
if (entry == null)
@@ -788,18 +786,15 @@ namespace Game
continue;
}
if (team != 0 && team != Team.Horde && team != Team.Alliance)
{
Log.outError(LogFilter.Sql, "Table `graveyard_zone` has a record for non player faction ({0}), skipped.", team);
continue;
}
if (!AddGraveYardLink(safeLocId, zoneId, team, false))
if (!AddGraveyardLink(safeLocId, zoneId, 0, false))
Log.outError(LogFilter.Sql, "Table `graveyard_zone` has a duplicate record for Graveyard (ID: {0}) and Zone (ID: {1}), skipped.", safeLocId, zoneId);
++count;
} while (result.NextRow());
Log.outInfo(LogFilter.ServerLoading, "Loaded {0} graveyard-zone links in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
}
public void LoadWorldSafeLocs()
{
uint oldMSTime = Time.GetMSTime();
@@ -831,7 +826,7 @@ namespace Game
Log.outInfo(LogFilter.ServerLoading, $"Loaded {_worldSafeLocs.Count} world locations {Time.GetMSTimeDiffToNow(oldMSTime)} ms");
}
public WorldSafeLocsEntry GetDefaultGraveYard(Team team)
public WorldSafeLocsEntry GetDefaultGraveyard(Team team)
{
if (team == Team.Horde)
return GetWorldSafeLoc(10);
@@ -840,7 +835,7 @@ namespace Game
else return null;
}
public WorldSafeLocsEntry GetClosestGraveYard(WorldLocation location, Team team, WorldObject conditionObject)
public WorldSafeLocsEntry GetClosestGraveyard(WorldLocation location, Team team, WorldObject conditionObject)
{
float x, y, z;
location.GetPosition(out x, out y, out z);
@@ -853,7 +848,7 @@ namespace Game
if (z > -500)
{
Log.outError(LogFilter.Server, "ZoneId not found for map {0} coords ({1}, {2}, {3})", MapId, x, y, z);
return GetDefaultGraveYard(team);
return GetDefaultGraveyard(team);
}
}
@@ -884,7 +879,7 @@ namespace Game
// then check faction
// if mapId != graveyard.mapId (ghost in instance) and search any graveyard associated
// then check faction
var range = GraveYardStorage.LookupByKey(zoneId);
var range = GraveyardStorage.LookupByKey(zoneId);
MapRecord mapEntry = CliDB.MapStorage.LookupByKey(MapId);
ConditionSourceInfo conditionSource = new(conditionObject);
@@ -894,7 +889,7 @@ namespace Game
{
if (zoneId != 0) // zone == 0 can't be fixed, used by bliz for bugged zones
Log.outError(LogFilter.Sql, "Table `game_graveyard_zone` incomplete: Zone {0} Team {1} does not have a linked graveyard.", zoneId, team);
return GetDefaultGraveYard(team);
return GetDefaultGraveyard(team);
}
// at corpse map
@@ -912,26 +907,38 @@ namespace Game
foreach (var data in range)
{
WorldSafeLocsEntry entry = GetWorldSafeLoc(data.safeLocId);
WorldSafeLocsEntry entry = GetWorldSafeLoc(data.SafeLocId);
if (entry == null)
{
Log.outError(LogFilter.Sql, "Table `game_graveyard_zone` has record for not existing graveyard (WorldSafeLocs.dbc id) {0}, skipped.", data.safeLocId);
Log.outError(LogFilter.Sql, "Table `game_graveyard_zone` has record for not existing graveyard (WorldSafeLocs.dbc id) {0}, skipped.", data.SafeLocId);
continue;
}
// skip enemy faction graveyard
// team == 0 case can be at call from .neargrave
if (data.team != 0 && team != 0 && data.team != (uint)team)
continue;
if (conditionObject)
{
if (!Global.ConditionMgr.IsObjectMeetingNotGroupedConditions(ConditionSourceType.Graveyard, data.safeLocId, conditionSource))
if (!Global.ConditionMgr.IsObjectMeetToConditions(conditionSource, data.Conditions))
continue;
if (entry.Loc.GetMapId() == mapEntry.ParentMapID && !conditionObject.GetPhaseShift().HasVisibleMapId(entry.Loc.GetMapId()))
continue;
}
else if (team != 0)
{
bool teamConditionMet = true;
foreach (Condition cond in data.Conditions)
{
if (cond.ConditionType != ConditionTypes.Team)
continue;
if (cond.ConditionValue1 == (uint)team)
continue;
teamConditionMet = false;
}
if (!teamConditionMet)
continue;
}
// find now nearest graveyard at other map
if (MapId != entry.Loc.GetMapId() && entry.Loc.GetMapId() != mapEntry.ParentMapID)
@@ -995,12 +1002,12 @@ namespace Game
return entryFar;
}
public GraveYardData FindGraveYardData(uint id, uint zoneId)
public GraveyardData FindGraveyardData(uint id, uint zoneId)
{
var range = GraveYardStorage.LookupByKey(zoneId);
var range = GraveyardStorage.LookupByKey(zoneId);
foreach (var data in range)
{
if (data.safeLocId == id)
if (data.SafeLocId == id)
return data;
}
return null;
@@ -1010,22 +1017,22 @@ namespace Game
{
return _worldSafeLocs.LookupByKey(id);
}
public Dictionary<uint, WorldSafeLocsEntry> GetWorldSafeLocs()
{
return _worldSafeLocs;
}
public bool AddGraveYardLink(uint id, uint zoneId, Team team, bool persist = true)
public bool AddGraveyardLink(uint id, uint zoneId, Team team, bool persist = true)
{
if (FindGraveYardData(id, zoneId) != null)
if (FindGraveyardData(id, zoneId) != null)
return false;
// add link to loaded data
GraveYardData data = new();
data.safeLocId = id;
data.team = (uint)team;
GraveyardData data = new();
data.SafeLocId = id;
GraveYardStorage.Add(zoneId, data);
GraveyardStorage.Add(zoneId, data);
// add link to DB
if (persist)
@@ -1034,59 +1041,39 @@ namespace Game
stmt.AddValue(0, id);
stmt.AddValue(1, zoneId);
stmt.AddValue(2, (uint)team);
DB.World.Execute(stmt);
// Store graveyard condition if team is set
if (team != 0)
{
PreparedStatement conditionStmt = WorldDatabase.GetPreparedStatement(WorldStatements.INS_CONDITION);
conditionStmt.AddValue(0, (uint)ConditionSourceType.Graveyard); // SourceTypeOrReferenceId
conditionStmt.AddValue(1, zoneId); // SourceGroup
conditionStmt.AddValue(2, id); // SourceEntry
conditionStmt.AddValue(3, 0); // SourceId
conditionStmt.AddValue(4, 0); // ElseGroup
conditionStmt.AddValue(5, (uint)ConditionTypes.Team); // ConditionTypeOrReference
conditionStmt.AddValue(6, 0); // ConditionTarget
conditionStmt.AddValue(7, (uint)team); // ConditionValue1
conditionStmt.AddValue(8, 0); // ConditionValue2
conditionStmt.AddValue(9, 0); // ConditionValue3
conditionStmt.AddValue(10, 0); // NegativeCondition
conditionStmt.AddValue(11, 0); // ErrorType
conditionStmt.AddValue(12, 0); // ErrorTextId
conditionStmt.AddValue(13, ""); // ScriptName
conditionStmt.AddValue(14, ""); // Comment
DB.World.Execute(conditionStmt);
// reload conditions to make sure everything is loaded as it should be
Global.ConditionMgr.LoadConditions(true);
//Global.ScriptMgr.NotifyScriptIDUpdate();
}
}
return true;
}
public void RemoveGraveYardLink(uint id, uint zoneId, Team team, bool persist = false)
{
var range = GraveYardStorage.LookupByKey(zoneId);
if (range.Empty())
{
Log.outError(LogFilter.Sql, "Table `game_graveyard_zone` incomplete: Zone {0} Team {1} does not have a linked graveyard.", zoneId, team);
return;
}
bool found = false;
foreach (var data in range)
{
// skip not matching safezone id
if (data.safeLocId != id)
continue;
// skip enemy faction graveyard at same map (normal area, city, or Battleground)
// team == 0 case can be at call from .neargrave
if (data.team != 0 && team != 0 && data.team != (uint)team)
continue;
found = true;
break;
}
// no match, return
if (!found)
return;
// remove from links
GraveYardStorage.Remove(zoneId);
// remove link from DB
if (persist)
{
PreparedStatement stmt = WorldDatabase.GetPreparedStatement(WorldStatements.DEL_GRAVEYARD_ZONE);
stmt.AddValue(0, id);
stmt.AddValue(1, zoneId);
stmt.AddValue(2, (uint)team);
DB.World.Execute(stmt);
}
}
//Scripts
public void LoadAreaTriggerScripts()
@@ -10893,7 +10880,7 @@ namespace Game
Dictionary<(uint mapId, Difficulty difficulty), Dictionary<uint, CellObjectGuids>> mapObjectGuidsStore = new();
Dictionary<(uint mapId, Difficulty diffuculty, uint phaseId), Dictionary<uint, CellObjectGuids>> mapPersonalObjectGuidsStore = new();
Dictionary<uint, InstanceTemplate> instanceTemplateStorage = new();
public MultiMap<uint, GraveYardData> GraveYardStorage = new();
public MultiMap<uint, GraveyardData> GraveyardStorage = new();
List<ushort> _transportMaps = new();
Dictionary<uint, SpawnGroupTemplateData> _spawnGroupDataStorage = new();
MultiMap<uint, SpawnMetadata> _spawnGroupMapStorage = new();
@@ -11402,10 +11389,10 @@ namespace Game
public WorldLocation Loc;
}
public class GraveYardData
public class GraveyardData
{
public uint safeLocId;
public uint team;
public uint SafeLocId;
public List<Condition> Conditions;
}
public class QuestPOIBlobData
+7 -3
View File
@@ -5,6 +5,7 @@ using Framework.Collections;
using Framework.Constants;
using Framework.Database;
using Game.Cache;
using Game.Conditions;
using Game.DataStorage;
using Game.Entities;
using Game.Groups;
@@ -2403,13 +2404,16 @@ namespace Game
uint team = (uint)GetPlayer().GetTeam();
List<uint> graveyardIds = new();
var range = Global.ObjectMgr.GraveYardStorage.LookupByKey(zoneId);
var range = Global.ObjectMgr.GraveyardStorage.LookupByKey(zoneId);
for (uint i = 0; i < range.Count && graveyardIds.Count < 16; ++i) // client max
{
var gYard = range[(int)i];
if (gYard.team == 0 || gYard.team == team)
graveyardIds.Add(i);
ConditionSourceInfo conditionSource = new(_player);
if (!Global.ConditionMgr.IsObjectMeetToConditions(conditionSource, gYard.Conditions))
continue;
graveyardIds.Add(i);
}
if (graveyardIds.Empty())
+2 -2
View File
@@ -260,7 +260,7 @@ namespace Game
WorldLocation corpseLocation = GetPlayer().GetCorpseLocation();
if (GetPlayer().HasCorpse())
{
corpseGrave = Global.ObjectMgr.GetClosestGraveYard(corpseLocation, GetPlayer().GetTeam(), GetPlayer());
corpseGrave = Global.ObjectMgr.GetClosestGraveyard(corpseLocation, GetPlayer().GetTeam(), GetPlayer());
}
// now can spawn bones
@@ -269,7 +269,7 @@ namespace Game
// teleport to nearest from corpse graveyard, if different from nearest to player ghost
if (corpseGrave != null)
{
WorldSafeLocsEntry ghostGrave = Global.ObjectMgr.GetClosestGraveYard(GetPlayer(), GetPlayer().GetTeam(), GetPlayer());
WorldSafeLocsEntry ghostGrave = Global.ObjectMgr.GetClosestGraveyard(GetPlayer(), GetPlayer().GetTeam(), GetPlayer());
if (corpseGrave != ghostGrave)
GetPlayer().TeleportTo(corpseGrave.Loc);