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
53 changes: 53 additions & 0 deletions spec/System/TestFlasks_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
describe("Flasks", function()
local function buildFlasks(rawFlasks, customMods)
newBuild()
build.configTab.input.customMods = customMods or ""
build.configTab:BuildModList()

for index, raw in ipairs(rawFlasks) do
local item = new("Item"):Item(raw)
build.itemsTab:AddItem(item, true)
local slot = build.itemsTab.slots["Flask " .. index]
slot:SetSelItemId(item.id)
slot.active = true
end
build.buildFlag = true
runCallback("OnFrame")
return build.calcsTab.mainOutput
end

local function buildLifeFlask(customMods)
return buildFlasks({ "Rarity: MAGIC\nTest Life Flask\nDivine Life Flask" },
"Life Flask Effects are not removed when Unreserved Life is Filled\n" .. (customMods or ""))
end

local function buildUtilityFlasks(customMods)
return buildFlasks({ "Rarity: NORMAL\nIron Flask", "Rarity: NORMAL\nGranite Flask" }, customMods)
end

it("applies Master Surgeon's recovery rate to active non-instant life flasks", function()
local baselineOutput = buildLifeFlask()
local reducedOutput = buildLifeFlask("50% less Flask Life Recovery rate")
assert.is_true(baselineOutput.LifeRecovery > 0)
assert.are.equal(baselineOutput.LifeRecovery / 2, reducedOutput.LifeRecovery)
end)

it("applies Regenerative Runes only to Iron Flasks", function()
local baseline = buildUtilityFlasks()
local increased = buildUtilityFlasks("20% increased Effect of Iron Flasks")

assert.is_true(baseline.Ward > 0)
assert.is_true(baseline.Armour > 0)
assert.are.equal(math.floor(baseline.Ward * 1.2), increased.Ward)
assert.are.equal(baseline.Armour, increased.Armour)
end)

it("adds Iron Flask effect to generic flask effect", function()
local generic = buildUtilityFlasks("30% increased Effect of Flasks")
local combined = buildUtilityFlasks("10% increased Effect of Flasks\n20% increased Effect of Iron Flasks")
local genericControl = buildUtilityFlasks("10% increased Effect of Flasks")

assert.are.equal(generic.Ward, combined.Ward)
assert.are.equal(genericControl.Armour, combined.Armour)
end)
end)
18 changes: 18 additions & 0 deletions spec/System/TestModParser_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
describe("TestModParser", function()
local function getMasterDistillerCritMultiplier(value, skillTypes, hasDiamondFlask)
local mods, extra = modLib.parseMod("If Diamond Flask Charges are consumed, +" .. value .. "% to Critical Strike Multiplier")
assert.is_nil(extra)
local modDB = new("ModDB"):ModDB()
modDB:AddList(mods)
modDB.conditions.HaveDiamondFlask = hasDiamondFlask
return modDB:Sum("BASE", { skillTypes = skillTypes }, "CritMultiplier")
end

it("applies the Master Distiller diamond flask bonus only to eligible skills while the flask is present", function()
assert.are.equal(100, getMasterDistillerCritMultiplier(100, {}, true))
assert.are.equal(60, getMasterDistillerCritMultiplier(60, {}, true))
assert.are.equal(0, getMasterDistillerCritMultiplier(100, {}, false))
assert.are.equal(0, getMasterDistillerCritMultiplier(100, { [SkillType.Triggered] = true }, true))
assert.are.equal(0, getMasterDistillerCritMultiplier(100, { [SkillType.Channel] = true }, true))
end)
end)
6 changes: 5 additions & 1 deletion src/Classes/ItemsTab.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4731,6 +4731,9 @@ function ItemsTabClass:AddItemStatDifferences(tooltip, item, base, slot)
local output = self.build.calcsTab.mainOutput
local durInc = modDB:Sum("INC", nil, "FlaskDuration")
local effectInc = modDB:Sum("INC", { actor = "player" }, "FlaskEffect")
if item.baseName == "Iron Flask" then
effectInc = effectInc + modDB:Sum("INC", { actor = "player" }, "IronFlaskEffect")
end
local lifeDur = 0
local manaDur = 0

Expand All @@ -4744,6 +4747,7 @@ function ItemsTabClass:AddItemStatDifferences(tooltip, item, base, slot)
local lifeInc = modDB:Sum("INC", nil, "FlaskLifeRecovery")
local lifeMore = modDB:More(nil, "FlaskLifeRecovery")
local lifeRateInc = modDB:Sum("INC", nil, "FlaskLifeRecoveryRate")
local lifeRateMore = modDB:More(nil, "FlaskLifeRecoveryRate")
local instantPerc = flaskData.instantPerc + modDB:Sum("BASE", nil, "LifeFlaskInstantRecovery")

-- More life recovery while on low life is not affected by flask effect (verified ingame).
Expand All @@ -4756,7 +4760,7 @@ function ItemsTabClass:AddItemStatDifferences(tooltip, item, base, slot)
local base = flaskData.lifeBase * (1 - instantPerc / 100) * (1 + lifeInc / 100) * lifeMore * (1 + effectInc / 100) * (1 + durInc / 100) * lowLifeMulti
local grad = base * output.LifeRecoveryRateMod
local esGrad = base * output.EnergyShieldRecoveryRateMod
lifeDur = flaskData.duration * (1 + durInc / 100) / (1 + rateInc / 100) / (1 + lifeRateInc / 100)
lifeDur = flaskData.duration * (1 + durInc / 100) / (1 + rateInc / 100) / (1 + lifeRateInc / 100) / lifeRateMore

