You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

523 lines
17 KiB

--whenever it say 'CombatID' it is referencing the Details! unique combatId
--whenever it say 'SegmentID' it is referencing the internal chart data registered for some details! combat
local Details = _G.Details
local detailsFramework = _G.DetailsFramework
local addonName, detailsInternal = ...
local CONST_LATEST_SEGMENT = 1
local tinsert = table.insert
local tremove = table.remove
local CONST_TICKER_NAME = "ChartDataTicker"
local CONST_TICKER_INTERVAL = 3
--create the chart object
detailsInternal.Charts = {}
local chartsObject = detailsInternal.Charts
--store all segments data
chartsObject.SegmentsData = {}
--current segment being displayed in the charts
chartsObject.SegmentOnVisualization = 0
--this table will hold the saved variable which tells which infomation to get during combat
chartsObject.DataToCapture = {}
function chartsObject.GetConfigToCaptureData()
return chartsObject.DataToCapture
end
function chartsObject.SetConfigToCaptureData(configTable)
chartsObject.DataToCapture = configTable
end
function chartsObject.GetSavedVariable()
return Details.data_harvested_for_charts
end
function chartsObject.StoreChartsForCurrentCombat()
local savedVariableTable = chartsObject.GetSavedVariable()
--Details.data_harvested_for_charts
end
function chartsObject.BuildPlayersTable(playersTable)
if (IsInRaid()) then
for i = 1, GetNumGroupMembers() do
local unitName = GetUnitName("raid" .. i, true)
playersTable[unitName] = {}
end
elseif (InIsParty()) then
for i = 1, GetNumGroupMembers() - 1 do
local unitName = GetUnitName("party" .. i, true)
playersTable[unitName] = {}
end
playersTable[UnitName("player")] = {}
else
playersTable[UnitName("player")] = {}
end
end
function chartsObject.CreateTableToReceiveChartData()
local t = {}
--get the list of players captures
local configsForCaptureData = chartsObject.GetConfigToCaptureData()
--data set to capture data of each individual player
local playerCaptures = configsForCaptureData.players
--data set to capture data of some combat attribute or totals
local combatTotalCaptures = configsForCaptureData.totals
if (#playerCaptures > 0) then
t.players = {}
for i = 1, #playerCaptures do
local capturePreset = playerCaptures[i]
local playersTable = {}
t.players[capturePreset.name] = playersTable
chartsObject.BuildPlayersTable(playersTable)
end
end
if (#combatTotalCaptures > 0) then
t.totals = {}
for i = 1, #combatTotalCaptures do
local capturePreset = combatTotalCaptures[i]
t.totals[capturePreset.name] = {}
end
end
return t
end
--function to grab data during combat
function chartsObject.Ticker()
if (chartsObject.HasValidAndOpenCombat()) then
--get Details! combat object
local detaisCurrentCombat = Details:GetCurrentCombat()
--get the list of players captures
local configsForCaptureData = chartsObject.GetConfigToCaptureData()
--data set to capture data of each individual player
local playerCaptures = configsForCaptureData.players
--data set to capture data of some combat attribute or totals
local combatTotalCaptures = configsForCaptureData.totals
local currentSegmentData = chartsObject.GetCurrentCombatData()
local chartData = currentSegmentData.ChartData
if (#playerCaptures > 0) then
--PAREI AQUI, PRECISA PEGAR O CAPTURE NAME, A TABELA COM OS NOMES DOS JOGADORES E PEGAR OS DADOS DO SEGMENTO DO DETAILS!
--DEPOIS TEM QUE FECHAR ISSO AQUI E GRAGAR NO SEGMENT DA CHART
--DEPOIS FAZER O MENU DE SELECIONAR O SEGMENTO MOSTRAR OS SEGMENTOS DO DETAILS PARA SELECIONAR
--POR FIM PROGRAMAR AS CHARTS PRA MOSTRAR OS GRAFICOS
for i = 1, #playerCaptures do
local capturePreset = playerCaptures[i]
local thisCaptureTable = chartData[capturePreset.Name]
t.players[capturePreset.name] = playersTable
chartsObject.BuildPlayersTable(playersTable)
end
end
if (#combatTotalCaptures > 0) then
t.totals = {}
for i = 1, #combatTotalCaptures do
local capturePreset = combatTotalCaptures[i]
t.totals[capturePreset.name] = {}
end
end
for i = 1, #playerCaptures do
local capturePreset = playerCaptures[i]
if (capturePreset.combatObjectSubTable) then
local subTable = detaisCurrentCombat[capturePreset.combatObjectSubTableName]
local value = subTable[capturePreset.combatObjectSubTableKey]
end
end
end
end
--[=[]]
players = {
--damage done by each player
{
name = "Damage of Each Individual Player",
combatObjectContainer = 1,
playerOnly = true,
playerKey = "total",
},
--total damage done by the raid group
{
name = "Damage of All Player Combined",
combatObjectSubTableName = "totals",
combatObjectSubTableKey = 1,
},
},
--]=]
function chartsObject.GetConfigToDataCaptureFromDetailsOptions()
local detailsObject = Details
local configTable = detailsObject.data_harvest_for_charsts
chartsObject.SetConfigToCaptureData(configTable)
end
function chartsObject.StartCombatDataTicker()
detailsInternal.Scheduler.NewTicker(CONST_TICKER_INTERVAL, chartsObject.Ticker, CONST_TICKER_NAME)
end
function chartsObject.StopCombatDataTicker()
detailsInternal.Scheduler.Cancel(CONST_TICKER_NAME)
end
--get a segment combat data
function chartsObject.GetSegmentsCombatData(combatIndex)
return chartsObject.SegmentsData[combatIndex]
end
--get a segment combat data by Details! combatId
function chartsObject.GetSegmentCombatDataByDetailsCombatID(detailsCombatId)
for i = 1, chartsObject.GetNumSegments() do
local thisSegmentCombatData = chartsObject.SegmentsData[i]
if (thisSegmentCombatData.detailsCombatID == detailsCombatId) then
return thisSegmentCombatData
end
end
end
--select a combat to make the chart frames show
function chartsObject.SelectSegmentDataToShow(segmentId)
segmentId = segmentId or CONST_LATEST_SEGMENT
local numSegments = chartsObject.GetNumSegments()
if (numSegments > 0) then
--pre step before calling the function which will signal the frame to update
chartsObject.ChartFramesShowSegment(CONST_LATEST_SEGMENT)
else
chartsObject.ChartFramesClear()
end
end
function chartsObject.ChartFramesClear()
--pre step before calling the function which will signal the frame to update
chartsObject.ChartFramesShowSegment(0)
end
--this function shouldn't be called directly, always call from SelectSegmentDataToShow or ChartFramesClear
function chartsObject.ChartFramesShowSegment(segmentId)
--set the combat data into the charts
chartsObject.SegmentOnVisualization = segmentId
--here go into the frames created and call refresh using the segment data
local segmentCombatData = chartsObject.GetSegmentsCombatData(segmentId)
if (segmentCombatData) then
--this is the lowest function and will call the frame api to refresh the data
else
chartsObject.SegmentOnVisualization = 0
--this is the lowest function and will call the frame api to refresh the data
end
end
--called when Details! reset the data
function chartsObject.ResetSegmentData()
Details:Destroy(chartsObject.SegmentsData)
--stop the ticker
chartsObject.StopCombatDataTicker()
--don't allow anything to be process under the start of a new combat
chartsObject.SetCombatState(false)
--signal the frames to update and shown no data
chartsObject.ChartFramesClear()
end
--set the combat state
function chartsObject.SetCombatState(state)
chartsObject.InCombat = state
end
function chartsObject.HasValidAndOpenCombat()
local bCombatState = chartsObject.GetCombatState()
if (bCombatState) then
local detaisCurrentCombat = Details:GetCurrentCombat()
local chartCurrentSegmentData = chartsObject.GetCurrentCombatData()
if (detaisCurrentCombat:GetCombatId() == chartCurrentSegmentData:GetCombatId()) then
--it's all good
return true
end
end
end
--return true if in combat
function chartsObject.GetCombatState()
return chartsObject.InCombat
end
function chartsObject.RemoveSegmentData(segmentId)
tremove(chartsObject.SegmentsData, segmentId)
chartsObject.SelectSegmentDataToShow(CONST_LATEST_SEGMENT)
end
function chartsObject.GetNumSegments()
return #chartsObject.SegmentsData
end
function chartsObject.GetCurrentCombatData()
return chartsObject.segmentData
end
--add the new combatData into the first index
local segmentDataMixin = {
GetCombatId = function(self)
return self.detailsCombatID
end,
}
--this is called when the player enter in combat
function chartsObject.CreateNewSegmentData(detailsCombatObject)
chartsObject.segmentData = {
--players Damage for the segment
PlayersDamage = {},
--players Healing for the segment
PlayersHealing = {},
--each index is a boss fight
BossTryDamage = 0,
--blood lust timer
BloodLustTimers = {},
--combatId
detailsCombatID = detailsCombatObject:GetCombatId(),
--charts data captured
ChartData = chartsObject.CreateTableToReceiveChartData(),
}
detailsFramework:Mixin(chartsObject.segmentData, segmentDataMixin)
tinsert(chartsObject.SegmentsData, 1, chartsObject.segmentData)
chartsObject.GetConfigToDataCaptureFromDetailsOptions()
chartsObject.SetCombatState(true)
chartsObject.StartCombatDataTicker()
return chartsObject.segmentData
end
--when a combat is finished, close and store the current combatData
function chartsObject.CloseSegmentData(bIsInvalid)
--in case a combat_invalid passed by here first
if (not chartsObject.GetCombatState()) then
return
end
chartsObject.StopCombatDataTicker()
chartsObject.SetCombatState(false)
local currentCombat = chartsObject.GetSegmentsCombatData(1)
currentCombat.Done = true
if (bIsInvalid) then
currentCombat.Invalid = true
chartsObject.RemoveSegmentData(1)
else
--check if the window is opened and update the chart current in sight
end
end
--Details Events:
function chartsObject.OnDetailsEvent(event, ...)
if (event == "COMBAT_PLAYER_ENTER") then --> combat started
local combatObject = select(1, ...)
if (not combatObject and Details) then
combatObject = Details:GetCurrentCombat()
if (not combatObject) then
return
end
end
chartsObject.CreateNewSegmentData(combatObject)
elseif (event == "COMBAT_PLAYER_LEAVE") then
chartsObject.CloseSegmentData()
elseif (event == "DETAILS_DATA_RESET") then
chartsObject.ResetSegmentData()
elseif (event == "COMBAT_INVALID") then
local bIsInvalid = true
chartsObject.CloseSegmentData(bIsInvalid)
elseif (event == "DETAILS_STARTED") then
--install the new tab on the Player Breakdown
chartsObject.InstallTab()
end
end
local eventListener = Details:CreateEventListener()
eventListener:RegisterEvent("COMBAT_PLAYER_ENTER", chartsObject.OnDetailsEvent)
eventListener:RegisterEvent("COMBAT_PLAYER_LEAVE", chartsObject.OnDetailsEvent)
eventListener:RegisterEvent("DETAILS_DATA_RESET", chartsObject.OnDetailsEvent)
eventListener:RegisterEvent("COMBAT_INVALID", chartsObject.OnDetailsEvent)
eventListener:RegisterEvent("DETAILS_STARTED", chartsObject.OnDetailsEvent)
function chartsObject.InstallTab()
local tabName = "Charts"
local tabNameLoc = "Damage Charts"
local canShowTab = function(tabOBject, playerObject)
local combatObject = Details:GetCombatFromBreakdownWindow()
if (combatObject) then
local chartsCombatData = chartsObject.GetSegmentCombatDataByDetailsCombatID(combatObject:GetCombatId())
if (chartsCombatData) then
return true
end
end
return false
end
local fillTab = function(tab, playerObject, combat)
--update the tab frame with information
end
local createdChartsTab = function(tab, frame)
chartsObject.CreateChartFrames(tab, frame)
end
local iconSettings = {
texture = [[Interface\BUTTONS\UI-GuildButton-OfficerNote-Disabled]],
coords = {0, 1, 0, 1},
width = 16,
height = 16,
}
Details:CreatePlayerDetailsTab(tabName, tabNameLoc, canShowTab, fillTab, nil, createdChartsTab, iconSettings)
end
function chartsObject.CreateChartFrames(tab, tabFrame)
--First Option: each player dps chart on each segment, this show the evolution of damage of each player
--Second Option: Total Damage Done by the entire raid comparing with other segments (one line of raid damage per segment)
--Thrid Option: your damage compared with other of the same class (chart damage of each player required)
--Your habilites compared segment by segment (no chart data required)
--segment scroll in the left
--boss image, boss name,
--when selecting a boss show the chart for the boss
local defaultChartSections = {
{
Name = "Raid Damage",
ChartID = 1,
ChartData = "alldamagers-segment",
},
{
},
}
local scrollWidth = 200
local scrollHeight = 500
local scrollButtonHeight = 20
local amountScrollLines = floor(scrollHeight / scrollButtonHeight)
local allLinesCreated = {}
local lineSelectedBackdropColor = {.5, .5, .5, .5}
local onClickLine_SelectChartToView = function(button, mouseButton)
for buttonId, line in ipairs(allLinesCreated) do
line:SetDefaultBackdropColor()
end
end
local lineMixin = {
SetDefaultBackdropColor = function(line)
line.__background:SetVertexColor(unpack(line.defaultBackgroundColor))
end,
SetSelectedBackdropColor = function(line)
line.__background:SetVertexColor(unpack(lineSelectedBackdropColor))
end,
OnClickLine = function(line)
--select the chart to view
end,
}
--function to create a line in the scroll frame
local createScrollLine = function(self, index)
--create a new line
local line = CreateFrame("button", "$parentLine" .. index, self, "BackdropTemplate")
detailsFramework:Mixin(line, lineMixin)
--set its parameters
line:SetPoint("topleft", self, "topleft", 1, -((index-1) * (scrollButtonHeight+1)) - 1)
line:SetSize(scrollWidth-19, scrollButtonHeight)
line:RegisterForClicks("LeftButtonDown", "RightButtonDown")
line:SetScript("OnClick", line.OnClickLine)
detailsFramework:ApplyStandardBackdrop(line)
line.defaultBackgroundColor = {line.__background:GetVertexColor()}
local icon = line:CreateTexture("$parentSpecIcon", "artwork")
icon:SetSize(scrollButtonHeight, scrollButtonHeight)
icon:SetAlpha(0.71)
local chartData = defaultChartSections[index]
local chartName = detailsFramework:CreateLabel(line, chartData.Name, 11, "white", "GameFontNormal")
icon:SetPoint("left", line, "left", 0, 0)
chartName:SetPoint("topleft", icon, "topright", 2, -3)
line.Icon = icon
line.ChartName = chartName
return line
end
local refreshScroll = function(self, data, offset, totalLines)
for i = 1, totalLines do
local index = i + offset
local chartData = data[index]
if (chartData) then
local line = self:GetLine(i)
line.ChartID = chartData.ChartID
line.ChartData = chartData.ChartData
line.ChartName.text = chartData.Name
end
end
end
--Create the scrollbox showing the selection for charts
local chartSelectionScrollBox = detailsFramework:CreateScrollBox(
tabFrame,
"$parentChartSelectionScroll",
refreshScroll,
{},
scrollWidth,
scrollHeight,
amountScrollLines,
scrollButtonHeight
)
detailsFramework:ReskinSlider(chartSelectionScrollBox)
chartSelectionScrollBox.ScrollBar:ClearAllPoints()
chartSelectionScrollBox.ScrollBar:SetPoint("topright", chartSelectionScrollBox, "topright", -2, -17)
chartSelectionScrollBox.ScrollBar:SetPoint("bottomright", chartSelectionScrollBox, "bottomright", -2, 17)
chartSelectionScrollBox:SetPoint("topright", tabFrame, "topleft", -1, 0)
chartSelectionScrollBox:SetPoint("bottomright", tabFrame, "bottomleft", -1, 0)
detailsFramework:ApplyStandardBackdrop(chartSelectionScrollBox)
tabFrame.chartSelectionScrollBox = chartSelectionScrollBox
--create the scrollbox lines
for i = 1, amountScrollLines do
chartSelectionScrollBox:CreateLine(createScrollLine)
end
end