diff --git a/src/Classes/BuildListControl.lua b/src/Classes/BuildListControl.lua index 4e32355fd0..41142778d6 100644 --- a/src/Classes/BuildListControl.lua +++ b/src/Classes/BuildListControl.lua @@ -10,6 +10,9 @@ local buildListHelpers = LoadModule("Modules/BuildListHelpers") ---@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 7f35a78715..aa924ea3f9 100644 --- a/src/Classes/CalcBreakdownControl.lua +++ b/src/Classes/CalcBreakdownControl.lua @@ -16,6 +16,7 @@ local band = 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 35e6d2696a..e0d34ee3a3 100644 --- a/src/Classes/CalcSectionControl.lua +++ b/src/Classes/CalcSectionControl.lua @@ -10,6 +10,13 @@ local m_min = math.min ---@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 7af7c72e63..7e035f5a22 100644 --- a/src/Classes/CalcsTab.lua +++ b/src/Classes/CalcsTab.lua @@ -467,8 +467,10 @@ function CalcsTabClass:BuildOutput() end -- Retrieve calculator functions - self.nodeCalculator = { self.calcs.getNodeCalculator(self.build) } - self.miscCalculator = { self.calcs.getMiscCalculator(self.build) } + local nodeCalcFunc, nodeCalcBase = self.calcs.getNodeCalculator(self.build) + self.nodeCalculator = { nodeCalcFunc, nodeCalcBase } + local miscCalcFunc, miscCalcBase = self.calcs.getMiscCalculator(self.build) + self.miscCalculator = { miscCalcFunc, miscCalcBase } end -- Controls the coroutine that calculates node power @@ -496,6 +498,10 @@ end function CalcsTabClass:PowerBuilder() -- local timer_start = GetTime() local useFullDPS = self.powerStat and self.powerStat.stat == "FullDPS" + ---@type CalcOverride + local override = { + repItem + } local calcFunc, calcBase = self:GetMiscCalculator() local cache = { } local distanceMap = { } @@ -757,12 +763,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 9979e581ff..85a25aa65d 100644 --- a/src/Classes/ConfigTab.lua +++ b/src/Classes/ConfigTab.lua @@ -12,9 +12,14 @@ local s_upper = string.upper local varList = LoadModule("Modules/ConfigOptions") local configVisibility = LoadModule("Modules/ConfigVisibility") ----@class CustomModBlock: ControlHost, Control +---@class CustomModBlockControl: ControlHost, Control local CustomModBlockClass = newClass("CustomModBlockControl", "ControlHost", "Control") +---@param anchor Anchor +---@param rect Rect +---@param configTab ConfigTab +---@param blockIndex integer +---@param blockData any function CustomModBlockClass:CustomModBlockControl(anchor, rect, configTab, blockIndex, blockData) self:Control(anchor, rect) self:ControlHost() diff --git a/src/Classes/Control.lua b/src/Classes/Control.lua index d8d2cd4ee3..e26d3ba6c9 100644 --- a/src/Classes/Control.lua +++ b/src/Classes/Control.lua @@ -41,13 +41,15 @@ local rect = { ---@field shown Prop ---@field x Prop? ---@field y Prop? +---@field width Prop? +---@field height Prop? local ControlClass = newClass("Control") ----@alias ControlAnchor [AnchorPoint, Control|ControlHost, AnchorPoint, boolean|nil] ----@alias ControlRect [number|nil, number|nil, number|nil, number] +---@alias Anchor [AnchorPoint, Control|ControlHost, AnchorPoint, boolean|nil] +---@alias Rect [Prop?,Prop?, Prop?, Prop?] ----@param anchor? ControlAnchor ----@param rect? ControlRect +---@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) diff --git a/src/Classes/GemSelectControl.lua b/src/Classes/GemSelectControl.lua index a65c2ded38..09a98b896b 100644 --- a/src/Classes/GemSelectControl.lua +++ b/src/Classes/GemSelectControl.lua @@ -18,8 +18,8 @@ local imbuedTooltipText = "\"Socketed in\" item must be set in order to add an i ---@class GemSelectControl: EditControl local GemSelectClass = newClass("GemSelectControl", "EditControl") ----@param anchor ControlAnchor ----@param rect ControlRect +---@param anchor Anchor +---@param rect Rect ---@param skillsTab SkillsTab ---@param index integer ---@param changeFunc fun(...) diff --git a/src/Classes/ImportTab.lua b/src/Classes/ImportTab.lua index 12f99be6b2..31c2631d16 100644 --- a/src/Classes/ImportTab.lua +++ b/src/Classes/ImportTab.lua @@ -1108,7 +1108,7 @@ end --- @class CharacterPassives ---- @field mastery_effects table +--- @field mastery_effects table --- @field skill_overrides table --- @field jewel_data table --- @field hashes_ex integer[] @@ -1119,10 +1119,10 @@ end --- @field alternate_ascendancy string | integer integer on website, string on oauth -- https://www.pathofexile.com/developer/docs/reference#type-Item ---- @alias Item any +--- @alias GGGItem any --- @class CharacterPassivesData : CharacterBasicData ---- @field jewels Item[] +--- @field jewels GGGItem[] --- @field passives CharacterPassives --- @param charData CharacterPassivesData --- @param deleteJewels boolean diff --git a/src/Classes/Item.lua b/src/Classes/Item.lua index 3197074d83..4a8527e040 100644 --- a/src/Classes/Item.lua +++ b/src/Classes/Item.lua @@ -110,6 +110,7 @@ for _, curInfluenceInfo in ipairs(influenceInfo) do influenceItemMap[curInfluenceInfo.display.." Item"] = curInfluenceInfo.key end +---@enum (key) LineFlags local lineFlags = { ["crafted"] = true, ["crucible"] = true, @@ -406,6 +407,19 @@ function ItemClass:NormaliseVariantSelections() end end +---@class ModLine A modifier line on an item. An in-game mod can translate to multiple ModLines. +---@field modList Mod[] +---@field line string The actual text for the line. This might describe a range of values, in which case applyRange() can be used with this and the range value to get a ranged line. +---@field range number? +---@field extra string? +---@field valueScalar number? +---@field [LineFlags] boolean? +---@field modTags string[]? +---@field variantList table? +---@field versionList table? +---@field variantGroupList table? +---@field modId string? + -- Parse raw item data and extract item name, base type, quality, and modifiers function ItemClass:ParseRaw(raw, rarity, highQuality) self.raw = raw @@ -472,11 +486,16 @@ function ItemClass:ParseRaw(raw, rarity, highQuality) self.sockets = { } self.classRequirementModLines = { } self.buffModLines = { } + ---@type ModLine[] self.enchantModLines = { } - self.scourgeModLines = { } - self.implicitModLines = { } - self.explicitModLines = { } - self.crucibleModLines = { } + ---@type ModLine[] + self.scourgeModLines = {} + ---@type ModLine[] + self.implicitModLines = {} + ---@type ModLine[] + self.explicitModLines = {} + ---@type ModLine[] + self.crucibleModLines = {} -- old items or trade-sourced items have increases to modifiers baked in to the item text, which -- means that we can't add e.g. quality or mod magnitude effect to them during parsing. we will -- assume an item to be an advanced copy format if either has mod roll information, a modifier @@ -849,6 +868,7 @@ function ItemClass:ParseRaw(raw, rarity, highQuality) gameModeStage = "EXPLICIT" end if not specName or foundExplicit or foundImplicit then + ---@type ModLine local modLine = { modTags = {} } line = line:gsub("{(%a*):?([^}]*)}", function(k,val) diff --git a/src/Classes/ItemDBControl.lua b/src/Classes/ItemDBControl.lua index 609aa5a3aa..33c7f22baa 100644 --- a/src/Classes/ItemDBControl.lua +++ b/src/Classes/ItemDBControl.lua @@ -13,6 +13,15 @@ local m_floor = math.floor ---@class ItemDBControl: ListControl local ItemDBClass = newClass("ItemDBControl", "ListControl") +---@class ItemDBData +---@field list Item[] +---@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 0360eaee88..aa4877dada 100644 --- a/src/Classes/ItemListControl.lua +++ b/src/Classes/ItemListControl.lua @@ -10,6 +10,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 90bf611c00..aab90d55d7 100644 --- a/src/Classes/ItemSlotControl.lua +++ b/src/Classes/ItemSlotControl.lua @@ -11,6 +11,13 @@ local itemSlotHelper = LoadModule("Modules/ItemSlotHelper") ---@class ItemSlotControl 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/ItemsTab.lua b/src/Classes/ItemsTab.lua index 3ae6e046aa..0583e38c0e 100644 --- a/src/Classes/ItemsTab.lua +++ b/src/Classes/ItemsTab.lua @@ -4308,6 +4308,9 @@ local function cloneSpecForJewelComparison(spec) return specCopy end +---@param itemsTab ItemsTab +---@param compareSlot ItemSlotControl +---@param replacementItem Item local function buildSpecForJewelComparison(itemsTab, compareSlot, replacementItem) local tempItemId local spec = cloneSpecForJewelComparison(itemsTab.build.spec) diff --git a/src/Classes/LabelControl.lua b/src/Classes/LabelControl.lua index afedc6fdf3..a8ff45838c 100644 --- a/src/Classes/LabelControl.lua +++ b/src/Classes/LabelControl.lua @@ -6,8 +6,8 @@ ---@class LabelControl: Control local LabelClass = newClass("LabelControl", "Control") ----@param anchor? ControlAnchor ----@param rect? ControlRect +---@param anchor? Anchor +---@param rect? Rect ---@param label string function LabelClass:LabelControl(anchor, rect, label) self:Control(anchor, rect) diff --git a/src/Classes/ListControl.lua b/src/Classes/ListControl.lua index 47dd9a8f90..e9b3ef6fa5 100644 --- a/src/Classes/ListControl.lua +++ b/src/Classes/ListControl.lua @@ -30,9 +30,16 @@ local m_min = math.min local m_max = math.max local m_floor = math.floor ----@class ListControl: Control, ControlHost +---@class ListControl: Control, ControlHost local ListClass = newClass("ListControl", "Control", "ControlHost") +---@param anchor Anchor +---@param rect Rect +---@param rowHeight number +---@param scroll "HORIZONTAL"|"VERTICAL"|nil +---@param isMutable boolean? +---@param list T[]? +---@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 4310fe1002..1fbd0d0809 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? + ---@class ModStore local ModStoreClass = newClass("ModStore") @@ -151,6 +157,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 @@ -162,6 +172,9 @@ function ModStoreClass:Sum(modType, cfg, ...) return self:SumInternal(self, modType, cfg, flags, keywordFlags, source, ...) end +---@param cfg? ModCfg +---@param ... string +---@return number function ModStoreClass:More(cfg, ...) local flags, keywordFlags = 0, 0 local source @@ -184,6 +197,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 @@ -195,6 +211,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 @@ -208,6 +227,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 @@ -262,14 +285,25 @@ 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) return self.conditions[var] or (self.parent and self.parent:GetCondition(var, cfg, true)) or (not noMod and self:Flag(cfg, conditionName[var])) 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) -- Checks if any buff in buffList matches -- Was needed for skills that provide multiple buffs (e.g. Herald of Agony) and can't be accesses with `buffList[1]` @@ -321,6 +355,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 4216c22be6..8253f4a471 100644 --- a/src/Classes/NotableDBControl.lua +++ b/src/Classes/NotableDBControl.lua @@ -21,6 +21,7 @@ end ---@class NotableDBControl : ListControl local NotableDBClass = newClass("NotableDBControl", "ListControl") +---@param itemsTab ItemsTab function NotableDBClass:NotableDBControl(anchor, rect, itemsTab, db, dbType) self:ListControl(anchor, rect, 16, "VERTICAL", false) self.itemsTab = itemsTab diff --git a/src/Classes/PassiveMasteryControl.lua b/src/Classes/PassiveMasteryControl.lua index 87242b0cb5..fded4d26b8 100644 --- a/src/Classes/PassiveMasteryControl.lua +++ b/src/Classes/PassiveMasteryControl.lua @@ -12,6 +12,16 @@ 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 diff --git a/src/Classes/PassiveSpec.lua b/src/Classes/PassiveSpec.lua index cd16dd659f..78f394433a 100644 --- a/src/Classes/PassiveSpec.lua +++ b/src/Classes/PassiveSpec.lua @@ -17,8 +17,13 @@ local band = bit.band local bor = bit.bor ---@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() @@ -46,6 +51,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 b6a705b0be..9dd6826a86 100644 --- a/src/Classes/PassiveTree.lua +++ b/src/Classes/PassiveTree.lua @@ -56,12 +56,13 @@ end ---@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, any> +---@field nodes table<"root"|integer, Node> ---@field jewelSlots integer[] ---@field min_x integer ---@field min_y integer @@ -517,7 +518,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 -- Migration... if versionNum < 3.10 then -- To new format diff --git a/src/Classes/PassiveTreeView.lua b/src/Classes/PassiveTreeView.lua index 17a0310241..a8f85883ae 100644 --- a/src/Classes/PassiveTreeView.lua +++ b/src/Classes/PassiveTreeView.lua @@ -167,6 +167,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 @@ -1314,6 +1319,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 = 12 self.zoom = 1.2 ^ self.zoomLevel @@ -1400,6 +1406,9 @@ function PassiveTreeViewClass:DoesNodeMatchSearchParams(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.recipe) @@ -1460,6 +1469,9 @@ function PassiveTreeViewClass:AddNodeName(tooltip, node, build) end end +---@param tooltip Tooltip +---@param node Node +---@param build Build function PassiveTreeViewClass:AddNodeTooltip(tooltip, node, build) local fontSizeBig = main.showFlavourText and 18 or 16 self.skillTooltip:Clear() diff --git a/src/Classes/SharedItemListControl.lua b/src/Classes/SharedItemListControl.lua index a4891b368f..05aa4943c7 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 13237af9bd..bf8349dec0 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 a9d181aa60..2dd39d578d 100644 --- a/src/Classes/SkillSetListControl.lua +++ b/src/Classes/SkillSetListControl.lua @@ -11,6 +11,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 28494df3c2..d8788b3cf3 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 7ea2fcedf0..ba830a13ac 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 dcfbc74e89..8a6349c20b 100644 --- a/src/Modules/Build.lua +++ b/src/Modules/Build.lua @@ -17,6 +17,7 @@ local s_format = string.format ---@class Build: ControlHost ---@field spec PassiveSpec added by TreeTab +---@field powerBuilderProgressCallback fun(progress: number) ---@field powerBuilderCallback fun() local buildMode = new("ControlHost"):ControlHost() @@ -1251,7 +1252,7 @@ function buildMode:OnFrame(inputEvents) self.skillsTab:UpdateSocketGroups() self.calcsTab:BuildOutput() 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 4821e7a2da..d89f13d0c9 100644 --- a/src/Modules/CalcActiveSkill.lua +++ b/src/Modules/CalcActiveSkill.lua @@ -81,6 +81,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, actor, socketGroup, summonSkill) + ---@class ActiveSkill local activeSkill = { activeEffect = activeEffect, supportList = supportList, @@ -100,6 +101,7 @@ function calcs.createActiveSkill(activeEffect, supportList, actor, socketGroup, end -- Initialise skill flag set ('attack', 'projectile', etc) + ---@class SkillFlags local skillFlags = copyTable(activeGrantedEffect.baseFlags) activeSkill.skillFlags = skillFlags skillFlags.hit = skillFlags.hit or activeSkill.skillTypes[SkillType.Attack] or activeSkill.skillTypes[SkillType.Damage] or activeSkill.skillTypes[SkillType.Projectile] @@ -452,6 +454,7 @@ function calcs.buildActiveSkillModList(env, activeSkill) end -- 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 d32ceb4182..756fb5609b 100644 --- a/src/Modules/CalcBreakdown.lua +++ b/src/Modules/CalcBreakdown.lua @@ -11,6 +11,7 @@ local m_sqrt = math.sqrt local s_format = string.format return function(modDB, output, actor) + ---@class Breakdown local breakdown = {} function breakdown.multiChain(out, chain) diff --git a/src/Modules/CalcDefence.lua b/src/Modules/CalcDefence.lua index 036d8e5c05..46549db47a 100644 --- a/src/Modules/CalcDefence.lua +++ b/src/Modules/CalcDefence.lua @@ -148,6 +148,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) @@ -187,6 +188,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 { } @@ -478,6 +480,7 @@ end -- Performs defensive calculations used by conditionals function calcs.defenceForConditionals(env, actor) local modDB = actor.modDB + ---@class Output local output = actor.output -- Armour defence types for conditionals @@ -504,10 +507,24 @@ function calcs.defenceForConditionals(env, actor) end end +---@class MinMaxTotalBreakdownResist +---@field min string min % +---@field max string max % +---@field total string total % -- Performs resistance calculations function calcs.resistances(actor) local modDB = actor.modDB + ---@class Output local output = actor.output + ---@class Breakdown + ---@field FireResist MinMaxTotalBreakdownResist? + ---@field ColdResist MinMaxTotalBreakdownResist? + ---@field LightningResist MinMaxTotalBreakdownResist? + ---@field ChaosResist MinMaxTotalBreakdownResist? + ---@field TotemFireResist MinMaxTotalBreakdownResist? + ---@field TotemColdResist MinMaxTotalBreakdownResist? + ---@field TotemLightningResist MinMaxTotalBreakdownResist? + ---@field TotemChaosResist MinMaxTotalBreakdownResist? local breakdown = actor.breakdown output["PhysicalResist"] = 0 @@ -637,7 +654,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 @@ -1636,7 +1655,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 3fd3f028e3..5bd1bada11 100644 --- a/src/Modules/CalcOffence.lua +++ b/src/Modules/CalcOffence.lua @@ -63,6 +63,7 @@ local damageStatsForTypes = setmetatable({ }, { __index = function(t, k) end }) local globalOutput = nil +---@class Breakdown? local globalBreakdown = nil -- Calculate min/max damage for the given damage type @@ -321,10 +322,15 @@ function calcs.calcTotemLife(env, activeSkill) 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 @@ -2111,7 +2117,10 @@ 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 if skillData.averageBurstHits then output.AverageBurstHits = skillData.averageBurstHits @@ -2524,7 +2533,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") @@ -4045,7 +4059,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 do -- Perfect Agony local handCondition = pass.label == "Off Hand" and { type = "Condition", var = "OffHandAttack" } or pass.label == "Main Hand" and { type = "Condition", var = "MainHandAttack" } or nil diff --git a/src/Modules/CalcPerform.lua b/src/Modules/CalcPerform.lua index 95e90c3825..f1578e6d51 100644 --- a/src/Modules/CalcPerform.lua +++ b/src/Modules/CalcPerform.lua @@ -68,7 +68,9 @@ end function doActorLifeMana(actor) local modDB = actor.modDB + ---@class Output local output = actor.output + ---@class Breakdown local breakdown = actor.breakdown local condList = modDB.conditions @@ -135,7 +137,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 @@ -528,6 +532,7 @@ end ---@param actor table function doActorLifeManaReservation(actor, addAura) local modDB = actor.modDB + ---@class Output local output = actor.output local condList = modDB.conditions @@ -613,6 +618,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 @@ -947,6 +953,7 @@ end -- Process charges local function doActorCharges(env, actor) local modDB = actor.modDB + ---@class Output local output = actor.output -- Calculate current and maximum charges @@ -1270,7 +1277,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 5b2d481a3c..e56006fc40 100644 --- a/src/Modules/CalcSetup.lua +++ b/src/Modules/CalcSetup.lua @@ -367,6 +367,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 @@ -374,6 +375,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 @@ -390,6 +399,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 b3da5f8733..27c470a538 100644 --- a/src/Modules/CalcTriggers.lua +++ b/src/Modules/CalcTriggers.lua @@ -137,7 +137,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 @@ -223,6 +225,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 slotMatch = slotMatch(env, skill) @@ -391,6 +394,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 917b29d35d..08cec202a1 100644 --- a/src/Modules/Calcs.lua +++ b/src/Modules/Calcs.lua @@ -120,7 +120,21 @@ function calcs.getNodeCalculator(build) 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 30202c4609..7e60c5d568 100644 --- a/src/Modules/Data.lua +++ b/src/Modules/Data.lua @@ -115,7 +115,7 @@ for k, v in pairs(miscData) do end ---@alias TransformFunc fun(in: number|string): (number|string)? ----@class StatTable +---@class PowerStat ---@field stat? string stat ID ---@field label string A short description of the stat ---@field transform TransformFunc?: number|string A function to e.g. invert the value, if the stat represents something where lower is better @@ -123,8 +123,9 @@ end ---@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}, @@ -179,7 +180,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) @@ -252,7 +253,6 @@ data.misc = { -- magic numbers FortifyBaseDuration = 6, ManaRegenBase = data.characterConstants["mana_regeneration_rate_per_minute_%"] / 60 / 100, EnergyShieldRechargeBase = data.characterConstants["energy_shield_recharge_rate_per_minute_%"] / 60 / 100, - EnergyShieldRechargeBase = 0.33, EnergyShieldRechargeDelay = 2, WardRechargeDelay = 2, Transfiguration = 0.3, diff --git a/src/Modules/Main.lua b/src/Modules/Main.lua index dab3eb6d35..c95b2c61aa 100644 --- a/src/Modules/Main.lua +++ b/src/Modules/Main.lua @@ -155,8 +155,10 @@ function main:Init() self:ChangeUserPath(self.userPath, ignoreBuild) end + ---@type ItemDBData self.uniqueDB = { list = { }, loading = true } - self.rareDB = { list = { }, 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 361ea05547..c70fe526ec 100644 --- a/src/Modules/ModTools.lua +++ b/src/Modules/ModTools.lua @@ -22,9 +22,13 @@ modLib = { } ---@alias Doubled ["MORE", "OVERRIDE"] ---@alias NumericModTypes "INC"|"MORE"|"BASE"|"OVERRIDE"|"MAX"|"CHANCE"|"DUMMY"|"Flag"|"MIN"|Doubled ----@overload fun(modName: string, modType: NumericModTypes, modVal?: number) ----@overload fun(modName: string, modType: "FLAG", modVal: boolean) ----@overload fun(modName: string, modType: "LIST", modVal: any[]|any) +-- 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 @@ -44,6 +48,13 @@ function modLib.createMod(modName, modType, modVal, ...) 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,