diff --git a/src/Classes/Control.lua b/src/Classes/Control.lua index edba66f1e4..5c46e147cd 100644 --- a/src/Classes/Control.lua +++ b/src/Classes/Control.lua @@ -74,12 +74,16 @@ function ControlClass:GetPos() local otherW, otherH = 0, 0 local width, height = 0, 0 local otherPos = anchorPos[self.anchor.otherPoint] - assert(otherPos, "invalid anchor position '"..tostring(self.anchor.otherPoint).."'") + if not otherPos then + error("invalid anchor position '"..tostring(self.anchor.otherPoint).."'", 2) + end if self.anchor.otherPoint ~= "TOPLEFT" then otherW, otherH = self.anchor.other:GetSize() end local pos = anchorPos[self.anchor.point] - assert(pos, "invalid anchor position '"..tostring(self.anchor.point).."'") + if not pos then + error("invalid anchor position '"..tostring(self.anchor.point).."'", 2) + end if self.anchor.point ~= "TOPLEFT" then width, height = self:GetSize() end diff --git a/src/Classes/ControlHost.lua b/src/Classes/ControlHost.lua index 13aec58ef9..6fb6ce4534 100644 --- a/src/Classes/ControlHost.lua +++ b/src/Classes/ControlHost.lua @@ -91,9 +91,10 @@ function ControlHostClass:ProcessControlsInput(inputEvents, viewPort) end function ControlHostClass:DrawControls(viewPort, selControl) + local sel = (self.selControl and self.selControl.hasFocus and self.selControl) or (selControl and selControl.hasFocus and selControl) for _, control in pairs(self.controls) do if control:IsShown() and control.Draw then - control:Draw(viewPort, (self.selControl and self.selControl.hasFocus and self.selControl ~= control) or (selControl and selControl.hasFocus and selControl ~= control)) + control:Draw(viewPort, sel and sel ~= control) end end end diff --git a/src/Classes/Item.lua b/src/Classes/Item.lua index c0d2e7a7dc..c0c56700fe 100644 --- a/src/Classes/Item.lua +++ b/src/Classes/Item.lua @@ -13,6 +13,7 @@ local m_floor = math.floor local dmgTypeList = {"Physical", "Lightning", "Cold", "Fire", "Chaos"} local catalystList = {"Abrasive", "Accelerating", "Dextral", "Fertile", "Imbued", "Intrinsic", "Noxious", "Prismatic", "Sinistral", "Tempering", "Turbulent", "Unstable"} local catalystDescriptorList = {"Attack", "Speed", "Suffix", "Life and Mana", "Caster", "Attribute", "Physical and Chaos", "Resistance", "Prefix", "Defence", "Elemental", "Critical"} +local lineFlagsList = { "unveiled", "prefix", "suffix" } local catalystTags = { { "attack" }, { "speed" }, @@ -291,15 +292,15 @@ function ItemClass:FindModifierSubstring(substring, itemSlotName) --getTagBasedModifiers(substring, itemSlotName) -- merge various modifier lines into one table - for _,v in pairs(self.explicitModLines) do t_insert(modLines, v) end + for _,v in ipairs(self.explicitModLines) do t_insert(modLines, v) end if explicit < 1 then - for _,v in pairs(self.enchantModLines) do t_insert(modLines, v) end - for _,v in pairs(self.scourgeModLines) do t_insert(modLines, v) end - for _,v in pairs(self.implicitModLines) do t_insert(modLines, v) end - for _,v in pairs(self.crucibleModLines) do t_insert(modLines, v) end + for _,v in ipairs(self.enchantModLines) do t_insert(modLines, v) end + for _,v in ipairs(self.scourgeModLines) do t_insert(modLines, v) end + for _,v in ipairs(self.implicitModLines) do t_insert(modLines, v) end + for _,v in ipairs(self.crucibleModLines) do t_insert(modLines, v) end end - for _,v in pairs(modLines) do + for _,v in ipairs(modLines) do if not v.disabled and self:CheckModLineVariant(v) then if v.line:lower():find(substring) and not v.line:lower():find(substring .. " modifier") then local excluded = false @@ -1396,7 +1397,7 @@ function ItemClass:ParseRaw(raw, rarity, highQuality) tagLookup[curTag] = true; end -- these aren't actual mod tags but do appear in mod magnitude mods - for _, lineFlag in ipairs({ "unveiled", "prefix", "suffix" }) do + for _, lineFlag in ipairs(lineFlagsList) do if mod[lineFlag] then tagLookup[lineFlag] = true end diff --git a/src/Classes/LabelControl.lua b/src/Classes/LabelControl.lua index 2f799ece2d..921dc01e3a 100644 --- a/src/Classes/LabelControl.lua +++ b/src/Classes/LabelControl.lua @@ -7,7 +7,12 @@ local LabelClass = newClass("LabelControl", "Control", function(self, anchor, re self.Control(anchor, rect) self.label = label self.width = function() - return DrawStringWidth(self:GetProperty("height"), "VAR", self:GetProperty("label")) + local curLabel = self:GetProperty("label") + if self.cachedLabel ~= curLabel then + self.cachedLabel = curLabel + self.cachedWidth = DrawStringWidth(self:GetProperty("height"), "VAR", curLabel or "") + end + return self.cachedWidth end end) diff --git a/src/Classes/ModDB.lua b/src/Classes/ModDB.lua index 3b7ae60922..7b5854f709 100644 --- a/src/Classes/ModDB.lua +++ b/src/Classes/ModDB.lua @@ -23,6 +23,9 @@ local ModDBClass = newClass("ModDB", "ModStore", function(self, parent) end) function ModDBClass:AddMod(mod) + if mod.source and not mod.baseSource then + mod.baseSource = mod.source:match("[^:]+") + end local name = mod.name if not self.mods[name] then self.mods[name] = { } @@ -108,6 +111,9 @@ end function ModDBClass:AddList(modList) local mods = self.mods for i, mod in ipairs(modList) do + if mod.source and not mod.baseSource then + mod.baseSource = mod.source:match("[^:]+") + end local name = mod.name if not mods[name] then mods[name] = { } @@ -124,7 +130,11 @@ function ModDBClass:AddDB(modDB) end local modsName = mods[modName] for i = 1, #modList do - t_insert(modsName, modList[i]) + local mod = modList[i] + if mod.source and not mod.baseSource then + mod.baseSource = mod.source:match("[^:]+") + end + t_insert(modsName, mod) end end end @@ -132,12 +142,13 @@ end function ModDBClass:SumInternal(context, modType, cfg, flags, keywordFlags, source, ...) local result = 0 local globalLimits = { } - for i = 1, select('#', ...) do - local modList = self.mods[select(i, ...)] + local numNames = select('#', ...) + if numNames == 1 then + local modList = self.mods[...] if modList then - for i = 1, #modList do - 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 )) then + for j = 1, #modList do + local mod = modList[j] + if mod.type == modType and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.baseSource == source) then if mod[1] then local value = context:EvalMod(mod, cfg, globalLimits) or 0 result = result + value @@ -147,6 +158,24 @@ function ModDBClass:SumInternal(context, modType, cfg, flags, keywordFlags, sour end end end + else + for i = 1, numNames do + local modName = select(i, ...) + local modList = self.mods[modName] + if modList then + for j = 1, #modList do + local mod = modList[j] + if mod.type == modType and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.baseSource == source) then + if mod[1] then + local value = context:EvalMod(mod, cfg, globalLimits) or 0 + result = result + value + else + result = result + mod.value + end + end + end + end + end end if self.parent then result = result + self.parent:SumInternal(context, modType, cfg, flags, keywordFlags, source, ...) @@ -158,13 +187,14 @@ function ModDBClass:MoreInternal(context, cfg, flags, keywordFlags, source, ...) local result = 1 local modPrecision = nil local globalLimits = { } - for i = 1, select('#', ...) do - local modList = self.mods[select(i, ...)] + local numNames = select('#', ...) + if numNames == 1 then + local modList = self.mods[...] local modResult = 1 --The more multipliers for each mod are computed to the nearest percent then applied. if modList then - for i = 1, #modList do - local mod = modList[i] - 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 + for j = 1, #modList do + local mod = modList[j] + if mod.type == "MORE" and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.baseSource == source) then local value if mod[1] then value = context:EvalMod(mod, cfg, globalLimits) or 0 @@ -186,6 +216,37 @@ function ModDBClass:MoreInternal(context, cfg, flags, keywordFlags, source, ...) else result = result * round(modResult, 2) end + else + for i = 1, numNames do + local modName = select(i, ...) + local modList = self.mods[modName] + local modResult = 1 --The more multipliers for each mod are computed to the nearest percent then applied. + if modList then + for j = 1, #modList do + local mod = modList[j] + if mod.type == "MORE" and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.baseSource == source) then + local value + if mod[1] then + value = context:EvalMod(mod, cfg, globalLimits) or 0 + else + value = mod.value or 0 + end + modResult = modResult * (1 + value / 100) + if modPrecision then + modPrecision = m_max(modPrecision, (data.highPrecisionMods[mod.name] and data.highPrecisionMods[mod.name][mod.type]) or modPrecision) + else + modPrecision = (data.highPrecisionMods[mod.name] and data.highPrecisionMods[mod.name][mod.type]) or nil + end + end + end + end + if modPrecision then + local power = 10 ^ modPrecision + result = math.floor(result * modResult * power) / power + else + result = result * round(modResult, 2) + end + end end if self.parent then result = result * self.parent:MoreInternal(context, cfg, flags, keywordFlags, source, ...) @@ -194,12 +255,13 @@ function ModDBClass:MoreInternal(context, cfg, flags, keywordFlags, source, ...) end function ModDBClass:FlagInternal(context, cfg, flags, keywordFlags, source, ...) - for i = 1, select('#', ...) do - local modList = self.mods[select(i, ...)] + local numNames = select('#', ...) + if numNames == 1 then + local modList = self.mods[...] if modList then - for i = 1, #modList do - local mod = modList[i] - if mod.type == "FLAG" and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.source:match("[^:]+") == source) then + for j = 1, #modList do + local mod = modList[j] + if mod.type == "FLAG" and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.baseSource == source) then if mod[1] then if context:EvalMod(mod, cfg) then return true @@ -210,6 +272,25 @@ function ModDBClass:FlagInternal(context, cfg, flags, keywordFlags, source, ...) end end end + else + for i = 1, numNames do + local modName = select(i, ...) + local modList = self.mods[modName] + if modList then + for j = 1, #modList do + local mod = modList[j] + if mod.type == "FLAG" and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.baseSource == source) then + if mod[1] then + if context:EvalMod(mod, cfg) then + return true + end + elseif mod.value then + return true + end + end + end + end + end end if self.parent then return self.parent:FlagInternal(context, cfg, flags, keywordFlags, source, ...) @@ -217,12 +298,13 @@ function ModDBClass:FlagInternal(context, cfg, flags, keywordFlags, source, ...) end function ModDBClass:OverrideInternal(context, cfg, flags, keywordFlags, source, ...) - for i = 1, select('#', ...) do - local modList = self.mods[select(i, ...)] + local numNames = select('#', ...) + if numNames == 1 then + local modList = self.mods[...] if modList then - for i = 1, #modList do - local mod = modList[i] - if mod.type == "OVERRIDE" and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.source:match("[^:]+") == source) then + for j = 1, #modList do + local mod = modList[j] + if mod.type == "OVERRIDE" and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.baseSource == source) then if mod[1] then local value = context:EvalMod(mod, cfg) if value then @@ -234,6 +316,26 @@ function ModDBClass:OverrideInternal(context, cfg, flags, keywordFlags, source, end end end + else + for i = 1, numNames do + local modName = select(i, ...) + local modList = self.mods[modName] + if modList then + for j = 1, #modList do + local mod = modList[j] + if mod.type == "OVERRIDE" and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.baseSource == source) then + if mod[1] then + local value = context:EvalMod(mod, cfg) + if value then + return value + end + elseif mod.value then + return mod.value + end + end + end + end + end end if self.parent then return self.parent:OverrideInternal(context, cfg, flags, keywordFlags, source, ...) @@ -241,12 +343,13 @@ function ModDBClass:OverrideInternal(context, cfg, flags, keywordFlags, source, end function ModDBClass:ListInternal(context, result, cfg, flags, keywordFlags, source, ...) - for i = 1, select('#', ...) do - local modList = self.mods[select(i, ...)] + local numNames = select('#', ...) + if numNames == 1 then + local modList = self.mods[...] if modList then - for i = 1, #modList do - local mod = modList[i] - if mod.type == "LIST" and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.source:match("[^:]+") == source) then + for j = 1, #modList do + local mod = modList[j] + if mod.type == "LIST" and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.baseSource == source) then local value if mod[1] then local value = context:EvalMod(mod, cfg) or nullValue @@ -259,6 +362,27 @@ function ModDBClass:ListInternal(context, result, cfg, flags, keywordFlags, sour end end end + else + for i = 1, numNames do + local modName = select(i, ...) + local modList = self.mods[modName] + if modList then + for j = 1, #modList do + local mod = modList[j] + if mod.type == "LIST" and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.baseSource == source) then + local value + if mod[1] then + local value = context:EvalMod(mod, cfg) or nullValue + if value then + t_insert(result, value) + end + elseif mod.value then + t_insert(result, mod.value) + end + end + end + end + end end if self.parent then self.parent:ListInternal(context, result, cfg, flags, keywordFlags, source, ...) @@ -267,13 +391,13 @@ end function ModDBClass:TabulateInternal(context, result, modType, cfg, flags, keywordFlags, source, ...) local globalLimits = { } - for i = 1, select('#', ...) do - local modName = select(i, ...) - local modList = self.mods[modName] + local numNames = select('#', ...) + if numNames == 1 then + local modList = self.mods[...] if modList then - for i = 1, #modList do - local mod = modList[i] - 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 + for j = 1, #modList do + local mod = modList[j] + if (mod.type == modType or not modType) and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.baseSource == source) then local value if mod[1] then value = context:EvalMod(mod, cfg, globalLimits) @@ -286,6 +410,27 @@ function ModDBClass:TabulateInternal(context, result, modType, cfg, flags, keywo end end end + else + for i = 1, numNames do + local modName = select(i, ...) + local modList = self.mods[modName] + if modList then + for j = 1, #modList do + local mod = modList[j] + if (mod.type == modType or not modType) and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.baseSource == source) then + local value + if mod[1] then + value = context:EvalMod(mod, cfg, globalLimits) + else + value = mod.value + end + if value and (value ~= 0 or mod.type == "OVERRIDE") then + t_insert(result, { value = value, mod = mod }) + end + end + end + end + end end if self.parent then self.parent:TabulateInternal(context, result, modType, cfg, flags, keywordFlags, source, ...) @@ -300,16 +445,30 @@ end ---@param source string @The mod source to match ---@return boolean @true if the mod is found, false otherwise. function ModDBClass:HasModInternal(modType, flags, keywordFlags, source, ...) - for i = 1, select('#', ...) do - local modList = self.mods[select(i, ...)] + local numNames = select('#', ...) + if numNames == 1 then + local modList = self.mods[...] if modList then - for i = 1, #modList do - 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:match("[^:]+") == source) then + for j = 1, #modList do + local mod = modList[j] + if mod.type == modType and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.baseSource == source) then return true end end end + else + for i = 1, numNames do + local modName = select(i, ...) + local modList = self.mods[modName] + if modList then + for j = 1, #modList do + local mod = modList[j] + if mod.type == modType and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.baseSource == source) then + return true + end + end + end + end end if self.parent then local parentResult = self.parent:HasModInternal(modType, flags, keywordFlags, source, ...) diff --git a/src/Classes/ModList.lua b/src/Classes/ModList.lua index 7bb6e2aba8..909f9dd821 100644 --- a/src/Classes/ModList.lua +++ b/src/Classes/ModList.lua @@ -21,6 +21,9 @@ local ModListClass = newClass("ModList", "ModStore", function(self, parent) end) function ModListClass:AddMod(mod) + if mod.source and not mod.baseSource then + mod.baseSource = mod.source:match("[^:]+") + end t_insert(self, mod) end @@ -84,7 +87,11 @@ end function ModListClass:AddList(modList) if modList then for i = 1, #modList do - t_insert(self, modList[i]) + local mod = modList[i] + if mod.source and not mod.baseSource then + mod.baseSource = mod.source:match("[^:]+") + end + t_insert(self, mod) end end end @@ -96,11 +103,12 @@ end function ModListClass:SumInternal(context, modType, cfg, flags, keywordFlags, source, ...) local result = 0 - for i = 1, select('#', ...) do - local modName = select(i, ...) - for i = 1, #self do - local mod = self[i] - if mod.name == modName and mod.type == modType and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.source:match("[^:]+") == source) then + local numNames = select('#', ...) + if numNames == 1 then + local modName = ... + for j = 1, #self do + local mod = self[j] + if mod.name == modName and mod.type == modType and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.baseSource == source) then if mod[1] then result = result + (context:EvalMod(mod, cfg) or 0) else @@ -108,6 +116,20 @@ function ModListClass:SumInternal(context, modType, cfg, flags, keywordFlags, so end end end + else + for i = 1, numNames do + local modName = select(i, ...) + for j = 1, #self do + local mod = self[j] + if mod.name == modName and mod.type == modType and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.baseSource == source) then + if mod[1] then + result = result + (context:EvalMod(mod, cfg) or 0) + else + result = result + mod.value + end + end + end + end end if self.parent then result = result + self.parent:SumInternal(context, modType, cfg, flags, keywordFlags, source, ...) @@ -118,12 +140,13 @@ end function ModListClass:MoreInternal(context, cfg, flags, keywordFlags, source, ...) local result = 1 local modPrecision = nil - for i = 1, select('#', ...) do + local numNames = select('#', ...) + if numNames == 1 then local modResult = 1 --The more multipliers for each mod are computed to the nearest percent then applied. - local modName = select(i, ...) - for i = 1, #self do - local mod = self[i] - if mod.name == modName and 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 modName = ... + for j = 1, #self do + local mod = self[j] + if mod.name == modName and mod.type == "MORE" and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.baseSource == source) then if mod[1] then modResult = modResult * (1 + (context:EvalMod(mod, cfg) or 0) / 100) else @@ -142,6 +165,32 @@ function ModListClass:MoreInternal(context, cfg, flags, keywordFlags, source, .. else result = result * round(modResult, 2) end + else + for i = 1, numNames do + local modResult = 1 --The more multipliers for each mod are computed to the nearest percent then applied. + local modName = select(i, ...) + for j = 1, #self do + local mod = self[j] + if mod.name == modName and mod.type == "MORE" and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.baseSource == source) then + if mod[1] then + modResult = modResult * (1 + (context:EvalMod(mod, cfg) or 0) / 100) + else + modResult = modResult * (1 + mod.value / 100) + end + if modPrecision then + modPrecision = m_max(modPrecision, (data.highPrecisionMods[mod.name] and data.highPrecisionMods[mod.name][mod.type]) or modPrecision) + else + modPrecision = (data.highPrecisionMods[mod.name] and data.highPrecisionMods[mod.name][mod.type]) or nil + end + end + end + if modPrecision then + local power = 10 ^ modPrecision + result = math.floor(result * modResult * power) / power + else + result = result * round(modResult, 2) + end + end end if self.parent then result = result * self.parent:MoreInternal(context, cfg, flags, keywordFlags, source, ...) @@ -150,11 +199,12 @@ function ModListClass:MoreInternal(context, cfg, flags, keywordFlags, source, .. end function ModListClass:FlagInternal(context, cfg, flags, keywordFlags, source, ...) - for i = 1, select('#', ...) do - local modName = select(i, ...) - for i = 1, #self do - local mod = self[i] - if mod.name == modName and mod.type == "FLAG" and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.source:match("[^:]+") == source) then + local numNames = select('#', ...) + if numNames == 1 then + local modName = ... + for j = 1, #self do + local mod = self[j] + if mod.name == modName and mod.type == "FLAG" and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.baseSource == source) then if mod[1] then if context:EvalMod(mod, cfg) then return true @@ -164,6 +214,22 @@ function ModListClass:FlagInternal(context, cfg, flags, keywordFlags, source, .. end end end + else + for i = 1, numNames do + local modName = select(i, ...) + for j = 1, #self do + local mod = self[j] + if mod.name == modName and mod.type == "FLAG" and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.baseSource == source) then + if mod[1] then + if context:EvalMod(mod, cfg) then + return true + end + elseif mod.value then + return true + end + end + end + end end if self.parent then return self.parent:FlagInternal(context, cfg, flags, keywordFlags, source, ...) @@ -171,11 +237,12 @@ function ModListClass:FlagInternal(context, cfg, flags, keywordFlags, source, .. end function ModListClass:OverrideInternal(context, cfg, flags, keywordFlags, source, ...) - for i = 1, select('#', ...) do - local modName = select(i, ...) - for i = 1, #self do - local mod = self[i] - if mod.name == modName and mod.type == "OVERRIDE" and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.source:match("[^:]+") == source) then + local numNames = select('#', ...) + if numNames == 1 then + local modName = ... + for j = 1, #self do + local mod = self[j] + if mod.name == modName and mod.type == "OVERRIDE" and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.baseSource == source) then if mod[1] then local value = context:EvalMod(mod, cfg) if value then @@ -186,6 +253,23 @@ function ModListClass:OverrideInternal(context, cfg, flags, keywordFlags, source end end end + else + for i = 1, numNames do + local modName = select(i, ...) + for j = 1, #self do + local mod = self[j] + if mod.name == modName and mod.type == "OVERRIDE" and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.baseSource == source) then + if mod[1] then + local value = context:EvalMod(mod, cfg) + if value then + return value + end + elseif mod.value then + return mod.value + end + end + end + end end if self.parent then return self.parent:OverrideInternal(context, cfg, flags, keywordFlags, source, ...) @@ -193,11 +277,12 @@ function ModListClass:OverrideInternal(context, cfg, flags, keywordFlags, source end function ModListClass:ListInternal(context, result, cfg, flags, keywordFlags, source, ...) - for i = 1, select('#', ...) do - local modName = select(i, ...) - for i = 1, #self do - local mod = self[i] - if mod.name == modName and mod.type == "LIST" and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.source:match("[^:]+") == source) then + local numNames = select('#', ...) + if numNames == 1 then + local modName = ... + for j = 1, #self do + local mod = self[j] + if mod.name == modName and mod.type == "LIST" and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.baseSource == source) then local value if mod[1] then local value = context:EvalMod(mod, cfg) or nullValue @@ -209,6 +294,24 @@ function ModListClass:ListInternal(context, result, cfg, flags, keywordFlags, so end end end + else + for i = 1, numNames do + local modName = select(i, ...) + for j = 1, #self do + local mod = self[j] + if mod.name == modName and mod.type == "LIST" and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.baseSource == source) then + local value + if mod[1] then + local value = context:EvalMod(mod, cfg) or nullValue + if value then + t_insert(result, value) + end + elseif mod.value then + t_insert(result, mod.value) + end + end + end + end end if self.parent then self.parent:ListInternal(context, result, cfg, flags, keywordFlags, source, ...) @@ -216,11 +319,12 @@ function ModListClass:ListInternal(context, result, cfg, flags, keywordFlags, so end function ModListClass:TabulateInternal(context, result, modType, cfg, flags, keywordFlags, source, ...) - for i = 1, select('#', ...) do - local modName = select(i, ...) - for i = 1, #self do - local mod = self[i] - if mod.name == modName and (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 numNames = select('#', ...) + if numNames == 1 then + local modName = ... + for j = 1, #self do + local mod = self[j] + if mod.name == modName and (mod.type == modType or not modType) and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.baseSource == source) then local value if mod[1] then value = context:EvalMod(mod, cfg) @@ -232,6 +336,24 @@ function ModListClass:TabulateInternal(context, result, modType, cfg, flags, key end end end + else + for i = 1, numNames do + local modName = select(i, ...) + for j = 1, #self do + local mod = self[j] + if mod.name == modName and (mod.type == modType or not modType) and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.baseSource == source) then + local value + if mod[1] then + value = context:EvalMod(mod, cfg) + else + value = mod.value + end + if value and (value ~= 0 or mod.type == "OVERRIDE") then + t_insert(result, { value = value, mod = mod }) + end + end + end + end end if self.parent then self.parent:TabulateInternal(context, result, modType, cfg, flags, keywordFlags, source, ...) diff --git a/src/Classes/PassiveTreeView.lua b/src/Classes/PassiveTreeView.lua index 17a3394de0..d2be48609e 100644 --- a/src/Classes/PassiveTreeView.lua +++ b/src/Classes/PassiveTreeView.lua @@ -712,7 +712,7 @@ function PassiveTreeViewClass:Draw(build, viewPort, inputEvents) -- Fade out lines in ascendancy classes other than the current one setConnectorColor(0.75, 0.75, 0.75) end - SetDrawColor(unpack(connectorColor)) + SetDrawColor(connectorColor[1], connectorColor[2], connectorColor[3]) local assetName = connector.type .. state -- The game uses Abyss connector art only when both connected nodes are conquered. if isAbyssConquered(node1) and isAbyssConquered(node2) then @@ -760,7 +760,8 @@ function PassiveTreeViewClass:Draw(build, viewPort, inputEvents) SetDrawColor(0, 1, 0) local asset = tree.assets[connector.type..state] or tree.assets[connector.type.."Normal"] if asset then - DrawImageQuad(asset.handle, unpack(connector.c)) + local c = connector.c + DrawImageQuad(asset.handle, c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8]) end end end diff --git a/src/Classes/Tooltip.lua b/src/Classes/Tooltip.lua index 1906629b70..a4e24e64aa 100644 --- a/src/Classes/Tooltip.lua +++ b/src/Classes/Tooltip.lua @@ -587,18 +587,15 @@ function TooltipClass:Draw(x, y, w, h, viewPort) elseif type(self.color) == "string" then SetDrawColor(self.color) else - SetDrawColor(unpack(self.color)) + local c = self.color + SetDrawColor(c[1], c[2], c[3], c[4]) end if not skip then if line[1] and line[1].handle then - local args = { line[1].handle, line[2], line[3], line[4], line[5] } - for _, v in ipairs(line[1]) do - t_insert(args, v) - end SetDrawColor(1,1,1) - DrawImage(unpack(args)) + DrawImage(line[1].handle, line[2], line[3], line[4], line[5], line[1][1], line[1][2], line[1][3], line[1][4]) else - DrawImage(unpack(line)) + DrawImage(line[1], line[2], line[3], line[4], line[5]) end end else @@ -632,7 +629,7 @@ function TooltipClass:Draw(x, y, w, h, viewPort) end -- Draw text line - DrawString(unpack(line)) + DrawString(line[1], line[2], line[3], line[4], line[5], line[6]) if line.strikethrough then local textX = line[1] local textY = line[2] @@ -653,7 +650,8 @@ function TooltipClass:Draw(x, y, w, h, viewPort) if type(self.color) == "string" then SetDrawColor(self.color) else - SetDrawColor(unpack(self.color)) + local c = self.color + SetDrawColor(c[1], c[2], c[3], c[4]) end -- draw vertical borders, accounting for separate extra column width diff --git a/src/Modules/CalcPerform.lua b/src/Modules/CalcPerform.lua index 9217e3b8d7..a489a625f5 100644 --- a/src/Modules/CalcPerform.lua +++ b/src/Modules/CalcPerform.lua @@ -20,6 +20,12 @@ local bor = bit.bor local band = bit.band local bnot = bit.bnot +local attributeStats = { "Str", "Dex", "Int" } +local modTypeBaseIncMore = { "BASE", "INC", "MORE" } +local omniComboStats = { "StrDex", "StrInt", "DexInt", "All" } +local lifeManaPools = { "Life", "Mana" } +local gearSlotsArmour = { "Helmet", "Gloves", "Boots", "Body Armour", "Weapon 2", "Weapon 3" } + --- getCachedOutputValue --- retrieves a value specified by key from a cached version of skill --- specified by @uuid or if not found in cache computes teh cache. @@ -387,7 +393,7 @@ local function doActorAttribsConditions(env, actor) -- Calculate attributes local calculateAttributes = function() for pass = 1, 2 do -- Calculate twice because of circular dependency (X attribute higher than Y attribute) - for _, stat in pairs({"Str","Dex","Int"}) do + for _, stat in ipairs(attributeStats) do output[stat] = m_max(round(calcLib.val(modDB, stat)), 0) if breakdown then breakdown[stat] = breakdown.simple(nil, nil, output[stat], stat) @@ -419,7 +425,7 @@ local function doActorAttribsConditions(env, actor) for pass = 1, 2 do -- Calculate twice because of circular dependency (X attribute higher than Y attribute) if pass ~= 1 then - for _, stat in pairs({"Str","Dex","Int"}) do + for _, stat in ipairs(attributeStats) do local base = classStats["base_"..stat:lower()] output[stat] = m_min(round(calcLib.val(modDB, stat)), base) if breakdown then @@ -436,9 +442,9 @@ local function doActorAttribsConditions(env, actor) -- Subtract out double and triple dips local conversion = { } local reduction = { } - for _, type in pairs({"BASE", "INC", "MORE"}) do + for _, type in ipairs(modTypeBaseIncMore) do conversion[type] = { } - for _, stat in pairs({"StrDex", "StrInt", "DexInt", "All"}) do + for _, stat in ipairs(omniComboStats) do conversion[type][stat] = modDB:Sum(type, nil, stat) or 0 end reduction[type] = conversion[type].StrDex + conversion[type].StrInt + conversion[type].DexInt + 2*conversion[type].All @@ -448,7 +454,7 @@ local function doActorAttribsConditions(env, actor) modDB:NewMod("Omni", "MORE", -reduction["MORE"], "Reduction from Double/Triple Dipped attributes to Omniscience") end - for _, stat in pairs({"Str","Dex","Int"}) do + for _, stat in ipairs(attributeStats) do local base = classStats["base_"..stat:lower()] output[stat] = base end @@ -530,7 +536,7 @@ function doActorLifeManaReservation(actor, addAura) local output = actor.output local condList = modDB.conditions - for _, pool in pairs({"Life", "Mana"}) do + for _, pool in ipairs(lifeManaPools) do local max = output[pool] local reserved if max > 0 then @@ -1489,7 +1495,7 @@ function calcs.perform(env, skipEHP) local energyShieldBase local tempTable1 = { } local slotCfg = wipeTable(tempTable1) - for _, slot in pairs({"Helmet","Gloves","Boots","Body Armour","Weapon 2","Weapon 3"}) do + for _, slot in ipairs(gearSlotsArmour) do local armourData = env.player.itemList[slot] and env.player.itemList[slot].armourData if armourData then slotCfg.slotName = slot diff --git a/src/Modules/CalcSetup.lua b/src/Modules/CalcSetup.lua index 4c7561e616..fb4f0edc02 100644 --- a/src/Modules/CalcSetup.lua +++ b/src/Modules/CalcSetup.lua @@ -13,6 +13,7 @@ local m_min = math.min local m_max = math.max local tempTable1 = { } +local attributeStats = { "Str", "Dex", "Int" } -- Initialise modifier database with stats and conditions common to all actors function calcs.initModDB(env, modDB) @@ -487,7 +488,7 @@ function calcs.initEnv(build, mode, override, specEnv) if not cachedPlayerDB then -- Initialise modifier database with base values - for _, stat in pairs({"Str","Dex","Int"}) do + for _, stat in ipairs(attributeStats) do modDB:NewMod(stat, "BASE", classStats["base_"..stat:lower()], "Base") end modDB.multipliers["Level"] = m_max(1, m_min(100, build.characterLevel)) @@ -775,7 +776,7 @@ function calcs.initEnv(build, mode, override, specEnv) local funcList = (item.jewelData and item.jewelData.funcList) or { { type = "Self", func = function(node, out, data) -- Default function just tallies all stats in radius if node then - for _, stat in pairs({"Str","Dex","Int"}) do + for _, stat in ipairs(attributeStats) do data[stat] = (data[stat] or 0) + out:Sum("BASE", nil, stat) end end