Skip to content
Merged
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
48 changes: 48 additions & 0 deletions spec/System/TestItemTools_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
local applyRangeTests = {
-- Number without range
[{ "+10 to maximum Life", 1.0, 1.0 }] = "+10 to maximum Life",
[{ "+10 to maximum Life", 1.0, 1.5 }] = "+15 to maximum Life",
[{ "+10 to maximum Life", 0.5, 1.0 }] = "+10 to maximum Life",
[{ "+10 to maximum Life", 0.5, 1.5 }] = "+15 to maximum Life",
-- One range
[{ "+(10-20) to maximum Life", 1.0, 1.0 }] = "+20 to maximum Life",
[{ "+(10-20) to maximum Life", 1.0, 1.5 }] = "+30 to maximum Life",
[{ "+(10-20) to maximum Life", 0.5, 1.0 }] = "+15 to maximum Life",
[{ "+(10-20) to maximum Life", 0.5, 1.5 }] = "+22 to maximum Life",
-- Two ranges
[{ "Adds (60-80) to (270-300) Physical Damage", 1.0, 1.0 }] = "Adds 80 to 300 Physical Damage",
[{ "Adds (60-80) to (270-300) Physical Damage", 1.0, 1.5 }] = "Adds 120 to 450 Physical Damage",
[{ "Adds (60-80) to (270-300) Physical Damage", 0.5, 1.0 }] = "Adds 70 to 285 Physical Damage",
[{ "Adds (60-80) to (270-300) Physical Damage", 0.5, 1.5 }] = "Adds 105 to 427 Physical Damage",
-- Range with increased/reduced
[{ "(10--10)% increased Charges per use", 1.0, 1.0 }] = "10% reduced Charges per use",
[{ "(10--10)% increased Charges per use", 1.0, 1.5 }] = "15% reduced Charges per use",
[{ "(10--10)% increased Charges per use", 0.5, 1.0 }] = "0% increased Charges per use",
[{ "(10--10)% increased Charges per use", 0.5, 1.5 }] = "0% increased Charges per use",
[{ "(10--10)% increased Charges per use", 0.0, 1.0 }] = "10% increased Charges per use",
[{ "(10--10)% increased Charges per use", 0.0, 1.5 }] = "15% increased Charges per use",
-- Range with constant numbers after
[{ "(15-20)% increased Cold Damage per 1% Cold Resistance above 75%", 1.0, 1.0 }] = "20% increased Cold Damage per 1% Cold Resistance above 75%",
[{ "(15-20)% increased Cold Damage per 1% Cold Resistance above 75%", 1.0, 1.5 }] = "30% increased Cold Damage per 1% Cold Resistance above 75%",
[{ "(15-20)% increased Cold Damage per 1% Cold Resistance above 75%", 0.5, 1.0 }] = "18% increased Cold Damage per 1% Cold Resistance above 75%",
[{ "(15-20)% increased Cold Damage per 1% Cold Resistance above 75%", 0.5, 1.5 }] = "27% increased Cold Damage per 1% Cold Resistance above 75%",
-- High precision range
[{ "Regenerate (66.7-75) Life per second", 1.0, 1.0 }] = "Regenerate 75 Life per second",
[{ "Regenerate (66.7-75) Life per second", 1.0, 1.5 }] = "Regenerate 112.5 Life per second",
[{ "Regenerate (66.7-75) Life per second", 0.5, 1.0 }] = "Regenerate 70.9 Life per second",
[{ "Regenerate (66.7-75) Life per second", 0.5, 1.5 }] = "Regenerate 106.3 Life per second",
-- Range with plus sign that is removed when negative
[{ "+(-25-50)% to Fire Resistance", 1.0, 1.0 }] = "+50% to Fire Resistance",
[{ "+(-25-50)% to Fire Resistance", 1.0, 1.5 }] = "+75% to Fire Resistance",
[{ "+(-25-50)% to Fire Resistance", 0.0, 1.0 }] = "-25% to Fire Resistance",
[{ "+(-25-50)% to Fire Resistance", 0.0, 1.5 }] = "-37% to Fire Resistance",
}

