mirror of
https://github.com/araxiaonline/TrinityCore2.git
synced 2026-06-16 04:49:38 -04:00
Implement new visibility system, based on Silverice patch for mangos
--HG-- branch : trunk
This commit is contained in:
@@ -29,6 +29,92 @@
|
||||
|
||||
using namespace Trinity;
|
||||
|
||||
void
|
||||
Player2PlayerNotifier::Visit(PlayerMapType &m)
|
||||
{
|
||||
for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
|
||||
{
|
||||
Player* plr = iter->getSource();
|
||||
if(plr == &i_player)
|
||||
continue;
|
||||
|
||||
vis_guids.erase(plr->GetGUID());
|
||||
i_player.UpdateVisibilityOf(plr,i_data,i_visibleNow);
|
||||
|
||||
// force == true - update i_player visibility for all player in cell, ignore optimization flags.
|
||||
if(!force && (plr->NotifyExecuted(NOTIFY_PLAYER_VISIBILITY) || plr->isNeedNotify(NOTIFY_PLAYER_VISIBILITY)))
|
||||
continue;
|
||||
|
||||
plr->UpdateVisibilityOf(&i_player);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
VisibleNotifier::SendToSelf()
|
||||
{
|
||||
for(Player::ClientGUIDs::const_iterator it = vis_guids.begin();it != vis_guids.end();++it)
|
||||
{ //player guids processed in Player2PlayerNotifier
|
||||
if(IS_PLAYER_GUID(*it))
|
||||
continue;
|
||||
|
||||
i_player.m_clientGUIDs.erase(*it);
|
||||
i_data.AddOutOfRangeGUID(*it);
|
||||
}
|
||||
|
||||
if(!i_data.HasData())
|
||||
return;
|
||||
|
||||
WorldPacket packet;
|
||||
i_data.BuildPacket(&packet);
|
||||
i_player.GetSession()->SendPacket(&packet);
|
||||
|
||||
for(std::set<Unit*>::const_iterator it = i_visibleNow.begin(); it != i_visibleNow.end(); ++it)
|
||||
i_player.SendInitialVisiblePackets(*it);
|
||||
}
|
||||
|
||||
void
|
||||
Player2PlayerNotifier::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())
|
||||
for(Transport::PlayerSet::const_iterator itr = transport->GetPassengers().begin();itr!=transport->GetPassengers().end();++itr)
|
||||
{
|
||||
if(vis_guids.find((*itr)->GetGUID()) != vis_guids.end())
|
||||
{
|
||||
vis_guids.erase((*itr)->GetGUID());
|
||||
|
||||
i_player.UpdateVisibilityOf((*itr), i_data, i_visibleNow);
|
||||
|
||||
if(!(*itr)->isNeedNotify(NOTIFY_PLAYER_VISIBILITY))
|
||||
(*itr)->UpdateVisibilityOf(&i_player);
|
||||
}
|
||||
}
|
||||
|
||||
for(Player::ClientGUIDs::const_iterator it = vis_guids.begin();it != vis_guids.end(); ++it)
|
||||
{
|
||||
//since its player-player notifier we work only with player guids
|
||||
if(!IS_PLAYER_GUID(*it))
|
||||
continue;
|
||||
|
||||
i_player.m_clientGUIDs.erase(*it);
|
||||
i_data.AddOutOfRangeGUID(*it);
|
||||
Player* plr = ObjectAccessor::FindPlayer(*it);
|
||||
if(plr && plr->IsInWorld() && !plr->NotifyExecuted(NOTIFY_PLAYER_VISIBILITY) && !plr->isNeedNotify(NOTIFY_PLAYER_VISIBILITY))
|
||||
plr->UpdateVisibilityOf(&i_player);
|
||||
}
|
||||
|
||||
if(!i_data.HasData())
|
||||
return;
|
||||
|
||||
WorldPacket packet;
|
||||
i_data.BuildPacket(&packet);
|
||||
i_player.GetSession()->SendPacket(&packet);
|
||||
|
||||
for(std::set<Unit*>::const_iterator it = i_visibleNow.begin(); it != i_visibleNow.end(); ++it)
|
||||
i_player.SendInitialVisiblePackets(*it);
|
||||
}
|
||||
|
||||
void
|
||||
VisibleChangesNotifier::Visit(PlayerMapType &m)
|
||||
{
|
||||
@@ -71,74 +157,6 @@ VisibleChangesNotifier::Visit(DynamicObjectMapType &m)
|
||||
void
|
||||
PlayerVisibilityNotifier::Notify()
|
||||
{
|
||||
// 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())
|
||||
{
|
||||
for (Transport::PlayerSet::const_iterator itr = transport->GetPassengers().begin(); itr!=transport->GetPassengers().end(); ++itr)
|
||||
{
|
||||
if(i_clientGUIDs.find((*itr)->GetGUID())!=i_clientGUIDs.end())
|
||||
{
|
||||
(*itr)->UpdateVisibilityOf(&i_player);
|
||||
i_player.UpdateVisibilityOf((*itr),i_data,i_visibleNow);
|
||||
i_clientGUIDs.erase((*itr)->GetGUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// generate outOfRange for not iterate objects
|
||||
i_data.AddOutOfRangeGUID(i_clientGUIDs);
|
||||
for (Player::ClientGUIDs::iterator itr = i_clientGUIDs.begin(); itr!=i_clientGUIDs.end(); ++itr)
|
||||
{
|
||||
i_player.m_clientGUIDs.erase(*itr);
|
||||
|
||||
#ifdef TRINITY_DEBUG
|
||||
if((sLog.getLogFilter() & LOG_FILTER_VISIBILITY_CHANGES)==0)
|
||||
sLog.outDebug("Object %u (Type: %u) is out of range (no in active cells set) now for player %u",GUID_LOPART(*itr),GuidHigh2TypeId(GUID_HIPART(*itr)),i_player.GetGUIDLow());
|
||||
#endif
|
||||
}
|
||||
|
||||
if( i_data.HasData() )
|
||||
{
|
||||
/*uint32 entry = 0, map;
|
||||
float x,y;
|
||||
if(!i_visibleNow.empty())
|
||||
{
|
||||
entry = (*i_visibleNow.begin())->GetEntry();
|
||||
map = (*i_visibleNow.begin())->GetMapId();
|
||||
x = (*i_visibleNow.begin())->GetPositionX();
|
||||
y = (*i_visibleNow.begin())->GetPositionY();
|
||||
sLog.outError("notify %u %u %f %f", entry, map, x, y);
|
||||
}*/
|
||||
|
||||
// send create/outofrange packet to player (except player create updates that already sent using SendUpdateToPlayer)
|
||||
WorldPacket packet;
|
||||
i_data.BuildPacket(&packet);
|
||||
i_player.GetSession()->SendPacket(&packet);
|
||||
|
||||
// send out of range to other players if need
|
||||
std::set<uint64> const& oor = i_data.GetOutOfRangeGUIDs();
|
||||
for (std::set<uint64>::const_iterator iter = oor.begin(); iter != oor.end(); ++iter)
|
||||
{
|
||||
if(!IS_PLAYER_GUID(*iter))
|
||||
continue;
|
||||
|
||||
Player* plr = ObjectAccessor::GetPlayer(i_player,*iter);
|
||||
if(plr)
|
||||
plr->UpdateVisibilityOf(&i_player);
|
||||
}
|
||||
}
|
||||
|
||||
// Now do operations that required done at object visibility change to visible
|
||||
|
||||
// send data at target visibility change (adding to client)
|
||||
for (std::set<WorldObject*>::const_iterator vItr = i_visibleNow.begin(); vItr != i_visibleNow.end(); ++vItr)
|
||||
// target aura duration for caster show only if target exist at caster client
|
||||
if((*vItr)!=&i_player && (*vItr)->isType(TYPEMASK_UNIT))
|
||||
i_player.SendInitialVisiblePackets((Unit*)(*vItr));
|
||||
|
||||
if(i_visibleNow.size() >= 30)
|
||||
i_player.SetToNotify();
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -38,6 +38,35 @@ class Player;
|
||||
|
||||
namespace Trinity
|
||||
{
|
||||
struct MANGOS_DLL_DECL VisibleNotifier
|
||||
{
|
||||
bool force;
|
||||
Player &i_player;
|
||||
UpdateData i_data;
|
||||
std::set<Unit*> i_visibleNow;
|
||||
Player::ClientGUIDs vis_guids;
|
||||
|
||||
explicit VisibleNotifier(Player &player, bool forced) :
|
||||
i_player(player), vis_guids(player.m_clientGUIDs), force(forced) {}
|
||||
explicit VisibleNotifier(Player &player) :
|
||||
i_player(player), vis_guids(player.m_clientGUIDs),
|
||||
force(player.isNeedNotify(NOTIFY_VISIBILITY_CHANGED)) {}
|
||||
template<class T> void Visit(GridRefManager<T> &m);
|
||||
void Visit(CreatureMapType &m);
|
||||
void Visit(PlayerMapType &m) {}
|
||||
void SendToSelf(void);
|
||||
};
|
||||
|
||||
struct MANGOS_DLL_DECL Player2PlayerNotifier : public VisibleNotifier
|
||||
{
|
||||
Player2PlayerNotifier(Player &player, bool forced = false) :
|
||||
VisibleNotifier(player, forced) {}
|
||||
|
||||
template<class T> void Visit(GridRefManager<T> &) {}
|
||||
void Visit(PlayerMapType &);
|
||||
void SendToSelf(void);
|
||||
};
|
||||
|
||||
struct TRINITY_DLL_DECL PlayerVisibilityNotifier
|
||||
{
|
||||
Player &i_player;
|
||||
@@ -52,12 +81,12 @@ namespace Trinity
|
||||
void Notify(void);
|
||||
};
|
||||
|
||||
struct TRINITY_DLL_DECL PlayerRelocationNotifier : public PlayerVisibilityNotifier
|
||||
struct MANGOS_DLL_DECL PlayerRelocationNotifier
|
||||
{
|
||||
PlayerRelocationNotifier(Player &player) : PlayerVisibilityNotifier(player) {}
|
||||
template<class T> inline void Visit(GridRefManager<T> &m) { PlayerVisibilityNotifier::Visit(m); }
|
||||
Player &i_player;
|
||||
PlayerRelocationNotifier(Player &pl) : i_player(pl) {}
|
||||
template<class T> void Visit(GridRefManager<T> &) {}
|
||||
#ifdef WIN32
|
||||
template<> inline void Visit(PlayerMapType &);
|
||||
template<> inline void Visit(CreatureMapType &);
|
||||
#endif
|
||||
};
|
||||
@@ -84,6 +113,31 @@ namespace Trinity
|
||||
void Visit(DynamicObjectMapType &);
|
||||
};
|
||||
|
||||
struct MANGOS_DLL_DECL DelayedUnitRelocation
|
||||
{
|
||||
typedef GridReadGuard ReadGuard;
|
||||
Map &i_map;
|
||||
CellLock<ReadGuard> &i_lock;
|
||||
const float i_radius;
|
||||
DelayedUnitRelocation(CellLock<ReadGuard> &lock, Map &map, float radius) :
|
||||
i_lock(lock), i_map(map), i_radius(radius) {}
|
||||
template<class T> void Visit(GridRefManager<T> &) {}
|
||||
void Visit(CreatureMapType &m) { Notify<Creature,CreatureRelocationNotifier >(m); }
|
||||
void Visit(PlayerMapType &m) { Notify<Player,PlayerRelocationNotifier >(m); }
|
||||
template<class T, class VISITOR>
|
||||
void Notify(GridRefManager<T> &);
|
||||
};
|
||||
|
||||
struct MANGOS_DLL_DECL ResetNotifier
|
||||
{
|
||||
uint16 reset_mask;
|
||||
ResetNotifier(uint16 notifies) : reset_mask(notifies) {}
|
||||
template<class T> void Visit(GridRefManager<T> &m) { /*resetNotify(m);*/}
|
||||
template<class T> void resetNotify(GridRefManager<T> &);
|
||||
void Visit(CreatureMapType &m) { resetNotify<Creature>(m);}
|
||||
void Visit(PlayerMapType &m) { resetNotify<Player>(m);}
|
||||
};
|
||||
|
||||
struct TRINITY_DLL_DECL GridUpdater
|
||||
{
|
||||
GridType &i_grid;
|
||||
@@ -1236,7 +1290,6 @@ namespace Trinity
|
||||
|
||||
#ifndef WIN32
|
||||
template<> inline void PlayerRelocationNotifier::Visit<Creature>(CreatureMapType &);
|
||||
template<> inline void PlayerRelocationNotifier::Visit<Player>(PlayerMapType &);
|
||||
template<> inline void CreatureRelocationNotifier::Visit<Player>(PlayerMapType &);
|
||||
template<> inline void CreatureRelocationNotifier::Visit<Creature>(CreatureMapType &);
|
||||
template<> inline void DynamicObjectUpdater::Visit<Creature>(CreatureMapType &);
|
||||
|
||||
@@ -29,6 +29,32 @@
|
||||
#include "CreatureAI.h"
|
||||
#include "SpellAuras.h"
|
||||
|
||||
|
||||
template<class T>
|
||||
inline void
|
||||
Trinity::VisibleNotifier::Visit(GridRefManager<T> &m)
|
||||
{
|
||||
for(typename GridRefManager<T>::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||
{
|
||||
vis_guids.erase(iter->getSource()->GetGUID());
|
||||
|
||||
if(force/* || iter->getSource()->isNeedNotify(NOTIFY_VISIBILITY_CHANGED)*/)
|
||||
i_player.UpdateVisibilityOf(iter->getSource(),i_data,i_visibleNow);
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
Trinity::VisibleNotifier::Visit(CreatureMapType &m)
|
||||
{
|
||||
for(CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||
{
|
||||
vis_guids.erase(iter->getSource()->GetGUID());
|
||||
|
||||
if(force || iter->getSource()->isNeedNotify(NOTIFY_VISIBILITY_CHANGED))
|
||||
i_player.UpdateVisibilityOf(iter->getSource(),i_data,i_visibleNow);
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
Trinity::ObjectUpdater::Visit(CreatureMapType &m)
|
||||
{
|
||||
@@ -70,45 +96,47 @@ Trinity::PlayerVisibilityNotifier::Visit(GridRefManager<T> &m)
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
template<class T, class VISITOR>
|
||||
inline void
|
||||
Trinity::PlayerRelocationNotifier::Visit(PlayerMapType &m)
|
||||
MaNGOS::DelayedUnitRelocation::Notify(GridRefManager<T> &m)
|
||||
{
|
||||
for (PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||
for(typename GridRefManager<T>::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||
{
|
||||
i_clientGUIDs.erase(iter->getSource()->GetGUID());
|
||||
|
||||
if(iter->getSource()->m_Notified) //self is also skipped in this check
|
||||
T * unit = iter->getSource();
|
||||
if(!unit->isAlive() || !unit->isNeedNotify(NOTIFY_AI_RELOCATION))
|
||||
continue;
|
||||
|
||||
i_player.UpdateVisibilityOf(iter->getSource(),i_data,i_visibleNow);
|
||||
iter->getSource()->UpdateVisibilityOf(&i_player);
|
||||
VISITOR relocate(*unit);
|
||||
TypeContainerVisitor<VISITOR, WorldTypeMapContainer > c2world_relocation(relocate);
|
||||
TypeContainerVisitor<VISITOR, GridTypeMapContainer > c2grid_relocation(relocate);
|
||||
|
||||
//if (!i_player.GetSharedVisionList().empty())
|
||||
// for (SharedVisionList::const_iterator it = i_player.GetSharedVisionList().begin(); it != i_player.GetSharedVisionList().end(); ++it)
|
||||
// (*it)->UpdateVisibilityOf(iter->getSource());
|
||||
i_lock->Visit(i_lock, c2world_relocation, i_map, *unit, i_radius);
|
||||
i_lock->Visit(i_lock, c2grid_relocation, i_map, *unit, i_radius);
|
||||
|
||||
// Cancel Trade
|
||||
if(i_player.GetTrader()==iter->getSource())
|
||||
if(!i_player.IsWithinDistInMap(iter->getSource(), 5)) // iteraction distance
|
||||
i_player.GetSession()->SendCancelTrade(); // will clode both side trade windows
|
||||
unit->SetNotified(NOTIFY_AI_RELOCATION);
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void
|
||||
MaNGOS::ResetNotifier::resetNotify(GridRefManager<T> &m)
|
||||
{
|
||||
for(typename GridRefManager<T>::iterator iter=m.begin(); iter != m.end(); ++iter)
|
||||
iter->getSource()->ResetAllNotifiesbyMask(reset_mask);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void
|
||||
Trinity::PlayerRelocationNotifier::Visit(CreatureMapType &m)
|
||||
{
|
||||
if(!i_player.isAlive() || i_player.isInFlight())
|
||||
return;
|
||||
|
||||
for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||
{
|
||||
i_clientGUIDs.erase(iter->getSource()->GetGUID());
|
||||
|
||||
if(iter->getSource()->m_Notified)
|
||||
continue;
|
||||
|
||||
i_player.UpdateVisibilityOf(iter->getSource(),i_data,i_visibleNow);
|
||||
|
||||
PlayerCreatureRelocationWorker(&i_player, iter->getSource());
|
||||
Creature * c = iter->getSource();
|
||||
if(c->isAlive() && !c->NotifyExecuted(NOTIFY_AI_RELOCATION))
|
||||
PlayerCreatureRelocationWorker(&i_player, c);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,14 +144,14 @@ template<>
|
||||
inline void
|
||||
Trinity::CreatureRelocationNotifier::Visit(PlayerMapType &m)
|
||||
{
|
||||
for (PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||
if(!i_creature.isAlive())
|
||||
return;
|
||||
|
||||
for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
|
||||
{
|
||||
if(iter->getSource()->m_Notified)
|
||||
continue;
|
||||
|
||||
iter->getSource()->UpdateVisibilityOf(&i_creature);
|
||||
|
||||
PlayerCreatureRelocationWorker(iter->getSource(), &i_creature);
|
||||
Player * pl = iter->getSource();
|
||||
if( pl->isAlive() && !pl->isInFlight() && !pl->NotifyExecuted(NOTIFY_AI_RELOCATION))
|
||||
PlayerCreatureRelocationWorker(pl, &i_creature);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,13 +164,9 @@ Trinity::CreatureRelocationNotifier::Visit(CreatureMapType &m)
|
||||
|
||||
for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||
{
|
||||
if(iter->getSource()->m_Notified)
|
||||
continue;
|
||||
|
||||
if(!iter->getSource()->isAlive())
|
||||
continue;
|
||||
|
||||
CreatureCreatureRelocationWorker(iter->getSource(), &i_creature);
|
||||
Creature* c = iter->getSource();
|
||||
if( c != &i_creature && c->isAlive() && !c->NotifyExecuted(NOTIFY_AI_RELOCATION))
|
||||
CreatureCreatureRelocationWorker(c, &i_creature);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
257
src/game/Map.cpp
257
src/game/Map.cpp
@@ -214,7 +214,10 @@ Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _par
|
||||
m_activeNonPlayersIter(m_activeNonPlayers.end()),
|
||||
i_gridExpiry(expiry), m_parentMap(_parent ? _parent : this),
|
||||
m_VisibleDistance(DEFAULT_VISIBILITY_DISTANCE)
|
||||
, i_notifyLock(false), i_scriptLock(false)
|
||||
, i_notifyLock(false), i_scriptLock(false),
|
||||
m_PlayerVisibilityNotifyTimer(0.75*DEFAULT_VISIBILITY_NOTIFY_PERIOD, 0.25*DEFAULT_VISIBILITY_NOTIFY_PERIOD),
|
||||
m_ObjectVisibilityNotifyTimer(DEFAULT_VISIBILITY_NOTIFY_PERIOD, 0 * DEFAULT_VISIBILITY_NOTIFY_PERIOD),
|
||||
m_RelocationNotifyTimer(DEFAULT_VISIBILITY_NOTIFY_PERIOD,0.5*DEFAULT_VISIBILITY_NOTIFY_PERIOD)
|
||||
{
|
||||
m_notifyTimer.SetInterval(IN_MILISECONDS/2);
|
||||
|
||||
@@ -236,6 +239,10 @@ void Map::InitVisibilityDistance()
|
||||
{
|
||||
//init visibility for continents
|
||||
m_VisibleDistance = World::GetMaxVisibleDistanceOnContinents();
|
||||
|
||||
m_PlayerVisibilityNotifyTimer.SetPeriodic(0.75*sWorld.GetVisibilityNotifyPeriodOnContinents(), 0.25*sWorld.GetVisibilityNotifyPeriodOnContinents());
|
||||
m_ObjectVisibilityNotifyTimer.SetPeriodic(sWorld.GetVisibilityNotifyPeriodOnContinents(), 0 * sWorld.GetVisibilityNotifyPeriodOnContinents());
|
||||
m_RelocationNotifyTimer.SetPeriodic(sWorld.GetVisibilityNotifyPeriodOnContinents(),0.5*sWorld.GetVisibilityNotifyPeriodOnContinents());
|
||||
}
|
||||
|
||||
// Template specialization of utility methods
|
||||
@@ -336,17 +343,13 @@ void Map::AddNotifier(T*)
|
||||
template<>
|
||||
void Map::AddNotifier(Player* obj)
|
||||
{
|
||||
//obj->m_Notified = false;
|
||||
//obj->m_IsInNotifyList = false;
|
||||
AddUnitToNotify(obj);
|
||||
obj->AddToNotify(NOTIFY_VISIBILITY_CHANGED | NOTIFY_AI_RELOCATION | NOTIFY_PLAYER_VISIBILITY);
|
||||
}
|
||||
|
||||
template<>
|
||||
void Map::AddNotifier(Creature* obj)
|
||||
{
|
||||
//obj->m_Notified = false;
|
||||
//obj->m_IsInNotifyList = false;
|
||||
AddUnitToNotify(obj);
|
||||
obj->AddToNotify(NOTIFY_VISIBILITY_CHANGED | NOTIFY_AI_RELOCATION);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -444,13 +447,14 @@ bool Map::Add(Player *player)
|
||||
CellPair p = Trinity::ComputeCellPair(player->GetPositionX(), player->GetPositionY());
|
||||
Cell cell(p);
|
||||
EnsureGridLoadedAtEnter(cell, player);
|
||||
player->ResetAllNotifies();
|
||||
player->AddToWorld();
|
||||
|
||||
SendInitSelf(player);
|
||||
SendInitTransports(player);
|
||||
|
||||
player->m_clientGUIDs.clear();
|
||||
//AddNotifier(player);
|
||||
AddNotifier<Player>(player);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -494,8 +498,8 @@ Map::Add(T *obj)
|
||||
//something, such as vehicle, needs to be update immediately
|
||||
//also, trigger needs to cast spell, if not update, cannot see visual
|
||||
//if(obj->GetTypeId() != TYPEID_UNIT)
|
||||
UpdateObjectVisibility(obj,cell,p);
|
||||
AddNotifier(obj);
|
||||
UpdateObjectVisibility(obj,cell,p);
|
||||
AddNotifier<T>(obj);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -601,7 +605,7 @@ bool Map::loaded(const GridPair &p) const
|
||||
|
||||
void Map::RelocationNotify()
|
||||
{
|
||||
i_notifyLock = true;
|
||||
/* i_notifyLock = true;
|
||||
|
||||
//Notify
|
||||
for (std::vector<Unit*>::iterator iter = i_unitsToNotify.begin(); iter != i_unitsToNotify.end(); ++iter)
|
||||
@@ -651,12 +655,12 @@ void Map::RelocationNotify()
|
||||
{
|
||||
i_unitsToNotify.insert(i_unitsToNotify.end(), i_unitsToNotifyBacklog.begin(), i_unitsToNotifyBacklog.end());
|
||||
i_unitsToNotifyBacklog.clear();
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
void Map::AddUnitToNotify(Unit* u)
|
||||
{
|
||||
if(u->m_NotifyListPos < 0 && u->IsInWorld())
|
||||
/* if(u->m_NotifyListPos < 0 && u->IsInWorld())
|
||||
{
|
||||
u->oldX = u->GetPositionX();
|
||||
u->oldY = u->GetPositionY();
|
||||
@@ -671,7 +675,7 @@ void Map::AddUnitToNotify(Unit* u)
|
||||
u->m_NotifyListPos = i_unitsToNotify.size();
|
||||
i_unitsToNotify.push_back(u);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
void Map::RemoveUnitFromNotify(Unit *unit)
|
||||
@@ -714,13 +718,6 @@ void Map::Update(const uint32 &t_diff)
|
||||
plr->Update(t_diff);
|
||||
}
|
||||
|
||||
m_notifyTimer.Update(t_diff);
|
||||
if (m_notifyTimer.Passed())
|
||||
{
|
||||
m_notifyTimer.Reset();
|
||||
RelocationNotify();
|
||||
}
|
||||
|
||||
/// update active cells around players and active objects
|
||||
resetMarkedCells();
|
||||
|
||||
@@ -772,9 +769,6 @@ void Map::Update(const uint32 &t_diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (plr->m_seer != plr && !plr->GetVehicle())
|
||||
AddUnitToNotify(plr);
|
||||
}
|
||||
|
||||
// non-player active objects
|
||||
@@ -836,10 +830,191 @@ void Map::Update(const uint32 &t_diff)
|
||||
}
|
||||
|
||||
MoveAllCreaturesInMoveList();
|
||||
|
||||
{
|
||||
bool hasPlayers = !m_mapRefManager.isEmpty();
|
||||
bool hasActiveObjects = !m_activeNonPlayers.empty();
|
||||
|
||||
if(hasPlayers)
|
||||
{
|
||||
if(m_PlayerVisibilityNotifyTimer.Update(t_diff))
|
||||
{ // process player-player visibility
|
||||
ProcesssPlayersVisibility();
|
||||
ResetNotifies(NOTIFY_PLAYER_VISIBILITY);
|
||||
}
|
||||
|
||||
if(m_ObjectVisibilityNotifyTimer.Update(t_diff))
|
||||
{
|
||||
ProcessObjectsVisibility();
|
||||
ResetNotifies(NOTIFY_VISIBILITY_CHANGED);
|
||||
}
|
||||
}
|
||||
|
||||
if(hasActiveObjects || hasPlayers)
|
||||
if(m_RelocationNotifyTimer.Update(t_diff))
|
||||
{
|
||||
ProcessRelocationNotifies();
|
||||
ResetNotifies(NOTIFY_AI_RELOCATION);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Map::ProcesssPlayersVisibility()
|
||||
{
|
||||
for(m_mapRefIter = m_mapRefManager.begin(); m_mapRefIter != m_mapRefManager.end(); ++m_mapRefIter)
|
||||
{
|
||||
Player* player = m_mapRefIter->getSource();
|
||||
|
||||
if (player->m_seer != player && !player->GetVehicle())
|
||||
AddNotifier<Player>(player);
|
||||
|
||||
if(!player->IsInWorld() || !player->isNeedNotify(NOTIFY_PLAYER_VISIBILITY))
|
||||
continue;
|
||||
|
||||
WorldObject const *viewPoint = player->m_seer;
|
||||
CellPair cellpair(Trinity::ComputeCellPair(viewPoint->GetPositionX(), viewPoint->GetPositionY()));
|
||||
|
||||
if (cellpair.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || cellpair.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
|
||||
continue;
|
||||
|
||||
Trinity::Player2PlayerNotifier notifier(*player);
|
||||
|
||||
Cell cell(cellpair);
|
||||
cell.data.Part.reserved = ALL_DISTRICT;
|
||||
//cell.SetNoCreate();
|
||||
TypeContainerVisitor<Trinity::Player2PlayerNotifier, WorldTypeMapContainer > world_notifier(notifier);
|
||||
CellLock<ReadGuard> cell_lock(cell, cellpair);
|
||||
cell_lock->Visit(cell_lock, world_notifier, *this, *viewPoint, GetVisibilityDistance());
|
||||
|
||||
// send data
|
||||
notifier.SendToSelf();
|
||||
player->RemoveFromNotify(NOTIFY_PLAYER_VISIBILITY);
|
||||
player->SetNotified(NOTIFY_PLAYER_VISIBILITY);
|
||||
}
|
||||
}
|
||||
|
||||
void Map::ProcessObjectsVisibility()
|
||||
{
|
||||
for(m_mapRefIter = m_mapRefManager.begin(); m_mapRefIter != m_mapRefManager.end(); ++m_mapRefIter)
|
||||
{
|
||||
Player* player = m_mapRefIter->getSource();
|
||||
|
||||
if (player->m_seer != player && !player->GetVehicle())
|
||||
AddNotifier<Player>(player);
|
||||
|
||||
if(!player->IsInWorld())
|
||||
continue;
|
||||
|
||||
WorldObject const *viewPoint = player->m_seer;
|
||||
CellPair cellpair(Trinity::ComputeCellPair(viewPoint->GetPositionX(), viewPoint->GetPositionY()));
|
||||
|
||||
if (cellpair.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || cellpair.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
|
||||
continue;
|
||||
|
||||
Cell cell(cellpair);
|
||||
cell.data.Part.reserved = ALL_DISTRICT;
|
||||
cell.SetNoCreate();
|
||||
|
||||
Trinity::VisibleNotifier notifier(*player);
|
||||
|
||||
TypeContainerVisitor<Trinity::VisibleNotifier, WorldTypeMapContainer > world_notifier(notifier);
|
||||
TypeContainerVisitor<Trinity::VisibleNotifier, GridTypeMapContainer > grid_notifier(notifier);
|
||||
CellLock<ReadGuard> cell_lock(cell, cellpair);
|
||||
cell_lock->Visit(cell_lock, world_notifier, *this, *viewPoint, GetVisibilityDistance());
|
||||
cell_lock->Visit(cell_lock, grid_notifier, *this, *viewPoint, GetVisibilityDistance());
|
||||
|
||||
// send data
|
||||
notifier.SendToSelf();
|
||||
player->SetNotified(NOTIFY_VISIBILITY_CHANGED);
|
||||
}
|
||||
}
|
||||
|
||||
void Map::ProcessRelocationNotifies()
|
||||
{
|
||||
for(GridRefManager<NGridType>::iterator i = GridRefManager<NGridType>::begin(); i != GridRefManager<NGridType>::end(); ++i)
|
||||
{
|
||||
NGridType *grid = i->getSource();
|
||||
|
||||
if(!grid || grid->GetGridState() != GRID_STATE_ACTIVE)
|
||||
continue;
|
||||
|
||||
uint32 gx = grid->getX(), gy = grid->getY();
|
||||
|
||||
CellPair cell_min(gx*MAX_NUMBER_OF_CELLS, gy*MAX_NUMBER_OF_CELLS);
|
||||
CellPair cell_max(cell_min.x_coord + MAX_NUMBER_OF_CELLS, cell_min.y_coord+MAX_NUMBER_OF_CELLS);
|
||||
|
||||
for(uint32 x = cell_min.x_coord; x <= cell_max.x_coord; ++x)
|
||||
{
|
||||
for(uint32 y = cell_min.y_coord; y <= cell_max.y_coord; ++y)
|
||||
{
|
||||
uint32 cell_id = (y * TOTAL_NUMBER_OF_CELLS_PER_MAP) + x;
|
||||
if(!isCellMarked(cell_id))
|
||||
continue;
|
||||
|
||||
CellPair pair(x,y);
|
||||
Cell cell(pair);
|
||||
cell.data.Part.reserved = CENTER_DISTRICT;
|
||||
cell.SetNoCreate();
|
||||
|
||||
CellLock<ReadGuard> cell_lock(cell, pair);
|
||||
Trinity::DelayedUnitRelocation cell_relocation(cell_lock, *this, GetVisibilityDistance());
|
||||
TypeContainerVisitor<Trinity::DelayedUnitRelocation, GridTypeMapContainer > grid_object_relocation(cell_relocation);
|
||||
TypeContainerVisitor<Trinity::DelayedUnitRelocation, WorldTypeMapContainer > world_object_relocation(cell_relocation);
|
||||
cell_lock->Visit(cell_lock, grid_object_relocation, *this);
|
||||
cell_lock->Visit(cell_lock, world_object_relocation, *this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Map::ResetNotifies(uint16 notify_mask)
|
||||
{
|
||||
if(notify_mask == NOTIFY_PLAYER_VISIBILITY)
|
||||
{
|
||||
for(m_mapRefIter = m_mapRefManager.begin(); m_mapRefIter != m_mapRefManager.end(); ++m_mapRefIter)
|
||||
m_mapRefIter->getSource()->ResetAllNotifiesbyMask(notify_mask);
|
||||
return;
|
||||
}
|
||||
|
||||
Trinity::ResetNotifier reset(notify_mask);
|
||||
TypeContainerVisitor<Trinity::ResetNotifier, GridTypeMapContainer > grid_notifier(reset);
|
||||
TypeContainerVisitor<Trinity::ResetNotifier, WorldTypeMapContainer > world_notifier(reset);
|
||||
|
||||
for(GridRefManager<NGridType>::iterator i = GridRefManager<NGridType>::begin(); i != GridRefManager<NGridType>::end(); ++i)
|
||||
{
|
||||
NGridType *grid = i->getSource();
|
||||
|
||||
if(!grid || grid->GetGridState() != GRID_STATE_ACTIVE)
|
||||
continue;
|
||||
|
||||
uint32 gx = grid->getX(), gy = grid->getY();
|
||||
|
||||
CellPair cell_min(gx*MAX_NUMBER_OF_CELLS, gy*MAX_NUMBER_OF_CELLS);
|
||||
CellPair cell_max(cell_min.x_coord + MAX_NUMBER_OF_CELLS, cell_min.y_coord+MAX_NUMBER_OF_CELLS);
|
||||
|
||||
for(uint32 x = cell_min.x_coord; x <= cell_max.x_coord; ++x)
|
||||
{
|
||||
for(uint32 y = cell_min.y_coord; y <= cell_max.y_coord; ++y)
|
||||
{
|
||||
uint32 cell_id = (y * TOTAL_NUMBER_OF_CELLS_PER_MAP) + x;
|
||||
if(!isCellMarked(cell_id))
|
||||
continue;
|
||||
|
||||
CellPair pair(x,y);
|
||||
Cell cell(pair);
|
||||
cell.data.Part.reserved = CENTER_DISTRICT;
|
||||
cell.SetNoCreate();
|
||||
CellLock<NullGuard> cell_lock(cell, pair);
|
||||
cell_lock->Visit(cell_lock, grid_notifier, *this);
|
||||
cell_lock->Visit(cell_lock, world_notifier, *this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Map::Remove(Player *player, bool remove)
|
||||
{
|
||||
player->ResetAllNotifies();
|
||||
player->RemoveFromWorld();
|
||||
SendRemoveTransports(player);
|
||||
|
||||
@@ -883,6 +1058,7 @@ template<class T>
|
||||
void
|
||||
Map::Remove(T *obj, bool remove)
|
||||
{
|
||||
obj->ResetAllNotifies();
|
||||
obj->RemoveFromWorld();
|
||||
if (obj->isActiveObject())
|
||||
RemoveFromActive(obj);
|
||||
@@ -946,7 +1122,7 @@ Map::PlayerRelocation(Player *player, float x, float y, float z, float orientati
|
||||
EnsureGridLoadedAtEnter(new_cell, player);
|
||||
}
|
||||
|
||||
AddUnitToNotify(player);
|
||||
AddNotifier<Player>(player);
|
||||
|
||||
NGridType* newGrid = getNGrid(new_cell.GridX(), new_cell.GridY());
|
||||
if (!same_cell && newGrid->GetGridState()!= GRID_STATE_ACTIVE)
|
||||
@@ -979,7 +1155,7 @@ Map::CreatureRelocation(Creature *creature, float x, float y, float z, float ang
|
||||
else
|
||||
{
|
||||
creature->Relocate(x, y, z, ang);
|
||||
AddUnitToNotify(creature);
|
||||
AddNotifier<Creature>(creature);
|
||||
}
|
||||
|
||||
if (creature->IsVehicle())
|
||||
@@ -1033,7 +1209,7 @@ void Map::MoveAllCreaturesInMoveList()
|
||||
// update pos
|
||||
c->Relocate(cm.x, cm.y, cm.z, cm.ang);
|
||||
//CreatureRelocationNotify(c,new_cell,new_cell.cellPair());
|
||||
AddUnitToNotify(c);
|
||||
AddNotifier<Creature>(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1140,7 +1316,7 @@ bool Map::CreatureRespawnRelocation(Creature *c)
|
||||
c->Relocate(resp_x, resp_y, resp_z, resp_o);
|
||||
c->GetMotionMaster()->Initialize(); // prevent possible problems with default move generators
|
||||
//CreatureRelocationNotify(c,resp_cell,resp_cell.cellPair());
|
||||
AddUnitToNotify(c);
|
||||
AddNotifier<Creature>(c);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -2141,34 +2317,35 @@ void Map::UpdateObjectVisibility( WorldObject* obj, Cell cell, CellPair cellpair
|
||||
cell_lock->Visit(cell_lock, player_notifier, *this, *obj, GetVisibilityDistance());
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
void Map::UpdatePlayerVisibility( Player* player, Cell cell, CellPair cellpair )
|
||||
{
|
||||
cell.data.Part.reserved = ALL_DISTRICT;
|
||||
|
||||
MaNGOS::PlayerNotifier pl_notifier(*player);
|
||||
TypeContainerVisitor<MaNGOS::PlayerNotifier, WorldTypeMapContainer > player_notifier(pl_notifier);
|
||||
Trinity::Player2PlayerNotifier pl_notifier(*player);
|
||||
TypeContainerVisitor<Trinity::Player2PlayerNotifier, WorldTypeMapContainer > player_notifier(pl_notifier);
|
||||
|
||||
CellLock<ReadGuard> cell_lock(cell, cellpair);
|
||||
cell_lock->Visit(cell_lock, player_notifier, *this, *player, GetVisibilityDistance());
|
||||
pl_notifier.SendToSelf();
|
||||
}
|
||||
|
||||
void Map::UpdateObjectsVisibilityFor( Player* player, Cell cell, CellPair cellpair )
|
||||
{
|
||||
MaNGOS::VisibleNotifier notifier(*player);
|
||||
Trinity::VisibleNotifier notifier(*player, true);
|
||||
|
||||
cell.data.Part.reserved = ALL_DISTRICT;
|
||||
cell.SetNoCreate();
|
||||
TypeContainerVisitor<MaNGOS::VisibleNotifier, WorldTypeMapContainer > world_notifier(notifier);
|
||||
TypeContainerVisitor<MaNGOS::VisibleNotifier, GridTypeMapContainer > grid_notifier(notifier);
|
||||
TypeContainerVisitor<Trinity::VisibleNotifier, WorldTypeMapContainer > world_notifier(notifier);
|
||||
TypeContainerVisitor<Trinity::VisibleNotifier, GridTypeMapContainer > grid_notifier(notifier);
|
||||
CellLock<GridReadGuard> cell_lock(cell, cellpair);
|
||||
cell_lock->Visit(cell_lock, world_notifier, *this, *player, GetVisibilityDistance());
|
||||
cell_lock->Visit(cell_lock, grid_notifier, *this, *player, GetVisibilityDistance());
|
||||
|
||||
// send data
|
||||
notifier.Notify();
|
||||
notifier.SendToSelf();
|
||||
}
|
||||
|
||||
/*
|
||||
void Map::PlayerRelocationNotify( Player* player, Cell cell, CellPair cellpair )
|
||||
{
|
||||
CellLock<ReadGuard> cell_lock(cell, cellpair);
|
||||
@@ -2524,6 +2701,10 @@ void InstanceMap::InitVisibilityDistance()
|
||||
{
|
||||
//init visibility distance for instances
|
||||
m_VisibleDistance = World::GetMaxVisibleDistanceInInstances();
|
||||
|
||||
m_PlayerVisibilityNotifyTimer.SetPeriodic(0.75*sWorld.GetVisibilityNotifyPeriodInInstances(), 0.25*sWorld.GetVisibilityNotifyPeriodInInstances());
|
||||
m_ObjectVisibilityNotifyTimer.SetPeriodic(sWorld.GetVisibilityNotifyPeriodInInstances(), 0 * sWorld.GetVisibilityNotifyPeriodInInstances());
|
||||
m_RelocationNotifyTimer.SetPeriodic(sWorld.GetVisibilityNotifyPeriodInInstances(),0.5*sWorld.GetVisibilityNotifyPeriodInInstances());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2873,6 +3054,10 @@ void BattleGroundMap::InitVisibilityDistance()
|
||||
{
|
||||
//init visibility distance for BG/Arenas
|
||||
m_VisibleDistance = World::GetMaxVisibleDistanceInBGArenas();
|
||||
|
||||
m_PlayerVisibilityNotifyTimer.SetPeriodic(0.75*sWorld.GetVisibilityNotifyPeriodInBGArenas(), 0.25*sWorld.GetVisibilityNotifyPeriodInBGArenas());
|
||||
m_ObjectVisibilityNotifyTimer.SetPeriodic(sWorld.GetVisibilityNotifyPeriodInBGArenas(), 0 * sWorld.GetVisibilityNotifyPeriodInBGArenas());
|
||||
m_RelocationNotifyTimer.SetPeriodic(sWorld.GetVisibilityNotifyPeriodInBGArenas(),0.5*sWorld.GetVisibilityNotifyPeriodInBGArenas());
|
||||
}
|
||||
|
||||
bool BattleGroundMap::CanEnter(Player * player)
|
||||
|
||||
@@ -405,6 +405,8 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
|
||||
virtual bool RemoveBones(uint64 guid, float x, float y);
|
||||
|
||||
void UpdateObjectVisibility(WorldObject* obj, Cell cell, CellPair cellpair);
|
||||
void UpdatePlayerVisibility( Player* player, Cell cell, CellPair cellpair );
|
||||
void UpdateObjectsVisibilityFor(Player* player, Cell cell, CellPair cellpair );
|
||||
|
||||
void resetMarkedCells() { marked_cells.reset(); }
|
||||
bool isCellMarked(uint32 pCellId) { return marked_cells.test(pCellId); }
|
||||
@@ -517,6 +519,10 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
|
||||
MapRefManager m_mapRefManager;
|
||||
MapRefManager::iterator m_mapRefIter;
|
||||
|
||||
PeriodicTimer m_ObjectVisibilityNotifyTimer;
|
||||
PeriodicTimer m_PlayerVisibilityNotifyTimer;
|
||||
PeriodicTimer m_RelocationNotifyTimer;
|
||||
|
||||
typedef std::set<WorldObject*> ActiveNonPlayers;
|
||||
ActiveNonPlayers m_activeNonPlayers;
|
||||
ActiveNonPlayers::iterator m_activeNonPlayersIter;
|
||||
@@ -537,6 +543,11 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
|
||||
|
||||
IntervalTimer m_notifyTimer;
|
||||
|
||||
void ProcessObjectsVisibility();
|
||||
void ProcesssPlayersVisibility();
|
||||
void ProcessRelocationNotifies();
|
||||
void ResetNotifies(uint16 notify_mask);
|
||||
|
||||
bool i_notifyLock, i_scriptLock;
|
||||
std::vector<Unit*> i_unitsToNotifyBacklog;
|
||||
std::vector<Unit*> i_unitsToNotify;
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
|
||||
class Transport;
|
||||
|
||||
#define DEFAULT_VISIBILITY_NOTIFY_PERIOD 1000
|
||||
|
||||
class MANGOS_DLL_DECL MapManager : public MaNGOS::Singleton<MapManager, MaNGOS::ClassLevelLockable<MapManager, ACE_Thread_Mutex> >
|
||||
{
|
||||
|
||||
|
||||
@@ -240,9 +240,6 @@ void Object::BuildUpdate(UpdateDataMapType &update_players)
|
||||
|
||||
void Object::SendUpdateToPlayer(Player* player)
|
||||
{
|
||||
// send update to another players
|
||||
SendUpdateObjectToAllExcept(player);
|
||||
|
||||
// send create update to player
|
||||
UpdateData upd;
|
||||
WorldPacket packet;
|
||||
@@ -1108,6 +1105,7 @@ WorldObject::WorldObject()
|
||||
, m_zoneScript(NULL)
|
||||
, m_isActive(false), m_isWorldObject(false)
|
||||
, m_name("")
|
||||
, m_notifyflags(0), m_executed_notifies(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -93,6 +93,15 @@ enum PhaseMasks
|
||||
PHASEMASK_ANYWHERE = 0xFFFFFFFF
|
||||
};
|
||||
|
||||
enum NotifyFlags
|
||||
{
|
||||
NOTIFY_NONE = 0x00,
|
||||
NOTIFY_AI_RELOCATION = 0x01,
|
||||
NOTIFY_VISIBILITY_CHANGED = 0x02,
|
||||
NOTIFY_PLAYER_VISIBILITY = 0x04,
|
||||
NOTIFY_ALL = 0xFF
|
||||
};
|
||||
|
||||
class WorldPacket;
|
||||
class UpdateData;
|
||||
class ByteBuffer;
|
||||
@@ -620,6 +629,17 @@ class TRINITY_DLL_SPEC WorldObject : public Object, public WorldLocation
|
||||
|
||||
void DestroyForNearbyPlayers();
|
||||
|
||||
//new relocation and visibility system functions
|
||||
void AddToNotify(uint16 f) { m_notifyflags |= f;}
|
||||
void RemoveFromNotify(uint16 f) { m_notifyflags &= ~f;}
|
||||
bool isNeedNotify(uint16 f) const { return m_notifyflags & f;}
|
||||
|
||||
bool NotifyExecuted(uint16 f) const { return m_executed_notifies & f;}
|
||||
void SetNotified(uint16 f) { m_executed_notifies |= f;}
|
||||
void ResetNotifies(uint16 f) { m_executed_notifies |= ~f;}
|
||||
void ResetAllNotifies() { m_notifyflags = 0; m_executed_notifies = 0; }
|
||||
void ResetAllNotifiesbyMask(uint16 f) { m_notifyflags &= ~f; m_executed_notifies &= ~f; }
|
||||
|
||||
bool isActiveObject() const { return m_isActive; }
|
||||
void setActive(bool isActiveObject);
|
||||
void SetWorldObject(bool apply);
|
||||
@@ -654,5 +674,8 @@ class TRINITY_DLL_SPEC WorldObject : public Object, public WorldLocation
|
||||
//uint32 m_mapId; // object at map with map_id
|
||||
uint32 m_InstanceId; // in map copy with instance id
|
||||
uint32 m_phaseMask; // in area phase state
|
||||
|
||||
uint16 m_notifyflags;
|
||||
uint16 m_executed_notifies;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -6015,6 +6015,9 @@ bool Player::SetPosition(float x, float y, float z, float orientation, bool tele
|
||||
// code block for underwater state update
|
||||
UpdateUnderwaterState(GetMap(), x, y, z);
|
||||
|
||||
if(GetTrader() && !IsWithinDistInMap(GetTrader(), 5))
|
||||
GetSession()->SendCancelTrade();
|
||||
|
||||
CheckExploreSystem();
|
||||
}
|
||||
else if(turn)
|
||||
@@ -19292,18 +19295,32 @@ bool Player::IsVisibleGloballyFor( Player* u ) const
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void UpdateVisibilityOf_helper(std::set<uint64>& s64, T* target)
|
||||
inline void UpdateVisibilityOf_helper(std::set<uint64>& s64, T* target, std::set<Unit*>& v)
|
||||
{
|
||||
s64.insert(target->GetGUID());
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void UpdateVisibilityOf_helper(std::set<uint64>& s64, GameObject* target)
|
||||
inline void UpdateVisibilityOf_helper(std::set<uint64>& s64, GameObject* target, std::set<Unit*>& v)
|
||||
{
|
||||
if(!target->IsTransport())
|
||||
s64.insert(target->GetGUID());
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void UpdateVisibilityOf_helper(std::set<uint64>& s64, Creature* target, std::set<Unit*>& v)
|
||||
{
|
||||
s64.insert(target->GetGUID());
|
||||
v.insert(target);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void UpdateVisibilityOf_helper(std::set<uint64>& s64, Player* target, std::set<Unit*>& v)
|
||||
{
|
||||
s64.insert(target->GetGUID());
|
||||
v.insert(target);
|
||||
}
|
||||
|
||||
void Player::UpdateVisibilityOf(WorldObject* target)
|
||||
{
|
||||
if(HaveAtClient(target))
|
||||
@@ -19327,7 +19344,7 @@ void Player::UpdateVisibilityOf(WorldObject* target)
|
||||
// UpdateVisibilityOf(((Unit*)target)->m_Vehicle);
|
||||
|
||||
target->SendUpdateToPlayer(this);
|
||||
UpdateVisibilityOf_helper(m_clientGUIDs, target);
|
||||
m_clientGUIDs.insert(target->GetGUID());
|
||||
|
||||
#ifdef TRINITY_DEBUG
|
||||
if((sLog.getLogFilter() & LOG_FILTER_VISIBILITY_CHANGES)==0)
|
||||
@@ -19355,7 +19372,7 @@ void Player::SendInitialVisiblePackets(Unit* target)
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Player::UpdateVisibilityOf(T* target, UpdateData& data, std::set<WorldObject*>& visibleNow)
|
||||
void Player::UpdateVisibilityOf(T* target, UpdateData& data, std::set<Unit*>& visibleNow)
|
||||
{
|
||||
if(HaveAtClient(target))
|
||||
{
|
||||
@@ -19377,9 +19394,8 @@ void Player::UpdateVisibilityOf(T* target, UpdateData& data, std::set<WorldObjec
|
||||
//if(target->isType(TYPEMASK_UNIT) && ((Unit*)target)->m_Vehicle)
|
||||
// UpdateVisibilityOf(((Unit*)target)->m_Vehicle, data, visibleNow);
|
||||
|
||||
visibleNow.insert(target);
|
||||
target->BuildCreateUpdateBlockForPlayer(&data, this);
|
||||
UpdateVisibilityOf_helper(m_clientGUIDs,target);
|
||||
UpdateVisibilityOf_helper(m_clientGUIDs,target,visibleNow);
|
||||
|
||||
#ifdef TRINITY_DEBUG
|
||||
if((sLog.getLogFilter() & LOG_FILTER_VISIBILITY_CHANGES)==0)
|
||||
@@ -19389,11 +19405,11 @@ void Player::UpdateVisibilityOf(T* target, UpdateData& data, std::set<WorldObjec
|
||||
}
|
||||
}
|
||||
|
||||
template void Player::UpdateVisibilityOf(Player* target, UpdateData& data, std::set<WorldObject*>& visibleNow);
|
||||
template void Player::UpdateVisibilityOf(Creature* target, UpdateData& data, std::set<WorldObject*>& visibleNow);
|
||||
template void Player::UpdateVisibilityOf(Corpse* target, UpdateData& data, std::set<WorldObject*>& visibleNow);
|
||||
template void Player::UpdateVisibilityOf(GameObject* target, UpdateData& data, std::set<WorldObject*>& visibleNow);
|
||||
template void Player::UpdateVisibilityOf(DynamicObject* target, UpdateData& data, std::set<WorldObject*>& visibleNow);
|
||||
template void Player::UpdateVisibilityOf(Player* target, UpdateData& data, std::set<Unit*>& visibleNow);
|
||||
template void Player::UpdateVisibilityOf(Creature* target, UpdateData& data, std::set<Unit*>& visibleNow);
|
||||
template void Player::UpdateVisibilityOf(Corpse* target, UpdateData& data, std::set<Unit*>& visibleNow);
|
||||
template void Player::UpdateVisibilityOf(GameObject* target, UpdateData& data, std::set<Unit*>& visibleNow);
|
||||
template void Player::UpdateVisibilityOf(DynamicObject* target, UpdateData& data, std::set<Unit*>& visibleNow);
|
||||
|
||||
void Player::InitPrimaryProfessions()
|
||||
{
|
||||
|
||||
@@ -2154,7 +2154,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||
void SendInitialVisiblePackets(Unit* target);
|
||||
|
||||
template<class T>
|
||||
void UpdateVisibilityOf(T* target, UpdateData& data, std::set<WorldObject*>& visibleNow);
|
||||
void UpdateVisibilityOf(T* target, UpdateData& data, std::set<Unit*>& visibleNow);
|
||||
|
||||
// Stealth detection system
|
||||
void HandleStealthedUnitsDetection();
|
||||
|
||||
@@ -11220,7 +11220,22 @@ void Unit::SetVisibility(UnitVisibility x)
|
||||
{
|
||||
m_Visibility = x;
|
||||
|
||||
SetToNotify();
|
||||
if(IsInWorld())
|
||||
{
|
||||
Map *m = GetMap();
|
||||
CellPair p(Trinity::ComputeCellPair(GetPositionX(), GetPositionY()));
|
||||
Cell cell(p);
|
||||
|
||||
if(GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
m->UpdatePlayerVisibility((Player*)this, cell, p);
|
||||
m->UpdateObjectsVisibilityFor((Player*)this, cell, p);
|
||||
}
|
||||
else
|
||||
m->UpdateObjectVisibility(this, cell, p);
|
||||
|
||||
AddToNotify(NOTIFY_AI_RELOCATION);
|
||||
}
|
||||
|
||||
if (x == VISIBILITY_GROUP_STEALTH)
|
||||
DestroyForNearbyPlayers();
|
||||
@@ -14034,9 +14049,10 @@ bool Unit::HandleAuraRaidProcFromCharge(AuraEffect* triggeredByAura)
|
||||
|
||||
void Unit::SetToNotify()
|
||||
{
|
||||
// it is called somewhere when obj is not in world (crash when log in instance)
|
||||
if (m_NotifyListPos < 0)
|
||||
GetMap()->AddUnitToNotify(this);
|
||||
if (GetTypeId() == TYPEID_PLAYER)
|
||||
AddToNotify(NOTIFY_VISIBILITY_CHANGED | NOTIFY_AI_RELOCATION | NOTIFY_PLAYER_VISIBILITY);
|
||||
else
|
||||
AddToNotify(NOTIFY_VISIBILITY_CHANGED | NOTIFY_AI_RELOCATION);
|
||||
}
|
||||
|
||||
void Unit::Kill(Unit *pVictim, bool durabilityLoss)
|
||||
|
||||
@@ -84,6 +84,10 @@ float World::m_MaxVisibleDistanceInFlight = DEFAULT_VISIBILITY_DISTANCE;
|
||||
float World::m_VisibleUnitGreyDistance = 0;
|
||||
float World::m_VisibleObjectGreyDistance = 0;
|
||||
|
||||
int32 World::m_visibility_notify_periodOnContinents = DEFAULT_VISIBILITY_NOTIFY_PERIOD;
|
||||
int32 World::m_visibility_notify_periodInInstances = DEFAULT_VISIBILITY_NOTIFY_PERIOD;
|
||||
int32 World::m_visibility_notify_periodInBGArenas = DEFAULT_VISIBILITY_NOTIFY_PERIOD;
|
||||
|
||||
/// World constructor
|
||||
World::World()
|
||||
{
|
||||
@@ -1132,6 +1136,10 @@ void World::LoadConfigSettings(bool reload)
|
||||
m_MaxVisibleDistanceInFlight = MAX_VISIBILITY_DISTANCE - m_VisibleObjectGreyDistance;
|
||||
}
|
||||
|
||||
m_visibility_notify_periodOnContinents = sConfig.GetIntDefault("Visibility.Notify.Period.OnContinents", DEFAULT_VISIBILITY_NOTIFY_PERIOD);
|
||||
m_visibility_notify_periodInInstances = sConfig.GetIntDefault("Visibility.Notify.Period.InInstances", DEFAULT_VISIBILITY_NOTIFY_PERIOD);
|
||||
m_visibility_notify_periodInBGArenas = sConfig.GetIntDefault("Visibility.Notify.Period.InBGArenas", DEFAULT_VISIBILITY_NOTIFY_PERIOD);
|
||||
|
||||
///- Read the "Data" directory from the config file
|
||||
std::string dataPath = sConfig.GetStringDefault("DataDir","./");
|
||||
if (dataPath.at(dataPath.length()-1)!='/' && dataPath.at(dataPath.length()-1)!='\\')
|
||||
|
||||
@@ -613,6 +613,9 @@ class World
|
||||
static float GetVisibleUnitGreyDistance() { return m_VisibleUnitGreyDistance; }
|
||||
static float GetVisibleObjectGreyDistance() { return m_VisibleObjectGreyDistance; }
|
||||
|
||||
static int32 GetVisibilityNotifyPeriodOnContinents(){ return m_visibility_notify_periodOnContinents; }
|
||||
static int32 GetVisibilityNotifyPeriodInInstances() { return m_visibility_notify_periodInInstances; }
|
||||
static int32 GetVisibilityNotifyPeriodInBGArenas() { return m_visibility_notify_periodInBGArenas; }
|
||||
|
||||
void SetWintergrapsTimer(uint32 timer, uint32 state)
|
||||
{
|
||||
@@ -723,6 +726,10 @@ class World
|
||||
static float m_VisibleUnitGreyDistance;
|
||||
static float m_VisibleObjectGreyDistance;
|
||||
|
||||
static int32 m_visibility_notify_periodOnContinents;
|
||||
static int32 m_visibility_notify_periodInInstances;
|
||||
static int32 m_visibility_notify_periodInBGArenas;
|
||||
|
||||
// CLI command holder to be thread safe
|
||||
ACE_Based::LockedQueue<CliCommandHolder*,ACE_Thread_Mutex> cliCmdQueue;
|
||||
SqlResultQueue *m_resultQueue;
|
||||
|
||||
@@ -95,5 +95,28 @@ struct TimeTrackerSmall
|
||||
int32 i_expiryTime;
|
||||
};
|
||||
|
||||
struct PeriodicTimer
|
||||
{
|
||||
PeriodicTimer(int32 period, int32 start_time) :
|
||||
i_expireTime(start_time), i_period(period) {}
|
||||
|
||||
bool Update(const uint32 &diff)
|
||||
{
|
||||
if((i_expireTime -= diff) > 0)
|
||||
return false;
|
||||
|
||||
i_expireTime += i_period > diff ? i_period : diff;
|
||||
return true;
|
||||
}
|
||||
|
||||
void SetPeriodic(int32 period, int32 start_time)
|
||||
{
|
||||
i_expireTime=start_time, i_period=period;
|
||||
}
|
||||
|
||||
int32 i_period;
|
||||
int32 i_expireTime;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1181,6 +1181,10 @@ Visibility.Distance.InFlight = 100
|
||||
Visibility.Distance.Grey.Unit = 1
|
||||
Visibility.Distance.Grey.Object = 10
|
||||
|
||||
Visibility.Notify.Period.OnContinents = 1000
|
||||
Visibility.Notify.Period.InInstances = 1000
|
||||
Visibility.Notify.Period.InBGArenas = 1000
|
||||
|
||||
###################################################################################################################
|
||||
# SERVER RATES
|
||||
#
|
||||
|
||||
Reference in New Issue
Block a user