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())
return;
if (IsPlayer())
if (!IsCreature() && !IsGameObject() && !IsDynamicObject())
return;
if (IsVisibilityOverridden())
{
if (IsFarVisible())
GetMap()->RemoveWorldObjectFromFarVisibleMap(this);
else if (IsZoneWideVisible())
GetMap()->RemoveWorldObjectFromZoneWideVisibleMap(GetZoneId(), this);
}
if (type == VisibilityDistanceType::Large || type == VisibilityDistanceType::Gigantic)
GetMap()->AddWorldObjectToFarVisibleMap(this);
else if (type == VisibilityDistanceType::Infinite)
GetMap()->AddWorldObjectToZoneWideVisibleMap(GetZoneId(), this);
// 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())
GetMap()->RemoveWorldObjectFromFarVisibleMap(this);
else if (IsZoneWideVisible())
GetMap()->RemoveWorldObjectFromZoneWideVisibleMap(_zoneId, this);
}
void WorldObject::AddToMapVisibilityOverrideContainers()
{
if (!IsVisibilityOverridden())
return;
if (!IsInWorld())
return;
if (IsFarVisible())
GetMap()->AddWorldObjectToFarVisibleMap(this);
else if (IsZoneWideVisible())
GetMap()->AddWorldObjectToZoneWideVisibleMap(_zoneId, this);
}
void WorldObject::CleanupsBeforeDelete(bool /*finalCleanup*/)
@@ -1177,6 +1199,9 @@ void WorldObject::AddToWorld()
Object::AddToWorld();
GetMap()->GetZoneAndAreaId(GetPhaseMask(), _zoneId, _areaId, GetPositionX(), GetPositionY(), GetPositionZ());
GetMap()->AddObjectToPendingUpdateList(this);
if (IsZoneWideVisible())
GetMap()->AddWorldObjectToZoneWideVisibleMap(_zoneId, this);
}
void WorldObject::RemoveFromWorld()
@@ -1184,8 +1209,7 @@ void WorldObject::RemoveFromWorld()
if (!IsInWorld())
return;
if (IsZoneWideVisible())
GetMap()->RemoveWorldObjectFromZoneWideVisibleMap(GetZoneId(), this);
RemoveFromMapVisibilityOverrideContainers();
DestroyForVisiblePlayers();

View File

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

View File

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