diff --git a/spec/System/TestItemMods_spec.lua b/spec/System/TestItemMods_spec.lua index adbaaf7551..3cd048c22f 100644 --- a/spec/System/TestItemMods_spec.lua +++ b/spec/System/TestItemMods_spec.lua @@ -176,4 +176,48 @@ describe("TetsItemMods", function() assert.are_not.equals(baseLife, build.calcsTab.mainOutput.Life) end) + + it("globalLimit mods", function() + build.configTab.input.customMods = [[ + -1000% to cold resistance + ]] + build.configTab:BuildModList() + build.itemsTab:CreateDisplayItemFromRaw([[Replica Nebulis + Clasped Sceptre + League: Heist + Quality: 20 + Sockets: B-B-B + LevelReq: 68 + Implicits: 1 + 40% increased Elemental Damage + {fractured}{range:1}(15-20)% increased Cast Speed + {range:1}(15-20)% increased Cold Damage per 1% Missing Cold Resistance, up to a maximum of 300% + {range:1}(15-20)% increased Fire Damage per 1% Missing Fire Resistance, up to a maximum of 300%]]) + build.itemsTab:AddDisplayItem() + build.skillsTab:PasteSocketGroup("Slot: Weapon 1\nFireball 20/0 Default 1\n") + runCallback("OnFrame") + + assert.are_not.equals(340, build.calcsTab.mainEnv.modDB:Sum("INC", "FireDamage")) + assert.are_not.equals(340, build.calcsTab.mainEnv.modDB:Sum("INC", "ColdDamage")) + + newBuild() + + build.configTab.input.customMods = [[ + Gain 25% increased Armour per 5 Power for 8 seconds when you Warcry, up to a maximum of 100% + Warcries have infinite Power + warcries grant arcane surge to you and allies, with 10% increased effect per 5 power, up to 100% + ]] + build.configTab:BuildModList() + build.itemsTab:CreateDisplayItemFromRaw([[ + New Item + Fur Plate + Armour: 60 + ]]) + build.itemsTab:AddDisplayItem() + build.skillsTab:PasteSocketGroup("Arc 20/0 Default 1") + + assert.are_not.equals(20, build.calcsTab.mainEnv.modDB:Sum("MORE", { flags = ModFlag.Cast }, "Speed")) + assert.are_not.equals(120, build.calcsTab.mainOutput.Armour) + runCallback("OnFrame") + end) end) diff --git a/src/Classes/ModDB.lua b/src/Classes/ModDB.lua index 75e0cad813..44f725f0d3 100644 --- a/src/Classes/ModDB.lua +++ b/src/Classes/ModDB.lua @@ -98,14 +98,7 @@ function ModDBClass:SumInternal(context, modType, cfg, flags, keywordFlags, sour local mod = modList[i] 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 if mod[1] then - local value = context:EvalMod(mod, cfg) or 0 - if mod[1].globalLimit and mod[1].globalLimitKey then - globalLimits[mod[1].globalLimitKey] = globalLimits[mod[1].globalLimitKey] or 0 - if globalLimits[mod[1].globalLimitKey] + value > mod[1].globalLimit then - value = mod[1].globalLimit - globalLimits[mod[1].globalLimitKey] - end - globalLimits[mod[1].globalLimitKey] = globalLimits[mod[1].globalLimitKey] + value - end + local value = context:EvalMod(mod, cfg, globalLimits) or 0 result = result + value else result = result + mod.value @@ -133,14 +126,7 @@ function ModDBClass:MoreInternal(context, cfg, flags, keywordFlags, source, ...) 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 local value if mod[1] then - value = context:EvalMod(mod, cfg) or 0 - if mod[1].globalLimit and mod[1].globalLimitKey then - globalLimits[mod[1].globalLimitKey] = globalLimits[mod[1].globalLimitKey] or 0 - if globalLimits[mod[1].globalLimitKey] + value > mod[1].globalLimit then - value = mod[1].globalLimit - globalLimits[mod[1].globalLimitKey] - end - globalLimits[mod[1].globalLimitKey] = globalLimits[mod[1].globalLimitKey] + value - end + value = context:EvalMod(mod, cfg, globalLimits) or 0 else value = mod.value or 0 end @@ -249,15 +235,7 @@ function ModDBClass:TabulateInternal(context, result, modType, cfg, flags, keywo 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 local value if mod[1] then - value = context:EvalMod(mod, cfg) - if mod[1].globalLimit and mod[1].globalLimitKey then - value = value or 0 - globalLimits[mod[1].globalLimitKey] = globalLimits[mod[1].globalLimitKey] or 0 - if globalLimits[mod[1].globalLimitKey] + value > mod[1].globalLimit then - value = mod[1].globalLimit - globalLimits[mod[1].globalLimitKey] - end - globalLimits[mod[1].globalLimitKey] = globalLimits[mod[1].globalLimitKey] + value - end + value = context:EvalMod(mod, cfg, globalLimits) else value = mod.value end diff --git a/src/Classes/ModStore.lua b/src/Classes/ModStore.lua index d1033107b4..03b670aaa2 100644 --- a/src/Classes/ModStore.lua +++ b/src/Classes/ModStore.lua @@ -283,12 +283,13 @@ function ModStoreClass:GetStat(stat, cfg) end end -function ModStoreClass:EvalMod(mod, cfg) +function ModStoreClass:EvalMod(mod, cfg, globalLimits) local value = mod.value for _, tag in ipairs(mod) do if tag.type == "Multiplier" then local target = self local limitTarget = self + -- Allow limiting a self multiplier on a parent multiplier (eg. Agony Crawler on player virulence) -- This explicit target is necessary because even though the GetMultiplier method does call self.parent.GetMultiplier, it does so with noMod = true, -- 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) return end end - end + end + + -- Apply global limits + for _, tag in ipairs(mod) do + if globalLimits and tag.globalLimit and tag.globalLimitKey then + value = value or 0 + globalLimits[tag.globalLimitKey] = globalLimits[tag.globalLimitKey] or 0 + if globalLimits[tag.globalLimitKey] + value > tag.globalLimit then + value = tag.globalLimit - globalLimits[tag.globalLimitKey] + end + globalLimits[tag.globalLimitKey] = globalLimits[tag.globalLimitKey] + value + end + end return value -end +end \ No newline at end of file