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
|