Core/Objects: Properly choose between "Destroyed" or "OutOfRange" during visibility update

Port From (https://github.com/TrinityCore/TrinityCore/commit/5a82a0381d704e4b4b9976daf04d541d1130e541)
This commit is contained in:
hondacrx
2022-03-09 12:33:25 -05:00
parent 510a1a0208
commit e65a1e95cf
6 changed files with 31 additions and 10 deletions
@@ -1020,10 +1020,7 @@ namespace Game.Entities
public override bool IsNeverVisibleFor(WorldObject seer) public override bool IsNeverVisibleFor(WorldObject seer)
{ {
if (IsServerSide()) return base.IsNeverVisibleFor(seer) || IsServerSide();
return true;
return base.IsNeverVisibleFor(seer);
} }
[System.Diagnostics.Conditional("DEBUG")] [System.Diagnostics.Conditional("DEBUG")]
+16 -3
View File
@@ -211,7 +211,7 @@ namespace Game.Entities
data.AddUpdateBlock(buffer); data.AddUpdateBlock(buffer);
} }
void BuildDestroyUpdateBlock(UpdateData data) public void BuildDestroyUpdateBlock(UpdateData data)
{ {
data.AddDestroyObject(GetGUID()); data.AddDestroyObject(GetGUID());
} }
@@ -230,6 +230,16 @@ namespace Game.Entities
target.SendPacket(packet); target.SendPacket(packet);
} }
public void SendOutOfRangeForPlayer(Player target)
{
Cypher.Assert(target);
UpdateData updateData = new(target.GetMapId());
BuildOutOfRangeUpdateBlock(updateData);
updateData.BuildPacket(out UpdateObject packet);
target.SendPacket(packet);
}
public void BuildMovementUpdate(WorldPacket data, CreateObjectBits flags) public void BuildMovementUpdate(WorldPacket data, CreateObjectBits flags)
{ {
int PauseTimesCount = 0; int PauseTimesCount = 0;
@@ -2868,7 +2878,9 @@ namespace Game.Entities
public virtual bool HasQuest(uint questId) { return false; } public virtual bool HasQuest(uint questId) { return false; }
public virtual bool HasInvolvedQuest(uint questId) { return false; } public virtual bool HasInvolvedQuest(uint questId) { return false; }
public void SetIsNewObject(bool enable) { _isNewObject = enable; } public void SetIsNewObject(bool enable) { _isNewObject = enable; }
public bool IsDestroyedObject() { return _isDestroyedObject; }
public void SetDestroyedObject(bool destroyed) { _isDestroyedObject = destroyed; }
public bool IsCreature() { return GetTypeId() == TypeId.Unit; } public bool IsCreature() { return GetTypeId() == TypeId.Unit; }
public bool IsPlayer() { return GetTypeId() == TypeId.Player; } public bool IsPlayer() { return GetTypeId() == TypeId.Player; }
public bool IsGameObject() { return GetTypeId() == TypeId.GameObject; } public bool IsGameObject() { return GetTypeId() == TypeId.GameObject; }
@@ -2926,7 +2938,7 @@ namespace Game.Entities
public virtual float GetCollisionHeight() { return 0.0f; } public virtual float GetCollisionHeight() { return 0.0f; }
public float GetMidsectionHeight() { return GetCollisionHeight() / 2.0f; } public float GetMidsectionHeight() { return GetCollisionHeight() / 2.0f; }
public virtual bool IsNeverVisibleFor(WorldObject seer) { return !IsInWorld; } public virtual bool IsNeverVisibleFor(WorldObject seer) { return !IsInWorld || IsDestroyedObject(); }
public virtual bool IsAlwaysVisibleFor(WorldObject seer) { return false; } public virtual bool IsAlwaysVisibleFor(WorldObject seer) { return false; }
public virtual bool IsInvisibleDueToDespawn() { return false; } public virtual bool IsInvisibleDueToDespawn() { return false; }
public virtual bool IsAlwaysDetectableFor(WorldObject seer) { return false; } public virtual bool IsAlwaysDetectableFor(WorldObject seer) { return false; }
@@ -3558,6 +3570,7 @@ namespace Game.Entities
protected CreateObjectBits m_updateFlag; protected CreateObjectBits m_updateFlag;
ObjectGuid m_guid; ObjectGuid m_guid;
bool _isNewObject; bool _isNewObject;
bool _isDestroyedObject;
public UpdateFieldHolder m_values; public UpdateFieldHolder m_values;
public ObjectFieldData m_objectData; public ObjectFieldData m_objectData;
+10 -2
View File
@@ -6071,7 +6071,11 @@ namespace Game.Entities
if (target.IsTypeId(TypeId.Unit)) if (target.IsTypeId(TypeId.Unit))
BeforeVisibilityDestroy(target.ToCreature(), this); BeforeVisibilityDestroy(target.ToCreature(), this);
target.DestroyForPlayer(this); if (!target.IsDestroyedObject())
target.SendOutOfRangeForPlayer(this);
else
target.DestroyForPlayer(this);
m_clientGUIDs.Remove(target.GetGUID()); m_clientGUIDs.Remove(target.GetGUID());
} }
} }
@@ -6097,7 +6101,11 @@ namespace Game.Entities
{ {
BeforeVisibilityDestroy(target, this); BeforeVisibilityDestroy(target, this);
target.BuildOutOfRangeUpdateBlock(data); if (!target.IsDestroyedObject())
target.BuildOutOfRangeUpdateBlock(data);
else
target.BuildDestroyUpdateBlock(data);
m_clientGUIDs.Remove(target.GetGUID()); m_clientGUIDs.Remove(target.GetGUID());
} }
} }
+1
View File
@@ -2916,6 +2916,7 @@ namespace Game.Maps
{ {
Cypher.Assert(obj.GetMapId() == GetId() && obj.GetInstanceId() == GetInstanceId()); Cypher.Assert(obj.GetMapId() == GetId() && obj.GetInstanceId() == GetInstanceId());
obj.SetDestroyedObject(true);
obj.CleanupsBeforeDelete(false); // remove or simplify at least cross referenced links obj.CleanupsBeforeDelete(false); // remove or simplify at least cross referenced links
i_objectsToRemove.Add(obj); i_objectsToRemove.Add(obj);
+1
View File
@@ -286,6 +286,7 @@ namespace Game.Maps
if (obj.IsTypeId(TypeId.Player)) if (obj.IsTypeId(TypeId.Player))
continue; continue;
obj.SetDestroyedObject(true);
obj.CleanupsBeforeDelete(); obj.CleanupsBeforeDelete();
} }
} }
+2 -1
View File
@@ -209,7 +209,8 @@ namespace Game
// the player may not be in the world when logging out // the player may not be in the world when logging out
// e.g if he got disconnected during a transfer to another map // e.g if he got disconnected during a transfer to another map
// calls to GetMap in this case may cause crashes // calls to GetMap in this case may cause crashes
GetPlayer().CleanupsBeforeDelete(); _player.SetDestroyedObject(true);
_player.CleanupsBeforeDelete();
Log.outInfo(LogFilter.Player, $"Account: {GetAccountId()} (IP: {GetRemoteAddress()}) Logout Character:[{_player.GetName()}] ({_player.GetGUID()}) Level: {_player.GetLevel()}, XP: {_player.GetXP()}/{_player.GetXPForNextLevel()} ({_player.GetXPForNextLevel() - _player.GetXP()} left)"); Log.outInfo(LogFilter.Player, $"Account: {GetAccountId()} (IP: {GetRemoteAddress()}) Logout Character:[{_player.GetName()}] ({_player.GetGUID()}) Level: {_player.GetLevel()}, XP: {_player.GetXP()}/{_player.GetXPForNextLevel()} ({_player.GetXPForNextLevel() - _player.GetXP()} left)");
Map map = GetPlayer().GetMap(); Map map = GetPlayer().GetMap();