diff --git a/Libs/DF/fw.lua b/Libs/DF/fw.lua index afe4c410..f118d64b 100644 --- a/Libs/DF/fw.lua +++ b/Libs/DF/fw.lua @@ -1,6 +1,6 @@ -local dversion = 228 +local dversion = 229 local major, minor = "DetailsFramework-1.0", dversion local DF, oldminor = LibStub:NewLibrary (major, minor) @@ -4238,3 +4238,5 @@ end _G.setfenv(func, newEnvironment) end + +----------------------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/Libs/DF/spells.lua b/Libs/DF/spells.lua index 2ee6c5d4..921ba1e7 100644 --- a/Libs/DF/spells.lua +++ b/Libs/DF/spells.lua @@ -974,8 +974,6 @@ DF.PotionIDs = { -- [] = true, -- [307165] = true, --Spiritual Anti-Venom - - } DF.FeastIDs = { diff --git a/Libs/DF/timebar.lua b/Libs/DF/timebar.lua index 0544ae79..77659df2 100644 --- a/Libs/DF/timebar.lua +++ b/Libs/DF/timebar.lua @@ -197,23 +197,27 @@ function TimeBarMetaFunctions:SetDirection(direction) self.direction = direction end +function TimeBarMetaFunctions:HasTimer() + return self.statusBar.hasTimer +end + function TimeBarMetaFunctions:StopTimer() if (self.statusBar.hasTimer) then + self.statusBar.hasTimer = nil local kill = self:RunHooksForWidget("OnTimerEnd", self.statusBar, self) if (kill) then return end - - local statusBar = self.statusBar - statusBar:SetScript("OnUpdate", nil) - - statusBar:SetMinMaxValues(0, 100) - statusBar:SetValue(100) - statusBar.rightText:SetText("") - - statusBar.spark:Hide() - statusBar.hasTimer = nil end + + local statusBar = self.statusBar + statusBar:SetScript("OnUpdate", nil) + + statusBar:SetMinMaxValues(0, 100) + statusBar:SetValue(100) + statusBar.rightText:SetText("") + + statusBar.spark:Hide() end local OnUpdateFunc = function(self, deltaTime) @@ -249,6 +253,12 @@ local OnUpdateFunc = function(self, deltaTime) end function TimeBarMetaFunctions:SetTimer(currentTime, startTime, endTime) + + if (not currentTime or currentTime == 0) then + self:StopTimer() + return + end + if (startTime and endTime) then if (self.statusBar.hasTimer and currentTime == self.statusBar.timeLeft1) then --it is the same timer called again @@ -266,6 +276,7 @@ function TimeBarMetaFunctions:SetTimer(currentTime, startTime, endTime) self.statusBar.timeLeft2 = currentTime end + --print("min|max values:", self.statusBar.starTime, self.statusBar.endTime) self.statusBar:SetMinMaxValues(self.statusBar.starTime, self.statusBar.endTime) if (self.direction == "right") then diff --git a/Libs/LibRaidStatus/LibRaidStatus.lua b/Libs/LibRaidStatus/LibRaidStatus.lua index 40ccc0a9..9cd80fa0 100644 --- a/Libs/LibRaidStatus/LibRaidStatus.lua +++ b/Libs/LibRaidStatus/LibRaidStatus.lua @@ -1,6 +1,6 @@ local major = "LibRaidStatus-1.0" -local CONST_LIB_VERSION = 11 +local CONST_LIB_VERSION = 13 LIB_RAID_STATUS_CAN_LOAD = false --declae the library within the LibStub @@ -17,7 +17,7 @@ LIB_RAID_STATUS_CAN_LOAD = false raidStatusLib.CanReceiveComms = false --print failures (when the function return an error) results to chat - local CONST_DIAGNOSTIC_ERRORS = true + local CONST_DIAGNOSTIC_ERRORS = false --print the data to be sent and data received from comm local CONST_DIAGNOSTIC_COMM = false @@ -120,15 +120,6 @@ LIB_RAID_STATUS_CAN_LOAD = false return newString end - --stract some indexes of a table - local selectIndexes = function(table, startIndex, amountIndexes) - local values = {} - for i = startIndex, startIndex+amountIndexes do - values[#values+1] = tonumber(table[i]) or 0 - end - return values - end - --return is a number is almost equal to another within a tolerance range function raidStatusLib.isNearlyEqual(value1, value2, tolerance) tolerance = tolerance or CONST_FRACTION_OF_A_SECOND @@ -140,6 +131,15 @@ LIB_RAID_STATUS_CAN_LOAD = false return raidStatusLib.CanReceiveComms end + --stract some indexes of a table + local selectIndexes = function(table, startIndex, amountIndexes) + local values = {} + for i = startIndex, startIndex+amountIndexes do + values[#values+1] = tonumber(table[i]) or 0 + end + return values + end + --transform a string table into a regular table --@table: a table with unknown values --@index: where in the table is the information we want @@ -160,7 +160,7 @@ LIB_RAID_STATUS_CAN_LOAD = false for i = indexStart, indexEnd, amountOfValues do if (valueIsTable) then local key = tonumber(table[i]) - local values = selectIndexes(table, i+1, 1) + local values = selectIndexes(table, i+1, max(amountOfValues-2, 1)) result[key] = values else local key = tonumber(table[i]) @@ -220,7 +220,6 @@ LIB_RAID_STATUS_CAN_LOAD = false --remove the first index (prefix) tremove(dataAsTable, 1) - --Details:Dump(dataAsTable) --trigger callbacks for i = 1, #callbackTable do @@ -659,19 +658,19 @@ LIB_RAID_STATUS_CAN_LOAD = false local cooldownTimeLeftCheck = function(tickerObject) local spellId = tickerObject.spellId tickerObject.cooldownTimeLeft = tickerObject.cooldownTimeLeft - CONST_COOLDOWN_CHECK_INTERVAL - local timeLeft, charges = raidStatusLib.cooldownManager.GetCooldownStatus(spellId) + local timeLeft, charges, startTime, duration = raidStatusLib.cooldownManager.GetCooldownStatus(spellId) --is the spell ready to use? if (timeLeft == 0) then --it's ready - raidStatusLib.cooldownManager.SendCooldownUpdate(spellId, 0, charges) + raidStatusLib.cooldownManager.SendCooldownUpdate(spellId, 0, charges, 0, 0) raidStatusLib.cooldownManager.cooldownTickers[spellId] = nil tickerObject:Cancel() else --check if the time left has changed if (not raidStatusLib.isNearlyEqual(tickerObject.cooldownTimeLeft, timeLeft, CONST_COOLDOWN_TIMELEFT_HAS_CHANGED)) then --there's a deviation, send a comm to communicate the change in the time left - raidStatusLib.cooldownManager.SendCooldownUpdate(spellId, timeLeft, charges) + raidStatusLib.cooldownManager.SendCooldownUpdate(spellId, timeLeft, charges, startTime, duration) tickerObject.cooldownTimeLeft = timeLeft end end @@ -724,11 +723,14 @@ LIB_RAID_STATUS_CAN_LOAD = false --update a single spell time and charges --called when the player casted a cooldown and when received a cooldown update from another player - local singleCooldownUpdate = function(unitName, spellId, newTimeLeft, newCharges) + --only update the db, no other action is taken + local singleCooldownUpdate = function(unitName, spellId, newTimeLeft, newCharges, startTime, duration) local unitCooldownTable = cooldownGetUnitTable(unitName) local spellIdTable = unitCooldownTable[spellId] or {} spellIdTable[1] = newTimeLeft spellIdTable[2] = newCharges + spellIdTable[3] = startTime + spellIdTable[4] = duration unitCooldownTable[spellId] = spellIdTable end @@ -736,6 +738,7 @@ LIB_RAID_STATUS_CAN_LOAD = false return raidStatusLib.cooldownManager.playerData end + --@playerName: name of the player function raidStatusLib.cooldownManager.GetPlayerCooldownTable(playerName) return raidStatusLib.cooldownManager.playerData[playerName] end @@ -746,18 +749,17 @@ LIB_RAID_STATUS_CAN_LOAD = false if (playerSpec) then if (LIB_RAID_STATUS_COOLDOWNS_BY_SPEC[playerSpec] and LIB_RAID_STATUS_COOLDOWNS_BY_SPEC[playerSpec][spellId]) then --get the cooldown time for this spell - local timeLeft, charges = raidStatusLib.cooldownManager.GetCooldownStatus(spellId) - + local timeLeft, charges, startTime, duration = raidStatusLib.cooldownManager.GetCooldownStatus(spellId) local playerName = UnitName("player") --update the time left - singleCooldownUpdate(playerName, spellId, timeLeft, charges) + singleCooldownUpdate(playerName, spellId, timeLeft, charges, startTime, duration) --trigger a public callback - raidStatusLib.publicCallback.TriggerCallback("CooldownUpdate", playerName, spellId, timeLeft, charges, raidStatusLib.cooldownManager.playerData) + raidStatusLib.publicCallback.TriggerCallback("CooldownUpdate", playerName, spellId, timeLeft, charges, startTime, duration, raidStatusLib.cooldownManager.playerData) --send to comm - raidStatusLib.cooldownManager.SendCooldownUpdate(spellId, timeLeft, charges) + raidStatusLib.cooldownManager.SendCooldownUpdate(spellId, timeLeft, charges, startTime, duration) --create a timer to monitor the time of this cooldown --as there's just a few of them to monitor, there's no issue on creating one timer per spell @@ -774,6 +776,8 @@ LIB_RAID_STATUS_CAN_LOAD = false local spellId = tonumber(dataAsArray[1]) local cooldownTimer = tonumber(dataAsArray[2]) local charges = tonumber(dataAsArray[3]) + local startTime = tonumber(dataAsArray[4]) + local duration = tonumber(dataAsArray[5]) --check integraty if (not spellId or spellId == 0) then @@ -784,13 +788,19 @@ LIB_RAID_STATUS_CAN_LOAD = false elseif (not charges) then return diagnosticError("cooldownManager|comm received|charges is invalid") + + elseif (not startTime) then + return diagnosticError("cooldownManager|comm received|startTime is invalid") + + elseif (not duration) then + return diagnosticError("cooldownManager|comm received|duration is invalid") end --update - singleCooldownUpdate(sourceName, spellId, cooldownTimer, charges) + singleCooldownUpdate(sourceName, spellId, cooldownTimer, charges, startTime, duration) --trigger a public callback - raidStatusLib.publicCallback.TriggerCallback("CooldownUpdate", sourceName, spellId, cooldownTimer, charges, raidStatusLib.cooldownManager.playerData) + raidStatusLib.publicCallback.TriggerCallback("CooldownUpdate", sourceName, spellId, cooldownTimer, charges, startTime, duration, raidStatusLib.cooldownManager.playerData) end) --when the player is ressed while in a group, send the cooldown list @@ -836,20 +846,22 @@ LIB_RAID_STATUS_CAN_LOAD = false local chargesAvailable, chargesTotal, start, duration = GetSpellCharges(spellId) if (chargesAvailable == chargesTotal) then - return 0, chargesTotal --all charges are ready to use + return 0, chargesTotal, 0, 0 --all charges are ready to use else --return the time to the next charge local timeLeft = start + duration - GetTime() - return ceil(timeLeft), chargesAvailable + local startTimeOffset = start - GetTime() + return ceil(timeLeft), chargesAvailable, startTimeOffset, duration --time left, charges, startTime end else local start, duration = GetSpellCooldown(spellId) if (start == 0) then --cooldown is ready - return 0, 1 + return 0, 1, 0, 0 --time left, charges, startTime else local timeLeft = start + duration - GetTime() - return ceil(timeLeft), 0 + local startTimeOffset = start - GetTime() + return ceil(timeLeft), 0, ceil(startTimeOffset), duration --time left, charges, startTime, duration end end else @@ -862,8 +874,8 @@ LIB_RAID_STATUS_CAN_LOAD = false --get the full cooldown list local playerCooldownList = raidStatusLib.cooldownManager.GetPlayerCooldownList() local dataToSend = CONST_COMM_COOLDOWNFULLLIST_PREFIX .. "," - --pack + --pack local playerCooldownString = raidStatusLib.PackTable(playerCooldownList) dataToSend = dataToSend .. playerCooldownString @@ -873,8 +885,8 @@ LIB_RAID_STATUS_CAN_LOAD = false end --send to comm a specific cooldown that was just used, a charge got available or its cooldown is over (ready to use) - function raidStatusLib.cooldownManager.SendCooldownUpdate(spellId, cooldownTimeLeft, charges) - local dataToSend = CONST_COMM_COOLDOWNUPDATE_PREFIX .. "," .. spellId .. "," .. cooldownTimeLeft .. "," .. charges + function raidStatusLib.cooldownManager.SendCooldownUpdate(spellId, cooldownTimeLeft, charges, startTime, duration) + local dataToSend = CONST_COMM_COOLDOWNUPDATE_PREFIX .. "," .. spellId .. "," .. cooldownTimeLeft .. "," .. charges .. "," .. startTime .. "," .. duration raidStatusLib.commHandler.SendCommData(dataToSend) diagnosticComm("SendCooldownUpdate| " .. dataToSend) --debug end @@ -883,15 +895,14 @@ LIB_RAID_STATUS_CAN_LOAD = false --@data: table received from comm --@source: player name function raidStatusLib.cooldownManager.OnReceiveCooldowns(data, source) - --unpack the table as a pairs table - local unpackedTable = raidStatusLib.UnpackTable(data, 1, true, true, 3) + --unpack the table as a pairs table | the cooldown info uses 5 indexes + local unpackedTable = raidStatusLib.UnpackTable(data, 1, true, true, 5) --add the list of cooldowns raidStatusLib.cooldownManager.AddUnitCooldownsList(source, unpackedTable) end raidStatusLib.commHandler.RegisterComm(CONST_COMM_COOLDOWNFULLLIST_PREFIX, raidStatusLib.cooldownManager.OnReceiveCooldowns) - --build a list with the local player cooldowns function raidStatusLib.cooldownManager.GetPlayerCooldownList() --get the player specId @@ -917,15 +928,19 @@ LIB_RAID_STATUS_CAN_LOAD = false --check if the player has the talent selected if (talentsHash[talentId]) then cooldowns[#cooldowns+1] = cooldownSpellId - local timeLeft, charges = raidStatusLib.cooldownManager.GetCooldownStatus(cooldownSpellId) + local timeLeft, charges, startTime, duration = raidStatusLib.cooldownManager.GetCooldownStatus(cooldownSpellId) cooldowns[#cooldowns+1] = timeLeft cooldowns[#cooldowns+1] = charges + cooldowns[#cooldowns+1] = startTime + cooldowns[#cooldowns+1] = duration end else cooldowns[#cooldowns+1] = cooldownSpellId - local timeLeft, charges = raidStatusLib.cooldownManager.GetCooldownStatus(cooldownSpellId) + local timeLeft, charges, startTime, duration = raidStatusLib.cooldownManager.GetCooldownStatus(cooldownSpellId) cooldowns[#cooldowns+1] = timeLeft cooldowns[#cooldowns+1] = charges + cooldowns[#cooldowns+1] = startTime + cooldowns[#cooldowns+1] = duration end end end @@ -935,6 +950,47 @@ LIB_RAID_STATUS_CAN_LOAD = false end end +--> vintage cooldown tracker +C_Timer.After(0.1, function() + local vintageCDTrackerFrame = CreateFrame("frame") + vintageCDTrackerFrame:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED") + local allCooldownsFromLib = LIB_RAID_STATUS_COOLDOWNS_INFO + local recentCastedSpells = {} + + vintageCDTrackerFrame:SetScript("OnEvent", function(self, event, ...) + if (event == "UNIT_SPELLCAST_SUCCEEDED") then + local unit, castGUID, spellId = ... + if (UnitInParty(unit) or UnitInRaid(unit)) then + local unitName = UnitName(unit) + local cooldownInfo = allCooldownsFromLib[spellId] + if (cooldownInfo and unitName and not raidStatusLib.cooldownManager.GetPlayerCooldownTable(unitName)) then + --check for cast_success spam from channel spells + local unitCastCooldown = recentCastedSpells[UnitGUID(unit)] + if (not unitCastCooldown) then + unitCastCooldown = {} + recentCastedSpells[UnitGUID(unit)] = unitCastCooldown + end + + if (not unitCastCooldown[spellId] or unitCastCooldown[spellId]+5 < GetTime()) then + unitCastCooldown[spellId] = GetTime() + --trigger a cooldown usage + + local duration = cooldownInfo.duration + --time left, charges, startTimeDeviation, duration + singleCooldownUpdate(unitName, spellId, duration, 0, 0, duration) + + --trigger a public callback + raidStatusLib.publicCallback.TriggerCallback("CooldownUpdate", unitName, spellId, duration, 0, 0, duration, raidStatusLib.cooldownManager.playerData) + end + end + end + end + end) +end) + + + + -------------------------------------------------------------------------------------------------------------------------------- --> ~equipment @@ -1227,9 +1283,9 @@ LIB_RAID_STATUS_CAN_LOAD = false local playerInfo = raidStatusLib.playerInfoManager.playerData[playerName] if (not playerInfo and createNew) then playerInfo = { - specId = 0, - renown = 1, - talents = {}, + specId = 0, + renown = 1, + talents = {}, conduits = {}, } raidStatusLib.playerInfoManager.playerData[playerName] = playerInfo @@ -1393,8 +1449,10 @@ function raidStatusLib.playerInfoManager.GetPlayerFullInfo() end - - +function raidStatusLib.playerInfoManager.onEnterWorld() + raidStatusLib.playerInfoManager.GetPlayerFullInfo() +end +raidStatusLib.internalCallback.RegisterCallback("onEnterWorld", raidStatusLib.playerInfoManager.onEnterWorld) -------------------------------------------------------------------------------------------------------------------------------- --> data diff --git a/boot.lua b/boot.lua index c381a7ef..be9a2da2 100644 --- a/boot.lua +++ b/boot.lua @@ -4,8 +4,8 @@ _ = nil _detalhes = LibStub("AceAddon-3.0"):NewAddon("_detalhes", "AceTimer-3.0", "AceComm-3.0", "AceSerializer-3.0", "NickTag-1.0") - _detalhes.build_counter = 8102 - _detalhes.alpha_build_counter = 8102 --if this is higher than the regular counter, use it instead + _detalhes.build_counter = 8154 + _detalhes.alpha_build_counter = 8154 --if this is higher than the regular counter, use it instead _detalhes.game_version = "v9.0.2" _detalhes.userversion = "v9.0.2." .. _detalhes.build_counter _detalhes.realversion = 144 --core version, this is used to check API version for scripts and plugins (see alias below) @@ -28,7 +28,18 @@ do local Loc = _G.LibStub("AceLocale-3.0"):GetLocale( "Details" ) local news = { - {"v9.0.1.8001.144", "December 19th, 2020"}, + {"v9.0.2.8154.144", "January 14th, 2021"}, + "Added total damage bars into the player list in the Breakdown window.", + "Added 'Square' or 'Roll' mode to Details! Streamer plugin, to change the statusbar mode to Squares, visit the options panel for the plugin.", + "Added Binding Shot to crowd control (Hunter)", + "Merged all whirlwind damage (Warrior).", + "Fixed errors on the 1-10 tutorial levels while playing Demon Hunters.", + "Fixed some cases of DeathLog not showing healing", + "Fixed windows making a group after '/details toggle', while the option to not make groups enabled.", + "Fixed some issues with the custom display 'Potion Used' and 'Health Potion & Stone'.", + "Fixed the breakdown window where using the comparisson tab sometimes made the frame to overlap with the aura tab.", + + {"v9.0.2.8001.144", "December 19th, 2020"}, "Added Details! Coach as a new experimental feature, you may want to test using /details coach", "Coach feature allows the raid leader to stay outside the raid while seeing in real time player deaths and damage information.", "Fixed issues with some raid encounters in Castle Nathria.", @@ -492,29 +503,31 @@ do --> plugins container _detalhes.StatusBar = {} --> maintain plugin menu - _detalhes.StatusBar.Menu = {} + _detalhes.StatusBar.Menu = {} --> plugins object - _detalhes.StatusBar.Plugins = {} + _detalhes.StatusBar.Plugins = {} --> name to plugin object - _detalhes.StatusBar.NameTable = {} + _detalhes.StatusBar.NameTable = {} --> constants - --[[global]] DETAILS_HEALTH_POTION_LIST = { - [250870] = true, --Coastal Healing Potion - [250872] = true, --Coastal Rejuvenation Potion - [6262] = true, --Warlock's Healthstone - [301308] = true, --Abyssal Healing Potion - [323436] = true --Phial of Serenity from Kyrians - } - --[[global]] DETAILS_HEALTH_POTION_ID = 250870 - --[[global]] DETAILS_REJU_POTION_ID = 250872 - --[[global]] DETAILS_MANA_POTION_ID = 250871 - --[[global]] DETAILS_FOCUS_POTION_ID = 252753 + --[[global]] DETAILS_HEALTH_POTION_ID = 307192 + --[[global]] DETAILS_REJU_POTION_ID = 307194 + --[[global]] DETAILS_MANA_POTION_ID = 307193 + --[[global]] DETAILS_FOCUS_POTION_ID = 307161 + --[[global]] DETAILS_HEALTHSTONE_ID = 6262 - --[[global]] DETAILS_INT_POTION_ID = 279151 - --[[global]] DETAILS_AGI_POTION_ID = 279152 - --[[global]] DETAILS_STR_POTION_ID = 279153 - --[[global]] DETAILS_STAMINA_POTION_ID = 279154 + --[[global]] DETAILS_INT_POTION_ID = 307162 + --[[global]] DETAILS_AGI_POTION_ID = 307159 + --[[global]] DETAILS_STR_POTION_ID = 307164 + --[[global]] DETAILS_STAMINA_POTION_ID = 307163 + + --[[global]] DETAILS_HEALTH_POTION_LIST = { + [DETAILS_HEALTH_POTION_ID] = true, --Healing Potion + [DETAILS_HEALTHSTONE_ID] = true, --Warlock's Healthstone + [DETAILS_REJU_POTION_ID] = true, --Rejuvenation Potion + [DETAILS_MANA_POTION_ID] = true, --Mana Potion + [323436] = true --Phial of Serenity (from Kyrians) + } _detalhes._detalhes_props = { DATA_TYPE_START = 1, --> Something on start diff --git a/classes/class_instance.lua b/classes/class_instance.lua index e6996e50..bc33345d 100644 --- a/classes/class_instance.lua +++ b/classes/class_instance.lua @@ -520,12 +520,14 @@ end else _detalhes:ReabrirTodasInstancias() - local instance1 = _detalhes:GetInstance (1) - local instance2 = _detalhes:GetInstance (2) + local instance1 = _detalhes:GetInstance(1) + local instance2 = _detalhes:GetInstance(2) if (instance1 and instance2) then - if (not instance1.ignore_mass_showhide and not instance2.ignore_mass_showhide) then - _detalhes:CheckCoupleWindows (instance1, instance2) + if (not Details.disable_window_groups) then + if (not instance1.ignore_mass_showhide and not instance2.ignore_mass_showhide) then + _detalhes:CheckCoupleWindows (instance1, instance2) + end end end end diff --git a/core/gears.lua b/core/gears.lua index 29dac3ce..56185da3 100644 --- a/core/gears.lua +++ b/core/gears.lua @@ -1761,11 +1761,9 @@ function Details.Database.StoreEncounter(combat) local myrole = UnitGroupRolesAssigned ("player") local mybest, onencounter = _detalhes.storage:GetBestFromPlayer (diff, encounter_id, myrole, _detalhes.playername, true) --> get dps or hps - local mybest2 = mybest[1] or 0 + local mybest2 = mybest and mybest[1] or 0 local myBestDps = mybest2 / onencounter.elapsed - --[12:18:37] Details!: error occurred on Details.Database.StoreEncounter(): Interface\AddOns\Details\core\gears.lua:1758: attempt to index local 'mybest' (a nil value) - if (mybest) then local d_one = 0 if (myrole == "DAMAGER" or myrole == "TANK") then diff --git a/frames/window_cdtracker.lua b/frames/window_cdtracker.lua index a2969866..5addc8bb 100644 --- a/frames/window_cdtracker.lua +++ b/frames/window_cdtracker.lua @@ -46,7 +46,7 @@ function Details.CooldownTracking.EnableTracker() raidStatusLib.RegisterCallback(Details.CooldownTracking, "CooldownListWiped", "CooldownListWipedFunc") raidStatusLib.RegisterCallback(Details.CooldownTracking, "CooldownUpdate", "CooldownUpdateFunc") - Details.CooldownTracking.RefreshScreenPanel() + Details.CooldownTracking.RefreshCooldownFrames() end function Details.CooldownTracking.DisableTracker() @@ -65,21 +65,100 @@ end function Details.CooldownTracking.CooldownListUpdateFunc() --print("CooldownListUpdate") - Details.CooldownTracking.RefreshScreenPanel() + Details.CooldownTracking.RefreshCooldowns() end function Details.CooldownTracking.CooldownListWipedFunc() --print("CooldownListWiped") - Details.CooldownTracking.RefreshScreenPanel() + Details.CooldownTracking.RefreshCooldowns() end function Details.CooldownTracking.CooldownUpdateFunc() - --print("CooldownUpdate") - Details.CooldownTracking.RefreshScreenPanel() + print("CooldownUpdate") + Details.CooldownTracking.RefreshCooldowns() end -function Details.CooldownTracking.RefreshScreenPanel() +function Details.CooldownTracking.HideAllBars() + for _, bar in ipairs (DetailsOnlineCDTrackerScreenPanel.bars) do + bar:ClearAllPoints() + bar:Hide() + end +end +function Details.CooldownTracking.GetOrCreateNewCooldownFrame(screenPanel, frameId) + local cooldownFrame = screenPanel.bars[frameId] + if (cooldownFrame) then + return cooldownFrame + end + + local cooldownFrame = DF:CreateTimeBar(screenPanel, [[Interface\AddOns\Details\images\bar_serenity]], width-2, bar_height-2, 100, nil, screenPanel:GetName() .. "CDFrame" .. frameId) + tinsert(screenPanel.bars, cooldownFrame) + return cooldownFrame +end + +function Details.CooldownTracking.SetupCooldownFrame(cooldownFrame, unitName, class, spellId) + local spellIcon = GetSpellTexture(spellId) + if (spellIcon) then + cooldownFrame:SetIcon(spellIcon, .1, .9, .1, .9) + + local classColor = C_ClassColor.GetClassColor(class) + cooldownFrame:SetStatusBarColor(classColor.r, classColor.g, classColor.b) + + cooldownFrame:SetLeftText(DF:RemoveRealmName(unitName)) + + cooldownFrame.spellId = spellId + cooldownFrame.class = class + cooldownFrame.unitName = unitName + end +end + + +function Details.CooldownTracking.SetupCooldownFrameTimer(cooldownFrame, startTime, endTime, currentTime) + if (currentTime == 0) then + cooldownFrame:StopTimer() + + else + cooldownFrame:SetTimer(currentTime, startTime, endTime) + end +end + +function Details.CooldownTracking.ProcessUnitCooldowns(unitId, statusBarFrameId, cooldownsOrganized) + local screenPanel = DetailsOnlineCDTrackerScreenPanel + if (not screenPanel) then + return + end + + local playerInfo = raidStatusLib.playerInfoManager.GetPlayerInfo() + local allCooldownsFromLib = LIB_RAID_STATUS_COOLDOWNS_BY_SPEC + local cooldownsEnabled = Details.ocd_tracker.cooldowns + + local unitName = UnitName(unitId) + local thisPlayerInfo = playerInfo[unitName] + local GUID = UnitGUID(unitId) + local _, unitClassEng, classId = UnitClass(unitId) + local unitSpec = (thisPlayerInfo and thisPlayerInfo.specId) or (Details:GetSpecFromSerial(GUID)) or 0 + + if (unitSpec and unitSpec ~= 0) then + local unitCooldowns = allCooldownsFromLib[unitSpec] + for spellId, cooldownType in pairs(unitCooldowns) do + if (cooldownsEnabled[spellId]) then + + local spellName = GetSpellInfo(spellId) + --print("CD:", spellName, unitName) --problema com shadowfiend do shadowpriest the mostra 2 vezes + + local cooldownFrame = Details.CooldownTracking.GetOrCreateNewCooldownFrame(screenPanel, statusBarFrameId) + Details.CooldownTracking.SetupCooldownFrame(cooldownFrame, unitName, unitClassEng, spellId) + tinsert(cooldownsOrganized[classId], cooldownFrame) + statusBarFrameId = statusBarFrameId + 1 + + screenPanel.playerCache[unitName] = screenPanel.playerCache[unitName] or {} + screenPanel.playerCache[unitName][spellId] = cooldownFrame + end + end + end +end + +function Details.CooldownTracking.RefreshCooldownFrames() local screenPanel = DetailsOnlineCDTrackerScreenPanel if (not screenPanel) then @@ -100,15 +179,29 @@ function Details.CooldownTracking.RefreshScreenPanel() libWindow.MakeDraggable(screenPanel) libWindow.RestorePosition(screenPanel) + screenPanel:RegisterEvent("GROUP_ROSTER_UPDATE") + screenPanel:SetScript("OnShow", function() + screenPanel:RegisterEvent("GROUP_ROSTER_UPDATE") + end) + screenPanel:SetScript("OnHide", function() + screenPanel:UnregisterEvent("GROUP_ROSTER_UPDATE") + end) + + screenPanel:SetScript("OnEvent", function(self, event) + if (event == "GROUP_ROSTER_UPDATE") then + if (screenPanel.scheduleRosterUpdate) then + return + end + screenPanel.scheduleRosterUpdate = C_Timer.NewTimer(1, Details.CooldownTracking.RefreshCooldownFrames) + end + end) + screenPanel.bars = {} + screenPanel.cooldownCache = Details.ocd_tracker.current_cooldowns + screenPanel.playerCache = {} end - function screenPanel.HideAllBars() - for _, bar in ipairs (screenPanel.bars) do - bar:ClearAllPoints() - bar:Hide() - end - end + screenPanel.scheduleRosterUpdate = nil if (Details.ocd_tracker.show_conditions.only_in_group) then if (not IsInGroup()) then @@ -125,31 +218,115 @@ function Details.CooldownTracking.RefreshScreenPanel() end end - local cooldownsAvailable = raidStatusLib.cooldownManager.GetCooldownTable() - local cooldownsEnabled = Details.ocd_tracker.cooldowns local cooldownsOrganized = {} - for classId = 1, 12 do --12 classes cooldownsOrganized[classId] = {} end + local numGroupMembers = GetNumGroupMembers() + local statusBarFrameId = 1 - for playerName, allPlayerCooldowns in pairs(cooldownsAvailable) do - local _, classEngName, classId = UnitClass(playerName) - if (classId) then - for spellId, cooldownInfo in pairs(allPlayerCooldowns) do - if (cooldownsEnabled[spellId]) then - cooldownsOrganized[classId][#cooldownsOrganized[classId]+1] = {playerName, cooldownInfo[1], cooldownInfo[2], classId, spellId, classEngName} + wipe(screenPanel.playerCache) + + if (IsInRaid()) then + for i = 1, numGroupMembers do + local unitId = "raid"..i + Details.CooldownTracking.ProcessUnitCooldowns(unitId, statusBarFrameId, cooldownsOrganized) + end + + elseif (IsInGroup()) then + for i = 1, numGroupMembers - 1 do + local unitId = "party"..i + Details.CooldownTracking.ProcessUnitCooldowns(unitId, statusBarFrameId, cooldownsOrganized) + end + + --player + Details.CooldownTracking.ProcessUnitCooldowns("player", statusBarFrameId, cooldownsOrganized) + end + + for classId = 1, 12 do --12 classes + table.sort(cooldownsOrganized[classId], function(t1, t2) return t1.spellId < t2.spellId end) + end + + Details.CooldownTracking.RefreshCooldowns() +end + +--esta passando NIL no startTime para o SetTimer +--o numero de frames criados é menor que o numero de frames mostrados, esta dando erro em local bar = screenPanel.bars[barIndex] 381 + +function Details.CooldownTracking.RefreshCooldowns() + local screenPanel = DetailsOnlineCDTrackerScreenPanel + if (not screenPanel) then + return + end + + --local cache saved with the character savedVariables + local cooldownCache = screenPanel.cooldownCache + local cooldownStatus = raidStatusLib.cooldownManager.GetCooldownTable() + local cooldownIndex = 1 + + for unitName, allPlayerCooldowns in pairs(cooldownStatus) do + for spellId, cooldownInfo in pairs(allPlayerCooldowns) do + local cooldownFrame = screenPanel.playerCache[unitName] and screenPanel.playerCache[unitName][spellId] + if (cooldownFrame) then + + local cooldownCache = cooldownCache[unitName] and cooldownCache[unitName][spellId] + if (not cooldownCache) then + --a cache with cooldown timers is saved within the host addon + screenPanel.cooldownCache[unitName] = screenPanel.cooldownCache[unitName] or {} + screenPanel.cooldownCache[unitName][spellId] = screenPanel.cooldownCache[unitName][spellId] or {} + cooldownCache = screenPanel.cooldownCache[unitName][spellId] end + + local timeLeft = cooldownInfo[1] + local charges = cooldownInfo[2] + local startTime = GetTime() - cooldownInfo[3] + local duration = cooldownInfo[4] + local endTime = startTime + duration + + --save the cooldown data in the host addon + cooldownCache[1] = timeLeft + cooldownCache[2] = charges + cooldownCache[3] = startTime + cooldownCache[4] = endTime + + cooldownFrame:Show() + + if (cooldownFrame.spellId ~= spellId or unitName ~= cooldownFrame.unitName) then + --there's a different spell showing or player using this frame + if (timeLeft ~= 0) then + local spellName = GetSpellInfo(spellId) + --print("set timer 3", spellName, startTime + timeLeft, startTime, endTime) + --cooldownFrame:SetTimer(startTime + timeLeft, startTime, endTime) + end + else + --spell and player are the same + if (timeLeft ~= 0) then + if (cooldownFrame:HasTimer()) then + if (cooldownFrame.timeLeft ~= timeLeft) then + local spellName = GetSpellInfo(spellId) + --print("set timer 1", spellName, startTime + timeLeft, startTime, endTime) + --cooldownFrame:SetTimer(startTime + timeLeft, startTime, endTime) + end + else + if (timeLeft ~= 0) then + local spellName = GetSpellInfo(spellId) + --print("set timer 2", spellName, startTime + timeLeft, startTime, endTime) + --cooldownFrame:SetTimer(startTime + timeLeft, startTime, endTime) + end + end + else + if (cooldownFrame:GetValue() ~= 100) then + cooldownFrame:StopTimer() + end + end + end + + cooldownIndex = cooldownIndex + 1 end end end - for classId = 1, 12 do --12 classes - local t = cooldownsOrganized[classId] - table.sort(t, function(t1, t2) return t1[5] < t2[5] end) --sort by spellId - end - - screenPanel.HideAllBars() + --[=[]] local cooldownIndex = 1 @@ -157,17 +334,8 @@ function Details.CooldownTracking.RefreshScreenPanel() local t = cooldownsOrganized[classId] for i = 1, #t do local bar = screenPanel.bars[cooldownIndex] - - if (not bar) then - local newBar = DF:CreateTimeBar(screenPanel, [[Interface\AddOns\Details\images\bar_serenity]], width-2, bar_height-2, 100, nil, "DetailsOCDBar" .. cooldownIndex) - tinsert(screenPanel.bars, newBar) - bar = newBar - end - cooldownIndex = cooldownIndex + 1 - bar:Show() - local cooldownTable = t[i] local classColor = C_ClassColor.GetClassColor(cooldownTable[6]) @@ -193,8 +361,10 @@ function Details.CooldownTracking.RefreshScreenPanel() end end end + --]=] cooldownIndex = cooldownIndex - 1 + print("total frames:", cooldownIndex) local xAnchor = 1 local defaultY = 0 @@ -263,7 +433,7 @@ function Details.OpenCDTrackerWindow() get = function() return Details.ocd_tracker.show_conditions.only_in_group end, set = function (self, fixedparam, value) Details.ocd_tracker.show_conditions.only_in_group = value - Details.CooldownTracking.RefreshScreenPanel() + Details.CooldownTracking.RefreshCooldownFrames() end, name = "Only in Group", desc = "Only in Group", @@ -274,7 +444,7 @@ function Details.OpenCDTrackerWindow() get = function() return Details.ocd_tracker.show_conditions.only_inside_instance end, set = function (self, fixedparam, value) Details.ocd_tracker.show_conditions.only_inside_instance = value - Details.CooldownTracking.RefreshScreenPanel() + Details.CooldownTracking.RefreshCooldownFrames() end, name = "Only Inside Instances", desc = "Only Inside Instances", diff --git a/frames/window_news.lua b/frames/window_news.lua index a117c6ed..7842b5ec 100644 --- a/frames/window_news.lua +++ b/frames/window_news.lua @@ -12,7 +12,6 @@ function Details:OpenNewsWindow(textToShow, dumpValues, keeptext) if (dumpValues == "change_log" or textToShow == "LeftButton") then newsFrame:Text (Loc ["STRING_VERSION_LOG"]) - --newsFrame:Icon ([[Interface\AddOns\Details\images\icons2]], {108/512, 189/512, 319/512, 400/512}) newsFrame:Show() return end @@ -46,7 +45,15 @@ function Details:OpenNewsWindow(textToShow, dumpValues, keeptext) if (keeptext) then newsFrame:Text ((DetailsNewsWindowText:GetText() or "") .. "\n\n" .. (textToShow or Loc ["STRING_VERSION_LOG"])) else + --show news newsFrame:Text (textToShow or Loc["STRING_VERSION_LOG"]) + --show textures + if (_detalhes.build_counter == 8154) then + newsFrame.imageFrame:Show() + newsFrame.imageFrame.texture:SetTexture([[interface/addons/details/images/news_images]]) + newsFrame.imageFrame.texture:SetSize(279, 452) + newsFrame.imageFrame.texture:SetTexCoord(0, 279/512, 0, 452/512) + end end end @@ -65,6 +72,16 @@ function Details:CreateOrOpenNewsWindow() frame:SetFrameStrata("FULLSCREEN") frame:SetMovable(true) frame:Hide() + DetailsFramework:ApplyStandardBackdrop(frame) + + frame.imageFrame = CreateFrame("frame", "DetailsNewsWindowImageFrame", frame, "BackdropTemplate") + frame.imageFrame:SetPoint("topleft", frame, "topright", 2, 0) + frame.imageFrame:SetPoint("bottomleft", frame, "bottomright", 2, 0) + frame.imageFrame:SetWidth(256) + DetailsFramework:ApplyStandardBackdrop(frame.imageFrame) + frame.imageFrame:Hide() + frame.imageFrame.texture = frame.imageFrame:CreateTexture(nil, "overlay") + frame.imageFrame.texture:SetPoint("topleft", frame.imageFrame, "topleft") local dumpFrame = g:CreateTextEntry(frame, function()end, 500, 512, "DumpTable", "$parentDumpTable") dumpFrame.editbox:SetMultiLine (true) diff --git a/frames/window_playerbreakdown.lua b/frames/window_playerbreakdown.lua index 38c45f7e..b892f07a 100644 --- a/frames/window_playerbreakdown.lua +++ b/frames/window_playerbreakdown.lua @@ -243,6 +243,7 @@ function _detalhes:AbreJanelaInfo (jogador, from_att_change, refresh, ShiftKeyDo info:ShowTabs() gump:Fade (info, 0) + Details:UpdateBreakdownPlayerList() --check which tab was selected and reopen that tab if (info.selectedTab == "Summary") then diff --git a/frames/window_playerbreakdown_list.lua b/frames/window_playerbreakdown_list.lua index c45ec0f6..1c800a2d 100644 --- a/frames/window_playerbreakdown_list.lua +++ b/frames/window_playerbreakdown_list.lua @@ -11,7 +11,7 @@ local scrollbox_size = {200, 405} local scrollbox_lines = 25 local player_line_height = 21.7 - local scrollbox_line_backdrop_color = {0, 0, 0, 0.5} + local scrollbox_line_backdrop_color = {0.2, 0.2, 0.2, 0.5} local scrollbox_line_backdrop_color_selected = {.6, .6, .1, 0.7} local scrollbox_line_backdrop_color_highlight = {.9, .9, .9, 0.5} local player_scroll_size = {180, 288} @@ -21,13 +21,17 @@ local refreshPlayerList = function(self, data, offset, totalLines) --update the scroll + local topResult = data[1] + if (topResult) then + topResult = topResult.total + end for i = 1, totalLines do local index = i + offset - local playerObject = data [index] + local playerObject = data[index] if (playerObject) then local line = self:GetLine(i) line.playerObject = playerObject - line:UpdateLine() + line:UpdateLine(topResult) end end end @@ -55,7 +59,7 @@ self.roleIcon:SetBlendMode("BLEND") end - local updatePlayerLine = function(self) + local updatePlayerLine = function(self, topResult) local playerSelected = Details:GetPlayerObjectFromBreakdownWindow() if (playerSelected and playerSelected == self.playerObject) then @@ -99,6 +103,12 @@ --set the player class name self.className:SetText(string.lower(_G.UnitClass(self.playerObject.nome) or self.playerObject:Class())) + + --set the statusbar + local r, g, b = self.playerObject:GetClassColor() + self.totalStatusBar:SetStatusBarColor(r, g, b, 1) + self.totalStatusBar:SetMinMaxValues(0, topResult) + self.totalStatusBar:SetValue(self.playerObject.total) end local createPlayerLine = function(self, index) @@ -127,20 +137,28 @@ playerName.textcolor = {1, 1, 1, .9} playerName.textsize = 11 local className = DF:CreateLabel(line, "", "GameFontNormal") - className.textcolor = {.5, .5, .5, .5} + className.textcolor = {.95, .8, .2, 0} className.textsize = 9 - + + local totalStatusBar = CreateFrame("statusbar", nil, line) + totalStatusBar:SetSize(scrollbox_size[1]-19-player_line_height, 4) + totalStatusBar:SetMinMaxValues(0, 100) + totalStatusBar:SetStatusBarTexture([[Interface\AddOns\Details\images\bar_skyline]]) + totalStatusBar:SetFrameLevel(line:GetFrameLevel()-1) + --setup anchors specIcon:SetPoint("topleft", line, "topleft", 0, 0) roleIcon:SetPoint("topleft", specIcon, "topright", 2, 0) --playerName:SetPoint("left", roleIcon, "right", 2, 0) playerName:SetPoint("topleft", specIcon, "topright", 2, -1) className:SetPoint("topleft", roleIcon, "bottomleft", 0, -2) - + totalStatusBar:SetPoint("bottomleft", specIcon, "bottomright", 0, 0) + line.specIcon = specIcon line.roleIcon = roleIcon line.playerName = playerName line.className = className + line.totalStatusBar = totalStatusBar line.UpdateLine = updatePlayerLine @@ -193,12 +211,12 @@ local unitClassID = classIds [playerObject:Class()] or 13 local unitName = playerObject:Name() local playerPosition = (((unitClassID or 0) + 128) ^ 4) + tonumber (string.byte (unitName, 1) .. "" .. string.byte (unitName, 2)) - tinsert(playerTable, {playerObject, playerPosition}) + tinsert(playerTable, {playerObject, playerPosition, playerObject.total}) end end end - table.sort (playerTable, DF.SortOrder2R) + table.sort (playerTable, DF.SortOrder3) local resultTable = {} for i = 1, #playerTable do @@ -208,7 +226,7 @@ return resultTable end - f:HookScript("OnShow", function() + function Details:UpdateBreakdownPlayerList() --run the update on the next tick C_Timer.After(0, function() local playerList = breakdownWindowPlayerList.BuildPlayerList() @@ -216,7 +234,12 @@ playerScroll:Refresh() playerScroll:Show() end) + end + + f:HookScript("OnShow", function() + Details:UpdateBreakdownPlayerList() end) end - - breakdownWindowPlayerList.CreatePlayerListFrame() \ No newline at end of file + + breakdownWindowPlayerList.CreatePlayerListFrame() + diff --git a/functions/playerclass.lua b/functions/playerclass.lua index a3aef963..b2932caf 100644 --- a/functions/playerclass.lua +++ b/functions/playerclass.lua @@ -95,7 +95,7 @@ do function _detalhes:GetSpecIcon (spec, useAlpha) if (spec) then - if (spec > 500) then --hack to new spec ids on new leveling zones from level 1-10 + if (spec > 600) then --hack to new spec ids on new leveling zones from level 1-10 spec = 65 end if (useAlpha) then diff --git a/functions/profiles.lua b/functions/profiles.lua index 713529f0..f65f2554 100644 --- a/functions/profiles.lua +++ b/functions/profiles.lua @@ -225,6 +225,8 @@ function _detalhes:ApplyProfile (profile_name, nosave, is_copy) _detalhes:Msg ("Profile Not Found.") return false end + + profile.ocd_tracker = nil --moved to local character saved --> always save the previous profile, except if nosave flag is up if (not nosave) then @@ -834,18 +836,6 @@ local default_profile = { 0, -- [3] }, }, - - --> ocd tracker test - ocd_tracker = { - enabled = false, - cooldowns = {}, - pos = {}, - show_conditions = { - only_in_group = true, - only_inside_instance = true, - }, - show_options = false, - }, --> minimap minimap = {hide = false, radius = 160, minimapPos = 220, onclick_what_todo = 1, text_type = 1, text_format = 3}, @@ -1116,6 +1106,19 @@ local default_player_data = { last_coach_name = false, }, + --> ocd tracker test + ocd_tracker = { + enabled = false, + cooldowns = {}, + pos = {}, + show_conditions = { + only_in_group = true, + only_inside_instance = true, + }, + show_options = false, + current_cooldowns = {}, + }, + --> force all fonts to have this outline force_font_outline = "", diff --git a/images/news_images.tga b/images/news_images.tga new file mode 100644 index 00000000..e0787cf9 Binary files /dev/null and b/images/news_images.tga differ diff --git a/startup.lua b/startup.lua index fe7fd9a5..2b484b74 100644 --- a/startup.lua +++ b/startup.lua @@ -500,6 +500,8 @@ function Details:StartMeUp() --I'll never stop! Details:Msg("use '/details me' macro to open the player breakdown for you!") end + Details.cached_specs[UnitGUID("player")] = GetSpecializationInfo(GetSpecialization() or 0) + function Details:InstallOkey() return true end