mirror of
https://github.com/brues-code/SuperCleveRoidMacros.git
synced 2026-09-16 03:38:00 +00:00
fix stopmacro and fix mouseover in other addons
This commit is contained in:
@@ -3,6 +3,45 @@ CleveRoids.RegisterActionEventHandler(function(slot, event)
|
||||
|
||||
local button = getglobal("BActionButton" .. slot)
|
||||
if button then
|
||||
BActionButton.Update(button)
|
||||
-- For slot change events, do a full button update
|
||||
if event == "ACTIONBAR_SLOT_CHANGED" then
|
||||
BActionButton.Update(button)
|
||||
end
|
||||
|
||||
-- COOLDOWN FIX: Always update the cooldown using CleveRoids' active spell
|
||||
-- Bongos uses button.cooldown for the cooldown frame
|
||||
local cooldownFrame = button.cooldown or getglobal(button:GetName() .. "Cooldown")
|
||||
if cooldownFrame then
|
||||
local start, duration, enable
|
||||
local spellSlot, bookType = CleveRoids.GetActionSpellSlot(slot)
|
||||
|
||||
if spellSlot and bookType then
|
||||
start, duration, enable = GetSpellCooldown(spellSlot, bookType)
|
||||
else
|
||||
local actions = CleveRoids.GetAction(slot)
|
||||
local actionToCheck = actions and (actions.active or actions.tooltip)
|
||||
if actionToCheck and actionToCheck.item then
|
||||
local item = actionToCheck.item
|
||||
if item.bagID and item.slot then
|
||||
start, duration, enable = GetContainerItemCooldown(item.bagID, item.slot)
|
||||
elseif item.inventoryID then
|
||||
start, duration, enable = GetInventoryItemCooldown("player", item.inventoryID)
|
||||
end
|
||||
elseif actionToCheck then
|
||||
local slotId = tonumber(actionToCheck.action)
|
||||
if slotId and slotId >= 1 and slotId <= 19 then
|
||||
start, duration, enable = GetInventoryItemCooldown("player", slotId)
|
||||
end
|
||||
end
|
||||
|
||||
if not start then
|
||||
start, duration, enable = GetActionCooldown(slot)
|
||||
end
|
||||
end
|
||||
|
||||
if start and duration then
|
||||
CooldownFrame_SetTimer(cooldownFrame, start, duration, (enable and enable > 0) and enable or 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
+92
-8
@@ -367,17 +367,75 @@ function Extension.RegisterPfUIActionEventHandler()
|
||||
|
||||
-- Register a handler that will be called whenever CleveRoids updates macro states
|
||||
if CleveRoids.RegisterActionEventHandler then
|
||||
Extension.DLOG("Registering pfUI action event handler")
|
||||
CleveRoids.RegisterActionEventHandler(function(slot, event, ...)
|
||||
-- Trigger pfUI's button update for this slot
|
||||
-- Mark the slot for update in pfUI's cache, which will be processed on next OnUpdate
|
||||
if pfUI.bars and pfUI.bars.update then
|
||||
pfUI.bars.update[slot] = true
|
||||
local button = pfUI.bars and pfUI.bars.buttons and pfUI.bars.buttons[slot]
|
||||
|
||||
if Extension.Debug then
|
||||
DEFAULT_CHAT_FRAME:AddMessage(string.format(
|
||||
"|cff00ff00[pfUI CD]|r slot=%s event=%s button=%s cd=%s",
|
||||
tostring(slot), tostring(event),
|
||||
button and "yes" or "no",
|
||||
(button and button.cd) and "yes" or "no"
|
||||
))
|
||||
end
|
||||
|
||||
-- Also directly call ButtonFullUpdate if the button exists
|
||||
local button = pfUI.bars and pfUI.bars.buttons and pfUI.bars.buttons[slot]
|
||||
if button and pfUI.bars.ButtonFullUpdate then
|
||||
pfUI.bars.ButtonFullUpdate(button)
|
||||
-- For slot change events, do a full button update
|
||||
if event == "ACTIONBAR_SLOT_CHANGED" then
|
||||
-- Trigger pfUI's button update for this slot
|
||||
-- Mark the slot for update in pfUI's cache, which will be processed on next OnUpdate
|
||||
if pfUI.bars and pfUI.bars.update then
|
||||
pfUI.bars.update[slot] = true
|
||||
end
|
||||
|
||||
-- Also directly call ButtonFullUpdate if the button exists
|
||||
if button and pfUI.bars.ButtonFullUpdate then
|
||||
pfUI.bars.ButtonFullUpdate(button)
|
||||
end
|
||||
end
|
||||
|
||||
-- COOLDOWN FIX: Always update cooldowns explicitly
|
||||
-- pfUI's macro scanner caches spell info and doesn't know about
|
||||
-- CleveRoids' conditional spell changes. Manually update the cooldown
|
||||
-- using the active spell from CleveRoids.
|
||||
-- Note: pfUI uses button.cd for cooldown frame (not button.cooldown)
|
||||
if button and button.cd then
|
||||
local start, duration, enable
|
||||
local spellSlot, bookType = CleveRoids.GetActionSpellSlot(slot)
|
||||
|
||||
if spellSlot and bookType then
|
||||
-- Active spell found - get its cooldown
|
||||
start, duration, enable = GetSpellCooldown(spellSlot, bookType)
|
||||
else
|
||||
-- No active spell - check for item cooldown
|
||||
local actions = CleveRoids.GetAction(slot)
|
||||
local actionToCheck = actions and (actions.active or actions.tooltip)
|
||||
if actionToCheck and actionToCheck.item then
|
||||
local item = actionToCheck.item
|
||||
if item.bagID and item.slot then
|
||||
start, duration, enable = GetContainerItemCooldown(item.bagID, item.slot)
|
||||
elseif item.inventoryID then
|
||||
start, duration, enable = GetInventoryItemCooldown("player", item.inventoryID)
|
||||
end
|
||||
elseif actionToCheck then
|
||||
-- Check for equipment slot (e.g., trinket)
|
||||
local slotId = tonumber(actionToCheck.action)
|
||||
if slotId and slotId >= 1 and slotId <= 19 then
|
||||
start, duration, enable = GetInventoryItemCooldown("player", slotId)
|
||||
end
|
||||
end
|
||||
|
||||
-- Fallback: use the hooked GetActionCooldown for non-CleveRoids actions
|
||||
if not start then
|
||||
start, duration, enable = GetActionCooldown(slot)
|
||||
end
|
||||
end
|
||||
|
||||
-- Apply cooldown if we have valid data
|
||||
-- Ensure enable is at least 1 (0 can hide the cooldown)
|
||||
if start and duration then
|
||||
CooldownFrame_SetTimer(button.cd, start, duration, (enable and enable > 0) and enable or 1)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
@@ -518,6 +576,24 @@ function Extension.OnLoad()
|
||||
|
||||
-- Initial compatibility check
|
||||
Extension.SetupCompatibility()
|
||||
|
||||
-- Add slash command to toggle pfUI cooldown debug
|
||||
-- Usage: /pfuicd to toggle debug mode
|
||||
SlashCmdList["PFUICD"] = function()
|
||||
Extension.Debug = not Extension.Debug
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00[pfUI Compat]|r Debug mode: " .. (Extension.Debug and "ON" or "OFF"))
|
||||
if Extension.Debug then
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00[pfUI Compat]|r Handler registered: " .. (Extension.actionHandlerRegistered and "YES" or "NO"))
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00[pfUI Compat]|r pfUI detected: " .. (Extension.pfUILoaded and "YES" or "NO"))
|
||||
if pfUI and pfUI.bars then
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00[pfUI Compat]|r pfUI.bars exists: YES")
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00[pfUI Compat]|r pfUI.bars.buttons: " .. (pfUI.bars.buttons and "YES" or "NO"))
|
||||
else
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00[pfUI Compat]|r pfUI.bars exists: NO")
|
||||
end
|
||||
end
|
||||
end
|
||||
SLASH_PFUICD1 = "/pfuicd"
|
||||
end
|
||||
|
||||
function Extension.ADDON_LOADED()
|
||||
@@ -536,6 +612,14 @@ end
|
||||
function Extension.PLAYER_LOGIN()
|
||||
-- Final check after everything is loaded
|
||||
Extension.SetupCompatibility()
|
||||
|
||||
-- Print startup status
|
||||
if Extension.pfUILoaded then
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00[SCRM]|r pfUI compatibility loaded. Use /pfuicd for debug.")
|
||||
if not Extension.actionHandlerRegistered then
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cffff0000[SCRM]|r WARNING: pfUI action handler NOT registered!")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Utility: Schedule a delayed function call (if not already defined)
|
||||
|
||||
+13
-7
@@ -2592,6 +2592,12 @@ function CleveRoids.ValidateUnitDebuff(unit, args)
|
||||
return false -- Debuff doesn't exist, so all comparisons fail
|
||||
end
|
||||
|
||||
-- For non-player units, get time remaining once (used for all time comparisons)
|
||||
local nonPlayerTimeRemaining = nil
|
||||
if unit ~= "player" then
|
||||
nonPlayerTimeRemaining = _get_debuff_timeleft(unit, args.name) or 0
|
||||
end
|
||||
|
||||
-- ALL comparisons must pass (AND logic)
|
||||
for _, comp in ipairs(args.comparisons) do
|
||||
if not ops[comp.operator] then
|
||||
@@ -2604,8 +2610,8 @@ function CleveRoids.ValidateUnitDebuff(unit, args)
|
||||
elseif unit == "player" then
|
||||
value_to_check = remaining or 0
|
||||
else
|
||||
-- Non-player units don't have remaining time, only check existence
|
||||
return found
|
||||
-- Non-player units: use time remaining from libdebuff
|
||||
value_to_check = nonPlayerTimeRemaining
|
||||
end
|
||||
|
||||
if not cmp[comp.operator](value_to_check, comp.amount) then
|
||||
@@ -4164,7 +4170,7 @@ CleveRoids.Keywords = {
|
||||
return true
|
||||
end
|
||||
|
||||
return CleveRoids.ValidatePower(conditionals.target, args.operator, args.amount)
|
||||
return CleveRoids.ValidatePower(conditionals.target or "target", args.operator, args.amount)
|
||||
end, conditionals, "power")
|
||||
end,
|
||||
|
||||
@@ -4215,7 +4221,7 @@ CleveRoids.Keywords = {
|
||||
return true
|
||||
end
|
||||
|
||||
return CleveRoids.ValidateRawPower(conditionals.target, args.operator, args.amount)
|
||||
return CleveRoids.ValidateRawPower(conditionals.target or "target", args.operator, args.amount)
|
||||
end, conditionals, "rawpower")
|
||||
end,
|
||||
|
||||
@@ -4295,7 +4301,7 @@ CleveRoids.Keywords = {
|
||||
return true
|
||||
end
|
||||
|
||||
return CleveRoids.ValidateHp(conditionals.target, args.operator, args.amount)
|
||||
return CleveRoids.ValidateHp(conditionals.target or "target", args.operator, args.amount)
|
||||
end, conditionals, "hp")
|
||||
end,
|
||||
|
||||
@@ -4326,7 +4332,7 @@ CleveRoids.Keywords = {
|
||||
return true
|
||||
end
|
||||
|
||||
return CleveRoids.ValidateLevel(conditionals.target, args.operator, args.amount)
|
||||
return CleveRoids.ValidateLevel(conditionals.target or "target", args.operator, args.amount)
|
||||
end, conditionals, "level")
|
||||
end,
|
||||
|
||||
@@ -4382,7 +4388,7 @@ CleveRoids.Keywords = {
|
||||
rawhp = function(conditionals)
|
||||
return Multi(conditionals.rawhp, function(args)
|
||||
if type(args) ~= "table" then return false end
|
||||
return CleveRoids.ValidateRawHp(conditionals.target, args.operator, args.amount)
|
||||
return CleveRoids.ValidateRawHp(conditionals.target or "target", args.operator, args.amount)
|
||||
end, conditionals, "rawhp")
|
||||
end,
|
||||
|
||||
|
||||
@@ -134,6 +134,7 @@ end
|
||||
-- /startattack hook
|
||||
CleveRoids.Hooks.STARTATTACK_SlashCmd = SlashCmdList.STARTATTACK
|
||||
SlashCmdList.STARTATTACK = function(msg)
|
||||
if CleveRoids.stopMacroFlag then return end
|
||||
msg = msg or ""
|
||||
if string.find(msg, "%[") then
|
||||
CleveRoids.DoConditionalStartAttack(msg)
|
||||
@@ -145,6 +146,7 @@ end
|
||||
-- /stopattack hook
|
||||
CleveRoids.Hooks.STOPATTACK_SlashCmd = SlashCmdList.STOPATTACK
|
||||
SlashCmdList.STOPATTACK = function(msg)
|
||||
if CleveRoids.stopMacroFlag then return end
|
||||
msg = msg or ""
|
||||
if string.find(msg, "%[") then
|
||||
-- If conditionals are present, let the function handle it.
|
||||
@@ -159,6 +161,7 @@ end
|
||||
-- /stopcasting hook
|
||||
CleveRoids.Hooks.STOPCASTING_SlashCmd = SlashCmdList.STOPCASTING
|
||||
SlashCmdList.STOPCASTING = function(msg)
|
||||
if CleveRoids.stopMacroFlag then return end
|
||||
msg = msg or ""
|
||||
if string.find(msg, "%[") then
|
||||
-- If conditionals are present, let the function handle it.
|
||||
@@ -170,8 +173,10 @@ SlashCmdList.STOPCASTING = function(msg)
|
||||
end
|
||||
end
|
||||
|
||||
-- /unqueue hook
|
||||
CleveRoids.Hooks.UNQUEUE_SlashCmd = SlashCmdList.UNQUEUE
|
||||
SlashCmdList.UNQUEUE = function(msg)
|
||||
if CleveRoids.stopMacroFlag then return end
|
||||
msg = msg or ""
|
||||
if string.find(msg, "%[") then
|
||||
-- If conditionals are present, let the function handle it.
|
||||
@@ -185,6 +190,7 @@ end
|
||||
-- /cast hook
|
||||
CleveRoids.Hooks.CAST_SlashCmd = SlashCmdList.CAST
|
||||
SlashCmdList.CAST = function(msg)
|
||||
if CleveRoids.stopMacroFlag then return end
|
||||
if msg and string.find(msg, "[%[%?!~{]") then
|
||||
CleveRoids.DoCast(msg)
|
||||
else
|
||||
|
||||
@@ -2075,6 +2075,12 @@ function CleveRoids.TestAction(cmd, args)
|
||||
end
|
||||
|
||||
function CleveRoids.DoWithConditionals(msg, hook, fixEmptyTargetFunc, targetBeforeAction, action)
|
||||
-- Check stopmacro flag (skip non-STOPMACRO commands when flag is set)
|
||||
-- This enables /stopmacro to work without SuperMacro for vanilla macros
|
||||
if CleveRoids.stopMacroFlag and action ~= "STOPMACRO" then
|
||||
return false
|
||||
end
|
||||
|
||||
local msg, conditionals = CleveRoids.GetParsedMsg(msg)
|
||||
|
||||
-- Debug: Log parsed msg and action type
|
||||
@@ -2315,6 +2321,11 @@ function CleveRoids.DoCastPet(msg)
|
||||
end
|
||||
|
||||
function CleveRoids.DoTarget(msg)
|
||||
-- Check stopmacro flag
|
||||
if CleveRoids.stopMacroFlag then
|
||||
return false
|
||||
end
|
||||
|
||||
local action, conditionals = CleveRoids.GetParsedMsg(msg)
|
||||
|
||||
if action ~= "" or type(conditionals) ~= "table" or not next(conditionals) then
|
||||
@@ -2611,6 +2622,11 @@ end
|
||||
-- Also checks if a condition is a spell so that you can mix item and spell use
|
||||
-- msg: The raw message intercepted from a /use or /equip command
|
||||
function CleveRoids.DoUse(msg)
|
||||
-- Check stopmacro flag
|
||||
if CleveRoids.stopMacroFlag then
|
||||
return false
|
||||
end
|
||||
|
||||
local handled = false
|
||||
|
||||
local action = function(msg)
|
||||
@@ -3279,6 +3295,9 @@ function CleveRoids.DoCastSequence(sequence)
|
||||
end
|
||||
|
||||
CleveRoids.DoConditionalCancelAura = function(msg)
|
||||
-- Check stopmacro flag
|
||||
if CleveRoids.stopMacroFlag then return false end
|
||||
|
||||
local s = CleveRoids.Trim(msg or "")
|
||||
if s == "" then return false end
|
||||
|
||||
@@ -3301,6 +3320,13 @@ local UnitAffectingCombat = UnitAffectingCombat
|
||||
local pairs = pairs
|
||||
|
||||
function CleveRoids.OnUpdate(self)
|
||||
-- Clear stopmacro flag at the start of each frame
|
||||
-- This ensures /stopmacro only affects commands in the same frame (same macro execution)
|
||||
-- Without SuperMacro, this is necessary because we can't hook into macro line execution
|
||||
if CleveRoids.stopMacroFlag then
|
||||
CleveRoids.stopMacroFlag = false
|
||||
end
|
||||
|
||||
-- PERFORMANCE: Single GetTime() call per frame
|
||||
local time = GetTime()
|
||||
|
||||
@@ -4678,6 +4704,59 @@ function CleveRoids.Frame:SPELL_UPDATE_COOLDOWN()
|
||||
if CleveRoidMacros.realtime == 0 then
|
||||
CleveRoids.QueueActionUpdate()
|
||||
end
|
||||
|
||||
-- COOLDOWN FIX: Explicitly update cooldowns on all managed action buttons
|
||||
-- This ensures cooldowns display correctly even when the active action hasn't changed
|
||||
CleveRoids.UpdateAllManagedCooldowns()
|
||||
end
|
||||
|
||||
-- Helper function to update cooldowns on all CleveRoids-managed action buttons
|
||||
function CleveRoids.UpdateAllManagedCooldowns()
|
||||
local Actions = CleveRoids.Actions
|
||||
if not Actions then return end
|
||||
|
||||
local handlerCount = CleveRoids.actionEventHandlers and table.getn(CleveRoids.actionEventHandlers) or 0
|
||||
if CleveRoids.cooldownDebug then
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cffff8800[CD Update]|r Updating cooldowns, " .. handlerCount .. " handlers registered")
|
||||
end
|
||||
|
||||
for slot, actions in pairs(Actions) do
|
||||
if actions then
|
||||
-- Get the cooldown info for this slot
|
||||
local start, duration, enable = GetActionCooldown(slot)
|
||||
|
||||
-- Update Blizzard action buttons
|
||||
local page = floor((slot - 1) / NUM_ACTIONBAR_BUTTONS) + 1
|
||||
local pageSlot = slot - (page - 1) * NUM_ACTIONBAR_BUTTONS
|
||||
|
||||
local button
|
||||
if slot >= 73 then
|
||||
button = _G["BonusActionButton" .. pageSlot]
|
||||
elseif slot >= 61 then
|
||||
button = _G["MultiBarBottomLeftButton" .. pageSlot]
|
||||
elseif slot >= 49 then
|
||||
button = _G["MultiBarBottomRightButton" .. pageSlot]
|
||||
elseif slot >= 37 then
|
||||
button = _G["MultiBarLeftButton" .. pageSlot]
|
||||
elseif slot >= 25 then
|
||||
button = _G["MultiBarRightButton" .. pageSlot]
|
||||
elseif page == CURRENT_ACTIONBAR_PAGE then
|
||||
button = _G["ActionButton" .. pageSlot]
|
||||
end
|
||||
|
||||
if button then
|
||||
local cooldown = _G[button:GetName() .. "Cooldown"]
|
||||
if cooldown and start and duration then
|
||||
CooldownFrame_SetTimer(cooldown, start, duration, (enable and enable > 0) and enable or 1)
|
||||
end
|
||||
end
|
||||
|
||||
-- Notify action event handlers (for pfUI/Bongos) about the cooldown update
|
||||
for _, fn_h in ipairs(CleveRoids.actionEventHandlers) do
|
||||
fn_h(slot, "ACTIONBAR_UPDATE_COOLDOWN")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
-- PERFORMANCE OPTIMIZATION: Throttled event handlers to reduce CPU spam
|
||||
-- UNIT_AURA can fire dozens of times per second during combat
|
||||
@@ -5050,6 +5129,18 @@ SlashCmdList["CLEVEROID"] = function(msg)
|
||||
return
|
||||
end
|
||||
|
||||
-- cooldowndebug (toggle cooldown update debug messages)
|
||||
if cmd == "cooldowndebug" or cmd == "cddebug" then
|
||||
CleveRoids.cooldownDebug = not CleveRoids.cooldownDebug
|
||||
CleveRoids.Print("Cooldown debug " .. (CleveRoids.cooldownDebug and "enabled" or "disabled"))
|
||||
if CleveRoids.cooldownDebug then
|
||||
CleveRoids.Print("Use /pfuicd for pfUI-specific cooldown debug")
|
||||
local handlerCount = CleveRoids.actionEventHandlers and table.getn(CleveRoids.actionEventHandlers) or 0
|
||||
CleveRoids.Print("Action event handlers registered: " .. handlerCount)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- slotdebug <slot> - Debug action slot state for tooltip/range/mana issues
|
||||
if cmd == "slotdebug" then
|
||||
local slot = tonumber(val)
|
||||
|
||||
@@ -19,7 +19,17 @@ end
|
||||
|
||||
-- Native UPDATE_MOUSEOVER_UNIT handler (priority 2)
|
||||
-- This works even when tooltips are hidden by other addons
|
||||
-- NOTE: We skip when selfTriggered is set to prevent TRP tooltip conflicts.
|
||||
-- When we call SetMouseoverUnit ourselves, it triggers UPDATE_MOUSEOVER_UNIT,
|
||||
-- which would add a redundant "native" source that persists after the real
|
||||
-- source (pfUI, etc.) clears - causing TRP to show stale profile info.
|
||||
function Extension.UPDATE_MOUSEOVER_UNIT()
|
||||
-- Skip if we ourselves triggered this event by calling SetMouseoverUnit
|
||||
if CleveRoids.__mo and CleveRoids.__mo.selfTriggered then
|
||||
CleveRoids.__mo.selfTriggered = false
|
||||
return
|
||||
end
|
||||
|
||||
if UnitExists("mouseover") then
|
||||
CleveRoids.SetMouseoverFrom("native", "mouseover")
|
||||
else
|
||||
|
||||
+3
-1
@@ -243,7 +243,7 @@ do
|
||||
local CleveRoids = _G.CleveRoids or {}
|
||||
_G.CleveRoids = CleveRoids
|
||||
|
||||
CleveRoids.__mo = CleveRoids.__mo or { sources = {}, current = nil }
|
||||
CleveRoids.__mo = CleveRoids.__mo or { sources = {}, current = nil, selfTriggered = false }
|
||||
|
||||
-- Priority levels for mouseover sources (higher = takes precedence)
|
||||
-- All unit frame addons get priority 3, native event gets 2, tooltip fallback gets 1
|
||||
@@ -302,6 +302,8 @@ do
|
||||
|
||||
local function apply(unit)
|
||||
if CleveRoids.hasSuperwow and _G.SetMouseoverUnit then
|
||||
-- Set flag so UPDATE_MOUSEOVER_UNIT handler knows we triggered this
|
||||
CleveRoids.__mo.selfTriggered = true
|
||||
_G.SetMouseoverUnit(unit)
|
||||
else
|
||||
CleveRoids.mouseoverUnit = unit
|
||||
|
||||
Reference in New Issue
Block a user