aboutsummaryrefslogtreecommitdiff
path: root/src/server/game
diff options
context:
space:
mode:
authorTreeston <treeston.mmoc@gmail.com>2017-12-30 20:28:41 +0100
committerGitHub <noreply@github.com>2017-12-30 20:28:41 +0100
commitd507a7e3388382960108b24143da48e5f912b4a7 (patch)
treeb4e3e62094e853cc8551126de438815779411cb7 /src/server/game
parent671a34a966aefa409966f6eb86f88ce671be9b36 (diff)
[3.3.5] CastSpell unclusterfucking (that's a word now) (#21123)
Core/Spell: The giant CastSpell unclusterfucking (that's a word now) of this generation. - CastSpell now always takes three arguments - target, spellId, and a struct containing extra arguments - This struct (CastSpellExtraArgs, see SpellDefines.h) serves as a conglomerate of every previous combination of the 20 billion different CastSpell overloads, all merged into one - It has some great utility constructors - check them out! All of these can be used to implicitly construct the ExtraArgs object. - A gajillion refactors to make everything behave the way it always has
Diffstat (limited to 'src/server/game')
-rw-r--r--src/server/game/AI/CoreAI/PassiveAI.cpp6
-rw-r--r--src/server/game/AI/CoreAI/PetAI.cpp2
-rw-r--r--src/server/game/AI/CoreAI/UnitAI.cpp22
-rw-r--r--src/server/game/AI/CoreAI/UnitAI.h9
-rw-r--r--src/server/game/AI/PlayerAI/PlayerAI.cpp2
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedCreature.cpp2
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp16
-rw-r--r--src/server/game/Entities/Pet/Pet.cpp12
-rw-r--r--src/server/game/Entities/Player/Player.cpp38
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp160
-rw-r--r--src/server/game/Entities/Unit/Unit.h214
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp4
-rw-r--r--src/server/game/Handlers/PetHandler.cpp4
-rw-r--r--src/server/game/Handlers/SpellHandler.cpp9
-rw-r--r--src/server/game/Handlers/TradeHandler.cpp4
-rw-r--r--src/server/game/Spells/Auras/SpellAuraDefines.h36
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp151
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.cpp50
-rw-r--r--src/server/game/Spells/Spell.cpp10
-rw-r--r--src/server/game/Spells/Spell.h2
-rw-r--r--src/server/game/Spells/SpellDefines.h196
-rw-r--r--src/server/game/Spells/SpellEffects.cpp100
-rw-r--r--src/server/game/Spells/SpellMgr.cpp83
23 files changed, 557 insertions, 575 deletions
diff --git a/src/server/game/AI/CoreAI/PassiveAI.cpp b/src/server/game/AI/CoreAI/PassiveAI.cpp
index abbff7a870b..3f979c5dbe3 100644
--- a/src/server/game/AI/CoreAI/PassiveAI.cpp
+++ b/src/server/game/AI/CoreAI/PassiveAI.cpp
@@ -99,7 +99,11 @@ int32 CritterAI::Permissible(Creature const* creature)
void TriggerAI::IsSummonedBy(Unit* summoner)
{
if (me->m_spells[0])
- me->CastSpell(me, me->m_spells[0], false, nullptr, nullptr, summoner->GetGUID());
+ {
+ CastSpellExtraArgs extra;
+ extra.OriginalCaster = summoner->GetGUID();
+ me->CastSpell(me, me->m_spells[0], extra);
+ }
}
int32 TriggerAI::Permissible(Creature const* creature)
diff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp
index 98841effb3b..95c6c0dd026 100644
--- a/src/server/game/AI/CoreAI/PetAI.cpp
+++ b/src/server/game/AI/CoreAI/PetAI.cpp
@@ -243,7 +243,7 @@ void PetAI::UpdateAI(uint32 diff)
SpellCastTargets targets;
targets.SetUnitTarget(target);
- spell->prepare(&targets);
+ spell->prepare(targets);
}
// deleted cached Spell objects
diff --git a/src/server/game/AI/CoreAI/UnitAI.cpp b/src/server/game/AI/CoreAI/UnitAI.cpp
index 244b0b5e047..a4b2e28dfd6 100644
--- a/src/server/game/AI/CoreAI/UnitAI.cpp
+++ b/src/server/game/AI/CoreAI/UnitAI.cpp
@@ -169,28 +169,18 @@ void UnitAI::DoCast(uint32 spellId)
me->CastSpell(target, spellId, false);
}
-void UnitAI::DoCast(Unit* victim, uint32 spellId, bool triggered)
+void UnitAI::DoCast(Unit* victim, uint32 spellId, CastSpellExtraArgs const& args)
{
- if (!victim || (me->HasUnitState(UNIT_STATE_CASTING) && !triggered))
+ if (me->HasUnitState(UNIT_STATE_CASTING) && !(args.TriggerFlags & TRIGGERED_IGNORE_CAST_IN_PROGRESS))
return;
- me->CastSpell(victim, spellId, triggered);
+ me->CastSpell(victim, spellId, args);
}
-void UnitAI::DoCastVictim(uint32 spellId, bool triggered)
+void UnitAI::DoCastVictim(uint32 spellId, CastSpellExtraArgs const& args)
{
- if (!me->GetVictim() || (me->HasUnitState(UNIT_STATE_CASTING) && !triggered))
- return;
-
- me->CastSpell(me->GetVictim(), spellId, triggered);
-}
-
-void UnitAI::DoCastAOE(uint32 spellId, bool triggered)
-{
- if (!triggered && me->HasUnitState(UNIT_STATE_CASTING))
- return;
-
- me->CastSpell(nullptr, spellId, triggered);
+ if (Unit* victim = me->GetVictim())
+ DoCast(victim, spellId, args);
}
uint32 UnitAI::GetDialogStatus(Player* /*player*/)
diff --git a/src/server/game/AI/CoreAI/UnitAI.h b/src/server/game/AI/CoreAI/UnitAI.h
index 345495579e1..9bd9836fe44 100644
--- a/src/server/game/AI/CoreAI/UnitAI.h
+++ b/src/server/game/AI/CoreAI/UnitAI.h
@@ -22,6 +22,7 @@
#include "Containers.h"
#include "EventMap.h"
#include "ObjectGuid.h"
+#include "SpellDefines.h"
#include "ThreatManager.h"
#define CAST_AI(a, b) (dynamic_cast<a*>(b))
@@ -294,10 +295,10 @@ class TC_GAME_API UnitAI
void AttackStartCaster(Unit* victim, float dist);
void DoCast(uint32 spellId);
- void DoCast(Unit* victim, uint32 spellId, bool triggered = false);
- void DoCastSelf(uint32 spellId, bool triggered = false) { DoCast(me, spellId, triggered); }
- void DoCastVictim(uint32 spellId, bool triggered = false);
- void DoCastAOE(uint32 spellId, bool triggered = false);
+ void DoCast(Unit* victim, uint32 spellId, CastSpellExtraArgs const& args = {});
+ void DoCastSelf(uint32 spellId, CastSpellExtraArgs const& args = {}) { DoCast(me, spellId, args); }
+ void DoCastVictim(uint32 spellId, CastSpellExtraArgs const& args = {});
+ void DoCastAOE(uint32 spellId, CastSpellExtraArgs const& args = {}) { DoCast(nullptr, spellId, args); }
float DoGetSpellMaxRange(uint32 spellId, bool positive = false);
diff --git a/src/server/game/AI/PlayerAI/PlayerAI.cpp b/src/server/game/AI/PlayerAI/PlayerAI.cpp
index a103b34ff56..ded7a97122e 100644
--- a/src/server/game/AI/PlayerAI/PlayerAI.cpp
+++ b/src/server/game/AI/PlayerAI/PlayerAI.cpp
@@ -690,7 +690,7 @@ void PlayerAI::DoCastAtTarget(TargetedSpell spell)
{
SpellCastTargets targets;
targets.SetUnitTarget(spell.second);
- spell.first->prepare(&targets);
+ spell.first->prepare(targets);
}
void PlayerAI::DoRangedAttackIfReady()
diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
index afa7e789b7a..8b2d0b0e410 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
+++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
@@ -183,7 +183,7 @@ void ScriptedAI::DoCastSpell(Unit* target, SpellInfo const* spellInfo, bool trig
return;
me->StopMoving();
- me->CastSpell(target, spellInfo, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE);
+ me->CastSpell(target, spellInfo->Id, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE);
}
void ScriptedAI::DoPlaySoundToSet(WorldObject* source, uint32 soundId)
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 9b1878b24d4..24f3a510859 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -1908,8 +1908,7 @@ void GameObject::Use(Unit* user)
if (!spellId)
return;
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
- if (!spellInfo)
+ if (!sSpellMgr->GetSpellInfo(spellId))
{
if (user->GetTypeId() != TYPEID_PLAYER || !sOutdoorPvPMgr->HandleCustomSpell(user->ToPlayer(), spellId, this))
TC_LOG_ERROR("misc", "WORLD: unknown spell id %u at use action for gameobject (Entry: %u GoType: %u)", spellId, GetEntry(), GetGoType());
@@ -1922,7 +1921,7 @@ void GameObject::Use(Unit* user)
sOutdoorPvPMgr->HandleCustomSpell(player, spellId, this);
if (spellCaster)
- spellCaster->CastSpell(user, spellInfo, triggered);
+ spellCaster->CastSpell(user, spellId, triggered);
else
CastSpell(user, spellId);
}
@@ -1951,7 +1950,7 @@ void GameObject::CastSpell(Unit* target, uint32 spellId, TriggerCastFlags trigge
if (self)
{
if (target)
- target->CastSpell(target, spellInfo, triggered);
+ target->CastSpell(target, spellInfo->Id, triggered);
return;
}
@@ -1963,6 +1962,8 @@ void GameObject::CastSpell(Unit* target, uint32 spellId, TriggerCastFlags trigge
// remove immunity flags, to allow spell to target anything
trigger->SetImmuneToAll(false);
+ CastSpellExtraArgs args;
+ args.TriggerFlags = triggered;
if (Unit* owner = GetOwner())
{
trigger->SetFaction(owner->GetFaction());
@@ -1972,14 +1973,17 @@ void GameObject::CastSpell(Unit* target, uint32 spellId, TriggerCastFlags trigge
trigger->SetByteValue(UNIT_FIELD_BYTES_2, 1, owner->GetByteValue(UNIT_FIELD_BYTES_2, 1));
// needed for GO casts for proper target validation checks
trigger->SetOwnerGUID(owner->GetGUID());
- trigger->CastSpell(target ? target : trigger, spellInfo, triggered, nullptr, nullptr, owner->GetGUID());
+
+ args.OriginalCaster = owner->GetGUID();
+ trigger->CastSpell(target ? target : trigger, spellInfo->Id, args);
}
else
{
trigger->SetFaction(spellInfo->IsPositive() ? FACTION_FRIENDLY : FACTION_MONSTER);
// Set owner guid for target if no owner available - needed by trigger auras
// - trigger gets despawned and there's no caster avalible (see AuraEffect::TriggerSpell())
- trigger->CastSpell(target ? target : trigger, spellInfo, triggered, nullptr, nullptr, target ? target->GetGUID() : ObjectGuid::Empty);
+ args.OriginalCaster = target ? target->GetGUID() : ObjectGuid::Empty;
+ trigger->CastSpell(target ? target : trigger, spellInfo->Id, args);
}
}
diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp
index 96e9746bbbe..797762867ca 100644
--- a/src/server/game/Entities/Pet/Pet.cpp
+++ b/src/server/game/Entities/Pet/Pet.cpp
@@ -1870,13 +1870,13 @@ void Pet::CastPetAura(PetAura const* aura)
if (!auraId)
return;
+ CastSpellExtraArgs args;
+ args.TriggerFlags = TRIGGERED_FULL_MASK;
+
if (auraId == 35696) // Demonic Knowledge
- {
- int32 basePoints = CalculatePct(aura->GetDamage(), GetStat(STAT_STAMINA) + GetStat(STAT_INTELLECT));
- CastCustomSpell(this, auraId, &basePoints, nullptr, nullptr, true);
- }
- else
- CastSpell(this, auraId, true);
+ args.SpellValueOverrides.AddMod(SPELLVALUE_BASE_POINT0, CalculatePct(aura->GetDamage(), GetStat(STAT_STAMINA) + GetStat(STAT_INTELLECT)));
+
+ CastSpell(this, auraId, args);
}
bool Pet::IsPetAura(Aura const* aura)
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 26ea8582f23..ab5f4618d7a 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -7679,7 +7679,7 @@ void Player::ApplyItemObtainSpells(Item* item, bool apply)
if (apply)
{
if (!HasAura(spellId))
- CastSpell(this, spellId, true, item);
+ CastSpell(this, spellId, item);
}
else
RemoveAurasDueToSpell(spellId);
@@ -7813,7 +7813,7 @@ void Player::ApplyEquipSpell(SpellInfo const* spellInfo, Item* item, bool apply,
TC_LOG_DEBUG("entities.player", "Player::ApplyEquipSpell: Player '%s' (%s) cast %s equip spell (ID: %i)",
GetName().c_str(), GetGUID().ToString().c_str(), (item ? "item" : "itemset"), spellInfo->Id);
- CastSpell(this, spellInfo, true, item);
+ CastSpell(this, spellInfo->Id, item);
}
else
{
@@ -7953,7 +7953,7 @@ void Player::CastItemCombatSpell(DamageInfo const& damageInfo, Item* item, ItemT
chance = GetWeaponProcChance();
if (roll_chance_f(chance) && sScriptMgr->OnCastItemCombatSpell(this, damageInfo.GetVictim(), spellInfo, item))
- CastSpell(damageInfo.GetVictim(), spellInfo->Id, true, item);
+ CastSpell(damageInfo.GetVictim(), spellInfo->Id, item);
}
}
@@ -8017,8 +8017,8 @@ void Player::CastItemCombatSpell(DamageInfo const& damageInfo, Item* item, ItemT
{
Unit* target = spellInfo->IsPositive() ? this : damageInfo.GetVictim();
+ CastSpellExtraArgs args(item);
// reduce effect values if enchant is limited
- CustomSpellValues values;
if (entry && (entry->AttributesMask & ENCHANT_PROC_ATTR_LIMIT_60) && target->getLevel() > 60)
{
int32 const lvlDifference = target->getLevel() - 60;
@@ -8029,11 +8029,10 @@ void Player::CastItemCombatSpell(DamageInfo const& damageInfo, Item* item, ItemT
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
if (spellInfo->Effects[i].IsEffect())
- values.AddSpellMod(static_cast<SpellValueMod>(SPELLVALUE_BASE_POINT0 + i), CalculatePct(spellInfo->Effects[i].CalcValue(this), effectPct));
+ args.SpellValueOverrides.AddMod(static_cast<SpellValueMod>(SPELLVALUE_BASE_POINT0 + i), CalculatePct(spellInfo->Effects[i].CalcValue(this), effectPct));
}
}
-
- CastCustomSpell(spellInfo->Id, values, target, TRIGGERED_FULL_MASK, item);
+ CastSpell(target, spellInfo->Id, args);
}
}
}
@@ -8060,7 +8059,7 @@ void Player::CastItemUseSpell(Item* item, SpellCastTargets const& targets, uint8
spell->m_CastItem = item;
spell->m_cast_count = cast_count; //set count of casts
spell->SetSpellValue(SPELLVALUE_BASE_POINT0, learning_spell_id);
- spell->prepare(&targets);
+ spell->prepare(targets);
return;
}
@@ -8088,7 +8087,7 @@ void Player::CastItemUseSpell(Item* item, SpellCastTargets const& targets, uint8
spell->m_CastItem = item;
spell->m_cast_count = cast_count; // set count of casts
spell->m_glyphIndex = glyphIndex; // glyph index
- spell->prepare(&targets);
+ spell->prepare(targets);
return;
}
@@ -8115,7 +8114,7 @@ void Player::CastItemUseSpell(Item* item, SpellCastTargets const& targets, uint8
spell->m_CastItem = item;
spell->m_cast_count = cast_count; // set count of casts
spell->m_glyphIndex = glyphIndex; // glyph index
- spell->prepare(&targets);
+ spell->prepare(targets);
return;
}
}
@@ -13664,11 +13663,14 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool
}
}
}
+
+ CastSpellExtraArgs args(item);
// Cast custom spell vs all equal basepoints got from enchant_amount
if (basepoints)
- CastCustomSpell(this, enchant_spell_id, &basepoints, &basepoints, &basepoints, true, item);
- else
- CastSpell(this, enchant_spell_id, true, item);
+ for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ args.SpellValueOverrides.AddMod(SpellValueMod(SPELLVALUE_BASE_POINT0 + i), basepoints);
+
+ CastSpell(this, enchant_spell_id, args);
}
else
RemoveAurasDueToItemSpell(enchant_spell_id, item->GetGUID());
@@ -14291,7 +14293,7 @@ void Player::OnGossipSelect(WorldObject* source, uint32 gossipListId, uint32 men
break;
case GOSSIP_OPTION_SPIRITHEALER:
if (isDead())
- source->ToCreature()->CastSpell(source->ToCreature(), 17251, true, nullptr, nullptr, GetGUID());
+ source->ToCreature()->CastSpell(source->ToCreature(), 17251, GetGUID());
break;
case GOSSIP_OPTION_QUESTGIVER:
PrepareQuestMenu(guid);
@@ -14312,8 +14314,8 @@ void Player::OnGossipSelect(WorldObject* source, uint32 gossipListId, uint32 men
{
// Cast spells that teach dual spec
// Both are also ImplicitTarget self and must be cast by player
- CastSpell(this, 63680, true, nullptr, nullptr, GetGUID());
- CastSpell(this, 63624, true, nullptr, nullptr, GetGUID());
+ CastSpell(this, 63680, GetGUID());
+ CastSpell(this, 63624, GetGUID());
PrepareGossipMenu(source, menuItemData->GossipActionMenuId);
SendPreparedGossip(source);
@@ -23744,11 +23746,11 @@ void Player::ResurrectUsingRequestData()
if (uint32 aura = _resurrectionData->Aura)
{
- CastSpell(this, aura, true, nullptr, nullptr, _resurrectionData->GUID);
+ CastSpell(this, aura, _resurrectionData->GUID);
return;
}
- /// Teleport before resurrecting by player, otherwise the player might get attacked from creatures near his corpse
+ // Teleport before resurrecting by player, otherwise the player might get attacked from creatures near his corpse
TeleportTo(_resurrectionData->Location);
if (IsBeingTeleported())
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index b67406eba74..a3332fe5ca0 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -958,133 +958,46 @@ void Unit::CastStop(uint32 except_spellid)
InterruptSpell(CurrentSpellTypes(i), false);
}
-void Unit::CastSpell(SpellCastTargets const& targets, SpellInfo const* spellInfo, CustomSpellValues const* value, TriggerCastFlags triggerFlags, Item* castItem, AuraEffect const* triggeredByAura, ObjectGuid originalCaster)
+void Unit::CastSpell(SpellCastTargets const& targets, uint32 spellId, CastSpellExtraArgs const& args)
{
- if (!spellInfo)
+ SpellInfo const* info = sSpellMgr->GetSpellInfo(spellId);
+ if (!info)
{
- TC_LOG_ERROR("entities.unit", "CastSpell: unknown spell by caster: %s %u)", (GetTypeId() == TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"), (GetTypeId() == TYPEID_PLAYER ? GetGUID().GetCounter() : GetEntry()));
+ TC_LOG_ERROR("entities.unit", "CastSpell: unknown spell %u by caster %s", spellId, GetGUID().ToString().c_str());
return;
}
- Spell* spell = new Spell(this, spellInfo, triggerFlags, originalCaster);
-
- if (value)
- for (CustomSpellValues::const_iterator itr = value->begin(); itr != value->end(); ++itr)
- spell->SetSpellValue(itr->first, itr->second);
-
- spell->m_CastItem = castItem;
- spell->prepare(&targets, triggeredByAura);
-}
-
-void Unit::CastSpell(Unit* victim, uint32 spellId, bool triggered, Item* castItem, AuraEffect const* triggeredByAura, ObjectGuid originalCaster)
-{
- CastSpell(victim, spellId, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, castItem, triggeredByAura, originalCaster);
-}
-
-void Unit::CastSpell(Unit* victim, uint32 spellId, TriggerCastFlags triggerFlags /*= TRIGGER_NONE*/, Item* castItem /*= nullptr*/, AuraEffect const* triggeredByAura /*= nullptr*/, ObjectGuid originalCaster /*= ObjectGuid::Empty*/)
-{
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
- if (!spellInfo)
- {
- TC_LOG_ERROR("entities.unit", "CastSpell: unknown spell id %u by caster: %s %u)", spellId, (GetTypeId() == TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"), (GetTypeId() == TYPEID_PLAYER ? GetGUID().GetCounter() : GetEntry()));
- return;
- }
-
- CastSpell(victim, spellInfo, triggerFlags, castItem, triggeredByAura, originalCaster);
-}
-
-void Unit::CastSpell(Unit* victim, SpellInfo const* spellInfo, bool triggered, Item* castItem/*= nullptr*/, AuraEffect const* triggeredByAura /*= nullptr*/, ObjectGuid originalCaster /*= ObjectGuid::Empty*/)
-{
- CastSpell(victim, spellInfo, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, castItem, triggeredByAura, originalCaster);
-}
-
-void Unit::CastSpell(Unit* victim, SpellInfo const* spellInfo, TriggerCastFlags triggerFlags, Item* castItem, AuraEffect const* triggeredByAura, ObjectGuid originalCaster)
-{
- SpellCastTargets targets;
- targets.SetUnitTarget(victim);
- CastSpell(targets, spellInfo, nullptr, triggerFlags, castItem, triggeredByAura, originalCaster);
-}
-
-void Unit::CastCustomSpell(Unit* target, uint32 spellId, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item* castItem, AuraEffect const* triggeredByAura, ObjectGuid originalCaster)
-{
- CustomSpellValues values;
- if (bp0)
- values.AddSpellMod(SPELLVALUE_BASE_POINT0, *bp0);
- if (bp1)
- values.AddSpellMod(SPELLVALUE_BASE_POINT1, *bp1);
- if (bp2)
- values.AddSpellMod(SPELLVALUE_BASE_POINT2, *bp2);
- CastCustomSpell(spellId, values, target, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, castItem, triggeredByAura, originalCaster);
-}
-
-void Unit::CastCustomSpell(uint32 spellId, SpellValueMod mod, int32 value, Unit* target, bool triggered, Item* castItem, AuraEffect const* triggeredByAura, ObjectGuid originalCaster)
-{
- CustomSpellValues values;
- values.AddSpellMod(mod, value);
- CastCustomSpell(spellId, values, target, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, castItem, triggeredByAura, originalCaster);
-}
-
-void Unit::CastCustomSpell(uint32 spellId, SpellValueMod mod, int32 value, Unit* target, TriggerCastFlags triggerFlags, Item* castItem, AuraEffect const* triggeredByAura, ObjectGuid originalCaster)
-{
- CustomSpellValues values;
- values.AddSpellMod(mod, value);
- CastCustomSpell(spellId, values, target, triggerFlags, castItem, triggeredByAura, originalCaster);
-}
-
-void Unit::CastCustomSpell(uint32 spellId, CustomSpellValues const& value, Unit* victim, TriggerCastFlags triggerFlags, Item* castItem, AuraEffect const* triggeredByAura, ObjectGuid originalCaster)
-{
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
- if (!spellInfo)
- {
- TC_LOG_ERROR("entities.unit", "CastSpell: unknown spell id %u by caster: %s %u)", spellId, (GetTypeId() == TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"), (GetTypeId() == TYPEID_PLAYER ? GetGUID().GetCounter() : GetEntry()));
- return;
- }
- SpellCastTargets targets;
- targets.SetUnitTarget(victim);
+ Spell* spell = new Spell(this, info, args.TriggerFlags, args.OriginalCaster);
+ for (auto const& pair : args.SpellValueOverrides)
+ spell->SetSpellValue(pair.first, pair.second);
- CastSpell(targets, spellInfo, &value, triggerFlags, castItem, triggeredByAura, originalCaster);
+ spell->m_CastItem = args.CastItem;
+ spell->prepare(targets, args.TriggeringAura);
}
-void Unit::CastSpell(float x, float y, float z, uint32 spellId, bool triggered, Item* castItem, AuraEffect const* triggeredByAura, ObjectGuid originalCaster)
+void Unit::CastSpell(WorldObject* target, uint32 spellId, CastSpellExtraArgs const& args)
{
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
- if (!spellInfo)
- {
- TC_LOG_ERROR("entities.unit", "CastSpell: unknown spell id %u by caster: %s %u)", spellId, (GetTypeId() == TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"), (GetTypeId() == TYPEID_PLAYER ? GetGUID().GetCounter() : GetEntry()));
- return;
- }
SpellCastTargets targets;
- targets.SetDst(x, y, z, GetOrientation());
-
- CastSpell(targets, spellInfo, nullptr, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, castItem, triggeredByAura, originalCaster);
-}
-
-void Unit::CastSpell(float x, float y, float z, uint32 spellId, TriggerCastFlags triggerFlags, Item* castItem, AuraEffect const* triggeredByAura, ObjectGuid originalCaster)
-{
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
- if (!spellInfo)
+ if (target)
{
- TC_LOG_ERROR("entities.unit", "CastSpell: unknown spell id %u by caster: %s %u)", spellId, (GetTypeId() == TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"), (GetTypeId() == TYPEID_PLAYER ? GetGUID().GetCounter() : GetEntry()));
- return;
+ if (Unit* unitTarget = target->ToUnit())
+ targets.SetUnitTarget(unitTarget);
+ else if (GameObject* goTarget = target->ToGameObject())
+ targets.SetGOTarget(goTarget);
+ else
+ {
+ TC_LOG_ERROR("entities.unit", "CastSpell: Invalid target %s passed to spell cast by %s", target->GetGUID().ToString().c_str(), GetGUID().ToString().c_str());
+ return;
+ }
}
- SpellCastTargets targets;
- targets.SetDst(x, y, z, GetOrientation());
-
- CastSpell(targets, spellInfo, nullptr, triggerFlags, castItem, triggeredByAura, originalCaster);
+ CastSpell(targets, spellId, args);
}
-void Unit::CastSpell(GameObject* go, uint32 spellId, bool triggered, Item* castItem, AuraEffect* triggeredByAura, ObjectGuid originalCaster)
+void Unit::CastSpell(Position const& dest, uint32 spellId, CastSpellExtraArgs const& args)
{
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
- if (!spellInfo)
- {
- TC_LOG_ERROR("entities.unit", "CastSpell: unknown spell id %u by caster: %s %u)", spellId, (GetTypeId() == TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"), (GetTypeId() == TYPEID_PLAYER ? GetGUID().GetCounter() : GetEntry()));
- return;
- }
SpellCastTargets targets;
- targets.SetGOTarget(go);
-
- CastSpell(targets, spellInfo, nullptr, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, castItem, triggeredByAura, originalCaster);
+ targets.SetDst(dest);
+ CastSpell(targets, spellId, args);
}
void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 damage, SpellInfo const* spellInfo, WeaponAttackType attackType, bool crit)
@@ -3133,7 +3046,7 @@ void Unit::_UpdateAutoRepeatSpell()
// we want to shoot
Spell* spell = new Spell(this, autoRepeatSpellInfo, TRIGGERED_FULL_MASK);
- spell->prepare(&(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_targets));
+ spell->prepare(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_targets);
// all went good, reset attack
resetAttackTimer(RANGED_ATTACK);
@@ -6033,7 +5946,7 @@ void Unit::ModifyAuraState(AuraStateType flag, bool apply)
if (!spellInfo || !spellInfo->IsPassive())
continue;
if (spellInfo->CasterAuraState == uint32(flag))
- CastSpell(this, itr->first, true, nullptr);
+ CastSpell(this, itr->first, true);
}
}
else if (Pet* pet = ToCreature()->ToPet())
@@ -6046,7 +5959,7 @@ void Unit::ModifyAuraState(AuraStateType flag, bool apply)
if (!spellInfo || !spellInfo->IsPassive())
continue;
if (spellInfo->CasterAuraState == uint32(flag))
- CastSpell(this, itr->first, true, nullptr);
+ CastSpell(this, itr->first, true);
}
}
}
@@ -10861,7 +10774,7 @@ void CharmInfo::InitPossessCreateSpells()
if (spellInfo)
{
if (spellInfo->IsPassive())
- _unit->CastSpell(_unit, spellInfo, true);
+ _unit->CastSpell(_unit, spellInfo->Id, true);
else
AddSpellToActionBar(spellInfo, ACT_PASSIVE, i % MAX_UNIT_ACTION_BAR_INDEX);
}
@@ -10894,7 +10807,7 @@ void CharmInfo::InitCharmCreateSpells()
if (spellInfo->IsPassive())
{
- _unit->CastSpell(_unit, spellInfo, true);
+ _unit->CastSpell(_unit, spellInfo->Id, true);
_charmspells[x].SetActionAndType(spellId, ACT_PASSIVE);
}
else
@@ -12125,7 +12038,7 @@ void Unit::Kill(Unit* victim, bool durabilityLoss)
victim->SetUInt32Value(PLAYER_SELF_RES_SPELL, ressSpellId);
// FORM_SPIRITOFREDEMPTION and related auras
- victim->CastSpell(victim, 27827, true, nullptr, aurEff);
+ victim->CastSpell(victim, 27827, aurEff);
spiritOfRedemption = true;
break;
}
@@ -13656,7 +13569,12 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId)
}
if (IsInMap(caster))
- caster->CastCustomSpell(itr->second.spellId, SpellValueMod(SPELLVALUE_BASE_POINT0+i), seatId + 1, target, flags, nullptr, nullptr, origCasterGUID);
+ {
+ CastSpellExtraArgs args(flags);
+ args.OriginalCaster = origCasterGUID;
+ args.SpellValueOverrides.AddMod(SpellValueMod(SPELLVALUE_BASE_POINT0+i), seatId+1);
+ caster->CastSpell(target, itr->second.spellId, args);
+ }
else // This can happen during Player::_LoadAuras
{
int32 bp0[MAX_SPELL_EFFECTS];
@@ -13670,7 +13588,7 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId)
else
{
if (IsInMap(caster))
- caster->CastSpell(target, spellEntry, flags, nullptr, nullptr, origCasterGUID);
+ caster->CastSpell(target, spellEntry->Id, CastSpellExtraArgs().SetOriginalCaster(origCasterGUID));
else
Aura::TryRefreshStackOrCreate(spellEntry, MAX_EFFECT_MASK, this, clicker, nullptr, nullptr, origCasterGUID);
}
@@ -13687,7 +13605,9 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId)
void Unit::EnterVehicle(Unit* base, int8 seatId)
{
- CastCustomSpell(VEHICLE_SPELL_RIDE_HARDCODED, SPELLVALUE_BASE_POINT0, seatId + 1, base, TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE);
+ CastSpellExtraArgs args(TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE);
+ args.SpellValueOverrides.AddBP0(seatId + 1);
+ CastSpell(base, VEHICLE_SPELL_RIDE_HARDCODED, args);
}
void Unit::_EnterVehicle(Vehicle* vehicle, int8 seatId, AuraApplication const* aurApp)
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index af0676ad2af..9659677282a 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -26,6 +26,7 @@
#include "HostileRefManager.h"
#include "OptionalFwd.h"
#include "SpellAuraDefines.h"
+#include "SpellDefines.h"
#include "ThreatManager.h"
#include "Timer.h"
#include "UnitDefines.h"
@@ -34,172 +35,6 @@
#define WORLD_TRIGGER 12999
-enum SpellInterruptFlags
-{
- SPELL_INTERRUPT_FLAG_MOVEMENT = 0x01, // why need this for instant?
- SPELL_INTERRUPT_FLAG_PUSH_BACK = 0x02, // push back
- SPELL_INTERRUPT_FLAG_UNK3 = 0x04, // any info?
- SPELL_INTERRUPT_FLAG_INTERRUPT = 0x08, // interrupt
- SPELL_INTERRUPT_FLAG_ABORT_ON_DMG = 0x10 // _complete_ interrupt on direct damage
- //SPELL_INTERRUPT_UNK = 0x20 // unk, 564 of 727 spells having this spell start with "Glyph"
-};
-
-// See SpellAuraInterruptFlags for other values definitions
-enum SpellChannelInterruptFlags
-{
- CHANNEL_INTERRUPT_FLAG_INTERRUPT = 0x08, // interrupt
- CHANNEL_FLAG_DELAY = 0x4000
-};
-
-enum SpellAuraInterruptFlags
-{
- AURA_INTERRUPT_FLAG_HITBYSPELL = 0x00000001, // 0 removed when getting hit by a negative spell?
- AURA_INTERRUPT_FLAG_TAKE_DAMAGE = 0x00000002, // 1 removed by any damage
- AURA_INTERRUPT_FLAG_CAST = 0x00000004, // 2 cast any spells
- AURA_INTERRUPT_FLAG_MOVE = 0x00000008, // 3 removed by any movement
- AURA_INTERRUPT_FLAG_TURNING = 0x00000010, // 4 removed by any turning
- AURA_INTERRUPT_FLAG_JUMP = 0x00000020, // 5 removed by entering combat
- AURA_INTERRUPT_FLAG_NOT_MOUNTED = 0x00000040, // 6 removed by dismounting
- AURA_INTERRUPT_FLAG_NOT_ABOVEWATER = 0x00000080, // 7 removed by entering water
- AURA_INTERRUPT_FLAG_NOT_UNDERWATER = 0x00000100, // 8 removed by leaving water
- AURA_INTERRUPT_FLAG_NOT_SHEATHED = 0x00000200, // 9 removed by unsheathing
- AURA_INTERRUPT_FLAG_TALK = 0x00000400, // 10 talk to npc / loot? action on creature
- AURA_INTERRUPT_FLAG_USE = 0x00000800, // 11 mine/use/open action on gameobject
- AURA_INTERRUPT_FLAG_MELEE_ATTACK = 0x00001000, // 12 removed by attacking
- AURA_INTERRUPT_FLAG_SPELL_ATTACK = 0x00002000, // 13 ???
- AURA_INTERRUPT_FLAG_UNK14 = 0x00004000, // 14
- AURA_INTERRUPT_FLAG_TRANSFORM = 0x00008000, // 15 removed by transform?
- AURA_INTERRUPT_FLAG_UNK16 = 0x00010000, // 16
- AURA_INTERRUPT_FLAG_MOUNT = 0x00020000, // 17 misdirect, aspect, swim speed
- AURA_INTERRUPT_FLAG_NOT_SEATED = 0x00040000, // 18 removed by standing up (used by food and drink mostly and sleep/Fake Death like)
- AURA_INTERRUPT_FLAG_CHANGE_MAP = 0x00080000, // 19 leaving map/getting teleported
- AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION = 0x00100000, // 20 removed by auras that make you invulnerable, or make other to lose selection on you
- AURA_INTERRUPT_FLAG_UNK21 = 0x00200000, // 21
- AURA_INTERRUPT_FLAG_TELEPORTED = 0x00400000, // 22
- AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT = 0x00800000, // 23 removed by entering pvp combat
- AURA_INTERRUPT_FLAG_DIRECT_DAMAGE = 0x01000000, // 24 removed by any direct damage
- AURA_INTERRUPT_FLAG_LANDING = 0x02000000, // 25 removed by hitting the ground
- AURA_INTERRUPT_FLAG_LEAVE_COMBAT = 0x80000000, // 31 removed by leaving combat
-
- AURA_INTERRUPT_FLAG_NOT_VICTIM = (AURA_INTERRUPT_FLAG_HITBYSPELL | AURA_INTERRUPT_FLAG_TAKE_DAMAGE | AURA_INTERRUPT_FLAG_DIRECT_DAMAGE)
-};
-
-enum SpellModOp : uint8
-{
- SPELLMOD_DAMAGE = 0,
- SPELLMOD_DURATION = 1,
- SPELLMOD_THREAT = 2,
- SPELLMOD_EFFECT1 = 3,
- SPELLMOD_CHARGES = 4,
- SPELLMOD_RANGE = 5,
- SPELLMOD_RADIUS = 6,
- SPELLMOD_CRITICAL_CHANCE = 7,
- SPELLMOD_ALL_EFFECTS = 8,
- SPELLMOD_NOT_LOSE_CASTING_TIME = 9,
- SPELLMOD_CASTING_TIME = 10,
- SPELLMOD_COOLDOWN = 11,
- SPELLMOD_EFFECT2 = 12,
- SPELLMOD_IGNORE_ARMOR = 13,
- SPELLMOD_COST = 14,
- SPELLMOD_CRIT_DAMAGE_BONUS = 15,
- SPELLMOD_RESIST_MISS_CHANCE = 16,
- SPELLMOD_JUMP_TARGETS = 17,
- SPELLMOD_CHANCE_OF_SUCCESS = 18,
- SPELLMOD_ACTIVATION_TIME = 19,
- SPELLMOD_DAMAGE_MULTIPLIER = 20,
- SPELLMOD_GLOBAL_COOLDOWN = 21,
- SPELLMOD_DOT = 22,
- SPELLMOD_EFFECT3 = 23,
- SPELLMOD_BONUS_MULTIPLIER = 24,
- // spellmod 25
- SPELLMOD_PROC_PER_MINUTE = 26,
- SPELLMOD_VALUE_MULTIPLIER = 27,
- SPELLMOD_RESIST_DISPEL_CHANCE = 28,
- SPELLMOD_CRIT_DAMAGE_BONUS_2 = 29, //one not used spell
- SPELLMOD_SPELL_COST_REFUND_ON_FAIL = 30,
-
- MAX_SPELLMOD
-};
-
-enum SpellValueMod : uint8
-{
- SPELLVALUE_BASE_POINT0,
- SPELLVALUE_BASE_POINT1,
- SPELLVALUE_BASE_POINT2,
- SPELLVALUE_RADIUS_MOD,
- SPELLVALUE_MAX_TARGETS,
- SPELLVALUE_AURA_STACK
-};
-
-class CustomSpellValues
-{
- typedef std::pair<SpellValueMod, int32> CustomSpellValueMod;
- typedef std::vector<CustomSpellValueMod> StorageType;
-
-public:
- typedef StorageType::const_iterator const_iterator;
-
-public:
- void AddSpellMod(SpellValueMod mod, int32 value)
- {
- storage_.push_back(CustomSpellValueMod(mod, value));
- }
-
- const_iterator begin() const
- {
- return storage_.begin();
- }
-
- const_iterator end() const
- {
- return storage_.end();
- }
-
-private:
- StorageType storage_;
-};
-
-enum SpellFacingFlags
-{
- SPELL_FACING_FLAG_INFRONT = 0x0001
-};
-
-// high byte (3 from 0..3) of UNIT_FIELD_BYTES_2
-enum ShapeshiftForm
-{
- FORM_NONE = 0x00,
- FORM_CAT = 0x01,
- FORM_TREE = 0x02,
- FORM_TRAVEL = 0x03,
- FORM_AQUA = 0x04,
- FORM_BEAR = 0x05,
- FORM_AMBIENT = 0x06,
- FORM_GHOUL = 0x07,
- FORM_DIREBEAR = 0x08,
- FORM_STEVES_GHOUL = 0x09,
- FORM_THARONJA_SKELETON = 0x0A,
- FORM_TEST_OF_STRENGTH = 0x0B,
- FORM_BLB_PLAYER = 0x0C,
- FORM_SHADOW_DANCE = 0x0D,
- FORM_CREATUREBEAR = 0x0E,
- FORM_CREATURECAT = 0x0F,
- FORM_GHOSTWOLF = 0x10,
- FORM_BATTLESTANCE = 0x11,
- FORM_DEFENSIVESTANCE = 0x12,
- FORM_BERSERKERSTANCE = 0x13,
- FORM_TEST = 0x14,
- FORM_ZOMBIE = 0x15,
- FORM_METAMORPHOSIS = 0x16,
- FORM_UNDEAD = 0x19,
- FORM_MASTER_ANGLER = 0x1A,
- FORM_FLIGHT_EPIC = 0x1B,
- FORM_SHADOW = 0x1C,
- FORM_FLIGHT = 0x1D,
- FORM_STEALTH = 0x1E,
- FORM_MOONKIN = 0x1F,
- FORM_SPIRITOFREDEMPTION = 0x20
-};
-
#define MAX_SPELL_CHARM 4
#define MAX_SPELL_VEHICLE 6
#define MAX_SPELL_POSSESS 8
@@ -310,35 +145,6 @@ enum WeaponDamageRange
MAXDAMAGE
};
-enum TriggerCastFlags : uint32
-{
- TRIGGERED_NONE = 0x00000000, //! Not triggered
- TRIGGERED_IGNORE_GCD = 0x00000001, //! Will ignore GCD
- TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD = 0x00000002, //! Will ignore Spell and Category cooldowns
- TRIGGERED_IGNORE_POWER_AND_REAGENT_COST = 0x00000004, //! Will ignore power and reagent cost
- TRIGGERED_IGNORE_CAST_ITEM = 0x00000008, //! Will not take away cast item or update related achievement criteria
- TRIGGERED_IGNORE_AURA_SCALING = 0x00000010, //! Will ignore aura scaling
- TRIGGERED_IGNORE_CAST_IN_PROGRESS = 0x00000020, //! Will not check if a current cast is in progress
- TRIGGERED_IGNORE_COMBO_POINTS = 0x00000040, //! Will ignore combo point requirement
- TRIGGERED_CAST_DIRECTLY = 0x00000080, //! In Spell::prepare, will be cast directly without setting containers for executed spell
- TRIGGERED_IGNORE_AURA_INTERRUPT_FLAGS = 0x00000100, //! Will ignore interruptible aura's at cast
- TRIGGERED_IGNORE_SET_FACING = 0x00000200, //! Will not adjust facing to target (if any)
- TRIGGERED_IGNORE_SHAPESHIFT = 0x00000400, //! Will ignore shapeshift checks
- TRIGGERED_IGNORE_CASTER_AURASTATE = 0x00000800, //! Will ignore caster aura states including combat requirements and death state
- TRIGGERED_DISALLOW_PROC_EVENTS = 0x00001000, //! Disallows proc events from triggered spell (default)
- TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE = 0x00002000, //! Will ignore mounted/on vehicle restrictions
- // reuse = 0x00004000,
- // reuse = 0x00008000,
- TRIGGERED_IGNORE_CASTER_AURAS = 0x00010000, //! Will ignore caster aura restrictions or requirements
- TRIGGERED_DONT_RESET_PERIODIC_TIMER = 0x00020000, //! Will allow periodic aura timers to keep ticking (instead of resetting)
- TRIGGERED_DONT_REPORT_CAST_ERROR = 0x00040000, //! Will return SPELL_FAILED_DONT_REPORT in CheckCast functions
- TRIGGERED_FULL_MASK = 0x0007FFFF, //! Used when doing CastSpell with triggered == true
-
- // debug flags (used with .cast triggered commands)
- TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT = 0x00080000, //! Will ignore equipped item requirements
- TRIGGERED_FULL_DEBUG_MASK = 0xFFFFFFFF
-};
-
enum UnitMods
{
UNIT_MOD_STAT_STRENGTH, // UNIT_MOD_STAT_STRENGTH..UNIT_MOD_STAT_SPIRIT must be in existed order, it's accessed by index values of Stats enum.
@@ -1278,20 +1084,10 @@ class TC_GAME_API Unit : public WorldObject
void EnergizeBySpell(Unit* victim, uint32 spellId, int32 damage, Powers powerType);
void EnergizeBySpell(Unit* victim, SpellInfo const* spellInfo, int32 damage, Powers powerType);
- void CastSpell(SpellCastTargets const& targets, SpellInfo const* spellInfo, CustomSpellValues const* value, TriggerCastFlags triggerFlags = TRIGGERED_NONE, Item* castItem = nullptr, AuraEffect const* triggeredByAura = nullptr, ObjectGuid originalCaster = ObjectGuid::Empty);
- void CastSpell(Unit* victim, uint32 spellId, bool triggered, Item* castItem = nullptr, AuraEffect const* triggeredByAura = nullptr, ObjectGuid originalCaster = ObjectGuid::Empty);
- void CastSpell(std::nullptr_t, uint32 spellId, bool triggered, Item* castItem = nullptr, AuraEffect* triggeredByAura = nullptr, ObjectGuid originalCaster = ObjectGuid::Empty) { CastSpell((Unit*)nullptr, spellId, triggered, castItem, triggeredByAura, originalCaster); }
- void CastSpell(Unit* victim, uint32 spellId, TriggerCastFlags triggerFlags = TRIGGERED_NONE, Item* castItem = nullptr, AuraEffect const* triggeredByAura = nullptr, ObjectGuid originalCaster = ObjectGuid::Empty);
- void CastSpell(std::nullptr_t, uint32 spellId, TriggerCastFlags triggerFlags = TRIGGERED_NONE, Item* castItem = nullptr, AuraEffect* triggeredByAura = nullptr, ObjectGuid originalCaster = ObjectGuid::Empty) { CastSpell((Unit*)nullptr, spellId, triggerFlags, castItem, triggeredByAura, originalCaster); }
- void CastSpell(Unit* victim, SpellInfo const* spellInfo, bool triggered, Item* castItem = nullptr, AuraEffect const* triggeredByAura = nullptr, ObjectGuid originalCaster = ObjectGuid::Empty);
- void CastSpell(Unit* victim, SpellInfo const* spellInfo, TriggerCastFlags triggerFlags = TRIGGERED_NONE, Item* castItem = nullptr, AuraEffect const* triggeredByAura = nullptr, ObjectGuid originalCaster = ObjectGuid::Empty);
- void CastSpell(float x, float y, float z, uint32 spellId, bool triggered, Item* castItem = nullptr, AuraEffect const* triggeredByAura = nullptr, ObjectGuid originalCaster = ObjectGuid::Empty);
- void CastSpell(float x, float y, float z, uint32 spellId, TriggerCastFlags triggerFlags = TRIGGERED_NONE, Item* castItem = nullptr, AuraEffect const* triggeredByAura = nullptr, ObjectGuid originalCaster = ObjectGuid::Empty);
- void CastSpell(GameObject* go, uint32 spellId, bool triggered, Item* castItem = nullptr, AuraEffect* triggeredByAura = nullptr, ObjectGuid originalCaster = ObjectGuid::Empty);
- void CastCustomSpell(Unit* victim, uint32 spellId, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item* castItem = nullptr, AuraEffect const* triggeredByAura = nullptr, ObjectGuid originalCaster = ObjectGuid::Empty);
- void CastCustomSpell(uint32 spellId, SpellValueMod mod, int32 value, Unit* victim, bool triggered, Item* castItem = nullptr, AuraEffect const* triggeredByAura = nullptr, ObjectGuid originalCaster = ObjectGuid::Empty);
- void CastCustomSpell(uint32 spellId, SpellValueMod mod, int32 value, Unit* victim = nullptr, TriggerCastFlags triggerFlags = TRIGGERED_NONE, Item* castItem = nullptr, AuraEffect const* triggeredByAura = nullptr, ObjectGuid originalCaster = ObjectGuid::Empty);
- void CastCustomSpell(uint32 spellId, CustomSpellValues const& value, Unit* victim = nullptr, TriggerCastFlags triggerFlags = TRIGGERED_NONE, Item* castItem = nullptr, AuraEffect const* triggeredByAura = nullptr, ObjectGuid originalCaster = ObjectGuid::Empty);
+ // CastSpell's third arg can be a variety of things - check out CastSpellExtraArgs' constructors!
+ void CastSpell(SpellCastTargets const& targets, uint32 spellId, CastSpellExtraArgs const& args = {});
+ void CastSpell(WorldObject* target, uint32 spellId, CastSpellExtraArgs const& args = {});
+ void CastSpell(Position const& dest, uint32 spellId, CastSpellExtraArgs const& args = {});
Aura* AddAura(uint32 spellId, Unit* target);
Aura* AddAura(SpellInfo const* spellInfo, uint8 effMask, Unit* target);
void SetAuraStack(uint32 spellId, Unit* target, uint32 stack);
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index 1bab6418e6c..249303f8e14 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -854,8 +854,8 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
{
// not blizz like, we must correctly save and load player instead...
if (pCurrChar->getRace() == RACE_NIGHTELF)
- pCurrChar->CastSpell(pCurrChar, 20584, true, nullptr);// auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form)
- pCurrChar->CastSpell(pCurrChar, 8326, true, nullptr); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?)
+ pCurrChar->CastSpell(pCurrChar, 20584, true);// auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form)
+ pCurrChar->CastSpell(pCurrChar, 8326, true); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?)
pCurrChar->SetMovement(MOVE_WATER_WALK);
}
diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp
index d285681fa9f..77ae7ce0847 100644
--- a/src/server/game/Handlers/PetHandler.cpp
+++ b/src/server/game/Handlers/PetHandler.cpp
@@ -382,7 +382,7 @@ void WorldSession::HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint32 spe
}
}
- spell->prepare(&(spell->m_targets));
+ spell->prepare(spell->m_targets);
}
else
{
@@ -812,7 +812,7 @@ void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket)
}
}
- spell->prepare(&(spell->m_targets));
+ spell->prepare(spell->m_targets);
}
else
{
diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp
index e5336d4af21..fc43628ace5 100644
--- a/src/server/game/Handlers/SpellHandler.cpp
+++ b/src/server/game/Handlers/SpellHandler.cpp
@@ -409,7 +409,7 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
Spell* spell = new Spell(caster, spellInfo, TRIGGERED_NONE, ObjectGuid::Empty, false);
spell->m_cast_count = castCount; // set count of casts
- spell->prepare(&targets);
+ spell->prepare(targets);
}
void WorldSession::HandleCancelCastOpcode(WorldPacket& recvPacket)
@@ -562,12 +562,9 @@ void WorldSession::HandleSelfResOpcode(WorldPacket & /*recvData*/)
if (_player->HasAuraType(SPELL_AURA_PREVENT_RESURRECTION))
return; // silent return, client should display error by itself and not send this opcode
- if (_player->GetUInt32Value(PLAYER_SELF_RES_SPELL))
+ if (uint32 spellId = _player->GetUInt32Value(PLAYER_SELF_RES_SPELL))
{
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(_player->GetUInt32Value(PLAYER_SELF_RES_SPELL));
- if (spellInfo)
- _player->CastSpell(_player, spellInfo, false, nullptr);
-
+ _player->CastSpell(_player, spellId);
_player->SetUInt32Value(PLAYER_SELF_RES_SPELL, 0);
}
}
diff --git a/src/server/game/Handlers/TradeHandler.cpp b/src/server/game/Handlers/TradeHandler.cpp
index 3490e6da98d..4fcf90a6577 100644
--- a/src/server/game/Handlers/TradeHandler.cpp
+++ b/src/server/game/Handlers/TradeHandler.cpp
@@ -521,10 +521,10 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/)
trader->ModifyMoney(my_trade->GetMoney());
if (my_spell)
- my_spell->prepare(&my_targets);
+ my_spell->prepare(my_targets);
if (his_spell)
- his_spell->prepare(&his_targets);
+ his_spell->prepare(his_targets);
// cleanup
clearAcceptTradeMode(my_trade, his_trade);
diff --git a/src/server/game/Spells/Auras/SpellAuraDefines.h b/src/server/game/Spells/Auras/SpellAuraDefines.h
index 4fac4728b6c..e287a5d97cf 100644
--- a/src/server/game/Spells/Auras/SpellAuraDefines.h
+++ b/src/server/game/Spells/Auras/SpellAuraDefines.h
@@ -398,4 +398,40 @@ enum AuraObjectType
DYNOBJ_AURA_TYPE
};
+// high byte (3 from 0..3) of UNIT_FIELD_BYTES_2
+enum ShapeshiftForm
+{
+ FORM_NONE = 0x00,
+ FORM_CAT = 0x01,
+ FORM_TREE = 0x02,
+ FORM_TRAVEL = 0x03,
+ FORM_AQUA = 0x04,
+ FORM_BEAR = 0x05,
+ FORM_AMBIENT = 0x06,
+ FORM_GHOUL = 0x07,
+ FORM_DIREBEAR = 0x08,
+ FORM_STEVES_GHOUL = 0x09,
+ FORM_THARONJA_SKELETON = 0x0A,
+ FORM_TEST_OF_STRENGTH = 0x0B,
+ FORM_BLB_PLAYER = 0x0C,
+ FORM_SHADOW_DANCE = 0x0D,
+ FORM_CREATUREBEAR = 0x0E,
+ FORM_CREATURECAT = 0x0F,
+ FORM_GHOSTWOLF = 0x10,
+ FORM_BATTLESTANCE = 0x11,
+ FORM_DEFENSIVESTANCE = 0x12,
+ FORM_BERSERKERSTANCE = 0x13,
+ FORM_TEST = 0x14,
+ FORM_ZOMBIE = 0x15,
+ FORM_METAMORPHOSIS = 0x16,
+ FORM_UNDEAD = 0x19,
+ FORM_MASTER_ANGLER = 0x1A,
+ FORM_FLIGHT_EPIC = 0x1B,
+ FORM_SHADOW = 0x1C,
+ FORM_FLIGHT = 0x1D,
+ FORM_STEALTH = 0x1E,
+ FORM_MOONKIN = 0x1F,
+ FORM_SPIRITOFREDEMPTION = 0x20
+};
+
#endif
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 41014b55e72..2541f14acdf 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -1100,10 +1100,10 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const
if (apply)
{
if (spellId)
- target->CastSpell(target, spellId, true, nullptr, this);
+ target->CastSpell(target, spellId, this);
if (spellId2)
- target->CastSpell(target, spellId2, true, nullptr, this);
+ target->CastSpell(target, spellId2, this);
if (target->GetTypeId() == TYPEID_PLAYER)
{
@@ -1121,7 +1121,7 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const
continue;
if (spellInfo->Stances & (UI64LIT(1) << (GetMiscValue() - 1)))
- target->CastSpell(target, itr->first, true, nullptr, this);
+ target->CastSpell(target, itr->first, this);
}
// Also do it for Glyphs
@@ -1136,7 +1136,7 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const
continue;
if (spellInfo->Stances & (UI64LIT(1) << (GetMiscValue() - 1)))
- target->CastSpell(target, glyph->SpellId, true, nullptr, this);
+ target->CastSpell(target, glyph->SpellId, this);
}
}
}
@@ -1146,7 +1146,7 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const
{
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(24932);
if (spellInfo && spellInfo->Stances & (UI64LIT(1) << (GetMiscValue() - 1)))
- target->CastSpell(target, 24932, true, nullptr, this);
+ target->CastSpell(target, 24932, this);
}
// Improved Barkskin - apply/remove armor bonus due to shapeshift
if (target->ToPlayer()->HasSpell(63410) || target->ToPlayer()->HasSpell(63411))
@@ -1164,9 +1164,10 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const
// Heart of the Wild
if (aurEff->GetSpellInfo()->SpellIconID == 240 && aurEff->GetMiscValue() == 3)
{
- int32 HotWMod = aurEff->GetAmount() / 2; // For each 2% Intelligence, you get 1% stamina and 1% attack power.
+ CastSpellExtraArgs args(this);
+ args.SpellValueOverrides.AddMod(SPELLVALUE_BASE_POINT0, aurEff->GetAmount() / 2); // For each 2% Intelligence, you get 1% stamina and 1% attack power.
- target->CastCustomSpell(HotWSpellId, SPELLVALUE_BASE_POINT0, HotWMod, target, true, nullptr, this);
+ target->CastSpell(target, HotWSpellId, args);
break;
}
}
@@ -1190,46 +1191,51 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const
spellId3 = 47180;
break;
}
- target->CastSpell(target, spellId3, true, nullptr, this);
+ target->CastSpell(target, spellId3, this);
}
// Master Shapeshifter - Cat
if (AuraEffect const* aurEff = target->GetDummyAuraEffect(SPELLFAMILY_GENERIC, 2851, 0))
{
- int32 bp = aurEff->GetAmount();
- target->CastCustomSpell(48420, SPELLVALUE_BASE_POINT0, bp, target, true);
+ CastSpellExtraArgs args(TRIGGERED_FULL_MASK);
+ args.SpellValueOverrides.AddMod(SPELLVALUE_BASE_POINT0, aurEff->GetAmount());
+ target->CastSpell(target, 48420, args);
}
- break;
+ break;
case FORM_DIREBEAR:
case FORM_BEAR:
// Master Shapeshifter - Bear
if (AuraEffect const* aurEff = target->GetDummyAuraEffect(SPELLFAMILY_GENERIC, 2851, 0))
{
- int32 bp = aurEff->GetAmount();
- target->CastCustomSpell(48418, SPELLVALUE_BASE_POINT0, bp, target, true);
+ CastSpellExtraArgs args(TRIGGERED_FULL_MASK);
+ args.SpellValueOverrides.AddMod(SPELLVALUE_BASE_POINT0, aurEff->GetAmount());
+ target->CastSpell(target, 48418, args);
}
// Survival of the Fittest
if (AuraEffect const* aurEff = target->GetAuraEffect(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE, SPELLFAMILY_DRUID, 961, 0))
{
- int32 bp = aurEff->GetSpellInfo()->Effects[EFFECT_2].CalcValue();
- target->CastCustomSpell(62069, SPELLVALUE_BASE_POINT0, bp, target, true, nullptr, this);
+ CastSpellExtraArgs args(this);
+ args.SpellValueOverrides.AddMod(SPELLVALUE_BASE_POINT0, aurEff->GetSpellInfo()->Effects[EFFECT_2].CalcValue());
+ target->CastSpell(target, 62069, args);
}
- break;
+ break;
case FORM_MOONKIN:
// Master Shapeshifter - Moonkin
if (AuraEffect const* aurEff = target->GetDummyAuraEffect(SPELLFAMILY_GENERIC, 2851, 0))
{
- int32 bp = aurEff->GetAmount();
- target->CastCustomSpell(48421, SPELLVALUE_BASE_POINT0, bp, target, true);
+ CastSpellExtraArgs args(TRIGGERED_FULL_MASK);
+ args.SpellValueOverrides.AddMod(SPELLVALUE_BASE_POINT0, aurEff->GetAmount());
+ target->CastSpell(target, 48421, args);
}
- break;
- // Master Shapeshifter - Tree of Life
+ break;
case FORM_TREE:
+ // Master Shapeshifter - Tree of Life
if (AuraEffect const* aurEff = target->GetDummyAuraEffect(SPELLFAMILY_GENERIC, 2851, 0))
{
- int32 bp = aurEff->GetAmount();
- target->CastCustomSpell(48422, SPELLVALUE_BASE_POINT0, bp, target, true);
+ CastSpellExtraArgs args(TRIGGERED_FULL_MASK);
+ args.SpellValueOverrides.AddMod(SPELLVALUE_BASE_POINT0, aurEff->GetAmount());
+ target->CastSpell(target, 48422, args);
}
- break;
+ break;
}
}
}
@@ -1705,9 +1711,10 @@ void AuraEffect::HandleAuraModShapeshift(AuraApplication const* aurApp, uint8 mo
{
case FORM_CAT:
{
- int32 basePoints = int32(std::min(oldPower, FurorChance));
+ CastSpellExtraArgs args(this);
+ args.SpellValueOverrides.AddMod(SPELLVALUE_BASE_POINT0, std::min(oldPower, FurorChance));
target->SetPower(POWER_ENERGY, 0);
- target->CastCustomSpell(target, 17099, &basePoints, nullptr, nullptr, true, nullptr, this);
+ target->CastSpell(target, 17099, args);
break;
}
case FORM_BEAR:
@@ -1770,12 +1777,12 @@ void AuraEffect::HandleAuraModShapeshift(AuraApplication const* aurApp, uint8 mo
case FORM_DIREBEAR:
case FORM_CAT:
if (AuraEffect* dummy = target->GetAuraEffect(37315, 0))
- target->CastSpell(target, 37316, true, nullptr, dummy);
+ target->CastSpell(target, 37316, dummy);
break;
// Nordrassil Regalia - bonus
case FORM_MOONKIN:
if (AuraEffect* dummy = target->GetAuraEffect(37324, 0))
- target->CastSpell(target, 37325, true, nullptr, dummy);
+ target->CastSpell(target, 37325, dummy);
break;
case FORM_BATTLESTANCE:
case FORM_DEFENSIVESTANCE:
@@ -4304,7 +4311,7 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
case 13139: // net-o-matic
// root to self part of (root_target->charge->root_self sequence
if (caster)
- caster->CastSpell(caster, 13138, true, nullptr, this);
+ caster->CastSpell(caster, 13138, this);
break;
case 34026: // kill command
{
@@ -4312,7 +4319,7 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
if (!pet)
break;
- target->CastSpell(target, 34027, true, nullptr, this);
+ target->CastSpell(target, 34027, this);
// set 3 stacks and 3 charges (to make all auras not disappear at once)
Aura* owner_aura = target->GetAura(34027, GetCasterGUID());
@@ -4333,15 +4340,15 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
if (caster)
{
if (caster->getGender() == GENDER_FEMALE)
- caster->CastSpell(target, 37095, true, nullptr, this); // Blood Elf Disguise
+ caster->CastSpell(target, 37095, this); // Blood Elf Disguise
else
- caster->CastSpell(target, 37093, true, nullptr, this);
+ caster->CastSpell(target, 37093, this);
}
break;
}
case 55198: // Tidal Force
{
- target->CastSpell(target, 55166, true, nullptr, this);
+ target->CastSpell(target, 55166, this);
// set 3 stacks and 3 charges (to make all auras not disappear at once)
Aura* owner_aura = target->GetAura(55166, GetCasterGUID());
if (owner_aura)
@@ -4357,7 +4364,7 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
}
case 39850: // Rocket Blast
if (roll_chance_i(20)) // backfire stun
- target->CastSpell(target, 51581, true, nullptr, this);
+ target->CastSpell(target, 51581, this);
break;
case 43873: // Headless Horseman Laugh
target->PlayDistanceSound(11965);
@@ -4366,9 +4373,9 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
if (caster)
{
if (caster->getGender() == GENDER_FEMALE)
- caster->CastSpell(target, 46356, true, nullptr, this);
+ caster->CastSpell(target, 46356, this);
else
- caster->CastSpell(target, 46355, true, nullptr, this);
+ caster->CastSpell(target, 46355, this);
}
break;
case 46361: // Reinforced Net
@@ -4410,7 +4417,7 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
}
if (finalSpelId)
- caster->CastSpell(target, finalSpelId, true, nullptr, this);
+ caster->CastSpell(target, finalSpelId, this);
}
switch (m_spellInfo->SpellFamilyName)
@@ -4430,7 +4437,7 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
break;
case 36730: // Flame Strike
{
- target->CastSpell(target, 36731, true, nullptr, this);
+ target->CastSpell(target, 36731, this);
break;
}
case 44191: // Flame Strike
@@ -4439,7 +4446,7 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
{
uint32 spellId = target->GetMap()->IsHeroic() ? 46163 : 44190;
- target->CastSpell(target, spellId, true, nullptr, this);
+ target->CastSpell(target, spellId, this);
}
break;
}
@@ -4453,14 +4460,14 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
break;
}
case 42783: // Wrath of the Astromancer
- target->CastSpell(target, GetAmount(), true, nullptr, this);
+ target->CastSpell(target, GetAmount(), this);
break;
case 46308: // Burning Winds cast only at creatures at spawn
- target->CastSpell(target, 47287, true, nullptr, this);
+ target->CastSpell(target, 47287, this);
break;
case 52172: // Coyote Spirit Despawn Aura
case 60244: // Blood Parrot Despawn Aura
- target->CastSpell(nullptr, GetAmount(), true, nullptr, this);
+ target->CastSpell(nullptr, GetAmount(), this);
break;
case 58600: // Restricted Flight Area
case 58730: // Restricted Flight Area
@@ -4503,7 +4510,7 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
SpellInfo const* spell = sSpellMgr->AssertSpellInfo(spellId);
for (uint32 i = 0; i < spell->StackAmount; ++i)
- caster->CastSpell(target, spell->Id, true, nullptr, nullptr, GetCasterGUID());
+ caster->CastSpell(target, spell->Id, GetCasterGUID());
break;
}
target->RemoveAurasDueToSpell(spellId);
@@ -4517,7 +4524,7 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
{
SpellInfo const* spell = sSpellMgr->AssertSpellInfo(spellId);
for (uint32 i = 0; i < spell->StackAmount; ++i)
- caster->CastSpell(target, spell->Id, true, nullptr, nullptr, GetCasterGUID());
+ caster->CastSpell(target, spell->Id, GetCasterGUID());
break;
}
target->RemoveAurasDueToSpell(spellId);
@@ -4678,7 +4685,7 @@ void AuraEffect::HandleChannelDeathItem(AuraApplication const* aurApp, uint8 mod
// Glyph of Drain Soul - chance to create an additional Soul Shard
if (AuraEffect* aur = caster->GetAuraEffect(58070, 0))
if (roll_chance_i(aur->GetMiscValue()))
- caster->CastSpell(caster, 58068, true, nullptr, aur); // We _could_ simply do ++count here, but Blizz does it this way :)
+ caster->CastSpell(caster, 58068, aur); // We _could_ simply do ++count here, but Blizz does it this way :)
}
}
@@ -4848,11 +4855,13 @@ void AuraEffect::HandleAuraLinked(AuraApplication const* aurApp, uint8 mode, boo
if (!caster)
return;
- // If amount avalible cast with basepoints (Crypt Fever for example)
- if (GetAmount())
- caster->CastCustomSpell(target, triggeredSpellId, &m_amount, nullptr, nullptr, true, nullptr, this);
- else
- caster->CastSpell(target, triggeredSpellId, true, nullptr, this);
+
+ CastSpellExtraArgs args(this);
+
+ if (GetAmount()) // If amount avalible cast with basepoints (Crypt Fever for example)
+ args.SpellValueOverrides.AddMod(SPELLVALUE_BASE_POINT0, GetAmount());
+
+ caster->CastSpell(target, triggeredSpellId, args);
}
else
{
@@ -5006,12 +5015,12 @@ void AuraEffect::HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster)
{
if (Unit* triggerCaster = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo) ? caster : target)
{
- triggerCaster->CastSpell(target, triggeredSpellInfo, true, nullptr, this);
+ triggerCaster->CastSpell(target, triggerSpellId, this);
TC_LOG_DEBUG("spells", "AuraEffect::HandlePeriodicTriggerSpellAuraTick: Spell %u Trigger %u", GetId(), triggeredSpellInfo->Id);
}
}
else
- TC_LOG_DEBUG("spells", "AuraEffect::HandlePeriodicTriggerSpellAuraTick: Spell %u has non-existent spell %u in EffectTriggered[%d] and is therefor not triggered.", GetId(), triggerSpellId, GetEffIndex());
+ TC_LOG_WARN("spells", "AuraEffect::HandlePeriodicTriggerSpellAuraTick: Spell %u has non-existent spell %u in EffectTriggered[%d] and is therefore not triggered.", GetId(), triggerSpellId, GetEffIndex());
}
void AuraEffect::HandlePeriodicTriggerSpellWithValueAuraTick(Unit* target, Unit* caster) const
@@ -5021,13 +5030,15 @@ void AuraEffect::HandlePeriodicTriggerSpellWithValueAuraTick(Unit* target, Unit*
{
if (Unit* triggerCaster = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo) ? caster : target)
{
- int32 basepoints = GetAmount();
- triggerCaster->CastCustomSpell(target, triggerSpellId, &basepoints, &basepoints, &basepoints, true, nullptr, this);
+ CastSpellExtraArgs args(this);
+ for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ args.SpellValueOverrides.AddMod(SpellValueMod(SPELLVALUE_BASE_POINT0 + i), GetAmount());
+ triggerCaster->CastSpell(target, triggerSpellId, args);
TC_LOG_DEBUG("spells", "AuraEffect::HandlePeriodicTriggerSpellWithValueAuraTick: Spell %u Trigger %u", GetId(), triggeredSpellInfo->Id);
}
}
else
- TC_LOG_DEBUG("spells","AuraEffect::HandlePeriodicTriggerSpellWithValueAuraTick: Spell %u has non-existent spell %u in EffectTriggered[%d] and is therefor not triggered.", GetId(), triggerSpellId, GetEffIndex());
+ TC_LOG_WARN("spells","AuraEffect::HandlePeriodicTriggerSpellWithValueAuraTick: Spell %u has non-existent spell %u in EffectTriggered[%d] and is therefore not triggered.", GetId(), triggerSpellId, GetEffIndex());
}
void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
@@ -5095,11 +5106,11 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
{
if (roll_chance_i(20))
{
- caster->CastSpell(caster, 43836, true, nullptr, this);
+ caster->CastSpell(caster, 43836, this);
// Glyph of Drain Soul - chance to create an additional Soul Shard
if (AuraEffect* aur = caster->GetAuraEffect(58070, 0))
if (roll_chance_i(aur->GetMiscValue()))
- caster->CastSpell(caster, 58068, true, nullptr, aur);
+ caster->CastSpell(caster, 58068, aur);
}
}
}
@@ -5501,7 +5512,10 @@ void AuraEffect::HandlePeriodicManaLeechAuraTick(Unit* target, Unit* caster) con
if (manaFeedVal > 0)
{
int32 feedAmount = CalculatePct(gainedAmount, manaFeedVal);
- caster->CastCustomSpell(caster, 32554, &feedAmount, nullptr, nullptr, true, nullptr, this);
+
+ CastSpellExtraArgs args(this);
+ args.SpellValueOverrides.AddMod(SPELLVALUE_BASE_POINT0, feedAmount);
+ caster->CastSpell(caster, 32554, args);
}
}
}
@@ -5655,7 +5669,7 @@ void AuraEffect::HandleProcTriggerSpellAuraProc(AuraApplication* aurApp, ProcEve
if (SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(triggerSpellId))
{
TC_LOG_DEBUG("spells", "AuraEffect::HandleProcTriggerSpellAuraProc: Triggering spell %u from aura %u proc", triggeredSpellInfo->Id, GetId());
- triggerCaster->CastSpell(triggerTarget, triggeredSpellInfo, true, nullptr, this);
+ triggerCaster->CastSpell(triggerTarget, triggeredSpellInfo->Id, this);
}
else
TC_LOG_ERROR("spells","AuraEffect::HandleProcTriggerSpellAuraProc: Could not trigger spell %u from aura %u proc, because the spell does not have an entry in Spell.dbc.", triggerSpellId, GetId());
@@ -5669,9 +5683,10 @@ void AuraEffect::HandleProcTriggerSpellWithValueAuraProc(AuraApplication* aurApp
uint32 triggerSpellId = GetSpellInfo()->Effects[m_effIndex].TriggerSpell;
if (SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(triggerSpellId))
{
- int32 basepoints0 = GetAmount();
- TC_LOG_DEBUG("spells", "AuraEffect::HandleProcTriggerSpellWithValueAuraProc: Triggering spell %u with value %d from aura %u proc", triggeredSpellInfo->Id, basepoints0, GetId());
- triggerCaster->CastCustomSpell(triggerTarget, triggerSpellId, &basepoints0, nullptr, nullptr, true, nullptr, this);
+ CastSpellExtraArgs args(this);
+ args.SpellValueOverrides.AddMod(SPELLVALUE_BASE_POINT0, GetAmount());
+ triggerCaster->CastSpell(triggerTarget, triggerSpellId, args);
+ TC_LOG_DEBUG("spells", "AuraEffect::HandleProcTriggerSpellWithValueAuraProc: Triggering spell %u with value %d from aura %u proc", triggeredSpellInfo->Id, GetAmount(), GetId());
}
else
TC_LOG_ERROR("spells","AuraEffect::HandleProcTriggerSpellWithValueAuraProc: Could not trigger spell %u from aura %u proc, because the spell does not have an entry in Spell.dbc.", triggerSpellId, GetId());
@@ -5737,7 +5752,7 @@ void AuraEffect::HandleRaidProcFromChargeAuraProc(AuraApplication* aurApp, ProcE
if (Unit* triggerTarget = target->GetNextRandomRaidMemberOrPet(radius))
{
- target->CastSpell(triggerTarget, GetSpellInfo(), true, nullptr, this, GetCasterGUID());
+ target->CastSpell(triggerTarget, GetId(), { this, GetCasterGUID() });
if (Aura* aura = triggerTarget->GetAura(GetId(), GetCasterGUID()))
aura->SetCharges(jumps);
}
@@ -5745,7 +5760,7 @@ void AuraEffect::HandleRaidProcFromChargeAuraProc(AuraApplication* aurApp, ProcE
}
TC_LOG_DEBUG("spells", "AuraEffect::HandleRaidProcFromChargeAuraProc: Triggering spell %u from aura %u proc", triggerSpellId, GetId());
- target->CastSpell(target, triggerSpellId, true, nullptr, this, GetCasterGUID());
+ target->CastSpell(target, triggerSpellId, { this, GetCasterGUID() });
}
@@ -5761,14 +5776,16 @@ void AuraEffect::HandleRaidProcFromChargeWithValueAuraProc(AuraApplication* aurA
}
uint32 triggerSpellId = 33110;
- int32 value = GetAmount();
-
int32 jumps = GetBase()->GetCharges();
// current aura expire on proc finish
GetBase()->SetCharges(0);
GetBase()->SetUsingCharges(true);
+ CastSpellExtraArgs args(this);
+ args.OriginalCaster = GetCasterGUID();
+ args.SpellValueOverrides.AddMod(SPELLVALUE_BASE_POINT0, GetAmount());
+
// next target selection
if (jumps > 0)
{
@@ -5778,7 +5795,7 @@ void AuraEffect::HandleRaidProcFromChargeWithValueAuraProc(AuraApplication* aurA
if (Unit* triggerTarget = target->GetNextRandomRaidMemberOrPet(radius))
{
- target->CastCustomSpell(triggerTarget, GetId(), &value, nullptr, nullptr, true, nullptr, this, GetCasterGUID());
+ target->CastSpell(triggerTarget, GetId(), args);
if (Aura* aura = triggerTarget->GetAura(GetId(), GetCasterGUID()))
aura->SetCharges(jumps);
}
@@ -5786,7 +5803,7 @@ void AuraEffect::HandleRaidProcFromChargeWithValueAuraProc(AuraApplication* aurA
}
TC_LOG_DEBUG("spells", "AuraEffect::HandleRaidProcFromChargeWithValueAuraProc: Triggering spell %u from aura %u proc", triggerSpellId, GetId());
- target->CastCustomSpell(target, triggerSpellId, &value, nullptr, nullptr, true, nullptr, this, GetCasterGUID());
+ target->CastSpell(target, triggerSpellId, args);
}
template TC_GAME_API void AuraEffect::GetTargetList(std::list<Unit*>&) const;
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index a6213736961..e6e81038d75 100644
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -1183,7 +1183,7 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
if (*itr < 0)
target->RemoveAurasDueToSpell(-(*itr));
else if (removeMode != AURA_REMOVE_BY_DEATH)
- target->CastSpell(target, *itr, true, nullptr, nullptr, GetCasterGUID());
+ target->CastSpell(target, *itr, GetCasterGUID());
}
}
if (std::vector<int32> const* spellTriggered = sSpellMgr->GetSpellLinked(GetId() + SPELL_LINK_AURA))
@@ -1245,8 +1245,9 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
// Druid T8 Restoration 4P Bonus
if (caster->HasAura(64760))
{
- int32 heal = GetEffect(EFFECT_0)->GetAmount();
- caster->CastCustomSpell(target, 64801, &heal, nullptr, nullptr, true, nullptr, GetEffect(EFFECT_0));
+ CastSpellExtraArgs args(GetEffect(EFFECT_0));
+ args.SpellValueOverrides.AddMod(SPELLVALUE_BASE_POINT0, GetEffect(EFFECT_0)->GetAmount());
+ caster->CastSpell(target, 64801, args);
}
}
break;
@@ -1281,9 +1282,13 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
switch (GetId())
{
case 44544: // Fingers of Frost
+ {
// Refresh or add visual aura
- target->CastCustomSpell(74396, SPELLVALUE_AURA_STACK, sSpellMgr->AssertSpellInfo(74396)->StackAmount, (Unit*)nullptr, true);
+ CastSpellExtraArgs args(TRIGGERED_FULL_MASK);
+ args.SpellValueOverrides.AddMod(SPELLVALUE_AURA_STACK, sSpellMgr->AssertSpellInfo(74396)->StackAmount);
+ target->CastSpell(nullptr, 74396, args);
break;
+ }
default:
break;
}
@@ -1308,10 +1313,12 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DOT);
+ CastSpellExtraArgs args(devouringPlague), args2(devouringPlague);
int32 basepoints0 = CalculatePct(devouringPlague->GetTotalTicks() * static_cast<int32>(damage), aurEff->GetAmount());
- int32 heal = CalculatePct(basepoints0, 15);
- caster->CastCustomSpell(63675, SPELLVALUE_BASE_POINT0, basepoints0, target, true, nullptr, devouringPlague);
- caster->CastCustomSpell(75999, SPELLVALUE_BASE_POINT0, heal, (Unit*)nullptr, true, nullptr, devouringPlague);
+ args.SpellValueOverrides.AddMod(SPELLVALUE_BASE_POINT0, basepoints0);
+ args2.SpellValueOverrides.AddMod(SPELLVALUE_BASE_POINT0, CalculatePct(basepoints0, 15));
+ caster->CastSpell(target, 63675, args);
+ caster->CastSpell(nullptr, 75999, args2);
}
}
// Power Word: Shield
@@ -1322,7 +1329,9 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
{
// instantly heal m_amount% of the absorb-value
int32 heal = glyph->GetAmount() * GetEffect(0)->GetAmount()/100;
- caster->CastCustomSpell(GetUnitOwner(), 56160, &heal, nullptr, nullptr, true, nullptr, GetEffect(0));
+ CastSpellExtraArgs args(GetEffect(0));
+ args.SpellValueOverrides.AddMod(SPELLVALUE_BASE_POINT0, heal);
+ caster->CastSpell(GetUnitOwner(), 56160, args);
}
}
break;
@@ -1372,7 +1381,7 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
default:
TC_LOG_ERROR("spells", "Aura::HandleAuraSpecificMods: Unknown rank of Crypt Fever/Ebon Plague (%d) found", aurEff->GetId());
}
- caster->CastSpell(target, spellId, true, 0, GetEffect(0));
+ caster->CastSpell(target, spellId, GetEffect(0));
}
}
break;
@@ -1401,7 +1410,7 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
case 66: // Invisibility
if (removeMode != AURA_REMOVE_BY_EXPIRE)
break;
- target->CastSpell(target, 32612, true, nullptr, GetEffect(1));
+ target->CastSpell(target, 32612, GetEffect(1));
target->CombatStop();
break;
default:
@@ -1462,7 +1471,9 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
if (AuraEffect const* aurEff = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, 178, 1))
{
int32 basepoints0 = aurEff->GetAmount() * caster->GetCreateMana() / 100;
- caster->CastCustomSpell(caster, 64103, &basepoints0, nullptr, nullptr, true, nullptr, GetEffect(0));
+ CastSpellExtraArgs args(GetEffect(0));
+ args.SpellValueOverrides.AddMod(SPELLVALUE_BASE_POINT0, basepoints0);
+ caster->CastSpell(caster, 64103, args);
}
}
// Power word: shield
@@ -1494,8 +1505,9 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
else if (aurEff->GetId() == 47537)
multiplier += 0.5f;
- int32 basepoints0 = int32(CalculatePct(caster->GetMaxPower(POWER_MANA), multiplier));
- caster->CastCustomSpell(caster, 47755, &basepoints0, nullptr, nullptr, true);
+ CastSpellExtraArgs args(TRIGGERED_FULL_MASK);
+ args.SpellValueOverrides.AddBP0(CalculatePct(caster->GetMaxPower(POWER_MANA), multiplier));
+ caster->CastSpell(caster, 47755, args);
}
// effect on aura target
if (AuraEffect const* aurEff = aura->GetEffect(1))
@@ -1508,8 +1520,9 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
{
case POWER_MANA:
{
- int32 basepoints0 = int32(CalculatePct(target->GetMaxPower(POWER_MANA), 2));
- caster->CastCustomSpell(target, 63654, &basepoints0, nullptr, nullptr, true);
+ CastSpellExtraArgs args(TRIGGERED_FULL_MASK);
+ args.SpellValueOverrides.AddBP0(CalculatePct(target->GetMaxPower(POWER_MANA), 2));
+ caster->CastSpell(target, 63654, args);
break;
}
case POWER_RAGE: triggeredSpellId = 63653; break;
@@ -1601,8 +1614,9 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
// Remove counter aura
target->RemoveAurasDueToSpell(31666);
- int32 basepoints0 = aurEff->GetAmount();
- target->CastCustomSpell(target, 31665, &basepoints0, nullptr, nullptr, true);
+ CastSpellExtraArgs args(TRIGGERED_FULL_MASK);
+ args.SpellValueOverrides.AddBP0(aurEff->GetAmount());
+ target->CastSpell(target, 31665, args);
}
}
// Overkill
@@ -1632,7 +1646,7 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
if (owner->HasAura(34692))
{
if (apply)
- owner->CastSpell(owner, 34471, true, 0, GetEffect(0));
+ owner->CastSpell(owner, 34471, GetEffect(0));
else
owner->RemoveAurasDueToSpell(34471);
}
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 17a2bb9ad16..d103a281c46 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -2740,7 +2740,7 @@ void Spell::DoTriggersOnSpellHit(Unit* unit, uint8 effMask)
{
if (CanExecuteTriggersOnHit(effMask, i->triggeredByAura) && roll_chance_i(i->chance))
{
- m_caster->CastSpell(unit, i->triggeredSpell, true);
+ m_caster->CastSpell(unit, i->triggeredSpell->Id, true);
TC_LOG_DEBUG("spells", "Spell %d triggered spell %d by SPELL_AURA_ADD_TARGET_TRIGGER aura", m_spellInfo->Id, i->triggeredSpell->Id);
// SPELL_AURA_ADD_TARGET_TRIGGER auras shouldn't trigger auras without duration
@@ -2771,7 +2771,7 @@ void Spell::DoTriggersOnSpellHit(Unit* unit, uint8 effMask)
if (*i < 0)
unit->RemoveAurasDueToSpell(-(*i));
else
- unit->CastSpell(unit, *i, true, nullptr, nullptr, m_caster->GetGUID());
+ unit->CastSpell(unit, *i, m_caster->GetGUID());
}
}
}
@@ -2882,7 +2882,7 @@ bool Spell::UpdateChanneledTargetList()
return channelTargetEffectMask == 0;
}
-void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggeredByAura)
+void Spell::prepare(SpellCastTargets const& targets, AuraEffect const* triggeredByAura)
{
if (m_CastItem)
{
@@ -2895,7 +2895,7 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered
m_castItemEntry = 0;
}
- InitExplicitTargets(*targets);
+ InitExplicitTargets(targets);
// Fill aura scaling information
if (m_caster->IsControlledByPlayer() && !m_spellInfo->IsPassive() && m_spellInfo->SpellLevel && !m_spellInfo->IsChanneled() && !(_triggeredCastFlags & TRIGGERED_IGNORE_AURA_SCALING))
@@ -5495,7 +5495,7 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint
{
if (strict) //starting cast, trigger pet stun (cast by pet so it doesn't attack player)
if (Pet* pet = m_caster->ToPlayer()->GetPet())
- pet->CastSpell(pet, 32752, true, nullptr, nullptr, pet->GetGUID());
+ pet->CastSpell(pet, 32752, pet->GetGUID());
}
else if (!m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET))
return SPELL_FAILED_ALREADY_HAVE_SUMMON;
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index 25ba9cd23a1..adf2619781a 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -405,7 +405,7 @@ class TC_GAME_API Spell
GameObject* SearchSpellFocus();
- void prepare(SpellCastTargets const* targets, AuraEffect const* triggeredByAura = nullptr);
+ void prepare(SpellCastTargets const& targets, AuraEffect const* triggeredByAura = nullptr);
void cancel();
void update(uint32 difftime);
void cast(bool skipCheck = false);
diff --git a/src/server/game/Spells/SpellDefines.h b/src/server/game/Spells/SpellDefines.h
new file mode 100644
index 00000000000..aa5f893e777
--- /dev/null
+++ b/src/server/game/Spells/SpellDefines.h
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2008-2018 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef TRINITY_SPELLDEFINES_H
+#define TRINITY_SPELLDEFINES_H
+
+#include "Define.h"
+#include "ObjectGuid.h"
+#include <vector>
+
+class Item;
+class AuraEffect;
+
+enum SpellInterruptFlags
+{
+ SPELL_INTERRUPT_FLAG_MOVEMENT = 0x01, // why need this for instant?
+ SPELL_INTERRUPT_FLAG_PUSH_BACK = 0x02, // push back
+ SPELL_INTERRUPT_FLAG_UNK3 = 0x04, // any info?
+ SPELL_INTERRUPT_FLAG_INTERRUPT = 0x08, // interrupt
+ SPELL_INTERRUPT_FLAG_ABORT_ON_DMG = 0x10 // _complete_ interrupt on direct damage
+ //SPELL_INTERRUPT_UNK = 0x20 // unk, 564 of 727 spells having this spell start with "Glyph"
+};
+
+// See SpellAuraInterruptFlags for other values definitions
+enum SpellChannelInterruptFlags
+{
+ CHANNEL_INTERRUPT_FLAG_INTERRUPT = 0x0008, // interrupt
+ CHANNEL_FLAG_DELAY = 0x4000
+};
+
+enum SpellAuraInterruptFlags
+{
+ AURA_INTERRUPT_FLAG_HITBYSPELL = 0x00000001, // 0 removed when getting hit by a negative spell?
+ AURA_INTERRUPT_FLAG_TAKE_DAMAGE = 0x00000002, // 1 removed by any damage
+ AURA_INTERRUPT_FLAG_CAST = 0x00000004, // 2 cast any spells
+ AURA_INTERRUPT_FLAG_MOVE = 0x00000008, // 3 removed by any movement
+ AURA_INTERRUPT_FLAG_TURNING = 0x00000010, // 4 removed by any turning
+ AURA_INTERRUPT_FLAG_JUMP = 0x00000020, // 5 removed by entering combat
+ AURA_INTERRUPT_FLAG_NOT_MOUNTED = 0x00000040, // 6 removed by dismounting
+ AURA_INTERRUPT_FLAG_NOT_ABOVEWATER = 0x00000080, // 7 removed by entering water
+ AURA_INTERRUPT_FLAG_NOT_UNDERWATER = 0x00000100, // 8 removed by leaving water
+ AURA_INTERRUPT_FLAG_NOT_SHEATHED = 0x00000200, // 9 removed by unsheathing
+ AURA_INTERRUPT_FLAG_TALK = 0x00000400, // 10 talk to npc / loot? action on creature
+ AURA_INTERRUPT_FLAG_USE = 0x00000800, // 11 mine/use/open action on gameobject
+ AURA_INTERRUPT_FLAG_MELEE_ATTACK = 0x00001000, // 12 removed by attacking
+ AURA_INTERRUPT_FLAG_SPELL_ATTACK = 0x00002000, // 13 ???
+ AURA_INTERRUPT_FLAG_UNK14 = 0x00004000, // 14
+ AURA_INTERRUPT_FLAG_TRANSFORM = 0x00008000, // 15 removed by transform?
+ AURA_INTERRUPT_FLAG_UNK16 = 0x00010000, // 16
+ AURA_INTERRUPT_FLAG_MOUNT = 0x00020000, // 17 misdirect, aspect, swim speed
+ AURA_INTERRUPT_FLAG_NOT_SEATED = 0x00040000, // 18 removed by standing up (used by food and drink mostly and sleep/Fake Death like)
+ AURA_INTERRUPT_FLAG_CHANGE_MAP = 0x00080000, // 19 leaving map/getting teleported
+ AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION = 0x00100000, // 20 removed by auras that make you invulnerable, or make other to lose selection on you
+ AURA_INTERRUPT_FLAG_UNK21 = 0x00200000, // 21
+ AURA_INTERRUPT_FLAG_TELEPORTED = 0x00400000, // 22
+ AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT = 0x00800000, // 23 removed by entering pvp combat
+ AURA_INTERRUPT_FLAG_DIRECT_DAMAGE = 0x01000000, // 24 removed by any direct damage
+ AURA_INTERRUPT_FLAG_LANDING = 0x02000000, // 25 removed by hitting the ground
+ AURA_INTERRUPT_FLAG_LEAVE_COMBAT = 0x80000000, // 31 removed by leaving combat
+
+ AURA_INTERRUPT_FLAG_NOT_VICTIM = (AURA_INTERRUPT_FLAG_HITBYSPELL | AURA_INTERRUPT_FLAG_TAKE_DAMAGE | AURA_INTERRUPT_FLAG_DIRECT_DAMAGE)
+};
+
+enum SpellModOp : uint8
+{
+ SPELLMOD_DAMAGE = 0,
+ SPELLMOD_DURATION = 1,
+ SPELLMOD_THREAT = 2,
+ SPELLMOD_EFFECT1 = 3,
+ SPELLMOD_CHARGES = 4,
+ SPELLMOD_RANGE = 5,
+ SPELLMOD_RADIUS = 6,
+ SPELLMOD_CRITICAL_CHANCE = 7,
+ SPELLMOD_ALL_EFFECTS = 8,
+ SPELLMOD_NOT_LOSE_CASTING_TIME = 9,
+ SPELLMOD_CASTING_TIME = 10,
+ SPELLMOD_COOLDOWN = 11,
+ SPELLMOD_EFFECT2 = 12,
+ SPELLMOD_IGNORE_ARMOR = 13,
+ SPELLMOD_COST = 14,
+ SPELLMOD_CRIT_DAMAGE_BONUS = 15,
+ SPELLMOD_RESIST_MISS_CHANCE = 16,
+ SPELLMOD_JUMP_TARGETS = 17,
+ SPELLMOD_CHANCE_OF_SUCCESS = 18,
+ SPELLMOD_ACTIVATION_TIME = 19,
+ SPELLMOD_DAMAGE_MULTIPLIER = 20,
+ SPELLMOD_GLOBAL_COOLDOWN = 21,
+ SPELLMOD_DOT = 22,
+ SPELLMOD_EFFECT3 = 23,
+ SPELLMOD_BONUS_MULTIPLIER = 24,
+ // spellmod 25
+ SPELLMOD_PROC_PER_MINUTE = 26,
+ SPELLMOD_VALUE_MULTIPLIER = 27,
+ SPELLMOD_RESIST_DISPEL_CHANCE = 28,
+ SPELLMOD_CRIT_DAMAGE_BONUS_2 = 29, //one not used spell
+ SPELLMOD_SPELL_COST_REFUND_ON_FAIL = 30,
+
+ MAX_SPELLMOD
+};
+
+enum SpellValueMod : uint8
+{
+ SPELLVALUE_BASE_POINT0,
+ SPELLVALUE_BASE_POINT1,
+ SPELLVALUE_BASE_POINT2,
+ SPELLVALUE_RADIUS_MOD,
+ SPELLVALUE_MAX_TARGETS,
+ SPELLVALUE_AURA_STACK
+};
+
+enum SpellFacingFlags
+{
+ SPELL_FACING_FLAG_INFRONT = 0x0001
+};
+
+enum TriggerCastFlags : uint32
+{
+ TRIGGERED_NONE = 0x00000000, //! Not triggered
+ TRIGGERED_IGNORE_GCD = 0x00000001, //! Will ignore GCD
+ TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD = 0x00000002, //! Will ignore Spell and Category cooldowns
+ TRIGGERED_IGNORE_POWER_AND_REAGENT_COST = 0x00000004, //! Will ignore power and reagent cost
+ TRIGGERED_IGNORE_CAST_ITEM = 0x00000008, //! Will not take away cast item or update related achievement criteria
+ TRIGGERED_IGNORE_AURA_SCALING = 0x00000010, //! Will ignore aura scaling
+ TRIGGERED_IGNORE_CAST_IN_PROGRESS = 0x00000020, //! Will not check if a current cast is in progress
+ TRIGGERED_IGNORE_COMBO_POINTS = 0x00000040, //! Will ignore combo point requirement
+ TRIGGERED_CAST_DIRECTLY = 0x00000080, //! In Spell::prepare, will be cast directly without setting containers for executed spell
+ TRIGGERED_IGNORE_AURA_INTERRUPT_FLAGS = 0x00000100, //! Will ignore interruptible aura's at cast
+ TRIGGERED_IGNORE_SET_FACING = 0x00000200, //! Will not adjust facing to target (if any)
+ TRIGGERED_IGNORE_SHAPESHIFT = 0x00000400, //! Will ignore shapeshift checks
+ TRIGGERED_IGNORE_CASTER_AURASTATE = 0x00000800, //! Will ignore caster aura states including combat requirements and death state
+ TRIGGERED_DISALLOW_PROC_EVENTS = 0x00001000, //! Disallows proc events from triggered spell (default)
+ TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE = 0x00002000, //! Will ignore mounted/on vehicle restrictions
+ // reuse = 0x00004000,
+ // reuse = 0x00008000,
+ TRIGGERED_IGNORE_CASTER_AURAS = 0x00010000, //! Will ignore caster aura restrictions or requirements
+ TRIGGERED_DONT_RESET_PERIODIC_TIMER = 0x00020000, //! Will allow periodic aura timers to keep ticking (instead of resetting)
+ TRIGGERED_DONT_REPORT_CAST_ERROR = 0x00040000, //! Will return SPELL_FAILED_DONT_REPORT in CheckCast functions
+ TRIGGERED_FULL_MASK = 0x0007FFFF, //! Used when doing CastSpell with triggered == true
+
+ // debug flags (used with .cast triggered commands)
+ TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT = 0x00080000, //! Will ignore equipped item requirements
+ TRIGGERED_FULL_DEBUG_MASK = 0xFFFFFFFF
+};
+
+struct TC_GAME_API CastSpellExtraArgs
+{
+ CastSpellExtraArgs() {}
+ CastSpellExtraArgs(bool triggered) : TriggerFlags(triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE) {}
+ CastSpellExtraArgs(TriggerCastFlags trigger) : TriggerFlags(trigger) {}
+ CastSpellExtraArgs(Item* item) : TriggerFlags(TRIGGERED_FULL_MASK), CastItem(item) {}
+ CastSpellExtraArgs(AuraEffect const* eff) : TriggerFlags(TRIGGERED_FULL_MASK), TriggeringAura(eff) {}
+ CastSpellExtraArgs(ObjectGuid const& origCaster) : TriggerFlags(TRIGGERED_FULL_MASK), OriginalCaster(origCaster) {}
+ CastSpellExtraArgs(AuraEffect const* eff, ObjectGuid const& origCaster) : TriggerFlags(TRIGGERED_FULL_MASK), TriggeringAura(eff), OriginalCaster(origCaster) {}
+ CastSpellExtraArgs(SpellValueMod mod, int32 val) { SpellValueOverrides.AddMod(mod, val); }
+
+ CastSpellExtraArgs& SetTriggerFlags(TriggerCastFlags flag) { TriggerFlags = flag; return *this; }
+ CastSpellExtraArgs& SetCastItem(Item* item) { CastItem = item; return *this; }
+ CastSpellExtraArgs& SetTriggeringAura(AuraEffect const* triggeringAura) { TriggeringAura = triggeringAura; return *this; }
+ CastSpellExtraArgs& SetOriginalCaster(ObjectGuid const& guid) { OriginalCaster = guid; return *this; }
+ CastSpellExtraArgs& AddSpellMod(SpellValueMod mod, int32 val) { SpellValueOverrides.AddMod(mod, val); return *this; }
+ CastSpellExtraArgs& AddSpellBP0(int32 val) { SpellValueOverrides.AddBP0(val); return *this; }
+
+ TriggerCastFlags TriggerFlags = TRIGGERED_NONE;
+ Item* CastItem = nullptr;
+ AuraEffect const* TriggeringAura = nullptr;
+ ObjectGuid OriginalCaster = ObjectGuid::Empty;
+ struct
+ {
+ public:
+ void AddMod(SpellValueMod mod, int32 val) { data.push_back({ mod, val }); }
+ void AddBP0(int32 bp0) { AddMod(SPELLVALUE_BASE_POINT0, bp0); } // because i don't want to type SPELLVALUE_BASE_POINT0 300 times
+
+ private:
+ auto begin() const { return data.cbegin(); }
+ auto end() const { return data.cend(); }
+
+ std::vector<std::pair<SpellValueMod, int32>> data;
+
+ friend class Unit;
+ } SpellValueOverrides;
+};
+
+#endif
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index f726fd3590b..1077a07e106 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -466,7 +466,9 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex)
if (AuraEffect* aurEff = owner->GetAuraEffect(SPELL_AURA_ADD_FLAT_MODIFIER, SPELLFAMILY_WARLOCK, 214, 0))
{
int32 bp0 = aurEff->GetId() == 54037 ? 4 : 8;
- m_caster->CastCustomSpell(m_caster, 54425, &bp0, nullptr, nullptr, true);
+ CastSpellExtraArgs args(TRIGGERED_FULL_MASK);
+ args.SpellValueOverrides.AddMod(SPELLVALUE_BASE_POINT0, bp0);
+ m_caster->CastSpell(m_caster, 54425, args);
}
}
}
@@ -487,7 +489,7 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex)
int chance = (*i)->GetSpellInfo()->Effects[EFFECT_1].CalcValue(m_caster);
if (roll_chance_i(chance))
// Mind Trauma
- m_caster->CastSpell(unitTarget, 48301, true, nullptr);
+ m_caster->CastSpell(unitTarget, 48301, true);
break;
}
}
@@ -855,17 +857,14 @@ void Spell::EffectTriggerSpell(SpellEffIndex effIndex)
targets.SetUnitTarget(m_caster);
}
- CustomSpellValues values;
+ CastSpellExtraArgs args(m_originalCasterGUID);
// set basepoints for trigger with value effect
if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE)
- {
- values.AddSpellMod(SPELLVALUE_BASE_POINT0, damage);
- values.AddSpellMod(SPELLVALUE_BASE_POINT1, damage);
- values.AddSpellMod(SPELLVALUE_BASE_POINT2, damage);
- }
+ for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ args.SpellValueOverrides.AddMod(SpellValueMod(SPELLVALUE_BASE_POINT0 + i), damage);
// original caster guid only for GO cast
- m_caster->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK, nullptr, nullptr, m_originalCasterGUID);
+ m_caster->CastSpell(targets, spellInfo->Id, args);
}
void Spell::EffectTriggerMissileSpell(SpellEffIndex effIndex)
@@ -902,18 +901,14 @@ void Spell::EffectTriggerMissileSpell(SpellEffIndex effIndex)
targets.SetUnitTarget(m_caster);
}
- CustomSpellValues values;
+ CastSpellExtraArgs args(m_originalCasterGUID);
// set basepoints for trigger with value effect
if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE)
- {
- // maybe need to set value only when basepoints == 0?
- values.AddSpellMod(SPELLVALUE_BASE_POINT0, damage);
- values.AddSpellMod(SPELLVALUE_BASE_POINT1, damage);
- values.AddSpellMod(SPELLVALUE_BASE_POINT2, damage);
- }
+ for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ args.SpellValueOverrides.AddMod(SpellValueMod(SPELLVALUE_BASE_POINT0 + i), damage);
// original caster guid only for GO cast
- m_caster->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK, nullptr, nullptr, m_originalCasterGUID);
+ m_caster->CastSpell(targets, spellInfo->Id, args);
}
void Spell::EffectForceCast(SpellEffIndex effIndex)
@@ -945,32 +940,28 @@ void Spell::EffectForceCast(SpellEffIndex effIndex)
break;
case 52463: // Hide In Mine Car
case 52349: // Overtake
- unitTarget->CastCustomSpell(unitTarget, spellInfo->Id, &damage, nullptr, nullptr, true, nullptr, nullptr, m_originalCasterGUID);
+ {
+ CastSpellExtraArgs args(m_originalCasterGUID);
+ args.SpellValueOverrides.AddMod(SPELLVALUE_BASE_POINT0, damage);
+ unitTarget->CastSpell(unitTarget, spellInfo->Id, args);
return;
+ }
}
}
switch (spellInfo->Id)
{
case 72298: // Malleable Goo Summon
- unitTarget->CastSpell(unitTarget, spellInfo->Id, true, nullptr, nullptr, m_originalCasterGUID);
+ unitTarget->CastSpell(unitTarget, spellInfo->Id, m_originalCasterGUID);
return;
}
- CustomSpellValues values;
- // set basepoints for trigger with value effect
+ CastSpellExtraArgs args(TRIGGERED_FULL_MASK);
if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_FORCE_CAST_WITH_VALUE)
- {
- // maybe need to set value only when basepoints == 0?
- values.AddSpellMod(SPELLVALUE_BASE_POINT0, damage);
- values.AddSpellMod(SPELLVALUE_BASE_POINT1, damage);
- values.AddSpellMod(SPELLVALUE_BASE_POINT2, damage);
- }
-
- SpellCastTargets targets;
- targets.SetUnitTarget(m_caster);
+ for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ args.SpellValueOverrides.AddMod(SpellValueMod(SPELLVALUE_BASE_POINT0 + i), damage);
- unitTarget->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK);
+ unitTarget->CastSpell(m_caster, spellInfo->Id, args);
}
void Spell::EffectTriggerRitualOfSummoning(SpellEffIndex effIndex)
@@ -989,7 +980,7 @@ void Spell::EffectTriggerRitualOfSummoning(SpellEffIndex effIndex)
finish();
- m_caster->CastSpell(nullptr, spellInfo, false);
+ m_caster->CastSpell(nullptr, spellInfo->Id, false);
}
void Spell::EffectJump(SpellEffIndex effIndex)
@@ -2292,11 +2283,13 @@ void Spell::EffectSummonType(SpellEffIndex effIndex)
spellId = spellInfo->Id;
}
+ CastSpellExtraArgs args(TRIGGERED_FULL_MASK);
+
// if we have small value, it indicates seat position
if (basePoints > 0 && basePoints < MAX_VEHICLE_SEATS)
- m_originalCaster->CastCustomSpell(spellId, SPELLVALUE_BASE_POINT0, basePoints, summon, true);
- else
- m_originalCaster->CastSpell(summon, spellId, true);
+ args.SpellValueOverrides.AddMod(SPELLVALUE_BASE_POINT0, basePoints);
+
+ m_originalCaster->CastSpell(summon, spellId, args);
uint32 faction = properties->Faction;
if (!faction)
@@ -2430,12 +2423,13 @@ void Spell::EffectDispel(SpellEffIndex effIndex)
// Devour Magic
if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->GetCategory() == SPELLCATEGORY_DEVOUR_MAGIC)
{
- int32 heal_amount = m_spellInfo->Effects[EFFECT_1].CalcValue();
- m_caster->CastCustomSpell(m_caster, 19658, &heal_amount, nullptr, nullptr, true);
+ CastSpellExtraArgs args(TRIGGERED_FULL_MASK);
+ args.SpellValueOverrides.AddMod(SPELLVALUE_BASE_POINT0, m_spellInfo->Effects[EFFECT_1].CalcValue());
+ m_caster->CastSpell(m_caster, 19658, args);
// Glyph of Felhunter
if (Unit* owner = m_caster->GetOwner())
if (owner->GetAura(56249))
- owner->CastCustomSpell(owner, 19658, &heal_amount, nullptr, nullptr, true);
+ owner->CastSpell(owner, 19658, args);
}
}
@@ -2796,7 +2790,7 @@ void Spell::EffectEnchantItemTmp(SpellEffIndex effIndex)
Spell* spell = new Spell(m_caster, spellInfo, TRIGGERED_FULL_MASK);
SpellCastTargets targets;
targets.SetItemTarget(item);
- spell->prepare(&targets);
+ spell->prepare(targets);
}
}
}
@@ -3183,7 +3177,7 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
// Skyshatter Harness item set bonus
// Stormstrike
if (AuraEffect* aurEff = m_caster->IsScriptOverriden(m_spellInfo, 5634))
- m_caster->CastSpell(m_caster, 38430, true, nullptr, aurEff);
+ m_caster->CastSpell(m_caster, 38430, aurEff);
break;
}
case SPELLFAMILY_DRUID:
@@ -3532,7 +3526,7 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
uint32 spell_id = roll_chance_i(20) ? 8854 : 8855;
- m_caster->CastSpell(m_caster, spell_id, true, nullptr);
+ m_caster->CastSpell(m_caster, spell_id, true);
return;
}
// Brittle Armor - need remove one 24575 Brittle Armor aura
@@ -3737,7 +3731,7 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
for (uint8 i = 0; i < 15; ++i)
{
m_caster->GetRandomPoint(*destTarget, radius, x, y, z);
- m_caster->CastSpell(x, y, z, 54522, true);
+ m_caster->CastSpell({x, y, z}, 54522, true);
}
break;
}
@@ -3841,7 +3835,7 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
// proc a spellcast
if (Aura* chargesAura = m_caster->GetAura(59907))
{
- m_caster->CastSpell(unitTarget, spell_heal, true, nullptr, nullptr, m_caster->ToTempSummon()->GetSummonerGUID());
+ m_caster->CastSpell(unitTarget, spell_heal, m_caster->ToTempSummon()->GetSummonerGUID());
if (chargesAura->ModCharges(-1))
m_caster->ToTempSummon()->UnSummon();
}
@@ -3860,7 +3854,6 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
case 58590: // Rank 9
case 58591: // Rank 10
{
- int32 basepoints0 = damage;
// Cast Absorb on totems
for (uint8 slot = SUMMON_SLOT_TOTEM; slot < MAX_TOTEM_SLOT; ++slot)
{
@@ -3870,14 +3863,17 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
Creature* totem = unitTarget->GetMap()->GetCreature(unitTarget->m_SummonSlot[slot]);
if (totem && totem->IsTotem())
{
- m_caster->CastCustomSpell(totem, 55277, &basepoints0, nullptr, nullptr, true);
+ CastSpellExtraArgs args(TRIGGERED_FULL_MASK);
+ args.SpellValueOverrides.AddMod(SPELLVALUE_BASE_POINT0, damage);
+ m_caster->CastSpell(totem, 55277, args);
}
}
// Glyph of Stoneclaw Totem
if (AuraEffect* aur = unitTarget->GetAuraEffect(63298, 0))
{
- basepoints0 *= aur->GetAmount();
- m_caster->CastCustomSpell(unitTarget, 55277, &basepoints0, nullptr, nullptr, true);
+ CastSpellExtraArgs args(TRIGGERED_FULL_MASK);
+ args.SpellValueOverrides.AddMod(SPELLVALUE_BASE_POINT0, damage * aur->GetAmount());
+ m_caster->CastSpell(unitTarget, 55277, args);
}
break;
}
@@ -4305,7 +4301,9 @@ void Spell::EffectFeedPet(SpellEffIndex effIndex)
player->DestroyItemCount(foodItem, count, true);
/// @todo fix crash when a spell has two effects, both pointed at the same item target
- m_caster->CastCustomSpell(pet, m_spellInfo->Effects[effIndex].TriggerSpell, &benefit, nullptr, nullptr, true);
+ CastSpellExtraArgs args(TRIGGERED_FULL_MASK);
+ args.SpellValueOverrides.AddMod(SPELLVALUE_BASE_POINT0, benefit);
+ m_caster->CastSpell(pet, m_spellInfo->Effects[effIndex].TriggerSpell, args);
}
void Spell::EffectDismissPet(SpellEffIndex effIndex)
@@ -4899,7 +4897,11 @@ void Spell::EffectDestroyAllTotems(SpellEffIndex /*effIndex*/)
}
ApplyPct(mana, damage);
if (mana)
- m_caster->CastCustomSpell(m_caster, 39104, &mana, nullptr, nullptr, true);
+ {
+ CastSpellExtraArgs args(TRIGGERED_FULL_MASK);
+ args.SpellValueOverrides.AddMod(SPELLVALUE_BASE_POINT0, mana);
+ m_caster->CastSpell(m_caster, 39104, args);
+ }
}
void Spell::EffectDurabilityDamage(SpellEffIndex effIndex)
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index 0eb8a31ad10..02ba482bf7b 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -3205,14 +3205,16 @@ void SpellMgr::LoadSpellInfoCorrections()
52438, // Summon Skittering Swarmer (Force Cast)
52449, // Summon Skittering Infector (Force Cast)
53609, // Summon Anub'ar Assassin (Force Cast)
- 53457 // Summon Impale Trigger (AoE)
+ 53457, // Summon Impale Trigger (AoE)
+ 45907 // Torch Target Picker
}, [](SpellInfo* spellInfo)
{
spellInfo->MaxAffectedTargets = 1;
});
- // Skartax Purple Beam
- ApplySpellFix({ 36384 }, [](SpellInfo* spellInfo)
+ ApplySpellFix({
+ 36384 // Skartax Purple Beam
+ }, [](SpellInfo* spellInfo)
{
spellInfo->MaxAffectedTargets = 2;
});
@@ -3245,6 +3247,44 @@ void SpellMgr::LoadSpellInfoCorrections()
});
ApplySpellFix({
+ 42005, // Bloodboil
+ 38296, // Spitfire Totem
+ 37676, // Insidious Whisper
+ 46008, // Negative Energy
+ 45641, // Fire Bloom
+ 55665, // Life Drain - Sapphiron (H)
+ 28796 // Poison Bolt Volly - Faerlina
+ }, [](SpellInfo* spellInfo)
+ {
+ spellInfo->MaxAffectedTargets = 5;
+ });
+
+ ApplySpellFix({
+ 54835 // Curse of the Plaguebringer - Noth (H)
+ }, [](SpellInfo* spellInfo)
+ {
+ spellInfo->MaxAffectedTargets = 8;
+ });
+
+ ApplySpellFix({
+ 40827, // Sinful Beam
+ 40859, // Sinister Beam
+ 40860, // Vile Beam
+ 40861, // Wicked Beam
+ 54098 // Poison Bolt Volly - Faerlina (H)
+ }, [](SpellInfo* spellInfo)
+ {
+ spellInfo->MaxAffectedTargets = 10;
+ });
+
+ ApplySpellFix({
+ 50312 // Unholy Frenzy
+ }, [](SpellInfo* spellInfo)
+ {
+ spellInfo->MaxAffectedTargets = 15;
+ });
+
+ ApplySpellFix({
47977, // Magic Broom
48025, // Headless Horseman's Mount
54729, // Winged Steed of the Ebon Blade
@@ -3281,43 +3321,6 @@ void SpellMgr::LoadSpellInfoCorrections()
spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ALLY);
});
- ApplySpellFix({
- 42005, // Bloodboil
- 38296, // Spitfire Totem
- 37676, // Insidious Whisper
- 46008, // Negative Energy
- 45641, // Fire Bloom
- 55665, // Life Drain - Sapphiron (H)
- 28796 // Poison Bolt Volly - Faerlina
- }, [](SpellInfo* spellInfo)
- {
- spellInfo->MaxAffectedTargets = 5;
- });
-
-
- // Curse of the Plaguebringer - Noth (H)
- ApplySpellFix({ 54835 }, [](SpellInfo* spellInfo)
- {
- spellInfo->MaxAffectedTargets = 8;
- });
-
- ApplySpellFix({
- 40827, // Sinful Beam
- 40859, // Sinister Beam
- 40860, // Vile Beam
- 40861, // Wicked Beam
- 54098 // Poison Bolt Volly - Faerlina (H)
- }, [](SpellInfo* spellInfo)
- {
- spellInfo->MaxAffectedTargets = 10;
- });
-
- // Unholy Frenzy
- ApplySpellFix({ 50312 }, [](SpellInfo* spellInfo)
- {
- spellInfo->MaxAffectedTargets = 15;
- });
-
// Murmur's Touch
ApplySpellFix({ 33711, 38794 }, [](SpellInfo* spellInfo)
{