2 * Copyright (C) 2005-2008 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"
29 #include "DynamicObject.h"
30 #include "GameObject.h"
40 struct MANGOS_DLL_DECL PlayerNotifier
42 explicit PlayerNotifier(Player
&pl
) : i_player(pl
) {}
43 void Visit(PlayerMapType
&);
44 template<class SKIP
> void Visit(GridRefManager
<SKIP
> &) {}
48 struct MANGOS_DLL_DECL VisibleNotifier
52 UpdateDataMapType i_data_updates
;
53 Player::ClientGUIDs i_clientGUIDs
;
54 std::set
<WorldObject
*> i_visibleNow
;
56 explicit VisibleNotifier(Player
&player
) : i_player(player
),i_clientGUIDs(player
.m_clientGUIDs
) {}
57 template<class T
> void Visit(GridRefManager
<T
> &m
);
58 void Visit(PlayerMapType
&);
62 struct MANGOS_DLL_DECL VisibleChangesNotifier
64 WorldObject
&i_object
;
66 explicit VisibleChangesNotifier(WorldObject
&object
) : i_object(object
) {}
67 template<class T
> void Visit(GridRefManager
<T
> &) {}
68 void Visit(PlayerMapType
&);
71 struct MANGOS_DLL_DECL GridUpdater
75 GridUpdater(GridType
&grid
, uint32 diff
) : i_grid(grid
), i_timeDiff(diff
) {}
77 template<class T
> void updateObjects(GridRefManager
<T
> &m
)
79 for(typename GridRefManager
<T
>::iterator iter
= m
.begin(); iter
!= m
.end(); ++iter
)
80 iter
->getSource()->Update(i_timeDiff
);
83 void Visit(PlayerMapType
&m
) { updateObjects
<Player
>(m
); }
84 void Visit(CreatureMapType
&m
){ updateObjects
<Creature
>(m
); }
85 void Visit(GameObjectMapType
&m
) { updateObjects
<GameObject
>(m
); }
86 void Visit(DynamicObjectMapType
&m
) { updateObjects
<DynamicObject
>(m
); }
87 void Visit(CorpseMapType
&m
) { updateObjects
<Corpse
>(m
); }
90 struct MANGOS_DLL_DECL MessageDeliverer
93 WorldPacket
*i_message
;
95 MessageDeliverer(Player
&pl
, WorldPacket
*msg
, bool to_self
) : i_player(pl
), i_message(msg
), i_toSelf(to_self
) {}
96 void Visit(PlayerMapType
&m
);
97 template<class SKIP
> void Visit(GridRefManager
<SKIP
> &) {}
100 struct MANGOS_DLL_DECL ObjectMessageDeliverer
102 WorldPacket
*i_message
;
103 explicit ObjectMessageDeliverer(WorldPacket
*msg
) : i_message(msg
) {}
104 void Visit(PlayerMapType
&m
);
105 template<class SKIP
> void Visit(GridRefManager
<SKIP
> &) {}
108 struct MANGOS_DLL_DECL MessageDistDeliverer
111 WorldPacket
*i_message
;
115 MessageDistDeliverer(Player
&pl
, WorldPacket
*msg
, float dist
, bool to_self
, bool ownTeamOnly
) : i_player(pl
), i_message(msg
), i_dist(dist
), i_toSelf(to_self
), i_ownTeamOnly(ownTeamOnly
) {}
116 void Visit(PlayerMapType
&m
);
117 template<class SKIP
> void Visit(GridRefManager
<SKIP
> &) {}
120 struct MANGOS_DLL_DECL ObjectMessageDistDeliverer
122 WorldObject
&i_object
;
123 WorldPacket
*i_message
;
125 ObjectMessageDistDeliverer(WorldObject
&obj
, WorldPacket
*msg
, float dist
) : i_object(obj
), i_message(msg
), i_dist(dist
) {}
126 void Visit(PlayerMapType
&m
);
127 template<class SKIP
> void Visit(GridRefManager
<SKIP
> &) {}
130 struct MANGOS_DLL_DECL ObjectUpdater
133 explicit ObjectUpdater(const uint32
&diff
) : i_timeDiff(diff
) {}
134 template<class T
> void Visit(GridRefManager
<T
> &m
);
135 void Visit(PlayerMapType
&) {}
136 void Visit(CorpseMapType
&) {}
137 void Visit(CreatureMapType
&);
141 struct MANGOS_DLL_DECL ObjectAccessorNotifier
146 ObjectAccessorNotifier(T
* &obj
, uint64 id
) : i_object(obj
), i_id(id
)
151 void Visit(GridRefManager
<T
> &m
)
153 if( i_object
== NULL
)
155 GridRefManager
<T
> *iter
= m
.find(i_id
);
156 if( iter
!= m
.end() )
158 assert( iter
->second
!= NULL
);
159 i_object
= iter
->second
;
164 template<class NOT_INTERESTED
> void Visit(GridRefManager
<NOT_INTERESTED
> &) {}
167 struct MANGOS_DLL_DECL PlayerRelocationNotifier
170 PlayerRelocationNotifier(Player
&pl
) : i_player(pl
) {}
171 template<class T
> void Visit(GridRefManager
<T
> &) {}
172 void Visit(PlayerMapType
&);
173 void Visit(CreatureMapType
&);
176 struct MANGOS_DLL_DECL CreatureRelocationNotifier
178 Creature
&i_creature
;
179 CreatureRelocationNotifier(Creature
&c
) : i_creature(c
) {}
180 template<class T
> void Visit(GridRefManager
<T
> &) {}
182 template<> void Visit(PlayerMapType
&);
186 struct MANGOS_DLL_DECL DynamicObjectUpdater
188 DynamicObject
&i_dynobject
;
190 DynamicObjectUpdater(DynamicObject
&dynobject
, Unit
* caster
) : i_dynobject(dynobject
)
193 Unit
* owner
= i_check
->GetOwner();
198 template<class T
> inline void Visit(GridRefManager
<T
> &) {}
200 template<> inline void Visit
<Player
>(PlayerMapType
&);
201 template<> inline void Visit
<Creature
>(CreatureMapType
&);
204 void VisitHelper(Unit
* target
);
207 // SEARCHERS & LIST SEARCHERS & WORKERS
209 // WorldObject searchers & workers
211 template<class Check
>
212 struct MANGOS_DLL_DECL WorldObjectSearcher
214 WorldObject
* &i_object
;
217 WorldObjectSearcher(WorldObject
* & result
, Check
& check
) : i_object(result
),i_check(check
) {}
219 void Visit(GameObjectMapType
&m
);
220 void Visit(PlayerMapType
&m
);
221 void Visit(CreatureMapType
&m
);
222 void Visit(CorpseMapType
&m
);
223 void Visit(DynamicObjectMapType
&m
);
225 template<class NOT_INTERESTED
> void Visit(GridRefManager
<NOT_INTERESTED
> &) {}
228 template<class Check
>
229 struct MANGOS_DLL_DECL WorldObjectListSearcher
231 std::list
<WorldObject
*> &i_objects
;
234 WorldObjectListSearcher(std::list
<WorldObject
*> &objects
, Check
& check
) : i_objects(objects
),i_check(check
) {}
236 void Visit(PlayerMapType
&m
);
237 void Visit(CreatureMapType
&m
);
238 void Visit(CorpseMapType
&m
);
239 void Visit(GameObjectMapType
&m
);
240 void Visit(DynamicObjectMapType
&m
);
242 template<class NOT_INTERESTED
> void Visit(GridRefManager
<NOT_INTERESTED
> &) {}
246 struct MANGOS_DLL_DECL WorldObjectWorker
250 explicit WorldObjectWorker(Do
const& _do
) : i_do(_do
) {}
252 void Visit(GameObjectMapType
&m
)
254 for(GameObjectMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
255 i_do(itr
->getSource());
258 void Visit(PlayerMapType
&m
)
260 for(PlayerMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
261 i_do(itr
->getSource());
263 void Visit(CreatureMapType
&m
)
265 for(CreatureMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
266 i_do(itr
->getSource());
269 void Visit(CorpseMapType
&m
)
271 for(CorpseMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
272 i_do(itr
->getSource());
275 void Visit(DynamicObjectMapType
&m
)
277 for(DynamicObjectMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
278 i_do(itr
->getSource());
281 template<class NOT_INTERESTED
> void Visit(GridRefManager
<NOT_INTERESTED
> &) {}
284 // Gameobject searchers
286 template<class Check
>
287 struct MANGOS_DLL_DECL GameObjectSearcher
289 GameObject
* &i_object
;
292 GameObjectSearcher(GameObject
* & result
, Check
& check
) : i_object(result
),i_check(check
) {}
294 void Visit(GameObjectMapType
&m
);
296 template<class NOT_INTERESTED
> void Visit(GridRefManager
<NOT_INTERESTED
> &) {}
299 // Last accepted by Check GO if any (Check can change requirements at each call)
300 template<class Check
>
301 struct MANGOS_DLL_DECL GameObjectLastSearcher
303 GameObject
* &i_object
;
306 GameObjectLastSearcher(GameObject
* & result
, Check
& check
) : i_object(result
),i_check(check
) {}
308 void Visit(GameObjectMapType
&m
);
310 template<class NOT_INTERESTED
> void Visit(GridRefManager
<NOT_INTERESTED
> &) {}
313 template<class Check
>
314 struct MANGOS_DLL_DECL GameObjectListSearcher
316 std::list
<GameObject
*> &i_objects
;
319 GameObjectListSearcher(std::list
<GameObject
*> &objects
, Check
& check
) : i_objects(objects
),i_check(check
) {}
321 void Visit(GameObjectMapType
&m
);
323 template<class NOT_INTERESTED
> void Visit(GridRefManager
<NOT_INTERESTED
> &) {}
328 // First accepted by Check Unit if any
329 template<class Check
>
330 struct MANGOS_DLL_DECL UnitSearcher
335 UnitSearcher(Unit
* & result
, Check
& check
) : i_object(result
),i_check(check
) {}
337 void Visit(CreatureMapType
&m
);
338 void Visit(PlayerMapType
&m
);
340 template<class NOT_INTERESTED
> void Visit(GridRefManager
<NOT_INTERESTED
> &) {}
343 // Last accepted by Check Unit if any (Check can change requirements at each call)
344 template<class Check
>
345 struct MANGOS_DLL_DECL UnitLastSearcher
350 UnitLastSearcher(Unit
* & result
, Check
& check
) : i_object(result
),i_check(check
) {}
352 void Visit(CreatureMapType
&m
);
353 void Visit(PlayerMapType
&m
);
355 template<class NOT_INTERESTED
> void Visit(GridRefManager
<NOT_INTERESTED
> &) {}
358 // All accepted by Check units if any
359 template<class Check
>
360 struct MANGOS_DLL_DECL UnitListSearcher
362 std::list
<Unit
*> &i_objects
;
365 UnitListSearcher(std::list
<Unit
*> &objects
, Check
& check
) : i_objects(objects
),i_check(check
) {}
367 void Visit(PlayerMapType
&m
);
368 void Visit(CreatureMapType
&m
);
370 template<class NOT_INTERESTED
> void Visit(GridRefManager
<NOT_INTERESTED
> &) {}
373 // Creature searchers
375 template<class Check
>
376 struct MANGOS_DLL_DECL CreatureSearcher
381 CreatureSearcher(Creature
* & result
, Check
& check
) : i_object(result
),i_check(check
) {}
383 void Visit(CreatureMapType
&m
);
385 template<class NOT_INTERESTED
> void Visit(GridRefManager
<NOT_INTERESTED
> &) {}
388 // Last accepted by Check Creature if any (Check can change requirements at each call)
389 template<class Check
>
390 struct MANGOS_DLL_DECL CreatureLastSearcher
395 CreatureLastSearcher(Creature
* & result
, Check
& check
) : i_object(result
),i_check(check
) {}
397 void Visit(CreatureMapType
&m
);
399 template<class NOT_INTERESTED
> void Visit(GridRefManager
<NOT_INTERESTED
> &) {}
402 template<class Check
>
403 struct MANGOS_DLL_DECL CreatureListSearcher
405 std::list
<Creature
*> &i_objects
;
408 CreatureListSearcher(std::list
<Creature
*> &objects
, Check
& check
) : i_objects(objects
),i_check(check
) {}
410 void Visit(CreatureMapType
&m
);
412 template<class NOT_INTERESTED
> void Visit(GridRefManager
<NOT_INTERESTED
> &) {}
417 template<class Check
>
418 struct MANGOS_DLL_DECL PlayerSearcher
423 PlayerSearcher(Player
* & result
, Check
& check
) : i_object(result
),i_check(check
) {}
425 void Visit(PlayerMapType
&m
);
427 template<class NOT_INTERESTED
> void Visit(GridRefManager
<NOT_INTERESTED
> &) {}
431 struct MANGOS_DLL_DECL PlayerWorker
435 explicit PlayerWorker(Do
& _do
) : i_do(_do
) {}
437 void Visit(PlayerMapType
&m
)
439 for(PlayerMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
440 i_do(itr
->getSource());
443 template<class NOT_INTERESTED
> void Visit(GridRefManager
<NOT_INTERESTED
> &) {}
446 // CHECKS && DO classes
448 // WorldObject check classes
449 class CannibalizeObjectCheck
452 CannibalizeObjectCheck(Unit
* funit
, float range
) : i_funit(funit
), i_range(range
) {}
453 bool operator()(Player
* u
)
455 if( i_funit
->IsFriendlyTo(u
) || u
->isAlive() || u
->isInFlight() )
458 if(i_funit
->IsWithinDistInMap(u
, i_range
) )
463 bool operator()(Corpse
* u
);
464 bool operator()(Creature
* u
)
466 if( i_funit
->IsFriendlyTo(u
) || u
->isAlive() || u
->isInFlight() ||
467 (u
->GetCreatureTypeMask() & CREATURE_TYPEMASK_HUMANOID_OR_UNDEAD
)==0)
470 if(i_funit
->IsWithinDistInMap(u
, i_range
) )
475 template<class NOT_INTERESTED
> bool operator()(NOT_INTERESTED
*) { return false; }
481 // WorldObject do classes
487 void operator()(Creature
* u
) const { u
->Respawn(); }
488 void operator()(GameObject
* u
) const { u
->Respawn(); }
489 void operator()(WorldObject
*) const {}
490 void operator()(Corpse
*) const {}
495 class GameObjectFocusCheck
498 GameObjectFocusCheck(Unit
const* unit
,uint32 focusId
) : i_unit(unit
), i_focusId(focusId
) {}
499 bool operator()(GameObject
* go
) const
501 if(go
->GetGOInfo()->type
!= GAMEOBJECT_TYPE_SPELL_FOCUS
)
504 if(go
->GetGOInfo()->spellFocus
.focusId
!= i_focusId
)
507 float dist
= go
->GetGOInfo()->spellFocus
.dist
;
509 return go
->IsWithinDistInMap(i_unit
, dist
);
516 // Find the nearest Fishing hole and return true only if source object is in range of hole
517 class NearestGameObjectFishingHole
520 NearestGameObjectFishingHole(WorldObject
const& obj
, float range
) : i_obj(obj
), i_range(range
) {}
521 bool operator()(GameObject
* go
)
523 if(go
->GetGOInfo()->type
== GAMEOBJECT_TYPE_FISHINGHOLE
&& go
->isSpawned() && i_obj
.IsWithinDistInMap(go
, i_range
) && i_obj
.IsWithinDistInMap(go
, go
->GetGOInfo()->fishinghole
.radius
))
525 i_range
= i_obj
.GetDistance(go
);
530 float GetLastRange() const { return i_range
; }
532 WorldObject
const& i_obj
;
536 NearestGameObjectFishingHole(NearestGameObjectFishingHole
const&);
539 // Success at unit in range, range update for next check (this can be use with GameobjectLastSearcher to find nearest GO)
540 class NearestGameObjectEntryInObjectRangeCheck
543 NearestGameObjectEntryInObjectRangeCheck(WorldObject
const& obj
,uint32 entry
, float range
) : i_obj(obj
), i_entry(entry
), i_range(range
) {}
544 bool operator()(GameObject
* go
)
546 if(go
->GetEntry() == i_entry
&& i_obj
.IsWithinDistInMap(go
, i_range
))
548 i_range
= i_obj
.GetDistance(go
); // use found GO range as new range limit for next check
553 float GetLastRange() const { return i_range
; }
555 WorldObject
const& i_obj
;
559 // prevent clone this object
560 NearestGameObjectEntryInObjectRangeCheck(NearestGameObjectEntryInObjectRangeCheck
const&);
563 class GameObjectWithDbGUIDCheck
566 GameObjectWithDbGUIDCheck(WorldObject
const& obj
,uint32 db_guid
) : i_obj(obj
), i_db_guid(db_guid
) {}
567 bool operator()(GameObject
const* go
) const
569 return go
->GetDBTableGUIDLow() == i_db_guid
;
572 WorldObject
const& i_obj
;
578 class AnyUnfriendlyUnitInObjectRangeCheck
581 AnyUnfriendlyUnitInObjectRangeCheck(WorldObject
const* obj
, Unit
const* funit
, float range
) : i_obj(obj
), i_funit(funit
), i_range(range
) {}
582 bool operator()(Unit
* u
)
584 if(u
->isAlive() && i_obj
->IsWithinDistInMap(u
, i_range
) && !i_funit
->IsFriendlyTo(u
))
590 WorldObject
const* i_obj
;
595 class AnyFriendlyUnitInObjectRangeCheck
598 AnyFriendlyUnitInObjectRangeCheck(WorldObject
const* obj
, Unit
const* funit
, float range
) : i_obj(obj
), i_funit(funit
), i_range(range
) {}
599 bool operator()(Unit
* u
)
601 if(u
->isAlive() && i_obj
->IsWithinDistInMap(u
, i_range
) && i_funit
->IsFriendlyTo(u
))
607 WorldObject
const* i_obj
;
612 class AnyUnitInObjectRangeCheck
615 AnyUnitInObjectRangeCheck(WorldObject
const* obj
, float range
) : i_obj(obj
), i_range(range
) {}
616 bool operator()(Unit
* u
)
618 if(u
->isAlive() && i_obj
->IsWithinDistInMap(u
, i_range
))
624 WorldObject
const* i_obj
;
628 // Success at unit in range, range update for next check (this can be use with UnitLastSearcher to find nearest unit)
629 class NearestAttackableUnitInObjectRangeCheck
632 NearestAttackableUnitInObjectRangeCheck(WorldObject
const* obj
, Unit
const* funit
, float range
) : i_obj(obj
), i_funit(funit
), i_range(range
) {}
633 bool operator()(Unit
* u
)
635 if( u
->isTargetableForAttack() && i_obj
->IsWithinDistInMap(u
, i_range
) &&
636 !i_funit
->IsFriendlyTo(u
) && u
->isVisibleForOrDetect(i_funit
,false) )
638 i_range
= i_obj
->GetDistance(u
); // use found unit range as new range limit for next check
645 WorldObject
const* i_obj
;
649 // prevent clone this object
650 NearestAttackableUnitInObjectRangeCheck(NearestAttackableUnitInObjectRangeCheck
const&);
653 class AnyAoETargetUnitInObjectRangeCheck
656 AnyAoETargetUnitInObjectRangeCheck(WorldObject
const* obj
, Unit
const* funit
, float range
)
657 : i_obj(obj
), i_funit(funit
), i_range(range
)
659 Unit
const* check
= i_funit
;
660 Unit
const* owner
= i_funit
->GetOwner();
663 i_targetForPlayer
= ( check
->GetTypeId()==TYPEID_PLAYER
);
665 bool operator()(Unit
* u
)
667 // Check contains checks for: live, non-selectable, non-attackable flags, flight check and GM check, ignore totems
668 if (!u
->isTargetableForAttack())
670 if(u
->GetTypeId()==TYPEID_UNIT
&& ((Creature
*)u
)->isTotem())
673 if(( i_targetForPlayer
? !i_funit
->IsFriendlyTo(u
) : i_funit
->IsHostileTo(u
) )&& i_obj
->IsWithinDistInMap(u
, i_range
))
679 bool i_targetForPlayer
;
680 WorldObject
const* i_obj
;
685 struct AnyDeadUnitCheck
687 bool operator()(Unit
* u
) { return !u
->isAlive(); }
690 struct AnyStealthedCheck
692 bool operator()(Unit
* u
) { return u
->GetVisibility()==VISIBILITY_GROUP_STEALTH
; }
697 class InAttackDistanceFromAnyHostileCreatureCheck
700 explicit InAttackDistanceFromAnyHostileCreatureCheck(Unit
* funit
) : i_funit(funit
) {}
701 bool operator()(Creature
* u
)
703 if(u
->isAlive() && u
->IsHostileTo(i_funit
) && i_funit
->IsWithinDistInMap(u
, u
->GetAttackDistance(i_funit
)))
712 class AnyAssistCreatureInRangeCheck
715 AnyAssistCreatureInRangeCheck(Unit
* funit
, Unit
* enemy
, float range
)
716 : i_funit(funit
), i_enemy(enemy
), i_range(range
)
719 bool operator()(Creature
* u
)
724 if ( !u
->CanAssistTo(i_funit
, i_enemy
) )
728 if( !i_funit
->IsWithinDistInMap(u
, i_range
) )
731 // only if see assisted creature
732 if( !i_funit
->IsWithinLOSInMap(u
) )
743 // Success at unit in range, range update for next check (this can be use with CreatureLastSearcher to find nearest creature)
744 class NearestCreatureEntryWithLiveStateInObjectRangeCheck
747 NearestCreatureEntryWithLiveStateInObjectRangeCheck(WorldObject
const& obj
,uint32 entry
, bool alive
, float range
)
748 : i_obj(obj
), i_entry(entry
), i_alive(alive
), i_range(range
) {}
750 bool operator()(Creature
* u
)
752 if(u
->GetEntry() == i_entry
&& u
->isAlive()==i_alive
&& i_obj
.IsWithinDistInMap(u
, i_range
))
754 i_range
= i_obj
.GetDistance(u
); // use found unit range as new range limit for next check
759 float GetLastRange() const { return i_range
; }
761 WorldObject
const& i_obj
;
766 // prevent clone this object
767 NearestCreatureEntryWithLiveStateInObjectRangeCheck(NearestCreatureEntryWithLiveStateInObjectRangeCheck
const&);
770 class AnyPlayerInObjectRangeCheck
773 AnyPlayerInObjectRangeCheck(WorldObject
const* obj
, float range
) : i_obj(obj
), i_range(range
) {}
774 bool operator()(Player
* u
)
776 if(u
->isAlive() && i_obj
->IsWithinDistInMap(u
, i_range
))
782 WorldObject
const* i_obj
;
787 template<> void PlayerRelocationNotifier::Visit
<Creature
>(CreatureMapType
&);
788 template<> void PlayerRelocationNotifier::Visit
<Player
>(PlayerMapType
&);
789 template<> void CreatureRelocationNotifier::Visit
<Player
>(PlayerMapType
&);
790 template<> void CreatureRelocationNotifier::Visit
<Creature
>(CreatureMapType
&);
791 template<> inline void DynamicObjectUpdater::Visit
<Creature
>(CreatureMapType
&);
792 template<> inline void DynamicObjectUpdater::Visit
<Player
>(PlayerMapType
&);