commit 265f0ef25d110960ecaaef7e0a9077e69e17c22c Author: Lauren Hinnen Date: Sat Aug 15 16:01:02 2026 -0500 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4befed3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.DS_Store +.idea diff --git a/TargetScanner/TargetScanner.lua b/TargetScanner/TargetScanner.lua new file mode 100755 index 0000000..68da5bf --- /dev/null +++ b/TargetScanner/TargetScanner.lua @@ -0,0 +1,233 @@ +-- ============================================================================ +-- 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") \ No newline at end of file diff --git a/TargetScanner/TargetScanner.toc b/TargetScanner/TargetScanner.toc new file mode 100755 index 0000000..9621efd --- /dev/null +++ b/TargetScanner/TargetScanner.toc @@ -0,0 +1,7 @@ +## Interface: 11503 +## Title: TargetScanner +## Notes: Specific item price scanner framework. +## Author: Lauren Hinnen +## Version: 1.0 + +TargetScanner.lua \ No newline at end of file diff --git a/TargetScanner/alchemyIngredientPage.php b/TargetScanner/alchemyIngredientPage.php new file mode 100644 index 0000000..72acb85 --- /dev/null +++ b/TargetScanner/alchemyIngredientPage.php @@ -0,0 +1,12 @@ + + + + + + + Alchemy Ingredient Selector + + + + + \ No newline at end of file diff --git a/TargetScanner/img/alchemy.png b/TargetScanner/img/alchemy.png new file mode 100644 index 0000000..719156d Binary files /dev/null and b/TargetScanner/img/alchemy.png differ diff --git a/TargetScanner/index.html b/TargetScanner/index.html new file mode 100755 index 0000000..09c3a4e --- /dev/null +++ b/TargetScanner/index.html @@ -0,0 +1,25 @@ + + + + + + + Alchemy Calculator + + +
+ +
+ + \ No newline at end of file diff --git a/TargetScanner/nav.html b/TargetScanner/nav.html new file mode 100644 index 0000000..6de30e5 --- /dev/null +++ b/TargetScanner/nav.html @@ -0,0 +1,53 @@ + + + + + + + Alchemy Calculator + + + +
+ +
+ + \ No newline at end of file diff --git a/TargetScanner/style.css b/TargetScanner/style.css new file mode 100644 index 0000000..0669170 --- /dev/null +++ b/TargetScanner/style.css @@ -0,0 +1,27 @@ +ul { + list-style-type: none; + margin: 0; + padding: 0; + background-color: #333333; + display: flex; +} + +ul li a { + display: block; + color: white; + padding: 14px 16px; + text-decoration: none; +} + +ul li a:hover { + background-color: #111111; +} + +ul li a.active { + background-color: #04AA6D; +} + +ul li a img { + width: 25px; + height: 25px; +} \ No newline at end of file