@@ -36,12 +36,12 @@ function calcs.hitChance(evasion, accuracy, uncapped)
3636 return uncapped and m_max (round (rawChance ), 5 ) or m_max (m_min (round (rawChance ), 100 ), 5 )
3737end
3838-- Calculate Deflect chance
39- function calcs .deflectChance (evasion , accuracy , uncapped )
40- if accuracy < 0 then
41- return 5
39+ function calcs .deflectChance (deflection , accuracy )
40+ if deflection < 1 then
41+ return 0
4242 end
43- local rawChance = ( accuracy * 0.9 ) / ( accuracy + evasion * 0.2 ) * 100
44- return uncapped and m_max ( round ( rawChance ), 0 ) or m_max (m_min (round (rawChance ), 100 ), 0 )
43+ local rawChance = ( accuracy * 0.9 ) / ( accuracy + deflection * 0.2 ) * 100
44+ return 100 - m_max (m_min (round (rawChance ), 100 ), 0 )
4545end
4646-- Calculate damage reduction from armour, float
4747function calcs .armourReductionF (armour , raw )
336336-- Based on code from FR and BS found in act_*.txt
337337--- @param activeSkill /output /breakdown references table passed in from calc offence
338338--- @param sourceType string type of incoming damage - it will be converted (taken as ) from this type if applicable
339- --- @param baseDmg for which to calculate the damage
339+ --- @param baseDmg string for which to calculate the damage
340340--- @return table of taken damage parts , and number , sum of damages
341341function calcs .applyDmgTakenConversion (activeSkill , output , breakdown , sourceType , baseDmg )
342342 local damageBreakdown = { }
@@ -1361,6 +1361,13 @@ function calcs.defence(env, actor)
13611361 output .EnergyShieldRecoveryCap = output .EnergyShield or 0
13621362 end
13631363
1364+ local enemyAccuracy = round (calcLib .val (enemyDB , " Accuracy" ))
1365+ if modDB :Flag (nil , " EnemyAccuracyDistancePenalty" ) then
1366+ local enemyDistance = m_max (m_min (modDB :Sum (" BASE" , nil , " Multiplier:enemyDistance" ), 120 ), 20 )
1367+ local accuracyPenalty = 1 - ((enemyDistance - 20 ) / 100 ) * (1 - 0.1 )
1368+ enemyAccuracy = m_floor (enemyAccuracy * accuracyPenalty )
1369+ end
1370+
13641371 if modDB :Flag (nil , " CannotEvade" ) or enemyDB :Flag (nil , " CannotBeEvaded" ) then
13651372 output .EvadeChance = 0
13661373 output .MeleeEvadeChance = 0
@@ -1374,12 +1381,6 @@ function calcs.defence(env, actor)
13741381 output .SpellEvadeChance = 100
13751382 output .SpellProjectileEvadeChance = 100
13761383 else
1377- local enemyAccuracy = round (calcLib .val (enemyDB , " Accuracy" ))
1378- if modDB :Flag (nil , " EnemyAccuracyDistancePenalty" ) then
1379- local enemyDistance = m_max (m_min (modDB :Sum (" BASE" , nil , " Multiplier:enemyDistance" ), 120 ), 20 )
1380- local accuracyPenalty = 1 - ((enemyDistance - 20 ) / 100 ) * (1 - 0.1 )
1381- enemyAccuracy = m_floor (enemyAccuracy * accuracyPenalty )
1382- end
13831384 local evadeChance = modDB :Sum (" BASE" , nil , " EvadeChance" )
13841385 local hitChance = calcLib .mod (enemyDB , nil , " HitChance" )
13851386 local evadeMax = modDB :Max (nil , " EvadeChanceMax" ) or data .misc .EvadeChanceCap
@@ -1435,6 +1436,21 @@ function calcs.defence(env, actor)
14351436 }
14361437 end
14371438 end
1439+
1440+ output .DeflectionRating = (output .Evasion * modDB :Sum (" BASE" , nil , " EvasionGainAsDeflection" ) / 100 + output .Armour * modDB :Sum (" BASE" , nil , " ArmourGainAsDeflection" ) / 100 ) * calcLib .mod (modDB , nil , " DeflectionRating" )
1441+ output .DeflectChance = calcs .deflectChance (output .DeflectionRating , enemyAccuracy )
1442+ if modDB :Flag (nil , " DeflectIsLucky" ) then
1443+ local notDeflect = 1 - output .DeflectChance / 100
1444+ output .DeflectChance = (1 - notDeflect * notDeflect ) * 100
1445+ end
1446+ output .DeflectEffect = m_min (m_max (data .misc .DeflectEffect + modDB :Sum (" BASE" , nil , " DeflectEffect" ), 0 ), 100 )
1447+ if breakdown then
1448+ breakdown .DeflectChance = {
1449+ s_format (" Enemy level: %d ^8(%s the Configuration tab)" , env .enemyLevel , env .configInput .enemyLevel and " overridden from" or " can be overridden in" ),
1450+ s_format (" Average enemy accuracy: %d" , enemyAccuracy ),
1451+ s_format (" Approximate deflect chance: %d%%" , output .DeflectChance ),
1452+ }
1453+ end
14381454 end
14391455
14401456 local spellSuppressionChance = modDB :Sum (" BASE" , nil , " SpellSuppressionChance" )
@@ -2352,15 +2368,16 @@ function calcs.buildDefenceEstimations(env, actor)
23522368 takenMult = (output [damageType .. " SpellTakenHitMult" ] + output [damageType .. " AttackTakenHitMult" ]) / 2
23532369 spellSuppressMult = output .EffectiveSpellSuppressionChance == 100 and (1 - output .SpellSuppressionEffect / 100 / 2 ) or 1
23542370 end
2371+ local deflectMulti = output .DeflectChance == 100 and (1 - output .DeflectEffect / 100 ) or 1
23552372 output [damageType .. " EffectiveAppliedArmour" ] = effectiveAppliedArmour
23562373 output [damageType .. " ResistTakenHitMulti" ] = resMult
2357- local afterReductionMulti = takenMult * spellSuppressMult
2374+ local afterReductionMulti = takenMult * spellSuppressMult * deflectMulti
23582375 output [damageType .. " AfterReductionTakenHitMulti" ] = afterReductionMulti
23592376 local baseMult = resMult * reductMult
23602377 output [damageType .. " BaseTakenHitMult" ] = baseMult * afterReductionMulti
23612378 local takenMultReflect = output [damageType .. " TakenReflect" ]
23622379 local finalReflect = baseMult * takenMultReflect
2363- output [damageType .. " TakenHit" ] = m_max (damage * baseMult + takenFlat , 0 ) * takenMult * spellSuppressMult + impaleDamage
2380+ output [damageType .. " TakenHit" ] = m_max (damage * baseMult + takenFlat , 0 ) * afterReductionMulti + impaleDamage
23642381 output [damageType .. " TakenHitMult" ] = (damage > 0 ) and (output [damageType .. " TakenHit" ] / damage ) or 0
23652382 output [" totalTakenHit" ] = output [" totalTakenHit" ] + output [damageType .. " TakenHit" ]
23662383 if output .AnyTakenReflect then
@@ -2420,10 +2437,13 @@ function calcs.buildDefenceEstimations(env, actor)
24202437 if spellSuppressMult ~= 1 then
24212438 t_insert (breakdown [damageType .. " TakenHitMult" ], s_format (" x Spell Suppression: %.3f" , spellSuppressMult ))
24222439 end
2440+ if deflectMulti ~= 1 then
2441+ t_insert (breakdown [damageType .. " TakenHitMult" ], s_format (" x Deflection: %.3f" , deflectMulti ))
2442+ end
24232443 if impaleDamage ~= 0 then
24242444 t_insert (breakdown [damageType .. " TakenHitMult" ], s_format (" + Impale: %.1f" , impaleDamage ))
24252445 end
2426- if takenMult ~= 1 or takenFlat ~= 0 or spellSuppressMult ~= 1 or impaleDamage ~= 0 then
2446+ if takenFlat ~= 0 or afterReductionMulti ~= 1 or impaleDamage ~= 0 then
24272447 t_insert (breakdown [damageType .. " TakenHitMult" ], s_format (" = %.3f" , output [damageType .. " TakenHitMult" ]))
24282448 end
24292449 if output .AnyTakenReflect then
@@ -3101,6 +3121,7 @@ function calcs.buildDefenceEstimations(env, actor)
31013121 DamageIn .EnergyShieldWhenHit = (DamageIn .EnergyShieldWhenHit or 0 ) + output .EnergyShieldOnSuppress * ( damageCategoryConfig == " Average" and 0.5 or 1 )
31023122 DamageIn .LifeWhenHit = (DamageIn .LifeWhenHit or 0 ) + output .LifeOnSuppress * ( damageCategoryConfig == " Average" and 0.5 or 1 )
31033123 end
3124+ local effectiveDeflectMulti = output .DeflectChance < 100 and 1 - output .DeflectChance * output .DeflectEffect / 10000 or 1
31043125 -- extra avoid chance
31053126 if damageCategoryConfig == " Projectile" or damageCategoryConfig == " SpellProjectile" then
31063127 ExtraAvoidChance = ExtraAvoidChance + output .AvoidProjectilesChance
@@ -3135,7 +3156,7 @@ function calcs.buildDefenceEstimations(env, actor)
31353156 end
31363157 averageAvoidChance = averageAvoidChance + AvoidChance
31373158 end
3138- DamageIn [damageType ] = output [damageType .. " TakenHit" ] * (blockEffect * suppressionEffect * (1 - AvoidChance / 100 ))
3159+ DamageIn [damageType ] = output [damageType .. " TakenHit" ] * (blockEffect * suppressionEffect * effectiveDeflectMulti * (1 - AvoidChance / 100 ))
31393160 end
31403161 -- recoup initialisation
31413162 if output [" anyRecoup" ] > 0 then
@@ -3151,7 +3172,7 @@ function calcs.buildDefenceEstimations(env, actor)
31513172 output [" LifeBelowHalfLossLostOverTime" ] = 0
31523173 end
31533174 averageAvoidChance = averageAvoidChance / 5
3154- output [" ConfiguredDamageChance" ] = 100 * (blockEffect * suppressionEffect * (1 - averageAvoidChance / 100 ))
3175+ output [" ConfiguredDamageChance" ] = 100 * (blockEffect * suppressionEffect * effectiveDeflectMulti * (1 - averageAvoidChance / 100 ))
31553176 output [" NumberOfMitigatedDamagingHits" ] = (output [" ConfiguredDamageChance" ] ~= 100 or DamageIn [" TrackRecoupable" ] or DamageIn [" TrackLifeLossOverTime" ] or DamageIn .GainWhenHit ) and numberOfHitsToDie (DamageIn ) or output [" NumberOfDamagingHits" ]
31563177 if breakdown then
31573178 breakdown [" ConfiguredDamageChance" ] = {
@@ -3163,6 +3184,9 @@ function calcs.buildDefenceEstimations(env, actor)
31633184 if suppressionEffect ~= 1 then
31643185 t_insert (breakdown [" ConfiguredDamageChance" ], s_format (" x %.3f ^8(suppression effect)" , suppressionEffect ))
31653186 end
3187+ if effectiveDeflectMulti ~= 1 then
3188+ t_insert (breakdown [" ConfiguredDamageChance" ], s_format (" x %.3f ^8(deflect effect)" , effectiveDeflectMulti ))
3189+ end
31663190 if averageAvoidChance > 0 then
31673191 t_insert (breakdown [" ConfiguredDamageChance" ], s_format (" x %.2f ^8(chance for avoidance to fail)" , 1 - averageAvoidChance / 100 ))
31683192 end
0 commit comments