Files
MetaHunt/modules/zhunter/zButtonCraft.lua
T
DuvelCorp 51d4c785fa 1.5.0
2026-03-31 21:25:35 +02:00

402 lines
13 KiB
Lua

local function zButtonCraft_GetRoot()
return MTH_ZH_GetSavedRoot()
end
local root = zButtonCraft_GetRoot()
if not root["zButtonCraft"] then
root["zButtonCraft"] = {}
root["zButtonCraft"]["spells"] = {}
root["zButtonCraft"]["rows"] = 1
root["zButtonCraft"]["horizontal"] = nil
root["zButtonCraft"]["vertical"] = nil
root["zButtonCraft"]["firstbutton"] = "RIGHT"
root["zButtonCraft"]["enabled"] = 0
root["zButtonCraft"]["tooltip"] = 1
root["zButtonCraft"]["parent"] = {}
root["zButtonCraft"]["parent"]["size"] = 36
root["zButtonCraft"]["parent"]["hide"] = nil
root["zButtonCraft"]["parent"]["circle"] = 1
root["zButtonCraft"]["children"] = {}
root["zButtonCraft"]["children"]["size"] = 36
root["zButtonCraft"]["children"]["hideonclick"] = 1
end
local ZHUNTER_CRAFT_BUTTON_MAX = 14
local zButtonCraft_LastSpellSignature = nil
local zButtonCraft_LastRefreshAt = 0
local zButtonCraft_MinRefreshInterval = 0.50
-- Exact spell names as they appear in the General spellbook tab.
-- spellName = the name returned by GetSpellName() to match against (case-insensitive)
-- display = label used for tooltips and options
local ZCRAFT_PROFESSIONS = {
{ spellName = "Alchemy", display = "Alchemy" },
{ spellName = "Blacksmithing", display = "Blacksmithing" },
{ spellName = "Disenchanting", display = "Disenchanting" },
{ spellName = "Enchanting", display = "Enchanting" },
{ spellName = "Engineering", display = "Engineering" },
{ spellName = "Leatherworking", display = "Leatherworking" },
{ spellName = "Tailoring", display = "Tailoring" },
{ spellName = "Jewelcrafting", display = "Jewelcrafting" },
{ spellName = "Mining", display = "Smelting" },
{ spellName = "Cooking", display = "Cooking" },
{ spellName = "First Aid", display = "First Aid" },
{ spellName = "Herbalism", display = "Herbalism" },
{ spellName = "Survival", display = "Survival" },
{ spellName = "Fishing", display = "Fishing" },
{ spellName = "Skinning", display = "Skinning" },
}
-- Build a lookup: lowercase spell name → ZCRAFT_PROFESSIONS entry
local ZCRAFT_SPELL_LOOKUP = {}
for i = 1, table.getn(ZCRAFT_PROFESSIONS) do
ZCRAFT_SPELL_LOOKUP[string.lower(ZCRAFT_PROFESSIONS[i].spellName)] = ZCRAFT_PROFESSIONS[i]
end
function zButtonCraft_GetSaved()
local currentRoot = zButtonCraft_GetRoot()
if not currentRoot["zButtonCraft"] then
currentRoot["zButtonCraft"] = {}
end
return currentRoot["zButtonCraft"]
end
local function zButtonCraft_EnsureConfig()
local saved = zButtonCraft_GetSaved()
saved["count"] = nil
if saved["enabled"] == nil then
saved["enabled"] = 0
end
if saved["tooltip"] == nil then
saved["tooltip"] = 1
end
if not saved["children"] then
saved["children"] = {}
end
if saved["children"]["hideonclick"] == nil then
saved["children"]["hideonclick"] = 1
end
if not saved["spells"] then
saved["spells"] = {}
end
if not saved["parent"] then
saved["parent"] = {}
end
if not saved["parent"]["size"] then
saved["parent"]["size"] = 36
end
if saved["parent"]["circle"] == nil then
saved["parent"]["circle"] = 1
end
if not saved["children"]["size"] then
saved["children"]["size"] = 36
end
if not saved["rows"] or saved["rows"] < 1 then
saved["rows"] = 1
end
if not saved["firstbutton"] then
saved["firstbutton"] = "RIGHT"
end
end
local function zButtonCraft_ApplyRuntimeSettings()
if not zButtonCraft then return end
local saved = zButtonCraft_GetSaved()
zButtonCraft.tooltip = saved["tooltip"] and true or false
zButtonCraft.hideonclick = saved["children"] and saved["children"]["hideonclick"] and true or false
zButtonCraft.expandonhover = saved["children"] and saved["children"]["expandonhover"] and true or false
zButtonCraft.fadetimer = saved["children"] and tonumber(saved["children"]["fadetimer"]) or 0
end
local function zButtonCraft_GetSpellSignature(spellIds)
if type(spellIds) ~= "table" or table.getn(spellIds) == 0 then return "" end
local parts = {}
for i = 1, table.getn(spellIds) do
parts[i] = tostring(spellIds[i] or "")
end
return table.concat(parts, ",")
end
-- Scans individual spells in the General tab and returns two parallel arrays:
-- spellIds = spellbook index of each matched craft spell
-- spellNames = display label for that profession
-- Results are ordered by ZCRAFT_PROFESSIONS priority.
local function zButtonCraft_CollectProfessions()
if type(GetNumSpellTabs) ~= "function" or type(GetSpellTabInfo) ~= "function"
or type(GetSpellName) ~= "function" then
return {}, {}
end
local bookType = BOOKTYPE_SPELL or "spell"
-- Find the General tab (always tab 1, but look it up to be safe)
local generalOffset, generalEntries
local tabCount = GetNumSpellTabs() or 0
for tabIndex = 1, tabCount do
local tabName, _, tabOffset, tabEntries = GetSpellTabInfo(tabIndex)
if tabName and string.lower(tabName) == "general" then
generalOffset = tabOffset
generalEntries = tabEntries
break
end
end
if not generalOffset or not generalEntries or generalEntries <= 0 then
return {}, {}
end
-- Scan every spell in General; collect matches keyed by profession order
local found = {} -- profession display → spellbook index (first match wins)
for i = 1, generalEntries do
local spellIndex = generalOffset + i
local spellName = GetSpellName(spellIndex, bookType)
if spellName then
local prof = ZCRAFT_SPELL_LOOKUP[string.lower(spellName)]
if prof and not found[prof.display] then
found[prof.display] = spellIndex
end
end
end
-- Return results in ZCRAFT_PROFESSIONS order
local spellIds = {}
local spellNames = {}
for profIndex = 1, table.getn(ZCRAFT_PROFESSIONS) do
local prof = ZCRAFT_PROFESSIONS[profIndex]
local spellIndex = found[prof.display]
if spellIndex then
table.insert(spellIds, spellIndex)
table.insert(spellNames, prof.display)
end
end
return spellIds, spellNames
end
local function zButtonCraft_ApplySpellIds(spellIds)
if not zButtonCraft then return 0 end
local parent = zButtonCraft
local childCount = parent.count or ZHUNTER_CRAFT_BUTTON_MAX
for i = 1, childCount do
local child = getglobal("zButtonCraft" .. i)
if child then
child:Hide()
child.id = nil
child.icon = nil
child.isspell = nil
end
end
local found = 0
for i = 1, table.getn(spellIds) do
if found >= childCount then break end
local spellId = spellIds[i]
if spellId then
found = found + 1
local child = getglobal("zButtonCraft" .. found)
if child then
child.id = spellId
child.isspell = 1
ZSpellButton_UpdateButton(child)
child:Show()
end
end
end
if found > 0 then
parent.id = spellIds[1]
parent.isspell = 1
ZSpellButton_UpdateButton(parent)
parent:Enable()
parent:Show()
else
parent.id = nil
parent:Hide()
end
return found
end
local function zButtonCraft_RefreshProfessions()
if not zButtonCraft then return 0 end
local saved = zButtonCraft_GetSaved()
local freshIds, freshNames = zButtonCraft_CollectProfessions()
-- Build lookup: display name → spellbook index from the fresh scan
local nameToId = {}
for i = 1, table.getn(freshNames) do
nameToId[freshNames[i]] = freshIds[i]
end
-- Honour saved user order when it exists
local existing = saved["spells"]
if existing and table.getn(existing) > 0 then
local orderedNames = {}
local orderedIds = {}
local seen = {}
-- Keep entries that still exist, in the user's order
for i = 1, table.getn(existing) do
local name = existing[i]
if nameToId[name] then
table.insert(orderedNames, name)
table.insert(orderedIds, nameToId[name])
seen[name] = true
end
end
-- Append any newly learned professions at the end
for i = 1, table.getn(freshNames) do
if not seen[freshNames[i]] then
table.insert(orderedNames, freshNames[i])
table.insert(orderedIds, freshIds[i])
end
end
freshNames = orderedNames
freshIds = orderedIds
end
saved["spellIds"] = freshIds
saved["spells"] = freshNames
zButtonCraft.spells = freshNames
zButtonCraft.found = zButtonCraft_ApplySpellIds(freshIds)
zButtonCraft_ApplyRuntimeSettings()
return zButtonCraft.found or 0
end
function zButtonCraft_OnLoad()
this:RegisterEvent("VARIABLES_LOADED")
end
function zButtonCraft_OnEvent()
if event == "VARIABLES_LOADED" then
if not zButtonCraft then return end
if UnitClass("player") ~= ZHUNTER_HUNTER then
zButtonCraft:UnregisterAllEvents()
zButtonCraft:Hide()
return
end
zButtonCraft_CreateButtons()
MTH_ZH_CraftAdjust = CreateFrame("Frame", "MTH_ZH_CraftAdjust")
MTH_ZH_CraftAdjust:RegisterEvent("SPELLS_CHANGED")
MTH_ZH_CraftAdjust:RegisterEvent("PLAYER_ENTERING_WORLD")
MTH_ZH_CraftAdjust:SetScript("OnEvent", MTH_ZH_CraftAdjust_OnEvent)
zButtonCraft_SetupSizeAndPosition()
end
end
function zButtonCraft_CreateButtons()
zButtonCraft_EnsureConfig()
if not zButtonCraft._mthChildrenCreated then
ZSpellButton_CreateChildren(zButtonCraft, "zButtonCraft", ZHUNTER_CRAFT_BUTTON_MAX)
zButtonCraft._mthChildrenCreated = 1
end
zButtonCraft_RefreshProfessions()
end
function zButtonCraft_SetupSizeAndPosition()
local saved = zButtonCraft_GetSaved()
if saved["enabled"] == false or saved["enabled"] == 0 then
if MTH_ZH_CraftAdjust then
MTH_ZH_CraftAdjust:UnregisterAllEvents()
MTH_ZH_CraftAdjust:SetScript("OnEvent", nil)
end
if zButtonCraft and zButtonCraft.Hide then
zButtonCraft:Hide()
end
return
end
if MTH_ZH_CraftAdjust then
MTH_ZH_CraftAdjust:RegisterEvent("SPELLS_CHANGED")
MTH_ZH_CraftAdjust:RegisterEvent("PLAYER_ENTERING_WORLD")
MTH_ZH_CraftAdjust:SetScript("OnEvent", MTH_ZH_CraftAdjust_OnEvent)
end
local displayCount = zButtonCraft.found or 0
if displayCount < 0 then displayCount = 0 end
if not (type(MTH_ZBar_ApplyToButton) == "function" and MTH_ZBar_ApplyToButton(zButtonCraft, displayCount)) then
ZSpellButton_SetSize(zButtonCraft, saved["parent"]["size"])
ZSpellButton_SetSize(zButtonCraft, saved["children"]["size"], 1)
ZSpellButton_SetExpandDirection(zButtonCraft, saved["firstbutton"])
ZSpellButton_ArrangeChildren(zButtonCraft, saved["rows"],
displayCount, saved["horizontal"], saved["vertical"])
end
end
function zButtonCraft_Reset()
local currentRoot = zButtonCraft_GetRoot()
currentRoot["zButtonCraft"] = {}
local saved = zButtonCraft_GetSaved()
saved["spells"] = {}
saved["rows"] = 1
saved["horizontal"] = nil
saved["vertical"] = nil
saved["firstbutton"] = "RIGHT"
saved["enabled"] = 1
saved["tooltip"] = 1
saved["parent"] = {}
saved["parent"]["size"] = 36
saved["parent"]["hide"] = nil
saved["parent"]["circle"] = 1
saved["children"] = {}
saved["children"]["size"] = 36
saved["children"]["hideonclick"] = 1
zButtonCraft_EnsureConfig()
end
function MTH_ZH_CraftAdjust_OnEvent()
if not zButtonCraft then return end
if event == "SPELLS_CHANGED" then
local now = GetTime and GetTime() or 0
if now > 0 and zButtonCraft_LastRefreshAt > 0 and (now - zButtonCraft_LastRefreshAt) < zButtonCraft_MinRefreshInterval then
return
end
local spellIds, _ = zButtonCraft_CollectProfessions()
local signature = zButtonCraft_GetSpellSignature(spellIds)
if signature == zButtonCraft_LastSpellSignature and not GameTooltip:IsOwned(zButtonCraft) then
return
end
zButtonCraft_LastSpellSignature = signature
zButtonCraft_LastRefreshAt = now
end
zButtonCraft_RefreshProfessions()
zButtonCraft_SetupSizeAndPosition()
if GameTooltip:IsOwned(zButtonCraft) then
ZSpellButtonParent_OnEnter(zButtonCraft)
end
end
function zButtonCraft_KeyBinding(index)
if MTH_ZH_IsModuleEnabled and not MTH_ZH_IsModuleEnabled() then return end
local button
if index then
button = getglobal("zButtonCraft" .. index)
else
button = zButtonCraft
end
if button and button.id then
CastSpell(button.id, "spell")
if zButtonCraft.hideonclick then
if type(ZSpellButton_SetChildrenExpanded) == "function" then
ZSpellButton_SetChildrenExpanded(zButtonCraft, false)
elseif zButtonCraft.children then
zButtonCraft.children:Hide()
end
end
end
end
SLASH_zButtonCraft1 = "/ZCraft"
SlashCmdList["zButtonCraft"] = function(msg)
if MTH_ZH_HandleDisabledSlash and MTH_ZH_HandleDisabledSlash("Craft button is disabled while module 'zhunter' is disabled.") then
return
end
if msg == "reset" then
zButtonCraft_Reset()
zButtonCraft:ClearAllPoints()
zButtonCraft:SetPoint("TOP", UIParent, "TOP", 0, -558)
zButtonCraft_RefreshProfessions()
zButtonCraft_SetupSizeAndPosition()
else
MTH_ZH_Print("Possible Commands: \"reset\"")
end
end