diff --git a/Compatibility/pfUI.lua b/Compatibility/pfUI.lua index d1cc15b..992cf25 100644 --- a/Compatibility/pfUI.lua +++ b/Compatibility/pfUI.lua @@ -2,9 +2,15 @@ local _G = _G or getfenv(0) local CleveRoids = _G.CleveRoids or {} local Extension = CleveRoids.RegisterExtension("Compatibility_pfUI") -Extension.RegisterEvent("ADDON_LOADED", "OnLoad") +Extension.RegisterEvent("ADDON_LOADED", "ADDON_LOADED") +Extension.RegisterEvent("PLAYER_LOGIN", "PLAYER_LOGIN") Extension.Debug = false +-- Track pfUI state +Extension.pfUILoaded = false +Extension.macrotweakLoaded = false +Extension.slashCommandsOverridden = false + function Extension.RunMacro(name) CleveRoids.ExecuteMacroByName(name) end @@ -28,10 +34,131 @@ function Extension.FocusNameHook() return target end +-- Check if pfUI's macrotweak module is loaded +function Extension.IsPfUIMacrotweakLoaded() + if not pfUI then return false end + + -- pfUI loads modules and stores them in pfUI.modules + if pfUI.modules and pfUI.modules.macrotweak then + return true + end + + -- Also check if the slash commands exist with pfUI's pattern + if SlashCmdList.PFUSE or SlashCmdList.PFEQUIP then + return true + end + + return false +end + +-- Override pfUI's /use and /equip with CleveRoids versions +function Extension.OverridePfUISlashCommands() + if Extension.slashCommandsOverridden then return end + + -- Save pfUI's original handlers as fallbacks + if SlashCmdList.PFUSE then + CleveRoids.Hooks.PFUI_USE = SlashCmdList.PFUSE + end + if SlashCmdList.PFEQUIP then + CleveRoids.Hooks.PFUI_EQUIP = SlashCmdList.PFEQUIP + end + + -- Override with CleveRoids' conditional-aware handlers + SlashCmdList.USE = CleveRoids.DoUse + SlashCmdList.EQUIP = CleveRoids.DoUse + SlashCmdList.PFUSE = CleveRoids.DoUse + SlashCmdList.PFEQUIP = CleveRoids.DoUse + SlashCmdList.SMEQUIP = CleveRoids.DoUse + + Extension.slashCommandsOverridden = true + + Extension.DLOG("Overrode /use and /equip commands for conditional support") +end + +-- Check and handle SendChatMessage hook compatibility +function Extension.HandleSendChatMessageHook() + -- Check if SendChatMessage has already been hooked by something else + local currentHook = _G.SendChatMessage + local originalSendChat = CleveRoids.Hooks.SendChatMessage + + if not originalSendChat then return end + + -- If pfUI already hooked SendChatMessage, we need to chain properly + if currentHook and currentHook ~= originalSendChat then + -- pfUI's hook is in place, let it handle #showtooltip filtering + -- Our hook is redundant, so we can skip it + Extension.DLOG("pfUI's SendChatMessage hook detected, using pfUI's filtering") + end +end + +-- Main compatibility check and setup +function Extension.SetupCompatibility() + Extension.pfUILoaded = (pfUI ~= nil) + Extension.macrotweakLoaded = Extension.IsPfUIMacrotweakLoaded() + + if Extension.pfUILoaded then + Extension.DLOG("pfUI detected") + + if Extension.macrotweakLoaded then + Extension.DLOG("pfUI macrotweak module detected") + + -- Override slash commands to ensure CleveRoids' conditional support works + Extension.OverridePfUISlashCommands() + + -- Handle SendChatMessage hook + Extension.HandleSendChatMessageHook() + end + end +end + function Extension.OnLoad() Extension.DLOG("Extension pfUI Loaded.") Extension.HookMethod(CleveRoids, "GetFocusName", "FocusNameHook", true) - Extension.UnregisterEvent("ADDON_LOADED", "Onload") + + -- Initial compatibility check + Extension.SetupCompatibility() +end + +function Extension.ADDON_LOADED() + -- Check if pfUI just loaded + if arg1 == "pfUI" then + Extension.pfUILoaded = true + -- pfUI modules load after ADDON_LOADED, so schedule a check + if CleveRoids.ScheduleTimer then + CleveRoids.ScheduleTimer(function() + Extension.SetupCompatibility() + end, 0.5) + end + end +end + +function Extension.PLAYER_LOGIN() + -- Final check after everything is loaded + Extension.SetupCompatibility() +end + +-- Utility: Schedule a delayed function call (if not already defined) +if not CleveRoids.ScheduleTimer then + local timerFrame = CreateFrame("Frame") + local timers = {} + + timerFrame:SetScript("OnUpdate", function() + local time = GetTime() + for i = table.getn(timers), 1, -1 do + local timer = timers[i] + if time >= timer.time then + timer.func() + table.remove(timers, i) + end + end + end) + + CleveRoids.ScheduleTimer = function(func, delay) + table.insert(timers, { + func = func, + time = GetTime() + delay + }) + end end _G["CleveRoids"] = CleveRoids diff --git a/Conditionals.lua b/Conditionals.lua index 2dce9e0..f8f1554 100644 --- a/Conditionals.lua +++ b/Conditionals.lua @@ -553,11 +553,38 @@ function CleveRoids.ValidateCooldown(args, ignoreGCD) if type(args) ~= "table" then -- Normalize the spell name by replacing underscores with spaces local normalized = string.gsub(args, "_", " ") + + -- NEW: If this is a numeric slot (1-19), resolve to the equipped item's name + local slotNum = tonumber(normalized) + if slotNum and slotNum >= 1 and slotNum <= 19 then + local link = GetInventoryItemLink("player", slotNum) + if link then + -- Extract item name from link + local _, _, itemName = string.find(link, "%[(.+)%]") + if itemName then + normalized = itemName + end + end + end + args = {name = normalized} else -- Also normalize if it's already a table if args.name then args.name = string.gsub(args.name, "_", " ") + + -- NEW: If this is a numeric slot (1-19), resolve to the equipped item's name + local slotNum = tonumber(args.name) + if slotNum and slotNum >= 1 and slotNum <= 19 then + local link = GetInventoryItemLink("player", slotNum) + if link then + -- Extract item name from link + local _, _, itemName = string.find(link, "%[(.+)%]") + if itemName then + args.name = itemName + end + end + end end end @@ -1315,24 +1342,68 @@ CleveRoids.Keywords = { end, usable = function(conditionals) - return Or(conditionals.usable, function(spellName) + return Or(conditionals.usable, function(name) -- If checking a reactive spell, use reactive logic - if CleveRoids.reactiveSpells[spellName] then - return CleveRoids.IsReactiveUsable(spellName) + if CleveRoids.reactiveSpells[name] then + return CleveRoids.IsReactiveUsable(name) end - -- Otherwise check general spell usability - return CleveRoids.CheckSpellUsable(spellName) + + -- Check if it's a spell first + local spell = CleveRoids.GetSpell(name) + if spell then + return CleveRoids.CheckSpellUsable(name) + end + + -- Not a spell - check if it's an item or slot number + local itemName = name + local slotNum = tonumber(name) + if slotNum and slotNum >= 1 and slotNum <= 19 then + -- Resolve slot number to item name + local link = GetInventoryItemLink("player", slotNum) + if link then + local _, _, extractedName = string.find(link, "%[(.+)%]") + if extractedName then + itemName = extractedName + end + end + end + + -- Check item cooldown (0 remaining = usable) + local remaining = CleveRoids.GetItemCooldown(itemName) + return remaining == 0 end) end, nousable = function(conditionals) - return And(conditionals.nousable, function(spellName) + return And(conditionals.nousable, function(name) -- If checking a reactive spell, use reactive logic - if CleveRoids.reactiveSpells[spellName] then - return not CleveRoids.IsReactiveUsable(spellName) + if CleveRoids.reactiveSpells[name] then + return not CleveRoids.IsReactiveUsable(name) end - -- Otherwise check general spell usability - return not CleveRoids.CheckSpellUsable(spellName) + + -- Check if it's a spell first + local spell = CleveRoids.GetSpell(name) + if spell then + return not CleveRoids.CheckSpellUsable(name) + end + + -- Not a spell - check if it's an item or slot number + local itemName = name + local slotNum = tonumber(name) + if slotNum and slotNum >= 1 and slotNum <= 19 then + -- Resolve slot number to item name + local link = GetInventoryItemLink("player", slotNum) + if link then + local _, _, extractedName = string.find(link, "%[(.+)%]") + if extractedName then + itemName = extractedName + end + end + end + + -- Check item cooldown (>0 remaining = not usable) + local remaining = CleveRoids.GetItemCooldown(itemName) + return remaining > 0 end) end, diff --git a/Console.lua b/Console.lua index 3e8cdcb..ab9ef5c 100644 --- a/Console.lua +++ b/Console.lua @@ -40,9 +40,10 @@ SlashCmdList.USE = CleveRoids.DoUse SLASH_EQUIP1 = "/equip" SlashCmdList.EQUIP = CleveRoids.DoUse --- take back supermacro and pfUI /equip +-- take back supermacro and pfUI /equip and /use SlashCmdList.SMEQUIP = CleveRoids.DoUse SlashCmdList.PFEQUIP = CleveRoids.DoUse +SlashCmdList.PFUSE = CleveRoids.DoUse SLASH_EQUIPMH1 = "/equipmh" SlashCmdList.EQUIPMH = CleveRoids.DoEquipMainhand diff --git a/Core.lua b/Core.lua index a1a6578..2d61106 100644 --- a/Core.lua +++ b/Core.lua @@ -2386,6 +2386,20 @@ function GetActionTexture(slot) local actions = CleveRoids.GetAction(slot) if actions and (actions.active or actions.tooltip) then + -- Prioritize active action, fall back to tooltip + local a = actions.active or actions.tooltip + + -- NEW: For slot-based actions, always fetch current equipment texture + local slotId = tonumber(a.action) + if slotId and slotId >= 1 and slotId <= 19 then + local currentTexture = GetInventoryItemTexture("player", slotId) + if currentTexture then + return currentTexture + end + -- No item equipped in that slot, return unknown texture + return CleveRoids.unknownTexture + end + local proxySlot = (actions.active and actions.active.spell) and CleveRoids.GetProxyActionSlot(actions.active.spell.name) if proxySlot and CleveRoids.Hooks.GetActionTexture(proxySlot) ~= actions.active.spell.texture then return CleveRoids.Hooks.GetActionTexture(proxySlot) @@ -2806,8 +2820,9 @@ function CleveRoids.Frame:BAG_UPDATE() -- Directly clear all relevant caches and force a UI refresh for all buttons. CleveRoids.Actions = {} - --CleveRoids.Macros = {} + CleveRoids.Macros = {} --CleveRoids.ParsedMsg = {} + CleveRoids.IndexActionBars() if CleveRoidMacros.realtime == 0 then CleveRoids.QueueActionUpdate() end @@ -2816,7 +2831,20 @@ end function CleveRoids.Frame:UNIT_INVENTORY_CHANGED() if arg1 ~= "player" then return end - CleveRoids.Frame:BAG_UPDATE() + + -- Equipment changes need immediate response, bypass BAG_UPDATE throttle + local now = GetTime() + CleveRoids.lastItemIndexTime = now + CleveRoids.IndexItems() + + -- Directly clear all relevant caches and force a UI refresh for all buttons + CleveRoids.Actions = {} + CleveRoids.Macros = {} + CleveRoids.IndexActionBars() + + if CleveRoidMacros.realtime == 0 then + CleveRoids.QueueActionUpdate() + end end function CleveRoids.Frame:START_AUTOREPEAT_SPELL() @@ -2930,9 +2958,13 @@ end CleveRoids.Hooks.SendChatMessage = SendChatMessage function SendChatMessage(msg, ...) + -- Filter out #showtooltip lines + -- pfUI's macrotweak also does this, but our pattern is more specific if msg and string.find(msg, "^#showtooltip") then return end + + -- Call the original (or pfUI's hook if it's in the chain) CleveRoids.Hooks.SendChatMessage(msg, unpack(arg)) end