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
20 #include "Database/DatabaseEnv.h"
21 #include "WorldPacket.h"
22 #include "WorldSession.h"
25 #include "UpdateMask.h"
27 #include "ObjectMgr.h"
30 #include "CreatureAI.h"
32 #include "DynamicObject.h"
33 #include "SpellAuras.h"
35 #include "UpdateData.h"
36 #include "MapManager.h"
37 #include "ObjectAccessor.h"
38 #include "RedZoneDistrict.h"
40 #include "SharedDefines.h"
42 #include "GameObject.h"
43 #include "GossipDef.h"
46 #include "CreatureAI.h"
48 pEffect SpellEffects
[TOTAL_SPELL_EFFECTS
]=
50 &Spell::EffectNULL
, //nothing
51 &Spell::EffectInstaKill
, //SPELL_EFFECT_INSTAKILL = 1
52 &Spell::EffectSchoolDMG
, //SPELL_EFFECT_SCHOOL_DAMAGE = 2
53 &Spell::EffectDummy
, //SPELL_EFFECT_DUMMY = 3
54 &Spell::EffectNULL
, //SPELL_EFFECT_PORTAL_TELEPORT = 4
55 &Spell::EffectTeleportUnits
, //SPELL_EFFECT_TELEPORT_UNITS = 5
56 &Spell::EffectApplyAura
, //SPELL_EFFECT_APPLY_AURA = 6
57 &Spell::EffectSchoolDMG
, //SPELL_EFFECT_ENVIRONMENTAL_DAMAGE =7
58 &Spell::EffectManaDrain
, //SPELL_EFFECT_MANA_DRAIN = 8
59 &Spell::EffectHealthLeach
, //SPELL_EFFECT_HEALTH_LEECH = 9
60 &Spell::EffectHeal
, //SPELL_EFFECT_HEAL = 10
61 &Spell::EffectNULL
, //SPELL_EFFECT_BIND = 11
62 &Spell::EffectNULL
, //SPELL_EFFECT_PORTAL = 12
63 &Spell::EffectNULL
, //SPELL_EFFECT_RITUAL_BASE = 13
64 &Spell::EffectNULL
, //SPELL_EFFECT_RITUAL_SPECIALIZE = 14
65 &Spell::EffectNULL
, //SPELL_EFFECT_RITUAL_ACTIVATE_PORTAL = 15
66 &Spell::EffectQuestComplete
, //SPELL_EFFECT_QUEST_COMPLETE = 16
67 &Spell::EffectWeaponDmg
, //SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL = 17
68 &Spell::EffectResurrect
, //SPELL_EFFECT_RESURRECT = 18
69 &Spell::EffectNULL
, //SPELL_EFFECT_ADD_EXTRA_ATTACKS = 19
70 &Spell::EffectNULL
, //SPELL_EFFECT_DODGE = 20
71 &Spell::EffectNULL
, //SPELL_EFFECT_EVADE = 21
72 &Spell::EffectParry
, //SPELL_EFFECT_PARRY = 22
73 &Spell::EffectNULL
, //SPELL_EFFECT_BLOCK = 23
74 &Spell::EffectCreateItem
, //SPELL_EFFECT_CREATE_ITEM = 24
75 &Spell::EffectNULL
, //SPELL_EFFECT_WEAPON = 25
76 &Spell::EffectNULL
, //SPELL_EFFECT_DEFENSE = 26
77 &Spell::EffectPersistentAA
, //SPELL_EFFECT_PERSISTENT_AREA_AURA = 27
78 &Spell::EffectSummon
, //SPELL_EFFECT_SUMMON = 28
79 &Spell::EffectMomentMove
, //SPELL_EFFECT_LEAP = 29
80 &Spell::EffectEnergize
, //SPELL_EFFECT_ENERGIZE = 30
81 &Spell::EffectWeaponDmg
, //SPELL_EFFECT_WEAPON_PERCENT_DAMAGE = 31
82 &Spell::EffectNULL
, //SPELL_EFFECT_TRIGGER_MISSILE = 32 //Useless
83 &Spell::EffectOpenLock
, //SPELL_EFFECT_OPEN_LOCK = 33
84 &Spell::EffectSummonChangeItem
, //SPELL_EFFECT_SUMMON_CHANGE_ITEM = 34
85 &Spell::EffectApplyAA
, //SPELL_EFFECT_APPLY_AREA_AURA = 35
86 &Spell::EffectLearnSpell
, //SPELL_EFFECT_LEARN_SPELL = 36
87 &Spell::EffectNULL
, //SPELL_EFFECT_SPELL_DEFENSE = 37 //Useless
88 &Spell::EffectDispel
, //SPELL_EFFECT_DISPEL = 38
89 &Spell::EffectNULL
, //SPELL_EFFECT_LANGUAGE = 39
90 &Spell::EffectDualWield
, //SPELL_EFFECT_DUAL_WIELD = 40
91 &Spell::EffectSummonWild
, //SPELL_EFFECT_SUMMON_WILD = 41
92 &Spell::EffectSummonWild
, //SPELL_EFFECT_SUMMON_GUARDIAN = 42
93 &Spell::EffectTeleUnitsFaceCaster
, //SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER = 43
94 &Spell::EffectLearnSkill
, //SPELL_EFFECT_SKILL_STEP = 44
95 &Spell::EffectNULL
, //unknown45 = 45
96 &Spell::EffectNULL
, //SPELL_EFFECT_SPAWN = 46
97 &Spell::EffectTradeSkill
, //SPELL_EFFECT_TRADE_SKILL = 47
98 &Spell::EffectNULL
, //SPELL_EFFECT_STEALTH = 48 //Useless
99 &Spell::EffectNULL
, //SPELL_EFFECT_DETECT = 49
100 &Spell::EffectTransmitted
, //SPELL_EFFECT_TRANS_DOOR = 50
101 &Spell::EffectNULL
, //SPELL_EFFECT_FORCE_CRITICAL_HIT = 51 //Useless
102 &Spell::EffectNULL
, //SPELL_EFFECT_GUARANTEE_HIT = 52
103 &Spell::EffectEnchantItemPerm
, //SPELL_EFFECT_ENCHANT_ITEM = 53
104 &Spell::EffectEnchantItemTmp
, //SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY = 54
105 &Spell::EffectTameCreature
, //SPELL_EFFECT_TAMECREATURE = 55
106 &Spell::EffectSummonPet
, //SPELL_EFFECT_SUMMON_PET = 56
107 &Spell::EffectLearnPetSpell
, //SPELL_EFFECT_LEARN_PET_SPELL = 57
108 &Spell::EffectWeaponDmg
, //SPELL_EFFECT_WEAPON_DAMAGE = 58
109 &Spell::EffectOpenSecretSafe
, //SPELL_EFFECT_OPEN_LOCK_ITEM = 59
110 &Spell::EffectProficiency
, //SPELL_EFFECT_PROFICIENCY = 60
111 &Spell::EffectSendEvent
, //SPELL_EFFECT_SEND_EVENT = 61
112 &Spell::EffectPowerDrain
, //SPELL_EFFECT_POWER_BURN = 62
113 &Spell::EffectThreat
, //SPELL_EFFECT_THREAT = 63
114 &Spell::EffectTriggerSpell
, //SPELL_EFFECT_TRIGGER_SPELL = 64
115 &Spell::EffectNULL
, //SPELL_EFFECT_HEALTH_FUNNEL = 65 //Useless
116 &Spell::EffectNULL
, //SPELL_EFFECT_POWER_FUNNEL = 66 //Useless
117 &Spell::EffectHealMaxHealth
, //SPELL_EFFECT_HEAL_MAX_HEALTH = 67
118 &Spell::EffectInterruptCast
, //SPELL_EFFECT_INTERRUPT_CAST = 68
119 &Spell::EffectNULL
, //SPELL_EFFECT_DISTRACT = 69
120 &Spell::EffectNULL
, //SPELL_EFFECT_PULL = 70
121 &Spell::EffectPickPocket
, //SPELL_EFFECT_PICKPOCKET = 71
122 &Spell::EffectNULL
, //SPELL_EFFECT_ADD_FARSIGHT = 72
123 &Spell::EffectSummonWild
, //SPELL_EFFECT_SUMMON_POSSESSED = 73
124 &Spell::EffectNULL
, //SPELL_EFFECT_SUMMON_TOTEM = 74 //Useless
125 &Spell::EffectNULL
, //SPELL_EFFECT_HEAL_MECHANICAL = 75
126 &Spell::EffectNULL
, //SPELL_EFFECT_SUMMON_OBJECT_WILD = 76
127 &Spell::EffectScriptEffect
, //SPELL_EFFECT_SCRIPT_EFFECT = 77
128 &Spell::EffectNULL
, //SPELL_EFFECT_ATTACK = 78 //Useless
129 &Spell::EffectNULL
, //SPELL_EFFECT_SANCTUARY = 79
130 &Spell::EffectAddComboPoints
, //SPELL_EFFECT_ADD_COMBO_POINTS = 80
131 &Spell::EffectNULL
, //SPELL_EFFECT_CREATE_HOUSE = 81
132 &Spell::EffectNULL
, //SPELL_EFFECT_BIND_SIGHT = 82
133 &Spell::EffectDuel
, //SPELL_EFFECT_DUEL = 83
134 &Spell::EffectNULL
, //SPELL_EFFECT_STUCK = 84
135 &Spell::EffectNULL
, //SPELL_EFFECT_SUMMON_PLAYER = 85
136 &Spell::EffectNULL
, //SPELL_EFFECT_ACTIVATE_OBJECT = 86
137 &Spell::EffectSummonTotem
, //SPELL_EFFECT_SUMMON_TOTEM_SLOT1 = 87
138 &Spell::EffectSummonTotem
, //SPELL_EFFECT_SUMMON_TOTEM_SLOT2 = 88
139 &Spell::EffectSummonTotem
, //SPELL_EFFECT_SUMMON_TOTEM_SLOT3 = 89
140 &Spell::EffectSummonTotem
, //SPELL_EFFECT_SUMMON_TOTEM_SLOT4 = 90
141 &Spell::EffectNULL
, //SPELL_EFFECT_THREAT_ALL = 91
142 &Spell::EffectEnchantHeldItem
, //SPELL_EFFECT_ENCHANT_HELD_ITEM = 92
143 &Spell::EffectNULL
, //SPELL_EFFECT_SUMMON_PHANTASM = 93
144 &Spell::EffectSelfResurrect
, //SPELL_EFFECT_SELF_RESURRECT = 94
145 &Spell::EffectSkinning
, //SPELL_EFFECT_SKINNING = 95
146 &Spell::EffectCharge
, //SPELL_EFFECT_CHARGE = 96
147 &Spell::EffectSummonCritter
, //SPELL_EFFECT_SUMMON_CRITTER = 97
148 &Spell::EffectNULL
, //SPELL_EFFECT_KNOCK_BACK = 98
149 &Spell::EffectDisEnchant
, //SPELL_EFFECT_DISENCHANT = 99
150 &Spell::EffectInebriate
, //SPELL_EFFECT_INEBRIATE = 100
151 &Spell::EffectFeedPet
, //SPELL_EFFECT_FEED_PET = 101
152 &Spell::EffectDismissPet
, //SPELL_EFFECT_DISMISS_PET = 102
153 &Spell::EffectReputation
, //SPELL_EFFECT_REPUTATION = 103
154 &Spell::EffectSummonObject
, //SPELL_EFFECT_SUMMON_OBJECT_SLOT1 = 104
155 &Spell::EffectSummonObject
, //SPELL_EFFECT_SUMMON_OBJECT_SLOT2 = 105
156 &Spell::EffectSummonObject
, //SPELL_EFFECT_SUMMON_OBJECT_SLOT3 = 106
157 &Spell::EffectSummonObject
, //SPELL_EFFECT_SUMMON_OBJECT_SLOT4 = 107
158 &Spell::EffectNULL
, //SPELL_EFFECT_DISPEL_MECHANIC = 108
159 &Spell::EffectSummonDeadPet
, //SPELL_EFFECT_SUMMON_DEAD_PET = 109
160 &Spell::EffectNULL
, //SPELL_EFFECT_DESTROY_ALL_TOTEMS = 110
161 &Spell::EffectNULL
, //SPELL_EFFECT_DURABILITY_DAMAGE = 111
162 &Spell::EffectNULL
, //SPELL_EFFECT_SUMMON_DEMON = 112
163 &Spell::EffectResurrectNew
, //SPELL_EFFECT_RESURRECT_NEW = 113
164 &Spell::EffectAttackMe
, //SPELL_EFFECT_ATTACK_ME = 114
165 &Spell::EffectNULL
, //SPELL_EFFECT_DURABILITY_DAMAGE_PCT = 115
166 &Spell::EffectNULL
, //SPELL_EFFECT_SKIN_PLAYER_CORPSE = 116
167 &Spell::EffectNULL
, //SPELL_EFFECT_SPIRIT_HEAL = 117
168 &Spell::EffectSkill
, //SPELL_EFFECT_SKILL = 118 -- professions and more
169 &Spell::EffectNULL
, //SPELL_EFFECT_APPLY_AURA_NEW = 119
170 &Spell::EffectNULL
, //SPELL_EFFECT_TELEPORT_GRAVEYARD = 120
171 &Spell::EffectWeaponDmg
//SPELL_EFFECT_NORMALIZED_WEAPON_DMG = 121
174 void Spell::EffectNULL(uint32 i
)
176 sLog
.outDebug("WORLD: Spell Effect DUMMY");
179 void Spell::EffectResurrectNew(uint32 i
)
181 if(!unitTarget
) return;
182 if(unitTarget
->GetTypeId() != TYPEID_PLAYER
) return;
183 if(unitTarget
->isAlive()) return;
184 if(!unitTarget
->IsInWorld()) return;
186 uint32 health
= m_spellInfo
->EffectBasePoints
[i
]+1;
187 uint32 mana
= m_spellInfo
->EffectMiscValue
[i
];
188 ((Player
*)unitTarget
)->setResurrect(m_caster
->GetGUID(), m_caster
->GetPositionX(), m_caster
->GetPositionY(), m_caster
->GetPositionZ(), health
, mana
);
189 SendResurrectRequest((Player
*)unitTarget
);
192 void Spell::EffectInstaKill(uint32 i
)
194 if( unitTarget
&& unitTarget
->isAlive() )
196 uint32 health
= unitTarget
->GetHealth();
197 m_caster
->DealDamage(unitTarget
, health
, 0, false);
201 void Spell::EffectSchoolDMG(uint32 i
)
203 if( unitTarget
&& unitTarget
->isAlive() )
204 m_caster
->SpellNonMeleeDamageLog(unitTarget
, m_spellInfo
->Id
, damage
);
207 void Spell::EffectDummy(uint32 i
)
212 // More spell specific code in begining
214 // Preparation Rogue - immediately finishes the cooldown on other Rogue abilities
215 if(m_spellInfo
->Id
== 14185)
217 if(m_caster
->GetTypeId()!=TYPEID_PLAYER
)
220 const PlayerSpellMap
& sp_list
= ((Player
*)m_caster
)->GetSpellMap();
221 for (PlayerSpellMap::const_iterator itr
= sp_list
.begin(); itr
!= sp_list
.end(); ++itr
)
223 uint32 classspell
= itr
->first
;
224 SpellEntry
*spellInfo
= sSpellStore
.LookupEntry(classspell
);
226 if (spellInfo
->SpellFamilyName
== SPELLFAMILY_ROGUE
&& spellInfo
->Id
!= 14185 &&
227 (spellInfo
->RecoveryTime
> 0 || spellInfo
->CategoryRecoveryTime
> 0))
230 data
.Initialize(SMSG_CLEAR_COOLDOWN
);
231 data
<< classspell
<< m_caster
->GetGUID();
233 ((Player
*)m_caster
)->GetSession()->SendPacket(&data
);
239 // Cold Snap - immediately finishes the cooldown on Frost spells
240 if(m_spellInfo
->Id
== 12472)
242 if(m_caster
->GetTypeId()!=TYPEID_PLAYER
)
245 const PlayerSpellMap
& sp_list
= ((Player
*)m_caster
)->GetSpellMap();
246 for (PlayerSpellMap::const_iterator itr
= sp_list
.begin(); itr
!= sp_list
.end(); ++itr
)
248 uint32 classspell
= itr
->first
;
249 SpellEntry
*spellInfo
= sSpellStore
.LookupEntry(classspell
);
251 if (spellInfo
->SpellFamilyName
== SPELLFAMILY_MAGE
&& spellInfo
->School
== SPELL_SCHOOL_FROST
&& spellInfo
->Id
!= 12472 &&
252 (spellInfo
->RecoveryTime
> 0 || spellInfo
->CategoryRecoveryTime
> 0))
255 data
.Initialize(SMSG_CLEAR_COOLDOWN
);
256 data
<< classspell
<< m_caster
->GetGUID();
258 ((Player
*)m_caster
)->GetSession()->SendPacket(&data
);
264 // If spell cannibalize and his casted, check special requirements and cast aura Cannibalize is all ok
265 if(m_spellInfo
->Id
== 20577)
267 // non-standard cast requirement check
268 SpellRangeEntry
* srange
= sSpellRangeStore
.LookupEntry(m_spellInfo
->rangeIndex
);
269 float max_range
= GetMaxRange(srange
);
271 FactionTemplateResolver myFaction
= m_caster
->getFactionTemplateEntry();
272 std::list
<Unit
*> UnitList
;
273 MapManager::Instance().GetMap(m_caster
->GetMapId())->GetUnitList(m_caster
->GetPositionX(), m_caster
->GetPositionY(),UnitList
);
274 for(std::list
<Unit
*>::iterator iter
=UnitList
.begin();iter
!=UnitList
.end();iter
++)
276 FactionTemplateResolver its_faction
= (*iter
)->getFactionTemplateEntry();
277 if(myFaction
.IsFriendlyTo(its_faction
) || (*iter
)->isAlive() || (*iter
)->isInFlight() ||
278 (((Creature
*)(*iter
))->GetCreatureInfo()->type
!= CREATURE_TYPE_HUMANOID
&& ((Creature
*)(*iter
))->GetCreatureInfo()->type
!= CREATURE_TYPE_UNDEAD
))
281 if(m_caster
->IsWithinDist(*iter
, max_range
) )
289 // clear cooldown at fail
290 if(m_caster
->GetTypeId()==TYPEID_PLAYER
)
293 data
.Initialize(SMSG_CLEAR_COOLDOWN
);
294 data
<< uint32(20577); // spell id
295 data
<< m_caster
->GetGUID();
297 ((Player
*)m_caster
)->GetSession()->SendPacket(&data
);
300 SendCastResult(CAST_FAIL_NO_NEARBY_CORPSES_TO_EAT
);
304 // ok, main function spell can be casted
306 finish(); // prepere to replacing this cpell cast to main function spell
309 SpellEntry
*spellInfo
= sSpellStore
.LookupEntry( 20578 );
310 Spell
*spell
= new Spell(m_caster
, spellInfo
, false, 0);
313 sLog
.outError("WORLD: unknown spell id %i\n", 20578);
317 SpellCastTargets targets
;
318 targets
.setUnitTarget(m_caster
);
319 spell
->prepare(&targets
);
323 // More generic code later
325 // starshards/curse of agony hack .. this applies to 1.10 only
326 if (m_triggeredByAura
)
328 SpellEntry
*trig_info
= m_triggeredByAura
->GetSpellProto();
329 if ((trig_info
->SpellIconID
== 1485 && trig_info
->SpellFamilyName
== SPELLFAMILY_PRIEST
) ||
330 (trig_info
->SpellIconID
== 544 && trig_info
->SpellFamilyName
== SPELLFAMILY_WARLOCK
))
332 Unit
*tmpTarget
= unitTarget
;
333 unitTarget
= m_triggeredByAura
->GetTarget();
334 damage
= trig_info
->EffectBasePoints
[i
]+1;
336 unitTarget
= tmpTarget
;
340 if(m_spellInfo
->SpellIconID
== 1648)
343 dmg
+= uint32(m_caster
->GetPower(POWER_RAGE
)/10 * FindSpellRank(m_spellInfo
->Id
)*3);
344 m_caster
->SpellNonMeleeDamageLog(unitTarget
, m_spellInfo
->Id
, dmg
);
345 m_caster
->SetPower(POWER_RAGE
,0);
349 void Spell::EffectTriggerSpell(uint32 i
)
351 SpellEntry
*spellInfo
= sSpellStore
.LookupEntry( m_spellInfo
->EffectTriggerSpell
[i
] );
355 sLog
.outError("WORLD: unknown spell id %i\n", m_spellInfo
->EffectTriggerSpell
[i
]);
359 m_TriggerSpell
= spellInfo
;
362 void Spell::EffectTeleportUnits(uint32 i
)
366 HandleTeleport(m_spellInfo
->Id
,unitTarget
);
369 void Spell::EffectApplyAura(uint32 i
)
373 if(!unitTarget
->isAlive())
375 uint8 castResult
= 0;
376 //If m_immuneToState type contain this aura type, IMMUNE aura.
377 for (SpellImmuneList::iterator itr
= unitTarget
->m_spellImmune
[IMMUNITY_EFFECT
].begin(), next
; itr
!= unitTarget
->m_spellImmune
[IMMUNITY_EFFECT
].end(); itr
= next
)
381 if((*itr
)->type
== m_spellInfo
->EffectApplyAuraName
[i
])
383 castResult
= CAST_FAIL_IMMUNE
;
389 SendCastResult(castResult
);
392 sLog
.outDebug("Spell: Aura is: %u", m_spellInfo
->EffectApplyAuraName
[i
]);
394 Aura
* Aur
= new Aura(m_spellInfo
, i
, unitTarget
,m_caster
, m_CastItem
);
396 if (!Aur
->IsPositive() && Aur
->GetTarget()->GetTypeId() == TYPEID_UNIT
)
398 switch (Aur
->GetModifier()->m_auraname
)
400 case SPELL_AURA_MOD_DETECT_RANGE
:
401 case SPELL_AURA_AURAS_VISIBLE
:
404 ((Creature
*)Aur
->GetTarget())->AI().AttackStart(m_caster
);
408 bool added
= unitTarget
->AddAura(Aur
);
410 if (added
&& Aur
->IsTrigger())
413 SpellEntry
*spellInfo
= sSpellStore
.LookupEntry(m_spellInfo
->EffectTriggerSpell
[i
]);
414 if (!spellInfo
) return;
415 if (spellInfo
->EffectImplicitTargetA
[0] == TARGET_SINGLE_ENEMY
&& m_caster
->GetTypeId() == TYPEID_PLAYER
)
417 Unit
*target
= ObjectAccessor::Instance().GetUnit(*m_caster
, ((Player
*)m_caster
)->GetSelection());
420 if (!m_caster
->IsFriendlyTo(target
))
421 Aur
->SetTarget(target
);
431 void Spell::EffectManaDrain(uint32 i
)
433 if(m_spellInfo
->EffectMiscValue
[i
] > 4)
436 Powers drain_power
= Powers(m_spellInfo
->EffectMiscValue
[i
]);
440 if(!unitTarget
->isAlive())
442 if(unitTarget
->getPowerType() != drain_power
)
445 uint32 curPower
= unitTarget
->GetPower(drain_power
);
446 float tmpvalue
= m_spellInfo
->EffectMultipleValue
[i
];
451 if(curPower
< damage
)
452 new_damage
= curPower
;
456 unitTarget
->ModifyPower(drain_power
,-new_damage
);
458 if(drain_power
== POWER_MANA
)
459 m_caster
->ModifyPower(POWER_MANA
,uint32(new_damage
*tmpvalue
));
462 void Spell::EffectSendEvent(uint32 i
)
466 void Spell::EffectPowerDrain(uint32 i
)
470 if(!unitTarget
->isAlive())
472 if(unitTarget
->getPowerType()!=POWER_MANA
)
475 uint32 curPower
= unitTarget
->GetPower(POWER_MANA
);
476 uint32 curHealth
= unitTarget
->GetHealth();
479 if(curPower
< damage
)
480 new_damage
= curPower
;
484 int32 tmpvalue
= int32(new_damage
*m_spellInfo
->EffectMultipleValue
[i
]);
486 unitTarget
->ModifyPower(POWER_MANA
,-new_damage
);
488 m_caster
->ModifyPower(POWER_MANA
,tmpvalue
);
489 m_caster
->SpellNonMeleeDamageLog(unitTarget
, m_spellInfo
->Id
, new_damage
);
493 void Spell::EffectHeal( uint32 i
)
495 if( unitTarget
&& unitTarget
->isAlive() )
497 int32 addhealth
= unitTarget
->SpellHealingBonus(m_spellInfo
, damage
);
498 bool crit
= m_caster
->SpellCriticalBonus(m_spellInfo
, &addhealth
);
499 if(unitTarget
->GetTypeId() == TYPEID_PLAYER
)
500 SendHealSpellOnPlayer(((Player
*)unitTarget
), m_spellInfo
->Id
, addhealth
, crit
);
502 unitTarget
->ModifyHealth( addhealth
);
504 //If the target is in combat, then player is in combat too
505 if( m_caster
!= unitTarget
&&
506 m_caster
->GetTypeId() == TYPEID_PLAYER
&&
507 unitTarget
->GetTypeId() == TYPEID_PLAYER
&&
508 unitTarget
->isInCombatWithPlayer() )
510 ((Player
*)m_caster
)->SetPvP(true);
515 void Spell::EffectHealthLeach(uint32 i
)
519 if(!unitTarget
->isAlive())
522 sLog
.outDebug("HealthLeach :%u", damage
);
524 uint32 curPower
= unitTarget
->GetPower(POWER_MANA
);
525 uint32 curHealth
= unitTarget
->GetHealth();
528 if(curHealth
< damage
)
529 new_damage
= curHealth
;
533 int32 tmpvalue
= int32(new_damage
*m_spellInfo
->EffectMultipleValue
[i
]);
535 m_caster
->ModifyHealth(tmpvalue
);
537 if(unitTarget
->GetTypeId() == TYPEID_PLAYER
)
538 SendHealSpellOnPlayer(((Player
*)unitTarget
), m_spellInfo
->Id
, uint32(tmpvalue
));
540 m_caster
->SpellNonMeleeDamageLog(unitTarget
, m_spellInfo
->Id
, new_damage
);
543 void Spell::EffectCreateItem(uint32 i
)
545 if (m_caster
->GetTypeId() != TYPEID_PLAYER
)
548 Player
* player
= (Player
*)m_caster
;
550 uint32 newitemid
= m_spellInfo
->EffectItemType
[i
];
551 ItemPrototype
const *pProto
= objmgr
.GetItemPrototype( newitemid
);
554 player
->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND
, NULL
, NULL
);
560 if(pProto
->Class
!= ITEM_CLASS_CONSUMABLE
|| m_spellInfo
->SpellFamilyName
!= SPELLFAMILY_MAGE
)
561 num_to_add
= max(m_spellInfo
->EffectBasePoints
[i
]+1, 1);
562 else if(player
->getLevel() >= m_spellInfo
->spellLevel
)
563 num_to_add
= ((player
->getLevel() - (m_spellInfo
->spellLevel
-1))*2);
568 uint8 msg
= player
->CanStoreNewItem( NULL_BAG
, NULL_SLOT
, dest
, newitemid
, num_to_add
, false);
569 if( msg
!= EQUIP_ERR_OK
)
571 player
->SendEquipError( msg
, NULL
, NULL
);
575 Item
*pItem
= player
->StoreNewItem( dest
, newitemid
, num_to_add
, true);
579 player
->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND
, NULL
, NULL
);
583 if( pItem
->GetProto()->Class
!= ITEM_CLASS_CONSUMABLE
)
584 pItem
->SetUInt32Value(ITEM_FIELD_CREATOR
,player
->GetGUIDLow());
586 //should send message "create item" to client.-FIX ME
587 player
->UpdateSkillPro(m_spellInfo
->Id
);
590 void Spell::EffectPersistentAA(uint32 i
)
592 float radius
= GetRadius(sSpellRadiusStore
.LookupEntry(m_spellInfo
->EffectRadiusIndex
[i
]));
593 int32 duration
= GetDuration(m_spellInfo
);
594 DynamicObject
* dynObj
= new DynamicObject();
595 if(!dynObj
->Create(objmgr
.GenerateLowGuid(HIGHGUID_DYNAMICOBJECT
), m_caster
, m_spellInfo
->Id
, i
, m_targets
.m_destX
, m_targets
.m_destY
, m_targets
.m_destZ
, duration
, radius
))
600 dynObj
->SetUInt32Value(OBJECT_FIELD_TYPE
, 65);
601 dynObj
->SetUInt32Value(GAMEOBJECT_DISPLAYID
, 368003);
602 dynObj
->SetUInt32Value(DYNAMICOBJECT_BYTES
, 0x01eeeeee);
603 m_caster
->AddDynObject(dynObj
);
604 dynObj
->AddToWorld();
605 MapManager::Instance().GetMap(dynObj
->GetMapId())->Add(dynObj
);
609 void Spell::EffectEnergize(uint32 i
)
613 if(!unitTarget
->isAlive())
616 if(m_spellInfo
->EffectMiscValue
[i
] > 4)
619 Powers power
= Powers(m_spellInfo
->EffectMiscValue
[i
]);
621 if(unitTarget
->getPowerType() != power
)
624 unitTarget
->ModifyPower(power
,damage
);
627 void Spell::EffectOpenLock(uint32 i
)
632 sLog
.outDebug( "WORLD: Open Lock - No GameObject Target!");
636 if(!m_caster
|| m_caster
->GetTypeId() != TYPEID_PLAYER
)
638 sLog
.outDebug( "WORLD: Open Lock - No Player Caster!");
642 LootType loottype
= LOOT_CORPSE
;
643 uint32 lockId
= gameObjTarget
->GetGOInfo()->sound0
;
644 LockEntry
*lockInfo
= sLockStore
.LookupEntry(lockId
);
647 sLog
.outError( "Spell::EffectOpenLock: gameobject [guid = %u] has an unknown lockId: %u!", gameObjTarget
->GetGUIDLow() , lockId
);
652 if(m_spellInfo
->EffectMiscValue
[0]==LOCKTYPE_HERBALISM
)
654 skill
= ((Player
*)m_caster
)->GetSkillValue(SKILL_HERBALISM
);
655 loottype
= LOOT_SKINNING
;
657 if(m_spellInfo
->EffectMiscValue
[0]==LOCKTYPE_MINING
)
659 skill
= ((Player
*)m_caster
)->GetSkillValue(SKILL_MINING
);
660 loottype
= LOOT_SKINNING
;
663 if((skill
!= 999) && (skill
< lockInfo
->requiredskill
))
665 SendCastResult(CAST_FAIL_FAILED
);
669 if( skill
>= (lockInfo
->requiredskill
+75) )
671 else if( skill
>= (lockInfo
->requiredskill
+50) )
673 else if( skill
>= (lockInfo
->requiredskill
+25) )
675 else if( skill
>= lockInfo
->requiredskill
)
677 else up_skillvalue
= 0;
679 if(loottype
== LOOT_CORPSE
&& gameObjTarget
->HaveLootSkill())
681 gameObjTarget
->SetLootSkill(false);
682 ((Player
*)m_caster
)->UpdateSkillPro(m_spellInfo
->Id
);
685 ((Player
*)m_caster
)->SendLoot(gameObjTarget
->GetGUID(),loottype
);
688 void Spell::EffectSummonChangeItem(uint32 i
)
690 if(m_caster
->GetTypeId() != TYPEID_PLAYER
)
693 Player
*player
= (Player
*)m_caster
;
695 uint32 newitemid
= m_spellInfo
->EffectItemType
[i
];
700 uint8 msg
= player
->CanStoreNewItem( NULL_BAG
, NULL_SLOT
, dest
, newitemid
, 1, false);
702 if( msg
== EQUIP_ERR_OK
)
704 player
->StoreNewItem( dest
, newitemid
, 1, true);
707 player
->SendEquipError( msg
, NULL
, NULL
);
710 void Spell::EffectOpenSecretSafe(uint32 i
)
712 EffectOpenLock(i
); //no difference for now
715 void Spell::EffectProficiency(uint32 i
)
717 if (!unitTarget
|| unitTarget
->GetTypeId() != TYPEID_PLAYER
)
719 Player
*p_target
= (Player
*)unitTarget
;
721 uint32 newflag
= m_spellInfo
->EquippedItemSubClass
;
722 if(m_spellInfo
->EquippedItemClass
== 2 && !(p_target
->GetWeaponProficiency() & newflag
))
724 p_target
->AddWeaponProficiency(newflag
);
725 p_target
->SendProficiency(uint8(0x02),p_target
->GetWeaponProficiency());
727 if(m_spellInfo
->EquippedItemClass
== 4 && !(p_target
->GetArmorProficiency() & newflag
))
729 p_target
->AddArmorProficiency(newflag
);
730 p_target
->SendProficiency(uint8(0x04),p_target
->GetArmorProficiency());
734 void Spell::EffectApplyAA(uint32 i
)
738 if(!unitTarget
->isAlive())
741 AreaAura
* Aur
= new AreaAura(m_spellInfo
, i
, unitTarget
, m_caster
);
742 unitTarget
->AddAura(Aur
);
745 void Spell::EffectSummon(uint32 i
)
747 if(m_caster
->GetPetGUID())
752 uint32 pet_entry
= m_spellInfo
->EffectMiscValue
[i
];
755 uint32 level
= m_caster
->getLevel();
756 Pet
* spawnCreature
= new Pet();
758 if(!spawnCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
),
759 m_caster
->GetMapId(),
760 m_caster
->GetPositionX(),m_caster
->GetPositionY(),
761 m_caster
->GetPositionZ(),m_caster
->GetOrientation(),
762 m_spellInfo
->EffectMiscValue
[i
]))
764 sLog
.outError("no such creature entry %u",m_spellInfo
->EffectMiscValue
[i
]);
765 delete spawnCreature
;
769 spawnCreature
->SetUInt64Value(UNIT_FIELD_SUMMONEDBY
,m_caster
->GetGUID());
770 spawnCreature
->SetPower( POWER_MANA
,28 + 10 * level
);
771 spawnCreature
->SetMaxPower(POWER_MANA
,28 + 10 * level
);
772 spawnCreature
->SetUInt32Value(UNIT_NPC_FLAGS
, 0);
773 spawnCreature
->setPowerType(POWER_MANA
);
774 spawnCreature
->SetHealth( 28 + 30*level
);
775 spawnCreature
->SetMaxHealth( 28 + 30*level
);
776 spawnCreature
->SetLevel( level
);
777 spawnCreature
->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE
,m_caster
->getFaction());
778 spawnCreature
->SetUInt32Value(UNIT_FIELD_FLAGS
,0);
779 spawnCreature
->SetUInt32Value(UNIT_FIELD_BYTES_1
,0);
780 spawnCreature
->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP
,0);
781 spawnCreature
->SetUInt32Value(UNIT_FIELD_PETEXPERIENCE
,0);
782 spawnCreature
->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP
,1000);
783 spawnCreature
->SetUInt64Value(UNIT_FIELD_CREATEDBY
, m_caster
->GetGUID());
785 spawnCreature->SetStat(STAT_STRENGTH,int(20+level*1.55));
786 spawnCreature->SetStat(STAT_AGILITY,int(20+level*0.64));
787 spawnCreature->SetStat(STAT_STAMINA,int(20+level*1.27));
788 spawnCreature->SetStat(STAT_INTELLECT,int(20+level*0.18));
789 spawnCreature->SetStat(STAT_SPIRIT,int(20+level*0.36));
791 spawnCreature
->SetArmor(level
*50);
792 spawnCreature
->AIM_Initialize();
795 if(m_caster
->GetTypeId() == TYPEID_PLAYER
)
796 name
= ((Player
*)m_caster
)->GetName();
798 name
= ((Creature
*)m_caster
)->GetCreatureInfo()->Name
;
799 name
.append("'s Pet");
800 spawnCreature
->SetName( name
);
802 MapManager::Instance().GetMap(m_caster
->GetMapId())->Add((Creature
*)spawnCreature
);
804 if(m_caster
->GetTypeId() == TYPEID_PLAYER
)
806 m_caster
->SetPet(spawnCreature
);
807 ((Player
*)m_caster
)->PetSpellInitialize();
808 ((Player
*)m_caster
)->SavePet();
812 void Spell::EffectLearnSpell(uint32 i
)
817 if(unitTarget
->GetTypeId() != TYPEID_PLAYER
)
819 if(m_caster
->GetTypeId() == TYPEID_PLAYER
)
821 Creature
*pet
= m_caster
->GetPet();
823 if( !pet
|| !pet
->isPet() || pet
!=unitTarget
)
826 EffectLearnPetSpell(i
);
831 Player
*player
= (Player
*)unitTarget
;
833 uint32 spellToLearn
= m_spellInfo
->EffectTriggerSpell
[i
];
834 //data.Initialize(SMSG_LEARNED_SPELL);
835 //data << spellToLearn;
836 //player->GetSession()->SendPacket(&data);
837 player
->learnSpell((uint16
)spellToLearn
);
838 //some addspell isn't needed if you have a good DB,FISHING && MINING && HERBALISM have to be needed.
841 case 4036: //SKILL_ENGINERING
843 player
->learnSpell(3918);
844 player
->learnSpell(3919);
845 player
->learnSpell(3920);
848 case 3908: //SKILL_TAILORING
850 player
->learnSpell(2387);
851 player
->learnSpell(2963);
854 case 7411: //SKILL_ENCHANTING
856 player
->learnSpell(7418);
857 player
->learnSpell(7421);
858 player
->learnSpell(13262);
861 case 2259: //SKILL_ALCHEMY
863 player
->learnSpell(2329);
864 player
->learnSpell(7183);
865 player
->learnSpell(2330);
868 case 2018: //SKILL_BLACKSMITHING
870 player
->learnSpell(2663);
871 player
->learnSpell(12260);
872 player
->learnSpell(2660);
873 player
->learnSpell(3115);
876 case 2108: //SKILL_LEATHERWORKING
878 player
->learnSpell(2152);
879 player
->learnSpell(9058);
880 player
->learnSpell(9059);
881 player
->learnSpell(2149);
882 player
->learnSpell(7126);
883 player
->learnSpell(2881);
886 case 2550: //SKILL_COOKING
888 player
->learnSpell(818);
889 player
->learnSpell(2540);
890 player
->learnSpell(2538);
893 case 3273: //SKILL_FIRST_AID
895 player
->learnSpell(3275);
898 case 7620: //SKILL_FISHING
900 player
->learnSpell(7738);
903 case 2575: //SKILL_MINING
905 player
->learnSpell(2580);
906 player
->learnSpell(2656);
907 player
->learnSpell(2657);
910 case 2366: //SKILL_HERBALISM
912 player
->learnSpell(2383);
915 case 264: //SKILL_BOWS
917 if(!player
->HasSpell(75))
918 player
->learnSpell(2480);
921 case 266: //SKILL_GUNS
923 if(!player
->HasSpell(75))
924 player
->learnSpell(7918);
927 case 5011: //SKILL_CROSSBOWS
929 if(!player
->HasSpell(75))
930 player
->learnSpell(7919);
933 case 2567: //SKILL_THROWN
935 player
->learnSpell(2764);
940 sLog
.outDebug( "Spell: Player %u have learned spell %u from NpcGUID=%u", player
->GetGUIDLow(), spellToLearn
, m_caster
->GetGUIDLow() );
943 void Spell::EffectDispel(uint32 i
)
945 m_caster
->RemoveFirstAuraByDispel(m_spellInfo
->EffectMiscValue
[i
]);
948 void Spell::EffectDualWield(uint32 i
)
950 if (unitTarget
->GetTypeId() == TYPEID_PLAYER
)
951 ((Player
*)unitTarget
)->SetCanDualWield(true);
954 void Spell::EffectPickPocket(uint32 i
)
956 if( m_caster
->GetTypeId() != TYPEID_PLAYER
)
959 if( !unitTarget
|| unitTarget
->GetTypeId() != TYPEID_UNIT
)
962 if( unitTarget
->getDeathState() == ALIVE
&& //victim is alive
963 //victim have to be humanoid
964 ((Creature
*)unitTarget
)->GetCreatureInfo()->type
== CREATURE_TYPE_HUMANOID
)
966 int chance
= 10 + m_caster
->getLevel() - unitTarget
->getLevel();
968 if ( ( rand() % 20 ) <= chance
)
970 //Stealing successfull
971 //sLog.outDebug("Sending loot from pickpocket");
972 ((Player
*)m_caster
)->SendLoot(unitTarget
->GetGUID(),LOOT_PICKPOKETING
);
976 //Reveal action + get attack
977 m_caster
->RemoveAurasDueToSpell(1784);
978 ((Creature
*)unitTarget
)->AI().AttackStart(m_caster
);
983 void Spell::EffectSummonWild(uint32 i
)
987 uint32 pet_entry
= m_spellInfo
->EffectMiscValue
[i
];
990 uint32 level
= m_caster
->getLevel();
992 // level of pet summoned using engineering item based at engineering skill level
993 if(m_caster
->GetTypeId()==TYPEID_PLAYER
&& m_CastItem
)
995 ItemPrototype
const *proto
= m_CastItem
->GetProto();
996 if(proto
&& proto
->RequiredSkill
== SKILL_ENGINERING
)
998 uint16 skill202
= ((Player
*)m_caster
)->GetSkillValue(SKILL_ENGINERING
);
1006 Pet
* spawnCreature
= new Pet();
1008 if(!spawnCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
),
1009 m_caster
->GetMapId(),
1010 m_caster
->GetPositionX(),m_caster
->GetPositionY(),
1011 m_caster
->GetPositionZ(),m_caster
->GetOrientation(),
1012 m_spellInfo
->EffectMiscValue
[i
]))
1014 sLog
.outError("no such creature entry %u",m_spellInfo
->EffectMiscValue
[i
]);
1015 delete spawnCreature
;
1019 spawnCreature
->SetUInt64Value(UNIT_FIELD_SUMMONEDBY
,m_caster
->GetGUID());
1020 spawnCreature
->setPowerType(POWER_MANA
);
1021 spawnCreature
->SetPower( POWER_MANA
,28 + 10 * level
);
1022 spawnCreature
->SetMaxPower(POWER_MANA
,28 + 10 * level
);
1023 spawnCreature
->SetUInt32Value(UNIT_NPC_FLAGS
, 0);
1024 spawnCreature
->SetHealth( 28 + 30*level
);
1025 spawnCreature
->SetMaxHealth( 28 + 30*level
);
1026 spawnCreature
->SetLevel(level
);
1027 spawnCreature
->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE
,m_caster
->getFaction());
1028 spawnCreature
->SetUInt32Value(UNIT_FIELD_FLAGS
,0);
1029 spawnCreature
->SetUInt32Value(UNIT_FIELD_BYTES_1
,0);
1030 spawnCreature
->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP
,0);
1031 spawnCreature
->SetUInt32Value(UNIT_FIELD_PETEXPERIENCE
,0);
1032 spawnCreature
->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP
,1000);
1033 spawnCreature
->SetUInt64Value(UNIT_FIELD_CREATEDBY
, m_caster
->GetGUID());
1035 spawnCreature
->SetArmor(level
*50);
1036 spawnCreature
->AIM_Initialize();
1038 MapManager::Instance().GetMap(m_caster
->GetMapId())->Add((Creature
*)spawnCreature
);
1040 if(m_caster
->GetTypeId() == TYPEID_PLAYER
)
1042 m_caster
->SetPet(spawnCreature
);
1043 ((Player
*)m_caster
)->PetSpellInitialize();
1044 ((Player
*)m_caster
)->SavePet();
1048 void Spell::EffectTeleUnitsFaceCaster(uint32 i
)
1053 if(unitTarget
->isInFlight())
1056 uint32 mapid
= m_caster
->GetMapId();
1057 float dis
= GetRadius(sSpellRadiusStore
.LookupEntry(m_spellInfo
->EffectRadiusIndex
[i
]));
1058 float fx
= m_caster
->GetPositionX() + dis
* cos(m_caster
->GetOrientation());
1059 float fy
= m_caster
->GetPositionY() + dis
* sin(m_caster
->GetOrientation());
1060 // teleport a bit above terrainlevel to avoid falling below it
1061 float fz
= MapManager::Instance ().GetMap(mapid
)->GetHeight(fx
,fy
) + 1.5;
1063 if(unitTarget
->GetTypeId() == TYPEID_PLAYER
)
1064 ((Player
*)unitTarget
)->TeleportTo(mapid
, fx
, fy
, fz
, -m_caster
->GetOrientation(), false);
1066 MapManager::Instance().GetMap(mapid
)->CreatureRelocation((Creature
*)m_caster
, fx
, fy
, fz
, -m_caster
->GetOrientation());
1069 void Spell::EffectLearnSkill(uint32 i
)
1071 if(unitTarget
->GetTypeId() != TYPEID_PLAYER
)
1074 uint32 skillid
= m_spellInfo
->EffectMiscValue
[i
];
1075 uint16 skillval
= ((Player
*)unitTarget
)->GetPureSkillValue(skillid
);
1076 ((Player
*)unitTarget
)->SetSkill(skillid
,skillval
?skillval
:1,damage
*75);
1079 void Spell::EffectTradeSkill(uint32 i
)
1081 if(unitTarget
->GetTypeId() != TYPEID_PLAYER
)
1083 // uint32 skillid = m_spellInfo->EffectMiscValue[i];
1084 // uint16 skillmax = ((Player*)unitTarget)->(skillid);
1085 // ((Player*)unitTarget)->SetSkill(skillid,skillval?skillval:1,skillmax+75);
1088 void Spell::EffectEnchantItemPerm(uint32 i
)
1090 if(m_caster
->GetTypeId() != TYPEID_PLAYER
)
1095 Player
* p_caster
= (Player
*)m_caster
;
1097 p_caster
->UpdateSkillPro(m_spellInfo
->Id
);
1099 if (m_spellInfo
->EffectMiscValue
[i
])
1101 uint32 enchant_id
= m_spellInfo
->EffectMiscValue
[i
];
1103 SpellItemEnchantmentEntry
*pEnchant
= sSpellItemEnchantmentStore
.LookupEntry(enchant_id
);
1107 // remove old enchanting before appling new if equiped
1108 if(itemTarget
->IsEquipped())
1110 if(uint32 old_enchant_id
= itemTarget
->GetUInt32Value(ITEM_FIELD_ENCHANTMENT
))
1111 p_caster
->AddItemEnchant(itemTarget
,old_enchant_id
,false);
1114 for(int x
=0;x
<3;x
++)
1115 itemTarget
->SetUInt32Value(ITEM_FIELD_ENCHANTMENT
+x
,0);
1117 itemTarget
->SetUInt32Value(ITEM_FIELD_ENCHANTMENT
, enchant_id
);
1119 // add new enchanting if equiped
1120 if(itemTarget
->IsEquipped())
1122 p_caster
->AddItemEnchant(itemTarget
,enchant_id
,true);
1125 //p_caster->GetSession()->SendEnchantmentLog(itemTarget->GetGUID(),p_caster->GetGUID(),itemTarget->GetEntry(),m_spellInfo->Id);
1126 //p_caster->GetSession()->SendItemEnchantTimeUpdate(itemTarget->GetGUID(),pEnchant->display_type,duration);
1130 void Spell::EffectEnchantItemTmp(uint32 i
)
1132 if(m_caster
->GetTypeId() != TYPEID_PLAYER
)
1135 Player
* p_caster
= (Player
*)m_caster
;
1140 if (m_spellInfo
->EffectMiscValue
[i
])
1142 uint32 enchant_id
= m_spellInfo
->EffectMiscValue
[i
];
1143 int32 duration
= GetDuration(m_spellInfo
);
1145 duration
= m_spellInfo
->EffectBasePoints
[i
]+1;
1148 SpellItemEnchantmentEntry
*pEnchant
= sSpellItemEnchantmentStore
.LookupEntry(enchant_id
);
1152 // remove old enchanting before applying new if equipped
1153 if(uint32 old_enchant_id
= itemTarget
->GetUInt32Value(ITEM_FIELD_ENCHANTMENT
+1*3))
1155 if(itemTarget
->IsEquipped())
1156 p_caster
->AddItemEnchant(itemTarget
,old_enchant_id
,false);
1158 // duration == 0 will remove EnchantDuration
1159 p_caster
->AddEnchantDuration(itemTarget
,1,0);
1162 for(int x
=0;x
<3;x
++)
1163 itemTarget
->SetUInt32Value(ITEM_FIELD_ENCHANTMENT
+3+x
,0);
1165 itemTarget
->SetUInt32Value(ITEM_FIELD_ENCHANTMENT
+3, enchant_id
);
1166 itemTarget
->SetUInt32Value(ITEM_FIELD_ENCHANTMENT
+3+1, duration
*1000);
1167 if(m_spellInfo
->SpellFamilyName
== 8)
1168 itemTarget
->SetUInt32Value(ITEM_FIELD_ENCHANTMENT
+3+2, 45+FindSpellRank(m_spellInfo
->Id
)*15);
1170 // add new enchanting if equipped
1171 if(itemTarget
->IsEquipped())
1173 p_caster
->AddItemEnchant(itemTarget
,enchant_id
,true);
1177 p_caster
->AddEnchantDuration(itemTarget
,1,duration
*1000);
1179 //p_caster->GetSession()->SendEnchantmentLog(itemTarget->GetGUID(),p_caster->GetGUID(),itemTarget->GetEntry(),m_spellInfo->Id);
1180 p_caster
->GetSession()->SendItemEnchantTimeUpdate(itemTarget
->GetGUID(),pEnchant
->display_type
,duration
);
1184 void Spell::EffectTameCreature(uint32 i
)
1186 if(m_caster
->GetPetGUID())
1192 if(unitTarget
->GetTypeId() == TYPEID_PLAYER
)
1195 Creature
* creatureTarget
= (Creature
*)unitTarget
;
1197 if(m_caster
->getClass() == CLASS_HUNTER
)
1199 creatureTarget
->AttackStop();
1200 if(m_caster
->getVictim()==creatureTarget
)
1201 m_caster
->AttackStop();
1203 uint32 petlevel
= creatureTarget
->getLevel();
1204 creatureTarget
->SetUInt64Value(UNIT_FIELD_SUMMONEDBY
, m_caster
->GetGUID());
1205 creatureTarget
->SetUInt64Value(UNIT_FIELD_CREATEDBY
, m_caster
->GetGUID());
1206 creatureTarget
->SetMaxPower(POWER_HAPPINESS
,1000000);
1207 creatureTarget
->SetPower( POWER_HAPPINESS
,600000);
1208 creatureTarget
->setPowerType(POWER_FOCUS
);
1209 creatureTarget
->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE
,m_caster
->getFaction());
1210 creatureTarget
->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP
,0);
1211 creatureTarget
->SetUInt32Value(UNIT_FIELD_PETEXPERIENCE
,0);
1212 creatureTarget
->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP
,1000);
1213 creatureTarget
->SetTamed(true);
1214 creatureTarget
->AIM_Initialize();
1216 if(m_caster
->GetTypeId() == TYPEID_PLAYER
)
1218 m_caster
->SetPet(creatureTarget
);
1219 ((Player
*)m_caster
)->PetSpellInitialize();
1220 ((Player
*)m_caster
)->SavePet();
1225 void Spell::EffectSummonPet(uint32 i
)
1228 m_caster
->GetClosePoint(NULL
, px
, py
, pz
);
1230 uint32 petentry
= m_spellInfo
->EffectMiscValue
[i
];
1232 Creature
*OldSummon
= m_caster
->GetPet();
1234 // if pet requested type already exist
1235 if(OldSummon
&& OldSummon
->isPet() && OldSummon
->GetCreatureInfo()->Entry
== petentry
)
1237 if(OldSummon
->isDead() )
1239 uint32 petlvl
= OldSummon
->getLevel();
1240 OldSummon
->RemoveFlag (UNIT_FIELD_FLAGS
, UNIT_FLAG_SKINNABLE
);
1241 OldSummon
->SetHealth( 28 + 10 * petlvl
);
1242 OldSummon
->SetMaxHealth( 28 + 10 * petlvl
);
1243 OldSummon
->SetPower( POWER_MANA
, 28 + 10 * petlvl
);
1244 OldSummon
->SetMaxPower(POWER_MANA
, 28 + 10 * petlvl
);
1245 OldSummon
->setDeathState(ALIVE
);
1246 OldSummon
->clearUnitState(UNIT_STAT_ALL_STATE
);
1247 (*OldSummon
)->Clear();
1249 MapManager::Instance().GetMap(OldSummon
->GetMapId())->Remove(OldSummon
,false);
1250 OldSummon
->SetMapId(m_caster
->GetMapId());
1251 OldSummon
->Relocate(px
, py
, pz
, OldSummon
->GetOrientation());
1252 MapManager::Instance().GetMap(m_caster
->GetMapId())->Add(OldSummon
);
1253 if(m_caster
->GetTypeId() == TYPEID_PLAYER
)
1255 ((Player
*)m_caster
)->PetSpellInitialize();
1256 ((Player
*)m_caster
)->SavePet();
1263 if(m_caster
->GetTypeId() == TYPEID_PLAYER
)
1264 ((Player
*)m_caster
)->UnsummonPet(OldSummon
);
1269 Pet
* NewSummon
= new Pet();
1271 uint32 ownerid
= m_caster
->GetGUIDLow();
1273 if(NewSummon
->LoadPetFromDB(m_caster
,petentry
))
1275 ((Player
*)m_caster
)->SavePet();
1279 if( NewSummon
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), m_caster
->GetMapId(), px
, py
, pz
+1, m_caster
->GetOrientation(), petentry
))
1281 uint32 petlevel
=m_caster
->getLevel();
1282 NewSummon
->SetLevel(petlevel
);
1283 NewSummon
->SetUInt64Value(UNIT_FIELD_SUMMONEDBY
, m_caster
->GetGUID());
1284 NewSummon
->SetUInt64Value(UNIT_FIELD_CREATEDBY
, m_caster
->GetGUID());
1285 NewSummon
->SetUInt32Value(UNIT_NPC_FLAGS
, 0);
1286 NewSummon
->SetHealth( 28 + 10 * petlevel
);
1287 NewSummon
->SetMaxHealth( 28 + 10 * petlevel
);
1288 NewSummon
->SetPower( POWER_MANA
, 28 + 10 * petlevel
);
1289 NewSummon
->SetMaxPower(POWER_MANA
, 28 + 10 * petlevel
);
1290 NewSummon
->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE
,m_caster
->getFaction());
1291 NewSummon
->SetUInt32Value(UNIT_FIELD_BYTES_0
,2048);
1292 NewSummon
->SetUInt32Value(UNIT_FIELD_FLAGS
,0);
1293 NewSummon
->SetUInt32Value(UNIT_FIELD_BYTES_1
,0);
1294 NewSummon
->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP
,5);
1295 NewSummon
->SetUInt32Value(UNIT_FIELD_PETEXPERIENCE
,0);
1296 NewSummon
->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP
,1000);
1297 NewSummon
->SetUInt32Value(UNIT_CREATED_BY_SPELL
, m_spellInfo
->Id
);
1298 NewSummon
->SetStat(STAT_STRENGTH
,22);
1299 NewSummon
->SetStat(STAT_AGILITY
,22);
1300 NewSummon
->SetStat(STAT_STAMINA
,25);
1301 NewSummon
->SetStat(STAT_INTELLECT
,28);
1302 NewSummon
->SetStat(STAT_SPIRIT
,27);
1304 for(uint32 i
=0; i
< CREATURE_MAX_SPELLS
; i
++)
1305 NewSummon
->m_spells
[i
] = 0;
1307 if(petentry
== 416) //imp
1309 NewSummon
->m_spells
[0] = 3110; //3110---fire bolt 1
1310 NewSummon
->AddActState(STATE_RA_SPELL1
);
1313 NewSummon
->SaveToDB();
1314 NewSummon
->AIM_Initialize();
1315 MapManager::Instance().GetMap(NewSummon
->GetMapId())->Add((Creature
*)NewSummon
);
1317 m_caster
->SetPet(NewSummon
);
1318 sLog
.outDebug("New Pet has guid %u", NewSummon
->GetGUIDLow());
1320 if(m_caster
->GetTypeId() == TYPEID_PLAYER
)
1322 ((Player
*)m_caster
)->PetSpellInitialize();
1323 ((Player
*)m_caster
)->SavePet();
1330 void Spell::EffectLearnPetSpell(uint32 i
)
1332 if(m_caster
->GetTypeId() != TYPEID_PLAYER
)
1335 Player
*_player
= (Player
*)m_caster
;
1337 Creature
*pet
= _player
->GetPet();
1343 SpellEntry
*learn_spellproto
= sSpellStore
.LookupEntry(m_spellInfo
->EffectTriggerSpell
[i
]);
1344 if(!learn_spellproto
)
1346 SpellEntry
*has_spellproto
;
1347 for(int8 x
=0;x
<4;x
++)
1349 has_spellproto
= sSpellStore
.LookupEntry(pet
->m_spells
[x
]);
1352 pet
->m_spells
[x
] = learn_spellproto
->Id
;
1355 else if(has_spellproto
->SpellIconID
== learn_spellproto
->SpellIconID
)
1357 pet
->m_spells
[x
] = learn_spellproto
->Id
;
1362 _player
->PetSpellInitialize();
1365 void Spell::EffectAttackMe(uint32 i
)
1367 if(unitTarget
->GetTypeId() != TYPEID_PLAYER
)
1369 unitTarget
->SetInFront(m_caster
);
1370 ((Creature
*)unitTarget
)->AI().AttackStart(m_caster
);
1374 void Spell::EffectWeaponDmg(uint32 i
)
1378 if(!unitTarget
->isAlive())
1381 uint32 wp
[4] = { SPELL_EFFECT_WEAPON_DAMAGE
, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE
, SPELL_EFFECT_NORMALIZED_WEAPON_DMG
, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL
};
1383 // multiple weap dmg effect workaround
1384 // execute only the first weapon damage
1385 // and handle all effects at once
1389 for (j
= 0; j
< 3; j
++)
1391 for (k
= 0; k
< 4; k
++)
1392 if (m_spellInfo
->Effect
[j
] == wp
[k
])
1398 if (m_spellInfo
->Effect
[j
] != SPELL_EFFECT_WEAPON_PERCENT_DAMAGE
)
1399 bonus
+= m_spellInfo
->EffectBasePoints
[j
]+1;
1403 WeaponAttackType attType
= BASE_ATTACK
;
1404 if(m_spellInfo
->rangeIndex
!= 1 && m_spellInfo
->rangeIndex
!= 2 && m_spellInfo
->rangeIndex
!= 7)
1405 attType
= RANGED_ATTACK
;
1408 uint32 nohitMask
= HITINFO_ABSORB
| HITINFO_RESIST
| HITINFO_MISS
;
1409 uint32 damageType
= NORMAL_DAMAGE
;
1410 uint32 victimState
= VICTIMSTATE_NORMAL
;
1412 uint32 blocked_dmg
= 0;
1413 uint32 absorbed_dmg
= 0;
1414 uint32 resisted_dmg
= 0;
1415 uint32 procflag
= 0;
1417 m_caster
->DoAttackDamage(unitTarget
, &damage
, &blocked_dmg
, &damageType
, &hitInfo
, &victimState
, &absorbed_dmg
, &resisted_dmg
, attType
);
1419 if (damage
+ bonus
> 0)
1424 for (j
= 0; j
< 3; j
++)
1425 if (m_spellInfo
->Effect
[j
] == SPELL_EFFECT_WEAPON_PERCENT_DAMAGE
)
1426 damage
= uint32(damage
* (m_spellInfo
->EffectBasePoints
[j
]+1) / 100);
1428 if (hitInfo
& nohitMask
)
1429 m_caster
->SendAttackStateUpdate(hitInfo
& nohitMask
, unitTarget
, 1, m_spellInfo
->School
, damage
, absorbed_dmg
, resisted_dmg
, 1, blocked_dmg
);
1431 m_caster
->SendSpellNonMeleeDamageLog(unitTarget
, m_spellInfo
->Id
, damage
+ absorbed_dmg
+ resisted_dmg
+ blocked_dmg
, m_spellInfo
->School
, absorbed_dmg
, resisted_dmg
, true, blocked_dmg
);
1432 m_caster
->DealDamage(unitTarget
, damage
, 0, true);
1435 if(m_caster
->GetTypeId() == TYPEID_PLAYER
)
1437 if(m_spellInfo
->rangeIndex
!= 1 && m_spellInfo
->rangeIndex
!= 2 && m_spellInfo
->rangeIndex
!= 7)
1439 Item
*pItem
= ((Player
*)m_caster
)->GetItemByPos( INVENTORY_SLOT_BAG_0
, EQUIPMENT_SLOT_RANGED
);
1440 if(!pItem
|| pItem
->IsBroken())
1443 if( pItem
->GetProto()->InventoryType
== INVTYPE_THROWN
)
1446 ((Player
*)m_caster
)->DestroyItemCount( pItem
, count
, true);
1449 ((Player
*)m_caster
)->DestroyItemCount( ((Player
*)m_caster
)->GetUInt32Value(PLAYER_AMMO_ID
) , 1, true);
1453 /*if(m_spellInfo->Effect[i] == 121)
1455 m_caster->resetAttackTimer(BASE_ATTACK);
1456 m_caster->resetAttackTimer(OFF_ATTACK);
1457 m_caster->resetAttackTimer(RANGED_ATTACK);
1461 void Spell::EffectThreat(uint32 i
)
1463 if(!unitTarget
|| !unitTarget
->isAlive() || !m_caster
->isAlive())
1465 unitTarget
->AddHostil(m_caster
->GetGUID(),float(damage
));
1468 void Spell::EffectHealMaxHealth(uint32 i
)
1472 if(!unitTarget
->isAlive())
1475 uint32 heal
= m_caster
->GetMaxHealth();
1477 unitTarget
->ModifyHealth(heal
);
1479 if(unitTarget
->GetTypeId() == TYPEID_PLAYER
)
1480 SendHealSpellOnPlayer((Player
*)unitTarget
, m_spellInfo
->Id
, heal
);
1483 void Spell::EffectInterruptCast(uint32 i
)
1487 if(!unitTarget
->isAlive())
1490 unitTarget
->InterruptSpell();
1493 void Spell::EffectScriptEffect(uint32 i
)
1495 if(!m_spellInfo
->Reagent
[0])
1497 // paladin's holy light / flash of light
1498 if ((m_spellInfo
->SpellFamilyName
== SPELLFAMILY_PALADIN
) &&
1499 (m_spellInfo
->SpellIconID
== 70 || m_spellInfo
->SpellIconID
== 242))
1502 if(m_spellInfo
->SpellFamilyName
== SPELLFAMILY_PALADIN
&& (m_spellInfo
->SpellFamilyFlags
& (1<<23)))
1504 // paladin's judgement
1505 if(!unitTarget
|| !unitTarget
->isAlive())
1507 uint32 spellId2
= 0;
1508 Unit::AuraMap
& m_auras
= m_caster
->GetAuras();
1509 Unit::AuraMap::iterator itr
,next
;
1511 for(itr
= m_auras
.begin(); itr
!= m_auras
.end(); itr
= next
)
1517 SpellEntry
*spellInfo
= itr
->second
->GetSpellProto();
1518 if (!spellInfo
) continue;
1519 if (spellInfo
->SpellVisual
!= 5622 || spellInfo
->SpellFamilyName
!= SPELLFAMILY_PALADIN
) continue;
1520 spellId2
= spellInfo
->EffectBasePoints
[2]+1;
1523 m_caster
->RemoveAurasDueToSpell(spellInfo
->Id
);
1524 next
= m_auras
.begin();
1529 SpellEntry
*spellInfo
= sSpellStore
.LookupEntry(spellId2
);
1532 Spell
*p_spell
= new Spell(m_caster
,spellInfo
,true,0);
1535 SpellCastTargets targets
;
1536 Unit
*ptarget
= unitTarget
;
1537 targets
.setUnitTarget(ptarget
);
1538 p_spell
->prepare(&targets
);
1543 switch(m_spellInfo
->Id
)
1546 m_spellInfo
->EffectItemType
[0] = 5512; //spell 6261; //primary healstone
1549 m_spellInfo
->EffectItemType
[0] = 5511; //spell 6262; //inferior healstone
1552 m_spellInfo
->EffectItemType
[0] = 5509; //spell 5720; //healstone
1555 m_spellInfo
->EffectItemType
[0] = 5510; //spell 5723; //strong healstone
1558 m_spellInfo
->EffectItemType
[0] = 9421; //spell 11732; //super healstone
1563 EffectCreateItem( i
);
1567 void Spell::EffectAddComboPoints(uint32 i
)
1572 if(m_caster
->GetTypeId() != TYPEID_PLAYER
)
1575 uint8 comboPoints
= ((m_caster
->GetUInt32Value(PLAYER_FIELD_BYTES
) & 0xFF00) >> 8);
1576 if(m_caster
->GetUInt64Value(PLAYER_FIELD_COMBO_TARGET
) != unitTarget
->GetGUID())
1578 comboPoints
= damage
;
1579 m_caster
->SetUInt64Value(PLAYER_FIELD_COMBO_TARGET
,unitTarget
->GetGUID());
1580 m_caster
->SetUInt32Value(PLAYER_FIELD_BYTES
,((m_caster
->GetUInt32Value(PLAYER_FIELD_BYTES
) & ~(0xFF << 8)) | (comboPoints
<< 8)));
1582 else if(comboPoints
< 5)
1584 comboPoints
+= damage
;
1587 m_caster
->SetUInt32Value(PLAYER_FIELD_BYTES
,((m_caster
->GetUInt32Value(PLAYER_FIELD_BYTES
) & ~(0xFF << 8)) | (comboPoints
<< 8)));
1592 void Spell::EffectDuel(uint32 i
)
1596 if(!m_caster
|| m_caster
->GetTypeId() != TYPEID_PLAYER
)
1599 if(!unitTarget
|| unitTarget
->GetTypeId() != TYPEID_PLAYER
)
1602 Player
*caster
= (Player
*)m_caster
;
1603 Player
*target
= (Player
*)unitTarget
;
1605 // caster or target already have requested duel
1606 if( caster
->isRequestedOrStartDuel() || target
->isRequestedOrStartDuel() ) return;
1608 //CREATE DUEL FLAG OBJECT
1609 GameObject
* pGameObj
= new GameObject();
1611 uint32 gameobject_id
= m_spellInfo
->EffectMiscValue
[i
];
1613 if(!pGameObj
->Create(objmgr
.GenerateLowGuid(HIGHGUID_GAMEOBJECT
), gameobject_id
,m_caster
->GetMapId(),
1614 m_caster
->GetPositionX()+(unitTarget
->GetPositionX()-m_caster
->GetPositionX())/2 ,
1615 m_caster
->GetPositionY()+(unitTarget
->GetPositionY()-m_caster
->GetPositionY())/2 ,
1616 m_caster
->GetPositionZ(),
1617 m_caster
->GetOrientation(), 0, 0, 0, 0))
1622 pGameObj
->SetFloatValue(OBJECT_FIELD_SCALE_X
,1.0f
);
1624 pGameObj
->SetUInt32Value(GAMEOBJECT_DISPLAYID
, 787 );
1625 pGameObj
->SetUInt32Value(GAMEOBJECT_FACTION
, m_caster
->getFaction() );
1626 pGameObj
->SetUInt32Value(GAMEOBJECT_TYPE_ID
, 16 );
1627 pGameObj
->SetUInt32Value(GAMEOBJECT_LEVEL
, m_caster
->getLevel()+1 );
1628 pGameObj
->SetRespawnTimer(GetDuration(m_spellInfo
));
1629 pGameObj
->SetSpellId(m_spellInfo
->Id
);
1631 m_caster
->AddGameObject(pGameObj
);
1632 MapManager::Instance().GetMap(pGameObj
->GetMapId())->Add(pGameObj
);
1635 //Send request to opositor
1636 data
.Initialize(SMSG_DUEL_REQUESTED
);
1637 data
<< pGameObj
->GetGUID();
1638 data
<< caster
->GetGUID();
1639 target
->GetSession()->SendPacket(&data
);
1640 //Set who are the oponents
1641 caster
->SetDuelVs(target
);
1642 target
->SetDuelVs(caster
);
1643 //Players are not in duel yet...
1644 caster
->SetInDuel(false);
1645 target
->SetInDuel(false);
1646 //Set who is the duel caster
1647 caster
->SetDuelSender(caster
);
1648 target
->SetDuelSender(caster
);
1650 caster
->SetUInt64Value(PLAYER_DUEL_ARBITER
,pGameObj
->GetGUID());
1651 target
->SetUInt64Value(PLAYER_DUEL_ARBITER
,pGameObj
->GetGUID());
1655 void Spell::EffectSummonTotem(uint32 i
)
1658 switch(m_spellInfo
->Effect
[i
])
1660 case SPELL_EFFECT_SUMMON_TOTEM_SLOT1
: slot
= 0; break;
1661 case SPELL_EFFECT_SUMMON_TOTEM_SLOT2
: slot
= 1; break;
1662 case SPELL_EFFECT_SUMMON_TOTEM_SLOT3
: slot
= 2; break;
1663 case SPELL_EFFECT_SUMMON_TOTEM_SLOT4
: slot
= 3; break;
1667 uint64 guid
= m_caster
->m_TotemSlot
[slot
];
1670 Creature
*OldTotem
= ObjectAccessor::Instance().GetCreature(*m_caster
, guid
);
1671 if(OldTotem
&& OldTotem
->isTotem()) ((Totem
*)OldTotem
)->UnSummon();
1672 m_caster
->m_TotemSlot
[slot
] = 0;
1675 Totem
* pTotem
= new Totem();
1677 if(!pTotem
->Create(objmgr
.GenerateLowGuid(HIGHGUID_GAMEOBJECT
),
1678 m_caster
->GetMapId(), m_caster
->GetPositionX(), m_caster
->GetPositionY(),
1679 m_caster
->GetPositionZ(),m_caster
->GetOrientation(),
1680 m_spellInfo
->EffectMiscValue
[i
] ))
1686 m_caster
->m_TotemSlot
[slot
] = pTotem
->GetGUID();
1687 pTotem
->SetOwner(m_caster
->GetGUID());
1688 //pTotem->SetSpell(pTotem->GetCreatureInfo()->spell1);
1689 pTotem
->SetSpell(m_spellInfo
->Id
); //use SummonTotem spellid
1690 pTotem
->SetDuration(GetDuration(m_spellInfo
));
1691 pTotem
->SetHealth(5);
1692 pTotem
->SetMaxHealth(5);
1696 void Spell::EffectEnchantHeldItem(uint32 i
)
1698 if(m_caster
->GetTypeId() != TYPEID_PLAYER
)
1701 Player
* p_caster
= (Player
*)m_caster
;
1707 if(!itemTarget
->IsEquipped())
1710 if (m_spellInfo
->EffectMiscValue
[i
])
1712 uint32 enchant_id
= m_spellInfo
->EffectMiscValue
[i
];
1713 int32 duration
= GetDuration(m_spellInfo
);
1715 duration
= m_spellInfo
->EffectBasePoints
[i
]+1;
1718 SpellItemEnchantmentEntry
*pEnchant
= sSpellItemEnchantmentStore
.LookupEntry(enchant_id
);
1722 // remove old enchanting before appling new
1723 if(uint32 old_enchant_id
= itemTarget
->GetUInt32Value(ITEM_FIELD_ENCHANTMENT
+pEnchant
->display_type
*3))
1724 p_caster
->AddItemEnchant(itemTarget
,enchant_id
,false);
1726 for(int x
=0;x
<3;x
++)
1727 itemTarget
->SetUInt32Value(ITEM_FIELD_ENCHANTMENT
+pEnchant
->display_type
*3+x
,0);
1729 itemTarget
->SetUInt32Value(ITEM_FIELD_ENCHANTMENT
+pEnchant
->display_type
*3, enchant_id
);
1730 itemTarget
->SetUInt32Value(ITEM_FIELD_ENCHANTMENT
+pEnchant
->display_type
*3+1, duration
*1000);
1732 // add new enchanting
1733 p_caster
->AddItemEnchant(itemTarget
,enchant_id
,true);
1735 //p_caster->GetSession()->SendEnchantmentLog(itemTarget->GetGUID(),p_caster->GetGUID(),itemTarget->GetEntry(),m_spellInfo->Id);
1736 p_caster
->GetSession()->SendItemEnchantTimeUpdate(itemTarget
->GetGUID(),pEnchant
->display_type
,duration
);
1740 void Spell::EffectDisEnchant(uint32 i
)
1742 if(m_caster
->GetTypeId() != TYPEID_PLAYER
)
1745 Player
* p_caster
= (Player
*)m_caster
;
1748 uint32 item_level
= itemTarget
->GetProto()->ItemLevel
;
1749 uint32 item_quality
= itemTarget
->GetProto()->Quality
;
1753 if(item_level
>= 51)
1755 if(item_quality
== 4)
1760 else if(item_quality
== 3)
1765 else if(item_quality
== 2)
1767 count
= urand(1,(item_level
/10));
1768 if(urand(1,100)< 85)
1774 else if(item_level
>= 46 && item_level
<= 50)
1776 if(item_quality
== 4)
1781 else if(item_quality
== 3)
1786 else if(item_quality
== 2)
1788 count
= urand(1,(item_level
/10));
1789 if(urand(1,100)< 85)
1795 else if(item_level
>= 41 && item_level
<= 45)
1797 if(item_quality
== 4)
1802 else if(item_quality
== 3)
1807 else if(item_quality
== 2)
1809 count
= urand(1,(item_level
/10));
1810 if(urand(1,100)< 85)
1816 else if(item_level
>= 36 && item_level
<= 40)
1818 if(item_quality
== 4)
1823 else if(item_quality
== 3)
1828 else if(item_quality
== 2)
1830 count
= urand(1,(item_level
/10));
1831 if(urand(1,100)< 85)
1837 else if(item_level
>= 31 && item_level
<= 35)
1839 if(item_quality
== 4)
1844 else if(item_quality
== 3)
1849 else if(item_quality
== 2)
1851 count
= (item_level
/10);
1852 if(urand(1,100)< 85)
1858 else if(item_level
>= 25 && item_level
<= 30)
1860 if(item_quality
== 4)
1865 else if(item_quality
== 3)
1870 else if(item_quality
== 2)
1872 count
= (item_level
/10);
1873 if(urand(1,100)< 85)
1879 else if(item_level
>= 21 && item_level
<= 25)
1881 if(item_quality
== 4)
1886 else if(item_quality
== 3)
1891 else if(item_quality
== 2)
1893 count
= (item_level
/10);
1894 if(urand(1,100)< 85)
1900 else if(item_level
>= 1 && item_level
<= 20)
1902 if(item_quality
== 4)
1907 else if(item_quality
== 3 && item_level
>=16)
1912 else if(item_quality
== 2)
1914 if(urand(1,100)< 70)
1919 else if(item_level
<=15 && urand(1,100)< 70 )
1924 else if(urand(1,100)< 50)
1937 if ( item
== 0 || count
== 0 )
1939 SendCastResult(CAST_FAIL_CANT_BE_DISENCHANTED
);
1940 //SendChannelUpdate(0);
1944 uint32 item_count
= 1;
1945 p_caster
->DestroyItemCount(itemTarget
,item_count
, true);
1946 p_caster
->UpdateSkillPro(m_spellInfo
->Id
);
1949 uint8 msg
= p_caster
->CanStoreNewItem( NULL_BAG
, NULL_SLOT
, dest
, item
, count
, false );
1950 if( msg
== EQUIP_ERR_OK
)
1951 p_caster
->StoreNewItem( dest
, item
, count
, true );
1953 p_caster
->SendEquipError( msg
, NULL
, NULL
);
1957 void Spell::EffectInebriate(uint32 i
)
1959 if(m_caster
->GetTypeId() != TYPEID_PLAYER
)
1962 Player
*player
= (Player
*)m_caster
;
1963 uint16 currentDrunk
= player
->GetDrunkValue();
1964 uint16 drunkMod
= (m_spellInfo
->EffectBasePoints
[i
]+1) * 0xFFFF / 100;
1965 if (currentDrunk
+ drunkMod
> 0xFFFF)
1966 currentDrunk
= 0xFFFF;
1968 currentDrunk
+= drunkMod
;
1969 player
->SetDrunkValue(currentDrunk
);
1972 void Spell::EffectFeedPet(uint32 i
)
1974 if(m_caster
->GetTypeId() != TYPEID_PLAYER
)
1977 Player
*_player
= (Player
*)m_caster
;
1979 Creature
*pet
= _player
->GetPet();
1985 pet
->ModifyPower(POWER_HAPPINESS
,damage
);
1987 SpellEntry
*spellinfo
= sSpellStore
.LookupEntry(m_spellInfo
->EffectTriggerSpell
[i
]);
1988 Spell
_spell(m_caster
, spellinfo
, true, 0);
1989 SpellCastTargets targets
;
1990 targets
.setUnitTarget(m_caster
);
1991 _spell
.prepare(&targets
);
1994 void Spell::EffectDismissPet(uint32 i
)
1996 if(m_caster
->GetTypeId() != TYPEID_PLAYER
)
1999 if(m_caster
->GetPet()->isPet())
2000 ((Player
*)m_caster
)->UnsummonPet();
2001 else if(m_caster
->GetPet()->isTamed())
2002 ((Player
*)m_caster
)->UnTamePet();
2005 void Spell::EffectSummonObject(uint32 i
)
2009 switch(m_spellInfo
->Effect
[i
])
2011 case SPELL_EFFECT_SUMMON_OBJECT_SLOT1
: slot
= 0; break;
2012 case SPELL_EFFECT_SUMMON_OBJECT_SLOT2
: slot
= 1; break;
2013 case SPELL_EFFECT_SUMMON_OBJECT_SLOT3
: slot
= 2; break;
2014 case SPELL_EFFECT_SUMMON_OBJECT_SLOT4
: slot
= 3; break;
2018 uint64 guid
= m_caster
->m_ObjectSlot
[slot
];
2021 GameObject
* obj
= NULL
;
2023 obj
= ObjectAccessor::Instance().GetGameObject(*m_caster
, guid
);
2025 if(obj
) obj
->Delete();
2026 m_caster
->m_ObjectSlot
[slot
] = 0;
2029 GameObject
* pGameObj
= new GameObject();
2030 uint32 display_id
= m_spellInfo
->EffectMiscValue
[i
];
2032 float rot2
= sin(m_caster
->GetOrientation()/2);
2033 float rot3
= cos(m_caster
->GetOrientation()/2);
2035 if(!pGameObj
->Create(objmgr
.GenerateLowGuid(HIGHGUID_GAMEOBJECT
), display_id
,m_caster
->GetMapId(), m_caster
->GetPositionX(), m_caster
->GetPositionY(), m_caster
->GetPositionZ(), m_caster
->GetOrientation(), 0, 0, rot2
, rot3
))
2041 pGameObj
->SetUInt32Value(GAMEOBJECT_LEVEL
,m_caster
->getLevel());
2042 pGameObj
->SetRespawnTimer(GetDuration(m_spellInfo
));
2043 pGameObj
->SetSpellId(m_spellInfo
->Id
);
2044 pGameObj
->SetLootState(GO_CLOSED
);
2045 m_caster
->AddGameObject(pGameObj
);
2047 sLog
.outError("AddObject at Spell.cpp 1100");
2049 MapManager::Instance().GetMap(pGameObj
->GetMapId())->Add(pGameObj
);
2050 data
.Initialize(SMSG_GAMEOBJECT_SPAWN_ANIM
);
2051 data
<< pGameObj
->GetGUID();
2052 m_caster
->SendMessageToSet(&data
,true);
2054 m_caster
->m_ObjectSlot
[slot
] = pGameObj
->GetGUID();
2057 void Spell::EffectResurrect(uint32 i
)
2062 if(unitTarget
->GetTypeId() != TYPEID_PLAYER
)
2065 if(unitTarget
->isAlive())
2067 if(!unitTarget
->IsInWorld())
2070 Player
* pTarget
= ((Player
*)unitTarget
);
2072 uint32 health
= m_spellInfo
->EffectBasePoints
[i
]+1;
2073 uint32 mana
= m_spellInfo
->EffectMiscValue
[i
];
2075 ((Player
*)unitTarget
)->setResurrect(m_caster
->GetGUID(), m_caster
->GetPositionX(), m_caster
->GetPositionY(), m_caster
->GetPositionZ(), health
, mana
);
2076 SendResurrectRequest(pTarget
);
2079 void Spell::EffectParry(uint32 i
)
2081 if (unitTarget
->GetTypeId() == TYPEID_PLAYER
)
2083 ((Player
*)unitTarget
)->SetCanParry(true);
2087 void Spell::EffectMomentMove(uint32 i
)
2089 if(unitTarget
->isInFlight())
2092 if( m_spellInfo
->rangeIndex
== 1) //self range
2094 uint32 mapid
= m_caster
->GetMapId();
2095 float dis
= GetRadius(sSpellRadiusStore
.LookupEntry(m_spellInfo
->EffectRadiusIndex
[i
]));
2096 float fx
= m_caster
->GetPositionX() + dis
* cos(m_caster
->GetOrientation());
2097 float fy
= m_caster
->GetPositionY() + dis
* sin(m_caster
->GetOrientation());
2098 // teleport a bit above terrainlevel to avoid falling below it
2099 float fz
= MapManager::Instance ().GetMap(mapid
)->GetHeight(fx
,fy
) + 1.5;
2101 if(unitTarget
->GetTypeId() == TYPEID_PLAYER
)
2102 ((Player
*)unitTarget
)->TeleportTo(mapid
, fx
, fy
, fz
, m_caster
->GetOrientation(), false);
2104 MapManager::Instance().GetMap(mapid
)->CreatureRelocation((Creature
*)m_caster
, fx
, fy
, fz
, m_caster
->GetOrientation());
2108 void Spell::EffectReputation(uint32 i
)
2110 if(m_caster
->GetTypeId() != TYPEID_PLAYER
)
2113 Player
*_player
= (Player
*)m_caster
;
2115 int32 rep_change
= m_spellInfo
->EffectBasePoints
[i
]+1; // field store reputation change -1
2117 uint32 faction_id
= m_spellInfo
->EffectMiscValue
[i
];
2119 FactionEntry
* factionEntry
= sFactionStore
.LookupEntry(faction_id
);
2124 _player
->ModifyFactionReputation(factionEntry
,rep_change
);
2127 void Spell::EffectQuestComplete(uint32 i
)
2129 if(m_caster
->GetTypeId() != TYPEID_PLAYER
)
2132 Player
*_player
= (Player
*)m_caster
;
2134 uint32 quest_id
= m_spellInfo
->EffectMiscValue
[i
];
2136 if(_player
->CanCompleteQuest( quest_id
) )
2137 _player
->CompleteQuest( quest_id
);
2141 if(_player
->GetQuestRewardStatus( quest_id
))
2144 _player
->PlayerTalkClass
->SendQuestReward( quest_id
, _player
->GetGUID(), true, NULL
, 0 );
2147 void Spell::EffectSelfResurrect(uint32 i
)
2149 if(!unitTarget
) return;
2150 if(unitTarget
->GetTypeId() != TYPEID_PLAYER
) return;
2151 if(unitTarget
->isAlive()) return;
2152 if(!unitTarget
->IsInWorld()) return;
2157 if(m_spellInfo
->SpellVisual
== 99 && m_spellInfo
->SpellIconID
==1)
2159 health
= m_spellInfo
->EffectBasePoints
[i
]+1 > 0 ? m_spellInfo
->EffectBasePoints
[i
]+1 :(-(m_spellInfo
->EffectBasePoints
[i
]+1));
2160 if(unitTarget
->getPowerType() == POWER_MANA
)
2161 mana
= m_spellInfo
->EffectMiscValue
[i
];
2165 health
= uint32(damage
/100*unitTarget
->GetMaxHealth());
2166 if(unitTarget
->getPowerType() == POWER_MANA
)
2167 mana
= uint32(damage
/100*unitTarget
->GetMaxPower(unitTarget
->getPowerType()));
2169 ((Player
*)unitTarget
)->setResurrect(m_caster
->GetGUID(), m_caster
->GetPositionX(), m_caster
->GetPositionY(), m_caster
->GetPositionZ(), health
, mana
);
2170 SendResurrectRequest((Player
*)unitTarget
);
2173 void Spell::EffectSkinning(uint32 i
)
2175 if(unitTarget
->GetTypeId() != TYPEID_UNIT
)
2177 if(!m_caster
|| m_caster
->GetTypeId() != TYPEID_PLAYER
)
2180 int32 skinningValue
= ((Player
*)m_caster
)->GetSkillValue(SKILL_SKINNING
);
2181 int32 targetLevel
= unitTarget
->getLevel();
2183 ((Player
*)m_caster
)->SendLoot(unitTarget
->GetGUID(),LOOT_SKINNING
);
2184 unitTarget
->RemoveFlag(UNIT_FIELD_FLAGS
, UNIT_FLAG_SKINNABLE
);
2186 int32 reqValue
= targetLevel
<20 ? (targetLevel
-10)*10 : targetLevel
*5;
2188 if(skinningValue
>= reqValue
+ 100)
2190 else if(skinningValue
>= reqValue
+ 50)
2192 else if(skinningValue
>= reqValue
+ 25)
2194 else if(skinningValue
>= reqValue
)
2196 else up_skillvalue
= 0;
2198 uint8 minColorLevel
= skinningValue
<25 ? 1 : skinningValue
<50 ? 2 : skinningValue
<100 ? 3 : 4;
2199 if(up_skillvalue
> minColorLevel
)
2200 up_skillvalue
= minColorLevel
;
2202 if( ((Creature
*)unitTarget
)->isElite() && up_skillvalue
> 1 && up_skillvalue
< 4)
2206 void Spell::EffectCharge(uint32 i
)
2208 if(!unitTarget
|| !m_caster
)
2212 unitTarget
->GetClosePoint(m_caster
, x
, y
, z
);
2213 if(unitTarget
->GetTypeId() != TYPEID_PLAYER
)
2214 ((Creature
*)unitTarget
)->StopMoving();
2216 m_caster
->SendMonsterMove(x
, y
, z
, false,true,1);
2217 m_caster
->Attack(unitTarget
);
2220 void Spell::EffectSummonCritter(uint32 i
)
2222 uint32 pet_entry
= m_spellInfo
->EffectMiscValue
[i
];
2225 Pet
* critter
= new Pet();
2227 if(!critter
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
),
2228 m_caster
->GetMapId(),
2229 m_caster
->GetPositionX(),m_caster
->GetPositionY(),
2230 m_caster
->GetPositionZ(),m_caster
->GetOrientation(),
2231 m_spellInfo
->EffectMiscValue
[i
]))
2233 sLog
.outError("no such creature entry %u",m_spellInfo
->EffectMiscValue
[i
]);
2238 critter
->SetUInt64Value(UNIT_FIELD_SUMMONEDBY
,m_caster
->GetGUID());
2239 critter
->SetUInt64Value(UNIT_FIELD_CREATEDBY
,m_caster
->GetGUID());
2240 critter
->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE
,m_caster
->getFaction());
2242 critter
->AIM_Initialize();
2245 if(m_caster
->GetTypeId() == TYPEID_PLAYER
)
2246 name
= ((Player
*)m_caster
)->GetName();
2248 name
= ((Creature
*)m_caster
)->GetCreatureInfo()->Name
;
2249 name
.append("'s Pet");
2250 critter
->SetName( name
);
2251 m_caster
->SetPet(critter
);
2252 MapManager::Instance().GetMap(m_caster
->GetMapId())->Add((Creature
*)critter
);
2253 if(m_caster
->GetTypeId() == TYPEID_PLAYER
)
2255 ((Player
*)m_caster
)->PetSpellInitialize();
2256 ((Player
*)m_caster
)->SavePet();
2260 void Spell::EffectSummonDeadPet(uint32 i
)
2262 if(m_caster
->GetTypeId() != TYPEID_PLAYER
)
2264 Player
*_player
= (Player
*)m_caster
;
2265 Creature
*_pet
= _player
->GetPet();
2270 Pet
*pet
= (Pet
*)_pet
;
2271 pet
->setDeathState( ALIVE
);
2272 pet
->clearUnitState(UNIT_STAT_ALL_STATE
);
2273 pet
->SetHealth( uint32(pet
->GetMaxHealth()*damage
/100));
2275 pet
->AIM_Initialize();
2277 _player
->PetSpellInitialize();
2281 void Spell::EffectTransmitted(uint32 i
)
2286 float min_dis
= GetMinRange(sSpellRangeStore
.LookupEntry(m_spellInfo
->rangeIndex
));
2287 float max_dis
= GetMaxRange(sSpellRangeStore
.LookupEntry(m_spellInfo
->rangeIndex
));
2288 float diff
= max_dis
- min_dis
+ 1;
2289 float dis
= (float)(rand()%(uint32
)diff
+ (uint32
)min_dis
);
2291 fx
= m_caster
->GetPositionX() + dis
* cos(m_caster
->GetOrientation());
2292 fy
= m_caster
->GetPositionY() + dis
* sin(m_caster
->GetOrientation());
2294 float fz
= MapManager::Instance ().GetMap(m_caster
->GetMapId())->GetHeight(fx
,fy
);
2296 if(m_spellInfo
->EffectMiscValue
[i
] == 35591)
2298 Map
* map
= MapManager::Instance().GetMap(m_caster
->GetMapId());
2299 if ( map
->IsUnderWater(fx
,fy
,fz
) )
2301 SendCastResult(CAST_FAIL_CANT_BE_CAST_HERE
);
2303 SendChannelUpdate(0);
2308 GameObject
* pGameObj
= new GameObject();
2309 uint32 name_id
= m_spellInfo
->EffectMiscValue
[i
];
2311 if(!pGameObj
->Create(objmgr
.GenerateLowGuid(HIGHGUID_GAMEOBJECT
), name_id
,m_caster
->GetMapId(),
2312 fx
, fy
, fz
, m_caster
->GetOrientation(), 0, 0, 0, 0))
2318 pGameObj
->SetUInt64Value(OBJECT_FIELD_CREATED_BY
, m_caster
->GetGUID() );
2319 pGameObj
->SetUInt32Value(12, 0x3F63BB3C );
2320 pGameObj
->SetUInt32Value(13, 0xBEE9E017 );
2321 pGameObj
->SetUInt32Value(GAMEOBJECT_LEVEL
, m_caster
->getLevel() );
2322 pGameObj
->SetRespawnTimer(GetDuration(m_spellInfo
));
2323 pGameObj
->SetSpellId(m_spellInfo
->Id
);
2325 DEBUG_LOG("AddObject at SpellEfects.cpp EffectTransmitted\n");
2326 //m_caster->AddGameObject(pGameObj);
2327 //m_ObjToDel.push_back(pGameObj);
2329 MapManager::Instance().GetMap(pGameObj
->GetMapId())->Add(pGameObj
);
2330 pGameObj
->AddToWorld();
2332 data
.Initialize(SMSG_GAMEOBJECT_SPAWN_ANIM
);
2333 data
<< uint64(pGameObj
->GetGUID());
2334 m_caster
->SendMessageToSet(&data
,true);
2336 if(m_spellInfo
->EffectMiscValue
[i
] == 35591)
2338 if( m_caster
->GetTypeId() == TYPEID_PLAYER
&& ((Player
*)m_caster
)->CheckFishingAble() > 0)
2340 //pGameObj->SetUInt32Value(GAMEOBJECT_STATE, 0);
2342 pGameObj
->SetFloatValue(GAMEOBJECT_ROTATION
+ 2, 0.88431775569915771 );
2344 pGameObj
->SetFloatValue(GAMEOBJECT_ROTATION
+ 3, -0.4668855369091033 );
2345 data
.Initialize(SMSG_GAMEOBJECT_CUSTOM_ANIM
);
2346 data
<<uint64(pGameObj
->GetGUID());
2348 ((Player
*)m_caster
)->GetSession()->SendPacket(&data
);
2349 //need fixed produre of fishing.
2350 ((Player
*)m_caster
)->SendLoot(pGameObj
->GetGUID(),LOOT_FISHING
);
2351 SendChannelUpdate(0);
2356 void Spell::EffectSkill(uint32 i
)
2358 if(m_caster
->GetTypeId() != TYPEID_PLAYER
)
2361 // This hack like code, but another way get GO for prevent effect skill applying for partly looted go not found
2362 if(m_spellInfo
->Effect
[0]==33 && !m_targetGOs
[0].empty())
2364 GameObject
* go
= m_targetGOs
[0].front();
2366 if(!go
->HaveLootSkill())
2369 go
->SetLootSkill(false);
2372 Player
*player
= (Player
*)m_caster
;
2374 uint32 skill_id
= m_spellInfo
->EffectMiscValue
[i
];
2376 if(skill_id
== SKILL_FISHING
&& up_skillvalue
!= 4)
2377 up_skillvalue
= player
->CheckFishingAble();
2378 if(skill_id
== SKILL_SKINNING
|| skill_id
== SKILL_FISHING
2379 || skill_id
== SKILL_HERBALISM
|| skill_id
== SKILL_MINING
)
2381 switch(up_skillvalue
)
2387 if(urand(1,100) <= 10)
2393 if(urand(1,100) <= 40)
2399 if(urand(1,100) <= 70)
2407 player
->UpdateSkill(skill_id
);
2409 player
->UpdateSkillPro(m_spellInfo
->Id
);