From 40d89df26e1f066046a86c5fac49c1beea622085 Mon Sep 17 00:00:00 2001 From: Tercio Jose Date: Wed, 10 May 2023 22:43:01 -0300 Subject: [PATCH] Fixed an issue where it throws an error when opening the Damage Taken breakdown --- Definitions.lua | 36 +- classes/class_damage.lua | 386 ++++++++++++--- frames/window_playerbreakdown.lua | 27 +- frames/window_playerbreakdown_spells.lua | 602 ++++++++++++++++------- functions/playerclass.lua | 70 ++- functions/profiles.lua | 9 +- 6 files changed, 858 insertions(+), 272 deletions(-) diff --git a/Definitions.lua b/Definitions.lua index 957ac6dd..d07a62cd 100644 --- a/Definitions.lua +++ b/Definitions.lua @@ -29,6 +29,9 @@ ---@class tablesize : {H: number, W: number} ---@class tablecoords : {L: number, R: number, T: number, B: number} +---@class texturecoords: {left: number, right: number, top: number, bottom: number} +---@class objectsize : {height: number, width: number} +---@class texturetable : {texture: string, coords: texturecoords, size: objectsize} ---@class spellid : number ---@class actorname : string @@ -399,11 +402,6 @@ ---@class targettable : {[string]: number} ---@class actor : table ----@field GetSpellContainer fun(actor: actor, containerType: "debuff"|"buff"|"spell"|"cooldowns") : spellcontainer ----@field Name fun(actor: actor) : string get the name of the actor ----@field Tempo fun(actor: actor) : number get the activity or effective time of the actor ----@field GetPets fun(actor: actor) : table get a table with all pet names that belong to the player ----@field GetSpellList fun(actor: actor) : table ---@field BuildSpellTargetFromBreakdownSpellData fun(actor: actor, bkSpellData: spelltableadv) : table ---@field BuildSpellTargetFromSpellTable fun(actor: actor, spellTable: spelltable) : table ---@field debuff_uptime_spells table @@ -424,6 +422,15 @@ ---@field total number ---@field pets table ---@field targets targettable +---@field damage_taken number amount of damage the actor took durent the segment +---@field damage_from table store the name of the actors which damaged the actor, format: [actorName] = true +---@field GetSpellContainer fun(actor: actor, containerType: "debuff"|"buff"|"spell"|"cooldowns") : spellcontainer +---@field Class fun(actor: actor) : string get the ingame class of the actor +---@field Spec fun(actor: actor) : string get the ingame spec of the actor +---@field Name fun(actor: actor) : string get the name of the actor +---@field Tempo fun(actor: actor) : number get the activity or effective time of the actor +---@field GetPets fun(actor: actor) : table get a table with all pet names that belong to the player +---@field GetSpellList fun(actor: actor) : table ---@class segmentid : number ---@class instanceid : number @@ -441,6 +448,7 @@ ---@field ativa boolean ---@field freezed boolean ---@field sub_atributo_last table +---@field row_info table ---@field GetInstanceGroup fun() : table ---@field GetCombat fun(instance: instance) ---@field ChangeIcon fun(instance: instance) @@ -480,6 +488,8 @@ ---@field combatTime number ---@field [spelltableadv] spelltableadv indexed part of the table +---@class headercolumndatasaved : {enabled: boolean, width: number, align: string} + ---@class breakdownexpandbutton : button ---@field texture texture @@ -493,6 +503,10 @@ ---@field Header df_headerframe ---@field RefreshMe fun(scrollFrame: breakdowntargetscrollframe, data: table|nil) +---@class breakdowngenericscrollframe : df_scrollboxmixin, scrollframe +---@field Header df_headerframe +---@field RefreshMe fun(scrollFrame: breakdowngenericscrollframe, data: table|nil) + ---@class breakdownphasescrollframe : df_scrollboxmixin, scrollframe ---@field Header df_headerframe ---@field RefreshMe fun(scrollFrame: breakdownphasescrollframe, data: table|nil) @@ -503,6 +517,18 @@ ---@field InLineTexts fontstring[] ---@field statusBar breakdownspellbarstatusbar +---@class breakdowngenericbar : button, df_headerfunctions +---@field index number +---@field rank number +---@field name string +---@field percent number +---@field amount number +---@field total number +---@field actorName string +---@field Icon texture +---@field InLineTexts fontstring[] +---@field statusBar breakdownspellbarstatusbar + ---@class breakdowntargetbar : button, df_headerfunctions ---@field index number ---@field rank number diff --git a/classes/class_damage.lua b/classes/class_damage.lua index 4c38dc87..78cfeacc 100644 --- a/classes/class_damage.lua +++ b/classes/class_damage.lua @@ -47,7 +47,7 @@ --constants local container_habilidades = Details.container_habilidades - local atributo_damage = Details.atributo_damage + local damageClass = Details.atributo_damage local atributo_misc = Details.atributo_misc local container_damage = Details.container_type.CONTAINER_DAMAGE_CLASS @@ -146,7 +146,7 @@ function Details:CreateActorLastEventTable() --[[exported]] return t end -function atributo_damage:CreateFFTable(targetName) --[[exported]] +function damageClass:CreateFFTable(targetName) --[[exported]] local newTable = {total = 0, spells = {}} self.friendlyfire[targetName] = newTable return newTable @@ -471,7 +471,7 @@ end ---this function is called from within an actorContainer when it needs to create a new actorObject for a new actor ---actorObject is a ordinary table with the actor attributes and a metatable to inherit the functions from Details object ---@return table - function atributo_damage:NovaTabela() --create new actorObject + function damageClass:NovaTabela() --create new actorObject local alphabetical = Details:GetOrderNumber() --constructor: creates a table with the actor attributes and then set the metatable to the actor prototype @@ -525,7 +525,7 @@ end spells = container_habilidades:NovoContainer(container_damage) } - setmetatable(newDamageActor, atributo_damage) + setmetatable(newDamageActor, damageClass) detailsFramework:Mixin(newDamageActor, Details222.Mixins.ActorMixin) detailsFramework:Mixin(newDamageActor, damageClassMixin) @@ -537,7 +537,7 @@ end --special cases -- dps (calculate dps for actors) - function atributo_damage:ContainerRefreshDps (container, combat_time) + function damageClass:ContainerRefreshDps (container, combat_time) local total = 0 @@ -778,7 +778,7 @@ end end local function RefreshBarraBySpell (tabela, barra, instancia) - atributo_damage:AtualizarBySpell (tabela, tabela.minha_barra, barra.colocacao, instancia) + damageClass:AtualizarBySpell (tabela, tabela.minha_barra, barra.colocacao, instancia) end local on_switch_DTBS_show = function(instance) @@ -1003,7 +1003,7 @@ end local DTBS_format_name = function(player_name) return Details:GetOnlyName(player_name) end local DTBS_format_amount = function(amount) return Details:ToK(amount) .. " (" .. format("%.1f", amount / bs_tooltip_table.damage_total * 100) .. "%)" end - function atributo_damage:ReportSingleDTBSLine (spell, instance, ShiftKeyDown, ControlKeyDown) + function damageClass:ReportSingleDTBSLine (spell, instance, ShiftKeyDown, ControlKeyDown) if (ControlKeyDown) then local spellname, _, spellicon = _GetSpellInfo(spell[1]) return Details:OpenAuraPanel (spell[1], spellname, spellicon) @@ -1019,7 +1019,7 @@ end return Details:Reportar(report_table, {_no_current = true, _no_inverse = true, _custom = true}) end - function atributo_damage:AtualizarBySpell(tabela, whichRowLine, colocacao, instance) + function damageClass:AtualizarBySpell(tabela, whichRowLine, colocacao, instance) tabela ["byspell"] = true --marca que esta tabela � uma tabela de frags, usado no controla na hora de montar o tooltip local thisLine = instance.barras [whichRowLine] --pega a refer�ncia da barra na janela @@ -1213,10 +1213,10 @@ end end local function RefreshBarraFrags (tabela, barra, instancia) - atributo_damage:AtualizarFrags(tabela, tabela.minha_barra, barra.colocacao, instancia) + damageClass:AtualizarFrags(tabela, tabela.minha_barra, barra.colocacao, instancia) end - function atributo_damage:AtualizarFrags(tabela, whichRowLine, colocacao, instancia) + function damageClass:AtualizarFrags(tabela, whichRowLine, colocacao, instancia) tabela ["frags"] = true --marca que esta tabela � uma tabela de frags, usado no controla na hora de montar o tooltip local thisLine = instancia.barras [whichRowLine] --pega a refer�ncia da barra na janela @@ -1455,7 +1455,7 @@ end return instance:TrocaTabela(instance.segmento, 5, #Details.custom) end - function atributo_damage:ReportSingleVoidZoneLine (actor, instance, ShiftKeyDown, ControlKeyDown) + function damageClass:ReportSingleVoidZoneLine (actor, instance, ShiftKeyDown, ControlKeyDown) local spellid = tooltip_void_zone_temp.spellid @@ -1732,7 +1732,7 @@ end ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --main refresh function -function atributo_damage:RefreshWindow(instancia, combatObject, forcar, exportar, refreshRequired) +function damageClass:RefreshWindow(instancia, combatObject, forcar, exportar, refreshRequired) local showing = combatObject[class_type] --o que esta sendo mostrado -> [1] - dano [2] - cura --pega o container com ._NameIndexTable ._ActorTable --not have something to show @@ -1898,7 +1898,7 @@ function atributo_damage:RefreshWindow(instancia, combatObject, forcar, exportar local lineContainer = instancia.barras for i = instancia.barraS[1], instancia.barraS[2], 1 do - atributo_damage:AtualizarFrags(ntable[i], whichRowLine, i, instancia) + damageClass:AtualizarFrags(ntable[i], whichRowLine, i, instancia) whichRowLine = whichRowLine+1 end @@ -2040,7 +2040,7 @@ function atributo_damage:RefreshWindow(instancia, combatObject, forcar, exportar --print(bs_index, #bs_table, instancia.barraS[1], instancia.barraS[2]) for i = instancia.barraS[1], instancia.barraS[2], 1 do - atributo_damage:AtualizarBySpell (bs_table[i], whichRowLine, i, instancia) + damageClass:AtualizarBySpell (bs_table[i], whichRowLine, i, instancia) whichRowLine = whichRowLine+1 end @@ -2184,7 +2184,7 @@ function atributo_damage:RefreshWindow(instancia, combatObject, forcar, exportar --print(keyName) if (subAttribute == 2) then local combat_time = instancia.showing:GetCombatTime() - total = atributo_damage:ContainerRefreshDps (actorTableContent, combat_time) + total = damageClass:ContainerRefreshDps (actorTableContent, combat_time) else --pega o total ja aplicado na tabela do combate total = combatObject.totals [class_type] @@ -2209,7 +2209,7 @@ function atributo_damage:RefreshWindow(instancia, combatObject, forcar, exportar if (subAttribute == 2) then --dps local combat_time = instancia.showing:GetCombatTime() - atributo_damage:ContainerRefreshDps (actorTableContent, combat_time) + damageClass:ContainerRefreshDps (actorTableContent, combat_time) end if (#actorTableContent < 1) then @@ -2239,7 +2239,7 @@ function atributo_damage:RefreshWindow(instancia, combatObject, forcar, exportar else if (subAttribute == 2) then --dps local combat_time = instancia.showing:GetCombatTime() - atributo_damage:ContainerRefreshDps (actorTableContent, combat_time) + damageClass:ContainerRefreshDps (actorTableContent, combat_time) end _table_sort(actorTableContent, Details.SortKeyGroup) @@ -2682,7 +2682,7 @@ local actor_class_color_r, actor_class_color_g, actor_class_color_b end -- ~atualizar ~barra ~update -function atributo_damage:RefreshLine(instance, lineContainer, whichRowLine, rank, total, sub_atributo, forcar, keyName, combat_time, percentage_type, use_animations, bars_show_data, bars_brackets, bars_separator) +function damageClass:RefreshLine(instance, lineContainer, whichRowLine, rank, total, sub_atributo, forcar, keyName, combat_time, percentage_type, use_animations, bars_show_data, bars_brackets, bars_separator) local thisLine = lineContainer[whichRowLine] if (not thisLine) then @@ -3237,7 +3237,7 @@ end ---------TOOLTIPS BIFURCA��O -- ~tooltip -function atributo_damage:ToolTip (instance, numero, barra, keydown) +function damageClass:ToolTip (instance, numero, barra, keydown) --seria possivel aqui colocar o icone da classe dele? if (instance.atributo == 5) then --custom @@ -3264,7 +3264,7 @@ local barAlha = .6 ---------DAMAGE DONE & DPS -function atributo_damage:ToolTip_DamageDone (instancia, numero, barra, keydown) +function damageClass:ToolTip_DamageDone (instancia, numero, barra, keydown) local owner = self.owner if (owner and owner.classe) then r, g, b = unpack(Details.class_colors [owner.classe]) @@ -3622,7 +3622,7 @@ end local ENEMIES_format_name = function(player) if (player == 0) then return false end return Details:GetOnlyName(player.nome) end local ENEMIES_format_amount = function(amount) if (amount <= 0) then return false end return Details:ToK(amount) .. " (" .. format("%.1f", amount / tooltip_temp_table.damage_total * 100) .. "%)" end -function atributo_damage:ReportEnemyDamageTaken (actor, instance, ShiftKeyDown, ControlKeyDown, fromFrags) +function damageClass:ReportEnemyDamageTaken (actor, instance, ShiftKeyDown, ControlKeyDown, fromFrags) if (ShiftKeyDown) then local inimigo = actor.nome local custom_name = inimigo .. " -" .. Loc ["STRING_CUSTOM_ENEMY_DT"] @@ -3670,10 +3670,10 @@ end local FRAGS_format_name = function(player_name) return Details:GetOnlyName(player_name) end local FRAGS_format_amount = function(amount) return Details:ToK(amount) .. " (" .. format("%.1f", amount / frags_tooltip_table.damage_total * 100) .. "%)" end -function atributo_damage:ReportSingleFragsLine (frag, instance, ShiftKeyDown, ControlKeyDown) +function damageClass:ReportSingleFragsLine (frag, instance, ShiftKeyDown, ControlKeyDown) if (ShiftKeyDown) then - return atributo_damage:ReportEnemyDamageTaken (frag, instance, ShiftKeyDown, ControlKeyDown, true) + return damageClass:ReportEnemyDamageTaken (frag, instance, ShiftKeyDown, ControlKeyDown, true) end local report_table = {"Details!: " .. frag [1] .. " - " .. Loc ["STRING_ATTRIBUTE_DAMAGE_TAKEN"]} @@ -3683,7 +3683,7 @@ function atributo_damage:ReportSingleFragsLine (frag, instance, ShiftKeyDown, Co return Details:Reportar (report_table, {_no_current = true, _no_inverse = true, _custom = true}) end -function atributo_damage:ToolTip_Enemies (instancia, numero, barra, keydown) +function damageClass:ToolTip_Enemies (instancia, numero, barra, keydown) local owner = self.owner if (owner and owner.classe) then @@ -3788,7 +3788,7 @@ function atributo_damage:ToolTip_Enemies (instancia, numero, barra, keydown) end ---------DAMAGE TAKEN -function atributo_damage:ToolTip_DamageTaken (instance, numero, barra, keydown) +function damageClass:ToolTip_DamageTaken (instance, numero, barra, keydown) --if the object has a owner, it's a pet local owner = self.owner if (owner and owner.classe) then @@ -3963,7 +3963,7 @@ function atributo_damage:ToolTip_DamageTaken (instance, numero, barra, keydown) end ---------FRIENDLY FIRE -function atributo_damage:ToolTip_FriendlyFire (instancia, numero, barra, keydown) +function damageClass:ToolTip_FriendlyFire (instancia, numero, barra, keydown) local owner = self.owner if (owner and owner.classe) then @@ -4078,7 +4078,7 @@ end ---------DETALHES BIFURCA��O ~detalhes ~detailswindow ~bi -function atributo_damage:MontaInfo() +function damageClass:MontaInfo() if (info.sub_atributo == 1 or info.sub_atributo == 2 or info.sub_atributo == 6) then --damage done & dps return self:MontaInfoDamageDone() elseif (info.sub_atributo == 3) then --damage taken @@ -4089,7 +4089,7 @@ function atributo_damage:MontaInfo() end ---------DETALHES bloco da direita BIFURCA��O -function atributo_damage:MontaDetalhes (spellid, barra, instancia) +function damageClass:MontaDetalhes (spellid, barra, instancia) if (info.sub_atributo == 1 or info.sub_atributo == 2) then return self:MontaDetalhesDamageDone (spellid, barra, instancia) @@ -4109,7 +4109,7 @@ end ------ Friendly Fire -function atributo_damage:MontaInfoFriendlyFire() +function damageClass:MontaInfoFriendlyFire() local instancia = info.instancia local combat = instancia:GetShowingCombat() @@ -4249,27 +4249,65 @@ function atributo_damage:MontaInfoFriendlyFire() end ------ Damage Taken -function atributo_damage:MontaInfoDamageTaken() +local damageTakenHeadersAllowed = {icon = true, name = true, rank = true, amount = true, persecond = true, percent = true} +function damageClass:MontaInfoDamageTaken() + ---@type actor + local actorObject = self + ---@type instance + local instance = info.instancia + ---@type combat + local combatObject = instance:GetCombat() + ---@type string + local actorName = actorObject:Name() - --build the code for the new breakdown window + ---@type number + local damageTakenTotal = actorObject.damage_taken + ---@type table + local damageTakenFrom = actorObject.damage_from + ---@type actorcontainer + local damageContainer = combatObject:GetContainer(class_type) + local resultTable = {} + + ---@type string + for aggressorName in pairs(damageTakenFrom) do + local sourceActorObject = damageContainer:GetActor(aggressorName) + if (sourceActorObject) then + ---@type table + local targets = sourceActorObject:GetTargets() + ---@type number|nil + local amountOfDamage = targets[actorName] + if (amountOfDamage) then + ---@type texturetable + local iconTable = Details:GetActorIcon(sourceActorObject) + + ---@type {name: string, amount: number, icon: texturetable} + local damageTakenTable = {name = aggressorName, total = amountOfDamage, icon = iconTable} + + resultTable[#resultTable+1] = damageTakenTable + end + end + end + + resultTable.totalValue = damageTakenTotal + resultTable.combatTime = combatObject:GetCombatTime() + resultTable.headersAllowed = damageTakenHeadersAllowed + + Details222.BreakdownWindow.SendGenericData(resultTable, actorObject, combatObject, instance) + + if 1 then return end - local damage_taken = self.damage_taken - local agressores = self.damage_from - local instancia = info.instancia - local tabela_do_combate = instancia.showing - local showing = tabela_do_combate [class_type] --o que esta sendo mostrado -> [1] - dano [2] - cura --pega o container com ._NameIndexTable ._ActorTable local barras = info.barras1 local meus_agressores = {} local este_agressor - for nome, _ in pairs(agressores) do - este_agressor = showing._ActorTable[showing._NameIndexTable[nome]] + for nome, _ in pairs(damageTakenFrom) do + este_agressor = damageContainer._ActorTable[damageContainer._NameIndexTable[nome]] if (este_agressor) then local alvos = este_agressor.targets local este_alvo = alvos [self.nome] if (este_alvo) then - meus_agressores [#meus_agressores+1] = {nome, este_alvo, este_alvo/damage_taken*100, este_agressor.classe} + meus_agressores [#meus_agressores+1] = {nome, este_alvo, este_alvo/damageTakenTotal*100, este_agressor.classe} end end end @@ -4291,7 +4329,7 @@ function atributo_damage:MontaInfoDamageTaken() for index, tabela in ipairs(meus_agressores) do barra = barras [index] if (not barra) then - barra = gump:CriaNovaBarraInfo1 (instancia, index) + barra = gump:CriaNovaBarraInfo1 (instance, index) end self:FocusLock(barra, tabela[1]) @@ -4305,6 +4343,49 @@ function atributo_damage:MontaInfoDamageTaken() self:UpdadeInfoBar(barra, index, tabela[1], tabela[1], tabela[2], formated_value, max_, tabela[3], "Interface\\AddOns\\Details\\images\\classes_small_alpha", true, texCoords, nil, tabela[4]) end + + --[=[ + ---@type number, spelltable + for spellId, spellTable in pairs(actorSpells) do + spellTable.ChartData = nil + + ---@type string + local spellName = _GetSpellInfo(spellId) + if (spellName) then + ---@type number in which index the spell with the same name was stored + local index = alreadyAdded[spellName] + if (index) then + ---@type spelltableadv + local bkSpellData = breakdownSpellDataList[index] + + bkSpellData.spellTables[#bkSpellData.spellTables+1] = spellTable + + ---@type bknesteddata + local nestedData = {spellId = spellId, spellTable = spellTable, petName = "", value = 0} + bkSpellData.nestedData[#bkSpellData.nestedData+1] = nestedData + bkSpellData.bCanExpand = true + else + ---@type spelltableadv + local bkSpellData = { + id = spellId, + spellschool = spellTable.spellschool, + bIsExpanded = Details222.BreakdownWindow.IsSpellExpanded(spellId), + bCanExpand = false, + + spellTables = {spellTable}, + nestedData = {{spellId = spellId, spellTable = spellTable, petName = "", value = 0}}, + } + + detailsFramework:Mixin(bkSpellData, Details.SpellTableMixin) + breakdownSpellDataList[#breakdownSpellDataList+1] = bkSpellData + alreadyAdded[spellName] = #breakdownSpellDataList + end + end + end + + --]=] + + end --[[exported]] function Details:UpdadeInfoBar(row, index, spellId, name, value, formattedValue, max, percent, icon, detalhes, texCoords, spellSchool, class) @@ -4487,7 +4568,7 @@ end --]=] ------ Damage Done & Dps -function atributo_damage:MontaInfoDamageDone() --I guess this fills the list of spells in the topleft scrollBar in the summary tab +function damageClass:MontaInfoDamageDone() --I guess this fills the list of spells in the topleft scrollBar in the summary tab --the goal of this function is to build a list of spells the actor used and send the data to Details! which will delivery to the summary tab actived --so the script only need to build the list of spells and send it to Details! ---@type actor @@ -4896,7 +4977,7 @@ end ------ Detalhe Info Friendly Fire -function atributo_damage:MontaDetalhesFriendlyFire (nome, barra) +function damageClass:MontaDetalhesFriendlyFire (nome, barra) local barras = info.barras3 local instancia = info.instancia @@ -4961,7 +5042,7 @@ function atributo_damage:MontaDetalhesFriendlyFire (nome, barra) end -- detalhes info enemies -function atributo_damage:MontaDetalhesEnemy (spellid, barra) +function damageClass:MontaDetalhesEnemy (spellid, barra) local container = info.instancia.showing[1] local barras = info.barras3 @@ -5059,7 +5140,7 @@ function atributo_damage:MontaDetalhesEnemy (spellid, barra) end ------ Detalhe Info Damage Taken -function atributo_damage:MontaDetalhesDamageTaken (nome, barra) +function damageClass:MontaDetalhesDamageTaken (nome, barra) local barras = info.barras3 local instancia = info.instancia @@ -5196,9 +5277,200 @@ local MontaDetalhesBuffProcs = function(actor, row, instance) end end +---called from the spell breakdown when a spellbar is hovered over +---@param spellBar breakdownspellbar +---@param spellBlockContainer breakdownspellblockframe +---@param blockIndex number +---@param summaryBlock breakdownspellblock +---@param spellId number +---@param elapsedTime number +---@param actorName string +---@param spellTable spelltable +---@param trinketData trinketdata +---@param combatObject combat +function damageClass:BuildSpellDetails(spellBar, spellBlockContainer, blockIndex, summaryBlock, spellId, elapsedTime, actorName, spellTable, trinketData, combatObject) + ---@type number + local totalHits = spellTable.counter + + --damage section showing damage done sub section + blockIndex = blockIndex + 1 + + do --update the texts in the summary block + local blockLine1, blockLine2, blockLine3 = summaryBlock:GetLines() + + local totalCasts = spellBar.amountCasts > 0 and spellBar.amountCasts or "(?)" + blockLine1.leftText:SetText(Loc ["STRING_CAST"] .. ": " .. totalCasts) --total amount of casts + + if (trinketData[spellId] and combatObject.trinketProcs) then + local trinketProcData = combatObject.trinketProcs[actorName] + if (trinketProcData) then + local trinketProc = trinketProcData[spellId] + if (trinketProc) then + blockLine1.leftText:SetText("Procs: " .. trinketProc.total) + end + end + end + + blockLine1.rightText:SetText(Loc ["STRING_HITS"]..": " .. totalHits) --hits and uptime + + blockLine2.leftText:SetText(Loc ["STRING_DAMAGE"]..": " .. Details:Format(spellTable.total)) --total damage + blockLine2.rightText:SetText(Details:GetSpellSchoolFormatedName(spellTable.spellschool)) --spell school + + blockLine3.leftText:SetText(Loc ["STRING_AVERAGE"] .. ": " .. Details:Format(spellBar.average)) --average damage + blockLine3.rightText:SetText(Loc ["STRING_DPS"] .. ": " .. Details:CommaValue(spellBar.perSecond)) --dps + end + + local emporwerSpell = spellTable.e_total + if (emporwerSpell) then + local empowerLevelSum = spellTable.e_total --total sum of empower levels + local empowerAmount = spellTable.e_amt --amount of casts with empower + local empowerAmountPerLevel = spellTable.e_lvl --{[1] = 4; [2] = 9; [3] = 15} + local empowerDamagePerLevel = spellTable.e_dmg --{[1] = 54548745, [2] = 74548745} + + ---@type breakdownspellblock + local empowerBlock = spellBlockContainer:GetBlock(blockIndex) + blockIndex = blockIndex + 1 + + local level1AverageDamage = "0" + local level2AverageDamage = "0" + local level3AverageDamage = "0" + local level4AverageDamage = "0" + local level5AverageDamage = "0" + + if (empowerDamagePerLevel[1]) then + level1AverageDamage = Details:Format(empowerDamagePerLevel[1] / empowerAmountPerLevel[1]) + end + if (empowerDamagePerLevel[2]) then + level2AverageDamage = Details:Format(empowerDamagePerLevel[2] / empowerAmountPerLevel[2]) + end + if (empowerDamagePerLevel[3]) then + level3AverageDamage = Details:Format(empowerDamagePerLevel[3] / empowerAmountPerLevel[3]) + end + if (empowerDamagePerLevel[4]) then + level4AverageDamage = Details:Format(empowerDamagePerLevel[4] / empowerAmountPerLevel[4]) + end + if (empowerDamagePerLevel[5]) then + level5AverageDamage = Details:Format(empowerDamagePerLevel[5] / empowerAmountPerLevel[5]) + end + + empowerBlock:Show() + empowerBlock:SetValue(100) + + empowerBlock.sparkTexture:SetPoint("left", empowerBlock, "left", empowerBlock:GetWidth() + Details.breakdown_spell_tab.blockspell_spark_offset, 0) + empowerBlock:SetColor(0.200, 0.576, 0.498, 0.6) + + local blockLine1, blockLine2, blockLine3 = empowerBlock:GetLines() + blockLine1.leftText:SetText("Spell Empower Average Level: " .. string.format("%.2f", empowerLevelSum / empowerAmount)) + + if (level1AverageDamage ~= "0") then + blockLine2.leftText:SetText("Level 1 Avg: " .. level1AverageDamage .. " (" .. (empowerAmountPerLevel[1] or 0) .. ")") + end + + if (level2AverageDamage ~= "0") then + blockLine2.centerText:SetText("Level 2 Avg: " .. level2AverageDamage .. " (" .. (empowerAmountPerLevel[2] or 0) .. ")") + end + + if (level3AverageDamage ~= "0") then + blockLine2.rightText:SetText("Level 3 Avg: " .. level3AverageDamage .. " (" .. (empowerAmountPerLevel[3] or 0) .. ")") + end + + if (level4AverageDamage ~= "0") then + blockLine3.leftText:SetText("Level 4 Avg: " .. level4AverageDamage .. " (" .. (empowerAmountPerLevel[4] or 0) .. ")") + end + + if (level5AverageDamage ~= "0") then + blockLine3.rightText:SetText("Level 5 Avg: " .. level5AverageDamage .. " (" .. (empowerAmountPerLevel[5] or 0) .. ")") + end + end + + --check if there's normal hits and build the block + ---@type number + local normalHitsAmt = spellTable.n_amt + + if (normalHitsAmt > 0) then + ---@type breakdownspellblock + local normalHitsBlock = spellBlockContainer:GetBlock(blockIndex) + normalHitsBlock:Show() + blockIndex = blockIndex + 1 + + local percent = normalHitsAmt / math.max(totalHits, 0.0001) * 100 + normalHitsBlock:SetValue(percent) + normalHitsBlock.sparkTexture:SetPoint("left", normalHitsBlock, "left", percent / 100 * normalHitsBlock:GetWidth() + Details.breakdown_spell_tab.blockspell_spark_offset, 0) + + local blockLine1, blockLine2, blockLine3 = normalHitsBlock:GetLines() + blockLine1.leftText:SetText(Loc ["STRING_NORMAL_HITS"]) + blockLine1.rightText:SetText(normalHitsAmt .. " [|cFFC0C0C0" .. string.format("%.1f", normalHitsAmt / math.max(totalHits, 0.0001) * 100) .. "%|r]") + + blockLine2.leftText:SetText(Loc ["STRING_MINIMUM_SHORT"] .. ": " .. Details:CommaValue(spellTable.n_min)) + blockLine2.rightText:SetText(Loc ["STRING_MAXIMUM_SHORT"] .. ": " .. Details:CommaValue(spellTable.n_max)) + + local normalAverage = spellTable.n_total / math.max(normalHitsAmt, 0.0001) + blockLine3.leftText:SetText(Loc ["STRING_AVERAGE"] .. ": " .. Details:CommaValue(normalAverage)) + + local tempo = (elapsedTime * spellTable.n_total) / math.max(spellTable.total, 0.001) + local normalAveragePercent = spellBar.average / normalAverage * 100 + local normalTempoPercent = normalAveragePercent * tempo / 100 + blockLine3.rightText:SetText(Loc ["STRING_DPS"] .. ": " .. Details:CommaValue(spellTable.n_total / normalTempoPercent)) + end + + ---@type number + local criticalHitsAmt = spellTable.c_amt + if (criticalHitsAmt > 0) then + ---@type breakdownspellblock + local critHitsBlock = spellBlockContainer:GetBlock(blockIndex) + critHitsBlock:Show() + blockIndex = blockIndex + 1 + + local percent = Details.SpellTableMixin.GetCritPercent(spellTable) + critHitsBlock:SetValue(percent) + critHitsBlock.sparkTexture:SetPoint("left", critHitsBlock, "left", percent / 100 * critHitsBlock:GetWidth() + Details.breakdown_spell_tab.blockspell_spark_offset, 0) + + local blockLine1, blockLine2, blockLine3 = critHitsBlock:GetLines() + blockLine1.leftText:SetText(Loc ["STRING_CRITICAL_HITS"]) + blockLine1.rightText:SetText(criticalHitsAmt .. " [|cFFC0C0C0" .. string.format("%.1f", criticalHitsAmt / math.max(totalHits, 0.0001) * 100) .. "%|r]") + + blockLine2.leftText:SetText(Loc ["STRING_MINIMUM_SHORT"] .. ": " .. Details:CommaValue(spellTable.c_min)) + blockLine2.rightText:SetText(Loc ["STRING_MAXIMUM_SHORT"] .. ": " .. Details:CommaValue(spellTable.c_max)) + + local critAverage = Details.SpellTableMixin.GetCritAverage(spellTable) + blockLine3.leftText:SetText(Loc ["STRING_AVERAGE"] .. ": " .. Details:CommaValue(critAverage)) + + local tempo = (elapsedTime * spellTable.c_total) / math.max(spellTable.total, 0.001) + local critAveragePercent = spellBar.average / critAverage * 100 + local critTempoPercent = critAveragePercent * tempo / 100 + blockLine3.rightText:SetText(Loc ["STRING_DPS"] .. ": " .. Details:CommaValue(spellTable.c_total / critTempoPercent)) + end + + if (trinketData[spellId]) then + ---@type trinketdata + local trinketInfo = trinketData[spellId] + + local minTime = trinketInfo.minTime + local maxTime = trinketInfo.maxTime + local average = trinketInfo.averageTime + + ---@type breakdownspellblock + local trinketBlock = spellBlockContainer:GetBlock(blockIndex) + trinketBlock:Show() + trinketBlock:SetValue(100) + trinketBlock.sparkTexture:SetPoint("left", trinketBlock, "left", trinketBlock:GetWidth() + Details.breakdown_spell_tab.blockspell_spark_offset, 0) + blockIndex = blockIndex + 1 + + local blockLine1, blockLine2, blockLine3 = trinketBlock:GetLines() + blockLine1.leftText:SetText("Trinket Info") + + blockLine1.rightText:SetText("PPM: " .. string.format("%.2f", average / 60)) + if (minTime == 9999999) then + blockLine2.leftText:SetText("Min Time: " .. _G["UNKNOWN"]) + else + blockLine2.leftText:SetText("Min Time: " .. math.floor(minTime)) + end + blockLine2.rightText:SetText("Max Time: " .. math.floor(maxTime)) + end +end --this build p the 6 rectangle boxes in the right side of the breakdown window summary tab -function atributo_damage:MontaDetalhesDamageDone (spellId, spellLine, instance) --this should be ~deprecated with the new breakdown tab +function damageClass:MontaDetalhesDamageDone (spellId, spellLine, instance) --this should be ~deprecated with the new breakdown tab print("MontaDetalhesDamageDone - deprecated", debugstack()) @@ -5689,7 +5961,7 @@ function Details:BuildPlayerDetailsSpellChart() end end -function atributo_damage:MontaTooltipDamageTaken (thisLine, index) +function damageClass:MontaTooltipDamageTaken (thisLine, index) local aggressor = info.instancia.showing [1]:PegarCombatente (_, thisLine.nome_inimigo) local container = aggressor.spells._ActorTable local habilidades = {} @@ -5725,7 +5997,7 @@ function atributo_damage:MontaTooltipDamageTaken (thisLine, index) end -function atributo_damage:MontaTooltipAlvos (thisLine, index, instancia) --~deprecated +function damageClass:MontaTooltipAlvos (thisLine, index, instancia) --~deprecated local inimigo = thisLine.nome_inimigo local habilidades = {} @@ -5850,7 +6122,7 @@ function atributo_damage:MontaTooltipAlvos (thisLine, index, instancia) --~depre end --controla se o dps do jogador esta travado ou destravado -function atributo_damage:Iniciar (iniciar) +function damageClass:Iniciar (iniciar) if (iniciar == nil) then return self.dps_started --retorna se o dps esta aberto ou fechado para este jogador elseif (iniciar) then @@ -5866,7 +6138,7 @@ end --core functions --limpa as tabelas tempor�rias ao resetar - function atributo_damage:ClearTempTables() + function damageClass:ClearTempTables() for i = #ntable, 1, -1 do ntable [i] = nil end @@ -5889,7 +6161,7 @@ end end --atualize a funcao de abreviacao - function atributo_damage:UpdateSelectedToKFunction() + function damageClass:UpdateSelectedToKFunction() SelectedToKFunction = ToKFunctions [Details.ps_abbreviation] FormatTooltipNumber = ToKFunctions [Details.tooltip.abbreviation] TooltipMaximizedMethod = Details.tooltip.maximize_method @@ -5897,13 +6169,13 @@ end end --diminui o total das tabelas do combate - function atributo_damage:subtract_total (combat_table) + function damageClass:subtract_total (combat_table) combat_table.totals [class_type] = combat_table.totals [class_type] - self.total if (self.grupo) then combat_table.totals_grupo [class_type] = combat_table.totals_grupo [class_type] - self.total end end - function atributo_damage:add_total (combat_table) + function damageClass:add_total (combat_table) combat_table.totals [class_type] = combat_table.totals [class_type] + self.total if (self.grupo) then combat_table.totals_grupo [class_type] = combat_table.totals_grupo [class_type] + self.total @@ -5911,7 +6183,7 @@ end end --restaura a tabela de last event - function atributo_damage:r_last_events_table (actor) + function damageClass:r_last_events_table (actor) if (not actor) then actor = self end @@ -5919,7 +6191,7 @@ end end --restaura e liga o ator com a sua shadow durante a inicializa��o (startup function) - function atributo_damage:r_onlyrefresh_shadow (actor) + function damageClass:r_onlyrefresh_shadow (actor) --criar uma shadow desse ator se ainda n�o tiver uma local overall_dano = Details.tabela_overall [1] local shadow = overall_dano._ActorTable [overall_dano._NameIndexTable [actor.nome]] @@ -5985,7 +6257,7 @@ end return shadow end - function atributo_damage:r_connect_shadow (actor, no_refresh, combat_object) + function damageClass:r_connect_shadow (actor, no_refresh, combat_object) --check if there's a custom combat, if not just use the overall container local host_combat = combat_object or Details.tabela_overall @@ -6228,7 +6500,7 @@ function Details.SumDamageActors(actor1, actor2, actorContainer) end -atributo_damage.__add = function(tabela1, tabela2) +damageClass.__add = function(tabela1, tabela2) --tempo decorrido local tempo = (tabela2.end_time or time()) - tabela2.start_time @@ -6337,7 +6609,7 @@ atributo_damage.__add = function(tabela1, tabela2) return tabela1 end -atributo_damage.__sub = function(tabela1, tabela2) +damageClass.__sub = function(tabela1, tabela2) --tempo decorrido local tempo = (tabela2.end_time or time()) - tabela2.start_time diff --git a/frames/window_playerbreakdown.lua b/frames/window_playerbreakdown.lua index 35a6e762..021f2f83 100644 --- a/frames/window_playerbreakdown.lua +++ b/frames/window_playerbreakdown.lua @@ -431,22 +431,29 @@ end ---@param instance instance function Details222.BreakdownWindow.SendSpellData(data, actorObject, combatObject, instance) --need to get the tab showing the summary and transmit the data to it - local tab = Details222.BreakdownWindow.CurrentDefaultTab - if (tab) then + local tabButton = Details222.BreakdownWindow.CurrentDefaultTab + if (tabButton) then --tab is the tab button - if (tab.OnReceiveSpellData) then - tab.OnReceiveSpellData(data, actorObject, combatObject, instance) + if (tabButton.OnReceiveSpellData) then + tabButton.OnReceiveSpellData(data, actorObject, combatObject, instance) end end end function Details222.BreakdownWindow.SendTargetData(targetList, actorObject, combatObject, instance) - --need to get the tab showing the summary and transmit the data to it - local tab = Details222.BreakdownWindow.CurrentDefaultTab - if (tab) then - --tab is the tab button - if (tab.OnReceiveTargetData) then - tab.OnReceiveTargetData(targetList, actorObject, combatObject, instance) + local tabButton = Details222.BreakdownWindow.CurrentDefaultTab + if (tabButton) then + if (tabButton.OnReceiveTargetData) then + tabButton.OnReceiveTargetData(targetList, actorObject, combatObject, instance) + end + end +end + +function Details222.BreakdownWindow.SendGenericData(resultTable, actorObject, combatObject, instance) + local tabButton = Details222.BreakdownWindow.CurrentDefaultTab + if (tabButton) then + if (tabButton.OnReceiveGenericData) then + tabButton.OnReceiveGenericData(resultTable, actorObject, combatObject, instance) end end end diff --git a/frames/window_playerbreakdown_spells.lua b/frames/window_playerbreakdown_spells.lua index 9259eb79..45e8f446 100644 --- a/frames/window_playerbreakdown_spells.lua +++ b/frames/window_playerbreakdown_spells.lua @@ -85,6 +85,11 @@ function spellsTab.GetPhaseScrollFrame() return spellsTab.PhaseScrollFrame end +---@return breakdowntargetscrollframe +function spellsTab.GetGenericScrollFrame() + return spellsTab.GenericScrollFrame +end + ---@return df_framecontainer function spellsTab.GetSpellScrollContainer() return spellsTab.SpellContainerFrame @@ -105,6 +110,11 @@ function spellsTab.GetPhaseScrollContainer() return spellsTab.PhaseContainerFrame end +---@return df_framecontainer +function spellsTab.GetGenericScrollContainer() + return spellsTab.GenericContainerFrame +end + function spellsTab.GetScrollFrameByContainerType(containerType) if (containerType == "spells") then return spellsTab.GetSpellScrollFrame() @@ -114,6 +124,9 @@ function spellsTab.GetScrollFrameByContainerType(containerType) elseif (containerType == "phases") then return spellsTab.GetPhaseScrollFrame() + + elseif (containerType == "generic") then + return spellsTab.GetGenericScrollFrame() end end @@ -122,6 +135,7 @@ function spellsTab.OnProfileChange() spellsTab.UpdateHeadersSettings("spells") spellsTab.UpdateHeadersSettings("targets") spellsTab.UpdateHeadersSettings("phases") + spellsTab.UpdateHeadersSettings("generic") end ------------------------------------------------------------------------------------------------------------------------------------------------ @@ -135,7 +149,6 @@ local headerContainerType = {} local columnOffset = 0 ---column header information saved into details database: if is enabaled, its with and align ----@class headercolumndatasaved : {enabled: boolean, width: number, align: string} local settingsPrototype = { enabled = true, width = 100, @@ -190,8 +203,18 @@ local phaseContainerColumnData = { {name = "percent", label = "%", key = "total", width = 44, align = "left", enabled = true, canSort = true, sortKey = "total", dataType = "number", order = "DESC", offset = columnOffset}, } +--generic container can show data from any attribute +local genericContainerColumnData = { + {name = "icon", width = 22, label = "", align = "left", enabled = true, offset = columnOffset}, + {name = "name", label = "name", width = 200, align = "left", enabled = true, offset = columnOffset}, + {name = "rank", label = "#", width = 30, align = "left", enabled = true, offset = columnOffset}, + {name = "amount", label = "total", key = "total", width = 50, align = "left", enabled = true, canSort = true, sortKey = "total", dataType = "number", order = "DESC", offset = columnOffset, selected = true}, + {name = "persecond", label = "ps", key = "total", width = 50, align = "left", enabled = true, canSort = true, sortKey = "ps", dataType = "number", order = "DESC", offset = columnOffset}, + {name = "percent", label = "%", key = "total", width = 50, align = "left", enabled = true, canSort = true, sortKey = "total", dataType = "number", order = "DESC", offset = columnOffset}, +} + ---get the header settings from details saved variables and the container column data ----@param containerType "spells"|"targets"|"phases" +---@param containerType "spells"|"targets"|"phases"|"generic" ---@return headercolumndatabase ---@return columndata function spellsTab.GetHeaderSettings(containerType) @@ -210,6 +233,22 @@ function spellsTab.GetHeaderSettings(containerType) elseif (containerType == "phases") then settings = Details.breakdown_spell_tab.phasecontainer_headers containerColumnData = phaseContainerColumnData + + elseif (containerType == "generic") then + settings = Details.breakdown_spell_tab.genericcontainer_headers + containerColumnData = genericContainerColumnData + + --as the generic data is received, it may have which columns can be shown + if (spellsTab.headersAllowed) then + for index, columnData in ipairs(containerColumnData) do + local newEnabledState = spellsTab.headersAllowed[columnData.name] or false + columnData.enabled = newEnabledState + --check if the settings already has the data, and then set the header enabled value to follow the headersAllowed table + if (settings[columnData.name]) then + settings[columnData.name].enabled = newEnabledState + end + end + end end ---@cast settings headercolumndatabase @@ -222,7 +261,7 @@ end ---@param columnName string ---@param value any local onHeaderColumnOptionChanged = function(headerFrame, optionName, columnName, value) - ---@type "spells"|"targets"|"phases" + ---@type "spells"|"targets"|"phases"|"generic" local containerType = headerContainerType[headerFrame] ---@type headercolumndatabase local settings = spellsTab.GetHeaderSettings(containerType) @@ -244,7 +283,7 @@ end ---copy settings from the ColumnInfo table which doesn't exists in the details profile ---this is called when the profile changes or when the tab is opened with a different actor than before ----@param containerType "spells"|"targets"|"phases" +---@param containerType "spells"|"targets"|"phases"|"generic" function spellsTab.UpdateHeadersSettings(containerType) ---details table which hold the settings for a container header local settings, containerColumnData = spellsTab.GetHeaderSettings(containerType) @@ -303,12 +342,16 @@ function spellsTab.UpdateHeadersSettings(containerType) elseif (containerType == "phases") then spellsTab.phasesHeaderData = spellsTab.BuildHeaderTable(containerType) spellsTab.GetPhaseScrollFrame().Header:SetHeaderTable(spellsTab.phasesHeaderData) + + elseif (containerType == "generic") then + spellsTab.genericHeaderData = spellsTab.BuildHeaderTable(containerType) + spellsTab.GetGenericScrollFrame().Header:SetHeaderTable(spellsTab.genericHeaderData) end end ---get the header settings from details profile and build a header table using the table which store all headers columns information ---the data for each header is stored on 'spellContainerColumnInfo' and 'targetContainerColumnInfo' variables ----@param containerType "spells"|"targets"|"phases" +---@param containerType "spells"|"targets"|"phases"|"generic" ---@return {name: string, width: number, text: string, align: string}[] function spellsTab.BuildHeaderTable(containerType) ---@type headercolumndata[] @@ -456,6 +499,7 @@ function spellsTab.OnShownTab() spellsTab.UpdateHeadersSettings("spells") spellsTab.UpdateHeadersSettings("targets") spellsTab.UpdateHeadersSettings("phases") + spellsTab.UpdateHeadersSettings("generic") end ---called when the tab is getting created, run only once @@ -464,6 +508,11 @@ end function spellsTab.OnCreateTabCallback(tabButton, tabFrame) --~init spellBreakdownSettings = Details.breakdown_spell_tab + spellsTab.TabFrame = tabFrame + + --initialize the allowed headers for generic data container + spellsTab.headersAllowed = {icon = true, name = true, rank = true, amount = true, persecond = true, percent = true} + --create the scrollbar to show the spells in the breakdown window spellsTab.CreateSpellScrollContainer(tabFrame) --finished --create the 6 spell blocks in the right side of the breakdown window, these blocks show the spell info like normal hits, critical hits, average, etc @@ -472,12 +521,12 @@ function spellsTab.OnCreateTabCallback(tabButton, tabFrame) --~init spellsTab.CreateTargetContainer(tabFrame) --create phases container spellsTab.CreatePhasesContainer(tabFrame) + --create generic container + spellsTab.CreateGenericContainer(tabFrame) --create the report buttons for each container --spellsTab.CreateReportButtons(tabFrame) - spellsTab.TabFrame = tabFrame - --create a button in the breakdown window to open the options for this tab local optionsButton = DF:CreateButton(tabFrame, Details.OpenSpellBreakdownOptions, 130, 20, "options", 14, nil, nil, nil, nil, nil, DF:GetTemplate("button", "OPTIONS_BUTTON_TEMPLATE")) optionsButton:SetPoint("bottomright", tabFrame, "bottomright", -5, 5) @@ -603,185 +652,9 @@ local onEnterSpellBar = function(spellBar, motion) --parei aqui: precisa por nom summaryBlock:SetValue(100) if (mainAttribute == DETAILS_ATTRIBUTE_DAMAGE) then --this should run within the damage class ~damage - local bShowDamageDone = subAttribute == DETAILS_SUBATTRIBUTE_DAMAGEDONE or subAttribute == DETAILS_SUBATTRIBUTE_DPS - - ---@type number - local totalHits = spellTable.counter - - --damage section showing damage done sub section - blockIndex = blockIndex + 1 - - do --update the texts in the summary block - local blockLine1, blockLine2, blockLine3 = summaryBlock:GetLines() - - local totalCasts = spellBar.amountCasts > 0 and spellBar.amountCasts or "(?)" - blockLine1.leftText:SetText(Loc ["STRING_CAST"] .. ": " .. totalCasts) --total amount of casts - - if (trinketData[spellId] and combatObject.trinketProcs) then - local trinketProcData = combatObject.trinketProcs[actorName] - if (trinketProcData) then - local trinketProc = trinketProcData[spellId] - if (trinketProc) then - blockLine1.leftText:SetText("Procs: " .. trinketProc.total) - end - end - end - - blockLine1.rightText:SetText(Loc ["STRING_HITS"]..": " .. totalHits) --hits and uptime - - blockLine2.leftText:SetText(Loc ["STRING_DAMAGE"]..": " .. Details:Format(spellTable.total)) --total damage - blockLine2.rightText:SetText(Details:GetSpellSchoolFormatedName(spellTable.spellschool)) --spell school - - blockLine3.leftText:SetText(Loc ["STRING_AVERAGE"] .. ": " .. Details:Format(spellBar.average)) --average damage - blockLine3.rightText:SetText(Loc ["STRING_DPS"] .. ": " .. Details:CommaValue(spellBar.perSecond)) --dps - end - - local emporwerSpell = spellTable.e_total - if (emporwerSpell) then - local empowerLevelSum = spellTable.e_total --total sum of empower levels - local empowerAmount = spellTable.e_amt --amount of casts with empower - local empowerAmountPerLevel = spellTable.e_lvl --{[1] = 4; [2] = 9; [3] = 15} - local empowerDamagePerLevel = spellTable.e_dmg --{[1] = 54548745, [2] = 74548745} - - ---@type breakdownspellblock - local empowerBlock = spellBlockContainer:GetBlock(blockIndex) - blockIndex = blockIndex + 1 - - local level1AverageDamage = "0" - local level2AverageDamage = "0" - local level3AverageDamage = "0" - local level4AverageDamage = "0" - local level5AverageDamage = "0" - - if (empowerDamagePerLevel[1]) then - level1AverageDamage = Details:Format(empowerDamagePerLevel[1] / empowerAmountPerLevel[1]) - end - if (empowerDamagePerLevel[2]) then - level2AverageDamage = Details:Format(empowerDamagePerLevel[2] / empowerAmountPerLevel[2]) - end - if (empowerDamagePerLevel[3]) then - level3AverageDamage = Details:Format(empowerDamagePerLevel[3] / empowerAmountPerLevel[3]) - end - if (empowerDamagePerLevel[4]) then - level4AverageDamage = Details:Format(empowerDamagePerLevel[4] / empowerAmountPerLevel[4]) - end - if (empowerDamagePerLevel[5]) then - level5AverageDamage = Details:Format(empowerDamagePerLevel[5] / empowerAmountPerLevel[5]) - end - - empowerBlock:Show() - empowerBlock:SetValue(100) - - empowerBlock.sparkTexture:SetPoint("left", empowerBlock, "left", empowerBlock:GetWidth() + spellBreakdownSettings.blockspell_spark_offset, 0) - empowerBlock:SetColor(0.200, 0.576, 0.498, 0.6) - - local blockLine1, blockLine2, blockLine3 = empowerBlock:GetLines() - blockLine1.leftText:SetText("Spell Empower Average Level: " .. string.format("%.2f", empowerLevelSum / empowerAmount)) - - if (level1AverageDamage ~= "0") then - blockLine2.leftText:SetText("Level 1 Avg: " .. level1AverageDamage .. " (" .. (empowerAmountPerLevel[1] or 0) .. ")") - end - - if (level2AverageDamage ~= "0") then - blockLine2.centerText:SetText("Level 2 Avg: " .. level2AverageDamage .. " (" .. (empowerAmountPerLevel[2] or 0) .. ")") - end - - if (level3AverageDamage ~= "0") then - blockLine2.rightText:SetText("Level 3 Avg: " .. level3AverageDamage .. " (" .. (empowerAmountPerLevel[3] or 0) .. ")") - end - - if (level4AverageDamage ~= "0") then - blockLine3.leftText:SetText("Level 4 Avg: " .. level4AverageDamage .. " (" .. (empowerAmountPerLevel[4] or 0) .. ")") - end - - if (level5AverageDamage ~= "0") then - blockLine3.rightText:SetText("Level 5 Avg: " .. level5AverageDamage .. " (" .. (empowerAmountPerLevel[5] or 0) .. ")") - end - end - - --check if there's normal hits and build the block - ---@type number - local normalHitsAmt = spellTable.n_amt - - if (normalHitsAmt > 0) then - ---@type breakdownspellblock - local normalHitsBlock = spellBlockContainer:GetBlock(blockIndex) - normalHitsBlock:Show() - blockIndex = blockIndex + 1 - - local percent = normalHitsAmt / math.max(totalHits, 0.0001) * 100 - normalHitsBlock:SetValue(percent) - normalHitsBlock.sparkTexture:SetPoint("left", normalHitsBlock, "left", percent / 100 * normalHitsBlock:GetWidth() + Details.breakdown_spell_tab.blockspell_spark_offset, 0) - - local blockLine1, blockLine2, blockLine3 = normalHitsBlock:GetLines() - blockLine1.leftText:SetText(Loc ["STRING_NORMAL_HITS"]) - blockLine1.rightText:SetText(normalHitsAmt .. " [|cFFC0C0C0" .. string.format("%.1f", normalHitsAmt / math.max(totalHits, 0.0001) * 100) .. "%|r]") - - blockLine2.leftText:SetText(Loc ["STRING_MINIMUM_SHORT"] .. ": " .. Details:CommaValue(spellTable.n_min)) - blockLine2.rightText:SetText(Loc ["STRING_MAXIMUM_SHORT"] .. ": " .. Details:CommaValue(spellTable.n_max)) - - local normalAverage = spellTable.n_total / math.max(normalHitsAmt, 0.0001) - blockLine3.leftText:SetText(Loc ["STRING_AVERAGE"] .. ": " .. Details:CommaValue(normalAverage)) - - local tempo = (elapsedTime * spellTable.n_total) / math.max(spellTable.total, 0.001) - local normalAveragePercent = spellBar.average / normalAverage * 100 - local normalTempoPercent = normalAveragePercent * tempo / 100 - blockLine3.rightText:SetText(Loc ["STRING_DPS"] .. ": " .. Details:CommaValue(spellTable.n_total / normalTempoPercent)) - end - - ---@type number - local criticalHitsAmt = spellTable.c_amt - if (criticalHitsAmt > 0) then - ---@type breakdownspellblock - local critHitsBlock = spellBlockContainer:GetBlock(blockIndex) - critHitsBlock:Show() - blockIndex = blockIndex + 1 - - local percent = Details.SpellTableMixin.GetCritPercent(spellTable) - critHitsBlock:SetValue(percent) - critHitsBlock.sparkTexture:SetPoint("left", critHitsBlock, "left", percent / 100 * critHitsBlock:GetWidth() + spellBreakdownSettings.blockspell_spark_offset, 0) - - local blockLine1, blockLine2, blockLine3 = critHitsBlock:GetLines() - blockLine1.leftText:SetText(Loc ["STRING_CRITICAL_HITS"]) - blockLine1.rightText:SetText(criticalHitsAmt .. " [|cFFC0C0C0" .. string.format("%.1f", criticalHitsAmt / math.max(totalHits, 0.0001) * 100) .. "%|r]") - - blockLine2.leftText:SetText(Loc ["STRING_MINIMUM_SHORT"] .. ": " .. Details:CommaValue(spellTable.c_min)) - blockLine2.rightText:SetText(Loc ["STRING_MAXIMUM_SHORT"] .. ": " .. Details:CommaValue(spellTable.c_max)) - - local critAverage = Details.SpellTableMixin.GetCritAverage(spellTable) - blockLine3.leftText:SetText(Loc ["STRING_AVERAGE"] .. ": " .. Details:CommaValue(critAverage)) - - local tempo = (elapsedTime * spellTable.c_total) / math.max(spellTable.total, 0.001) - local critAveragePercent = spellBar.average / critAverage * 100 - local critTempoPercent = critAveragePercent * tempo / 100 - blockLine3.rightText:SetText(Loc ["STRING_DPS"] .. ": " .. Details:CommaValue(spellTable.c_total / critTempoPercent)) - end - - if (trinketData[spellId]) then - ---@type trinketdata - local trinketInfo = trinketData[spellId] - - local minTime = trinketInfo.minTime - local maxTime = trinketInfo.maxTime - local average = trinketInfo.averageTime - - ---@type breakdownspellblock - local trinketBlock = spellBlockContainer:GetBlock(blockIndex) - trinketBlock:Show() - trinketBlock:SetValue(100) - trinketBlock.sparkTexture:SetPoint("left", trinketBlock, "left", trinketBlock:GetWidth() + spellBreakdownSettings.blockspell_spark_offset, 0) - blockIndex = blockIndex + 1 - - local blockLine1, blockLine2, blockLine3 = trinketBlock:GetLines() - blockLine1.leftText:SetText("Trinket Info") - - blockLine1.rightText:SetText("PPM: " .. string.format("%.2f", average / 60)) - if (minTime == 9999999) then - blockLine2.leftText:SetText("Min Time: " .. _G["UNKNOWN"]) - else - blockLine2.leftText:SetText("Min Time: " .. math.floor(minTime)) - end - blockLine2.rightText:SetText("Max Time: " .. math.floor(maxTime)) + --bounce to damage class to handle the spell details + if (subAttribute == 1 or subAttribute == 2 or subAttribute == 6) then + Details.atributo_damage:BuildSpellDetails(spellBar, spellBlockContainer, blockIndex, summaryBlock, spellId, elapsedTime, actorName, spellTable, trinketData, combatObject) end elseif (mainAttribute == DETAILS_ATTRIBUTE_HEAL) then --this should run within the heal class ~healing @@ -1190,8 +1063,16 @@ function spellsTab.CreateSpellBlockContainer(tabFrame) --~create ~createblock ~s if (settingName == "UpdateSize") then --get the tabFrame width and height local width, height = tabFrame:GetSize() + local containerWidth + --get with of the container holding the spellscrollframe - local containerWidth = spellsTab.GetSpellScrollContainer():GetWidth() + if (spellsTab.GetSpellScrollContainer():IsShown()) then + containerWidth = spellsTab.GetSpellScrollContainer():GetWidth() + + elseif (spellsTab.GetGenericScrollContainer():IsShown()) then + containerWidth = spellsTab.GetGenericScrollContainer():GetWidth() + end + --calculate the widh of the spellblockcontainer by subtracting the width of the spellscrollframe container from the tabFrame width local spellBlockContainerWidth = width - containerWidth - 38 --set the width of the spellblockcontainer @@ -1514,6 +1395,26 @@ function spellsTab.CreatePhaseBar(self, index) --~create ~createphase ~phasebar return phaseBar end +---get a spell bar from the scroll box, if it doesn't exist, return nil +---@param scrollFrame table +---@param lineIndex number +---@return breakdownphasebar +local getGenericBar = function(scrollFrame, lineIndex) + ---@type breakdowngenericbar + local genericBar = scrollFrame:GetLine(lineIndex) + + --reset header alignment + genericBar:ResetFramesToHeaderAlignment() + + --reset columns, hiding them + genericBar.Icon:Hide() + for inLineIndex = 1, #genericBar.InLineTexts do + genericBar.InLineTexts[inLineIndex]:SetText("") + end + + return genericBar +end + ---get a spell bar from the scroll box, if it doesn't exist, return nil ---@param scrollFrame table ---@param lineIndex number @@ -1538,7 +1439,86 @@ end ---@param scrollData table ---@param offset number ---@param totalLines number -local refreshPhaseFunc = function(scrollFrame, scrollData, offset, totalLines) --~refreshspells ~refreshfunc ~refresh ~refreshp ~updatephasebar +local refreshGenericFunc = function(scrollFrame, scrollData, offset, totalLines) --~refreshgeneric ~refreshfunc ~refresh ~refreshg ~updategenericbar + local lineIndex = 1 + local combatTime = scrollData.combatTime + local totalValue = scrollData.totalValue + + for i = 1, totalLines do + local index = i + offset + local dataTable = scrollData[index] + + if (dataTable) then + local genericBar = getGenericBar(scrollFrame, lineIndex) + genericBar.statusBar:SetValue(dataTable.total / scrollFrame.topValue * 100) + + ---@type number + local textIndex = 1 + + if (scrollData.headersAllowed.icon) then + ---@type texturetable + local dataIcon = dataTable.icon + genericBar.Icon:Show() + genericBar.Icon:SetTexture(dataIcon.texture) + genericBar.Icon:SetTexCoord(dataIcon.coords.left, dataIcon.coords.right, dataIcon.coords.top, dataIcon.coords.bottom) + genericBar.Icon:SetSize(CONST_SPELLSCROLL_LINEHEIGHT-2, CONST_SPELLSCROLL_LINEHEIGHT-2) + genericBar:AddFrameToHeaderAlignment(genericBar.Icon) + end + + if (scrollData.headersAllowed.name) then + ---@type fontstring + local fontString = genericBar.InLineTexts[textIndex] + genericBar:AddFrameToHeaderAlignment(fontString) + fontString:SetText(dataTable.name) + textIndex = textIndex + 1 + end + + if (scrollData.headersAllowed.rank) then + ---@type fontstring + local fontString = genericBar.InLineTexts[textIndex] + genericBar:AddFrameToHeaderAlignment(fontString) + fontString:SetText(index) + textIndex = textIndex + 1 + end + + if (scrollData.headersAllowed.amount) then + ---@type fontstring + local fontString = genericBar.InLineTexts[textIndex] + genericBar:AddFrameToHeaderAlignment(fontString) + fontString:SetText(Details:Format(dataTable.total)) + textIndex = textIndex + 1 + end + + if (scrollData.headersAllowed.persecond) then + ---@type fontstring + local fontString = genericBar.InLineTexts[textIndex] + genericBar:AddFrameToHeaderAlignment(fontString) + fontString:SetText(Details:Format(dataTable.total / combatTime)) + textIndex = textIndex + 1 + end + + if (scrollData.headersAllowed.percent) then + ---@type fontstring + local fontString = genericBar.InLineTexts[textIndex] + genericBar:AddFrameToHeaderAlignment(fontString) + fontString:SetText(string.format("%.1f", dataTable.total / totalValue * 100) .. "%") + textIndex = textIndex + 1 + end + + lineIndex = lineIndex + 1 + if (lineIndex > totalLines) then + break + end + end + end +end + + +---@param scrollFrame table +---@param scrollData table +---@param offset number +---@param totalLines number +local refreshPhaseFunc = function(scrollFrame, scrollData, offset, totalLines) --~refreshphases ~refreshfunc ~refresh ~refreshp ~updatephasebar local lineIndex = 1 local formatFunc = Details:GetCurrentToKFunction() local phaseElapsedTime = scrollData.phaseElapsed @@ -1772,13 +1752,217 @@ function spellsTab.CreatePhasesContainer(tabFrame) --~phase ~createphasecontaine phaseScrollFrame:CreateLine(spellsTab.CreatePhaseBar) end - tabFrame.phases = tabFrame:CreateFontString(nil, "overlay", "QuestFont_Large") + tabFrame.phases = container:CreateFontString(nil, "overlay", "QuestFont_Large") tabFrame.phases:SetPoint("bottomleft", container, "topleft", 2, 2) tabFrame.phases:SetText("Phases:") --localize-me return phaseScrollFrame end +---create a genericbar within the generic scroll +---@param self breakdowngenericscrollframe +---@param index number +---@return breakdowngenericbar +function spellsTab.CreateGenericBar(self, index) --~create ~generic ~creategeneric ~genericbar + ---@type breakdowngenericbar + local genericBar = CreateFrame("button", self:GetName() .. "GenericBarButton" .. index, self) + genericBar.index = index + + --size and positioning + genericBar:SetHeight(CONST_SPELLSCROLL_LINEHEIGHT) + local y = (index-1) * CONST_SPELLSCROLL_LINEHEIGHT * -1 + (1 * -index) - 15 + genericBar:SetPoint("topleft", self, "topleft", 0, y) + genericBar:SetPoint("topright", self, "topright", 0, y) + + genericBar:EnableMouse(true) + + genericBar:SetAlpha(0.9) + genericBar:SetFrameStrata("HIGH") + genericBar:SetScript("OnEnter", onEnterBreakdownGenericBar) + genericBar:SetScript("OnLeave", onLeaveBreakdownGenericBar) + + DF:Mixin(genericBar, DF.HeaderFunctions) + + ---@type breakdownspellbarstatusbar + local statusBar = CreateFrame("StatusBar", "$parentStatusBar", genericBar) + statusBar:SetAllPoints() + statusBar:SetAlpha(0.5) + statusBar:SetMinMaxValues(0, 100) + statusBar:SetValue(50) + statusBar:EnableMouse(false) + statusBar:SetFrameLevel(genericBar:GetFrameLevel() - 1) + genericBar.statusBar = statusBar + + ---@type texture this is the statusbar texture + local statusBarTexture = statusBar:CreateTexture("$parentTexture", "artwork") + statusBarTexture:SetTexture(SharedMedia:Fetch("statusbar", "Details Hyanda")) + statusBar:SetStatusBarTexture(statusBarTexture) + statusBar:SetStatusBarColor(1, 1, 1, 1) + + ---@type texture shown when the mouse hoverover this bar + local hightlightTexture = statusBar:CreateTexture("$parentTextureHighlight", "highlight") + hightlightTexture:SetColorTexture(1, 1, 1, 0.2) + hightlightTexture:SetAllPoints() + statusBar.highlightTexture = hightlightTexture + + ---@type texture background texture + local backgroundTexture = statusBar:CreateTexture("$parentTextureBackground", "border") + backgroundTexture:SetAllPoints() + backgroundTexture:SetColorTexture(.05, .05, .05) + backgroundTexture:SetAlpha(1) + statusBar.backgroundTexture = backgroundTexture + + --create an icon + ---@type texture + local icon = statusBar:CreateTexture("$parentTexture", "overlay") + icon:SetPoint("left", statusBar, "left", 0, 0) + icon:SetSize(CONST_SPELLSCROLL_LINEHEIGHT-2, CONST_SPELLSCROLL_LINEHEIGHT-2) + icon:SetTexCoord(.1, .9, .1, .9) + genericBar.Icon = icon + + genericBar:AddFrameToHeaderAlignment(icon) + + genericBar.InLineTexts = {} + + for i = 1, 5 do + ---@type fontstring + local fontString = genericBar:CreateFontString("$parentFontString" .. i, "overlay", "GameFontHighlightSmall") + fontString:SetJustifyH("left") + fontString:SetTextColor(1, 1, 1, 1) + fontString:SetNonSpaceWrap(true) + fontString:SetWordWrap(false) + genericBar["lineText" .. i] = fontString + genericBar.InLineTexts[i] = fontString + fontString:SetTextColor(1, 1, 1, 1) + genericBar:AddFrameToHeaderAlignment(fontString) + end + + genericBar:AlignWithHeader(self.Header, "left") + + return genericBar +end + +---create the generic container, this container hold bars that can show any type of data +---@param tabFrame tabframe +---@return breakdowngenericscrollframe +function spellsTab.CreateGenericContainer(tabFrame) --~create ~generic ~creategenericcontainer ~creategenericscroll ~creategeneric + ---@type width + local width = Details.breakdown_spell_tab.genericcontainer_width + ---@type height + local height = Details.breakdown_spell_tab.genericcontainer_height + + local defaultAmountOfLines = 50 + + --create a container for the scrollframe + local options = { + width = Details.breakdown_spell_tab.genericcontainer_width, + height = Details.breakdown_spell_tab.genericcontainer_height, + is_locked = Details.breakdown_spell_tab.genericcontainer_islocked, + can_move = false, + can_move_children = false, + use_top_resizer = true, + use_right_resizer = true, + use_bottom_resizer = true, + use_left_resizer = true, + } + + ---@type df_framecontainer + local container = DF:CreateFrameContainer(tabFrame, options, tabFrame:GetName() .. "GenericScrollContainer") + container:SetPoint("topleft", tabFrame, "topleft", 0, 0) + container:SetFrameLevel(tabFrame:GetFrameLevel()+1) + spellsTab.GenericContainerFrame = container + + --when a setting is changed in the container, it will call this function, it is registered below with SetSettingChangedCallback() + local settingChangedCallbackFunction = function(frameContainer, settingName, settingValue) + if (frameContainer:IsShown()) then + if (settingName == "height") then + ---@type number + local currentHeight = spellsTab.GetGenericScrollFrame():GetHeight() + Details.breakdown_spell_tab.genericcontainer_height = settingValue + spellsTab.GetGenericScrollFrame():SetNumFramesShown(math.floor(currentHeight / CONST_SPELLSCROLL_LINEHEIGHT) - 2) + + elseif (settingName == "width") then + Details.breakdown_spell_tab.genericcontainer_width = settingValue + + elseif (settingName == "is_locked") then + Details.breakdown_spell_tab.genericcontainer_islocked = settingValue + end + + spellsTab.GetSpellBlockContainer():SendSettingChangedCallback("UpdateSize", -1) + end + end + container:SetSettingChangedCallback(settingChangedCallbackFunction) + + --create a scrollframe + local genericScrollFrame = DF:CreateScrollBox(container, "$parentGenericScroll", refreshGenericFunc, {}, width, height, defaultAmountOfLines, CONST_SPELLSCROLL_LINEHEIGHT) + DF:ReskinSlider(genericScrollFrame) + genericScrollFrame:SetBackdrop({}) + genericScrollFrame:SetAllPoints() + + container:RegisterChildForDrag(genericScrollFrame) + + genericScrollFrame.DontHideChildrenOnPreRefresh = false + tabFrame.GenericScrollFrame = genericScrollFrame + spellsTab.GenericScrollFrame = genericScrollFrame + + --settingChangedCallbackFunction(container, "height", Details.breakdown_spell_tab.genericcontainer_height) + + function genericScrollFrame:RefreshMe(data) --~refreshme (generic) ~refreshg + --get which column is currently selected and the sort order + local columnIndex, order, key = genericScrollFrame.Header:GetSelectedColumn() + genericScrollFrame.SortKey = key + + ---@type string + local keyToSort = key + + if (order == "DESC") then + table.sort(data, + function(t1, t2) + return t1[keyToSort] > t2[keyToSort] + end) + genericScrollFrame.topValue = data[1] and data[1][keyToSort] + else + table.sort(data, + function(t1, t2) + return t1[keyToSort] < t2[keyToSort] + end) + genericScrollFrame.topValue = data[#data] and data[#data][keyToSort] + end + + genericScrollFrame:SetData(data) + genericScrollFrame:Refresh() + end + + --~header + local headerOptions = { + padding = 2, + header_height = 14, + + reziser_shown = true, + reziser_width = 2, + reziser_color = {.5, .5, .5, 0.7}, + reziser_max_width = 246, + } + + ---@type df_headerframe + local header = DetailsFramework:CreateHeader(container, genericContainerColumnData, headerOptions) + genericScrollFrame.Header = header + genericScrollFrame.Header:SetPoint("topleft", genericScrollFrame, "topleft", 0, 1) + genericScrollFrame.Header:SetColumnSettingChangedCallback(onHeaderColumnOptionChanged) + + --cache the type of this container + headerContainerType[genericScrollFrame.Header] = "generic" + + --create the scroll lines + for i = 1, defaultAmountOfLines do + genericScrollFrame:CreateLine(spellsTab.CreateGenericBar) + end + + --need to create the second scroll frame to show the details about the spelltable/actor hovered over + + return genericScrollFrame +end + ---create the target container ---@param tabFrame tabframe ---@return breakdowntargetscrollframe @@ -1831,7 +2015,7 @@ function spellsTab.CreateTargetContainer(tabFrame) --~create ~target ~createtarg --create the scrollframe similar to scrollframe used in the spellscrollframe --replace this with a framework scrollframe ---@type breakdowntargetscrollframe - local targetScrollFrame = DF:CreateScrollBox(container, "$parentSpellScroll", refreshTargetsFunc, {}, width, height, defaultAmountOfLines, CONST_SPELLSCROLL_LINEHEIGHT) + local targetScrollFrame = DF:CreateScrollBox(container, "$parentTargetScroll", refreshTargetsFunc, {}, width, height, defaultAmountOfLines, CONST_SPELLSCROLL_LINEHEIGHT) DF:ReskinSlider(targetScrollFrame) targetScrollFrame:SetBackdrop({}) targetScrollFrame:SetAllPoints() @@ -2902,6 +3086,15 @@ function Details.InitializeSpellBreakdownTab() spellsTab.mainAttribute = mainAttribute spellsTab.subAttribute = subAttribute + --show the regular containers + spellsTab.GetSpellScrollContainer():Show() + spellsTab.GetPhaseScrollContainer():Show() + spellsTab.GetTargetScrollContainer():Show() + + --hide the generic container + spellsTab.GetGenericScrollContainer():Hide() + + --refresh the data spellsTab.GetSpellScrollFrame():RefreshMe(data) spellsTab.GetPhaseScrollFrame():RefreshMe(data) end @@ -2918,6 +3111,35 @@ function Details.InitializeSpellBreakdownTab() spellsTab.GetTargetScrollFrame():RefreshMe(data) end + ---when the window handler sends data which is not a spell or target data + ---@param data table + ---@param actorObject actor + ---@param combatObject combat + ---@param instance instance + function tabButton.OnReceiveGenericData(data, actorObject, combatObject, instance) + ---@type number, number + local mainAttribute, subAttribute = instance:GetDisplay() + spellsTab.mainAttribute = mainAttribute + spellsTab.subAttribute = subAttribute + + if (spellsTab.headersAllowed ~= data.headersAllowed) then + --refresh the header frame + spellsTab.UpdateHeadersSettings("generic") + --bug: now allowing to sort + end + + --when generic data is shown, the damage-healing-targets-scrolls / spell details blocks/ can be removed + spellsTab.GetSpellScrollContainer():Hide() + spellsTab.GetPhaseScrollContainer():Hide() + spellsTab.GetTargetScrollContainer():Hide() + + --show the generic scroll + spellsTab.GetGenericScrollContainer():Show() + + --refresh the data + spellsTab.GetGenericScrollFrame():RefreshMe(data) + end + ---@type detailseventlistener local eventListener = Details:CreateEventListener() eventListener:RegisterEvent("DETAILS_PROFILE_APPLYED", function() diff --git a/functions/playerclass.lua b/functions/playerclass.lua index e0abe347..d9aae4b6 100644 --- a/functions/playerclass.lua +++ b/functions/playerclass.lua @@ -12,11 +12,63 @@ do local openRaidLib = LibStub:GetLibrary("LibOpenRaid-1.0", true) local unknown_class_coords = {0.75, 1, 0.75, 1} + ---return a table containing information about the texture to use for the actor icon + ---@param actorObject actor + ---@return texturetable + function Details:GetActorIcon(actorObject) + ---@type instance + local instance = Details:GetInstance(1) + + local spec = actorObject:Spec() + if (spec and spec > 0) then + ---@type string + local fileName + + --get the spec icon file currently in use + if (instance) then + fileName = instance.row_info.spec_file + else + fileName = Details.instance_defaults.row_info.spec_file + end + + local left, right, top, bottom = unpack(Details.class_specs_coords[spec]) + + local textureTable = { + texture = fileName, + coords = {left = left, right = right, top = top, bottom = bottom}, + size = {height = 16, width = 16}, + } + + return textureTable + end + + local class = actorObject:Class() or "UNKNOW" + local left, right, top, bottom = unpack(Details.class_coords[class]) + + ---@type string + local fileName + --get the spec icon file currently in use + if (instance) then + fileName = instance.row_info.icon_file + else + fileName = Details.instance_defaults.row_info.icon_file + end + + local textureTable = { + texture = fileName, + coords = {left = left, right = right, top = top, bottom = bottom}, + size = {height = 16, width = 16}, + } + + return textureTable + end + + function Details:GetUnknownClassIcon() return [[Interface\AddOns\Details\images\classes_small]], unpack(unknown_class_coords) end - function Details:GetIconTexture (iconType, withAlpha) + function Details:GetIconTexture(iconType, withAlpha) iconType = string.lower(iconType) if (iconType == "spec") then @@ -37,16 +89,16 @@ do -- try get the class from actor name function Details:GetClass(name) - local _, class = UnitClass (name) + local _, class = UnitClass(name) if (not class) then for index, container in ipairs(Details.tabela_overall) do - local index = container._NameIndexTable [name] + local index = container._NameIndexTable[name] if (index) then - local actor = container._ActorTable [index] + local actor = container._ActorTable[index] if (actor.classe ~= "UNGROUPPLAYER") then - local left, right, top, bottom = unpack(Details.class_coords [actor.classe] or unknown_class_coords) - local r, g, b = unpack(Details.class_colors [actor.classe]) + local left, right, top, bottom = unpack(Details.class_coords[actor.classe] or unknown_class_coords) + local r, g, b = unpack(Details.class_colors[actor.classe]) return actor.classe, left, right, top, bottom, r or 1, g or 1, b or 1 end end @@ -54,8 +106,8 @@ do return "UNKNOW", 0.75, 1, 0.75, 1, 1, 1, 1, 1 else - local left, right, top, bottom = unpack(Details.class_coords [class]) - local r, g, b = unpack(Details.class_colors [class]) + local left, right, top, bottom = unpack(Details.class_coords[class]) + local r, g, b = unpack(Details.class_colors[class]) return class, left, right, top, bottom, r or 1, g or 1, b or 1 end end @@ -69,7 +121,7 @@ do NONE = {0, 50/512, 110/512, 150/512}, } function Details:GetRoleIcon (role) - return [[Interface\AddOns\Details\images\icons2]], unpack(roles [role]) + return [[Interface\AddOns\Details\images\icons2]], unpack(roles[role]) end function Details:GetClassIcon(class) diff --git a/functions/profiles.lua b/functions/profiles.lua index f01e14ce..28b917d0 100644 --- a/functions/profiles.lua +++ b/functions/profiles.lua @@ -1408,7 +1408,7 @@ local default_global_data = { }, }, ---/run Details.breakdown_spell_tab.targetcontainer_height = 140 +--/run wipe(Details.breakdown_spell_tab) .genericcontainer_headers --breakdown spell tab breakdown_spell_tab = { blockcontainer_width = 430, @@ -1440,11 +1440,18 @@ local default_global_data = { phasecontainer_height = 140, phasecontainer_islocked = true, + genericcontainer_enabled = true, + genericcontainer_width = 429, + genericcontainer_height = 311 + 140 + 30, + genericcontainer_islocked = true, + spellbar_background_alpha = 0.92, spellcontainer_headers = {}, --store information about active headers and their sizes (spells) targetcontainer_headers = {}, --store information about active headers and their sizes (target) phasecontainer_headers = {}, --store information about active headers and their sizes (phases) + genericcontainer_headers = {}, --store information about active headers and their sizes (generic) + spellcontainer_header_height = 20, spellcontainer_header_fontsize = 10, spellcontainer_header_fontcolor = {1, 1, 1, 1},