diff --git a/AuctionatorConfig.xml b/AuctionatorConfig.xml new file mode 100644 index 0000000..54e920e --- /dev/null +++ b/AuctionatorConfig.xml @@ -0,0 +1,628 @@ + + + + + + + + + + + + + + + + Atr_ShowOptionTooltip(this); + GameTooltip:Hide(); + + + + + + + + + + + + + + + + + + Atr_ShowOptionTooltip(this:GetParent()); + GameTooltip:Hide(); + Atr_Option_OnClick (this); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + this:SetBackdropColor(0.2, 0.2, 0.2); + + + + + + + + + + + this.TimeSinceLastUpdate = 0; + Atr_LoadOptionsSubPanel (this, ZT("Basic Options")); + + + Atr_BasicOptionsUpdate (this, arg1); + + + + + + + + + + AuctionatorOption_Enable_Alt_CB_Text:SetText (ZT("Enable alt-key shortcut")); + + + + + + + AuctionatorOption_Open_All_Bags_CB_Text:SetText (ZT("Automatically open all bags")); + + + + + + + + AuctionatorOption_Show_StartingPrice_CB_Text:SetText (ZT("Show Starting Price on the Sell Tab")); + + + + + + + + AuctionatorOption_Def_Duration_CB_Text:SetText (ZT("Set a default duration")); + + + + + + + + + + + getglobal(this:GetName().."Text"):SetText(AtrNS.durationText[1]); + Atr_SetDurationOptionRB (this:GetName()); + + + + + + getglobal(this:GetName().."Text"):SetText(AtrNS.durationText[2]); + Atr_SetDurationOptionRB (this:GetName()); + + + + + + getglobal(this:GetName().."Text"):SetText(AtrNS.durationText[3]); + Atr_SetDurationOptionRB (this:GetName()); + + + + + + + + + + + + + + + + + Atr_ShowOptionTooltip(this); + GameTooltip:Hide(); + + + + + + + + UIDropDownMenu_Initialize(this, AuctionatorOption_Deftab_Initialize); + UIDropDownMenu_JustifyText ("LEFT", AuctionatorOption_Deftab); + + + + + + + + + + + + + + + Atr_LoadOptionsSubPanel (this, ZT("Tooltips")); + + + + + + + + + + + + + + + + + + + + ATR_tipsVendorOpt_CB_Text:SetText (ZT("Show vendor prices in tooltips")); + + + + + + + ATR_tipsAuctionOpt_CB_Text:SetText (ZT("Show auction house prices in tooltips")); + + + + + + + ATR_tipsDisenchantOpt_CB_Text:SetText (ZT("Show disenchant prices in tooltips")); + + + + + + + + UIDropDownMenu_Initialize(this, Atr_tipsShiftDD_Initialize); + UIDropDownMenu_SetSelectedValue(Atr_tipsShiftDD, 1); + UIDropDownMenu_JustifyText ("LEFT", Atr_tipsShiftDD); + + + + + + + + + UIDropDownMenu_Initialize(this, Atr_deDetailsDD_Initialize); + UIDropDownMenu_SetWidth (175, Atr_deDetailsDD); + UIDropDownMenu_JustifyText ("LEFT", Atr_deDetailsDD); + UIDropDownMenu_SetSelectedValue(Atr_deDetailsDD, 1); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Atr_LoadOptionsSubPanel (this, ZT("Undercutting")); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Atr_LoadOptionsSubPanel (this, ZT("Selling"), nil, ZT("Configure how you typically like to sell the items listed below.")); + + + + + + + + + + + + + + + + + + + + FauxScrollFrame_OnVerticalScroll(16, Atr_StackingList_Display); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HideInterfaceOptionsMask() + + + + + + + + + + + Atr_SONumStacks_OnLoad(this); + + + + + + + + + + + + + + + + + + + + + + + + + + + + Atr_LoadOptionsSubPanel (this, ZT("Scanning")); + + + + + + + + + + + + + + Atr_scanLevelDD_showTip(this); + GameTooltip:Hide(); + + + + + + + + + UIDropDownMenu_Initialize(this, Atr_scanLevelDD_Initialize); + UIDropDownMenu_SetSelectedValue(Atr_scanLevelDD, 1); + UIDropDownMenu_JustifyText ("LEFT", Atr_scanLevelDD); + + Atr_scanLevelDD_showTip(this); + GameTooltip:Hide(); + + + + + + + + + + + + + + + + Atr_LoadOptionsSubPanel (this, ZT("About"), ZT("About Auctionator")); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/AuctionatorConflicts.lua b/AuctionatorConflicts.lua new file mode 100644 index 0000000..968a18b --- /dev/null +++ b/AuctionatorConflicts.lua @@ -0,0 +1,88 @@ + +local addonName, addonTable = "Auctionator", AtrNS; +local zc = addonTable.zc; + + +local Atr_orig_RecipeKnown_EventScan; +local Atr_orig_LootLink_OnEvent; +local Atr_orig_WOWEcon_Scan_AH; + +----------------------------------------- + + +local function Atr_RecipeKnown_EventScan (rkSelf, rkEvent, rkArg1) + + if (event == "AUCTION_ITEM_LIST_UPDATE") then + + if (Atr_IsTabSelected()) then + return; + end + + local numBatchAuctions = GetNumAuctionItems("list"); + if (numBatchAuctions > 50) then -- full scan + return; + end + end + + Atr_orig_RecipeKnown_EventScan (rkSelf, rkEvent, rkArg1); +end + +----------------------------------------- + +local function Atr_LootLink_OnEvent () + + if (event == "AUCTION_ITEM_LIST_UPDATE") then + + if (Atr_IsTabSelected()) then + return; + end + + local numBatchAuctions = GetNumAuctionItems("list"); + if (numBatchAuctions > 50) then -- full scan + return; + end + end + + Atr_orig_LootLink_OnEvent (); +end + +----------------------------------------- + +local function Atr_WOWEcon_Scan_AH () + + if (Atr_IsTabSelected()) then + return; + end + + local numBatchAuctions = GetNumAuctionItems("list"); + if (numBatchAuctions > 50) then -- full scan + return; + end + + Atr_orig_WOWEcon_Scan_AH (); +end + + +----------------------------------------- + +function Atr_Check_For_Conflicts (addonName) + + if (zc.StringSame (addonName, "recipeknown") and RecipeKnown_EventScan) then + Atr_orig_RecipeKnown_EventScan = RecipeKnown_EventScan; + RecipeKnown_EventScan = Atr_RecipeKnown_EventScan + zc.msg_yellow ("Auctionator is patching RecipeKnown to prevent a known conflict."); + end + + if (zc.StringContains (addonName, "lootlink") and LootLink_OnEvent) then + Atr_orig_LootLink_OnEvent = LootLink_OnEvent; + LootLink_OnEvent = Atr_LootLink_OnEvent + zc.msg_yellow ("Auctionator is patching LootLink to prevent a known conflict."); + end + + if (zc.StringContains (addonName, "wowecon") and WOWEcon_Scan_AH) then + Atr_orig_WOWEcon_Scan_AH = WOWEcon_Scan_AH; + WOWEcon_Scan_AH = Atr_WOWEcon_Scan_AH + zc.msg_yellow ("Auctionator is patching WowEcon to prevent a known conflict."); + end + +end diff --git a/AuctionatorHints.lua b/AuctionatorHints.lua new file mode 100644 index 0000000..295f021 --- /dev/null +++ b/AuctionatorHints.lua @@ -0,0 +1,887 @@ + +local addonName, addonTable = "Auctionator", AtrNS; +local zc = addonTable.zc; + + +----------------------------------------- + +local auctionator_orig_GameTooltip_OnTooltipAddMoney; + +----------------------------------------- + +function auctionator_GameTooltip_OnTooltipAddMoney (self, cost, maxcost) + + if (AUCTIONATOR_V_TIPS == 1) then + return; + end + + auctionator_orig_GameTooltip_OnTooltipAddMoney (self, cost, maxcost); +end + +----------------------------------------- + +function Atr_Hook_OnTooltipAddMoney() + -- the 3.x port hid the stock vendor line here; the 1.12 tooltip has no such hook +end + +------------------------------------------------ + +local function Atr_AppendHint (results, price, text, volume) + + if (price and price > 0) then + local e = {}; + e.price = price; + e.text = text; + e.volume = volume; + + table.insert (results, e); + end + +end + +------------------------------------------------ + +function Atr_BuildHints (itemName) + + local results = {}; + + local itemLink = Atr_GetItemLink (itemName); + + if (itemLink == nil and itemName == nil) then + return results; + end + + -- Auctionator Full Scan + + if (itemName ~= nil and gAtr_ScanDB[itemName] ~= nil) then + Atr_AppendHint (results, gAtr_ScanDB[itemName], ZT("Auctionator scan data")); + end + + -- most recent historical price + + local price = Atr_GetMostRecentSale(itemName); + if (price ~= nil) then + Atr_AppendHint (results, price, ZT("your most recent posting")); + end + + -- Wowecon + + if (Wowecon and Wowecon.API) then + + local priceG, volG, priceS, volS; + + if (itemLink) then + priceG, volG = Wowecon.API.GetAuctionPrice_ByLink (itemLink, Wowecon.API.GLOBAL_PRICE) + priceS, volS = Wowecon.API.GetAuctionPrice_ByLink (itemLink, Wowecon.API.SERVER_PRICE) + else + priceG, volG = Wowecon.API.GetAuctionPrice_ByName (itemName, Wowecon.API.GLOBAL_PRICE) + priceS, volS = Wowecon.API.GetAuctionPrice_ByName (itemName, Wowecon.API.SERVER_PRICE) + end + + Atr_AppendHint (results, priceG, ZT("Wowecon global price"), volG); + Atr_AppendHint (results, priceS, ZT("Wowecon server price"), volS); + + end + + if (itemLink) then + + -- GoingPrice Wowhead + + local id = zc.ItemIDfromLink (itemLink); + + id = tonumber(id); + + if (GoingPrice_Wowhead_Data and GoingPrice_Wowhead_Data[id] and GoingPrice_Wowhead_SV._index) then + local index = GoingPrice_Wowhead_SV._index["Buyout price"]; + + if (index ~= nil) then + local price = GoingPrice_Wowhead_Data[id][index]; + + Atr_AppendHint (results, price, "GoingPrice - Wowhead"); + end + end + + -- GoingPrice Allakhazam + + if (GoingPrice_Allakhazam_Data and GoingPrice_Allakhazam_Data[id] and GoingPrice_Allakhazam_SV._index) then + local index = GoingPrice_Allakhazam_SV._index["Median"]; + + if (index ~= nil) then + local price = GoingPrice_Allakhazam_Data[id][index]; + + Atr_AppendHint (results, price, "GoingPrice - Allakhazam"); + end + end + end + + return results; + +end + +----------------------------------------- + +function Atr_ShowHints () + + Atr_Col1_Heading:Hide(); + Atr_Col1_Heading_Button:Hide(); + Atr_Col3_Heading_Button:Hide(); + Atr_Col3_Heading:Hide(); + Atr_Col4_Heading:Hide(); + + Atr_Col3_Heading:SetText (ZT("Source")); + + local currentPane = Atr_GetCurrentPane(); + + currentPane.hints = Atr_BuildHints (currentPane.activeScan.itemName); + + local numrows = currentPane.hints and getn(currentPane.hints) or 0; + + if (numrows > 0) then + Atr_Col1_Heading:Show(); + Atr_Col3_Heading:Show(); + end + + local line; -- 1 through 12 of our window to scroll + local dataOffset; -- an index into our data calculated from the scroll offset + + FauxScrollFrame_Update (AuctionatorScrollFrame, numrows, 12, 16); + + for line = 1,12 do + + dataOffset = line + FauxScrollFrame_GetOffset (AuctionatorScrollFrame); + + local lineEntry = getglobal ("AuctionatorEntry"..line); + + lineEntry:SetID(dataOffset); + + if (dataOffset <= numrows and currentPane.hints[dataOffset]) then + + local data = currentPane.hints[dataOffset]; + + local lineEntry_item_tag = "AuctionatorEntry"..line.."_PerItem_Price"; + + local lineEntry_item = getglobal(lineEntry_item_tag); + local lineEntry_itemtext = getglobal("AuctionatorEntry"..line.."_PerItem_Text"); + local lineEntry_text = getglobal("AuctionatorEntry"..line.."_EntryText"); + local lineEntry_stack = getglobal("AuctionatorEntry"..line.."_StackPrice"); + + lineEntry_item:Show(); + lineEntry_itemtext:Hide(); + lineEntry_stack:SetText (""); + Atr_ShowRowStackMoney (lineEntry, nil); + + Atr_SetMFcolor (lineEntry_item_tag, true); + + MoneyFrame_Update (lineEntry_item_tag, zc.round(data.price) ); + + local text = data.text; + if (data.volume) then + text = text.." ("..ZT("trade volume")..": "..data.volume..")"; + end + + lineEntry_text:SetText (text); + lineEntry_text:SetTextColor (0.8, 0.8, 1.0); + + lineEntry:Show(); + else + lineEntry:Hide(); + end + end + + Atr_HighlightEntry (currentPane.hintsIndex); +end + + +----------------------------------------- + +function Atr_SetMFcolor (frameName, blue) + + local r, g, b = 1, 1, 1; + + if (blue) then + r, g, b = 0.7, 0.7, 1.0; + end + + local names = { "GoldButtonText", "SilverButtonText", "CopperButtonText" }; + local i; + + for i = 1, 3 do + local fs = getglobal (frameName..names[i]); + if (fs) then + fs:SetTextColor (r, g, b); + end + end + +end + + +----------------------------------------- + +function Atr_GetAuctionPrice (item) -- itemName or itemID + + local itemName; + + if (type (item) == "number") then + itemName = Atr_GetItemInfo (item); + else + itemName = item; + end + + if (itemName == nil) then + return nil; + end + + if (gAtr_ScanDB[itemName]) then + return gAtr_ScanDB[itemName]; + end + + return Atr_GetMostRecentSale (itemName); +end + +----------------------------------------- + +local function Atr_CalcTextWid (price) + + local wid = 15; + + if (price > 9) then wid = wid + 12; end; + if (price > 99) then wid = wid + 44; end; + if (price > 999) then wid = wid + 12; end; + if (price > 9999) then wid = wid + 44; end; + if (price > 99999) then wid = wid + 12; end; + if (price > 999999) then wid = wid + 12; end; + if (price > 9999999) then wid = wid + 12; end; + if (price > 99999999) then wid = wid + 12; end; + + return wid; +end + +----------------------------------------- + +local function Atr_CalcTTpadding (price1, price2) + + local padding = ""; + + if (price1 and price2) then + local vpwidth = Atr_CalcTextWid (price1); + local apwidth = Atr_CalcTextWid (price2); + + local padlen = math.floor ((apwidth - vpwidth)/6); + local k; + + for k = 1,padlen do + padding = padding.." "; + end + end + + return padding; + +end + +----------------------------------------- + +local UNCOMMON = 2; +local RARE = 3; +local EPIC = 4; + +local WEAPON = 1; +local ARMOR = 2; + +local LESSER_MAGIC = 10938; +local GREATER_MAGIC = 10939; +local STRANGE_DUST = 10940; + +local SMALL_GLIMMERING = 10978; +local LESSER_ASTRAL = 10998; + +local GREATER_ASTRAL = 11082; +local SOUL_DUST = 11083; +local LARGE_GLIMMERING = 11084; + +local LESSER_MYSTIC = 11134; +local GREATER_MYSTIC = 11135; +local VISION_DUST = 11137; +local SMALL_GLOWING = 11138; +local LARGE_GLOWING = 11139; + +local LESSER_NETHER = 11174; +local GREATER_NETHER = 11175; +local DREAM_DUST = 11176; +local SMALL_RADIANT = 11177; +local LARGE_RADIANT = 11178; + +local SMALL_BRILLIANT = 14343; +local LARGE_BRILLIANT = 14344; + +local LESSER_ETERNAL = 16202; +local GREATER_ETERNAL = 16203; +local ILLUSION_DUST = 16204; + +local NEXUS_CRYSTAL = 20725; + +local ARCANE_DUST = 22445; +local GREATER_PLANAR = 22446; +local LESSER_PLANAR = 22447; +local SMALL_PRISMATIC = 22448; +local LARGE_PRISMATIC = 22449; +local VOID_CRYSTAL = 22450; + +local DREAM_SHARD = 34052; +local SMALL_DREAM = 34053; + +local INFINITE_DUST = 34054; +local GREATER_COSMIC = 34055; +local LESSER_COSMIC = 34056; +local ABYSS_CRYSTAL = 34057; + +local engDEnames = {}; + +engDEnames [LESSER_MAGIC] = "Lesser Magic Essence"; +engDEnames [GREATER_MAGIC] = "Greater Magic Essence"; +engDEnames [STRANGE_DUST] = "Strange Dust"; + +engDEnames [SMALL_GLIMMERING] = "Small Glimmering Shard"; +engDEnames [LESSER_ASTRAL] = "Lesser Astral Essence"; + +engDEnames [GREATER_ASTRAL] = "Greater Astral Essence"; +engDEnames [SOUL_DUST] = "Soul Dust"; +engDEnames [LARGE_GLIMMERING] = "Large Glimmering Essence"; + +engDEnames [LESSER_MYSTIC] = "Lesser Mystic Essence"; +engDEnames [GREATER_MYSTIC] = "Greater Mystic Essence"; +engDEnames [VISION_DUST] = "Vision Dust"; +engDEnames [SMALL_GLOWING] = "Small Glowing Shard"; +engDEnames [LARGE_GLOWING] = "Large Glowing Shard"; + +engDEnames [LESSER_NETHER] = "Lesser Nether Essence"; +engDEnames [GREATER_NETHER] = "Greater Nether Essence"; +engDEnames [DREAM_DUST] = "Dream Dust"; +engDEnames [SMALL_RADIANT] = "Small Radiant"; +engDEnames [LARGE_RADIANT] = "Large Radiant"; + +engDEnames [SMALL_BRILLIANT] = "Small Brilliant Shard"; +engDEnames [LARGE_BRILLIANT] = "Large Brilliant Shard"; + +engDEnames [LESSER_ETERNAL] = "Lesser Eternal Essence"; +engDEnames [GREATER_ETERNAL] = "Greater Eternal Essence"; +engDEnames [ILLUSION_DUST] = "Illusion Dust"; + +engDEnames [NEXUS_CRYSTAL] = "Nexus Crystal"; + +engDEnames [ARCANE_DUST] = "Arcane Dust"; +engDEnames [GREATER_PLANAR] = "Greater Planar Essence"; +engDEnames [LESSER_PLANAR] = "Lesser Planar Essence"; +engDEnames [SMALL_PRISMATIC] = "Small Prismatic Shard"; +engDEnames [LARGE_PRISMATIC] = "Large Prismatic Shard"; +engDEnames [VOID_CRYSTAL] = "Void Crystal"; + +engDEnames [DREAM_SHARD] = "Dream Shard"; +engDEnames [SMALL_DREAM] = "Small Dream Shard"; + +engDEnames [INFINITE_DUST] = "Infinite Dust"; +engDEnames [GREATER_COSMIC] = "Greater Cosmic Essence"; +engDEnames [LESSER_COSMIC] = "Lesser Cosmic Essence"; +engDEnames [ABYSS_CRYSTAL] = "Abyss Crystal"; + + +local dustsAndEssences = {}; + +tinsert (dustsAndEssences, LESSER_MAGIC) +tinsert (dustsAndEssences, GREATER_MAGIC) +tinsert (dustsAndEssences, STRANGE_DUST) + +tinsert (dustsAndEssences, SMALL_GLIMMERING) +tinsert (dustsAndEssences, LESSER_ASTRAL) + +tinsert (dustsAndEssences, GREATER_ASTRAL) +tinsert (dustsAndEssences, SOUL_DUST) +tinsert (dustsAndEssences, LARGE_GLIMMERING) + +tinsert (dustsAndEssences, LESSER_MYSTIC) +tinsert (dustsAndEssences, GREATER_MYSTIC) +tinsert (dustsAndEssences, VISION_DUST) +tinsert (dustsAndEssences, SMALL_GLOWING) +tinsert (dustsAndEssences, LARGE_GLOWING) + +tinsert (dustsAndEssences, LESSER_NETHER) +tinsert (dustsAndEssences, GREATER_NETHER) +tinsert (dustsAndEssences, DREAM_DUST) +tinsert (dustsAndEssences, SMALL_RADIANT) +tinsert (dustsAndEssences, LARGE_RADIANT) + +tinsert (dustsAndEssences, SMALL_BRILLIANT) +tinsert (dustsAndEssences, LARGE_BRILLIANT) + +tinsert (dustsAndEssences, LESSER_ETERNAL) +tinsert (dustsAndEssences, GREATER_ETERNAL) +tinsert (dustsAndEssences, ILLUSION_DUST) + +tinsert (dustsAndEssences, NEXUS_CRYSTAL) + +tinsert (dustsAndEssences, ARCANE_DUST) +tinsert (dustsAndEssences, GREATER_PLANAR) +tinsert (dustsAndEssences, LESSER_PLANAR) +tinsert (dustsAndEssences, SMALL_PRISMATIC) +tinsert (dustsAndEssences, LARGE_PRISMATIC) +tinsert (dustsAndEssences, VOID_CRYSTAL) + +tinsert (dustsAndEssences, DREAM_SHARD) +tinsert (dustsAndEssences, SMALL_DREAM) + +tinsert (dustsAndEssences, INFINITE_DUST) +tinsert (dustsAndEssences, GREATER_COSMIC) +tinsert (dustsAndEssences, LESSER_COSMIC) +tinsert (dustsAndEssences, ABYSS_CRYSTAL) + +gAtr_dustCacheIndex = 0; -- the 3.x dust list is not cached on 1.12 (pulling unknown items can disconnect) +local dustCacheState = 0; + +----------------------------------------- + +function Atr_GetNextDustIntoCache() -- make sure all the dusts and essences are in the local cache + -- only needed after a major patch and a cache wipe + if (gAtr_dustCacheIndex == 0) then + return; + end + + local itemID = dustsAndEssences[gAtr_dustCacheIndex]; + local itemString = "item:"..itemID..":0:0:0:0:0:0:0"; + + local itemName, itemLink = Atr_GetItemInfo (itemString); + + if (itemLink == nil and dustCacheState == 0) then + dustCacheState = 1; + zc.md ("pulling "..itemString.." into the local cache"); + AtrScanningTooltip:SetHyperlink(itemString); + end + + if (itemLink) then + --zc.md (itemName.." is already in local cache"); + dustCacheState = 0; + gAtr_dustCacheIndex = gAtr_dustCacheIndex + 1; + + if (gAtr_dustCacheIndex > getn(dustsAndEssences)) then + gAtr_dustCacheIndex = 0; -- finished + end + end +end + +----------------------------------------- + +local deItemNames = {}; + +local function Atr_GetDEitemName (itemID) + + if (deItemNames[itemID] == nil) then + local itemName = Atr_GetItemInfo (itemID); + if (itemName == nil) then + zc.md ("defaulting to english DE mat name: "..engDEnames [itemID]); + return engDEnames [itemID]; + end + + deItemNames[itemID] = itemName; + end + + return deItemNames[itemID]; + +end + +----------------------------------------- + +function Atr_GetAuctionPriceDE (itemID) -- same as Atr_GetAuctionPrice but understands that some "lesser" essences are convertible with "greater" + + local lesserPrice; + local greaterPrice; + + if (itemID == LESSER_COSMIC) then + lesserPrice = Atr_GetAuctionPrice (Atr_GetDEitemName (LESSER_COSMIC)); + greaterPrice = Atr_GetAuctionPrice (Atr_GetDEitemName (GREATER_COSMIC)); + end + + if (itemID == LESSER_PLANAR) then + lesserPrice = Atr_GetAuctionPrice (Atr_GetDEitemName (LESSER_PLANAR)); + greaterPrice = Atr_GetAuctionPrice (Atr_GetDEitemName (GREATER_PLANAR)); + end + + if (lesserPrice ~= nil and greaterPrice ~= nil and lesserPrice * 3 > greaterPrice) then + return math.floor (greaterPrice / 3); + end + + return Atr_GetAuctionPrice (Atr_GetDEitemName (itemID)); +end + +----------------------------------------- + +local deTable = {}; + +----------------------------------------- + +local function deKey (itemType, itemRarity) + local s = tostring(itemType).."_"..itemRarity + return s; +end + +----------------------------------------- + +local function DEtableInsert(t, info) + + local entry = {}; + + local x, i, n; + + entry[1] = info[1]; + entry[2] = info[2]; + + n = 3; + + for x = 3,getn(info),3 do + local nums = info[x+1]; + if (type(nums) == "number") then + entry[n] = info[x]; + entry[n+1] = info[x+1]; + entry[n+2] = info[x+2]; + n = n + 3; + else + for i = nums[1],nums[2] do + entry[n] = info[x]/(nums[2]-nums[1]+1); + entry[n+1] = i; + entry[n+2] = info[x+2]; + n = n + 3; + end + end + end + + table.insert (t, entry); + +end + + +----------------------------------------- + +function Atr_InitDETable() -- disenchant tables are for the 3.x item level system; vanilla items have no item level + +end + +----------------------------------------- + +local function Atr_FindDEentry (itemType, itemRarity, itemLevel) + + local itemTypeNum = Atr_ItemType2AuctionClass (itemType); + + local t = deTable[deKey(itemTypeNum, itemRarity)]; + + if (t) then + local n; + for n = 1, getn(t) do + + local ta = t[n]; + + if (itemLevel >= ta[1] and itemLevel <= ta[2]) then + return ta; + end + end + end + + +end + +----------------------------------------- + +local function Atr_AddDEDetailsToTip (tip, itemType, itemRarity, itemLevel, DEreqLevel) + + local ta = Atr_FindDEentry (itemType, itemRarity, itemLevel); + + if (ta) then + local x; + for x = 3,getn(ta),3 do + local percent = math.floor (ta[x]*100) / 100; + + local deitem = Atr_GetDEitemName(ta[x+2]); + if (deitem == nil) then + deitem = "???"; + end + + tip:AddLine (" |cFFFFFFFF"..percent.."%|r "..ta[x+1].." "..deitem); + end + end + + tip:AddLine (" |cFFAAAAFF"..ZT("Required DE skill level")..": "..DEreqLevel); +end + +----------------------------------------- + +function Atr_DumpDETable (itemType, itemRarity) + + local t = deTable[deKey(itemType, itemRarity)]; + + if (t) then + local n, x; + for n = 1, getn(t) do + local ta = t[n]; + + zc.msg_pink ("iLvl: "..ta[1].."-"..ta[2]); + + for x = 3,getn(ta),3 do + zc.msg_pink (" "..ta[x].."% "..ta[x+1].." "..Atr_GetDEitemName(ta[x+2]).." ("..Atr_GetAuctionPrice (Atr_GetDEitemName(ta[x+2]))..")"); + end + end + end + +end + +----------------------------------------- + +function Atr_CalcDisenchantPrice (itemType, itemRarity, itemLevel) + + if (Atr_IsWeaponType (itemType) or Atr_IsArmorType (itemType)) then + if (itemRarity == UNCOMMON or itemRarity == RARE or itemRarity == EPIC) then + + local dePrice = 0; + + local ta = Atr_FindDEentry (itemType, itemRarity, itemLevel); + if (ta) then + local x; + for x = 3,getn(ta),3 do + local price = Atr_GetAuctionPriceDE (ta[x+2]); + if (price) then + dePrice = dePrice + (ta[x] * ta[x+1] * price); + end + end + end + + return math.floor (dePrice/100); + end + end + + return nil; -- can't be disenchanted +end + +----------------------------------------- + +local function ShowTipWithPricing (tip, link, num) + + Atr_TipBeginMoney (tip); + + + if (link == nil) then + return; + end + +--[[ + if (num == "tradeskill") then + + local skill = link; + + local n; + for n = 1,GetTradeSkillNumReagents(skill) do + local rname, _, rnum = GetTradeSkillReagentInfo(skill, n); + local rlink = GetTradeSkillReagentItemLink (skill, n); + zc.md (skill, rlink, rnum); + end + + return; + end +]]-- + + local itemName, itemLink, itemRarity, itemLevel, itemMinLevel, itemType, _, _, _, _, itemVendorPrice = Atr_GetItemInfo (link); + + local itemID = zc.ItemIDfromLink (link); + itemID = tonumber(itemID); + + local vendorPrice = 0; + local auctionPrice = 0; + local dePrice = nil; + + if (AUCTIONATOR_V_TIPS == 1) then vendorPrice = itemVendorPrice; end; + if (AUCTIONATOR_A_TIPS == 1) then auctionPrice = Atr_GetAuctionPrice (itemName); end; + if (AUCTIONATOR_D_TIPS == 1 and itemLevel) then dePrice = Atr_CalcDisenchantPrice (itemType, itemRarity, itemLevel); end; + + local xstring = ""; + local showStackPrices = IsShiftKeyDown(); + + if (AUCTIONATOR_SHIFT_TIPS == 2) then + showStackPrices = not IsShiftKeyDown(); + end + + if (num and showStackPrices) then + if (auctionPrice) then auctionPrice = auctionPrice * num; end; + if (vendorPrice) then vendorPrice = vendorPrice * num; end; + if (dePrice) then dePrice = dePrice * num; end; + xstring = "|cFFAAAAFF x"..num.."|r"; + end; + + if (vendorPrice == nil) then + vendorPrice = 0; + end + + -- vendor info + + if (AUCTIONATOR_V_TIPS == 1 and vendorPrice > 0) then + local vpadding = Atr_CalcTTpadding (vendorPrice, auctionPrice); + Atr_TipAddMoneyLine (tip, ZT("Vendor")..xstring, vendorPrice) + end + + -- auction info + + if (AUCTIONATOR_A_TIPS == 1) then + + local bonding = Atr_GetBonding(itemID); + local isBOP = (bonding == 1); + local isQuest = (bonding == 4 or bonding == 5); + + if (isBOP) then + tip:AddDoubleLine (ZT("Auction")..xstring, "|cFFFFFFFF"..ZT("BOP").." "); + elseif (isQuest) then + tip:AddDoubleLine (ZT("Auction")..xstring, "|cFFFFFFFF"..ZT("Quest Item").." "); + elseif (auctionPrice ~= nil) then + Atr_TipAddMoneyLine (tip, ZT("Auction")..xstring, auctionPrice); + else + tip:AddDoubleLine (ZT("Auction")..xstring, "|cFFFFFFFF"..ZT("unknown").." "); + end + end + + -- disenchanting info + + if (AUCTIONATOR_D_TIPS == 1 and dePrice ~= nil) then + if (dePrice > 0) then + Atr_TipAddMoneyLine (tip, ZT("Disenchant")..xstring, dePrice); + else + tip:AddDoubleLine (ZT("Disenchant")..xstring, "|cFFFFFFFF"..ZT("unknown").." "); + end + end + + local showDetails = true; + + if (AUCTIONATOR_DE_DETAILS_TIPS == 1) then showDetails = IsShiftKeyDown(); end; + if (AUCTIONATOR_DE_DETAILS_TIPS == 2) then showDetails = IsControlKeyDown(); end; + if (AUCTIONATOR_DE_DETAILS_TIPS == 3) then showDetails = IsAltKeyDown(); end; + if (AUCTIONATOR_DE_DETAILS_TIPS == 4) then showDetails = false; end; + if (AUCTIONATOR_DE_DETAILS_TIPS == 5) then showDetails = true; end; + + if (showDetails and dePrice ~= nil) then + Atr_AddDEDetailsToTip (tip, itemType, itemRarity, itemLevel, Atr_DEReqLevel(itemID)); + end + + tip:Show() + +end + +----------------------------------------- + +local function Atr_SafeTipHook (tip, method, fn) + + Atr_hooksecurefunc (tip, method, function (t, a, b, c, d) + local ok, err = pcall (fn, t, a, b, c, d); + if (not ok) then + Atr_ReportError ("tooltip "..method..": "..tostring(err)); -- never break the tooltip, but say why + end + end); + +end + +----------------------------------------- + +Atr_SafeTipHook (GameTooltip, "SetBagItem", + function(tip, bag, slot) + local _, num = GetContainerItemInfo(bag, slot); + ShowTipWithPricing (tip, GetContainerItemLink(bag, slot), num); + end +); + +Atr_SafeTipHook (GameTooltip, "SetAuctionItem", + function (tip, type, index) + local _, _, num = GetAuctionItemInfo(type, index); + ShowTipWithPricing (tip, GetAuctionItemLink(type, index), num); + end +); + +Atr_SafeTipHook (GameTooltip, "SetAuctionSellItem", + function (tip) + local link, name, count = Atr_SellSlotLink(); + ShowTipWithPricing (tip, link, count); + end +); + +Atr_SafeTipHook (GameTooltip, "SetLootItem", + function (tip, slot) + if LootSlotIsItem(slot) then + local _, _, num = GetLootSlotInfo(slot); + ShowTipWithPricing (tip, GetLootSlotLink(slot), num); + end + end +); + +Atr_SafeTipHook (GameTooltip, "SetLootRollItem", + function (tip, slot) + local _, _, num = GetLootRollItemInfo(slot); + ShowTipWithPricing (tip, GetLootRollItemLink(slot), num); + end +); + +Atr_SafeTipHook (GameTooltip, "SetInventoryItem", + function (tip, unit, slot) + ShowTipWithPricing (tip, GetInventoryItemLink(unit, slot), GetInventoryItemCount(unit, slot)); + end +); + +Atr_SafeTipHook (GameTooltip, "SetTradeSkillItem", + function (tip, skill, id) + local link = GetTradeSkillItemLink(skill); + local num = GetTradeSkillNumMade(skill); + if id then + local _, _, reagentNum = GetTradeSkillReagentInfo(skill, id); + link = GetTradeSkillReagentItemLink(skill, id); + num = reagentNum; + end + + ShowTipWithPricing (tip, link, num); + end +); + +Atr_SafeTipHook (GameTooltip, "SetTradePlayerItem", + function (tip, id) + local _, _, num = GetTradePlayerItemInfo(id); + ShowTipWithPricing (tip, GetTradePlayerItemLink(id), num); + end +); + +Atr_SafeTipHook (GameTooltip, "SetTradeTargetItem", + function (tip, id) + local _, _, num = GetTradeTargetItemInfo(id); + ShowTipWithPricing (tip, GetTradeTargetItemLink(id), num); + end +); + +Atr_SafeTipHook (GameTooltip, "SetQuestItem", + function (tip, type, index) + local _, _, num = GetQuestItemInfo(type, index); + ShowTipWithPricing (tip, GetQuestItemLink(type, index), num); + end +); + +Atr_SafeTipHook (GameTooltip, "SetQuestLogItem", + function (tip, type, index) + local num, _; + if type == "choice" then + _, _, num = GetQuestLogChoiceInfo(index); + else + _, _, num = GetQuestLogRewardInfo(index) + end + + ShowTipWithPricing (tip, GetQuestLogItemLink(type, index), num); + end +); + +Atr_SafeTipHook (GameTooltip, "SetHyperlink", + function (tip, itemstring, num) + local name, link = Atr_GetItemInfo (itemstring); + ShowTipWithPricing (tip, link, num); + end +); + +Atr_SafeTipHook (ItemRefTooltip, "SetHyperlink", + function (tip, itemstring) + local name, link = Atr_GetItemInfo (itemstring); + ShowTipWithPricing (tip, link); + end +); diff --git a/AuctionatorLocalize.lua b/AuctionatorLocalize.lua new file mode 100644 index 0000000..bc02988 --- /dev/null +++ b/AuctionatorLocalize.lua @@ -0,0 +1,257 @@ + +local addonName, addonTable = "Auctionator", AtrNS; +local zc = addonTable.zc; + + +----------------------------------------- + +AtrL = {}; + +----------------------------------------- + +function Atr_PickLocalizationTable (locale) + + local f = getglobal ("AtrBuildLTable_"..locale); + if (type (f) == "function") then + f(); +-- DEFAULT_CHAT_FRAME:AddMessage (locale.." found"); + else + AtrBuildLTable_enUS(); +-- DEFAULT_CHAT_FRAME:AddMessage (locale.." not found"); + end + +end + +----------------------------------------- + +Atr_PickLocalizationTable (GetLocale()); +--Atr_PickLocalizationTable ("esES"); + +----------------------------------------- + +function ZT (s) + + if (s == nil or s == "") then + return s; + end + + if (AtrL) then + local s1 = AtrL[s]; + if (s1 and s1 ~= "") then + return s1; + end + end + + return s; +end + + +----------------------------------------- + +function zc.IsEnglishLocale() + + return (GetLocale() == "enUS" or GetLocale() == "enGB"); + +end + +----------------------------------------- + +local testt = {}; +local Atr_excludes = { Cancel=1, Okay=1, Done=1, Close=1 } + +----------------------------------------- + +local function Atr_LocalizeChildText (frame) + + local child; + local subregions = { frame:GetRegions() }; + for _, child in ipairs(subregions) do + + if (type (child.GetText) == "function") then + local ftext = child:GetText(); + local fname = tostring(child:GetName()); + + if (ftext and ftext ~= "" and not Atr_excludes[ftext] and not zc.StringStartsWith (fname, "AuctionatorEntry")) then + testt[ftext] = 1; + child:SetText (ZT(ftext)); + end + end + end + + local kids = { frame:GetChildren() }; + for _, child in ipairs(kids) do + + if (type (child.GetText) == "function") then + local ftext = child:GetText(); + local fname = tostring(child:GetName()); + + if (ftext and ftext ~= "" and not Atr_excludes[ftext] and not zc.StringStartsWith (fname, "AuctionatorEntry")) then + testt[ftext] = 1; + + if (child:GetObjectType() == "Button") then + local oldwid = math.floor(child:GetWidth()); + child:SetText (ZT(ftext)); + local newwid = math.floor(child:GetTextWidth()) + 15; + if (newwid > oldwid) then + child:SetWidth (newwid+20); + end + else + child:SetText (ZT(ftext)); + end + end + end + + if (child:GetObjectType() ~= "Button") then + Atr_LocalizeChildText (child); + end + end + +end + +----------------------------------------- + +function Atr_LocalizeFrames () + + -- the 3.x port walked every frame with EnumerateFrames() to translate it; the 1.12 client has no + -- such call and this build ships English text only, so there is nothing to do. + +end + +----------------------------------------- + +local kUncutGems = { + 36924, -- sky sapphire + 36925, -- majestic zircon + + 36918, -- scarlet ruby + 36919, -- cardinal ruby + + 36933, -- forest emerald + 36934, -- eye of zul + + 36930, -- monarch topaz + 36931, -- ametrine + + 36927, -- twilight opal + 36928, -- dreadstone + + 36921, -- autumns glow + 36922, -- kings amber + + 41334, -- earthsiege diamond + 41266, -- skyflare diamond + + 42225 -- dragon's eye + } + +----------------------------------------- + +function Atr_IsCutGem (itemLink) return false; end +function Atr_IsGlyph (itemLink) return false; end +function Atr_IsGem (itemLink) return false; end +function Atr_IsItemEnhancement (itemLink) return false; end + +local function Atr_IsTypeAndSub (itemLink, wantType, wantSub) + + if (itemLink == nil) then + return false; + end + + local _, _, _, _, _, itemType, itemSubType = Atr_GetItemInfo (itemLink); + + return (itemType ~= nil and itemSubType ~= nil and zc.StringSame (itemType, wantType) and zc.StringSame (itemSubType, wantSub)); +end + +function Atr_IsPotion (itemLink) return Atr_IsTypeAndSub (itemLink, "Consumable", "Potion"); end +function Atr_IsElixir (itemLink) return Atr_IsTypeAndSub (itemLink, "Consumable", "Elixir"); end +function Atr_IsFlask (itemLink) return Atr_IsTypeAndSub (itemLink, "Consumable", "Flask"); end +function Atr_IsHerb (itemLink) return Atr_IsTypeAndSub (itemLink, "Trade Goods", "Herb"); end + +----------------------------------------- + +local gItemClasses; +local gItemSubClasses; + +----------------------------------------- +-- if Blizz introduces new auction classes this might need to change + +function Atr_IsWeaponType (itemType) return (Atr_ItemType2AuctionClass (itemType) == 1); end +function Atr_IsArmorType (itemType) return (Atr_ItemType2AuctionClass (itemType) == 2); end + +----------------------------------------- + +function Atr_IsClass (itemLink, class, subclass) + + if (itemLink == nil) then + return false; + end + + local _, _, _, _, _, itemType, itemSubType = Atr_GetItemInfo (itemLink); + + local itemClass = Atr_ItemType2AuctionClass (itemType); + local itemSubClass; + + if (itemClass == class) then + + if (subclass == nil) then + return true; + end + + itemSubClass = Atr_SubType2AuctionSubclass (itemClass, itemSubType) + + if (subclass == itemSubClass) then + return true; + end + end + + return false; +end + +----------------------------------------- + +function Atr_ItemType2AuctionClass(itemType) + + if (gItemClasses == nil) then + gItemClasses = { GetAuctionItemClasses() }; + end + + if getn(gItemClasses) > 0 then + local itemClass; + for x, itemClass in pairs(gItemClasses) do + if (zc.StringSame (itemClass, itemType)) then + return x; + end + end + end + + return 0; +end + + +----------------------------------------- + +function Atr_SubType2AuctionSubclass(auctionClass, itemSubtype) + + if (gItemSubClasses == nil) then + gItemSubClasses = {}; + end + + if (gItemSubClasses[auctionClass] == nil) then + gItemSubClasses[auctionClass] = { GetAuctionItemSubClasses(auctionClass) }; + end + + local subclasses = gItemSubClasses[auctionClass]; + + if getn(subclasses) > 0 then + local itemSubClass; + for x, itemSubClass in pairs(subclasses) do + if (zc.StringSame (itemSubClass, itemSubtype)) then + return x; + end + end + end + + return 0; +end + + diff --git a/AuctionatorOptions.lua b/AuctionatorOptions.lua new file mode 100644 index 0000000..e9eb5c9 --- /dev/null +++ b/AuctionatorOptions.lua @@ -0,0 +1,118 @@ +-- AuctionatorOptions.lua: the 3.x options panels lived in the Interface Options window, which 1.12 does not have. +-- The panels themselves (AuctionatorConfig.xml) are reused; this file hosts them in one standalone window. + +local TAB_ORDER = { "Atr_BasicOptionsFrame", "Atr_TooltipsOptionsFrame", "Atr_UCConfigFrame", + "Atr_StackingOptionsFrame", "Atr_ScanningOptionsFrame", "AuctionatorDescriptionFrame" } + +local tabButtons = {} +local selected = 1 + +local function SelectTab(index) + + selected = index + + for i = 1, getn(TAB_ORDER) do + local panel = getglobal(TAB_ORDER[i]) + if panel then + if i == index then panel:Show() else panel:Hide() end + end + local b = tabButtons[i] + if b then + if i == index then b:Disable() else b:Enable() end + end + end + + if Atr_MemorizeFrame then Atr_MemorizeFrame:Hide() end +end + +local function SaveAll() + + for i = 1, getn(TAB_ORDER) do + local panel = getglobal(TAB_ORDER[i]) + if panel and type(panel.okay) == "function" then + panel.okay() + end + end + + Atr_OptionsWindow:Hide() +end + +local function Build() + + if Atr_OptionsWindow then return end + + local f = CreateFrame("Frame", "Atr_OptionsWindow", UIParent) + f:SetWidth(480) + f:SetHeight(470) + f:SetPoint("CENTER", UIParent, "CENTER", 0, 20) + f:SetFrameStrata("DIALOG") + f:SetToplevel(true) + f:EnableMouse(true) + f:SetMovable(true) + f:RegisterForDrag("LeftButton") + f:SetScript("OnDragStart", function() this:StartMoving() end) + f:SetScript("OnDragStop", function() this:StopMovingOrSizing() end) + f:SetBackdrop({ bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background", + edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border", tile = true, tileSize = 32, edgeSize = 32, + insets = { left = 11, right = 12, top = 12, bottom = 11 } }) + f:Hide() + tinsert(UISpecialFrames, "Atr_OptionsWindow") + + local title = f:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge") + title:SetPoint("TOP", f, "TOP", 0, -18) + title:SetText("OctoAuctionator") + + local labels = { "Basic", "Tooltips", "Undercut", "Selling", "Scanning", "About" } + local x = 20 + for i = 1, getn(TAB_ORDER) do + local b = CreateFrame("Button", "Atr_OptionsTab" .. i, f, "UIPanelButtonTemplate") + b:SetWidth(70) + b:SetHeight(20) + b:SetPoint("TOPLEFT", f, "TOPLEFT", x, -44) + b:SetText(labels[i]) + local idx = i + b:SetScript("OnClick", function() SelectTab(idx) end) + tabButtons[i] = b + x = x + 72 + end + + for i = 1, getn(TAB_ORDER) do + local panel = getglobal(TAB_ORDER[i]) + if panel then + panel:SetParent(f) + panel:ClearAllPoints() + panel:SetPoint("TOPLEFT", f, "TOPLEFT", 14, -70) + panel:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -14, 50) + panel:SetFrameLevel(f:GetFrameLevel() + 2) + end + end + + local okay = CreateFrame("Button", "Atr_OptionsOkay", f, "UIPanelButtonTemplate") + okay:SetWidth(90) + okay:SetHeight(22) + okay:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -108, 18) + okay:SetText("Okay") + okay:SetScript("OnClick", SaveAll) + + local cancel = CreateFrame("Button", "Atr_OptionsCancel", f, "UIPanelButtonTemplate") + cancel:SetWidth(90) + cancel:SetHeight(22) + cancel:SetPoint("LEFT", okay, "RIGHT", 4, 0) + cancel:SetText("Cancel") + cancel:SetScript("OnClick", function() + if Atr_Options_Cancel then Atr_Options_Cancel() end + f:Hide() + end) +end + +function Atr_ShowOptions() + + if AUCTIONATOR_SAVEDVARS == nil then Atr_ResetSavedVars() end + + Build() + + if Atr_InitOptionsPanels then Atr_InitOptionsPanels() end + + SelectTab(selected) + Atr_OptionsWindow:Show() +end