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; SpellOnCalcCritChanceFnType _onCalcCritChanceHandlerScript;
} }
public class TargetHook : EffectHook public class TargetHook : EffectHook
{ {
public TargetHook(uint effectIndex, Targets targetType, bool area, bool dest = false) : base(effectIndex) 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; 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() public bool IsInTargetHook()
{ {
switch ((SpellScriptHookType)m_currentScriptState) switch ((SpellScriptHookType)m_currentScriptState)
@@ -551,10 +560,40 @@ namespace Game.Scripting
public Unit GetExplTargetUnit() { return m_spell.m_targets.GetUnitTarget(); } 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 // 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 // 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: // 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 // 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; 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) void DoAllEffectOnTarget(TargetInfo target)
{ {
if (target == null || target.processed) if (target == null || target.processed)
@@ -6853,9 +6868,9 @@ namespace Game.Spells
if (m_caster.IsTypeId(TypeId.Player)) if (m_caster.IsTypeId(TypeId.Player))
{ {
int targetAmount = m_UniqueTargetInfo.Count; long targetAmount = GetUnitTargetCountForEffect(effect.EffectIndex);
if (targetAmount > 20) 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) // Meteor like spells (divided damage to targets)
if (m_spellInfo.HasAttribute(SpellCustomAttributes.ShareDamage)) 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 // divide to all targets
if (count != 0) if (count != 0)
damage /= count; damage /= (int)count;
} }
switch (m_spellInfo.SpellFamilyName) switch (m_spellInfo.SpellFamilyName)