diff --git a/Libs/DF/button.lua b/Libs/DF/button.lua index e640fb42..c112bbb2 100644 --- a/Libs/DF/button.lua +++ b/Libs/DF/button.lua @@ -1332,7 +1332,7 @@ detailsFramework.TabButtonMixin = { ---@return df_tabbutton function detailsFramework:CreateTabButton(parent, frameName) ---@type df_tabbutton - local tabButton = CreateFrame("button", frameName, parent) + local tabButton = CreateFrame("button", frameName, parent, "BackdropTemplate") tabButton:SetSize(50, 20) tabButton.bIsSelected = false diff --git a/Libs/DF/fw.lua b/Libs/DF/fw.lua index 687f0c40..28b771c6 100644 --- a/Libs/DF/fw.lua +++ b/Libs/DF/fw.lua @@ -1,6 +1,6 @@ -local dversion = 551 +local dversion = 553 local major, minor = "DetailsFramework-1.0", dversion local DF, oldminor = LibStub:NewLibrary(major, minor) @@ -2505,6 +2505,9 @@ local templateOnLeave = function(frame) end end +DF.TemplateOnEnter = templateOnEnter +DF.TemplateOnLeave = templateOnLeave + ---set a details framework template into a regular frame ---@param self table ---@param frame uiobject @@ -2630,10 +2633,10 @@ DF.dropdown_templates["OPTIONS_DROPDOWN_TEMPLATE"] = { tile = true }, - backdropcolor = {1, 1, 1, .7}, - backdropbordercolor = {0, 0, 0, 1}, - onentercolor = {1, 1, 1, .9}, - onenterbordercolor = {1, 1, 1, 1}, + backdropcolor = {0.1, 0.1, 0.1, .7}, + onentercolor = {0.3, 0.3, 0.3, .7}, + backdropbordercolor = {0, 0, 0, .7}, + onenterbordercolor = {0.3, 0.3, 0.3, 0.8}, dropicon = "Interface\\BUTTONS\\arrow-Down-Down", dropiconsize = {16, 16}, diff --git a/Libs/DF/schedules.lua b/Libs/DF/schedules.lua index 8666ec2d..20cc8e11 100644 --- a/Libs/DF/schedules.lua +++ b/Libs/DF/schedules.lua @@ -268,6 +268,28 @@ function detailsFramework.Schedules.AfterById(time, callback, id, ...) return newTimer end +--Schedules a callback function to be executed after a specified time delay. +--It uniquely identifies each scheduled task by an ID, if another schedule with the same id is made, it will be ignore until the previous one is finished. +function detailsFramework.Schedules.AfterByIdNoCancel(time, callback, id, ...) + if (not detailsFramework.Schedules.ExecuteTimerTableNoCancel) then + detailsFramework.Schedules.ExecuteTimerTableNoCancel = {} + end + + local alreadyHaveTimer = detailsFramework.Schedules.ExecuteTimerTableNoCancel[id] + if (alreadyHaveTimer) then + return + end + + local newTimer = detailsFramework.Schedules.NewTimer(time, callback, ...) + detailsFramework.Schedules.ExecuteTimerTableNoCancel[id] = newTimer + + C_Timer.After(time, function() + detailsFramework.Schedules.ExecuteTimerTableNoCancel[id] = nil + end) + + return newTimer +end + --schedule a function to be called after 'time' --prompt example: create a schedule that runs the function 'variable name' after 'time' amount of seconds function detailsFramework.Schedules.After(time, callback) diff --git a/Libs/DF/textentry.lua b/Libs/DF/textentry.lua index 5a6f004e..b0fdcdde 100644 --- a/Libs/DF/textentry.lua +++ b/Libs/DF/textentry.lua @@ -287,7 +287,12 @@ detailsFramework.TextEntryCounter = detailsFramework.TextEntryCounter or 1 if (textentry:IsEnabled()) then textentry.current_bordercolor = textentry.current_bordercolor or {textentry:GetBackdropBorderColor()} - textentry:SetBackdropBorderColor(1, 1, 1, 1) + local onEnterBorderColor = object.onenter_backdrop_border_color + if (onEnterBorderColor) then + textentry:SetBackdropBorderColor(detailsFramework:ParseColors(onEnterBorderColor)) + else + textentry:SetBackdropBorderColor(1, 1, 1, 0.6) + end end end @@ -522,11 +527,13 @@ function TextEntryMetaFunctions:SetTemplate(template) if (template.backdrop) then self.editbox:SetBackdrop(template.backdrop) end + if (template.backdropcolor) then local r, g, b, a = detailsFramework:ParseColors(template.backdropcolor) self.editbox:SetBackdropColor(r, g, b, a) self.onleave_backdrop = {r, g, b, a} end + if (template.backdropbordercolor) then local r, g, b, a = detailsFramework:ParseColors(template.backdropbordercolor) self.editbox:SetBackdropBorderColor(r, g, b, a) @@ -536,8 +543,40 @@ function TextEntryMetaFunctions:SetTemplate(template) self.editbox.current_bordercolor[4] = a self.onleave_backdrop_border_color = {r, g, b, a} end + + if (template.onentercolor) then + local r, g, b, a = detailsFramework:ParseColors(template.onentercolor) + self.onenter_backdrop = {r, g, b, a} + self:HookScript("OnEnter", detailsFramework.TemplateOnEnter) + self.__has_onentercolor_script = true + end + + if (template.onleavecolor) then + local r, g, b, a = detailsFramework:ParseColors(template.onleavecolor) + self.onleave_backdrop = {r, g, b, a} + self:HookScript("OnLeave", detailsFramework.TemplateOnLeave) + self.__has_onleavecolor_script = true + end + + if (template.onenterbordercolor) then + local r, g, b, a = detailsFramework:ParseColors(template.onenterbordercolor) + self.onenter_backdrop_border_color = {r, g, b, a} + if (not self.__has_onentercolor_script) then + self:HookScript("OnEnter", detailsFramework.TemplateOnEnter) + end + end + + if (template.onleavebordercolor) then + local r, g, b, a = detailsFramework:ParseColors(template.onleavebordercolor) + self.onleave_backdrop_border_color = {r, g, b, a} + if (not self.__has_onleavecolor_script) then + self:HookScript("OnLeave", detailsFramework.TemplateOnLeave) + end + end end +--TextEntryMetaFunctions.SetTemplate = DetailsFramework.SetTemplate + ------------------------------------------------------------------------------------------------------------ --object constructor diff --git a/Libs/LibOpenRaid/LibOpenRaid.lua b/Libs/LibOpenRaid/LibOpenRaid.lua index 05722fc1..8218db51 100644 --- a/Libs/LibOpenRaid/LibOpenRaid.lua +++ b/Libs/LibOpenRaid/LibOpenRaid.lua @@ -60,6 +60,8 @@ end openRaidLib.inGroup = false openRaidLib.UnitIDCache = {} + openRaidLib.Util = openRaidLib.Util or {} + local CONST_CVAR_TEMPCACHE = "LibOpenRaidTempCache" local CONST_CVAR_TEMPCACHE_DEBUG = "LibOpenRaidTempCacheDebug" diff --git a/boot.lua b/boot.lua index 06931ab3..bf4e3a84 100644 --- a/boot.lua +++ b/boot.lua @@ -19,12 +19,12 @@ local addonName, Details222 = ... local version = GetBuildInfo() - Details.build_counter = 12819 - Details.alpha_build_counter = 12819 --if this is higher than the regular counter, use it instead + Details.build_counter = 12820 + Details.alpha_build_counter = 12820 --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 - Details.realversion = 158 --core version, this is used to check API version for scripts and plugins (see alias below) + Details.realversion = 159 --core version, this is used to check API version for scripts and plugins (see alias below) Details.gametoc = tvs Details.APIVersion = Details.realversion --core version Details.version = Details.userversion .. " (core " .. Details.realversion .. ")" --simple stirng to show to players diff --git a/classes/class_combat.lua b/classes/class_combat.lua index 800428ce..b577e52e 100644 --- a/classes/class_combat.lua +++ b/classes/class_combat.lua @@ -940,6 +940,25 @@ local segmentTypeToString = { end end + function classCombat:CutDeathByTime(time) + local deathsTable = self:GetDeaths() + for i = #deathsTable, 1, -1 do + local deathTable = deathsTable[i] + local playerName, playerClass, deathTime, deathCombatTime, deathTimeString, playerMaxHealth, deathEvents, lastCooldown, spec = Details:UnpackDeathTable(deathTable) + for evIndex = 1, #deathEvents do + local event = deathEvents[evIndex] + local evType = event[1] + if (type(evType) == "boolean") then + local eventTime = event[4] + print(eventTime, deathTime) + if (eventTime+10 < deathTime) then + print("this event is ignored, and should be removed", event[1]) + end + end + end + end + end + --return the total of a specific attribute local power_table = {0, 1, 3, 6, 0, "alternatepower"} diff --git a/classes/class_utility.lua b/classes/class_utility.lua index 993f1522..47a6e057 100644 --- a/classes/class_utility.lua +++ b/classes/class_utility.lua @@ -205,8 +205,9 @@ function Details.ShowDeathTooltip(instance, lineFrame, combatObject, deathTable) --death parser for i, event in ipairs(events) do - local currentHP = event[5] - local healthPercent = floor(currentHP / maxHP * 100) + --local currentHP = event[5] * 100 + --local healthPercent = floor(currentHP / maxHP * 100) + local healthPercent = floor(event[5] * 100) if (healthPercent > 100) then healthPercent = 100 end @@ -226,7 +227,7 @@ function Details.ShowDeathTooltip(instance, lineFrame, combatObject, deathTable) local eventTime = event[4] local source = Details:GetOnlyName(event[6] or "") - if (eventTime + 12 > timeOfDeath) then + if (eventTime + 10 > timeOfDeath) then if (type(evType) == "boolean") then --is damage or heal? if (evType) then --bool true diff --git a/core/control.lua b/core/control.lua index c0253853..ec92b309 100644 --- a/core/control.lua +++ b/core/control.lua @@ -521,7 +521,7 @@ currentCombat:SetDateToNow(bSetStartTime, bSetEndTime) currentCombat:SetEndTime(GetTime()) - --drop last events table to garbage collector + --drop player last events table to garbage collector currentCombat.player_last_events = {} --flag instance type diff --git a/core/gears.lua b/core/gears.lua index 280922d0..0ad116d8 100644 --- a/core/gears.lua +++ b/core/gears.lua @@ -2724,6 +2724,29 @@ function Details.FillTableWithPlayerSpells(completeListOfSpells) end end end + + local getNumPetSpells = function() + --'HasPetSpells' contradicts the name and return the amount of pet spells available instead of a boolean + return HasPetSpells() + end + + --get pet spells from the pet spellbook + local numPetSpells = getNumPetSpells() + if (numPetSpells) then + for i = 1, numPetSpells do + local spellName, _, unmaskedSpellId = GetSpellBookItemName(i, spellBookPetEnum) + if (unmaskedSpellId) then + unmaskedSpellId = GetOverrideSpell(unmaskedSpellId) + local bIsPassive = IsPassiveSpell(i, spellBookPetEnum) + if (spellName and not bIsPassive) then + completeListOfSpells[unmaskedSpellId] = true + end + end + end + end + + --dumpt(completeListOfSpells) + return completeListOfSpells end function Details.SavePlayTimeOnClass() diff --git a/core/parser.lua b/core/parser.lua index ea266c23..8bf6a458 100755 --- a/core/parser.lua +++ b/core/parser.lua @@ -847,15 +847,15 @@ end --record death log - local t = last_events_cache[targetName] + local actorLatestEvents = last_events_cache[targetName] - if (not t) then - t = _current_combat:CreateLastEventsTable(targetName) + if (not actorLatestEvents) then + actorLatestEvents = _current_combat:CreateLastEventsTable(targetName) end - local i = t.n + local i = actorLatestEvents.n - local thisEvent = t [i] + local thisEvent = actorLatestEvents[i] thisEvent[1] = true --true if this is a damage || false for healing thisEvent[2] = spellId --spellid || false if this is a battle ress line thisEvent[3] = amount --amount of damage or healing @@ -869,14 +869,14 @@ unitId = Details:GuessArenaEnemyUnitId(targetName) end if (unitId) then - thisEvent[5] = UnitHealth(unitId) + thisEvent[5] = UnitHealth(unitId) / UnitHealthMax(unitId) else thisEvent[5] = cacheAnything.arenaHealth[targetName] or 100000 end cacheAnything.arenaHealth[targetName] = thisEvent[5] else - thisEvent[5] = UnitHealth(targetName) + thisEvent[5] = UnitHealth(targetName) / UnitHealthMax(targetName) end thisEvent[6] = sourceName --source name @@ -890,9 +890,9 @@ i = i + 1 if (i == _amount_of_last_events + 1) then - t.n = 1 + actorLatestEvents.n = 1 else - t.n = i + actorLatestEvents.n = i end end @@ -977,7 +977,7 @@ thisEvent[2] = spellId --spellid || false if this is a battle ress line thisEvent[3] = amount --amount of damage or healing thisEvent[4] = time --parser time - thisEvent[5] = UnitHealth(targetName) --current unit heal + thisEvent[5] = UnitHealth(targetName) / UnitHealthMax(targetName) --current unit heal thisEvent[6] = sourceName --source name thisEvent[7] = absorbed thisEvent[8] = spellType or school @@ -1223,7 +1223,7 @@ this_event [2] = spellId --spellid || false if this is a battle ress line this_event [3] = amount --amount of damage or healing this_event [4] = time --parser time - this_event [5] = UnitHealth(sourceName) --current unit heal + this_event [5] = UnitHealth(sourceName) / UnitHealthMax(sourceName) --current unit heal this_event [6] = sourceName --source name this_event [7] = absorbed this_event [8] = school @@ -1318,7 +1318,7 @@ this_event [2] = spellid --spellid || false if this is a battle ress line this_event [3] = amount --amount of damage or healing this_event [4] = time --parser time - this_event [5] = UnitHealth(who_name) --current unit heal + this_event [5] = UnitHealth(who_name) / UnitHealthMax(who_name) --current unit heal this_event [6] = who_name --source name this_event [7] = absorbed this_event [8] = school @@ -1438,7 +1438,7 @@ this_event [2] = spellid --spellid || false if this is a battle ress line this_event [3] = amount --amount of damage or healing this_event [4] = time --parser time - this_event [5] = UnitHealth(alvo_name) --current unit heal + this_event [5] = UnitHealth(alvo_name) / UnitHealthMax(alvo_name) --current unit heal this_event [6] = who_name --source name this_event [7] = absorbed this_event [8] = spelltype or school @@ -1748,7 +1748,7 @@ end ----------------------------------------------------------------------------------------------------------------------------------------- - --HEALING serach key: ~healing | + --HEALING serach key: ~healing ~heal | ----------------------------------------------------------------------------------------------------------------------------------------- -- https://github.com/TrinityCore/TrinityCore/blob/d81a9e5bc3b3e13b47332b3e7817bd0a0b228cbc/src/server/game/Spells/Auras/SpellAuraEffects.h#L313-L367 @@ -2139,7 +2139,7 @@ end previousEvent[7] = previousEvent[7] or bIsShield previousEvent[1] = false --true if this is a damage || false for healing - previousEvent[5] = UnitHealth(targetName) + previousEvent[5] = UnitHealth(targetName) / UnitHealthMax(targetName) previousEvent[11] = (previousEvent[11] or 0) + 1 --attempt to perform arithmetic on a boolean value (during battlegrounds - fix 02 Nov 2023) else local thisEvent = t[i] @@ -2158,12 +2158,12 @@ unitId = Details:GuessArenaEnemyUnitId(targetName) end if (unitId) then - thisEvent[5] = UnitHealth(unitId) + thisEvent[5] = UnitHealth(unitId) / UnitHealthMax(unitId) else thisEvent[5] = 0 end else - thisEvent[5] = UnitHealth(targetName) + thisEvent[5] = UnitHealth(targetName) / UnitHealthMax(targetName) end thisEvent[6] = sourceName @@ -2304,7 +2304,7 @@ this_event [2] = spellid --spellid || false if this is a battle ress line this_event [3] = amount --amount of damage or healing this_event [4] = time --parser time - this_event [5] = UnitHealth(alvo_name) --current unit heal + this_event [5] = UnitHealth(alvo_name) / UnitHealthMax(alvo_name) --current unit heal this_event [6] = who_name --source name this_event [7] = is_shield this_event [8] = absorbed @@ -2409,7 +2409,7 @@ thisEvent[2] = spellId --spellid thisEvent[3] = 1 thisEvent[4] = time --parser time - thisEvent[5] = UnitHealth(targetName) --current unit heal + thisEvent[5] = UnitHealth(targetName) / UnitHealthMax(targetName) --current unit heal thisEvent[6] = sourceName --source name thisEvent[7] = false thisEvent[8] = false @@ -2890,7 +2890,7 @@ thisEvent[2] = spellId --spellid thisEvent[3] = 1 thisEvent[4] = time --parser time - thisEvent[5] = UnitHealth(targetName) --current unit heal + thisEvent[5] = UnitHealth(targetName) / UnitHealthMax(targetName) --current unit heal thisEvent[6] = sourceName --source name thisEvent[7] = false thisEvent[8] = false @@ -2950,7 +2950,7 @@ thisEvent[2] = spellId --spellid thisEvent[3] = stackSize or 1 thisEvent[4] = time --parser time - thisEvent[5] = UnitHealth(targetName) --current unit heal + thisEvent[5] = UnitHealth(targetName) / UnitHealthMax(targetName) --current unit heal thisEvent[6] = sourceName --source name thisEvent[7] = false thisEvent[8] = false @@ -3425,7 +3425,7 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1 thisEvent[2] = spellId --spellid || false if this is a battle ress line thisEvent[3] = 1 --amount of damage or healing thisEvent[4] = time - thisEvent[5] = UnitHealth(sourceName) + thisEvent[5] = UnitHealth(sourceName) / UnitHealthMax(sourceName) thisEvent[6] = sourceName i = i + 1 @@ -3888,7 +3888,7 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1 spellId, 1, time, - UnitHealth(targetName), + UnitHealth(targetName) / UnitHealthMax(targetName), sourceName }) break @@ -4099,6 +4099,8 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1 --get the index of the last event recorded local lastIndex = recordedEvents.n + --first, remove all healing events where the player was at full health + --here the event log gets reordered as in the parser it work with index recycling if (lastIndex < _amount_of_last_events+1 and not recordedEvents[lastIndex][4]) then --the last events table amount of indexes is less than the amount of events to store @@ -4223,8 +4225,6 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1 eventsBeforePlayerDeath[#eventsBeforePlayerDeath+1] = eventTable end - - local maxHealth if (thisPlayer.arena_enemy) then --this is an arena enemy, get the heal with the unit Id diff --git a/frames/window_cdtracker.lua b/frames/window_cdtracker.lua index 9cd23e12..2f405a92 100644 --- a/frames/window_cdtracker.lua +++ b/frames/window_cdtracker.lua @@ -17,6 +17,8 @@ Details222.CooldownTracking = { cooldownPanels = {}, } +local GetSpellTexture = C_Spell and C_Spell.GetSpellTexture or GetSpellTexture + function Details222.CooldownTracking.IsCooldownIgnored(spellId) return Details.ocd_tracker.ignored_cooldowns[spellId] end @@ -864,7 +866,7 @@ end for spellId, spellInfo in pairs(LIB_OPEN_RAID_COOLDOWNS_INFO) do if (spellInfo.class == className) then - local spellName, _, spellIcon = GetSpellInfo(spellId) + local spellName, _, spellIcon = Details222.GetSpellInfo(spellId) if (spellName) then local smallSpellName = string.sub(spellName, 1, 12) diff --git a/frames/window_spellcategory.lua b/frames/window_spellcategory.lua index b81eab52..c665af58 100644 --- a/frames/window_spellcategory.lua +++ b/frames/window_spellcategory.lua @@ -3,6 +3,7 @@ --this code should run only on beta periods of an new expansion local Details = _G.Details +---@type detailsframework local DF = _G.DetailsFramework local _ @@ -23,11 +24,26 @@ local scrollLineHeight = 20 Details.Survey = {} function Details.Survey.GetTargetCharacterForRealm() + if true then return "" end if (UnitFactionGroup("player") == "Horde") then - return "FistbirtbrezPQ" + return "" --character name end end +---@class savedcooldowninfo +---@field cooldown number +---@field duration number +---@field type number|boolean +---@field silence number +---@field charges number + +---@class savedcooldowninfoscrolldata +---@field spellId number +---@field type number|boolean +---@field spellName string +---@field savedCooldownInfo savedcooldowninfo + +---@return table function Details.Survey.GetCategorySpellListForClass() local savedSpellsCategories = Details.spell_category_savedtable local unitClass = select(2, UnitClass("player")) @@ -36,10 +52,119 @@ function Details.Survey.GetCategorySpellListForClass() thisClassSavedTable = {} savedSpellsCategories[unitClass] = thisClassSavedTable end - Details.FillTableWithPlayerSpells(thisClassSavedTable) + + local allPlayerSpells = {} + Details.FillTableWithPlayerSpells(allPlayerSpells) + + for spellId in pairs(allPlayerSpells) do + if (not thisClassSavedTable[spellId]) then + --get the cooldown time for the spell + local cooldownTime = GetSpellBaseCooldown(spellId) + + local chargesInfo = C_Spell.GetSpellCharges(spellId) + local chargesAmount = 1 + + if (chargesInfo) then + chargesAmount = chargesInfo.maxCharges + + --if the cooldown time doesn't match the requirement, check if the spell has charges and use the cooldown of the charge as the cooldown time + if (not cooldownTime or cooldownTime <= 5000) then + if (chargesInfo and chargesInfo.maxCharges > 0) then + cooldownTime = chargesInfo.cooldownDuration * 1000 + end + end + end + + if (cooldownTime and cooldownTime > 5000 and cooldownTime <= 360000) then --requirement: cooldown time must be greater than 5 seconds and lower then 6 minutes + local cooldownTable = LIB_OPEN_RAID_COOLDOWNS_INFO[spellId] + if (cooldownTable) then + thisClassSavedTable[spellId] = {cooldown = cooldownTime, duration = cooldownTable.duration or 0, type = cooldownTable.type or true, silence = cooldownTable.silence or 0, charges = cooldownTable.charges or chargesAmount} + else + thisClassSavedTable[spellId] = {cooldown = cooldownTime, duration = 0, type = true, silence = 0, charges = chargesAmount} + end + else + --local spellName = C_Spell.GetSpellInfo(spellId).name + --print("Cooldown not match:", spellName, spellId, cooldownTime) + end + end + end + return thisClassSavedTable end +---@param savedCooldownInfo savedcooldowninfo +---@param spellId number +---@param unitClass string +---@return string +local makeSpellExportString = function(savedCooldownInfo, spellId, unitClass) + local spellInfo = C_Spell.GetSpellInfo(spellId) + if (not spellInfo) then + Details:Msg("spell not found", spellId) + return "" + end + + if (savedCooldownInfo.type == true) then + Details:Msg("spell not categorized:", spellInfo.name) + return "" + end + + local spellName = spellInfo.name + + if (savedCooldownInfo.type == 9) then --interrupt + return "["..spellId.."] = {cooldown = ".. (floor(savedCooldownInfo.cooldown / 1000)) ..",\tduration = "..savedCooldownInfo.duration..",\tsilence = ".. savedCooldownInfo.silence ..",\tspecs = {},\ttalent = false,\tcharges = " .. savedCooldownInfo.charges ..",\tclass = \""..unitClass.."\",\ttype = "..savedCooldownInfo.type.."}, --" .. spellName + else + return "["..spellId.."] = {cooldown = ".. (floor(savedCooldownInfo.cooldown / 1000)) ..",\tduration = "..savedCooldownInfo.duration..",\tspecs = {},\ttalent = false,\tcharges = " .. savedCooldownInfo.charges ..",\tclass = \""..unitClass.."\",\ttype = "..savedCooldownInfo.type.."}, --" .. spellName + end +end + + +function Details.Survey.ExportSpellCatogeryData() + local savedSpellsCategories = Details.spell_category_savedtable + local unitClass = select(2, UnitClass("player")) + local thisClassSavedTable = savedSpellsCategories[unitClass] + local exportString = "\n\n\n" + + for spellId, savedCooldownInfo in pairs(thisClassSavedTable) do + ---@type spellinfo + local spellInfo = C_Spell.GetSpellInfo(spellId) + + ---@cast savedCooldownInfo savedcooldowninfo + if (savedCooldownInfo.type ~= true) then + if (spellInfo) then + local stringToExport = makeSpellExportString(savedCooldownInfo, spellId, unitClass) + exportString = exportString .. stringToExport .. "\n" + end + end + end + + exportString = exportString .. "\n\n\n" + dumpt(exportString) +end + +function Details.Survey.ExportSingleSpellCatogeryData(line) + local spellId = line.spellId + + local savedSpellsCategories = Details.spell_category_savedtable + local unitClass = select(2, UnitClass("player")) + local thisClassSavedTable = savedSpellsCategories[unitClass] + + ---@type savedcooldowninfo + local savedCooldownInfo = spellId and thisClassSavedTable[spellId] + + if (savedCooldownInfo) then + ---@type spellinfo + local spellInfo = C_Spell.GetSpellInfo(spellId) + if (spellInfo) then + local stringToExport = makeSpellExportString(savedCooldownInfo, spellId, unitClass) + if (stringToExport ~= "") then + dumpt("\n\n\n" .. stringToExport .. "\n\n\n") + end + end + end + + return "something went wrong" +end + function Details.Survey.SendSpellCatogeryDataToTargetCharacter() local targetCharacter = Details.Survey.GetTargetCharacterForRealm() if (not targetCharacter) then @@ -146,8 +271,10 @@ function Details.Survey.OpenSpellCategoryScreen() DetailsSpellCategoryFrame = DetailsFramework:CreateSimplePanel(UIParent) local detailsSpellCategoryFrame = DetailsSpellCategoryFrame detailsSpellCategoryFrame:SetSize(scroll_width, windowHeight+26) - detailsSpellCategoryFrame:SetTitle("Identifying and Categorizing Cooldown Spells") + detailsSpellCategoryFrame:SetTitle("Details! Damage Meter: Spell Category Selection") detailsSpellCategoryFrame.Data = {} + detailsSpellCategoryFrame.Title:ClearAllPoints() + detailsSpellCategoryFrame.Title:SetPoint("left", detailsSpellCategoryFrame.TitleBar, "left", 5, 0) --statusbar local statusBar = CreateFrame("frame", nil, detailsSpellCategoryFrame, "BackdropTemplate") @@ -162,26 +289,31 @@ function Details.Survey.OpenSpellCategoryScreen() statusBar2:SetPoint("topleft", statusBar, "bottomleft") statusBar2:SetPoint("topright", statusBar, "bottomright") statusBar2:SetHeight(20) - statusBar2:SetAlpha(0.8) + statusBar2:SetAlpha(0.99) DF:ApplyStandardBackdrop(statusBar2) DF:ApplyStandardBackdrop(statusBar2) - local dataInfoLabel = DF:CreateLabel(statusBar2, "This cooldown data is send to people on Details! team and shared in 'Open Raid' library where any weakaura or addon can use it", 12, "silver") - dataInfoLabel:SetPoint("center", 0, 0) + local dataInfoLabel = DF:CreateLabel(statusBar2, "An AddOn By Terciob", 12, "white") + dataInfoLabel:SetPoint("left", 5, 0) dataInfoLabel.justifyH = "center" --create the header + local defaultWidth = 70 local headerTable = { {text = "Icon", width = 24}, - {text = "Spell Name", width = 140}, - {text = "NONE", width = 70}, - {text = "Offensive CD", width = 100}, - {text = "Personal Defensive CD", width = 120}, - {text = "Targeted Defensive CD", width = 120}, - {text = "Raid Defensive CD", width = 120}, - {text = "Raid Utility CD", width = 100}, - {text = "Interrupt", width = 70}, - {text = "Dispel", width = 50}, - {text = "CC", width = 50}, + {text = "Spell Name", width = 150}, + {text = "NONE", width = defaultWidth}, + {text = "Offensive CD", width = defaultWidth}, + {text = "Personal CD", width = defaultWidth}, + {text = "Targeted CD", width = defaultWidth}, + {text = "Raid CD", width = defaultWidth}, + {text = "Utility CD", width = defaultWidth}, + {text = "Interrupt", width = defaultWidth}, + {text = "Dispel", width = defaultWidth}, + {text = "CC", width = defaultWidth}, + {text = "Racial", width = defaultWidth}, + {text = "Cooldown", width = defaultWidth}, + {text = "Duration", width = defaultWidth}, + {text = "Export", width = defaultWidth}, } local headerOptions = { padding = 2, @@ -192,10 +324,11 @@ function Details.Survey.OpenSpellCategoryScreen() maxLineWidth = maxLineWidth + headerSettings.width end - detailsSpellCategoryFrame:SetWidth(maxLineWidth + 20) + detailsSpellCategoryFrame:SetWidth(maxLineWidth + 50) local thisClassSavedTable = Details.Survey.GetCategorySpellListForClass() - local sendButton = DetailsFramework:CreateButton(statusBar, function() Details.Survey.SendSpellCatogeryDataToTargetCharacter(); DetailsSpellCategoryFrame:Hide() end, 800, 20, "SAVE and SEND") + --local sendButton = DetailsFramework:CreateButton(statusBar, function() Details.Survey.SendSpellCatogeryDataToTargetCharacter(); DetailsSpellCategoryFrame:Hide() end, 800, 20, "SAVE and SEND") + local sendButton = DetailsFramework:CreateButton(statusBar, function() Details.Survey.ExportSpellCatogeryData(); DetailsSpellCategoryFrame:Hide() end, 800, 20, "EXPORT ALL") sendButton:SetPoint("center", statusBar, "center", 0, 0) detailsSpellCategoryFrame.Header = DetailsFramework:CreateHeader(detailsSpellCategoryFrame, headerTable, headerOptions) @@ -204,21 +337,31 @@ function Details.Survey.OpenSpellCategoryScreen() local tooltipDesc = {} tooltipDesc[2] = "|cffffff00" .. headerTable[4].text .. "|r|n" .. "Examples:\nPower Infusion, Ice Veins, Combustion, Adrenaline Rush" --ofensive cooldowns tooltipDesc[3] = "|cffffff00" .. headerTable[5].text .. "|r|n" .. "Examples:\nIce Block, Dispersion, Cloak of Shadows, Shield Wall " --personal cooldowns - tooltipDesc[4] = "|cffffff00" .. headerTable[6].text .. "|r|n" .. "Examples:\nBlessing of Sacrifice, Ironbark, Life Cocoon, Pain Suppression" --targetted devense cooldowns + tooltipDesc[4] = "|cffffff00" .. headerTable[6].text .. "|r|n" .. "Examples:\nBlessing of Sacrifice, Ironbark, Life Cocoon, Pain Suppression" --targeted devense cooldowns tooltipDesc[5] = "|cffffff00" .. headerTable[7].text .. "|r|n" .. "Examples:\nPower Word: Barrier, Spirit Link Totem, Tranquility, Anti-Magic Zone" --raid wide cooldowns tooltipDesc[6] = "|cffffff00" .. headerTable[8].text .. "|r|n" .. "Examples:\nStampeding Roar, Leap of Faith" tooltipDesc[7] = "" tooltipDesc[8] = "" tooltipDesc[9] = "" + tooltipDesc[10] = "" + tooltipDesc[11] = "" + tooltipDesc[12] = "" + tooltipDesc[13] = "" + tooltipDesc[14] = "" + tooltipDesc[15] = "" --create the scroll bar local scrollRefreshFunc = function(self, data, offset, totalLines) for i = 1, totalLines do local index = i + offset - local spellTable = data[index] + ---@type savedcooldowninfoscrolldata + local savedCooldownScrollData = data[index] - if (spellTable) then - local spellId = spellTable[1] + if (savedCooldownScrollData) then + ---@type savedcooldowninfo + local savedCooldownInfo = savedCooldownScrollData.savedCooldownInfo + + local spellId = savedCooldownScrollData.spellId --get a line local line = self:GetLine(i) local spellName, _, spellIcon = Details.GetSpellInfo(spellId) @@ -227,16 +370,45 @@ function Details.Survey.OpenSpellCategoryScreen() line.SpellNameText.text = spellName local radioGroup = line.RadioGroup line.spellId = spellId + line.spellTable = savedCooldownScrollData + + local durationTextEntry = line.DurationEntry + durationTextEntry:SetText(savedCooldownInfo.duration or "") + + local cooldownTextEntry = line.CooldownEntry + local cdTime = savedCooldownInfo.cooldown + if (cdTime) then + cdTime = floor(cdTime / 1000) + else + cdTime = 0 + end + cooldownTextEntry:SetText(cdTime) local hasOptionSelected = false local radioGroupOptions = {} - for o in ipairs({"", "", "", "", "", "", "", "", ""}) do - hasOptionSelected = spellTable[2] ~= 1 + local cooldownType = savedCooldownInfo.type + + for o = 1, 10 do + if (not hasOptionSelected) then + hasOptionSelected = cooldownType ~= true + end + + local bOptionIsNone = o == 1 + radioGroupOptions[o] = { name = "", - param = o, - get = function() return spellTable[2] == o end, - callback = function(param, optionId) spellTable[2] = param; thisClassSavedTable[spellId] = param; Details.spell_category_latest_save = time() end, + + param = (bOptionIsNone and true) or (o - 1), + + get = function() + return (bOptionIsNone and cooldownType == true and true) or (o - 1 == cooldownType) + end, + + callback = function(param, radioButtonIndex) + savedCooldownInfo.type = param + savedCooldownScrollData.type = param + Details.spell_category_latest_save = time() + end, } end radioGroup:SetOptions(radioGroupOptions) @@ -256,16 +428,21 @@ function Details.Survey.OpenSpellCategoryScreen() if (not childrenFrame.haveTooltipAlready and childId > 1) then if (tooltipDesc[childId] and tooltipDesc[childId] ~= "") then childrenFrame:SetScript("OnEnter", function() - GameCooltip:Preset(2) - GameCooltip:AddLine(tooltipDesc[childId]) - GameCooltip:SetOwner(childrenFrame) - GameCooltip:Show() - GameCooltipFrame1:ClearAllPoints() - GameCooltipFrame1:SetPoint("bottomright", line, "bottomleft", -2, 0) + line.CurrectLineTexture:Show() + if (line.spellId) then + GameTooltip:SetOwner(line, "ANCHOR_NONE") + GameTooltip:SetPoint("bottomright", line, "bottomleft", -2, 0) + GameTooltip:SetSpellByID(line.spellId) + GameTooltip:Show() + end end) + childrenFrame:SetScript("OnLeave", function() + line.CurrectLineTexture:Hide() GameCooltip:Hide() + GameTooltip:Hide() end) + childrenFrame.haveTooltipAlready = true end end @@ -278,6 +455,7 @@ function Details.Survey.OpenSpellCategoryScreen() local lineOnEnter = function(self) self:SetBackdropColor(unpack(backdrop_color_on_enter)) + self.CurrectLineTexture:Show() if (self.spellId) then GameTooltip:SetOwner(self, "ANCHOR_NONE") GameTooltip:SetPoint("bottomright", self, "bottomleft", -2, 0) @@ -288,6 +466,7 @@ function Details.Survey.OpenSpellCategoryScreen() local lineOnLeave = function(self) self:SetBackdropColor(unpack(self.backdropColor)) + self.CurrectLineTexture:Hide() GameTooltip:Hide() end @@ -296,6 +475,45 @@ function Details.Survey.OpenSpellCategoryScreen() spellScroll:SetPoint("topleft", detailsSpellCategoryFrame, "topleft", startX, scrollY) detailsSpellCategoryFrame.SpellScroll = spellScroll + local onCommitSpellDuration = function(_, _, text, self) + local line = self:GetParent() + local amountOfTime = tonumber(text) + if (amountOfTime and type(amountOfTime) == "number") then + ---@type savedcooldowninfoscrolldata + local spellTable = line.spellTable + local savedCooldownInfo = spellTable.savedCooldownInfo + savedCooldownInfo.duration = amountOfTime + end + end + + local onCommitSpellCooldown = function(_, _, text, self) + local line = self:GetParent() + local amountOfTime = tonumber(text) + if (amountOfTime and type(amountOfTime) == "number") then + ---@type savedcooldowninfoscrolldata + local spellTable = line.spellTable + local savedCooldownInfo = spellTable.savedCooldownInfo + savedCooldownInfo.cooldown = amountOfTime + end + end + + local onEnterExportButton = function(self) + local line = self:GetParent() + line.CurrectLineTexture:Show() + if (line.spellId) then + GameTooltip:SetOwner(line, "ANCHOR_NONE") + GameTooltip:SetPoint("bottomright", line, "bottomleft", -2, 0) + GameTooltip:SetSpellByID(line.spellId) + GameTooltip:Show() + end + end + + local onLeaveExportButton = function(self) + local line = self:GetParent() + line.CurrectLineTexture:Hide() + GameTooltip:Hide() + end + local scrollCreateline = function(self, lineId) --self is spellScroll local line = CreateFrame("frame", "$parentLine" .. lineId, self, "BackdropTemplate") DF:Mixin(line, DF.HeaderFunctions) @@ -311,6 +529,13 @@ function Details.Survey.OpenSpellCategoryScreen() line.hasDataBackground = background background:Hide() + local currectLineTexture = line:CreateTexture(nil, "background") + currectLineTexture:SetColorTexture(1, .2, .2, 0.4) + currectLineTexture:SetPoint("topleft", line, "topleft", 0, 0) + currectLineTexture:SetPoint("bottomright", line, "bottomright", 0, 0) + currectLineTexture:Hide() + line.CurrectLineTexture = currectLineTexture + line:SetBackdrop(backdrop) if (lineId % 2 == 0) then line.backdropColor = backdrop_color @@ -331,6 +556,31 @@ function Details.Survey.OpenSpellCategoryScreen() --164 is the with of the first two headers (icon and spell name) local radioGroup = DF:CreateRadioGroup(line, {}, "$parentRadioGroup1", {width = maxLineWidth - 164, height = 20}, {offset_x = 0, amount_per_line = 7}) + --create a button to export the data shown in the this line + local exportButton = DF:CreateButton(line, function() Details.Survey.ExportSingleSpellCatogeryData(line) end, 70-2, 20, "Export") + exportButton:SetPoint("right", line, "right", -2, 0) + exportButton:SetTemplate("STANDARD_GRAY") + exportButton:SetHook("OnEnter", onEnterExportButton) + exportButton:SetHook("OnLeave", onLeaveExportButton) + + --create a text entry to allow the user to write the duration of the spell + local durationEntry = DF:CreateTextEntry(line, onCommitSpellDuration, 50, 20) + durationEntry:SetNumeric(true) + durationEntry:SetMaxLetters(5) + durationEntry:SetTemplate(DF:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE")) + durationEntry:SetPoint("right", exportButton, "left", -14, 0) + durationEntry:SetHook("OnEnter", onEnterExportButton) + durationEntry:SetHook("OnLeave", onLeaveExportButton) + + --create a text entry to allow the user to write the cooldown of the spell + local cooldownEntry = DF:CreateTextEntry(line, onCommitSpellCooldown, 50, 20) + cooldownEntry:SetNumeric(true) + cooldownEntry:SetMaxLetters(5) + cooldownEntry:SetTemplate(DF:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE")) + cooldownEntry:SetPoint("right", durationEntry, "left", -22, 0) + cooldownEntry:SetHook("OnEnter", onEnterExportButton) + cooldownEntry:SetHook("OnLeave", onLeaveExportButton) + line:AddFrameToHeaderAlignment(icon) line:AddFrameToHeaderAlignment(spellNameText) line:AddFrameToHeaderAlignment(radioGroup) @@ -339,6 +589,9 @@ function Details.Survey.OpenSpellCategoryScreen() line.Icon = icon line.SpellNameText = spellNameText line.RadioGroup = radioGroup + line.ExportButton = exportButton + line.DurationEntry = durationEntry + line.CooldownEntry = cooldownEntry return line end @@ -350,10 +603,21 @@ function Details.Survey.OpenSpellCategoryScreen() function spellScroll:RefreshScroll() --create a list of spells from the spell book + ---@type savedcooldowninfoscrolldata[] local indexedSpells = {} - for spellId, result in pairs(thisClassSavedTable) do - indexedSpells[#indexedSpells+1] = {spellId, result == true and 1 or result} + for spellId, savedCooldownInfo in pairs(thisClassSavedTable) do + ---@cast savedCooldownInfo savedcooldowninfo + local spellInfo = C_Spell.GetSpellInfo(spellId) + if (spellInfo) then + indexedSpells[#indexedSpells+1] = { + spellId = spellId, + type = savedCooldownInfo.type == true and 1 or savedCooldownInfo.type, + spellName = spellInfo.name, + savedCooldownInfo = savedCooldownInfo + } + end end + table.sort(indexedSpells, function(a, b) return a.spellName < b.spellName end) --sort by name spellScroll:SetData(indexedSpells) spellScroll:Refresh() end diff --git a/functions/slash.lua b/functions/slash.lua index 3a22c4b8..3f698d78 100644 --- a/functions/slash.lua +++ b/functions/slash.lua @@ -1539,7 +1539,7 @@ function SlashCmdList.DETAILS (msg, editbox) elseif (msg == "generateracialslist") then Details.GenerateRacialSpellList() - elseif (msg == "survey") then + elseif (msg == "spellcat") then Details.Survey.OpenSurveyPanel() else