From 0c16f3241ebe0100e7a6314909b2992304c539f6 Mon Sep 17 00:00:00 2001 From: Salikh Gurgenidze Date: Sat, 22 Nov 2025 11:57:23 +0400 Subject: [PATCH 1/8] clean: unused code --- UI/ItemButton.lua | 116 ---------------------------------------------- 1 file changed, 116 deletions(-) diff --git a/UI/ItemButton.lua b/UI/ItemButton.lua index 51da5e5..e3cd83f 100644 --- a/UI/ItemButton.lua +++ b/UI/ItemButton.lua @@ -661,120 +661,4 @@ function Guda_ItemButton_OnLeave(self) Guda_BagFrame_ClearBagButtonHighlight() end end -end - --- OnDragStart handler -function Guda_ItemButton_OnDragStart(self, button) - -- Don't allow dragging other characters' items or in read-only mode - if self.otherChar or self.isReadOnly then - return - end - - -- Only allow left button drag - if button == "LeftButton" and self.hasItem then - -- Ensure the global click catcher doesn't intercept the drag/drop - local cc = getglobal and getglobal("Guda_ClickCatcher") - if cc and cc.Hide and cc:IsShown() then - cc:Hide() - end - PickupContainerItem(self.bagID, self.slotID) - end -end - --- OnReceiveDrag handler -function Guda_ItemButton_OnReceiveDrag(self) - -- Don't allow dragging to other characters' items or in read-only mode - if self.otherChar or self.isReadOnly then - return - end - - -- Place the item being dragged - PickupContainerItem(self.bagID, self.slotID) - - -- Trigger UI update after drop completes (was skipped during drag) - if addon and addon.Modules and addon.Modules.BagFrame then - addon.Modules.BagFrame:Update() - end -end - --- Handle mouse-up to emulate Blizzard drop behavior on 1.12 where OnReceiveDrag may not always fire --- (rollback) no custom OnMouseUp; rely on Blizzard default - --- OnMouseDown handler - pick up item when pressing mouse button (classic pattern) --- (rollback) no custom OnMouseDown; rely on Blizzard default - --- OnDragStop handler (optional cleanup) -function Guda_ItemButton_OnDragStop(self) - -- Reset cursor to default to avoid lingering special cursors - if ResetCursor then - ResetCursor() - end - - -- Trigger UI update after drag completes (was skipped during drag) - if addon and addon.Modules and addon.Modules.BagFrame then - addon.Modules.BagFrame:Update() - end -end - --- Stack split callback (called by StackSplitFrame) -local function ItemButton_SplitStack(self, split) - if self.bagID and self.slotID then - SplitContainerItem(self.bagID, self.slotID, split) - end -end - --- OnClick handler -function Guda_ItemButton_OnClick(self, button) - -- Don't allow interaction with other characters' items or in read-only mode - if self.otherChar or self.isReadOnly then return end - - -- Set the split callback - self.SplitStack = ItemButton_SplitStack - - -- Modified clicks - if IsShiftKeyDown() then - if button == "LeftButton" and self.hasItem then - -- Get live count and link - local _, count = GetContainerItemInfo(self.bagID, self.slotID) - local itemLink = GetContainerItemLink(self.bagID, self.slotID) - - -- Shift+Left Click on stackable item: Show split stack dialog - if count and count > 1 then - OpenStackSplitFrame(count, self, "BOTTOMRIGHT", "TOPRIGHT") - return - end - -- If not stackable or only 1 item, link to chat - if itemLink and ChatFrameEditBox:IsVisible() then - ChatFrameEditBox:Insert(itemLink) - end - end - return - elseif IsControlKeyDown() then - -- Ctrl+Click: Dress up (if applicable) - if self.hasItem then - local itemLink = GetContainerItemLink(self.bagID, self.slotID) - if itemLink then - DressUpItemLink(itemLink) - end - end - return - end - - if button == "LeftButton" then - -- Left clicks are handled by MouseDown/MouseUp to prevent instant self-drop. - return - elseif button == "RightButton" then - -- Right click: Use item (only if slot has an item) - if self.hasItem then - UseContainerItem(self.bagID, self.slotID) - end - end -end - --- Release all buttons -function Guda_ReleaseAllButtons() - for _, button in pairs(buttonPool) do - button:Hide() - button:ClearAllPoints() - end end \ No newline at end of file From 4758d8b516fd43c8780068d41a252497f95ceab7 Mon Sep 17 00:00:00 2001 From: Salikh Gurgenidze Date: Sat, 22 Nov 2025 13:20:34 +0400 Subject: [PATCH 2/8] red color overlay for unusable item --- UI/ItemButton.lua | 200 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 190 insertions(+), 10 deletions(-) diff --git a/UI/ItemButton.lua b/UI/ItemButton.lua index e3cd83f..9457576 100644 --- a/UI/ItemButton.lua +++ b/UI/ItemButton.lua @@ -1,11 +1,10 @@ -- Local alias to the addon root table (must be defined before any usages below) local addon = Guda - + -- Item button pool local buttonPool = {} local nextButtonID = 1 --- Hidden tooltip for scanning quest items local scanTooltip = CreateFrame("GameTooltip", "Guda_QuestScanTooltip", nil, "GameTooltipTemplate") scanTooltip:SetOwner(WorldFrame, "ANCHOR_NONE") @@ -35,6 +34,179 @@ local function IsQuestItem(bagID, slotID) return false end +--===================================================== +-- Unusable item detection (pfUI-inspired implementation) +-- Adds a red tint overlay to items that your character +-- cannot use (class/race/skill restrictions), excluding +-- purely broken durability cases. +--===================================================== +local function Guda_GetUnusableColor() + if pfUI and C and C.appearance and C.appearance.bags and C.appearance.bags.unusable_color then + local cr, cg, cb, ca = strsplit(",", C.appearance.bags.unusable_color) + local r = tonumber(cr) or 0.9 + local g = tonumber(cg) or 0.2 + local b = tonumber(cb) or 0.2 + local a = tonumber(ca) or 1.0 + return r, g, b, a + end + -- Then Blizzard's RED_FONT_COLOR if present + if RED_FONT_COLOR then + return RED_FONT_COLOR.r, RED_FONT_COLOR.g, RED_FONT_COLOR.b, 1.0 + end + -- Default pfUI-like + return 0.9, 0.2, 0.2, 1.0 +end + +-- Build durability match pattern based on the client template +local durabilityPattern +if DURABILITY_TEMPLATE then + -- e.g. "Durability %d / %d" -> "Durability (.+)" + durabilityPattern = string.gsub(DURABILITY_TEMPLATE, "%%[^%s]+", "(.+)") +end + +-- Tiny helper to compare font color to Blizzard's RED_FONT_COLOR +local function IsRedColor(r, g, b) + if not r or not g or not b or not RED_FONT_COLOR then return false end + local dr = math.abs(r - RED_FONT_COLOR.r) + local dg = math.abs(g - RED_FONT_COLOR.g) + local db = math.abs(b - RED_FONT_COLOR.b) + return (dr < 0.08 and dg < 0.08 and db < 0.08) +end + +-- Scan tooltip for red text that is NOT a durability line +local function IsItemUnusable(bagID, slotID, isBank) + if not bagID or not slotID then return false end + + -- Some clients require SetOwner before every SetBagItem/SetInventoryItem to populate lines + if scanTooltip.SetOwner then + scanTooltip:SetOwner(UIParent or WorldFrame, "ANCHOR_NONE") + end + scanTooltip:ClearLines() + + if isBank and bagID == -1 then + -- Bank frame item buttons map slots 1.. to inventory slots 40.. (39 + slot) + if scanTooltip.SetInventoryItem then + scanTooltip:SetInventoryItem("player", 39 + slotID) + else + -- Fallback to bag scan if API missing + scanTooltip:SetBagItem(bagID, slotID) + end + else + scanTooltip:SetBagItem(bagID, slotID) + end + + if scanTooltip.Show then scanTooltip:Show() end + + local num = scanTooltip:NumLines() or 0 + for i = 1, num do + -- Scan LEFT column + local left = getglobal("Guda_QuestScanTooltipTextLeft" .. i) + if left and left:IsShown() then + local text = left:GetText() + local r, g, b = left:GetTextColor() + -- Be tolerant with red detection in case client colors differ slightly + local isRed = IsRedColor(r, g, b) or (r and g and b and r > 0.85 and g < 0.3 and b < 0.3) + if text and isRed then + -- Ignore red durability (broken) lines + if durabilityPattern and string.find(text, durabilityPattern, 1) then + -- skip durability + else + if scanTooltip.Hide then scanTooltip:Hide() end + return true + end + end + end + + -- Scan RIGHT column as well (required level etc can appear here on some clients) + local right = getglobal("Guda_QuestScanTooltipTextRight" .. i) + if right and right:IsShown() then + local text = right:GetText() + local r, g, b = right:GetTextColor() + local isRed = IsRedColor(r, g, b) or (r and g and b and r > 0.85 and g < 0.3 and b < 0.3) + if text and isRed then + if durabilityPattern and string.find(text, durabilityPattern, 1) then + -- skip durability + else + if scanTooltip.Hide then scanTooltip:Hide() end + return true + end + end + end + end + + if scanTooltip.Hide then scanTooltip:Hide() end + + return false +end + +-- Apply/remove red tint on item texture for unusable items +local function Guda_ItemButton_UpdateUsableTint(self) + -- Only evaluate for live (player) items; DB cached items from other chars cannot be scanned + if not self or not self.hasItem or not self.bagID or not self.slotID or self.isReadOnly then + -- Clear any tint/overlay on non-live/empty slots + if self.unusableOverlay and self.unusableOverlay.Hide then self.unusableOverlay:Hide() end + if SetItemButtonTextureVertexColor then SetItemButtonTextureVertexColor(self, 1.0, 1.0, 1.0) end + return + end + + local unusable = IsItemUnusable(self.bagID, self.slotID, self.isBank) + -- Ensure overlay exists (created in OnLoad, but be defensive) + if not self.unusableOverlay then + local icon = getglobal(self:GetName().."IconTexture") or getglobal(self:GetName().."Icon") or self.icon or self.Icon + local overlay = (icon and icon:GetParent() or self):CreateTexture(nil, "OVERLAY") + overlay:SetAllPoints(icon or self) + overlay:SetTexture("Interface\\ChatFrame\\ChatFrameBackground") + overlay:Hide() + self.unusableOverlay = overlay + end + + -- Always reset base icon vertex color to white; we drive the red via overlay to avoid external resets + if SetItemButtonTextureVertexColor then SetItemButtonTextureVertexColor(self, 1.0, 1.0, 1.0) end + + if unusable then + local r, g, b, a = Guda_GetUnusableColor() + -- Slightly reduce alpha to avoid over-darkening the icon + local alpha = (a or 1.0) * 0.45 + self.unusableOverlay:SetVertexColor(r or 0.9, g or 0.2, b or 0.2, alpha) + self.unusableOverlay:Show() + else + if self.unusableOverlay and self.unusableOverlay.Hide then self.unusableOverlay:Hide() end + end +end + +--===================================================== +-- Global rescanner to keep unusable tint in sync +--===================================================== +local function Guda_ItemButton_RescanAllUsableTint() + if not buttonPool then return end + for _, btn in pairs(buttonPool) do + if btn and btn:IsShown() and btn.hasItem and not btn.isReadOnly then + if Guda_ItemButton_UpdateUsableTint then + Guda_ItemButton_UpdateUsableTint(btn) + end + end + end +end + +-- Event frame to refresh overlays when usability can change +if not Guda_UnusableTintEventFrame then + Guda_UnusableTintEventFrame = CreateFrame("Frame", "Guda_UnusableTintEventFrame") + Guda_UnusableTintEventFrame:RegisterEvent("BAG_UPDATE") + Guda_UnusableTintEventFrame:RegisterEvent("UNIT_INVENTORY_CHANGED") + Guda_UnusableTintEventFrame:RegisterEvent("PLAYER_LEVEL_UP") + if GetBuildInfo then + -- Some clients expose skill update via this event name + Guda_UnusableTintEventFrame:RegisterEvent("SKILL_LINES_CHANGED") + end + -- Bank related + Guda_UnusableTintEventFrame:RegisterEvent("PLAYERBANKSLOTS_CHANGED") + Guda_UnusableTintEventFrame:RegisterEvent("PLAYERBANKBAGSLOTS_CHANGED") + + Guda_UnusableTintEventFrame:SetScript("OnEvent", function() + Guda_ItemButton_RescanAllUsableTint() + end) +end + -- Create or get a button from the pool function Guda_GetItemButton(parent) -- Try to reuse existing button @@ -251,6 +423,10 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha if not self.isReadOnly and Guda_ItemButton_UpdateCooldown then Guda_ItemButton_UpdateCooldown(self) end + -- Update unusable red overlay tint + if Guda_ItemButton_UpdateUsableTint then + Guda_ItemButton_UpdateUsableTint(self) + end else -- Fully clear all item button state for empty slots if SetItemButtonTexture then SetItemButtonTexture(self, nil) end @@ -272,6 +448,11 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha end if emptySlotBg then emptySlotBg:Show() end + + -- Ensure any unusable tint is cleared on empty + if SetItemButtonTextureVertexColor then + SetItemButtonTextureVertexColor(self, 1.0, 1.0, 1.0) + end end -- Resize empty slot background to match icon size (slightly larger to ensure coverage) @@ -375,7 +556,7 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha SetItemButtonDesaturated(self, isLocked, 0.5, 0.5, 0.5) end - -- Hide NormalTexture for filled slots (pfUI style) + -- Hide NormalTexture for filled slots self:SetNormalTexture("") local normalBorder = getglobal(self:GetName().."NormalTexture") if normalBorder then @@ -388,7 +569,7 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha emptySlotBg:SetAlpha(0.3) -- More subtle for filled slots end - -- Search filtering (pfUI style - ONLY use alpha, no other effects) + -- Search filtering if matchesFilter then -- Matching items: full opacity (1.0) self:SetAlpha(1.0) @@ -405,7 +586,7 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha countText:Hide() end - -- Set quality border (pfUI style using backdrop border) + -- Set quality border if self.qualityBorder then if bagID == -2 then -- Special border for keyring items (cyan/blue) @@ -498,18 +679,18 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha emptySlotBg:SetAlpha(0.5) -- Slightly more visible end - -- Dim empty slots when searching (pfUI style) + -- Dim empty slots when searching if matchesFilter then -- No search active or passes filter: normal opacity self:SetAlpha(1.0) else - -- Search active and doesn't match: very dim (25% like pfUI) + -- Search active and doesn't match: very dim self:SetAlpha(0.25) end countText:Hide() - -- Show border for empty keyring slots (pfUI style) + -- Show border for empty keyring slots if self.qualityBorder then if bagID == -2 then self.qualityBorder:SetBackdropBorderColor(0.2, 0.8, 1.0, 0.5) -- Dimmer cyan for empty slots @@ -530,7 +711,6 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha self:Show() end - -- Setup icon texture using pfUI's approach (anchor to fill button) -- In 1.12.1, ItemButtonTemplate creates an icon named "$parentIconTexture" local iconTexture = getglobal(self:GetName().."IconTexture") if not iconTexture then @@ -555,7 +735,7 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha iconTexture:SetPoint("CENTER", self, "CENTER", -0.5, 0.5) iconTexture:SetWidth(iconDisplaySize) iconTexture:SetHeight(iconDisplaySize) - -- Crop icon edges slightly (pfUI uses .08 to .92) + -- Crop icon edges slightly iconTexture:SetTexCoord(0.08, 0.92, 0.08, 0.92) iconTexture:Show() From 9ee1a027f002369de1abdbf64312459a109f08dc Mon Sep 17 00:00:00 2001 From: Salikh Gurgenidze Date: Sat, 22 Nov 2025 14:05:40 +0400 Subject: [PATCH 3/8] feat: update readme --- Core/Main.lua | 25 ------ README.md | 211 ++++++++++++++++++++++++---------------------- UI/ItemButton.lua | 2 - 3 files changed, 112 insertions(+), 126 deletions(-) diff --git a/Core/Main.lua b/Core/Main.lua index 97eba3b..9e21949 100644 --- a/Core/Main.lua +++ b/Core/Main.lua @@ -6,24 +6,6 @@ local addon = Guda local Main = {} addon.Modules.Main = Main --- Manual save function (for slash command) -function Main:SaveData() - addon:Debug("Saving data...") - - -- Save bags - addon.Modules.BagScanner:SaveToDatabase() - - -- Save bank (if available) - if addon.Modules.BankScanner:IsBankOpen() then - addon.Modules.BankScanner:SaveToDatabase() - end - - -- Save money - addon.Modules.MoneyTracker:Update() - - addon:Debug("Save complete") -end - -- Initialize addon function Main:Initialize() -- Wait for PLAYER_LOGIN to ensure saved variables are loaded @@ -83,11 +65,6 @@ function Main:SetupSlashCommands() -- Sort bank addon.Modules.SortEngine:SortBank() - elseif msg == "save" then - -- Manual save - Main:SaveData() - addon:Print("Data saved manually") - elseif msg == "debug" then -- Toggle debug addon.DEBUG = not addon.DEBUG @@ -102,10 +79,8 @@ function Main:SetupSlashCommands() addon:Print("Commands:") addon:Print("/guda - Toggle bags") addon:Print("/guda bank - Toggle bank") - addon:Print("/guda chars - Select character") addon:Print("/guda sort - Sort bags") addon:Print("/guda sortbank - Sort bank") - addon:Print("/guda save - Manual save") addon:Print("/guda debug - Toggle debug mode") addon:Print("/guda cleanup - Remove old characters") diff --git a/README.md b/README.md index eadbfbd..8aca89e 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,48 @@ # Guda -A comprehensive bag and bank management addon for Turtle WoW (1.12.1). +A comprehensive **bag and bank management addon** for **World of Warcraft 1.12.1**, fully compatible with **Turtle WoW**. -## Features +Guda provides a modern, unified bag/bank experience with multi-character support, sorting, item tracking, and quality-of-life tools. + +--- + +## 📦 Features ### 🎒 Bag Management -- **Unified Bag View**: All your bags in one window -- **Smart Sorting**: Sort by quality, name, or item type -- **Search Functionality**: Quickly find items with the search box -- **Quality Borders**: Visual quality indicators on items +* **Unified Bag View** – All bags displayed in one window +* **Smart Sorting** – Sort by quality, name, or item type +* **Search Box** – Quickly find items +* **Quality Borders** – Items are visually color-coded based on rarity ### 🏦 Bank Management -- **Bank Viewing**: View your bank from anywhere (cached data) -- **Bank Sorting**: Organize your bank with one click -- **Persistent Storage**: Bank contents saved and viewable offline +* **Remote Bank Viewing** – View cached bank contents from anywhere +* **One-Click Sorting** – Organize your bank easily +* **Persistent Storage** – Bank data saved between sessions ### 👥 Multi-Character Support -- **Cross-Character Viewing**: View any character's bags and bank -- **Money Tracking**: See total gold across all characters -- **Character Selector**: Easy switching between characters -- **Faction Filtering**: Only shows characters of the same faction -- **Item Counting**: Track total quantities of items across all characters, including: - - Bags - - Bank - - Equipped items - - Displayed in tooltips with breakdown +* **Cross-Character Viewing** – View bags & banks of any character +* **Money Tracking** – See total gold across all characters +* **Character Selector** – Switch characters quickly +* **Faction Filtering** – Shows only characters from the same faction +* **Global Item Counting** – Item totals across all characters, including: + + * Bags + * Banks + * Equipped items + * Tooltip breakdown per character ### 💰 Money Display -- **Current Character**: Shows your current gold/silver/copper -- **Total Money**: Displays combined wealth across all characters -- **Per-Character**: View each character's money in the selector +* **Current Character Money** +* **Total Money Across All Characters** +* **Per-Character Overview** in the selector -## Slash Commands +--- + +## 📝 Slash Commands ``` /guda or /gn @@ -44,121 +51,127 @@ A comprehensive bag and bank management addon for Turtle WoW (1.12.1). /guda bank - Toggle bank view /guda sort - Sort your bags /guda sortbank - Sort your bank (must be at bank) -/guda save - Manually save data /guda debug - Toggle debug mode /guda cleanup - Remove characters not seen in 90 days /guda help - Show this help ``` -## How to Use +--- + +## 🚀 How to Use ### Basic Usage 1. Press **B** or type `/guda` to open your bags -2. Click **Characters** button to view other characters -3. Click **Bank** button to view your bank (cached) +2. Click **Characters** to switch characters +3. Click **Bank** to view your cached bank 4. Click **Sort** to organize your bags ### Sorting -- **Sort Bags**: Click the **Sort** button or `/guda sort` -- **Sort Bank**: Click **Sort Bank** button (must be at bank) or `/guda sortbank` -- **Sort Methods**: Quality (default), Name, or Type - - Quality: Epic → Rare → Uncommon → Common - - Name: Alphabetical - - Type: By item class and subclass +* **Sort Bags**: Press **Sort** or use `/guda sort` +* **Sort Bank**: Use **Sort Bank** or `/guda sortbank` +* Sorting modes: -## Features in Detail + * **Quality** (Epic → Rare → Uncommon → Common) + * **Name** (A → Z) + * **Type** (Item class & subclass) -### Bag Scanner +--- -- Automatically scans bags on login and updates -- Tracks all items with full details (name, quality, count, etc.) -- Updates in real-time as you loot/move items +## 🧠 Internal Systems -### Bank Scanner +### 🔍 Bag Scanner -- Scans bank when you open it -- Saves bank contents for offline viewing -- Updates automatically while bank is open +* Scans all bags at login +* Updates when looting, moving, or modifying items +* Stores item details (count, quality, name, link, etc.) -### Money Tracker +### 🏦 Bank Scanner -- Tracks money changes in real-time -- Shows current character money -- Calculates total across all characters -- Per-character money in character selector +* Scans on bank open +* Saves snapshot for offline viewing +* Updates live while the bank is open -### Data Storage +### 💰 Money Tracker -- Saves to `Guda_DB` (global) -- Character settings in `Guda_CharDB` -- Persistent across sessions -- Automatic cleanup of old characters (90+ days) +* Tracks money changes in real time +* Displays per-character, current character, and total money -## Configuration +### 🗄️ Data Storage -Currently all configuration is automatic. Future versions may include: +* **Guda_DB** – Global data: -- Customizable sort methods -- Buttons per row -- Filter options -- Color customization + * Bag & bank contents + * Character money + * Last update timestamps +* **Guda_CharDB** – Per-character UI settings -## Known Limitations +--- -- **Sort Functionality**: Basic sorting is implemented but actual item moving requires additional complexity to handle: - - Soulbound items - - Bag type restrictions (soul bags, etc.) - - Quest items - - Locked items -- **Bank Access**: Must open bank at least once to cache contents -- **Same Faction**: Can only view characters of the same faction +## ⚙️ Configuration -## Technical Details +Configuration is currently automatic. Future updates may include: -### Saved Variables +* Custom sort methods +* Adjustable layout (buttons per row, item size) +* Item filters +* Color customization -- `Guda_DB`: Global database (all characters) - - Character data (bags, bank, money) - - Last update timestamps -- `Guda_CharDB`: Per-character settings - - UI preferences - - Sort method +--- -### Auto-Save Schedule +## ⚠️ Known Limitations -- Every 30 minutes while playing -- On player logout -- Manual: `/guda save` +* **Sorting**: -### Events Monitored + * Advanced sorting requires handling bag restrictions (soul bags, profession bags) + * Locked and soulbound items need special handling +* **Bank Access**: -- `BAG_UPDATE`: Bag content changes -- `BANKFRAME_OPENED`: Bank opened -- `BANKFRAME_CLOSED`: Bank closed -- `PLAYER_MONEY`: Money changes -- `PLAYER_LOGIN`: Character login -- `PLAYER_LOGOUT`: Character logout + * Must open the bank at least once to cache contents +* **Faction Restriction**: -## Credits + * Only shows characters from the same faction -Created for Turtle WoW 1.12.1 -Version 1.0.2 +--- -## Support +## 🖼️ Images -For bugs or feature requests, please report them in-game or on the forums. +### Guda Settings -## Changelog +![Guda Settings](https://i.imgur.com/Tfzl6ru.png) -### Version 1.0.2 +### Bag View -- Initial release -- Bag viewing and sorting -- Bank viewing and sorting -- Multi-character support -- Money tracking -- Auto-save system -- Character selector -- Search functionality +![Bag View](https://i.imgur.com/cqISq71.png) + +### Bank View + +![Bank View](https://i.imgur.com/rV1f8Lu.png) + +--- + +## 🐞 Common Issues + +### 1. Cannot open bags using **B** + +Set the keybinding: +**Esc → Key Bindings → Guda → Toggle Bags** + +![Keybindings Fix](https://i.imgur.com/IJv36Lg.png) + +### 2. Issues after updating the addon + +Delete outdated saved variables: + +``` +WTF/Account//SavedVariables/Guda.lua +WTF/Account//SavedVariables/Guda.lua.bak +``` + +--- + +## 📢 Support + +For bugs or feature requests, please open an issue or post on the Turtle WoW forums. +Your feedback helps improve the addon! diff --git a/UI/ItemButton.lua b/UI/ItemButton.lua index 9457576..f962f4c 100644 --- a/UI/ItemButton.lua +++ b/UI/ItemButton.lua @@ -169,8 +169,6 @@ local function Guda_ItemButton_UpdateUsableTint(self) local alpha = (a or 1.0) * 0.45 self.unusableOverlay:SetVertexColor(r or 0.9, g or 0.2, b or 0.2, alpha) self.unusableOverlay:Show() - else - if self.unusableOverlay and self.unusableOverlay.Hide then self.unusableOverlay:Hide() end end end From 57d1c511aaf6f59354f4271eadf5f75d67f021cf Mon Sep 17 00:00:00 2001 From: Salikh Gurgenidze Date: Sat, 22 Nov 2025 15:44:03 +0400 Subject: [PATCH 4/8] improved quest item and unusable item logics --- README.md | 2 +- UI/ItemButton.lua | 88 +++++++++++++++++++---------------------------- 2 files changed, 36 insertions(+), 54 deletions(-) diff --git a/README.md b/README.md index 8aca89e..bea0df0 100644 --- a/README.md +++ b/README.md @@ -173,5 +173,5 @@ WTF/Account//SavedVariables/Guda.lua.bak ## 📢 Support -For bugs or feature requests, please open an issue or post on the Turtle WoW forums. +For bugs or feature requests, please open an issue. Your feedback helps improve the addon! diff --git a/UI/ItemButton.lua b/UI/ItemButton.lua index f962f4c..c2e5380 100644 --- a/UI/ItemButton.lua +++ b/UI/ItemButton.lua @@ -8,30 +8,46 @@ local nextButtonID = 1 local scanTooltip = CreateFrame("GameTooltip", "Guda_QuestScanTooltip", nil, "GameTooltipTemplate") scanTooltip:SetOwner(WorldFrame, "ANCHOR_NONE") --- (rollback) no custom drag-source tracking or target resolution; rely on Blizzard handlers - -- Check if an item is a quest item by scanning its tooltip local function IsQuestItem(bagID, slotID) - if not bagID or not slotID then return false end + if not bagID or not slotID then return false end - scanTooltip:ClearLines() - scanTooltip:SetBagItem(bagID, slotID) + scanTooltip:ClearLines() + scanTooltip:SetBagItem(bagID, slotID) - -- Check all tooltip lines for "Quest Item" text - for i = 1, scanTooltip:NumLines() do - local line = getglobal("Guda_QuestScanTooltipTextLeft" .. i) - if line then - local text = line:GetText() - if text then - -- Check for "Quest Item" text (case sensitive to match WoW's tooltip) - if string.find(text, "Quest Item") then - return true - end - end - end - end + local isQuestItem = false - return false + -- Check all tooltip lines for quest-related text + for i = 1, scanTooltip:NumLines() do + local line = getglobal("Guda_QuestScanTooltipTextLeft" .. i) + if line then + local text = line:GetText() + if text then + addon:Print("text:%s", text or '') + -- Check for various quest-related text patterns + if string.find(text, "Quest Item") or + string.find(text, "Quest Starter") or + (string.find(text, "Manual") or string.find(text, "Soulbond")) or + string.find(text, "This Item Begins a Quest") then + isQuestItem = true + break + end + end + end + end + + -- Also check if the item type is "Quest" + if not isQuestItem then + local link = GetContainerItemLink(bagID, slotID) + if link then + local itemName, itemLink, itemRarity, itemLevel, itemMinLevel, itemType = GetItemInfo(link) + if itemType == "Quest" then + isQuestItem = true + end + end + end + + return isQuestItem end --===================================================== @@ -134,8 +150,6 @@ local function IsItemUnusable(bagID, slotID, isBank) end end - if scanTooltip.Hide then scanTooltip:Hide() end - return false end @@ -172,38 +186,6 @@ local function Guda_ItemButton_UpdateUsableTint(self) end end ---===================================================== --- Global rescanner to keep unusable tint in sync ---===================================================== -local function Guda_ItemButton_RescanAllUsableTint() - if not buttonPool then return end - for _, btn in pairs(buttonPool) do - if btn and btn:IsShown() and btn.hasItem and not btn.isReadOnly then - if Guda_ItemButton_UpdateUsableTint then - Guda_ItemButton_UpdateUsableTint(btn) - end - end - end -end - --- Event frame to refresh overlays when usability can change -if not Guda_UnusableTintEventFrame then - Guda_UnusableTintEventFrame = CreateFrame("Frame", "Guda_UnusableTintEventFrame") - Guda_UnusableTintEventFrame:RegisterEvent("BAG_UPDATE") - Guda_UnusableTintEventFrame:RegisterEvent("UNIT_INVENTORY_CHANGED") - Guda_UnusableTintEventFrame:RegisterEvent("PLAYER_LEVEL_UP") - if GetBuildInfo then - -- Some clients expose skill update via this event name - Guda_UnusableTintEventFrame:RegisterEvent("SKILL_LINES_CHANGED") - end - -- Bank related - Guda_UnusableTintEventFrame:RegisterEvent("PLAYERBANKSLOTS_CHANGED") - Guda_UnusableTintEventFrame:RegisterEvent("PLAYERBANKBAGSLOTS_CHANGED") - - Guda_UnusableTintEventFrame:SetScript("OnEvent", function() - Guda_ItemButton_RescanAllUsableTint() - end) -end -- Create or get a button from the pool function Guda_GetItemButton(parent) From 53d82cb606d965e26fa5bbd301a5ac4009f180fe Mon Sep 17 00:00:00 2001 From: Salikh Gurgenidze Date: Sat, 22 Nov 2025 15:45:18 +0400 Subject: [PATCH 5/8] print log removed on questitemcheck --- UI/ItemButton.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UI/ItemButton.lua b/UI/ItemButton.lua index c2e5380..714e8e4 100644 --- a/UI/ItemButton.lua +++ b/UI/ItemButton.lua @@ -23,7 +23,7 @@ local function IsQuestItem(bagID, slotID) if line then local text = line:GetText() if text then - addon:Print("text:%s", text or '') + --addon:Print("text:%s", text or '') -- Check for various quest-related text patterns if string.find(text, "Quest Item") or string.find(text, "Quest Starter") or From b78360f86790c857764db80d20c93795348763fc Mon Sep 17 00:00:00 2001 From: Salikh Gurgenidze Date: Sun, 23 Nov 2025 13:10:19 +0400 Subject: [PATCH 6/8] fix: when bags are open, opening bank isn't closing them --- UI/BankFrame.lua | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/UI/BankFrame.lua b/UI/BankFrame.lua index 9b527ae..61c9afd 100644 --- a/UI/BankFrame.lua +++ b/UI/BankFrame.lua @@ -935,11 +935,14 @@ function BankFrame:Initialize() -- Show current character's bank in interactive mode currentViewChar = nil - -- Hide BagFrame to prevent button overlap - local bagFrame = getglobal("Guda_BagFrame") - if bagFrame and bagFrame:IsShown() then - bagFrame:Hide() - end + -- Do not auto-hide BagFrame when opening BankFrame + -- Previously, we hid BagFrame to prevent button overlap: + -- local bagFrame = getglobal("Guda_BagFrame") + -- if bagFrame and bagFrame:IsShown() then + -- bagFrame:Hide() + -- end + -- Users may want both frames visible simultaneously; layout issues, if any, + -- should be addressed via positioning rather than auto-hiding. -- Show and update custom bank frame local customBankFrame = getglobal("Guda_BankFrame") From 978988e0bf050b605fd532293540b31f30559591 Mon Sep 17 00:00:00 2001 From: Salikh Gurgenidze Date: Sun, 23 Nov 2025 13:50:22 +0400 Subject: [PATCH 7/8] fix: add quest icons --- UI/ItemButton.lua | 53 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/UI/ItemButton.lua b/UI/ItemButton.lua index 714e8e4..eaa7a2a 100644 --- a/UI/ItemButton.lua +++ b/UI/ItemButton.lua @@ -9,6 +9,7 @@ local scanTooltip = CreateFrame("GameTooltip", "Guda_QuestScanTooltip", nil, "Ga scanTooltip:SetOwner(WorldFrame, "ANCHOR_NONE") -- Check if an item is a quest item by scanning its tooltip +-- Check if an item is a quest item by scanning its tooltip and determine type local function IsQuestItem(bagID, slotID) if not bagID or not slotID then return false end @@ -16,6 +17,7 @@ local function IsQuestItem(bagID, slotID) scanTooltip:SetBagItem(bagID, slotID) local isQuestItem = false + local isQuestStarter = false -- Check all tooltip lines for quest-related text for i = 1, scanTooltip:NumLines() do @@ -23,14 +25,18 @@ local function IsQuestItem(bagID, slotID) if line then local text = line:GetText() if text then - --addon:Print("text:%s", text or '') - -- Check for various quest-related text patterns - if string.find(text, "Quest Item") or - string.find(text, "Quest Starter") or - (string.find(text, "Manual") or string.find(text, "Soulbond")) or - string.find(text, "This Item Begins a Quest") then + -- Check for quest starter patterns + 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 + -- Check for regular quest item patterns + elseif string.find(text, "Quest Item") or + (string.find(text, "Manual") or string.find(text, "Soulbond")) then + isQuestItem = true + -- Don't break, might still find a quest starter pattern end end end @@ -43,11 +49,19 @@ local function IsQuestItem(bagID, slotID) local itemName, itemLink, itemRarity, itemLevel, itemMinLevel, itemType = GetItemInfo(link) if itemType == "Quest" then isQuestItem = true + -- For quest type items, check if they're starters by name/description + if itemName and (string.find(itemName, "Note") or + string.find(itemName, "Letter") or + string.find(itemName, "Orders") or + string.find(itemName, "Rune") or + string.find(itemName, "Tablet")) then + isQuestStarter = true + end end end end - return isQuestItem + return isQuestItem, isQuestStarter end --===================================================== @@ -205,6 +219,26 @@ function Guda_GetItemButton(parent) return button end +-- Update quest icon based on item type (starter vs regular quest item) +local function Guda_ItemButton_UpdateQuestIcon(self, isQuest, isQuestStarter) + if not self.questIcon then return end + + if isQuest then + -- Set appropriate texture based on quest type + if not isQuestStarter then + addon:Print("isQuestSTarter:" .. tostring(isQuestStarter)) + local texture = self.questIcon:GetRegions() + if texture and texture.SetTexture then + texture:SetTexture("Interface\\GossipFrame\\ActiveQuestIcon") + texture:SetTexCoord(0, 1, 0, 1) + end + end + self.questIcon:Show() + else + self.questIcon:Hide() + end +end + -- OnLoad handler function Guda_ItemButton_OnLoad(self) self.hasItem = false @@ -622,7 +656,7 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha -- Check for quest items and show golden border + icon (higher priority than quality border) -- Only check for current character's items (not other characters or bank in read-only mode) - local isQuest = not self.otherChar and not self.isReadOnly and IsQuestItem(bagID, slotID) + local isQuest, isQuestStarter = IsQuestItem(bagID, slotID) if self.questBorder then if isQuest then @@ -639,7 +673,8 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha self.questIcon:Hide() end end - + -- Update quest icon with the appropriate texture + Guda_ItemButton_UpdateQuestIcon(self, isQuest, isQuestStarter) self:Show() else self.hasItem = false From 2a6cf50511658ae393026f38a533d1978f5a7222 Mon Sep 17 00:00:00 2001 From: Salikh Gurgenidze Date: Sun, 23 Nov 2025 13:52:28 +0400 Subject: [PATCH 8/8] fix: quest item icons --- Guda.toc | 2 +- UI/ItemButton.lua | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Guda.toc b/Guda.toc index 037f9e7..6933128 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.3 +## Version: 1.1.4 ## SavedVariables: Guda_DB ## SavedVariablesPerCharacter: Guda_CharDB diff --git a/UI/ItemButton.lua b/UI/ItemButton.lua index eaa7a2a..2bb1e0c 100644 --- a/UI/ItemButton.lua +++ b/UI/ItemButton.lua @@ -225,8 +225,15 @@ local function Guda_ItemButton_UpdateQuestIcon(self, isQuest, isQuestStarter) if isQuest then -- Set appropriate texture based on quest type - if not isQuestStarter then - addon:Print("isQuestSTarter:" .. tostring(isQuestStarter)) + if isQuestStarter then + -- Quest starter: exclamation mark + local texture = self.questIcon:GetRegions() + if texture and texture.SetTexture then + texture:SetTexture("Interface\\GossipFrame\\AvailableQuestIcon") + texture:SetTexCoord(0, 1, 0, 1) + end + else + -- Regular quest item: question mark local texture = self.questIcon:GetRegions() if texture and texture.SetTexture then texture:SetTexture("Interface\\GossipFrame\\ActiveQuestIcon")