diff --git a/Libs/DF/addon.lua b/Libs/DF/addon.lua index 6ebf01154..8285d6dcc 100644 --- a/Libs/DF/addon.lua +++ b/Libs/DF/addon.lua @@ -34,20 +34,22 @@ local addonLoaded = function(addonFrame, event, addonName) local playerGUID = UnitGUID("player") --the guid points to a profile name ---@type table - local savedVariables = detailsFramework.SavedVars.GetSavedVariables(addonObject) + local tSavedVariables = detailsFramework.SavedVars.GetSavedVariables(addonObject) --check if the player has a profileId saved - local playerProfileId = savedVariables.profile_ids[playerGUID] - if (not playerProfileId) then - --it doesn't, set it to use the default profile - playerProfileId = CONST_DEFAULT_PROFILE_NAME - savedVariables.profile_ids[playerGUID] = playerProfileId + local profileId = tSavedVariables.profile_ids[playerGUID] + if (not profileId) then + --if it doesn't, set it to use the default profile + profileId = CONST_DEFAULT_PROFILE_NAME + tSavedVariables.profile_ids[playerGUID] = profileId end - local profileTable = detailsFramework.SavedVars.GetProfile(addonObject) + local bCreateIfNotFound = true + local profileTable = detailsFramework.SavedVars.GetProfile(addonObject, bCreateIfNotFound) + addonObject.profile = profileTable if (addonObject.OnLoad) then - detailsFramework:Dispatch(addonObject.OnLoad, addonObject, profileTable) + detailsFramework:Dispatch(addonObject.OnLoad, addonObject, addonObject.profile) end end @@ -56,8 +58,7 @@ local addonInit = function(addonFrame) local addonObject = addonFrame.__addonObject if (addonObject.OnInit) then - local profileTable = detailsFramework.SavedVars.GetProfile(addonObject) - detailsFramework:Dispatch(addonObject.OnInit, addonObject, profileTable) + detailsFramework:Dispatch(addonObject.OnInit, addonObject, addonObject.profile) end end diff --git a/Libs/DF/cooltip.lua b/Libs/DF/cooltip.lua index 416d09f6d..72db42ef9 100644 --- a/Libs/DF/cooltip.lua +++ b/Libs/DF/cooltip.lua @@ -50,6 +50,10 @@ function DF:CreateCoolTip() end end + function gameCooltip:Msg(...) + print("|cFFFFFF00Cooltip|r:", ...) + end + function gameCooltip:SetDebug(bDebugState) gameCooltip.debug = bDebugState end @@ -3459,7 +3463,7 @@ function DF:CreateCoolTip() local okay, errortext = pcall(host.CoolTip.BuildFunc, host, host.CoolTip and host.CoolTip.FixedValue) if (not okay) then - gameCooltip:PrintDebug("ExecFunc() injected function error:", errortext) + gameCooltip:Msg("ExecFunc() injected function error:", errortext) end gameCooltip:SetOwner(host, host.CoolTip.MyAnchor, host.CoolTip.HisAnchor, host.CoolTip.X, host.CoolTip.Y) diff --git a/Libs/DF/definitions.lua b/Libs/DF/definitions.lua index 603324290..597f15287 100644 --- a/Libs/DF/definitions.lua +++ b/Libs/DF/definitions.lua @@ -12,4 +12,5 @@ ---@field AddRoundedCornersToFrame fun(self:table, frame:frame, optionsTable:df_roundedpanel_preset?) ---@field ParseColors fun(self:table, red:any, green:number?, blue:number?, alpha:number?) : red, green, blue, alpha ---@field Mixin fun(self:table, target:table, ...) : table ----@field SetButtonTexture fun(self:table, button:button|df_button, texture:atlasname|texturepath|textureid) \ No newline at end of file +---@field SetButtonTexture fun(self:table, button:button|df_button, texture:atlasname|texturepath|textureid) +---@field CreateFadeAnimation fun(self:table, UIObject:uiobject, fadeInTime:number?, fadeOutTime:number?, fadeInAlpha:number?, fadeOutAlpha:number?) diff --git a/Libs/DF/fw.lua b/Libs/DF/fw.lua index e4d0385a1..37ef328d8 100644 --- a/Libs/DF/fw.lua +++ b/Libs/DF/fw.lua @@ -1,6 +1,6 @@ -local dversion = 454 +local dversion = 456 local major, minor = "DetailsFramework-1.0", dversion local DF, oldminor = LibStub:NewLibrary(major, minor) @@ -584,8 +584,11 @@ end function DF.table.removeduplicate(table1, table2) for key, value in pairs(table2) do if (type(value) == "table") then - if (table1[key]) then - DF.table.removeduplicate(value, table1[key]) + if (type(table1[key]) == "table") then + DF.table.removeduplicate(table1[key], value) + if (not next(table1[key])) then + table1[key] = nil + end end else if (type(table1[key]) == "number" and type(value) == "number") then @@ -619,10 +622,10 @@ end function DF.table.deploy(t1, t2) for key, value in pairs(t2) do if (type(value) == "table") then - t1 [key] = t1 [key] or {} - DF.table.deploy(t1 [key], t2 [key]) - elseif (t1 [key] == nil) then - t1 [key] = value + t1[key] = t1[key] or {} + DF.table.deploy(t1[key], t2[key]) + elseif (t1[key] == nil) then + t1[key] = value end end return t1 @@ -814,6 +817,7 @@ else end ---format a number with commas +---@param self table ---@param value number ---@return string function DF:CommaValue(value) @@ -832,6 +836,7 @@ function DF:CommaValue(value) end ---call the function 'callback' for each group member passing the unitID and the extra arguments +---@param self table ---@param callback function ---@vararg any function DF:GroupIterator(callback, ...) @@ -852,6 +857,7 @@ function DF:GroupIterator(callback, ...) end ---get an integer an format it as string with the time format 16:45 +---@param self table ---@param value number ---@return string function DF:IntegerToTimer(value) --~formattime @@ -859,6 +865,7 @@ function DF:IntegerToTimer(value) --~formattime end ---remove the realm name from a name +---@param self table ---@param name string ---@return string, number function DF:RemoveRealmName(name) @@ -866,6 +873,7 @@ function DF:RemoveRealmName(name) end ---remove the owner name of the pet or guardian +---@param self table ---@param name string ---@return string, number function DF:RemoveOwnerName(name) @@ -873,6 +881,7 @@ function DF:RemoveOwnerName(name) end ---remove realm and owner names also remove brackets from spell actors +---@param self table ---@param name string ---@return string function DF:CleanUpName(name) @@ -883,6 +892,7 @@ function DF:CleanUpName(name) end ---remove the realm name from a name +---@param self table ---@param name string ---@return string, number function DF:RemoveRealName(name) @@ -890,6 +900,7 @@ function DF:RemoveRealName(name) end ---get the UIObject of type 'FontString' named fontString and set the font size to the maximum value of the arguments +---@param self table ---@param fontString fontstring ---@vararg number function DF:SetFontSize(fontString, ...) @@ -898,6 +909,7 @@ function DF:SetFontSize(fontString, ...) end ---get the UIObject of type 'FontString' named fontString and set the font to the argument fontface +---@param self table ---@param fontString fontstring ---@param fontface string function DF:SetFontFace(fontString, fontface) @@ -911,24 +923,26 @@ function DF:SetFontFace(fontString, fontface) end ---get the FontString passed and set the font color +---@param self table ---@param fontString fontstring ---@param r any ----@param g number|nil ----@param b number|nil ----@param a number|nil +---@param g number? +---@param b number? +---@param a number? function DF:SetFontColor(fontString, r, g, b, a) r, g, b, a = DF:ParseColors(r, g, b, a) fontString:SetTextColor(r, g, b, a) end ---get the FontString passed and set the font shadow color and offset +---@param self table ---@param fontString fontstring ----@param r number ----@param g number ----@param b number ----@param a number ----@param x number ----@param y number +---@param r any +---@param g number? +---@param b number? +---@param a number? +---@param x number? +---@param y number? function DF:SetFontShadow(fontString, r, g, b, a, x, y) r, g, b, a = DF:ParseColors(r, g, b, a) fontString:SetShadowColor(r, g, b, a) @@ -941,6 +955,7 @@ function DF:SetFontShadow(fontString, r, g, b, a, x, y) end ---get the FontString object passed and set the rotation of the text shown +---@param self table ---@param fontString fontstring ---@param degrees number function DF:SetFontRotation(fontString, degrees) @@ -958,6 +973,7 @@ function DF:SetFontRotation(fontString, degrees) end ---receives a string and a color and return the string wrapped with the color using |c and |r scape codes +---@param self table ---@param text string ---@param color any ---@return string @@ -975,6 +991,7 @@ function DF:AddColorToText(text, color) --wrap text with a color end ---receives a string 'text' and a class name and return the string wrapped with the class color using |c and |r scape codes +---@param self table ---@param text string ---@param className string ---@return string @@ -997,6 +1014,7 @@ function DF:AddClassColorToText(text, className) end ---create a string with the spell icon and the spell name using |T|t scape codes to add the icon inside the string +---@param self table ---@param spellId any ---@return string function DF:MakeStringFromSpellId(spellId) @@ -3401,6 +3419,11 @@ end ----------------------------- --animations +---create an animation 'hub' which is an animationGroup but with some extra functions +---@param parent uiobject +---@param onPlay function? +---@param onFinished function? +---@return animationgroup function DF:CreateAnimationHub(parent, onPlay, onFinished) local newAnimation = parent:CreateAnimationGroup() newAnimation:SetScript("OnPlay", onPlay) @@ -3443,6 +3466,38 @@ function DF:CreateAnimation(animation, animationType, order, duration, arg1, arg return anim end +---receives an uiobject, when its parent get hover overed, starts the fade in animation +---start the fade out animation when the mouse leaves the parent +---@param UIObject uiobject +---@param fadeInTime number +---@param fadeOutTime number +---@param fadeInAlpha number +---@param fadeOutAlpha number +function DF:CreateFadeAnimation(UIObject, fadeInTime, fadeOutTime, fadeInAlpha, fadeOutAlpha) + fadeInTime = fadeInTime or 0.1 + fadeOutTime = fadeOutTime or 0.1 + fadeInAlpha = fadeInAlpha or 1 + fadeOutAlpha = fadeOutAlpha or 0 + + local fadeInAnimationHub = DF:CreateAnimationHub(UIObject, function() UIObject:Show(); UIObject:SetAlpha(fadeOutAlpha) end, function() UIObject:SetAlpha(fadeInAlpha) end) + local fadeIn = DF:CreateAnimation(fadeInAnimationHub, "Alpha", 1, fadeInTime, fadeOutAlpha, fadeInAlpha) + + local fadeOutAnimationHub = DF:CreateAnimationHub(UIObject, nil, function() UIObject:Hide(); UIObject:SetAlpha(0) end) + local fadeOut = DF:CreateAnimation(fadeOutAnimationHub, "Alpha", 2, fadeOutTime, fadeInAlpha, fadeOutAlpha) + + local scriptFrame + --hook the parent OnEnter and OnLeave + if (UIObject:IsObjectType("FontString") or UIObject:IsObjectType("Texture")) then + scriptFrame = UIObject:GetParent() + else + scriptFrame = UIObject + end + + ---@cast scriptFrame frame + scriptFrame:HookScript("OnEnter", function() fadeOutAnimationHub:Stop(); fadeInAnimationHub:Play() end) + scriptFrame:HookScript("OnLeave", function() fadeInAnimationHub:Stop(); fadeOutAnimationHub:Play() end) +end + ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ --frame shakes @@ -3475,7 +3530,6 @@ FrameshakeUpdateFrame:SetScript("OnUpdate", function(self, deltaTime) end end) - local frameshake_ShakeFinished = function(parent, shakeObject) if (shakeObject.IsPlaying) then shakeObject.IsPlaying = false @@ -3545,7 +3599,6 @@ frameshake_DoUpdate = function(parent, shakeObject, deltaTime) local scaleShake = min(shakeObject.IsFadingIn and (shakeObject.IsFadingInTime / shakeObject.FadeInTime) or 1, shakeObject.IsFadingOut and (1 - shakeObject.IsFadingOutTime / shakeObject.FadeOutTime) or 1) if (scaleShake > 0) then - --delate the time by the frequency on both X and Y offsets shakeObject.XSineOffset = shakeObject.XSineOffset + (deltaTime * shakeObject.Frequency) shakeObject.YSineOffset = shakeObject.YSineOffset + (deltaTime * shakeObject.Frequency) @@ -3577,12 +3630,9 @@ frameshake_DoUpdate = function(parent, shakeObject, deltaTime) elseif (#anchor == 5) then local anchorName1, anchorTo, anchorName2, point1, point2 = unpack(anchor) - --parent:ClearAllPoints() - parent:SetPoint(anchorName1, anchorTo, anchorName2, point1 + newX, point2 + newY) end end - end else frameshake_ShakeFinished(parent, shakeObject) @@ -3666,7 +3716,7 @@ local frameshake_play = function(parent, shakeObject, scaleDirection, scaleAmpli frameshake_DoUpdate(parent, shakeObject) end -local frameshake_SetConfig = function(parent, shakeObject, duration, amplitude, frequency, absoluteSineX, absoluteSineY, scaleX, scaleY, fadeInTime, fadeOutTime, anchorPoints) +local frameshake_SetConfig = function(parent, shakeObject, duration, amplitude, frequency, absoluteSineX, absoluteSineY, scaleX, scaleY, fadeInTime, fadeOutTime) shakeObject.Amplitude = amplitude or shakeObject.Amplitude shakeObject.Frequency = frequency or shakeObject.Frequency shakeObject.Duration = duration or shakeObject.Duration @@ -3690,8 +3740,41 @@ local frameshake_SetConfig = function(parent, shakeObject, duration, amplitude, shakeObject.OriginalDuration = shakeObject.Duration end +---@class frameshake : table +---@field Amplitude number +---@field Frequency number +---@field Duration number +---@field FadeInTime number +---@field FadeOutTime number +---@field ScaleX number +---@field ScaleY number +---@field AbsoluteSineX boolean +---@field AbsoluteSineY boolean +---@field IsPlaying boolean +---@field TimeLeft number +---@field OriginalScaleX number +---@field OriginalScaleY number +---@field OriginalFrequency number +---@field OriginalAmplitude number +---@field OriginalDuration number +---@field PlayFrameShake fun(parent:uiobject, shakeObject:frameshake, scaleDirection:number?, scaleAmplitude:number?, scaleFrequency:number?, scaleDuration:number?) +---@field StopFrameShake fun(parent:uiobject, shakeObject:frameshake) +---@field SetFrameShakeSettings fun(parent:uiobject, shakeObject:frameshake, duration:number?, amplitude:number?, frequency:number?, absoluteSineX:boolean?, absoluteSineY:boolean?, scaleX:number?, scaleY:number?, fadeInTime:number?, fadeOutTime:number?) + +---create a frame shake object +---@param parent uiobject +---@param duration number? +---@param amplitude number? +---@param frequency number? +---@param absoluteSineX boolean? +---@param absoluteSineY boolean? +---@param scaleX number? +---@param scaleY number? +---@param fadeInTime number? +---@param fadeOutTime number? +---@param anchorPoints table? +---@return frameshake function DF:CreateFrameShake(parent, duration, amplitude, frequency, absoluteSineX, absoluteSineY, scaleX, scaleY, fadeInTime, fadeOutTime, anchorPoints) - --create the shake table local frameShake = { Amplitude = amplitude or 2, diff --git a/Libs/DF/savedvars.lua b/Libs/DF/savedvars.lua index 11acdbb5f..437924a09 100644 --- a/Libs/DF/savedvars.lua +++ b/Libs/DF/savedvars.lua @@ -11,83 +11,78 @@ local CONST_DEFAULT_PROFILE_NAME = "default" local UnitGUID = UnitGUID +---@alias profileid string the profile id is the name of the profile, by default it has the name "default" + --create namespace detailsFramework.SavedVars = {} ---get the saved variables table for the addon ----@param addonObject df_addon the addon frame created by detailsFramework:CreateNewAddOn() +---@param addonObject df_addon the addon object created by detailsFramework:CreateNewAddOn() ---@return table function detailsFramework.SavedVars.GetSavedVariables(addonObject) - assert(type(addonObject) == "table", "SetProfile: addonObject must be a table.") + assert(type(addonObject) == "table", "GetSavedVariables: addonObject must be a table.") if (addonObject.__savedGlobalVarsName) then - local savedVariables = _G[addonObject.__savedGlobalVarsName] + local savedVariablesTable = _G[addonObject.__savedGlobalVarsName] --check if the saved variables table is created, if not create one - if (not savedVariables) then + if (not savedVariablesTable) then --first run if (addonObject.__savedVarsDefaultTemplate) then - savedVariables = { - profiles = { - --store profiles created from the 'savedVarsTemplate' - [CONST_DEFAULT_PROFILE_NAME] = detailsFramework.table.deploy({}, addonObject.__savedVarsDefaultTemplate) - }, - profile_ids = {} --store the profile id for each character using its GUID + savedVariablesTable = { + --store profiles created from the 'savedVarsTemplate' + --[CONST_DEFAULT_PROFILE_NAME] = detailsFramework.table.deploy({}, addonObject.__savedVarsDefaultTemplate) + ---@type table + profiles = {}, --store profiles between game sessions + ---@type table + profile_ids = {} --points which profileid the player is using by storing the player GUID as the key and the profileid as the value } else - savedVariables = {} + savedVariablesTable = {} end --set the table to be global savedVariables - _G[addonObject.__savedGlobalVarsName] = savedVariables - end - - if (not savedVariables.profiles) then - savedVariables.profiles = { - profiles = { - --store profiles created from the 'savedVarsTemplate' - [CONST_DEFAULT_PROFILE_NAME] = detailsFramework.table.deploy({}, addonObject.__savedVarsDefaultTemplate) - } - } - end - - if (not savedVariables.profile_ids) then - savedVariables.profile_ids = {} + _G[addonObject.__savedGlobalVarsName] = savedVariablesTable end - return savedVariables + return savedVariablesTable end return {} end ----@param addonObject df_addon the addon frame created by detailsFramework:CreateNewAddOn() ----@param bCreateIfNotFound boolean|nil if true, create the profile if it doesn't exist ----@param profileToCopyFrom profile|nil if bCreateIfNotFound is true, copy the profile from this profile +---@param addonObject df_addon the addon object created by detailsFramework:CreateNewAddOn() +---@param bCreateIfNotFound boolean? if true, create the profile if it doesn't exist +---@param profileToCopyFrom profile? if bCreateIfNotFound is true, copy the profile from this profile function detailsFramework.SavedVars.GetProfile(addonObject, bCreateIfNotFound, profileToCopyFrom) assert(type(addonObject) == "table", "GetProfile: addonObject must be a table.") + local playerGUID = UnitGUID("player") local savedVariables = detailsFramework.SavedVars.GetSavedVariables(addonObject) - local playerProfileName = savedVariables.profile_ids[UnitGUID("player")] --get the profile name from the player guid - local profileTable = savedVariables.profiles[playerProfileName] + local profileId = savedVariables.profile_ids[playerGUID] --get the profile name from the player guid + local profileTable = savedVariables.profiles[profileId] if (not profileTable and bCreateIfNotFound) then profileTable = {} if (profileToCopyFrom) then + assert(type(profileToCopyFrom) == "table", "GetProfile: profileToCopyFrom must be a table (or nil).") --profileToCopyFrom has been cleaned at this point and only have values set by the user profileTable = detailsFramework.table.deploy(profileTable, profileToCopyFrom) end + end + if (profileTable and not profileTable.__loaded and addonObject.__savedVarsDefaultTemplate) then --as deploy does not overwrite existing values, it won't overwrite the values set by 'profileToCopyFrom' profileTable = detailsFramework.table.deploy(profileTable, addonObject.__savedVarsDefaultTemplate) - savedVariables.profiles[playerProfileName] = profileTable + --mark the profile as loaded + profileTable.__loaded = true end return profileTable end ----@param addonObject df_addon the addon frame created by detailsFramework:CreateNewAddOn() +---@param addonObject df_addon the addon object created by detailsFramework:CreateNewAddOn() ---@param profileName profilename the name of the profile to set ---@param bCopyFromCurrentProfile boolean if true, copy the current profile to the new profile function detailsFramework.SavedVars.SetProfile(addonObject, profileName, bCopyFromCurrentProfile) @@ -97,7 +92,9 @@ function detailsFramework.SavedVars.SetProfile(addonObject, profileName, bCopyFr ---@type profile local currentProfile = detailsFramework.SavedVars.GetProfile(addonObject) --save the current profile - detailsFramework.SavedVars.SaveProfile(addonObject) + if (addonObject.profile) then + detailsFramework.SavedVars.SaveProfile(addonObject) + end --set the new profile local savedVariables = detailsFramework.SavedVars.GetSavedVariables(addonObject) @@ -109,6 +106,7 @@ function detailsFramework.SavedVars.SetProfile(addonObject, profileName, bCopyFr --get the new profile creating if doesn't exist ---@type profile local profileTable = detailsFramework.SavedVars.GetProfile(addonObject, bCreateIfNotFound, bCopyFromCurrentProfile and currentProfile or nil) + addonObject.profile = profileTable if (addonObject.OnProfileChanged) then detailsFramework:Dispatch(addonObject.OnProfileChanged, addonObject, profileTable) @@ -117,16 +115,27 @@ end ---@param addonObject df_addon the addon frame created by detailsFramework:CreateNewAddOn() function detailsFramework.SavedVars.SaveProfile(addonObject) - assert(type(addonObject) == "table", "SetProfile: addonObject must be a table.") + assert(type(addonObject) == "table", "SaveProfile: addonObject must be a table.") --the current profile in use - local profileTable = detailsFramework.SavedVars.GetProfile(addonObject) - --profile template or "default profile" - local profileTemplate = addonObject.__savedVarsDefaultTemplate - - --if the addon has a default template, remove the keys which are the same as the default template - --these keys haven't been changed by the user, hence doesn't need to save them - if (profileTemplate) then - detailsFramework.table.removeduplicate(profileTable, addonObject.__savedVarsDefaultTemplate) + local profileTable = rawget(addonObject, "profile") + if (profileTable) then + if (profileTable.__loaded) then + --profile template (default profile) + local profileTemplate = addonObject.__savedVarsDefaultTemplate + + --if the addon has a default template, remove the keys which are the same as the default template + --these keys haven't been changed by the user, hence doesn't need to save them + if (profileTemplate) then + detailsFramework.table.removeduplicate(profileTable, addonObject.__savedVarsDefaultTemplate) + end + + profileTable.__loaded = nil --remove the __loaded key + + local savedVariables = detailsFramework.SavedVars.GetSavedVariables(addonObject) + local playerGUID = UnitGUID("player") + local playerProfileId = savedVariables.profile_ids[playerGUID] --"default" by default + savedVariables.profiles[playerProfileId] = profileTable + end end end \ No newline at end of file diff --git a/boot.lua b/boot.lua index 78818b258..d0a966d7f 100644 --- a/boot.lua +++ b/boot.lua @@ -13,8 +13,8 @@ local addonName, Details222 = ... local version, build, date, tocversion = GetBuildInfo() - Details.build_counter = 11774 - Details.alpha_build_counter = 11774 --if this is higher than the regular counter, use it instead + Details.build_counter = 11855 + Details.alpha_build_counter = 11855 --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 @@ -142,6 +142,87 @@ do --]=] local news = { + {"v10.1.0.11022.151", "July 11th, 2023"}, + "Added: Hovering over the Augmented Evoker icon shows the Evoker's damage, along with an estimated damage done by its buffs.", + "Auras tab at the Breakdown Window, now shows damage buffs received from other players (Ebon Might, Precience and Power Infusion).", + "Auras tab now ignores regular 'world auras' (those weekly buffs of reputation, etc).", + "Added individual bar for Neltharus Weapons. Weapons on final boss and the Burning Chain (Flamanis).", + "Update interval is set to 0.1 on arenas matches using the real-time dps feature.", + "Evoker's predicted damage done is now also shown in the overall data.", + "Removed 'Real Time DPS' from the time measure dropdown.", + "Added 'Show Real Time DPS' toggle to show real time dps while in combat.", + "Added 'Order Bars By Real Time DPS' toggle to order bars by the amount of real time dps.", + "Added 'Always Use Real Time in Arenas' toggle to always use real time dps in Arenas.", + "Fixed an issue where the Breakdown Window was not refreshing when the data was reset.", + "Fixed an issue where clicking on a plugin icon in the Details! title bar would not open the plugin.", + "Fixed bugs reported for the Encounter Details plugin.", + "Fixed bugs reported for the Real Time DPS.", + "Fixed Welcome Window sometimes not opening for new instalations (Flamanis).", + "*Combat start code verification cleanup (Flamanis).", + "*Added .last_dps_realtime to player actors, caches the latest real time dps calculated.", + "*Added: actordamage.total_extra for cases where there's a secondary bar for a damage actor.", + "*If any damage actor has 'total_extra' bigger than 0, the extra bar is shown.", + "*Added: Details:ShowExtraStatusbar(lineFrame, amount, extraAmount, totalAmount, topAmount, instanceObject, onEnterFunc, onLeaveFunc)", + "*Renamed 'InstaciaCallFunction' to 'InstanceCallDetailsFunc'.", + "*Renamed 'PegaHabilidade' to GetOrCreateSpell.", + "*Renamed 'PegarCombatente' to 'GetOrCreateActor'.", + "*List of spec names for spec tooltip detection now load at Startup not at lua compiling stage.", + "*Fixed custom displays ignoring actor.customColor.", + "*Details! Framework and LibOpenRaid upgrades.", + + {"v10.1.0.11022.151", "July 11th, 2023"}, + "Effective time is used when displaying tooltips information.", + "Wrap the specid name locatlization cache in a Details Framework check.", + "More fixes for real time dps.", + "Don't populate overall segment on load and force refresh window on segment swap.", + "Added: spec detection from the specialization name shown on tooltip.", + "Improvements to class detection by using GetPlayerInfoByGUID()", + "Removed Breath of Eons from spec detection for augmentation evokers.", + "When DBM/BW send a callback, check if the current combat in details is valid.", + "When the actor is considered a ungroupped player, check if that player has a spec and show the spec icon instead.", + "Segments locked don't swap windows to overall.", + "Use the new API 'SetSegment' over 'TrocaTabela' for the segment selector.", + "Sort damage taken tooltip on damage amount.", + "Added: Details:GetBossEncounterTexture(encounterName); Added combat.bossIcon; Added combat.bossTimers.", + "Added: Details:DoesCombatWithUIDExists(uniqueCombatId); Details:GetCombatByUID(uniqueCombatId); combat:GetCombatUID().", + "Added: Details:RemoveSegmentByCombatObject(combatObject).", + "Details:UnpackDeathTable(deathTable) now return the spec of the character as the last parameter returned.", + "classCombat:GetTimeData(chartName) now check if the combat has a TimeData table or return an empty table; Added classCombat:EraseTimeData(chartName).", + "Code for Dispel has been modernized, deathTable now includes the key .spec.", + "Added: key .unixtime into is_boss to know when the boss was killed.", + "Fixed an issue with auto run code not saving properly.", + "Ignore vessel periodic damage when out of combat.", + "More fixes for Augmentation Evoker on 10.1.5.", + "Another wave of code changes, modernizations and refactoring.", + "Combat Objects which has been discarded due to any reason will have the boolean member: __destroyed set to true. With this change, 3rd party code can see if the data cached is up to date or obsolete.", + "Removed several deprecated code from March 2023 and earlier.", + "Large amount of code cleanup and refactoring, some functions got renamed, they are listed below:", + "- 'TravarTempos' renamed to 'LockActivityTime'.", + "- 'ClearTempTables' renamed to 'ClearCacheTables'.", + "- 'SpellIsDot' renamed to 'SetAsDotSpell'.", + "- 'FlagCurrentCombat' remamed to 'FlagNewCombat_PVPState'.", + "- 'UpdateContainerCombatentes' renamed to 'UpdatePetCache'.", + "- 'segmentClass:AddCombat(combatObject)' renamed to 'Details222.Combat.AddCombat(combatToBeAdded)'.", + "- 'CurrentCombat.verifica_combate' timer is now obsolete.", + "- 'Details.last_closed_combat' is now obsolete.", + "- 'Details.EstaEmCombate' is now obsolete.", + "- 'Details.options' is now obsolete.", + "- Spec Guess Timers are now stored within Details222.GuessSpecSchedules.Schedules, all timers are killed at the end of the combat or at a data reset.", + "- Initial time delay to send the startup signal (event sent when details has started) reduced from 5 to 4 seconds.", + "- Fixed some division by zero on ptr 10.1.5.", + "- Fixed DETAILS_STARTED event not triggering in some cases due to 'event not registered'.", + "Fixed Auto Run Code window not closing by click on the close button.", + "Set up statusbar options instead of using metatable.", + "More code cleanup and framework updates.", + "TimeData code modernizations.", + "Implementations to show plugins in the breakdown window.", + "Damage Taken by Spell overhaul, now it uses modern Details API.", + "Time Machine overhaul.", + "Splitted the window_playerbreakdown_spells.lua into three more files.", + "Added IconTexture directive to the TOC files.", + "Disabled time captures for spellTables, this should be done by a plugin.", + "Replacing table.wipe with Details:Destroy().", + {"v10.1.0.11022.151", "May 20th, 2023"}, "Breakdown pet options has changed to: 'Group Pets by Their Names' or 'Group Pets by Their Spells'.", "Evoker empowered level now ocupies less space on the rectangle showing the damage by empower level.", @@ -1036,32 +1117,54 @@ do end end - --[=[ - for key, tooltip in pairs(_G) do - if (type(tooltip) == "table" and tooltip.GetName) then - if (tooltip.IsShown and tooltip.HookScript and not tooltip.widget and not tooltip.MyObject) then - if (tooltip.GetObjectType and not getmetatable(tooltip)) then - print(tooltip:GetObjectType()) - if (tooltip:GetObjectType() == "GameTooltip") then - if (tooltip:IsShown()) then - print(tooltip:GetName()) - end - end - end - end - end - end - --]=] - if (value == nil) then - local allTooltips = {"GameTooltip", "EventTraceTooltip", "FrameStackTooltip", "GarrisonMissionMechanicTooltip", "GarrisonMissionMechanicFollowerCounterTooltip", "ItemSocketingDescription", "NamePlateTooltip", "PrivateAurasTooltip", "RuneforgeFrameResultTooltip", "ItemRefTooltip", "QuickKeybindTooltip", "SettingsTooltip"} + local allTooltips = {"GameTooltip", "GameTooltipTooltip", "EventTraceTooltip", "FrameStackTooltip", "GarrisonMissionMechanicTooltip", "GarrisonMissionMechanicFollowerCounterTooltip", "ItemSocketingDescription", "NamePlateTooltip", "PrivateAurasTooltip", "RuneforgeFrameResultTooltip", "ItemRefTooltip", "QuickKeybindTooltip", "SettingsTooltip"} for i = 1, #allTooltips do local tooltipName = allTooltips[i] local tooltip = _G[tooltipName] - if (tooltip and tooltip.GetTooltipData) then + if (tooltip and tooltip.GetTooltipData and tooltip:IsVisible()) then local tooltipData = tooltip:GetTooltipData() - if (tooltipData)then + if (tooltipData) then + if (tooltip.ItemTooltip and tooltip.ItemTooltip:IsVisible()) then + local icon = tooltip.ItemTooltip.Icon + if (icon) then + local texture = icon:GetTexture() + local atlas = icon:GetAtlas() + if (texture or atlas) then + tooltipData.IconTexture = texture + tooltipData.IconAtlas = atlas + end + end + end + + if (tooltipData.hyperlink) then + local itemName, itemLink, itemQuality, itemLevel, itemMinLevel, itemType, itemSubType, + itemStackCount, itemEquipLoc, itemTexture, sellPrice, classID, subclassID, bindType, + expacID, setID, isCraftingReagent = GetItemInfo(tooltipData.hyperlink) + + local itemInfo = { + itemName = itemName, + itemLink = itemLink, + itemQuality = itemQuality, + itemLevel = itemLevel, + itemMinLevel = itemMinLevel, + itemType = itemType, + itemSubType = itemSubType, + itemStackCount = itemStackCount, + itemEquipLoc = itemEquipLoc, + itemTexture = itemTexture, + sellPrice = sellPrice, + classID = classID, + subclassID = subclassID, + bindType = bindType, + expacID = expacID, + setID = setID, + isCraftingReagent = isCraftingReagent + } + DetailsFramework.table.deploy(tooltipData, itemInfo) + end + return Details:Dump(tooltipData) end end diff --git a/classes/container_actors.lua b/classes/container_actors.lua index 6f17edafe..89d0b7968 100644 --- a/classes/container_actors.lua +++ b/classes/container_actors.lua @@ -506,10 +506,11 @@ end --check if the nickname fit some minimal rules to be presented to other players local checkValidNickname = function(nickname, playerName) if (nickname and type(nickname) == "string") then - if (nickname == "") then + nickname = nickname:trim() + if (nickname == "" or nickname:len() < 2) then return playerName - - elseif (nickname:find(" ")) then + end + if (nickname:len() > 20) then return playerName end else diff --git a/frames/window_breakdown/breakdown_spells_spellframes.lua b/frames/window_breakdown/breakdown_spells_spellframes.lua index 14cd3d68a..cedf68834 100644 --- a/frames/window_breakdown/breakdown_spells_spellframes.lua +++ b/frames/window_breakdown/breakdown_spells_spellframes.lua @@ -189,7 +189,7 @@ local onEnterSpellBar = function(spellBar, motion) --parei aqui: precisa por nom local elapsedTime = spellBar.combatTime --this should be actorObject:Tempo() ---@type string - local actorName = spellsTab.GetActor():Name() + local actorName = spellsTab.GetActor():Name() --attempt to index a nil value ---@type spelltable local spellTable = spellBar.spellTable diff --git a/frames/window_breakdown/window_playerbreakdown_auras.lua b/frames/window_breakdown/window_playerbreakdown_auras.lua index 96d1331a4..8b37c8dfd 100644 --- a/frames/window_breakdown/window_playerbreakdown_auras.lua +++ b/frames/window_breakdown/window_playerbreakdown_auras.lua @@ -13,7 +13,7 @@ local buffs_to_ignore = { [381748] = true, --Blessing of the Bronze [397734] = true, --Word of a Worthy Ally [402221] = true, --Obsidian Resonance - --[] = true, -- + [225788] = true, --Sign of the Emissary --[] = true, -- } diff --git a/frames/window_main.lua b/frames/window_main.lua index a8376e761..62db0f2de 100644 --- a/frames/window_main.lua +++ b/frames/window_main.lua @@ -2076,7 +2076,6 @@ local iconFrame_OnEnter = function(self) elseif (actor.nome) then --ensure it's an actor table - local serial = actor.serial local name = actor:name() local class = actor:class() @@ -2255,6 +2254,7 @@ local iconFrame_OnEnter = function(self) GameCooltip:AddLine("Evoker Predicted Damage:", Details:Format(damageDone) .. " (" .. Details:Format(damageDone / Details:GetCurrentCombat():GetCombatTime()) .. ")", 1, "white") GameCooltip:AddIcon([[]], 1, 1, 1, 20) Details:AddTooltipBackgroundStatusbar() + height = height + 19 end GameCooltip:SetOption("FixedHeight", height) diff --git a/plugins/Details_Compare2/Details_Compare2_Wrath.toc b/plugins/Details_Compare2/Details_Compare2_Wrath.toc index 6e0851950..22c797d7c 100644 --- a/plugins/Details_Compare2/Details_Compare2_Wrath.toc +++ b/plugins/Details_Compare2/Details_Compare2_Wrath.toc @@ -1,4 +1,4 @@ -## Interface: 30401 +## Interface: 30402 ## Title: Details!: Compare 2.0 ## Notes: Replace the Compare tab in the player breakdown window. ## RequiredDeps: Details diff --git a/plugins/Details_DataStorage/Details_DataStorage-Wrath.toc b/plugins/Details_DataStorage/Details_DataStorage-Wrath.toc index f37d96e8b..80d943778 100644 --- a/plugins/Details_DataStorage/Details_DataStorage-Wrath.toc +++ b/plugins/Details_DataStorage/Details_DataStorage-Wrath.toc @@ -1,4 +1,4 @@ -## Interface: 30401 +## Interface: 30402 ## Title: Details!: Storage ## Notes: Stores information for Details! Damage Meter ## DefaultState: Enabled diff --git a/plugins/Details_DataStorage/Details_DataStorage_Wrath.toc b/plugins/Details_DataStorage/Details_DataStorage_Wrath.toc index f37d96e8b..80d943778 100644 --- a/plugins/Details_DataStorage/Details_DataStorage_Wrath.toc +++ b/plugins/Details_DataStorage/Details_DataStorage_Wrath.toc @@ -1,4 +1,4 @@ -## Interface: 30401 +## Interface: 30402 ## Title: Details!: Storage ## Notes: Stores information for Details! Damage Meter ## DefaultState: Enabled diff --git a/plugins/Details_EncounterDetails/Details_EncounterDetails-Wrath.toc b/plugins/Details_EncounterDetails/Details_EncounterDetails-Wrath.toc index b6f4cd7a0..7cb7a0245 100644 --- a/plugins/Details_EncounterDetails/Details_EncounterDetails-Wrath.toc +++ b/plugins/Details_EncounterDetails/Details_EncounterDetails-Wrath.toc @@ -1,4 +1,4 @@ -## Interface: 30401 +## Interface: 30402 ## Title: Details!: Encounter Breakdown (plugin) ## Notes: Show detailed information about a boss encounter. Also provide damage per phase, graphic charts, easy weakauras creation. ## RequiredDeps: Details diff --git a/plugins/Details_EncounterDetails/Details_EncounterDetails_Wrath.toc b/plugins/Details_EncounterDetails/Details_EncounterDetails_Wrath.toc index b6f4cd7a0..7cb7a0245 100644 --- a/plugins/Details_EncounterDetails/Details_EncounterDetails_Wrath.toc +++ b/plugins/Details_EncounterDetails/Details_EncounterDetails_Wrath.toc @@ -1,4 +1,4 @@ -## Interface: 30401 +## Interface: 30402 ## Title: Details!: Encounter Breakdown (plugin) ## Notes: Show detailed information about a boss encounter. Also provide damage per phase, graphic charts, easy weakauras creation. ## RequiredDeps: Details