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
@@ -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