Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 18 additions & 10 deletions src/Classes/CalcBreakdownControl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,11 @@ function CalcBreakdownClass:SetBreakdownData(displayData, pinned)
end
end
if #self.sectionList == 0 then
self.calcsTab:ClearDisplayStat()
if self.clearDisplayFunc then
self.clearDisplayFunc()
else
self.calcsTab:ClearDisplayStat()
end
return
end

Expand Down Expand Up @@ -116,7 +120,7 @@ end

-- Add sections based on the breakdown data generated by the Calcs module
function CalcBreakdownClass:AddBreakdownSection(sectionData)
local actor = self.calcsTab.input.showMinion and self.calcsTab.calcsEnv.minion or self.calcsTab.calcsEnv.player
local actor = self:GetActor()
local breakdown
local ns, name = sectionData.breakdown:match("^(%a+)%.(%a+)$")
if ns then
Expand Down Expand Up @@ -269,7 +273,7 @@ end

-- Add a table section showing a list of modifiers
function CalcBreakdownClass:AddModSection(sectionData, modList)
local actor = self.calcsTab.input.showMinion and self.calcsTab.calcsEnv.minion or self.calcsTab.calcsEnv.player
local actor = self:GetActor()
local build = self.calcsTab.build

-- Build list of modifiers to display
Expand Down Expand Up @@ -674,12 +678,13 @@ function CalcBreakdownClass:Draw(viewPort)
local scrollBar = self.controls.scrollBar
local width = self.contentWidth
local height = self.contentHeight
local borderThickness = self.borderThickness
if self.contentHeight > viewPort.height then
-- Content won't fit the screen height, so set the scrollbar
width = self.contentWidth + scrollBar.width
height = viewPort.height
scrollBar.height = height - 4
scrollBar:SetContentDimension(self.contentHeight - 4, viewPort.height - 4)
scrollBar.height = height - borderThickness * 2
scrollBar:SetContentDimension(self.contentHeight - borderThickness * 2, viewPort.height - borderThickness * 2)
else
scrollBar:SetContentDimension(0, 0)
end
Expand All @@ -696,15 +701,14 @@ function CalcBreakdownClass:Draw(viewPort)
-- Draw background
SetDrawLayer(nil, 10)
SetDrawColor(0, 0, 0, 0.9)
DrawImage(nil, x + 2, y + 2, width - 4, height - 4)
DrawImage(nil, x + borderThickness, y + borderThickness, width - borderThickness * 2, height - borderThickness * 2)
-- Draw border (this is put in sub layer 11 so it draws over the contents, in case they don't fit the screen)
SetDrawLayer(nil, 11)
if self.pinned then
SetDrawColor(0.25, 1, 0.25)
SetDrawColor(unpack(self.pinnedColour))
else
SetDrawColor(0.33, 0.66, 0.33)
SetDrawColor(unpack(self.borderColour))
end
local borderThickness = 2
DrawImage(nil, x, y, width, borderThickness)
DrawImage(nil, x, y + height - borderThickness, width, borderThickness)
DrawImage(nil, x, y, borderThickness, height)
Expand Down Expand Up @@ -746,7 +750,11 @@ function CalcBreakdownClass:OnKeyDown(key, doubleClick)
if key:match("BUTTON") then
if not mOver then
-- Mouse click outside the control, hide the breakdown
self.calcsTab:ClearDisplayStat()
if self.clearDisplayFunc then
self.clearDisplayFunc()
else
self.calcsTab:ClearDisplayStat()
end
self.shown = false
return
end
Expand Down
53 changes: 53 additions & 0 deletions src/Classes/CalcBreakdownControl.lua.rej
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
diff a/src/Classes/CalcBreakdownControl.lua b/src/Classes/CalcBreakdownControl.lua (rejected hunks)
@@ -27,8 +27,14 @@ function CalcBreakdownClass:CalcBreakdownControl(calcsTab)
self.rangeGuide:Load("Assets/range_guide.png")
self.uiOverlay = NewImageHandle()
self.uiOverlay:Load("Assets/game_ui_small.png")
+ self.borderThickness = 2
self.controls.scrollBar = new("ScrollBarControl"):ScrollBarControl({ "RIGHT", self, "RIGHT" }, { -2, 0, 18, 0 }, 80,
"VERTICAL", true)
+ self.controls.scrollBar.x = function()
+ return -self.borderThickness
+ end
+ self.pinnedColour = { 0.25, 1, 0.25 }
+ self.borderColour = { 0.33, 0.66, 0.33 }
return self
end

@@ -39,21 +45,34 @@ function CalcBreakdownClass:IsMouseOver()
return self:IsMouseInBounds() or self:GetMouseOverControl()
end

-function CalcBreakdownClass:SetBreakdownData(displayData, pinned)
+function CalcBreakdownClass:GetActor()
+ local env = self.calcsTab[self.envName or "calcsEnv"]
+ local actor = self.calcsTab.input.showMinion and env.minion or env.player
+ if self.forceActor then
+ actor = env[self.forceActor]
+ end
+ return actor, env
+end
+---@param displayData any
+---@param pinned any
+---@param forceActor "player"|"minion"|nil
+function CalcBreakdownClass:SetBreakdownData(displayData, pinned, forceActor)
self.pinned = pinned
if displayData == self.sourceData then
return
end
self.sourceData = displayData
+ self.forceActor = forceActor
self.shown = false
if not displayData then
return
end

-- Build list of sections
+ local actor, env = self:GetActor()
self.sectionList = wipeTable(self.sectionList)
for _, sectionData in ipairs(displayData) do
- if self.calcsTab:CheckFlag(sectionData) then
+ if self.calcsTab:CheckFlag(sectionData, actor, env.player) then
if sectionData.breakdown then
self:AddBreakdownSection(sectionData)
elseif sectionData.modName then
19 changes: 19 additions & 0 deletions src/Classes/CalcsTab.lua.rej
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
diff a/src/Classes/CalcsTab.lua b/src/Classes/CalcsTab.lua (rejected hunks)
@@ -393,7 +393,7 @@ function CalcsTabClass:SetDisplayStat(displayData, pin)
self.controls.breakdown:SetBreakdownData(displayData, pin)
end

-function CalcsTabClass:CheckFlag(obj, actor)
+function CalcsTabClass:CheckFlag(obj, actor, player)
actor = actor or (self.input.showMinion and self.calcsEnv.minion or self.calcsEnv.player)
local skillFlags = actor.mainSkill.skillFlags
if obj.flag and not skillFlags[obj.flag] then
@@ -406,7 +406,7 @@ function CalcsTabClass:CheckFlag(obj, actor)
end
end
end
- if obj.playerFlag and not self.calcsEnv.player.mainSkill.skillFlags[obj.playerFlag] then
+ if obj.playerFlag and not (player or self.calcsEnv.player).mainSkill.skillFlags[obj.playerFlag] then
return
end
if obj.notFlag and skillFlags[obj.notFlag] then
31 changes: 30 additions & 1 deletion src/Classes/TextListControl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,47 @@ function TextListClass:Draw(viewPort)
local lineY = -scrollBar.offset
for _, lineInfo in ipairs(self.list) do
if lineInfo[colIndex] then
DrawString(lineInfo.x or colInfo.x, lineY, lineInfo.align or colInfo.align, lineInfo.height, lineInfo.font or "VAR", lineInfo[colIndex])
local textX = lineInfo.x or colInfo.x
local align = lineInfo.align or colInfo.align
DrawString(textX, lineY, align, lineInfo.height, lineInfo.font or "VAR", lineInfo[colIndex])
if lineInfo.underline and lineInfo.underline[colIndex] then
local width = DrawStringWidth(lineInfo.height, "VAR", StripEscapes(lineInfo[colIndex]))
-- note: not fully handled. this is currently only used for
-- the side bar stats
if align == "RIGHT_X" then
textX = textX - width
end
SetDrawColor(0.5, 0.5, 0.5)
DrawImage(nil, textX, lineY + lineInfo.height, width, 1)
end
end
lineY = lineY + lineInfo.height
end
end
-- determine which line the user is hovering over
self.hoveredLine = nil
local cursorX, cursorY = GetCursorPos()
if cursorX >= x + 2 and cursorX < x + width - 18 and cursorY >= y + 2 and cursorY < y + height - 2 then
local rowY = y - scrollBar.offset + 2
-- suboptimal. should do binary search if this causes performance problems
for _, lineInfo in ipairs(self.list) do
if cursorY >= rowY and cursorY < rowY + lineInfo.height then
self.hoveredLine = { line = lineInfo, x = x, y = rowY, width = width }
break
end
rowY = rowY + lineInfo.height
end
end
SetViewport()
end

function TextListClass:OnKeyDown(key, doubleClick)
if not self:IsShown() or not self:IsEnabled() then
return
end
if key == "LEFTBUTTON" and self.onClick then
self.onClick(self.hoveredLine)
end
local mOverControl = self:GetMouseOverControl()
if mOverControl and mOverControl.OnKeyDown then
return mOverControl:OnKeyDown(key)
Expand Down
3 changes: 2 additions & 1 deletion src/Data/Global.lua
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,9 @@ function updateColorCode(code, color)
end

function hexToRGB(hex)
hex = hex:gsub("%^x", "") -- Remove "^x" prefix
hex = hex:gsub("0x", "") -- Remove "0x" prefix
hex = hex:gsub("#","") -- Remove '#' if present
hex = hex:gsub("#", "") -- Remove '#' if present
if #hex ~= 6 then
return nil
end
Expand Down
4 changes: 2 additions & 2 deletions src/Modules/Build.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2255,15 +2255,15 @@ function buildMode:RefreshStatList()
t_insert(statBoxList, { height = 14, align = "CENTER_X", x = 140, "^8" .. self.calcsTab.mainEnv.minion.mainSkill.infoMessage2})
end
end
self:AddDisplayStatList(self.minionDisplayStats, self.calcsTab.mainEnv.minion)
self:AddDisplayStatList(self.minionDisplayStats, self.calcsTab.mainEnv.minion, "minion")
t_insert(statBoxList, { height = 10 })
t_insert(statBoxList, { height = 18, "^7Player:" })
end
if self.calcsTab.mainEnv.player.mainSkill.activeEffect.statSet.skillFlags.disable then
t_insert(statBoxList, { height = 16, "^7Skill disabled:" })
t_insert(statBoxList, { height = 14, align = "CENTER_X", x = 140, self.calcsTab.mainEnv.player.mainSkill.disableReason })
end
self:AddDisplayStatList(self.displayStats, self.calcsTab.mainEnv.player)
self:AddDisplayStatList(self.displayStats, self.calcsTab.mainEnv.player, "player")
self:InsertItemWarnings()
self:EstimatePlayerProgress()
end
Expand Down
91 changes: 91 additions & 0 deletions src/Modules/Build.lua.rej
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
diff a/src/Modules/Build.lua b/src/Modules/Build.lua (rejected hunks)
@@ -575,7 +575,7 @@ function buildMode:Init(dbFileName, buildName, buildXML, convertBuild, importLin
function self.controls.statBox.onClick(hoveredLine)
self:SetDisplayStat(hoveredLine, true)
end
-self.controls.warnings = new("Control"):Control({"TOPLEFT",self.controls.statBox,"BOTTOMLEFT",true}, {0, 0, 0, 18})
+ self.controls.warnings = new("Control"):Control({"TOPLEFT",self.controls.statBox,"BOTTOMLEFT",true}, {0, 0, 0, 18})
self.controls.warnings.lines = {}
self.controls.warnings.width = function(control)
return control.str and DrawStringWidth(16, "FIXED", control.str) + 8 or 0
@@ -1365,7 +1365,7 @@ function buildMode:SetDisplayStat(hovered, pin)
return
end

- self.sidebarBreakdownData = self:GetSidebarBreakdown(key, hovered.line.modNames, hovered.line.ignoredSections)
+ self.sidebarBreakdownData = self:GetSidebarBreakdown(key, hovered.line.modNames, hovered.line.ignoredSections, hovered.line.actorName)
self.sidebarBreakdownData.x = hovered.x - 1
self.sidebarBreakdownData.y = hovered.y
self.sidebarBreakdownData.width = hovered.width
@@ -1802,8 +1802,12 @@ end
---@param key string A breakdown key
---@param modNames string[]? A modName key. Required if the mod name is different from the breakdown key. E.g. breakdown has Time while the mod has Speed
---@param ignoredSections table<string, boolean>?
-function buildMode:GetSidebarBreakdown(key, modNames, ignoredSections)
- local entry = self:BuildBreakdownIndex()[key]
+---@param actorName string?
+function buildMode:GetSidebarBreakdown(key, modNames, ignoredSections, actorName)
+ local env = actorName and self.calcsTab.mainEnv[actorName]
+ local breakdownData = env and env.breakdown and env.breakdown[key]
+ local sourceKey = breakdownData and breakdownData.breakdownSource or key
+ local entry = self:BuildBreakdownIndex()[sourceKey]
if not entry then
local output = { { breakdown = key } }
-- it's possible for calc sections to not have a breakdown, while still
@@ -1816,7 +1820,11 @@ function buildMode:GetSidebarBreakdown(key, modNames, ignoredSections)
local displayData = {}
-- this will include all of the hover information for the selected breakdown
for _, cell in ipairs(entry.colData) do
- t_insert(displayData, copyTable(cell))
+ local displayCell = copyTable(cell)
+ if displayCell.breakdown == sourceKey then
+ displayCell.breakdown = key
+ end
+ t_insert(displayData, displayCell)
end
-- sometimes the breakdown doesn't include the mod names. for
-- example life has its mod tables separated to the inc and more breakdowns.
@@ -1857,19 +1865,34 @@ function buildMode:GetStatBreakdownKey(statData, actorName)
if not breakdown then
return nil
end
- -- note that this intentionally doesn't check if the breakdown exists so
- -- that we can still display mod lists
- if statData.breakdown then
- return statData.breakdown
- end
- if statData.childStat then
+ local key
+ if statData.breakdown ~= nil then
+ key = statData.breakdown
+ elseif statData.childStat then
local parent = breakdown[statData.stat]
if parent and parent[statData.childStat] then
- return statData.stat .. "." .. statData.childStat
+ key = statData.stat .. "." .. statData.childStat
end
+ elseif breakdown[statData.stat] then
+ key = statData.stat
+ end
+ if key == nil then
+ return nil
end
- if breakdown[statData.stat] then
- return statData.stat
+ -- Modifier-only popups do not require a calculated breakdown.
+ if statData.modNames then
+ return key
+ end
+ local namespace, name = key:match("^(%a+)%.(%a+)$")
+ local breakdownData = namespace and breakdown[namespace] and breakdown[namespace][name] or breakdown[key]
+ if breakdownData and (#breakdownData > 0
+ or breakdownData.radius
+ or breakdownData.rowList and #breakdownData.rowList > 0
+ or breakdownData.reservations and #breakdownData.reservations > 0
+ or breakdownData.damageTypes and #breakdownData.damageTypes > 0
+ or breakdownData.slots and #breakdownData.slots > 0
+ or breakdownData.modList and #breakdownData.modList > 0) then
+ return key
end
return nil
end
3 changes: 2 additions & 1 deletion src/Modules/BuildDisplayStats.lua
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ local displayStats = {
{ stat = "SealCooldown", label = "Seal Gain Frequency", fmt = ".2fs", lowerIsBetter = true },
{ stat = "SealMax", label = "Max Number of Seals", fmt = "d" },
{ stat = "TimeMaxSeals", label = "Time to Gain Max Seals", fmt = ".2fs", lowerIsBetter = true },
{ stat = "AreaOfEffectRadiusMetres", label = "AoE Radius", fmt = ".1fm" },
{ stat = "AreaOfEffectRadiusMetres", label = "AoE Radius", fmt = ".1fm", breakdown = "AreaOfEffectRadius", modNames = { "AreaOfEffect" } },
{ stat = "BrandAttachmentRangeMetre", label = "Attachment Range", fmt = ".1fm", flag = "brand" },
{ stat = "BrandTicks", label = "Activations per Brand", fmt = "d", flag = "brand" },
{ stat = "ManaCost", label = "Mana Cost", fmt = "d", color = colorCodes.MANA, pool = "ManaUnreserved", compPercent = true, lowerIsBetter = true, condFunc = function(v,o) return o.ManaHasCost end },
Expand Down Expand Up @@ -249,6 +249,7 @@ local minionDisplayStats = {
{ stat = "EnergyShieldLeechGainRate", label = "ES Leech/On Hit Rate", fmt = ".1f", color = colorCodes.ES, compPercent = true },
}
-- Extra stats saved to the xml if not already saved there, mostly for 3rd party tools
---@type string[]
local extraSaveStats = {
"PowerCharges",
"PowerChargesMax",
Expand Down
25 changes: 25 additions & 0 deletions src/Modules/BuildDisplayStats.lua.rej
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
diff a/src/Modules/BuildDisplayStats.lua b/src/Modules/BuildDisplayStats.lua (rejected hunks)
@@ -54,7 +54,7 @@ local displayStats = {
{ 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, breakdown = "MainHand.Speed", modNames = { "Speed" }, ignoredSections = { "Inc. Cast Speed", "More Cast Speed", } },
+ { 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, breakdown = "Speed", modNames = { "Speed" }, ignoredSections = { "Inc. Cast Speed", "More Cast Speed", } },
{ stat = "KineticFusilladeMaxEffectiveAPS", label = "Max Eff. KF Attack Rate", fmt = ".2f", compPercent = true, flag = "attack", condFunc = function(v) return v > 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, modNames = { "Speed" } },
{ stat = "Speed", label = "Effective Trigger Rate", fmt = ".2f", compPercent = true, notFlag = "skipEffectiveRate", condFunc = function(v,o) return (o.TriggerTime or 0) ~= 0 end },
@@ -68,11 +68,10 @@ local displayStats = {
{ stat = "TrapThrowCount", label = "Avg. Traps per Throw", fmt = ".2f"},
{ stat = "MineThrowCount", label = "Avg. Mines per Throw", fmt = ".2f"},
{ stat = "TotemPlacementTime", label = "Totem Placement Time", fmt = ".2fs", compPercent = true, lowerIsBetter = true, condFunc = function(v, o) return not o.TriggerTime end },
- { stat = "PreEffectiveCritChance", label = "Crit Chance", fmt = ".2f%%", flag = "hit", breakdown = "CritChance" },
- { stat = "CritChance", label = "Effective Crit Chance", fmt = ".2f%%", flag = "hit", notFlag = "spell", condFunc = function(v, o) return v ~= o.PreEffectiveCritChance end, breakdown = "MainHand.CritChance" },
- { stat = "CritChance", label = "Effective Crit Chance", fmt = ".2f%%", flag = "hit", notFlag = "attack", condFunc = function(v, o) return v ~= o.PreEffectiveCritChance end, breakdown = "CritChance" },
+ { stat = "PreEffectiveCritChance", label = "Crit Chance", fmt = ".2f%%", flag = "hit", breakdown = "PreEffectiveCritChance" },
+ { stat = "CritChance", label = "Effective Crit Chance", fmt = ".2f%%", flag = "hit", condFunc = function(v, o) return v ~= o.PreEffectiveCritChance end, breakdown = "CritChance" },
{ stat = "CritMultiplier", label = "Crit Multiplier", fmt = "d%%", pc = true, condFunc = function(v, o) return (o.CritChance or 0) > 0 end, breakdown = "CritMultiplier" },
- { stat = "HitChance", label = "Hit Chance", fmt = ".0f%%", flag = "attack", breakdown = "MainHand.AccuracyHitChance" },
+ { stat = "HitChance", label = "Hit Chance", fmt = ".0f%%", flag = "attack", breakdown = "HitChance" },
{ stat = "HitChance", label = "Hit Chance", fmt = ".0f%%", condFunc = function(v,o) return o.enemyHasSpellBlock 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" },
Loading