Skip to content

Commit d36be05

Browse files
unrealdreamzLocalIdentity
andauthored
Fix eHP value decreasing when allocating defence nodes (PathOfBuildingCommunity#1929)
* Fix stateful EHP block speedup * Stabilize regression fixtures and total price order * Regenerate ModCache * Strengthen regression coverage * Revert * Revert "Regenerate ModCache" This reverts commit 81ba442. * Revert wrong test * Change variable name * Simplify test * Add back block test * Fix Test --------- Co-authored-by: LocalIdentity <localidentity2@gmail.com>
1 parent 521d7f9 commit d36be05

2 files changed

Lines changed: 47 additions & 2 deletions

File tree

spec/System/TestDefence_spec.lua

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,7 @@ describe("TestDefence", function()
527527
assert.are.equals(0, floor(poolsRemaining.Life))
528528
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
529529
end)
530-
530+
531531
it("uses block chance against projectile spells", function()
532532
build.configTab.input.enemyIsBoss = "None"
533533
build.configTab.input.enemyDamageType = "SpellProjectile"
@@ -549,4 +549,44 @@ describe("TestDefence", function()
549549
assert.are.equals(15, build.calcsTab.calcsOutput.EffectiveAverageBlockChance)
550550
assert.are.equals(85, build.calcsTab.calcsOutput.ConfiguredDamageChance)
551551
end)
552+
553+
it("limits EHP speedup when hit damage is delayed", function()
554+
local function assertClose(actual, expected)
555+
assert.is_true(math.abs(actual - expected) < 0.01)
556+
end
557+
558+
local function calcEHP(extraMods)
559+
newBuild()
560+
build.configTab.input.enemyPhysicalDamage = "500"
561+
build.configTab.input.enemyFireDamage = "500"
562+
build.configTab.input.enemyColdDamage = "500"
563+
build.configTab.input.enemyLightningDamage = "500"
564+
build.configTab.input.enemyChaosDamage = "0"
565+
build.configTab.input.customMods = [[
566+
+4000 to maximum Life
567+
75% of Life Loss from Hits is prevented, then that much Life is lost over 4 seconds instead
568+
+75% to all Elemental Resistances
569+
+75% to Chaos Resistance
570+
]] .. (extraMods or "")
571+
pob1and2Compat()
572+
runCallback("OnFrame")
573+
runCallback("OnFrame")
574+
local calcsOutput = build.calcsTab.calcsOutput
575+
return {
576+
TotalEHP = calcsOutput.TotalEHP,
577+
EffectiveBlockChance = calcsOutput.EffectiveBlockChance,
578+
NumberOfMitigatedDamagingHits = calcsOutput.NumberOfMitigatedDamagingHits,
579+
}
580+
end
581+
582+
local base = calcEHP()
583+
local block = calcEHP("\n+10% to Block chance\n")
584+
585+
newBuild()
586+
587+
assertClose(base.TotalEHP, 17582.417582418)
588+
assertClose(block.TotalEHP, 19008.019008019)
589+
assertClose(block.EffectiveBlockChance, 10)
590+
assert.is_true(block.TotalEHP > base.TotalEHP)
591+
end)
552592
end)

src/Modules/CalcDefence.lua

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3078,13 +3078,16 @@ function calcs.buildDefenceEstimations(env, actor)
30783078
end
30793079
iterationMultiplier = 1
30803080
-- to speed it up, run recursively but accelerated
3081-
local speedUp = data.misc.ehpCalcSpeedUp
3081+
-- MoM/life-loss-prevention mechanics can collapse too many hits into one
3082+
-- resulting in eHP jumps so we slow the acceleration.
3083+
local speedUp = DamageIn["LimitEHPSpeedup"] and 4 or data.misc.ehpCalcSpeedUp
30823084
DamageIn["cyclesRan"] = DamageIn["cyclesRan"] or false
30833085
if not DamageIn["cyclesRan"] and poolTable.Life > 0 and DamageIn["iterations"] < maxIterations then
30843086
Damage = { }
30853087
for _, damageType in ipairs(dmgTypeList) do
30863088
Damage[damageType] = DamageIn[damageType] * speedUp
30873089
end
3090+
Damage["LimitEHPSpeedup"] = DamageIn["LimitEHPSpeedup"]
30883091
if DamageIn.GainWhenHit then
30893092
Damage.GainWhenHit = true
30903093
Damage.LifeWhenHit = DamageIn.LifeWhenHit
@@ -3136,6 +3139,7 @@ function calcs.buildDefenceEstimations(env, actor)
31363139
for _, damageType in ipairs(dmgTypeList) do
31373140
DamageIn[damageType] = output[damageType.."TakenHit"]
31383141
end
3142+
DamageIn["LimitEHPSpeedup"] = output["preventedLifeLossTotal"] > 0
31393143
output["NumberOfDamagingHits"] = numberOfHitsToDie(DamageIn)
31403144
end
31413145

@@ -3227,6 +3231,7 @@ function calcs.buildDefenceEstimations(env, actor)
32273231
output["LifeLossLostOverTime"] = 0
32283232
output["LifeBelowHalfLossLostOverTime"] = 0
32293233
end
3234+
DamageIn["LimitEHPSpeedup"] = DamageIn["TrackRecoupable"] or DamageIn["TrackLifeLossOverTime"] or DamageIn.GainWhenHit
32303235
averageAvoidChance = averageAvoidChance / 5
32313236
output["ConfiguredDamageChance"] = 100 * (blockEffect * suppressionEffect * effectiveDeflectMulti * (1 - averageAvoidChance / 100))
32323237
output["NumberOfMitigatedDamagingHits"] = (output["ConfiguredDamageChance"] ~= 100 or DamageIn["TrackRecoupable"] or DamageIn["TrackLifeLossOverTime"] or DamageIn.GainWhenHit) and numberOfHitsToDie(DamageIn) or output["NumberOfDamagingHits"]

0 commit comments

Comments
 (0)