feat(Core/Visibility): Far visibility worldobjects (#22828)

This commit is contained in:
Takenbacon
2025-09-07 04:02:03 -07:00
committed by GitHub
parent d55851c513
commit a28824df85
22 changed files with 461 additions and 156 deletions
+2
View File
@@ -106,6 +106,8 @@ struct Cell
template<class T> static void VisitObjects(WorldObject const* obj, T& visitor, float radius);
template<class T> static void VisitObjects(float x, float y, Map* map, T& visitor, float radius);
template<class T> static void VisitFarVisibleObjects(WorldObject const* obj, T& visitor, float radius);
private:
template<class T, class CONTAINER> void VisitCircle(TypeContainerVisitor<T, CONTAINER>&, Map&, CellCoord const&, CellCoord const&) const;
};
+10
View File
@@ -181,4 +181,14 @@ inline void Cell::VisitObjects(float x, float y, Map* map, T& visitor, float rad
cell.Visit(p, gnotifier, *map, x, y, radius);
}
template<class T>
inline void Cell::VisitFarVisibleObjects(WorldObject const* center_obj, T& visitor, float radius)
{
CellCoord p(Acore::ComputeCellCoord(center_obj->GetPositionX(), center_obj->GetPositionY()));
Cell cell(p);
TypeContainerVisitor<T, FarVisibleGridContainer> gnotifier(visitor);
cell.Visit(p, gnotifier, *center_obj->GetMap(), *center_obj, radius);
}
#endif
+27 -3
View File
@@ -33,16 +33,20 @@
#include "TypeContainer.h"
#include "TypeContainerVisitor.h"
class WorldObject;
template
<
class GRID_OBJECT_TYPES
class GRID_OBJECT_TYPES,
class FAR_VISIBLE_OBJECT_TYPES
>
class GridCell
{
public:
~GridCell() = default;
template<class SPECIFIC_OBJECT> void AddGridObject(SPECIFIC_OBJECT* obj)
template<class SPECIFIC_OBJECT>
void AddGridObject(SPECIFIC_OBJECT* obj)
{
_gridObjects.template insert<SPECIFIC_OBJECT>(obj);
ASSERT(obj->IsInGrid());
@@ -50,12 +54,32 @@ public:
// Visit grid objects
template<class T>
void Visit(TypeContainerVisitor<T, TypeMapContainer<GRID_OBJECT_TYPES> >& visitor)
void Visit(TypeContainerVisitor<T, TypeMapContainer<GRID_OBJECT_TYPES>>& visitor)
{
visitor.Visit(_gridObjects);
}
template<class SPECIFIC_OBJECT>
void AddFarVisibleObject(SPECIFIC_OBJECT* obj)
{
_farVisibleObjects.template Insert<SPECIFIC_OBJECT>(obj);
}
template<class SPECIFIC_OBJECT>
void RemoveFarVisibleObject(SPECIFIC_OBJECT* obj)
{
_farVisibleObjects.template Remove<SPECIFIC_OBJECT>(obj);
}
// Visit far objects
template<class T>
void Visit(TypeContainerVisitor<T, TypeVectorContainer<FAR_VISIBLE_OBJECT_TYPES>>& visitor)
{
visitor.Visit(_farVisibleObjects);
}
private:
TypeMapContainer<GRID_OBJECT_TYPES> _gridObjects;
TypeVectorContainer<FAR_VISIBLE_OBJECT_TYPES> _farVisibleObjects;
};
#endif
+6 -2
View File
@@ -57,6 +57,9 @@ typedef TYPELIST_5(GameObject, Player, Creature, Corpse, DynamicObject) AllMapGr
// List of object types stored on map level
typedef TYPELIST_4(Creature, GameObject, DynamicObject, Corpse) AllMapStoredObjectTypes;
// List of object types that can have far visible range
typedef TYPELIST_2(Creature, GameObject) AllFarVisibleObjectTypes;
typedef GridRefMgr<Corpse> CorpseMapType;
typedef GridRefMgr<Creature> CreatureMapType;
typedef GridRefMgr<DynamicObject> DynamicObjectMapType;
@@ -73,10 +76,11 @@ enum GridMapTypeMask
GRID_MAP_TYPE_MASK_ALL = 0x1F
};
typedef GridCell<AllMapGridStoredObjectTypes> GridCellType;
typedef MapGrid<AllMapGridStoredObjectTypes> MapGridType;
typedef GridCell<AllMapGridStoredObjectTypes, AllFarVisibleObjectTypes> GridCellType;
typedef MapGrid<AllMapGridStoredObjectTypes, AllFarVisibleObjectTypes> MapGridType;
typedef TypeMapContainer<AllMapGridStoredObjectTypes> GridTypeMapContainer;
typedef TypeVectorContainer<AllFarVisibleObjectTypes> FarVisibleGridContainer;
typedef TypeUnorderedMapContainer<AllMapStoredObjectTypes, ObjectGuid> MapStoredObjectTypesContainer;
template<uint32 LIMIT>
+17 -6
View File
@@ -25,12 +25,13 @@ class GridTerrainData;
template
<
class GRID_OBJECT_TYPES
class GRID_OBJECT_TYPES,
class FAR_VISIBLE_OBJECT_TYPES
>
class MapGrid
{
public:
typedef GridCell<GRID_OBJECT_TYPES> GridCellType;
typedef GridCell<GRID_OBJECT_TYPES, FAR_VISIBLE_OBJECT_TYPES> GridCellType;
MapGrid(uint16 const x, uint16 const y)
: _x(x), _y(y), _objectDataLoaded(false), _terrainData(nullptr) { }
@@ -54,9 +55,19 @@ public:
GetOrCreateCell(x, y).RemoveGridObject(obj);
}
template<class SPECIFIC_OBJECT> void AddFarVisibleObject(uint16 const x, uint16 const y, SPECIFIC_OBJECT* obj)
{
GetOrCreateCell(x, y).AddFarVisibleObject(obj);
}
template<class SPECIFIC_OBJECT> void RemoveFarVisibleObject(uint16 const x, uint16 const y, SPECIFIC_OBJECT* obj)
{
GetOrCreateCell(x, y).RemoveFarVisibleObject(obj);
}
// Visit all cells
template<class T, class TT>
void VisitAllCells(TypeContainerVisitor<T, TypeMapContainer<TT> >& visitor)
void VisitAllCells(TypeContainerVisitor<T, TT>& visitor)
{
for (auto& cellX : _cells)
{
@@ -72,7 +83,7 @@ public:
// Visit single cell
template<class T, class TT>
void VisitCell(uint16 const x, uint16 const y, TypeContainerVisitor<T, TypeMapContainer<TT> >& visitor)
void VisitCell(uint16 const x, uint16 const y, TypeContainerVisitor<T, TT>& visitor)
{
GridCellType* gridCell = GetCell(x, y);
if (!gridCell)
@@ -81,7 +92,7 @@ public:
gridCell->Visit(visitor);
}
void link(GridRefMgr<MapGrid<GRID_OBJECT_TYPES>>* pTo)
void link(GridRefMgr<MapGrid<GRID_OBJECT_TYPES, FAR_VISIBLE_OBJECT_TYPES>>* pTo)
{
_gridReference.link(pTo, this);
}
@@ -134,7 +145,7 @@ private:
bool _objectDataLoaded;
std::array<std::array<std::unique_ptr<GridCellType>, MAX_NUMBER_OF_CELLS>, MAX_NUMBER_OF_CELLS> _cells; // N * N array
GridReference<MapGrid<GRID_OBJECT_TYPES>> _gridReference;
GridReference<MapGrid<GRID_OBJECT_TYPES, FAR_VISIBLE_OBJECT_TYPES>> _gridReference;
// Instances will share a copy of the parent maps terrainData
std::shared_ptr<GridTerrainData> _terrainData;
@@ -29,38 +29,31 @@ void VisibleNotifier::Visit(GameObjectMapType& m)
for (GameObjectMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
{
GameObject* go = iter->GetSource();
if (i_largeOnly != go->IsVisibilityOverridden())
continue;
i_player.UpdateVisibilityOf(go, i_data, i_visibleNow);
}
}
void VisibleNotifier::SendToSelf()
{
// at this moment i_clientGUIDs have guids that not iterate at grid level checks
// but exist one case when this possible and object not out of range: transports
if (Transport* transport = i_player.GetTransport())
// Update far visible objects
ZoneWideVisibleWorldObjectsSet const* zoneWideVisibleObjects = i_player.GetMap()->GetZoneWideVisibleWorldObjectsForZone(i_player.GetZoneId());
if (zoneWideVisibleObjects)
{
for (Transport::PassengerSet::const_iterator itr = transport->GetPassengers().begin(); itr != transport->GetPassengers().end(); ++itr)
for (WorldObject* obj : *zoneWideVisibleObjects)
{
if (i_largeOnly != (*itr)->IsVisibilityOverridden())
continue;
switch ((*itr)->GetTypeId())
switch (obj->GetTypeId())
{
case TYPEID_GAMEOBJECT:
i_player.UpdateVisibilityOf((*itr)->ToGameObject(), i_data, i_visibleNow);
break;
case TYPEID_PLAYER:
i_player.UpdateVisibilityOf((*itr)->ToPlayer(), i_data, i_visibleNow);
(*itr)->ToPlayer()->UpdateVisibilityOf(&i_player);
break;
case TYPEID_UNIT:
i_player.UpdateVisibilityOf((*itr)->ToCreature(), i_data, i_visibleNow);
break;
default:
break;
case TYPEID_GAMEOBJECT:
i_player.UpdateVisibilityOf(obj->ToGameObject(), i_data, i_visibleNow);
break;
case TYPEID_UNIT:
i_player.UpdateVisibilityOf(obj->ToCreature(), i_data, i_visibleNow);
break;
case TYPEID_DYNAMICOBJECT:
i_player.UpdateVisibilityOf(obj->ToDynObject(), i_data, i_visibleNow);
break;
default:
break;
}
}
}
@@ -69,26 +62,7 @@ void VisibleNotifier::SendToSelf()
for (VisibleWorldObjectsMap::iterator itr = visibleWorldObjects->begin(); itr != visibleWorldObjects->end();)
{
WorldObject* obj = itr->second;
if (i_largeOnly != obj->IsVisibilityOverridden())
{
++itr;
continue;
}
// pussywizard: static transports are removed only in RemovePlayerFromMap and here if can no longer detect (eg. phase changed)
if (itr->first.IsTransport())
{
if (GameObject* staticTrans = obj->ToGameObject())
{
if (i_player.CanSeeOrDetect(staticTrans, false, true))
{
++itr;
continue;
}
}
}
if (i_player.m_seer->IsWithinDist(obj, i_player.GetSightRange(obj), true))
if (!i_player.IsWorldObjectOutOfSightRange(obj))
{
++itr;
continue;
@@ -111,12 +85,7 @@ void VisibleNotifier::SendToSelf()
i_player.GetSession()->SendPacket(&packet);
for (std::vector<Unit*>::const_iterator it = i_visibleNow.begin(); it != i_visibleNow.end(); ++it)
{
if (i_largeOnly != (*it)->IsVisibilityOverridden())
continue;
i_player.GetInitialVisiblePackets(*it);
}
}
void VisibleChangesNotifier::Visit(PlayerMapType& m)
@@ -45,16 +45,16 @@ namespace Acore
Player& i_player;
std::vector<Unit*>& i_visibleNow;
bool i_gobjOnly;
bool i_largeOnly;
UpdateData i_data;
VisibleNotifier(Player& player, bool gobjOnly, bool largeOnly) :
i_player(player), i_visibleNow(player.m_newVisible), i_gobjOnly(gobjOnly), i_largeOnly(largeOnly)
VisibleNotifier(Player& player, bool gobjOnly) :
i_player(player), i_visibleNow(player.m_newVisible), i_gobjOnly(gobjOnly)
{
i_visibleNow.clear();
}
void Visit(GameObjectMapType&);
template<class T> void Visit(std::vector<T>& m);
template<class T> void Visit(GridRefMgr<T>& m);
void SendToSelf(void);
};
@@ -72,8 +72,9 @@ namespace Acore
struct PlayerRelocationNotifier : public VisibleNotifier
{
PlayerRelocationNotifier(Player& player, bool largeOnly): VisibleNotifier(player, false, largeOnly) { }
PlayerRelocationNotifier(Player& player): VisibleNotifier(player, false) { }
template<class T> void Visit(std::vector<T>& m) { VisibleNotifier::Visit(m); }
template<class T> void Visit(GridRefMgr<T>& m) { VisibleNotifier::Visit(m); }
void Visit(PlayerMapType&);
};
@@ -25,6 +25,13 @@
#include "WorldPacket.h"
#include "WorldSession.h"
template<class T>
inline void Acore::VisibleNotifier::Visit(std::vector<T>& m)
{
for (typename std::vector<T>::iterator iter = m.begin(); iter != m.end(); ++iter)
i_player.UpdateVisibilityOf((*iter), i_data, i_visibleNow);
}
template<class T>
inline void Acore::VisibleNotifier::Visit(GridRefMgr<T>& m)
{
@@ -33,12 +40,7 @@ inline void Acore::VisibleNotifier::Visit(GridRefMgr<T>& m)
return;
for (typename GridRefMgr<T>::iterator iter = m.begin(); iter != m.end(); ++iter)
{
if (i_largeOnly != iter->GetSource()->IsVisibilityOverridden())
continue;
i_player.UpdateVisibilityOf(iter->GetSource(), i_data, i_visibleNow);
}
}
// SEARCHERS & LIST SEARCHERS & WORKERS