Core/Spells: Cleanup spell effects

Port From (https://github.com/TrinityCore/TrinityCore/commit/8a4e1119ac21e2d1112d1717337597fe073e495f)
This commit is contained in:
hondacrx
2021-09-08 17:40:50 -04:00
parent 2af5cad79f
commit 5c4a7511ff
41 changed files with 2378 additions and 1987 deletions
@@ -2087,7 +2087,7 @@ namespace Framework.Constants
public enum SpellEffectName public enum SpellEffectName
{ {
Any = -1, Any = -1,
Null = 0, None = 0,
Instakill = 1, Instakill = 1,
SchoolDamage = 2, SchoolDamage = 2,
Dummy = 3, Dummy = 3,
+38 -45
View File
@@ -345,13 +345,9 @@ namespace Game.AI
} }
else else
{ {
foreach (SpellEffectInfo effect in spellInfo.GetEffects()) foreach (var spellEffectInfo in spellInfo.GetEffects())
{ {
if (effect == null) var targetType = spellEffectInfo.TargetA.GetTarget();
continue;
var targetType = effect.TargetA.GetTarget();
if (targetType == Targets.UnitTargetEnemy || targetType == Targets.DestTargetEnemy) if (targetType == Targets.UnitTargetEnemy || targetType == Targets.DestTargetEnemy)
{ {
if (AIInfo.target < AITarget.Victim) if (AIInfo.target < AITarget.Victim)
@@ -363,7 +359,7 @@ namespace Game.AI
AIInfo.target = AITarget.Enemy; AIInfo.target = AITarget.Enemy;
} }
if (effect.Effect == SpellEffectName.ApplyAura) if (spellEffectInfo.IsEffect(SpellEffectName.ApplyAura))
{ {
if (targetType == Targets.UnitTargetEnemy) if (targetType == Targets.UnitTargetEnemy)
{ {
@@ -384,73 +380,70 @@ namespace Game.AI
AIInfo.Effects = 0; AIInfo.Effects = 0;
AIInfo.Targets = 0; AIInfo.Targets = 0;
foreach (SpellEffectInfo effect in spellInfo.GetEffects()) foreach (var spellEffectInfo in spellInfo.GetEffects())
{ {
if (effect == null)
continue;
// Spell targets self. // Spell targets self.
if (effect.TargetA.GetTarget() == Targets.UnitCaster) if (spellEffectInfo.TargetA.GetTarget() == Targets.UnitCaster)
AIInfo.Targets |= 1 << ((int)SelectTargetType.Self - 1); AIInfo.Targets |= 1 << ((int)SelectTargetType.Self - 1);
// Spell targets a single enemy. // Spell targets a single enemy.
if (effect.TargetA.GetTarget() == Targets.UnitTargetEnemy || if (spellEffectInfo.TargetA.GetTarget() == Targets.UnitTargetEnemy ||
effect.TargetA.GetTarget() == Targets.DestTargetEnemy) spellEffectInfo.TargetA.GetTarget() == Targets.DestTargetEnemy)
AIInfo.Targets |= 1 << ((int)SelectTargetType.SingleEnemy - 1); AIInfo.Targets |= 1 << ((int)SelectTargetType.SingleEnemy - 1);
// Spell targets AoE at enemy. // Spell targets AoE at enemy.
if (effect.TargetA.GetTarget() == Targets.UnitSrcAreaEnemy || if (spellEffectInfo.TargetA.GetTarget() == Targets.UnitSrcAreaEnemy ||
effect.TargetA.GetTarget() == Targets.UnitDestAreaEnemy || spellEffectInfo.TargetA.GetTarget() == Targets.UnitDestAreaEnemy ||
effect.TargetA.GetTarget() == Targets.SrcCaster || spellEffectInfo.TargetA.GetTarget() == Targets.SrcCaster ||
effect.TargetA.GetTarget() == Targets.DestDynobjEnemy) spellEffectInfo.TargetA.GetTarget() == Targets.DestDynobjEnemy)
AIInfo.Targets |= 1 << ((int)SelectTargetType.AoeEnemy - 1); AIInfo.Targets |= 1 << ((int)SelectTargetType.AoeEnemy - 1);
// Spell targets an enemy. // Spell targets an enemy.
if (effect.TargetA.GetTarget() == Targets.UnitTargetEnemy || if (spellEffectInfo.TargetA.GetTarget() == Targets.UnitTargetEnemy ||
effect.TargetA.GetTarget() == Targets.DestTargetEnemy || spellEffectInfo.TargetA.GetTarget() == Targets.DestTargetEnemy ||
effect.TargetA.GetTarget() == Targets.UnitSrcAreaEnemy || spellEffectInfo.TargetA.GetTarget() == Targets.UnitSrcAreaEnemy ||
effect.TargetA.GetTarget() == Targets.UnitDestAreaEnemy || spellEffectInfo.TargetA.GetTarget() == Targets.UnitDestAreaEnemy ||
effect.TargetA.GetTarget() == Targets.SrcCaster || spellEffectInfo.TargetA.GetTarget() == Targets.SrcCaster ||
effect.TargetA.GetTarget() == Targets.DestDynobjEnemy) spellEffectInfo.TargetA.GetTarget() == Targets.DestDynobjEnemy)
AIInfo.Targets |= 1 << ((int)SelectTargetType.AnyEnemy - 1); AIInfo.Targets |= 1 << ((int)SelectTargetType.AnyEnemy - 1);
// Spell targets a single friend (or self). // Spell targets a single friend (or self).
if (effect.TargetA.GetTarget() == Targets.UnitCaster || if (spellEffectInfo.TargetA.GetTarget() == Targets.UnitCaster ||
effect.TargetA.GetTarget() == Targets.UnitTargetAlly || spellEffectInfo.TargetA.GetTarget() == Targets.UnitTargetAlly ||
effect.TargetA.GetTarget() == Targets.UnitTargetParty) spellEffectInfo.TargetA.GetTarget() == Targets.UnitTargetParty)
AIInfo.Targets |= 1 << ((int)SelectTargetType.SingleFriend - 1); AIInfo.Targets |= 1 << ((int)SelectTargetType.SingleFriend - 1);
// Spell targets AoE friends. // Spell targets AoE friends.
if (effect.TargetA.GetTarget() == Targets.UnitCasterAreaParty || if (spellEffectInfo.TargetA.GetTarget() == Targets.UnitCasterAreaParty ||
effect.TargetA.GetTarget() == Targets.UnitLastTargetAreaParty || spellEffectInfo.TargetA.GetTarget() == Targets.UnitLastTargetAreaParty ||
effect.TargetA.GetTarget() == Targets.SrcCaster) spellEffectInfo.TargetA.GetTarget() == Targets.SrcCaster)
AIInfo.Targets |= 1 << ((int)SelectTargetType.AoeFriend - 1); AIInfo.Targets |= 1 << ((int)SelectTargetType.AoeFriend - 1);
// Spell targets any friend (or self). // Spell targets any friend (or self).
if (effect.TargetA.GetTarget() == Targets.UnitCaster || if (spellEffectInfo.TargetA.GetTarget() == Targets.UnitCaster ||
effect.TargetA.GetTarget() == Targets.UnitTargetAlly || spellEffectInfo.TargetA.GetTarget() == Targets.UnitTargetAlly ||
effect.TargetA.GetTarget() == Targets.UnitTargetParty || spellEffectInfo.TargetA.GetTarget() == Targets.UnitTargetParty ||
effect.TargetA.GetTarget() == Targets.UnitCasterAreaParty || spellEffectInfo.TargetA.GetTarget() == Targets.UnitCasterAreaParty ||
effect.TargetA.GetTarget() == Targets.UnitLastTargetAreaParty || spellEffectInfo.TargetA.GetTarget() == Targets.UnitLastTargetAreaParty ||
effect.TargetA.GetTarget() == Targets.SrcCaster) spellEffectInfo.TargetA.GetTarget() == Targets.SrcCaster)
AIInfo.Targets |= 1 << ((int)SelectTargetType.AnyFriend - 1); AIInfo.Targets |= 1 << ((int)SelectTargetType.AnyFriend - 1);
// Make sure that this spell includes a damage effect. // Make sure that this spell includes a damage effect.
if (effect.Effect == SpellEffectName.SchoolDamage || if (spellEffectInfo.Effect == SpellEffectName.SchoolDamage ||
effect.Effect == SpellEffectName.Instakill || spellEffectInfo.Effect == SpellEffectName.Instakill ||
effect.Effect == SpellEffectName.EnvironmentalDamage || spellEffectInfo.Effect == SpellEffectName.EnvironmentalDamage ||
effect.Effect == SpellEffectName.HealthLeech) spellEffectInfo.Effect == SpellEffectName.HealthLeech)
AIInfo.Effects |= 1 << ((int)SelectEffect.Damage - 1); AIInfo.Effects |= 1 << ((int)SelectEffect.Damage - 1);
// Make sure that this spell includes a healing effect (or an apply aura with a periodic heal). // Make sure that this spell includes a healing effect (or an apply aura with a periodic heal).
if (effect.Effect == SpellEffectName.Heal || if (spellEffectInfo.Effect == SpellEffectName.Heal ||
effect.Effect == SpellEffectName.HealMaxHealth || spellEffectInfo.Effect == SpellEffectName.HealMaxHealth ||
effect.Effect == SpellEffectName.HealMechanical || spellEffectInfo.Effect == SpellEffectName.HealMechanical ||
(effect.Effect == SpellEffectName.ApplyAura && effect.ApplyAuraName == AuraType.PeriodicHeal)) (spellEffectInfo.Effect == SpellEffectName.ApplyAura && spellEffectInfo.ApplyAuraName == AuraType.PeriodicHeal))
AIInfo.Effects |= 1 << ((int)SelectEffect.Healing - 1); AIInfo.Effects |= 1 << ((int)SelectEffect.Healing - 1);
// Make sure that this spell applies an aura. // Make sure that this spell applies an aura.
if (effect.Effect == SpellEffectName.ApplyAura) if (spellEffectInfo.Effect == SpellEffectName.ApplyAura)
AIInfo.Effects |= 1 << ((int)SelectEffect.Aura - 1); AIInfo.Effects |= 1 << ((int)SelectEffect.Aura - 1);
} }
@@ -1046,13 +1046,13 @@ namespace Game.AI
return false; return false;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(e.Action.cast.spell, Difficulty.None); SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(e.Action.cast.spell, Difficulty.None);
foreach (SpellEffectInfo effect in spellInfo.GetEffects()) foreach (var spellEffectInfo in spellInfo.GetEffects())
{ {
if (effect != null && (effect.IsEffect(SpellEffectName.KillCredit) || effect.IsEffect(SpellEffectName.KillCredit2))) if (spellEffectInfo.IsEffect(SpellEffectName.KillCredit) || spellEffectInfo.IsEffect(SpellEffectName.KillCredit2))
{ {
if (effect.TargetA.GetTarget() == Targets.UnitCaster) if (spellEffectInfo.TargetA.GetTarget() == Targets.UnitCaster)
Log.outError(LogFilter.Sql, "SmartAIMgr: Entry {0} SourceType {1} Event {2} Action {3} Effect: SPELL_EFFECT_KILL_CREDIT: (SpellId: {4} targetA: {5} - targetB: {6}) has invalid target for this Action", Log.outError(LogFilter.Sql, "SmartAIMgr: Entry {0} SourceType {1} Event {2} Action {3} Effect: SPELL_EFFECT_KILL_CREDIT: (SpellId: {4} targetA: {5} - targetB: {6}) has invalid target for this Action",
e.EntryOrGuid, e.GetScriptType(), e.EventId, e.GetActionType(), e.Action.cast.spell, effect.TargetA.GetTarget(), effect.TargetB.GetTarget()); e.EntryOrGuid, e.GetScriptType(), e.EventId, e.GetActionType(), e.Action.cast.spell, spellEffectInfo.TargetA.GetTarget(), spellEffectInfo.TargetB.GetTarget());
} }
} }
break; break;
+2 -3
View File
@@ -4175,14 +4175,13 @@ namespace Game.Achievements
criteria.Id, criteria.Entry.Type, DataType, Aura.SpellId); criteria.Id, criteria.Entry.Type, DataType, Aura.SpellId);
return false; return false;
} }
SpellEffectInfo effect = spellEntry.GetEffect(Aura.EffectIndex); if (spellEntry.GetEffects().Count <= Aura.EffectIndex)
if (effect == null)
{ {
Log.outError(LogFilter.Sql, "Table `criteria_data` (Entry: {0} Type: {1}) for data type {2} has wrong spell effect index in value2 ({3}), ignored.", Log.outError(LogFilter.Sql, "Table `criteria_data` (Entry: {0} Type: {1}) for data type {2} has wrong spell effect index in value2 ({3}), ignored.",
criteria.Id, criteria.Entry.Type, DataType, Aura.EffectIndex); criteria.Id, criteria.Entry.Type, DataType, Aura.EffectIndex);
return false; return false;
} }
if (effect.ApplyAuraName == 0) if (spellEntry.GetEffect(Aura.EffectIndex).ApplyAuraName == 0)
{ {
Log.outError(LogFilter.Sql, "Table `criteria_data` (Entry: {0} Type: {1}) for data type {2} has non-aura spell effect (ID: {3} Effect: {4}), ignores.", Log.outError(LogFilter.Sql, "Table `criteria_data` (Entry: {0} Type: {1}) for data type {2} has non-aura spell effect (ID: {3} Effect: {4}), ignores.",
criteria.Id, criteria.Entry.Type, DataType, Aura.SpellId, Aura.EffectIndex); criteria.Id, criteria.Entry.Type, DataType, Aura.SpellId, Aura.EffectIndex);
+6 -6
View File
@@ -1121,10 +1121,10 @@ namespace Game.Chat
} }
bool known = target && target.HasSpell(spellInfo.Id); bool known = target && target.HasSpell(spellInfo.Id);
SpellEffectInfo effect = spellInfo.GetEffect(0); SpellEffectInfo spellEffectInfo = spellInfo.GetEffect(0);
bool learn = effect?.Effect == SpellEffectName.LearnSpell; bool learn = spellEffectInfo.Effect == SpellEffectName.LearnSpell;
SpellInfo learnSpellInfo = effect != null ? Global.SpellMgr.GetSpellInfo(effect.TriggerSpell, spellInfo.Difficulty) : null; SpellInfo learnSpellInfo = Global.SpellMgr.GetSpellInfo(spellEffectInfo.TriggerSpell, spellInfo.Difficulty);
bool talent = spellInfo.HasAttribute(SpellCustomAttributes.IsTalent); bool talent = spellInfo.HasAttribute(SpellCustomAttributes.IsTalent);
bool passive = spellInfo.IsPassive(); bool passive = spellInfo.IsPassive();
@@ -1195,10 +1195,10 @@ namespace Game.Chat
} }
bool known = target && target.HasSpell(id); bool known = target && target.HasSpell(id);
SpellEffectInfo effect = spellInfo.GetEffect(0); SpellEffectInfo spellEffectInfo = spellInfo.GetEffect(0);
bool learn = (effect.Effect == SpellEffectName.LearnSpell); bool learn = spellEffectInfo.Effect == SpellEffectName.LearnSpell;
SpellInfo learnSpellInfo = Global.SpellMgr.GetSpellInfo(effect.TriggerSpell, Difficulty.None); SpellInfo learnSpellInfo = Global.SpellMgr.GetSpellInfo(spellEffectInfo.TriggerSpell, Difficulty.None);
bool talent = spellInfo.HasAttribute(SpellCustomAttributes.IsTalent); bool talent = spellInfo.HasAttribute(SpellCustomAttributes.IsTalent);
bool passive = spellInfo.IsPassive(); bool passive = spellInfo.IsPassive();
+24 -45
View File
@@ -577,35 +577,31 @@ namespace Game
{ {
uint conditionEffMask = cond.SourceGroup; uint conditionEffMask = cond.SourceGroup;
List<uint> sharedMasks = new(); List<uint> sharedMasks = new();
for (byte i = 0; i < SpellConst.MaxEffects; ++i) foreach (var spellEffectInfo in spellInfo.GetEffects())
{ {
SpellEffectInfo effect = spellInfo.GetEffect(i);
if (effect == null)
continue;
// additional checks by condition type // additional checks by condition type
if ((conditionEffMask & (1 << i)) != 0) if ((conditionEffMask & (1 << (int)spellEffectInfo.EffectIndex)) != 0)
{ {
switch (cond.ConditionType) switch (cond.ConditionType)
{ {
case ConditionTypes.ObjectEntryGuid: case ConditionTypes.ObjectEntryGuid:
{ {
SpellCastTargetFlags implicitTargetMask = SpellInfo.GetTargetFlagMask(effect.TargetA.GetObjectType()) | SpellInfo.GetTargetFlagMask(effect.TargetB.GetObjectType()); SpellCastTargetFlags implicitTargetMask = SpellInfo.GetTargetFlagMask(spellEffectInfo.TargetA.GetObjectType()) | SpellInfo.GetTargetFlagMask(spellEffectInfo.TargetB.GetObjectType());
if (implicitTargetMask.HasFlag(SpellCastTargetFlags.UnitMask) && cond.ConditionValue1 != (uint)TypeId.Unit && cond.ConditionValue1 != (uint)TypeId.Player) if (implicitTargetMask.HasFlag(SpellCastTargetFlags.UnitMask) && cond.ConditionValue1 != (uint)TypeId.Unit && cond.ConditionValue1 != (uint)TypeId.Player)
{ {
Log.outError(LogFilter.Sql, $"{cond} in `condition` table - spell {spellInfo.Id} EFFECT_{i} - target requires ConditionValue1 to be either TYPEID_UNIT ({(uint)TypeId.Unit}) or TYPEID_PLAYER ({(uint)TypeId.Player})"); Log.outError(LogFilter.Sql, $"{cond} in `condition` table - spell {spellInfo.Id} EFFECT_{spellEffectInfo.EffectIndex} - target requires ConditionValue1 to be either TYPEID_UNIT ({(uint)TypeId.Unit}) or TYPEID_PLAYER ({(uint)TypeId.Player})");
return; return;
} }
if (implicitTargetMask.HasFlag(SpellCastTargetFlags.GameobjectMask) && cond.ConditionValue1 != (uint)TypeId.GameObject) if (implicitTargetMask.HasFlag(SpellCastTargetFlags.GameobjectMask) && cond.ConditionValue1 != (uint)TypeId.GameObject)
{ {
Log.outError(LogFilter.Sql, $"{cond} in `condition` table - spell {spellInfo.Id} EFFECT_{i} - target requires ConditionValue1 to be TYPEID_GAMEOBJECT ({(uint)TypeId.GameObject})"); Log.outError(LogFilter.Sql, $"{cond} in `condition` table - spell {spellInfo.Id} EFFECT_{spellEffectInfo.EffectIndex} - target requires ConditionValue1 to be TYPEID_GAMEOBJECT ({(uint)TypeId.GameObject})");
return; return;
} }
if (implicitTargetMask.HasFlag(SpellCastTargetFlags.CorpseMask) && cond.ConditionValue1 != (uint)TypeId.Corpse) if (implicitTargetMask.HasFlag(SpellCastTargetFlags.CorpseMask) && cond.ConditionValue1 != (uint)TypeId.Corpse)
{ {
Log.outError(LogFilter.Sql, $"{cond} in `condition` table - spell {spellInfo.Id} EFFECT_{i} - target requires ConditionValue1 to be TYPEID_CORPSE ({(uint)TypeId.Corpse})"); Log.outError(LogFilter.Sql, $"{cond} in `condition` table - spell {spellInfo.Id} EFFECT_{spellEffectInfo.EffectIndex} - target requires ConditionValue1 to be TYPEID_CORPSE ({(uint)TypeId.Corpse})");
return; return;
} }
break; break;
@@ -616,21 +612,16 @@ namespace Game
} }
// check if effect is already a part of some shared mask // check if effect is already a part of some shared mask
if (sharedMasks.Any(mask => !!Convert.ToBoolean(mask & (1 << i)))) if (sharedMasks.Any(mask => !!Convert.ToBoolean(mask & (1 << (int)spellEffectInfo.EffectIndex))))
continue; continue;
// build new shared mask with found effect // build new shared mask with found effect
uint sharedMask = (uint)(1 << i); uint sharedMask = (uint)(1 << (int)spellEffectInfo.EffectIndex);
List<Condition> cmp = effect.ImplicitTargetConditions; List<Condition> cmp = spellEffectInfo.ImplicitTargetConditions;
for (byte effIndex = (byte)(i + 1); effIndex < SpellConst.MaxEffects; ++effIndex) for (uint effIndex = spellEffectInfo.EffectIndex + 1; effIndex < spellInfo.GetEffects().Count; ++effIndex)
{ if (spellInfo.GetEffect(effIndex).ImplicitTargetConditions == cmp)
SpellEffectInfo inner = spellInfo.GetEffect(effIndex); sharedMask |= (uint)(1 << (int)effIndex);
if (inner == null)
continue;
if (inner.ImplicitTargetConditions == cmp)
sharedMask |= (uint)(1 << effIndex);
}
sharedMasks.Add(sharedMask); sharedMasks.Add(sharedMask);
} }
@@ -645,15 +636,11 @@ namespace Game
if (((1 << firstEffIndex) & effectMask) != 0) if (((1 << firstEffIndex) & effectMask) != 0)
break; break;
if (firstEffIndex >= SpellConst.MaxEffects) if (firstEffIndex >= spellInfo.GetEffects().Count)
return; return;
SpellEffectInfo effect = spellInfo.GetEffect(firstEffIndex);
if (effect == null)
continue;
// get shared data // get shared data
List<Condition> sharedList = effect.ImplicitTargetConditions; List<Condition> sharedList = spellInfo.GetEffect(firstEffIndex).ImplicitTargetConditions;
// there's already data entry for that sharedMask // there's already data entry for that sharedMask
if (sharedList != null) if (sharedList != null)
@@ -672,15 +659,11 @@ namespace Game
// add new list, create new shared mask // add new list, create new shared mask
sharedList = new List<Condition>(); sharedList = new List<Condition>();
bool assigned = false; bool assigned = false;
for (byte i = firstEffIndex; i < SpellConst.MaxEffects; ++i) for (uint i = firstEffIndex; i < spellInfo.GetEffects().Count; ++i)
{ {
SpellEffectInfo eff = spellInfo.GetEffect(i); if (((1 << (int)i) & commonMask) != 0)
if (eff == null)
continue;
if (((1 << i) & commonMask) != 0)
{ {
eff.ImplicitTargetConditions = sharedList; spellInfo.GetEffect(i).ImplicitTargetConditions = sharedList;
assigned = true; assigned = true;
} }
} }
@@ -966,19 +949,15 @@ namespace Game
uint origGroup = cond.SourceGroup; uint origGroup = cond.SourceGroup;
for (byte i = 0; i < SpellConst.MaxEffects; ++i) foreach (SpellEffectInfo spellEffectInfo in spellInfo.GetEffects())
{ {
if (((1 << i) & cond.SourceGroup) == 0) if (((1 << (int)spellEffectInfo.EffectIndex) & cond.SourceGroup) == 0)
continue; continue;
SpellEffectInfo effect = spellInfo.GetEffect(i); if (spellEffectInfo.ChainTargets > 0)
if (effect == null)
continue; continue;
if (effect.ChainTargets > 0) switch (spellEffectInfo.TargetA.GetSelectionCategory())
continue;
switch (effect.TargetA.GetSelectionCategory())
{ {
case SpellTargetSelectionCategories.Nearby: case SpellTargetSelectionCategories.Nearby:
case SpellTargetSelectionCategories.Cone: case SpellTargetSelectionCategories.Cone:
@@ -990,7 +969,7 @@ namespace Game
break; break;
} }
switch (effect.TargetB.GetSelectionCategory()) switch (spellEffectInfo.TargetB.GetSelectionCategory())
{ {
case SpellTargetSelectionCategories.Nearby: case SpellTargetSelectionCategories.Nearby:
case SpellTargetSelectionCategories.Cone: case SpellTargetSelectionCategories.Cone:
@@ -1002,8 +981,8 @@ namespace Game
break; break;
} }
Log.outError(LogFilter.Sql, "SourceEntry {0} SourceGroup {1} in `condition` table - spell {2} does not have implicit targets of types: _AREA_, _CONE_, _NEARBY_, _CHAIN_ for effect {3}, SourceGroup needs correction, ignoring.", cond.SourceEntry, origGroup, cond.SourceEntry, i); Log.outError(LogFilter.Sql, "SourceEntry {0} SourceGroup {1} in `condition` table - spell {2} does not have implicit targets of types: _AREA_, _CONE_, _NEARBY_, _CHAIN_ for effect {3}, SourceGroup needs correction, ignoring.", cond.SourceEntry, origGroup, cond.SourceEntry, spellEffectInfo.EffectIndex);
cond.SourceGroup &= ~(uint)(1 << i); cond.SourceGroup &= ~(1u << (int)spellEffectInfo.EffectIndex);
} }
// all effects were removed, no need to add the condition at all // all effects were removed, no need to add the condition at all
if (cond.SourceGroup == 0) if (cond.SourceGroup == 0)
+6 -10
View File
@@ -2045,12 +2045,12 @@ namespace Game.Entities
return false; return false;
bool immunedToAllEffects = true; bool immunedToAllEffects = true;
foreach (SpellEffectInfo effect in spellInfo.GetEffects()) foreach (var spellEffectInfo in spellInfo.GetEffects())
{ {
if (effect == null || !effect.IsEffect()) if (!spellEffectInfo.IsEffect())
continue; continue;
if (!IsImmunedToSpellEffect(spellInfo, effect.EffectIndex, caster)) if (!IsImmunedToSpellEffect(spellInfo, spellEffectInfo, caster))
{ {
immunedToAllEffects = false; immunedToAllEffects = false;
break; break;
@@ -2063,16 +2063,12 @@ namespace Game.Entities
return base.IsImmunedToSpell(spellInfo, caster); return base.IsImmunedToSpell(spellInfo, caster);
} }
public override bool IsImmunedToSpellEffect(SpellInfo spellInfo, uint index, WorldObject caster) public override bool IsImmunedToSpellEffect(SpellInfo spellInfo, SpellEffectInfo spellEffectInfo, WorldObject caster)
{ {
SpellEffectInfo effect = spellInfo.GetEffect(index); if (GetCreatureTemplate().CreatureType == CreatureType.Mechanical && spellEffectInfo.IsEffect(SpellEffectName.Heal))
if (effect == null)
return true; return true;
if (GetCreatureTemplate().CreatureType == CreatureType.Mechanical && effect.Effect == SpellEffectName.Heal) return base.IsImmunedToSpellEffect(spellInfo, spellEffectInfo, caster);
return true;
return base.IsImmunedToSpellEffect(spellInfo, index, caster);
} }
public bool IsElite() public bool IsElite()
+3 -3
View File
@@ -444,9 +444,9 @@ namespace Game.Misc
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(quest.RewardSpell, Difficulty.None); SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(quest.RewardSpell, Difficulty.None);
if (spellInfo != null) if (spellInfo != null)
{ {
foreach (SpellEffectInfo effect in spellInfo.GetEffects()) foreach (var spellEffectInfo in spellInfo.GetEffects())
if (effect != null && effect.IsEffect(SpellEffectName.LearnSpell)) if (spellEffectInfo.IsEffect(SpellEffectName.LearnSpell))
packet.LearnSpells.Add(effect.TriggerSpell); packet.LearnSpells.Add(spellEffectInfo.TriggerSpell);
} }
quest.BuildQuestRewards(packet.Rewards, _session.GetPlayer()); quest.BuildQuestRewards(packet.Rewards, _session.GetPlayer());
+3 -3
View File
@@ -129,13 +129,13 @@ namespace Game.Entities
// check ranks // check ranks
bool hasLearnSpellEffect = false; bool hasLearnSpellEffect = false;
bool knowsAllLearnedSpells = true; bool knowsAllLearnedSpells = true;
foreach (SpellEffectInfo spellEffect in Global.SpellMgr.GetSpellInfo(trainerSpell.SpellId, Difficulty.None).GetEffects()) foreach (var spellEffectInfo in Global.SpellMgr.GetSpellInfo(trainerSpell.SpellId, Difficulty.None).GetEffects())
{ {
if (spellEffect == null || !spellEffect.IsEffect(SpellEffectName.LearnSpell)) if (!spellEffectInfo.IsEffect(SpellEffectName.LearnSpell))
continue; continue;
hasLearnSpellEffect = true; hasLearnSpellEffect = true;
if (!player.HasSpell(spellEffect.TriggerSpell)) if (!player.HasSpell(spellEffectInfo.TriggerSpell))
knowsAllLearnedSpells = false; knowsAllLearnedSpells = false;
} }
@@ -2219,11 +2219,11 @@ namespace Game.Entities
SpellInfo transform = Global.SpellMgr.GetSpellInfo(unit.GetTransForm(), unit.GetMap().GetDifficultyID()); SpellInfo transform = Global.SpellMgr.GetSpellInfo(unit.GetTransForm(), unit.GetMap().GetDifficultyID());
if (transform != null) if (transform != null)
{ {
foreach (SpellEffectInfo effect in transform.GetEffects()) foreach (var spellEffectInfo in transform.GetEffects())
{ {
if (effect != null && effect.IsAura(AuraType.Transform)) if (spellEffectInfo.IsAura(AuraType.Transform))
{ {
CreatureTemplate transformInfo = Global.ObjectMgr.GetCreatureTemplate((uint)effect.MiscValue); CreatureTemplate transformInfo = Global.ObjectMgr.GetCreatureTemplate((uint)spellEffectInfo.MiscValue);
if (transformInfo != null) if (transformInfo != null)
{ {
cinfo = transformInfo; cinfo = transformInfo;
+4 -5
View File
@@ -1682,18 +1682,17 @@ namespace Game.Entities
return null; return null;
} }
public int CalculateSpellDamage(Unit target, SpellInfo spellProto, uint effIndex, int? basePoints = null, uint castItemId = 0, int itemLevel = -1) public int CalculateSpellDamage(Unit target, SpellEffectInfo spellEffectInfo, int? basePoints = null, uint castItemId = 0, int itemLevel = -1)
{ {
return CalculateSpellDamage(out _, target, spellProto, effIndex, basePoints, castItemId, itemLevel); return CalculateSpellDamage(out _, target, spellEffectInfo, basePoints, castItemId, itemLevel);
} }
// function uses real base points (typically value - 1) // function uses real base points (typically value - 1)
public int CalculateSpellDamage(out float variance, Unit target, SpellInfo spellProto, uint effIndex, int? basePoints = null, uint castItemId = 0, int itemLevel = -1) public int CalculateSpellDamage(out float variance, Unit target, SpellEffectInfo spellEffectInfo, int? basePoints = null, uint castItemId = 0, int itemLevel = -1)
{ {
SpellEffectInfo effect = spellProto.GetEffect(effIndex);
variance = 0.0f; variance = 0.0f;
return effect != null ? effect.CalcValue(out variance, this, basePoints, target, castItemId, itemLevel) : 0; return spellEffectInfo != null ? spellEffectInfo.CalcValue(out variance, this, basePoints, target, castItemId, itemLevel) : 0;
} }
public float GetSpellMaxRangeForTarget(Unit target, SpellInfo spellInfo) public float GetSpellMaxRangeForTarget(Unit target, SpellInfo spellInfo)
+4 -3
View File
@@ -5136,9 +5136,10 @@ namespace Game.Entities
CastSpellExtraArgs args = new(TriggerCastFlags.FullMask); CastSpellExtraArgs args = new(TriggerCastFlags.FullMask);
args.CastItem = artifact; args.CastItem = artifact;
if (artifactPowerRank.AuraPointsOverride != 0) if (artifactPowerRank.AuraPointsOverride != 0)
for (int i = 0; i < SpellConst.MaxEffects; ++i) {
if (spellInfo.GetEffect((uint)i) != null) foreach (var spellEffectInfo in spellInfo.GetEffects())
args.AddSpellMod(SpellValueMod.BasePoint0 + i, (int)artifactPowerRank.AuraPointsOverride); args.AddSpellMod(SpellValueMod.BasePoint0 + (int)spellEffectInfo.EffectIndex, (int)artifactPowerRank.AuraPointsOverride);
}
CastSpell(this, artifactPowerRank.SpellID, args); CastSpell(this, artifactPowerRank.SpellID, args);
} }
+2 -5
View File
@@ -107,9 +107,9 @@ namespace Game.Entities
// check learned spells state // check learned spells state
bool found = false; bool found = false;
foreach (SpellEffectInfo eff in spellInfo.GetEffects()) foreach (var spellEffectInfo in spellInfo.GetEffects())
{ {
if (eff != null && eff.Effect == SpellEffectName.LearnSpell && !HasSpell(eff.TriggerSpell)) if (spellEffectInfo.IsEffect(SpellEffectName.LearnSpell) && !HasSpell(spellEffectInfo.TriggerSpell))
{ {
found = true; found = true;
break; break;
@@ -121,9 +121,6 @@ namespace Game.Entities
return; return;
SpellEffectInfo effect = spellInfo.GetEffect(0); SpellEffectInfo effect = spellInfo.GetEffect(0);
if (effect == null)
return;
uint learned_0 = effect.TriggerSpell; uint learned_0 = effect.TriggerSpell;
if (!HasSpell(learned_0)) if (!HasSpell(learned_0))
{ {
+7 -7
View File
@@ -1711,8 +1711,8 @@ namespace Game.Entities
// special check to filter things like Shield Wall, the aura is not permanent and must stay even without required item // special check to filter things like Shield Wall, the aura is not permanent and must stay even without required item
if (!spellInfo.IsPassive()) if (!spellInfo.IsPassive())
{ {
foreach (SpellEffectInfo effect in spellInfo.GetEffects()) foreach (var spellEffectInfo in spellInfo.GetEffects())
if (effect != null && effect.IsAura()) if (spellEffectInfo.IsAura())
return true; return true;
} }
} }
@@ -2284,9 +2284,9 @@ namespace Game.Entities
// passive spells which apply aura and have an item requirement are to be added manually, instead of casted // passive spells which apply aura and have an item requirement are to be added manually, instead of casted
if (spellInfo.EquippedItemClass >= 0) if (spellInfo.EquippedItemClass >= 0)
{ {
foreach (SpellEffectInfo effectInfo in spellInfo.GetEffects()) foreach (var spellEffectInfo in spellInfo.GetEffects())
{ {
if (effectInfo != null && effectInfo.IsAura()) if (spellEffectInfo.IsAura())
{ {
if (!HasAura(spellInfo.Id) && HasItemFitToSpellRequirements(spellInfo)) if (!HasAura(spellInfo.Id) && HasItemFitToSpellRequirements(spellInfo))
AddAura(spellInfo.Id, this); AddAura(spellInfo.Id, this);
@@ -3289,10 +3289,10 @@ namespace Game.Entities
int effectPct = Math.Max(0, 100 - (lvlDifference * lvlPenaltyFactor)); int effectPct = Math.Max(0, 100 - (lvlDifference * lvlPenaltyFactor));
for (byte i = 0; i < SpellConst.MaxEffects; ++i) foreach (var spellEffectInfo in spellInfo.GetEffects())
{ {
if (spellInfo.GetEffect(i).IsEffect()) if (spellEffectInfo.IsEffect())
args.AddSpellMod(SpellValueMod.BasePoint0 + i, MathFunctions.CalculatePct(spellInfo.GetEffect(i).CalcValue(this), effectPct)); args.AddSpellMod(SpellValueMod.BasePoint0 + (int)spellEffectInfo.EffectIndex, MathFunctions.CalculatePct(spellEffectInfo.CalcValue(this), effectPct));
} }
} }
@@ -91,9 +91,9 @@ namespace Game.Entities
RemoveSpell(talent.SpellID, true); RemoveSpell(talent.SpellID, true);
// search for spells that the talent teaches and unlearn them // search for spells that the talent teaches and unlearn them
foreach (SpellEffectInfo effect in spellInfo.GetEffects()) foreach (var spellEffectInfo in spellInfo.GetEffects())
if (effect != null && effect.TriggerSpell > 0 && effect.Effect == SpellEffectName.LearnSpell) if (spellEffectInfo.IsEffect(SpellEffectName.LearnSpell) && spellEffectInfo.TriggerSpell > 0)
RemoveSpell(effect.TriggerSpell, true); RemoveSpell(spellEffectInfo.TriggerSpell, true);
if (talent.OverridesSpellID != 0) if (talent.OverridesSpellID != 0)
RemoveOverrideSpell(talent.OverridesSpellID, talent.SpellID); RemoveOverrideSpell(talent.OverridesSpellID, talent.SpellID);
@@ -301,9 +301,9 @@ namespace Game.Entities
RemoveSpell(talentInfo.SpellID, true); RemoveSpell(talentInfo.SpellID, true);
// search for spells that the talent teaches and unlearn them // search for spells that the talent teaches and unlearn them
foreach (SpellEffectInfo effect in spellInfo.GetEffects()) foreach (var spellEffectInfo in spellInfo.GetEffects())
if (effect != null && effect.TriggerSpell > 0 && effect.Effect == SpellEffectName.LearnSpell) if (spellEffectInfo.IsEffect(SpellEffectName.LearnSpell) && spellEffectInfo.TriggerSpell > 0)
RemoveSpell(effect.TriggerSpell, true); RemoveSpell(spellEffectInfo.TriggerSpell, true);
if (talentInfo.OverridesSpellID != 0) if (talentInfo.OverridesSpellID != 0)
RemoveOverrideSpell(talentInfo.OverridesSpellID, talentInfo.SpellID); RemoveOverrideSpell(talentInfo.OverridesSpellID, talentInfo.SpellID);
@@ -318,9 +318,9 @@ namespace Game.Entities
RemoveSpell(talentInfo.SpellID, true); RemoveSpell(talentInfo.SpellID, true);
// search for spells that the talent teaches and unlearn them // search for spells that the talent teaches and unlearn them
foreach (SpellEffectInfo effect in spellInfo.GetEffects()) foreach (var spellEffectInfo in spellInfo.GetEffects())
if (effect != null && effect.TriggerSpell > 0 && effect.Effect == SpellEffectName.LearnSpell) if (spellEffectInfo.IsEffect(SpellEffectName.LearnSpell) && spellEffectInfo.TriggerSpell > 0)
RemoveSpell(effect.TriggerSpell, true); RemoveSpell(spellEffectInfo.TriggerSpell, true);
if (talentInfo.OverridesSpellID != 0) if (talentInfo.OverridesSpellID != 0)
RemoveOverrideSpell(talentInfo.OverridesSpellID, talentInfo.SpellID); RemoveOverrideSpell(talentInfo.OverridesSpellID, talentInfo.SpellID);
+6 -9
View File
@@ -3636,19 +3636,16 @@ namespace Game.Entities
return false; return false;
} }
public override bool IsImmunedToSpellEffect(SpellInfo spellInfo, uint index, WorldObject caster) public override bool IsImmunedToSpellEffect(SpellInfo spellInfo, SpellEffectInfo spellEffectInfo, WorldObject caster)
{ {
SpellEffectInfo effect = spellInfo.GetEffect(index);
if (effect == null || !effect.IsEffect())
return false;
// players are immune to taunt (the aura and the spell effect). // players are immune to taunt (the aura and the spell effect).
if (effect.IsAura(AuraType.ModTaunt)) if (spellEffectInfo.IsAura(AuraType.ModTaunt))
return true;
if (effect.IsEffect(SpellEffectName.AttackMe))
return true; return true;
return base.IsImmunedToSpellEffect(spellInfo, index, caster); if (spellEffectInfo.IsEffect(SpellEffectName.AttackMe))
return true;
return base.IsImmunedToSpellEffect(spellInfo, spellEffectInfo, caster);
} }
void RegenerateAll() void RegenerateAll()
+8 -11
View File
@@ -1005,12 +1005,12 @@ namespace Game.Entities
return 0; return 0;
int resistMech = 0; int resistMech = 0;
foreach (SpellEffectInfo effect in spellInfo.GetEffects()) foreach (var spellEffectInfo in spellInfo.GetEffects())
{ {
if (effect == null || !effect.IsEffect()) if (!spellEffectInfo.IsEffect())
break; break;
int effect_mech = (int)spellInfo.GetEffectMechanic(effect.EffectIndex); int effect_mech = (int)spellInfo.GetEffectMechanic(spellEffectInfo.EffectIndex);
if (effect_mech != 0) if (effect_mech != 0)
{ {
int temp = GetTotalAuraModifierByMiscValue(AuraType.ModMechanicResistance, effect_mech); int temp = GetTotalAuraModifierByMiscValue(AuraType.ModMechanicResistance, effect_mech);
@@ -1538,21 +1538,18 @@ namespace Game.Entities
if (chrSpec == null) if (chrSpec == null)
return; return;
for (uint i = 0; i < PlayerConst.MaxMasterySpells; ++i) foreach (uint masterySpellId in chrSpec.MasterySpellID)
{ {
Aura aura = GetAura(chrSpec.MasterySpellID[i]); Aura aura = GetAura(masterySpellId);
if (aura != null) if (aura != null)
{ {
foreach (SpellEffectInfo effect in aura.GetSpellInfo().GetEffects()) foreach (var spellEffectInfo in aura.GetSpellInfo().GetEffects())
{ {
if (effect == null) float mult = spellEffectInfo.BonusCoefficient;
continue;
float mult = effect.BonusCoefficient;
if (MathFunctions.fuzzyEq(mult, 0.0f)) if (MathFunctions.fuzzyEq(mult, 0.0f))
continue; continue;
aura.GetEffect(effect.EffectIndex).ChangeAmount((int)(value * mult)); aura.GetEffect(spellEffectInfo.EffectIndex).ChangeAmount((int)(value * mult));
} }
} }
} }
+4 -5
View File
@@ -143,17 +143,16 @@ namespace Game.Entities
AddObjectToRemoveList(); AddObjectToRemoveList();
} }
public override bool IsImmunedToSpellEffect(SpellInfo spellInfo, uint index, WorldObject caster) public override bool IsImmunedToSpellEffect(SpellInfo spellInfo, SpellEffectInfo spellEffectInfo, WorldObject caster)
{ {
// @todo possibly all negative auras immune? // @todo possibly all negative auras immune?
if (GetEntry() == 5925) if (GetEntry() == 5925)
return false; return false;
SpellEffectInfo effect = spellInfo.GetEffect(index); if (spellEffectInfo == null)
if (effect == null)
return true; return true;
switch (effect.ApplyAuraName) switch (spellEffectInfo.ApplyAuraName)
{ {
case AuraType.PeriodicDamage: case AuraType.PeriodicDamage:
case AuraType.PeriodicLeech: case AuraType.PeriodicLeech:
@@ -164,7 +163,7 @@ namespace Game.Entities
break; break;
} }
return base.IsImmunedToSpellEffect(spellInfo, index, caster); return base.IsImmunedToSpellEffect(spellInfo, spellEffectInfo, caster);
} }
public uint GetSpell(byte slot = 0) { return m_spells[slot]; } public uint GetSpell(byte slot = 0) { return m_spells[slot]; }
+3 -3
View File
@@ -226,12 +226,12 @@ namespace Game.Entities
SpellInfo spInfo = Global.SpellMgr.GetSpellInfo(minion.ToTotem().GetSpell(), GetMap().GetDifficultyID()); SpellInfo spInfo = Global.SpellMgr.GetSpellInfo(minion.ToTotem().GetSpell(), GetMap().GetDifficultyID());
if (spInfo != null) if (spInfo != null)
{ {
foreach (SpellEffectInfo effect in spInfo.GetEffects()) foreach (var spellEffectInfo in spInfo.GetEffects())
{ {
if (effect == null || effect.Effect != SpellEffectName.Summon) if (spellEffectInfo == null || !spellEffectInfo.IsEffect(SpellEffectName.Summon))
continue; continue;
RemoveAllMinionsByEntry((uint)effect.MiscValue); RemoveAllMinionsByEntry((uint)spellEffectInfo.MiscValue);
} }
} }
} }
+40 -53
View File
@@ -69,7 +69,7 @@ namespace Game.Entities
return DoneAdvertisedBenefit; return DoneAdvertisedBenefit;
} }
public uint SpellDamageBonusDone(Unit victim, SpellInfo spellProto, uint pdamage, DamageEffectType damagetype, SpellEffectInfo effect, uint stack = 1) public uint SpellDamageBonusDone(Unit victim, SpellInfo spellProto, uint pdamage, DamageEffectType damagetype, SpellEffectInfo spellEffectInfo, uint stack = 1)
{ {
if (spellProto == null || victim == null || damagetype == DamageEffectType.Direct) if (spellProto == null || victim == null || damagetype == DamageEffectType.Direct)
return pdamage; return pdamage;
@@ -83,7 +83,7 @@ namespace Game.Entities
{ {
Unit owner = GetOwner(); Unit owner = GetOwner();
if (owner != null) if (owner != null)
return owner.SpellDamageBonusDone(victim, spellProto, pdamage, damagetype, effect, stack); return owner.SpellDamageBonusDone(victim, spellProto, pdamage, damagetype, spellEffectInfo, stack);
} }
int DoneTotal = 0; int DoneTotal = 0;
@@ -100,9 +100,9 @@ namespace Game.Entities
DoneAdvertisedBenefit += ((Guardian)this).GetBonusDamage(); DoneAdvertisedBenefit += ((Guardian)this).GetBonusDamage();
// Check for table values // Check for table values
if (effect.BonusCoefficientFromAP > 0.0f) if (spellEffectInfo.BonusCoefficientFromAP > 0.0f)
{ {
float ApCoeffMod = effect.BonusCoefficientFromAP; float ApCoeffMod = spellEffectInfo.BonusCoefficientFromAP;
Player modOwner = GetSpellModOwner(); Player modOwner = GetSpellModOwner();
if (modOwner) if (modOwner)
{ {
@@ -130,7 +130,7 @@ namespace Game.Entities
} }
// Default calculation // Default calculation
float coeff = effect.BonusCoefficient; float coeff = spellEffectInfo.BonusCoefficient;
if (DoneAdvertisedBenefit != 0) if (DoneAdvertisedBenefit != 0)
{ {
Player modOwner1 = GetSpellModOwner(); Player modOwner1 = GetSpellModOwner();
@@ -382,14 +382,14 @@ namespace Game.Entities
return damage; return damage;
} }
public uint SpellHealingBonusDone(Unit victim, SpellInfo spellProto, uint healamount, DamageEffectType damagetype, SpellEffectInfo effect, uint stack = 1) public uint SpellHealingBonusDone(Unit victim, SpellInfo spellProto, uint healamount, DamageEffectType damagetype, SpellEffectInfo spellEffectInfo, uint stack = 1)
{ {
// For totems get healing bonus from owner (statue isn't totem in fact) // For totems get healing bonus from owner (statue isn't totem in fact)
if (IsTypeId(TypeId.Unit) && IsTotem()) if (IsTypeId(TypeId.Unit) && IsTotem())
{ {
Unit owner = GetOwner(); Unit owner = GetOwner();
if (owner) if (owner)
return owner.SpellHealingBonusDone(victim, spellProto, healamount, damagetype, effect, stack); return owner.SpellHealingBonusDone(victim, spellProto, healamount, damagetype, spellEffectInfo, stack);
} }
// No bonus healing for potion spells // No bonus healing for potion spells
@@ -428,14 +428,14 @@ namespace Game.Entities
DoneAdvertisedBenefit += (uint)((Guardian)this).GetBonusDamage(); DoneAdvertisedBenefit += (uint)((Guardian)this).GetBonusDamage();
// Check for table values // Check for table values
float coeff = effect.BonusCoefficient; float coeff = spellEffectInfo.BonusCoefficient;
if (effect.BonusCoefficientFromAP > 0.0f) if (spellEffectInfo.BonusCoefficientFromAP > 0.0f)
{ {
WeaponAttackType attType = (spellProto.IsRangedWeaponSpell() && spellProto.DmgClass != SpellDmgClass.Melee) ? WeaponAttackType.RangedAttack : WeaponAttackType.BaseAttack; WeaponAttackType attType = (spellProto.IsRangedWeaponSpell() && spellProto.DmgClass != SpellDmgClass.Melee) ? WeaponAttackType.RangedAttack : WeaponAttackType.BaseAttack;
float APbonus = (float)victim.GetTotalAuraModifier(attType == WeaponAttackType.BaseAttack ? AuraType.MeleeAttackPowerAttackerBonus : AuraType.RangedAttackPowerAttackerBonus); float APbonus = (float)victim.GetTotalAuraModifier(attType == WeaponAttackType.BaseAttack ? AuraType.MeleeAttackPowerAttackerBonus : AuraType.RangedAttackPowerAttackerBonus);
APbonus += GetTotalAttackPowerValue(attType); APbonus += GetTotalAttackPowerValue(attType);
DoneTotal += (int)(effect.BonusCoefficientFromAP * stack * APbonus); DoneTotal += (int)(spellEffectInfo.BonusCoefficientFromAP * stack * APbonus);
} }
else if (coeff <= 0.0f) // no AP and no SP coefs, skip else if (coeff <= 0.0f) // no AP and no SP coefs, skip
{ {
@@ -458,12 +458,9 @@ namespace Game.Entities
DoneTotal += (int)(DoneAdvertisedBenefit * coeff * stack); DoneTotal += (int)(DoneAdvertisedBenefit * coeff * stack);
} }
foreach (SpellEffectInfo eff in spellProto.GetEffects()) foreach (var otherSpellEffectInfo in spellProto.GetEffects())
{ {
if (eff == null) switch (otherSpellEffectInfo.ApplyAuraName)
continue;
switch (eff.ApplyAuraName)
{ {
// Bonus healing does not apply to these spells // Bonus healing does not apply to these spells
case AuraType.PeriodicLeech: case AuraType.PeriodicLeech:
@@ -471,7 +468,7 @@ namespace Game.Entities
DoneTotal = 0; DoneTotal = 0;
break; break;
} }
if (eff.Effect == SpellEffectName.HealthLeech) if (otherSpellEffectInfo.IsEffect(SpellEffectName.HealthLeech))
DoneTotal = 0; DoneTotal = 0;
} }
@@ -1247,14 +1244,14 @@ namespace Game.Entities
} }
bool immuneToAllEffects = true; bool immuneToAllEffects = true;
foreach (SpellEffectInfo effect in spellInfo.GetEffects()) foreach (var spellEffectInfo in spellInfo.GetEffects())
{ {
// State/effect immunities applied by aura expect full spell immunity // State/effect immunities applied by aura expect full spell immunity
// Ignore effects with mechanic, they are supposed to be checked separately // Ignore effects with mechanic, they are supposed to be checked separately
if (effect == null || !effect.IsEffect()) if (!spellEffectInfo.IsEffect())
continue; continue;
if (!IsImmunedToSpellEffect(spellInfo, effect.EffectIndex, caster)) if (!IsImmunedToSpellEffect(spellInfo, spellEffectInfo, caster))
{ {
immuneToAllEffects = false; immuneToAllEffects = false;
break; break;
@@ -1313,22 +1310,20 @@ namespace Game.Entities
return mask; return mask;
} }
public virtual bool IsImmunedToSpellEffect(SpellInfo spellInfo, uint index, WorldObject caster) public virtual bool IsImmunedToSpellEffect(SpellInfo spellInfo, SpellEffectInfo spellEffectInfo, WorldObject caster)
{ {
if (spellInfo == null) if (spellInfo == null)
return false; return false;
SpellEffectInfo effect = spellInfo.GetEffect(index); if (spellEffectInfo == null || !spellEffectInfo.IsEffect())
if (effect == null || !effect.IsEffect())
return false; return false;
// If m_immuneToEffect type contain this effect type, IMMUNE effect. // If m_immuneToEffect type contain this effect type, IMMUNE effect.
uint eff = (uint)effect.Effect;
var effectList = m_spellImmune[(int)SpellImmunity.Effect]; var effectList = m_spellImmune[(int)SpellImmunity.Effect];
if (effectList.ContainsKey(eff)) if (effectList.ContainsKey((uint)spellEffectInfo.Effect))
return true; return true;
uint mechanic = (uint)effect.Mechanic; uint mechanic = (uint)spellEffectInfo.Mechanic;
if (mechanic != 0) if (mechanic != 0)
{ {
var mechanicList = m_spellImmune[(int)SpellImmunity.Mechanic]; var mechanicList = m_spellImmune[(int)SpellImmunity.Mechanic];
@@ -1338,7 +1333,7 @@ namespace Game.Entities
if (!spellInfo.HasAttribute(SpellAttr3.IgnoreHitResult)) if (!spellInfo.HasAttribute(SpellAttr3.IgnoreHitResult))
{ {
uint aura = (uint)effect.ApplyAuraName; uint aura = (uint)spellEffectInfo.ApplyAuraName;
if (aura != 0) if (aura != 0)
{ {
var list = m_spellImmune[(int)SpellImmunity.State]; var list = m_spellImmune[(int)SpellImmunity.State];
@@ -1351,7 +1346,7 @@ namespace Game.Entities
var immuneAuraApply = GetAuraEffectsByType(AuraType.ModImmuneAuraApplySchool); var immuneAuraApply = GetAuraEffectsByType(AuraType.ModImmuneAuraApplySchool);
foreach (var auraEffect in immuneAuraApply) foreach (var auraEffect in immuneAuraApply)
if (Convert.ToBoolean(auraEffect.GetMiscValue() & (int)spellInfo.GetSchoolMask()) && // Check school if (Convert.ToBoolean(auraEffect.GetMiscValue() & (int)spellInfo.GetSchoolMask()) && // Check school
((caster && !IsFriendlyTo(caster)) || !spellInfo.IsPositiveEffect(index))) // Harmful ((caster && !IsFriendlyTo(caster)) || !spellInfo.IsPositiveEffect(spellEffectInfo.EffectIndex))) // Harmful
return true; return true;
} }
} }
@@ -2195,9 +2190,9 @@ namespace Game.Entities
} }
// turn off snare auras by setting amount to 0 // turn off snare auras by setting amount to 0
foreach (SpellEffectInfo spellEffectInfo in aura.GetSpellInfo().GetEffects()) foreach (var spellEffectInfo in aura.GetSpellInfo().GetEffects())
{ {
if (spellEffectInfo != null && pair.Value.HasEffect(spellEffectInfo.EffectIndex) && spellEffectInfo.Mechanic == Mechanics.Snare) if (pair.Value.HasEffect(spellEffectInfo.EffectIndex) && spellEffectInfo.Mechanic == Mechanics.Snare)
aura.GetEffect(spellEffectInfo.EffectIndex).ChangeAmount(0); aura.GetEffect(spellEffectInfo.EffectIndex).ChangeAmount(0);
} }
} }
@@ -2492,12 +2487,13 @@ namespace Game.Entities
if (target.IsImmunedToSpell(spellInfo, this)) if (target.IsImmunedToSpell(spellInfo, this))
return null; return null;
for (byte i = 0; i < SpellConst.MaxEffects; ++i) foreach (var spellEffectInfo in spellInfo.GetEffects())
{ {
if (!Convert.ToBoolean(effMask & (1 << i))) if ((effMask & (1 << (int)spellEffectInfo.EffectIndex)) == 0)
continue; continue;
if (target.IsImmunedToSpellEffect(spellInfo, i, this))
effMask &= ~(uint)(1 << i); if (target.IsImmunedToSpellEffect(spellInfo, spellEffectInfo, this))
effMask &= ~(1u << (int)spellEffectInfo.EffectIndex);
} }
if (effMask == 0) if (effMask == 0)
@@ -2546,12 +2542,9 @@ namespace Game.Entities
{ {
byte i = 0; byte i = 0;
bool valid = false; bool valid = false;
foreach (SpellEffectInfo effect in spellEntry.GetEffects()) foreach (var spellEffectInfo in spellEntry.GetEffects())
{ {
if (effect == null) if (spellEffectInfo.ApplyAuraName == AuraType.ControlVehicle)
continue;
if (effect.ApplyAuraName == AuraType.ControlVehicle)
{ {
valid = true; valid = true;
break; break;
@@ -2575,11 +2568,8 @@ namespace Game.Entities
else // This can happen during Player._LoadAuras else // This can happen during Player._LoadAuras
{ {
int[] bp = new int[SpellConst.MaxEffects]; int[] bp = new int[SpellConst.MaxEffects];
foreach (SpellEffectInfo effect in spellEntry.GetEffects()) foreach (var spellEffectInfo in spellEntry.GetEffects())
{ bp[spellEffectInfo.EffectIndex] = spellEffectInfo.BasePoints;
if (effect != null)
bp[effect.EffectIndex] = effect.BasePoints;
}
bp[i] = seatId; bp[i] = seatId;
@@ -2643,7 +2633,7 @@ namespace Game.Entities
if (spellInfo.Mechanic != 0 && Convert.ToBoolean(mechanicMask & (1 << (int)spellInfo.Mechanic))) if (spellInfo.Mechanic != 0 && Convert.ToBoolean(mechanicMask & (1 << (int)spellInfo.Mechanic)))
return true; return true;
foreach (SpellEffectInfo spellEffectInfo in spellInfo.GetEffects()) foreach (var spellEffectInfo in spellInfo.GetEffects())
if (spellEffectInfo != null && pair.Value.HasEffect(spellEffectInfo.EffectIndex) && spellEffectInfo.IsEffect() && spellEffectInfo.Mechanic != 0) if (spellEffectInfo != null && pair.Value.HasEffect(spellEffectInfo.EffectIndex) && spellEffectInfo.IsEffect() && spellEffectInfo.Mechanic != 0)
if ((mechanicMask & (1 << (int)spellEffectInfo.Mechanic)) != 0) if ((mechanicMask & (1 << (int)spellEffectInfo.Mechanic)) != 0)
return true; return true;
@@ -3891,22 +3881,19 @@ namespace Game.Entities
return null; return null;
// update basepoints with new values - effect amount will be recalculated in ModStackAmount // update basepoints with new values - effect amount will be recalculated in ModStackAmount
foreach (SpellEffectInfo effect in createInfo.GetSpellInfo().GetEffects()) foreach (var spellEffectInfo in createInfo.GetSpellInfo().GetEffects())
{ {
if (effect == null) AuraEffect auraEff = foundAura.GetEffect(spellEffectInfo.EffectIndex);
continue; if (auraEff == null)
AuraEffect eff = foundAura.GetEffect(effect.EffectIndex);
if (eff == null)
continue; continue;
int bp; int bp;
if (createInfo.BaseAmount != null) if (createInfo.BaseAmount != null)
bp = createInfo.BaseAmount[effect.EffectIndex]; bp = createInfo.BaseAmount[spellEffectInfo.EffectIndex];
else else
bp = effect.BasePoints; bp = spellEffectInfo.BasePoints;
eff.m_baseAmount = bp; auraEff.m_baseAmount = bp;
} }
// correct cast item guid if needed // correct cast item guid if needed
+6 -10
View File
@@ -2089,7 +2089,7 @@ namespace Game.Entities
RemoveDynamicUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.ChannelObjects), index); RemoveDynamicUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.ChannelObjects), index);
} }
public static bool IsDamageReducedByArmor(SpellSchoolMask schoolMask, SpellInfo spellInfo = null, sbyte effIndex = -1) public static bool IsDamageReducedByArmor(SpellSchoolMask schoolMask, SpellInfo spellInfo = null, SpellEffectInfo spellEffectInfo = null)
{ {
// only physical spells damage gets reduced by armor // only physical spells damage gets reduced by armor
if ((schoolMask & SpellSchoolMask.Normal) == 0) if ((schoolMask & SpellSchoolMask.Normal) == 0)
@@ -2101,16 +2101,12 @@ namespace Game.Entities
if (spellInfo.HasAttribute(SpellCustomAttributes.IgnoreArmor)) if (spellInfo.HasAttribute(SpellCustomAttributes.IgnoreArmor))
return false; return false;
if (effIndex != -1) // bleeding effects are not reduced by armor
if (spellEffectInfo != null)
{ {
// bleeding effects are not reduced by armor if (spellEffectInfo.ApplyAuraName == AuraType.PeriodicDamage || spellEffectInfo.Effect == SpellEffectName.SchoolDamage)
SpellEffectInfo effect = spellInfo.GetEffect((uint)effIndex); if (spellInfo.GetEffectMechanicMask(spellEffectInfo.EffectIndex).HasAnyFlag((1u << (int)Mechanics.Bleed)))
if (effect != null) return false;
{
if (effect.ApplyAuraName == AuraType.PeriodicDamage || effect.Effect == SpellEffectName.SchoolDamage)
if (spellInfo.GetEffectMechanicMask((byte)effIndex).HasAnyFlag((1u << (int)Mechanics.Bleed)))
return false;
}
} }
} }
+16 -11
View File
@@ -1447,11 +1447,16 @@ namespace Game
continue; continue;
} }
byte i = (byte)((script.Key >> 24) & 0x000000FF); byte spellEffIndex = (byte)((script.Key >> 24) & 0x000000FF);
if (spellEffIndex >= spellInfo.GetEffects().Count)
{
Log.outError(LogFilter.Sql, $"Table `spell_scripts` has too high effect index {spellEffIndex} for spell (Id: {spellId}) as script id");
continue;
}
//check for correct spellEffect //check for correct spellEffect
SpellEffectInfo effect = spellInfo.GetEffect(i); if (spellInfo.GetEffect(spellEffIndex).Effect == 0 || (spellInfo.GetEffect(spellEffIndex).Effect != SpellEffectName.ScriptEffect && spellInfo.GetEffect(spellEffIndex).Effect != SpellEffectName.Dummy))
if (effect != null && (effect.Effect == 0 || (effect.Effect != SpellEffectName.ScriptEffect && effect.Effect != SpellEffectName.Dummy))) Log.outError(LogFilter.Sql, $"Table `spell_scripts` - spell {spellId} effect {spellEffIndex} is not SPELL_EFFECT_SCRIPT_EFFECT or SPELL_EFFECT_DUMMY");
Log.outError(LogFilter.Sql, "Table `spell_scripts` - spell {0} effect {1} is not SPELL_EFFECT_SCRIPT_EFFECT or SPELL_EFFECT_DUMMY", spellId, i);
} }
} }
public void LoadEventScripts() public void LoadEventScripts()
@@ -1473,11 +1478,11 @@ namespace Game
SpellInfo spell = Global.SpellMgr.GetSpellInfo(spellNameEntry.Id, Difficulty.None); SpellInfo spell = Global.SpellMgr.GetSpellInfo(spellNameEntry.Id, Difficulty.None);
if (spell != null) if (spell != null)
{ {
foreach (SpellEffectInfo effect in spell.GetEffects()) foreach (var spellEffectInfo in spell.GetEffects())
{ {
if (effect != null && effect.Effect == SpellEffectName.SendEvent) if (spellEffectInfo.IsEffect(SpellEffectName.SendEvent))
if (effect.MiscValue != 0) if (spellEffectInfo.MiscValue != 0)
evt_scripts.Add((uint)effect.MiscValue); evt_scripts.Add((uint)spellEffectInfo.MiscValue);
} }
} }
} }
@@ -7516,12 +7521,12 @@ namespace Game
if (spellInfo == null) if (spellInfo == null)
continue; continue;
foreach (SpellEffectInfo effect in spellInfo.GetEffects()) foreach (var spellEffectInfo in spellInfo.GetEffects())
{ {
if (effect == null || effect.Effect != SpellEffectName.QuestComplete) if (spellEffectInfo.Effect != SpellEffectName.QuestComplete)
continue; continue;
uint questId = (uint)effect.MiscValue; uint questId = (uint)spellEffectInfo.MiscValue;
Quest quest = GetQuestTemplate(questId); Quest quest = GetQuestTemplate(questId);
// some quest referenced in spells not exist (outdated spells) // some quest referenced in spells not exist (outdated spells)
+2 -2
View File
@@ -294,9 +294,9 @@ namespace Game
return; return;
} }
foreach (SpellEffectInfo effect in spellInfo.GetEffects()) foreach (var spellEffectInfo in spellInfo.GetEffects())
{ {
if (effect != null && (effect.TargetA.GetTarget() == Targets.UnitSrcAreaEnemy || effect.TargetA.GetTarget() == Targets.UnitDestAreaEnemy || effect.TargetA.GetTarget() == Targets.DestDynobjEnemy)) if (spellEffectInfo.TargetA.GetTarget() == Targets.UnitSrcAreaEnemy || spellEffectInfo.TargetA.GetTarget() == Targets.UnitDestAreaEnemy || spellEffectInfo.TargetA.GetTarget() == Targets.DestDynobjEnemy)
return; return;
} }
+23 -15
View File
@@ -134,7 +134,7 @@ namespace Game.Scripting
public virtual void Register() { } public virtual void Register() { }
// Function called on server startup, if returns false script won't be used in core // Function called on server startup, if returns false script won't be used in core
// use for: dbc/template data presence/correctness checks // use for: dbc/template data presence/correctness checks
public virtual bool Validate(SpellInfo spellEntry) { return true; } public virtual bool Validate(SpellInfo spellInfo) { return true; }
// Function called when script is created, if returns false script will be unloaded afterwards // Function called when script is created, if returns false script will be unloaded afterwards
// use for: initializing local script variables (DO NOT USE CONSTRUCTOR FOR THIS PURPOSE!) // use for: initializing local script variables (DO NOT USE CONSTRUCTOR FOR THIS PURPOSE!)
public virtual bool Load() { return true; } public virtual bool Load() { return true; }
@@ -194,15 +194,15 @@ namespace Game.Scripting
public override bool CheckEffect(SpellInfo spellEntry, uint effIndex) public override bool CheckEffect(SpellInfo spellEntry, uint effIndex)
{ {
SpellEffectInfo effect = spellEntry.GetEffect(effIndex); if (spellEntry.GetEffects().Count <= effIndex)
if (effect == null)
return false; return false;
if (effect.Effect == 0 && _effName == 0) SpellEffectInfo spellEffectInfo = spellEntry.GetEffect(effIndex);
if (spellEffectInfo.Effect == 0 && _effName == 0)
return true; return true;
if (effect.Effect == 0) if (spellEffectInfo.Effect == 0)
return false; return false;
return (_effName == SpellEffectName.Any) || (effect.Effect == _effName); return (_effName == SpellEffectName.Any) || (spellEffectInfo.Effect == _effName);
} }
public void Call(uint effIndex) public void Call(uint effIndex)
@@ -267,16 +267,16 @@ namespace Game.Scripting
_dest = dest; _dest = dest;
} }
public override bool CheckEffect(SpellInfo spellEntry, uint effIndex) public override bool CheckEffect(SpellInfo spellEntry, uint effIndexToCheck)
{ {
if (_targetType == 0) if (_targetType == 0)
return false; return false;
SpellEffectInfo effect = spellEntry.GetEffect(effIndex); if (spellEntry.GetEffects().Count <= effIndexToCheck)
if (effect == null)
return false; return false;
if (effect.TargetA.GetTarget() != _targetType && effect.TargetB.GetTarget() != _targetType) SpellEffectInfo spellEffectInfo = spellEntry.GetEffect(effIndexToCheck);
if (spellEffectInfo.TargetA.GetTarget() != _targetType && spellEffectInfo.TargetB.GetTarget() != _targetType)
return false; return false;
SpellImplicitTargetInfo targetInfo = new(_targetType); SpellImplicitTargetInfo targetInfo = new(_targetType);
@@ -896,15 +896,17 @@ namespace Game.Scripting
public override bool CheckEffect(SpellInfo spellEntry, uint effIndex) public override bool CheckEffect(SpellInfo spellEntry, uint effIndex)
{ {
SpellEffectInfo effect = spellEntry.GetEffect(effIndex); if (spellEntry.GetEffects().Count <= effIndex)
if (effect == null)
return false; return false;
if (effect.ApplyAuraName == 0 && effAurName == 0) SpellEffectInfo spellEffectInfo = spellEntry.GetEffect(effIndex);
if (spellEffectInfo.ApplyAuraName == 0 && effAurName == 0)
return true; return true;
if (effect.ApplyAuraName == 0)
if (spellEffectInfo.ApplyAuraName == 0)
return false; return false;
return (effAurName == AuraType.Any) || (effect.ApplyAuraName == effAurName);
return (effAurName == AuraType.Any) || (spellEffectInfo.ApplyAuraName == effAurName);
} }
AuraType effAurName; AuraType effAurName;
@@ -1448,6 +1450,12 @@ namespace Game.Scripting
// returns proto of the spell // returns proto of the spell
public SpellInfo GetSpellInfo() { return m_aura.GetSpellInfo(); } public SpellInfo GetSpellInfo() { return m_aura.GetSpellInfo(); }
public SpellEffectInfo GetEffectInfo(uint effIndex)
{
return m_aura.GetSpellInfo().GetEffect(effIndex);
}
// returns spellid of the spell // returns spellid of the spell
public uint GetId() { return m_aura.GetId(); } public uint GetId() { return m_aura.GetId(); }
+73 -68
View File
@@ -129,9 +129,9 @@ namespace Game.Spells
if (IsSelfcasted() || caster == null || !caster.IsFriendlyTo(GetTarget())) if (IsSelfcasted() || caster == null || !caster.IsFriendlyTo(GetTarget()))
{ {
bool negativeFound = false; bool negativeFound = false;
foreach (SpellEffectInfo effect in GetBase().GetSpellInfo().GetEffects()) foreach (var spellEffectInfo in GetBase().GetSpellInfo().GetEffects())
{ {
if (effect != null && (Convert.ToBoolean((1 << (int)effect.EffectIndex) & effMask) && !GetBase().GetSpellInfo().IsPositiveEffect(effect.EffectIndex))) if (((1 << (int)spellEffectInfo.EffectIndex) & effMask) != 0 && !GetBase().GetSpellInfo().IsPositiveEffect(spellEffectInfo.EffectIndex))
{ {
negativeFound = true; negativeFound = true;
break; break;
@@ -144,9 +144,9 @@ namespace Game.Spells
else else
{ {
bool positiveFound = false; bool positiveFound = false;
foreach (SpellEffectInfo effect in GetBase().GetSpellInfo().GetEffects()) foreach (var spellEffectInfo in GetBase().GetSpellInfo().GetEffects())
{ {
if (effect != null && (Convert.ToBoolean((1 << (int)effect.EffectIndex) & effMask) && GetBase().GetSpellInfo().IsPositiveEffect(effect.EffectIndex))) if (((1 << (int)spellEffectInfo.EffectIndex) & effMask) != 0 && GetBase().GetSpellInfo().IsPositiveEffect(spellEffectInfo.EffectIndex))
{ {
positiveFound = true; positiveFound = true;
break; break;
@@ -380,10 +380,10 @@ namespace Game.Spells
// shouldn't be in constructor - functions in AuraEffect.AuraEffect use polymorphism // shouldn't be in constructor - functions in AuraEffect.AuraEffect use polymorphism
_effects = new AuraEffect[SpellConst.MaxEffects]; _effects = new AuraEffect[SpellConst.MaxEffects];
foreach (SpellEffectInfo effect in GetSpellInfo().GetEffects()) foreach (var spellEffectInfo in GetSpellInfo().GetEffects())
{ {
if (effect != null && Convert.ToBoolean(effMask & (1 << (int)effect.EffectIndex))) if ((effMask & (1 << (int)spellEffectInfo.EffectIndex)) != 0)
_effects[effect.EffectIndex] = new AuraEffect(this, effect, baseAmount != null ? baseAmount[effect.EffectIndex] : null, caster); _effects[spellEffectInfo.EffectIndex] = new AuraEffect(this, spellEffectInfo, baseAmount != null ? baseAmount[spellEffectInfo.EffectIndex] : null, caster);
} }
} }
@@ -518,10 +518,10 @@ namespace Game.Spells
bool addUnit = true; bool addUnit = true;
// check target immunities // check target immunities
for (byte effIndex = 0; effIndex < SpellConst.MaxEffects; ++effIndex) foreach (var spellEffectInfo in GetSpellInfo().GetEffects())
{ {
if (unit.IsImmunedToSpellEffect(GetSpellInfo(), effIndex, caster)) if (unit.IsImmunedToSpellEffect(GetSpellInfo(), spellEffectInfo, caster))
value &= ~(1u << effIndex); value &= ~(1u << (int)spellEffectInfo.EffectIndex);
} }
@@ -954,9 +954,9 @@ namespace Game.Spells
public bool HasMoreThanOneEffectForType(AuraType auraType) public bool HasMoreThanOneEffectForType(AuraType auraType)
{ {
uint count = 0; uint count = 0;
foreach (SpellEffectInfo effect in GetSpellInfo().GetEffects()) foreach (var spellEffectInfo in GetSpellInfo().GetEffects())
{ {
if (effect != null && HasEffect(effect.EffectIndex) && effect.ApplyAuraName == auraType) if (HasEffect(spellEffectInfo.EffectIndex) && spellEffectInfo.ApplyAuraName == auraType)
++count; ++count;
} }
@@ -965,9 +965,9 @@ namespace Game.Spells
public bool IsArea() public bool IsArea()
{ {
foreach (SpellEffectInfo effect in GetSpellInfo().GetEffects()) foreach (var spellEffectInfo in GetSpellInfo().GetEffects())
{ {
if (effect != null && HasEffect(effect.EffectIndex) && effect.IsAreaAuraEffect()) if (HasEffect(spellEffectInfo.EffectIndex) && spellEffectInfo.IsAreaAuraEffect())
return true; return true;
} }
return false; return false;
@@ -1003,12 +1003,12 @@ namespace Game.Spells
if (GetCasterGUID() != GetOwner().GetGUID()) if (GetCasterGUID() != GetOwner().GetGUID())
{ {
// owner == caster for area auras, check for possible bad data in DB // owner == caster for area auras, check for possible bad data in DB
foreach (SpellEffectInfo effect in GetSpellInfo().GetEffects()) foreach (var spellEffectInfo in GetSpellInfo().GetEffects())
{ {
if (effect == null || !effect.IsEffect()) if (!spellEffectInfo.IsEffect())
continue; continue;
if (effect.IsTargetingArea() || effect.IsAreaAuraEffect()) if (spellEffectInfo.IsTargetingArea() || spellEffectInfo.IsAreaAuraEffect())
return false; return false;
} }
@@ -1496,17 +1496,17 @@ namespace Game.Spells
if (IsPassive() && sameCaster && (m_spellInfo.IsDifferentRankOf(existingSpellInfo) || (m_spellInfo.Id == existingSpellInfo.Id && m_castItemGuid.IsEmpty()))) if (IsPassive() && sameCaster && (m_spellInfo.IsDifferentRankOf(existingSpellInfo) || (m_spellInfo.Id == existingSpellInfo.Id && m_castItemGuid.IsEmpty())))
return false; return false;
foreach (SpellEffectInfo effect in existingSpellInfo.GetEffects()) foreach (var spellEffectInfo in existingSpellInfo.GetEffects())
{ {
// prevent remove triggering aura by triggered aura // prevent remove triggering aura by triggered aura
if (effect != null && effect.TriggerSpell == GetId()) if (spellEffectInfo.TriggerSpell == GetId())
return true; return true;
} }
foreach (SpellEffectInfo effect in GetSpellInfo().GetEffects()) foreach (var spellEffectInfo in GetSpellInfo().GetEffects())
{ {
// prevent remove triggered aura by triggering aura refresh // prevent remove triggered aura by triggering aura refresh
if (effect != null && effect.TriggerSpell == existingAura.GetId()) if (spellEffectInfo.TriggerSpell == existingAura.GetId())
return true; return true;
} }
@@ -1544,35 +1544,40 @@ namespace Game.Spells
return true; return true;
// check same periodic auras // check same periodic auras
for (byte i = 0; i < SpellConst.MaxEffects; i++) bool hasPeriodicNonAreaEffect(SpellInfo spellInfo)
{ {
SpellEffectInfo effect = m_spellInfo.GetEffect(i); foreach (var spellEffectInfo in spellInfo.GetEffects())
if (effect == null)
continue;
switch (effect.ApplyAuraName)
{ {
// DOT or HOT from different casters will stack switch (spellEffectInfo.ApplyAuraName)
case AuraType.PeriodicDamage: {
case AuraType.PeriodicDummy: // DOT or HOT from different casters will stack
case AuraType.PeriodicHeal: case AuraType.PeriodicDamage:
case AuraType.PeriodicTriggerSpell: case AuraType.PeriodicDummy:
case AuraType.PeriodicEnergize: case AuraType.PeriodicHeal:
case AuraType.PeriodicManaLeech: case AuraType.PeriodicTriggerSpell:
case AuraType.PeriodicLeech: case AuraType.PeriodicEnergize:
case AuraType.PowerBurn: case AuraType.PeriodicManaLeech:
case AuraType.ObsModPower: case AuraType.PeriodicLeech:
case AuraType.ObsModHealth: case AuraType.PowerBurn:
case AuraType.PeriodicTriggerSpellWithValue: case AuraType.ObsModPower:
SpellEffectInfo existingEffect = m_spellInfo.GetEffect(i); case AuraType.ObsModHealth:
// periodic auras which target areas are not allowed to stack this way (replenishment for example) case AuraType.PeriodicTriggerSpellWithValue:
if (effect.IsTargetingArea() || (existingEffect != null && existingEffect.IsTargetingArea())) {
// periodic auras which target areas are not allowed to stack this way (replenishment for example)
if (spellEffectInfo.IsTargetingArea())
return false;
return true;
}
default:
break; break;
return true; }
default:
break;
} }
return false;
} }
if (hasPeriodicNonAreaEffect(m_spellInfo) && hasPeriodicNonAreaEffect(existingSpellInfo))
return true;
} }
if (HasEffectType(AuraType.ControlVehicle) && existingAura.HasEffectType(AuraType.ControlVehicle)) if (HasEffectType(AuraType.ControlVehicle) && existingAura.HasEffectType(AuraType.ControlVehicle))
@@ -2398,17 +2403,17 @@ namespace Game.Spells
{ {
case TypeId.Unit: case TypeId.Unit:
case TypeId.Player: case TypeId.Player:
foreach (SpellEffectInfo effect in spellProto.GetEffects()) foreach (var spellEffectInfo in spellProto.GetEffects())
{ {
if (effect != null && effect.IsUnitOwnedAuraEffect()) if (spellEffectInfo.IsUnitOwnedAuraEffect())
effMask |= (uint)(1 << (int)effect.EffectIndex); effMask |= (1u << (int)spellEffectInfo.EffectIndex);
} }
break; break;
case TypeId.DynamicObject: case TypeId.DynamicObject:
foreach (SpellEffectInfo effect in spellProto.GetEffects()) foreach (var spellEffectInfo in spellProto.GetEffects())
{ {
if (effect != null && effect.Effect == SpellEffectName.PersistentAreaAura) if (spellEffectInfo.Effect == SpellEffectName.PersistentAreaAura)
effMask |= (uint)(1 << (int)effect.EffectIndex); effMask |= (1u << (int)spellEffectInfo.EffectIndex);
} }
break; break;
default: default:
@@ -2627,13 +2632,13 @@ namespace Game.Spells
targets.Add(target, targetPair.Value); targets.Add(target, targetPair.Value);
} }
foreach (SpellEffectInfo effect in GetSpellInfo().GetEffects()) foreach (var spellEffectInfo in GetSpellInfo().GetEffects())
{ {
if (effect == null || !HasEffect(effect.EffectIndex)) if (!HasEffect(spellEffectInfo.EffectIndex))
continue; continue;
// area auras only // area auras only
if (effect.Effect == SpellEffectName.ApplyAura) if (spellEffectInfo.Effect == SpellEffectName.ApplyAura)
continue; continue;
// skip area update if owner is not in world! // skip area update if owner is not in world!
@@ -2644,11 +2649,11 @@ namespace Game.Spells
continue; continue;
List<Unit> units = new(); List<Unit> units = new();
var condList = effect.ImplicitTargetConditions; var condList = spellEffectInfo.ImplicitTargetConditions;
float radius = effect.CalcRadius(refe); float radius = spellEffectInfo.CalcRadius(refe);
SpellTargetCheckTypes selectionType = SpellTargetCheckTypes.Default; SpellTargetCheckTypes selectionType = SpellTargetCheckTypes.Default;
switch (effect.Effect) switch (spellEffectInfo.Effect)
{ {
case SpellEffectName.ApplyAreaAuraParty: case SpellEffectName.ApplyAreaAuraParty:
case SpellEffectName.ApplyAreaAuraPartyNonrandom: case SpellEffectName.ApplyAreaAuraPartyNonrandom:
@@ -2709,7 +2714,7 @@ namespace Game.Spells
if (!targets.ContainsKey(unit)) if (!targets.ContainsKey(unit))
targets[unit] = 0; targets[unit] = 0;
targets[unit] |= 1u << (int)effect.EffectIndex; targets[unit] |= 1u << (int)spellEffectInfo.EffectIndex;
} }
} }
} }
@@ -2717,10 +2722,10 @@ namespace Game.Spells
public void AddStaticApplication(Unit target, uint effMask) public void AddStaticApplication(Unit target, uint effMask)
{ {
// only valid for non-area auras // only valid for non-area auras
foreach (SpellEffectInfo effect in GetSpellInfo().GetEffects()) foreach (var spellEffectInfo in GetSpellInfo().GetEffects())
{ {
if (effect != null && (effMask & (1u << (int)effect.EffectIndex)) != 0 && effect.Effect != SpellEffectName.ApplyAura) if ((effMask & (1u << (int)spellEffectInfo.EffectIndex)) != 0 && spellEffectInfo.IsEffect(SpellEffectName.ApplyAura))
effMask &= ~(1u << (int)effect.EffectIndex); effMask &= ~(1u << (int)spellEffectInfo.EffectIndex);
} }
if (effMask == 0) if (effMask == 0)
@@ -2765,18 +2770,18 @@ namespace Game.Spells
Unit dynObjOwnerCaster = GetDynobjOwner().GetCaster(); Unit dynObjOwnerCaster = GetDynobjOwner().GetCaster();
float radius = GetDynobjOwner().GetRadius(); float radius = GetDynobjOwner().GetRadius();
foreach (SpellEffectInfo effect in GetSpellInfo().GetEffects()) foreach (var spellEffectInfo in GetSpellInfo().GetEffects())
{ {
if (effect == null || !HasEffect(effect.EffectIndex)) if (!HasEffect(spellEffectInfo.EffectIndex))
continue; continue;
// we can't use effect type like area auras to determine check type, check targets // we can't use effect type like area auras to determine check type, check targets
SpellTargetCheckTypes selectionType = effect.TargetA.GetCheckType(); SpellTargetCheckTypes selectionType = spellEffectInfo.TargetA.GetCheckType();
if (effect.TargetB.GetReferenceType() == SpellTargetReferenceTypes.Dest) if (spellEffectInfo.TargetB.GetReferenceType() == SpellTargetReferenceTypes.Dest)
selectionType = effect.TargetB.GetCheckType(); selectionType = spellEffectInfo.TargetB.GetCheckType();
List<Unit> targetList = new(); List<Unit> targetList = new();
var condList = effect.ImplicitTargetConditions; var condList = spellEffectInfo.ImplicitTargetConditions;
WorldObjectSpellAreaTargetCheck check = new(radius, GetDynobjOwner(), dynObjOwnerCaster, dynObjOwnerCaster, GetSpellInfo(), selectionType, condList, SpellTargetObjectTypes.Unit); WorldObjectSpellAreaTargetCheck check = new(radius, GetDynobjOwner(), dynObjOwnerCaster, dynObjOwnerCaster, GetSpellInfo(), selectionType, condList, SpellTargetObjectTypes.Unit);
UnitListSearcher searcher = new(GetDynobjOwner(), targetList, check); UnitListSearcher searcher = new(GetDynobjOwner(), targetList, check);
@@ -2790,7 +2795,7 @@ namespace Game.Spells
if (!targets.ContainsKey(unit)) if (!targets.ContainsKey(unit))
targets[unit] = 0; targets[unit] = 0;
targets[unit] |= 1u << (int)effect.EffectIndex; targets[unit] |= 1u << (int)spellEffectInfo.EffectIndex;
} }
} }
} }
+12 -12
View File
@@ -2097,8 +2097,8 @@ namespace Game.Spells
} }
//some spell has one aura of mount and one of vehicle //some spell has one aura of mount and one of vehicle
foreach (SpellEffectInfo effect in GetSpellInfo().GetEffects()) foreach (var spellEffectInfo in GetSpellInfo().GetEffects())
if (effect != null && GetSpellEffectInfo().Effect == SpellEffectName.Summon && effect.MiscValue == GetMiscValue()) if (spellEffectInfo.IsEffect(SpellEffectName.Summon) && spellEffectInfo.MiscValue == GetMiscValue())
displayId = 0; displayId = 0;
} }
@@ -4910,7 +4910,7 @@ namespace Game.Spells
// Consecrate ticks can miss and will not show up in the combat log // Consecrate ticks can miss and will not show up in the combat log
// dynobj auras must always have a caster // dynobj auras must always have a caster
if (GetSpellEffectInfo().Effect == SpellEffectName.PersistentAreaAura && if (GetSpellEffectInfo().IsEffect(SpellEffectName.PersistentAreaAura) &&
caster.SpellHitResult(target, GetSpellInfo(), false) != SpellMissInfo.None) caster.SpellHitResult(target, GetSpellInfo(), false) != SpellMissInfo.None)
return; return;
@@ -4982,7 +4982,7 @@ namespace Game.Spells
damage = Unit.SpellCriticalDamageBonus(caster, m_spellInfo, damage, target); damage = Unit.SpellCriticalDamageBonus(caster, m_spellInfo, damage, target);
// Calculate armor mitigation // Calculate armor mitigation
if (Unit.IsDamageReducedByArmor(GetSpellInfo().GetSchoolMask(), GetSpellInfo(), (sbyte)GetEffIndex())) if (Unit.IsDamageReducedByArmor(GetSpellInfo().GetSchoolMask(), GetSpellInfo(), GetSpellEffectInfo()))
{ {
uint damageReducedArmor = Unit.CalcArmorReducedDamage(caster, target, damage, GetSpellInfo(), GetSpellInfo().GetAttackType(), GetBase().GetCasterLevel()); uint damageReducedArmor = Unit.CalcArmorReducedDamage(caster, target, damage, GetSpellInfo(), GetSpellInfo().GetAttackType(), GetBase().GetCasterLevel());
cleanDamage.mitigated_damage += damage - damageReducedArmor; cleanDamage.mitigated_damage += damage - damageReducedArmor;
@@ -4991,7 +4991,7 @@ namespace Game.Spells
if (!GetSpellInfo().HasAttribute(SpellAttr4.FixedDamage)) if (!GetSpellInfo().HasAttribute(SpellAttr4.FixedDamage))
{ {
if (GetSpellEffectInfo().IsTargetingArea() || GetSpellEffectInfo().IsAreaAuraEffect() || GetSpellEffectInfo().Effect == SpellEffectName.PersistentAreaAura) if (GetSpellEffectInfo().IsTargetingArea() || GetSpellEffectInfo().IsAreaAuraEffect() || GetSpellEffectInfo().IsEffect(SpellEffectName.PersistentAreaAura))
damage = (uint)target.CalculateAOEAvoidance((int)damage, (uint)m_spellInfo.SchoolMask, GetBase().GetCastItemGUID()); damage = (uint)target.CalculateAOEAvoidance((int)damage, (uint)m_spellInfo.SchoolMask, GetBase().GetCastItemGUID());
} }
@@ -5043,7 +5043,7 @@ namespace Game.Spells
} }
// dynobj auras must always have a caster // dynobj auras must always have a caster
if (GetSpellEffectInfo().Effect == SpellEffectName.PersistentAreaAura && if (GetSpellEffectInfo().IsEffect(SpellEffectName.PersistentAreaAura) &&
caster.SpellHitResult(target, GetSpellInfo(), false) != SpellMissInfo.None) caster.SpellHitResult(target, GetSpellInfo(), false) != SpellMissInfo.None)
return; return;
@@ -5064,7 +5064,7 @@ namespace Game.Spells
damage = Unit.SpellCriticalDamageBonus(caster, m_spellInfo, damage, target); damage = Unit.SpellCriticalDamageBonus(caster, m_spellInfo, damage, target);
// Calculate armor mitigation // Calculate armor mitigation
if (Unit.IsDamageReducedByArmor(GetSpellInfo().GetSchoolMask(), GetSpellInfo(), (sbyte)GetEffIndex())) if (Unit.IsDamageReducedByArmor(GetSpellInfo().GetSchoolMask(), GetSpellInfo(), GetSpellEffectInfo()))
{ {
uint damageReducedArmor = Unit.CalcArmorReducedDamage(caster, target, damage, GetSpellInfo(), GetSpellInfo().GetAttackType(), GetBase().GetCasterLevel()); uint damageReducedArmor = Unit.CalcArmorReducedDamage(caster, target, damage, GetSpellInfo(), GetSpellInfo().GetAttackType(), GetBase().GetCasterLevel());
cleanDamage.mitigated_damage += damage - damageReducedArmor; cleanDamage.mitigated_damage += damage - damageReducedArmor;
@@ -5073,7 +5073,7 @@ namespace Game.Spells
if (!GetSpellInfo().HasAttribute(SpellAttr4.FixedDamage)) if (!GetSpellInfo().HasAttribute(SpellAttr4.FixedDamage))
{ {
if (GetSpellEffectInfo().IsTargetingArea() || GetSpellEffectInfo().IsAreaAuraEffect() || GetSpellEffectInfo().Effect == SpellEffectName.PersistentAreaAura) if (GetSpellEffectInfo().IsTargetingArea() || GetSpellEffectInfo().IsAreaAuraEffect() || GetSpellEffectInfo().IsEffect(SpellEffectName.PersistentAreaAura))
damage = (uint)target.CalculateAOEAvoidance((int)damage, (uint)m_spellInfo.SchoolMask, GetBase().GetCastItemGUID()); damage = (uint)target.CalculateAOEAvoidance((int)damage, (uint)m_spellInfo.SchoolMask, GetBase().GetCastItemGUID());
} }
@@ -5236,7 +5236,7 @@ namespace Game.Spells
return; return;
} }
if (GetSpellEffectInfo().Effect == SpellEffectName.PersistentAreaAura && if (GetSpellEffectInfo().IsEffect(SpellEffectName.PersistentAreaAura) &&
caster.SpellHitResult(target, GetSpellInfo(), false) != SpellMissInfo.None) caster.SpellHitResult(target, GetSpellInfo(), false) != SpellMissInfo.None)
return; return;
@@ -5648,11 +5648,11 @@ namespace Game.Spells
else else
{ {
List<uint> summonedEntries = new(); List<uint> summonedEntries = new();
foreach (var spellEffect in triggerSpellInfo.GetEffects()) foreach (var spellEffectInfo in triggerSpellInfo.GetEffects())
{ {
if (spellEffect != null && spellEffect.Effect == SpellEffectName.Summon) if (spellEffectInfo.IsEffect(SpellEffectName.Summon))
{ {
uint summonEntry = (uint)spellEffect.MiscValue; uint summonEntry = (uint)spellEffectInfo.MiscValue;
if (summonEntry != 0) if (summonEntry != 0)
summonedEntries.Add(summonEntry); summonedEntries.Add(summonEntry);
File diff suppressed because it is too large Load Diff
+13 -26
View File
@@ -37,7 +37,7 @@ namespace Game.Spells
{ {
public partial class Spell public partial class Spell
{ {
[SpellEffectHandler(SpellEffectName.Null)] [SpellEffectHandler(SpellEffectName.None)]
[SpellEffectHandler(SpellEffectName.Portal)] [SpellEffectHandler(SpellEffectName.Portal)]
[SpellEffectHandler(SpellEffectName.BindSight)] [SpellEffectHandler(SpellEffectName.BindSight)]
[SpellEffectHandler(SpellEffectName.CallPet)] [SpellEffectHandler(SpellEffectName.CallPet)]
@@ -1155,12 +1155,9 @@ namespace Game.Spells
return; return;
// only handle at last effect // only handle at last effect
for (uint i = effectInfo.EffectIndex + 1; i < SpellConst.MaxEffects; ++i) for (uint i = effectInfo.EffectIndex + 1; i < m_spellInfo.GetEffects().Count; ++i)
{ if (m_spellInfo.GetEffect(i).IsEffect(SpellEffectName.PersistentAreaAura))
SpellEffectInfo otherEffect = m_spellInfo.GetEffect(i);
if (otherEffect != null && otherEffect.IsEffect(SpellEffectName.PersistentAreaAura))
return; return;
}
Cypher.Assert(dynObjAura == null); Cypher.Assert(dynObjAura == null);
@@ -2482,13 +2479,9 @@ namespace Game.Spells
// multiple weapon dmg effect workaround // multiple weapon dmg effect workaround
// execute only the last weapon damage // execute only the last weapon damage
// and handle all effects at once // and handle all effects at once
for (var j = effectInfo.EffectIndex + 1; j < SpellConst.MaxEffects; ++j) for (var j = effectInfo.EffectIndex + 1; j < m_spellInfo.GetEffects().Count; ++j)
{ {
var effect = m_spellInfo.GetEffect(j); switch (m_spellInfo.GetEffect(j).Effect)
if (effect == null)
continue;
switch (effect.Effect)
{ {
case SpellEffectName.WeaponDamage: case SpellEffectName.WeaponDamage:
case SpellEffectName.WeaponDamageNoSchool: case SpellEffectName.WeaponDamageNoSchool:
@@ -2518,23 +2511,20 @@ namespace Game.Spells
bool normalized = false; bool normalized = false;
float weaponDamagePercentMod = 1.0f; float weaponDamagePercentMod = 1.0f;
foreach (SpellEffectInfo effect in m_spellInfo.GetEffects()) foreach (var spellEffectInfo in m_spellInfo.GetEffects())
{ {
if (effect == null) switch (spellEffectInfo.Effect)
continue;
switch (effect.Effect)
{ {
case SpellEffectName.WeaponDamage: case SpellEffectName.WeaponDamage:
case SpellEffectName.WeaponDamageNoSchool: case SpellEffectName.WeaponDamageNoSchool:
fixed_bonus += CalculateDamage(effect.EffectIndex, unitTarget); fixed_bonus += CalculateDamage(spellEffectInfo, unitTarget);
break; break;
case SpellEffectName.NormalizedWeaponDmg: case SpellEffectName.NormalizedWeaponDmg:
fixed_bonus += CalculateDamage(effect.EffectIndex, unitTarget); fixed_bonus += CalculateDamage(spellEffectInfo, unitTarget);
normalized = true; normalized = true;
break; break;
case SpellEffectName.WeaponPercentDamage: case SpellEffectName.WeaponPercentDamage:
MathFunctions.ApplyPct(ref weaponDamagePercentMod, CalculateDamage(effect.EffectIndex, unitTarget)); MathFunctions.ApplyPct(ref weaponDamagePercentMod, CalculateDamage(spellEffectInfo, unitTarget));
break; break;
default: default:
break; // not weapon damage effect, just skip break; // not weapon damage effect, just skip
@@ -2571,14 +2561,11 @@ namespace Game.Spells
uint weaponDamage = unitCaster.CalculateDamage(m_attackType, normalized, addPctMods); uint weaponDamage = unitCaster.CalculateDamage(m_attackType, normalized, addPctMods);
// Sequence is important // Sequence is important
foreach (SpellEffectInfo effect in m_spellInfo.GetEffects()) foreach (var spellEffectInfo in m_spellInfo.GetEffects())
{ {
if (effect == null)
continue;
// We assume that a spell have at most one fixed_bonus // We assume that a spell have at most one fixed_bonus
// and at most one weaponDamagePercentMod // and at most one weaponDamagePercentMod
switch (effect.Effect) switch (spellEffectInfo.Effect)
{ {
case SpellEffectName.WeaponDamage: case SpellEffectName.WeaponDamage:
case SpellEffectName.WeaponDamageNoSchool: case SpellEffectName.WeaponDamageNoSchool:
@@ -3092,7 +3079,7 @@ namespace Game.Spells
{ {
// @todo a hack, range = 11, should after some time cast, otherwise too far // @todo a hack, range = 11, should after some time cast, otherwise too far
unitCaster.CastSpell(parent, 62496, new CastSpellExtraArgs(true)); unitCaster.CastSpell(parent, 62496, new CastSpellExtraArgs(true));
unitTarget.CastSpell(parent, (uint)m_spellInfo.GetEffect(0).CalcValue()); unitTarget.CastSpell(parent, (uint)damage); // DIFFICULTY_NONE, so effect always valid
} }
} }
} }
+175 -222
View File
@@ -41,7 +41,7 @@ namespace Game.Spells
if (spellEffect == null) if (spellEffect == null)
continue; continue;
_effects[spellEffect.EffectIndex] = new SpellEffectInfo(this, spellEffect); _effects.Add(new SpellEffectInfo(this, spellEffect));
} }
SpellName = spellName.Name; SpellName = spellName.Name;
@@ -246,20 +246,19 @@ namespace Game.Spells
} }
public SpellInfo(SpellNameRecord spellName, Difficulty difficulty, List<SpellEffectRecord> effects) public SpellInfo(SpellNameRecord spellName, Difficulty difficulty, List<SpellEffectRecord> effects)
{ {
Id = spellName.Id; Id = spellName.Id;
Difficulty = difficulty; Difficulty = difficulty;
SpellName = spellName.Name; SpellName = spellName.Name;
foreach (SpellEffectRecord spellEffect in effects) foreach (SpellEffectRecord spellEffect in effects)
_effects[spellEffect.EffectIndex] = new SpellEffectInfo(this, spellEffect); _effects.Add(new SpellEffectInfo(this, spellEffect));
} }
public bool HasEffect(SpellEffectName effect) public bool HasEffect(SpellEffectName effect)
{ {
foreach (SpellEffectInfo eff in _effects) foreach (var effectInfo in _effects)
if (eff != null && eff.IsEffect(effect)) if (effectInfo.IsEffect(effect))
return true; return true;
return false; return false;
@@ -267,8 +266,8 @@ namespace Game.Spells
public bool HasAura(AuraType aura) public bool HasAura(AuraType aura)
{ {
foreach (SpellEffectInfo effect in _effects) foreach (var effectInfo in _effects)
if (effect != null && effect.IsAura(aura)) if (effectInfo.IsAura(aura))
return true; return true;
return false; return false;
@@ -276,8 +275,8 @@ namespace Game.Spells
public bool HasAreaAuraEffect() public bool HasAreaAuraEffect()
{ {
foreach (SpellEffectInfo effect in _effects) foreach (var effectInfo in _effects)
if (effect != null && effect.IsAreaAuraEffect()) if (effectInfo.IsAreaAuraEffect())
return true; return true;
return false; return false;
@@ -285,12 +284,9 @@ namespace Game.Spells
public bool HasOnlyDamageEffects() public bool HasOnlyDamageEffects()
{ {
foreach (SpellEffectInfo effect in _effects) foreach (var effectInfo in _effects)
{ {
if (effect == null) switch (effectInfo.Effect)
continue;
switch (effect.Effect)
{ {
case SpellEffectName.WeaponDamage: case SpellEffectName.WeaponDamage:
case SpellEffectName.WeaponDamageNoSchool: case SpellEffectName.WeaponDamageNoSchool:
@@ -311,11 +307,9 @@ namespace Game.Spells
public bool IsExplicitDiscovery() public bool IsExplicitDiscovery()
{ {
SpellEffectInfo effect0 = GetEffect(0); return ((GetEffect(0).Effect == SpellEffectName.CreateRandomItem
SpellEffectInfo effect1 = GetEffect(1); || GetEffect(0).Effect == SpellEffectName.CreateLoot)
&& GetEffect(1).Effect == SpellEffectName.ScriptEffect)
return ((effect0 != null && (effect0.Effect == SpellEffectName.CreateRandomItem || effect0.Effect == SpellEffectName.CreateLoot))
&& effect1 != null && effect1.Effect == SpellEffectName.ScriptEffect)
|| Id == 64323; || Id == 64323;
} }
@@ -326,19 +320,19 @@ namespace Game.Spells
public bool IsQuestTame() public bool IsQuestTame()
{ {
SpellEffectInfo effect0 = GetEffect(0); if (GetEffects().Count < 2)
SpellEffectInfo effect1 = GetEffect(1); return false;
return effect0 != null && effect1 != null && effect0.Effect == SpellEffectName.Threat && effect1.Effect == SpellEffectName.ApplyAura
&& effect1.ApplyAuraName == AuraType.Dummy; return GetEffect(0).Effect == SpellEffectName.Threat && GetEffect(1).Effect == SpellEffectName.ApplyAura && GetEffect(1).ApplyAuraName == AuraType.Dummy;
} }
public bool IsProfession() public bool IsProfession()
{ {
foreach (SpellEffectInfo effect in _effects) foreach (var effectInfo in _effects)
{ {
if (effect != null && effect.Effect == SpellEffectName.Skill) if (effectInfo.IsEffect(SpellEffectName.Skill))
{ {
uint skill = (uint)effect.MiscValue; uint skill = (uint)effectInfo.MiscValue;
if (Global.SpellMgr.IsProfessionSkill(skill)) if (Global.SpellMgr.IsProfessionSkill(skill))
return true; return true;
@@ -349,10 +343,9 @@ namespace Game.Spells
public bool IsPrimaryProfession() public bool IsPrimaryProfession()
{ {
foreach (SpellEffectInfo effect in _effects) foreach (var effectInfo in _effects)
if (effect != null && effect.Effect == SpellEffectName.Skill) if (effectInfo.IsEffect(SpellEffectName.Skill) && Global.SpellMgr.IsPrimaryProfessionSkill((uint)effectInfo.MiscValue))
if (Global.SpellMgr.IsPrimaryProfessionSkill((uint)effect.MiscValue)) return true;
return true;
return false; return false;
} }
@@ -375,8 +368,8 @@ namespace Game.Spells
public bool IsAffectingArea() public bool IsAffectingArea()
{ {
foreach (SpellEffectInfo effect in _effects) foreach (var effectInfo in _effects)
if (effect != null && effect.IsEffect() && (effect.IsTargetingArea() || effect.IsEffect(SpellEffectName.PersistentAreaAura) || effect.IsAreaAuraEffect())) if (effectInfo.IsEffect() && (effectInfo.IsTargetingArea() || effectInfo.IsEffect(SpellEffectName.PersistentAreaAura) || effectInfo.IsAreaAuraEffect()))
return true; return true;
return false; return false;
@@ -385,8 +378,8 @@ namespace Game.Spells
// checks if spell targets are selected from area, doesn't include spell effects in check (like area wide auras for example) // checks if spell targets are selected from area, doesn't include spell effects in check (like area wide auras for example)
public bool IsTargetingArea() public bool IsTargetingArea()
{ {
foreach (SpellEffectInfo effect in _effects) foreach (var effectInfo in _effects)
if (effect != null && effect.IsEffect() && effect.IsTargetingArea()) if (effectInfo.IsEffect() && effectInfo.IsTargetingArea())
return true; return true;
return false; return false;
@@ -405,12 +398,12 @@ namespace Game.Spells
if (triggeringSpell.IsChanneled()) if (triggeringSpell.IsChanneled())
{ {
SpellCastTargetFlags mask = 0; SpellCastTargetFlags mask = 0;
foreach (SpellEffectInfo effect in _effects) foreach (var effectInfo in _effects)
{ {
if (effect != null && (effect.TargetA.GetTarget() != Framework.Constants.Targets.UnitCaster && effect.TargetA.GetTarget() != Framework.Constants.Targets.DestCaster if (effectInfo.TargetA.GetTarget() != Framework.Constants.Targets.UnitCaster && effectInfo.TargetA.GetTarget() != Framework.Constants.Targets.DestCaster
&& effect.TargetB.GetTarget() != Framework.Constants.Targets.UnitCaster && effect.TargetB.GetTarget() != Framework.Constants.Targets.DestCaster)) && effectInfo.TargetB.GetTarget() != Framework.Constants.Targets.UnitCaster && effectInfo.TargetB.GetTarget() != Framework.Constants.Targets.DestCaster)
{ {
mask |= effect.GetProvidedTargetMask(); mask |= effectInfo.GetProvidedTargetMask();
} }
} }
@@ -441,22 +434,19 @@ namespace Game.Spells
return false; return false;
// All stance spells. if any better way, change it. // All stance spells. if any better way, change it.
foreach (SpellEffectInfo effect in _effects) foreach (var effectInfo in _effects)
{ {
if (effect == null)
continue;
switch (SpellFamilyName) switch (SpellFamilyName)
{ {
case SpellFamilyNames.Paladin: case SpellFamilyNames.Paladin:
// Paladin aura Spell // Paladin aura Spell
if (effect.Effect == SpellEffectName.ApplyAreaAuraRaid) if (effectInfo.Effect == SpellEffectName.ApplyAreaAuraRaid)
return false; return false;
break; break;
case SpellFamilyNames.Druid: case SpellFamilyNames.Druid:
// Druid form Spell // Druid form Spell
if (effect.Effect == SpellEffectName.ApplyAura && if (effectInfo.Effect == SpellEffectName.ApplyAura &&
effect.ApplyAuraName == AuraType.ModShapeshift) effectInfo.ApplyAuraName == AuraType.ModShapeshift)
return false; return false;
break; break;
} }
@@ -504,26 +494,18 @@ namespace Game.Spells
if (HasAttribute(SpellAttr2.CanTargetDead) || Targets.HasAnyFlag(SpellCastTargetFlags.CorpseAlly | SpellCastTargetFlags.CorpseEnemy | SpellCastTargetFlags.UnitDead)) if (HasAttribute(SpellAttr2.CanTargetDead) || Targets.HasAnyFlag(SpellCastTargetFlags.CorpseAlly | SpellCastTargetFlags.CorpseEnemy | SpellCastTargetFlags.UnitDead))
return true; return true;
foreach (SpellEffectInfo effect in _effects) foreach (var effectInfo in _effects)
{ if (effectInfo.TargetA.GetObjectType() == SpellTargetObjectTypes.Corpse || effectInfo.TargetB.GetObjectType() == SpellTargetObjectTypes.Corpse)
if (effect == null)
continue;
if (effect.TargetA.GetObjectType() == SpellTargetObjectTypes.Corpse || effect.TargetB.GetObjectType() == SpellTargetObjectTypes.Corpse)
return true; return true;
}
return false; return false;
} }
public bool IsGroupBuff() public bool IsGroupBuff()
{ {
foreach (SpellEffectInfo effect in _effects) foreach (var effectInfo in _effects)
{ {
if (effect == null) switch (effectInfo.TargetA.GetCheckType())
continue;
switch (effect.TargetA.GetCheckType())
{ {
case SpellTargetCheckTypes.Party: case SpellTargetCheckTypes.Party:
case SpellTargetCheckTypes.Raid: case SpellTargetCheckTypes.Raid:
@@ -794,8 +776,7 @@ namespace Game.Spells
// talents that learn spells can have stance requirements that need ignore // talents that learn spells can have stance requirements that need ignore
// (this requirement only for client-side stance show in talent description) // (this requirement only for client-side stance show in talent description)
/* TODO: 6.x fix this in proper way (probably spell flags/attributes?) /* TODO: 6.x fix this in proper way (probably spell flags/attributes?)
if (CliDB.GetTalentSpellCost(Id) > 0 && if (CliDB.GetTalentSpellCost(Id) > 0 && HasEffect(SpellEffects.LearnSpell))
(Effects[0].Effect == SpellEffects.LearnSpell || Effects[1].Effect == SpellEffects.LearnSpell || Effects[2].Effect == SpellEffects.LearnSpell))
return SpellCastResult.SpellCastOk; return SpellCastResult.SpellCastOk;
*/ */
@@ -974,16 +955,16 @@ namespace Game.Spells
// aura limitations // aura limitations
if (player) if (player)
{ {
foreach (SpellEffectInfo effect in _effects) foreach (var effectInfo in _effects)
{ {
if (effect == null || !effect.IsAura()) if (!effectInfo.IsAura())
continue; continue;
switch (effect.ApplyAuraName) switch (effectInfo.ApplyAuraName)
{ {
case AuraType.ModShapeshift: case AuraType.ModShapeshift:
{ {
SpellShapeshiftFormRecord spellShapeshiftForm = CliDB.SpellShapeshiftFormStorage.LookupByKey(effect.MiscValue); SpellShapeshiftFormRecord spellShapeshiftForm = CliDB.SpellShapeshiftFormStorage.LookupByKey(effectInfo.MiscValue);
if (spellShapeshiftForm != null) if (spellShapeshiftForm != null)
{ {
uint mountType = spellShapeshiftForm.MountTypeID; uint mountType = spellShapeshiftForm.MountTypeID;
@@ -995,7 +976,7 @@ namespace Game.Spells
} }
case AuraType.Mounted: case AuraType.Mounted:
{ {
uint mountType = (uint)effect.MiscValueB; uint mountType = (uint)effectInfo.MiscValueB;
MountRecord mountEntry = Global.DB2Mgr.GetMount(Id); MountRecord mountEntry = Global.DB2Mgr.GetMount(Id);
if (mountEntry != null) if (mountEntry != null)
mountType = mountEntry.MountTypeID; mountType = mountEntry.MountTypeID;
@@ -1224,11 +1205,11 @@ namespace Game.Spells
if (vehicle) if (vehicle)
{ {
VehicleSeatFlags checkMask = 0; VehicleSeatFlags checkMask = 0;
foreach (SpellEffectInfo effect in _effects) foreach (var effectInfo in _effects)
{ {
if (effect != null && effect.ApplyAuraName == AuraType.ModShapeshift) if (effectInfo.IsAura(AuraType.ModShapeshift))
{ {
var shapeShiftFromEntry = CliDB.SpellShapeshiftFormStorage.LookupByKey((uint)effect.MiscValue); var shapeShiftFromEntry = CliDB.SpellShapeshiftFormStorage.LookupByKey((uint)effectInfo.MiscValue);
if (shapeShiftFromEntry != null && !shapeShiftFromEntry.Flags.HasAnyFlag(SpellShapeshiftFormFlags.Stance)) if (shapeShiftFromEntry != null && !shapeShiftFromEntry.Flags.HasAnyFlag(SpellShapeshiftFormFlags.Stance))
checkMask |= VehicleSeatFlags.Uncontrolled; checkMask |= VehicleSeatFlags.Uncontrolled;
break; break;
@@ -1249,12 +1230,12 @@ namespace Game.Spells
// Can only summon uncontrolled minions/guardians when on controlled vehicle // Can only summon uncontrolled minions/guardians when on controlled vehicle
if (vehicleSeat.HasFlag(VehicleSeatFlags.CanControl | VehicleSeatFlags.Unk2)) if (vehicleSeat.HasFlag(VehicleSeatFlags.CanControl | VehicleSeatFlags.Unk2))
{ {
foreach (SpellEffectInfo effect in _effects) foreach (var effectInfo in _effects)
{ {
if (effect == null || effect.Effect != SpellEffectName.Summon) if (!effectInfo.IsEffect(SpellEffectName.Summon))
continue; continue;
var props = CliDB.SummonPropertiesStorage.LookupByKey(effect.MiscValueB); var props = CliDB.SummonPropertiesStorage.LookupByKey(effectInfo.MiscValueB);
if (props != null && props.Control != SummonCategory.Wild) if (props != null && props.Control != SummonCategory.Wild)
return SpellCastResult.CantDoThatRightNow; return SpellCastResult.CantDoThatRightNow;
} }
@@ -1296,9 +1277,9 @@ namespace Game.Spells
if (Mechanic != 0) if (Mechanic != 0)
mask |= (uint)(1 << (int)Mechanic); mask |= (uint)(1 << (int)Mechanic);
foreach (SpellEffectInfo effect in _effects) foreach (var effectInfo in _effects)
if (effect != null && effect.IsEffect() && effect.Mechanic != 0) if (effectInfo.IsEffect() && effectInfo.Mechanic != 0)
mask |= 1u << (int)effect.Mechanic; mask |= 1u << (int)effectInfo.Mechanic;
return mask; return mask;
} }
@@ -1309,9 +1290,8 @@ namespace Game.Spells
if (Mechanic != 0) if (Mechanic != 0)
mask |= 1u << (int)Mechanic; mask |= 1u << (int)Mechanic;
var effect = _effects[effIndex]; if (GetEffect(effIndex).IsEffect() && GetEffect(effIndex).Mechanic != 0)
if (effect != null && effect.IsEffect() && effect.Mechanic != 0) mask |= 1u << (int)GetEffect(effIndex).Mechanic;
mask |= 1u << (int)effect.Mechanic;
return mask; return mask;
} }
@@ -1322,18 +1302,17 @@ namespace Game.Spells
if (Mechanic != 0) if (Mechanic != 0)
mask |= (uint)(1 << (int)Mechanic); mask |= (uint)(1 << (int)Mechanic);
foreach (SpellEffectInfo effect in _effects) foreach (var effectInfo in _effects)
if (effect != null && Convert.ToBoolean(effectMask & (1 << (int)effect.EffectIndex)) && effect.Mechanic != 0) if ((effectMask & (1 << (int)effectInfo.EffectIndex)) != 0 && effectInfo.Mechanic != 0)
mask |= 1u << (int)effect.Mechanic; mask |= 1u << (int)effectInfo.Mechanic;
return mask; return mask;
} }
public Mechanics GetEffectMechanic(uint effIndex) public Mechanics GetEffectMechanic(uint effIndex)
{ {
SpellEffectInfo effect = GetEffect(effIndex); if (GetEffect(effIndex).IsEffect() && GetEffect(effIndex).Mechanic != 0)
if (effect != null && effect.IsEffect() && effect.Mechanic != 0) return GetEffect(effIndex).Mechanic;
return effect.Mechanic;
if (Mechanic != 0) if (Mechanic != 0)
return Mechanic; return Mechanic;
@@ -1391,8 +1370,8 @@ namespace Game.Spells
if (Convert.ToBoolean(GetSchoolMask() & SpellSchoolMask.Frost)) if (Convert.ToBoolean(GetSchoolMask() & SpellSchoolMask.Frost))
{ {
foreach (SpellEffectInfo effect in _effects) foreach (var effectInfo in _effects)
if (effect != null && (effect.IsAura(AuraType.ModStun) || effect.IsAura(AuraType.ModRoot))) if (effectInfo.IsAura(AuraType.ModStun) || effectInfo.IsAura(AuraType.ModRoot) || effectInfo.IsAura(AuraType.ModRoot2))
_auraState = AuraStateType.Frozen; _auraState = AuraStateType.Frozen;
} }
@@ -1466,12 +1445,12 @@ namespace Game.Spells
{ {
bool food = false; bool food = false;
bool drink = false; bool drink = false;
foreach (SpellEffectInfo effect in _effects) foreach (var effectInfo in _effects)
{ {
if (effect == null || !effect.IsAura()) if (!effectInfo.IsAura())
continue; continue;
switch (effect.ApplyAuraName) switch (effectInfo.ApplyAuraName)
{ {
// Food // Food
case AuraType.ModRegen: case AuraType.ModRegen:
@@ -1523,8 +1502,7 @@ namespace Game.Spells
if (SpellFamilyFlags[0].HasAnyFlag(0x400u)) if (SpellFamilyFlags[0].HasAnyFlag(0x400u))
_spellSpecific = SpellSpecificType.MageArcaneBrillance; _spellSpecific = SpellSpecificType.MageArcaneBrillance;
SpellEffectInfo effect = GetEffect(0); if (SpellFamilyFlags[0].HasAnyFlag(0x1000000u) && GetEffect(0).IsAura(AuraType.ModConfuse))
if (effect != null && SpellFamilyFlags[0].HasAnyFlag(0x1000000u) && effect.IsAura(AuraType.ModConfuse))
_spellSpecific = SpellSpecificType.MagePolymorph; _spellSpecific = SpellSpecificType.MagePolymorph;
break; break;
@@ -1617,11 +1595,11 @@ namespace Game.Spells
break; break;
} }
foreach (SpellEffectInfo effect in _effects) foreach (var effectInfo in _effects)
{ {
if (effect != null && effect.Effect == SpellEffectName.ApplyAura) if (effectInfo.IsEffect(SpellEffectName.ApplyAura))
{ {
switch (effect.ApplyAuraName) switch (effectInfo.ApplyAuraName)
{ {
case AuraType.ModCharm: case AuraType.ModCharm:
case AuraType.ModPossessPet: case AuraType.ModPossessPet:
@@ -2105,7 +2083,7 @@ namespace Game.Spells
public void _LoadImmunityInfo() public void _LoadImmunityInfo()
{ {
var loadImmunityInfoFn = new Action<SpellEffectInfo>(effectInfo => foreach (SpellEffectInfo effect in _effects)
{ {
uint schoolImmunityMask = 0; uint schoolImmunityMask = 0;
uint applyHarmfulAuraImmunityMask = 0; uint applyHarmfulAuraImmunityMask = 0;
@@ -2113,12 +2091,12 @@ namespace Game.Spells
uint dispelImmunity = 0; uint dispelImmunity = 0;
uint damageImmunityMask = 0; uint damageImmunityMask = 0;
int miscVal = effectInfo.MiscValue; int miscVal = effect.MiscValue;
int amount = effectInfo.CalcValue(); int amount = effect.CalcValue();
ImmunityInfo immuneInfo = effectInfo.GetImmunityInfo(); ImmunityInfo immuneInfo = effect.GetImmunityInfo();
switch (effectInfo.ApplyAuraName) switch (effect.ApplyAuraName)
{ {
case AuraType.MechanicImmunityMask: case AuraType.MechanicImmunityMask:
{ {
@@ -2360,14 +2338,6 @@ namespace Game.Spells
immuneInfo.DamageSchoolMask = damageImmunityMask; immuneInfo.DamageSchoolMask = damageImmunityMask;
_allowedMechanicMask |= immuneInfo.MechanicImmuneMask; _allowedMechanicMask |= immuneInfo.MechanicImmuneMask;
});
foreach (SpellEffectInfo effect in _effects)
{
if (effect == null)
continue;
loadImmunityInfoFn(effect);
} }
if (HasAttribute(SpellAttr5.UsableWhileStunned)) if (HasAttribute(SpellAttr5.UsableWhileStunned))
@@ -2408,9 +2378,9 @@ namespace Game.Spells
} }
} }
public void ApplyAllSpellImmunitiesTo(Unit target, SpellEffectInfo effect, bool apply) public void ApplyAllSpellImmunitiesTo(Unit target, SpellEffectInfo spellEffectInfo, bool apply)
{ {
ImmunityInfo immuneInfo = effect.GetImmunityInfo(); ImmunityInfo immuneInfo = spellEffectInfo.GetImmunityInfo();
uint schoolImmunity = immuneInfo.SchoolImmuneMask; uint schoolImmunity = immuneInfo.SchoolImmuneMask;
if (schoolImmunity != 0) if (schoolImmunity != 0)
@@ -2488,9 +2458,9 @@ namespace Game.Spells
if (auraSpellInfo == null) if (auraSpellInfo == null)
return false; return false;
foreach (SpellEffectInfo effectInfo in _effects) foreach (var effectInfo in _effects)
{ {
if (effectInfo == null) if (!effectInfo.IsEffect())
continue; continue;
ImmunityInfo immuneInfo = effectInfo.GetImmunityInfo(); ImmunityInfo immuneInfo = effectInfo.GetImmunityInfo();
@@ -2514,16 +2484,12 @@ namespace Game.Spells
return true; return true;
bool immuneToAllEffects = true; bool immuneToAllEffects = true;
foreach (SpellEffectInfo auraSpellEffectInfo in auraSpellInfo.GetEffects()) foreach (var auraSpellEffectInfo in auraSpellInfo.GetEffects())
{ {
if (auraSpellEffectInfo == null) if (!auraSpellEffectInfo.IsEffect())
continue; continue;
SpellEffectName effectName = auraSpellEffectInfo.Effect; if (!immuneInfo.SpellEffectImmune.Contains(auraSpellEffectInfo.Effect))
if (effectName == 0)
continue;
if (!immuneInfo.SpellEffectImmune.Contains(effectName))
{ {
immuneToAllEffects = false; immuneToAllEffects = false;
break; break;
@@ -2580,19 +2546,16 @@ namespace Game.Spells
if (aurEff.GetSpellInfo().HasAttribute(SpellAttr0.UnaffectedByInvulnerability)) if (aurEff.GetSpellInfo().HasAttribute(SpellAttr0.UnaffectedByInvulnerability))
return false; return false;
foreach (SpellEffectInfo effectInfo in _effects) foreach (var effectInfo in GetEffects())
{ {
if (effectInfo == null) if (!effectInfo.IsEffect(SpellEffectName.ApplyAura))
continue;
if (effectInfo.Effect != SpellEffectName.ApplyAura)
continue; continue;
uint miscValue = (uint)effectInfo.MiscValue; uint miscValue = (uint)effectInfo.MiscValue;
switch (effectInfo.ApplyAuraName) switch (effectInfo.ApplyAuraName)
{ {
case AuraType.StateImmunity: case AuraType.StateImmunity:
if (miscValue != (uint)aurEff.GetSpellEffectInfo().ApplyAuraName) if (miscValue != (uint)aurEff.GetAuraType())
continue; continue;
break; break;
case AuraType.SchoolImmunity: case AuraType.SchoolImmunity:
@@ -2702,35 +2665,35 @@ namespace Game.Spells
uint totalTicks = 0; uint totalTicks = 0;
int DotDuration = GetDuration(); int DotDuration = GetDuration();
foreach (SpellEffectInfo effect in _effects) foreach (var effectInfo in GetEffects())
{ {
if (effect != null && effect.Effect == SpellEffectName.ApplyAura) if (!effectInfo.IsEffect(SpellEffectName.ApplyAura))
continue;
switch (effectInfo.ApplyAuraName)
{ {
switch (effect.ApplyAuraName) case AuraType.PeriodicDamage:
{ case AuraType.PeriodicDamagePercent:
case AuraType.PeriodicDamage: case AuraType.PeriodicHeal:
case AuraType.PeriodicDamagePercent: case AuraType.ObsModHealth:
case AuraType.PeriodicHeal: case AuraType.ObsModPower:
case AuraType.ObsModHealth: case AuraType.Unk48:
case AuraType.ObsModPower: case AuraType.PowerBurn:
case AuraType.Unk48: case AuraType.PeriodicLeech:
case AuraType.PowerBurn: case AuraType.PeriodicManaLeech:
case AuraType.PeriodicLeech: case AuraType.PeriodicEnergize:
case AuraType.PeriodicManaLeech: case AuraType.PeriodicDummy:
case AuraType.PeriodicEnergize: case AuraType.PeriodicTriggerSpell:
case AuraType.PeriodicDummy: case AuraType.PeriodicTriggerSpellWithValue:
case AuraType.PeriodicTriggerSpell: case AuraType.PeriodicHealthFunnel:
case AuraType.PeriodicTriggerSpellWithValue: // skip infinite periodics
case AuraType.PeriodicHealthFunnel: if (effectInfo.ApplyAuraPeriod > 0 && DotDuration > 0)
// skip infinite periodics {
if (effect.ApplyAuraPeriod > 0 && DotDuration > 0) totalTicks = (uint)DotDuration / effectInfo.ApplyAuraPeriod;
{ if (HasAttribute(SpellAttr5.StartPeriodicAtApply))
totalTicks = (uint)DotDuration / effect.ApplyAuraPeriod; ++totalTicks;
if (HasAttribute(SpellAttr5.StartPeriodicAtApply)) }
++totalTicks; break;
}
break;
}
} }
} }
@@ -3160,13 +3123,13 @@ namespace Game.Spells
return this; return this;
bool needRankSelection = false; bool needRankSelection = false;
foreach (SpellEffectInfo effect in _effects) foreach (var effectInfo in GetEffects())
{ {
if (effect != null && IsPositiveEffect(effect.EffectIndex) && if (IsPositiveEffect(effectInfo.EffectIndex) &&
(effect.Effect == SpellEffectName.ApplyAura || (effectInfo.IsEffect(SpellEffectName.ApplyAura) ||
effect.Effect == SpellEffectName.ApplyAreaAuraParty || effectInfo.IsEffect(SpellEffectName.ApplyAreaAuraParty) ||
effect.Effect == SpellEffectName.ApplyAreaAuraRaid) && effectInfo.IsEffect(SpellEffectName.ApplyAreaAuraRaid)) &&
effect.Scaling.Coefficient != 0) effectInfo.Scaling.Coefficient != 0)
{ {
needRankSelection = true; needRankSelection = true;
break; break;
@@ -3245,20 +3208,20 @@ namespace Game.Spells
bool dstSet = false; bool dstSet = false;
SpellCastTargetFlags targetMask = Targets; SpellCastTargetFlags targetMask = Targets;
// prepare target mask using effect target entries // prepare target mask using effect target entries
foreach (SpellEffectInfo effect in _effects) foreach (var effectInfo in GetEffects())
{ {
if (effect == null || !effect.IsEffect()) if (!effectInfo.IsEffect())
continue; continue;
targetMask |= effect.TargetA.GetExplicitTargetMask(ref srcSet, ref dstSet); targetMask |= effectInfo.TargetA.GetExplicitTargetMask(ref srcSet, ref dstSet);
targetMask |= effect.TargetB.GetExplicitTargetMask(ref srcSet, ref dstSet); targetMask |= effectInfo.TargetB.GetExplicitTargetMask(ref srcSet, ref dstSet);
// add explicit target flags based on spell effects which have SpellEffectImplicitTargetTypes.Explicit and no valid target provided // add explicit target flags based on spell effects which have SpellEffectImplicitTargetTypes.Explicit and no valid target provided
if (effect.GetImplicitTargetType() != SpellEffectImplicitTargetTypes.Explicit) if (effectInfo.GetImplicitTargetType() != SpellEffectImplicitTargetTypes.Explicit)
continue; continue;
// extend explicit target mask only if valid targets for effect could not be provided by target types // extend explicit target mask only if valid targets for effect could not be provided by target types
SpellCastTargetFlags effectTargetMask = effect.GetMissingTargetMask(srcSet, dstSet, targetMask); SpellCastTargetFlags effectTargetMask = effectInfo.GetMissingTargetMask(srcSet, dstSet, targetMask);
// don't add explicit object/dest flags when spell has no max range // don't add explicit object/dest flags when spell has no max range
if (GetMaxRange(true) == 0.0f && GetMaxRange(false) == 0.0f) if (GetMaxRange(true) == 0.0f && GetMaxRange(false) == 0.0f)
@@ -3270,24 +3233,22 @@ namespace Game.Spells
ExplicitTargetMask = (uint)targetMask; ExplicitTargetMask = (uint)targetMask;
} }
public bool _isPositiveTarget(SpellInfo spellInfo, uint effIndex) public bool _isPositiveTarget(SpellEffectInfo effect)
{ {
SpellEffectInfo effect = spellInfo.GetEffect(effIndex); if (!effect.IsEffect())
if (effect == null || !effect.IsEffect())
return true; return true;
return (effect.TargetA.GetCheckType() != SpellTargetCheckTypes.Enemy && return effect.TargetA.GetCheckType() != SpellTargetCheckTypes.Enemy &&
effect.TargetB.GetCheckType() != SpellTargetCheckTypes.Enemy); effect.TargetB.GetCheckType() != SpellTargetCheckTypes.Enemy;
} }
bool _isPositiveEffectImpl(SpellInfo spellInfo, uint effIndex, List<Tuple<SpellInfo, uint>> visited) bool _isPositiveEffectImpl(SpellInfo spellInfo, SpellEffectInfo effect, List<Tuple<SpellInfo, uint>> visited)
{ {
SpellEffectInfo effect = spellInfo.GetEffect(effIndex); if ( !effect.IsEffect())
if (effect == null || !effect.IsEffect())
return true; return true;
// attribute may be already set in DB // attribute may be already set in DB
if (!spellInfo.IsPositiveEffect(effIndex)) if (!spellInfo.IsPositiveEffect(effect.EffectIndex))
return false; return false;
// passive auras like talents are all positive // passive auras like talents are all positive
@@ -3298,7 +3259,7 @@ namespace Game.Spells
if (spellInfo.HasAttribute(SpellAttr0.Negative1)) if (spellInfo.HasAttribute(SpellAttr0.Negative1))
return false; return false;
visited.Add(Tuple.Create(spellInfo, effIndex)); visited.Add(Tuple.Create(spellInfo, effect.EffectIndex));
int bp = effect.CalcValue(); int bp = effect.CalcValue();
switch (spellInfo.SpellFamilyName) switch (spellInfo.SpellFamilyName)
@@ -3352,16 +3313,13 @@ namespace Game.Spells
if (spellInfo.HasAttribute(SpellAttr1.DontRefreshDurationOnRecast)) if (spellInfo.HasAttribute(SpellAttr1.DontRefreshDurationOnRecast))
{ {
// check for targets, there seems to be an assortment of dummy triggering spells that should be negative // check for targets, there seems to be an assortment of dummy triggering spells that should be negative
foreach (SpellEffectInfo otherEffect in spellInfo.GetEffects()) foreach (var otherEffect in spellInfo.GetEffects())
if (otherEffect != null && !_isPositiveTarget(spellInfo, otherEffect.EffectIndex)) if (!_isPositiveTarget(otherEffect))
return false; return false;
} }
foreach (SpellEffectInfo otherEffect in spellInfo.GetEffects()) foreach (var otherEffect in spellInfo.GetEffects())
{ {
if (otherEffect == null)
continue;
switch (otherEffect.Effect) switch (otherEffect.Effect)
{ {
case SpellEffectName.Heal: case SpellEffectName.Heal:
@@ -3371,7 +3329,7 @@ namespace Game.Spells
case SpellEffectName.EnergizePct: case SpellEffectName.EnergizePct:
return true; return true;
case SpellEffectName.Instakill: case SpellEffectName.Instakill:
if (otherEffect.EffectIndex != effIndex && // for spells like 38044: instakill effect is negative but auras on target must count as buff if (otherEffect.EffectIndex != effect.EffectIndex && // for spells like 38044: instakill effect is negative but auras on target must count as buff
otherEffect.TargetA.GetTarget() == effect.TargetA.GetTarget() && otherEffect.TargetA.GetTarget() == effect.TargetA.GetTarget() &&
otherEffect.TargetB.GetTarget() == effect.TargetB.GetTarget()) otherEffect.TargetB.GetTarget() == effect.TargetB.GetTarget())
return false; return false;
@@ -3430,7 +3388,7 @@ namespace Game.Spells
case SpellEffectName.AttackMe: case SpellEffectName.AttackMe:
case SpellEffectName.PowerBurn: case SpellEffectName.PowerBurn:
// check targets // check targets
if (!_isPositiveTarget(spellInfo, effIndex)) if (!_isPositiveTarget(effect))
return false; return false;
break; break;
case SpellEffectName.Dispel: case SpellEffectName.Dispel:
@@ -3446,11 +3404,11 @@ namespace Game.Spells
} }
// also check targets // also check targets
if (!_isPositiveTarget(spellInfo, effIndex)) if (!_isPositiveTarget(effect))
return false; return false;
break; break;
case SpellEffectName.DispelMechanic: case SpellEffectName.DispelMechanic:
if (!_isPositiveTarget(spellInfo, effIndex)) if (!_isPositiveTarget(effect))
{ {
// non-positive mechanic dispel on negative target // non-positive mechanic dispel on negative target
switch ((Mechanics)effect.MiscValue) switch ((Mechanics)effect.MiscValue)
@@ -3468,7 +3426,7 @@ namespace Game.Spells
case SpellEffectName.Threat: case SpellEffectName.Threat:
case SpellEffectName.ModifyThreatPercent: case SpellEffectName.ModifyThreatPercent:
// check targets AND basepoints // check targets AND basepoints
if (!_isPositiveTarget(spellInfo, effIndex) && bp > 0) if (!_isPositiveTarget(effect) && bp > 0)
return false; return false;
break; break;
default: default:
@@ -3513,7 +3471,7 @@ namespace Game.Spells
case AuraType.ModAttackPower: case AuraType.ModAttackPower:
case AuraType.ModRangedAttackPower: case AuraType.ModRangedAttackPower:
case AuraType.ModDamagePercentDone: case AuraType.ModDamagePercentDone:
if (!_isPositiveTarget(spellInfo, effIndex) && bp < 0) if (!_isPositiveTarget(effect) && bp < 0)
return false; return false;
break; break;
case AuraType.ModDamageTaken: // dependent from basepoint sign (positive . negative) case AuraType.ModDamageTaken: // dependent from basepoint sign (positive . negative)
@@ -3527,24 +3485,21 @@ namespace Game.Spells
return false; return false;
break; break;
case AuraType.ModDamagePercentTaken: // check targets and basepoints (ex Recklessness) case AuraType.ModDamagePercentTaken: // check targets and basepoints (ex Recklessness)
if (!_isPositiveTarget(spellInfo, effIndex) && bp > 0) if (!_isPositiveTarget(effect) && bp > 0)
return false; return false;
break; break;
case AuraType.AddTargetTrigger: case AuraType.AddTargetTrigger:
return true; return true;
case AuraType.PeriodicTriggerSpellWithValue: case AuraType.PeriodicTriggerSpellWithValue:
case AuraType.PeriodicTriggerSpell: case AuraType.PeriodicTriggerSpell:
if (!_isPositiveTarget(spellInfo, effIndex)) if (!_isPositiveTarget(effect))
{ {
SpellInfo spellTriggeredProto = Global.SpellMgr.GetSpellInfo(effect.TriggerSpell, spellInfo.Difficulty); SpellInfo spellTriggeredProto = Global.SpellMgr.GetSpellInfo(effect.TriggerSpell, spellInfo.Difficulty);
if (spellTriggeredProto != null) if (spellTriggeredProto != null)
{ {
// negative targets of main spell return early // negative targets of main spell return early
foreach (SpellEffectInfo spellTriggeredEffect in spellTriggeredProto.GetEffects()) foreach (var spellTriggeredEffect in spellTriggeredProto.GetEffects())
{ {
if (spellTriggeredEffect == null)
continue;
// already seen this // already seen this
if (visited.Contains(Tuple.Create(spellTriggeredProto, spellTriggeredEffect.EffectIndex))) if (visited.Contains(Tuple.Create(spellTriggeredProto, spellTriggeredEffect.EffectIndex)))
continue; continue;
@@ -3554,7 +3509,7 @@ namespace Game.Spells
// if non-positive trigger cast targeted to positive target this main cast is non-positive // if non-positive trigger cast targeted to positive target this main cast is non-positive
// this will place this spell auras as debuffs // this will place this spell auras as debuffs
if (_isPositiveTarget(spellTriggeredProto, spellTriggeredEffect.EffectIndex) && !_isPositiveEffectImpl(spellTriggeredProto, spellTriggeredEffect.EffectIndex, visited)) if (_isPositiveTarget(spellTriggeredEffect) && !_isPositiveEffectImpl(spellTriggeredProto, spellTriggeredEffect, visited))
return false; return false;
} }
} }
@@ -3585,7 +3540,7 @@ namespace Game.Spells
case AuraType.ModAttackerRangedCritChance: case AuraType.ModAttackerRangedCritChance:
case AuraType.ModAttackerSpellAndWeaponCritChance: case AuraType.ModAttackerSpellAndWeaponCritChance:
// have positive and negative spells, check target // have positive and negative spells, check target
if (!_isPositiveTarget(spellInfo, effIndex)) if (!_isPositiveTarget(effect))
return false; return false;
break; break;
case AuraType.ModConfuse: case AuraType.ModConfuse:
@@ -3677,11 +3632,8 @@ namespace Game.Spells
{ {
// spells with at least one negative effect are considered negative // spells with at least one negative effect are considered negative
// some self-applied spells have negative effects but in self casting case negative check ignored. // some self-applied spells have negative effects but in self casting case negative check ignored.
foreach (SpellEffectInfo spellTriggeredEffect in spellTriggeredProto.GetEffects()) foreach (var spellTriggeredEffect in spellTriggeredProto.GetEffects())
{ {
if (spellTriggeredEffect == null)
continue;
// already seen this // already seen this
if (visited.Contains(Tuple.Create(spellTriggeredProto, spellTriggeredEffect.EffectIndex))) if (visited.Contains(Tuple.Create(spellTriggeredProto, spellTriggeredEffect.EffectIndex)))
continue; continue;
@@ -3689,7 +3641,7 @@ namespace Game.Spells
if (!spellTriggeredEffect.IsEffect()) if (!spellTriggeredEffect.IsEffect())
continue; continue;
if (!_isPositiveEffectImpl(spellTriggeredProto, spellTriggeredEffect.EffectIndex, visited)) if (!_isPositiveEffectImpl(spellTriggeredProto, spellTriggeredEffect, visited))
return false; return false;
} }
} }
@@ -3703,18 +3655,18 @@ namespace Game.Spells
{ {
List<Tuple<SpellInfo, uint>> visited = new(); List<Tuple<SpellInfo, uint>> visited = new();
for (byte i = 0; i < SpellConst.MaxEffects; ++i) foreach (SpellEffectInfo effect in GetEffects())
if (!_isPositiveEffectImpl(this, i, visited)) if (!_isPositiveEffectImpl(this, effect, visited))
NegativeEffects[i] = true; NegativeEffects[(int)effect.EffectIndex] = true;
// additional checks after effects marked // additional checks after effects marked
foreach (SpellEffectInfo effect in GetEffects()) foreach (var spellEffectInfo in GetEffects())
{ {
if (effect == null || !effect.IsEffect() || !IsPositiveEffect(effect.EffectIndex)) if (!spellEffectInfo.IsEffect() || !IsPositiveEffect(spellEffectInfo.EffectIndex))
continue; continue;
switch (effect.ApplyAuraName) switch (spellEffectInfo.ApplyAuraName)
{ {
// has other non positive effect? // has other non positive effect?
// then it should be marked negative despite of targets (ex 8510, 8511, 8893, 10267) // then it should be marked negative despite of targets (ex 8510, 8511, 8893, 10267)
@@ -3725,9 +3677,14 @@ namespace Game.Spells
case AuraType.Transform: case AuraType.Transform:
case AuraType.ModAttackspeed: case AuraType.ModAttackspeed:
case AuraType.ModDecreaseSpeed: case AuraType.ModDecreaseSpeed:
if (!IsPositive()) {
NegativeEffects[(int)effect.EffectIndex] = true; for (uint j = spellEffectInfo.EffectIndex + 1; j < GetEffects().Count; ++j)
if (!IsPositiveEffect(j)
&& spellEffectInfo.TargetA.GetTarget() == GetEffect(j).TargetA.GetTarget()
&& spellEffectInfo.TargetB.GetTarget() == GetEffect(j).TargetB.GetTarget())
NegativeEffects[(int)spellEffectInfo.EffectIndex] = true;
break; break;
}
default: default:
break; break;
} }
@@ -3737,21 +3694,17 @@ namespace Game.Spells
public void _UnloadImplicitTargetConditionLists() public void _UnloadImplicitTargetConditionLists()
{ {
// find the same instances of ConditionList and delete them. // find the same instances of ConditionList and delete them.
for (int i = 0; i < _effects.Length; ++i) foreach (var effectInfo in _effects)
{ {
SpellEffectInfo effect = _effects[i]; var cur = effectInfo.ImplicitTargetConditions;
if (effect != null) if (cur == null)
{ continue;
var cur = effect.ImplicitTargetConditions;
if (cur == null)
continue;
for (var j = i; j < _effects.Length; ++j) for (int j = (int)effectInfo.EffectIndex; j < _effects.Count; ++j)
{ {
SpellEffectInfo eff = _effects[j]; SpellEffectInfo eff = _effects[j];
if (eff != null && eff.ImplicitTargetConditions == cur) if (eff.ImplicitTargetConditions == cur)
eff.ImplicitTargetConditions = null; eff.ImplicitTargetConditions = null;
}
} }
} }
} }
@@ -3804,14 +3757,14 @@ namespace Game.Spells
return CategoryId; return CategoryId;
} }
public SpellEffectInfo[] GetEffects() { return _effects; } public List<SpellEffectInfo> GetEffects() { return _effects; }
public SpellEffectInfo GetEffect(uint index) { return _effects[index]; } public SpellEffectInfo GetEffect(uint index) { return _effects[(int)index]; }
public bool HasTargetType(Targets target) public bool HasTargetType(Targets target)
{ {
foreach (SpellEffectInfo effect in _effects) foreach (var effectInfo in _effects)
if (effect != null && (effect.TargetA.GetTarget() == target || effect.TargetB.GetTarget() == target)) if (effectInfo.TargetA.GetTarget() == target || effectInfo.TargetB.GetTarget() == target)
return true; return true;
return false; return false;
@@ -3945,7 +3898,7 @@ namespace Game.Spells
public uint ExplicitTargetMask { get; set; } public uint ExplicitTargetMask { get; set; }
public SpellChainNode ChainEntry { get; set; } public SpellChainNode ChainEntry { get; set; }
SpellEffectInfo[] _effects = new SpellEffectInfo[SpellConst.MaxEffects]; List<SpellEffectInfo> _effects = new();
List<SpellXSpellVisualRecord> _visuals = new(); List<SpellXSpellVisualRecord> _visuals = new();
SpellSpecificType _spellSpecific; SpellSpecificType _spellSpecific;
AuraStateType _auraState; AuraStateType _auraState;
File diff suppressed because it is too large Load Diff
+6 -8
View File
@@ -127,12 +127,12 @@ namespace Scripts.Spells.DeathKnight
public override bool Validate(SpellInfo spellInfo) public override bool Validate(SpellInfo spellInfo)
{ {
return ValidateSpellInfo(SpellIds.RunicPowerEnergize, SpellIds.VolatileShielding); return ValidateSpellInfo(SpellIds.RunicPowerEnergize, SpellIds.VolatileShielding) && spellInfo.GetEffects().Count > 1;
} }
public override bool Load() public override bool Load()
{ {
absorbPct = GetSpellInfo().GetEffect(1).CalcValue(GetCaster()); absorbPct = GetEffectInfo(1).CalcValue(GetCaster());
maxHealth = GetCaster().GetMaxHealth(); maxHealth = GetCaster().GetMaxHealth();
absorbedAmount = 0; absorbedAmount = 0;
return true; return true;
@@ -427,7 +427,7 @@ namespace Scripts.Spells.DeathKnight
public override bool Validate(SpellInfo spellInfo) public override bool Validate(SpellInfo spellInfo)
{ {
return ValidateSpellInfo(SpellIds.DeathStrikeEnabler, SpellIds.DeathStrikeHeal, SpellIds.BloodShieldMastery, SpellIds.BloodShieldAbsorb, SpellIds.RecentlyUsedDeathStrike, SpellIds.Frost, SpellIds.DeathStrikeOffhand) return ValidateSpellInfo(SpellIds.DeathStrikeEnabler, SpellIds.DeathStrikeHeal, SpellIds.BloodShieldMastery, SpellIds.BloodShieldAbsorb, SpellIds.RecentlyUsedDeathStrike, SpellIds.Frost, SpellIds.DeathStrikeOffhand)
&& spellInfo.GetEffect(1) != null && spellInfo.GetEffect(2) != null; && spellInfo.GetEffects().Count > 2;
} }
void HandleDummy(uint effIndex) void HandleDummy(uint effIndex)
@@ -437,12 +437,10 @@ namespace Scripts.Spells.DeathKnight
AuraEffect enabler = caster.GetAuraEffect(SpellIds.DeathStrikeEnabler, 0, GetCaster().GetGUID()); AuraEffect enabler = caster.GetAuraEffect(SpellIds.DeathStrikeEnabler, 0, GetCaster().GetGUID());
if (enabler != null) if (enabler != null)
{ {
SpellInfo spellInfo = GetSpellInfo();
// Heals you for 25% of all damage taken in the last 5 sec, // Heals you for 25% of all damage taken in the last 5 sec,
int heal = MathFunctions.CalculatePct(enabler.CalculateAmount(GetCaster()), spellInfo.GetEffect(1).CalcValue(GetCaster())); int heal = MathFunctions.CalculatePct(enabler.CalculateAmount(GetCaster()), GetEffectInfo(1).CalcValue(GetCaster()));
// minimum 7.0% of maximum health. // minimum 7.0% of maximum health.
int pctOfMaxHealth = MathFunctions.CalculatePct(spellInfo.GetEffect(2).CalcValue(GetCaster()), caster.GetMaxHealth()); int pctOfMaxHealth = MathFunctions.CalculatePct(GetEffectInfo(2).CalcValue(GetCaster()), caster.GetMaxHealth());
heal = Math.Max(heal, pctOfMaxHealth); heal = Math.Max(heal, pctOfMaxHealth);
caster.CastSpell(caster, SpellIds.DeathStrikeHeal, new CastSpellExtraArgs(TriggerCastFlags.FullMask).AddSpellMod(SpellValueMod.BasePoint0, heal)); caster.CastSpell(caster, SpellIds.DeathStrikeHeal, new CastSpellExtraArgs(TriggerCastFlags.FullMask).AddSpellMod(SpellValueMod.BasePoint0, heal));
@@ -530,7 +528,7 @@ namespace Scripts.Spells.DeathKnight
{ {
public override bool Validate(SpellInfo spellInfo) public override bool Validate(SpellInfo spellInfo)
{ {
return ValidateSpellInfo(SpellIds.CorpseExplosionTriggered); return ValidateSpellInfo(SpellIds.CorpseExplosionTriggered) && spellInfo.GetEffects().Count > 2;
} }
void HandleDamage(uint effIndex) void HandleDamage(uint effIndex)
+4 -5
View File
@@ -410,7 +410,7 @@ namespace Scripts.Spells.Druid
public override bool Validate(SpellInfo spellInfo) public override bool Validate(SpellInfo spellInfo)
{ {
return ValidateSpellInfo(SpellIds.IncarnationKingOfTheJungle) return ValidateSpellInfo(SpellIds.IncarnationKingOfTheJungle)
&& Global.SpellMgr.GetSpellInfo(SpellIds.IncarnationKingOfTheJungle, Difficulty.None).GetEffect(1) != null; && Global.SpellMgr.GetSpellInfo(SpellIds.IncarnationKingOfTheJungle, Difficulty.None).GetEffects().Count > 1;
} }
void HandleHitTargetBurn(uint effIndex) void HandleHitTargetBurn(uint effIndex)
@@ -1570,8 +1570,7 @@ namespace Scripts.Spells.Druid
public override bool Validate(SpellInfo spellInfo) public override bool Validate(SpellInfo spellInfo)
{ {
SpellEffectInfo effectInfo = spellInfo.GetEffect(2); if (spellInfo.GetEffects().Count <= 2 || spellInfo.GetEffect(2).IsEffect() || spellInfo.GetEffect(2).CalcValue() <= 0)
if (effectInfo == null || effectInfo.IsEffect() || effectInfo.CalcValue() <= 0)
return false; return false;
return true; return true;
} }
@@ -1587,7 +1586,7 @@ namespace Scripts.Spells.Druid
return true; return true;
}); });
int maxTargets = GetSpellInfo().GetEffect(2).CalcValue(GetCaster()); int maxTargets = GetEffectInfo(2).CalcValue(GetCaster());
if (targets.Count > maxTargets) if (targets.Count > maxTargets)
{ {
@@ -1626,7 +1625,7 @@ namespace Scripts.Spells.Druid
return; return;
// calculate from base damage, not from aurEff.GetAmount() (already modified) // calculate from base damage, not from aurEff.GetAmount() (already modified)
float damage = caster.CalculateSpellDamage(GetUnitOwner(), GetSpellInfo(), aurEff.GetEffIndex()); float damage = caster.CalculateSpellDamage(GetUnitOwner(), aurEff.GetSpellEffectInfo());
// Wild Growth = first tick gains a 6% bonus, reduced by 2% each tick // Wild Growth = first tick gains a 6% bonus, reduced by 2% each tick
float reduction = 2.0f; float reduction = 2.0f;
+41 -27
View File
@@ -529,7 +529,7 @@ namespace Scripts.Spells.Generic
public override bool Validate(SpellInfo spellInfo) public override bool Validate(SpellInfo spellInfo)
{ {
if (!spellInfo.GetEffect(0).IsAura() || spellInfo.GetEffect(0).ApplyAuraName != AuraType.ModPowerRegen) if (spellInfo.GetEffects().Empty() || !spellInfo.GetEffect(0).IsAura(AuraType.ModPowerRegen))
{ {
Log.outError(LogFilter.Spells, "Aura {GetId()} structure has been changed - first aura is no longer SPELL_AURA_MOD_POWER_REGEN"); Log.outError(LogFilter.Spells, "Aura {GetId()} structure has been changed - first aura is no longer SPELL_AURA_MOD_POWER_REGEN");
return false; return false;
@@ -625,7 +625,7 @@ namespace Scripts.Spells.Generic
{ {
public override bool Validate(SpellInfo spellInfo) public override bool Validate(SpellInfo spellInfo)
{ {
return ValidateSpellInfo(spellInfo.GetEffect(0).TriggerSpell); return !spellInfo.GetEffects().Empty() && ValidateSpellInfo(spellInfo.GetEffect(0).TriggerSpell);
} }
void PeriodicTick(AuraEffect aurEff) void PeriodicTick(AuraEffect aurEff)
@@ -634,7 +634,7 @@ namespace Scripts.Spells.Generic
if (!RandomHelper.randChance(GetSpellInfo().ProcChance)) if (!RandomHelper.randChance(GetSpellInfo().ProcChance))
return; return;
GetTarget().CastSpell((Unit)null, GetSpellInfo().GetEffect(aurEff.GetEffIndex()).TriggerSpell, true); GetTarget().CastSpell(null, aurEff.GetSpellEffectInfo().TriggerSpell, true);
} }
public override void Register() public override void Register()
@@ -896,19 +896,19 @@ namespace Scripts.Spells.Generic
{ {
public override bool Validate(SpellInfo spellInfo) public override bool Validate(SpellInfo spellInfo)
{ {
return ValidateSpellInfo((uint)spellInfo.GetEffect(2).CalcValue()); return spellInfo.GetEffects().Count > 2 && ValidateSpellInfo((uint)spellInfo.GetEffect(2).CalcValue());
} }
void HandleApply(AuraEffect aurEff, AuraEffectHandleModes mode) void HandleApply(AuraEffect aurEff, AuraEffectHandleModes mode)
{ {
Unit caster = GetCaster(); Unit caster = GetCaster();
if (caster) if (caster)
caster.CastSpell(GetTarget(), (uint)GetSpellInfo().GetEffect(2).CalcValue()); caster.CastSpell(GetTarget(), (uint)GetEffectInfo(2).CalcValue());
} }
void HandleRemove(AuraEffect aurEff, AuraEffectHandleModes mode) void HandleRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
{ {
GetTarget().RemoveAurasDueToSpell((uint)GetSpellInfo().GetEffect(2).CalcValue(), GetCasterGUID()); GetTarget().RemoveAurasDueToSpell((uint)GetEffectInfo(2).CalcValue(), GetCasterGUID());
} }
public override void Register() public override void Register()
@@ -1565,19 +1565,20 @@ namespace Scripts.Spells.Generic
[Script] [Script]
class spell_gen_gift_of_naaru : AuraScript class spell_gen_gift_of_naaru : AuraScript
{ {
public override bool Validate(SpellInfo spellInfo)
{
return spellInfo.GetEffects().Count > 1;
}
void CalculateAmount(AuraEffect aurEff, ref int amount, ref bool canBeRecalculated) void CalculateAmount(AuraEffect aurEff, ref int amount, ref bool canBeRecalculated)
{ {
if (!GetCaster() || aurEff.GetTotalTicks() == 0) if (!GetCaster() || aurEff.GetTotalTicks() == 0)
return; return;
SpellEffectInfo eff1 = GetSpellInfo().GetEffect(1); float healPct = GetEffectInfo(1).CalcValue() / 100.0f;
if (eff1 != null) float heal = healPct * GetCaster().GetMaxHealth();
{ int healTick = (int)Math.Floor(heal / aurEff.GetTotalTicks());
float healPct = eff1.CalcValue() / 100.0f; amount += healTick;
float heal = healPct * GetCaster().GetMaxHealth();
int healTick = (int)Math.Floor(heal / aurEff.GetTotalTicks());
amount += healTick;
}
} }
public override void Register() public override void Register()
@@ -1785,7 +1786,7 @@ namespace Scripts.Spells.Generic
if (spell.HasEffect(SpellEffectName.ScriptEffect)) if (spell.HasEffect(SpellEffectName.ScriptEffect))
OnEffectHitTarget.Add(new EffectHandler(HandleScriptEffect, SpellConst.EffectFirstFound, SpellEffectName.ScriptEffect)); OnEffectHitTarget.Add(new EffectHandler(HandleScriptEffect, SpellConst.EffectFirstFound, SpellEffectName.ScriptEffect));
if (spell.GetEffect(0).Effect == SpellEffectName.Charge) if (spell.GetEffect(0).IsEffect(SpellEffectName.Charge))
OnEffectHitTarget.Add(new EffectHandler(HandleChargeEffect, 0, SpellEffectName.Charge)); OnEffectHitTarget.Add(new EffectHandler(HandleChargeEffect, 0, SpellEffectName.Charge));
} }
} }
@@ -1816,7 +1817,7 @@ namespace Scripts.Spells.Generic
{ {
public override bool Validate(SpellInfo spellInfo) public override bool Validate(SpellInfo spellInfo)
{ {
return ValidateSpellInfo(spellInfo.GetEffect(0).TriggerSpell); return !spellInfo.GetEffects().Empty() && ValidateSpellInfo(spellInfo.GetEffect(0).TriggerSpell);
} }
void PeriodicTick(AuraEffect aurEff) void PeriodicTick(AuraEffect aurEff)
@@ -1825,7 +1826,7 @@ namespace Scripts.Spells.Generic
CastSpellExtraArgs args = new(aurEff); CastSpellExtraArgs args = new(aurEff);
args.AddSpellMod(SpellValueMod.MaxTargets, (int)aurEff.GetTickNumber() / 10 + 1); args.AddSpellMod(SpellValueMod.MaxTargets, (int)aurEff.GetTickNumber() / 10 + 1);
GetTarget().CastSpell((Unit)null, GetSpellInfo().GetEffect(aurEff.GetEffIndex()).TriggerSpell, args); GetTarget().CastSpell((Unit)null, aurEff.GetSpellEffectInfo().TriggerSpell, args);
} }
public override void Register() public override void Register()
@@ -1980,6 +1981,11 @@ namespace Scripts.Spells.Generic
[Script] [Script]
class spell_gen_oracle_wolvar_reputation : SpellScript class spell_gen_oracle_wolvar_reputation : SpellScript
{ {
public override bool Validate(SpellInfo spellInfo)
{
return spellInfo.GetEffects().Count > 1;
}
public override bool Load() public override bool Load()
{ {
return GetCaster().IsTypeId(TypeId.Player); return GetCaster().IsTypeId(TypeId.Player);
@@ -1988,7 +1994,7 @@ namespace Scripts.Spells.Generic
void HandleDummy(uint effIndex) void HandleDummy(uint effIndex)
{ {
Player player = GetCaster().ToPlayer(); Player player = GetCaster().ToPlayer();
uint factionId = (uint)GetEffectInfo(effIndex).CalcValue(); uint factionId = (uint)GetEffectInfo().CalcValue();
int repChange = GetEffectInfo(1).CalcValue(); int repChange = GetEffectInfo(1).CalcValue();
FactionRecord factionEntry = CliDB.FactionStorage.LookupByKey(factionId); FactionRecord factionEntry = CliDB.FactionStorage.LookupByKey(factionId);
@@ -2291,11 +2297,16 @@ namespace Scripts.Spells.Generic
[Script] // 62418 Impale [Script] // 62418 Impale
class spell_gen_remove_on_health_pct : AuraScript class spell_gen_remove_on_health_pct : AuraScript
{ {
public override bool Validate(SpellInfo spellInfo)
{
return spellInfo.GetEffects().Count > 1;
}
void PeriodicTick(AuraEffect aurEff) void PeriodicTick(AuraEffect aurEff)
{ {
// they apply damage so no need to check for ticks here // they apply damage so no need to check for ticks here
if (GetTarget().HealthAbovePct(GetSpellInfo().GetEffect(1).CalcValue())) if (GetTarget().HealthAbovePct(GetEffectInfo(1).CalcValue()))
{ {
Remove(AuraRemoveMode.EnemySpell); Remove(AuraRemoveMode.EnemySpell);
PreventDefaultAction(); PreventDefaultAction();
@@ -2318,7 +2329,7 @@ namespace Scripts.Spells.Generic
void PeriodicTick(AuraEffect aurEff) void PeriodicTick(AuraEffect aurEff)
{ {
// if it has only periodic effect, allow 1 tick // if it has only periodic effect, allow 1 tick
bool onlyEffect = GetSpellInfo().GetEffects().Length == 1; bool onlyEffect = GetSpellInfo().GetEffects().Count == 1;
if (onlyEffect && aurEff.GetTickNumber() <= 1) if (onlyEffect && aurEff.GetTickNumber() <= 1)
return; return;
@@ -3042,9 +3053,12 @@ namespace Scripts.Spells.Generic
{ {
public override bool Validate(SpellInfo spellInfo) public override bool Validate(SpellInfo spellInfo)
{ {
SpellEffectInfo effect = spellInfo.GetEffect(0); if (spellInfo.GetEffects().Empty())
if (effect == null || effect.CalcValue() < 1)
return false; return false;
if (spellInfo.GetEffect(0).CalcValue() < 1)
return false;
return true; return true;
} }
@@ -3236,7 +3250,7 @@ namespace Scripts.Spells.Generic
public override bool Validate(SpellInfo spellInfo) public override bool Validate(SpellInfo spellInfo)
{ {
return ValidateSpellInfo((uint)RequiredMixologySpells.Mixology); return ValidateSpellInfo((uint)RequiredMixologySpells.Mixology) && !spellInfo.GetEffects().Empty();
} }
public override bool Load() public override bool Load()
@@ -3252,7 +3266,7 @@ namespace Scripts.Spells.Generic
void CalculateAmount(AuraEffect aurEff, ref int amount, ref bool canBeRecalculated) void CalculateAmount(AuraEffect aurEff, ref int amount, ref bool canBeRecalculated)
{ {
if (GetCaster().HasAura((uint)RequiredMixologySpells.Mixology) && GetCaster().HasSpell(GetSpellInfo().GetEffect(0).TriggerSpell)) if (GetCaster().HasAura((uint)RequiredMixologySpells.Mixology) && GetCaster().HasSpell(GetEffectInfo(0).TriggerSpell))
{ {
switch ((RequiredMixologySpells)GetId()) switch ((RequiredMixologySpells)GetId())
{ {
@@ -3596,14 +3610,14 @@ namespace Scripts.Spells.Generic
[Script] // 99947 - Face Rage [Script] // 99947 - Face Rage
class spell_gen_face_rage : AuraScript class spell_gen_face_rage : AuraScript
{ {
public override bool Validate(SpellInfo spell) public override bool Validate(SpellInfo spellInfo)
{ {
return ValidateSpellInfo(SpellIds.FaceRage); return ValidateSpellInfo(SpellIds.FaceRage) && spellInfo.GetEffects().Count > 2;
} }
void OnRemove(AuraEffect effect, AuraEffectHandleModes mode) void OnRemove(AuraEffect effect, AuraEffectHandleModes mode)
{ {
GetTarget().RemoveAurasDueToSpell(GetSpellInfo().GetEffect(2).TriggerSpell); GetTarget().RemoveAurasDueToSpell(GetEffectInfo(2).TriggerSpell);
} }
public override void Register() public override void Register()
+1 -1
View File
@@ -134,7 +134,7 @@ namespace Scripts.Spells.Hunter
{ {
public override bool Validate(SpellInfo spellInfo) public override bool Validate(SpellInfo spellInfo)
{ {
return spellInfo.GetEffect(0) != null && ValidateSpellInfo(SpellIds.MastersCallTriggered, (uint)spellInfo.GetEffect(0).CalcValue()); return !spellInfo.GetEffects().Empty() && ValidateSpellInfo(SpellIds.MastersCallTriggered, (uint)spellInfo.GetEffect(0).CalcValue());
} }
public override bool Load() public override bool Load()
+6 -11
View File
@@ -380,11 +380,6 @@ namespace Scripts.Spells.Items
public const uint JomGabbar = 29602; public const uint JomGabbar = 29602;
public const uint BattleTrance = 45040; public const uint BattleTrance = 45040;
public const uint WorldQuellerFocus = 90900; public const uint WorldQuellerFocus = 90900;
public const uint AzureWaterStrider = 118089;
public const uint CrimsonWaterStrider = 127271;
public const uint OrangeWaterStrider = 127272;
public const uint JadeWaterStrider = 127274;
public const uint GoldenWaterStrider = 127278;
public const uint BrutalKinship1 = 144671; public const uint BrutalKinship1 = 144671;
public const uint BrutalKinship2 = 145738; public const uint BrutalKinship2 = 145738;
} }
@@ -1302,7 +1297,7 @@ namespace Scripts.Spells.Items
{ {
public override bool Validate(SpellInfo spellInfo) public override bool Validate(SpellInfo spellInfo)
{ {
return spellInfo.GetEffect(0) != null; return !spellInfo.GetEffects().Empty();
} }
bool CheckProc(ProcEventInfo eventInfo) bool CheckProc(ProcEventInfo eventInfo)
@@ -3346,7 +3341,7 @@ namespace Scripts.Spells.Items
{ {
public override bool Validate(SpellInfo spellInfo) public override bool Validate(SpellInfo spellInfo)
{ {
return spellInfo.GetEffect(1) != null; return spellInfo.GetEffects().Count > 1;
} }
public override bool Load() public override bool Load()
@@ -3358,7 +3353,7 @@ namespace Scripts.Spells.Items
{ {
Item artifact = GetOwner().ToPlayer().GetItemByGuid(GetAura().GetCastItemGUID()); Item artifact = GetOwner().ToPlayer().GetItemByGuid(GetAura().GetCastItemGUID());
if (artifact) if (artifact)
amount = (int)(GetSpellInfo().GetEffect(1).BasePoints * artifact.GetTotalPurchasedArtifactPowers() / 100); amount = (int)(GetEffectInfo(1).BasePoints * artifact.GetTotalPurchasedArtifactPowers() / 100);
} }
public override void Register() public override void Register()
@@ -3372,7 +3367,7 @@ namespace Scripts.Spells.Items
{ {
public override bool Validate(SpellInfo spellInfo) public override bool Validate(SpellInfo spellInfo)
{ {
return spellInfo.GetEffect(1) != null; return spellInfo.GetEffects().Count > 1;
} }
public override bool Load() public override bool Load()
@@ -3476,9 +3471,9 @@ namespace Scripts.Spells.Items
[Script] // 127278 - Golden Water Strider [Script] // 127278 - Golden Water Strider
class spell_item_water_strider : AuraScript class spell_item_water_strider : AuraScript
{ {
public override bool Validate(SpellInfo spell) public override bool Validate(SpellInfo spellInfo)
{ {
return ValidateSpellInfo(SpellIds.AzureWaterStrider, SpellIds.CrimsonWaterStrider, SpellIds.OrangeWaterStrider, SpellIds.JadeWaterStrider, SpellIds.GoldenWaterStrider); return spellInfo.GetEffects().Count > 1;
} }
void OnRemove(AuraEffect effect, AuraEffectHandleModes mode) void OnRemove(AuraEffect effect, AuraEffectHandleModes mode)
+13 -15
View File
@@ -151,7 +151,7 @@ namespace Scripts.Spells.Mage
public override bool Validate(SpellInfo spellInfo) public override bool Validate(SpellInfo spellInfo)
{ {
return ValidateSpellInfo(SpellIds.ArcaneBarrageR3, SpellIds.ArcaneBarrageEnergize) && spellInfo.GetEffect(1) != null; return ValidateSpellInfo(SpellIds.ArcaneBarrageR3, SpellIds.ArcaneBarrageEnergize) && spellInfo.GetEffects().Count > 1;
} }
void ConsumeArcaneCharges() void ConsumeArcaneCharges()
@@ -214,8 +214,10 @@ namespace Scripts.Spells.Mage
if (!ValidateSpellInfo(SpellIds.ArcaneMage, SpellIds.Reverberate)) if (!ValidateSpellInfo(SpellIds.ArcaneMage, SpellIds.Reverberate))
return false; return false;
SpellEffectInfo damageEffect = spellInfo.GetEffect(1); if (spellInfo.GetEffects().Count <= 1)
return damageEffect != null && damageEffect.IsEffect(SpellEffectName.SchoolDamage); return false;
return spellInfo.GetEffect(1).IsEffect(SpellEffectName.SchoolDamage);
} }
void CheckRequiredAuraForBaselineEnergize(uint effIndex) void CheckRequiredAuraForBaselineEnergize(uint effIndex)
@@ -319,7 +321,7 @@ namespace Scripts.Spells.Mage
{ {
public override bool Validate(SpellInfo spellInfo) public override bool Validate(SpellInfo spellInfo)
{ {
return spellInfo.GetEffect(2) != null && ValidateSpellInfo(SpellIds.CauterizeDot, SpellIds.Cauterized, spellInfo.GetEffect(2).TriggerSpell); return spellInfo.GetEffects().Count > 2 && ValidateSpellInfo(SpellIds.CauterizeDot, SpellIds.Cauterized, spellInfo.GetEffect(2).TriggerSpell);
} }
void HandleAbsorb(AuraEffect aurEff, DamageInfo dmgInfo, ref uint absorbAmount) void HandleAbsorb(AuraEffect aurEff, DamageInfo dmgInfo, ref uint absorbAmount)
@@ -335,7 +337,7 @@ namespace Scripts.Spells.Mage
} }
GetTarget().SetHealth(GetTarget().CountPctFromMaxHealth(effectInfo.GetAmount())); GetTarget().SetHealth(GetTarget().CountPctFromMaxHealth(effectInfo.GetAmount()));
GetTarget().CastSpell(GetTarget(), GetSpellInfo().GetEffect(2).TriggerSpell, new CastSpellExtraArgs(TriggerCastFlags.FullMask)); GetTarget().CastSpell(GetTarget(), GetEffectInfo(2).TriggerSpell, new CastSpellExtraArgs(TriggerCastFlags.FullMask));
GetTarget().CastSpell(GetTarget(), SpellIds.CauterizeDot, new CastSpellExtraArgs(TriggerCastFlags.FullMask)); GetTarget().CastSpell(GetTarget(), SpellIds.CauterizeDot, new CastSpellExtraArgs(TriggerCastFlags.FullMask));
GetTarget().CastSpell(GetTarget(), SpellIds.Cauterized, new CastSpellExtraArgs(TriggerCastFlags.FullMask)); GetTarget().CastSpell(GetTarget(), SpellIds.Cauterized, new CastSpellExtraArgs(TriggerCastFlags.FullMask));
} }
@@ -517,15 +519,11 @@ namespace Scripts.Spells.Mage
{ {
// Thermal Void // Thermal Void
Aura thermalVoid = caster.GetAura(SpellIds.ThermalVoid); Aura thermalVoid = caster.GetAura(SpellIds.ThermalVoid);
if (thermalVoid != null) if (!thermalVoid.GetSpellInfo().GetEffects().Empty())
{ {
SpellEffectInfo thermalVoidEffect = thermalVoid.GetSpellInfo().GetEffect(0); Aura icyVeins = caster.GetAura(SpellIds.IcyVeins);
if (thermalVoidEffect != null) if (icyVeins != null)
{ icyVeins.SetDuration(icyVeins.GetDuration() + thermalVoid.GetSpellInfo().GetEffect(0).CalcValue(caster) * Time.InMilliseconds);
Aura icyVeins = caster.GetAura(SpellIds.IcyVeins);
if (icyVeins != null)
icyVeins.SetDuration(icyVeins.GetDuration() + thermalVoidEffect.CalcValue(caster) * Time.InMilliseconds);
}
} }
// Chain Reaction // Chain Reaction
@@ -750,7 +748,7 @@ namespace Scripts.Spells.Mage
{ {
public override bool Validate(SpellInfo spellInfo) public override bool Validate(SpellInfo spellInfo)
{ {
return ValidateSpellInfo(SpellIds.RingOfFrostSummon, SpellIds.RingOfFrostFreeze); return ValidateSpellInfo(SpellIds.RingOfFrostSummon, SpellIds.RingOfFrostFreeze) && !Global.SpellMgr.GetSpellInfo(SpellIds.RingOfFrostSummon, GetCastDifficulty()).GetEffects().Empty();
} }
void HandleEffectPeriodic(AuraEffect aurEff) void HandleEffectPeriodic(AuraEffect aurEff)
@@ -806,7 +804,7 @@ namespace Scripts.Spells.Mage
{ {
public override bool Validate(SpellInfo spellInfo) public override bool Validate(SpellInfo spellInfo)
{ {
return ValidateSpellInfo(SpellIds.RingOfFrostSummon, SpellIds.RingOfFrostFreeze); return ValidateSpellInfo(SpellIds.RingOfFrostSummon, SpellIds.RingOfFrostFreeze) && !Global.SpellMgr.GetSpellInfo(SpellIds.RingOfFrostSummon, GetCastDifficulty()).GetEffects().Empty();
} }
void FilterTargets(List<WorldObject> targets) void FilterTargets(List<WorldObject> targets)
+8 -6
View File
@@ -20,6 +20,7 @@ using Game.Entities;
using Game.Scripting; using Game.Scripting;
using Game.Spells; using Game.Spells;
using System; using System;
using System.Collections.Generic;
namespace Scripts.Spells.Monk namespace Scripts.Spells.Monk
{ {
@@ -304,14 +305,15 @@ namespace Scripts.Spells.Monk
{ {
float _period; float _period;
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.StaggerDamageAura)
&& !Global.SpellMgr.GetSpellInfo(SpellIds.StaggerDamageAura, Difficulty.None).GetEffects().Empty();
}
public override bool Load() public override bool Load()
{ {
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.StaggerDamageAura, GetCastDifficulty()); _period = (float)Global.SpellMgr.GetSpellInfo(SpellIds.StaggerDamageAura, GetCastDifficulty()).GetEffect(0).ApplyAuraPeriod;
SpellEffectInfo effInfo = spellInfo?.GetEffect(0);
if (effInfo == null)
return false;
_period = (float)effInfo.ApplyAuraPeriod;
return true; return true;
} }
+11 -20
View File
@@ -115,7 +115,7 @@ namespace Scripts.Spells.Priest
public override bool Validate(SpellInfo spellInfo) public override bool Validate(SpellInfo spellInfo)
{ {
return ValidateSpellInfo(SpellIds.AtonementHeal); return ValidateSpellInfo(SpellIds.AtonementHeal) && spellInfo.GetEffects().Count > 1;
} }
bool CheckProc(ProcEventInfo eventInfo) bool CheckProc(ProcEventInfo eventInfo)
@@ -133,7 +133,7 @@ namespace Scripts.Spells.Priest
Unit target = Global.ObjAccessor.GetUnit(GetTarget(), targetGuid); Unit target = Global.ObjAccessor.GetUnit(GetTarget(), targetGuid);
if (target) if (target)
{ {
if (target.GetExactDist(GetTarget()) < GetSpellInfo().GetEffect(1).CalcValue()) if (target.GetExactDist(GetTarget()) < GetEffectInfo(1).CalcValue())
GetTarget().CastSpell(target, SpellIds.AtonementHeal, args); GetTarget().CastSpell(target, SpellIds.AtonementHeal, args);
return false; return false;
@@ -242,12 +242,12 @@ namespace Scripts.Spells.Priest
public override bool Validate(SpellInfo spellInfo) public override bool Validate(SpellInfo spellInfo)
{ {
return ValidateSpellInfo(SpellIds.GuardianSpiritHeal); return ValidateSpellInfo(SpellIds.GuardianSpiritHeal) && spellInfo.GetEffects().Count > 1;
} }
public override bool Load() public override bool Load()
{ {
healPct = (uint)GetSpellInfo().GetEffect(1).CalcValue(); healPct = (uint)GetEffectInfo(1).CalcValue();
return true; return true;
} }
@@ -285,10 +285,9 @@ namespace Scripts.Spells.Priest
public override bool Validate(SpellInfo spellInfo) public override bool Validate(SpellInfo spellInfo)
{ {
return ValidateSpellInfo(SpellIds.Heal, SpellIds.FlashHeal, SpellIds.PrayerOfHealing, SpellIds.Renew, SpellIds.Smite, SpellIds.HolyWordChastise, SpellIds.HolyWordSanctify, SpellIds.HolyWordSerenity) return ValidateSpellInfo(SpellIds.Heal, SpellIds.FlashHeal, SpellIds.PrayerOfHealing, SpellIds.Renew, SpellIds.Smite, SpellIds.HolyWordChastise, SpellIds.HolyWordSanctify, SpellIds.HolyWordSerenity)
&& Global.SpellMgr.GetSpellInfo(SpellIds.HolyWordSerenity, Difficulty.None).GetEffect(1) != null && Global.SpellMgr.GetSpellInfo(SpellIds.HolyWordSerenity, Difficulty.None).GetEffects().Count > 1
&& Global.SpellMgr.GetSpellInfo(SpellIds.HolyWordSanctify, Difficulty.None).GetEffect(2) != null && Global.SpellMgr.GetSpellInfo(SpellIds.HolyWordSanctify, Difficulty.None).GetEffects().Count > 3
&& Global.SpellMgr.GetSpellInfo(SpellIds.HolyWordSanctify, Difficulty.None).GetEffect(3) != null && Global.SpellMgr.GetSpellInfo(SpellIds.HolyWordChastise, Difficulty.None).GetEffects().Count > 1;
&& Global.SpellMgr.GetSpellInfo(SpellIds.HolyWordChastise, Difficulty.None).GetEffect(1) != null;
} }
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo) void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
@@ -480,16 +479,12 @@ namespace Scripts.Spells.Priest
{ {
public override bool Validate(SpellInfo spellInfo) public override bool Validate(SpellInfo spellInfo)
{ {
return ValidateSpellInfo(SpellIds.Atonement, SpellIds.AtonementTriggered, SpellIds.Trinity); return ValidateSpellInfo(SpellIds.Atonement, SpellIds.AtonementTriggered, SpellIds.Trinity) && spellInfo.GetEffects().Count > 3;
} }
void OnTargetSelect(List<WorldObject> targets) void OnTargetSelect(List<WorldObject> targets)
{ {
SpellEffectInfo eff2 = GetEffectInfo(2); uint maxTargets = (uint)(GetEffectInfo(2).CalcValue(GetCaster()) + 1); // adding 1 for explicit target unit
if (eff2 == null)
return;
uint maxTargets = (uint)(eff2.CalcValue(GetCaster()) + 1); // adding 1 for explicit target unit
if (targets.Count > maxTargets) if (targets.Count > maxTargets)
{ {
Unit explTarget = GetExplTargetUnit(); Unit explTarget = GetExplTargetUnit();
@@ -516,11 +511,7 @@ namespace Scripts.Spells.Priest
if (caster.HasAura(SpellIds.Trinity)) if (caster.HasAura(SpellIds.Trinity))
return; return;
SpellEffectInfo effect3 = GetEffectInfo(3); int durationPct = GetEffectInfo(3).CalcValue(caster);
if (effect3 == null)
return;
int durationPct = effect3.CalcValue(caster);
if (caster.HasAura(SpellIds.Atonement)) if (caster.HasAura(SpellIds.Atonement))
caster.CastSpell(GetHitUnit(), SpellIds.AtonementTriggered, new CastSpellExtraArgs(SpellValueMod.DurationPct, durationPct).SetTriggerFlags(TriggerCastFlags.FullMask)); caster.CastSpell(GetHitUnit(), SpellIds.AtonementTriggered, new CastSpellExtraArgs(SpellValueMod.DurationPct, durationPct).SetTriggerFlags(TriggerCastFlags.FullMask));
} }
@@ -622,7 +613,7 @@ namespace Scripts.Spells.Priest
public override bool Validate(SpellInfo spellInfo) public override bool Validate(SpellInfo spellInfo)
{ {
return ValidateSpellInfo(SpellIds.PrayerOfMendingHeal, SpellIds.PrayerOfMendingAura) return ValidateSpellInfo(SpellIds.PrayerOfMendingHeal, SpellIds.PrayerOfMendingAura)
&& Global.SpellMgr.GetSpellInfo(SpellIds.PrayerOfMendingHeal, Difficulty.None).GetEffect(0) != null; && !Global.SpellMgr.GetSpellInfo(SpellIds.PrayerOfMendingHeal, Difficulty.None).GetEffects().Empty();
} }
public override bool Load() public override bool Load()
+9 -4
View File
@@ -673,14 +673,19 @@ namespace Scripts.Spells.Quest
[Script] [Script]
class spell_q12683_take_sputum_sample : SpellScript class spell_q12683_take_sputum_sample : SpellScript
{ {
public override bool Validate(SpellInfo spellInfo)
{
return spellInfo.GetEffects().Count > 1;
}
void HandleDummy(uint effIndex) void HandleDummy(uint effIndex)
{ {
uint reqAuraId = (uint)GetSpellInfo().GetEffect(1).CalcValue(); uint reqAuraId = (uint)GetEffectInfo(1).CalcValue();
Unit caster = GetCaster(); Unit caster = GetCaster();
if (caster.HasAuraEffect(reqAuraId, 0)) if (caster.HasAuraEffect(reqAuraId, 0))
{ {
uint spellId = (uint)GetSpellInfo().GetEffect(0).CalcValue(); uint spellId = (uint)GetEffectInfo(0).CalcValue();
caster.CastSpell(caster, spellId, true); caster.CastSpell(caster, spellId, true);
} }
} }
@@ -1451,7 +1456,7 @@ namespace Scripts.Spells.Quest
{ {
public override bool Validate(SpellInfo spellInfo) public override bool Validate(SpellInfo spellInfo)
{ {
return ValidateSpellInfo((uint)spellInfo.GetEffect(0).CalcValue()); return !spellInfo.GetEffects().Empty() && ValidateSpellInfo((uint)spellInfo.GetEffect(0).CalcValue());
} }
void HandleEffectDummy(uint effIndex) void HandleEffectDummy(uint effIndex)
@@ -1612,7 +1617,7 @@ namespace Scripts.Spells.Quest
{ {
void ModDest(ref SpellDestination dest) void ModDest(ref SpellDestination dest)
{ {
float dist = GetSpellInfo().GetEffect(0).CalcRadius(GetCaster()); float dist = GetEffectInfo(0).CalcRadius(GetCaster());
float angle = RandomHelper.FRand(0.75f, 1.25f) * MathFunctions.PI; float angle = RandomHelper.FRand(0.75f, 1.25f) * MathFunctions.PI;
Position pos = GetCaster().GetNearPosition(dist, angle); Position pos = GetCaster().GetNearPosition(dist, angle);
+11 -15
View File
@@ -199,26 +199,22 @@ namespace Scripts.Spells.Warlock
{ {
public override bool Validate(SpellInfo spellInfo) public override bool Validate(SpellInfo spellInfo)
{ {
return ValidateSpellInfo(SpellIds.GlyphOfDemonTraining, SpellIds.DevourMagicHeal); return ValidateSpellInfo(SpellIds.GlyphOfDemonTraining, SpellIds.DevourMagicHeal) && spellInfo.GetEffects().Count > 1;
} }
void OnSuccessfulDispel(uint effIndex) void OnSuccessfulDispel(uint effIndex)
{ {
SpellEffectInfo effect = GetSpellInfo().GetEffect(1); Unit caster = GetCaster();
if (effect != null) CastSpellExtraArgs args = new(TriggerCastFlags.FullMask);
{ args.AddSpellMod(SpellValueMod.BasePoint0, GetEffectInfo(1).CalcValue(caster));
Unit caster = GetCaster();
CastSpellExtraArgs args = new(TriggerCastFlags.FullMask);
args.AddSpellMod(SpellValueMod.BasePoint0, effect.CalcValue(caster));
caster.CastSpell(caster, SpellIds.DevourMagicHeal, args); caster.CastSpell(caster, SpellIds.DevourMagicHeal, args);
// Glyph of Felhunter // Glyph of Felhunter
Unit owner = caster.GetOwner(); Unit owner = caster.GetOwner();
if (owner) if (owner)
if (owner.GetAura(SpellIds.GlyphOfDemonTraining) != null) if (owner.GetAura(SpellIds.GlyphOfDemonTraining) != null)
owner.CastSpell(owner, SpellIds.DevourMagicHeal, args); owner.CastSpell(owner, SpellIds.DevourMagicHeal, args);
}
} }
public override void Register() public override void Register()
@@ -370,7 +366,7 @@ namespace Scripts.Spells.Warlock
if (caster == null) if (caster == null)
return; return;
amount = caster.SpellBaseDamageBonusDone(GetSpellInfo().GetSchoolMask()) * GetSpellInfo().GetEffect(0).CalcValue(caster) / 100; amount = caster.SpellBaseDamageBonusDone(GetSpellInfo().GetSchoolMask()) * GetEffectInfo(0).CalcValue(caster) / 100;
} }
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo) void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
+5 -5
View File
@@ -302,7 +302,7 @@ namespace Scripts.Spells.Warrior
{ {
public override bool Validate(SpellInfo spellInfo) public override bool Validate(SpellInfo spellInfo)
{ {
return ValidateSpellInfo(SpellIds.Stoicism); return ValidateSpellInfo(SpellIds.Stoicism) && spellInfo.GetEffects().Count > 1;
} }
void HandleProc(ProcEventInfo eventInfo) void HandleProc(ProcEventInfo eventInfo)
@@ -310,7 +310,7 @@ namespace Scripts.Spells.Warrior
PreventDefaultAction(); PreventDefaultAction();
Unit target = eventInfo.GetActionTarget(); Unit target = eventInfo.GetActionTarget();
int bp0 = (int)MathFunctions.CalculatePct(target.GetMaxHealth(), GetSpellInfo().GetEffect(1).CalcValue()); int bp0 = (int)MathFunctions.CalculatePct(target.GetMaxHealth(), GetEffectInfo(1).CalcValue());
CastSpellExtraArgs args = new(TriggerCastFlags.FullMask); CastSpellExtraArgs args = new(TriggerCastFlags.FullMask);
args.AddSpellMod(SpellValueMod.BasePoint0, bp0); args.AddSpellMod(SpellValueMod.BasePoint0, bp0);
target.CastSpell((Unit)null, SpellIds.Stoicism, args); target.CastSpell((Unit)null, SpellIds.Stoicism, args);
@@ -378,7 +378,7 @@ namespace Scripts.Spells.Warrior
if (!ValidateSpellInfo(SpellIds.Shockwave, SpellIds.ShockwaveStun)) if (!ValidateSpellInfo(SpellIds.Shockwave, SpellIds.ShockwaveStun))
return false; return false;
return spellInfo.GetEffect(0) != null && spellInfo.GetEffect(3) != null; return spellInfo.GetEffects().Count > 3;
} }
public override bool Load() public override bool Load()
@@ -395,8 +395,8 @@ namespace Scripts.Spells.Warrior
// Cooldown reduced by 20 sec if it strikes at least 3 targets. // Cooldown reduced by 20 sec if it strikes at least 3 targets.
void HandleAfterCast() void HandleAfterCast()
{ {
if (_targetCount >= (uint)GetSpellInfo().GetEffect(0).CalcValue()) if (_targetCount >= (uint)GetEffectInfo(0).CalcValue())
GetCaster().ToPlayer().GetSpellHistory().ModifyCooldown(GetSpellInfo().Id, TimeSpan.FromSeconds(-GetSpellInfo().GetEffect(3).CalcValue())); GetCaster().ToPlayer().GetSpellHistory().ModifyCooldown(GetSpellInfo().Id, TimeSpan.FromSeconds(-GetEffectInfo(3).CalcValue()));
} }
public override void Register() public override void Register()