Split the window_playerbreakdown_spells.lua into three more files

This commit is contained in:
Tercio Jose
2023-06-08 22:03:37 -03:00
parent 631b3ceaa0
commit cc09a733bf
15 changed files with 1608 additions and 1494 deletions
@@ -0,0 +1,16 @@
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
local GetSpellInfo = GetSpellInfo
local _GetSpellInfo = Details.GetSpellInfo
local GameTooltip = GameTooltip
local IsShiftKeyDown = IsShiftKeyDown
local DF = DetailsFramework
local tinsert = tinsert
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,15 @@
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
local GetSpellInfo = GetSpellInfo
local _GetSpellInfo = Details.GetSpellInfo
local GameTooltip = GameTooltip
local IsShiftKeyDown = IsShiftKeyDown
local DF = DetailsFramework
local tinsert = tinsert
@@ -0,0 +1,858 @@
local Details = _G.Details
local Loc = _G.LibStub("AceLocale-3.0"):GetLocale ( "Details" )
local SharedMedia = _G.LibStub:GetLibrary("LibSharedMedia-3.0")
local UIParent = UIParent
local gump = Details.gump
local _
local addonName, Details222 = ...
--remove warnings in the code
local ipairs = ipairs
local tinsert = tinsert
local tremove = tremove
local type = type
local unpack = _G.unpack
local PixelUtil = PixelUtil
local UISpecialFrames = UISpecialFrames
local CreateFrame = _G.CreateFrame
local detailsFramework = DetailsFramework
local subAttributes = Details.sub_atributos
local breakdownWindow = Details.playerDetailWindow
local SummaryWidgets = {}
local CurrentTab = "Summary"
local PLAYER_DETAILS_WINDOW_WIDTH = 890
local PLAYER_DETAILS_WINDOW_HEIGHT = 574
local PLAYER_DETAILS_STATUSBAR_HEIGHT = 20
local PLAYER_DETAILS_STATUSBAR_ALPHA = 1
Details.player_details_tabs = {}
breakdownWindow.currentTabsInUse = {}
Details222.BreakdownWindow.BackdropSettings = {
backdrop = {edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true},
backdropcolor = {DetailsFramework:GetDefaultBackdropColor()},
backdropbordercolor = {0, 0, 0, 0.7},
}
------------------------------------------------------------------------------------------------------------------------------
--self = instancia
--jogador = classe_damage ou classe_heal
function Details:GetBreakdownTabsInUse()
return breakdownWindow.currentTabsInUse
end
function Details:GetBreakdownTabByName(tabName, tablePool)
tablePool = tablePool or Details.player_details_tabs
for index = 1, #tablePool do
local tab = tablePool[index]
if (tab.tabname == tabName) then
return tab, index
end
end
end
--return the combat being used to show the data in the opened breakdown window
function Details:GetCombatFromBreakdownWindow()
return breakdownWindow.instancia and breakdownWindow.instancia.showing
end
---return the window that requested to open the player breakdown window
---@return instance
function Details:GetActiveWindowFromBreakdownWindow()
return breakdownWindow.instancia
end
--return if the breakdown window is showing damage or heal
function Details:GetDisplayTypeFromBreakdownWindow()
return breakdownWindow.atributo, breakdownWindow.sub_atributo
end
--return the actor object in use by the breakdown window
function Details:GetActorObjectFromBreakdownWindow()
return breakdownWindow.jogador
end
function Details:GetBreakdownWindow()
return Details.playerDetailWindow
end
function Details:IsBreakdownWindowOpen()
return breakdownWindow.ativo
end
---open the breakdown window
---@param self details
---@param instanceObject instance
---@param actorObject actor
---@param bFromAttributeChange boolean|nil
---@param bIsRefresh boolean|nil
---@param bIsShiftKeyDown boolean|nil
---@param bIsControlKeyDown boolean|nil
function Details:OpenBreakdownWindow(instanceObject, actorObject, bFromAttributeChange, bIsRefresh, bIsShiftKeyDown, bIsControlKeyDown)
---@type number, number
local mainAttribute, subAttribute = instanceObject:GetDisplay()
if (not Details.row_singleclick_overwrite[mainAttribute] or not Details.row_singleclick_overwrite[mainAttribute][subAttribute]) then
Details:CloseBreakdownWindow()
return
elseif (type(Details.row_singleclick_overwrite[mainAttribute][subAttribute]) == "function") then
if (bFromAttributeChange) then
Details:CloseBreakdownWindow()
return
end
Details.row_singleclick_overwrite[mainAttribute][subAttribute](_, actorObject, instanceObject, bIsShiftKeyDown, bIsControlKeyDown)
return
end
if (instanceObject:GetMode() == DETAILS_MODE_RAID) then
Details:CloseBreakdownWindow()
return
end
--Details.info_jogador armazena o jogador que esta sendo mostrado na janela de detalhes
if (breakdownWindow.jogador and breakdownWindow.jogador == actorObject and instanceObject and breakdownWindow.atributo and mainAttribute == breakdownWindow.atributo and subAttribute == breakdownWindow.sub_atributo and not bIsRefresh) then
Details:CloseBreakdownWindow() --se clicou na mesma barra ento fecha a janela de detalhes
return
elseif (not actorObject) then
Details:CloseBreakdownWindow()
return
end
--create the player list frame in the left side of the window
Details.PlayerBreakdown.CreatePlayerListFrame()
Details.PlayerBreakdown.CreateDumpDataFrame()
if (not breakdownWindow.bHasInitialized) then
local infoNumPoints = breakdownWindow:GetNumPoints()
for i = 1, infoNumPoints do
local point1, anchorObject, point2, x, y = breakdownWindow:GetPoint(i)
if (not anchorObject) then
breakdownWindow:ClearAllPoints()
end
end
breakdownWindow:SetUserPlaced(false)
breakdownWindow:SetDontSavePosition(true)
local okay, errorText = pcall(function()
breakdownWindow:SetPoint("center", UIParent, "center", 0, 0)
end)
if (not okay) then
breakdownWindow:ClearAllPoints()
breakdownWindow:SetPoint("center", UIParent, "center", 0, 0)
end
breakdownWindow.bHasInitialized = true
end
if (not breakdownWindow.RightSideBar) then
--breakdownWindow:CreateRightSideBar()
end
--todo: all portuguese keys to english
breakdownWindow.ativo = true --sinaliza o addon que a janela esta aberta
breakdownWindow.atributo = mainAttribute --instancia.atributo -> grava o atributo (damage, heal, etc)
breakdownWindow.sub_atributo = subAttribute --instancia.sub_atributo -> grava o sub atributo (damage done, dps, damage taken, etc)
breakdownWindow.jogador = actorObject --de qual jogador (objeto classe_damage)
breakdownWindow.instancia = instanceObject --salva a referncia da instncia que pediu o breakdownWindow
breakdownWindow.target_text = Loc ["STRING_TARGETS"] .. ":"
breakdownWindow.target_member = "total"
breakdownWindow.target_persecond = false
breakdownWindow.mostrando = nil
local nome = breakdownWindow.jogador.nome --nome do jogador
local atributo_nome = subAttributes[breakdownWindow.atributo].lista [breakdownWindow.sub_atributo] .. " " .. Loc ["STRING_ACTORFRAME_REPORTOF"] --// nome do atributo // precisa ser o sub atributo correto???
--removendo o nome da realm do jogador
if (nome:find("-")) then
nome = nome:gsub(("-.*"), "")
end
if (breakdownWindow.instancia.atributo == 1 and breakdownWindow.instancia.sub_atributo == 6) then --enemy
atributo_nome = subAttributes [breakdownWindow.atributo].lista [1] .. " " .. Loc ["STRING_ACTORFRAME_REPORTOF"]
end
breakdownWindow.actorName:SetText(nome) --found it
breakdownWindow.attributeName:SetText(atributo_nome)
local serial = actorObject.serial
local avatar
if (serial ~= "") then
avatar = NickTag:GetNicknameTable (serial)
end
if (avatar and avatar [1]) then
breakdownWindow.actorName:SetText((not Details.ignore_nicktag and avatar [1]) or nome)
end
if (avatar and avatar [2]) then
breakdownWindow.avatar:SetTexture(avatar [2])
breakdownWindow.avatar_bg:SetTexture(avatar [4])
if (avatar [5]) then
breakdownWindow.avatar_bg:SetTexCoord(unpack(avatar [5]))
end
if (avatar [6]) then
breakdownWindow.avatar_bg:SetVertexColor(unpack(avatar [6]))
end
breakdownWindow.avatar_nick:SetText(avatar [1] or nome)
breakdownWindow.avatar_attribute:SetText(atributo_nome)
breakdownWindow.avatar_attribute:SetPoint("CENTER", breakdownWindow.avatar_nick, "CENTER", 0, 14)
breakdownWindow.avatar:Show()
breakdownWindow.avatar_bg:Show()
breakdownWindow.avatar_bg:SetAlpha(.65)
breakdownWindow.avatar_nick:Show()
breakdownWindow.avatar_attribute:Show()
breakdownWindow.actorName:Hide()
breakdownWindow.attributeName:Hide()
else
breakdownWindow.avatar:Hide()
breakdownWindow.avatar_bg:Hide()
breakdownWindow.avatar_nick:Hide()
breakdownWindow.avatar_attribute:Hide()
breakdownWindow.actorName:Show()
breakdownWindow.attributeName:Show()
end
breakdownWindow.attributeName:SetPoint("bottomleft", breakdownWindow.actorName, "topleft", 0, 2)
---@type string
local actorClass = actorObject.classe --classe not registered because it should be renamed to english 'class'
if (not actorClass) then
actorClass = "monster"
end
breakdownWindow.classIcon:SetTexture("Interface\\AddOns\\Details\\images\\classes") --top left
breakdownWindow.SetClassIcon(actorObject, actorClass)
Details.FadeHandler.Fader(breakdownWindow, 0)
Details:UpdateBreakdownPlayerList()
Details:InitializeAurasTab()
Details:InitializeCompareTab()
--open tab
local tabsShown = {}
local tabsReplaced = {}
local tabReplacedAmount = 0
Details:Destroy(breakdownWindow.currentTabsInUse)
for index = 1, #Details.player_details_tabs do
local tab = Details.player_details_tabs[index]
tab.replaced = nil
tabsShown[#tabsShown+1] = tab
end
for index = 1, #tabsShown do
--get the tab
local tab = tabsShown[index]
if (tab.replaces) then
local attributeList = tab.replaces.attributes
if (attributeList[breakdownWindow.atributo]) then
if (attributeList[breakdownWindow.atributo][breakdownWindow.sub_atributo]) then
local tabReplaced, tabIndex = Details:GetBreakdownTabByName(tab.replaces.tabNameToReplace, tabsShown)
if (tabReplaced and tabIndex < index) then
tabReplaced:Hide()
tabReplaced.frame:Hide()
tinsert(tabsReplaced, tabReplaced)
tremove(tabsShown, tabIndex)
tinsert(tabsShown, tabIndex, tab)
if (tabReplaced.tabname == breakdownWindow.selectedTab) then
breakdownWindow.selectedTab = tab.tabname
end
tabReplaced.replaced = true
tabReplacedAmount = tabReplacedAmount + 1
end
end
end
end
end
local newTabsShown = {}
local tabAlreadyInUse = {}
for index = 1, #tabsShown do
if (not tabAlreadyInUse[tabsShown[index].tabname]) then
tabAlreadyInUse[tabsShown[index].tabname] = true
tinsert(newTabsShown, tabsShown[index])
end
end
tabsShown = newTabsShown
breakdownWindow.currentTabsInUse = newTabsShown
breakdownWindow:ShowTabs()
Details222.BreakdownWindow.CurrentDefaultTab = nil
local shownTab
for index = 1, #tabsShown do
local tabButton = tabsShown[index]
if (tabButton:condition(breakdownWindow.jogador, breakdownWindow.atributo, breakdownWindow.sub_atributo)) then
if (tabButton.IsDefaultTab) then
Details222.BreakdownWindow.CurrentDefaultTab = tabButton
end
if (breakdownWindow.selectedTab == tabButton.tabname) then
tabButton:DoClick()
tabButton:OnShowFunc()
shownTab = tabButton
actorObject:MontaInfo() --old api to update the breakdown window
end
end
end
if (shownTab) then
shownTab:Click()
end
end
function Details:CloseBreakdownWindow()
if (breakdownWindow.ativo) then
Details.FadeHandler.Fader(breakdownWindow, 1)
breakdownWindow.ativo = false --sinaliza o addon que a janela esta agora fechada
breakdownWindow.jogador = nil
breakdownWindow.atributo = nil
breakdownWindow.sub_atributo = nil
breakdownWindow.instancia = nil
breakdownWindow.actorName:SetText("")
breakdownWindow.attributeName:SetText("")
--iterate all tabs and clear caches
local tabsInUse = Details:GetBreakdownTabsInUse()
for index = 1, #tabsInUse do
local tabButton = tabsInUse[index]
tabButton.last_actor = nil
end
end
end
function Details.PlayerBreakdown.CreateDumpDataFrame()
breakdownWindow.dumpDataFrame = CreateFrame("frame", "$parentDumpTableFrame", DetailsBreakdownWindowPlayerScrollBox, "BackdropTemplate")
breakdownWindow.dumpDataFrame:SetPoint("topleft", DetailsBreakdownWindowPlayerScrollBox, "topleft", 0, 0)
breakdownWindow.dumpDataFrame:SetPoint("bottomright", DetailsBreakdownWindowPlayerScrollBox, "bottomright", 0, 0)
breakdownWindow.dumpDataFrame:SetFrameLevel(DetailsBreakdownWindowPlayerScrollBox:GetFrameLevel() + 10)
detailsFramework:ApplyStandardBackdrop(breakdownWindow.dumpDataFrame, true)
breakdownWindow.dumpDataFrame:Hide()
--create a details framework special lua editor
breakdownWindow.dumpDataFrame.luaEditor = detailsFramework:NewSpecialLuaEditorEntry(breakdownWindow.dumpDataFrame, 1, 1, "text", "$parentCodeEditorWindow")
breakdownWindow.dumpDataFrame.luaEditor:SetPoint("topleft", breakdownWindow.dumpDataFrame, "topleft", 2, -2)
breakdownWindow.dumpDataFrame.luaEditor:SetPoint("bottomright", breakdownWindow.dumpDataFrame, "bottomright", -2, 2)
breakdownWindow.dumpDataFrame.luaEditor:SetFrameLevel(breakdownWindow.dumpDataFrame:GetFrameLevel()+1)
breakdownWindow.dumpDataFrame.luaEditor:SetBackdrop({})
--hide the scroll bar
DetailsBreakdownWindowPlayerScrollBoxDumpTableFrameCodeEditorWindowScrollBar:Hide()
end
function breakdownWindow:CreateRightSideBar() --not enabled
breakdownWindow.RightSideBar = CreateFrame("frame", nil, breakdownWindow, "BackdropTemplate")
breakdownWindow.RightSideBar:SetWidth(20)
breakdownWindow.RightSideBar:SetPoint("topleft", breakdownWindow, "topright", 1, 0)
breakdownWindow.RightSideBar:SetPoint("bottomleft", breakdownWindow, "bottomright", 1, 0)
local rightSideBarAlpha = 0.75
detailsFramework:ApplyStandardBackdrop(breakdownWindow.RightSideBar)
local toggleMergePlayerSpells = function()
Details.merge_player_abilities = not Details.merge_player_abilities
local playerObject = Details:GetActorObjectFromBreakdownWindow()
local instanceObject = Details:GetActiveWindowFromBreakdownWindow()
Details:OpenBreakdownWindow(instanceObject, playerObject) --toggle
Details:OpenBreakdownWindow(instanceObject, playerObject)
end
local mergePlayerSpellsCheckbox = detailsFramework:CreateSwitch(breakdownWindow, toggleMergePlayerSpells, Details.merge_player_abilities, _, _, _, _, _, _, _, _, _, _, detailsFramework:GetTemplate("switch", "OPTIONS_CHECKBOX_BRIGHT_TEMPLATE"))
mergePlayerSpellsCheckbox:SetAsCheckBox()
mergePlayerSpellsCheckbox:SetPoint("bottom", breakdownWindow.RightSideBar, "bottom", 0, 2)
local mergePlayerSpellsLabel = breakdownWindow.RightSideBar:CreateFontString(nil, "overlay", "GameFontNormal")
mergePlayerSpellsLabel:SetText("Merge Player Spells")
detailsFramework:SetFontRotation(mergePlayerSpellsLabel, 90)
mergePlayerSpellsLabel:SetPoint("center", mergePlayerSpellsCheckbox.widget, "center", -6, mergePlayerSpellsCheckbox:GetHeight()/2 + mergePlayerSpellsLabel:GetStringWidth() / 2)
--
local toggleMergePetSpells = function()
Details.merge_pet_abilities = not Details.merge_pet_abilities
local playerObject = Details:GetActorObjectFromBreakdownWindow()
local instanceObject = Details:GetActiveWindowFromBreakdownWindow()
Details:OpenBreakdownWindow(instanceObject, playerObject) --toggle
Details:OpenBreakdownWindow(instanceObject, playerObject)
end
local mergePetSpellsCheckbox = detailsFramework:CreateSwitch(breakdownWindow, toggleMergePetSpells, Details.merge_pet_abilities, _, _, _, _, _, _, _, _, _, _, detailsFramework:GetTemplate("switch", "OPTIONS_CHECKBOX_BRIGHT_TEMPLATE"))
mergePetSpellsCheckbox:SetAsCheckBox(true)
mergePetSpellsCheckbox:SetPoint("bottom", breakdownWindow.RightSideBar, "bottom", 0, 160)
local mergePetSpellsLabel = breakdownWindow.RightSideBar:CreateFontString(nil, "overlay", "GameFontNormal")
mergePetSpellsLabel:SetText("Merge Pet Spells")
detailsFramework:SetFontRotation(mergePetSpellsLabel, 90)
mergePetSpellsLabel:SetPoint("center", mergePetSpellsCheckbox.widget, "center", -6, mergePetSpellsCheckbox:GetHeight()/2 + mergePetSpellsLabel:GetStringWidth() / 2)
mergePlayerSpellsCheckbox:SetAlpha(rightSideBarAlpha)
mergePlayerSpellsLabel:SetAlpha(rightSideBarAlpha)
mergePetSpellsCheckbox:SetAlpha(rightSideBarAlpha)
mergePetSpellsLabel:SetAlpha(rightSideBarAlpha)
end
---@type {[number]: boolean}
Details222.BreakdownWindow.ExpandedSpells = {}
---set a spell as expanded or not in the breakdown window
---@param key any
---@param bIsExpanded boolean
function Details222.BreakdownWindow.SetSpellAsExpanded(key, bIsExpanded)
Details222.BreakdownWindow.ExpandedSpells[key] = bIsExpanded
end
---get the state of the expanded for a spell
---@param key any
---@return boolean
function Details222.BreakdownWindow.IsSpellExpanded(key)
return Details222.BreakdownWindow.ExpandedSpells[key]
end
---receives spell data to show in the summary tab
---@param data breakdownspelldatalist
---@param actorObject actor
---@param combatObject combat
---@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 tabButton = Details222.BreakdownWindow.CurrentDefaultTab
if (tabButton) then
--tab is the tab button
if (tabButton.OnReceiveSpellData) then
tabButton.OnReceiveSpellData(data, actorObject, combatObject, instance)
end
end
end
function Details222.BreakdownWindow.SendTargetData(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
---set the class or spec icon for the actor displayed
---@param actorObject actor
---@param class string
function breakdownWindow.SetClassIcon(actorObject, class)
if (actorObject.spellicon) then
breakdownWindow.classIcon:SetTexture(actorObject.spellicon)
breakdownWindow.classIcon:SetTexCoord(.1, .9, .1, .9)
elseif (actorObject.spec) then
breakdownWindow.classIcon:SetTexture([[Interface\AddOns\Details\images\spec_icons_normal_alpha]])
breakdownWindow.classIcon:SetTexCoord(unpack(_detalhes.class_specs_coords [actorObject.spec]))
else
local coords = CLASS_ICON_TCOORDS[class]
if (coords) then
breakdownWindow.classIcon:SetTexture([[Interface\Glues\CHARACTERCREATE\UI-CHARACTERCREATE-CLASSES]])
local l, r, t, b = unpack(coords)
breakdownWindow.classIcon:SetTexCoord(l+0.01953125, r-0.01953125, t+0.01953125, b-0.01953125)
else
local c = _detalhes.class_coords ["MONSTER"]
breakdownWindow.classIcon:SetTexture("Interface\\AddOns\\Details\\images\\classes")
breakdownWindow.classIcon:SetTexCoord(c[1], c[2], c[3], c[4])
end
end
end
function Details:SetBreakdownWindowBackgroundTexture(texture)
breakdownWindow.backgroundTexture:SetTexture(texture)
end
--search key: ~create ~inicio ~start
function Details:CreateBreakdownWindow()
table.insert(UISpecialFrames, breakdownWindow:GetName())
breakdownWindow.extra_frames = {}
breakdownWindow.Loaded = true
Details.playerDetailWindow = breakdownWindow
breakdownWindow:SetWidth(PLAYER_DETAILS_WINDOW_WIDTH)
breakdownWindow:SetHeight(PLAYER_DETAILS_WINDOW_HEIGHT)
breakdownWindow:SetFrameStrata("HIGH")
breakdownWindow:SetToplevel(true)
breakdownWindow:EnableMouse(true)
breakdownWindow:SetResizable(true)
breakdownWindow:SetMovable(true)
breakdownWindow:SetClampedToScreen(true)
--make the window movable
if (not breakdownWindow.registeredLibWindow) then
local LibWindow = LibStub("LibWindow-1.1")
breakdownWindow.registeredLibWindow = true
if (LibWindow) then
breakdownWindow.libWindowTable = breakdownWindow.libWindowTable or {}
LibWindow.RegisterConfig(breakdownWindow, breakdownWindow.libWindowTable)
LibWindow.RestorePosition(breakdownWindow)
LibWindow.MakeDraggable(breakdownWindow)
LibWindow.SavePosition(breakdownWindow)
breakdownWindow:SetScript("OnMouseDown", function(self, button)
if (button == "RightButton") then
Details:CloseBreakdownWindow()
end
end)
end
end
detailsFramework:ApplyStandardBackdrop(breakdownWindow)
--background
breakdownWindow.backgroundTexture = breakdownWindow:CreateTexture("$parent", "background", nil, -3)
breakdownWindow.backgroundTexture:SetAllPoints()
breakdownWindow.backgroundTexture:Hide()
--host the textures and fontstring of the default frame of the player breakdown window
--what is the summary window: is the frame where all the widgets for the summary tab are created
breakdownWindow.SummaryWindowWidgets = CreateFrame("frame", "DetailsBreakdownWindowSummaryWidgets", breakdownWindow, "BackdropTemplate")
local SWW = breakdownWindow.SummaryWindowWidgets
SWW:SetAllPoints()
table.insert(SummaryWidgets, SWW) --where SummaryWidgets is declared: at the header of the file, what is the purpose of this table?
breakdownWindow.SummaryWindowWidgets:Hide()
detailsFramework:CreateScaleBar(breakdownWindow, Details.player_details_window)
breakdownWindow:SetScale(Details.player_details_window.scale)
--class icon
breakdownWindow.classIcon = breakdownWindow:CreateTexture(nil, "overlay", nil, 1)
breakdownWindow.classIcon:SetPoint("topleft", breakdownWindow, "topleft", 2, -17)
breakdownWindow.classIcon:SetSize(54, 54)
breakdownWindow.classIcon:SetAlpha(0.7)
--close button
breakdownWindow.closeButton = CreateFrame("Button", nil, breakdownWindow, "UIPanelCloseButton")
breakdownWindow.closeButton:SetSize(20, 20)
breakdownWindow.closeButton:SetPoint("TOPRIGHT", breakdownWindow, "TOPRIGHT", -5, -4)
breakdownWindow.closeButton:SetFrameLevel(breakdownWindow:GetFrameLevel()+5)
breakdownWindow.closeButton:GetNormalTexture():SetDesaturated(true)
breakdownWindow.closeButton:GetNormalTexture():SetVertexColor(.6, .6, .6)
breakdownWindow.closeButton:SetScript("OnClick", function(self)
Details:CloseBreakdownWindow()
end)
--title
detailsFramework:NewLabel(breakdownWindow, breakdownWindow, nil, "titleText", Loc ["STRING_PLAYER_DETAILS"], "GameFontHighlightLeft", 12, {227/255, 186/255, 4/255})
breakdownWindow.titleText:SetPoint("center", breakdownWindow, "center")
breakdownWindow.titleText:SetPoint("top", breakdownWindow, "top", 0, -6)
--create the texts shown on the window
do
breakdownWindow.actorName = breakdownWindow:CreateFontString(nil, "overlay", "QuestFont_Large")
breakdownWindow.actorName:SetPoint("left", breakdownWindow.classIcon, "right", 20, -7)
breakdownWindow.attributeName = breakdownWindow:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
breakdownWindow.avatar = breakdownWindow:CreateTexture(nil, "overlay")
breakdownWindow.avatar_bg = breakdownWindow:CreateTexture(nil, "overlay")
breakdownWindow.avatar_attribute = breakdownWindow:CreateFontString(nil, "overlay", "GameFontHighlightSmall")
breakdownWindow.avatar_nick = breakdownWindow:CreateFontString(nil, "overlay", "QuestFont_Large")
breakdownWindow.avatar:SetDrawLayer("overlay", 3)
breakdownWindow.avatar_bg:SetDrawLayer("overlay", 2)
breakdownWindow.avatar_nick:SetDrawLayer("overlay", 4)
breakdownWindow.avatar:SetPoint("TOPLEFT", breakdownWindow, "TOPLEFT", 60, -10)
breakdownWindow.avatar_bg:SetPoint("TOPLEFT", breakdownWindow, "TOPLEFT", 60, -12)
breakdownWindow.avatar_bg:SetSize(275, 60)
breakdownWindow.avatar_nick:SetPoint("TOPLEFT", breakdownWindow, "TOPLEFT", 195, -54)
breakdownWindow.avatar:Hide()
breakdownWindow.avatar_bg:Hide()
breakdownWindow.avatar_nick:Hide()
end
--statusbar
local statusBar = CreateFrame("frame", nil, breakdownWindow, "BackdropTemplate")
statusBar:SetPoint("bottomleft", breakdownWindow, "bottomleft")
statusBar:SetPoint("bottomright", breakdownWindow, "bottomright")
statusBar:SetHeight(PLAYER_DETAILS_STATUSBAR_HEIGHT)
detailsFramework:ApplyStandardBackdrop(statusBar)
statusBar:SetAlpha(PLAYER_DETAILS_STATUSBAR_ALPHA)
breakdownWindow.statusBar = statusBar
statusBar.Text = detailsFramework:CreateLabel(statusBar)
statusBar.Text:SetPoint("left", 2, 0)
--create the gradients in the top and bottom side of the breakdown window
local gradientStartColor = Details222.ColorScheme.GetColorFor("gradient-background")
local gradientUp = detailsFramework:CreateTexture(breakdownWindow, {gradient = "vertical", fromColor = gradientStartColor, toColor = {0, 0, 0, 0.2}}, 1, 68, "artwork", {0, 1, 0, 1})
gradientUp:SetPoint("tops", 1, 1)
local gradientHeight = 481
local gradientDown = detailsFramework:CreateTexture(breakdownWindow, {gradient = "vertical", fromColor = "transparent", toColor = {0, 0, 0, 0.7}}, 1, gradientHeight, "border", {0, 1, 0, 1})
gradientDown:SetPoint("bottomleft", breakdownWindow.statusBar, "topleft", 1, 1)
gradientDown:SetPoint("bottomright", breakdownWindow.statusBar, "topright", -1, 1)
function breakdownWindow:SetStatusbarText(text, fontSize, fontColor)
if (not text) then
breakdownWindow:SetStatusbarText("Details! Damage Meter | Use '/details stats' for statistics", 10, "gray")
return
end
statusBar.Text.text = text
statusBar.Text.fontsize = fontSize
statusBar.Text.fontcolor = fontColor
end
--set default text
breakdownWindow:SetStatusbarText()
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--tabs ~tabs
function breakdownWindow:ShowTabs()
local tabsShown = 0
local secondRowIndex = 1
local breakLine = 6 --the tab it'll start the second line
local tablePool = Details:GetBreakdownTabsInUse()
for index = 1, #tablePool do
local tabButton = tablePool[index]
if (tabButton:condition(breakdownWindow.jogador, breakdownWindow.atributo, breakdownWindow.sub_atributo) and not tabButton.replaced) then
--test if can show the tutorial for the comparison tab
if (tabButton.tabname == "Compare") then
--Details:SetTutorialCVar ("DETAILS_INFO_TUTORIAL1", false)
if (not Details:GetTutorialCVar("DETAILS_INFO_TUTORIAL1")) then
Details:SetTutorialCVar ("DETAILS_INFO_TUTORIAL1", true)
local alert = CreateFrame("frame", "DetailsInfoPopUp1", breakdownWindow, "DetailsHelpBoxTemplate")
alert.ArrowUP:Show()
alert.ArrowGlowUP:Show()
alert.Text:SetText(Loc ["STRING_INFO_TUTORIAL_COMPARISON1"])
alert:SetPoint("bottom", tabButton.widget or tabButton, "top", 5, 28)
alert:Show()
end
end
tabButton:Show()
tabsShown = tabsShown + 1
tabButton:ClearAllPoints()
--get the button width
local buttonTemplate = gump:GetTemplate("button", "DETAILS_TAB_BUTTON_TEMPLATE")
local buttonWidth = buttonTemplate.width + 1
--pixelutil might not be compatible with classic wow
if (PixelUtil) then
PixelUtil.SetSize(tabButton, buttonTemplate.width, buttonTemplate.height)
if (tabsShown >= breakLine) then --next row of icons
PixelUtil.SetPoint(tabButton, "bottomright", breakdownWindow, "topright", -514 + (buttonWidth * (secondRowIndex)), -50)
secondRowIndex = secondRowIndex + 1
else
PixelUtil.SetPoint(tabButton, "bottomright", breakdownWindow, "topright", -514 + (buttonWidth * tabsShown), -69)
end
else
tabButton:SetSize(buttonTemplate.width, buttonTemplate.height)
if (tabsShown >= breakLine) then --next row of icons
tabButton:SetPoint("bottomright", breakdownWindow, "topright", -514 + (buttonWidth * (secondRowIndex)), -50)
secondRowIndex = secondRowIndex + 1
else
tabButton:SetPoint("bottomright", breakdownWindow, "topright", -514 + (buttonWidth * tabsShown), -69)
end
end
tabButton:SetAlpha(0.8)
else
tabButton.frame:Hide()
tabButton:Hide()
end
end
if (tabsShown < 2) then
tablePool[1]:SetPoint("bottomleft", breakdownWindow.container_barras, "topleft", 490 - (94 * (1-0)), 1)
end
--selected by default
tablePool[1]:Click()
end
breakdownWindow:SetScript("OnHide", function(self)
Details:CloseBreakdownWindow()
for _, tab in ipairs(Details.player_details_tabs) do
tab:Hide()
tab.frame:Hide()
end
end)
breakdownWindow.tipo = 1 --tipo da janela // 1 = janela normal
return breakdownWindow
end
breakdownWindow.selectedTab = "Summary"
function Details:CreatePlayerDetailsTab(tabName, locName, conditionFunc, fillFunc, tabOnClickFunc, onCreateFunc, iconSettings, replace, bIsDefaultTab) --~tab
if (not tabName) then
tabName = "unnamed"
end
--create a button to select the tab
local tabButton = detailsFramework:CreateButton(breakdownWindow, function()end, 20, 20, locName, nil, nil, nil, nil, breakdownWindow:GetName() .. "TabButton" .. tabName .. math.random(1, 1000), nil, "DETAILS_TAB_BUTTON_TEMPLATE")
tabButton:SetFrameLevel(breakdownWindow:GetFrameLevel()+1)
tabButton:Hide()
if (tabName == "Summary") then
tabButton:SetTemplate("DETAILS_TAB_BUTTONSELECTED_TEMPLATE")
end
tabButton.IsDefaultTab = bIsDefaultTab
tabButton.condition = conditionFunc
tabButton.tabname = tabName
tabButton.localized_name = locName
tabButton.onclick = tabOnClickFunc
tabButton.fillfunction = fillFunc
tabButton.last_actor = {} --need to double check is this getting cleared
---@type tabframe
local tabFrame = CreateFrame("frame", breakdownWindow:GetName() .. "TabFrame" .. tabName .. math.random(1, 10000), breakdownWindow, "BackdropTemplate")
tabFrame:SetFrameLevel(breakdownWindow:GetFrameLevel()+1)
tabFrame:SetPoint("topleft", breakdownWindow, "topleft", 0, -70)
tabFrame:SetPoint("bottomright", breakdownWindow, "bottomright", -1, 20)
tabFrame:Hide()
DetailsFramework:ApplyStandardBackdrop(tabFrame)
tabFrame:SetBackdropBorderColor(0, 0, 0, 0.3)
tabFrame.__background:SetAlpha(0.3)
tabFrame.RightEdge:Hide()
--create the gradients in the top and bottom side of the breakdown window
local gradientStartColor = Details222.ColorScheme.GetColorFor("gradient-background")
local red, green, blue = unpack(gradientStartColor)
local gradientUpDown = detailsFramework:CreateTexture(tabFrame, {gradient = "vertical", fromColor = {red, green, blue, 0}, toColor = {red, green, blue, 0.4}}, 1, 34*2, "artwork", {0, 1, 0, 1})
gradientUpDown:SetPoint("topleft", tabFrame, "topleft", 0, 0)
gradientUpDown:SetPoint("topright", tabFrame, "topright", 0, 0)
tabButton.tabFrame = tabFrame
tabButton.frame = tabFrame
if (iconSettings) then
local texture = iconSettings.texture
local coords = iconSettings.coords
local width = iconSettings.width
local height = iconSettings.height
local overlay, textdistance, leftpadding, textheight, short_method --nil
tabButton:SetIcon(texture, width, height, "overlay", coords, overlay, textdistance, leftpadding, textheight, short_method)
if (iconSettings.desaturated) then
tabButton.icon:SetDesaturated(true)
end
end
if (tabButton.fillfunction) then
tabFrame:SetScript("OnShow", function()
---@type actor
local actorObject = Details:GetActorObjectFromBreakdownWindow()
if (tabButton.last_actor == actorObject) then
return
end
---@type instance
local instanceObject = Details:GetActiveWindowFromBreakdownWindow()
---@type combat
local combatObject = instanceObject:GetCombat()
tabButton.last_actor = actorObject --it's caching the actor, on pre-reset need to clean up this variable (need to check this later)
tabButton:fillfunction(actorObject, combatObject)
end)
end
if (onCreateFunc) then
onCreateFunc(tabButton, tabFrame)
end
tabButton.replaces = replace
Details.player_details_tabs[#Details.player_details_tabs+1] = tabButton
local onTabClickCallback = function(self) --self = tabButton
self = self.MyObject or self --framework button
for _, thisTabButton in ipairs(Details:GetBreakdownTabsInUse()) do
thisTabButton.frame:Hide()
thisTabButton:SetTemplate("DETAILS_TAB_BUTTON_TEMPLATE")
end
self:SetTemplate("DETAILS_TAB_BUTTONSELECTED_TEMPLATE")
breakdownWindow.selectedTab = self.tabname
end
if (not tabOnClickFunc) then
tabButton.OnShowFunc = function(self)
--hide all tab frames, reset the template on all tabs
--then set the template on this tab and set as selected tab
onTabClickCallback(self)
--show the tab frame
tabFrame:Show()
end
tabButton:SetScript("OnClick", tabButton.OnShowFunc)
else
--custom
tabButton.OnShowFunc = function(self)
--hide all tab frames, reset the template on all tabs
--then set the template on this tab and set as selected tab
onTabClickCallback(self)
--run onclick func
local result, errorText = pcall(tabOnClickFunc, tabButton, tabFrame)
if (not result) then
print("error on running tabOnClick function:", errorText)
end
end
tabButton:SetScript("OnClick", tabButton.OnShowFunc)
end
function tabButton:DoClick()
self:GetScript("OnClick")(self)
end
tabButton:SetScript("PostClick", function(self)
CurrentTab = self.tabname or self.MyObject.tabname
if (CurrentTab ~= "Summary") then
for _, widget in ipairs(SummaryWidgets) do
widget:Hide()
end
else
for _, widget in ipairs(SummaryWidgets) do
widget:Show()
end
end
end)
return tabButton, tabFrame
end
@@ -0,0 +1,294 @@
local Details = Details
local GameTooltip = GameTooltip
local unpack = unpack
local CreateFrame = CreateFrame
local GetSpellInfo = GetSpellInfo
local auras_tab_create = function(tab, frame)
local DF = DetailsFramework
local scroll_line_amount = 22
local scroll_width = 410
local scrollHeight = 445
local scroll_line_height = 19
local text_size = 10
local debuffScrollStartX = 445
local headerOffsetsBuffs = {
--buff label, uptime, applications, refreshes, wa
6, 190, 290, 336, 380
}
local headerOffsetsDebuffs = {
--debuff label, uptime, applications, refreshes, wa
426, 630, 729, 775, 820
}
local line_onenter = function(self)
GameTooltip:SetOwner(self, "ANCHOR_TOPRIGHT")
Details:GameTooltipSetSpellByID (self.spellID)
GameTooltip:Show()
self:SetBackdropColor(1, 1, 1, .2)
end
local line_onleave = function(self)
GameTooltip:Hide()
self:SetBackdropColor(unpack(self.BackgroundColor))
end
local line_onclick = function(self)
end
--buff scroll
--icon - name - applications - refreshes - uptime
--
--local wa_button = function(self, mouseButton, spellID, auraType)
-- local spellName, _, spellIcon = GetSpellInfo(spellID)
-- Details:OpenAuraPanel (spellID, spellName, spellIcon, nil, auraType == "BUFF" and 4 or 2, 1)
--end
local scroll_createline = function(self, index)
local line = CreateFrame("button", "$parentLine" .. index, self,"BackdropTemplate")
line:SetPoint("topleft", self, "topleft", 1, -((index-1)*(scroll_line_height+1)))
line:SetSize(scroll_width -2, scroll_line_height)
line:SetScript("OnEnter", line_onenter)
line:SetScript("OnLeave", line_onleave)
line:SetScript("OnClick", line_onclick)
line:SetBackdrop({bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
line:SetBackdropColor(0, 0, 0, 0.2)
local icon = line:CreateTexture("$parentIcon", "overlay")
icon:SetSize(scroll_line_height -2 , scroll_line_height - 2)
local name = line:CreateFontString("$parentName", "overlay", "GameFontNormal")
local uptime = line:CreateFontString("$parentName", "overlay", "GameFontNormal")
local apply = line:CreateFontString("$parentName", "overlay", "GameFontNormal")
local refresh = line:CreateFontString("$parentName", "overlay", "GameFontNormal")
--local waButton = DF:CreateButton(line, wa_button, 18, 18)
--waButton:SetIcon ([[Interface\AddOns\WeakAuras\Media\Textures\icon]])
DF:SetFontSize(name, text_size)
DF:SetFontSize(uptime, text_size)
DF:SetFontSize(apply, text_size)
DF:SetFontSize(refresh, text_size)
icon:SetPoint("left", line, "left", 2, 0)
name:SetPoint("left", icon, "right", 2, 0)
uptime:SetPoint("left", line, "left", 186, 0)
apply:SetPoint("left", line, "left", 276, 0)
refresh:SetPoint("left", line, "left", 322, 0)
--waButton:SetPoint("left", line, "left", 372, 0)
line.Icon = icon
line.Name = name
line.Uptime = uptime
line.Apply = apply
line.Refresh = refresh
--line.WaButton = waButton
name:SetJustifyH("left")
uptime:SetJustifyH("left")
apply:SetJustifyH("center")
refresh:SetJustifyH("center")
apply:SetWidth(26)
refresh:SetWidth(26)
return line
end
local line_bg_color = {{1, 1, 1, .1}, {1, 1, 1, 0}}
local scroll_buff_refresh = function(self, data, offset, total_lines)
local haveWA = false --_G.WeakAuras
for i = 1, total_lines do
local index = i + offset
local aura = data [index]
if (aura) then
local line = self:GetLine (i)
line.spellID = aura.spellID
line.Icon:SetTexture(aura [1])
line.Icon:SetTexCoord(.1, .9, .1, .9)
line.Name:SetText(aura [2])
line.Uptime:SetText(DF:IntegerToTimer(aura [3]) .. " (|cFFBBAAAA" .. math.floor(aura [6]) .. "%|r)")
line.Apply:SetText(aura [4])
line.Refresh:SetText(aura [5])
--if (haveWA) then
-- line.WaButton:SetClickFunction(wa_button, aura.spellID, line.AuraType)
--else
-- line.WaButton:Disable()
--end
if (i%2 == 0) then
line:SetBackdropColor(unpack(line_bg_color [1]))
line.BackgroundColor = line_bg_color [1]
else
line:SetBackdropColor(unpack(line_bg_color [2]))
line.BackgroundColor = line_bg_color [2]
end
end
end
end
local create_titledesc_frame = function(anchorWidget, desc)
local f = CreateFrame("frame", nil, frame)
f:SetSize(40, 20)
f:SetPoint("center", anchorWidget, "center")
f:SetScript("OnEnter", function()
GameTooltip:SetOwner(f, "ANCHOR_TOPRIGHT")
GameTooltip:AddLine(desc)
GameTooltip:Show()
end)
f:SetScript("OnLeave", function()
GameTooltip:Hide()
end)
return f
end
local buffLabel = DF:CreateLabel(frame, "Buff Name")
buffLabel:SetPoint(headerOffsetsBuffs[1], -10)
local uptimeLabel = DF:CreateLabel(frame, "Uptime")
uptimeLabel:SetPoint(headerOffsetsBuffs[2], -10)
local appliedLabel = DF:CreateLabel(frame, "A")
appliedLabel:SetPoint(headerOffsetsBuffs[3], -10)
create_titledesc_frame (appliedLabel.widget, "applications")
local refreshedLabel = DF:CreateLabel(frame, "R")
refreshedLabel:SetPoint(headerOffsetsBuffs[4], -10)
create_titledesc_frame (refreshedLabel.widget, "refreshes")
--local waLabel = DF:CreateLabel(frame, "WA")
--waLabel:SetPoint(headerOffsetsBuffs[5], -10)
--create_titledesc_frame (waLabel.widget, "create weak aura")
local buffScroll = DF:CreateScrollBox (frame, "$parentBuffUptimeScroll", scroll_buff_refresh, {}, scroll_width, scrollHeight, scroll_line_amount, scroll_line_height)
buffScroll:SetPoint("topleft", frame, "topleft", 5, -30)
for i = 1, scroll_line_amount do
local line = buffScroll:CreateLine (scroll_createline)
line.AuraType = "BUFF"
end
DF:ReskinSlider(buffScroll)
tab.BuffScroll = buffScroll
--debuff scroll
--icon - name - applications - refreshes - uptime
--
local debuffLabel = DF:CreateLabel(frame, "Debuff Name")
debuffLabel:SetPoint(headerOffsetsDebuffs[1], -10)
local uptimeLabel2 = DF:CreateLabel(frame, "Uptime")
uptimeLabel2:SetPoint(headerOffsetsDebuffs[2], -10)
local appliedLabel2 = DF:CreateLabel(frame, "A")
appliedLabel2:SetPoint(headerOffsetsDebuffs[3], -10)
create_titledesc_frame (appliedLabel2.widget, "applications")
local refreshedLabel2 = DF:CreateLabel(frame, "R")
refreshedLabel2:SetPoint(headerOffsetsDebuffs[4], -10)
create_titledesc_frame (refreshedLabel2.widget, "refreshes")
--local waLabel2 = DF:CreateLabel(frame, "WA")
--waLabel2:SetPoint(headerOffsetsDebuffs[5], -10)
--create_titledesc_frame (waLabel2.widget, "create weak aura")
local debuffScroll = DF:CreateScrollBox (frame, "$parentDebuffUptimeScroll", scroll_buff_refresh, {}, scroll_width, scrollHeight, scroll_line_amount, scroll_line_height)
debuffScroll:SetPoint("topleft", frame, "topleft", debuffScrollStartX, -30)
for i = 1, scroll_line_amount do
local line = debuffScroll:CreateLine (scroll_createline)
line.AuraType = "DEBUFF"
end
DF:ReskinSlider(debuffScroll)
tab.DebuffScroll = debuffScroll
if (not frame.__background) then
DetailsFramework:ApplyStandardBackdrop(frame)
frame.__background:SetAlpha(0.6)
end
end
local auras_tab_fill = function(tab, player, combat)
---@type actor
local miscActor = combat:GetActor(4, player:name())
---@type number
local combatTime = combat:GetCombatTime()
if (miscActor) then
do --buffs
local newAuraTable = {}
local spellContainer = miscActor:GetSpellContainer("buff")
if (spellContainer) then
for spellId, spellTable in spellContainer:ListSpells() do
local spellName, _, spellIcon = GetSpellInfo(spellId)
if (not spellTable.uptime) then
--print(_GetSpellInfo(spellID))
--dumpt(spellObject)
end
local uptime = spellTable.uptime or 0
table.insert(newAuraTable, {spellIcon, spellName, uptime, spellTable.appliedamt, spellTable.refreshamt, uptime / combatTime * 100, spellID = spellId})
end
end
table.sort(newAuraTable, Details.Sort3)
tab.BuffScroll:SetData(newAuraTable)
tab.BuffScroll:Refresh()
end
do --debuffs
local newAuraTable = {}
local spellContainer = miscActor:GetSpellContainer("debuff")
if (spellContainer) then
for spellId, spellTable in spellContainer:ListSpells() do
local spellName, _, spellIcon = GetSpellInfo(spellId)
table.insert(newAuraTable, {spellIcon, spellName, spellTable.uptime, spellTable.appliedamt, spellTable.refreshamt, spellTable.uptime / combatTime * 100, spellID = spellId})
end
end
table.sort(newAuraTable, Details.Sort3)
tab.DebuffScroll:SetData(newAuraTable)
tab.DebuffScroll:Refresh()
end
end
end
local iconTableAuras = {
texture = [[Interface\AddOns\Details\images\icons]],
coords = {257/512, 278/512, 0/512, 19/512},
width = 16,
height = 16,
}
function Details:InitializeAurasTab()
--check if the tab is already created
for i = 1, #Details.player_details_tabs do
local tabButton = Details.player_details_tabs[i]
if (tabButton.tabname == "Auras") then
return
end
end
Details:CreatePlayerDetailsTab("Auras", --[1] tab name
"Auras", --[2] localized name
function(tabOBject, playerObject) --[3] condition
return true
end,
auras_tab_fill, --[4] fill function
nil, --[5] onclick
auras_tab_create, --[6] oncreate
iconTableAuras --icon table
)
end
@@ -0,0 +1,715 @@
local Details = Details
local unpack = unpack
local _GetSpellInfo = Details.GetSpellInfo
local PLAYER_DETAILS_STATUSBAR_HEIGHT = 20
local CreateFrame = CreateFrame
local GameTooltip = GameTooltip
local Loc = LibStub("AceLocale-3.0"):GetLocale ( "Details" )
local red = "FFFFAAAA"
local green = "FFAAFFAA"
local avoidance_create = function(tab, frame)
--Percent Desc
local percent_desc = frame:CreateFontString(nil, "artwork", "GameFontNormal")
percent_desc:SetText("Percent values are comparisons with the previous try.")
percent_desc:SetPoint("bottomleft", frame, "bottomleft", 13, 13 + PLAYER_DETAILS_STATUSBAR_HEIGHT)
percent_desc:SetTextColor(.5, .5, .5, 1)
--SUMMARY
local summaryBox = CreateFrame("frame", nil, frame, "BackdropTemplate")
Details.gump:ApplyStandardBackdrop(summaryBox)
summaryBox:SetPoint("topleft", frame, "topleft", 10, -15)
summaryBox:SetSize(200, 160)
local y = -5
local padding = 16
local summary_text = summaryBox:CreateFontString(nil, "artwork", "GameFontNormal")
summary_text:SetText("Summary")
summary_text :SetPoint("topleft", summaryBox, "topleft", 5, y)
y = y - padding
--total damage received
local damagereceived = summaryBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
damagereceived:SetPoint("topleft", summaryBox, "topleft", 15, y)
damagereceived:SetText("Total Damage Taken:") --localize-me
damagereceived:SetTextColor(.8, .8, .8, 1)
local damagereceived_amt = summaryBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
damagereceived_amt:SetPoint("left", damagereceived, "right", 2, 0)
damagereceived_amt:SetText("0")
tab.damagereceived = damagereceived_amt
y = y - padding
--per second
local damagepersecond = summaryBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
damagepersecond:SetPoint("topleft", summaryBox, "topleft", 20, y)
damagepersecond:SetText("Per Second:") --localize-me
local damagepersecond_amt = summaryBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
damagepersecond_amt:SetPoint("left", damagepersecond, "right", 2, 0)
damagepersecond_amt:SetText("0")
tab.damagepersecond = damagepersecond_amt
y = y - padding
--total absorbs
local absorbstotal = summaryBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
absorbstotal:SetPoint("topleft", summaryBox, "topleft", 15, y)
absorbstotal:SetText("Total Absorbs:") --localize-me
absorbstotal:SetTextColor(.8, .8, .8, 1)
local absorbstotal_amt = summaryBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
absorbstotal_amt:SetPoint("left", absorbstotal, "right", 2, 0)
absorbstotal_amt:SetText("0")
tab.absorbstotal = absorbstotal_amt
y = y - padding
--per second
local absorbstotalpersecond = summaryBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
absorbstotalpersecond:SetPoint("topleft", summaryBox, "topleft", 20, y)
absorbstotalpersecond:SetText("Per Second:") --localize-me
local absorbstotalpersecond_amt = summaryBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
absorbstotalpersecond_amt:SetPoint("left", absorbstotalpersecond, "right", 2, 0)
absorbstotalpersecond_amt:SetText("0")
tab.absorbstotalpersecond = absorbstotalpersecond_amt
--MELEE
y = -5
local meleeBox = CreateFrame("frame", nil, frame, "BackdropTemplate")
Details.gump:ApplyStandardBackdrop(meleeBox)
meleeBox:SetPoint("topleft", summaryBox, "bottomleft", 0, -5)
meleeBox:SetSize(200, 160)
local melee_text = meleeBox:CreateFontString(nil, "artwork", "GameFontNormal")
melee_text:SetText("Melee")
melee_text :SetPoint("topleft", meleeBox, "topleft", 5, y)
y = y - padding
--dodge
local dodge = meleeBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
dodge:SetPoint("topleft", meleeBox, "topleft", 15, y)
dodge:SetText("Dodge:") --localize-me
dodge:SetTextColor(.8, .8, .8, 1)
local dodge_amt = meleeBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
dodge_amt:SetPoint("left", dodge, "right", 2, 0)
dodge_amt:SetText("0")
tab.dodge = dodge_amt
y = y - padding
local dodgepersecond = meleeBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
dodgepersecond:SetPoint("topleft", meleeBox, "topleft", 20, y)
dodgepersecond:SetText("Per Second:") --localize-me
local dodgepersecond_amt = meleeBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
dodgepersecond_amt:SetPoint("left", dodgepersecond, "right", 2, 0)
dodgepersecond_amt:SetText("0")
tab.dodgepersecond = dodgepersecond_amt
y = y - padding
-- parry
local parry = meleeBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
parry:SetPoint("topleft", meleeBox, "topleft", 15, y)
parry:SetText("Parry:") --localize-me
parry:SetTextColor(.8, .8, .8, 1)
local parry_amt = meleeBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
parry_amt:SetPoint("left", parry, "right", 2, 0)
parry_amt:SetText("0")
tab.parry = parry_amt
y = y - padding
local parrypersecond = meleeBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
parrypersecond:SetPoint("topleft", meleeBox, "topleft", 20, y)
parrypersecond:SetText("Per Second:") --localize-me
local parrypersecond_amt = meleeBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
parrypersecond_amt:SetPoint("left", parrypersecond, "right", 2, 0)
parrypersecond_amt:SetText("0")
tab.parrypersecond = parrypersecond_amt
y = y - padding
-- block
local block = meleeBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
block:SetPoint("topleft", meleeBox, "topleft", 15, y)
block:SetText("Block:") --localize-me
block:SetTextColor(.8, .8, .8, 1)
local block_amt = meleeBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
block_amt:SetPoint("left", block, "right", 2, 0)
block_amt:SetText("0")
tab.block = block_amt
y = y - padding
local blockpersecond = meleeBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
blockpersecond:SetPoint("topleft", meleeBox, "topleft", 20, y)
blockpersecond:SetText("Per Second:") --localize-me
local blockpersecond_amt = meleeBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
blockpersecond_amt:SetPoint("left", blockpersecond, "right", 2, 0)
blockpersecond_amt:SetText("0")
tab.blockpersecond = blockpersecond_amt
y = y - padding
local blockeddamage = meleeBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
blockeddamage:SetPoint("topleft", meleeBox, "topleft", 20, y)
blockeddamage:SetText("Damage Blocked:") --localize-me
local blockeddamage_amt = meleeBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
blockeddamage_amt:SetPoint("left", blockeddamage, "right", 2, 0)
blockeddamage_amt:SetText("0")
tab.blockeddamage_amt = blockeddamage_amt
--ABSORBS
y = -5
local absorbsBox = CreateFrame("frame", nil, frame, "BackdropTemplate")
Details.gump:ApplyStandardBackdrop(absorbsBox)
absorbsBox:SetPoint("topleft", summaryBox, "topright", 10, 0)
absorbsBox:SetSize(200, 160)
local absorb_text = absorbsBox:CreateFontString(nil, "artwork", "GameFontNormal")
absorb_text:SetText("Absorb")
absorb_text :SetPoint("topleft", absorbsBox, "topleft", 5, y)
y = y - padding
--full absorbs
local fullsbsorbed = absorbsBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
fullsbsorbed:SetPoint("topleft", absorbsBox, "topleft", 20, y)
fullsbsorbed:SetText("Full Absorbs:") --localize-me
fullsbsorbed:SetTextColor(.8, .8, .8, 1)
local fullsbsorbed_amt = absorbsBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
fullsbsorbed_amt:SetPoint("left", fullsbsorbed, "right", 2, 0)
fullsbsorbed_amt:SetText("0")
tab.fullsbsorbed = fullsbsorbed_amt
y = y - padding
--partially absorbs
local partiallyabsorbed = absorbsBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
partiallyabsorbed:SetPoint("topleft", absorbsBox, "topleft", 20, y)
partiallyabsorbed:SetText("Partially Absorbed:") --localize-me
partiallyabsorbed:SetTextColor(.8, .8, .8, 1)
local partiallyabsorbed_amt = absorbsBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
partiallyabsorbed_amt:SetPoint("left", partiallyabsorbed, "right", 2, 0)
partiallyabsorbed_amt:SetText("0")
tab.partiallyabsorbed = partiallyabsorbed_amt
y = y - padding
--partially absorbs per second
local partiallyabsorbedpersecond = absorbsBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
partiallyabsorbedpersecond:SetPoint("topleft", absorbsBox, "topleft", 25, y)
partiallyabsorbedpersecond:SetText("Average:") --localize-me
local partiallyabsorbedpersecond_amt = absorbsBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
partiallyabsorbedpersecond_amt:SetPoint("left", partiallyabsorbedpersecond, "right", 2, 0)
partiallyabsorbedpersecond_amt:SetText("0")
tab.partiallyabsorbedpersecond = partiallyabsorbedpersecond_amt
y = y - padding
--no absorbs
local noabsorbs = absorbsBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
noabsorbs:SetPoint("topleft", absorbsBox, "topleft", 20, y)
noabsorbs:SetText("No Absorption:") --localize-me
noabsorbs:SetTextColor(.8, .8, .8, 1)
local noabsorbs_amt = absorbsBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
noabsorbs_amt:SetPoint("left", noabsorbs, "right", 2, 0)
noabsorbs_amt:SetText("0")
tab.noabsorbs = noabsorbs_amt
--HEALING
y = -5
local healingBox = CreateFrame("frame", nil, frame,"BackdropTemplate")
Details.gump:ApplyStandardBackdrop(healingBox)
healingBox:SetPoint("topleft", absorbsBox, "bottomleft", 0, -5)
healingBox:SetSize(200, 160)
local healing_text = healingBox:CreateFontString(nil, "artwork", "GameFontNormal")
healing_text:SetText("Healing")
healing_text :SetPoint("topleft", healingBox, "topleft", 5, y)
y = y - padding
--self healing
local selfhealing = healingBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
selfhealing:SetPoint("topleft", healingBox, "topleft", 20, y)
selfhealing:SetText("Self Healing:") --localize-me
selfhealing:SetTextColor(.8, .8, .8, 1)
local selfhealing_amt = healingBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
selfhealing_amt:SetPoint("left", selfhealing, "right", 2, 0)
selfhealing_amt:SetText("0")
tab.selfhealing = selfhealing_amt
y = y - padding
--self healing per second
local selfhealingpersecond = healingBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
selfhealingpersecond:SetPoint("topleft", healingBox, "topleft", 25, y)
selfhealingpersecond:SetText("Per Second:") --localize-me
local selfhealingpersecond_amt = healingBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
selfhealingpersecond_amt:SetPoint("left", selfhealingpersecond, "right", 2, 0)
selfhealingpersecond_amt:SetText("0")
tab.selfhealingpersecond = selfhealingpersecond_amt
y = y - padding
for i = 1, 5 do
local healer = healingBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
healer:SetPoint("topleft", healingBox, "topleft", 20, y + ((i-1)*15)*-1)
healer:SetText("healer name:") --localize-me
healer:SetTextColor(.8, .8, .8, 1)
local healer_amt = healingBox:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
healer_amt:SetPoint("left", healer, "right", 2, 0)
healer_amt:SetText("0")
tab ["healer" .. i] = {healer, healer_amt}
end
--SPELLS
y = -5
local spellsBox = CreateFrame("frame", nil, frame,"BackdropTemplate")
Details.gump:ApplyStandardBackdrop(spellsBox)
spellsBox:SetPoint("topleft", absorbsBox, "topright", 10, 0)
spellsBox:SetSize(346, 160 * 2 + 5)
local spells_text = spellsBox:CreateFontString(nil, "artwork", "GameFontNormal")
spells_text:SetText("Spells")
spells_text :SetPoint("topleft", spellsBox, "topleft", 5, y)
local frame_tooltip_onenter = function(self)
if (self.spellid) then
--self:SetBackdrop({bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", tile = true, tileSize = 512, edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border", edgeSize = 8})
self:SetBackdropColor(.5, .5, .5, .5)
GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT")
Details:GameTooltipSetSpellByID (self.spellid)
GameTooltip:Show()
end
end
local frame_tooltip_onleave = function(self)
if (self.spellid) then
self:SetBackdropColor(.5, .5, .5, .1)
GameTooltip:Hide()
end
end
y = y - padding
for i = 1, 40 do
local frame_tooltip = CreateFrame("frame", nil, spellsBox,"BackdropTemplate")
frame_tooltip:SetPoint("topleft", spellsBox, "topleft", 5, y + ((i-1)*17)*-1)
frame_tooltip:SetSize(spellsBox:GetWidth()-10, 16)
frame_tooltip:SetScript("OnEnter", frame_tooltip_onenter)
frame_tooltip:SetScript("OnLeave", frame_tooltip_onleave)
frame_tooltip:Hide()
frame_tooltip:SetBackdrop({bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", tile = true, tileSize = 512})
frame_tooltip:SetBackdropColor(.5, .5, .5, .1)
local icon = frame_tooltip:CreateTexture(nil, "artwork")
icon:SetSize(14, 14)
icon:SetPoint("left", frame_tooltip, "left")
local spell = frame_tooltip:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
spell:SetPoint("left", icon, "right", 2, 0)
spell:SetText("spell name:") --localize-me
spell:SetTextColor(.8, .8, .8, 1)
local spell_amt = frame_tooltip:CreateFontString(nil, "artwork", "GameFontHighlightSmall")
spell_amt:SetPoint("left", spell, "right", 2, 0)
spell_amt:SetText("0")
tab ["spell" .. i] = {spell, spell_amt, icon, frame_tooltip}
end
end
local getpercent = function(value, lastvalue, elapsed_time, inverse)
local ps = value / elapsed_time
local diff
if (lastvalue == 0) then
diff = "+0%"
else
if (ps >= lastvalue) then
local d = ps - lastvalue
d = d / lastvalue * 100
d = math.floor(math.abs(d))
if (d > 999) then
d = "> 999"
end
if (inverse) then
diff = "|c" .. green .. "+" .. d .. "%|r"
else
diff = "|c" .. red .. "+" .. d .. "%|r"
end
else
local d = lastvalue - ps
d = d / math.max(ps, 0.001) * 100
d = math.floor(math.abs(d))
if (d > 999) then
d = "> 999"
end
if (inverse) then
diff = "|c" .. red .. "-" .. d .. "%|r"
else
diff = "|c" .. green .. "-" .. d .. "%|r"
end
end
end
return ps, diff
end
local avoidance_fill = function(tab, player, combat)
local elapsed_time = combat:GetCombatTime()
local last_combat = combat.previous_combat --this is always nil from 2023 may 26
if (not last_combat or not last_combat [1]) then
last_combat = combat
end
local last_actor = last_combat (1, player.nome)
local n = player.nome
if (n:find("-")) then
n = n:gsub(("-.*"), "")
end
--damage taken
local playerdamage = combat (1, player.nome)
if (not playerdamage.avoidance) then
playerdamage.avoidance = Details:CreateActorAvoidanceTable()
end
local damagetaken = playerdamage.damage_taken
local last_damage_received = 0
if (last_actor) then
last_damage_received = last_actor.damage_taken / last_combat:GetCombatTime()
end
tab.damagereceived:SetText(Details:ToK2 (damagetaken))
local ps, diff = getpercent (damagetaken, last_damage_received, elapsed_time)
tab.damagepersecond:SetText(Details:comma_value (math.floor(ps)) .. " (" .. diff .. ")")
--absorbs
local totalabsorbs = playerdamage.avoidance.overall.ABSORB_AMT
local incomingtotal = damagetaken + totalabsorbs
local last_total_absorbs = 0
if (last_actor and last_actor.avoidance) then
last_total_absorbs = last_actor.avoidance.overall.ABSORB_AMT / last_combat:GetCombatTime()
end
tab.absorbstotal:SetText(Details:ToK2 (totalabsorbs) .. " (" .. math.floor(totalabsorbs / incomingtotal * 100) .. "%)")
local ps, diff = getpercent (totalabsorbs, last_total_absorbs, elapsed_time, true)
tab.absorbstotalpersecond:SetText(Details:comma_value (math.floor(ps)) .. " (" .. diff .. ")")
--dodge
local totaldodge = playerdamage.avoidance.overall.DODGE
tab.dodge:SetText(totaldodge)
local last_total_dodge = 0
if (last_actor and last_actor.avoidance) then
last_total_dodge = last_actor.avoidance.overall.DODGE / last_combat:GetCombatTime()
end
local ps, diff = getpercent (totaldodge, last_total_dodge, elapsed_time, true)
tab.dodgepersecond:SetText( string.format("%.2f", ps) .. " (" .. diff .. ")")
--parry
local totalparry = playerdamage.avoidance.overall.PARRY
tab.parry:SetText(totalparry)
local last_total_parry = 0
if (last_actor and last_actor.avoidance) then
last_total_parry = last_actor.avoidance.overall.PARRY / last_combat:GetCombatTime()
end
local ps, diff = getpercent (totalparry, last_total_parry, elapsed_time, true)
tab.parrypersecond:SetText(string.format("%.2f", ps) .. " (" .. diff .. ")")
--block
local totalblock = playerdamage.avoidance.overall.BLOCKED_HITS
tab.block:SetText(totalblock)
local last_total_block = 0
if (last_actor and last_actor.avoidance) then
last_total_block = last_actor.avoidance.overall.BLOCKED_HITS / last_combat:GetCombatTime()
end
local ps, diff = getpercent (totalblock, last_total_block, elapsed_time, true)
tab.blockpersecond:SetText(string.format("%.2f", ps) .. " (" .. diff .. ")")
tab.blockeddamage_amt:SetText(Details:ToK2 (playerdamage.avoidance.overall.BLOCKED_AMT))
--absorb
local fullabsorb = playerdamage.avoidance.overall.FULL_ABSORBED
local halfabsorb = playerdamage.avoidance.overall.PARTIAL_ABSORBED
local halfabsorb_amt = playerdamage.avoidance.overall.PARTIAL_ABSORB_AMT
local noabsorb = playerdamage.avoidance.overall.FULL_HIT
tab.fullsbsorbed:SetText(fullabsorb)
tab.partiallyabsorbed:SetText(halfabsorb)
tab.noabsorbs:SetText(noabsorb)
if (halfabsorb_amt > 0) then
local average = halfabsorb_amt / halfabsorb --tenho o average
local last_average = 0
if (last_actor and last_actor.avoidance and last_actor.avoidance.overall.PARTIAL_ABSORBED > 0) then
last_average = last_actor.avoidance.overall.PARTIAL_ABSORB_AMT / last_actor.avoidance.overall.PARTIAL_ABSORBED
end
local ps, diff = getpercent (halfabsorb_amt, last_average, halfabsorb, true)
tab.partiallyabsorbedpersecond:SetText(Details:comma_value (math.floor(ps)) .. " (" .. diff .. ")")
else
tab.partiallyabsorbedpersecond:SetText("0.00 (0%)")
end
--healing
local actor_heal = combat (2, player.nome)
if (not actor_heal) then
tab.selfhealing:SetText("0")
tab.selfhealingpersecond:SetText("0 (0%)")
else
local last_actor_heal = last_combat (2, player.nome)
local este_alvo = actor_heal.targets [player.nome]
if (este_alvo) then
local heal_total = este_alvo
tab.selfhealing:SetText(Details:ToK2 (heal_total))
if (last_actor_heal) then
local este_alvo = last_actor_heal.targets [player.nome]
if (este_alvo) then
local heal = este_alvo
local last_heal = heal / last_combat:GetCombatTime()
local ps, diff = getpercent (heal_total, last_heal, elapsed_time, true)
tab.selfhealingpersecond:SetText(Details:comma_value (math.floor(ps)) .. " (" .. diff .. ")")
else
tab.selfhealingpersecond:SetText("0 (0%)")
end
else
tab.selfhealingpersecond:SetText("0 (0%)")
end
else
tab.selfhealing:SetText("0")
tab.selfhealingpersecond:SetText("0 (0%)")
end
-- taken from healer
local heal_from = actor_heal.healing_from
local myReceivedHeal = {}
for actorName, _ in pairs(heal_from) do
local thisActor = combat (2, actorName)
local targets = thisActor.targets --targets is a container with target classes
local amount = targets [player.nome] or 0
myReceivedHeal [#myReceivedHeal+1] = {actorName, amount, thisActor.classe}
end
table.sort (myReceivedHeal, Details.Sort2) --Sort2 sort by second index
for i = 1, 5 do
local label1, label2 = unpack(tab ["healer" .. i])
if (myReceivedHeal [i]) then
local name = myReceivedHeal [i][1]
name = Details:GetOnlyName(name)
--name = Details:RemoveOwnerName (name)
label1:SetText(name .. ":")
local class = myReceivedHeal [i][3]
if (class) then
local c = _G["RAID_CLASS_COLORS"][class]
if (c) then
label1:SetTextColor(c.r, c.g, c.b)
end
else
label1:SetTextColor(.8, .8, .8, 1)
end
local last_actor = last_combat (2, myReceivedHeal [i][1])
if (last_actor) then
local targets = last_actor.targets
local amount = targets [player.nome] or 0
if (amount) then
local last_heal = amount
local ps, diff = getpercent (myReceivedHeal[i][2], last_heal, 1, true)
label2:SetText( Details:ToK2 (myReceivedHeal[i][2] or 0) .. " (" .. diff .. ")")
else
label2:SetText( Details:ToK2 (myReceivedHeal[i][2] or 0))
end
else
label2:SetText( Details:ToK2 (myReceivedHeal[i][2] or 0))
end
else
label1:SetText("-- -- -- --")
label1:SetTextColor(.8, .8, .8, 1)
label2:SetText("")
end
end
end
--Spells
--cooldowns
local index_used = 1
local misc_player = combat (4, player.nome)
local encounter_time = combat:GetCombatTime()
if (misc_player) then
if (misc_player.cooldowns_defensive_spells) then
local minha_tabela = misc_player.cooldowns_defensive_spells._ActorTable
local buffUpdateSpells = misc_player.buff_uptime_spells -- ._ActorTable
local cooldowns_usados = {}
for _spellid, _tabela in pairs(minha_tabela) do
cooldowns_usados [#cooldowns_usados+1] = {_spellid, _tabela.counter}
end
if (#cooldowns_usados > 0) then
table.sort (cooldowns_usados, Details.Sort2)
for i = 1, #cooldowns_usados do
local esta_habilidade = cooldowns_usados[i]
local nome_magia, _, icone_magia = _GetSpellInfo(esta_habilidade[1])
local label1, label2, icon1, framebg = unpack(tab ["spell" .. index_used])
framebg.spellid = esta_habilidade[1]
framebg:Show()
--attempt to get the buff update
local spellInfo = buffUpdateSpells:GetSpell (framebg.spellid)
if (spellInfo) then
label2:SetText(esta_habilidade[2] .. " (" .. math.floor(spellInfo.uptime / encounter_time * 100) .. "% uptime)")
else
label2:SetText(esta_habilidade[2])
end
--update the line
label1:SetText(nome_magia .. ":")
icon1:SetTexture(icone_magia)
icon1:SetTexCoord(0.0625, 0.953125, 0.0625, 0.953125)
index_used = index_used + 1
end
end
end
end
local cooldownInfo = DetailsFramework.CooldownsInfo
--see cooldowns that other players used in this actor
for playerName, _ in pairs(combat.raid_roster) do
if (playerName ~= player.nome) then
local miscPlayer = combat (4, playerName)
if (miscPlayer) then
if (miscPlayer.cooldowns_defensive_spells) then
local cooldowns = miscPlayer.cooldowns_defensive_spells
for spellID, spellTable in cooldowns:ListActors() do
local targets = spellTable.targets
if (targets) then
for targetName, amountCasted in pairs(targets) do
if (targetName == player.nome) then
local spellName, _, spellIcon = _GetSpellInfo(spellID)
local label1, label2, icon1, framebg = unpack(tab ["spell" .. index_used])
framebg.spellid = spellID
framebg:Show()
--attempt to get the buff update
local info = cooldownInfo [spellID]
local cooldownDuration = info and info.duration or 0
if (cooldownDuration > 0) then
label2:SetText(amountCasted .. " (" .. "|cFFFFFF00" .. miscPlayer.nome .. "|r " .. math.floor(cooldownDuration / encounter_time * 100) .. "% uptime)")
else
label2:SetText(amountCasted)
end
--update the line
label1:SetText(spellName .. ":")
icon1:SetTexture(spellIcon)
icon1:SetTexCoord(0.0625, 0.953125, 0.0625, 0.953125)
index_used = index_used + 1
end
end
end
end
end
end
end
end
for i = index_used, 40 do
local label1, label2, icon1, framebg = unpack(tab ["spell" .. i])
framebg.spellid = nil
framebg:Hide()
label1:SetText("")
label2:SetText("")
icon1:SetTexture("")
end
--habilidade usada para interromper
end
local iconTableAvoidance = {
texture = [[Interface\AddOns\Details\images\icons]],
--coords = {363/512, 381/512, 0/512, 17/512},
coords = {384/512, 402/512, 19/512, 38/512},
width = 16,
height = 16,
}
Details:CreatePlayerDetailsTab ("Avoidance", --[1] tab name
Loc ["STRING_INFO_TAB_AVOIDANCE"], --[2] localized name
function(tabOBject, playerObject) --[3] condition
if (playerObject.isTank) then
return true
else
return false
end
end,
avoidance_fill, --[4] fill function
nil, --[5] onclick
avoidance_create, --[6] oncreate
iconTableAvoidance --[7] icon
)
@@ -0,0 +1,523 @@
--whenever it say 'CombatID' it is referencing the Details! unique combatId
--whenever it say 'SegmentID' it is referencing the internal chart data registered for some details! combat
local Details = _G.Details
local detailsFramework = _G.DetailsFramework
local addonName, detailsInternal = ...
local CONST_LATEST_SEGMENT = 1
local tinsert = table.insert
local tremove = table.remove
local CONST_TICKER_NAME = "ChartDataTicker"
local CONST_TICKER_INTERVAL = 3
--create the chart object
detailsInternal.Charts = {}
local chartsObject = detailsInternal.Charts
--store all segments data
chartsObject.SegmentsData = {}
--current segment being displayed in the charts
chartsObject.SegmentOnVisualization = 0
--this table will hold the saved variable which tells which infomation to get during combat
chartsObject.DataToCapture = {}
function chartsObject.GetConfigToCaptureData()
return chartsObject.DataToCapture
end
function chartsObject.SetConfigToCaptureData(configTable)
chartsObject.DataToCapture = configTable
end
function chartsObject.GetSavedVariable()
return Details.data_harvested_for_charts
end
function chartsObject.StoreChartsForCurrentCombat()
local savedVariableTable = chartsObject.GetSavedVariable()
--Details.data_harvested_for_charts
end
function chartsObject.BuildPlayersTable(playersTable)
if (IsInRaid()) then
for i = 1, GetNumGroupMembers() do
local unitName = GetUnitName("raid" .. i, true)
playersTable[unitName] = {}
end
elseif (InIsParty()) then
for i = 1, GetNumGroupMembers() - 1 do
local unitName = GetUnitName("party" .. i, true)
playersTable[unitName] = {}
end
playersTable[UnitName("player")] = {}
else
playersTable[UnitName("player")] = {}
end
end
function chartsObject.CreateTableToReceiveChartData()
local t = {}
--get the list of players captures
local configsForCaptureData = chartsObject.GetConfigToCaptureData()
--data set to capture data of each individual player
local playerCaptures = configsForCaptureData.players
--data set to capture data of some combat attribute or totals
local combatTotalCaptures = configsForCaptureData.totals
if (#playerCaptures > 0) then
t.players = {}
for i = 1, #playerCaptures do
local capturePreset = playerCaptures[i]
local playersTable = {}
t.players[capturePreset.name] = playersTable
chartsObject.BuildPlayersTable(playersTable)
end
end
if (#combatTotalCaptures > 0) then
t.totals = {}
for i = 1, #combatTotalCaptures do
local capturePreset = combatTotalCaptures[i]
t.totals[capturePreset.name] = {}
end
end
return t
end
--function to grab data during combat
function chartsObject.Ticker()
if (chartsObject.HasValidAndOpenCombat()) then
--get Details! combat object
local detaisCurrentCombat = Details:GetCurrentCombat()
--get the list of players captures
local configsForCaptureData = chartsObject.GetConfigToCaptureData()
--data set to capture data of each individual player
local playerCaptures = configsForCaptureData.players
--data set to capture data of some combat attribute or totals
local combatTotalCaptures = configsForCaptureData.totals
local currentSegmentData = chartsObject.GetCurrentSegmentData()
local chartData = currentSegmentData.ChartData
if (#playerCaptures > 0) then
--PAREI AQUI, PRECISA PEGAR O CAPTURE NAME, A TABELA COM OS NOMES DOS JOGADORES E PEGAR OS DADOS DO SEGMENTO DO DETAILS!
--DEPOIS TEM QUE FECHAR ISSO AQUI E GRAGAR NO SEGMENT DA CHART
--DEPOIS FAZER O MENU DE SELECIONAR O SEGMENTO MOSTRAR OS SEGMENTOS DO DETAILS PARA SELECIONAR
--POR FIM PROGRAMAR AS CHARTS PRA MOSTRAR OS GRAFICOS
for i = 1, #playerCaptures do
local capturePreset = playerCaptures[i]
local thisCaptureTable = chartData[capturePreset.Name]
t.players[capturePreset.name] = playersTable
chartsObject.BuildPlayersTable(playersTable)
end
end
if (#combatTotalCaptures > 0) then
t.totals = {}
for i = 1, #combatTotalCaptures do
local capturePreset = combatTotalCaptures[i]
t.totals[capturePreset.name] = {}
end
end
for i = 1, #playerCaptures do
local capturePreset = playerCaptures[i]
if (capturePreset.combatObjectSubTable) then
local subTable = detaisCurrentCombat[capturePreset.combatObjectSubTableName]
local value = subTable[capturePreset.combatObjectSubTableKey]
end
end
end
end
--[=[]]
players = {
--damage done by each player
{
name = "Damage of Each Individual Player",
combatObjectContainer = 1,
playerOnly = true,
playerKey = "total",
},
--total damage done by the raid group
{
name = "Damage of All Player Combined",
combatObjectSubTableName = "totals",
combatObjectSubTableKey = 1,
},
},
--]=]
function chartsObject.GetConfigToDataCaptureFromDetailsOptions()
local detailsObject = Details
local configTable = detailsObject.data_harvest_for_charsts
chartsObject.SetConfigToCaptureData(configTable)
end
function chartsObject.StartCombatDataTicker()
detailsInternal.Scheduler.NewTicker(CONST_TICKER_INTERVAL, chartsObject.Ticker, CONST_TICKER_NAME)
end
function chartsObject.StopCombatDataTicker()
detailsInternal.Scheduler.Cancel(CONST_TICKER_NAME)
end
--get a segment combat data
function chartsObject.GetSegmentsCombatData(combatIndex)
return chartsObject.SegmentsData[combatIndex]
end
--get a segment combat data by Details! combatId
function chartsObject.GetSegmentCombatDataByDetailsCombatID(detailsCombatId)
for i = 1, chartsObject.GetNumSegments() do
local thisSegmentCombatData = chartsObject.SegmentsData[i]
if (thisSegmentCombatData.detailsCombatID == detailsCombatId) then
return thisSegmentCombatData
end
end
end
--select a combat to make the chart frames show
function chartsObject.SelectSegmentDataToShow(segmentId)
segmentId = segmentId or CONST_LATEST_SEGMENT
local numSegments = chartsObject.GetNumSegments()
if (numSegments > 0) then
--pre step before calling the function which will signal the frame to update
chartsObject.ChartFramesShowSegment(CONST_LATEST_SEGMENT)
else
chartsObject.ChartFramesClear()
end
end
function chartsObject.ChartFramesClear()
--pre step before calling the function which will signal the frame to update
chartsObject.ChartFramesShowSegment(0)
end
--this function shouldn't be called directly, always call from SelectSegmentDataToShow or ChartFramesClear
function chartsObject.ChartFramesShowSegment(segmentId)
--set the combat data into the charts
chartsObject.SegmentOnVisualization = segmentId
--here go into the frames created and call refresh using the segment data
local segmentCombatData = chartsObject.GetSegmentsCombatData(segmentId)
if (segmentCombatData) then
--this is the lowest function and will call the frame api to refresh the data
else
chartsObject.SegmentOnVisualization = 0
--this is the lowest function and will call the frame api to refresh the data
end
end
--called when Details! reset the data
function chartsObject.ResetSegmentData()
Details:Destroy(chartsObject.SegmentsData)
--stop the ticker
chartsObject.StopCombatDataTicker()
--don't allow anything to be process under the start of a new combat
chartsObject.SetCombatState(false)
--signal the frames to update and shown no data
chartsObject.ChartFramesClear()
end
--set the combat state
function chartsObject.SetCombatState(state)
chartsObject.InCombat = state
end
function chartsObject.HasValidAndOpenCombat()
local bCombatState = chartsObject.GetCombatState()
if (bCombatState) then
local detaisCurrentCombat = Details:GetCurrentCombat()
local chartCurrentSegmentData = chartsObject.GetCurrentSegmentData()
if (detaisCurrentCombat:GetCombatId() == chartCurrentSegmentData:GetCombatId()) then
--it's all good
return true
end
end
end
--return true if in combat
function chartsObject.GetCombatState()
return chartsObject.InCombat
end
function chartsObject.RemoveSegmentData(segmentId)
tremove(chartsObject.SegmentsData, segmentId)
chartsObject.SelectSegmentDataToShow(CONST_LATEST_SEGMENT)
end
function chartsObject.GetNumSegments()
return #chartsObject.SegmentsData
end
function chartsObject.GetCurrentSegmentData()
return chartsObject.segmentData
end
--add the new combatData into the first index
local segmentDataMixin = {
GetCombatId = function(self)
return self.detailsCombatID
end,
}
--this is called when the player enter in combat
function chartsObject.CreateNewSegmentData(detailsCombatObject)
chartsObject.segmentData = {
--players Damage for the segment
PlayersDamage = {},
--players Healing for the segment
PlayersHealing = {},
--each index is a boss fight
BossTryDamage = 0,
--blood lust timer
BloodLustTimers = {},
--combatId
detailsCombatID = detailsCombatObject:GetCombatId(),
--charts data captured
ChartData = chartsObject.CreateTableToReceiveChartData(),
}
detailsFramework:Mixin(chartsObject.segmentData, segmentDataMixin)
tinsert(chartsObject.SegmentsData, 1, chartsObject.segmentData)
chartsObject.GetConfigToDataCaptureFromDetailsOptions()
chartsObject.SetCombatState(true)
chartsObject.StartCombatDataTicker()
return chartsObject.segmentData
end
--when a combat is finished, close and store the current combatData
function chartsObject.CloseSegmentData(bIsInvalid)
--in case a combat_invalid passed by here first
if (not chartsObject.GetCombatState()) then
return
end
chartsObject.StopCombatDataTicker()
chartsObject.SetCombatState(false)
local currentCombat = chartsObject.GetSegmentsCombatData(1)
currentCombat.Done = true
if (bIsInvalid) then
currentCombat.Invalid = true
chartsObject.RemoveSegmentData(1)
else
--check if the window is opened and update the chart current in sight
end
end
--Details Events:
function chartsObject.OnDetailsEvent(event, ...)
if (event == "COMBAT_PLAYER_ENTER") then --> combat started
local combatObject = select(1, ...)
if (not combatObject and Details) then
combatObject = Details:GetCurrentCombat()
if (not combatObject) then
return
end
end
chartsObject.CreateNewSegmentData(combatObject)
elseif (event == "COMBAT_PLAYER_LEAVE") then
chartsObject.CloseSegmentData()
elseif (event == "DETAILS_DATA_RESET") then
chartsObject.ResetSegmentData()
elseif (event == "COMBAT_INVALID") then
local bIsInvalid = true
chartsObject.CloseSegmentData(bIsInvalid)
elseif (event == "DETAILS_STARTED") then
--install the new tab on the Player Breakdown
chartsObject.InstallTab()
end
end
local eventListener = Details:CreateEventListener()
eventListener:RegisterEvent("COMBAT_PLAYER_ENTER", chartsObject.OnDetailsEvent)
eventListener:RegisterEvent("COMBAT_PLAYER_LEAVE", chartsObject.OnDetailsEvent)
eventListener:RegisterEvent("DETAILS_DATA_RESET", chartsObject.OnDetailsEvent)
eventListener:RegisterEvent("COMBAT_INVALID", chartsObject.OnDetailsEvent)
eventListener:RegisterEvent("DETAILS_STARTED", chartsObject.OnDetailsEvent)
function chartsObject.InstallTab()
local tabName = "Charts"
local tabNameLoc = "Damage Charts"
local canShowTab = function(tabOBject, playerObject)
local combatObject = Details:GetCombatFromBreakdownWindow()
if (combatObject) then
local chartsCombatData = chartsObject.GetSegmentCombatDataByDetailsCombatID(combatObject:GetCombatId())
if (chartsCombatData) then
return true
end
end
return false
end
local fillTab = function(tab, playerObject, combat)
--update the tab frame with information
end
local createdChartsTab = function(tab, frame)
chartsObject.CreateChartFrames(tab, frame)
end
local iconSettings = {
texture = [[Interface\BUTTONS\UI-GuildButton-OfficerNote-Disabled]],
coords = {0, 1, 0, 1},
width = 16,
height = 16,
}
Details:CreatePlayerDetailsTab(tabName, tabNameLoc, canShowTab, fillTab, nil, createdChartsTab, iconSettings)
end
function chartsObject.CreateChartFrames(tab, tabFrame)
--First Option: each player dps chart on each segment, this show the evolution of damage of each player
--Second Option: Total Damage Done by the entire raid comparing with other segments (one line of raid damage per segment)
--Thrid Option: your damage compared with other of the same class (chart damage of each player required)
--Your habilites compared segment by segment (no chart data required)
--segment scroll in the left
--boss image, boss name,
--when selecting a boss show the chart for the boss
local defaultChartSections = {
{
Name = "Raid Damage",
ChartID = 1,
ChartData = "alldamagers-segment",
},
{
},
}
local scrollWidth = 200
local scrollHeight = 500
local scrollButtonHeight = 20
local amountScrollLines = floor(scrollHeight / scrollButtonHeight)
local allLinesCreated = {}
local lineSelectedBackdropColor = {.5, .5, .5, .5}
local onClickLine_SelectChartToView = function(button, mouseButton)
for buttonId, line in ipairs(allLinesCreated) do
line:SetDefaultBackdropColor()
end
end
local lineMixin = {
SetDefaultBackdropColor = function(line)
line.__background:SetVertexColor(unpack(line.defaultBackgroundColor))
end,
SetSelectedBackdropColor = function(line)
line.__background:SetVertexColor(unpack(lineSelectedBackdropColor))
end,
OnClickLine = function(line)
--select the chart to view
end,
}
--function to create a line in the scroll frame
local createScrollLine = function(self, index)
--create a new line
local line = CreateFrame("button", "$parentLine" .. index, self, "BackdropTemplate")
detailsFramework:Mixin(line, lineMixin)
--set its parameters
line:SetPoint("topleft", self, "topleft", 1, -((index-1) * (scrollButtonHeight+1)) - 1)
line:SetSize(scrollWidth-19, scrollButtonHeight)
line:RegisterForClicks("LeftButtonDown", "RightButtonDown")
line:SetScript("OnClick", line.OnClickLine)
detailsFramework:ApplyStandardBackdrop(line)
line.defaultBackgroundColor = {line.__background:GetVertexColor()}
local icon = line:CreateTexture("$parentSpecIcon", "artwork")
icon:SetSize(scrollButtonHeight, scrollButtonHeight)
icon:SetAlpha(0.71)
local chartData = defaultChartSections[index]
local chartName = detailsFramework:CreateLabel(line, chartData.Name, 11, "white", "GameFontNormal")
icon:SetPoint("left", line, "left", 0, 0)
chartName:SetPoint("topleft", icon, "topright", 2, -3)
line.Icon = icon
line.ChartName = chartName
return line
end
local refreshScroll = function(self, data, offset, totalLines)
for i = 1, totalLines do
local index = i + offset
local chartData = data[index]
if (chartData) then
local line = self:GetLine(i)
line.ChartID = chartData.ChartID
line.ChartData = chartData.ChartData
line.ChartName.text = chartData.Name
end
end
end
--Create the scrollbox showing the selection for charts
local chartSelectionScrollBox = detailsFramework:CreateScrollBox(
tabFrame,
"$parentChartSelectionScroll",
refreshScroll,
{},
scrollWidth,
scrollHeight,
amountScrollLines,
scrollButtonHeight
)
detailsFramework:ReskinSlider(chartSelectionScrollBox)
chartSelectionScrollBox.ScrollBar:ClearAllPoints()
chartSelectionScrollBox.ScrollBar:SetPoint("topright", chartSelectionScrollBox, "topright", -2, -17)
chartSelectionScrollBox.ScrollBar:SetPoint("bottomright", chartSelectionScrollBox, "bottomright", -2, 17)
chartSelectionScrollBox:SetPoint("topright", tabFrame, "topleft", -1, 0)
chartSelectionScrollBox:SetPoint("bottomright", tabFrame, "bottomleft", -1, 0)
detailsFramework:ApplyStandardBackdrop(chartSelectionScrollBox)
tabFrame.chartSelectionScrollBox = chartSelectionScrollBox
--create the scrollbox lines
for i = 1, amountScrollLines do
chartSelectionScrollBox:CreateLine(createScrollLine)
end
end
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,413 @@
local Details = _G.Details
local detailsFramework = _G.DetailsFramework
local openRaidLib = LibStub:GetLibrary("LibOpenRaid-1.0", true)
local addonName, Details222 = ...
local breakdownWindowPlayerList = {}
local unpack = table.unpack or unpack
local C_Timer = _G.C_Timer
local tinsert = _G.tinsert
local scrollbox_size = {215, 405}
local scrollbox_lines = 23
local player_line_height = 21.7
local scrollbox_line_backdrop_color = {0.2, 0.2, 0.2, 0.5}
local scrollbox_line_backdrop_color_selected = {.6, .6, .1, 0.7}
local scrollbox_line_backdrop_color_highlight = {.9, .9, .9, 0.5}
local player_scroll_size = {195, 288}
--header setup
local headerTable = {
{text = "", width = 20},
{text = "Player Name", width = 100},
{text = "iLvL", width = 30},
{text = "WCL Parse", width = 60},
}
local headerOptions = {
padding = 2,
}
function breakdownWindowPlayerList.CreatePlayerListFrame()
local f = _G.DetailsBreakdownWindow
local refreshScrollFunc = function(self, data, offset, totalLines)
--update the scroll
local topResult = data[1]
if (topResult) then
topResult = topResult.total
end
---@type combat
local combatObject = Details:GetCombatFromBreakdownWindow()
local encounterId = combatObject:GetEncounterCleuID()
local difficultyId = combatObject:GetDifficulty()
for i = 1, totalLines do --~refresh
local index = i + offset
local playerObject = data[index]
if (playerObject) then
local line = self:GetLine(i)
line.playerObject = playerObject
line.combatObject = combatObject
line.index = index
line:UpdateLine(topResult, encounterId, difficultyId)
end
end
end
local lineOnClick = function(self)
if (self.playerObject ~= Details:GetActorObjectFromBreakdownWindow()) then
Details:OpenBreakdownWindow(Details:GetActiveWindowFromBreakdownWindow(), self.playerObject)
f.playerScrollBox:Refresh()
end
end
local lineOnEnter = function(self)
self:SetBackdropColor(unpack(scrollbox_line_backdrop_color_highlight))
self.specIcon:SetBlendMode("ADD")
self.roleIcon:SetBlendMode("ADD")
end
local lineOnLeave = function(self)
if (self.isSelected) then
self:SetBackdropColor(unpack(scrollbox_line_backdrop_color_selected))
else
self:SetBackdropColor(unpack(scrollbox_line_backdrop_color))
end
self.specIcon:SetBlendMode("BLEND")
self.roleIcon:SetBlendMode("BLEND")
end
local updatePlayerLine = function(self, topResult, encounterId, difficultyId) --~update
local playerSelected = Details:GetActorObjectFromBreakdownWindow()
if (playerSelected and playerSelected == self.playerObject) then
self:SetBackdropColor(unpack(scrollbox_line_backdrop_color_selected))
self.isSelected = true
else
self:SetBackdropColor(unpack(scrollbox_line_backdrop_color))
self.isSelected = nil
end
local specRole
--adjust the player icon
if (self.playerObject.spellicon) then
self.specIcon:SetTexture(self.playerObject.spellicon)
self.specIcon:SetTexCoord(.1, .9, .1, .9)
else
local specIcon, L, R, T, B = Details:GetSpecIcon(self.playerObject.spec, false)
if (specIcon) then
self.specIcon:SetTexture(specIcon)
self.specIcon:SetTexCoord(L, R, T, B)
if (DetailsFramework.IsTimewalkWoW()) then
specRole = "NONE"
else
---@type number
local spec = self.playerObject.spec
if (spec) then
specRole = select(5, _G.GetSpecializationInfoByID(self.playerObject.spec))
end
end
else
self.specIcon:SetTexture("")
end
end
--adjust the role icon
if (specRole) then
local roleIcon, L, R, T, B = Details:GetRoleIcon(specRole)
if (roleIcon) then
self.roleIcon:SetTexture(roleIcon)
self.roleIcon:SetTexCoord(L, R, T, B)
else
self.roleIcon:SetTexture("")
end
else
self.roleIcon:SetTexture("")
end
local playerGear = openRaidLib and openRaidLib.GetUnitGear(self.playerObject.nome)
--do not show the role icon
self.roleIcon:SetTexture("") --not in use
--set the player name
self.playerName:SetText(Details:GetOnlyName(self.playerObject.nome))
self.rankText:SetText(self.index) --not in use
--set the player class name
--self.className:SetText(string.lower(_G.UnitClass(self.playerObject.nome) or self.playerObject:Class())) --not in use
--item level
self.itemLevelText:SetText(self.playerObject.ilvl or (playerGear and playerGear.ilevel) or "0")
local actorSpecId = self.playerObject.spec
local actorTotal = self.playerObject.total
local combatObject = self.combatObject
--warcraftlogs percentile
if (self.playerObject.tipo == DETAILS_ATTRIBUTE_DAMAGE) then
local actorDPS = self.playerObject.total / combatObject:GetCombatTime()
local parsePercent = Details222.WarcraftLogs.GetDamageParsePercent(encounterId, difficultyId, actorSpecId, actorDPS)
if (parsePercent) then
parsePercent = math.floor(parsePercent)
local colorName = Details222.WarcraftLogs.GetParseColor(parsePercent)
self.percentileText:SetTextColor(detailsFramework:ParseColors(colorName))
self.percentileText:SetText(math.floor(parsePercent))
self.percentileText.alpha = 1
else
parsePercent = Details222.ParsePercent.GetPercent(DETAILS_ATTRIBUTE_DAMAGE, difficultyId, encounterId, actorSpecId, actorDPS)
if (parsePercent) then
parsePercent = math.floor(parsePercent)
local colorName = Details222.WarcraftLogs.GetParseColor(parsePercent)
self.percentileText:SetTextColor(detailsFramework:ParseColors(colorName))
self.percentileText:SetText(math.floor(parsePercent))
self.percentileText.alpha = 1
else
self.percentileText:SetText("#.def")
self.percentileText:SetAlpha(0.25)
end
end
else
self.percentileText:SetText("#.def")
self.percentileText:SetAlpha(0.25)
end
--set the statusbar
local r, g, b = self.playerObject:GetClassColor()
self.totalStatusBar:SetStatusBarColor(r, g, b, 1)
self.totalStatusBar:SetMinMaxValues(0, topResult)
self.totalStatusBar:SetValue(actorTotal)
end
--get a Details! window
local lowerInstanceId = Details:GetLowerInstanceNumber()
local fontFile
local fontSize
local fontOutline
if (lowerInstanceId) then
local instance = Details:GetInstance(lowerInstanceId)
if (instance) then
fontFile = instance.row_info.font_face
fontSize = instance.row_info.font_size
fontOutline = instance.row_info.textL_outline
end
end
local createPlayerLine = function(self, index)
--create a new line
local line = _G.CreateFrame("button", "$parentLine" .. index, self, "BackdropTemplate")
detailsFramework:Mixin(line, detailsFramework.HeaderFunctions)
local upFrame = CreateFrame("frame", nil, line)
upFrame:SetFrameLevel(line:GetFrameLevel()+2)
upFrame:SetAllPoints()
--set its parameters
line:SetPoint("topleft", self, "topleft", 1, -((index) * (player_line_height+1)) - 1)
line:SetSize(scrollbox_size[1], player_line_height)
--line:SetSize(scrollbox_size[1]-19, player_line_height)
line:RegisterForClicks("LeftButtonDown", "RightButtonDown")
line:SetScript("OnEnter", lineOnEnter)
line:SetScript("OnLeave", lineOnLeave)
line:SetScript("OnClick", lineOnClick)
detailsFramework:ApplyStandardBackdrop(line)
local specIcon = upFrame:CreateTexture("$parentSpecIcon", "artwork")
specIcon:SetSize(headerTable[1].width - 1, headerTable[1].width - 1)
specIcon:SetAlpha(0.71)
local roleIcon = upFrame:CreateTexture("$parentRoleIcon", "overlay")
roleIcon:SetSize((player_line_height-2) / 2, (player_line_height-2) / 2)
roleIcon:SetAlpha(0.71)
local playerName = detailsFramework:CreateLabel(upFrame, "", 11, "white", "GameFontNormal")
if (fontFile) then
playerName.fontface = fontFile
end
if (fontSize) then
playerName.fontsize = fontSize
end
if (fontOutline) then
playerName.outline = fontOutline
end
--~create
playerName.textcolor = {1, 1, 1, .9}
local className = detailsFramework:CreateLabel(upFrame, "", "GameFontNormal")
className.textcolor = {.95, .8, .2, 0}
className.textsize = 9
local itemLevelText = detailsFramework:CreateLabel(upFrame, "", "GameFontNormal")
itemLevelText.textcolor = {1, 1, 1, .7}
itemLevelText.textsize = 11
local percentileText = detailsFramework:CreateLabel(upFrame, "", "GameFontNormal")
percentileText.textcolor = {1, 1, 1, .7}
percentileText.textsize = 11
local rankText = detailsFramework:CreateLabel(upFrame, "", "GameFontNormal")
rankText.textcolor = {.3, .3, .3, .7}
rankText.textsize = fontSize
local totalStatusBar = CreateFrame("statusbar", nil, line)
totalStatusBar:SetSize(scrollbox_size[1]-player_line_height, 4)
totalStatusBar:SetMinMaxValues(0, 100)
totalStatusBar:SetStatusBarTexture([[Interface\AddOns\Details\images\bar_skyline]])
totalStatusBar:SetFrameLevel(line:GetFrameLevel()+1)
totalStatusBar:SetAlpha(0.5)
--setup anchors
--specIcon:SetPoint("topleft", line, "topleft", 0, 0)
--roleIcon:SetPoint("topleft", specIcon, "topright", 2, 0)
--playerName:SetPoint("topleft", specIcon, "topright", 2, -3)
--className:SetPoint("topleft", roleIcon, "bottomleft", 0, -2)
--rankText:SetPoint("right", line, "right", -2, 0)
totalStatusBar:SetPoint("bottomleft", specIcon, "bottomright", 0, 0)
line.specIcon = specIcon
line.roleIcon = roleIcon
line.playerName = playerName
line.className = className
line.rankText = rankText
line.totalStatusBar = totalStatusBar
line.itemLevelText = itemLevelText
line.percentileText = percentileText
line:AddFrameToHeaderAlignment(specIcon)
line:AddFrameToHeaderAlignment(playerName)
line:AddFrameToHeaderAlignment(itemLevelText)
line:AddFrameToHeaderAlignment(percentileText)
line:AlignWithHeader(f.Header, "left")
line.UpdateLine = updatePlayerLine
return line
end
local playerScroll = detailsFramework:CreateScrollBox(f, "$parentPlayerScrollBox", refreshScrollFunc, {}, player_scroll_size[1] + 22, player_scroll_size[2], scrollbox_lines, player_line_height)
detailsFramework:ReskinSlider(playerScroll)
playerScroll.ScrollBar:ClearAllPoints()
playerScroll.ScrollBar:SetPoint("topright", playerScroll, "topright", -2, -37)
playerScroll.ScrollBar:SetPoint("bottomright", playerScroll, "bottomright", -2, 17)
playerScroll.ScrollBar:Hide()
playerScroll:SetPoint("topright", f, "topleft", -1, 0)
playerScroll:SetPoint("bottomright", f, "bottomleft", -1, 0)
playerScroll:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
playerScroll:SetBackdropColor(0, 0, 0, 0.2)
playerScroll:SetBackdropBorderColor(0, 0, 0, 1)
f.playerScrollBox = playerScroll
--need to be created before
f.Header = DetailsFramework:CreateHeader(f, headerTable, headerOptions)
f.Header:SetPoint("topleft", playerScroll, "topleft", 0, -1)
f.Header:SetPoint("topright", playerScroll, "topright", 0, -1)
detailsFramework:ApplyStandardBackdrop(f.Header)
f.Header.__background:SetColorTexture(.60, .60, .60)
local playerSelectionLabel = detailsFramework:CreateLabel(playerScroll, "Click to select a player", 14)
playerSelectionLabel:SetPoint("bottom", playerScroll, "bottom", 0, 7)
--create the scrollbox lines
for i = 1, scrollbox_lines do
playerScroll:CreateLine(createPlayerLine)
end
local classIds = {
WARRIOR = 1,
PALADIN = 2,
HUNTER = 3,
ROGUE = 4,
PRIEST = 5,
DEATHKNIGHT = 6,
SHAMAN = 7,
MAGE = 8,
WARLOCK = 9,
MONK = 10,
DRUID = 11,
DEMONHUNTER = 12,
EVOKER = 13,
}
--get the player list from the segment and build a table compatible with the scroll box
function breakdownWindowPlayerList.BuildPlayerList()
---@type combat
local combatObject = Details:GetCombatFromBreakdownWindow()
local playerTable = {}
if (combatObject) then
local displayType = Details:GetDisplayTypeFromBreakdownWindow()
local containerType = displayType == 1 and DETAILS_ATTRIBUTE_DAMAGE or DETAILS_ATTRIBUTE_HEAL
---@type actorcontainer
local actorContainer = combatObject:GetContainer(containerType)
for index, actorObject in actorContainer:ListActors() do
if (actorObject:IsPlayer() and actorObject:IsGroupPlayer()) then
local unitClassID = classIds[actorObject:Class()] or 13
local unitName = actorObject:Name()
local playerPosition = (((unitClassID or 0) + 128) ^ 4) + tonumber(string.byte(unitName, 1) .. "" .. string.byte(unitName, 2))
---@type {key1: actor, key2: number, key3: number}
local data = {actorObject, playerPosition, actorObject.total}
tinsert(playerTable, data)
end
end
end
table.sort(playerTable, detailsFramework.SortOrder3)
local resultTable = {}
for i = 1, #playerTable do
resultTable[#resultTable+1] = playerTable[i][1]
end
return resultTable
end
local updatePlayerList = function()
local playerList = breakdownWindowPlayerList.BuildPlayerList()
playerScroll:SetData(playerList)
playerScroll:Refresh()
playerScroll:Show()
end
function Details:UpdateBreakdownPlayerList()
--run the update on the next tick
C_Timer.After(0, updatePlayerList)
--DF.Schedules.RunNextTick(updatePlayerList)
end
f:HookScript("OnShow", function()
Details:UpdateBreakdownPlayerList()
end)
f:HookScript("OnHide", function()
for lineIndex, line in ipairs(f.playerScrollBox:GetLines()) do
line.playerObject = nil
line.combatObject = nil
end
end)
local gradientStartColor = Details222.ColorScheme.GetColorFor("gradient-background")
local gradientBelow = DetailsFramework:CreateTexture(f.playerScrollBox,
{gradient = "vertical", fromColor = gradientStartColor, toColor = "transparent"}, 1, 90, "artwork", {0, 1, 0, 1})
gradientBelow:SetPoint("bottoms", 1, 1)
end
function Details.PlayerBreakdown.CreatePlayerListFrame()
if (not Details.PlayerBreakdown.playerListFrameCreated) then
breakdownWindowPlayerList.CreatePlayerListFrame()
Details.PlayerBreakdown.playerListFrameCreated = true
end
end
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,266 @@
local Details = Details
local DF = DetailsFramework
--create the main frame for the options panel
local createOptionsPanel = function()
local startX = 5
local startY = -32
local heightSize = 540
local DetailsSpellBreakdownTab = DetailsSpellBreakdownTab
local UIParent = UIParent
local options_text_template = DF:GetTemplate("font", "OPTIONS_FONT_TEMPLATE")
local options_dropdown_template = DF:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE")
local options_switch_template = DF:GetTemplate("switch", "OPTIONS_CHECKBOX_TEMPLATE")
local options_slider_template = DF:GetTemplate("slider", "OPTIONS_SLIDER_TEMPLATE")
local options_button_template = DF:GetTemplate("button", "OPTIONS_BUTTON_TEMPLATE")
local optionsFrame = DF:CreateSimplePanel(UIParent, 550, 500, "Details! Breakdown Options", "DetailsSpellBreakdownOptionsPanel")
optionsFrame:SetFrameStrata("DIALOG")
optionsFrame:SetPoint("topleft", UIParent, "topleft", 2, -40)
optionsFrame:Show()
local bUseSolidColor = true
DF:ApplyStandardBackdrop(optionsFrame, bUseSolidColor)
local resetSettings = function()
for key, value in pairs (Details.default_global_data.breakdown_spell_tab) do
if (type(value) == "table") then
local t = DF.table.copy({}, value)
Details.breakdown_spell_tab[key] = t
else
Details.breakdown_spell_tab[key] = value
end
end
local instanceObject = Details:GetActiveWindowFromBreakdownWindow()
local actorObject = Details:GetActorObjectFromBreakdownWindow()
local bFromAttributeChange = true
local bIsRefresh = true
local bIsShiftKeyDown = false
local bIsControlKeyDown = false
Details:CloseBreakdownWindow()
Details:OpenBreakdownWindow(instanceObject, actorObject, bFromAttributeChange, bIsRefresh, bIsShiftKeyDown, bIsControlKeyDown)
DetailsSpellBreakdownTab.GetSpellBlockFrame():UpdateBlocks()
DetailsSpellBreakdownTab.UpdateShownSpellBlock()
DetailsSpellBreakdownTab.UpdateHeadersSettings("spells")
DetailsSpellBreakdownOptionsPanel:RefreshOptions()
Details:Msg("Settings reseted to default.")
end
local resetSettingsButton = DF:CreateButton(optionsFrame, resetSettings, 130, 20, "Reset Settings")
resetSettingsButton:SetPoint("bottomleft", optionsFrame, "bottomleft", 5, 5)
resetSettingsButton:SetTemplate(options_button_template)
local subSectionTitleTextTemplate = DF:GetTemplate("font", "ORANGE_FONT_TEMPLATE")
local optionsTable = {
{type = "label", get = function() return "Spell Details Block" end, text_template = subSectionTitleTextTemplate},
{--block height
type = "range",
get = function() return Details.breakdown_spell_tab.blockspell_height end,
set = function(self, fixedparam, value)
Details.breakdown_spell_tab.blockspell_height = value
DetailsSpellBreakdownTab.GetSpellBlockFrame():UpdateBlocks()
end,
min = 50,
max = 80,
step = 1,
name = "Block Height",
desc = "Block Height",
},
{type = "blank"},
{type = "blank"},
{type = "label", get = function() return "Spell Header Options" end, text_template = subSectionTitleTextTemplate},
{ --per second
type = "toggle",
get = function() return Details.breakdown_spell_tab.spellcontainer_headers["persecond"].enabled end,
set = function(self, fixedparam, value)
Details.breakdown_spell_tab.spellcontainer_headers["persecond"].enabled = value
DetailsSpellBreakdownTab.UpdateHeadersSettings("spells")
end,
name = "Per Second",
desc = "Per Second",
},
{ --amount of casts
type = "toggle",
get = function() return Details.breakdown_spell_tab.spellcontainer_headers["casts"].enabled end,
set = function(self, fixedparam, value)
Details.breakdown_spell_tab.spellcontainer_headers["casts"].enabled = value
DetailsSpellBreakdownTab.UpdateHeadersSettings("spells")
end,
name = "Casts",
desc = "Casts",
},
{ --critical hits percent
type = "toggle",
get = function() return Details.breakdown_spell_tab.spellcontainer_headers["critpercent"].enabled end,
set = function(self, fixedparam, value)
Details.breakdown_spell_tab.spellcontainer_headers["critpercent"].enabled = value
DetailsSpellBreakdownTab.UpdateHeadersSettings("spells")
end,
name = "Critical Hits Percent",
desc = "Critical Hits Percent",
},
{ --amount of hits
type = "toggle",
get = function() return Details.breakdown_spell_tab.spellcontainer_headers["hits"].enabled end,
set = function(self, fixedparam, value)
Details.breakdown_spell_tab.spellcontainer_headers["hits"].enabled = value
DetailsSpellBreakdownTab.UpdateHeadersSettings("spells")
end,
name = "Hits Amount",
desc = "Hits Amount",
},
{ --average damage of healing per cast amount
type = "toggle",
get = function() return Details.breakdown_spell_tab.spellcontainer_headers["castavg"].enabled end,
set = function(self, fixedparam, value)
Details.breakdown_spell_tab.spellcontainer_headers["castavg"].enabled = value
DetailsSpellBreakdownTab.UpdateHeadersSettings("spells")
end,
name = "Cast Average",
desc = "Cast Average",
},
{ --debuff uptime
type = "toggle",
get = function() return Details.breakdown_spell_tab.spellcontainer_headers["uptime"].enabled end,
set = function(self, fixedparam, value)
Details.breakdown_spell_tab.spellcontainer_headers["uptime"].enabled = value
DetailsSpellBreakdownTab.UpdateHeadersSettings("spells")
end,
name = "Uptime",
desc = "Uptime",
},
{ --overheal
type = "toggle",
get = function() return Details.breakdown_spell_tab.spellcontainer_headers["overheal"].enabled end,
set = function(self, fixedparam, value)
Details.breakdown_spell_tab.spellcontainer_headers["overheal"].enabled = value
DetailsSpellBreakdownTab.UpdateHeadersSettings("spells")
end,
name = "Overheal",
desc = "Overheal",
},
{ --absorbed
type = "toggle",
get = function() return Details.breakdown_spell_tab.spellcontainer_headers["absorbed"].enabled end,
set = function(self, fixedparam, value)
Details.breakdown_spell_tab.spellcontainer_headers["absorbed"].enabled = value
DetailsSpellBreakdownTab.UpdateHeadersSettings("spells")
end,
name = "Heal Absorbed",
desc = "Heal Absorbed",
},
{type = "breakline"},
{type = "label", get = function() return "Scroll Options" end, text_template = subSectionTitleTextTemplate},
{ --locked
type = "toggle",
get = function() return Details.breakdown_spell_tab.spellcontainer_islocked end,
set = function(self, fixedparam, value)
---@type df_framecontainer
local container = DetailsSpellBreakdownTab.GetSpellScrollContainer()
container:SetResizeLocked(value)
local container = DetailsSpellBreakdownTab.GetTargetScrollContainer()
container:SetResizeLocked(value)
end,
name = "Is Locked",
desc = "Is Locked",
},
{--background alpha
type = "range",
get = function() return Details.breakdown_spell_tab.spellbar_background_alpha end,
set = function(self, fixedparam, value)
Details.breakdown_spell_tab.spellbar_background_alpha = value
DetailsSpellBreakdownTab.GetSpellScrollFrame():Refresh()
end,
min = 0,
max = 1,
step = 0.1,
usedecimals = true,
name = "Background Alpha",
desc = "Background Alpha",
},
{type = "blank"},
{type = "label", get = function() return "Group Player Spells:" end, text_template = subSectionTitleTextTemplate},
{ --nest player spells | merge player spells
type = "toggle",
get = function() return Details.breakdown_spell_tab.nest_players_spells_with_same_name end,
set = function(self, fixedparam, value)
Details.breakdown_spell_tab.nest_players_spells_with_same_name = value
end,
name = "Group Player Spells With Same Name",
desc = "Group spells casted by players which has the same name",
},
{type = "blank"},
{type = "label", get = function() return "Group Pet Spells:" end, text_template = subSectionTitleTextTemplate},
{ --nest pet spells with the same name
type = "toggle",
get = function() return Details.breakdown_spell_tab.nest_pet_spells_by_name end,
set = function(self, fixedparam, value)
Details.breakdown_spell_tab.nest_pet_spells_by_name = value
end,
name = "Group Pet Names Under a Pet Spell Bar",
desc = "Group Pets By Name",
hooks = {["OnSwitch"] = function()
if (Details.breakdown_spell_tab.nest_pet_spells_by_name) then
Details.breakdown_spell_tab.nest_pet_spells_by_caster = false
DetailsSpellBreakdownOptionsPanel:RefreshOptions()
end
end}
},
{ --nest pet spells with the same name
type = "toggle",
get = function() return Details.breakdown_spell_tab.nest_pet_spells_by_caster end,
set = function(self, fixedparam, value)
Details.breakdown_spell_tab.nest_pet_spells_by_caster = value
end,
name = "Group Pet Spells Under a Pet Name Bar",
desc = "Group Pets By Spell",
hooks = {["OnSwitch"] = function()
if (Details.breakdown_spell_tab.nest_pet_spells_by_caster) then
Details.breakdown_spell_tab.nest_pet_spells_by_name = false
DetailsSpellBreakdownOptionsPanel:RefreshOptions()
end
end}
},
}
--build the menu
optionsTable.always_boxfirst = true
DF:BuildMenu(optionsFrame, optionsTable, startX, startY, heightSize, false, options_text_template, options_dropdown_template, options_switch_template, true, options_slider_template, options_button_template)
end
function Details.OpenSpellBreakdownOptions()
if (DetailsSpellBreakdownOptionsPanel) then
DetailsSpellBreakdownOptionsPanel:RefreshOptions()
DetailsSpellBreakdownOptionsPanel:Show()
return
end
createOptionsPanel()
end