Merge pull request #3 from vatichild/feat/equipment-usability
Feat/equipment usability
This commit is contained in:
@@ -6,24 +6,6 @@ local addon = Guda
|
|||||||
local Main = {}
|
local Main = {}
|
||||||
addon.Modules.Main = 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
|
-- Initialize addon
|
||||||
function Main:Initialize()
|
function Main:Initialize()
|
||||||
-- Wait for PLAYER_LOGIN to ensure saved variables are loaded
|
-- Wait for PLAYER_LOGIN to ensure saved variables are loaded
|
||||||
@@ -83,11 +65,6 @@ function Main:SetupSlashCommands()
|
|||||||
-- Sort bank
|
-- Sort bank
|
||||||
addon.Modules.SortEngine:SortBank()
|
addon.Modules.SortEngine:SortBank()
|
||||||
|
|
||||||
elseif msg == "save" then
|
|
||||||
-- Manual save
|
|
||||||
Main:SaveData()
|
|
||||||
addon:Print("Data saved manually")
|
|
||||||
|
|
||||||
elseif msg == "debug" then
|
elseif msg == "debug" then
|
||||||
-- Toggle debug
|
-- Toggle debug
|
||||||
addon.DEBUG = not addon.DEBUG
|
addon.DEBUG = not addon.DEBUG
|
||||||
@@ -102,10 +79,8 @@ function Main:SetupSlashCommands()
|
|||||||
addon:Print("Commands:")
|
addon:Print("Commands:")
|
||||||
addon:Print("/guda - Toggle bags")
|
addon:Print("/guda - Toggle bags")
|
||||||
addon:Print("/guda bank - Toggle bank")
|
addon:Print("/guda bank - Toggle bank")
|
||||||
addon:Print("/guda chars - Select character")
|
|
||||||
addon:Print("/guda sort - Sort bags")
|
addon:Print("/guda sort - Sort bags")
|
||||||
addon:Print("/guda sortbank - Sort bank")
|
addon:Print("/guda sortbank - Sort bank")
|
||||||
addon:Print("/guda save - Manual save")
|
|
||||||
addon:Print("/guda debug - Toggle debug mode")
|
addon:Print("/guda debug - Toggle debug mode")
|
||||||
addon:Print("/guda cleanup - Remove old characters")
|
addon:Print("/guda cleanup - Remove old characters")
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
## Title: Guda
|
## Title: Guda
|
||||||
## Notes: All-in-one bag and bank addon for Turtle WoW
|
## Notes: All-in-one bag and bank addon for Turtle WoW
|
||||||
## Author: Vati
|
## Author: Vati
|
||||||
## Version: 1.1.3
|
## Version: 1.1.4
|
||||||
## SavedVariables: Guda_DB
|
## SavedVariables: Guda_DB
|
||||||
## SavedVariablesPerCharacter: Guda_CharDB
|
## SavedVariablesPerCharacter: Guda_CharDB
|
||||||
|
|
||||||
|
|||||||
@@ -1,41 +1,48 @@
|
|||||||
# Guda
|
# 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
|
### 🎒 Bag Management
|
||||||
|
|
||||||
- **Unified Bag View**: All your bags in one window
|
* **Unified Bag View** – All bags displayed in one window
|
||||||
- **Smart Sorting**: Sort by quality, name, or item type
|
* **Smart Sorting** – Sort by quality, name, or item type
|
||||||
- **Search Functionality**: Quickly find items with the search box
|
* **Search Box** – Quickly find items
|
||||||
- **Quality Borders**: Visual quality indicators on items
|
* **Quality Borders** – Items are visually color-coded based on rarity
|
||||||
|
|
||||||
### 🏦 Bank Management
|
### 🏦 Bank Management
|
||||||
|
|
||||||
- **Bank Viewing**: View your bank from anywhere (cached data)
|
* **Remote Bank Viewing** – View cached bank contents from anywhere
|
||||||
- **Bank Sorting**: Organize your bank with one click
|
* **One-Click Sorting** – Organize your bank easily
|
||||||
- **Persistent Storage**: Bank contents saved and viewable offline
|
* **Persistent Storage** – Bank data saved between sessions
|
||||||
|
|
||||||
### 👥 Multi-Character Support
|
### 👥 Multi-Character Support
|
||||||
|
|
||||||
- **Cross-Character Viewing**: View any character's bags and bank
|
* **Cross-Character Viewing** – View bags & banks of any character
|
||||||
- **Money Tracking**: See total gold across all characters
|
* **Money Tracking** – See total gold across all characters
|
||||||
- **Character Selector**: Easy switching between characters
|
* **Character Selector** – Switch characters quickly
|
||||||
- **Faction Filtering**: Only shows characters of the same faction
|
* **Faction Filtering** – Shows only characters from the same faction
|
||||||
- **Item Counting**: Track total quantities of items across all characters, including:
|
* **Global Item Counting** – Item totals across all characters, including:
|
||||||
- Bags
|
|
||||||
- Bank
|
* Bags
|
||||||
- Equipped items
|
* Banks
|
||||||
- Displayed in tooltips with breakdown
|
* Equipped items
|
||||||
|
* Tooltip breakdown per character
|
||||||
|
|
||||||
### 💰 Money Display
|
### 💰 Money Display
|
||||||
|
|
||||||
- **Current Character**: Shows your current gold/silver/copper
|
* **Current Character Money**
|
||||||
- **Total Money**: Displays combined wealth across all characters
|
* **Total Money Across All Characters**
|
||||||
- **Per-Character**: View each character's money in the selector
|
* **Per-Character Overview** in the selector
|
||||||
|
|
||||||
## Slash Commands
|
---
|
||||||
|
|
||||||
|
## 📝 Slash Commands
|
||||||
|
|
||||||
```
|
```
|
||||||
/guda or /gn
|
/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 bank - Toggle bank view
|
||||||
/guda sort - Sort your bags
|
/guda sort - Sort your bags
|
||||||
/guda sortbank - Sort your bank (must be at bank)
|
/guda sortbank - Sort your bank (must be at bank)
|
||||||
/guda save - Manually save data
|
|
||||||
/guda debug - Toggle debug mode
|
/guda debug - Toggle debug mode
|
||||||
/guda cleanup - Remove characters not seen in 90 days
|
/guda cleanup - Remove characters not seen in 90 days
|
||||||
/guda help - Show this help
|
/guda help - Show this help
|
||||||
```
|
```
|
||||||
|
|
||||||
## How to Use
|
---
|
||||||
|
|
||||||
|
## 🚀 How to Use
|
||||||
|
|
||||||
### Basic Usage
|
### Basic Usage
|
||||||
|
|
||||||
1. Press **B** or type `/guda` to open your bags
|
1. Press **B** or type `/guda` to open your bags
|
||||||
2. Click **Characters** button to view other characters
|
2. Click **Characters** to switch characters
|
||||||
3. Click **Bank** button to view your bank (cached)
|
3. Click **Bank** to view your cached bank
|
||||||
4. Click **Sort** to organize your bags
|
4. Click **Sort** to organize your bags
|
||||||
|
|
||||||
### Sorting
|
### Sorting
|
||||||
|
|
||||||
- **Sort Bags**: Click the **Sort** button or `/guda sort`
|
* **Sort Bags**: Press **Sort** or use `/guda sort`
|
||||||
- **Sort Bank**: Click **Sort Bank** button (must be at bank) or `/guda sortbank`
|
* **Sort Bank**: Use **Sort Bank** or `/guda sortbank`
|
||||||
- **Sort Methods**: Quality (default), Name, or Type
|
* Sorting modes:
|
||||||
- Quality: Epic → Rare → Uncommon → Common
|
|
||||||
- Name: Alphabetical
|
|
||||||
- Type: By item class and subclass
|
|
||||||
|
|
||||||
## Features in Detail
|
* **Quality** (Epic → Rare → Uncommon → Common)
|
||||||
|
* **Name** (A → Z)
|
||||||
|
* **Type** (Item class & subclass)
|
||||||
|
|
||||||
### Bag Scanner
|
---
|
||||||
|
|
||||||
- Automatically scans bags on login and updates
|
## 🧠 Internal Systems
|
||||||
- Tracks all items with full details (name, quality, count, etc.)
|
|
||||||
- Updates in real-time as you loot/move items
|
|
||||||
|
|
||||||
### Bank Scanner
|
### 🔍 Bag Scanner
|
||||||
|
|
||||||
- Scans bank when you open it
|
* Scans all bags at login
|
||||||
- Saves bank contents for offline viewing
|
* Updates when looting, moving, or modifying items
|
||||||
- Updates automatically while bank is open
|
* Stores item details (count, quality, name, link, etc.)
|
||||||
|
|
||||||
### Money Tracker
|
### 🏦 Bank Scanner
|
||||||
|
|
||||||
- Tracks money changes in real-time
|
* Scans on bank open
|
||||||
- Shows current character money
|
* Saves snapshot for offline viewing
|
||||||
- Calculates total across all characters
|
* Updates live while the bank is open
|
||||||
- Per-character money in character selector
|
|
||||||
|
|
||||||
### Data Storage
|
### 💰 Money Tracker
|
||||||
|
|
||||||
- Saves to `Guda_DB` (global)
|
* Tracks money changes in real time
|
||||||
- Character settings in `Guda_CharDB`
|
* Displays per-character, current character, and total money
|
||||||
- Persistent across sessions
|
|
||||||
- Automatic cleanup of old characters (90+ days)
|
|
||||||
|
|
||||||
## Configuration
|
### 🗄️ Data Storage
|
||||||
|
|
||||||
Currently all configuration is automatic. Future versions may include:
|
* **Guda_DB** – Global data:
|
||||||
|
|
||||||
- Customizable sort methods
|
* Bag & bank contents
|
||||||
- Buttons per row
|
* Character money
|
||||||
- Filter options
|
* Last update timestamps
|
||||||
- Color customization
|
* **Guda_CharDB** – Per-character UI settings
|
||||||
|
|
||||||
## Known Limitations
|
---
|
||||||
|
|
||||||
- **Sort Functionality**: Basic sorting is implemented but actual item moving requires additional complexity to handle:
|
## ⚙️ Configuration
|
||||||
- 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
|
|
||||||
|
|
||||||
## 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
|
* **Sorting**:
|
||||||
- On player logout
|
|
||||||
- Manual: `/guda save`
|
|
||||||
|
|
||||||
### 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
|
* Must open the bank at least once to cache contents
|
||||||
- `BANKFRAME_OPENED`: Bank opened
|
* **Faction Restriction**:
|
||||||
- `BANKFRAME_CLOSED`: Bank closed
|
|
||||||
- `PLAYER_MONEY`: Money changes
|
|
||||||
- `PLAYER_LOGIN`: Character login
|
|
||||||
- `PLAYER_LOGOUT`: Character logout
|
|
||||||
|
|
||||||
## 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
|

