diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Spells/Spell.cpp | 106 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.h | 2 |
2 files changed, 78 insertions, 30 deletions
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index fd354cdcfb1..8304e18df69 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -4427,6 +4427,13 @@ void Spell::finish(SpellCastResult result) Unit::ProcSkillsAndAuras(unitCaster, nullptr, PROC_FLAG_CAST_ENDED, PROC_FLAG_NONE, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_NONE, PROC_HIT_NONE, this, nullptr, nullptr); + if (IsEmpowerSpell()) + { + // Empower spells trigger gcd at the end of cast instead of at start + if (SpellInfo const* gcd = sSpellMgr->GetSpellInfo(SPELL_EMPOWER_HARDCODED_GCD, DIFFICULTY_NONE)) + unitCaster->GetSpellHistory()->AddGlobalCooldown(gcd, Milliseconds(gcd->StartRecoveryTime)); + } + if (result != SPELL_CAST_OK) { // on failure (or manual cancel) send TraitConfigCommitFailed to revert talent UI saved config selection @@ -4435,7 +4442,10 @@ void Spell::finish(SpellCastResult result) m_caster->ToPlayer()->SendDirectMessage(WorldPackets::Traits::TraitConfigCommitFailed(traitConfig->ID).Write()); if (IsEmpowerSpell()) + { unitCaster->GetSpellHistory()->ResetCooldown(m_spellInfo->Id, true); + RefundPower(); + } return; } @@ -4466,13 +4476,6 @@ void Spell::finish(SpellCastResult result) // Stop Attack for some spells if (m_spellInfo->HasAttribute(SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT)) unitCaster->AttackStop(); - - if (IsEmpowerSpell()) - { - // Empower spells trigger gcd at the end of cast instead of at start - if (SpellInfo const* gcd = sSpellMgr->GetSpellInfo(SPELL_EMPOWER_HARDCODED_GCD, DIFFICULTY_NONE)) - unitCaster->GetSpellHistory()->AddGlobalCooldown(gcd, Milliseconds(gcd->StartRecoveryTime)); - } } template<class T> @@ -5537,30 +5540,27 @@ void Spell::TakePower() return; } + bool hit = true; + if (unitCaster->GetTypeId() == TYPEID_PLAYER) + { + if (m_spellInfo->HasAttribute(SPELL_ATTR1_DISCOUNT_POWER_ON_MISS)) + { + ObjectGuid targetGUID = m_targets.GetUnitTargetGUID(); + if (!targetGUID.IsEmpty()) + hit = std::ranges::any_of(m_UniqueTargetInfo, [&](TargetInfo const& targetInfo) { return targetInfo.TargetGUID == targetGUID && targetInfo.MissCondition == SPELL_MISS_NONE; }); + } + } + for (SpellPowerCost& cost : m_powerCost) { - Powers powerType = Powers(cost.Power); - bool hit = true; - if (unitCaster->GetTypeId() == TYPEID_PLAYER) + if (!hit) { - if (m_spellInfo->HasAttribute(SPELL_ATTR1_DISCOUNT_POWER_ON_MISS)) - { - ObjectGuid targetGUID = m_targets.GetUnitTargetGUID(); - if (!targetGUID.IsEmpty()) - { - auto ihit = std::find_if(std::begin(m_UniqueTargetInfo), std::end(m_UniqueTargetInfo), [&](TargetInfo const& targetInfo) { return targetInfo.TargetGUID == targetGUID && targetInfo.MissCondition != SPELL_MISS_NONE; }); - if (ihit != std::end(m_UniqueTargetInfo)) - { - hit = false; - //lower spell cost on fail (by talent aura) - if (Player* modOwner = unitCaster->GetSpellModOwner()) - modOwner->ApplySpellMod(m_spellInfo, SpellModOp::PowerCostOnMiss, cost.Amount); - } - } - } + //lower spell cost on fail (by talent aura) + if (Player* modOwner = unitCaster->GetSpellModOwner()) + modOwner->ApplySpellMod(m_spellInfo, SpellModOp::PowerCostOnMiss, cost.Amount); } - if (powerType == POWER_RUNES) + if (cost.Power == POWER_RUNES) { TakeRunePower(hit); continue; @@ -5570,19 +5570,52 @@ void Spell::TakePower() continue; // health as power used - if (powerType == POWER_HEALTH) + if (cost.Power == POWER_HEALTH) { unitCaster->ModifyHealth(-cost.Amount); continue; } - if (powerType >= MAX_POWERS) + unitCaster->ModifyPower(cost.Power, -cost.Amount); + } +} + +void Spell::RefundPower() +{ + // GameObjects don't use power + Unit* unitCaster = m_caster->ToUnit(); + if (!unitCaster) + return; + + if (m_CastItem || m_triggeredByAuraSpell) + return; + + //Don't take power if the spell is cast while .cheat power is enabled. + if (unitCaster->GetTypeId() == TYPEID_PLAYER) + { + if (unitCaster->ToPlayer()->GetCommandStatus(CHEAT_POWER)) + return; + } + + for (SpellPowerCost& cost : m_powerCost) + { + if (cost.Power == POWER_RUNES) + { + RefundRunePower(); + continue; + } + + if (!cost.Amount) + continue; + + // health as power used + if (cost.Power == POWER_HEALTH) { - TC_LOG_ERROR("spells", "Spell::TakePower: Unknown power type '{}'", powerType); + unitCaster->ModifyHealth(cost.Amount); continue; } - unitCaster->ModifyPower(powerType, -cost.Amount); + unitCaster->ModifyPower(cost.Power, cost.Amount); } } @@ -5637,6 +5670,19 @@ void Spell::TakeRunePower(bool didHit) } } +void Spell::RefundRunePower() +{ + if (m_caster->GetTypeId() != TYPEID_PLAYER || m_caster->ToPlayer()->GetClass() != CLASS_DEATH_KNIGHT) + return; + + Player* player = m_caster->ToPlayer(); + + // restore old rune state + for (int32 i = 0; i < player->GetMaxPower(POWER_RUNES); ++i) + if (m_runesState & (1 << i)) + player->SetRuneCooldown(i, 0); +} + void Spell::TakeReagents() { if (m_caster->GetTypeId() != TYPEID_PLAYER) diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 8f25f5844dd..02f10b26413 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -478,8 +478,10 @@ class TC_GAME_API Spell void cast(bool skipCheck = false); void finish(SpellCastResult result = SPELL_CAST_OK); void TakePower(); + void RefundPower(); void TakeRunePower(bool didHit); + void RefundRunePower(); void TakeReagents(); void TakeCastItem(); |