annotate Modules/Crafting.lua @ 121:f7efbd879062

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