-- $Revision$ -- Cauldron main file Cauldron = LibStub("AceAddon-3.0"):NewAddon("Cauldron", "AceEvent-3.0", "AceTimer-3.0", "AceConsole-3.0", "AceHook-3.0", "LibLogger-1.0"); local L = LibStub("AceLocale-3.0"):GetLocale("Cauldron"); Cauldron.version = "@project-revision@"; Cauldron.date = string.sub("$Date$", 8, 17); -- key binding names BINDING_HEADER_CAULDRON = "Cauldron"; BINDING_NAME_TOGGLE_CAULDRONSHOPPINGLIST = "Toggle Shopping List Window"; BINDING_NAME_CAULDRONRESET = "Reset Cauldron"; Cauldron.options = {}; Cauldron.options.buttons = {}; Cauldron.vars = { enabled = true, inventory = {}; }; Cauldron.libs = {}; -- Cauldron.libs.Abacus = LibStub("LibAbacus-3.0"); -- Cauldron.libs.PT = LibStub("LibPeriodicTable-3.1"); Cauldron.libs.GUI = LibStub("AceGUI-3.0"); -- logging Cauldron:SetLogLevel(Cauldron.logLevels.INFO); -- Cauldron:SetLogLevel(Cauldron.logLevels.DEBUG); CURRENT_TRADESKILL = ""; function Cauldron:OnInitialize() local dbDefaults = { profile = { }, realm = { userdata = {}, -- Stores all known characters }, global = { difficulty = {}, -- Stores at what level difficulty is changed for all recipes. } } self.db = LibStub("AceDB-3.0"):New("CauldronDB", dbDefaults) -- set up slash command options local options = { desc = L["Cauldron"], handler = Cauldron, type = 'group', args = { shoppinglist = { name = L["Shopping list"], desc = L["Open shopping list window"], type = 'execute', func = function() Cauldron:ShowShoppingList() end, }, enable = { name = L["Enable Cauldron"], desc = L["Use Cauldron as your tradeskill interface"], type = 'execute', func = function() Cauldron:Enable() end, }, disable = { name = L["Disable Cauldron"], desc = L["Use the standard Blizzard window as your tradeskill interface"], type = 'execute', func = function() Cauldron:Disable() end, }, version = { name = L["Version"], desc = L["Shows the version number of the addon"], type = 'execute', func = function() self:DisplayVersion() end, }, --@alpha@ logging = { name = L["Logging"], desc = L["Sets or displays the logging level"], type = 'select', values = { normal = L["Normal logging of warnings and errors"], debug = L["Debug logging (very verbose)"], }, get = function() Cauldron:Print(Cauldron:GetLogLevel()); end, set = function(l) if l == "debug" then Cauldron:SetLogLevel(Cauldron.logLevels.DEBUG); else Cauldron:SetLogLevel(Cauldron.logLevels.INFO); end end, }, --@end-alpha@ reset = { name = L["Reset"], desc = L["Resets Cauldron to a fresh state"], type = 'execute', func = function() self:Reset() end, }, -- debug = LibStub('LibLogDebug-1.0'):GetAce3OptionTable(self, 110), }, } -- register slash command with options LibStub("AceConfig-3.0"):RegisterOptionsTable("Cauldron", options, {"cauldron"}); --[[ initialize PT for i=1,GetNumAddOns() do local metadata = GetAddOnMetadata(i, "X-PeriodicTable-3.0-Module"); if metadata then local name, _, _, enabled = GetAddOnInfo(i); if enabled then LoadAddOn(name); end end end collectgarbage(); --]] --@alpha@ -- register test suite if WoWUnit then WoWUnit:AddTestSuite("CauldronTestSuite", CauldronTestSuite); end --@end-alpha@ -- let the user know the addon is loaded self:Print(L["Cauldron loaded; version "],Cauldron.version); end function Cauldron:InitPlayer() --@alpha@ self:debug("InitPlayer enter"); --@end-alpha@ if not self.vars.playername then self.vars.playername = UnitName("player"); if not self.db.realm.userdata[self.vars.playername] then self.db.realm.userdata[self.vars.playername] = {}; end -- if not self.db.realm.userdata[self.vars.playername].knownRecipes then -- self.db.realm.userdata[self.vars.playername].knownRecipes = {}; -- end if not self.db.realm.userdata[self.vars.playername].skills then self.db.realm.userdata[self.vars.playername].skills = {}; end if not self.db.realm.userdata[self.vars.playername].queue then self.db.realm.userdata[self.vars.playername].queue = CauldronQueue:NewQueue(); end if not self.db.realm.userdata[self.vars.playername].options then self.db.realm.userdata[self.vars.playername].options = { autoBuy = false, compactView = false, }; end if not self.db.realm.shopping then self.db.realm.shopping = CauldronShopping:NewList(); end end --@alpha@ self:debug("InitPlayer exit"); --@end-alpha@ end function Cauldron:OnEnable() --@alpha@ self:debug("OnEnable enter"); --@end-alpha@ -- set init flag, for some callbacks self.initializing = true; self:InitPlayer(); -- scan bags self:ScanBags(); -- register for events we're interested in self:RegisterEvent("TRADE_SKILL_SHOW", "OnTradeShow"); self:RegisterEvent("TRADE_SKILL_UPDATE", "OnSkillUpdate"); self:RegisterEvent("TRADE_SKILL_CLOSE", "OnTradeClose"); self:RegisterEvent("SKILL_LINES_CHANGED", "OnSkillUpdate"); self:RegisterEvent("ADDON_LOADED", "OnAddonLoaded"); self:RegisterEvent("UNIT_PORTRAIT_UPDATE", "OnEvent"); self:RegisterEvent("UPDATE_TRADESKILL_RECAST", "OnTradeSkillRecast"); self:RegisterEvent("BANKFRAME_OPENED", "OnBankOpened"); -- self:RegisterEvent("BANKFRAME_CLOSED"); -- self:RegisterEvent("PLAYERBANKSLOTS_CHANGED"); -- self:RegisterEvent("PLAYERBANKBAGSLOTS_CHANGED"); self:RegisterEvent("MERCHANT_SHOW", "OnMerchantShow"); -- self:RegisterEvent("MERCHANT_UPDATE"); -- self:RegisterEvent("MERCHANT_CLOSED"); self:RegisterEvent("BAG_UPDATE", "OnBagUpdate"); -- self:RegisterEvent("TRAINER_CLOSED"); -- self:RegisterEvent("PLAYER_REGEN_DISABLED"); -- self:RegisterEvent("PLAYER_REGEN_ENABLED"); -- self:RegisterEvent("AUCTION_HOUSE_CLOSED"); -- self:RegisterEvent("AUCTION_HOUSE_SHOW"); self:RegisterEvent("CRAFT_SHOW", "OnCraftShow"); self:RegisterEvent("CRAFT_CLOSE", "OnCraftClose"); -- self:RegisterEvent("PLAYER_LOGOUT"); self:RegisterEvent("UI_ERROR_MESSAGE", "OnError"); -- setup hooks for tooltips self:HookTooltips(); -- clear init flag self.initializing = false; --@alpha@ self:debug("OnEnable exit"); --@end-alpha@ end function Cauldron:OnDisable() --@alpha@ self:debug("OnDisable enter"); --@end-alpha@ --@alpha@ self:debug("OnDisable exit"); --@end-alpha@ end function Cauldron:OnAddonLoaded(event, addon) --@alpha@ self:debug("OnAddonLoaded enter"); --@end-alpha@ -- show the shopping list? if self.db.profile.showShoppingList then Cauldron:ShowShoppingList(); else if CauldronShopping:ContainsItems(self.db.realm.shopping) then Cauldron:ShowShoppingList(); end end --@alpha@ self:debug("OnAddonLoaded exit"); --@end-alpha@ end function Cauldron:OnEvent(event, ...) --@alpha@ self:debug("OnEvent enter"); --@end-alpha@ if ( event == "UNIT_PORTRAIT_UPDATE" ) then local arg1 = ...; if ( arg1 == "player" ) then SetPortraitTexture(CauldronFramePortrait, "player"); end end --@alpha@ self:debug("OnEvent exit"); --@end-alpha@ end function Cauldron:OnTradeShow() self:debug("OnTradeShow enter"); -- update our known skills self:debug("OnTradeShow: update known skills"); -- self:ScheduleTimer(self.UpdateSkills,1,self); if not Cauldron.updatingSkills then self.updatingSkills = true; self:UpdateSkills(); self.updatingSkills = false; end -- show the UI frame self:debug("OnTradeShow: show the UI"); self:Frame_Show(); self:debug("OnTradeShow exit"); end function Cauldron:OnTradeUpdate() self:debug("OnTradeUpdate enter"); -- TODO self:debug("OnTradeUpdate exit"); end function Cauldron:OnTradeClose() --@alpha@ self:debug("OnTradeClose enter"); --@end-alpha@ self:Frame_Hide(); --@alpha@ self:debug("OnTradeClose exit"); --@end-alpha@ end function Cauldron:OnSkillUpdate() --@alpha@ self:debug("OnSkillUpdate enter"); --@end-alpha@ -- self:UpdateSkills(); -- self:UpdateSpecializations(); -- if not IsTradeSkillLinked() then -- if (GetTradeSkillLine() ~= "UNKNOWN") then -- self:ScheduleTimer(self.UpdateKnownRecipes, 1, self); -- end -- end if CURRENT_TRADESKILL ~= "" then if not Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[CURRENT_TRADESKILL] then return; end -- TODO check if the skill rank has changed, and unselect -- Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[CURRENT_TRADESKILL].window.selected = 0; if not Cauldron.updatingSkills then Cauldron.updatingSkills = true; Cauldron:UpdateSkills(); Cauldron.updatingSkills = false; end CauldronQueue:CalculateAllRequiredItems(Cauldron.db.realm.userdata[Cauldron.vars.playername].queue); end self:Frame_Update(); --@alpha@ self:debug("OnSkillUpdate exit"); --@end-alpha@ end function Cauldron:OnTradeSkillRecast() --@alpha@ self:debug("OnTradeSkillRecast enter"); --@end-alpha@ -- keep the processing flag set self.processing = true; self:UpdateSkills(); CauldronAmountInputBox:SetNumber(GetTradeskillRepeatCount()); self:Frame_Update(); --@alpha@ self:debug("OnTradeSkillRecast exit"); --@end-alpha@ end function Cauldron:OnBagUpdate(event, bagid) --@alpha@ self:debug("OnBagUpdate enter"); --@end-alpha@ -- make sure we're not reacting to initial bag update events when the DB isn't initialized yet if (self.initializing) or (not self.db) or (not self.vars) then return; end local queue = self.db.realm.userdata[self.vars.playername].queue; -- check if the item acquired is in the intermediate list or shopping list local items = Cauldron:GetItemDeltas(bagid); self:debug("items="..tostring(items)); local recalc = false; for item, itemCount in pairs(items) do --@alpha@ self:debug("OnBagUpdate: item="..tostring(item).."; itemCount="..tostring(itemCount)); --@end-alpha@ if itemCount > 0 then -- adjust shopping list --@alpha@ self:debug("OnBagUpdate: adjust shopping list"); --@end-alpha@ CauldronShopping:RemoveFromList(self.db.realm.shopping, self.vars.playername, item, itemCount); -- adjust intermediate list self:debug("OnBagUpdate: adjust intermediate list"); local intItem = CauldronQueue:GetIntermediateItem(queue, item); if intItem then -- the item is found in the intermediate list, so recalculate the queue self:debug("OnBagUpdate: set recalc flag"); recalc = true; end -- adjust queue, but only if window is open self:debug("adjust queue? item="..item); if CauldronFrame:IsShown() then self:debug("window is open; self.makingItem="..tostring(self.makingItem)); if self.makingItem == item then self:debug("OnBagUpdate: adjust queue for item: "..self.makingItem.."; itemCount="..itemCount); CauldronQueue:AdjustItemCount(queue, item, -itemCount); end end end end if recalc then self:debug("OnBagUpdate: recalculating queue"); CauldronQueue:CalculateAllRequiredItems(queue); Cauldron:UpdateQueue(); end -- check if we were making something, and then update the queue --[[ if self.makingItem then --@alpha@ self:debug("OnBagUpdate: self.makingItem="..self.makingItem); --@end-alpha@ local count = GetItemCount(self.makingItem); --@alpha@ self:debug("OnBagUpdate: count="..count); self:debug("OnBagUpdate: self.itemCurrentCount="..self.itemCurrentCount); --@end-alpha@ if count ~= self.itemCurrentCount then local delta = self.itemCurrentCount - count; -- TODO: is this necessary? --@alpha@ self:debug("OnBagUpdate: delta="..delta); --@end-alpha@ CauldronQueue:AdjustItemCount(Cauldron:GetQueue(), self.queueInfo.name, -1); self.itemCurrentCount = count; end else -- end --]] -- Cauldron:UpdateSkills(); self:Frame_Update(); Cauldron:UpdateShoppingList(); -- update the bags Cauldron:ScanBags(); --@alpha@ self:debug("OnBagUpdate exit"); --@end-alpha@ end function Cauldron:OnCraftShow() --@alpha@ self:debug("OnCraftShow enter"); --@end-alpha@ -- TODO --@alpha@ self:debug("OnCraftShow exit"); --@end-alpha@ end function Cauldron:OnCraftClose() --@alpha@ self:debug("OnCraftClose enter"); --@end-alpha@ -- TODO --@alpha@ self:debug("OnCraftClose exit"); --@end-alpha@ end function Cauldron:OnMerchantShow() --@alpha@ self:debug("OnMerchantShow enter"); --@end-alpha@ Cauldron:ShowShoppingList(); if Cauldron.db.realm.userdata[Cauldron.vars.playername].options.autoBuy then CauldronShopping:AutoBuyShoppingItems(Cauldron.db.realm.shopping, Cauldron.vars.playername); end --@alpha@ self:debug("OnMerchantShow exit"); --@end-alpha@ end function Cauldron:OnBankOpened() --@alpha@ self:debug("OnBankOpened enter"); --@end-alpha@ Cauldron:ShowShoppingList(); --@alpha@ self:debug("OnBankOpened exit"); --@end-alpha@ end function Cauldron:OnError() --@alpha@ self:debug("OnError enter"); --@end-alpha@ -- TODO --@alpha@ self:debug("OnError exit"); --@end-alpha@ end function Cauldron:TradeSkillFrame_SetSelection(id) --@alpha@ self:debug("TradeSkillFrame_SetSelection enter"); --@end-alpha@ -- TODO --@alpha@ self:debug("TradeSkillFrame_SetSelection exit"); --@end-alpha@ end function Cauldron:GetSelectedSkill() --@alpha@ self:debug("GetSelectedSkill enter"); --@end-alpha@ local skillName = CURRENT_TRADESKILL; if IsTradeSkillLinked() then skillName = "Linked-"..skillName; end if (not self.db.realm.userdata[self.vars.playername]) or (not self.db.realm.userdata[self.vars.playername].skills[skillName]) then return; end local selected = self.db.realm.userdata[self.vars.playername].skills[skillName].window.selected; for name, info in pairs(self.db.realm.userdata[self.vars.playername].skills[skillName].recipes) do if selected == info.index then return info; end end --@alpha@ self:debug("GetSelectedSkill exit"); --@end-alpha@ return nil; end function Cauldron:QueueAllTradeSkillItem() --@alpha@ self:debug("QueueAllTradeSkillItem enter"); --@end-alpha@ local skillInfo = Cauldron:GetSelectedSkill(); if skillInfo then local amount = skillInfo.available; local potential = Cauldron:GetPotentialCraftCount(skillInfo); local queueAmount = 0; -- if regular amount > 0 ... if amount > 0 then if (potential > 0) and IsShiftKeyDown() then queueAmount = potential; else queueAmount = amount; end else queueAmount = potential; end if queueAmount > 0 then CauldronQueue:AddItem(self.db.realm.userdata[self.vars.playername].queue, skillInfo, queueAmount); Cauldron:UpdateQueue(); -- update the shopping list Cauldron:UpdateShoppingListFromQueue(); else -- self:info("No amount to queue for "..skillInfo.name.."."); end end --@alpha@ self:debug("QueueAllTradeSkillItem exit"); --@end-alpha@ end function Cauldron:QueueTradeSkillItem() --@alpha@ self:debug("QueueTradeSkillItem enter"); --@end-alpha@ local skillInfo = Cauldron:GetSelectedSkill(); if skillInfo then local amount = CauldronAmountInputBox:GetNumber(); if not amount or amount < 1 then amount = 1; end CauldronQueue:AddItem(self.db.realm.userdata[self.vars.playername].queue, skillInfo, amount); Cauldron:UpdateQueue(); -- update the shopping list Cauldron:UpdateShoppingListFromQueue(); end --@alpha@ self:debug("QueueTradeSkillItem exit"); --@end-alpha@ end function Cauldron:CreateAllTradeSkillItem() --@alpha@ self:debug("CreateAllTradeSkillItem enter"); --@end-alpha@ if ( (not PartialPlayTime()) and (not NoPlayTime()) ) then CauldronAmountInputBox:ClearFocus(); local skillInfo = Cauldron:GetSelectedSkill(); CauldronAmountInputBox:SetNumber(skillInfo.available); DoTradeSkill(skillInfo.index, skillInfo.available); end --@alpha@ self:debug("CreateAllTradeSkillItem exit"); --@end-alpha@ end function Cauldron:CreateTradeSkillItem() --@alpha@ self:debug("CreateTradeSkillItem enter"); --@end-alpha@ if ( (not PartialPlayTime()) and (not NoPlayTime()) ) then CauldronAmountInputBox:ClearFocus(); local skillInfo = Cauldron:GetSelectedSkill(); local amount = CauldronAmountInputBox:GetNumber(); DoTradeSkill(skillInfo.index, amount); end --@alpha@ self:debug("CreateTradeSkillItem exit"); --@end-alpha@ end function Cauldron:ProcessQueue() self:debug("ProcessQueue enter"); if IsTradeSkillLinked() then self:error("Can't process queue for linked tradeskill!"); return; end --[[ TODO: update queue logic -- look at first item, if it can be made, make it (lower of queued quantity vs. quantity able to make) -- if items other than first can be made and first can't, ask user if they want to make that instead --]] local queue = CauldronQueue:GetItems(self.db.realm.userdata[self.vars.playername].queue); self:debug("ProcessQueue: queue="..#queue); local queueInfo = nil; local skillInfo = nil; if #queue > 0 then self:debug("ProcessQueue: checking first main queue item to see if it can be made now"); -- see if first item can be made queueInfo = queue[1]; self:debug("ProcessQueue: queueInfo="..queueInfo.name); skillInfo = Cauldron:GetSkillInfo(queueInfo.tradeskill, queueInfo.name); self:debug("ProcessQueue: skillInfo="..tostring(skillInfo)); if skillInfo.available > 0 then self:debug("First item in main queue can be made "..skillInfo.available.." times"); self:SubmitItemToProcess(queueInfo, skillInfo, math.min(skillInfo.available, queueInfo.amount)); return; --[[ else -- see if queue contains other items that can be made if the first can't be if #queue > 1 then for i=2,#queue do queueInfo = queue[i]; skillInfo = Cauldron:GetSkillInfo(queueInfo.tradeskill, queueInfo.name); self:debug("ProcessQueue: skillInfo="..tostring(skillInfo)); if skillInfo.available > 0 then -- present dialog to user to move item to top of queue Cauldron:ConfirmDialog(L["Confirm"], L["message"], L["Okay"], function() Cauldron:info("Okay"); -- TODO end, L["Cancel"], function() Cauldron:info("Cancel"); -- TODO end); return; end end end --]] end end -- find intermediate items that need to be crafted local intQueue = CauldronQueue:GetIntermediates(self.db.realm.userdata[self.vars.playername].queue); self:debug("ProcessQueue: intQueue="..#intQueue); if #intQueue > 0 then self:debug("ProcessQueue: processing intermediate queue items"); queueInfo = intQueue[1]; self:debug("ProcessQueue: queueInfo="..queueInfo.name); skillInfo = Cauldron:GetSkillInfo(queueInfo.tradeskill, queueInfo.name); self:debug("ProcessQueue: skillInfo="..tostring(skillInfo)); else if #queue > 0 then self:debug("ProcessQueue: processing main queue items"); queueInfo = queue[1]; self:debug("ProcessQueue: queueInfo="..queueInfo.name); skillInfo = Cauldron:GetSkillInfo(queueInfo.tradeskill, queueInfo.name); self:debug("ProcessQueue: skillInfo="..tostring(skillInfo)); end end self:SubmitItemToProcess(queueInfo, skillInfo); self:debug("ProcessQueue exit"); end function Cauldron:SubmitItemToProcess(queueInfo, skillInfo, amount) self:debug("SubmitItemToProcess enter"); if queueInfo and skillInfo then self:debug("ProcessQueue: queueInfo="..queueInfo.name); if queueInfo.tradeskill ~= CURRENT_TRADESKILL then local msg = string.format(L["Crafting %1$s requires the %2$s skill."], queueInfo.name, queueInfo.tradeskill); UIErrorsFrame:AddMessage(msg, 1.0, 0.0, 0.0); return; end self:debug("ProcessQueue: process item: "..queueInfo.name); Cauldron:ProcessItem(skillInfo, queueInfo, amount or queueInfo.amount); else if not queueInfo then self:error("Missing queue info!"); end if not skillInfo then self:error("Missing skill info!"); end end self:debug("SubmitItemToProcess exit"); end function Cauldron:ProcessItem(skillInfo, queueInfo, amount) self:debug("ProcessItem enter"); if (not skillInfo) or (amount < 1) then self:error("ProcessItem: Missing skill info!"); return; end if ((not PartialPlayTime()) and (not NoPlayTime())) then -- record the item we're making self.makingItem, _ = GetItemInfo(skillInfo.itemLink); self:debug("ProcessItem: self.makingItem="..self.makingItem); self.itemCurrentCount = GetItemCount(skillInfo.itemLink); self:debug("ProcessItem: self.itemCurrentCount="..self.itemCurrentCount); self.queueInfo = queueInfo; -- tell the user what we're doing self:Print(string.format(L["Crafting %1$d of %2$s..."], amount, self.makingItem)); -- do it DoTradeSkill(skillInfo.index, amount); else -- TODO: notify player? end self:debug("ProcessItem exit"); end function Cauldron:RemoveQueueItem(name) CauldronQueue:RemoveItem(Cauldron:GetQueue(), name); end function Cauldron:IncreaseItemPriority(name, top) CauldronQueue:IncreasePriority(Cauldron:GetQueue(), name, top); end function Cauldron:DecreaseItemPriority(name, bottom) CauldronQueue:DecreasePriority(Cauldron:GetQueue(), name, bottom); end function Cauldron:DecreaseItemCount(name) CauldronQueue:AdjustItemCount(Cauldron:GetQueue(), name, -1); end function Cauldron:GetQueue(player) --@alpha@ self:debug("GetQueue enter"); --@end-alpha@ if not player then player = self.vars.playername; end local queue = self.db.realm.userdata[player].queue; if not queue then queue = CauldronQueue:NewQueue(); self.db.realm.userdata[player].queue = queue; end --@alpha@ self:debug("GetQueue enter"); --@end-alpha@ return queue; end function Cauldron:AddItemToShoppingList(itemName, amount, replace) if replace then CauldronShopping:RemoveFromList(self.db.realm.shopping, self.vars.playername, itemName); end CauldronShopping:AddToList(self.db.realm.shopping, self.vars.playername, itemName, amount); Cauldron:ShowShoppingList(); end function Cauldron:RemoveShoppingListItem(requestor, itemName) CauldronShopping:RemoveFromList(self.db.realm.shopping, requestor, itemName, nil); -- if not CauldronShopping:ContainsItems(self.db.realm.shopping) then -- Cauldron:HideShoppingList(); -- end end function Cauldron:UpdateShoppingListFromQueue() local items = CauldronQueue:GetReagents(self.db.realm.userdata[self.vars.playername].queue); if items then for i,item in ipairs(items) do local id = Cauldron:GetIdFromLink(item.link); local have = GetItemCount(item.link); local need = math.max(0, item.amount - have); if (need > 0) and Cauldron:IsVendorItem(id) then Cauldron:AddItemToShoppingList(item.name, need, true); end end end end function Cauldron:LocaleString(str) return L[str]; end function Cauldron:DisplayVersion() self:Print(L["Version "],Cauldron.version); self:Print(L["Date: "],Cauldron.date); end ---------------------------------------------------------------- -- Tooltip Functions ---------------------------------------------------------------- function Cauldron:HookTooltips() --@alpha@ self:debug("HookTooltips enter"); --@end-alpha@ -- self:SecureHook(GameTooltip, "SetBagItem"); -- self:SecureHook(GameTooltip, "SetInventoryItem"); -- self:SecureHook(GameTooltip, "SetLootItem"); self:SecureHook(GameTooltip, "SetHyperlink"); self:SecureHook(GameTooltip, "SetTradeSkillItem"); -- self:SecureHook(GameTooltip, "SetMerchantItem"); -- self:SecureHook(GameTooltip, "SetAuctionItem"); -- self:SecureHook(GameTooltip, "SetTrainerService"); -- self:SecureHook(GameTooltip, "SetGuildBankItem"); -- self:SecureHook("SetItemRef"); --@alpha@ self:debug("HookTooltips exit"); --@end-alpha@ end function Cauldron:SetTradeSkillItem(tooltip, itemIndex, reagentIndex) local link; local name; if reagentIndex then local skillInfo = Cauldron:GetSkillInfoByIndex(itemIndex); local reagentInfo = Cauldron:GetReagentInfoByIndex(itemIndex, reagentIndex); if reagentInfo then -- let the user know if the reagent is a "non-key" reagent if not reagentInfo.key then tooltip:AddLine("|cff666666"..L["Available at vendor"].."|r"); end end else -- link = GetTradeSkillItemLink(itemIndex); -- name = Cauldron:GetIdFromLink(link); end tooltip:Show(); end function Cauldron:SetHyperlink(tooltip, link) -- local name = Cauldron:GetNameFromLink(link); -- local skillInfo = Cauldron: end ---------------------------------------------------------------------- -- Property functions ---------------------------------------------------------------------- --[[ Databroker Stuff --]] local ldb = LibStub:GetLibrary("LibDataBroker-1.1", true) if ldb then ldb:NewDataObject("Cauldron", { type = "launcher", text = "Cauldron shopping list", icon = "Interface\\Icons\\INV_Elemental_Mote_Nether", OnClick = function(frame, button) if button == "LeftButton" then Cauldron:ShowShoppingList(); elseif button == "RightButton" then Cauldron:ShoppingList_Toggle(); end end, OnTooltipShow = function(tooltip) tooltip:AddLine("Cauldron " .. Cauldron.version) end, }) end --[[ Database table structure: ["userdata"] = { ["<character-name>"] = { ["queue"] = { ["intermediate"] = { ["<skill>"] = { ["tradeskill"] = "<tradeskill>", -- human-readable name of the tradeskill that contains this skill ["name"] = "<skill>", -- human-readable name of the skill ["amount"] = <amount>, -- amount of this skill that must be executed ["priority"] = <priority>, -- priority of the skill, for ordering in the queue ["icon"] = "<icon>", -- the icon path of the skill, for display ["link"] = "<link>", }, }, ["main"] = { ["<skill>"] = { ["tradeskill"] = "<tradeskill>", ["name"] = "<skill>", ["amount"] = <amount>, ["priority"] = <priority>, ["icon"] = "<icon>", ["link"] = "<link>", }, }, ["reagents"] = { ["<reagent>"] = { ["tradeskill"] = "<tradeskill>", ["name"] = "<reagent>", ["amount"] = <amount>, ["icon"] = "<icon>", ["link"] = "<link>", }, }, }, ["skills"] = { ["<tradeskill>"] = { ["window"] = { -- window metadata ["categories"] = { -- category cache of the tradeskill ["<category>"] = { -- name of the category ["shown"] = true, -- whether the category is being shown in the skill list }, ... }, ["search"] = "", -- search text the user typed in the search box ["filter"] = { -- flags for the filter dropdown ["sortAlpha"] = false, -- should the list be sorted alphabetically (mutually-exclusive to "sortDifficulty" and "sortBenefit") ["sortDifficulty"] = true, -- should the list be sorted by difficulty (mutually-exclusive to "sortAlpha" and "sortBenefit") ["sortBenefit"] = false, -- should the list be sorted by potentcy of the benefit the crafted item/enchantment grants (mutually-exclusive to "sortDifficulty" and "sortAlpha") UNUSED ["haveAllReagents"] = false, -- should only items with all required reagents be shown in the list? ["haveKeyReagents"] = false, -- should only items with all key reagents be shown in the list? ["haveAnyReagents"] = false, -- should only items with any reagents be shown in the list? ["optimal"] = true, -- should optimal skills be shown? ["medium"] = true, -- should medium skills be shown? ["easy"] = true, -- should easy skills be shown? ["trivial"] = false, -- should trivial skills be shown? ["favorites"] = false, -- should only favorite skills be shown? }, ["skills"] = { ["<skill>"] = { ["expanded"] = false, -- should the skill's reagents be displayed? ["favorite"] = false, -- is the skill a favorite? }, ... }, ["selected"] = 1, -- skill index of the selected skill (gets reset on skill update events, like skill level increases and training) ["slots"] = { -- slot cache ["INVTYPE_FEET"] = true, ["INVTYPE_BAG"] = true, ["INVTYPE_CLOAK"] = true, ["(none)"] = true, -- special slot for items that don't have an assigned slot ["INVTYPE_WRIST"] = true, ["INVTYPE_WAIST"] = true, ["INVTYPE_CHEST"] = true, ["INVTYPE_LEGS"] = true, ["INVTYPE_HAND"] = true, }, }, ["recipes"] = { ["<skill>"] = { ["index"] = <skill index>, ["name"] = "<skill>", ["link"] = "<link>", ["icon"] = "<icon>", ["verb"] = "<verb>", -- this is present for skills that cast, like enchantments ["tradeskill"] = "<tradeskill>", ["difficulty"] = "<difficulty>", ["available"] = <available>, ["minMade"] = <min>, ["maxMade"] = <max>, ["slot"] = "INVTYPE_LEGS", ["defaultCategory"] = "<category>", ["reagents"] = { { ["name"] = "<reagent name>", ["numRequired"] = <required>, -- the number required of this reagent to complete one execution of the skill ["index"] = <reagent index>, -- the index of the reagent, for API call usage ["skillIndex"] = <skill index>, -- the index of the skill, for API call usage ["icon"] = "<icon>", ["key"] = <true-or-false>, }, -- [1] ... }, ["keywords"] = "<skill>,<reagent>,...", }, }, }, }, }, }, ["shopping"] = { ["<character-name>"] = { ["<reagent name>"] = <amount>, }, }, --]] function Cauldron:Enable() Cauldron.vars.enabled = true; self:Print(L["enabled"]); end function Cauldron:Disable() Cauldron.vars.enabled = false; self:Print(L["disabled"]); Cauldron:Frame_Hide(); end function Cauldron:Reset() self:Print("Starting reset."); -- close the window self:Print("Closing windows..."); Cauldron:Frame_Hide(); HideUIPanel(TradeSkillFrame); Cauldron:HideShoppingList(); -- reset some internal variables self:Print("Resetting internal variables..."); self.vars.enabled = true; -- reset the shopping list self:Print("Clearing shopping list..."); self.db.realm.shopping = CauldronShopping:NewList(); -- reset the skills for each character self:Print("Purging data structures..."); for toon, info in pairs(self.db.realm.userdata) do self.db.realm.userdata[toon] = {}; self.db.realm.userdata[toon].skills = {}; self.db.realm.userdata[toon].queue = CauldronQueue:NewQueue(); self.db.realm.userdata[toon].options = { autoBuy = false, compactView = false, }; end self:Print("Reset complete."); end