Harden macros, world map and actionbar panels

This commit is contained in:
Dusk-92
2026-08-30 09:11:44 +02:00
parent 279417bd54
commit 38674064d6
5 changed files with 167 additions and 112 deletions
+74 -59
View File
@@ -1,5 +1,6 @@
local _G = ShaguTweaks.GetGlobalEnv() local _G = ShaguTweaks.GetGlobalEnv()
local T = ShaguTweaks.T local T = ShaguTweaks.T
local API = ShaguTweaks.API or {}
local libspell = ShaguTweaks.libspell local libspell = ShaguTweaks.libspell
local module = ShaguTweaks:register({ local module = ShaguTweaks:register({
@@ -14,75 +15,86 @@ local module = ShaguTweaks:register({
module.enable = function(self) module.enable = function(self)
local gfind = string.gmatch or string.gfind local gfind = string.gmatch or string.gfind
local function ButtonMacroScan(bar) local function BuildMacroCache()
if not bar:IsVisible() then return end local cache = {}
for macroSlot = 1, 36 do
local name, _, body = GetMacroInfo(macroSlot)
if name and body then
cache[name] = { id = macroSlot, body = body }
end
end
return cache
end
local button, icon local function GetMacroBody(actionSlot, cache)
if API.GetActionInfo then
local actionType, id = API.GetActionInfo(actionSlot)
if actionType == "macro" and id then
local _, _, body = GetMacroInfo(id)
if body then return body end
end
end
local macroName = GetActionText(actionSlot)
local entry = macroName and cache[macroName]
return entry and entry.body or nil
end
local function ResolveSpell(body)
if not body then return end
local fallback
for line in gfind(body, "[^%\n]+") do
local _, _, match = string.find(line, "^#showtooltip%s+(.+)")
if match then return match end
if not fallback then
_, _, fallback = string.find(line, "%-%-showtooltip%s+(.+)")
end
if not fallback then
_, _, fallback = string.find(line, "^/cast%s+(.+)")
end
if not fallback then
_, _, fallback = string.find(line, "^/pfcast%s+(.+)")
end
if not fallback then
_, _, fallback = string.find(line, "CastSpellByName%(%\"(.+)%\"%)")
end
end
return fallback
end
local function ButtonMacroScan(bar, macroCache)
if not bar:IsVisible() then return end
local prefix = bar:GetName() local prefix = bar:GetName()
prefix = bar == MainMenuBar and "Action" or prefix prefix = bar == MainMenuBar and "Action" or prefix
prefix = bar == BonusActionBarFrame and "BonusAction" or prefix prefix = bar == BonusActionBarFrame and "BonusAction" or prefix
-- scan all 12 slots in bar for index = 1, 12 do
for slot = 1, 12 do local button = _G[prefix.."Button"..index]
button = _G[prefix.."Button"..slot] local icon = _G[prefix.."Button"..index.."Icon"]
icon = _G[prefix.."Button"..slot.."Icon"]
if not button then break end if not button then break end
local macro = GetActionText(ActionButton_GetPagedID(_G[prefix.."Button"..slot]))
local spellslot = nil local actionSlot = ActionButton_GetPagedID(button)
local booktype = nil local texture = GetActionTexture(actionSlot)
button.spellslot, button.booktype = nil, nil
if macro then local body = GetMacroBody(actionSlot, macroCache)
local name, body, _ local match = ResolveSpell(body)
for slot = 1, 36 do -- 36 macro slots if match then
name, _, body = GetMacroInfo(slot) local _, _, spell, rank = string.find(match, "(.+)%((.+)%)")
if name == macro then break end spell = spell or match
button.spellslot, button.booktype = libspell.GetSpellIndex(spell, rank)
if button.spellslot and button.booktype then
texture = GetSpellTexture(button.spellslot, button.booktype) or texture
end end
end
if name and body then if icon and texture and texture ~= icon:GetTexture() then
local match icon:SetTexture(texture)
for line in gfind(body, "[^%\n]+") do
_, _, match = string.find(line, '^#showtooltip (.+)')
if not match then
-- add support to specify custom tooltips via:
-- /run --showtooltip SPELLNAME
_, _, match = string.find(line, '%-%-showtooltip (.+)')
end
if not match then
_, _, match = string.find(line, '^/cast (.+)')
end
if not match then
_, _, match = string.find(line, '^/pfcast (.+)')
end
if not match then
_, _, match = string.find(line, 'CastSpellByName%(%"(.+)%"%)')
end
if match then
local _, _, spell, rank = string.find(match, '(.+)%((.+)%)')
spell = spell or match
button.spellslot, button.booktype = libspell.GetSpellIndex(spell, rank)
-- overwrite with spell macro texture where possible
local texture = GetActionTexture(slot)
if button.spellslot and button.booktype then
texture = GetSpellTexture(button.spellslot, button.booktype)
end
-- update button texture
if texture and texture ~= icon:GetTexture() then
icon:SetTexture(texture)
end
end
end
end
end end
end end
end end
@@ -99,6 +111,9 @@ module.enable = function(self)
macroicons:RegisterEvent("UPDATE_BONUS_ACTIONBAR") macroicons:RegisterEvent("UPDATE_BONUS_ACTIONBAR")
macroicons:RegisterEvent("ACTIONBAR_SHOWGRID") macroicons:RegisterEvent("ACTIONBAR_SHOWGRID")
macroicons:SetScript("OnEvent", function() macroicons:SetScript("OnEvent", function()
for _, bar in pairs(bars) do ButtonMacroScan(bar) end local macroCache = BuildMacroCache()
for _, bar in pairs(bars) do
ButtonMacroScan(bar, macroCache)
end
end) end)
end end
+48 -34
View File
@@ -1,5 +1,6 @@
local _G = ShaguTweaks.GetGlobalEnv() local _G = ShaguTweaks.GetGlobalEnv()
local T = ShaguTweaks.T local T = ShaguTweaks.T
local API = ShaguTweaks.API or {}
local module = ShaguTweaks:register({ local module = ShaguTweaks:register({
title = T["Macro Tweaks"], title = T["Macro Tweaks"],
@@ -11,72 +12,85 @@ local module = ShaguTweaks:register({
}) })
module.enable = function(self) module.enable = function(self)
-- make sure #showtooltip inside macros won't be sent -- This interception is intentional: #showtooltip is macro metadata and must
local hookSendChatMessage = SendChatMessage -- not be sent as chat text by the Vanilla macro parser.
function _G.SendChatMessage(msg, ...) local hookSendChatMessage = _G.SendChatMessage
if msg and string.find(msg, "^#showtooltip ") then return end function _G.SendChatMessage(msg, a1, a2, a3, a4, a5, a6, a7, a8)
hookSendChatMessage(msg, unpack(arg)) if msg and string.find(msg, "^#showtooltip%s") then return end
return hookSendChatMessage(msg, a1, a2, a3, a4, a5, a6, a7, a8)
end end
-- do not write macro calls into chat input history -- do not write executed macro commands into chat input history
if not ChatFrameEditBox._AddHistoryLine then if not ChatFrameEditBox._AddHistoryLine then
local userinput local userinput
ChatFrameEditBox._AddHistoryLine = ChatFrameEditBox.AddHistoryLine ChatFrameEditBox._AddHistoryLine = ChatFrameEditBox.AddHistoryLine
ChatFrameEditBox.AddHistoryLine = function(self, text) ChatFrameEditBox.AddHistoryLine = function(self, text)
if not userinput and text and string.find(text, "^/run(.+)") then return end if not userinput and text then
if not userinput and string.find(text, "^/script(.+)") then return end if string.find(text, "^/run%s*") then return end
if not userinput and string.find(text, "^/cast(.+)") then return end if string.find(text, "^/script%s*") then return end
if string.find(text, "^/cast%s*") then return end
end
ChatFrameEditBox._AddHistoryLine(self, text) ChatFrameEditBox._AddHistoryLine(self, text)
end end
local OnEnter = ChatFrameEditBox:GetScript("OnEnterPressed") local OnEnter = ChatFrameEditBox:GetScript("OnEnterPressed")
ChatFrameEditBox:SetScript("OnEnterPressed", function(a1,a2,a3,a4) ChatFrameEditBox:SetScript("OnEnterPressed", function(a1,a2,a3,a4)
userinput = true userinput = true
OnEnter(a1,a2,a3,a4) if OnEnter then OnEnter(a1,a2,a3,a4) end
userinput = nil userinput = nil
end) end)
end end
local function GetBagItemName(bag, slot)
if API.GetContainerItemID and API.GetItemNameByID then
local itemID = API.GetContainerItemID(bag, slot)
local name = itemID and API.GetItemNameByID(itemID)
if name then return name end
end
local itemLink = GetContainerItemLink(bag, slot)
if not itemLink then return end
local _, _, itemID = string.find(itemLink, "item:(%d+)")
return itemID and GetItemInfo(itemID) or nil
end
local function FindItem(item) local function FindItem(item)
local wanted = string.lower(item or "")
for bag = 4, 0, -1 do for bag = 4, 0, -1 do
for slot = 1, GetContainerNumSlots(bag) do for slot = 1, GetContainerNumSlots(bag) do
local itemLink = GetContainerItemLink(bag,slot) local query = GetBagItemName(bag, slot)
if itemLink then if query and string.lower(query) == wanted then
local _, _, parse = strfind(itemLink, "(%d+):") return bag, slot
local query = GetItemInfo(parse)
if query and query ~= "" and string.lower(query) == string.lower(item) then
return bag, slot
end
end end
end end
end end
return nil
end end
-- add /use and /equip to the macro api:
-- https://wowwiki.fandom.com/wiki/Making_a_macro
-- supported arguments:
-- /use <itemname>
-- /use <inventory slot>
-- /use <bag> <slot>
_G.SLASH_EQUIP1 = "/equip" _G.SLASH_EQUIP1 = "/equip"
_G.SLASH_EQUIP2 = "/use" _G.SLASH_EQUIP2 = "/use"
_G.SlashCmdList.EQUIP = function (msg) _G.SlashCmdList.EQUIP = function(msg)
if not msg or msg == "" then return end if not msg or msg == "" then return end
local bag, slot, _
if string.find(msg, "%d+%s+%d+") then local bag, slot
_, _, bag, slot = string.find(msg, "(%d+)%s+(%d+)") local _, _, parsedBag, parsedSlot = string.find(msg, "^(%d+)%s+(%d+)$")
elseif string.find(msg, "%d+") then if parsedBag and parsedSlot then
_, _, slot = string.find(msg, "(%d+)") bag, slot = parsedBag, parsedSlot
else else
bag, slot = FindItem(msg) local _, _, inventorySlot = string.find(msg, "^(%d+)$")
if inventorySlot then
slot = inventorySlot
else
bag, slot = FindItem(msg)
end
end end
bag = bag and tonumber(bag) or nil
slot = slot and tonumber(slot) or nil
if bag and slot then if bag and slot then
UseContainerItem(bag, slot) UseContainerItem(bag, slot)
elseif not bag and slot then elseif slot then
UseInventoryItem(slot) UseInventoryItem(slot)
end end
end end
+16 -3
View File
@@ -1,5 +1,6 @@
local _G = ShaguTweaks.GetGlobalEnv() local _G = ShaguTweaks.GetGlobalEnv()
local T = ShaguTweaks.T local T = ShaguTweaks.T
local API = ShaguTweaks.API or {}
local module = ShaguTweaks:register({ local module = ShaguTweaks:register({
title = T["Show Bags"], title = T["Show Bags"],
@@ -49,7 +50,9 @@ module.enable = function(self)
bagframe:RegisterEvent("PLAYER_ENTERING_WORLD") bagframe:RegisterEvent("PLAYER_ENTERING_WORLD")
bagframe:SetScript("OnDragStart", function() bagframe:SetScript("OnDragStart", function()
if not IsShiftKeyDown() or not IsControlKeyDown() then return end local shift = API.IsShiftKeyDown and API.IsShiftKeyDown() or IsShiftKeyDown()
local control = API.IsControlKeyDown and API.IsControlKeyDown() or IsControlKeyDown()
if not shift or not control then return end
this:StartMoving() this:StartMoving()
end) end)
@@ -58,7 +61,13 @@ module.enable = function(self)
end) end)
bagframe:SetScript("OnUpdate", function() bagframe:SetScript("OnUpdate", function()
if MouseIsOver(this) and IsShiftKeyDown() and IsControlKeyDown() then this.modifierTimer = (this.modifierTimer or 0) + arg1
if this.modifierTimer < .05 then return end
this.modifierTimer = 0
local shift = API.IsShiftKeyDown and API.IsShiftKeyDown() or IsShiftKeyDown()
local control = API.IsControlKeyDown and API.IsControlKeyDown() or IsControlKeyDown()
if MouseIsOver(this) and shift and control then
if not this.mousedisabled then if not this.mousedisabled then
-- disable mouse events on all frames -- disable mouse events on all frames
this.mousedisabled = true this.mousedisabled = true
@@ -78,14 +87,18 @@ module.enable = function(self)
end) end)
bagframe:SetScript("OnEvent", function() bagframe:SetScript("OnEvent", function()
if this.initialized then return end
this.initialized = true
ShaguTweaks.DarkenFrame(bagframe) ShaguTweaks.DarkenFrame(bagframe)
for id, frame in pairs(frames) do for id, frame in pairs(frames) do
local anchor = frames[id-1] or bagframe local anchor = frames[id-1] or bagframe
frame:ClearAllPoints()
frame:SetPoint("LEFT", anchor, id == 1 and "LEFT" or "RIGHT", id == 1 and 5 or 2, 0) frame:SetPoint("LEFT", anchor, id == 1 and "LEFT" or "RIGHT", id == 1 and 5 or 2, 0)
frame:SetParent(bagframe) frame:SetParent(bagframe)
frame:SetScale(.8) frame:SetScale(.8)
frame.Show = frame:Show() frame.Show = nil
frame:Show() frame:Show()
end end
end) end)
+17 -3
View File
@@ -1,5 +1,6 @@
local _G = ShaguTweaks.GetGlobalEnv() local _G = ShaguTweaks.GetGlobalEnv()
local T = ShaguTweaks.T local T = ShaguTweaks.T
local API = ShaguTweaks.API or {}
local module = ShaguTweaks:register({ local module = ShaguTweaks:register({
title = T["Show Micro Menu"], title = T["Show Micro Menu"],
@@ -27,6 +28,7 @@ module.enable = function(self)
microframe:SetPoint("BOTTOMRIGHT", UIParent, "BOTTOMRIGHT", -8, 8) microframe:SetPoint("BOTTOMRIGHT", UIParent, "BOTTOMRIGHT", -8, 8)
microframe:SetWidth(225) microframe:SetWidth(225)
microframe:SetHeight(44) microframe:SetHeight(44)
microframe:SetScale(module.config["panelmicro.scale"])
microframe:SetFrameStrata("MEDIUM") microframe:SetFrameStrata("MEDIUM")
microframe:SetBackdrop({ microframe:SetBackdrop({
@@ -49,7 +51,9 @@ module.enable = function(self)
microframe:RegisterEvent("PLAYER_ENTERING_WORLD") microframe:RegisterEvent("PLAYER_ENTERING_WORLD")
microframe:SetScript("OnDragStart", function() microframe:SetScript("OnDragStart", function()
if not IsShiftKeyDown() or not IsControlKeyDown() then return end local shift = API.IsShiftKeyDown and API.IsShiftKeyDown() or IsShiftKeyDown()
local control = API.IsControlKeyDown and API.IsControlKeyDown() or IsControlKeyDown()
if not shift or not control then return end
this:StartMoving() this:StartMoving()
end) end)
@@ -58,7 +62,13 @@ module.enable = function(self)
end) end)
microframe:SetScript("OnUpdate", function() microframe:SetScript("OnUpdate", function()
if MouseIsOver(this) and IsShiftKeyDown() and IsControlKeyDown() then this.modifierTimer = (this.modifierTimer or 0) + arg1
if this.modifierTimer < .05 then return end
this.modifierTimer = 0
local shift = API.IsShiftKeyDown and API.IsShiftKeyDown() or IsShiftKeyDown()
local control = API.IsControlKeyDown and API.IsControlKeyDown() or IsControlKeyDown()
if MouseIsOver(this) and shift and control then
if not this.mousedisabled then if not this.mousedisabled then
-- disable mouse events on all frames -- disable mouse events on all frames
this.mousedisabled = true this.mousedisabled = true
@@ -78,13 +88,17 @@ module.enable = function(self)
end) end)
microframe:SetScript("OnEvent", function() microframe:SetScript("OnEvent", function()
if this.initialized then return end
this.initialized = true
ShaguTweaks.DarkenFrame(microframe) ShaguTweaks.DarkenFrame(microframe)
for id, frame in pairs(frames) do for id, frame in pairs(frames) do
local anchor = frames[id-1] or microframe local anchor = frames[id-1] or microframe
frame:ClearAllPoints()
frame:SetPoint("LEFT", anchor, id == 1 and "LEFT" or "RIGHT", id == 1 and 3.5 or -2, id==1 and 10 or 0) frame:SetPoint("LEFT", anchor, id == 1 and "LEFT" or "RIGHT", id == 1 and 3.5 or -2, id==1 and 10 or 0)
frame:SetParent(microframe) frame:SetParent(microframe)
frame.Show = frame:Show() frame.Show = nil
frame:Show() frame:Show()
end end
end) end)
+12 -13
View File
@@ -1,5 +1,6 @@
local _G = ShaguTweaks.GetGlobalEnv() local _G = ShaguTweaks.GetGlobalEnv()
local T = ShaguTweaks.T local T = ShaguTweaks.T
local hooksecurefunc = ShaguTweaks.hooksecurefunc
local hooksecurefunc = hooksecurefunc or ShaguTweaks.hooksecurefunc local hooksecurefunc = hooksecurefunc or ShaguTweaks.hooksecurefunc
local module = ShaguTweaks:register({ local module = ShaguTweaks:register({
@@ -197,7 +198,7 @@ module.enable = function(self)
local function ShaguTweaksWorldMapFrame_Update() local function ShaguTweaksWorldMapFrame_Update()
-- create metatable if not yet created -- create metatable if not yet created
this.overlayData = this.overlayData or setmetatable(ShaguTweaks.MapOverlayData, {__index = function(t,k) WorldMapFrame.overlayData = WorldMapFrame.overlayData or setmetatable(ShaguTweaks.MapOverlayData, {__index = function(t,k)
local v = {} local v = {}
rawset(t,k,v) rawset(t,k,v)
return v return v
@@ -213,7 +214,7 @@ module.enable = function(self)
local alreadyknown = {} local alreadyknown = {}
for i=1, numOverlays do for i=1, numOverlays do
local textureName, textureWidth, textureHeight, offsetX, offsetY, mapPointX, mapPointY = GetMapOverlayInfo(i) local textureName, textureWidth, textureHeight, offsetX, offsetY, mapPointX, mapPointY = GetMapOverlayInfo(i)
local overlayHash = create_hash(textureName, textureWidth, textureHeight, offsetX, offsetY, mapPointX, mapPointY) local overlayHash = create_hash(prefix, textureName, textureWidth, textureHeight, offsetX, offsetY, mapPointX, mapPointY)
alreadyknown[textureName] = overlayHash alreadyknown[textureName] = overlayHash
end end
@@ -222,7 +223,7 @@ module.enable = function(self)
frame:Hide() frame:Hide()
end end
local zoneData = this.overlayData[mapFileName] local zoneData = WorldMapFrame.overlayData[mapFileName]
local textureCount = 0 local textureCount = 0
local texturePixelWidth, textureFileWidth, texturePixelHeight, textureFileHeight local texturePixelWidth, textureFileWidth, texturePixelHeight, textureFileHeight
for i, hash in ipairs(zoneData) do for i, hash in ipairs(zoneData) do
@@ -317,18 +318,16 @@ module.enable = function(self)
end end
end end
-- hook map reveal functions before and after the actual call -- Preserve the native updater: clear custom overlays before it runs, then
local ShaguTweaksHookWorldMapFrame_Update = _G.WorldMapFrame_Update -- append the reveal layer afterwards.
_G.WorldMapFrame_Update = function(self) hooksecurefunc("WorldMapFrame_Update", function()
-- hide all previously set textures
for i = 1, NUM_WORLDMAP_OVERLAYS do for i = 1, NUM_WORLDMAP_OVERLAYS do
_G[string.format("%s%s","WorldMapOverlay",i)]:Hide() local texture = _G[string.format("%s%s","WorldMapOverlay",i)]
if texture then texture:Hide() end
end end
end, true)
-- let the game put its explored tiles on the map hooksecurefunc("WorldMapFrame_Update", function()
ShaguTweaksHookWorldMapFrame_Update(self)
-- let the addon extend it with its own data
ShaguTweaksWorldMapFrame_Update() ShaguTweaksWorldMapFrame_Update()
end end)
end end