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