local MAJOR , MINOR = " LibItemUpgradeInfo-1.0 " , 30
local type , tonumber , select , strsplit , GetItemInfoFromHyperlink = type , tonumber , select , strsplit , GetItemInfoFromHyperlink
local unpack , GetDetailedItemLevelInfo = unpack , GetDetailedItemLevelInfo
local library , previous = _G.LibStub : NewLibrary ( MAJOR , MINOR )
local lib = library --#lib Needed to keep Eclipse LDT happy
if not lib then return end
local pp = print
--[===[@debug@
LoadAddOn ( " Blizzard_DebugTools " )
LoadAddOn ( " LibDebug " )
if LibDebug then LibDebug ( ) end
--@end-debug@]===]
--@non-debug@
local print = function ( ) end
--@end-non-debug@
--[[
Caching system
1 itemName String The name of the item .
2 itemLink String The item link of the item .
3 itemRarity Number The quality of the item . The value is 0 to 7 , which represents Poor to Heirloom . This appears to include gains from upgrades / bonuses .
4 itemLevel Number The item level of this item , not including item levels gained from upgrades . There is currently no API to get the item level including upgrades / bonuses .
5 itemMinLevel Number The minimum level required to use the item , 0 meaning no level requirement .
6 itemType String The type of the item : Armor , Weapon , Quest , Key , etc .
7 itemSubType String The sub - type of the item : Enchanting , Cloth , Sword , etc . See itemType .
8 itemStackCount Number How many of the item per stack : 20 for Runecloth , 1 for weapon , 100 for Alterac Ram Hide , etc .
9 itemEquipLoc String The type of inventory equipment location in which the item may be equipped , or " " if it can ' t be equippable. The string returned is also the name of a global string variable e.g. if "INVTYPE_WEAPONMAINHAND" is returned, _G["INVTYPE_WEAPONMAINHAND"] will be the localized, displayable name of the location.
10 iconFileDataID Number The FileDataID for the icon texture for the item .
11 itemSellPrice Number The price , in copper , a vendor is willing to pay for this item , 0 for items that cannot be sold .
12 itemClassID Number This is the numerical value that determines the string to display for ' itemType ' .
13 itemSubClassID Number This is the numerical value that determines the string to display for ' itemSubType '
14 bindType Number Item binding type : 0 - none ; 1 - on pickup ; 2 - on equip ; 3 - on use ; 4 - quest .
15 expacID Number
16 itemSetID Number
17 isCraftingReagent bool
--]]
-- ItemLink Constants
local i_Name = 1
local i_Link = 2
local i_Rarity = 3
local i_Quality = 3
local i_Level = 4
local i_MinLevel = 5
local i_ClassName = 6
local i_SubClassName = 7
local i_StackCount = 8
local i_EquipLoc = 9
local i_TextureId = 10
local i_SellPrice = 11
local i_ClassID = 12
local i_SubClass_ID = 13
local i_unk1 = 14
local i_unk2 = 15
local i_unk3 = 16
local i_unk4 = 17
do
local oGetItemInfo = GetItemInfo
lib.itemcache = lib.itemcache or
setmetatable ( { miss = 0 , tot = 0 } , {
__index = function ( table , key )
if ( not key ) then return " " end
if ( key == " miss " ) then return 0 end
if ( key == " tot " ) then return 0 end
local cached = { oGetItemInfo ( key ) }
if # cached == 0 then return nil end
local itemLink = cached [ 2 ]
if not itemLink then return nil end
local itemID = lib : GetItemID ( itemLink )
local quality = cached [ 3 ]
local cacheIt = true
if quality == LE_ITEM_QUALITY_ARTIFACT then
local relic1 , relic2 , relic3 = select ( 4 , strsplit ( ' : ' , itemLink ) )
if relic1 and relic1 ~= ' ' and not oGetItemInfo ( relic1 ) then cacheIt = false end
if relic2 and relic2 ~= ' ' and not oGetItemInfo ( relic2 ) then cacheIt = false end
if relic3 and relic3 ~= ' ' and not oGetItemInfo ( relic3 ) then cacheIt = false end
end
cached.englishClass = GetItemClassInfo ( cached [ 12 ] )
cached.englishSubClass = GetItemSubClassInfo ( cached [ 12 ] , cached [ 13 ] )
if cacheIt then
rawset ( table , key , cached )
end
table.miss = table.miss + 1
return cached
end
} )
end
local cache = lib.itemcache
local function CachedGetItemInfo ( key , index )
if not key then return nil end
index = index or 1
cache.tot = cache.tot + 1
local cached = cache [ key ]
if cached and type ( cached ) == ' table ' then
return select ( index , unpack ( cached ) )
else
rawset ( cache , key , nil ) -- voiding broken cache entry
end
end
local upgradeTable = {
[ 1 ] = { upgrade = 1 , max = 1 , ilevel = 8 } ,
[ 373 ] = { upgrade = 1 , max = 3 , ilevel = 4 } ,
[ 374 ] = { upgrade = 2 , max = 3 , ilevel = 8 } ,
[ 375 ] = { upgrade = 1 , max = 3 , ilevel = 4 } ,
[ 376 ] = { upgrade = 2 , max = 3 , ilevel = 4 } ,
[ 377 ] = { upgrade = 3 , max = 3 , ilevel = 4 } ,
[ 378 ] = { ilevel = 7 } ,
[ 379 ] = { upgrade = 1 , max = 2 , ilevel = 4 } ,
[ 380 ] = { upgrade = 2 , max = 2 , ilevel = 4 } ,
[ 445 ] = { upgrade = 0 , max = 2 , ilevel = 0 } ,
[ 446 ] = { upgrade = 1 , max = 2 , ilevel = 4 } ,
[ 447 ] = { upgrade = 2 , max = 2 , ilevel = 8 } ,
[ 451 ] = { upgrade = 0 , max = 1 , ilevel = 0 } ,
[ 452 ] = { upgrade = 1 , max = 1 , ilevel = 8 } ,
[ 453 ] = { upgrade = 0 , max = 2 , ilevel = 0 } ,
[ 454 ] = { upgrade = 1 , max = 2 , ilevel = 4 } ,
[ 455 ] = { upgrade = 2 , max = 2 , ilevel = 8 } ,
[ 456 ] = { upgrade = 0 , max = 1 , ilevel = 0 } ,
[ 457 ] = { upgrade = 1 , max = 1 , ilevel = 8 } ,
[ 458 ] = { upgrade = 0 , max = 4 , ilevel = 0 } ,
[ 459 ] = { upgrade = 1 , max = 4 , ilevel = 4 } ,
[ 460 ] = { upgrade = 2 , max = 4 , ilevel = 8 } ,
[ 461 ] = { upgrade = 3 , max = 4 , ilevel = 12 } ,
[ 462 ] = { upgrade = 4 , max = 4 , ilevel = 16 } ,
[ 465 ] = { upgrade = 0 , max = 2 , ilevel = 0 } ,
[ 466 ] = { upgrade = 1 , max = 2 , ilevel = 4 } ,
[ 467 ] = { upgrade = 2 , max = 2 , ilevel = 8 } ,
[ 468 ] = { upgrade = 0 , max = 4 , ilevel = 0 } ,
[ 469 ] = { upgrade = 1 , max = 4 , ilevel = 4 } ,
[ 470 ] = { upgrade = 2 , max = 4 , ilevel = 8 } ,
[ 471 ] = { upgrade = 3 , max = 4 , ilevel = 12 } ,
[ 472 ] = { upgrade = 4 , max = 4 , ilevel = 16 } ,
[ 491 ] = { upgrade = 0 , max = 4 , ilevel = 0 } ,
[ 492 ] = { upgrade = 1 , max = 4 , ilevel = 4 } ,
[ 493 ] = { upgrade = 2 , max = 4 , ilevel = 8 } ,
[ 494 ] = { upgrade = 0 , max = 6 , ilevel = 0 } ,
[ 495 ] = { upgrade = 1 , max = 6 , ilevel = 4 } ,
[ 496 ] = { upgrade = 2 , max = 6 , ilevel = 8 } ,
[ 497 ] = { upgrade = 3 , max = 6 , ilevel = 12 } ,
[ 498 ] = { upgrade = 4 , max = 6 , ilevel = 16 } ,
[ 503 ] = { upgrade = 3 , max = 3 , ilevel = 1 } ,
[ 504 ] = { upgrade = 3 , max = 4 , ilevel = 12 } ,
[ 505 ] = { upgrade = 4 , max = 4 , ilevel = 16 } ,
[ 506 ] = { upgrade = 5 , max = 6 , ilevel = 20 } ,
[ 507 ] = { upgrade = 6 , max = 6 , ilevel = 24 } ,
[ 529 ] = { upgrade = 0 , max = 2 , ilevel = 0 } ,
[ 530 ] = { upgrade = 1 , max = 2 , ilevel = 5 } ,
[ 531 ] = { upgrade = 2 , max = 2 , ilevel = 10 } ,
[ 535 ] = { upgrade = 1 , max = 3 , ilevel = 15 } ,
[ 536 ] = { upgrade = 2 , max = 3 , ilevel = 30 } ,
[ 537 ] = { upgrade = 3 , max = 3 , ilevel = 45 } ,
[ 538 ] = { upgrade = 0 , max = 3 , ilevel = 0 } ,
}
do
local stub = { ilevel = 0 }
setmetatable ( upgradeTable , { __index = function ( t , key )
return stub
end } )
end
-- Tooltip Scanning stuff
local itemLevelPattern = _G.ITEM_LEVEL : gsub ( " %%d " , " (%%d+) " )
local soulboundPattern = _G.ITEM_SOULBOUND
local boePattern = _G.ITEM_BIND_ON_EQUIP
local bopPattern = _G.ITEM_BIND_ON_PICKUP
local boaPattern1 = _G.ITEM_BIND_TO_BNETACCOUNT
local boaPattern2 = _G.ITEM_BNETACCOUNTBOUND
local patterns = {
[ soulboundPattern ] = " soulbound " ,
[ boePattern ] = " boe " ,
[ bopPattern ] = " bop " ,
[ boaPattern1 ] = " boa " ,
[ boaPattern2 ] = " boa " ,
}
local scanningTooltip
local anchor
lib.tipCache = lib.tipCache or setmetatable ( { } , { __index = function ( table , key ) return { } end } )
local tipCache = lib.tipCache
local emptytable = { }
local function ScanTip ( itemLink , itemLevel , show )
if type ( itemLink ) == " number " then
itemLink = CachedGetItemInfo ( itemLink , 2 )
if not itemLink then return emptytable end
end
if type ( tipCache [ itemLink ] . ilevel ) == " nil " then -- or not tipCache[itemLink].cached then
local cacheIt = true
if not scanningTooltip then
anchor = CreateFrame ( " Frame " )
anchor : Hide ( )
scanningTooltip = _G.CreateFrame ( " GameTooltip " , " LibItemUpgradeInfoTooltip " , nil , " GameTooltipTemplate " )
end
--scanningTooltip:ClearLines()
GameTooltip_SetDefaultAnchor ( scanningTooltip , anchor )
local itemString = itemLink : match ( " |H(.-)|h " )
local rc , message = pcall ( scanningTooltip.SetHyperlink , scanningTooltip , itemString )
if ( not rc ) then
return emptytable
end
scanningTooltip : Show ( )
local quality , _ , _ , class , subclass , _ , _ , _ , _ , classIndex , subclassIndex = CachedGetItemInfo ( itemLink , 3 )
-- line 1 is the item name
-- line 2 may be the item level, or it may be a modifier like "Heroic"
-- check up to line 6 just in case
local ilevel , soulbound , bop , boe , boa , heirloom
if quality == LE_ITEM_QUALITY_ARTIFACT and itemLevel then
local relic1 , relic2 , relic3 = select ( 4 , strsplit ( ' : ' , itemLink ) )
if relic1 and relic1 ~= ' ' and not CachedGetItemInfo ( relic1 ) then cacheIt = false end
if relic2 and relic2 ~= ' ' and not CachedGetItemInfo ( relic2 ) then cacheIt = false end
if relic3 and relic3 ~= ' ' and not CachedGetItemInfo ( relic3 ) then cacheIt = false end
ilevel = itemLevel
end
if show then
for i = 1 , 12 do
local l , ltext = _G [ " LibItemUpgradeInfoTooltipTextLeft " .. i ] , nil
local r , rtext = _G [ " LibItemUpgradeInfoTooltipTextRight " .. i ] , nil
if l then
ltext = l : GetText ( )
rtext = r : GetText ( )
_G.print ( i , ltext , ' - ' , rtext )
end
end
end
tipCache [ itemLink ] = {
ilevel = nil ,
soulbound = nil ,
bop = nil ,
boe = nil ,
boa = nil ,
cached = cacheIt
}
local c = tipCache [ itemLink ]
for i = 2 , 6 do
local label , text = _G [ " LibItemUpgradeInfoTooltipTextLeft " .. i ] , nil
if label then text = label : GetText ( ) end
if text then
if show then _G.print ( " |cFFFFFF00 " .. text .. " |r " ) end
if c.ilevel == nil then c.ilevel = tonumber ( text : match ( itemLevelPattern ) ) end
for pattern , key in pairs ( patterns ) do
if type ( c [ key ] ) == " nil " then
if text : find ( pattern ) then
if show then _G.print ( text , " matched " , pattern ) end
c [ key ] = true
end
end
end
end
end
c.ilevel = c.ilevel or itemLevel
itemLevel = GetDetailedItemLevelInfo ( itemLink )
if type ( c.ilevel ) == " number " then
c.ilevel = math.max ( c.ilevel , itemLevel )
else
c.ilevel = itemLevel
end
scanningTooltip : Hide ( )
end
return tipCache [ itemLink ]
end
-- GetUpgradeID(itemString)
--
-- Arguments:
-- itemString - String - An itemLink or itemString denoting the item
--
-- Returns:
-- Number - The upgrade ID (possibly 0), or nil if the input is invalid or
-- does not contain upgrade info
function lib : GetUpgradeID ( itemString )
if type ( itemString ) ~= " string " then return end
local itemString = itemString : match ( " item[%-?%d:]+ " ) or " " -- Standardize itemlink to itemstring
local instaid , _ , numBonuses , affixes = select ( 12 , strsplit ( " : " , itemString , 15 ) )
instaid = tonumber ( instaid ) or 7
numBonuses = tonumber ( numBonuses ) or 0
if instaid > 0 and ( instaid - 4 ) % 8 == 0 then
return tonumber ( ( select ( numBonuses + 1 , strsplit ( " : " , affixes ) ) ) )
end
end
-- GetCurrentUpgrade(id)
--
-- Returns the current upgrade level of the item, e.g. 1 for a 1/2 item.
--
-- Arguments:
-- id - Number - The upgrade ID of the item (obtained via GetUpgradeID())
--
-- Returns:
-- Number - The current upgrade level of the item. Returns nil if the item
-- cannot be upgraded
function lib : GetCurrentUpgrade ( id )
return upgradeTable [ id ] . upgrade
end
-- GetMaximumUpgrade(id)
--
-- Returns the maximum upgrade level of the item, e.g. 2 for a 1/2 item.
--
-- Arguments:
-- id - Number - The upgrade ID of the item (obtained via GetUpgradeID())
--
-- Returns:
-- Number - The maximum upgrade level of the item. Returns nil if the item
-- cannot be upgraded
function lib : GetMaximumUpgrade ( id )
return upgradeTable [ id ] . max
end
-- GetItemLevelUpgrade(id)
--
-- Returns the item level increase that this upgrade is worth, e.g. 4 for a
-- 1/2 item or 8 for a 2/2 item.
--
-- Arguments:
-- id - Number - The upgrade ID of the item (obtained via GetUpgradeID())
--
-- Returns:
-- Number - The item level increase of the item. Returns 0 if the item
-- cannot be or has not been upgraded
function lib : GetItemLevelUpgrade ( id )
return upgradeTable [ id ] . ilevel
end
-- GetItemUpgradeInfo(itemString)
--
-- Returns the current upgrade level, maximum upgrade level, and item level
-- increase for an item.
--
-- Arguments:
-- itemString - String - An itemLink or itemString denoting the item
--
-- Returns if the item can be upgraded:
-- Number - The current upgrade level of the item
-- Number - The maximum upgrade level of the item
-- Number - The item level increase of the item
-- or if the item cannot be upgraded:
-- nil
-- nil
-- 0
-- or if the item is invalid or does not contain upgrade info:
-- nil
function lib : GetItemUpgradeInfo ( itemString )
local id = self : GetUpgradeID ( itemString )
if id then
local cur = self : GetCurrentUpgrade ( id )
local max = self : GetMaximumUpgrade ( id )
local delta = self : GetItemLevelUpgrade ( id )
return cur , max , delta
end
return nil
end
-- GetHeirloomTrueLevel(itemString)
--
-- Returns the true item level for an heirloom (actually, returns the true level for any adapting item)
--
-- Arguments:
-- itemString - String - An itemLink or itemString denoting the item
--
-- Returns:
-- Number, Boolean - The true item level of the item. If the item is not
-- an heirloom, or an error occurs when trying to scan the
-- item tooltip, the second return value is false. Otherwise
-- the second return value is true. If the input is invalid,
-- (nil, false) is returned.
-- Convert the ITEM_LEVEL constant into a pattern for our use
function lib : GetHeirloomTrueLevel ( itemString )
if type ( itemString ) ~= " string " then return nil , false end
local _ , itemLink , rarity , itemLevel = CachedGetItemInfo ( itemString )
if ( not itemLink ) then
return nil , false
end
local rc = ScanTip ( itemLink , itemLevel )
if rc.ilevel then
return rc.ilevel , true
end
return itemLevel , false
end
-- GetUpgradedItemLevel(itemString)
--
-- Returns the true item level of the item, including upgrades and heirlooms.
--
-- Arguments:
-- itemString - String - An itemLink or itemString denoting the item
--
-- Returns:
-- Number - The true item level of the item, or nil if the input is invalid
function lib : GetUpgradedItemLevel ( itemString )
-- check for heirlooms first
local ilvl , isTrue = self : GetHeirloomTrueLevel ( itemString )
if isTrue then
return ilvl
end
-- not an heirloom? fall back to the regular item logic
local id = self : GetUpgradeID ( itemString )
if ilvl and id then
ilvl = ilvl + self : GetItemLevelUpgrade ( id )
end
return ilvl
end
-- IsBop(itemString)
--
-- Check an item for Bind On Pickup.
--
-- Arguments:
-- itemString - String - An itemLink or itemString denoting the item
--
-- Returns:
-- Boolean - True if Bind On Pickup
function lib : IsBop ( itemString )
local rc = ScanTip ( itemString )
return rc.bop
end
-- IsBoe(itemString)
--
-- Check an item for Bind On Equip.
--
-- Arguments:
-- itemString - String - An itemLink or itemString denoting the item
--
-- Returns:
-- Boolean - True if Bind On Equip
function lib : IsBoe ( itemString )
local rc = ScanTip ( itemString )
return rc.boe
end
-- IsBoa(itemString)
--
-- Check an item for Bind On Aaccount
--
-- Arguments:
-- itemString - String - An itemLink or itemString denoting the item
--
-- Returns:
-- Boolean - True if Bind On Equip
function lib : IsBoa ( itemString )
local rc = ScanTip ( itemString )
return rc.boa
end
-- IsArtifact(itemString)
--
-- Check an item for Heirloom
--
-- Arguments:
-- itemString - String - An itemLink or itemString denoting the item
--
-- Returns:
-- Boolean - True if Artifact
function lib : IsArtifact ( itemString )
return CachedGetItemInfo ( itemString , i_Quality ) == LE_ITEM_QUALITY_ARTIFACT
end
-- GetClassInfoIsHeirloom(itemString)
--
-- Retrieve class and subclass
--
-- Arguments:
-- itemString - String - An itemLink or itemString denoting the item
--
-- Returns:
-- class,subclass
function lib : GetClassInfo ( itemString )
local rc = ScantTip ( itemString )
return rc.class , rc.subclass
end
-- IsHeirloom(itemString)
--
-- Check an item for Heirloom
--
-- Arguments:
-- itemString - String - An itemLink or itemString denoting the item
--
-- Returns:
-- Boolean - True if Heirloom
function lib : IsHeirloom ( itemString )
return CachedGetItemInfo ( itemString , i_Quality ) == LE_ITEM_QUALITY_HEIRLOOM
end
---
-- Parses an itemlink and returns itemId without calling API again
-- @param #lib self
-- @param #string itemlink
-- @return #number itemId or 0
function lib : GetItemID ( itemlink )
if ( type ( itemlink ) == " string " ) then
local itemid , context = GetItemInfoFromHyperlink ( itemlink )
return tonumber ( itemid ) or 0
--return tonumber(itemlink:match("Hitem:(%d+):")) or 0
else
return 0
end
end
---
--
-- Returns a caching version of GetItemInfo. Can be used to override the original one.
-- Adds a second parameter to directly retrieving a specific value
-- (Note: internally uses select so it's actually like calling select(n,GetItemInfo(itemID))
--
-- Arguments:
-- self #lib self
--
-- Returns:
-- #function The new function
--@do-not-package--
local slots = {
INVSLOT_AMMO = INVSLOT_AMMO ,
INVSLOT_HEAD = INVSLOT_HEAD ,
INVSLOT_NECK = INVSLOT_NECK ,
INVSLOT_SHOULDER = INVSLOT_SHOULDER ,
INVSLOT_BODY = INVSLOT_BODY ,
INVSLOT_CHEST = INVSLOT_CHEST ,
INVSLOT_WAIST = INVSLOT_WAIST ,
INVSLOT_LEGS = INVSLOT_LEGS ,
INVSLOT_FEET = INVSLOT_FEET ,
INVSLOT_WRIST = INVSLOT_WRIST ,
INVSLOT_HAND = INVSLOT_HAND ,
INVSLOT_FINGER1 = INVSLOT_FINGER1 ,
INVSLOT_FINGER2 = INVSLOT_FINGER2 ,
INVSLOT_TRINKET1 = INVSLOT_TRINKET1 ,
INVSLOT_TRINKET2 = INVSLOT_TRINKET2 ,
INVSLOT_BACK = INVSLOT_BACK ,
INVSLOT_MAINHAND = INVSLOT_MAINHAND ,
INVSLOT_OFFHAND = INVSLOT_OFFHAND ,
INVSLOT_RANGED = INVSLOT_RANGED ,
INVSLOT_TABARD = INVSLOT_TABARD ,
}
local INVSLOT_FIRST_EQUIPPED = INVSLOT_FIRST_EQUIPPED ;
local INVSLOT_LAST_EQUIPPED = INVSLOT_LAST_EQUIPPED
_G.SLASH_CHECKSLOT1 = " /checkslot "
SlashCmdList [ ' CHECKSLOT ' ] = function ( args , chatframe )
_G.print ( args )
local slot = strsplit ( ' ' , args )
if not slot or slot == " " then
DevTools_Dump ( slots )
return
end
slot = tonumber ( slot )
local itemlink = GetInventoryItemLink ( " player " , slot )
if itemlink then
for k , v in pairs ( slots ) do
if slot == v then _G.print ( " Item in " , k ) break end
end
_G.print ( itemlink )
DevTools_Dump ( { GetDetailedItemLevelInfo ( itemlink ) } )
print ( itemlink )
_G.print ( lib : ScanTip ( itemlink ) )
end
end
function lib : ScanTip ( itemLink )
--self.itemcache[itemLink]=nil
self.tipCache [ itemLink ] = nil
local GameTooltip = _G.LibItemUpgradeInfoTooltip
if GameTooltip then
GameTooltip_SetDefaultAnchor ( GameTooltip , UIParent )
GameTooltip : SetHyperlink ( itemLink )
GameTooltip : Show ( )
end
return ScanTip ( itemLink , 100 , true )
end
function lib : GetCachingGetItemInfo ( )
return CachedGetItemInfo
end
function lib : GetCacheStats ( )
local c = lib.itemcache
local h = c.tot - c.miss
local perc = ( h > 0 ) and h / c.tot * 100 or 0
return c.miss , h , perc
end
function lib : GetCache ( )
return lib.itemcache
end
function lib : CleanCache ( )
return wipe ( lib.itemcache )
end
--[===========[ ]===========]
--[===[ Debug utilities ]===]
--[===========[ ]===========]
local function compareTables ( t1 , t2 )
local seen = { }
for k , v1 in pairs ( t1 ) do
seen [ k ] = true
local v2 = rawget ( t2 , k )
if not v2 then return false end
if type ( v1 ) ~= type ( v2 ) then return false end
if type ( v1 ) == " table " then
if not compareTables ( v1 , v2 ) then return false end
elseif v1 ~= v2 then return false end
end
for k in pairs ( t2 ) do
if not seen [ k ] then return false end
end
return true
end
-- prints the table rows in red and green
-- omits the lead { and the trailing }
local function printDiffTable ( t1 , t2 )
local keys , seen = { } , { }
for k in pairs ( t1 ) do
keys [ # keys + 1 ] = k
seen [ k ] = true
end
for k in pairs ( t2 ) do
if not seen [ k ] then
keys [ # keys + 1 ] = k
end
end
table.sort ( keys )
local function formatTable ( t )
local comps = { }
for k , v in pairs ( t ) do
comps [ # comps + 1 ] = ( " %s = %d " ) : format ( k , v )
end
return " { " .. table.concat ( comps , " , " ) .. " } "
end
for _ , k in ipairs ( keys ) do
local v1 , v2 = rawget ( t1 , k ) , rawget ( t2 , k )
local equal
if type ( v1 ) == " table " and type ( v2 ) == " table " then equal = compareTables ( v1 , v2 )
else equal = v1 == v2 end
if not equal then
if v1 then
pp ( ( " |cffff0000 [%d] = %s,|r " ) : format ( k , formatTable ( v1 ) ) )
end
if v2 then
pp ( ( " |cff00ff00 [%d] = %s,|r " ) : format ( k , formatTable ( v2 ) ) )
end
end
end
end
-- Scans the first 10000 upgrade IDs
-- Run this with /run LibStub:GetLibrary("LibItemUpgradeInfo-1.0"):_CheckUpgradeTable()
-- If you don't have Aspirant's Staff of Harmony cached it may error out, just try again.
do
local debugFrame
local worker
local newTable
local debugTooltip
function lib : _CheckUpgradeTable ( itemLink )
if worker then
pp ( " |cffff0000LibItemUpgradeInfo-1.0: upgrade check already in progress " )
return
end
if not debugFrame then
debugFrame = _G.CreateFrame ( " frame " )
debugFrame : Hide ( )
debugFrame : SetScript ( " OnUpdate " , function ( )
local ok , result , count , max = pcall ( worker )
if not ok or result then
debugFrame : Hide ( )
worker = nil
end
if not ok then
pp ( " |cffff0000LibItemUpgradeInfo-1.0 error: " .. result .. " |r " )
elseif result then
pp ( " LibItemUpgradeInfo-1.0: scan complete " )
if compareTables ( upgradeTable , newTable ) then
pp ( " LibItemUpgradeInfo-1.0: |cff00ff00No changes|r " )
else
pp ( " LibItemUpgradeInfo-1.0: |cffff0000New table:|r { " )
printDiffTable ( upgradeTable , newTable )
pp ( " } " )
end
else
pp ( " LibItemUpgradeInfo-1.0: scanning " .. count .. " / " .. max )
end
end )
end
if not debugTooltip then
debugTooltip = _G.CreateFrame ( " GameTooltip " , " LibItemUpgradeInfoDebugTooltip " , nil , " GameTooltipTemplate " )
debugTooltip : SetOwner ( _G.WorldFrame , " ANCHOR_NONE " )
end
newTable = { }
--local itemLink = "|cff0070dd|Hitem:89551:0:0:0:0:0:0:0:90:253:0:0:1:0|h[Aspirant's Staff of Harmony]|h|r"
local itemLink = itemLink or " |cff0070dd|Hitem:89551:0:0:0:0:0:0:0:100:253:4:0:0:0|h[Aspirant's Staff of Harmony]|h|r "
-- Livello è il 9,upgradeid il 14. Al decimo posto, un valore che deve essere 4 o 4+n *8) per far scattare l'uso dell'upgradeid
local itemLevel = select ( 4 , _G.GetItemInfo ( itemLink ) )
assert ( itemLevel , " Can't find item level for itemLink " )
local count , max , batchsize = 0 , 10000 , 200
worker = function ( )
for i = count , math.min ( max , count + batchsize ) do
local link = itemLink : gsub ( " %d+|h " , i .. " |h " )
debugTooltip : ClearLines ( )
debugTooltip : SetHyperlink ( link )
local upgrade , max
local curLevel , maxLevel = _G.LibItemUpgradeInfoDebugTooltipTextLeft3 : GetText ( ) : match ( " ^Upgrade Level: (%d+)/(%d+) " )
local ilvl = tonumber ( _G.LibItemUpgradeInfoDebugTooltipTextLeft2 : GetText ( ) : match ( " Item Level (%d+) " ) )
if not ilvl then
ilvl = tonumber ( _G.LibItemUpgradeInfoDebugTooltipTextLeft3 : GetText ( ) : match ( " Item Level (%d+) " ) )
end
assert ( ilvl ~= nil , " Can't find ItemLevel in tooltip: " .. _G.LibItemUpgradeInfoDebugTooltipTextLeft2 : GetText ( ) )
if curLevel or maxLevel or ilvl ~= itemLevel then
newTable [ i ] = { upgrade = tonumber ( curLevel ) , max = tonumber ( maxLevel ) , ilevel = ilvl - itemLevel }
end
end
count = count + batchsize
return ( count > max ) , count , max
end
debugFrame : Show ( )
end
end
--@end-do-not-package--
-- vim: set noet sw=4 ts=4: