Skip to content

Commit 07b4083

Browse files
Wires77Paliak
andauthored
Fix globalLimit being sensitive to tag order (#1225)
* Fix globalLimit being sensitive to tag order (#8652) * FEAT(items): Add showcased uniques to New.lua * FEAT(mods): add handling for new mods on Scornflux * FEAT(mods): add handling for "Take X Fire Damage when you use a Skill" * FEAT(mods): add handling for Damage penetrates "Fire Resistance equal to your overcapped Fire Resistance" * FEAT(mods): add handling for "Warcries have an additional Life Cost equal to 15% of your Maximum Life" * FEAT(mods): add handling for "Warcry Skills have X increased Area of Effect" * FEAT(mods): add handling for `Gain no armour from equipped body armour` * FEAT(mods): port generalized "doubled" mod handling from POB2 #1095 * Update spelling and ModCache * FIX(mods): globalLimit style mods did not work sometimes When a mod gots pice wise parsed the tags can be added to the mod table in unpredictable order. The inital implementation was simply checking the first tag which caused the global limit functionality to not work sometimes. This commit moves the logic into EvalMod. * FEAT(mods): add support for "you have no Str/Dex" mods * FIX(spelling): un-rake-able --------- Co-authored-by: Wires77 <Wires77@users.noreply.github.com> * [PATCH 1/3] FIX: globalLimit not applying * [PATCH 2/3] MISC(test): add some more tests for globlaLimit type mods * [PATCH 3/3] MISC(test): test PerStat code path * Fix tests for PoE2 --------- Co-authored-by: Paliak <91493239+Paliak@users.noreply.github.com>
1 parent 6a06297 commit 07b4083

3 files changed

Lines changed: 63 additions & 28 deletions

File tree

spec/System/TestItemMods_spec.lua

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,4 +176,48 @@ describe("TetsItemMods", function()
176176

177177
assert.are_not.equals(baseLife, build.calcsTab.mainOutput.Life)
178178
end)
179+
180+
it("globalLimit mods", function()
181+
build.configTab.input.customMods = [[
182+
-1000% to cold resistance
183+
]]
184+
build.configTab:BuildModList()
185+
build.itemsTab:CreateDisplayItemFromRaw([[Replica Nebulis
186+
Clasped Sceptre
187+
League: Heist
188+
Quality: 20
189+
Sockets: B-B-B
190+
LevelReq: 68
191+
Implicits: 1
192+
40% increased Elemental Damage
193+
{fractured}{range:1}(15-20)% increased Cast Speed
194+
{range:1}(15-20)% increased Cold Damage per 1% Missing Cold Resistance, up to a maximum of 300%
195+
{range:1}(15-20)% increased Fire Damage per 1% Missing Fire Resistance, up to a maximum of 300%]])
196+
build.itemsTab:AddDisplayItem()
197+
build.skillsTab:PasteSocketGroup("Slot: Weapon 1\nFireball 20/0 Default 1\n")
198+
runCallback("OnFrame")
199+
200+
assert.are_not.equals(340, build.calcsTab.mainEnv.modDB:Sum("INC", "FireDamage"))
201+
assert.are_not.equals(340, build.calcsTab.mainEnv.modDB:Sum("INC", "ColdDamage"))
202+
203+
newBuild()
204+
205+
build.configTab.input.customMods = [[
206+
Gain 25% increased Armour per 5 Power for 8 seconds when you Warcry, up to a maximum of 100%
207+
Warcries have infinite Power
208+
warcries grant arcane surge to you and allies, with 10% increased effect per 5 power, up to 100%
209+
]]
210+
build.configTab:BuildModList()
211+
build.itemsTab:CreateDisplayItemFromRaw([[
212+
New Item
213+
Fur Plate
214+
Armour: 60
215+
]])
216+
build.itemsTab:AddDisplayItem()
217+
build.skillsTab:PasteSocketGroup("Arc 20/0 Default 1")
218+
219+
assert.are_not.equals(20, build.calcsTab.mainEnv.modDB:Sum("MORE", { flags = ModFlag.Cast }, "Speed"))
220+
assert.are_not.equals(120, build.calcsTab.mainOutput.Armour)
221+
runCallback("OnFrame")
222+
end)
179223
end)

src/Classes/ModDB.lua

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -98,14 +98,7 @@ function ModDBClass:SumInternal(context, modType, cfg, flags, keywordFlags, sour
9898
local mod = modList[i]
9999
if mod.type == modType and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or ( mod.source and (mod.source:match("[^:]+") == source or mod.source == source))) then
100100
if mod[1] then
101-
local value = context:EvalMod(mod, cfg) or 0
102-
if mod[1].globalLimit and mod[1].globalLimitKey then
103-
globalLimits[mod[1].globalLimitKey] = globalLimits[mod[1].globalLimitKey] or 0
104-
if globalLimits[mod[1].globalLimitKey] + value > mod[1].globalLimit then
105-
value = mod[1].globalLimit - globalLimits[mod[1].globalLimitKey]
106-
end
107-
globalLimits[mod[1].globalLimitKey] = globalLimits[mod[1].globalLimitKey] + value
108-
end
101+
local value = context:EvalMod(mod, cfg, globalLimits) or 0
109102
result = result + value
110103
else
111104
result = result + mod.value
@@ -133,14 +126,7 @@ function ModDBClass:MoreInternal(context, cfg, flags, keywordFlags, source, ...)
133126
if mod.type == "MORE" and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.source:match("[^:]+") == source) then
134127
local value
135128
if mod[1] then
136-
value = context:EvalMod(mod, cfg) or 0
137-
if mod[1].globalLimit and mod[1].globalLimitKey then
138-
globalLimits[mod[1].globalLimitKey] = globalLimits[mod[1].globalLimitKey] or 0
139-
if globalLimits[mod[1].globalLimitKey] + value > mod[1].globalLimit then
140-
value = mod[1].globalLimit - globalLimits[mod[1].globalLimitKey]
141-
end
142-
globalLimits[mod[1].globalLimitKey] = globalLimits[mod[1].globalLimitKey] + value
143-
end
129+
value = context:EvalMod(mod, cfg, globalLimits) or 0
144130
else
145131
value = mod.value or 0
146132
end
@@ -249,15 +235,7 @@ function ModDBClass:TabulateInternal(context, result, modType, cfg, flags, keywo
249235
if (mod.type == modType or not modType) and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.source:match("[^:]+") == source) then
250236
local value
251237
if mod[1] then
252-
value = context:EvalMod(mod, cfg)
253-
if mod[1].globalLimit and mod[1].globalLimitKey then
254-
value = value or 0
255-
globalLimits[mod[1].globalLimitKey] = globalLimits[mod[1].globalLimitKey] or 0
256-
if globalLimits[mod[1].globalLimitKey] + value > mod[1].globalLimit then
257-
value = mod[1].globalLimit - globalLimits[mod[1].globalLimitKey]
258-
end
259-
globalLimits[mod[1].globalLimitKey] = globalLimits[mod[1].globalLimitKey] + value
260-
end
238+
value = context:EvalMod(mod, cfg, globalLimits)
261239
else
262240
value = mod.value
263241
end

