translated code to English and a few bug fixes from latest alpha
This commit is contained in:
+59
-2
@@ -6,6 +6,50 @@
|
||||
---| "TOOLBAR"
|
||||
---| "STATUSBAR"
|
||||
|
||||
---@alias detailsevent
|
||||
---| "DETAILS_INSTANCE_OPEN"
|
||||
---| "DETAILS_INSTANCE_CLOSE"
|
||||
---| "DETAILS_INSTANCE_SIZECHANGED"
|
||||
---| "DETAILS_INSTANCE_STARTRESIZE"
|
||||
---| "DETAILS_INSTANCE_ENDRESIZE"
|
||||
---| "DETAILS_INSTANCE_STARTSTRETCH"
|
||||
---| "DETAILS_INSTANCE_ENDSTRETCH"
|
||||
---| "DETAILS_INSTANCE_CHANGESEGMENT"
|
||||
---| "DETAILS_INSTANCE_CHANGEATTRIBUTE"
|
||||
---| "DETAILS_INSTANCE_CHANGEMODE"
|
||||
---| "DETAILS_INSTANCE_NEWROW"
|
||||
---| "DETAILS_OPTIONS_MODIFIED"
|
||||
---| "DETAILS_DATA_RESET"
|
||||
---| "DETAILS_DATA_SEGMENTREMOVED"
|
||||
---| "COMBAT_ENCOUNTER_START"
|
||||
---| "COMBAT_ENCOUNTER_END"
|
||||
---| "COMBAT_PLAYER_ENTER"
|
||||
---| "COMBAT_PLAYER_LEAVE"
|
||||
---| "COMBAT_PLAYER_TIMESTARTED"
|
||||
---| "COMBAT_BOSS_WIPE"
|
||||
---| "COMBAT_BOSS_DEFEATED"
|
||||
---| "COMBAT_BOSS_FOUND"
|
||||
---| "COMBAT_INVALID"
|
||||
---| "COMBAT_PREPOTION_UPDATED"
|
||||
---| "COMBAT_CHARTTABLES_CREATING"
|
||||
---| "COMBAT_CHARTTABLES_CREATED"
|
||||
---| "COMBAT_ENCOUNTER_PHASE_CHANGED"
|
||||
---| "COMBAT_ARENA_START"
|
||||
---| "COMBAT_ARENA_END"
|
||||
---| "COMBAT_MYTHICDUNGEON_START"
|
||||
---| "COMBAT_MYTHICDUNGEON_END"
|
||||
---| "GROUP_ONENTER"
|
||||
---| "GROUP_ONLEAVE"
|
||||
---| "ZONE_TYPE_CHANGED"
|
||||
---| "REALM_CHANNEL_ENTER"
|
||||
---| "REALM_CHANNEL_LEAVE"
|
||||
---| "COMM_EVENT_RECEIVED"
|
||||
---| "COMM_EVENT_SENT"
|
||||
---| "UNIT_SPEC"
|
||||
---| "UNIT_TALENTS"
|
||||
---| "PLAYER_TARGET"
|
||||
---| "DETAILS_PROFILE_APPLYED"
|
||||
|
||||
---@alias containertype number this container type is the number used to identify the actorcontainer type when using combat:GetContainer(containertype), can be 1, 2, 3, or 4.
|
||||
|
||||
---@class details
|
||||
@@ -18,8 +62,19 @@
|
||||
---@field CreateEventListener fun(self: details) : table
|
||||
|
||||
---@class detailseventlistener : table
|
||||
---@field RegisterEvent fun(self: detailseventlistener, event: "DETAILS_INSTANCE_OPEN"|"DETAILS_INSTANCE_CLOSE"|"DETAILS_INSTANCE_SIZECHANGED"|"DETAILS_INSTANCE_STARTRESIZE"|"DETAILS_INSTANCE_ENDRESIZE"|"DETAILS_INSTANCE_STARTSTRETCH"|"DETAILS_INSTANCE_ENDSTRETCH"|"DETAILS_INSTANCE_CHANGESEGMENT"|"DETAILS_INSTANCE_CHANGEATTRIBUTE"|"DETAILS_INSTANCE_CHANGEMODE"|"DETAILS_INSTANCE_NEWROW"|"DETAILS_OPTIONS_MODIFIED"|"DETAILS_DATA_RESET"|"DETAILS_DATA_SEGMENTREMOVED"|"COMBAT_ENCOUNTER_START"|"COMBAT_ENCOUNTER_END"|"COMBAT_PLAYER_ENTER"|"COMBAT_PLAYER_LEAVE"|"COMBAT_PLAYER_TIMESTARTED"|"COMBAT_BOSS_WIPE"|"COMBAT_BOSS_DEFEATED"|"COMBAT_BOSS_FOUND"|"COMBAT_INVALID"|"COMBAT_PREPOTION_UPDATED"|"COMBAT_CHARTTABLES_CREATING"|"COMBAT_CHARTTABLES_CREATED"|"COMBAT_ENCOUNTER_PHASE_CHANGED"|"COMBAT_ARENA_START"|"COMBAT_ARENA_END"|"COMBAT_MYTHICDUNGEON_START"|"COMBAT_MYTHICDUNGEON_END"|"GROUP_ONENTER"|"GROUP_ONLEAVE"|"ZONE_TYPE_CHANGED"|"REALM_CHANNEL_ENTER"|"REALM_CHANNEL_LEAVE"|"COMM_EVENT_RECEIVED"|"COMM_EVENT_SENT"|"UNIT_SPEC"|"UNIT_TALENTS"|"PLAYER_TARGET"|"DETAILS_PROFILE_APPLYED", callback: function)
|
||||
---@field UnregisterEvent fun(self: detailseventlistener, event: "DETAILS_INSTANCE_OPEN"|"DETAILS_INSTANCE_CLOSE"|"DETAILS_INSTANCE_SIZECHANGED"|"DETAILS_INSTANCE_STARTRESIZE"|"DETAILS_INSTANCE_ENDRESIZE"|"DETAILS_INSTANCE_STARTSTRETCH"|"DETAILS_INSTANCE_ENDSTRETCH"|"DETAILS_INSTANCE_CHANGESEGMENT"|"DETAILS_INSTANCE_CHANGEATTRIBUTE"|"DETAILS_INSTANCE_CHANGEMODE"|"DETAILS_INSTANCE_NEWROW"|"DETAILS_OPTIONS_MODIFIED"|"DETAILS_DATA_RESET"|"DETAILS_DATA_SEGMENTREMOVED"|"COMBAT_ENCOUNTER_START"|"COMBAT_ENCOUNTER_END"|"COMBAT_PLAYER_ENTER"|"COMBAT_PLAYER_LEAVE"|"COMBAT_PLAYER_TIMESTARTED"|"COMBAT_BOSS_WIPE"|"COMBAT_BOSS_DEFEATED"|"COMBAT_BOSS_FOUND"|"COMBAT_INVALID"|"COMBAT_PREPOTION_UPDATED"|"COMBAT_CHARTTABLES_CREATING"|"COMBAT_CHARTTABLES_CREATED"|"COMBAT_ENCOUNTER_PHASE_CHANGED"|"COMBAT_ARENA_START"|"COMBAT_ARENA_END"|"COMBAT_MYTHICDUNGEON_START"|"COMBAT_MYTHICDUNGEON_END"|"GROUP_ONENTER"|"GROUP_ONLEAVE"|"ZONE_TYPE_CHANGED"|"REALM_CHANNEL_ENTER"|"REALM_CHANNEL_LEAVE"|"COMM_EVENT_RECEIVED"|"COMM_EVENT_SENT"|"UNIT_SPEC"|"UNIT_TALENTS"|"PLAYER_TARGET"|"DETAILS_PROFILE_APPLYED")
|
||||
---@field RegisterEvent fun(self: detailseventlistener, event: detailsevent, callback: function)
|
||||
---@field UnregisterEvent fun(self: detailseventlistener, event: detailsevent)
|
||||
|
||||
---@class deathtable : table
|
||||
---@field key1 any[] what happened to the player before death
|
||||
---@field key2 number unix time
|
||||
---@field key3 string player name
|
||||
---@field key4 string player class
|
||||
---@field key5 number max health
|
||||
---@field key6 string time of death as string
|
||||
---@field dead boolean just a boolean to indicate this is a death table
|
||||
---@field last_cooldown {key1: unixtime, key2: spellid}
|
||||
---@field dead_at number combatElapsedTime
|
||||
|
||||
---@class customspellinfo : {name: string, isPassive: boolean, itemId: number, icon: string|number}
|
||||
---@class customiteminfo: {itemId: number, isPassive: boolean}
|
||||
@@ -43,6 +98,8 @@
|
||||
---@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 PhaseData table
|
||||
---@field is_boss table
|
||||
---@field GetTimeData fun(dataName: string) : table
|
||||
---@field GetPhases fun(combat: combat) : table
|
||||
---@field GetCombatTime fun(combat) : number
|
||||
|
||||
+1
-1
@@ -1317,7 +1317,7 @@ detailsFramework.CloseButtonMixin = {
|
||||
---@param parent frame
|
||||
---@param frameName string|nil
|
||||
---@return df_closebutton
|
||||
function detailsFramework:CreateCloseButton(parent, frameName)
|
||||
function detailsFramework:CreateCloseButton(parent, frameName) --make documentation
|
||||
---@type df_closebutton
|
||||
local closeButton = CreateFrame("button", frameName, parent, "UIPanelCloseButton")
|
||||
closeButton:SetFrameLevel(parent:GetFrameLevel() + 1)
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
|
||||
--documentation: see the header of the file charts.lua
|
||||
|
||||
|
||||
--1º example: making a simple chart, just copy and paste this code into a lua file and run it
|
||||
do
|
||||
local ChartFrameTest = ChartFrameExample1 or DetailsFramework:CreateGraphicLineFrame(UIParent, "ChartFrameExample1")
|
||||
ChartFrameTest:SetPoint("left", UIParent, "left", 10, 0) --set the position of the chart
|
||||
ChartFrameTest:SetSize(800, 600) --set the size of the chart
|
||||
DetailsFramework:ApplyStandardBackdrop(ChartFrameTest) --apply a backdrop to this example hence see the frame size
|
||||
|
||||
--set the data (required)
|
||||
local data = {1, 2, 30, 25, 6, 5, 4, 8, 7, 4, 1, 12, 15, 24, 18, 17, 14, 15, 8, 4, 14, 42, 22, 25, 30, 35, 39, 8, 7, 4, 1, 2, 5, 4, 8, 7, 4, 12, 12, 4}
|
||||
local smoothnessLevel = 1 --(optional, default: 1)
|
||||
ChartFrameTest:SetData(data, smoothnessLevel)
|
||||
--draw the chart
|
||||
ChartFrameTest:Plot()
|
||||
end
|
||||
|
||||
--2º example: setting the color, thickness and scale of the line:
|
||||
do
|
||||
local ChartFrameTest = ChartFrameExample2 or DetailsFramework:CreateGraphicLineFrame(UIParent, "ChartFrameExample2")
|
||||
ChartFrameTest:SetPoint("left", UIParent, "left", 10, 0) --set the position of the chart
|
||||
ChartFrameTest:SetSize(800, 600) --set the size of the chart
|
||||
DetailsFramework:ApplyStandardBackdrop(ChartFrameTest) --apply a backdrop to this example hence see the frame size
|
||||
|
||||
--set the line thickness (optional, default: 2)
|
||||
local lineThickness = 3
|
||||
ChartFrameTest:SetLineThickness(lineThickness)
|
||||
|
||||
--set the chart color (optional, default: "white")
|
||||
local lineColor = {r = 1, g = 1, b = 0} --set it to "yellow"
|
||||
ChartFrameTest:SetColor(lineColor) --using {r = 1, g = 1, b = 0}
|
||||
ChartFrameTest:SetColor("yellow") --using the color name
|
||||
ChartFrameTest:SetColor(1, 1, 0) --passing the rgb directly
|
||||
ChartFrameTest:SetColor({1, 1, 0}) --using an index table
|
||||
|
||||
--set the data (required)
|
||||
local data = {1, 2, 30, 25, 6, 5, 4, 8, 7, 4, 1, 12, 15, 24 ,18, 17 ,14, 15, 8 , 4, 14, 42, 22, 25, 30, 35, 39, 8, 7, 4, 1, 2, 5, 4 ,8, 7 ,4, 12, 12 , 4}
|
||||
local smoothnessLevel = 1 --(optional, default: 1)
|
||||
ChartFrameTest:SetData(data, smoothnessLevel)
|
||||
|
||||
--height modifier, if for some reason need to scale the chart height
|
||||
local heightScale = 1 --(optional, default: 1)
|
||||
--draw the chart
|
||||
ChartFrameTest:Plot(heightScale)
|
||||
end
|
||||
|
||||
--3º example: setting the axes lines and labels
|
||||
do
|
||||
local ChartFrameTest = ChartFrameExample3 or DetailsFramework:CreateGraphicLineFrame(UIParent, "ChartFrameExample3")
|
||||
ChartFrameTest:SetPoint("left", UIParent, "left", 10, 0)
|
||||
ChartFrameTest:SetSize(800, 600)
|
||||
DetailsFramework:ApplyStandardBackdrop(ChartFrameTest)
|
||||
|
||||
--create guide lines in the left and bottom of the chart
|
||||
local xOffset = 48 --pixels from the left border of the chart
|
||||
local yOffset = 28 --pixels from the bottom border of the chart
|
||||
local whichSide = "left" --which side of vertical line should be placed
|
||||
local thickness = 1
|
||||
local amountYLabels = 10 --amounf of texts indicating the scale of the chart
|
||||
local amountXLabels = 10
|
||||
local r, g, b, a = 1, 1, 1, 1
|
||||
ChartFrameTest:CreateAxesLines(xOffset, yOffset, whichSide, thickness, amountYLabels, amountXLabels, r, g, b, a)
|
||||
|
||||
--the labels in the bottom line can be 'time', 'number' or 'value'
|
||||
ChartFrameTest:SetXAxisDataType("time")
|
||||
--set the data to be used in the bottom line labels, how the data is formatted depends on the type set above
|
||||
ChartFrameTest:SetXAxisData(10) --with type 'time' the chart interprets this as seconds and shows 1:00 to 10:00
|
||||
|
||||
ChartFrameTest:SetXAxisDataType("number")
|
||||
ChartFrameTest:SetXAxisData(600) --the chart interprets this as a 'number' type and displays it as 60, 120, 180.
|
||||
|
||||
ChartFrameTest:SetXAxisDataType("value")
|
||||
ChartFrameTest:SetXAxisData("hello", "world", 1, 2, 3, 4, "chart", 0, 1, 0) --and 'value' show the values passed
|
||||
|
||||
--setting the data, doesn't matter if it is set at the top or right before Plot()
|
||||
local data = {1, 2, 30, 25, 6, 5, 4, 8, 7, 4, 1, 12, 15, 24 ,18, 17 ,14, 15, 8 , 4, 14, 42, 22, 25, 30, 35, 39, 8, 7, 4, 1, 2, 5, 4 ,8, 7 ,4, 12, 12 , 4}
|
||||
ChartFrameTest:SetData(data) --smoothnessLevel is absent here, it'll use 1 as default
|
||||
ChartFrameTest:Plot()
|
||||
end
|
||||
|
||||
--4º example: a multi line chart is a chart which supports multiple lines, each line can have a different color, name, smoothnessLevel and thickness
|
||||
do
|
||||
local ChartFrameTest = ChartFrameExample4 or DetailsFramework:CreateGraphicMultiLineFrame(UIParent, "ChartFrameExample4")
|
||||
ChartFrameTest:SetPoint("left", UIParent, "left", 10, 0)
|
||||
ChartFrameTest:SetSize(800, 600)
|
||||
DetailsFramework:ApplyStandardBackdrop(ChartFrameTest)
|
||||
|
||||
--when using multi-line, the Reset() function instructs the chart to discard the previous data as new data is about to be added
|
||||
ChartFrameTest:Reset()
|
||||
|
||||
--smoothnessLevel, name, red, green, blue, alpha
|
||||
local smoothnessLevel = 2 --(optional, default: 0)
|
||||
local line1Name, line2Name, line3Name = "Line 1", "Line 2", "Line 3" --show the line name at the top right corner (optional, default none)
|
||||
local line1Color, line2Color, line3Color = "lime", "purple", "orange" --(optional, default "white")
|
||||
|
||||
--add data into the chart (it plots a line for each data added when :Plot() is called)
|
||||
local data1 = {1, 2, 30, 25, 6, 5, 4, 8, 7, 4, 1, 12, 15, 24 ,18, 17 ,14, 15, 8 , 4, 14, 42, 22, 25, 30, 35, 39, 8, 7, 4, 1, 2, 5, 4}
|
||||
ChartFrameTest:AddData(data1, smoothnessLevel, line1Name, line1Color)
|
||||
|
||||
local data2 = {3, 5, 20, 25, 6, 5, 15, 18, 12, 14, 11, 8, 7, 8 ,7, 4 ,1, 25, 26 , 30, 28, 20, 22, 25, 20, 15, 10, 8, 7, 4, 1, 2, 5, 4}
|
||||
ChartFrameTest:AddData(data2, smoothnessLevel, line2Name, line2Color)
|
||||
|
||||
local data3 = {5, 7, 15, 30, 6, 2, 10, 13, 10, 5, 11, 8, 7, 5, 3, 1, 1, 8, 10 , 12, 15, 20, 25, 25, 20, 17, 12, 7, 7, 6, 4, 5, 6, 5}
|
||||
ChartFrameTest:AddData(data3, smoothnessLevel, line3Name, line3Color)
|
||||
|
||||
ChartFrameTest:Plot()
|
||||
end
|
||||
+484
-107
@@ -6,48 +6,95 @@ end
|
||||
|
||||
local CreateFrame = CreateFrame
|
||||
local unpack = unpack
|
||||
local wipe = table.wipe
|
||||
local _
|
||||
|
||||
---@class chart_guideline : fontstring
|
||||
---@field circleTexture texture
|
||||
---@field guideLine line
|
||||
|
||||
---@class chart_nameindicator : frame
|
||||
---@field Texture texture
|
||||
---@field Label fontstring
|
||||
|
||||
---@alias x_axisdatatype
|
||||
---| "time" when setting the text into the labels, it will be converted into a time format
|
||||
---| "number" same as timer, but the number is not comverted to time
|
||||
---| "value" a fixed table with values is passed by the SetXAxisData() function
|
||||
|
||||
---@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
|
||||
---@field xAxisLine line the horizontal line which can be anchored in the top or bottom side of the frame, if the chart is a multi chart, this line is shared by all charts
|
||||
---@field xAxisDataNumber any if the data type of the x axis is "number" or "time"
|
||||
---@field xAxisDataValues table if the data type of the x axis is "value"
|
||||
---@field xAxisDataType x_axisdatatype the data type of the x axis, if time, the x axis will be a time axis, if value, the x axis will be a value axis
|
||||
---@field yAxisLabels chart_guideline[] the vertical axis labels to indicate the values of the chart data
|
||||
---@field xAxisLabels fontstring[] the horizontal axis labels to indicate the values of the chart data
|
||||
---@field plotFrame frame the plot frame which is the frame that will hold the chart lines
|
||||
---@field lineThickness number the thickness of the chart lines
|
||||
---@field chartLeftOffset number the offset of the left side of the chart frame to the plot frame
|
||||
---@field chartBottomOffset number the offset of the bottom side of the chart frame to the plot frame
|
||||
---@field xAxisLabelsYOffset number default: -6, the offset of the horizontal axis labels to the horizontal axis line (y coordinate)
|
||||
---@field smoothnessLevel number default: 0, the smoothness level of the chart lines, 0 is no smoothness
|
||||
---@field SetAxesColor 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 SetAxesThickness fun(self: df_chartmulti, thickness: number) : boolean set the thickness of both axis lines
|
||||
---@field CreateAxesLines fun(self: df_chartmulti|df_chart, xOffset: number, yOffset: number, whichSide: "left"|"right", thickness: number, amountYLabels: number, amountXLabels: number, red: any, green: number|nil, blue: number|nil, alpha: number|nil)
|
||||
---@field SetXAxisDataType fun(self: df_chartmulti|df_chart, dataType: x_axisdatatype) : boolean set the data type of the x axis, if time, the x axis will be a time axis, if value, the x axis will be a value axis
|
||||
---@field SetXAxisData fun(self: df_chartmulti|df_chart, data: any) set the data of the x axis, if time, the x axis will be a time axis, if value, the x axis will be a value axis
|
||||
---@field SharedContrustor fun(self: df_chartmulti|df_chart) set default values for fields used on both chart types
|
||||
---@field IsMultiChart fun(self: df_chartmulti|df_chart) : boolean return true if the chart is a multi chart
|
||||
|
||||
---@param self df_chart|df_chartmulti
|
||||
local chartFrameSharedConstructor = function(self)
|
||||
self.xAxisDataType = "number"
|
||||
self.lineThickness = 2
|
||||
self.xAxisDataNumber = 0
|
||||
self.xAxisDataValues = {}
|
||||
self.xAxisLabels = {}
|
||||
self.yAxisLabels = {}
|
||||
self.chartLeftOffset = 0
|
||||
self.chartBottomOffset = 0
|
||||
self.xAxisLabelsYOffset = -6
|
||||
self.smoothnessLevel = 0
|
||||
end
|
||||
|
||||
---@class df_chart: frame, df_data, df_value, df_chartshared
|
||||
---@field _dataInfo df_data
|
||||
---@field color number[] red green blue alpha
|
||||
---@field height number
|
||||
---@field nextLine number
|
||||
---@field minValue number
|
||||
---@field maxValue number
|
||||
---@field data number[]
|
||||
---@field lines line[]
|
||||
---@field fixedLineWidth number
|
||||
---@field chartName string
|
||||
---@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
|
||||
---@field GetLineWidth fun(self: df_chart) : number calculate the width of each drawn line
|
||||
---@field SetLineWidth fun(self: df_chart, width: number) set the line width to a fixed value
|
||||
---@field Plot fun(self: df_chart) draw the graphic using lines and following the data set by SetData()
|
||||
---@field GetAmountLines fun(self: df_chart) : number return the amount of lines in use
|
||||
---@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 GetColor fun(self: df_chart) : red, green, blue, alpha
|
||||
---@field SetLineThickness fun(self: df_chart, thickness: number) set the line thickness
|
||||
---@field CalcYAxisPointForValue fun(self: df_chart, value: number)
|
||||
---@field CalcYAxisPointForValue fun(self: df_chart, value: number, plotFrameHeightScaled: number) : number
|
||||
---@field UpdateFrameSizeCache fun(self: df_chart)
|
||||
---@field Plot fun(self: df_chart, yPointScale: number|nil, bUpdateLabels: boolean|nil) draw the graphic using lines and following the data set by SetData() or AddData() in multi chart
|
||||
|
||||
---@class df_chartmulti : df_chart, df_chartshared
|
||||
---@field chartFrames df_chart[]
|
||||
---@field nextChartselframe number
|
||||
---@field biggestDataValue number
|
||||
---@field nextChartFrame number
|
||||
---@field lineNameIndicators chart_nameindicator[]
|
||||
---@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 AddData fun(self: df_chartmulti, data: table, name: string, red: any, 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)
|
||||
@@ -55,44 +102,75 @@ local _
|
||||
---@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)
|
||||
---@field UpdateChartNamesIndicator fun(self: df_chartmulti) if the chart names has been passed while adding data, this function will update the chart names indicator
|
||||
---@field Plot fun(self: df_chartmulti) draw the graphic using lines and following the data set by SetData() or AddData() in multi chart
|
||||
|
||||
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,
|
||||
---create the plot frame which is the frame that will hold the chart lines
|
||||
---@param self df_chartmulti|df_chart
|
||||
---@return frame
|
||||
local createPlotFrame = function(self)
|
||||
local plotFrame = CreateFrame("frame", "$parentPlotFrame", self, "BackdropTemplate")
|
||||
plotFrame:SetAllPoints()
|
||||
self.plotFrame = plotFrame
|
||||
return plotFrame
|
||||
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,
|
||||
}
|
||||
---generate the vertical axis labels to indicate the values of the chart data
|
||||
---@param parent frame
|
||||
---@param amountLabels number
|
||||
---@param labelsTable chart_guideline[]
|
||||
---@param red number
|
||||
---@param green number
|
||||
---@param blue number
|
||||
---@param alpha number
|
||||
local createVerticalAxisLabels = function(parent, amountLabels, labelsTable, red, green, blue, alpha)
|
||||
for i = 1, amountLabels do
|
||||
---@type fontstring
|
||||
local label = parent:CreateFontString("$parentYAxisLabel" .. i, "overlay", "GameFontNormal")
|
||||
---@cast label chart_guideline
|
||||
|
||||
--> functions shared by both single and multi chart frames
|
||||
label:SetJustifyH("right")
|
||||
label:SetTextColor(red, green, blue, alpha)
|
||||
detailsFramework:SetFontSize(label, 11)
|
||||
table.insert(labelsTable, label)
|
||||
|
||||
local circleTexture = parent:CreateTexture("$parentYAxisLabel" .. i .. "CircleTexture", "border")
|
||||
circleTexture:SetSize(4, 4)
|
||||
circleTexture:SetTexture([[Interface\CHARACTERFRAME\TempPortraitAlphaMaskSmall]])
|
||||
circleTexture:SetVertexColor(red, green, blue, alpha)
|
||||
circleTexture:SetPoint("right", label, "right", 5, 0)
|
||||
|
||||
local guideLine = parent:CreateLine("$parentYAxisLabel" .. i .. "GuideLine", "border")
|
||||
guideLine:SetThickness(1)
|
||||
guideLine:SetColorTexture(red, green, blue, 0.05)
|
||||
|
||||
label.circleTexture = circleTexture
|
||||
label.guideLine = guideLine
|
||||
end
|
||||
end
|
||||
|
||||
---generate the horizontal axis labels to indicate the values of the chart data
|
||||
---@param parent frame
|
||||
---@param amountLabels number
|
||||
---@param labelsTable fontstring[]
|
||||
---@param red number
|
||||
---@param green number
|
||||
---@param blue number
|
||||
---@param alpha number
|
||||
local createHorizontalAxisLabels = function(parent, amountLabels, labelsTable, red, green, blue, alpha)
|
||||
for i = 1, amountLabels do
|
||||
local label = parent:CreateFontString("$parentXAxisLabel" .. i, "overlay", "GameFontNormal")
|
||||
label:SetJustifyH("left")
|
||||
label:SetTextColor(red, green, blue, alpha)
|
||||
detailsFramework:SetFontSize(label, 11)
|
||||
table.insert(labelsTable, label)
|
||||
end
|
||||
end
|
||||
|
||||
---create the x and y axis lines with their labels
|
||||
---@param self df_chart|df_chartmulti
|
||||
---@param xOffset number
|
||||
---@param yOffset number
|
||||
---@param whichSide "left"|"right"
|
||||
---@param thickness number
|
||||
---@param amountYLabels number
|
||||
@@ -102,58 +180,217 @@ detailsFramework.ChartFrameSharedMixin = {
|
||||
---@param blue number|nil
|
||||
---@param alpha number|nil
|
||||
---@return boolean
|
||||
local createAxysLines = function(self, whichSide, thickness, amountYLabels, amountXLabels, red, green, blue, alpha)
|
||||
local createAxesLines = function(self, xOffset, yOffset, whichSide, thickness, amountYLabels, amountXLabels, red, green, blue, alpha)
|
||||
if (self.axisCreated) then
|
||||
return false
|
||||
end
|
||||
|
||||
self.yAxisLabels = {}
|
||||
self.xAxisLabels = {}
|
||||
local plotFrame = self.plotFrame
|
||||
|
||||
--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
|
||||
self.chartLeftOffset = xOffset or 48
|
||||
self.chartBottomOffset = yOffset or 28
|
||||
whichSide = whichSide or "left"
|
||||
thickness = thickness or 1
|
||||
amountYLabels = amountYLabels or 10
|
||||
amountXLabels = amountXLabels or 10
|
||||
red = red or 1
|
||||
green = green or 1
|
||||
blue = blue or 1
|
||||
alpha = alpha or 1
|
||||
|
||||
--adjust the plotFrame size and point taking in consideration of the left and bottom offsets, this is done to free space for the axis labels
|
||||
plotFrame:SetSize(self:GetWidth() - self.chartLeftOffset - 10, self:GetHeight() - self.chartBottomOffset - 20)
|
||||
plotFrame:ClearAllPoints()
|
||||
plotFrame:SetPoint("topleft", self, "topleft", self.chartLeftOffset, -1)
|
||||
plotFrame:SetPoint("bottomright", self, "bottomright", -1, self.chartBottomOffset)
|
||||
|
||||
--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 labels
|
||||
---@type line
|
||||
local yAxisLine = self:CreateLine("$parentYAxisLine", "overlay")
|
||||
local yAxisLine = plotFrame: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")
|
||||
local xAxisLine = plotFrame:CreateLine("$parentXAxisLine", "overlay")
|
||||
self.xAxisLine = xAxisLine
|
||||
|
||||
--vertical axis point
|
||||
if (whichSide == "left") then
|
||||
yAxisLine:SetStartPoint("topleft", plotFrame, 0, -1)
|
||||
yAxisLine:SetEndPoint("bottomleft", plotFrame, 0, self.chartBottomOffset * -1)
|
||||
else
|
||||
yAxisLine:SetStartPoint("topright", plotFrame, 0, -1)
|
||||
yAxisLine:SetEndPoint("bottomleft", plotFrame, 0, self.chartBottomOffset)
|
||||
end
|
||||
|
||||
--horizontal axis point
|
||||
xAxisLine:SetStartPoint("bottomleft", plotFrame, self.chartLeftOffset * -1, 0)
|
||||
xAxisLine:SetEndPoint("bottomright", plotFrame, -1, 0)
|
||||
|
||||
red, green, blue, alpha = detailsFramework:ParseColors(red, green, blue, alpha)
|
||||
self:SetAxesColor(red, green, blue, alpha)
|
||||
|
||||
self:SetAxisColor(red, green, blue, alpha)
|
||||
self:SetAxisThickness(thickness)
|
||||
--set the thickness of the both axis lines
|
||||
self:SetAxesThickness(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()
|
||||
createVerticalAxisLabels(plotFrame, amountYLabels, self.yAxisLabels, red, green, blue, alpha)
|
||||
createHorizontalAxisLabels(plotFrame, amountXLabels, self.xAxisLabels, red, green, blue, alpha)
|
||||
|
||||
self.axisCreated = true
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
---@param self df_chartmulti|df_chart
|
||||
---@param ... any
|
||||
local setXAxisData = function(self, ...)
|
||||
--when the data type is set to time, the x axis data is a number which represents the biggest time in seconds of all charts added
|
||||
if (self.xAxisDataType == "time" or self.xAxisDataType == "number") then
|
||||
self.xAxisDataNumber = math.max(self.xAxisDataNumber, select(1, ...))
|
||||
else
|
||||
wipe(self.xAxisDataValues)
|
||||
self.xAxisDataValues = {...}
|
||||
end
|
||||
end
|
||||
|
||||
---@param self df_chartmulti|df_chart
|
||||
---@param dataType x_axisdatatype
|
||||
local setXAxisDataType = function(self, dataType)
|
||||
assert(type(dataType) == "string", "string expected on :SetXAxisDataType(string)")
|
||||
self.xAxisDataType = dataType
|
||||
|
||||
if (dataType == "time" or dataType == "number") then
|
||||
self.xAxisDataNumber = 0
|
||||
|
||||
elseif (dataType == "value") then
|
||||
wipe(self.xAxisDataValues)
|
||||
end
|
||||
end
|
||||
|
||||
---updates the values of the labels on the axes to reflect the data shown
|
||||
---@param self df_chart|df_chartmulti
|
||||
local updateLabelValues = function(self)
|
||||
local maxValue = self:GetMaxValue()
|
||||
local height = self.plotFrame:GetHeight()
|
||||
local verticalLabelCount = #self.yAxisLabels
|
||||
local heightStep = height / verticalLabelCount
|
||||
|
||||
--update the labels in the vertical axis line
|
||||
for i = 1, verticalLabelCount do
|
||||
local label = self.yAxisLabels[i]
|
||||
local value = maxValue * (i / verticalLabelCount)
|
||||
label:ClearAllPoints()
|
||||
label:SetPoint("topright", self.yAxisLine, "bottomleft", -6, heightStep * i + self.chartBottomOffset)
|
||||
label:SetText(detailsFramework.FormatNumber(value))
|
||||
|
||||
label.circleTexture:ClearAllPoints()
|
||||
label.circleTexture:SetPoint("center", self.yAxisLine, "bottomleft", -2, heightStep * i - 5 + self.chartBottomOffset)
|
||||
|
||||
label.guideLine:SetStartPoint("center", label.circleTexture, 0, 0)
|
||||
label.guideLine:SetEndPoint("bottomright", self.plotFrame, 0, heightStep * i - 5)
|
||||
end
|
||||
|
||||
--update the labels in the horizontal axis line
|
||||
local xAxisDataType = self.xAxisDataType
|
||||
local horizontalLabelCount = #self.xAxisLabels
|
||||
local width = self.plotFrame:GetWidth()
|
||||
local widthStep = width / horizontalLabelCount
|
||||
|
||||
for i = horizontalLabelCount, 1, -1 do
|
||||
local label = self.xAxisLabels[i]
|
||||
label:ClearAllPoints()
|
||||
label:SetJustifyH("right")
|
||||
|
||||
--set the point of each x axis label
|
||||
label:SetPoint("topright", self.plotFrame, "bottomleft", widthStep * i, self.xAxisLabelsYOffset or -6)
|
||||
|
||||
--get the type set for the x axis labels and format the value accordingly
|
||||
if (xAxisDataType == "time" or xAxisDataType == "number") then
|
||||
local maxNumberValue = self.xAxisDataNumber
|
||||
local thisValue = maxNumberValue * (i / horizontalLabelCount)
|
||||
if (xAxisDataType == "time") then
|
||||
label:SetText(detailsFramework:IntegerToTimer(thisValue))
|
||||
else
|
||||
label:SetText(detailsFramework.FormatNumber(thisValue))
|
||||
end
|
||||
|
||||
elseif (xAxisDataType == "value") then
|
||||
label:SetText(self.xAxisDataValues[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
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
|
||||
SetAxesColor = function(self, red, green, blue, alpha)
|
||||
if (not self.yAxisLine) then
|
||||
return false
|
||||
end
|
||||
|
||||
--set the color of both axis lines
|
||||
red, green, blue, alpha = detailsFramework:ParseColors(red, green, blue, alpha)
|
||||
self.yAxisLine:SetColorTexture(red, green, blue, alpha)
|
||||
self.xAxisLine:SetColorTexture(red, green, blue, alpha)
|
||||
|
||||
--iterage over all labels and set their color
|
||||
for i = 1, #self.yAxisLabels do
|
||||
self.yAxisLabels[i]:SetTextColor(red, green, blue, alpha)
|
||||
end
|
||||
|
||||
for i = 1, #self.xAxisLabels do
|
||||
self.xAxisLabels[i]:SetTextColor(red, green, blue, alpha)
|
||||
end
|
||||
|
||||
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
|
||||
SetAxesThickness = function(self, thickness)
|
||||
if (not self.yAxisLine) then
|
||||
return false
|
||||
end
|
||||
self.yAxisLine:SetThickness(thickness)
|
||||
self.xAxisLine:SetThickness(thickness)
|
||||
return true
|
||||
end,
|
||||
|
||||
---create the x and y axis lines with their labels
|
||||
---@param self df_chart|df_chartmulti
|
||||
---@param xOffset number
|
||||
---@param yOffset number
|
||||
---@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
|
||||
CreateAxesLines = function(self, xOffset, yOffset, whichSide, thickness, amountYLabels, amountXLabels, red, green, blue, alpha)
|
||||
return createAxesLines(self, xOffset, yOffset, whichSide, thickness, amountYLabels, amountXLabels, red, green, blue, alpha)
|
||||
end,
|
||||
|
||||
---@param self df_chartmulti|df_chart
|
||||
---@param ... any
|
||||
SetXAxisData = function(self, ...)
|
||||
setXAxisData(self, ...)
|
||||
end,
|
||||
|
||||
---@param self df_chartmulti|df_chart
|
||||
---@param dataType x_axisdatatype
|
||||
SetXAxisDataType = function(self, dataType)
|
||||
setXAxisDataType(self, dataType)
|
||||
end,
|
||||
}
|
||||
|
||||
detailsFramework.ChartFrameMixin = {
|
||||
---set the default values for the chart frame
|
||||
---@param self df_chart
|
||||
@@ -161,13 +398,28 @@ detailsFramework.ChartFrameMixin = {
|
||||
self.nextLine = 1
|
||||
self.minValue = 0
|
||||
self.maxValue = 1
|
||||
self.lineThickness = 1
|
||||
self.lineThickness = 2
|
||||
self.data = {}
|
||||
self.lines = {}
|
||||
self.color = {1, 1, 1, 1}
|
||||
|
||||
--OnSizeChanged
|
||||
self:SetScript("OnSizeChanged", self.OnSizeChanged)
|
||||
|
||||
chartFrameSharedConstructor(self)
|
||||
end,
|
||||
|
||||
IsMultiChart = function(self)
|
||||
return false
|
||||
end,
|
||||
|
||||
---get the chart color
|
||||
---@param self df_chart
|
||||
---@return number red
|
||||
---@return number green
|
||||
---@return number blue
|
||||
---@return number alpha
|
||||
GetColor = function(self)
|
||||
return unpack(self.color)
|
||||
end,
|
||||
|
||||
---set the color for the lines
|
||||
@@ -192,7 +444,7 @@ detailsFramework.ChartFrameMixin = {
|
||||
|
||||
if (not line) then
|
||||
---@type line
|
||||
line = self:CreateLine(nil, "overlay")
|
||||
line = self.plotFrame:CreateLine(nil, "overlay", nil, 5)
|
||||
self.lines[self.nextLine] = line
|
||||
end
|
||||
|
||||
@@ -247,7 +499,7 @@ detailsFramework.ChartFrameMixin = {
|
||||
return self.fixedLineWidth
|
||||
else
|
||||
local amountData = self:GetDataSize()
|
||||
local frameWidth = self:GetWidth()
|
||||
local frameWidth = self.plotFrame:GetWidth()
|
||||
return frameWidth / amountData
|
||||
end
|
||||
end,
|
||||
@@ -262,8 +514,10 @@ detailsFramework.ChartFrameMixin = {
|
||||
|
||||
---@param self df_chart
|
||||
---@param value number
|
||||
CalcYAxisPointForValue = function(self, value)
|
||||
return value / self.maxValue * self.height
|
||||
---@param plotFrameHeightScaled number
|
||||
---@return number
|
||||
CalcYAxisPointForValue = function(self, value, plotFrameHeightScaled)
|
||||
return value / self.maxValue * (plotFrameHeightScaled)
|
||||
end,
|
||||
|
||||
---@param self df_chart
|
||||
@@ -278,11 +532,11 @@ detailsFramework.ChartFrameMixin = {
|
||||
end,
|
||||
|
||||
---@param self df_chart
|
||||
Plot = function(self)
|
||||
---@param yPointScale number|nil
|
||||
---@param bUpdateLabels boolean|nil
|
||||
Plot = function(self, yPointScale, bUpdateLabels)
|
||||
--debug
|
||||
--self:SetData({38, 26, 12, 63, 100, 96, 42, 94, 25, 75, 61, 54, 71, 40, 34, 100, 66, 90, 39, 13, 99, 18, 72, 18, 83, 45, 56, 24, 33, 85, 95, 71, 15, 66, 19, 58, 52, 9, 83, 99, 100, 4, 3, 56, 6, 80, 94, 7, 40, 55, 98, 92, 20, 9, 35, 89, 72, 7, 13, 81, 29, 78, 55, 70, 12, 33, 39, 3, 84, 31, 10, 53, 51, 69, 66, 58, 71, 60, 31, 71, 27, 76, 21, 75, 15, 89, 2, 81, 72, 78, 74, 80, 97, 10, 59, 0, 31, 5, 1, 82, 71, 89, 78, 94, 74, 20, 65, 72, 56, 40, 92, 91, 40, 79, 4, 56, 18, 88, 88, 20, 20, 10, 47, 26, 80, 26, 75, 21, 57, 10, 67, 66, 84, 83, 14, 47, 83, 9, 7, 73, 63, 32, 64, 20, 40, 3, 46, 54, 17, 37, 82, 66, 65, 22, 12, 1, 100, 41, 1, 72, 38, 41, 71, 69, 88, 34, 10, 50, 9, 25, 19, 27, 3, 13, 40, 75, 3, 11, 93, 58, 81, 80, 93, 25, 74, 68, 91, 87, 79, 48, 66, 53, 64, 18, 51, 19, 32, 4, 21, 43})
|
||||
local currentXPoint = 0
|
||||
local currentYPoint = 0
|
||||
|
||||
self:UpdateFrameSizeCache()
|
||||
|
||||
@@ -293,7 +547,9 @@ detailsFramework.ChartFrameMixin = {
|
||||
local firstValue = self:GetDataFirstValue()
|
||||
assert(firstValue, "Can't Plot(), chart has no data, use Chart:SetData(table)")
|
||||
|
||||
currentYPoint = self:CalcYAxisPointForValue(firstValue)
|
||||
local plotFrameHeightScaled = self.plotFrame:GetHeight() * (yPointScale or 1)
|
||||
local currentXPoint = 0
|
||||
local currentYPoint = self:CalcYAxisPointForValue(firstValue, plotFrameHeightScaled)
|
||||
|
||||
--calculate the width space which line should have
|
||||
local eachLineWidth = self:GetLineWidth()
|
||||
@@ -302,8 +558,13 @@ detailsFramework.ChartFrameMixin = {
|
||||
|
||||
for i = 1, maxLines do
|
||||
local line = self:GetLine()
|
||||
|
||||
line:SetColorTexture(unpack(self.color))
|
||||
line:SetThickness(self.lineThickness)
|
||||
|
||||
if (line.thickness ~= self.lineThickness) then
|
||||
line:SetThickness(self.lineThickness)
|
||||
line.thickness = self.lineThickness
|
||||
end
|
||||
|
||||
--the start point starts where the latest point finished
|
||||
line:SetStartPoint("bottomleft", currentXPoint, currentYPoint)
|
||||
@@ -313,9 +574,13 @@ detailsFramework.ChartFrameMixin = {
|
||||
|
||||
--end point
|
||||
local value = self:GetDataNextValue()
|
||||
currentYPoint = self:CalcYAxisPointForValue(value)
|
||||
currentYPoint = self:CalcYAxisPointForValue(value, plotFrameHeightScaled)
|
||||
line:SetEndPoint("bottomleft", currentXPoint, currentYPoint)
|
||||
end
|
||||
|
||||
if (bUpdateLabels or bUpdateLabels == nil) then
|
||||
updateLabelValues(self)
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
@@ -337,7 +602,36 @@ local createChartFrame = function(parent, name)
|
||||
chartFrame:ChartFrameConstructor()
|
||||
|
||||
--when a new data is set, update the min and max values
|
||||
local onSetDataCallback = function()
|
||||
local onSetDataCallback = function(data, smoothnessLevel)
|
||||
local newData = {}
|
||||
|
||||
smoothnessLevel = smoothnessLevel or 0
|
||||
|
||||
if (smoothnessLevel > 0) then
|
||||
smoothnessLevel = smoothnessLevel + 2
|
||||
|
||||
for i = 1, #data do
|
||||
local thisValue = 0
|
||||
local amountDataAdded = 0
|
||||
|
||||
--calculate the sum within the window
|
||||
for o = i - math.floor(smoothnessLevel / 2), i + math.floor(smoothnessLevel / 2) do
|
||||
if o >= 1 and o <= #data then
|
||||
thisValue = thisValue + data[o]
|
||||
amountDataAdded = amountDataAdded + 1
|
||||
end
|
||||
end
|
||||
|
||||
--calculate the average and store in the smoothedData value
|
||||
local average = thisValue / amountDataAdded
|
||||
table.insert(newData, average)
|
||||
end
|
||||
else
|
||||
newData = data
|
||||
end
|
||||
|
||||
chartFrame:SetDataRaw(newData)
|
||||
|
||||
local minValue, maxValue = chartFrame:GetDataMinMaxValues()
|
||||
chartFrame:SetMinMaxValues(minValue, maxValue)
|
||||
--clear the lines
|
||||
@@ -345,6 +639,7 @@ local createChartFrame = function(parent, name)
|
||||
end
|
||||
chartFrame:AddDataChangeCallback(onSetDataCallback)
|
||||
|
||||
createPlotFrame(chartFrame) --creates chartFrame.plotFrame
|
||||
return chartFrame
|
||||
end
|
||||
|
||||
@@ -358,26 +653,36 @@ detailsFramework.MultiChartFrameMixin = {
|
||||
MultiChartFrameConstructor = function(self)
|
||||
self.nextChartselframe = 1
|
||||
self.biggestDataValue = 0
|
||||
self.lineThickness = 1
|
||||
self.lineThickness = 2
|
||||
self.nextChartFrame = 1
|
||||
self.chartFrames = {}
|
||||
self.lineNameIndicators = {}
|
||||
|
||||
chartFrameSharedConstructor(self)
|
||||
end,
|
||||
|
||||
CreateAxisLines = function(self, whichSide, thickness, amountYLabels, amountXLabels, red, green, blue, alpha)
|
||||
createAxysLines(self, whichSide, thickness, amountYLabels, amountXLabels, red, green, blue, alpha)
|
||||
IsMultiChart = function(self)
|
||||
return true
|
||||
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 smoothnessLevel number|nil
|
||||
---@param name string|nil
|
||||
---@param red any
|
||||
---@param green number|nil
|
||||
---@param blue number|nil
|
||||
---@param alpha number|nil
|
||||
AddData = function(self, data, red, green, blue, alpha)
|
||||
AddData = function(self, data, smoothnessLevel, name, red, green, blue, alpha)
|
||||
assert(type(data) == "table", "MultiChartFrame:AddData() usage: AddData(table)")
|
||||
local chartFrame = self:GetChart()
|
||||
|
||||
red, green, blue, alpha = detailsFramework:ParseColors(red, green, blue, alpha)
|
||||
chartFrame:SetColor(red, green, blue, alpha)
|
||||
chartFrame:SetData(data)
|
||||
chartFrame:SetData(data, smoothnessLevel)
|
||||
|
||||
chartFrame.chartName = name or ""
|
||||
|
||||
self:SetMaxValueIfBigger(chartFrame:GetMaxValue())
|
||||
self:SetMinValueIfLower(chartFrame:GetMinValue())
|
||||
@@ -466,23 +771,94 @@ detailsFramework.MultiChartFrameMixin = {
|
||||
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)
|
||||
|
||||
local plotAreaWidth = self:GetWidth()
|
||||
local maxDataSize = self:GetMaxDataSize()
|
||||
local eachLineWidth = plotAreaWidth / maxDataSize
|
||||
|
||||
UpdateChartNamesIndicator = function(self)
|
||||
local allCharts = self:GetCharts()
|
||||
for i = 1, self:GetAmountCharts() do
|
||||
local chartFrame = allCharts[i]
|
||||
chartFrame:SetLineThickness(self.lineThickness)
|
||||
chartFrame:SetLineWidth(eachLineWidth)
|
||||
chartFrame:Plot()
|
||||
local allChartsAmount = self:GetAmountCharts()
|
||||
|
||||
--hide all indicators already created
|
||||
for i = 1, #self.lineNameIndicators do
|
||||
local thisIndicator = self.lineNameIndicators[i]
|
||||
thisIndicator:Hide()
|
||||
end
|
||||
|
||||
local nameIndicatorIndex = 1
|
||||
|
||||
for i = allChartsAmount, 1, -1 do
|
||||
local chartFrame = allCharts[i]
|
||||
local chartName = chartFrame.chartName
|
||||
local red, green, blue, alpha = chartFrame:GetColor()
|
||||
|
||||
---@type chart_nameindicator
|
||||
local thisIndicator = self.lineNameIndicators[nameIndicatorIndex]
|
||||
if (not thisIndicator) then
|
||||
---@type chart_nameindicator
|
||||
thisIndicator = CreateFrame("frame", "$parentLineNameIndicator" .. i, self)
|
||||
thisIndicator:SetSize(60, 12)
|
||||
thisIndicator:Hide()
|
||||
if (nameIndicatorIndex == 1) then
|
||||
thisIndicator:SetPoint("topright", self, "topright", nameIndicatorIndex * -10, -10)
|
||||
end
|
||||
|
||||
thisIndicator.Texture = thisIndicator:CreateTexture("$parentTexture", "overlay")
|
||||
thisIndicator.Texture:SetSize(12, 12)
|
||||
|
||||
thisIndicator.Label = thisIndicator:CreateFontString("$parentLabel", "overlay", "GameFontNormal")
|
||||
detailsFramework:SetFontSize(thisIndicator.Label, 11)
|
||||
detailsFramework:SetFontColor(thisIndicator.Label, "white")
|
||||
|
||||
thisIndicator.Texture:SetPoint("left", thisIndicator, "left", 0, 0)
|
||||
thisIndicator.Label:SetPoint("left", thisIndicator.Texture, "right", 2, 0)
|
||||
self.lineNameIndicators[nameIndicatorIndex] = thisIndicator
|
||||
end
|
||||
|
||||
thisIndicator.Texture:SetColorTexture(red, green, blue, alpha)
|
||||
thisIndicator.Label:SetText(chartName)
|
||||
local textWidth = thisIndicator.Label:GetStringWidth()
|
||||
thisIndicator:SetWidth(math.max(textWidth + thisIndicator.Texture:GetWidth() + 4, 85))
|
||||
|
||||
if (nameIndicatorIndex > 1) then
|
||||
local previousIndicator = self.lineNameIndicators[nameIndicatorIndex-1]
|
||||
thisIndicator:SetPoint("topright", previousIndicator, "topleft", -2, 0)
|
||||
end
|
||||
|
||||
nameIndicatorIndex = nameIndicatorIndex + 1
|
||||
|
||||
if (chartName ~= "") then
|
||||
thisIndicator:Show()
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
---draw all the charts added to the multi chart frame
|
||||
---@param multiChartFrame df_chartmulti
|
||||
Plot = function(multiChartFrame)
|
||||
local minValue, multiChartMaxValue = multiChartFrame:GetMinMaxValues()
|
||||
local plotAreaWidth = multiChartFrame.plotFrame:GetWidth() --if there's no axis, the plotFrame has no width
|
||||
local maxDataSize = multiChartFrame:GetMaxDataSize()
|
||||
local eachLineWidth = plotAreaWidth / maxDataSize
|
||||
local allCharts = multiChartFrame:GetCharts()
|
||||
|
||||
for i = 1, multiChartFrame:GetAmountCharts() do
|
||||
local chartFrame = allCharts[i]
|
||||
chartFrame.chartLeftOffset = multiChartFrame.chartLeftOffset
|
||||
chartFrame.chartBottomOffset = multiChartFrame.chartLeftOffset
|
||||
|
||||
chartFrame.plotFrame:ClearAllPoints()
|
||||
chartFrame.plotFrame:SetAllPoints(multiChartFrame.plotFrame)
|
||||
|
||||
chartFrame:SetLineThickness(multiChartFrame.lineThickness)
|
||||
chartFrame:SetLineWidth(eachLineWidth)
|
||||
|
||||
--get the percentage of how small this data is compared to the biggest data
|
||||
--this percentage is then used to scale down the to fit correctly the fontStrings showing the value metrics
|
||||
local yPointScale = chartFrame.maxValue / multiChartMaxValue
|
||||
local bUpdateLabels = false
|
||||
chartFrame:Plot(yPointScale, bUpdateLabels)
|
||||
end
|
||||
|
||||
updateLabelValues(multiChartFrame)
|
||||
multiChartFrame:UpdateChartNamesIndicator()
|
||||
end,
|
||||
}
|
||||
|
||||
@@ -503,5 +879,6 @@ function detailsFramework:CreateGraphicMultiLineFrame(parent, name)
|
||||
chartFrame:ValueConstructor()
|
||||
chartFrame:MultiChartFrameConstructor()
|
||||
|
||||
createPlotFrame(chartFrame) --creates chartFrame.plotFrame
|
||||
return chartFrame
|
||||
end
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
|
||||
|
||||
local dversion = 439
|
||||
local dversion = 441
|
||||
local major, minor = "DetailsFramework-1.0", dversion
|
||||
local DF, oldminor = LibStub:NewLibrary(major, minor)
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
<Script file="languages.lua"/>
|
||||
<Script file="timebar.lua"/>
|
||||
<Script file="charts.lua"/>
|
||||
<Script file="scripting.lua"/>
|
||||
<Script file="externals.lua"/>
|
||||
|
||||
<Include file="tutorial_alert.xml"/>
|
||||
|
||||
+14
-3
@@ -730,7 +730,8 @@ detailsFramework.SortFunctions = {
|
||||
---@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 SetData fun(self: df_data, data: table, anyValue: any)
|
||||
---@field SetDataRaw fun(self: df_data, data: table) set the data without triggering callback
|
||||
---@field GetDataNextValue fun(self: df_data) : any
|
||||
---@field ResetDataIndex fun(self: df_data)
|
||||
|
||||
@@ -767,17 +768,27 @@ detailsFramework.DataMixin = {
|
||||
allCallbacks[func] = nil
|
||||
end,
|
||||
|
||||
---set the data without callback
|
||||
---@param self table
|
||||
---@param data table
|
||||
SetDataRaw = function(self, data)
|
||||
assert(type(data) == "table", "invalid table for SetData.")
|
||||
self._dataInfo.data = data
|
||||
self:ResetDataIndex()
|
||||
end,
|
||||
|
||||
---set the data table
|
||||
---@param self table
|
||||
---@param data table
|
||||
SetData = function(self, data)
|
||||
---@param anyValue any @any value to pass to the callback functions before the payload is added
|
||||
SetData = function(self, data, anyValue)
|
||||
assert(type(data) == "table", "invalid table for SetData.")
|
||||
self._dataInfo.data = data
|
||||
self:ResetDataIndex()
|
||||
|
||||
local allCallbacks = self._dataInfo.callbacks
|
||||
for func, payload in pairs(allCallbacks) do
|
||||
xpcall(func, geterrorhandler(), data, unpack(payload))
|
||||
xpcall(func, geterrorhandler(), data, anyValue, unpack(payload))
|
||||
end
|
||||
end,
|
||||
|
||||
|
||||
+17
-9
@@ -13,6 +13,7 @@ local unpack = table.unpack or unpack --lua local
|
||||
local type = type --lua local
|
||||
local floor = math.floor --lua local
|
||||
local loadstring = loadstring --lua local
|
||||
local CreateFrame = CreateFrame
|
||||
|
||||
local IS_WOW_PROJECT_MAINLINE = WOW_PROJECT_ID == WOW_PROJECT_MAINLINE
|
||||
local IS_WOW_PROJECT_NOT_MAINLINE = WOW_PROJECT_ID ~= WOW_PROJECT_MAINLINE
|
||||
@@ -4391,11 +4392,18 @@ detailsFramework.TitleFunctions = {
|
||||
|
||||
}
|
||||
|
||||
function detailsFramework:CreateTitleBar (f, titleText)
|
||||
---@class df_titlebar : frame
|
||||
---@field TitleLabel fontstring
|
||||
---@field CloseButton button
|
||||
|
||||
local titleBar = CreateFrame("frame", f:GetName() and f:GetName() .. "TitleBar" or nil, f,"BackdropTemplate")
|
||||
titleBar:SetPoint("topleft", f, "topleft", 2, -3)
|
||||
titleBar:SetPoint("topright", f, "topright", -2, -3)
|
||||
---create a title bar with a font string in the center and a close button in the right side
|
||||
---@param parent frame
|
||||
---@param titleText string
|
||||
---@return df_titlebar
|
||||
function detailsFramework:CreateTitleBar(parent, titleText)
|
||||
local titleBar = CreateFrame("frame", parent:GetName() and parent:GetName() .. "TitleBar" or nil, parent, "BackdropTemplate")
|
||||
titleBar:SetPoint("topleft", parent, "topleft", 2, -3)
|
||||
titleBar:SetPoint("topright", parent, "topright", -2, -3)
|
||||
titleBar:SetHeight(20)
|
||||
titleBar:SetBackdrop(SimplePanel_frame_backdrop) --it's an upload from this file
|
||||
titleBar:SetBackdropColor(.2, .2, .2, 1)
|
||||
@@ -4415,7 +4423,7 @@ function detailsFramework:CreateTitleBar (f, titleText)
|
||||
closeButton:SetScript("OnClick", simple_panel_close_click) --upvalue from this file
|
||||
|
||||
local titleLabel = titleBar:CreateFontString(titleBar:GetName() and titleBar:GetName() .. "TitleText" or nil, "overlay", "GameFontNormal")
|
||||
titleLabel:SetTextColor(.8, .8, .8, 1)
|
||||
titleLabel:SetTextColor(detailsFramework:ParseColors("gold"))
|
||||
titleLabel:SetText(titleText or "")
|
||||
|
||||
--anchors
|
||||
@@ -4423,14 +4431,14 @@ function detailsFramework:CreateTitleBar (f, titleText)
|
||||
titleLabel:SetPoint("center", titleBar, "center")
|
||||
|
||||
--members
|
||||
f.TitleBar = titleBar
|
||||
f.CloseButton = closeButton
|
||||
f.TitleLabel = titleLabel
|
||||
parent.TitleBar = titleBar
|
||||
parent.CloseButton = closeButton
|
||||
parent.TitleLabel = titleLabel
|
||||
|
||||
titleBar.CloseButton = closeButton
|
||||
titleBar.Text = titleLabel
|
||||
|
||||
detailsFramework:Mixin(f, detailsFramework.TitleFunctions)
|
||||
detailsFramework:Mixin(parent, detailsFramework.TitleFunctions)
|
||||
|
||||
return titleBar
|
||||
end
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
|
||||
local detailsFramework = DetailsFramework
|
||||
|
||||
if (not detailsFramework or not DetailsFrameworkCanLoad) then
|
||||
return
|
||||
end
|
||||
|
||||
local unpack = unpack
|
||||
local CreateFrame = CreateFrame
|
||||
local geterrorhandler = geterrorhandler
|
||||
local wipe = wipe
|
||||
|
||||
local parseCodeForNamedLocalFunctions = function(codeBlock, startIndex, listOfFunctionsFound)
|
||||
local nestedLevel = 0
|
||||
local endIndex = startIndex
|
||||
local currentQuote = ""
|
||||
---@type number for the 'function' keyword, need to ignore the one that started the 'local function' capture
|
||||
local ignoreFunctionIndex = startIndex + 6
|
||||
|
||||
---@type boolean
|
||||
local bFoundEnd = false
|
||||
---@type boolean
|
||||
local bIsInString = false
|
||||
---@type boolean
|
||||
local bIsInComment = false
|
||||
|
||||
while (endIndex <= #codeBlock) do
|
||||
local char = string.sub(codeBlock, endIndex, endIndex)
|
||||
|
||||
--check if the character is inside a comment
|
||||
if (char == "-") then
|
||||
local nextChar = string.sub(codeBlock, endIndex + 1, endIndex + 1)
|
||||
if nextChar == "-" then
|
||||
bIsInComment = true
|
||||
end
|
||||
|
||||
elseif (char == "\n") then
|
||||
bIsInComment = false
|
||||
end
|
||||
|
||||
if (not bIsInComment) then
|
||||
--check if it is inside a string
|
||||
if (char == "'" or char == '"') then
|
||||
if (not bIsInString) then
|
||||
bIsInString = true
|
||||
currentQuote = char
|
||||
|
||||
elseif (bIsInString and currentQuote == char) then
|
||||
bIsInString = false
|
||||
currentQuote = ""
|
||||
end
|
||||
end
|
||||
|
||||
if (not bIsInString) then
|
||||
--check if the word starts with "i", "f", "d" or "e"
|
||||
if (char == "i") then
|
||||
local nextChars = string.sub(codeBlock, endIndex, endIndex + 1)
|
||||
if (nextChars == "if") then
|
||||
nestedLevel = nestedLevel + 1
|
||||
end
|
||||
|
||||
elseif (char == "f") then
|
||||
local nextChars = string.sub(codeBlock, endIndex, endIndex + 7)
|
||||
--also check if the index isn't the one that started the 'local function' capture
|
||||
if (nextChars == "function" and endIndex ~= ignoreFunctionIndex) then
|
||||
nestedLevel = nestedLevel + 1
|
||||
end
|
||||
|
||||
--for 'do' keyword, used by for and while and also by the 'do' keyword itself creating a block
|
||||
elseif (char == "d") then
|
||||
local nextChars = string.sub(codeBlock, endIndex, endIndex + 1)
|
||||
if (nextChars == "do") then
|
||||
nestedLevel = nestedLevel + 1
|
||||
end
|
||||
|
||||
elseif (char == "e") then
|
||||
local nextChars = string.sub(codeBlock, endIndex, endIndex + 2)
|
||||
if (nextChars == "end") then
|
||||
if (nestedLevel > 0) then
|
||||
--reduce the nested level by 1
|
||||
nestedLevel = nestedLevel - 1
|
||||
else
|
||||
--if the nested level is zero then the end of the function got found
|
||||
bFoundEnd = true
|
||||
endIndex = endIndex + 2 --adjust endIndex to include the 'end' keyword
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endIndex = endIndex + 1
|
||||
end
|
||||
|
||||
if (bFoundEnd) then
|
||||
---@type string get the function body
|
||||
local functionBody = string.sub(codeBlock, startIndex, endIndex)
|
||||
table.insert(listOfFunctionsFound, functionBody)
|
||||
return endIndex
|
||||
end
|
||||
end
|
||||
|
||||
---search a code block for named local functions and bring them to the top of the code block
|
||||
---this is useful for when you want to call a function before it's defined
|
||||
---same thing as been implemented in Lua 5.2 but not in WoW Lua
|
||||
---@param codeBlock string
|
||||
function detailsFramework:BringNamedLocalFunctionToTop(codeBlock)
|
||||
---@type string[]
|
||||
local listOfFunctionsFound = {}
|
||||
---@type number|nil
|
||||
local startIndex = string.find(codeBlock, "local function")
|
||||
|
||||
while startIndex do
|
||||
startIndex = parseCodeForNamedLocalFunctions(codeBlock, startIndex, listOfFunctionsFound)
|
||||
if (not startIndex) then
|
||||
break
|
||||
end
|
||||
startIndex = string.find(codeBlock, "local function", startIndex + 1)
|
||||
end
|
||||
|
||||
for i = #listOfFunctionsFound, 1, -1 do
|
||||
local thisMatch = listOfFunctionsFound[i]
|
||||
local blockStartIndex = thisMatch[2]
|
||||
local blockEndIndex = thisMatch[3]
|
||||
codeBlock = codeBlock:sub(1, blockStartIndex - 1) .. codeBlock:sub(blockEndIndex + 1)
|
||||
end
|
||||
|
||||
for i = #listOfFunctionsFound, 1, -1 do
|
||||
codeBlock = listOfFunctionsFound[i][1] .. "\n\n" .. codeBlock
|
||||
end
|
||||
end
|
||||
+12
-7
@@ -447,6 +447,7 @@ detailsFramework.TextEntryCounter = detailsFramework.TextEntryCounter or 1
|
||||
OnEnterPressed(self.editbox, byScript)
|
||||
end
|
||||
|
||||
---set the textEntry as a search box, it will add a magnifying glass icon on the left side and a clearSearchButton in the right.
|
||||
function TextEntryMetaFunctions:SetAsSearchBox()
|
||||
if (self.__bIsSearchBox) then
|
||||
return
|
||||
@@ -941,10 +942,14 @@ local set_speciallua_editor_font_size = function(borderFrame, newSize)
|
||||
borderFrame.editboxlines:SetFont(file, newSize, flags)
|
||||
end
|
||||
|
||||
function detailsFramework:NewSpecialLuaEditorEntry(parent, width, height, member, name, nointent, showLineNumbers)
|
||||
if (name:find("$parent")) then
|
||||
local parentName = detailsFramework.GetParentName(parent)
|
||||
name = name:gsub("$parent", parentName)
|
||||
function detailsFramework:NewSpecialLuaEditorEntry(parent, width, height, member, name, nointent, showLineNumbers, bNoName)
|
||||
if (not bNoName) then
|
||||
if (name:find("$parent")) then
|
||||
local parentName = detailsFramework.GetParentName(parent)
|
||||
name = name:gsub("$parent", parentName)
|
||||
end
|
||||
else
|
||||
name = nil
|
||||
end
|
||||
|
||||
local borderframe = CreateFrame("Frame", name, parent,"BackdropTemplate")
|
||||
@@ -955,9 +960,9 @@ function detailsFramework:NewSpecialLuaEditorEntry(parent, width, height, member
|
||||
end
|
||||
|
||||
local scrollframe = CreateFrame("ScrollFrame", name, borderframe, "UIPanelScrollFrameTemplate, BackdropTemplate")
|
||||
local scrollframeNumberLines = CreateFrame("ScrollFrame", name .. "NumberLines", borderframe, "UIPanelScrollFrameTemplate, BackdropTemplate")
|
||||
local scrollframeNumberLines = CreateFrame("ScrollFrame", name and (name .. "NumberLines"), borderframe, "UIPanelScrollFrameTemplate, BackdropTemplate")
|
||||
|
||||
scrollframe.editbox = CreateFrame("editbox", "$parentEditBox", scrollframe,"BackdropTemplate")
|
||||
scrollframe.editbox = CreateFrame("editbox", name and "$parentEditBox", scrollframe,"BackdropTemplate")
|
||||
scrollframe.editbox:SetMultiLine (true)
|
||||
scrollframe.editbox:SetAutoFocus(false)
|
||||
scrollframe.editbox:SetScript("OnCursorChanged", _G.ScrollingEdit_OnCursorChanged)
|
||||
@@ -967,7 +972,7 @@ function detailsFramework:NewSpecialLuaEditorEntry(parent, width, height, member
|
||||
|
||||
--line number
|
||||
if (showLineNumbers) then
|
||||
scrollframeNumberLines.editbox = CreateFrame("editbox", "$parentLineNumbers", scrollframeNumberLines, "BackdropTemplate")
|
||||
scrollframeNumberLines.editbox = CreateFrame("editbox", name and "$parentLineNumbers", scrollframeNumberLines, "BackdropTemplate")
|
||||
scrollframeNumberLines.editbox:SetMultiLine (true)
|
||||
scrollframeNumberLines.editbox:SetAutoFocus(false)
|
||||
scrollframeNumberLines.editbox:SetEnabled (false)
|
||||
|
||||
@@ -77,6 +77,20 @@
|
||||
---| "Button5Up"
|
||||
---| "Button5Down"
|
||||
|
||||
---@alias justifyh
|
||||
---| "left"
|
||||
---| "right"
|
||||
---| "center"
|
||||
|
||||
---@alias justifyv
|
||||
---| "top"
|
||||
---| "bottom"
|
||||
---| "middle"
|
||||
|
||||
---@alias orientation
|
||||
---| "HORIZONTAL"
|
||||
---| "VERTICAL"
|
||||
|
||||
---@alias width number property that represents the horizontal size of a UI element, such as a frame or a texture. Gotten from the first result of GetWidth() or from the first result of GetSize(). It is expected a GetWidth() or GetSize() when the type 'height' is used.
|
||||
---@alias height number property that represents the vertical size of a UI element, such as a frame or a texture. Gotten from the first result of GetHeight() or from the second result of GetSize(). It is expected a GetHeight() or GetSize() when the type 'height' is used.
|
||||
---@alias red number color value representing the red component of a color, the value must be between 0 and 1. To retrieve a color from a string or table use: local red, green, blue, alpha = DetailsFramework:ParseColors(color)
|
||||
@@ -99,7 +113,7 @@
|
||||
---@alias npcid number a number that identifies a specific npc in the game.
|
||||
---@alias textureid number each texture from the game client has an id.
|
||||
---@alias texturepath string access textures from addons.
|
||||
|
||||
---@alias unixtime number
|
||||
|
||||
---@class _G
|
||||
---@field RegisterAttributeDriver fun(statedriver: frame, attribute: string, conditional: string)
|
||||
@@ -109,8 +123,6 @@
|
||||
---@field GetCursorPosition fun(): number, number return the position of the cursor on the screen, in pixels, relative to the bottom left corner of the screen.
|
||||
---@field C_Timer C_Timer
|
||||
|
||||
---@class unixtime : number const
|
||||
|
||||
---@class timer : table
|
||||
---@field Cancel fun(self: timer)
|
||||
---@field IsCancelled fun(self: timer): boolean
|
||||
@@ -238,12 +250,13 @@
|
||||
---@field GetRegions fun(self: frame) : region[]
|
||||
---@field CreateTexture fun(self: frame, name: string|nil, layer: drawlayer, inherits: string|nil, subLayer: number|nil) : texture
|
||||
---@field CreateFontString fun(self: frame, name: string|nil, layer: drawlayer, inherits: string|nil, subLayer: number|nil) : fontstring
|
||||
---@field EnableMouse fun(self: frame, enable: boolean)
|
||||
---@field SetResizable fun(self: frame, enable: boolean)
|
||||
---@field EnableMouseWheel fun(self: frame, enable: boolean)
|
||||
---@field RegisterForDrag fun(self: frame, button: string)
|
||||
---@field SetResizeBounds fun(self: frame, minWidth: number, minHeight: number, maxWidth: number, maxHeight: number)
|
||||
---@field RegisterEvent fun(self: frame, event: string)
|
||||
---@field EnableMouse fun(self: frame, enable: boolean) enable mouse interaction
|
||||
---@field SetResizable fun(self: frame, enable: boolean) enable resizing of the frame
|
||||
---@field EnableMouseWheel fun(self: frame, enable: boolean) enable mouse wheel scrolling
|
||||
---@field RegisterForDrag fun(self: frame, button: string) register the frame for drag events, allowing it to be dragged by the mouse
|
||||
---@field SetResizeBounds fun(self: frame, minWidth: number, minHeight: number, maxWidth: number, maxHeight: number) set the minimum and maximum size of the frame
|
||||
---@field RegisterEvent fun(self: frame, event: string) register for an event, trigers "OnEvent" script when the event is fired
|
||||
---@field HookScript fun(self: frame, event: string, handler: function) run a function after the frame's script has been executed, carrying the same arguments
|
||||
|
||||
---@class button : frame
|
||||
---@field Click fun(self: button)
|
||||
@@ -278,12 +291,12 @@
|
||||
---@field SetMinMaxValues fun(self: statusbar, minValue: number, maxValue: number)
|
||||
---@field SetValue fun(self: statusbar, value: number)
|
||||
---@field SetValueStep fun(self: statusbar, valueStep: number)
|
||||
---@field SetOrientation fun(self: statusbar, orientation: string)
|
||||
---@field SetOrientation fun(self: statusbar, orientation: orientation)
|
||||
---@field SetReverseFill fun(self: statusbar, reverseFill: boolean)
|
||||
---@field GetMinMaxValues fun(self: statusbar) : number, number
|
||||
---@field GetValue fun(self: statusbar) : number
|
||||
---@field GetValueStep fun(self: statusbar) : number
|
||||
---@field GetOrientation fun(self: statusbar) : string
|
||||
---@field GetOrientation fun(self: statusbar) : orientation
|
||||
---@field GetReverseFill fun(self: statusbar) : boolean
|
||||
|
||||
---@class scrollframe : frame
|
||||
@@ -311,9 +324,9 @@
|
||||
---@field GetShadowOffset fun(self: fontstring) : number, number
|
||||
---@field SetTextColor fun(self: fontstring, r: red|number, g: green|number, b: blue|number, a: alpha|number)
|
||||
---@field GetTextColor fun(self: fontstring) : number, number, number, number
|
||||
---@field SetJustifyH fun(self: fontstring, justifyH: string)
|
||||
---@field SetJustifyH fun(self: fontstring, justifyH: justifyh)
|
||||
---@field GetJustifyH fun(self: fontstring) : string
|
||||
---@field SetJustifyV fun(self: fontstring, justifyV: string)
|
||||
---@field SetJustifyV fun(self: fontstring, justifyV: justifyv)
|
||||
---@field GetJustifyV fun(self: fontstring) : string
|
||||
---@field SetNonSpaceWrap fun(self: fontstring, nonSpaceWrap: boolean)
|
||||
---@field GetNonSpaceWrap fun(self: fontstring) : boolean
|
||||
|
||||
@@ -82,6 +82,8 @@
|
||||
Details222.Textures = {}
|
||||
--namespace for pet
|
||||
Details222.Pets = {}
|
||||
--auto run code
|
||||
Details222.AutoRunCode = {}
|
||||
Details222.Instances = {}
|
||||
Details222.MythicPlus = {}
|
||||
Details222.EJCache = {}
|
||||
@@ -1162,7 +1164,8 @@ end
|
||||
|
||||
function Details222.ClassCache.MakeCache()
|
||||
--iterage among all segments in the container history, get the damage container and get the actor list, check if the actor is a player and if it is, get the class and store it in the cache
|
||||
for _, combatObject in ipairs(Details.tabela_historico.tabelas) do
|
||||
local segmentsTable = Details:GetCombatSegments()
|
||||
for _, combatObject in ipairs(segmentsTable) do
|
||||
for _, actorObject in combatObject:GetContainer(DETAILS_ATTRIBUTE_DAMAGE):ListActors() do
|
||||
if (actorObject:IsPlayer()) then
|
||||
local actorName = actorObject.nome
|
||||
@@ -1303,6 +1306,13 @@ function Details:DestroyActor(actorObject, actorContainer, combatObject, callSta
|
||||
local combatTotalsTable = combatObject.totals[containerType] --without group
|
||||
local combatTotalsTableInGroup = combatObject.totals_grupo[containerType] --with group
|
||||
|
||||
--remove the actor from the parser cache
|
||||
local c1, c2, c3, c4 = Details222.Cache.GetParserCacheTables()
|
||||
c1[actorObject.serial] = nil
|
||||
c2[actorObject.serial] = nil
|
||||
c3[actorObject.serial] = nil
|
||||
c4[actorObject.serial] = nil
|
||||
|
||||
if (not actorObject.ownerName) then --not a pet
|
||||
if (containerType == 1 or containerType == 2) then --damage|healing done
|
||||
combatTotalsTable = combatTotalsTable - actorObject.total
|
||||
|
||||
@@ -731,9 +731,9 @@ end
|
||||
function classCombat:TravarTempos()
|
||||
if (self [1]) then
|
||||
for _, jogador in ipairs(self [1]._ActorTable) do --damage
|
||||
if (jogador:Iniciar()) then -- retorna se ele esta com o dps ativo
|
||||
if (jogador:GetOrChangeActivityStatus()) then -- retorna se ele esta com o dps ativo
|
||||
Details222.TimeMachine.StopTime(jogador)
|
||||
jogador:Iniciar(false) --lock the actor timer
|
||||
jogador:GetOrChangeActivityStatus(false) --lock the actor timer
|
||||
else
|
||||
if (jogador.start_time == 0) then
|
||||
jogador.start_time = _tempo
|
||||
@@ -746,9 +746,9 @@ end
|
||||
end
|
||||
if (self [2]) then
|
||||
for _, jogador in ipairs(self [2]._ActorTable) do --healing
|
||||
if (jogador:Iniciar()) then -- retorna se ele esta com o dps ativo
|
||||
if (jogador:GetOrChangeActivityStatus()) then -- retorna se ele esta com o dps ativo
|
||||
Details222.TimeMachine.StopTime(jogador)
|
||||
jogador:Iniciar(false) --lock the actor timer
|
||||
jogador:GetOrChangeActivityStatus(false) --lock the actor timer
|
||||
else
|
||||
if (jogador.start_time == 0) then
|
||||
jogador.start_time = _tempo
|
||||
|
||||
+12
-10
@@ -854,9 +854,9 @@ end
|
||||
end
|
||||
|
||||
if (not bIsCustomSpell) then
|
||||
for spellId, spellTable in pairs(actorObject.spells._ActorTable) do
|
||||
if (spellId ~= spellId) then
|
||||
local spellname = select(1, GetSpellInfo(spellId))
|
||||
for thisSpellId, spellTable in pairs(actorObject.spells._ActorTable) do
|
||||
if (thisSpellId ~= spellId) then --this is invalid
|
||||
local spellname = select(1, GetSpellInfo(thisSpellId))
|
||||
if (spellname == spellName) then
|
||||
for targetName, damageAmount in pairs(spellTable.targets) do
|
||||
local got = false
|
||||
@@ -905,8 +905,7 @@ end
|
||||
return totalDamage, topDamage, amount
|
||||
]]
|
||||
|
||||
local function ShowDTBSInWindow (spell, instance)
|
||||
|
||||
local function ShowDTBSInWindow (spell, instance) --for hold shift key and click, show players which took damage from this spell
|
||||
local spellname, _, icon = _GetSpellInfo(spell [1])
|
||||
local custom_name = spellname .. " - " .. Loc ["STRING_CUSTOM_DTBS"] .. ""
|
||||
|
||||
@@ -2657,10 +2656,12 @@ function damageClass:RefreshLine(instance, lineContainer, whichRowLine, rank, to
|
||||
percentString = format("%.1f", self[keyName] / instance.top * 100)
|
||||
end
|
||||
|
||||
local currentCombat = Details:GetCurrentCombat()
|
||||
|
||||
--calculate the actor dps
|
||||
if ((Details.time_type == 2 and self.grupo) or not Details:CaptureGet("damage") or instance.segmento == -1) then
|
||||
if (instance.segmento == -1 and combat_time == 0) then
|
||||
local actor = Details.tabela_vigente(1, self.nome)
|
||||
local actor = currentCombat(1, self.nome)
|
||||
if (actor) then
|
||||
local combatTime = actor:Tempo()
|
||||
dps = damageTotal / combatTime
|
||||
@@ -6198,16 +6199,17 @@ function damageClass:MontaTooltipAlvos (thisLine, index, instancia) --~deprecate
|
||||
GameCooltip:Show()
|
||||
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
--controla se o dps do jogador esta travado ou destravado
|
||||
function damageClass:Iniciar (iniciar)
|
||||
if (iniciar == nil) then
|
||||
function damageClass:GetOrChangeActivityStatus(activityStatus)
|
||||
if (activityStatus == nil) then
|
||||
return self.dps_started --retorna se o dps esta aberto ou fechado para este jogador
|
||||
elseif (iniciar) then
|
||||
|
||||
elseif (activityStatus) then
|
||||
self.dps_started = true
|
||||
Details222.TimeMachine.AddActor(self)
|
||||
|
||||
else
|
||||
self.dps_started = false
|
||||
Details222.TimeMachine.RemoveActor(self)
|
||||
|
||||
@@ -2768,7 +2768,7 @@ function healingClass:MontaDetalhesHealingDone (spellid, barra) --deprecated wit
|
||||
end
|
||||
|
||||
--controla se o dps do jogador esta travado ou destravado
|
||||
function healingClass:Iniciar (iniciar)
|
||||
function healingClass:GetOrChangeActivityStatus (iniciar)
|
||||
if (iniciar == nil) then
|
||||
return self.iniciar_hps --retorna se o dps esta aberto ou fechado para este jogador
|
||||
elseif (iniciar) then
|
||||
|
||||
+436
-437
File diff suppressed because it is too large
Load Diff
@@ -1374,7 +1374,7 @@ end
|
||||
|
||||
|
||||
--controla se o dps do jogador esta travado ou destravado
|
||||
function atributo_energy:Iniciar (iniciar)
|
||||
function atributo_energy:GetOrChangeActivityStatus (iniciar)
|
||||
return false --retorna se o dps esta aberto ou fechado para este jogador
|
||||
end
|
||||
|
||||
|
||||
@@ -2316,7 +2316,7 @@ function atributo_misc:MontaTooltipAlvos (esta_barra, index)
|
||||
end
|
||||
|
||||
--controla se o dps do jogador esta travado ou destravado
|
||||
function atributo_misc:Iniciar (iniciar)
|
||||
function atributo_misc:GetOrChangeActivityStatus (iniciar)
|
||||
return false --retorna se o dps esta aberto ou fechado para este jogador
|
||||
end
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ local addonName, Details222 = ...
|
||||
|
||||
local combatClass = Details.combate
|
||||
local segmentClass = Details.historico
|
||||
local timeMachine = Details.timeMachine
|
||||
local bitBand = bit.band
|
||||
|
||||
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -32,29 +31,42 @@ end
|
||||
|
||||
function Details:GetCombat(combat)
|
||||
if (not combat) then
|
||||
return Details.tabela_vigente
|
||||
return Details:GetCurrentCombat()
|
||||
|
||||
elseif (type(combat) == "number") then
|
||||
if (combat == -1) then --overall
|
||||
return Details.tabela_overall
|
||||
return Details:GetOverallCombat()
|
||||
|
||||
elseif (combat == 0) then --current
|
||||
return Details.tabela_vigente
|
||||
return Details:GetCurrentCombat()
|
||||
else
|
||||
return Details.tabela_historico.tabelas[combat]
|
||||
local segmentsTable = Details:GetCombatSegments()
|
||||
return segmentsTable[combat]
|
||||
end
|
||||
|
||||
elseif (type(combat) == "string") then
|
||||
if (combat == "overall") then
|
||||
return Details.tabela_overall
|
||||
return Details:GetOverallCombat()
|
||||
|
||||
elseif (combat == "current") then
|
||||
return Details.tabela_vigente
|
||||
return Details:GetCurrentCombat()
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
---remove a segment from the segments table
|
||||
---@param segmentIndex number
|
||||
---@return boolean, combat
|
||||
function Details:RemoveSegment(segmentIndex)
|
||||
assert(type(segmentIndex) == "number", "Usage: Details:RemoveSegment(segmentIndex: number)")
|
||||
|
||||
local segmentsTable = Details:GetCombatSegments()
|
||||
local segmentRemoved = table.remove(segmentsTable, segmentIndex)
|
||||
return segmentRemoved ~= nil, segmentRemoved
|
||||
end
|
||||
|
||||
--returns a private table containing all stored segments
|
||||
function Details:GetCombatSegments()
|
||||
return Details.tabela_historico.tabelas
|
||||
@@ -82,9 +94,11 @@ function segmentClass:AddToOverallData(combatObject)
|
||||
if (Details.debug) then
|
||||
Details:Msg("(debug) new boss detected 'overall_clear_newboss' is true, cleaning overall data.")
|
||||
end
|
||||
for index, combat in ipairs(Details.tabela_historico.tabelas) do
|
||||
|
||||
for index, combat in ipairs(Details:GetCombatSegments()) do
|
||||
combat.overall_added = false
|
||||
end
|
||||
|
||||
segmentClass:ResetOverallData()
|
||||
end
|
||||
end
|
||||
@@ -145,8 +159,9 @@ function segmentClass:AddToOverallData(combatObject)
|
||||
Details.tabela_overall:SetEndTime(combatObject.end_time)
|
||||
end
|
||||
|
||||
local currentCombat = Details:GetCurrentCombat()
|
||||
if (Details.tabela_overall.data_inicio == 0) then
|
||||
Details.tabela_overall.data_inicio = Details.tabela_vigente.data_inicio or 0
|
||||
Details.tabela_overall.data_inicio = currentCombat.data_inicio or 0
|
||||
end
|
||||
|
||||
Details.tabela_overall:seta_data(Details._detalhes_props.DATA_TYPE_END)
|
||||
@@ -239,23 +254,25 @@ end
|
||||
---@param combatObject combat
|
||||
function segmentClass:AddCombat(combatObject)
|
||||
---@type combat[]
|
||||
local segmentTable = self.tabelas
|
||||
local segmentsTable = Details:GetCombatSegments()
|
||||
---@type number
|
||||
local maxSegmentsAllowed = Details.segments_amount
|
||||
|
||||
local bSegmentDestroyed = false
|
||||
|
||||
--check all instances for freeze state
|
||||
if (#segmentTable < maxSegmentsAllowed) then
|
||||
if (#segmentsTable < maxSegmentsAllowed) then
|
||||
---@type combat
|
||||
local oldestCombatObject = segmentTable[#segmentTable]
|
||||
local oldestCombatObject = segmentsTable[#segmentsTable]
|
||||
--if there's no segment stored, then this as the first segment
|
||||
if (not oldestCombatObject) then
|
||||
oldestCombatObject = combatObject
|
||||
end
|
||||
Details:InstanciaCallFunction(Details.CheckFreeze, #segmentTable + 1, oldestCombatObject)
|
||||
Details:InstanciaCallFunction(Details.CheckFreeze, #segmentsTable + 1, oldestCombatObject)
|
||||
end
|
||||
|
||||
--add to the first index of the segment table
|
||||
table.insert(segmentTable, 1, combatObject)
|
||||
table.insert(segmentsTable, 1, combatObject)
|
||||
|
||||
--count boss tries
|
||||
---@type string
|
||||
@@ -266,8 +283,8 @@ function segmentClass:AddCombat(combatObject)
|
||||
if (not tryNumber) then
|
||||
---@type combat
|
||||
local previousCombatObject
|
||||
for i = 2, #segmentTable do
|
||||
previousCombatObject = segmentTable[i]
|
||||
for i = 2, #segmentsTable do
|
||||
previousCombatObject = segmentsTable[i]
|
||||
if (previousCombatObject and previousCombatObject.is_boss and previousCombatObject.is_boss.name and previousCombatObject.is_boss.try_number and previousCombatObject.is_boss.name == bossName and not previousCombatObject.is_boss.killed) then
|
||||
tryNumber = previousCombatObject.is_boss.try_number + 1
|
||||
break
|
||||
@@ -296,9 +313,9 @@ function segmentClass:AddCombat(combatObject)
|
||||
end
|
||||
|
||||
--erase trash segments
|
||||
if (segmentTable[2]) then
|
||||
if (segmentsTable[2]) then
|
||||
---@type combat
|
||||
local previousCombatObject = segmentTable[2]
|
||||
local previousCombatObject = segmentsTable[2]
|
||||
---@type actorcontainer
|
||||
local containerDamage = previousCombatObject:GetContainer(DETAILS_ATTRIBUTE_DAMAGE)
|
||||
---@type actorcontainer
|
||||
@@ -320,7 +337,7 @@ function segmentClass:AddCombat(combatObject)
|
||||
|
||||
if (Details.trash_auto_remove) then
|
||||
---@type combat
|
||||
local thirdCombat = segmentTable[3]
|
||||
local thirdCombat = segmentsTable[3]
|
||||
|
||||
if (thirdCombat and not thirdCombat.is_mythic_dungeon_segment) then
|
||||
if ((thirdCombat.is_trash and not thirdCombat.is_boss) or(thirdCombat.is_temporary)) then
|
||||
@@ -333,17 +350,18 @@ function segmentClass:AddCombat(combatObject)
|
||||
end
|
||||
|
||||
--remove
|
||||
local combatObjectRemoved = table.remove(segmentTable, 3)
|
||||
if (combatObjectRemoved) then
|
||||
---@type boolean, combat
|
||||
local bSegmentRemoved, combatObjectRemoved = Details:RemoveSegment(3)
|
||||
if (bSegmentRemoved) then
|
||||
Details:DestroyCombat(combatObjectRemoved)
|
||||
Details:SendEvent("DETAILS_DATA_SEGMENTREMOVED")
|
||||
bSegmentDestroyed = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local segmentsTable = Details.tabela_historico.tabelas
|
||||
local segmentsTable = Details:GetCombatSegments()
|
||||
|
||||
--check if the segment table is full
|
||||
if (#segmentsTable > maxSegmentsAllowed) then
|
||||
@@ -399,19 +417,35 @@ function segmentClass:AddCombat(combatObject)
|
||||
end
|
||||
|
||||
--remove it
|
||||
segmentsTable = Details.tabela_historico.tabelas
|
||||
---@type combat
|
||||
local combatObjectRemoved = table.remove(segmentsTable, segmentIdToBeRemoved)
|
||||
if (combatObjectRemoved) then
|
||||
segmentsTable = Details:GetCombatSegments()
|
||||
---@type boolean, combat
|
||||
local bSegmentRemoved, combatObjectRemoved = Details:RemoveSegment(segmentIdToBeRemoved)
|
||||
if (bSegmentRemoved) then
|
||||
Details:DestroyCombat(combatObjectRemoved)
|
||||
Details:SendEvent("DETAILS_DATA_SEGMENTREMOVED")
|
||||
bSegmentDestroyed = true
|
||||
end
|
||||
end
|
||||
|
||||
---@debug check if there's a destroyed segment within the segment container
|
||||
local segments = Details:GetCombatSegments()
|
||||
if (#segments > 0) then
|
||||
for i = 1, #segments do
|
||||
local thisCombatObject = segments[i]
|
||||
if (thisCombatObject.__destroyed) then
|
||||
Details:Msg("(debug) container_segments line: 419 (__destroyed combat in segments container)")
|
||||
end
|
||||
end
|
||||
end
|
||||
---@end-debug
|
||||
|
||||
Details:InstanceCall(function(instanceObject) instanceObject:RefreshCombat() end)
|
||||
|
||||
--update the combat shown on all instances
|
||||
Details:InstanciaCallFunction(Details.AtualizaSegmentos_AfterCombat, self)
|
||||
|
||||
if (bSegmentDestroyed) then
|
||||
Details:SendEvent("DETAILS_DATA_SEGMENTREMOVED")
|
||||
end
|
||||
end
|
||||
|
||||
---verify if the instance is freezed, if true unfreeze it
|
||||
@@ -451,7 +485,6 @@ function segmentClass:ResetOverallData()
|
||||
Details:CloseBreakdownWindow()
|
||||
|
||||
Details:DestroyCombat(Details.tabela_overall)
|
||||
Details:SendEvent("DETAILS_DATA_SEGMENTREMOVED")
|
||||
Details.tabela_overall = combatClass:NovaTabela()
|
||||
|
||||
for index, instanceObject in ipairs(Details:GetAllInstances()) do
|
||||
@@ -471,6 +504,8 @@ function segmentClass:ResetOverallData()
|
||||
--stop bar testing if any
|
||||
Details:StopTestBarUpdate()
|
||||
Details:ClockPluginTickOnSegment()
|
||||
|
||||
Details:SendEvent("DETAILS_DATA_SEGMENTREMOVED")
|
||||
end
|
||||
|
||||
function segmentClass:ResetAllCombatData()
|
||||
@@ -481,8 +516,10 @@ function segmentClass:ResetAllCombatData()
|
||||
--stop bar testing if any
|
||||
Details:StopTestBarUpdate()
|
||||
|
||||
if (Details.tabela_vigente.verifica_combate) then --finaliza a checagem se esta ou n�o no combate
|
||||
Details:CancelTimer(Details.tabela_vigente.verifica_combate)
|
||||
local currentCombat = Details:GetCurrentCombat()
|
||||
|
||||
if (currentCombat.verifica_combate) then --finaliza a checagem se esta ou n�o no combate
|
||||
Details:CancelTimer(currentCombat.verifica_combate)
|
||||
end
|
||||
|
||||
Details.last_closed_combat = nil
|
||||
@@ -497,30 +534,30 @@ function segmentClass:ResetAllCombatData()
|
||||
Details.schedule_store_boss_encounter = nil
|
||||
--_detalhes.schedule_remove_overall = nil
|
||||
|
||||
--fecha a janela de informa��es do jogador
|
||||
--close breakdown window
|
||||
Details:CloseBreakdownWindow()
|
||||
|
||||
--empty temporary tables
|
||||
Details.atributo_damage:ClearTempTables()
|
||||
|
||||
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")
|
||||
local segmentsTable = Details:GetCombatSegments()
|
||||
|
||||
for i = #segmentsTable, 1, -1 do
|
||||
---@type boolean, combat
|
||||
local bSegmentRemoved, combatObjectRemoved = Details:RemoveSegment(i)
|
||||
Details:DestroyCombat(combatObjectRemoved)
|
||||
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)
|
||||
--the current combat when finished will be moved to the first index of "segmentsTable", need the check if the current combat was already destroyed
|
||||
if (not currentCombat.__destroyed) then
|
||||
Details:DestroyCombat(currentCombat)
|
||||
if (currentCombat == segmentsTable[1]) then
|
||||
---@type boolean, combat
|
||||
local bSegmentRemoved, combatObjectRemoved = Details:RemoveSegment(1)
|
||||
end
|
||||
Details:SendEvent("DETAILS_DATA_SEGMENTREMOVED")
|
||||
end
|
||||
|
||||
Details:DestroyCombat(Details.tabela_overall) --not creating a new one immediatelly
|
||||
Details:SendEvent("DETAILS_DATA_SEGMENTREMOVED")
|
||||
|
||||
Details:Destroy(Details.spellcache)
|
||||
|
||||
@@ -590,6 +627,7 @@ function segmentClass:ResetAllCombatData()
|
||||
Details:RefreshMainWindow(-1) --atualiza todas as instancias
|
||||
|
||||
Details:SendEvent("DETAILS_DATA_RESET", nil, nil)
|
||||
Details:SendEvent("DETAILS_DATA_SEGMENTREMOVED")
|
||||
end
|
||||
|
||||
function Details.refresh:r_historico(este_historico)
|
||||
|
||||
+1617
-1615
File diff suppressed because it is too large
Load Diff
+2
-1
@@ -401,7 +401,8 @@ function _detalhes:TrackSpecsNow (track_everything)
|
||||
end
|
||||
else
|
||||
local combatlist = {}
|
||||
for _, combat in ipairs(_detalhes.tabela_historico.tabelas) do
|
||||
local segmentsTable = Details:GetCombatSegments()
|
||||
for _, combat in ipairs(segmentsTable) do
|
||||
tinsert(combatlist, combat)
|
||||
end
|
||||
tinsert(combatlist, _detalhes.tabela_vigente)
|
||||
|
||||
+65
-42
@@ -98,10 +98,10 @@ local classTypeUtility = Details.atributos.misc
|
||||
local overallCombatObject = Details.tabela_overall
|
||||
|
||||
---@type combat[]
|
||||
local allSegments = Details.tabela_historico.tabelas
|
||||
local segmentsTable = Details:GetCombatSegments()
|
||||
|
||||
--retore the call "combat()" functionality
|
||||
for _, combatObject in ipairs(allSegments) do
|
||||
for _, combatObject in ipairs(segmentsTable) do
|
||||
combatObject.__call = Details.call_combate
|
||||
end
|
||||
|
||||
@@ -118,8 +118,8 @@ local classTypeUtility = Details.atributos.misc
|
||||
local bIsInInstance = IsInInstance()
|
||||
|
||||
--inicia a recupera��o das tabelas e montagem do overall
|
||||
if (#allSegments > 0) then
|
||||
for index, thisCombatObject in ipairs(allSegments) do
|
||||
if (#segmentsTable > 0) then
|
||||
for index, thisCombatObject in ipairs(segmentsTable) do
|
||||
---@cast thisCombatObject combat
|
||||
|
||||
--set the metatable, __call and __index
|
||||
@@ -338,14 +338,15 @@ local classTypeUtility = Details.atributos.misc
|
||||
---remove all .owner references from actors, this unlink pets from owners but still leave the actor.ownerName member to rebuild later
|
||||
function Details:RemoveOwnerFromPets()
|
||||
---@type combat[]
|
||||
local combatTables = Details.tabela_historico.tabelas or {}
|
||||
local segmentsTable = Details:GetCombatSegments() or {}
|
||||
|
||||
local bOverallAdded
|
||||
if (not Details.overall_clear_logout) then
|
||||
table.insert(combatTables, Details.tabela_overall)
|
||||
table.insert(segmentsTable, Details.tabela_overall)
|
||||
bOverallAdded = true
|
||||
end
|
||||
|
||||
for _, combatObject in ipairs(combatTables) do
|
||||
for _, combatObject in ipairs(segmentsTable) do
|
||||
---@cast combatObject combat
|
||||
for _, actorContainer in ipairs(combatObject) do
|
||||
---@cast actorContainer actorcontainer
|
||||
@@ -357,22 +358,22 @@ local classTypeUtility = Details.atributos.misc
|
||||
end
|
||||
|
||||
if (bOverallAdded) then
|
||||
table.remove(combatTables, #combatTables)
|
||||
table.remove(segmentsTable, #segmentsTable)
|
||||
end
|
||||
end
|
||||
|
||||
function Details:DoClassesCleanup()
|
||||
---@type combat[]
|
||||
local combatTables = Details.tabela_historico.tabelas or {}
|
||||
local segmentsTable = Details:GetCombatSegments() or {}
|
||||
local bOverallAdded = false
|
||||
if (not Details.overall_clear_logout) then
|
||||
--add the overall segment to the cleanup within the other segments
|
||||
--it is removed after the cleanup
|
||||
table.insert(combatTables, Details.tabela_overall)
|
||||
table.insert(segmentsTable, Details.tabela_overall)
|
||||
bOverallAdded = true
|
||||
end
|
||||
|
||||
for index, combatObject in ipairs(combatTables) do
|
||||
for index, combatObject in ipairs(segmentsTable) do
|
||||
---@cast combatObject combat
|
||||
for classType, actorContainer in ipairs(combatObject) do
|
||||
---@cast actorContainer actorcontainer
|
||||
@@ -400,20 +401,20 @@ local classTypeUtility = Details.atributos.misc
|
||||
|
||||
if (bOverallAdded) then
|
||||
--remove the overall segment from the regular segments
|
||||
table.remove(combatTables, #combatTables)
|
||||
table.remove(segmentsTable, #segmentsTable)
|
||||
end
|
||||
end
|
||||
|
||||
function Details:DoContainerCleanup()
|
||||
---@type combat[]
|
||||
local combatTables = Details.tabela_historico.tabelas or {}
|
||||
local segmentsTable = Details:GetCombatSegments() or {}
|
||||
local bOverallAdded
|
||||
if (not Details.overall_clear_logout) then
|
||||
table.insert(combatTables, Details.tabela_overall)
|
||||
table.insert(segmentsTable, Details.tabela_overall)
|
||||
bOverallAdded = true
|
||||
end
|
||||
|
||||
for _, combatObject in ipairs(combatTables) do
|
||||
for _, combatObject in ipairs(segmentsTable) do
|
||||
---@cast combatObject combat
|
||||
Details.clear:c_combate(combatObject)
|
||||
for _, actorContainer in ipairs(combatObject) do
|
||||
@@ -423,27 +424,27 @@ local classTypeUtility = Details.atributos.misc
|
||||
end
|
||||
|
||||
if (bOverallAdded) then
|
||||
table.remove(combatTables, #combatTables)
|
||||
table.remove(segmentsTable, #segmentsTable)
|
||||
end
|
||||
end
|
||||
|
||||
function Details:DoContainerIndexCleanup()
|
||||
---@type combat[]
|
||||
local allSegments = Details.tabela_historico.tabelas or {}
|
||||
local segmentsTable = Details:GetCombatSegments() or {}
|
||||
local bOverallAdded
|
||||
if (not Details.overall_clear_logout) then
|
||||
table.insert(allSegments, Details.tabela_overall)
|
||||
table.insert(segmentsTable, Details.tabela_overall)
|
||||
bOverallAdded = true
|
||||
end
|
||||
|
||||
for _, combatObject in ipairs(allSegments) do
|
||||
for _, combatObject in ipairs(segmentsTable) do
|
||||
for _, actorContainer in ipairs(combatObject) do
|
||||
Details.clear:c_container_combatentes_index(actorContainer)
|
||||
end
|
||||
end
|
||||
|
||||
if (bOverallAdded) then
|
||||
table.remove(allSegments, #allSegments)
|
||||
table.remove(segmentsTable, #segmentsTable)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -460,26 +461,32 @@ local classTypeUtility = Details.atributos.misc
|
||||
---@type combat[]
|
||||
local combatTables = {}
|
||||
---@type combat[]
|
||||
local allSegments = Details.tabela_historico.tabelas or {}
|
||||
local segmentsTable = Details:GetCombatSegments() or {}
|
||||
|
||||
--remove segments marked as 'trash'
|
||||
for i = #allSegments, 1, -1 do
|
||||
for i = #segmentsTable, 1, -1 do
|
||||
---@type combat
|
||||
local combatObject = allSegments[i]
|
||||
if (combatObject:IsTrash()) then --error, IsTrash is not a function, probably because the combat got destroyed
|
||||
table.remove(allSegments, i)
|
||||
Details:DestroyCombat(combatObject) --no need to send DETAILS_DATA_SEGMENTREMOVED due to this be in the logout process
|
||||
local combatObject = segmentsTable[i]
|
||||
if (combatObject.__destroyed) then
|
||||
table.remove(segmentsTable, i)
|
||||
end
|
||||
end
|
||||
|
||||
--remove segments marked as 'trash'
|
||||
for i = #segmentsTable, 1, -1 do
|
||||
---@type combat
|
||||
local combatObject = segmentsTable[i]
|
||||
if (combatObject:IsTrash()) then
|
||||
table.remove(segmentsTable, i)
|
||||
end
|
||||
end
|
||||
|
||||
segmentsTable = Details:GetCombatSegments() or {}
|
||||
|
||||
--remove segments > of the segment limit to save
|
||||
if (Details.segments_amount_to_save and Details.segments_amount_to_save < Details.segments_amount) then
|
||||
for i = Details.segments_amount, Details.segments_amount_to_save + 1, -1 do
|
||||
if (Details.tabela_historico.tabelas[i]) then
|
||||
---@type combat
|
||||
local combatObject = Details.tabela_historico.tabelas[i]
|
||||
table.remove(Details.tabela_historico.tabelas, i)
|
||||
Details:DestroyCombat(combatObject)
|
||||
if (segmentsTable[i]) then
|
||||
table.remove(segmentsTable, i)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -488,7 +495,6 @@ local classTypeUtility = Details.atributos.misc
|
||||
if (Details.overall_clear_logout) then
|
||||
Details.tabela_overall = nil
|
||||
_detalhes_database.tabela_overall = nil
|
||||
Details:DestroyCombat(Details.tabela_overall)
|
||||
else
|
||||
---@type combat
|
||||
local overallCombatObject = Details.tabela_overall
|
||||
@@ -538,7 +544,7 @@ local classTypeUtility = Details.atributos.misc
|
||||
end
|
||||
end
|
||||
|
||||
for i, combatObject in ipairs(allSegments) do
|
||||
for i, combatObject in ipairs(segmentsTable) do
|
||||
---@cast combatObject combat
|
||||
combatTables[#combatTables+1] = combatObject
|
||||
end
|
||||
@@ -805,21 +811,38 @@ local classTypeUtility = Details.atributos.misc
|
||||
---@type number
|
||||
local amountRemoved = 0
|
||||
|
||||
--create a list of all combats except the current one
|
||||
---@type table<number, combat>
|
||||
local allSegments = Details:GetCombatSegments()
|
||||
---@type table
|
||||
local segmentsList = {}
|
||||
|
||||
---@type combat
|
||||
local currentCombat = Details:GetCurrentCombat()
|
||||
|
||||
for _, combatObject in ipairs(allSegments) do
|
||||
--create a list of all combats except the current one
|
||||
---@type table<number, combat>
|
||||
local segmentsTable = Details:GetCombatSegments()
|
||||
|
||||
--collect destroyed combat objects
|
||||
local bGotSegmentsRemoved = false
|
||||
for i = #segmentsTable, 1, -1 do
|
||||
local combatObject = segmentsTable[i]
|
||||
if (combatObject ~= currentCombat) then
|
||||
if (combatObject.__destroyed) then
|
||||
table.remove(segmentsTable, i)
|
||||
bGotSegmentsRemoved = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (bGotSegmentsRemoved) then
|
||||
Details:SendEvent("DETAILS_DATA_SEGMENTREMOVED")
|
||||
end
|
||||
|
||||
---@type table
|
||||
local segmentsList = {}
|
||||
|
||||
--add all segments except the current one
|
||||
for _, combatObject in ipairs(segmentsTable) do
|
||||
if (combatObject ~= currentCombat) then
|
||||
segmentsList[#segmentsList+1] = combatObject
|
||||
end
|
||||
end
|
||||
|
||||
--add the current segment at the end of the list
|
||||
segmentsList[#segmentsList+1] = currentCombat
|
||||
|
||||
|
||||
+37
-23
@@ -1062,10 +1062,10 @@
|
||||
--~activity time
|
||||
if (not sourceActor.dps_started) then
|
||||
--register on time machine
|
||||
sourceActor:Iniciar(true)
|
||||
sourceActor:GetOrChangeActivityStatus(true)
|
||||
|
||||
if (ownerActor and not ownerActor.dps_started) then
|
||||
ownerActor:Iniciar(true)
|
||||
ownerActor:GetOrChangeActivityStatus(true)
|
||||
if (ownerActor.end_time) then
|
||||
ownerActor.end_time = nil
|
||||
else
|
||||
@@ -1983,7 +1983,7 @@
|
||||
local jogador_alvo, alvo_dono = healing_cache [alvo_serial]
|
||||
if (not jogador_alvo) then
|
||||
jogador_alvo, alvo_dono, alvo_name = _current_heal_container:PegarCombatente (alvo_serial, alvo_name, alvo_flags, true)
|
||||
if (not alvo_dono and alvo_flags and also_serial ~= "") then
|
||||
if (not alvo_dono and alvo_flags and alvo_serial ~= "") then
|
||||
healing_cache [alvo_serial] = jogador_alvo
|
||||
end
|
||||
end
|
||||
@@ -2261,10 +2261,10 @@
|
||||
------------------------------------------------------------------------------------------------
|
||||
--~activity time
|
||||
if (not sourceActor.iniciar_hps) then
|
||||
sourceActor:Iniciar (true) --inicia o hps do jogador
|
||||
sourceActor:GetOrChangeActivityStatus (true) --inicia o hps do jogador
|
||||
|
||||
if (ownerActor and not ownerActor.iniciar_hps) then
|
||||
ownerActor:Iniciar (true)
|
||||
ownerActor:GetOrChangeActivityStatus (true)
|
||||
if (ownerActor.end_time) then
|
||||
ownerActor.end_time = nil
|
||||
else
|
||||
@@ -4898,7 +4898,7 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1
|
||||
--end
|
||||
end
|
||||
|
||||
Details:DispatchAutoRunCode("on_zonechanged")
|
||||
Details222.AutoRunCode.DispatchAutoRunCode("on_zonechanged")
|
||||
Details:SchedulePetUpdate(7)
|
||||
Details:CheckForPerformanceProfile()
|
||||
end
|
||||
@@ -5183,7 +5183,7 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1
|
||||
end
|
||||
end
|
||||
|
||||
Details:DispatchAutoRunCode("on_entercombat")
|
||||
Details222.AutoRunCode.DispatchAutoRunCode("on_entercombat")
|
||||
|
||||
Details.tabela_vigente.CombatStartedAt = GetTime()
|
||||
end
|
||||
@@ -5284,7 +5284,7 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1
|
||||
if (not OnRegenEnabled) then
|
||||
Details:Destroy(bitfield_swap_cache)
|
||||
Details:Destroy(empower_cache)
|
||||
Details:DispatchAutoRunCode("on_leavecombat")
|
||||
Details222.AutoRunCode.DispatchAutoRunCode("on_leavecombat")
|
||||
end
|
||||
|
||||
if (Details.solo and Details.PluginCount.SOLO > 0) then --code too old and I don't have documentation for it
|
||||
@@ -5596,7 +5596,7 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1
|
||||
Details:CheckVersion()
|
||||
Details:SendEvent("GROUP_ONENTER")
|
||||
|
||||
Details:DispatchAutoRunCode("on_groupchange")
|
||||
Details222.AutoRunCode.DispatchAutoRunCode("on_groupchange")
|
||||
|
||||
Details:Destroy(Details.trusted_characters)
|
||||
C_Timer.After(5, Details.ScheduleSyncPlayerActorData)
|
||||
@@ -5614,7 +5614,7 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1
|
||||
Details:InstanceCall(Details.AdjustAlphaByContext)
|
||||
Details:CheckSwitchOnLogon()
|
||||
Details:SendEvent("GROUP_ONLEAVE")
|
||||
Details:DispatchAutoRunCode("on_groupchange")
|
||||
Details222.AutoRunCode.DispatchAutoRunCode("on_groupchange")
|
||||
Details:Destroy(Details.trusted_characters)
|
||||
else
|
||||
--player is still in a group
|
||||
@@ -5670,7 +5670,7 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1
|
||||
|
||||
function Details:CreateBattlegroundSegment()
|
||||
if (_in_combat) then
|
||||
Details.tabela_vigente.discard_segment = true
|
||||
Details222.discardSegment = true
|
||||
Details:EndCombat()
|
||||
end
|
||||
|
||||
@@ -5693,6 +5693,8 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1
|
||||
return
|
||||
end
|
||||
|
||||
Details222.AutoRunCode.Code = {}
|
||||
|
||||
Details.popup = _G.GameCooltip
|
||||
Details.in_group = IsInGroup() or IsInRaid()
|
||||
Details.temp_table1 = {}
|
||||
@@ -5731,7 +5733,7 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1
|
||||
Details:UpdateParserGears()
|
||||
|
||||
--load auto run code
|
||||
Details:StartAutoRun()
|
||||
Details222.AutoRunCode.StartAutoRun()
|
||||
|
||||
Details.isLoaded = true
|
||||
end
|
||||
@@ -5856,6 +5858,8 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1
|
||||
---@type string current step of the logout process, used to log which is the current step when an error happens
|
||||
local currentStep = ""
|
||||
|
||||
Details222.AutoRunCode.OnLogout()
|
||||
|
||||
--save the time played on this class, run protected
|
||||
local savePlayTimeClass, savePlayTimeErrorText = pcall(function() Details.SavePlayTimeOnClass() end)
|
||||
|
||||
@@ -6037,6 +6041,12 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1
|
||||
return damage_cache[value] or damage_cache_pets[value] or damage_cache_petsOwners[value]
|
||||
end
|
||||
|
||||
---return tables containing the cache of actors
|
||||
---@return table damageCache, table damageCachePets, table damageCachePetOwners, table healingCache
|
||||
function Details222.Cache.GetParserCacheTables()
|
||||
return damage_cache, damage_cache_pets, damage_cache_petsOwners, healing_cache
|
||||
end
|
||||
|
||||
function Details:PrintParserCacheIndexes()
|
||||
local amount = 0
|
||||
for n, nn in pairs(damage_cache) do
|
||||
@@ -6455,9 +6465,9 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1
|
||||
end
|
||||
|
||||
--get an actor
|
||||
function Details:GetActor(combat, attribute, actorName)
|
||||
if (not combat) then
|
||||
combat = "current" --current combat
|
||||
function Details:GetActor(combatId, attribute, actorName)
|
||||
if (not combatId) then
|
||||
combatId = "current" --current combat
|
||||
end
|
||||
|
||||
if (not attribute) then
|
||||
@@ -6468,7 +6478,7 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1
|
||||
actorName = Details.playername
|
||||
end
|
||||
|
||||
if (combat == 0 or combat == "current") then
|
||||
if (combatId == 0 or combatId == "current") then
|
||||
local actor = Details.tabela_vigente(attribute, actorName)
|
||||
if (actor) then
|
||||
return actor
|
||||
@@ -6476,7 +6486,7 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1
|
||||
return nil
|
||||
end
|
||||
|
||||
elseif (combat == -1 or combat == "overall") then
|
||||
elseif (combatId == -1 or combatId == "overall") then
|
||||
local actor = Details.tabela_overall(attribute, actorName)
|
||||
if (actor) then
|
||||
return actor
|
||||
@@ -6484,12 +6494,16 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1
|
||||
return nil
|
||||
end
|
||||
|
||||
elseif (type(combat) == "number") then
|
||||
local combatTables = Details.tabela_historico.tabelas[combat]
|
||||
if (combatTables) then
|
||||
local actor = combatTables(attribute, actorName)
|
||||
if (actor) then
|
||||
return actor
|
||||
elseif (type(combatId) == "number") then
|
||||
local segmentsTable = Details:GetCombatSegments()
|
||||
---@type combat
|
||||
local combatObject = segmentsTable[combatId]
|
||||
|
||||
if (combatObject) then
|
||||
---@type actor
|
||||
local actorObject = combatObject(attribute, actorName)
|
||||
if (actorObject) then
|
||||
return actorObject
|
||||
else
|
||||
return nil
|
||||
end
|
||||
|
||||
@@ -108,7 +108,7 @@ function chartsObject.Ticker()
|
||||
--data set to capture data of some combat attribute or totals
|
||||
local combatTotalCaptures = configsForCaptureData.totals
|
||||
|
||||
local currentSegmentData = chartsObject.GetCurrentSegmentData()
|
||||
local currentSegmentData = chartsObject.GetCurrentCombatData()
|
||||
local chartData = currentSegmentData.ChartData
|
||||
|
||||
if (#playerCaptures > 0) then
|
||||
@@ -244,7 +244,7 @@ function chartsObject.HasValidAndOpenCombat()
|
||||
local bCombatState = chartsObject.GetCombatState()
|
||||
if (bCombatState) then
|
||||
local detaisCurrentCombat = Details:GetCurrentCombat()
|
||||
local chartCurrentSegmentData = chartsObject.GetCurrentSegmentData()
|
||||
local chartCurrentSegmentData = chartsObject.GetCurrentCombatData()
|
||||
if (detaisCurrentCombat:GetCombatId() == chartCurrentSegmentData:GetCombatId()) then
|
||||
--it's all good
|
||||
return true
|
||||
@@ -266,7 +266,7 @@ function chartsObject.GetNumSegments()
|
||||
return #chartsObject.SegmentsData
|
||||
end
|
||||
|
||||
function chartsObject.GetCurrentSegmentData()
|
||||
function chartsObject.GetCurrentCombatData()
|
||||
return chartsObject.segmentData
|
||||
end
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ function breakdownWindowPlayerList.CreatePlayerListFrame()
|
||||
---@type button
|
||||
local pluginButton = breakdownWindowFrame.RegisteredPluginButtons[i]
|
||||
pluginButton:Show()
|
||||
pluginButton:Hide() --not ready yet
|
||||
pluginButton:ClearAllPoints()
|
||||
|
||||
if (i == 1) then
|
||||
@@ -451,7 +452,7 @@ function breakdownWindowPlayerList.CreatePlayerListFrame()
|
||||
end)
|
||||
|
||||
local gradientStartColor = Details222.ColorScheme.GetColorFor("gradient-background")
|
||||
local gradientBelow = DetailsFramework:CreateTexture(breakdownWindowFrame.playerScrollBox,
|
||||
local gradientBelow = DetailsFramework:CreateTexture(breakdownWindowFrame.playerScrollBox,
|
||||
{gradient = "vertical", fromColor = gradientStartColor, toColor = "transparent"}, 1, 90, "artwork", {0, 1, 0, 1})
|
||||
gradientBelow:SetPoint("bottoms", 1, 1)
|
||||
end
|
||||
|
||||
@@ -6206,7 +6206,8 @@ function Details:GetSegmentInfo(index)
|
||||
elseif (index == 0 or index == "current") then
|
||||
combat = Details.tabela_vigente
|
||||
else
|
||||
combat = Details.tabela_historico.tabelas[index]
|
||||
local segmentsTable = Details:GetCombatSegments()
|
||||
combat = segmentsTable[index]
|
||||
end
|
||||
|
||||
if (combat) then
|
||||
@@ -6319,8 +6320,10 @@ local buildSegmentTooltip = function(self, deltaTime)
|
||||
local amountOfSegments = 0
|
||||
local segmentsWithACombat = 0
|
||||
|
||||
local segmentsTable = Details:GetCombatSegments()
|
||||
|
||||
for i = 1, Details.segments_amount do
|
||||
if (Details.tabela_historico.tabelas[i]) then
|
||||
if (segmentsTable[i]) then
|
||||
segmentsWithACombat = segmentsWithACombat + 1
|
||||
else
|
||||
break
|
||||
@@ -6339,7 +6342,7 @@ local buildSegmentTooltip = function(self, deltaTime)
|
||||
local isMythicDungeon = false
|
||||
for i = Details.segments_amount, 1, -1 do
|
||||
if (i <= fill) then
|
||||
local thisCombat = Details.tabela_historico.tabelas[i]
|
||||
local thisCombat = segmentsTable[i]
|
||||
if (thisCombat and not thisCombat.__destroyed) then
|
||||
local enemy = thisCombat.is_boss and thisCombat.is_boss.name
|
||||
local segmentInfoAdded = false
|
||||
|
||||
@@ -195,6 +195,7 @@ function Details.options.InitializeOptionsWindow(instance)
|
||||
--search field
|
||||
local searchBox = detailsFramework:CreateTextEntry(footerFrame, function()end, 140, 20, _, _, _, options_dropdown_template)
|
||||
searchBox:SetPoint("left", changelog, "right", 10, 0)
|
||||
searchBox:SetAsSearchBox()
|
||||
|
||||
local searchLabel = detailsFramework:CreateLabel(footerFrame, "Search:") --localize-me
|
||||
searchLabel:SetPoint("bottomleft", searchBox, "topleft", 0, 2)
|
||||
|
||||
+166
-142
@@ -1,189 +1,213 @@
|
||||
|
||||
local Details = _G.Details
|
||||
local DF = _G.DetailsFramework
|
||||
local detailsFramework = _G.DetailsFramework
|
||||
local _
|
||||
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- ~run ~runcode
|
||||
local addonName, Details222 = ...
|
||||
local CreateFrame = CreateFrame
|
||||
local UIParent = UIParent
|
||||
local load = loadstring
|
||||
|
||||
function Details:InitializeRunCodeWindow()
|
||||
local DetailsRunCodePanel = DF:CreateSimplePanel(UIParent, 700, 480, "Details! Run Code", "DetailsRunCodePanel")
|
||||
DetailsRunCodePanel.Frame = DetailsRunCodePanel
|
||||
DetailsRunCodePanel.__name = "Auto Run Code"
|
||||
DetailsRunCodePanel.real_name = "DETAILS_RUNCODEWINDOW"
|
||||
local detailsRunCodePanel = detailsFramework:CreateSimplePanel(UIParent, 700, 480, "Details! Run Code Automation", "DetailsRunCodePanel")
|
||||
detailsRunCodePanel.Frame = detailsRunCodePanel
|
||||
detailsRunCodePanel.__name = "Auto Run Code"
|
||||
detailsRunCodePanel.real_name = "DETAILS_RUNCODEWINDOW"
|
||||
--DetailsRunCodePanel.__icon = [[Interface\AddOns\Details\images\lua_logo]]
|
||||
DetailsRunCodePanel.__icon = [[Interface\AddOns\Details\images\run_code]]
|
||||
detailsRunCodePanel.__icon = [[Interface\AddOns\Details\images\run_code]]
|
||||
--DetailsRunCodePanel.__iconcoords = {0, 1, 0, 1}
|
||||
DetailsRunCodePanel.__iconcoords = {0, 30/32, 0, 25/32}
|
||||
DetailsRunCodePanel.__iconcoords = {0, 1, 0, 1}
|
||||
DetailsRunCodePanel.__iconcolor = "white"
|
||||
DetailsPluginContainerWindow.EmbedPlugin (DetailsRunCodePanel, DetailsRunCodePanel, true)
|
||||
|
||||
function DetailsRunCodePanel.RefreshWindow()
|
||||
Details.OpenRunCodeWindow()
|
||||
detailsRunCodePanel.__iconcoords = {0, 30/32, 0, 25/32}
|
||||
detailsRunCodePanel.__iconcoords = {0, 1, 0, 1}
|
||||
detailsRunCodePanel.__iconcolor = "white"
|
||||
DetailsPluginContainerWindow.EmbedPlugin(detailsRunCodePanel, detailsRunCodePanel, true)
|
||||
|
||||
function detailsRunCodePanel.RefreshWindow()
|
||||
Details222.AutoRunCode.OpenRunCodeWindow()
|
||||
end
|
||||
|
||||
DetailsRunCodePanel:Hide()
|
||||
|
||||
detailsRunCodePanel:Hide()
|
||||
|
||||
Details222.AutoRunCode.DetailsRunCodePanel = detailsRunCodePanel
|
||||
end
|
||||
|
||||
function Details.OpenRunCodeWindow()
|
||||
if (not DetailsRunCodePanel or not DetailsRunCodePanel.Initialized) then
|
||||
|
||||
DetailsRunCodePanel.Initialized = true
|
||||
|
||||
local f = DetailsRunCodePanel or DF:CreateSimplePanel(UIParent, 700, 480, "Details! Run Code", "DetailsRunCodePanel")
|
||||
function Details222.AutoRunCode.OpenRunCodeWindow()
|
||||
local detailsRunCodePanel = Details222.AutoRunCode.DetailsRunCodePanel
|
||||
|
||||
if (not detailsRunCodePanel or not detailsRunCodePanel.Initialized) then
|
||||
detailsRunCodePanel.Initialized = true
|
||||
|
||||
local autoRunCodeFrame = detailsRunCodePanel or detailsFramework:CreateSimplePanel(UIParent, 700, 480, "Details! Run Code", "DetailsRunCodePanel")
|
||||
|
||||
--lua editor
|
||||
local code_editor = DF:NewSpecialLuaEditorEntry(f, 885, 510, "text", "$parentCodeEditorWindow")
|
||||
f.CodeEditor = code_editor
|
||||
code_editor:SetPoint("topleft", f, "topleft", 20, -56)
|
||||
|
||||
--code editor appearance
|
||||
code_editor.scroll:SetBackdrop(nil)
|
||||
code_editor.editbox:SetBackdrop(nil)
|
||||
code_editor:SetBackdrop(nil)
|
||||
|
||||
DF:ReskinSlider(code_editor.scroll)
|
||||
|
||||
if (not code_editor.__background) then
|
||||
code_editor.__background = code_editor:CreateTexture(nil, "background")
|
||||
end
|
||||
|
||||
code_editor:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1})
|
||||
code_editor:SetBackdropBorderColor(0, 0, 0, 1)
|
||||
|
||||
code_editor.__background:SetColorTexture(0.2317647, 0.2317647, 0.2317647)
|
||||
code_editor.__background:SetVertexColor(0.27, 0.27, 0.27)
|
||||
code_editor.__background:SetAlpha(0.8)
|
||||
code_editor.__background:SetVertTile(true)
|
||||
code_editor.__background:SetHorizTile(true)
|
||||
code_editor.__background:SetAllPoints()
|
||||
|
||||
--code compile error warning
|
||||
local errortext_frame = CreateFrame("frame", nil, code_editor,"BackdropTemplate")
|
||||
errortext_frame:SetPoint("bottomleft", code_editor, "bottomleft", 1, 1)
|
||||
errortext_frame:SetPoint("bottomright", code_editor, "bottomright", -1, 1)
|
||||
errortext_frame:SetHeight(20)
|
||||
errortext_frame:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
|
||||
errortext_frame:SetBackdropBorderColor(0, 0, 0, 1)
|
||||
errortext_frame:SetBackdropColor(0, 0, 0)
|
||||
|
||||
DF:CreateFlashAnimation (errortext_frame)
|
||||
|
||||
local errortext_label = DF:CreateLabel(errortext_frame, "", DF:GetTemplate("font", "ORANGE_FONT_TEMPLATE"))
|
||||
errortext_label.textcolor = "red"
|
||||
errortext_label:SetPoint("left", errortext_frame, "left", 3, 0)
|
||||
code_editor.NextCodeCheck = 0.33
|
||||
|
||||
code_editor:HookScript ("OnUpdate", function(self, deltaTime)
|
||||
code_editor.NextCodeCheck = code_editor.NextCodeCheck - deltaTime
|
||||
local codeEditor = detailsFramework:NewSpecialLuaEditorEntry(UIParent, 885, 510, nil, nil, false, true, true)
|
||||
codeEditor:SetPoint("topleft", autoRunCodeFrame, "topleft", 20, -56)
|
||||
codeEditor:SetFrameStrata(autoRunCodeFrame:GetFrameStrata())
|
||||
codeEditor:SetFrameLevel(autoRunCodeFrame:GetFrameLevel()+1)
|
||||
|
||||
if (code_editor.NextCodeCheck < 0) then
|
||||
local script = code_editor:GetText()
|
||||
local func, errortext = loadstring (script, "Q")
|
||||
if (not func) then
|
||||
local firstLine = strsplit("\n", script, 2)
|
||||
errortext = errortext:gsub(firstLine, "")
|
||||
errortext = errortext:gsub("%[string \"", "")
|
||||
errortext = errortext:gsub("...\"]:", "")
|
||||
errortext = errortext:gsub("Q\"]:", "")
|
||||
errortext = "Line " .. errortext
|
||||
errortext_label.text = errortext
|
||||
else
|
||||
errortext_label.text = ""
|
||||
end
|
||||
|
||||
code_editor.NextCodeCheck = 0.33
|
||||
function Details222.AutoRunCode.CodeEditorSetText(codeKey)
|
||||
local text = Details222.AutoRunCode.CodeTable[codeKey]
|
||||
return codeEditor:SetText(text)
|
||||
end
|
||||
|
||||
detailsRunCodePanel:HookScript("OnShow", function()
|
||||
codeEditor:Show()
|
||||
end)
|
||||
detailsRunCodePanel:SetScript("OnHide", function()
|
||||
codeEditor:Hide()
|
||||
end)
|
||||
|
||||
--code editor appearance
|
||||
codeEditor.scroll:SetBackdrop(nil)
|
||||
codeEditor.editbox:SetBackdrop(nil)
|
||||
codeEditor:SetBackdrop(nil)
|
||||
|
||||
detailsFramework:ReskinSlider(codeEditor.scroll)
|
||||
|
||||
if (not codeEditor.__background) then
|
||||
codeEditor.__background = codeEditor:CreateTexture(nil, "background")
|
||||
end
|
||||
|
||||
codeEditor:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1})
|
||||
codeEditor:SetBackdropBorderColor(0, 0, 0, 1)
|
||||
|
||||
codeEditor.__background:SetColorTexture(0.2317647, 0.2317647, 0.2317647)
|
||||
codeEditor.__background:SetVertexColor(0.27, 0.27, 0.27)
|
||||
codeEditor.__background:SetAlpha(0.8)
|
||||
codeEditor.__background:SetVertTile(true)
|
||||
codeEditor.__background:SetHorizTile(true)
|
||||
codeEditor.__background:SetAllPoints()
|
||||
|
||||
--code compile error warning
|
||||
local errortext_frame = CreateFrame("frame", nil, codeEditor, "BackdropTemplate")
|
||||
errortext_frame:SetPoint("bottomleft", codeEditor, "bottomleft", 1, 1)
|
||||
errortext_frame:SetPoint("bottomright", codeEditor, "bottomright", -1, 1)
|
||||
errortext_frame:SetHeight(20)
|
||||
errortext_frame:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
|
||||
errortext_frame:SetBackdropBorderColor(0, 0, 0, 1)
|
||||
errortext_frame:SetBackdropColor(0, 0, 0)
|
||||
|
||||
detailsFramework:CreateFlashAnimation (errortext_frame)
|
||||
|
||||
local errortext_label = detailsFramework:CreateLabel(errortext_frame, "", detailsFramework:GetTemplate("font", "ORANGE_FONT_TEMPLATE"))
|
||||
errortext_label.textcolor = "red"
|
||||
errortext_label:SetPoint("left", errortext_frame, "left", 3, 0)
|
||||
codeEditor.NextCodeCheck = 0.33
|
||||
|
||||
codeEditor:HookScript ("OnUpdate", function(self, deltaTime)
|
||||
codeEditor.NextCodeCheck = codeEditor.NextCodeCheck - deltaTime
|
||||
|
||||
if (codeEditor.NextCodeCheck < 0) then
|
||||
local script = codeEditor:GetText()
|
||||
local func, errortext = load(script, "Q")
|
||||
if (not func) then
|
||||
local firstLine = strsplit("\n", script, 2)
|
||||
errortext = errortext:gsub(firstLine, "")
|
||||
errortext = errortext:gsub("%[string \"", "")
|
||||
errortext = errortext:gsub("...\"]:", "")
|
||||
errortext = errortext:gsub("Q\"]:", "")
|
||||
errortext = "Line " .. errortext
|
||||
errortext_label.text = errortext
|
||||
else
|
||||
errortext_label.text = ""
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
codeEditor.NextCodeCheck = 0.33
|
||||
end
|
||||
end)
|
||||
|
||||
--script selector
|
||||
local on_select_CodeType_option = function(self, fixedParameter, value)
|
||||
--set the current editing code type
|
||||
f.EditingCode = Details.RunCodeTypes [value].Value
|
||||
f.EditingCodeKey = Details.RunCodeTypes [value].ProfileKey
|
||||
|
||||
autoRunCodeFrame.EditingCode = Details.RunCodeTypes[value].Value
|
||||
autoRunCodeFrame.EditingCodeKey = Details.RunCodeTypes[value].ProfileKey
|
||||
|
||||
--load the code for the event
|
||||
local code = Details.run_code [f.EditingCodeKey]
|
||||
code_editor:SetText(code)
|
||||
Details222.AutoRunCode.CodeEditorSetText(autoRunCodeFrame.EditingCodeKey)
|
||||
end
|
||||
|
||||
|
||||
local build_CodeType_dropdown_options = function()
|
||||
local t = {}
|
||||
|
||||
|
||||
for i = 1, #Details.RunCodeTypes do
|
||||
local option = Details.RunCodeTypes [i]
|
||||
t [#t + 1] = {label = option.Name, value = option.Value, onclick = on_select_CodeType_option, desc = option.Desc}
|
||||
end
|
||||
|
||||
|
||||
return t
|
||||
end
|
||||
|
||||
local code_type_label = DF:CreateLabel(f, "Event:", DF:GetTemplate("font", "ORANGE_FONT_TEMPLATE"))
|
||||
local code_type_dropdown = DF:CreateDropDown (f, build_CodeType_dropdown_options, 1, 160, 20, "CodeTypeDropdown", _, DF:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE"))
|
||||
|
||||
local code_type_label = detailsFramework:CreateLabel(autoRunCodeFrame, "Event:", detailsFramework:GetTemplate("font", "ORANGE_FONT_TEMPLATE"))
|
||||
local code_type_dropdown = detailsFramework:CreateDropDown(autoRunCodeFrame, build_CodeType_dropdown_options, 1, 160, 20, "CodeTypeDropdown", _, detailsFramework:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE"))
|
||||
code_type_dropdown:SetPoint("left", code_type_label, "right", 2, 0)
|
||||
code_type_dropdown:SetFrameLevel(code_editor:GetFrameLevel() + 10)
|
||||
code_type_label:SetPoint("bottomleft", code_editor, "topleft", 0, 8)
|
||||
|
||||
code_type_dropdown:SetFrameLevel(codeEditor:GetFrameLevel() + 10)
|
||||
code_type_label:SetPoint("bottomleft", codeEditor, "topleft", 0, 8)
|
||||
|
||||
--create save button
|
||||
local save_script = function()
|
||||
local code = code_editor:GetText()
|
||||
local func, errortext = loadstring (code, "Q")
|
||||
|
||||
local code = codeEditor:GetText()
|
||||
local func, errortext = load(code, "Q")
|
||||
|
||||
if (func) then
|
||||
Details.run_code [f.EditingCodeKey] = code
|
||||
Details:RecompileAutoRunCode()
|
||||
Details222.AutoRunCode.CodeTable[autoRunCodeFrame.EditingCodeKey] = code
|
||||
Details222.AutoRunCode.RecompileAutoRunCode()
|
||||
Details:Msg("Code saved!")
|
||||
code_editor:ClearFocus()
|
||||
codeEditor:ClearFocus()
|
||||
else
|
||||
errortext_frame:Flash(0.2, 0.2, 0.4, true, nil, nil, "NONE")
|
||||
Details:Msg("Can't save the code: it has errors.")
|
||||
end
|
||||
end
|
||||
|
||||
local button_y = -6
|
||||
|
||||
local save_script_button = DF:CreateButton(f, save_script, 120, 20, "Save", -1, nil, nil, nil, nil, nil, DF:GetTemplate("button", "OPTIONS_BUTTON_TEMPLATE"), DF:GetTemplate("font", "PLATER_BUTTON"))
|
||||
save_script_button:SetIcon ([[Interface\BUTTONS\UI-Panel-ExpandButton-Up]], 20, 20, "overlay", {0.1, .9, 0.1, .9})
|
||||
save_script_button:SetPoint("topright", code_editor, "bottomright", 0, button_y)
|
||||
|
||||
--create cancel button
|
||||
|
||||
local cancel_script = function()
|
||||
code_editor:SetText(Details.run_code [f.EditingCodeKey])
|
||||
Details:Msg("Code cancelled!")
|
||||
code_editor:ClearFocus()
|
||||
Details222.AutoRunCode.CodeEditorSetText(autoRunCodeFrame.EditingCodeKey)
|
||||
codeEditor:ClearFocus()
|
||||
end
|
||||
|
||||
local cancel_script_button = DF:CreateButton(f, cancel_script, 120, 20, "Cancel", -1, nil, nil, nil, nil, nil, DF:GetTemplate("button", "OPTIONS_BUTTON_TEMPLATE"), DF:GetTemplate("font", "PLATER_BUTTON"))
|
||||
cancel_script_button:SetIcon ([[Interface\BUTTONS\UI-Panel-MinimizeButton-Up]], 20, 20, "overlay", {0.1, .9, 0.1, .9})
|
||||
cancel_script_button:SetPoint("topleft", code_editor, "bottomleft", 0, button_y)
|
||||
|
||||
--create run now button
|
||||
|
||||
|
||||
local execute_script = function()
|
||||
local script = code_editor:GetText()
|
||||
local func, errortext = loadstring (script, "Q")
|
||||
|
||||
local script = codeEditor:GetText()
|
||||
local func, errortext = load(script, "Q")
|
||||
|
||||
if (func) then
|
||||
DF:SetEnvironment(func)
|
||||
DF:QuickDispatch(func)
|
||||
detailsFramework:SetEnvironment(func)
|
||||
detailsFramework:QuickDispatch(func)
|
||||
else
|
||||
errortext_frame:Flash(0.2, 0.2, 0.4, true, nil, nil, "NONE")
|
||||
end
|
||||
end
|
||||
|
||||
local run_script_button = DF:CreateButton(f, execute_script, 120, 20, "Test Code", -1, nil, nil, nil, nil, nil, DF:GetTemplate("button", "OPTIONS_BUTTON_TEMPLATE"), DF:GetTemplate("font", "PLATER_BUTTON"))
|
||||
run_script_button:SetIcon ([[Interface\BUTTONS\UI-SpellbookIcon-NextPage-Up]], 20, 20, "overlay", {0.05, 0.95, 0.05, 0.95})
|
||||
run_script_button:SetPoint("bottomright", code_editor, "topright", 0, 3)
|
||||
|
||||
end
|
||||
|
||||
DetailsPluginContainerWindow.OpenPlugin (DetailsRunCodePanel)
|
||||
DetailsRunCodePanel.CodeTypeDropdown:Select(1, true)
|
||||
|
||||
--show the initialization code when showing up this window
|
||||
DetailsRunCodePanel.EditingCode = Details.RunCodeTypes [1].Value
|
||||
DetailsRunCodePanel.EditingCodeKey = Details.RunCodeTypes [1].ProfileKey
|
||||
|
||||
local code = Details.run_code [DetailsRunCodePanel.EditingCodeKey]
|
||||
DetailsRunCodePanel.CodeEditor:SetText(code)
|
||||
local button_y = -6
|
||||
|
||||
local saveButton = CreateFrame("button", nil, codeEditor)
|
||||
detailsFramework:ApplyStandardBackdrop(saveButton)
|
||||
saveButton:SetSize(120, 20)
|
||||
saveButton:SetText("Save")
|
||||
saveButton:SetScript("OnClick", save_script)
|
||||
saveButton:SetPoint("topright", codeEditor, "bottomright", 0, button_y)
|
||||
saveButton:SetNormalFontObject("GameFontNormal")
|
||||
|
||||
local cancelButton = CreateFrame("button", nil, codeEditor)
|
||||
detailsFramework:ApplyStandardBackdrop(cancelButton)
|
||||
cancelButton:SetSize(120, 20)
|
||||
cancelButton:SetText("Cancel")
|
||||
cancelButton:SetScript("OnClick", cancel_script)
|
||||
cancelButton:SetPoint("topleft", codeEditor, "bottomleft", 0, button_y)
|
||||
cancelButton:SetNormalFontObject("GameFontNormal")
|
||||
|
||||
--create run now button
|
||||
local runButton = CreateFrame("button", nil, codeEditor)
|
||||
detailsFramework:ApplyStandardBackdrop(runButton)
|
||||
runButton:SetSize(120, 20)
|
||||
runButton:SetText("Test Code")
|
||||
runButton:SetScript("OnClick", execute_script)
|
||||
runButton:SetPoint("bottomright", codeEditor, "topright", 0, 3)
|
||||
runButton:SetNormalFontObject("GameFontNormal")
|
||||
end
|
||||
|
||||
DetailsPluginContainerWindow.OpenPlugin(detailsRunCodePanel)
|
||||
detailsRunCodePanel.CodeTypeDropdown:Select(1, true)
|
||||
|
||||
--show the initialization code when showing up this window
|
||||
detailsRunCodePanel.EditingCode = Details.RunCodeTypes[1].Value
|
||||
detailsRunCodePanel.EditingCodeKey = Details.RunCodeTypes[1].ProfileKey
|
||||
|
||||
Details222.AutoRunCode.CodeEditorSetText(detailsRunCodePanel.EditingCodeKey)
|
||||
end
|
||||
|
||||
+89
-86
@@ -9,6 +9,7 @@ local _
|
||||
local unpack = unpack
|
||||
local floor = math.floor
|
||||
local gameCooltip = GameCooltip
|
||||
local CreateFrame = CreateFrame
|
||||
|
||||
--api locals
|
||||
do
|
||||
@@ -164,7 +165,7 @@ do
|
||||
self.MainFrame.texture:SetBlendMode("BLEND")
|
||||
on_leave_all_switch_button(self.MainFrame)
|
||||
end
|
||||
|
||||
|
||||
allDisplaysFrame.check_text_size = function(font_string)
|
||||
local text_width = font_string:GetStringWidth()
|
||||
while (text_width > 104) do
|
||||
@@ -174,20 +175,20 @@ do
|
||||
text_width = font_string:GetStringWidth()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local create_all_switch_button = function(attribute, sub_attribute, x, y)
|
||||
local button = CreateFrame("button", "DetailsAllAttributesFrame" .. attribute .. sub_attribute, allDisplaysFrame)
|
||||
button:SetSize(130, 16)
|
||||
button.texture = button:CreateTexture(nil, "overlay")
|
||||
button.texture:SetPoint("left", 0, 0)
|
||||
button.texture:SetSize(icon_size, icon_size)
|
||||
|
||||
|
||||
local texture_highlight_frame = CreateFrame("button", "DetailsAllAttributesFrame" .. attribute .. sub_attribute .. "IconFrame", button)
|
||||
texture_highlight_frame:SetSize(icon_size, icon_size)
|
||||
texture_highlight_frame:SetPoint("left", 0, 0)
|
||||
texture_highlight_frame.texture = button.texture
|
||||
texture_highlight_frame.MainFrame = button
|
||||
|
||||
|
||||
button.text = button:CreateFontString(nil, "overlay", "GameFontNormal")
|
||||
button.text:SetPoint("left", button.texture, "right", 2, 0)
|
||||
button.attribute = attribute
|
||||
@@ -195,22 +196,22 @@ do
|
||||
button:SetPoint("topleft", x, y)
|
||||
Details:SetFontSize(button.text, Details.all_switch_config.font_size)
|
||||
Details:SetFontColor(button.text, text_color)
|
||||
|
||||
|
||||
button:SetScript("OnClick", on_click_all_switch_button)
|
||||
button:SetScript("OnEnter", on_enter_all_switch_button)
|
||||
button:SetScript("OnLeave", on_leave_all_switch_button)
|
||||
|
||||
|
||||
texture_highlight_frame:SetScript("OnClick", on_click_all_switch_button)
|
||||
texture_highlight_frame:SetScript("OnEnter", on_enter_all_switch_button_icon)
|
||||
texture_highlight_frame:SetScript("OnLeave", on_leave_all_switch_button_icon)
|
||||
|
||||
|
||||
button:RegisterForClicks ("LeftButtonDown", "RightButtonDown")
|
||||
|
||||
return button
|
||||
end
|
||||
|
||||
|
||||
allDisplaysFrame:SetScript("OnShow", function()
|
||||
|
||||
|
||||
if (not allDisplaysFrame.already_built) then
|
||||
local x, y = 8, -8
|
||||
allDisplaysFrame.higher_counter = 0
|
||||
@@ -228,9 +229,9 @@ do
|
||||
local title_str = allDisplaysFrame:CreateFontString(nil, "overlay", "GameFontNormal")
|
||||
title_str:SetPoint("left", title_icon, "right", 2, 0)
|
||||
title_str:SetText(loc_attribute_name)
|
||||
|
||||
|
||||
y = y - 20
|
||||
|
||||
|
||||
allDisplaysFrame.buttons [attribute] = {}
|
||||
for i = 1, #Details.sub_atributos [attribute].lista do
|
||||
--localized sub attribute name
|
||||
@@ -246,20 +247,20 @@ do
|
||||
tinsert(allDisplaysFrame.buttons [attribute], button)
|
||||
y = y - 17
|
||||
end
|
||||
|
||||
|
||||
if (#Details.sub_atributos [attribute].lista > allDisplaysFrame.higher_counter) then
|
||||
allDisplaysFrame.higher_counter = #Details.sub_atributos [attribute].lista
|
||||
end
|
||||
|
||||
|
||||
x = x + 130
|
||||
y = -8
|
||||
end
|
||||
|
||||
|
||||
--prepare for scripts
|
||||
allDisplaysFrame.x = x
|
||||
allDisplaysFrame.y = -8
|
||||
allDisplaysFrame.buttons [Details.atributos[0]+1] = {}
|
||||
|
||||
|
||||
local title_icon = allDisplaysFrame:CreateTexture(nil, "overlay")
|
||||
local texture, l, r, t, b = Details:GetAttributeIcon (Details.atributos[0]+1)
|
||||
title_icon:SetTexture([[Interface\AddOns\Details\images\icons]])
|
||||
@@ -269,11 +270,11 @@ do
|
||||
local title_str = allDisplaysFrame:CreateFontString(nil, "overlay", "GameFontNormal")
|
||||
title_str:SetPoint("left", title_icon, "right", 2, 0)
|
||||
title_str:SetText("Scripts")
|
||||
|
||||
|
||||
title_icon:SetPoint("topleft", allDisplaysFrame.x, allDisplaysFrame.y)
|
||||
allDisplaysFrame.y = allDisplaysFrame.y - 20
|
||||
allDisplaysFrame.title_custom = title_icon
|
||||
|
||||
|
||||
allDisplaysFrame.already_built = true
|
||||
|
||||
--prepare for plugins
|
||||
@@ -289,13 +290,13 @@ do
|
||||
title_icon:SetPoint("topleft", allDisplaysFrame.x + 130, -8)
|
||||
allDisplaysFrame.title_scripts = title_icon
|
||||
end
|
||||
|
||||
|
||||
--update scripts
|
||||
local custom_index = Details.atributos[0]+1
|
||||
for _, button in ipairs(allDisplaysFrame.buttons [custom_index]) do
|
||||
button:Hide()
|
||||
end
|
||||
|
||||
|
||||
local button_index = 1
|
||||
for i = #Details.custom, 1, -1 do
|
||||
local button = allDisplaysFrame.buttons [custom_index] [button_index]
|
||||
@@ -304,7 +305,7 @@ do
|
||||
tinsert(allDisplaysFrame.buttons [custom_index], button)
|
||||
allDisplaysFrame.y = allDisplaysFrame.y - 17
|
||||
end
|
||||
|
||||
|
||||
local custom = Details.custom [i]
|
||||
button.text:SetText(custom.name)
|
||||
Details:SetFontSize(button.text, Details.all_switch_config.font_size)
|
||||
@@ -313,10 +314,10 @@ do
|
||||
button.texture:SetTexture(custom.icon)
|
||||
button.texture:SetTexCoord(0.078125, 0.921875, 0.078125, 0.921875)
|
||||
button:Show()
|
||||
|
||||
|
||||
button_index = button_index + 1
|
||||
end
|
||||
|
||||
|
||||
if (#Details.custom > allDisplaysFrame.higher_counter) then
|
||||
allDisplaysFrame.higher_counter = #Details.custom
|
||||
end
|
||||
@@ -351,12 +352,12 @@ do
|
||||
|
||||
button.text:SetText(ptable[1])
|
||||
Details:SetFontSize(button.text, Details.all_switch_config.font_size)
|
||||
|
||||
|
||||
allDisplaysFrame.check_text_size(button.text)
|
||||
button.texture:SetTexture(ptable[2])
|
||||
button.texture:SetTexCoord(0.078125, 0.921875, 0.078125, 0.921875)
|
||||
button:Show()
|
||||
|
||||
|
||||
button_index = button_index + 1
|
||||
end
|
||||
end
|
||||
@@ -496,42 +497,42 @@ function Details.switch:ShowMe(instancia)
|
||||
Details.switch.CloseMe()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local hide_label = function(self)
|
||||
self.texture:Hide()
|
||||
self.button:Hide()
|
||||
self.background:Hide()
|
||||
self:Hide()
|
||||
end
|
||||
|
||||
|
||||
local show_label = function(self)
|
||||
self.texture:Show()
|
||||
self.button:Show()
|
||||
self.background:Show()
|
||||
self:Show()
|
||||
end
|
||||
|
||||
|
||||
local on_enter = function(self)
|
||||
--self.MyObject.this_background:SetBlendMode("ADD")
|
||||
--self.MyObject.boss_texture:SetBlendMode("ADD")
|
||||
end
|
||||
|
||||
|
||||
local on_leave = function(self)
|
||||
self.MyObject.this_background:SetBlendMode("BLEND")
|
||||
self.MyObject.boss_texture:SetBlendMode("BLEND")
|
||||
end
|
||||
|
||||
|
||||
function Details.switch:CreateSegmentBlock()
|
||||
local s = gump:CreateLabel(Details.switch.frame)
|
||||
Details:SetFontSize(s, 9)
|
||||
|
||||
|
||||
local index = #Details.switch.segments_blocks
|
||||
if (index == 1) then --overall button
|
||||
index = -1
|
||||
elseif (index >= 2) then
|
||||
index = index - 1
|
||||
end
|
||||
|
||||
|
||||
local button = gump:CreateButton(Details.switch.frame, segment_switch, 100, 20, "", index)
|
||||
button:SetPoint("topleft", s, "topleft", -17, 0)
|
||||
button:SetPoint("bottomright", s, "bottomright", 0, 0)
|
||||
@@ -546,24 +547,24 @@ function Details.switch:ShowMe(instancia)
|
||||
background:SetWidth(85)
|
||||
background:SetPoint("topleft", s.widget, "topleft", -16, 3)
|
||||
background:SetPoint("bottomright", s.widget, "bottomright", -3, -5)
|
||||
|
||||
|
||||
button.this_background = background
|
||||
button.boss_texture = boss_texture.widget
|
||||
|
||||
|
||||
s.texture = boss_texture
|
||||
s.button = button
|
||||
s.background = background
|
||||
|
||||
|
||||
button:SetScript("OnEnter", on_enter)
|
||||
button:SetScript("OnLeave", on_leave)
|
||||
|
||||
|
||||
s.HideMe = hide_label
|
||||
s.ShowMe = show_label
|
||||
|
||||
|
||||
tinsert(Details.switch.segments_blocks, s)
|
||||
return s
|
||||
end
|
||||
|
||||
|
||||
function Details.switch:GetSegmentBlock (index)
|
||||
local block = Details.switch.segments_blocks [index]
|
||||
if (not block) then
|
||||
@@ -572,38 +573,38 @@ function Details.switch:ShowMe(instancia)
|
||||
return block
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function Details.switch:ClearSegmentBlocks()
|
||||
for _, block in ipairs(Details.switch.segments_blocks) do
|
||||
block:HideMe()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function Details.switch:ResizeSegmentBlocks()
|
||||
|
||||
local x = 7
|
||||
local y = 5
|
||||
|
||||
|
||||
local window_width, window_height = Details.switch.current_instancia:GetSize()
|
||||
|
||||
|
||||
local horizontal_amt = floor(math.max(window_width / 100, 2))
|
||||
local vertical_amt = floor((window_height - y) / 20)
|
||||
local size = window_width / horizontal_amt
|
||||
|
||||
|
||||
local frame = Details.switch.frame
|
||||
|
||||
|
||||
Details.switch:ClearSegmentBlocks()
|
||||
|
||||
|
||||
local i = 1
|
||||
for vertical = 1, vertical_amt do
|
||||
x = 7
|
||||
for horizontal = 1, horizontal_amt do
|
||||
local button = Details.switch:GetSegmentBlock (i)
|
||||
|
||||
|
||||
button:SetPoint("topleft", frame, "topleft", x + 16, -y)
|
||||
button:SetSize(size - 22, 12)
|
||||
button:ShowMe()
|
||||
|
||||
|
||||
i = i + 1
|
||||
x = x + size
|
||||
if (i > 40) then
|
||||
@@ -613,37 +614,39 @@ function Details.switch:ShowMe(instancia)
|
||||
y = y + 20
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Details.switch.segments_blocks = {}
|
||||
|
||||
--current and overall
|
||||
Details.switch:CreateSegmentBlock()
|
||||
Details.switch:CreateSegmentBlock()
|
||||
|
||||
|
||||
local block1 = Details.switch:GetSegmentBlock (1)
|
||||
block1:SetText(Loc["STRING_CURRENTFIGHT"])
|
||||
block1.texture:SetTexture([[Interface\Scenarios\ScenariosParts]])
|
||||
block1.texture:SetTexCoord(55/512, 81/512, 368/512, 401/512)
|
||||
|
||||
|
||||
local block2 = Details.switch:GetSegmentBlock (2)
|
||||
block2:SetText(Loc["STRING_SEGMENT_OVERALL"])
|
||||
block2.texture:SetTexture([[Interface\Scenarios\ScenariosParts]])
|
||||
block2.texture:SetTexCoord(55/512, 81/512, 368/512, 401/512)
|
||||
end
|
||||
|
||||
|
||||
Details.switch:ClearSegmentBlocks()
|
||||
Details.switch:HideAllBookmarks()
|
||||
|
||||
local segment_index = 1
|
||||
for i = 3, #Details.tabela_historico.tabelas + 2 do
|
||||
|
||||
local combat = Details.tabela_historico.tabelas [segment_index]
|
||||
|
||||
local block = Details.switch:GetSegmentBlock (i)
|
||||
local enemy, color, raid_type, killed, is_trash, portrait, background, background_coords = Details:GetSegmentInfo (segment_index)
|
||||
|
||||
block:SetText("#" .. segment_index .. " " .. enemy)
|
||||
|
||||
local segmentsTable = Details:GetCombatSegments()
|
||||
|
||||
local segmentIndex = 1
|
||||
for i = 3, #segmentsTable + 2 do
|
||||
---@type combat
|
||||
local combat = segmentsTable[segmentIndex]
|
||||
|
||||
local block = Details.switch:GetSegmentBlock(i)
|
||||
local enemy, color, raid_type, killed, is_trash, portrait, background, background_coords = Details:GetSegmentInfo(segmentIndex)
|
||||
|
||||
block:SetText("#" .. segmentIndex .. " " .. enemy)
|
||||
|
||||
if (combat.is_boss and combat.instance_type == "raid") then
|
||||
local L, R, T, B, Texture = Details:GetBossIcon (combat.is_boss.mapid, combat.is_boss.index)
|
||||
if (L) then
|
||||
@@ -655,30 +658,30 @@ function Details.switch:ShowMe(instancia)
|
||||
else
|
||||
block.texture:SetTexture([[Interface\Scenarios\ScenarioIcon-Boss]])
|
||||
end
|
||||
|
||||
|
||||
block:ShowMe()
|
||||
segment_index = segment_index + 1
|
||||
segmentIndex = segmentIndex + 1
|
||||
end
|
||||
|
||||
|
||||
Details.switch.frame:SetScale(instancia.window_scale)
|
||||
Details.switch:ResizeSegmentBlocks()
|
||||
|
||||
for i = segment_index+2, #Details.switch.segments_blocks do
|
||||
|
||||
for i = segmentIndex+2, #Details.switch.segments_blocks do
|
||||
Details.switch.segments_blocks [i]:HideMe()
|
||||
end
|
||||
|
||||
|
||||
Details.switch.frame:SetPoint("topleft", instancia.baseframe, "topleft", 0, 1)
|
||||
Details.switch.frame:SetPoint("bottomright", instancia.baseframe, "bottomright", 0, 1)
|
||||
Details.switch.frame:Show()
|
||||
|
||||
|
||||
return
|
||||
|
||||
|
||||
else
|
||||
if (Details.switch.segments_blocks) then
|
||||
Details.switch:ClearSegmentBlocks()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--check if there is some custom contidional
|
||||
if (instancia.atributo == 5) then
|
||||
local custom_object = instancia:GetCustomObject()
|
||||
@@ -689,13 +692,13 @@ function Details.switch:ShowMe(instancia)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Details.switch.frame:SetPoint("topleft", instancia.baseframe, "topleft", 0, 1)
|
||||
Details.switch.frame:SetPoint("bottomright", instancia.baseframe, "bottomright", 0, 1)
|
||||
|
||||
local altura = instancia.baseframe:GetHeight()
|
||||
local mostrar_quantas = floor(altura / Details.switch.button_height) * 2
|
||||
|
||||
|
||||
local precisa_mostrar = 0
|
||||
for i = 1, #Details.switch.table do
|
||||
local slot = Details.switch.table [i]
|
||||
@@ -709,31 +712,31 @@ function Details.switch:ShowMe(instancia)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if (Details.switch.mostrar_quantas ~= mostrar_quantas) then
|
||||
|
||||
if (Details.switch.mostrar_quantas ~= mostrar_quantas) then
|
||||
for i = 1, #Details.switch.buttons do
|
||||
if (i <= mostrar_quantas) then
|
||||
if (i <= mostrar_quantas) then
|
||||
Details.switch.buttons [i]:Show()
|
||||
else
|
||||
Details.switch.buttons [i]:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if (#Details.switch.buttons < mostrar_quantas) then
|
||||
Details.switch.slots = mostrar_quantas
|
||||
end
|
||||
|
||||
|
||||
Details.switch.mostrar_quantas = mostrar_quantas
|
||||
end
|
||||
|
||||
|
||||
Details.switch:Resize (precisa_mostrar)
|
||||
Details.switch:Update()
|
||||
|
||||
|
||||
Details.switch.frame:SetScale(instancia.window_scale)
|
||||
Details.switch.frame:Show()
|
||||
|
||||
|
||||
Details.switch:Resize (precisa_mostrar)
|
||||
|
||||
|
||||
if (DetailsSwitchPanel.all_switch:IsShown()) then
|
||||
return DetailsSwitchPanel.all_switch:Hide()
|
||||
end
|
||||
@@ -927,7 +930,7 @@ function Details.switch:Update()
|
||||
for i = 1, slots_shown do
|
||||
--bookmark index
|
||||
local index = (offset * Details.switch.vertical_amt) + i
|
||||
|
||||
|
||||
--button
|
||||
local button = Details.switch.buttons [i]
|
||||
if (not button) then
|
||||
@@ -937,21 +940,21 @@ function Details.switch:Update()
|
||||
end
|
||||
|
||||
local options = Details.switch.table [index]
|
||||
if (not options and index <= 40) then
|
||||
if (not options and index <= 40) then
|
||||
options = {}
|
||||
Details.switch.table [index] = options
|
||||
end
|
||||
|
||||
|
||||
button.bookmark_number = index --button on icon
|
||||
button.button2.bookmark_number = index --button on text
|
||||
|
||||
|
||||
local icone
|
||||
local coords
|
||||
local name
|
||||
local vcolor
|
||||
local add
|
||||
local textColor = "white"
|
||||
|
||||
|
||||
if (options and options.sub_atributo) then
|
||||
if (options.atributo == 5) then --custom
|
||||
local CustomObject = Details.custom [options.sub_atributo]
|
||||
@@ -967,7 +970,7 @@ function Details.switch:Update()
|
||||
name = CustomObject.name
|
||||
vcolor = vertex_color_default
|
||||
end
|
||||
|
||||
|
||||
elseif (options.atributo == "plugin") then --plugin
|
||||
|
||||
local plugin = Details:GetPlugin (options.sub_atributo)
|
||||
|
||||
+3
-1
@@ -11,6 +11,7 @@ local addonName, Details222 = ...
|
||||
|
||||
--local helpers
|
||||
local getCombatObject = function(segmentNumber)
|
||||
---@type combat
|
||||
local combatObject
|
||||
|
||||
--select which segment to use, use low level variables for performance
|
||||
@@ -19,7 +20,8 @@ local getCombatObject = function(segmentNumber)
|
||||
elseif (segmentNumber == 0) then
|
||||
combatObject = Details.tabela_vigente
|
||||
else
|
||||
combatObject = Details.tabela_historico.tabelas [segmentNumber]
|
||||
local segmentsTable = Details:GetCombatSegments()
|
||||
combatObject = segmentsTable[segmentNumber]
|
||||
end
|
||||
|
||||
return combatObject
|
||||
|
||||
+32
-27
@@ -1,29 +1,29 @@
|
||||
local Details = _G.Details
|
||||
local DF = _G.DetailsFramework
|
||||
local detailsFramework = _G.DetailsFramework
|
||||
local C_Timer = _G.C_Timer
|
||||
local addonName, Details222 = ...
|
||||
local load = loadstring
|
||||
|
||||
--auto run scripts
|
||||
Details.AutoRunCode = {}
|
||||
local codeTable
|
||||
local functionCache = {}
|
||||
|
||||
--compile and store code
|
||||
function Details:RecompileAutoRunCode()
|
||||
for codeKey, code in pairs(codeTable) do
|
||||
local func, errorText = _G.loadstring(code)
|
||||
function Details222.AutoRunCode.RecompileAutoRunCode()
|
||||
for codeKey, code in pairs(Details222.AutoRunCode.CodeTable) do
|
||||
local func, errorText = load(code)
|
||||
if (func) then
|
||||
DetailsFramework:SetEnvironment(func)
|
||||
Details.AutoRunCode[codeKey] = func
|
||||
detailsFramework:SetEnvironment(func)
|
||||
functionCache[codeKey] = func
|
||||
else
|
||||
--if the code didn't pass, create a dummy function for it without triggering errors
|
||||
Details.AutoRunCode[codeKey] = function() end
|
||||
functionCache[codeKey] = function() end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--function to dispatch events
|
||||
function Details:DispatchAutoRunCode(codeKey)
|
||||
local func = Details.AutoRunCode[codeKey]
|
||||
function Details222.AutoRunCode.DispatchAutoRunCode(codeKey)
|
||||
local func = functionCache[codeKey]
|
||||
|
||||
if (type(func) ~= "function") then
|
||||
Details:Msg("error running function for auto run script", codeKey)
|
||||
@@ -39,15 +39,15 @@ function Details:DispatchAutoRunCode(codeKey)
|
||||
end
|
||||
|
||||
--auto run frame to dispatch scrtips for some events that details! doesn't handle
|
||||
local autoRunCodeEventFrame = _G.CreateFrame("frame")
|
||||
local autoRunCodeEventFrame = CreateFrame("frame")
|
||||
|
||||
if (not _G.DetailsFramework.IsTimewalkWoW()) then
|
||||
if (not detailsFramework.IsTimewalkWoW()) then
|
||||
autoRunCodeEventFrame:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED")
|
||||
end
|
||||
|
||||
autoRunCodeEventFrame.OnEventFunc = function(self, event)
|
||||
--ignore events triggered more than once in a small time window
|
||||
if (autoRunCodeEventFrame [event] and not autoRunCodeEventFrame [event]:IsCancelled()) then
|
||||
if (autoRunCodeEventFrame[event] and not autoRunCodeEventFrame[event]:IsCancelled()) then
|
||||
return
|
||||
end
|
||||
|
||||
@@ -55,13 +55,13 @@ autoRunCodeEventFrame.OnEventFunc = function(self, event)
|
||||
--create a trigger for the event, many times it is triggered more than once
|
||||
--so if the event is triggered a second time, it will be ignored
|
||||
local newTimer = C_Timer.NewTimer(1, function()
|
||||
Details:DispatchAutoRunCode("on_specchanged")
|
||||
|
||||
Details222.AutoRunCode.DispatchAutoRunCode("on_specchanged")
|
||||
|
||||
--clear and invalidate the timer
|
||||
autoRunCodeEventFrame[event]:Cancel()
|
||||
autoRunCodeEventFrame[event] = nil
|
||||
end)
|
||||
|
||||
|
||||
--store the trigger
|
||||
autoRunCodeEventFrame[event] = newTimer
|
||||
end
|
||||
@@ -71,21 +71,26 @@ autoRunCodeEventFrame:SetScript("OnEvent", autoRunCodeEventFrame.OnEventFunc)
|
||||
|
||||
--dispatch scripts at startup
|
||||
C_Timer.After(2, function()
|
||||
Details:DispatchAutoRunCode("on_init")
|
||||
Details:DispatchAutoRunCode("on_specchanged")
|
||||
Details:DispatchAutoRunCode("on_zonechanged")
|
||||
Details222.AutoRunCode.DispatchAutoRunCode("on_init")
|
||||
Details222.AutoRunCode.DispatchAutoRunCode("on_specchanged")
|
||||
Details222.AutoRunCode.DispatchAutoRunCode("on_zonechanged")
|
||||
|
||||
if (_G.InCombatLockdown()) then
|
||||
Details:DispatchAutoRunCode("on_entercombat")
|
||||
Details222.AutoRunCode.DispatchAutoRunCode("on_entercombat")
|
||||
else
|
||||
Details:DispatchAutoRunCode("on_leavecombat")
|
||||
Details222.AutoRunCode.DispatchAutoRunCode("on_leavecombat")
|
||||
end
|
||||
|
||||
Details:DispatchAutoRunCode("on_groupchange")
|
||||
Details222.AutoRunCode.DispatchAutoRunCode("on_groupchange")
|
||||
end)
|
||||
|
||||
function Details:StartAutoRun()
|
||||
--compile code
|
||||
codeTable = Details.run_code
|
||||
Details:RecompileAutoRunCode()
|
||||
function Details222.AutoRunCode.StartAutoRun()
|
||||
local newData = detailsFramework.table.copy({}, Details.run_code)
|
||||
Details.run_code = nil
|
||||
Details222.AutoRunCode.CodeTable = newData
|
||||
Details222.AutoRunCode.RecompileAutoRunCode()
|
||||
end
|
||||
|
||||
function Details222.AutoRunCode.OnLogout()
|
||||
Details.run_code = Details222.AutoRunCode.CodeTable
|
||||
end
|
||||
+67
-66
@@ -36,7 +36,7 @@ local create_deathrecap_line = function(parent, n)
|
||||
line:SetPoint("topright", parent, "topright", -10, (-24 * n) - 17)
|
||||
line:SetScript("OnEnter", on_deathrecap_line_enter)
|
||||
line:SetScript("OnLeave", on_deathrecap_line_leave)
|
||||
|
||||
|
||||
line:SetSize(300, 21)
|
||||
|
||||
local timeAt = line:CreateFontString(nil, "overlay", "GameFontNormal")
|
||||
@@ -50,14 +50,14 @@ local create_deathrecap_line = function(parent, n)
|
||||
local amount = line:CreateFontString(nil, "overlay", "GameFontNormal")
|
||||
local lifePercent = line:CreateFontString(nil, "overlay", "GameFontNormal")
|
||||
local lifeStatusBar = line:CreateTexture(nil, "border", nil, -3)
|
||||
|
||||
|
||||
--grave icon
|
||||
local graveIcon = line:CreateTexture(nil, "overlay")
|
||||
graveIcon:SetTexture([[Interface\MINIMAP\POIIcons]])
|
||||
graveIcon:SetTexCoord(146/256, 160/256, 0/512, 18/512)
|
||||
graveIcon:SetPoint("left", line, "left", 11, 0)
|
||||
graveIcon:SetSize(14, 18)
|
||||
|
||||
|
||||
--spell icon
|
||||
spellIcon:SetSize(19, 19)
|
||||
spellIconBorder:SetTexture([[Interface\ENCOUNTERJOURNAL\LootTab]])
|
||||
@@ -71,12 +71,12 @@ local create_deathrecap_line = function(parent, n)
|
||||
sourceName:SetPoint("left", line, "left", 82, 0)
|
||||
amount:SetPoint("left", line, "left", 240, 0)
|
||||
lifePercent:SetPoint("left", line, "left", 320, 0)
|
||||
|
||||
|
||||
--text colors
|
||||
Details.gump:SetFontColor(amount, "red")
|
||||
Details.gump:SetFontColor(timeAt, "gray")
|
||||
Details.gump:SetFontColor(sourceName, "yellow")
|
||||
|
||||
|
||||
Details.gump:SetFontSize(sourceName, 10)
|
||||
|
||||
--text alpha
|
||||
@@ -84,13 +84,13 @@ local create_deathrecap_line = function(parent, n)
|
||||
sourceName:SetAlpha(textAlpha)
|
||||
amount:SetAlpha(textAlpha)
|
||||
lifePercent:SetAlpha(textAlpha)
|
||||
|
||||
|
||||
--text setup
|
||||
amount:SetWidth(85)
|
||||
amount:SetJustifyH("right")
|
||||
lifePercent:SetWidth(42)
|
||||
lifePercent:SetJustifyH("right")
|
||||
|
||||
|
||||
--life statusbar
|
||||
lifeStatusBar:SetPoint("topleft", line, "topleft")
|
||||
lifeStatusBar:SetPoint("bottomleft", line, "bottomleft")
|
||||
@@ -99,7 +99,7 @@ local create_deathrecap_line = function(parent, n)
|
||||
backgroundTexture:SetTexture([[Interface\AddOns\Details\images\deathrecap_background]])
|
||||
backgroundTexture:SetTexCoord(0, 1, 0, 1)
|
||||
backgroundTexture:SetVertexColor(.1, .1, .1, .3)
|
||||
|
||||
|
||||
--top border
|
||||
local TopFader = line:CreateTexture(nil, "border")
|
||||
TopFader:SetTexture([[Interface\AddOns\Details\images\deathrecap_background_top]])
|
||||
@@ -110,13 +110,13 @@ local create_deathrecap_line = function(parent, n)
|
||||
TopFader:SetHeight(32)
|
||||
TopFader:Hide()
|
||||
line.TopFader = TopFader
|
||||
|
||||
|
||||
if (n == 10) then
|
||||
--bottom fader
|
||||
local backgroundTexture2 = line:CreateTexture(nil, "border")
|
||||
backgroundTexture2:SetTexture([[Interface\AddOns\Details\images\deathrecap_background_bottom]])
|
||||
backgroundTexture2:SetTexCoord(0, 1, 0, 1)
|
||||
backgroundTexture2:SetVertexColor(.1, .1, .1, .3)
|
||||
backgroundTexture2:SetVertexColor(.1, .1, .1, .3)
|
||||
backgroundTexture2:SetPoint("topleft", backgroundTexture, "bottomleft", 0, 0)
|
||||
backgroundTexture2:SetPoint("topright", backgroundTexture, "bottomright", 0, 0)
|
||||
backgroundTexture2:SetHeight(32)
|
||||
@@ -125,7 +125,7 @@ local create_deathrecap_line = function(parent, n)
|
||||
Details.gump:SetFontSize(lifePercent, 14)
|
||||
backgroundTexture:SetVertexColor(.2, .1, .1, .3)
|
||||
end
|
||||
|
||||
|
||||
backgroundTexture:SetPoint("topleft", 0, 1)
|
||||
backgroundTexture:SetPoint("bottomright", 0, -1)
|
||||
backgroundTexture:SetDesaturated(true)
|
||||
@@ -135,7 +135,7 @@ local create_deathrecap_line = function(parent, n)
|
||||
backgroundTextureOverlay:SetDesaturated(true)
|
||||
backgroundTextureOverlay:SetAlpha(0.5)
|
||||
backgroundTextureOverlay:Hide()
|
||||
|
||||
|
||||
line.timeAt = timeAt
|
||||
line.spellIcon = spellIcon
|
||||
line.sourceName = sourceName
|
||||
@@ -145,14 +145,14 @@ local create_deathrecap_line = function(parent, n)
|
||||
line.backgroundTextureOverlay = backgroundTextureOverlay
|
||||
line.graveIcon = graveIcon
|
||||
line.lifeStatusBar = lifeStatusBar
|
||||
|
||||
|
||||
if (n == 10) then
|
||||
graveIcon:Show()
|
||||
line.timeAt:Hide()
|
||||
else
|
||||
graveIcon:Hide()
|
||||
end
|
||||
|
||||
|
||||
return line
|
||||
end
|
||||
|
||||
@@ -162,13 +162,13 @@ end
|
||||
|
||||
function Details.BuildDeathTableFromRecap (recapID)
|
||||
local events = DeathRecap_GetEvents (recapID)
|
||||
|
||||
|
||||
--check if it is a valid recap
|
||||
if (not events or #events <= 0) then
|
||||
DeathRecapFrame.Unavailable:Show()
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
--build an death log using details format
|
||||
ArtificialDeathLog = {
|
||||
{}, --deathlog events
|
||||
@@ -200,11 +200,11 @@ function Details.BuildDeathTableFromRecap (recapID)
|
||||
evtData.overkill,
|
||||
not spellId and {spellId, spellName, texture},
|
||||
}
|
||||
|
||||
|
||||
tinsert(ArtificialDeathLog[1], ev)
|
||||
ArtificialDeathLog.n = ArtificialDeathLog.n + 1
|
||||
end
|
||||
|
||||
|
||||
return ArtificialDeathLog
|
||||
end
|
||||
|
||||
@@ -226,7 +226,7 @@ function Details.GetDeathRecapFromChat()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if (recapIDFromChat) then
|
||||
Details.OpenDetailsDeathRecap (nil, recapIDFromChat, true)
|
||||
return
|
||||
@@ -258,29 +258,29 @@ function Details.OpenDetailsDeathRecap (segment, RecapID, fromChat)
|
||||
if (not Details.DeathRecap) then
|
||||
Details.DeathRecap = CreateFrame("frame", "DetailsDeathRecap", DeathRecapFrame, "BackdropTemplate")
|
||||
Details.DeathRecap:SetAllPoints()
|
||||
|
||||
|
||||
DeathRecapFrame.Title:SetText(DeathRecapFrame.Title:GetText() .. " (by Details!)")
|
||||
|
||||
|
||||
--lines
|
||||
Details.DeathRecap.Lines = {}
|
||||
for i = 1, 10 do
|
||||
Details.DeathRecap.Lines [i] = create_deathrecap_line (Details.DeathRecap, i)
|
||||
end
|
||||
|
||||
|
||||
--segments
|
||||
Details.DeathRecap.Segments = {}
|
||||
for i = 5, 1, -1 do
|
||||
local segmentButton = CreateFrame("button", "DetailsDeathRecapSegmentButton" .. i, Details.DeathRecap, "BackdropTemplate")
|
||||
|
||||
|
||||
segmentButton:SetSize(16, 20)
|
||||
segmentButton:SetPoint("topright", DeathRecapFrame, "topright", (-abs(i-6) * 22) - 10, -5)
|
||||
|
||||
|
||||
local text = segmentButton:CreateFontString(nil, "overlay", "GameFontNormal")
|
||||
segmentButton.text = text
|
||||
text:SetText("#" .. i)
|
||||
text:SetPoint("center")
|
||||
Details.gump:SetFontColor(text, "silver")
|
||||
|
||||
|
||||
segmentButton:SetScript("OnClick", function()
|
||||
OpenDetailsDeathRecapAtSegment (i)
|
||||
end)
|
||||
@@ -306,9 +306,9 @@ function Details.OpenDetailsDeathRecap (segment, RecapID, fromChat)
|
||||
|
||||
--in case a combat has been created after the player death, the death won't be at the current segment
|
||||
if (not foundPlayer) then
|
||||
local segmentHistory = Details:GetCombatSegments()
|
||||
local segmentsTable = Details:GetCombatSegments()
|
||||
for i = 1, 2 do
|
||||
local segment = segmentHistory [1]
|
||||
local segment = segmentsTable [1]
|
||||
if (segment and segment ~= Details.tabela_vigente) then
|
||||
if (Details.tabela_vigente.start_time - 3 < segment.end_time) then
|
||||
death = segment.last_events_tables
|
||||
@@ -321,34 +321,35 @@ function Details.OpenDetailsDeathRecap (segment, RecapID, fromChat)
|
||||
if (Details.death_recap.show_segments) then
|
||||
local last_index = 0
|
||||
local buttonsInUse = {}
|
||||
local segmentsTable = Details:GetCombatSegments()
|
||||
|
||||
for i, button in ipairs(Details.DeathRecap.Segments) do
|
||||
if (Details.tabela_historico.tabelas [i]) then
|
||||
if (segmentsTable[i]) then
|
||||
button:Show()
|
||||
tinsert(buttonsInUse, button)
|
||||
table.insert(buttonsInUse, button)
|
||||
Details.gump:SetFontColor(button.text, "silver")
|
||||
last_index = i
|
||||
else
|
||||
button:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local buttonsInUse2 = {}
|
||||
for i = #buttonsInUse, 1, -1 do
|
||||
tinsert(buttonsInUse2, buttonsInUse[i])
|
||||
table.insert(buttonsInUse2, buttonsInUse[i])
|
||||
end
|
||||
for i = 1, #buttonsInUse2 do
|
||||
local button = buttonsInUse2 [i]
|
||||
button:ClearAllPoints()
|
||||
button:SetPoint("topright", DeathRecapFrame, "topright", (-i * 22) - 10, -5)
|
||||
end
|
||||
|
||||
|
||||
if (not segment) then
|
||||
Details.gump:SetFontColor(Details.DeathRecap.Segments [1].text, "orange")
|
||||
else
|
||||
Details.gump:SetFontColor(Details.DeathRecap.Segments [segment].text, "orange")
|
||||
death = Details.tabela_historico.tabelas [segment] and Details.tabela_historico.tabelas [segment].last_events_tables
|
||||
death = segmentsTable[segment] and segmentsTable[segment].last_events_tables
|
||||
end
|
||||
|
||||
else
|
||||
for i, button in ipairs(Details.DeathRecap.Segments) do
|
||||
button:Hide()
|
||||
@@ -368,9 +369,9 @@ function Details.OpenDetailsDeathRecap (segment, RecapID, fromChat)
|
||||
--get the death events from the blizzard's recap
|
||||
ArtificialDeathLog = Details.BuildDeathTableFromRecap (RecapID)
|
||||
end
|
||||
|
||||
|
||||
DeathRecapFrame.Unavailable:Hide()
|
||||
|
||||
|
||||
--get the relevance config
|
||||
local relevanceTime = Details.death_recap.relevance_time
|
||||
|
||||
@@ -389,12 +390,12 @@ function Details.OpenDetailsDeathRecap (segment, RecapID, fromChat)
|
||||
if (t) then
|
||||
local events = t [1]
|
||||
local timeOfDeath = t [2]
|
||||
|
||||
|
||||
local BiggestDamageHits = {}
|
||||
for i = #events, 1, -1 do
|
||||
tinsert(BiggestDamageHits, events [i])
|
||||
end
|
||||
table.sort (BiggestDamageHits, function(t1, t2)
|
||||
table.sort (BiggestDamageHits, function(t1, t2)
|
||||
return t1[3] > t2[3]
|
||||
end)
|
||||
for i = #BiggestDamageHits, 1, -1 do
|
||||
@@ -402,7 +403,7 @@ function Details.OpenDetailsDeathRecap (segment, RecapID, fromChat)
|
||||
tremove(BiggestDamageHits, i)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--check if the event which killed the player is in the list, or addit to BiggestDamageHits
|
||||
local hitKill
|
||||
for i = #events, 1, -1 do
|
||||
@@ -449,7 +450,7 @@ function Details.OpenDetailsDeathRecap (segment, RecapID, fromChat)
|
||||
end
|
||||
else
|
||||
--cut table to show only 10 events
|
||||
while (#BiggestDamageHits > 10) do
|
||||
while (#BiggestDamageHits > 10) do
|
||||
tremove(BiggestDamageHits, 11)
|
||||
end
|
||||
end
|
||||
@@ -459,21 +460,21 @@ function Details.OpenDetailsDeathRecap (segment, RecapID, fromChat)
|
||||
Details.GetDeathRecapFromChat()
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
table.sort (BiggestDamageHits, function(t1, t2)
|
||||
table.sort (BiggestDamageHits, function(t1, t2)
|
||||
return t1[4] > t2[4]
|
||||
end)
|
||||
|
||||
local events = BiggestDamageHits
|
||||
|
||||
|
||||
local maxHP = t [5]
|
||||
local lineIndex = 10
|
||||
|
||||
|
||||
--for i = #events, 1, -1 do
|
||||
for i, event in ipairs(events) do
|
||||
for i, event in ipairs(events) do
|
||||
local event = events [i]
|
||||
|
||||
|
||||
local evType = event [1]
|
||||
local hp = min (floor(event [5] / maxHP * 100), 100)
|
||||
local spellName, _, spellIcon = Details.GetSpellInfo(event [2])
|
||||
@@ -481,11 +482,11 @@ function Details.OpenDetailsDeathRecap (segment, RecapID, fromChat)
|
||||
local eventTime = event [4]
|
||||
local source = event [6]
|
||||
local overkill = event [10] or 0
|
||||
|
||||
|
||||
local customSpellInfo = event [11]
|
||||
|
||||
|
||||
if (type(evType) == "boolean" and evType) then
|
||||
|
||||
|
||||
local line = Details.DeathRecap.Lines [lineIndex]
|
||||
if (line) then
|
||||
line.timeAt:SetText(format("%.1f", eventTime - timeOfDeath) .. "s")
|
||||
@@ -493,11 +494,11 @@ function Details.OpenDetailsDeathRecap (segment, RecapID, fromChat)
|
||||
line.TopFader:Hide()
|
||||
--line.spellIcon:SetTexCoord(.1, .9, .1, .9)
|
||||
--line.sourceName:SetText("|cFFC6B0D9" .. source .. "|r")
|
||||
|
||||
|
||||
--parse source and cut the length of the string after setting the spellname and source
|
||||
local sourceClass = Details:GetClass(source)
|
||||
local sourceSpec = Details:GetSpec(source)
|
||||
|
||||
|
||||
if (not sourceClass) then
|
||||
local combat = Details:GetCurrentCombat()
|
||||
if (combat) then
|
||||
@@ -507,7 +508,7 @@ function Details.OpenDetailsDeathRecap (segment, RecapID, fromChat)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if (not sourceSpec) then
|
||||
local combat = Details:GetCurrentCombat()
|
||||
if (combat) then
|
||||
@@ -517,19 +518,19 @@ function Details.OpenDetailsDeathRecap (segment, RecapID, fromChat)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--remove real name or owner name
|
||||
source = Details:GetOnlyName(source)
|
||||
--remove owner name
|
||||
source = source:gsub((" <.*"), "")
|
||||
|
||||
|
||||
--if a player?
|
||||
if (Details.player_class [sourceClass]) then
|
||||
source = Details:AddClassOrSpecIcon (source, sourceClass, sourceSpec, 16, true)
|
||||
|
||||
|
||||
elseif (sourceClass == "PET") then
|
||||
source = Details:AddClassOrSpecIcon (source, sourceClass)
|
||||
|
||||
|
||||
end
|
||||
|
||||
--remove the dot signal from the spell name
|
||||
@@ -545,14 +546,14 @@ function Details.OpenDetailsDeathRecap (segment, RecapID, fromChat)
|
||||
--/run for a,b in pairs(_G) do if (type(b)=="string" and b:find("Falling")) then print(a,b) end end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
spellName = spellName:gsub(L["STRING_DOT"], "")
|
||||
spellName = spellName:gsub("[*] ", "")
|
||||
source = source or ""
|
||||
|
||||
|
||||
line.sourceName:SetText(spellName .. " (" .. "|cFFC6B0D9" .. source .. "|r" .. ")")
|
||||
DetailsFramework:TruncateText (line.sourceName, 185)
|
||||
|
||||
|
||||
if (amount > 1000) then
|
||||
--line.amount:SetText("-" .. Details:ToK (amount))
|
||||
line.amount:SetText("-" .. Details:comma_value(floor(amount)))
|
||||
@@ -560,14 +561,14 @@ function Details.OpenDetailsDeathRecap (segment, RecapID, fromChat)
|
||||
--line.amount:SetText("-" .. floor(amount))
|
||||
line.amount:SetText("-" .. floor(amount))
|
||||
end
|
||||
|
||||
|
||||
line.lifePercent:SetText(hp .. "%")
|
||||
line.lifeStatusBar:SetWidth(line:GetWidth() * (hp/100))
|
||||
|
||||
line.spellid = event [2]
|
||||
|
||||
|
||||
line:Show()
|
||||
|
||||
|
||||
if (Details.death_recap.show_life_percent) then
|
||||
line.lifePercent:Show()
|
||||
line.amount:SetPoint("left", line, "left", 240, 0)
|
||||
@@ -578,16 +579,16 @@ function Details.OpenDetailsDeathRecap (segment, RecapID, fromChat)
|
||||
--line.lifePercent:SetPoint("left", line, "left", 320, 0)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
lineIndex = lineIndex - 1
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local lastLine = Details.DeathRecap.Lines [lineIndex + 1]
|
||||
if (lastLine) then
|
||||
lastLine.TopFader:Show()
|
||||
end
|
||||
|
||||
|
||||
DeathRecapFrame.Unavailable:Hide()
|
||||
else
|
||||
if (not fromChat) then
|
||||
@@ -674,7 +675,7 @@ end)
|
||||
--[=[ hooks not loaded at this point
|
||||
Details:InstallHook(DETAILS_HOOK_DEATH, function(_, _, _, _, _, _, _, targetName)
|
||||
if (targetName == UnitName("player")) then
|
||||
|
||||
|
||||
end
|
||||
end)
|
||||
--]=]
|
||||
|
||||
@@ -105,6 +105,7 @@ end
|
||||
|
||||
--load previous saved combat data
|
||||
function Details222.LoadSavedVariables.CombatSegments()
|
||||
--this is the table where the character data is saved as well the combat data
|
||||
local currentCharacterData = _G["_detalhes_database"] --no need to check if it exists, it's already checked
|
||||
if (currentCharacterData == nil) then
|
||||
currentCharacterData = {}
|
||||
@@ -189,7 +190,7 @@ function Details222.LoadSavedVariables.CombatSegments()
|
||||
end
|
||||
|
||||
--get the first segment saved and use it as current segment
|
||||
Details.tabela_vigente = Details.tabela_historico.tabelas[1]
|
||||
Details.tabela_vigente = Details.tabela_historico.tabelas[1] --only low level access to this table allowed
|
||||
|
||||
--need refresh for all containers
|
||||
for _, actorContainer in ipairs(Details.tabela_overall) do
|
||||
|
||||
+22
-22
@@ -64,7 +64,7 @@ function DetailsMythicPlusFrame.MergeSegmentsOnEnd()
|
||||
|
||||
--get the current combat just created and the table with all past segments
|
||||
local newCombat = Details:GetCurrentCombat()
|
||||
local segmentHistory = Details:GetCombatSegments()
|
||||
local segmentsTable = Details:GetCombatSegments()
|
||||
|
||||
local totalTime = 0
|
||||
local startDate, endDate = "", ""
|
||||
@@ -73,14 +73,14 @@ function DetailsMythicPlusFrame.MergeSegmentsOnEnd()
|
||||
|
||||
if (Details.mythic_plus.reverse_death_log) then
|
||||
for i = 1, 40 do --copy the deaths from the first segment to the last one
|
||||
local thisCombat = segmentHistory[i]
|
||||
local thisCombat = segmentsTable[i]
|
||||
if (thisCombat and thisCombat.is_mythic_dungeon_run_id == Details.mythic_dungeon_id) then
|
||||
newCombat:CopyDeathsFrom(thisCombat, true)
|
||||
end
|
||||
end
|
||||
else
|
||||
for i = 40, 1, -1 do --copy the deaths from the last segment to the new segment
|
||||
local thisCombat = segmentHistory[i]
|
||||
local thisCombat = segmentsTable[i]
|
||||
if (thisCombat) then
|
||||
if (thisCombat.is_mythic_dungeon_run_id == Details.mythic_dungeon_id) then
|
||||
newCombat:CopyDeathsFrom(thisCombat, true)
|
||||
@@ -91,7 +91,7 @@ function DetailsMythicPlusFrame.MergeSegmentsOnEnd()
|
||||
|
||||
--add all boss segments from this run to this new segment
|
||||
for i = 1, 40 do --from the newer combat to the oldest
|
||||
local thisCombat = segmentHistory[i]
|
||||
local thisCombat = segmentsTable[i]
|
||||
if (thisCombat and thisCombat.is_mythic_dungeon_run_id == Details.mythic_dungeon_id) then
|
||||
local canAddThisSegment = true
|
||||
if (Details.mythic_plus.make_overall_boss_only) then
|
||||
@@ -255,11 +255,11 @@ function DetailsMythicPlusFrame.MergeTrashCleanup (isFromSchedule)
|
||||
end
|
||||
|
||||
--delete all segments that were merged
|
||||
local segmentHistory = Details:GetCombatSegments()
|
||||
for segmentId = #segmentHistory, 1, -1 do
|
||||
local segment = segmentHistory[segmentId]
|
||||
local segmentsTable = Details:GetCombatSegments()
|
||||
for segmentId = #segmentsTable, 1, -1 do
|
||||
local segment = segmentsTable[segmentId]
|
||||
if (segment and segment._trashoverallalreadyadded) then
|
||||
tremove(segmentHistory, segmentId)
|
||||
tremove(segmentsTable, segmentId)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -342,16 +342,16 @@ function DetailsMythicPlusFrame.MergeRemainingTrashAfterAllBossesDone()
|
||||
|
||||
--remove trash segments from the segment history after the merge
|
||||
local removedCurrentSegment = false
|
||||
local segmentHistory = Details:GetCombatSegments()
|
||||
local segmentsTable = Details:GetCombatSegments()
|
||||
for _, pastCombat in ipairs(segmentsToMerge) do
|
||||
for i = #segmentHistory, 1, -1 do
|
||||
local segment = segmentHistory [i]
|
||||
for i = #segmentsTable, 1, -1 do
|
||||
local segment = segmentsTable [i]
|
||||
if (segment == pastCombat) then
|
||||
--remove the segment
|
||||
if (Details.tabela_vigente == segment) then
|
||||
removedCurrentSegment = true
|
||||
end
|
||||
tremove(segmentHistory, i)
|
||||
tremove(segmentsTable, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
@@ -363,8 +363,8 @@ function DetailsMythicPlusFrame.MergeRemainingTrashAfterAllBossesDone()
|
||||
|
||||
if (removedCurrentSegment) then
|
||||
--find another current segment
|
||||
local segmentHistory = Details:GetCombatSegments()
|
||||
Details.tabela_vigente = segmentHistory [1]
|
||||
local segmentsTable = Details:GetCombatSegments()
|
||||
Details.tabela_vigente = segmentsTable [1]
|
||||
|
||||
if (not Details.tabela_vigente) then
|
||||
--assuming there's no segment from the dungeon run
|
||||
@@ -425,11 +425,11 @@ function DetailsMythicPlusFrame.BossDefeated(this_is_end_end, encounterID, encou
|
||||
local segmentsToMerge = DetailsMythicPlusFrame.TrashMergeScheduled or {}
|
||||
|
||||
--table with all past semgnets
|
||||
local segmentHistory = Details:GetCombatSegments()
|
||||
local segmentsTable = Details:GetCombatSegments()
|
||||
|
||||
--iterate among segments
|
||||
for i = 1, 25 do --from the newer combat to the oldest
|
||||
local pastCombat = segmentHistory [i]
|
||||
local pastCombat = segmentsTable [i]
|
||||
--does the combat exists
|
||||
if (pastCombat and not pastCombat._trashoverallalreadyadded and pastCombat.is_mythic_dungeon_trash) then
|
||||
--is the combat a mythic segment from this run?
|
||||
@@ -522,10 +522,10 @@ function DetailsMythicPlusFrame.MythicDungeonFinished (fromZoneLeft)
|
||||
end
|
||||
|
||||
--table with all past semgnets
|
||||
local segmentHistory = Details:GetCombatSegments()
|
||||
local segmentsTable = Details:GetCombatSegments()
|
||||
|
||||
for i = 1, #segmentHistory do
|
||||
local pastCombat = segmentHistory [i]
|
||||
for i = 1, #segmentsTable do
|
||||
local pastCombat = segmentsTable [i]
|
||||
--does the combat exists
|
||||
|
||||
if (pastCombat and not pastCombat._trashoverallalreadyadded and pastCombat:GetCombatTime() > 5) then
|
||||
@@ -562,10 +562,10 @@ function DetailsMythicPlusFrame.MythicDungeonFinished (fromZoneLeft)
|
||||
end
|
||||
|
||||
--find the latest trash overall
|
||||
local segmentHistory = Details:GetCombatSegments()
|
||||
local segmentsTable = Details:GetCombatSegments()
|
||||
local latestTrashOverall
|
||||
for i = 1, #segmentHistory do
|
||||
local pastCombat = segmentHistory [i]
|
||||
for i = 1, #segmentsTable do
|
||||
local pastCombat = segmentsTable [i]
|
||||
if (pastCombat and pastCombat.is_mythic_dungeon and pastCombat.is_mythic_dungeon.SegmentID == "trashoverall") then
|
||||
latestTrashOverall = pastCombat
|
||||
break
|
||||
|
||||
+2
-1
@@ -273,7 +273,8 @@ function SlashCmdList.DETAILS (msg, editbox)
|
||||
local segmentId = rest and tonumber(rest)
|
||||
if (segmentId and segmentId ~= 1) then
|
||||
local segmentToErase = tonumber(segmentId)
|
||||
local combatObject = tremove(Details.tabela_historico.tabelas, segmentToErase)
|
||||
local combatObject = table.remove(Details:GetCombatSegments(), segmentToErase)
|
||||
|
||||
if (combatObject) then
|
||||
Details:DestroyCombat(combatObject)
|
||||
Details:SendEvent("DETAILS_DATA_SEGMENTREMOVED")
|
||||
|
||||
@@ -2562,8 +2562,8 @@ end
|
||||
function PhaseFrame:UpdateSegmentCompareBars (phase)
|
||||
--segmento atual (numero)
|
||||
local segmentNumber = EncounterDetails._segment
|
||||
local segmentTable = PhaseFrame.CurrentSegment
|
||||
local bossID = segmentTable:GetBossInfo() and segmentTable:GetBossInfo().id
|
||||
local segmentsTable = PhaseFrame.CurrentSegment
|
||||
local bossID = segmentsTable:GetBossInfo() and segmentsTable:GetBossInfo().id
|
||||
|
||||
local index = 1
|
||||
for i, segment in ipairs (_detalhes:GetCombatSegments()) do
|
||||
@@ -2573,7 +2573,7 @@ function PhaseFrame:UpdateSegmentCompareBars (phase)
|
||||
local timers = PhaseFrame:GetPhaseTimers (segment)
|
||||
|
||||
if (timers [phase]) then
|
||||
if (segment ~= segmentTable) then
|
||||
if (segment ~= segmentsTable) then
|
||||
bar.name:SetText ("Segment " .. i .. ":")
|
||||
_detalhes.gump:SetFontColor (bar.name, "orange")
|
||||
bar.done:SetText (_detalhes.gump:IntegerToTimer (timers [phase]))
|
||||
|
||||
Reference in New Issue
Block a user