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