aboutsummaryrefslogtreecommitdiff
path: root/src/server/game
diff options
context:
space:
mode:
authorTreeston <treeston.mmoc@gmail.com>2017-12-30 20:28:41 +0100
committerShauren <shauren.trinity@gmail.com>2021-04-16 15:22:42 +0200
commit9b141207d170e4b2b4e6d9290d5f921f76cbcea0 (patch)
tree47d65d966a66699f6de7e308047e408bdb255bff /src/server/game
parent2ea8f5e6fced094f28c45ac84123c85477122567 (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 (cherry picked from commit d507a7e3388382960108b24143da48e5f912b4a7)
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.cpp24
-rw-r--r--src/server/game/AI/CoreAI/UnitAI.h8
-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/Battlefield/Zones/BattlefieldTB.cpp4
-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.cpp57
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp182
-rw-r--r--src/server/game/Entities/Unit/Unit.h168
-rw-r--r--src/server/game/Entities/Unit/UnitDefines.h48
-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.cpp10
-rw-r--r--src/server/game/Handlers/ToyHandler.cpp2
-rw-r--r--src/server/game/Handlers/TradeHandler.cpp4
-rw-r--r--src/server/game/Spells/Auras/SpellAuraDefines.h48
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp101
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.cpp16
-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.h168
-rw-r--r--src/server/game/Spells/SpellEffects.cpp90
-rw-r--r--src/server/game/Spells/SpellMgr.cpp8
26 files changed, 470 insertions, 528 deletions
diff --git a/src/server/game/AI/CoreAI/PassiveAI.cpp b/src/server/game/AI/CoreAI/PassiveAI.cpp
index 2463f57f694..331267d1f19 100644
--- a/src/server/game/AI/CoreAI/PassiveAI.cpp
+++ b/src/server/game/AI/CoreAI/PassiveAI.cpp
@@ -98,7 +98,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 25c43525da2..2a2b8c62bd3 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 ccdb4097323..87277f7bfbf 100644
--- a/src/server/game/AI/CoreAI/UnitAI.cpp
+++ b/src/server/game/AI/CoreAI/UnitAI.cpp
@@ -96,7 +96,7 @@ bool UnitAI::DoSpellAttackIfReady(uint32 spellId)
{
if (me->IsWithinCombatRange(me->GetVictim(), spellInfo->GetMaxRange(false)))
{
- me->CastSpell(me->GetVictim(), spellInfo, TRIGGERED_NONE);
+ me->CastSpell(me->GetVictim(), spellId, me->GetMap()->GetDifficultyID());
me->resetAttackTimer();
return true;
}
@@ -167,28 +167,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);
}
#define UPDATE_TARGET(a) {if (AIInfo->target<a) AIInfo->target=a;}
diff --git a/src/server/game/AI/CoreAI/UnitAI.h b/src/server/game/AI/CoreAI/UnitAI.h
index 91f8a820189..a290c8ec402 100644
--- a/src/server/game/AI/CoreAI/UnitAI.h
+++ b/src/server/game/AI/CoreAI/UnitAI.h
@@ -298,10 +298,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); }
virtual bool ShouldSparWith(Unit const* /*target*/) const { return false; }
diff --git a/src/server/game/AI/PlayerAI/PlayerAI.cpp b/src/server/game/AI/PlayerAI/PlayerAI.cpp
index 695975fa177..be52282a482 100644
--- a/src/server/game/AI/PlayerAI/PlayerAI.cpp
+++ b/src/server/game/AI/PlayerAI/PlayerAI.cpp
@@ -575,7 +575,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 ae30dcca730..965fd290a1d 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
+++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
@@ -176,7 +176,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/Battlefield/Zones/BattlefieldTB.cpp b/src/server/game/Battlefield/Zones/BattlefieldTB.cpp
index a5ddeb42526..81ac01277e9 100644
--- a/src/server/game/Battlefield/Zones/BattlefieldTB.cpp
+++ b/src/server/game/Battlefield/Zones/BattlefieldTB.cpp
@@ -212,7 +212,7 @@ void BattlefieldTB::OnPlayerJoinWar(Player* player)
// Bonus damage buff for attackers
if (player->GetTeamId() == GetAttackerTeam() && GetData(BATTLEFIELD_TB_DATA_TOWERS_DESTROYED) > 0)
- player->CastCustomSpell(SPELL_TOWER_ATTACK_BONUS, SPELLVALUE_AURA_STACK, GetData(BATTLEFIELD_TB_DATA_TOWERS_DESTROYED), player, TRIGGERED_FULL_MASK);
+ player->CastSpell(player, SPELL_TOWER_ATTACK_BONUS, CastSpellExtraArgs(TRIGGERED_FULL_MASK).AddSpellMod(SPELLVALUE_AURA_STACK, GetData(BATTLEFIELD_TB_DATA_TOWERS_DESTROYED)));
}
@@ -759,7 +759,7 @@ void BattlefieldTB::TowerDestroyed(TBTowerId tbTowerId)
// Attack bonus buff
for (ObjectGuid const& guid : m_PlayersInWar[GetAttackerTeam()])
if (Player* player = ObjectAccessor::FindPlayer(guid))
- player->CastCustomSpell(SPELL_TOWER_ATTACK_BONUS, SPELLVALUE_AURA_STACK, GetData(BATTLEFIELD_TB_DATA_TOWERS_DESTROYED), player, TRIGGERED_FULL_MASK);
+ player->CastSpell(player, SPELL_TOWER_ATTACK_BONUS, CastSpellExtraArgs(TRIGGERED_FULL_MASK).AddSpellMod(SPELLVALUE_AURA_STACK, GetData(BATTLEFIELD_TB_DATA_TOWERS_DESTROYED)));
// Honor reward
TeamCastSpell(GetAttackerTeam(), SPELL_REWARD_TOWER_DESTROYED);
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 13ecb688257..e6f90796b89 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -2123,8 +2123,7 @@ void GameObject::Use(Unit* user)
if (!spellId)
return;
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId, GetMap()->GetDifficultyID());
- if (!spellInfo)
+ if (!sSpellMgr->GetSpellInfo(spellId, GetMap()->GetDifficultyID()))
{
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());
@@ -2137,7 +2136,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);
}
@@ -2166,7 +2165,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;
}
@@ -2179,6 +2178,8 @@ void GameObject::CastSpell(Unit* target, uint32 spellId, TriggerCastFlags trigge
trigger->SetImmuneToAll(false);
PhasingHandler::InheritPhaseShift(trigger, this);
+ CastSpellExtraArgs args;
+ args.TriggerFlags = triggered;
if (Unit* owner = GetOwner())
{
trigger->SetFaction(owner->GetFaction());
@@ -2188,14 +2189,17 @@ void GameObject::CastSpell(Unit* target, uint32 spellId, TriggerCastFlags trigge
trigger->SetPvpFlags(owner->GetPvpFlags());
// 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 d66e0b859e6..0e32be435b4 100644
--- a/src/server/game/Entities/Pet/Pet.cpp
+++ b/src/server/game/Entities/Pet/Pet.cpp
@@ -1702,13 +1702,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 71005da4166..0cf360516ac 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -7862,7 +7862,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);
@@ -7994,7 +7994,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
{
@@ -8103,13 +8103,15 @@ void Player::ApplyArtifactPowerRank(Item* artifact, ArtifactPowerRankEntry const
}
else if (apply)
{
- CustomSpellValues csv;
+ CastSpellExtraArgs args;
+ args.TriggerFlags = TRIGGERED_FULL_MASK;
+ args.CastItem = artifact;
if (artifactPowerRank->AuraPointsOverride)
for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
if (spellInfo->GetEffect(i))
- csv.AddSpellMod(SpellValueMod(SPELLVALUE_BASE_POINT0 + i), artifactPowerRank->AuraPointsOverride);
+ args.AddSpellMod(SpellValueMod(SPELLVALUE_BASE_POINT0 + i), artifactPowerRank->AuraPointsOverride);
- CastCustomSpell(artifactPowerRank->SpellID, csv, this, TRIGGERED_FULL_MASK, artifact);
+ CastSpell(this, artifactPowerRank->SpellID, args);
}
}
else
@@ -8166,7 +8168,7 @@ void Player::ApplyAzeriteItemMilestonePower(AzeriteItem* item, AzeriteItemMilest
if (AzeritePowerEntry const* azeritePower = sAzeritePowerStore.LookupEntry(azeriteItemMilestonePower->AzeritePowerID))
{
if (apply)
- CastSpell(this, azeritePower->SpellID, true, item);
+ CastSpell(this, azeritePower->SpellID, item);
else
RemoveAurasDueToItemSpell(azeritePower->SpellID, item->GetGUID());
}
@@ -8183,7 +8185,7 @@ void Player::ApplyAzeriteEssence(AzeriteItem* item, uint32 azeriteEssenceId, uin
if (major && currentRank == 1)
{
if (apply)
- CastCustomSpell(SPELL_ID_HEART_ESSENCE_ACTION_BAR_OVERRIDE, SPELLVALUE_BASE_POINT0, azeriteEssencePower->MajorPowerDescription, this, TRIGGERED_FULL_MASK);
+ CastSpell(this, SPELL_ID_HEART_ESSENCE_ACTION_BAR_OVERRIDE, CastSpellExtraArgs(TRIGGERED_FULL_MASK).AddSpellBP0(azeriteEssencePower->MajorPowerDescription));
else
RemoveAurasDueToSpell(SPELL_ID_HEART_ESSENCE_ACTION_BAR_OVERRIDE);
}
@@ -8196,7 +8198,7 @@ void Player::ApplyAzeriteEssencePower(AzeriteItem* item, AzeriteEssencePowerEntr
if (SpellInfo const* powerSpell = sSpellMgr->GetSpellInfo(azeriteEssencePower->MinorPowerDescription, DIFFICULTY_NONE))
{
if (apply)
- CastSpell(this, powerSpell, true, item);
+ CastSpell(this, powerSpell->Id, item);
else
RemoveAurasDueToItemSpell(powerSpell->Id, item->GetGUID());
}
@@ -8208,7 +8210,7 @@ void Player::ApplyAzeriteEssencePower(AzeriteItem* item, AzeriteEssencePowerEntr
if (powerSpell->IsPassive())
{
if (apply)
- CastSpell(this, powerSpell, true, item);
+ CastSpell(this, powerSpell->Id, item);
else
RemoveAurasDueToItemSpell(powerSpell->Id, item->GetGUID());
}
@@ -8228,7 +8230,7 @@ void Player::ApplyAzeritePower(AzeriteEmpoweredItem* item, AzeritePowerEntry con
if (apply)
{
if (!azeritePower->SpecSetID || sDB2Manager.IsSpecSetMember(azeritePower->SpecSetID, GetPrimarySpecialization()))
- CastSpell(this, azeritePower->SpellID, true, item);
+ CastSpell(this, azeritePower->SpellID, item);
}
else
RemoveAurasDueToItemSpell(azeritePower->SpellID, item->GetGUID());
@@ -8320,7 +8322,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);
}
}
@@ -8384,17 +8386,17 @@ void Player::CastItemCombatSpell(DamageInfo const& damageInfo, Item* item, ItemT
if (roll_chance_f(chance))
{
if (spellInfo->IsPositive())
- CastSpell(this, spellInfo, true, item);
+ CastSpell(this, spellInfo->Id, item);
else
- CastSpell(damageInfo.GetVictim(), spellInfo, true, item);
+ CastSpell(damageInfo.GetVictim(), spellInfo->Id, item);
}
if (roll_chance_f(chance))
{
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->GetLevelForTarget(this) > 60)
{
int32 const lvlDifference = target->GetLevelForTarget(this) - 60;
@@ -8405,11 +8407,10 @@ void Player::CastItemCombatSpell(DamageInfo const& damageInfo, Item* item, ItemT
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
if (spellInfo->GetEffect(i)->IsEffect())
- values.AddSpellMod(static_cast<SpellValueMod>(SPELLVALUE_BASE_POINT0 + i), CalculatePct(spellInfo->GetEffect(i)->CalcValue(this), effectPct));
+ args.SpellValueOverrides.AddMod(static_cast<SpellValueMod>(SPELLVALUE_BASE_POINT0 + i), CalculatePct(spellInfo->GetEffect(i)->CalcValue(this), effectPct));
}
}
-
- CastCustomSpell(spellInfo->Id, values, target, TRIGGERED_FULL_MASK, item);
+ CastSpell(target, spellInfo->Id, args);
}
}
}
@@ -8443,7 +8444,7 @@ void Player::CastItemUseSpell(Item* item, SpellCastTargets const& targets, Objec
spell->m_fromClient = true;
spell->m_CastItem = item;
spell->SetSpellValue(SPELLVALUE_BASE_POINT0, learning_spell_id);
- spell->prepare(&targets);
+ spell->prepare(targets);
return;
}
}
@@ -8473,7 +8474,7 @@ void Player::CastItemUseSpell(Item* item, SpellCastTargets const& targets, Objec
spell->m_CastItem = item;
spell->m_misc.Raw.Data[0] = misc[0];
spell->m_misc.Raw.Data[1] = misc[1];
- spell->prepare(&targets);
+ spell->prepare(targets);
return;
}
@@ -8507,7 +8508,7 @@ void Player::CastItemUseSpell(Item* item, SpellCastTargets const& targets, Objec
spell->m_CastItem = item;
spell->m_misc.Raw.Data[0] = misc[0];
spell->m_misc.Raw.Data[1] = misc[1];
- spell->prepare(&targets);
+ spell->prepare(targets);
return;
}
}
@@ -14301,7 +14302,7 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool
if (enchant_spell_id)
{
if (apply)
- CastSpell(this, enchant_spell_id, true, item);
+ CastSpell(this, enchant_spell_id, item);
else
RemoveAurasDueToItemSpell(enchant_spell_id, item->GetGUID());
}
@@ -14918,7 +14919,7 @@ void Player::OnGossipSelect(WorldObject* source, uint32 optionIndex, uint32 menu
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);
@@ -15604,7 +15605,7 @@ void Player::AddQuest(Quest const* quest, Object* questGiver)
if (Unit* unit = questGiver->ToUnit())
caster = unit;
- caster->CastSpell(this, spellInfo, true);
+ caster->CastSpell(this, spellInfo->Id, CastSpellExtraArgs(TRIGGERED_FULL_MASK).SetCastDifficulty(spellInfo->Difficulty));
}
SetQuestSlot(log_slot, quest_id, qtime);
@@ -15941,7 +15942,7 @@ void Player::RewardQuest(Quest const* quest, LootItemType rewardType, uint32 rew
if (Unit* unit = questGiver->ToUnit())
caster = unit;
- caster->CastSpell(this, spellInfo, true);
+ caster->CastSpell(this, spellInfo->Id, CastSpellExtraArgs(TRIGGERED_FULL_MASK).SetCastDifficulty(spellInfo->Difficulty));
}
else
{
@@ -15957,7 +15958,7 @@ void Player::RewardQuest(Quest const* quest, LootItemType rewardType, uint32 rew
if (Unit* unit = questGiver->ToUnit())
caster = unit;
- caster->CastSpell(this, spellInfo, true);
+ caster->CastSpell(this, spellInfo->Id, CastSpellExtraArgs(TRIGGERED_FULL_MASK).SetCastDifficulty(spellInfo->Difficulty));
}
}
@@ -22449,7 +22450,7 @@ void Player::VehicleSpellInitialize()
}
if (spellInfo->IsPassive())
- vehicle->CastSpell(vehicle, spellInfo, true);
+ vehicle->CastSpell(vehicle, spellInfo->Id, true);
petSpells.ActionButtons[i] = MAKE_UNIT_ACTION_BUTTON(spellId, i + 8);
}
@@ -25794,7 +25795,7 @@ bool Player::IsAtRecruitAFriendDistance(WorldObject const* pOther) const
void Player::ResurrectUsingRequestData()
{
- /// 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())
@@ -25825,7 +25826,7 @@ void Player::ResurrectUsingRequestDataImpl()
SetPower(POWER_LUNAR_POWER, 0);
if (uint32 aura = resurrectAura)
- CastSpell(this, aura, true, nullptr, nullptr, resurrectGUID);
+ CastSpell(this, aura, resurrectGUID);
SpawnCorpseBones();
}
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index d69a54935e9..0121c59f71d 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -1001,147 +1001,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)
- {
- TC_LOG_ERROR("entities.unit", "CastSpell: unknown spell by caster: %s", 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, GetMap()->GetDifficultyID());
- if (!spellInfo)
- {
- TC_LOG_ERROR("entities.unit", "CastSpell: unknown spell id %u by caster: %s", spellId, GetGUID().ToString().c_str());
- 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, GetMap()->GetDifficultyID());
- if (!spellInfo)
+ SpellInfo const* info = sSpellMgr->GetSpellInfo(spellId, args.CastDifficulty != DIFFICULTY_NONE ? args.CastDifficulty : GetMap()->GetDifficultyID());
+ if (!info)
{
- TC_LOG_ERROR("entities.unit", "CastSpell: unknown spell id %u by caster: %s", spellId, GetGUID().ToString().c_str());
+ TC_LOG_ERROR("entities.unit", "CastSpell: unknown spell %u by caster %s", spellId, GetGUID().ToString().c_str());
return;
}
- SpellCastTargets targets;
- targets.SetUnitTarget(victim);
- CastSpell(targets, spellInfo, &value, triggerFlags, castItem, triggeredByAura, originalCaster);
-}
+ Spell* spell = new Spell(this, info, args.TriggerFlags, args.OriginalCaster);
+ for (auto const& pair : args.SpellValueOverrides)
+ spell->SetSpellValue(pair.first, pair.second);
-void Unit::CastSpell(float x, float y, float z, uint32 spellId, bool triggered, Item* castItem, AuraEffect const* triggeredByAura, ObjectGuid originalCaster)
-{
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId, GetMap()->GetDifficultyID());
- if (!spellInfo)
- {
- TC_LOG_ERROR("entities.unit", "CastSpell: unknown spell id %u by caster: %s", spellId, GetGUID().ToString().c_str());
- return;
- }
- SpellCastTargets targets;
- targets.SetDst(x, y, z, GetOrientation());
-
- CastSpell(targets, spellInfo, nullptr, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, castItem, triggeredByAura, originalCaster);
+ spell->m_CastItem = args.CastItem;
+ spell->prepare(targets, args.TriggeringAura);
}
-void Unit::CastSpell(float x, float y, float z, uint32 spellId, TriggerCastFlags triggerFlags, Item* castItem, AuraEffect const* triggeredByAura, ObjectGuid originalCaster)
+void Unit::CastSpell(WorldObject* target, uint32 spellId, CastSpellExtraArgs const& args)
{
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId, GetMap()->GetDifficultyID());
- if (!spellInfo)
- {
- TC_LOG_ERROR("entities.unit", "CastSpell: unknown spell id %u by caster: %s", spellId, GetGUID().ToString().c_str());
- return;
- }
SpellCastTargets targets;
- targets.SetDst(x, y, z, GetOrientation());
-
- CastSpell(targets, spellInfo, nullptr, triggerFlags, castItem, triggeredByAura, originalCaster);
-}
-
-void Unit::CastSpell(GameObject* go, uint32 spellId, bool triggered, Item* castItem, AuraEffect const* triggeredByAura, ObjectGuid originalCaster)
-{
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId, GetMap()->GetDifficultyID());
- if (!spellInfo)
+ if (target)
{
- TC_LOG_ERROR("entities.unit", "CastSpell: unknown spell id %u by caster: %s", spellId, GetGUID().ToString().c_str());
- 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.SetGOTarget(go);
-
- CastSpell(targets, spellInfo, nullptr, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, castItem, triggeredByAura, originalCaster);
+ CastSpell(targets, spellId, args);
}
-void Unit::CastSpell(Item* target, uint32 spellId, bool triggered, Item* castItem, AuraEffect const* triggeredByAura, ObjectGuid originalCaster)
+void Unit::CastSpell(Position const& dest, uint32 spellId, CastSpellExtraArgs const& args)
{
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId, GetMap()->GetDifficultyID());
- if (!spellInfo)
- {
- TC_LOG_ERROR("entities.unit", "CastSpell: unknown spell id %u by caster: %s", spellId, GetGUID().ToString().c_str());
- return;
- }
SpellCastTargets targets;
- targets.SetItemTarget(target);
-
- 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)
@@ -2125,7 +2024,10 @@ void Unit::AttackerStateUpdate(Unit* victim, WeaponAttackType attType, bool extr
}
else
{
- CastSpell(victim, meleeAttackSpellId, true, nullptr, meleeAttackAuraEffect);
+ CastSpellExtraArgs args;
+ args.TriggerFlags = TRIGGERED_FULL_MASK;
+ args.TriggeringAura = meleeAttackAuraEffect;
+ CastSpell(victim, meleeAttackSpellId, args);
uint32 hitInfo = HITINFO_AFFECTS_VICTIM | HITINFO_NO_ANIMATION;
if (attType == OFF_ATTACK)
@@ -2996,7 +2898,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);
@@ -5991,7 +5893,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())
@@ -6004,7 +5906,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);
}
}
}
@@ -10181,7 +10083,10 @@ void Unit::TriggerOnPowerChangeAuras(Powers power, int32 oldVal, int32 newVal)
break;
}
- CastSpell(this, triggerSpell, true, nullptr, effect);
+ CastSpellExtraArgs args;
+ args.TriggerFlags = TRIGGERED_FULL_MASK;
+ args.TriggeringAura = effect;
+ CastSpell(this, triggerSpell, args);
}
}
}
@@ -10452,7 +10357,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);
}
@@ -10485,7 +10390,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
@@ -13012,7 +12917,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];
@@ -13027,7 +12937,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, ObjectGuid::Create<HighGuid::Cast>(SPELL_CAST_SOURCE_NORMAL, GetMapId(), spellEntry->Id, GetMap()->GenerateLowGuid<HighGuid::Cast>()), MAX_EFFECT_MASK, this, clicker, GetMap()->GetDifficultyID(), nullptr, nullptr, origCasterGUID);
}
@@ -13044,7 +12954,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 0a1f3c72686..92da6ccbb20 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -39,125 +39,6 @@
#define SPELL_DH_DOUBLE_JUMP 196055
#define DISPLAYID_HIDDEN_MOUNT 73200
-enum class SpellModOp : uint8
-{
- HealingAndDamage = 0,
- Duration = 1,
- Hate = 2,
- PointsIndex0 = 3,
- ProcCharges = 4,
- Range = 5,
- Radius = 6,
- CritChance = 7,
- Points = 8,
- ResistPushback = 9,
- ChangeCastTime = 10,
- Cooldown = 11,
- PointsIndex1 = 12,
- TargetResistance = 13,
- PowerCost0 = 14, // Used when SpellPowerEntry::PowerIndex == 0
- CritDamageAndHealing = 15,
- HitChance = 16,
- ChainTargets = 17,
- ProcChance = 18,
- Period = 19,
- ChainAmplitude = 20,
- StartCooldown = 21,
- PeriodicHealingAndDamage = 22,
- PointsIndex2 = 23,
- BonusCoefficient = 24,
- TriggerDamage = 25, // NYI
- ProcFrequency = 26,
- Amplitude = 27,
- DispelResistance = 28,
- CrowdDamage = 29, // NYI
- PowerCostOnMiss = 30,
- Doses = 31,
- PointsIndex3 = 32,
- PointsIndex4 = 33,
- PowerCost1 = 34, // Used when SpellPowerEntry::PowerIndex == 1
- ChainJumpDistance = 35,
- AreaTriggerMaxSummons = 36, // NYI
- MaxAuraStacks = 37,
- ProcCooldown = 38,
- PowerCost2 = 39, // Used when SpellPowerEntry::PowerIndex == 2
-};
-
-#define MAX_SPELLMOD 40
-
-enum SpellValueMod : uint8
-{
- SPELLVALUE_BASE_POINT0,
- SPELLVALUE_BASE_POINT1,
- SPELLVALUE_BASE_POINT2,
- SPELLVALUE_BASE_POINT3,
- SPELLVALUE_BASE_POINT4,
- SPELLVALUE_BASE_POINT5,
- SPELLVALUE_BASE_POINT6,
- SPELLVALUE_BASE_POINT7,
- SPELLVALUE_BASE_POINT8,
- SPELLVALUE_BASE_POINT9,
- SPELLVALUE_BASE_POINT10,
- SPELLVALUE_BASE_POINT11,
- SPELLVALUE_BASE_POINT12,
- SPELLVALUE_BASE_POINT13,
- SPELLVALUE_BASE_POINT14,
- SPELLVALUE_BASE_POINT15,
- SPELLVALUE_BASE_POINT16,
- SPELLVALUE_BASE_POINT17,
- SPELLVALUE_BASE_POINT18,
- SPELLVALUE_BASE_POINT19,
- SPELLVALUE_BASE_POINT20,
- SPELLVALUE_BASE_POINT21,
- SPELLVALUE_BASE_POINT22,
- SPELLVALUE_BASE_POINT23,
- SPELLVALUE_BASE_POINT24,
- SPELLVALUE_BASE_POINT25,
- SPELLVALUE_BASE_POINT26,
- SPELLVALUE_BASE_POINT27,
- SPELLVALUE_BASE_POINT28,
- SPELLVALUE_BASE_POINT29,
- SPELLVALUE_BASE_POINT30,
- SPELLVALUE_BASE_POINT31,
- SPELLVALUE_BASE_POINT_END,
- 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
-};
-
#define MAX_SPELL_CHARM 4
#define MAX_SPELL_VEHICLE 6
#define MAX_SPELL_POSSESS 8
@@ -284,36 +165,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_IGNORE_TARGET_CHECK = 0x00100000, //! Will ignore most target checks (mostly DBC target checks)
- TRIGGERED_FULL_DEBUG_MASK = 0xFFFFFFFF
-};
-
enum UnitMods
{
UNIT_MOD_STAT_STRENGTH, // UNIT_MOD_STAT_STRENGTH..UNIT_MOD_STAT_INTELLECT must be in existed order, it's accessed by index values of Stats enum.
@@ -1326,21 +1177,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 const* 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 const* 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 const* triggeredByAura = nullptr, ObjectGuid originalCaster = ObjectGuid::Empty);
- void CastSpell(Item* target, uint32 spellId, bool triggered, Item* castItem = nullptr, AuraEffect const* 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, uint32 effMask, Unit* target);
void SetAuraStack(uint32 spellId, Unit* target, uint32 stack);
diff --git a/src/server/game/Entities/Unit/UnitDefines.h b/src/server/game/Entities/Unit/UnitDefines.h
index f12b41498d8..b0191780ae8 100644
--- a/src/server/game/Entities/Unit/UnitDefines.h
+++ b/src/server/game/Entities/Unit/UnitDefines.h
@@ -98,54 +98,6 @@ enum UnitPetFlag : uint8
UNIT_PET_FLAG_CAN_BE_ABANDONED = 0x02
};
-// high byte (3 from 0..3) of UNIT_FIELD_BYTES_2
-enum ShapeshiftForm
-{
- FORM_NONE = 0,
- FORM_CAT_FORM = 1,
- FORM_TREE_OF_LIFE = 2,
- FORM_TRAVEL_FORM = 3,
- FORM_AQUATIC_FORM = 4,
- FORM_BEAR_FORM = 5,
- FORM_AMBIENT = 6,
- FORM_GHOUL = 7,
- FORM_DIRE_BEAR_FORM = 8,
- FORM_CRANE_STANCE = 9,
- FORM_THARONJA_SKELETON = 10,
- FORM_DARKMOON_TEST_OF_STRENGTH = 11,
- FORM_BLB_PLAYER = 12,
- FORM_SHADOW_DANCE = 13,
- FORM_CREATURE_BEAR = 14,
- FORM_CREATURE_CAT = 15,
- FORM_GHOST_WOLF = 16,
- FORM_BATTLE_STANCE = 17,
- FORM_DEFENSIVE_STANCE = 18,
- FORM_BERSERKER_STANCE = 19,
- FORM_SERPENT_STANCE = 20,
- FORM_ZOMBIE = 21,
- FORM_METAMORPHOSIS = 22,
- FORM_OX_STANCE = 23,
- FORM_TIGER_STANCE = 24,
- FORM_UNDEAD = 25,
- FORM_FRENZY = 26,
- FORM_FLIGHT_FORM_EPIC = 27,
- FORM_SHADOWFORM = 28,
- FORM_FLIGHT_FORM = 29,
- FORM_STEALTH = 30,
- FORM_MOONKIN_FORM = 31,
- FORM_SPIRIT_OF_REDEMPTION = 32,
- FORM_GLADIATOR_STANCE = 33,
- FORM_METAMORPHOSIS_2 = 34,
- FORM_MOONKIN_FORM_RESTORATION = 35,
- FORM_TREANT_FORM = 36,
- FORM_SPIRIT_OWL_FORM = 37,
- FORM_SPIRIT_OWL_FORM_2 = 38,
- FORM_WISP_FORM = 39,
- FORM_WISP_FORM_2 = 40,
- FORM_SOULSHAPE = 41,
- FORM_FORGEBORNE_REVERIES = 42
-};
-
enum UnitMoveType
{
MOVE_WALK = 0,
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index 66275e774bd..caae1003ccd 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -1217,10 +1217,10 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
{
// not blizz like, we must correctly save and load player instead...
if (pCurrChar->getRace() == RACE_NIGHTELF && !pCurrChar->HasAura(20584))
- 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, 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)
if (!pCurrChar->HasAura(8326))
- pCurrChar->CastSpell(pCurrChar, 8326, true, nullptr); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?)
+ pCurrChar->CastSpell(pCurrChar, 8326, true); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?)
pCurrChar->SetWaterWalking(true);
}
diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp
index ee05f6918c2..9a2863ae12c 100644
--- a/src/server/game/Handlers/PetHandler.cpp
+++ b/src/server/game/Handlers/PetHandler.cpp
@@ -387,7 +387,7 @@ void WorldSession::HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint32 spe
}
}
- spell->prepare(&(spell->m_targets));
+ spell->prepare(spell->m_targets);
}
else
{
@@ -713,7 +713,7 @@ void WorldSession::HandlePetCastSpellOpcode(WorldPackets::Spells::PetCastSpell&
spellPrepare.ServerCastID = spell->m_castId;
SendPacket(spellPrepare.Write());
- spell->prepare(&targets);
+ spell->prepare(targets);
}
else
{
diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp
index 11db09e1013..ad2a073a4a4 100644
--- a/src/server/game/Handlers/SpellHandler.cpp
+++ b/src/server/game/Handlers/SpellHandler.cpp
@@ -342,7 +342,7 @@ void WorldSession::HandleCastSpellOpcode(WorldPackets::Spells::CastSpell& cast)
spell->m_fromClient = true;
spell->m_misc.Raw.Data[0] = cast.Cast.Misc[0];
spell->m_misc.Raw.Data[1] = cast.Cast.Misc[1];
- spell->prepare(&targets);
+ spell->prepare(targets);
}
void WorldSession::HandleCancelCastOpcode(WorldPackets::Spells::CancelCast& packet)
@@ -489,14 +489,10 @@ void WorldSession::HandleSelfResOpcode(WorldPackets::Spells::SelfRes& selfRes)
if (_player->HasAuraType(SPELL_AURA_PREVENT_RESURRECTION))
return; // silent return, client should display error by itself and not send this opcode
- auto const& selfResSpells = _player->m_activePlayerData->SelfResSpells;
- if (std::find(selfResSpells.begin(), selfResSpells.end(), selfRes.SpellID) == selfResSpells.end())
+ if (_player->m_activePlayerData->SelfResSpells.FindIndex(selfRes.SpellID) < 0)
return;
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(selfRes.SpellID, _player->GetMap()->GetDifficultyID());
- if (spellInfo)
- _player->CastSpell(_player, spellInfo, false, nullptr);
-
+ _player->CastSpell(_player, selfRes.SpellID, _player->GetMap()->GetDifficultyID());
_player->RemoveSelfResSpell(selfRes.SpellID);
}
diff --git a/src/server/game/Handlers/ToyHandler.cpp b/src/server/game/Handlers/ToyHandler.cpp
index 42a0408b6e3..7f310325047 100644
--- a/src/server/game/Handlers/ToyHandler.cpp
+++ b/src/server/game/Handlers/ToyHandler.cpp
@@ -93,7 +93,7 @@ void WorldSession::HandleUseToy(WorldPackets::Toy::UseToy& packet)
spell->m_misc.Raw.Data[0] = packet.Cast.Misc[0];
spell->m_misc.Raw.Data[1] = packet.Cast.Misc[1];
spell->m_castFlagsEx |= CAST_FLAG_EX_USE_TOY_SPELL;
- spell->prepare(&targets);
+ spell->prepare(targets);
}
void WorldSession::HandleToyClearFanfare(WorldPackets::Toy::ToyClearFanfare& toyClearFanfare)
diff --git a/src/server/game/Handlers/TradeHandler.cpp b/src/server/game/Handlers/TradeHandler.cpp
index c53c68ce681..69791345e3f 100644
--- a/src/server/game/Handlers/TradeHandler.cpp
+++ b/src/server/game/Handlers/TradeHandler.cpp
@@ -509,10 +509,10 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPackets::Trade::AcceptTrade& acc
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 ec87dc3eb3e..7c9944a1929 100644
--- a/src/server/game/Spells/Auras/SpellAuraDefines.h
+++ b/src/server/game/Spells/Auras/SpellAuraDefines.h
@@ -591,4 +591,52 @@ enum AuraObjectType
DYNOBJ_AURA_TYPE
};
+// high byte (3 from 0..3) of UNIT_FIELD_BYTES_2
+enum ShapeshiftForm
+{
+ FORM_NONE = 0,
+ FORM_CAT_FORM = 1,
+ FORM_TREE_OF_LIFE = 2,
+ FORM_TRAVEL_FORM = 3,
+ FORM_AQUATIC_FORM = 4,
+ FORM_BEAR_FORM = 5,
+ FORM_AMBIENT = 6,
+ FORM_GHOUL = 7,
+ FORM_DIRE_BEAR_FORM = 8,
+ FORM_CRANE_STANCE = 9,
+ FORM_THARONJA_SKELETON = 10,
+ FORM_DARKMOON_TEST_OF_STRENGTH = 11,
+ FORM_BLB_PLAYER = 12,
+ FORM_SHADOW_DANCE = 13,
+ FORM_CREATURE_BEAR = 14,
+ FORM_CREATURE_CAT = 15,
+ FORM_GHOST_WOLF = 16,
+ FORM_BATTLE_STANCE = 17,
+ FORM_DEFENSIVE_STANCE = 18,
+ FORM_BERSERKER_STANCE = 19,
+ FORM_SERPENT_STANCE = 20,
+ FORM_ZOMBIE = 21,
+ FORM_METAMORPHOSIS = 22,
+ FORM_OX_STANCE = 23,
+ FORM_TIGER_STANCE = 24,
+ FORM_UNDEAD = 25,
+ FORM_FRENZY = 26,
+ FORM_FLIGHT_FORM_EPIC = 27,
+ FORM_SHADOWFORM = 28,
+ FORM_FLIGHT_FORM = 29,
+ FORM_STEALTH = 30,
+ FORM_MOONKIN_FORM = 31,
+ FORM_SPIRIT_OF_REDEMPTION = 32,
+ FORM_GLADIATOR_STANCE = 33,
+ FORM_METAMORPHOSIS_2 = 34,
+ FORM_MOONKIN_FORM_RESTORATION = 35,
+ FORM_TREANT_FORM = 36,
+ FORM_SPIRIT_OWL_FORM = 37,
+ FORM_SPIRIT_OWL_FORM_2 = 38,
+ FORM_WISP_FORM = 39,
+ FORM_WISP_FORM_2 = 40,
+ FORM_SOULSHAPE = 41,
+ FORM_FORGEBORNE_REVERIES = 42
+};
+
#endif
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 515badef5aa..cf5ed8a765d 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -1234,16 +1234,16 @@ 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 (spellId3)
- target->CastSpell(target, spellId3, true, nullptr, this);
+ target->CastSpell(target, spellId3, this);
if (spellId4)
- target->CastSpell(target, spellId4, true, nullptr, this);
+ target->CastSpell(target, spellId4, this);
if (target->GetTypeId() == TYPEID_PLAYER)
{
@@ -1267,7 +1267,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);
}
}
}
@@ -1703,12 +1703,12 @@ void AuraEffect::HandleAuraModShapeshift(AuraApplication const* aurApp, uint8 mo
case FORM_BEAR_FORM:
case FORM_CAT_FORM:
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_FORM:
if (AuraEffect* dummy = target->GetAuraEffect(37324, 0))
- target->CastSpell(target, 37325, true, nullptr, dummy);
+ target->CastSpell(target, 37325, dummy);
break;
default:
break;
@@ -4382,7 +4382,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
{
@@ -4390,7 +4390,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());
@@ -4411,15 +4411,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 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);
@@ -4428,9 +4428,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
@@ -4468,7 +4468,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)
@@ -4488,7 +4488,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
@@ -4497,7 +4497,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;
}
@@ -4511,14 +4511,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 91604: // Restricted Flight Area
if (aurApp->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE)
@@ -4558,9 +4558,13 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
if (apply && caster)
{
SpellInfo const* spell = sSpellMgr->AssertSpellInfo(spellId, GetBase()->GetCastDifficulty());
+ CastSpellExtraArgs args;
+ args.TriggerFlags = TRIGGERED_FULL_MASK;
+ args.OriginalCaster = GetCasterGUID();
+ args.CastDifficulty = spell->Difficulty;
for (uint32 i = 0; i < spell->StackAmount; ++i)
- caster->CastSpell(target, spell, true, nullptr, nullptr, GetCasterGUID());
+ caster->CastSpell(target, spell->Id, args);
break;
}
target->RemoveAurasDueToSpell(spellId);
@@ -4573,8 +4577,13 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
if (apply && caster)
{
SpellInfo const* spell = sSpellMgr->AssertSpellInfo(spellId, GetBase()->GetCastDifficulty());
+ CastSpellExtraArgs args;
+ args.TriggerFlags = TRIGGERED_FULL_MASK;
+ args.OriginalCaster = GetCasterGUID();
+ args.CastDifficulty = spell->Difficulty;
+
for (uint32 i = 0; i < spell->StackAmount; ++i)
- caster->CastSpell(target, spell, true, nullptr, nullptr, GetCasterGUID());
+ caster->CastSpell(target, spell->Id, args);
break;
}
target->RemoveAurasDueToSpell(spellId);
@@ -4860,11 +4869,13 @@ void AuraEffect::HandleAuraLinked(AuraApplication const* aurApp, uint8 mode, boo
{
if (apply)
{
- // 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
{
@@ -5081,12 +5092,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
@@ -5096,13 +5107,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
@@ -5152,7 +5165,7 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
if (GetSpellInfo()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellInfo()->SpellFamilyFlags[0] & 0x00004000))
{
if (caster->GetTypeId() == TYPEID_PLAYER && caster->ToPlayer()->isHonorOrXPTarget(target))
- caster->CastSpell(caster, 95810, true, nullptr, this);
+ caster->CastSpell(caster, 95810, this);
}
if (GetSpellInfo()->SpellFamilyName == SPELLFAMILY_GENERIC)
{
@@ -5515,7 +5528,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);
}
}
@@ -5654,7 +5670,7 @@ void AuraEffect::HandleProcTriggerSpellAuraProc(AuraApplication* aurApp, ProcEve
if (SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(triggerSpellId, GetBase()->GetCastDifficulty()))
{
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 if (triggerSpellId && GetAuraType() != SPELL_AURA_DUMMY)
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());
@@ -5668,9 +5684,10 @@ void AuraEffect::HandleProcTriggerSpellWithValueAuraProc(AuraApplication* aurApp
uint32 triggerSpellId = GetSpellEffectInfo()->TriggerSpell;
if (SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(triggerSpellId, GetBase()->GetCastDifficulty()))
{
- 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());
@@ -5853,7 +5870,13 @@ void AuraEffect::HandleLinkedSummon(AuraApplication const* aurApp, uint8 mode, b
// on apply cast summon spell
if (apply)
- target->CastSpell(target, triggerSpellInfo, true, nullptr, this);
+ {
+ CastSpellExtraArgs args;
+ args.TriggerFlags = TRIGGERED_FULL_MASK;
+ args.TriggeringAura = this;
+ args.CastDifficulty = triggerSpellInfo->Difficulty;
+ target->CastSpell(target, triggerSpellInfo->Id, args);
+ }
// on unapply we need to search for and remove the summoned creature
else
{
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index dfe0ef6276a..8f9d716a304 100644
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -1249,7 +1249,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))
@@ -1311,8 +1311,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;
@@ -1329,7 +1330,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:
@@ -1363,8 +1364,9 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
if (AuraEffect const* aurEff = aura->GetEffect(0))
{
float multiplier = float(aurEff->GetAmount());
- 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);
}
}
}
@@ -1391,7 +1393,7 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
if (owner->HasAura(34692))
{
if (apply)
- owner->CastSpell(owner, 34471, true, nullptr, 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 0e897c3b109..25e0e56bdf5 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -2767,7 +2767,7 @@ void Spell::DoTriggersOnSpellHit(Unit* unit, uint32 effMask)
{
if (CanExecuteTriggersOnHit(effMask, i->triggeredByAura) && roll_chance_i(i->chance))
{
- m_caster->CastSpell(unit, i->triggeredSpell, TRIGGERED_FULL_MASK);
+ m_caster->CastSpell(unit, i->triggeredSpell->Id, CastSpellExtraArgs(TRIGGERED_FULL_MASK).SetCastDifficulty(i->triggeredSpell->Difficulty));
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
@@ -2798,7 +2798,7 @@ void Spell::DoTriggersOnSpellHit(Unit* unit, uint32 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());
}
}
}
@@ -2916,7 +2916,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)
{
@@ -2935,7 +2935,7 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered
}
}
- InitExplicitTargets(*targets);
+ InitExplicitTargets(targets);
m_spellState = SPELL_STATE_PREPARING;
@@ -5597,7 +5597,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 811a3c55159..8253062a290 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -522,7 +522,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
index c330b2b1aa8..0b81f9ced5c 100644
--- a/src/server/game/Spells/SpellDefines.h
+++ b/src/server/game/Spells/SpellDefines.h
@@ -20,6 +20,12 @@
#include "Define.h"
#include "EnumFlag.h"
+#include "ObjectGuid.h"
+#include <vector>
+
+class Item;
+class AuraEffect;
+enum Difficulty : uint8;
namespace UF
{
@@ -122,6 +128,168 @@ enum class SpellAuraInterruptFlags2 : uint32
DEFINE_ENUM_FLAG(SpellAuraInterruptFlags2);
+enum class SpellModOp : uint8
+{
+ HealingAndDamage = 0,
+ Duration = 1,
+ Hate = 2,
+ PointsIndex0 = 3,
+ ProcCharges = 4,
+ Range = 5,
+ Radius = 6,
+ CritChance = 7,
+ Points = 8,
+ ResistPushback = 9,
+ ChangeCastTime = 10,
+ Cooldown = 11,
+ PointsIndex1 = 12,
+ TargetResistance = 13,
+ PowerCost0 = 14, // Used when SpellPowerEntry::PowerIndex == 0
+ CritDamageAndHealing = 15,
+ HitChance = 16,
+ ChainTargets = 17,
+ ProcChance = 18,
+ Period = 19,
+ ChainAmplitude = 20,
+ StartCooldown = 21,
+ PeriodicHealingAndDamage = 22,
+ PointsIndex2 = 23,
+ BonusCoefficient = 24,
+ TriggerDamage = 25, // NYI
+ ProcFrequency = 26,
+ Amplitude = 27,
+ DispelResistance = 28,
+ CrowdDamage = 29, // NYI
+ PowerCostOnMiss = 30,
+ Doses = 31,
+ PointsIndex3 = 32,
+ PointsIndex4 = 33,
+ PowerCost1 = 34, // Used when SpellPowerEntry::PowerIndex == 1
+ ChainJumpDistance = 35,
+ AreaTriggerMaxSummons = 36, // NYI
+ MaxAuraStacks = 37,
+ ProcCooldown = 38,
+ PowerCost2 = 39, // Used when SpellPowerEntry::PowerIndex == 2
+};
+
+#define MAX_SPELLMOD 40
+
+enum SpellValueMod : uint8
+{
+ SPELLVALUE_BASE_POINT0,
+ SPELLVALUE_BASE_POINT1,
+ SPELLVALUE_BASE_POINT2,
+ SPELLVALUE_BASE_POINT3,
+ SPELLVALUE_BASE_POINT4,
+ SPELLVALUE_BASE_POINT5,
+ SPELLVALUE_BASE_POINT6,
+ SPELLVALUE_BASE_POINT7,
+ SPELLVALUE_BASE_POINT8,
+ SPELLVALUE_BASE_POINT9,
+ SPELLVALUE_BASE_POINT10,
+ SPELLVALUE_BASE_POINT11,
+ SPELLVALUE_BASE_POINT12,
+ SPELLVALUE_BASE_POINT13,
+ SPELLVALUE_BASE_POINT14,
+ SPELLVALUE_BASE_POINT15,
+ SPELLVALUE_BASE_POINT16,
+ SPELLVALUE_BASE_POINT17,
+ SPELLVALUE_BASE_POINT18,
+ SPELLVALUE_BASE_POINT19,
+ SPELLVALUE_BASE_POINT20,
+ SPELLVALUE_BASE_POINT21,
+ SPELLVALUE_BASE_POINT22,
+ SPELLVALUE_BASE_POINT23,
+ SPELLVALUE_BASE_POINT24,
+ SPELLVALUE_BASE_POINT25,
+ SPELLVALUE_BASE_POINT26,
+ SPELLVALUE_BASE_POINT27,
+ SPELLVALUE_BASE_POINT28,
+ SPELLVALUE_BASE_POINT29,
+ SPELLVALUE_BASE_POINT30,
+ SPELLVALUE_BASE_POINT31,
+ SPELLVALUE_BASE_POINT_END,
+ 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_IGNORE_TARGET_CHECK = 0x00100000, //! Will ignore most target checks (mostly DBC target checks)
+ TRIGGERED_FULL_DEBUG_MASK = 0xFFFFFFFF
+};
+
+struct TC_GAME_API CastSpellExtraArgs
+{
+ CastSpellExtraArgs() = default;
+ 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(Difficulty castDifficulty) : CastDifficulty(castDifficulty) {}
+ 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& SetCastDifficulty(Difficulty castDifficulty) { CastDifficulty = castDifficulty; 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;
+ Difficulty CastDifficulty = Difficulty(0);
+ struct
+ {
+ public:
+ void AddMod(SpellValueMod mod, int32 val) { data.emplace_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;
+};
+
struct SpellCastVisual
{
uint32 SpellXSpellVisualID = 0;
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index d39479ccd5a..d7cfda76147 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -714,17 +714,14 @@ void Spell::EffectTriggerSpell(SpellEffIndex /*effIndex*/)
targets.SetUnitTarget(m_caster);
}
- CustomSpellValues values;
+ CastSpellExtraArgs args(m_originalCasterGUID);
// set basepoints for trigger with value effect
if (effectInfo->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*/)
@@ -761,18 +758,14 @@ void Spell::EffectTriggerMissileSpell(SpellEffIndex /*effIndex*/)
targets.SetUnitTarget(m_caster);
}
- CustomSpellValues values;
+ CastSpellExtraArgs args(m_originalCasterGUID);
// set basepoints for trigger with value effect
if (effectInfo->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*/)
@@ -804,32 +797,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 (effectInfo->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*/)
@@ -848,7 +837,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*/)
@@ -2048,11 +2037,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)
@@ -2809,7 +2800,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:
@@ -3076,7 +3067,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
@@ -3281,7 +3272,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;
}
@@ -3386,7 +3377,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();
}
@@ -3405,7 +3396,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)
{
@@ -3415,7 +3405,9 @@ 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);
}
}
break;
@@ -3808,7 +3800,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, effectInfo->TriggerSpell, &benefit, nullptr, nullptr, true);
+ CastSpellExtraArgs args(TRIGGERED_FULL_MASK);
+ args.SpellValueOverrides.AddMod(SPELLVALUE_BASE_POINT0, benefit);
+ m_caster->CastSpell(pet, effectInfo->TriggerSpell, args);
}
void Spell::EffectDismissPet(SpellEffIndex effIndex)
@@ -4172,7 +4166,7 @@ void Spell::EffectCharge(SpellEffIndex /*effIndex*/)
m_caster->Attack(unitTarget, true);
if (effectInfo->TriggerSpell)
- m_caster->CastSpell(unitTarget, effectInfo->TriggerSpell, true, nullptr, nullptr, m_originalCasterGUID);
+ m_caster->CastSpell(unitTarget, effectInfo->TriggerSpell, m_originalCasterGUID);
}
}
@@ -4197,7 +4191,7 @@ void Spell::EffectChargeDest(SpellEffIndex /*effIndex*/)
else if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
{
if (effectInfo->TriggerSpell)
- m_caster->CastSpell(destTarget->GetPositionX(), destTarget->GetPositionY(), destTarget->GetPositionZ(), effectInfo->TriggerSpell, true, nullptr, nullptr, m_originalCasterGUID);
+ m_caster->CastSpell(*destTarget, effectInfo->TriggerSpell, m_originalCasterGUID);
}
}
@@ -4485,7 +4479,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)
@@ -5276,8 +5274,10 @@ void Spell::EffectCastButtons(SpellEffIndex /*effIndex*/)
if (!spellInfo->HasAttribute(SPELL_ATTR9_SUMMON_PLAYER_TOTEM))
continue;
- TriggerCastFlags triggerFlags = TriggerCastFlags(TRIGGERED_IGNORE_GCD | TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_CAST_DIRECTLY | TRIGGERED_DONT_REPORT_CAST_ERROR);
- m_caster->CastSpell(m_caster, spellInfo, triggerFlags);
+ CastSpellExtraArgs args;
+ args.TriggerFlags = TriggerCastFlags(TRIGGERED_IGNORE_GCD | TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_CAST_DIRECTLY | TRIGGERED_DONT_REPORT_CAST_ERROR);
+ args.CastDifficulty = GetCastDifficulty();
+ m_caster->CastSpell(m_caster, spellInfo->Id, args);
}
}
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index 206e5a35cac..76b7aa34161 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -3455,14 +3455,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;
});