From c9a1096adeaf32d01fc6d46c018031f6caff1b74 Mon Sep 17 00:00:00 2001 From: Tercio Jose Date: Wed, 4 Dec 2024 16:21:23 -0300 Subject: [PATCH] Release: Framework, OpenRaid updates + changes from the last 2 weeks. --- Details.toc | 4 +- Details_Cata.toc | 4 +- Libs/DF/buildmenu.lua | 63 ++ Libs/DF/cooltip.lua | 26 +- Libs/DF/definitions.lua | 11 +- Libs/DF/dropdown.lua | 86 ++- Libs/DF/fw.lua | 31 +- Libs/DF/timebar.lua | 45 +- Libs/DF/timeline.lua | 628 +++++++++++------- Libs/LibOpenRaid/GetPlayerInformation.lua | 106 ++- Libs/LibOpenRaid/LibOpenRaid.lua | 334 ++++------ .../LibOpenRaid/ThingsToMantain_WarWithin.lua | 7 +- Libs/LibOpenRaid/docs.txt | 38 +- boot.lua | 6 +- frames/window_scrolldamage.lua | 21 +- luaserver.lua | 5 +- 16 files changed, 848 insertions(+), 567 deletions(-) diff --git a/Details.toc b/Details.toc index 5ebf01ddb..106b216ac 100644 --- a/Details.toc +++ b/Details.toc @@ -1,5 +1,5 @@ ## Interface: 110005 -## Interface-Cata: 40400 +## Interface-Cata: 40401 ## Title: Details! Damage Meter ## Notes: Essential tool to impress that chick in your raid. ## Notes-ruRU: Незаменимый инструмент, чтобы произвести впечатление на цыпочку в вашем рейде. @@ -10,7 +10,7 @@ ## IconTexture: Interface\AddOns\Details\images\minimap ## X-Curse-Project-ID: 61284 -## X-Wago-ID: 25NRDlK3 +## X-Wago-ID: qv63A7Gb #@no-lib-strip@ Libs\libs.xml diff --git a/Details_Cata.toc b/Details_Cata.toc index 94552b8fc..9f8adc6db 100644 --- a/Details_Cata.toc +++ b/Details_Cata.toc @@ -1,4 +1,4 @@ -## Interface: 40400 +## Interface: 40401 ## Title: Details! Damage Meter ## Notes: Essential tool to impress that chick in your raid. ## Notes-ruRU: Незаменимый инструмент, чтобы произвести впечатление на цыпочку в вашем рейде. @@ -9,7 +9,7 @@ ## IconTexture: Interface\AddOns\Details\images\minimap ## X-Curse-Project-ID: 61284 -## X-Wago-ID: 25NRDlK3 +## X-Wago-ID: qv63A7Gb #@no-lib-strip@ Libs\libs.xml diff --git a/Libs/DF/buildmenu.lua b/Libs/DF/buildmenu.lua index 93f7a5a8a..248dc12cd 100644 --- a/Libs/DF/buildmenu.lua +++ b/Libs/DF/buildmenu.lua @@ -654,6 +654,36 @@ local setExecuteProperties = function(parent, widget, widgetTable, currentXOffse return maxColumnWidth, maxWidgetWidth, latestInlineWidget end +local setImageProperties = function(parent, widget, widgetTable, currentXOffset, currentYOffset) + --.texture .width .height .filterType .texcoord + if (type(widgetTable.texture) == "table") then + local r, g, b, a = detailsFramework:ParseColors(widgetTable.texture) + widget:SetColorTexture(r, g, b, a) + else + widget:SetTexture(widgetTable.texture, "CLAMP", "CLAMP", widgetTable.filterType) + end + + widget:SetSize(widgetTable.width, widgetTable.height) + + local left, right, top, bottom = 0, 1, 0, 1 + if (widgetTable.texcoord) then + left, right, top, bottom = unpack(widgetTable.texcoord) + end + widget:SetTexCoord(left, right, top, bottom) + + if (widgetTable.vertexcolor) then + local r, g, b, a = detailsFramework:ParseColors(widgetTable.vertexcolor) + widget:SetVertexColor(r, g, b, a) + else + widget:SetVertexColor(1, 1, 1, 1) + end + + setWidgetId(parent, widgetTable, widget) + + widget:ClearAllPoints() + widget:SetPoint("topleft", parent, "topleft", currentXOffset, currentYOffset) +end + local setTextEntryProperties = function(parent, widget, widgetTable, currentXOffset, currentYOffset, template, widgetWidth, widgetHeight, bAlignAsPairs, nAlignAsPairsLength, valueChangeHook, maxColumnWidth, maxWidgetWidth, textTemplate, latestInlineWidget) widget._get = widgetTable.get widget.text = widgetTable.get() @@ -889,6 +919,7 @@ function detailsFramework:SetAsOptionsPanel(frame) ["button"] = {}, -- "execute" ["textentry"] = {}, -- ["label"] = {}, --"text" + ["image"] = {}, } frame.widgetids = {} frame.GetWidgetById = getFrameById @@ -997,6 +1028,15 @@ local getMenuWidgetVolative = function(parent, widgetType, indexTable) widgetObject:ClearHooks() end indexTable[widgetType] = indexTable[widgetType] + 1 + + elseif (widgetType == "image") then + widgetObject = parent.widget_list_by_type[widgetType][indexTable[widgetType]] + if (not widgetObject) then + widgetObject = parent:CreateTexture("$parentWidget" .. widgetType .. indexTable[widgetType], "overlay") + table.insert(parent.widget_list, widgetObject) + table.insert(parent.widget_list_by_type[widgetType], widgetObject) + end + indexTable[widgetType] = indexTable[widgetType] + 1 end --if the widget is inside the no combat table, remove it @@ -1251,6 +1291,15 @@ function detailsFramework:BuildMenuVolatile(parent, menuOptions, xOffset, yOffse maxColumnWidth, maxWidgetWidth = setTextEntryProperties(parent, textentry, widgetTable, currentXOffset, currentYOffset, buttonTemplate, widgetWidth, widgetHeight, bAlignAsPairs, nAlignAsPairsLength, valueChangeHook, maxColumnWidth, maxWidgetWidth, textTemplate) amountLineWidgetAdded = amountLineWidgetAdded + 1 + + --image + elseif (widgetTable.type == "image") then + local image = getMenuWidgetVolative(parent, "image", widgetIndexes) + widgetCreated = image + + setImageProperties(parent, image, widgetTable, currentXOffset, currentYOffset) + + amountLineWidgetAdded = amountLineWidgetAdded + 1 end --end loop if (widgetTable.nocombat) then @@ -1565,6 +1614,20 @@ function detailsFramework:BuildMenu(parent, menuOptions, xOffset, yOffset, heigh widgetCreated = textentry amountLineWidgetAdded = amountLineWidgetAdded + 1 + + elseif (widgetTable.type == "image") then + local image = parent:CreateTexture("$parentMenuImage" .. index, "overlay") + + setImageProperties(parent, image, widgetTable, currentXOffset, currentYOffset) + + currentYOffset = currentYOffset - widgetTable.height + 10 + + --store the widget created into the overall table and the widget by type + table.insert(parent.widget_list, image) + table.insert(parent.widget_list_by_type.textentry, image) + + widgetCreated = image + amountLineWidgetAdded = amountLineWidgetAdded + 1 end if (widgetTable.nocombat) then diff --git a/Libs/DF/cooltip.lua b/Libs/DF/cooltip.lua index 2e38a47ab..046ff69f8 100644 --- a/Libs/DF/cooltip.lua +++ b/Libs/DF/cooltip.lua @@ -28,7 +28,7 @@ end --api locals local PixelUtil = PixelUtil or DFPixelUtil -local version = 28 +local version = 29 local CONST_MENU_TYPE_MAINMENU = "main" local CONST_MENU_TYPE_SUBMENU = "sub" @@ -1053,6 +1053,16 @@ function DF:CreateCoolTip() if (gameCooltip.OptionsTable.TextSize and not leftTextSettings[6]) then DF:SetFontSize(menuButton.leftText, gameCooltip.OptionsTable.TextSize) + elseif (leftTextSettings[6]) then + DF:SetFontSize(menuButton.leftText, leftTextSettings[6]) + else + DF:SetFontSize(menuButton.leftText, 10) + end + + if (leftTextSettings[8]) then + DF:SetFontOutline(menuButton.leftText, leftTextSettings[8]) + else + DF:SetFontOutline(menuButton.leftText, "NONE") end if (gameCooltip.OptionsTable.LeftTextWidth) then @@ -1160,6 +1170,20 @@ function DF:CreateCoolTip() DF:SetFontSize(menuButton.rightText, gameCooltip.OptionsTable.TextSize) end + if (gameCooltip.OptionsTable.TextSize and not rightTextSettings[6]) then + DF:SetFontSize(menuButton.rightText, gameCooltip.OptionsTable.TextSize) + elseif (rightTextSettings[6]) then + DF:SetFontSize(menuButton.rightText, rightTextSettings[6]) + else + DF:SetFontSize(menuButton.rightText, 10) + end + + if (rightTextSettings[8]) then + DF:SetFontOutline(menuButton.rightText, rightTextSettings[8]) + else + DF:SetFontOutline(menuButton.rightText, "NONE") + end + if (gameCooltip.OptionsTable.RightTextWidth) then menuButton.rightText:SetWidth(gameCooltip.OptionsTable.RightTextWidth) else diff --git a/Libs/DF/definitions.lua b/Libs/DF/definitions.lua index 3f1a3dcc2..0980edc8c 100644 --- a/Libs/DF/definitions.lua +++ b/Libs/DF/definitions.lua @@ -61,6 +61,9 @@ ---@field Color any? ---@field Texture any +GameCooltipFrame1 = {} +GameCooltipFrame2 = {} + ---df version of an atlasinfo from the game API, it include color and desaturation information ---a df atlas can be created using DetailsFramework:CreateAtlas() and then used with DetailsFramework:SetAtlas() ---@class df_atlasinfo : atlasinfo @@ -142,6 +145,9 @@ ---@field RoundedCornerPanelMixin df_roundedcornermixin ---@field Schedules df_schedule ---@field HeaderFunctions df_headerfunctions +---@field TimeLine_LineMixin df_timeline_line_mixin +---@field TimeLineMixin df_timeline_mixin +---@field NameplateBorderMixin df_nameplate_border_mixin ---@field RoleTypes roleinfo[] ---@field Language df_language ---@field Ejc df_ejc @@ -199,7 +205,7 @@ ---@field IsDragonflightWow fun():boolean ---@field IsWarWow fun():boolean ---@field IsTWWWow fun():boolean ----@field CreateFullBorder fun(self:table, name:string, parent:frame) : frame +---@field CreateFullBorder fun(self:table, name:string, parent:frame) : border_frame ---@field CreateButton fun(self:table, parent:frame, func:function, width:number, height:number, text:any, param1:any, param2:any, texture:atlasname|texturepath|textureid|nil, member:string?, name:string?, shortMethod:any, buttonTemplate:table?, textTemplate:table?) : df_button callback function(blizzButton, clickType, param1, param2) end ---@field CreateCloseButton fun(self:table, parent:frame, frameName:string?) : df_closebutton ---@field CreateTabButton fun(self:table, parent:frame, frameName:string?) : df_tabbutton @@ -268,9 +274,10 @@ ---@field CreateSimplePanel fun(self:table, parent:frame, width:number?, height:number?, title:string?, frameName:string?, panelOptions:table?, savedVariableTable:table?) : simplepanel ---@field CreateNewAddOn fun(self:table, addonName:string, globalSavedVariablesName:string, savedVarsTemplate:table) : table ---@field CreateBossScrollSelectorForInstance fun(self:table, instanceId:any, parent:uiobject, name:string?, options:df_bossscrollselector_options?, callback:function?, ...) : df_bossscrollselector ----@field CreateTimeLineFrame fun(self:table, parent:frame, name:string, timelineOptions:df_timeline_options, elapsedtimeOptions:df_elapsedtime_options) : df_timeline +---@field CreateTimeLineFrame fun(self:table, parent:frame, name:string, timelineOptions:df_timeline_options, elapsedtimeOptions:df_elapsedtime_options) : df_timeline, df_timeline_header?, df_timeline_header_body? create a timeline frame, header and headerBody is nil if the timelineOptions has no header_detached set to true ---@field CreateTitleBar fun(self:table, parent:frame, titleText:string) : df_titlebar ---@field CreateElapsedTimeFrame fun(self:table, parent:frame, name:string?, options:df_elapsedtime_options?) : df_elapsedtime +---@field CreateIconRow fun(self:table, parent:frame, name:string?, options:table?) : df_iconrow ---@field ConvertAnchorPointToInside fun(self:table, anchorPoint:anchorid) : anchorid ---@field ExpansionHasAugEvoker fun():boolean ---@field LoadSpellCache fun(self:table, hashMap:table, indexTable:table, allSpellsSameName:table) : hashMap:table, indexTable:table, allSpellsSameName:table load all spells in the game and add them into the passed tables diff --git a/Libs/DF/dropdown.lua b/Libs/DF/dropdown.lua index 2cb158232..211187b88 100644 --- a/Libs/DF/dropdown.lua +++ b/Libs/DF/dropdown.lua @@ -11,6 +11,41 @@ ]=] +---@class df_dropdown : table, frame, df_widgets +---@field func function +---@field SetTemplate fun(self:df_dropdown, template:table|string) +---@field SetFixedParameter fun(self:df_dropdown, value:any) is sent as 2nd argument to the callback function, the value is the same no matter which option is selected +---@field BuildDropDownFontList fun(self:df_dropdown, onClick:function, icon:any, iconTexcoord:table?, iconSize:table?):table make a dropdown list with all fonts available, on select a font, call the function onClick +---@field SetFunction fun(self:df_dropdown, func:function) +---@field SetEmptyTextAndIcon fun(self:df_dropdown, text:string, icon:any) +---@field Select fun(self:df_dropdown, optionName:string|number, byOptionNumber:boolean?, bOnlyShown:boolean?, runCallback:boolean?):boolean +---@field SelectDelayed fun(self:df_dropdown, optionName:string|number, byOptionNumber:boolean?, bOnlyShown:boolean?, runCallback:boolean?) --call Select() after a random delay +---@field Open fun(self:df_dropdown) +---@field Close fun(self:df_dropdown) +---@field Refresh fun(self:df_dropdown) +---@field GetValue fun(self:df_dropdown):any +---@field GetFunction fun(self:df_dropdown):function +---@field GetMenuSize fun(self:df_dropdown):number, number +---@field SetMenuSize fun(self:df_dropdown, width:number, height:number) +---@field Disable fun(self:df_dropdown) +---@field Enable fun(self:df_dropdown) + +---@class dropdownoption : table +---@field value any +---@field label string text shown in the dropdown option +---@field onclick fun(dropdownObject:table, fixedValue:any, value:any)? function to call when the option is selected +---@field icon string|number? texture +---@field color any any color format +---@field font string? +---@field texcoord number[]? left, right, top, bottom +---@field iconcolor any any color format +---@field iconsize number[]? width, height +---@field languageId string? +---@field rightbutton function? function to call on right click +---@field statusbar string|number? statusbar texture +---@field statusbarcolor any any color format +---@field rightTexture string|number? texture +---@field centerTexture string|number? texture ---@type detailsframework local DF = _G ["DetailsFramework"] @@ -393,6 +428,12 @@ local canRunCallbackFunctionForOption = function(canRunCallback, optionTable, dr end end +function DropDownMetaFunctions:SelectDelayed(optionName, byOptionNumber, bOnlyShown, runCallback) + DF.Schedules.After(DF.Math.RandomFraction(0.016, 0.3), function() + self:Select(optionName, byOptionNumber, bOnlyShown, runCallback) + end) +end + ---if bOnlyShown is true it'll first create a table with visible options that has .shown and then select in this table the index passed (if byOptionNumber) ---@param optionName string value or string shown in the name of the option ---@param byOptionNumber number the option name is considered a number and selects the index of the menu @@ -522,10 +563,20 @@ function DropDownMetaFunctions:Selected(thisOption) end end + ---@type fontstring + local thisLabel = self.label + + local parentWidth = self:GetWidth() + if (addonId and phraseId) then self.label:SetText(DF.Language.GetText(addonId, phraseId)) else - self.label:SetText(thisOption.label) + thisLabel:SetText(thisOption.label) + thisLabel:SetWordWrap(false) + thisLabel:SetIndentedWordWrap(false) + thisLabel:SetWidth(parentWidth + 30) + DF:TruncateText(thisLabel, parentWidth-30) + thisLabel:Show() end self.icon:SetTexture(thisOption.icon) @@ -702,22 +753,6 @@ function DetailsFrameworkDropDownOptionOnLeave(frame) frame:GetParent().mouseover:Hide() end ----@class dropdownoption : table ----@field value any ----@field label string text shown in the dropdown option ----@field onclick fun(dropdownObject:table, fixedValue:any, value:any)? function to call when the option is selected ----@field icon string|number? texture ----@field color any any color format ----@field font string? ----@field texcoord number[]? left, right, top, bottom ----@field iconcolor any any color format ----@field iconsize number[]? width, height ----@field languageId string? ----@field rightbutton function? function to call on right click ----@field statusbar string|number? statusbar texture ----@field statusbarcolor any any color format ----@field rightTexture string|number? texture ----@field centerTexture string|number? texture --@button is the raw button frame, object is the button capsule --click on the main dropdown frame (not the menu options popup) @@ -1145,23 +1180,6 @@ end ------------------------------------------------------------------------------------------------------------ --object constructor ----@class df_dropdown : table, frame, df_widgets ----@field func function ----@field SetTemplate fun(self:df_dropdown, template:table|string) ----@field SetFixedParameter fun(self:df_dropdown, value:any) is sent as 2nd argument to the callback function, the value is the same no matter which option is selected ----@field BuildDropDownFontList fun(self:df_dropdown, onClick:function, icon:any, iconTexcoord:table?, iconSize:table?):table make a dropdown list with all fonts available, on select a font, call the function onClick ----@field SetFunction fun(self:df_dropdown, func:function) ----@field SetEmptyTextAndIcon fun(self:df_dropdown, text:string, icon:any) ----@field Select fun(self:df_dropdown, optionName:string|number, byOptionNumber:boolean?, bOnlyShown:boolean?, runCallback:boolean?):boolean ----@field Open fun(self:df_dropdown) ----@field Close fun(self:df_dropdown) ----@field Refresh fun(self:df_dropdown) ----@field GetValue fun(self:df_dropdown):any ----@field GetFunction fun(self:df_dropdown):function ----@field GetMenuSize fun(self:df_dropdown):number, number ----@field SetMenuSize fun(self:df_dropdown, width:number, height:number) ----@field Disable fun(self:df_dropdown) ----@field Enable fun(self:df_dropdown) ---return a function which when called returns a table filled with all fonts available and ready to be used on dropdowns ---@param callback function diff --git a/Libs/DF/fw.lua b/Libs/DF/fw.lua index 5973c39a4..f2859f7f4 100644 --- a/Libs/DF/fw.lua +++ b/Libs/DF/fw.lua @@ -1,6 +1,6 @@ -local dversion = 582 +local dversion = 585 local major, minor = "DetailsFramework-1.0", dversion local DF, oldminor = LibStub:NewLibrary(major, minor) @@ -4289,7 +4289,24 @@ function DF:CreateBorder(parent, alpha1, alpha2, alpha3) end --DFNamePlateBorder as copy from "NameplateFullBorderTemplate" -> DF:CreateFullBorder (name, parent) -local DFNamePlateBorderTemplateMixin = {}; +---@class df_nameplate_border_mixin : table +---@field SetVertexColor fun(self:border_frame, r:number, g:number, b:number, a:number) +---@field GetVertexColor fun(self:border_frame):number, number, number r, g, b +---@field SetBorderSizes fun(self:border_frame, borderSize:number, borderSizeMinPixels:number, upwardExtendHeightPixels:number, upwardExtendHeightMinPixels:number) +---@field UpdateSizes fun(self:border_frame) +---@field Left texture +---@field Right texture +---@field Bottom texture +---@field Top texture +---@field Textures texture[] +---@field borderSize number +---@field borderSizeMinPixels number +---@field upwardExtendHeightPixels number +---@field upwardExtendHeightMinPixels number + +local DFNamePlateBorderTemplateMixin = {} + +DF.NameplateBorderMixin = DFNamePlateBorderTemplateMixin function DFNamePlateBorderTemplateMixin:SetVertexColor(r, g, b, a) for i, texture in ipairs(self.Textures) do @@ -4336,7 +4353,9 @@ function DFNamePlateBorderTemplateMixin:UpdateSizes() end end -function DF:CreateFullBorder (name, parent) +---@class border_frame : frame, df_nameplate_border_mixin + +function DF:CreateFullBorder(name, parent) local border = CreateFrame("Frame", name, parent) border:SetAllPoints() border:SetIgnoreParentScale(true) @@ -5559,8 +5578,10 @@ DF.DebugMixin = { end, CheckStack = function(self) - local stack = debugstack() - Details:Dump (stack) + if (Details) then + local stack = debugstack() + Details:Dump (stack) + end end, } diff --git a/Libs/DF/timebar.lua b/Libs/DF/timebar.lua index d99ffb6f5..5ca8cb211 100644 --- a/Libs/DF/timebar.lua +++ b/Libs/DF/timebar.lua @@ -31,7 +31,7 @@ local GetTime = GetTime ---@field SetColor fun(self:df_timebar, color:any, green:number|nil, blue:number|nil, alpha:number|nil) ---@field SetLeftText fun(self:df_timebar, text:string) ---@field SetRightText fun(self:df_timebar, text:string) ----@field SetFont fun(self:df_timebar, font:string|nil, size:number|nil, color:any, shadow:boolean|nil) +---@field SetFont fun(self:df_timebar, font:string|nil, size:number|nil, color:any, outline:string|boolean|nil, shadowColor:any, shadowX:number?, shadowY:number?) ---@field SetThrottle fun(self:df_timebar, seconds:number) ---@field SetDirection fun(self:df_timebar, direction:string) ---@field SetBackgroundColor fun(self:df_timebar, color:any, green:number|nil, blue:number|nil, alpha:number|nil) @@ -185,6 +185,7 @@ end function TimeBarMetaFunctions:SetIcon(texture, L, R, T, B) if (texture) then self.statusBar.icon:Show() + self.statusBar.icon:ClearAllPoints() self.statusBar.icon:SetPoint("left", self.statusBar, "left", 2, 0) self.statusBar.icon:SetSize(self.statusBar:GetHeight()-2, self.statusBar:GetHeight()-2) self.statusBar.leftText:ClearAllPoints() @@ -221,21 +222,35 @@ function TimeBarMetaFunctions:SetRightText(text) self.statusBar.rightText:SetText(text) end -function TimeBarMetaFunctions:SetFont(font, size, color, shadow) +function TimeBarMetaFunctions:SetFont(font, size, color, outline, shadowColor, shadowX, shadowY) if (font) then detailsFramework:SetFontFace(self.statusBar.leftText, font) + detailsFramework:SetFontFace(self.statusBar.rightText, font) end if (size) then detailsFramework:SetFontSize(self.statusBar.leftText, size) + detailsFramework:SetFontSize(self.statusBar.rightText, size) end if (color) then detailsFramework:SetFontColor(self.statusBar.leftText, color) + detailsFramework:SetFontColor(self.statusBar.rightText, color) end - if (shadow) then - detailsFramework:SetFontOutline(self.statusBar.leftText, shadow) + if (outline) then + detailsFramework:SetFontOutline(self.statusBar.leftText, outline) + detailsFramework:SetFontOutline(self.statusBar.rightText, outline) + end + + if (shadowColor) then + self.statusBar.leftText:SetShadowColor(detailsFramework:ParseColors(shadowColor)) + self.statusBar.rightText:SetShadowColor(detailsFramework:ParseColors(shadowColor)) + end + + if (shadowX and shadowY) then + self.statusBar.leftText:SetShadowOffset(shadowX, shadowY) + self.statusBar.rightText:SetShadowOffset(shadowX, shadowY) end end @@ -341,17 +356,21 @@ local OnUpdateFunc = function(self, deltaTime) local startTime, endTime = self:GetMinMaxValues() if (not self.dontShowSpark) then - if (self.direction == "right") then - if (endTime - startTime > 0) then - local pct = abs((timeNow - endTime) / (endTime - startTime)) + if (endTime - startTime > 0) then + local pct = abs((timeNow - endTime) / (endTime - startTime)) + pct = abs(1 - pct) + local sparkOffset = -16 + + if (self.direction ~= "right") then + --moving from right to left, so invert the pct pct = abs(1 - pct) - spark:SetPoint("left", self, "left", (self:GetWidth() * pct) - 16, 0) - spark:Show() - else - spark:Hide() + sparkOffset = -14 end + + spark:SetPoint("left", self, "left", (self:GetWidth() * pct) + sparkOffset, 0) + spark:Show() else - spark:SetPoint("right", self, "right", self:GetWidth() * (timeNow/self.endTime), 0) + spark:Hide() end end @@ -413,7 +432,7 @@ function TimeBarMetaFunctions:SetTimer(currentTime, startTime, endTime) self.statusBar.spark:Hide() else self.statusBar.spark:Show() - self.statusBar.spark:SetHeight(self.statusBar:GetHeight()+20) + self.statusBar.spark:SetHeight(self.statusBar:GetHeight()+26) if (self.statusBar.sparkAlpha) then self.statusBar.spark:SetAlpha(self.statusBar.sparkAlpha) diff --git a/Libs/DF/timeline.lua b/Libs/DF/timeline.lua index bcdd58942..fb414021d 100644 --- a/Libs/DF/timeline.lua +++ b/Libs/DF/timeline.lua @@ -7,43 +7,12 @@ end local _ --lua locals -local rawset = rawset --lua local -local rawget = rawget --lua local -local setmetatable = setmetatable --lua local 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 --- TWW compatibility: -local Enum = _G.Enum -local C_SpellBook = _G.C_SpellBook - - -local GetSpellInfo = GetSpellInfo or function(spellID) if not spellID then return nil end local si = C_Spell.GetSpellInfo(spellID) if si then return si.name, nil, si.iconID, si.castTime, si.minRange, si.maxRange, si.spellID, si.originalIconID end end -local GetNumSpellTabs = GetNumSpellTabs or C_SpellBook.GetNumSpellBookSkillLines -local GetSpellTabInfo = GetSpellTabInfo or function(tabLine) local skillLine = C_SpellBook.GetSpellBookSkillLineInfo(tabLine) if skillLine then return skillLine.name, skillLine.iconID, skillLine.itemIndexOffset, skillLine.numSpellBookItems, skillLine.isGuild, skillLine.offSpecID end end -local SPELLBOOK_BANK_PLAYER = Enum.SpellBookSpellBank and Enum.SpellBookSpellBank.Player or "player" -local SpellBookItemTypeMap = Enum.SpellBookItemType and {[Enum.SpellBookItemType.Spell] = "SPELL", [Enum.SpellBookItemType.None] = "NONE", [Enum.SpellBookItemType.Flyout] = "FLYOUT", [Enum.SpellBookItemType.FutureSpell] = "FUTURESPELL", [Enum.SpellBookItemType.PetAction] = "PETACTION" } or {} -local GetSpellBookItemInfo = GetSpellBookItemInfo or function(...) local si = C_SpellBook.GetSpellBookItemInfo(...) if si then return SpellBookItemTypeMap[si.itemType] or "NONE", (si.itemType == Enum.SpellBookItemType.Flyout or si.itemType == Enum.SpellBookItemType.PetAction) and si.actionID or si.spellID or si.actionID, si end end -local GetSpellBookItemTexture = GetSpellBookItemTexture or function(...) return C_SpellBook.GetSpellBookItemTexture(...) end -local GetSpellTexture = GetSpellTexture or function(...) return C_Spell.GetSpellTexture(...) end - -local IS_WOW_PROJECT_MAINLINE = WOW_PROJECT_ID == WOW_PROJECT_MAINLINE -local IS_WOW_PROJECT_NOT_MAINLINE = WOW_PROJECT_ID ~= WOW_PROJECT_MAINLINE -local IS_WOW_PROJECT_CLASSIC_ERA = WOW_PROJECT_ID == WOW_PROJECT_CLASSIC - -local CastInfo = detailsFramework.CastInfo - local PixelUtil = PixelUtil or DFPixelUtil -local UnitGroupRolesAssigned = detailsFramework.UnitGroupRolesAssigned - -local cleanfunction = function() end -local APIFrameFunctions - - ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ --horizontal scroll frame @@ -60,6 +29,7 @@ local APIFrameFunctions ---@field pixels_per_second number ---@field scale_min number ---@field scale_max number +---@field zoom_out_zero boolean if true, when the scale is reduced by mouse wheel, it will be set to 0 ---@field use_perpixel_buttons boolean ---@field backdrop backdrop ---@field backdrop_color number[] @@ -70,11 +40,14 @@ local APIFrameFunctions ---@field slider_backdrop_border_color number[] ---@field title_template string "ORANGE_FONT_TEMPLATE" ---@field text_tempate string "OPTIONS_FONT_TEMPLATE" ----@field on_enter fun(self:frame) --line ----@field on_leave fun(self:frame) --line +---@field on_enter fun(self:df_timeline_line) --line +---@field on_leave fun(self:df_timeline_line) --line +---@field on_create_line fun(self:df_timeline_line) --line +---@field on_refresh_line fun(self:df_timeline_line) --line ---@field block_on_enter fun(self:button) ---@field block_on_leave fun(self:button) ---@field block_on_click fun(self:button) +---@field block_on_create fun(self:df_timeline_line_block) ---@field block_on_set_data fun(self:button, data:table) ---@field block_on_enter_auralength fun(self:df_timeline_line_block) ---@field block_on_leave_auralength fun(self:df_timeline_line_block) @@ -98,6 +71,7 @@ local timeline_options = { scale_min = 0.15, scale_max = 1, + zoom_out_zero = false, backdrop = {edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true}, backdrop_color = {0, 0, 0, 0.2}, @@ -111,6 +85,7 @@ local timeline_options = { title_template = "ORANGE_FONT_TEMPLATE", text_tempate = "OPTIONS_FONT_TEMPLATE", + ---@param self df_timeline_line on_enter = function(self) self:SetBackdropColor(unpack(self.backdrop_color_highlight)) end, @@ -142,6 +117,13 @@ local timeline_options = { ---@field customIcon any ---@field customName any ---@field isIconRow boolean? +---@field showRightIcon boolean? +---@field blockLengthHeight number? --need to remove +---@field blockLengthYOffset number? --need to remove +---@field auraLengthColor any +---@field auraLengthTexture any +---@field auraHeight number? +---@field auraYOffset number? ---@class df_timeline_linedata : table ---@field spellId number @@ -149,6 +131,9 @@ local timeline_options = { ---@field coords number[]? ---@field text string? ---@field timeline df_timeline_block_data[] +---@field lineHeight number? +---@field disabled boolean? +---@field type string|number? helper to identify the line, defined by user ---@class df_timeline_scrolldata : table ---@field length number @@ -164,37 +149,68 @@ local timeline_options = { ---@field customIcon any ---@field customName any ----@class df_timeline_line_block : frame +---@class df_timeline_line_block : button ---@field icon texture ---@field text fontstring ---@field background texture ----@field auraLength frame +---@field blockLength df_timeline_line_blocklength ---@field info df_timeline_line_blockinfo +---@field timeline df_timeline +---@field backgroundBorder border_frame + +---@class df_timeline_line_blocklength : button +---@field isMoving boolean +---@field Texture texture +---@field RightIcon texture +---@field block df_timeline_line_block +---@field timeline df_timeline + +---@param auraLengthFrame df_timeline_line_blocklength +local registerForDrag = function(auraLengthFrame) + auraLengthFrame:SetMovable(true) + auraLengthFrame:SetScript("OnMouseDown", function() + do return end + auraLengthFrame.isMoving = true + auraLengthFrame:StartMoving() + auraLengthFrame:ClearAllPoints() + + auraLengthFrame:SetScript("OnUpdate", function() + --get the timeline + local timeline = auraLengthFrame.timeline + local blockUnderMouse = timeline:GetBlockUnderMouse() + if (blockUnderMouse) then + print("underblock") + else + print("no block under mouse") + end + end) + end) + + auraLengthFrame:SetScript("OnMouseUp", function() + do return end + auraLengthFrame:StopMovingOrSizing() + auraLengthFrame.isMoving = false + auraLengthFrame:SetScript("OnUpdate", nil) + --set the original point + --auraLengthFrame:ClearAllPoints() + --auraLengthFrame:SetPoint("topleft", cooldownSelectorScroll, "topleft", auraLengthFrame.originalXPoint, auraLengthFrame.originalYPoint) + end) +end ---@class df_timeline_line_mixin : frame ---@field lineHeader frame ---@field blocks df_timeline_line_block[] ----@field SetBlock fun(self:df_timeline_line, index:number, blockInfo:table) +---@field CreateBlock fun(self:df_timeline_line, index:number):df_timeline_line_block ---@field GetBlock fun(self:df_timeline_line, index:number):df_timeline_line_block ---@field SetBlocksFromData fun(self:df_timeline_line) +---@field GetAllBlocks fun(self:df_timeline_line):df_timeline_line_block[] +---@field CreateBlockLength fun(block:df_timeline_line_block):df_timeline_line_blocklength +---@field OnEnterBlockLength fun(self:df_timeline_line_block) +---@field OnLeaveBlockLength fun(self:df_timeline_line_block) ---@field Reset fun(self:df_timeline_line) detailsFramework.TimeLine_LineMixin = { - --self is the line - SetBlock = function(self, index, blockInfo) - --get the block information - --see what is the current scale - --adjust the block position - - local block = self:GetBlock(index) - - --need: - --the total time of the timeline - --the current scale of the timeline - --the elapsed time of this block - --icon of the block - --text - --background color - + GetAllBlocks = function(self) + return self.blocks end, SetBlocksFromData = function(self) @@ -217,6 +233,22 @@ detailsFramework.TimeLine_LineMixin = { --lineData store members: .text .icon .timeline ---@type df_timeline_linedata local lineData = data.lines[self.dataIndex] + self.lineData = lineData + + local mouseEnabled = not lineData.disabled + self.lineHeader:EnableMouse(mouseEnabled) + self:EnableMouse(mouseEnabled) + self:SetMouseClickEnabled(mouseEnabled) + self:SetPropagateMouseClicks(true) + self.enabled = mouseEnabled + + if (lineData.lineHeight) then + self:SetHeight(lineData.lineHeight) + self.lineHeader:SetHeight(lineData.lineHeight) + else + self:SetHeight(timeline.options.line_height) + self.lineHeader:SetHeight(timeline.options.line_height) + end self.spellId = lineData.spellId @@ -268,8 +300,8 @@ detailsFramework.TimeLine_LineMixin = { local customName = blockInfo.customName local inRow = blockInfo.isIconRow local showRightIcon = blockInfo.showRightIcon - local auraHeight = blockInfo.auraHeight - local auraYOffset = blockInfo.auraYOffset + local blockLengthHeight = blockInfo.blockLengthHeight or blockInfo.auraHeight + local blockLengthYOffset = blockInfo.blockLengthYOffset or blockInfo.auraYOffset local xOffset = pixelPerSecond * timeInSeconds local width = pixelPerSecond * length @@ -308,7 +340,8 @@ detailsFramework.TimeLine_LineMixin = { if (customIcon) then iconTexture = customIcon elseif (blockSpellId) then - iconTexture = GetSpellTexture(blockSpellId) + local spellInfo = C_Spell.GetSpellInfo(blockSpellId) + iconTexture = spellInfo.iconID end block.icon:SetTexture(iconTexture) @@ -325,43 +358,52 @@ detailsFramework.TimeLine_LineMixin = { PixelUtil.SetSize(block, self:GetHeight(), self:GetHeight()) if (isAura) then - block.auraLength:Show() + block.blockLength:Show() local thisAuraDuration = auraDuration if (timeInSeconds + thisAuraDuration > timeline.data.length) then thisAuraDuration = timeline.data.length - timeInSeconds end - if (blockInfo.auraLengthColor) then - local r, g, b = unpack(blockInfo.auraLengthColor) - block.auraLength.Texture:SetVertexColor(r, g, b, 0.5) + local blockLengthTexture = blockInfo.auraLengthTexture + if (blockLengthTexture) then + block.blockLength.Texture:SetTexture(blockLengthTexture, true) + block.blockLength.Texture:SetHorizTile(true) + else + block.blockLength.Texture:SetColorTexture(1, 1, 1, 1) + end + + local auraLengthColor = blockInfo.auraLengthColor + if (auraLengthColor) then + local r, g, b, a = detailsFramework:ParseColors(auraLengthColor) + block.blockLength.Texture:SetVertexColor(r, g, b, a or 0.5) else - block.auraLength.Texture:SetVertexColor(1, 1, 1, 0.5) + block.blockLength.Texture:SetVertexColor(1, 1, 1, 0.5) end - block.auraLength.Texture:Show() + block.blockLength.Texture:Show() - block.auraLength:SetWidth(pixelPerSecond * thisAuraDuration) - block.auraLength:SetHeight(auraHeight and auraHeight or block:GetHeight()) + block.blockLength:SetWidth(pixelPerSecond * thisAuraDuration) + block.blockLength:SetHeight(blockLengthHeight and blockLengthHeight or block:GetHeight()) if (showRightIcon) then - block.auraLength.RightIcon:SetTexture(iconTexture) - block.auraLength.RightIcon:SetTexCoord(.1, .9, .1, .9) - block.auraLength.RightIcon:SetWidth(block.auraLength:GetHeight()) - block.auraLength.RightIcon:Show() + block.blockLength.RightIcon:SetTexture(iconTexture) + block.blockLength.RightIcon:SetTexCoord(.1, .9, .1, .9) + block.blockLength.RightIcon:SetWidth(block.blockLength:GetHeight()) + block.blockLength.RightIcon:Show() else - block.auraLength.RightIcon:SetTexture(nil) - block.auraLength.RightIcon:Hide() + block.blockLength.RightIcon:SetTexture(nil) + block.blockLength.RightIcon:Hide() end if (inRow) then - block.auraLength:SetPoint("bottomleft", rowStartBlock or block.icon, "bottomleft", 0, auraYOffset) + block.blockLength:SetPoint("bottomleft", rowStartBlock or block.icon, "bottomleft", 0, blockLengthYOffset) else - block.auraLength:SetPoint("bottomleft", block.icon, "bottomleft", 0, auraYOffset) + block.blockLength:SetPoint("bottomleft", block.icon, "bottomleft", 0, blockLengthYOffset) end --block:SetWidth(max(pixelPerSecond * auraDuration, 16)) else - block.auraLength:Hide() + block.blockLength:Hide() end block.background:SetVertexColor(0, 0, 0, 0) @@ -369,7 +411,7 @@ detailsFramework.TimeLine_LineMixin = { block.icon:SetTexture("") block.background:SetVertexColor(0, 0, 0, 0) PixelUtil.SetSize(block, max(width, 16), self:GetHeight()) - block.auraLength:Hide() + block.blockLength:Hide() end if (timeline.options.block_on_set_data) then @@ -383,90 +425,109 @@ detailsFramework.TimeLine_LineMixin = { end end, - OnEnterAuraLength = function(self) - ---@type df_timeline - local timeline = self.timeline - if (timeline.options.block_on_enter_auralength) then - timeline.options.block_on_enter_auralength(self) + GetBlock = function(self, index) + local block = self.blocks[index] + if (not block) then --CreateBlock + block = self:CreateBlock(index) end + return block end, - OnLeaveAuraLength = function(self) - ---@type df_timeline - local timeline = self.timeline - if (timeline.options.block_on_enter_auralength) then - timeline.options.block_on_leave_auralength(self) + CreateBlock = function(self, index) + ---@type df_timeline_line_block + local block = CreateFrame("button", nil, self, "BackdropTemplate") + block:SetMouseClickEnabled(false) + self.blocks[index] = block + + local background = block:CreateTexture(nil, "background") + background:SetColorTexture(1, 1, 1, 1) + local icon = block:CreateTexture(nil, "artwork") + local text = block:CreateFontString(nil, "artwork", "GameFontNormal") + + detailsFramework.TimeLine_LineMixin.CreateBlockLength(block) + + local backgroundBorder = detailsFramework:CreateFullBorder("$parentBorder", block) + local iconOffset = UIParent:GetEffectiveScale() * -1 + PixelUtil.SetPoint(backgroundBorder, "topleft", block, "topleft", -iconOffset, iconOffset) + PixelUtil.SetPoint(backgroundBorder, "topright", block, "topright", iconOffset, iconOffset) + PixelUtil.SetPoint(backgroundBorder, "bottomleft", block, "bottomleft", -iconOffset, -iconOffset) + PixelUtil.SetPoint(backgroundBorder, "bottomright", block, "bottomright", iconOffset, -iconOffset) + + backgroundBorder:SetVertexColor(0, 0, 0, 1) --need to create a class for border frame + + background:SetAllPoints() + icon:SetPoint("center", block, "center", 0, 0) + text:SetPoint("left", icon, "right", 2, 0) + detailsFramework:SetFontOutline(text, "OUTLINE") + + block.icon = icon + block.text = text + block.background = background + block.backgroundBorder = backgroundBorder + + ---@type df_timeline_options + local timelineOptions = self:GetParent():GetParent().options + + block:SetScript("OnEnter", timelineOptions.block_on_enter) + block:SetScript("OnLeave", timelineOptions.block_on_leave) + + block:SetMouseClickEnabled(false) + ---@diagnostic disable-next-line: missing-fields + block.info = {} + + if (timelineOptions.block_on_create) then + timelineOptions.block_on_create(block) end + + return block end, - CreateAuraLength = function(block) - local auraLengthFrame = CreateFrame("frame", nil, block) - auraLengthFrame:SetFrameLevel(block:GetFrameLevel() - 1) - auraLengthFrame:SetScript("OnEnter", detailsFramework.TimeLine_LineMixin.OnEnterAuraLength) - auraLengthFrame:SetScript("OnLeave", detailsFramework.TimeLine_LineMixin.OnLeaveAuraLength) + CreateBlockLength = function(block) + ---@type df_timeline_line_blocklength + local blockLengthFrame = CreateFrame("button", nil, block) + blockLengthFrame:SetFrameLevel(block:GetFrameLevel() - 1) + blockLengthFrame:SetScript("OnEnter", detailsFramework.TimeLine_LineMixin.OnEnterBlockLength) + blockLengthFrame:SetScript("OnLeave", detailsFramework.TimeLine_LineMixin.OnLeaveBlockLength) --save reference of the block - auraLengthFrame.block = block + blockLengthFrame.block = block --save reference of the timeline - auraLengthFrame.timeline = block:GetParent():GetParent():GetParent() + blockLengthFrame.timeline = block:GetParent():GetParent():GetParent() + + registerForDrag(blockLengthFrame) - local auraLengthTexture = auraLengthFrame:CreateTexture(nil, "border") + local auraLengthTexture = blockLengthFrame:CreateTexture(nil, "border") auraLengthTexture:SetColorTexture(1, 1, 1, 1) auraLengthTexture:SetVertexColor(1, 1, 1, 0.1) auraLengthTexture:SetAllPoints() - auraLengthFrame.Texture = auraLengthTexture + blockLengthFrame.Texture = auraLengthTexture + + --icon which will be shown at the end of the blockLength frame if the icon is enabled + local rightIcon = blockLengthFrame:CreateTexture(nil, "border") + rightIcon:SetPoint("topright", blockLengthFrame, "topright", 0, 0) + rightIcon:SetPoint("bottomright", blockLengthFrame, "bottomright", 0, 0) + blockLengthFrame.RightIcon = rightIcon - --icon which will be shown at the end of the auraLength frame if the icon is enabled - local rightIcon = auraLengthFrame:CreateTexture(nil, "border") - rightIcon:SetPoint("topright", auraLengthFrame, "topright", 0, 0) - rightIcon:SetPoint("bottomright", auraLengthFrame, "bottomright", 0, 0) - auraLengthFrame.RightIcon = rightIcon + detailsFramework:CreateHighlightTexture(blockLengthFrame) - detailsFramework:CreateHighlightTexture(auraLengthFrame) + block.blockLength = blockLengthFrame - block.auraLength = auraLengthFrame + return blockLengthFrame end, - GetBlock = function(self, index) - local block = self.blocks[index] - if (not block) then - block = CreateFrame("button", nil, self, "BackdropTemplate") - block:SetMouseClickEnabled(false) - self.blocks[index] = block - - local background = block:CreateTexture(nil, "background") - background:SetColorTexture(1, 1, 1, 1) - local icon = block:CreateTexture(nil, "artwork") - local text = block:CreateFontString(nil, "artwork", "GameFontNormal") - - detailsFramework.TimeLine_LineMixin.CreateAuraLength(block) - - local backgroundBorder = detailsFramework:CreateFullBorder("$parentBorder", block) - local iconOffset = -1 * UIParent:GetEffectiveScale() - PixelUtil.SetPoint(backgroundBorder, "topleft", block, "topleft", -iconOffset, iconOffset) - PixelUtil.SetPoint(backgroundBorder, "topright", block, "topright", iconOffset, iconOffset) - PixelUtil.SetPoint(backgroundBorder, "bottomleft", block, "bottomleft", -iconOffset, -iconOffset) - PixelUtil.SetPoint(backgroundBorder, "bottomright", block, "bottomright", iconOffset, -iconOffset) - - backgroundBorder:SetVertexColor(0, 0, 0, 1) - - background:SetAllPoints() - icon:SetPoint("left") - text:SetPoint("left", icon, "right", 2, 0) - detailsFramework:SetFontOutline(text, "OUTLINE") - - block.icon = icon - block.text = text - block.background = background - block.backgroundBorder = backgroundBorder - - block:SetScript("OnEnter", self:GetParent():GetParent().options.block_on_enter) - block:SetScript("OnLeave", self:GetParent():GetParent().options.block_on_leave) - - block:SetMouseClickEnabled(false) - block.info = {} + OnEnterBlockLength = function(self) + ---@type df_timeline + local timeline = self.timeline + if (timeline.options.block_on_enter_auralength) then + timeline.options.block_on_enter_auralength(self) end + end, - return block + OnLeaveBlockLength = function(self) + ---@type df_timeline + local timeline = self.timeline + if (timeline.options.block_on_enter_auralength) then + timeline.options.block_on_leave_auralength(self) + end end, Reset = function(self) @@ -479,32 +540,48 @@ detailsFramework.TimeLine_LineMixin = { end, } +---@class df_timeline_header_body : frame +---@field Buttons button[] +---@field originalHeight number +---@field Lines frame[] + +---@class df_timeline_header : scrollframe +---@field body frame +---@field headerBody df_timeline_header_body +---@field verticalSlider slider + ---@class df_timeline_body : frame ---@field Buttons button[] ---@field originalHeight number ---@field effectiveWidth number ----@class df_timeline_line : frame, df_timeline_line_mixin +---@class df_timeline_line : button, df_timeline_line_mixin +---@field index number ---@field spellId number ---@field icon df_image ---@field text df_label ---@field dataIndex number ---@field backdrop_color table ---@field backdrop_color_highlight table +---@field enabled boolean +---@field lineData df_timeline_linedata ---@class df_timeline : scrollframe, df_timeline_mixin, df_optionsmixin, df_framelayout, df_lineindicator ---@field body df_timeline_body ----@field onClickCallback fun() ----@field onClickCallbackFunc fun() +---@field onClickCallback fun(...) +---@field onClickCallbackFunc fun(...) ---@field onClickCallbackArgs any[] ----@field headerFrame scrollframe headerFrame only exists if the options.header_detached is true +---@field headerFrame df_timeline_header headerFrame only exists if the options.header_detached is true ---@field headerBody frame headerBody only exists if the options.header_detached is true ---@field resizeButton button ---@field elapsedTimeFrame df_elapsedtime ---@field horizontalSlider slider ---@field scaleSlider slider ---@field verticalSlider slider +---@field oldScale number ---@field currentScale number +---@field oldMinWidth number +---@field oldMaxWidth number ---@field scrolledWidth number ---@field data df_timeline_scrolldata ---@field lines df_timeline_line[] @@ -513,21 +590,29 @@ detailsFramework.TimeLine_LineMixin = { ---@field totalLength number ---@field defaultColor table ---@field headerWidth number +---@field delayButtonRefreshTimer timer ---@class df_timeline_mixin : table ---@field GetLine fun(self:df_timeline, index:number):df_timeline_line ---@field ResetAllLines fun(self:df_timeline) ----@field RefreshTimeLine fun(self:df_timeline, bDoNotRefreshButtons:boolean?) +---@field GetAllLines fun(self:df_timeline):df_timeline_line[] +---@field GetBlockUnderMouse fun(self:df_timeline):df_timeline_line_block? +---@field GetBlockOrLengthUnderMouse fun(self:df_timeline):df_timeline_line_block? +---@field GetTimeUnderMouse fun(self:df_timeline):number +---@field GetBodyWidthUnderMouse fun(self:df_timeline):number +---@field RefreshTimeLine fun(self:df_timeline, bDelayButtonRefresh:boolean?, bFromScale:boolean?) ---@field SetData fun(self:df_timeline, data:table) ---@field GetData fun(self:df_timeline):table ---@field RefreshResize fun(self:df_timeline) +---@field RefreshPerPixelButtons fun(self:df_timeline) ---@field SetCanResize fun(self:df_timeline, canResize:boolean) ---@field OnSizeChanged fun(self:df_timeline) ---@field SetOnClickCallback fun(self:df_timeline, callback:fun(), ...:any) ---@field UpdateOnClickCallback fun(self:df_timeline, button:button?) ---@field GetHorizontalScrolledWidth fun(self:df_timeline):number ----@field HideVerticalScrollBar fun(self:df_timeline) +---@field HideVerticalScroll fun(self:df_timeline) ---@field SetScale fun(self:df_timeline, scale:number) + detailsFramework.TimeLineMixin = { GetHorizontalScrolledWidth = function(self) return self.scrolledWidth @@ -617,27 +702,42 @@ detailsFramework.TimeLineMixin = { if (not line) then --create a new line ---@type df_timeline_line - line = CreateFrame("frame", "$parentLine" .. index, self.body, "BackdropTemplate") + line = CreateFrame("button", "$parentLine" .. index, self.body, "BackdropTemplate") detailsFramework:Mixin(line, detailsFramework.TimeLine_LineMixin) self.lines[index] = line - local xPosition + line.index = index + + local yPosition if (self.options.show_elapsed_timeline) then - xPosition = -((index-1) * (self.options.line_height + 1)) - 2 - self.options.elapsed_timeline_height + yPosition = -((index-1) * (self.options.line_height + 1)) - 2 - self.options.elapsed_timeline_height else - xPosition = -((index-1) * (self.options.line_height + 1)) - 1 + --need code cleanup as the 'else' stuff isn't in use anymore + yPosition = -((index-1) * (self.options.line_height + 1)) - 1 + end + + local yPadding = -10 + yPosition = yPosition + yPadding + + if (index == 1) then + line:SetPoint("topleft", self.body, "topleft", 1, yPosition) + else + line:SetPoint("topleft", self.lines[index-1], "bottomleft", 0, -1) end - line:SetPoint("topleft", self.body, "topleft", 1, xPosition) line:SetSize(1, self.options.line_height) --width is set when updating the frame local detachedHeaderFrame = self.headerFrame local lineHeader if (detachedHeaderFrame) then - lineHeader = CreateFrame("frame", nil, self.headerBody, "BackdropTemplate") + lineHeader = CreateFrame("frame", "$parentHeader", self.headerBody, "BackdropTemplate") lineHeader:SetSize(detachedHeaderFrame:GetWidth(), self.options.line_height) - lineHeader:SetPoint("topleft", self.headerBody, "topleft", 0, xPosition) + if (index == 1) then + lineHeader:SetPoint("topleft", self.headerBody, "topleft", 0, yPosition) + else + lineHeader:SetPoint("topleft", self.lines[index-1].lineHeader, "bottomleft", 0, -1) + end detailsFramework:CreateHighlightTexture(lineHeader, "HighlightTexture") lineHeader.HighlightTexture:SetDrawLayer("overlay", 1) lineHeader.HighlightTexture:Hide() @@ -649,7 +749,7 @@ detailsFramework.TimeLineMixin = { lineHeader.Line = line else - lineHeader = CreateFrame("frame", nil, line, "BackdropTemplate") + lineHeader = CreateFrame("frame", "$parentHeader", line, "BackdropTemplate") lineHeader:SetPoint("topleft", line, "topleft", 0, 0) lineHeader:SetPoint("bottomleft", line, "bottomleft", 0, 0) line:SetScript("OnEnter", self.options.on_enter) @@ -679,6 +779,10 @@ detailsFramework.TimeLineMixin = { line.backdrop_color = self.options.backdrop_color or {.1, .1, .1, .3} line.backdrop_color_highlight = self.options.backdrop_color_highlight or {.3, .3, .3, .5} + + if (self.options.on_create_line) then + self.options.on_create_line(line) + end end return line @@ -733,12 +837,74 @@ detailsFramework.TimeLineMixin = { end end, + GetBlockUnderMouse = function(self) + local allLines = self:GetAllLines() + + for i = 1, #allLines do + local thisLine = allLines[i] + local allBlocksInTheLine = thisLine:GetAllBlocks() + for j = 1, #allBlocksInTheLine do + local thisBlock = allBlocksInTheLine[j] + if (thisBlock:IsShown()) then + if (thisBlock:IsMouseOver()) then + return thisBlock + end + end + end + end + + return nil + end, + + GetBlockOrLengthUnderMouse = function(self) + local allLines = self:GetAllLines() + + for i = 1, #allLines do + local thisLine = allLines[i] + local allBlocksInTheLine = thisLine:GetAllBlocks() + for j = 1, #allBlocksInTheLine do + local thisBlock = allBlocksInTheLine[j] + if (thisBlock:IsShown()) then + if (thisBlock:IsMouseOver()) then + return thisBlock + end + + local blockLength = thisBlock.blockLength + if (blockLength and blockLength:IsShown()) then + if (blockLength:IsMouseOver()) then + return thisBlock + end + end + end + end + end + + return nil + end, + + GetBodyWidthUnderMouse = function(self) + local x, y = GetCursorPosition() + local scale = 1 / UIParent:GetEffectiveScale() + x = x * scale + + local left = self.body:GetLeft() + local width = x - left + + return width + end, + + GetTimeUnderMouse = function(self) + local bodyWidthUnderMouse = self:GetBodyWidthUnderMouse() + local time = bodyWidthUnderMouse / (self.pixelPerSecond * self.currentScale) + return time + end, + --todo --make the on enter and leave tooltips --set icons and texts --skin the sliders - RefreshTimeLine = function(self, bDoNotRefreshButtons) --~refresh + RefreshTimeLine = function(self, bDelayButtonRefresh, bFromScale) --~refresh if (not self.data.lines) then return end @@ -754,61 +920,58 @@ detailsFramework.TimeLineMixin = { local timelineWidth = self:GetWidth() - --original code - --[=[ - --how many pixels represent 1 second - local bodyWidth = totalLength * pixelPerSecond * currentScale - self.body:SetWidth(bodyWidth + self.options.header_width) - self.body.effectiveWidth = bodyWidth - - --reduce the default canvas size from the body with and don't allow the max value be negative - local newMaxValue = max(bodyWidth - (self:GetWidth() - self.options.header_width), 0) - - --adjust the scale slider range - local oldMin, oldMax = self.horizontalSlider:GetMinMaxValues() - self.horizontalSlider:SetMinMaxValues(0, newMaxValue) - self.horizontalSlider:SetValue(detailsFramework:MapRangeClamped(oldMin, oldMax, 0, newMaxValue, self.horizontalSlider:GetValue())) - ]=] - --calculate the width that the body width should be local bodyWidth = totalLength * pixelPerSecond * currentScale - --get the biggest value between the calculated body width and (timeline width minus header width) in case the desired body width is smaller than the timeline width - --local bodyFrameWidth = max(bodyWidth + effectiveHeaderWidth, timelineWidth - effectiveHeaderWidth) - --self.body:SetWidth(bodyFrameWidth) self.body:SetWidth(bodyWidth + effectiveHeaderWidth) - --[=[ - print("effectiveHeaderWidth", effectiveHeaderWidth) - if (bodyWidth + effectiveHeaderWidth > timelineWidth - effectiveHeaderWidth) then - print(1) - else - print(2) --this is fucking with the elapsed time bar | need to see further in the script that's happening - end - --]=] - --reduce the default timeline size from the body width and don't allow the max value be negative - local newMaxValue = max(bodyWidth - timelineWidth + effectiveHeaderWidth, 0) - - --print(desiredBodyWidth + effectiveHeaderWidth, timelineWidth - effectiveHeaderWidth) --1020, 750 + local diff = bodyWidth - timelineWidth + local newMaxValue = max(diff + effectiveHeaderWidth, 0) self.body.effectiveWidth = bodyWidth + --cache values + self.pixelPerSecond = pixelPerSecond + self.totalLength = totalLength + self.headerWidth = effectiveHeaderWidth + --adjust the scale slider range + --new max value is zero when all content is shown in the timeline (no scroll needed) local oldMin, oldMax = self.horizontalSlider:GetMinMaxValues() - self.horizontalSlider:SetMinMaxValues(0, newMaxValue) - self.horizontalSlider:SetValue(detailsFramework:MapRangeClamped(oldMin, oldMax, 0, newMaxValue, self.horizontalSlider:GetValue())) + local newHorizontalSliderValue = self.horizontalSlider:GetValue() + if (bFromScale) then + local timeUnderMouse = self:GetTimeUnderMouse() + local timeUnderMouseInPixels = (timeUnderMouse * pixelPerSecond * self.currentScale) + newHorizontalSliderValue = timeUnderMouseInPixels + end + + if (newMaxValue == 0) then + --no scroll is needed + self.horizontalSlider:SetMinMaxValues(0, 0) + self.horizontalSlider:SetValue(0) + + elseif (oldMax ~= newMaxValue) then + self.horizontalSlider:SetMinMaxValues(0, newMaxValue) + self.horizontalSlider:SetValue(newHorizontalSliderValue) --it is setting for zoom even when if the refresh is not from zoom + end + + self.oldMinWidth = 0 + self.oldMaxWidth = newMaxValue local defaultColor = self.data.defaultColor or {1, 1, 1, 1} - --cache values - self.pixelPerSecond = pixelPerSecond - self.totalLength = totalLength self.defaultColor = defaultColor - self.headerWidth = effectiveHeaderWidth --buttons are the vertical clickable areas inside the timeline, each second on the time line has one - if (not bDoNotRefreshButtons and self.options.use_perpixel_buttons) then + if (not bDelayButtonRefresh and self.options.use_perpixel_buttons) then self:RefreshPerPixelButtons() + elseif (bDelayButtonRefresh and self.options.use_perpixel_buttons) then + if (self.delayButtonRefreshTimer and not self.delayButtonRefreshTimer:IsCancelled()) then + self.delayButtonRefreshTimer:Cancel() + end + self.delayButtonRefreshTimer = detailsFramework.Schedules.NewTimer(0.1, function() + self:RefreshPerPixelButtons() + end) end --calculate the total height @@ -834,14 +997,16 @@ detailsFramework.TimeLineMixin = { end --refresh lines - local howManyLinesTheTimelineCanShow = floor(self:GetHeight() / (lineHeight + linePadding)) - 1 - --for i = 1, math.min(#self.data.lines, howManyLinesTheTimelineCanShow) do for i = 1, #self.data.lines do local line = self:GetLine(i) line.dataIndex = i --this index is used inside the line update function to know which data to get line.lineHeader:SetWidth(self.options.header_width) line:SetBlocksFromData() --the function to update runs within the line object line.lineHeader:Show() + + if (self.options.on_refresh_line) then + self.options.on_refresh_line(line) + end end --refresh elapsed time frame @@ -878,10 +1043,12 @@ detailsFramework.TimeLineMixin = { local timelineHeader = { ---@param self df_timeline CreateDetachedHeader = function(self) + ---@type df_timeline_header local headerFrame = CreateFrame("scrollframe", nil, self, "BackdropTemplate") headerFrame:SetWidth(self.options.header_width) self.headerFrame = headerFrame + ---@type df_timeline_header_body local headerBody = CreateFrame("frame", nil, headerFrame, "BackdropTemplate") headerBody:SetSize(headerFrame:GetSize()) headerBody.Lines = {} @@ -909,6 +1076,7 @@ local onScaleChange_RefreshTimer = nil ---@class df_timeline_body : frame, df_lineindicator + ---creates a scrollable panel with vertical, horizontal and scale sliders to show a timeline ---also creates a frame for the elapsed timeline at the top, it shows the time in seconds ---@param parent frame @@ -939,6 +1107,7 @@ function detailsFramework:CreateTimeLineFrame(parent, name, timelineOptions, ela frameCanvas.lines = {} frameCanvas.currentScale = 0.5 + frameCanvas.oldScale = 0.5 frameCanvas:SetSize(width, height) detailsFramework:ApplyStandardBackdrop(frameCanvas) @@ -1010,23 +1179,16 @@ function detailsFramework:CreateTimeLineFrame(parent, name, timelineOptions, ela scaleSlider:SetOrientation("horizontal") scaleSlider:SetMinMaxValues(frameCanvas.options.scale_min, frameCanvas.options.scale_max) - scaleSlider:SetValue(detailsFramework:GetRangeValue(frameCanvas.options.scale_min, frameCanvas.options.scale_max, 0.5)) + scaleSlider:SetValue(detailsFramework.Math.GetRangeValue(frameCanvas.options.scale_min, frameCanvas.options.scale_max, 0.5)) - scaleSlider:SetScript("OnValueChanged", function(self) + scaleSlider:SetScript("OnValueChanged", function(self, delta) local stepValue = ceil(self:GetValue() * 100) / 100 if (stepValue ~= frameCanvas.currentScale) then - local current = stepValue + frameCanvas.oldScale = frameCanvas.currentScale frameCanvas.currentScale = stepValue - local bDoNotRefreshButtons = true - frameCanvas:RefreshTimeLine(bDoNotRefreshButtons) - - if (onScaleChange_RefreshTimer and not onScaleChange_RefreshTimer:IsCancelled()) then - onScaleChange_RefreshTimer:Cancel() - end - - onScaleChange_RefreshTimer = detailsFramework.Schedules.NewTimer(0.1, function() - frameCanvas:RefreshTimeLine() - end) + local bDelayButtonRefresh = true + local bFromScale = true + frameCanvas:RefreshTimeLine(bDelayButtonRefresh, bFromScale) end end) @@ -1062,21 +1224,6 @@ function detailsFramework:CreateTimeLineFrame(parent, name, timelineOptions, ela local minValue, maxValue = horizontalSlider:GetMinMaxValues() local currentHorizontal = horizontalSlider:GetValue() - if (delta < 0) then - if (verticalSlider:IsShown()) then - local amountToScroll = frameBody:GetHeight() / 20 - verticalSlider:SetValue(verticalSlider:GetValue() + amountToScroll) - return - end - - elseif (delta > 0) then - if (verticalSlider:IsShown()) then - local amountToScroll = frameBody:GetHeight() / 20 - verticalSlider:SetValue(verticalSlider:GetValue() - amountToScroll) - return - end - end - if (IsShiftKeyDown() and delta < 0) then if (verticalSlider:IsShown()) then local amountToScroll = frameBody:GetHeight() / 20 @@ -1090,10 +1237,14 @@ function detailsFramework:CreateTimeLineFrame(parent, name, timelineOptions, ela end elseif (IsControlKeyDown() and delta > 0) then - scaleSlider:SetValue(min(scaleSlider:GetValue() + 0.1, 1)) + scaleSlider:SetValue(min(scaleSlider:GetValue() + 0.1, frameCanvas.options.scale_max)) elseif (IsControlKeyDown() and delta < 0) then - scaleSlider:SetValue(max(scaleSlider:GetValue() - 0.1, 0.15)) + if (self.options.zoom_out_zero) then + scaleSlider:SetValue(0) + else + scaleSlider:SetValue(max(scaleSlider:GetValue() - 0.1, frameCanvas.options.scale_min)) + end elseif (delta < 0 and currentHorizontal < maxValue) then local amountToScroll = frameBody:GetWidth() / 20 @@ -1113,22 +1264,35 @@ function detailsFramework:CreateTimeLineFrame(parent, name, timelineOptions, ela frameBody.GetHorizontalScrolledWidth = frameCanvas.GetHorizontalScrolledWidth + local dragOnTickFunc = function() + local x = GetCursorPosition() + local deltaX = frameBody.MouseX - x + local current = horizontalSlider:GetValue() + horizontalSlider:SetValue(current + (deltaX * 1.2) * ((IsShiftKeyDown() and 2) or (IsAltKeyDown() and 0.5) or 1)) + frameBody.MouseX = x + end + + frameBody.isDragging = false + + frameBody:SetScript("OnUpdate", function(thisFrameBody, deltaTime) + if (frameBody.isDragging) then + dragOnTickFunc() + end + + if (frameBody:IsMouseOver()) then + frameBody.mouseTime = frameCanvas:GetTimeUnderMouse() + end + end) + --mouse drag frameBody:SetScript("OnMouseDown", function(self, button) local x = GetCursorPosition() self.MouseX = x - - frameBody:SetScript("OnUpdate", function(self, deltaTime) - local x = GetCursorPosition() - local deltaX = self.MouseX - x - local current = horizontalSlider:GetValue() - horizontalSlider:SetValue(current + (deltaX * 1.2) * ((IsShiftKeyDown() and 2) or (IsAltKeyDown() and 0.5) or 1)) - self.MouseX = x - end) + frameBody.isDragging = true end) frameBody:SetScript("OnMouseUp", function(self, button) - frameBody:SetScript("OnUpdate", nil) + frameBody.isDragging = false end) local headerFrame, headerBody diff --git a/Libs/LibOpenRaid/GetPlayerInformation.lua b/Libs/LibOpenRaid/GetPlayerInformation.lua index 424448461..1324424b1 100644 --- a/Libs/LibOpenRaid/GetPlayerInformation.lua +++ b/Libs/LibOpenRaid/GetPlayerInformation.lua @@ -93,28 +93,34 @@ local IsShadowlands = function() end end ---information about the player character to send, each expansion has its own system and data can be different ---it's always a number -function openRaidLib.UnitInfoManager.GetPlayerInfo1() - if (IsShadowlands()) then - --return the renown level within the player covenant - local renown = C_CovenantSanctumUI.GetRenownLevel() or 1 - return renown - end - - return 0 -end - ---information about the player character to send, each expansion has its own system and data can be different ---it's always a number -function openRaidLib.UnitInfoManager.GetPlayerInfo2() - if (IsShadowlands()) then - --return which covenant the player picked - local covenant = C_Covenants.GetActiveCovenantID() or 0 - return covenant +function openRaidLib.GetHeroTalentId() + if (IsTWWExpansion()) then + local configId = C_ClassTalents.GetActiveConfigID() + if (not configId) then + return + end + local configInfo = C_Traits.GetConfigInfo(configId) + for treeIndex, treeId in ipairs(configInfo.treeIDs) do + local treeNodes = C_Traits.GetTreeNodes(treeId) + for nodeIdIndex, treeNodeID in ipairs(treeNodes) do + local traitNodeInfo = C_Traits.GetNodeInfo(configId, treeNodeID) + if (traitNodeInfo) then + local activeEntry = traitNodeInfo.activeEntry + if (activeEntry) then + local entryId = activeEntry.entryID + local rank = activeEntry.rank + if (rank > 0) then + local entryInfo = C_Traits.GetEntryInfo(configId, entryId) + if (not entryInfo.definitionID and entryInfo.subTreeID) then + return entryInfo.subTreeID + end + end + end + end + end + end end - - return 0 + return end --default player class-spec talent system @@ -155,6 +161,15 @@ local getDragonflightTalentsExportedString = function() end end +---@return string +local getDragonlightTalentAsString = function() + local activeConfigID = C_ClassTalents.GetActiveConfigID() + if (activeConfigID and activeConfigID > 0) then + return C_Traits.GenerateImportString(activeConfigID) + end + return "" +end + local getDragonflightTalentsAsIndexTable = function() local allTalents = {} local configId = C_ClassTalents.GetActiveConfigID() @@ -198,6 +213,36 @@ local getDragonflightTalentsAsIndexTable = function() return allTalents end +function openRaidLib.GetDragonFlightTalentsAsString() + local talents = getDragonlightTalentAsString() + + --if is tww + if (IsTWWExpansion()) then + local heroTalentId = openRaidLib.GetHeroTalentId() + if (heroTalentId) then + talents = talents .. "@HT" .. openRaidLib.GetHeroTalentId() + end + end + + return talents +end + +function openRaidLib.ParseTalentString(talentString) + local heroTalentId = talentString:match("@HT(%d+)") + if (heroTalentId) then + heroTalentId = tonumber(heroTalentId) + if (heroTalentId) then + --remove the hero talent from the string + talentString = talentString:gsub("@HT%d+", "") + return talentString, heroTalentId + else + return talentString + end + else + return talentString + end +end + --creates two tables, one with indexed talents and another with pairs values ([talentId] = true) function openRaidLib.UnitInfoManager.GetPlayerTalentsAsPairsTable() local talentsPairs = {} @@ -249,9 +294,9 @@ function openRaidLib.UnitInfoManager.GetPlayerTalents() end function openRaidLib.UnitInfoManager.GetPlayerPvPTalents() - if (IsDragonflight()) then - return {} - end + --if (IsDragonflight()) then + -- return {} + --end local talentsPvP = {0, 0, 0} local talentList = C_SpecializationInfo.GetAllSelectedPvpTalentIDs() @@ -325,16 +370,6 @@ function openRaidLib.UnitInfoManager.GetPlayerConduits() return conduits end -function openRaidLib.UnitInfoManager.GetPlayerBorrowedTalents() - local borrowedTalentVersion = openRaidLib.GetBorrowedTalentVersion() - - if (borrowedTalentVersion == CONST_BTALENT_VERSION_COVENANTS) then - return openRaidLib.UnitInfoManager.GetPlayerConduits() - end - - return {} -end - function openRaidLib.GearManager.GetPlayerItemLevel() if (_G.GetAverageItemLevel) then @@ -522,6 +557,9 @@ end local addCooldownToTable = function(cooldowns, cooldownsHash, cooldownSpellId, timeNow) local timeLeft, charges, startTimeOffset, duration, auraDuration = openRaidLib.CooldownManager.GetPlayerCooldownStatus(cooldownSpellId) + --local spellInfo = C_Spell.GetSpellInfo(cooldownSpellId) + --print(spellInfo.name, "charges:", charges) + cooldowns[#cooldowns+1] = cooldownSpellId cooldowns[#cooldowns+1] = timeLeft cooldowns[#cooldowns+1] = charges diff --git a/Libs/LibOpenRaid/LibOpenRaid.lua b/Libs/LibOpenRaid/LibOpenRaid.lua index dadb324a8..738a198bb 100644 --- a/Libs/LibOpenRaid/LibOpenRaid.lua +++ b/Libs/LibOpenRaid/LibOpenRaid.lua @@ -56,7 +56,7 @@ end local major = "LibOpenRaid-1.0" -local CONST_LIB_VERSION = 145 +local CONST_LIB_VERSION = 147 if (LIB_OPEN_RAID_MAX_VERSION) then if (CONST_LIB_VERSION <= LIB_OPEN_RAID_MAX_VERSION) then @@ -117,8 +117,6 @@ end local CONST_COMM_PLAYER_DEAD_PREFIX = "D" local CONST_COMM_PLAYER_ALIVE_PREFIX = "A" local CONST_COMM_PLAYERINFO_PREFIX = "P" - local CONST_COMM_PLAYERINFO_TALENTS_PREFIX = "T" - local CONST_COMM_PLAYERINFO_PVPTALENTS_PREFIX = "V" local CONST_COMM_KEYSTONE_DATA_PREFIX = "K" local CONST_COMM_KEYSTONE_DATAREQUEST_PREFIX = "J" @@ -471,6 +469,7 @@ end --trigger callbacks for i = 1, #callbackTable do + --dumpt(dataAsTable) callbackTable[i](dataAsTable, sender) end end @@ -494,8 +493,6 @@ end [CONST_COMM_PLAYER_DEAD_PREFIX] = {}, --player is dead [CONST_COMM_PLAYER_ALIVE_PREFIX] = {}, --player is alive [CONST_COMM_PLAYERINFO_PREFIX] = {}, --info about the player - [CONST_COMM_PLAYERINFO_TALENTS_PREFIX] = {}, --talents info - [CONST_COMM_PLAYERINFO_PVPTALENTS_PREFIX] = {}, --pvp talents info [CONST_COMM_KEYSTONE_DATA_PREFIX] = {}, --received keystone data [CONST_COMM_KEYSTONE_DATAREQUEST_PREFIX] = {}, --received a request to send keystone data [CONST_COMM_OPENNOTES_RECEIVED_PREFIX] = {}, --received notes @@ -733,9 +730,10 @@ end end local result, errortext = xpcall(callback, geterrorhandler(), unpack(payload)) - --if (not result) then - -- sendChatMessage("openRaidLib: error on scheduler:", tickerObject.scheduleName, tickerObject.stack) - --end + --local result, errortext = pcall(callback, unpack(payload)) + if (not result) then + sendChatMessage("openRaidLib: error on scheduler:", tickerObject.scheduleName, tickerObject.stack) + end return result end @@ -831,8 +829,8 @@ end "GearDurabilityUpdate", "UnitInfoUpdate", "UnitInfoWipe", - "TalentUpdate", - "PvPTalentUpdate", + "TalentUpdate", --deprecated + "PvPTalentUpdate", --deprecated "KeystoneUpdate", "KeystoneWipe", "NoteUpdated", @@ -1089,7 +1087,7 @@ end delayedTalentChange() end, ["TRAIT_TREE_CURRENCY_INFO_UPDATED"] = function(...) - delayedTalentChange() + --delayedTalentChange() end, --SPELLS_CHANGED @@ -1236,9 +1234,9 @@ end local unitName = UnitName("player") --player data local playerFullInfo = openRaidLib.UnitInfoManager.GetPlayerFullInfo() - openRaidLib.UnitInfoManager.AddUnitInfo(unitName, unpack(playerFullInfo)) + openRaidLib.UnitInfoManager.AddUnitInfo(unitName, unpack(playerFullInfo)) --unpack: specId, talentsString, pvpTalentsTableUnpacked - --gear info + --gear info --C_Timer.After(2, function() local playerGearInfo = openRaidLib.GearManager.GetPlayerFullGearInfo() openRaidLib.GearManager.AddUnitGearList(unitName, unpack(playerGearInfo)) @@ -1389,6 +1387,43 @@ end -------------------------------------------------------------------------------------------------------------------------------- --~player general ~info ~unit ~unitinfo + ---@class unitinfomanager : table + ---@field Version number + ---@field UnitData table + ---@field GetAllUnitsInfo fun():table + ---@field GetUnitInfo fun(unitId:string, createNew:boolean?):unitinfodata + ---@field EraseData fun() + ---@field SetUnitInfo fun(unitName:string, unitInfo:unitinfodata, specId:number, talentsString:string, pvpTalentsTableUnpacked:table) + ---@field UpdateUnitInfo fun(unitName:string, specId:number?, talentsString:string?, pvpTalentsTableUnpacked:table?) + ---@field AddUnitInfo fun(unitName:string, specId:number, talentsString:string, pvpTalentsTableUnpacked:table) + ---@field OnReceiveUnitFullInfo fun(data:table, unitName:string) + ---@field SendAllPlayerInfo fun() + ---@field GetPlayerFullInfo fun():unitinfocomm + ---@field GetPlayerPvPTalents fun():table + ---@field OnPlayerTalentChanged fun() + ---@field OnReceivePvPTalentsUpdate fun(data:table, unitName:string) + ---@field OnPlayerLeaveGroup fun() + ---@field SendPlayerInfoAfterCombat fun() + ---@field OnLeaveCombat fun() + + ---@class unitinfodata : table + ---@field specId number + ---@field specName string + ---@field heroTalentId number + ---@field role string + ---@field talents string + ---@field pvpTalents table + ---@field class string + ---@field classId number + ---@field className string + ---@field name string + ---@field nameFull string + + ---@class unitinfocomm : table + ---@field [1] number specId + ---@field [2] string talents + ---@field [3] table pvpTalents + --API calls --return a table containing all information of units --format: [playerName-realm] = {information} @@ -1403,21 +1438,22 @@ end end --manager constructor - openRaidLib.UnitInfoManager = { - --structure: - --[playerName] = {ilevel = 100, durability = 100, weaponEnchant = 0, noGems = {}, noEnchants = {}} - UnitData = {}, - } + ---@type unitinfomanager + ---@diagnostic disable-next-line: missing-fields + local UnitInfoManager = {} + UnitInfoManager.UnitData = {} + UnitInfoManager.Version = 1 + openRaidLib.UnitInfoManager = UnitInfoManager + + ---@type unitinfodata local unitTablePrototype = { specId = 0, specName = "", + heroTalentId = 0, role = "", - renown = 1, - covenantId = 0, - talents = {}, - conduits = {}, - pvpTalents = {}, + talents = "", --export string + pvpTalents = {}, --should be 3 spellIds class = "", classId = 0, className = "", @@ -1425,31 +1461,45 @@ end nameFull = "", } - function openRaidLib.UnitInfoManager.GetAllUnitsInfo() - return openRaidLib.UnitInfoManager.UnitData + ---@return unitinfodata + local createNewUnitInfo = function() + ---@type unitinfodata + ---@diagnostic disable-next-line: missing-fields + local newUnitInfo = {} + openRaidLib.TCopy(newUnitInfo, unitTablePrototype) + return newUnitInfo + end + + function UnitInfoManager.GetAllUnitsInfo() + return UnitInfoManager.UnitData end --get the unit table or create a new one if 'createNew' is true - function openRaidLib.UnitInfoManager.GetUnitInfo(unitName, createNew) - local unitInfo = openRaidLib.UnitInfoManager.UnitData[unitName] + function UnitInfoManager.GetUnitInfo(unitName, createNew) + ---@type unitinfodata + local unitInfo = UnitInfoManager.UnitData[unitName] if (not unitInfo and createNew) then - unitInfo = {} - openRaidLib.TCopy(unitInfo, unitTablePrototype) - openRaidLib.UnitInfoManager.UnitData[unitName] = unitInfo + unitInfo = createNewUnitInfo() + UnitInfoManager.UnitData[unitName] = unitInfo end return unitInfo end - function openRaidLib.UnitInfoManager.EraseData() - table.wipe(openRaidLib.UnitInfoManager.UnitData) + function UnitInfoManager.EraseData() + table.wipe(UnitInfoManager.UnitData) end - function openRaidLib.UnitInfoManager.SetUnitInfo(unitName, unitInfo, specId, renown, covenantId, talentsTableUnpacked, conduitsTableUnpacked, pvpTalentsTableUnpacked) + ---@param unitName string + ---@param unitInfo unitinfodata + ---@param specId number + ---@param talentsString string + ---@param pvpTalentsTableUnpacked table + function UnitInfoManager.SetUnitInfo(unitName, unitInfo, specId, talentsString, pvpTalentsTableUnpacked) if (not GetSpecializationInfoByID) then --tbc hot fix return end - local specId, specName, specDescription, specIcon, role = GetSpecializationInfoByID(specId or 0) + local specId, specName, specDescription, specIcon, role, classFile, classLocName = GetSpecializationInfoByID(specId or 0) local className, classString, classId = UnitClass(unitName) --cold login bug where the player class info cannot be retrived by the player name, after a /reload it's all good @@ -1460,13 +1510,13 @@ end end end + local talentString, heroTalent = openRaidLib.ParseTalentString(talentsString) + unitInfo.specId = specId or unitInfo.specId unitInfo.specName = specName or unitInfo.specName + unitInfo.heroTalentId = heroTalent or unitInfo.heroTalentId unitInfo.role = role or "DAMAGER" - unitInfo.renown = renown or unitInfo.renown - unitInfo.covenantId = covenantId or unitInfo.covenantId - unitInfo.talents = talentsTableUnpacked or unitInfo.talents - unitInfo.conduits = conduitsTableUnpacked or unitInfo.conduits + unitInfo.talents = talentString or "" unitInfo.pvpTalents = pvpTalentsTableUnpacked or unitInfo.pvpTalents unitInfo.class = classString unitInfo.classId = classId @@ -1475,68 +1525,52 @@ end unitInfo.nameFull = unitName end - function openRaidLib.UnitInfoManager.AddUnitInfo(unitName, specId, renown, covenantId, talentsTableUnpacked, conduitsTableUnpacked, pvpTalentsTableUnpacked) - local unitInfo = openRaidLib.UnitInfoManager.GetUnitInfo(unitName, true) - openRaidLib.UnitInfoManager.SetUnitInfo(unitName, unitInfo, specId, renown, covenantId, talentsTableUnpacked, conduitsTableUnpacked, pvpTalentsTableUnpacked) - openRaidLib.publicCallback.TriggerCallback("UnitInfoUpdate", openRaidLib.GetUnitID(unitName), openRaidLib.UnitInfoManager.UnitData[unitName], openRaidLib.UnitInfoManager.GetAllUnitsInfo()) + function UnitInfoManager.AddUnitInfo(unitName, specId, talentsString, pvpTalentsTableUnpacked) + local unitInfo = UnitInfoManager.GetUnitInfo(unitName, true) --returning nil + UnitInfoManager.SetUnitInfo(unitName, unitInfo, specId, talentsString, pvpTalentsTableUnpacked) + openRaidLib.publicCallback.TriggerCallback("UnitInfoUpdate", openRaidLib.GetUnitID(unitName), UnitInfoManager.UnitData[unitName], UnitInfoManager.GetAllUnitsInfo()) end - --triggered when the lib receives a unit information from another player in the raid - --@data: table received from comm - --@unitName: player name - function openRaidLib.UnitInfoManager.OnReceiveUnitFullInfo(data, unitName) - local specId = tonumber(data[1]) - - local playerInfo1 = tonumber(data[2]) + function UnitInfoManager.UpdateUnitInfo(playerName, specId, talentsString, pvpTalentsTableUnpacked) + local unitInfo = UnitInfoManager.GetUnitInfo(playerName, true) + UnitInfoManager.SetUnitInfo(playerName, unitInfo, specId or unitInfo.specId, talentsString or unitInfo.talents, pvpTalentsTableUnpacked or unitInfo.pvpTalents) + openRaidLib.publicCallback.TriggerCallback("UnitInfoUpdate", openRaidLib.GetUnitID(playerName), UnitInfoManager.UnitData[playerName], UnitInfoManager.GetAllUnitsInfo()) + end - local playerInfo2 = tonumber(data[3]) - if (not playerInfo2 or playerInfo2 > 4) then --cleanup on 10.0 - --invalid covanentId - different lib versions, it'll fix itself on dragonflight - return - end + function UnitInfoManager.OnReceiveUnitFullInfo(data, unitName) + --triggered when the lib receives a unit information from another player in the raid + local specId = tonumber(data[1]) + local talentsString = data[2] - local talentsSize = tonumber(data[4]) - if (not talentsSize) then + local unitInfoVersion = data[7] + if (type(unitInfoVersion) ~= "string" or not unitInfoVersion:find("!")) then + openRaidLib.DiagnosticError("UnitInfoManager.OnReceiveUnitFullInfo: invalid version data", unitInfoVersion) return end - local borrowedTalentsTableIndex = tonumber((talentsSize + 1) + 3) + 1 -- +3 for spec, playerInfo1 and playerInfo2 data | talentSizeIndex + talentSize | +1 for talents size - local borrowedTalentsSize = data[borrowedTalentsTableIndex] - - local pvpTalentsTableIndex = 3 + 3 + talentsSize + borrowedTalentsSize -- +3 for spec, playerInfo1 and playerInfo2 data | +3 for talents, conduit and pvptalents index for size - local pvpTalentsSize = data[pvpTalentsTableIndex] - - --unpack the talents data as a ipairs table - local talentsTableUnpacked = openRaidLib.UnpackTable(data, 4, false, false, talentsSize) - - --unpack the borrowed talents data as a ipairs table - local borrowedTalentsTableUnpacked = openRaidLib.UnpackTable(data, borrowedTalentsTableIndex, false, false, borrowedTalentsSize) - - --back compatibility with versions without pvp talents - if (type(data[pvpTalentsTableIndex]) == "string" or not data[pvpTalentsTableIndex]) then - --add a dummy table as pvp talents - openRaidLib.UnitInfoManager.AddUnitInfo(unitName, specId, playerInfo1, playerInfo2, talentsTableUnpacked, borrowedTalentsTableUnpacked, {0, 0, 0}) + local versionNumber = tonumber(unitInfoVersion:match("!(%d+)")) + if (not versionNumber or versionNumber < UnitInfoManager.Version) then + openRaidLib.DiagnosticError("UnitInfoManager.OnReceiveUnitFullInfo: invalid version number", versionNumber, UnitInfoManager.Version) return end --unpack the pvp talents data as a ipairs table - local pvpTalentsTableUnpacked = openRaidLib.UnpackTable(data, pvpTalentsTableIndex, false, false, pvpTalentsSize) + local pvpTalentsIndex = 3 + local pvpTalentsSize = 3 + local pvpTalentsTableUnpacked = openRaidLib.UnpackTable(data, pvpTalentsIndex, false, false, pvpTalentsSize) --add to the list of players information and also trigger a public callback - openRaidLib.UnitInfoManager.AddUnitInfo(unitName, specId, playerInfo1, playerInfo2, talentsTableUnpacked, borrowedTalentsTableUnpacked, pvpTalentsTableUnpacked) + UnitInfoManager.AddUnitInfo(unitName, specId, talentsString, pvpTalentsTableUnpacked) end - openRaidLib.commHandler.RegisterComm(CONST_COMM_PLAYERINFO_PREFIX, openRaidLib.UnitInfoManager.OnReceiveUnitFullInfo) + openRaidLib.commHandler.RegisterComm(CONST_COMM_PLAYERINFO_PREFIX, UnitInfoManager.OnReceiveUnitFullInfo) -function openRaidLib.UnitInfoManager.SendAllPlayerInfo() - local playerInfo = openRaidLib.UnitInfoManager.GetPlayerFullInfo() +function UnitInfoManager.SendAllPlayerInfo() + local playerInfo = UnitInfoManager.GetPlayerFullInfo() local dataToSend = CONST_COMM_PLAYERINFO_PREFIX .. "," dataToSend = dataToSend .. playerInfo[1] .. "," --spec id - dataToSend = dataToSend .. playerInfo[2] .. "," --player info 1 - dataToSend = dataToSend .. playerInfo[3] .. "," --player info 2 - dataToSend = dataToSend .. openRaidLib.PackTable(playerInfo[4]) .. "," --player talents class-spec - dataToSend = dataToSend .. openRaidLib.PackTable(playerInfo[5]) .. "," --player talents borrowed - dataToSend = dataToSend .. openRaidLib.PackTable(playerInfo[6]) .. "," --player talents pvp + dataToSend = dataToSend .. playerInfo[2] .. "," --talents string + dataToSend = dataToSend .. openRaidLib.PackTable(playerInfo[3]) .. ",!1" --player talents pvp --send the data openRaidLib.commHandler.SendCommData(dataToSend) @@ -1545,18 +1579,16 @@ end --player info format: --index 1: number: specId ---index 2: number: tbd, depends on expansion ---index 3: number: tbd, depends on expansion ---index 4: talents 1: player talents: length vary depends on talent system ---index 5: talents 2: borrowed power talents: length vary from expansions ---index 6: talents 3: pvp talents -function openRaidLib.UnitInfoManager.GetPlayerFullInfo() +--index 2: talents as string +--index 3: pvp talents as table +---@return unitinfocomm +function UnitInfoManager.GetPlayerFullInfo() local playerInfo = {} if (isTimewalkWoW()) then --indexes: specId, renown, covenant, talent, conduits, pvp talents --return a placeholder table - return {0, 0, 0, {0, 0, 0, 0, 0, 0, 0}, {0, 0}, 0} + return {0, "", {0, 0, 0}} end local specId = 0 @@ -1566,50 +1598,25 @@ function openRaidLib.UnitInfoManager.GetPlayerFullInfo() specId = GetSpecializationInfo(selectedSpecialization) or 0 end end - playerInfo[1] = specId - - --player information 1 (this can be different for each expansion) - playerInfo[2] = openRaidLib.UnitInfoManager.GetPlayerInfo1() - - --player information 2 (this can be different for each expansion) - playerInfo[3] = openRaidLib.UnitInfoManager.GetPlayerInfo2() + table.insert(playerInfo, specId) --player class-spec talents - local talents = openRaidLib.UnitInfoManager.GetPlayerTalents() - playerInfo[4] = talents - - --borrowed talents (conduits talents on shadowlands) - local borrowedTalents = openRaidLib.UnitInfoManager.GetPlayerBorrowedTalents() - playerInfo[5] = borrowedTalents + local talentsAsString = openRaidLib.GetDragonFlightTalentsAsString() + table.insert(playerInfo, talentsAsString) --pvp talents - local pvpTalents = openRaidLib.UnitInfoManager.GetPlayerPvPTalents() - playerInfo[6] = pvpTalents + local pvpTalents = UnitInfoManager.GetPlayerPvPTalents() + table.insert(playerInfo, pvpTalents) return playerInfo end ---talent update (when the player changes a talent and the lib needs to notify other players in the group) -function openRaidLib.UnitInfoManager.SendTalentUpdate() - --talents - local playerName = UnitName("player") - local unitInfo = openRaidLib.UnitInfoManager.GetUnitInfo(playerName, true) - local talentsToSend = unitInfo.talents - local dataToSend = "" .. CONST_COMM_PLAYERINFO_TALENTS_PREFIX .. "," - local talentsString = openRaidLib.PackTable(talentsToSend) - dataToSend = dataToSend .. talentsString - - --send the data - openRaidLib.commHandler.SendCommData(dataToSend) - diagnosticComm("SendTalentUpdateData| " .. dataToSend) --debug -end - --/dump LibStub:GetLibrary("LibOpenRaid-1.0", true).UnitInfoManager.GetUnitInfo(UnitName("player")) -function openRaidLib.UnitInfoManager.OnPlayerTalentChanged() +function UnitInfoManager.OnPlayerTalentChanged() --this talent update could be a specialization change, so we need to pass the specId as well local playerName = UnitName("player") - local unitInfo = openRaidLib.UnitInfoManager.GetUnitInfo(playerName, true) + local unitInfo = UnitInfoManager.GetUnitInfo(playerName, true) local specId = 0 if (getSpecializationVersion() == CONST_SPECIALIZATION_VERSION_MODERN) then @@ -1619,92 +1626,39 @@ function openRaidLib.UnitInfoManager.OnPlayerTalentChanged() end end - openRaidLib.UnitInfoManager.SetUnitInfo(playerName, unitInfo, specId, nil, nil, openRaidLib.UnitInfoManager.GetPlayerTalents()) + UnitInfoManager.SetUnitInfo(playerName, unitInfo, specId, openRaidLib.GetDragonFlightTalentsAsString(), UnitInfoManager.GetPlayerPvPTalents()) --trigger public callback event - openRaidLib.publicCallback.TriggerCallback("TalentUpdate", "player", unitInfo.talents, unitInfo, openRaidLib.UnitInfoManager.GetAllUnitsInfo()) - - --schedule send to the group - openRaidLib.Schedules.NewUniqueTimer(1 + math.random(0, 1), openRaidLib.UnitInfoManager.SendTalentUpdate, "UnitInfoManager", "sendTalent_Schedule") -end -openRaidLib.internalCallback.RegisterCallback("talentUpdate", openRaidLib.UnitInfoManager.OnPlayerTalentChanged) - -function openRaidLib.UnitInfoManager.OnReceiveTalentsUpdate(data, unitName) - local talentsTableUnpacked = openRaidLib.UnpackTable(data, 1, false, false, 7) --this 7 should be a constant - - local unitInfo = openRaidLib.UnitInfoManager.GetUnitInfo(unitName, true) - if (unitInfo) then - openRaidLib.UnitInfoManager.SetUnitInfo(unitName, unitInfo, nil, nil, nil, talentsTableUnpacked) - --trigger public callback event - openRaidLib.publicCallback.TriggerCallback("TalentUpdate", openRaidLib.GetUnitID(unitName), unitInfo.talents, unitInfo, openRaidLib.UnitInfoManager.GetAllUnitsInfo()) - end -end -openRaidLib.commHandler.RegisterComm(CONST_COMM_PLAYERINFO_TALENTS_PREFIX, openRaidLib.UnitInfoManager.OnReceiveTalentsUpdate) - ---pvp talent update (when the player changes a pvp talent and the lib needs to notify other players in the group) -function openRaidLib.UnitInfoManager.SendPvPTalentUpdate() - --pvp talents - local playerName = UnitName("player") - local unitInfo = openRaidLib.UnitInfoManager.GetUnitInfo(playerName, true) - local pvpTalentsToSend = unitInfo.pvpTalents - local pvpTalentsString = openRaidLib.PackTable(pvpTalentsToSend) - - local dataToSend = "" .. CONST_COMM_PLAYERINFO_PVPTALENTS_PREFIX .. "," - dataToSend = dataToSend .. pvpTalentsString - - --send the data - openRaidLib.commHandler.SendCommData(dataToSend) - diagnosticComm("SendPvPTalentUpdateData| " .. dataToSend) --debug -end - -function openRaidLib.UnitInfoManager.OnPlayerPvPTalentChanged() - --update the local player - local playerName = UnitName("player") - local unitInfo = openRaidLib.UnitInfoManager.GetUnitInfo(playerName, true) - openRaidLib.UnitInfoManager.SetUnitInfo(playerName, unitInfo, nil, nil, nil, nil, nil, openRaidLib.UnitInfoManager.GetPlayerPvPTalents()) + openRaidLib.publicCallback.TriggerCallback("TalentUpdate", "player", unitInfo.talents, unitInfo, UnitInfoManager.GetAllUnitsInfo()) --schedule send to the group - openRaidLib.Schedules.NewUniqueTimer(1 + math.random(0, 1), openRaidLib.UnitInfoManager.SendPvPTalentUpdate, "UnitInfoManager", "sendPvPTalent_Schedule") - - --trigger public callback event - openRaidLib.publicCallback.TriggerCallback("PvPTalentUpdate", "player", unitInfo.pvpTalents, unitInfo, openRaidLib.UnitInfoManager.GetAllUnitsInfo()) -end -openRaidLib.internalCallback.RegisterCallback("pvpTalentUpdate", openRaidLib.UnitInfoManager.OnPlayerPvPTalentChanged) - -function openRaidLib.UnitInfoManager.OnReceivePvPTalentsUpdate(data, unitName) - local pvpTalentsTableUnpacked = openRaidLib.UnpackTable(data, 1, false, false, 3) --this 3 should be a constant - - local unitInfo = openRaidLib.UnitInfoManager.GetUnitInfo(unitName, true) - if (unitInfo) then - unitInfo.pvpTalents = pvpTalentsTableUnpacked - --trigger public callback event - openRaidLib.publicCallback.TriggerCallback("PvPTalentUpdate", openRaidLib.GetUnitID(unitName), unitInfo.pvpTalents, unitInfo, openRaidLib.UnitInfoManager.GetAllUnitsInfo()) - end + openRaidLib.Schedules.NewUniqueTimer(2 + math.random(0, 1), UnitInfoManager.SendAllPlayerInfo, "UnitInfoManager", "sendAllPlayerInfo_Schedule") end -openRaidLib.commHandler.RegisterComm(CONST_COMM_PLAYERINFO_PVPTALENTS_PREFIX, openRaidLib.UnitInfoManager.OnReceivePvPTalentsUpdate) +openRaidLib.internalCallback.RegisterCallback("talentUpdate", UnitInfoManager.OnPlayerTalentChanged) -function openRaidLib.UnitInfoManager.OnPlayerLeaveGroup() +function UnitInfoManager.OnPlayerLeaveGroup() local unitName = UnitName("player") --clear the data - openRaidLib.UnitInfoManager.EraseData() + UnitInfoManager.EraseData() --trigger a public callback - openRaidLib.publicCallback.TriggerCallback("UnitInfoWipe", openRaidLib.UnitInfoManager.UnitData) + openRaidLib.publicCallback.TriggerCallback("UnitInfoWipe", UnitInfoManager.UnitData) --need to build the player info again - local playerFullInfo = openRaidLib.UnitInfoManager.GetPlayerFullInfo() - openRaidLib.UnitInfoManager.AddUnitInfo(unitName, unpack(playerFullInfo)) + local playerFullInfo = UnitInfoManager.GetPlayerFullInfo() + UnitInfoManager.AddUnitInfo(unitName, unpack(playerFullInfo)) end -openRaidLib.internalCallback.RegisterCallback("onLeaveGroup", openRaidLib.UnitInfoManager.OnPlayerLeaveGroup) +openRaidLib.internalCallback.RegisterCallback("onLeaveGroup", UnitInfoManager.OnPlayerLeaveGroup) --send data when leaving combat -function openRaidLib.UnitInfoManager.SendPlayerInfoAfterCombat() - openRaidLib.UnitInfoManager.SendAllPlayerInfo() +function UnitInfoManager.SendPlayerInfoAfterCombat() + openRaidLib.Schedules.NewUniqueTimer(2 + math.random(0, 1), UnitInfoManager.SendAllPlayerInfo, "UnitInfoManager", "sendAllPlayerInfo_Schedule") end -function openRaidLib.UnitInfoManager.OnLeaveCombat() - openRaidLib.Schedules.NewUniqueTimer(1 + math.random(1, 4), openRaidLib.UnitInfoManager.SendPlayerInfoAfterCombat, "UnitInfoManager", "leaveCombat_Schedule") + +function UnitInfoManager.OnLeaveCombat() + openRaidLib.Schedules.NewUniqueTimer(1 + math.random(1, 4), UnitInfoManager.SendPlayerInfoAfterCombat, "UnitInfoManager", "leaveCombat_Schedule") end -openRaidLib.internalCallback.RegisterCallback("onLeaveCombat", openRaidLib.UnitInfoManager.OnLeaveCombat) +openRaidLib.internalCallback.RegisterCallback("onLeaveCombat", UnitInfoManager.OnLeaveCombat) -------------------------------------------------------------------------------------------------------------------------------- diff --git a/Libs/LibOpenRaid/ThingsToMantain_WarWithin.lua b/Libs/LibOpenRaid/ThingsToMantain_WarWithin.lua index 17fc9785e..c4e69dda8 100644 --- a/Libs/LibOpenRaid/ThingsToMantain_WarWithin.lua +++ b/Libs/LibOpenRaid/ThingsToMantain_WarWithin.lua @@ -359,7 +359,7 @@ do [184364] = {cooldown = 120, duration = 8, specs = {72}, talent = false, charges = 1, class = "WARRIOR", type = 2}, --Enraged Regeneration [5246] = {cooldown = 90, duration = 8, specs = {71, 72, 73}, talent = false, charges = 1, class = "WARRIOR", type = 8}, --Intimidating Shout [12975] = {cooldown = 180, duration = 15, specs = {73}, talent = false, charges = 1, class = "WARRIOR", type = 2}, --Last Stand - [97462] = {cooldown = 180, duration = 10, specs = {71, 72, 73}, talent = false, charges = 1, class = "WARRIOR", type = 4, cdtype = "DR"}, --Rallying Cry + [97462] = {cooldown = 180, duration = 10, specs = {71, 72, 73}, talent = false, charges = 1, class = "WARRIOR", type = 4, cdtype = "DR", nostack = true}, --Rallying Cry. No Stack means that casting two rallying cries at the same time, won't duplicate the effect [152277] = {cooldown = 60, duration = 6, specs = {71}, talent = false, charges = 1, class = "WARRIOR", type = 1}, --Ravager [228920] = {cooldown = 60, duration = 6, specs = {73}, talent = false, charges = 1, class = "WARRIOR", type = 1}, --Ravager [1719] = {cooldown = 90, duration = 10, specs = {72}, talent = false, charges = 1, class = "WARRIOR", type = 1}, --Recklessness @@ -539,7 +539,7 @@ do [132469] = {cooldown = 30, duration = 0, specs = {102, 103, 104, 105}, talent = false, charges = 1, class = "DRUID", type = 8}, --Typhoon [102793] = {cooldown = 60, duration = 10, specs = {102, 103, 104, 105}, talent = false, charges = 1, class = "DRUID", type = 8}, --Ursol's Vortex [124974] = {cooldown = 90, duration = 0, specs = {102, 103, 104, 105}, talent = false, charges = 1, class = "DRUID", type = 4}, --Nature's Vigil - [77761] = {cooldown = 120, duration = 8, specs = {102, 103, 104, 105}, talent = false, charges = 1, class = "DRUID", type = 5, cdtype = "SPEED"}, --Stampeding Roar + [77761] = {cooldown = 120, duration = 8, specs = {102, 103, 104, 105}, talent = false, charges = 1, class = "DRUID", type = 5, cdtype = "SPEED", nostack = true}, --Stampeding Roar --[106898] = {cooldown = 120, duration = 8, specs = {102, 103, 104, 105}, talent = false, charges = 1, class = "DRUID", type = 5}, --Stampeding Roar --[77764] = {cooldown = 120, duration = 8, specs = {102, 103, 104, 105}, talent = false, charges = 1, class = "DRUID", type = 5}, --Stampeding Roar [5211] = {cooldown = 60, duration = 0, specs = {}, talent = false, charges = 1, class = "DRUID", type = 8}, --Mighty Bash @@ -732,7 +732,8 @@ do --[403208] = {cooldown = 0, duration = 0, specs = {1473}, talent = false, charges = 1, class = "EVOKER", type = 0}, --Draconic Attunements --[403264] = {cooldown = 3, duration = 0, specs = {1473}, talent = false, charges = 1, class = "EVOKER", type = 0}, --Black Attunement --[403265] = {cooldown = 3, duration = 0, specs = {1473}, talent = false, charges = 1, class = "EVOKER", type = 0}, --Bronze Attunement - [403631] = {cooldown = 120, duration = 0, specs = {1473}, talent = false, charges = 1, class = "EVOKER", type = 1}, --Breath of Eons + --[403631] = {cooldown = 120, duration = 0, specs = {1473}, talent = false, charges = 1, class = "EVOKER", type = 1}, --Breath of Eons + [442204] = {cooldown = 120, duration = 0, specs = {1473}, talent = false, charges = 1, class = "EVOKER", type = 1}, --Breath of Eons [404977] = {cooldown = 180, duration = 0, specs = {1473}, talent = false, charges = 1, class = "EVOKER", type = 1}, --Time Skip [406732] = {cooldown = 120, duration = 0, specs = {1473}, talent = false, charges = 1, class = "EVOKER", type = 3}, --Spatial Paradox [408233] = {cooldown = 60, duration = 0, specs = {1473}, talent = false, charges = 1, class = "EVOKER", type = 5}, --Bestow Weyrnstone diff --git a/Libs/LibOpenRaid/docs.txt b/Libs/LibOpenRaid/docs.txt index 543b9d2e6..1f8a986dc 100644 --- a/Libs/LibOpenRaid/docs.txt +++ b/Libs/LibOpenRaid/docs.txt @@ -109,14 +109,12 @@ unitInfo = { .specId = number .specName = string .role = string - .renown = number - .covenantId = number - .talents = {talentId, talentId, talentId, ...} + .heroTalentId = number + .talents = dragonflight talent string, e.g: "CkGAvcQZXENQPQXqed372Hg2KuxMzssYmZmZWegZZYGjFGLjZAAAAAAAAAAAAsBDzwYGNzAmxYmxgplZGAAAAAwAAAgltxGmmZWGCAABsgZmBA" .pvpTalents = {talentId, talentId, talentId} - .conduits = {spellId, conduitLevel, spellId, conduitLevel, spellId, conduitLevel, ...} .class = string class eng name 'ROGUE' .classId = number - .className = string class localized name + .className = string class localized name 'Rogue' .name = string name without realm .nameFull = string name with realm 'unitName-ServerName' } @@ -369,11 +367,9 @@ function MyAddonObject.OnUnitUpdate(unitId, unitInfo, allUnitsInfo) local specId = unitInfo.specId local specName = unitInfo.specName local role = unitInfo.role - local renown = unitInfo.renown - local covenantId = unitInfo.covenantId + local heroTalentId = unitInfo.heroTalentId local talents = unitInfo.talents local pvpTalents = unitInfo.pvpTalents - local conduits = unitInfo.conduits local class = unitInfo.class = string class eng name 'ROGUE' local classId = unitInfo.classId = number local className = unitInfo.className @@ -399,35 +395,13 @@ openRaidLib.RegisterCallback(MyAddonObject, "UnitInfoWipe", "OnUnitInfoWipe") Note: a "UnitUpdate" callback is triggered right after this event to notify the player info is updated. =================================================================================================================================== -"TalentUpdate": when a unit changed a talent +"TalentUpdate": when a unit changed a talent | DEPRECATRED | Use: OnUnitUpdate =================================================================================================================================== -function MyAddonObject.OnTalentUpdate(unitId, talents, unitInfo, allUnitsInfo) - for i = 1, 7 do - local talentId = talents[i] - local talentID, talentName, texture, selected, available = GetTalentInfoByID(talentId) - print(talentName) - end -end - ---registering the callback: -openRaidLib.RegisterCallback(MyAddonObject, "TalentUpdate", "OnTalentUpdate") - =================================================================================================================================== -"PvPTalentUpdate": when an unit changed a pvp talent +"PvPTalentUpdate": when an unit changed a pvp talent | DEPRECATRED | Use: OnUnitUpdate =================================================================================================================================== -function MyAddonObject.OnPvPTalentUpdate(unitId, pvpTalents, unitInfo, allUnitsInfo) - for i = 1, 3 do - local talentId = pvpTalents[i] - local talentID, talentName, icon, selected, available, spellID, unlocked, row, column, known, grantedByAura = GetPvpTalentInfoByID(talentId) - print(talentName) - end -end - ---registering the callback: -openRaidLib.RegisterCallback(MyAddonObject, "PvPTalentUpdate", "OnPvPTalentUpdate") - =================================================================================================================================== "UnitDeath": when an unit died =================================================================================================================================== diff --git a/boot.lua b/boot.lua index b75e64c01..0cdad292d 100644 --- a/boot.lua +++ b/boot.lua @@ -15,12 +15,10 @@ if (__details_debug.prescience_timeline) then wipe(__details_debug.prescience_timeline) end - local addonName, Details222 = ... local version, build, date, tvs = GetBuildInfo() - - Details.build_counter = 13191 - Details.alpha_build_counter = 13191 --if this is higher than the regular counter, use it instead + Details.build_counter = 13303 + Details.alpha_build_counter = 13303 --if this is higher than the regular counter, use it instead Details.dont_open_news = true Details.game_version = version Details.userversion = version .. " " .. Details.build_counter diff --git a/frames/window_scrolldamage.lua b/frames/window_scrolldamage.lua index 3d26c21a6..ab055ae37 100644 --- a/frames/window_scrolldamage.lua +++ b/frames/window_scrolldamage.lua @@ -1,6 +1,7 @@ local Details = _G.Details +---@type detailsframework local DF = _G.DetailsFramework local _, Details222 = ... _ = nil @@ -8,7 +9,7 @@ local _GetSpellInfo = Details.GetSpellInfo function Details:ScrollDamage() if (not DetailsScrollDamage) then - DetailsScrollDamage = DetailsFramework:CreateSimplePanel(UIParent) + DetailsScrollDamage = DF:CreateSimplePanel(UIParent) DetailsScrollDamage:SetSize(427 - 40 - 20 - 20, 505 - 150 + 20 + 40) DetailsScrollDamage:SetTitle("/details scroll") DetailsScrollDamage.Data = {} @@ -18,7 +19,7 @@ function Details:ScrollDamage() DetailsScrollDamage.Title:SetPoint("center", DetailsScrollDamage.TitleBar, "center", 108, 0) - DetailsFramework:ApplyStandardBackdrop(DetailsScrollDamage) + DF:ApplyStandardBackdrop(DetailsScrollDamage) local scroll_width = 395 - 40 - 20 - 20 local scroll_height = 340 @@ -30,7 +31,7 @@ function Details:ScrollDamage() local backdrop_color_is_critical = {.4, .4, .2, 0.2} local backdrop_color_is_critical_on_enter = {1, 1, .8, 0.4} - local dropdownTemplate = DetailsFramework:GetTemplate("dropdown", "OPTIONS_DROPDOWNDARK_TEMPLATE") + local dropdownTemplate = DF:GetTemplate("dropdown", "OPTIONS_DROPDOWNDARK_TEMPLATE") local y = -15 local headerY = y - 15 @@ -52,7 +53,7 @@ function Details:ScrollDamage() LibWindow.MakeDraggable(DetailsScrollDamage) LibWindow.RestorePosition(DetailsScrollDamage) - local scaleBar = DetailsFramework:CreateScaleBar(DetailsScrollDamage, Details.damage_scroll_position) + local scaleBar = DF:CreateScaleBar(DetailsScrollDamage, Details.damage_scroll_position) DetailsScrollDamage:SetScale(Details.damage_scroll_position.scale) --header @@ -67,7 +68,7 @@ function Details:ScrollDamage() padding = 2, } - DetailsScrollDamage.Header = DetailsFramework:CreateHeader(DetailsScrollDamage, headerTable, headerOptions) + DetailsScrollDamage.Header = DF:CreateHeader(DetailsScrollDamage, headerTable, headerOptions) DetailsScrollDamage.Header:SetPoint("topleft", DetailsScrollDamage, "topleft", 5, headerY) DetailsScrollDamage.searchText = "" DetailsScrollDamage.searchCache = {} @@ -171,7 +172,7 @@ function Details:ScrollDamage() iconFrame:SetScript("OnLeave", lineOnLeave) --spellname - local spellNameText = DetailsFramework:CreateTextEntry(line, function()end, DetailsScrollDamage.Header:GetColumnWidth(2), scroll_line_height, _, _, _, dropdownTemplate) + local spellNameText = DF:CreateTextEntry(line, function()end, DetailsScrollDamage.Header:GetColumnWidth(2), scroll_line_height, _, _, _, dropdownTemplate) --damage local damageText = DF:CreateLabel(line, "", fontSize, "white") @@ -180,7 +181,7 @@ function Details:ScrollDamage() local timeText = DF:CreateLabel(line, "", fontSize, "white") --spell ID - local spellIDText = DetailsFramework:CreateTextEntry(line, function()end, DetailsScrollDamage.Header:GetColumnWidth(5), scroll_line_height, _, _, _, dropdownTemplate) + local spellIDText = DF:CreateTextEntry(line, function()end, DetailsScrollDamage.Header:GetColumnWidth(5), scroll_line_height, _, _, _, dropdownTemplate) line:AddFrameToHeaderAlignment(icon) line:AddFrameToHeaderAlignment(spellNameText) @@ -271,11 +272,11 @@ function Details:ScrollDamage() local onToggleAutoOpen = function(_, _, state) Details.damage_scroll_auto_open = state end - local autoOpenCheckbox = DetailsFramework:CreateSwitch(statusBar, onToggleAutoOpen, Details.auto_open_news_window, _, _, _, _, "AutoOpenCheckbox", _, _, _, _, _, DetailsFramework:GetTemplate("switch", "OPTIONS_CHECKBOX_BRIGHT_TEMPLATE")) + local autoOpenCheckbox = DF:CreateSwitch(statusBar, onToggleAutoOpen, Details.auto_open_news_window, _, _, _, _, "AutoOpenCheckbox", _, _, _, _, _, DF:GetTemplate("switch", "OPTIONS_CHECKBOX_BRIGHT_TEMPLATE")) autoOpenCheckbox:SetAsCheckBox() autoOpenCheckbox:SetPoint("left", statusBar, "left", 5, 0) - local autoOpenText = DetailsFramework:CreateLabel(statusBar, "Auto Open on Training Dummy", 10) + local autoOpenText = DF:CreateLabel(statusBar, "Auto Open on Training Dummy", 10) autoOpenText:SetPoint("left", autoOpenCheckbox, "right", 2, 0) --search bar @@ -316,7 +317,7 @@ targetDummieHandle:SetScript("OnEvent", function(_, _, unit) if (UnitExists("target")) then local serial = UnitGUID("target") if (serial) then - local npcId = DetailsFramework:GetNpcIdFromGuid(serial) + local npcId = DF:GetNpcIdFromGuid(serial) if (npcId) then if (targetDummiesIds[npcId]) then Details:ScrollDamage() diff --git a/luaserver.lua b/luaserver.lua index 9068d8c4d..b87aea902 100644 --- a/luaserver.lua +++ b/luaserver.lua @@ -492,7 +492,7 @@ BackdropTemplateMixin = {} ---@field GetRight fun(self: uiobject): number ---@field GetTop fun(self: uiobject): number ---@field GetBottom fun(self: uiobject): number ----@field SetPoint fun(self: uiobject, point: anchorpoint, relativeFrame: uiobject, relativePoint: anchorpoint, xOffset: number, yOffset: number) +---@field SetPoint fun(self: uiobject, point: anchorpoint, relativeFrame: uiobject?, relativePoint: anchorpoint?, xOffset: number?, yOffset: number?) ---@field ClearAllPoints fun(self: uiobject) ---@field CreateAnimationGroup fun(self: uiobject, name: string|nil, templateName: string|nil) : animationgroup ---@field SetIgnoreParentAlpha fun(self: region, ignore: boolean) @@ -668,9 +668,8 @@ BackdropTemplateMixin = {} ---@field ClearPointsOffset fun(self: frame) ---@field GetPoint fun(self: frame, anchorIndex: number?, resolveCollapsed: boolean?) : string, frame, string, number, number ---@field GetPointByName fun(self: frame, point: string, resolveCollapsed: boolean?) : string, frame, string, number, number ----@field SetAllPoints fun(self: frame, relativeTo: frame?, doResize: boolean?) +---@field SetAllPoints fun(self: frame, relativeTo: uiobject?, doResize: boolean?) ---@field SetHeight fun(self: frame, height: number) ----@field SetPoint fun(self: frame, point: string, relativeTo: frame?, relativePoint: string?, offsetX: number?, offsetY: number?) ---@field SetSize fun(self: frame, x: number, y: number) ---@field SetWidth fun(self: frame, width: number) ---@field CreateAnimationGroup fun(self: frame, name: string?, templateName: string?) : animationgroup