From 32e81e99a6e78f1c4c95ab5f10559956da99614e Mon Sep 17 00:00:00 2001 From: ken Date: Fri, 22 May 2026 18:19:22 -0500 Subject: [PATCH] Add sidebar stat suffixes and compact value formatting option Adds the ability to add a suffix to sidebar display Adds toggle in Options menu to compact values in sidebar display --- src/Modules/Build.lua | 51 +++++++++++++--- src/Modules/BuildDisplayStats.lua | 98 +++++++++++++++---------------- src/Modules/CalcPerform.lua | 1 + src/Modules/Main.lua | 14 +++++ 4 files changed, 107 insertions(+), 57 deletions(-) diff --git a/src/Modules/Build.lua b/src/Modules/Build.lua index b7376f5d6bb..fe744bb7fcd 100644 --- a/src/Modules/Build.lua +++ b/src/Modules/Build.lua @@ -10,6 +10,7 @@ local t_insert = table.insert local t_sort = table.sort local m_min = math.min local m_max = math.max +local m_huge = math.huge local m_floor = math.floor local m_abs = math.abs local s_format = string.format @@ -1195,6 +1196,9 @@ function buildMode:OnFrame(inputEvents) if main.thousandsSeparator ~= self.lastShowThousandsSeparator then self:RefreshStatList() end + if main.useCompactValues ~= self.lastUseCompactValues then + self:RefreshStatList() + end if main.decimalSeparator ~= self.lastShowDecimalSeparator then self:RefreshStatList() end @@ -1204,7 +1208,6 @@ function buildMode:OnFrame(inputEvents) -- Update contents of main skill dropdowns self:RefreshSkillSelectControls(self.controls, self.mainSocketGroup, "") - -- Draw contents of current tab local sideBarWidth = 312 local tabViewPort = { @@ -1587,11 +1590,32 @@ function buildMode:FormatStat(statData, statVal, overCapStatVal, colorOverride) color = colorCodes.NEGATIVE end - local valStr = s_format("%"..statData.fmt, val) - local number, suffix = valStr:match("^([%+%-]?%d+%.%d+)(%D*)$") - if number then - valStr = number:gsub("0+$", ""):gsub("%.$", "") .. suffix - end + local valStr + + if val == m_huge or val == -m_huge then + valStr = s_format("%"..statData.fmt, val) + elseif statData.compactValue and main.useCompactValues then + local absVal = m_abs(val) + + if absVal >= 1000000000 then + valStr = s_format("%.1fB", val / 1000000000) + elseif absVal >= 1000000 then + valStr = s_format("%.1fM", val / 1000000) + elseif absVal >= 10000 then + valStr = s_format("%.1fK", val / 1000) + else + valStr = formatNumSep(s_format("%"..statData.fmt, val)) + end + else + valStr = s_format("%"..statData.fmt, val) + local number, suffix = valStr:match("^([%+%-]?%d+%.%d+)(%D*)$") + if number then + valStr = number:gsub("0+$", ""):gsub("%.$", "") .. suffix + end + valStr = formatNumSep(valStr) +end + +valStr = color .. valStr valStr = color .. formatNumSep(valStr) if overCapStatVal and overCapStatVal > 0 then @@ -1601,6 +1625,7 @@ function buildMode:FormatStat(statData, statVal, overCapStatVal, colorOverride) self.lastShowThousandsSeparator = main.thousandsSeparator self.lastShowDecimalSeparator = main.decimalSeparator self.lastShowTitlebarName = main.showTitlebarName + self.lastUseCompactValues = main.useCompactValues return valStr end @@ -1621,6 +1646,10 @@ function buildMode:AddDisplayStatList(statList, actor) end if statVal and ((statData.condFunc and statData.condFunc(statVal,actor.output)) or (not statData.condFunc and statVal ~= 0)) then local overCapStatVal = actor.output[statData.overCapStat] or nil + -- Allow stats to suppress numeric overcap display in special cases, such as Chaos Inoculation. + if overCapStatVal and statData.overCapStatCondFunc and not statData.overCapStatCondFunc(statVal, actor.output) then + overCapStatVal = nil + end if statData.stat == "SkillDPS" then labelColor = colorCodes.CUSTOM table.sort(actor.output.SkillDPS, function(a,b) return (a.dps * a.count) > (b.dps * b.count) end) @@ -1636,7 +1665,7 @@ function buildMode:AddDisplayStatList(statList, actor) t_insert(statBoxList, { height = 16, lhsString, - self:FormatStat({fmt = "1.f"}, skillData.dps * skillData.count, overCapStatVal), + self:FormatStat({ fmt = ".1f", compactValue = statData.compactValue }, skillData.dps * skillData.count, overCapStatVal), }) if skillData.skillPart then t_insert(statBoxList, { @@ -1659,10 +1688,16 @@ function buildMode:AddDisplayStatList(statList, actor) if actor.output[statData.stat.."Warning"] or (statData.warnFunc and statData.warnFunc(statVal, actor.output) and statData.warnColor) then colorOverride = colorCodes.NEGATIVE end + -- Optional gray parenthetical text after a formatted stat, e.g. "100% (Immune)" or "2,759 (Guard)". + -- condFunc controls row visibility; suffixCondFunc only controls the suffix. + local formattedStat = self:FormatStat(statData, statVal, overCapStatVal, colorOverride) + if statData.suffix and (not statData.suffixCondFunc or statData.suffixCondFunc(statVal, actor.output)) then + formattedStat = formattedStat .. "^x808080" .. " (" .. statData.suffix .. ")" + end t_insert(statBoxList, { height = 16, labelColor..statData.label..":", - self:FormatStat(statData, statVal, overCapStatVal, colorOverride), + formattedStat, }) end end diff --git a/src/Modules/BuildDisplayStats.lua b/src/Modules/BuildDisplayStats.lua index 3eab844b527..45492f2995a 100644 --- a/src/Modules/BuildDisplayStats.lua +++ b/src/Modules/BuildDisplayStats.lua @@ -9,12 +9,12 @@ local displayStats = { { stat = "ActiveMinionLimit", label = "Active Minion Limit", fmt = "d" }, - { stat = "AverageHit", label = "Average Hit", fmt = ".1f", compPercent = true }, - { stat = "PvpAverageHit", label = "PvP Average Hit", fmt = ".1f", compPercent = true, flag = "isPvP" }, - { stat = "AverageDamage", label = "Average Damage", fmt = ".1f", compPercent = true, flag = "attack" }, - { stat = "AverageDamage", label = "Average Damage", fmt = ".1f", compPercent = true, flag = "monsterExplode", condFunc = function(v,o) return o.HitChance ~= 100 end }, - { stat = "AverageBurstDamage", label = "Average Burst Damage", fmt = ".1f", compPercent = true, condFunc = function(v,o) return o.AverageBurstHits and o.AverageBurstHits > 1 and v > 0 end }, - { stat = "PvpAverageDamage", label = "PvP Average Damage", fmt = ".1f", compPercent = true, flag = "attackPvP" }, + { stat = "AverageHit", label = "Average Hit", fmt = ".1f", compactValue = true, compPercent = true }, + { stat = "PvpAverageHit", label = "PvP Average Hit", fmt = ".1f", compactValue = true, compPercent = true, flag = "isPvP" }, + { stat = "AverageDamage", label = "Average Damage", fmt = ".1f", compactValue = true, compPercent = true, flag = "attack" }, + { stat = "AverageDamage", label = "Average Damage", fmt = ".1f", compactValue = true, compPercent = true, flag = "monsterExplode", condFunc = function(v,o) return o.HitChance ~= 100 end }, + { stat = "AverageBurstDamage", label = "Average Burst Damage", fmt = ".1f", compactValue = true, compPercent = true, condFunc = function(v,o) return o.AverageBurstHits and o.AverageBurstHits > 1 and v > 0 end }, + { stat = "PvpAverageDamage", label = "PvP Average Damage", fmt = ".1f", compactValue = true, compPercent = true, flag = "attackPvP" }, { stat = "Speed", label = "Attack Rate", fmt = ".2f", compPercent = true, flag = "attack", condFunc = function(v,o) return v > 0 and (o.TriggerTime or 0) == 0 end }, { stat = "Speed", label = "Cast Rate", fmt = ".2f", compPercent = true, flag = "spell", condFunc = function(v,o) return v > 0 and (o.TriggerTime or 0) == 0 end }, { stat = "Speed", label = "Effective Trigger Rate", fmt = ".2f", compPercent = true, notFlag = "skipEffectiveRate", condFunc = function(v,o) return (o.TriggerTime or 0) ~= 0 end }, @@ -33,37 +33,37 @@ local displayStats = { { stat = "CritMultiplier", label = "Crit Multiplier", fmt = "d%%", pc = true, condFunc = function(v,o) return (o.CritChance or 0) > 0 end }, { stat = "HitChance", label = "Hit Chance", fmt = ".0f%%", flag = "attack" }, { stat = "HitChance", label = "Hit Chance", fmt = ".0f%%", condFunc = function(v,o) return o.enemyHasSpellBlock end }, - { stat = "TotalDPS", label = "Hit DPS", fmt = ".1f", compPercent = true, flag = "notAverage" }, - { stat = "PvpTotalDPS", label = "PvP Hit DPS", fmt = ".1f", compPercent = true, flag = "notAveragePvP" }, - { stat = "TotalDPS", label = "Hit DPS", fmt = ".1f", compPercent = true, flag = "showAverage", condFunc = function(v,o) return (o.TriggerTime or 0) ~= 0 end }, - { stat = "TotalDot", label = "DoT DPS", fmt = ".1f", compPercent = true }, - { stat = "WithDotDPS", label = "Total DPS inc. DoT", fmt = ".1f", compPercent = true, flag = "notAverage", condFunc = function(v,o) return v ~= o.TotalDPS and (o.PoisonDPS or 0) == 0 and (o.IgniteDPS or 0) == 0 and (o.ImpaleDPS or 0) == 0 and (o.BleedDPS or 0) == 0 end }, - { stat = "BleedDPS", label = "Bleed DPS", fmt = ".1f", compPercent = true, warnFunc = function(v) return v >= data.misc.DotDpsCap and "Bleed DPS exceeds in game limit" end }, - { stat = "CorruptingBloodDPS", label = "Corrupting Blood DPS", fmt = ".1f", compPercent = true, warnFunc = function(v,o) return v >= data.misc.DotDpsCap and "Corrupting Blood DPS exceeds in game limit" end }, - { stat = "BleedDamage", label = "Total Damage per Bleed", fmt = ".1f", compPercent = true, flag = "showAverage" }, - { stat = "WithBleedDPS", label = "Total DPS inc. Bleed", fmt = ".1f", compPercent = true, flag = "notAverage", condFunc = function(v,o) return v ~= o.TotalDPS and (o.TotalDot or 0) == 0 and (o.PoisonDPS or 0) == 0 and (o.ImpaleDPS or 0) == 0 and (o.IgniteDPS or 0) == 0 end }, - { stat = "IgniteDPS", label = "Ignite DPS", fmt = ".1f", compPercent = true, warnFunc = function(v) return v >= data.misc.DotDpsCap and "Ignite DPS exceeds in game limit" end }, - { stat = "IgniteDamage", label = "Total Damage per Ignite", fmt = ".1f", compPercent = true, flag = "showAverage" }, - { stat = "BurningGroundDPS", label = "Burning Ground DPS", fmt = ".1f", compPercent = true, warnFunc = function(v,o) return v >= data.misc.DotDpsCap and "Burning Ground DPS exceeds in game limit" end }, - { stat = "MirageBurningGroundDPS", label = "Mirage Burning Ground DPS", fmt = ".1f", compPercent = true, condFunc = function(v,o) return v ~= o.BurningGroundDPS end, warnFunc = function(v,o) return v >= data.misc.DotDpsCap and "Mirage Burning Ground DPS exceeds in game limit" end }, - { stat = "WithIgniteDPS", label = "Total DPS inc. Ignite", fmt = ".1f", compPercent = true, flag = "notAverage", condFunc = function(v,o) return v ~= o.TotalDPS and (o.TotalDot or 0) == 0 and (o.PoisonDPS or 0) == 0 and (o.ImpaleDPS or 0) == 0 and (o.BleedDPS or 0) == 0 end }, - { stat = "WithIgniteAverageDamage", label = "Average Dmg. inc. Ignite", fmt = ".1f", compPercent = true }, - { stat = "PoisonDPS", label = "Single Poison DPS", fmt = ".1f", compPercent = true, warnFunc = function(v) return v >= data.misc.DotDpsCap and "Poison DPS exceeds in game limit" end }, - { stat = "CausticGroundDPS", label = "Caustic Ground DPS", fmt = ".1f", compPercent = true, warnFunc = function(v,o) return v >= data.misc.DotDpsCap and "Caustic Ground DPS exceeds in game limit" end }, - { stat = "MirageCausticGroundDPS", label = "Mirage Caustic Ground DPS", fmt = ".1f", compPercent = true, condFunc = function(v,o) return v ~= o.CausticGroundDPS end, warnFunc = function(v,o) return v >= data.misc.DotDpsCap and "Mirage Caustic Ground DPS exceeds in game limit" end }, - { stat = "PoisonDamage", label = "Total Damage per Poison", fmt = ".1f", compPercent = true }, - { stat = "WithPoisonDPS", label = "Total DPS inc. Poison", fmt = ".1f", compPercent = true, flag = "poison", flag = "notAverage", condFunc = function(v,o) return v ~= o.TotalDPS and (o.TotalDot or 0) == 0 and (o.IgniteDPS or 0) == 0 and (o.ImpaleDPS or 0) == 0 and (o.BleedDPS or 0) == 0 end }, - { stat = "DecayDPS", label = "Decay DPS", fmt = ".1f", compPercent = true }, - { stat = "TotalDotDPS", label = "Total DoT DPS", fmt = ".1f", compPercent = true, condFunc = function(v,o) return o.showTotalDotDPS or ( v ~= o.TotalDot and v ~= o.TotalPoisonDPS and v ~= o.CausticGroundDPS and v ~= (o.TotalIgniteDPS or o.IgniteDPS) and v ~= o.BurningGroundDPS and v ~= o.BleedDPS and v~= o.CorruptingBloodDPS and v ~= o.MirageCausticGroundDPS and v ~= o.MirageBurningGroundDPS) end, warnFunc = function(v) return v >= data.misc.DotDpsCap and "DoT DPS exceeds in game limit" end }, - { stat = "ImpaleDPS", label = "Impale Damage", fmt = ".1f", compPercent = true, flag = "impale", flag = "showAverage" }, - { stat = "WithImpaleDPS", label = "Damage inc. Impale", fmt = ".1f", compPercent = true, flag = "impale", flag = "showAverage", condFunc = function(v,o) return v ~= o.TotalDPS and (o.TotalDot or 0) == 0 and (o.IgniteDPS or 0) == 0 and (o.PoisonDPS or 0) == 0 and (o.BleedDPS or 0) == 0 end }, - { stat = "ImpaleDPS", label = "Impale DPS", fmt = ".1f", compPercent = true, flag = "impale", flag = "notAverage" }, - { stat = "WithImpaleDPS", label = "Total DPS inc. Impale", fmt = ".1f", compPercent = true, flag = "impale", flag = "notAverage", condFunc = function(v,o) return v ~= o.TotalDPS and (o.TotalDot or 0) == 0 and (o.IgniteDPS or 0) == 0 and (o.PoisonDPS or 0) == 0 and (o.BleedDPS or 0) == 0 end }, - { stat = "MirageDPS", label = "Total Mirage DPS", fmt = ".1f", compPercent = true, flag = "mirageArcher", condFunc = function(v,o) return v > 0 end }, - { stat = "MirageDPS", label = "Total Wisp DPS", fmt = ".1f", compPercent = true, flag = "wisp", condFunc = function(v,o) return v > 0 end }, - { stat = "CullingDPS", label = "Culling DPS", fmt = ".1f", compPercent = true, condFunc = function(v,o) return (o.CullingDPS or 0) > 0 end }, + { stat = "TotalDPS", label = "Hit DPS", fmt = ".1f", compactValue = true, compPercent = true, flag = "notAverage" }, + { stat = "PvpTotalDPS", label = "PvP Hit DPS", fmt = ".1f", compactValue = true, compPercent = true, flag = "notAveragePvP" }, + { stat = "TotalDPS", label = "Hit DPS", fmt = ".1f", compactValue = true, compPercent = true, flag = "showAverage", condFunc = function(v,o) return (o.TriggerTime or 0) ~= 0 end }, + { stat = "TotalDot", label = "DoT DPS", fmt = ".1f", compactValue = true, compPercent = true }, + { stat = "WithDotDPS", label = "Total DPS inc. DoT", fmt = ".1f", compactValue = true, compPercent = true, flag = "notAverage", condFunc = function(v,o) return v ~= o.TotalDPS and (o.PoisonDPS or 0) == 0 and (o.IgniteDPS or 0) == 0 and (o.ImpaleDPS or 0) == 0 and (o.BleedDPS or 0) == 0 end }, + { stat = "BleedDPS", label = "Bleed DPS", fmt = ".1f", compactValue = true, compPercent = true, warnFunc = function(v) return v >= data.misc.DotDpsCap and "Bleed DPS exceeds in game limit" end }, + { stat = "CorruptingBloodDPS", label = "Corrupting Blood DPS", compactValue = true, fmt = ".1f", compPercent = true, warnFunc = function(v,o) return v >= data.misc.DotDpsCap and "Corrupting Blood DPS exceeds in game limit" end }, + { stat = "BleedDamage", label = "Total Damage per Bleed", fmt = ".1f", compactValue = true, compPercent = true, flag = "showAverage" }, + { stat = "WithBleedDPS", label = "Total DPS inc. Bleed", fmt = ".1f", compactValue = true, compPercent = true, flag = "notAverage", condFunc = function(v,o) return v ~= o.TotalDPS and (o.TotalDot or 0) == 0 and (o.PoisonDPS or 0) == 0 and (o.ImpaleDPS or 0) == 0 and (o.IgniteDPS or 0) == 0 end }, + { stat = "IgniteDPS", label = "Ignite DPS", fmt = ".1f", compPercent = true, compactValue = true, warnFunc = function(v) return v >= data.misc.DotDpsCap and "Ignite DPS exceeds in game limit" end }, + { stat = "IgniteDamage", label = "Total Damage per Ignite", fmt = ".1f", compactValue = true, compPercent = true, flag = "showAverage" }, + { stat = "BurningGroundDPS", label = "Burning Ground DPS", fmt = ".1f", compactValue = true, compPercent = true, warnFunc = function(v,o) return v >= data.misc.DotDpsCap and "Burning Ground DPS exceeds in game limit" end }, + { stat = "MirageBurningGroundDPS", label = "Mirage Burning Ground DPS", compactValue = true, fmt = ".1f", compPercent = true, condFunc = function(v,o) return v ~= o.BurningGroundDPS end, warnFunc = function(v,o) return v >= data.misc.DotDpsCap and "Mirage Burning Ground DPS exceeds in game limit" end }, + { stat = "WithIgniteDPS", label = "Total DPS inc. Ignite", fmt = ".1f", compactValue = true, compPercent = true, flag = "notAverage", condFunc = function(v,o) return v ~= o.TotalDPS and (o.TotalDot or 0) == 0 and (o.PoisonDPS or 0) == 0 and (o.ImpaleDPS or 0) == 0 and (o.BleedDPS or 0) == 0 end }, + { stat = "WithIgniteAverageDamage", label = "Average Dmg. inc. Ignite", compactValue = true, fmt = ".1f", compPercent = true }, + { stat = "PoisonDPS", label = "Single Poison DPS", fmt = ".1f", compactValue = true, compPercent = true, warnFunc = function(v) return v >= data.misc.DotDpsCap and "Poison DPS exceeds in game limit" end }, + { stat = "CausticGroundDPS", label = "Caustic Ground DPS", fmt = ".1f", compactValue = true, compPercent = true, warnFunc = function(v,o) return v >= data.misc.DotDpsCap and "Caustic Ground DPS exceeds in game limit" end }, + { stat = "MirageCausticGroundDPS", label = "Mirage Caustic Ground DPS", compactValue = true, fmt = ".1f", compPercent = true, condFunc = function(v,o) return v ~= o.CausticGroundDPS end, warnFunc = function(v,o) return v >= data.misc.DotDpsCap and "Mirage Caustic Ground DPS exceeds in game limit" end }, + { stat = "PoisonDamage", label = "Total Damage per Poison", fmt = ".1f", compactValue = true, compPercent = true }, + { stat = "WithPoisonDPS", label = "Total DPS inc. Poison", fmt = ".1f", compactValue = true, compPercent = true, flag = "poison", flag = "notAverage", condFunc = function(v,o) return v ~= o.TotalDPS and (o.TotalDot or 0) == 0 and (o.IgniteDPS or 0) == 0 and (o.ImpaleDPS or 0) == 0 and (o.BleedDPS or 0) == 0 end }, + { stat = "DecayDPS", label = "Decay DPS", fmt = ".1f", compactValue = true, compPercent = true }, + { stat = "TotalDotDPS", label = "Total DoT DPS", fmt = ".1f", compactValue = true, compPercent = true, condFunc = function(v,o) return o.showTotalDotDPS or ( v ~= o.TotalDot and v ~= o.TotalPoisonDPS and v ~= o.CausticGroundDPS and v ~= (o.TotalIgniteDPS or o.IgniteDPS) and v ~= o.BurningGroundDPS and v ~= o.BleedDPS and v~= o.CorruptingBloodDPS and v ~= o.MirageCausticGroundDPS and v ~= o.MirageBurningGroundDPS) end, warnFunc = function(v) return v >= data.misc.DotDpsCap and "DoT DPS exceeds in game limit" end }, + { stat = "ImpaleDPS", label = "Impale Damage", fmt = ".1f", compactValue = true, compPercent = true, flag = "impale", flag = "showAverage" }, + { stat = "WithImpaleDPS", label = "Damage inc. Impale", fmt = ".1f", compactValue = true, compPercent = true, flag = "impale", flag = "showAverage", condFunc = function(v,o) return v ~= o.TotalDPS and (o.TotalDot or 0) == 0 and (o.IgniteDPS or 0) == 0 and (o.PoisonDPS or 0) == 0 and (o.BleedDPS or 0) == 0 end }, + { stat = "ImpaleDPS", label = "Impale DPS", fmt = ".1f", compactValue = true, compPercent = true, flag = "impale", flag = "notAverage" }, + { stat = "WithImpaleDPS", label = "Total DPS inc. Impale", compactValue = true, fmt = ".1f", compPercent = true, flag = "impale", flag = "notAverage", condFunc = function(v,o) return v ~= o.TotalDPS and (o.TotalDot or 0) == 0 and (o.IgniteDPS or 0) == 0 and (o.PoisonDPS or 0) == 0 and (o.BleedDPS or 0) == 0 end }, + { stat = "MirageDPS", label = "Total Mirage DPS", fmt = ".1f", compactValue = true, compPercent = true, flag = "mirageArcher", condFunc = function(v,o) return v > 0 end }, + { stat = "MirageDPS", label = "Total Wisp DPS", fmt = ".1f", compactValue = true, compPercent = true, flag = "wisp", condFunc = function(v,o) return v > 0 end }, + { stat = "CullingDPS", label = "Culling DPS", fmt = ".1f", compactValue = true, compPercent = true, condFunc = function(v,o) return (o.CullingDPS or 0) > 0 end }, { stat = "ReservationDPS", label = "Reservation DPS", fmt = ".1f", compPercent = true, condFunc = function(v,o) return (o.ReservationDPS or 0) > 0 end }, - { stat = "CombinedDPS", label = "Combined DPS", fmt = ".1f", compPercent = true, flag = "notAverage", condFunc = function(v,o) return v ~= ((o.TotalDPS or 0) + (o.TotalDot or 0)) and v ~= o.WithImpaleDPS and ( o.showTotalDotDPS or ( v ~= o.WithPoisonDPS and v ~= o.WithIgniteDPS and v ~= o.WithBleedDPS ) ) end }, + { stat = "CombinedDPS", label = "Combined DPS", fmt = ".1f", compactValue = true, compPercent = true, flag = "notAverage", condFunc = function(v,o) return v ~= ((o.TotalDPS or 0) + (o.TotalDot or 0)) and v ~= o.WithImpaleDPS and ( o.showTotalDotDPS or ( v ~= o.WithPoisonDPS and v ~= o.WithIgniteDPS and v ~= o.WithBleedDPS ) ) end }, { stat = "CombinedAvg", label = "Combined Total Damage", fmt = ".1f", compPercent = true, flag = "showAverage", condFunc = function(v,o) return (v ~= o.AverageDamage and (o.TotalDot or 0) == 0) and (v ~= o.WithPoisonDPS or v ~= o.WithIgniteDPS or v ~= o.WithBleedDPS) end }, { stat = "ExplodeChance", label = "Total Explode Chance", fmt = ".0f%%" }, { stat = "CombinedAvgToMonsterLife", label = "Enemy Life Equivalent", fmt = ".1f%%" }, @@ -100,14 +100,14 @@ local displayStats = { { }, { stat = "Devotion", label = "Devotion", color = colorCodes.RARE, fmt = "d" }, { }, - { stat = "TotalEHP", label = "Effective Hit Pool", fmt = ".0f", compPercent = true }, - { stat = "PvPTotalTakenHit", label = "PvP Hit Taken", fmt = ".1f", flag = "isPvP", lowerIsBetter = true }, - { stat = "PhysicalMaximumHitTaken", label = "Phys Max Hit", fmt = ".0f", color = colorCodes.PHYS, compPercent = true, }, - { stat = "LightningMaximumHitTaken", label = "Elemental Max Hit", fmt = ".0f", color = colorCodes.LIGHTNING, compPercent = true, condFunc = function(v,o) return o.LightningMaximumHitTaken == o.ColdMaximumHitTaken and o.LightningMaximumHitTaken == o.FireMaximumHitTaken end }, - { stat = "FireMaximumHitTaken", label = "Fire Max Hit", fmt = ".0f", color = colorCodes.FIRE, compPercent = true, condFunc = function(v,o) return o.LightningMaximumHitTaken ~= o.ColdMaximumHitTaken or o.LightningMaximumHitTaken ~= o.FireMaximumHitTaken end }, - { stat = "ColdMaximumHitTaken", label = "Cold Max Hit", fmt = ".0f", color = colorCodes.COLD, compPercent = true, condFunc = function(v,o) return o.LightningMaximumHitTaken ~= o.ColdMaximumHitTaken or o.LightningMaximumHitTaken ~= o.FireMaximumHitTaken end }, - { stat = "LightningMaximumHitTaken", label = "Lightning Max Hit", fmt = ".0f", color = colorCodes.LIGHTNING, compPercent = true, condFunc = function(v,o) return o.LightningMaximumHitTaken ~= o.ColdMaximumHitTaken or o.LightningMaximumHitTaken ~= o.FireMaximumHitTaken end }, - { stat = "ChaosMaximumHitTaken", label = "Chaos Max Hit", fmt = ".0f", color = colorCodes.CHAOS, compPercent = true }, + { stat = "TotalEHP", label = "Effective Hit Pool", fmt = ".0f", suffix = "Guard", compactValue = true,compPercent = true, suffixCondFunc = function(v,o) return o.GuardSkillActive end }, + { stat = "PvPTotalTakenHit", label = "PvP Hit Taken", fmt = ".1f", flag = "isPvP", compactValue = true, lowerIsBetter = true }, + { stat = "PhysicalMaximumHitTaken", label = "Phys Max Hit", fmt = ".0f", compactValue = true, color = colorCodes.PHYS, compPercent = true, }, + { stat = "LightningMaximumHitTaken", label = "Elemental Max Hit", fmt = ".0f", compactValue = true, color = colorCodes.LIGHTNING, compPercent = true, condFunc = function(v,o) return o.LightningMaximumHitTaken == o.ColdMaximumHitTaken and o.LightningMaximumHitTaken == o.FireMaximumHitTaken end }, + { stat = "FireMaximumHitTaken", label = "Fire Max Hit", fmt = ".0f", compactValue = true, color = colorCodes.FIRE, compPercent = true, condFunc = function(v,o) return o.LightningMaximumHitTaken ~= o.ColdMaximumHitTaken or o.LightningMaximumHitTaken ~= o.FireMaximumHitTaken end }, + { stat = "ColdMaximumHitTaken", label = "Cold Max Hit", fmt = ".0f", compactValue = true, color = colorCodes.COLD, compPercent = true, condFunc = function(v,o) return o.LightningMaximumHitTaken ~= o.ColdMaximumHitTaken or o.LightningMaximumHitTaken ~= o.FireMaximumHitTaken end }, + { stat = "LightningMaximumHitTaken", label = "Lightning Max Hit", fmt = ".0f", compactValue = true, color = colorCodes.LIGHTNING, compPercent = true, condFunc = function(v,o) return o.LightningMaximumHitTaken ~= o.ColdMaximumHitTaken or o.LightningMaximumHitTaken ~= o.FireMaximumHitTaken end }, + { stat = "ChaosMaximumHitTaken", label = "Chaos Max Hit", fmt = ".0f", compactValue = true, color = colorCodes.CHAOS, compPercent = true }, { }, { stat = "MainHand", childStat = "Accuracy", label = "MH Accuracy", fmt = "d", condFunc = function(v,o) return o.PreciseTechnique end, warnFunc = function(v,o) return v < o.Life and "You do not have enough Accuracy for Precise Technique" end, warnColor = true }, { stat = "OffHand", childStat = "Accuracy", label = "OH Accuracy", fmt = "d", condFunc = function(v,o) return o.PreciseTechnique end, warnFunc = function(v,o) return v < o.Life and "You do not have enough Accuracy for Precise Technique" end, warnColor = true }, @@ -172,9 +172,9 @@ local displayStats = { { stat = "ColdResistOverCap", label = "Cold Res. Over Max", fmt = "d%%", hideStat = true }, { stat = "LightningResist", label = "Lightning Resistance", fmt = "d%%", color = colorCodes.LIGHTNING, condFunc = function() return true end, overCapStat = "LightningResistOverCap" }, { stat = "LightningResistOverCap", label = "Lightning Res. Over Max", fmt = "d%%", hideStat = true }, - { stat = "ChaosResist", label = "Chaos Resistance", fmt = "d%%", color = colorCodes.CHAOS, condFunc = function(v,o) return not o.ChaosInoculation end, overCapStat = "ChaosResistOverCap" }, + { stat = "ChaosResist", label = "Chaos Resistance", fmt = "d%%", color = colorCodes.CHAOS, overCapStat = "ChaosResistOverCap", overCapStatCondFunc = function(v,o) return not o.ChaosInoculation end, suffix = "Immune", suffixCondFunc = function(v,o) return o.ChaosInoculation end }, { stat = "ChaosResistOverCap", label = "Chaos Res. Over Max", fmt = "d%%", hideStat = true }, - { label = "Chaos Resistance", val = "Immune", labelStat = "ChaosResist", color = colorCodes.CHAOS, condFunc = function(o) return o.ChaosInoculation end }, + { }, { stat = "EffectiveMovementSpeedMod", label = "Movement Speed Modifier", fmt = "+d%%", mod = true, condFunc = function() return true end }, --[[ potentially useful mods @@ -199,10 +199,10 @@ local displayStats = { { stat = "LootRarity", label = "Item Rarity", fmt = "+d%%" }, --]] { }, - { stat = "FullDPS", label = "Full DPS", fmt = ".1f", color = colorCodes.CURRENCY, compPercent = true }, - { stat = "FullDotDPS", label = "Full Dot DPS", fmt = ".1f", color = colorCodes.CURRENCY, compPercent = true, condFunc = function (v) return v >= data.misc.DotDpsCap end, warnFunc = function (v) return "Full Dot DPS exceeds in game limit" end }, + { stat = "FullDPS", label = "Full DPS", fmt = ".1f", compactValue = true, color = colorCodes.CURRENCY, compPercent = true }, + { stat = "FullDotDPS", label = "Full Dot DPS", fmt = ".1f", compactValue = true, color = colorCodes.CURRENCY, compPercent = true, condFunc = function (v) return v >= data.misc.DotDpsCap end, warnFunc = function (v) return "Full Dot DPS exceeds in game limit" end }, { }, - { stat = "SkillDPS", label = "Skill DPS", condFunc = function() return true end }, + { stat = "SkillDPS", label = "Skill DPS", compactValue = true,condFunc = function() return true end }, } local minionDisplayStats = { { stat = "AverageDamage", label = "Average Damage", fmt = ".1f", compPercent = true }, diff --git a/src/Modules/CalcPerform.lua b/src/Modules/CalcPerform.lua index 03ab616ab83..0b9bfa8c734 100644 --- a/src/Modules/CalcPerform.lua +++ b/src/Modules/CalcPerform.lua @@ -3187,6 +3187,7 @@ function calcs.perform(env, skipEHP) modDB.conditions["AffectedBy"..guard.name:gsub(" ","")] = true mergeBuff(guard.modList, buffs, guard.name) end + output.GuardSkillActive = modDB.conditions["AffectedByGuardSkill"] or false -- Apply buff/debuff modifiers for _, modList in pairs(buffs) do diff --git a/src/Modules/Main.lua b/src/Modules/Main.lua index beae31b7beb..74f8b87ba36 100644 --- a/src/Modules/Main.lua +++ b/src/Modules/Main.lua @@ -103,6 +103,7 @@ function main:Init() self.colorNegative = defaultColorCodes.NEGATIVE self.colorHighlight = defaultColorCodes.HIGHLIGHT self.showThousandsSeparators = true + self.useCompactValues = true self.edgeSearchHighlight = true self.thousandsSeparator = "," self.decimalSeparator = "." @@ -569,6 +570,9 @@ function main:LoadSettings(ignoreBuild) if node.attrib.thousandsSeparator then self.thousandsSeparator = node.attrib.thousandsSeparator end + if node.attrib.useCompactValues then + self.useCompactValues = node.attrib.useCompactValues == "true" + end if node.attrib.decimalSeparator then self.decimalSeparator = node.attrib.decimalSeparator end @@ -742,6 +746,7 @@ function main:SaveSettings() colorHighlight = self.colorHighlight, showThousandsSeparators = tostring(self.showThousandsSeparators), thousandsSeparator = self.thousandsSeparator, + useCompactValues = tostring(self.useCompactValues), decimalSeparator = self.decimalSeparator, showTitlebarName = tostring(self.showTitlebarName), betaTest = tostring(self.betaTest), @@ -827,6 +832,7 @@ function main:OpenOptionsPopup(savedState) colorNegative = self.colorNegative, colorHighlight = self.colorHighlight, showThousandsSeparators = self.showThousandsSeparators, + useCompactValues = self.useCompactValues, thousandsSeparator = self.thousandsSeparator, decimalSeparator = self.decimalSeparator, showTitlebarName = self.showTitlebarName, @@ -1041,6 +1047,13 @@ function main:OpenOptionsPopup(savedState) end) controls.showThousandsSeparators.state = self.showThousandsSeparators + nextRow() + controls.useCompactValues = new("CheckBoxControl", { "TOPLEFT", controls.sectionAnchor, "TOPLEFT" }, { currentX + defaultLabelPlacementX, currentY, 20 }, "^7Compact Large #'s (e.g. 1.2K):", function(state) + self.useCompactValues = state + end) + controls.useCompactValues.state = self.useCompactValues + + nextRow() controls.thousandsSeparator = new("EditControl", { "TOPLEFT", controls.sectionAnchor, "TOPLEFT" }, { currentX + defaultLabelPlacementX, currentY, 30, 20 }, self.thousandsSeparator, nil, "%w", 1, function(buf) self.thousandsSeparator = buf @@ -1173,6 +1186,7 @@ function main:OpenOptionsPopup(savedState) self.colorHighlight = savedState.colorHighlight updateColorCode("HIGHLIGHT", self.colorHighlight) self.showThousandsSeparators = savedState.showThousandsSeparators + self.useCompactValues = savedState.useCompactValues self.thousandsSeparator = savedState.thousandsSeparator self.decimalSeparator = savedState.decimalSeparator self.showTitlebarName = savedState.showTitlebarName