[8483] Implement glyph 43361.
[getmangos.git] / src / game / GridNotifiers.h
blob38fbd1704c44546c8a7b5a3047a4d00a30c37431
1 /*
2 * Copyright (C) 2005-2009 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_GRIDNOTIFIERS_H
20 #define MANGOS_GRIDNOTIFIERS_H
22 #include "ObjectGridLoader.h"
23 #include "ByteBuffer.h"
24 #include "UpdateData.h"
25 #include <iostream>
27 #include "Corpse.h"
28 #include "Object.h"
29 #include "DynamicObject.h"
30 #include "GameObject.h"
31 #include "Player.h"
32 #include "Unit.h"
33 #include "CreatureAI.h"
35 class Player;
36 //class Map;
38 namespace MaNGOS
41 struct MANGOS_DLL_DECL PlayerNotifier
43 explicit PlayerNotifier(Player &pl) : i_player(pl) {}
44 void Visit(PlayerMapType &);
45 template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
46 Player &i_player;
49 struct MANGOS_DLL_DECL VisibleNotifier
51 Player &i_player;
52 UpdateData i_data;
53 UpdateDataMapType i_data_updates;
54 Player::ClientGUIDs i_clientGUIDs;
55 std::set<WorldObject*> i_visibleNow;
57 explicit VisibleNotifier(Player &player) : i_player(player),i_clientGUIDs(player.m_clientGUIDs) {}
58 template<class T> void Visit(GridRefManager<T> &m);
59 void Visit(PlayerMapType &);
60 void Notify(void);
63 struct MANGOS_DLL_DECL VisibleChangesNotifier
65 WorldObject &i_object;
67 explicit VisibleChangesNotifier(WorldObject &object) : i_object(object) {}
68 template<class T> void Visit(GridRefManager<T> &) {}
69 void Visit(PlayerMapType &);
72 struct MANGOS_DLL_DECL GridUpdater
74 GridType &i_grid;
75 uint32 i_timeDiff;
76 GridUpdater(GridType &grid, uint32 diff) : i_grid(grid), i_timeDiff(diff) {}
78 template<class T> void updateObjects(GridRefManager<T> &m)
80 for(typename GridRefManager<T>::iterator iter = m.begin(); iter != m.end(); ++iter)
81 iter->getSource()->Update(i_timeDiff);
84 void Visit(PlayerMapType &m) { updateObjects<Player>(m); }
85 void Visit(CreatureMapType &m){ updateObjects<Creature>(m); }
86 void Visit(GameObjectMapType &m) { updateObjects<GameObject>(m); }
87 void Visit(DynamicObjectMapType &m) { updateObjects<DynamicObject>(m); }
88 void Visit(CorpseMapType &m) { updateObjects<Corpse>(m); }
91 struct MANGOS_DLL_DECL MessageDeliverer
93 Player &i_player;
94 WorldPacket *i_message;
95 bool i_toSelf;
96 MessageDeliverer(Player &pl, WorldPacket *msg, bool to_self) : i_player(pl), i_message(msg), i_toSelf(to_self) {}
97 void Visit(PlayerMapType &m);
98 template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
101 struct MANGOS_DLL_DECL ObjectMessageDeliverer
103 uint32 i_phaseMask;
104 WorldPacket *i_message;
105 explicit ObjectMessageDeliverer(WorldObject& obj, WorldPacket *msg)
106 : i_phaseMask(obj.GetPhaseMask()), i_message(msg) {}
107 void Visit(PlayerMapType &m);
108 template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
111 struct MANGOS_DLL_DECL MessageDistDeliverer
113 Player &i_player;
114 WorldPacket *i_message;
115 bool i_toSelf;
116 bool i_ownTeamOnly;
117 float i_dist;
119 MessageDistDeliverer(Player &pl, WorldPacket *msg, float dist, bool to_self, bool ownTeamOnly)
120 : i_player(pl), i_message(msg), i_toSelf(to_self), i_ownTeamOnly(ownTeamOnly), i_dist(dist) {}
121 void Visit(PlayerMapType &m);
122 template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
125 struct MANGOS_DLL_DECL ObjectMessageDistDeliverer
127 WorldObject &i_object;
128 WorldPacket *i_message;
129 float i_dist;
130 ObjectMessageDistDeliverer(WorldObject &obj, WorldPacket *msg, float dist) : i_object(obj), i_message(msg), i_dist(dist) {}
131 void Visit(PlayerMapType &m);
132 template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
135 struct MANGOS_DLL_DECL ObjectUpdater
137 uint32 i_timeDiff;
138 explicit ObjectUpdater(const uint32 &diff) : i_timeDiff(diff) {}
139 template<class T> void Visit(GridRefManager<T> &m);
140 void Visit(PlayerMapType &) {}
141 void Visit(CorpseMapType &) {}
142 void Visit(CreatureMapType &);
145 template<class T>
146 struct MANGOS_DLL_DECL ObjectAccessorNotifier
148 T *& i_object;
150 uint64 i_id;
151 ObjectAccessorNotifier(T * &obj, uint64 id) : i_object(obj), i_id(id)
153 i_object = NULL;
156 void Visit(GridRefManager<T> &m )
158 if( i_object == NULL )
160 GridRefManager<T> *iter = m.find(i_id);
161 if( iter != m.end() )
163 assert( iter->second != NULL );
164 i_object = iter->second;
169 template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
172 struct MANGOS_DLL_DECL PlayerRelocationNotifier
174 Player &i_player;
175 PlayerRelocationNotifier(Player &pl) : i_player(pl) {}
176 template<class T> void Visit(GridRefManager<T> &) {}
177 void Visit(PlayerMapType &);
178 void Visit(CreatureMapType &);
181 struct MANGOS_DLL_DECL CreatureRelocationNotifier
183 Creature &i_creature;
184 CreatureRelocationNotifier(Creature &c) : i_creature(c) {}
185 template<class T> void Visit(GridRefManager<T> &) {}
186 #ifdef WIN32
187 template<> void Visit(PlayerMapType &);
188 #endif
191 struct MANGOS_DLL_DECL DynamicObjectUpdater
193 DynamicObject &i_dynobject;
194 Unit* i_check;
195 DynamicObjectUpdater(DynamicObject &dynobject, Unit* caster) : i_dynobject(dynobject)
197 i_check = caster;
198 Unit* owner = i_check->GetOwner();
199 if(owner)
200 i_check = owner;
203 template<class T> inline void Visit(GridRefManager<T> &) {}
204 #ifdef WIN32
205 template<> inline void Visit<Player>(PlayerMapType &);
206 template<> inline void Visit<Creature>(CreatureMapType &);
207 #endif
209 void VisitHelper(Unit* target);
212 // SEARCHERS & LIST SEARCHERS & WORKERS
214 // WorldObject searchers & workers
216 template<class Check>
217 struct MANGOS_DLL_DECL WorldObjectSearcher
219 uint32 i_phaseMask;
220 WorldObject* &i_object;
221 Check &i_check;
223 WorldObjectSearcher(WorldObject const* searcher, WorldObject* & result, Check& check)
224 : i_phaseMask(searcher->GetPhaseMask()), i_object(result),i_check(check) {}
226 void Visit(GameObjectMapType &m);
227 void Visit(PlayerMapType &m);
228 void Visit(CreatureMapType &m);
229 void Visit(CorpseMapType &m);
230 void Visit(DynamicObjectMapType &m);
232 template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
235 template<class Check>
236 struct MANGOS_DLL_DECL WorldObjectListSearcher
238 uint32 i_phaseMask;
239 std::list<WorldObject*> &i_objects;
240 Check& i_check;
242 WorldObjectListSearcher(WorldObject const* searcher, std::list<WorldObject*> &objects, Check & check)
243 : i_phaseMask(searcher->GetPhaseMask()), i_objects(objects),i_check(check) {}
245 void Visit(PlayerMapType &m);
246 void Visit(CreatureMapType &m);
247 void Visit(CorpseMapType &m);
248 void Visit(GameObjectMapType &m);
249 void Visit(DynamicObjectMapType &m);
251 template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
254 template<class Do>
255 struct MANGOS_DLL_DECL WorldObjectWorker
257 uint32 i_phaseMask;
258 Do const& i_do;
260 WorldObjectWorker(WorldObject const* searcher, Do const& _do)
261 : i_phaseMask(searcher->GetPhaseMask()), i_do(_do) {}
263 void Visit(GameObjectMapType &m)
265 for(GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
266 if(itr->getSource()->InSamePhase(i_phaseMask))
267 i_do(itr->getSource());
270 void Visit(PlayerMapType &m)
272 for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
273 if(itr->getSource()->InSamePhase(i_phaseMask))
274 i_do(itr->getSource());
276 void Visit(CreatureMapType &m)
278 for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
279 if(itr->getSource()->InSamePhase(i_phaseMask))
280 i_do(itr->getSource());
283 void Visit(CorpseMapType &m)
285 for(CorpseMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
286 if(itr->getSource()->InSamePhase(i_phaseMask))
287 i_do(itr->getSource());
290 void Visit(DynamicObjectMapType &m)
292 for(DynamicObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
293 if(itr->getSource()->InSamePhase(i_phaseMask))
294 i_do(itr->getSource());
297 template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
300 // Gameobject searchers
302 template<class Check>
303 struct MANGOS_DLL_DECL GameObjectSearcher
305 uint32 i_phaseMask;
306 GameObject* &i_object;
307 Check &i_check;
309 GameObjectSearcher(WorldObject const* searcher, GameObject* & result, Check& check)
310 : i_phaseMask(searcher->GetPhaseMask()), i_object(result),i_check(check) {}
312 void Visit(GameObjectMapType &m);
314 template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
317 // Last accepted by Check GO if any (Check can change requirements at each call)
318 template<class Check>
319 struct MANGOS_DLL_DECL GameObjectLastSearcher
321 uint32 i_phaseMask;
322 GameObject* &i_object;
323 Check& i_check;
325 GameObjectLastSearcher(WorldObject const* searcher, GameObject* & result, Check& check)
326 : i_phaseMask(searcher->GetPhaseMask()), i_object(result), i_check(check) {}
328 void Visit(GameObjectMapType &m);
330 template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
333 template<class Check>
334 struct MANGOS_DLL_DECL GameObjectListSearcher
336 uint32 i_phaseMask;
337 std::list<GameObject*> &i_objects;
338 Check& i_check;
340 GameObjectListSearcher(WorldObject const* searcher, std::list<GameObject*> &objects, Check & check)
341 : i_phaseMask(searcher->GetPhaseMask()), i_objects(objects), i_check(check) {}
343 void Visit(GameObjectMapType &m);
345 template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
348 // Unit searchers
350 // First accepted by Check Unit if any
351 template<class Check>
352 struct MANGOS_DLL_DECL UnitSearcher
354 uint32 i_phaseMask;
355 Unit* &i_object;
356 Check & i_check;
358 UnitSearcher(WorldObject const* searcher, Unit* & result, Check & check)
359 : i_phaseMask(searcher->GetPhaseMask()), i_object(result),i_check(check) {}
361 void Visit(CreatureMapType &m);
362 void Visit(PlayerMapType &m);
364 template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
367 // Last accepted by Check Unit if any (Check can change requirements at each call)
368 template<class Check>
369 struct MANGOS_DLL_DECL UnitLastSearcher
371 uint32 i_phaseMask;
372 Unit* &i_object;
373 Check & i_check;
375 UnitLastSearcher(WorldObject const* searcher, Unit* & result, Check & check)
376 : i_phaseMask(searcher->GetPhaseMask()), i_object(result),i_check(check) {}
378 void Visit(CreatureMapType &m);
379 void Visit(PlayerMapType &m);
381 template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
384 // All accepted by Check units if any
385 template<class Check>
386 struct MANGOS_DLL_DECL UnitListSearcher
388 uint32 i_phaseMask;
389 std::list<Unit*> &i_objects;
390 Check& i_check;
392 UnitListSearcher(WorldObject const* searcher, std::list<Unit*> &objects, Check & check)
393 : i_phaseMask(searcher->GetPhaseMask()), i_objects(objects),i_check(check) {}
395 void Visit(PlayerMapType &m);
396 void Visit(CreatureMapType &m);
398 template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
401 // Creature searchers
403 template<class Check>
404 struct MANGOS_DLL_DECL CreatureSearcher
406 uint32 i_phaseMask;
407 Creature* &i_object;
408 Check & i_check;
410 CreatureSearcher(WorldObject const* searcher, Creature* & result, Check & check)
411 : i_phaseMask(searcher->GetPhaseMask()), i_object(result),i_check(check) {}
413 void Visit(CreatureMapType &m);
415 template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
418 // Last accepted by Check Creature if any (Check can change requirements at each call)
419 template<class Check>
420 struct MANGOS_DLL_DECL CreatureLastSearcher
422 uint32 i_phaseMask;
423 Creature* &i_object;
424 Check & i_check;
426 CreatureLastSearcher(WorldObject const* searcher, Creature* & result, Check & check)
427 : i_phaseMask(searcher->GetPhaseMask()), i_object(result),i_check(check) {}
429 void Visit(CreatureMapType &m);
431 template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
434 template<class Check>
435 struct MANGOS_DLL_DECL CreatureListSearcher
437 uint32 i_phaseMask;
438 std::list<Creature*> &i_objects;
439 Check& i_check;
441 CreatureListSearcher(WorldObject const* searcher, std::list<Creature*> &objects, Check & check)
442 : i_phaseMask(searcher->GetPhaseMask()), i_objects(objects),i_check(check) {}
444 void Visit(CreatureMapType &m);
446 template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
449 template<class Do>
450 struct MANGOS_DLL_DECL CreatureWorker
452 uint32 i_phaseMask;
453 Do& i_do;
455 CreatureWorker(WorldObject const* searcher, Do& _do)
456 : i_phaseMask(searcher->GetPhaseMask()), i_do(_do) {}
458 void Visit(CreatureMapType &m)
460 for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
461 if(itr->getSource()->InSamePhase(i_phaseMask))
462 i_do(itr->getSource());
465 template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
468 // Player searchers
470 template<class Check>
471 struct MANGOS_DLL_DECL PlayerSearcher
473 uint32 i_phaseMask;
474 Player* &i_object;
475 Check & i_check;
477 PlayerSearcher(WorldObject const* searcher, Player* & result, Check & check)
478 : i_phaseMask(searcher->GetPhaseMask()), i_object(result),i_check(check) {}
480 void Visit(PlayerMapType &m);
482 template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
485 template<class Do>
486 struct MANGOS_DLL_DECL PlayerWorker
488 uint32 i_phaseMask;
489 Do& i_do;
491 PlayerWorker(WorldObject const* searcher, Do& _do)
492 : i_phaseMask(searcher->GetPhaseMask()), i_do(_do) {}
494 void Visit(PlayerMapType &m)
496 for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
497 if(itr->getSource()->InSamePhase(i_phaseMask))
498 i_do(itr->getSource());
501 template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
504 template<class Do>
505 struct MANGOS_DLL_DECL PlayerDistWorker
507 WorldObject const* i_searcher;
508 float i_dist;
509 Do& i_do;
511 PlayerDistWorker(WorldObject const* searcher, float _dist, Do& _do)
512 : i_searcher(searcher), i_dist(_dist), i_do(_do) {}
514 void Visit(PlayerMapType &m)
516 for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
517 if (itr->getSource()->InSamePhase(i_searcher) && itr->getSource()->IsWithinDist(i_searcher,i_dist))
518 i_do(itr->getSource());
521 template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
524 // CHECKS && DO classes
526 // WorldObject check classes
527 class RaiseDeadObjectCheck
529 public:
530 RaiseDeadObjectCheck(Unit* funit, float range) : i_funit(funit), i_range(range) {}
531 bool operator()(Creature* u)
533 if (i_funit->GetTypeId()!=TYPEID_PLAYER || !((Player*)i_funit)->isHonorOrXPTarget(u) ||
534 u->getDeathState() != CORPSE || u->isDeadByDefault() || u->isInFlight() ||
535 ( u->GetCreatureTypeMask() & (1 << (CREATURE_TYPE_HUMANOID-1)) )==0 ||
536 (u->GetDisplayId() != u->GetNativeDisplayId()))
537 return false;
539 return i_funit->IsWithinDistInMap(u, i_range);
541 template<class NOT_INTERESTED> bool operator()(NOT_INTERESTED*) { return false; }
542 private:
543 Unit* const i_funit;
544 float i_range;
547 class ExplodeCorpseObjectCheck
549 public:
550 ExplodeCorpseObjectCheck(Unit* funit, float range) : i_funit(funit), i_range(range) {}
551 bool operator()(Player* u)
553 if (u->getDeathState()!=CORPSE || u->isInFlight() ||
554 u->HasAuraType(SPELL_AURA_GHOST) || (u->GetDisplayId() != u->GetNativeDisplayId()))
555 return false;
557 return i_funit->IsWithinDistInMap(u, i_range);
559 bool operator()(Creature* u)
561 if (u->getDeathState()!=CORPSE || u->isInFlight() || u->isDeadByDefault() ||
562 (u->GetDisplayId() != u->GetNativeDisplayId()) ||
563 (u->GetCreatureTypeMask() & CREATURE_TYPEMASK_MECHANICAL_OR_ELEMENTAL)!=0)
564 return false;
566 return i_funit->IsWithinDistInMap(u, i_range);
568 template<class NOT_INTERESTED> bool operator()(NOT_INTERESTED*) { return false; }
569 private:
570 Unit* const i_funit;
571 float i_range;
574 class CannibalizeObjectCheck
576 public:
577 CannibalizeObjectCheck(Unit* funit, float range) : i_funit(funit), i_range(range) {}
578 bool operator()(Player* u)
580 if( i_funit->IsFriendlyTo(u) || u->isAlive() || u->isInFlight() )
581 return false;
583 return i_funit->IsWithinDistInMap(u, i_range);
585 bool operator()(Corpse* u);
586 bool operator()(Creature* u)
588 if (i_funit->IsFriendlyTo(u) || u->isAlive() || u->isInFlight() ||
589 (u->GetCreatureTypeMask() & CREATURE_TYPEMASK_HUMANOID_OR_UNDEAD)==0)
590 return false;
592 return i_funit->IsWithinDistInMap(u, i_range);
594 template<class NOT_INTERESTED> bool operator()(NOT_INTERESTED*) { return false; }
595 private:
596 Unit* const i_funit;
597 float i_range;
600 // WorldObject do classes
602 class RespawnDo
604 public:
605 RespawnDo() {}
606 void operator()(Creature* u) const { u->Respawn(); }
607 void operator()(GameObject* u) const { u->Respawn(); }
608 void operator()(WorldObject*) const {}
609 void operator()(Corpse*) const {}
612 // GameObject checks
614 class GameObjectFocusCheck
616 public:
617 GameObjectFocusCheck(Unit const* unit,uint32 focusId) : i_unit(unit), i_focusId(focusId) {}
618 bool operator()(GameObject* go) const
620 if(go->GetGOInfo()->type != GAMEOBJECT_TYPE_SPELL_FOCUS)
621 return false;
623 if(go->GetGOInfo()->spellFocus.focusId != i_focusId)
624 return false;
626 float dist = go->GetGOInfo()->spellFocus.dist;
628 return go->IsWithinDistInMap(i_unit, dist);
630 private:
631 Unit const* i_unit;
632 uint32 i_focusId;
635 // Find the nearest Fishing hole and return true only if source object is in range of hole
636 class NearestGameObjectFishingHole
638 public:
639 NearestGameObjectFishingHole(WorldObject const& obj, float range) : i_obj(obj), i_range(range) {}
640 bool operator()(GameObject* go)
642 if(go->GetGOInfo()->type == GAMEOBJECT_TYPE_FISHINGHOLE && go->isSpawned() && i_obj.IsWithinDistInMap(go, i_range) && i_obj.IsWithinDistInMap(go, go->GetGOInfo()->fishinghole.radius))
644 i_range = i_obj.GetDistance(go);
645 return true;
647 return false;
649 float GetLastRange() const { return i_range; }
650 private:
651 WorldObject const& i_obj;
652 float i_range;
654 // prevent clone
655 NearestGameObjectFishingHole(NearestGameObjectFishingHole const&);
658 // Success at unit in range, range update for next check (this can be use with GameobjectLastSearcher to find nearest GO)
659 class NearestGameObjectEntryInObjectRangeCheck
661 public:
662 NearestGameObjectEntryInObjectRangeCheck(WorldObject const& obj,uint32 entry, float range) : i_obj(obj), i_entry(entry), i_range(range) {}
663 bool operator()(GameObject* go)
665 if(go->GetEntry() == i_entry && i_obj.IsWithinDistInMap(go, i_range))
667 i_range = i_obj.GetDistance(go); // use found GO range as new range limit for next check
668 return true;
670 return false;
672 float GetLastRange() const { return i_range; }
673 private:
674 WorldObject const& i_obj;
675 uint32 i_entry;
676 float i_range;
678 // prevent clone this object
679 NearestGameObjectEntryInObjectRangeCheck(NearestGameObjectEntryInObjectRangeCheck const&);
682 class GameObjectWithDbGUIDCheck
684 public:
685 GameObjectWithDbGUIDCheck(WorldObject const& obj,uint32 db_guid) : i_obj(obj), i_db_guid(db_guid) {}
686 bool operator()(GameObject const* go) const
688 return go->GetDBTableGUIDLow() == i_db_guid;
690 private:
691 WorldObject const& i_obj;
692 uint32 i_db_guid;
695 // Unit checks
697 class MostHPMissingInRange
699 public:
700 MostHPMissingInRange(Unit const* obj, float range, uint32 hp) : i_obj(obj), i_range(range), i_hp(hp) {}
701 bool operator()(Unit* u)
703 if(u->isAlive() && u->isInCombat() && !i_obj->IsHostileTo(u) && i_obj->IsWithinDistInMap(u, i_range) && u->GetMaxHealth() - u->GetHealth() > i_hp)
705 i_hp = u->GetMaxHealth() - u->GetHealth();
706 return true;
708 return false;
710 private:
711 Unit const* i_obj;
712 float i_range;
713 uint32 i_hp;
716 class FriendlyCCedInRange
718 public:
719 FriendlyCCedInRange(Unit const* obj, float range) : i_obj(obj), i_range(range) {}
720 bool operator()(Unit* u)
722 if(u->isAlive() && u->isInCombat() && !i_obj->IsHostileTo(u) && i_obj->IsWithinDistInMap(u, i_range) &&
723 (u->isFeared() || u->isCharmed() || u->isFrozen() || u->hasUnitState(UNIT_STAT_STUNNED) || u->hasUnitState(UNIT_STAT_CONFUSED)))
725 return true;
727 return false;
729 private:
730 Unit const* i_obj;
731 float i_range;
734 class FriendlyMissingBuffInRange
736 public:
737 FriendlyMissingBuffInRange(Unit const* obj, float range, uint32 spellid) : i_obj(obj), i_range(range), i_spell(spellid) {}
738 bool operator()(Unit* u)
740 if(u->isAlive() && u->isInCombat() && !i_obj->IsHostileTo(u) && i_obj->IsWithinDistInMap(u, i_range) &&
741 !(u->HasAura(i_spell, 0) || u->HasAura(i_spell, 1) || u->HasAura(i_spell, 2)))
743 return true;
745 return false;
747 private:
748 Unit const* i_obj;
749 float i_range;
750 uint32 i_spell;
753 class AnyUnfriendlyUnitInObjectRangeCheck
755 public:
756 AnyUnfriendlyUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range) : i_obj(obj), i_funit(funit), i_range(range) {}
757 bool operator()(Unit* u)
759 if(u->isAlive() && i_obj->IsWithinDistInMap(u, i_range) && !i_funit->IsFriendlyTo(u))
760 return true;
761 else
762 return false;
764 private:
765 WorldObject const* i_obj;
766 Unit const* i_funit;
767 float i_range;
770 class AnyUnfriendlyVisibleUnitInObjectRangeCheck
772 public:
773 AnyUnfriendlyVisibleUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range)
774 : i_obj(obj), i_funit(funit), i_range(range) {}
776 bool operator()(Unit* u)
778 return u->isAlive()
779 && i_obj->IsWithinDistInMap(u, i_range)
780 && !i_funit->IsFriendlyTo(u)
781 && u->isVisibleForOrDetect(i_funit,i_funit,false);
783 private:
784 WorldObject const* i_obj;
785 Unit const* i_funit;
786 float i_range;
789 class AnyFriendlyUnitInObjectRangeCheck
791 public:
792 AnyFriendlyUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range) : i_obj(obj), i_funit(funit), i_range(range) {}
793 bool operator()(Unit* u)
795 if(u->isAlive() && i_obj->IsWithinDistInMap(u, i_range) && i_funit->IsFriendlyTo(u))
796 return true;
797 else
798 return false;
800 private:
801 WorldObject const* i_obj;
802 Unit const* i_funit;
803 float i_range;
806 class AnyUnitInObjectRangeCheck
808 public:
809 AnyUnitInObjectRangeCheck(WorldObject const* obj, float range) : i_obj(obj), i_range(range) {}
810 bool operator()(Unit* u)
812 if(u->isAlive() && i_obj->IsWithinDistInMap(u, i_range))
813 return true;
815 return false;
817 private:
818 WorldObject const* i_obj;
819 float i_range;
822 // Success at unit in range, range update for next check (this can be use with UnitLastSearcher to find nearest unit)
823 class NearestAttackableUnitInObjectRangeCheck
825 public:
826 NearestAttackableUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range) : i_obj(obj), i_funit(funit), i_range(range) {}
827 bool operator()(Unit* u)
829 if( u->isTargetableForAttack() && i_obj->IsWithinDistInMap(u, i_range) &&
830 !i_funit->IsFriendlyTo(u) && u->isVisibleForOrDetect(i_funit,i_funit,false) )
832 i_range = i_obj->GetDistance(u); // use found unit range as new range limit for next check
833 return true;
836 return false;
838 private:
839 WorldObject const* i_obj;
840 Unit const* i_funit;
841 float i_range;
843 // prevent clone this object
844 NearestAttackableUnitInObjectRangeCheck(NearestAttackableUnitInObjectRangeCheck const&);
847 class AnyAoETargetUnitInObjectRangeCheck
849 public:
850 AnyAoETargetUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range, bool hitHidden = true)
851 : i_obj(obj), i_funit(funit), i_range(range), i_hitHidden(hitHidden)
853 Unit const* check = i_funit;
854 Unit const* owner = i_funit->GetOwner();
855 if(owner)
856 check = owner;
857 i_targetForPlayer = ( check->GetTypeId()==TYPEID_PLAYER );
859 bool operator()(Unit* u)
861 // Check contains checks for: live, non-selectable, non-attackable flags, flight check and GM check, ignore totems
862 if (!u->isTargetableForAttack())
863 return false;
864 if(u->GetTypeId()==TYPEID_UNIT && ((Creature*)u)->isTotem())
865 return false;
866 if (!i_hitHidden && !u->isVisibleForOrDetect(i_funit, i_funit, false))
867 return false;
869 if(( i_targetForPlayer ? !i_funit->IsFriendlyTo(u) : i_funit->IsHostileTo(u) )&& i_obj->IsWithinDistInMap(u, i_range))
870 return true;
872 return false;
874 private:
875 bool i_targetForPlayer;
876 WorldObject const* i_obj;
877 Unit const* i_funit;
878 float i_range;
879 bool i_hitHidden;
882 // do attack at call of help to friendly crearture
883 class CallOfHelpCreatureInRangeDo
885 public:
886 CallOfHelpCreatureInRangeDo(Unit* funit, Unit* enemy, float range)
887 : i_funit(funit), i_enemy(enemy), i_range(range)
889 void operator()(Creature* u)
891 if (u == i_funit)
892 return;
894 if (!u->CanAssistTo(i_funit, i_enemy, false))
895 return;
897 // too far
898 if (!i_funit->IsWithinDistInMap(u, i_range))
899 return;
901 // only if see assisted creature
902 if (!i_funit->IsWithinLOSInMap(u))
903 return;
905 if (u->AI())
906 u->AI()->AttackStart(i_enemy);
908 private:
909 Unit* const i_funit;
910 Unit* const i_enemy;
911 float i_range;
914 struct AnyDeadUnitCheck
916 bool operator()(Unit* u) { return !u->isAlive(); }
919 struct AnyStealthedCheck
921 bool operator()(Unit* u) { return u->GetVisibility()==VISIBILITY_GROUP_STEALTH; }
924 // Creature checks
926 class InAttackDistanceFromAnyHostileCreatureCheck
928 public:
929 explicit InAttackDistanceFromAnyHostileCreatureCheck(Unit* funit) : i_funit(funit) {}
930 bool operator()(Creature* u)
932 if(u->isAlive() && u->IsHostileTo(i_funit) && i_funit->IsWithinDistInMap(u, u->GetAttackDistance(i_funit)))
933 return true;
935 return false;
937 private:
938 Unit* const i_funit;
941 class AnyAssistCreatureInRangeCheck
943 public:
944 AnyAssistCreatureInRangeCheck(Unit* funit, Unit* enemy, float range)
945 : i_funit(funit), i_enemy(enemy), i_range(range)
948 bool operator()(Creature* u)
950 if(u == i_funit)
951 return false;
953 if ( !u->CanAssistTo(i_funit, i_enemy) )
954 return false;
956 // too far
957 if( !i_funit->IsWithinDistInMap(u, i_range) )
958 return false;
960 // only if see assisted creature
961 if( !i_funit->IsWithinLOSInMap(u) )
962 return false;
964 return true;
966 private:
967 Unit* const i_funit;
968 Unit* const i_enemy;
969 float i_range;
972 class NearestAssistCreatureInCreatureRangeCheck
974 public:
975 NearestAssistCreatureInCreatureRangeCheck(Creature* obj, Unit* enemy, float range)
976 : i_obj(obj), i_enemy(enemy), i_range(range) {}
978 bool operator()(Creature* u)
980 if(u == i_obj)
981 return false;
982 if(!u->CanAssistTo(i_obj,i_enemy))
983 return false;
985 if(!i_obj->IsWithinDistInMap(u, i_range))
986 return false;
988 if(!i_obj->IsWithinLOSInMap(u))
989 return false;
991 i_range = i_obj->GetDistance(u); // use found unit range as new range limit for next check
992 return true;
994 float GetLastRange() const { return i_range; }
995 private:
996 Creature* const i_obj;
997 Unit* const i_enemy;
998 float i_range;
1000 // prevent clone this object
1001 NearestAssistCreatureInCreatureRangeCheck(NearestAssistCreatureInCreatureRangeCheck const&);
1004 // Success at unit in range, range update for next check (this can be use with CreatureLastSearcher to find nearest creature)
1005 class NearestCreatureEntryWithLiveStateInObjectRangeCheck
1007 public:
1008 NearestCreatureEntryWithLiveStateInObjectRangeCheck(WorldObject const& obj,uint32 entry, bool alive, float range)
1009 : i_obj(obj), i_entry(entry), i_alive(alive), i_range(range) {}
1011 bool operator()(Creature* u)
1013 if(u->GetEntry() == i_entry && u->isAlive()==i_alive && i_obj.IsWithinDistInMap(u, i_range))
1015 i_range = i_obj.GetDistance(u); // use found unit range as new range limit for next check
1016 return true;
1018 return false;
1020 float GetLastRange() const { return i_range; }
1021 private:
1022 WorldObject const& i_obj;
1023 uint32 i_entry;
1024 bool i_alive;
1025 float i_range;
1027 // prevent clone this object
1028 NearestCreatureEntryWithLiveStateInObjectRangeCheck(NearestCreatureEntryWithLiveStateInObjectRangeCheck const&);
1031 class AnyPlayerInObjectRangeCheck
1033 public:
1034 AnyPlayerInObjectRangeCheck(WorldObject const* obj, float range) : i_obj(obj), i_range(range) {}
1035 bool operator()(Player* u)
1037 if(u->isAlive() && i_obj->IsWithinDistInMap(u, i_range))
1038 return true;
1040 return false;
1042 private:
1043 WorldObject const* i_obj;
1044 float i_range;
1047 // Player checks and do
1049 // Prepare using Builder localized packets with caching and send to player
1050 template<class Builder>
1051 class LocalizedPacketDo
1053 public:
1054 explicit LocalizedPacketDo(Builder& builder) : i_builder(builder) {}
1056 ~LocalizedPacketDo()
1058 for(size_t i = 0; i < i_data_cache.size(); ++i)
1059 delete i_data_cache[i];
1061 void operator()( Player* p );
1063 private:
1064 Builder& i_builder;
1065 std::vector<WorldPacket*> i_data_cache; // 0 = default, i => i-1 locale index
1068 // Prepare using Builder localized packets with caching and send to player
1069 template<class Builder>
1070 class LocalizedPacketListDo
1072 public:
1073 typedef std::vector<WorldPacket*> WorldPacketList;
1074 explicit LocalizedPacketListDo(Builder& builder) : i_builder(builder) {}
1076 ~LocalizedPacketListDo()
1078 for(size_t i = 0; i < i_data_cache.size(); ++i)
1079 for(size_t j = 0; j < i_data_cache[i].size(); ++j)
1080 delete i_data_cache[i][j];
1082 void operator()( Player* p );
1084 private:
1085 Builder& i_builder;
1086 std::vector<WorldPacketList> i_data_cache;
1087 // 0 = default, i => i-1 locale index
1090 #ifndef WIN32
1091 template<> void PlayerRelocationNotifier::Visit<Creature>(CreatureMapType &);
1092 template<> void PlayerRelocationNotifier::Visit<Player>(PlayerMapType &);
1093 template<> void CreatureRelocationNotifier::Visit<Player>(PlayerMapType &);
1094 template<> void CreatureRelocationNotifier::Visit<Creature>(CreatureMapType &);
1095 template<> inline void DynamicObjectUpdater::Visit<Creature>(CreatureMapType &);
1096 template<> inline void DynamicObjectUpdater::Visit<Player>(PlayerMapType &);
1097 #endif
1099 #endif