src/Classes/ModStore.lua

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -283,12 +283,13 @@ function ModStoreClass:GetStat(stat, cfg)
283283
end
284284
end
285285

286-
function ModStoreClass:EvalMod(mod, cfg)
286+
function ModStoreClass:EvalMod(mod, cfg, globalLimits)
287287
local value = mod.value
288288
for _, tag in ipairs(mod) do
289289
if tag.type == "Multiplier" then
290290
local target = self
291291
local limitTarget = self
292+
292293
-- Allow limiting a self multiplier on a parent multiplier (eg. Agony Crawler on player virulence)
293294
-- This explicit target is necessary because even though the GetMultiplier method does call self.parent.GetMultiplier, it does so with noMod = true,
294295
-- disabling the summation (3rd part): (not noMod and self:Sum("BASE", cfg, multiplierName[var]) or 0)
@@ -825,6 +826,18 @@ function ModStoreClass:EvalMod(mod, cfg)
825826
return
826827
end
827828
end
828-
end
829+
end
830+
831+
-- Apply global limits
832+
for _, tag in ipairs(mod) do
833+
if globalLimits and tag.globalLimit and tag.globalLimitKey then
834+
value = value or 0
835+
globalLimits[tag.globalLimitKey] = globalLimits[tag.globalLimitKey] or 0
836+
if globalLimits[tag.globalLimitKey] + value > tag.globalLimit then
837+
value = tag.globalLimit - globalLimits[tag.globalLimitKey]
838+
end
839+
globalLimits[tag.globalLimitKey] = globalLimits[tag.globalLimitKey] + value
840+
end
841+
end
829842
return value
830-
end
843+
end

0 commit comments

Comments
 (0)