aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Spells/Spell.cpp26
-rw-r--r--src/server/game/Spells/Spell.h4
-rw-r--r--src/server/game/Spells/SpellEffects.cpp12
-rw-r--r--src/server/game/Spells/SpellScript.cpp41
-rw-r--r--src/server/game/Spells/SpellScript.h9
5 files changed, 77 insertions, 15 deletions
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 5f024a813ea..e523ce7c111 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -2362,6 +2362,30 @@ void Spell::AddDestTarget(SpellDestination const& dest, uint32 effIndex)
m_destTargets[effIndex] = dest;
}
+int64 Spell::GetUnitTargetCountForEffect(SpellEffIndex effect) const
+{
+ return std::count_if(m_UniqueTargetInfo.begin(), m_UniqueTargetInfo.end(), [effect](TargetInfo const& targetInfo)
+ {
+ return targetInfo.EffectMask & (1 << effect);
+ });
+}
+
+int64 Spell::GetGameObjectTargetCountForEffect(SpellEffIndex effect) const
+{
+ return std::count_if(m_UniqueGOTargetInfo.begin(), m_UniqueGOTargetInfo.end(), [effect](GOTargetInfo const& targetInfo)
+ {
+ return targetInfo.EffectMask & (1 << effect);
+ });
+}
+
+int64 Spell::GetItemTargetCountForEffect(SpellEffIndex effect) const
+{
+ return std::count_if(m_UniqueItemInfo.begin(), m_UniqueItemInfo.end(), [effect](ItemTargetInfo const& targetInfo)
+ {
+ return targetInfo.EffectMask & (1 << effect);
+ });
+}
+
void Spell::TargetInfo::PreprocessTarget(Spell* spell)
{
Unit* unit = spell->m_caster->GetGUID() == TargetGUID ? spell->m_caster->ToUnit() : ObjectAccessor::GetUnit(*spell->m_caster, TargetGUID);
@@ -7784,7 +7808,7 @@ void Spell::DoEffectOnLaunchTarget(TargetInfo& targetInfo, float multiplier, Spe
if (m_originalCaster->GetTypeId() == TYPEID_PLAYER)
{
// cap damage of player AOE
- uint32 targetAmount = m_UniqueTargetInfo.size();
+ int64 targetAmount = GetUnitTargetCountForEffect(spellEffectInfo.EffectIndex);
if (targetAmount > 10)
m_damage = m_damage * 10 / targetAmount;
}
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index fe8b1a54670..f14e83c1677 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -466,6 +466,10 @@ class TC_GAME_API Spell
void CallScriptOnResistAbsorbCalculateHandlers(DamageInfo const& damageInfo, uint32& resistAmount, int32& absorbAmount);
+ int64 GetUnitTargetCountForEffect(SpellEffIndex effect) const;
+ int64 GetGameObjectTargetCountForEffect(SpellEffIndex effect) const;
+ int64 GetItemTargetCountForEffect(SpellEffIndex effect) const;
+
protected:
bool HasGlobalCooldown() const;
void TriggerGlobalCooldown();
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 6b4192efaef..77387b17798 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -332,18 +332,8 @@ void Spell::EffectSchoolDMG()
// Meteor like spells (divided damage to targets)
if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_SHARE_DAMAGE))
{
- uint32 count = 0;
- for (auto ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
- {
- if (ihit->MissCondition != SPELL_MISS_NONE)
- continue;
-
- if (ihit->EffectMask & (1 << effectInfo->EffectIndex))
- ++count;
- }
-
// divide to all targets
- if (count)
+ if (int64 count = GetUnitTargetCountForEffect(SpellEffIndex(effectInfo->EffectIndex)))
damage /= count;
}
diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp
index 66d02bb104e..874427e77ff 100644
--- a/src/server/game/Spells/SpellScript.cpp
+++ b/src/server/game/Spells/SpellScript.cpp
@@ -408,6 +408,14 @@ bool SpellScript::IsInCheckCastHook() const
{
return m_currentScriptState == SPELL_SCRIPT_HOOK_CHECK_CAST;
}
+
+bool SpellScript::IsAfterTargetSelectionPhase() const
+{
+ return IsInHitPhase()
+ || m_currentScriptState == SPELL_SCRIPT_HOOK_ON_CAST
+ || m_currentScriptState == SPELL_SCRIPT_HOOK_AFTER_CAST;
+}
+
bool SpellScript::IsInTargetHook() const
{
switch (m_currentScriptState)
@@ -509,6 +517,39 @@ Item* SpellScript::GetExplTargetItem() const
return m_spell->m_targets.GetItemTarget();
}
+int64 SpellScript::GetUnitTargetCountForEffect(SpellEffIndex effect) const
+{
+ if (!IsAfterTargetSelectionPhase())
+ {
+ TC_LOG_ERROR("scripts", "Script: `%s` Spell: `%u`: function SpellScript::GetUnitTargetCountForEffect was called, but function has no effect in current hook! (spell has not selected targets yet)",
+ m_scriptName->c_str(), m_scriptSpellId);
+ return 0;
+ }
+ return m_spell->GetUnitTargetCountForEffect(effect);
+}
+
+int64 SpellScript::GetGameObjectTargetCountForEffect(SpellEffIndex effect) const
+{
+ if (!IsAfterTargetSelectionPhase())
+ {
+ TC_LOG_ERROR("scripts", "Script: `%s` Spell: `%u`: function SpellScript::GetGameObjectTargetCountForEffect was called, but function has no effect in current hook! (spell has not selected targets yet)",
+ m_scriptName->c_str(), m_scriptSpellId);
+ return 0;
+ }
+ return m_spell->GetGameObjectTargetCountForEffect(effect);
+}
+
+int64 SpellScript::GetItemTargetCountForEffect(SpellEffIndex effect) const
+{
+ if (!IsAfterTargetSelectionPhase())
+ {
+ TC_LOG_ERROR("scripts", "Script: `%s` Spell: `%u`: function SpellScript::GetItemTargetCountForEffect was called, but function has no effect in current hook! (spell has not selected targets yet)",
+ m_scriptName->c_str(), m_scriptSpellId);
+ return 0;
+ }
+ return m_spell->GetItemTargetCountForEffect(effect);
+}
+
Unit* SpellScript::GetHitUnit() const
{
if (!IsInTargetHook())
diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h
index 6b399c3a59e..9c8e61a9b00 100644
--- a/src/server/game/Spells/SpellScript.h
+++ b/src/server/game/Spells/SpellScript.h
@@ -194,9 +194,6 @@ enum SpellScriptHookType
#define HOOK_SPELL_HIT_START SPELL_SCRIPT_HOOK_EFFECT_HIT
#define HOOK_SPELL_HIT_END SPELL_SCRIPT_HOOK_AFTER_HIT + 1
-#define HOOK_SPELL_START SPELL_SCRIPT_HOOK_EFFECT
-#define HOOK_SPELL_END SPELL_SCRIPT_HOOK_CHECK_CAST + 1
-#define HOOK_SPELL_COUNT HOOK_SPELL_END - HOOK_SPELL_START
class TC_GAME_API SpellScript : public _SpellScript
{
@@ -343,6 +340,7 @@ class TC_GAME_API SpellScript : public _SpellScript
void _PrepareScriptCall(SpellScriptHookType hookType);
void _FinishScriptCall();
bool IsInCheckCastHook() const;
+ bool IsAfterTargetSelectionPhase() const;
bool IsInTargetHook() const;
bool IsInModifiableHook() const;
bool IsInHitPhase() const;
@@ -469,6 +467,11 @@ class TC_GAME_API SpellScript : public _SpellScript
// returns: Item which was selected as an explicit spell target or NULL if there's no target
Item* GetExplTargetItem() const;
+ // methods usable only after spell targets have been fully selected
+ int64 GetUnitTargetCountForEffect(SpellEffIndex effect) const;
+ int64 GetGameObjectTargetCountForEffect(SpellEffIndex effect) const;
+ int64 GetItemTargetCountForEffect(SpellEffIndex effect) const;
+
// methods useable only during spell hit on target, or during spell launch on target:
// returns: target of current effect if it was Unit otherwise NULL
Unit* GetHitUnit() const;