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