Mercurial > wow > inventory
view Core.lua @ 220:c04257b42b03
bonusQueue should be 10% by default again.
summaryThresholdShow is now 10.000% by default.
author | Zerotorescue |
---|---|
date | Mon, 07 Feb 2011 00:03:06 +0100 |
parents | ca05b8ade1ea |
children | 2e4e52a589e5 |
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) addon.supportedAddons.crafting[name] = { ["Queue"] = queue, ["IsEnabled"] = enabled, ["OnSelect"] = onSelect, }; 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