More bug fixes for destroyed combats; TimeData code modernizations

This commit is contained in:
Tercio Jose
2023-06-14 18:43:33 -03:00
parent efd131ef04
commit a2c5e926c9
9 changed files with 446 additions and 142 deletions
+1
View File
@@ -43,6 +43,7 @@
---@field totals {key1: table, key2: table, key3: table, key3: table}
---@field totals_grupo {key1: table, key2: table, key3: table, key3: table}
---@field __destroyed boolean
---@field GetTimeData fun(dataName: string) : table
---@field GetPhases fun(combat: combat) : table
---@field GetCombatTime fun(combat) : number
---@field GetDeaths fun(combat) : table --get the table which contains the deaths of the combat
+212 -22
View File
@@ -1,19 +1,30 @@
local DF = _G["DetailsFramework"]
if (not DF or not DetailsFrameworkCanLoad) then
local detailsFramework = _G["DetailsFramework"]
if (not detailsFramework or not DetailsFrameworkCanLoad) then
return
end
local CreateFrame = CreateFrame
local unpack = unpack
local _
---@class df_chart: frame, data
---@field _dataInfo data
---@class df_chartshared: table
---@field yAxisLine line the vertical line which can be anchored in the left or right side of the frame, if the chart is a multi chart, this line is shared by all charts
---@field xAxisLine line
---@field lineThickness number
---@field yAxisLabels fontstring[]
---@field xAxisLabels fontstring[]
---@field SetAxisColor fun(self: df_chartmulti, red: number|string|table|nil, green: number|nil, blue: number|nil, alpha: number|nil) : boolean set the color of both axis lines
---@field SetAxisThickness fun(self: df_chartmulti, thickness: number) : boolean set the thickness of both axis lines
---@class df_chart: frame, df_data, df_value, df_chartshared
---@field _dataInfo df_data
---@field color number[] red green blue alpha
---@field nextLine number
---@field minValue number
---@field maxValue number
---@field lineThickness number
---@field data table
---@field lines table
---@field data number[]
---@field lines line[]
---@field ChartFrameConstructor fun(self: df_chart) set the default values for the chart frame
---@field GetLine fun(self: df_chart) : line return a line and also internally handle next line
---@field GetLines fun(self: df_chart) : line[] return a table with all lines already created
@@ -24,14 +35,126 @@ local _
---@field OnSizeChanged fun(self: df_chart)
---@field HideLines fun(self: df_chart) hide all lines already created
---@field Reset fun(self: df_chart) hide all lines and reset the next line to 1
---@field SetColor fun(self: df_chart, r: number|string|table|nil, g: number|nil, b: number|nil, a: number|nil) set the color for the lines
---@field SetLineThickness fun(self: df_chart, thickness: number) set the line thickness
---@field CalcYAxisPointForValue fun(self: df_chart, value: number)
---@field UpdateFrameSizeCache fun(self: df_chart)
---@class df_chartmulti : df_chart, df_chartshared
---@field chartFrames df_chart[]
---@field nextChartselframe number
---@field biggestDataValue number
---@field MultiChartFrameConstructor fun(self: df_chartmulti)
---@field GetCharts fun(self: df_chartmulti) : df_chart[]
---@field GetChart fun(self: df_chartmulti) : df_chart
---@field AddData fun(self: df_chartmulti, data: table, red: number|string|table|nil, green: number|nil, blue: number|nil, alpha: number|nil)
---@field GetAmountCharts fun(self: df_chartmulti): number
---@field HideCharts fun(self: df_chartmulti)
---@field Reset fun(self: df_chartmulti)
---@field SetChartsMinMaxValues fun(self: df_chartmulti, minValue: number, maxValue: number)
---@field SetMaxDataSize fun(self: df_chartmulti, dataSize: number)
---@field GetMaxDataSize fun(self: df_chartmulti)
---@field SetLineThickness fun(self: df_chart, thickness: number) set the line thickness for all chart frames
---@field Plot fun(self: df_chartmulti)
detailsFramework.ChartFrameSharedMixin = {
---set the color of both axis lines
---@param self df_chart|df_chartmulti
---@param red any
---@param green number|nil
---@param blue number|nil
---@param alpha number|nil
---@return boolean bColorChanged return true if the color was set, false if the axis lines are not created yet
SetAxisColor = function(self, red, green, blue, alpha)
if (not self.yAxisLine) then
return false
end
red, green, blue, alpha = detailsFramework:ParseColors(red, green, blue, alpha)
self.yAxisLine:SetColorTexture(red, green, blue, alpha)
self.xAxisLine:SetColorTexture(red, green, blue, alpha)
return true
end,
---set the thickness of both axis lines
---@param self df_chart|df_chartmulti
---@param thickness number
---@return boolean bThicknessChanged return true if the thickness was set, false if the axis lines are not created yet
SetAxisThickness = function(self, thickness)
if (not self.yAxisLine) then
return false
end
self.yAxisLine:SetThickness(thickness)
self.xAxisLine:SetThickness(thickness)
return true
end,
}
local ChartFrameMixin = {
--> functions shared by both single and multi chart frames
---create the x and y axis lines with their labels
---@param self df_chart|df_chartmulti
---@param whichSide "left"|"right"
---@param thickness number
---@param amountYLabels number
---@param amountXLabels number
---@param red any
---@param green number|nil
---@param blue number|nil
---@param alpha number|nil
---@return boolean
local createAxysLines = function(self, whichSide, thickness, amountYLabels, amountXLabels, red, green, blue, alpha)
if (self.axisCreated) then
return false
end
self.yAxisLabels = {}
self.xAxisLabels = {}
--this is the vertical line which can be anchored in the left or right side of the frame, it separates the chart lines from the measurements texts
---@type line
local yAxisLine = self:CreateLine("$parentYAxisLine", "overlay")
self.yAxisLine = yAxisLine
--and the horizontal line which is always anchored in the bottom of the frame
---@type line
local xAxisLine = self:CreateLine("$parentXAxisLine", "overlay")
self.xAxisLine = xAxisLine
red, green, blue, alpha = detailsFramework:ParseColors(red, green, blue, alpha)
self:SetAxisColor(red, green, blue, alpha)
self:SetAxisThickness(thickness)
--create the labels in the vertical axis line
for i = 1, amountYLabels do
local label = self:CreateFontString("$parentYAxisLabel" .. i, "overlay", "GameFontNormal")
label:SetJustifyH("right")
label:SetTextColor(red, green, blue, alpha)
table.insert(self.yAxisLabels, label)
end
--create the labels in the horizontal axis line
for i = 1, amountXLabels do
local label = self:CreateFontString("$parentXAxisLabel" .. i, "overlay", "GameFontNormal")
label:SetJustifyH("left")
label:SetTextColor(red, green, blue, alpha)
table.insert(self.xAxisLabels, label)
end
yAxisLine:SetStartPoint("topleft", self, "topleft", 0, 0)
yAxisLine:SetEndPoint("bottomleft", self, "bottomleft", 0, 0)
yAxisLine:Hide()
xAxisLine:SetStartPoint("bottomleft", self, "bottomleft", 0, 0)
xAxisLine:SetEndPoint("bottomright", self, "bottomright", 0, 0)
xAxisLine:Hide()
self.axisCreated = true
return true
end
detailsFramework.ChartFrameMixin = {
---set the default values for the chart frame
---@param self df_chart
ChartFrameConstructor = function(self)
@@ -41,19 +164,38 @@ local ChartFrameMixin = {
self.lineThickness = 1
self.data = {}
self.lines = {}
self.color = {1, 1, 1, 1}
--OnSizeChanged
self:SetScript("OnSizeChanged", self.OnSizeChanged)
end,
---set the color for the lines
---@param self df_chart
---@param r number
---@param g number
---@param b number
---@param a number|nil
SetColor = function(self, r, g, b, a)
r, g, b, a = detailsFramework:ParseColors(r, g, b, a)
self.color[1] = r
self.color[2] = g
self.color[3] = b
self.color[4] = a or 1
end,
---internally handle next line
---@param self df_chart
GetLine = function(self)
---@type line
local line = self.lines[self.nextLine]
if (not line) then
---@type line
line = self:CreateLine(nil, "overlay")
self.lines[self.nextLine] = line
end
self.nextLine = self.nextLine + 1
line:Show()
return line
@@ -160,8 +302,8 @@ local ChartFrameMixin = {
for i = 1, maxLines do
local line = self:GetLine()
line:SetColorTexture(1, 1, 1, 1)
line:SetThickness(1)
line:SetColorTexture(unpack(self.color))
line:SetThickness(self.lineThickness)
--the start point starts where the latest point finished
line:SetStartPoint("bottomleft", currentXPoint, currentYPoint)
@@ -185,9 +327,10 @@ local createChartFrame = function(parent, name)
---@type df_chart
local chartFrame = CreateFrame("frame", name, parent, "BackdropTemplate")
DF:Mixin(chartFrame, DF.DataMixin)
DF:Mixin(chartFrame, DF.ValueMixin)
DF:Mixin(chartFrame, ChartFrameMixin)
detailsFramework:Mixin(chartFrame, detailsFramework.DataMixin)
detailsFramework:Mixin(chartFrame, detailsFramework.ValueMixin)
detailsFramework:Mixin(chartFrame, detailsFramework.ChartFrameMixin)
detailsFramework:Mixin(chartFrame, detailsFramework.ChartFrameSharedMixin)
chartFrame:DataConstructor()
chartFrame:ValueConstructor()
@@ -205,22 +348,35 @@ local createChartFrame = function(parent, name)
return chartFrame
end
function DF:CreateGraphicLineFrame(parent, name)
function detailsFramework:CreateGraphicLineFrame(parent, name)
---@type df_chart
local newGraphicFrame = createChartFrame(parent, name)
return newGraphicFrame
end
local MultiChartFrameMixin = {
detailsFramework.MultiChartFrameMixin = {
MultiChartFrameConstructor = function(self)
self.nextChartselframe = 1
self.biggestDataValue = 0
self.lineThickness = 1
self.chartFrames = {}
end,
AddData = function(self, data)
CreateAxisLines = function(self, whichSide, thickness, amountYLabels, amountXLabels, red, green, blue, alpha)
createAxysLines(self, whichSide, thickness, amountYLabels, amountXLabels, red, green, blue, alpha)
end,
---add a new chart data and create a new chart frame if necessary to the multi chart
---@param self df_chartmulti
---@param data table
---@param red number|string|table|nil
---@param green number|nil
---@param blue number|nil
---@param alpha number|nil
AddData = function(self, data, red, green, blue, alpha)
assert(type(data) == "table", "MultiChartFrame:AddData() usage: AddData(table)")
local chartFrame = self:GetChart()
chartFrame:SetColor(red, green, blue, alpha)
chartFrame:SetData(data)
self:SetMaxValueIfBigger(chartFrame:GetMaxValue())
@@ -230,7 +386,9 @@ local MultiChartFrameMixin = {
self:SetMaxDataSize(dataAmount)
end,
--internally handle next line
---internally handle next line
---@param self df_chartmulti
---@return df_chart
GetChart = function(self)
local chartFrame = self.chartFrames[self.nextChartFrame]
if (not chartFrame) then
@@ -244,14 +402,22 @@ local MultiChartFrameMixin = {
return chartFrame
end,
---get all charts added to the multi chart frame
---@param self df_chartmulti
---@return df_chart[]
GetCharts = function(self)
return self.chartFrames
end,
---get the amount of charts added to the multi chart frame
---@param self df_chartmulti
---@return number
GetAmountCharts = function(self)
return self.nextChartFrame - 1
end,
---hide all charts
---@param self df_chartmulti
HideCharts = function(self)
local charts = self:GetCharts()
for i = 1, #charts do
@@ -260,11 +426,17 @@ local MultiChartFrameMixin = {
end
end,
---reset the multi chart frame
---@param self df_chartmulti
Reset = function(self)
self:HideCharts()
self.nextChartFrame = 1
end,
---set the min and max values of all charts
---@param self df_chartmulti
---@param minValue number
---@param maxValue number
SetChartsMinMaxValues = function(self, minValue, maxValue)
local allCharts = self:GetCharts()
for i = 1, self:GetAmountCharts() do
@@ -273,14 +445,29 @@ local MultiChartFrameMixin = {
end
end,
---set the max data size of all charts
---@param self df_chartmulti
---@param dataSize number
SetMaxDataSize = function(self, dataSize)
self.biggestDataValue = max(self.biggestDataValue, dataSize)
self.biggestDataValue = math.max(self.biggestDataValue, dataSize)
end,
---get the max data size of all charts
---@param self df_chartmulti
---@return number
GetMaxDataSize = function(self)
return self.biggestDataValue
end,
---@param self df_chartmulti
---@param value number
SetLineThickness = function(self, value)
assert(type(value) == "number", "number expected on :SetLineThickness(number)")
self.lineThickness = value
end,
---draw all the charts added to the multi chart frame
---@param self df_chartmulti
Plot = function(self)
local minValue, maxValue = self:GetMinMaxValues()
self:SetChartsMinMaxValues(minValue, maxValue)
@@ -292,6 +479,7 @@ local MultiChartFrameMixin = {
local allCharts = self:GetCharts()
for i = 1, self:GetAmountCharts() do
local chartFrame = allCharts[i]
chartFrame:SetLineThickness(self.lineThickness)
chartFrame:SetLineWidth(eachLineWidth)
chartFrame:Plot()
end
@@ -301,14 +489,16 @@ local MultiChartFrameMixin = {
---create a chart frame object with support to multi lines
---@param parent frame
---@param name string|nil
---@return df_chart
function DF:CreateGraphicMultiLineFrame(parent, name)
---@return df_chartmulti
function detailsFramework:CreateGraphicMultiLineFrame(parent, name)
name = name or ("DetailsMultiChartFrameID" .. math.random(1, 10000000))
---@type df_chartmulti
local chartFrame = CreateFrame("frame", name, parent, "BackdropTemplate")
DF:Mixin(chartFrame, DF.ValueMixin)
DF:Mixin(chartFrame, MultiChartFrameMixin)
detailsFramework:Mixin(chartFrame, detailsFramework.ValueMixin)
detailsFramework:Mixin(chartFrame, detailsFramework.MultiChartFrameMixin)
detailsFramework:Mixin(chartFrame, detailsFramework.ChartFrameSharedMixin)
chartFrame:ValueConstructor()
chartFrame:MultiChartFrameConstructor()
+19 -1
View File
@@ -1,6 +1,6 @@
local dversion = 438
local dversion = 439
local major, minor = "DetailsFramework-1.0", dversion
local DF, oldminor = LibStub:NewLibrary(major, minor)
@@ -5358,3 +5358,21 @@ end
-----------------------------------------------------------------------------------------------------------------------------------------------------------
---receives an object and print debug info about its visibility
---use to know why a frame is not showing
---@param UIObject any
function DF:DebugVisibility(UIObject)
local bIsShown = UIObject:IsShown()
print("Is Shown:", bIsShown and "|cFF00FF00true|r" or "|cFFFF0000false|r")
local bIsVisible = UIObject:IsVisible()
print("Is Visible:", bIsVisible and "|cFF00FF00true|r" or "|cFFFF0000false|r")
local width, height = UIObject:GetSize()
print("Width:", width > 0 and "|cFF00FF00" .. width .. "|r" or "|cFFFF00000|r")
print("Height:", height > 0 and "|cFF00FF00" .. height .. "|r" or "|cFFFF00000|r")
local numPoints = UIObject:GetNumPoints()
print("Num Points:", numPoints > 0 and "|cFF00FF00" .. numPoints .. "|r" or "|cFFFF00000|r")
end
+58 -13
View File
@@ -717,18 +717,22 @@ detailsFramework.SortFunctions = {
end
}
---@class data : table
---@field data table
---@class df_data : table
---@field _dataInfo {data: table, dataCurrentIndex: number, callbacks: function[]}
---@field callbacks table<function, any[]>
---@field dataCurrentIndex number
---@field callbacks table
---@field DataConstructor fun(self: data)
---@field AddDataChangeCallback fun(self: data, callback: function, ...: any)
---@field RemoveDataChangeCallback fun(self: data, callback: function)
---@field GetData fun(self: data)
---@field SetData fun(self: data, data: table)
---@field GetDataNextValue fun(self: data) : any
---@field ResetDataIndex fun(self: data)
---@field DataConstructor fun(self: df_data)
---@field AddDataChangeCallback fun(self: df_data, callback: function, ...: any)
---@field RemoveDataChangeCallback fun(self: df_data, callback: function)
---@field GetData fun(self: df_data)
---@field GetDataSize fun(self: df_data) : number
---@field GetDataFirstValue fun(self: df_data) : any
---@field GetDataLastValue fun(self: df_data) : any
---@field GetDataMinMaxValues fun(self: df_data) : number, number
---@field GetDataMinMaxValueFromSubTable fun(self: df_data, key: string) : number, number when data uses sub tables, get the min max values from a specific index or key, if the value stored is number, return the min and max values
---@field SetData fun(self: df_data, data: table)
---@field GetDataNextValue fun(self: df_data) : any
---@field ResetDataIndex fun(self: df_data)
---mixin to use with DetailsFramework:Mixin(table, detailsFramework.DataMixin)
---add 'data' to a table, this table can be used to store data for the object
@@ -822,6 +826,7 @@ detailsFramework.DataMixin = {
end,
---get the min and max values from the data table, if the value stored is number, return the min and max values
---could be used together with SetMinMaxValues from the df_value mixin
---@param self table
---@return number, number
GetDataMinMaxValues = function(self)
@@ -865,45 +870,85 @@ detailsFramework.DataMixin = {
end,
}
---@class df_value : table
---@field minValue number
---@field maxValue number
---@field ValueConstructor fun(self: df_value)
---@field SetMinMaxValues fun(self: df_value, minValue: number, maxValue: number)
---@field GetMinMaxValues fun(self: df_value) : number, number
---@field GetMinValue fun(self: df_value) : number
---@field GetMaxValue fun(self: df_value) : number
---@field SetMinValue fun(self: df_value, minValue: number)
---@field SetMinValueIfLower fun(self: df_value, ...: number)
---@field SetMaxValue fun(self: df_value, maxValue: number)
---@field SetMaxValueIfBigger fun(self: df_value, ...: number)
---mixin to use with DetailsFramework:Mixin(table, detailsFramework.ValueMixin)
---add support to min value and max value into a table or object
---@class DetailsFramework.ValueMixin
detailsFramework.ValueMixin = {
---initialize the value table
---@param self table
ValueConstructor = function(self)
self.minValue = 0
self.maxValue = 1
end,
---set the min and max values
---@param self table
---@param minValue number
---@param maxValue number
SetMinMaxValues = function(self, minValue, maxValue)
self.minValue = minValue
self.maxValue = maxValue
end,
---get the min and max values
---@param self table
---@return number, number
GetMinMaxValues = function(self)
return self.minValue, self.maxValue
end,
---get the min value
---@param self table
---@return number
GetMinValue = function(self)
return self.minValue
end,
---get the max value
---@param self table
---@return number
GetMaxValue = function(self)
return self.maxValue
end,
---set the min value
---@param self table
---@param minValue number
SetMinValue = function(self, minValue)
self.minValue = minValue
end,
---set the min value if one of the values passed is lower than the current min value
---@param self table
---@param ... number
SetMinValueIfLower = function(self, ...)
self.minValue = min(self.minValue, ...)
self.minValue = math.min(self.minValue, ...)
end,
---set the max value
---@param self table
---@param maxValue number
SetMaxValue = function(self, maxValue)
self.maxValue = maxValue
end,
---set the max value if one of the values passed is bigger than the current max value
---@param self table
---@param ... number
SetMaxValueIfBigger = function(self, ...)
self.maxValue = max(self.maxValue, ...)
self.maxValue = math.max(self.maxValue, ...)
end,
}
+6 -2
View File
@@ -196,9 +196,13 @@
---@field Stop fun(self: animation)
---@class line : uiobject
---@field SetStartPoint fun(self: line, point: anchorpoint, relativeFrame: uiobject, relativePoint: anchorpoint, xOffset: number, yOffset: number)
---@field SetEndPoint fun(self: line, point: anchorpoint, relativeFrame: uiobject, relativePoint: anchorpoint, xOffset: number, yOffset: number)
---@field GetEndPoint fun(self: line) : relativePoint: anchorpoint, relativeTo: anchorpoint, offsetX: number, offsetY: number
---@field GetStartPoint fun(self: line) : relativePoint: anchorpoint, relativeTo: anchorpoint, offsetX: number, offsetY: number
---@field GetThickness fun(self: line) : number
---@field SetStartPoint fun(self: line, point: anchorpoint, relativeFrame: uiobject|number, relativePoint: anchorpoint|number, xOffset: number|nil, yOffset: number|nil)
---@field SetEndPoint fun(self: line, point: anchorpoint, relativeFrame: uiobject|number, relativePoint: anchorpoint|number, xOffset: number|nil, yOffset: number|nil)
---@field SetColorTexture fun(self: line, red: number, green: number, blue: number, alpha: number)
---@field SetThickness fun(self: line, thickness: number)
---@class frame : uiobject
---@field CreateLine fun(self: frame, name: string|nil, drawLayer: drawlayer, templateName: string|nil, subLevel: number|nil) : line
+6 -6
View File
@@ -67,10 +67,10 @@
--api functions
--combat (container type, actor name)
Details.call_combate = function(self, class_type, name)
local container = self[class_type]
local index_mapa = container._NameIndexTable [name]
local actor = container._ActorTable [index_mapa]
Details.call_combate = function(self, classType, actorName)
local container = self[classType]
local index_mapa = container._NameIndexTable[actorName]
local actor = container._ActorTable[index_mapa]
return actor
end
classCombat.__call = Details.call_combate
@@ -81,7 +81,7 @@
end
--set the combat date
function classCombat:SetDate (started, ended)
function classCombat:SetDate(started, ended)
if (started and type(started) == "string") then
self.data_inicio = started
end
@@ -95,7 +95,7 @@
return self.TimeData[name]
end
function classCombat:GetContainer (attribute)
function classCombat:GetContainer(attribute)
return self [attribute]
end
+25 -3
View File
@@ -16,6 +16,9 @@ local _UnitName = UnitName --wow api locals
local _UnitIsPlayer = UnitIsPlayer --wow api locals
local _UnitGroupRolesAssigned = DetailsFramework.UnitGroupRolesAssigned --wow api locals
local segmentClass = Details.historico
local combatClass = Details.combate
local _detalhes = _G.Details
local _
local addonName, Details222 = ...
@@ -217,11 +220,30 @@ local instanceMixins = {
---@type segmentid
local segmentId = instance:GetSegmentId()
if (segmentId == DETAILS_SEGMENTID_OVERALL) then
instance.showing = Details:GetOverallCombat()
---@type combat
local combatObject = Details:GetOverallCombat()
if (combatObject.__destroyed) then
combatObject = combatClass:NovaTabela()
end
instance.showing = combatObject
elseif (segmentId == DETAILS_SEGMENTID_CURRENT) then
instance.showing = Details:GetCurrentCombat()
---@type combat
local combatObject = Details:GetCurrentCombat()
if (combatObject.__destroyed) then
combatObject = combatClass:NovaTabela(nil, Details.tabela_overall)
end
instance.showing = combatObject
else
instance.showing = Details:GetCombat(segmentId)
---@type combat
local combatObject = Details:GetCombat(segmentId)
if (combatObject.__destroyed) then
table.remove(Details:GetCombatSegments(), segmentId)
combatObject = combatClass:NovaTabela()
table.insert(Details:GetCombatSegments(), segmentId, combatObject)
end
instance.showing = combatObject
end
---@type combat
+24 -15
View File
@@ -314,7 +314,6 @@ function segmentClass:AddCombat(combatObject)
for _, actorObject in containerHeal:ListActors() do
---@cast actorObject actor
--clear last events table
actorObject.last_events_table = nil
Details222.TimeMachine.RemoveActor(actorObject)
end
@@ -344,8 +343,10 @@ function segmentClass:AddCombat(combatObject)
end
end
local segmentsTable = Details.tabela_historico.tabelas
--check if the segment table is full
if (#segmentTable > maxSegmentsAllowed) then
if (#segmentsTable > maxSegmentsAllowed) then
---@type combat
local combatObjectToBeRemoved
---@type number
@@ -357,7 +358,7 @@ function segmentClass:AddCombat(combatObject)
local bossId = combatObject.is_boss and combatObject.is_boss.id
---@type combat
local oldestSegment = segmentTable[#segmentTable]
local oldestSegment = segmentsTable[#segmentsTable]
local oldestBossId = oldestSegment.is_boss and oldestSegment.is_boss.id
if (Details.zone_type == "raid" and bossId and oldestBossId and bossId == oldestBossId) then
@@ -367,9 +368,9 @@ function segmentClass:AddCombat(combatObject)
local shorterSegmentId
local minTime = 99999
for segmentId = 4, #segmentTable do
for segmentId = 4, #segmentsTable do
---@type combat
local thisCombatObject = segmentTable[segmentId]
local thisCombatObject = segmentsTable[segmentId]
if (thisCombatObject.is_boss and thisCombatObject.is_boss.id == bossId and thisCombatObject:GetCombatTime() < minTime and not thisCombatObject.is_boss.killed) then
shorterCombatObject = thisCombatObject
shorterSegmentId = segmentId
@@ -385,8 +386,8 @@ function segmentClass:AddCombat(combatObject)
--if couldn't find a boss to remove, then remove the oldest segment
if (not combatObjectToBeRemoved) then
combatObjectToBeRemoved = segmentTable[#segmentTable]
segmentIdToBeRemoved = #segmentTable
combatObjectToBeRemoved = segmentsTable[#segmentsTable]
segmentIdToBeRemoved = #segmentsTable
end
--check time machine
@@ -398,14 +399,17 @@ function segmentClass:AddCombat(combatObject)
end
--remove it
segmentsTable = Details.tabela_historico.tabelas
---@type combat
local combatObjectRemoved = table.remove(segmentTable, segmentIdToBeRemoved)
local combatObjectRemoved = table.remove(segmentsTable, segmentIdToBeRemoved)
if (combatObjectRemoved) then
Details:DestroyCombat(combatObjectRemoved)
Details:SendEvent("DETAILS_DATA_SEGMENTREMOVED")
end
end
Details:InstanceCall(function(instanceObject) instanceObject:RefreshCombat() end)
--update the combat shown on all instances
Details:InstanciaCallFunction(Details.AtualizaSegmentos_AfterCombat, self)
end
@@ -499,15 +503,19 @@ function segmentClass:ResetAllCombatData()
--empty temporary tables
Details.atributo_damage:ClearTempTables()
for _, combatObject in ipairs(Details.tabela_historico.tabelas) do
---@cast combatObject combat
Details:DestroyCombat(combatObject)
for i = #Details.tabela_historico.tabelas, 1, -1 do
---@type combat
local combtaObjectRemoved = table.remove(Details.tabela_historico.tabelas, i)
Details:DestroyCombat(combtaObjectRemoved)
Details:SendEvent("DETAILS_DATA_SEGMENTREMOVED")
end
--the current combat when finished will be moved to the first index of "tabela_historico.tabelas", need the check if the current combat was already destroyed
if (not Details.tabela_vigente.__destroyed) then
Details:DestroyCombat(Details.tabela_vigente)
if (Details.tabela_vigente == Details.tabela_historico.tabelas[1]) then
table.remove(Details.tabela_historico.tabelas, 1)
end
Details:SendEvent("DETAILS_DATA_SEGMENTREMOVED")
end
@@ -525,15 +533,16 @@ function segmentClass:ResetAllCombatData()
-- novo container de historico
Details.tabela_historico = segmentClass:CreateNewSegmentDatabase() --joga fora a tabela antiga e cria uma nova
--novo container para armazenar pets
Details.tabela_pets = Details.container_pets:NovoContainer()
Details:UpdateContainerCombatentes()
Details.container_pets:BuscarPets()
-- nova tabela do overall e current
Details.tabela_overall = combatClass:NovaTabela() --joga fora a tabela antiga e cria uma nova
-- cria nova tabela do combate atual
Details.tabela_vigente = combatClass:NovaTabela(nil, Details.tabela_overall)
--novo container para armazenar pets
Details.tabela_pets = Details.container_pets:NovoContainer()
Details:UpdateContainerCombatentes()
Details.container_pets:BuscarPets()
---@type instance[]
local allInstances = Details:GetAllInstances()
+95 -80
View File
@@ -7,16 +7,30 @@
--create a namespace
Details222.TimeCapture = {}
--mantain the enabled time captures
Details.timeContainer = {}
Details.timeContainer.Exec = {}
---@class timedataexec : table
---@field func function
---@field data table
---@field attributes table
---@field is_user boolean
---mantain the enabled time captures
---@class timedatacontainer : table
---@field Exec timedataexec[]
---@class timedatasaved : {key1: string, key2: function, key3: table, key4: string, key5: string, key6: string, key7: boolean}
---@field do_not_save boolean
do
---@type timedatacontainer
local timeContainer = {}
Details.timeContainer = timeContainer
Details.timeContainer.Exec = {}
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--local pointers
local ipairs = ipairs
local _math_floor = math.floor
local _pcall = pcall
local time = time
local pcall = pcall
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--constants
@@ -29,44 +43,47 @@
local INDEX_ICON = 6
local INDEX_ENABLED = 7
local DEFAULT_USER_MATRIX = {max_value = 0, last_value = 0}
local DEFAULT_USER_MATRIX = {
max_value = 0,
last_value = 0
}
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--register and unregister captures
function Details:TimeDataUpdate (index_or_name, name, func, matrix, author, version, icon, is_enabled)
local this_capture
local thisCapture
if (type(index_or_name) == "number") then
this_capture = Details.savedTimeCaptures [index_or_name]
thisCapture = Details.savedTimeCaptures[index_or_name]
else
for index, t in ipairs(Details.savedTimeCaptures) do
if (t [INDEX_NAME] == index_or_name) then
this_capture = t
for index, timeDataSaved in ipairs(Details.savedTimeCaptures) do
---@cast timeDataSaved timedatasaved
if (timeDataSaved [INDEX_NAME] == index_or_name) then
thisCapture = timeDataSaved
end
end
end
if (not this_capture) then
if (not thisCapture) then
return false
end
if (this_capture.do_not_save) then
if (thisCapture.do_not_save) then
return Details:Msg("This capture belongs to a plugin and cannot be edited.")
end
this_capture [INDEX_NAME] = name or this_capture [INDEX_NAME]
this_capture [INDEX_FUNCTION] = func or this_capture [INDEX_FUNCTION]
this_capture [INDEX_MATRIX] = matrix or this_capture [INDEX_MATRIX]
this_capture [INDEX_AUTHOR] = author or this_capture [INDEX_AUTHOR]
this_capture [INDEX_VERSION] = version or this_capture [INDEX_VERSION]
this_capture [INDEX_ICON] = icon or this_capture [INDEX_ICON]
thisCapture[INDEX_NAME] = name or thisCapture[INDEX_NAME]
thisCapture[INDEX_FUNCTION] = func or thisCapture[INDEX_FUNCTION]
thisCapture[INDEX_MATRIX] = matrix or thisCapture[INDEX_MATRIX]
thisCapture[INDEX_AUTHOR] = author or thisCapture[INDEX_AUTHOR]
thisCapture[INDEX_VERSION] = version or thisCapture[INDEX_VERSION]
thisCapture[INDEX_ICON] = icon or thisCapture[INDEX_ICON]
if (is_enabled ~= nil) then
this_capture [INDEX_ENABLED] = is_enabled
thisCapture[INDEX_ENABLED] = is_enabled
else
this_capture [INDEX_ENABLED] = this_capture [INDEX_ENABLED]
thisCapture[INDEX_ENABLED] = thisCapture[INDEX_ENABLED]
end
if (_G.DetailsOptionsWindow and _G.DetailsOptionsWindow:IsShown()) then
@@ -74,41 +91,40 @@
end
return true
end
--matrix = table containing {max_value = 0, last_value = 0}
function Details:TimeDataRegister(name, func, matrix, author, version, icon, is_enabled, force_no_save)
function Details:TimeDataRegister(timeDataName, callbackFunc, matrix, author, version, icon, bIsEnabled, bForceNoSave)
--check name
if (not name) then
if (not timeDataName) then
return "Couldn't register the time capture, name was nil."
end
--check if the name already exists
for index, t in ipairs(Details.savedTimeCaptures) do
if (t [INDEX_NAME] == name) then
if (t [INDEX_NAME] == timeDataName) then
return "Couldn't register the time capture, name already registred."
end
end
--check function
if (not func) then
if (not callbackFunc) then
return "Couldn't register the time capture, invalid function."
end
local no_save = nil
--passed a function means that this isn't came from a user
--so the plugin register the capture every time it loads.
if (type(func) == "function") then
if (type(callbackFunc) == "function") then
no_save = true
--this a custom capture from a user, so we register a default user table for matrix
elseif (type(func) == "string") then
elseif (type(callbackFunc) == "string") then
matrix = DEFAULT_USER_MATRIX
end
if (not no_save and force_no_save) then
if (not no_save and bForceNoSave) then
no_save = true
end
@@ -121,27 +137,26 @@
version = version or "v1.0"
icon = icon or [[Interface\InventoryItems\WoWUnknownItem01]]
tinsert(Details.savedTimeCaptures, {name, func, matrix, author, version, icon, is_enabled, do_not_save = no_save})
table.insert(Details.savedTimeCaptures, {timeDataName, callbackFunc, matrix, author, version, icon, bIsEnabled, do_not_save = no_save})
if (_G.DetailsOptionsWindow and _G.DetailsOptionsWindow:IsShown()) then
DetailsOptionsWindowTab17UserTimeCapturesFillPanel.MyObject:Refresh()
end
return true
end
--unregister
function Details:TimeDataUnregister (name)
if (type(name) == "number") then
tremove(Details.savedTimeCaptures, name)
table.remove(Details.savedTimeCaptures, name)
if (_G.DetailsOptionsWindow and _G.DetailsOptionsWindow:IsShown()) then
DetailsOptionsWindowTab17UserTimeCapturesFillPanel.MyObject:Refresh()
end
else
for index, t in ipairs(Details.savedTimeCaptures) do
if (t [INDEX_NAME] == name) then
tremove(Details.savedTimeCaptures, index)
table.remove(Details.savedTimeCaptures, index)
if (_G.DetailsOptionsWindow and _G.DetailsOptionsWindow:IsShown()) then
DetailsOptionsWindowTab17UserTimeCapturesFillPanel.MyObject:Refresh()
end
@@ -154,16 +169,19 @@
--cleanup when logout
function Details:TimeDataCleanUpTemporary()
---@type timedatasaved[]
local newData = {}
for index, t in ipairs(Details.savedTimeCaptures) do
if (not t.do_not_save) then
tinsert(newData, t)
for index, timeDataSaved in ipairs(Details.savedTimeCaptures) do
if (not timeDataSaved.do_not_save) then
table.insert(newData, timeDataSaved)
end
end
Details.savedTimeCaptures = newData
end
local tick_time = 0
local tickTime = 0
--starting a combat
function Details:TimeDataCreateChartTables()
@@ -171,54 +189,58 @@
local chartTables = {}
--drop the last capture exec table without wiping
---@type timedataexec
local exec = {}
Details.timeContainer.Exec = exec
Details:SendEvent("COMBAT_CHARTTABLES_CREATING")
--build the exec table
for index, t in ipairs(Details.savedTimeCaptures) do
if (t[INDEX_ENABLED]) then
for index, chartData in ipairs(Details.savedTimeCaptures) do
if (chartData[INDEX_ENABLED]) then
local data = {}
chartTables[t[INDEX_NAME]] = data
chartTables[chartData[INDEX_NAME]] = data
if (type(t[INDEX_FUNCTION]) == "string") then
if (type(chartData[INDEX_FUNCTION]) == "string") then
--user
local func, errortext = loadstring(t[INDEX_FUNCTION])
local func, errortext = loadstring(chartData[INDEX_FUNCTION])
if (func) then
DetailsFramework:SetEnvironment(func)
tinsert(exec, {func = func, data = data, attributes = Details.CopyTable(t[INDEX_MATRIX]), is_user = true})
---@type timedataexec
local timeDataTable = {func = func, data = data, attributes = Details.CopyTable(chartData[INDEX_MATRIX]), is_user = true}
table.insert(exec, timeDataTable)
else
Details:Msg("|cFFFF9900error compiling script for time data (charts)|r: ", errortext)
end
else
--plugin
local func = t[INDEX_FUNCTION]
local func = chartData[INDEX_FUNCTION]
DetailsFramework:SetEnvironment(func)
tinsert(exec, {func = func, data = data, attributes = Details.CopyTable(t[INDEX_MATRIX])})
---@type timedataexec
local timeDataTable = {func = func, data = data, attributes = Details.CopyTable(chartData[INDEX_MATRIX])}
table.insert(exec, timeDataTable)
end
end
end
Details:SendEvent("COMBAT_CHARTTABLES_CREATED")
tick_time = 0
tickTime = 0
--return the capture table the to combat object
return chartTables
end
local exec_user_func = function(func, attributes, data, this_second)
local okey, result = _pcall (func, attributes)
local execUserFunc = function(func, attributes, data, thisSecond)
local okey, result = pcall(func, attributes)
if (not okey) then
Details:Msg("|cFFFF9900error on chart script function|r:", result)
result = 0
end
local current = result - attributes.last_value
data [this_second] = current
data[thisSecond] = current
if (current > attributes.max_value) then
attributes.max_value = current
@@ -226,27 +248,20 @@
end
attributes.last_value = result
end
function Details:TimeDataTick()
tick_time = tick_time + 1
for index, t in ipairs(Details.timeContainer.Exec) do
if (t.is_user) then
tickTime = tickTime + 1
for index, timeDataTable in ipairs(Details.timeContainer.Exec) do
---@cast timeDataTable timedataexec
if (timeDataTable.is_user) then
--by a user
exec_user_func (t.func, t.attributes, t.data, tick_time)
execUserFunc(timeDataTable.func, timeDataTable.attributes, timeDataTable.data, tickTime)
else
--by a plugin
t.func (t.attributes, t.data, tick_time)
timeDataTable.func(timeDataTable.attributes, timeDataTable.data, tickTime)
end
end
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@@ -262,7 +277,7 @@
if (not combatTime or combatTime == 0) then
return 0
else
return ToKFunctions [Details.minimap.text_format] (_, combat.totals_grupo[1] / combatTime)
return ToKFunctions[Details.minimap.text_format](_, combat.totals_grupo[1] / combatTime)
end
end,
-- raid hps [2]
@@ -272,7 +287,7 @@
if (not combatTime or combatTime == 0) then
return 0
else
return ToKFunctions [Details.minimap.text_format] (_, combat.totals_grupo[2] / combatTime)
return ToKFunctions[Details.minimap.text_format](_, combat.totals_grupo[2] / combatTime)
end
end
}
@@ -280,7 +295,7 @@
local get_combat_time = function()
local combat_time = Details.tabela_vigente:GetCombatTime()
local minutos, segundos = _math_floor(combat_time / 60), _math_floor(combat_time % 60)
local minutos, segundos = math.floor(combat_time / 60), math.floor(combat_time % 60)
if (segundos < 10) then
segundos = "0" .. segundos
end
@@ -288,8 +303,8 @@
end
local get_damage_position = function()
local damage_container = Details.tabela_vigente [1]
damage_container:SortByKey ("total")
local damage_container = Details.tabela_vigente[1]
damage_container:SortByKey("total")
local pos = 1
for index, actor in ipairs(damage_container._ActorTable) do
@@ -305,8 +320,8 @@
end
local get_heal_position = function()
local heal_container = Details.tabela_vigente [2]
heal_container:SortByKey ("total")
local heal_container = Details.tabela_vigente[2]
heal_container:SortByKey("total")
local pos = 1
for index, actor in ipairs(heal_container._ActorTable) do
@@ -322,8 +337,8 @@
end
local get_damage_diff = function()
local damage_container = Details.tabela_vigente [1]
damage_container:SortByKey ("total")
local damage_container = Details.tabela_vigente[1]
damage_container:SortByKey("total")
local first
local first_index
@@ -348,18 +363,18 @@
if (second) then
local diff = first.total - second.total
return "+" .. ToKFunctions [Details.minimap.text_format] (_, diff)
return "+" .. ToKFunctions[Details.minimap.text_format] (_, diff)
else
return "0"
end
else
local player = damage_container._NameIndexTable [Details.playername]
local player = damage_container._NameIndexTable[Details.playername]
if (player) then
player = damage_container._ActorTable [player]
player = damage_container._ActorTable[player]
local diff = first.total - player.total
return "-" .. ToKFunctions [Details.minimap.text_format] (_, diff)
return "-" .. ToKFunctions[Details.minimap.text_format](_, diff)
else
return ToKFunctions [Details.minimap.text_format] (_, first.total)
return ToKFunctions[Details.minimap.text_format](_, first.total)
end
end
else