Advertisement
Sinthed

Untitled

Jan 27th, 2024
15
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 60.47 KB | None | 0 0
  1. local EV = LibStub("AceAddon-3.0"):NewAddon("ExtVendor", "AceTimer-3.0")
  2.  
  3. EXTVENDOR_VERSION = GetAddOnMetadata("ExtVendor", "Version");
  4. EXTVENDOR_VERSION_ID = 10502;
  5. EXTVENDOR_ITEMS_PER_SUBPAGE = MERCHANT_ITEMS_PER_PAGE; -- transfer original page size to become "sub-pages"
  6. EXTVENDOR_SUBPAGES_PER_PAGE = 2; -- number of sub-pages per page
  7. MERCHANT_ITEMS_PER_PAGE = 20; -- overrides default value of base ui, default functions will handle page display accordingly
  8. EXTVENDOR_HOOKS = {};
  9. EXTVENDOR_DATA = {};
  10. EXTVENDOR_PROFILE = "";
  11. EXTVENDOR_SELECTED_QUALITY = 0;
  12. EXTVENDOR_SPECIFIC_QUALITY = false;
  13.  
  14. local L = LibStub("AceLocale-3.0"):GetLocale("ExtVendor", true);
  15.  
  16. local EXTVENDOR_NUM_PAGES = 1;
  17. local SLOT_FILTER_INDEX = 0;
  18. local STAT_FILTER_INDEX = 0;
  19.  
  20. EXTVENDOR_ARMOR_RANKS = {
  21. [L["ARMOR_CLOTH"]] = 1,
  22. [L["ARMOR_LEATHER"]] = 2,
  23. [L["ARMOR_MAIL"]] = 3,
  24. [L["ARMOR_PLATE"]] = 4,
  25. };
  26.  
  27. local SLOT_FILTERS = {
  28. [1] = {"INVTYPE_HEAD", "INVTYPE_SHOULDER", "INVTYPE_CLOAK", "INVTYPE_CHEST", "INVTYPE_ROBE", "INVTYPE_WRIST", "INVTYPE_HAND", "INVTYPE_WAIST", "INVTYPE_LEGS", "INVTYPE_FEET"},
  29. [2] = {"INVTYPE_HEAD"},
  30. [3] = {"INVTYPE_SHOULDER"},
  31. [4] = {"INVTYPE_CLOAK"},
  32. [5] = {"INVTYPE_CHEST", "INVTYPE_ROBE"},
  33. [6] = {"INVTYPE_WRIST"},
  34. [7] = {"INVTYPE_HAND"},
  35. [8] = {"INVTYPE_WAIST"},
  36. [9] = {"INVTYPE_LEGS"},
  37. [10] = {"INVTYPE_FEET"},
  38.  
  39. [20] = {"INVTYPE_NECK", "INVTYPE_BODY", "INVTYPE_TABARD", "INVTYPE_FINGER", "INVTYPE_TRINKET"},
  40. [21] = {"INVTYPE_NECK"},
  41. [22] = {"INVTYPE_BODY"},
  42. [23] = {"INVTYPE_TABARD"},
  43. [24] = {"INVTYPE_FINGER"},
  44. [25] = {"INVTYPE_TRINKET"},
  45.  
  46. [30] = {"INVTYPE_WEAPON", "INVTYPE_WEAPONMAINHAND", "INVTYPE_WEAPONTWOHAND", "INVTYPE_WEAPONOFFHAND", "INVTYPE_RANGED", "INVTYPE_RANGEDRIGHT"},
  47. [31] = {"INVTYPE_WEAPON", "INVTYPE_WEAPONMAINHAND"},
  48. [32] = {"INVTYPE_WEAPONTWOHAND"},
  49. [33] = {"INVTYPE_WEAPONOFFHAND"},
  50. [34] = {"INVTYPE_RANGED", "INVTYPE_RANGEDRIGHT"},
  51.  
  52. [40] = {"INVTYPE_HOLDABLE", "INVTYPE_SHIELD"},
  53. [41] = {"INVTYPE_HOLDABLE"},
  54. [42] = {"INVTYPE_SHIELD"},
  55. };
  56.  
  57. local STAT_FILTERS = {
  58. [1] = {"ITEM_MOD_STRENGTH_SHORT", "ITEM_MOD_STRENGTH_SHORT", "ITEM_MOD_AGILITY_SHORT", "ITEM_MOD_INTELLECT_SHORT", "ITEM_MOD_SPIRIT_SHORT"},
  59. [2] = {"ITEM_MOD_STRENGTH_SHORT"},
  60. [3] = {"ITEM_MOD_AGILITY_SHORT"},
  61. [4] = {"ITEM_MOD_INTELLECT_SHORT"},
  62. [5] = {"ITEM_MOD_SPIRIT_SHORT"},
  63.  
  64. [6] = {"ITEM_MOD_ATTACK_POWER_SHORT", "ITEM_MOD_SPELL_POWER_SHORT", "ITEM_MOD_CRIT_RATING_SHORT", "ITEM_MOD_HIT_RATING_SHORT", "ITEM_MOD_HASTE_RATING_SHORT", "ITEM_MOD_EXPERTISE_RATING_SHORT", "ITEM_MOD_ARMOR_PENETRATION_RATING_SHORT", "ITEM_MOD_SPELL_PENETRATION_SHORT"},
  65. [7] = {"ITEM_MOD_ATTACK_POWER_SHORT"},
  66. [8] = {"ITEM_MOD_SPELL_POWER_SHORT"},
  67. [9] = {"ITEM_MOD_CRIT_RATING_SHORT"},
  68. [10] = {"ITEM_MOD_HIT_RATING_SHORT"},
  69. [11] = {"ITEM_MOD_HASTE_RATING_SHORT"},
  70. [12] = {"ITEM_MOD_EXPERTISE_RATING_SHORT"},
  71. [13] = {"ITEM_MOD_ARMOR_PENETRATION_RATING_SHORT"},
  72. [14] = {"ITEM_MOD_SPELL_PENETRATION_SHORT"},
  73.  
  74. [15] = {"ITEM_MOD_DEFENSE_SKILL_RATING_SHORT", "ITEM_MOD_DODGE_RATING_SHORT", "ITEM_MOD_PARRY_RATING_SHORT", "ITEM_MOD_BLOCK_RATING_SHORT", "ITEM_MOD_BLOCK_VALUE_SHORT", "ITEM_MOD_RESILIENCE_RATING"},
  75. [16] = {"ITEM_MOD_DEFENSE_SKILL_RATING_SHORT"},
  76. [17] = {"ITEM_MOD_DODGE_RATING_SHORT"},
  77. [18] = {"ITEM_MOD_PARRY_RATING_SHORT"},
  78. [19] = {"ITEM_MOD_BLOCK_RATING_SHORT"},
  79. [20] = {"ITEM_MOD_BLOCK_VALUE_SHORT"},
  80. [21] = {"ITEM_MOD_RESILIENCE_RATING"}
  81. }
  82. --========================================
  83. -- Initial load routine
  84. --========================================
  85. function ExtVendor_OnLoad(self)
  86.  
  87. ExtVendor_RebuildMerchantFrame();
  88.  
  89. ExtVendor_UpdateButtonPositions();
  90.  
  91. EXTVENDOR_HOOKS["MerchantFrame_UpdateMerchantInfo"] = MerchantFrame_UpdateMerchantInfo;
  92. MerchantFrame_UpdateMerchantInfo = ExtVendor_UpdateMerchantInfo;
  93. EXTVENDOR_HOOKS["MerchantFrame_UpdateBuybackInfo"] = MerchantFrame_UpdateBuybackInfo;
  94. MerchantFrame_UpdateBuybackInfo = ExtVendor_UpdateBuybackInfo;
  95.  
  96. MerchantFrame:HookScript("OnShow", ExtVendor_OnShow);
  97. MerchantFrame:HookScript("OnHide", ExtVendor_OnHide);
  98.  
  99. self:RegisterEvent("ADDON_LOADED");
  100.  
  101. SLASH_EXTVENDOR1 = "/evui";
  102. SlashCmdList["EXTVENDOR"] = ExtVendor_CommandHandler;
  103.  
  104. end
  105.  
  106. local function ExtVendor_AutoSell_Junk()
  107. if EXTVENDOR_DATA.config.enable_quickvendor_auto then
  108. ExtVendor_ConfirmQuickVendor()
  109. end
  110. end
  111.  
  112. --========================================
  113. -- Hooked merchant frame OnShow
  114. --========================================
  115. function ExtVendor_OnShow(self)
  116. if EXTVENDOR_DATA['config']['hide_default_vendor_auto_sell'] then
  117. MerchantFrameSellJunkFrameAutoSellCheck:Hide()
  118. else
  119. MerchantFrameSellJunkFrameAutoSellCheck:Show()
  120. end
  121. MerchantFrameSearchBox:SetText("");
  122. --[[ if (EXTVENDOR_DATA['config']['stockfilter_defall']) then
  123. SetMerchantFilter(LE_LOOT_FILTER_ALL);
  124. end ]]
  125. ExtVendor_SetMinimumQuality(0);
  126. ExtVendor_SetSlotFilter(0);
  127. ExtVendor_AutoSell_Junk();
  128. end
  129.  
  130. --========================================
  131. -- Hooked merchant frame OnHide
  132. --========================================
  133. function ExtVendor_OnHide(self)
  134.  
  135. CloseDropDownMenus();
  136.  
  137. end
  138.  
  139. --========================================
  140. -- Event handler
  141. --========================================
  142. function ExtVendor_OnEvent(self, event, ...)
  143.  
  144. if (event == "ADDON_LOADED") then
  145. local arg1 = ...;
  146. if (arg1 == "ExtVendor") then
  147. ExtVendor_Setup();
  148. end
  149. end
  150.  
  151. end
  152.  
  153. --========================================
  154. -- Post-load setup
  155. --========================================
  156. function ExtVendor_Setup()
  157.  
  158. EXTVENDOR_PROFILE = GetRealmName() .. "." .. UnitName("player");
  159.  
  160. local version = ExtVendor_CheckSetting("version", EXTVENDOR_VERSION_ID);
  161.  
  162. EXTVENDOR_DATA['config']['version'] = EXTVENDOR_VERSION_ID;
  163.  
  164. ExtVendor_CheckSetting("hide_filtered", false);
  165. ExtVendor_CheckSetting("hide_known_recipes", false);
  166. ExtVendor_CheckSetting("hide_known_ascension_collection_items", false);
  167. ExtVendor_CheckSetting("stockfilter_defall", false);
  168. ExtVendor_CheckSetting("show_load_message", false);
  169. ExtVendor_CheckSetting("mousewheel_paging", true);
  170. ExtVendor_CheckSetting("enable_quickvendor", true);
  171. ExtVendor_CheckSetting("enable_quickvendor_auto", true);
  172. ExtVendor_CheckSetting("scale", 1);
  173. ExtVendor_CheckSetting("filter_purchased_recipes", true);
  174.  
  175. ExtVendor_CheckSetting("quickvendor_alreadyknown", false);
  176. ExtVendor_CheckSetting("quickvendor_whitegear", false);
  177.  
  178. if (EXTVENDOR_DATA['config']['show_load_message']) then
  179. ExtVendor_Message(string.format(L["LOADED_MESSAGE"], EXTVENDOR_VERSION));
  180. end
  181.  
  182. -- initialize the customizable blacklist
  183. if (not EXTVENDOR_DATA['quickvendor_blacklist']) then
  184. EXTVENDOR_DATA['quickvendor_blacklist'] = EXTVENDOR_QUICKVENDOR_DEFAULT_BLACKLIST;
  185. end
  186. -- initialize global whitelist
  187. if (not EXTVENDOR_DATA['quickvendor_whitelist']) then
  188. EXTVENDOR_DATA['quickvendor_whitelist'] = {};
  189. end
  190.  
  191. if (not EXTVENDOR_DATA[EXTVENDOR_PROFILE]) then
  192. EXTVENDOR_DATA[EXTVENDOR_PROFILE] = {};
  193. end
  194.  
  195. -- initialize per-character whitelist
  196. if (not EXTVENDOR_DATA[EXTVENDOR_PROFILE]['quickvendor_whitelist']) then
  197. EXTVENDOR_DATA[EXTVENDOR_PROFILE]['quickvendor_whitelist'] = {};
  198. end
  199.  
  200. ExtVendor_UpdateMouseScrolling();
  201. ExtVendor_UpdateQuickVendorButtonVisibility();
  202.  
  203. end
  204.  
  205. --========================================
  206. -- Check configuration setting, and
  207. -- initialize with default value if not
  208. -- present
  209. --========================================
  210. function ExtVendor_CheckSetting(field, default)
  211.  
  212. if (not EXTVENDOR_DATA['config']) then
  213. EXTVENDOR_DATA['config'] = {};
  214. end
  215. if (EXTVENDOR_DATA['config'][field] == nil) then
  216. EXTVENDOR_DATA['config'][field] = default;
  217. end
  218. return EXTVENDOR_DATA['config'][field];
  219. end
  220.  
  221. --========================================
  222. -- Rearrange item slot positions
  223. --========================================
  224. function ExtVendor_UpdateButtonPositions(isBuyBack)
  225.  
  226. local btn;
  227. local vertSpacing, horizSpacing;
  228.  
  229. if (isBuyBack) then
  230. vertSpacing = -30;
  231. horizSpacing = 50;
  232. else
  233. vertSpacing = -16;
  234. horizSpacing = 12;
  235. end
  236. for i = 1, MERCHANT_ITEMS_PER_PAGE, 1 do
  237. btn = _G["MerchantItem" .. i];
  238. if (isBuyBack) then
  239. if (i > BUYBACK_ITEMS_PER_PAGE) then
  240. btn:Hide();
  241. else
  242. if (i == 1) then
  243. btn:SetPoint("TOPLEFT", MerchantFrame, "TOPLEFT", 64, -105);
  244. else
  245. if ((i % 3) == 1) then
  246. btn:SetPoint("TOPLEFT", _G["MerchantItem" .. (i - 3)], "BOTTOMLEFT", 0, vertSpacing);
  247. else
  248. btn:SetPoint("TOPLEFT", _G["MerchantItem" .. (i - 1)], "TOPRIGHT", horizSpacing, 0);
  249. end
  250. end
  251. end
  252. else
  253. btn:Show();
  254. if ((i % EXTVENDOR_ITEMS_PER_SUBPAGE) == 1) then
  255. if (i == 1) then
  256. btn:SetPoint("TOPLEFT", MerchantFrame, "TOPLEFT", 34, -82);
  257. else
  258. btn:SetPoint("TOPLEFT", _G["MerchantItem" .. (i - (EXTVENDOR_ITEMS_PER_SUBPAGE - 1))], "TOPRIGHT", 12, 0);
  259. end
  260. else
  261. if ((i % 2) == 1) then
  262. btn:SetPoint("TOPLEFT", _G["MerchantItem" .. (i - 2)], "BOTTOMLEFT", 0, vertSpacing);
  263. else
  264. btn:SetPoint("TOPLEFT", _G["MerchantItem" .. (i - 1)], "TOPRIGHT", horizSpacing, 0);
  265. end
  266. end
  267. end
  268. end
  269.  
  270. end
  271. local numButtons = 0
  272. --========================================
  273. -- Show merchant page
  274. --========================================
  275. function ExtVendor_UpdateMerchantInfo()
  276. EXTVENDOR_HOOKS["MerchantFrame_UpdateMerchantInfo"]();
  277. ExtVendor_UpdateButtonPositions();
  278.  
  279. -- set title and portrait
  280. MerchantNameText:SetText(UnitName("NPC"));
  281. SetPortraitTexture(MerchantFramePortrait, "NPC");
  282.  
  283. -- locals
  284. local totalMerchantItems = GetMerchantNumItems();
  285. local visibleMerchantItems = 0;
  286. local indexes = {};
  287. local search = string.trim(MerchantFrameSearchBox:GetText());
  288. local name, texture, price, quantity, numAvailable, isUsable, extendedCost, r, g, b, notOptimal;
  289. local link, quality, itemType, itemId, itemEquipLoc;
  290. local isFiltered = false;
  291. local isBoP = false;
  292. local isKnown = false;
  293. local isCollectionItemKnow = false;
  294.  
  295. -- **************************************************
  296. -- Pre-check filtering if hiding filtered items
  297. -- **************************************************
  298. if (EXTVENDOR_DATA['config']['hide_filtered']) then
  299. visibleMerchantItems = 0;
  300. for i = 1, totalMerchantItems, 1 do
  301. name, texture, price, quantity, numAvailable, isUsable, extendedCost = GetMerchantItemInfo(i);
  302. if (name) then
  303. isFiltered = false;
  304. link = GetMerchantItemLink(i);
  305. quality = 1;
  306. isKnown = false;
  307. isBoP = false;
  308. isCollectionItemKnow = false;
  309.  
  310. -- get info from item link
  311. if (link) then
  312. isBoP, isKnown = ExtVendor_GetExtendedItemInfo(link);
  313. itemId = ExtVendor_GetItemID(link);
  314. isCollectionItemKnow = C_VanityCollection.IsCollectionItemOwned(itemId);
  315. _, _, quality, _, _, itemType, _, _, itemEquipLoc, _, _ = GetItemInfo(link);
  316. end
  317. -- filter known recipes
  318. if (EXTVENDOR_DATA['config']['hide_known_recipes'] and isKnown) then
  319. isFiltered = true;
  320. end
  321. -- filter known skill cards
  322. if (EXTVENDOR_DATA['config']['hide_known_ascension_collection_items'] and isCollectionItemKnow) then
  323. isFiltered = true;
  324. end
  325. -- filter purchased recipes
  326. if (EXTVENDOR_DATA['config']['filter_purchased_recipes']) then
  327. if (itemType == L["ITEMTYPE_RECIPE"]) then
  328. if (ExtVendor_HasItemInBags(itemId) > 0) then
  329. isFiltered = true;
  330. end
  331. end
  332. end
  333. -- check search filter
  334. if (string.len(search) > 0) then
  335. if (not string.find(string.lower(name), string.lower(search), 1, true)) then
  336. isFiltered = true;
  337. end
  338. end
  339. -- check quality filter
  340. if (EXTVENDOR_SELECTED_QUALITY > 0) then
  341. if ((quality < EXTVENDOR_SELECTED_QUALITY) or ((quality > EXTVENDOR_SELECTED_QUALITY) and EXTVENDOR_SPECIFIC_QUALITY)) then
  342. isFiltered = true;
  343. end
  344. end
  345.  
  346. -- check slot filter
  347. if (SLOT_FILTER_INDEX > 0) then
  348. if (SLOT_FILTERS[SLOT_FILTER_INDEX]) then
  349. local validSlot = false;
  350. for _, slot in pairs(SLOT_FILTERS[SLOT_FILTER_INDEX]) do
  351. if (slot == itemEquipLoc) then
  352. validSlot = true;
  353. end
  354. end
  355. if (not validSlot) then
  356. isFiltered = true;
  357. end
  358. end
  359. end
  360.  
  361. -- check stat filter
  362. if (STAT_FILTER_INDEX > 0) then
  363. if (STAT_FILTERS[STAT_FILTER_INDEX]) and link then
  364. local ItemStats = {};
  365. GetItemStats(link, ItemStats);
  366. local validSlot = false;
  367. for _, slot in pairs(STAT_FILTERS[STAT_FILTER_INDEX]) do
  368. if (ItemStats[slot]) then
  369. validSlot = true;
  370. end
  371. end
  372. if (not validSlot) then
  373. isFiltered = true;
  374. end
  375. end
  376. end
  377.  
  378. -- ***** add item to list if not filtered *****
  379. if (not isFiltered) then
  380. table.insert(indexes, i);
  381. visibleMerchantItems = visibleMerchantItems + 1;
  382. end
  383. end
  384. end
  385. else
  386. -- no item hiding, add all items to list
  387. visibleMerchantItems = totalMerchantItems;
  388. for i = 1, totalMerchantItems, 1 do
  389. table.insert(indexes, i);
  390. end
  391. end
  392.  
  393. -- validate current page shown
  394. if (MerchantFrame.page > math.max(1, math.ceil(visibleMerchantItems / MERCHANT_ITEMS_PER_PAGE))) then
  395. MerchantFrame.page = math.max(1, math.ceil(visibleMerchantItems / MERCHANT_ITEMS_PER_PAGE));
  396. end
  397.  
  398. -- Show correct page count based on number of items shown
  399. MerchantPageText:SetFormattedText(MERCHANT_PAGE_NUMBER, MerchantFrame.page, math.ceil(visibleMerchantItems / MERCHANT_ITEMS_PER_PAGE));
  400.  
  401. -- **************************************************
  402. -- Display items on merchant page
  403. -- **************************************************
  404. local isAltCurrency = {}
  405.  
  406. if numButtons then
  407. for i = 1, numButtons, 1 do
  408. _G["MerchantFrame_AltCurrency"..i]:Hide()
  409. _G["MerchantFrame_AltCurrency_Icon"..i]:Hide()
  410. end
  411. end
  412.  
  413. for i = 1, MERCHANT_ITEMS_PER_PAGE, 1 do
  414. local index = ((MerchantFrame.page - 1) * MERCHANT_ITEMS_PER_PAGE) + i;
  415. local itemButton = _G["MerchantItem" .. i .. "ItemButton"];
  416. itemButton.link = nil;
  417. local merchantButton = _G["MerchantItem" .. i];
  418. local merchantMoney = _G["MerchantItem" .. i .. "MoneyFrame"];
  419. local merchantAltCurrency = _G["MerchantItem" .. i .. "AltCurrencyFrame"];
  420.  
  421. if (index <= visibleMerchantItems) then
  422. name, texture, price, quantity, numAvailable, isUsable, extendedCost = GetMerchantItemInfo(indexes[index]);
  423. if (name ~= nil) then
  424. _G["MerchantItem"..i.."Name"]:SetText(name);
  425. SetItemButtonCount(itemButton, quantity);
  426. SetItemButtonStock(itemButton, numAvailable);
  427. SetItemButtonTexture(itemButton, texture);
  428. local honorPoints, arenaPoints = GetMerchantItemCostInfo(i);
  429. -- update item's currency info
  430. if ( extendedCost and (price <= 0) ) then
  431. itemButton.price = nil;
  432. itemButton.extendedCost = true;
  433. itemButton.link = GetMerchantItemLink(indexes[index]);
  434. itemButton.texture = texture;
  435. MerchantFrame_UpdateAltCurrency(indexes[index], i);
  436. merchantAltCurrency:ClearAllPoints();
  437. merchantAltCurrency:SetPoint("BOTTOMLEFT", "MerchantItem"..i.."NameFrame", "BOTTOMLEFT", 0, 31);
  438. merchantMoney:Hide();
  439. merchantAltCurrency:Show();
  440. if honorPoints > 0 then
  441. isAltCurrency.honor = {"honor", true, "honor"}
  442. elseif arenaPoints > 0 then
  443. isAltCurrency.arena = {"arena", true, "arena"}
  444. elseif _G["MerchantItem" .. i .. "AltCurrencyFrameItem1"].itemLink then
  445. local _, id = strsplit(":", _G["MerchantItem" .. i .. "AltCurrencyFrameItem1"].itemLink)
  446. isAltCurrency[id] = {id}
  447. end
  448. elseif ( extendedCost and (price > 0) ) then
  449. itemButton.price = price;
  450. itemButton.extendedCost = true;
  451. itemButton.link = GetMerchantItemLink(indexes[index]);
  452. itemButton.texture = texture;
  453. MerchantFrame_UpdateAltCurrency(indexes[index], i);
  454. MoneyFrame_Update(merchantMoney:GetName(), price);
  455. merchantAltCurrency:ClearAllPoints();
  456. merchantAltCurrency:SetPoint("LEFT", merchantMoney:GetName(), "RIGHT", -14, 0);
  457. merchantAltCurrency:Show();
  458. merchantMoney:Show();
  459. if honorPoints > 0 then
  460. isAltCurrency.honor = {"honor", true, "honor"}
  461. elseif arenaPoints > 0 then
  462. isAltCurrency.arena = {"arena", true, "arena"}
  463. elseif _G["MerchantItem" .. i .. "AltCurrencyFrameItem1"].itemLink then
  464. local _, id = strsplit(":", _G["MerchantItem" .. i .. "AltCurrencyFrameItem1"].itemLink)
  465. isAltCurrency[id] = {id}
  466. end
  467. else
  468. itemButton.price = price;
  469. itemButton.extendedCost = nil;
  470. itemButton.link = GetMerchantItemLink(indexes[index]);
  471. itemButton.texture = texture;
  472. MoneyFrame_Update(merchantMoney:GetName(), price);
  473. merchantAltCurrency:Hide();
  474. merchantMoney:Show();
  475. end
  476.  
  477. isBoP = false;
  478. isKnown = false;
  479. isFiltered = false;
  480. isCollectionItemKnow = false;
  481.  
  482. quality = 1;
  483. if (itemButton.link) then
  484. isBoP, isKnown = ExtVendor_GetExtendedItemInfo(itemButton.link);
  485. itemId = ExtVendor_GetItemID(itemButton.link);
  486. isCollectionItemKnow = C_VanityCollection.IsCollectionItemOwned(itemId);
  487. _, _, quality, _, _, itemType, itemSubType, _, itemEquipLoc, _, _ = GetItemInfo(itemButton.link);
  488. end
  489.  
  490. -- set color
  491. r, g, b = GetItemQualityColor(quality);
  492. _G["MerchantItem" .. i .. "Name"]:SetTextColor(r, g, b);
  493.  
  494. -- check filtering
  495. if (not EXTVENDOR_DATA['config']['hide_filtered']) then
  496. -- check search filter
  497. if (string.len(search) > 0) then
  498. if (not string.find(string.lower(name), string.lower(search), 1, true)) then
  499. isFiltered = true;
  500. end
  501. end
  502. -- check quality filter
  503. if (EXTVENDOR_SELECTED_QUALITY > 0) then
  504. if ((quality < EXTVENDOR_SELECTED_QUALITY) or ((quality > EXTVENDOR_SELECTED_QUALITY) and EXTVENDOR_SPECIFIC_QUALITY)) then
  505. isFiltered = true;
  506. end
  507. end
  508. -- filter known recipes
  509. if (EXTVENDOR_DATA['config']['hide_known_recipes'] and isKnown) then
  510. isFiltered = true;
  511. end
  512. -- filter known skill cards
  513. if (EXTVENDOR_DATA['config']['hide_known_ascension_collection_items'] and isCollectionItemKnow) then
  514. isFiltered = true;
  515. end
  516. -- filter purchased recipes
  517. if (EXTVENDOR_DATA['config']['filter_purchased_recipes']) then
  518. if (itemType == L["ITEMTYPE_RECIPE"]) then
  519. if (ExtVendor_HasItemInBags(itemId) > 0) then
  520. isFiltered = true;
  521. end
  522. end
  523. end
  524. -- check slot filter
  525. if (SLOT_FILTER_INDEX > 0) then
  526. if (SLOT_FILTERS[SLOT_FILTER_INDEX]) then
  527. local validSlot = false;
  528. for _, slot in pairs(SLOT_FILTERS[SLOT_FILTER_INDEX]) do
  529. if (slot == itemEquipLoc) then
  530. validSlot = true;
  531. end
  532. end
  533. if (not validSlot) then
  534. isFiltered = true;
  535. end
  536. end
  537. end
  538.  
  539. -- check stat filter
  540. if (STAT_FILTER_INDEX > 0) then
  541. if (STAT_FILTERS[STAT_FILTER_INDEX]) and itemButton.link then
  542. local ItemStats = {};
  543. GetItemStats(itemButton.link, ItemStats);
  544. local validSlot = false;
  545. for _, slot in pairs(STAT_FILTERS[STAT_FILTER_INDEX]) do
  546. if (ItemStats[slot]) then
  547. validSlot = true;
  548. end
  549. end
  550. if (not validSlot) then
  551. isFiltered = true;
  552. end
  553. end
  554. end
  555. end
  556.  
  557. ExtVendor_SearchDimItem(_G["MerchantItem" .. i], isFiltered);
  558.  
  559. itemButton.hasItem = true;
  560. itemButton:SetID(indexes[index]);
  561. itemButton:Show();
  562. local colorMult = 1.0;
  563. local detailColor = {};
  564. local slotColor = {};
  565. -- unavailable items (limited stock, bought out) are darkened
  566. if ( numAvailable == 0 ) then
  567. colorMult = 0.5;
  568. end
  569. if ( not isUsable ) then
  570. slotColor = {r = 1.0, g = 0, b = 0};
  571. detailColor = {r = 1.0, g = 0, b = 0};
  572. else
  573. if (notOptimal) then
  574. slotColor = {r = 0.25, g = 0.25, b = 0.25};
  575. detailColor = {r = 0.5, g = 0, b = 0};
  576. else
  577. slotColor = {r = 1.0, g = 1.0, b = 1.0};
  578. detailColor = {r = 0.5, g = 0.5, b = 0.5};
  579. end
  580. end
  581. SetItemButtonNameFrameVertexColor(merchantButton, detailColor.r * colorMult, detailColor.g * colorMult, detailColor.b * colorMult);
  582. SetItemButtonSlotVertexColor(merchantButton, slotColor.r * colorMult, slotColor.g * colorMult, slotColor.b * colorMult);
  583. SetItemButtonTextureVertexColor(itemButton, slotColor.r * colorMult, slotColor.g * colorMult, slotColor.b * colorMult);
  584. SetItemButtonNormalTextureVertexColor(itemButton, slotColor.r * colorMult, slotColor.g * colorMult, slotColor.b * colorMult);
  585. end
  586. else
  587. itemButton.price = nil;
  588. itemButton.hasItem = nil;
  589. itemButton:Hide();
  590. SetItemButtonNameFrameVertexColor(merchantButton, 0.5, 0.5, 0.5);
  591. SetItemButtonSlotVertexColor(merchantButton,0.4, 0.4, 0.4);
  592. _G["MerchantItem"..i.."Name"]:SetText("");
  593. _G["MerchantItem"..i.."MoneyFrame"]:Hide();
  594. _G["MerchantItem"..i.."AltCurrencyFrame"]:Hide();
  595. ExtVendor_SearchDimItem(_G["MerchantItem" .. i], false);
  596. end
  597. end
  598.  
  599. if isAltCurrency then
  600. ExtVendor_UpdateAltCurrency(isAltCurrency)
  601. end
  602. MerchantFrame_UpdateRepairButtons();
  603.  
  604. -- Handle vendor buy back item
  605. local buybackName, buybackTexture, buybackPrice, buybackQuantity, buybackNumAvailable, buybackIsUsable = GetBuybackItemInfo(GetNumBuybackItems());
  606. if ( buybackName ) then
  607. MerchantBuyBackItemName:SetText(buybackName);
  608. SetItemButtonCount(MerchantBuyBackItemItemButton, buybackQuantity);
  609. SetItemButtonStock(MerchantBuyBackItemItemButton, buybackNumAvailable);
  610. SetItemButtonTexture(MerchantBuyBackItemItemButton, buybackTexture);
  611. MerchantBuyBackItemMoneyFrame:Show();
  612. MoneyFrame_Update("MerchantBuyBackItemMoneyFrame", buybackPrice);
  613. MerchantBuyBackItem:Show();
  614. else
  615. MerchantBuyBackItemName:SetText("");
  616. MerchantBuyBackItemMoneyFrame:Hide();
  617. SetItemButtonTexture(MerchantBuyBackItemItemButton, "");
  618. SetItemButtonCount(MerchantBuyBackItemItemButton, 0);
  619. -- Hide the tooltip upon sale
  620. if ( GameTooltip:IsOwned(MerchantBuyBackItemItemButton) ) then
  621. GameTooltip:Hide();
  622. end
  623. end
  624.  
  625. -- Handle paging buttons
  626. if ( visibleMerchantItems > MERCHANT_ITEMS_PER_PAGE ) then
  627. if ( MerchantFrame.page == 1 ) then
  628. MerchantPrevPageButton:Disable();
  629. else
  630. MerchantPrevPageButton:Enable();
  631. end
  632. if ( MerchantFrame.page == ceil(visibleMerchantItems / MERCHANT_ITEMS_PER_PAGE) or visibleMerchantItems == 0) then
  633. MerchantNextPageButton:Disable();
  634. else
  635. MerchantNextPageButton:Enable();
  636. end
  637. EXTVENDOR_NUM_PAGES = ceil(visibleMerchantItems / MERCHANT_ITEMS_PER_PAGE);
  638. MerchantPageText:Show();
  639. MerchantPrevPageButton:Show();
  640. MerchantNextPageButton:Show();
  641. else
  642. EXTVENDOR_NUM_PAGES = 1;
  643. MerchantPageText:Hide();
  644. MerchantPrevPageButton:Hide();
  645. MerchantNextPageButton:Hide();
  646. end
  647.  
  648. -- Show all merchant related items
  649. MerchantBuyBackItem:Show();
  650. MerchantFrameBottomLeftBorder:Show();
  651. MerchantFrameBottomRightBorder:Show();
  652.  
  653. -- Hide buyback related items
  654. for i = 13, MERCHANT_ITEMS_PER_PAGE, 1 do
  655. _G["MerchantItem" .. i]:Show();
  656. end
  657.  
  658. local numHiddenItems = math.max(0, totalMerchantItems - visibleMerchantItems);
  659. local hstring = (numHiddenItems == 1) and L["SINGLE_ITEM_HIDDEN"] or L["MULTI_ITEMS_HIDDEN"];
  660. MerchantFrameHiddenText:SetText(string.format(hstring, numHiddenItems));
  661.  
  662. -- update text color for buyback slot
  663. local link = GetBuybackItemLink(GetNumBuybackItems());
  664. if (link) then
  665. local _, _, quality = GetItemInfo(link);
  666. local r, g, b = GetItemQualityColor(quality);
  667. MerchantBuyBackItemName:SetTextColor(r, g, b);
  668. end
  669.  
  670. if (ExtVendor_GetQuickVendorList()) then
  671. ExtVendor_SetJunkButtonState(true);
  672. else
  673. ExtVendor_SetJunkButtonState(false);
  674. end
  675. end
  676.  
  677. --========================================
  678. -- Show buyback page
  679. --========================================
  680. function ExtVendor_UpdateBuybackInfo()
  681. EXTVENDOR_HOOKS["MerchantFrame_UpdateBuybackInfo"]();
  682. ExtVendor_UpdateButtonPositions(true);
  683. -- apply coloring
  684. local btn, link, quality, r, g, b;
  685. for i = 1, BUYBACK_ITEMS_PER_PAGE, 1 do
  686. btn = _G["MerchantItem" .. i];
  687. if (btn) then
  688. link = GetBuybackItemLink(i);
  689. if (link) then
  690. _, _, quality = GetItemInfo(link);
  691. r, g, b = GetItemQualityColor(quality);
  692. _G["MerchantItem" .. i .. "Name"]:SetTextColor(r, g, b);
  693. end
  694. ExtVendor_SearchDimItem(btn, false);
  695. end
  696. end
  697. end
  698.  
  699. function ExtVendor_PairsByKeys(t)
  700. local a = {}
  701. for n in pairs(t) do
  702. table.insert(a, n)
  703. end
  704. table.sort(a)
  705.  
  706. local i = 0
  707. local iter = function()
  708. i = i + 1
  709. if a[i] == nil then
  710. return nil
  711. else
  712. return a[i], t[a[i]]
  713. end
  714. end
  715. return iter
  716. end
  717.  
  718. local function createAtlCurrencys(num)
  719. if _G["MerchantFrame_AltCurrency"..num] then return _G["MerchantFrame_AltCurrency"..num] end
  720. local altCurrencyFrame = "MerchantFrame_AltCurrency"..num
  721. local altCurrencyFrameIcon = "MerchantFrame_AltCurrency_Icon"..num
  722. local button = CreateFrame("Button", altCurrencyFrame, MerchantFrame)
  723. button:SetSize(100,15)
  724. button.icon = button:CreateTexture(altCurrencyFrameIcon,"ARTWORK");
  725. button.icon:SetSize(13,13);
  726. button.icon:SetPoint("RIGHT", altCurrencyFrame,0,0);
  727. button.Lable = button:CreateFontString(nil, "BORDER", "GameFontNormal");
  728. button.Lable:SetPoint("RIGHT", altCurrencyFrameIcon, -15, 1);
  729. button.Lable:SetJustifyH("RIGHT");
  730. button:SetScript("OnLeave", function () GameTooltip:Hide() end)
  731. button:Hide()
  732. numButtons = numButtons + 1
  733. return _G[altCurrencyFrame]
  734. end
  735.  
  736. local function setTooltip(button)
  737. button:SetScript("OnEnter", function(self)
  738. GameTooltip:SetOwner(self, "ANCHOR_RIGHT", -13, -50)
  739. if tonumber(button.itemID) then
  740. GameTooltip:SetHyperlink(select(2,GetItemInfo(button.itemID)));
  741. else
  742. GameTooltip:AddLine(button.itemID)
  743. end
  744. GameTooltip:Show()
  745. end)
  746. end
  747.  
  748. local function updateCurrency(text, button)
  749. if text == "arena" then
  750. button.Lable:SetText("Arena Points: |cffffffff"..GetArenaCurrency())
  751. else
  752. button.Lable:SetText("Honor Points: |cffffffff"..GetHonorCurrency())
  753. end
  754. end
  755.  
  756. local fac = UnitFactionGroup("player")
  757.  
  758. function ExtVendor_UpdateAltCurrency(currencyTable)
  759. local i = 1
  760. local sorted = {}
  761. for id, v in pairs(currencyTable) do
  762. if id == "honor" or id == "arena" then
  763. sorted[id] = v
  764. else
  765. sorted[GetItemInfo(v[1])] = v
  766. end
  767. end
  768. table.sort(sorted)
  769. for _,currency in ExtVendor_PairsByKeys(sorted) do
  770. if currency[1] then
  771. local button = createAtlCurrencys(i)
  772. if currency[2] and currency[3] == "honor" then
  773. button.itemID = "Honor Points"
  774. button.icon:SetTexture("Interface\\TargetingFrame\\UI-PVP-"..fac);
  775. button.Lable:SetText("Honor Points: |cffffffff"..GetHonorCurrency())
  776. button.icon:SetSize(16,16);
  777. EV:ScheduleTimer(updateCurrency, .2, "honor", button)
  778. elseif currency[2] and currency[3] == "arena" then
  779. button.itemID = "Arena Points"
  780. button.icon:SetTexture("Interface\\PVPFrame\\PVP-ArenaPoints-Icon");
  781. button.Lable:SetText("Arena Points: |cffffffff"..GetArenaCurrency())
  782. button.icon:SetSize(16,16);
  783. EV:ScheduleTimer(updateCurrency, .2, "arena", button)
  784. else
  785. button.itemID = currency[1]
  786. button.icon:SetTexture(GetItemIcon(currency[1]));
  787. button.Lable:SetText("|cffffffff"..GetItemCount(currency[1]))
  788. button.icon:SetSize(13,13);
  789. end
  790. setTooltip(button)
  791. if i == 1 then
  792. button:ClearAllPoints()
  793. button:SetPoint("RIGHT","MerchantMoneyFrameGoldButton", (- MerchantMoneyFrameGoldButtonText:GetStringWidth()) - 20,-1);
  794. else
  795. local lastFrame = i - 1
  796. button:ClearAllPoints()
  797. button:SetPoint("RIGHT",_G["MerchantFrame_AltCurrency"..lastFrame], (- button.Lable:GetStringWidth()) - 20,0);
  798. end
  799. button:SetWidth(button.Lable:GetStringWidth() + 15)
  800. button:Show()
  801. button.icon:Show()
  802. i = i + 1
  803. end
  804. end
  805. end
  806. --========================================
  807. -- Rebuilds the merchant frame into
  808. -- the extended design
  809. --========================================
  810. function ExtVendor_RebuildMerchantFrame()
  811.  
  812. -- set the new width of the frame
  813. if ExtVendor_LastPos then
  814. MerchantFrame:SetPoint(ExtVendor_LastPos);
  815. end
  816.  
  817. MerchantFrame:SetWidth(736);
  818. MerchantFrame:RegisterForDrag("LeftButton");
  819. MerchantFrame:SetScript("OnDragStart", function ()
  820. MerchantFrame:StartMoving();
  821. MerchantFrame.isMoving = true;
  822. end)
  823. MerchantFrame:SetMovable(true);
  824. MerchantFrame:SetScript("OnDragStop", function ()
  825. MerchantFrame:StopMovingOrSizing();
  826. ExtVendor_LastPos = MerchantFrame:GetPoint();
  827. MerchantFrame.isMoving = false;
  828. end)
  829. MerchantRepairSettingsButton:SetPoint("BottomLeft",MerchantFrame,152,111);
  830. -- create new item buttons as needed
  831. for i = 1, MERCHANT_ITEMS_PER_PAGE, 1 do
  832. if (not _G["MerchantItem" .. i]) then
  833. CreateFrame("Frame", "MerchantItem" .. i, MerchantFrame, "MerchantItemTemplate");
  834. end
  835. end
  836.  
  837. -- Thank you Blizzard for making the frame dynamically resizable for me. :D
  838.  
  839. -- retexture the border element around the repair/buyback spots on the merchant tab
  840. MerchantFrameBottomLeftBorder:SetTexture("Interface\\AddOns\\ExtVendor\\textures\\bottomborder");
  841. MerchantFrameBottomRightBorder:SetTexture("Interface\\AddOns\\ExtVendor\\textures\\bottomborder");
  842.  
  843. local topmiddleleft = MerchantFrame:CreateTexture("ExtFrameTop", "BACKGROUND");
  844. topmiddleleft:SetPoint("TOP", MerchantFrame,85, 0);
  845. topmiddleleft:SetTexture("Interface\\AddOns\\ExtVendor\\textures\\UI-Merchant-TopRight","MIRROR","MIRROR");
  846. topmiddleleft:SetHorizTile(true);
  847. topmiddleleft:SetWidth(400);
  848.  
  849. local botmiddleleft = MerchantFrame:CreateTexture("ExtFrameBot", "BACKGROUND");
  850. botmiddleleft:SetPoint("BOTTOM", MerchantFrame, 100, 0);
  851. botmiddleleft:SetTexture("Interface\\AddOns\\ExtVendor\\textures\\UI-MERCHANT-BOTRIGHT","MIRROR","MIRROR");
  852. botmiddleleft:SetHorizTile(true);
  853. botmiddleleft:SetWidth(450);
  854.  
  855. -- alter the position of the buyback item slot on the merchant tab
  856. MerchantBuyBackItem:ClearAllPoints();
  857. MerchantBuyBackItem:SetPoint("TOPLEFT", MerchantItem10, "BOTTOMLEFT", -11, -18.5);
  858.  
  859. -- move the next/previous page buttons
  860. MerchantPrevPageButton:ClearAllPoints();
  861. MerchantPrevPageButton:SetPoint("CENTER", MerchantFrame, "BOTTOM", 30, 110);
  862. MerchantPageText:ClearAllPoints();
  863. MerchantPageText:SetPoint("BOTTOM", MerchantFrame, "BOTTOM", 160, 105);
  864. MerchantNextPageButton:ClearAllPoints();
  865. MerchantNextPageButton:SetPoint("CENTER", MerchantFrame, "BOTTOM", 290, 110);
  866. -- currency insets
  867. -- MerchantFrameAltCurrencyFrame:ClearAllPoints();
  868. -- MerchantFrameAltCurrencyFrame:SetPoint("BOTTOMRIGHT", "MerchantItem"..i.."NameFrame", "BOTTOMLEFT", 0, 0);
  869. --merchantAltCurrency:Show();
  870.  
  871. --[[ MerchantExtraCurrencyBg:ClearAllPoints();
  872. MerchantExtraCurrencyBg:SetPoint("TOPLEFT", MerchantExtraCurrencyInset, "TOPLEFT", 3, -2);
  873. MerchantExtraCurrencyBg:SetPoint("BOTTOMRIGHT", MerchantExtraCurrencyInset, "BOTTOMRIGHT", -3, 2); ]]
  874. -- add the search box
  875. local editbox = CreateFrame("EditBox", "MerchantFrameSearchBox", MerchantFrame, "EV_SearchBoxTemplate");
  876. editbox:SetWidth(200);
  877. editbox:SetHeight(24);
  878. editbox:SetPoint("TOPRIGHT", MerchantFrame, "TOPRIGHT", -55, -42);
  879. editbox:SetAutoFocus(false);
  880. editbox:SetScript("OnTextChanged", ExtVendor_UpdateDisplay);
  881. editbox:SetMaxLetters(30);
  882.  
  883. -- add quick-vendor button
  884. local junkBtn = CreateFrame("Button", "MerchantFrameSellJunkButton", MerchantFrame);
  885. junkBtn:SetWidth(32);
  886. junkBtn:SetHeight(32);
  887. junkBtn:SetPoint("TOPLEFT", MerchantFrame, "TOPLEFT", 80, -38);
  888. junkBtn.tooltip = L["QUICKVENDOR_BUTTON_TOOLTIP"];
  889. junkBtn:SetScript("OnClick", ExtVendor_StartQuickVendor);
  890. junkBtn:SetScript("OnEnter", ExtVendor_ShowButtonTooltip);
  891. junkBtn:SetScript("OnLeave", ExtVendor_HideButtonTooltip);
  892. junkBtn:SetPushedTexture("Interface\\Buttons\\UI-Quickslot-Depress");
  893. junkBtn:SetHighlightTexture("Interface\\Buttons\\ButtonHilight-Square", "ADD");
  894. junkBtn.junkBtnIcon = junkBtn:CreateTexture("MerchantFrameSellJunkButtonIcon", "BORDER");
  895. junkBtn.junkBtnIcon:SetTexture("Interface\\Icons\\inv_misc_bag_10");
  896. junkBtn.junkBtnIcon:SetPoint("TOPLEFT", junkBtn, "TOPLEFT", 0, 0);
  897. junkBtn.junkBtnIcon:SetPoint("BOTTOMRIGHT", junkBtn, "BOTTOMRIGHT", 0, 0);
  898.  
  899. -- filter button
  900. local filterBtn = CreateFrame("Button", "MerchantFrameFilterButton", MerchantFrame, "ExtVendor_UIButtonStretchTemplate");
  901. filterBtn:SetText(FILTER);
  902. filterBtn:SetPoint("RIGHT", MerchantFrameSearchBox, "LEFT", -30, 0);
  903. filterBtn:SetWidth(80);
  904. filterBtn:SetHeight(22);
  905. filterBtn:SetScript("OnClick", ExtVendor_DisplayFilterDropDown);
  906. MerchantFrameFilterButtonRightArrow:Show();
  907.  
  908. -- create text for showing number of hidden items
  909. local hiddenText = MerchantFrame:CreateFontString("MerchantFrameHiddenText", "ARTWORK", "GameFontNormal");
  910. hiddenText:SetPoint("RIGHT", MerchantFrameFilterButton, "LEFT", -10, 0);
  911. hiddenText:SetJustifyH("RIGHT");
  912. hiddenText:SetText("0 item(s) hidden");
  913.  
  914. -- hide the new stock filter dropdown
  915. --MerchantFrameLootFilter:Hide();
  916.  
  917. -- filter options dropdown
  918. local filterDropdown = CreateFrame("Frame", "MerchantFrameFilterDropDown", UIParent, "UIDropDownMenuTemplate");
  919.  
  920. -- create a new tooltip object for handling item tooltips in the background
  921. evTooltip = CreateFrame("GameTooltip", "ExtVendorHiddenTooltip", UIParent, "GameTooltipTemplate");
  922.  
  923. function MerchantItemButton_OnModifiedClick(self, button)
  924. if ( MerchantFrame.selectedTab == 1 ) then
  925. -- Is merchant frame
  926. if ( HandleModifiedItemClick(GetMerchantItemLink(self:GetID())) ) then
  927. return;
  928. end
  929. if IsAltKeyDown() then
  930. local maxStack = GetMerchantItemMaxStack(self:GetID());
  931. if ( self.extendedCost ) then
  932. MerchantFrame_ConfirmExtendedItemCost(self);
  933. elseif ( self.price and self.price >= MERCHANT_HIGH_PRICE_COST ) then
  934. MerchantFrame_ConfirmHighCostItem(self);
  935. else
  936. BuyMerchantItem(self:GetID(),maxStack);
  937. end
  938. elseif ( IsModifiedClick("SPLITSTACK") ) then
  939. local maxStack = GetMerchantItemMaxStack(self:GetID());
  940. if ( self.price and (self.price > 0) ) then
  941. local canAfford = floor(GetMoney() / self.price);
  942. if ( canAfford < maxStack ) then
  943. maxStack = canAfford;
  944. end
  945. end
  946. OpenStackSplitFrame(1000, self, "BOTTOMLEFT", "TOPLEFT");
  947. return;
  948. end
  949. else
  950. HandleModifiedItemClick(GetBuybackItemLink(self:GetID()));
  951. end
  952. end
  953. end
  954.  
  955. --========================================
  956. -- Performs additional updates to main
  957. -- display - fades items for searching
  958. -- and applies quality colors to names
  959. --========================================
  960. function ExtVendor_UpdateDisplay()
  961.  
  962. if (MerchantFrame.selectedTab == 1) then
  963. ExtVendor_UpdateMerchantInfo();
  964. elseif (MerchantFrame.selectedTab == 2) then
  965. ExtVendor_UpdateBuybackInfo();
  966. end
  967.  
  968. CloseDropDownMenus();
  969.  
  970. end
  971.  
  972. --========================================
  973. -- Dims or shows an item frame
  974. --========================================
  975. function ExtVendor_SearchDimItem(itemFrame, isDimmed)
  976.  
  977. if (not itemFrame) then return; end
  978.  
  979. local alpha;
  980.  
  981. if (isDimmed) then
  982. alpha = 0.2;
  983. else
  984. alpha = 1;
  985. end
  986. itemFrame:SetAlpha(alpha);
  987.  
  988. local btn = _G[itemFrame:GetName() .. "ItemButton"];
  989. if (isDimmed) then
  990. btn:Disable();
  991. else
  992. btn:Enable();
  993. end
  994.  
  995. end
  996.  
  997. --========================================
  998. -- Show button tooltips
  999. --========================================
  1000. function ExtVendor_ShowButtonTooltip(self)
  1001.  
  1002. if (self.tooltip) then
  1003. GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
  1004. GameTooltip:SetText(self.tooltip);
  1005. GameTooltip:Show();
  1006. end
  1007.  
  1008. end
  1009.  
  1010. --========================================
  1011. -- Hide button tooltips
  1012. --========================================
  1013. function ExtVendor_HideButtonTooltip(self)
  1014.  
  1015. if (GameTooltip:GetOwner() == self) then
  1016. GameTooltip:Hide();
  1017. end
  1018.  
  1019. end
  1020.  
  1021. --========================================
  1022. -- Enable/disable the sell junk button
  1023. --========================================
  1024. function ExtVendor_SetJunkButtonState(state)
  1025. if (state) then
  1026. MerchantFrameSellJunkButton:Enable();
  1027. MerchantFrameSellJunkButtonIcon:SetDesaturated(false);
  1028. else
  1029. MerchantFrameSellJunkButton:Disable();
  1030. MerchantFrameSellJunkButtonIcon:SetDesaturated(true);
  1031. end
  1032. end
  1033.  
  1034. --========================================
  1035. -- Gold/silver/copper money formatting
  1036. --========================================
  1037. function ExtVendor_FormatMoneyString(value, trailing)
  1038.  
  1039. value = tonumber(value) or 0;
  1040.  
  1041. local gold = math.floor(value / 10000);
  1042. local silver = math.floor(value / 100) % 100;
  1043. local copper = value % 100;
  1044.  
  1045. local disp = "";
  1046.  
  1047. if (gold > 0) then
  1048. disp = disp .. format(GOLD_AMOUNT_TEXTURE, gold, 0, 0) .. " ";
  1049. end
  1050. if ((silver > 0) or (trailing and (gold > 0))) then
  1051. disp = disp .. format(SILVER_AMOUNT_TEXTURE, silver, 0, 0) .. " ";
  1052. end
  1053. if ((copper > 0) or (trailing and ((gold > 0) or (silver > 0)))) then
  1054. disp = disp .. format(COPPER_AMOUNT_TEXTURE, copper, 0, 0);
  1055. end
  1056.  
  1057. return disp;
  1058.  
  1059. end
  1060.  
  1061. --========================================
  1062. -- Initialize the item quality dropdown
  1063. --========================================
  1064. function ExtVendor_InitQualityFilter()
  1065.  
  1066. local info = {};
  1067. local color;
  1068. for i = 0, 7, 1 do
  1069. -- skip common, legendary and artifact qualities for now
  1070. if ((i ~= 1) and (i ~= 5) and (i ~= 6)) then
  1071. if (i == 0) then
  1072. info.text = ALL;
  1073. else
  1074. color = select(4,GetItemQualityColor(i));
  1075. info.text = color .. _G["ITEM_QUALITY" .. i .. "_DESC"];
  1076. end
  1077. info.value = i;
  1078. info.checked = nil;
  1079. info.func = ExtVendor_SelectFilterQuality;
  1080. ExtVendor_UIDropDownMenu_AddButton(info);
  1081. end
  1082. end
  1083.  
  1084. end
  1085.  
  1086. --========================================
  1087. -- Handler for selecting an item quality
  1088. --========================================
  1089. function ExtVendor_SelectFilterQuality(self)
  1090. ExtVendor_UIDropDownMenu_SetSelectedValue(MerchantFrameQualityFilter, self.value);
  1091. EXTVENDOR_SELECTED_QUALITY = self.value;
  1092.  
  1093. ExtVendor_UpdateDisplay();
  1094. end
  1095.  
  1096. --========================================
  1097. -- Show the filter options dropdown menu
  1098. --========================================
  1099. function ExtVendor_DisplayFilterDropDown(self)
  1100. local menu = {
  1101. { text = L["HIDE_FILTERED"], checked = EXTVENDOR_DATA['config']['hide_filtered'], func = function() ExtVendor_ToggleSetting("hide_filtered"); ExtVendor_UpdateDisplay(); end },
  1102. { text = L["HIDE_KNOWN_RECIPES"], checked = EXTVENDOR_DATA['config']['hide_known_recipes'], func = function() ExtVendor_ToggleSetting("hide_known_recipes"); ExtVendor_UpdateDisplay(); end },
  1103. { text = L["HIDE_KNOWN_ASCENSION_COLLECTION_ITEMS"], checked = EXTVENDOR_DATA['config']['hide_known_ascension_collection_items'], func = function() ExtVendor_ToggleSetting("hide_known_ascension_collection_items"); ExtVendor_UpdateDisplay(); end },
  1104. { text = L["FILTER_RECIPES"], hasArrow = true, notCheckable = true,
  1105. menuList = {
  1106. { text = L["FILTER_ALREADY_KNOWN"], checked = EXTVENDOR_DATA['config']['hide_known_recipes'], func = function() ExtVendor_ToggleSetting("hide_known_recipes"); ExtVendor_UpdateDisplay(); end },
  1107. { text = L["FILTER_PURCHASED"], checked = EXTVENDOR_DATA['config']['filter_purchased_recipes'], func = function() ExtVendor_ToggleSetting("filter_purchased_recipes"); ExtVendor_UpdateDisplay(); end },
  1108. },
  1109. },
  1110. { text = L["FILTER_STAT"], hasArrow = true, notCheckable = true,
  1111. menuList = {
  1112. { text = ALL, checked = (STAT_FILTER_INDEX == 0), func = function() ExtVendor_SetSlotFilter(0, true); end },
  1113. { text = L["STAT_PRIMARY"], hasArrow = true, notCheckable = true,
  1114. menuList = {
  1115. { text = ALL, checked = (STAT_FILTER_INDEX == 1), func = function() ExtVendor_SetSlotFilter(1, true); end },
  1116. { text = L["STAT_STRENGTH"], checked = (STAT_FILTER_INDEX == 2), func = function() ExtVendor_SetSlotFilter(2, true); end },
  1117. { text = L["STAT_AGILITY"], checked = (STAT_FILTER_INDEX == 3), func = function() ExtVendor_SetSlotFilter(3, true); end },
  1118. { text = L["STAT_INTELLECT"], checked = (STAT_FILTER_INDEX == 4), func = function() ExtVendor_SetSlotFilter(4, true); end },
  1119. { text = L["STAT_SPIRIT"], checked = (STAT_FILTER_INDEX == 5), func = function() ExtVendor_SetSlotFilter(5, true); end },
  1120. },
  1121. },
  1122. { text = L["STAT_SECONDARY"], hasArrow = true, notCheckable = true,
  1123. menuList = {
  1124. { text = ALL, checked = (STAT_FILTER_INDEX == 6), func = function() ExtVendor_SetSlotFilter(6, true); end },
  1125. { text = L["STAT_ATTACT_POWER"], checked = (STAT_FILTER_INDEX == 7), func = function() ExtVendor_SetSlotFilter(7, true); end },
  1126. { text = L["STAT_SPELL_POWER"], checked = (STAT_FILTER_INDEX == 8), func = function() ExtVendor_SetSlotFilter(8, true); end },
  1127. { text = L["STAT_CRIT"], checked = (STAT_FILTER_INDEX == 9), func = function() ExtVendor_SetSlotFilter(9, true); end },
  1128. { text = L["STAT_HIT"], checked = (STAT_FILTER_INDEX == 10), func = function() ExtVendor_SetSlotFilter(10, true); end },
  1129. { text = L["STAT_HASTE"], checked = (STAT_FILTER_INDEX == 11), func = function() ExtVendor_SetSlotFilter(11, true); end },
  1130. { text = L["STAT_EXPERTISE"], checked = (STAT_FILTER_INDEX == 12), func = function() ExtVendor_SetSlotFilter(12, true); end },
  1131. { text = L["STAT_ARMOR_PEN"], checked = (STAT_FILTER_INDEX == 13), func = function() ExtVendor_SetSlotFilter(13, true); end },
  1132. { text = L["STAT_SPELL_PEN"], checked = (STAT_FILTER_INDEX == 14), func = function() ExtVendor_SetSlotFilter(14, true); end },
  1133. { text = L["STAMINA"], checked = (STAT_FILTER_INDEX == 15), func = function() ExtVendor_SetSlotFilter(15, true); end },
  1134. },
  1135. },
  1136. { text = L["STAT_DEFENSIVE"], hasArrow = true, notCheckable = true,
  1137. menuList = {
  1138. { text = ALL, checked = (STAT_FILTER_INDEX == 15), func = function() ExtVendor_SetSlotFilter(15, true); end },
  1139. { text = L["DEFENSE"], checked = (STAT_FILTER_INDEX == 16), func = function() ExtVendor_SetSlotFilter(16, true); end },
  1140. { text = L["DODGE"], checked = (STAT_FILTER_INDEX == 17), func = function() ExtVendor_SetSlotFilter(17, true); end },
  1141. { text = L["PARRY"], checked = (STAT_FILTER_INDEX == 18), func = function() ExtVendor_SetSlotFilter(18, true); end },
  1142. { text = L["BLOCK"], checked = (STAT_FILTER_INDEX == 19), func = function() ExtVendor_SetSlotFilter(19, true); end },
  1143. { text = L["BLOCK_VALUE"], checked = (STAT_FILTER_INDEX == 20), func = function() ExtVendor_SetSlotFilter(20, true); end },
  1144. { text = L["RESILIENCE"], checked = (STAT_FILTER_INDEX == 21), func = function() ExtVendor_SetSlotFilter(21, true); end },
  1145. },
  1146. },
  1147. },
  1148. },
  1149. { text = L["FILTER_SLOT"], hasArrow = true, notCheckable = true,
  1150. menuList = {
  1151. { text = ALL, checked = (SLOT_FILTER_INDEX == 0), func = function() ExtVendor_SetSlotFilter(0); end },
  1152. { text = L["SLOT_CAT_ARMOR"], hasArrow = true, notCheckable = true,
  1153. menuList = {
  1154. { text = ALL, checked = (SLOT_FILTER_INDEX == 1), func = function() ExtVendor_SetSlotFilter(1); end },
  1155. { text = L["SLOT_HEAD"], checked = (SLOT_FILTER_INDEX == 2), func = function() ExtVendor_SetSlotFilter(2); end },
  1156. { text = L["SLOT_SHOULDER"], checked = (SLOT_FILTER_INDEX == 3), func = function() ExtVendor_SetSlotFilter(3); end },
  1157. { text = L["SLOT_BACK"], checked = (SLOT_FILTER_INDEX == 4), func = function() ExtVendor_SetSlotFilter(4); end },
  1158. { text = L["SLOT_CHEST"], checked = (SLOT_FILTER_INDEX == 5), func = function() ExtVendor_SetSlotFilter(5); end },
  1159. { text = L["SLOT_WRIST"], checked = (SLOT_FILTER_INDEX == 6), func = function() ExtVendor_SetSlotFilter(6); end },
  1160. { text = L["SLOT_HANDS"], checked = (SLOT_FILTER_INDEX == 7), func = function() ExtVendor_SetSlotFilter(7); end },
  1161. { text = L["SLOT_WAIST"], checked = (SLOT_FILTER_INDEX == 8), func = function() ExtVendor_SetSlotFilter(8); end },
  1162. { text = L["SLOT_LEGS"], checked = (SLOT_FILTER_INDEX == 9), func = function() ExtVendor_SetSlotFilter(9); end },
  1163. { text = L["SLOT_FEET"], checked = (SLOT_FILTER_INDEX == 10), func = function() ExtVendor_SetSlotFilter(10); end },
  1164. },
  1165. },
  1166. { text = L["SLOT_CAT_ACCESSORIES"], hasArrow = true, notCheckable = true,
  1167. menuList = {
  1168. { text = ALL, checked = (SLOT_FILTER_INDEX == 20), func = function() ExtVendor_SetSlotFilter(20); end },
  1169. { text = L["SLOT_NECK"], checked = (SLOT_FILTER_INDEX == 21), func = function() ExtVendor_SetSlotFilter(21); end },
  1170. { text = L["SLOT_SHIRT"], checked = (SLOT_FILTER_INDEX == 22), func = function() ExtVendor_SetSlotFilter(22); end },
  1171. { text = L["SLOT_TABARD"], checked = (SLOT_FILTER_INDEX == 23), func = function() ExtVendor_SetSlotFilter(23); end },
  1172. { text = L["SLOT_FINGER"], checked = (SLOT_FILTER_INDEX == 24), func = function() ExtVendor_SetSlotFilter(24); end },
  1173. { text = L["SLOT_TRINKET"], checked = (SLOT_FILTER_INDEX == 25), func = function() ExtVendor_SetSlotFilter(25); end },
  1174. },
  1175. },
  1176. { text = L["SLOT_CAT_WEAPONS"], hasArrow = true, notCheckable = true,
  1177. menuList = {
  1178. { text = ALL, checked = (SLOT_FILTER_INDEX == 30), func = function() ExtVendor_SetSlotFilter(30); end },
  1179. { text = L["SLOT_WEAPON1H"], checked = (SLOT_FILTER_INDEX == 31), func = function() ExtVendor_SetSlotFilter(31); end },
  1180. { text = L["SLOT_WEAPON2H"], checked = (SLOT_FILTER_INDEX == 32), func = function() ExtVendor_SetSlotFilter(32); end },
  1181. { text = L["SLOT_WEAPONOH"], checked = (SLOT_FILTER_INDEX == 33), func = function() ExtVendor_SetSlotFilter(33); end },
  1182. { text = L["SLOT_RANGED"], checked = (SLOT_FILTER_INDEX == 34), func = function() ExtVendor_SetSlotFilter(34); end },
  1183. },
  1184. },
  1185. { text = L["SLOT_CAT_OFFHAND"], hasArrow = true, notCheckable = true,
  1186. menuList = {
  1187. { text = ALL, checked = (SLOT_FILTER_INDEX == 40), func = function() ExtVendor_SetSlotFilter(40); end },
  1188. { text = L["SLOT_OFFHAND"], checked = (SLOT_FILTER_INDEX == 41), func = function() ExtVendor_SetSlotFilter(41); end },
  1189. { text = L["SLOT_SHIELD"], checked = (SLOT_FILTER_INDEX == 42), func = function() ExtVendor_SetSlotFilter(42); end },
  1190. },
  1191. },
  1192. },
  1193. },
  1194. { text = L["QUALITY_FILTER_MINIMUM"], hasArrow = true, notCheckable = true,
  1195. menuList = {
  1196. { text = ALL, checked = (EXTVENDOR_SELECTED_QUALITY == 0), func = function() ExtVendor_SetMinimumQuality(0); end },
  1197. { text = ITEM_QUALITY_COLORS[2].hex .. ITEM_QUALITY2_DESC, checked = (EXTVENDOR_SELECTED_QUALITY == 2), func = function() ExtVendor_SetMinimumQuality(2); end },
  1198. { text = ITEM_QUALITY_COLORS[3].hex .. ITEM_QUALITY3_DESC, checked = (EXTVENDOR_SELECTED_QUALITY == 3), func = function() ExtVendor_SetMinimumQuality(3); end },
  1199. { text = ITEM_QUALITY_COLORS[4].hex .. ITEM_QUALITY4_DESC, checked = (EXTVENDOR_SELECTED_QUALITY == 4), func = function() ExtVendor_SetMinimumQuality(4); end },
  1200. { text = ITEM_QUALITY_COLORS[7].hex .. ITEM_QUALITY7_DESC, checked = (EXTVENDOR_SELECTED_QUALITY == 7), func = function() ExtVendor_SetMinimumQuality(7); end },
  1201. },
  1202. },
  1203. { text = L["QUALITY_FILTER_SPECIFIC"], hasArrow = true, notCheckable = true,
  1204. menuList = {
  1205. { text = ALL, checked = (EXTVENDOR_SELECTED_QUALITY == 0), func = function() ExtVendor_SetMinimumQuality(0); end },
  1206. { text = ITEM_QUALITY_COLORS[1].hex .. ITEM_QUALITY1_DESC, checked = (EXTVENDOR_SELECTED_QUALITY == 1), func = function() ExtVendor_SetSpecificQuality(1); end },
  1207. { text = ITEM_QUALITY_COLORS[2].hex .. ITEM_QUALITY2_DESC, checked = (EXTVENDOR_SELECTED_QUALITY == 2), func = function() ExtVendor_SetSpecificQuality(2); end },
  1208. { text = ITEM_QUALITY_COLORS[3].hex .. ITEM_QUALITY3_DESC, checked = (EXTVENDOR_SELECTED_QUALITY == 3), func = function() ExtVendor_SetSpecificQuality(3); end },
  1209. { text = ITEM_QUALITY_COLORS[4].hex .. ITEM_QUALITY4_DESC, checked = (EXTVENDOR_SELECTED_QUALITY == 4), func = function() ExtVendor_SetSpecificQuality(4); end },
  1210. { text = ITEM_QUALITY_COLORS[7].hex .. ITEM_QUALITY7_DESC, checked = (EXTVENDOR_SELECTED_QUALITY == 7), func = function() ExtVendor_SetSpecificQuality(7); end },
  1211. },
  1212. },
  1213. { text = L["CONFIGURE_QUICKVENDOR"], notCheckable = true, func = function() ExtVendor_QVConfigFrame:Show(); end },
  1214. { text = L["MAIN_OPTIONS"], notCheckable = true, func = function() InterfaceOptionsFrame_OpenToCategory(ExtVendorConfigContainer); end },
  1215. };
  1216. EasyMenu(menu, MerchantFrameFilterDropDown, self, 0, 0, "MENU", 1);
  1217. end
  1218.  
  1219. --========================================
  1220. -- Toggles a boolean config setting
  1221. --========================================
  1222. function ExtVendor_ToggleSetting(name)
  1223. if (EXTVENDOR_DATA['config'][name]) then
  1224. EXTVENDOR_DATA['config'][name] = false;
  1225. else
  1226. EXTVENDOR_DATA['config'][name] = true;
  1227. end
  1228. end
  1229.  
  1230. --========================================
  1231. -- Sets the minimum quality filter
  1232. --========================================
  1233. function ExtVendor_SetMinimumQuality(quality)
  1234. EXTVENDOR_SELECTED_QUALITY = math.max(0, math.min(7, quality));
  1235. EXTVENDOR_SPECIFIC_QUALITY = false;
  1236. ExtVendor_UpdateDisplay();
  1237. end
  1238.  
  1239. --========================================
  1240. -- Sets the specific quality filter
  1241. --========================================
  1242. function ExtVendor_SetSpecificQuality(quality)
  1243. EXTVENDOR_SELECTED_QUALITY = math.max(0, math.min(7, quality));
  1244. EXTVENDOR_SPECIFIC_QUALITY = true;
  1245. ExtVendor_UpdateDisplay();
  1246. end
  1247.  
  1248. --========================================
  1249. -- Output message to chat frame
  1250. --========================================
  1251. function ExtVendor_Message(msg)
  1252. DEFAULT_CHAT_FRAME:AddMessage("|cffffff00<" .. L["ADDON_TITLE"] .. ">|r " .. msg);
  1253. end
  1254.  
  1255. --========================================
  1256. -- Slash command handler
  1257. --========================================
  1258. function ExtVendor_CommandHandler(cmd)
  1259. if cmd == "wlistchar" then
  1260. local _, link = GameTooltip:GetItem()
  1261. if GameTooltip:IsShown() and link then
  1262. local type = {}
  1263. type.isWhitelist = true
  1264. type.isLocal = true
  1265. ExtVendor_QVConfig_OnItemDrop(type, link)
  1266. end
  1267. elseif cmd == "wlist" then
  1268. local _, link = GameTooltip:GetItem()
  1269. if GameTooltip:IsShown() and link then
  1270. local type = {}
  1271. type.isWhitelist = true
  1272. type.isLocal = false
  1273. ExtVendor_QVConfig_OnItemDrop(type, link)
  1274. end
  1275. elseif cmd == "blist" then
  1276. local _, link = GameTooltip:GetItem()
  1277. if GameTooltip:IsShown() and link then
  1278. local type = {}
  1279. type.isWhitelist = false
  1280. type.isLocal = false
  1281. ExtVendor_QVConfig_OnItemDrop(type, link)
  1282. end
  1283. else
  1284. InterfaceOptionsFrame_OpenToCategory(ExtVendorConfigContainer);
  1285. end
  1286. end
  1287.  
  1288. --========================================
  1289. -- Called with pcall to safely catch
  1290. -- errors (fixes battle pet error)
  1291. --========================================
  1292. function ExtVendor_SetHiddenTooltip(link)
  1293. ExtVendorHiddenTooltip:SetHyperlink(link);
  1294. end
  1295.  
  1296. --========================================
  1297. -- Mouse wheel handler
  1298. --========================================
  1299. function ExtVendor_OnMouseWheel(self, delta)
  1300. if (delta > 0) then
  1301. if ((MerchantFrame.page > 1) and (MerchantPrevPageButton:IsEnabled()) and (MerchantPrevPageButton:IsVisible())) then
  1302. MerchantPrevPageButton:Click();
  1303. end
  1304. else
  1305. if ((MerchantFrame.page < EXTVENDOR_NUM_PAGES) and (MerchantNextPageButton:IsEnabled()) and (MerchantNextPageButton:IsVisible())) then
  1306. MerchantNextPageButton:Click();
  1307. end
  1308. end
  1309. end
  1310.  
  1311. --========================================
  1312. -- Enables/disables the mouse wheel
  1313. -- handler depending on config
  1314. --========================================
  1315. function ExtVendor_UpdateMouseScrolling(state)
  1316. if (EXTVENDOR_DATA['config']['mousewheel_paging']) then
  1317. MerchantFrame:EnableMouseWheel();
  1318. MerchantFrame:SetScript("OnMouseWheel", ExtVendor_OnMouseWheel);
  1319. else
  1320. MerchantFrame:SetScript("OnMouseWheel", nil);
  1321. end
  1322. end
  1323.  
  1324. --========================================
  1325. -- Changes the equipment slot filter
  1326. --========================================
  1327. function ExtVendor_SetSlotFilter(index, stat)
  1328. if stat then
  1329. STAT_FILTER_INDEX = index;
  1330. else
  1331. SLOT_FILTER_INDEX = index;
  1332. end
  1333. ExtVendor_UpdateDisplay();
  1334. end
  1335.  
  1336. --========================================
  1337. -- Sets the scale of the vendor frame to
  1338. -- the configured scale
  1339. --========================================
  1340. function ExtVendor_UpdateScale()
  1341. MerchantFrame:SetScale(EXTVENDOR_DATA['config']['scale']);
  1342. end
  1343.  
  1344. --========================================
  1345. -- Returns how many of an item of the
  1346. -- specified ID is in the player's bags
  1347. --========================================
  1348. function ExtVendor_HasItemInBags(itemId)
  1349. local count = 0;
  1350. for bag = 0, 4, 1 do
  1351. if (GetContainerNumSlots(bag)) then
  1352. for slot = 1, GetContainerNumSlots(bag), 1 do
  1353. local id = GetContainerItemID(bag, slot);
  1354. if (id == itemId) then
  1355. count = count + 1;
  1356. end
  1357. end
  1358. end
  1359. end
  1360. return count;
  1361. end
  1362.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement