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 T = ShaguTweaks.T
local API = ShaguTweaks.API or {}
local libspell = ShaguTweaks.libspell
local module = ShaguTweaks:register({
@@ -14,75 +15,86 @@ local module = ShaguTweaks:register({
module.enable = function(self)
local gfind = string.gmatch or string.gfind
local function ButtonMacroScan(bar)
if not bar:IsVisible() then return end
local function BuildMacroCache()
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()
prefix = bar == MainMenuBar and "Action" or prefix
prefix = bar == BonusActionBarFrame and "BonusAction" or prefix
-- scan all 12 slots in bar
for slot = 1, 12 do
button = _G[prefix.."Button"..slot]
icon = _G[prefix.."Button"..slot.."Icon"]
for index = 1, 12 do
local button = _G[prefix.."Button"..index]
local icon = _G[prefix.."Button"..index.."Icon"]
if not button then break end
local macro = GetActionText(ActionButton_GetPagedID(_G[prefix.."Button"..slot]))
local spellslot = nil
local booktype = nil
local actionSlot = ActionButton_GetPagedID(button)
local texture = GetActionTexture(actionSlot)
button.spellslot, button.booktype = nil, nil
if macro then
local name, body, _
for slot = 1, 36 do -- 36 macro slots
name, _, body = GetMacroInfo(slot)
if name == macro then break end
local body = GetMacroBody(actionSlot, macroCache)
local match = ResolveSpell(body)
if match then
local _, _, spell, rank = string.find(match, "(.+)%((.+)%)")
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
if name and body then
local match
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
if icon and texture and texture ~= icon:GetTexture() then
icon:SetTexture(texture)
end
end
end
@@ -99,6 +111,9 @@ module.enable = function(self)
macroicons:RegisterEvent("UPDATE_BONUS_ACTIONBAR")
macroicons:RegisterEvent("ACTIONBAR_SHOWGRID")
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
+48 -34
View File
@@ -1,5 +1,6 @@
local _G = ShaguTweaks.GetGlobalEnv()
local T = ShaguTweaks.T
local API = ShaguTweaks.API or {}
local module = ShaguTweaks:register({
title = T["Macro Tweaks"],
@@ -11,72 +12,85 @@ local module = ShaguTweaks:register({
})
module.enable = function(self)
-- make sure #showtooltip inside macros won't be sent
local hookSendChatMessage = SendChatMessage
function _G.SendChatMessage(msg, ...)
if msg and string.find(msg, "^#showtooltip ") then return end
hookSendChatMessage(msg, unpack(arg))
-- This interception is intentional: #showtooltip is macro metadata and must
-- not be sent as chat text by the Vanilla macro parser.
local hookSendChatMessage = _G.SendChatMessage
function _G.SendChatMessage(msg, a1, a2, a3, a4, a5, a6, a7, a8)
if msg and string.find(msg, "^#showtooltip%s") then return end
return hookSendChatMessage(msg, a1, a2, a3, a4, a5, a6, a7, a8)
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
local userinput
ChatFrameEditBox._AddHistoryLine = ChatFrameEditBox.AddHistoryLine
ChatFrameEditBox.AddHistoryLine = function(self, text)
if not userinput and text and string.find(text, "^/run(.+)") then return end
if not userinput and string.find(text, "^/script(.+)") then return end
if not userinput and string.find(text, "^/cast(.+)") then return end
if not userinput and text then
if string.find(text, "^/run%s*") 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)
end
local OnEnter = ChatFrameEditBox:GetScript("OnEnterPressed")
ChatFrameEditBox:SetScript("OnEnterPressed", function(a1,a2,a3,a4)
userinput = true
OnEnter(a1,a2,a3,a4)
userinput = nil
if OnEnter then OnEnter(a1,a2,a3,a4) end
userinput = nil
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 wanted = string.lower(item or "")
for bag = 4, 0, -1 do
for slot = 1, GetContainerNumSlots(bag) do
local itemLink = GetContainerItemLink(bag,slot)
if itemLink then
local _, _, parse = strfind(itemLink, "(%d+):")
local query = GetItemInfo(parse)
if query and query ~= "" and string.lower(query) == string.lower(item) then
return bag, slot
end
local query = GetBagItemName(bag, slot)
if query and string.lower(query) == wanted then
return bag, slot
end
end
end
return nil
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_EQUIP2 = "/use"
_G.SlashCmdList.EQUIP = function (msg)
_G.SlashCmdList.EQUIP = function(msg)
if not msg or msg == "" then return end
local bag, slot, _
if string.find(msg, "%d+%s+%d+") then
_, _, bag, slot = string.find(msg, "(%d+)%s+(%d+)")
elseif string.find(msg, "%d+") then
_, _, slot = string.find(msg, "(%d+)")
local bag, slot
local _, _, parsedBag, parsedSlot = string.find(msg, "^(%d+)%s+(%d+)$")
if parsedBag and parsedSlot then
bag, slot = parsedBag, parsedSlot
else
bag, slot = FindItem(msg)
local _, _, inventorySlot = string.find(msg, "^(%d+)$")
if inventorySlot then
slot = inventorySlot
else
bag, slot = FindItem(msg)
end
end
bag = bag and tonumber(bag) or nil
slot = slot and tonumber(slot) or nil
if bag and slot then
UseContainerItem(bag, slot)
elseif not bag and slot then
elseif slot then
UseInventoryItem(slot)
end
end
+16 -3
View File
@@ -1,5 +1,6 @@
local _G = ShaguTweaks.GetGlobalEnv()
local T = ShaguTweaks.T
local API = ShaguTweaks.API or {}
local module = ShaguTweaks:register({
title = T["Show Bags"],
@@ -49,7 +50,9 @@ module.enable = function(self)
bagframe:RegisterEvent("PLAYER_ENTERING_WORLD")
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()
end)
@@ -58,7 +61,13 @@ module.enable = function(self)
end)
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
-- disable mouse events on all frames
this.mousedisabled = true
@@ -78,14 +87,18 @@ module.enable = function(self)
end)
bagframe:SetScript("OnEvent", function()
if this.initialized then return end
this.initialized = true
ShaguTweaks.DarkenFrame(bagframe)
for id, frame in pairs(frames) do
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:SetParent(bagframe)
frame:SetScale(.8)
frame.Show = frame:Show()
frame.Show = nil
frame:Show()
end
end)
+17 -3
View File
@@ -1,5 +1,6 @@
local _G = ShaguTweaks.GetGlobalEnv()
local T = ShaguTweaks.T
local API = ShaguTweaks.API or {}
local module = ShaguTweaks:register({
title = T["Show Micro Menu"],
@@ -27,6 +28,7 @@ module.enable = function(self)
microframe:SetPoint("BOTTOMRIGHT", UIParent, "BOTTOMRIGHT", -8, 8)
microframe:SetWidth(225)
microframe:SetHeight(44)
microframe:SetScale(module.config["panelmicro.scale"])
microframe:SetFrameStrata("MEDIUM")
microframe:SetBackdrop({
@@ -49,7 +51,9 @@ module.enable = function(self)
microframe:RegisterEvent("PLAYER_ENTERING_WORLD")
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()
end)
@@ -58,7 +62,13 @@ module.enable = function(self)
end)
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
-- disable mouse events on all frames
this.mousedisabled = true
@@ -78,13 +88,17 @@ module.enable = function(self)
end)
microframe:SetScript("OnEvent", function()
if this.initialized then return end
this.initialized = true
ShaguTweaks.DarkenFrame(microframe)
for id, frame in pairs(frames) do
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:SetParent(microframe)
frame.Show = frame:Show()
frame.Show = nil
frame:Show()
end
end)
+12 -13
View File
@@ -1,5 +1,6 @@
local _G = ShaguTweaks.GetGlobalEnv()
local T = ShaguTweaks.T
local hooksecurefunc = ShaguTweaks.hooksecurefunc
local hooksecurefunc = hooksecurefunc or ShaguTweaks.hooksecurefunc
local module = ShaguTweaks:register({
@@ -197,7 +198,7 @@ module.enable = function(self)
local function ShaguTweaksWorldMapFrame_Update()
-- 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 = {}
rawset(t,k,v)
return v
@@ -213,7 +214,7 @@ module.enable = function(self)
local alreadyknown = {}
for i=1, numOverlays do
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
end
@@ -222,7 +223,7 @@ module.enable = function(self)
frame:Hide()
end
local zoneData = this.overlayData[mapFileName]
local zoneData = WorldMapFrame.overlayData[mapFileName]
local textureCount = 0
local texturePixelWidth, textureFileWidth, texturePixelHeight, textureFileHeight
for i, hash in ipairs(zoneData) do
@@ -317,18 +318,16 @@ module.enable = function(self)
end
end
-- hook map reveal functions before and after the actual call
local ShaguTweaksHookWorldMapFrame_Update = _G.WorldMapFrame_Update
_G.WorldMapFrame_Update = function(self)
-- hide all previously set textures
-- Preserve the native updater: clear custom overlays before it runs, then
-- append the reveal layer afterwards.
hooksecurefunc("WorldMapFrame_Update", function()
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, true)
-- let the game put its explored tiles on the map
ShaguTweaksHookWorldMapFrame_Update(self)
-- let the addon extend it with its own data
hooksecurefunc("WorldMapFrame_Update", function()
ShaguTweaksWorldMapFrame_Update()
end
end)
end