permanently enchant items

This commit is contained in:
Salikh Gurgenidze
2026-01-23 23:35:26 +04:00
parent 122ee5992e
commit 9590bcd676
4 changed files with 154 additions and 16 deletions
+44 -1
View File
@@ -732,6 +732,34 @@ local function ScanTooltipForQuest(tooltip, tooltipName)
return isQuestItem, isQuestStarter
end
-- Check if item has "Permanently..." text (enchanting scrolls/vellums)
-- These should NOT be considered quest items even if they have Quest category
local function IsPermanentEnchantItem(tooltip, tooltipName)
if not tooltip then
addon:Debug("IsPermanentEnchantItem: tooltip is nil")
return false
end
local numLines = tooltip:NumLines() or 0
addon:Debug("IsPermanentEnchantItem: scanning %d lines", numLines)
for i = 1, numLines do
local line = getglobal(tooltipName .. "TextLeft" .. i)
if line then
local text = line:GetText()
if text then
local tl = string.lower(text)
addon:Debug("IsPermanentEnchantItem line %d: %s", i, tl)
-- Just check for "permanently" anywhere (green text doesn't have "Use:" prefix)
if string.find(tl, "permanently") then
addon:Debug("IsPermanentEnchantItem: FOUND permanently!")
return true
end
end
end
end
addon:Debug("IsPermanentEnchantItem: NOT found")
return false
end
-- Consolidated quest item detection function
-- Handles tooltip scanning, category checks, equipment filtering, and QuestItemsDB lookup
-- Parameters:
@@ -772,8 +800,23 @@ function Utils:IsQuestItem(bagID, slotID, itemData, isOtherChar, isBank)
itemType == "Weapon" or itemType == "Armor")
local isQuestCategory = (itemCategory == "Quest" or itemType == "Quest")
-- Priority 1: If explicitly categorized as Quest, it's a quest item
-- Priority 1: If explicitly categorized as Quest, check if it's actually an enchant item first
if isQuestCategory then
addon:Debug("IsQuestItem: Quest category detected, checking for permanent enchant...")
-- Check tooltip for "Permanently" (enchanting scrolls should not be quest items)
if not isOtherChar and bagID and slotID then
local tooltip = GetScanTooltip()
tooltip:ClearLines()
tooltip:SetBagItem(bagID, slotID)
local isPermanent = IsPermanentEnchantItem(tooltip, "GudaBagScanTooltip")
addon:Debug("IsQuestItem: IsPermanentEnchantItem returned %s", tostring(isPermanent))
if isPermanent then
return false, false -- Not a quest item, it's an enchant scroll
end
else
addon:Debug("IsQuestItem: Skipping permanent enchant check (otherChar=%s, bagID=%s, slotID=%s)",
tostring(isOtherChar), tostring(bagID), tostring(slotID))
end
return true, false
end
+78 -15
View File
@@ -130,19 +130,27 @@ end
local function GetItemProperties(bagID, slotID, itemLink)
if not itemLink then return nil end
-- Extract base item link for stable caching (item:ID:Enchant:...)
local _, _, baseLink = string.find(itemLink, "(item:%d+:%d+:%d+:%d+:%d+:%d+:%d+:%d+)")
local cacheKey = baseLink or itemLink
if propertyCache[cacheKey] then
if addon.DEBUG then
addon:Print("GetItemProperties CACHE HIT for %s", cacheKey or "unknown")
end
return propertyCache[cacheKey]
end
if addon.DEBUG then
addon:Print("GetItemProperties CACHE MISS - scanning bagID=%s slotID=%s", tostring(bagID), tostring(slotID))
end
local props = {
isQuest = false,
isQuestStarter = false,
isQuestUsable = false,
isPermanentEnchant = false, -- "Use: Permanently adds" items
isGray = false,
restoreTag = nil
}
@@ -182,13 +190,22 @@ local function GetItemProperties(bagID, slotID, itemLink)
end
-- Usable check
if string.find(tl, "use:") or
string.find(tl, "right%-click") or
string.find(tl, "right click") or
if string.find(tl, "use:") or
string.find(tl, "right%-click") or
string.find(tl, "right click") or
string.find(tl, "click to") then
props.isQuestUsable = true
end
-- Permanent enchant check (scrolls with "Permanently...")
-- Check for "permanently" anywhere in the line (green text doesn't have "Use:" prefix)
if string.find(tl, "permanently") then
props.isPermanentEnchant = true
if addon.DEBUG then
addon:Print("Detected permanent enchant: %s", tl)
end
end
-- Restore tag check (higher priority tags override lower ones)
if string.find(tl, "while eating") then
props.restoreTag = "eat"
@@ -212,6 +229,10 @@ local function GetItemProperties(bagID, slotID, itemLink)
end
end
if addon.DEBUG and props.isPermanentEnchant then
addon:Print("GetItemProperties RETURNING isPermanentEnchant=true for %s", cacheKey or "unknown")
end
propertyCache[cacheKey] = props
return props
end
@@ -670,9 +691,29 @@ local function AddSortKeys(items)
item.equipSlotOrder = EQUIP_SLOT_ORDER[itemSubType] or 999
else
item.sortedClass = CATEGORY_ORDER[itemCategory] or 99
-- Check if item is a permanent enchant (should NOT be Quest)
local itemProps = GetItemProperties(item.bagID, item.slot, item.data.link)
local isPermanentEnchant = itemProps and itemProps.isPermanentEnchant or false
-- Debug: trace isPermanentEnchant value
if addon.DEBUG and (itemCategory == "Quest" or itemType == "Quest") then
addon:Print("GetItemProperties for %s: props=%s, isPermanentEnchant=%s",
item.itemName or "unknown",
itemProps and "exists" or "NIL",
itemProps and tostring(itemProps.isPermanentEnchant) or "N/A")
end
-- Permanent enchant items always sort BEFORE quest items (category 6)
-- regardless of their itemCategory or itemType
if isPermanentEnchant then
item.sortedClass = 6 -- Same as Tools, comes before Quest (7)
if addon.DEBUG then
addon:Print("PERMANENT ENCHANT: %s -> sortedClass=6", item.itemName or "unknown")
end
-- 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)
if item.sortedClass ~= (CATEGORY_ORDER["Quest"] or 7) then
elseif item.sortedClass ~= (CATEGORY_ORDER["Quest"] or 7) then
local nameLower = string.lower(item.itemName)
if string.find(nameLower, "manual") or string.find(nameLower, "quest") then
item.sortedClass = CATEGORY_ORDER["Quest"] or 7
@@ -687,6 +728,12 @@ local function AddSortKeys(items)
end
end
item.equipSlotOrder = 999
-- Debug: Show final sortedClass for quest-related items
if addon.DEBUG and (itemCategory == "Quest" or itemType == "Quest" or isPermanentEnchant) then
addon:Print("SORT CLASS: %s -> sortedClass=%d, isPermanentEnchant=%s",
item.itemName or "unknown", item.sortedClass, tostring(isPermanentEnchant))
end
end
-- Subclass ordering
@@ -704,19 +751,23 @@ local function AddSortKeys(items)
item.subclass = itemSubType or ""
-- Quest flags: mark quest items and detect starter/usable states
-- Note: permanent enchant items should NOT be marked as quest items
item.isQuest = false
item.isQuestStarter = false
item.isQuestUsable = false
item.isPermanentEnchant = isPermanentEnchant -- Store for potential use in sorting
local nameLower = string.lower(item.itemName)
if itemCategory == "Quest" or string.find(nameLower, "quest") or item.data.class == "Quest" or IsQuestItemTooltip(item.bagID, item.slot) then
item.isQuest = true
if IsQuestItemStarter(item.bagID, item.slot) then item.isQuestStarter = true end
if IsQuestItemUsable(item.bagID, item.slot) then item.isQuestUsable = true end
elseif addon.IsQuestItemByID then
-- Check QuestItemsDB for faction-specific quest items
local playerFaction = UnitFactionGroup("player")
if addon:IsQuestItemByID(itemID, playerFaction) then
if not isPermanentEnchant then
if itemCategory == "Quest" or string.find(nameLower, "quest") or item.data.class == "Quest" or IsQuestItemTooltip(item.bagID, item.slot) then
item.isQuest = true
if IsQuestItemStarter(item.bagID, item.slot) then item.isQuestStarter = true end
if IsQuestItemUsable(item.bagID, item.slot) then item.isQuestUsable = true end
elseif addon.IsQuestItemByID then
-- Check QuestItemsDB for faction-specific quest items
local playerFaction = UnitFactionGroup("player")
if addon:IsQuestItemByID(itemID, playerFaction) then
item.isQuest = true
end
end
end
@@ -1292,6 +1343,9 @@ end
-- Execute exactly ONE full sorting pass over bags (used by safety wrapper)
function SortEngine:SortBagsPass()
-- Clear property cache to ensure fresh detection
propertyCache = {}
local bagIDs = addon.Constants.BAGS
-- Phase 1: Detect specialized bags
@@ -1346,6 +1400,9 @@ function SortEngine:SortBagsPass()
end
function SortEngine:SortBags()
-- Clear property cache to ensure fresh detection
propertyCache = {}
local bagIDs = addon.Constants.BAGS
-- Phase 1: Detect specialized bags
@@ -1412,6 +1469,9 @@ end
-- Execute exactly ONE full sorting pass over bank (used by safety wrapper)
function SortEngine:SortBankPass()
-- Clear property cache to ensure fresh detection
propertyCache = {}
if not addon.Modules.BankScanner:IsBankOpen() then
addon:Print("Bank must be open to sort!")
return 0
@@ -1468,6 +1528,9 @@ function SortEngine:SortBankPass()
end
function SortEngine:SortBank()
-- Clear property cache to ensure fresh detection
propertyCache = {}
if not addon.Modules.BankScanner:IsBankOpen() then
addon:Print("Bank must be open to sort!")
return 0
+21
View File
@@ -1338,6 +1338,27 @@ function Guda_ItemButton_OnEnter(self)
GameTooltip:Show()
-- Debug: Print item info including equipSlot when debug mode is enabled
if addon.DEBUG and self.hasItem and self.bagID and self.slotID then
local link = GetContainerItemLink(self.bagID, self.slotID)
if link then
local itemID = addon.Modules.Utils:ExtractItemID(link)
if itemID then
local name, _, itemQuality, iLevel, itemCategory, itemType, itemStackCount, itemSubType, itemTexture, itemEquipLoc, itemSellPrice = GetItemInfo(itemID)
addon:Print("=== Item Debug Info ===")
addon:Print("name: %s", tostring(name))
addon:Print("itemQuality: %s", tostring(itemQuality))
addon:Print("iLevel: %s", tostring(iLevel))
addon:Print("itemCategory: %s", tostring(itemCategory))
addon:Print("itemType: %s", tostring(itemType))
addon:Print("itemStackCount: %s", tostring(itemStackCount))
addon:Print("itemSubType: %s", tostring(itemSubType))
addon:Print("itemTexture: %s", tostring(itemTexture))
addon:Print("itemEquipLoc: %s", tostring(itemEquipLoc))
addon:Print("itemSellPrice: %s", tostring(itemSellPrice))
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)
+11
View File
@@ -36,6 +36,7 @@ function QuestItemBar:CheckQuestItemUsable(bagID, slotID)
local isQuestItem = false
local isQuestStarter = false
local isUsable = false
local isPermanentEnchant = false -- Track enchanting scrolls/vellums
for i = 1, tooltip:NumLines() do
local line = getglobal("Guda_QuestBarScanTooltipTextLeft" .. i)
@@ -57,10 +58,20 @@ function QuestItemBar:CheckQuestItemUsable(bagID, slotID)
if string.find(tl, "use:") or string.find(tl, "begins a quest") or string.find(tl, "starts a quest") then
isUsable = true
end
-- Check for permanent enchant items (should NOT be quest items)
-- Just check for "permanently" anywhere (green text doesn't have "Use:" prefix)
if string.find(tl, "permanently") then
isPermanentEnchant = true
end
end
end
end
-- Permanent enchant items are NOT quest items, even if categorized as Quest
if isPermanentEnchant then
return false, false, false
end
-- Fallback check for quest category if not detected from tooltip
local link = GetContainerItemLink(bagID, slotID)
local itemID