diff --git a/Source/Game/Entities/StatSystem.cs b/Source/Game/Entities/StatSystem.cs index 132adff25..182dc5628 100644 --- a/Source/Game/Entities/StatSystem.cs +++ b/Source/Game/Entities/StatSystem.cs @@ -1479,14 +1479,7 @@ namespace Game.Entities expertise += GetTotalAuraModifier(AuraType.ModExpertise, aurEff => { - // item neutral spell - if ((int)aurEff.GetSpellInfo().EquippedItemClass == -1) - return true; - // item dependent spell - else if (weapon != null && weapon.IsFitToSpellRequirements(aurEff.GetSpellInfo())) - return true; - - return false; + return aurEff.GetSpellInfo().IsItemFitToSpellRequirements(weapon); }); if (expertise < 0) diff --git a/Source/Game/Spells/Spell.cs b/Source/Game/Spells/Spell.cs index 7a2e48981..405889b0a 100644 --- a/Source/Game/Spells/Spell.cs +++ b/Source/Game/Spells/Spell.cs @@ -55,25 +55,7 @@ namespace Game.Spells m_needComboPoints = m_spellInfo.NeedsComboPoints(); // Get data for type of attack - switch (m_spellInfo.DmgClass) - { - case SpellDmgClass.Melee: - if (m_spellInfo.HasAttribute(SpellAttr3.ReqOffhand)) - m_attackType = WeaponAttackType.OffAttack; - else - m_attackType = WeaponAttackType.BaseAttack; - break; - case SpellDmgClass.Ranged: - m_attackType = m_spellInfo.IsRangedWeaponSpell() ? WeaponAttackType.RangedAttack : WeaponAttackType.BaseAttack; - break; - default: - // Wands - if (m_spellInfo.HasAttribute(SpellAttr2.AutorepeatFlag)) - m_attackType = WeaponAttackType.RangedAttack; - else - m_attackType = WeaponAttackType.BaseAttack; - break; - } + m_attackType = info.GetAttackType(); m_spellSchoolMask = m_spellInfo.GetSchoolMask(); // Can be override for some spell (wand shoot for example) @@ -6252,32 +6234,35 @@ namespace Game.Spells // check weapon presence in slots for main/offhand weapons if (!Convert.ToBoolean(_triggeredCastFlags & TriggerCastFlags.IgnoreEquippedItemRequirement) && m_spellInfo.EquippedItemClass >= 0) { - // main hand weapon required - if (m_spellInfo.HasAttribute(SpellAttr3.MainHand)) + var weaponCheck = new Func(attackType => { - Item item = m_caster.ToPlayer().GetWeaponForAttack(WeaponAttackType.BaseAttack); + Item item = m_caster.ToPlayer().GetWeaponForAttack(attackType); // skip spell if no weapon in slot or broken - if (item == null || item.IsBroken()) + if (!item || item.IsBroken()) return SpellCastResult.EquippedItemClass; // skip spell if weapon not fit to triggered spell if (!item.IsFitToSpellRequirements(m_spellInfo)) return SpellCastResult.EquippedItemClass; + + return SpellCastResult.SpellCastOk; + }); + + // main hand weapon required + if (m_spellInfo.HasAttribute(SpellAttr3.MainHand)) + { + SpellCastResult mainHandResult = weaponCheck(WeaponAttackType.BaseAttack); + if (mainHandResult != SpellCastResult.SpellCastOk) + return mainHandResult; } // offhand hand weapon required if (m_spellInfo.HasAttribute(SpellAttr3.ReqOffhand)) { - Item item = m_caster.ToPlayer().GetWeaponForAttack(WeaponAttackType.OffAttack); - - // skip spell if no weapon in slot or broken - if (item == null || item.IsBroken()) - return SpellCastResult.EquippedItemClass; - - // skip spell if weapon not fit to triggered spell - if (!item.IsFitToSpellRequirements(m_spellInfo)) - return SpellCastResult.EquippedItemClass; + SpellCastResult offHandResult = weaponCheck(WeaponAttackType.OffAttack); + if (offHandResult != SpellCastResult.SpellCastOk) + return offHandResult; } } diff --git a/Source/Game/Spells/SpellInfo.cs b/Source/Game/Spells/SpellInfo.cs index 87be27af8..c91380dd6 100644 --- a/Source/Game/Spells/SpellInfo.cs +++ b/Source/Game/Spells/SpellInfo.cs @@ -634,6 +634,45 @@ namespace Game.Spells return !(HasAttribute(SpellAttr1.NoThreat) || HasAttribute(SpellAttr3.NoInitialAggro)); } + public WeaponAttackType GetAttackType() + { + WeaponAttackType result; + switch (DmgClass) + { + case SpellDmgClass.Melee: + if (HasAttribute(SpellAttr3.ReqOffhand)) + result = WeaponAttackType.OffAttack; + else + result = WeaponAttackType.BaseAttack; + break; + case SpellDmgClass.Ranged: + result = IsRangedWeaponSpell() ? WeaponAttackType.RangedAttack : WeaponAttackType.BaseAttack; + break; + default: + // Wands + if (IsAutoRepeatRangedSpell()) + result = WeaponAttackType.RangedAttack; + else + result = WeaponAttackType.BaseAttack; + break; + } + + return result; + } + + public bool IsItemFitToSpellRequirements(Item item) + { + // item neutral spell + if (EquippedItemClass == ItemClass.None) + return true; + + // item dependent spell + if (item && item.IsFitToSpellRequirements(this)) + return true; + + return false; + } + public bool IsAffected(SpellFamilyNames familyName, FlagArray128 familyFlags) { if (familyName == 0)