Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
SpellEffectsCombat.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "AccountMgr.h"
7#include "AreaTrigger.h"
8#include "Battleground.h"
9#include "BattlegroundMgr.h"
10#include "BattlePetMgr.h"
11#include "CellImpl.h"
12#include "Common.h"
13#include "Creature.h"
14#include "CreatureAI.h"
15#include "DatabaseEnv.h"
16#include "DynamicObject.h"
17#include "Formulas.h"
18#include "GameObject.h"
19#include "GameObjectAI.h"
20#include "GossipDef.h"
21#include "GridNotifiers.h"
22#include "GridNotifiersImpl.h"
23#include "Group.h"
24#include "Guild.h"
25#include "GuildMgr.h"
26#include "InstanceScript.h"
27#include "Language.h"
28#include "Log.h"
29#include "MapManager.h"
30#include "ObjectAccessor.h"
31#include "ObjectMgr.h"
32#include "Opcodes.h"
33#include "OutdoorPvPMgr.h"
34#include "PathGenerator.h"
35#include "Pet.h"
36#include "Player.h"
37#include "ReputationMgr.h"
38#include "ScriptMgr.h"
39#include "SharedDefines.h"
40#include "SkillDiscovery.h"
41#include "SkillExtraItems.h"
42#include "SocialMgr.h"
43#include "Spell.h"
44#include "SpellAuraEffects.h"
45#include "SpellAuras.h"
46#include "SpellCombatMetadata.h"
47#include "SpellMgr.h"
48#include "SpellValidation.h"
49#include "TemporarySummon.h"
50#include "Totem.h"
51#include "Unit.h"
52#include "UpdateData.h"
53#include "UpdateMask.h"
54#include "Util.h"
55#include "Vehicle.h"
56#include "VMapFactory.h"
57#include "World.h"
58#include "WorldPacket.h"
59
61{
63 return;
64
65 if (!unitTarget || !unitTarget->IsAlive())
66 return;
67
68 if (unitTarget->GetTypeId() == TypeID::TYPEID_PLAYER)
69 if (unitTarget->ToPlayer()->GetCommandStatus(CHEAT_GOD))
70 return;
71
72 if (m_caster == unitTarget) // prevent interrupt message
73 finish();
74
75 ObjectGuid targetguid = unitTarget->GetGUID();
76 ObjectGuid casterguid = m_caster->GetGUID();
77
78 WorldPacket data(SMSG_SPELLINSTAKILLLOG, 8 + 8 + 4);
79
80 data.WriteBit(casterguid[6]);
81 data.WriteBit(targetguid[0]);
82 data.WriteBit(casterguid[7]);
83 data.WriteBit(targetguid[2]);
84 data.WriteBit(casterguid[3]);
85 data.WriteBit(casterguid[1]);
86 data.WriteBit(casterguid[2]);
87 data.WriteBit(casterguid[0]);
88 data.WriteBit(casterguid[4]);
89 data.WriteBit(targetguid[4]);
90 data.WriteBit(targetguid[7]);
91 data.WriteBit(targetguid[1]);
92 data.WriteBit(targetguid[6]);
93 data.WriteBit(targetguid[5]);
94 data.WriteBit(casterguid[5]);
95 data.WriteBit(targetguid[3]);
96
97 data.WriteByteSeq(casterguid[0]);
98 data.WriteByteSeq(targetguid[1]);
99 data.WriteByteSeq(casterguid[3]);
100 data.WriteByteSeq(casterguid[4]);
101 data.WriteByteSeq(casterguid[5]);
102 data.WriteByteSeq(casterguid[7]);
103 data.WriteByteSeq(targetguid[0]);
104 data.WriteByteSeq(casterguid[6]);
105 data.WriteByteSeq(targetguid[2]);
106 data.WriteByteSeq(targetguid[4]);
107 data.WriteByteSeq(casterguid[1]);
108 data << int32(m_spellInfo->Id);
109 data.WriteByteSeq(targetguid[3]);
110 data.WriteByteSeq(casterguid[2]);
111 data.WriteByteSeq(targetguid[7]);
112 data.WriteByteSeq(targetguid[6]);
113 data.WriteByteSeq(targetguid[5]);
114
115 m_caster->SendMessageToSet(&data, true);
116
117 m_caster->DealDamage(unitTarget, unitTarget->GetHealth(), NULL, NODAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
118}
119
121{
123 return;
124
125 if (!unitTarget || !unitTarget->IsAlive())
126 return;
127
128 uint32 absorb = 0;
129 uint32 resist = 0;
130
131 m_caster->CalcAbsorbResist(unitTarget, m_spellInfo->GetSchoolMask(), SPELL_DIRECT_DAMAGE, damage, &absorb, &resist, m_spellInfo);
132
133 m_caster->SendSpellNonMeleeDamageLog(unitTarget, m_spellInfo->Id, damage, m_spellInfo->GetSchoolMask(), absorb, resist, false, 0, false);
134 if (unitTarget->GetTypeId() == TypeID::TYPEID_PLAYER)
135 unitTarget->ToPlayer()->EnvironmentalDamage(DAMAGE_FIRE, damage);
136}
137
139{
141 return;
142
143 if (unitTarget && unitTarget->IsAlive())
144 {
145 bool apply_direct_bonus = true;
146 switch (m_spellInfo->SpellFamilyName)
147 {
149 {
150 // Meteor like spells (divided damage to targets)
151 if (m_spellInfo->AttributesCu & SPELL_ATTR0_CU_SHARE_DAMAGE)
152 {
153 uint32 count = 0;
154 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
155 if (ihit->effectMask & (1 << effIndex))
156 ++count;
157
158 damage /= count; // divide to all targets
159 }
160
162 {
165 ((InstanceMap*)m_caster->GetMap())->GetDifficulty());
166 break;
168 {
169 damage = unitTarget->GetHealth() / 2;
172 break;
173 }
175 {
177 return;
178 break;
179 }
181 {
183 break;
184 }
185 default:
186 break;
187 }
188 break;
189 }
191 {
192 // Victory Rush
194 ApplyPct(damage, m_caster->GetTotalAttackPowerValue(WeaponAttackType::BASE_ATTACK));
195 // Shockwave
197 {
198 int32 pct = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, 2);
199 if (pct > 0)
200 damage += int32(CalculatePct(m_caster->GetTotalAttackPowerValue(WeaponAttackType::BASE_ATTACK), pct));
201 break;
202 }
203 break;
204 }
206 {
207 // Ferocious Bite
208 if (m_caster->GetTypeId() == TypeID::TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags[0] & 0x000800000) && m_spellInfo->SpellVisual[0] == 6587)
209 {
210 // converts each extra point of energy ( up to 25 energy ) into additional damage
211 int32 energy = -(m_caster->ModifyPower(POWER_ENERGY, -25));
212 // 25 energy = 100% more damage
213 AddPct(damage, energy * 4);
214 }
215 break;
216 }
218 {
219 // Envenom
220 if (m_spellInfo->SpellFamilyFlags[1] & 0x00000008)
221 {
222 if (Player* player = m_caster->ToPlayer())
223 {
224 // consume from stack dozes not more that have combo-points
225 if (uint32 combo = player->GetComboPoints())
226 {
227 // Eviscerate and Envenom Bonus Damage (item set effect)
228 if (m_caster->HasAura(37169))
229 damage += combo * 40;
230 }
231 }
232 }
233 // Eviscerate
234 else if (m_spellInfo->SpellFamilyFlags[0] & 0x00020000)
235 {
236 if (Player* player = m_caster->ToPlayer())
237 {
238 if (uint32 combo = player->GetComboPoints())
239 {
240 float ap = m_caster->GetTotalAttackPowerValue(WeaponAttackType::BASE_ATTACK);
241 damage += std::rand() % int32(ap * combo * 0.07f) + int32(ap * combo * 0.03f);
242
243 // Eviscerate and Envenom Bonus Damage (item set effect)
244 if (m_caster->HasAura(37169))
245 damage += combo * 40;
246 }
247 }
248 }
249 break;
250 }
252 {
253 // Blood Boil - bonus for diseased targets
254 if (m_spellInfo->SpellFamilyFlags[0] & 0x00040000)
255 {
256 if (unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DEATHKNIGHT, 0, 0, 0x00000002, m_caster->GetGUID()))
257 {
258 damage += m_damage / 2;
259 damage += int32(m_caster->GetTotalAttackPowerValue(WeaponAttackType::BASE_ATTACK) * 0.035f);
260 }
261 }
262 break;
263 }
264 }
265
266 if (m_originalCaster && damage > 0 && apply_direct_bonus)
267 {
270 }
271
272 m_damage += damage;
273 }
274}
275
277{
279 return;
280
281 if (effIndex < EFFECT_0 || effIndex > EFFECT_31)
282 return;
283
284 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
285 return;
286
287 Powers powerType = Powers(m_spellInfo->Effects[effIndex].MiscValue);
288
289 if (!unitTarget || !unitTarget->IsAlive() || unitTarget->getPowerType() != powerType || damage < 0)
290 return;
291
292 // add spell damage bonus
295
296 int32 newDamage = -(unitTarget->ModifyPower(powerType, -damage));
297
298 float gainMultiplier = 0.0f;
299
300 // Don't restore from self drain
301 if (m_caster != unitTarget)
302 {
303 gainMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
304
305 int32 gain = int32(newDamage * gainMultiplier);
306
307 m_caster->EnergizeBySpell(m_caster, m_spellInfo->Id, gain, powerType);
308 }
309 ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, powerType, newDamage, gainMultiplier);
310}
311
313{
315 return;
316
317 if (effIndex < EFFECT_0 || effIndex > EFFECT_31)
318 return;
319
320 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
321 return;
322
323 Powers powerType = Powers(m_spellInfo->Effects[effIndex].MiscValue);
324
325 if (!unitTarget || !unitTarget->IsAlive() || unitTarget->getPowerType() != powerType || damage < 0)
326 return;
327
328 // burn x% of target's mana, up to maximum of 2x% of caster's mana (Mana Burn)
330 {
331 int32 maxDamage = int32(CalculatePct(m_caster->GetMaxPower(powerType), damage * 2));
332 damage = int32(CalculatePct(unitTarget->GetMaxPower(powerType), damage));
333 damage = std::min(damage, maxDamage);
334 }
335
336 int32 newDamage = -(unitTarget->ModifyPower(powerType, -damage));
337
338 // NO - Not a typo - EffectPowerBurn uses effect value multiplier - not effect damage multiplier
339 float dmgMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
340
341 // add log data before multiplication (need power amount, not damage)
342 ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, powerType, newDamage, 0.0f);
343
344 newDamage = int32(newDamage * dmgMultiplier);
345
346 m_damage += newDamage;
347}
348
350{
352 return;
353
354 if (unitTarget && unitTarget->IsAlive() && damage >= 0)
355 {
356 // Try to get original caster
358
359 // Skip if m_originalCaster not available
360 if (!caster)
361 return;
362
363 int32 addhealth = damage;
364
365 // Vessel of the Naaru (Vial of the Sunwell trinket)
367 {
368 // Amount of heal - depends from stacked Holy Energy
369 int damageAmount = 0;
371 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(stackAuraSpellId, 0))
372 {
373 damageAmount += aurEff->GetAmount();
374 m_caster->RemoveAurasDueToSpell(stackAuraSpellId);
375 }
376
377 addhealth += damageAmount;
378 }
379 // Runic Healing Injector (heal increased by 25% for engineers - 3.2.0 patch change)
381 {
382 if (Player* player = m_caster->ToPlayer())
383 if (player->HasSkill(SKILL_ENGINEERING))
385 }
386 // Swiftmend - consumes Regrowth or Rejuvenation
387 else if (m_spellInfo->TargetAuraState == AURA_STATE_SWIFTMEND && unitTarget->HasAuraState(AURA_STATE_SWIFTMEND, m_spellInfo, m_caster))
388 {
389 Unit::AuraEffectList const& RejorRegr = unitTarget->GetAuraEffectsByType(SPELL_AURA_PERIODIC_HEAL);
390 // find most short by duration
391 AuraEffect* targetAura = NULL;
392 for (Unit::AuraEffectList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i)
393 {
394 if ((*i)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_DRUID
395 && (*i)->GetSpellInfo()->SpellFamilyFlags[0] & 0x50)
396 {
397 if (!targetAura || (*i)->GetBase()->GetDuration() < targetAura->GetBase()->GetDuration())
398 targetAura = *i;
399 }
400 }
401
402 if (!targetAura)
403 {
404 SF_LOG_ERROR("spells", "Target(GUID:" UI64FMTD ") has aurastate AURA_STATE_SWIFTMEND but no matching aura.", unitTarget->GetGUID());
405 return;
406 }
407
408 int32 tickheal = targetAura->GetAmount();
409 if (Unit* auraCaster = targetAura->GetCaster())
410 tickheal = auraCaster->SpellHealingBonusDone(unitTarget, targetAura->GetSpellInfo(), tickheal, DOT);
411 //int32 tickheal = targetAura->GetSpellInfo()->EffectBasePoints[idx] + 1;
412 //It is said that talent bonus should not be included
413
414 int32 tickcount = 0;
415 // Rejuvenation
416 if (targetAura->GetSpellInfo()->SpellFamilyFlags[0] & 0x10)
417 tickcount = 4;
418 // Regrowth
419 else // if (targetAura->GetSpellInfo()->SpellFamilyFlags[0] & 0x40)
420 tickcount = 6;
421
422 addhealth += tickheal * tickcount;
423
424 // Glyph of Swiftmend
425 if (!caster->HasAura(54824))
426 unitTarget->RemoveAura(targetAura->GetId(), targetAura->GetCasterGUID());
427
428 //addhealth += tickheal * tickcount;
429 //addhealth = caster->SpellHealingBonus(m_spellInfo, addhealth, HEAL, unitTarget);
430 }
431 // Death Pact - return pct of max health to caster
432 else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && m_spellInfo->SpellFamilyFlags[0] & 0x00080000)
434 else
435 addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL);
436
437 addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL);
438
439 // Remove Grievious bite if fully healed
440 if (unitTarget->HasAura(48920) && (unitTarget->GetHealth() + addhealth >= unitTarget->GetMaxHealth()))
441 unitTarget->RemoveAura(48920);
442
443 m_damage -= addhealth;
444 }
445}
446
448{
450 return;
451
452 if (!unitTarget || !unitTarget->IsAlive() || damage < 0)
453 return;
454
455 // Skip if m_originalCaster not available
456 if (!m_originalCaster)
457 return;
458
459 uint32 heal = m_originalCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, unitTarget->CountPctFromMaxHealth(damage), HEAL);
460 heal = unitTarget->SpellHealingBonusTaken(m_originalCaster, m_spellInfo, heal, HEAL);
461
462 m_healing += heal;
463}
464
466{
468 return;
469
470 if (!unitTarget || !unitTarget->IsAlive() || damage < 0)
471 return;
472
473 // Skip if m_originalCaster not available
474 if (!m_originalCaster)
475 return;
476
477 uint32 heal = m_originalCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, uint32(damage), HEAL);
478
479 m_healing += unitTarget->SpellHealingBonusTaken(m_originalCaster, m_spellInfo, heal, HEAL);
480}
481
483{
485 return;
486
487 if (!unitTarget || !unitTarget->IsAlive() || damage < 0)
488 return;
489
492
493 SF_LOG_DEBUG("spells", "HealthLeech :%i", damage);
494
495 float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
496
497 m_damage += damage;
498 // get max possible damage, don't count overkill for heal
499 uint32 healthGain = uint32(-unitTarget->GetHealthGain(-damage) * healMultiplier);
500
501 if (m_caster->IsAlive())
502 {
503 healthGain = m_caster->SpellHealingBonusDone(m_caster, m_spellInfo, healthGain, HEAL);
504 healthGain = m_caster->SpellHealingBonusTaken(m_caster, m_spellInfo, healthGain, HEAL);
505
506 m_caster->HealBySpell(m_caster, m_spellInfo, uint32(healthGain));
507 }
508}
509
510void Spell::DoCreateItem(uint32 /*i*/, uint32 itemtype)
511{
512 if (!unitTarget || unitTarget->GetTypeId() != TypeID::TYPEID_PLAYER)
513 return;
514
515 Player* player = unitTarget->ToPlayer();
516
517 uint32 newitemid = itemtype;
518 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(newitemid);
519 if (!pProto)
520 {
521 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL);
522 return;
523 }
524
525 // bg reward have some special in code work
527 switch (m_spellInfo->Id)
528 {
532 break;
536 break;
540 break;
541 default:
542 break;
543 }
544
545 uint32 num_to_add = damage;
546
547 if (num_to_add < 1)
548 num_to_add = 1;
549 if (num_to_add > pProto->GetMaxStackSize())
550 num_to_add = pProto->GetMaxStackSize();
551
552 // init items_count to 1, since 1 item will be created regardless of specialization
553 int items_count = 1;
554 // the chance to create additional items
555 float additionalCreateChance = 0.0f;
556 // the maximum number of created additional items
557 uint8 additionalMaxNum = 0;
558 // get the chance and maximum number for creating extra items
559 if (CanCreateExtraItems(player, m_spellInfo->Id, additionalCreateChance, additionalMaxNum))
560 {
561 // roll with this chance till we roll not to create or we create the max num
562 while (roll_chance_f(additionalCreateChance) && items_count <= additionalMaxNum)
563 ++items_count;
564 }
565
566 // really will be created more items
567 num_to_add *= items_count;
568
569 // can the player store the new item?
570 ItemPosCountVec dest;
571 uint32 no_space = 0;
572 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, newitemid, num_to_add, &no_space);
573 if (msg != EQUIP_ERR_OK)
574 {
575 // convert to possible store amount
576 if (msg == EQUIP_ERR_INV_FULL || msg == EQUIP_ERR_ITEM_MAX_COUNT)
577 num_to_add -= no_space;
578 else
579 {
580 // if not created by another reason from full inventory or unique items amount limitation
581 player->SendEquipError(msg, NULL, NULL, newitemid);
582 return;
583 }
584 }
585
586 if (num_to_add)
587 {
588 // create the new item and store it
589 Item* pItem = player->StoreNewItem(dest, newitemid, true, Item::GenerateItemRandomPropertyId(newitemid));
590
591 // was it successful? return error if not
592 if (!pItem)
593 {
594 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL);
595 return;
596 }
597
598 // set the "Crafted by ..." property of the item
599 if (pItem->GetTemplate()->Class != ITEM_CLASS_CONSUMABLE && pItem->GetTemplate()->Class != ITEM_CLASS_QUEST && newitemid != 6265 && newitemid != 6948)
601
602 // send info to the client
603 player->SendNewItem(pItem, num_to_add, true, bgType == BattlegroundTypeId::BATTLEGROUND_TYPE_NONE);
604
606 if (Guild* guild = player->GetGuild())
607 guild->AddGuildNews(GUILD_NEWS_ITEM_CRAFTED, player->GetGUID(), 0, pProto->ItemId);
608
609
610 // we succeeded in creating at least one item, so a levelup is possible
612 player->UpdateCraftSkill(m_spellInfo->Id);
613 }
614
615 /*
616 // for battleground marks send by mail if not add all expected
617 if (no_space > 0 && bgType)
618 {
619 if (Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(BattlegroundTypeId(bgType)))
620 bg->SendRewardMarkByMail(player, newitemid, no_space);
621 }
622 */
623}
624
626{
628 return;
629
630 if (!unitTarget)
631 return;
632 if (!unitTarget->IsAlive())
633 return;
634
635 if (effIndex < EFFECT_0 || effIndex > EFFECT_31)
636 return;
637
638 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
639 return;
640
641 Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue);
642
643 // Some level depends spells
644 int level_multiplier = 0;
645 int level_diff = 0;
646 if (Skyfire::Spells::EnergizeLevelScalingRule const* scalingRule =
648 {
649 level_diff = int32(m_caster->getLevel()) - scalingRule->BaseLevel;
650 level_multiplier = scalingRule->LevelMultiplier;
651 }
653 damage = int32(CalculatePct(unitTarget->GetCreateMana(), damage));
655 {
656 if (Player* player = m_caster->ToPlayer())
657 if (player->HasSkill(SKILL_ENGINEERING))
659 }
660
661 if (level_diff > 0)
662 damage -= level_multiplier * level_diff;
663
664 if (damage < 0 && power != POWER_ECLIPSE)
665 return;
666
667 if (unitTarget->GetMaxPower(power) == 0)
668 return;
669
671 {
673
674 if (Player* player = m_caster->ToPlayer())
675 if (AuraEffect* aurEff = player->GetAuraEffect(
678 }
679
680 m_caster->EnergizeBySpell(unitTarget, m_spellInfo->Id, damage, power);
681
682 // Mad Alchemist's Potion
684 {
685 // find elixirs on target
686 bool guardianFound = false;
687 bool battleFound = false;
688 Unit::AuraApplicationMap& Auras = unitTarget->GetAppliedAuras();
689 for (Unit::AuraApplicationMap::iterator itr = Auras.begin(); itr != Auras.end(); ++itr)
690 {
691 uint32 spell_id = itr->second->GetBase()->GetId();
692 if (!guardianFound)
693 if (sSpellMgr->IsSpellMemberOfSpellGroup(spell_id, SPELL_GROUP_ELIXIR_GUARDIAN))
694 guardianFound = true;
695 if (!battleFound)
696 if (sSpellMgr->IsSpellMemberOfSpellGroup(spell_id, SPELL_GROUP_ELIXIR_BATTLE))
697 battleFound = true;
698 if (battleFound && guardianFound)
699 break;
700 }
701
702 // get all available elixirs by mask and spell level
703 std::set<uint32> avalibleElixirs;
704 if (!guardianFound)
705 sSpellMgr->GetSetOfSpellsInSpellGroup(SPELL_GROUP_ELIXIR_GUARDIAN, avalibleElixirs);
706 if (!battleFound)
707 sSpellMgr->GetSetOfSpellsInSpellGroup(SPELL_GROUP_ELIXIR_BATTLE, avalibleElixirs);
708 for (std::set<uint32>::iterator itr = avalibleElixirs.begin(); itr != avalibleElixirs.end();)
709 {
710 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(*itr);
711 if (spellInfo->SpellLevel < m_spellInfo->SpellLevel || spellInfo->SpellLevel > unitTarget->getLevel())
712 avalibleElixirs.erase(itr++);
713 else if (sSpellMgr->IsSpellMemberOfSpellGroup(*itr, SPELL_GROUP_ELIXIR_SHATTRATH))
714 avalibleElixirs.erase(itr++);
715 else if (sSpellMgr->IsSpellMemberOfSpellGroup(*itr, SPELL_GROUP_ELIXIR_UNSTABLE))
716 avalibleElixirs.erase(itr++);
717 else
718 ++itr;
719 }
720
721 if (!avalibleElixirs.empty())
722 {
723 // cast random elixir on target
725 }
726 }
727}
728
730{
732 return;
733
734 if (!unitTarget)
735 return;
736 if (!unitTarget->IsAlive())
737 return;
738
739 if (effIndex < EFFECT_0 || effIndex > EFFECT_31)
740 return;
741
742 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
743 return;
744
745 Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue);
746
747 uint32 maxPower = unitTarget->GetMaxPower(power);
748 if (maxPower == 0)
749 return;
750
751 uint32 gain = CalculatePct(maxPower, damage);
752 m_caster->EnergizeBySpell(unitTarget, m_spellInfo->Id, gain, power);
753}
754
755void Spell::SendLoot(uint64 guid, LootType loottype)
756{
757 Player* player = m_caster->ToPlayer();
758 if (!player)
759 return;
760
761 if (gameObjTarget)
762 {
763 // Players shouldn't be able to loot gameobjects that are currently despawned
764 if (!gameObjTarget->isSpawned() && !player->IsGameMaster())
765 {
766 SF_LOG_ERROR("spells", "Possible hacking attempt: Player %s [guid: %u] tried to loot a gameobject [entry: %u id: %u] which is on respawn time without being in GM mode!",
767 player->GetName().c_str(), player->GetGUIDLow(), gameObjTarget->GetEntry(), gameObjTarget->GetGUIDLow());
768 return;
769 }
770 // special case, already has GossipHello inside so return and avoid calling twice
771 if (gameObjTarget->GetGoType() == GAMEOBJECT_TYPE_GOOBER)
772 {
774 return;
775 }
776
777 if (sScriptMgr->OnGossipHello(player, gameObjTarget))
778 return;
779
780 if (gameObjTarget->AI()->GossipHello(player))
781 return;
782
783 switch (gameObjTarget->GetGoType())
784 {
787 {
788 gameObjTarget->UseDoorOrButton(0, false, player);
789 return;
790 }
792 {
793 player->PrepareGossipMenu(gameObjTarget, gameObjTarget->GetGOInfo()->questgiver.gossipID, true);
795 return;
796 }
798 {
799 // triggering linked GO
800 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->spellFocus.linkedTrapId)
801 gameObjTarget->TriggeringLinkedGameObject(trapEntry, m_caster);
802 return;
803 }
805 {
807 if (gameObjTarget->GetGOInfo()->chest.eventId)
808 {
809 SF_LOG_DEBUG("spells", "Chest ScriptStart id %u for GO %u", gameObjTarget->GetGOInfo()->chest.eventId, gameObjTarget->GetDBTableGUIDLow());
810 player->GetMap()->ScriptsStart(sEventScripts, gameObjTarget->GetGOInfo()->chest.eventId, player, gameObjTarget);
811 }
812
813 // triggering linked GO
814 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->chest.linkedTrapId)
815 gameObjTarget->TriggeringLinkedGameObject(trapEntry, m_caster);
816
817 // Don't return, let loots been taken
818 break;
819 }
820 default:
821 break;
822 }
823 }
824
825 // Send loot
826 player->SendLoot(guid, loottype);
827}
828
829typedef std::list< std::pair<uint32, uint64> > DispelList;
831{
833 return;
834
835 if (!unitTarget)
836 return;
837
838 // Create dispel mask by dispel type
839 uint32 dispel_type = m_spellInfo->Effects[effIndex].MiscValue;
840 uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(dispel_type));
841
842 DispelChargesList dispel_list;
843 unitTarget->GetDispellableAuraList(m_caster, dispelMask, dispel_list);
844 if (dispel_list.empty())
845 return;
846
847 // Ok if exist some buffs for dispel try dispel it
848 uint32 failCount = 0;
849 DispelChargesList success_list;
850 WorldPacket dataFail(SMSG_DISPEL_FAILED, 8 + 8 + 4 + 4 + damage * 4);
851 // dispel N = damage buffs (or while exist buffs for dispel)
852 for (int32 count = 0; count < damage && !dispel_list.empty();)
853 {
854 // Random select buff for dispel
855 DispelChargesList::iterator itr = dispel_list.begin();
856 std::advance(itr, std::rand() % dispel_list.size());
857
858 int32 chance = itr->first->CalcDispelChance(unitTarget, !unitTarget->IsFriendlyTo(m_caster));
859 // 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
860 if (!chance)
861 {
862 dispel_list.erase(itr);
863 continue;
864 }
865 else
866 {
867 if (roll_chance_i(chance))
868 {
869 bool alreadyListed = false;
870 for (DispelChargesList::iterator successItr = success_list.begin(); successItr != success_list.end(); ++successItr)
871 {
872 if (successItr->first->GetId() == itr->first->GetId())
873 {
874 ++successItr->second;
875 alreadyListed = true;
876 }
877 }
878 if (!alreadyListed)
879 success_list.push_back(std::make_pair(itr->first, 1));
880 --itr->second;
881 if (itr->second <= 0)
882 dispel_list.erase(itr);
883 }
884 else
885 {
886 if (!failCount)
887 {
888 // Failed to dispell
889 dataFail << uint64(m_caster->GetGUID()); // Caster GUID
890 dataFail << uint64(unitTarget->GetGUID()); // Victim GUID
891 dataFail << uint32(m_spellInfo->Id); // dispel spell id
892 }
893 ++failCount;
894 dataFail << uint32(itr->first->GetId()); // Spell Id
895 }
896 ++count;
897 }
898 }
899
900 if (failCount)
901 m_caster->SendMessageToSet(&dataFail, true);
902
903 if (success_list.empty())
904 return;
905
906 WorldPacket dataSuccess(SMSG_SPELLDISPELLOG, 8 + 8 + 1 + 1 + 4 + success_list.size() * (3 + 1 + 1 + 4));
907 // Send packet header
908 dataSuccess.WriteGuidMask(m_caster->GetObjectGUID(), 2);
909 dataSuccess.WriteGuidMask(unitTarget->GetObjectGUID(), 4);
910 dataSuccess.WriteGuidMask(m_caster->GetObjectGUID(), 6);
911 dataSuccess.WriteGuidMask(unitTarget->GetObjectGUID(), 5);
912 dataSuccess.WriteBit(0); // steal
913 dataSuccess.WriteBit(0); // break
914 dataSuccess.WriteGuidMask(m_caster->GetObjectGUID(), 5, 7, 4, 0, 1);
915
916 dataSuccess.WriteBits(success_list.size(), 22); // count
917
918 dataSuccess.WriteGuidMask(unitTarget->GetObjectGUID(), 0);
919
920 for (DispelChargesList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
921 {
922 // Send dispelled spell info
923 dataSuccess.WriteBit(0); // Needed
924 dataSuccess.WriteBit(0); // Rolled
925 dataSuccess.WriteBit(0); // Harmful
926 }
927
928 dataSuccess.WriteGuidMask(unitTarget->GetObjectGUID(), 3, 2);
929 dataSuccess.WriteGuidMask(m_caster->GetObjectGUID(), 3);
930 dataSuccess.WriteGuidMask(unitTarget->GetObjectGUID(), 1, 7, 6);
931
932 dataSuccess.FlushBits();
933
934 for (DispelChargesList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
935 {
936 // Send dispelled spell info
937 //if (Needed) dataSuccess << Needed;
938 dataSuccess << uint32(itr->first->GetId()); // Spell Id
939 //if (Rolled) dataSuccess << Rolled;
940 unitTarget->RemoveAurasDueToSpellByDispel(itr->first->GetId(), m_spellInfo->Id, itr->first->GetCasterGUID(), m_caster, itr->second);
941 }
942
943 dataSuccess.WriteGuidBytes(unitTarget->GetObjectGUID(), 4);
944 dataSuccess.WriteGuidBytes(m_caster->GetObjectGUID(), 3);
945 dataSuccess.WriteGuidBytes(unitTarget->GetObjectGUID(), 6, 0);
946 dataSuccess.WriteGuidBytes(m_caster->GetObjectGUID(), 5, 1);
947 dataSuccess.WriteGuidBytes(unitTarget->GetObjectGUID(), 3, 2, 1, 5);
948 dataSuccess.WriteGuidBytes(m_caster->GetObjectGUID(), 0);
949 dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
950 dataSuccess.WriteGuidBytes(m_caster->GetObjectGUID(), 7, 6, 2);
951 dataSuccess.WriteGuidBytes(unitTarget->GetObjectGUID(), 7);
952 dataSuccess.WriteGuidBytes(m_caster->GetObjectGUID(), 4);
953 m_caster->SendMessageToSet(&dataSuccess, true);
954
955 // On success dispel
956 // Devour Magic
957 if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->GetCategory() == SPELLCATEGORY_DEVOUR_MAGIC)
958 {
959 int32 heal_amount = m_spellInfo->Effects[EFFECT_1].CalcValue(m_caster);
960 m_caster->CastCustomSpell(m_caster, 19658, &heal_amount, NULL, NULL, true);
961 // Glyph of Felhunter
962 if (Unit* owner = m_caster->GetOwner())
963 if (owner->GetAura(56249))
964 owner->CastCustomSpell(owner, 19658, &heal_amount, NULL, NULL, true);
965 }
966}
967
969{
971 return;
972
973 unitTarget->SetCanDualWield(true);
974 if (unitTarget->GetTypeId() == TypeID::TYPEID_UNIT)
975 unitTarget->ToCreature()->UpdateDamagePhysical(WeaponAttackType::OFF_ATTACK);
976}
977
979{
981 return;
982
983 if (!unitTarget)
984 return;
985
986 // this effect use before aura Taunt apply for prevent taunt already attacking target
987 // for spell as marked "non effective at already attacking target"
988 if (!unitTarget || !unitTarget->CanHaveThreatList()
989 || unitTarget->GetVictim() == m_caster)
990 {
992 return;
993 }
994
995 // Also use this effect to set the taunter's threat to the taunted creature's highest value
996 if (unitTarget->getThreatManager().getCurrentVictim())
997 {
998 float myThreat = unitTarget->getThreatManager().getThreat(m_caster);
999 float itsThreat = unitTarget->getThreatManager().getCurrentVictim()->getThreat();
1000 if (itsThreat > myThreat)
1001 unitTarget->getThreatManager().addThreat(m_caster, itsThreat - myThreat);
1002 }
1003
1004 //Set aggro victim to caster
1005 if (!unitTarget->getThreatManager().getOnlineContainer().empty())
1006 if (HostileReference* forcedVictim = unitTarget->getThreatManager().getOnlineContainer().getReferenceByTarget(m_caster))
1007 unitTarget->getThreatManager().setCurrentVictim(forcedVictim);
1008
1009 if (unitTarget->ToCreature()->IsAIEnabled && !unitTarget->ToCreature()->HasReactState(REACT_PASSIVE))
1010 unitTarget->ToCreature()->AI()->AttackStart(m_caster);
1011}
1012
1014{
1016 return;
1017
1018 if (!unitTarget || !unitTarget->IsAlive())
1019 return;
1020
1021 // multiple weapon dmg effect workaround
1022 // execute only the last weapon damage
1023 // and handle all effects at once
1024 for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
1025 {
1026 switch (m_spellInfo->Effects[j].Effect)
1027 {
1032 return; // we must calculate only at last weapon effect
1033 break;
1034 }
1035 }
1036
1037 // some spell specific modifiers
1038 float totalDamagePercentMod = 1.0f; // applied to final bonus+weapon damage
1039 int32 fixed_bonus = 0;
1040 int32 spell_bonus = 0; // bonus specific for spell
1041
1042 switch (m_spellInfo->SpellFamilyName)
1043 {
1045 {
1046 // Devastate (player ones)
1047 if (m_spellInfo->SpellFamilyFlags[1] & 0x40)
1048 {
1049 // Player can apply only 58567 Sunder Armor effect.
1050 bool needCast = !unitTarget->HasAura(58567, m_caster->GetGUID());
1051 if (needCast)
1052 m_caster->CastSpell(unitTarget, 58567, true);
1053
1054 if (Aura* aur = unitTarget->GetAura(58567, m_caster->GetGUID()))
1055 {
1056 if (int32 num = (needCast ? 0 : 1))
1057 aur->ModStackAmount(num);
1058 fixed_bonus += (aur->GetStackAmount() - 1) * CalculateDamage(2, unitTarget);
1059 }
1060 }
1061 break;
1062 }
1063 case SPELLFAMILY_ROGUE:
1064 {
1065 // Hemorrhage
1066 if (m_spellInfo->SpellFamilyFlags[0] & 0x2000000)
1067 {
1068 // 72% more damage with daggers
1069 if (m_caster->GetTypeId() == TypeID::TYPEID_PLAYER)
1070 if (Item* item = m_caster->ToPlayer()->GetWeaponForAttack(m_attackType, true))
1071 if (item->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER)
1072 totalDamagePercentMod *= 1.45f;
1073 }
1074 break;
1075 }
1076 case SPELLFAMILY_SHAMAN:
1077 {
1078 // Skyshatter Harness item set bonus
1079 // Stormstrike
1080 if (AuraEffect* aurEff = m_caster->IsScriptOverriden(m_spellInfo, 5634))
1081 m_caster->CastSpell(m_caster, 38430, true, NULL, aurEff);
1082 break;
1083 }
1084 case SPELLFAMILY_DRUID:
1085 {
1086 // Mangle (Cat): CP
1087 if (m_spellInfo->SpellFamilyFlags[1] & 0x400)
1088 {
1089 if (m_caster->GetTypeId() == TypeID::TYPEID_PLAYER)
1090 m_caster->ToPlayer()->AddComboPoints(unitTarget, 1, this);
1091 }
1092 // Shred, Maul - Rend and Tear
1093 else if (m_spellInfo->SpellFamilyFlags[0] & 0x00008800 && unitTarget->HasAuraState(AURA_STATE_BLEEDING))
1094 {
1095 if (AuraEffect const* rendAndTear = m_caster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 2859, 0))
1096 AddPct(totalDamagePercentMod, rendAndTear->GetAmount());
1097 }
1098 break;
1099 }
1100 case SPELLFAMILY_HUNTER:
1101 {
1102 // Kill Shot - bonus damage from Ranged Attack Power
1103 if (m_spellInfo->SpellFamilyFlags[1] & 0x800000)
1104 spell_bonus += int32(0.45f * m_caster->GetTotalAttackPowerValue(WeaponAttackType::RANGED_ATTACK));
1105 break;
1106 }
1108 {
1109 // Blood Strike
1110 if (m_spellInfo->SpellFamilyFlags[0] & 0x400000)
1111 {
1112 float bonusPct = m_spellInfo->Effects[EFFECT_2].CalcValue(m_caster) * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) / 2.0f;
1113 // Death Knight T8 Melee 4P Bonus
1114 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(64736, EFFECT_0))
1115 AddPct(bonusPct, aurEff->GetAmount());
1116 AddPct(totalDamagePercentMod, bonusPct);
1117 break;
1118 }
1119 // Death Strike
1120 if (m_spellInfo->SpellFamilyFlags[0] & 0x10)
1121 {
1122 // Glyph of Death Strike
1123 // 2% more damage per 5 runic power, up to a maximum of 40%
1124 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(59336, EFFECT_0))
1125 if (uint32 runic = std::min<uint32>(uint32(m_caster->GetPower(POWER_RUNIC_POWER) / 2.5f), aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue(m_caster)))
1126 AddPct(totalDamagePercentMod, runic);
1127 break;
1128 }
1129 // Obliterate (12.5% more damage per disease)
1130 if (m_spellInfo->SpellFamilyFlags[1] & 0x20000)
1131 {
1132 float bonusPct = m_spellInfo->Effects[EFFECT_2].CalcValue(m_caster) * unitTarget->GetDiseasesByCaster(m_caster->GetGUID(), false) / 2.0f;
1133 // Death Knight T8 Melee 4P Bonus
1134 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(64736, EFFECT_0))
1135 AddPct(bonusPct, aurEff->GetAmount());
1136 AddPct(totalDamagePercentMod, bonusPct);
1137 break;
1138 }
1139 // Blood-Caked Strike - Blood-Caked Blade
1140 if (m_spellInfo->SpellIconID == 1736)
1141 {
1142 AddPct(totalDamagePercentMod, unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) * 50.0f);
1143 break;
1144 }
1145 // Heart Strike
1146 if (m_spellInfo->SpellFamilyFlags[0] & 0x1000000)
1147 {
1148 float bonusPct = m_spellInfo->Effects[EFFECT_2].CalcValue(m_caster) * unitTarget->GetDiseasesByCaster(m_caster->GetGUID());
1149 // Death Knight T8 Melee 4P Bonus
1150 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(64736, EFFECT_0))
1151 AddPct(bonusPct, aurEff->GetAmount());
1152
1153 AddPct(totalDamagePercentMod, bonusPct);
1154 break;
1155 }
1156 break;
1157 }
1158 }
1159
1160 bool normalized = false;
1161 float weaponDamagePercentMod = 1.0f;
1162 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
1163 {
1164 switch (m_spellInfo->Effects[j].Effect)
1165 {
1168 fixed_bonus += CalculateDamage(j, unitTarget);
1169 break;
1171 fixed_bonus += CalculateDamage(j, unitTarget);
1172 normalized = true;
1173 break;
1175 ApplyPct(weaponDamagePercentMod, CalculateDamage(j, unitTarget));
1176 break;
1177 default:
1178 break; // not weapon damage effect, just skip
1179 }
1180 }
1181
1182 // apply to non-weapon bonus weapon total pct effect, weapon total flat effect included in weapon damage
1183 if (fixed_bonus || spell_bonus)
1184 {
1185 UnitMods unitMod;
1186 switch (m_attackType)
1187 {
1188 default:
1192 }
1193
1194 float weapon_total_pct = 1.0f;
1195 if (m_spellInfo->SchoolMask & SPELL_SCHOOL_MASK_NORMAL)
1196 weapon_total_pct = m_caster->GetModifierValue(unitMod, TOTAL_PCT);
1197
1198 if (fixed_bonus)
1199 fixed_bonus = int32(fixed_bonus * weapon_total_pct);
1200 if (spell_bonus)
1201 spell_bonus = int32(spell_bonus * weapon_total_pct);
1202 }
1203
1204 int32 weaponDamage = m_caster->CalculateDamage(m_attackType, normalized, true);
1205
1206 // Sequence is important
1207 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
1208 {
1209 // We assume that a spell have at most one fixed_bonus
1210 // and at most one weaponDamagePercentMod
1211 switch (m_spellInfo->Effects[j].Effect)
1212 {
1216 {
1217 weaponDamage += fixed_bonus;
1218 break;
1219 }
1221 {
1222 weaponDamage = int32(weaponDamage * weaponDamagePercentMod);
1223 break;
1224 }
1225 default:
1226 break; // not weapon damage effect, just skip
1227 }
1228 }
1229
1230 if (spell_bonus)
1231 weaponDamage += spell_bonus;
1232
1233 if (totalDamagePercentMod != 1.0f)
1234 weaponDamage = int32(weaponDamage * totalDamagePercentMod);
1235
1236 // prevent negative damage
1237 uint32 eff_damage(std::max(weaponDamage, 0));
1238
1239 // Add melee damage bonuses (also check for negative)
1240 uint32 damage = m_caster->MeleeDamageBonusDone(unitTarget, eff_damage, m_attackType, m_spellInfo);
1241
1242 m_damage += unitTarget->MeleeDamageBonusTaken(m_caster, damage, m_attackType, m_spellInfo);
1243}
1244
1246{
1248 return;
1249
1250 if (!unitTarget || !unitTarget->IsAlive() || !m_caster->IsAlive())
1251 return;
1252
1253 if (!unitTarget->CanHaveThreatList())
1254 return;
1255
1256 unitTarget->AddThreat(m_caster, float(damage));
1257}
1258
1260{
1262 return;
1263
1264 if (!unitTarget || !unitTarget->IsAlive())
1265 return;
1266
1267 int32 addhealth = 0;
1268
1269 // damage == 0 - heal for caster max health
1270 if (damage == 0)
1271 addhealth = m_caster->GetMaxHealth();
1272 else
1273 addhealth = unitTarget->GetMaxHealth() - unitTarget->GetHealth();
1274
1275 m_healing += addhealth;
1276}
1277
1279{
1281 return;
1282
1283 if (!unitTarget || !unitTarget->IsAlive())
1284 return;
1285
1287 // also exist case: apply cooldown to interrupted cast only and to all spells
1288 // there is no CURRENT_AUTOREPEAT_SPELL spells that can be interrupted
1290 {
1291 if (Spell* spell = unitTarget->GetCurrentSpell(CurrentSpellTypes(i)))
1292 {
1293 SpellInfo const* curSpellInfo = spell->m_spellInfo;
1294 // check if we can interrupt spell
1295 if ((spell->getState() == SPELL_STATE_CASTING
1296 || (spell->getState() == SPELL_STATE_PREPARING && spell->GetCastTime() > 0.0f))
1300 {
1301 if (m_originalCaster)
1302 {
1303 int32 duration = m_spellInfo->GetDuration();
1304 unitTarget->ProhibitSpellSchool(curSpellInfo->GetSchoolMask(), unitTarget->ModSpellDuration(m_spellInfo, unitTarget, duration, false, 1 << effIndex));
1305 }
1306 ExecuteLogEffectInterruptCast(effIndex, unitTarget, curSpellInfo->Id);
1307 unitTarget->InterruptSpell(CurrentSpellTypes(i), false);
1308 }
1309 }
1310 }
1311}
1312
1314{
1316 return;
1317
1318 if (!unitTarget)
1319 return;
1320
1321 unitTarget->getHostileRefManager().UpdateVisibility();
1322
1323 Unit::AttackerSet const& attackers = unitTarget->getAttackers();
1324 for (Unit::AttackerSet::const_iterator itr = attackers.begin(); itr != attackers.end();)
1325 {
1326 if (!(*itr)->CanSeeOrDetect(unitTarget))
1327 (*(itr++))->AttackStop();
1328 else
1329 ++itr;
1330 }
1331
1332 unitTarget->m_lastSanctuaryTime = getMSTime();
1333
1334 // Vanish allows to remove all threat and cast regular stealth so other spells can be used
1335 if (m_caster->GetTypeId() == TypeID::TYPEID_PLAYER
1336 && m_spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE
1337 && (m_spellInfo->SpellFamilyFlags[0] & SPELLFAMILYFLAG0_ROGUE_VANISH))
1338 {
1339 m_caster->ToPlayer()->RemoveAurasByType(SPELL_AURA_MOD_ROOT);
1340 // Overkill
1341 if (m_caster->ToPlayer()->HasSpell(58426))
1342 m_caster->CastSpell(m_caster, 58427, true);
1343 }
1344}
1345
1347{
1349 return;
1350
1351 if (!unitTarget)
1352 return;
1353
1354 if (!m_caster->m_movedPlayer)
1355 return;
1356
1357 if (damage <= 0)
1358 return;
1359
1360 m_caster->m_movedPlayer->AddComboPoints(unitTarget, damage, this);
1361}
1362
1364{
1366 return;
1367
1368 if (!unitTarget || !unitTarget->IsAlive() || !unitTarget->GetVictim())
1369 return;
1370
1371 if (unitTarget->m_extraAttacks)
1372 return;
1373
1374 unitTarget->m_extraAttacks = damage;
1375
1376 ExecuteLogEffectExtraAttacks(effIndex, unitTarget->GetVictim(), damage);
1377}
1378
1380{
1382 return;
1383
1384 if (m_caster->GetTypeId() == TypeID::TYPEID_PLAYER)
1385 m_caster->ToPlayer()->SetCanDodge(true);
1386}
1387
1389{
1391 return;
1392
1393 if (m_caster->GetTypeId() == TypeID::TYPEID_PLAYER)
1394 m_caster->ToPlayer()->SetCanParry(true);
1395}
1396
1398{
1400 return;
1401
1402 if (m_caster->GetTypeId() == TypeID::TYPEID_PLAYER)
1403 m_caster->ToPlayer()->SetCanBlock(true);
1404}
1405
1407{
1409 return;
1410
1411 if (!unitTarget)
1412 return;
1413
1414 uint32 mechanic = m_spellInfo->Effects[effIndex].MiscValue;
1415
1416 std::queue < std::pair < uint32, uint64 > > dispel_list;
1417
1418 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
1419 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
1420 {
1421 Aura* aura = itr->second;
1422 if (!aura->GetApplicationOfTarget(unitTarget->GetGUID()))
1423 continue;
1424 if (roll_chance_i(aura->CalcDispelChance(unitTarget, !unitTarget->IsFriendlyTo(m_caster))))
1426 dispel_list.push(std::make_pair(aura->GetId(), aura->GetCasterGUID()));
1427 }
1428
1429 for (; dispel_list.size(); dispel_list.pop())
1430 {
1431 unitTarget->RemoveAura(dispel_list.front().first, dispel_list.front().second, 0, AURA_REMOVE_BY_ENEMY_SPELL);
1432 }
1433}
1434
1436{
1438 return;
1439
1440 if (!unitTarget)
1441 return;
1442
1443 unitTarget->getThreatManager().modifyThreatPercent(m_caster, damage);
1444}
1445
1447{
1449 return;
1450
1451 SF_LOG_DEBUG("spells", "Effect: StealBeneficialBuff");
1452
1453 if (!unitTarget || unitTarget == m_caster) // can't steal from self
1454 return;
1455
1456 DispelChargesList steal_list;
1457
1458 // Create dispel mask by dispel type
1459 uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[effIndex].MiscValue));
1460 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
1461 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
1462 {
1463 Aura* aura = itr->second;
1464 AuraApplication* aurApp = aura->GetApplicationOfTarget(unitTarget->GetGUID());
1465 if (!aurApp)
1466 continue;
1467
1468 if ((aura->GetSpellInfo()->GetDispelMask()) & dispelMask)
1469 {
1470 // Need check for passive? this
1471 if (!aurApp->IsPositive() || aura->IsPassive() || aura->GetSpellInfo()->AttributesEx4 & SPELL_ATTR4_NOT_STEALABLE)
1472 continue;
1473
1474 // The charges / stack amounts don't count towards the total number of auras that can be dispelled.
1475 // Ie: A dispel on a target with 5 stacks of Winters Chill and a Polymorph has 1 / (1 + 1) -> 50% chance to dispell
1476 // Polymorph instead of 1 / (5 + 1) -> 16%.
1477 bool dispel_charges = aura->GetSpellInfo()->AttributesEx7 & SPELL_ATTR7_DISPEL_CHARGES;
1478 uint8 charges = dispel_charges ? aura->GetCharges() : aura->GetStackAmount();
1479 if (charges > 0)
1480 steal_list.push_back(std::make_pair(aura, charges));
1481 }
1482 }
1483
1484 if (steal_list.empty())
1485 return;
1486
1487 // Ok if exist some buffs for dispel try dispel it
1488 uint32 failCount = 0;
1489 DispelList success_list;
1490 WorldPacket dataFail(SMSG_DISPEL_FAILED, 8 + 8 + 4 + 4 + damage * 4);
1491 // dispel N = damage buffs (or while exist buffs for dispel)
1492 for (int32 count = 0; count < damage && !steal_list.empty();)
1493 {
1494 // Random select buff for dispel
1495 DispelChargesList::iterator itr = steal_list.begin();
1496 std::advance(itr, std::rand() % steal_list.size());
1497
1498 int32 chance = itr->first->CalcDispelChance(unitTarget, !unitTarget->IsFriendlyTo(m_caster));
1499 // 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
1500 if (!chance)
1501 {
1502 steal_list.erase(itr);
1503 continue;
1504 }
1505 else
1506 {
1507 if (roll_chance_i(chance))
1508 {
1509 success_list.push_back(std::make_pair(itr->first->GetId(), itr->first->GetCasterGUID()));
1510 --itr->second;
1511 if (itr->second <= 0)
1512 steal_list.erase(itr);
1513 }
1514 else
1515 {
1516 if (!failCount)
1517 {
1518 // Failed to dispell
1519 dataFail << uint64(m_caster->GetGUID()); // Caster GUID
1520 dataFail << uint64(unitTarget->GetGUID()); // Victim GUID
1521 dataFail << uint32(m_spellInfo->Id); // dispel spell id
1522 }
1523 ++failCount;
1524 dataFail << uint32(itr->first->GetId()); // Spell Id
1525 }
1526 ++count;
1527 }
1528 }
1529
1530 if (failCount)
1531 m_caster->SendMessageToSet(&dataFail, true);
1532
1533 if (success_list.empty())
1534 return;
1535
1536 WorldPacket dataSuccess(SMSG_SPELLSTEALLOG, 8 + 8 + 4 + 1 + 4 + damage * 5);
1537 dataSuccess.append(unitTarget->GetPackGUID()); // Victim GUID
1538 dataSuccess.append(m_caster->GetPackGUID()); // Caster GUID
1539 dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
1540 dataSuccess << uint8(0); // not used
1541 dataSuccess << uint32(success_list.size()); // count
1542 for (DispelList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
1543 {
1544 dataSuccess << uint32(itr->first); // Spell Id
1545 dataSuccess << uint8(0); // 0 - steals !=0 transfers
1546 unitTarget->RemoveAurasDueToSpellBySteal(itr->first, itr->second, m_caster);
1547 }
1548 m_caster->SendMessageToSet(&dataSuccess, true);
1549}
1550
1552{
1554 return;
1555
1556 if (m_caster->GetTypeId() != TypeID::TYPEID_PLAYER)
1557 return;
1558
1559 Player* player = m_caster->ToPlayer();
1560
1561 if (player->getClass() != CLASS_DEATH_KNIGHT)
1562 return;
1563
1564 // needed later
1565 m_runesState = m_caster->ToPlayer()->GetRunesState();
1566
1567 uint32 count = damage;
1568 if (count == 0) count = 1;
1569 for (uint32 j = 0; j < MAX_RUNES && count > 0; ++j)
1570 {
1571 if (player->GetRuneCooldown(j) && player->GetCurrentRune(j) == RuneType(m_spellInfo->Effects[effIndex].MiscValue))
1572 {
1574 if (player->GetBaseRune(j) != RuneType(m_spellInfo->Effects[effIndex].MiscValueB))
1575 continue;
1576 player->SetRuneCooldown(j, 0);
1577 --count;
1578 }
1579 }
1580
1581 // Blood Tap
1583 {
1584 for (uint32 l = 0; l + 1 < MAX_RUNES && count > 0; ++l)
1585 {
1586 // Check if both runes are on cd as that is the only time when this needs to come into effect
1587 if ((player->GetRuneCooldown(l) && player->GetCurrentRune(l) == RuneType(m_spellInfo->Effects[effIndex].MiscValueB)) && (player->GetRuneCooldown(l + 1) && player->GetCurrentRune(l + 1) == RuneType(m_spellInfo->Effects[effIndex].MiscValueB)))
1588 {
1589 // Should always update the rune with the lowest cd
1590 if (l + 1 < MAX_RUNES && player->GetRuneCooldown(l) >= player->GetRuneCooldown(l + 1))
1591 l++;
1592 player->SetRuneCooldown(l, 0);
1593 --count;
1594 // is needed to push through to the client that the rune is active
1595 player->ResyncRunes(MAX_RUNES);
1596 }
1597 else
1598 break;
1599 }
1600 }
1601
1602 // Empower rune weapon
1604 {
1605 // Need to do this just once
1606 if (effIndex != 0)
1607 return;
1608
1609 for (uint32 i = 0; i < MAX_RUNES; ++i)
1610 {
1611 if (player->GetRuneCooldown(i) && (player->GetCurrentRune(i) == RuneType::RUNE_FROST || player->GetCurrentRune(i) == RuneType::RUNE_DEATH))
1612 player->SetRuneCooldown(i, 0);
1613 }
1614 }
1615}
1616
1618{
1620 return;
1621
1622 if (m_caster->GetTypeId() == TypeID::TYPEID_PLAYER)
1623 m_caster->ToPlayer()->SetCanTitanGrip(true);
1624}
1625
1627{
1629 return;
1630
1631 if (unitTarget)
1632 m_caster->SetRedirectThreat(unitTarget->GetGUID(), uint32(damage));
1633}
1634
1636{
1638 return;
1639
1640 if (!unitTarget)
1641 return;
1642 // there may be need of specifying casterguid of removed auras
1643 unitTarget->RemoveAurasDueToSpell(m_spellInfo->Effects[effIndex].TriggerSpell);
1644}
1645
1647{
1649 return;
1650
1651 if (!unitTarget)
1652 return;
1653
1654 m_damage += unitTarget->CountPctFromMaxHealth(damage);
1655}
@ SPELL_WS_MARK_WINNER
@ SPELL_AV_MARK_LOSER
@ SPELL_WS_MARK_LOSER
@ SPELL_AB_MARK_LOSER
@ SPELL_AB_MARK_WINNER
@ SPELL_AV_MARK_WINNER
#define MAX_SPELL_EFFECTS
std::int32_t int32
Definition Define.h:73
#define UI64FMTD
Definition Define.h:64
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
std::int8_t int8
Definition Define.h:75
std::uint64_t uint64
Definition Define.h:76
uint32 const MinNewsItemLevel[MAX_CONTENT]
Definition Guild.h:258
@ GUILD_NEWS_ITEM_CRAFTED
Definition Guild.h:244
InventoryResult
Definition Item.h:27
@ EQUIP_ERR_ITEM_NOT_FOUND
Definition Item.h:51
@ EQUIP_ERR_OK
Definition Item.h:28
@ EQUIP_ERR_INV_FULL
Definition Item.h:78
@ EQUIP_ERR_ITEM_MAX_COUNT
Definition Item.h:45
@ ITEM_SUBCLASS_WEAPON_DAGGER
@ ITEM_CLASS_QUEST
@ ITEM_CLASS_CONSUMABLE
#define SF_LOG_DEBUG(filterType__,...)
Definition Log.h:134
#define SF_LOG_ERROR(filterType__,...)
Definition Log.h:143
LootType
Definition LootMgr.h:66
@ TYPEID_PLAYER
Definition Object.h:55
@ TYPEID_UNIT
Definition Object.h:54
ScriptMapMap sEventScripts
Definition ObjectMgr.cpp:51
#define sObjectMgr
Definition ObjectMgr.h:1617
std::vector< ItemPosCount > ItemPosCountVec
Definition Player.h:777
@ DAMAGE_FIRE
Definition Player.h:844
RuneType
Definition Player.h:485
@ RUNE_FROST
Definition Player.h:488
@ RUNE_DEATH
Definition Player.h:489
#define MAX_RUNES
Definition Player.h:476
@ CHEAT_GOD
Definition Player.h:988
#define sScriptMgr
Definition ScriptMgr.h:764
@ GAMEOBJECT_TYPE_BUTTON
@ GAMEOBJECT_TYPE_SPELL_FOCUS
@ GAMEOBJECT_TYPE_CHEST
@ GAMEOBJECT_TYPE_QUESTGIVER
@ GAMEOBJECT_TYPE_GOOBER
@ GAMEOBJECT_TYPE_DOOR
SpellEffIndex
@ EFFECT_1
@ EFFECT_0
@ EFFECT_31
@ EFFECT_2
Powers
@ MAX_POWERS
@ POWER_ECLIPSE
@ POWER_RUNIC_POWER
@ POWER_ENERGY
@ SPELL_EFFECT_WEAPON_DAMAGE
@ SPELL_EFFECT_NORMALIZED_WEAPON_DMG
@ SPELL_EFFECT_WEAPON_PERCENT_DAMAGE
@ SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL
@ SPELL_PREVENTION_TYPE_SILENCE
@ SPELL_PREVENTION_TYPE_UNK
@ SPELL_ATTR7_DISPEL_CHARGES
@ ITEM_QUALITY_EPIC
@ SPELL_ATTR4_NOT_STEALABLE
@ CLASS_DEATH_KNIGHT
@ SPELLFAMILY_WARLOCK
@ SPELLFAMILY_GENERIC
@ SPELLFAMILY_WARRIOR
@ SPELLFAMILY_HUNTER
@ SPELLFAMILY_ROGUE
@ SPELLFAMILY_SHAMAN
@ SPELLFAMILY_DRUID
@ SPELLFAMILY_DEATHKNIGHT
BattlegroundTypeId
@ AURA_STATE_BLEEDING
@ AURA_STATE_SWIFTMEND
DispelType
@ SKILL_ENGINEERING
@ SPELL_SCHOOL_MASK_NORMAL
bool CanCreateExtraItems(Player *player, uint32 spellId, float &additionalChance, uint8 &additionalMax)
@ SPELL_EFFECT_HANDLE_LAUNCH_TARGET
Definition Spell.h:275
@ SPELL_EFFECT_HANDLE_LAUNCH
Definition Spell.h:274
@ SPELL_EFFECT_HANDLE_HIT
Definition Spell.h:276
@ SPELL_EFFECT_HANDLE_HIT_TARGET
Definition Spell.h:277
@ SPELL_STATE_PREPARING
Definition Spell.h:265
@ SPELL_STATE_CASTING
Definition Spell.h:266
@ SPELL_AURA_PERIODIC_DAMAGE
@ SPELL_AURA_PERIODIC_HEAL
@ SPELL_AURA_MOD_ROOT
std::list< std::pair< uint32, uint64 > > DispelList
@ SPELL_ATTR0_CU_SHARE_DAMAGE
Definition SpellInfo.h:68
@ SPELLFAMILYFLAG0_ROGUE_VANISH
Definition SpellMgr.h:45
@ SPELL_GROUP_ELIXIR_SHATTRATH
Definition SpellMgr.h:319
@ SPELL_GROUP_ELIXIR_BATTLE
Definition SpellMgr.h:316
@ SPELL_GROUP_ELIXIR_GUARDIAN
Definition SpellMgr.h:317
@ SPELL_GROUP_ELIXIR_UNSTABLE
Definition SpellMgr.h:318
#define sSpellMgr
Definition SpellMgr.h:744
@ SPELLCATEGORY_DEVOUR_MAGIC
Definition SpellMgr.h:31
uint32 getMSTime()
Definition Timer.h:12
@ CHANNEL_INTERRUPT_FLAG_INTERRUPT
Definition Unit.h:35
UnitMods
Definition Unit.h:439
@ UNIT_MOD_DAMAGE_OFFHAND
Definition Unit.h:473
@ UNIT_MOD_DAMAGE_RANGED
Definition Unit.h:474
@ UNIT_MOD_DAMAGE_MAINHAND
Definition Unit.h:472
#define CURRENT_FIRST_NON_MELEE_SPELL
Definition Unit.h:1114
@ AURA_REMOVE_BY_ENEMY_SPELL
Definition Unit.h:409
@ TOTAL_PCT
Definition Unit.h:387
@ NULL_BAG
Definition Unit.h:336
@ NULL_SLOT
Definition Unit.h:337
CurrentSpellTypes
Definition Unit.h:1107
@ CURRENT_CHANNELED_SPELL
Definition Unit.h:1110
@ CURRENT_GENERIC_SPELL
Definition Unit.h:1109
@ CURRENT_AUTOREPEAT_SPELL
Definition Unit.h:1111
@ SPELL_INTERRUPT_FLAG_INTERRUPT
Definition Unit.h:27
std::list< std::pair< Aura *, uint8 > > DispelChargesList
Definition Unit.h:371
@ REACT_PASSIVE
Definition Unit.h:1156
@ NODAMAGE
Definition Unit.h:618
@ DOT
Definition Unit.h:616
@ SPELL_DIRECT_DAMAGE
Definition Unit.h:615
@ HEAL
Definition Unit.h:617
@ ITEM_FIELD_CREATOR
bool roll_chance_f(float chance)
Definition Util.h:83
bool roll_chance_i(int chance)
Definition Util.h:89
T AddPct(T &base, U pct)
Definition Util.h:109
T ApplyPct(T &base, U pct)
Definition Util.h:115
T CalculatePct(T base, U pct)
Definition Util.h:103
bool IsPositive() const
Definition SpellAuras.h:61
SpellInfo const * GetSpellInfo() const
uint32 GetId() const
Unit * GetCaster() const
Aura * GetBase() const
uint64 GetCasterGUID() const
int32 GetAmount() const
uint64 GetCasterGUID() const
Definition SpellAuras.h:91
const AuraApplication * GetApplicationOfTarget(uint64 guid) const
Definition SpellAuras.h:176
uint32 GetId() const
Definition SpellAuras.h:88
int32 GetDuration() const
Definition SpellAuras.h:119
int32 CalcDispelChance(Unit *auraTarget, bool offensive) const
uint8 GetStackAmount() const
Definition SpellAuras.h:133
uint8 GetCharges() const
Definition SpellAuras.h:126
SpellInfo const * GetSpellInfo() const
Definition SpellAuras.h:87
bool IsPassive() const
void WriteGuidBytes(const ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:264
bool WriteBit(uint32 bit)
Definition ByteBuffer.h:164
void WriteGuidMask(const ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:248
void append(T value)
Definition ByteBuffer.h:147
void WriteBits(T value, size_t bits)
Definition ByteBuffer.h:192
void WriteByteSeq(uint8 b)
Definition ByteBuffer.h:227
void FlushBits()
Definition ByteBuffer.h:154
Definition Guild.h:324
Definition Item.h:202
ItemTemplate const * GetTemplate() const
Definition Item.cpp:528
static int32 GenerateItemRandomPropertyId(uint32 item_id)
Definition Item.cpp:575
void ScriptsStart(std::map< uint32, std::multimap< uint32, ScriptInfo > > const &scripts, uint32 id, Object *source, Object *target)
Put scripts in the execution queue.
uint64 GetGUID() const
Definition Object.h:119
uint32 GetGUIDLow() const
Definition Object.h:120
void SetUInt32Value(uint16 index, uint32 value)
Definition Object.cpp:1038
void SendEquipError(InventoryResult msg, Item *pItem, Item *pItem2=NULL, uint32 itemid=0)
void SetRuneCooldown(uint8 index, uint32 cooldown)
Definition Player.cpp:20536
bool UpdateCraftSkill(uint32 spellid)
Definition Player.cpp:6162
void SendPreparedGossip(WorldObject *source)
Definition Player.cpp:11815
void ResyncRunes(uint8 count)
Definition Player.cpp:20593
Guild * GetGuild()
Definition Player.cpp:22662
uint32 GetRuneCooldown(uint8 index) const
Definition Player.h:3065
RuneType GetCurrentRune(uint8 index) const
Definition Player.h:3061
bool IsGameMaster() const
Definition Player.h:1369
InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 item, uint32 count, uint32 *no_space_count=NULL) const
Item * StoreNewItem(ItemPosCountVec const &pos, uint32 item, bool update, int32 randomPropertyId=0, AllowedLooterSet const &allowedLooters=AllowedLooterSet())
void PrepareGossipMenu(WorldObject *source, uint32 menuId=0, bool showQuests=false)
Definition Player.cpp:11668
void SendNewItem(Item *item, uint32 count, bool received, bool created, bool broadcast=false)
Definition Player.cpp:11604
void SendLoot(uint64 guid, LootType loot_type, bool isAoE=false)
Definition Player.cpp:9346
RuneType GetBaseRune(uint8 index) const
Definition Player.h:3057
void EffectHealPct(SpellEffIndex effIndex)
void EffectPowerBurn(SpellEffIndex effIndex)
GameObject * gameObjTarget
Definition Spell.h:628
void EffectModifyThreatPercent(SpellEffIndex effIndex)
Unit * m_originalCaster
Definition Spell.h:587
void EffectDamageFromMaxHealthPCT(SpellEffIndex effIndex)
static void SendCastResult(Player *caster, SpellInfo const *spellInfo, uint8 cast_count, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE, Opcodes opcode=SMSG_CAST_FAILED)
Definition Spell.cpp:3874
void EffectStealBeneficialBuff(SpellEffIndex effIndex)
int32 damage
Definition Spell.h:630
SpellEffectHandleMode effectHandleMode
Definition Spell.h:631
void EffectDodge(SpellEffIndex effIndex)
void EffectThreat(SpellEffIndex effIndex)
void EffectEnergizePct(SpellEffIndex effIndex)
void EffectTitanGrip(SpellEffIndex effIndex)
Unit *const m_caster
Definition Spell.h:581
Spell(Unit *caster, SpellInfo const *info, TriggerCastFlags triggerFlags, uint64 originalCasterGUID=0, bool skipCheck=false)
Definition Spell.cpp:500
WeaponAttackType m_attackType
Definition Spell.h:593
void EffectRemoveAura(SpellEffIndex effIndex)
uint64 m_originalCasterGUID
Definition Spell.h:585
void EffectBlock(SpellEffIndex effIndex)
void EffectParry(SpellEffIndex effIndex)
int32 m_damage
Definition Spell.h:643
void ExecuteLogEffectTakeTargetPower(uint8 effIndex, Unit *target, uint32 powerType, uint32 powerTaken, float gainMultiplier)
Definition Spell.cpp:4902
int32 CalculateDamage(uint8 i, Unit const *target) const
Definition Spell.h:489
void EffectInterruptCast(SpellEffIndex effIndex)
void EffectHealthLeech(SpellEffIndex effIndex)
void EffectDispel(SpellEffIndex effIndex)
void EffectPowerDrain(SpellEffIndex effIndex)
void EffectSchoolDMG(SpellEffIndex effIndex)
int32 m_healing
Definition Spell.h:644
void EffectHealMechanical(SpellEffIndex effIndex)
void EffectAddExtraAttacks(SpellEffIndex effIndex)
std::list< TargetInfo > m_UniqueTargetInfo
Definition Spell.h:671
Unit * unitTarget
Definition Spell.h:626
void EffectEnergize(SpellEffIndex effIndex)
void ExecuteLogEffectInterruptCast(uint8 effIndex, Unit *victim, uint32 spellId)
Definition Spell.cpp:4914
void EffectWeaponDmg(SpellEffIndex effIndex)
void EffectEnvironmentalDMG(SpellEffIndex effIndex)
void EffectRedirectThreat(SpellEffIndex effIndex)
void EffectInstaKill(SpellEffIndex effIndex)
void EffectDualWield(SpellEffIndex effIndex)
void SendLoot(uint64 guid, LootType loottype)
Item * m_CastItem
Definition Spell.h:531
void EffectHealMaxHealth(SpellEffIndex effIndex)
void EffectSanctuary(SpellEffIndex effIndex)
void DoCreateItem(uint32 i, uint32 itemtype)
void EffectAddComboPoints(SpellEffIndex effIndex)
void EffectHeal(SpellEffIndex effIndex)
void ExecuteLogEffectExtraAttacks(uint8 effIndex, Unit *victim, uint32 attCount)
Definition Spell.cpp:4908
void EffectDispelMechanic(SpellEffIndex effIndex)
void finish(bool ok=true)
Definition Spell.cpp:3762
void EffectActivateRune(SpellEffIndex effIndex)
SpellInfo const *const m_spellInfo
Definition Spell.h:530
uint8 m_runesState
Definition Spell.h:601
void EffectTaunt(SpellEffIndex effIndex)
uint32 ChannelInterruptFlags
Definition SpellInfo.h:200
uint32 SpellLevel
Definition SpellInfo.h:206
uint32 PreventionType
Definition SpellInfo.h:229
uint32 Id
Definition SpellInfo.h:160
uint32 GetDispelMask() const
flag128 SpellFamilyFlags
Definition SpellInfo.h:227
SpellSchoolMask GetSchoolMask() const
uint32 InterruptFlags
Definition SpellInfo.h:198
uint32 AttributesEx7
Definition SpellInfo.h:171
uint32 GetAllEffectsMechanicMask() const
uint32 AttributesEx4
Definition SpellInfo.h:168
Definition Unit.h:1367
std::multimap< uint32, AuraApplication * > AuraApplicationMap
Definition Unit.h:1376
uint32 SpellHealingBonusDone(Unit *victim, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack=1) const
uint8 getClass() const
Definition Unit.h:1543
bool HasAura(uint32 spellId, uint64 casterGUID=0, uint64 itemCasterGUID=0, uint32 reqEffMask=0) const
std::multimap< uint32, Aura * > AuraMap
Definition Unit.h:1372
std::set< Unit * > AttackerSet
Definition Unit.h:1369
uint32 CountPctFromMaxHealth(int32 pct) const
Definition Unit.h:1633
std::list< AuraEffect * > AuraEffectList
Definition Unit.h:1383
Map * GetMap() const
Definition Object.h:740
std::string const & GetName() const
Definition Object.h:664
@ SMSG_DISPEL_FAILED
Definition Opcodes.h:638
@ SMSG_SPELLSTEALLOG
Definition Opcodes.h:976
@ SMSG_SPELLINSTAKILLLOG
Definition Opcodes.h:972
@ SMSG_SPELLDISPELLOG
Definition Opcodes.h:971
#define sWorld
Definition World.h:910
C::value_type const & SelectRandomContainerElement(C const &container)
Definition Containers.h:48
bool IsEmpowerRuneWeaponSpell(uint32 spellId)
bool IsMadAlchemistsPotionSpell(uint32 spellId)
GenericSchoolDamageRule GetGenericSchoolDamageRule(uint32 spellId)
bool IsVesselOfTheNaaruHealSpell(uint32 spellId)
uint32 GetStanceOfTheFierceTigerAuraSpellId()
uint32 GetConsumptionDamage(uint32 difficulty)
bool IsPrimalWisdomEnergizeSpell(uint32 spellId)
int32 GetGargoyleStrikeDamageForLevel(uint32 level)
uint32 GetThundercrashMinimumDamage()
bool IsVictoryRushDamageSpell(uint32 spellId)
uint32 GetEngineeringHealingBonusPct()
bool IsManaBurnSpell(uint32 spellId)
bool IsArcaneChargeAllowedCreatureType(uint32 creatureType)
uint32 GetVesselOfTheNaaruStackAuraSpellId()
bool IsRunicManaInjectorSpell(uint32 spellId)
bool IsBloodTapRuneSpell(uint32 spellId)
bool IsJabEnergizeSpell(uint32 spellId)
bool IsShockwaveDamageSpell(uint32 spellId)
EnergizeLevelScalingRule const * GetEnergizeLevelScalingRule(uint32 spellId)
bool IsRunicHealingInjectorSpell(uint32 spellId)
bool HasMechanic(uint32 mask, uint32 mechanic)
uint32 GetMaxStackSize() const