-- ============================================================================ -- Addon Name: TargetScanner -- Description: Item scanner tailored for the -- Anniversary Edition Auction House API. -- API Version: Compatible with Anniversary Realms (1.15.x) -- ============================================================================ local addonName, addonTable = ... -- 1. CONFIGURATION: Define target item names and your maximum unit buyout threshold. -- Server-side queries accept item names as search filters rather than raw IDs. -- WoW Anniversary Edition Alchemy Consumables Configuration (Max Price in Copper) local TargetItems = { -- Restoration Potions (Health) ["Minor Healing Potion"] = { maxPrice = 500 }, ["Lesser Healing Potion"] = { maxPrice = 1500 }, ["Healing Potion"] = { maxPrice = 5000 }, ["Greater Healing Potion"] = { maxPrice = 20000 }, ["Superior Healing Potion"] = { maxPrice = 50000 }, ["Major Healing Potion"] = { maxPrice = 150000 }, -- Restoration Potions (Mana) ["Lesser Mana Potion"] = { maxPrice = 2000 }, ["Mana Potion"] = { maxPrice = 6000 }, ["Greater Mana Potion"] = { maxPrice = 25000 }, ["Superior Mana Potion"] = { maxPrice = 75000 }, ["Major Mana Potion"] = { maxPrice = 200000 }, ["Combat Mana Potion"] = { maxPrice = 100000 }, -- Utility & Defensive Potions ["Swiftness Potion"] = { maxPrice = 80000 }, ["Swim Speed Potion"] = { maxPrice = 15000 }, ["Free Action Potion"] = { maxPrice = 150000 }, ["Living Action Potion"] = { maxPrice = 250000 }, ["Limited Invulnerability Potion"] = { maxPrice = 180000 }, ["Restorative Potion"] = { maxPrice = 120000 }, ["Invisibility Potion"] = { maxPrice = 100000 }, ["Lesser Invisibility Potion"] = { maxPrice = 40000 }, ["Potion of Dreamless Sleep"] = { maxPrice = 60000 }, ["Purification Potion"] = { maxPrice = 50000 }, ["Wildvine Potion"] = { maxPrice = 90000 }, -- Elemental Protection Potions ["Fire Protection Potion"] = { maxPrice = 30000 }, ["Greater Fire Protection Potion"] = { maxPrice = 250000 }, ["Mighty Fire Protection Potion"] = { maxPrice = 400000 }, ["Frost Protection Potion"] = { maxPrice = 20000 }, ["Greater Frost Protection Potion"] = { maxPrice = 150000 }, ["Mighty Frost Protection Potion"] = { maxPrice = 300000 }, ["Nature Protection Potion"] = { maxPrice = 25000 }, ["Greater Nature Protection Potion"] = { maxPrice = 200000 }, ["Mighty Nature Protection Potion"] = { maxPrice = 350000 }, ["Shadow Protection Potion"] = { maxPrice = 30000 }, ["Greater Shadow Protection Potion"] = { maxPrice = 220000 }, ["Mighty Shadow Protection Potion"] = { maxPrice = 380000 }, ["Arcane Protection Potion"] = { maxPrice = 15000 }, ["Greater Arcane Protection Potion"] = { maxPrice = 100000 }, -- Combat Stats & Class Potions ["Rage Potion"] = { maxPrice = 10000 }, ["Great Rage Potion"] = { maxPrice = 40000 }, ["Mighty Rage Potion"] = { maxPrice = 180000 }, ["Greater Stoneshield Potion"] = { maxPrice = 120000 }, ["Mageblood Potion"] = { maxPrice = 90000 }, ["Major Troll's Blood Potion"] = { maxPrice = 40000 }, -- Physical/Combat Elixirs ["Elixir of Lion's Strength"] = { maxPrice = 800 }, ["Elixir of Lesser Agility"] = { maxPrice = 3000 }, ["Elixir of Agility"] = { maxPrice = 25000 }, ["Elixir of Giants"] = { maxPrice = 45000 }, ["Elixir of Brute Force"] = { maxPrice = 60000 }, ["Elixir of the Mongoose"] = { maxPrice = 180000 }, -- Caster Elixirs ["Elixir of Firepower"] = { maxPrice = 15000 }, ["Elixir of Greater Firepower"] = { maxPrice = 70000 }, ["Elixir of Shadow Power"] = { maxPrice = 55000 }, ["Elixir of Greater Intellect"] = { maxPrice = 35000 }, ["Elixir of the Sages"] = { maxPrice = 40000 }, ["Arcane Elixir"] = { maxPrice = 45000 }, ["Greater Arcane Elixir"] = { maxPrice = 160000 }, -- Defensive & Utility Elixirs ["Elixir of Defense"] = { maxPrice = 8000 }, ["Elixir of Fortitude"] = { maxPrice = 35000 }, ["Elixir of Superior Defense"] = { maxPrice = 150000 }, ["Elixir of Poison Resistance"] = { maxPrice = 25000 }, ["Gift of Arthas"] = { maxPrice = 30000 }, ["Elixir of Dream Vision"] = { maxPrice = 40000 }, -- Raid Flasks (Persistent through death) ["Flask of the Titans"] = { maxPrice = 600000 }, ["Flask of Supreme Power"] = { maxPrice = 600000 }, ["Flask of Distilled Wisdom"] = { maxPrice = 600000 }, ["Flask of Chromatic Resistance"] = { maxPrice = 400000 }, ["Flask of Petrification"] = { maxPrice = 500000 }, -- Alchemy Oils ["Shadow Oil"] = { maxPrice = 80000 }, ["Frost Oil"] = { maxPrice = 50000 } } -- Addon state properties local currentItemIndex = 1 local itemOrder = {} local isScanning = false -- Chronologically map out the sequence keys for name, _ in pairs(TargetItems) do table.insert(itemOrder, name) end -- 2. FRAME & EVENT DISPATCHER local ScannerFrame = CreateFrame("Frame") ScannerFrame:RegisterEvent("AUCTION_HOUSE_SHOW") ScannerFrame:RegisterEvent("AUCTION_HOUSE_CLOSED") ScannerFrame:RegisterEvent("AUCTION_ITEM_LIST_UPDATE") -- 3. CORE PRINT UTILITY local function PrintMessage(msg) print("|cFF00FFCC[TargetScanner]|r: " .. msg) end -- Converts flat copper currencies into beautifully color-coded Gold/Silver/Copper strings local function FormatMoney(copper) if not copper or copper == 0 then return "0g" end local gold = math.floor(copper / 10000) local silver = math.floor((copper % 10000) / 100) local cop = copper % 100 return string.format("|cFFFFD700%dg|r |cFFC7C7C7%ds|r |cFFB87333%dc|r", gold, silver, cop) end -- 4. SEQUENCE STEP MANAGER local function ScanNextItem() if not isScanning then return end -- Check if we finished checking our tailored list if currentItemIndex > #itemOrder then PrintMessage("Scan process complete!") isScanning = false currentItemIndex = 1 return end local targetName = itemOrder[currentItemIndex] PrintMessage("Querying server for: " .. targetName .. "...") -- Auction Query API Structure: -- QueryAuctionItems("name", minLevel, maxLevel, page, isUsable, rarityFilter, getAll, exactMatch) -- We set exactMatch (parameter 8) to true to cut out extraneous suffix permutations QueryAuctionItems(targetName, nil, nil, 0, nil, nil, false, true) end -- Main interface execution call function TargetScanner_StartScan() if isScanning then PrintMessage("A scan sequence is already actively running.") return end isScanning = true currentItemIndex = 1 PrintMessage("Kicking off sequential tracking for " .. #itemOrder .. " Classic items...") ScanNextItem() end -- 5. EVENT SYSTEM INTERACTION ScannerFrame:SetScript("OnEvent", function(self, event, ...) if event == "AUCTION_HOUSE_SHOW" then PrintMessage("Anniversary Auction House ready. Type /tscan to check values.") elseif event == "AUCTION_HOUSE_CLOSED" then isScanning = false currentItemIndex = 1 elseif event == "AUCTION_ITEM_LIST_UPDATE" then -- This event fires when server database page details load into local client visibility if not isScanning then return end local batchCount, totalCount = GetNumAuctionItems("list") local targetName = itemOrder[currentItemIndex] local config = TargetItems[targetName] local foundDeals = false -- Scan through all listings currently sent to the client list buffer for i = 1, batchCount do -- Data fetch return structure map local name, _, count, _, _, _, _, _, _, buyoutPrice = GetAuctionItemInfo("list", i) if name == targetName and buyoutPrice and buyoutPrice > 0 then -- Divide by stack count size to extract true single unit prices local unitPrice = buyoutPrice / count if unitPrice <= config.maxPrice then PrintMessage(string.format("PROFITABLE LISTING: %s x%d - Unit Cost: %s (Total Buyout: %s)", name, count, FormatMoney(unitPrice), FormatMoney(buyoutPrice) )) foundDeals = true end end end if not foundDeals then PrintMessage("No listings found below price caps for: " .. targetName) end -- Increment queue index to prepare the next item currentItemIndex = currentItemIndex + 1 -- CRITICAL: Servers implement severe request limits. -- An explicit 2.0-second delay protects the client connection from disconnects. C_Timer.After(2.0, function() ScanNextItem() end) end end) -- 6. INTERFACE INTERACTION COMMAND SLASH_TARSCAN1 = "/tscan" SlashCmdList["TARSCAN"] = function(msg) -- WoW utilizes 'AuctionFrame' if not AuctionFrame or not AuctionFrame:IsShown() then PrintMessage("Aborted: You must have an interaction window open with an Auctioneer NPC.") return end TargetScanner_StartScan() end PrintMessage("Targeted script loaded. Macro command: /tscan")