diff --git a/src/Classes/PassiveTree.lua b/src/Classes/PassiveTree.lua index cf16ce0b1c..b1c6fe3e6b 100644 --- a/src/Classes/PassiveTree.lua +++ b/src/Classes/PassiveTree.lua @@ -232,7 +232,7 @@ function PassiveTreeClass:PassiveTree(treeVersion) if not self.assets then self.assets = require("TreeData.3_19.Assets") - self.assets = self.assets.assets + self.assets = copyTable(self.assets.assets, true) if self.alternate_ascendancies then -- backgrounds self.assets["ClassesPrimalist"] = {[0.3835]="https://web.poecdn.com/gen/image/WzIyLCJlMzIwYTYwYmNiZTY4ZmQ5YTc2NmE1ZmY4MzhjMDMyNCIseyJ0IjoyNywic3AiOjAuMzgzNX1d/3d68393250/ClassesPrimalist.png"} diff --git a/src/Modules/Build.lua b/src/Modules/Build.lua index d080d84c90..88d4ee8e0e 100644 --- a/src/Modules/Build.lua +++ b/src/Modules/Build.lua @@ -1752,7 +1752,12 @@ function buildMode:FormatStat(statData, statVal, overCapStatVal, colorOverride) end -- lazily index the calcs tab sections so that we can look up the matching --- sections by breakdown name +-- sections by breakdown name. this function works by iterating through calc +-- sections. it will link every breakdown key to the first found calc section +-- column (basically, a box). the result will contain references to this column +-- data and will also contain a set of mod names referred to by cells of said +-- box. if a cell shouldn't be picked, the field `skipSideBarIndex` can be set +-- on the cell. function buildMode:BuildBreakdownIndex() if self.breakdownIndex then return self.breakdownIndex @@ -1765,10 +1770,12 @@ function buildMode:BuildBreakdownIndex() -- cells for each mod name local modSectionsByName = {} local breakdownCells = {} - for _, row in ipairs(subSection.data) do + ---@type CalcSectionData + local subSectionData = subSection.data + for _, row in ipairs(subSectionData) do for _, colData in ipairs(row) do for _, cell in ipairs(colData) do - if cell.breakdown and not breakdownCells[cell.breakdown] then + if not cell.skipSideBarIndex and cell.breakdown and not breakdownCells[cell.breakdown] then breakdownCells[cell.breakdown] = colData end if cell.modName then diff --git a/src/Modules/BuildDisplayStats.lua b/src/Modules/BuildDisplayStats.lua index 421b77ec2f..950c579f09 100644 --- a/src/Modules/BuildDisplayStats.lua +++ b/src/Modules/BuildDisplayStats.lua @@ -13,6 +13,7 @@ local function maxHitSuffix(value, output) return value == math.huge and "Immune" or output.GuardSkillActive and "Guard" or nil end +local defenseIgnoredSections = { "Base from Gear", "Inc. from Tree" } ---@alias DisplayStatCondFunc fun(value: any, output: table):boolean? Show the row only when this returns truthy (usually receives the value and the actor output; the label-only variant receives output as its first arg) ---@alias DisplayStatWarnFunc fun(value: any, output: table):string|boolean|nil Returns a warning string to surface, or falsy for none @@ -173,7 +174,7 @@ local displayStats = { { }, -- the breakdown for armour, es and ev doesn't have anything relevant, and -- we are better off ignoring it and just showing relevant mods - { stat = "EnergyShield", label = "Energy Shield", fmt = "d", compactValue = true, color = colorCodes.ES, compPercent = true, breakdown = "", modNames = { "EnergyShield", "Defences" } }, + { stat = "EnergyShield", label = "Energy Shield", fmt = "d", compactValue = true, color = colorCodes.ES, compPercent = true, modNames = { "EnergyShield", "Defences" }, ignoredSections = defenseIgnoredSections }, { stat = "EnergyShieldRecoveryCap", label = "Recoverable ES", color = colorCodes.ES, fmt = "d", condFunc = function(v,o) return o.CappingES end }, { stat = "Spec:EnergyShieldInc", label = "%Inc ES from Tree", color = colorCodes.ES, fmt = "d%%" }, { stat = "EnergyShieldRegenRecovery", label = "ES Regen", color = colorCodes.ES, fmt = ".1f", condFunc = function(v,o) return o.EnergyShieldRecovery <= 0 and o.EnergyShieldRegenRecovery ~= 0 end }, @@ -181,7 +182,7 @@ local displayStats = { { stat = "EnergyShieldLeechGainRate", label = "ES Leech/On Hit Rate", color = colorCodes.ES, fmt = ".1f", compPercent = true }, { stat = "EnergyShieldLeechGainPerHit", label = "ES Leech/Gain per Hit", color = colorCodes.ES, fmt = ".1f", compPercent = true }, { }, - { stat = "Ward", label = "Ward", fmt = "d", compactValue = true, color = colorCodes.WARD, compPercent = true }, + { stat = "Ward", label = "Ward", fmt = "d", compactValue = true, color = colorCodes.WARD, compPercent = true, modNames = { "Ward" }, ignoredSections = defenseIgnoredSections }, { }, { stat = "Rage", label = "Rage", fmt = "d", color = colorCodes.RAGE, compPercent = true }, { stat = "RageRegenRecovery", label = "Rage Regen", fmt = ".1f", color = colorCodes.RAGE, compPercent = true }, @@ -192,13 +193,13 @@ local displayStats = { { stat = "NetManaRegen", label = "Net Mana Recovery", fmt = "+.1f", color = colorCodes.MANA }, { stat = "NetEnergyShieldRegen", label = "Net ES Recovery", fmt = "+.1f", color = colorCodes.ES }, { }, - { stat = "Evasion", label = "Evasion rating", fmt = "d", color = colorCodes.EVASION, compPercent = true, breakdown = "", modNames = { "Evasion", "ArmourAndEvasion", "Defences" } }, + { stat = "Evasion", label = "Evasion rating", fmt = "d", color = colorCodes.EVASION, compPercent = true, modNames = { "Evasion", "ArmourAndEvasion", "Defences" }, ignoredSections = defenseIgnoredSections }, { stat = "Spec:EvasionInc", label = "%Inc Evasion from Tree", color = colorCodes.EVASION, fmt = "d%%" }, { stat = "MeleeEvadeChance", label = "Evade Chance", fmt = "d%%", color = colorCodes.EVASION, condFunc = function(v,o) return v > 0 and o.MeleeEvadeChance == o.ProjectileEvadeChance end }, { stat = "MeleeEvadeChance", label = "Melee Evade Chance", fmt = "d%%", color = colorCodes.EVASION, condFunc = function(v,o) return v > 0 and o.MeleeEvadeChance ~= o.ProjectileEvadeChance end }, { stat = "ProjectileEvadeChance", label = "Projectile Evade Chance", fmt = "d%%", color = colorCodes.EVASION, condFunc = function(v,o) return v > 0 and o.MeleeEvadeChance ~= o.ProjectileEvadeChance end }, { }, - { stat = "Armour", label = "Armour", fmt = "d", compPercent = true, breakdown = "", modNames = { "Armour", "ArmourAndEvasion", "Defences" } }, + { stat = "Armour", label = "Armour", fmt = "d", compPercent = true, modNames = { "Armour", "ArmourAndEvasion", "Defences", "ArmourDefense" }, ignoredSections = defenseIgnoredSections }, { stat = "Spec:ArmourInc", label = "%Inc Armour from Tree", fmt = "d%%" }, { stat = "PhysicalDamageReduction", label = "Phys. Damage Reduction", fmt = "d%%", condFunc = function() return true end }, { }, @@ -272,7 +273,7 @@ local minionDisplayStats = { { stat = "Life", label = "Total Life", fmt = ".1f", compactValue = true, color = colorCodes.LIFE, compPercent = true, modNames = { "Life" }, ignoredSections = { "Base from Gear", "Inc. from Tree" } }, { stat = "LifeRegenRecovery", label = "Life Recovery", fmt = ".1f", color = colorCodes.LIFE }, { stat = "LifeLeechGainRate", label = "Life Leech/On Hit Rate", fmt = ".1f", color = colorCodes.LIFE, compPercent = true }, - { stat = "EnergyShield", label = "Energy Shield", fmt = "d", compactValue = true, color = colorCodes.ES, compPercent = true }, + { stat = "EnergyShield", label = "Energy Shield", fmt = "d", compactValue = true, color = colorCodes.ES, compPercent = true, modNames = { "EnergyShield", "Defences" }, ignoredSections = defenseIgnoredSections }, { stat = "EnergyShieldRegenRecovery", label = "ES Recovery", fmt = ".1f", color = colorCodes.ES }, { stat = "EnergyShieldLeechGainRate", label = "ES Leech/On Hit Rate", fmt = ".1f", color = colorCodes.ES, compPercent = true }, } diff --git a/src/Modules/CalcSections.lua b/src/Modules/CalcSections.lua index 5ddc7ca835..e6b2284aa5 100644 --- a/src/Modules/CalcSections.lua +++ b/src/Modules/CalcSections.lua @@ -64,6 +64,7 @@ local rageCost = { ---@field label? string Heading shown above the resulting table ---@field control? table Injected by calcs for e.g. the skill details ---@field controlName? string +---@field skipSideBarIndex boolean? Set to true if this cell should be ignored while indexing the side bar breakdowns, and a later breakdown source should be preferred. ---@class CalcSectionColumn : CalcSectionEntry One column cell: a format and descriptions for the popup ---@field [integer] CalcSectionEntry @@ -1575,7 +1576,7 @@ return { } }, { 1, "EnergyShield", 2, colorCodes.ES, {{ defaultCollapsed = false, label = "Energy Shield", data = { extra = "{0:output:EnergyShield}", - { label = "Base from Armours", { format = "{0:output:Gear:EnergyShield}", { breakdown = "EnergyShield", gearOnly = true }, }, }, + { label = "Base from Armours", { format = "{0:output:Gear:EnergyShield}", { breakdown = "EnergyShield", gearOnly = true, skipSideBarIndex = true }, }, }, { label = "Global Base", { format = "{0:mod:1}", { modName = "EnergyShield", modType = "BASE" }, }, }, { label = "Inc. from Tree", { format = "{0:mod:1}%", { modName = "EnergyShield", modType = "INC", modSource = "Tree" }, }, }, { label = "Total Increased", { format = "{0:mod:1}%", { modName = { "EnergyShield", "Defences" }, modType = "INC" }, }, }, @@ -1637,7 +1638,7 @@ return { } }, { 1, "Ward", 2, colorCodes.WARD, {{ defaultCollapsed = false, label = "Ward", data = { extra = "{0:output:Ward}", - { label = "Base from Armours", { format = "{0:output:Gear:Ward}", { breakdown = "Ward", gearOnly = true }, }, }, + { label = "Base from Armours", { format = "{0:output:Gear:Ward}", { breakdown = "Ward", gearOnly = true }, }, }, { label = "Global Base", { format = "{0:mod:1}", { modName = "Ward", modType = "BASE" }, }, }, { label = "Inc. from Tree", { format = "{0:mod:1}%", { modName = "Ward", modType = "INC", modSource = "Tree" }, }, }, { label = "Total Increased", { format = "{0:mod:1}%", { modName = { "Ward", "Defences" }, modType = "INC" }, }, }, @@ -1672,7 +1673,7 @@ return { } }, { 1, "Armour", 3, colorCodes.ARMOUR, {{ defaultCollapsed = false, label = "Armour", data = { extra = "{0:output:Armour}", - { label = "Base from Armours", { format = "{0:output:Gear:Armour}", { breakdown = "Armour", gearOnly = true }, }, }, + { label = "Base from Armours", { format = "{0:output:Gear:Armour}", { breakdown = "Armour", gearOnly = true, skipSideBarIndex = true, }, }, }, { label = "Global Base", { format = "{0:mod:1}", { modName = { "Armour", "ArmourAndEvasion" }, modType = "BASE" }, }, }, { label = "Inc. from Tree", { format = "{0:mod:1}%", { modName = { "Armour", "ArmourAndEvasion" }, modType = "INC", modSource = "Tree", }, }, }, { label = "Total Increased", { format = "{0:mod:1}%", { modName = { "Armour", "ArmourAndEvasion", "Defences" }, modType = "INC" }, }, }, @@ -1703,7 +1704,7 @@ return { } }, { 1, "Evasion", 3, colorCodes.EVASION, {{ defaultCollapsed = false, label = "Evasion", data = { extra = "{0:output:Evasion}", - { label = "Base from Armours", { format = "{0:output:Gear:Evasion}", { breakdown = "Evasion", gearOnly = true }, }, }, + { label = "Base from Armours", { format = "{0:output:Gear:Evasion}", { breakdown = "Evasion", gearOnly = true, skipSideBarIndex = true }, }, }, { label = "Global Base", { format = "{0:mod:1}", { modName = { "Evasion", "ArmourAndEvasion" }, modType = "BASE" }, }, }, { label = "Inc. from Tree", { format = "{0:mod:1}%", { modName = { "Evasion", "ArmourAndEvasion" }, modType = "INC", modSource = "Tree" }, }, }, { label = "Total Increased", { format = "{0:mod:1}%", { modName = { "Evasion", "ArmourAndEvasion", "Defences" }, modType = "INC" }, }, },