root/trunk/src/game/GridNotifiers.h @ 266

Revision 266, 31.3 kB (checked in by yumileroy, 17 years ago)

*Fix the bug that updatepacket is not sent to players.
*TODO: move creature::update to map::update. This requires that move activeobjectlist to map.

Original author: megamage
Date: 2008-11-20 20:28:17-06:00

Line 
1/*
2 * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
3 *
4 * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#ifndef TRINITY_GRIDNOTIFIERS_H
22#define TRINITY_GRIDNOTIFIERS_H
23
24#include "ObjectGridLoader.h"
25#include "ByteBuffer.h"
26#include "UpdateData.h"
27#include <iostream>
28
29#include "Corpse.h"
30#include "Object.h"
31#include "DynamicObject.h"
32#include "GameObject.h"
33#include "Player.h"
34#include "Unit.h"
35
36class Player;
37//class Map;
38
39namespace Trinity
40{
41
42    struct TRINITY_DLL_DECL PlayerNotifier
43    {
44        explicit PlayerNotifier(Player &pl) : i_player(pl) {}
45        void Visit(PlayerMapType &);
46        template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
47        Player &i_player;
48    };
49
50    struct TRINITY_DLL_DECL VisibleNotifier
51    {
52        Player &i_player;
53        UpdateData i_data;
54        UpdateDataMapType i_data_updates;
55        Player::ClientGUIDs i_clientGUIDs;
56        std::set<WorldObject*> i_visibleNow;
57
58        explicit VisibleNotifier(Player &player) : i_player(player),i_clientGUIDs(player.m_clientGUIDs) {}
59        template<class T> void Visit(GridRefManager<T> &m);
60        void Visit(PlayerMapType &);
61        void Notify(void);
62    };
63
64    struct TRINITY_DLL_DECL VisibleChangesNotifier
65    {
66        WorldObject &i_object;
67
68        explicit VisibleChangesNotifier(WorldObject &object) : i_object(object) {}
69        template<class T> void Visit(GridRefManager<T> &) {}
70        void Visit(PlayerMapType &);
71    };
72
73    struct TRINITY_DLL_DECL GridUpdater
74    {
75        GridType &i_grid;
76        uint32 i_timeDiff;
77        GridUpdater(GridType &grid, uint32 diff) : i_grid(grid), i_timeDiff(diff) {}
78
79        template<class T> void updateObjects(GridRefManager<T> &m)
80        {
81            for(typename GridRefManager<T>::iterator iter = m.begin(); iter != m.end(); ++iter)
82                iter->getSource()->Update(i_timeDiff);
83        }
84
85        void Visit(PlayerMapType &m) { updateObjects<Player>(m); }
86        void Visit(CreatureMapType &m){ updateObjects<Creature>(m); }
87        void Visit(GameObjectMapType &m) { updateObjects<GameObject>(m); }
88        void Visit(DynamicObjectMapType &m) { updateObjects<DynamicObject>(m); }
89        void Visit(CorpseMapType &m) { updateObjects<Corpse>(m); }
90    };
91
92    struct TRINITY_DLL_DECL Deliverer
93    {
94        WorldObject &i_source;
95        WorldPacket *i_message;
96        std::set<uint64> plr_list;
97        bool i_toPossessor;
98        bool i_toSelf;
99        float i_dist;
100        Deliverer(WorldObject &src, WorldPacket *msg, bool to_possessor, bool to_self, float dist = 0.0f) : i_source(src), i_message(msg), i_toPossessor(to_possessor), i_toSelf(to_self), i_dist(dist) {}
101        void Visit(PlayerMapType &m);
102        void Visit(CreatureMapType &m);
103        void Visit(DynamicObjectMapType &m);
104        virtual void VisitObject(Player* plr) = 0;
105        void SendPacket(Player* plr);
106        template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
107    };
108       
109    struct TRINITY_DLL_DECL MessageDeliverer : public Deliverer
110    {
111        MessageDeliverer(Player &pl, WorldPacket *msg, bool to_possessor, bool to_self) : Deliverer(pl, msg, to_possessor, to_self) {}
112        void VisitObject(Player* plr);
113    };
114
115    struct TRINITY_DLL_DECL ObjectMessageDeliverer : public Deliverer
116    {
117        explicit ObjectMessageDeliverer(WorldObject &src, WorldPacket *msg, bool to_possessor) : Deliverer(src, msg, to_possessor, false) {}
118        void VisitObject(Player* plr) { SendPacket(plr); }
119    };
120
121    struct TRINITY_DLL_DECL MessageDistDeliverer : public Deliverer
122    {
123        bool i_ownTeamOnly;
124        MessageDistDeliverer(Player &pl, WorldPacket *msg, bool to_possessor, float dist, bool to_self, bool ownTeamOnly) : Deliverer(pl, msg, to_possessor, to_self, dist), i_ownTeamOnly(ownTeamOnly) {}
125        void VisitObject(Player* plr);
126    };
127
128    struct TRINITY_DLL_DECL ObjectMessageDistDeliverer : public Deliverer
129    {
130        ObjectMessageDistDeliverer(WorldObject &obj, WorldPacket *msg, bool to_possessor, float dist) : Deliverer(obj, msg, to_possessor, false, dist) {}
131        void VisitObject(Player* plr) { SendPacket(plr); }
132    };
133
134    struct TRINITY_DLL_DECL ObjectUpdater
135    {
136        uint32 i_timeDiff;
137        explicit ObjectUpdater(const uint32 &diff) : i_timeDiff(diff) {}
138        template<class T> void Visit(GridRefManager<T> &m);
139        void Visit(PlayerMapType &) {}
140        void Visit(CorpseMapType &) {}
141        void Visit(CreatureMapType &);
142    };
143
144    template<class T>
145        struct TRINITY_DLL_DECL ObjectAccessorNotifier
146    {
147        T *& i_object;
148
149        uint64 i_id;
150        ObjectAccessorNotifier(T * &obj, uint64 id) : i_object(obj), i_id(id)
151        {
152            i_object = NULL;
153        }
154
155        void Visit(GridRefManager<T> &m )
156        {
157            if( i_object == NULL )
158            {
159                GridRefManager<T> *iter = m.find(i_id);
160                if( iter != m.end() )
161                {
162                    assert( iter->second != NULL );
163                    i_object = iter->second;
164                }
165            }
166        }
167
168        template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
169    };
170
171    struct TRINITY_DLL_DECL PlayerRelocationNotifier
172    {
173        Player &i_player;
174        PlayerRelocationNotifier(Player &pl) : i_player(pl) {}
175        template<class T> void Visit(GridRefManager<T> &) {}
176        void Visit(PlayerMapType &);
177        void Visit(CreatureMapType &);
178    };
179
180    struct TRINITY_DLL_DECL CreatureRelocationNotifier
181    {
182        Creature &i_creature;
183        CreatureRelocationNotifier(Creature &c) : i_creature(c) {}
184        template<class T> void Visit(GridRefManager<T> &) {}
185        #ifdef WIN32
186        template<> void Visit(PlayerMapType &);
187        #endif
188    };
189
190    struct TRINITY_DLL_DECL DynamicObjectUpdater
191    {
192        DynamicObject &i_dynobject;
193        Unit* i_check;
194        DynamicObjectUpdater(DynamicObject &dynobject, Unit* caster) : i_dynobject(dynobject)
195        {
196            i_check = caster;
197            Unit* owner = i_check->GetOwner();
198            if(owner)
199                i_check = owner;
200        }
201
202        template<class T> inline void Visit(GridRefManager<T>  &) {}
203        #ifdef WIN32
204        template<> inline void Visit<Player>(PlayerMapType &);
205        template<> inline void Visit<Creature>(CreatureMapType &);
206        #endif
207
208        void VisitHelper(Unit* target);
209    };
210
211    // SEARCHERS & LIST SEARCHERS & WORKERS
212
213    // WorldObject searchers & workers
214
215    template<class Check>
216        struct TRINITY_DLL_DECL WorldObjectSearcher
217    {
218        WorldObject* &i_object;
219        Check &i_check;
220
221        WorldObjectSearcher(WorldObject* & result, Check& check) : i_object(result),i_check(check) {}
222
223        void Visit(GameObjectMapType &m);
224        void Visit(PlayerMapType &m);
225        void Visit(CreatureMapType &m);
226        void Visit(CorpseMapType &m);
227        void Visit(DynamicObjectMapType &m);
228
229        template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
230    };
231
232    template<class Check>
233        struct TRINITY_DLL_DECL WorldObjectListSearcher
234    {
235        std::list<WorldObject*> &i_objects;
236        Check& i_check;
237
238        WorldObjectListSearcher(std::list<WorldObject*> &objects, Check & check) : i_objects(objects),i_check(check) {}
239
240        void Visit(PlayerMapType &m);
241        void Visit(CreatureMapType &m);
242        void Visit(CorpseMapType &m);
243        void Visit(GameObjectMapType &m);
244        void Visit(DynamicObjectMapType &m);
245
246        template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
247    };
248
249    template<class Do>
250        struct TRINITY_DLL_DECL WorldObjectWorker
251    {
252        Do const& i_do;
253
254        explicit WorldObjectWorker(Do const& _do) : i_do(_do) {}
255
256        void Visit(GameObjectMapType &m)
257        {
258            for(GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
259                i_do(itr->getSource());
260        }
261
262        void Visit(PlayerMapType &m)
263        {
264            for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
265                i_do(itr->getSource());
266        }
267        void Visit(CreatureMapType &m)
268        {
269            for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
270                i_do(itr->getSource());
271        }
272
273        void Visit(CorpseMapType &m)
274        {
275            for(CorpseMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
276                i_do(itr->getSource());
277        }
278
279        void Visit(DynamicObjectMapType &m)
280        {
281            for(DynamicObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
282                i_do(itr->getSource());
283        }
284
285        template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
286    };
287
288    // Gameobject searchers
289
290    template<class Check>
291        struct TRINITY_DLL_DECL GameObjectSearcher
292    {
293        GameObject* &i_object;
294        Check &i_check;
295
296        GameObjectSearcher(GameObject* & result, Check& check) : i_object(result),i_check(check) {}
297
298        void Visit(GameObjectMapType &m);
299
300        template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
301    };
302
303    // Last accepted by Check GO if any (Check can change requirements at each call)
304    template<class Check>
305        struct TRINITY_DLL_DECL GameObjectLastSearcher
306    {
307        GameObject* &i_object;
308        Check& i_check;
309
310        GameObjectLastSearcher(GameObject* & result, Check& check) : i_object(result),i_check(check) {}
311
312        void Visit(GameObjectMapType &m);
313
314        template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
315    };
316
317    template<class Check>
318        struct TRINITY_DLL_DECL GameObjectListSearcher
319    {
320        std::list<GameObject*> &i_objects;
321        Check& i_check;
322
323        GameObjectListSearcher(std::list<GameObject*> &objects, Check & check) : i_objects(objects),i_check(check) {}
324
325        void Visit(GameObjectMapType &m);
326
327        template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
328    };
329
330    // Unit searchers
331
332    // First accepted by Check Unit if any
333    template<class Check>
334        struct TRINITY_DLL_DECL UnitSearcher
335    {
336        Unit* &i_object;
337        Check & i_check;
338
339        UnitSearcher(Unit* & result, Check & check) : i_object(result),i_check(check) {}
340
341        void Visit(CreatureMapType &m);
342        void Visit(PlayerMapType &m);
343
344        template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
345    };
346
347    // Last accepted by Check Unit if any (Check can change requirements at each call)
348    template<class Check>
349        struct TRINITY_DLL_DECL UnitLastSearcher
350    {
351        Unit* &i_object;
352        Check & i_check;
353
354        UnitLastSearcher(Unit* & result, Check & check) : i_object(result),i_check(check) {}
355
356        void Visit(CreatureMapType &m);
357        void Visit(PlayerMapType &m);
358
359        template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
360    };
361
362    // All accepted by Check units if any
363    template<class Check>
364        struct TRINITY_DLL_DECL UnitListSearcher
365    {
366        std::list<Unit*> &i_objects;
367        Check& i_check;
368
369        UnitListSearcher(std::list<Unit*> &objects, Check & check) : i_objects(objects),i_check(check) {}
370
371        void Visit(PlayerMapType &m);
372        void Visit(CreatureMapType &m);
373
374        template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
375    };
376
377    // Creature searchers
378
379    template<class Check>
380        struct TRINITY_DLL_DECL CreatureSearcher
381    {
382        Creature* &i_object;
383        Check & i_check;
384
385        CreatureSearcher(Creature* & result, Check & check) : i_object(result),i_check(check) {}
386
387        void Visit(CreatureMapType &m);
388
389        template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
390    };
391
392    // Last accepted by Check Creature if any (Check can change requirements at each call)
393    template<class Check>
394        struct TRINITY_DLL_DECL CreatureLastSearcher
395    {
396        Creature* &i_object;
397        Check & i_check;
398
399        CreatureLastSearcher(Creature* & result, Check & check) : i_object(result),i_check(check) {}
400
401        void Visit(CreatureMapType &m);
402
403        template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
404    };
405
406    template<class Check>
407        struct TRINITY_DLL_DECL CreatureListSearcher
408    {
409        std::list<Creature*> &i_objects;
410        Check& i_check;
411
412        CreatureListSearcher(std::list<Creature*> &objects, Check & check) : i_objects(objects),i_check(check) {}
413
414        void Visit(CreatureMapType &m);
415
416        template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
417    };
418
419    // Player searchers
420
421    template<class Check>
422    struct TRINITY_DLL_DECL PlayerSearcher
423    {
424        Player* &i_object;
425        Check & i_check;
426
427        PlayerSearcher(Player* & result, Check & check) : i_object(result),i_check(check) {}
428
429        void Visit(PlayerMapType &m);
430
431        template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
432    };
433
434    template<class Do>
435    struct TRINITY_DLL_DECL PlayerWorker
436    {
437        Do& i_do;
438
439        explicit PlayerWorker(Do& _do) : i_do(_do) {}
440
441        void Visit(PlayerMapType &m)
442        {
443            for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
444                i_do(itr->getSource());
445        }
446
447        template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
448    };
449
450    // CHECKS && DO classes
451
452    // WorldObject check classes
453    class CannibalizeObjectCheck
454    {
455        public:
456            CannibalizeObjectCheck(Unit* funit, float range) : i_funit(funit), i_range(range) {}
457            bool operator()(Player* u)
458            {
459                if( i_funit->IsFriendlyTo(u) || u->isAlive() || u->isInFlight() )
460                    return false;
461
462                if(i_funit->IsWithinDistInMap(u, i_range) )
463                    return true;
464
465                return false;
466            }
467            bool operator()(Corpse* u);
468            bool operator()(Creature* u)
469            {
470                if( i_funit->IsFriendlyTo(u) || u->isAlive() || u->isInFlight() ||
471                    (u->GetCreatureTypeMask() & CREATURE_TYPEMASK_HUMANOID_OR_UNDEAD)==0)
472                    return false;
473
474                if(i_funit->IsWithinDistInMap(u, i_range) )
475                    return true;
476
477                return false;
478            }
479            template<class NOT_INTERESTED> bool operator()(NOT_INTERESTED* u) { return false; }
480        private:
481            Unit* const i_funit;
482            float i_range;
483    };
484
485    // WorldObject do classes
486
487    class RespawnDo
488    {
489        public:
490            RespawnDo() {}
491            void operator()(Creature* u) const { u->Respawn(); }
492            void operator()(GameObject* u) const { u->Respawn(); }
493            void operator()(WorldObject*) const {}
494            void operator()(Corpse*) const {}
495    };
496
497    // GameObject checks
498
499    class GameObjectFocusCheck
500    {
501        public:
502            GameObjectFocusCheck(Unit const* unit,uint32 focusId) : i_unit(unit), i_focusId(focusId) {}
503            bool operator()(GameObject* go) const
504            {
505                if(go->GetGOInfo()->type != GAMEOBJECT_TYPE_SPELL_FOCUS)
506                    return false;
507
508                if(go->GetGOInfo()->spellFocus.focusId != i_focusId)
509                    return false;
510
511                float dist = go->GetGOInfo()->spellFocus.dist;
512
513                return go->IsWithinDistInMap(i_unit, dist);
514            }
515        private:
516            Unit const* i_unit;
517            uint32 i_focusId;
518    };
519
520    // Find the nearest Fishing hole and return true only if source object is in range of hole
521    class NearestGameObjectFishingHole
522    {
523        public:
524            NearestGameObjectFishingHole(WorldObject const& obj, float range) : i_obj(obj), i_range(range) {}
525            bool operator()(GameObject* go)
526            {
527                if(go->GetGOInfo()->type == GAMEOBJECT_TYPE_FISHINGHOLE && go->isSpawned() && i_obj.IsWithinDistInMap(go, i_range) && i_obj.IsWithinDistInMap(go, go->GetGOInfo()->fishinghole.radius))
528                {
529                    i_range = i_obj.GetDistance(go);
530                    return true;
531                }
532                return false;
533            }
534            float GetLastRange() const { return i_range; }
535        private:
536            WorldObject const& i_obj;
537            float  i_range;
538
539            // prevent clone
540            NearestGameObjectFishingHole(NearestGameObjectFishingHole const&);
541    };
542
543    // Success at unit in range, range update for next check (this can be use with GameobjectLastSearcher to find nearest GO)
544    class NearestGameObjectEntryInObjectRangeCheck
545    {
546        public:
547            NearestGameObjectEntryInObjectRangeCheck(WorldObject const& obj,uint32 entry, float range) : i_obj(obj), i_entry(entry), i_range(range) {}
548            bool operator()(GameObject* go)
549            {
550                if(go->GetEntry() == i_entry && i_obj.IsWithinDistInMap(go, i_range))
551                {
552                    i_range = i_obj.GetDistance(go);        // use found GO range as new range limit for next check
553                    return true;
554                }
555                return false;
556            }
557            float GetLastRange() const { return i_range; }
558        private:
559            WorldObject const& i_obj;
560            uint32 i_entry;
561            float  i_range;
562
563            // prevent clone this object
564            NearestGameObjectEntryInObjectRangeCheck(NearestGameObjectEntryInObjectRangeCheck const&);
565    };
566
567    class GameObjectWithDbGUIDCheck
568    {
569        public:
570            GameObjectWithDbGUIDCheck(WorldObject const& obj,uint32 db_guid) : i_obj(obj), i_db_guid(db_guid) {}
571            bool operator()(GameObject const* go) const
572            {
573                return go->GetDBTableGUIDLow() == i_db_guid;
574            }
575        private:
576            WorldObject const& i_obj;
577            uint32 i_db_guid;
578    };
579
580    // Unit checks
581
582    class AnyUnfriendlyUnitInObjectRangeCheck
583    {
584        public:
585            AnyUnfriendlyUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range) : i_obj(obj), i_funit(funit), i_range(range) {}
586            bool operator()(Unit* u)
587            {
588                if(u->isAlive() && i_obj->IsWithinDistInMap(u, i_range) && !i_funit->IsFriendlyTo(u))
589                    return true;
590                else
591                    return false;
592            }
593        private:
594            WorldObject const* i_obj;
595            Unit const* i_funit;
596            float i_range;
597    };
598
599    class AnyFriendlyUnitInObjectRangeCheck
600    {
601        public:
602            AnyFriendlyUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range) : i_obj(obj), i_funit(funit), i_range(range) {}
603            bool operator()(Unit* u)
604            {
605                if(u->isAlive() && i_obj->IsWithinDistInMap(u, i_range) && i_funit->IsFriendlyTo(u))
606                    return true;
607                else
608                    return false;
609            }
610        private:
611            WorldObject const* i_obj;
612            Unit const* i_funit;
613            float i_range;
614    };
615
616    class AnyUnitInObjectRangeCheck
617    {
618        public:
619            AnyUnitInObjectRangeCheck(WorldObject const* obj, float range) : i_obj(obj), i_range(range) {}
620            bool operator()(Unit* u)
621            {
622                if(u->isAlive() && i_obj->IsWithinDistInMap(u, i_range))
623                    return true;
624
625                return false;
626            }
627        private:
628            WorldObject const* i_obj;
629            float i_range;
630    };
631
632    // Success at unit in range, range update for next check (this can be use with UnitLastSearcher to find nearest unit)
633    class NearestAttackableUnitInObjectRangeCheck
634    {
635        public:
636            NearestAttackableUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range) : i_obj(obj), i_funit(funit), i_range(range) {}
637            bool operator()(Unit* u)
638            {
639                if( u->isTargetableForAttack() && i_obj->IsWithinDistInMap(u, i_range) &&
640                    !i_funit->IsFriendlyTo(u) && u->isVisibleForOrDetect(i_funit,false)  )
641                {
642                    i_range = i_obj->GetDistance(u);        // use found unit range as new range limit for next check
643                    return true;
644                }
645
646                return false;
647            }
648        private:
649            WorldObject const* i_obj;
650            Unit const* i_funit;
651            float i_range;
652
653            // prevent clone this object
654            NearestAttackableUnitInObjectRangeCheck(NearestAttackableUnitInObjectRangeCheck const&);
655    };
656
657    class AnyAoETargetUnitInObjectRangeCheck
658    {
659        public:
660            AnyAoETargetUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range)
661                : i_obj(obj), i_funit(funit), i_range(range)
662            {
663                Unit const* check = i_funit;
664                Unit const* owner = i_funit->GetOwner();
665                if(owner)
666                    check = owner;
667                i_targetForPlayer = ( check->GetTypeId()==TYPEID_PLAYER );
668            }
669            bool operator()(Unit* u)
670            {
671                // Check contains checks for: live, non-selectable, non-attackable flags, flight check and GM check, ignore totems
672                if (!u->isTargetableForAttack())
673                    return false;
674                if(u->GetTypeId()==TYPEID_UNIT && ((Creature*)u)->isTotem())
675                    return false;
676
677                if(( i_targetForPlayer ? !i_funit->IsFriendlyTo(u) : i_funit->IsHostileTo(u) )&& i_obj->IsWithinDistInMap(u, i_range))
678                    return true;
679
680                return false;
681            }
682        private:
683            bool i_targetForPlayer;
684            WorldObject const* i_obj;
685            Unit const* i_funit;
686            float i_range;
687    };
688
689    struct AnyDeadUnitCheck
690    {
691        bool operator()(Unit* u) { return !u->isAlive(); }
692    };
693
694    struct AnyStealthedCheck
695    {
696        bool operator()(Unit* u) { return u->GetVisibility()==VISIBILITY_GROUP_STEALTH; }
697    };
698
699    // Creature checks
700
701    class NearestHostileUnitInAttackDistanceCheck
702    {
703        public:
704            explicit NearestHostileUnitInAttackDistanceCheck(Creature* creature, float dist = 0) : m_creature(creature) 
705            {
706                m_range = (dist == 0 ? 9999 : dist);
707                m_force = (dist == 0 ? false : true);
708            }
709            bool operator()(Unit* u)
710            {
711                if(!u->isAlive() || !m_creature->IsHostileTo(u))
712                    return false;
713
714                float dist;
715                if(m_force) dist = m_range;
716                else
717                {
718                    dist = m_creature->GetAttackDistance(u);
719                    if(dist > m_range) dist = m_range;
720                }
721                if(!m_creature->IsWithinDistInMap(u, dist))
722                    return false;
723
724                if(!m_creature->canSeeOrDetect(u, true, false))
725                    return false;
726
727                m_range = m_creature->GetDistance(u);
728                return true;
729            }
730            float GetLastRange() const { return m_range; }
731        private:
732            Creature* const m_creature;
733            float m_range;
734            bool m_force;
735            NearestHostileUnitInAttackDistanceCheck(NearestHostileUnitInAttackDistanceCheck const&);
736    };
737
738    class NearestAssistCreatureInCreatureRangeCheck
739    {
740        public:
741            NearestAssistCreatureInCreatureRangeCheck(Creature* obj,Unit* enemy, float range)
742                : i_obj(obj), i_enemy(enemy), i_range(range) {}
743
744            bool operator()(Creature* u)
745            {
746                if(u->getFaction() == i_obj->getFaction() && !u->isInCombat() && !u->GetCharmerOrOwnerGUID() && u->IsHostileTo(i_enemy) && u->isAlive()&& i_obj->IsWithinDistInMap(u, i_range) && i_obj->IsWithinLOSInMap(u))
747                {
748                    i_range = i_obj->GetDistance(u);         // use found unit range as new range limit for next check
749                    return true;
750                }
751                return false;
752            }
753            float GetLastRange() const { return i_range; }
754        private:
755            Creature* const i_obj;
756            Unit* const i_enemy;
757            float  i_range;
758
759            // prevent clone this object
760            NearestAssistCreatureInCreatureRangeCheck(NearestAssistCreatureInCreatureRangeCheck const&);
761    };
762
763    class AnyAssistCreatureInRangeCheck
764    {
765        public:
766            AnyAssistCreatureInRangeCheck(Unit* funit, Unit* enemy, float range)
767                : i_funit(funit), i_enemy(enemy), i_range(range)
768            {
769            }
770            bool operator()(Creature* u)
771            {
772                if(u == i_funit)
773                    return false;
774
775                // we don't need help from zombies :)
776                if( !u->isAlive() )
777                    return false;
778
779                // skip fighting creature
780                if( u->isInCombat() )
781                    return false;
782
783                // only from same creature faction
784                if(u->getFaction() != i_funit->getFaction() )
785                    return false;
786
787                // only free creature
788                if( u->GetCharmerOrOwnerGUID() )
789                    return false;
790
791                // too far
792                if( !i_funit->IsWithinDistInMap(u, i_range) )
793                    return false;
794
795                // skip non hostile to caster enemy creatures
796                if( !u->IsHostileTo(i_enemy) )
797                    return false;
798
799                // only if see assisted creature
800                if(!u->IsWithinLOSInMap(i_funit) )
801                    return false;
802
803                return true;
804            }
805        private:
806            Unit* const i_funit;
807            Unit* const i_enemy;
808            float i_range;
809    };
810
811    // Success at unit in range, range update for next check (this can be use with CreatureLastSearcher to find nearest creature)
812    class NearestCreatureEntryWithLiveStateInObjectRangeCheck
813    {
814        public:
815            NearestCreatureEntryWithLiveStateInObjectRangeCheck(WorldObject const& obj,uint32 entry, bool alive, float range)
816                : i_obj(obj), i_entry(entry), i_alive(alive), i_range(range) {}
817
818            bool operator()(Creature* u)
819            {
820                if(u->GetEntry() == i_entry && u->isAlive()==i_alive && i_obj.IsWithinDistInMap(u, i_range))
821                {
822                    i_range = i_obj.GetDistance(u);         // use found unit range as new range limit for next check
823                    return true;
824                }
825                return false;
826            }
827            float GetLastRange() const { return i_range; }
828        private:
829            WorldObject const& i_obj;
830            uint32 i_entry;
831            bool   i_alive;
832            float  i_range;
833
834            // prevent clone this object
835            NearestCreatureEntryWithLiveStateInObjectRangeCheck(NearestCreatureEntryWithLiveStateInObjectRangeCheck const&);
836    };
837
838    class AnyPlayerInObjectRangeCheck
839    {
840    public:
841        AnyPlayerInObjectRangeCheck(WorldObject const* obj, float range) : i_obj(obj), i_range(range) {}
842        bool operator()(Player* u)
843        {
844            if(u->isAlive() && i_obj->IsWithinDistInMap(u, i_range))
845                return true;
846
847            return false;
848        }
849    private:
850        WorldObject const* i_obj;
851        float i_range;
852    };
853
854    // Searchers used by ScriptedAI
855    class MostHPMissingInRange
856    {
857    public:
858        MostHPMissingInRange(Unit const* obj, float range, uint32 hp) : i_obj(obj), i_range(range), i_hp(hp) {}
859        bool operator()(Unit* u)
860        {
861            if(u->isAlive() && u->isInCombat() && !i_obj->IsHostileTo(u) && i_obj->IsWithinDistInMap(u, i_range) && u->GetMaxHealth() - u->GetHealth() > i_hp)
862            {
863                i_hp = u->GetMaxHealth() - u->GetHealth();
864                return true;
865            }
866            return false;
867        }
868    private:
869        Unit const* i_obj;
870        float i_range;
871        uint32 i_hp;
872    };
873
874    class FriendlyCCedInRange
875    {
876    public:
877        FriendlyCCedInRange(Unit const* obj, float range) : i_obj(obj), i_range(range) {}
878        bool operator()(Unit* u)
879        {
880            if(u->isAlive() && u->isInCombat() && !i_obj->IsHostileTo(u) && i_obj->IsWithinDistInMap(u, i_range) &&
881                (u->isFeared() || u->isCharmed() || u->isFrozen() || u->hasUnitState(UNIT_STAT_STUNNED) || u->hasUnitState(UNIT_STAT_CONFUSED)))
882            {
883                return true;
884            }
885            return false;
886        }
887    private:
888        Unit const* i_obj;
889        float i_range;
890    };
891
892    class FriendlyMissingBuffInRange
893    {
894    public:
895        FriendlyMissingBuffInRange(Unit const* obj, float range, uint32 spellid) : i_obj(obj), i_range(range), i_spell(spellid) {}
896        bool operator()(Unit* u)
897        {
898            if(u->isAlive() && u->isInCombat() && !i_obj->IsHostileTo(u) && i_obj->IsWithinDistInMap(u, i_range) && 
899                !(u->HasAura(i_spell, 0) || u->HasAura(i_spell, 1) || u->HasAura(i_spell, 2)))
900            {
901                return true;
902            }
903            return false;
904        }
905    private:
906        Unit const* i_obj;
907        float i_range;
908        uint32 i_spell;
909    };
910
911    class AllFriendlyCreaturesInGrid
912    {
913    public:
914        AllFriendlyCreaturesInGrid(Unit const* obj) : pUnit(obj) {}
915        bool operator() (Unit* u)
916        {
917            if(u->isAlive() && u->GetVisibility() == VISIBILITY_ON && u->IsFriendlyTo(pUnit))
918                return true;
919
920            return false;
921        }
922    private:
923        Unit const* pUnit;
924    };
925
926    class AllGameObjectsWithEntryInGrid
927    {
928    public:
929        AllGameObjectsWithEntryInGrid(uint32 ent) : entry(ent) {}
930        bool operator() (GameObject* g)
931        {
932            if(g->GetEntry() == entry)
933                return true;
934
935            return false;
936        }
937    private:
938        uint32 entry;
939    };
940
941    class AllCreaturesOfEntryInRange
942    {
943    public:
944        AllCreaturesOfEntryInRange(Unit const* obj, uint32 ent, float ran) : pUnit(obj), entry(ent), range(ran) {}
945        bool operator() (Unit* u)
946        {
947            if(u->GetEntry() == entry && pUnit->IsWithinDistInMap(u, range))
948                return true;
949
950            return false;
951        }
952    private:
953        Unit const* pUnit;
954        uint32 entry;
955        float range;
956    };
957
958    #ifndef WIN32
959    template<> void PlayerRelocationNotifier::Visit<Creature>(CreatureMapType &);
960    template<> void PlayerRelocationNotifier::Visit<Player>(PlayerMapType &);
961    template<> void CreatureRelocationNotifier::Visit<Player>(PlayerMapType &);
962    template<> void CreatureRelocationNotifier::Visit<Creature>(CreatureMapType &);
963    template<> inline void DynamicObjectUpdater::Visit<Creature>(CreatureMapType &);
964    template<> inline void DynamicObjectUpdater::Visit<Player>(PlayerMapType &);
965    #endif
966}
967#endif
Note: See TracBrowser for help on using the browser.