286 lines
9.1 KiB
Lua
286 lines
9.1 KiB
Lua
-- Guda Quest Item Bar
|
|
-- Displays usable quest items in a separate bar
|
|
|
|
local addon = Guda
|
|
local QuestItemBar = addon.Modules.QuestItemBar
|
|
if not QuestItemBar then
|
|
-- Fallback if Init.lua changed
|
|
QuestItemBar = {}
|
|
addon.Modules.QuestItemBar = QuestItemBar
|
|
end
|
|
|
|
local buttons = {}
|
|
local questItems = {}
|
|
|
|
-- Create a hidden tooltip for scanning
|
|
local scanTooltip
|
|
local function GetScanTooltip()
|
|
if not scanTooltip then
|
|
scanTooltip = CreateFrame("GameTooltip", "Guda_QuestBarScanTooltip", nil, "GameTooltipTemplate")
|
|
scanTooltip:SetOwner(WorldFrame, "ANCHOR_NONE")
|
|
end
|
|
return scanTooltip
|
|
end
|
|
|
|
-- Check if an item is usable by scanning its tooltip for "Use:"
|
|
local function IsItemUsable(bagID, slotID)
|
|
if not bagID or not slotID then return false end
|
|
|
|
local tooltip = GetScanTooltip()
|
|
tooltip:ClearLines()
|
|
tooltip:SetBagItem(bagID, slotID)
|
|
|
|
for i = 1, tooltip:NumLines() do
|
|
local line = getglobal("Guda_QuestBarScanTooltipTextLeft" .. i)
|
|
if line then
|
|
local text = line:GetText()
|
|
if text and (string.find(text, "Use:") or string.find(text, "Starts a Quest")) then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
-- Scan bags for quest items
|
|
function QuestItemBar:ScanForQuestItems()
|
|
questItems = {}
|
|
|
|
-- Scan backpack and 4 bags
|
|
for bagID = 0, 4 do
|
|
local numSlots = GetContainerNumSlots(bagID)
|
|
for slotID = 1, numSlots do
|
|
local texture, count = GetContainerItemInfo(bagID, slotID)
|
|
if texture then
|
|
-- Re-use IsQuestItem logic from ItemButton.lua if accessible,
|
|
-- or implement a simple check here since we're in a separate module.
|
|
-- UI\ItemButton.lua defines IsQuestItem locally, so we'll implement a similar check.
|
|
|
|
local isQuest, isStarter = self:IsQuestItem(bagID, slotID)
|
|
if isQuest and IsItemUsable(bagID, slotID) then
|
|
table.insert(questItems, {
|
|
bagID = bagID,
|
|
slotID = slotID,
|
|
texture = texture,
|
|
count = count
|
|
})
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Local implementation of IsQuestItem (similar to the one in ItemButton.lua)
|
|
function QuestItemBar:IsQuestItem(bagID, slotID)
|
|
local tooltip = GetScanTooltip()
|
|
tooltip:ClearLines()
|
|
tooltip:SetBagItem(bagID, slotID)
|
|
|
|
local isQuestItem = false
|
|
local isQuestStarter = false
|
|
|
|
for i = 1, tooltip:NumLines() do
|
|
local line = getglobal("Guda_QuestBarScanTooltipTextLeft" .. i)
|
|
if line then
|
|
local text = line:GetText()
|
|
if text then
|
|
if string.find(text, "Quest Starter") or
|
|
string.find(text, "This Item Begins a Quest") or
|
|
string.find(text, "Use: Starts a Quest") then
|
|
isQuestItem = true
|
|
isQuestStarter = true
|
|
break
|
|
elseif string.find(text, "Quest Item") then
|
|
isQuestItem = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if not isQuestItem then
|
|
local link = GetContainerItemLink(bagID, slotID)
|
|
if link and addon.Modules.Utils and addon.Modules.Utils.ExtractItemID and addon.Modules.Utils.GetItemInfoSafe then
|
|
local itemID = addon.Modules.Utils:ExtractItemID(link)
|
|
if itemID then
|
|
local _, _, _, _, itemCategory, itemType = addon.Modules.Utils:GetItemInfoSafe(itemID)
|
|
if itemCategory == "Quest" or itemType == "Quest" then
|
|
isQuestItem = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return isQuestItem, isQuestStarter
|
|
end
|
|
|
|
-- Update the bar buttons
|
|
function QuestItemBar:Update()
|
|
if addon.Modules.DB:GetSetting("showQuestBar") == false then
|
|
local frame = Guda_QuestItemBar
|
|
if frame then frame:Hide() end
|
|
return
|
|
end
|
|
self:ScanForQuestItems()
|
|
|
|
local frame = Guda_QuestItemBar
|
|
if not frame then return end
|
|
|
|
-- Hide all buttons first
|
|
for _, button in ipairs(buttons) do
|
|
button:Hide()
|
|
end
|
|
|
|
if table.getn(questItems) == 0 then
|
|
frame:Hide()
|
|
return
|
|
end
|
|
|
|
frame:Show()
|
|
|
|
local buttonSize = 37
|
|
local spacing = 2
|
|
local xOffset = 5
|
|
|
|
for i, item in ipairs(questItems) do
|
|
local button = buttons[i]
|
|
if not button then
|
|
button = CreateFrame("Button", "Guda_QuestItemBarButton" .. i, frame, "Guda_ItemButtonTemplate")
|
|
table.insert(buttons, button)
|
|
end
|
|
|
|
button:SetID(item.slotID)
|
|
-- SetBagItem expects bagID and slotID
|
|
button.bagID = item.bagID
|
|
button.slotID = item.slotID
|
|
button.itemData = { link = GetContainerItemLink(item.bagID, item.slotID) }
|
|
|
|
button.hasItem = true
|
|
button.isBank = false
|
|
button.otherChar = nil
|
|
|
|
-- Custom click handler for Quest Item Bar
|
|
button:SetScript("OnClick", function()
|
|
if arg1 == "LeftButton" then
|
|
if IsShiftKeyDown() then
|
|
local link = GetContainerItemLink(this.bagID, this.slotID)
|
|
if link then
|
|
HandleModifiedItemClick(link)
|
|
end
|
|
else
|
|
UseContainerItem(this.bagID, this.slotID)
|
|
end
|
|
elseif arg1 == "RightButton" then
|
|
-- Right click also uses it or maybe open socketing?
|
|
-- UseContainerItem handles both depending on context usually.
|
|
UseContainerItem(this.bagID, this.slotID)
|
|
end
|
|
end)
|
|
|
|
button:SetScript("OnEnter", function()
|
|
Guda_ItemButton_OnEnter(this)
|
|
end)
|
|
|
|
button:SetScript("OnLeave", function()
|
|
Guda_ItemButton_OnLeave(this)
|
|
end)
|
|
|
|
local icon = getglobal(button:GetName() .. "IconTexture")
|
|
icon:SetTexture(item.texture)
|
|
|
|
local count = getglobal(button:GetName() .. "Count")
|
|
if item.count > 1 then
|
|
count:SetText(item.count)
|
|
count:Show()
|
|
else
|
|
count:Hide()
|
|
end
|
|
|
|
button:ClearAllPoints()
|
|
button:SetPoint("LEFT", frame, "LEFT", xOffset + (i-1) * (buttonSize + spacing), 0)
|
|
button:Show()
|
|
|
|
-- Update visual overlays (cooldown, etc)
|
|
if Guda_ItemButton_UpdateCooldown then
|
|
Guda_ItemButton_UpdateCooldown(button)
|
|
end
|
|
|
|
-- Allow dragging the bar via buttons
|
|
button:RegisterForDrag("LeftButton")
|
|
button:SetScript("OnDragStart", function()
|
|
if IsShiftKeyDown() then
|
|
this:GetParent():StartMoving()
|
|
this:GetParent().isMoving = true
|
|
end
|
|
end)
|
|
button:SetScript("OnDragStop", function()
|
|
local parent = this:GetParent()
|
|
if parent.isMoving then
|
|
parent:StopMovingOrSizing()
|
|
parent.isMoving = false
|
|
local point, _, relativePoint, x, y = parent:GetPoint()
|
|
addon.Modules.DB:SetSetting("questBarPosition", {point = point, relativePoint = relativePoint, x = x, y = y})
|
|
end
|
|
end)
|
|
end
|
|
|
|
-- Adjust frame width based on number of items
|
|
local newWidth = xOffset * 2 + table.getn(questItems) * (buttonSize + spacing) - spacing
|
|
frame:SetWidth(math.max(newWidth, 40))
|
|
end
|
|
|
|
function QuestItemBar:UpdateCooldowns()
|
|
for _, button in ipairs(buttons) do
|
|
if button:IsShown() and Guda_ItemButton_UpdateCooldown then
|
|
Guda_ItemButton_UpdateCooldown(button)
|
|
end
|
|
end
|
|
end
|
|
|
|
function QuestItemBar:Initialize()
|
|
local frame = CreateFrame("Frame", "Guda_QuestItemBar", UIParent)
|
|
frame:SetWidth(40)
|
|
frame:SetHeight(45)
|
|
frame:SetPoint("BOTTOM", UIParent, "BOTTOM", 0, 150)
|
|
frame:EnableMouse(true)
|
|
frame:SetMovable(true)
|
|
frame:SetClampedToScreen(true)
|
|
|
|
addon:ApplyBackdrop(frame, "DEFAULT_FRAME")
|
|
|
|
-- Handle dragging
|
|
frame:RegisterForDrag("LeftButton")
|
|
frame:SetScript("OnDragStart", function()
|
|
this:StartMoving()
|
|
end)
|
|
frame:SetScript("OnDragStop", function()
|
|
this:StopMovingOrSizing()
|
|
local point, _, relativePoint, x, y = this:GetPoint()
|
|
addon.Modules.DB:SetSetting("questBarPosition", {point = point, relativePoint = relativePoint, x = x, y = y})
|
|
end)
|
|
|
|
-- Restore position
|
|
local pos = addon.Modules.DB:GetSetting("questBarPosition")
|
|
if pos and pos.point then
|
|
frame:ClearAllPoints()
|
|
frame:SetPoint(pos.point, UIParent, pos.relativePoint or pos.point, pos.x, pos.y)
|
|
end
|
|
|
|
-- Register for events
|
|
addon.Modules.Events:Register("BAG_UPDATE", function()
|
|
QuestItemBar:Update()
|
|
end, "QuestItemBar")
|
|
|
|
addon.Modules.Events:Register("BAG_UPDATE_COOLDOWN", function()
|
|
QuestItemBar:UpdateCooldowns()
|
|
end, "QuestItemBar")
|
|
|
|
addon.Modules.Events:Register("PLAYER_ENTERING_WORLD", function()
|
|
QuestItemBar:Update()
|
|
end, "QuestItemBar")
|
|
|
|
QuestItemBar:Update()
|
|
addon:Debug("QuestItemBar initialized")
|
|
end
|
|
|
|
QuestItemBar.isLoaded = true
|