diff --git a/Core/Database.lua b/Core/Database.lua index 7bdeeb0..230a9f0 100644 --- a/Core/Database.lua +++ b/Core/Database.lua @@ -42,11 +42,15 @@ function DB:Initialize() showQualityBorderEquipment = true, showQualityBorderOther = true, showSearchBar = true, + showQuestBar = true, }, } end -- Ensure new settings exist for existing installations + if Guda_CharDB.settings.showQuestBar == nil then + Guda_CharDB.settings.showQuestBar = true + end if not Guda_CharDB.settings.bagColumns then Guda_CharDB.settings.bagColumns = 10 end diff --git a/Core/Init.lua b/Core/Init.lua index 20a13a7..7453306 100644 --- a/Core/Init.lua +++ b/Core/Init.lua @@ -94,7 +94,22 @@ addon.Constants = { } -- Initialize modules storage -addon.Modules = {} +addon.Modules = { + Main = {}, + DB = {}, + Events = {}, + Utils = {}, + Tooltip = {}, + BagScanner = {}, + BankScanner = {}, + MoneyTracker = {}, + EquipmentScanner = {}, + SortEngine = {}, + BagFrame = {}, + BankFrame = {}, + QuestItemBar = {}, + SettingsPopup = {}, +} -- Readiness flags for safe early keybind handling addon._ready = false diff --git a/Core/Main.lua b/Core/Main.lua index 058befa..04c72a6 100644 --- a/Core/Main.lua +++ b/Core/Main.lua @@ -22,8 +22,25 @@ function Main:Initialize() addon.Modules.EquipmentScanner:Initialize() -- Initialize UI + addon:Print("Initializing UI...") addon.Modules.BagFrame:Initialize() addon.Modules.BankFrame:Initialize() + + addon:Debug("Checking QuestItemBar module...") + if addon.Modules.QuestItemBar and addon.Modules.QuestItemBar.isLoaded then + addon:Debug("QuestItemBar module found and loaded, initializing...") + local success, err = pcall(function() addon.Modules.QuestItemBar:Initialize() end) + if not success then + addon:Error("Failed to initialize QuestItemBar: %s", tostring(err)) + end + else + if not addon.Modules.QuestItemBar then + addon:Error("QuestItemBar module table is MISSING from addon.Modules!") + else + addon:Error("QuestItemBar module file failed to load (isLoaded is nil)!") + end + end + addon.Modules.SettingsPopup:Initialize() -- Initialize tooltip @@ -85,6 +102,13 @@ function Main:SetupSlashCommands() addon.DEBUG = not addon.DEBUG addon:Print("Debug mode: %s", addon.DEBUG and "ON" or "OFF") + elseif msg == "quest" then + -- Toggle quest bar + local show = not addon.Modules.DB:GetSetting("showQuestBar") + addon.Modules.DB:SetSetting("showQuestBar", show) + addon.Modules.QuestItemBar:Update() + addon:Print("Quest bar: %s", show and "ON" or "OFF") + elseif msg == "cleanup" then -- Cleanup old characters addon.Modules.DB:CleanupOldCharacters() diff --git a/Guda.toc b/Guda.toc index e5268a6..290d278 100644 --- a/Guda.toc +++ b/Guda.toc @@ -2,7 +2,7 @@ ## Title: Guda ## Notes: All-in-one bag and bank addon for Turtle WoW ## Author: Vati -## Version: 1.1.8 +## Version: 1.1.9 ## SavedVariables: Guda_DB ## SavedVariablesPerCharacter: Guda_CharDB @@ -25,8 +25,8 @@ Sorting\SortEngine.lua UI\ItemButton.lua UI\BagFrame.lua UI\BankFrame.lua +UI\QuestItemBar.lua UI\SettingsPopup.lua - UI\ItemButton.xml UI\BagFrame.xml UI\BankFrame.xml diff --git a/UI/QuestItemBar.lua b/UI/QuestItemBar.lua new file mode 100644 index 0000000..0fe8353 --- /dev/null +++ b/UI/QuestItemBar.lua @@ -0,0 +1,241 @@ +-- 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) } + + 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() + + -- Set custom data for tooltip handling + button.hasItem = true + + -- 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: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("PLAYER_ENTERING_WORLD", function() + QuestItemBar:Update() + end, "QuestItemBar") + + QuestItemBar:Update() + addon:Debug("QuestItemBar initialized") +end + +QuestItemBar.isLoaded = true diff --git a/UI/SettingsPopup.lua b/UI/SettingsPopup.lua index a393f1c..4cd2e19 100644 --- a/UI/SettingsPopup.lua +++ b/UI/SettingsPopup.lua @@ -54,6 +54,10 @@ function Guda_SettingsPopup_OnShow(self) if showSearchBar == nil then showSearchBar = true end + local showQuestBar = Guda.Modules.DB:GetSetting("showQuestBar") + if showQuestBar == nil then + showQuestBar = true + end -- Update sliders and checkboxes local bagSlider = getglobal("Guda_SettingsPopup_BagColumnsSlider") @@ -66,6 +70,7 @@ function Guda_SettingsPopup_OnShow(self) local qualityBorderEquipmentCheckbox = getglobal("Guda_SettingsPopup_QualityBorderEquipmentCheckbox") local qualityBorderOtherCheckbox = getglobal("Guda_SettingsPopup_QualityBorderOtherCheckbox") local showSearchBarCheckbox = getglobal("Guda_SettingsPopup_ShowSearchBarCheckbox") + local showQuestBarCheckbox = getglobal("Guda_SettingsPopup_ShowQuestBarCheckbox") if bagSlider then bagSlider:SetValue(bagColumns) @@ -106,6 +111,10 @@ function Guda_SettingsPopup_OnShow(self) if showSearchBarCheckbox then showSearchBarCheckbox:SetChecked(showSearchBar and 1 or 0) end + + if showQuestBarCheckbox then + showQuestBarCheckbox:SetChecked(showQuestBar and 1 or 0) + end end -- Toggle visibility @@ -555,6 +564,45 @@ function Guda_SettingsPopup_ShowSearchBarCheckbox_OnClick(self) end end +-- Show Quest Bar Checkbox OnLoad +function Guda_SettingsPopup_ShowQuestBarCheckbox_OnLoad(self) + local text = getglobal(self:GetName().."Text") + if text then + text:SetText("Show Quest Bar") + + -- Increase font size + local font, _, flags = text:GetFont() + if font then + text:SetFont(font, 13, flags) + end + end + + local showQuestBar = true + if Guda and Guda.Modules and Guda.Modules.DB then + showQuestBar = Guda.Modules.DB:GetSetting("showQuestBar") + if showQuestBar == nil then + showQuestBar = true + end + end + + self:SetChecked(showQuestBar and 1 or 0) +end + +-- Show Quest Bar Checkbox OnClick +function Guda_SettingsPopup_ShowQuestBarCheckbox_OnClick(self) + local isChecked = self:GetChecked() == 1 + + -- Save setting + if Guda and Guda.Modules and Guda.Modules.DB then + Guda.Modules.DB:SetSetting("showQuestBar", isChecked) + end + + -- Update quest bar visibility + if Guda.Modules.QuestItemBar and Guda.Modules.QuestItemBar.Update then + Guda.Modules.QuestItemBar:Update() + end +end + -- Initialize function SettingsPopup:Initialize() Guda:Debug("Settings popup initialized") diff --git a/UI/SettingsPopup.xml b/UI/SettingsPopup.xml index ac1e096..259d560 100644 --- a/UI/SettingsPopup.xml +++ b/UI/SettingsPopup.xml @@ -3,7 +3,7 @@ - + @@ -264,6 +264,25 @@ + + + + + + + + + + + + + Guda_SettingsPopup_ShowQuestBarCheckbox_OnLoad(this) + + + Guda_SettingsPopup_ShowQuestBarCheckbox_OnClick(this) + + +