describe("TestItemTools", function()
for args, expected in pairs(applyRangeTests) do
it(string.format("tests applyRange('%s', %.2f, %.2f)", unpack(args)), function()
local result = itemLib.applyRange(unpack(args))
assert.are.equals(expected, result)
end)
end
end)
6 changes: 3 additions & 3 deletions src/Data/Rares.lua
Original file line number Diff line number Diff line change
Expand Up @@ -563,9 +563,9 @@ Suffix: FireResist4
Suffix: ColdResist4
Suffix: LightningResist4
Implicits: 3
{variant:1}+(12 to 16)% to Fire and Cold Resistances
{variant:2}+(12 to 16)% to Cold and Lightning Resistances
{variant:3}+(12 to 16)% to Fire and Lightning Resistances
{variant:1}+(12-16)% to Fire and Cold Resistances
{variant:2}+(12-16)% to Cold and Lightning Resistances
{variant:3}+(12-16)% to Fire and Lightning Resistances
]],[[
Ring
Unset Ring
Expand Down
71 changes: 45 additions & 26 deletions src/Modules/ItemTools.lua
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,39 @@ function itemLib.getLineRangeMinMax(line)
return rangeMin, rangeMax
end

-- Apply range value (0 to 1) to a modifier that has a range: (x to x) or (x-x to x-x)
local antonyms = {
["increased"] = "reduced",
["reduced"] = "increased",
["more"] = "less",
["less"] = "more",
}

-- Apply range value (0 to 1) to a modifier that has a range: "(x-x)" or "(x-x) to (x-x)"
function itemLib.applyRange(line, range, valueScalar)
local numbers = 0
local precision = nil
local precisionSame = true
-- Create a line with ranges removed to check if the mod is a high precision mod.
local testLine = line:gsub("%((%d+)%-(%d+) to (%d+)%-(%d+)%)", "(%1-%2) to (%3-%4)")
:gsub("(%+?)%((%-?%d+) to (%d+)%)", "%1(%2-%3)")
:gsub("(%+?)%((%-?%d+%.?%d*)%-(%-?%d+%.?%d*)%)", function(plus, min, max) return plus.."1" end)
:gsub("%-(%d+%%) increased", function(num) return num.." reduced" end)
:gsub("%-(%d+%%) reduced", function(num) return num.." increased" end)
:gsub("%-(%d+%%) more", function(num) return num.." less" end)
:gsub("%-(%d+%%) less", function(num) return num.." more" end)
local testLine = not line:find("-", 1, true) and line or
line:gsub("(%+?)%((%-?%d+%.?%d*)%-(%-?%d+%.?%d*)%)",
function(plus, min, max)
min = tonumber(min)
local maxPrecision = min + range * (tonumber(max) - min)
local minPrecision = m_floor(maxPrecision + 0.5)
if minPrecision ~= maxPrecision then
precisionSame = false
end
return (minPrecision < 0 and "" or plus) .. tostring(minPrecision)
end)
:gsub("%-(%d+%%) (%a+)",
function(num, word)
local antonym = antonyms[word]
return antonym and (num.." "..antonym) or ("-"..num.." "..word)
end)

if precisionSame and (not valueScalar or valueScalar == 1) then
return testLine
end

local precision = nil
local modList, extra = modLib.parseMod(testLine)
if modList and not extra then
for _, mod in pairs(modList) do
Expand All @@ -86,27 +107,25 @@ function itemLib.applyRange(line, range, valueScalar)
if not precision and line:match("(%d+%.%d*)") then
precision = data.defaultHighPrecision
end
line = line:gsub("%((%d+)%-(%d+) to (%d+)%-(%d+)%)", "(%1-%2) to (%3-%4)")
:gsub("(%+?)%((%-?%d+) to (%d+)%)", "%1(%2-%3)")
:gsub("(%+?)%((%-?%d+%.?%d*)%-(%-?%d+%.?%d*)%)",

local numbers = 0
line = line:gsub("(%+?)%((%-?%d+%.?%d*)%-(%-?%d+%.?%d*)%)",
function(plus, min, max)
numbers = numbers + 1
local power = 10 ^ (precision or 0)
local numVal = m_floor((tonumber(min) + range * (tonumber(max) - tonumber(min))) * power + 0.5) / power
if numVal < 0 then
if plus == "+" then
plus = ""
end
end
return plus .. tostring(numVal)
return (numVal < 0 and "" or plus) .. tostring(numVal)
end)
:gsub("%-(%d+%%) increased", function(num) return num.." reduced" end)
:gsub("%-(%d+%%) reduced", function(num) return num.." increased" end)
:gsub("%-(%d+%%) more", function(num) return num.." less" end)
:gsub("%-(%d+%%) less", function(num) return num.." more" end)
if numbers == 0 and line:match("(%d+%.?%d*)%%? ") then --If a mod contains x or x% and is not already a ranged value, then only the first number will be scalable as any following numbers will always be conditions or unscalable values.
numbers = 1
end
:gsub("%-(%d+%%) (%a+)",
function(num, word)
local antonym = antonyms[word]
return antonym and (num.." "..antonym) or ("-"..num.." "..word)
end)

if numbers == 0 and line:match("(%d+%.?%d*)%%? ") then --If a mod contains x or x% and is not already a ranged value, then only the first number will be scalable as any following numbers will always be conditions or unscalable values.
numbers = 1
end

return itemLib.applyValueScalar(line, valueScalar, numbers, precision)
end

Expand Down