diff options
Diffstat (limited to 'src/game')
-rw-r--r-- | src/game/Creature.cpp | 2 | ||||
-rw-r--r-- | src/game/GridNotifiers.cpp | 188 | ||||
-rw-r--r-- | src/game/GridNotifiers.h | 83 | ||||
-rw-r--r-- | src/game/GridNotifiersImpl.h | 112 | ||||
-rw-r--r-- | src/game/Map.cpp | 218 | ||||
-rw-r--r-- | src/game/Map.h | 15 | ||||
-rw-r--r-- | src/game/MapManager.h | 2 | ||||
-rw-r--r-- | src/game/MiscHandler.cpp | 6 | ||||
-rw-r--r-- | src/game/NPCHandler.cpp | 6 | ||||
-rw-r--r-- | src/game/Object.cpp | 9 | ||||
-rw-r--r-- | src/game/Object.h | 10 | ||||
-rw-r--r-- | src/game/Player.cpp | 27 | ||||
-rw-r--r-- | src/game/Player.h | 4 | ||||
-rw-r--r-- | src/game/SpellAuraEffects.cpp | 6 | ||||
-rw-r--r-- | src/game/Unit.cpp | 43 | ||||
-rw-r--r-- | src/game/Unit.h | 4 |
16 files changed, 269 insertions, 466 deletions
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 3e834f4aca0..8f24f923b1e 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -1588,7 +1588,7 @@ void Creature::Respawn(bool force) poolhandler.UpdatePool<Creature>(poolid, GetDBTableGUIDLow()); } - SetToNotify(); + UpdateObjectVisibility(); } void Creature::ForcedDespawn(uint32 timeMSToDespawn) diff --git a/src/game/GridNotifiers.cpp b/src/game/GridNotifiers.cpp index 99f7e1241b6..91b70467a93 100644 --- a/src/game/GridNotifiers.cpp +++ b/src/game/GridNotifiers.cpp @@ -30,51 +30,8 @@ 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()) @@ -86,22 +43,22 @@ Player2PlayerNotifier::SendToSelf() i_player.UpdateVisibilityOf((*itr), i_data, i_visibleNow); - if(!(*itr)->isNeedNotify(NOTIFY_PLAYER_VISIBILITY)) + if(!(*itr)->isNeedNotify(NOTIFY_VISIBILITY_CHANGED)) (*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(IS_PLAYER_GUID(*it)) + { + Player* plr = ObjectAccessor::FindPlayer(*it); + if(plr && plr->IsInWorld() && !plr->isNeedNotify(NOTIFY_VISIBILITY_CHANGED)) + plr->UpdateVisibilityOf(&i_player); + } } if(!i_data.HasData()) @@ -154,6 +111,135 @@ VisibleChangesNotifier::Visit(DynamicObjectMapType &m) caster->UpdateVisibilityOf(&i_object); } +inline void CreatureUnitRelocationWorker(Creature* c, Unit* u) +{ + if(!u->isAlive() || !c->isAlive() || u->isInFlight()) + return; + + if(c->HasReactState(REACT_AGGRESSIVE) && !c->hasUnitState(UNIT_STAT_SIGHTLESS)) + if(c->_IsWithinDist(u, c->m_SightDistance, true) && c->IsAIEnabled) + c->AI()->MoveInLineOfSight(u); +} + +void PlayerRelocationNotifier::Visit(PlayerMapType &m) +{ + for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter) + { + Player* plr = iter->getSource(); + + vis_guids.erase(plr->GetGUID()); + + i_player.UpdateVisibilityOf(plr,i_data,i_visibleNow); + + if (plr->m_seer->isNeedNotify(NOTIFY_VISIBILITY_CHANGED)) + continue; + + plr->UpdateVisibilityOf(&i_player); + } +} + +void PlayerRelocationNotifier::Visit(CreatureMapType &m) +{ + bool relocated_for_ai = (&i_player == i_player.m_seer); + + for(CreatureMapType::iterator iter=m.begin(); iter != m.end(); ++iter) + { + Creature * c = iter->getSource(); + + vis_guids.erase(c->GetGUID()); + + i_player.UpdateVisibilityOf(c,i_data,i_visibleNow); + + if (relocated_for_ai && !c->isNeedNotify(NOTIFY_VISIBILITY_CHANGED)) + CreatureUnitRelocationWorker(c, &i_player); + } +} + +void CreatureRelocationNotifier::Visit(PlayerMapType &m) +{ + for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter) + { + Player * pl = iter->getSource(); + + if(!pl->m_seer->isNeedNotify(NOTIFY_VISIBILITY_CHANGED)) + pl->UpdateVisibilityOf(&i_creature); + + CreatureUnitRelocationWorker(&i_creature, pl); + } +} + +void CreatureRelocationNotifier::Visit(CreatureMapType &m) +{ + if(!i_creature.isAlive()) + return; + + for(CreatureMapType::iterator iter=m.begin(); iter != m.end(); ++iter) + { + Creature* c = iter->getSource(); + CreatureUnitRelocationWorker(&i_creature, c); + + if(!c->isNeedNotify(NOTIFY_VISIBILITY_CHANGED)) + CreatureUnitRelocationWorker(c, &i_creature); + } +} + +void DelayedUnitRelocation::Visit(CreatureMapType &m) +{ + for(CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter) + { + Creature * unit = iter->getSource(); + if(!unit->isNeedNotify(NOTIFY_VISIBILITY_CHANGED)) + continue; + + CreatureRelocationNotifier relocate(*unit); + + TypeContainerVisitor<CreatureRelocationNotifier, WorldTypeMapContainer > c2world_relocation(relocate); + TypeContainerVisitor<CreatureRelocationNotifier, GridTypeMapContainer > c2grid_relocation(relocate); + + cell.Visit(p, c2world_relocation, i_map, *unit, i_radius); + cell.Visit(p, c2grid_relocation, i_map, *unit, i_radius); + } +} + +void DelayedUnitRelocation::Visit(PlayerMapType &m) +{ + for(PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter) + { + Player * player = iter->getSource(); + WorldObject const *viewPoint = player->m_seer; + + if(!viewPoint->isNeedNotify(NOTIFY_VISIBILITY_CHANGED)) + continue; + + if(player != viewPoint && !viewPoint->IsPositionValid()) + continue; + + CellPair pair2(Trinity::ComputeCellPair(viewPoint->GetPositionX(), viewPoint->GetPositionY())); + Cell cell2(pair2); + //cell.SetNoCreate(); need load cells around viewPoint or player, that's why its commented + + PlayerRelocationNotifier relocate(*player); + TypeContainerVisitor<PlayerRelocationNotifier, WorldTypeMapContainer > c2world_relocation(relocate); + TypeContainerVisitor<PlayerRelocationNotifier, GridTypeMapContainer > c2grid_relocation(relocate); + + cell2.Visit(pair2, c2world_relocation, i_map, *viewPoint, i_radius); + cell2.Visit(pair2, c2grid_relocation, i_map, *viewPoint, i_radius); + + relocate.SendToSelf(); + } +} + +void AIRelocationNotifier::Visit(CreatureMapType &m) +{ + for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter) + { + Creature *c = iter->getSource(); + CreatureUnitRelocationWorker(c, &i_unit); + if(isCreature) + CreatureUnitRelocationWorker((Creature*)&i_unit, c); + } +} + void MessageDistDeliverer::Visit(PlayerMapType &m) { diff --git a/src/game/GridNotifiers.h b/src/game/GridNotifiers.h index 9031794a6ac..c6c4ee30a87 100644 --- a/src/game/GridNotifiers.h +++ b/src/game/GridNotifiers.h @@ -40,41 +40,34 @@ namespace Trinity { struct 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)) {} + VisibleNotifier(Player &player) : i_player(player), vis_guids(player.m_clientGUIDs) {} template<class T> void Visit(GridRefManager<T> &m); - void Visit(CreatureMapType &m); - void Visit(PlayerMapType &m) {} void SendToSelf(void); }; - struct Player2PlayerNotifier : public VisibleNotifier + struct VisibleChangesNotifier { - Player2PlayerNotifier(Player &player, bool forced = false) : - VisibleNotifier(player, forced) {} + WorldObject &i_object; + explicit VisibleChangesNotifier(WorldObject &object) : i_object(object) {} template<class T> void Visit(GridRefManager<T> &) {} void Visit(PlayerMapType &); - void SendToSelf(void); + void Visit(CreatureMapType &); + void Visit(DynamicObjectMapType &); }; - struct PlayerRelocationNotifier + struct PlayerRelocationNotifier : public VisibleNotifier { - Player &i_player; - PlayerRelocationNotifier(Player &pl) : i_player(pl) {} - template<class T> void Visit(GridRefManager<T> &) {} - #ifdef WIN32 - template<> inline void Visit(CreatureMapType &); - #endif + PlayerRelocationNotifier(Player &pl) : VisibleNotifier(pl) {} + + template<class T> void Visit(GridRefManager<T> &m) { VisibleNotifier::Visit(m); } + void Visit(CreatureMapType &); + void Visit(PlayerMapType &); }; struct CreatureRelocationNotifier @@ -82,47 +75,31 @@ namespace Trinity Creature &i_creature; CreatureRelocationNotifier(Creature &c) : i_creature(c) {} template<class T> void Visit(GridRefManager<T> &) {} - #ifdef WIN32 - template<> inline void Visit(PlayerMapType &); - template<> inline void Visit(CreatureMapType &); - #endif - }; - - struct VisibleChangesNotifier - { - WorldObject &i_object; - - explicit VisibleChangesNotifier(WorldObject &object) : i_object(object) {} - template<class T> void Visit(GridRefManager<T> &) {} - void Visit(PlayerMapType &); void Visit(CreatureMapType &); - void Visit(DynamicObjectMapType &); + void Visit(PlayerMapType &); }; struct DelayedUnitRelocation { Map &i_map; - const Cell& i_cell; - const CellPair& i_cellPair; + Cell &cell; + CellPair &p; const float i_radius; - DelayedUnitRelocation(const Cell& cell, const CellPair& cellp, Map &map, float radius) : - i_cell(cell), i_cellPair(cellp), i_map(map), i_radius(radius) {} + DelayedUnitRelocation(Cell &c, CellPair &pair, Map &map, float radius) : + cell(c), p(pair), 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> &); + void Visit(CreatureMapType &); + void Visit(PlayerMapType &); }; - struct 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 AIRelocationNotifier + { + Unit &i_unit; + bool isCreature; + explicit AIRelocationNotifier(Unit &unit) : i_unit(unit), isCreature(unit.GetTypeId() == TYPEID_UNIT) {} + template<class T> void Visit(GridRefManager<T> &) {} + void Visit(CreatureMapType &); + }; struct GridUpdater { @@ -1225,11 +1202,5 @@ namespace Trinity std::vector<WorldPacketList> i_data_cache; // 0 = default, i => i-1 locale index }; - - #ifndef WIN32 - template<> inline void PlayerRelocationNotifier::Visit<Creature>(CreatureMapType &); - template<> inline void CreatureRelocationNotifier::Visit<Player>(PlayerMapType &); - template<> inline void CreatureRelocationNotifier::Visit<Creature>(CreatureMapType &); - #endif } #endif diff --git a/src/game/GridNotifiersImpl.h b/src/game/GridNotifiersImpl.h index 01eae14141b..09a4d64adfc 100644 --- a/src/game/GridNotifiersImpl.h +++ b/src/game/GridNotifiersImpl.h @@ -37,21 +37,7 @@ 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); + i_player.UpdateVisibilityOf(iter->getSource(),i_data,i_visibleNow); } } @@ -63,102 +49,6 @@ Trinity::ObjectUpdater::Visit(CreatureMapType &m) iter->getSource()->Update(i_timeDiff); } -inline void PlayerCreatureRelocationWorker(Player* pl, Creature* c) -{ - if(!pl->isAlive() || !c->isAlive() || pl->isInFlight()) - return; - - // Creature AI reaction - if(c->HasReactState(REACT_AGGRESSIVE) && !c->hasUnitState(UNIT_STAT_SIGHTLESS)) - if(c->_IsWithinDist(pl, c->m_SightDistance, true) && c->IsAIEnabled) - c->AI()->MoveInLineOfSight(pl); -} - -inline void CreatureCreatureRelocationWorker(Creature* c1, Creature* c2) -{ - if(c1->HasReactState(REACT_AGGRESSIVE) && !c1->hasUnitState(UNIT_STAT_SIGHTLESS)) - if(c1->_IsWithinDist(c2, c1->m_SightDistance, true) && c1->IsAIEnabled) - c1->AI()->MoveInLineOfSight(c2); - - if(c2->HasReactState(REACT_AGGRESSIVE) && !c2->hasUnitState(UNIT_STAT_SIGHTLESS)) - if(c1->_IsWithinDist(c2, c2->m_SightDistance, true) && c2->IsAIEnabled) - c2->AI()->MoveInLineOfSight(c1); -} - -template<class T, class VISITOR> -inline void -Trinity::DelayedUnitRelocation::Notify(GridRefManager<T> &m) -{ - for(typename GridRefManager<T>::iterator iter = m.begin(); iter != m.end(); ++iter) - { - T * unit = iter->getSource(); - if(!unit->isAlive() || !unit->isNeedNotify(NOTIFY_AI_RELOCATION)) - continue; - - VISITOR relocate(*unit); - TypeContainerVisitor<VISITOR, WorldTypeMapContainer > c2world_relocation(relocate); - TypeContainerVisitor<VISITOR, GridTypeMapContainer > c2grid_relocation(relocate); - - i_cell.Visit(i_cellPair, c2world_relocation, i_map, *unit, i_radius); - i_cell.Visit(i_cellPair, c2grid_relocation, i_map, *unit, i_radius); - - unit->SetNotified(NOTIFY_AI_RELOCATION); - } -} - -template<class T> -inline void -Trinity::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) - { - Creature * c = iter->getSource(); - if(c->isAlive() && !c->NotifyExecuted(NOTIFY_AI_RELOCATION)) - PlayerCreatureRelocationWorker(&i_player, c); - } -} - -template<> -inline void -Trinity::CreatureRelocationNotifier::Visit(PlayerMapType &m) -{ - if(!i_creature.isAlive()) - return; - - 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); - } -} - -template<> -inline void -Trinity::CreatureRelocationNotifier::Visit(CreatureMapType &m) -{ - if(!i_creature.isAlive()) - return; - - for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter) - { - Creature* c = iter->getSource(); - if( c != &i_creature && c->isAlive() && !c->NotifyExecuted(NOTIFY_AI_RELOCATION)) - CreatureCreatureRelocationWorker(c, &i_creature); - } -} - // SEARCHERS & LIST SEARCHERS & WORKERS // WorldObject searchers & workers diff --git a/src/game/Map.cpp b/src/game/Map.cpp index dbfe03f5ee3..52cef896809 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -214,10 +214,8 @@ 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_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_VisibilityNotifyPeriod(DEFAULT_VISIBILITY_NOTIFY_PERIOD), + i_scriptLock(false) { for (unsigned int idx=0; idx < MAX_NUMBER_OF_GRIDS; ++idx) { @@ -237,10 +235,7 @@ 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()); + m_VisibilityNotifyPeriod = World::GetVisibilityNotifyPeriodOnContinents(); } // Template specialization of utility methods @@ -333,23 +328,6 @@ void Map::DeleteFromWorld(Player* pl) delete pl; } -template<class T> -void Map::AddNotifier(T*) -{ -} - -template<> -void Map::AddNotifier(Player* obj) -{ - obj->AddToNotify(NOTIFY_VISIBILITY_CHANGED | NOTIFY_AI_RELOCATION | NOTIFY_PLAYER_VISIBILITY); -} - -template<> -void Map::AddNotifier(Creature* obj) -{ - obj->AddToNotify(NOTIFY_VISIBILITY_CHANGED | NOTIFY_AI_RELOCATION); -} - void Map::EnsureGridCreated(const GridPair &p) { @@ -452,14 +430,13 @@ bool Map::Add(Player *player) assert( grid != NULL ); AddToGrid(player, grid, cell); - player->ResetAllNotifies(); player->AddToWorld(); SendInitSelf(player); SendInitTransports(player); player->m_clientGUIDs.clear(); - AddNotifier<Player>(player); + player->UpdateObjectVisibility(true); return true; } @@ -478,8 +455,7 @@ Map::Add(T *obj) Cell cell(p); if(obj->IsInWorld()) // need some clean up later { - UpdateObjectVisibility(obj,cell,p); // is this needed? - AddNotifier(obj); + obj->UpdateObjectVisibility(true); return; } @@ -502,9 +478,7 @@ 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<T>(obj); + obj->UpdateObjectVisibility(true); } /* @@ -729,109 +703,33 @@ 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); - cell.Visit(cellpair, world_notifier, *this, *viewPoint, GetVisibilityDistance()); - - // send data - notifier.SendToSelf(); - player->RemoveFromNotify(NOTIFY_PLAYER_VISIBILITY); - player->SetNotified(NOTIFY_PLAYER_VISIBILITY); - } + if(!m_mapRefManager.isEmpty() || !m_activeNonPlayers.empty()) + ProcessRelocationNotifies(t_diff); } -void Map::ProcessObjectsVisibility() +struct ResetNotifier { - for(m_mapRefIter = m_mapRefManager.begin(); m_mapRefIter != m_mapRefManager.end(); ++m_mapRefIter) + template<class T>inline void resetNotify(GridRefManager<T> &m) { - 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); - cell.Visit(cellpair, world_notifier, *this, *viewPoint, GetVisibilityDistance()); - cell.Visit(cellpair, grid_notifier, *this, *viewPoint, GetVisibilityDistance()); - - // send data - notifier.SendToSelf(); - player->SetNotified(NOTIFY_VISIBILITY_CHANGED); + for(typename GridRefManager<T>::iterator iter=m.begin(); iter != m.end(); ++iter) + iter->getSource()->ResetAllNotifies(); } -} + template<class T> void Visit(GridRefManager<T> &) {} + void Visit(CreatureMapType &m) { resetNotify<Creature>(m);} + void Visit(PlayerMapType &m) { resetNotify<Player>(m);} +}; -void Map::ProcessRelocationNotifies() +void Map::ProcessRelocationNotifies(const uint32 & diff) { for(GridRefManager<NGridType>::iterator i = GridRefManager<NGridType>::begin(); i != GridRefManager<NGridType>::end(); ++i) { NGridType *grid = i->getSource(); - if(!grid || grid->GetGridState() != GRID_STATE_ACTIVE) + if (grid->GetGridState() != GRID_STATE_ACTIVE) + continue; + + grid->getGridInfoRef()->getRelocationTimer().TUpdate(diff); + if (!grid->getGridInfoRef()->getRelocationTimer().TPassed()) continue; uint32 gx = grid->getX(), gy = grid->getY(); @@ -849,39 +747,32 @@ void Map::ProcessRelocationNotifies() CellPair pair(x,y); Cell cell(pair); - cell.data.Part.reserved = CENTER_DISTRICT; cell.SetNoCreate(); Trinity::DelayedUnitRelocation cell_relocation(cell, pair, *this, GetVisibilityDistance()); TypeContainerVisitor<Trinity::DelayedUnitRelocation, GridTypeMapContainer > grid_object_relocation(cell_relocation); TypeContainerVisitor<Trinity::DelayedUnitRelocation, WorldTypeMapContainer > world_object_relocation(cell_relocation); - cell.Visit(pair, grid_object_relocation, *this); - cell.Visit(pair, world_object_relocation, *this); + Visit(cell, grid_object_relocation); + Visit(cell, world_object_relocation); } } } -} - -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); + ResetNotifier reset; + TypeContainerVisitor<ResetNotifier, GridTypeMapContainer > grid_notifier(reset); + TypeContainerVisitor<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) + if (grid->GetGridState() != GRID_STATE_ACTIVE) + continue; + + if (!grid->getGridInfoRef()->getRelocationTimer().TPassed()) continue; + grid->getGridInfoRef()->getRelocationTimer().TReset(diff, m_VisibilityNotifyPeriod); + uint32 gx = grid->getX(), gy = grid->getY(); CellPair cell_min(gx*MAX_NUMBER_OF_CELLS, gy*MAX_NUMBER_OF_CELLS); @@ -897,10 +788,9 @@ void Map::ResetNotifies(uint16 notify_mask) CellPair pair(x,y); Cell cell(pair); - cell.data.Part.reserved = CENTER_DISTRICT; cell.SetNoCreate(); - cell.Visit(pair, grid_notifier, *this); - cell.Visit(pair, world_notifier, *this); + Visit(cell, grid_notifier); + Visit(cell, world_notifier); } } } @@ -908,7 +798,6 @@ void Map::ResetNotifies(uint16 notify_mask) void Map::Remove(Player *player, bool remove) { - player->ResetAllNotifies(); player->RemoveFromWorld(); SendRemoveTransports(player); @@ -926,8 +815,8 @@ void Map::Remove(Player *player, bool remove) NGridType *grid = getNGrid(cell.GridX(), cell.GridY()); assert(grid != NULL); + player->UpdateObjectVisibility(true); RemoveFromGrid(player,grid,cell); - UpdateObjectVisibility(player,cell,p); } } @@ -952,7 +841,6 @@ template<class T> void Map::Remove(T *obj, bool remove) { - obj->ResetAllNotifies(); obj->RemoveFromWorld(); if (obj->isActiveObject()) RemoveFromActive(obj); @@ -969,8 +857,8 @@ Map::Remove(T *obj, bool remove) NGridType *grid = getNGrid(cell.GridX(), cell.GridY()); assert(grid != NULL); + obj->UpdateObjectVisibility(true); RemoveFromGrid(obj,grid,cell); - UpdateObjectVisibility(obj,cell,p); } } @@ -1012,7 +900,7 @@ Map::PlayerRelocation(Player *player, float x, float y, float z, float orientati AddToGrid(player, newGrid,new_cell); } - AddNotifier<Player>(player); + player->UpdateObjectVisibility(false); } void @@ -1038,7 +926,7 @@ Map::CreatureRelocation(Creature *creature, float x, float y, float z, float ang else { creature->Relocate(x, y, z, ang); - AddNotifier<Creature>(creature); + creature->UpdateObjectVisibility(false); } assert(CheckGridIntegrity(creature,true)); @@ -1072,7 +960,7 @@ void Map::MoveAllCreaturesInMoveList() // update pos c->Relocate(cm.x, cm.y, cm.z, cm.ang); //CreatureRelocationNotify(c,new_cell,new_cell.cellPair()); - AddNotifier<Creature>(c); + c->UpdateObjectVisibility(false); } else { @@ -1179,7 +1067,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()); - AddNotifier<Creature>(c); + c->UpdateObjectVisibility(false); return true; } else @@ -2176,21 +2064,9 @@ void Map::UpdateObjectVisibility( WorldObject* obj, Cell cell, CellPair cellpair cell.Visit(cellpair, player_notifier, *this, *obj, GetVisibilityDistance()); } - -void Map::UpdatePlayerVisibility( Player* player, Cell cell, CellPair cellpair ) -{ - cell.data.Part.reserved = ALL_DISTRICT; - - Trinity::Player2PlayerNotifier pl_notifier(*player); - TypeContainerVisitor<Trinity::Player2PlayerNotifier, WorldTypeMapContainer > player_notifier(pl_notifier); - - cell.Visit(cellpair, player_notifier, *this, *player, GetVisibilityDistance()); - pl_notifier.SendToSelf(); -} - void Map::UpdateObjectsVisibilityFor( Player* player, Cell cell, CellPair cellpair ) { - Trinity::VisibleNotifier notifier(*player, true); + Trinity::VisibleNotifier notifier(*player); cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); @@ -2556,10 +2432,7 @@ 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()); + m_VisibilityNotifyPeriod = World::GetVisibilityNotifyPeriodInInstances(); } /* @@ -2911,10 +2784,7 @@ 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()); + m_VisibilityNotifyPeriod = World::GetVisibilityNotifyPeriodInBGArenas(); } bool BattleGroundMap::CanEnter(Player * player) diff --git a/src/game/Map.h b/src/game/Map.h index 8bef03bf8ea..292431eeecb 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -379,7 +379,6 @@ class Map : public GridRefManager<NGridType>, public Trinity::ObjectLevelLockabl 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(); } @@ -491,9 +490,7 @@ class Map : public GridRefManager<NGridType>, public Trinity::ObjectLevelLockabl MapRefManager m_mapRefManager; MapRefManager::iterator m_mapRefIter; - PeriodicTimer m_ObjectVisibilityNotifyTimer; - PeriodicTimer m_PlayerVisibilityNotifyTimer; - PeriodicTimer m_RelocationNotifyTimer; + int32 m_VisibilityNotifyPeriod; typedef std::set<WorldObject*> ActiveNonPlayers; ActiveNonPlayers m_activeNonPlayers; @@ -510,10 +507,9 @@ class Map : public GridRefManager<NGridType>, public Trinity::ObjectLevelLockabl GridMap *GridMaps[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS]; std::bitset<TOTAL_NUMBER_OF_CELLS_PER_MAP*TOTAL_NUMBER_OF_CELLS_PER_MAP> marked_cells; - void ProcessObjectsVisibility(); - void ProcesssPlayersVisibility(); - void ProcessRelocationNotifies(); - void ResetNotifies(uint16 notify_mask); + //these functions used to process player/mob aggro reactions and + //visibility calculations. Highly optimized for massive calculations + void ProcessRelocationNotifies(const uint32 &diff); bool i_scriptLock; std::set<WorldObject *> i_objectsToRemove; @@ -526,9 +522,6 @@ class Map : public GridRefManager<NGridType>, public Trinity::ObjectLevelLockabl void AddToGrid(T*, NGridType *, Cell const&); template<class T> - void AddNotifier(T*); - - template<class T> void RemoveFromGrid(T*, NGridType *, Cell const&); template<class T> diff --git a/src/game/MapManager.h b/src/game/MapManager.h index 60e2255f8af..3f01c7e2f34 100644 --- a/src/game/MapManager.h +++ b/src/game/MapManager.h @@ -31,8 +31,6 @@ class Transport; -#define DEFAULT_VISIBILITY_NOTIFY_PERIOD 1100 - class MapManager : public Trinity::Singleton<MapManager, Trinity::ClassLevelLockable<MapManager, ACE_Thread_Mutex> > { diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp index 52853c57fd3..cf9515c3db9 100644 --- a/src/game/MiscHandler.cpp +++ b/src/game/MiscHandler.cpp @@ -1416,10 +1416,8 @@ void WorldSession::HandleFarSightOpcode( WorldPacket & recv_data ) sLog.outDebug("Unhandled mode in CMSG_FAR_SIGHT: %u", apply); return; } - // Update visibility after vision change - //Cell cell(pair); - //GetPlayer()->GetMap()->UpdateObjectsVisibilityFor(_player, cell, pair); - GetPlayer()->SetToNotify(); + + GetPlayer()->UpdateVisibilityForPlayer(); } void WorldSession::HandleSetTitleOpcode( WorldPacket & recv_data ) diff --git a/src/game/NPCHandler.cpp b/src/game/NPCHandler.cpp index fc2c590745a..dad51d76586 100644 --- a/src/game/NPCHandler.cpp +++ b/src/game/NPCHandler.cpp @@ -425,13 +425,11 @@ void WorldSession::SendSpiritResurrect() _player->TeleportTo(corpseGrave->map_id, corpseGrave->x, corpseGrave->y, corpseGrave->z, _player->GetOrientation()); // or update at original position else - //ObjectAccessor::UpdateVisibilityForPlayer(_player); - _player->SetToNotify(); + _player->UpdateObjectVisibility(); } // or update at original position else - //ObjectAccessor::UpdateVisibilityForPlayer(_player); - _player->SetToNotify(); + _player->UpdateObjectVisibility(); } void WorldSession::HandleBinderActivateOpcode( WorldPacket & recv_data ) diff --git a/src/game/Object.cpp b/src/game/Object.cpp index 4e0f7c01964..40cac8a7891 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -2272,12 +2272,11 @@ void WorldObject::DestroyForNearbyPlayers() } } -void WorldObject::UpdateObjectVisibility() +void WorldObject::UpdateObjectVisibility(bool /*forced*/) { - CellPair p = Trinity::ComputeCellPair(GetPositionX(), GetPositionY()); - Cell cell(p); - - GetMap()->UpdateObjectVisibility(this, cell, p); + //updates object's visibility for nearby players + Trinity::VisibleChangesNotifier notifier(*this); + VisitNearbyWorldObject(GetMap()->GetVisibilityDistance(), notifier); } struct WorldObjectChangeAccumulator diff --git a/src/game/Object.h b/src/game/Object.h index 0b4b71c13a5..d54c510a646 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -98,7 +98,6 @@ enum NotifyFlags NOTIFY_NONE = 0x00, NOTIFY_AI_RELOCATION = 0x01, NOTIFY_VISIBILITY_CHANGED = 0x02, - NOTIFY_PLAYER_VISIBILITY = 0x04, NOTIFY_ALL = 0xFF }; @@ -656,19 +655,16 @@ class WorldObject : public Object, public WorldLocation void GetCreatureListWithEntryInGrid(std::list<Creature*>& lList, uint32 uiEntry, float fMaxSearchRange); void DestroyForNearbyPlayers(); - void UpdateObjectVisibility(); + virtual void UpdateObjectVisibility(bool forced = true); void BuildUpdate(UpdateDataMapType& ); - //new relocation and visibility system functions + //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;} - + uint16 GetNotifyFlags() const { return m_notifyflags; } 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); diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 1a5e2720525..73fedb9d7fe 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -2374,8 +2374,7 @@ void Player::SetGameMaster(bool on) getHostilRefManager().setOnlineOfflineState(true); } - //ObjectAccessor::UpdateVisibilityForPlayer(this); - SetToNotify(); + UpdateObjectVisibility(); } void Player::SetGMVisible(bool on) @@ -4446,8 +4445,7 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness) sOutdoorPvPMgr.HandlePlayerResurrects(this, newzone); // update visibility - //ObjectAccessor::UpdateVisibilityForPlayer(this); - SetToNotify(); + UpdateObjectVisibility(); if(!applySickness) return; @@ -20123,6 +20121,27 @@ template void Player::UpdateVisibilityOf(Corpse* target, UpdateData& data 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::UpdateObjectVisibility(bool forced) +{ + if (!forced) + AddToNotify(NOTIFY_VISIBILITY_CHANGED); + else + { + Unit::UpdateObjectVisibility(true); + // updates visibility of all objects around point of view for current player + Trinity::VisibleNotifier notifier(*this); + m_seer->VisitNearbyObject(GetMap()->GetVisibilityDistance(), notifier); + notifier.SendToSelf(); // send gathered data + } +} + +void Player::UpdateVisibilityForPlayer() +{ + Trinity::VisibleNotifier notifier(*this); + m_seer->VisitNearbyObject(GetMap()->GetVisibilityDistance(), notifier); + notifier.SendToSelf(); // send gathered data +} + void Player::InitPrimaryProfessions() { SetFreePrimaryProfessions(sWorld.getConfig(CONFIG_MAX_PRIMARY_TRADE_SKILL)); diff --git a/src/game/Player.h b/src/game/Player.h index ae179894121..e6f97770949 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -2180,8 +2180,10 @@ class Player : public Unit, public GridObject<Player> bool IsVisibleInGridForPlayer(Player const* pl) const; bool IsVisibleGloballyFor(Player* pl) const; - void UpdateVisibilityOf(WorldObject* target); void SendInitialVisiblePackets(Unit* target); + void UpdateObjectVisibility(bool forced = true); + void UpdateVisibilityForPlayer(); + void UpdateVisibilityOf(WorldObject* target); template<class T> void UpdateVisibilityOf(T* target, UpdateData& data, std::set<Unit*>& visibleNow); diff --git a/src/game/SpellAuraEffects.cpp b/src/game/SpellAuraEffects.cpp index f9cf199e90f..c352a72ef4f 100644 --- a/src/game/SpellAuraEffects.cpp +++ b/src/game/SpellAuraEffects.cpp @@ -2554,7 +2554,7 @@ void AuraEffect::HandleInvisibilityDetect(AuraApplication const * aurApp, uint8 target->m_detectInvisibilityMask |= (1 << GetMiscValue()); } if(target->GetTypeId() == TYPEID_PLAYER) - target->SetToNotify(); + target->UpdateObjectVisibility(); } void AuraEffect::HandleInvisibility(AuraApplication const * aurApp, uint8 mode, bool apply) const @@ -2578,7 +2578,7 @@ void AuraEffect::HandleInvisibility(AuraApplication const * aurApp, uint8 mode, if(target->GetTypeId() == TYPEID_PLAYER) target->SetFlag(PLAYER_FIELD_BYTES2,PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW); - target->SetToNotify(); + target->UpdateObjectVisibility(); } else { @@ -2593,7 +2593,7 @@ void AuraEffect::HandleInvisibility(AuraApplication const * aurApp, uint8 mode, if(!target->m_invisibilityMask && target->GetTypeId() == TYPEID_PLAYER) target->RemoveFlag(PLAYER_FIELD_BYTES2,PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW); - target->SetToNotify(); + target->UpdateObjectVisibility(); } } diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index e92fcfad94f..c0d100f2bd4 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -11697,26 +11697,7 @@ bool Unit::canDetectStealthOf(Unit const* target, float distance) const void Unit::SetVisibility(UnitVisibility x) { m_Visibility = x; - - 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(); + UpdateObjectVisibility(); } void Unit::UpdateSpeed(UnitMoveType mtype, bool forced) @@ -13034,7 +13015,6 @@ void Unit::AddToWorld() if (!IsInWorld()) { WorldObject::AddToWorld(); - SetToNotify(); } } @@ -14539,14 +14519,6 @@ bool Unit::HandleAuraRaidProcFromCharge(AuraEffect* triggeredByAura) } /*-----------------------TRINITY-----------------------------*/ -void Unit::SetToNotify() -{ - 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) { // Prevent killing unit twice (and giving reward from kill twice) @@ -15483,6 +15455,19 @@ void Unit::SetPhaseMask(uint32 newPhaseMask, bool update) summon->SetPhaseMask(newPhaseMask,true); } +void Unit::UpdateObjectVisibility(bool forced) +{ + if (!forced) + AddToNotify(NOTIFY_VISIBILITY_CHANGED); + else + { + WorldObject::UpdateObjectVisibility(true); + // call MoveInLineOfSight for nearby creatures + Trinity::AIRelocationNotifier notifier(*this); + VisitNearbyObject(GetMap()->GetVisibilityDistance(), notifier); + } +} + void Unit::KnockbackFrom(float x, float y, float speedXY, float speedZ) { Player *player = NULL; diff --git a/src/game/Unit.h b/src/game/Unit.h index 1390d9eb09e..d30f694e88d 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -1734,6 +1734,7 @@ class Unit : public WorldObject bool canDetectInvisibilityOf(Unit const* u) const; bool canDetectStealthOf(Unit const* u, float distance) const; void SetPhaseMask(uint32 newPhaseMask, bool update);// overwrite WorldObject::SetPhaseMask + void UpdateObjectVisibility(bool forced = true); // virtual functions for all world objects types bool isVisibleForInState(Player const* u, bool inVisibleList) const; @@ -1903,9 +1904,6 @@ class Unit : public WorldObject uint32 GetModelForForm(ShapeshiftForm form); - // relocation notification - void SetToNotify(); - void SetReducedThreatPercent(uint32 pct, uint64 guid) { m_reducedThreatPercent = pct; |