local scaningID, scaningLink, scaningStack local scaningMoneyFound, scaningChargesFound, scaningDurabilityFound, scaningDurabilityMaxFound local scanningIsSoulboundFound local scanningIsUnsellableFound local scaningStatsModFound={} ItemDataCache.ScaningStatsModFound=scaningStatsModFound local scanStatsMod function ItemDataCache.OnTooltipAddMoney(self, money) -- if(scaningID==10446) then -- ItemDataCache.Chatback("Caught adding money. ID: "..scaningID.." StackSize: "..scaningStack.." Price: "..money.." PriceForOne: "..(money/scaningStack)) -- ItemDataCache.Chatback(debugstack()) -- end scaningMoneyFound=money/scaningStack end --[[ ARMOR_TEMPLATE = "%d Armor"; -- Item's armor display template DAMAGE_TEMPLATE = "%d - %d Damage"; -- Weapon damage template DAMAGE_TEMPLATE_WITH_SCHOOL = "%d - %d %s Damage"; DPS_TEMPLATE = "(%.1f damage per second)"; HP_TEMPLATE = "%d Health"; MAX_HP_TEMPLATE = "%d Max health"; PLUS_AMMO_DAMAGE_TEMPLATE = "+ %g damage per second"; PLUS_AMMO_SCHOOL_DAMAGE_TEMPLATE = "+ %g %s damage per second"; PLUS_DAMAGE_TEMPLATE = "+ %d - %d Damage"; PLUS_DAMAGE_TEMPLATE_WITH_SCHOOL = "+%d - %d %s Damage"; PLUS_SINGLE_DAMAGE_TEMPLATE = "+ %d Damage"; PLUS_SINGLE_DAMAGE_TEMPLATE_WITH_SCHOOL = "+%d %s Damage"; RESISTANCE_TEMPLATE = "%d %s"; SHIELD_BLOCK_TEMPLATE = "%d Block"; SINGLE_DAMAGE_TEMPLATE = "%d Damage"; SINGLE_DAMAGE_TEMPLATE_WITH_SCHOOL = "%d %s Damage"; -- Weapon damage template, for weapons doing school damage ITEM_MOD_HASTE_SPELL_RATING = "Improves spell haste rating by %d."; ITEM_MOD_HEALTH = "%c%d Health"; -- Item adds %d to health, %c is +/- ITEM_SOULBOUND ITEM_READABLE ITEM_UNIQUE ITEM_UNIQUE_EQUIPPABLE ITEM_UNIQUE_MULTIPLE ITEM_OPENABLE --]] local patternStatsMod={} ItemDataCache.PatternStatsMod=patternStatsMod local initPatternStatsModDone function ItemDataCache.InitStatModPatterns() for varName, varValue in pairs(_G) do local at, _, stat=strfind(varName, "^ITEM_MOD_(.+)") if(at) then -- %%.-d should catch %c%d too patternStatsMod[string.lower(stat)]=gsub(varValue, "%%.-d", "([+-]?%%d+)") -- ItemDataCache.Chatback(patternStatsMod[string.lower(stat)]) end end patternStatsMod.armor=gsub(ARMOR_TEMPLATE, "%%.-d", "(%%d+)") patternStatsMod.block=gsub(SHIELD_BLOCK_TEMPLATE, "%%.-d", "(%%d+)") initPatternStatsModDone = true end local patternItemSpellChargesP1=gsub(ITEM_SPELL_CHARGES_P1, "%%.-d", "(%%d+)") local patternItemSpellCharges=gsub(ITEM_SPELL_CHARGES, "%%.-d", "(%%d+)") local patternDurability=gsub(DURABILITY_TEMPLATE, "%%.-d", "(%%d+)") function ItemDataCache.ScanTooltip() scaningChargesFound=false scaningDurabilityFound=false scaningDurabilityMaxFound=false scanningIsSoulboundFound=false scanningIsUnsellableFound=false if(scanStatsMod or ItemDataCache.ScanStatsMod) then for stat, pattern in pairs(patternStatsMod) do scaningStatsModFound[stat]=nil end end for i=2, ItemDataCacheTooltip:NumLines(), 1 do local line=getglobal("ItemDataCacheTooltipTextLeft"..i):GetText() if (line) then -- Do something with one tooltip line -- ItemDataCache.Chatback(line) -- Check for "No sell price" if(line==ITEM_UNSELLABLE) then scanningIsUnsellableFound=true elseif(line==ITEM_SOULBOUND) then scanningIsSoulboundFound=true end if(not scaningChargesFound) then scaningChargesFound=strmatch(line, patternItemSpellChargesP1) end if(not scaningChargesFound) then scaningChargesFound=strmatch(line, patternItemSpellCharges) end if(scaningChargesFound) then scaningChargesFound=tonumber(scaningChargesFound) end if(not (scaningDurabilityFound and scaningDurabilityMaxFound)) then scaningDurabilityFound, scaningDurabilityMaxFound=strmatch(line, patternDurability) end -- ItemDataCache.Chatback(scaningLink..": "..tostring(scaningDurabilityFound).."/"..tostring(scaningDurabilityMaxFound)) if(scaningDurabilityFound and scaningDurabilityMaxFound) then scaningDurabilityFound=tonumber(scaningDurabilityFound) scaningDurabilityMaxFound=tonumber(scaningDurabilityMaxFound) end if(scanStatsMod or ItemDataCache.ScanStatsMod) then if(not initPatternStatsModDone) then ItemDataCache.InitStatModPatterns() end for stat, pattern in pairs(patternStatsMod) do -- ItemDataCache.Chatback("CHK: "..stat.." "..pattern.." "..line) local result=strmatch(line, pattern) if(result) then scaningStatsModFound[stat]=(scaningStatsModFound[stat] or 0)+tonumber(result) -- ItemDataCache.Chatback("RES: "..stat.." "..scaningStatsModFound[stat]) break end end end end end if(scanStatsMod or ItemDataCache.ScanStatsMod) then scanStatsMod=false ItemDataCache.ScanStatsMod=false end end -- simplified version to find only one attribute (pattern) function ItemDataCache.ScanTooltipPattern(pattern) for i=2, ItemDataCacheTooltip:NumLines(), 1 do local line=getglobal("ItemDataCacheTooltipTextLeft"..i):GetText() if(line and line==pattern) then return true end end return false end function ItemDataCache.TooltipScanBagItem(bag, slot) scaningMoneyFound=false ItemDataCacheTooltip:ClearLines() -- ItemDataCache.Chatback("Trying to scan "..bag.." "..slot..".") ItemDataCacheTooltip:SetBagItem(bag, slot) return ItemDataCache.ScanTooltip() end function ItemDataCacheTooltip.ScanHyperlink(item) scaningMoneyFound=false ItemDataCacheTooltip:ClearLines() ItemDataCacheTooltip:SetHyperlink(item) return ItemDataCache.ScanTooltip() end function ItemDataCache.TooltipScanBagItemIsSoulbound(bag, slot) ItemDataCacheTooltip:ClearLines() ItemDataCacheTooltip:SetBagItem(bag, slot) return ItemDataCache.ScanTooltipPattern(ITEM_SOULBOUND) end function ItemDataCache.DebugScanTooltip() for i=2, ItemDataCacheTooltip:NumLines(), 1 do local line=getglobal("ItemDataCacheTooltipTextLeft"..i):GetText() if (line) then ItemDataCache.Chatback(line) end end end local function ItemDataCacheInternal_InitRecipeClasses() if(ItemDataCache.InitLocalClassName(9, 3) and ItemDataCache.InitLocalClassName(9, 6) and ItemDataCache.InitLocalClassName(9, 8)) then -- self-destruct ItemDataCacheInternal_InitRecipeClasses=nil end end function ItemDataCache.PurgeLocalDataByID_maxcharges() if(ItemDataCacheInternal_InitRecipeClasses) then ItemDataCacheInternal_InitRecipeClasses() end local removed=0 for index, value in pairs(ItemDataCacheLocal.ByID_maxcharges) do local class, subClass=ItemDataCache.Get.ByID_class(index) if((class and subClass) and ((class==9 and subClass==3) or (class==9 and subClass==6) or (class==9 and subClass==8))) then ItemDataCacheLocal.ByID_maxcharges[index]=nil removed=removed+1 end end ItemDataCache.Chatback("Finished local data purge for ByID_maxcharges. "..removed.." incorrect entries removed.") -- self-destruct ItemDataCache.PurgeLocalDataByID_maxcharges=nil end -- /script ItemDataCache.ScanBagsAtMerchant() function ItemDataCache.ScanBagsAtMerchant() -- ItemDataCache.Chatback("Scanning...") if((not MerchantFrame:IsVisible()) or InRepairMode()) then return end for bag=0,NUM_BAG_FRAMES do for slot=1,GetContainerNumSlots(bag) do scaningLink=GetContainerItemLink(bag, slot) if(scaningLink) then local _ scaningID=tonumber(strmatch(scaningLink, ".*item:(%d+):.*")) _, scaningStack=GetContainerItemInfo(bag, slot) -- ItemDataCache.Chatback("Trying to scan "..scaningLink.." ("..scaningID..").") ItemDataCache.TooltipScanBagItem(bag, slot) -- UpdateLocalDataByID will call OnUpdate which can call IDC function again and mess up -- file-scoped variable values. -- Let's save all we need to write data to DB now. local thisLink=scaningLink local thisID=scaningID local thisChargesFound=scaningChargesFound local thisMoneyFound=scaningMoneyFound local thisDurabilityFound=scaningDurabilityFound local thisDurabilityMaxFound=scaningDurabilityMaxFound local thisIsUnsellableFound=scanningIsUnsellableFound -- if(thisMoneyFound) then ItemDataCache.Chatback(thisMoneyFound) end if(thisChargesFound) then if(ItemDataCacheInternal_InitRecipeClasses) then ItemDataCacheInternal_InitRecipeClasses() end local class, subClass=ItemDataCache.Get.ByID_class(thisID) if((class and subClass) and ((class==9 and subClass==3) or (class==9 and subClass==6) or (class==9 and subClass==8))) then ItemDataCache.UpdateLocalDataByID("ByID_maxcharges", thisID, nil) else ItemDataCache.UpdateLocalDataByID("ByID_maxcharges", thisID, true) end end -- if(thisChargesFound) then ItemDataCache.Chatback(thisLink.." charges: "..tostring(thisChargesFound)..".") end -- ignore item and reset local price if item have charges and price is different from 0 if(thisIsUnsellableFound) then ItemDataCache.UpdateLocalDataByID("ByID_selltovendor", thisID, 0) elseif(ItemDataCache.Get.ByID_maxcharges(thisID)) then -- ItemDataCache.Chatback(thisLink.." first pass") if(ItemDataCacheLocal.ByID_selltovendor[itemID] and ItemDataCacheLocal.ByID_selltovendor[itemID] ~= 0) then ItemDataCache.UpdateLocalDataByID("ByID_selltovendor", thisID, nil) end -- Only save item if it is at full durability elseif(thisDurabilityFound == thisDurabilityMaxFound) then if(thisMoneyFound) then ItemDataCache.UpdateLocalDataByID("ByID_selltovendor", thisID, thisMoneyFound) end end end end end end