[9290] Some cleanups in realmd, no functional changes
[getmangos.git] / src / game / GridNotifiersImpl.h
blob79e6351082b78efe5dc271bc56f960679e4e2afe
1 /*
2 * Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #ifndef MANGOS_GRIDNOTIFIERSIMPL_H
20 #define MANGOS_GRIDNOTIFIERSIMPL_H
22 #include "GridNotifiers.h"
23 #include "WorldPacket.h"
24 #include "Corpse.h"
25 #include "Player.h"
26 #include "UpdateData.h"
27 #include "CreatureAI.h"
28 #include "SpellAuras.h"
30 template<class T>
31 inline void
32 MaNGOS::VisibleNotifier::Visit(GridRefManager<T> &m)
34 WorldObject const* viewPoint = i_player.GetViewPoint();
36 for(typename GridRefManager<T>::iterator iter = m.begin(); iter != m.end(); ++iter)
38 i_player.UpdateVisibilityOf(viewPoint,iter->getSource(),i_data,i_data_updates,i_visibleNow);
39 i_clientGUIDs.erase(iter->getSource()->GetGUID());
43 inline void
44 MaNGOS::ObjectUpdater::Visit(CreatureMapType &m)
46 for(CreatureMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
47 iter->getSource()->Update(i_timeDiff);
50 inline void
51 MaNGOS::PlayerRelocationNotifier::Visit(PlayerMapType &m)
53 for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
55 if(&i_player==iter->getSource())
56 continue;
58 // visibility for players updated by ObjectAccessor::UpdateVisibilityFor calls in appropriate places
60 // Cancel Trade
61 if(i_player.GetTrader()==iter->getSource())
62 // iteraction distance
63 if(!i_player.IsWithinDistInMap(iter->getSource(), 5))
64 i_player.GetSession()->SendCancelTrade(); // will clode both side trade windows
68 inline void PlayerCreatureRelocationWorker(Player* pl, WorldObject const* viewPoint, Creature* c)
70 // update creature visibility at player/creature move
71 pl->UpdateVisibilityOf(viewPoint,c);
73 // Creature AI reaction
74 if(!c->hasUnitState(UNIT_STAT_FLEEING))
76 if( c->AI() && c->AI()->IsVisible(pl) && !c->IsInEvadeMode() )
77 c->AI()->MoveInLineOfSight(pl);
81 inline void CreatureCreatureRelocationWorker(Creature* c1, Creature* c2)
83 if(!c1->hasUnitState(UNIT_STAT_FLEEING))
85 if( c1->AI() && c1->AI()->IsVisible(c2) && !c1->IsInEvadeMode() )
86 c1->AI()->MoveInLineOfSight(c2);
89 if(!c2->hasUnitState(UNIT_STAT_FLEEING))
91 if( c2->AI() && c2->AI()->IsVisible(c1) && !c2->IsInEvadeMode() )
92 c2->AI()->MoveInLineOfSight(c1);
96 inline void
97 MaNGOS::PlayerRelocationNotifier::Visit(CreatureMapType &m)
99 if(!i_player.isAlive() || i_player.isInFlight())
100 return;
102 WorldObject const* viewPoint = i_player.GetViewPoint();
104 for(CreatureMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
105 if (iter->getSource()->isAlive())
106 PlayerCreatureRelocationWorker(&i_player,viewPoint,iter->getSource());
109 template<>
110 inline void
111 MaNGOS::CreatureRelocationNotifier::Visit(PlayerMapType &m)
113 if(!i_creature.isAlive())
114 return;
116 for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
117 if (Player* player = iter->getSource())
118 if (player->isAlive() && !player->isInFlight())
119 PlayerCreatureRelocationWorker(player, player->GetViewPoint(), &i_creature);
122 template<>
123 inline void
124 MaNGOS::CreatureRelocationNotifier::Visit(CreatureMapType &m)
126 if(!i_creature.isAlive())
127 return;
129 for(CreatureMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
131 Creature* c = iter->getSource();
132 if( c != &i_creature && c->isAlive())
133 CreatureCreatureRelocationWorker(c, &i_creature);
137 inline void MaNGOS::DynamicObjectUpdater::VisitHelper(Unit* target)
139 if(!target->isAlive() || target->isInFlight() )
140 return;
142 if(target->GetTypeId()==TYPEID_UNIT && ((Creature*)target)->isTotem())
143 return;
145 if (!i_dynobject.IsWithinDistInMap(target, i_dynobject.GetRadius()))
146 return;
148 //Check targets for not_selectable unit flag and remove
149 if (target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE))
150 return;
152 // Evade target
153 if( target->GetTypeId()==TYPEID_UNIT && ((Creature*)target)->IsInEvadeMode() )
154 return;
156 //Check player targets and remove if in GM mode or GM invisibility (for not self casting case)
157 if( target->GetTypeId()==TYPEID_PLAYER && target != i_check && (((Player*)target)->isGameMaster() || ((Player*)target)->GetVisibility()==VISIBILITY_OFF) )
158 return;
160 if (i_check->GetTypeId()==TYPEID_PLAYER )
162 if (i_check->IsFriendlyTo( target ))
163 return;
165 else
167 if (!i_check->IsHostileTo( target ))
168 return;
171 if (i_dynobject.IsAffecting(target))
172 return;
174 SpellEntry const *spellInfo = sSpellStore.LookupEntry(i_dynobject.GetSpellId());
175 uint32 eff_index = i_dynobject.GetEffIndex();
176 // Check target immune to spell or aura
177 if (target->IsImmunedToSpell(spellInfo) || target->IsImmunedToSpellEffect(spellInfo, eff_index))
178 return;
179 // Apply PersistentAreaAura on target
180 PersistentAreaAura* Aur = new PersistentAreaAura(spellInfo, eff_index, NULL, target, i_dynobject.GetCaster());
181 target->AddAura(Aur);
182 i_dynobject.AddAffected(target);
185 template<>
186 inline void
187 MaNGOS::DynamicObjectUpdater::Visit(CreatureMapType &m)
189 for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
190 VisitHelper(itr->getSource());
193 template<>
194 inline void
195 MaNGOS::DynamicObjectUpdater::Visit(PlayerMapType &m)
197 for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
198 VisitHelper(itr->getSource());
201 // SEARCHERS & LIST SEARCHERS & WORKERS
203 // WorldObject searchers & workers
205 template<class Check>
206 void MaNGOS::WorldObjectSearcher<Check>::Visit(GameObjectMapType &m)
208 // already found
209 if(i_object)
210 return;
212 for(GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
214 if(!itr->getSource()->InSamePhase(i_phaseMask))
215 continue;
217 if (i_check(itr->getSource()))
219 i_object = itr->getSource();
220 return;
225 template<class Check>
226 void MaNGOS::WorldObjectSearcher<Check>::Visit(PlayerMapType &m)
228 // already found
229 if(i_object)
230 return;
232 for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
234 if(!itr->getSource()->InSamePhase(i_phaseMask))
235 continue;
237 if(i_check(itr->getSource()))
239 i_object = itr->getSource();
240 return;
245 template<class Check>
246 void MaNGOS::WorldObjectSearcher<Check>::Visit(CreatureMapType &m)
248 // already found
249 if(i_object)
250 return;
252 for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
254 if(!itr->getSource()->InSamePhase(i_phaseMask))
255 continue;
257 if(i_check(itr->getSource()))
259 i_object = itr->getSource();
260 return;
265 template<class Check>
266 void MaNGOS::WorldObjectSearcher<Check>::Visit(CorpseMapType &m)
268 // already found
269 if(i_object)
270 return;
272 for(CorpseMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
274 if(!itr->getSource()->InSamePhase(i_phaseMask))
275 continue;
277 if(i_check(itr->getSource()))
279 i_object = itr->getSource();
280 return;
285 template<class Check>
286 void MaNGOS::WorldObjectSearcher<Check>::Visit(DynamicObjectMapType &m)
288 // already found
289 if(i_object)
290 return;
292 for(DynamicObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
294 if(!itr->getSource()->InSamePhase(i_phaseMask))
295 continue;
297 if(i_check(itr->getSource()))
299 i_object = itr->getSource();
300 return;
305 template<class Check>
306 void MaNGOS::WorldObjectListSearcher<Check>::Visit(PlayerMapType &m)
308 for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
309 if(itr->getSource()->InSamePhase(i_phaseMask))
310 if(i_check(itr->getSource()))
311 i_objects.push_back(itr->getSource());
314 template<class Check>
315 void MaNGOS::WorldObjectListSearcher<Check>::Visit(CreatureMapType &m)
317 for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
318 if(itr->getSource()->InSamePhase(i_phaseMask))
319 if(i_check(itr->getSource()))
320 i_objects.push_back(itr->getSource());
323 template<class Check>
324 void MaNGOS::WorldObjectListSearcher<Check>::Visit(CorpseMapType &m)
326 for(CorpseMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
327 if(itr->getSource()->InSamePhase(i_phaseMask))
328 if(i_check(itr->getSource()))
329 i_objects.push_back(itr->getSource());
332 template<class Check>
333 void MaNGOS::WorldObjectListSearcher<Check>::Visit(GameObjectMapType &m)
335 for(GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
336 if(itr->getSource()->InSamePhase(i_phaseMask))
337 if(i_check(itr->getSource()))
338 i_objects.push_back(itr->getSource());
341 template<class Check>
342 void MaNGOS::WorldObjectListSearcher<Check>::Visit(DynamicObjectMapType &m)
344 for(DynamicObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
345 if(itr->getSource()->InSamePhase(i_phaseMask))
346 if(i_check(itr->getSource()))
347 i_objects.push_back(itr->getSource());
350 // Gameobject searchers
352 template<class Check>
353 void MaNGOS::GameObjectSearcher<Check>::Visit(GameObjectMapType &m)
355 // already found
356 if(i_object)
357 return;
359 for(GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
361 if(!itr->getSource()->InSamePhase(i_phaseMask))
362 continue;
364 if(i_check(itr->getSource()))
366 i_object = itr->getSource();
367 return;
372 template<class Check>
373 void MaNGOS::GameObjectLastSearcher<Check>::Visit(GameObjectMapType &m)
375 for(GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
377 if(!itr->getSource()->InSamePhase(i_phaseMask))
378 continue;
380 if(i_check(itr->getSource()))
381 i_object = itr->getSource();
385 template<class Check>
386 void MaNGOS::GameObjectListSearcher<Check>::Visit(GameObjectMapType &m)
388 for(GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
389 if(itr->getSource()->InSamePhase(i_phaseMask))
390 if(i_check(itr->getSource()))
391 i_objects.push_back(itr->getSource());
394 // Unit searchers
396 template<class Check>
397 void MaNGOS::UnitSearcher<Check>::Visit(CreatureMapType &m)
399 // already found
400 if(i_object)
401 return;
403 for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
405 if(!itr->getSource()->InSamePhase(i_phaseMask))
406 continue;
408 if(i_check(itr->getSource()))
410 i_object = itr->getSource();
411 return;
416 template<class Check>
417 void MaNGOS::UnitSearcher<Check>::Visit(PlayerMapType &m)
419 // already found
420 if(i_object)
421 return;
423 for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
425 if(!itr->getSource()->InSamePhase(i_phaseMask))
426 continue;
428 if(i_check(itr->getSource()))
430 i_object = itr->getSource();
431 return;
436 template<class Check>
437 void MaNGOS::UnitLastSearcher<Check>::Visit(CreatureMapType &m)
439 for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
441 if(!itr->getSource()->InSamePhase(i_phaseMask))
442 continue;
444 if(i_check(itr->getSource()))
445 i_object = itr->getSource();
449 template<class Check>
450 void MaNGOS::UnitLastSearcher<Check>::Visit(PlayerMapType &m)
452 for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
454 if(!itr->getSource()->InSamePhase(i_phaseMask))
455 continue;
457 if(i_check(itr->getSource()))
458 i_object = itr->getSource();
462 template<class Check>
463 void MaNGOS::UnitListSearcher<Check>::Visit(PlayerMapType &m)
465 for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
466 if(itr->getSource()->InSamePhase(i_phaseMask))
467 if(i_check(itr->getSource()))
468 i_objects.push_back(itr->getSource());
471 template<class Check>
472 void MaNGOS::UnitListSearcher<Check>::Visit(CreatureMapType &m)
474 for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
475 if(itr->getSource()->InSamePhase(i_phaseMask))
476 if(i_check(itr->getSource()))
477 i_objects.push_back(itr->getSource());
480 // Creature searchers
482 template<class Check>
483 void MaNGOS::CreatureSearcher<Check>::Visit(CreatureMapType &m)
485 // already found
486 if(i_object)
487 return;
489 for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
491 if(!itr->getSource()->InSamePhase(i_phaseMask))
492 continue;
494 if(i_check(itr->getSource()))
496 i_object = itr->getSource();
497 return;
502 template<class Check>
503 void MaNGOS::CreatureLastSearcher<Check>::Visit(CreatureMapType &m)
505 for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
507 if(!itr->getSource()->InSamePhase(i_phaseMask))
508 continue;
510 if(i_check(itr->getSource()))
511 i_object = itr->getSource();
515 template<class Check>
516 void MaNGOS::CreatureListSearcher<Check>::Visit(CreatureMapType &m)
518 for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
519 if(itr->getSource()->InSamePhase(i_phaseMask))
520 if( i_check(itr->getSource()))
521 i_objects.push_back(itr->getSource());
524 template<class Check>
525 void MaNGOS::PlayerSearcher<Check>::Visit(PlayerMapType &m)
527 // already found
528 if(i_object)
529 return;
531 for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
533 if(!itr->getSource()->InSamePhase(i_phaseMask))
534 continue;
536 if(i_check(itr->getSource()))
538 i_object = itr->getSource();
539 return;
544 template<class Builder>
545 void MaNGOS::LocalizedPacketDo<Builder>::operator()( Player* p )
547 int32 loc_idx = p->GetSession()->GetSessionDbLocaleIndex();
548 uint32 cache_idx = loc_idx+1;
549 WorldPacket* data;
551 // create if not cached yet
552 if(i_data_cache.size() < cache_idx+1 || !i_data_cache[cache_idx])
554 if(i_data_cache.size() < cache_idx+1)
555 i_data_cache.resize(cache_idx+1);
557 data = new WorldPacket(SMSG_MESSAGECHAT, 200);
559 i_builder(*data,loc_idx);
561 i_data_cache[cache_idx] = data;
563 else
564 data = i_data_cache[cache_idx];
566 p->SendDirectMessage(data);
569 template<class Builder>
570 void MaNGOS::LocalizedPacketListDo<Builder>::operator()( Player* p )
572 int32 loc_idx = p->GetSession()->GetSessionDbLocaleIndex();
573 uint32 cache_idx = loc_idx+1;
574 WorldPacketList* data_list;
576 // create if not cached yet
577 if(i_data_cache.size() < cache_idx+1 || i_data_cache[cache_idx].empty())
579 if(i_data_cache.size() < cache_idx+1)
580 i_data_cache.resize(cache_idx+1);
582 data_list = &i_data_cache[cache_idx];
584 i_builder(*data_list,loc_idx);
586 else
587 data_list = &i_data_cache[cache_idx];
589 for(size_t i = 0; i < data_list->size(); ++i)
590 p->SendDirectMessage((*data_list)[i]);
593 #endif // MANGOS_GRIDNOTIFIERSIMPL_H