-- LocalLifeFlaskAdditionalLifeRecovery flask mods
if flaskData.lifeAdditional > 0 and not self.build.configTab.input.conditionFullLife then
Expand Down
7 changes: 6 additions & 1 deletion src/Modules/CalcPerform.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1664,8 +1664,9 @@ function calcs.perform(env, skipEHP)
local flaskRecInc = modDB:Sum("INC", nil, "Flask"..type.."Recovery")
local flaskRecMore = modDB:More(nil, "Flask"..type.."Recovery")
local flaskRateInc = modDB:Sum("INC", nil, "Flask"..type.."RecoveryRate")
local flaskRateMore = modDB:More(nil, "Flask"..type.."RecoveryRate")
local flaskTotal = base * (1 - instPerc / 100) * (1 + flaskRecInc / 100) * flaskRecMore * (1 + flaskDurInc / 100)
local flaskDur = dur * (1 + flaskDurInc / 100) / (1 + flaskTotalRateInc / 100) / (1 + flaskRateInc / 100)
local flaskDur = dur * (1 + flaskDurInc / 100) / (1 + flaskTotalRateInc / 100) / (1 + flaskRateInc / 100) / flaskRateMore

-- More life recovery while on low life is not affected by flask effect (verified ingame).
-- Since this will be multiplied by the flask effect value below we have to counteract this by removing the flask effect from the value beforehand.
Expand Down Expand Up @@ -1701,6 +1702,10 @@ function calcs.perform(env, skipEHP)
local function calcFlaskMods(item, baseName, buffModList, modList, onlyMinion)
local flaskEffectInc = effectInc + item.flaskData.effectInc
local flaskEffectIncNonPlayer = effectIncNonPlayer + item.flaskData.effectInc
if item.baseName == "Iron Flask" then
flaskEffectInc = flaskEffectInc + modDB:Sum("INC", { actor = "player" }, "IronFlaskEffect")
flaskEffectIncNonPlayer = flaskEffectIncNonPlayer + modDB:Sum("INC", nil, "IronFlaskEffect")
end
if item.rarity == "MAGIC" and not (item.base.flask.life or item.base.flask.mana) then
flaskEffectInc = flaskEffectInc + effectIncMagic
flaskEffectIncNonPlayer = flaskEffectIncNonPlayer + effectIncMagicNonPlayer
Expand Down
1 change: 1 addition & 0 deletions src/Modules/CalcSections.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1798,6 +1798,7 @@ return {
{ label = "Inc. Recovery Rate", { format = "{0:mod:1,2}%",
{ label = "Life Flask Recovery Rate", modName = "FlaskLifeRecoveryRate", modType = "INC"},
{ label = "Generic Flask Recovery Rate", modName = "FlaskRecoveryRate", modType = "INC" }}, },
{ label = "More Recovery Rate", { format = "{0:mod:1}%", { modName = "FlaskLifeRecoveryRate", modType = "MORE" }}, },
{ label = "Charges/s", { format = "{2:output:LifeFlaskChargeGen}",
{ label = "Life Flask Charges/s", modName = "LifeFlaskChargesGenerated", modType = "BASE"},
{ label = "Generic Flask Charges/s", modName = { "FlaskChargesGenerated", "FlaskChargesGeneratedPerEmptyFlask" }, modType = "BASE" }}, },
Expand Down
4 changes: 4 additions & 0 deletions src/Modules/ModParser.lua
Original file line number Diff line number Diff line change
Expand Up @@ -857,6 +857,7 @@ local modNameList = {
-- Flask and Tincture modifiers
["effect"] = "LocalEffect",
["effect of flasks"] = "FlaskEffect",
["effect of iron flasks"] = "IronFlaskEffect",
["effect of tinctures"] = "TinctureEffect",
["amount recovered"] = "FlaskRecovery",
["life recovered"] = "FlaskRecovery",
Expand Down Expand Up @@ -2979,6 +2980,9 @@ local specialModList = {
["if diamond flask charges are consumed, (%d+)%% increased critical strike chance"] = function (num) return {
mod("CritChance", "INC", num, { type = "SkillType", skillType = SkillType.Triggered, neg = true }, { type = "SkillType", skillType = SkillType.Channel, neg = true }, { type = "Condition", var = "HaveDiamondFlask" })
} end,
["if diamond flask charges are consumed, %+(%d+)%% to critical strike multiplier"] = function (num) return {
mod("CritMultiplier", "BASE", num, { type = "SkillType", skillType = SkillType.Triggered, neg = true }, { type = "SkillType", skillType = SkillType.Channel, neg = true }, { type = "Condition", var = "HaveDiamondFlask" })
} end,
["if bismuth flask charges are consumed, penetrate (%d+)%% elemental resistances"] = function (num) return {
mod("ElementalPenetration", "BASE", num, { type = "SkillType", skillType = SkillType.Triggered, neg = true }, { type = "SkillType", skillType = SkillType.Channel, neg = true }, { type = "Condition", var = "HaveBismuthFlask" })
} end,
Expand Down
Loading