Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions spec/System/TestDefence_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,49 @@ describe("TestDefence", function()
assert.are.equals(manaWithoutTotalEnergyShield + 100, player.output.Mana)
end)

it("scales conversion rates down proportionally when they total more than 100%", function()
-- 50% to Energy Shield plus 75% to Armour (with 75% Chaos Resistance) is 125%, so both scale by 100/125
build.configTab.input.customMods = "\z
50% of Maximum Life Converted to Energy Shield\n\z
Convert 1% of maximum Life to twice as much Armour per 1% Chaos Resistance above 0%\n\z
+75% to Chaos Resistance\n\z
"
build.configTab:BuildModList()
runCallback("OnFrame")

local lifeBase = build.calcsTab.mainEnv.player.modDB:Sum("BASE", nil, "Life")
local factor = 100 / 125
assert.are.equals(round(lifeBase * 50 * factor / 100), build.calcsTab.mainOutput.EnergyShield)
assert.are.equals(round(lifeBase * (75 * factor + 75) / 100), build.calcsTab.mainOutput.Armour)
end)

it("takes each conversion target's share from the unconverted slot base", function()
local function energyShieldBodyArmourWith(customMods)
newBuild()
build.itemsTab:CreateDisplayItemFromRaw([[
New Item
Tattered Robe
+100 to maximum Energy Shield
]])
build.itemsTab:AddDisplayItem()
build.configTab.input.customMods = customMods
build.configTab:BuildModList()
runCallback("OnFrame")
return build.calcsTab.mainOutput
end
local toMana = "Convert 40% of maximum Energy Shield to maximum Mana"
local asArmour = "Gain 20% of maximum Energy Shield as extra Armour"

local manaOnly = energyShieldBodyArmourWith(toMana)
local armourOnly = energyShieldBodyArmourWith(asArmour)
local both = energyShieldBodyArmourWith(toMana .. "\n" .. asArmour)

-- Gaining Armour from Energy Shield must not reduce the Energy Shield kept or the Mana converted
assert.are.equals(manaOnly.EnergyShield, both.EnergyShield)
assert.are.equals(manaOnly.Mana, both.Mana)
assert.are.equals(armourOnly.Armour, both.Armour)
end)

it("Geofri's Sanctuary mods work", function()
build.itemsTab:CreateDisplayItemFromRaw([[
Geofri's Sanctuary
Expand Down
7 changes: 5 additions & 2 deletions src/Modules/CalcDefence.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1372,7 +1372,7 @@ function calcs.defence(env, actor)
if totalConversion > 100 then
local factor = 100 / totalConversion
totalConversion = 100
for name, val in ipairs(source.conversionRate) do
for name, val in pairs(source.conversionRate) do
source.conversionRate[name] = val * factor
end
end
Expand Down Expand Up @@ -1410,7 +1410,6 @@ function calcs.defence(env, actor)
if breakdown then
breakdown.slot(slot, source.name .. " to " .. target.name .. " conversion", { slotName = slot }, targetBase, nil, unpack(target.mods))
end
source.basePerSlot[slot] = source.basePerSlot[slot] * (100 - source.totalConversion) / 100
end
end
local targetBase = globalBase * rate / 100
Expand All @@ -1437,6 +1436,10 @@ function calcs.defence(env, actor)
end
end
if source.defence then
-- Every target takes its share from the unconverted base, so reduce the source once, after all targets
for _, slot in pairs({ "Helmet", "Gloves", "Boots", "Body Armour", "Weapon 2", "Weapon 3" }) do
source.basePerSlot[slot] = source.basePerSlot[slot] * (100 - source.totalConversion) / 100
end
source.globalBase = globalBase * (100 - source.totalConversion) / 100
source.totalBase = totalBase * (100 - source.totalConversion) / 100
end
Expand Down