|
||||||
|
|
||||||
### Version 1.0.2
|
### Bag View
|
||||||
|
|
||||||
- Initial release
|

|
||||||
- Bag viewing and sorting
|
|
||||||
- Bank viewing and sorting
|
### Bank View
|
||||||
- Multi-character support
|
|
||||||
- Money tracking
|

|
||||||
- Auto-save system
|
|
||||||
- Character selector
|
---
|
||||||
- Search functionality
|
|
||||||
|
## 🐞 Common Issues
|
||||||
|
|
||||||
|
### 1. Cannot open bags using **B**
|
||||||
|
|
||||||
|
Set the keybinding:
|
||||||
|
**Esc → Key Bindings → Guda → Toggle Bags**
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### 2. Issues after updating the addon
|
||||||
|
|
||||||
|
Delete outdated saved variables:
|
||||||
|
|
||||||
|
```
|
||||||
|
WTF/Account/<ACCOUNT_NAME>/SavedVariables/Guda.lua
|
||||||
|
WTF/Account/<ACCOUNT_NAME>/SavedVariables/Guda.lua.bak
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📢 Support
|
||||||
|
|
||||||
|
For bugs or feature requests, please open an issue.
|
||||||
|
Your feedback helps improve the addon!
|
||||||
|
|||||||
+8
-5
@@ -935,11 +935,14 @@ function BankFrame:Initialize()
|
|||||||
-- Show current character's bank in interactive mode
|
-- Show current character's bank in interactive mode
|
||||||
currentViewChar = nil
|
currentViewChar = nil
|
||||||
|
|
||||||
-- Hide BagFrame to prevent button overlap
|
-- Do not auto-hide BagFrame when opening BankFrame
|
||||||
local bagFrame = getglobal("Guda_BagFrame")
|
-- Previously, we hid BagFrame to prevent button overlap:
|
||||||
if bagFrame and bagFrame:IsShown() then
|
-- local bagFrame = getglobal("Guda_BagFrame")
|
||||||
bagFrame:Hide()
|
-- if bagFrame and bagFrame:IsShown() then
|
||||||
end
|
-- 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
|
-- Show and update custom bank frame
|
||||||
local customBankFrame = getglobal("Guda_BankFrame")
|
local customBankFrame = getglobal("Guda_BankFrame")
|
||||||
|
|||||||
+224
-138
@@ -5,27 +5,159 @@ local addon = Guda
|
|||||||
local buttonPool = {}
|
local buttonPool = {}
|
||||||
local nextButtonID = 1
|
local nextButtonID = 1
|
||||||
|
|
||||||
-- Hidden tooltip for scanning quest items
|
|
||||||
local scanTooltip = CreateFrame("GameTooltip", "Guda_QuestScanTooltip", nil, "GameTooltipTemplate")
|
local scanTooltip = CreateFrame("GameTooltip", "Guda_QuestScanTooltip", nil, "GameTooltipTemplate")
|
||||||
scanTooltip:SetOwner(WorldFrame, "ANCHOR_NONE")
|
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
|
-- 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)
|
local function IsQuestItem(bagID, slotID)
|
||||||
|
if not bagID or not slotID then return false end
|
||||||
|
|
||||||
|
scanTooltip:ClearLines()
|
||||||
|
scanTooltip:SetBagItem(bagID, slotID)
|
||||||
|
|
||||||
|
local isQuestItem = false
|
||||||
|
local isQuestStarter = 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
|
||||||
|
-- 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
|
||||||
|
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
|
||||||
|
-- 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, isQuestStarter
|
||||||
|
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
|
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()
|
scanTooltip:ClearLines()
|
||||||
scanTooltip:SetBagItem(bagID, slotID)
|
|
||||||
|
|
||||||
-- Check all tooltip lines for "Quest Item" text
|
if isBank and bagID == -1 then
|
||||||
for i = 1, scanTooltip:NumLines() do
|
-- Bank frame item buttons map slots 1.. to inventory slots 40.. (39 + slot)
|
||||||
local line = getglobal("Guda_QuestScanTooltipTextLeft" .. i)
|
if scanTooltip.SetInventoryItem then
|
||||||
if line then
|
scanTooltip:SetInventoryItem("player", 39 + slotID)
|
||||||
local text = line:GetText()
|
else
|
||||||
if text then
|
-- Fallback to bag scan if API missing
|
||||||
-- Check for "Quest Item" text (case sensitive to match WoW's tooltip)
|
scanTooltip:SetBagItem(bagID, slotID)
|
||||||
if string.find(text, "Quest Item") then
|
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
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -35,6 +167,40 @@ local function IsQuestItem(bagID, slotID)
|
|||||||
return false
|
return false
|
||||||
end
|
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()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Create or get a button from the pool
|
-- Create or get a button from the pool
|
||||||
function Guda_GetItemButton(parent)
|
function Guda_GetItemButton(parent)
|
||||||
-- Try to reuse existing button
|
-- Try to reuse existing button
|
||||||
@@ -53,6 +219,33 @@ function Guda_GetItemButton(parent)
|
|||||||
return button
|
return button
|
||||||
end
|
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 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")
|
||||||
|
texture:SetTexCoord(0, 1, 0, 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self.questIcon:Show()
|
||||||
|
else
|
||||||
|
self.questIcon:Hide()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- OnLoad handler
|
-- OnLoad handler
|
||||||
function Guda_ItemButton_OnLoad(self)
|
function Guda_ItemButton_OnLoad(self)
|
||||||
self.hasItem = false
|
self.hasItem = false
|
||||||
@@ -251,6 +444,10 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha
|
|||||||
if not self.isReadOnly and Guda_ItemButton_UpdateCooldown then
|
if not self.isReadOnly and Guda_ItemButton_UpdateCooldown then
|
||||||
Guda_ItemButton_UpdateCooldown(self)
|
Guda_ItemButton_UpdateCooldown(self)
|
||||||
end
|
end
|
||||||
|
-- Update unusable red overlay tint
|
||||||
|
if Guda_ItemButton_UpdateUsableTint then
|
||||||
|
Guda_ItemButton_UpdateUsableTint(self)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
-- Fully clear all item button state for empty slots
|
-- Fully clear all item button state for empty slots
|
||||||
if SetItemButtonTexture then SetItemButtonTexture(self, nil) end
|
if SetItemButtonTexture then SetItemButtonTexture(self, nil) end
|
||||||
@@ -272,6 +469,11 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha
|
|||||||
end
|
end
|
||||||
|
|
||||||
if emptySlotBg then emptySlotBg:Show() 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
|
end
|
||||||
|
|
||||||
-- Resize empty slot background to match icon size (slightly larger to ensure coverage)
|
-- Resize empty slot background to match icon size (slightly larger to ensure coverage)
|
||||||
@@ -375,7 +577,7 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha
|
|||||||
SetItemButtonDesaturated(self, isLocked, 0.5, 0.5, 0.5)
|
SetItemButtonDesaturated(self, isLocked, 0.5, 0.5, 0.5)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Hide NormalTexture for filled slots (pfUI style)
|
-- Hide NormalTexture for filled slots
|
||||||
self:SetNormalTexture("")
|
self:SetNormalTexture("")
|
||||||
local normalBorder = getglobal(self:GetName().."NormalTexture")
|
local normalBorder = getglobal(self:GetName().."NormalTexture")
|
||||||
if normalBorder then
|
if normalBorder then
|
||||||
@@ -388,7 +590,7 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha
|
|||||||
emptySlotBg:SetAlpha(0.3) -- More subtle for filled slots
|
emptySlotBg:SetAlpha(0.3) -- More subtle for filled slots
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Search filtering (pfUI style - ONLY use alpha, no other effects)
|
-- Search filtering
|
||||||
if matchesFilter then
|
if matchesFilter then
|
||||||
-- Matching items: full opacity (1.0)
|
-- Matching items: full opacity (1.0)
|
||||||
self:SetAlpha(1.0)
|
self:SetAlpha(1.0)
|
||||||
@@ -405,7 +607,7 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha
|
|||||||
countText:Hide()
|
countText:Hide()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Set quality border (pfUI style using backdrop border)
|
-- Set quality border
|
||||||
if self.qualityBorder then
|
if self.qualityBorder then
|
||||||
if bagID == -2 then
|
if bagID == -2 then
|
||||||
-- Special border for keyring items (cyan/blue)
|
-- Special border for keyring items (cyan/blue)
|
||||||
@@ -461,7 +663,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)
|
-- 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)
|
-- 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 self.questBorder then
|
||||||
if isQuest then
|
if isQuest then
|
||||||
@@ -478,7 +680,8 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha
|
|||||||
self.questIcon:Hide()
|
self.questIcon:Hide()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
-- Update quest icon with the appropriate texture
|
||||||
|
Guda_ItemButton_UpdateQuestIcon(self, isQuest, isQuestStarter)
|
||||||
self:Show()
|
self:Show()
|
||||||
else
|
else
|
||||||
self.hasItem = false
|
self.hasItem = false
|
||||||
@@ -498,18 +701,18 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha
|
|||||||
emptySlotBg:SetAlpha(0.5) -- Slightly more visible
|
emptySlotBg:SetAlpha(0.5) -- Slightly more visible
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Dim empty slots when searching (pfUI style)
|
-- Dim empty slots when searching
|
||||||
if matchesFilter then
|
if matchesFilter then
|
||||||
-- No search active or passes filter: normal opacity
|
-- No search active or passes filter: normal opacity
|
||||||
self:SetAlpha(1.0)
|
self:SetAlpha(1.0)
|
||||||
else
|
else
|
||||||
-- Search active and doesn't match: very dim (25% like pfUI)
|
-- Search active and doesn't match: very dim
|
||||||
self:SetAlpha(0.25)
|
self:SetAlpha(0.25)
|
||||||
end
|
end
|
||||||
|
|
||||||
countText:Hide()
|
countText:Hide()
|
||||||
|
|
||||||
-- Show border for empty keyring slots (pfUI style)
|
-- Show border for empty keyring slots
|
||||||
if self.qualityBorder then
|
if self.qualityBorder then
|
||||||
if bagID == -2 then
|
if bagID == -2 then
|
||||||
self.qualityBorder:SetBackdropBorderColor(0.2, 0.8, 1.0, 0.5) -- Dimmer cyan for empty slots
|
self.qualityBorder:SetBackdropBorderColor(0.2, 0.8, 1.0, 0.5) -- Dimmer cyan for empty slots
|
||||||
@@ -530,7 +733,6 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha
|
|||||||
self:Show()
|
self:Show()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Setup icon texture using pfUI's approach (anchor to fill button)
|
|
||||||
-- In 1.12.1, ItemButtonTemplate creates an icon named "$parentIconTexture"
|
-- In 1.12.1, ItemButtonTemplate creates an icon named "$parentIconTexture"
|
||||||
local iconTexture = getglobal(self:GetName().."IconTexture")
|
local iconTexture = getglobal(self:GetName().."IconTexture")
|
||||||
if not iconTexture then
|
if not iconTexture then
|
||||||
@@ -555,7 +757,7 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha
|
|||||||
iconTexture:SetPoint("CENTER", self, "CENTER", -0.5, 0.5)
|
iconTexture:SetPoint("CENTER", self, "CENTER", -0.5, 0.5)
|
||||||
iconTexture:SetWidth(iconDisplaySize)
|
iconTexture:SetWidth(iconDisplaySize)
|
||||||
iconTexture:SetHeight(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:SetTexCoord(0.08, 0.92, 0.08, 0.92)
|
||||||
iconTexture:Show()
|
iconTexture:Show()
|
||||||
|
|
||||||
@@ -662,119 +864,3 @@ function Guda_ItemButton_OnLeave(self)
|
|||||||
end
|
end
|
||||||
end
|
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
|
|
||||||
Reference in New Issue
Block a user