2 * Copyright (C) 2005,2006 MaNGOS <http://www.mangosproject.org/>
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
22 #include "GridDefines.h"
23 #include "Database/DBCStores.h"
35 #define SKILL_TAILORING 197
36 #define SKILL_ALCHEMY 171
37 #define SKILL_LEATHERWORKING 165
38 #define SKILL_ENGINERING 202
39 #define SKILL_FIRST_AID 129
40 #define SKILL_MINING 186
41 #define SKILL_COOKING 185
42 #define SKILL_POISONS 40
43 #define SKILL_SKINNING 393
44 #define SKILL_ENCHANTING 333
45 #define SKILL_BLACKSMITHING 164
46 #define SKILL_HERBALISM 182
47 #define SKILL_FISHING 356
48 #define SKILL_OPENLOCK 242
50 enum SpellCastTargetFlags
52 TARGET_FLAG_SELF
= 0x0000,
53 TARGET_FLAG_UNIT
= 0x0002,
54 TARGET_FLAG_OBJECT
= 0x0800,
55 TARGET_FLAG_ITEM
= 0x1010,
56 TARGET_FLAG_SOURCE_LOCATION
= 0x0020,
57 TARGET_FLAG_DEST_LOCATION
= 0x0040,
58 TARGET_FLAG_STRING
= 0x2000
67 TARGET_AE_E_INSTANT
= 16,
73 TARGET_DUELVSPLAYER
= 25,
75 TARGET_AE_E_CHANNEL
= 28,
78 TARGET_SELF_FISHING
= 39,
79 TARGET_TOTEM_EARTH
= 41,
80 TARGET_TOTEM_WATER
= 42,
81 TARGET_TOTEM_AIR
= 43,
82 TARGET_TOTEM_FIRE
= 44,
84 TARGET_DY_OBJ
= 47, //DynamicObject
85 TARGET_AE_SELECTED
= 53,
86 TARGET_S_F_2
= 57, //single friend
91 CAST_FLAG_UNKNOWN1
= 0x2,
92 CAST_FLAG_UNKNOWN2
= 0x10,
96 enum SpellNotifyPushType
102 struct TeleportCoords
113 struct SpellNotifierPlayer
;
114 struct SpellNotifierCreatureAndPlayer
;
117 class SpellCastTargets
124 void read ( WorldPacket
* data
,Unit
*caster
);
125 void write ( WorldPacket
* data
);
127 SpellCastTargets
& operator=(const SpellCastTargets
&target
)
129 m_unitTarget
= target
.m_unitTarget
;
130 m_itemTarget
= target
.m_itemTarget
;
131 m_GOTarget
= target
.m_GOTarget
;
133 m_srcX
= target
.m_srcX
;
134 m_srcY
= target
.m_srcY
;
135 m_srcZ
= target
.m_srcZ
;
137 m_destX
= target
.m_destX
;
138 m_destY
= target
.m_destY
;
139 m_destZ
= target
.m_destZ
;
141 m_strTarget
= target
.m_strTarget
;
143 m_targetMask
= target
.m_targetMask
;
147 Unit
*getUnitTarget() { return m_unitTarget
;};
148 void setUnitTarget(Unit
*target
)
150 m_destX
= target
->GetPositionX();
151 m_destY
= target
->GetPositionY();
152 m_destZ
= target
->GetPositionZ();
153 m_unitTarget
= target
;
157 GameObject
*m_GOTarget
;
158 float m_srcX
, m_srcY
, m_srcZ
;
159 float m_destX
, m_destY
, m_destZ
;
160 std::string m_strTarget
;
169 SPELL_STATE_NULL
= 0,
170 SPELL_STATE_PREPARING
= 1,
171 SPELL_STATE_CASTING
= 2,
172 SPELL_STATE_FINISHED
= 3,
186 FORM_CREATUREBEAR
= 14,
188 FORM_BATTLESTANCE
= 17,
189 FORM_DEFENSIVESTANCE
= 18,
190 FORM_BERSERKERSTANCE
= 19,
195 enum SpellFailedReason
197 CAST_FAIL_ALREADY_FULL_HEALTH
= 1,
198 CAST_FAIL_ALREADY_FULL_MANA
= 2,
199 //CAST_FAIL_ALREADY_FULL_RAGE = 2,
200 CAST_FAIL_CREATURE_ALREADY_TAMING
= 3,
201 CAST_FAIL_ALREADY_HAVE_CHARMED
= 4,
202 CAST_FAIL_ALREADY_HAVE_SUMMON
= 5,
203 CAST_FAIL_ALREADY_OPEN
= 6,
204 CAST_FAIL_MORE_POWERFUL_SPELL_ACTIVE
= 7,
205 CAST_FAIL_FAILED
= 8,
206 CAST_FAIL_NO_TARGET
= 9,
207 CAST_FAIL_INVALID_TARGET
= 10,
208 CAST_FAIL_CANT_BE_CHARMED
= 11,
209 CAST_FAIL_CANT_BE_DISENCHANTED
= 12,
210 CAST_FAIL_TARGET_IS_TAPPED
= 13,
211 CAST_FAIL_CANT_START_DUEL_INVISIBLE
= 14,
212 CAST_FAIL_CANT_START_DUEL_STEALTHED
= 15,
213 CAST_FAIL_TOO_CLOSE_TO_ENEMY
= 16,
214 CAST_FAIL_CANT_DO_THAT_YET
= 17,
215 CAST_FAIL_YOU_ARE_DEAD
= 18,
216 CAST_FAIL_OBJECT_ALREADY_BEING_USED
= 19,
217 CAST_FAIL_CANT_DO_WHILE_CONFUSED
= 20,
218 CAST_FAIL_MUST_HAVE_ITEM_EQUIPPED
= 22,
219 CAST_FAIL_MUST_HAVE_XXXX_EQUIPPED
= 23,
220 CAST_FAIL_MUST_HAVE_XXXX_IN_MAINHAND
= 24,
221 CAST_FAIL_INTERNAL_ERROR
= 25,
222 CAST_FAIL_FIZZLED
= 26,
223 CAST_FAIL_YOU_ARE_FLEEING
= 27,
224 CAST_FAIL_FOOD_TOO_LOWLEVEL_FOR_PET
= 28,
225 CAST_FAIL_TARGET_IS_TOO_HIGH
= 29,
226 CAST_FAIL_IMMUNE
= 32, // was 31 in pre 1.7
227 CAST_FAIL_INTERRUPTED
= 33, // was 32 in pre 1.7
228 //CAST_FAIL_INTERRUPTED_COMBAT = 31,
229 CAST_FAIL_ITEM_ALREADY_ENCHANTED
= 34,
230 CAST_FAIL_ITEM_IS_GONE
= 35,
231 CAST_FAIL_ENCHANT_NOT_EXISTING_ITEM
= 36,
232 CAST_FAIL_ITEM_NOT_READY
= 37,
233 CAST_FAIL_YOU_ARE_NOT_HIGH_ENOUGH
= 38,
234 CAST_FAIL_NOT_IN_LINE_OF_SIGHT
= 39,
235 CAST_FAIL_TARGET_TOO_LOW
= 40,
236 CAST_FAIL_SKILL_NOT_HIGH_ENOUGH
= 41,
237 CAST_FAIL_WEAPON_HAND_IS_EMPTY
= 42,
238 CAST_FAIL_CANT_DO_WHILE_MOVING
= 43,
239 CAST_FAIL_NEED_AMMO_IN_PAPERDOLL_SLOT
= 44,
240 CAST_FAIL_REQUIRES_SOMETHING
= 45,
241 CAST_FAIL_NEED_EXOTIC_AMMO
= 46,
242 CAST_FAIL_NO_PATH_AVAILABLE
= 47,
243 CAST_FAIL_NOT_BEHIND_TARGET
= 48,
244 CAST_FAIL_DIDNT_LAND_IN_FISHABLE_WATER
= 49,
245 CAST_FAIL_CANT_BE_CAST_HERE
= 50,
246 CAST_FAIL_NOT_IN_FRONT_OF_TARGET
= 51,
247 CAST_FAIL_NOT_IN_CONTROL_OF_ACTIONS
= 52,
248 CAST_FAIL_SPELL_NOT_LEARNED
= 53,
249 CAST_FAIL_CANT_USE_WHEN_MOUNTED
= 54,
250 CAST_FAIL_YOU_ARE_IN_FLIGHT
= 55,
251 CAST_FAIL_YOU_ARE_ON_TRANSPORT
= 56,
252 CAST_FAIL_SPELL_NOT_READY_YET
= 57,
253 CAST_FAIL_CANT_DO_IN_SHAPESHIFT
= 58,
254 CAST_FAIL_HAVE_TO_BE_STANDING
= 59,
255 CAST_FAIL_CAN_USE_ONLY_ON_OWN_OBJECT
= 60, // rogues trying "enchant" other's weapon with poison
256 CAST_FAIL_CANT_ENCHANT_TRADE_ITEM
= 61,
257 CAST_FAIL_HAVE_TO_BE_UNSHEATHED
= 62, // yellow text
258 CAST_FAIL_CANT_CAST_AS_GHOST
= 63,
259 CAST_FAIL_NO_AMMO
= 64,
260 CAST_FAIL_NO_CHARGES_REMAIN
= 65,
261 CAST_FAIL_COMBO_POINTS_REQUIRED
= 66,
262 CAST_FAIL_NO_DUELING_HERE
= 67,
263 CAST_FAIL_NOT_ENOUGH_ENDURANCE
= 68,
264 CAST_FAIL_THERE_ARENT_ANY_FISH_HERE
= 69,
265 CAST_FAIL_CANT_USE_WHILE_SHAPESHIFTED
= 70,
266 CAST_FAIL_CANT_MOUNT_HERE
= 71,
267 CAST_FAIL_YOU_DO_NOT_HAVE_PET
= 72,
268 CAST_FAIL_NOT_ENOUGH_MANA
= 73,
269 CAST_FAIL_CANT_USE_WHILE_SWIMMING
= 74,
270 CAST_FAIL_CAN_ONLY_USE_AT_DAY
= 75,
271 CAST_FAIL_CAN_ONLY_USE_INDOORS
= 76,
272 CAST_FAIL_CAN_ONLY_USE_MOUNTED
= 77,
273 CAST_FAIL_CAN_ONLY_USE_AT_NIGHT
= 78,
274 CAST_FAIL_CAN_ONLY_USE_OUTDOORS
= 79,
275 //CAST_FAIL_ONLY_SHAPESHIFTED = 80, // didn't display
276 CAST_FAIL_CAN_ONLY_USE_STEALTHED
= 81,
277 CAST_FAIL_CAN_ONLY_USE_WHILE_SWIMMING
= 82,
278 CAST_FAIL_OUT_OF_RANGE
= 83,
279 CAST_FAIL_CANT_USE_WHILE_PACIFIED
= 84,
280 CAST_FAIL_YOU_ARE_POSSESSED
= 85,
281 CAST_FAIL_YOU_NEED_TO_BE_IN_XXX
= 87,
282 CAST_FAIL_REQUIRES_XXX
= 88,
283 CAST_FAIL_UNABLE_TO_MOVE
= 89,
284 CAST_FAIL_SILENCED
= 90,
285 CAST_FAIL_ANOTHER_ACTION_IS_IN_PROGRESS
= 91,
286 CAST_FAIL_ALREADY_LEARNED_THAT_SPELL
= 92,
287 CAST_FAIL_SPELL_NOT_AVAILABLE_TO_YOU
= 93,
288 CAST_FAIL_CANT_DO_WHILE_STUNNED
= 94,
289 CAST_FAIL_YOUR_TARGET_IS_DEAD
= 95,
290 CAST_FAIL_TARGET_IS_IN_COMBAT
= 96,
291 CAST_FAIL_CANT_DO_THAT_YET_2
= 97,
292 CAST_FAIL_TARGET_IS_DUELING
= 98,
293 CAST_FAIL_TARGET_IS_HOSTILE
= 99,
294 CAST_FAIL_TARGET_IS_TOO_ENRAGED_TO_CHARM
= 100,
295 CAST_FAIL_TARGET_IS_FRIENDLY
= 101,
296 CAST_FAIL_TARGET_CANT_BE_IN_COMBAT
= 102,
297 CAST_FAIL_CANT_TARGET_PLAYERS
= 103,
298 CAST_FAIL_TARGET_IS_ALIVE
= 104,
299 CAST_FAIL_TARGET_NOT_IN_YOUR_PARTY
= 104,
300 CAST_FAIL_CREATURE_MUST_BE_LOOTED_FIRST
= 106,
301 CAST_FAIL_TARGET_IS_NOT_A_PLAYER
= 107,
302 CAST_FAIL_NO_POCKETS_TO_PICK
= 108,
303 CAST_FAIL_TARGET_HAS_NO_WEAPONS_EQUIPPED
= 109,
304 CAST_FAIL_NOT_SKINNABLE
= 110,
305 CAST_FAIL_TOO_CLOSE
= 112,
306 CAST_FAIL_TOO_MANY_OF_THAT_ITEM_ALREADY
= 113,
307 CAST_FAIL_NOT_ENOUGH_TRAINING_POINTS
= 115,
308 CAST_FAIL_FAILED_ATTEMPT
= 116,
309 CAST_FAIL_TARGET_NEED_TO_BE_BEHIND
= 117,
310 CAST_FAIL_TARGET_NEED_TO_BE_INFRONT
= 118,
311 CAST_FAIL_PET_DOESNT_LIKE_THAT_FOOD
= 119,
312 CAST_FAIL_CANT_CAST_WHILE_FATIGUED
= 120,
313 CAST_FAIL_TARGET_MUST_BE_IN_THIS_INSTANCE
= 121,
314 CAST_FAIL_CANT_CAST_WHILE_TRADING
= 122,
315 CAST_FAIL_TARGET_IS_NOT_PARTY_OR_RAID
= 123,
316 CAST_FAIL_CANT_DISENCHANT_WHILE_LOOTING
= 124,
317 CAST_FAIL_TARGET_IS_IN_FFA_PVP_COMBAT
= 125,
318 CAST_FAIL_NO_NEARBY_CORPSES_TO_EAT
= 126,
319 CAST_FAIL_CAN_ONLY_USE_IN_BATTLEGROUNDS
= 127,
320 CAST_FAIL_TARGET_IS_NOT_A_GHOST
= 128,
321 CAST_FAIL_YOUR_PET_CANT_LEARN_MORE_SKILLS
= 129,
322 CAST_FAIL_UNKNOWN_REASON
= 130,
326 #define SPELL_SPELL_CHANNEL_UPDATE_INTERVAL 1000
330 friend struct MaNGOS::SpellNotifierPlayer
;
331 friend struct MaNGOS::SpellNotifierCreatureAndPlayer
;
334 void EffectNULL(uint32
);
335 void EffectSchoolDMG(uint32 i
);
336 void EffectTepeportUnits(uint32 i
);
337 void EffectApplyAura(uint32 i
);
338 void EffectPowerDrain(uint32 i
);
339 void EffectHeal(uint32 i
);
340 void EffectHealthLeach(uint32 i
);
341 void EffectCreateItem(uint32 i
);
342 void EffectPresistentAA(uint32 i
);
343 void EffectEnergize(uint32 i
);
344 void EffectOpenLock(uint32 i
);
345 void EffectOpenSecretSafe(uint32 i
);
346 void EffectApplyAA(uint32 i
);
347 void EffectLearnSpell(uint32 i
);
348 void EffectDispel(uint32 i
);
349 void EffectSummonWild(uint32 i
);
350 void EffectLearnSkill(uint32 i
);
351 void EffectEnchantItemPerm(uint32 i
);
352 void EffectEnchantItemTmp(uint32 i
);
353 void EffectSummonPet(uint32 i
);
354 void EffectWeaponDmg(uint32 i
);
355 void EffectWeaponDmgPerc(uint32 i
);
356 void EffectHealMaxHealth(uint32 i
);
357 void EffectInterruptCast(uint32 i
);
358 void EffectAddComboPoints(uint32 i
);
359 void EffectDuel(uint32 i
);
360 void EffectSummonTotem(uint32 i
);
361 void EffectEnchantHeldItem(uint32 i
);
362 void EffectSummonObject(uint32 i
);
363 void EffectResurrect(uint32 i
);
364 void EffectMomentMove(uint32 i
); //by vendy
365 void EffectTransmitted(uint32 i
);
366 void EffectTriggerSpell(uint32 i
);
367 void EffectSkinning(uint32 i
);
368 void EffectSkill(uint32
);
370 Spell( Unit
* Caster
, SpellEntry
*info
, bool triggered
, Aura
* Aur
);
372 void prepare(SpellCastTargets
* targets
);
374 void update(uint32 difftime
);
382 uint32
CalculateDamage(uint8 i
);
383 void HandleTeleport(uint32 id
, Unit
* Target
);
384 void Delayed(int32 delaytime
);
385 void reflect(Unit
*refunit
);
386 inline uint32
getState() { return m_spellState
; }
388 void writeSpellGoTargets( WorldPacket
* data
);
389 void FillTargetMap();
390 void SetTargetMap(uint32 i
,uint32 cur
,std::list
<Unit
*> &TagUnitMap
,std::list
<Item
*> &TagItemMap
,std::list
<GameObject
*> &TagGOMap
);
392 void SendCastResult(uint8 result
);
393 void SendSpellStart();
395 void SendLogExecute();
396 void SendInterrupted(uint8 result
);
397 void SendChannelUpdate(uint32 time
);
398 void SendChannelStart(uint32 duration
);
399 void SendResurrectRequest(Player
* target
);
401 void HandleEffects(Unit
*pUnitTarget
,Item
*pItemTarget
,GameObject
*pGOTarget
,uint32 i
);
402 void HandleAddAura(Unit
* Target
);
404 SpellEntry
* m_spellInfo
;
406 SpellCastTargets m_targets
;
414 // Current targets, to be used in SpellEffects
417 GameObject
* gameObjTarget
;
418 // -------------------------------------------
422 // List of all Spell targets
423 std::list
<Unit
*> m_targetUnits
[3];
424 std::list
<Item
*> m_targetItems
[3];
425 std::list
<GameObject
*> m_targetGOs
[3];
426 // -------------------------------------------
428 // List of all targets that arent repeated. (Unique)
430 std::list
<Unit
*> UniqueTargets
;
431 std::list
<GameObject
*> UniqueGOsTargets
;
432 // -------------------------------------------
436 uint32 m_intervalTimer
;
437 SpellEntry
* m_TriggerSpell
;
439 float m_castPositionX
;
440 float m_castPositionY
;
441 float m_castPositionZ
;
442 bool m_Istriggeredpell
;
443 Aura
* m_triggeredByAura
;
446 // List of all Objects to be Deleted in spell Finish
447 std::list
<DynamicObject
*> m_dynObjToDel
;
448 std::list
<GameObject
*> m_ObjToDel
;
449 // -------------------------------------------
454 REPLENISH_UNDEFINED
= 0,
455 REPLENISH_HEALTH
= 20,
462 struct MANGOS_DLL_DECL SpellNotifierPlayer
464 std::list
<Unit
*> &i_data
;
466 const uint32
& i_index
;
467 SpellNotifierPlayer(Spell
&spell
, std::list
<Unit
*> &data
, const uint32
&i
) : i_data(data
), i_spell(spell
), i_index(i
) {}
468 inline void Visit(PlayerMapType
&m
)
470 float radius
= GetRadius(sSpellRadius
.LookupEntry(i_spell
.m_spellInfo
->EffectRadiusIndex
[i_index
]));
471 for(PlayerMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
473 if( !itr
->second
->isAlive() )
475 if( itr
->second
->GetDistanceSq(i_spell
.m_targets
.m_destX
, i_spell
.m_targets
.m_destY
, i_spell
.m_targets
.m_destZ
) < radius
* radius
476 && itr
->second
->GetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE
) != i_spell
.m_caster
->GetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE
) )
477 if(( itr
->second
->GetDistanceSq(i_spell
.m_targets
.m_destX
, i_spell
.m_targets
.m_destY
, i_spell
.m_targets
.m_destZ
) < radius
* radius
)
478 && itr
->second
->GetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE
) != i_spell
.m_caster
->GetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE
) )
479 i_data
.push_back(itr
->second
);
484 struct MANGOS_DLL_DECL SpellNotifierCreatureAndPlayer
486 std::list
<Unit
*> &i_data
;
488 const uint32
& i_index
;
489 const uint32
& i_push_type
;
490 SpellNotifierCreatureAndPlayer(Spell
&spell
, std::list
<Unit
*> &data
, const uint32
&i
,const uint32
&type
)
491 : i_data(data
), i_spell(spell
), i_index(i
), i_push_type(type
){}
493 template<class T
> inline void Visit(std::map
<OBJECT_HANDLE
, T
*> &m
)
495 float radius
= GetRadius(sSpellRadius
.LookupEntry(i_spell
.m_spellInfo
->EffectRadiusIndex
[i_index
]));
496 for(typename
std::map
<OBJECT_HANDLE
, T
*>::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
502 if((i_spell
.m_caster
->isInFront((Unit
*)(itr
->second
), radius
)) && (itr
->second
)->GetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE
) != i_spell
.m_caster
->GetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE
))
503 i_data
.push_back(itr
->second
);
505 case PUSH_SELF_CENTER
:
506 if((i_spell
.m_caster
->GetDistanceSq( (Unit
*)(itr
->second
) ) < radius
* radius
) && itr
->second
->GetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE
) != i_spell
.m_caster
->GetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE
) )
507 i_data
.push_back(itr
->second
);
509 case PUSH_DEST_CENTER
:
510 if((itr
->second
->GetDistanceSq(i_spell
.m_targets
.m_destX
, i_spell
.m_targets
.m_destY
, i_spell
.m_targets
.m_destZ
) < radius
* radius
) && itr
->second
->GetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE
) != i_spell
.m_caster
->GetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE
) )
511 i_data
.push_back(itr
->second
);
518 template<> inline void Visit(std::map
<OBJECT_HANDLE
, Corpse
*> &m
) {}
519 template<> inline void Visit(std::map
<OBJECT_HANDLE
, GameObject
*> &m
) {}
520 template<> inline void Visit(std::map
<OBJECT_HANDLE
, DynamicObject
*> &m
) {}
525 template<> inline void SpellNotifierCreatureAndPlayer::Visit(std::map
<OBJECT_HANDLE
, Corpse
*> &m
) {}
526 template<> inline void SpellNotifierCreatureAndPlayer::Visit(std::map
<OBJECT_HANDLE
, GameObject
*> &m
) {}
527 template<> inline void SpellNotifierCreatureAndPlayer::Visit(std::map
<OBJECT_HANDLE
, DynamicObject
*> &m
) {}
532 typedef void(Spell::*pEffect
)(uint32 i
);