Core/Spells: Expose number of targets selected for each spell effect to scripts to allow implementing spells that do something depending on number of targets hit

Port From (https://github.com/TrinityCore/TrinityCore/commit/1a7779a6e6464d9bc5b367e02820213edd60f704)
This commit is contained in:
hondacrx
2021-05-13 20:35:45 -04:00
parent 031cde7cb2
commit 1509cdfded
3 changed files with 61 additions and 7 deletions
+42 -3
View File
@@ -257,7 +257,7 @@ namespace Game.Scripting
SpellOnCalcCritChanceFnType _onCalcCritChanceHandlerScript;
}
public class TargetHook : EffectHook
{
public TargetHook(uint effectIndex, Targets targetType, bool area, bool dest = false) : base(effectIndex)
@@ -430,6 +430,15 @@ namespace Game.Scripting
{
return m_currentScriptState == (byte)SpellScriptHookType.CheckCast;
}
bool IsAfterTargetSelectionPhase()
{
return IsInHitPhase()
|| m_currentScriptState == (byte)SpellScriptHookType.OnCast
|| m_currentScriptState == (byte)SpellScriptHookType.AfterCast
|| m_currentScriptState == (byte)SpellScriptHookType.CalcCritChance;
}
public bool IsInTargetHook()
{
switch ((SpellScriptHookType)m_currentScriptState)
@@ -551,10 +560,40 @@ namespace Game.Scripting
public Unit GetExplTargetUnit() { return m_spell.m_targets.GetUnitTarget(); }
// returns: GameObject which was selected as an explicit spell target or null if there's no target
GameObject GetExplTargetGObj() { return m_spell.m_targets.GetGOTarget(); }
public GameObject GetExplTargetGObj() { return m_spell.m_targets.GetGOTarget(); }
// returns: Item which was selected as an explicit spell target or null if there's no target
Item GetExplTargetItem() { return m_spell.m_targets.GetItemTarget(); }
public Item GetExplTargetItem() { return m_spell.m_targets.GetItemTarget(); }
public long GetUnitTargetCountForEffect(uint effect)
{
if (!IsAfterTargetSelectionPhase())
{
Log.outError(LogFilter.Scripts, $"Script: `{m_scriptName}` Spell: `{m_scriptSpellId}`: function SpellScript.GetUnitTargetCountForEffect was called, but function has no effect in current hook! (spell has not selected targets yet)");
return 0;
}
return m_spell.GetUnitTargetCountForEffect(effect);
}
public long GetGameObjectTargetCountForEffect(uint effect)
{
if (!IsAfterTargetSelectionPhase())
{
Log.outError(LogFilter.Scripts, $"Script: `{m_scriptName}` Spell: `{m_scriptSpellId}`: function SpellScript.GetGameObjectTargetCountForEffect was called, but function has no effect in current hook! (spell has not selected targets yet)");
return 0;
}
return m_spell.GetGameObjectTargetCountForEffect(effect);
}
public long GetItemTargetCountForEffect(uint effect)
{
if (!IsAfterTargetSelectionPhase())
{
Log.outError(LogFilter.Scripts, $"Script: `{m_scriptName}` Spell: `{m_scriptSpellId}`: function SpellScript.GetItemTargetCountForEffect was called, but function has no effect in current hook! (spell has not selected targets yet)");
return 0;
}
return m_spell.GetItemTargetCountForEffect(effect);
}
// 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
+17 -2
View File
@@ -1758,6 +1758,21 @@ namespace Game.Spells
m_destTargets[effIndex] = dest;
}
public long GetUnitTargetCountForEffect(uint effect)
{
return m_UniqueTargetInfo.Count(targetInfo => (targetInfo.effectMask & (1 << (int)effect)) != 0);
}
public long GetGameObjectTargetCountForEffect(uint effect)
{
return m_UniqueGOTargetInfo.Count(targetInfo => (targetInfo.effectMask & (1 << (int)effect)) != 0);
}
public long GetItemTargetCountForEffect(uint effect)
{
return m_UniqueItemInfo.Count(targetInfo => (targetInfo.effectMask & (1 << (int)effect)) != 0);
}
void DoAllEffectOnTarget(TargetInfo target)
{
if (target == null || target.processed)
@@ -6853,9 +6868,9 @@ namespace Game.Spells
if (m_caster.IsTypeId(TypeId.Player))
{
int targetAmount = m_UniqueTargetInfo.Count;
long targetAmount = GetUnitTargetCountForEffect(effect.EffectIndex);
if (targetAmount > 20)
m_damage = m_damage * 20 / targetAmount;
m_damage = (int)(m_damage * 20 / targetAmount);
}
}
}
+2 -2
View File
@@ -153,11 +153,11 @@ namespace Game.Spells
// Meteor like spells (divided damage to targets)
if (m_spellInfo.HasAttribute(SpellCustomAttributes.ShareDamage))
{
int count = m_UniqueTargetInfo.Count(targetInfo => Convert.ToBoolean(targetInfo.effectMask & (1 << (int)effIndex)));
long count = GetUnitTargetCountForEffect(effIndex);
// divide to all targets
if (count != 0)
damage /= count;
damage /= (int)count;
}
switch (m_spellInfo.SpellFamilyName)