vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 -- ============================================================================
2 -- TTCraftAddict.lua
3 --
4 -- Copyright (c) Matthew Johnson. All rights reserved.
5 --
6 -- This work may be freely adapted and distributed as long as this notice remains intact.
7 -- This work may NOT be (re)sold or included in any compilations that are (re)sold.
8 --
9 -- ============================================================================
10  
11 -- ============================================================================
12 -- Object definitions.
13 -- ============================================================================
14 TTCA_Item =
15 {
16 Name = nil,
17 Type = nil,
18 Level = nil,
19 Id = nil,
20 ReagentId = nil,
21 Texture = nil,
22 NumAvailable = nil,
23 NumRequired = nil,
24 New = function (self)
25 obj = {};
26 setmetatable(obj, self);
27 self.__index = self;
28 return obj;
29 end,
30 };
31  
32 -- ============================================================================
33 -- Global variables.
34 -- ============================================================================
35 local Pre_TTCA_TradeSkillFrame_SetSelection = nil;
36 local Pre_TTCA_CraftFrame_SetSelection = nil;
37  
38 -- The list of items in the build tree.
39 local vTTCA_BuildTree = nil;
40  
41 -- The list of raw materials needed to build the selected item.
42 local vTTCA_MaterialList = nil;
43  
44 -- The list of items need to be made to build the selected item.
45 local vTTCA_ConstructionList = nil;
46  
47 -- The list of tools needed to build the selected item.
48 local vTTCA_ToolList = nil;
49  
50 -- The currently active tab.
51 local vTTCA_ActiveTab = nil
52  
53 -- Flag to determine if we are currently building the tree.
54 local vfTTCA_BuildingTree = false;
55  
56 -- Flag to determine if we should watch for a bag update so we know when to
57 -- build the next item.
58 local vfTTCA_WatchForBagUpdate = false;
59  
60 -- ============================================================================
61 -- Global defines.
62 -- ============================================================================
63 TTCA_LISTITEMS_VISIBLE = 15;
64 TTCA_LISTITEM_HEIGHT = 22;
65 TTCA_LISTITEM_WIDTH = 300;
66 TTCA_LISTITEM_INDENT = 15;
67  
68 TTCA_TAB_BUILDTREE = 1;
69 TTCA_TAB_MATERIALS = 2;
70  
71 local TTCA_TypeColor =
72 {
73 ["optimal"] = { r = 1.00, g = 0.50, b = 0.25 },
74 ["medium"] = { r = 1.00, g = 1.00, b = 0.00 },
75 ["easy"] = { r = 0.25, g = 0.75, b = 0.25 },
76 ["trivial"] = { r = 0.50, g = 0.50, b = 0.50 },
77 ["reagent"] = { r = 0.50, g = 0.50, b = 0.50 },
78 ["selected"] = { r = 1.00, g = 1.00, b = 1.00 },
79 ["unavailable"] = { r = 1.00, g = 0.00, b = 0.00 },
80 ["header"] = { r = 0.30, g = 0.30, b = 1.00 },
81 };
82  
83 -- ============================================================================
84 -- OnLoad
85 --
86 -- Called when this addon is first loaded.
87 -- ============================================================================
88 function TTCA_OnLoad()
89  
90 -- Register events
91 this:RegisterEvent("BAG_UPDATE");
92 this:RegisterEvent("CRAFT_CLOSE");
93 this:RegisterEvent("CRAFT_SHOW");
94 this:RegisterEvent("CRAFT_UPDATE");
95 this:RegisterEvent("SPELLCAST_INTERRUPTED");
96 this:RegisterEvent("SPELLCAST_STOP");
97 this:RegisterEvent("TRADE_SKILL_CLOSE");
98 this:RegisterEvent("TRADE_SKILL_SHOW");
99 this:RegisterEvent("TRADE_SKILL_UPDATE");
100  
101 --TradeSkillFrame_LoadUI();
102  
103 -- Hook
104 Pre_TTCA_TradeSkillFrame_SetSelection = TradeSkillFrame_SetSelection;
105 TradeSkillFrame_SetSelection = TTCA_Override_TradeSkillFrame_OnSetSelection;
106  
107 Pre_TTCA_CraftFrame_SetSelection = CraftFrame_SetSelection;
108 CraftFrame_SetSelection = TTCA_Override_CraftFrame_OnSetSelection;
109  
110 end
111  
112 -- ============================================================================
113 -- OnEvent
114 --
115 -- Called to handle the events registered for this addon.
116 -- ============================================================================
117 function TTCA_OnEvent()
118  
119 if (vfTTCA_BuildingTree) then
120  
121 if ((vfTTCA_WatchForBagUpdate) and (event == "BAG_UPDATE")) then
122  
123 vfTTCA_WatchForBagUpdate = false;
124 TTCA_Update();
125 TTCA_BuildNextItem(vTTCA_ConstructionList);
126  
127 elseif (event == "SPELLCAST_INTERRUPTED") then
128  
129 -- Building was interrupted, reset the building flag.
130 vfTTCA_BuildingTree = false;
131 vfTTCA_WatchForBagUpdate = false;
132  
133 elseif (event == "SPELLCAST_STOP") then
134  
135 -- Finished building the current item, so build the next item in
136 -- the construction list when the current item appears in the
137 -- character's bag.
138 vfTTCA_WatchForBagUpdate = true;
139  
140 end
141  
142 end
143  
144 if ((event == "CRAFT_CLOSE") or (event == "TRADE_SKILL_CLOSE")) then
145 TTCA_OnTradeSkillClose();
146  
147 elseif ((event == "CRAFT_SHOW") or (event == "TRADE_SKILL_SHOW")) then
148 TTCA_OnTradeSkillShow();
149  
150 elseif ((event == "CRAFT_UPDATE") or (event == "TRADE_SKILL_UPDATE")) then
151 TTCA_OnTradeSkillUpdate();
152  
153 end
154  
155 end
156  
157 -- ============================================================================
158 -- Override_TradeSkillFrame_OnSetSelection
159 --
160 -- This event occurs every time a selection is set within the built in craft
161 -- skill window. This function is hooked into the built in function so that
162 -- this addon can catch the selection change events.
163 -- ============================================================================
164 function TTCA_Override_CraftFrame_OnSetSelection(id)
165  
166 Pre_TTCA_CraftFrame_SetSelection(id);
167  
168 end
169  
170 -- ============================================================================
171 -- Override_TradeSkillFrame_OnSetSelection
172 --
173 -- This event occurs every time a selection is set within the built in trade
174 -- skill window. This function is hooked into the built in function so that
175 -- this addon can catch the selection change events.
176 -- ============================================================================
177 function TTCA_Override_TradeSkillFrame_OnSetSelection(id)
178  
179 Pre_TTCA_TradeSkillFrame_SetSelection(id);
180  
181 -- If the id is the currently selected item, don't bother reseting stuff.
182 if ((vTTCA_BuildTree ~= nil) and (id ~= vTTCA_BuildTree[1].Id)) then
183  
184 -- Reset the build tree scroll frame.
185 TTCA_Reset();
186  
187 -- Reset the quantity.
188 TTCA_InputBox_Quantity:SetNumber(1);
189  
190 end
191  
192 -- The selection may have changed, so update the trade skill build tree.
193 TTCA_Update();
194  
195 end
196  
197 -- ============================================================================
198 -- OnTradeSkillClose
199 --
200 -- This event occurs when the user closes the built in trade skill window.
201 -- ============================================================================
202 function TTCA_OnTradeSkillClose()
203  
204 -- Hide the trade skill build tree.
205 TTCA_ShowBuildTree(false);
206  
207 -- Hide the trade skill show button.
208 HideUIPanel(TTCA_Button_ShowBuildTree);
209  
210 end
211  
212 -- ============================================================================
213 -- OnTradeSkillShow
214 --
215 -- This event occurs when the users opens the built in trade skill window.
216 -- ============================================================================
217 function TTCA_OnTradeSkillShow()
218  
219 -- Show the trade skill tree expand button.
220 TTCA_Button_ShowBuildTree:SetPoint("TOPLEFT", TTCA_GetTradeSkillOrCraftFrameName(), "TOPRIGHT", -37, -9);
221 ShowUIPanel(TTCA_Button_ShowBuildTree);
222  
223 -- Reset the selected build tree item.
224 TTCA_SetSelection(1);
225  
226 -- Reset the quantity.
227 TTCA_InputBox_Quantity:SetNumber(1);
228  
229 end
230  
231 -- ============================================================================
232 -- OnTradeSkillUpdate
233 --
234 -- This event occurs every time the built in trade skill window fires an update
235 -- event.
236 -- ============================================================================
237 function TTCA_OnTradeSkillUpdate()
238  
239 -- Update the build tree frame.
240 TTCA_Update();
241  
242 end
243  
244 -- ============================================================================
245 -- ShowBuildTree
246 --
247 -- Shows/Hides the trade skill build tree window.
248 -- ============================================================================
249 function TTCA_ShowBuildTree(show)
250  
251 -- If the active tab is not yet set, make it the first tab.
252 if (vTTCA_ActiveTab == nil) then
253  
254 vTTCA_ActiveTab = TTCA_TAB_BUILDTREE;
255 PanelTemplates_SelectTab(TTCA_Tab_BuildTree);
256  
257 end
258  
259 if (show) then
260  
261 -- Hide the expand button and show the skill tree frame.
262 HideUIPanel(TTCA_Button_ShowBuildTree);
263 ShowUIPanel(TTCA_MainFrame);
264 TTCA_MainFrame:SetPoint("TOPLEFT", TTCA_GetTradeSkillOrCraftFrameName(), "TOPRIGHT", -35, -13);
265 TTCA_Update();
266 PlaySound("igCharacterInfoOpen");
267  
268 else
269  
270 -- Hide the trade skill expand frame and show the expand button.
271 HideUIPanel(TTCA_MainFrame);
272 ShowUIPanel(TTCA_Button_ShowBuildTree);
273 PlaySound("igCharacterInfoClose");
274  
275 end
276  
277 end
278  
279 -- ============================================================================
280 -- Reset
281 --
282 -- Resets the scroll frame to its initial values.
283 -- ============================================================================
284 function TTCA_Reset()
285  
286 -- Reset the scroll frame.
287 FauxScrollFrame_SetOffset(TTCA_List_ScrollFrame, 0);
288 TTCA_List_ScrollFrameScrollBar:SetValue(0);
289  
290 -- Reset the buttons.
291 TTCA_Button_CreateTree:Disable();
292 TTCA_Button_CreateAllTree:Disable();
293  
294 end
295  
296 -- ============================================================================
297 -- Update
298 --
299 -- Calculate the build tree, required raw materials, tools, and a construction
300 -- list for the currently selected item.
301 -- ============================================================================
302 function TTCA_Update()
303  
304 -- If the build tree window isn't visible, don't bother updating.
305 if (not TTCA_MainFrame:IsVisible()) then
306 return;
307 end
308  
309 -- Create the build tree.
310 vTTCA_BuildTree = {};
311 TTCA_CreateBuildTree(TTCA_GetSkillSelectionIndex(), vTTCA_BuildTree, nil, TTCA_InputBox_Quantity:GetNumber());
312  
313 -- Compute raw material requirements and the construction list for the currently
314 -- selected item.
315 vTTCA_MaterialList, vTTCA_ConstructionList, vTTCA_ToolList = TTCA_CreateMaterialConstructionToolLists(vTTCA_BuildTree, TTCA_GetSelection());
316  
317 -- Disable the create tree button.
318 TTCA_Button_CreateTree:Disable();
319 TTCA_Button_CreateAllTree:Disable();
320  
321 -- Update the list of items with the build tree or the material summary,
322 -- depending on which tab is active.
323 if (vTTCA_ActiveTab == TTCA_TAB_BUILDTREE) then
324  
325 TTCA_UpdateBuildTree(vTTCA_BuildTree);
326  
327 if (TTCA_IsItemBuildable(vTTCA_BuildTree, TTCA_GetSelection()) and (vTTCA_BuildTree[TTCA_GetSelection()].Type ~= "reagent")) then
328  
329 TTCA_Button_CreateTree:Enable();
330 TTCA_Button_CreateAllTree:Enable();
331  
332 end
333  
334 elseif (vTTCA_ActiveTab == TTCA_TAB_MATERIALS) then
335  
336 TTCA_UpdateMaterials(vTTCA_MaterialList);
337  
338 end
339  
340 end
341  
342 -- ============================================================================
343 -- UpdateBuildTree
344 -- ============================================================================
345 function TTCA_UpdateBuildTree(buildTree)
346  
347 -- Find the total number of items in the build tree.
348 local cBuildTreeItems = getn(buildTree);
349  
350 -- Find the scroll offset for the faux scroll frame.
351 local iListItemOffset = FauxScrollFrame_GetOffset(TTCA_List_ScrollFrame);
352  
353 -- Update the scroll frame.
354 FauxScrollFrame_Update(TTCA_List_ScrollFrame, cBuildTreeItems, TTCA_LISTITEMS_VISIBLE, TTCA_LISTITEM_HEIGHT, nil, nil, nil, TTCA_ListItem_HighlightFrame, 300, 300);
355  
356 -- Hide the highlight frame until we know where it is appearing.
357 TTCA_ListItem_HighlightFrame:Hide();
358  
359 -- Loop through our visible list items and update each one.
360 for i=1, TTCA_LISTITEMS_VISIBLE, 1 do
361  
362 local listItem = getglobal("TTCA_ListItem" .. i);
363 local listItemIndent = getglobal("TTCA_ListItem" .. i .. "_Indent");
364 local listItemTexture = getglobal("TTCA_ListItem" .. i .. "_Texture");
365 local listItemTooltipTriggerFrame = getglobal("TTCA_ListItem" .. i .. "_TooltipTriggerFrame");
366  
367 local iBuildTreeIndex = i + iListItemOffset;
368  
369 if (iBuildTreeIndex <= cBuildTreeItems) then
370  
371 local buildTreeItem = buildTree[iBuildTreeIndex];
372  
373 if (buildTreeItem.Name ~= nil) then
374  
375 -- Indent the item by its level.
376 listItemIndent:SetWidth(TTCA_LISTITEM_INDENT * (buildTreeItem.Level-1) + 1);
377  
378 -- Set the texture.
379 listItemTexture:SetTexture(buildTreeItem.Texture);
380 listItemTexture:SetWidth(20);
381 listItemTexture:Show();
382  
383 -- Set the name, number required, and number available.
384 local itemText = buildTreeItem.Name .. " ";
385 local itemNumText = "(" .. buildTreeItem.NumAvailable .. "/" .. buildTreeItem.NumRequired .. ")";
386 local itemNumBuildableText = "";
387 local itemNumTextColor;
388  
389 -- If this item is not a reagent, compute how many we can build based on the num available.
390 if (buildTreeItem.Type ~= "reagent") then
391 itemNumBuildableText = " [" .. floor(buildTreeItem.NumAvailable / buildTreeItem.NumRequired) .. "]";
392 end
393  
394 -- If the number available is >= the number required, then color the text differently.
395 if (buildTreeItem.NumAvailable >= buildTreeItem.NumRequired) then
396 itemNumTextColor = HIGHLIGHT_FONT_COLOR_CODE;
397 else
398 itemNumTextColor = GRAY_FONT_COLOR_CODE;
399 end
400 listItem:SetText(itemText .. itemNumTextColor .. itemNumText .. itemNumBuildableText .. FONT_COLOR_CODE_CLOSE);
401  
402 -- Set the color of the text.
403 local listItemColor = TTCA_TypeColor[buildTreeItem.Type];
404 listItem:SetTextColor(listItemColor.r, listItemColor.g, listItemColor.b);
405  
406 -- Set the Id so we know which button gets selected on clicks.
407 listItem.Index = iBuildTreeIndex;
408  
409 -- Set some values on the texture so we can show tooltips for each item.
410 listItemTooltipTriggerFrame.Id = buildTreeItem.Id;
411 listItemTooltipTriggerFrame.ReagentId = buildTreeItem.ReagentId;
412 listItemTooltipTriggerFrame:Show();
413  
414 -- Set some values on the item so we can link it when shift-clicked.
415 listItem.Id = buildTreeItem.Id;
416 listItem.ReagentId = buildTreeItem.ReagentId;
417  
418 -- Update the highlight frame.
419 if (TTCA_GetSelection() == iBuildTreeIndex) then
420  
421 -- Set the selected item's text color.
422 local listItemTextColor = TTCA_TypeColor["selected"];
423 listItem:SetTextColor(listItemTextColor.r, listItemTextColor.g, listItemTextColor.b);
424  
425 -- Set the color and location of the highlight frame.
426 TTCA_ListItem_Highlight:SetVertexColor(listItemColor.r, listItemColor.g, listItemColor.b);
427 TTCA_ListItem_HighlightFrame:SetPoint("TOPLEFT", "TTCA_ListItem" .. i, "TOPLEFT", -3, 0);
428 TTCA_ListItem_HighlightFrame:Show();
429  
430 end
431  
432 -- Show the button.
433 listItem:Show();
434  
435 end
436  
437 else
438  
439 -- Hide the button since it is unused.
440 listItem:Hide();
441  
442 end
443  
444 end
445  
446 end
447  
448 -- ============================================================================
449 -- UpdateMaterials
450 -- ============================================================================
451 function TTCA_UpdateMaterials(materialList)
452  
453 -- Find the total number of items in the material list.
454 local cMaterialItems = getn(materialList);
455  
456 -- Find the scroll offset for the faux scroll frame.
457 local iListItemOffset = FauxScrollFrame_GetOffset(TTCA_List_ScrollFrame);
458  
459 -- Update the scroll frame.
460 FauxScrollFrame_Update(TTCA_List_ScrollFrame, cMaterialItems, TTCA_LISTITEMS_VISIBLE, TTCA_LISTITEM_HEIGHT, nil, nil, nil, TTCA_ListItem_HighlightFrame, 300, 300);
461  
462 -- Hide the highlight frame since it isn't used for this view.
463 TTCA_ListItem_HighlightFrame:Hide();
464  
465 -- Loop through our material list.
466 for i=1, TTCA_LISTITEMS_VISIBLE, 1 do
467  
468 local listItem = getglobal("TTCA_ListItem" .. i);
469 local listItemIndent = getglobal("TTCA_ListItem" .. i .. "_Indent");
470 local listItemTexture = getglobal("TTCA_ListItem" .. i .. "_Texture");
471 local listItemTooltipTriggerFrame = getglobal("TTCA_ListItem" .. i .. "_TooltipTriggerFrame");
472  
473 local iMaterialListIndex = i + iListItemOffset;
474  
475 if (iMaterialListIndex <= cMaterialItems) then
476  
477 local materialListItem = materialList[iMaterialListIndex];
478  
479 if (materialListItem.Name ~= nil) then
480  
481 -- Indent the item by its level.
482 listItemIndent:SetWidth(TTCA_LISTITEM_INDENT * (materialListItem.Level-1) + 1);
483  
484 -- Set the texture, if one exists.
485 if (materialListItem.Texture) then
486 listItemTexture:SetTexture(materialListItem.Texture);
487 listItemTexture:SetWidth(20);
488 listItemTexture:Show();
489 else
490 listItemTexture:SetWidth(1);
491 listItemTexture:Hide();
492 end
493  
494 -- Set the name.
495 local wzName = materialListItem.Name;
496  
497 -- Set the number required and available, if they exist.
498 if (materialListItem.NumAvailable and materialListItem.NumRequired) then
499 wzName = wzName .. " (" .. materialListItem.NumAvailable .. "/" .. materialListItem.NumRequired .. ")";
500 end
501  
502 -- Set the text on the list item.
503 listItem:SetText(wzName);
504  
505 -- Set the color of the text.
506 local listItemColor = TTCA_TypeColor["reagent"];
507  
508 -- If the number required and available exists, then color the item if we have enough.
509 if (materialListItem.NumAvailable and materialListItem.NumRequired) then
510  
511 if (materialListItem.NumAvailable >= materialListItem.NumRequired) then
512 listItemColor = TTCA_TypeColor["selected"];
513 end
514  
515 elseif (materialListItem.Type) then
516  
517 listItemColor = TTCA_TypeColor[materialListItem.Type];
518  
519 end
520  
521 listItem:SetTextColor(listItemColor.r, listItemColor.g, listItemColor.b);
522  
523 -- Set some values on the texture so we can show tooltips for each item. But if the
524 -- texture isn't set, don't bother doing this.
525 if (materialListItem.Texture) then
526  
527 listItemTooltipTriggerFrame.Id = materialListItem.Id;
528 listItemTooltipTriggerFrame.ReagentId = materialListItem.ReagentId;
529 listItemTooltipTriggerFrame:Show();
530  
531 else
532  
533 listItemTooltipTriggerFrame:Hide();
534  
535 end
536  
537 -- Set some values on the item so we can link it when shift-clicked.
538 listItem.Id = materialListItem.Id;
539 listItem.ReagentId = materialListItem.ReagentId;
540  
541 -- Show the button.
542 listItem:Show();
543  
544 end
545  
546 else
547  
548 -- Hide the button since it is unused.
549 listItem:Hide();
550  
551 end
552  
553 end
554  
555 end
556  
557 -- ============================================================================
558 -- GetSelection
559 --
560 -- Returns the item currently selected in the build tree tab.
561 -- ============================================================================
562 function TTCA_GetSelection()
563  
564 return TTCA_MainFrame.SelectionIndex;
565  
566 end
567  
568 -- ============================================================================
569 -- SetSelection
570 --
571 -- Makes the item at the given build tree index the currently selected item.
572 -- ============================================================================
573 function TTCA_SetSelection(index)
574  
575 TTCA_MainFrame.SelectionIndex = index;
576 TTCA_Update();
577  
578 end
579  
580 -- ============================================================================
581 -- FindTradeSkillIdByName
582 --
583 -- Iterates through all of the player's trade skills and returns the index of
584 -- the first trade skill that matches the given name. If no match is found
585 -- then nil is returned.
586 -- ============================================================================
587 function TTCA_FindTradeSkillIdByName(tradeSkillName)
588  
589 local cTradeSkills = TTCA_GetNumSkills();
590  
591 for i=1, cTradeSkills, 1 do
592  
593 local name = TTCA_GetSkillInfo(i);
594  
595 if (tradeSkillName == name) then
596 return i;
597 end
598  
599 end
600  
601 return nil;
602  
603 end
604  
605 -- ============================================================================
606 -- CreateMaterialConstructionToolLists
607 --
608 -- Generates a list of raw materials required in order to create the selected
609 -- item. If no item is selected, it creates a summary for the first item.
610 -- ============================================================================
611 function TTCA_CreateMaterialConstructionToolLists(buildTree, index)
612  
613 if ((index <= 0) or (index > getn(buildTree))) then
614 index = 1;
615 end
616  
617 local materialList = {};
618 local constructionList = {};
619 local toolList = {};
620 local finalizedMaterialList = {};
621  
622 TTCA_CreateMaterialConstructionToolListsSub(materialList, constructionList, toolList, buildTree, index, buildTree[index].NumRequired);
623  
624 -- Sort the material list alphabetically.
625 materialList = TTCA_Sort(materialList);
626  
627 -- Sort the tool list alphabetically.
628 toolList = TTCA_Sort(toolList);
629  
630 -- Construct the final version of the material list.
631 -- Format: selected item, tools, materials.
632  
633 -- Add the selected item as the first item in the material list.
634 local selectedItem = TTCA_Item:New();
635 selectedItem.Name = buildTree[index].Name;
636 selectedItem.Type = buildTree[index].Type;
637 selectedItem.Texture = buildTree[index].Texture;
638 selectedItem.Id = buildTree[index].Id;
639 selectedItem.ReagentId = buildTree[index].ReagentId;
640 selectedItem.Level = 1;
641 tinsert(finalizedMaterialList, selectedItem);
642  
643 -- Add the tools to the material list.
644 if (getn(toolList) > 0) then
645  
646 -- Add a tool header if there is at least one tool.
647 local toolHeaderItem = TTCA_Item:New();
648 toolHeaderItem.Name = TTCA_TEXT_REQUIREDTOOLS;
649 toolHeaderItem.Type = "header";
650 toolHeaderItem.Level = 2;
651 tinsert(finalizedMaterialList, toolHeaderItem);
652  
653 -- Now add the tools.
654 for i=1, getn(toolList), 1 do
655  
656 local toolItem = TTCA_Item:New()
657 toolItem.Name = toolList[i].Name;
658 toolItem.Type = toolList[i].Type;
659 toolItem.Level = 3;
660 tinsert(finalizedMaterialList, toolItem);
661  
662 end
663  
664 end
665  
666 -- Add the materials to the material list.
667 if (getn(materialList) > 0) then
668  
669 -- Add a material header if there is at least on material.
670 local materialHeaderItem = TTCA_Item:New();
671 materialHeaderItem.Name = TTCA_TEXT_REQUIREDMATERIALS;
672 materialHeaderItem.Type = "header";
673 materialHeaderItem.Level = 2;
674 tinsert(finalizedMaterialList, materialHeaderItem);
675  
676 -- Now add the materials.
677 for i=1, getn(materialList), 1 do
678  
679 local materialItem = materialList[i];
680 materialItem.Level = 3;
681 tinsert(finalizedMaterialList, materialItem);
682  
683 end
684  
685 end
686  
687 return finalizedMaterialList, constructionList, toolList;
688  
689 end
690  
691 -- ============================================================================
692 -- CreateMaterialConstructionToolListsSub
693 -- ============================================================================
694 function TTCA_CreateMaterialConstructionToolListsSub(materialList, constructionList, toolList, buildTree, index, iNumRequired)
695  
696 local currentItem = buildTree[index];
697  
698 -- If this item is a reagent, add it to the summary.
699 if (currentItem.Type == "reagent") then
700  
701 if (currentItem.Name == nil) then
702 return;
703 end
704  
705 -- Initialize this reagent information if it hasn't been in the summary
706 -- before.
707 if (materialList[currentItem.Name] == nil) then
708 materialList[currentItem.Name] = {};
709 materialList[currentItem.Name].NumRequired = 0;
710 end
711  
712 -- Add this reagent's information to the summary.
713 materialList[currentItem.Name].Name = currentItem.Name;
714 materialList[currentItem.Name].Type = currentItem.Type;
715 materialList[currentItem.Name].NumAvailable = currentItem.NumAvailable;
716 materialList[currentItem.Name].NumRequired = materialList[currentItem.Name].NumRequired + currentItem.NumRequired;
717 materialList[currentItem.Name].Texture = currentItem.Texture;
718 materialList[currentItem.Name].Id = currentItem.Id;
719 materialList[currentItem.Name].ReagentId = currentItem.ReagentId;
720  
721 else
722  
723 -- This is not a reagent, so add it to the construction list.
724 tinsert(constructionList, currentItem);
725  
726 -- Get the tools required for this item.
727 TTCA_AppendToolsToList(toolList, GetTradeSkillTools(currentItem.Id));
728  
729 -- This is not a reagent, so recurse over its reagents.
730 local cBuildItems = getn(buildTree);
731  
732 for i=index+1, cBuildItems, 1 do
733  
734 if (i <= cBuildItems) then
735  
736 if (currentItem.Level + 1 == buildTree[i].Level) then
737  
738 TTCA_CreateMaterialConstructionToolListsSub(materialList, constructionList, toolList, buildTree, i, iNumRequired);
739  
740 elseif (currentItem.Level == buildTree[i].Level) then
741  
742 return;
743  
744 end
745  
746 end
747  
748 end
749  
750 end
751  
752 end
753  
754 -- ============================================================================
755 -- AppendToolsToList
756 -- ============================================================================
757 function TTCA_AppendToolsToList(list, ...)
758  
759 if (not list) then
760 return;
761 end
762  
763 -- Loop over the tools and add each one to the tool list.
764 for i=1, arg.n, 2 do
765  
766 local toolDetails = {};
767  
768 if (arg[i+1] == 1) then
769 toolDetails.Type = "selected";
770 else
771 toolDetails.Type = "unavailable";
772 end
773  
774 toolDetails.Name = arg[i];
775 list[toolDetails.Name] = toolDetails;
776  
777 end
778  
779 end
780  
781 -- ============================================================================
782 -- CreateBuildTree
783 -- ============================================================================
784 function TTCA_CreateBuildTree(tradeSkillId, buildTree, level, numRequired)
785  
786 if ((tradeSkillId <= 0) or (buildTree == nil)) then
787 return nil;
788 end
789  
790 if (level == nil) then
791 level = 1;
792 end
793  
794 if (numRequired == nil) then
795 numRequired = 1;
796 end
797  
798 -- Create a new trade skill item.
799 local tradeSkillItem = TTCA_Item:New();
800 tradeSkillItem.Name, tradeSkillItem.Type, tradeSkillItem.NumAvailable = TTCA_GetSkillInfo(tradeSkillId);
801 tradeSkillItem.Level = level;
802 tradeSkillItem.Id = tradeSkillId;
803 tradeSkillItem.Texture = TTCA_GetSkillIcon(tradeSkillId);
804 tradeSkillItem.NumRequired = numRequired;
805  
806 -- Add this item to the trade skill tree.
807 tinsert(buildTree, tradeSkillItem);
808  
809 -- Create the reagent information for this trade skill.
810 local cReagents = TTCA_GetSkillNumReagents(tradeSkillId);
811  
812 for i=1, cReagents, 1 do
813  
814 -- Get the reagent name.
815 local reagentName = TTCA_GetSkillReagentInfo(tradeSkillId, i);
816  
817 -- Figure out if the reagent is craftable as a trade skill item.
818 local iReagentTradeSkillId = TTCA_FindTradeSkillIdByName(reagentName);
819  
820 if (not (iReagentTradeSkillId == nil)) then
821  
822 -- Figure out how many are required.
823 local name, texture, reagentNumRequired = TTCA_GetSkillReagentInfo(tradeSkillId, i);
824  
825 -- The reagent is a craftable item, so create a trade skill item for it.
826 local tradeSkillReagentItem = TTCA_CreateBuildTree(iReagentTradeSkillId, buildTree, level + 1, reagentNumRequired * tradeSkillItem.NumRequired);
827  
828 -- Initialize some other reagent information.
829 tradeSkillReagentItem.Name, tradeSkillReagentItem.Texture, tradeSkillReagentItem.NumRequired, tradeSkillReagentItem.NumAvailable = TTCA_GetSkillReagentInfo(tradeSkillId, i);
830  
831 -- Modify the number required by the quantity entered.
832 tradeSkillReagentItem.NumRequired = tradeSkillReagentItem.NumRequired * tradeSkillItem.NumRequired;
833  
834 else
835  
836 -- The reagent is not a craftable item, so get the reagent info for it.
837  
838 -- Create a new trade skill item for this reagent.
839 local tradeSkillReagentItem = TTCA_Item:New();
840 tradeSkillReagentItem.Name, tradeSkillReagentItem.Texture, tradeSkillReagentItem.NumRequired, tradeSkillReagentItem.NumAvailable = TTCA_GetSkillReagentInfo(tradeSkillId, i);
841 tradeSkillReagentItem.Level = level + 1;
842 tradeSkillReagentItem.Id = tradeSkillId;
843 tradeSkillReagentItem.ReagentId = i;
844 tradeSkillReagentItem.Type = "reagent";
845  
846 -- Sometimes NumAvailable can be nil. Not yet sure why or how, but let's add some code for when it does.
847 if (tradeSkillReagentItem.NumAvailable == nil) then
848  
849 DEFAULT_CHAT_FRAME:AddMessage("Congrats! You've encountered a bug that I'm trying to track down. Please go to www.wowinterface.com and send a message to twig314159 with the following information:");
850 DEFAULT_CHAT_FRAME:AddMessage("ItemName = " .. tradeSkillItem.Name);
851 DEFAULT_CHAT_FRAME:AddMessage("ReagentName = " .. tradeSkillReagentItem.Name);
852 DEFAULT_CHAT_FRAME:AddMessage("ReagentNumAvailable = " .. tradeSkillReagentItem.NumAvailable);
853  
854 -- Fix up NumAvailable if it does happen to be nil.
855 tradeSkillReagentItem.NumAvailable = 0;
856  
857 end
858  
859 -- Modify the number required by the quantity entered.
860 tradeSkillReagentItem.NumRequired = tradeSkillReagentItem.NumRequired * tradeSkillItem.NumRequired;
861  
862 -- Add this item to the trade skill tree.
863 tinsert(buildTree, tradeSkillReagentItem);
864  
865 end
866  
867 end
868  
869 return tradeSkillItem;
870  
871 end
872  
873 -- ============================================================================
874 -- ListItem_OnClick
875 -- ============================================================================
876 function TTCA_ListItem_OnClick(button)
877  
878 if (button == "LeftButton") then
879  
880 local fShift = IsShiftKeyDown();
881 local fAlt = IsAltKeyDown();
882  
883 -- If the user shift-clicked the item, insert a link to it.
884 if (fShift and not fAlt) then
885  
886 if (ChatFrameEditBox:IsVisible()) then
887 ChatFrameEditBox:Insert(TTCA_GetItemLink(this.Id, this.ReagentId));
888 end
889  
890 -- If the user alt-clicked the item, link the entire dependency tree.
891 -- If the build tree is active, then link all dependencies of the alt-clicked item.
892 -- If the materials tree is active, then link only the materials listed in that view.
893 elseif (fAlt and not fShift) then
894  
895 -- If the chat edit box is not visible, just bail so we don't waste time
896 -- iterating only to do nothing.
897 if (not ChatFrameEditBox:IsVisible()) then
898 return;
899 end
900  
901 -- The chat box is visible, so figure out who/what we're chatting with
902 -- so we can send each item as a seperate message and make sure it goes
903 -- to the right destination.
904 ChatEdit_ParseText(ChatFrameEditBox, 0);
905 local chatType = ChatFrameEditBox.chatType;
906 local chatLanguage = ChatFrameEditBox.language;
907 local chatTarget = nil;
908  
909 -- Set the chat target.
910 if (chatType == "WHISPER") then
911 chatTarget = ChatFrameEditBox.tellTarget;
912 elseif (chatType == "CHANNEL") then
913 chatTarget = ChatFrameEditBox.channelTarget;
914 end
915  
916 -- Link the dependency tree.
917 if (vTTCA_ActiveTab == TTCA_TAB_BUILDTREE) then
918  
919 local cBuildItems = getn(vTTCA_BuildTree);
920  
921 -- Loop through the build tree so we can link each item that this item depends on.
922 for i=this.Index, cBuildItems, 1 do
923  
924 local buildTreeItem = vTTCA_BuildTree[i];
925  
926 if (buildTreeItem ~= nil) then
927  
928 local text = "";
929  
930 -- Generate a nice little header first.
931 if (i == this.Index) then
932  
933 text = TTCA_TEXT_MATERIALSFOR .. TTCA_GetItemLink(buildTreeItem.Id, buildTreeItem.ReagentId);
934  
935 else
936  
937 -- If we arrive back at the same level we started, then we're done!
938 if (buildTreeItem.Level == vTTCA_BuildTree[this.Index].Level) then
939 return;
940 end
941  
942 -- Otherwise, ident the item and dump it to the chat window.
943 for n=vTTCA_BuildTree[this.Index].Level, buildTreeItem.Level, 1 do
944 text = text .. " ";
945 end
946  
947 text = text .. TTCA_GetItemLink(buildTreeItem.Id, buildTreeItem.ReagentId) .. " x" .. buildTreeItem.NumRequired;
948  
949 end
950  
951 if (text ~= nil) then
952  
953 -- Now send the text and add it to the chat history.
954 SendChatMessage(text, chatType, chatLanguage, chatTarget);
955 ChatFrameEditBox:AddHistoryLine(text);
956  
957 end
958  
959 end
960  
961 end
962  
963 -- Link all the raw materials.
964 elseif (vTTCA_ActiveTab == TTCA_TAB_MATERIALS) then
965  
966 -- Find the total number of materials.
967 local cMaterialItems = getn(vTTCA_MaterialList);
968  
969 -- Loop through the material list so we can link each one.
970 for i=1, cMaterialItems, 1 do
971  
972 local materialListItem = vTTCA_MaterialList[i];
973  
974 if (materialListItem.Name ~= nil) then
975  
976 local text = nil;
977  
978 -- Generate a nice little header first.
979 if (i == 1) then
980 text = TTCA_TEXT_MATERIALSFOR .. TTCA_GetItemLink(materialListItem.Id, materialListItem.ReagentId);
981 end
982  
983 -- We want to link only reagents (not headers, tools, etc).
984 if (materialListItem.Type == "reagent") then
985  
986 text = " " .. TTCA_GetItemLink(materialListItem.Id, materialListItem.ReagentId) .. " x" .. materialListItem.NumRequired;
987  
988 end
989  
990 if (text ~= nil) then
991  
992 -- Now send the text and add it to the chat history.
993 SendChatMessage(text, chatType, chatLanguage, chatTarget);
994 ChatFrameEditBox:AddHistoryLine(text);
995  
996 end
997  
998 end
999  
1000 end
1001  
1002 end
1003  
1004 -- Otherwise, just make the item the currently selected item.
1005 else
1006  
1007 if (vTTCA_ActiveTab == TTCA_TAB_BUILDTREE) then
1008  
1009 TTCA_SetSelection(this.Index);
1010 TTCA_Update();
1011  
1012 end
1013  
1014 end
1015  
1016 end
1017  
1018 end
1019  
1020 -- ============================================================================
1021 -- ListItem_OnEnter
1022 -- ============================================================================
1023 function TTCA_ListItem_OnEnter()
1024  
1025 if (this.Id) then
1026  
1027 GameTooltip:SetOwner(this, "ANCHOR_UPPERLEFT");
1028  
1029 if (TTCA_IsCraftFrameVisible()) then
1030 GameTooltip:SetCraftItem(this.Id, this.ReagentId);
1031 else
1032 GameTooltip:SetTradeSkillItem(this.Id, this.ReagentId);
1033 end
1034  
1035 end
1036  
1037 end
1038  
1039 -- ============================================================================
1040 -- ListItem_OnLeave
1041 -- ============================================================================
1042 function TTCA_ListItem_OnLeave()
1043  
1044 GameTooltip:Hide();
1045  
1046 end
1047  
1048 -- ============================================================================
1049 -- CreateTree_OnClick
1050 -- ============================================================================
1051 function TTCA_CreateTree_OnClick(createAll)
1052  
1053 -- Set the building tree flag.
1054 vfTTCA_BuildingTree = true;
1055  
1056 -- Set the flag that says we're trying to build as many as we can.
1057 vfTTCA_BuildingAll = createAll;
1058  
1059 TTCA_BuildNextItem(vTTCA_ConstructionList);
1060  
1061 end
1062  
1063 -- ============================================================================
1064 -- Tab_OnClick
1065 -- ============================================================================
1066 function TTCA_Tab_OnClick(activateTab)
1067  
1068 if (vTTCA_ActiveTab ~= activateTab) then
1069  
1070 -- Reset the scroll frame.
1071 TTCA_Reset();
1072  
1073 -- Deselect all of the tabs.
1074 PanelTemplates_DeselectTab(TTCA_Tab_BuildTree);
1075 PanelTemplates_DeselectTab(TTCA_Tab_Materials);
1076  
1077 -- Select the tab the user clicked.
1078 vTTCA_ActiveTab = activateTab;
1079 PanelTemplates_SelectTab(this);
1080  
1081 -- Update the frame list.
1082 TTCA_Update();
1083  
1084 end
1085  
1086 end
1087  
1088 -- ============================================================================
1089 -- IncrementQuantity_OnClick
1090 -- ============================================================================
1091 function TTCA_IncrementQuantity_OnClick(delta)
1092  
1093 local iNewNumber = TTCA_InputBox_Quantity:GetNumber() + delta;
1094  
1095 if ((iNewNumber > 0) and (iNewNumber < 100)) then
1096  
1097 TTCA_InputBox_Quantity:SetNumber(iNewNumber);
1098  
1099 -- Since the number has changed, we need to update our build tree.
1100 TTCA_Update();
1101  
1102 end
1103  
1104 end
1105  
1106 -- ============================================================================
1107 -- BuildNextItem
1108 -- ============================================================================
1109 function TTCA_BuildNextItem(constructionList)
1110  
1111 local cItems = getn(constructionList);
1112  
1113 -- Loop through each item in the list and build it if we have all the
1114 -- reagents available.
1115 for i=1, cItems, 1 do
1116  
1117 local currentItem = constructionList[i];
1118  
1119 local tradeSkillDetails = {};
1120 tradeSkillDetails.Name, tradeSkillDetails.Type, tradeSkillDetails.NumAvailable = TTCA_GetSkillInfo(currentItem.Id);
1121  
1122 if ((tradeSkillDetails.NumAvailable > 0) and (currentItem.NumAvailable <= currentItem.NumRequired) and (i==1)) then
1123  
1124 -- If we built the first item in the list and not building as many as
1125 -- we can, then we're done!
1126 if (not vfTTCA_BuildingAll) then
1127 vfTTCA_BuildingTree = false;
1128 end
1129  
1130 TTCA_DoSkill(currentItem.Id, 1);
1131  
1132 -- This means we built our intended target. So, decrement the quantity by 1.
1133 -- If it would be zero, then we really are done. If not, keep building.
1134 if (TTCA_InputBox_Quantity:GetNumber() - 1 > 0) then
1135  
1136 TTCA_IncrementQuantity_OnClick(-1);
1137 vfTTCA_BuildingTree = true;
1138  
1139 end
1140  
1141 return;
1142  
1143 elseif ((tradeSkillDetails.NumAvailable > 0) and (currentItem.NumAvailable < currentItem.NumRequired)) then
1144  
1145 TTCA_DoSkill(currentItem.Id, 1);
1146  
1147 return;
1148  
1149 end
1150  
1151 end
1152  
1153 -- If we made it here, then we went through the whole build list and found
1154 -- nothing to build, so stop trying.
1155 vfTTCA_BuildingTree = false;
1156 vfTTCA_BuildingAll = false;
1157  
1158 end
1159  
1160 -- ============================================================================
1161 -- IsItemBuildable
1162 -- ============================================================================
1163 function TTCA_IsItemBuildable(buildTree, index, iNumRequired)
1164  
1165 if (iNumRequired == nil) then
1166 iNumRequired = 1;
1167 end
1168  
1169 local currentItem = buildTree[index];
1170  
1171 if (currentItem == nil) then
1172 return false;
1173 end
1174  
1175 -- If this item is a reagent, report that it is buildable as long as we
1176 -- have enough.
1177 if (currentItem.Type == "reagent") then
1178  
1179 if (currentItem.NumAvailable >= currentItem.NumRequired) then
1180  
1181 return true;
1182  
1183 end
1184  
1185 else
1186  
1187 -- This item is not a regeant, so only report it is buildable if all of
1188 -- its children are buildable or we already have enough of them.
1189 local fIsBuildable = true;
1190  
1191 if (currentItem.NumAvailable >= currentItem.NumRequired) then
1192  
1193 return fIsBuildable;
1194  
1195 end
1196  
1197 local cBuildItems = getn(buildTree);
1198  
1199 for i=index+1, cBuildItems, 1 do
1200  
1201 if (i <= cBuildItems) then
1202  
1203 if (currentItem.Level + 1 == buildTree[i].Level) then
1204  
1205 if (not TTCA_IsItemBuildable(buildTree, i, currentItem.NumRequired)) then
1206  
1207 fIsBuildable = false;
1208  
1209 end
1210  
1211 elseif (currentItem.Level == buildTree[i].Level) then
1212  
1213 return fIsBuildable;
1214  
1215 end
1216  
1217 end
1218  
1219 end
1220  
1221 return fIsBuildable;
1222  
1223 end
1224  
1225 return false;
1226  
1227 end
1228  
1229 -- ============================================================================
1230 -- Sort
1231 -- ============================================================================
1232 function TTCA_Sort(dictionary)
1233  
1234 local sortedList = {};
1235  
1236 -- Convert out dictionary list into an array.
1237 for key, value in dictionary do
1238 tinsert(sortedList, value);
1239 end
1240  
1241 -- Sort the array by the .Name property.
1242 sort(sortedList, function(a, b) return a.Name < b.Name end);
1243  
1244 return sortedList;
1245  
1246 end
1247  
1248 -- ============================================================================
1249 -- LinkItem
1250 --
1251 -- Returns a link to the given item. This link can then be used in a chat box.
1252 -- ============================================================================
1253 function TTCA_GetItemLink(itemId, reagentId)
1254  
1255 if (itemId and reagentId == nil) then
1256 return TTCA_GetSkillItemLink(itemId);
1257 elseif (itemId and reagentId) then
1258 return TTCA_GetSkillReagentItemLink(itemId, reagentId);
1259 end
1260  
1261 return nil;
1262  
1263 end
1264  
1265 function TTCA_IsCraftFrameVisible()
1266  
1267 return (CraftFrame ~= nil and CraftFrame:IsVisible());
1268  
1269 end
1270  
1271 function TTCA_GetTradeSkillOrCraftFrameName()
1272  
1273 if (TradeSkillFrame ~= nil and TradeSkillFrame:IsVisible()) then
1274 return TradeSkillFrame:GetName();
1275 elseif (CraftFrame ~= nil and CraftFrame:IsVisible()) then
1276 return CraftFrame:GetName();
1277 else
1278 return nil;
1279 end
1280  
1281 end
1282  
1283 function TTCA_GetSkillSelectionIndex()
1284  
1285 if (TTCA_IsCraftFrameVisible()) then
1286 return GetCraftSelectionIndex();
1287 else
1288 return GetTradeSkillSelectionIndex();
1289 end
1290  
1291 end
1292  
1293 function TTCA_GetNumSkills()
1294  
1295 if (TTCA_IsCraftFrameVisible()) then
1296 return GetNumCrafts();
1297 else
1298 return GetNumTradeSkills();
1299 end
1300  
1301 end
1302  
1303 function TTCA_GetSkillInfo(i)
1304  
1305 local name, subName, type, numAvailable, isExpanded;
1306  
1307 if (TTCA_IsCraftFrameVisible()) then
1308 name, subName, type, numAvailable, isExpanded = GetCraftInfo(i);
1309 else
1310 name, type, numAvailable, isExpanded = GetTradeSkillInfo(i);
1311 end
1312  
1313 return name, type, numAvailable, isExpanded;
1314  
1315 end
1316  
1317 function TTCA_GetSkillIcon(i)
1318  
1319 if (TTCA_IsCraftFrameVisible()) then
1320 return GetCraftIcon(i);
1321 else
1322 return GetTradeSkillIcon(i);
1323 end
1324  
1325 end
1326  
1327 function TTCA_GetSkillNumReagents(i)
1328  
1329 if (TTCA_IsCraftFrameVisible()) then
1330 return GetCraftNumReagents(i);
1331 else
1332 return GetTradeSkillNumReagents(i);
1333 end
1334  
1335 end
1336  
1337 function TTCA_GetSkillReagentInfo(index, reagentIndex)
1338  
1339 if (TTCA_IsCraftFrameVisible()) then
1340 return GetCraftReagentInfo(index, reagentIndex);
1341 else
1342 return GetTradeSkillReagentInfo(index, reagentIndex);
1343 end
1344  
1345 end
1346  
1347 function TTCA_DoSkill(i, n)
1348  
1349 if (TTCA_IsCraftFrameVisible()) then
1350 return DoCraft(i);
1351 else
1352 return DoTradeSkill(i, n);
1353 end
1354  
1355 end
1356  
1357 function TTCA_GetSkillItemLink(itemId)
1358  
1359 if (TTCA_IsCraftFrameVisible()) then
1360 return GetCraftItemLink(itemId);
1361 else
1362 return GetTradeSkillItemLink(itemId);
1363 end
1364  
1365 end
1366  
1367 function TTCA_GetSkillReagentItemLink(itemId, reagentId)
1368  
1369 if (TTCA_IsCraftFrameVisible()) then
1370 return GetCraftReagentItemLink(itemId, reagentId);
1371 else
1372 return GetTradeSkillReagentItemLink(itemId, reagentId);
1373 end
1374  
1375 end
1376