From 907fab4e1cbdc646fb369a8ab57a425fde48a085 Mon Sep 17 00:00:00 2001 From: vaisest <4550061+vaisest@users.noreply.github.com> Date: Sat, 29 Aug 2026 12:31:38 +0300 Subject: [PATCH 1/2] Add a bunch of type hints --- src/Classes/BuildListControl.lua | 3 + src/Classes/CalcBreakdownControl.lua | 1 + src/Classes/CalcSectionControl.lua | 7 ++ src/Classes/CalcsTab.lua | 10 +-- src/Classes/CompareCalcsHelpers.lua | 9 +++ src/Classes/ConfigTab.lua | 10 +-- src/Classes/Control.lua | 9 ++- src/Classes/GemSelectControl.lua | 6 ++ src/Classes/ItemDBControl.lua | 10 +++ src/Classes/ItemListControl.lua | 4 + src/Classes/ItemSlotControl.lua | 7 ++ src/Classes/LabelControl.lua | 5 +- src/Classes/ListControl.lua | 10 ++- src/Classes/ModStore.lua | 38 +++++++++ src/Classes/NotableDBControl.lua | 1 + src/Classes/PassiveMasteryControl.lua | 12 ++- src/Classes/PassiveSpec.lua | 6 ++ src/Classes/PassiveTree.lua | 23 +++++- src/Classes/PassiveTreeView.lua | 13 ++++ src/Classes/SharedItemListControl.lua | 4 + src/Classes/SkillListControl.lua | 3 + src/Classes/SkillSetListControl.lua | 3 + src/Classes/TimelessJewelSocketControl.lua | 6 ++ src/Classes/TradeQuery.lua | 1 + src/Modules/Build.lua | 6 +- src/Modules/CalcActiveSkill.lua | 6 +- src/Modules/CalcBase.lua | 89 ++++++++++++++++++++++ src/Modules/CalcBreakdown.lua | 3 +- src/Modules/CalcDefence.lua | 7 ++ src/Modules/CalcOffence.lua | 26 ++++++- src/Modules/CalcPerform.lua | 7 +- src/Modules/CalcSetup.lua | 11 +++ src/Modules/CalcTriggers.lua | 4 + src/Modules/Calcs.lua | 61 ++++----------- src/Modules/Data.lua | 10 ++- src/Modules/Main.lua | 6 +- src/Modules/ModTools.lua | 20 +++++ 37 files changed, 379 insertions(+), 78 deletions(-) diff --git a/src/Classes/BuildListControl.lua b/src/Classes/BuildListControl.lua index 8a46e7bb95..65e2083c7d 100644 --- a/src/Classes/BuildListControl.lua +++ b/src/Classes/BuildListControl.lua @@ -9,6 +9,9 @@ local s_format = string.format ---@class BuildListControl: ListControl local BuildListClass = newClass("BuildListControl", "ListControl") +---@param anchor Anchor? +---@param rect Rect? +---@param listMode any function BuildListClass:BuildListControl(anchor, rect, listMode) self:ListControl(anchor, rect, 20, "VERTICAL", false, listMode.list) self.listMode = listMode diff --git a/src/Classes/CalcBreakdownControl.lua b/src/Classes/CalcBreakdownControl.lua index 1154bcad02..3668cce32b 100644 --- a/src/Classes/CalcBreakdownControl.lua +++ b/src/Classes/CalcBreakdownControl.lua @@ -16,6 +16,7 @@ local band = AND64 -- bit.band ---@class CalcBreakdownControl: Control, ControlHost local CalcBreakdownClass = newClass("CalcBreakdownControl", "Control", "ControlHost") +---@param calcsTab CalcsTab function CalcBreakdownClass:CalcBreakdownControl(calcsTab) self:Control() self:ControlHost() diff --git a/src/Classes/CalcSectionControl.lua b/src/Classes/CalcSectionControl.lua index 1f796ee92c..85441eaa01 100644 --- a/src/Classes/CalcSectionControl.lua +++ b/src/Classes/CalcSectionControl.lua @@ -8,6 +8,13 @@ local t_insert = table.insert ---@class CalcSectionControl: Control, ControlHost local CalcSectionClass = newClass("CalcSectionControl", "Control", "ControlHost") +---@param calcsTab CalcsTab +---@param width any +---@param id any +---@param group any +---@param colour any +---@param subSection any +---@param updateFunc any function CalcSectionClass:CalcSectionControl(calcsTab, width, id, group, colour, subSection, updateFunc) self:Control(calcsTab, {0, 0, width, 0}) self:ControlHost() diff --git a/src/Classes/CalcsTab.lua b/src/Classes/CalcsTab.lua index 16aa139e03..4c06f2cd8c 100644 --- a/src/Classes/CalcsTab.lua +++ b/src/Classes/CalcsTab.lua @@ -498,8 +498,8 @@ function CalcsTabClass:BuildOutput() end -- Retrieve calculator functions - self.nodeCalculator = { self.calcs.getNodeCalculator(self.build) } - self.miscCalculator = { self.calcs.getMiscCalculator(self.build) } + local miscCalcFunc, miscCalcBase = self.calcs.getMiscCalculator(self.build) + self.miscCalculator = { miscCalcFunc, miscCalcBase } end -- Controls the coroutine that calculates node power @@ -702,12 +702,8 @@ function CalcsTabClass:CalculateCombinedOffDefStat(original, modified) return dpsIncr / modifiedDps, defence end -function CalcsTabClass:GetNodeCalculator() - return unpack(self.nodeCalculator) -end - function CalcsTabClass:GetMiscCalculator() - return unpack(self.miscCalculator) + return self.miscCalculator[1], self.miscCalculator[2] end function CalcsTabClass:CreateUndoState() diff --git a/src/Classes/CompareCalcsHelpers.lua b/src/Classes/CompareCalcsHelpers.lua index 455c7b3a23..1a5254e8d0 100644 --- a/src/Classes/CompareCalcsHelpers.lua +++ b/src/Classes/CompareCalcsHelpers.lua @@ -40,6 +40,8 @@ function M.FormatCalcModName(modName) end -- Resolve a modifier's source to a human-readable name +---@param mod Mod +---@param build Build function M.ResolveSourceName(mod, build) if not mod.source then return "" end local sourceType = mod.source:match("[^:]+") or "" @@ -138,6 +140,8 @@ function M.FormatModRow(row, sectionData, build) end -- Get breakdown text lines for a build's actor +---@param sectionData any +---@param build Build function M.GetBreakdownLines(sectionData, build) if not sectionData.breakdown then return nil end local calcsActor = build.calcsTab and build.calcsTab.calcsEnv and build.calcsTab.calcsEnv.player @@ -164,6 +168,8 @@ end -- Draw the calcs hover tooltip showing breakdown for both builds with common/unique grouping -- tooltip, primaryBuild, primaryLabel passed as args instead of self +---@param tooltip Tooltip +---@param primaryBuild Build function M.DrawCalcsTooltip(tooltip, primaryBuild, primaryLabel, colData, rowLabel, rowX, rowY, rowW, rowH, vp, compareEntry) if tooltip:CheckForUpdate(colData, rowLabel) then -- Get calcsEnv actors (these have breakdown data populated) @@ -318,6 +324,8 @@ function M.DrawCalcsTooltip(tooltip, primaryBuild, primaryLabel, colData, rowLab end -- Resolve a modifier's source name for breakdown panel display +---@param mod Mod +---@param build Build local function resolveModSource(mod, build) local sourceType = mod.source and mod.source:match("[^:]+") or "?" local sourceName = "" @@ -352,6 +360,7 @@ local function resolveModSource(mod, build) end -- Draw a breakdown panel for a single build's SkillBuffs or SkillDebuffs, +---@param build Build function M.DrawSkillBreakdownPanel(build, breakdownKey, label, cellX, cellY, cellW, cellH, vp) local player = build.calcsTab and build.calcsTab.calcsEnv and build.calcsTab.calcsEnv.player diff --git a/src/Classes/ConfigTab.lua b/src/Classes/ConfigTab.lua index 3e8e7155d1..3d6a27badf 100644 --- a/src/Classes/ConfigTab.lua +++ b/src/Classes/ConfigTab.lua @@ -13,13 +13,13 @@ local s_upper = string.upper local varList = require("Modules.ConfigOptions") local configModBrowser = require("Modules.ConfigModBrowser") ----@class CustomModBlockControl : Control, ControlHost -local CustomModBlockClass = newClass("CustomModBlockControl", "Control", "ControlHost") +---@class CustomModBlockControl: ControlHost, Control +local CustomModBlockClass = newClass("CustomModBlockControl", "ControlHost", "Control") ----@param anchor Anchor ----@param rect Rect +---@param anchor Anchor? +---@param rect Rect? ---@param configTab ConfigTab ----@param blockIndex any +---@param blockIndex integer ---@param blockData any function CustomModBlockClass:CustomModBlockControl(anchor, rect, configTab, blockIndex, blockData) self:Control(anchor, rect) diff --git a/src/Classes/Control.lua b/src/Classes/Control.lua index a63a5a830a..5aadf03667 100644 --- a/src/Classes/Control.lua +++ b/src/Classes/Control.lua @@ -39,10 +39,17 @@ local rect = { ---@field shown Prop ---@field x Prop? ---@field y Prop? +---@field width Prop? +---@field height Prop? ---@field collapseY number? An additional offset which is applied when this control uses a collapsed anchor. ---@field collapseX number? An additional offset which is applied when this control uses a collapsed anchor. local ControlClass = newClass("Control") +---@alias Anchor [AnchorPoint, Control|ControlHost, AnchorPoint, boolean|nil] +---@alias Rect [Prop?,Prop?, Prop?, Prop?] + +---@param anchor? Anchor +---@param rect? Rect function ControlClass:Control(anchor, rect) self.rectStart = rect or {0, 0, 0, 0} self.x, self.y, self.width, self.height = unpack(self.rectStart) @@ -160,4 +167,4 @@ function ControlClass:TabAdvance(step) end end return self -end \ No newline at end of file +end diff --git a/src/Classes/GemSelectControl.lua b/src/Classes/GemSelectControl.lua index f5a434c530..6700cbc7ca 100644 --- a/src/Classes/GemSelectControl.lua +++ b/src/Classes/GemSelectControl.lua @@ -18,6 +18,12 @@ local toolTipText = "Prefix tag searches with a colon and exclude tags with a da ---@class GemSelectControl: EditControl local GemSelectClass = newClass("GemSelectControl", "EditControl") +---@param anchor Anchor? +---@param rect Rect? +---@param skillsTab SkillsTab +---@param index integer +---@param changeFunc fun(...) +---@param forceTooltip boolean function GemSelectClass:GemSelectControl(anchor, rect, skillsTab, index, changeFunc, forceTooltip) self:EditControl(anchor, rect, nil, nil, "^ %a':-") self.controls.scrollBar = new("ScrollBarControl"):ScrollBarControl({ "TOPRIGHT", self, "TOPRIGHT" }, { -1, 0, 18, 0 }, (self.height - 4) * 4) diff --git a/src/Classes/ItemDBControl.lua b/src/Classes/ItemDBControl.lua index 1691558d42..8fe05db24f 100644 --- a/src/Classes/ItemDBControl.lua +++ b/src/Classes/ItemDBControl.lua @@ -13,6 +13,16 @@ local m_floor = math.floor ---@class ItemDBControl: ListControl local ItemDBClass = newClass("ItemDBControl", "ListControl") +---@class ItemDBData +---@field list table +---@field byTitle? table +---@field loading boolean? + +---@param anchor Anchor? +---@param rect Rect? +---@param itemsTab ItemsTab +---@param db ItemDBData +---@param dbType "RARE"|"UNIQUE" function ItemDBClass:ItemDBControl(anchor, rect, itemsTab, db, dbType) self:ListControl(anchor, rect, 16, "VERTICAL", false) self.itemsTab = itemsTab diff --git a/src/Classes/ItemListControl.lua b/src/Classes/ItemListControl.lua index f2a4d61ced..b1cef41e05 100644 --- a/src/Classes/ItemListControl.lua +++ b/src/Classes/ItemListControl.lua @@ -9,6 +9,10 @@ local t_insert = table.insert ---@class ItemListControl: ListControl local ItemListClass = newClass("ItemListControl", "ListControl") +---@param anchor Anchor? +---@param rect Rect? +---@param itemsTab ItemsTab +---@param forceTooltip boolean? function ItemListClass:ItemListControl(anchor, rect, itemsTab, forceTooltip) self:ListControl(anchor, rect, 16, "VERTICAL", true, itemsTab.itemOrderList, forceTooltip) self.itemsTab = itemsTab diff --git a/src/Classes/ItemSlotControl.lua b/src/Classes/ItemSlotControl.lua index 95ee0b76f2..1cf2b54f7a 100644 --- a/src/Classes/ItemSlotControl.lua +++ b/src/Classes/ItemSlotControl.lua @@ -12,6 +12,13 @@ local BuildExportPoE2 = LoadModule("Modules/BuildExportPoE2") ---@class ItemSlotControl: DropDownControl local ItemSlotClass = newClass("ItemSlotControl", "DropDownControl") +---@param anchor Anchor? +---@param x Prop +---@param y Prop +---@param itemsTab ItemsTab +---@param slotName string +---@param slotLabel string +---@param nodeId integer? function ItemSlotClass:ItemSlotControl(anchor, x, y, itemsTab, slotName, slotLabel, nodeId) self:DropDownControl(anchor, {x, y, 310, 20}, { }, function(index, value) if self.items[index] ~= self.selItemId then diff --git a/src/Classes/LabelControl.lua b/src/Classes/LabelControl.lua index 04d084ced7..f684cfcd32 100644 --- a/src/Classes/LabelControl.lua +++ b/src/Classes/LabelControl.lua @@ -6,6 +6,9 @@ ---@class LabelControl: Control local LabelClass = newClass("LabelControl", "Control") +---@param anchor? Anchor +---@param rect? Rect +---@param label Prop function LabelClass:LabelControl(anchor, rect, label) self:Control(anchor, rect) self.label = label @@ -18,4 +21,4 @@ end function LabelClass:Draw() local x, y = self:GetPos() DrawString(x, y, "LEFT", self:GetProperty("height"), "VAR", self:GetProperty("label")) -end \ No newline at end of file +end diff --git a/src/Classes/ListControl.lua b/src/Classes/ListControl.lua index 3d56711104..60f2b6fcd7 100644 --- a/src/Classes/ListControl.lua +++ b/src/Classes/ListControl.lua @@ -30,9 +30,17 @@ local m_min = math.min local m_max = math.max local m_floor = math.floor ----@class ListControl: Control, ControlHost +---@class ListControl: Control, ControlHost +---@field list T[] local ListClass = newClass("ListControl", "Control", "ControlHost") +---@param anchor Anchor? +---@param rect Rect? +---@param rowHeight number +---@param scroll "HORIZONTAL"|"VERTICAL"|boolean|nil +---@param isMutable boolean? +---@param list any[]? +---@param forceTooltip any function ListClass:ListControl(anchor, rect, rowHeight, scroll, isMutable, list, forceTooltip) self:Control(anchor, rect) self:ControlHost() diff --git a/src/Classes/ModStore.lua b/src/Classes/ModStore.lua index c31acde6c8..12d29f1f7d 100644 --- a/src/Classes/ModStore.lua +++ b/src/Classes/ModStore.lua @@ -27,6 +27,12 @@ local conditionName = setmetatable({ }, { __index = function(t, var) return t[var] end }) +-- TODO: very incomplete +---@class ModCfg +---@field flags number? bit mask +---@field keywordFlags number? +---@field skillName string? +---@field source string? ---@class ModStore local ModStoreClass = newClass("ModStore") @@ -154,6 +160,10 @@ function ModStoreClass:Combine(modType, cfg, ...) end end +---@param modType string +---@param cfg? ModCfg +---@param ... string +---@return number function ModStoreClass:Sum(modType, cfg, ...) local flags, keywordFlags = 0, 0 local source @@ -200,6 +210,9 @@ function ModStoreClass:SumNegativeValues(modType, cfg, modName, ...) return total end +---@param cfg? ModCfg +---@param ... string +---@return number function ModStoreClass:More(cfg, ...) local flags, keywordFlags = 0, 0 local source @@ -222,6 +235,9 @@ function ModStoreClass:Flag(cfg, ...) return self:FlagInternal(self, cfg, flags, keywordFlags, source, ...) end +---@param cfg? ModCfg +---@param ... string +---@return any function ModStoreClass:Override(cfg, ...) local flags, keywordFlags = 0, 0 local source @@ -233,6 +249,9 @@ function ModStoreClass:Override(cfg, ...) return self:OverrideInternal(self, cfg, flags, keywordFlags, source, ...) end +---@param cfg? ModCfg +---@param ... string +---@return any[] function ModStoreClass:List(cfg, ...) local flags, keywordFlags = 0, 0 local source @@ -246,6 +265,10 @@ function ModStoreClass:List(cfg, ...) return result end +---@param modType string +---@param cfg? ModCfg +---@param ... string +---@return table[] function ModStoreClass:Tabulate(modType, cfg, ...) local flags, keywordFlags = 0, 0 local source @@ -289,6 +312,10 @@ function ModStoreClass:HasMod(modType, cfg, ...) return self:HasModInternal(modType, flags, keywordFlags, source, ...) end +---@param var string +---@param cfg? ModCfg +---@param noMod? boolean +---@return boolean function ModStoreClass:GetCondition(var, cfg, noMod) if (cfg and cfg.overrideCond and cfg.overrideCond[var] ~= nil) then return cfg.overrideCond[var] @@ -297,10 +324,17 @@ function ModStoreClass:GetCondition(var, cfg, noMod) end end +---@param var string +---@param cfg? ModCfg +---@param noMod? boolean +---@return number function ModStoreClass:GetMultiplier(var, cfg, noMod) return (not noMod and self:Override(cfg, multiplierName[var])) or (self.multipliers[var] or 0) + (self.parent and self.parent:GetMultiplier(var, cfg, true) or 0) + (not noMod and self:Sum("BASE", cfg, multiplierName[var]) or 0) end +---@param stat string +---@param cfg? ModCfg +---@return number function ModStoreClass:GetStat(stat, cfg) if stat == "ManaReservedPercent" then local reservedPercentMana = 0 @@ -346,6 +380,10 @@ function ModStoreClass:GetStat(stat, cfg) end end +---@param mod Mod +---@param cfg? ModCfg +---@param globalLimits? table +---@return any function ModStoreClass:EvalMod(mod, cfg, globalLimits) local value = mod.value local GetStat = self.GetStat diff --git a/src/Classes/NotableDBControl.lua b/src/Classes/NotableDBControl.lua index 5c574db0ec..ac6ab00971 100644 --- a/src/Classes/NotableDBControl.lua +++ b/src/Classes/NotableDBControl.lua @@ -24,6 +24,7 @@ end ---@class NotableDBControl: ListControl local NotableDBClass = newClass("NotableDBControl", "ListControl") +---@param itemsTab ItemsTab function NotableDBClass:NotableDBControl(anchor, rect, itemsTab, db, dbType) local headerHeight = 96 local innerRect = {rect[1], rect[2]+headerHeight, rect[3], rect[4]-headerHeight} diff --git a/src/Classes/PassiveMasteryControl.lua b/src/Classes/PassiveMasteryControl.lua index 1b924f806b..09a8ff1019 100644 --- a/src/Classes/PassiveMasteryControl.lua +++ b/src/Classes/PassiveMasteryControl.lua @@ -13,13 +13,23 @@ local m_floor = math.floor ---@class PassiveMasteryControl: ListControl local PassiveMasteryControlClass = newClass("PassiveMasteryControl", "ListControl") +---@class MasterListElem +---@field label string +---@field id number + +---@param anchor Anchor? +---@param rect Rect +---@param list MasterListElem[] +---@param treeTab TreeTab +---@param node Node +---@param saveButton ButtonControl function PassiveMasteryControlClass:PassiveMasteryControl(anchor, rect, list, treeTab, node, saveButton) self.list = list or { } -- automagical width for j=1,#list do rect[3] = m_max(rect[3], DrawStringWidth(16, "VAR", list[j].label) + 5) end - self:ListControl(anchor, rect, 16, false, false, self.list) + self:ListControl(anchor, rect, 16, nil, false, self.list) self.treeTab = treeTab self.treeView = treeTab.viewer self.node = node diff --git a/src/Classes/PassiveSpec.lua b/src/Classes/PassiveSpec.lua index 7b6da9ca25..79fd637493 100644 --- a/src/Classes/PassiveSpec.lua +++ b/src/Classes/PassiveSpec.lua @@ -23,8 +23,13 @@ local legacyClassIdMap = { } ---@class PassiveSpec: UndoHandler +---@field nodes table +---@field allocNodes table local PassiveSpecClass = newClass("PassiveSpec", "UndoHandler") +---@param build Build +---@param treeVersion any +---@param convert any function PassiveSpecClass:PassiveSpec(build, treeVersion, convert) self:UndoHandler() @@ -56,6 +61,7 @@ function PassiveSpecClass:Init(treeVersion, convert) for _, treeNode in pairs(self.tree.nodes) do -- Exclude proxy or groupless nodes, as well as expansion sockets if treeNode.group and not treeNode.isProxy and not treeNode.group.isProxy and (not treeNode.expansionJewel or not treeNode.expansionJewel.parent) then + ---@class Node self.nodes[treeNode.id] = setmetatable({ linked = { }, power = { } diff --git a/src/Classes/PassiveTree.lua b/src/Classes/PassiveTree.lua index f052c4d4b0..c0622749bf 100644 --- a/src/Classes/PassiveTree.lua +++ b/src/Classes/PassiveTree.lua @@ -35,7 +35,26 @@ local function getFile(URL) return #page > 0 and page end +---@class PassiveTreeGroup +---@field x number +---@field y number +---@field orbits integer[] +---@field nodes string[] +---@field background any +---@field isProxy boolean? ---@class PassiveTree +---@field classes any[] A list of classes on the tree +---@field alternate_ascendancies any[]? +---@field tree "Default"|"DefaultAltAscendancies" +---@field groups PassiveTreeGroup[] +---@field nodes table<"root"|integer, Node> +---@field jewelSlots integer[] +---@field min_x integer +---@field min_y integer +---@field max_x integer +---@field max_y integer +---@field constants table +---@field points table local PassiveTreeClass = newClass("PassiveTree") function PassiveTreeClass:PassiveTree(treeVersion) @@ -191,7 +210,9 @@ function PassiveTreeClass:PassiveTree(treeVersion) self.sockets = { } self.masteryEffects = { } local nodeMap = { } - for _, node in pairs(self.nodes) do + for _, n in pairs(self.nodes) do + ---@class Node + local node = n node.id = node.skill node.iname = node.stringId node.g = node.group diff --git a/src/Classes/PassiveTreeView.lua b/src/Classes/PassiveTreeView.lua index 8a854c6c45..b36251c96b 100644 --- a/src/Classes/PassiveTreeView.lua +++ b/src/Classes/PassiveTreeView.lua @@ -139,6 +139,11 @@ end -- Returns the draw color for a node when compare overlay is active. -- Handles diff coloring for allocated/unallocated, mastery changes, and jewel socket differences. +---@param node Node +---@param compareNode Node +---@param spec PassiveSpec +---@param build Build +---@param nodeDefaultColor any function PassiveTreeViewClass:GetCompareNodeColor(node, compareNode, spec, build, nodeDefaultColor) if not compareNode then return nodeDefaultColor @@ -1444,6 +1449,7 @@ function PassiveTreeViewClass:Zoom(level, viewPort) self.zoomY = relY + (self.zoomY - relY) * factor end +---@param build Build function PassiveTreeViewClass:Focus(x, y, viewPort, build) self.zoomLevel = 20 self.zoom = 1.2 ^ self.zoomLevel @@ -1547,6 +1553,9 @@ function PassiveTreeViewClass:DoesNodeMatchSearchParams(build, node) end end +---@param tooltip Tooltip +---@param node Node +---@param build Build function PassiveTreeViewClass:AddNodeName(tooltip, node, build) local fontSizeBig = main.showFlavourText and 18 or 16 tooltip:SetRecipe(node.infoRecipe) @@ -1606,6 +1615,10 @@ function PassiveTreeViewClass:AddNodeName(tooltip, node, build) end end +---@param tooltip Tooltip +---@param node Node +---@param build Build +---@param incSmallPassiveSkillEffect number? Whether the function should stop after writing the mod info, before any allocation-specific info function PassiveTreeViewClass:AddNodeTooltip(tooltip, node, build, incSmallPassiveSkillEffect) local fontSizeBig = main.showFlavourText and 18 or 16 tooltip.center = true diff --git a/src/Classes/SharedItemListControl.lua b/src/Classes/SharedItemListControl.lua index 7d0583722f..b578a390cb 100644 --- a/src/Classes/SharedItemListControl.lua +++ b/src/Classes/SharedItemListControl.lua @@ -10,6 +10,10 @@ local t_remove = table.remove ---@class SharedItemListControl: ListControl local SharedItemListClass = newClass("SharedItemListControl", "ListControl") +---@param anchor Anchor? +---@param rect Rect? +---@param itemsTab ItemsTab +---@param forceTooltip boolean? function SharedItemListClass:SharedItemListControl(anchor, rect, itemsTab, forceTooltip) self:ListControl(anchor, rect, 16, "VERTICAL", true, main.sharedItemList, forceTooltip) self.itemsTab = itemsTab diff --git a/src/Classes/SkillListControl.lua b/src/Classes/SkillListControl.lua index 954b14cae4..95e5966630 100644 --- a/src/Classes/SkillListControl.lua +++ b/src/Classes/SkillListControl.lua @@ -29,6 +29,9 @@ local slot_map = { ---@class SkillListControl: ListControl local SkillListClass = newClass("SkillListControl", "ListControl") +---@param anchor Anchor? +---@param rect Rect? +---@param skillsTab SkillsTab function SkillListClass:SkillListControl(anchor, rect, skillsTab) self:ListControl(anchor, rect, 16, "VERTICAL", true, skillsTab.socketGroupList) self.skillsTab = skillsTab diff --git a/src/Classes/SkillSetListControl.lua b/src/Classes/SkillSetListControl.lua index 415f7581cc..35cecbe2d3 100644 --- a/src/Classes/SkillSetListControl.lua +++ b/src/Classes/SkillSetListControl.lua @@ -12,6 +12,9 @@ local s_format = string.format ---@class SkillSetListControl: ListControl local SkillSetListClass = newClass("SkillSetListControl", "ListControl") +---@param anchor Anchor? +---@param rect Rect? +---@param skillsTab SkillsTab function SkillSetListClass:SkillSetListControl(anchor, rect, skillsTab) self:ListControl(anchor, rect, 16, "VERTICAL", true, skillsTab.skillSetOrderList) self.skillsTab = skillsTab diff --git a/src/Classes/TimelessJewelSocketControl.lua b/src/Classes/TimelessJewelSocketControl.lua index 3e841231df..5328e73976 100644 --- a/src/Classes/TimelessJewelSocketControl.lua +++ b/src/Classes/TimelessJewelSocketControl.lua @@ -9,6 +9,12 @@ local m_min = math.min ---@class TimelessJewelSocketControl: DropDownControl local TimelessJewelSocketClass = newClass("TimelessJewelSocketControl", "DropDownControl") +---@param anchor Anchor? +---@param rect Rect? +---@param list any[] +---@param selFunc any +---@param build Build +---@param socketViewer any function TimelessJewelSocketClass:TimelessJewelSocketControl(anchor, rect, list, selFunc, build, socketViewer) self:DropDownControl(anchor, rect, list, selFunc) self.build = build diff --git a/src/Classes/TradeQuery.lua b/src/Classes/TradeQuery.lua index 69c8d6d26c..cdff5eedb2 100644 --- a/src/Classes/TradeQuery.lua +++ b/src/Classes/TradeQuery.lua @@ -22,6 +22,7 @@ local baseSlots = { "Weapon 1", "Weapon 2", "Weapon 1 Swap", "Weapon 2 Swap", "H ---@class TradeQuery local TradeQueryClass = newClass("TradeQuery") +---@param itemsTab ItemsTab function TradeQueryClass:TradeQuery(itemsTab) self.itemsTab = itemsTab self.itemsTab.leagueDropList = { } diff --git a/src/Modules/Build.lua b/src/Modules/Build.lua index 6287f7a485..8d00ac7b52 100644 --- a/src/Modules/Build.lua +++ b/src/Modules/Build.lua @@ -17,6 +17,10 @@ local function firstToUpper(str) return (str:gsub("^%l", string.upper)) end +---@class Build: ControlHost +---@field spec PassiveSpec added by TreeTab +---@field powerBuilderProgressCallback fun(progress: number)? +---@field powerBuilderCallback fun() local buildMode = new("ControlHost"):ControlHost() local function InsertIfNew(t, val) @@ -1351,7 +1355,7 @@ function buildMode:OnFrame(inputEvents) self.controls.breakdown:SetBreakdownData(unpack(self.breakdownInputs)) end self:RefreshStatList() - self.configTab.calcFunc, self.configTab.calcBase = self.calcsTab:GetMiscCalculator(self) + self.configTab.calcFunc, self.configTab.calcBase = self.calcsTab:GetMiscCalculator() end if main.showThousandsSeparators ~= self.lastShowThousandsSeparators then self:RefreshStatList() diff --git a/src/Modules/CalcActiveSkill.lua b/src/Modules/CalcActiveSkill.lua index 8e821a387d..e8365205a4 100644 --- a/src/Modules/CalcActiveSkill.lua +++ b/src/Modules/CalcActiveSkill.lua @@ -143,6 +143,7 @@ end -- Create an active skill using the given active gem and list of support gems -- It will determine the base flag set, and check which of the support gems can support this skill function calcs.createActiveSkill(activeEffect, supportList, env, actor, socketGroup, summonSkill) + ---@class ActiveSkill local activeSkill = { activeEffect = activeEffect, supportList = supportList, @@ -162,7 +163,9 @@ function calcs.createActiveSkill(activeEffect, supportList, env, actor, socketGr end -- Initialise skill flag set ('attack', 'projectile', etc) - local statSet, skillFlags + ---@class SkillFlags + local skillFlags + local statSet if env.mode == "CALCS" then statSet = activeEffect.grantedEffect.statSets[activeEffect.statSetCalcs.index] skillFlags = statSet and copyTable(statSet.baseFlags) or { } @@ -672,6 +675,7 @@ function calcs.buildActiveSkillModList(env, activeSkill) effectiveRange = env.configInput.enemyDistance or env.configPlaceholder.enemyDistance -- Build config structure for modifier searches + ---@class ModCfg activeSkill.skillCfg = { flags = bor(skillModFlags, activeSkill.weapon1Flags or activeSkill.weapon2Flags or 0), keywordFlags = skillKeywordFlags, diff --git a/src/Modules/CalcBase.lua b/src/Modules/CalcBase.lua index cf23cec318..391aeda567 100644 --- a/src/Modules/CalcBase.lua +++ b/src/Modules/CalcBase.lua @@ -2,3 +2,92 @@ ---@class Calcs local calcs = {} return calcs + +---@class Output +---@field MainHand Output +---@field OffHand Output +---@field Minion Output? +---@field ActivePhantasmLimit number? +---@field ActiveSpectreLimit number? +---@field BattleCryExertsCount number? +---@field BattleMageCryCastTime number? +---@field BattleMageCryCooldown number? +---@field BattleMageCryDuration number? +---@field BattlemageUpTimeRatio number? +---@field BleedDamage number? +---@field ChaosHitAverage number? +---@field ChaosResist number? +---@field ColdHitAverage number? +---@field ColdResistOverCap number? +---@field ColdResistTotal number? +---@field CullMultiplier number? +---@field Dex number? +---@field EffectiveBlockChance number? +---@field EffectiveProjectileBlockChance number? +---@field EffectiveSpellBlockChance number? +---@field EffectiveSpellProjectileBlockChance number? +---@field EnergyShieldLeechDuration number? +---@field EnergyShieldRecoupRecoveryAvg number? +---@field EnergyShieldRegenRecovery number? +---@field ESCost number? +---@field FireHitAverage number? +---@field FireResistOverCap number? +---@field FireResistTotal number? +---@field FreezeChanceOnCrit number? +---@field FreezeChanceOnHit number? +---@field GlobalWarcryUptimeRatio number? +---@field IgniteAvoidChance number? +---@field IgniteChanceOnCrit number? +---@field IgniteChanceOnHit number? +---@field InfernalCryCastTime number? +---@field InfernalCryCooldown number? +---@field InfernalCryDuration number? +---@field InfernalExertsCount number? +---@field InfernalUpTimeRatio number? +---@field Int number? +---@field LifeCancellableReservation number? +---@field LifeCost number? +---@field LifeLeechDuration number? +---@field LifeRecoupRecoveryAvg number? +---@field LifeRegenRecovery number? +---@field LifeReservedPercent number? +---@field LifeUnreserved number? +---@field LightningHitAverage number? +---@field LightningResist number? +---@field LightningResistOverCap number? +---@field LightningResistTotal number? +---@field ManaCost number? +---@field ManaCostRaw number? +---@field ManaHasCost boolean? +---@field ManaLeechDuration number? +---@field ManaRecoupRecoveryAvg number? +---@field ManaRegenRecovery number? +---@field ManaUnreserved number? +---@field PhysicalTakenDamage number? +---@field PhysicalTakenHit number? +---@field PoisonAvoidChance number? +---@field RageCost number? +---@field ReservationDpsMultiplier number? +---@field ReturnChance number? +---@field SelfIgniteDuration number? +---@field SelfIgniteEffect number? +---@field SelfPoisonDuration number? +---@field SelfPoisonEffect number? +---@field Str number? +---@field TotalVaalRejuvenationTotemLife number? +---@field TotemChaosResist number? +---@field TotemLife number? + +---@class Breakdown +---@field MainHand Breakdown? +---@field OffHand Breakdown? + +---@class Actor +---@field output Output +---@field modDB ModDB +---@field enemy Actor? +---@field breakdown? Breakdown? + +---@class ActiveSkill +---@field skillModList ModList +---@field skillCfg ModCfg diff --git a/src/Modules/CalcBreakdown.lua b/src/Modules/CalcBreakdown.lua index 63c38bb120..eabb0d2bc6 100644 --- a/src/Modules/CalcBreakdown.lua +++ b/src/Modules/CalcBreakdown.lua @@ -14,7 +14,8 @@ local m_max = math.max local s_format = string.format return function(modDB, output, actor) - local breakdown = { } + ---@class Breakdown + local breakdown = {} function breakdown.multiChain(out, chain) local base = (chain.base and chain.base[2]) or nil diff --git a/src/Modules/CalcDefence.lua b/src/Modules/CalcDefence.lua index 3efeeab9f0..4e7e4b44a6 100644 --- a/src/Modules/CalcDefence.lua +++ b/src/Modules/CalcDefence.lua @@ -430,6 +430,7 @@ end ---@param actor table actor (with output and modDB) for which to calculate the damage ---@return number, table sum of damages and a table of taken damage parts function calcs.takenHitFromDamage(rawDamage, damageType, actor) + ---@class Output local output = actor.output local modDB = actor.modDB local function damageMitigationMultiplierForType(damage, type) @@ -469,6 +470,7 @@ end ---@param actor table actor (with output and modDB) for which to calculate the pools ---@return table pools reduced by damage function calcs.reducePoolsByDamage(poolTable, damageTable, actor) + ---@class Output local output = actor.output local modDB = actor.modDB local poolTbl = poolTable or { } @@ -766,7 +768,9 @@ end function calcs.defence(env, actor) local modDB = actor.modDB local enemyDB = actor.enemy.modDB + ---@class Output local output = actor.output + ---@class Breakdown local breakdown = actor.breakdown local condList = modDB.conditions @@ -829,6 +833,7 @@ function calcs.defence(env, actor) end end + ---@alias MinMaxTotalBreakdownResist [string, string, string] -- Resistances output["PhysicalResist"] = 0 @@ -2032,7 +2037,9 @@ end function calcs.buildDefenceEstimations(env, actor) local modDB = actor.modDB local enemyDB = actor.enemy.modDB + ---@class Output local output = actor.output + ---@class Breakdown local breakdown = actor.breakdown local condList = modDB.conditions diff --git a/src/Modules/CalcOffence.lua b/src/Modules/CalcOffence.lua index 0c1f70b40e..bcb2940da3 100644 --- a/src/Modules/CalcOffence.lua +++ b/src/Modules/CalcOffence.lua @@ -64,6 +64,7 @@ local damageStatsForTypes = setmetatable({ }, { __index = function(t, k) end }) local globalOutput = nil +---@type Breakdown? local globalBreakdown = nil local function calcConvertedDamage(activeSkill, output, cfg, damageType) @@ -380,10 +381,15 @@ function calcSkillDuration(skillModList, skillCfg, skillData, env, enemyDB) end -- Performs all offensive calculations +---@param env Env +---@param actor Actor +---@param activeSkill ActiveSkill function calcs.offence(env, actor, activeSkill) local modDB = actor.modDB local enemyDB = actor.enemy.modDB + ---@class Output local output = actor.output + ---@class Breakdown local breakdown = actor.breakdown local skillModList = activeSkill.skillModList @@ -2557,7 +2563,11 @@ function calcs.offence(env, actor, activeSkill) -- Calculate how often you hit (speed, accuracy, block, etc) for _, pass in ipairs(passList) do globalOutput, globalBreakdown = output, breakdown - local source, output, cfg, breakdown = pass.source, pass.output, pass.cfg, pass.breakdown + local source = pass.source + ---@class Output + local output = pass.output + local cfg = pass.cfg + local breakdown = pass.breakdown if skillData.averageBurstHits then output.AverageBurstHits = skillData.averageBurstHits @@ -3201,7 +3211,12 @@ function calcs.offence(env, actor, activeSkill) --Calculate damage (exerts, crits, ruthless, DPS, etc) for _, pass in ipairs(passList) do globalOutput, globalBreakdown = output, breakdown - local source, output, cfg, breakdown = pass.source, pass.output, pass.cfg, pass.breakdown + local source = pass.source + ---@class Output + local output = pass.output + local cfg = pass.cfg + ---@class Breakdown + local breakdown = pass.breakdown -- Exerted Attack members local exertedDoubleDamage = env.modDB:Sum("BASE", cfg, "ExertDoubleDamageChance") @@ -4860,7 +4875,12 @@ function calcs.offence(env, actor, activeSkill) -- Calculate ailments and debuffs (poison, bleed, ignite, impale, exposure, etc) for _, pass in ipairs(passList) do globalOutput, globalBreakdown = output, breakdown - local source, output, cfg, breakdown = pass.source, pass.output, pass.cfg, pass.breakdown + local source = pass.source + ---@class Output + local output = pass.output + local cfg = pass.cfg + ---@class Breakdown + local breakdown = pass.breakdown -- Legacy PoE1 ailments (to be removed later): Scorched, Brittle, Sapped, Impale output.ImpaleChance = 0 diff --git a/src/Modules/CalcPerform.lua b/src/Modules/CalcPerform.lua index ac1c64b710..f40a1c719c 100644 --- a/src/Modules/CalcPerform.lua +++ b/src/Modules/CalcPerform.lua @@ -216,7 +216,9 @@ end ---@param actor table local function doActorAttribsConditions(env, actor) local modDB = actor.modDB + ---@class Output local output = actor.output + ---@class Breakdown local breakdown = actor.breakdown local condList = modDB.conditions @@ -579,6 +581,7 @@ end local function doActorMisc(env, actor) local modDB = actor.modDB local enemyDB = actor.enemy.modDB + ---@class Output local output = actor.output local condList = modDB.conditions @@ -853,6 +856,7 @@ end -- Process charges local function doActorCharges(env, actor) local modDB = actor.modDB + ---@class Output local output = actor.output -- Calculate current and maximum charges @@ -1179,7 +1183,8 @@ function calcs.perform(env, skipEHP) end env.player.output = { } - env.enemy.output = { } + env.enemy.output = {} + ---@class Output local output = env.player.output env.partyMembers = env.build.partyTab.actor diff --git a/src/Modules/CalcSetup.lua b/src/Modules/CalcSetup.lua index 7f0f8a2fde..f4e236f2a5 100644 --- a/src/Modules/CalcSetup.lua +++ b/src/Modules/CalcSetup.lua @@ -622,6 +622,7 @@ local function addBestSupport(supportEffect, appliedSupportList, mode) end end +---@alias CalcEnvMode "MAIN"|"CALCS"|"EFFECTIVE"|"COMBAT"|"BUFFED"|"CALCULATOR" -- Initialise environment: -- 1. Initialises the player and enemy modifier databases -- 2. Merges modifiers for all items @@ -629,6 +630,14 @@ end -- 4. Merges modifiers for all allocated passive nodes -- 5. Builds a list of active skills and their supports (calcs.createActiveSkill) -- 6. Builds modifier lists for all active skills (calcs.buildActiveSkillModList) +---@param build Build +---@param mode CalcEnvMode +---@param override CalcOverride? +---@param specEnv any? +---@return Env +---@return ModDB? cachedPlayerDB +---@return ModDB? cachedEnemyDB +---@return ModDB? cachedMinionDB function calcs.initEnv(build, mode, override, specEnv) ClearMatchKeywordFlagsCache() -- accelerator variables @@ -645,6 +654,8 @@ function calcs.initEnv(build, mode, override, specEnv) local classStats = nil if not env then + ---@class Env + ---@field minion Actor? env = { } env.build = build env.data = build.data diff --git a/src/Modules/CalcTriggers.lua b/src/Modules/CalcTriggers.lua index 79800b5e5f..91a1a75534 100644 --- a/src/Modules/CalcTriggers.lua +++ b/src/Modules/CalcTriggers.lua @@ -138,7 +138,9 @@ local function helmetFocusHandler(env) if not env.player.mainSkill.skillFlags.minion and not env.player.mainSkill.skillFlags.disable and env.player.mainSkill.triggeredBy then local triggerName = "Focus" env.player.mainSkill.skillData.triggered = true + ---@class Output local output = env.player.output + ---@class Breakdown local breakdown = env.player.breakdown local triggerCD = env.player.mainSkill.triggeredBy.grantedEffect.levels[env.player.mainSkill.triggeredBy.level].cooldown local triggeredCD = env.player.mainSkill.skillData.cooldown @@ -225,6 +227,7 @@ local function CWCHandler(env) local source = nil local triggerName = "Cast While Channeling" local output = env.player.output + ---@class Breakdown local breakdown = env.player.breakdown for _, skill in ipairs(env.player.activeSkillList) do local match1 = env.player.mainSkill.activeEffect.grantedEffect.fromItem and skill.socketGroup and skill.socketGroup.slot == env.player.mainSkill.socketGroup.slot @@ -386,6 +389,7 @@ end local function defaultTriggerHandler(env, config) local actor = config.actor local output = config.actor.output + ---@class Breakdown local breakdown = config.actor.breakdown local source = config.source local triggeredSkills = config.triggeredSkills or {} diff --git a/src/Modules/Calcs.lua b/src/Modules/Calcs.lua index d6142af6c8..8534668208 100644 --- a/src/Modules/Calcs.lua +++ b/src/Modules/Calcs.lua @@ -70,57 +70,22 @@ local function infoDump(env) prettyPrintTable(env.player.output) end --- Generate a function for calculating the effect of some modification to the environment -local function getCalculator(build, fullInit, modFunc) - -- Initialise environment - local env, cachedPlayerDB, cachedEnemyDB, cachedMinionDB = calcs.initEnv(build, "CALCULATOR") - - -- Run base calculation pass - calcs.perform(env) - local fullDPS = calcs.calcFullDPS(build, "CALCULATOR", {}, { cachedPlayerDB = cachedPlayerDB, cachedEnemyDB = cachedEnemyDB, cachedMinionDB = cachedMinionDB, env = nil }) - env.player.output.SkillDPS = fullDPS.skills - env.player.output.FullDPS = fullDPS.combinedDPS - env.player.output.FullDotDPS = fullDPS.TotalDotDPS - local baseOutput = env.player.output - - env.modDB.parent = cachedPlayerDB - env.enemyDB.parent = cachedEnemyDB - if cachedMinionDB then - env.minion.modDB.parent = cachedMinionDB - end - return function(...) - -- Remove mods added during the last pass - wipeTable(env.modDB.mods) - wipeTable(env.modDB.conditions) - wipeTable(env.modDB.multipliers) - wipeTable(env.enemyDB.mods) - wipeTable(env.enemyDB.conditions) - wipeTable(env.enemyDB.multipliers) - - -- Call function to make modifications to the environment - modFunc(env, ...) - - -- Run calculation pass - calcs.perform(env) - fullDPS = calcs.calcFullDPS(build, "CALCULATOR", {}, { cachedPlayerDB = cachedPlayerDB, cachedEnemyDB = cachedEnemyDB, cachedMinionDB = cachedMinionDB, env = nil}) - env.player.output.SkillDPS = fullDPS.skills - env.player.output.FullDPS = fullDPS.combinedDPS - env.player.output.FullDotDPS = fullDPS.TotalDotDPS - - return env.player.output - end, baseOutput -end - --- Get fast calculator for adding tree node modifiers -function calcs.getNodeCalculator(build) - return getCalculator(build, true, function(env, nodeList) - -- Build and merge modifiers for these nodes - env.modDB:AddList(calcs.buildModListForNodeList(env, nodeList)) - end) -end +---@class CalcOverride +---@field spec PassiveSpec? +---@field addNodes table? A set of passive nodes. Only keyed by node id for anointed nodes. +---@field removeNodes table? A set of passive nodes. Only keyed by node id for anointed nodes. +---@field repSlotName string? The name of the replaced item slot +---@field repItem Item? +---@field toggleFlask Item? Item object used as a table key. +---@field toggleTincture Item? Item object used as a table key. +---@field conditions string[]? +---@field extraJewelFuncs ModList? -- Get calculator for other changes (adding/removing nodes, items, gems, etc) +---@param build Build +---@return fun(override?: CalcOverride, useFullDPS?: boolean): Output calcFunc +---@return Output output function calcs.getMiscCalculator(build) -- Run base calculation pass local env, cachedPlayerDB, cachedEnemyDB, cachedMinionDB = calcs.initEnv(build, "CALCULATOR") diff --git a/src/Modules/Data.lua b/src/Modules/Data.lua index 781832d686..c5c3c6ff1a 100644 --- a/src/Modules/Data.lua +++ b/src/Modules/Data.lua @@ -117,16 +117,18 @@ for k, v in pairs(miscData) do data[k] = v end ----@class StatTable +---@alias TransformFunc fun(in: number|string): (number|string)? +---@class PowerStat ---@field stat? string stat ID ---@field label string A short description of the stat ----@field transform fun(in: number|string): number|string A function to e.g. invert the value, if the stat represents something where lower is better +---@field transform? fun(in: number|string): number|string A function to e.g. invert the value, if the stat represents something where lower is better ---@field combinedOffDef? boolean ---@field ignoreForNodes? boolean ---@field ignoreForItems? boolean ---@field reverseSort? boolean +---@field itemField string? ----@type StatTable[] +---@type PowerStat[] data.powerStatList = { { stat=nil, label="Offence/Defence", combinedOffDef=true, ignoreForItems=true }, { stat=nil, label="Name", itemField="Name", ignoreForNodes=true, reverseSort=true, transform=function(value) return value:gsub("^The ","") end}, @@ -182,7 +184,7 @@ data.powerStatList = { } ---@param output any Calc output ----@param statTable StatTable Table with stats as in data.powerStatList +---@param statTable PowerStat Table with stats as in data.powerStatList ---@param skipTransform? boolean Whether the stat transform should be skipped. This is useful if you want to e.g. divide two less is better stats ---@return number function data.powerStatList.GetFromOutput(output, statTable, skipTransform) diff --git a/src/Modules/Main.lua b/src/Modules/Main.lua index 7cd2b2a3c1..9a94174612 100644 --- a/src/Modules/Main.lua +++ b/src/Modules/Main.lua @@ -147,8 +147,10 @@ function main:Init() self:ChangeUserPath(self.userPath, ignoreBuild) end - self.uniqueDB = { list = { }, loading = true } - self.rareDB = { list = { }, loading = true } + ---@type ItemDBData + self.uniqueDB = { list = {}, byTitle = {}, loading = true } + ---@type ItemDBData + self.rareDB = { list = {}, loading = true } local function loadItemDBs() for type, typeList in pairsYield(data.uniques) do diff --git a/src/Modules/ModTools.lua b/src/Modules/ModTools.lua index b71a2e1ca9..ad75d08c4d 100644 --- a/src/Modules/ModTools.lua +++ b/src/Modules/ModTools.lua @@ -17,6 +17,18 @@ local bor = OR64 -- bit.bor modLib = { } +--- "Flag" is only used with CanNotUseItem +---@alias Doubled ["MORE", "OVERRIDE"] +---@alias NumericModTypes "INC"|"MORE"|"BASE"|"OVERRIDE"|"MAX"|"CHANCE"|"DUMMY"|"Flag"|"MIN"|Doubled + +-- Massive discriminated union. Todo: probably has to be built with an LLM for a start +---@class ModTag +---@field type string + +---@overload fun(modName: string, modType: NumericModTypes, modVal?: number, sourceOrTag: string|ModTag?, flagsOrModTag: number|ModTag?, keywordFlagsOrModTag: number|ModTag?, ...: ModTag) +---@overload fun(modName: string, modType: "FLAG", modVal: boolean, sourceOrModTag: string|ModTag?, flagsOrModTag: number|ModTag?, keywordFlagsOrModTag: number|ModTag?, ...: ModTag) +---@overload fun(modName: string, modType: "LIST", modVal: any[]|any, sourceOrModTag: string|ModTag?, flagsOrModTag: number|ModTag?, keywordFlagsOrModTag: number|ModTag?, ...: ModTag) +---@return Mod function modLib.createMod(modName, modType, modVal, ...) local flags = 0 local keywordFlags = 0 @@ -34,6 +46,14 @@ function modLib.createMod(modName, modType, modVal, ...) keywordFlags = select(3, ...) tagStart = 4 end + ---@class Mod + ---@field name string + ---@field type NumericModTypes|"FLAG"|"LIST" + ---@field value number|boolean|any Number for numeric mod types, boolean for FLAG, any for LIST + ---@field flags number + ---@field keywordFlags number + ---@field source? string + ---@field [integer] ModTag return { name = modName, type = modType, From ab54f6d4eab064ae026d3a8f1d0a93adbb531108 Mon Sep 17 00:00:00 2001 From: LocalIdentity Date: Sun, 30 Aug 2026 00:51:49 +1000 Subject: [PATCH 2/2] Fix inaccurate PoE 2 type hints Add the missing AnchorPoint enum and generic Prop type definitions. Allow control anchors to use a Control, ControlHost, or no parent. Pass nil when creating CalcSectionControl without a parent control. Mark optional UI fields such as label, slotLabel, and forceTooltip correctly. Mark optional callbacks and conversion functions correctly. Correct passive tree types, including integer node IDs, optional background data, and nullable node comparisons. Mark main-hand and off-hand calculation outputs as optional. Restrict CalcEnvMode to the modes actually accepted by initEnv. Correct the calculator callback name from toggleTincture to toggleCharm. Mark optional calculator callback arguments correctly. Remove unused or invalid declarations such as byTitle, TransformFunc, points, and Doubled. --- src/Classes/CalcSectionControl.lua | 2 +- src/Classes/Control.lua | 5 ++++- src/Classes/ItemDBControl.lua | 1 - src/Classes/ItemSlotControl.lua | 2 +- src/Classes/LabelControl.lua | 2 +- src/Classes/ListControl.lua | 2 +- src/Classes/PassiveSpec.lua | 2 +- src/Classes/PassiveTree.lua | 5 ++--- src/Classes/PassiveTreeView.lua | 2 +- src/Modules/Build.lua | 2 +- src/Modules/CalcBase.lua | 4 ++-- src/Modules/CalcSetup.lua | 2 +- src/Modules/Calcs.lua | 4 ++-- src/Modules/Data.lua | 1 - src/Modules/Main.lua | 2 +- src/Modules/ModTools.lua | 3 +-- 16 files changed, 20 insertions(+), 21 deletions(-) diff --git a/src/Classes/CalcSectionControl.lua b/src/Classes/CalcSectionControl.lua index 85441eaa01..66dea3cb87 100644 --- a/src/Classes/CalcSectionControl.lua +++ b/src/Classes/CalcSectionControl.lua @@ -16,7 +16,7 @@ local CalcSectionClass = newClass("CalcSectionControl", "Control", "ControlHost" ---@param subSection any ---@param updateFunc any function CalcSectionClass:CalcSectionControl(calcsTab, width, id, group, colour, subSection, updateFunc) - self:Control(calcsTab, {0, 0, width, 0}) + self:Control(nil, {0, 0, width, 0}) self:ControlHost() self.calcsTab = calcsTab self.id = id diff --git a/src/Classes/Control.lua b/src/Classes/Control.lua index 5aadf03667..9e59aab634 100644 --- a/src/Classes/Control.lua +++ b/src/Classes/Control.lua @@ -6,6 +6,7 @@ local t_insert = table.insert local m_floor = math.floor +---@enum (key) AnchorPoint local anchorPos = { ["TOPLEFT"] = { 0 , 0 }, ["TOP"] = { 0.5, 0 }, @@ -45,7 +46,9 @@ local rect = { ---@field collapseX number? An additional offset which is applied when this control uses a collapsed anchor. local ControlClass = newClass("Control") ----@alias Anchor [AnchorPoint, Control|ControlHost, AnchorPoint, boolean|nil] +---@generic T +---@alias Prop (fun(self: self): T) | T +---@alias Anchor [AnchorPoint, Control|ControlHost|nil, AnchorPoint, boolean|nil] ---@alias Rect [Prop?,Prop?, Prop?, Prop?] ---@param anchor? Anchor diff --git a/src/Classes/ItemDBControl.lua b/src/Classes/ItemDBControl.lua index 8fe05db24f..fbb004f766 100644 --- a/src/Classes/ItemDBControl.lua +++ b/src/Classes/ItemDBControl.lua @@ -15,7 +15,6 @@ local ItemDBClass = newClass("ItemDBControl", "ListControl") ---@class ItemDBData ---@field list table ----@field byTitle? table ---@field loading boolean? ---@param anchor Anchor? diff --git a/src/Classes/ItemSlotControl.lua b/src/Classes/ItemSlotControl.lua index 1cf2b54f7a..640b2c9277 100644 --- a/src/Classes/ItemSlotControl.lua +++ b/src/Classes/ItemSlotControl.lua @@ -17,7 +17,7 @@ local ItemSlotClass = newClass("ItemSlotControl", "DropDownControl") ---@param y Prop ---@param itemsTab ItemsTab ---@param slotName string ----@param slotLabel string +---@param slotLabel? string ---@param nodeId integer? function ItemSlotClass:ItemSlotControl(anchor, x, y, itemsTab, slotName, slotLabel, nodeId) self:DropDownControl(anchor, {x, y, 310, 20}, { }, function(index, value) diff --git a/src/Classes/LabelControl.lua b/src/Classes/LabelControl.lua index f684cfcd32..194f4d7ded 100644 --- a/src/Classes/LabelControl.lua +++ b/src/Classes/LabelControl.lua @@ -8,7 +8,7 @@ local LabelClass = newClass("LabelControl", "Control") ---@param anchor? Anchor ---@param rect? Rect ----@param label Prop +---@param label? Prop function LabelClass:LabelControl(anchor, rect, label) self:Control(anchor, rect) self.label = label diff --git a/src/Classes/ListControl.lua b/src/Classes/ListControl.lua index 60f2b6fcd7..1ffc492acb 100644 --- a/src/Classes/ListControl.lua +++ b/src/Classes/ListControl.lua @@ -40,7 +40,7 @@ local ListClass = newClass("ListControl", "Control", "ControlHost") ---@param scroll "HORIZONTAL"|"VERTICAL"|boolean|nil ---@param isMutable boolean? ---@param list any[]? ----@param forceTooltip any +---@param forceTooltip? any function ListClass:ListControl(anchor, rect, rowHeight, scroll, isMutable, list, forceTooltip) self:Control(anchor, rect) self:ControlHost() diff --git a/src/Classes/PassiveSpec.lua b/src/Classes/PassiveSpec.lua index 79fd637493..636204787e 100644 --- a/src/Classes/PassiveSpec.lua +++ b/src/Classes/PassiveSpec.lua @@ -29,7 +29,7 @@ local PassiveSpecClass = newClass("PassiveSpec", "UndoHandler") ---@param build Build ---@param treeVersion any ----@param convert any +---@param convert? any function PassiveSpecClass:PassiveSpec(build, treeVersion, convert) self:UndoHandler() diff --git a/src/Classes/PassiveTree.lua b/src/Classes/PassiveTree.lua index c0622749bf..9b08e54b7e 100644 --- a/src/Classes/PassiveTree.lua +++ b/src/Classes/PassiveTree.lua @@ -39,8 +39,8 @@ end ---@field x number ---@field y number ---@field orbits integer[] ----@field nodes string[] ----@field background any +---@field nodes integer[] +---@field background any? ---@field isProxy boolean? ---@class PassiveTree ---@field classes any[] A list of classes on the tree @@ -54,7 +54,6 @@ end ---@field max_x integer ---@field max_y integer ---@field constants table ----@field points table local PassiveTreeClass = newClass("PassiveTree") function PassiveTreeClass:PassiveTree(treeVersion) diff --git a/src/Classes/PassiveTreeView.lua b/src/Classes/PassiveTreeView.lua index b36251c96b..86ffcd4659 100644 --- a/src/Classes/PassiveTreeView.lua +++ b/src/Classes/PassiveTreeView.lua @@ -140,7 +140,7 @@ end -- Returns the draw color for a node when compare overlay is active. -- Handles diff coloring for allocated/unallocated, mastery changes, and jewel socket differences. ---@param node Node ----@param compareNode Node +---@param compareNode Node? ---@param spec PassiveSpec ---@param build Build ---@param nodeDefaultColor any diff --git a/src/Modules/Build.lua b/src/Modules/Build.lua index 8d00ac7b52..aec7c05ded 100644 --- a/src/Modules/Build.lua +++ b/src/Modules/Build.lua @@ -20,7 +20,7 @@ end ---@class Build: ControlHost ---@field spec PassiveSpec added by TreeTab ---@field powerBuilderProgressCallback fun(progress: number)? ----@field powerBuilderCallback fun() +---@field powerBuilderCallback fun()? local buildMode = new("ControlHost"):ControlHost() local function InsertIfNew(t, val) diff --git a/src/Modules/CalcBase.lua b/src/Modules/CalcBase.lua index 391aeda567..939ec803bd 100644 --- a/src/Modules/CalcBase.lua +++ b/src/Modules/CalcBase.lua @@ -4,8 +4,8 @@ local calcs = {} return calcs ---@class Output ----@field MainHand Output ----@field OffHand Output +---@field MainHand Output? +---@field OffHand Output? ---@field Minion Output? ---@field ActivePhantasmLimit number? ---@field ActiveSpectreLimit number? diff --git a/src/Modules/CalcSetup.lua b/src/Modules/CalcSetup.lua index f4e236f2a5..0d1188d628 100644 --- a/src/Modules/CalcSetup.lua +++ b/src/Modules/CalcSetup.lua @@ -622,7 +622,7 @@ local function addBestSupport(supportEffect, appliedSupportList, mode) end end ----@alias CalcEnvMode "MAIN"|"CALCS"|"EFFECTIVE"|"COMBAT"|"BUFFED"|"CALCULATOR" +---@alias CalcEnvMode "MAIN"|"CALCS"|"CALCULATOR" -- Initialise environment: -- 1. Initialises the player and enemy modifier databases -- 2. Merges modifiers for all items diff --git a/src/Modules/Calcs.lua b/src/Modules/Calcs.lua index 8534668208..69378e3f51 100644 --- a/src/Modules/Calcs.lua +++ b/src/Modules/Calcs.lua @@ -78,13 +78,13 @@ end ---@field repSlotName string? The name of the replaced item slot ---@field repItem Item? ---@field toggleFlask Item? Item object used as a table key. ----@field toggleTincture Item? Item object used as a table key. +---@field toggleCharm Item? Item object used as a table key. ---@field conditions string[]? ---@field extraJewelFuncs ModList? -- Get calculator for other changes (adding/removing nodes, items, gems, etc) ---@param build Build ----@return fun(override?: CalcOverride, useFullDPS?: boolean): Output calcFunc +---@return fun(override?: CalcOverride, useFullDPS?: boolean, fastCalcOptions?: table): Output calcFunc ---@return Output output function calcs.getMiscCalculator(build) -- Run base calculation pass diff --git a/src/Modules/Data.lua b/src/Modules/Data.lua index c5c3c6ff1a..a5f6bdb379 100644 --- a/src/Modules/Data.lua +++ b/src/Modules/Data.lua @@ -117,7 +117,6 @@ for k, v in pairs(miscData) do data[k] = v end ----@alias TransformFunc fun(in: number|string): (number|string)? ---@class PowerStat ---@field stat? string stat ID ---@field label string A short description of the stat diff --git a/src/Modules/Main.lua b/src/Modules/Main.lua index 9a94174612..d4cbb8e2cc 100644 --- a/src/Modules/Main.lua +++ b/src/Modules/Main.lua @@ -148,7 +148,7 @@ function main:Init() end ---@type ItemDBData - self.uniqueDB = { list = {}, byTitle = {}, loading = true } + self.uniqueDB = { list = {}, loading = true } ---@type ItemDBData self.rareDB = { list = {}, loading = true } diff --git a/src/Modules/ModTools.lua b/src/Modules/ModTools.lua index ad75d08c4d..b115fe8f4e 100644 --- a/src/Modules/ModTools.lua +++ b/src/Modules/ModTools.lua @@ -18,8 +18,7 @@ local bor = OR64 -- bit.bor modLib = { } --- "Flag" is only used with CanNotUseItem ----@alias Doubled ["MORE", "OVERRIDE"] ----@alias NumericModTypes "INC"|"MORE"|"BASE"|"OVERRIDE"|"MAX"|"CHANCE"|"DUMMY"|"Flag"|"MIN"|Doubled +---@alias NumericModTypes "INC"|"MORE"|"BASE"|"OVERRIDE"|"MAX"|"CHANCE"|"DUMMY"|"Flag"|"MIN" -- Massive discriminated union. Todo: probably has to be built with an LLM for a start ---@class ModTag