Mercurial > wow > inventory
view Core.lua @ 225:2e4e52a589e5
Added onQueueStart and onQueueEnd events to crafting addon registering.
GnomeWorks queue frame should automatically be closed before adding items to the queue and opened afterwards to speed this process up.
author | Zerotorescue |
---|---|
date | Mon, 07 Feb 2011 15:06:41 +0100 |
parents | c04257b42b03 |
children |
line wrap: on
line source
-- You can access this addon's object through: LibStub("AceAddon-3.0"):GetAddon("Inventorium") local addon = select(2, ...); addon = LibStub("AceAddon-3.0"):NewAddon(addon, "Inventorium", "AceEvent-3.0"); local _G = _G; local sformat, ssplit, slower, strim, smatch = _G.string.format, _G.string.split, _G.string.lower, _G.string.trim, _G.string.match; local floor, print, pairs, tonumber = _G.floor, _G.print, _G.pairs, _G.tonumber; --@debug@ local addonRevision = 1; -- used to update the database whenever required --@end-debug@ --[===[@non-debug@ local addonRevision = @project-revision@; --@end-non-debug@]===] -- All modules must be able to retrieve our supported addons database, thus keep it a part of the addon object rather than local addon.supportedAddons = {}; addon.supportedAddons.auctionPricing = {}; addon.supportedAddons.itemCount = {}; addon.supportedAddons.crafting = {}; addon.Locations = { ["Bag"] = "Bag", ["Bank"] = "Bank", ["Guild"] = "Guild", ["Mailbox"] = "Mailbox", ["Merchant"] = "Merchant", }; function addon:OnInitialize() -- SAVED VARIABLES local defaults = { global = { version = nil, }, profile = { defaults = { -- General auctionPricingAddon = "Auctioneer", itemCountAddon = "DataStore (with guilds)", craftingAddon = "AdvancedTradeSkillWindow", trackAtCharacters = { }, dontAlertAtCharacters = { }, localItemData = { ["Bag"] = true, ["Auction House"] = true, }, -- Minimumm stock minLocalStock = 20, alertBelowLocalMinimum = true, autoRefill = true, autoRefillSkipConfirm = false, minGlobalStock = 40, alertBelowGlobalMinimum = true, -- Queueing restockTarget = 40, minCraftingQueue = 0.05, bonusQueue = 0.1, priceThreshold = 0, -- Summary summaryThresholdShow = 100, -- 10.000% summaryHidePriceThreshold = false, -- Global (can't be overridden) minimapIcon = true, hideHelp = false, scanInterval = "0.1", -- string because the associated select requires it to be summary = { speed = 20, width = 700, height = 600, }, colors = { red = 0, orange = 0.3, yellow = 0.6, green = 0.95, }, itemCountGuildsExcluded = { }, }, groups = { -- items = {}, -- isVirtual = nil, }, }, factionrealm = { characters = { }, }, }; -- Register our saved variables database self.db = LibStub("AceDB-3.0"):New("InventoriumDB", defaults, true); -- SLASH COMMANDS -- Disable the AddonLoader slash commands SLASH_INVENTORIUM1 = nil; SLASH_IM1 = nil; -- Register our own slash commands SLASH_INVENTORIUM1 = "/inventorium"; SLASH_INVENTORIUM2 = "/im"; SlashCmdList["INVENTORIUM"] = function(msg) addon:CommandHandler(msg); end; -- Debug command handling self:RegisterSlash(function(this) this.debugChannel = false; for i = 1, NUM_CHAT_WINDOWS do local name = GetChatWindowInfo(i); if string.upper(name) == "IMDEBUG" then addon:Print("A debug channel already exists, removing the old one... (" .. i .. ")"); FCF_Close(_G["ChatFrame" .. i]); end end if not this.debugChannel then -- Create a new debug channel local chatFrame = FCF_OpenNewWindow('IMDebug'); ChatFrame_RemoveAllMessageGroups(chatFrame); this.debugChannel = chatFrame; addon:Print("New debug channel created."); end end, { "d", "debug", "imdebug" }); -- Remember this character is on this account local playerName = UnitName("player"); if not self.db.factionrealm.characters[playerName] then self.db.factionrealm.characters[playerName] = true; -- Default to tracking on all chars, untracking is a convenience, not tracking by default would probably get multiple issue reports. self.db.profile.defaults.trackAtCharacters[playerName] = true; end self:UpdateDatabase(); end -- Database patching after new revisions function addon:UpdateDatabase() if not self.db.global.version or self.db.global.version < addonRevision then -- Is our database outdated? Then patch it. --[[if self.db.global.version < 1337 then end]] -- Remember the version of our database self.db.global.version = addonRevision; end end function addon:GetOptionByKey(groupName, optionName, noDefault) if groupName and addon.db.profile.groups[groupName] and addon.db.profile.groups[groupName][optionName] ~= nil then -- If this option exists within the settings of this group return addon.db.profile.groups[groupName][optionName]; elseif groupName and addon.db.profile.groups[groupName] and addon.db.profile.groups[groupName].virtualGroup ~= "" and not noDefault then -- If a virtual group was selected return self:GetOptionByKey(addon.db.profile.groups[groupName].virtualGroup, optionName, noDefault); elseif addon.db.profile.defaults[optionName] and not noDefault then return addon.db.profile.defaults[optionName]; else return nil; end end local autoSelectedItemCountAddon; function addon:GetItemCountAddon(group) local selectedExternalAddon = self:GetOptionByKey(group, "itemCountAddon"); if self.supportedAddons.itemCount[selectedExternalAddon] and self.supportedAddons.itemCount[selectedExternalAddon].IsEnabled() then -- Try to use the default item count addon if self.supportedAddons.itemCount[selectedExternalAddon].SetGuildState then self.supportedAddons.itemCount[selectedExternalAddon].SetGuildState(self.db.profile.defaults.itemCountGuildsExcluded); end return self.supportedAddons.itemCount[selectedExternalAddon], selectedExternalAddon; elseif self.supportedAddons.itemCount[autoSelectedItemCountAddon] and self.supportedAddons.itemCount[autoSelectedItemCountAddon].IsEnabled() then -- Use previously automatically selected addon if self.supportedAddons.itemCount[autoSelectedItemCountAddon].SetGuildState then self.supportedAddons.itemCount[autoSelectedItemCountAddon].SetGuildState(self.db.profile.defaults.itemCountGuildsExcluded); end return self.supportedAddons.itemCount[autoSelectedItemCountAddon], autoSelectedItemCountAddon; else -- Default not available, get the first one then -- We are finding the best match, quality is used to compare everything local altName, altValue, altQuality; for name, value in pairs(self.supportedAddons.itemCount) do if value.IsEnabled() then -- Quality is based on functionality supported; TotalCount, LocalCount & GuildSelect = 3; TotalCount & LocalCount = 2, TotalCount = 1 local quality = ((value.GetTotalCount and value.GetCharacterCount and value.SetGuildState and 3) or (value.GetTotalCount and value.GetCharacterCount and 2) or (value.GetTotalCount and 1) or 0); if quality == 3 then -- Best quality means instant return -- Remember this was auto selected so we don't loop again autoSelectedItemCountAddon = name; return value, name; elseif not altQuality or quality > altQuality then -- Compare quality; improvement? = overwrite altName = name; altValue = value; altQuality = quality; end end end if altName and altValue and altQuality then -- Remember this was auto selected so we don't loop again autoSelectedItemCountAddon = altName; return altValue, altName; end end return; end function addon:GetItemCount(itemId, group) itemId = tonumber(itemId); if not itemId then return; end local itemCountAddon = self:GetItemCountAddon(group); return (itemCountAddon and itemCountAddon.GetTotalCount and itemCountAddon.GetTotalCount(itemId)) or -1; end function addon:GetLocalItemCount(itemId, group) itemId = tonumber(itemId); if not itemId then return; end local itemCountAddon = self:GetItemCountAddon(group); local currentItemCount; if itemCountAddon and itemCountAddon.GetCharacterCount then local bag, bank, auctionHouse, mail = itemCountAddon.GetCharacterCount(itemId); local selectedLocalItemCountSources = self:GetOptionByKey(group, "localItemData"); currentItemCount = 0; if selectedLocalItemCountSources["Bag"] then currentItemCount = currentItemCount + bag; end if selectedLocalItemCountSources["Bank"] then currentItemCount = currentItemCount + bank; end if selectedLocalItemCountSources["Auction House"] then currentItemCount = currentItemCount + auctionHouse; end if selectedLocalItemCountSources["Mailbox"] then currentItemCount = currentItemCount + mail; end end return currentItemCount or -1; end function addon:GetAuctionValue(itemLink, group) if not itemLink then return -5; end local selectedExternalAddon = self:GetOptionByKey(group, "auctionPricingAddon"); if self.supportedAddons.auctionPricing[selectedExternalAddon] and self.supportedAddons.auctionPricing[selectedExternalAddon].IsEnabled() then -- Try to use the default auction pricing addon return self.supportedAddons.auctionPricing[selectedExternalAddon].GetValue(itemLink); else -- Default not available, get the first one then for name, value in pairs(self.supportedAddons.auctionPricing) do if value.IsEnabled() then return value.GetValue(itemLink); end end end return -2; end -- Slash commands local slashArgs = {}; local slashError = "Wrong argument, the following arguments are available:"; function addon:CommandHandler(message) local cmd, arg = ssplit(" ", (message or ""), 2); cmd = slower(cmd); if slashArgs[cmd] then -- Pass a reference to the addon (to be used as "self") and the provided arg slashArgs[cmd](addon, arg); else addon:Print(slashError); end end function addon:RegisterSlash(func, args, description) for _, arg in pairs(args) do slashArgs[arg] = func; end if description then slashError = slashError .. "\n" .. description; end end function addon:ColorCode(num, required) local percentage = ( num / required ); if percentage >= addon.db.profile.defaults.colors.green then return sformat("|cff00ff00%d|r", num); elseif percentage >= addon.db.profile.defaults.colors.yellow then return sformat("|cffffff00%d|r", num); elseif percentage >= addon.db.profile.defaults.colors.orange then return sformat("|cffff9933%d|r", num); elseif percentage >= addon.db.profile.defaults.colors.red then return sformat("|cffff0000%d|r", num); else return num; end end function addon:DisplayItemCount(value, minimumStock) if value == -1 then return "|cffffff00Unknown|r"; elseif value == -2 then return "|cffffff00-|r"; elseif value == -3 then return "|cffffff00Unknown|r"; else return sformat("%s / %d", self:ColorCode(value, minimumStock), minimumStock); end end -- Readable money local goldText = "%s%d|cffffd700g|r "; local silverText = "%s%d|cffc7c7cfs|r "; local copperText = "%s%d|cffeda55fc|r"; function addon:ReadableMoney(copper, clean) local text = ""; local gold = floor( copper / COPPER_PER_GOLD ); if gold > 0 then text = sformat(goldText, text, gold); end if not clean or (not gold or gold < 10) then local silver = floor( ( copper % COPPER_PER_GOLD ) / COPPER_PER_SILVER ); if silver > 0 then text = sformat(silverText, text, silver); end if not clean or (not gold or gold < 1) then local copper = floor( copper % COPPER_PER_SILVER ); if copper > 0 or text == "" then text = sformat(copperText, text, copper); end end end return strim(text); end function addon:ReadableMoneyToCopper(value) -- If a player enters a value it will be filled without color codes -- If it is retrieved from the database, it will be colored coded -- Thus we look for both local gold = tonumber(smatch(value, "(%d+)|c[a-fA-F0-9]+g|r") or smatch(value, "(%d+)g")); local silver = tonumber(smatch(value, "(%d+)|c[a-fA-F0-9]+s|r") or smatch(value, "(%d+)s")); local copper = tonumber(smatch(value, "(%d+)|c[a-fA-F0-9]+c|r") or smatch(value, "(%d+)c")); return ( (gold or 0) * COPPER_PER_GOLD ) + ( (silver or 0) * COPPER_PER_SILVER ) + (copper or 0); end function addon:ValidateReadableMoney(info, value) -- If a player enters a value it will be filled without color codes -- If it is retrieved from the database, it will be colored coded -- Thus we look for both local gold = tonumber(smatch(value, "(%d+)|c[a-fA-F0-9]+g|r") or smatch(value, "(%d+)g")); local silver = tonumber(smatch(value, "(%d+)|c[a-fA-F0-9]+s|r") or smatch(value, "(%d+)s")); local copper = tonumber(smatch(value, "(%d+)|c[a-fA-F0-9]+c|r") or smatch(value, "(%d+)c")); if not gold and not silver and not copper then return "The provided amount of money is invalid. Please provide the amount of money as #g#s#c, e.g. 591617g24s43c."; else return true; end end -- Public function IMRegisterPricingAddon(name, get, enabled, onSelect) addon.supportedAddons.auctionPricing[name] = { ["GetValue"] = get, ["IsEnabled"] = enabled, ["OnSelect"] = onSelect, }; end function IMRegisterItemCountAddon(name, getTotal, getCharacter, enabled, onSelect, getGuildNames, setGuildState) addon.supportedAddons.itemCount[name] = { ["GetTotalCount"] = getTotal, ["GetCharacterCount"] = getCharacter, ["IsEnabled"] = enabled, ["OnSelect"] = onSelect, ["GetGuildNames"] = getGuildNames, ["SetGuildState"] = setGuildState, }; end function IMRegisterCraftingAddon(name, queue, enabled, onSelect, onQueueStart, onQueueEnd) addon.supportedAddons.crafting[name] = { ["Queue"] = queue, ["IsEnabled"] = enabled, ["OnSelect"] = onSelect, ["OnQueueStart"] = onQueueStart, ["OnQueueEnd"] = onQueueEnd, }; end -- We need a global command handler for our chat-links function InventoriumCommandHandler(msg) addon:CommandHandler(msg); end -- General addon.Colors = { ["Red"] = { 1, 0, 0 }, ["Orange"] = { 1, .46, .1 }, ["Green"] = { 0, 1, 0 }, ["Blue"] = { 0, 0, 1 }, ["Yellow"] = { 1, 1, 0 }, ["Cyan"] = { 0, 1, 1 }, }; -- easy to extend if more colors are needed function addon:Print(text, color) local red, green, blue; if color then red, green, blue = color[1], color[2], color[3]; end DEFAULT_CHAT_FRAME:AddMessage(text or "", red, green, blue, nil, 5); end function addon:GetItemId(itemLink) itemLink = itemLink and itemLink:match("|Hitem:([-0-9]+):"); -- if itemLink is nil, it won't execute the second part itemLink = itemLink and tonumber(itemLink); return itemLink; end -- Debug local function ReadableTable(t, includeKeys, jumps) local tabs = ""; for i = 1, (jumps or 0) do tabs = tabs .. " "; end local temp = "{\n"; for i, v in pairs(t) do if type(v) == "table" then if includeKeys then local key = (type(i) == "number" and tostring(i)) or sformat("\"%s\"", tostring(i)); temp = sformat("%s%s [%s] => %s,\n", temp, tabs, key, ReadableTable(v, includeKeys, (jumps or 0) + 1)); else temp = sformat("%s%s %s,\n", temp, tabs, ReadableTable(v, includeKeys, (jumps or 0) + 1)); end else if includeKeys then local key = (type(i) == "number" and tostring(i)) or sformat("\"%s\"", tostring(i)); local value = (type(v) == "number" and tostring(v)) or sformat("\"%s\"", tostring(v)); temp = sformat("%s%s [%s] => %s,\n", temp, tabs, key, value); else local value = (type(v) == "number" and tostring(v)) or sformat("\"%s\"", tostring(v)); temp = sformat("%s%s %s,\n", temp, tabs, value); end end end temp = temp .. tabs .. "}"; return temp; end function addon:Debug(t, ...) if not self.debugChannel and self.debugChannel ~= false then -- We want to check just once, so if you add a debug channel later just do a /reload (registering an event for this is wasted resources) self.debugChannel = false; for i = 1, NUM_CHAT_WINDOWS do local name = GetChatWindowInfo(i); if name:upper() == "IMDEBUG" then self.debugChannel = _G["ChatFrame" .. i]; end end end if self.debugChannel then if type(t) == "table" then t = ReadableTable(t, true); end self.debugChannel:AddMessage("|cffffff00Inventorium|r:" .. sformat(t, ...)); end end