diff --git a/CMFunctions.lua b/CMFunctions.lua index da03d83..e5dfe0b 100644 --- a/CMFunctions.lua +++ b/CMFunctions.lua @@ -625,7 +625,7 @@ function CombatMetronome:AutomaticSVCleanup() CombatMetronome.debug:Print("No SV cleanup necessary. Last SV cleanup has taken place less than a year ago on "..CombatMetronome.SV.lastSVCleanup.lastCleanup.day.."-"..CombatMetronome.SV.lastSVCleanup.lastCleanup.month.."-"..CombatMetronome.SV.lastSVCleanup.lastCleanup.year) elseif CombatMetronome.SV.automaticSVCleanup.lastCleanup.year == 0 then CombatMetronome.debug:Print("No SV cleanup has taken place yet. Starting automatic cleanup.") - self:CleanupSVEnstries() + self:CleanupSVEntries() elseif year > CombatMetronome.SV.automaticSVCleanup.lastCleanup.year and month >= CombatMetronome.SV.lastSVCleanup.lastCleanup.month then CombatMetronome.SV.lastSVCleanup = {["year"] = year, ["month"] = month, ["day"] = day} CombatMetronome.debug:Print("Last SV cleanup was about a year ago. Starting automatic cleanup.") diff --git a/CMProgressbar.lua b/CMProgressbar.lua index 305caf5..5575c22 100644 --- a/CMProgressbar.lua +++ b/CMProgressbar.lua @@ -176,7 +176,7 @@ function CombatMetronome:Update() cdTimer = time - start end - local duration = math.max(ability.heavy and 0 or (self.gcd or 1000), ability.delay) + (self.currentEvent.adjust or 0) + local duration = math.max(ability.heavy and self.SV.Progressbar.stopHATracking and 0 or (self.gcd or 1000), ability.delay) + (self.currentEvent.adjust or 0) -- local timeRemaining = ((start + duration + latency) - time) / 1000 or ((start + channelTime + latency) - time) < 0 and 0 local timeRemaining = (duration - cdTimer) / 1000 local castProgress = 1 - (cdTimer/duration) diff --git a/CMResources.lua b/CMResources.lua index d912266..5f7278e 100644 --- a/CMResources.lua +++ b/CMResources.lua @@ -107,7 +107,7 @@ function CombatMetronome:UpdateLabels() else self.Resources.hpLabel:SetHidden(true) end - if not CombatMetronome.SV.Resources.unlockExecuteReminder then + if not CombatMetronome.SV.Resources.unlockExecuteReminder and CombatMetronome.Resources.executeThreshold then if not IsUnitDead("reticleover") and showResources and CombatMetronome.SV.Resources.showExecuteReminder and hp~=1 and 100 * (hp / maxHp) <= CombatMetronome.Resources.executeThreshold and CombatMetronome.Resources.executeThreshold ~= 0 then self.Resources.executeLabel:SetHidden(false) else diff --git a/CMSettings.lua b/CMSettings.lua index 54802b7..412f493 100644 --- a/CMSettings.lua +++ b/CMSettings.lua @@ -1448,7 +1448,7 @@ function CombatMetronome:BuildMenu() }, { type = "slider", - name = "Modify skill adjust", + name = "Modify skill adjust (in ms)", min = -MAX_ADJUST, max = MAX_ADJUST, step = 1, diff --git a/Changelog.txt b/Changelog.txt index 6bbfd89..383b878 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -1,3 +1,8 @@ +2025-07-02 v1.7.3 +! Finally applied correct version, so it is now correctly shown in the settings menu +! Additional failsaves for not tracking all gcd +! Fixing minor spelling errors that caused bugs + 2025-06-05 v1.7.2 ! Bugfix for flame skull stacks ! Bugfix for channeled/cast abilities < 1 sec not releasing channel color correctly diff --git a/CombatMetronome.addon b/CombatMetronome.addon index 7676c66..fd7ce8b 100644 --- a/CombatMetronome.addon +++ b/CombatMetronome.addon @@ -1,11 +1,11 @@ ## Title: |ce11212C|rombat |ce11212M|retronome ## Description: The All-in-one Combat Timing bar. Track your heavy swings, ability cooldowns and cast/channels all in one bar to help you perfect your rotation timing and take advantage of abilty queuing with live latency information. ## Author: Darianopolis, |c2a52beb|rarny -## Version: 1.7.2 -## AddOnVersion: 010702 +## Version: 1.7.3 +## AddOnVersion: 010703 ## APIVersion: 101046 ## SavedVariables: CombatMetronomeSavedVars -## DependsOn: LibAddonMenu-2.0>=40 libAddonKeybinds>=5 DariansUtilities>=10801 LibChatMessage>=113 LibNotification>=15 +## DependsOn: LibAddonMenu-2.0>=40 libAddonKeybinds>=5 DariansUtilities>=10802 LibChatMessage>=113 LibNotification>=15 ## OptionalDependsOn: LibSetDetection>=4 ; This Add-on is not created by, affiliated with or sponsored by ZeniMax diff --git a/CombatMetronome.lua b/CombatMetronome.lua index 06ee1e9..afdee70 100644 --- a/CombatMetronome.lua +++ b/CombatMetronome.lua @@ -11,7 +11,7 @@ CombatMetronome = { version = { ["patch"] = 1, ["major"] = 7, - ["minor"] = 0, + ["minor"] = 3, }, API = GetAPIVersion(), beta = beta, @@ -317,19 +317,19 @@ function CombatMetronome:RegisterCM() self.cmRegistered = true - if CombatMetronome.SV.Progressbar.trackCollectibles or (CombatMetronome.SV.Progressbar.showMountNick and CombatMetronome.SV.Progressbar.trackMounting) then + if CombatMetronome.SV.Progressbar.trackGCD and (CombatMetronome.SV.Progressbar.trackCollectibles or (CombatMetronome.SV.Progressbar.showMountNick and CombatMetronome.SV.Progressbar.trackMounting)) then CombatMetronome:RegisterCollectiblesTracker() end - if CombatMetronome.SV.Progressbar.trackItems then + if CombatMetronome.SV.Progressbar.trackGCD and CombatMetronome.SV.Progressbar.trackItems then CombatMetronome:RegisterItemsTracker() end - if CombatMetronome:CheckForCombatEventsRegister() then + if CombatMetronome.SV.Progressbar.trackGCD and CombatMetronome:CheckForCombatEventsRegister() then CombatMetronome:RegisterCombatEvents() end - if CombatMetronome.SV.Progressbar.trackSynergies then + if CombatMetronome.SV.Progressbar.trackGCD and CombatMetronome.SV.Progressbar.trackSynergies then CombatMetronome:RegisterSynergyChanged() end -- if CombatMetronome.SV.debug.enabled then CombatMetronome.debug:Print("cm is registered") end @@ -340,22 +340,24 @@ function CombatMetronome:RegisterCollectiblesTracker() self.name.."CollectibleUsed", EVENT_COLLECTIBLE_UPDATED, function(_, id) - local name,_,icon,_,_,_,_,type,_ = GetCollectibleInfo(id) - if type == COLLECTIBLE_CATEGORY_TYPE_ASSISTANT or type == COLLECTIBLE_CATEGORY_TYPE_COMPANION then - CombatMetronome:SetIconsAndNamesNil() - self.Progressbar.collectibleInUse = {} - self.Progressbar.collectibleInUse.name = Util.Text.CropZOSString(name, "collectible") - self.Progressbar.collectibleInUse.icon = icon - zo_callLater(function() self.Progressbar.collectibleInUse = nil end, 1000) - end - if type == COLLECTIBLE_CATEGORY_TYPE_MOUNT then - -- if id == GetActiveCollectibleByType(COLLECTIBLE_CATEGORY_TYPE_MOUNT,GAMEPLAY_ACTOR_CATEGORY_PLAYER) then - self.Progressbar.activeMount.name = Util.Text.CropZOSString(GetCollectibleNickname(id), "collectible") - self.Progressbar.activeMount.icon = icon - if CombatMetronome.menu.icons[2] then - CombatMetronome.menu.icons[2]:SetTexture(icon) - end - -- end + if CombatMetronome.SV.Progressbar.trackGCD then + local name,_,icon,_,_,_,_,type,_ = GetCollectibleInfo(id) + if type == COLLECTIBLE_CATEGORY_TYPE_ASSISTANT or type == COLLECTIBLE_CATEGORY_TYPE_COMPANION then + CombatMetronome:SetIconsAndNamesNil() + self.Progressbar.collectibleInUse = {} + self.Progressbar.collectibleInUse.name = Util.Text.CropZOSString(name, "collectible") + self.Progressbar.collectibleInUse.icon = icon + zo_callLater(function() self.Progressbar.collectibleInUse = nil end, 1000) + end + if type == COLLECTIBLE_CATEGORY_TYPE_MOUNT then + -- if id == GetActiveCollectibleByType(COLLECTIBLE_CATEGORY_TYPE_MOUNT,GAMEPLAY_ACTOR_CATEGORY_PLAYER) then + self.Progressbar.activeMount.name = Util.Text.CropZOSString(GetCollectibleNickname(id), "collectible") + self.Progressbar.activeMount.icon = icon + if CombatMetronome.menu.icons[2] then + CombatMetronome.menu.icons[2]:SetTexture(icon) + end + -- end + end end end ) @@ -368,19 +370,21 @@ function CombatMetronome:RegisterItemsTracker() self.name.."InventoryItemUsed", EVENT_INVENTORY_ITEM_USED, function() - local bagSize = GetBagSize(1) - CombatMetronome:SetIconsAndNamesNil() - self.itemCache = {} - self.itemCache.name = {} - self.itemCache.icon = {} - for i = 1, bagSize do - self.itemCache.name[i] = Util.Text.CropZOSString(GetItemName(1, i), "item") - self.itemCache.icon[i] = GetItemInfo(1, i) + if CombatMetronome.SV.Progressbar.trackGCD then + local bagSize = GetBagSize(1) + CombatMetronome:SetIconsAndNamesNil() + self.itemCache = {} + self.itemCache.name = {} + self.itemCache.icon = {} + for i = 1, bagSize do + self.itemCache.name[i] = Util.Text.CropZOSString(GetItemName(1, i), "item") + self.itemCache.icon[i] = GetItemInfo(1, i) + end + -- zo_callLater(function() + -- self.itemCache = nil + -- end, + -- 400) end - -- zo_callLater(function() - -- self.itemCache = nil - -- end, - -- 400) end ) @@ -388,19 +392,21 @@ function CombatMetronome:RegisterItemsTracker() self.name.."InventoryItemInfo", EVENT_INVENTORY_SINGLE_SLOT_UPDATE, function(_, bagId, slotId, _, _, _, stackCountChange, _, _, _, _) - if not self.Progressbar.synergy.wasUsed and stackCountChange == -1 and self.itemCache then - CombatMetronome:SetIconsAndNamesNil() - self.Progressbar.itemUsed = { - ["name"] = self.itemCache.name[slotId], - ["icon"] = self.itemCache.icon[slotId] - } - zo_callLater(function() - if self.Progressbar.itemUsed then - self.Progressbar.itemUsed = nil - self.itemCache = nil - end - end, - 950) + if CombatMetronome.SV.Progressbar.trackGCD then + if not self.Progressbar.synergy.wasUsed and stackCountChange == -1 and self.itemCache then + CombatMetronome:SetIconsAndNamesNil() + self.Progressbar.itemUsed = { + ["name"] = self.itemCache.name[slotId], + ["icon"] = self.itemCache.icon[slotId] + } + zo_callLater(function() + if self.Progressbar.itemUsed then + self.Progressbar.itemUsed = nil + self.itemCache = nil + end + end, + 950) + end end end ) @@ -417,7 +423,7 @@ function CombatMetronome:RegisterCombatEvents() -- ------------------------------ function (_, res, err, aName, aGraphic, aSlotType, sName, sType, tName, tType, hVal, pType, dType, _, sUId, tUId, aId, _ ) - if Util.Text.CropZOSString(sName, "name") == self.currentCharacterName then + if Util.Text.CropZOSString(sName, "name") == self.currentCharacterName and CombatMetronome.SV.Progressbar.trackGCD then if IsMounted() and aId == 36432 and self.Progressbar.activeMount.action ~= "Dismounting" then CombatMetronome:SetIconsAndNamesNil() self.Progressbar.activeMount.action = "Dismounting" @@ -463,14 +469,16 @@ function CombatMetronome:RegisterSynergyChanged() self.name.."SynergyChanged", EVENT_SYNERGY_ABILITY_CHANGED, function() - local hasSynergy, name, icon, _, _ = GetCurrentSynergyInfo() - if hasSynergy then - -- if CombatMetronome.SV.debug.enabled then self.debug:Print("Found synergy: "..Util.Text.CropZOSString(name, "synergy")) end - self.Progressbar.synergy.name = Util.Text.CropZOSString(name, "synergy") - self.Progressbar.synergy.icon = icon - -- else - -- self.Progressbar.synergy = nil - -- if CombatMetronome.SV.debug.enabled then self.debug:Print("Synergy deleted") end + if CombatMetronome.SV.Progressbar.trackGCD then + local hasSynergy, name, icon, _, _ = GetCurrentSynergyInfo() + if hasSynergy then + -- if CombatMetronome.SV.debug.enabled then self.debug:Print("Found synergy: "..Util.Text.CropZOSString(name, "synergy")) end + self.Progressbar.synergy.name = Util.Text.CropZOSString(name, "synergy") + self.Progressbar.synergy.icon = icon + -- else + -- self.Progressbar.synergy = nil + -- if CombatMetronome.SV.debug.enabled then self.debug:Print("Synergy deleted") end + end end end ) @@ -721,7 +729,7 @@ end function CombatMetronome:DevTools() local ADDON_DEPENDENCY_VERSIONS = { - ["libAddonKeybinds"] = -1, ["LibAddonMenu-2.0"] = -1, ["LibChatMessage"] = -1, ["LibSetDetection"] = -1, ["LibNotification"] = -1, ["LibGroupBroadcast"] = -1, + ["libAddonKeybinds"] = -1, ["LibAddonMenu-2.0"] = -1, ["LibChatMessage"] = -1, ["LibSetDetection"] = -1, ["LibNotification"] = -1, ["LibGroupBroadcast"] = -1, ["LibAddonMenuOrderListBox"] = -1, } local function GetDependencyVersions() diff --git a/DariansUtilities/Changelog.txt b/DariansUtilities/Changelog.txt index de5f88d..a3588b5 100644 --- a/DariansUtilities/Changelog.txt +++ b/DariansUtilities/Changelog.txt @@ -1,3 +1,7 @@ +2025-07-02 v1.8.2 ++ Reenabling slot updated as ability trigger in an attempt to fix ability triggers +- Also reverting those changes right back. + 2025-06-06 v1.8.1 ! Bugfixes for stack tracking of GF and FS diff --git a/DariansUtilities/DariansUtilities.addon b/DariansUtilities/DariansUtilities.addon index d1b289c..902f053 100644 --- a/DariansUtilities/DariansUtilities.addon +++ b/DariansUtilities/DariansUtilities.addon @@ -1,8 +1,8 @@ ## Title: DariansUtilities ## Description: Darian's Mod Library ## Author: Darianopolis, |c2a52beb|rarny -## Version: 1.8.1 -## AddOnVersion: 10801 +## Version: 1.8.2 +## AddOnVersion: 10802 ## APIVersion: 101046 ## IsLibrary: true diff --git a/DariansUtilities/abilities/Ability.lua b/DariansUtilities/abilities/Ability.lua index 78582c3..cc30744 100644 --- a/DariansUtilities/abilities/Ability.lua +++ b/DariansUtilities/abilities/Ability.lua @@ -283,10 +283,10 @@ function Ability.Tracker:GCDCheck() local cdInfo = {[1] = { ["sR"] = 0, ["sD"] = 0 }, [2] = { ["sR"] = 0, ["sD"] = 0 }} for i = 3, 7 do sR, sD, global, _ = GetSlotCooldownInfo(i) + if j == 3 then break end if global then cdInfo[j] = { ["sR"] = sR, ["sD"] = sD } j = j+1 - if j == 2 then break end end end @@ -518,6 +518,8 @@ function Ability.Tracker:AbilityUsed(trigger) return end + -- local time = GetFrameTimeMilliseconds() + local gcdProgress, sR, sD if self.queuedEvent and self.queuedEvent.ability.heavy then sR, sD, _, _ = GetSlotCooldownInfo(2) @@ -528,6 +530,8 @@ function Ability.Tracker:AbilityUsed(trigger) if gcdProgress > 0.92 or (self.queuedEvent and self.queuedEvent.ability.heavy) then + -- if (self.queuedEvent and self.queuedEvent.ability.heavy) or self.abilityTrigger == time then + -- killing old self.currentEvent since new event is coming if self.currentEvent then self:CancelCurrentEvent("Old event over, new event coming") end @@ -558,6 +562,12 @@ function Ability.Tracker:AbilityUsed(trigger) end self.lastAbilityFinished = event.start + math.max(event.ability.delay, self.adjustedGCD) + + if trigger == "Slot updated" or trigger == "CD updated" then + self.abilityTriggerCounters.normal = self.abilityTriggerCounters.normal + 1 + end + -- else + -- self.abilityTrigger = time end end @@ -598,6 +608,37 @@ function Ability.Tracker:CallbackAbilityCancelled(event) -- end end +function Ability.Tracker:HandleSlotUpdated(e, slot) + if (slot < 3) then return + elseif self.queuedEvent and self.queuedEvent.slot ~= slot then return + end + + -- local remaining, duration, global, t = GetSlotCooldownInfo(slot) + local gcdProgress, sR, sD = self:GCDCheck() + local time = GetFrameTimeMilliseconds() + + if (sD > 0 and sR > 0) then + self.gcd = sD + + local oldStart = self.eventStart or 0 + self.eventStart = time + sR - sD + + -- if (oldStart ~= self.eventStart) then + -- _=self.log and d(""..time.." : Event start "..tostring(duration - remaining).."ms ago") + -- end + + if self.queuedEvent and self.eventStart > oldStart then + -- _=self.log and d(""..time.." : Moved queued "..self.queuedEvent.ability.name.." to current") + -- log(" Dispatching ", self.queuedEvent.ability.name) + -- log(" oldStart = ", oldStart) + -- log(" newStart = ", self.eventStart) + -- log(" current = ", GetFrameTimeMilliseconds()) + self:AbilityUsed("Slot updated") + -- self.abilityTriggerCounters.normal = self.abilityTriggerCounters.normal + 1 + end + end +end + function Ability.Tracker:HandleCooldownsUpdated() self.cdTriggerTime = GetFrameTimeMilliseconds() @@ -619,8 +660,8 @@ function Ability.Tracker:HandleCooldownsUpdated() self.eventStart = self.cdTriggerTime + sR - sD if self.eventStart + (CombatMetronome.SV.debug.triggers and CombatMetronome.SV.debug.triggerTimer or 170) >= self.cdTriggerTime then -- CombatMetronome.debug:Print("Firing "..self.queuedEvent.ability.name) - self:AbilityUsed("normal") - self.abilityTriggerCounters.normal = self.abilityTriggerCounters.normal + 1 + self:AbilityUsed("CD updated") + -- self.abilityTriggerCounters.normal = self.abilityTriggerCounters.normal + 1 end end end @@ -812,13 +853,13 @@ function Ability.Tracker:HandleCombatEvent(_, res, err, aName, _, aSlotTy return end -- local lightId = GetSlotBoundId(1) - if aSlotType == ACTION_SLOT_TYPE_LIGHT_ATTACK --[[and res == 2240 and time ~= self.lastLightAttack ]]then - if res == ACTION_RESULT_EFFECT_GAINED and time ~= self.lastLightAttack then + if aSlotType == ACTION_SLOT_TYPE_LIGHT_ATTACK or aSlotType == ACTION_SLOT_TYPE_WEAPON_ATTACK--[[and res == 2240 and time ~= self.lastLightAttack ]]then + if (res == ACTION_RESULT_EFFECT_GAINED or res == ACTION_RESULT_CRITICAL_DAMAGE or res == ACTION_RESULT_DAMAGE) and time ~= self.lastLightAttack then Ability.Tracker:CallbackLightAttackUsed(time) + self.lastLightAttack = time end --CombatMetronome.debug:Print(res.." - "..hVal.." - "..overflow) end - self.lastLightAttack = time else return end