vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 ------------------------------------------------------
2 -- AutoCraft.lua
3 -- Originally based on BetterTradeSkill by Matt Perry (http://somewhere.fscked.org)
4 ------------------------------------------------------
5 FAC_VERSION = "11200.1";
6 ------------------------------------------------------
7  
8 FAC_Config = {};
9 FAC_Config.AutoIterate = false;
10  
11 local P = {};
12 AutoCraft = P;
13  
14 P.OrderedQueue = {};
15 P.QueuedReagents = {};
16 P.ManuallyPaused = false;
17 P.SkillCache = {};
18 P.ReagentCache = {};
19 P.NoOverride = true;
20 P.TradeSkillsSeen = {};
21  
22 local MAX_QUEUE_BUTTONS = 10;
23 local CACHE_TIME = 5; -- We cache the returns from our hooked GetTradeSkillInfo because it can be called many times a second without actually having any relevant conditions be different. This keeps us from repeatedly recalculating it when not needed.
24 local QUEUE_ADVANCE_DELAY = 1; -- In 1.8 we seem to have problems if we try to advance the queue too soon after finishing an item (if the item we just finished is needed to craft the next item in the queue, WoW thinks we don't have it yet and thus can't craft the next item). May have something to do with lag. So, we wait this many seconds before trying to advance the queue.
25 local TRADESKILL_UPDATE_TIME = 5;
26  
27 function P.GetTradeSkillInfo(index)
28 if (P.SkillCache[index] and (GetTime() - P.SkillCache[index].time < CACHE_TIME)) then
29 local info = P.SkillCache[index].info;
30 return info.skillName, info.difficulty, info.numAvailable, info.isExpanded, info.itemName;
31 end
32  
33 local skillName, difficulty, numAvailable, isExpanded = P.Orig_GetTradeSkillInfo(index);
34  
35 if (skillName == nil or difficulty == "header") then
36 -- something calls us a lot when the TradeSkillFrame is first shown, and Orig_GetTradeSkillInfo returns bogus at that time.
37 -- just pass along bogus returns so we don't get bogged down in calculation or cache checks;
38 -- we'll get called again and be able to use the right info soon enough.
39 return skillName, difficulty, numAvailable, isExpanded, nil;
40 end
41  
42 -- Adjustment #1: recalculate numAvailable based on our altered GetTradeSkillReagentInfo (normally its value is calculated by the client)
43 local reagentTally = {};
44 for reagentIndex = 1, GetTradeSkillNumReagents(index) do
45 local reagentName, _, reagentCount, playerReagentCount = P.GetTradeSkillReagentInfo(index, reagentIndex);
46 local completeItemsWorth = math.max(math.floor(playerReagentCount / reagentCount), 0);
47 table.insert(reagentTally, completeItemsWorth); -- how many could we make if this were the only reagent in question?
48 end
49 numAvailable = (math.min(unpack(reagentTally)) or 0); -- this is how many we can really make if we include already-queued reagents
50  
51 -- Adjustment #2 (TODO): how many of this item could we make if we were to make/buy the reagents right now?
52  
53 -- For testing
54 --numAvailable = math.random(5);
55  
56 local itemName = P.GetTradeItemName(index);
57 if (skillName ~= nil) then
58 P.SkillCache[index] = { time=GetTime(), info={ skillName=skillName, difficulty=difficulty, numAvailable=numAvailable, isExpanded=isExpanded, itemName=itemName } };
59 end
60  
61 return skillName, difficulty, numAvailable, isExpanded, itemName;
62 end
63  
64 function P.GetTradeSkillReagentInfo(skillIndex, reagentIndex)
65 local index = skillIndex.."."..reagentIndex;
66 if (P.ReagentCache[index] and (GetTime() - P.ReagentCache[index].time < CACHE_TIME)) then
67 local info = P.ReagentCache[index].info;
68 return info.reagentName, info.reagentTexture, info.reagentCount, info.playerReagentCount;
69 end
70  
71 local reagentName, reagentTexture, reagentCount, playerReagentCount = P.Orig_GetTradeSkillReagentInfo(skillIndex, reagentIndex);
72  
73 if (reagentName == nil or reagentTexture == nil) then
74 -- something calls us a lot when the TradeSkillFrame is first shown, and Orig_GetTradeSkillReagentInfo returns bogus then.
75 -- just pass along bogus returns so we don't get bogged down in calculation or cache checks;
76 -- we'll get called again and be able to use the right info soon enough.
77 return reagentName, reagentTexture, reagentCount, playerReagentCount;
78 end
79  
80 -- Adjustment #1: if you've queued some of this item, add them to effective "inventory" for determining what you can make from it.
81 playerReagentCount = playerReagentCount + P.NumOfItemInQueue(reagentName);
82  
83 -- Adjustment #2: if your queue contains items that use this reagent, subtract the amount that will be used from your "inventory".
84 for _, queueEntry in P.OrderedQueue do
85 local perItemCount = queueEntry.reagentsPerItem[reagentName];
86 if (perItemCount ~= nil) then
87 playerReagentCount = playerReagentCount - ((queueEntry.numQueued - queueEntry.numProduced) * perItemCount);
88 end
89 end
90 playerReagentCount = math.max(playerReagentCount, 0);
91  
92 if (reagentName ~= nil) then
93 P.ReagentCache[index] = { time=GetTime(), info={ reagentName=reagentName, reagentTexture=reagentTexture, reagentCount=reagentCount, playerReagentCount=playerReagentCount } };
94 end
95  
96 return reagentName, reagentTexture, reagentCount, playerReagentCount;
97 end
98  
99 function P.GetTradeSkillTools(skillIndex)
100 local toolInfo = {P.Orig_GetTradeSkillTools(skillIndex)};
101 local newToolInfo = {};
102 for index = 1, table.getn(toolInfo) do
103 local item = toolInfo[index];
104 if (item and type(item) == "string") then
105 table.insert(newToolInfo, item);
106 if (toolInfo[index+1] == 1 or P.NumOfItemInQueue(item) > 0) then
107 table.insert(newToolInfo, 1);
108 end
109 end
110 end
111 return unpack(newToolInfo);
112 end
113  
114 function P.TradeSkillFrame_Update()
115 P.Orig_TradeSkillFrame_Update();
116  
117 local skillName = GetTradeSkillLine();
118 if (P.TradeSkillsSeen[skillName] == nil) then
119 P.TradeSkillsSeen[skillName] = GetTime();
120 --GFWUtils.Print("Disabling TradeSkillFrame overrides.");
121 P.NoOverride = true;
122 end
123 if (P.NoOverride or FAC_Config.NoOverride) then return; end
124  
125 local numTradeSkills = GetNumTradeSkills();
126 local skillOffset = FauxScrollFrame_GetOffset(TradeSkillListScrollFrame);
127 for i=1, TRADE_SKILLS_DISPLAYED, 1 do
128 local skillIndex = i + skillOffset;
129 local skillName, skillType, numAvailable, isExpanded = P.GetTradeSkillInfo(skillIndex);
130 local skillButton = getglobal("TradeSkillSkill"..i);
131 if ( skillIndex <= numTradeSkills and skillName ) then
132 if ( numAvailable == 0 ) then
133 skillButton:SetText(" "..skillName);
134 else
135 skillButton:SetText(" "..skillName.." ["..numAvailable.."]");
136 end
137 end
138 end
139 end
140  
141 function P.TradeSkillFrame_SetSelection(id)
142 P.Orig_TradeSkillFrame_SetSelection(id);
143  
144 local skillName = GetTradeSkillLine();
145 if (P.TradeSkillsSeen[skillName] == nil) then
146 P.TradeSkillsSeen[skillName] = GetTime();
147 --GFWUtils.Print("Disabling TradeSkillFrame overrides.");
148 P.NoOverride = true;
149 end
150 if (P.NoOverride or FAC_Config.NoOverride) then return; end
151  
152 local creatable = 1;
153 local numReagents = GetTradeSkillNumReagents(id);
154 for i=1, numReagents, 1 do
155 local reagentName, reagentTexture, reagentCount, playerReagentCount = P.GetTradeSkillReagentInfo(id, i);
156 local reagent = getglobal("TradeSkillReagent"..i)
157 local name = getglobal("TradeSkillReagent"..i.."Name");
158 local count = getglobal("TradeSkillReagent"..i.."Count");
159 if ( reagentName and reagentTexture ) then
160 if ( playerReagentCount < reagentCount ) then
161 SetItemButtonTextureVertexColor(reagent, 0.5, 0.5, 0.5);
162 name:SetTextColor(GRAY_FONT_COLOR.r, GRAY_FONT_COLOR.g, GRAY_FONT_COLOR.b);
163 creatable = nil;
164 else
165 SetItemButtonTextureVertexColor(reagent, 1.0, 1.0, 1.0);
166 name:SetTextColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b);
167 end
168 if ( playerReagentCount >= 100 ) then
169 playerReagentCount = "*";
170 end
171 count:SetText(playerReagentCount.." /"..reagentCount);
172 end
173 end
174 local spellFocus = BuildColoredListString(P.GetTradeSkillTools(id));
175 if ( spellFocus ) then
176 TradeSkillRequirementText:SetText(spellFocus);
177 end
178  
179 if (creatable) then
180 AutoCraftQueue:Enable();
181 AutoCraftQueueAll:Enable();
182 else
183 AutoCraftQueue:Disable();
184 AutoCraftQueueAll:Disable();
185 end
186 end
187  
188 function P.Load()
189 if (not P.Loaded) then
190 -- Attach our UI elements to the TradeSkillFrame now that it's loaded.
191 AutoCraftBackground:SetParent(TradeSkillFrame);
192 AutoCraftBackground:SetPoint("TOPLEFT", 0, 0);
193 AutoCraftBackground:SetHeight(TradeSkillFrame:GetHeight() + 48);
194 -- reset this in case someone (say, EnhancedTradeSkill) resized TradeSkillFrame on us
195 AutoCraftBackground:Show();
196 AutoCraftQueue:SetParent(TradeSkillFrame);
197 AutoCraftQueue:SetPoint("TOPLEFT", TradeSkillCreateButton, "TOPLEFT", 0, 0);
198 AutoCraftQueue:Show();
199 AutoCraftQueueAll:SetParent(TradeSkillFrame);
200 AutoCraftQueueAll:SetPoint("TOPLEFT", TradeSkillCreateAllButton, "TOPLEFT", 0, 0);
201 AutoCraftQueueAll:Show();
202 AutoCraftBuy:SetParent(TradeSkillFrame);
203 AutoCraftBuy:SetPoint("TOPLEFT", TradeSkillCancelButton, "TOPLEFT", 0, 0);
204 AutoCraftBuy:Show();
205 AutoCraftQueueEverything:SetParent(TradeSkillFrame);
206 AutoCraftQueueEverything:Show();
207 AutoCraftRunQueue:SetParent(TradeSkillFrame);
208 AutoCraftRunQueue:Show();
209 AutoCraftClear:SetParent(TradeSkillFrame);
210 AutoCraftClear:Show();
211 AutoCraftRunAutomatically:SetParent(TradeSkillFrame);
212 AutoCraftRunAutomatically:Show();
213 AutoCraftRunAutomaticallyText:SetText(FAC_RUN_AUTOMATICALLY_CHECKBUTTON);
214 AutoCraftRunAutomatically:SetChecked(FAC_Config.AutoIterate);
215  
216 -- Hide the old Create buttons so I can put my buttons in their place.
217 -- Not sure if this will always work, but it does at the moment.
218 TradeSkillCreateButton:Hide();
219 TradeSkillCreateAllButton:Hide();
220 TradeSkillCancelButton:Hide();
221  
222 -- we don't actually hook these anymore, but we keep the "aliases" around to be clearly readable when we're calling originals.
223 P.Orig_GetTradeSkillTools = GetTradeSkillTools;
224 P.Orig_GetTradeSkillReagentInfo = GetTradeSkillReagentInfo;
225 P.Orig_GetTradeSkillInfo = GetTradeSkillInfo;
226  
227 -- we do hook these, however.
228 P.Orig_TradeSkillFrame_SetSelection = TradeSkillFrame_SetSelection;
229 TradeSkillFrame_SetSelection = P.TradeSkillFrame_SetSelection;
230 P.Orig_TradeSkillFrame_Update = TradeSkillFrame_Update;
231 TradeSkillFrame_Update = P.TradeSkillFrame_Update;
232  
233 P.Loaded = true;
234 GFWUtils.Print("Fizzwidget AutoCraft "..FAC_VERSION.." initialized!");
235 end
236 end
237  
238 function P.NumOfItemInQueue(itemName)
239 for _, queueEntry in P.OrderedQueue do
240 if (queueEntry.item == itemName) then
241 local numPerCraft = (queueEntry.numPerCraft or 0);
242 local numQueued = (queueEntry.numQueued or 0);
243 if (numPerCraft > 1) then
244 return numQueued * numPerCraft;
245 else
246 return numQueued;
247 end
248 end
249 end
250 return 0;
251 end
252  
253 function P.OnUpdate(elapsed)
254 if (P.NoOverride and P.Loaded and TradeSkillFrame and TradeSkillFrame:IsVisible()) then
255 local skillName = GetTradeSkillLine();
256 if (P.TradeSkillsSeen[skillName] and (GetTime() - P.TradeSkillsSeen[skillName] > TRADESKILL_UPDATE_TIME)) then
257 P.NoOverride = false;
258 --GFWUtils.Print("Enabling TradeSkillFrame overrides.");
259 TradeSkillFrame_SetSelection(GetTradeSkillSelectionIndex());
260 TradeSkillFrame_Update();
261 end
262 end
263 if (not CastingBarFrame:IsVisible()) then
264 P.CastingOtherSpell = false;
265 P.CraftingQueuedItem = false;
266 end
267 if (P.AdvanceQueueTime ~= nil and GetTime() >= P.AdvanceQueueTime) then
268 P.Iterate();
269 P.AdvanceQueueTime = nil;
270 end
271 end
272  
273 function P.OnLoad()
274 -- we do most of our loading once the TradeSkillFrame loads (which is on-demand now).
275  
276 this:RegisterEvent("ADDON_LOADED");
277 this:RegisterEvent("CHAT_MSG_SPELL_TRADESKILLS");
278 this:RegisterEvent("MERCHANT_SHOW");
279 this:RegisterEvent("MERCHANT_CLOSED");
280 this:RegisterEvent("TRADE_SKILL_SHOW");
281 this:RegisterEvent("TRADE_SKILL_CLOSE");
282 this:RegisterEvent("TRADE_SKILL_UPDATE");
283 this:RegisterEvent("SPELLCAST_INTERRUPTED");
284 this:RegisterEvent("SPELLCAST_FAILED");
285 this:RegisterEvent("SPELLCAST_START");
286 this:RegisterEvent("SPELLCAST_STOP");
287  
288 if ( IsAddOnLoaded("Blizzard_TradeSkillUI") ) then
289 -- P.Load();
290 end
291  
292 end
293  
294 function P.OnEvent(event, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
295  
296 if (event == "ADDON_LOADED" and (arg1 == "Blizzard_TradeSkillUI" or IsAddOnLoaded("Blizzard_TradeSkillUI"))) then
297 P.Load();
298 end
299 if (not P.Loaded) then
300 -- all the other events we care about only have relevance once we're fully in action and attached to the TradeSkill UI
301 return;
302 end
303  
304 --DevTools_Dump({event=event, arg1=arg1, arg2=arg2, arg3=arg3, arg4=arg4, arg5=arg5, arg6=arg6, arg7=arg7, arg8=arg8, arg9=arg9});
305 if (event == "CHAT_MSG_SPELL_TRADESKILLS") then
306 if (FAC_CreateItemPattern == nil) then
307 FAC_CreateItemPattern = GFWUtils.FormatToPattern(TRADESKILL_LOG_FIRSTPERSON);
308 end
309 for item in string.gfind(arg1, FAC_CreateItemPattern) do
310 P.HandleCreated(item);
311 return;
312 end
313 elseif (event == "TRADE_SKILL_CLOSE" or event == "MERCHANT_SHOW" or event == "MERCHANT_CLOSED") then
314 P.UpdateDisplay();
315 elseif (event == "TRADE_SKILL_SHOW") then
316 P.UpdateDisplay();
317 AutoCraftRunAutomaticallyText:SetText(FAC_RUN_AUTOMATICALLY_CHECKBUTTON);
318 AutoCraftRunAutomatically:SetChecked(FAC_Config.AutoIterate);
319 -- if we've just switched to the tradeskill window needed for the head of the queue, start iterating again
320 if (not P.ManuallyPaused and P.OrderedQueue[1] ~= nil and P.OrderedQueue[1].skill == GetTradeSkillLine()) then
321 P.Iterate();
322 end
323 elseif (event == "TRADE_SKILL_UPDATE") then
324 P.UpdateDisplay();
325 elseif (event == "SPELLCAST_FAILED" or event == "SPELLCAST_INTERRUPTED") then
326 P.CastingOtherSpell = false;
327 P.CraftingQueuedItem = false;
328 if (P.Unqueueing or P.CastingOtherSpell) then
329 P.Unqueueing = false;
330 P.Iterate();
331 return;
332 end
333 P.UpdateDisplay();
334 elseif (event == "SPELLCAST_STOP") then
335 if (P.CastingOtherSpell) then
336 P.CastingOtherSpell = false;
337 P.Iterate();
338 P.UpdateDisplay();
339 end
340 elseif (event == "SPELLCAST_START") then
341 if (P.OrderedQueue[1] and CastingBarText:GetText() == P.OrderedQueue[1].recipe) then
342 P.CraftingQueuedItem = true;
343 P.CastingOtherSpell = false;
344 else
345 P.CraftingQueuedItem = false;
346 P.CastingOtherSpell = true;
347 end
348 P.UpdateDisplay();
349 end
350 end
351  
352 function P.Queue_OnClick()
353 local id = tonumber(this:GetID());
354 if (P.OrderedQueue[id]) then
355 table.remove(P.OrderedQueue, id);
356 if (id == 1 and P.CraftingQueuedItem) then
357 P.Unqueueing = true;
358 SpellStopCasting();
359 end
360 TradeSkillFrame_SetSelection(GetTradeSkillSelectionIndex());
361 TradeSkillFrame_Update();
362 P.UpdateDisplay();
363 P.Queue_UpdateTooltip(id);
364 end
365 end
366  
367 function P.Queue_OnEvent()
368 P.Queue_UpdateTooltip(tonumber(this:GetID()));
369 end
370  
371 function P.Queue_UpdateTooltip(id)
372 local button = getglobal("QueuedSkillIcon"..id);
373 if (button:IsVisible()) then
374 GameTooltip:SetOwner(button, "ANCHOR_TOPLEFT");
375 if ( id == 1 and P.CraftingQueuedItem) then
376 GameTooltip:SetText(NORMAL_FONT_COLOR_CODE..FAC_CREATING..FONT_COLOR_CODE_CLOSE, 1.0, 1.0, 1.0);
377 else
378 GameTooltip:SetText(NORMAL_FONT_COLOR_CODE..FAC_QUEUED..FONT_COLOR_CODE_CLOSE, 1.0, 1.0, 1.0);
379 end
380 if (id == MAX_QUEUE_BUTTONS and table.getn(P.OrderedQueue) > MAX_QUEUE_BUTTONS) then
381 GameTooltip:AppendText(string.format(FAC_ADDITIONAL_ENTRIES, table.getn(P.OrderedQueue) - MAX_QUEUE_BUTTONS + 1));
382 for index = MAX_QUEUE_BUTTONS, table.getn(P.OrderedQueue) do
383 local num = P.OrderedQueue[index].numQueued - P.OrderedQueue[index].numProduced;
384 GameTooltip:AppendText("\n"..num .."x ".. P.OrderedQueue[index].item);
385 end
386 GameTooltip:AddLine(string.format(FAC_CLICK_TO_CANCEL_FORMAT, P.OrderedQueue[MAX_QUEUE_BUTTONS].item));
387 else
388 local num = P.OrderedQueue[id].numQueued - P.OrderedQueue[id].numProduced;
389 GameTooltip:AppendText(num .."x ".. P.OrderedQueue[id].item);
390 GameTooltip:AddLine(FAC_CLICK_TO_CANCEL);
391 end
392 GameTooltip:Show();
393 end
394 end
395  
396 function P.QueueEverything()
397 local numSkills = GetNumTradeSkills();
398 local startIndex, stopIndex, increment;
399 if (IsAltKeyDown()) then
400 startIndex = 1;
401 stopIndex = numSkills;
402 increment = 1;
403 else
404 startIndex = numSkills;
405 stopIndex = 1;
406 increment = -1;
407 end
408 for index = startIndex, stopIndex, increment do
409 local recipeName, _, numAvailable, _, itemName = P.GetTradeSkillInfo(index);
410 if (numAvailable > 0) then
411 P.AddToQueue(recipeName, itemName, index, numAvailable);
412 end
413 end
414 TradeSkillFrame_SetSelection(GetTradeSkillSelectionIndex());
415 TradeSkillFrame_Update();
416 if (table.getn(P.OrderedQueue) == 0) then
417 GFWUtils.Print(FAC_NOTHING_TO_QUEUE);
418 end
419 end
420  
421 -- TODO: option-click for "buy all" equivalent to "queue all"
422 function P.BuyReagents(amount)
423 local index = GetTradeSkillSelectionIndex();
424  
425 --if (IsAltKeyDown()) then
426 -- amount = TradeSkillFrame.numAvailable;
427 --end
428  
429 for reagentIndex = 1, GetTradeSkillNumReagents(index) do
430 local reagentName, _, reagentCount, playerReagentCount = P.GetTradeSkillReagentInfo(index, reagentIndex);
431 local amountNeeded = (reagentCount * amount) - playerReagentCount;
432  
433 for merchantIndex = 1, GetMerchantNumItems() do
434 local name, _, price, numPerBuy, numAvailable, _ = GetMerchantItemInfo(merchantIndex);
435 if (name == reagentName) then
436 if (numAvailable >= 0 and (numAvailable * numPerBuy) < amountNeeded) then
437 amountNeeded = numAvailable * numPerBuy;
438 end
439 local amountToBuy = math.ceil(amountNeeded / numPerBuy);
440 if (amountToBuy > 0) then
441 if (numPerBuy > 1) then
442 GFWUtils.Print(string.format(FAC_BUYING_SETS_FORMAT, amountToBuy, name));
443 while (amountToBuy > 0 ) do
444 local amountBuyingNow = 1; -- dumb workaround for the API not telling us max stack size for things that come in multi-packs
445 BuyMerchantItem(merchantIndex, amountBuyingNow);
446 amountToBuy = amountToBuy - amountBuyingNow;
447 end
448 else
449 while (amountToBuy > 0 ) do
450 local maxPerBuy = GetMerchantItemMaxStack(merchantIndex);
451 local amountBuyingNow = math.min(amountToBuy, maxPerBuy);
452 GFWUtils.Print(string.format(FAC_BUYING_FORMAT, amountBuyingNow, name));
453 BuyMerchantItem(merchantIndex, amountBuyingNow);
454 amountToBuy = amountToBuy - amountBuyingNow;
455 end
456 end
457 elseif (numAvailable == 0) then
458 GFWUtils.Print(string.format(FAC_NOT_AVAILABLE_FORMAT, name));
459 else
460 GFWUtils.Print(string.format(FAC_ALREADY_ENOUGH_FORMAT, name, amount, P.GetTradeItemName(index)));
461 end
462 break;
463 end
464 end
465 end
466 end
467  
468 function P.Queue(amount)
469 local index = GetTradeSkillSelectionIndex();
470 local recipeName, _, numAvailable, _, itemName = P.GetTradeSkillInfo(index);
471  
472 if (amount > numAvailable) then amount = numAvailable; end
473  
474 if (amount > 0) then
475 P.AddToQueue(recipeName, itemName, index, amount);
476 end
477 TradeSkillFrame_SetSelection(GetTradeSkillSelectionIndex());
478 TradeSkillFrame_Update();
479 P.UpdateDisplay();
480 end
481  
482 function P.AddToQueue(recipeName, item, index, amount)
483  
484 local alreadyQueued = false;
485 GFWUtils.Print(FAC_QUEUEING .. GFWUtils.Hilite(amount .. " x ") .. GetTradeSkillItemLink(index));
486 for _, queueEntry in P.OrderedQueue do
487 if (item == queueEntry.item) then
488 queueEntry.numQueued = queueEntry.numQueued + amount;
489 alreadyQueued = true;
490 end
491 end
492 if (not alreadyQueued) then
493 local reagentsPerItem = {};
494 for reagentIndex = 1, GetTradeSkillNumReagents(index) do
495 local reagentName, _, reagentCount, _ = P.GetTradeSkillReagentInfo(index, reagentIndex);
496 reagentsPerItem[reagentName] = reagentCount;
497 end
498 local minMade, maxMade = GetTradeSkillNumMade(index);
499 local numPerCraft = math.min((minMade or 0), (maxMade or 0));
500 -- assume recipes that make a variable number of items will always produce the minimum, so we can't end up over-queueing.
501  
502 table.insert(P.OrderedQueue, {recipe=recipeName, item=item, numQueued=amount, numProduced=0, icon=GetTradeSkillIcon(index), skill=GetTradeSkillLine(), reagentsPerItem=reagentsPerItem, numPerCraft=numPerCraft});
503 end
504  
505 TradeSkillFrame_SetSelection(GetTradeSkillSelectionIndex());
506 TradeSkillFrame_Update();
507 P.UpdateDisplay();
508 if (FAC_Config.AutoIterate) then
509 P.ManuallyPaused = false;
510 P.Iterate();
511 else
512 P.ManuallyPaused = true;
513 end
514 P.UpdateDisplay();
515 end
516  
517 function P.UpdateDisplay()
518  
519 -- we clear these out in case relevant inventory has (actually or effectively) changed.
520 P.SkillCache = {};
521 P.ReagentCache = {};
522  
523 if (MerchantFrame:IsVisible()) then
524 AutoCraftBuy:Enable();
525 else
526 AutoCraftBuy:Disable();
527 end
528  
529 if (table.getn(P.OrderedQueue) > 0) then
530 if (P.CraftingQueuedItem) then
531 QueueMessageText:Hide();
532 QueueMessageText:SetText("");
533 AutoCraftRunQueue:SetText(FAC_PAUSE_QUEUE_BUTTON);
534 else
535 if (not P.ManuallyPaused and P.OrderedQueue[1] ~= nil and P.OrderedQueue[1].skill ~= GetTradeSkillLine()) then
536 QueueMessageText:SetText(FAC_QUEUE_PAUSED..": "..string.format(FAC_SWITCH_WINDOW_FORMAT, P.OrderedQueue[1].skill));
537 elseif (P.CastingOtherSpell) then
538 if (CastingBarText:GetText() ~= nil) then
539 QueueMessageText:SetText(FAC_QUEUE_PAUSED..": "..string.format(FAC_WAITING_SPELL_FORMAT, CastingBarText:GetText()));
540 end
541 else
542 QueueMessageText:SetText(FAC_QUEUE_PAUSED);
543 end
544 QueueMessageText:Show();
545 AutoCraftRunQueue:SetText(FAC_RUN_QUEUE_BUTTON);
546 end
547  
548 AutoCraftRunQueue:Enable();
549 AutoCraftClear:Enable();
550 else
551 QueueMessageText:Hide();
552 QueueMessageText:SetText("");
553 AutoCraftRunQueue:SetText(FAC_RUN_QUEUE_BUTTON);
554 AutoCraftRunQueue:Disable();
555 AutoCraftClear:Disable();
556 end
557  
558 for i = 1, MAX_QUEUE_BUTTONS do
559 button = getglobal("QueuedSkillIcon"..i);
560 currentItem = P.OrderedQueue[i];
561 if (currentItem == nil) then
562 button:Hide();
563 else
564 if (i == MAX_QUEUE_BUTTONS and table.getn(P.OrderedQueue) > MAX_QUEUE_BUTTONS) then
565 SetItemButtonTexture(button, "Interface\\Icons\\INV_Misc_QuestionMark");
566 SetItemButtonCount(button, (table.getn(P.OrderedQueue) - MAX_QUEUE_BUTTONS - 1));
567 else
568 SetItemButtonTexture(button, currentItem.icon);
569 SetItemButtonCount(button, (currentItem.numQueued - currentItem.numProduced));
570 end
571 button:Show();
572 end
573 end
574 end
575  
576 function P.StartStop()
577 if (P.CraftingQueuedItem == true) then
578 P.ManuallyPaused = true;
579 SpellStopCasting();
580 P.UpdateDisplay();
581 else
582 P.ManuallyPaused = false;
583 P.Iterate();
584 P.UpdateDisplay();
585 end
586 end
587  
588 function P.Clear()
589 if (table.getn(P.OrderedQueue) > 0) then
590 if (P.CraftingQueuedItem and not P.ManuallyPaused) then
591 SpellStopCasting();
592 end
593 P.OrderedQueue = {};
594 TradeSkillFrame_SetSelection(GetTradeSkillSelectionIndex());
595 TradeSkillFrame_Update();
596 P.UpdateDisplay();
597 end
598 end
599  
600 function P.Iterate()
601 if (P.CraftingQueuedItem or P.CastingOtherSpell) then return; end
602 if (table.getn(P.OrderedQueue) > 0) then
603 local index = P.GetTradeRecipeIndex(P.OrderedQueue[1].recipe);
604 if (index >= 0) then
605 if (P.OrderedQueue[1].skill == GetTradeSkillLine()) then
606 DoTradeSkill(index, (P.OrderedQueue[1].numQueued - P.OrderedQueue[1].numProduced));
607 P.UpdateDisplay();
608 return;
609 end
610 end
611 P.ManuallyPaused = false;
612 P.UpdateDisplay();
613 end
614 end
615  
616 function P.HandleCreated(item)
617 if (P.OrderedQueue[1] and item == P.OrderedQueue[1].item) then
618 P.OrderedQueue[1].numProduced = P.OrderedQueue[1].numProduced + 1;
619 if (P.OrderedQueue[1].numProduced >= P.OrderedQueue[1].numQueued) then
620 P.CraftingQueuedItem = false; -- this will get set back to true when we get the SPELLCAST_START event
621 table.remove(P.OrderedQueue, 1);
622 end
623 TradeSkillFrame_SetSelection(GetTradeSkillSelectionIndex());
624 TradeSkillFrame_Update();
625 P.UpdateDisplay();
626 --P.Iterate();
627 if (table.getn(P.OrderedQueue) > 0) then
628 P.AdvanceQueueTime = GetTime() + QUEUE_ADVANCE_DELAY;
629 end
630 end
631 end
632  
633 function P.GetTradeItemName(index)
634 local linktext = GetTradeSkillItemLink(index);
635 if (linktext) then
636 local _,_,item = string.find(linktext, "^.*%[(.*)%].*$");
637 return item;
638 else
639 local item, difficulty, amount = P.Orig_GetTradeSkillInfo(index);
640 return item;
641 end
642 end
643  
644 -- find the trade skill index based on the skill name (recipe name), as indices are subject to change.
645 function P.GetTradeRecipeIndex(recipeName)
646 local numSkills = GetNumTradeSkills();
647 for index = 1, numSkills do
648 local skillName = P.Orig_GetTradeSkillInfo(index);
649 if (skillName == recipeName) then
650 return index;
651 end
652 end
653 return -1;
654 end