comparison Craft.lua @ 111:af23986010ef v1.1beta0

Rewrote the main part to clarify things, should have removed some hidden nasty bugs.
author contrebasse
date Thu, 02 Jun 2011 23:07:23 +0200
parents
children 3854c682bb4a
comparison
equal deleted inserted replaced
110:d60d6b4cab0c 111:af23986010ef
1 local addonName, A = ...
2
3 -- GLOBALS: SPELL_FAILED_ERROR, OpenStackSplitFrame, StackSplitFrame_OnChar, StackSplitFrame
4
5 -- Lua functions
6 local tostring = tostring
7 local min = math.min
8 local max = math.max
9 local floor = math.floor
10
11 -- Wow functions
12 local IsTradeSkillGuild = IsTradeSkillGuild
13 local IsTradeSkillLinked = IsTradeSkillLinked
14 local IsModifierKeyDown = IsModifierKeyDown
15 local IsShiftKeyDown = IsShiftKeyDown
16 local GetTradeSkillSelectionIndex = GetTradeSkillSelectionIndex
17 local GetTradeSkillReagentItemLink = GetTradeSkillReagentItemLink
18 local GetTradeSkillReagentInfo = GetTradeSkillReagentInfo
19 local GetTradeSkillLine = GetTradeSkillLine
20 local GetItemInfo = GetItemInfo
21 local DoTradeSkill = DoTradeSkill
22
23 --SPELL_FAILED_REAGENTS = "Missing reagent: %s";
24 --ERR_SPELL_FAILED_REAGENTS_GENERIC = "Missing reagent";
25 --ERR_INTERNAL_BAG_ERROR = "Internal Bag Error";
26 --SPELL_FAILED_ERROR = "Internal error";
27
28 ---------------------------------------------------
29 -- Craft items
30 ---------------------------------------------------
31 -- Function run after selecting a item in the tradeskill window
32 -- It only "prefilters" the possibilities
33 function A.ProcessReagent(btn)
34 -- Do not manage guild or linked tradeskill
35 if IsTradeSkillGuild() or IsTradeSkillLinked() then return end
36
37 -- We want no modifiers, or shift to choose the number of reagent to craft
38 if IsModifierKeyDown() and not IsShiftKeyDown() then return end
39 local chooseNumberToCraft = IsShiftKeyDown()
40
41 -- Index of the reagent in the recipe, taken from the button name
42 local reagentIndexInRecipe = A.buttonNumber(btn)
43
44 -- ID of the reagent we want to craft
45 local recipeIndex = GetTradeSkillSelectionIndex()
46 local reagentID = A.link2ID(GetTradeSkillReagentItemLink(recipeIndex, reagentIndexInRecipe))
47
48 -- Continue only if the reagent is known
49 if not reagentID or not A.data[reagentID] then return end
50
51 -- If only one recipe is known for the reagent and it is an actual recipe, use it
52 if #(A.data[reagentID]) == 1 and not A.data[reagentID][1].macro then
53 A.CraftItemWithRecipe(recipeIndex,reagentID,A.data[reagentID][1],reagentIndexInRecipe,chooseNumberToCraft,btn)
54
55 else -- Many recipes are known for this item, or it is not a standard tradeskill display them all
56 A.externalCraftWindow(reagentID,reagentIndexInRecipe)
57 end -- if
58 --A.RestoreActiveFilters()
59 end -- function
60
61 -- Launch the procedure for a standard recipe
62 -- Can be called from the external window
63 function A.CraftItemWithRecipe(recipeIndex,reagentID,recipeData,reagentIndexInRecipe,chooseNumberToCraft,btn)
64 -- Check that it's the same tradeskill
65 if recipeData.tradeskillName ~= GetTradeSkillLine() then
66 A.Error(A.L["The recipe to make this reagent is in another tradeskill. Currently ReagentMaker can not manage such a case, sorry."])
67 return
68 end
69
70 -- Check how many times the recipe is makable
71 local numMakable = A.numRecipeMakable(recipeData[1],recipeData[2])
72 if not numMakable then
73 A.Error(SPELL_FAILED_ERROR)
74 return
75 end
76
77 if numMakable<=0 then
78 -- If not makable, try a one-step recursion
79 -- enables e.g. to mill to create an ink
80 -- need a unique reagent
81 if recipeData[1] and A.data[recipeData[1]] then
82 if A.externalCraftWindow(recipeData[1],reagentIndexInRecipe,reagentID) ~= false then
83 -- there was no problem opening the external window
84 return
85 end
86 end
87
88 -- There isn't enough reagents
89 --@todo include name of reagent if unique
90 A.Error(A.L["You do not have enough reagents to craft [%s]"]:format(GetItemInfo(reagentID) or "item #"..reagentID))
91 return
92 end
93
94 -- Optimal number of items to craft
95 local numToMake = A.numToMake(recipeIndex, reagentIndexInRecipe,numMakable, recipeData[3], recipeData[4])
96
97 -- Choose number or craft directly
98 if chooseNumberToCraft then
99 -- Store info to be able to run the function later
100 btn.ReagentMaker_reagentID = reagentID
101 btn.ReagentMaker_recipeData = recipeData
102
103 -- Open dialog
104 OpenStackSplitFrame(numMakable, btn, "TOP", "BOTTOM")
105
106 -- Fill in the number to make
107 numToMake = tostring(numToMake)
108 for i = 1,numToMake:len() do
109 StackSplitFrame_OnChar(StackSplitFrame,numToMake:gsub(i,i))
110 end
111 StackSplitFrame.typing = 0 -- reinit the frame so that the entered value will be erased on text entry
112 else
113 A.DoCraft(reagentID,recipeData,numToMake)
114 end -- if
115 end
116
117 -- Compute optimal number of items to craft
118 function A.numToMake(recipeIndex, reagentIndexInRecipe,numReagentMakable,minMade,maxMade)
119 -- Look at how many we need to make one item for the selected recipe
120 local numToMake = 1
121 local _, _, reagentCount, playerReagentCount = GetTradeSkillReagentInfo(recipeIndex, reagentIndexInRecipe)
122 -- make enough reagents to craft one more item
123 numToMake = min(floor(playerReagentCount/reagentCount+1)*reagentCount-playerReagentCount,numReagentMakable)
124
125 -- take into account that some recipe craft more than one item
126 -- use the mean between min and max, but make at least one...
127 if not minMade then
128 minMade = 1
129 elseif minMade<1 then
130 -- from the percentage, compute the mean number of crafts to make
131 minMade = 1/minMade
132 end
133 if not maxMade then
134 maxMade = minMade
135 end
136 numToMake = max(floor(2*numToMake/(maxMade+minMade)),1)
137 return numToMake
138 end
139
140 -- function used after choosing the number of reagent to craft
141 function A.SplitStack(owner,split)
142 A.DoCraft(owner.ReagentMaker_reagentID,owner.ReagentMaker_recipeData,split)
143 owner.ReagentMaker_reagentID = nil
144 owner.ReagentMaker_recipeData = nil
145 end
146
147 -- Find the recipe and do the crafting
148 function A.DoCraft(reagentID,recipeData,numToMake)
149 -- Remove filters
150 A.SaveActiveFilters(recipeData.header)
151
152 -- Find recipe index
153 local reagentIndex = A.findExactSkillIndex(reagentID,recipeData.spellLink) -- finds only the first recipe that creates the reagent, should check recipe name too
154
155 -- Error if not found
156 if not reagentIndex then
157 A.Error(A.L["The recipe to make the reagent seems to be hidden, it is not makable. Try to remove the filters on the recipes."])
158 A.RestoreActiveFilters()
159 return
160 end
161
162 -- Craft the item, finally !
163 DoTradeSkill(reagentIndex,numToMake)
164
165 -- Restore Filters
166 A.RestoreActiveFilters()
167 end