feat(Core/Visibility): Far visibility worldobjects (#22828)
This commit is contained in:
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user