Files
ShaguTweaks-ClassicAPI/mods/actionbar-reagents.lua
T
OEVGandClaude Opus 5.5 2c58ce2aa3 Merge the ShaguTweaks Extras ClassicAPI modules into ShaguTweaks (3.7)
Bring in 27 module files from Dusk/ShaguTweaks-Extras-ClassicAPI
(8e14bb4): action bar, chat, loot, macro, merchant (Buy Em All),
minimap & world map, tooltip and unit frame modules, with their
textures. Titles are unchanged, so saved toggles carry over.

- Categories: Chat -> Chat & Social, World Map -> Minimap & World Map,
  Merchant & Auction -> Merchant; Macro is a new category.
- Texture paths point at ShaguTweaks\img.
- Not merged: Raid Frames, Bag Item Click and Bag Search Bar (Bagshui
  covers them), Auction Alt-Buy (aux covers it).
- Chat note when the old ShaguTweaks-extras addon is still enabled.
- English translation keys, notices, license copy, asset provenance,
  README, changelog and version 3.7.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019W3rwusM4i1CYaHQAYixJ7
2026-11-02 21:52:53 +00:00

128 lines
4.1 KiB
Lua
Executable File

local _G = ShaguTweaks.GetGlobalEnv()
local T = ShaguTweaks.T
local API = ShaguTweaks.API
local module = ShaguTweaks:register({
title = T["Reagent Counter"],
description = T["Shows a reagent counter on action buttons."],
expansions = { ["vanilla"] = true, ["tbc"] = false },
maintainer = "@shagu (GitHub)",
category = T["Action Bar"],
enabled = nil,
})
module.enable = function(self)
local reagent_slots = { }
local reagent_counts = { }
local bars = { "Action", "BonusAction", "MultiBarBottomLeft", "MultiBarBottomRight", "MultiBarLeft", "MultiBarRight" }
local reagentcounter = CreateFrame("Frame", "ShaguTweaksReagentCount", UIParent)
reagentcounter:RegisterEvent("PLAYER_ENTERING_WORLD")
reagentcounter:RegisterEvent("ACTIONBAR_SLOT_CHANGED")
reagentcounter:RegisterEvent("ACTIONBAR_PAGE_CHANGED")
reagentcounter:RegisterEvent("UPDATE_BONUS_ACTIONBAR")
reagentcounter:RegisterEvent("UPDATE_MACROS")
reagentcounter:RegisterEvent("BAG_UPDATE")
-- Hidden frames still receive events, but do not execute OnUpdate.
-- Wake for one frame only when work is pending.
reagentcounter:Hide()
reagentcounter:SetScript("OnEvent", function()
this.pending = true
if event ~= "BAG_UPDATE" then
this.rescan = true
end
this:Show()
end)
reagentcounter:SetScript("OnUpdate", function()
if not this.pending then
this:Hide()
return
end
-- Rebuild the action-slot -> reagent mapping only when the action layout
-- changes. ClassicAPI resolves the spell/macro directly, so no tooltip
-- scan or localized reagent-name parsing is required.
if this.rescan then
reagent_counts = {}
for slot = 1, 120 do
reagentcounter.ScanSlot(slot)
end
end
-- Count only reagents referenced by active actions. ClassicAPI reads the
-- inventory directly, avoiding a Lua bag scan for every reagent.
for itemID in pairs(reagent_counts) do
reagent_counts[itemID] = API.GetItemCount(itemID, false, false) or 0
end
-- update all actionbar buttons
for _, prefix in ipairs(bars) do
for i = 1, NUM_ACTIONBAR_BUTTONS do
local button = _G[prefix .. "Button" .. i]
if button then
local text = _G[button:GetName().."Count"]
local slot = ActionButton_GetPagedID(button)
if text then
local itemID = reagent_slots[slot]
if itemID then
text:SetText(reagent_counts[itemID] or 0)
elseif not IsConsumableAction(slot) then
text:SetText()
end
end
end
end
end
this.pending = nil
this.rescan = nil
this:Hide()
end)
reagentcounter.ScanSlot = function(slot)
reagent_slots[slot] = nil
if not HasAction(slot) then return end
local actionType, actionID = API.GetActionInfo(slot)
local spellID
if actionType == "spell" then
spellID = actionID
elseif actionType == "macro" and actionID then
local _, _, macroSpellID = API.GetMacroSpell(actionID)
spellID = macroSpellID
end
if not spellID then return end
local reagents = API.GetSpellReagents(spellID)
local reagent = reagents and reagents[1]
if not reagent or not reagent.itemID then return end
-- The action button only has one count field. Preserve the historical
-- behavior by showing the first reagent's owned stack count.
reagent_slots[slot] = reagent.itemID
reagent_counts[reagent.itemID] = reagent_counts[reagent.itemID] or 0
end
-- The stock UI clears the Count fontstring on non-consumable actions whenever
-- ActionButton_UpdateCount() runs. Re-apply our reagent value afterwards so
-- login/reload refreshes cannot erase it a moment later.
ShaguTweaks.hooksecurefunc("ActionButton_UpdateCount", function()
local button = this
if not button or not button.GetName then return end
local slot = ActionButton_GetPagedID(button)
local itemID = slot and reagent_slots[slot]
if not itemID then return end
local text = _G[button:GetName().."Count"]
if text then
text:SetText(reagent_counts[itemID] or 0)
end
end)
end