annotate Modules/Crafting.lua @ 125:bb78b6c9892d

When using the process button for Enchanting, ItemAuditor will check which vellum is used and will use the vellum from your inventory. If the correct vellum is not found, it will upgrade to the next level (use vellum II instead of vellum I). This also means that you have to press process for each scroll to be created.
author Asa Ayers <Asa.Ayers@Gmail.com>
date Thu, 02 Sep 2010 22:25:03 -0700
parents 060d1c45afab
children e8d3c299542c
rev   line source
Asa@63 1 local ItemAuditor = select(2, ...)
Asa@124 2 local Crafting = ItemAuditor:NewModule("Crafting", 'AceEvent-3.0')
Asa@59 3
Asa@86 4 local Utils = ItemAuditor:GetModule("Utils")
Asa@86 5
Asa@59 6 local AceGUI = LibStub("AceGUI-3.0")
Asa@59 7 local ScrollingTable = LibStub("ScrollingTable")
Asa@59 8
Asa@59 9 local validateMoney = ItemAuditor.validateMoney
Asa@59 10 local parseMoney = ItemAuditor.parseMoney
Asa@59 11
Asa@59 12 local realData = {}
Asa@59 13
Asa@124 14 local vellumLevelMap = {
Asa@124 15 [38682] = 37602, -- Armor Vellum => Armor Vellum II
Asa@124 16 [37602] = 43145, -- Armor Vellum II => Armor Vellum III
Asa@124 17 [39349] = 39350, -- Weapon Vellum => Weapon Vellum II
Asa@124 18 [39350] = 43146, -- Weapon Vellum II => Weapon Vellum III
Asa@124 19 }
Asa@67 20
Asa@68 21 local queueDestinations = {}
Asa@70 22 local displayCraftingDestinations = {}
Asa@68 23 function Crafting.RegisterQueueDestination(name, destination)
Asa@68 24 queueDestinations[name] = destination
Asa@70 25 displayCraftingDestinations[name] = name
Asa@70 26 end
Asa@70 27
Asa@70 28 function Crafting.UnRegisterQueueDestination(name)
Asa@70 29 queueDestinations[name] = nil
Asa@70 30 displayCraftingDestinations[name] = nil
Asa@70 31 end
Asa@70 32
Asa@70 33 function Crafting.GetQueueDestination()
Asa@70 34 local dest = ItemAuditor.db.profile.queue_destination
Asa@70 35 if dest and queueDestinations[dest] then
Asa@70 36 return queueDestinations[dest], dest
Asa@70 37 end
Asa@70 38 -- If there is none selected or the selected option has
Asa@70 39 -- dissapeared, choose the first one in the list
Asa@70 40 for name, func in pairs(queueDestinations) do
Asa@70 41 if dest then
Asa@70 42 ItemAuditor:Print("%s is no longer available as a queue destination. %s is the new default", dest, name)
Asa@70 43 end
Asa@70 44 ItemAuditor.db.profile.queue_destination = name
Asa@70 45 return func, name
Asa@70 46 end
Asa@70 47
Asa@70 48 error('Unable to determine queue destination.')
Asa@68 49 end
Asa@68 50
Asa@68 51 function ItemAuditor:GetCraftingThreshold()
Asa@101 52 return self.db.char.profitable_threshold
Asa@68 53 end
Asa@68 54
Asa@67 55 ItemAuditor.Options.args.crafting_options = {
Asa@70 56 name = "Crafting",
Asa@67 57 type = 'group',
Asa@67 58 args = {
Asa@70 59 queue_destination = {
Asa@70 60 type = "select",
Asa@70 61 name = "Queue Destination",
Asa@70 62 desc = "Select the addon who's queue you would like ItemAuditor to post to.",
Asa@70 63 values = displayCraftingDestinations,
Asa@70 64 get = function() return select(2, Crafting.GetQueueDestination()) end,
Asa@70 65 set = function(info, value) ItemAuditor.db.profile.queue_destination = value end,
Asa@72 66 order = 1,
Asa@70 67 },
Asa@72 68 deciders = {
Asa@72 69 type="header",
Asa@72 70 name="Crafting Deciders",
Asa@72 71 order = 10,
Asa@72 72 },
Asa@67 73 },
Asa@67 74 }
Asa@67 75
Asa@59 76 local function displayMoney(rowFrame, cellFrame, data, cols, row, realrow, column, fShow, table, ...)
Asa@59 77 if fShow == true then
Asa@59 78 local money = data[realrow][column]
Asa@59 79 if money then
Asa@59 80 cellFrame.text:SetText(ItemAuditor:FormatMoney(tonumber(money)))
Asa@59 81 else
Asa@59 82 cellFrame.text:SetText("")
Asa@59 83 end
Asa@59 84
Asa@59 85 end
Asa@59 86 end
Asa@59 87
Asa@59 88 local craftingCols = {
Asa@59 89 { name= "Item", width = 200, defaultsort = "desc",
Asa@59 90 ['DoCellUpdate'] = function(rowFrame, cellFrame, data, cols, row, realrow, column, fShow, table, ...)
Asa@59 91 if fShow == true then
Asa@59 92 local data = realData[realrow]
Asa@59 93 cellFrame.text:SetText(data.link)
Asa@59 94 end
Asa@59 95 end,
Asa@59 96 },
Asa@59 97 { name= "Cost Each", width = 100, align = "RIGHT",
Asa@59 98 ['DoCellUpdate'] = displayMoney,
Asa@59 99 },
Asa@59 100 { name= "Est Sale Each", width = 100, align = "RIGHT",
Asa@59 101 ['DoCellUpdate'] = displayMoney,
Asa@59 102 },
Asa@99 103 { name= "Decided By", width = 125, align = "RIGHT",
Asa@59 104
Asa@59 105 },
Asa@59 106 { name= "craft", width = 50, align = "RIGHT",
Asa@59 107
Asa@59 108 },
Asa@99 109 { name= "Have Mats", width = 60, align = "RIGHT",
Asa@99 110
Asa@99 111 },
Asa@123 112 { name= "Profit Each", width = 100, align = "RIGHT",
Asa@59 113 ['DoCellUpdate'] = displayMoney,
Asa@59 114 },
Asa@59 115 }
Asa@59 116
Asa@68 117 function Crafting.ExportToSkillet(data)
Asa@68 118 local skillString = select(3, string.find(data.recipeLink, "^|%x+|H(.+)|h%[.+%]"))
Asa@68 119 local _, skillId = strsplit(":", skillString)
Asa@68 120
Asa@68 121 ItemAuditor:AddToQueue(skillId,tradeSkillIndex, data.queue)
Asa@68 122 end
Asa@68 123
Asa@68 124 Crafting.RegisterQueueDestination('Skillet', Crafting.ExportToSkillet)
Asa@68 125
Asa@68 126
Asa@68 127
Asa@68 128 function Crafting.Export(destination)
Asa@68 129 if type(destination) == 'function' then
Asa@68 130 -- do nothing
Asa@68 131 elseif destination == nil then
Asa@70 132 destination = Crafting.GetQueueDestination()
Asa@68 133 elseif type(destination) == 'string' then
Asa@68 134 destination = queueDestinations[destination]
Asa@68 135 else
Asa@68 136 error('destination must be a function or a string')
Asa@68 137 end
Asa@68 138
Asa@59 139 local index = 1
Asa@59 140 local data = ItemAuditor:GetCraftingRow(index)
Asa@59 141 while data do
Asa@68 142 if data.queue > 0 then
Asa@68 143 destination(data)
Asa@68 144 end
Asa@61 145 index = index + 1
Asa@61 146 data = ItemAuditor:GetCraftingRow(index)
Asa@59 147
Asa@59 148 end
Asa@59 149 end
Asa@59 150
Asa@74 151 -- ItemAuditor:GetModule('Crafting').filter_queued = false
Asa@99 152 Crafting.filter_have_mats = false
Asa@99 153 Crafting.filter_show_all = false
Asa@74 154 local function tableFilter(self, row, ...)
Asa@99 155 if Crafting.filter_show_all then
Asa@99 156 return true
Asa@99 157 end
Asa@99 158
Asa@74 159 -- column 5 is how many should be crafted
Asa@99 160 if Crafting.filter_have_mats and row[6] == 'n' then
Asa@99 161 return false
Asa@99 162 end
Asa@99 163 if strfind(row[4], 'VETO: .*') or row[5] == 0 then
Asa@74 164 return false
Asa@74 165 end
Asa@74 166 return true
Asa@74 167 end
Asa@74 168
Asa@59 169 local craftingContent = false
Asa@59 170 local craftingTable = false
Asa@60 171 local btnProcess = false
Asa@59 172 local function ShowCrafting(container)
Asa@59 173 if craftingContent == false then
Asa@59 174 local window = container.frame
Asa@59 175 craftingContent = CreateFrame("Frame",nil,window)
Asa@59 176 craftingContent:SetBackdropColor(0, 0, 1, 0.5)
Asa@59 177 craftingContent:SetBackdropBorderColor(1, 0, 0, 1)
Asa@59 178
Asa@59 179 craftingContent:SetPoint("TOPLEFT", window, 10, -50)
Asa@59 180 craftingContent:SetPoint("BOTTOMRIGHT",window, -10, 10)
Asa@59 181
Asa@59 182 craftingTable = ScrollingTable:CreateST(craftingCols, 22, nil, nil, craftingContent )
Asa@59 183
Asa@59 184 IAcc = craftingContent
Asa@59 185 IAccWindow = window
Asa@59 186 craftingTable.frame:SetPoint("TOPLEFT",craftingContent, 0,0)
Asa@59 187 craftingTable.frame:SetPoint("BOTTOMRIGHT", craftingContent, 0, 30)
Asa@59 188
Asa@59 189 craftingTable:RegisterEvents({
Asa@59 190 ["OnEnter"] = function (rowFrame, cellFrame, data, cols, row, realrow, column, scrollingTable, ...)
Asa@59 191 if realrow then
Asa@59 192 local data = realData[realrow]
Asa@59 193
Asa@59 194 GameTooltip:SetOwner(rowFrame, "ANCHOR_CURSOR")
Asa@59 195 GameTooltip:SetHyperlink(data.link)
Asa@59 196 GameTooltip:Show()
Asa@59 197 end
Asa@59 198 end,
Asa@59 199 ["OnLeave"] = function (rowFrame, cellFrame, data, cols, row, realrow, column, scrollingTable, ...)
Asa@59 200 GameTooltip:Hide()
Asa@59 201 end,
Asa@59 202 });
Asa@59 203
Asa@99 204 local craftingView = CreateFrame("Button", nil, craftingContent, "UIPanelButtonTemplate")
Asa@99 205 craftingView:SetText("View")
Asa@99 206 craftingView:SetSize(50, 25)
Asa@99 207 craftingView:SetPoint("BOTTOMLEFT", craftingContent, 0, 0)
Asa@99 208
Asa@99 209 local menu = {
Asa@99 210 { text = "View", isTitle = true},
Asa@99 211 { text = "To be crafted", func = function()
Asa@99 212 Crafting.filter_have_mats = false
Asa@99 213 Crafting.filter_show_all = false
Asa@99 214 ItemAuditor:RefreshCraftingTable()
Asa@99 215 end },
Asa@99 216 { text = "Have Mats", func = function()
Asa@99 217 Crafting.filter_have_mats = true
Asa@99 218 Crafting.filter_show_all = false
Asa@99 219 ItemAuditor:RefreshCraftingTable()
Asa@99 220 end },
Asa@99 221 { text = "All", func = function()
Asa@99 222 Crafting.filter_have_mats = false
Asa@99 223 Crafting.filter_show_all = true
Asa@99 224 ItemAuditor:RefreshCraftingTable()
Asa@99 225 end },
Asa@99 226 }
Asa@99 227 local menuFrame = CreateFrame("Frame", "ExampleMenuFrame", UIParent, "UIDropDownMenuTemplate")
Asa@99 228 craftingView:SetScript("OnClick", function (self, button, down)
Asa@99 229 EasyMenu(menu, menuFrame, "cursor", 0 , 0, "MENU");
Asa@99 230 end)
Asa@99 231
Asa@99 232
Asa@59 233 btnProcess = CreateFrame("Button", nil, craftingContent, "UIPanelButtonTemplate")
Asa@59 234 btnProcess:SetText("Process")
Asa@59 235 btnProcess:SetSize(100, 25)
Asa@59 236 btnProcess:SetPoint("BOTTOMRIGHT", craftingContent, 0, 0)
Asa@59 237 btnProcess:RegisterForClicks("LeftButtonUp");
Asa@59 238
Asa@60 239 local function UpdateProcessTooltip(btn)
Asa@59 240 local data = ItemAuditor:GetCraftingRow(1)
Asa@59 241 if data then
Asa@59 242 GameTooltip:SetOwner(this, "ANCHOR_CURSOR")
Asa@59 243 GameTooltip:SetText(format('Create %sx%s', data.link, data.queue))
Asa@59 244 GameTooltip:Show()
Asa@59 245 end
Asa@60 246 end
Asa@124 247
Asa@124 248 --[[
Asa@124 249 When enchanting UseContainerItem seems to be protected, so the enchants
Asa@124 250 have to be done one at a time.
Asa@124 251 ]]
Asa@124 252 local function useVellum(vellumID, idealVellum)
Asa@124 253 for bagID = 0, NUM_BAG_SLOTS do
Asa@124 254 for slotID = 0, GetContainerNumSlots(bagID) do
Asa@124 255 local link = GetContainerItemLink(bagID, slotID)
Asa@124 256 local id = Utils.GetItemID(link);
Asa@124 257 if id == vellumID then
Asa@124 258 if idealVellum then
Asa@124 259 ItemAuditor:Print("Using %s instead of %s.",
Asa@124 260 select(2, GetItemInfo(vellumID)),
Asa@124 261 select(2, GetItemInfo(idealVellum))
Asa@124 262 )
Asa@124 263 end
Asa@124 264 UseContainerItem(bagID, slotID)
Asa@124 265 return
Asa@124 266 end
Asa@124 267 end
Asa@124 268 end
Asa@124 269 if vellumLevelMap[vellumID] then
Asa@124 270 return useVellum(vellumLevelMap[vellumID], idealVellum or vellumID)
Asa@124 271 end
Asa@124 272 end
Asa@124 273
Asa@60 274 btnProcess:SetScript("OnClick", function (self, button, down)
Asa@60 275 local data = ItemAuditor:GetCraftingRow(1)
Asa@60 276 if data then
Asa@124 277 local queue = data.queue
Asa@124 278 local vellumID = nil
Asa@124 279 _, _, _, _, altVerb = GetTradeSkillInfo(data.tradeSkillIndex)
Asa@124 280 if altVerb == 'Enchant' and LSW.scrollData[data.recipeID] ~= nil then
Asa@124 281 vellumID = LSW.scrollData[data.recipeID]["vellumID"]
Asa@124 282 queue = 1
Asa@124 283 end
Asa@124 284 ItemAuditor:Print('Crafting %sx%s', data.link, queue)
Asa@124 285 DoTradeSkill(data.tradeSkillIndex, queue)
Asa@124 286 if vellumID then
Asa@124 287 useVellum(vellumID)
Asa@124 288 end
Asa@124 289
Asa@124 290 data.queue = data.queue - queue
Asa@60 291 ItemAuditor:RefreshCraftingTable()
Asa@60 292 UpdateProcessTooltip()
Asa@60 293 end
Asa@59 294 end)
Asa@59 295
Asa@60 296 btnProcess:SetScript("OnEnter", UpdateProcessTooltip)
Asa@60 297
Asa@59 298 btnProcess:SetScript("OnLeave", function()
Asa@59 299 GameTooltip:Hide()
Asa@59 300 end)
Asa@59 301
Asa@59 302 btnSkillet = CreateFrame("Button", nil, craftingContent, "UIPanelButtonTemplate")
Asa@99 303
Asa@59 304 btnSkillet:SetSize(125, 25)
Asa@59 305 btnSkillet:SetPoint("BOTTOMRIGHT", btnProcess, 'BOTTOMLEFT', 0, 0)
Asa@59 306 btnSkillet:RegisterForClicks("LeftButtonUp");
Asa@59 307 btnSkillet:SetScript("OnClick", function (self, button, down)
Asa@70 308 Crafting.Export()
Asa@59 309 end)
Asa@59 310
Asa@59 311 end
Asa@70 312 local destination = select(2, Crafting.GetQueueDestination())
Asa@70 313 btnSkillet:SetText("Export to "..destination)
Asa@70 314
Asa@59 315 craftingContent:Show()
Asa@59 316
Asa@59 317 if container.parent then
Asa@59 318 local width = 80
Asa@59 319 for i, data in pairs(craftingCols) do
Asa@59 320 width = width + data.width
Asa@59 321 end
Asa@59 322 container.parent:SetWidth(width);
Asa@59 323 end
Asa@59 324
Asa@59 325 ItemAuditor:RegisterEvent("TRADE_SKILL_SHOW", function()
Asa@59 326 if craftingContent and craftingContent:IsVisible() then
Asa@59 327 ItemAuditor:UpdateCraftingTable()
Asa@59 328 end
Asa@59 329 end)
Asa@59 330 ItemAuditor:UpdateCraftingTable()
Asa@59 331
Asa@59 332 return craftingContent
Asa@59 333 end
Asa@59 334
Asa@59 335 ItemAuditor:RegisterTab('Crafting', 'tab_crafting', ShowCrafting)
Asa@59 336 function ItemAuditor:DisplayCrafting()
Asa@59 337 self:CreateFrame('tab_crafting')
Asa@59 338 end
Asa@59 339
Asa@59 340 local craftingDeciders = {}
Asa@59 341
Asa@72 342 function Crafting.RegisterCraftingDecider(name, decider, options)
Asa@59 343 craftingDeciders[name] = decider
Asa@72 344
Asa@72 345 ItemAuditor.Options.args.crafting_options.args['chk'..name] = {
Asa@72 346 type = "toggle",
Asa@72 347 name = "Enable "..name,
Asa@72 348 get = function() return not ItemAuditor.db.profile.disabled_deciders[name] end,
Asa@72 349 set = function(info, value) ItemAuditor.db.profile.disabled_deciders[name] = not value end,
Asa@72 350 order = 11,
Asa@72 351 }
Asa@72 352
Asa@72 353 if options then
Asa@72 354 ItemAuditor.Options.args.crafting_options.args['decider_'..name] = {
Asa@72 355 handler = {},
Asa@72 356 name = name,
Asa@72 357 type = 'group',
Asa@72 358 args = options,
Asa@72 359 }
Asa@72 360 end
Asa@59 361 end
Asa@59 362
Asa@59 363 local lastWinnder = ""
Asa@59 364 local function Decide(data)
Asa@59 365 local newDecision = 0
Asa@74 366 local reason = ""
Asa@59 367 for name, decider in pairs(craftingDeciders) do
Asa@72 368 if not ItemAuditor.db.profile.disabled_deciders[name] and name ~= lastWinner then
Asa@74 369 newDecision, reason = decider(data)
Asa@74 370
Asa@59 371 if newDecision > data.queue then
Asa@59 372 data.queue = newDecision
Asa@74 373 lastWinner = (reason or name)
Asa@59 374 return Decide(data)
Asa@59 375 elseif newDecision < 0 then
Asa@59 376 lastWinner = ""
Asa@74 377 return 'VETO: '..(reason or name), -1
Asa@59 378 end
Asa@59 379 end
Asa@59 380 end
Asa@59 381
Asa@59 382 winner = lastWinner
Asa@59 383 lastWinner = ""
Asa@59 384
Asa@77 385 data.queue = ceil(data.queue / GetTradeSkillNumMade(data.tradeSkillIndex))
Asa@77 386
Asa@59 387 return winner, data.queue
Asa@59 388 end
Asa@59 389
Asa@59 390 local function isProfitable(data)
Asa@59 391 if data.profit > 0 and data.profit > ItemAuditor:GetCraftingThreshold() then
Asa@59 392 return 1
Asa@59 393 end
Asa@99 394 return -1, 'Not Profitable'
Asa@59 395 end
Asa@72 396
Asa@101 397 local isProfitableOptions = {
Asa@101 398 profitable_threshold = {
Asa@101 399 type = "input",
Asa@101 400 name = "Crafting Threshold",
Asa@101 401 desc = "Don't create items that will make less than this amount of profit",
Asa@101 402 get = function() return
Asa@101 403 Utils.FormatMoney(ItemAuditor:GetCraftingThreshold(), '', true)
Asa@101 404 end,
Asa@101 405 validate = function(info, value)
Asa@101 406 if not Utils.validateMoney(value) then
Asa@101 407 return "Invalid money format"
Asa@101 408 end
Asa@101 409 return true
Asa@101 410 end,
Asa@101 411 set = function(info, value)
Asa@101 412 ItemAuditor.db.char.profitable_threshold = Utils.parseMoney(value)
Asa@101 413 end,
Asa@101 414 usage = "###g ##s ##c",
Asa@101 415 order = 0,
Asa@101 416 },
Asa@101 417 }
Asa@101 418
Asa@101 419 Crafting.RegisterCraftingDecider('Is Profitable', isProfitable, isProfitableOptions)
Asa@59 420
Asa@74 421
Asa@59 422
Asa@59 423 local tableData = {}
Asa@59 424 function ItemAuditor:UpdateCraftingTable()
Asa@59 425 if LSW == nil then
Asa@59 426 self:Print("This feature requires LilSparky's Workshop.")
Asa@59 427 return
Asa@59 428 end
Asa@59 429 if GetAuctionBuyout ~= nil then
Asa@59 430 elseif AucAdvanced and AucAdvanced.Version then
Asa@59 431 else
Asa@59 432 self:Print("This feature requires Auctionator, Auctioneer, AuctionLite, or AuctionMaster.")
Asa@59 433 return
Asa@59 434 end
Asa@59 435 wipe(realData)
Asa@59 436 wipe(tableData)
Asa@59 437
Asa@59 438 local profitableItems = {}
Asa@59 439 local profitableIndex = 1
Asa@59 440 local numChecked = 0
Asa@59 441 local row = 1
Asa@59 442
Asa@59 443 for i = 1, GetNumTradeSkills() do
Asa@59 444 local itemLink = GetTradeSkillItemLink(i)
Asa@86 445 local itemId = Utils.GetItemID(itemLink)
Asa@124 446 local vellumID = nil
Asa@59 447
Asa@59 448 --Figure out if its an enchant or not
Asa@59 449 _, _, _, _, altVerb = GetTradeSkillInfo(i)
Asa@59 450 if LSW.scrollData[itemId] ~= nil and altVerb == 'Enchant' then
Asa@59 451 -- Ask LSW for the correct scroll
Asa@124 452 local sd = LSW.scrollData[itemId]
Asa@124 453 itemId = sd.scrollID
Asa@124 454 vellumID = sd.vellumID
Asa@59 455 end
Asa@59 456
Asa@59 457 local recipeLink = GetTradeSkillRecipeLink(i)
Asa@59 458 local stackSize = 1
Asa@59 459 if recipeLink ~= nil and itemId ~= nil then
Asa@59 460 local skillName, skillType, numAvailable, isExpanded, altVerb = GetTradeSkillInfo(i)
Asa@59 461 local itemName, itemLink= GetItemInfo(itemId)
Asa@74 462
Asa@74 463 -- This check has to be here for things like Inscription Research that don't produce an item.
Asa@74 464 if itemLink then
Asa@82 465 local count = ItemAuditor:GetItemCount(itemId)
Asa@74 466 local reagents = {}
Asa@74 467 local totalCost = 0
Asa@74 468 for reagentId = 1, GetTradeSkillNumReagents(i) do
Asa@74 469 local reagentName, _, reagentCount = GetTradeSkillReagentInfo(i, reagentId);
Asa@74 470 local reagentLink = GetTradeSkillReagentItemLink(i, reagentId)
Asa@102 471 local reagentTotalCost = self:GetReagentCost(reagentLink, reagentCount)
Asa@74 472
Asa@74 473 reagents[reagentId] = {
Asa@93 474 link = reagentLink,
Asa@124 475 itemID = Utils.GetItemID(reagentLink),
Asa@74 476 name = reagentName,
Asa@74 477 count = reagentCount,
Asa@102 478 price = reagentTotalCost / reagentCount,
Asa@94 479 need = 0, -- This will get populated after the decisions have been made. it can't
Asa@94 480 -- be done before that because highest profit items get priority on materials.
Asa@74 481 }
Asa@102 482 totalCost = totalCost + reagentTotalCost
Asa@74 483 end
Asa@124 484 if vellumID then
Asa@124 485 reagentId = GetTradeSkillNumReagents(i) + 1
Asa@124 486 local reagentName, reagentLink = GetItemInfo(vellumID)
Asa@124 487 reagents[reagentId] = {
Asa@124 488 link = reagentLink,
Asa@124 489 itemID = vellumID,
Asa@124 490 name = reagentName,
Asa@124 491 count = 1,
Asa@124 492 price = self:GetReagentCost(reagentLink, 1),
Asa@124 493 need = 0, -- This will get populated after the decisions have been made. it can't
Asa@124 494 -- be done before that because highest profit items get priority on materials.
Asa@124 495 }
Asa@124 496 totalCost = totalCost + self:GetReagentCost(reagentLink, 1)
Asa@124 497 end
Asa@116 498
Asa@116 499 local price = (self:GetAuctionPrice(itemLink) or 0)
Asa@116 500 totalCost = totalCost + (price * ItemAuditor:GetAHCut())
Asa@74 501 local data = {
Asa@74 502 recipeLink = recipeLink,
Asa@95 503 recipeID = Utils.GetItemID(recipeLink),
Asa@74 504 link = itemLink,
Asa@74 505 name = itemName,
Asa@74 506 count = count,
Asa@110 507 price = price,
Asa@74 508 cost = totalCost,
Asa@110 509 profit = price - totalCost,
Asa@74 510 reagents = reagents,
Asa@74 511 count = count,
Asa@74 512 tradeSkillIndex = i,
Asa@74 513 queue = 0,
Asa@74 514 winner = "",
Asa@74 515 }
Asa@59 516
Asa@74 517 data.winner, data.queue = Decide(data)
Asa@99 518 --[[
Asa@99 519 If it wasn't vetoed we need to reduce the number by how many are owned
Asa@99 520 but this should not go below 0
Asa@99 521 ]]
Asa@99 522 if data.queue > 0 then
Asa@99 523 data.queue = max(0, data.queue - count)
Asa@99 524 end
Asa@74 525
Asa@74 526 -- If a tradeskill makes 5 at a time and something asks for 9, we should only
Asa@74 527 -- craft twice to get 10.
Asa@74 528 data.queue = ceil(data.queue / GetTradeSkillNumMade(i))
Asa@74 529
Asa@74 530 realData[row] = data
Asa@74 531 row = row + 1
Asa@59 532 end
Asa@59 533 end
Asa@59 534 end
Asa@99 535 table.sort(realData, function(a, b) return a.profit*max(1, a.queue) > b.profit*max(1, b.queue) end)
Asa@94 536
Asa@94 537 local numOwned = {}
Asa@124 538
Asa@94 539 for key, data in pairs(realData) do
Asa@94 540 data.haveMaterials = true
Asa@94 541 for id, reagent in pairs(data.reagents) do
Asa@122 542 reagent.count = reagent.count * data.queue
Asa@122 543
Asa@94 544 if not numOwned[reagent.link] then
Asa@94 545 numOwned[reagent.link] = ItemAuditor:GetItemCount(ItemAuditor:GetIDFromLink(reagent.link))
Asa@94 546 end
Asa@94 547 numOwned[reagent.link] = numOwned[reagent.link] - reagent.count
Asa@94 548
Asa@124 549 -- Vellums count in cost, but not against whether or not you have the mats.
Asa@124 550 -- I chose to do it this way because you can use a higher level of vellum
Asa@124 551 -- and I'm not sure the best way to determine cost and materials in that situation.
Asa@124 552 if numOwned[reagent.link] < 0 and not vellumLevelMap[reagent.itemID] then
Asa@94 553 data.haveMaterials = false
Asa@94 554 reagent.need = min(reagent.count, abs(numOwned[reagent.link]))
Asa@94 555 end
Asa@94 556 end
Asa@94 557 end
Asa@94 558
Asa@68 559 if craftingTable then
Asa@68 560 craftingTable:SetFilter(tableFilter)
Asa@68 561 self:RefreshCraftingTable()
Asa@68 562 end
Asa@60 563 end
Asa@60 564
Asa@60 565 function ItemAuditor:RefreshCraftingTable()
Asa@99 566 local displayMaterials
Asa@59 567 for key, data in pairs(realData) do
Asa@99 568 displayMaterials = 'n'
Asa@99 569 if data.haveMaterials then
Asa@99 570 displayMaterials = 'y'
Asa@99 571 end
Asa@59 572 tableData[key] = {
Asa@59 573 data.name,
Asa@59 574 data.cost,
Asa@59 575 data.price,
Asa@59 576 data.winner,
Asa@99 577 abs(data.queue),
Asa@99 578 displayMaterials,
Asa@123 579 data.profit,
Asa@59 580 }
Asa@59 581 end
Asa@60 582 craftingTable:SetData(tableData, true)
Asa@59 583
Asa@60 584 if self:GetCraftingRow(1) then
Asa@60 585 btnProcess:Enable()
Asa@60 586 else
Asa@60 587 btnProcess:Disable()
Asa@60 588 end
Asa@59 589 end
Asa@59 590
Asa@59 591 function ItemAuditor:GetCraftingRow(row)
Asa@59 592 if craftingTable then
Asa@59 593 for _, index in pairs(craftingTable.sorttable) do
Asa@59 594 local tableRow = tableData[index]
Asa@59 595 if tableFilter(nil, tableRow) then
Asa@59 596 row = row - 1
Asa@59 597 if row == 0 then
Asa@59 598 return realData[index]
Asa@59 599 end
Asa@59 600 end
Asa@59 601 end
Asa@59 602 elseif realData then
Asa@59 603 return realData[row]
Asa@59 604 end
Asa@59 605 return nil
Asa@59 606 end
Asa@67 607 ItemAuditor.Options.args.crafting = {
Asa@67 608 type = "execute",
Asa@67 609 name = "crafting",
Asa@67 610 desc = "This opens a window to configure a crafting queue.",
Asa@67 611 func = "DisplayCrafting",
Asa@67 612 guiHidden = false,
Asa@67 613 }