@@ -1449,6 +1449,7 @@ function calcs.buildDefenceEstimations(env, actor)
14491449 }
14501450 end
14511451 local enemyCritChance = enemyDB :Flag (nil , " NeverCrit" ) and 0 or enemyDB :Flag (nil , " AlwaysCrit" ) and 100 or (m_max (m_min ((modDB :Override (nil , " enemyCritChance" ) or env .configInput [" enemyCritChance" ] or env .configPlaceholder [" enemyCritChance" ] or 0 ) * (1 + modDB :Sum (" INC" , nil , " EnemyCritChance" ) / 100 + enemyDB :Sum (" INC" , nil , " CritChance" ) / 100 ) * (1 - output [" ConfiguredEvadeChance" ] / 100 ), 100 ), 0 ))
1452+ output [" EnemyCritChance" ] = enemyCritChance
14521453 local enemyCritDamage = m_max ((env .configInput [" enemyCritDamage" ] or env .configPlaceholder [" enemyCritDamage" ] or 0 ) + enemyDB :Sum (" BASE" , nil , " CritMultiplier" ), 0 )
14531454 output [" EnemyCritEffect" ] = 1 + enemyCritChance / 100 * (enemyCritDamage / 100 ) * (1 - output .CritExtraDamageReduction / 100 )
14541455 local enemyCfg = {keywordFlags = bit .bnot (KeywordFlag .MatchAll )} -- Match all keywordFlags parameter for enemy min-max damage mods
@@ -3243,63 +3244,147 @@ function calcs.buildDefenceEstimations(env, actor)
32433244 }
32443245 end
32453246 end
3246- local enemyDotChance = 0 -- this is for future use for calculating ignite/bleed/poison etc
3247- if damageCategoryConfig == " DamageOverTime" or enemyDotChance > 0 then
3247+ local enemyCritAilmentEffect = 1 + output .EnemyCritChance / 100 * 0.5 * (1 - output .CritExtraDamageReduction / 100 )
3248+ -- this is just used so that ailments don't always showup if the enemy has no other way of applying the ailment and they have a low crit chance
3249+ local enemyCritThreshold = 10.1
3250+ local enemyBleedChance = 0
3251+ local enemyIgniteChance = 0
3252+ if output .SelfIgniteEffect ~= 0 and output .IgniteAvoidChance < 100 and output .SelfIgniteDuration ~= 0 and damageCategoryConfig ~= " DamageOverTime" then
3253+ enemyIgniteChance = enemyDB :Sum (" BASE" , nil , " IgniteChance" , " ElementalAilmentChance" )
3254+ local enemyCritAilmentChance = (not modDB :Flag (nil , " CritsOnYouDontAlwaysApplyElementalAilments" )) and ((output .EnemyCritChance > enemyCritThreshold or enemyIgniteChance > 0 ) and output .EnemyCritChance or 0 ) or 0
3255+ enemyIgniteChance = (enemyCritAilmentChance + (1 - enemyCritAilmentChance / 100 ) * enemyIgniteChance ) * (1 - output .IgniteAvoidChance / 100 )
3256+ end
3257+ local enemyPoisonChance = 0
3258+ if output .SelfPoisonEffect ~= 0 and output .PoisonAvoidChance < 100 and output .SelfPoisonDuration ~= 0 and damageCategoryConfig ~= " DamageOverTime" then
3259+ enemyPoisonChance = enemyDB :Sum (" BASE" , nil , " PoisonChance" ) * (1 - output .PoisonAvoidChance / 100 )
3260+ end
3261+ if damageCategoryConfig == " DamageOverTime" or (enemyIgniteChance + enemyPoisonChance + enemyBleedChance ) > 0 then
32483262 output .TotalDegen = output .TotalBuildDegen or 0
3249- for _ , damageType in ipairs (dmgTypeList ) do
3250- local source = " Config"
3251- local baseVal = tonumber (env .configInput [" enemy" .. damageType .. " Damage" ])
3252- if baseVal == nil then
3253- source = " Default"
3254- baseVal = tonumber (env .configPlaceholder [" enemy" .. damageType .. " Damage" ]) or 0
3255- end
3256- if baseVal > 0 then
3257- for damageConvertedType , convertPercent in pairs (actor .damageOverTimeShiftTable [damageType ]) do
3258- if convertPercent > 0 then
3259- local total = baseVal * (convertPercent / 100 ) * output [damageConvertedType .. " TakenDotMult" ]
3260- output [damageConvertedType .. " EnemyDegen" ] = (output [damageConvertedType .. " EnemyDegen" ] or 0 ) + total
3261- output .TotalDegen = output .TotalDegen + total
3262- if breakdown then
3263- breakdown .TotalDegen = breakdown .TotalDegen or {
3264- rowList = { },
3265- colList = {
3266- { label = " Source" , key = " source" },
3267- { label = " Base Type" , key = " type" },
3268- { label = " Final Type" , key = " type2" },
3269- { label = " Base" , key = " base" },
3270- { label = " Taken As Percent" , key = " conv" },
3271- { label = " Multiplier" , key = " mult" },
3272- { label = " Total" , key = " total" },
3263+ if damageCategoryConfig == " DamageOverTime" then
3264+ for _ , damageType in ipairs (dmgTypeList ) do
3265+ local source = " Config"
3266+ local baseVal = tonumber (env .configInput [" enemy" .. damageType .. " Damage" ])
3267+ if baseVal == nil then
3268+ source = " Default"
3269+ baseVal = tonumber (env .configPlaceholder [" enemy" .. damageType .. " Damage" ]) or 0
3270+ end
3271+ if baseVal > 0 then
3272+ for damageConvertedType , convertPercent in pairs (actor .damageOverTimeShiftTable [damageType ]) do
3273+ if convertPercent > 0 then
3274+ local total = baseVal * (convertPercent / 100 ) * output [damageConvertedType .. " TakenDotMult" ]
3275+ output [damageConvertedType .. " EnemyDegen" ] = (output [damageConvertedType .. " EnemyDegen" ] or 0 ) + total
3276+ output .TotalDegen = output .TotalDegen + total
3277+ if breakdown then
3278+ breakdown .TotalDegen = breakdown .TotalDegen or {
3279+ rowList = { },
3280+ colList = {
3281+ { label = " Source" , key = " source" },
3282+ { label = " Base Type" , key = " type" },
3283+ { label = " Final Type" , key = " type2" },
3284+ { label = " Base" , key = " base" },
3285+ { label = " Taken As Percent" , key = " conv" },
3286+ { label = " Multiplier" , key = " mult" },
3287+ { label = " Total" , key = " total" },
3288+ }
32733289 }
3274- }
3275- t_insert ( breakdown . TotalDegen . rowList , {
3276- source = source ,
3277- type = damageType ,
3278- type2 = damageConvertedType ,
3279- base = s_format (" %.1f " , baseVal ),
3280- conv = s_format (" x %.2f%% " , convertPercent ),
3281- mult = s_format (" x %.2f " , output [ damageConvertedType .. " TakenDotMult " ] ),
3282- total = s_format ( " %.1f " , total ),
3283- })
3284- breakdown [ damageConvertedType .. " EnemyDegen " ] = breakdown [ damageConvertedType .. " EnemyDegen " ] or {
3285- rowList = { },
3286- colList = {
3287- { label = " Source " , key = " source " },
3288- { label = " Base Type " , key = " type " },
3289- { label = " Base " , key = " base " },
3290- { label = " Taken As Percent " , key = " conv " },
3291- { label = " Multiplier " , key = " mult " },
3292- { label = " Total " , key = " total " },
3290+ t_insert ( breakdown . TotalDegen . rowList , {
3291+ source = source ,
3292+ type = damageType ,
3293+ type2 = damageConvertedType ,
3294+ base = s_format ( " %.1f " , baseVal ) ,
3295+ conv = s_format (" x %.2f%% " , convertPercent ),
3296+ mult = s_format (" x %.2f" , output [ damageConvertedType .. " TakenDotMult " ] ),
3297+ total = s_format (" %.1f " , total ),
3298+ })
3299+ breakdown [ damageConvertedType .. " EnemyDegen " ] = breakdown [ damageConvertedType .. " EnemyDegen " ] or {
3300+ rowList = { },
3301+ colList = {
3302+ { label = " Source " , key = " source " },
3303+ { label = " Base Type " , key = " type " },
3304+ { label = " Base" , key = " base " },
3305+ { label = " Taken As Percent " , key = " conv " },
3306+ { label = " Multiplier " , key = " mult " },
3307+ { label = " Total " , key = " total " },
3308+ }
32933309 }
3294- }
3295- t_insert (breakdown [damageConvertedType .. " EnemyDegen" ].rowList , {
3296- source = source ,
3297- type = damageType ,
3298- base = s_format (" %.1f" , baseVal ),
3299- conv = s_format (" x %.2f%%" , convertPercent ),
3300- mult = s_format (" x %.2f" , output [damageConvertedType .. " TakenDotMult" ]),
3301- total = s_format (" %.1f" , total ),
3302- })
3310+ t_insert (breakdown [damageConvertedType .. " EnemyDegen" ].rowList , {
3311+ source = source ,
3312+ type = damageType ,
3313+ base = s_format (" %.1f" , baseVal ),
3314+ conv = s_format (" x %.2f%%" , convertPercent ),
3315+ mult = s_format (" x %.2f" , output [damageConvertedType .. " TakenDotMult" ]),
3316+ total = s_format (" %.1f" , total ),
3317+ })
3318+ end
3319+ end
3320+ end
3321+ end
3322+ end
3323+ elseif (enemyIgniteChance + enemyPoisonChance + enemyBleedChance ) > 0 then
3324+ local ailmentList = {}
3325+ if enemyBleedChance > 0 then
3326+ ailmentList [" Bleed" ] = { damageType = " Physical" , sourceTypes = { " Physical" } }
3327+ end
3328+ if enemyIgniteChance > 0 then
3329+ ailmentList [" Ignite" ] = { damageType = " Fire" , sourceTypes = enemyDB :Flag (nil , " AllDamageIgnites" ) and dmgTypeList or { " Fire" } }
3330+ end
3331+ if enemyPoisonChance > 0 then
3332+ ailmentList [" Poison" ] = { damageType = " Chaos" , sourceTypes = { " Physical" , " Chaos" } }
3333+ end
3334+ for source , ailment in pairs (ailmentList ) do
3335+ local baseVal = 0
3336+ for _ , damageType in ipairs (ailment .sourceTypes ) do
3337+ baseVal = baseVal + output [damageType .. " TakenDamage" ]
3338+ end
3339+ baseVal = baseVal * data .misc [source .. " PercentBase" ] * (enemyCritAilmentEffect / output [" EnemyCritEffect" ]) * output [" Self" .. source .. " Effect" ] / 100
3340+ if baseVal > 0 then
3341+ for damageConvertedType , convertPercent in pairs (actor .damageOverTimeShiftTable [ailment .damageType ]) do
3342+ if convertPercent > 0 then
3343+ local total = baseVal * (convertPercent / 100 ) * output [damageConvertedType .. " TakenDotMult" ]
3344+ output [damageConvertedType .. " EnemyDegen" ] = (output [damageConvertedType .. " EnemyDegen" ] or 0 ) + total
3345+ output .TotalDegen = output .TotalDegen + total
3346+ if breakdown then
3347+ breakdown .TotalDegen = breakdown .TotalDegen or {
3348+ rowList = { },
3349+ colList = {
3350+ { label = " Source" , key = " source" },
3351+ { label = " Base Type" , key = " type" },
3352+ { label = " Final Type" , key = " type2" },
3353+ { label = " Base" , key = " base" },
3354+ { label = " Taken As Percent" , key = " conv" },
3355+ { label = " Multiplier" , key = " mult" },
3356+ { label = " Total" , key = " total" },
3357+ }
3358+ }
3359+ t_insert (breakdown .TotalDegen .rowList , {
3360+ source = source ,
3361+ type = ailment .damageType ,
3362+ type2 = damageConvertedType ,
3363+ base = s_format (" %.1f" , baseVal ),
3364+ conv = s_format (" x %.2f%%" , convertPercent ),
3365+ mult = s_format (" x %.2f" , output [damageConvertedType .. " TakenDotMult" ]),
3366+ total = s_format (" %.1f" , total ),
3367+ })
3368+ breakdown [damageConvertedType .. " EnemyDegen" ] = breakdown [damageConvertedType .. " EnemyDegen" ] or {
3369+ rowList = { },
3370+ colList = {
3371+ { label = " Source" , key = " source" },
3372+ { label = " Base Type" , key = " type" },
3373+ { label = " Base" , key = " base" },
3374+ { label = " Taken As Percent" , key = " conv" },
3375+ { label = " Multiplier" , key = " mult" },
3376+ { label = " Total" , key = " total" },
3377+ }
3378+ }
3379+ t_insert (breakdown [damageConvertedType .. " EnemyDegen" ].rowList , {
3380+ source = source ,
3381+ type = ailment .damageType ,
3382+ base = s_format (" %.1f" , baseVal ),
3383+ conv = s_format (" x %.2f%%" , convertPercent ),
3384+ mult = s_format (" x %.2f" , output [damageConvertedType .. " TakenDotMult" ]),
3385+ total = s_format (" %.1f" , total ),
3386+ })
3387+ end
33033388 end
33043389 end
33053390 end
@@ -3379,18 +3464,30 @@ function calcs.buildDefenceEstimations(env, actor)
33793464 end
33803465 end
33813466 end
3382- output .ComprehensiveNetLifeRegen = output .ComprehensiveNetLifeRegen - totalLifeDegen
3383- output .ComprehensiveNetManaRegen = output .ComprehensiveNetManaRegen - totalManaDegen
3384- output .ComprehensiveNetEnergyShieldRegen = output .ComprehensiveNetEnergyShieldRegen - totalEnergyShieldDegen
3467+ output .ComprehensiveNetLifeRegen = output .ComprehensiveNetLifeRegen + ( output . LifeRecoupRecoveryAvg or 0 ) - totalLifeDegen - ( output . LifeLossLostAvg or 0 )
3468+ output .ComprehensiveNetManaRegen = output .ComprehensiveNetManaRegen + ( output . ManaRecoupRecoveryAvg or 0 ) - totalManaDegen
3469+ output .ComprehensiveNetEnergyShieldRegen = output .ComprehensiveNetEnergyShieldRegen + ( output . EnergyShieldRecoupRecoveryAvg or 0 ) - totalEnergyShieldDegen
33853470 output .ComprehensiveTotalNetRegen = output .ComprehensiveNetLifeRegen + output .ComprehensiveNetManaRegen + output .ComprehensiveNetEnergyShieldRegen
33863471 if breakdown then
33873472 t_insert (breakdown .ComprehensiveNetLifeRegen , s_format (" %.1f ^8(total life regen)" , output .LifeRegenRecovery ))
3473+ if (output .LifeRecoupRecoveryAvg or 0 ) ~= 0 then
3474+ t_insert (breakdown .ComprehensiveNetLifeRegen , s_format (" + %.1f ^8(average life recoup)" , (output .LifeRecoupRecoveryAvg or 0 )))
3475+ end
33883476 t_insert (breakdown .ComprehensiveNetLifeRegen , s_format (" - %.1f ^8(total life degen)" , totalLifeDegen ))
3477+ if (output .LifeLossLostAvg or 0 ) ~= 0 then
3478+ t_insert (breakdown .ComprehensiveNetLifeRegen , s_format (" - %.1f ^8(average life lost over time)" , (output .LifeLossLostAvg or 0 )))
3479+ end
33893480 t_insert (breakdown .ComprehensiveNetLifeRegen , s_format (" = %.1f" , output .ComprehensiveNetLifeRegen ))
33903481 t_insert (breakdown .ComprehensiveNetManaRegen , s_format (" %.1f ^8(total mana regen)" , output .ManaRegenRecovery ))
3482+ if (output .ManaRecoupRecoveryAvg or 0 ) ~= 0 then
3483+ t_insert (breakdown .ComprehensiveNetManaRegen , s_format (" + %.1f ^8(average mana recoup)" , (output .ManaRecoupRecoveryAvg or 0 )))
3484+ end
33913485 t_insert (breakdown .ComprehensiveNetManaRegen , s_format (" - %.1f ^8(total mana degen)" , totalManaDegen ))
33923486 t_insert (breakdown .ComprehensiveNetManaRegen , s_format (" = %.1f" , output .ComprehensiveNetManaRegen ))
33933487 t_insert (breakdown .ComprehensiveNetEnergyShieldRegen , s_format (" %.1f ^8(total energy shield regen)" , output .EnergyShieldRegenRecovery ))
3488+ if (output .EnergyShieldRecoupRecoveryAvg or 0 ) ~= 0 then
3489+ t_insert (breakdown .ComprehensiveNetEnergyShieldRegen , s_format (" + %.1f ^8(average energy shield recoup)" , (output .EnergyShieldRecoupRecoveryAvg or 0 )))
3490+ end
33943491 t_insert (breakdown .ComprehensiveNetEnergyShieldRegen , s_format (" - %.1f ^8(total energy shield degen)" , totalEnergyShieldDegen ))
33953492 t_insert (breakdown .ComprehensiveNetEnergyShieldRegen , s_format (" = %.1f" , output .ComprehensiveNetEnergyShieldRegen ))
33963493 breakdown .ComprehensiveTotalNetRegen = {
0 commit comments