chore: hoist plugins to root and move main into Details/
Each Details_* plugin and the main Details addon now lives in its own repo-root folder, matching the Exiles fork-layout convention.
This commit is contained in:
@@ -0,0 +1,945 @@
|
||||
|
||||
local addonId, edTable = ...
|
||||
local AceLocale = LibStub("AceLocale-3.0")
|
||||
local Loc = AceLocale:GetLocale("Details_EncounterDetails")
|
||||
local Details = Details
|
||||
local _
|
||||
|
||||
local openAtStartup = "false"
|
||||
|
||||
local isDebug = false
|
||||
local function DebugMessage(...)
|
||||
if (isDebug) then
|
||||
print("|cFFFFFF00EBreakDown|r:", ...)
|
||||
end
|
||||
end
|
||||
|
||||
local PLUGIN_REAL_NAME = "DETAILS_PLUGIN_ENCOUNTER_DETAILS"
|
||||
|
||||
edTable.PluginAbsoluteName = PLUGIN_REAL_NAME
|
||||
|
||||
local _GetSpellInfo = Details.getspellinfo --wow api local
|
||||
local CreateFrame = CreateFrame --wow api local
|
||||
local GetTime = GetTime --wow api local
|
||||
local GetCursorPosition = GetCursorPosition --wow api local
|
||||
local GameTooltip = GameTooltip --wow api local
|
||||
local GameCooltip = GameCooltip2
|
||||
|
||||
local ipairs = ipairs
|
||||
local pairs = pairs
|
||||
local bitBand = bit.band
|
||||
|
||||
--create the plugin object
|
||||
local encounterDetails = Details:NewPluginObject("Details_EncounterDetails", DETAILSPLUGIN_ALWAYSENABLED)
|
||||
table.insert(UISpecialFrames, "Details_EncounterDetails")
|
||||
edTable.PluginObject = encounterDetails
|
||||
|
||||
EncounterDetailsGlobal = encounterDetails --[[GLOBAL]]
|
||||
|
||||
edTable.defaultBackgroundColor = {0.5, 0.5, 0.5, 0.3}
|
||||
edTable.defaultBackgroundColor_OnEnter = {0.5, 0.5, 0.5, 0.7}
|
||||
edTable.defaultBackdrop = {bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true}
|
||||
|
||||
local edFrame = encounterDetails.Frame
|
||||
edFrame.DefaultBarHeight = 20
|
||||
edFrame.CooltipStatusbarAlpha = .834
|
||||
edFrame.DefaultBarTexture = "Interface\\AddOns\\Details\\images\\bar_serenity"
|
||||
edFrame.encounterSummaryWidgets = {}
|
||||
encounterDetails:SetPluginDescription("Raid encounters summary, show basic stuff like dispels, interrupts and also graphic charts, boss emotes and the Weakaura Creation Tool.")
|
||||
|
||||
--main combat object
|
||||
local _combat_object
|
||||
|
||||
encounterDetails.name = "Encounter Breakdown"
|
||||
encounterDetails.debugmode = false
|
||||
|
||||
function encounterDetails:FormatCooltipSettings()
|
||||
GameCooltip:SetType("tooltip")
|
||||
GameCooltip:SetOption("StatusBarTexture", [[Interface\AddOns\Details\images\bar_serenity]])
|
||||
GameCooltip:SetOption("StatusBarHeightMod", 0)
|
||||
GameCooltip:SetOption("FixedWidth", 280)
|
||||
GameCooltip:SetOption("TextSize", 11)
|
||||
GameCooltip:SetOption("LeftBorderSize", -4)
|
||||
GameCooltip:SetOption("RightBorderSize", 5)
|
||||
GameCooltip:SetOption("ButtonsYMod", 0)
|
||||
GameCooltip:SetOption("YSpacingMod", -1)
|
||||
end
|
||||
|
||||
encounterDetails.CooltipLineHeight = 18
|
||||
|
||||
--main object frame functions
|
||||
local function CreatePluginFrames(data)
|
||||
--saved data if any
|
||||
encounterDetails.data = data or {}
|
||||
|
||||
--record if button is shown
|
||||
encounterDetails.showing = false
|
||||
|
||||
--record if boss window is open or not
|
||||
encounterDetails.window_open = false
|
||||
encounterDetails.combat_boss_found = false
|
||||
|
||||
--OnEvent Table
|
||||
function encounterDetails:OnDetailsEvent(event, ...)
|
||||
--when main frame became hide
|
||||
if (event == "HIDE") then --plugin hidded, disabled
|
||||
self.open = false
|
||||
|
||||
--when main frame is shown on screen
|
||||
elseif (event == "SHOW") then --plugin hidded, disabled
|
||||
self.open = true
|
||||
encounterDetails:RefreshScale()
|
||||
|
||||
--when details finish his startup and are ready to work
|
||||
elseif (event == "DETAILS_STARTED") then
|
||||
if (openAtStartup) then
|
||||
C_Timer.After(0.1, function()
|
||||
--Details:OpenPlugin('Encounter Breakdown')
|
||||
end)
|
||||
end
|
||||
|
||||
--check if details are in combat, if not check if the last fight was a boss fight
|
||||
if (not encounterDetails:IsInCombat()) then
|
||||
--get the current combat table
|
||||
_combat_object = encounterDetails:GetCombat()
|
||||
--check if was a boss fight
|
||||
encounterDetails:WasEncounter()
|
||||
end
|
||||
|
||||
local string_damage_done_func = [[
|
||||
--get the current combat
|
||||
local currentCombat = Details:GetCurrentCombat()
|
||||
--total damage done by the raid group
|
||||
local raidGroupDamageDone = currentCombat:GetTotal(DETAILS_ATTRIBUTE_DAMAGE, nil, DETAILS_TOTALS_ONLYGROUP)
|
||||
return raidGroupDamageDone or 0
|
||||
]]
|
||||
Details:TimeDataRegister("Raid Damage Done", string_damage_done_func, nil, "Encounter Details", "v1.0", [[Interface\ICONS\Ability_DualWield]], true, true)
|
||||
|
||||
if (encounterDetails.db.show_icon == 4) then
|
||||
encounterDetails:ShowIcon()
|
||||
elseif (encounterDetails.db.show_icon == 5) then
|
||||
encounterDetails:AutoShowIcon()
|
||||
end
|
||||
|
||||
elseif (event == "COMBAT_PLAYER_ENTER") then --combat started
|
||||
if (encounterDetails.showing and encounterDetails.db.hide_on_combat) then
|
||||
--EncounterDetails:HideIcon()
|
||||
encounterDetails:CloseWindow()
|
||||
end
|
||||
|
||||
encounterDetails.current_whisper_table = {}
|
||||
|
||||
elseif (event == "COMBAT_PLAYER_LEAVE") then
|
||||
--combat leave and enter always send current combat table
|
||||
_combat_object = select(1, ...)
|
||||
--check if was a boss fight
|
||||
encounterDetails:WasEncounter()
|
||||
|
||||
if (encounterDetails.combat_boss_found) then
|
||||
encounterDetails.combat_boss_found = false
|
||||
end
|
||||
|
||||
if (encounterDetails.db.show_icon == 5) then
|
||||
encounterDetails:AutoShowIcon()
|
||||
end
|
||||
|
||||
local chartName = "Raid Damage Done"
|
||||
local combatUniquieID = _combat_object:GetCombatNumber()
|
||||
local chartData = _combat_object:GetTimeData(chartName)
|
||||
|
||||
if (chartData) then
|
||||
EncounterDetailsDB.chartData[combatUniquieID] = EncounterDetailsDB.chartData[combatUniquieID] or {}
|
||||
EncounterDetailsDB.chartData[combatUniquieID][chartName] = chartData
|
||||
--store when this chart was created to cleanup later
|
||||
chartData.__time = time()
|
||||
--remove the time data from the combat object
|
||||
_combat_object:EraseTimeData(chartName)
|
||||
end
|
||||
|
||||
local whisperTable = encounterDetails.current_whisper_table
|
||||
if (whisperTable and _combat_object.is_boss and _combat_object.is_boss.name) then
|
||||
whisperTable.boss = _combat_object.is_boss.name
|
||||
table.insert(encounterDetails.boss_emotes_table, 1, whisperTable)
|
||||
|
||||
if (#encounterDetails.boss_emotes_table > encounterDetails.db.max_emote_segments) then
|
||||
table.remove(encounterDetails.boss_emotes_table, encounterDetails.db.max_emote_segments+1)
|
||||
end
|
||||
end
|
||||
|
||||
elseif (event == "COMBAT_BOSS_FOUND") then
|
||||
encounterDetails.combat_boss_found = true
|
||||
if (encounterDetails.db.show_icon == 5) then
|
||||
encounterDetails:AutoShowIcon()
|
||||
end
|
||||
|
||||
elseif (event == "DETAILS_DATA_RESET") then
|
||||
if (encounterDetails.chartPanel) then
|
||||
encounterDetails.chartPanel:Reset()
|
||||
end
|
||||
|
||||
if (encounterDetails.db.show_icon == 5) then
|
||||
encounterDetails:AutoShowIcon()
|
||||
end
|
||||
|
||||
encounterDetails:CloseWindow()
|
||||
|
||||
--drop last combat table
|
||||
encounterDetails.LastSegmentShown = nil
|
||||
|
||||
--wipe emotes
|
||||
table.wipe(encounterDetails.boss_emotes_table)
|
||||
|
||||
elseif (event == "GROUP_ONENTER") then
|
||||
if (encounterDetails.db.show_icon == 2) then
|
||||
encounterDetails:ShowIcon()
|
||||
end
|
||||
|
||||
elseif (event == "GROUP_ONLEAVE") then
|
||||
if (encounterDetails.db.show_icon == 2) then
|
||||
encounterDetails:HideIcon()
|
||||
end
|
||||
|
||||
elseif (event == "ZONE_TYPE_CHANGED") then
|
||||
if (encounterDetails.db.show_icon == 1) then
|
||||
if (select(1, ...) == "raid") then
|
||||
encounterDetails:ShowIcon()
|
||||
else
|
||||
encounterDetails:HideIcon()
|
||||
end
|
||||
end
|
||||
|
||||
elseif (event == "PLUGIN_DISABLED") then
|
||||
encounterDetails:HideIcon()
|
||||
encounterDetails:CloseWindow()
|
||||
|
||||
elseif (event == "PLUGIN_ENABLED") then
|
||||
if (encounterDetails.db.show_icon == 5) then
|
||||
encounterDetails:AutoShowIcon()
|
||||
|
||||
elseif (encounterDetails.db.show_icon == 4) then
|
||||
encounterDetails:ShowIcon()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function encounterDetails:WasEncounter()
|
||||
--check if last combat was a boss encounter
|
||||
if (not encounterDetails.debugmode) then
|
||||
if (not _combat_object.is_boss) then
|
||||
return
|
||||
|
||||
elseif (_combat_object.is_boss.encounter == "pvp") then
|
||||
return
|
||||
end
|
||||
|
||||
if (_combat_object.instance_type ~= "raid") then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
--boss found, show the icon
|
||||
encounterDetails:ShowIcon()
|
||||
end
|
||||
|
||||
function encounterDetails:ShowIcon()
|
||||
encounterDetails.showing = true
|
||||
--[1] button to show [2] button animation: "star", "blink" or true(blink)
|
||||
encounterDetails:ShowToolbarIcon(encounterDetails.ToolbarButton, "star")
|
||||
end
|
||||
|
||||
--hide icon on toolbar
|
||||
function encounterDetails:HideIcon()
|
||||
encounterDetails.showing = false
|
||||
encounterDetails:HideToolbarIcon(encounterDetails.ToolbarButton)
|
||||
end
|
||||
|
||||
--user clicked on button, need open or close window
|
||||
function encounterDetails:OpenWindow()
|
||||
if (encounterDetails.Frame:IsShown()) then
|
||||
return encounterDetails:CloseWindow()
|
||||
end
|
||||
|
||||
DetailsPluginContainerWindow.OpenPlugin(encounterDetails)
|
||||
|
||||
--build all window data
|
||||
encounterDetails.db.opened = encounterDetails.db.opened + 1
|
||||
encounterDetails:OpenAndRefresh()
|
||||
|
||||
--show
|
||||
edFrame:Show()
|
||||
encounterDetails.open = true
|
||||
|
||||
if (edFrame.ShowType == "graph") then
|
||||
encounterDetails:ShowChartFrame()
|
||||
end
|
||||
|
||||
--select latest emote segment
|
||||
encounterDetails.emoteSegmentsDropdown:Select(1)
|
||||
encounterDetails.emoteSegmentsDropdown:Refresh()
|
||||
encounterDetails:SetEmoteSegment(1)
|
||||
|
||||
if (edFrame.ShowType ~= "emotes") then
|
||||
--hide emote frames
|
||||
for _, widget in pairs(encounterDetails.Frame.EmoteWidgets) do
|
||||
widget:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function encounterDetails:CloseWindow()
|
||||
encounterDetails.open = false
|
||||
edFrame:Hide()
|
||||
Details:CloseBreakdownWindow()
|
||||
return true
|
||||
end
|
||||
|
||||
local cooltip_menu = function()
|
||||
local gameCooltip = GameCooltip
|
||||
|
||||
gameCooltip:Reset()
|
||||
gameCooltip:SetType("menu")
|
||||
|
||||
gameCooltip:SetOption("TextSize", Details.font_sizes.menus)
|
||||
gameCooltip:SetOption("TextFont", Details.font_faces.menus)
|
||||
|
||||
gameCooltip:SetOption("ButtonHeightModSub", -2)
|
||||
gameCooltip:SetOption("ButtonHeightMod", -5)
|
||||
|
||||
gameCooltip:SetOption("ButtonsYModSub", -3)
|
||||
gameCooltip:SetOption("ButtonsYMod", -6)
|
||||
|
||||
gameCooltip:SetOption("YSpacingModSub", -3)
|
||||
gameCooltip:SetOption("YSpacingMod", 1)
|
||||
|
||||
gameCooltip:SetOption("HeighMod", 3)
|
||||
gameCooltip:SetOption("SubFollowButton", true)
|
||||
|
||||
Details:SetTooltipMinWidth()
|
||||
|
||||
--summary
|
||||
gameCooltip:AddLine("Encounter Summary")
|
||||
gameCooltip:AddMenu(1, encounterDetails.Frame.switch, "main")
|
||||
gameCooltip:AddIcon("Interface\\AddOns\\Details_EncounterDetails\\images\\boss_frame_buttons", 1, 1, 20, 20, 0, 0.125, 0, 0.5)
|
||||
|
||||
--chart
|
||||
gameCooltip:AddLine("Damage Graphic")
|
||||
gameCooltip:AddMenu(1, encounterDetails.Frame.switch, "graph")
|
||||
gameCooltip:AddIcon("Interface\\AddOns\\Details_EncounterDetails\\images\\boss_frame_buttons", 1, 1, 20, 20, 0.125*3, 0.125*4, 0, 0.5)
|
||||
|
||||
--emotes
|
||||
gameCooltip:AddLine("Boss Emotes")
|
||||
gameCooltip:AddMenu(1, encounterDetails.Frame.switch, "emotes")
|
||||
gameCooltip:AddIcon("Interface\\AddOns\\Details_EncounterDetails\\images\\boss_frame_buttons", 1, 1, 20, 20, 0.125*4, 0.125*5, 0, 0.5)
|
||||
|
||||
--phases
|
||||
gameCooltip:AddLine("Damage by Boss Phase")
|
||||
gameCooltip:AddMenu(1, encounterDetails.Frame.switch, "phases")
|
||||
gameCooltip:AddIcon("Interface\\AddOns\\Details_EncounterDetails\\images\\boss_frame_buttons", 1, 1, 20, 20, 0.125, 0.125*2, 0, 0.505625)
|
||||
|
||||
--apply the backdrop settings to the menu
|
||||
Details:FormatCooltipBackdrop()
|
||||
gameCooltip:SetOwner(ENCOUNTERDETAILS_BUTTON, "bottom", "top", 0, 0)
|
||||
gameCooltip:ShowCooltip()
|
||||
end
|
||||
|
||||
encounterDetails.ToolbarButton = Details.ToolBar:NewPluginToolbarButton(encounterDetails.OpenWindow, "Interface\\AddOns\\Details_EncounterDetails\\images\\icon", Loc ["STRING_PLUGIN_NAME"], Loc ["STRING_TOOLTIP"], 16, 16, "ENCOUNTERDETAILS_BUTTON", cooltip_menu) --"Interface\\COMMON\\help-i"
|
||||
encounterDetails.ToolbarButton.shadow = true --loads icon_shadow.tga when the instance is showing icons with shadows
|
||||
|
||||
--setpoint anchors mod if needed
|
||||
encounterDetails.ToolbarButton.y = 0.5
|
||||
encounterDetails.ToolbarButton.x = 0
|
||||
|
||||
--build all frames ans widgets
|
||||
Details.EncounterDetailsTempWindow(encounterDetails)
|
||||
Details.EncounterDetailsTempWindow = nil
|
||||
end
|
||||
|
||||
--custom tooltip for dead details ---------------------------------------------------------------------------------------------------------
|
||||
|
||||
--tooltip backdrop, color and border
|
||||
local bgColor, borderColor = {0.17, 0.17, 0.17, .9}, {.30, .30, .30, .3}
|
||||
|
||||
local function KillInfo(deathTable, row)
|
||||
local iconSize = 19
|
||||
|
||||
local eventos = deathTable [1]
|
||||
local hora_da_morte = deathTable [2]
|
||||
local hp_max = deathTable [5]
|
||||
|
||||
local battleress = false
|
||||
local lastcooldown = false
|
||||
|
||||
GameCooltip:Reset()
|
||||
GameCooltip:SetType("tooltipbar")
|
||||
GameCooltip:SetOwner(row)
|
||||
|
||||
GameCooltip:AddLine("Click to Report", nil, 1, "orange")
|
||||
GameCooltip:AddIcon([[Interface\TUTORIALFRAME\UI-TUTORIAL-FRAME]], 1, 1, 12, 16, 0.015625, 0.13671875, 0.4375, 0.59765625)
|
||||
GameCooltip:AddStatusBar(0, 1, 1, 1, 1, 1, false, {value = 100, color = {.3, .3, .3, .5}, specialSpark = false, texture = [[Interface\AddOns\Details\images\bar_serenity]]})
|
||||
|
||||
local statusBarBackground = {value = 100, color = {.21, .21, .21, 0.8}, texture = [[Interface\AddOns\Details\images\bar_serenity]]}
|
||||
|
||||
--death parser
|
||||
for index, event in ipairs(eventos) do
|
||||
|
||||
local hp = math.floor(event[5]/hp_max*100)
|
||||
if (hp > 100) then
|
||||
hp = 100
|
||||
end
|
||||
|
||||
local evtype = event [1]
|
||||
local spellname, _, spellicon = _GetSpellInfo(event [2])
|
||||
local amount = event [3]
|
||||
local time = event [4]
|
||||
local source = event [6]
|
||||
|
||||
if (type(evtype) == "boolean") then
|
||||
--is damage or heal
|
||||
if (evtype) then
|
||||
--damage
|
||||
|
||||
local overkill = event [10] or 0
|
||||
if (overkill > 0) then
|
||||
amount = amount - overkill
|
||||
overkill = "(" .. Details:ToK(overkill) .. " |cFFFF8800overkill|r)"
|
||||
else
|
||||
overkill = ""
|
||||
end
|
||||
|
||||
if (source:find("%[")) then
|
||||
source = source:gsub("%[%*%] ", "")
|
||||
end
|
||||
|
||||
GameCooltip:AddLine("" .. string.format("%.1f", time - hora_da_morte) .. "s " .. spellname .. "(" .. source .. ")", "-" .. Details:ToK(amount) .. overkill .. "(" .. hp .. "%)", 1, "white", "white")
|
||||
GameCooltip:AddIcon(spellicon, 1, 1, 16, 16, .1, .9, .1, .9)
|
||||
|
||||
if (event [9]) then
|
||||
--friendly fire
|
||||
GameCooltip:AddStatusBar(hp, 1, "darkorange", true, statusBarBackground)
|
||||
else
|
||||
--from a enemy
|
||||
GameCooltip:AddStatusBar(hp, 1, "red", true, statusBarBackground)
|
||||
end
|
||||
else
|
||||
--heal
|
||||
local class = Details:GetClass(source)
|
||||
local spec = Details:GetSpec(source)
|
||||
|
||||
GameCooltip:AddLine("" .. string.format("%.1f", time - hora_da_morte) .. "s " .. spellname .. "(" .. Details:GetOnlyName(Details:AddClassOrSpecIcon(source, class, spec, 16, true)) .. ")", "+" .. Details:ToK(amount) .. "(" .. hp .. "%)", 1, "white", "white")
|
||||
GameCooltip:AddIcon(spellicon, 1, 1, 16, 16, .1, .9, .1, .9)
|
||||
GameCooltip:AddStatusBar(hp, 1, "green", true, statusBarBackground)
|
||||
end
|
||||
|
||||
elseif (type(evtype) == "number") then
|
||||
if (evtype == 1) then
|
||||
--cooldown
|
||||
GameCooltip:AddLine("" .. string.format("%.1f", time - hora_da_morte) .. "s " .. spellname .. "(" .. source .. ")", "cooldown(" .. hp .. "%)", 1, "white", "white")
|
||||
GameCooltip:AddIcon(spellicon, 1, 1, 16, 16, .1, .9, .1, .9)
|
||||
GameCooltip:AddStatusBar(100, 1, "yellow", true, statusBarBackground)
|
||||
|
||||
elseif (evtype == 2 and not battleress) then
|
||||
--battle ress
|
||||
battleress = event
|
||||
|
||||
elseif (evtype == 3) then
|
||||
--last cooldown used
|
||||
lastcooldown = event
|
||||
|
||||
elseif (evtype == 4) then
|
||||
--debuff
|
||||
if (source:find("%[")) then
|
||||
source = source:gsub("%[%*%] ", "")
|
||||
end
|
||||
|
||||
GameCooltip:AddLine("" .. string.format("%.1f", time - hora_da_morte) .. "s [x" .. amount .. "] " .. spellname .. "(" .. source .. ")", "debuff(" .. hp .. "%)", 1, "white", "white")
|
||||
GameCooltip:AddIcon(spellicon, 1, 1, 16, 16, .1, .9, .1, .9)
|
||||
GameCooltip:AddStatusBar(100, 1, "purple", true, statusBarBackground)
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
GameCooltip:AddLine(deathTable [6] .. " " .. "died" , "-- -- -- ", 1, "white")
|
||||
GameCooltip:AddIcon("Interface\\AddOns\\Details\\images\\small_icons", 1, 1, iconSize, iconSize, .75, 1, 0, 1)
|
||||
GameCooltip:AddStatusBar(0, 1, .5, .5, .5, .5, false, {value = 100, color = {.5, .5, .5, 1}, specialSpark = false, texture = [[Interface\AddOns\Details\images\bar4_vidro]]})
|
||||
|
||||
if (battleress) then
|
||||
local nome_magia, _, icone_magia = _GetSpellInfo(battleress [2])
|
||||
GameCooltip:AddLine("+" .. string.format("%.1f", battleress[4] - hora_da_morte) .. "s " .. nome_magia .. "(" .. battleress[6] .. ")", "", 1, "white")
|
||||
GameCooltip:AddIcon("Interface\\Glues\\CharacterSelect\\Glues-AddOn-Icons", 1, 1, nil, nil, .75, 1, 0, 1)
|
||||
GameCooltip:AddStatusBar(0, 1, .5, .5, .5, .5, false, {value = 100, color = {.5, .5, .5, 1}, specialSpark = false, texture = [[Interface\AddOns\Details\images\bar4_vidro]]})
|
||||
end
|
||||
|
||||
if (lastcooldown) then
|
||||
if (lastcooldown[3] == 1) then
|
||||
local nome_magia, _, icone_magia = _GetSpellInfo(lastcooldown [2])
|
||||
GameCooltip:AddLine(string.format("%.1f", lastcooldown[4] - hora_da_morte) .. "s " .. nome_magia .. "(" .. Loc ["STRING_LAST_COOLDOWN"] .. ")")
|
||||
GameCooltip:AddIcon(icone_magia)
|
||||
else
|
||||
GameCooltip:AddLine(Loc ["STRING_NOLAST_COOLDOWN"])
|
||||
GameCooltip:AddIcon([[Interface\CHARACTERFRAME\UI-Player-PlayTimeUnhealthy]], 1, 1, 18, 18)
|
||||
end
|
||||
GameCooltip:AddStatusBar(0, 1, 1, 1, 1, 1, false, {value = 100, color = {.3, .3, .3, 1}, specialSpark = false, texture = [[Interface\AddOns\Details\images\bar_serenity]]})
|
||||
end
|
||||
|
||||
--death log cooltip settings
|
||||
GameCooltip:SetOption("StatusBarHeightMod", -6)
|
||||
GameCooltip:SetOption("FixedWidth", 400)
|
||||
GameCooltip:SetOption("TextSize", 10)
|
||||
GameCooltip:SetOption("LeftBorderSize", -4)
|
||||
GameCooltip:SetOption("RightBorderSize", 5)
|
||||
GameCooltip:SetOption("StatusBarTexture", [[Interface\AddOns\Details\images\bar_serenity]])
|
||||
GameCooltip:SetBackdrop(1, Details.cooltip_preset2_backdrop, bgColor, borderColor)
|
||||
|
||||
GameCooltip:SetOwner(row, "bottomright", "bottomleft", -2, -50)
|
||||
row.OverlayTexture:Show()
|
||||
GameCooltip:ShowCooltip()
|
||||
end
|
||||
|
||||
--custom tooltip for dispells details ---------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
--custom tooltip for kick details ---------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
--custom tooltip clicks on any bar ---------------------------------------------------------------------------------------------------------
|
||||
function Details:BossInfoRowClick(barra, param1)
|
||||
|
||||
if (type(self) == "table") then
|
||||
barra, param1 = self, barra
|
||||
end
|
||||
|
||||
if (type(param1) == "table") then
|
||||
barra = param1
|
||||
end
|
||||
|
||||
if (barra._no_report) then
|
||||
return
|
||||
end
|
||||
|
||||
local reportar
|
||||
|
||||
if (barra.TTT == "morte" or true) then --deaths -- todos os boxes est�o usando cooltip, por isso o 'true'.
|
||||
|
||||
reportar = {barra.report_text .. " " ..(barra.lineText1 and barra.lineText1:GetText() or barra:GetParent() and barra:GetParent().lineText1 and barra:GetParent().lineText1:GetText() or "")}
|
||||
local beginAt = 1
|
||||
if (barra.TTT == "damage_taken" or barra.TTT == "habilidades_inimigas" or barra.TTT == "total_interrupt" or barra.TTT == "add") then
|
||||
beginAt = 2
|
||||
end
|
||||
--"habilidades_inimigas"
|
||||
for i = beginAt, GameCooltip:GetNumLines(), 1 do
|
||||
local texto_left, texto_right = GameCooltip:GetText(i)
|
||||
|
||||
if (texto_left and texto_right) then
|
||||
texto_left = texto_left:gsub(("|T(.*)|t "), "")
|
||||
reportar [#reportar+1] = ""..texto_left.." "..texto_right..""
|
||||
end
|
||||
end
|
||||
else
|
||||
|
||||
barra.report_text = barra.report_text or ""
|
||||
reportar = {barra.report_text .. " " .. _G.GameTooltipTextLeft1:GetText()}
|
||||
local numLines = GameTooltip:NumLines()
|
||||
|
||||
for i = 1, numLines, 1 do
|
||||
local nome_left = "GameTooltipTextLeft"..i
|
||||
local texto_left = _G[nome_left]
|
||||
texto_left = texto_left:GetText()
|
||||
|
||||
local nome_right = "GameTooltipTextRight"..i
|
||||
local texto_right = _G[nome_right]
|
||||
texto_right = texto_right:GetText()
|
||||
|
||||
if (texto_left and texto_right) then
|
||||
texto_left = texto_left:gsub(("|T(.*)|t "), "")
|
||||
reportar [#reportar+1] = ""..texto_left.." "..texto_right..""
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return Details:Reportar(reportar, {_no_current = true, _no_inverse = true, _custom = true})
|
||||
end
|
||||
|
||||
--custom tooltip that handle mouse enter and leave on customized rows ---------------------------------------------------------------------------------------------------------
|
||||
|
||||
local backdrop_bar_onenter = {bgFile = [[Interface\AddOns\Details\images\background]], tile = true, tileSize = 16, edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border", edgeSize = 8, insets = {left = 1, right = 1, top = 0, bottom = 1}}
|
||||
local backdrop_bar_onleave = {bgFile = [[Interface\AddOns\Details\images\background]], tile = true, tileSize = 16, insets = {left = 1, right = 1, top = 0, bottom = 1}}
|
||||
|
||||
function encounterDetails:SetRowScripts(barra, index, container)
|
||||
|
||||
barra:SetScript("OnMouseDown", function(self)
|
||||
if (self.fading_in) then
|
||||
return
|
||||
end
|
||||
|
||||
self.mouse_down = GetTime()
|
||||
local x, y = GetCursorPosition()
|
||||
self.x = math.floor(x)
|
||||
self.y = math.floor(y)
|
||||
|
||||
--EncounterDetailsFrame:StartMoving()
|
||||
edFrame.isMoving = true
|
||||
|
||||
end)
|
||||
|
||||
barra:SetScript("OnMouseUp", function(self)
|
||||
|
||||
if (self.fading_in) then
|
||||
return
|
||||
end
|
||||
|
||||
if (edFrame.isMoving) then
|
||||
--EncounterDetailsFrame:GetParent():StopMovingOrSizing()
|
||||
edFrame.isMoving = false
|
||||
--instancia:SaveMainWindowPosition() --precisa fazer algo pra salvar o trem
|
||||
end
|
||||
|
||||
local x, y = GetCursorPosition()
|
||||
x = math.floor(x)
|
||||
y = math.floor(y)
|
||||
|
||||
if ((self.mouse_down+0.4 > GetTime() and(x == self.x and y == self.y)) or(x == self.x and y == self.y)) then
|
||||
Details:BossInfoRowClick(self)
|
||||
end
|
||||
end)
|
||||
|
||||
barra:SetScript("OnEnter", --MOUSE OVER
|
||||
function(self)
|
||||
--aqui 1
|
||||
if (container.fading_in or container.faded) then
|
||||
return
|
||||
end
|
||||
|
||||
self.mouse_over = true
|
||||
self:SetHeight(encounterDetails.Frame.DefaultBarHeight + 1)
|
||||
self:SetAlpha(1)
|
||||
encounterDetails.SetBarBackdrop_OnEnter(self)
|
||||
|
||||
--GameTooltip:SetOwner(self, "ANCHOR_TOPRIGHT")
|
||||
GameCooltip:Preset(2)
|
||||
GameCooltip:SetOwner(self)
|
||||
encounterDetails:FormatCooltipSettings()
|
||||
|
||||
if (not self.TTT) then --tool tip type
|
||||
return
|
||||
end
|
||||
|
||||
if (self.TTT == "damage_taken") then --damage taken
|
||||
DamageTakenDetails(self.jogador, barra)
|
||||
|
||||
elseif (self.TTT == "habilidades_inimigas") then --enemy abilytes
|
||||
self.spellid = self.jogador [4]
|
||||
EnemySkills(self.jogador, self)
|
||||
|
||||
elseif (self.TTT == "total_interrupt") then
|
||||
self.spellid = self.jogador [3]
|
||||
KickBy(self.jogador, self)
|
||||
|
||||
elseif (self.TTT == "dispell") then
|
||||
self.spellid = self.jogador [3]
|
||||
DispellInfo(self.jogador, self)
|
||||
|
||||
elseif (self.TTT == "morte") then --deaths
|
||||
KillInfo(self.jogador, self) --aqui 2
|
||||
end
|
||||
|
||||
GameCooltip:Show()
|
||||
end)
|
||||
|
||||
barra:SetScript("OnLeave", --MOUSE OUT
|
||||
function(self)
|
||||
|
||||
self:SetScript("OnUpdate", nil)
|
||||
|
||||
if (self.fading_in or self.faded or not self:IsShown() or self.hidden) then
|
||||
return
|
||||
end
|
||||
|
||||
self:SetHeight(encounterDetails.Frame.DefaultBarHeight)
|
||||
self:SetAlpha(0.9)
|
||||
|
||||
encounterDetails.SetBarBackdrop_OnLeave(self)
|
||||
|
||||
GameTooltip:Hide()
|
||||
GameCooltip:Hide()
|
||||
|
||||
if (self.OverlayTexture) then
|
||||
self.OverlayTexture:Hide()
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
--Here start the data mine ---------------------------------------------------------------------------------------------------------
|
||||
function encounterDetails:OpenAndRefresh(_, segment)
|
||||
local segmentsDropdown = _G[edFrame:GetName() .. "SegmentsDropdown"]
|
||||
segmentsDropdown.MyObject:Refresh()
|
||||
encounterDetails.LastOpenedTime = GetTime()
|
||||
segmentsDropdown.MyObject:Refresh()
|
||||
|
||||
edFrame.ShowType = encounterDetails.db.last_section_selected
|
||||
|
||||
if (segment) then
|
||||
_combat_object = encounterDetails:GetCombat(segment)
|
||||
encounterDetails._segment = segment
|
||||
DebugMessage("there's a segment to use:", segment, _combat_object, _combat_object and _combat_object.is_boss)
|
||||
|
||||
else
|
||||
DebugMessage("no segment has been passed, looping segments to find one.")
|
||||
local segmentsTable = Details:GetCombatSegments()
|
||||
local foundABoss = false
|
||||
|
||||
for index, combatObject in ipairs(segmentsTable) do
|
||||
if (combatObject.is_boss and combatObject.is_boss.index) then
|
||||
encounterDetails._segment = index
|
||||
_combat_object = combatObject
|
||||
|
||||
DebugMessage("segment found: ", index, combatObject:GetCombatName(), combatObject.is_trash)
|
||||
--the first segment found here will be the first segment the dropdown found, so it can use the index 1 of the dropdown list
|
||||
_G [edFrame:GetName().."SegmentsDropdown"].MyObject:Select(1, true)
|
||||
|
||||
foundABoss = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if (not foundABoss) then
|
||||
DebugMessage("boss not found during the segment loop")
|
||||
end
|
||||
end
|
||||
|
||||
if (not _combat_object) then
|
||||
--EncounterDetails:Msg("no combat found.")
|
||||
DebugMessage("_combat_object is nil, EXIT")
|
||||
return
|
||||
end
|
||||
|
||||
if (not _combat_object.is_boss) then
|
||||
DebugMessage("_combat_object is not a boss, trying another loop in the segments")
|
||||
|
||||
local foundSegment
|
||||
for index, combat in ipairs(encounterDetails:GetCombatSegments()) do
|
||||
if (combat.is_boss and encounterDetails:GetBossDetails(combat.is_boss.mapid, combat.is_boss.index)) then
|
||||
_combat_object = combat
|
||||
|
||||
--the first segment found here will be the first segment the dropdown found, so it can use the index 1 of the dropdown list
|
||||
_G [edFrame:GetName() .. "SegmentsDropdown"].MyObject:Select(1, true)
|
||||
|
||||
DebugMessage("found another segment during another loop", index, combat:GetCombatName(), combat.is_trash)
|
||||
foundSegment = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if (not foundSegment) then
|
||||
DebugMessage("boss not found during the second loop segment")
|
||||
end
|
||||
|
||||
if (not _combat_object.is_boss) then
|
||||
DebugMessage("_combat_object still isn't a boss segment, trying to get the last segment shown.")
|
||||
if (encounterDetails.LastSegmentShown) then
|
||||
_combat_object = encounterDetails.LastSegmentShown
|
||||
DebugMessage("found the last segment shown, using it.")
|
||||
else
|
||||
DebugMessage("the segment isn't a boss, EXIT.")
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
encounterDetails.LastSegmentShown = _combat_object
|
||||
|
||||
encounterDetails.Frame.switch(edFrame.ShowType)
|
||||
|
||||
if (edFrame.ShowType == "phases") then
|
||||
EncounterDetailsPhaseFrame.OnSelectPhase(1)
|
||||
|
||||
elseif (edFrame.ShowType == "graph") then
|
||||
encounterDetails:ShowChartFrame()
|
||||
end
|
||||
|
||||
-------------- set boss name and zone name --------------
|
||||
edFrame.bossNameLabel:SetText(_combat_object.is_boss.encounter)
|
||||
edFrame.raidNameLabel:SetText(_combat_object.is_boss.zone)
|
||||
|
||||
-------------- set portrait and background image --------------
|
||||
|
||||
local mapID = _combat_object.is_boss.mapid
|
||||
local L, R, T, B, Texture = encounterDetails:GetBossIcon(mapID, _combat_object.is_boss.index)
|
||||
|
||||
if (L) then
|
||||
edFrame.bossIcon:SetTexture(Texture)
|
||||
edFrame.bossIcon:SetTexCoord(L, R, T, B)
|
||||
else
|
||||
edFrame.bossIcon:SetTexture([[Interface\CHARACTERFRAME\TempPortrait]])
|
||||
edFrame.bossIcon:SetTexCoord(0, 1, 0, 1)
|
||||
end
|
||||
|
||||
--[=[
|
||||
local file, L, R, T, B = EncounterDetails:GetRaidBackground(_combat_object.is_boss.mapid)
|
||||
if (file) then
|
||||
edFrame.raidBackgroundTexture:SetTexture(file)
|
||||
edFrame.raidBackgroundTexture:SetTexCoord(L, R, T, B)
|
||||
else
|
||||
edFrame.raidBackgroundTexture:SetTexture([[Interface\Glues\LOADINGSCREENS\LoadScreenDungeon]])
|
||||
edFrame.raidBackgroundTexture:SetTexCoord(0, 1, 120/512, 408/512)
|
||||
end
|
||||
--]=]
|
||||
|
||||
edFrame.raidBackgroundTexture:SetTexture(.3, .3, .3, .5)
|
||||
end
|
||||
|
||||
local events_to_track = {
|
||||
["SPELL_CAST_START"] = true, --not instant cast
|
||||
["SPELL_CAST_SUCCESS"] = true, --not instant cast
|
||||
["SPELL_AURA_APPLIED"] = true, --if is a debuff
|
||||
["SPELL_DAMAGE"] = true, --damage
|
||||
["SPELL_PERIODIC_DAMAGE"] = true, --dot damage
|
||||
["SPELL_HEAL"] = true, --healing
|
||||
["SPELL_PERIODIC_HEAL"] = true, --dot healing
|
||||
}
|
||||
|
||||
local enemy_spell_pool
|
||||
local CLEvents = function(self, event, ...)
|
||||
local time, token, hidding, who_serial, who_name, who_flags, who_flags2, alvo_serial, alvo_name, alvo_flags, alvo_flags2, spellid, spellname, school, aura_type = CombatLogGetCurrentEventInfo(...)
|
||||
|
||||
if (events_to_track [token] and bitBand(who_flags or 0x0, 0x00000060) ~= 0) then
|
||||
local t = enemy_spell_pool [spellid]
|
||||
if (not t) then
|
||||
t = {["token"] = {[token] = true}, ["source"] = who_name, ["school"] = school}
|
||||
if (token == "SPELL_AURA_APPLIED") then
|
||||
t.type = aura_type
|
||||
end
|
||||
enemy_spell_pool [spellid] = t
|
||||
return
|
||||
|
||||
elseif (t.token [token]) then
|
||||
return
|
||||
end
|
||||
|
||||
t.token [token] = true
|
||||
if (token == "SPELL_AURA_APPLIED") then
|
||||
t.type = aura_type
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local installPluginFunc = function()
|
||||
if (Details and Details.InstallOkey and Details:InstallOkey()) then
|
||||
--create widgets
|
||||
CreatePluginFrames(data)
|
||||
|
||||
local PLUGIN_MINIMAL_DETAILS_VERSION_REQUIRED = 1
|
||||
local PLUGIN_TYPE = "TOOLBAR"
|
||||
local PLUGIN_LOCALIZED_NAME = Loc ["STRING_PLUGIN_NAME"]
|
||||
local PLUGIN_ICON = [[Interface\Scenarios\ScenarioIcon-Boss]]
|
||||
local PLUGIN_AUTHOR = "Terciob"
|
||||
local PLUGIN_VERSION = "v1.06"
|
||||
|
||||
local defaultSettings = {
|
||||
show_icon = 5, --automatic
|
||||
hide_on_combat = false, --hide the window when a new combat start
|
||||
max_emote_segments = 3,
|
||||
opened = 0,
|
||||
encounter_timers_dbm = {},
|
||||
encounter_timers_bw = {},
|
||||
window_scale = 1,
|
||||
last_section_selected = "main",
|
||||
}
|
||||
|
||||
--install
|
||||
local install, saveddata, isEnabled = Details:InstallPlugin(
|
||||
PLUGIN_TYPE,
|
||||
PLUGIN_LOCALIZED_NAME,
|
||||
PLUGIN_ICON,
|
||||
encounterDetails,
|
||||
PLUGIN_REAL_NAME,
|
||||
PLUGIN_MINIMAL_DETAILS_VERSION_REQUIRED,
|
||||
PLUGIN_AUTHOR,
|
||||
PLUGIN_VERSION,
|
||||
defaultSettings
|
||||
)
|
||||
|
||||
if (type(install) == "table" and install.error) then
|
||||
print(install.error)
|
||||
end
|
||||
|
||||
encounterDetails.charsaved = EncounterDetailsDB or {emotes = {}, chartData = {}}
|
||||
EncounterDetailsDB = encounterDetails.charsaved
|
||||
|
||||
EncounterDetailsDB.chartData = EncounterDetailsDB.chartData or {}
|
||||
EncounterDetailsDB.emotes = EncounterDetailsDB.emotes or {}
|
||||
|
||||
--make a cleanup on saved charts
|
||||
local now = time()
|
||||
for combatUniqueId, charts in pairs(EncounterDetailsDB.chartData) do
|
||||
--check if details! still have a combat with the same id
|
||||
local bCombatExists = Details:DoesCombatWithUIDExists(combatUniqueId)
|
||||
if (not bCombatExists) then
|
||||
EncounterDetailsDB.chartData[combatUniqueId] = nil
|
||||
else
|
||||
--check if the data is already 48hrs old
|
||||
for chartName, chartData in pairs(charts) do
|
||||
if (chartData.__time) then
|
||||
if (now - chartData.__time > 60*60*24*2) then
|
||||
charts[chartName] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
encounterDetails.charsaved.encounter_spells = encounterDetails.charsaved.encounter_spells or {}
|
||||
encounterDetails.boss_emotes_table = encounterDetails.charsaved.emotes
|
||||
|
||||
--build a table on global saved variables
|
||||
if (not Details.global_plugin_database["DETAILS_PLUGIN_ENCOUNTER_DETAILS"]) then
|
||||
Details.global_plugin_database["DETAILS_PLUGIN_ENCOUNTER_DETAILS"] = {encounter_timers_dbm = {}, encounter_timers_bw= {}}
|
||||
end
|
||||
|
||||
--Register needed events
|
||||
Details:RegisterEvent(encounterDetails, "COMBAT_PLAYER_ENTER")
|
||||
Details:RegisterEvent(encounterDetails, "COMBAT_PLAYER_LEAVE")
|
||||
Details:RegisterEvent(encounterDetails, "COMBAT_BOSS_FOUND")
|
||||
Details:RegisterEvent(encounterDetails, "DETAILS_DATA_RESET")
|
||||
Details:RegisterEvent(encounterDetails, "GROUP_ONENTER")
|
||||
Details:RegisterEvent(encounterDetails, "GROUP_ONLEAVE")
|
||||
Details:RegisterEvent(encounterDetails, "ZONE_TYPE_CHANGED")
|
||||
|
||||
edFrame:RegisterEvent("ENCOUNTER_START")
|
||||
edFrame:RegisterEvent("ENCOUNTER_END")
|
||||
encounterDetails.EnemySpellPool = encounterDetails.charsaved.encounter_spells
|
||||
enemy_spell_pool = encounterDetails.EnemySpellPool
|
||||
encounterDetails.CLEvents = CreateFrame("frame", nil, UIParent, "BackdropTemplate")
|
||||
encounterDetails.CLEvents:SetScript("OnEvent", CLEvents)
|
||||
encounterDetails.CLEvents:Hide()
|
||||
|
||||
encounterDetails.BossWhispColors = {
|
||||
[1] = "RAID_BOSS_EMOTE",
|
||||
[2] = "RAID_BOSS_WHISPER",
|
||||
[3] = "MONSTER_EMOTE",
|
||||
[4] = "MONSTER_SAY",
|
||||
[5] = "MONSTER_WHISPER",
|
||||
[6] = "MONSTER_PARTY",
|
||||
[7] = "MONSTER_YELL",
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
function encounterDetails:OnEvent(self, event, ...)
|
||||
if (event == "ENCOUNTER_START") then
|
||||
--tracks if a enemy spell is instant cast
|
||||
encounterDetails.CLEvents:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
|
||||
|
||||
elseif (event == "ENCOUNTER_END") then
|
||||
encounterDetails.CLEvents:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
|
||||
|
||||
elseif (event == "ADDON_LOADED") then
|
||||
local addonName = select(1, ...)
|
||||
if (addonName == "Details_EncounterDetails") then
|
||||
C_Timer.After(1, installPluginFunc)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,22 @@
|
||||
## Interface: 30300
|
||||
## Title: Details!: Encounter Breakdown (plugin)
|
||||
## Notes: Show detailed information about a boss encounter. Also provide damage per phase, graphic charts, easy weakauras creation.
|
||||
## RequiredDeps: Details
|
||||
## DefaultState: disabled
|
||||
## OptionalDeps: Ace3
|
||||
## SavedVariablesPerCharacter: EncounterDetailsDB
|
||||
## X-IconTexture: Interface\AddOns\Details\images\minimap
|
||||
|
||||
## X-Wago-ID: 7nGvv0Gx
|
||||
|
||||
enUS.lua
|
||||
ptBR.lua
|
||||
|
||||
Details_EncounterDetails.lua
|
||||
frames_chart.lua
|
||||
frames_emote.lua
|
||||
frames_phases.lua
|
||||
frames_summary.lua
|
||||
frames.lua
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
---@class ed_barline : button
|
||||
---@field statusBar statusbar
|
||||
---@field lineText1 fontstring
|
||||
---@field lineText4 fontstring
|
||||
---@field statusBarTexture texture
|
||||
---@field Icon texture
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
|
||||
..\FrameXML\UI.xsd">
|
||||
</Ui>
|
||||
@@ -0,0 +1,68 @@
|
||||
local Loc = LibStub("AceLocale-3.0"):NewLocale("Details_EncounterDetails", "enUS", true)
|
||||
|
||||
if (not Loc) then
|
||||
return
|
||||
end
|
||||
|
||||
Loc ["STRING_PLUGIN_NAME"] = "Encounter Breakdown"
|
||||
Loc ["STRING_WINDOW_TITLE"] = "Details! Encounter Breakdown"
|
||||
Loc ["STRING_TOTAL_DAMAGE"] = "Total Damage"
|
||||
Loc ["STRING_TOTAL_HEAL"] = "Total Heal"
|
||||
Loc ["STRING_SHOW_ALL_DATA"] = "Show overall data"
|
||||
Loc ["STRING_SHOW_PHASE_DATA"] = "Show details for this phase"
|
||||
Loc ["STRING_NOT IMPLEMENTED"] = "Not implemented yet"
|
||||
Loc ["STRING_DIED"] = "died"
|
||||
Loc ["STRING_MELEE_DAMAGE"] = "melee damage"
|
||||
Loc ["STRING_DAMAGE_TAKEN_REPORT"] = "Damage taken by"
|
||||
Loc ["STRING_ABILITY_DAMAGE"] = "Ability damage"
|
||||
Loc ["STRING_DAMAGE_TAKEN"] = "Damage Taken"
|
||||
Loc ["STRING_TOOK_DAMAGE_FROM"] = "Took damage from"
|
||||
Loc ["STRING_INTERRUPT_BY"] = "interrupted by"
|
||||
Loc ["STRING_DISPELLED_BY"] = "dispelled by"
|
||||
Loc ["STRING_DEAD_LOG"] = "last seconds of"
|
||||
Loc ["STRING_CURRENT"] = "Current"
|
||||
Loc ["STRING_TRY"] = "Fight"
|
||||
Loc ["STRING_DAMAGE_AT"] = "Damage Taken"
|
||||
Loc ["STRING_INFLICTED_BY"] = "Damage inflicted by"
|
||||
Loc ["STRING_INFLICTED"] = "Damage inflicted"
|
||||
Loc ["STRING_ADDS"] = "Adds"
|
||||
Loc ["STRING_INTERRUPTS"] = "Interrupts"
|
||||
Loc ["STRING_INTERRUPTS_OF"] = "Interrupts of"
|
||||
Loc ["STRING_DISPELLS_OF"] = "dispells of"
|
||||
Loc ["STRING_DISPELLS"] = "Dispels"
|
||||
Loc ["STRING_DEATH_LOG"] = "Death Log"
|
||||
Loc ["STRING_FIGHT_SUMMARY"] = "Encounter Summary"
|
||||
Loc ["STRING_FIGHT_GRAPHIC"] = "Encounter Charts and Phases"
|
||||
Loc ["STRING_FIGHT_EMOTES"] = "Encounter Emotes"
|
||||
Loc ["STRING_FIGHT_SPELLS"] = "Encounter Spells and Auras"
|
||||
Loc ["STRING_TOOLTIP"] = "Show Encounter Details Window"
|
||||
Loc ["STRING_LAST_COOLDOWN"] = "last cooldown used"
|
||||
Loc ["STRING_NOLAST_COOLDOWN"] = "no cooldown used"
|
||||
|
||||
Loc ["STRING_BOSS_NOT_REGISTRED"] = "This encounter isn't registred on Details!\nMake sure this raid is enabled over addon control panel on the character selection screen."
|
||||
|
||||
Loc ["STRING_HOLDSHIFT"] = "SHIFT For Spell Description"
|
||||
|
||||
Loc ["STRING_ADDS_HELP"] = "Mouse over |cFF00FF00Arrow Up|r\nfor dmg received, |cFFFF0000Arrow\n|cFFFF0000Down|r for dmg dealt. |cFFFFFF00Click\n|cFFFFFF00Arrow|r: Report the data\nshown on tooltip."
|
||||
Loc ["STRING_INTERRIPT_HELP"] = " |cFFFFFF00Click|r on a bar:\nopen report window.\nIn the right we have the\namount interrupted against\nthe total times casted."
|
||||
Loc ["STRING_DISPELL_HELP"] = " \n|cFFFFFF00Click|r on a bar:\nopen report window."
|
||||
Loc ["STRING_DEATHS_HELP"] = " \n|cFFFFFF00Click|r on a bar:\nopen report window."
|
||||
|
||||
--mechanic types
|
||||
Loc ["STRING_HEAL"] = "heal"
|
||||
Loc ["STRING_LOWDPS"] = "lowdps"
|
||||
Loc ["STRING_LOWHEAL"] = "lowheal"
|
||||
Loc ["STRING_VOIDZONE"] = "voidzone"
|
||||
Loc ["STRING_DISPELL"] = "dispell"
|
||||
Loc ["STRING_INTERRUPT"] = "interrupt"
|
||||
Loc ["STRING_POSITIONING"] = "positioning"
|
||||
Loc ["STRING_RUNAWAY"] = "runaway"
|
||||
Loc ["STRING_TANKSWITCH"] = "tankswitch"
|
||||
Loc ["STRING_MECHANIC"] = "mechanic"
|
||||
Loc ["STRING_CROWDCONTROL"] = "cc"
|
||||
Loc ["STRING_TANKCOOLDOWN"] = "tankcooldown"
|
||||
Loc ["STRING_KILLADD"] = "killadd"
|
||||
Loc ["STRING_SPREADOUT"] = "spreadout"
|
||||
Loc ["STRING_STOPCAST"] = "stopcast"
|
||||
Loc ["STRING_FACING"] = "facing"
|
||||
Loc ["STRING_STACK"] = "stack"
|
||||
@@ -0,0 +1,526 @@
|
||||
do
|
||||
local addonId, edTable = ...
|
||||
local Details = _G._detalhes
|
||||
local AceLocale = LibStub("AceLocale-3.0")
|
||||
local Loc = AceLocale:GetLocale("Details_EncounterDetails")
|
||||
local Graphics = LibStub:GetLibrary("LibGraph-2.0")
|
||||
local ipairs = ipairs
|
||||
local _GetSpellInfo = Details.getspellinfo
|
||||
local unpack = unpack
|
||||
local detailsFramework = DetailsFramework
|
||||
local CreateFrame = CreateFrame
|
||||
local GameCooltip = GameCooltip
|
||||
local _
|
||||
|
||||
Details.EncounterDetailsTempWindow = function(encounterDetails)
|
||||
--options panel
|
||||
encounterDetails.SetBarBackdrop_OnEnter = function(self)
|
||||
self:SetBackdropColor(unpack(edTable.defaultBackgroundColor_OnEnter))
|
||||
end
|
||||
|
||||
encounterDetails.SetBarBackdrop_OnLeave = function(self)
|
||||
self:SetBackdropColor(unpack(edTable.defaultBackgroundColor))
|
||||
end
|
||||
|
||||
function encounterDetails:AutoShowIcon()
|
||||
local bFoundBoss = false
|
||||
for _, combatObject in ipairs(encounterDetails:GetCombatSegments()) do
|
||||
---@cast combatObject combat
|
||||
if (combatObject.is_boss) then
|
||||
encounterDetails:ShowIcon()
|
||||
bFoundBoss = true
|
||||
end
|
||||
end
|
||||
|
||||
if (encounterDetails:GetCurrentCombat().is_boss) then
|
||||
encounterDetails:ShowIcon()
|
||||
bFoundBoss = true
|
||||
end
|
||||
|
||||
if (not bFoundBoss) then
|
||||
encounterDetails:HideIcon()
|
||||
end
|
||||
end
|
||||
|
||||
local buildOptionsPanel = function()
|
||||
local pluginIcon = "Interface\\AddOns\\Details_EncounterDetails\\images\\icon"
|
||||
local pluginIconCoords = {0.15, 0.85, 0.15, 0.85}
|
||||
local optionsFrame = encounterDetails:CreatePluginOptionsFrame("EncounterDetailsOptionsWindow", "Encounter Breakdown Options", 3, pluginIcon, pluginIconCoords)
|
||||
-- 1 = only when inside a raid map
|
||||
-- 2 = only when in raid group
|
||||
-- 3 = only after a boss encounter
|
||||
-- 4 = always show
|
||||
-- 5 = automatic show when have at least 1 encounter with boss
|
||||
|
||||
local onShowIconCallback = function(_, _, value)
|
||||
encounterDetails.db.show_icon = value
|
||||
if (value == 1) then
|
||||
if (encounterDetails:GetZoneType() == "raid") then
|
||||
encounterDetails:ShowIcon()
|
||||
else
|
||||
encounterDetails:HideIcon()
|
||||
end
|
||||
|
||||
elseif (value == 2) then
|
||||
if (encounterDetails:InGroup()) then
|
||||
encounterDetails:ShowIcon()
|
||||
else
|
||||
encounterDetails:HideIcon()
|
||||
end
|
||||
|
||||
elseif (value == 3) then
|
||||
if (encounterDetails:GetCurrentCombat().is_boss) then
|
||||
encounterDetails:ShowIcon()
|
||||
else
|
||||
encounterDetails:HideIcon()
|
||||
end
|
||||
|
||||
elseif (value == 4) then
|
||||
encounterDetails:ShowIcon()
|
||||
|
||||
elseif (value == 5) then
|
||||
encounterDetails:AutoShowIcon()
|
||||
end
|
||||
end
|
||||
|
||||
local on_show_menu = {
|
||||
{value = 1, label = "Inside Raid", onclick = onShowIconCallback, desc = "Only show the icon while inside a raid."},
|
||||
{value = 2, label = "In Group", onclick = onShowIconCallback, desc = "Only show the icon while in group."},
|
||||
{value = 3, label = "After Encounter", onclick = onShowIconCallback, desc = "Show the icon after a raid boss encounter."},
|
||||
{value = 4, label = "Always", onclick = onShowIconCallback, desc = "Always show the icon."},
|
||||
{value = 5, label = "Auto", onclick = onShowIconCallback, desc = "The plugin decides when the icon needs to be shown."},
|
||||
}
|
||||
|
||||
--/dump DETAILS_PLUGIN_ENCOUNTER_DETAILS.db.show_icon
|
||||
|
||||
local menu = {
|
||||
{
|
||||
type = "select",
|
||||
get = function() return encounterDetails.db.show_icon end,
|
||||
values = function() return on_show_menu end,
|
||||
desc = "When the icon is shown in the Details! tooltip.",
|
||||
name = "Show Icon"
|
||||
},
|
||||
{
|
||||
type = "toggle",
|
||||
get = function() return encounterDetails.db.hide_on_combat end,
|
||||
set = function(self, fixedparam, value) encounterDetails.db.hide_on_combat = value end,
|
||||
desc = "Encounter Breakdown window automatically close when you enter in combat.",
|
||||
name = "Hide on Combat"
|
||||
},
|
||||
{
|
||||
type = "range",
|
||||
get = function() return encounterDetails.db.max_emote_segments end,
|
||||
set = function(self, fixedparam, value) encounterDetails.db.max_emote_segments = value end,
|
||||
min = 1,
|
||||
max = 10,
|
||||
step = 1,
|
||||
desc = "Keep how many segments emotes.",
|
||||
name = "Emote Segments Amount",
|
||||
usedecimals = true,
|
||||
},
|
||||
{
|
||||
type = "range",
|
||||
get = function() return encounterDetails.db.window_scale end,
|
||||
set = function(self, fixedparam, value) encounterDetails.db.window_scale = value; encounterDetails:RefreshScale() end,
|
||||
min = 0.65,
|
||||
max = 1.50,
|
||||
step = 0.1,
|
||||
desc = "Set the window size",
|
||||
name = "Window Scale",
|
||||
usedecimals = true,
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
local options_text_template = detailsFramework:GetTemplate("font", "OPTIONS_FONT_TEMPLATE")
|
||||
local options_dropdown_template = detailsFramework:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE")
|
||||
local options_switch_template = detailsFramework:GetTemplate("switch", "OPTIONS_CHECKBOX_TEMPLATE")
|
||||
local options_slider_template = detailsFramework:GetTemplate("slider", "OPTIONS_SLIDER_TEMPLATE")
|
||||
local options_button_template = detailsFramework:GetTemplate("button", "OPTIONS_BUTTON_TEMPLATE")
|
||||
|
||||
detailsFramework:BuildMenu(optionsFrame, menu, 15, -75, 260, false, options_text_template, options_dropdown_template, options_switch_template, true, options_slider_template, options_button_template)
|
||||
end
|
||||
|
||||
encounterDetails.OpenOptionsPanel = function()
|
||||
if (not EncounterDetailsOptionsWindow) then
|
||||
buildOptionsPanel()
|
||||
end
|
||||
EncounterDetailsOptionsWindow:Show()
|
||||
end
|
||||
|
||||
function encounterDetails:RefreshScale()
|
||||
local scale = encounterDetails.db.window_scale
|
||||
if (encounterDetails.Frame) then
|
||||
encounterDetails.Frame:SetScale(scale)
|
||||
end
|
||||
end
|
||||
|
||||
-- ~start ~main ~frame ~baseframe ~bossframe
|
||||
local edFrame = encounterDetails.Frame
|
||||
detailsFramework:ApplyStandardBackdrop(edFrame)
|
||||
edFrame:SetFrameStrata("high")
|
||||
edFrame:SetToplevel(true)
|
||||
edFrame:SetWidth(898)
|
||||
edFrame:SetHeight(504)
|
||||
edFrame:EnableMouse(true)
|
||||
edFrame:SetResizable(false)
|
||||
edFrame:SetMovable(true)
|
||||
edFrame:SetPoint("center", UIParent, "center", 0, 0)
|
||||
|
||||
--background
|
||||
edFrame.bosFrameBackgroundTexture = edFrame:CreateTexture(nil, "background")
|
||||
edFrame.bosFrameBackgroundTexture:SetTexture([[Interface\AddOns\Details\images\background]], true)
|
||||
edFrame.bosFrameBackgroundTexture:SetAlpha(0.7)
|
||||
edFrame.bosFrameBackgroundTexture:SetVertexColor(0.27, 0.27, 0.27)
|
||||
edFrame.bosFrameBackgroundTexture:SetVertTile(true)
|
||||
edFrame.bosFrameBackgroundTexture:SetHorizTile(true)
|
||||
edFrame.bosFrameBackgroundTexture:SetSize(790, 454)
|
||||
edFrame.bosFrameBackgroundTexture:SetAllPoints()
|
||||
|
||||
--title bar
|
||||
local titleBar = detailsFramework:CreateTitleBar(edFrame, Loc ["STRING_WINDOW_TITLE"])
|
||||
titleBar.CloseButton:Hide()
|
||||
|
||||
--close button
|
||||
titleBar.CloseButton = detailsFramework:CreateCloseButton(titleBar)
|
||||
titleBar.CloseButton:SetScript("OnClick", function(self)
|
||||
encounterDetails:CloseWindow()
|
||||
end)
|
||||
|
||||
titleBar.CloseButton:SetPoint("right", titleBar, "right", -2, 0)
|
||||
|
||||
--header background
|
||||
local headerFrame = CreateFrame("frame", "EncounterDetailsHeaderFrame", edFrame, "BackdropTemplate")
|
||||
headerFrame:EnableMouse(false)
|
||||
headerFrame:SetPoint("topleft", titleBar, "bottomleft", -1, -1)
|
||||
headerFrame:SetPoint("topright", titleBar, "bottomright", 1, -1)
|
||||
headerFrame:SetBackdrop({bgFile = [[Interface\AddOns\Details\images\background]], tileSize = 64, tile = true})
|
||||
headerFrame:SetBackdropColor(.7, .7, .7, .4)
|
||||
headerFrame:SetHeight(48)
|
||||
|
||||
edFrame.raidBackgroundTexture = edFrame:CreateTexture(nil, "border")
|
||||
edFrame.raidBackgroundTexture:SetPoint("topleft", edFrame, "topleft", 0, -74)
|
||||
edFrame.raidBackgroundTexture:SetPoint("bottomright", edFrame, "bottomright", 0, 0)
|
||||
edFrame.raidBackgroundTexture:SetDrawLayer("border", 2)
|
||||
edFrame.raidBackgroundTexture:SetAlpha(0.1)
|
||||
|
||||
local gradientBelow = detailsFramework:CreateTexture(headerFrame,
|
||||
{gradient = "vertical", fromColor = {0, 0, 0, 0.5}, toColor = "transparent"}, 1, 48, "artwork", {0, 1, 0, 1})
|
||||
gradientBelow:SetPoint("bottoms", 1, 1)
|
||||
|
||||
--boss icon in the top left corner
|
||||
edFrame.bossIcon = headerFrame:CreateTexture(nil, "overlay")
|
||||
edFrame.bossIcon:SetPoint("topleft", edFrame, "topleft", 9, -24)
|
||||
edFrame.bossIcon:SetWidth(46)
|
||||
edFrame.bossIcon:SetHeight(46)
|
||||
|
||||
--raid name
|
||||
detailsFramework:NewLabel(headerFrame, headerFrame, nil, "raidNameLabel", "Unknown Raid", "GameFontHighlightSmall")
|
||||
edFrame.raidNameLabel = headerFrame.raidNameLabel
|
||||
edFrame.raidNameLabel:SetPoint("topleft", edFrame, "topleft", 60, -34)
|
||||
|
||||
--encounter name
|
||||
detailsFramework:NewLabel(headerFrame, headerFrame, nil, "bossNameLabel", "Unknown Encounter", "QuestFont_Large")
|
||||
edFrame.bossNameLabel = headerFrame.bossNameLabel
|
||||
edFrame.bossNameLabel:SetPoint("topleft", edFrame.raidNameLabel, "bottomleft", 0, -2)
|
||||
|
||||
edFrame.bossIcon:Hide()
|
||||
edFrame.raidNameLabel.show = false
|
||||
edFrame.bossNameLabel.show = false
|
||||
|
||||
edFrame:SetScript("OnMouseDown", function(self, button)
|
||||
if (button == "LeftButton") then
|
||||
self:StartMoving()
|
||||
self.isMoving = true
|
||||
|
||||
elseif (button == "RightButton" and not self.isMoving) then
|
||||
encounterDetails:CloseWindow()
|
||||
end
|
||||
end)
|
||||
|
||||
edFrame:SetScript("OnMouseUp", function(self)
|
||||
if (self.isMoving) then
|
||||
self:StopMovingOrSizing()
|
||||
self.isMoving = false
|
||||
end
|
||||
end)
|
||||
|
||||
edFrame.ShowType = "main"
|
||||
|
||||
--> revisar
|
||||
edFrame.Reset = function()
|
||||
edFrame.switch(nil, nil, "main")
|
||||
if (encounterDetails.chartPanel) then
|
||||
encounterDetails.chartPanel:ResetData()
|
||||
end
|
||||
edFrame.linhas = nil
|
||||
end
|
||||
|
||||
local hide_Graph = function()
|
||||
if (encounterDetails.chartPanel) then
|
||||
encounterDetails.chartPanel:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
local hide_Emote = function()
|
||||
for _, widget in pairs(edFrame.EmoteWidgets) do
|
||||
widget:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
local hide_Summary = function()
|
||||
for _, frame in ipairs(edFrame.encounterSummaryWidgets) do
|
||||
frame:Hide()
|
||||
|
||||
frame:SetScript("OnShow", function()
|
||||
--print(debugstack())
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
local resetSelectedButtonTemplate = function()
|
||||
edFrame.buttonSwitchNormal:SetTemplate(detailsFramework:GetTemplate("button", "DETAILS_PLUGIN_BUTTON_TEMPLATE"))
|
||||
edFrame.buttonSwitchPhases:SetTemplate(detailsFramework:GetTemplate("button", "DETAILS_PLUGIN_BUTTON_TEMPLATE"))
|
||||
edFrame.buttonSwitchGraphic:SetTemplate(detailsFramework:GetTemplate("button", "DETAILS_PLUGIN_BUTTON_TEMPLATE"))
|
||||
edFrame.buttonSwitchBossEmotes:SetTemplate(detailsFramework:GetTemplate("button", "DETAILS_PLUGIN_BUTTON_TEMPLATE"))
|
||||
end
|
||||
|
||||
edFrame.switch = function(buttonObject, _, tabName)
|
||||
local tabSelected
|
||||
if (type(buttonObject) == "string") then
|
||||
tabSelected = buttonObject
|
||||
|
||||
elseif (type(tabName) == "string") then
|
||||
tabSelected = tabName
|
||||
end
|
||||
|
||||
if (not edFrame:IsShown()) then
|
||||
Details:OpenPlugin("DETAILS_PLUGIN_ENCOUNTER_DETAILS")
|
||||
end
|
||||
|
||||
EncounterDetailsPhaseFrame:Hide()
|
||||
resetSelectedButtonTemplate()
|
||||
|
||||
if (tabSelected == "main") then
|
||||
edFrame.raidBackgroundTexture:Show()
|
||||
|
||||
for _, frame in ipairs(edFrame.encounterSummaryWidgets) do
|
||||
frame:Show()
|
||||
end
|
||||
|
||||
hide_Graph()
|
||||
hide_Emote()
|
||||
|
||||
edFrame.ShowType = "main"
|
||||
edFrame.segmentsDropdown:Enable()
|
||||
edFrame.buttonSwitchNormal:SetTemplate(detailsFramework:GetTemplate("button", "DETAILS_PLUGIN_BUTTONSELECTED_TEMPLATE"))
|
||||
encounterDetails.db.last_section_selected = edFrame.ShowType
|
||||
|
||||
if (encounterDetails.LastSegmentShown) then
|
||||
encounterDetails.RefreshSummaryPage(encounterDetails.LastSegmentShown)
|
||||
else
|
||||
encounterDetails.RefreshSummaryPage(Details:GetCurrentCombat())
|
||||
end
|
||||
|
||||
elseif (tabSelected == "emotes") then
|
||||
Details:SetTutorialCVar("ENCOUNTER_BREAKDOWN_EMOTES", true)
|
||||
if (encounterDetails.Frame.buttonSwitchBossEmotes.AntsFrame) then
|
||||
encounterDetails.Frame.buttonSwitchBossEmotes.AntsFrame:Hide()
|
||||
end
|
||||
|
||||
--hide boss frames
|
||||
for _, frame in ipairs(edFrame.encounterSummaryWidgets) do
|
||||
frame:Hide()
|
||||
end
|
||||
|
||||
edFrame.raidBackgroundTexture:Show()
|
||||
|
||||
--hide graph
|
||||
if (encounterDetails.chartPanel) then
|
||||
encounterDetails.chartPanel:Hide()
|
||||
end
|
||||
|
||||
--show emote frames
|
||||
for _, widget in pairs(edFrame.EmoteWidgets) do
|
||||
widget:Show()
|
||||
end
|
||||
|
||||
edFrame.ShowType = "emotes"
|
||||
encounterDetails.EmoteScrollFrame:Update()
|
||||
edFrame.EmotesSegment:Refresh()
|
||||
edFrame.EmotesSegment:Select(encounterDetails.emoteSegmentIndex)
|
||||
edFrame.segmentsDropdown:Disable()
|
||||
edFrame.buttonSwitchBossEmotes:SetTemplate(detailsFramework:GetTemplate("button", "DETAILS_PLUGIN_BUTTONSELECTED_TEMPLATE"))
|
||||
encounterDetails.db.last_section_selected = edFrame.ShowType
|
||||
|
||||
elseif (tabSelected == "phases") then
|
||||
Details:SetTutorialCVar("ENCOUNTER_BREAKDOWN_PHASES", true)
|
||||
if (encounterDetails.Frame.buttonSwitchPhases.AntsFrame) then
|
||||
encounterDetails.Frame.buttonSwitchPhases.AntsFrame:Hide()
|
||||
end
|
||||
|
||||
hide_Summary()
|
||||
hide_Graph()
|
||||
hide_Emote()
|
||||
|
||||
edFrame.ShowType = "phases"
|
||||
|
||||
EncounterDetailsPhaseFrame:Show()
|
||||
|
||||
edFrame.buttonSwitchPhases:SetTemplate(detailsFramework:GetTemplate("button", "DETAILS_PLUGIN_BUTTONSELECTED_TEMPLATE"))
|
||||
|
||||
encounterDetails.db.last_section_selected = edFrame.ShowType
|
||||
|
||||
elseif (tabSelected == "graph") then
|
||||
Details:SetTutorialCVar("ENCOUNTER_BREAKDOWN_CHART", true)
|
||||
if (encounterDetails.Frame.buttonSwitchGraphic.AntsFrame) then
|
||||
encounterDetails.Frame.buttonSwitchGraphic.AntsFrame:Hide()
|
||||
end
|
||||
|
||||
encounterDetails:ShowChartFrame()
|
||||
|
||||
if (not encounterDetails.chartPanel) then
|
||||
return
|
||||
end
|
||||
|
||||
edFrame.raidBackgroundTexture:Hide()
|
||||
|
||||
for _, frame in ipairs(edFrame.encounterSummaryWidgets) do
|
||||
frame:Hide()
|
||||
end
|
||||
|
||||
encounterDetails.chartPanel:Show()
|
||||
edFrame.ShowType = "graph"
|
||||
|
||||
--hide emote frames
|
||||
for _, widget in pairs(edFrame.EmoteWidgets) do
|
||||
widget:Hide()
|
||||
end
|
||||
|
||||
edFrame.segmentsDropdown:Enable()
|
||||
edFrame.buttonSwitchGraphic:SetTemplate(detailsFramework:GetTemplate("button", "DETAILS_PLUGIN_BUTTONSELECTED_TEMPLATE"))
|
||||
encounterDetails.db.last_section_selected = edFrame.ShowType
|
||||
end
|
||||
end
|
||||
|
||||
-- ~button ~menu
|
||||
local BUTTON_WIDTH = 120
|
||||
local BUTTON_HEIGHT = 20
|
||||
local HEADER_MENUBUTTONS_SPACEMENT = 4
|
||||
local HEADER_MENUBUTTONS_X = 290
|
||||
local HEADER_MENUBUTTONS_Y = -38
|
||||
|
||||
--create selection tab buttons
|
||||
do
|
||||
--summary
|
||||
edFrame.buttonSwitchNormal = detailsFramework:CreateButton(edFrame, edFrame.switch, BUTTON_WIDTH, BUTTON_HEIGHT, "Summary", "main")
|
||||
edFrame.buttonSwitchNormal:SetIcon("Interface\\AddOns\\Details_EncounterDetails\\images\\boss_frame_buttons", 18, 18, "overlay", {0, 32/256, 0, 0.505625})
|
||||
edFrame.buttonSwitchNormal:SetTemplate(detailsFramework:GetTemplate("button", "DETAILS_PLUGIN_BUTTONSELECTED_TEMPLATE"))
|
||||
edFrame.buttonSwitchNormal:SetWidth(BUTTON_WIDTH)
|
||||
--summary for the breakdown window
|
||||
edFrame.buttonSwitchNormalBreakdown = detailsFramework:CreateButton(edFrame, edFrame.switch, BUTTON_WIDTH, BUTTON_HEIGHT, "Summary", "main")
|
||||
edFrame.buttonSwitchNormalBreakdown:SetIcon("Interface\\AddOns\\Details_EncounterDetails\\images\\boss_frame_buttons", 18, 18, "overlay", {0, 32/256, 0, 0.505625})
|
||||
edFrame.buttonSwitchNormalBreakdown:SetTemplate(detailsFramework:GetTemplate("button", "DETAILS_PLUGIN_BUTTONSELECTED_TEMPLATE"))
|
||||
edFrame.buttonSwitchNormalBreakdown:SetWidth(BUTTON_WIDTH)
|
||||
_G.DetailsBreakdownWindow.RegisterPluginButton(edFrame.buttonSwitchNormalBreakdown, edTable.PluginObject, edTable.PluginAbsoluteName)
|
||||
|
||||
--phases
|
||||
edFrame.buttonSwitchPhases = detailsFramework:CreateButton(edFrame, edFrame.switch, BUTTON_WIDTH, BUTTON_HEIGHT, "Phases", "phases")
|
||||
edFrame.buttonSwitchPhases:SetIcon("Interface\\AddOns\\Details_EncounterDetails\\images\\boss_frame_buttons", 18, 18, "overlay", {65/256, 96/256, 0, 0.505625})
|
||||
edFrame.buttonSwitchPhases:SetTemplate(detailsFramework:GetTemplate("button", "DETAILS_PLUGIN_BUTTON_TEMPLATE"))
|
||||
edFrame.buttonSwitchPhases:SetWidth(BUTTON_WIDTH)
|
||||
--phases for the breakdown window
|
||||
edFrame.buttonSwitchPhasesBreakdown = detailsFramework:CreateButton(edFrame, edFrame.switch, BUTTON_WIDTH, BUTTON_HEIGHT, "Phases", "phases")
|
||||
edFrame.buttonSwitchPhasesBreakdown:SetIcon("Interface\\AddOns\\Details_EncounterDetails\\images\\boss_frame_buttons", 18, 18, "overlay", {65/256, 96/256, 0, 0.505625})
|
||||
edFrame.buttonSwitchPhasesBreakdown:SetTemplate(detailsFramework:GetTemplate("button", "DETAILS_PLUGIN_BUTTON_TEMPLATE"))
|
||||
edFrame.buttonSwitchPhasesBreakdown:SetWidth(BUTTON_WIDTH)
|
||||
_G.DetailsBreakdownWindow.RegisterPluginButton(edFrame.buttonSwitchPhasesBreakdown, edTable.PluginObject, edTable.PluginAbsoluteName)
|
||||
|
||||
--chart
|
||||
edFrame.buttonSwitchGraphic = detailsFramework:CreateButton(edFrame, edFrame.switch, BUTTON_WIDTH, BUTTON_HEIGHT, "Damage Graphic", "graph")
|
||||
edFrame.buttonSwitchGraphic:SetIcon("Interface\\AddOns\\Details_EncounterDetails\\images\\boss_frame_buttons", 18, 18, "overlay", {97/256, 128/256, 0, 0.505625})
|
||||
edFrame.buttonSwitchGraphic:SetTemplate(detailsFramework:GetTemplate("button", "DETAILS_PLUGIN_BUTTON_TEMPLATE"))
|
||||
edFrame.buttonSwitchGraphic:SetWidth(BUTTON_WIDTH)
|
||||
--charts for the breakdown window
|
||||
edFrame.buttonSwitchGraphicBreakdown = detailsFramework:CreateButton(edFrame, edFrame.switch, BUTTON_WIDTH, BUTTON_HEIGHT, "Damage Graphic", "graph")
|
||||
edFrame.buttonSwitchGraphicBreakdown:SetIcon("Interface\\AddOns\\Details_EncounterDetails\\images\\boss_frame_buttons", 18, 18, "overlay", {97/256, 128/256, 0, 0.505625})
|
||||
edFrame.buttonSwitchGraphicBreakdown:SetTemplate(detailsFramework:GetTemplate("button", "DETAILS_PLUGIN_BUTTON_TEMPLATE"))
|
||||
edFrame.buttonSwitchGraphicBreakdown:SetWidth(BUTTON_WIDTH)
|
||||
_G.DetailsBreakdownWindow.RegisterPluginButton(edFrame.buttonSwitchGraphicBreakdown, edTable.PluginObject, edTable.PluginAbsoluteName)
|
||||
|
||||
--emotes
|
||||
edFrame.buttonSwitchBossEmotes = detailsFramework:CreateButton(edFrame, edFrame.switch, BUTTON_WIDTH, BUTTON_HEIGHT, "Emotes", "emotes")
|
||||
edFrame.buttonSwitchBossEmotes:SetIcon("Interface\\AddOns\\Details_EncounterDetails\\images\\boss_frame_buttons", 18, 18, "overlay", {129/256, 160/256, 0, 0.505625})
|
||||
edFrame.buttonSwitchBossEmotes:SetTemplate(detailsFramework:GetTemplate("button", "DETAILS_PLUGIN_BUTTON_TEMPLATE"))
|
||||
edFrame.buttonSwitchBossEmotes:SetWidth(BUTTON_WIDTH)
|
||||
--emotes for the breakdown window
|
||||
edFrame.buttonSwitchBossEmotesBreakdown = detailsFramework:CreateButton(edFrame, edFrame.switch, BUTTON_WIDTH, BUTTON_HEIGHT, "Emotes", "emotes")
|
||||
edFrame.buttonSwitchBossEmotesBreakdown:SetIcon("Interface\\AddOns\\Details_EncounterDetails\\images\\boss_frame_buttons", 18, 18, "overlay", {129/256, 160/256, 0, 0.505625})
|
||||
edFrame.buttonSwitchBossEmotesBreakdown:SetTemplate(detailsFramework:GetTemplate("button", "DETAILS_PLUGIN_BUTTON_TEMPLATE"))
|
||||
edFrame.buttonSwitchBossEmotesBreakdown:SetWidth(BUTTON_WIDTH)
|
||||
_G.DetailsBreakdownWindow.RegisterPluginButton(edFrame.buttonSwitchBossEmotesBreakdown, edTable.PluginObject, edTable.PluginAbsoluteName)
|
||||
|
||||
--anchors
|
||||
edFrame.buttonSwitchNormal:SetPoint("topleft", edFrame, "topleft", 5, -26)
|
||||
edFrame.buttonSwitchPhases:SetPoint("left", edFrame.buttonSwitchNormal, "right", HEADER_MENUBUTTONS_SPACEMENT, 0)
|
||||
edFrame.buttonSwitchGraphic:SetPoint("topleft", edFrame.buttonSwitchNormal, "bottomleft", 0, -3)
|
||||
edFrame.buttonSwitchBossEmotes:SetPoint("left", edFrame.buttonSwitchGraphic, "right", HEADER_MENUBUTTONS_SPACEMENT, 0)
|
||||
|
||||
edFrame.AllButtons = {edFrame.buttonSwitchNormal, edFrame.buttonSwitchGraphic, edFrame.buttonSwitchBossEmotes, edFrame.buttonSwitchPhases}
|
||||
end
|
||||
|
||||
--segment selection
|
||||
C_Timer.After(5, function()
|
||||
local buildSegmentosMenu = function(self)
|
||||
local segmentList = Details:GetCombatSegments()
|
||||
local resultTable = {}
|
||||
|
||||
for index, combate in ipairs(segmentList) do
|
||||
if (combate.is_boss and combate.is_boss.index) then
|
||||
local bossIcon = Details:GetBossEncounterTexture(combate.is_boss.id or combate.is_boss.encounter or combate.is_boss.name)
|
||||
resultTable[#resultTable+1] = {
|
||||
value = index,
|
||||
label = "#" .. index .. " " .. (combate.is_boss.encounter or combate.is_boss.name or _G["UNKNOWN"]),
|
||||
icon = bossIcon,
|
||||
iconsize = {32, 20},
|
||||
texcoord = {0, 1, 0, 0.9},
|
||||
onclick = encounterDetails.OpenAndRefresh
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
return resultTable
|
||||
end
|
||||
|
||||
--space between the 4 tab buttons and the segments and macro frames
|
||||
local xSpacement = 20
|
||||
--~dropdown
|
||||
local segmentDropdown = detailsFramework:NewDropDown(edFrame, _, "$parentSegmentsDropdown", "segmentsDropdown", 218, 20, buildSegmentosMenu, nil)
|
||||
segmentDropdown:SetPoint("left", edFrame.buttonSwitchPhases, "right", xSpacement, 0)
|
||||
segmentDropdown:SetTemplate(detailsFramework:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE"))
|
||||
|
||||
--options button
|
||||
local optionsButton = detailsFramework:NewButton(edFrame, nil, "$parentOptionsButton", "OptionsButton", 120, 20, encounterDetails.OpenOptionsPanel, nil, nil, nil, "Options")
|
||||
optionsButton:SetPoint("left", segmentDropdown, "right", 10, 0)
|
||||
optionsButton:SetTemplate(detailsFramework:GetTemplate("button", "DETAILS_PLUGIN_BUTTON_TEMPLATE"))
|
||||
optionsButton:SetIcon([[Interface\Buttons\UI-OptionsButton]], 14, 14, nil, {0, 1, 0, 1}, nil, 3)
|
||||
end)
|
||||
|
||||
--macro box
|
||||
edFrame.MacroEditBox = detailsFramework:CreateTextEntry(edFrame, function()end, 300, 20)
|
||||
edFrame.MacroEditBox:SetPoint("left", edFrame.buttonSwitchBossEmotes, "right", xSpacement, 0)
|
||||
edFrame.MacroEditBox:SetAlpha(0.7)
|
||||
edFrame.MacroEditBox:SetText("/run Details:OpenPlugin('Encounter Breakdown')")
|
||||
edFrame.MacroEditBox:SetTemplate(detailsFramework:GetTemplate("button", "DETAILS_PLUGIN_BUTTON_TEMPLATE"))
|
||||
edFrame.MacroEditBox:SetSize(348, 20)
|
||||
|
||||
edFrame.MacroEditBox:HookScript("OnEditFocusGained", function()
|
||||
C_Timer.After(0, function() edFrame.MacroEditBox:HighlightText() end)
|
||||
end)
|
||||
|
||||
edFrame.MacroEditBox.BackgroundLabel = detailsFramework:CreateLabel(edFrame.MacroEditBox, "macro")
|
||||
edFrame.MacroEditBox.BackgroundLabel:SetPoint("left", edFrame.MacroEditBox, "left", 6, 0)
|
||||
edFrame.MacroEditBox.BackgroundLabel:SetTextColor(.3, .3, .3, .98)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,417 @@
|
||||
|
||||
local addonId, edTable = ...
|
||||
local Details = _G._detalhes
|
||||
local AceLocale = LibStub("AceLocale-3.0")
|
||||
local Loc = AceLocale:GetLocale("Details_EncounterDetails")
|
||||
local Graphics = LibStub:GetLibrary("LibGraph-2.0")
|
||||
local ipairs = ipairs
|
||||
local _GetSpellInfo = Details.getspellinfo
|
||||
local unpack = unpack
|
||||
local detailsFramework = DetailsFramework
|
||||
local CreateFrame = CreateFrame
|
||||
local GameCooltip = GameCooltip
|
||||
local GameTooltip = GameTooltip
|
||||
local wipe = table.wipe
|
||||
local _
|
||||
|
||||
local encounterDetails = _G.EncounterDetailsGlobal
|
||||
local edFrame = encounterDetails.Frame
|
||||
|
||||
edFrame.EnemySpellsWidgets = {}
|
||||
|
||||
local CONST_MAX_AURA_LINES = 21
|
||||
|
||||
local aurasButtonTemplate = {
|
||||
backdrop = {edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true},
|
||||
backdropcolor = {.3, .3, .3, .5},
|
||||
onentercolor = {1, 1, 1, .5},
|
||||
backdropbordercolor = {0, 0, 0, 1},
|
||||
}
|
||||
|
||||
local spell_blocks = {}
|
||||
local bossmods_blocks = {}
|
||||
|
||||
local on_focus_gain = function(self)
|
||||
self:HighlightText()
|
||||
end
|
||||
|
||||
local on_focus_lost = function(self)
|
||||
self:HighlightText(0, 0)
|
||||
end
|
||||
|
||||
local on_enter_spell = function(self)
|
||||
if (self.MyObject._spellid) then
|
||||
GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT")
|
||||
|
||||
if (type(self.MyObject._spellid) == "string") then
|
||||
local spellId = self.MyObject._spellid:gsub("%a", "")
|
||||
spellId = tonumber(spellId)
|
||||
if (spellId) then
|
||||
GameTooltip:SetSpellByID(spellId)
|
||||
end
|
||||
else
|
||||
GameTooltip:SetSpellByID(self.MyObject._spellid)
|
||||
end
|
||||
GameTooltip:Show()
|
||||
|
||||
self:SetBackdropColor(1, 1, 1, .5)
|
||||
self:SetBackdropBorderColor(0, 0, 0, 1)
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
local on_leave_spell = function(self, capsule)
|
||||
GameTooltip:Hide()
|
||||
self:SetBackdropColor(.3, .3, .3, .5)
|
||||
end
|
||||
|
||||
local create_aura_func = function(self, button, spellid, encounter_id)
|
||||
local name, _, icon = encounterDetails.getspellinfo(spellid)
|
||||
encounterDetails:OpenAuraPanel(spellid, name, self and self.MyObject._icon.texture, encounter_id)
|
||||
end
|
||||
|
||||
local info_onenter = function(self)
|
||||
local spellid = self._spellid
|
||||
|
||||
local info = encounterDetails.EnemySpellPool[spellid]
|
||||
if (info) then
|
||||
Details:CooltipPreset(2)
|
||||
GameCooltip:SetOption("FixedWidth", false)
|
||||
|
||||
for token, _ in pairs(info.token) do
|
||||
GameCooltip:AddLine("event:", token, 1, nil, "white")
|
||||
end
|
||||
|
||||
GameCooltip:AddLine("source:", info.source, 1, nil, "white")
|
||||
GameCooltip:AddLine("school:", encounterDetails:GetSpellSchoolFormatedName(info.school), 1, nil, "white")
|
||||
|
||||
if (info.type) then
|
||||
GameCooltip:AddLine("aura type:", info.type, 1, nil, "white")
|
||||
end
|
||||
GameCooltip:ShowCooltip(self, "tooltip")
|
||||
end
|
||||
|
||||
self:SetBackdropColor(1, 1, 1, .5)
|
||||
end
|
||||
local info_onleave = function(self)
|
||||
GameCooltip:Hide()
|
||||
self:SetBackdropColor(.3, .3, .3, .5)
|
||||
end
|
||||
|
||||
local bossModsTitle = detailsFramework:CreateLabel(edFrame, "Boss Mods Time Bars:", 12, "orange")
|
||||
bossModsTitle:SetPoint(10, -85)
|
||||
table.insert(edFrame.EnemySpellsWidgets, bossModsTitle)
|
||||
bossModsTitle:Hide()
|
||||
|
||||
local bossSpellsTitle = detailsFramework:CreateLabel(edFrame, "Boss Spells and Auras:", 12, "orange")
|
||||
bossSpellsTitle:SetPoint(444, -85)
|
||||
table.insert(edFrame.EnemySpellsWidgets, bossSpellsTitle)
|
||||
bossSpellsTitle:Hide()
|
||||
|
||||
--create boss mods list
|
||||
for i = 1, CONST_MAX_AURA_LINES do
|
||||
local anchor_frame = CreateFrame("frame", "BossFrameBossModsAnchor" .. i, edFrame, "BackdropTemplate")
|
||||
|
||||
local spellicon = detailsFramework:NewImage(anchor_frame, [[Interface\ICONS\TEMP]], 19, 19, "background", nil, "icon", "$parentIcon")
|
||||
|
||||
--timerId
|
||||
local spellid = detailsFramework:CreateTextEntry(anchor_frame, encounterDetails.empty_function, 80, 20, nil, "$parentSpellId")
|
||||
spellid:SetTemplate(aurasButtonTemplate)
|
||||
spellid:SetHook("OnEditFocusGained", on_focus_gain)
|
||||
spellid:SetHook("OnEditFocusLost", on_focus_lost)
|
||||
spellid:SetHook("OnEnter", on_enter_spell)
|
||||
spellid:SetHook("OnLeave", on_leave_spell)
|
||||
|
||||
--ability name
|
||||
local spellname = detailsFramework:CreateTextEntry(anchor_frame, encounterDetails.empty_function, 180, 20, nil, "$parentSpellName")
|
||||
spellname:SetTemplate(aurasButtonTemplate)
|
||||
spellname:SetHook("OnEditFocusGained", on_focus_gain)
|
||||
spellname:SetHook("OnEditFocusLost", on_focus_lost)
|
||||
spellname:SetHook("OnEnter", on_enter_spell)
|
||||
spellname:SetHook("OnLeave", on_leave_spell)
|
||||
|
||||
local create_aura = detailsFramework:NewButton(anchor_frame, nil, "$parentCreateAuraButton", "AuraButton", 90, 18, create_aura_func, nil, nil, nil, "Make Aura")
|
||||
create_aura:SetTemplate(aurasButtonTemplate)
|
||||
|
||||
spellicon:SetPoint("topleft", edFrame, "topleft", 10, -85 +(i * 21 * -1))
|
||||
spellid:SetPoint("left", spellicon, "right", 4, 0)
|
||||
spellname:SetPoint("left", spellid, "right", 4, 0)
|
||||
create_aura:SetPoint("left", spellname, "right", 4, 0)
|
||||
|
||||
spellid:SetBackdropBorderColor(0, 0, 0)
|
||||
spellname:SetBackdropBorderColor(0, 0, 0)
|
||||
|
||||
anchor_frame.icon = spellicon
|
||||
anchor_frame.spellid = spellid
|
||||
anchor_frame.spellname = spellname
|
||||
anchor_frame.aurabutton = create_aura
|
||||
anchor_frame.aurabutton._icon = spellicon
|
||||
|
||||
table.insert(bossmods_blocks, anchor_frame)
|
||||
table.insert(edFrame.EnemySpellsWidgets, anchor_frame)
|
||||
|
||||
anchor_frame:Hide()
|
||||
end
|
||||
|
||||
--create buff list
|
||||
for i = 1, CONST_MAX_AURA_LINES do
|
||||
local anchor_frame = CreateFrame("frame", "BossFrameSpellAnchor" .. i, edFrame, "BackdropTemplate")
|
||||
|
||||
local spellicon = detailsFramework:NewImage(anchor_frame, [[Interface\ICONS\TEMP]], 19, 19, "background", nil, "icon", "$parentIcon")
|
||||
|
||||
local spellid = detailsFramework:CreateTextEntry(anchor_frame, encounterDetails.empty_function, 80, 20)
|
||||
spellid:SetTemplate(aurasButtonTemplate)
|
||||
spellid:SetHook("OnEditFocusGained", on_focus_gain)
|
||||
spellid:SetHook("OnEditFocusLost", on_focus_lost)
|
||||
spellid:SetHook("OnEnter", on_enter_spell)
|
||||
spellid:SetHook("OnLeave", on_leave_spell)
|
||||
|
||||
local spellname = detailsFramework:CreateTextEntry(anchor_frame, encounterDetails.empty_function, 160, 20)
|
||||
spellname:SetTemplate(aurasButtonTemplate)
|
||||
spellname:SetHook("OnEditFocusGained", on_focus_gain)
|
||||
spellname:SetHook("OnEditFocusLost", on_focus_lost)
|
||||
spellname:SetHook("OnEnter", on_enter_spell)
|
||||
spellname:SetHook("OnLeave", on_leave_spell)
|
||||
|
||||
--spellicon_button:SetPoint("topleft", BossFrame, "topleft", 255, -65 +(i * 21 * -1))
|
||||
spellicon:SetPoint("topleft", edFrame, "topleft", 443, -85 +(i * 21 * -1))
|
||||
spellid:SetPoint("left", spellicon, "right", 4, 0)
|
||||
spellname:SetPoint("left", spellid, "right", 4, 0)
|
||||
|
||||
local spellinfo = CreateFrame("frame", nil, anchor_frame,"BackdropTemplate")
|
||||
spellinfo:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
|
||||
spellinfo:SetBackdropColor(.3, .3, .3, .5)
|
||||
spellinfo:SetBackdropBorderColor(0, 0, 0, 1)
|
||||
spellinfo:SetSize(80, 20)
|
||||
spellinfo:SetScript("OnEnter", info_onenter)
|
||||
spellinfo:SetScript("OnLeave", info_onleave)
|
||||
|
||||
local spellinfotext = spellinfo:CreateFontString(nil, "overlay", "GameFontNormal")
|
||||
spellinfotext:SetPoint("center", spellinfo, "center")
|
||||
spellinfotext:SetText("info")
|
||||
spellinfo:SetPoint("left", spellname.widget, "right", 4, 0)
|
||||
|
||||
local create_aura = detailsFramework:NewButton(anchor_frame, nil, "$parentCreateAuraButton", "AuraButton", 90, 18, create_aura_func, nil, nil, nil, "Make Aura")
|
||||
create_aura:SetPoint("left", spellinfo, "right", 4, 0)
|
||||
create_aura:SetTemplate(aurasButtonTemplate)
|
||||
|
||||
anchor_frame.icon = spellicon
|
||||
anchor_frame.spellid = spellid
|
||||
anchor_frame.spellname = spellname
|
||||
anchor_frame.aurabutton = create_aura
|
||||
anchor_frame.aurabutton._icon = spellicon
|
||||
anchor_frame.info = spellinfo
|
||||
|
||||
table.insert(spell_blocks, anchor_frame)
|
||||
table.insert(edFrame.EnemySpellsWidgets, anchor_frame)
|
||||
|
||||
anchor_frame:Hide()
|
||||
end
|
||||
|
||||
local update_enemy_spells = function()
|
||||
local combat = encounterDetails:GetCombat(encounterDetails._segment)
|
||||
local spell_list = {}
|
||||
|
||||
if (combat) then
|
||||
for i, npc in combat[1]:ListActors() do
|
||||
--damage
|
||||
if (npc:IsNeutralOrEnemy()) then
|
||||
for spellid, spell in pairs(npc.spells._ActorTable) do
|
||||
if (spellid > 10) then
|
||||
local name, _, icon = encounterDetails.getspellinfo(spellid)
|
||||
table.insert(spell_list, {spellid, name, icon, nil, npc.serial})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for i, npc in combat[2]:ListActors() do
|
||||
--heal
|
||||
if (npc:IsNeutralOrEnemy()) then
|
||||
for spellid, spell in pairs(npc.spells._ActorTable) do
|
||||
if (spellid > 10) then
|
||||
local name, _, icon = encounterDetails.getspellinfo(spellid)
|
||||
table.insert(spell_list, {spellid, name, icon, true, npc.serial})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
table.sort(spell_list, function(t1, t2)
|
||||
return t1[2] < t2[2]
|
||||
end)
|
||||
|
||||
encounterDetails.SpellScrollframe.spell_pool = spell_list
|
||||
encounterDetails.SpellScrollframe.encounter_id = combat.is_boss and combat.is_boss.id
|
||||
encounterDetails.SpellScrollframe:Update()
|
||||
end
|
||||
end
|
||||
|
||||
local refresh_bossmods_timers = function(self)
|
||||
local combat = encounterDetails:GetCombat(encounterDetails._segment)
|
||||
local offset = FauxScrollFrame_GetOffset(self)
|
||||
local already_added = {}
|
||||
local db = Details.boss_mods_timers
|
||||
local encounter_id = combat.is_boss and combat.is_boss.id
|
||||
|
||||
if (db) then
|
||||
wipe(already_added)
|
||||
local timersToAdd = {}
|
||||
|
||||
for timerId, timerTable in pairs(db.encounter_timers_dbm) do
|
||||
if (timerTable.id == encounter_id) then
|
||||
local spellId = timerTable [7]
|
||||
local spellIcon = timerTable [5]
|
||||
local spellName
|
||||
|
||||
local spell = timerId
|
||||
spell = spell:gsub("ej", "")
|
||||
spell = tonumber(spell)
|
||||
|
||||
if (spell and not already_added[spell]) then
|
||||
if (spell > 40000) then
|
||||
local spellname, _, spellicon = _GetSpellInfo(spell)
|
||||
table.insert(timersToAdd, {label = spellname, value = {timerTable[2], spellname, spellIcon or spellicon, timerTable.id, timerTable[7]}, icon = spellIcon or spellicon})
|
||||
else
|
||||
local sectionInfo = C_EncounterJournal.GetSectionInfo(spell)
|
||||
table.insert(timersToAdd, {label = sectionInfo.title, value = {timerTable[2], sectionInfo.title, spellIcon or sectionInfo.abilityIcon, timerTable.id, timerTable[7]}, icon = spellIcon or sectionInfo.abilityIcon})
|
||||
end
|
||||
|
||||
already_added[spell] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
table.sort(timersToAdd, function(t1, t2)
|
||||
return t1.label < t2.label
|
||||
end)
|
||||
|
||||
local offset = FauxScrollFrame_GetOffset(self)
|
||||
|
||||
for barIndex = 1, CONST_MAX_AURA_LINES do
|
||||
|
||||
local data = timersToAdd[barIndex + offset]
|
||||
local bar = bossmods_blocks[barIndex]
|
||||
|
||||
if (data) then
|
||||
bar:Show()
|
||||
|
||||
bar.icon.texture = data.icon
|
||||
bar.icon:SetTexCoord(.1, .9, .1, .9)
|
||||
bar.spellid.text = data.value[1] or "--x--x--"
|
||||
bar.spellname.text = data.label or "--x--x--"
|
||||
|
||||
bar.spellid._spellid = data.value[1]
|
||||
bar.spellname._spellid = data.value[1]
|
||||
|
||||
local func = function()
|
||||
local timerId, spellname, spellicon, encounterid, spellid = unpack(data.value)
|
||||
encounterDetails:OpenAuraPanel(timerId, spellname, spellicon, encounterid, DETAILS_WA_TRIGGER_DBM_TIMER, DETAILS_WA_AURATYPE_TEXT, {dbm_timer_id = timerId, spellid = spellid, text = "Next " .. spellname .. " In", text_size = 72, icon = spellicon})
|
||||
end
|
||||
|
||||
bar.aurabutton:SetClickFunction(func)
|
||||
else
|
||||
bar:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
FauxScrollFrame_Update(self, #timersToAdd, CONST_MAX_AURA_LINES, 20)
|
||||
|
||||
if (#timersToAdd > 0) then
|
||||
self:Show()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local refresh_spellauras = function(self)
|
||||
local pool = encounterDetails.SpellScrollframe.spell_pool
|
||||
local encounter_id = encounterDetails.SpellScrollframe.encounter_id
|
||||
local offset = FauxScrollFrame_GetOffset(self)
|
||||
|
||||
for bar_index = 1, CONST_MAX_AURA_LINES do
|
||||
local data = pool[bar_index + offset]
|
||||
local bar = spell_blocks[bar_index]
|
||||
|
||||
if (data) then
|
||||
bar:Show()
|
||||
|
||||
bar.icon.texture = data[3]
|
||||
bar.icon:SetTexCoord(.1, .9, .1, .9)
|
||||
bar.spellid.text = data[1]
|
||||
bar.spellname.text = data[2]
|
||||
|
||||
bar.spellid._spellid = data[1]
|
||||
bar.spellname._spellid = data[1]
|
||||
bar.info._spellid = data[1]
|
||||
|
||||
local is_heal = data[4]
|
||||
if (is_heal) then
|
||||
bar.spellid:SetBackdropBorderColor(0, 1, 0)
|
||||
bar.spellname:SetBackdropBorderColor(0, 1, 0)
|
||||
else
|
||||
bar.spellid:SetBackdropBorderColor(0, 0, 0)
|
||||
bar.spellname:SetBackdropBorderColor(0, 0, 0)
|
||||
end
|
||||
|
||||
bar.aurabutton:SetClickFunction(create_aura_func, data [1], encounter_id)
|
||||
else
|
||||
bar:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
FauxScrollFrame_Update(self, #pool, CONST_MAX_AURA_LINES, 20)
|
||||
end
|
||||
|
||||
local spellScrollFrame = CreateFrame("ScrollFrame", "EncounterDetails_SpellAurasScroll", edFrame, "FauxScrollFrameTemplate, BackdropTemplate")
|
||||
spellScrollFrame:SetScript("OnVerticalScroll", function(self, offset) FauxScrollFrame_OnVerticalScroll(self, offset, 14, refresh_spellauras) end)
|
||||
spellScrollFrame:SetPoint("topleft", edFrame, "topleft", 200, -75)
|
||||
spellScrollFrame:SetPoint("bottomright", edFrame, "bottomright", -33, 42)
|
||||
spellScrollFrame.Update = refresh_spellauras
|
||||
spellScrollFrame:Hide()
|
||||
encounterDetails.SpellScrollframe = spellScrollFrame
|
||||
detailsFramework:ReskinSlider(spellScrollFrame)
|
||||
|
||||
table.insert(edFrame.EnemySpellsWidgets, spellScrollFrame)
|
||||
encounterDetails.update_enemy_spells = update_enemy_spells
|
||||
|
||||
local bossmodsScrollFrame = CreateFrame("ScrollFrame", "EncounterDetails_BossModsScroll", edFrame, "FauxScrollFrameTemplate, BackdropTemplate")
|
||||
bossmodsScrollFrame:SetScript("OnVerticalScroll", function(self, offset) FauxScrollFrame_OnVerticalScroll(self, offset, 14, refresh_bossmods_timers) end)
|
||||
bossmodsScrollFrame:SetPoint("topleft", edFrame, "topleft", 10, -75)
|
||||
bossmodsScrollFrame:SetPoint("bottomleft", edFrame, "bottomleft", 250, 42)
|
||||
bossmodsScrollFrame.Update = refresh_bossmods_timers
|
||||
bossmodsScrollFrame:Hide()
|
||||
encounterDetails.BossModsScrollframe = bossmodsScrollFrame
|
||||
|
||||
table.insert(edFrame.EnemySpellsWidgets, bossmodsScrollFrame)
|
||||
encounterDetails.update_bossmods = function() bossmodsScrollFrame:Update() end
|
||||
|
||||
local build_bigwigs_bars = function()
|
||||
local t = {}
|
||||
local db = Details.boss_mods_timers
|
||||
if (db) then
|
||||
wipe(already_added)
|
||||
local encounter_id = encounterDetails.SpellScrollframe.encounter_id
|
||||
|
||||
for timer_id, timer_table in pairs(db.encounter_timers_bw) do
|
||||
if (timer_table.id == encounter_id) then
|
||||
local spell = timer_id
|
||||
if (spell and not already_added [spell]) then
|
||||
local int_spell = tonumber(spell)
|
||||
if (not int_spell) then
|
||||
local spellname = timer_table [2]:gsub(" %(.%)", "")
|
||||
table.insert(t, {label = spellname, value = {timer_table [2], spellname, timer_table [5], timer_table.id}, icon = timer_table [5], onclick = on_select_bw_bar})
|
||||
elseif (int_spell < 0) then
|
||||
local title, description, depth, abilityIcon, displayInfo, siblingID, nextSectionID, filteredByDifficulty, link, startsOpen, flag1, flag2, flag3, flag4 = C_EncounterJournal.GetSectionInfo(abs(int_spell))
|
||||
table.insert(t, {label = title, value = {timer_table [2], title, timer_table [5] or abilityIcon, timer_table.id}, icon = timer_table [5] or abilityIcon, onclick = on_select_bw_bar})
|
||||
else
|
||||
local spellname, _, spellicon = _GetSpellInfo(int_spell)
|
||||
table.insert(t, {label = spellname, value = {timer_table [2], spellname, timer_table [5] or spellicon, timer_table.id}, icon = timer_table [5] or spellicon, onclick = on_select_bw_bar})
|
||||
end
|
||||
|
||||
already_added [spell] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return t
|
||||
end
|
||||
@@ -0,0 +1,698 @@
|
||||
|
||||
local addonId, edTable = ...
|
||||
local Details = _G._detalhes
|
||||
local AceLocale = LibStub("AceLocale-3.0")
|
||||
local Loc = AceLocale:GetLocale("Details_EncounterDetails")
|
||||
local Graphics = LibStub:GetLibrary("LibGraph-2.0")
|
||||
local ipairs = ipairs
|
||||
local _GetSpellInfo = Details.getspellinfo
|
||||
local unpack = unpack
|
||||
local detailsFramework = DetailsFramework
|
||||
local CreateFrame = CreateFrame
|
||||
local GameCooltip = GameCooltip
|
||||
local wipe = table.wipe
|
||||
local _
|
||||
|
||||
--VerticalLines são os indicatores de onde aconteceram mortes, precisa ser renomeados e criar uma classe pra eles
|
||||
--precisa fazer um indicator genérico na classe df_chart para ser usado como indicador de bloodlust ou qualquer coisa que indica um evento por x tempo
|
||||
|
||||
---@class ed_phaseframe : frame
|
||||
---@field texture texture
|
||||
|
||||
local encounterDetails = _G.EncounterDetailsGlobal
|
||||
local edFrame = encounterDetails.Frame
|
||||
|
||||
--an auxiliary table to store things related to df_chartmulti but can't be stored in 'chartPanel'
|
||||
encounterDetails.chartFrameAux = {}
|
||||
|
||||
local CONST_CHART_WIDTH = 921
|
||||
local CONST_CHART_HEIGHT = 524
|
||||
local CONST_CHART_LENGTH = 810
|
||||
local CONST_CHART_TIMELINE_Y_POSITION = -540
|
||||
local CONST_CHART_MAX_DEATHS_ICONS = 6
|
||||
|
||||
local CONST_PHASE_PANEL_WIDTH = 451
|
||||
local CONST_PHASE_BAR_HEIGHT = 16
|
||||
|
||||
local DETAILS_ATTRIBUTE_DAMAGE = 1
|
||||
|
||||
local phaseAlpha = 0.5
|
||||
local lastBoss = nil
|
||||
local chartLineColors = {{1, 1, 1, 1}, {1, 0.5, 0.3, 1}, {0.75, 0.7, 0.1, 1}, {0.2, 0.9, 0.2, 1}, {0.2, 0.5, 0.9, 1}}
|
||||
encounterDetails.CombatsAlreadyDrew = {}
|
||||
|
||||
---create a multi chart frame
|
||||
---@return df_chartmulti
|
||||
local createMultiChartFrame = function()
|
||||
---@type df_chartmulti
|
||||
local chartPanel = detailsFramework:CreateGraphicMultiLineFrame(edFrame, "EncounterDetailsChartPanel")
|
||||
chartPanel.xAxisLabelsYOffset = -9
|
||||
chartPanel:CreateAxesLines(48, 28, "left", 1, 10, 10, 1, 1, 1, 1)
|
||||
chartPanel:SetXAxisDataType("time")
|
||||
chartPanel:SetSize(CONST_CHART_WIDTH, CONST_CHART_HEIGHT)
|
||||
chartPanel:SetPoint("topleft", encounterDetails.Frame, "topleft", 2, -76)
|
||||
chartPanel:SetLineThickness(3)
|
||||
encounterDetails.chartPanel = chartPanel
|
||||
|
||||
detailsFramework:ApplyStandardBackdrop(chartPanel)
|
||||
|
||||
---@type ed_phaseframe[]
|
||||
encounterDetails.chartFrameAux.PhaseFrames = {}
|
||||
encounterDetails.chartFrameAux.VerticalLines = {}
|
||||
|
||||
local phaseTooltip = encounterDetails:CreatePhaseTooltip(chartPanel)
|
||||
encounterDetails:CreatePhaseIndicators(chartPanel, phaseTooltip)
|
||||
|
||||
detailsFramework:NewLabel(chartPanel, chartPanel, nil, "phases_string", "phases:", "GameFontHighlightSmall")
|
||||
chartPanel["phases_string"]:SetPoint("bottomleft", chartPanel, "bottomleft", 5, 10)
|
||||
|
||||
chartPanel:SetScript("OnShow", function()
|
||||
chartPanel["phases_string"]:Show()
|
||||
end)
|
||||
|
||||
chartPanel:SetScript("OnHide", function()
|
||||
chartPanel["phases_string"]:Hide()
|
||||
end)
|
||||
|
||||
return chartPanel
|
||||
end
|
||||
|
||||
function encounterDetails:ShowChartFrame()
|
||||
local segment = encounterDetails._segment
|
||||
if (not segment) then
|
||||
return
|
||||
end
|
||||
|
||||
---@type df_chartmulti
|
||||
local multiChartPanel = encounterDetails.chartPanel
|
||||
|
||||
if (not multiChartPanel) then
|
||||
---@type df_chartmulti
|
||||
multiChartPanel = createMultiChartFrame()
|
||||
end
|
||||
multiChartPanel:Reset()
|
||||
|
||||
---@type combat
|
||||
local combatObject = encounterDetails:GetCombat(segment)
|
||||
--elapsed combat time
|
||||
if (combatObject:GetCombatTime() < 12) then
|
||||
return
|
||||
end
|
||||
|
||||
local uniqueCombatId = combatObject:GetCombatUID()
|
||||
local chartData = EncounterDetailsDB.chartData[uniqueCombatId]
|
||||
local currentChartData = chartData and chartData["Raid Damage Done"]
|
||||
|
||||
if (not currentChartData or not combatObject.start_time or not combatObject.end_time) then
|
||||
encounterDetails:Msg("This segment doesn't have chart data.")
|
||||
return
|
||||
|
||||
elseif (currentChartData.max_value and currentChartData.max_value == 0) then
|
||||
return
|
||||
end
|
||||
|
||||
encounterDetails.Frame.linhas = 1 --can't find references to this variable
|
||||
if (encounterDetails.Frame.linhas > 5) then
|
||||
encounterDetails.Frame.linhas = 1
|
||||
end
|
||||
|
||||
for _, line in ipairs(encounterDetails.chartFrameAux.VerticalLines) do
|
||||
line:Hide()
|
||||
end
|
||||
|
||||
local encounterId = combatObject.is_boss and combatObject.is_boss.id
|
||||
local chartIndex = 2
|
||||
local smoothnessLevel = 3
|
||||
|
||||
---draw the damage line from the 5th combat to 2nd combat
|
||||
for i = segment + 4, segment + 1, -1 do
|
||||
---@type combat
|
||||
local thisCombatObject = encounterDetails:GetCombat(i)
|
||||
if (thisCombatObject) then
|
||||
local elapsedTime = thisCombatObject:GetCombatTime()
|
||||
if (elapsedTime > 12 and thisCombatObject.is_boss and thisCombatObject.is_boss.id == encounterId) then --is the same boss
|
||||
local thisUniqueCombatId = thisCombatObject:GetCombatUID()
|
||||
local thisChartData = EncounterDetailsDB.chartData[thisUniqueCombatId] and EncounterDetailsDB.chartData[thisUniqueCombatId]["Raid Damage Done"]
|
||||
|
||||
--check if this is a valid chart data
|
||||
if (thisChartData and thisChartData.max_value and thisChartData.max_value > 0) then
|
||||
local tryNumber = thisCombatObject.is_boss.try_number or i
|
||||
multiChartPanel:AddData(thisChartData, smoothnessLevel, "Try #" .. tryNumber, chartLineColors[chartIndex])
|
||||
multiChartPanel:SetXAxisData(elapsedTime)
|
||||
chartIndex = chartIndex + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---@type number[]
|
||||
local bloodLustTimers = combatObject.bloodlust or {}
|
||||
|
||||
for index, bloodlustCombatTime in ipairs(bloodLustTimers) do
|
||||
multiChartPanel:AddBackdropIndicator("Bloodlust #" .. index, bloodlustCombatTime, bloodlustCombatTime + 40, {0, 0, 1, 0.2})
|
||||
end
|
||||
|
||||
encounterDetails:UpdatePhaseIndicators(multiChartPanel, combatObject)
|
||||
|
||||
multiChartPanel:AddData(currentChartData, smoothnessLevel, "current", chartLineColors[1])
|
||||
multiChartPanel:SetXAxisData(combatObject:GetCombatTime())
|
||||
multiChartPanel:Plot()
|
||||
multiChartPanel:Show()
|
||||
end
|
||||
|
||||
|
||||
function encounterDetails:UpdatePhaseIndicators(chartPanel, combatObject)
|
||||
encounterDetails:ClearPhaseIndicators()
|
||||
|
||||
--update phase indicators
|
||||
local phaseData = combatObject.PhaseData
|
||||
local plotFrameWidth = chartPanel.plotFrame:GetWidth()
|
||||
local scale = (plotFrameWidth) / combatObject:GetCombatTime()
|
||||
|
||||
for i = 1, #phaseData do
|
||||
local phase = phaseData[i][1]
|
||||
local phaseStartAt = phaseData[i][2]
|
||||
local phaseIndicator = encounterDetails:GetPhaseIndicator(i, phase)
|
||||
|
||||
if (phaseStartAt == 1) then
|
||||
phaseStartAt = 0
|
||||
end
|
||||
|
||||
phaseIndicator:SetPoint("topleft", chartPanel.plotFrame, "bottomleft", (phaseStartAt * scale), -6)
|
||||
phaseIndicator.phase = phase
|
||||
phaseIndicator.start_at = phaseStartAt
|
||||
|
||||
local nextPhase = phaseData[i+1]
|
||||
if (nextPhase) then
|
||||
local duration = nextPhase[2] - phaseStartAt
|
||||
phaseIndicator:SetWidth(scale * duration)
|
||||
phaseIndicator.elapsed = duration
|
||||
else
|
||||
local duration = combatObject:GetCombatTime() - phaseStartAt
|
||||
phaseIndicator:SetWidth(scale * duration)
|
||||
phaseIndicator.elapsed = duration
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---tooltip frame on hovering over
|
||||
---@param chartPanel df_chartmulti
|
||||
---@return frame
|
||||
function encounterDetails:CreatePhaseTooltip(chartPanel)
|
||||
---@type frame
|
||||
local phaseTooltip = CreateFrame("frame", "EncounterDetailsPhasePanel", chartPanel, "BackdropTemplate")
|
||||
phaseTooltip:SetFrameStrata("TOOLTIP")
|
||||
phaseTooltip:SetFrameLevel(1000)
|
||||
phaseTooltip:SetWidth(450)
|
||||
detailsFramework:ApplyStandardBackdrop(phaseTooltip)
|
||||
|
||||
local damageTexture = detailsFramework:CreateImage(phaseTooltip,[[Interface\AddOns\Details\images\skins\classic_skin_v1]], 16, 16, "overlay", {11/1024, 24/1024, 376/1024, 390/1024})
|
||||
local damageLabel = detailsFramework:CreateLabel(phaseTooltip, "Damage Done:")
|
||||
damageTexture:SetPoint("topleft", phaseTooltip, "topleft", 10, -10)
|
||||
damageLabel:SetPoint("left", damageTexture, "right", 4, 0)
|
||||
|
||||
local healingTexture = detailsFramework:CreateImage(phaseTooltip,[[Interface\AddOns\Details\images\skins\classic_skin_v1]], 16, 16, "overlay", {43/1024, 57/1024, 376/1024, 390/1024})
|
||||
local healingLabel = detailsFramework:CreateLabel(phaseTooltip, "Healing Done:")
|
||||
healingTexture:SetPoint("topleft", phaseTooltip, "topleft", 250, -10)
|
||||
healingLabel:SetPoint("left", healingTexture, "right", 4, 0)
|
||||
|
||||
phaseTooltip.phase_label = detailsFramework:CreateLabel(phaseTooltip, "")
|
||||
phaseTooltip.phase_label.fontsize = 10
|
||||
phaseTooltip.time_label = detailsFramework:CreateLabel(phaseTooltip, "")
|
||||
phaseTooltip.time_label.fontsize = 10
|
||||
phaseTooltip.report_label = detailsFramework:CreateLabel(phaseTooltip, "|cFFffb400Left Click|r: Report Damage |cFFffb400Right Click|r: Report Heal")
|
||||
phaseTooltip.report_label.fontsize = 10
|
||||
|
||||
phaseTooltip.phase_label:SetPoint("bottomleft", phaseTooltip, "bottomleft", 10, 5)
|
||||
phaseTooltip.time_label:SetPoint("left", phaseTooltip.phase_label, "right", 5, 0)
|
||||
phaseTooltip.report_label:SetPoint("bottomright", phaseTooltip, "bottomright", -10, 5)
|
||||
|
||||
local phaseFrameBackgroundTexture = detailsFramework:CreateImage(phaseTooltip,[[Interface\Tooltips\UI-Tooltip-Background]], nil, nil, "artwork")
|
||||
phaseFrameBackgroundTexture:SetPoint("left", phaseTooltip.phase_label, "left")
|
||||
phaseFrameBackgroundTexture.height = 16
|
||||
phaseFrameBackgroundTexture:SetPoint("right", phaseTooltip.report_label, "right")
|
||||
phaseFrameBackgroundTexture:SetVertexColor(0, 0, 0, 1)
|
||||
|
||||
phaseTooltip.damage_labels = {}
|
||||
phaseTooltip.heal_labels = {}
|
||||
|
||||
function phaseTooltip:ClearLabels()
|
||||
for i, tooltipBar in ipairs(phaseTooltip.damage_labels) do
|
||||
tooltipBar:Hide()
|
||||
end
|
||||
for i, tooltipBar in ipairs(phaseTooltip.heal_labels) do
|
||||
tooltipBar:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
local createTooltipBar = function(index, xOffset)
|
||||
---@type statusbar
|
||||
local newtooltipBar = CreateFrame("statusbar", nil, phaseTooltip, "BackdropTemplate")
|
||||
newtooltipBar:SetSize(200, 16)
|
||||
newtooltipBar:SetFrameLevel(phaseTooltip:GetFrameLevel() + 50 - index)
|
||||
newtooltipBar:SetMinMaxValues(0, 1)
|
||||
newtooltipBar:SetPoint("topleft", phaseTooltip, "topleft", 5 + xOffset, ((index * 16) * -1) - 30)
|
||||
|
||||
local playerName = detailsFramework:CreateLabel(newtooltipBar, "", 11, "white", nil, nil, nil, "overlay")
|
||||
|
||||
local amountLabel = detailsFramework:CreateLabel(newtooltipBar, "", 11, nil, nil, nil, nil, "overlay")
|
||||
amountLabel:SetJustifyH("right")
|
||||
|
||||
local iconTexture = detailsFramework:CreateImage(newtooltipBar, "", 16, 16, "overlay")
|
||||
|
||||
local backgroundTexture = detailsFramework:CreateImage(newtooltipBar, [[Interface\AddOns\Details\images\bar_serenity]], nil, nil, "border")
|
||||
backgroundTexture.height = 16
|
||||
backgroundTexture:SetVertexColor(.1, .1, .1, 0.834)
|
||||
|
||||
local statusBarTexture = newtooltipBar:CreateTexture(nil, "artwork")
|
||||
statusBarTexture:SetTexture([[Interface\AddOns\Details\images\bar_serenity]])
|
||||
statusBarTexture:SetVertexColor(.3, .3, .3, 1)
|
||||
statusBarTexture:SetAllPoints()
|
||||
newtooltipBar:SetStatusBarTexture(statusBarTexture)
|
||||
|
||||
backgroundTexture:SetAllPoints()
|
||||
iconTexture:SetPoint("left", newtooltipBar, "left", 0, 0)
|
||||
playerName:SetPoint("left", iconTexture, "right", 2, 0)
|
||||
amountLabel:SetPoint("right", newtooltipBar, "right", -2, 0)
|
||||
|
||||
newtooltipBar.lefttext = playerName
|
||||
newtooltipBar.righttext = amountLabel
|
||||
newtooltipBar.icon = iconTexture
|
||||
newtooltipBar.bg = backgroundTexture
|
||||
newtooltipBar.statusBarTexture = statusBarTexture
|
||||
|
||||
return newtooltipBar
|
||||
end
|
||||
|
||||
function phaseTooltip:GetTooltipBar(index, barType)
|
||||
local thisBar
|
||||
|
||||
if (barType == "damage") then
|
||||
thisBar = phaseTooltip.damage_labels[index]
|
||||
if (not thisBar) then
|
||||
thisBar = createTooltipBar(index, 0)
|
||||
phaseTooltip.damage_labels[index] = thisBar
|
||||
end
|
||||
|
||||
elseif (barType == "healing") then
|
||||
thisBar = phaseTooltip.heal_labels[index]
|
||||
if (not thisBar) then
|
||||
thisBar = createTooltipBar(index, 235)
|
||||
phaseTooltip.heal_labels[index] = thisBar
|
||||
end
|
||||
end
|
||||
|
||||
thisBar:Show()
|
||||
return thisBar
|
||||
end
|
||||
|
||||
return phaseTooltip
|
||||
end
|
||||
|
||||
---phase indicators below the x axis
|
||||
---@param chartPanel df_chartmulti
|
||||
function encounterDetails:CreatePhaseIndicators(chartPanel, phaseTooltip)
|
||||
local sparkContainer = {}
|
||||
local phaseColors = {{0.2, 1, 0.2, phaseAlpha}, {1, 1, 0.2, phaseAlpha}, {1, 0.2, 0.2, phaseAlpha}, {0.2, 1, 1, phaseAlpha}, {0.2, 0.2, 1, phaseAlpha},
|
||||
[1.5] = {0.25, 0.95, 0.25, phaseAlpha},[2.5] = {0.95, 0.95, 0.25, phaseAlpha},[3.5] = {0.95, 0.25, 0.25, phaseAlpha}
|
||||
}
|
||||
|
||||
local createSpark = function()
|
||||
local newSpark = phaseTooltip:CreateTexture(nil, "overlay")
|
||||
newSpark:SetTexture([[Interface\CastingBar\UI-CastingBar-Spark]])
|
||||
newSpark:SetBlendMode("ADD")
|
||||
newSpark:Hide()
|
||||
table.insert(sparkContainer, newSpark)
|
||||
end
|
||||
|
||||
local getSpark = function(index)
|
||||
local spark = sparkContainer[index]
|
||||
if (not spark) then
|
||||
createSpark()
|
||||
spark = sparkContainer[index]
|
||||
end
|
||||
spark:ClearAllPoints()
|
||||
return spark
|
||||
end
|
||||
|
||||
local hideSparks = function()
|
||||
for _, spark in ipairs(sparkContainer) do
|
||||
spark:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
local onClickPhase = function(self, button)
|
||||
---@type combat
|
||||
local combatObject = encounterDetails:GetCombat(encounterDetails._segment)
|
||||
|
||||
if (button == "LeftButton") then
|
||||
local result = {}
|
||||
local reportFunc = function(IsCurrent, IsReverse, AmtLines)
|
||||
AmtLines = AmtLines + 1
|
||||
if (#result > AmtLines) then
|
||||
for i = #result, AmtLines+1, -1 do
|
||||
table.remove(result, i)
|
||||
end
|
||||
end
|
||||
encounterDetails:SendReportLines(result)
|
||||
end
|
||||
|
||||
--need to build here because the mouse will leave the block to click in the send button
|
||||
table.insert(result, "Details!: Damage for Phase " .. self.phase .. " of " .. (combatObject and combatObject.is_boss and combatObject.is_boss.name or "Unknown") .. ":")
|
||||
for i = 1, #self.damage_actors do
|
||||
table.insert(result, encounterDetails:GetOnlyName(self.damage_actors[i][1]) .. ": " .. Details:ToK(math.floor(self.damage_actors[i][2])))
|
||||
end
|
||||
encounterDetails:SendReportWindow(reportFunc, nil, nil, true)
|
||||
|
||||
elseif (button == "RightButton") then
|
||||
local result = {}
|
||||
local reportFunc = function(IsCurrent, IsReverse, AmtLines)
|
||||
AmtLines = AmtLines + 1
|
||||
if (#result > AmtLines) then
|
||||
for i = #result, AmtLines+1, -1 do
|
||||
table.remove(result, i)
|
||||
end
|
||||
end
|
||||
encounterDetails:SendReportLines(result)
|
||||
end
|
||||
|
||||
table.insert(result, "Details!: Healing for Phase " .. self.phase .. " of " ..(combatObject and combatObject.is_boss and combatObject.is_boss.name or "Unknown") .. ":")
|
||||
for i = 1, #self.heal_actors do
|
||||
table.insert(result, encounterDetails:GetOnlyName(self.heal_actors[i][1]) .. ": " .. Details:ToK(math.floor(self.heal_actors[i][2])))
|
||||
end
|
||||
encounterDetails:SendReportWindow(reportFunc, nil, nil, true)
|
||||
end
|
||||
end
|
||||
|
||||
local onEnterPhase = function(self)
|
||||
local leftSpark = getSpark(1)
|
||||
local rightSpark = getSpark(2)
|
||||
leftSpark:SetPoint("left", self.texture, "left", -16, 0)
|
||||
rightSpark:SetPoint("right", self.texture, "right", 16, 0)
|
||||
leftSpark:Show()
|
||||
rightSpark:Show()
|
||||
self.texture:SetBlendMode("ADD")
|
||||
|
||||
local phase = self.phase
|
||||
local sparkIndex = 3
|
||||
|
||||
self.texture:SetVertexColor(1, 1, 1)
|
||||
|
||||
for _, thisPhaseFrame in ipairs(encounterDetails.chartFrameAux.PhaseFrames) do
|
||||
if (thisPhaseFrame ~= self and thisPhaseFrame.phase == phase) then
|
||||
local thisPhaseLeftSpark = getSpark(sparkIndex)
|
||||
local thisPhaseRightSpark = getSpark(sparkIndex+1)
|
||||
thisPhaseLeftSpark:SetPoint("left", thisPhaseFrame.texture, "left", -16, 0)
|
||||
thisPhaseRightSpark:SetPoint("right", thisPhaseFrame.texture, "right", 16, 0)
|
||||
thisPhaseLeftSpark:Show()
|
||||
thisPhaseRightSpark:Show()
|
||||
thisPhaseFrame.texture:SetBlendMode("ADD")
|
||||
thisPhaseFrame.texture:SetVertexColor(1, 1, 1)
|
||||
sparkIndex = sparkIndex + 2
|
||||
end
|
||||
end
|
||||
|
||||
---@type combat
|
||||
local combatObject = encounterDetails:GetCombat(encounterDetails._segment)
|
||||
|
||||
if (combatObject) then
|
||||
phaseTooltip:ClearLabels()
|
||||
|
||||
--damage
|
||||
---@type table<number, table<string, number>>
|
||||
local listOfPlayers = {}
|
||||
for playerName, damageDone in pairs(combatObject.PhaseData.damage[self.phase]) do
|
||||
table.insert(listOfPlayers, {playerName, damageDone})
|
||||
end
|
||||
table.sort(listOfPlayers, Details.Sort2)
|
||||
local topDamage = listOfPlayers[1] and listOfPlayers[1][2]
|
||||
|
||||
for index, playerTable in ipairs(listOfPlayers) do
|
||||
local playerName = playerTable[1]
|
||||
local damageDone = playerTable[2]
|
||||
|
||||
local tooltipBar = phaseTooltip:GetTooltipBar(index, "damage")
|
||||
tooltipBar:SetValue(damageDone / topDamage)
|
||||
|
||||
tooltipBar.lefttext.text = encounterDetails:GetOnlyName(playerName)
|
||||
tooltipBar.righttext.text = Details:ToK(math.floor(damageDone))
|
||||
|
||||
---@type actor
|
||||
local actor = combatObject:GetActor(DETAILS_ATTRIBUTE_DAMAGE, playerName)
|
||||
|
||||
local class = encounterDetails:GetClass(playerName)
|
||||
local spec = encounterDetails:GetSpec(playerName) or actor and actor.spec
|
||||
|
||||
--get the class color for the actor
|
||||
local red, green, blue = Details:GetClassColor(class)
|
||||
tooltipBar:SetStatusBarColor(red, green, blue)
|
||||
|
||||
if (spec) then
|
||||
tooltipBar.icon.texture = [[Interface\\GLUES\\CHARACTERCREATE\\UI-CHARACTERCREATE-CLASSES-SPECSl]]
|
||||
tooltipBar.icon.texcoord = encounterDetails.class_specs_coords[spec]
|
||||
|
||||
elseif (class) then
|
||||
tooltipBar.icon.texture = [[Interface\AddOns\Details\images\classes_small_alpha]]
|
||||
tooltipBar.icon.texcoord = Details.class_coords[class]
|
||||
|
||||
else
|
||||
tooltipBar.icon.texture = [[Interface\LFGFRAME\LFGROLE_BW]]
|
||||
tooltipBar.icon:SetTexCoord(.25, .5, 0, 1)
|
||||
end
|
||||
|
||||
tooltipBar:Show()
|
||||
end
|
||||
|
||||
local damage_players = #listOfPlayers
|
||||
self.damage_actors = listOfPlayers
|
||||
|
||||
--healing
|
||||
---@type table<number, table<string, number>>
|
||||
local listOfPlayersHeal = {}
|
||||
for playerName, heal in pairs(combatObject.PhaseData.heal[self.phase]) do
|
||||
table.insert(listOfPlayersHeal, {playerName, heal})
|
||||
end
|
||||
table.sort(listOfPlayersHeal, Details.Sort2)
|
||||
local topHealing = listOfPlayersHeal[1] and listOfPlayersHeal[1][2]
|
||||
|
||||
for index, playerTable in ipairs(listOfPlayersHeal) do
|
||||
local playerName = playerTable[1]
|
||||
local healingDone = playerTable[2]
|
||||
|
||||
local tooltipBar = phaseTooltip:GetTooltipBar(index, "healing")
|
||||
tooltipBar:SetValue(healingDone / topHealing)
|
||||
|
||||
tooltipBar.lefttext.text = encounterDetails:GetOnlyName(playerName)
|
||||
tooltipBar.righttext.text = Details:ToK(math.floor(healingDone))
|
||||
|
||||
---@type actor
|
||||
local actor = combatObject:GetActor(DETAILS_ATTRIBUTE_DAMAGE, playerName)
|
||||
|
||||
local class = encounterDetails:GetClass(playerName)
|
||||
local spec = encounterDetails:GetSpec(playerName) or actor and actor.spec
|
||||
|
||||
--get the class color for the actor
|
||||
local red, green, blue = Details:GetClassColor(class)
|
||||
tooltipBar:SetStatusBarColor(red, green, blue)
|
||||
|
||||
if (spec) then
|
||||
tooltipBar.icon.texture = [[Interface\\GLUES\\CHARACTERCREATE\\UI-CHARACTERCREATE-CLASSES-SPECS]]
|
||||
tooltipBar.icon.texcoord = encounterDetails.class_specs_coords[spec]
|
||||
|
||||
elseif (class) then
|
||||
tooltipBar.icon:SetTexture([[Interface\AddOns\Details\images\classes_small_alpha]])
|
||||
tooltipBar.icon:SetTexCoord(unpack(Details.class_coords[class]))
|
||||
|
||||
else
|
||||
tooltipBar.icon:SetTexture([[Interface\LFGFRAME\LFGROLE_BW]])
|
||||
tooltipBar.icon:SetTexCoord(.25, .5, 0, 1)
|
||||
end
|
||||
|
||||
tooltipBar:Show()
|
||||
end
|
||||
|
||||
local heal_players = #listOfPlayersHeal
|
||||
self.heal_actors = listOfPlayersHeal
|
||||
|
||||
--show the panel
|
||||
phaseTooltip:SetHeight((math.max(damage_players, heal_players) * 16) + 60)
|
||||
phaseTooltip:SetPoint("bottom", self, "top", 0, 10)
|
||||
phaseTooltip:Show()
|
||||
|
||||
phaseTooltip.phase_label.text = "|cFFffb400Phase|r: " .. self.phase
|
||||
|
||||
local m, s = math.floor(self.elapsed / 60), math.floor(self.elapsed % 60)
|
||||
phaseTooltip.time_label.text = "|cFFffb400Elapsed|r: " .. m .. "m " .. s .. "s"
|
||||
end
|
||||
end
|
||||
|
||||
local onLeavePhase = function(self)
|
||||
wipe(self.damage_actors)
|
||||
wipe(self.heal_actors)
|
||||
|
||||
for _, phaseTextureFrame in ipairs(encounterDetails.chartFrameAux.PhaseFrames) do
|
||||
phaseTextureFrame.texture:SetBlendMode("BLEND")
|
||||
phaseTextureFrame.texture:SetVertexColor(unpack(phaseTextureFrame.texture.original_color))
|
||||
end
|
||||
|
||||
hideSparks()
|
||||
phaseTooltip:Hide()
|
||||
end
|
||||
|
||||
function encounterDetails:GetPhaseIndicator(index, phase)
|
||||
local phaseIndicatorFrame = encounterDetails.chartFrameAux.PhaseFrames[index]
|
||||
|
||||
if (not phaseIndicatorFrame) then
|
||||
---@type ed_phaseframe
|
||||
phaseIndicatorFrame = CreateFrame("frame", "EncounterDetailsPhaseTexture" .. index, chartPanel, "BackdropTemplate")
|
||||
phaseIndicatorFrame:SetHeight(CONST_PHASE_BAR_HEIGHT)
|
||||
|
||||
local phaseTexture = phaseIndicatorFrame:CreateTexture(nil, "artwork")
|
||||
phaseTexture:SetAllPoints()
|
||||
phaseTexture:SetColorTexture(1, 1, 1, phaseAlpha)
|
||||
phaseTexture.original_color = {1, 1, 1}
|
||||
phaseIndicatorFrame.texture = phaseTexture
|
||||
|
||||
phaseIndicatorFrame:SetScript("OnEnter", onEnterPhase)
|
||||
phaseIndicatorFrame:SetScript("OnLeave", onLeavePhase)
|
||||
phaseIndicatorFrame:SetScript("OnMouseUp", onClickPhase)
|
||||
|
||||
phaseIndicatorFrame = phaseIndicatorFrame
|
||||
table.insert(encounterDetails.chartFrameAux.PhaseFrames, phaseIndicatorFrame)
|
||||
end
|
||||
|
||||
phaseIndicatorFrame:ClearAllPoints()
|
||||
|
||||
phase = math.min(phase, 5)
|
||||
if (not phaseColors[phase]) then
|
||||
Details:Msg("Phase out of range:", phase)
|
||||
phase = math.max(phase, 1)
|
||||
end
|
||||
|
||||
local phaseColor = phaseColors[phase]
|
||||
if (not phaseColor) then
|
||||
phaseColor = {1, 1, 1}
|
||||
end
|
||||
|
||||
phaseIndicatorFrame.texture:SetVertexColor(unpack(phaseColor))
|
||||
local originalColor = phaseIndicatorFrame.texture.original_color
|
||||
originalColor[1], originalColor[2], originalColor[3] = unpack(phaseColors[phase])
|
||||
|
||||
phaseIndicatorFrame:Show()
|
||||
|
||||
return phaseIndicatorFrame
|
||||
end
|
||||
|
||||
function encounterDetails:ClearPhaseIndicators()
|
||||
for i, texture in pairs(encounterDetails.chartFrameAux.PhaseFrames) do
|
||||
texture:Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---not in use at the moment
|
||||
---@param self any
|
||||
---@param chartPanel df_chart
|
||||
---@param detailsGraphicData any
|
||||
---@param combatObject combat
|
||||
---@param drawDeathsCombat combat
|
||||
function encounterDetails:DrawSegmentGraphic(chartPanel, detailsGraphicData, combatObject, drawDeathsCombat)
|
||||
|
||||
--> add death icons for the first deaths in the segment
|
||||
if (drawDeathsCombat) then
|
||||
local mortes = drawDeathsCombat.last_events_tables
|
||||
local scaleG = CONST_CHART_LENGTH / drawDeathsCombat:GetCombatTime()
|
||||
|
||||
for _, row in ipairs(encounterDetails.chartFrameAux.VerticalLines) do
|
||||
row:Hide()
|
||||
end
|
||||
|
||||
for i = 1, math.min(CONST_CHART_MAX_DEATHS_ICONS, #mortes) do
|
||||
|
||||
local vRowFrame = encounterDetails.chartFrameAux.VerticalLines[i]
|
||||
|
||||
if (not vRowFrame) then
|
||||
vRowFrame = CreateFrame("frame", "DetailsEncountersVerticalLine"..i, chartPanel, "BackdropTemplate")
|
||||
vRowFrame:SetWidth(20)
|
||||
vRowFrame:SetHeight(43)
|
||||
vRowFrame:SetFrameLevel(chartPanel:GetFrameLevel()+2)
|
||||
|
||||
vRowFrame:SetScript("OnEnter", function(frame)
|
||||
if (vRowFrame.dead[1] and vRowFrame.dead[1][3] and vRowFrame.dead[1][3][2]) then
|
||||
GameCooltip:Reset()
|
||||
|
||||
--time of death and player name
|
||||
GameCooltip:AddLine(vRowFrame.dead[6].." "..vRowFrame.dead[3])
|
||||
local class, l, r, t, b = Details:GetClass(vRowFrame.dead[3])
|
||||
if (class) then
|
||||
GameCooltip:AddIcon([[Interface\AddOns\Details\images\classes_small]], 1, 1, 12, 12, l, r, t, b)
|
||||
end
|
||||
GameCooltip:AddLine("")
|
||||
|
||||
--last hits:
|
||||
local death = vRowFrame.dead
|
||||
local amt = 0
|
||||
for i = #death[1], 1, -1 do
|
||||
local this_hit = death[1][i]
|
||||
if (type(this_hit[1]) == "boolean" and this_hit[1]) then
|
||||
local spellname, _, spellicon = _GetSpellInfo(this_hit[2])
|
||||
local t = death[2] - this_hit[4]
|
||||
GameCooltip:AddLine("-" .. string.format("%.1f", t) .. " " .. spellname .. "(" .. this_hit[6] .. ")", encounterDetails:comma_value(this_hit[3]))
|
||||
GameCooltip:AddIcon(spellicon, 1, 1, 12, 12, 0.1, 0.9, 0.1, 0.9)
|
||||
amt = amt + 1
|
||||
if (amt == 3) then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
GameCooltip:SetOption("TextSize", 9.5)
|
||||
GameCooltip:SetOption("HeightAnchorMod", -15)
|
||||
|
||||
GameCooltip:SetWallpaper(1,[[Interface\SPELLBOOK\Spellbook-Page-1]], {.6, 0.1, 0, 0.64453125}, {1, 1, 1, 0.1}, true)
|
||||
GameCooltip:ShowCooltip(frame, "tooltip")
|
||||
end
|
||||
end)
|
||||
|
||||
vRowFrame:SetScript("OnLeave", function(frame)
|
||||
Details.popup:ShowMe(false)
|
||||
end)
|
||||
|
||||
vRowFrame.texture = vRowFrame:CreateTexture(nil, "overlay")
|
||||
vRowFrame.texture:SetTexture("Interface\\AddOns\\Details\\images\\verticalline")
|
||||
vRowFrame.texture:SetWidth(3)
|
||||
vRowFrame.texture:SetHeight(20)
|
||||
vRowFrame.texture:SetPoint("center", "DetailsEncountersVerticalLine"..i, "center")
|
||||
vRowFrame.texture:SetPoint("bottom", "DetailsEncountersVerticalLine"..i, "bottom", 0, 0)
|
||||
vRowFrame.texture:SetVertexColor(1, 1, 1, .5)
|
||||
|
||||
vRowFrame.icon = vRowFrame:CreateTexture(nil, "overlay")
|
||||
vRowFrame.icon:SetTexture("Interface\\WorldStateFrame\\SkullBones")
|
||||
vRowFrame.icon:SetTexCoord(0.046875, 0.453125, 0.046875, 0.46875)
|
||||
vRowFrame.icon:SetWidth(16)
|
||||
vRowFrame.icon:SetHeight(16)
|
||||
vRowFrame.icon:SetPoint("center", "DetailsEncountersVerticalLine"..i, "center")
|
||||
vRowFrame.icon:SetPoint("bottom", "DetailsEncountersVerticalLine"..i, "bottom", 0, 20)
|
||||
|
||||
encounterDetails.chartFrameAux.VerticalLines[i] = vRowFrame
|
||||
end
|
||||
|
||||
local deadTime = mortes[i].dead_at
|
||||
vRowFrame:SetPoint("topleft", encounterDetails.Frame, "topleft",(deadTime*scaleG)+70, -CONST_CHART_HEIGHT-22)
|
||||
vRowFrame.dead = mortes[i]
|
||||
vRowFrame:Show()
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function encounterDetails:CreateGraphPanel() --not in use
|
||||
--bloodlust indicators
|
||||
chartPanel.bloodlustIndicators = {}
|
||||
for i = 1, 5 do
|
||||
local bloodlustTexture = chartPanel:CreateTexture(nil, "overlay")
|
||||
bloodlustTexture:SetColorTexture(0, 1, 0, 0,6)
|
||||
chartPanel.bloodlustIndicators[#chartPanel.bloodlustIndicators+1] = bloodlustTexture
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,374 @@
|
||||
|
||||
local addonId, edTable = ...
|
||||
local Details = _G._detalhes
|
||||
local AceLocale = LibStub("AceLocale-3.0")
|
||||
local Loc = AceLocale:GetLocale("Details_EncounterDetails")
|
||||
local Graphics = LibStub:GetLibrary("LibGraph-2.0")
|
||||
local ipairs = ipairs
|
||||
local _GetSpellInfo = Details.getspellinfo
|
||||
local unpack = unpack
|
||||
local detailsFramework = DetailsFramework
|
||||
local CreateFrame = CreateFrame
|
||||
local GameCooltip = GameCooltip
|
||||
local _
|
||||
local GetSpellLink = GetSpellLink or C_Spell.GetSpellLink --api local
|
||||
|
||||
local encounterDetails = _G.EncounterDetailsGlobal
|
||||
local edFrame = encounterDetails.Frame
|
||||
|
||||
local emote_segment_index = 1
|
||||
local searching
|
||||
local emoteLines = {}
|
||||
local emoteSearchTable = {}
|
||||
local CONST_EMOTES_MAX_LINES = 32
|
||||
|
||||
encounterDetails.emoteSegmentIndex = emote_segment_index
|
||||
|
||||
--emotes frame
|
||||
local emoteFrame = CreateFrame("frame", "DetailsEncountersEmoteFrame", UIParent, "BackdropTemplate")
|
||||
emoteFrame:RegisterEvent("CHAT_MSG_RAID_BOSS_EMOTE")
|
||||
emoteFrame:RegisterEvent("CHAT_MSG_RAID_BOSS_WHISPER")
|
||||
emoteFrame:RegisterEvent("CHAT_MSG_MONSTER_EMOTE")
|
||||
emoteFrame:RegisterEvent("CHAT_MSG_MONSTER_SAY")
|
||||
emoteFrame:RegisterEvent("CHAT_MSG_MONSTER_WHISPER")
|
||||
emoteFrame:RegisterEvent("CHAT_MSG_MONSTER_PARTY")
|
||||
emoteFrame:RegisterEvent("CHAT_MSG_MONSTER_YELL")
|
||||
encounterDetails.EmoteFrame = emoteFrame
|
||||
|
||||
local emoteTable = {
|
||||
["CHAT_MSG_RAID_BOSS_EMOTE"] = 1,
|
||||
["CHAT_MSG_RAID_BOSS_WHISPER"] = 2,
|
||||
["CHAT_MSG_MONSTER_EMOTE"] = 3,
|
||||
["CHAT_MSG_MONSTER_SAY"] = 4,
|
||||
["CHAT_MSG_MONSTER_WHISPER"] = 5,
|
||||
["CHAT_MSG_MONSTER_PARTY"] = 6,
|
||||
["CHAT_MSG_MONSTER_YELL"] = 7,
|
||||
}
|
||||
|
||||
emoteFrame:SetScript("OnEvent", function(...)
|
||||
if (not encounterDetails.current_whisper_table) then
|
||||
return
|
||||
end
|
||||
|
||||
local combat = encounterDetails:GetCombat("current")
|
||||
--local arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 = ...
|
||||
--print("2 =", arg2, "3 =", arg3, "4 =", arg4, "5 =", arg5, "6 =", arg6, "7 =", arg7, "8 =", arg8, "9 =", arg9)
|
||||
if (combat and encounterDetails:IsInCombat() and encounterDetails:GetZoneType() == "raid") then
|
||||
local arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 = ...
|
||||
table.insert(encounterDetails.current_whisper_table, {combat:GetCombatTime(), arg3, arg4, emoteTable [arg2]})
|
||||
end
|
||||
end)
|
||||
|
||||
local refresh_emotes = function(self)
|
||||
local offset = FauxScrollFrame_GetOffset(self)
|
||||
local emotePool = encounterDetails.charsaved.emotes[emote_segment_index]
|
||||
|
||||
if (searching) then
|
||||
local i = 0
|
||||
local lower = string.lower
|
||||
|
||||
for index, data in ipairs(emotePool) do
|
||||
if (lower(data[2]):find(lower(searching))) then
|
||||
i = i + 1
|
||||
emoteSearchTable[i] = data
|
||||
end
|
||||
for o = #emoteSearchTable, i + 1, -1 do
|
||||
emoteSearchTable[o] = nil
|
||||
end
|
||||
emotePool = emoteSearchTable
|
||||
end
|
||||
|
||||
edFrame.SearchResults:Show()
|
||||
edFrame.SearchResults:SetText("Found " .. i .. " matches")
|
||||
|
||||
if (i > 0) then
|
||||
edFrame.ReportEmoteButton:Enable()
|
||||
elseif (i == 0) then
|
||||
edFrame.ReportEmoteButton:Disable()
|
||||
end
|
||||
else
|
||||
edFrame.SearchResults:Hide()
|
||||
end
|
||||
|
||||
if (emotePool) then
|
||||
for barIndex = 1, CONST_EMOTES_MAX_LINES do
|
||||
local data = emotePool[barIndex + offset]
|
||||
local bar = emoteLines[barIndex]
|
||||
|
||||
if (data) then
|
||||
bar:Show()
|
||||
|
||||
local min, sec = math.floor(data[1] / 60), math.floor(data[1] % 60)
|
||||
bar.leftText:SetText(min .. "m" .. sec .. "s:")
|
||||
|
||||
if (data[2] == "") then
|
||||
bar.rightText:SetText("--x--x--")
|
||||
else
|
||||
bar.rightText:SetText(string.format(data[2], data[3]))
|
||||
end
|
||||
|
||||
local colorString = encounterDetails.BossWhispColors[data[4]]
|
||||
local colorTable = _G.ChatTypeInfo[colorString]
|
||||
|
||||
bar.rightText:SetTextColor(colorTable.r, colorTable.g, colorTable.b)
|
||||
bar.icon:SetTexture([[Interface\CHARACTERFRAME\UI-StateIcon]])
|
||||
bar.icon:SetTexCoord(0, 0.5, 0.5, 1)
|
||||
bar.icon:SetBlendMode("ADD")
|
||||
else
|
||||
bar:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
FauxScrollFrame_Update(self, #emotePool, CONST_EMOTES_MAX_LINES, 15)
|
||||
else
|
||||
for barIndex = 1, CONST_EMOTES_MAX_LINES do
|
||||
local bar = emoteLines[barIndex]
|
||||
bar:Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
edFrame.EmoteWidgets = {}
|
||||
--~emotes ~whispers
|
||||
|
||||
local barDivEmotes = detailsFramework:CreateImage(edFrame, "Interface\\AddOns\\Details_EncounterDetails\\images\\boss_bg", 4, 480, "artwork", {724/1024, 728/1024, 0, 245/512})
|
||||
barDivEmotes:SetPoint("TOPLEFT", edFrame, "TOPLEFT", 244, -74)
|
||||
barDivEmotes:Hide()
|
||||
table.insert(edFrame.EmoteWidgets, barDivEmotes)
|
||||
|
||||
local emoteScrollFrame = CreateFrame("ScrollFrame", "EncounterDetails_EmoteScroll", edFrame, "FauxScrollFrameTemplate, BackdropTemplate")
|
||||
emoteScrollFrame:SetScript("OnVerticalScroll", function(self, offset) FauxScrollFrame_OnVerticalScroll(self, offset, 14, refresh_emotes) end)
|
||||
emoteScrollFrame:SetPoint("topleft", edFrame, "topleft", 249, -75)
|
||||
emoteScrollFrame:SetPoint("bottomright", edFrame, "bottomright", -33, 42)
|
||||
emoteScrollFrame.Update = refresh_emotes
|
||||
emoteScrollFrame:Hide()
|
||||
detailsFramework:ReskinSlider(emoteScrollFrame, 3)
|
||||
encounterDetails.EmoteScrollFrame = emoteScrollFrame
|
||||
|
||||
table.insert(edFrame.EmoteWidgets, emoteScrollFrame)
|
||||
|
||||
local onEnterRow = function(self)
|
||||
self:SetBackdrop({bgFile = [[Interface\AddOns\Details\images\background]], tile = true, tileSize = 16})
|
||||
self:SetBackdropColor(1, 1, 1, .6)
|
||||
if (self.rightText:IsTruncated()) then
|
||||
GameCooltip:Reset()
|
||||
GameCooltip:AddLine(self.rightText:GetText())
|
||||
GameCooltip:SetOwner(self, "bottomleft", "topleft", 42, -9)
|
||||
GameCooltip:Show()
|
||||
end
|
||||
end
|
||||
local onLeaveRow = function(self)
|
||||
self:SetBackdrop({bgFile = [[Interface\AddOns\Details\images\background]], tile = true, tileSize = 16})
|
||||
self:SetBackdropColor(1, 1, 1, .3)
|
||||
GameCooltip:Hide()
|
||||
end
|
||||
|
||||
local onMouseUpRow = function(self)
|
||||
--report
|
||||
local text = self.rightText:GetText()
|
||||
local time = self.leftText:GetText()
|
||||
|
||||
local reportFunc = function()
|
||||
-- remove textures
|
||||
text = text:gsub("(|T).*(|t)", "")
|
||||
-- remove colors
|
||||
text = text:gsub("|c%x?%x?%x?%x?%x?%x?%x?%x?", "")
|
||||
text = text:gsub("|r", "")
|
||||
-- replace links
|
||||
for _, spellid in text:gmatch("(|Hspell:)(.-)(|h)") do
|
||||
local spell = tonumber(spellid)
|
||||
local link = GetSpellLink(spell)
|
||||
text = text:gsub("(|Hspell).*(|h)", link)
|
||||
end
|
||||
-- remove unit links
|
||||
text = text:gsub("(|Hunit).-(|h)", "")
|
||||
-- remove the left space
|
||||
text = text:gsub("^%s$", "")
|
||||
|
||||
encounterDetails:SendReportLines({"Details! Encounter Emote at " .. time, "\"" .. text .. "\""})
|
||||
end
|
||||
|
||||
encounterDetails:SendReportWindow(reportFunc)
|
||||
end
|
||||
|
||||
for i = 1, CONST_EMOTES_MAX_LINES do
|
||||
local line = CreateFrame("frame", nil, edFrame,"BackdropTemplate")
|
||||
local y = (i-1) * 15 * -1
|
||||
line:SetPoint("topleft", emoteScrollFrame, "topleft", 0, y)
|
||||
line:SetPoint("topright", emoteScrollFrame, "topright", 0, y)
|
||||
line:SetHeight(14)
|
||||
line:SetBackdrop({bgFile = [[Interface\AddOns\Details\images\background]], tile = true, tileSize = 16})
|
||||
line:SetBackdropColor(1, 1, 1, .3)
|
||||
|
||||
line.icon = line:CreateTexture(nil, "overlay")
|
||||
line.icon:SetPoint("left", line, "left", 2, 0)
|
||||
line.icon:SetSize(14, 14)
|
||||
|
||||
line.leftText = line:CreateFontString(nil, "overlay", "GameFontHighlightSmall")
|
||||
line.leftText:SetPoint("left", line.icon, "right", 2, 0)
|
||||
line.leftText:SetHeight(14)
|
||||
line.leftText:SetJustifyH("left")
|
||||
|
||||
line.rightText = line:CreateFontString(nil, "overlay", "GameFontHighlightSmall")
|
||||
line.rightText:SetPoint("left", line.icon, "right", 46, 0)
|
||||
line.rightText:SetHeight(14)
|
||||
line.rightText:SetJustifyH("left")
|
||||
|
||||
line:SetFrameLevel(emoteScrollFrame:GetFrameLevel()+1)
|
||||
|
||||
line:SetScript("OnEnter", onEnterRow)
|
||||
line:SetScript("OnLeave", onLeaveRow)
|
||||
line:SetScript("OnMouseUp", onMouseUpRow)
|
||||
table.insert(emoteLines, line)
|
||||
table.insert(edFrame.EmoteWidgets, line)
|
||||
line:Hide()
|
||||
end
|
||||
|
||||
--select emote segment
|
||||
local emotesSegmentLabel = detailsFramework:CreateLabel(edFrame, "Segment:", 11, nil, "GameFontHighlightSmall")
|
||||
emotesSegmentLabel:SetPoint("topleft", edFrame, "topleft", 10, -85)
|
||||
|
||||
local onEmoteSegmentSelected = function(_, _, segment)
|
||||
FauxScrollFrame_SetOffset(emoteScrollFrame, 0)
|
||||
emote_segment_index = segment
|
||||
encounterDetails.emoteSegmentIndex = segment
|
||||
emoteScrollFrame:Update()
|
||||
end
|
||||
|
||||
function encounterDetails:SetEmoteSegment(segment)
|
||||
emote_segment_index = segment
|
||||
encounterDetails.emoteSegmentIndex = segment
|
||||
end
|
||||
|
||||
local segmentIcon = [[Interface\AddOns\Details\images\icons]]
|
||||
local segmentIconCoords = {0.7373046875, 0.9912109375, 0.6416015625, 0.7978515625}
|
||||
local segmentIconColor = {1, 1, 1, 0.5}
|
||||
|
||||
local buildEmoteSementsList = function()
|
||||
local resultTable = {}
|
||||
if (not encounterDetails.charsaved) then
|
||||
return resultTable
|
||||
end
|
||||
for index, segment in ipairs(encounterDetails.charsaved.emotes) do
|
||||
local bossIcon, iconWidth, iconHeight, iconL, iconR, iconT, iconB = Details:GetBossEncounterTexture(segment.boss or "unknown")
|
||||
bossIcon = bossIcon or ""
|
||||
iconWidth, iconHeight = iconWidth or 16, iconHeight or 16
|
||||
iconL, iconR, iconT, iconB = iconL or 0, iconR or 1, iconT or 0, iconB or 1
|
||||
|
||||
table.insert(resultTable, {
|
||||
label = "#" .. index .. " " ..(segment.boss or "unknown"),
|
||||
value = index,
|
||||
icon = bossIcon,
|
||||
iconsize = {iconWidth, iconHeight},
|
||||
texcoord = {iconL, iconR, iconT, iconB},
|
||||
onclick = onEmoteSegmentSelected,
|
||||
iconcolor = segmentIconColor
|
||||
})
|
||||
end
|
||||
return resultTable
|
||||
end
|
||||
|
||||
local emoteSegmentsDropdown = detailsFramework:NewDropDown(edFrame, _, "$parentEmotesSegmentDropdown", "EmotesSegment", 180, 20, buildEmoteSementsList, 1)
|
||||
emoteSegmentsDropdown:SetPoint("topleft", emotesSegmentLabel, "bottomleft", -1, -2)
|
||||
emoteSegmentsDropdown:SetTemplate(detailsFramework:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE"))
|
||||
encounterDetails.emoteSegmentsDropdown = emoteSegmentsDropdown
|
||||
|
||||
table.insert(edFrame.EmoteWidgets, emoteSegmentsDropdown)
|
||||
table.insert(edFrame.EmoteWidgets, emotesSegmentLabel)
|
||||
|
||||
--search box
|
||||
local emotesSearchLabel = detailsFramework:CreateLabel(edFrame, "Search:", 11, nil, "GameFontHighlightSmall")
|
||||
emotesSearchLabel:SetPoint("topleft", edFrame, "topleft", 10, -130)
|
||||
|
||||
local emotesSearchResultsLabel = detailsFramework:CreateLabel(edFrame, "", 11, nil, "GameFontNormal", "SearchResults")
|
||||
emotesSearchResultsLabel:SetPoint("topleft", edFrame, "topleft", 10, -190)
|
||||
|
||||
local searchTextEntry = detailsFramework:NewTextEntry(edFrame, nil, "$parentEmoteSearchBox", nil, 180, 20)
|
||||
searchTextEntry:SetTemplate(detailsFramework:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE"))
|
||||
searchTextEntry:SetPoint("topleft",emotesSearchLabel, "bottomleft", -1, -2)
|
||||
searchTextEntry:SetJustifyH("left")
|
||||
searchTextEntry:SetAsSearchBox()
|
||||
|
||||
searchTextEntry:SetHook("OnTextChanged", function()
|
||||
searching = searchTextEntry:GetText()
|
||||
if (searching == "") then
|
||||
searching = nil
|
||||
FauxScrollFrame_SetOffset(emoteScrollFrame, 0)
|
||||
edFrame.ReportEmoteButton:Disable()
|
||||
emoteScrollFrame:Update()
|
||||
else
|
||||
FauxScrollFrame_SetOffset(emoteScrollFrame, 0)
|
||||
edFrame.ReportEmoteButton:Enable()
|
||||
emoteScrollFrame:Update()
|
||||
end
|
||||
end)
|
||||
|
||||
table.insert(edFrame.EmoteWidgets, searchTextEntry)
|
||||
table.insert(edFrame.EmoteWidgets, emotesSearchLabel)
|
||||
|
||||
-- report button
|
||||
local reportEmoteButton = detailsFramework:NewButton(edFrame, nil, "$parentReportEmoteButton", "ReportEmoteButton", 180, 20, function()
|
||||
local reportFunc = function(IsCurrent, IsReverse, AmtLines)
|
||||
local segment = encounterDetails.charsaved.emotes and encounterDetails.charsaved.emotes[emote_segment_index]
|
||||
|
||||
if (segment) then
|
||||
encounterDetails.report_lines = {"Details!: Emotes for " .. segment.boss}
|
||||
local added = 0
|
||||
|
||||
for index = 1, 16 do
|
||||
local bar = emoteLines[index]
|
||||
if (bar:IsShown() and added < AmtLines) then
|
||||
local time = bar.leftText:GetText()
|
||||
local text = bar.rightText:GetText()
|
||||
|
||||
--"|Hunit:77182:Oregorger|hOregorger prepares to cast |cFFFF0000|Hspell:156879|h[Blackrock Barrage]|h|r."
|
||||
|
||||
-- remove textures
|
||||
text = text:gsub("(|T).*(|t)", "")
|
||||
-- remove colors
|
||||
text = text:gsub("|c%x?%x?%x?%x?%x?%x?%x?%x?", "")
|
||||
text = text:gsub("|r", "")
|
||||
-- replace links
|
||||
for _, spellid in text:gmatch("(|Hspell:)(.-)(|h)") do
|
||||
local spell = tonumber(spellid)
|
||||
local link = GetSpellLink(spell)
|
||||
text = text:gsub("(|Hspell).*(|h)", link)
|
||||
end
|
||||
-- remove unit links
|
||||
text = text:gsub("(|Hunit).-(|h)", "")
|
||||
-- remove the left space
|
||||
text = text:gsub("^%s$", "")
|
||||
|
||||
table.insert(encounterDetails.report_lines, time .. " " .. text)
|
||||
added = added + 1
|
||||
|
||||
if (added == AmtLines) then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
encounterDetails:SendReportLines(encounterDetails.report_lines)
|
||||
else
|
||||
encounterDetails:Msg("There is nothing to report.")
|
||||
end
|
||||
end
|
||||
|
||||
local use_slider = true
|
||||
encounterDetails:SendReportWindow(reportFunc, nil, nil, use_slider)
|
||||
end, nil, nil, nil, "Report Results")
|
||||
|
||||
reportEmoteButton:SetIcon([[Interface\AddOns\Details\images\report_button]], 8, 14, nil, {0, 1, 0, 1}, nil, 4, 2)
|
||||
reportEmoteButton:SetTemplate(detailsFramework:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE"))
|
||||
|
||||
reportEmoteButton:SetPoint("topleft", searchTextEntry, "bottomleft", 0, -4)
|
||||
reportEmoteButton:Disable()
|
||||
|
||||
table.insert(edFrame.EmoteWidgets, reportEmoteButton)
|
||||
|
||||
for _, widget in pairs(edFrame.EmoteWidgets) do
|
||||
widget:Hide()
|
||||
end
|
||||
|
||||
local emoteReportLabel = detailsFramework:NewLabel(searchTextEntry.widget, searchTextEntry.widget, nil, "report_click", "|cFFffb400Left Click|r: Report Line")
|
||||
emoteReportLabel:SetPoint("topleft", searchTextEntry.widget, "bottomleft", 1, -61)
|
||||
@@ -0,0 +1,471 @@
|
||||
|
||||
local addonId, edTable = ...
|
||||
local Details = _G._detalhes
|
||||
local AceLocale = LibStub("AceLocale-3.0")
|
||||
local Loc = AceLocale:GetLocale("Details_EncounterDetails")
|
||||
local Graphics = LibStub:GetLibrary("LibGraph-2.0")
|
||||
local ipairs = ipairs
|
||||
local _GetSpellInfo = Details.getspellinfo
|
||||
local unpack = unpack
|
||||
local detailsFramework = DetailsFramework
|
||||
local CreateFrame = CreateFrame
|
||||
local GameCooltip = GameCooltip
|
||||
local wipe = table.wipe
|
||||
local _
|
||||
|
||||
local encounterDetails = _G.EncounterDetailsGlobal
|
||||
local edFrame = encounterDetails.Frame
|
||||
|
||||
local phaseFrame = CreateFrame("frame", "EncounterDetailsPhaseFrame", edFrame, "BackdropTemplate")
|
||||
phaseFrame:SetAllPoints()
|
||||
phaseFrame:SetFrameLevel(edFrame:GetFrameLevel()+1)
|
||||
phaseFrame.DamageTable = {}
|
||||
phaseFrame.HealingTable = {}
|
||||
phaseFrame.LastPhaseSelected = 1
|
||||
phaseFrame.CurrentSegment = {}
|
||||
phaseFrame.PhaseButtons = {}
|
||||
EncounterDetailsPhaseFrame:Hide()
|
||||
|
||||
local phaseButtonTemplateHighlight = {
|
||||
backdrop = {edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true},
|
||||
backdropcolor = {.7, .7, .7, .5},
|
||||
onentercolor = {1, 1, 1, .5},
|
||||
backdropbordercolor = {.70, .70, .70, 1},
|
||||
}
|
||||
|
||||
local phaseButtonTemplate = {
|
||||
backdrop = {edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true},
|
||||
backdropcolor = {.7, .7, .7, .5},
|
||||
onentercolor = {1, 1, 1, .5},
|
||||
backdropbordercolor = {0, 0, 0, 1},
|
||||
}
|
||||
|
||||
local scrollWidth, scrollHeight, scrollLineAmount, scrollLineHeight = 250, 420, 20, 20
|
||||
local phasesY = -88
|
||||
local anchorY = -120
|
||||
|
||||
phaseFrame:SetScript("OnShow", function()
|
||||
phaseFrame.OnSelectPhase(1)
|
||||
end)
|
||||
|
||||
function phaseFrame:ClearAll()
|
||||
--disable all buttons
|
||||
for i = 1, #phaseFrame.PhaseButtons do
|
||||
phaseFrame.PhaseButtons[i]:SetTemplate(phaseButtonTemplate)
|
||||
phaseFrame.PhaseButtons[i]:Disable()
|
||||
end
|
||||
|
||||
--update damage and healing scrolls
|
||||
wipe(phaseFrame.DamageTable)
|
||||
wipe(phaseFrame.HealingTable)
|
||||
|
||||
--refresh the scroll
|
||||
phaseFrame.Damage_Scroll:Refresh()
|
||||
phaseFrame.Heal_Scroll:Refresh()
|
||||
|
||||
--clear phase bars
|
||||
phaseFrame:ClearPhaseBars()
|
||||
end
|
||||
|
||||
local selectSegment = function(_, _, phaseSelected)
|
||||
phaseFrame["OnSelectPhase"](phaseSelected)
|
||||
end
|
||||
|
||||
function phaseFrame.OnSelectPhase(phaseSelected)
|
||||
|
||||
phaseFrame:ClearAll()
|
||||
|
||||
--get the selected segment
|
||||
phaseFrame.CurrentSegment = encounterDetails:GetCombat(encounterDetails._segment)
|
||||
if (not phaseFrame.CurrentSegment) then
|
||||
return
|
||||
end
|
||||
|
||||
--get the heal and damage for phase selected
|
||||
local phaseData = phaseFrame.CurrentSegment.PhaseData
|
||||
if (not phaseData) then
|
||||
return
|
||||
end
|
||||
|
||||
phaseSelected = phaseSelected or phaseFrame.LastPhaseSelected
|
||||
phaseFrame.LastPhaseSelected = phaseSelected
|
||||
|
||||
local phases = phaseFrame:GetPhaseTimers(phaseFrame.CurrentSegment, true)
|
||||
for buttonIndex, phase in ipairs(phases) do
|
||||
local button = phaseFrame.PhaseButtons[buttonIndex]
|
||||
if (phase == phaseSelected) then
|
||||
button:SetTemplate(phaseButtonTemplateHighlight)
|
||||
else
|
||||
button:SetTemplate(phaseButtonTemplate)
|
||||
if (phaseFrame.CurrentSegment.PhaseData.damage[phase]) then
|
||||
button:Enable()
|
||||
else
|
||||
button:Disable()
|
||||
end
|
||||
end
|
||||
button:SetText(phase)
|
||||
button:SetClickFunction(selectSegment, phase)
|
||||
end
|
||||
|
||||
if (not phaseData.damage[phaseSelected]) then
|
||||
phaseFrame:ClearAll()
|
||||
return
|
||||
end
|
||||
|
||||
--update damage and healing scrolls
|
||||
wipe(phaseFrame.DamageTable)
|
||||
for charName, amount in pairs(phaseData.damage[phaseSelected]) do
|
||||
table.insert(phaseFrame.DamageTable, {charName, amount})
|
||||
end
|
||||
table.sort(phaseFrame.DamageTable, function(a, b) return a[2] > b[2] end)
|
||||
|
||||
wipe(phaseFrame.HealingTable)
|
||||
for charName, amount in pairs(phaseData.heal[phaseSelected]) do
|
||||
table.insert(phaseFrame.HealingTable, {charName, amount})
|
||||
end
|
||||
table.sort(phaseFrame.HealingTable, function(a, b) return a[2] > b[2] end)
|
||||
|
||||
--refresh the scroll
|
||||
phaseFrame.Damage_Scroll:Refresh()
|
||||
phaseFrame.Heal_Scroll:Refresh()
|
||||
|
||||
phaseFrame:UpdatePhaseBars()
|
||||
end
|
||||
|
||||
local PhaseSelectLabel = detailsFramework:CreateLabel(phaseFrame, "Select Phase:", 12, "orange")
|
||||
local DamageLabel = detailsFramework:CreateLabel(phaseFrame, "Damage Done")
|
||||
local HealLabel = detailsFramework:CreateLabel(phaseFrame, "Healing Done")
|
||||
local PhaseTimersLabel = detailsFramework:CreateLabel(phaseFrame, "Time Spent on Each Phase")
|
||||
|
||||
local report_damage = function(IsCurrent, IsReverse, AmtLines)
|
||||
local result = {}
|
||||
local reportFunc = function(IsCurrent, IsReverse, AmtLines)
|
||||
AmtLines = AmtLines + 1
|
||||
if (#result > AmtLines) then
|
||||
for i = #result, AmtLines+1, -1 do
|
||||
table.remove(result, i)
|
||||
end
|
||||
end
|
||||
encounterDetails:SendReportLines(result)
|
||||
end
|
||||
|
||||
table.insert(result, "Details!: Damage for Phase " .. phaseFrame.LastPhaseSelected .. " of " ..(phaseFrame.CurrentSegment and phaseFrame.CurrentSegment.is_boss and phaseFrame.CurrentSegment.is_boss.name or "Unknown") .. ":")
|
||||
for i = 1, #phaseFrame.DamageTable do
|
||||
table.insert(result, encounterDetails:GetOnlyName(phaseFrame.DamageTable[i][1]) .. ": " .. Details:ToK(math.floor(phaseFrame.DamageTable[i][2])))
|
||||
end
|
||||
|
||||
encounterDetails:SendReportWindow(reportFunc, nil, nil, true)
|
||||
end
|
||||
|
||||
local Report_DamageButton = detailsFramework:CreateButton(phaseFrame, report_damage, 16, 16, "report")
|
||||
Report_DamageButton:SetPoint("left", DamageLabel, "left", scrollWidth-44, 0)
|
||||
Report_DamageButton.textcolor = "gray"
|
||||
Report_DamageButton.textsize = 9
|
||||
|
||||
local report_healing = function()
|
||||
local result = {}
|
||||
local reportFunc = function(IsCurrent, IsReverse, AmtLines)
|
||||
AmtLines = AmtLines + 1
|
||||
if (#result > AmtLines) then
|
||||
for i = #result, AmtLines+1, -1 do
|
||||
table.remove(result, i)
|
||||
end
|
||||
end
|
||||
encounterDetails:SendReportLines(result)
|
||||
end
|
||||
|
||||
table.insert(result, "Details!: Healing for Phase " .. phaseFrame.LastPhaseSelected .. " of " ..(phaseFrame.CurrentSegment and phaseFrame.CurrentSegment.is_boss and phaseFrame.CurrentSegment.is_boss.name or "Unknown") .. ":")
|
||||
for i = 1, #phaseFrame.HealingTable do
|
||||
table.insert(result, encounterDetails:GetOnlyName(phaseFrame.HealingTable[i][1]) .. ": " .. Details:ToK(math.floor(phaseFrame.HealingTable[i][2])))
|
||||
end
|
||||
|
||||
encounterDetails:SendReportWindow(reportFunc, nil, nil, true)
|
||||
end
|
||||
local Report_HealingButton = detailsFramework:CreateButton(phaseFrame, report_healing, 16, 16, "report")
|
||||
Report_HealingButton:SetPoint("left", HealLabel, "left", scrollWidth-44, 0)
|
||||
Report_HealingButton.textcolor = "gray"
|
||||
Report_HealingButton.textsize = 9
|
||||
|
||||
|
||||
PhaseSelectLabel:SetPoint("topleft", phaseFrame, "topleft", 10, phasesY)
|
||||
|
||||
DamageLabel:SetPoint("topleft", phaseFrame, "topleft", 10, anchorY)
|
||||
HealLabel:SetPoint("topleft", phaseFrame, "topleft", scrollWidth + 40, anchorY)
|
||||
PhaseTimersLabel:SetPoint("topleft", phaseFrame, "topleft",(scrollWidth * 2) +(40*2), anchorY)
|
||||
|
||||
for i = 1, 10 do
|
||||
local button = detailsFramework:CreateButton(phaseFrame, phaseFrame.OnSelectPhase, 60, 20, "", i)
|
||||
button:SetPoint("left", PhaseSelectLabel, "right", 8 +((i-1) * 61), 0)
|
||||
table.insert(phaseFrame.PhaseButtons, button)
|
||||
end
|
||||
|
||||
|
||||
|
||||
local ScrollRefresh = function(self, data, offset, total_lines)
|
||||
local formatToK = Details:GetCurrentToKFunction()
|
||||
local removeRealm = Details.GetOnlyName
|
||||
|
||||
local topValue = data[1] and data[1][2]
|
||||
|
||||
for i = 1, scrollLineAmount do
|
||||
local index = i + offset
|
||||
local player = data[index]
|
||||
if (player) then
|
||||
local line = self:GetLine(i)
|
||||
local texture, L, R, T, B = Details:GetPlayerIcon(player[1], phaseFrame.CurrentSegment)
|
||||
|
||||
line.icon:SetTexture(texture)
|
||||
line.icon:SetTexCoord(L, R, T, B)
|
||||
line.name:SetText(index .. ". " .. removeRealm(_, player[1]))
|
||||
line.done:SetText(formatToK(_, player[2]) .. " (" .. string.format("%.1f", player[2] / topValue * 100) .. "%)")
|
||||
line.statusbar:SetValue(player[2] / topValue * 100)
|
||||
local actorClass = Details:GetClass(player[1])
|
||||
if (actorClass) then
|
||||
line.statusbar:SetColor(actorClass)
|
||||
else
|
||||
line.statusbar:SetColor("silver")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local onEnterLine = function(self)
|
||||
self:SetBackdropColor(unpack(edTable.defaultBackgroundColor_OnEnter))
|
||||
end
|
||||
|
||||
local onLeaveLine = function(self)
|
||||
self:SetBackdropColor(unpack(edTable.defaultBackgroundColor))
|
||||
end
|
||||
|
||||
local scrollCreateLine = function(self, index)
|
||||
local line = CreateFrame("button", "$parentLine" .. index, self,"BackdropTemplate")
|
||||
line:SetPoint("topleft", self, "topleft", 0, -((index-1)*(scrollLineHeight+1)))
|
||||
line:SetSize(scrollWidth, scrollLineHeight)
|
||||
line:SetScript("OnEnter", onEnterLine)
|
||||
line:SetScript("OnLeave", onLeaveLine)
|
||||
line:SetScript("OnClick", line_onclick)
|
||||
|
||||
line:SetBackdrop({bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
|
||||
line:SetBackdropColor(unpack(edTable.defaultBackgroundColor))
|
||||
|
||||
local statusBar = detailsFramework:CreateBar(line, encounterDetails.Frame.DefaultBarTexture, 1, 1, 100)
|
||||
statusBar:SetAllPoints(line)
|
||||
statusBar.backgroundtexture = encounterDetails.Frame.DefaultBarTexture
|
||||
statusBar.backgroundcolor = {.3, .3, .3, .3}
|
||||
|
||||
local icon = statusBar:CreateTexture("$parentIcon", "overlay")
|
||||
icon:SetSize(scrollLineHeight, scrollLineHeight)
|
||||
|
||||
local name = statusBar:CreateFontString("$parentName", "overlay", "GameFontNormal")
|
||||
detailsFramework:SetFontSize(name, 10)
|
||||
icon:SetPoint("left", line, "left", 2, 0)
|
||||
name:SetPoint("left", icon, "right", 2, 0)
|
||||
detailsFramework:SetFontColor(name, "white")
|
||||
|
||||
local done = statusBar:CreateFontString("$parentDone", "overlay", "GameFontNormal")
|
||||
detailsFramework:SetFontSize(done, 10)
|
||||
detailsFramework:SetFontColor(done, "white")
|
||||
done:SetPoint("right", line, "right", -2, 0)
|
||||
|
||||
line.icon = icon
|
||||
line.name = name
|
||||
line.done = done
|
||||
line.statusbar = statusBar
|
||||
name:SetHeight(10)
|
||||
name:SetJustifyH("left")
|
||||
return line
|
||||
end
|
||||
|
||||
local damageScroll = detailsFramework:CreateScrollBox(phaseFrame, "$parentDamageScroll", ScrollRefresh, phaseFrame.DamageTable, scrollWidth, scrollHeight, scrollLineAmount, scrollLineHeight)
|
||||
local healScroll = detailsFramework:CreateScrollBox(phaseFrame, "$parentHealScroll", ScrollRefresh, phaseFrame.HealingTable, scrollWidth, scrollHeight, scrollLineAmount, scrollLineHeight)
|
||||
|
||||
damageScroll:SetPoint("topleft", DamageLabel.widget, "bottomleft", 0, -4)
|
||||
healScroll:SetPoint("topleft", HealLabel.widget, "bottomleft", 0, -4)
|
||||
|
||||
detailsFramework:ReskinSlider(damageScroll, 4)
|
||||
detailsFramework:ReskinSlider(healScroll, 4)
|
||||
|
||||
for i = 1, scrollLineAmount do
|
||||
damageScroll:CreateLine(scrollCreateLine)
|
||||
end
|
||||
|
||||
phaseFrame.Damage_Scroll = damageScroll
|
||||
damageScroll:SetBackdrop({bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", tile = true, tileSize = 16})
|
||||
damageScroll:SetBackdropColor(0, 0, 0, .4)
|
||||
|
||||
for i = 1, scrollLineAmount do
|
||||
healScroll:CreateLine(scrollCreateLine)
|
||||
end
|
||||
|
||||
phaseFrame.Heal_Scroll = healScroll
|
||||
healScroll:SetBackdrop({bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", tile = true, tileSize = 16})
|
||||
healScroll:SetBackdropColor(0, 0, 0, .4)
|
||||
|
||||
|
||||
phaseFrame.PhasesBars = {}
|
||||
phaseFrame.PhasesSegmentCompare = {}
|
||||
|
||||
local PhaseBarOnEnter = function(self)
|
||||
phaseFrame:UpdateSegmentCompareBars(self.phase)
|
||||
self:SetBackdropColor(unpack(edTable.defaultBackgroundColor_OnEnter))
|
||||
end
|
||||
|
||||
local PhaseBarOnLeave = function(self)
|
||||
phaseFrame:ClearSegmentCompareBars()
|
||||
self:SetBackdropColor(unpack(edTable.defaultBackgroundColor))
|
||||
end
|
||||
|
||||
local PhaseBarOnClick = function(self)
|
||||
--report
|
||||
end
|
||||
|
||||
--cria as linhas mostrando o tempo decorride de cada phase
|
||||
for i = 1, 10 do
|
||||
local line = CreateFrame("button", "$parentPhaseBar" .. i, phaseFrame,"BackdropTemplate")
|
||||
line:SetPoint("topleft", PhaseTimersLabel.widget, "bottomleft", 0, -((i-1)*(31)) - 4)
|
||||
line:SetSize(175, 30)
|
||||
line:SetScript("OnEnter", PhaseBarOnEnter)
|
||||
line:SetScript("OnLeave", PhaseBarOnLeave)
|
||||
line:SetScript("OnClick", PhaseBarOnClick)
|
||||
|
||||
line:SetBackdrop({bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
|
||||
line:SetBackdropColor(unpack(edTable.defaultBackgroundColor))
|
||||
|
||||
local icon = line:CreateTexture("$parentIcon", "overlay")
|
||||
icon:SetSize(16, 16)
|
||||
icon:SetTexture([[Interface\AddOns\Details\images\clock]])
|
||||
local name = line:CreateFontString("$parentName", "overlay", "GameFontNormal")
|
||||
detailsFramework:SetFontSize(name, 10)
|
||||
local done = line:CreateFontString("$parentDone", "overlay", "GameFontNormal")
|
||||
detailsFramework:SetFontSize(done, 10)
|
||||
|
||||
icon:SetPoint("left", line, "left", 2, 0)
|
||||
name:SetPoint("left", icon, "right", 2, 0)
|
||||
done:SetPoint("right", line, "right", -3, 0)
|
||||
|
||||
line.icon = icon
|
||||
line.name = name
|
||||
line.done = done
|
||||
name:SetHeight(10)
|
||||
name:SetJustifyH("left")
|
||||
|
||||
table.insert(phaseFrame.PhasesBars, line)
|
||||
end
|
||||
|
||||
--cria a linha do segmento para a compara��o, � o que fica na parte direita da tela
|
||||
--ele � acessado para mostrar quando passar o mouse sobre uma das barras de phase
|
||||
for i = 1, 20 do
|
||||
local line = CreateFrame("button", "$parentSegmentCompareBar" .. i, phaseFrame,"BackdropTemplate")
|
||||
line:SetPoint("topleft", PhaseTimersLabel.widget, "bottomleft", 175+10, -((i-1)*(scrollLineHeight+1)) - 4)
|
||||
line:SetSize(150, scrollLineHeight)
|
||||
|
||||
line:SetBackdrop({bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
|
||||
line:SetBackdropColor(unpack(edTable.defaultBackgroundColor))
|
||||
line:Hide()
|
||||
local name = line:CreateFontString("$parentName", "overlay", "GameFontNormal")
|
||||
detailsFramework:SetFontSize(name, 9)
|
||||
name:SetPoint("left", line, "left", 2, 0)
|
||||
|
||||
local done = line:CreateFontString("$parentDone", "overlay", "GameFontNormal")
|
||||
detailsFramework:SetFontSize(done, 9)
|
||||
done:SetPoint("right", line, "right", -2, 0)
|
||||
|
||||
line.name = name
|
||||
line.done = done
|
||||
name:SetHeight(10)
|
||||
name:SetJustifyH("left")
|
||||
|
||||
table.insert(phaseFrame.PhasesSegmentCompare, line)
|
||||
end
|
||||
|
||||
function phaseFrame:ClearPhaseBars()
|
||||
for i = 1, #phaseFrame.PhasesBars do
|
||||
local bar = phaseFrame.PhasesBars[i]
|
||||
bar.name:SetText("")
|
||||
bar.done:SetText("")
|
||||
bar.phase = nil
|
||||
bar:Hide()
|
||||
end
|
||||
end
|
||||
function phaseFrame:ClearSegmentCompareBars()
|
||||
for i = 1, #phaseFrame.PhasesSegmentCompare do
|
||||
phaseFrame.PhasesSegmentCompare[i]:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
function phaseFrame:GetPhaseTimers(segment, ordered)
|
||||
local t = {}
|
||||
|
||||
segment = segment or phaseFrame.CurrentSegment
|
||||
|
||||
for phaseIT = 1, #segment.PhaseData do
|
||||
local phase, startAt = unpack(segment.PhaseData[phaseIT]) --phase iterator
|
||||
local endAt = segment.PhaseData[phaseIT+1] and segment.PhaseData[phaseIT+1][2] or segment:GetCombatTime()
|
||||
local elapsed = endAt - startAt
|
||||
t[phase] = (t[phase] or 0) + elapsed
|
||||
end
|
||||
|
||||
if (ordered) then
|
||||
local order = {}
|
||||
for phase, _ in pairs(t) do
|
||||
table.insert(order, phase)
|
||||
end
|
||||
table.sort(order, function(a, b) return a < b end)
|
||||
return order, t
|
||||
end
|
||||
|
||||
return t
|
||||
end
|
||||
|
||||
--executa quando atualizar o segment geral
|
||||
function phaseFrame:UpdatePhaseBars()
|
||||
local timers, hash = phaseFrame:GetPhaseTimers(phaseFrame.CurrentSegment, true)
|
||||
local i = 1
|
||||
for index, phase in ipairs(timers) do
|
||||
local timer = hash[phase]
|
||||
phaseFrame.PhasesBars[i].name:SetText("|cFFC0C0C0Phase:|r |cFFFFFFFF" .. phase)
|
||||
phaseFrame.PhasesBars[i].done:SetText(detailsFramework:IntegerToTimer(timer))
|
||||
phaseFrame.PhasesBars[i].phase = phase
|
||||
phaseFrame.PhasesBars[i]:Show()
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
|
||||
--executa quando passar o mouse sobre uma bnarra de phase
|
||||
function phaseFrame:UpdateSegmentCompareBars(phase)
|
||||
--segmento atual(numero)
|
||||
local segmentNumber = encounterDetails._segment
|
||||
local segmentTable = phaseFrame.CurrentSegment
|
||||
local bossID = segmentTable:GetBossInfo() and segmentTable:GetBossInfo().id
|
||||
|
||||
local index = 1
|
||||
for i, segment in ipairs(Details:GetCombatSegments()) do
|
||||
if (segment:GetBossInfo() and segment:GetBossInfo().id == bossID) then
|
||||
|
||||
local bar = phaseFrame.PhasesSegmentCompare [index]
|
||||
local timers = phaseFrame:GetPhaseTimers(segment)
|
||||
|
||||
if (timers [phase]) then
|
||||
if (segment ~= segmentTable) then
|
||||
bar.name:SetText("Segment " .. i .. ":")
|
||||
detailsFramework:SetFontColor(bar.name, "orange")
|
||||
bar.done:SetText(detailsFramework:IntegerToTimer(timers [phase]))
|
||||
detailsFramework:SetFontColor(bar.done, "orange")
|
||||
else
|
||||
bar.name:SetText("Segment " .. i .. ":")
|
||||
detailsFramework:SetFontColor(bar.name, "white")
|
||||
bar.done:SetText(detailsFramework:IntegerToTimer(timers [phase]))
|
||||
detailsFramework:SetFontColor(bar.done, "white")
|
||||
end
|
||||
else
|
||||
bar.name:SetText("Segment " .. i .. ":")
|
||||
detailsFramework:SetFontColor(bar.name, "red")
|
||||
bar.done:SetText("--x--x--")
|
||||
end
|
||||
|
||||
bar:Show()
|
||||
index = index + 1
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 64 KiB |
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 4.0 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,61 @@
|
||||
local Loc = LibStub("AceLocale-3.0"):NewLocale("Details_EncounterDetails", "ptBR")
|
||||
|
||||
if (not Loc) then
|
||||
return
|
||||
end
|
||||
|
||||
Loc ["STRING_PLUGIN_NAME"] = "Detalhes do Combate"
|
||||
Loc ["STRING_WINDOW_TITLE"] = "Detalhes do Combate"
|
||||
Loc ["STRING_TOTAL_DAMAGE"] = "Total de Dano"
|
||||
Loc ["STRING_TOTAL_HEAL"] = "Total de Cura"
|
||||
Loc ["STRING_SHOW_ALL_DATA"] = "Mostrar dados totais"
|
||||
Loc ["STRING_SHOW_PHASE_DATA"] = "Mostrar dados apenas para esta fase"
|
||||
Loc ["STRING_NOT IMPLEMENTED"] = "Nao esta implementado ainda"
|
||||
Loc ["STRING_DIED"] = "morreu"
|
||||
Loc ["STRING_MELEE_DAMAGE"] = "dano corpo-a-corpo"
|
||||
Loc ["STRING_DAMAGE_TAKEN_REPORT"] = "Dano recebido por habilidade"
|
||||
Loc ["STRING_ABILITY_DAMAGE"] = "Dano da habilidade"
|
||||
Loc ["STRING_DAMAGE_TAKEN"] = "Dano recebido"
|
||||
Loc ["STRING_TOOK_DAMAGE_FROM"] = "Recebeu dano de"
|
||||
Loc ["STRING_INTERRUPT_BY"] = "interrompido por"
|
||||
Loc ["STRING_DISPELLED_BY"] = "removido por"
|
||||
Loc ["STRING_DEAD_LOG"] = "ultimos segundos de"
|
||||
Loc ["STRING_CURRENT"] = "Atual"
|
||||
Loc ["STRING_TRY"] = "Luta"
|
||||
Loc ["STRING_DAMAGE_AT"] = "Dano causado em"
|
||||
Loc ["STRING_INFLICTED_BY"] = "Dano causado por"
|
||||
Loc ["STRING_ADDS"] = "Adds"
|
||||
Loc ["STRING_INTERRUPTS"] = "Cortes"
|
||||
Loc ["STRING_DISPELLS"] = "Dissipados"
|
||||
Loc ["STRING_DEATH_LOG"] = "Ultimos Segundos"
|
||||
Loc ["STRING_FIGHT_SUMMARY"] = "detalhes da luta"
|
||||
Loc ["STRING_FIGHT_GRAPHIC"] = "graficos da performance"
|
||||
Loc ["STRING_TOOLTIP"] = "Mostrar os detalhes do combate"
|
||||
Loc ["STRING_LAST_COOLDOWN"] = "ultimo cooldown usado"
|
||||
Loc ["STRING_NOLAST_COOLDOWN"] = "nenhum cooldown usado"
|
||||
|
||||
Loc ["STRING_HOLDSHIFT"] = "SHIFT Para Descricao da Habilidade"
|
||||
|
||||
Loc ["STRING_ADDS_HELP"] = "Passe o mouse |cFF00FF00Flecha|r\ndano recebido, |cFFFF0000Flecha|r\ndano feito.|cFFFFFF00Clique|r: Reporta\nos dados no tooltip."
|
||||
Loc ["STRING_INTERRIPT_HELP"] = "\n\n|cFFFFFF00Clique|r na barra: abre a janela de enviar relatorio."
|
||||
Loc ["STRING_DISPELL_HELP"] = "\n\n|cFFFFFF00Clique|r na barra: abre a janela de enviar relatorio."
|
||||
Loc ["STRING_DEATHS_HELP"] = "\n\n|cFFFFFF00Clique|r na barra: abre a janela de enviar relatorio."
|
||||
|
||||
--mechanic types
|
||||
Loc ["STRING_HEAL"] = "cura"
|
||||
Loc ["STRING_LOWDPS"] = "dpsbaixo"
|
||||
Loc ["STRING_LOWHEAL"] = "curabaixa"
|
||||
Loc ["STRING_VOIDZONE"] = "voidzone"
|
||||
Loc ["STRING_DISPELL"] = "dispell"
|
||||
Loc ["STRING_INTERRUPT"] = "interromper"
|
||||
Loc ["STRING_POSITIONING"] = "posicao"
|
||||
Loc ["STRING_RUNAWAY"] = "correr"
|
||||
Loc ["STRING_TANKSWITCH"] = "trocadetank"
|
||||
Loc ["STRING_MECHANIC"] = "mecanica"
|
||||
Loc ["STRING_CROWDCONTROL"] = "cc"
|
||||
Loc ["STRING_TANKCOOLDOWN"] = "tankcooldown"
|
||||
Loc ["STRING_KILLADD"] = "mataradd"
|
||||
Loc ["STRING_SPREADOUT"] = "separar"
|
||||
Loc ["STRING_STOPCAST"] = "pararcast"
|
||||
Loc ["STRING_FACING"] = "virar"
|
||||
Loc ["STRING_STACK"] = "juntar"
|
||||
Reference in New Issue
Block a user