diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/game/GridNotifiers.cpp | 154 | ||||
-rw-r--r-- | src/game/GridNotifiers.h | 63 | ||||
-rw-r--r-- | src/game/GridNotifiersImpl.h | 98 | ||||
-rw-r--r-- | src/game/Map.cpp | 257 | ||||
-rw-r--r-- | src/game/Map.h | 11 | ||||
-rw-r--r-- | src/game/MapManager.h | 2 | ||||
-rw-r--r-- | src/game/Object.cpp | 4 | ||||
-rw-r--r-- | src/game/Object.h | 23 | ||||
-rw-r--r-- | src/game/Player.cpp | 38 | ||||
-rw-r--r-- | src/game/Player.h | 2 | ||||
-rw-r--r-- | src/game/Unit.cpp | 24 | ||||
-rw-r--r-- | src/game/World.cpp | 8 | ||||
-rw-r--r-- | src/game/World.h | 7 | ||||
-rw-r--r-- | src/shared/Timer.h | 23 | ||||
-rw-r--r-- | src/trinitycore/trinitycore.conf.dist | 4 |
15 files changed, 553 insertions, 165 deletions
diff --git a/src/game/GridNotifiers.cpp b/src/game/GridNotifiers.cpp index cf403208389..8d3b906da8f 100644 --- a/src/game/GridNotifiers.cpp +++ b/src/game/GridNotifiers.cpp @@ -30,6 +30,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) { for (PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter) @@ -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 diff --git a/src/game/GridNotifiers.h b/src/game/GridNotifiers.h index 9deb5cb2e24..97bba42fe93 100644 --- a/src/game/GridNotifiers.h +++ b/src/game/GridNotifiers.h @@ -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 &); diff --git a/src/game/GridNotifiersImpl.h b/src/game/GridNotifiersImpl.h index fd73119f0d3..e1738af4324 100644 --- a/src/game/GridNotifiersImpl.h +++ b/src/game/GridNotifiersImpl.h @@ -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(iter->getSource()->m_Notified) - continue; - - iter->getSource()->UpdateVisibilityOf(&i_creature); + if(!i_creature.isAlive()) + return; - PlayerCreatureRelocationWorker(iter->getSource(), &i_creature); + for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter) + { + 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); } } diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 5a72c6ed8f0..0ddbf359f40 100644 --- a/src/game/Map.cpp +++ b/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) diff --git a/src/game/Map.h b/src/game/Map.h index 981a48bbbb6..9144624b23d 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -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; diff --git a/src/game/MapManager.h b/src/game/MapManager.h index f4bc5feafa2..df90add4d57 100644 --- a/src/game/MapManager.h +++ b/src/game/MapManager.h @@ -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> > { diff --git a/src/game/Object.cpp b/src/game/Object.cpp index f3cff243e93..0c8c215d09a 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -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) { } diff --git a/src/game/Object.h b/src/game/Object.h index 83189f30b23..93cf0d40e85 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -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 diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 69571eb9ee1..51fbc3413c0 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -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() { diff --git a/src/game/Player.h b/src/game/Player.h index 9038c8926b9..f216f4e548b 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -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(); diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index af07f8eee97..4f3e90bf507 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -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) diff --git a/src/game/World.cpp b/src/game/World.cpp index dc14a5229e0..05d7e5cef21 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -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)!='\\') diff --git a/src/game/World.h b/src/game/World.h index 6baff8aac4d..9777e97a046 100644 --- a/src/game/World.h +++ b/src/game/World.h @@ -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; diff --git a/src/shared/Timer.h b/src/shared/Timer.h index 82f5be161d9..46bba5475bc 100644 --- a/src/shared/Timer.h +++ b/src/shared/Timer.h @@ -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 diff --git a/src/trinitycore/trinitycore.conf.dist b/src/trinitycore/trinitycore.conf.dist index 7c741e38e0e..0d6e7d2e557 100644 --- a/src/trinitycore/trinitycore.conf.dist +++ b/src/trinitycore/trinitycore.conf.dist @@ -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 # |