fix(Core/Object): Improve safety of visibility override containers (#23219)

This commit is contained in:
Takenbacon
2025-10-13 08:36:42 -07:00
committed by GitHub
parent 9ff1d3f06a
commit 5aa3161885
3 changed files with 42 additions and 17 deletions

View File

@@ -1095,23 +1095,45 @@ void WorldObject::SetVisibilityDistanceOverride(VisibilityDistanceType type)
if (type == GetVisibilityOverrideType()) if (type == GetVisibilityOverrideType())
return; return;
if (IsPlayer()) if (!IsCreature() && !IsGameObject() && !IsDynamicObject())
return; return;
if (IsVisibilityOverridden()) // Important to remove from old visibility override containers first
RemoveFromMapVisibilityOverrideContainers();
// Always update _visibilityDistanceOverrideType, even when not in world
_visibilityDistanceOverrideType = type;
// Finally, add to new visibility override containers
AddToMapVisibilityOverrideContainers();
}
void WorldObject::RemoveFromMapVisibilityOverrideContainers()
{ {
if (!IsVisibilityOverridden())
return;
if (!IsInWorld())
return;
if (IsFarVisible()) if (IsFarVisible())
GetMap()->RemoveWorldObjectFromFarVisibleMap(this); GetMap()->RemoveWorldObjectFromFarVisibleMap(this);
else if (IsZoneWideVisible()) else if (IsZoneWideVisible())
GetMap()->RemoveWorldObjectFromZoneWideVisibleMap(GetZoneId(), this); GetMap()->RemoveWorldObjectFromZoneWideVisibleMap(_zoneId, this);
} }
if (type == VisibilityDistanceType::Large || type == VisibilityDistanceType::Gigantic) void WorldObject::AddToMapVisibilityOverrideContainers()
GetMap()->AddWorldObjectToFarVisibleMap(this); {
else if (type == VisibilityDistanceType::Infinite) if (!IsVisibilityOverridden())
GetMap()->AddWorldObjectToZoneWideVisibleMap(GetZoneId(), this); return;
_visibilityDistanceOverrideType = type; if (!IsInWorld())
return;
if (IsFarVisible())
GetMap()->AddWorldObjectToFarVisibleMap(this);
else if (IsZoneWideVisible())
GetMap()->AddWorldObjectToZoneWideVisibleMap(_zoneId, this);
} }
void WorldObject::CleanupsBeforeDelete(bool /*finalCleanup*/) void WorldObject::CleanupsBeforeDelete(bool /*finalCleanup*/)
@@ -1177,6 +1199,9 @@ void WorldObject::AddToWorld()
Object::AddToWorld(); Object::AddToWorld();
GetMap()->GetZoneAndAreaId(GetPhaseMask(), _zoneId, _areaId, GetPositionX(), GetPositionY(), GetPositionZ()); GetMap()->GetZoneAndAreaId(GetPhaseMask(), _zoneId, _areaId, GetPositionX(), GetPositionY(), GetPositionZ());
GetMap()->AddObjectToPendingUpdateList(this); GetMap()->AddObjectToPendingUpdateList(this);
if (IsZoneWideVisible())
GetMap()->AddWorldObjectToZoneWideVisibleMap(_zoneId, this);
} }
void WorldObject::RemoveFromWorld() void WorldObject::RemoveFromWorld()
@@ -1184,8 +1209,7 @@ void WorldObject::RemoveFromWorld()
if (!IsInWorld()) if (!IsInWorld())
return; return;
if (IsZoneWideVisible()) RemoveFromMapVisibilityOverrideContainers();
GetMap()->RemoveWorldObjectFromZoneWideVisibleMap(GetZoneId(), this);
DestroyForVisiblePlayers(); DestroyForVisiblePlayers();

View File

@@ -780,6 +780,9 @@ private:
//bool CanDetectStealthOf(WorldObject const* obj) const; //bool CanDetectStealthOf(WorldObject const* obj) const;
bool CanDetectStealthOf(WorldObject const* obj, bool checkAlert = false) const; bool CanDetectStealthOf(WorldObject const* obj, bool checkAlert = false) const;
void RemoveFromMapVisibilityOverrideContainers();
void AddToMapVisibilityOverrideContainers();
GuidUnorderedSet _allowedLooters; GuidUnorderedSet _allowedLooters;
ObjectVisibilityContainer _objectVisibilityContainer; ObjectVisibilityContainer _objectVisibilityContainer;

View File

@@ -727,8 +727,6 @@ void Map::RemoveFromMap(T* obj, bool remove)
obj->RemoveFromWorld(); obj->RemoveFromWorld();
obj->RemoveFromGrid(); obj->RemoveFromGrid();
if (obj->IsFarVisible())
RemoveWorldObjectFromFarVisibleMap(obj);
obj->ResetMap(); obj->ResetMap();