void VisibleNotifier::Notify() { Player& player = *i_camera.GetOwner(); // 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 = player.GetTransport()) { for(Transport::PlayerSet::const_iterator itr = transport->GetPassengers().begin();itr!=transport->GetPassengers().end();++itr) { if (i_clientGUIDs.find((*itr)->GetObjectGuid()) != i_clientGUIDs.end()) { // ignore far sight case (*itr)->UpdateVisibilityOf(*itr, &player); player.UpdateVisibilityOf(&player, *itr, i_data, i_visibleNow); i_clientGUIDs.erase((*itr)->GetObjectGuid()); } } } // generate outOfRange for not iterate objects i_data.AddOutOfRangeGUID(i_clientGUIDs); for(GuidSet::iterator itr = i_clientGUIDs.begin();itr!=i_clientGUIDs.end();++itr) { player.m_clientGUIDs.erase(*itr); DEBUG_FILTER_LOG(LOG_FILTER_VISIBILITY_CHANGES, "%s is out of range (no in active cells set) now for %s", itr->GetString().c_str(), player.GetGuidStr().c_str()); } if (i_data.HasData()) { // send create/outofrange packet to player (except player create updates that already sent using SendUpdateToPlayer) WorldPacket packet; i_data.BuildPacket(&packet); player.GetSession()->SendPacket(&packet); // send out of range to other players if need GuidSet const& oor = i_data.GetOutOfRangeGUIDs(); for(GuidSet::const_iterator iter = oor.begin(); iter != oor.end(); ++iter) { if (!iter->IsPlayer()) continue; if (Player* plr = ObjectAccessor::FindPlayer(*iter)) plr->UpdateVisibilityOf(plr->GetCamera().GetBody(), &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) != &player && (*vItr)->isType(TYPEMASK_UNIT)) player.SendAuraDurationsForTarget((Unit*)(*vItr)); } }
void VisibleNotifier::SendToSelf() { // at this moment i_clientGUIDs have guids that not iterate at grid level checks // but exist one case when this possible and object not out of range: transports if (Transport* transport = i_player.GetTransport()) { for (Transport::PassengerSet::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()); switch ((*itr)->GetTypeId()) { case TYPEID_GAMEOBJECT: i_player.UpdateVisibilityOf((*itr)->ToGameObject(), i_data, i_visibleNow); break; case TYPEID_PLAYER: i_player.UpdateVisibilityOf((*itr)->ToPlayer(), i_data, i_visibleNow); if (!(*itr)->isNeedNotify(NOTIFY_VISIBILITY_CHANGED)) (*itr)->ToPlayer()->UpdateVisibilityOf(&i_player); break; case TYPEID_UNIT: i_player.UpdateVisibilityOf((*itr)->ToCreature(), i_data, i_visibleNow); break; case TYPEID_DYNAMICOBJECT: i_player.UpdateVisibilityOf((*itr)->ToDynObject(), i_data, i_visibleNow); break; default: break; } } } } for (GuidSet::const_iterator it = vis_guids.begin(); it != vis_guids.end(); ++it) { i_player.m_clientGUIDs.erase(*it); i_data.AddOutOfRangeGUID(*it); if (it->IsPlayer()) { Player* player = ObjectAccessor::FindPlayer(*it); if (player && !player->isNeedNotify(NOTIFY_VISIBILITY_CHANGED)) player->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); }