Files
PathOfBuilding/spec/System/TestDefence_spec.lua
Dobromił Cepil 7787b72dba Add support for Shaper of Winter/Call of the Void damage taken mod (#8649)
* add support for 3.26 shaper of winter

* add unit tests for enemy damage lessened by chill effect
2025-06-13 11:42:15 +10:00

1180 lines
51 KiB
Lua

describe("TestDefence", function()
before_each(function()
newBuild()
end)
teardown(function()
-- newBuild() takes care of resetting everything in setup()
end)
-- a small helper function to calculate damage taken from limited test parameters
local function takenHitFromTypeMaxHit(type, enemyDamageMulti)
return build.calcsTab.calcs.takenHitFromDamage(build.calcsTab.calcsOutput[type.."MaximumHitTaken"] * (enemyDamageMulti or 1), type, build.calcsTab.calcsEnv.player)
end
local function poolsRemainingAfterTypeMaxHit(type, enemyDamageMulti)
local _, takenDamages = takenHitFromTypeMaxHit(type, enemyDamageMulti)
return build.calcsTab.calcs.reducePoolsByDamage(nil, takenDamages, build.calcsTab.calcsEnv.player)
end
-- boring part
it("no armour max hits", function()
build.configTab.input.enemyIsBoss = "None"
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(60, build.calcsTab.calcsOutput.PhysicalMaximumHitTaken)
assert.are.equals(38, build.calcsTab.calcsOutput.FireMaximumHitTaken)
assert.are.equals(38, build.calcsTab.calcsOutput.ColdMaximumHitTaken)
assert.are.equals(38, build.calcsTab.calcsOutput.LightningMaximumHitTaken)
assert.are.equals(38, build.calcsTab.calcsOutput.ChaosMaximumHitTaken)
build.configTab.input.customMods = "\z
+200 to all resistances\n\z
200% additional Physical Damage Reduction\n\z
"
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(600, build.calcsTab.calcsOutput.PhysicalMaximumHitTaken)
assert.are.equals(240, build.calcsTab.calcsOutput.FireMaximumHitTaken)
assert.are.equals(240, build.calcsTab.calcsOutput.ColdMaximumHitTaken)
assert.are.equals(240, build.calcsTab.calcsOutput.LightningMaximumHitTaken)
assert.are.equals(240, build.calcsTab.calcsOutput.ChaosMaximumHitTaken)
build.configTab.input.customMods = "\z
+200 to all resistances\n\z
+200 to all maximum resistances\n\z
200% additional Physical Damage Reduction\n\z
"
build.configTab.input.enemyPhysicalOverwhelm = 15 -- should result 75% DR
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(240, build.calcsTab.calcsOutput.PhysicalMaximumHitTaken)
assert.are.equals(600, build.calcsTab.calcsOutput.FireMaximumHitTaken)
assert.are.equals(600, build.calcsTab.calcsOutput.ColdMaximumHitTaken)
assert.are.equals(600, build.calcsTab.calcsOutput.LightningMaximumHitTaken)
assert.are.equals(600, build.calcsTab.calcsOutput.ChaosMaximumHitTaken)
build.configTab.input.customMods = "\z
+200 to all resistances\n\z
+200 to all maximum resistances\n\z
50% reduced damage taken\n\z
"
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(120, build.calcsTab.calcsOutput.PhysicalMaximumHitTaken)
assert.are.equals(1200, build.calcsTab.calcsOutput.FireMaximumHitTaken)
assert.are.equals(1200, build.calcsTab.calcsOutput.ColdMaximumHitTaken)
assert.are.equals(1200, build.calcsTab.calcsOutput.LightningMaximumHitTaken)
assert.are.equals(1200, build.calcsTab.calcsOutput.ChaosMaximumHitTaken)
build.configTab.input.customMods = "\z
+200 to all resistances\n\z
+200 to all maximum resistances\n\z
50% reduced damage taken\n\z
50% less damage taken\n\z
"
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(240, build.calcsTab.calcsOutput.PhysicalMaximumHitTaken)
assert.are.equals(2400, build.calcsTab.calcsOutput.FireMaximumHitTaken)
assert.are.equals(2400, build.calcsTab.calcsOutput.ColdMaximumHitTaken)
assert.are.equals(2400, build.calcsTab.calcsOutput.LightningMaximumHitTaken)
assert.are.equals(2400, build.calcsTab.calcsOutput.ChaosMaximumHitTaken)
build.configTab.input.customMods = "\z
+200 to all resistances\n\z
+200 to all maximum resistances\n\z
50% reduced damage taken\n\z
50% less damage taken\n\z
Nearby enemies deal 20% less damage\n\z
"
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(300, build.calcsTab.calcsOutput.PhysicalMaximumHitTaken)
assert.are.equals(3000, build.calcsTab.calcsOutput.FireMaximumHitTaken)
assert.are.equals(3000, build.calcsTab.calcsOutput.ColdMaximumHitTaken)
assert.are.equals(3000, build.calcsTab.calcsOutput.LightningMaximumHitTaken)
assert.are.equals(3000, build.calcsTab.calcsOutput.ChaosMaximumHitTaken)
local poolsRemaining = poolsRemainingAfterTypeMaxHit("Lightning", 0.8)
assert.are.equals(0, floor(poolsRemaining.Life))
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
build.configTab.input.customMods = "\z
+200 to all resistances\n\z
+200 to all maximum resistances\n\z
50% reduced damage taken\n\z
50% less damage taken\n\z
Nearby enemies deal 20% less damage\n\z
Gain 100% of life as extra maximum energy shield\n\z
intelligence provides no bonus to energy shield\n\z
"
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(600, build.calcsTab.calcsOutput.PhysicalMaximumHitTaken)
assert.are.equals(6000, build.calcsTab.calcsOutput.FireMaximumHitTaken)
assert.are.equals(6000, build.calcsTab.calcsOutput.ColdMaximumHitTaken)
assert.are.equals(6000, build.calcsTab.calcsOutput.LightningMaximumHitTaken)
assert.are.equals(3000, build.calcsTab.calcsOutput.ChaosMaximumHitTaken)
poolsRemaining = poolsRemainingAfterTypeMaxHit("Lightning", 0.8)
assert.are.equals(0, floor(poolsRemaining.EnergyShield))
assert.are.equals(0, floor(poolsRemaining.Life))
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
end)
-- a small helper function to calculate damage taken from limited test parameters
local function takenHitFromTypeMaxHit(type, enemyDamageMulti)
return build.calcsTab.calcs.takenHitFromDamage(build.calcsTab.calcsOutput[type.."MaximumHitTaken"] * (enemyDamageMulti or 1), type, build.calcsTab.calcsEnv.player)
end
it("progenesis and petrified blood", function()
build.configTab.input.enemyIsBoss = "None"
-- Petrified blood
build.skillsTab:PasteSocketGroup("\z
Petrified Blood 20/0 Default 1\n\z
Arrogance 21/0 Default 1\n\z
") -- 50% petrified effect, when exactly half of the life is reserved, should make the life pool be equivalent to no petrified effect and full life.
build.skillsTab:ProcessSocketGroup(build.skillsTab.socketGroupList[1])
build.configTab.input.customMods = "\z
+200 to all resistances\n\z
+200 to all maximum resistances\n\z
50% reduced damage taken\n\z
50% less damage taken\n\z
Nearby enemies deal 20% less damage\n\z
40% increased reservation efficiency\n\z
25% increased effect of buffs on you\n\z
"
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(300, build.calcsTab.calcsOutput.PhysicalMaximumHitTaken)
assert.are.equals(3000, build.calcsTab.calcsOutput.FireMaximumHitTaken)
assert.are.equals(3000, build.calcsTab.calcsOutput.ColdMaximumHitTaken)
assert.are.equals(3000, build.calcsTab.calcsOutput.LightningMaximumHitTaken)
assert.are.equals(3000, build.calcsTab.calcsOutput.ChaosMaximumHitTaken)
build.skillsTab.socketGroupList = {}
build.skillsTab:PasteSocketGroup("\z
Petrified Blood 20/0 Default 1\n\z
Arrogance 21/0 Default 1\n\z
")
build.skillsTab:ProcessSocketGroup(build.skillsTab.socketGroupList[1])
build.configTab.input.customMods = "\z
+200 to all resistances\n\z
+200 to all maximum resistances\n\z
50% reduced damage taken\n\z
50% less damage taken\n\z
Nearby enemies deal 20% less damage\n\z
100% less intelligence\n\z
+60 to maximum energy shield\n\z
40% increased reservation efficiency\n\z
25% increased effect of buffs on you\n\z
" -- petrified blood should not interact with pools other than life.
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(600, build.calcsTab.calcsOutput.PhysicalMaximumHitTaken)
assert.are.equals(6000, build.calcsTab.calcsOutput.FireMaximumHitTaken)
assert.are.equals(6000, build.calcsTab.calcsOutput.ColdMaximumHitTaken)
assert.are.equals(6000, build.calcsTab.calcsOutput.LightningMaximumHitTaken)
assert.are.equals(3000, build.calcsTab.calcsOutput.ChaosMaximumHitTaken)
build.skillsTab.socketGroupList = {}
build.skillsTab:PasteSocketGroup("\z
Petrified Blood 20/0 Default 1\n\z
") -- 80% petrified effect, starting from full life, should make the life pool be equivalent to 0.5 * life (unprotected upper half) and then 5 * 0.5 * life (protected lower half), making it 3* bigger in total
build.skillsTab:ProcessSocketGroup(build.skillsTab.socketGroupList[1])
build.configTab.input.customMods = "\z
+200 to all resistances\n\z
+200 to all maximum resistances\n\z
50% reduced damage taken\n\z
50% less damage taken\n\z
Nearby enemies deal 20% less damage\n\z
100% increased effect of buffs on you\n\z
"
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(900, build.calcsTab.calcsOutput.PhysicalMaximumHitTaken)
assert.are.equals(9000, build.calcsTab.calcsOutput.FireMaximumHitTaken)
assert.are.equals(9000, build.calcsTab.calcsOutput.ColdMaximumHitTaken)
assert.are.equals(9000, build.calcsTab.calcsOutput.LightningMaximumHitTaken)
assert.are.equals(9000, build.calcsTab.calcsOutput.ChaosMaximumHitTaken)
build.skillsTab.socketGroupList = {}
-- Progenesis
build.configTab.input.customMods = "\z
+200 to all resistances\n\z
+200 to all maximum resistances\n\z
50% reduced damage taken\n\z
50% less damage taken\n\z
Nearby enemies deal 20% less damage\n\z
When Hit during effect, 50% of Life loss from Damage taken occurs over 4 seconds instead\n\z
" -- 50% progenesis should just simply double the life pool
build.configTab.input.conditionUsingFlask = true
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(600, build.calcsTab.calcsOutput.PhysicalMaximumHitTaken)
assert.are.equals(6000, build.calcsTab.calcsOutput.FireMaximumHitTaken)
assert.are.equals(6000, build.calcsTab.calcsOutput.ColdMaximumHitTaken)
assert.are.equals(6000, build.calcsTab.calcsOutput.LightningMaximumHitTaken)
assert.are.equals(6000, build.calcsTab.calcsOutput.ChaosMaximumHitTaken)
build.configTab.input.customMods = "\z
+200 to all resistances\n\z
+200 to all maximum resistances\n\z
50% reduced damage taken\n\z
50% less damage taken\n\z
Nearby enemies deal 20% less damage\n\z
When Hit during effect, 50% of Life loss from Damage taken occurs over 4 seconds instead\n\z
100% less intelligence\n\z
+60 to maximum energy shield\n\z
" -- progenesis should not interact with pools other than life.
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(900, build.calcsTab.calcsOutput.PhysicalMaximumHitTaken)
assert.are.equals(9000, build.calcsTab.calcsOutput.FireMaximumHitTaken)
assert.are.equals(9000, build.calcsTab.calcsOutput.ColdMaximumHitTaken)
assert.are.equals(9000, build.calcsTab.calcsOutput.LightningMaximumHitTaken)
assert.are.equals(6000, build.calcsTab.calcsOutput.ChaosMaximumHitTaken)
-- Progenesis + petrified blood
build.skillsTab:PasteSocketGroup("\z
Petrified Blood 20/0 Default 1\n\z
Arrogance 21/0 Default 1\n\z
")
build.skillsTab:ProcessSocketGroup(build.skillsTab.socketGroupList[1])
build.configTab.input.customMods = "\z
+200 to all resistances\n\z
+200 to all maximum resistances\n\z
50% reduced damage taken\n\z
50% less damage taken\n\z
Nearby enemies deal 20% less damage\n\z
When Hit during effect, 50% of Life loss from Damage taken occurs over 4 seconds instead\n\z
40% increased reservation efficiency\n\z
25% increased effect of buffs on you\n\z
" -- With half of life reserved, both effects are active and multiplicative with each other, making the effective life pool 4 * half life = 2 * life (or same as no petrified, no reserve and 50% progenesis)
build.configTab.input.conditionUsingFlask = true
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(600, build.calcsTab.calcsOutput.PhysicalMaximumHitTaken)
assert.are.equals(6000, build.calcsTab.calcsOutput.FireMaximumHitTaken)
assert.are.equals(6000, build.calcsTab.calcsOutput.ColdMaximumHitTaken)
assert.are.equals(6000, build.calcsTab.calcsOutput.LightningMaximumHitTaken)
assert.are.equals(6000, build.calcsTab.calcsOutput.ChaosMaximumHitTaken)
build.skillsTab.socketGroupList = {}
build.skillsTab:PasteSocketGroup("\z
Petrified Blood 20/0 Default 1\n\z
")
build.skillsTab:ProcessSocketGroup(build.skillsTab.socketGroupList[1])
build.configTab.input.customMods = "\z
+200 to all resistances\n\z
+200 to all maximum resistances\n\z
50% reduced damage taken\n\z
50% less damage taken\n\z
Nearby enemies deal 20% less damage\n\z
When Hit during effect, 50% of Life loss from Damage taken occurs over 4 seconds instead\n\z
25% increased effect of buffs on you\n\z
" -- With no life reserved, progenesis first doubles the pool of life above low, then both progenesis and petrified quadruple the pool of life below low, so effective pool is 3 * life
build.configTab.input.conditionUsingFlask = true
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(900, build.calcsTab.calcsOutput.PhysicalMaximumHitTaken)
assert.are.equals(9000, build.calcsTab.calcsOutput.FireMaximumHitTaken)
assert.are.equals(9000, build.calcsTab.calcsOutput.ColdMaximumHitTaken)
assert.are.equals(9000, build.calcsTab.calcsOutput.LightningMaximumHitTaken)
assert.are.equals(9000, build.calcsTab.calcsOutput.ChaosMaximumHitTaken)
build.skillsTab.socketGroupList = {}
build.skillsTab:PasteSocketGroup("\z
Petrified Blood 20/0 Default 1\n\z
")
build.skillsTab:ProcessSocketGroup(build.skillsTab.socketGroupList[1])
build.configTab.input.customMods = "\z
+200 to all resistances\n\z
+200 to all maximum resistances\n\z
50% reduced damage taken\n\z
50% less damage taken\n\z
Nearby enemies deal 20% less damage\n\z
When Hit during effect, 60% of Life loss from Damage taken occurs over 4 seconds instead\n\z
100% less intelligence\n\z
+60 to maximum energy shield\n\z
" -- wonkier numbers to test the pool reduction function
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(1300, build.calcsTab.calcsOutput.PhysicalMaximumHitTaken)
assert.are.equals(13000, build.calcsTab.calcsOutput.FireMaximumHitTaken)
assert.are.equals(13000, build.calcsTab.calcsOutput.ColdMaximumHitTaken)
assert.are.equals(13000, build.calcsTab.calcsOutput.LightningMaximumHitTaken)
assert.are.equals(10000, build.calcsTab.calcsOutput.ChaosMaximumHitTaken)
local _, takenDamages = takenHitFromTypeMaxHit("Fire", 0.8)
local poolsRemaining = build.calcsTab.calcs.reducePoolsByDamage(nil, takenDamages, build.calcsTab.calcsEnv.player)
assert.are.equals(0, poolsRemaining.EnergyShield)
assert.are.equals(0, poolsRemaining.Life)
assert.are.equals(120, poolsRemaining.LifeLossLostOverTime)
assert.are.equals(20, poolsRemaining.LifeBelowHalfLossLostOverTime)
build.skillsTab:PasteSocketGroup("\z
Petrified Blood 20/0 Default 1\n\z
")
build.skillsTab:ProcessSocketGroup(build.skillsTab.socketGroupList[1])
build.configTab.input.customMods = "\z
+1950 to life\n\z
+2960 to mana\n\z
+3000 to energy shield\n\z
100% less attributes\n\z
100% less mana reserved\n\z
+60% to all resistances\n\z
chaos damage does not bypass energy shield\n\z
mind over matter\n\z
eldritch battery\n\z
10% of lightning damage is taken from mana before life\n\z
chaos damage is taken from mana before life\n\z
When Hit during effect, 50% of Life loss from Damage taken occurs over 4 seconds instead\n\z
25% increased effect of buffs on you\n\z
"
build.configTab.input.conditionUsingFlask = true
build.configTab:BuildModList()
runCallback("OnFrame")
_, takenDamages = takenHitFromTypeMaxHit("Fire")
poolsRemaining = build.calcsTab.calcs.reducePoolsByDamage(nil, takenDamages, build.calcsTab.calcsEnv.player)
assert.are.equals(0, poolsRemaining.Life)
assert.are.equals(0, poolsRemaining.EnergyShield)
assert.is.not_false(poolsRemaining.Mana > 0)
_, takenDamages = takenHitFromTypeMaxHit("Lightning")
poolsRemaining = build.calcsTab.calcs.reducePoolsByDamage(nil, takenDamages, build.calcsTab.calcsEnv.player)
assert.are.equals(0, poolsRemaining.Life)
assert.are.equals(0, poolsRemaining.EnergyShield)
assert.are.equals(0, poolsRemaining.Mana)
_, takenDamages = takenHitFromTypeMaxHit("Chaos")
poolsRemaining = build.calcsTab.calcs.reducePoolsByDamage(nil, takenDamages, build.calcsTab.calcsEnv.player)
assert.are.equals(0, poolsRemaining.Life)
assert.are.equals(0, poolsRemaining.EnergyShield)
assert.are.equals(0, poolsRemaining.Mana)
build.skillsTab.socketGroupList = {}
end)
-- fun part
it("armoured max hits", function()
build.configTab.input.enemyIsBoss = "None"
build.configTab.input.customMods = "\z
+940 to maximum life\n\z
+10000 to armour\n\z
" -- hit of 2000 on 10000 armour results in 50% DR which reduces the damage to 1000 - total HP
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(1000, takenHitFromTypeMaxHit("Physical"))
assert.are.equals(625, build.calcsTab.calcsOutput.FireMaximumHitTaken)
assert.are.equals(625, build.calcsTab.calcsOutput.ColdMaximumHitTaken)
assert.are.equals(625, build.calcsTab.calcsOutput.LightningMaximumHitTaken)
assert.are.equals(625, build.calcsTab.calcsOutput.ChaosMaximumHitTaken)
build.configTab.input.customMods = "\z
+940 to maximum life\n\z
+100000 to armour\n\z
" -- hit of 5000 on 100000 armour results in 80% DR which reduces the damage to 1000 - total HP
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(1000, takenHitFromTypeMaxHit("Physical"))
assert.are.equals(625, build.calcsTab.calcsOutput.FireMaximumHitTaken)
assert.are.equals(625, build.calcsTab.calcsOutput.ColdMaximumHitTaken)
assert.are.equals(625, build.calcsTab.calcsOutput.LightningMaximumHitTaken)
assert.are.equals(625, build.calcsTab.calcsOutput.ChaosMaximumHitTaken)
build.configTab.input.customMods = "\z
+940 to maximum life\n\z
+1000000000 to armour\n\z
" -- 90% DR cap
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(1000, takenHitFromTypeMaxHit("Physical"))
assert.are.equals(625, build.calcsTab.calcsOutput.FireMaximumHitTaken)
assert.are.equals(625, build.calcsTab.calcsOutput.ColdMaximumHitTaken)
assert.are.equals(625, build.calcsTab.calcsOutput.LightningMaximumHitTaken)
assert.are.equals(625, build.calcsTab.calcsOutput.ChaosMaximumHitTaken)
build.configTab.input.customMods = "\z
+940 to maximum life\n\z
+1000000000 to armour\n\z
" -- 90% DR cap
build.configTab.input.enemyPhysicalOverwhelm = 15 -- should result 75% DR
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(1000, takenHitFromTypeMaxHit("Physical"))
assert.are.equals(625, build.calcsTab.calcsOutput.FireMaximumHitTaken)
assert.are.equals(625, build.calcsTab.calcsOutput.ColdMaximumHitTaken)
assert.are.equals(625, build.calcsTab.calcsOutput.LightningMaximumHitTaken)
assert.are.equals(625, build.calcsTab.calcsOutput.ChaosMaximumHitTaken)
build.configTab.input.customMods = "\z
+940 to maximum life\n\z
+10000 to armour\n\z
+60% to all elemental resistances\n\z
Armour applies to Fire, Cold and Lightning Damage taken from Hits instead of Physical Damage\n\z
" -- with no resistances results should be same as physical
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(1000, build.calcsTab.calcsOutput.PhysicalMaximumHitTaken)
assert.are.equals(1000, takenHitFromTypeMaxHit("Fire"))
assert.are.equals(1000, takenHitFromTypeMaxHit("Cold"))
assert.are.equals(1000, takenHitFromTypeMaxHit("Lightning"))
assert.are.equals(625, build.calcsTab.calcsOutput.ChaosMaximumHitTaken)
build.configTab.input.customMods = "\z
+940 to maximum life\n\z
+10000 to armour\n\z
+110% to all elemental resistances\n\z
Armour applies to Fire, Cold and Lightning Damage taken from Hits instead of Physical Damage\n\z
" -- max hit should be 4000
-- [max] [res] [armour] [armour] [max] [res]
-- 4000 * 0.5 * (1 - 10000 / (10000 + 5 * 4000 * 0.5)) = 1000
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(1000, build.calcsTab.calcsOutput.PhysicalMaximumHitTaken)
assert.are.equals(1000, takenHitFromTypeMaxHit("Fire"))
assert.are.equals(1000, takenHitFromTypeMaxHit("Cold"))
assert.are.equals(1000, takenHitFromTypeMaxHit("Lightning"))
assert.are.equals(625, build.calcsTab.calcsOutput.ChaosMaximumHitTaken)
build.configTab.input.customMods = "\z
+940 to maximum life\n\z
+10000 to armour\n\z
+110% to all elemental resistances\n\z
Armour applies to Fire, Cold and Lightning Damage taken from Hits instead of Physical Damage\n\z
50% less damage taken\n\z
" -- max hit should be 6472
-- [max] [res] [armour] [armour] [max] [res] [less]
-- 6472 * 0.5 * (1 - 10000 / (10000 + 5 * 6472 * 0.5)) * 0.5 = 1000
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(2000, build.calcsTab.calcsOutput.PhysicalMaximumHitTaken)
assert.are.equals(1000, takenHitFromTypeMaxHit("Fire"))
assert.are.equals(1000, takenHitFromTypeMaxHit("Cold"))
assert.are.equals(1000, takenHitFromTypeMaxHit("Lightning"))
assert.are.equals(1250, build.calcsTab.calcsOutput.ChaosMaximumHitTaken)
end)
describe("Energy shield increased by spell block chance", function()
it("energy shield increased by spell block chance if corresponding 'maximum es' flag is present", function()
build.configTab.input.enemyIsBoss = "None"
build.configTab.input.customMods = "\z
You have no intelligence\n\z
100 Energy shield \n\z
maximum energy shield is increased by chance to block spell damage\n\z
50% chance to block spell damage\n\z
"
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(0, build.calcsTab.calcsOutput.SpellBlockChanceOverCap )
assert.are.equals(50, build.calcsTab.calcsOutput.SpellBlockChance)
assert.are.equals(150, build.calcsTab.calcsOutput.EnergyShield)
end)
it("energy shield increased by spell block chance if corresponding 'maximum es' flag is present should be capped to max block", function()
build.configTab.input.enemyIsBoss = "None"
build.configTab.input.customMods = "\z
You have no intelligence\n\z
100 Energy shield \n\z
maximum energy shield is increased by chance to block spell damage\n\z
100% chance to block spell damage\n\z
"
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(25, build.calcsTab.calcsOutput.SpellBlockChanceOverCap )
assert.are.equals(75, build.calcsTab.calcsOutput.SpellBlockChance)
assert.are.equals(175, build.calcsTab.calcsOutput.EnergyShield)
end)
end)
describe("enemy damage lessened by half of chill effect", function ()
it("enemy damage lessened by half of chill effect if the corresponding conditions are fulfilled", function()
build.configTab.input.enemyIsBoss = "None"
build.configTab.input.conditionEnemyChilled = true
-- default max chill effect
build.configTab.input.conditionEnemyChilledEffect = 30
build.configTab.input.customMods = "\z
enemies chilled by your hits lessen their damage dealt by half of chill effect\n\z
"
build.configTab:BuildModList()
runCallback("OnFrame")
-- 15% less since it's half of current chill effect
assert.are.equals(0.85, build.calcsTab.calcsOutput.PhysicalEnemyDamageMult)
assert.are.equals(0.85, build.calcsTab.calcsOutput.LightningEnemyDamageMult)
assert.are.equals(0.85, build.calcsTab.calcsOutput.ColdEnemyDamageMult)
assert.are.equals(0.85, build.calcsTab.calcsOutput.FireEnemyDamageMult)
assert.are.equals(0.85, build.calcsTab.calcsOutput.ChaosEnemyDamageMult)
end)
it("enemy damage is not lessened if the enemy is not chilled", function()
build.configTab.input.enemyIsBoss = "None"
build.configTab.input.customMods = "\z
enemies chilled by your hits lessen their damage dealt by half of chill effect\n\z
"
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(1, build.calcsTab.calcsOutput.PhysicalEnemyDamageMult)
assert.are.equals(1, build.calcsTab.calcsOutput.LightningEnemyDamageMult)
assert.are.equals(1, build.calcsTab.calcsOutput.ColdEnemyDamageMult)
assert.are.equals(1, build.calcsTab.calcsOutput.FireEnemyDamageMult)
assert.are.equals(1, build.calcsTab.calcsOutput.ChaosEnemyDamageMult)
end)
it("lessened enemy damage respects chill cap", function()
build.configTab.input.enemyIsBoss = "None"
build.configTab.input.conditionEnemyChilled = true
-- default max chill effect is 30%, so this shouldn't affect the resulting enemy damage multiplier beyond the cap
build.configTab.input.conditionEnemyChilledEffect = 100
build.configTab.input.customMods = "\z
enemies chilled by your hits lessen their damage dealt by half of chill effect\n\z
"
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(0.85, build.calcsTab.calcsOutput.PhysicalEnemyDamageMult)
assert.are.equals(0.85, build.calcsTab.calcsOutput.LightningEnemyDamageMult)
assert.are.equals(0.85, build.calcsTab.calcsOutput.ColdEnemyDamageMult)
assert.are.equals(0.85, build.calcsTab.calcsOutput.FireEnemyDamageMult)
assert.are.equals(0.85, build.calcsTab.calcsOutput.ChaosEnemyDamageMult)
end)
end)
local function withinTenPercent(value, otherValue)
local ratio = otherValue / value
return 0.9 < ratio and ratio < 1.1
end
it("damage conversion max hits", function()
build.configTab.input.enemyIsBoss = "None"
build.configTab.input.customMods = "\z
+940 to maximum life\n\z
+200 to all resistances\n\z
+200 to all maximum resistances\n\z
50% reduced damage taken\n\z
50% less damage taken\n\z
50% of physical damage taken as fire\n\z
"
build.configTab:BuildModList()
runCallback("OnFrame")
assert.is.not_false(withinTenPercent(1000, takenHitFromTypeMaxHit("Physical")))
build.configTab.input.customMods = "\z
+940 to maximum life\n\z
+200 to all resistances\n\z
+200 to all maximum resistances\n\z
50% reduced damage taken\n\z
50% less damage taken\n\z
50% of physical damage taken as fire\n\z
50% of cold damage taken as fire\n\z
"
build.configTab:BuildModList()
runCallback("OnFrame")
assert.is.not_false(withinTenPercent(1000, takenHitFromTypeMaxHit("Physical")))
assert.is.not_false(withinTenPercent(1000, takenHitFromTypeMaxHit("Cold")))
build.configTab.input.customMods = "\z
+940 to maximum life\n\z
+10000 to armour\n\z
+110% to all elemental resistances\n\z
Armour applies to Fire, Cold and Lightning Damage taken from Hits instead of Physical Damage\n\z
50% of physical damage taken as fire\n\z
50% of cold damage taken as fire\n\z
"
build.configTab:BuildModList()
runCallback("OnFrame")
assert.is.not_false(withinTenPercent(1000, takenHitFromTypeMaxHit("Physical")))
assert.is.not_false(withinTenPercent(1000, takenHitFromTypeMaxHit("Cold")))
build.configTab.input.customMods = "\z
+940 to maximum life\n\z
+10000 to armour\n\z
+110% to all elemental resistances\n\z
Armour applies to Fire, Cold and Lightning Damage taken from Hits instead of Physical Damage\n\z
50% of physical damage taken as fire\n\z
50% of cold damage taken as fire\n\z
50% less fire damage taken\n\z
"
build.configTab:BuildModList()
runCallback("OnFrame")
assert.is.not_false(withinTenPercent(1000, takenHitFromTypeMaxHit("Physical")))
assert.is.not_false(withinTenPercent(1000, takenHitFromTypeMaxHit("Cold")))
build.configTab.input.customMods = "\z
+940 to maximum life\n\z
+10000 to armour\n\z
+110% to fire resistance\n\z
Armour applies to Fire, Cold and Lightning Damage taken from Hits instead of Physical Damage\n\z
100% of cold damage taken as fire\n\z
50% of lightning damage taken as fire\n\z
50% less fire damage taken\n\z
"
build.configTab:BuildModList()
runCallback("OnFrame")
assert.is.not_false(withinTenPercent(1000, takenHitFromTypeMaxHit("Physical")))
assert.is.not_false(withinTenPercent(1000, takenHitFromTypeMaxHit("Cold")))
build.configTab.input.customMods = "\z
+99 to energy shield\n\z
100% less attributes\n\z
+60% to all elemental resistances\n\z
25% of Elemental Damage from Hits taken as Chaos Damage\n\z
Chaos Inoculation\n\z
"
build.configTab:BuildModList()
runCallback("OnFrame")
local poolsRemaining = poolsRemainingAfterTypeMaxHit("Cold")
assert.are.equals(0, floor(poolsRemaining.Life))
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
end)
it("damage conversion to different size pools", function()
-- conversion into a smaller pool
build.configTab.input.customMods = "\z
+40 to maximum life\n\z
+950 to mana\n\z
+10000 to armour\n\z
+110% to all elemental resistances\n\z
Armour applies to Fire, Cold and Lightning Damage taken from Hits instead of Physical Damage\n\z
100% of Lightning Damage is taken from Mana before Life\n\z
10% of lightning damage taken as cold damage\n\z
" -- Small amount of conversion into a smaller pool leads to the higher pool damage type (lightning) draining it's own excess pool (mana), and then joining back on the shared pools (life)
build.configTab:BuildModList()
runCallback("OnFrame")
local poolsRemaining = poolsRemainingAfterTypeMaxHit("Lightning")
assert.are.equals(0, floor(poolsRemaining.Mana))
assert.are.equals(0, floor(poolsRemaining.Life))
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
build.configTab.input.customMods = "\z
+40 to maximum life\n\z
+950 to mana\n\z
+10000 to armour\n\z
+110% to all elemental resistances\n\z
Armour applies to Fire, Cold and Lightning Damage taken from Hits instead of Physical Damage\n\z
100% of Lightning Damage is taken from Mana before Life\n\z
20% of lightning damage taken as cold damage\n\z
" -- This is a case where cold damage drains the whole life pool and lightning damage drains the entire mana pool, leaving nothing
build.configTab:BuildModList()
runCallback("OnFrame")
poolsRemaining = poolsRemainingAfterTypeMaxHit("Lightning")
assert.are.equals(0, floor(poolsRemaining.Mana))
assert.are.equals(0, floor(poolsRemaining.Life))
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
build.configTab.input.customMods = "\z
+40 to maximum life\n\z
+1950 to mana\n\z
+10000 to armour\n\z
+110% to all elemental resistances\n\z
Armour applies to Fire, Cold and Lightning Damage taken from Hits instead of Physical Damage\n\z
100% of Lightning Damage is taken from Mana before Life\n\z
20% of lightning damage taken as cold damage\n\z
" -- Any extra mana in this case will not help and be left over after death, since life hits 0 from the cold damage alone
build.configTab:BuildModList()
runCallback("OnFrame")
poolsRemaining = poolsRemainingAfterTypeMaxHit("Lightning")
assert.are.equals(1000, round(poolsRemaining.Mana))
assert.are.equals(0, floor(poolsRemaining.Life))
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
-- conversion into a bigger pool
build.configTab.input.customMods = "\z
+40 to maximum life\n\z
+950 to mana\n\z
+10000 to armour\n\z
+110% to all elemental resistances\n\z
Armour applies to Fire, Cold and Lightning Damage taken from Hits instead of Physical Damage\n\z
100% of Lightning Damage is taken from Mana before Life\n\z
90% of cold damage taken as lightning damage\n\z
" -- With inverted conversion amounts the behaviour of converting into a bigger pool should be exactly the same as converting into a lower one.
build.configTab:BuildModList()
runCallback("OnFrame")
poolsRemaining = poolsRemainingAfterTypeMaxHit("Cold")
assert.are.equals(0, floor(poolsRemaining.Mana))
assert.are.equals(0, floor(poolsRemaining.Life))
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
build.configTab.input.customMods = "\z
+40 to maximum life\n\z
+950 to mana\n\z
+10000 to armour\n\z
+110% to all elemental resistances\n\z
Armour applies to Fire, Cold and Lightning Damage taken from Hits instead of Physical Damage\n\z
100% of Lightning Damage is taken from Mana before Life\n\z
80% of cold damage taken as lightning damage\n\z
"
build.configTab:BuildModList()
runCallback("OnFrame")
poolsRemaining = poolsRemainingAfterTypeMaxHit("Cold")
assert.are.equals(0, floor(poolsRemaining.Mana))
assert.are.equals(0, floor(poolsRemaining.Life))
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
build.configTab.input.customMods = "\z
+40 to maximum life\n\z
+1950 to mana\n\z
+10000 to armour\n\z
+110% to all elemental resistances\n\z
Armour applies to Fire, Cold and Lightning Damage taken from Hits instead of Physical Damage\n\z
100% of Lightning Damage is taken from Mana before Life\n\z
80% of cold damage taken as lightning damage\n\z
"
build.configTab:BuildModList()
runCallback("OnFrame")
poolsRemaining = poolsRemainingAfterTypeMaxHit("Cold")
assert.are.equals(1000, round(poolsRemaining.Mana))
assert.are.equals(0, floor(poolsRemaining.Life))
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
build.configTab.input.customMods = "\z
+940 to maximum life\n\z
+950 to mana\n\z
+1000 to energy shield\n\z
+10000 to armour\n\z
+110% to all elemental resistances\n\z
Armour applies to Fire, Cold and Lightning Damage taken from Hits instead of Physical Damage\n\z
100% of Lightning Damage is taken from Mana before Life\n\z
80% of cold damage taken as lightning damage\n\z
50% of fire damage taken as chaos damage\n\z
"
build.configTab:BuildModList()
runCallback("OnFrame")
poolsRemaining = poolsRemainingAfterTypeMaxHit("Cold")
assert.are.equals(0, floor(poolsRemaining.EnergyShield))
assert.are.equals(0, floor(poolsRemaining.Mana))
assert.are.equals(0, floor(poolsRemaining.Life))
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
poolsRemaining = poolsRemainingAfterTypeMaxHit("Fire")
assert.are.not_false(0 < floor(poolsRemaining.EnergyShield))
assert.are.equals(1000, floor(poolsRemaining.Mana))
assert.are.not_false(1 >= floor(poolsRemaining.Life))
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
end)
it("energy shield bypass tests #pet", function()
build.configTab.input.enemyIsBoss = "None"
-- Mastery
build.configTab.input.customMods = [[
+40 to maximum life
+200 to energy shield
50% of chaos damage taken does not bypass energy shield
You have no intelligence
+60% to all resistances
]]
build.configTab:BuildModList()
runCallback("OnFrame")
local poolsRemaining = poolsRemainingAfterTypeMaxHit("Chaos")
assert.are.equals(100, round(poolsRemaining.EnergyShield))
assert.are.equals(0, floor(poolsRemaining.Life))
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
assert.are.equals(300, build.calcsTab.calcsOutput.FireMaximumHitTaken)
assert.are.equals(200, build.calcsTab.calcsOutput.ChaosMaximumHitTaken)
-- Negative overrides positive
build.configTab.input.customMods = [[
+40 to maximum life
+100 to energy shield
physical damage taken bypasses energy shield
Chaos damage does not bypass energy shield
You have no intelligence
+60% to all resistances
]]
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(100, build.calcsTab.calcsOutput.PhysicalMaximumHitTaken)
assert.are.equals(200, build.calcsTab.calcsOutput.FireMaximumHitTaken)
assert.are.equals(200, build.calcsTab.calcsOutput.ChaosMaximumHitTaken)
poolsRemaining = poolsRemainingAfterTypeMaxHit("Physical")
assert.are.equals(100, floor(poolsRemaining.EnergyShield))
assert.are.equals(0, floor(poolsRemaining.Life))
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
poolsRemaining = poolsRemainingAfterTypeMaxHit("Chaos")
assert.are.equals(0, floor(poolsRemaining.EnergyShield))
assert.are.equals(0, floor(poolsRemaining.Life))
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
-- Chaos damage should still bypass
build.configTab.input.customMods = build.configTab.input.customMods .. "\nAll damage taken bypasses energy shield"
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(100, build.calcsTab.calcsOutput.PhysicalMaximumHitTaken)
assert.are.equals(100, build.calcsTab.calcsOutput.FireMaximumHitTaken)
assert.are.equals(100, build.calcsTab.calcsOutput.ChaosMaximumHitTaken)
-- Make sure we can't reach over 100% bypass
build.configTab.input.customMods = [[
+40 to maximum life
+100 to energy shield
Chaos damage does not bypass energy shield
50% of chaos damage taken does not bypass energy shield
You have no intelligence
+60% to all resistances
]]
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(200, build.calcsTab.calcsOutput.FireMaximumHitTaken)
assert.are.equals(200, build.calcsTab.calcsOutput.ChaosMaximumHitTaken)
-- Chaos damage should still bypass
build.configTab.input.customMods = build.configTab.input.customMods .. "\nAll damage taken bypasses energy shield"
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(100, build.calcsTab.calcsOutput.FireMaximumHitTaken)
assert.are.equals(100, build.calcsTab.calcsOutput.ChaosMaximumHitTaken)
poolsRemaining = poolsRemainingAfterTypeMaxHit("Physical")
assert.are.equals(100, floor(poolsRemaining.EnergyShield))
assert.are.equals(0, floor(poolsRemaining.Life))
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
poolsRemaining = poolsRemainingAfterTypeMaxHit("Chaos")
assert.are.equals(100, round(poolsRemaining.EnergyShield))
assert.are.equals(0, floor(poolsRemaining.Life))
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
-- Bypass + MoM
build.configTab.input.customMods = [[
+40 to maximum life
+50 to mana
+200 to energy shield
50% of non-chaos damage taken bypasses energy shield
50% of chaos damage taken does not bypass energy shield
50% of Lightning Damage is taken from Mana before Life
intelligence provides no bonus to energy shield
+60% to all resistances
]]
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(400, build.calcsTab.calcsOutput.LightningMaximumHitTaken)
assert.are.equals(200, build.calcsTab.calcsOutput.FireMaximumHitTaken)
assert.are.equals(200, build.calcsTab.calcsOutput.ChaosMaximumHitTaken)
poolsRemaining = poolsRemainingAfterTypeMaxHit("Chaos")
assert.are.equals(100, round(poolsRemaining.EnergyShield))
assert.are.equals(0, floor(poolsRemaining.Life))
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
poolsRemaining = poolsRemainingAfterTypeMaxHit("Fire")
assert.are.equals(100, round(poolsRemaining.EnergyShield))
assert.are.equals(0, floor(poolsRemaining.Life))
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
poolsRemaining = poolsRemainingAfterTypeMaxHit("Lightning")
assert.are.equals(0, round(poolsRemaining.EnergyShield))
assert.are.equals(0, floor(poolsRemaining.Mana))
assert.are.equals(0, floor(poolsRemaining.Life))
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
build.configTab.input.customMods = [[
+40 to maximum life
+150 to mana
+300 to energy shield
50% of non-chaos damage taken bypasses energy shield
50% of chaos damage taken does not bypass energy shield
50% of Lightning Damage is taken from Mana before Life
intelligence provides no bonus to energy shield
+60% to all resistances
]]
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(400, build.calcsTab.calcsOutput.LightningMaximumHitTaken)
assert.are.equals(200, build.calcsTab.calcsOutput.FireMaximumHitTaken)
assert.are.equals(200, build.calcsTab.calcsOutput.ChaosMaximumHitTaken)
poolsRemaining = poolsRemainingAfterTypeMaxHit("Chaos")
assert.are.equals(200, round(poolsRemaining.EnergyShield))
assert.are.equals(0, floor(poolsRemaining.Life))
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
poolsRemaining = poolsRemainingAfterTypeMaxHit("Fire")
assert.are.equals(200, round(poolsRemaining.EnergyShield))
assert.are.equals(0, floor(poolsRemaining.Life))
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
poolsRemaining = poolsRemainingAfterTypeMaxHit("Lightning")
assert.are.equals(100, round(poolsRemaining.EnergyShield))
assert.are.equals(100, floor(poolsRemaining.Mana))
assert.are.equals(0, floor(poolsRemaining.Life))
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
end)
it("Unbreakable + Iron Reflexes", function()
build.configTab.input.customMods = [[
you have no dexterity
]]
build.configTab:BuildModList()
runCallback("OnFrame")
-- Get the base to make this test more adaptable to changes
local baseArmour = build.calcsTab.mainOutput.Armour
local baseEvasion = build.calcsTab.mainOutput.Evasion
build.configTab.input.customMods = [[
Converts all Evasion Rating to Armour. Dexterity provides no bonus to Evasion Rating
you have no dexterity
]]
build.itemsTab:CreateDisplayItemFromRaw([[
New Item
Shabby Jerkin
Quality: 20
]])
build.itemsTab:AddDisplayItem()
build.configTab:BuildModList()
runCallback("OnFrame")
-- Get the base + Shabby Jerkin to make this test more adaptable to changes
local ironReflexesArmour = build.calcsTab.mainOutput.Armour - baseArmour - baseEvasion
print("build.calcsTab.mainOutput.Armour:" .. build.calcsTab.mainOutput.Armour)
build.configTab.input.customMods = [[
Armour from Equipped Body Armour is doubled
Converts all Evasion Rating to Armour. Dexterity provides no bonus to Evasion Rating
you have no dexterity
]]
build.configTab:BuildModList()
runCallback("OnFrame")
-- Evasion from Body Armour is converted to Armour before being doubled
assert.are.equals(2*ironReflexesArmour + baseArmour + baseEvasion, build.calcsTab.mainOutput.Armour)
build.configTab.input.customMods = [[
Armour from Equipped Body Armour is doubled
Converts all Evasion Rating to Armour. Dexterity provides no bonus to Evasion Rating
Gain no armour from equipped body armour
you have no dexterity
]]
build.configTab:BuildModList()
runCallback("OnFrame")
-- Only the base armour from the chest is affected.
-- Armour converted with Iron Reflexes still applies
assert.are.equals(2*ironReflexesArmour + baseArmour + baseEvasion, build.calcsTab.mainOutput.Armour)
build.configTab.input.customMods = [[
Armour from Equipped Body Armour is doubled
Converts all Evasion Rating to Armour. Dexterity provides no bonus to Evasion Rating
Gain no armour from equipped body armour
defences from equipped body armour are doubled if it has no socketed gems
you have no dexterity
]]
build.configTab:BuildModList()
runCallback("OnFrame")
-- Oath Of Maji double defences stack with Unbreakable
assert.are.equals(2*2*ironReflexesArmour + baseArmour + baseEvasion, build.calcsTab.mainOutput.Armour)
build.configTab.input.customMods = [[
Armour from Equipped Body Armour is doubled
Armour from Equipped Body Armour is doubled
Converts all Evasion Rating to Armour. Dexterity provides no bonus to Evasion Rating
Gain no armour from equipped body armour
defences from equipped body armour are doubled if it has no socketed gems
you have no dexterity
]]
build.configTab:BuildModList()
runCallback("OnFrame")
-- Mod form unbreakable should apply only once
assert.are.equals(2*2*ironReflexesArmour + baseArmour + baseEvasion, build.calcsTab.mainOutput.Armour)
build.configTab.input.customMods = [[
Armour from Equipped Body Armour is doubled
Armour from Equipped Body Armour is doubled
Converts all Evasion Rating to Armour. Dexterity provides no bonus to Evasion Rating
Gain no armour from equipped body armour
defences from equipped body armour are doubled if it has no socketed gems
defences from equipped body armour are doubled if it has no socketed gems
you have no dexterity
]]
build.configTab:BuildModList()
runCallback("OnFrame")
-- Oath Of Maji should apply only once
assert.are.equals(2*2*ironReflexesArmour + baseArmour + baseEvasion, build.calcsTab.mainOutput.Armour)
end)
it("MoM + EB", function()
build.configTab.input.enemyIsBoss = "None"
-- enough mana and es, 0% and 100% bypass
build.configTab.input.customMods = [[
50% of damage is taken from mana before life
energy shield protects mana instead of life
+40 to maximum life
+1960 to mana
+2000 to energy shield
You have no intelligence
+60% to all resistances
]]
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(200, build.calcsTab.calcsOutput.FireMaximumHitTaken)
assert.are.equals(200, build.calcsTab.calcsOutput.ChaosMaximumHitTaken)
local poolsRemaining = poolsRemainingAfterTypeMaxHit("Chaos")
assert.are.equals(2000, round(poolsRemaining.EnergyShield))
assert.are.equals(1900, round(poolsRemaining.Mana))
assert.are.equals(0, floor(poolsRemaining.Life))
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
poolsRemaining = poolsRemainingAfterTypeMaxHit("Fire")
assert.are.equals(1900, round(poolsRemaining.EnergyShield))
assert.are.equals(2000, round(poolsRemaining.Mana))
assert.are.equals(0, floor(poolsRemaining.Life))
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
-- enough mana and es, 50% bypass
build.configTab.input.customMods = [[
50% of damage is taken from mana before life
energy shield protects mana instead of life
50% of non-chaos damage taken bypasses energy shield
+40 to maximum life
+1960 to mana
+2000 to energy shield
You have no intelligence
+60% to all resistances
]]
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(200, build.calcsTab.calcsOutput.FireMaximumHitTaken)
poolsRemaining = poolsRemainingAfterTypeMaxHit("Fire")
assert.are.equals(1950, round(poolsRemaining.EnergyShield))
assert.are.equals(1950, round(poolsRemaining.Mana))
assert.are.equals(0, floor(poolsRemaining.Life))
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
-- es bottleneck, 0% and 100% bypass
build.configTab.input.customMods = [[
50% of damage is taken from mana before life
energy shield protects mana instead of life
+40 to maximum life
+1960 to mana
+50 to energy shield
You have no intelligence
+60% to all resistances
]]
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(200, build.calcsTab.calcsOutput.FireMaximumHitTaken)
assert.are.equals(200, build.calcsTab.calcsOutput.ChaosMaximumHitTaken)
poolsRemaining = poolsRemainingAfterTypeMaxHit("Chaos")
assert.are.equals(50, round(poolsRemaining.EnergyShield))
assert.are.equals(1900, round(poolsRemaining.Mana))
assert.are.equals(0, floor(poolsRemaining.Life))
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
poolsRemaining = poolsRemainingAfterTypeMaxHit("Fire")
assert.are.equals(0, round(poolsRemaining.EnergyShield))
assert.are.equals(1950, round(poolsRemaining.Mana))
assert.are.equals(0, floor(poolsRemaining.Life))
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
-- es bottleneck, 50% bypass
build.configTab.input.customMods = [[
50% of damage is taken from mana before life
energy shield protects mana instead of life
50% of non-chaos damage taken bypasses energy shield
+40 to maximum life
+1960 to mana
+40 to energy shield
You have no intelligence
+60% to all resistances
]]
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(200, build.calcsTab.calcsOutput.FireMaximumHitTaken)
poolsRemaining = poolsRemainingAfterTypeMaxHit("Fire")
assert.are.equals(0, round(poolsRemaining.EnergyShield))
assert.are.equals(1940, round(poolsRemaining.Mana))
assert.are.equals(0, floor(poolsRemaining.Life))
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
-- mana bottleneck, 0% and 100% bypass
build.configTab.input.customMods = [[
50% of damage is taken from mana before life
energy shield protects mana instead of life
+40 to maximum life
+2000 to energy shield
You have no intelligence
+60% to all resistances
]]
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(200, build.calcsTab.calcsOutput.FireMaximumHitTaken)
assert.are.equals(140, build.calcsTab.calcsOutput.ChaosMaximumHitTaken)
poolsRemaining = poolsRemainingAfterTypeMaxHit("Chaos")
assert.are.equals(2000, round(poolsRemaining.EnergyShield))
assert.are.equals(0, round(poolsRemaining.Mana))
assert.are.equals(0, floor(poolsRemaining.Life))
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
poolsRemaining = poolsRemainingAfterTypeMaxHit("Fire")
assert.are.equals(1900, round(poolsRemaining.EnergyShield))
assert.are.equals(40, round(poolsRemaining.Mana))
assert.are.equals(0, floor(poolsRemaining.Life))
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
-- mana bottleneck, 50% bypass
-- taking 160 damage in this scenario:
-- 160 damage is split to 80 damage straight to life, 80 damage to MoM pools
-- 50% of the 80 MoM pool damage is taken by ES and 50% bypasses
-- pool of 20 mana takes 40 damage, gets depleted and the remaining damage continues on to life, for a total of 100 damage to life
build.configTab.input.customMods = [[
50% of damage is taken from mana before life
energy shield protects mana instead of life
50% of non-chaos damage taken bypasses energy shield
+40 to maximum life
-20 to mana
+2000 to energy shield
You have no intelligence
+60% to all resistances
]]
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(160, build.calcsTab.calcsOutput.FireMaximumHitTaken)
poolsRemaining = poolsRemainingAfterTypeMaxHit("Fire")
assert.are.equals(1960, round(poolsRemaining.EnergyShield))
assert.are.equals(0, round(poolsRemaining.Mana))
assert.are.equals(0, floor(poolsRemaining.Life))
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
-- mana+es bottleneck, 0% and 100% bypass
build.configTab.input.customMods = [[
50% of damage is taken from mana before life
energy shield protects mana instead of life
+940 to maximum life
+50 to energy shield
You have no intelligence
+60% to all resistances
]]
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(1090, build.calcsTab.calcsOutput.FireMaximumHitTaken)
assert.are.equals(1040, build.calcsTab.calcsOutput.ChaosMaximumHitTaken)
poolsRemaining = poolsRemainingAfterTypeMaxHit("Chaos")
assert.are.equals(50, round(poolsRemaining.EnergyShield))
assert.are.equals(0, round(poolsRemaining.Mana))
assert.are.equals(0, floor(poolsRemaining.Life))
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
poolsRemaining = poolsRemainingAfterTypeMaxHit("Fire")
assert.are.equals(0, round(poolsRemaining.EnergyShield))
assert.are.equals(0, round(poolsRemaining.Mana))
assert.are.equals(0, floor(poolsRemaining.Life))
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
-- mana+es bottleneck, 50% bypass
build.configTab.input.customMods = [[
50% of damage is taken from mana before life
energy shield protects mana instead of life
50% of non-chaos damage taken bypasses energy shield
+940 to maximum life
+50 to energy shield
You have no intelligence
+60% to all resistances
]]
build.configTab:BuildModList()
runCallback("OnFrame")
assert.are.equals(1090, build.calcsTab.calcsOutput.FireMaximumHitTaken)
poolsRemaining = poolsRemainingAfterTypeMaxHit("Fire")
assert.are.equals(0, round(poolsRemaining.EnergyShield))
assert.are.equals(0, round(poolsRemaining.Mana))
assert.are.equals(0, floor(poolsRemaining.Life))
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
end)
end)