annotate Modules/Queue.lua @ 240:24e71ed0a422

Added a default for when no addon was selected. Scanner is now disabled when the item count addon returns an error code.
author Zerotorescue
date Sat, 12 Feb 2011 20:15:31 +0100
parents 2e4e52a589e5
children
rev   line source
Zerotorescue@17 1 local addon = select(2, ...);
Zerotorescue@202 2 local mod = addon:NewModule("Queue", "AceEvent-3.0");
Zerotorescue@13 3
Zerotorescue@132 4 local _G = _G;
Zerotorescue@144 5 local tonumber, tostring, pairs, sformat, smatch, slower, floor, ceil, tinsert, twipe = _G.tonumber, _G.tostring, _G.pairs, _G.string.format, _G.string.match, _G.string.lower, _G.floor, _G.ceil, _G.table.insert, _G.table.wipe;
Zerotorescue@132 6
Zerotorescue@132 7 local queue, skipped = {}, {};
Zerotorescue@132 8
Zerotorescue@132 9 -- strings are passed by reference, so it takes no additional memory if one string was used in a thousand tables compared to any other reference type
Zerotorescue@132 10 local skipReasons = {
Zerotorescue@143 11 ["NOT_CRAFTABLE"] = {
Zerotorescue@143 12 "|cff3d3d3dNot in profession|r", -- gray
Zerotorescue@143 13 "This item is not part of this profession.",
Zerotorescue@143 14 0,
Zerotorescue@143 15 },
Zerotorescue@143 16 ["CAPPED"] = {
Zerotorescue@143 17 "|cff66ff33Fully stocked|r", -- lime/green
Zerotorescue@143 18 "The recorded item count is above or equal to your minimum restock target setting.",
Zerotorescue@143 19 5,
Zerotorescue@143 20 },
Zerotorescue@143 21 ["MIN_CRAFTING_QUEUE"] = {
Zerotorescue@143 22 "|cffffff00Min crafting queue|r", -- yellow
Zerotorescue@143 23 "The amount of missing items is below or equal to your \"don't queue if I only miss\"-setting.",
Zerotorescue@143 24 10,
Zerotorescue@143 25 },
Zerotorescue@143 26 ["LOW_VALUE"] = {
Zerotorescue@143 27 "|cffff6633Underpriced|r", -- orange
Zerotorescue@143 28 "The recorded auction value of this item is below your price threshold.",
Zerotorescue@143 29 15,
Zerotorescue@143 30 },
Zerotorescue@144 31 ["REMOVED"] = { -- because this is updated realtime, it is most useful around the top of the list
Zerotorescue@144 32 "|cffff0000Removed|r", -- red
Zerotorescue@144 33 "You manually removed this item from the queue.",
Zerotorescue@144 34 45,
Zerotorescue@144 35 },
Zerotorescue@144 36 ["FINISHED"] = { -- because this is updated realtime, it is most useful on the top of the list
Zerotorescue@144 37 "|cff00ff00Just finished|r", -- green
Zerotorescue@144 38 "Just finished restocking this item.",
Zerotorescue@144 39 50,
Zerotorescue@144 40 },
Zerotorescue@132 41 };
Zerotorescue@132 42
Zerotorescue@145 43 local function Compare(a, b, this, aRow, bRow, columnNo)
Zerotorescue@145 44 if a == b then
Zerotorescue@145 45 local column = this.cols[columnNo];
Zerotorescue@145 46 if column.sortnext then
Zerotorescue@145 47 local nextcol = this.cols[column.sortnext];
Zerotorescue@145 48 if not(nextcol.sort) then
Zerotorescue@145 49 if nextcol.comparesort then
Zerotorescue@145 50 return nextcol.comparesort(this, aRow, bRow, column.sortnext);
Zerotorescue@145 51 else
Zerotorescue@145 52 return this:CompareSort(this, bRow, column.sortnext);
Zerotorescue@145 53 end
Zerotorescue@145 54 else
Zerotorescue@145 55 return false;
Zerotorescue@145 56 end
Zerotorescue@145 57 else
Zerotorescue@145 58 return false;
Zerotorescue@145 59 end
Zerotorescue@145 60 elseif (this.cols[columnNo].sort or this.cols[columnNo].defaultsort or "asc") == "dsc" then
Zerotorescue@145 61 return a > b;
Zerotorescue@145 62 else
Zerotorescue@145 63 return a < b;
Zerotorescue@145 64 end
Zerotorescue@145 65 end
Zerotorescue@145 66
Zerotorescue@132 67 local function MakeQueueWindow()
Zerotorescue@143 68 if not InventoriumQueuer then
Zerotorescue@143 69 addon:CreateQueueFrame();
Zerotorescue@143 70
Zerotorescue@132 71 local frame = InventoriumQueuer; -- both for speed as code-consistency
Zerotorescue@132 72
Zerotorescue@132 73 -- Scrolling table with a list of items to be moved
Zerotorescue@132 74 local scrollTableWidth = ( frame.frmMeasureDummy:GetWidth() - 30 ); -- adjust width by the scrollbar size
Zerotorescue@132 75 local headers = {
Zerotorescue@132 76 {
Zerotorescue@132 77 ["name"] = "Item",
Zerotorescue@144 78 ["width"] = (scrollTableWidth * .65),
Zerotorescue@132 79 ["defaultsort"] = "asc",
Zerotorescue@145 80 ["comparesort"] = function(this, aRow, bRow, columnNo)
Zerotorescue@132 81 local aName, _, aRarity = GetItemInfo(this:GetRow(aRow).rowData.itemId);
Zerotorescue@132 82 local bName, _, bRarity = GetItemInfo(this:GetRow(bRow).rowData.itemId);
Zerotorescue@145 83 aName = sformat("%d%s", (10 - (aRarity or 10)), slower(aName or ""));
Zerotorescue@145 84 bName = sformat("%d%s", (10 - (bRarity or 10)), slower(bName or ""));
Zerotorescue@132 85
Zerotorescue@145 86 return Compare(aName, bName, this, aRow, bRow, columnNo);
Zerotorescue@132 87 end,
Zerotorescue@132 88 ["sort"] = "asc", -- when the data is set, use this column so sort the default data
Zerotorescue@144 89 ["tooltipTitle"] = "Item",
Zerotorescue@144 90 ["tooltip"] = "Click to sort the list by item quality then item name.",
Zerotorescue@132 91 },
Zerotorescue@132 92 {
Zerotorescue@132 93 ["name"] = "Amount",
Zerotorescue@144 94 ["width"] = (scrollTableWidth * .15),
Zerotorescue@132 95 ["align"] = "RIGHT",
Zerotorescue@132 96 ["defaultsort"] = "dsc",
Zerotorescue@145 97 ["comparesort"] = function(this, aRow, bRow, columnNo)
Zerotorescue@145 98 local a = this:GetRow(aRow).rowData.amount;
Zerotorescue@145 99 local b = this:GetRow(bRow).rowData.amount;
Zerotorescue@145 100
Zerotorescue@145 101 return Compare(a, b, this, aRow, bRow, columnNo);
Zerotorescue@143 102 end,
Zerotorescue@132 103 ["sortnext"] = 1,
Zerotorescue@144 104 ["tooltipTitle"] = "Amount needed",
Zerotorescue@144 105 ["tooltip"] = "Click to sort the list by the amount of items needed to reach the restock target.",
Zerotorescue@132 106 },
Zerotorescue@132 107 {
Zerotorescue@132 108 ["name"] = "Extra",
Zerotorescue@144 109 ["width"] = (scrollTableWidth * .15),
Zerotorescue@132 110 ["align"] = "RIGHT",
Zerotorescue@132 111 ["defaultsort"] = "dsc",
Zerotorescue@145 112 ["comparesort"] = function(this, aRow, bRow, columnNo)
Zerotorescue@145 113 local a = this:GetRow(aRow).rowData.bonus;
Zerotorescue@145 114 local b = this:GetRow(bRow).rowData.bonus;
Zerotorescue@145 115
Zerotorescue@145 116 return Compare(a, b, this, aRow, bRow, columnNo);
Zerotorescue@143 117 end,
Zerotorescue@132 118 ["sortnext"] = 1,
Zerotorescue@144 119 ["tooltipTitle"] = "Extra items",
Zerotorescue@144 120 ["tooltip"] = "Click to sort the list by the amount of bonus items.",
Zerotorescue@144 121 },
Zerotorescue@144 122 {
Zerotorescue@144 123 ["name"] = "X",
Zerotorescue@144 124 ["width"] = (scrollTableWidth * .05),
Zerotorescue@144 125 ["align"] = "CENTER",
Zerotorescue@144 126 ["sortnext"] = 1,
Zerotorescue@144 127 ["tooltipTitle"] = "Remove",
Zerotorescue@144 128 ["tooltip"] = "Click any of the fields in this column to remove this item from the queue.",
Zerotorescue@144 129 ["onClick"] = function(rowData)
Zerotorescue@144 130 -- Remove this element from the queue
Zerotorescue@144 131 for index, q in pairs(queue) do
Zerotorescue@144 132 if q == rowData then
Zerotorescue@144 133 table.remove(queue, index);
Zerotorescue@144 134 mod:Skip(q.itemId, skipReasons.REMOVED);
Zerotorescue@144 135 break;
Zerotorescue@144 136 end
Zerotorescue@144 137 end
Zerotorescue@144 138
Zerotorescue@144 139 -- Rebuild our scrolltable (records were removed and added)
Zerotorescue@144 140 mod:BuildQueue();
Zerotorescue@144 141 end,
Zerotorescue@144 142 ["color"] = { ["r"] = 1.0, ["g"] = 0.0, ["b"] = 0.0, ["a"] = 1, },
Zerotorescue@132 143 },
Zerotorescue@132 144 };
Zerotorescue@132 145
Zerotorescue@132 146 local scrollTableWidth = ( InventoriumQueuerUnqueueables.frmMeasureDummy:GetWidth() - 30 ); -- adjust width by the scrollbar size
Zerotorescue@132 147 local unqueueablesHeaders = {
Zerotorescue@132 148 {
Zerotorescue@132 149 ["name"] = "Item",
Zerotorescue@132 150 ["width"] = (scrollTableWidth * .6),
Zerotorescue@132 151 ["defaultsort"] = "asc",
Zerotorescue@145 152 ["comparesort"] = function(this, aRow, bRow, columnNo)
Zerotorescue@132 153 local aName, _, aRarity = GetItemInfo(this:GetRow(aRow).rowData.itemId);
Zerotorescue@132 154 local bName, _, bRarity = GetItemInfo(this:GetRow(bRow).rowData.itemId);
Zerotorescue@145 155 aName = sformat("%d%s", (10 - (aRarity or 10)), slower(aName or ""));
Zerotorescue@145 156 bName = sformat("%d%s", (10 - (bRarity or 10)), slower(bName or ""));
Zerotorescue@132 157
Zerotorescue@145 158 return Compare(aName, bName, this, aRow, bRow, columnNo);
Zerotorescue@132 159 end,
Zerotorescue@144 160 ["tooltipTitle"] = "Item",
Zerotorescue@144 161 ["tooltip"] = "Click to sort the list by item quality then item name.",
Zerotorescue@132 162 },
Zerotorescue@132 163 {
Zerotorescue@132 164 ["name"] = "Reason",
Zerotorescue@132 165 ["width"] = (scrollTableWidth * .4),
Zerotorescue@132 166 ["defaultsort"] = "dsc",
Zerotorescue@145 167 ["comparesort"] = function(this, aRow, bRow, columnNo)
Zerotorescue@145 168 local a = this:GetRow(aRow).rowData.reason[3];
Zerotorescue@145 169 local b = this:GetRow(bRow).rowData.reason[3];
Zerotorescue@145 170
Zerotorescue@145 171 return Compare(a, b, this, aRow, bRow, columnNo);
Zerotorescue@143 172 end,
Zerotorescue@143 173 ["sort"] = "dsc", -- when the data is set, use this column to sort the default data
Zerotorescue@132 174 ["sortnext"] = 1,
Zerotorescue@144 175 ["tooltipTitle"] = "Reason",
Zerotorescue@144 176 ["tooltip"] = "Click to sort the list by the reason the items couldn't be queued.",
Zerotorescue@132 177 },
Zerotorescue@132 178 };
Zerotorescue@132 179
Zerotorescue@132 180 local proceedButton = {
Zerotorescue@132 181 text = "Queue",
Zerotorescue@144 182 tooltipTitle = "Queue",
Zerotorescue@144 183 tooltip = "Add these items to the queue of your crafting addon.",
Zerotorescue@144 184 onClick = function() mod:QueueProcess(); end,
Zerotorescue@132 185 };
Zerotorescue@132 186 local cancelButton = {
Zerotorescue@132 187 text = "Cancel",
Zerotorescue@144 188 tooltipTitle = "Cancel",
Zerotorescue@144 189 tooltip = "Do not queue anything and close the window.",
Zerotorescue@144 190 onClick = function() mod:QueueAbort(); end,
Zerotorescue@132 191 };
Zerotorescue@145 192 local craftButton = {
Zerotorescue@145 193 text = "Craft",
Zerotorescue@145 194 tooltipTitle = "Craft",
Zerotorescue@145 195 tooltip = "Start crafting the first item.",
Zerotorescue@145 196 onClick = function() mod:StartCrafting(); end,
Zerotorescue@145 197 };
Zerotorescue@132 198
Zerotorescue@145 199 addon:SetQueueFrameSettings("Inventorium Queue", "The following items can be added to the queue of your crafting addon. Do you wish to proceed?", proceedButton, cancelButton, craftButton, headers, unqueueablesHeaders);
Zerotorescue@132 200 end
Zerotorescue@132 201 end
Zerotorescue@132 202
Zerotorescue@144 203 function mod:BuildQueue()
Zerotorescue@132 204 MakeQueueWindow();
Zerotorescue@132 205
Zerotorescue@132 206 -- This table is never copied, just referenced. It is the same for every row.
Zerotorescue@132 207 local queueablesColumns = {
Zerotorescue@132 208 {
Zerotorescue@132 209 ["value"] = function(data, cols, realrow, column, table)
Zerotorescue@132 210 return IdToItemLink(data[realrow].rowData.itemId);
Zerotorescue@132 211 end,
Zerotorescue@132 212 }, -- item
Zerotorescue@132 213 {
Zerotorescue@132 214 ["value"] = function(data, cols, realrow, column, table)
Zerotorescue@132 215 return data[realrow].rowData.amount;
Zerotorescue@132 216 end,
Zerotorescue@132 217 }, -- amount
Zerotorescue@132 218 {
Zerotorescue@132 219 ["value"] = function(data, cols, realrow, column, table)
Zerotorescue@143 220 return ((data[realrow].rowData.bonus == 0) and 0) or "+" .. data[realrow].rowData.bonus;
Zerotorescue@132 221 end,
Zerotorescue@132 222 ["color"] = function(data, cols, realrow, column, table)
Zerotorescue@132 223 return ((data[realrow].rowData.bonus == 0) and { r = 1, g = 1, b = 1, a = 0.5 }) or { r = 0, g = 1, b = 0, a = 1 };
Zerotorescue@132 224 end,
Zerotorescue@132 225 }, -- extra
Zerotorescue@144 226 {
Zerotorescue@144 227 ["value"] = "X",
Zerotorescue@144 228 },
Zerotorescue@132 229 };
Zerotorescue@132 230
Zerotorescue@132 231 -- Store the list with rows in this
Zerotorescue@132 232 local queueables = {};
Zerotorescue@132 233
Zerotorescue@132 234 for _, q in pairs(queue) do
Zerotorescue@132 235 tinsert(queueables, {
Zerotorescue@132 236 ["rowData"] = q, -- this is not a key usually found in a row item and ignored by the library
Zerotorescue@132 237 ["cols"] = queueablesColumns,
Zerotorescue@132 238 });
Zerotorescue@132 239 end
Zerotorescue@132 240
Zerotorescue@132 241 -- This table is never copied, just referenced. It is the same for every row.
Zerotorescue@132 242 local unqueueablesColumns = {
Zerotorescue@132 243 {
Zerotorescue@132 244 ["value"] = function(data, cols, realrow, column, table)
Zerotorescue@132 245 return IdToItemLink(data[realrow].rowData.itemId);
Zerotorescue@132 246 end,
Zerotorescue@132 247 }, -- item
Zerotorescue@132 248 {
Zerotorescue@132 249 ["value"] = function(data, cols, realrow, column, table)
Zerotorescue@132 250 return data[realrow].rowData.reason[1];
Zerotorescue@132 251 end,
Zerotorescue@132 252 }, -- reason
Zerotorescue@132 253 };
Zerotorescue@132 254
Zerotorescue@132 255 -- Store the list with rows in this
Zerotorescue@132 256 local unqueueables = {};
Zerotorescue@132 257
Zerotorescue@132 258 for _, s in pairs(skipped) do
Zerotorescue@132 259 tinsert(unqueueables, {
Zerotorescue@132 260 ["rowData"] = s, -- this is not a key usually found in a row item and ignored by the library
Zerotorescue@132 261 ["cols"] = unqueueablesColumns,
Zerotorescue@132 262 });
Zerotorescue@132 263 end
Zerotorescue@132 264
Zerotorescue@132 265 addon:SetQueueFrameData(queueables, unqueueables);
Zerotorescue@132 266 end
Zerotorescue@62 267
Zerotorescue@144 268 local function RefreshQueue()
Zerotorescue@144 269 InventoriumQueuer.scrollTable:Refresh();
Zerotorescue@14 270 end
Zerotorescue@14 271
Zerotorescue@144 272 do -- Crafting region
Zerotorescue@144 273 -- We are keeping these events within the module object to allow for easier testing and overriding
Zerotorescue@144 274 -- To test: LibStub("AceAddon-3.0"):GetAddon("Inventorium"):GetModule("Queue"):FUNCTION_NAME(param1, param2, ...);
Zerotorescue@144 275
Zerotorescue@144 276 -- Start crafting the selected skill (or the first in line)
Zerotorescue@144 277 local currentQueueItem;
Zerotorescue@144 278 function mod:StartCrafting(test)
Zerotorescue@144 279 local frame = InventoriumQueuer; -- both for speed as code-consistency
Zerotorescue@144 280
Zerotorescue@144 281 local selectedIndex = frame.scrollTable:GetSelection(); -- gets realrow index
Zerotorescue@144 282
Zerotorescue@145 283 addon:Debug("%s was selected.", tostring(selectedIndex));
Zerotorescue@144 284
Zerotorescue@144 285 if not selectedIndex then
Zerotorescue@144 286 -- Select the top most element (scrolltable with index of 1 will contain a index of the related realrow of the data table)
Zerotorescue@144 287 selectedIndex = ((frame.scrollTable.sorttable and frame.scrollTable.sorttable[1]) or 1);
Zerotorescue@144 288
Zerotorescue@145 289 addon:Debug("%s should be the top record.", tostring(selectedIndex));
Zerotorescue@144 290 end
Zerotorescue@144 291
Zerotorescue@145 292 local nextQueue = frame.scrollTable.data[selectedIndex].rowData or frame.scrollTable.data[1].rowData; -- if the selected index still fails, try to get the first record
Zerotorescue@144 293
Zerotorescue@144 294 if nextQueue then
Zerotorescue@144 295 if not test then
Zerotorescue@145 296 self:ResetTradeSkillFilters();
Zerotorescue@145 297
Zerotorescue@144 298 -- Initiate spell (test will be used while debugging to fake crafts)
Zerotorescue@144 299 DoTradeSkill(nextQueue.craft.no, ceil(nextQueue.amount / nextQueue.craft.quantity));
Zerotorescue@144 300 end
Zerotorescue@144 301
Zerotorescue@144 302 -- Remember what we're crafting (saves many loops and/or table storing)
Zerotorescue@144 303 currentQueueItem = nextQueue;
Zerotorescue@144 304
Zerotorescue@144 305 return;
Zerotorescue@144 306 else
Zerotorescue@144 307 addon:Print("Nothing is available in the craft queue.", addon.Colors.Red);
Zerotorescue@144 308 end
Zerotorescue@144 309 end
Zerotorescue@144 310
Zerotorescue@144 311 function mod:SpellCastComplete(_, unit, _, _, _, spellId)
Zerotorescue@144 312 -- Sadly the item isn't put in our inventory yet so we don't know how many were made.
Zerotorescue@144 313 -- Because of that we assume the average amount was made, this isn't really the best solution, but it's pretty-est - for now.
Zerotorescue@144 314
Zerotorescue@144 315 if unit == "player" and currentQueueItem and spellId == currentQueueItem.craft.spellId then
Zerotorescue@144 316 -- Decrease amount remaining by one quantity
Zerotorescue@144 317 currentQueueItem.amount = ( currentQueueItem.amount - currentQueueItem.craft.quantity );
Zerotorescue@144 318
Zerotorescue@144 319 if currentQueueItem.amount < 1 then
Zerotorescue@144 320 -- We finished crafting this item
Zerotorescue@144 321
Zerotorescue@144 322 -- Remove this element from the queue
Zerotorescue@144 323 for index, q in pairs(queue) do
Zerotorescue@144 324 if q == currentQueueItem then
Zerotorescue@144 325 table.remove(queue, index);
Zerotorescue@144 326 break;
Zerotorescue@144 327 end
Zerotorescue@144 328 end
Zerotorescue@144 329
Zerotorescue@144 330 -- Add this queue item to the "Unqueueables" frame - we finished it so it is no longer queueable and the user may become interested
Zerotorescue@144 331 self:Skip(currentQueueItem.itemId, skipReasons.FINISHED);
Zerotorescue@144 332
Zerotorescue@144 333 -- We are no longer crafting anything
Zerotorescue@144 334 currentQueueItem = nil;
Zerotorescue@144 335
Zerotorescue@144 336 -- Rebuild our scrolltable (records were removed and added)
Zerotorescue@144 337 mod:BuildQueue();
Zerotorescue@144 338 else
Zerotorescue@144 339 -- Refresh the scrolltable (update item counts)
Zerotorescue@144 340 RefreshQueue();
Zerotorescue@144 341 end
Zerotorescue@144 342 end
Zerotorescue@144 343 end
Zerotorescue@144 344
Zerotorescue@144 345 function mod:SpellCastStart(_, unit, _, _, _, spellId)
Zerotorescue@144 346 if unit == "player" and currentQueueItem and spellId == currentQueueItem.craft.spellId then
Zerotorescue@144 347 self.isProcessing = true;
Zerotorescue@144 348 end
Zerotorescue@144 349 end
Zerotorescue@144 350
Zerotorescue@144 351 function mod:SpellCastStop(_, unit, _, _, _, spellId)
Zerotorescue@144 352 if unit == "player" and currentQueueItem and spellId == currentQueueItem.craft.spellId then
Zerotorescue@144 353 self.isProcessing = nil;
Zerotorescue@144 354 end
Zerotorescue@144 355 end
Zerotorescue@144 356
Zerotorescue@144 357 function mod:SpellCastFailed(_, unit, _, _, _, spellId)
Zerotorescue@144 358 if unit == "player" and currentQueueItem and spellId == currentQueueItem.craft.spellId then
Zerotorescue@144 359 currentQueueItem = nil;
Zerotorescue@144 360 self.isProcessing = nil;
Zerotorescue@144 361 end
Zerotorescue@144 362 end
Zerotorescue@144 363
Zerotorescue@144 364 --@debug@
Zerotorescue@144 365 function TestCraft()
Zerotorescue@144 366 mod:StartCrafting(true);
Zerotorescue@144 367 mod:SpellCastComplete("UNIT_SPELLCAST_SUCCEEDED", "player", "Relentless Earthsiege Diamond", nil, nil, 55400);
Zerotorescue@144 368 end
Zerotorescue@144 369 --@end-debug@
Zerotorescue@14 370 end
Zerotorescue@14 371
Zerotorescue@144 372 function mod:QueueProcess()
Zerotorescue@144 373 -- Prepare a table with all possible tradeskill craftables
Zerotorescue@144 374 local craftables = self:GetTradeskillCraftables();
Zerotorescue@144 375
Zerotorescue@225 376 local craftingAddon = self:GetCraftingAddon(group);
Zerotorescue@225 377
Zerotorescue@225 378 if craftingAddon.OnQueueStart then
Zerotorescue@225 379 craftingAddon.OnQueueStart();
Zerotorescue@225 380 end
Zerotorescue@225 381
Zerotorescue@144 382 for _, q in pairs(queue) do
Zerotorescue@144 383 if craftables[q.itemId] then
Zerotorescue@144 384 if self:QueueWithAddon(craftables[q.itemId].no, ceil(q.amount / craftables[q.itemId].quantity), q.groupName) == -1 then
Zerotorescue@144 385 addon:Print("Couldn't queue, no supported crafting addon found.", addon.Colors.Red);
Zerotorescue@144 386
Zerotorescue@144 387 self:QueueAbort();
Zerotorescue@144 388 return;
Zerotorescue@144 389 else
Zerotorescue@144 390 -- Update the crafted-item count
Zerotorescue@144 391 for groupName, values in pairs(addon.db.profile.groups) do
Zerotorescue@144 392 if values.items and values.items[q.itemId] then
Zerotorescue@144 393 values.items[q.itemId] = (tonumber(values.items[q.itemId]) or 0) + 1;
Zerotorescue@144 394 break;
Zerotorescue@144 395 end
Zerotorescue@144 396 end
Zerotorescue@144 397 end
Zerotorescue@144 398 else
Zerotorescue@144 399 addon:Debug("Lost %s", IdToItemLink(q.itemId));
Zerotorescue@144 400 end
Zerotorescue@144 401 end
Zerotorescue@144 402
Zerotorescue@225 403 if craftingAddon.OnQueueEnd then
Zerotorescue@225 404 craftingAddon.OnQueueEnd();
Zerotorescue@225 405 end
Zerotorescue@225 406
Zerotorescue@144 407 self:QueueHide();
Zerotorescue@144 408 end
Zerotorescue@144 409
Zerotorescue@144 410 function mod:QueueAbort()
Zerotorescue@144 411 self:QueueHide();
Zerotorescue@144 412 end
Zerotorescue@144 413
Zerotorescue@144 414 function mod:QueueHide()
Zerotorescue@144 415 twipe(queue);
Zerotorescue@144 416 twipe(skipped);
Zerotorescue@144 417
Zerotorescue@144 418 if InventoriumQueuer then
Zerotorescue@144 419 InventoriumQueuer:Hide();
Zerotorescue@144 420 end
Zerotorescue@13 421 end
Zerotorescue@13 422
Zerotorescue@13 423 function mod:QueueAll()
Zerotorescue@132 424 -- Prepare a table with all possible tradeskill craftables
Zerotorescue@132 425 local craftables = self:GetTradeskillCraftables();
Zerotorescue@132 426
Zerotorescue@132 427 -- Forget old queue
Zerotorescue@132 428 twipe(queue);
Zerotorescue@132 429 twipe(skipped);
Zerotorescue@132 430
Zerotorescue@14 431 local playerName = UnitName("player");
Zerotorescue@14 432
Zerotorescue@14 433 -- Go through all groups
Zerotorescue@61 434 for groupName, values in pairs(addon.db.profile.groups) do
Zerotorescue@62 435 local trackAt = addon:GetOptionByKey(groupName, "trackAtCharacters");
Zerotorescue@14 436
Zerotorescue@14 437 if trackAt[playerName] then
Zerotorescue@209 438 if not self:QueueGroup(groupName, craftables) then
Zerotorescue@209 439 return;
Zerotorescue@209 440 end
Zerotorescue@13 441 end
Zerotorescue@13 442 end
Zerotorescue@132 443
Zerotorescue@144 444 mod:BuildQueue();
Zerotorescue@13 445 end
Zerotorescue@13 446
Zerotorescue@149 447 function mod:QueueGroup(groupName, craftables, displayQueue)
Zerotorescue@132 448 -- Prepare a table with all possible tradeskill craftables
Zerotorescue@132 449 if not craftables then
Zerotorescue@132 450 craftables = self:GetTradeskillCraftables(); -- nil when no tradeskill window is open
Zerotorescue@132 451 end
Zerotorescue@132 452
Zerotorescue@132 453 if not craftables then
Zerotorescue@207 454 addon:Print("No tradeskill window detected. Please open a profession before trying to queue.", addon.Colors.Red);
Zerotorescue@209 455 return false; -- exit
Zerotorescue@132 456 elseif not addon.db.profile.groups[groupName] then
Zerotorescue@132 457 addon:Print(sformat("Tried to queue items from a group named \"%s\", but no such group exists.", groupName), addon.Colors.Red);
Zerotorescue@209 458 return false; -- exit
Zerotorescue@132 459 elseif not addon.db.profile.groups[groupName].items then
Zerotorescue@132 460 addon:Debug("This group (%s) has no items.", groupName);
Zerotorescue@209 461 return true; -- continue with next group
Zerotorescue@14 462 end
Zerotorescue@14 463
Zerotorescue@132 464 -- Retrieve group settings
Zerotorescue@146 465 local restockTarget = addon:GetOptionByKey(groupName, "restockTarget");
Zerotorescue@146 466 local bonusQueue = addon:GetOptionByKey(groupName, "bonusQueue");
Zerotorescue@194 467 local minCraftingQueue = floor( addon:GetOptionByKey(groupName, "minCraftingQueue") * restockTarget ); -- If the minCraftingQueue is 5% and restockTarget is 60, this will result in 3
Zerotorescue@132 468 local priceThreshold = addon:GetOptionByKey(groupName, "priceThreshold");
Zerotorescue@13 469
Zerotorescue@140 470 for itemId, count in pairs(addon.db.profile.groups[groupName].items) do
Zerotorescue@132 471 if craftables[itemId] then
Zerotorescue@146 472 local currentStock = addon:GetItemCount(itemId, groupName);
Zerotorescue@31 473
Zerotorescue@146 474 if currentStock >= 0 then
Zerotorescue@146 475 -- Current stock will be -1 when no itemcount addon was found
Zerotorescue@31 476
Zerotorescue@146 477 -- Calculate the amount to be queued
Zerotorescue@146 478 local amount = ( restockTarget - currentStock );
Zerotorescue@146 479 local bonus = 0;
Zerotorescue@17 480
Zerotorescue@146 481 if currentStock == 0 and bonusQueue > 0 then
Zerotorescue@146 482 -- If we have none left and the bonus queue is enabled, modify the amount to be queued
Zerotorescue@31 483
Zerotorescue@146 484 bonus = floor( ( amount * ( bonusQueue ) ) + .5 ); -- round
Zerotorescue@146 485
Zerotorescue@146 486 -- Update amount
Zerotorescue@146 487 amount = (amount + bonus);
Zerotorescue@146 488 end
Zerotorescue@146 489
Zerotorescue@153 490 if amount > 0 and amount > minCraftingQueue then
Zerotorescue@146 491 -- If we are queuing at least one AND more than the minimum amount, then proceed
Zerotorescue@146 492
Zerotorescue@146 493 -- Get auction value when it is relevant
Zerotorescue@146 494 local value = (priceThreshold ~= 0 and addon:GetAuctionValue(IdToItemLink(itemId), groupName));
Zerotorescue@146 495
Zerotorescue@146 496 if priceThreshold == 0 or value == -1 or value >= priceThreshold then
Zerotorescue@146 497 -- If no price threshold is set or the auction value is equal to or larger than the price threshold, then proceed
Zerotorescue@146 498
Zerotorescue@146 499 self:Queue(itemId, amount, bonus, craftables[itemId], groupName);
Zerotorescue@146 500 else
Zerotorescue@146 501 self:Skip(itemId, skipReasons.LOW_VALUE);
Zerotorescue@146 502 --addon:Debug("%s is valued at %s while %s is needed", IdToItemLink(itemId), tostring(value), tostring(priceThreshold));
Zerotorescue@146 503 end
Zerotorescue@132 504 else
Zerotorescue@146 505 if amount <= 0 then
Zerotorescue@146 506 -- less than 0 = (over)capped
Zerotorescue@146 507 self:Skip(itemId, skipReasons.CAPPED);
Zerotorescue@146 508 else
Zerotorescue@146 509 -- more than 0 = below min crafting queue
Zerotorescue@146 510 self:Skip(itemId, skipReasons.MIN_CRAFTING_QUEUE);
Zerotorescue@146 511 end
Zerotorescue@14 512 end
Zerotorescue@14 513 else
Zerotorescue@146 514 -- No item count addon
Zerotorescue@209 515 addon:Print("No usable itemcount addon found.", addon.Colors.Red);
Zerotorescue@209 516 return false; -- exit
Zerotorescue@13 517 end
Zerotorescue@132 518 else
Zerotorescue@132 519 self:Skip(itemId, skipReasons.NOT_CRAFTABLE);
Zerotorescue@13 520 end
Zerotorescue@13 521 end
Zerotorescue@149 522
Zerotorescue@149 523 if displayQueue then
Zerotorescue@149 524 mod:BuildQueue();
Zerotorescue@149 525 end
Zerotorescue@209 526
Zerotorescue@209 527 return true; -- continue
Zerotorescue@13 528 end
Zerotorescue@13 529
Zerotorescue@143 530 function mod:Queue(itemId, amount, bonus, craft, groupName)
Zerotorescue@132 531 tinsert(queue, {
Zerotorescue@143 532 ["itemId"] = itemId, -- needed to display the queued item in the queue window
Zerotorescue@143 533 ["amount"] = amount, -- the amount missing
Zerotorescue@143 534 ["bonus"] = bonus, -- the amount queued by the bonus queue
Zerotorescue@143 535 ["craft"] = craft, -- (craftable) - needed to find the proper element of this parent array when crafting has finished (spellId), and to update the numCrafts (quantity)
Zerotorescue@143 536 ["groupName"] = groupName, -- related group, needed to find the selected crafting addon
Zerotorescue@132 537 });
Zerotorescue@132 538 end
Zerotorescue@132 539
Zerotorescue@132 540 function mod:Skip(itemId, reason)
Zerotorescue@132 541 tinsert(skipped, {
Zerotorescue@132 542 ["itemId"] = itemId,
Zerotorescue@132 543 ["reason"] = reason,
Zerotorescue@132 544 });
Zerotorescue@132 545 end
Zerotorescue@132 546
Zerotorescue@225 547 function mod:GetCraftingAddon(group)
Zerotorescue@225 548 local selectedExternalAddon = addon:GetOptionByKey(group, "craftingAddon");
Zerotorescue@225 549
Zerotorescue@225 550 if addon.supportedAddons.crafting[selectedExternalAddon] and addon.supportedAddons.crafting[selectedExternalAddon].IsEnabled() then
Zerotorescue@225 551 -- Try to use the default auction pricing addon
Zerotorescue@225 552
Zerotorescue@225 553 return addon.supportedAddons.crafting[selectedExternalAddon], selectedExternalAddon;
Zerotorescue@225 554 else
Zerotorescue@225 555 -- Default not available, get the first one then
Zerotorescue@225 556
Zerotorescue@225 557 for name, value in pairs(addon.supportedAddons.crafting) do
Zerotorescue@225 558 if value.IsEnabled() then
Zerotorescue@225 559 return value, name;
Zerotorescue@225 560 end
Zerotorescue@225 561 end
Zerotorescue@225 562 end
Zerotorescue@225 563
Zerotorescue@225 564 return;
Zerotorescue@225 565 end
Zerotorescue@225 566
Zerotorescue@132 567 function mod:QueueWithAddon(tradeSkillIndex, amount, group)
Zerotorescue@132 568 -- Sanity check
Zerotorescue@13 569 tradeSkillIndex = tonumber(tradeSkillIndex);
Zerotorescue@13 570 amount = tonumber(amount);
Zerotorescue@13 571
Zerotorescue@225 572 local craftingAddon = self:GetCraftingAddon(group);
Zerotorescue@23 573
Zerotorescue@225 574 if craftingAddon then
Zerotorescue@225 575 return craftingAddon.Queue(tradeSkillIndex, amount);
Zerotorescue@13 576 else
Zerotorescue@225 577 return -1;
Zerotorescue@13 578 end
Zerotorescue@13 579 end
Zerotorescue@132 580
Zerotorescue@144 581 function mod:OnEnable()
Zerotorescue@144 582 -- Register our own slash commands
Zerotorescue@144 583 -- /im queue
Zerotorescue@144 584 addon:RegisterSlash(function()
Zerotorescue@144 585 mod:QueueAll();
Zerotorescue@144 586 end, { "q", "que", "queue" }, "|Hfunction:InventoriumCommandHandler:queue|h|cff00fff7/im queue|r|h (or /im q) - Queue all items found in the currently opened profession that are within the groups tracked at this current character.");
Zerotorescue@144 587
Zerotorescue@144 588 self:RegisterMessage("IM_QUEUE_ALL");
Zerotorescue@144 589 self:RegisterMessage("IM_QUEUE_GROUP");
Zerotorescue@144 590
Zerotorescue@144 591 -- When closing the tradeskill window also hide the queue screen.
Zerotorescue@144 592 -- We scan the recipes right before queueing not when the tradeskill is opened because we really don't need it at any other time.
Zerotorescue@144 593 self:RegisterEvent("TRADE_SKILL_CLOSE", "QueueAbort");
Zerotorescue@144 594
Zerotorescue@144 595 -- Crafting events
Zerotorescue@144 596 self:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED", "SpellCastComplete");
Zerotorescue@144 597
Zerotorescue@144 598 -- Button en-/disabling
Zerotorescue@144 599 self:RegisterEvent("UNIT_SPELLCAST_START", "SpellCastStart");
Zerotorescue@144 600 self:RegisterEvent("UNIT_SPELLCAST_STOP", "SpellCastStop");
Zerotorescue@144 601
Zerotorescue@144 602 self:RegisterEvent("UNIT_SPELLCAST_FAILED", "SpellCastFailed");
Zerotorescue@144 603 self:RegisterEvent("UNIT_SPELLCAST_INTERRUPTED", "SpellCastFailed");
Zerotorescue@144 604 end
Zerotorescue@132 605
Zerotorescue@144 606 do -- Addon messages (Ace3) region
Zerotorescue@144 607 function mod:IM_QUEUE_ALL()
Zerotorescue@144 608 self:QueueAll();
Zerotorescue@144 609 end
Zerotorescue@144 610
Zerotorescue@144 611 function mod:IM_QUEUE_GROUP(event, groupName)
Zerotorescue@149 612 self:QueueGroup(groupName, nil, true);
Zerotorescue@132 613 end
Zerotorescue@132 614 end
Zerotorescue@132 615
Zerotorescue@144 616 do -- Trade skill recipes region
Zerotorescue@145 617 -- Reset all filters so no crafts are hidden
Zerotorescue@145 618 function mod:ResetTradeSkillFilters()
Zerotorescue@145 619 SetTradeSkillSubClassFilter(0, 1, 1);
Zerotorescue@145 620 SetTradeSkillItemNameFilter("");
Zerotorescue@145 621 SetTradeSkillItemLevelFilter(0, 0);
Zerotorescue@145 622 TradeSkillOnlyShowSkillUps(false);
Zerotorescue@145 623 TradeSkillOnlyShowMakeable(false);
Zerotorescue@145 624
Zerotorescue@145 625 -- Expand all categories so no crafts are hidden
Zerotorescue@144 626 for i = GetNumTradeSkills(), 1, -1 do
Zerotorescue@144 627 local _, skillType, _, isExpanded = GetTradeSkillInfo(i);
Zerotorescue@144 628
Zerotorescue@144 629 if skillType == "header" and not isExpanded then
Zerotorescue@144 630 ExpandTradeSkillSubClass(i);
Zerotorescue@132 631 end
Zerotorescue@132 632 end
Zerotorescue@132 633 end
Zerotorescue@144 634
Zerotorescue@144 635 -- Get all craftable items into a table. Each record contains "no", "spellId" and "quantity". The last is the average amount made per craft.
Zerotorescue@144 636 function mod:GetTradeskillCraftables()
Zerotorescue@144 637 local craftables = {};
Zerotorescue@144 638
Zerotorescue@144 639 if GetTradeSkillLine() ~= "UNKNOWN" then
Zerotorescue@145 640 self:ResetTradeSkillFilters();
Zerotorescue@144 641
Zerotorescue@144 642 -- Cache all craftable items
Zerotorescue@144 643 for i = 1, GetNumTradeSkills() do
Zerotorescue@144 644 local itemLink = GetTradeSkillItemLink(i);
Zerotorescue@144 645
Zerotorescue@144 646 if itemLink then
Zerotorescue@144 647 local itemId = addon:GetItemId(itemLink);
Zerotorescue@144 648 if not itemId then
Zerotorescue@144 649 -- If this isn't an item, it can only be an enchant instead
Zerotorescue@144 650 itemId = tonumber(smatch(itemLink, "|Henchant:([-0-9]+)|h"));
Zerotorescue@144 651
Zerotorescue@144 652 if itemId and addon.scrollIds[itemId] then
Zerotorescue@144 653 -- Only if this scroll id actually exists
Zerotorescue@144 654 itemId = addon.scrollIds[itemId]; -- change enchantIds into scrollIds
Zerotorescue@144 655 end
Zerotorescue@144 656 end
Zerotorescue@144 657
Zerotorescue@144 658 -- Remember the average amount of items created per craft (doesn't need to be a round number, since we multiply this by the amount of items to be queued we're better off rounding at that time)
Zerotorescue@144 659 local minMade, maxMade = GetTradeSkillNumMade(i);
Zerotorescue@144 660 local average = ((minMade == maxMade) and minMade) or ((minMade + maxMade) / 2);
Zerotorescue@144 661
Zerotorescue@144 662 local recipeLink = GetTradeSkillRecipeLink(i);
Zerotorescue@144 663 local spellId = tonumber(smatch(recipeLink, "|Henchant:([-0-9]+)|h"));
Zerotorescue@144 664
Zerotorescue@144 665 craftables[itemId] = {
Zerotorescue@144 666 ["no"] = i, -- needed to start crafting at the end of the entire cycle
Zerotorescue@144 667 ["spellId"] = spellId, -- needed to detect creation of this item was finished
Zerotorescue@144 668 ["quantity"] = average, -- needed to calculate the amount of crafts
Zerotorescue@144 669 };
Zerotorescue@144 670 end
Zerotorescue@144 671 end
Zerotorescue@144 672 else
Zerotorescue@144 673 return;
Zerotorescue@144 674 end
Zerotorescue@144 675
Zerotorescue@144 676 return craftables;
Zerotorescue@144 677 end
Zerotorescue@132 678 end