diff --git a/src/Modules/CalcOffence.lua b/src/Modules/CalcOffence.lua index fd2a91bc2e..33ceec1c84 100644 --- a/src/Modules/CalcOffence.lua +++ b/src/Modules/CalcOffence.lua @@ -2448,7 +2448,7 @@ function calcs.offence(env, actor, activeSkill) elseif mode == "AVERAGE" then output[stat] = ((output.MainHand[stat] or 0) + (output.OffHand[stat] or 0)) / 2 elseif mode == "CRIT" then - if skillFlags.bothWeaponAttack and skillData.doubleHitsWhenDualWielding then + if skillFlags.bothWeaponAttack and skillData.combinesHitsWhenDualWielding then output[stat] = (output.MainHand[stat] or 0) + (output.OffHand[stat] or 0) - ((output.MainHand[stat] or 0) * (output.OffHand[stat] or 0) / 100) else output[stat] = ((output.MainHand[stat] or 0) + (output.OffHand[stat] or 0)) / 2 @@ -2522,7 +2522,7 @@ function calcs.offence(env, actor, activeSkill) end elseif mode == "DPS" then output[stat] = (output.MainHand[stat] or 0) + (output.OffHand[stat] or 0) - if not skillData.doubleHitsWhenDualWielding then + if not skillData.combinesHitsWhenDualWielding then output[stat] = output[stat] / 2 end end @@ -3037,11 +3037,26 @@ function calcs.offence(env, actor, activeSkill) end elseif skillFlags.bothWeaponAttack then if breakdown then - breakdown.Speed = { - "Both weapons:", - s_format("2 / (1 / %.2f + 1 / %.2f)", output.MainHand.Speed, output.OffHand.Speed), - s_format("= %.2f", output.Speed), - } + if skillData.combinesHitsWhenDualWielding then + breakdown.Speed = { + "Combined hit from both weapons:", + s_format("1 / (1 / %.2f + 1 / %.2f)", output.MainHand.Speed, output.OffHand.Speed), + s_format("= %.2f", output.Speed), + } + elseif skillData.doubleHitsWhenDualWielding then + breakdown.Speed = { + "Simultaneous hits from each weapon:", + s_format("2 / (1 / %.2f + 1 / %.2f)", output.MainHand.Speed, output.OffHand.Speed), + s_format("%.2f * 2 ^8(hits twice per attack)", output.Speed), + s_format("= %.2f", output.Speed), + } + else + breakdown.Speed = { + "Alternating both weapons:", + s_format("2 / (1 / %.2f + 1 / %.2f)", output.MainHand.Speed, output.OffHand.Speed), + s_format("= %.2f", output.Speed), + } + end end end if skillData.channelTimeMultiplier then @@ -3727,6 +3742,12 @@ function calcs.offence(env, actor, activeSkill) output.DoubleDamageEffect = output.DoubleDamageChance / 100 output.ScaledDamageEffect = output.ScaledDamageEffect * (1 + output.DoubleDamageEffect + output.TripleDamageEffect) + -- Dual wield DPS multiplier + -- NOTE: This solution is a bit "hacky", but ensures that the hit rate multiplier for dual wielding isn't applied multiple times + if skillFlags.bothWeaponAttack and skillData.doubleHitsWhenDualWielding and pass.label == "Off Hand" then + skillModList:NewMod("DPS", "MORE", 100, "Hits with both weapons") + end + skillData.dpsMultiplier = ( skillData.dpsMultiplier or 1 ) * calcLib.mod(skillModList, skillCfg, "DPS") local hitRate = output.HitChance / 100 * (globalOutput.HitSpeed or globalOutput.Speed) * skillData.dpsMultiplier @@ -4463,8 +4484,10 @@ function calcs.offence(env, actor, activeSkill) if breakdown then breakdown.AverageDamage = { } t_insert(breakdown.AverageDamage, "Both weapons:") - if skillData.doubleHitsWhenDualWielding then + if skillData.combinesHitsWhenDualWielding then t_insert(breakdown.AverageDamage, s_format("%.1f + %.1f ^8(skill hits with both weapons at once)", output.MainHand.AverageDamage, output.OffHand.AverageDamage)) + elseif skillData.doubleHitsWhenDualWielding then + t_insert(breakdown.AverageDamage, s_format("%.1f + %.1f ^8(skill hits once with each weapon)", output.MainHand.AverageDamage, output.OffHand.AverageDamage)) else t_insert(breakdown.AverageDamage, s_format("(%.1f + %.1f) / 2 ^8(skill alternates weapons)", output.MainHand.AverageDamage, output.OffHand.AverageDamage)) end @@ -4472,7 +4495,7 @@ function calcs.offence(env, actor, activeSkill) if skillFlags.isPvP then breakdown.PvpAverageDamage = { } t_insert(breakdown.PvpAverageDamage, "Both weapons:") - if skillData.doubleHitsWhenDualWielding then + if skillData.combinesHitsWhenDualWielding then t_insert(breakdown.PvpAverageDamage, s_format("%.1f + %.1f ^8(skill hits with both weapons at once)", output.MainHand.PvpAverageDamage, output.OffHand.PvpAverageDamage)) else t_insert(breakdown.PvpAverageDamage, s_format("(%.1f + %.1f) / 2 ^8(skill alternates weapons)", output.MainHand.PvpAverageDamage, output.OffHand.PvpAverageDamage)) @@ -5938,7 +5961,7 @@ function calcs.offence(env, actor, activeSkill) end if skillFlags.impale then local mainHandImpaleDPS, offHandImpaleDPS - if skillFlags.attack and skillData.doubleHitsWhenDualWielding and skillFlags.bothWeaponAttack then + if skillFlags.attack and skillData.combinesHitsWhenDualWielding and skillFlags.bothWeaponAttack then -- separately combine mainHandImpaleDPS = output.MainHand.impaleStoredHitAvg * ((output.MainHand.ImpaleModifier or 1) - 1) * output.MainHand.HitChance / 100 * skillData.dpsMultiplier offHandImpaleDPS = output.OffHand.impaleStoredHitAvg * ((output.OffHand.ImpaleModifier or 1) - 1) * output.OffHand.HitChance / 100 * skillData.dpsMultiplier @@ -5960,7 +5983,7 @@ function calcs.offence(env, actor, activeSkill) output.CombinedDPS = output.CombinedDPS + output.ImpaleDPS if breakdown then breakdown.ImpaleDPS = {} - if skillFlags.attack and skillData.doubleHitsWhenDualWielding and skillFlags.bothWeaponAttack then + if skillFlags.attack and skillData.combinesHitsWhenDualWielding and skillFlags.bothWeaponAttack then t_insert(breakdown.ImpaleDPS, s_format("Main Hand:")) t_insert(breakdown.ImpaleDPS, s_format("%.2f ^8(MH average physical hit before mitigation)", output.MainHand.impaleStoredHitAvg)) t_insert(breakdown.ImpaleDPS, s_format("x %.2f ^8(MH chance to hit)", output.MainHand.HitChance / 100)) diff --git a/src/Modules/CalcTriggers.lua b/src/Modules/CalcTriggers.lua index d861968b9e..2ee4867f78 100644 --- a/src/Modules/CalcTriggers.lua +++ b/src/Modules/CalcTriggers.lua @@ -429,7 +429,7 @@ local function defaultTriggerHandler(env, config) end -- Dual wield triggers - if trigRate and source and env.player.weaponData1.type and env.player.weaponData2.type and not source.skillData.doubleHitsWhenDualWielding and (source.skillTypes[SkillType.Melee] or source.skillTypes[SkillType.Attack]) and actor.mainSkill.triggeredBy and actor.mainSkill.triggeredBy.grantedEffect.support and actor.mainSkill.triggeredBy.grantedEffect.fromItem then + if trigRate and source and env.player.weaponData1.type and env.player.weaponData2.type and not source.skillData.combinesHitsWhenDualWielding and (source.skillTypes[SkillType.Melee] or source.skillTypes[SkillType.Attack]) and actor.mainSkill.triggeredBy and actor.mainSkill.triggeredBy.grantedEffect.support and actor.mainSkill.triggeredBy.grantedEffect.fromItem then trigRate = trigRate / 2 if breakdown then t_insert(breakdown.EffectiveSourceRate, 2, s_format("/ 2 ^8(due to dual wielding)")) @@ -722,7 +722,7 @@ local function defaultTriggerHandler(env, config) local sourceHitChance = GlobalCache.cachedData[env.mode][uuid].HitChance or 0 if sourceHitChance ~= 100 then -- Some skills hit with both weapons at the same time. Each weapon rolls accuracy and crit independently - if source and env.player.weaponData1.type and env.player.weaponData2.type and source.skillData.doubleHitsWhenDualWielding then + if source and env.player.weaponData1.type and env.player.weaponData2.type and source.skillData.combinesHitsWhenDualWielding then local mainHandHit = GlobalCache.cachedData[env.mode][uuid].Env.player.output.MainHand.HitChance local offHandHit = GlobalCache.cachedData[env.mode][uuid].Env.player.output.OffHand.HitChance local bothHit = mainHandHit * offHandHit / 100 @@ -747,7 +747,7 @@ local function defaultTriggerHandler(env, config) local sourceCritChance = GlobalCache.cachedData[env.mode][uuid].CritChance or 0 if sourceCritChance ~= 100 then -- Some skills hit with both weapons at the same time. Each weapon rolls accuracy and crit independently - if source and env.player.weaponData1.type and env.player.weaponData2.type and source.skillData.doubleHitsWhenDualWielding then + if source and env.player.weaponData1.type and env.player.weaponData2.type and source.skillData.combinesHitsWhenDualWielding then local mainHandCrit = GlobalCache.cachedData[env.mode][uuid].Env.player.output.MainHand.CritChance local offHandCrit = GlobalCache.cachedData[env.mode][uuid].Env.player.output.OffHand.CritChance local bothHit = mainHandCrit * offHandCrit / 100