You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1606 lines
59 KiB
1606 lines
59 KiB
|
|
local addonName, Details222 = ...
|
|
local breakdownWindow = Details.BreakdownWindow
|
|
local Loc = LibStub("AceLocale-3.0"):GetLocale("Details")
|
|
local SharedMedia = LibStub:GetLibrary("LibSharedMedia-3.0")
|
|
local unpack = unpack
|
|
local GetTime = GetTime
|
|
local CreateFrame = CreateFrame
|
|
local GetSpellLink = GetSpellLink or C_Spell.GetSpellLink --api local
|
|
local GetSpellInfo = Details222.GetSpellInfo
|
|
local _GetSpellInfo = Details.GetSpellInfo
|
|
local GameTooltip = GameTooltip
|
|
local IsShiftKeyDown = IsShiftKeyDown
|
|
local tinsert = table.insert
|
|
|
|
---@type detailsframework
|
|
local DF = DetailsFramework
|
|
---@type detailsframework
|
|
local detailsFramework = DetailsFramework
|
|
|
|
local spellsTab = DetailsSpellBreakdownTab
|
|
|
|
local CONST_BAR_HEIGHT = 20
|
|
local CONST_SPELLSCROLL_LINEHEIGHT = 20
|
|
local CONST_TARGET_TEXTURE = [[Interface\MINIMAP\TRACKING\Target]]
|
|
local CONST_SPELLBLOCK_DEFAULT_COLOR = {.4, .4, .4, 1}
|
|
local CONST_SPELLBLOCK_HEADERTEXT_COLOR = {.9, .8, 0, 1}
|
|
local CONST_SPELLBLOCK_HEADERTEXT_SIZE = 11
|
|
|
|
local spellBlockContainerSettings = {
|
|
amount = 6, --amount of block the container have
|
|
lineAmount = 3, --amount of line each block have
|
|
}
|
|
|
|
local headerContainerType = spellsTab.headerContainerType
|
|
|
|
local formatPetName = function(petName, spellName, ownerName)
|
|
--remove the owner name from the pet name
|
|
local petNameWithoutOwner = petName:gsub((" <.*"), "")
|
|
|
|
local texture = [[Interface\AddOns\Details\images\classes_small]]
|
|
|
|
local bUseAlphaIcons = true
|
|
local specIcon = nil
|
|
local iconSize = 14
|
|
|
|
if (petName:len() == 0) then
|
|
return Details:AddClassOrSpecIcon(spellName, "PET", specIcon, iconSize, bUseAlphaIcons)
|
|
end
|
|
|
|
petNameWithoutOwner = Details:AddClassOrSpecIcon(petNameWithoutOwner, "PET", specIcon, iconSize, bUseAlphaIcons)
|
|
|
|
return spellName .. " |cFFCCBBBB" .. petNameWithoutOwner .. "|r"
|
|
end
|
|
|
|
---some values required by the header sort key is not available in the spellTable, so they need to be calculated
|
|
---@param combatObject combat
|
|
---@param spellData spelltable|spelltableadv
|
|
---@param key string
|
|
---@return any
|
|
local getValueForHeaderSortKey = function(combatObject, spellData, key)
|
|
if (key == "critpercent") then
|
|
return Details.SpellTableMixin.GetCritPercent(spellData)
|
|
|
|
elseif (key == "casts") then
|
|
local spellName = GetSpellInfo(spellData.id)
|
|
local amountOfCasts = combatObject:GetSpellCastAmount(spellsTab.GetActor():Name(), spellName)
|
|
return amountOfCasts
|
|
|
|
elseif (key == "castavg") then
|
|
local spellName = GetSpellInfo(spellData.id)
|
|
local amountOfCasts = combatObject:GetSpellCastAmount(spellsTab.GetActor():Name(), spellName)
|
|
return Details.SpellTableMixin.GetCastAverage(spellData, amountOfCasts)
|
|
|
|
elseif (key == "uptime") then
|
|
return combatObject:GetSpellUptime(spellsTab.GetActor():Name(), spellData.id)
|
|
|
|
elseif (key == "healabsorbed") then
|
|
return spellData.absorbed
|
|
end
|
|
end
|
|
|
|
---run when the user clicks the columnHeader
|
|
---@param headerFrame df_headerframe
|
|
---@param columnHeader df_headercolumnframe
|
|
local onColumnHeaderClickCallback = function(headerFrame, columnHeader)
|
|
---@type string
|
|
local containerType = headerContainerType[headerFrame]
|
|
|
|
local scrollFrame = spellsTab.GetScrollFrameByContainerType(containerType)
|
|
scrollFrame:Refresh()
|
|
|
|
local instance = spellsTab.GetInstance()
|
|
instance:RefreshWindow(true)
|
|
end
|
|
|
|
---on enter function for the spell target frame
|
|
---@param targetFrame breakdowntargetframe
|
|
local onEnterSpellTarget = function(targetFrame)
|
|
--the spell target frame is created in the statusbar which is placed above the line frame
|
|
local lineBar = targetFrame:GetParent():GetParent()
|
|
local spellId = targetFrame.spellId
|
|
|
|
---@type actor
|
|
local actorObject = Details:GetActorObjectFromBreakdownWindow()
|
|
|
|
local targets
|
|
if (targetFrame.bIsMainLine) then
|
|
---@type spelltableadv
|
|
local bkSpellData = targetFrame.bkSpellData
|
|
targets = actorObject:BuildSpellTargetFromBreakdownSpellData(bkSpellData)
|
|
else
|
|
local spellTable = targetFrame.spellTable
|
|
targets = actorObject:BuildSpellTargetFromSpellTable(spellTable)
|
|
end
|
|
|
|
---@type number the top value of targets
|
|
local topValue = math.max(targets[1] and targets[1][2] or 0, 0.001)
|
|
|
|
local gameCooltip = GameCooltip
|
|
--cooltip:Preset(2)
|
|
Details:FormatCooltipForSpells()
|
|
gameCooltip:SetOption("FixedWidth", 260)
|
|
gameCooltip:SetOption("YSpacingMod", -8)
|
|
|
|
for targetIndex, targetTable in ipairs(targets) do
|
|
local targetName = targetTable[1]
|
|
local value = targetTable[2]
|
|
gameCooltip:AddLine(targetIndex .. ". " .. targetName, Details:Format(value))
|
|
gameCooltip:AddIcon(CONST_TARGET_TEXTURE, 1, 1, 20, 20)
|
|
Details:AddTooltipBackgroundStatusbar(false, value / topValue * 100)
|
|
end
|
|
|
|
gameCooltip:SetOwner(targetFrame)
|
|
gameCooltip:Show()
|
|
end
|
|
|
|
local onLeaveSpellTarget = function(self)
|
|
GameTooltip:Hide()
|
|
GameCooltip:Hide()
|
|
self:GetParent():GetParent():GetScript("OnLeave")(self:GetParent():GetParent())
|
|
self.texture:SetAlpha(.7)
|
|
self:SetAlpha(.7)
|
|
end
|
|
|
|
--create a details bar on the right side of the window
|
|
local onEnterSpellBlock = function(spellBlock) --info background is the 6 bars in the right side of the window?
|
|
spellBlock.overlay:Show()
|
|
spellBlock.reportButton:Show()
|
|
end
|
|
|
|
local onLeaveSpellBlock = function(spellBlock)
|
|
spellBlock.overlay:Hide()
|
|
spellBlock.reportButton:Hide()
|
|
end
|
|
|
|
local onEnterInfoReport = function(self)
|
|
Details.FadeHandler.Fader(self:GetParent().overlay, 0)
|
|
Details.FadeHandler.Fader(self, 0)
|
|
end
|
|
|
|
local onLeaveInfoReport = function(self)
|
|
Details.FadeHandler.Fader(self:GetParent().overlay, 1)
|
|
Details.FadeHandler.Fader(self, 1)
|
|
end
|
|
|
|
---run this function when the mouse hover over a breakdownspellbar
|
|
---@param spellBar breakdownspellbar
|
|
---@param motion boolean|nil
|
|
local onEnterSpellBar = function(spellBar, motion) --parei aqui: precisa por nomes nas funções e formatar as linhas das funcções
|
|
--all values from spellBar are cached values
|
|
--check if there's a spellbar selected, if there's one, ignore the mouseover
|
|
if (spellsTab.HasSelectedSpellBar() and motion) then
|
|
return
|
|
end
|
|
|
|
spellsTab.currentSpellBar = spellBar
|
|
Details222.FocusedSpellId = spellBar.spellId
|
|
|
|
---@type instance
|
|
local instance = spellsTab.GetInstance()
|
|
|
|
---@type combat
|
|
local combatObject = spellsTab.GetCombat()
|
|
|
|
---@type number, number
|
|
local mainAttribute, subAttribute = instance:GetDisplay()
|
|
|
|
---@type breakdownspellblockframe
|
|
local spellBlockContainer = spellsTab.GetSpellBlockFrame()
|
|
spellBlockContainer:ClearBlocks()
|
|
|
|
---@type number
|
|
local spellId = spellBar.spellId
|
|
|
|
---@type number
|
|
local elapsedTime = spellBar.combatTime --this should be actorObject:Tempo()
|
|
|
|
---@type string
|
|
local actorName = spellsTab.GetActor():Name() --attempt to index a nil value x2
|
|
|
|
---@type spelltable
|
|
local spellTable = spellBar.spellTable
|
|
|
|
if (IsShiftKeyDown()) then
|
|
if (type(spellId) == "number") then
|
|
GameCooltip:Preset(2)
|
|
GameCooltip:SetOwner(spellBar)
|
|
|
|
--if this is an actor header (e.g. a pet bar showing its nested spells)
|
|
if (spellBar.bkSpellData.bIsActorHeader) then
|
|
local petActor = combatObject:GetContainer(mainAttribute):GetActor(spellBar.bkSpellData.actorName)
|
|
local textToEditor = ""
|
|
for key, value in pairs(petActor) do
|
|
if (type(value) ~= "function" and type(value) ~= "table") then
|
|
textToEditor = textToEditor .. key .. " = " .. tostring(value) .. "\n"
|
|
end
|
|
|
|
breakdownWindow.dumpDataFrame:Show()
|
|
breakdownWindow.dumpDataFrame.luaEditor:SetText(textToEditor)
|
|
--hide the scroll bar
|
|
_G["DetailsBreakdownWindowPlayerScrollBoxDumpTableFrameCodeEditorWindowScrollBar"]:Hide()
|
|
end
|
|
|
|
GameCooltip:AddLine("npc id: " .. petActor.aID)
|
|
GameCooltip:Show()
|
|
return
|
|
end
|
|
|
|
---@type actor
|
|
local thisActor = spellsTab.GetActor()
|
|
|
|
---@type spelltable
|
|
local thisSpellTable = thisActor:GetSpell(spellId)
|
|
|
|
if (not thisSpellTable) then
|
|
local petName = spellBar.bkSpellData.actorName
|
|
local actorContainer = combatObject:GetContainer(mainAttribute)
|
|
local petObject = actorContainer:GetActor(petName)
|
|
if (petObject) then
|
|
thisSpellTable = petObject:GetSpell(spellId)
|
|
end
|
|
end
|
|
|
|
GameCooltip:AddLine("spell id: " .. thisSpellTable.id)
|
|
GameCooltip:Show() --add the icon for the bar bar with nested spells (place the icon of the npc or pet)
|
|
|
|
local textToEditor = ""
|
|
for key, value in pairs(thisSpellTable) do
|
|
if (type(value) ~= "function" and type(value) ~= "table") then
|
|
textToEditor = textToEditor .. key .. " = " .. tostring(value) .. "\n"
|
|
end
|
|
end
|
|
|
|
breakdownWindow.dumpDataFrame:Show()
|
|
breakdownWindow.dumpDataFrame.luaEditor:SetText(textToEditor)
|
|
--hide the scroll bar
|
|
_G["DetailsBreakdownWindowPlayerScrollBoxDumpTableFrameCodeEditorWindowScrollBar"]:Hide()
|
|
end
|
|
|
|
elseif (breakdownWindow.dumpDataFrame:IsShown()) then
|
|
breakdownWindow.dumpDataFrame:Hide()
|
|
end
|
|
|
|
if (spellId == 98021) then --spirit link totem
|
|
GameTooltip:SetOwner(spellBar, "ANCHOR_TOPLEFT")
|
|
GameTooltip:AddLine(Loc ["STRING_SPIRIT_LINK_TOTEM_DESC"])
|
|
GameTooltip:Show()
|
|
end
|
|
|
|
---@type trinketdata
|
|
local trinketData = Details:GetTrinketData()
|
|
|
|
---@type number
|
|
local blockIndex = 1
|
|
|
|
--get the first spell block to use as summary
|
|
---@type breakdownspellblock
|
|
local summaryBlock = spellBlockContainer:GetBlock(blockIndex)
|
|
summaryBlock:Show()
|
|
summaryBlock:SetValue(50)
|
|
summaryBlock:SetValue(100)
|
|
|
|
if (mainAttribute == DETAILS_ATTRIBUTE_DAMAGE) then
|
|
--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
|
|
|
|
--need to know how many blocks the damage class used
|
|
local blocksInUse = spellBlockContainer:GetBlocksInUse()
|
|
local maxBlocks = spellBlockContainer:GetBlocksAmount()
|
|
|
|
for i = blocksInUse + 1, math.min(maxBlocks, 4) do --in the current state of the breakdown, showing 5 will overlap with the phase container
|
|
spellBlockContainer:ShowEmptyBlock(i)
|
|
end
|
|
|
|
elseif (mainAttribute == DETAILS_ATTRIBUTE_HEAL) then --this should run within the heal class ~healing
|
|
---@type number
|
|
local totalHits = spellTable.counter
|
|
|
|
--healing section showing healing 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
|
|
blockLine1.rightText:SetText(Loc ["STRING_HITS"]..": " .. totalHits) --hits and uptime
|
|
|
|
blockLine2.leftText:SetText(Loc ["STRING_HEAL"]..": " .. 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_HPS"] .. ": " .. Details:CommaValue(spellBar.perSecond)) --dps
|
|
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 normalHPS = 0
|
|
if (spellTable.n_total > 0) then
|
|
local tempo = (elapsedTime * spellTable.n_total) / math.max(spellTable.total, 0.001)
|
|
local normalAveragePercent = spellBar.average / normalAverage * 100
|
|
local normalTempoPercent = normalAveragePercent * tempo / 100
|
|
normalHPS = spellTable.n_total / normalTempoPercent
|
|
end
|
|
|
|
blockLine3.rightText:SetText(Loc ["STRING_HPS"] .. ": " .. Details:CommaValue(normalHPS))
|
|
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 = criticalHitsAmt / math.max(totalHits, 0.0001) * 100
|
|
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 = spellTable.c_total / math.max(criticalHitsAmt, 0.0001)
|
|
blockLine3.leftText:SetText(Loc ["STRING_AVERAGE"] .. ": " .. Details:CommaValue(critAverage))
|
|
|
|
local critHPS = 0
|
|
if (spellTable.c_total > 0) then
|
|
local tempo = (elapsedTime * spellTable.c_total) / math.max(spellTable.total, 0.001)
|
|
local critAveragePercent = spellBar.average / critAverage * 100
|
|
local critTempoPercent = critAveragePercent * tempo / 100
|
|
critHPS = spellTable.c_total / critTempoPercent
|
|
end
|
|
|
|
blockLine3.rightText:SetText(Loc ["STRING_HPS"] .. ": " .. Details:CommaValue(critHPS))
|
|
end
|
|
|
|
---@type number
|
|
local overheal = spellTable.overheal or 0
|
|
if (overheal > 0) then
|
|
--blockIndex = blockIndex + 1 --skip one block
|
|
---@type breakdownspellblock
|
|
local overhealBlock = spellBlockContainer:GetBlock(blockIndex)
|
|
overhealBlock:Show()
|
|
blockIndex = blockIndex + 1
|
|
|
|
local blockName
|
|
if (spellTable.is_shield) then
|
|
blockName = Loc ["STRING_SHIELD_OVERHEAL"]
|
|
else
|
|
blockName = Loc ["STRING_OVERHEAL"]
|
|
end
|
|
|
|
local percent = overheal / (overheal + spellTable.total) * 100
|
|
overhealBlock:SetValue(percent)
|
|
overhealBlock.sparkTexture:SetPoint("left", overhealBlock, "left", percent / 100 * overhealBlock:GetWidth() + Details.breakdown_spell_tab.blockspell_spark_offset, 0)
|
|
|
|
overhealBlock:SetColor(1, 0, 0, 0.4)
|
|
|
|
local blockLine1, blockLine2, blockLine3 = overhealBlock:GetLines()
|
|
blockLine1.leftText:SetText(blockName)
|
|
|
|
local overhealString = Details:CommaValue(overheal)
|
|
local overhealText = overhealString .. " / " .. string.format("%.1f", percent) .. "%"
|
|
blockLine1.rightText:SetText(overhealText)
|
|
end
|
|
end
|
|
|
|
--effects on entering the bar line
|
|
spellBar:SetHeight(CONST_SPELLSCROLL_LINEHEIGHT + 1)
|
|
spellBar:SetAlpha(1)
|
|
spellBar.spellIcon:SetSize(CONST_SPELLSCROLL_LINEHEIGHT + 2, CONST_SPELLSCROLL_LINEHEIGHT + 2)
|
|
spellBar.spellIcon:SetAlpha(1)
|
|
end
|
|
|
|
---run this function when the mouse leaves a breakdownspellbar
|
|
---@param spellBar breakdownspellbar
|
|
local onLeaveSpellBar = function(spellBar)
|
|
spellsTab.currentSpellBar = nil
|
|
|
|
--remove effects on entering the bar line
|
|
spellBar:SetHeight(CONST_SPELLSCROLL_LINEHEIGHT)
|
|
spellBar:SetAlpha(0.9)
|
|
|
|
GameTooltip:Hide()
|
|
GameCooltip:Hide()
|
|
|
|
--clear spell blocks
|
|
if (not spellsTab.HasSelectedSpellBar()) then
|
|
spellsTab.GetSpellBlockFrame():ClearBlocks()
|
|
end
|
|
|
|
if (breakdownWindow.dumpDataFrame:IsShown()) then
|
|
breakdownWindow.dumpDataFrame:Hide()
|
|
end
|
|
end
|
|
|
|
---on mouse down a breakdownspellbar in the breakdown window
|
|
---@param spellBar breakdownspellbar
|
|
---@param button string
|
|
local onMouseDownBreakdownSpellBar = function(spellBar, button)
|
|
local x, y = _G.GetCursorPosition()
|
|
spellBar.cursorPosX = math.floor(x)
|
|
spellBar.cursorPosY = math.floor(y)
|
|
end
|
|
|
|
---on mouse up a breakdownspellbar in the breakdown window
|
|
---@param spellBar breakdownspellbar
|
|
---@param button string
|
|
local onMouseUpBreakdownSpellBar = function(spellBar, button)
|
|
spellBar.onMouseUpTime = GetTime()
|
|
|
|
---@type number, number
|
|
local x, y = _G.GetCursorPosition()
|
|
x = math.floor(x)
|
|
y = math.floor(y)
|
|
|
|
---@type boolean
|
|
local bIsMouseInTheSamePosition = (x == spellBar.cursorPosX) and (y == spellBar.cursorPosY)
|
|
|
|
--if the mouse is in the same position, then the user clicked the bar
|
|
if (bIsMouseInTheSamePosition) then
|
|
spellsTab.SelectSpellBar(spellBar)
|
|
end
|
|
end
|
|
|
|
local onEnterSpellIconFrame = function(self)
|
|
local line = self:GetParent()
|
|
if (line.spellId and type(line.spellId) == "number") then
|
|
local spellName = _GetSpellInfo(line.spellId)
|
|
if (spellName) then
|
|
GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT")
|
|
Details:GameTooltipSetSpellByID(line.spellId)
|
|
GameTooltip:Show()
|
|
end
|
|
end
|
|
line:GetScript("OnEnter")(line)
|
|
end
|
|
|
|
local onLeaveSpellIconFrame = function(self)
|
|
GameTooltip:Hide()
|
|
self:GetParent():GetScript("OnLeave")(self:GetParent())
|
|
end
|
|
|
|
--------------------------------------------------------------------------------------------------------------------------------------------
|
|
--Spell Blocks
|
|
|
|
local spellBlockMixin = {
|
|
---get one of the three lines containing fontstrings to show data
|
|
---line 1 is the top line, line 2 is the middle line and line 3 is the bottom line
|
|
---@param self breakdownspellblock
|
|
---@param lineIndex number
|
|
---@return breakdownspellblockline
|
|
GetLine = function(self, lineIndex)
|
|
---@type breakdownspellblockline
|
|
local line = self.Lines[lineIndex]
|
|
return line
|
|
end,
|
|
|
|
---return all lines in the spell block, all spell block have 3 lines
|
|
---@param self breakdownspellblock
|
|
---@return breakdownspellblockline, breakdownspellblockline, breakdownspellblockline
|
|
GetLines = function(self)
|
|
return unpack(self.Lines)
|
|
end,
|
|
|
|
---@param self breakdownspellblock
|
|
SetColor = function(self, ...)
|
|
local r, g, b, a = DF:ParseColors(...)
|
|
self.statusBarTexture:SetColorTexture(r, g, b, a)
|
|
end,
|
|
}
|
|
|
|
---create a spell block into the spellblockcontainer
|
|
---@param spellBlockContainer breakdownspellblockframe
|
|
---@param index number
|
|
---@return breakdownspellblock
|
|
function spellsTab.CreateSpellBlock(spellBlockContainer, index) --~breakdownspellblock ~create ~spellblocks
|
|
---@type breakdownspellblock
|
|
local spellBlock = CreateFrame("statusbar", "$parentBlock" .. index, spellBlockContainer, "BackdropTemplate")
|
|
detailsFramework:Mixin(spellBlock, spellBlockMixin)
|
|
|
|
local statusBarTexture = spellBlock:CreateTexture("$parentTexture", "artwork")
|
|
statusBarTexture:SetColorTexture(unpack(CONST_SPELLBLOCK_DEFAULT_COLOR))
|
|
statusBarTexture:SetPoint("topleft", spellBlock, "topleft", 1, -1)
|
|
statusBarTexture:SetPoint("bottomleft", spellBlock, "bottomleft", 1, 1)
|
|
spellBlock.statusBarTexture = statusBarTexture
|
|
|
|
spellBlock:SetScript("OnEnter", onEnterSpellBlock)
|
|
spellBlock:SetScript("OnLeave", onLeaveSpellBlock)
|
|
spellBlock:SetScript("OnValueChanged", function()
|
|
statusBarTexture:SetWidth(spellBlock:GetValue() / 100 * spellBlock:GetWidth())
|
|
end)
|
|
|
|
spellBlock:SetMinMaxValues(0, 100)
|
|
spellBlock:SetValue(100)
|
|
|
|
--set the backdrop to have a 8x8 edge file
|
|
spellsTab.ApplyStandardBackdrop(spellBlock)
|
|
|
|
--create the lines which will host the texts
|
|
spellBlock.Lines = {}
|
|
for i = 1, spellBlockContainerSettings.lineAmount do
|
|
---@type breakdownspellblockline
|
|
local line = CreateFrame("frame", "$parentLine" .. i, spellBlock)
|
|
spellBlock.Lines[i] = line
|
|
|
|
line.leftText = line:CreateFontString("$parentLeftText", "overlay", "GameFontHighlightSmall")
|
|
line.centerText = line:CreateFontString("$parentLeftText", "overlay", "GameFontHighlightSmall")
|
|
line.rightText = line:CreateFontString("$parentLeftText", "overlay", "GameFontHighlightSmall")
|
|
|
|
line.leftText:SetPoint("left", line, "left", 2, 0)
|
|
line.leftText:SetJustifyH("left")
|
|
line.centerText:SetPoint("center", line, "center", 0, 0)
|
|
line.centerText:SetJustifyH("center")
|
|
line.rightText:SetPoint("right", line, "right", -2, 0)
|
|
line.rightText:SetJustifyH("right")
|
|
end
|
|
|
|
--overlay texture which fade in and out when the spell block is hovered over
|
|
--is only possible to hover over a spell block when the spellbar is selected
|
|
spellBlock.overlay = spellBlock:CreateTexture("$parentOverlay", "artwork")
|
|
spellBlock.overlay:SetTexture("Interface\\AddOns\\Details\\images\\overlay_detalhes")
|
|
spellBlock.overlay:SetPoint("topleft", spellBlock, "topleft", -8, 8)
|
|
spellBlock.overlay:SetPoint("bottomright", spellBlock, "bottomright", 26, -14)
|
|
Details.FadeHandler.Fader(spellBlock.overlay, 1) --hide
|
|
|
|
--report button, also only shown when the spell block is hovered over
|
|
spellBlock.reportButton = Details.gump:NewDetailsButton(spellBlock, nil, nil, Details.Reportar, Details.BreakdownWindowFrame, 10 + index, 16, 16,
|
|
"Interface\\COMMON\\VOICECHAT-ON", "Interface\\COMMON\\VOICECHAT-ON", "Interface\\COMMON\\VOICECHAT-ON", "Interface\\COMMON\\VOICECHAT-ON", nil, "DetailsJanelaInfoReport1")
|
|
Details.FadeHandler.Fader(spellBlock.reportButton, 1) --hide
|
|
spellBlock.reportButton:SetScript("OnEnter", onEnterInfoReport)
|
|
spellBlock.reportButton:SetScript("OnLeave", onLeaveInfoReport)
|
|
|
|
--spark texture
|
|
spellBlock.sparkTexture = spellBlock:CreateTexture("$parentOverlaySparkTexture", "overlay")
|
|
spellBlock.sparkTexture:SetTexture("Interface\\AddOns\\Details\\images\\bar_detalhes2_end")
|
|
spellBlock.sparkTexture:SetBlendMode("ADD")
|
|
|
|
local gradientDown = detailsFramework:CreateTexture(spellBlock, {gradient = "vertical", fromColor = {0, 0, 0, 0.1}, toColor = "transparent"}, 1, spellBlock:GetHeight(), "background", {0, 1, 0, 1})
|
|
gradientDown:SetPoint("bottoms")
|
|
spellBlock.gradientTexture = gradientDown
|
|
spellBlock.gradientTexture:Hide()
|
|
|
|
return spellBlock
|
|
end
|
|
|
|
local spellBlockContainerMixin = {
|
|
---refresh all the spellblocks in the container ~UpdateBlocks
|
|
---this function adjust the frame properties, does not update the data shown on them
|
|
---@param self breakdownspellblockframe
|
|
UpdateBlocks = function(self) --~update
|
|
---@type number, number
|
|
local width, height = Details.breakdown_spell_tab.blockcontainer_width, Details.breakdown_spell_tab.blockcontainer_height
|
|
local blockHeight = Details.breakdown_spell_tab.blockspell_height
|
|
local backgroundColor = Details.breakdown_spell_tab.blockspell_backgroundcolor
|
|
local borderColor = Details.breakdown_spell_tab.blockspell_bordercolor
|
|
local padding = Details.breakdown_spell_tab.blockspell_padding * -1
|
|
local color = Details.breakdown_spell_tab.blockspell_color
|
|
|
|
self:SetSize(width, height)
|
|
|
|
backgroundColor[1], backgroundColor[2], backgroundColor[3], backgroundColor[4] = 0.05, 0.05, 0.05, 0.2
|
|
color[1], color[2], color[3], color[4] = 0.6, 0.6, 0.6, 0.55
|
|
|
|
for i = 1, #self.SpellBlocks do
|
|
---@type breakdownspellblock
|
|
local spellBlock = self.SpellBlocks[i]
|
|
|
|
spellBlock:SetSize(width - 2, blockHeight)
|
|
spellBlock:SetPoint("topleft", self, "topleft", 1, (blockHeight * (i - 1) - i) * -1 - (i*2) + ((i-1) * padding))
|
|
spellBlock:SetPoint("topright", self, "topright", 1, (blockHeight * (i - 1) - i) * -1 - (i*2) + ((i-1) * padding))
|
|
|
|
spellBlock.sparkTexture:SetSize(Details.breakdown_spell_tab.blockspell_spark_width, blockHeight)
|
|
spellBlock.sparkTexture:SetShown(Details.breakdown_spell_tab.blockspell_spark_show)
|
|
spellBlock.sparkTexture:SetVertexColor(unpack(Details.breakdown_spell_tab.blockspell_spark_color))
|
|
spellBlock.reportButton:SetPoint("bottomright", spellBlock.overlay, "bottomright", -2, 2)
|
|
spellBlock.gradientTexture:SetHeight(blockHeight)
|
|
|
|
spellBlock:SetBackdropBorderColor(unpack(borderColor)) --border color
|
|
spellBlock.statusBarTexture:SetVertexColor(unpack(Details.breakdown_spell_tab.blockspell_color)) --bar color
|
|
|
|
local lineHeight = blockHeight * 0.2687
|
|
|
|
--update the lines
|
|
local previousLine
|
|
for o = 1, spellBlockContainerSettings.lineAmount do
|
|
---@type breakdownspellblockline
|
|
local line = spellBlock.Lines[o]
|
|
line:SetSize(width - 2, lineHeight)
|
|
if (previousLine) then
|
|
line:SetPoint("topleft", previousLine, "bottomleft", 0, -2)
|
|
else
|
|
line:SetPoint("topleft", spellBlock, "topleft", 1, -2)
|
|
end
|
|
previousLine = line
|
|
end
|
|
end
|
|
end,
|
|
|
|
---@param self breakdownspellblockframe
|
|
ClearBlocks = function(self)
|
|
for i = 1, self:GetBlocksAmount() do
|
|
---@type breakdownspellblock
|
|
local spellBlock = self.SpellBlocks[i]
|
|
spellBlock:Hide()
|
|
|
|
spellBlock:SetColor(unpack(CONST_SPELLBLOCK_DEFAULT_COLOR))
|
|
|
|
--set the status bar value to zero
|
|
spellBlock:SetValue(0)
|
|
spellBlock.statusBarTexture:Show()
|
|
spellBlock.sparkTexture:Show()
|
|
|
|
--clear the text shown in their lines
|
|
for o = 1, 3 do
|
|
spellBlock.Lines[o].leftText:SetText("")
|
|
|
|
--set the color of the top left text in the block, the text is used as header text
|
|
if (o == 1) then
|
|
DF:SetFontColor(spellBlock.Lines[o].leftText, CONST_SPELLBLOCK_HEADERTEXT_COLOR)
|
|
DF:SetFontSize(spellBlock.Lines[o].leftText, CONST_SPELLBLOCK_HEADERTEXT_SIZE)
|
|
end
|
|
|
|
spellBlock.Lines[o].centerText:SetText("")
|
|
spellBlock.Lines[o].rightText:SetText("")
|
|
end
|
|
end
|
|
|
|
for i = 1, math.min(self:GetBlocksAmount(), 4) do
|
|
self:ShowEmptyBlock(i)
|
|
end
|
|
|
|
self.blocksInUse = 0
|
|
end,
|
|
|
|
---show the empty block in the container, this is done to preview where the rectangle will be
|
|
---@param self breakdownspellblockframe
|
|
---@param index number
|
|
ShowEmptyBlock = function(self, index)
|
|
local spellBlock = self.SpellBlocks[index]
|
|
spellBlock:Show()
|
|
spellBlock:SetValue(0)
|
|
spellBlock.statusBarTexture:Hide()
|
|
spellBlock.sparkTexture:Hide()
|
|
end,
|
|
|
|
---get a breakdownspellblock from the container
|
|
---@param self breakdownspellblockframe
|
|
---@param index number
|
|
---@return breakdownspellblock
|
|
GetBlock = function(self, index)
|
|
self.blocksInUse = self.blocksInUse + 1
|
|
local spellBlock = self.SpellBlocks[index]
|
|
spellBlock.statusBarTexture:Show()
|
|
spellBlock.sparkTexture:Show()
|
|
return self.SpellBlocks[index]
|
|
end,
|
|
|
|
---get the amount of blocks in use
|
|
---@param self breakdownspellblockframe
|
|
---@return number
|
|
GetBlocksInUse = function(self)
|
|
return self.blocksInUse
|
|
end,
|
|
|
|
---get the total blocks created
|
|
---@param self breakdownspellblockframe
|
|
---@return number
|
|
GetBlocksAmount = function(self)
|
|
return #self.SpellBlocks
|
|
end,
|
|
}
|
|
|
|
---create the spell blocks which shows the critical hits, normal hits, etc
|
|
---@param tabFrame tabframe
|
|
---@return breakdownspellblockframe
|
|
function spellsTab.CreateSpellBlockContainer(tabFrame) --~create ~createblock ~spellblock ~block ~container
|
|
--create a container for the scrollframe
|
|
local options = {
|
|
width = Details.breakdown_spell_tab.blockcontainer_width,
|
|
height = Details.breakdown_spell_tab.blockcontainer_height,
|
|
is_locked = Details.breakdown_spell_tab.blockcontainer_islocked,
|
|
can_move = false,
|
|
can_move_children = false,
|
|
use_bottom_resizer = true,
|
|
use_right_resizer = true,
|
|
}
|
|
|
|
---@type df_framecontainer
|
|
local container = DF:CreateFrameContainer(tabFrame, options, tabFrame:GetName() .. "SpellScrollContainer")
|
|
container:SetPoint("topleft", spellsTab.GetSpellScrollContainer(), "topright", 26, 0)
|
|
container:SetFrameLevel(tabFrame:GetFrameLevel() + 10)
|
|
spellsTab.BlocksContainerFrame = container
|
|
|
|
local settingChangedCallbackFunction = function(frameContainer, settingName, settingValue)
|
|
if (frameContainer:IsShown()) then
|
|
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
|
|
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
|
|
container:SetWidth(spellBlockContainerWidth)
|
|
|
|
elseif (settingName == "height") then
|
|
---@type number
|
|
local currentHeight = spellsTab.GetSpellScrollFrame():GetHeight()
|
|
Details.breakdown_spell_tab.blockcontainer_height = settingValue
|
|
spellsTab.GetSpellScrollFrame():SetNumFramesShown(math.floor(currentHeight / CONST_SPELLSCROLL_LINEHEIGHT) - 1)
|
|
|
|
elseif (settingName == "width") then
|
|
Details.breakdown_spell_tab.blockcontainer_width = settingValue
|
|
|
|
elseif (settingName == "is_locked") then
|
|
Details.breakdown_spell_tab.blockcontainer_islocked = settingValue
|
|
end
|
|
|
|
--update the spell blocks
|
|
spellsTab.GetSpellBlockFrame():UpdateBlocks()
|
|
|
|
if (spellsTab.GetSelectedSpellBar()) then
|
|
onEnterSpellBar(spellsTab.GetSelectedSpellBar())
|
|
end
|
|
end
|
|
end
|
|
container:SetSettingChangedCallback(settingChangedCallbackFunction)
|
|
|
|
--create the container which will hold the spell blocks
|
|
---@type breakdownspellblockframe
|
|
local spellBlockFrame = CreateFrame("Frame", "$parentSpellBlockContainer", container, "BackdropTemplate")
|
|
spellBlockFrame:EnableMouse(false)
|
|
spellBlockFrame:SetResizable(false)
|
|
spellBlockFrame:SetMovable(false)
|
|
spellBlockFrame:SetAllPoints()
|
|
detailsFramework:Mixin(spellBlockFrame, spellBlockContainerMixin)
|
|
|
|
tabFrame.SpellBlockFrame = spellBlockFrame
|
|
spellsTab.SpellBlockFrame = spellBlockFrame
|
|
|
|
container:RegisterChildForDrag(spellBlockFrame)
|
|
|
|
spellBlockFrame.SpellBlocks = {}
|
|
spellBlockFrame.blocksInUse = 0
|
|
|
|
--create the spell blocks within the spellBlockFrame
|
|
for i = 1, spellBlockContainerSettings.amount do
|
|
---@type breakdownspellblock
|
|
local spellBlock = spellsTab.CreateSpellBlock(spellBlockFrame, i)
|
|
table.insert(spellBlockFrame.SpellBlocks, spellBlock)
|
|
--size and point are set on ~UpdateBlocks
|
|
end
|
|
|
|
spellBlockFrame:UpdateBlocks()
|
|
|
|
return spellBlockFrame
|
|
end
|
|
|
|
function spellsTab.UpdateShownSpellBlock()
|
|
if (spellsTab.currentSpellBar) then
|
|
onEnterSpellBar(spellsTab.currentSpellBar)
|
|
|
|
elseif (spellsTab.GetSelectedSpellBar()) then
|
|
onEnterSpellBar(spellsTab.GetSelectedSpellBar())
|
|
end
|
|
end
|
|
|
|
|
|
--logistics: class_damage build the list of spells, send it to window_playerbreakdown, which gets the current summary tab and send the data for it
|
|
--in this tab, the data is sent to the refresh function
|
|
|
|
local onClickExpandButton = function(expandButton, button)
|
|
---@type breakdownspellbar
|
|
local spellBar = expandButton:GetParent()
|
|
---@type table
|
|
local scrolFrame = spellBar:GetParent()
|
|
---@type boolean
|
|
local bIsSpellExpaded = expandButton.bIsSpellExpaded
|
|
|
|
--check if the one of the expanded bars was a selected spellbar and deselect
|
|
--get the current selected spellbar
|
|
---@type breakdownspellbar
|
|
local selectedSpellBar = spellsTab.GetSelectedSpellBar()
|
|
|
|
if (bIsSpellExpaded) then --it's already expended, it'll close the expanded spellbars
|
|
--check if the selected spellbar is one of the expanded spellbars and deselect it
|
|
for i = 1, #spellBar.ExpandedChildren do
|
|
---@type breakdownspellbar
|
|
local expandedSpellBar = spellBar.ExpandedChildren[i]
|
|
if (expandedSpellBar == selectedSpellBar) then
|
|
--deselect the spellbar
|
|
spellsTab.UnSelectSpellBar()
|
|
break
|
|
end
|
|
end
|
|
else
|
|
spellsTab.UnSelectSpellBar()
|
|
end
|
|
|
|
--todo: check is any other bar has expanded state true, and close the expand (or not)
|
|
|
|
--toggle this spell expand mode
|
|
Details222.BreakdownWindow.SetSpellAsExpanded(expandButton.petName or expandButton.spellId, not bIsSpellExpaded)
|
|
|
|
--call the refresh function of the window
|
|
---@type instance
|
|
local instanceObject = spellsTab.GetInstance()
|
|
instanceObject:RefreshWindow(true)
|
|
end
|
|
|
|
|
|
---update a line using the data passed
|
|
---@param spellBar breakdownspellbar
|
|
---@param index number spell position (from best to wrost)
|
|
---@param actorName string
|
|
---@param combatObject combat
|
|
---@param scrollFrame table
|
|
---@param headerTable table
|
|
---@param bkSpellData spelltableadv
|
|
---@param spellTableIndex number
|
|
---@param totalValue number
|
|
---@param topValue number
|
|
---@param bIsMainLine boolean if true this is the line which has all the values of the spell merged
|
|
---@param sortKey string
|
|
---@param spellTablesAmount number
|
|
local updateSpellBar = function(spellBar, index, actorName, combatObject, scrollFrame, headerTable, bkSpellData, spellTableIndex, totalValue, topValue, bIsMainLine, sortKey, spellTablesAmount)
|
|
--scrollFrame is defined as a table which is false, scrollFrame is a frame
|
|
|
|
local textIndex = 1
|
|
for headerIndex = 1, #headerTable do
|
|
---@type number
|
|
local spellId
|
|
---@type number
|
|
local value
|
|
---@type spelltable
|
|
local spellTable
|
|
|
|
spellBar.bkSpellData = bkSpellData
|
|
|
|
local petName = ""
|
|
---@type boolean @if true, this is the main line of an actor which has its spells nested in the bkSpellData.nestedData
|
|
local bIsActorHeader = bkSpellData.bIsActorHeader
|
|
|
|
if (bIsMainLine and bIsActorHeader) then
|
|
spellTable = bkSpellData
|
|
value = bkSpellData.total
|
|
spellId = 0
|
|
petName = actorName
|
|
|
|
elseif (bIsMainLine) then
|
|
spellTable = bkSpellData
|
|
value = bkSpellData.total
|
|
spellId = bkSpellData.id
|
|
petName = bkSpellData.nestedData[spellTableIndex].actorName
|
|
|
|
else
|
|
spellTable = bkSpellData.nestedData[spellTableIndex].spellTable
|
|
value = spellTable.total
|
|
spellId = spellTable.id
|
|
|
|
--if isn't a spell from a nested actor, then it can use the pet name in the spell name
|
|
if (not bkSpellData.nestedData[spellTableIndex].bIsActorHeader) then
|
|
petName = bkSpellData.nestedData[spellTableIndex].actorName
|
|
end
|
|
|
|
spellBar.bIsExpandedSpell = true
|
|
end
|
|
|
|
spellBar.spellId = spellId
|
|
|
|
---@cast spellTable spelltable
|
|
spellBar.spellTable = spellTable
|
|
|
|
---@type string, number, any, string?, boolean?
|
|
local spellName, _, spellIcon, defaultName, bBreakdownCanStack = Details.GetCustomSpellInfo(spellId)
|
|
if (not spellName) then
|
|
spellName = actorName
|
|
---@type npcid
|
|
local npcId = tonumber(bkSpellData.npcId) or 0
|
|
spellIcon = Details.NpcIdToIcon[npcId] or bkSpellData.actorIcon or ""
|
|
end
|
|
|
|
--if this damage was made by an item, then get the default spellName of the damaging spell
|
|
--the name from GetSpellInfo are probably modified by a custom spell name
|
|
--amount of casts does not use custom names but always the damaging spell name from combatlog
|
|
local defaultSpellName = Details.GetItemSpellInfo(spellId)
|
|
---@type number
|
|
local amtCasts = combatObject:GetSpellCastAmount(actorName, defaultSpellName or spellName)
|
|
spellBar.amountCasts = amtCasts
|
|
|
|
---@type number
|
|
local uptime = combatObject:GetSpellUptime(actorName, spellId)
|
|
|
|
---@type number
|
|
local combatTime = combatObject:GetCombatTime()
|
|
|
|
--statusbar size by percent
|
|
if (topValue > 0) then
|
|
local barValue = spellTable[sortKey] or getValueForHeaderSortKey(combatObject, spellTable, sortKey)
|
|
spellBar.statusBar:SetValue(barValue / topValue * 100)
|
|
else
|
|
spellBar.statusBar:SetValue(0)
|
|
end
|
|
|
|
if (petName ~= "") then
|
|
--if is a pet spell and has more pets nested || nop, now is a pet with its spells nested
|
|
if (spellTablesAmount > 1 and bIsMainLine) then
|
|
spellName = formatPetName("", spellName, "") --causing error as spellName is nil
|
|
elseif (bIsMainLine) then
|
|
spellName = formatPetName(petName, spellName, actorName)
|
|
else
|
|
spellName = formatPetName(petName, "", "")
|
|
end
|
|
end
|
|
|
|
spellBar.spellId = spellId
|
|
spellBar.spellIconFrame.spellId = spellId
|
|
--spellBar.statusBar.backgroundTexture:SetAlpha(Details.breakdown_spell_tab.spellbar_background_alpha)
|
|
|
|
--statusbar color by school
|
|
local r, g, b = Details:GetSpellSchoolColor(spellTable.spellschool or 1)
|
|
spellBar.statusBar:SetStatusBarColor(r, g, b, 0.963)
|
|
|
|
if (spellTable.counter > 0) then
|
|
spellBar.average = value / spellTable.counter
|
|
else
|
|
spellBar.average = 0.0001
|
|
end
|
|
|
|
spellBar.combatTime = combatTime
|
|
|
|
---@type fontstring
|
|
local text = spellBar.InLineTexts[textIndex]
|
|
local header = headerTable[headerIndex]
|
|
|
|
if (header.name == "icon") then
|
|
spellBar.spellIcon:Show()
|
|
spellBar.spellIcon:SetTexture(spellIcon)
|
|
spellBar.spellIcon:SetAlpha(0.92)
|
|
spellBar:AddFrameToHeaderAlignment(spellBar.spellIconFrame)
|
|
|
|
elseif (header.name == "target") then --the tab does not have knownledge about the targets of the spell, it must be passed over
|
|
---@type breakdowntargetframe
|
|
local targetsSquareFrame = spellBar.targetsSquareFrame
|
|
targetsSquareFrame:Show()
|
|
targetsSquareFrame.spellId = spellId
|
|
targetsSquareFrame.bkSpellData = spellTable
|
|
targetsSquareFrame.spellTable = spellTable
|
|
targetsSquareFrame.bIsMainLine = bIsMainLine
|
|
spellBar:AddFrameToHeaderAlignment(targetsSquareFrame)
|
|
|
|
elseif (header.name == "rank") then
|
|
text:SetText(index)
|
|
spellBar:AddFrameToHeaderAlignment(text)
|
|
spellBar.rank = index
|
|
textIndex = textIndex + 1
|
|
|
|
elseif (header.name == "expand") then
|
|
text:SetText("")
|
|
spellBar:AddFrameToHeaderAlignment(spellBar.expandButton)
|
|
textIndex = textIndex + 1
|
|
|
|
if (bkSpellData.bCanExpand and bIsMainLine) then
|
|
spellBar.expandButton:Show()
|
|
local bIsSpellExpaded = Details222.BreakdownWindow.IsSpellExpanded(bIsActorHeader and actorName or spellId)
|
|
spellBar.expandButton.spellId = bIsActorHeader and actorName or spellId
|
|
spellBar.expandButton.bIsSpellExpaded = bIsSpellExpaded
|
|
spellBar.expandButton:SetScript("OnClick", onClickExpandButton)
|
|
|
|
--update the texture taking the state of the expanded value
|
|
if (bIsSpellExpaded) then
|
|
spellBar.expandButton.texture:SetTexture([[Interface\AddOns\Details\images\arrow_face_down]])
|
|
--spellBar.expandButton.texture:SetTexCoord(0, 1, 0, 1)
|
|
spellBar.expandButton.texture:SetRotation(0)
|
|
else
|
|
spellBar.expandButton.texture:SetTexture([[Interface\AddOns\Details\images\arrow_face_down]])
|
|
--spellBar.expandButton.texture:SetTexCoord(0, 1, 0, 1)
|
|
spellBar.expandButton.texture:SetRotation(math.pi/2)
|
|
end
|
|
|
|
spellBar.expandButton.texture:SetAlpha(0.7)
|
|
spellBar.expandButton.texture:SetSize(16, 16)
|
|
end
|
|
|
|
elseif (header.name == "name") then
|
|
text:SetText(Details:RemoveOwnerName(spellName))
|
|
spellBar.name = spellName
|
|
spellBar:AddFrameToHeaderAlignment(text)
|
|
textIndex = textIndex + 1
|
|
|
|
elseif (header.name == "amount") then
|
|
text:SetText(Details:Format(value))
|
|
spellBar:AddFrameToHeaderAlignment(text)
|
|
textIndex = textIndex + 1
|
|
|
|
elseif (header.name == "persecond") then
|
|
spellBar.perSecond = value / combatTime
|
|
|
|
---@type string
|
|
local perSecondFormatted = Details:Format(spellBar.perSecond)
|
|
text:SetText(perSecondFormatted)
|
|
|
|
spellBar:AddFrameToHeaderAlignment(text)
|
|
textIndex = textIndex + 1
|
|
|
|
elseif (header.name == "percent") then
|
|
spellBar.percent = value / totalValue * 100
|
|
---@type string
|
|
local percentFormatted = string.format("%.1f", spellBar.percent) .. "%"
|
|
text:SetText(percentFormatted)
|
|
|
|
spellBar:AddFrameToHeaderAlignment(text)
|
|
textIndex = textIndex + 1
|
|
|
|
elseif (header.name == "casts") then
|
|
text:SetText(amtCasts)
|
|
spellBar:AddFrameToHeaderAlignment(text)
|
|
textIndex = textIndex + 1
|
|
|
|
elseif (header.name == "critpercent") then
|
|
text:SetText(string.format("%.1f", spellTable.c_amt / (spellTable.counter) * 100) .. "%")
|
|
spellBar:AddFrameToHeaderAlignment(text)
|
|
textIndex = textIndex + 1
|
|
|
|
elseif (header.name == "hits") then
|
|
text:SetText(spellTable.counter)
|
|
spellBar:AddFrameToHeaderAlignment(text)
|
|
textIndex = textIndex + 1
|
|
|
|
elseif (header.name == "castavg") then
|
|
if (amtCasts > 0) then
|
|
spellBar.castAverage = value / amtCasts
|
|
text:SetText(Details:Format(spellBar.castAverage))
|
|
else
|
|
text:SetText("0")
|
|
end
|
|
spellBar:AddFrameToHeaderAlignment(text)
|
|
textIndex = textIndex + 1
|
|
|
|
elseif (header.name == "uptime") then --need to get the uptime of the spell with the biggest uptime
|
|
local uptimePercent = uptime / combatTime * 100
|
|
if (uptimePercent > 0) then
|
|
text:SetText(string.format("%.1f", uptime / combatTime * 100) .. "%")
|
|
else
|
|
text:SetText("")
|
|
end
|
|
|
|
spellBar:AddFrameToHeaderAlignment(text)
|
|
textIndex = textIndex + 1
|
|
|
|
elseif (header.name == "overheal" and spellTable.overheal) then
|
|
if (spellTable.overheal > 0) then
|
|
local totalHeal = spellTable.overheal + value
|
|
text:SetText(Details:ToK2(spellTable.overheal) .. " (" .. math.floor(spellTable.overheal / totalHeal * 100) .. "%)")
|
|
else
|
|
text:SetText("0%")
|
|
end
|
|
spellBar:AddFrameToHeaderAlignment(text)
|
|
textIndex = textIndex + 1
|
|
|
|
elseif (header.name == "absorbed") then
|
|
text:SetText(Details:Format(spellTable.absorbed or 0))
|
|
spellBar:AddFrameToHeaderAlignment(text)
|
|
textIndex = textIndex + 1
|
|
end
|
|
end
|
|
|
|
spellBar:AlignWithHeader(scrollFrame.Header, "left")
|
|
end
|
|
|
|
---get a spell bar from the scroll box, if it doesn't exist, return nil
|
|
---@param scrollFrame table
|
|
---@param lineIndex number
|
|
---@return breakdownspellbar
|
|
local getSpellBar = function(scrollFrame, lineIndex)
|
|
---@type breakdownspellbar
|
|
local spellBar = scrollFrame:GetLine(lineIndex)
|
|
|
|
spellBar.bIsExpandedSpell = false
|
|
|
|
Details:Destroy(spellBar.ExpandedChildren)
|
|
|
|
--reset header alignment
|
|
spellBar:ResetFramesToHeaderAlignment()
|
|
|
|
spellsTab.UpdateBarSettings(spellBar)
|
|
|
|
--reset columns, hiding them
|
|
spellBar.spellIcon:Hide()
|
|
spellBar.expandButton:Hide()
|
|
spellBar.targetsSquareFrame:Hide()
|
|
for inLineIndex = 1, #spellBar.InLineTexts do
|
|
spellBar.InLineTexts[inLineIndex]:SetText("")
|
|
end
|
|
|
|
return spellBar
|
|
end
|
|
|
|
---refresh the data shown in the spells scroll box
|
|
---@param scrollFrame table
|
|
---@param scrollData breakdownspelldatalist
|
|
---@param offset number
|
|
---@param totalLines number
|
|
local refreshSpellsFunc = function(scrollFrame, scrollData, offset, totalLines) --~refreshspells ~refreshfunc ~refresh ~refreshs
|
|
---@type number
|
|
local topValue = scrollFrame.topValue
|
|
---@type number
|
|
local totalValue = scrollData.totalValue
|
|
---@type actor
|
|
local actorObject = spellsTab.GetActor()
|
|
---@type string
|
|
local actorName = actorObject:Name()
|
|
|
|
---@type combat
|
|
local combatObject = spellsTab.GetCombat()
|
|
---@type instance
|
|
local instanceObject = spellsTab.GetInstance()
|
|
|
|
local keyToSort = scrollFrame.SortKey
|
|
local orderToSort = scrollFrame.SortKey
|
|
local headerTable = spellsTab.spellsHeaderData
|
|
|
|
--todo: when swapping sort orders, close already expanded spells
|
|
local lineIndex = 1
|
|
for i = 1, totalLines do
|
|
local index = i + offset
|
|
|
|
---@type spelltableadv
|
|
local bkSpellData = scrollData[index]
|
|
|
|
if (bkSpellData) then
|
|
---@type number
|
|
local spellTablesAmount = #bkSpellData.nestedData
|
|
|
|
---called mainSpellBar because it is the line that shows the sum of all spells merged (if any)
|
|
---@type breakdownspellbar
|
|
local mainSpellBar = getSpellBar(scrollFrame, lineIndex)
|
|
do
|
|
--main line of the spell, where the sum of all spells merged is shown
|
|
if (mainSpellBar) then
|
|
lineIndex = lineIndex + 1
|
|
local bIsMainLine = true
|
|
local bIsActorHeader = bkSpellData.bIsActorHeader
|
|
local spellTableIndex = 1
|
|
local spellBar = mainSpellBar
|
|
|
|
local nameToUse = actorName
|
|
if (bIsActorHeader) then
|
|
nameToUse = bkSpellData.actorName
|
|
end
|
|
|
|
|
|
|
|
--both calls are equal but the traceback will be different in case of an error
|
|
if (bIsActorHeader) then
|
|
updateSpellBar(spellBar, index, nameToUse, combatObject, scrollFrame, headerTable, bkSpellData, spellTableIndex, totalValue, topValue, bIsMainLine, keyToSort, spellTablesAmount)
|
|
else
|
|
--here
|
|
updateSpellBar(spellBar, index, nameToUse, combatObject, scrollFrame, headerTable, bkSpellData, spellTableIndex, totalValue, topValue, bIsMainLine, keyToSort, spellTablesAmount)
|
|
end
|
|
end
|
|
end
|
|
|
|
--if the spell is expanded
|
|
--then it adds the lines for each spell merged, but it cannot use the bkSpellData, it needs the spellTable, it's kinda using bkSpellData, need to debug
|
|
if (bkSpellData.bIsExpanded and (spellTablesAmount > 1)) then
|
|
--filling necessary information to sort the data by the selected header column
|
|
for spellTableIndex = 1, spellTablesAmount do
|
|
---@type bknesteddata
|
|
local nestedBkSpellData = bkSpellData.nestedData[spellTableIndex]
|
|
---@type spelltable
|
|
local spellTable = nestedBkSpellData.spellTable
|
|
nestedBkSpellData.value = spellTable[keyToSort] or getValueForHeaderSortKey(combatObject, spellTable, keyToSort)
|
|
end
|
|
|
|
--sort the nested data
|
|
if (orderToSort == "DESC") then
|
|
table.sort(bkSpellData.nestedData,
|
|
function(t1, t2)
|
|
return t1.value < t2.value
|
|
end)
|
|
else
|
|
table.sort(bkSpellData.nestedData,
|
|
function(t1, t2)
|
|
return t1.value > t2.value
|
|
end)
|
|
end
|
|
|
|
for spellTableIndex = 1, spellTablesAmount do
|
|
---@type breakdownspellbar
|
|
local spellBar = getSpellBar(scrollFrame, lineIndex)
|
|
if (spellBar) then
|
|
---@type bknesteddata
|
|
local nestedBkSpellData = bkSpellData.nestedData[spellTableIndex]
|
|
|
|
lineIndex = lineIndex + 1
|
|
---@type string
|
|
local petName = nestedBkSpellData.actorName
|
|
---@type string
|
|
local nameToUse = petName ~= "" and petName or actorName
|
|
local bIsMainLine = false
|
|
|
|
bkSpellData[keyToSort] = nestedBkSpellData.value
|
|
|
|
updateSpellBar(spellBar, index, nameToUse, combatObject, scrollFrame, headerTable, bkSpellData, spellTableIndex, totalValue, topValue, bIsMainLine, keyToSort, spellTablesAmount)
|
|
mainSpellBar.ExpandedChildren[#mainSpellBar.ExpandedChildren + 1] = spellBar
|
|
end
|
|
end
|
|
end
|
|
|
|
if (lineIndex > totalLines) then
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
---creates a scrollframe which show breakdownspellbar to show the spells used by an actor
|
|
---@param tabFrame tabframe
|
|
---@return breakdownspellscrollframe
|
|
function spellsTab.CreateSpellScrollContainer(tabFrame) --~scroll ~create ~spell ~container ~createspellcontainer
|
|
---@type width
|
|
local width = Details.breakdown_spell_tab.spellcontainer_width
|
|
---@type height
|
|
local height = Details.breakdown_spell_tab.spellcontainer_height
|
|
|
|
local options = {
|
|
width = Details.breakdown_spell_tab.spellcontainer_width,
|
|
height = Details.breakdown_spell_tab.spellcontainer_height,
|
|
is_locked = Details.breakdown_spell_tab.spellcontainer_islocked,
|
|
can_move = false,
|
|
can_move_children = false,
|
|
use_bottom_resizer = true,
|
|
use_right_resizer = false,
|
|
}
|
|
|
|
---create a container for the scrollframe
|
|
---@type df_framecontainer
|
|
local container = DF:CreateFrameContainer(tabFrame, options, tabFrame:GetName() .. "SpellScrollContainer")
|
|
container:SetPoint("topleft", tabFrame, "topleft", 5, -5)
|
|
container:SetFrameLevel(tabFrame:GetFrameLevel() + 10)
|
|
spellsTab.SpellContainerFrame = 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) --doing here the callback for thge settings changed in the container
|
|
if (frameContainer:IsShown()) then
|
|
if (settingName == "height") then
|
|
---@type number
|
|
local currentHeight = spellsTab.GetSpellScrollFrame():GetHeight()
|
|
Details.breakdown_spell_tab.spellcontainer_height = settingValue
|
|
spellsTab.GetSpellScrollFrame():SetNumFramesShown(math.floor(currentHeight / CONST_SPELLSCROLL_LINEHEIGHT) - 1)
|
|
|
|
elseif (settingName == "width") then
|
|
Details.breakdown_spell_tab.spellcontainer_width = settingValue
|
|
|
|
elseif (settingName == "is_locked") then
|
|
Details.breakdown_spell_tab.spellcontainer_islocked = settingValue
|
|
end
|
|
|
|
spellsTab.GetSpellBlockContainer():SendSettingChangedCallback("UpdateSize", -1)
|
|
end
|
|
end
|
|
container:SetSettingChangedCallback(settingChangedCallbackFunction)
|
|
|
|
--amount of lines which will be created for the scrollframe
|
|
local defaultAmountOfLines = 50
|
|
|
|
---@type breakdownspellscrollframe
|
|
local scrollFrame = DF:CreateScrollBox(container, "$parentSpellScroll", refreshSpellsFunc, {}, width, height, defaultAmountOfLines, CONST_SPELLSCROLL_LINEHEIGHT)
|
|
DF:ReskinSlider(scrollFrame)
|
|
scrollFrame:SetPoint("topleft", container, "topleft", 0, 0) --need to set the points
|
|
scrollFrame:SetPoint("bottomright", container, "bottomright", 0, 0) --need to set the points
|
|
|
|
container:RegisterChildForDrag(scrollFrame)
|
|
|
|
scrollFrame.DontHideChildrenOnPreRefresh = true
|
|
tabFrame.SpellScrollFrame = scrollFrame
|
|
spellsTab.SpellScrollFrame = scrollFrame
|
|
|
|
spellsTab.ApplyStandardBackdrop(container, scrollFrame)
|
|
|
|
---@param self breakdownphasescrollframe
|
|
---@return breakdownreporttable
|
|
function scrollFrame:GetReportData()
|
|
local instance = spellsTab.GetInstance()
|
|
|
|
---@type breakdownspelldatalist
|
|
local data = self:GetData()
|
|
|
|
local formatFunc = Details:GetCurrentToKFunction()
|
|
local actorObject = spellsTab.GetActor()
|
|
local displayId, subDisplayId = instance:GetDisplay()
|
|
local subDisplayName = Details:GetSubAttributeName(displayId, subDisplayId)
|
|
local combatName = instance:GetCombat():GetCombatName()
|
|
|
|
---@type breakdownreporttable
|
|
local reportData = {
|
|
title = subDisplayName .. " for " .. detailsFramework:RemoveRealmName(actorObject:Name()) .. " | " .. combatName
|
|
}
|
|
|
|
local topValue = data[1] and data[1].total or 0
|
|
|
|
for i = 1, #data do
|
|
---@type spelltableadv
|
|
local bkSpellData = data[i]
|
|
local spellId = bkSpellData.id
|
|
local spellName = Details.GetSpellInfo(spellId)
|
|
|
|
if (not spellName) then
|
|
--dumpt(bkSpellData)
|
|
if (bkSpellData.npcId) then
|
|
spellName = detailsFramework:CleanUpName(bkSpellData.actorName)
|
|
end
|
|
else
|
|
spellName = detailsFramework:CleanUpName(spellName)
|
|
end
|
|
|
|
reportData[#reportData+1] = {
|
|
name = spellName,
|
|
amount = formatFunc(nil, bkSpellData.total),
|
|
percent = string.format("%.1f", bkSpellData.total/topValue*100) .. "%",
|
|
}
|
|
end
|
|
|
|
return reportData
|
|
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,
|
|
|
|
header_click_callback = onColumnHeaderClickCallback,
|
|
|
|
header_backdrop_color = {0.1, 0.1, 0.1, 0.4},
|
|
text_color = {1, 1, 1, 0.823},
|
|
}
|
|
|
|
local headerTable = {}
|
|
|
|
---create the header frame, the header frame is the frame which shows the columns names to describe the data shown in the scrollframe
|
|
---@type df_headerframe
|
|
local header = DetailsFramework:CreateHeader(container, headerTable, headerOptions)
|
|
scrollFrame.Header = header
|
|
scrollFrame.Header:SetPoint("topleft", scrollFrame, "topleft", 0, 1)
|
|
scrollFrame.Header:SetColumnSettingChangedCallback(spellsTab.OnHeaderColumnOptionChanged)
|
|
|
|
--cache the containerType which this header is used for
|
|
headerContainerType[scrollFrame.Header] = "spells"
|
|
|
|
--create the scroll lines
|
|
for i = 1, defaultAmountOfLines do
|
|
scrollFrame:CreateLine(spellsTab.CreateSpellBar)
|
|
end
|
|
|
|
---set the data and refresh the scrollframe
|
|
---@param self breakdownspellscrollframe
|
|
---@param data breakdownspelldatalist
|
|
function scrollFrame:RefreshMe(data) --~refreshme (spells) ~refreshmes
|
|
--get which column is currently selected and the sort order
|
|
local columnIndex, order, key = scrollFrame.Header:GetSelectedColumn()
|
|
scrollFrame.SortKey = key
|
|
scrollFrame.SortOrder = order
|
|
|
|
---@type string
|
|
local keyToSort = key
|
|
|
|
---@type combat
|
|
local combatObject = spellsTab.GetCombat()
|
|
---@type number, number
|
|
local mainAttribute, subAttribute = spellsTab.GetInstance():GetDisplay()
|
|
|
|
--filling necessary information to sort the data by the selected header column
|
|
for i = 1, #data do
|
|
---@type spelltableadv
|
|
local bkSpellData = data[i]
|
|
if (not bkSpellData[keyToSort]) then
|
|
local value = getValueForHeaderSortKey(combatObject, bkSpellData, keyToSort)
|
|
bkSpellData[keyToSort] = value
|
|
end
|
|
end
|
|
|
|
if (order == "DESC") then
|
|
table.sort(data,
|
|
---@param t1 spelltableadv
|
|
---@param t2 spelltableadv
|
|
function(t1, t2)
|
|
return t1[keyToSort] > t2[keyToSort]
|
|
end)
|
|
self.topValue = data[1] and data[1][keyToSort]
|
|
else
|
|
table.sort(data,
|
|
---@param t1 spelltableadv
|
|
---@param t2 spelltableadv
|
|
function(t1, t2)
|
|
return t1[keyToSort] < t2[keyToSort]
|
|
end)
|
|
self.topValue = data[#data] and data[#data][keyToSort]
|
|
end
|
|
|
|
self:SetData(data)
|
|
self:Refresh()
|
|
end
|
|
|
|
return scrollFrame
|
|
end
|
|
|
|
|
|
---create a spellbar within the spell scroll
|
|
---@param self breakdownspellscrollframe
|
|
---@param index number
|
|
---@return breakdownspellbar
|
|
function spellsTab.CreateSpellBar(self, index) --~spellbar ~spellline ~spell ~create ~createline ~createspell ~createspellbar
|
|
---@type breakdownspellbar
|
|
local spellBar = CreateFrame("button", self:GetName() .. "SpellBarButton" .. index, self)
|
|
spellBar.index = index
|
|
|
|
--size and positioning
|
|
spellBar:SetHeight(CONST_SPELLSCROLL_LINEHEIGHT)
|
|
local y = (index-1) * CONST_SPELLSCROLL_LINEHEIGHT * -1 + (1 * -index) - 15
|
|
spellBar:SetPoint("topleft", self, "topleft", 1, y)
|
|
spellBar:SetPoint("topright", self, "topright", -1, y)
|
|
|
|
spellBar:EnableMouse(true)
|
|
spellBar:RegisterForClicks("AnyUp", "AnyDown")
|
|
spellBar:SetAlpha(0.823)
|
|
spellBar:SetFrameStrata("high")
|
|
spellBar:SetScript("OnEnter", onEnterSpellBar)
|
|
spellBar:SetScript("OnLeave", onLeaveSpellBar)
|
|
spellBar:SetScript("OnMouseDown", onMouseDownBreakdownSpellBar)
|
|
spellBar:SetScript("OnMouseUp", onMouseUpBreakdownSpellBar)
|
|
spellBar.onMouseUpTime = 0
|
|
spellBar.ExpandedChildren = {}
|
|
|
|
DF:Mixin(spellBar, DF.HeaderFunctions)
|
|
|
|
---@type breakdownspellbarstatusbar
|
|
local statusBar = CreateFrame("StatusBar", "$parentStatusBar", spellBar)
|
|
statusBar:SetAllPoints()
|
|
statusBar:SetAlpha(0.5)
|
|
statusBar:SetMinMaxValues(0, 100)
|
|
statusBar:SetValue(50)
|
|
statusBar:EnableMouse(false)
|
|
statusBar:SetFrameLevel(spellBar:GetFrameLevel() - 1)
|
|
spellBar.statusBar = statusBar
|
|
|
|
---@type texture this is the statusbar texture
|
|
local statusBarTexture = statusBar:CreateTexture("$parentTexture", "artwork")
|
|
statusBar:SetStatusBarTexture(statusBarTexture)
|
|
statusBar:SetStatusBarColor(1, 1, 1, 1)
|
|
|
|
---@type texture background texture
|
|
local backgroundTexture = statusBar:CreateTexture("$parentTextureBackground", "border")
|
|
backgroundTexture:SetAllPoints()
|
|
statusBar.backgroundTexture = backgroundTexture
|
|
|
|
---@type texture overlay texture to use when the spellbar is selected
|
|
local statusBarOverlayTexture = statusBar:CreateTexture("$parentTextureOverlay", "overlay", nil, 7)
|
|
statusBarOverlayTexture:SetTexture([[Interface/AddOns/Details/images/overlay_indicator_1]])
|
|
statusBarOverlayTexture:SetVertexColor(1, 1, 1, 0.2)
|
|
statusBarOverlayTexture:SetAllPoints()
|
|
statusBarOverlayTexture:Hide()
|
|
spellBar.overlayTexture = statusBarOverlayTexture
|
|
statusBar.overlayTexture = statusBarOverlayTexture
|
|
|
|
---@type texture shown when the mouse hoverover this spellbar
|
|
local hightlightTexture = statusBar:CreateTexture("$parentTextureHighlight", "highlight")
|
|
hightlightTexture:SetColorTexture(1, 1, 1, 0.2)
|
|
hightlightTexture:SetAllPoints()
|
|
statusBar.highlightTexture = hightlightTexture
|
|
|
|
--button to expand the bar when there's spells merged
|
|
---@type breakdownexpandbutton
|
|
local expandButton = CreateFrame("button", "$parentExpandButton", spellBar, "BackdropTemplate")
|
|
expandButton:SetSize(CONST_BAR_HEIGHT, CONST_BAR_HEIGHT)
|
|
expandButton:RegisterForClicks("LeftButtonDown")
|
|
spellBar.expandButton = expandButton
|
|
|
|
---@type texture
|
|
local expandButtonTexture = expandButton:CreateTexture("$parentTexture", "artwork")
|
|
expandButtonTexture:SetPoint("center", expandButton, "center", 0, 0)
|
|
expandButtonTexture:SetSize(CONST_BAR_HEIGHT-2, CONST_BAR_HEIGHT-2)
|
|
expandButton.texture = expandButtonTexture
|
|
|
|
--frame which will show the spell tooltip
|
|
---@type frame
|
|
local spellIconFrame = CreateFrame("frame", "$parentIconFrame", spellBar, "BackdropTemplate")
|
|
spellIconFrame:SetSize(CONST_BAR_HEIGHT - 2, CONST_BAR_HEIGHT - 2)
|
|
spellIconFrame:SetScript("OnEnter", onEnterSpellIconFrame)
|
|
spellIconFrame:SetScript("OnLeave", onLeaveSpellIconFrame)
|
|
spellBar.spellIconFrame = spellIconFrame
|
|
|
|
--create the icon to show the spell texture
|
|
---@type texture
|
|
local spellIcon = spellIconFrame:CreateTexture("$parentTexture", "overlay")
|
|
spellIcon:SetAllPoints()
|
|
spellIcon:SetTexCoord(.1, .9, .1, .9)
|
|
detailsFramework:SetMask(spellIcon, Details:GetTextureAtlas("iconmask"))
|
|
spellBar.spellIcon = spellIcon
|
|
|
|
--create a square frame which is placed at the right side of the line to show which targets for damaged by the spell
|
|
---@type breakdowntargetframe
|
|
local targetsSquareFrame = CreateFrame("frame", "$parentTargetsFrame", statusBar, "BackdropTemplate")
|
|
targetsSquareFrame:SetSize(CONST_SPELLSCROLL_LINEHEIGHT, CONST_SPELLSCROLL_LINEHEIGHT)
|
|
targetsSquareFrame:SetAlpha(.7)
|
|
targetsSquareFrame:SetScript("OnEnter", onEnterSpellTarget)
|
|
targetsSquareFrame:SetScript("OnLeave", onLeaveSpellTarget)
|
|
targetsSquareFrame:SetFrameLevel(statusBar:GetFrameLevel()+2)
|
|
spellBar.targetsSquareFrame = targetsSquareFrame
|
|
|
|
---@type texture
|
|
local targetTexture = targetsSquareFrame:CreateTexture("$parentTexture", "overlay")
|
|
targetTexture:SetTexture(CONST_TARGET_TEXTURE)
|
|
targetTexture:SetAllPoints()
|
|
targetTexture:SetDesaturated(true)
|
|
spellBar.targetsSquareTexture = targetTexture
|
|
targetsSquareFrame.texture = targetTexture
|
|
|
|
spellBar:AddFrameToHeaderAlignment(spellIconFrame)
|
|
spellBar:AddFrameToHeaderAlignment(targetsSquareFrame)
|
|
|
|
--create texts
|
|
---@type fontstring[]
|
|
spellBar.InLineTexts = {}
|
|
|
|
for i = 1, 16 do
|
|
---@type fontstring
|
|
local fontString = spellBar:CreateFontString("$parentFontString" .. i, "overlay", "GameFontHighlightSmall")
|
|
fontString:SetJustifyH("left")
|
|
fontString:SetTextColor(1, 1, 1, 1)
|
|
fontString:SetNonSpaceWrap(true)
|
|
fontString:SetWordWrap(false)
|
|
spellBar["lineText" .. i] = fontString
|
|
spellBar.InLineTexts[i] = fontString
|
|
fontString:SetTextColor(1, 1, 1, 1)
|
|
spellBar:AddFrameToHeaderAlignment(fontString)
|
|
end
|
|
|
|
spellBar:AlignWithHeader(self.Header, "left")
|
|
return spellBar
|
|
end
|
|
|