aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Miscellaneous/SharedDefines.h2
-rw-r--r--src/server/game/Miscellaneous/enuminfo_SharedDefines.cpp2
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp11
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.cpp13
-rw-r--r--src/server/game/Spells/Spell.cpp4
-rw-r--r--src/server/game/Spells/SpellEffects.cpp6
6 files changed, 24 insertions, 14 deletions
diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h
index 031adca7f87..64456094a5a 100644
--- a/src/server/game/Miscellaneous/SharedDefines.h
+++ b/src/server/game/Miscellaneous/SharedDefines.h
@@ -688,7 +688,7 @@ enum SpellAttr6 : uint32
SPELL_ATTR6_NOT_AN_ATTACK = 0x00000004, /*NYI*/ // TITLE Not an Attack
SPELL_ATTR6_CAN_ASSIST_IMMUNE_PC = 0x00000008, // TITLE Can Assist Immune PC
SPELL_ATTR6_IGNORE_FOR_MOD_TIME_RATE = 0x00000010, /*NYI, time rate not implemented*/ // TITLE Ignore For Mod Time Rate
- SPELL_ATTR6_DO_NOT_CONSUME_RESOURCES = 0x00000020, // TITLE Do Not Consume Resources
+ SPELL_ATTR6_DO_NOT_CONSUME_RESOURCES = 0x00000020, // TITLE Do Not Consume Resources DESCRIPTION Requires power/reagents to cast but doesn't consume them
SPELL_ATTR6_FLOATING_COMBAT_TEXT_ON_CAST = 0x00000040, // TITLE Floating Combat Text On Cast (client only)
SPELL_ATTR6_AURA_IS_WEAPON_PROC = 0x00000080, // TITLE Aura Is Weapon Proc
SPELL_ATTR6_DO_NOT_CHAIN_TO_CROWD_CONTROLLED_TARGETS = 0x00000100, // TITLE Do Not Chain To Crowd-Controlled Targets DESCRIPTION Implicit targeting (chaining and area targeting) will not impact crowd controlled targets
diff --git a/src/server/game/Miscellaneous/enuminfo_SharedDefines.cpp b/src/server/game/Miscellaneous/enuminfo_SharedDefines.cpp
index 76b0301b3c8..070e30749f5 100644
--- a/src/server/game/Miscellaneous/enuminfo_SharedDefines.cpp
+++ b/src/server/game/Miscellaneous/enuminfo_SharedDefines.cpp
@@ -1059,7 +1059,7 @@ TC_API_EXPORT EnumText EnumUtils<SpellAttr6>::ToString(SpellAttr6 value)
case SPELL_ATTR6_NOT_AN_ATTACK: return { "SPELL_ATTR6_NOT_AN_ATTACK", "Not an Attack", "" };
case SPELL_ATTR6_CAN_ASSIST_IMMUNE_PC: return { "SPELL_ATTR6_CAN_ASSIST_IMMUNE_PC", "Can Assist Immune PC", "" };
case SPELL_ATTR6_IGNORE_FOR_MOD_TIME_RATE: return { "SPELL_ATTR6_IGNORE_FOR_MOD_TIME_RATE", "Ignore For Mod Time Rate", "" };
- case SPELL_ATTR6_DO_NOT_CONSUME_RESOURCES: return { "SPELL_ATTR6_DO_NOT_CONSUME_RESOURCES", "Do Not Consume Resources", "" };
+ case SPELL_ATTR6_DO_NOT_CONSUME_RESOURCES: return { "SPELL_ATTR6_DO_NOT_CONSUME_RESOURCES", "Do Not Consume Resources", "Requires power/reagents to cast but doesn't consume them" };
case SPELL_ATTR6_FLOATING_COMBAT_TEXT_ON_CAST: return { "SPELL_ATTR6_FLOATING_COMBAT_TEXT_ON_CAST", "Floating Combat Text On Cast (client only)", "" };
case SPELL_ATTR6_AURA_IS_WEAPON_PROC: return { "SPELL_ATTR6_AURA_IS_WEAPON_PROC", "Aura Is Weapon Proc", "" };
case SPELL_ATTR6_DO_NOT_CHAIN_TO_CROWD_CONTROLLED_TARGETS: return { "SPELL_ATTR6_DO_NOT_CHAIN_TO_CROWD_CONTROLLED_TARGETS", "Do Not Chain To Crowd-Controlled Targets", "Implicit targeting (chaining and area targeting) will not impact crowd controlled targets" };
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index e2717caf061..5969e4bd37e 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -5494,7 +5494,10 @@ void AuraEffect::HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster)
{
if (Unit* triggerCaster = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo) ? caster : target)
{
- triggerCaster->CastSpell(target, triggerSpellId, this);
+ triggerCaster->CastSpell(target, triggerSpellId, CastSpellExtraArgsInit{
+ .TriggerFlags = TRIGGERED_FULL_MASK & ~(TRIGGERED_IGNORE_POWER_COST | TRIGGERED_IGNORE_REAGENT_COST),
+ .TriggeringAura = this
+ });
TC_LOG_DEBUG("spells.aura.effect", "AuraEffect::HandlePeriodicTriggerSpellAuraTick: Spell {} Trigger {}", GetId(), triggeredSpellInfo->Id);
}
}
@@ -5516,6 +5519,7 @@ void AuraEffect::HandlePeriodicTriggerSpellWithValueAuraTick(Unit* target, Unit*
if (Unit* triggerCaster = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo) ? caster : target)
{
CastSpellExtraArgs args(this);
+ args.SetTriggerFlags(TRIGGERED_FULL_MASK & ~(TRIGGERED_IGNORE_POWER_COST | TRIGGERED_IGNORE_REAGENT_COST));
for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
args.AddSpellMod(SpellValueMod(SPELLVALUE_BASE_POINT0 + i), GetAmount());
triggerCaster->CastSpell(target, triggerSpellId, args);
@@ -6072,7 +6076,9 @@ void AuraEffect::HandleProcTriggerSpellAuraProc(AuraApplication* aurApp, ProcEve
if (SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(triggerSpellId, GetBase()->GetCastDifficulty()))
{
TC_LOG_DEBUG("spells.aura.effect", "AuraEffect::HandleProcTriggerSpellAuraProc: Triggering spell {} from aura {} proc", triggeredSpellInfo->Id, GetId());
- triggerCaster->CastSpell(triggerTarget, triggeredSpellInfo->Id, CastSpellExtraArgs(this).SetTriggeringSpell(eventInfo.GetProcSpell()));
+ triggerCaster->CastSpell(triggerTarget, triggeredSpellInfo->Id, CastSpellExtraArgs(this)
+ .SetTriggeringSpell(eventInfo.GetProcSpell())
+ .SetTriggerFlags(TRIGGERED_FULL_MASK & ~(TRIGGERED_IGNORE_POWER_COST | TRIGGERED_IGNORE_REAGENT_COST)));
}
else if (triggerSpellId && GetAuraType() != SPELL_AURA_DUMMY)
TC_LOG_ERROR("spells.aura.effect.nospell","AuraEffect::HandleProcTriggerSpellAuraProc: Spell {} has non-existent spell {} in EffectTriggered[{}] and is therefore not triggered.", GetId(), triggerSpellId, GetEffIndex());
@@ -6095,6 +6101,7 @@ void AuraEffect::HandleProcTriggerSpellWithValueAuraProc(AuraApplication* aurApp
if (SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(triggerSpellId, GetBase()->GetCastDifficulty()))
{
CastSpellExtraArgs args(this);
+ args.SetTriggerFlags(TRIGGERED_FULL_MASK & ~(TRIGGERED_IGNORE_POWER_COST | TRIGGERED_IGNORE_REAGENT_COST));
args.SetTriggeringSpell(eventInfo.GetProcSpell());
args.AddSpellMod(SPELLVALUE_BASE_POINT0, GetAmount());
triggerCaster->CastSpell(triggerTarget, triggerSpellId, args);
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index 8a79f88b68e..b11f603d481 100644
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -471,12 +471,15 @@ m_isRemoved(false), m_isSingleTarget(false), m_isUsingCharges(false), m_dropEven
m_procCooldown(TimePoint::min()),
m_lastProcAttemptTime(GameTime::Now() - Seconds(10)), m_lastProcSuccessTime(GameTime::Now() - Seconds(120)), m_scriptRef(this, NoopAuraDeleter())
{
- for (SpellPowerEntry const* power : m_spellInfo->PowerCosts)
- if (power && (power->ManaPerSecond != 0 || power->PowerPctPerSecond > 0.0f))
- m_periodicCosts.push_back(power);
+ if (!m_spellInfo->HasAttribute(SPELL_ATTR6_DO_NOT_CONSUME_RESOURCES))
+ {
+ for (SpellPowerEntry const* power : m_spellInfo->PowerCosts)
+ if (power && (power->ManaPerSecond != 0 || power->PowerPctPerSecond > 0.0f))
+ m_periodicCosts.push_back(power);
- if (!m_periodicCosts.empty())
- m_timeCla = 1 * IN_MILLISECONDS;
+ if (!m_periodicCosts.empty())
+ m_timeCla = 1 * IN_MILLISECONDS;
+ }
m_maxDuration = CalcMaxDuration(createInfo.Caster);
m_duration = m_maxDuration;
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 6126d7fc635..fb4e5a00c1e 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -5416,7 +5416,7 @@ void Spell::TakePower()
if (!unitCaster)
return;
- if (m_CastItem || m_triggeredByAuraSpell)
+ if (m_CastItem || m_spellInfo->HasAttribute(SPELL_ATTR6_DO_NOT_CONSUME_RESOURCES))
return;
//Don't take power if the spell is cast while .cheat power is enabled.
@@ -5611,7 +5611,7 @@ void Spell::TakeReagents()
return;
// do not take reagents for these item casts
- if (m_CastItem && m_CastItem->GetTemplate()->HasFlag(ITEM_FLAG_NO_REAGENT_COST))
+ if ((m_CastItem && m_CastItem->GetTemplate()->HasFlag(ITEM_FLAG_NO_REAGENT_COST)) || m_spellInfo->HasAttribute(SPELL_ATTR6_DO_NOT_CONSUME_RESOURCES))
return;
Player* p_caster = m_caster->ToPlayer();
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 392393d9d9d..30f75c86cb8 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -694,7 +694,7 @@ void Spell::EffectTriggerSpell()
targets.Update(caster); // refresh pointers stored in targets
// original caster guid only for GO cast
- CastSpellExtraArgs args(TRIGGERED_FULL_MASK);
+ CastSpellExtraArgs args(TRIGGERED_FULL_MASK & ~(TRIGGERED_IGNORE_POWER_COST | TRIGGERED_IGNORE_REAGENT_COST));
args.SetOriginalCaster(originalCaster);
args.OriginalCastId = originalCastId;
args.OriginalCastItemLevel = itemLevel;
@@ -763,7 +763,7 @@ void Spell::EffectTriggerMissileSpell()
targets.SetGOTarget(go);
}
- CastSpellExtraArgs args(TRIGGERED_FULL_MASK);
+ CastSpellExtraArgs args(TRIGGERED_FULL_MASK & ~(TRIGGERED_IGNORE_POWER_COST | TRIGGERED_IGNORE_REAGENT_COST));
args.SetOriginalCaster(m_originalCasterGUID);
args.SetTriggeringSpell(this);
args.SetCustomArg(m_customArg);
@@ -837,7 +837,7 @@ void Spell::EffectForceCast()
return;
}
- CastSpellExtraArgs args(TRIGGERED_FULL_MASK);
+ CastSpellExtraArgs args(TRIGGERED_FULL_MASK & ~(TRIGGERED_IGNORE_POWER_COST | TRIGGERED_IGNORE_REAGENT_COST));
args.SetTriggeringSpell(this);
if (effectInfo->Effect == SPELL_EFFECT_FORCE_CAST_WITH_VALUE)
for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)