diff options
Diffstat (limited to 'src/game/GridNotifiers.cpp')
-rw-r--r-- | src/game/GridNotifiers.cpp | 188 |
1 files changed, 137 insertions, 51 deletions
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) { |