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