@@ -3340,6 +3340,7 @@ function calcs.offence(env, actor, activeSkill)
33403340 end
33413341
33423342 -- Calculate crit chance, crit multiplier, and their combined effect
3343+ local forcedOutcomeApplies = false
33433344 if skillModList :Flag (cfg , " NeverCrit" ) then
33443345 output .PreEffectiveCritChance = 0
33453346 output .CritChance = 0
@@ -3429,10 +3430,11 @@ function calcs.offence(env, actor, activeSkill)
34293430 if env .mode_effective and skillModList :Flag (cfg , " BifurcateCrit" ) then
34303431 output .CritChance = (1 - (1 - output .CritChance / 100 ) ^ 2 ) * 100
34313432 end
3432- if env .mode_effective and skillModList :Flag (cfg , " ForcedOutcome" ) then
3433- -- Lucky crits: not considered a 'reroll' for the sake of forced outcome penalties, just a higher crit chance
3434- -- Bifurcated crits: only considered a 'reroll' if both of them fail to crit
3435- -- So just use the crit chance as calculated, and it already works with both of them
3433+ local preForcedOutcomeCritChance = output .CritChance
3434+ if env .mode_effective and skillModList :Flag (cfg , " ForcedOutcome" ) and output .CritChance > 0 then
3435+ forcedOutcomeApplies = true
3436+ -- Lucky crits use their effective crit chance without an extra roll-down penalty.
3437+ -- Bifurcated crits roll twice per roll-down; only both rolls failing advances the penalty.
34363438 local critChance = output .CritChance / 100
34373439 local nonCritChance = 1 - critChance
34383440
@@ -3441,6 +3443,12 @@ function calcs.offence(env, actor, activeSkill)
34413443 0.7 * nonCritChance * critChance + -- 70% if we roll non-crit then a crit
34423444 0.4 * m_pow (nonCritChance , 2 ) * critChance + -- 40% if we roll two non-crit then a crit
34433445 0.1 * m_pow (nonCritChance , 3 ) * critChance -- 10% if we roll three non-crits then a crit
3446+ if skillModList :Flag (cfg , " BifurcateCrit" ) then
3447+ -- The terminating stage can crit twice, so scale its one-or-more-crit bonus
3448+ -- by the expected number of crits on that stage.
3449+ critBonusMultiplier = critBonusMultiplier * 2 * output .PreBifurcateCritChance / output .CritChance
3450+ output .CritBifurcates = output .PreBifurcateCritChance ^ 2 / output .CritChance
3451+ end
34443452
34453453 -- This gets rounded when used in damage logic, so round it ahead of time to make the breakdown accurate (and less ugly)
34463454 local lessCritBonus = round ((1 - critBonusMultiplier ) * - 100.0 , 0 )
@@ -3484,9 +3492,9 @@ function calcs.offence(env, actor, activeSkill)
34843492 if env .mode_effective and skillModList :Flag (cfg , " BifurcateCrit" ) then
34853493 t_insert (breakdown .CritChance , " Critical Strike Bifurcates:" )
34863494 t_insert (breakdown .CritChance , s_format (" 1 - (1 - %.4f) x (1 - %.4f)" , preBifurcateCritChance / 100 , preBifurcateCritChance / 100 ))
3487- t_insert (breakdown .CritChance , s_format (" = %.2f%%" , output . CritChance ))
3495+ t_insert (breakdown .CritChance , s_format (" = %.2f%%" , preForcedOutcomeCritChance ))
34883496 end
3489- if env . mode_effective and skillModList : Flag ( cfg , " ForcedOutcome " ) then
3497+ if forcedOutcomeApplies then
34903498 t_insert (breakdown .CritChance , " Inevitable Critical Hits (Forced Outcome):" )
34913499 t_insert (breakdown .CritChance , " = 100% ^8(override)" )
34923500 end
@@ -3508,7 +3516,7 @@ function calcs.offence(env, actor, activeSkill)
35083516
35093517 output .PreEffectiveCritMultiplier = 1 + extraDamage
35103518 -- if crit bifurcates are enabled, roll for crit twice and add multiplier for each
3511- if env .mode_effective and skillModList :Flag (cfg , " BifurcateCrit" ) then
3519+ if env .mode_effective and skillModList :Flag (cfg , " BifurcateCrit" ) and not forcedOutcomeApplies then
35123520 -- get crit chance and calculate odds of critting twice
35133521 local critChancePercentage = output .PreBifurcateCritChance
35143522 local bifurcateMultiChance = (critChancePercentage ^ 2 ) / 100
0 commit comments