@@ -287,8 +287,7 @@ function calcs.applyDmgTakenConversion(activeSkill, output, breakdown, sourceTyp
287287 local percentOfArmourApplies = m_min ((not activeSkill .skillModList :Flag (nil , " ArmourDoesNotApplyTo" .. damageType .. " DamageTaken" ) and activeSkill .skillModList :Sum (" BASE" , nil , " ArmourAppliesTo" .. damageType .. " DamageTaken" ) or 0 ), 100 )
288288 if percentOfArmourApplies > 0 then
289289 local effArmour = (output .Armour * percentOfArmourApplies / 100 ) * (1 + output .ArmourDefense )
290- local effDamage = damage * resMult
291- armourReduct = round (effArmour ~= 0 and damage * resMult ~= 0 and calcs .armourReductionF (effArmour , effDamage ) or 0 )
290+ armourReduct = round (effArmour ~= 0 and damage ~= 0 and calcs .armourReductionF (effArmour , damage ) or 0 )
292291 armourReduct = m_min (output .DamageReductionMax , armourReduct )
293292 end
294293 reductMult = (1 - m_max (m_min (output .DamageReductionMax , armourReduct + reduction ), 0 ) / 100 ) * damageTakenMods
@@ -321,13 +320,13 @@ function calcs.takenHitFromDamage(rawDamage, damageType, actor)
321320 local output = actor .output
322321 local modDB = actor .modDB
323322 local function damageMitigationMultiplierForType (damage , type )
324- local totalResistMult = output [type .. " ResistTakenHitMulti" ]
325323 local effectiveAppliedArmour = output [type .. " EffectiveAppliedArmour" ]
326- local armourDRPercent = calcs .armourReductionF (effectiveAppliedArmour , damage * totalResistMult )
324+ local armourDRPercent = calcs .armourReductionF (effectiveAppliedArmour , damage )
327325 local flatDRPercent = modDB :Flag (nil , " SelfIgnore" .. " Base" .. type .. " DamageReduction" ) and 0 or output [" Base" .. type .. " DamageReductionWhenHit" ] or output [" Base" .. type .. " DamageReduction" ]
328326 local totalDRPercent = m_min (output .DamageReductionMax , armourDRPercent + flatDRPercent )
329327 local enemyOverwhelmPercent = modDB :Flag (nil , " SelfIgnore" .. type .. " DamageReduction" ) and 0 or output [type .. " EnemyOverwhelm" ]
330328 local totalDRMulti = 1 - m_max (m_min (output .DamageReductionMax , totalDRPercent - enemyOverwhelmPercent ), 0 ) / 100
329+ local totalResistMult = output [type .. " ResistTakenHitMulti" ]
331330 return totalResistMult * totalDRMulti
332331 end
333332 local receivedDamageSum = 0
@@ -1983,10 +1982,10 @@ function calcs.buildDefenceEstimations(env, actor)
19831982 end
19841983 output [damageType .. " takenFlat" ] = takenFlat
19851984 if percentOfArmourApplies > 0 then
1986- armourReduct = calcs .armourReduction (effectiveAppliedArmour , damage * resMult )
1985+ armourReduct = calcs .armourReduction (effectiveAppliedArmour , damage )
19871986 armourReduct = m_min (output .DamageReductionMax , armourReduct )
19881987 if impaleDamage > 0 then
1989- impaleArmourReduct = m_min (output .DamageReductionMax , calcs .armourReduction (effectiveAppliedArmour , impaleDamage * resMult ))
1988+ impaleArmourReduct = m_min (output .DamageReductionMax , calcs .armourReduction (effectiveAppliedArmour , impaleDamage ))
19901989 end
19911990 end
19921991 local totalReduct = m_min (output .DamageReductionMax , armourReduct + reduction )
@@ -1999,15 +1998,15 @@ function calcs.buildDefenceEstimations(env, actor)
19991998 if breakdown then
20001999 breakdown [damageType .. " DamageReduction" ] = { }
20012000 if armourReduct ~= 0 then
2001+ if percentOfArmourApplies ~= 100 then
2002+ t_insert (breakdown [damageType .. " DamageReduction" ], s_format (" %d%% percent of armour applies" , percentOfArmourApplies ))
2003+ end
2004+ t_insert (breakdown [damageType .. " DamageReduction" ], s_format (" Reduction from Armour: %d%%" , armourReduct ))
20022005 if resMult ~= 1 then
20032006 t_insert (breakdown [damageType .. " DamageReduction" ], s_format (" Enemy Hit Damage After Resistance: %d ^8(total incoming damage)" , damage * resMult ))
20042007 else
20052008 t_insert (breakdown [damageType .. " DamageReduction" ], s_format (" Enemy Hit Damage: %d ^8(total incoming damage)" , damage ))
20062009 end
2007- if percentOfArmourApplies ~= 100 then
2008- t_insert (breakdown [damageType .. " DamageReduction" ], s_format (" %d%% percent of armour applies" , percentOfArmourApplies ))
2009- end
2010- t_insert (breakdown [damageType .. " DamageReduction" ], s_format (" Reduction from Armour: %d%%" , armourReduct ))
20112010 end
20122011 if reduction ~= 0 then
20132012 t_insert (breakdown [damageType .. " DamageReduction" ], s_format (" Base %s Damage Reduction: %d%%" , damageType , reduction ))
@@ -2046,24 +2045,10 @@ function calcs.buildDefenceEstimations(env, actor)
20462045 end
20472046 if breakdown then
20482047 breakdown [damageType .. " TakenHitMult" ] = { }
2049- if resist ~= 0 then
2050- t_insert (breakdown [damageType .. " TakenHitMult" ], s_format (" Resistance: %.2f" , 1 - resist / 100 ))
2051- end
2052- if enemyPen ~= 0 then
2053- t_insert (breakdown [damageType .. " TakenHitMult" ], s_format (" + Enemy Pen: %.2f" , enemyPen / 100 ))
2054- end
2055- if resist ~= 0 and enemyPen ~= 0 then
2056- t_insert (breakdown [damageType .. " TakenHitMult" ], s_format (" = %.2f" , resMult ))
2057- end
20582048 if reduction ~= 0 then
20592049 t_insert (breakdown [damageType .. " TakenHitMult" ], s_format (" Base %s Damage Reduction: %.2f" , damageType , 1 - reduction / 100 ))
20602050 end
20612051 if armourReduct ~= 0 then
2062- if resMult ~= 1 then
2063- t_insert (breakdown [damageType .. " TakenHitMult" ], s_format (" Enemy Hit Damage After Resistance: %d ^8(total incoming damage)" , damage * resMult ))
2064- else
2065- t_insert (breakdown [damageType .. " TakenHitMult" ], s_format (" Enemy Hit Damage: %d ^8(total incoming damage)" , damage ))
2066- end
20672052 if percentOfArmourApplies ~= 100 then
20682053 t_insert (breakdown [damageType .. " TakenHitMult" ], s_format (" %d%% percent of armour applies" , percentOfArmourApplies ))
20692054 end
@@ -2075,6 +2060,15 @@ function calcs.buildDefenceEstimations(env, actor)
20752060 if reduction ~= 0 or armourReduct ~= 0 or enemyOverwhelm ~= 0 then
20762061 t_insert (breakdown [damageType .. " TakenHitMult" ], s_format (" = %.2f" , reductMult ))
20772062 end
2063+ if resist ~= 0 then
2064+ t_insert (breakdown [damageType .. " TakenHitMult" ], s_format (" Resistance: %.2f" , 1 - resist / 100 ))
2065+ end
2066+ if enemyPen ~= 0 then
2067+ t_insert (breakdown [damageType .. " TakenHitMult" ], s_format (" + Enemy Pen: %.2f" , enemyPen / 100 ))
2068+ end
2069+ if resist ~= 0 and enemyPen ~= 0 then
2070+ t_insert (breakdown [damageType .. " TakenHitMult" ], s_format (" = %.2f" , resMult ))
2071+ end
20782072 if resMult ~= 1 and reductMult ~= 1 then
20792073 t_insert (breakdown [damageType .. " TakenHitMult" ], s_format (" %.2f x %.2f = %.3f" , resMult , reductMult , baseMult ))
20802074 end
@@ -3198,30 +3192,32 @@ function calcs.buildDefenceEstimations(env, actor)
31983192 local totalResistMult = output [damageConvertedType .. " ResistTakenHitMulti" ]
31993193
32003194 local reductionPercent = modDB :Flag (nil , " SelfIgnore" .. " Base" .. damageConvertedType .. " DamageReduction" ) and 0 or output [" Base" .. damageConvertedType .. " DamageReductionWhenHit" ] or output [" Base" .. damageConvertedType .. " DamageReduction" ]
3201- local flatDR = reductionPercent / 100
32023195 local enemyOverwhelmPercent = modDB :Flag (nil , " SelfIgnore" .. damageConvertedType .. " DamageReduction" ) and 0 or output [damageConvertedType .. " EnemyOverwhelm" ]
3196+ local flatDR = reductionPercent / 100
32033197
32043198 -- We know the damage and armour calculation chain. The important part for max hit calculations is:
3205- -- dmgAfterRes = RAW * DamageConvertedMulti * ResistanceMulti
3206- -- armourDR = AppliedArmour / (AppliedArmour + data.misc.ArmourRatio * dmgAfterRes)
3207- -- totalDR = max(min(armourDR + FlatDR, MaxReduction) - Overwhelm, 0) -- min and max is complicated to actually math out so skip caps first and tack it on later. Result should be close enough
3208- -- dmgReceived = dmgAfterRes * (1 - totalDR)
3209- -- damageTaken = (dmgReceived + takenFlat) * TakenMulti
3199+ -- armourDR = AppliedArmour / (AppliedArmour + data.misc.ArmourRatio * RAW * DamageConvertedMulti)
3200+ -- drMulti = 1 - max(min(armourDR + FlatDR, MaxReduction) - Overwhelm, 0) -- min and max is complicated to actually math out so skip caps first and tack it on later. Result should be close enough
3201+ -- dmgAfterRes = RAW * DamageConvertedMulti * drMulti * ResistanceMulti
3202+ -- damageTaken = (dmgAfterRes + takenFlat) * TakenMulti
32103203 -- If we consider damageTaken to be the total hit pool of the actor, we can go backwards in the chain until we find the max hit - the RAW damage.
32113204 -- Unfortunately the above is slightly simplified and is missing a line that *really* complicates stuff for exact calculations:
32123205 -- damageTaken = damageTakenAsPhys + damageTakenAsFire + damageTakenAsCold + damageTakenAsLightning + damageTakenAsChaos
32133206 -- Trying to solve that for RAW might require solving a polynomial equation of 6th degree, so this solution settles for solving the parts independently and then approximating the final result
32143207 --
32153208 -- To solve only one part the above can be expressed as this:
3216- -- data.misc.ArmourRatio * (1 - FlatDR + Overwhelm) * TakenMulti * ResistanceMulti * ResistanceMulti * DamageConvertedMulti * DamageConvertedMulti * RAW * RAW + ((Overwhelm - FlatDR) * AppliedArmour * TakenMulti
3217- -- - data.misc.ArmourRatio * (damageTaken - takenFlat * TakenMulti)) * ResistanceMulti * DamageConvertedMulti * RAW - (damageTaken - takenFlat * TakenMulti) * AppliedArmour = 0
3209+ -- RAW * RAW * data.misc.ArmourRatio * DamageConvertedMulti * (1 - FlatDR + Overwhelm)
3210+ -- + RAW * (AppliedArmour * (1 - FlatDR + Overwhelm) - AppliedArmour - (damageTaken / TakenMulti - takenFlat) / (DamageConvertedMulti * ResistanceMulti) * data.misc.ArmourRatio * DamageConvertedMulti)
3211+ -- - (damageTaken / TakenMulti - takenFlat) / (DamageConvertedMulti * ResistanceMulti) * AppliedArmour = 0
32183212 -- Which means that
32193213 -- RAW = [quadratic]
32203214
3221- local resistXConvert = totalResistMult * damageConvertedMulti
3222- local a = data .misc .ArmourRatio * (1 - flatDR + enemyOverwhelmPercent / 100 ) * totalTakenMulti * resistXConvert * resistXConvert
3223- local b = ((enemyOverwhelmPercent / 100 - flatDR ) * effectiveAppliedArmour * totalTakenMulti - data .misc .ArmourRatio * (totalHitPool - takenFlat * totalTakenMulti )) * resistXConvert
3224- local c = - effectiveAppliedArmour * (totalHitPool - takenFlat * totalTakenMulti )
3215+ local oneMinusFlatPlusOverwhelm = (1 + flatDR - enemyOverwhelmPercent / 100 )
3216+ local HP_tTM_tF_DCM_tRM = (totalHitPool / totalTakenMulti - takenFlat ) / (damageConvertedMulti * totalResistMult )
3217+
3218+ local a = data .misc .ArmourRatio * damageConvertedMulti * oneMinusFlatPlusOverwhelm
3219+ local b = (effectiveAppliedArmour * oneMinusFlatPlusOverwhelm - effectiveAppliedArmour - HP_tTM_tF_DCM_tRM * data .misc .ArmourRatio * damageConvertedMulti )
3220+ local c = - HP_tTM_tF_DCM_tRM * effectiveAppliedArmour
32253221
32263222 local RAW = (m_sqrt (b * b - 4 * a * c ) - b ) / (2 * a )
32273223
0 commit comments