fix: juju powers as consumables
This commit is contained in:
@@ -81,6 +81,18 @@ C.PROFESSION_TOOL_IDS = {
|
||||
[20824] = true, -- Simple Grinder
|
||||
}
|
||||
|
||||
-- Items classified as "Quest" by GetItemInfo but are actually consumables
|
||||
-- These get reclassified as "Consumable" for category view and sorting
|
||||
C.QUEST_CATEGORY_EXCLUSIONS = {
|
||||
[12450] = true, -- Juju Flurry
|
||||
[12451] = true, -- Juju Power
|
||||
[12455] = true, -- Juju Ember
|
||||
[12457] = true, -- Juju Chill
|
||||
[12458] = true, -- Juju Guile
|
||||
[12459] = true, -- Juju Escape
|
||||
[12460] = true, -- Juju Might
|
||||
}
|
||||
|
||||
-- Weapon subtypes that should NOT be marked as junk
|
||||
C.PROFESSION_TOOL_SUBTYPES = {
|
||||
["Fishing Pole"] = true,
|
||||
|
||||
@@ -172,6 +172,17 @@ local function DetectQuestItem(lines, itemData)
|
||||
local isQuestItem = false
|
||||
local isQuestStarter = false
|
||||
|
||||
-- Early exit: exclude known non-quest items misclassified by the API
|
||||
if itemData and itemData.link and addon.Constants and addon.Constants.QUEST_CATEGORY_EXCLUSIONS then
|
||||
local _, _, idStr = string.find(itemData.link, "item:(%d+)")
|
||||
if idStr then
|
||||
local id = tonumber(idStr)
|
||||
if id and addon.Constants.QUEST_CATEGORY_EXCLUSIONS[id] then
|
||||
return false, false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Check item category first
|
||||
if itemData and itemData.class == "Quest" then
|
||||
isQuestItem = true
|
||||
|
||||
@@ -841,6 +841,11 @@ function Utils:IsQuestItem(bagID, slotID, itemData, isOtherChar, isBank)
|
||||
end
|
||||
end
|
||||
|
||||
-- Early exit: exclude known non-quest items that the API misclassifies as "Quest"
|
||||
if itemID and addon.Constants and addon.Constants.QUEST_CATEGORY_EXCLUSIONS and addon.Constants.QUEST_CATEGORY_EXCLUSIONS[itemID] then
|
||||
return false, false
|
||||
end
|
||||
|
||||
-- Check if item is equipment (should not be classified as quest unless explicitly Quest category)
|
||||
local isEquipment = (itemCategory == "Weapon" or itemCategory == "Armor" or
|
||||
itemType == "Weapon" or itemType == "Armor")
|
||||
|
||||
@@ -221,6 +221,14 @@ function BagScanner:ScanSlot(bagID, slot)
|
||||
itemData.iLevel = iLevel
|
||||
itemData.type = itemType
|
||||
itemData.class = itemCategory
|
||||
-- Override misclassified Quest items (e.g. Juju consumables) to Consumable
|
||||
if itemCategory == "Quest" and itemLink and addon.Constants and addon.Constants.QUEST_CATEGORY_EXCLUSIONS then
|
||||
local itemID = addon.Modules.Utils:ExtractItemID(itemLink)
|
||||
if itemID and addon.Constants.QUEST_CATEGORY_EXCLUSIONS[itemID] then
|
||||
itemData.class = "Consumable"
|
||||
itemData.type = "Consumable"
|
||||
end
|
||||
end
|
||||
itemData.subclass = itemSubType
|
||||
itemData.equipSlot = itemEquipLoc
|
||||
itemData.locked = locked
|
||||
|
||||
+11
-5
@@ -800,7 +800,12 @@ local function AddSortKeys(items)
|
||||
item.sortedClass = 1 -- All equippable gear gets priority class
|
||||
item.equipSlotOrder = EQUIP_SLOT_ORDER[itemSubType] or 999
|
||||
else
|
||||
item.sortedClass = CATEGORY_ORDER[itemCategory] or 99
|
||||
-- Override misclassified Quest items (e.g. Juju consumables) to Consumable
|
||||
if itemCategory == "Quest" and (addon.Constants.QUEST_CATEGORY_EXCLUSIONS and addon.Constants.QUEST_CATEGORY_EXCLUSIONS[itemID]) then
|
||||
item.sortedClass = CATEGORY_ORDER["Consumable"] or 2
|
||||
else
|
||||
item.sortedClass = CATEGORY_ORDER[itemCategory] or 99
|
||||
end
|
||||
|
||||
-- Check if item is a permanent enchant (should NOT be Quest)
|
||||
local itemProps = GetItemProperties(item.bagID, item.slot, item.data.link)
|
||||
@@ -812,9 +817,10 @@ local function AddSortKeys(items)
|
||||
item.sortedClass = 6 -- Same as Tools, comes before Quest (7)
|
||||
-- Heuristic: Detect items that should be in the Quest category (priority 7)
|
||||
-- but aren't categorized as such by the game (e.g. some "Manual" items)
|
||||
elseif item.sortedClass ~= (CATEGORY_ORDER["Quest"] or 7) then
|
||||
-- Skip items with a known non-Quest category (e.g. Consumable, Trade Goods)
|
||||
elseif item.sortedClass ~= (CATEGORY_ORDER["Quest"] or 7) and not CATEGORY_ORDER[itemCategory] then
|
||||
local nameLower = string.lower(item.itemName)
|
||||
if string.find(nameLower, "manual") or string.find(nameLower, "quest") then
|
||||
if string.find(nameLower, "manual") then
|
||||
item.sortedClass = CATEGORY_ORDER["Quest"] or 7
|
||||
elseif IsQuestItemTooltip(item.bagID, item.slot, item.data) then
|
||||
item.sortedClass = CATEGORY_ORDER["Quest"] or 7
|
||||
@@ -859,8 +865,8 @@ local function AddSortKeys(items)
|
||||
item.isQuestUsable = false
|
||||
item.isPermanentEnchant = isPermanentEnchant -- Store for potential use in sorting
|
||||
local nameLower = string.lower(item.itemName)
|
||||
if not isPermanentEnchant then
|
||||
if itemCategory == "Quest" or string.find(nameLower, "quest") or item.data.class == "Quest" or IsQuestItemTooltip(item.bagID, item.slot, item.data) then
|
||||
if not isPermanentEnchant and not (addon.Constants.QUEST_CATEGORY_EXCLUSIONS and addon.Constants.QUEST_CATEGORY_EXCLUSIONS[itemID]) then
|
||||
if itemCategory == "Quest" or item.data.class == "Quest" or IsQuestItemTooltip(item.bagID, item.slot, item.data) then
|
||||
item.isQuest = true
|
||||
if IsQuestItemStarter(item.bagID, item.slot, item.data) then item.isQuestStarter = true end
|
||||
if IsQuestItemUsable(item.bagID, item.slot, item.data) then item.isQuestUsable = true end
|
||||
|
||||
+114
-1
@@ -84,6 +84,70 @@ local function IsQuestItem(bagID, slotID, isBank, itemData)
|
||||
return false, false
|
||||
end
|
||||
|
||||
--=====================================================
|
||||
-- Inner Shadow (inset quality glow, GudaBags-inspired)
|
||||
-- 4 gradient textures along edges colored by item quality
|
||||
--=====================================================
|
||||
local INNER_SHADOW_SIZE = 4
|
||||
local INNER_SHADOW_ALPHA = 0.5
|
||||
|
||||
-- Create the 4-edge inner shadow textures on a button, anchored to an icon texture
|
||||
local function CreateInnerShadow(button, anchorTo)
|
||||
local shadow = {}
|
||||
-- Top edge
|
||||
shadow.top = button:CreateTexture(nil, "ARTWORK", nil, 1)
|
||||
shadow.top:SetPoint("TOPLEFT", anchorTo, "TOPLEFT", 0, 0)
|
||||
shadow.top:SetPoint("TOPRIGHT", anchorTo, "TOPRIGHT", 0, 0)
|
||||
shadow.top:SetHeight(INNER_SHADOW_SIZE)
|
||||
shadow.top:SetTexture("Interface\\ChatFrame\\ChatFrameBackground")
|
||||
shadow.top:Hide()
|
||||
-- Bottom edge
|
||||
shadow.bottom = button:CreateTexture(nil, "ARTWORK", nil, 1)
|
||||
shadow.bottom:SetPoint("BOTTOMLEFT", anchorTo, "BOTTOMLEFT", 0, 0)
|
||||
shadow.bottom:SetPoint("BOTTOMRIGHT", anchorTo, "BOTTOMRIGHT", 0, 0)
|
||||
shadow.bottom:SetHeight(INNER_SHADOW_SIZE)
|
||||
shadow.bottom:SetTexture("Interface\\ChatFrame\\ChatFrameBackground")
|
||||
shadow.bottom:Hide()
|
||||
-- Left edge
|
||||
shadow.left = button:CreateTexture(nil, "ARTWORK", nil, 1)
|
||||
shadow.left:SetPoint("TOPLEFT", anchorTo, "TOPLEFT", 0, 0)
|
||||
shadow.left:SetPoint("BOTTOMLEFT", anchorTo, "BOTTOMLEFT", 0, 0)
|
||||
shadow.left:SetWidth(INNER_SHADOW_SIZE)
|
||||
shadow.left:SetTexture("Interface\\ChatFrame\\ChatFrameBackground")
|
||||
shadow.left:Hide()
|
||||
-- Right edge
|
||||
shadow.right = button:CreateTexture(nil, "ARTWORK", nil, 1)
|
||||
shadow.right:SetPoint("TOPRIGHT", anchorTo, "TOPRIGHT", 0, 0)
|
||||
shadow.right:SetPoint("BOTTOMRIGHT", anchorTo, "BOTTOMRIGHT", 0, 0)
|
||||
shadow.right:SetWidth(INNER_SHADOW_SIZE)
|
||||
shadow.right:SetTexture("Interface\\ChatFrame\\ChatFrameBackground")
|
||||
shadow.right:Hide()
|
||||
return shadow
|
||||
end
|
||||
|
||||
-- Show inner shadow with a given quality color
|
||||
local function ShowInnerShadow(shadow, r, g, b)
|
||||
if not shadow then return end
|
||||
local a = INNER_SHADOW_ALPHA
|
||||
shadow.top:SetGradientAlpha("VERTICAL", r, g, b, 0, r, g, b, a)
|
||||
shadow.top:Show()
|
||||
shadow.bottom:SetGradientAlpha("VERTICAL", r, g, b, a, r, g, b, 0)
|
||||
shadow.bottom:Show()
|
||||
shadow.left:SetGradientAlpha("HORIZONTAL", r, g, b, a, r, g, b, 0)
|
||||
shadow.left:Show()
|
||||
shadow.right:SetGradientAlpha("HORIZONTAL", r, g, b, 0, r, g, b, a)
|
||||
shadow.right:Show()
|
||||
end
|
||||
|
||||
-- Hide inner shadow
|
||||
local function HideInnerShadow(shadow)
|
||||
if not shadow then return end
|
||||
shadow.top:Hide()
|
||||
shadow.bottom:Hide()
|
||||
shadow.left:Hide()
|
||||
shadow.right:Hide()
|
||||
end
|
||||
|
||||
--=====================================================
|
||||
-- Junk Icon Pool (Baganator-inspired memory optimization)
|
||||
-- Uses frame pooling to avoid creating new frames per button
|
||||
@@ -400,6 +464,14 @@ function Guda_ItemButton_OnLoad(self)
|
||||
self.qualityBorder = backdrop
|
||||
end
|
||||
|
||||
-- Create inner shadow for quality color glow (anchored to icon texture)
|
||||
if not self.innerShadow then
|
||||
local iconTex = getglobal(self:GetName() .. "IconTexture")
|
||||
if iconTex then
|
||||
self.innerShadow = CreateInnerShadow(self, iconTex)
|
||||
end
|
||||
end
|
||||
|
||||
-- Create quest item border (golden, higher priority than quality border)
|
||||
if not self.questBorder then
|
||||
local questBackdrop = CreateFrame("Frame", nil, self)
|
||||
@@ -564,6 +636,7 @@ local function ResetButtonVisualState(self)
|
||||
if self.questBorder then self.questBorder:Hide() end
|
||||
if self.questIcon then self.questIcon:Hide() end
|
||||
if self.qualityBorder then self.qualityBorder:Hide() end
|
||||
HideInnerShadow(self.innerShadow)
|
||||
if self.unusableOverlay then self.unusableOverlay:Hide() end
|
||||
HideJunkIcon(self)
|
||||
|
||||
@@ -763,11 +836,13 @@ local function UpdateQualityBorder(self, itemQuality, itemLink, bagID, Utils)
|
||||
-- Special border for keyring items (cyan/blue)
|
||||
self.qualityBorder:SetBackdropBorderColor(0.2, 0.8, 1.0, 1)
|
||||
self.qualityBorder:Show()
|
||||
ShowInnerShadow(self.innerShadow, 0.2, 0.8, 1.0)
|
||||
return
|
||||
end
|
||||
|
||||
if not itemQuality then
|
||||
self.qualityBorder:Hide()
|
||||
HideInnerShadow(self.innerShadow)
|
||||
return
|
||||
end
|
||||
|
||||
@@ -796,8 +871,10 @@ local function UpdateQualityBorder(self, itemQuality, itemLink, bagID, Utils)
|
||||
end
|
||||
self.qualityBorder:SetBackdropBorderColor(r, g, b, 1)
|
||||
self.qualityBorder:Show()
|
||||
ShowInnerShadow(self.innerShadow, r, g, b)
|
||||
else
|
||||
self.qualityBorder:Hide()
|
||||
HideInnerShadow(self.innerShadow)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -852,8 +929,10 @@ local function ClearItemButton(self, emptySlotBg, countText, bagID)
|
||||
if bagID == -2 then
|
||||
self.qualityBorder:SetBackdropBorderColor(0.2, 0.8, 1.0, 0.5)
|
||||
self.qualityBorder:Show()
|
||||
ShowInnerShadow(self.innerShadow, 0.2, 0.8, 1.0)
|
||||
else
|
||||
self.qualityBorder:Hide()
|
||||
HideInnerShadow(self.innerShadow)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1176,12 +1255,13 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha
|
||||
countText:Hide()
|
||||
end
|
||||
|
||||
-- Set quality border
|
||||
-- Set quality border and inner shadow
|
||||
if self.qualityBorder then
|
||||
if bagID == -2 then
|
||||
-- Special border for keyring items (cyan/blue)
|
||||
self.qualityBorder:SetBackdropBorderColor(0.2, 0.8, 1.0, 1)
|
||||
self.qualityBorder:Show()
|
||||
ShowInnerShadow(self.innerShadow, 0.2, 0.8, 1.0)
|
||||
elseif itemQuality then
|
||||
-- Check settings to determine if we should show borders
|
||||
local showEquipmentBorder, showOtherBorder
|
||||
@@ -1215,11 +1295,14 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha
|
||||
end
|
||||
self.qualityBorder:SetBackdropBorderColor(r, g, b, 1)
|
||||
self.qualityBorder:Show()
|
||||
ShowInnerShadow(self.innerShadow, r, g, b)
|
||||
else
|
||||
self.qualityBorder:Hide()
|
||||
HideInnerShadow(self.innerShadow)
|
||||
end
|
||||
else
|
||||
self.qualityBorder:Hide()
|
||||
HideInnerShadow(self.innerShadow)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1283,8 +1366,10 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha
|
||||
if bagID == -2 then
|
||||
self.qualityBorder:SetBackdropBorderColor(0.2, 0.8, 1.0, 0.5) -- Dimmer cyan for empty slots
|
||||
self.qualityBorder:Show()
|
||||
ShowInnerShadow(self.innerShadow, 0.2, 0.8, 1.0)
|
||||
else
|
||||
self.qualityBorder:Hide()
|
||||
HideInnerShadow(self.innerShadow)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1490,6 +1575,33 @@ function Guda_ItemButton_OnEnter(self)
|
||||
|
||||
GameTooltip:Show()
|
||||
|
||||
-- Debug: print item classification info to chat when debug mode is active
|
||||
if addon.DEBUG and self.hasItem and self.bagID and self.slotID and not self._debugPrinted then
|
||||
local link = self.itemData and self.itemData.link or GetContainerItemLink(self.bagID, self.slotID)
|
||||
if link then
|
||||
local itemID = addon.Modules.Utils:ExtractItemID(link)
|
||||
if itemID then
|
||||
local itemName, _, itemRarity, itemLevel, itemCategory, itemType, _, itemSubType = GetItemInfo(itemID)
|
||||
addon:Debug("Item: %s (ID: %s)", tostring(itemName), tostring(itemID))
|
||||
addon:Debug(" Category: %s | Type: %s | SubType: %s", tostring(itemCategory), tostring(itemType), tostring(itemSubType))
|
||||
addon:Debug(" Quality: %s | iLvl: %s", tostring(itemRarity), tostring(itemLevel))
|
||||
if addon.Modules.ItemDetection then
|
||||
local props = addon.Modules.ItemDetection:GetItemProperties({link = link}, self.bagID, self.slotID)
|
||||
local flags = {}
|
||||
if props.isQuestItem then table.insert(flags, "Quest") end
|
||||
if props.isQuestStarter then table.insert(flags, "Starter") end
|
||||
if props.isQuestUsable then table.insert(flags, "Usable") end
|
||||
if props.isJunk then table.insert(flags, "Junk") end
|
||||
if props.isPermanentEnchant then table.insert(flags, "Enchant") end
|
||||
if props.isUnusable then table.insert(flags, "Unusable") end
|
||||
local flagStr = table.getn(flags) > 0 and table.concat(flags, ", ") or "none"
|
||||
addon:Debug(" Flags: %s", flagStr)
|
||||
end
|
||||
self._debugPrinted = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Handle merchant sell cursor (same approach as BagShui)
|
||||
if MerchantFrame:IsShown() and not self.isBank and not self.otherChar and self.hasItem then
|
||||
ShowContainerSellCursor(self.bagID, self.slotID)
|
||||
@@ -1501,6 +1613,7 @@ end
|
||||
|
||||
-- OnLeave handler
|
||||
function Guda_ItemButton_OnLeave(self)
|
||||
self._debugPrinted = nil
|
||||
-- Clear any viewed character hint on the tooltip when leaving
|
||||
if GameTooltip then
|
||||
GameTooltip.GudaViewedCharacter = nil
|
||||
|
||||
@@ -30,7 +30,6 @@ function TrackedItemBar:ScanForTrackedItems()
|
||||
local itemOrder = {}
|
||||
local itemIsQuest = {}
|
||||
local itemIsQuestStarter = {}
|
||||
local itemQualities = {}
|
||||
|
||||
-- Scan backpack and 4 bags
|
||||
for bagID = 0, 4 do
|
||||
@@ -51,9 +50,6 @@ function TrackedItemBar:ScanForTrackedItems()
|
||||
local isQuest, isStarter = IsQuestItem(bagID, slotID)
|
||||
itemIsQuest[id] = isQuest
|
||||
itemIsQuestStarter[id] = isStarter
|
||||
-- Get item quality
|
||||
local _, _, itemQuality = GetItemInfo(id)
|
||||
itemQualities[id] = tonumber(itemQuality)
|
||||
table.insert(itemOrder, id)
|
||||
end
|
||||
itemCounts[id] = itemCounts[id] + count
|
||||
@@ -88,7 +84,6 @@ function TrackedItemBar:ScanForTrackedItems()
|
||||
isQuestStarter = itemIsQuestStarter[id],
|
||||
isUnusable = isUnusable,
|
||||
isJunk = isJunk,
|
||||
quality = itemQualities[id],
|
||||
})
|
||||
end
|
||||
end
|
||||
@@ -112,7 +107,6 @@ function TrackedItemBar:Update()
|
||||
-- Hide all buttons and their overlays initially
|
||||
for _, btn in ipairs(buttons) do
|
||||
btn:Hide()
|
||||
if btn.qualityBorder then btn.qualityBorder:Hide() end
|
||||
if btn.unusableOverlay then btn.unusableOverlay:Hide() end
|
||||
if btn.junkIcon then btn.junkIcon:Hide() end
|
||||
end
|
||||
@@ -136,19 +130,6 @@ function TrackedItemBar:Update()
|
||||
questBorder:Hide()
|
||||
button.questBorder = questBorder
|
||||
|
||||
-- Create quality border (colored by rarity)
|
||||
local qualityBorder = CreateFrame("Frame", nil, button)
|
||||
qualityBorder:SetFrameLevel(button:GetFrameLevel() + 5)
|
||||
qualityBorder:SetBackdrop({
|
||||
bgFile = nil,
|
||||
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
||||
edgeSize = 12,
|
||||
insets = {left = 4, right = 4, top = 4, bottom = 4}
|
||||
})
|
||||
qualityBorder:SetBackdropBorderColor(0, 0, 0, 0)
|
||||
qualityBorder:Hide()
|
||||
button.qualityBorder = qualityBorder
|
||||
|
||||
-- Create quest icon (question mark in corner)
|
||||
local questIcon = CreateFrame("Frame", nil, button)
|
||||
questIcon:SetFrameLevel(button:GetFrameLevel() + 7)
|
||||
@@ -258,23 +239,6 @@ function TrackedItemBar:Update()
|
||||
emptyBg:SetHeight(buttonSize)
|
||||
end
|
||||
|
||||
-- Position and show/hide quality border
|
||||
if button.qualityBorder then
|
||||
button.qualityBorder:ClearAllPoints()
|
||||
button.qualityBorder:SetPoint("TOPLEFT", icon, "TOPLEFT", -5, 5)
|
||||
button.qualityBorder:SetPoint("BOTTOMRIGHT", icon, "BOTTOMRIGHT", 5, -5)
|
||||
if info.quality and info.quality >= 1 then
|
||||
local r, g, b = 1, 1, 1
|
||||
if addon.Modules.Utils and addon.Modules.Utils.GetQualityColor then
|
||||
r, g, b = addon.Modules.Utils:GetQualityColor(info.quality)
|
||||
end
|
||||
button.qualityBorder:SetBackdropBorderColor(r, g, b, 1)
|
||||
button.qualityBorder:Show()
|
||||
else
|
||||
button.qualityBorder:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
-- Position and show/hide quest border
|
||||
if button.questBorder then
|
||||
button.questBorder:ClearAllPoints()
|
||||
|
||||
Reference in New Issue
Block a user