PK
N~ёL
ExtVendor/PK
N~ёL ExtVendor/config/PK
Ys-Eс6Ѕl" " ExtVendor/config/about.lualocal L = LibStub("AceLocale-3.0"):GetLocale("ExtVendor", true);
local ABOUT = {
author = "Alex Ellison (Germbread - Deathwing-US)",
email = GetAddOnMetadata("ExtVendor", "X-Email"),
hosts = {
"http://www.wowinterface.com/",
"http://www.curse.com/",
},
translators = {
{ name = "BNS", locale = "Traditional Chinese, Simplified Chinese" },
},
};
local CONFIG_SHOWN = false;
--========================================
-- Setting up the config frame
--========================================
function ExtVendorConfig_About_OnLoad(self)
self.name = L["ABOUT"];
self.parent = L["ADDON_TITLE"];
self.okay = function(self) ExtVendorConfig_About_OnClose(); end;
self.cancel = function(self) ExtVendorConfig_About_OnClose(); end;
self.refresh = function(self) ExtVendorConfig_About_OnRefresh(); end;
InterfaceOptions_AddCategory(self);
ExtVendorConfigAboutTitle:SetText(string.format(L["VERSION_TEXT"], "|cffffffffv" .. EXTVENDOR_VERSION));
ExtVendorConfigAboutAuthor:SetText(L["LABEL_AUTHOR"] .. ": |cffffffff" .. ABOUT.author);
ExtVendorConfigAboutEmail:SetText(L["LABEL_EMAIL"] .. ": |cffffffff" .. ABOUT.email);
ExtVendorConfigAboutURLs:SetText(L["LABEL_HOSTS"] .. ":");
ExtVendorConfigAboutTranslatorsHeader:SetText(L["TRANSLATORS"]);
end
--========================================
-- Refresh
--========================================
function ExtVendorConfig_About_OnRefresh()
if (CONFIG_SHOWN) then return; end
local i2;
for i = 1, table.maxn(ABOUT.hosts), 1 do
local fontString = _G["ExtVendorConfigAbout_SiteList" .. i];
if (not fontString) then
fontString = ExtVendorConfigAbout:CreateFontString("ExtVendorConfigAbout_SiteList" .. i, "ARTWORK", "GameFontHighlight");
end
fontString:ClearAllPoints();
fontString:SetPoint("TOPLEFT", ExtVendorConfigAboutURLs, "TOPLEFT", 20, -(i * 20));
fontString:SetText(ABOUT.hosts[i]);
i2 = i;
end
local th = _G["ExtVendorConfigAboutTranslatorsHeader"];
if (th ~= nil) then
th:ClearAllPoints();
th:SetPoint("TOPLEFT", ExtVendorConfigAboutTitle, "BOTTOMLEFT", 15, -(150 + (i2 * 20)));
end
for i = 1, table.maxn(ABOUT.translators), 1 do
local fontString = _G["ExtVendorConfigAbout_Translator" .. i];
if (not fontString) then
fontString = ExtVendorConfigAbout:CreateFontString("ExtVendorConfigAbout_Translator" .. i, "ARTWORK", "GameFontHighlight");
end
fontString:ClearAllPoints();
fontString:SetPoint("TOPLEFT", ExtVendorConfigAboutTranslatorsHeader, "TOPLEFT", 20, -(i * 20));
fontString:SetText(ABOUT.translators[i].name .. " |cffa0a0a0(" .. ABOUT.translators[i].locale .. ")");
end
CONFIG_SHOWN = true;
end
--========================================
-- Closing the window
--========================================
function ExtVendorConfig_About_OnClose()
CONFIG_SHOWN = false;
end
PK
Жi,EАmьјe e ExtVendor/config/about.xml
ExtVendorConfig_About_OnLoad(self);
PK
ю
LN @N* N* ExtVendor/config/Config.lualocal L = LibStub("AceLocale-3.0"):GetLocale("ExtVendor", true);
-- ********** variables for storing previous values **********
local OLD_LOADMESSAGE = false;
local OLD_SUBARMOR_SHOW = false;
local OLD_STOCK_DEFALL = false;
local OLD_QUICKVENDOR_ENABLEBUTTON = false;
local OLD_QUICKVENDOR_SUBOPTIMAL = false;
local OLD_QUICKVENDOR_ALREADYKNOWN = false;
local OLD_QUICKVENDOR_UNUSABLEEQUIP = false;
local OLD_QUICKVENDOR_WHITEGEAR = false;
local OLD_SCALE = 1;
-- ***********************************************************
local CONFIG_SHOWN = false;
--========================================
-- Setting up the config frame
--========================================
function ExtVendorConfig_OnLoad(self)
self.name = L["ADDON_TITLE"];
self.okay = function(self) ExtVendorConfig_Close(); end;
self.cancel = function(self) ExtVendorConfig_Cancel(); end;
self.refresh = function(self) ExtVendorConfig_Refresh(); end;
self.default = function(self) ExtVendorConfig_SetDefaults(); end;
InterfaceOptions_AddCategory(self);
ExtVendorConfigTitle:SetText(string.format(L["VERSION_TEXT"], "|cffffffffv" .. EXTVENDOR_VERSION));
-- ********** General Options **********
ExtVendorConfig_GeneralContainerTitle:SetText(L["CONFIG_HEADING_GENERAL"]);
ExtVendorConfig_GeneralContainer_ShowLoadMsgText:SetText(L["OPTION_STARTUP_MESSAGE"]);
ExtVendorConfig_GeneralContainer_ShowLoadMsg.tooltip = L["OPTION_STARTUP_MESSAGE_TOOLTIP"];
ExtVendorConfig_GeneralContainer_Scale.tooltip = L["OPTION_SCALE_TOOLTIP"];
-- ********** Filter Options **********
ExtVendorConfig_FilterContainerTitle:SetText(L["CONFIG_HEADING_FILTER"]);
ExtVendorConfig_FilterContainer_ShowSuboptimalArmorText:SetText(L["OPTION_FILTER_SUBARMOR_SHOW"]);
ExtVendorConfig_FilterContainer_ShowSuboptimalArmor.tooltip = L["OPTION_FILTER_SUBARMOR_SHOW_TOOLTIP"];
ExtVendorConfig_FilterContainer_StockDefaultAllText:SetText(L["OPTION_STOCKFILTER_DEFAULTALL"]);
ExtVendorConfig_FilterContainer_StockDefaultAll.tooltip = L["OPTION_STOCKFILTER_DEFAULTALL_TOOLTIP"];
-- ********** Quick-Vendor Options **********
ExtVendorConfig_QuickVendorContainerTitle:SetText(L["CONFIG_HEADING_QUICKVENDOR"]);
ExtVendorConfig_QuickVendorContainer_EnableButtonText:SetText(L["OPTION_QUICKVENDOR_ENABLEBUTTON"]);
ExtVendorConfig_QuickVendorContainer_EnableButton.tooltip = L["OPTION_QUICKVENDOR_ENABLEBUTTON_TOOLTIP"];
ExtVendorConfig_QuickVendorContainer_SuboptimalArmorText:SetText(L["OPTION_QUICKVENDOR_SUBARMOR"]);
ExtVendorConfig_QuickVendorContainer_SuboptimalArmor.tooltip = L["OPTION_QUICKVENDOR_SUBARMOR_TOOLTIP"] .. "\n\n|cff00ff00" .. L["QUICKVENDOR_SOULBOUND"];
ExtVendorConfig_QuickVendorContainer_AlreadyKnownText:SetText(L["OPTION_QUICKVENDOR_ALREADYKNOWN"]);
ExtVendorConfig_QuickVendorContainer_AlreadyKnown.tooltip = L["OPTION_QUICKVENDOR_ALREADYKNOWN_TOOLTIP"] .. "\n\n|cff00ff00" .. L["QUICKVENDOR_SOULBOUND"];
ExtVendorConfig_QuickVendorContainer_UnusableEquipText:SetText(L["OPTION_QUICKVENDOR_UNUSABLE"]);
ExtVendorConfig_QuickVendorContainer_UnusableEquip.tooltip = L["OPTION_QUICKVENDOR_UNUSABLE_TOOLTIP"] .. "\n\n|cff00ff00" .. L["QUICKVENDOR_SOULBOUND"];
ExtVendorConfig_QuickVendorContainer_WhiteGearText:SetText(L["OPTION_QUICKVENDOR_WHITEGEAR"]);
ExtVendorConfig_QuickVendorContainer_WhiteGear.tooltip = L["OPTION_QUICKVENDOR_WHITEGEAR_TOOLTIP"];
end
--==================================================
-- Handle when the configuration is opened
--==================================================
function ExtVendorConfig_OnShow()
if (CONFIG_SHOWN) then return; end
ExtVendorConfig_StoreCurrentSettings();
CONFIG_SHOWN = true;
end
--========================================
-- Sets the values of the controls to
-- reflect currently loaded settings
--========================================
function ExtVendorConfig_Refresh()
ExtVendorConfig_OnShow();
ExtVendorConfig_GeneralContainer_ShowLoadMsg:SetChecked(EXTVENDOR_DATA['config']['show_load_message']);
ExtVendorConfig_GeneralContainer_Scale:SetValue((EXTVENDOR_DATA['config']['scale'] * 20) - 15);
ExtVendorConfig_FilterContainer_ShowSuboptimalArmor:SetChecked(EXTVENDOR_DATA['config']['show_suboptimal_armor']);
ExtVendorConfig_FilterContainer_StockDefaultAll:SetChecked(EXTVENDOR_DATA['config']['stockfilter_defall']);
ExtVendorConfig_QuickVendorContainer_EnableButton:SetChecked(EXTVENDOR_DATA['config']['enable_quickvendor']);
ExtVendorConfig_QuickVendorContainer_SuboptimalArmor:SetChecked(EXTVENDOR_DATA['config']['quickvendor_suboptimal']);
ExtVendorConfig_QuickVendorContainer_AlreadyKnown:SetChecked(EXTVENDOR_DATA['config']['quickvendor_alreadyknown']);
ExtVendorConfig_QuickVendorContainer_UnusableEquip:SetChecked(EXTVENDOR_DATA['config']['quickvendor_unusable']);
ExtVendorConfig_QuickVendorContainer_WhiteGear:SetChecked(EXTVENDOR_DATA['config']['quickvendor_whitegear']);
end
--==================================================
-- Store current settings to restore if the user
-- presses cancel
--==================================================
function ExtVendorConfig_StoreCurrentSettings()
OLD_LOADMESSAGE = EXTVENDOR_DATA['config']['show_load_message'];
OLD_SCALE = EXTVENDOR_DATA['config']['scale'];
OLD_SUBARMOR_SHOW = EXTVENDOR_DATA['config']['show_suboptimal_armor'];
OLD_STOCK_DEFALL = EXTVENDOR_DATA['config']['stockfilter_defall'];
OLD_QUICKVENDOR_ENABLEBUTTON = EXTVENDOR_DATA['config']['enable_quickvendor'];
OLD_QUICKVENDOR_SUBOPTIMAL = EXTVENDOR_DATA['config']['quickvendor_suboptimal'];
OLD_QUICKVENDOR_ALREADYKNOWN = EXTVENDOR_DATA['config']['quickvendor_alreadyknown'];
OLD_QUICKVENDOR_UNUSABLEEQUIP = EXTVENDOR_DATA['config']['quickvendor_unusable'];
OLD_QUICKVENDOR_WHITEGEAR = EXTVENDOR_DATA['config']['quickvendor_whitegear'];
end
--========================================
-- Closing the config window
--========================================
function ExtVendorConfig_Close()
CONFIG_SHOWN = false;
end
--==================================================
-- Handle clicking the Cancel button; restore
-- all settings to their previous values
--==================================================
function ExtVendorConfig_Cancel()
EXTVENDOR_DATA['config']['show_load_message'] = OLD_LOADMESSAGE;
EXTVENDOR_DATA['config']['scale'] = OLD_SCALE;
EXTVENDOR_DATA['config']['show_suboptimal_armor'] = OLD_SUBARMOR_SHOW;
EXTVENDOR_DATA['config']['stockfilter_defall'] = OLD_STOCK_DEFALL;
EXTVENDOR_DATA['config']['enable_quickvendor'] = OLD_QUICKVENDOR_ENABLEBUTTON;
EXTVENDOR_DATA['config']['quickvendor_suboptimal'] = OLD_QUICKVENDOR_SUBOPTIMAL;
EXTVENDOR_DATA['config']['quickvendor_alreadyknown'] = OLD_QUICKVENDOR_ALREADYKNOWN;
EXTVENDOR_DATA['config']['quickvendor_unusable'] = OLD_QUICKVENDOR_UNUSABLEEQUIP;
EXTVENDOR_DATA['config']['quickvendor_whitegear'] = OLD_QUICKVENDOR_WHITEGEAR;
ExtVendor_UpdateQuickVendorButtonVisibility();
ExtVendor_UpdateDisplay();
ExtVendorConfig_Close();
end
--========================================
-- Handler for checking/unchecking
-- checkbox(es)
--========================================
function ExtVendorConfig_CheckBox_OnClick(self, id)
if (id == 1) then
if (self:GetChecked()) then
EXTVENDOR_DATA['config']['show_load_message'] = true;
else
EXTVENDOR_DATA['config']['show_load_message'] = false;
end
-- ********** Filter Options **********
elseif (id == 10) then
if (self:GetChecked()) then
EXTVENDOR_DATA['config']['show_suboptimal_armor'] = true;
else
EXTVENDOR_DATA['config']['show_suboptimal_armor'] = false;
end
ExtVendor_UpdateDisplay();
elseif (id == 11) then
if (self:GetChecked()) then
EXTVENDOR_DATA['config']['stockfilter_defall'] = true;
else
EXTVENDOR_DATA['config']['stockfilter_defall'] = false;
end
-- ********** Quick-Vendor Options **********
elseif (id == 20) then
if (self:GetChecked()) then
EXTVENDOR_DATA['config']['enable_quickvendor'] = true;
else
EXTVENDOR_DATA['config']['enable_quickvendor'] = false;
end
ExtVendor_UpdateQuickVendorButtonVisibility();
elseif (id == 21) then
if (self:GetChecked()) then
EXTVENDOR_DATA['config']['quickvendor_suboptimal'] = true;
else
EXTVENDOR_DATA['config']['quickvendor_suboptimal'] = false;
end
ExtVendor_RefreshQuickVendorButton();
elseif (id == 22) then
if (self:GetChecked()) then
EXTVENDOR_DATA['config']['quickvendor_alreadyknown'] = true;
else
EXTVENDOR_DATA['config']['quickvendor_alreadyknown'] = false;
end
ExtVendor_RefreshQuickVendorButton();
elseif (id == 23) then
if (self:GetChecked()) then
EXTVENDOR_DATA['config']['quickvendor_unusable'] = true;
else
EXTVENDOR_DATA['config']['quickvendor_unusable'] = false;
end
ExtVendor_RefreshQuickVendorButton();
elseif (id == 24) then
if (self:GetChecked()) then
EXTVENDOR_DATA['config']['quickvendor_whitegear'] = true;
else
EXTVENDOR_DATA['config']['quickvendor_whitegear'] = false;
end
ExtVendor_RefreshQuickVendorButton();
end
end
--========================================
-- Handler for mousing over options
-- on the config window
--========================================
function ExtVendorConfig_Option_OnEnter(self)
if (self.tooltip) then
GameTooltip:SetOwner(self, "ANCHOR_NONE");
GameTooltip:SetPoint("TOPLEFT", self:GetName(), "BOTTOMLEFT", -10, -4);
GameTooltip:SetText(self.tooltip, 1, 1, 1);
GameTooltip:Show();
end
end
--========================================
-- Moving the mouse away from config
-- options
--========================================
function ExtVendorConfig_Option_OnLeave(self)
GameTooltip:Hide();
end
--========================================
-- Handler for changing slider(s)
--========================================
function ExtVendorConfig_Slider_OnValueChanged(self, id)
if (id == 1) then
local newScale = (self:GetValue() * 5) + 75;
EXTVENDOR_DATA['config']['scale'] = newScale * 0.01;
ExtVendor_UpdateScale();
ExtVendorConfig_Slider_UpdateText(self, string.format(L["OPTION_SCALE"], newScale .. "%"));
end
end
--========================================
-- Slider text update for value changes
--========================================
function ExtVendorConfig_Slider_UpdateText(slider, text)
_G[slider:GetName() .. "Text1"]:SetText(text);
end
PK
ё
LH8 8 ExtVendor/config/Config.xml
ExtVendorConfig_CheckBox_OnClick(self, self:GetID());
if (self:GetChecked()) then
PlaySound("igMainMenuOptionCheckBoxOff");
else
PlaySound("igMainMenuOptionCheckBoxOn");
end
ExtVendorConfig_Option_OnEnter(self);
ExtVendorConfig_Option_OnLeave(self);
ExtVendorConfig_Option_OnEnter(self);
ExtVendorConfig_Option_OnLeave(self);
_G[self:GetName().."Low"]:SetText("50%");
_G[self:GetName().."High"]:SetText("150%");
ExtVendorConfig_Slider_OnValueChanged(self, self:GetID());
ExtVendorConfig_OnLoad(self);
PK
ГђLhЊ#ъе ъе ExtVendor/ExtVendor.luaEXTVENDOR_VERSION = GetAddOnMetadata("ExtVendor", "Version");
EXTVENDOR_VERSION_ID = 10602;
EXTVENDOR_ITEMS_PER_SUBPAGE = MERCHANT_ITEMS_PER_PAGE; -- transfer original page size to become "sub-pages"
EXTVENDOR_SUBPAGES_PER_PAGE = 2; -- number of sub-pages per page
MERCHANT_ITEMS_PER_PAGE = 20; -- overrides default value of base ui, default functions will handle page display accordingly
EXTVENDOR_HOOKS = {};
EXTVENDOR_DATA = {};
EXTVENDOR_PROFILE = "";
EXTVENDOR_SELECTED_QUALITY = 0;
EXTVENDOR_SPECIFIC_QUALITY = false;
local L = LibStub("AceLocale-3.0"):GetLocale("ExtVendor", true);
local EXTVENDOR_DUMMY;
local EXTVENDOR_DEBUG = false;
local EXTVENDOR_NUM_PAGES = 1;
local EXTVENDOR_SHOW_TRANSMOG_ONLY = false;
local EXTVENDOR_HIDE_COLLECTED_TRANSMOG = false;
local LAST_INVENTORY_UPDATE = 0;
local QUEUE_DISPLAY_REFRESH = false;
local SLOT_FILTER_INDEX = 0;
local SUPPRESS_UPDATES = false;
local SUPPRESS_SEARCH_ONCHANGE_UPDATE = false;
EXTVENDOR_ARMOR_RANKS = {
[L["ARMOR_CLOTH"]] = 1,
[L["ARMOR_LEATHER"]] = 2,
[L["ARMOR_MAIL"]] = 3,
[L["ARMOR_PLATE"]] = 4,
};
local SLOT_FILTERS = {
[1] = {"INVTYPE_HEAD", "INVTYPE_SHOULDER", "INVTYPE_CLOAK", "INVTYPE_CHEST", "INVTYPE_ROBE", "INVTYPE_WRIST", "INVTYPE_HAND", "INVTYPE_WAIST", "INVTYPE_LEGS", "INVTYPE_FEET"},
[2] = {"INVTYPE_HEAD"},
[3] = {"INVTYPE_SHOULDER"},
[4] = {"INVTYPE_CLOAK"},
[5] = {"INVTYPE_CHEST", "INVTYPE_ROBE"},
[6] = {"INVTYPE_WRIST"},
[7] = {"INVTYPE_HAND"},
[8] = {"INVTYPE_WAIST"},
[9] = {"INVTYPE_LEGS"},
[10] = {"INVTYPE_FEET"},
[20] = {"INVTYPE_NECK", "INVTYPE_BODY", "INVTYPE_TABARD", "INVTYPE_FINGER", "INVTYPE_TRINKET"},
[21] = {"INVTYPE_NECK"},
[22] = {"INVTYPE_BODY"},
[23] = {"INVTYPE_TABARD"},
[24] = {"INVTYPE_FINGER"},
[25] = {"INVTYPE_TRINKET"},
[30] = {"INVTYPE_WEAPON", "INVTYPE_WEAPONMAINHAND", "INVTYPE_2HWEAPON", "INVTYPE_WEAPONOFFHAND", "INVTYPE_RANGED", "INVTYPE_RANGEDRIGHT"},
[31] = {"INVTYPE_WEAPON", "INVTYPE_WEAPONMAINHAND"},
[32] = {"INVTYPE_2HWEAPON"},
[33] = {"INVTYPE_WEAPONOFFHAND"},
[34] = {"INVTYPE_RANGED", "INVTYPE_RANGEDRIGHT"},
[40] = {"INVTYPE_HOLDABLE", "INVTYPE_SHIELD"},
[41] = {"INVTYPE_HOLDABLE"},
[42] = {"INVTYPE_SHIELD"},
};
local function DebugMessage(msg)
if (not EXTVENDOR_DEBUG) then return; end
ExtVendor_Message("|cffff0000[DEBUG]|r " .. msg);
end
--========================================
-- Initial load routine
--========================================
function ExtVendor_OnLoad(self)
ExtVendor_RebuildMerchantFrame();
ExtVendor_UpdateButtonPositions();
EXTVENDOR_HOOKS["MerchantFrame_UpdateMerchantInfo"] = MerchantFrame_UpdateMerchantInfo;
MerchantFrame_UpdateMerchantInfo = function() end --ExtVendor_UpdateMerchantInfo;
EXTVENDOR_HOOKS["MerchantFrame_UpdateBuybackInfo"] = MerchantFrame_UpdateBuybackInfo;
MerchantFrame_UpdateBuybackInfo = ExtVendor_UpdateBuybackInfo;
EXTVENDOR_HOOKS["MerchantPrevPageButton_OnClick"] = MerchantPrevPageButton_OnClick;
MerchantPrevPageButton_OnClick = ExtVendor_PrevPageButton;
EXTVENDOR_HOOKS["MerchantNextPageButton_OnClick"] = MerchantNextPageButton_OnClick;
MerchantNextPageButton_OnClick = ExtVendor_NextPageButton;
MerchantFrame:HookScript("OnShow", ExtVendor_OnShow);
MerchantFrame:HookScript("OnHide", ExtVendor_OnHide);
self:RegisterEvent("ADDON_LOADED");
self:RegisterEvent("UNIT_INVENTORY_CHANGED");
self:RegisterEvent("MERCHANT_SHOW");
self:RegisterEvent("MERCHANT_UPDATE");
SLASH_EXTVENDOR1 = "/evui";
SlashCmdList["EXTVENDOR"] = ExtVendor_CommandHandler;
end
--========================================
-- Hooked merchant frame OnShow
--========================================
function ExtVendor_OnShow(self)
SUPPRESS_UPDATES = true;
SUPPRESS_SEARCH_ONCHANGE_UPDATE = true;
MerchantFrameSearchBox:SetText("");
if (EXTVENDOR_DATA['config']['stockfilter_defall']) then
SetMerchantFilter(LE_LOOT_FILTER_ALL);
end
ExtVendor_SetMinimumQuality(0);
ExtVendor_SetSlotFilter(0);
SUPPRESS_UPDATES = false;
end
--========================================
-- Hooked merchant frame OnHide
--========================================
function ExtVendor_OnHide(self)
CloseDropDownMenus();
end
--========================================
-- Event handler
--========================================
function ExtVendor_OnEvent(self, event, ...)
if (event == "ADDON_LOADED") then
local arg1 = ...;
if (arg1 == "ExtVendor") then
ExtVendor_Setup();
end
elseif (event == "UNIT_INVENTORY_CHANGED") then
local unit = ...;
if (unit == "player") then
if (MerchantFrame:IsVisible() and (not ExtVendor_IsProcessingQuickVendor())) then
ExtVendor_OnInventoryUpdate()
end
end
elseif ((event == "MERCHANT_SHOW") or (event == "MERCHANT_UPDATE")) then
QUEUE_DISPLAY_REFRESH = true;
end
end
--========================================
-- Update handler - handle refresh
-- queueing to limit the merchant frame
-- to no more than 1 refresh per
-- 1/10 seconds
--========================================
function ExtVendor_OnUpdate(self, elapsed)
if (QUEUE_DISPLAY_REFRESH) then
if ((GetTime() - LAST_INVENTORY_UPDATE) > 0.01) then
ExtVendor_UpdateDisplay();
LAST_INVENTORY_UPDATE = GetTime();
QUEUE_DISPLAY_REFRESH = false;
end
end
SUPPRESS_SEARCH_ONCHANGE_UPDATE = false;
end
--========================================
-- ...
--========================================
function ExtVendor_OnInventoryUpdate()
if ((GetTime() - LAST_INVENTORY_UPDATE) > 0.1) then
ExtVendor_UpdateDisplay();
LAST_INVENTORY_UPDATE = GetTime();
else
QUEUE_DISPLAY_REFRESH = true;
end
end
--========================================
-- Post-load setup
--========================================
function ExtVendor_Setup()
EXTVENDOR_PROFILE = GetRealmName() .. "." .. UnitName("player");
local version = ExtVendor_CheckSetting("version", EXTVENDOR_VERSION_ID);
EXTVENDOR_DATA['config']['version'] = EXTVENDOR_VERSION_ID;
ExtVendor_CheckSetting("usable_items", false);
ExtVendor_CheckSetting("hide_filtered", false);
ExtVendor_CheckSetting("optimal_armor", false);
ExtVendor_CheckSetting("show_suboptimal_armor", false);
ExtVendor_CheckSetting("hide_known_recipes", false);
ExtVendor_CheckSetting("stockfilter_defall", false);
ExtVendor_CheckSetting("show_load_message", false);
ExtVendor_CheckSetting("enable_quickvendor", true);
ExtVendor_CheckSetting("scale", 1);
ExtVendor_CheckSetting("filter_purchased_recipes", true);
ExtVendor_CheckSetting("quickvendor_suboptimal", false);
ExtVendor_CheckSetting("quickvendor_alreadyknown", false);
ExtVendor_CheckSetting("quickvendor_unusable", false);
ExtVendor_CheckSetting("quickvendor_whitegear", false);
if (EXTVENDOR_DATA['config']['show_load_message']) then
ExtVendor_Message(string.format(L["LOADED_MESSAGE"], EXTVENDOR_VERSION));
end
-- initialize the customizable blacklist
if (not EXTVENDOR_DATA['quickvendor_blacklist']) then
EXTVENDOR_DATA['quickvendor_blacklist'] = EXTVENDOR_QUICKVENDOR_DEFAULT_BLACKLIST;
end
-- initialize global whitelist
if (not EXTVENDOR_DATA['quickvendor_whitelist']) then
EXTVENDOR_DATA['quickvendor_whitelist'] = {};
end
if (not EXTVENDOR_DATA[EXTVENDOR_PROFILE]) then
EXTVENDOR_DATA[EXTVENDOR_PROFILE] = {};
end
-- initialize per-character whitelist
if (not EXTVENDOR_DATA[EXTVENDOR_PROFILE]['quickvendor_whitelist']) then
EXTVENDOR_DATA[EXTVENDOR_PROFILE]['quickvendor_whitelist'] = {};
end
ExtVendor_UpdateQuickVendorButtonVisibility();
end
--========================================
-- Check configuration setting, and
-- initialize with default value if not
-- present
--========================================
function ExtVendor_CheckSetting(field, default)
if (not EXTVENDOR_DATA['config']) then
EXTVENDOR_DATA['config'] = {};
end
if (EXTVENDOR_DATA['config'][field] == nil) then
EXTVENDOR_DATA['config'][field] = default;
end
return EXTVENDOR_DATA['config'][field];
end
--========================================
-- Rearrange item slot positions
--========================================
function ExtVendor_UpdateButtonPositions(isBuyBack)
local btn;
local vertSpacing;
if (isBuyBack) then
vertSpacing = -30;
horizSpacing = 50;
else
vertSpacing = -16;
horizSpacing = 12;
end
for i = 1, MERCHANT_ITEMS_PER_PAGE, 1 do
btn = _G["MerchantItem" .. i];
if (isBuyBack) then
if (i > BUYBACK_ITEMS_PER_PAGE) then
btn:Hide();
else
if (i == 1) then
btn:SetPoint("TOPLEFT", MerchantFrame, "TOPLEFT", 64, -105);
else
if ((i % 3) == 1) then
btn:SetPoint("TOPLEFT", _G["MerchantItem" .. (i - 3)], "BOTTOMLEFT", 0, vertSpacing);
else
btn:SetPoint("TOPLEFT", _G["MerchantItem" .. (i - 1)], "TOPRIGHT", horizSpacing, 0);
end
end
end
else
btn:Show();
if ((i % EXTVENDOR_ITEMS_PER_SUBPAGE) == 1) then
if (i == 1) then
btn:SetPoint("TOPLEFT", MerchantFrame, "TOPLEFT", 24, -70);
else
btn:SetPoint("TOPLEFT", _G["MerchantItem" .. (i - (EXTVENDOR_ITEMS_PER_SUBPAGE - 1))], "TOPRIGHT", 12, 0);
end
else
if ((i % 2) == 1) then
btn:SetPoint("TOPLEFT", _G["MerchantItem" .. (i - 2)], "BOTTOMLEFT", 0, vertSpacing);
else
btn:SetPoint("TOPLEFT", _G["MerchantItem" .. (i - 1)], "TOPRIGHT", horizSpacing, 0);
end
end
end
end
end
function ExtVendor_PrevPageButton()
EXTVENDOR_HOOKS["MerchantPrevPageButton_OnClick"]();
ExtVendor_UpdateMerchantInfo();
end
function ExtVendor_NextPageButton()
EXTVENDOR_HOOKS["MerchantNextPageButton_OnClick"]();
ExtVendor_UpdateMerchantInfo();
end
--========================================
-- Show merchant page
--========================================
function ExtVendor_UpdateMerchantInfo()
if (SUPPRESS_UPDATES) then return; end
EXTVENDOR_HOOKS["MerchantFrame_UpdateMerchantInfo"]();
ExtVendor_UpdateButtonPositions();
-- set title and portrait
MerchantNameText:SetText(UnitName("NPC"));
SetPortraitTexture(MerchantFramePortrait, "NPC");
-- locals
local totalMerchantItems = GetMerchantNumItems();
local visibleMerchantItems = 0;
local indexes = {};
local search = string.trim(MerchantFrameSearchBox:GetText());
local name, texture, price, quantity, numAvailable, isPurchasable, isUsable, extendedCost, r, g, b, notOptimal;
local link, quality, itemLevel, itemMinLevel, itemType, itemSubType, itemStackCount, itemEquipLoc, itemSellPrice, itemId, bindType;
local isFiltered = false;
local isKnown = false;
local isDarkmoonReplica = false;
local checkAlreadyKnown;
local kc;
local i, j;
-- **************************************************
-- Pre-check filtering if hiding filtered items
-- **************************************************
if (EXTVENDOR_DATA['config']['hide_filtered']) then
visibleMerchantItems = 0;
for i = 1, totalMerchantItems, 1 do
name, texture, price, quantity, numAvailable, isPurchasable, isUsable, extendedCost = GetMerchantItemInfo(i);
if (name) then
link = GetMerchantItemLink(i);
isDarkmoonReplica = false;
isBoP = false;
isKnown = false;
isFiltered = false;
quality = 1;
-- get info from item link
if (link) then
isKnown = ExtVendor_GetExtendedItemInfo(link);
itemId = ExtVendor_GetItemID(link);
EXTVENDOR_DUMMY, EXTVENDOR_DUMMY, quality, itemLevel, itemMinLevel, itemType, itemSubType, itemStackCount, itemEquipLoc, EXTVENDOR_DUMMY, itemSellPrice, EXTVENDOR_DUMMY, EXTVENDOR_DUMMY, bindType = GetItemInfo(link);
end
-- check if item is a darkmoon faire replica
if ((bindType ~= 1) and (string.sub(name, 1, string.len(L["REPLICA"]) + 1) == (L["REPLICA"] .. " "))) then
isDarkmoonReplica = true;
end
-- filter known recipes
if (EXTVENDOR_DATA['config']['hide_known_recipes'] and isKnown) then
isFiltered = true;
end
-- filter purchased recipes
if (EXTVENDOR_DATA['config']['filter_purchased_recipes']) then
if (itemType == L["ITEMTYPE_RECIPE"]) then
if (ExtVendor_HasItemInBags(itemId) > 0) then
isFiltered = true;
end
end
end
-- check search filter
if (string.len(search) > 0) then
if (not string.find(string.lower(name), string.lower(search), 1, true)) then
isFiltered = true;
end
end
-- check quality filter
if (EXTVENDOR_SELECTED_QUALITY > 0) then
if ((quality < EXTVENDOR_SELECTED_QUALITY) or ((quality > EXTVENDOR_SELECTED_QUALITY) and EXTVENDOR_SPECIFIC_QUALITY)) then
isFiltered = true;
end
end
-- check usability filter
if (EXTVENDOR_DATA['config']['usable_items'] and (not isUsable) and (quality ~= 7) and (not isDarkmoonReplica)) then
isFiltered = true;
end
-- check optimal armor filter
if (EXTVENDOR_DATA['config']['optimal_armor'] and (not EXTVENDOR_DATA['config']['show_suboptimal_armor'])) then
if ((quality ~= 7) and isUsable and (not isDarkmoonReplica)) then
if (not ExtVendor_IsOptimalArmor(itemType, itemSubType, itemEquipLoc)) then
isFiltered = true;
end
end
end
-- check slot filter
if (SLOT_FILTER_INDEX > 0) then
if (SLOT_FILTERS[SLOT_FILTER_INDEX]) then
local validSlot = false;
for j, slot in pairs(SLOT_FILTERS[SLOT_FILTER_INDEX]) do
if (slot == itemEquipLoc) then
validSlot = true;
end
end
if (not validSlot) then
isFiltered = true;
end
end
end
-- check transmog filter
if (EXTVENDOR_SHOW_TRANSMOG_ONLY) then
if (not ExtVendor_ItemIsValidForTransmog(itemType, itemSubType, itemEquipLoc)) then
isFiltered = true;
end
end
-- filter collected appearances
if (EXTVENDOR_HIDE_COLLECTED_TRANSMOG) then
if (ExtVendor_ItemIsValidForTransmog(itemType, itemSubType, itemEquipLoc)) then
local collected, collectedAlt = ExtVendor_ItemAppearanceIsOwned(itemId);
if (collected) then
isFiltered = true;
end
end
end
-- ***** add item to list if not filtered *****
if (not isFiltered) then
table.insert(indexes, i);
visibleMerchantItems = visibleMerchantItems + 1;
end
end
end
else
-- no item hiding, add all items to list
visibleMerchantItems = totalMerchantItems;
for i = 1, totalMerchantItems, 1 do
table.insert(indexes, i);
end
end
-- validate current page shown
if (MerchantFrame.page > math.max(1, math.ceil(visibleMerchantItems / MERCHANT_ITEMS_PER_PAGE))) then
MerchantFrame.page = math.max(1, math.ceil(visibleMerchantItems / MERCHANT_ITEMS_PER_PAGE));
end
-- Show correct page count based on number of items shown
MerchantPageText:SetFormattedText(MERCHANT_PAGE_NUMBER, MerchantFrame.page, math.ceil(visibleMerchantItems / MERCHANT_ITEMS_PER_PAGE));
-- **************************************************
-- Display items on merchant page
-- **************************************************
for i = 1, MERCHANT_ITEMS_PER_PAGE, 1 do
local index = ((MerchantFrame.page - 1) * MERCHANT_ITEMS_PER_PAGE) + i;
local itemButton = _G["MerchantItem" .. i .. "ItemButton"];
itemButton.link = nil;
local merchantButton = _G["MerchantItem" .. i];
local merchantMoney = _G["MerchantItem" .. i .. "MoneyFrame"];
local merchantAltCurrency = _G["MerchantItem" .. i .. "AltCurrencyFrame"];
if (index <= visibleMerchantItems) then
name, texture, price, quantity, numAvailable, isPurchasable, isUsable, extendedCost = GetMerchantItemInfo(indexes[index]);
if (name ~= nil) then
_G["MerchantItem"..i.."Name"]:SetText(name);
SetItemButtonCount(itemButton, quantity);
SetItemButtonStock(itemButton, numAvailable);
SetItemButtonTexture(itemButton, texture);
-- update item's currency info
if ( extendedCost and (price <= 0) ) then
itemButton.price = nil;
itemButton.extendedCost = true;
itemButton.link = GetMerchantItemLink(indexes[index]);
itemButton.texture = texture;
MerchantFrame_UpdateAltCurrency(indexes[index], i);
merchantAltCurrency:ClearAllPoints();
merchantAltCurrency:SetPoint("BOTTOMLEFT", "MerchantItem"..i.."NameFrame", "BOTTOMLEFT", 0, 31);
merchantMoney:Hide();
merchantAltCurrency:Show();
elseif ( extendedCost and (price > 0) ) then
itemButton.price = price;
itemButton.extendedCost = true;
itemButton.link = GetMerchantItemLink(indexes[index]);
itemButton.texture = texture;
MerchantFrame_UpdateAltCurrency(indexes[index], i);
MoneyFrame_Update(merchantMoney:GetName(), price);
merchantAltCurrency:ClearAllPoints();
merchantAltCurrency:SetPoint("LEFT", merchantMoney:GetName(), "RIGHT", -14, 0);
merchantAltCurrency:Show();
merchantMoney:Show();
else
itemButton.price = price;
itemButton.extendedCost = nil;
itemButton.link = GetMerchantItemLink(indexes[index]);
itemButton.texture = texture;
MoneyFrame_Update(merchantMoney:GetName(), price);
merchantAltCurrency:Hide();
merchantMoney:Show();
end
isDarkmoonReplica = false;
isKnown = false;
isFiltered = false;
quality = 1;
if (itemButton.link) then
isKnown = ExtVendor_GetExtendedItemInfo(itemButton.link);
itemId = ExtVendor_GetItemID(link);
EXTVENDOR_DUMMY, EXTVENDOR_DUMMY, quality, itemLevel, itemMinLevel, itemType, itemSubType, itemStackCount, itemEquipLoc, EXTVENDOR_DUMMY, itemSellPrice, EXTVENDOR_DUMMY, EXTVENDOR_DUMMY, bindType = GetItemInfo(itemButton.link);
end
-- check if item is a darkmoon faire replica
if ((bindType ~= 1) and (string.sub(name, 1, string.len(L["REPLICA"]) + 1) == (L["REPLICA"] .. " "))) then
isDarkmoonReplica = true;
end
-- check filtering
if (not EXTVENDOR_DATA['config']['hide_filtered']) then
-- check search filter
if (string.len(search) > 0) then
if (not string.find(string.lower(name), string.lower(search), 1, true)) then
isFiltered = true;
end
end
-- check usability filter
if (EXTVENDOR_DATA['config']['usable_items'] and (not isUsable) and (quality ~= 7)) then
isFiltered = true;
end
-- check quality filter
if (EXTVENDOR_SELECTED_QUALITY > 0) then
if ((quality < EXTVENDOR_SELECTED_QUALITY) or ((quality > EXTVENDOR_SELECTED_QUALITY) and EXTVENDOR_SPECIFIC_QUALITY)) then
isFiltered = true;
end
end
-- filter known recipes
if (EXTVENDOR_DATA['config']['hide_known_recipes'] and isKnown) then
isFiltered = true;
end
-- filter purchased recipes
if (EXTVENDOR_DATA['config']['filter_purchased_recipes']) then
if (itemType == L["ITEMTYPE_RECIPE"]) then
if (ExtVendor_HasItemInBags(itemId) > 0) then
isFiltered = true;
end
end
end
-- check slot filter
if (SLOT_FILTER_INDEX > 0) then
if (SLOT_FILTERS[SLOT_FILTER_INDEX]) then
local validSlot = false;
for j, slot in pairs(SLOT_FILTERS[SLOT_FILTER_INDEX]) do
if (slot == itemEquipLoc) then
validSlot = true;
end
end
if (not validSlot) then
isFiltered = true;
end
end
end
-- check transmog filter
if (EXTVENDOR_SHOW_TRANSMOG_ONLY) then
if (not ExtVendor_ItemIsValidForTransmog(itemType, itemSubType, itemEquipLoc)) then
isFiltered = true;
end
end
-- filter collected appearances
if (EXTVENDOR_HIDE_COLLECTED_TRANSMOG) then
if (ExtVendor_ItemIsValidForTransmog(itemType, itemSubType, itemEquipLoc)) then
local collected, collectedAlt = ExtVendor_ItemAppearanceIsOwned(itemId);
if (collected) then
isFiltered = true;
end
end
end
end
-- filter suboptimal armor
if ((quality ~= 7) and isUsable and (not isDarkmoonReplica)) then
if (EXTVENDOR_DATA['config']['optimal_armor']) then
if (not ExtVendor_IsOptimalArmor(itemType, itemSubType, itemEquipLoc)) then
isFiltered = true;
end
end
end
ExtVendor_SearchDimItem(_G["MerchantItem" .. i], isFiltered);
itemButton.hasItem = true;
itemButton:SetID(indexes[index]);
itemButton:Show();
local colorMult = 1.0;
local detailColor = {};
local slotColor = {};
-- unavailable items (limited stock, bought out) are darkened
if ( numAvailable == 0 ) then
colorMult = 0.5;
end
if ( not isUsable ) then
slotColor = {r = 1.0, g = 0, b = 0};
detailColor = {r = 1.0, g = 0, b = 0};
else
if (notOptimal) then
slotColor = {r = 0.25, g = 0.25, b = 0.25};
detailColor = {r = 0.5, g = 0, b = 0};
else
slotColor = {r = 1.0, g = 1.0, b = 1.0};
detailColor = {r = 0.5, g = 0.5, b = 0.5};
end
end
SetItemButtonNameFrameVertexColor(merchantButton, detailColor.r * colorMult, detailColor.g * colorMult, detailColor.b * colorMult);
SetItemButtonSlotVertexColor(merchantButton, slotColor.r * colorMult, slotColor.g * colorMult, slotColor.b * colorMult);
SetItemButtonTextureVertexColor(itemButton, slotColor.r * colorMult, slotColor.g * colorMult, slotColor.b * colorMult);
SetItemButtonNormalTextureVertexColor(itemButton, slotColor.r * colorMult, slotColor.g * colorMult, slotColor.b * colorMult);
end
else
itemButton.price = nil;
itemButton.hasItem = nil;
itemButton:Hide();
SetItemButtonNameFrameVertexColor(merchantButton, 0.5, 0.5, 0.5);
SetItemButtonSlotVertexColor(merchantButton,0.4, 0.4, 0.4);
_G["MerchantItem"..i.."Name"]:SetText("");
_G["MerchantItem"..i.."MoneyFrame"]:Hide();
_G["MerchantItem"..i.."AltCurrencyFrame"]:Hide();
ExtVendor_SearchDimItem(_G["MerchantItem" .. i], false);
end
end
MerchantFrame_UpdateRepairButtons();
-- Handle vendor buy back item
local buybackName, buybackTexture, buybackPrice, buybackQuantity, buybackNumAvailable, buybackIsUsable = GetBuybackItemInfo(GetNumBuybackItems());
if ( buybackName ) then
MerchantBuyBackItemName:SetText(buybackName);
SetItemButtonCount(MerchantBuyBackItemItemButton, buybackQuantity);
SetItemButtonStock(MerchantBuyBackItemItemButton, buybackNumAvailable);
SetItemButtonTexture(MerchantBuyBackItemItemButton, buybackTexture);
MerchantBuyBackItemMoneyFrame:Show();
MoneyFrame_Update("MerchantBuyBackItemMoneyFrame", buybackPrice);
MerchantBuyBackItem:Show();
else
MerchantBuyBackItemName:SetText("");
MerchantBuyBackItemMoneyFrame:Hide();
SetItemButtonTexture(MerchantBuyBackItemItemButton, "");
SetItemButtonCount(MerchantBuyBackItemItemButton, 0);
-- Hide the tooltip upon sale
if ( GameTooltip:IsOwned(MerchantBuyBackItemItemButton) ) then
GameTooltip:Hide();
end
end
-- Handle paging buttons
if ( visibleMerchantItems > MERCHANT_ITEMS_PER_PAGE ) then
if ( MerchantFrame.page == 1 ) then
MerchantPrevPageButton:Disable();
else
MerchantPrevPageButton:Enable();
end
if ( MerchantFrame.page == ceil(visibleMerchantItems / MERCHANT_ITEMS_PER_PAGE) or visibleMerchantItems == 0) then
MerchantNextPageButton:Disable();
else
MerchantNextPageButton:Enable();
end
EXTVENDOR_NUM_PAGES = ceil(visibleMerchantItems / MERCHANT_ITEMS_PER_PAGE);
MerchantPageText:Show();
MerchantPrevPageButton:Show();
MerchantNextPageButton:Show();
else
EXTVENDOR_NUM_PAGES = 1;
MerchantPageText:Hide();
MerchantPrevPageButton:Hide();
MerchantNextPageButton:Hide();
end
-- Show all merchant related items
MerchantBuyBackItem:Show();
MerchantFrameBottomLeftBorder:Show();
MerchantFrameBottomRightBorder:Show();
-- Hide buyback related items
for i = 13, MERCHANT_ITEMS_PER_PAGE, 1 do
_G["MerchantItem" .. i]:Show();
end
local numHiddenItems = math.max(0, totalMerchantItems - visibleMerchantItems);
local hstring = (numHiddenItems == 1) and L["SINGLE_ITEM_HIDDEN"] or L["MULTI_ITEMS_HIDDEN"];
MerchantFrameHiddenText:SetText(string.format(hstring, numHiddenItems));
ExtVendor_RefreshQuickVendorButton();
end
--========================================
-- Show buyback page
--========================================
function ExtVendor_UpdateBuybackInfo()
EXTVENDOR_HOOKS["MerchantFrame_UpdateBuybackInfo"]();
ExtVendor_UpdateButtonPositions(true);
end
--========================================
-- Rebuilds the merchant frame into
-- the extended design
--========================================
function ExtVendor_RebuildMerchantFrame()
-- set the new width of the frame
MerchantFrame:SetWidth(690);
-- create new item buttons as needed
for i = 1, MERCHANT_ITEMS_PER_PAGE, 1 do
if (not _G["MerchantItem" .. i]) then
CreateFrame("Frame", "MerchantItem" .. i, MerchantFrame, "MerchantItemTemplate");
end
end
-- Thank you Blizzard for making the frame dynamically resizable for me. :D
-- retexture the border element around the repair/buyback spots on the merchant tab
MerchantFrameBottomLeftBorder:SetTexture("Interface\\AddOns\\ExtVendor\\textures\\bottomborder");
MerchantFrameBottomRightBorder:SetTexture("Interface\\AddOns\\ExtVendor\\textures\\bottomborder");
-- alter the position of the buyback item slot on the merchant tab
MerchantBuyBackItem:ClearAllPoints();
MerchantBuyBackItem:SetPoint("TOPLEFT", MerchantItem10, "BOTTOMLEFT", -14, -20);
-- move the next/previous page buttons
MerchantPrevPageButton:ClearAllPoints();
MerchantPrevPageButton:SetPoint("CENTER", MerchantFrame, "BOTTOM", 30, 55);
MerchantPageText:ClearAllPoints();
MerchantPageText:SetPoint("BOTTOM", MerchantFrame, "BOTTOM", 160, 50);
MerchantNextPageButton:ClearAllPoints();
MerchantNextPageButton:SetPoint("CENTER", MerchantFrame, "BOTTOM", 290, 55);
-- currency insets
MerchantExtraCurrencyInset:ClearAllPoints();
MerchantExtraCurrencyInset:SetPoint("BOTTOMRIGHT", MerchantMoneyInset, "BOTTOMLEFT", 0, 0);
MerchantExtraCurrencyInset:SetPoint("TOPLEFT", MerchantMoneyInset, "TOPLEFT", -165, 0);
MerchantExtraCurrencyBg:ClearAllPoints();
MerchantExtraCurrencyBg:SetPoint("TOPLEFT", MerchantExtraCurrencyInset, "TOPLEFT", 3, -2);
MerchantExtraCurrencyBg:SetPoint("BOTTOMRIGHT", MerchantExtraCurrencyInset, "BOTTOMRIGHT", -3, 2);
-- add the search box
local editbox = CreateFrame("EditBox", "MerchantFrameSearchBox", MerchantFrame, "EV_SearchBoxTemplate");
editbox:SetWidth(200);
editbox:SetHeight(24);
editbox:SetPoint("TOPRIGHT", MerchantFrame, "TOPRIGHT", -15, -30);
editbox:SetAutoFocus(false);
editbox:SetScript("OnTextChanged", ExtVendor_OnSearchTextChanged);
editbox:SetMaxLetters(30);
-- add quick-vendor button
local junkBtn = CreateFrame("Button", "MerchantFrameSellJunkButton", MerchantFrame);
junkBtn:SetWidth(32);
junkBtn:SetHeight(32);
junkBtn:SetPoint("TOPLEFT", MerchantFrame, "TOPLEFT", 70, -27);
junkBtn.tooltip = L["QUICKVENDOR_BUTTON_TOOLTIP"];
junkBtn:SetScript("OnClick", ExtVendor_StartQuickVendor);
junkBtn:SetScript("OnEnter", ExtVendor_ShowButtonTooltip);
junkBtn:SetScript("OnLeave", ExtVendor_HideButtonTooltip);
junkBtn:SetPushedTexture("Interface\\Buttons\\UI-Quickslot-Depress");
junkBtn:SetHighlightTexture("Interface\\Buttons\\ButtonHilight-Square", "ADD");
junkBtnIcon = junkBtn:CreateTexture("MerchantFrameSellJunkButtonIcon", "BORDER");
junkBtnIcon:SetTexture("Interface\\Icons\\Inv_Misc_Bag_10");
junkBtnIcon:SetPoint("TOPLEFT", junkBtn, "TOPLEFT", 0, 0);
junkBtnIcon:SetPoint("BOTTOMRIGHT", junkBtn, "BOTTOMRIGHT", 0, 0);
-- filter button
local filterBtn = CreateFrame("Button", "MerchantFrameFilterButton", MerchantFrame, "UIMenuButtonStretchTemplate");
filterBtn:SetText(FILTER);
filterBtn:SetPoint("RIGHT", MerchantFrameSearchBox, "LEFT", -30, 0);
filterBtn:SetWidth(80);
filterBtn:SetHeight(22);
filterBtn:SetScript("OnClick", ExtVendor_DisplayFilterDropDown);
-- create text for showing number of hidden items
local hiddenText = MerchantFrame:CreateFontString("MerchantFrameHiddenText", "ARTWORK", "GameFontNormal");
hiddenText:SetPoint("RIGHT", MerchantFrameFilterButton, "LEFT", -10, 0);
hiddenText:SetJustifyH("RIGHT");
hiddenText:SetText("0 item(s) hidden");
-- hide the new stock filter dropdown
MerchantFrameLootFilter:Hide();
-- filter options dropdown
local filterDropdown = CreateFrame("Frame", "MerchantFrameFilterDropDown", UIParent, "UIDropDownMenuTemplate");
-- create a new tooltip object for handling item tooltips in the background
evTooltip = CreateFrame("GameTooltip", "ExtVendorHiddenTooltip", UIParent, "GameTooltipTemplate");
end
--========================================
-- Performs additional updates to main
-- display - fades items for searching
-- and applies quality colors to names
--========================================
function ExtVendor_UpdateDisplay()
if (not SUPPRESS_UPDATES) then
if (MerchantFrame.selectedTab == 1) then
ExtVendor_UpdateMerchantInfo();
elseif (MerchantFrame.selectedTab == 2) then
ExtVendor_UpdateBuybackInfo();
end
end
CloseDropDownMenus();
end
function ExtVendor_OnSearchTextChanged()
if (not SUPPRESS_SEARCH_ONCHANGE_UPDATE) then
ExtVendor_UpdateDisplay();
end
end
--========================================
-- Dims or shows an item frame
--========================================
function ExtVendor_SearchDimItem(itemFrame, isDimmed)
if (not itemFrame) then return; end
local alpha;
if (isDimmed) then
alpha = 0.2;
else
alpha = 1;
end
itemFrame:SetAlpha(alpha);
local btn = _G[itemFrame:GetName() .. "ItemButton"];
if (isDimmed) then
btn:Disable();
else
btn:Enable();
end
end
--========================================
-- Show button tooltips
--========================================
function ExtVendor_ShowButtonTooltip(self)
if (self.tooltip) then
GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
GameTooltip:SetText(self.tooltip);
GameTooltip:Show();
end
end
--========================================
-- Hide button tooltips
--========================================
function ExtVendor_HideButtonTooltip(self)
if (GameTooltip:GetOwner() == self) then
GameTooltip:Hide();
end
end
--========================================
-- Enable/disable the sell junk button
--========================================
function ExtVendor_SetJunkButtonState(state)
if (state) then
MerchantFrameSellJunkButton:Enable();
MerchantFrameSellJunkButtonIcon:SetDesaturated(false);
else
MerchantFrameSellJunkButton:Disable();
MerchantFrameSellJunkButtonIcon:SetDesaturated(true);
end
end
--========================================
-- Gold/silver/copper money formatting
--========================================
function ExtVendor_FormatMoneyString(value, trailing)
value = tonumber(value) or 0;
local gold = math.floor(value / 10000);
local silver = math.floor(value / 100) % 100;
local copper = value % 100;
local disp = "";
if (gold > 0) then
disp = disp .. format(GOLD_AMOUNT_TEXTURE, gold, 0, 0) .. " ";
end
if ((silver > 0) or (trailing and (gold > 0))) then
disp = disp .. format(SILVER_AMOUNT_TEXTURE, silver, 0, 0) .. " ";
end
if ((copper > 0) or (trailing and ((gold > 0) or (silver > 0)))) then
disp = disp .. format(COPPER_AMOUNT_TEXTURE, copper, 0, 0);
end
return disp;
end
--========================================
-- Initialize the item quality dropdown
--========================================
function ExtVendor_InitQualityFilter()
local info = {};
local color;
for i = 0, 7, 1 do
-- skip common, legendary and artifact qualities for now
if ((i ~= 1) and (i ~= 5) and (i ~= 6)) then
if (i == 0) then
info.text = ALL;
else
EXTVENDOR_DUMMY, EXTVENDOR_DUMMY, EXTVENDOR_DUMMY, color = GetItemQualityColor(i);
info.text = "|c" .. color .. _G["ITEM_QUALITY" .. i .. "_DESC"];
end
info.value = i;
info.checked = nil;
info.func = ExtVendor_SelectFilterQuality;
UIDropDownMenu_AddButton(info);
end
end
end
--========================================
-- Handler for selecting an item quality
--========================================
function ExtVendor_SelectFilterQuality(self)
UIDropDownMenu_SetSelectedValue(MerchantFrameQualityFilter, self.value);
EXTVENDOR_SELECTED_QUALITY = self.value;
ExtVendor_UpdateDisplay();
end
--========================================
-- Show the filter options dropdown menu
--========================================
function ExtVendor_DisplayFilterDropDown(self)
local className = UnitClass("player");
local currFilter = GetMerchantFilter();
stockFilters = { { text = className, checked = ((currFilter ~= LE_LOOT_FILTER_BOE) and (currFilter ~= LE_LOOT_FILTER_ALL)), func = function() ExtVendor_SetStockFilter(LE_LOOT_FILTER_CLASS); end } };
local numSpecs = GetNumSpecializations();
for i = 1, numSpecs do
local EXTVENDOR_DUMMY, name, EXTVENDOR_DUMMY, icon = GetSpecializationInfo(i);
table.insert(stockFilters, { text = name, checked = (currFilter == LE_LOOT_FILTER_SPEC1 + i - 1), leftPadding = 10, func = function() ExtVendor_SetStockFilter(LE_LOOT_FILTER_SPEC1 + i - 1); end });
end
table.insert(stockFilters, { text = ALL_SPECS, checked = (currFilter == LE_LOOT_FILTER_CLASS), leftPadding = 10, func = function() ExtVendor_SetStockFilter(LE_LOOT_FILTER_CLASS); end });
table.insert(stockFilters, { text = ITEM_BIND_ON_EQUIP, checked = (currFilter == LE_LOOT_FILTER_BOE), func = function(self) ExtVendor_SetStockFilter(LE_LOOT_FILTER_BOE); end });
table.insert(stockFilters, { text = ALL, checked = (currFilter == LE_LOOT_FILTER_ALL), func = function() ExtVendor_SetStockFilter(LE_LOOT_FILTER_ALL); end });
local menu = {
{ text = L["HIDE_FILTERED"], checked = EXTVENDOR_DATA['config']['hide_filtered'], func = function() ExtVendor_ToggleSetting("hide_filtered"); ExtVendor_UpdateDisplay(); end },
{ text = "", notCheckable = true, notClickable = true, disabled = true },
{ text = L["HIDE_UNUSABLE"], checked = EXTVENDOR_DATA['config']['usable_items'], func = function() ExtVendor_ToggleSetting("usable_items"); ExtVendor_UpdateDisplay(); end },
{ text = L["HIDE_KNOWN_RECIPES"], checked = EXTVENDOR_DATA['config']['hide_known_recipes'], func = function() ExtVendor_ToggleSetting("hide_known_recipes"); ExtVendor_UpdateDisplay(); end },
{ text = L["FILTER_SUBOPTIMAL"], checked = EXTVENDOR_DATA['config']['optimal_armor'], func = function() ExtVendor_ToggleSetting("optimal_armor"); ExtVendor_UpdateDisplay(); end },
{ text = L["FILTER_TRANSMOG"], hasArrow = true, notCheckable = true,
menuList = {
{ text = L["FILTER_TRANSMOG_ONLY"], checked = EXTVENDOR_SHOW_TRANSMOG_ONLY, func = function() ExtVendor_SetFilterTransmogOnly(not EXTVENDOR_SHOW_TRANSMOG_ONLY); end },
{ text = L["FILTER_COLLECTED_TRANSMOG"], checked = EXTVENDOR_HIDE_COLLECTED_TRANSMOG, func = function() ExtVendor_SetFilterCollectedTransmog(not EXTVENDOR_HIDE_COLLECTED_TRANSMOG); end },
},
},
{ text = L["FILTER_RECIPES"], hasArrow = true, notCheckable = true,
menuList = {
{ text = L["FILTER_ALREADY_KNOWN"], checked = EXTVENDOR_DATA['config']['hide_known_recipes'], func = function() ExtVendor_ToggleSetting("hide_known_recipes"); ExtVendor_UpdateDisplay(); end },
{ text = L["FILTER_PURCHASED"], checked = EXTVENDOR_DATA['config']['filter_purchased_recipes'], func = function() ExtVendor_ToggleSetting("filter_purchased_recipes"); ExtVendor_UpdateDisplay(); end },
},
},
{ text = L["FILTER_SLOT"], hasArrow = true, notCheckable = true,
menuList = {
{ text = ALL, checked = (SLOT_FILTER_INDEX == 0), func = function() ExtVendor_SetSlotFilter(0); end },
{ text = L["SLOT_CAT_ARMOR"], hasArrow = true, notCheckable = true,
menuList = {
{ text = ALL, checked = (SLOT_FILTER_INDEX == 1), func = function() ExtVendor_SetSlotFilter(1); end },
{ text = L["SLOT_HEAD"], checked = (SLOT_FILTER_INDEX == 2), func = function() ExtVendor_SetSlotFilter(2); end },
{ text = L["SLOT_SHOULDER"], checked = (SLOT_FILTER_INDEX == 3), func = function() ExtVendor_SetSlotFilter(3); end },
{ text = L["SLOT_BACK"], checked = (SLOT_FILTER_INDEX == 4), func = function() ExtVendor_SetSlotFilter(4); end },
{ text = L["SLOT_CHEST"], checked = (SLOT_FILTER_INDEX == 5), func = function() ExtVendor_SetSlotFilter(5); end },
{ text = L["SLOT_WRIST"], checked = (SLOT_FILTER_INDEX == 6), func = function() ExtVendor_SetSlotFilter(6); end },
{ text = L["SLOT_HANDS"], checked = (SLOT_FILTER_INDEX == 7), func = function() ExtVendor_SetSlotFilter(7); end },
{ text = L["SLOT_WAIST"], checked = (SLOT_FILTER_INDEX == 8), func = function() ExtVendor_SetSlotFilter(8); end },
{ text = L["SLOT_LEGS"], checked = (SLOT_FILTER_INDEX == 9), func = function() ExtVendor_SetSlotFilter(9); end },
{ text = L["SLOT_FEET"], checked = (SLOT_FILTER_INDEX == 10), func = function() ExtVendor_SetSlotFilter(10); end },
},
},
{ text = L["SLOT_CAT_ACCESSORIES"], hasArrow = true, notCheckable = true,
menuList = {
{ text = ALL, checked = (SLOT_FILTER_INDEX == 20), func = function() ExtVendor_SetSlotFilter(20); end },
{ text = L["SLOT_NECK"], checked = (SLOT_FILTER_INDEX == 21), func = function() ExtVendor_SetSlotFilter(21); end },
{ text = L["SLOT_SHIRT"], checked = (SLOT_FILTER_INDEX == 22), func = function() ExtVendor_SetSlotFilter(22); end },
{ text = L["SLOT_TABARD"], checked = (SLOT_FILTER_INDEX == 23), func = function() ExtVendor_SetSlotFilter(23); end },
{ text = L["SLOT_FINGER"], checked = (SLOT_FILTER_INDEX == 24), func = function() ExtVendor_SetSlotFilter(24); end },
{ text = L["SLOT_TRINKET"], checked = (SLOT_FILTER_INDEX == 25), func = function() ExtVendor_SetSlotFilter(25); end },
},
},
{ text = L["SLOT_CAT_WEAPONS"], hasArrow = true, notCheckable = true,
menuList = {
{ text = ALL, checked = (SLOT_FILTER_INDEX == 30), func = function() ExtVendor_SetSlotFilter(30); end },
{ text = L["SLOT_WEAPON1H"], checked = (SLOT_FILTER_INDEX == 31), func = function() ExtVendor_SetSlotFilter(31); end },
{ text = L["SLOT_WEAPON2H"], checked = (SLOT_FILTER_INDEX == 32), func = function() ExtVendor_SetSlotFilter(32); end },
{ text = L["SLOT_WEAPONOH"], checked = (SLOT_FILTER_INDEX == 33), func = function() ExtVendor_SetSlotFilter(33); end },
{ text = L["SLOT_RANGED"], checked = (SLOT_FILTER_INDEX == 34), func = function() ExtVendor_SetSlotFilter(34); end },
},
},
{ text = L["SLOT_CAT_OFFHAND"], hasArrow = true, notCheckable = true,
menuList = {
{ text = ALL, checked = (SLOT_FILTER_INDEX == 40), func = function() ExtVendor_SetSlotFilter(40); end },
{ text = L["SLOT_OFFHAND"], checked = (SLOT_FILTER_INDEX == 41), func = function() ExtVendor_SetSlotFilter(41); end },
{ text = L["SLOT_SHIELD"], checked = (SLOT_FILTER_INDEX == 42), func = function() ExtVendor_SetSlotFilter(42); end },
},
},
},
},
{ text = L["QUALITY_FILTER_MINIMUM"], hasArrow = true, notCheckable = true,
menuList = {
{ text = ALL, checked = (EXTVENDOR_SELECTED_QUALITY == 0), func = function() ExtVendor_SetMinimumQuality(0); end },
{ text = ITEM_QUALITY_COLORS[2].hex .. ITEM_QUALITY2_DESC, checked = (EXTVENDOR_SELECTED_QUALITY == 2), func = function() ExtVendor_SetMinimumQuality(2); end },
{ text = ITEM_QUALITY_COLORS[3].hex .. ITEM_QUALITY3_DESC, checked = (EXTVENDOR_SELECTED_QUALITY == 3), func = function() ExtVendor_SetMinimumQuality(3); end },
{ text = ITEM_QUALITY_COLORS[4].hex .. ITEM_QUALITY4_DESC, checked = (EXTVENDOR_SELECTED_QUALITY == 4), func = function() ExtVendor_SetMinimumQuality(4); end },
{ text = ITEM_QUALITY_COLORS[7].hex .. ITEM_QUALITY7_DESC, checked = (EXTVENDOR_SELECTED_QUALITY == 7), func = function() ExtVendor_SetMinimumQuality(7); end },
},
},
{ text = L["QUALITY_FILTER_SPECIFIC"], hasArrow = true, notCheckable = true,
menuList = {
{ text = ALL, checked = (EXTVENDOR_SELECTED_QUALITY == 0), func = function() ExtVendor_SetMinimumQuality(0); end },
{ text = ITEM_QUALITY_COLORS[1].hex .. ITEM_QUALITY1_DESC, checked = (EXTVENDOR_SELECTED_QUALITY == 1), func = function() ExtVendor_SetSpecificQuality(1); end },
{ text = ITEM_QUALITY_COLORS[2].hex .. ITEM_QUALITY2_DESC, checked = (EXTVENDOR_SELECTED_QUALITY == 2), func = function() ExtVendor_SetSpecificQuality(2); end },
{ text = ITEM_QUALITY_COLORS[3].hex .. ITEM_QUALITY3_DESC, checked = (EXTVENDOR_SELECTED_QUALITY == 3), func = function() ExtVendor_SetSpecificQuality(3); end },
{ text = ITEM_QUALITY_COLORS[4].hex .. ITEM_QUALITY4_DESC, checked = (EXTVENDOR_SELECTED_QUALITY == 4), func = function() ExtVendor_SetSpecificQuality(4); end },
{ text = ITEM_QUALITY_COLORS[7].hex .. ITEM_QUALITY7_DESC, checked = (EXTVENDOR_SELECTED_QUALITY == 7), func = function() ExtVendor_SetSpecificQuality(7); end },
},
},
{ text = L["STOCK_FILTER"], hasArrow = true, notCheckable = true, menuList = stockFilters },
{ text = "", notCheckable = true, notClickable = true, disabled = true },
{ text = L["CONFIGURE_QUICKVENDOR"], notCheckable = true, func = function() ExtVendor_QVConfigFrame:Show(); end },
};
EasyMenu(menu, MerchantFrameFilterDropDown, self, 0, 0, "MENU", 1);
end
--========================================
-- Sets the 'stock' filter and updates
-- the vendor display
--========================================
function ExtVendor_SetStockFilter(index)
SetMerchantFilter(index);
ExtVendor_UpdateDisplay();
end
--========================================
-- Toggles a boolean config setting
--========================================
function ExtVendor_ToggleSetting(name)
if (EXTVENDOR_DATA['config'][name]) then
EXTVENDOR_DATA['config'][name] = false;
else
EXTVENDOR_DATA['config'][name] = true;
end
end
--========================================
-- Sets the minimum quality filter
--========================================
function ExtVendor_SetMinimumQuality(quality)
EXTVENDOR_SELECTED_QUALITY = math.max(0, math.min(7, quality));
EXTVENDOR_SPECIFIC_QUALITY = false;
ExtVendor_UpdateDisplay();
end
--========================================
-- Sets the specific quality filter
--========================================
function ExtVendor_SetSpecificQuality(quality)
EXTVENDOR_SELECTED_QUALITY = math.max(0, math.min(7, quality));
EXTVENDOR_SPECIFIC_QUALITY = true;
ExtVendor_UpdateDisplay();
end
--========================================
-- Output message to chat frame
--========================================
function ExtVendor_Message(msg)
DEFAULT_CHAT_FRAME:AddMessage("|cffffff00<" .. L["ADDON_TITLE"] .. ">|r " .. msg);
end
--========================================
-- Slash command handler
--========================================
function ExtVendor_CommandHandler(cmd)
if (strlower(cmd) == "debug") then
EXTVENDOR_DEBUG = not EXTVENDOR_DEBUG;
if (EXTVENDOR_DEBUG) then
ExtVendor_Message("Debugging mode enabled");
else
ExtVendor_Message("Debugging mode disabled");
end
return;
end
InterfaceOptionsFrame_OpenToCategory(ExtVendorConfigContainer);
end
--========================================
-- Called with pcall to safely catch
-- errors (fixes battle pet error)
--========================================
function ExtVendor_SetHiddenTooltip(link)
ExtVendorHiddenTooltip:SetHyperlink(link);
end
--========================================
-- Changes the equipment slot filter
--========================================
function ExtVendor_SetSlotFilter(index)
SLOT_FILTER_INDEX = index;
ExtVendor_UpdateDisplay();
end
--========================================
-- Sets the scale of the vendor frame to
-- the configured scale
--========================================
function ExtVendor_UpdateScale()
MerchantFrame:SetScale(EXTVENDOR_DATA['config']['scale']);
end
--========================================
-- Returns how many of an item of the
-- specified ID is in the player's bags
--========================================
function ExtVendor_HasItemInBags(itemId)
local count = 0;
for bag = 0, 4, 1 do
if (GetContainerNumSlots(bag)) then
for slot = 1, GetContainerNumSlots(bag), 1 do
local id = GetContainerItemID(bag, slot);
if (id == itemId) then
count = count + 1;
end
end
end
end
return count;
end
--========================================
-- Updates the quick vendor button's
-- state based on combat/inventory
--========================================
function ExtVendor_RefreshQuickVendorButton()
if (not InCombatLockdown()) then
if (ExtVendor_GetQuickVendorList()) then
ExtVendor_SetJunkButtonState(true);
else
ExtVendor_SetJunkButtonState(false);
end
else
ExtVendor_SetJunkButtonState(false);
end
end
--========================================
-- Returns whether an item is of a type
-- that can be transmogrified (armor or
-- weapon - excluding rings, etc.)
--========================================
function ExtVendor_ItemIsValidForTransmog(itemType, itemSubType, equipSlot)
if ((itemType ~= "Weapon") and (itemType ~= "Armor")) then return false; end
if ((equipSlot ~= "INVTYPE_HEAD") and
(equipSlot ~= "INVTYPE_SHOULDER") and
(equipSlot ~= "INVTYPE_CLOAK") and
(equipSlot ~= "INVTYPE_CHEST") and (equipSlot ~= "INVTYPE_ROBE") and
(equipSlot ~= "INVTYPE_BODY") and
(equipSlot ~= "INVTYPE_TABARD") and
(equipSlot ~= "INVTYPE_WRIST") and
(equipSlot ~= "INVTYPE_HAND") and
(equipSlot ~= "INVTYPE_WAIST") and
(equipSlot ~= "INVTYPE_LEGS") and
(equipSlot ~= "INVTYPE_FEET") and
(equipSlot ~= "INVTYPE_WEAPON") and
(equipSlot ~= "INVTYPE_2HWEAPON") and
(equipSlot ~= "INVTYPE_WEAPONMAINHAND") and
(equipSlot ~= "INVTYPE_WEAPONOFFHAND") and
(equipSlot ~= "INVTYPE_HOLDABLE") and
(equipSlot ~= "INVTYPE_SHIELD") and
(equipSlot ~= "INVTYPE_RANGED") and
(equipSlot ~= "INVTYPE_RANGEDRIGHT")) then return false; end
return true;
end
--========================================
-- Enables/disables filtering of
-- transmoggable item types
--========================================
function ExtVendor_SetFilterTransmogOnly(state)
EXTVENDOR_SHOW_TRANSMOG_ONLY = state;
ExtVendor_UpdateDisplay();
end
--========================================
-- Enables/disables filtering of
-- collected item appearances
--========================================
function ExtVendor_SetFilterCollectedTransmog(state)
EXTVENDOR_HIDE_COLLECTED_TRANSMOG = state;
ExtVendor_UpdateDisplay();
end
--========================================
-- Returns whether the player has
-- collected the appearance for the
-- specified item, and/or any other items
-- that share the same appearance
--========================================
function ExtVendor_ItemAppearanceIsOwned(itemId)
if (not itemId) then return false, false; end
local itemVisualId, itemSourceId = C_TransmogCollection.GetItemInfo(itemId);
local sourceInfo = C_TransmogCollection.GetSourceInfo(itemSourceId);
local found = sourceInfo.isCollected;
local foundAlt = false;
local itemName = sourceInfo.name;
local sources = C_TransmogCollection.GetAllAppearanceSources(sourceInfo.visualID);
for i, sourceID in ipairs(sources) do
local sourceInfo = C_TransmogCollection.GetSourceInfo(sourceID)
if sourceInfo.isCollected then
foundAlt = true;
end
end
return found, foundAlt;
end
PK
ЌЕђLГG!У У ExtVendor/ExtVendor.toc## Interface: 80000
## Title: Extended Vendor UI |cffffffffv1.7.0a
## Notes: Extends the merchant interface for easier browsing.
## Author: Germbread
## Version: 1.7.0a
## SavedVariables: EXTVENDOR_DATA
## X-Email: germbread@gmail.com
lib\LibStub.lua
lib\AceLocale-3.0.lua
locale\enUS.lua
locale\zhTW.lua
locale\zhCN.lua
ExtVendor.xml
SellJunkPopup.xml
config\Config.xml
config\about.xml
QuickVendorConfig\QuickVendorConfig.xml
PK
=яJGЯЁФ Ф ExtVendor/ExtVendor.xml
EditBox_ClearFocus(self);
EditBox_ClearHighlight(self);
EditBox_HighlightText(self);
ExtVendor_OnLoad(self);
ExtVendor_OnEvent(self, event, ...);
ExtVendor_OnUpdate(self, elapsed);
PK
ЗђLйЫј$ ј$ ExtVendor/ItemInfo.lualocal L = LibStub("AceLocale-3.0"):GetLocale("ExtVendor", true);
local CLASS_PROFICIENCIES = {
["DEATHKNIGHT"] = {
weapons = { "1H_AXE", "1H_MACE", "1H_SWORD", "2H_AXE", "2H_MACE", "2H_SWORD", "POLEARM" },
},
-- # TODO: verify that DEMONHUNTER is the proper class id
["DEMONHUNTER"] = {
weapons = { "WARGLAIVE", "DAGGER", "FIST", "1H_AXE", "1H_MACE", "1H_SWORD" },
},
["DRUID"] = {
weapons = { "1H_MACE", "2H_MACE", "POLEARM", "STAFF", "DAGGER", "FIST" },
},
["HUNTER"] = {
weapons = { "1H_AXE", "1H_SWORD", "2H_AXE", "2H_SWORD", "POLEARM", "STAFF", "DAGGER", "FIST", "BOW", "GUN", "CROSSBOW" },
},
["MAGE"] = {
weapons = { "1H_SWORD", "STAFF", "DAGGER", "WAND" },
},
["MONK"] = {
weapons = { "1H_AXE", "1H_MACE", "1H_SWORD", "POLEARM", "STAFF", "FIST" },
},
["PALADIN"] = {
weapons = { "1H_AXE", "1H_MACE", "1H_SWORD", "2H_AXE", "2H_MACE", "2H_SWORD", "POLEARM" },
canUseShields = true,
},
["PRIEST"] = {
weapons = { "1H_MACE", "DAGGER", "STAFF", "WAND" },
},
["ROGUE"] = {
weapons = { "1H_AXE", "1H_MACE", "1H_SWORD", "DAGGER", "FIST" },
},
["SHAMAN"] = {
weapons = { "1H_AXE", "1H_MACE", "2H_AXE", "2H_MACE", "DAGGER", "FIST", "STAFF" },
canUseShields = true,
},
["WARLOCK"] = {
weapons = { "1H_SWORD", "DAGGER", "STAFF", "WAND" },
},
["WARRIOR"] = {
weapons = { "1H_AXE", "1H_MACE", "1H_SWORD", "2H_AXE", "2H_MACE", "2H_SWORD", "DAGGER", "FIST", "POLEARM", "STAFF" },
canUseShields = true,
},
};
--========================================
-- Retrieve additional item info via the
-- item's tooltip
--========================================
function ExtVendor_GetExtendedItemInfo(link)
-- set up return values
local isKnown = false;
local classes = {};
local isAccountBound = false;
-- generate item tooltip in hidden tooltip object
ExtVendorHiddenTooltip:SetOwner(UIParent, "ANCHOR_LEFT");
local itemId = ExtVendor_GetItemID(link);
local ok = pcall(ExtVendor_SetHiddenTooltip, link);
if (ok) then
for cl = 2, ExtVendorHiddenTooltip:NumLines(), 1 do
local checkLine = _G["ExtVendorHiddenTooltipTextLeft" .. cl]:GetText();
if (checkLine) then
-- check for "Already Known"
if (checkLine == ITEM_SPELL_KNOWN) then
isKnown = true;
end
-- check for battle.net account binding
if (string.match(checkLine, ITEM_BIND_TO_BNETACCOUNT) or string.match(checkLine, ITEM_BIND_TO_ACCOUNT)) then
isAccountBound = true;
end
-- check for "Classes: xxx"
local checkClasses = ExtVendor_GetRequiredClasses(checkLine);
if (checkClasses) then
classes = checkClasses;
end
end
end
end
ExtVendorHiddenTooltip:Hide();
return isKnown, classes, itemId, isAccountBound;
end
--========================================
-- Returns an item's ID from the given
-- link
--========================================
function ExtVendor_GetItemID(link)
if (link) then
local w;
for w in string.gmatch(link, "item:(%d+):") do
return tonumber(w);
end
end
return nil;
end
--========================================
-- Returns a list of required classes
-- based on the "Classes:" line of an
-- item tooltip
--========================================
function ExtVendor_GetRequiredClasses(tooltipString)
if (string.find(tooltipString, L["CLASSES"])) then
local out = {};
local i;
local className = "";
for i = string.len(L["CLASSES"]) + 1, string.len(tooltipString), 1 do
local chr = string.sub(tooltipString, i, i);
local skipChar = false;
local finishName = false;
if (chr == ",") then
finishName = true;
skipChar = true;
elseif (i == string.len(tooltipString)) then
finishName = true;
end
if (not skipChar) then
className = className .. chr;
end
if (finishName) then
table.insert(out, string.trim(className));
className = "";
end
end
return out;
end
return nil;
end
--========================================
-- Returns whether or not the specified
-- class is in the given list of classes
--========================================
function ExtVendor_ClassIsAllowed(class, classes)
if (table.maxn(classes) > 0) then
for index, name in pairs(classes) do
if (class == name) then
return true;
end
end
return false;
end
return true;
end
--========================================
-- Returns whether or not the character's
-- class can EVER wear armor of the given
-- type (e.g. mages can NEVER wear
-- leather or higher, shamans can NEVER
-- wear plate, etc.)
--========================================
function ExtVendor_IsUsableArmorType(type, subType, slot)
local maxArmor = select(2, ExtVendor_GetOptimalArmorType());
if ((type == L["ARMOR"]) and (slot ~= "INVTYPE_CLOAK")) then
if ((subType == L["ARMOR_CLOTH"]) or (subType == L["ARMOR_LEATHER"]) or (subType == L["ARMOR_MAIL"]) or (subType == L["ARMOR_PLATE"])) then
if (EXTVENDOR_ARMOR_RANKS[subType] > EXTVENDOR_ARMOR_RANKS[maxArmor]) then
return false;
end
elseif (subType == L["ARMOR_SHIELD"]) then
local EXTVENDOR_DUMMY, cls = UnitClass("player");
if (CLASS_PROFICIENCIES[cls].canUseShields) then
return true;
end
return false;
end
end
return true;
end
--========================================
-- Returns whether or not the character's
-- class can use the given weapon type
-- based on class proficiencies
--========================================
function ExtVendor_IsUsableWeaponType(type, subType, slot)
if (type == L["WEAPON"]) then
if ((subType == L["WEAPON_1H_AXE"]) or (subType == L["WEAPON_1H_MACE"]) or (subType == L["WEAPON_1H_SWORD"]) or (subType == L["WEAPON_2H_AXE"])
or (subType == L["WEAPON_2H_MACE"]) or (subType == L["WEAPON_2H_SWORD"]) or (subType == L["WEAPON_POLEARM"]) or (subType == L["WEAPON_DAGGER"])
or (subType == L["WEAPON_FIST"]) or (subType == L["WEAPON_STAFF"]) or (subType == L["WEAPON_WAND"]) or (subType == L["WEAPON_BOW"])
or (subType == L["WEAPON_GUN"]) or (subType == L["WEAPON_CROSSBOW"])) then
local EXTVENDOR_DUMMY, cls = UnitClass("player");
for index, wt in pairs(CLASS_PROFICIENCIES[cls].weapons) do
if (L["WEAPON_" .. wt] == subType) then
return true;
end
end
return false;
end
end
return true;
end
--========================================
-- Determine if a piece of armor is the
-- best type for the player's class
-- (cloth/leather/mail/plate)
--========================================
function ExtVendor_IsOptimalArmor(type, subType, slot)
if (type == L["ARMOR"]) then
if (slot == "INVTYPE_CLOAK") then
return true;
end
if ((subType == L["ARMOR_CLOTH"]) or (subType == L["ARMOR_LEATHER"]) or (subType == L["ARMOR_MAIL"]) or (subType == L["ARMOR_PLATE"])) then
local opt = ExtVendor_GetOptimalArmorType();
if (EXTVENDOR_ARMOR_RANKS[subType] < EXTVENDOR_ARMOR_RANKS[opt]) then
--DebugMessage("ExtVendor_IsOptimalArmor(\"" .. type .. "\", \"" .. subType .. "\", \"" .. slot .. "\") = FALSE");
return false;
end
end
end
--DebugMessage("ExtVendor_IsOptimalArmor(\"" .. type .. "\", \"" .. subType .. "\", \"" .. slot .. "\") = TRUE");
return true;
end
--========================================
-- Returns the optimal armor type for the
-- player's class (factors in level for
-- hunters, shamans, paladins and
-- warriors), as well as the highest
-- armor type the class can ever wear
-- (regardless of level)
--========================================
function ExtVendor_GetOptimalArmorType()
local EXTVENDOR_DUMMY, cls = UnitClass("player");
local lvl = UnitLevel("player");
local optArmor, maxArmor;
if ((cls == "MAGE") or (cls == "WARLOCK") or (cls == "PRIEST")) then
maxArmor = L["ARMOR_CLOTH"];
elseif ((cls == "ROGUE") or (cls == "DRUID") or (cls == "MONK") or (cls == "DEMONHUNTER")) then
maxArmor = L["ARMOR_LEATHER"];
elseif ((cls == "HUNTER") or (cls == "SHAMAN")) then
maxArmor = L["ARMOR_MAIL"];
elseif ((cls == "PALADIN") or (cls == "WARRIOR") or (cls == "DEATHKNIGHT")) then
maxArmor = L["ARMOR_PLATE"];
end
optArmor = maxArmor;
return optArmor, maxArmor;
end
PK
N~ёL ExtVendor/lib/PK
Тyн>ЂVMO O ExtVendor/lib/AceLocale-3.0.lua--- **AceLocale-3.0** manages localization in addons, allowing for multiple locale to be registered with fallback to the base locale for untranslated strings.
-- @class file
-- @name AceLocale-3.0
-- @release $Id: AceLocale-3.0.lua 1005 2011-01-29 14:19:43Z mikk $
local MAJOR,MINOR = "AceLocale-3.0", 5
local AceLocale, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
if not AceLocale then return end -- no upgrade needed
-- Lua APIs
local assert, tostring, error = assert, tostring, error
local setmetatable, rawset, rawget = setmetatable, rawset, rawget
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script
-- GLOBALS: GAME_LOCALE, geterrorhandler
local gameLocale = GetLocale()
if gameLocale == "enGB" then
gameLocale = "enUS"
end
AceLocale.apps = AceLocale.apps or {} -- array of ["AppName"]=localetableref
AceLocale.appnames = AceLocale.appnames or {} -- array of [localetableref]="AppName"
-- This metatable is used on all tables returned from GetLocale
local readmeta = {
__index = function(self, key) -- requesting totally unknown entries: fire off a nonbreaking error and return key
rawset(self, key, key) -- only need to see the warning once, really
geterrorhandler()(MAJOR..": "..tostring(AceLocale.appnames[self])..": Missing entry for '"..tostring(key).."'")
return key
end
}
-- This metatable is used on all tables returned from GetLocale if the silent flag is true, it does not issue a warning on unknown keys
local readmetasilent = {
__index = function(self, key) -- requesting totally unknown entries: return key
rawset(self, key, key) -- only need to invoke this function once
return key
end
}
-- Remember the locale table being registered right now (it gets set by :NewLocale())
-- NOTE: Do never try to register 2 locale tables at once and mix their definition.
local registering
-- local assert false function
local assertfalse = function() assert(false) end
-- This metatable proxy is used when registering nondefault locales
local writeproxy = setmetatable({}, {
__newindex = function(self, key, value)
rawset(registering, key, value == true and key or value) -- assigning values: replace 'true' with key string
end,
__index = assertfalse
})
-- This metatable proxy is used when registering the default locale.
-- It refuses to overwrite existing values
-- Reason 1: Allows loading locales in any order
-- Reason 2: If 2 modules have the same string, but only the first one to be
-- loaded has a translation for the current locale, the translation
-- doesn't get overwritten.
--
local writedefaultproxy = setmetatable({}, {
__newindex = function(self, key, value)
if not rawget(registering, key) then
rawset(registering, key, value == true and key or value)
end
end,
__index = assertfalse
})
--- Register a new locale (or extend an existing one) for the specified application.
-- :NewLocale will return a table you can fill your locale into, or nil if the locale isn't needed for the players
-- game locale.
-- @paramsig application, locale[, isDefault[, silent]]
-- @param application Unique name of addon / module
-- @param locale Name of the locale to register, e.g. "enUS", "deDE", etc.
-- @param isDefault If this is the default locale being registered (your addon is written in this language, generally enUS)
-- @param silent If true, the locale will not issue warnings for missing keys. Must be set on the first locale registered. If set to "raw", nils will be returned for unknown keys (no metatable used).
-- @usage
-- -- enUS.lua
-- local L = LibStub("AceLocale-3.0"):NewLocale("TestLocale", "enUS", true)
-- L["string1"] = true
--
-- -- deDE.lua
-- local L = LibStub("AceLocale-3.0"):NewLocale("TestLocale", "deDE")
-- if not L then return end
-- L["string1"] = "Zeichenkette1"
-- @return Locale Table to add localizations to, or nil if the current locale is not required.
function AceLocale:NewLocale(application, locale, isDefault, silent)
-- GAME_LOCALE allows translators to test translations of addons without having that wow client installed
local gameLocale = GAME_LOCALE or gameLocale
local app = AceLocale.apps[application]
if silent and app then
geterrorhandler()("Usage: NewLocale(application, locale[, isDefault[, silent]]): 'silent' must be specified for the first locale registered")
end
if not app then
if silent=="raw" then
app = {}
else
app = setmetatable({}, silent and readmetasilent or readmeta)
end
AceLocale.apps[application] = app
AceLocale.appnames[app] = application
end
if locale ~= gameLocale and not isDefault then
return -- nop, we don't need these translations
end
registering = app -- remember globally for writeproxy and writedefaultproxy
if isDefault then
return writedefaultproxy
end
return writeproxy
end
--- Returns localizations for the current locale (or default locale if translations are missing).
-- Errors if nothing is registered (spank developer, not just a missing translation)
-- @param application Unique name of addon / module
-- @param silent If true, the locale is optional, silently return nil if it's not found (defaults to false, optional)
-- @return The locale table for the current language.
function AceLocale:GetLocale(application, silent)
if not silent and not AceLocale.apps[application] then
error("Usage: GetLocale(application[, silent]): 'application' - No locales registered for '"..tostring(application).."'", 2)
end
return AceLocale.apps[application]
end
PK
Тyн>ЎЃъюu u ExtVendor/lib/LibStub.lua-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info
-- LibStub is hereby placed in the Public Domain Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
local LibStub = _G[LIBSTUB_MAJOR]
if not LibStub or LibStub.minor < LIBSTUB_MINOR then
LibStub = LibStub or {libs = {}, minors = {} }
_G[LIBSTUB_MAJOR] = LibStub
LibStub.minor = LIBSTUB_MINOR
function LibStub:NewLibrary(major, minor)
assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
local oldminor = self.minors[major]
if oldminor and oldminor >= minor then return nil end
self.minors[major], self.libs[major] = minor, self.libs[major] or {}
return self.libs[major], oldminor
end
function LibStub:GetLibrary(major, silent)
if not self.libs[major] and not silent then
error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
end
return self.libs[major], self.minors[major]
end
function LibStub:IterateLibraries() return pairs(self.libs) end
setmetatable(LibStub, { __call = LibStub.GetLibrary })
end
PK
N~ёL ExtVendor/locale/PK