root/trunk/src/game/Spell.h @ 145

Revision 145, 25.4 kB (checked in by yumileroy, 17 years ago)

[svn] Add function GameObject::CastSpell?. Used for hunter's trap and so.
Use original caster instead caster to check spell hit result.
Let spell triggers have the same faction as the summoner.
Fix the bug that trigger creatures attack enemy. (no need use civilian extra flag in the future, 128 is enough)
Fix shadow step.

Original author: megamage
Date: 2008-11-02 00:59:44-05: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 __SPELL_H
22#define __SPELL_H
23
24#include "GridDefines.h"
25
26class WorldSession;
27class Unit;
28class DynamicObj;
29class Player;
30class GameObject;
31class Group;
32class Aura;
33
34enum SpellCastTargetFlags
35{
36    /*TARGET_FLAG_NONE             = 0x0000,
37    TARGET_FLAG_SWIMMER          = 0x0002,
38    TARGET_FLAG_ITEM             = 0x0010,
39    TARGET_FLAG_SOURCE_AREA      = 0x0020,
40    TARGET_FLAG_DEST_AREA        = 0x0040,
41    TARGET_FLAG_UNKNOWN          = 0x0080,
42    TARGET_FLAG_SELF             = 0x0100,
43    TARGET_FLAG_PVP_CORPSE       = 0x0200,
44    TARGET_FLAG_MASS_SPIRIT_HEAL = 0x0400,
45    TARGET_FLAG_BEAST_CORPSE     = 0x0402,
46    TARGET_FLAG_OBJECT           = 0x4000,
47    TARGET_FLAG_RESURRECTABLE    = 0x8000*/
48
49    TARGET_FLAG_SELF            = 0x00000000,
50    TARGET_FLAG_UNIT            = 0x00000002,               // pguid
51    TARGET_FLAG_ITEM            = 0x00000010,               // pguid
52    TARGET_FLAG_SOURCE_LOCATION = 0x00000020,               // 3 float
53    TARGET_FLAG_DEST_LOCATION   = 0x00000040,               // 3 float
54    TARGET_FLAG_OBJECT_UNK      = 0x00000080,               // ?
55    TARGET_FLAG_PVP_CORPSE      = 0x00000200,               // pguid
56    TARGET_FLAG_OBJECT          = 0x00000800,               // pguid
57    TARGET_FLAG_TRADE_ITEM      = 0x00001000,               // pguid
58    TARGET_FLAG_STRING          = 0x00002000,               // string
59    TARGET_FLAG_UNK1            = 0x00004000,               // ?
60    TARGET_FLAG_CORPSE          = 0x00008000,               // pguid
61    TARGET_FLAG_UNK2            = 0x00010000                // pguid
62};
63
64enum SpellCastFlags
65{
66    CAST_FLAG_UNKNOWN1           = 0x00000002,
67    CAST_FLAG_UNKNOWN2           = 0x00000010,
68    CAST_FLAG_AMMO               = 0x00000020,
69    CAST_FLAG_UNKNOWN3           = 0x00000100
70};
71
72enum SpellNotifyPushType
73{
74    PUSH_IN_FRONT,
75    PUSH_IN_BACK,
76    PUSH_IN_LINE,
77    PUSH_SELF_CENTER,
78    PUSH_DEST_CENTER,
79};
80
81bool IsQuestTameSpell(uint32 spellId);
82
83namespace Trinity
84{
85    struct SpellNotifierCreatureAndPlayer;
86}
87
88class SpellCastTargets
89{
90    public:
91        SpellCastTargets();
92        ~SpellCastTargets();
93
94        bool read ( WorldPacket * data, Unit *caster );
95        void write ( WorldPacket * data );
96
97        SpellCastTargets& operator=(const SpellCastTargets &target)
98        {
99            m_unitTarget = target.m_unitTarget;
100            m_itemTarget = target.m_itemTarget;
101            m_GOTarget   = target.m_GOTarget;
102
103            m_unitTargetGUID   = target.m_unitTargetGUID;
104            m_GOTargetGUID     = target.m_GOTargetGUID;
105            m_CorpseTargetGUID = target.m_CorpseTargetGUID;
106            m_itemTargetGUID   = target.m_itemTargetGUID;
107
108            m_itemTargetEntry  = target.m_itemTargetEntry;
109
110            //m_srcX = target.m_srcX;
111            //m_srcY = target.m_srcY;
112            //m_srcZ = target.m_srcZ;
113
114            m_mapId = -1;
115            m_destX = target.m_destX;
116            m_destY = target.m_destY;
117            m_destZ = target.m_destZ;
118            m_hasDest = target.m_hasDest;
119
120            m_strTarget = target.m_strTarget;
121
122            m_targetMask = target.m_targetMask;
123
124            return *this;
125        }
126
127        uint64 getUnitTargetGUID() const { return m_unitTargetGUID; }
128        Unit *getUnitTarget() const { return m_unitTarget; }
129        void setUnitTarget(Unit *target);
130        void setDestination(float x, float y, float z, bool send = true, int32 mapId = -1);
131        void setDestination(Unit *target, bool send = true);
132
133        uint64 getGOTargetGUID() const { return m_GOTargetGUID; }
134        GameObject *getGOTarget() const { return m_GOTarget; }
135        void setGOTarget(GameObject *target);
136
137        uint64 getCorpseTargetGUID() const { return m_CorpseTargetGUID; }
138        void setCorpseTarget(Corpse* corpse);
139        uint64 getItemTargetGUID() const { return m_itemTargetGUID; }
140        Item* getItemTarget() const { return m_itemTarget; }
141        uint32 getItemTargetEntry() const { return m_itemTargetEntry; }
142        void setItemTarget(Item* item);
143        void updateTradeSlotItem()
144        {
145            if(m_itemTarget && (m_targetMask & TARGET_FLAG_TRADE_ITEM))
146            {
147                m_itemTargetGUID = m_itemTarget->GetGUID();
148                m_itemTargetEntry = m_itemTarget->GetEntry();
149            }
150        }
151
152        bool IsEmpty() const { return m_GOTargetGUID==0 && m_unitTargetGUID==0 && m_itemTarget==0 && m_CorpseTargetGUID==0; }
153        bool HasDest() const { return m_hasDest; }
154
155        void Update(Unit* caster);
156
157        float m_srcX, m_srcY, m_srcZ;
158        int32 m_mapId;
159        float m_destX, m_destY, m_destZ;
160        bool m_hasDest;
161        std::string m_strTarget;
162
163        uint32 m_targetMask;
164    private:
165        // objects (can be used at spell creating and after Update at casting
166        Unit *m_unitTarget;
167        GameObject *m_GOTarget;
168        Item *m_itemTarget;
169
170        // object GUID/etc, can be used always
171        uint64 m_unitTargetGUID;
172        uint64 m_GOTargetGUID;
173        uint64 m_CorpseTargetGUID;
174        uint64 m_itemTargetGUID;
175        uint32 m_itemTargetEntry;
176};
177
178enum SpellState
179{
180    SPELL_STATE_NULL      = 0,
181    SPELL_STATE_PREPARING = 1,
182    SPELL_STATE_CASTING   = 2,
183    SPELL_STATE_FINISHED  = 3,
184    SPELL_STATE_IDLE      = 4,
185    SPELL_STATE_DELAYED   = 5
186};
187
188enum ReplenishType
189{
190    REPLENISH_UNDEFINED = 0,
191    REPLENISH_HEALTH    = 20,
192    REPLENISH_MANA      = 21,
193    REPLENISH_RAGE      = 22
194};
195
196enum SpellTargets
197{
198    SPELL_TARGETS_FRIENDLY,
199    SPELL_TARGETS_AOE_DAMAGE,
200    SPELL_TARGETS_ENTRY
201};
202
203#define SPELL_SPELL_CHANNEL_UPDATE_INTERVAL 1000
204
205typedef std::multimap<uint64, uint64> SpellTargetTimeMap;
206
207class Spell
208{
209    friend struct Trinity::SpellNotifierCreatureAndPlayer;
210    public:
211
212        void EffectNULL(uint32 );
213        void EffectUnused(uint32 );
214        void EffectDistract(uint32 i);
215        void EffectPull(uint32 i);
216        void EffectSchoolDMG(uint32 i);
217        void EffectEnvirinmentalDMG(uint32 i);
218        void EffectInstaKill(uint32 i);
219        void EffectDummy(uint32 i);
220        void EffectTeleportUnits(uint32 i);
221        void EffectApplyAura(uint32 i);
222        void EffectSendEvent(uint32 i);
223        void EffectPowerBurn(uint32 i);
224        void EffectPowerDrain(uint32 i);
225        void EffectHeal(uint32 i);
226        void EffectHealthLeech(uint32 i);
227        void EffectQuestComplete(uint32 i);
228        void EffectCreateItem(uint32 i);
229        void EffectPersistentAA(uint32 i);
230        void EffectEnergize(uint32 i);
231        void EffectOpenLock(uint32 i);
232        void EffectSummonChangeItem(uint32 i);
233        void EffectOpenSecretSafe(uint32 i);
234        void EffectProficiency(uint32 i);
235        void EffectApplyAreaAura(uint32 i);
236        void EffectSummonType(uint32 i);
237        void EffectSummon(uint32 i);
238        void EffectLearnSpell(uint32 i);
239        void EffectDispel(uint32 i);
240        void EffectDualWield(uint32 i);
241        void EffectPickPocket(uint32 i);
242        void EffectAddFarsight(uint32 i);
243        void EffectSummonWild(uint32 i);
244        void EffectSummonGuardian(uint32 i);
245        void EffectHealMechanical(uint32 i);
246        void EffectTeleUnitsFaceCaster(uint32 i);
247        void EffectLearnSkill(uint32 i);
248        void EffectAddHonor(uint32 i);
249        void EffectTradeSkill(uint32 i);
250        void EffectEnchantItemPerm(uint32 i);
251        void EffectEnchantItemTmp(uint32 i);
252        void EffectTameCreature(uint32 i);
253        void EffectSummonPet(uint32 i);
254        void EffectLearnPetSpell(uint32 i);
255        void EffectWeaponDmg(uint32 i);
256        void EffectForceCast(uint32 i);
257        void EffectTriggerSpell(uint32 i);
258        void EffectTriggerMissileSpell(uint32 i);
259        void EffectThreat(uint32 i);
260        void EffectHealMaxHealth(uint32 i);
261        void EffectInterruptCast(uint32 i);
262        void EffectSummonObjectWild(uint32 i);
263        void EffectScriptEffect(uint32 i);
264        void EffectSanctuary(uint32 i);
265        void EffectAddComboPoints(uint32 i);
266        void EffectDuel(uint32 i);
267        void EffectStuck(uint32 i);
268        void EffectSummonPlayer(uint32 i);
269        void EffectActivateObject(uint32 i);
270        void EffectSummonTotem(uint32 i);
271        void EffectEnchantHeldItem(uint32 i);
272        void EffectSummonObject(uint32 i);
273        void EffectResurrect(uint32 i);
274        void EffectParry(uint32 i);
275        void EffectBlock(uint32 i);
276        void EffectMomentMove(uint32 i);
277        void EffectTransmitted(uint32 i);
278        void EffectDisEnchant(uint32 i);
279        void EffectInebriate(uint32 i);
280        void EffectFeedPet(uint32 i);
281        void EffectDismissPet(uint32 i);
282        void EffectReputation(uint32 i);
283        void EffectSelfResurrect(uint32 i);
284        void EffectSkinning(uint32 i);
285        void EffectCharge(uint32 i);
286        void EffectProspecting(uint32 i);
287        void EffectSendTaxi(uint32 i);
288        void EffectSummonCritter(uint32 i);
289        void EffectKnockBack(uint32 i);
290        void EffectPlayerPull(uint32 i);
291        void EffectDispelMechanic(uint32 i);
292        void EffectSummonDeadPet(uint32 i);
293        void EffectDestroyAllTotems(uint32 i);
294        void EffectDurabilityDamage(uint32 i);
295        void EffectSkill(uint32 i);
296        void EffectTaunt(uint32 i);
297        void EffectDurabilityDamagePCT(uint32 i);
298        void EffectModifyThreatPercent(uint32 i);
299        void EffectResurrectNew(uint32 i);
300        void EffectAddExtraAttacks(uint32 i);
301        void EffectSpiritHeal(uint32 i);
302        void EffectSkinPlayerCorpse(uint32 i);
303        void EffectSummonDemon(uint32 i);
304        void EffectStealBeneficialBuff(uint32 i);
305        void EffectUnlearnSpecialization(uint32 i);
306        void EffectHealPct(uint32 i);
307        void EffectEnergisePct(uint32 i);
308        void EffectTriggerSpellWithValue(uint32 i);
309        void EffectTriggerRitualOfSummoning(uint32 i);
310        void EffectKillCredit(uint32 i);
311        void EffectQuestFail(uint32 i);
312
313        Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 originalCasterGUID = 0, Spell** triggeringContainer = NULL );
314        ~Spell();
315
316        void prepare(SpellCastTargets * targets, Aura* triggeredByAura = NULL);
317        void cancel();
318        void update(uint32 difftime);
319        void cast(bool skipCheck = false);
320        void finish(bool ok = true);
321        void TakePower();
322        void TakeReagents();
323        void TakeCastItem();
324        void TriggerSpell();
325        uint8 CanCast(bool strict);
326        int16 PetCanCast(Unit* target);
327        bool CanAutoCast(Unit* target);
328
329        // handlers
330        void handle_immediate();
331        uint64 handle_delayed(uint64 t_offset);
332        // handler helpers
333        void _handle_immediate_phase();
334        void _handle_finish_phase();
335
336        uint8 CheckItems();
337        uint8 CheckRange(bool strict);
338        uint8 CheckPower();
339        uint8 CheckCasterAuras() const;
340
341        int32 CalculateDamage(uint8 i, Unit* target) { return m_caster->CalculateSpellDamage(m_spellInfo,i,m_currentBasePoints[i],target); }
342        int32 CalculatePowerCost();
343
344        bool HaveTargetsForEffect(uint8 effect) const;
345        void Delayed();
346        void DelayedChannel();
347        inline uint32 getState() const { return m_spellState; }
348        void setState(uint32 state) { m_spellState = state; }
349
350        void DoCreateItem(uint32 i, uint32 itemtype);
351
352        void WriteSpellGoTargets( WorldPacket * data );
353        void WriteAmmoToPacket( WorldPacket * data );
354        void FillTargetMap();
355
356        void SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap);
357
358        Unit* SelectMagnetTarget();
359        std::pair <bool,Unit *> m_magnetPair;
360        bool CheckTarget( Unit* target, uint32 eff, bool hitPhase );
361
362        void SendCastResult(uint8 result);
363        void SendSpellStart();
364        void SendSpellGo();
365        void SendSpellCooldown();
366        void SendLogExecute();
367        void SendInterrupted(uint8 result);
368        void SendChannelUpdate(uint32 time);
369        void SendChannelStart(uint32 duration);
370        void SendResurrectRequest(Player* target);
371        void SendPlaySpellVisual(uint32 SpellID);
372
373        void HandleEffects(Unit *pUnitTarget,Item *pItemTarget,GameObject *pGOTarget,uint32 i, float DamageMultiplier = 1.0);
374        void HandleThreatSpells(uint32 spellId);
375        //void HandleAddAura(Unit* Target);
376
377        SpellEntry const* m_spellInfo;
378        int32 m_currentBasePoints[3];                       // cache SpellEntry::EffectBasePoints and use for set custom base points
379        Item* m_CastItem;
380        uint8 m_cast_count;
381        SpellCastTargets m_targets;
382
383        int32 GetCastTime() const { return m_casttime; }
384        bool IsAutoRepeat() const { return m_autoRepeat; }
385        void SetAutoRepeat(bool rep) { m_autoRepeat = rep; }
386        void ReSetTimer() { m_timer = m_casttime > 0 ? m_casttime : 0; }
387        bool IsNextMeleeSwingSpell() const
388        {
389            return m_spellInfo->Attributes & (SPELL_ATTR_ON_NEXT_SWING_1|SPELL_ATTR_ON_NEXT_SWING_2);
390        }
391        bool IsRangedSpell() const
392        {
393            return  m_spellInfo->Attributes & SPELL_ATTR_RANGED;
394        }
395        bool IsChannelActive() const { return m_caster->GetUInt32Value(UNIT_CHANNEL_SPELL) != 0; }
396        bool IsMeleeAttackResetSpell() const { return !m_IsTriggeredSpell && (m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_AUTOATTACK);  }
397        bool IsRangedAttackResetSpell() const { return !m_IsTriggeredSpell && IsRangedSpell() && (m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_AUTOATTACK); }
398
399        bool IsDeletable() const { return m_deletable; }
400        void SetDeletable(bool deletable) { m_deletable = deletable; }
401        uint64 GetDelayStart() const { return m_delayStart; }
402        void SetDelayStart(uint64 m_time) { m_delayStart = m_time; }
403        uint64 GetDelayMoment() const { return m_delayMoment; }
404
405        bool IsNeedSendToClient() const;
406
407        CurrentSpellTypes GetCurrentContainer();
408
409        Unit* GetCaster() const { return m_caster; }
410        Unit* GetOriginalCaster() const { return m_originalCaster; }
411        int32 GetPowerCost() const { return m_powerCost; }
412
413        void UpdatePointers();                              // must be used at call Spell code after time delay (non triggered spell cast/update spell call/etc)
414
415        bool IsAffectedBy(SpellEntry const *spellInfo, uint32 effectId);
416
417        bool CheckTargetCreatureType(Unit* target) const;
418
419        void AddTriggeredSpell(SpellEntry const* spell) { m_TriggerSpells.push_back(spell); }
420
421        void CleanupTargetList();
422    protected:
423
424        void SendLoot(uint64 guid, LootType loottype);
425
426        Unit* m_caster;
427
428        uint64 m_originalCasterGUID;                        // real source of cast (aura caster/etc), used for spell targets selection
429                                                            // e.g. damage around area spell trigered by victim aura and da,age emeies of aura caster
430        Unit* m_originalCaster;                             // cached pointer for m_originalCaster, updated at Spell::UpdatePointers()
431
432        Spell** m_selfContainer;                            // pointer to our spell container (if applicable)
433        Spell** m_triggeringContainer;                      // pointer to container with spell that has triggered us
434
435        //Spell data
436        SpellSchoolMask m_spellSchoolMask;                  // Spell school (can be overwrite for some spells (wand shoot for example)
437        WeaponAttackType m_attackType;                      // For weapon based attack
438        int32 m_powerCost;                                  // Calculated spell cost     initialized only in Spell::prepare
439        int32 m_casttime;                                   // Calculated spell cast time initialized only in Spell::prepare
440        bool m_canReflect;                                  // can reflect this spell?
441        bool m_autoRepeat;
442
443        uint8 m_delayAtDamageCount;
444        int32 GetNextDelayAtDamageMsTime() { return m_delayAtDamageCount < 5 ? 1000 - (m_delayAtDamageCount++)* 200 : 200; }
445
446        // Delayed spells system
447        uint64 m_delayStart;                                // time of spell delay start, filled by event handler, zero = just started
448        uint64 m_delayMoment;                               // moment of next delay call, used internally
449        bool m_immediateHandled;                            // were immediate actions handled? (used by delayed spells only)
450
451        // These vars are used in both delayed spell system and modified immediate spell system
452        bool m_deletable;                                   // is the spell pending deletion or must be updated till permitted to delete?
453        bool m_needSpellLog;                                // need to send spell log?
454        uint8 m_applyMultiplierMask;                        // by effect: damage multiplier needed?
455        float m_damageMultipliers[3];                       // by effect: damage multiplier
456
457        // Current targets, to be used in SpellEffects (MUST BE USED ONLY IN SPELL EFFECTS)
458        Unit* unitTarget;
459        Item* itemTarget;
460        GameObject* gameObjTarget;
461        int32 damage;
462
463        // this is set in Spell Hit, but used in Apply Aura handler
464        DiminishingLevels m_diminishLevel;
465        DiminishingGroup m_diminishGroup;
466
467        // -------------------------------------------
468        GameObject* focusObject;
469
470        //******************************************
471        // Spell trigger system
472        //******************************************
473        void doTriggers(SpellMissInfo missInfo, uint32 damage=0, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NONE, uint32 block=0, uint32 absorb=0, bool crit=false);
474
475        //*****************************************
476        // Spell target subsystem
477        //*****************************************
478        // Targets store structures and data
479        uint32 m_countOfHit;
480        uint32 m_countOfMiss;
481        struct TargetInfo
482        {
483            uint64 targetGUID;
484            uint64 timeDelay;
485            SpellMissInfo missCondition:8;
486            SpellMissInfo reflectResult:8;
487            uint8  effectMask:8;
488            bool   processed:1;
489        };
490        std::list<TargetInfo> m_UniqueTargetInfo;
491        uint8 m_needAliveTargetMask;                        // Mask req. alive targets
492
493        struct GOTargetInfo
494        {
495            uint64 targetGUID;
496            uint64 timeDelay;
497            uint8  effectMask:8;
498            bool   processed:1;
499        };
500        std::list<GOTargetInfo> m_UniqueGOTargetInfo;
501
502        struct ItemTargetInfo
503        {
504            Item  *item;
505            uint8 effectMask;
506        };
507        std::list<ItemTargetInfo> m_UniqueItemInfo;
508
509        void AddUnitTarget(Unit* target, uint32 effIndex);
510        void AddUnitTarget(uint64 unitGUID, uint32 effIndex);
511        void AddGOTarget(GameObject* target, uint32 effIndex);
512        void AddGOTarget(uint64 goGUID, uint32 effIndex);
513        void AddItemTarget(Item* target, uint32 effIndex);
514        void DoAllEffectOnTarget(TargetInfo *target);
515        void DoSpellHitOnUnit(Unit *unit, uint32 effectMask);
516        void DoAllEffectOnTarget(GOTargetInfo *target);
517        void DoAllEffectOnTarget(ItemTargetInfo *target);
518        bool IsAliveUnitPresentInTargetList();
519        void SearchAreaTarget(std::list<Unit*> &data, float radius, const uint32 &type,
520            SpellTargets TargetType, uint32 entry = 0);
521        Unit* SearchNearbyTarget(float radius, SpellTargets TargetType, uint32 entry = 0);
522        void SearchChainTarget(std::list<Unit*> &data, Unit* pUnitTarget, float max_range, uint32 unMaxTargets);
523        // -------------------------------------------
524
525        //List For Triggered Spells
526        typedef std::list<SpellEntry const*> TriggerSpells;
527        TriggerSpells m_TriggerSpells;
528
529        uint32 m_spellState;
530        uint32 m_timer;
531
532        float m_castPositionX;
533        float m_castPositionY;
534        float m_castPositionZ;
535        float m_castOrientation;
536        bool m_IsTriggeredSpell;
537
538        // if need this can be replaced by Aura copy
539        // we can't store original aura link to prevent access to deleted auras
540        // and in same time need aura data and after aura deleting.
541        SpellEntry const* m_triggeredByAuraSpell;
542};
543
544namespace Trinity
545{
546    struct TRINITY_DLL_DECL SpellNotifierCreatureAndPlayer
547    {
548        std::list<Unit*> *i_data;
549        Spell &i_spell;
550        const uint32& i_push_type;
551        float i_radius;
552        SpellTargets i_TargetType;
553        Unit* i_caster;
554        uint32 i_entry;
555
556        SpellNotifierCreatureAndPlayer(Spell &spell, std::list<Unit*> &data, float radius, const uint32 &type,
557            SpellTargets TargetType = SPELL_TARGETS_AOE_DAMAGE, uint32 entry = 0)
558            : i_data(&data), i_spell(spell), i_push_type(type), i_radius(radius), i_TargetType(TargetType), i_entry(entry)
559        {
560            i_caster = spell.GetCaster();
561        }
562
563        template<class T> inline void Visit(GridRefManager<T>  &m)
564        {
565            assert(i_data);
566
567            if(!i_caster)
568                return;
569
570            for(typename GridRefManager<T>::iterator itr = m.begin(); itr != m.end(); ++itr)
571            {
572                if( !itr->getSource()->isAlive() || (itr->getSource()->GetTypeId() == TYPEID_PLAYER && ((Player*)itr->getSource())->isInFlight()))
573                    continue;
574
575                switch (i_TargetType)
576                {
577                    case SPELL_TARGETS_FRIENDLY:
578                        if (!itr->getSource()->isTargetableForAttack() || !i_caster->IsFriendlyTo( itr->getSource() ))
579                            continue;
580                        break;
581                    case SPELL_TARGETS_AOE_DAMAGE:
582                    {
583                        if(itr->getSource()->GetTypeId()==TYPEID_UNIT && ((Creature*)itr->getSource())->isTotem())
584                            continue;
585                        if(!itr->getSource()->isTargetableForAttack())
586                            continue;
587
588                        Unit* check = i_caster->GetCharmerOrOwnerOrSelf();
589
590                        if( check->GetTypeId()==TYPEID_PLAYER )
591                        {
592                            if (check->IsFriendlyTo( itr->getSource() ))
593                                continue;
594                        }
595                        else
596                        {
597                            if (!check->IsHostileTo( itr->getSource() ))
598                                continue;
599                        }
600                    }break;
601                    case SPELL_TARGETS_ENTRY:
602                    {
603                        if(itr->getSource()->GetTypeId()!=TYPEID_UNIT || itr->getSource()->GetEntry()!= i_entry)
604                            continue;
605                    }break;
606                    default: continue;
607                }
608
609                switch(i_push_type)
610                {
611                    case PUSH_IN_FRONT:
612                        if(i_caster->isInFront((Unit*)(itr->getSource()), i_radius, M_PI/3 ))
613                            i_data->push_back(itr->getSource());
614                        break;
615                    case PUSH_IN_BACK:
616                        if(i_caster->isInBack((Unit*)(itr->getSource()), i_radius, M_PI/3 ))
617                            i_data->push_back(itr->getSource());
618                        break;
619                    case PUSH_IN_LINE:
620                        if(i_caster->isInLine((Unit*)(itr->getSource()), i_radius ))
621                            i_data->push_back(itr->getSource());
622                        break;
623                    case PUSH_SELF_CENTER:
624                        if(i_caster->IsWithinDistInMap((Unit*)(itr->getSource()), i_radius))
625                            i_data->push_back(itr->getSource());
626                        break;
627                    case PUSH_DEST_CENTER:
628                        if((itr->getSource()->GetDistance(i_spell.m_targets.m_destX, i_spell.m_targets.m_destY, i_spell.m_targets.m_destZ) < i_radius ))
629                            i_data->push_back(itr->getSource());
630                        break;
631                }
632            }
633        }
634
635        #ifdef WIN32
636        template<> inline void Visit(CorpseMapType & ) {}
637        template<> inline void Visit(GameObjectMapType & ) {}
638        template<> inline void Visit(DynamicObjectMapType & ) {}
639        #endif
640    };
641
642    #ifndef WIN32
643    template<> inline void SpellNotifierCreatureAndPlayer::Visit(CorpseMapType& ) {}
644    template<> inline void SpellNotifierCreatureAndPlayer::Visit(GameObjectMapType& ) {}
645    template<> inline void SpellNotifierCreatureAndPlayer::Visit(DynamicObjectMapType& ) {}
646    #endif
647}
648
649typedef void(Spell::*pEffect)(uint32 i);
650
651class SpellEvent : public BasicEvent
652{
653    public:
654        SpellEvent(Spell* spell);
655        virtual ~SpellEvent();
656
657        virtual bool Execute(uint64 e_time, uint32 p_time);
658        virtual void Abort(uint64 e_time);
659    protected:
660        Spell* m_Spell;
661};
662#endif
Note: See TracBrowser for help on using the browser.