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 --A.RestoreActiveFilters()
|
contrebasse@111
|
59 end -- function
|
contrebasse@111
|
60
|
contrebasse@111
|
61 -- Launch the procedure for a standard recipe
|
contrebasse@111
|
62 -- Can be called from the external window
|
contrebasse@111
|
63 function A.CraftItemWithRecipe(recipeIndex,reagentID,recipeData,reagentIndexInRecipe,chooseNumberToCraft,btn)
|
contrebasse@111
|
64 -- Check that it's the same tradeskill
|
contrebasse@111
|
65 if recipeData.tradeskillName ~= GetTradeSkillLine() then
|
contrebasse@111
|
66 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
|
67 return
|
contrebasse@111
|
68 end
|
contrebasse@111
|
69
|
contrebasse@111
|
70 -- Check how many times the recipe is makable
|
contrebasse@111
|
71 local numMakable = A.numRecipeMakable(recipeData[1],recipeData[2])
|
contrebasse@111
|
72 if not numMakable then
|
contrebasse@111
|
73 A.Error(SPELL_FAILED_ERROR)
|
contrebasse@111
|
74 return
|
contrebasse@111
|
75 end
|
contrebasse@111
|
76
|
contrebasse@111
|
77 if numMakable<=0 then
|
contrebasse@111
|
78 -- If not makable, try a one-step recursion
|
contrebasse@111
|
79 -- enables e.g. to mill to create an ink
|
contrebasse@111
|
80 -- need a unique reagent
|
contrebasse@111
|
81 if recipeData[1] and A.data[recipeData[1]] then
|
contrebasse@111
|
82 if A.externalCraftWindow(recipeData[1],reagentIndexInRecipe,reagentID) ~= false then
|
contrebasse@111
|
83 -- there was no problem opening the external window
|
contrebasse@111
|
84 return
|
contrebasse@111
|
85 end
|
contrebasse@111
|
86 end
|
contrebasse@111
|
87
|
contrebasse@111
|
88 -- There isn't enough reagents
|
contrebasse@111
|
89 --@todo include name of reagent if unique
|
contrebasse@111
|
90 A.Error(A.L["You do not have enough reagents to craft [%s]"]:format(GetItemInfo(reagentID) or "item #"..reagentID))
|
contrebasse@111
|
91 return
|
contrebasse@111
|
92 end
|
contrebasse@111
|
93
|
contrebasse@111
|
94 -- Optimal number of items to craft
|
contrebasse@111
|
95 local numToMake = A.numToMake(recipeIndex, reagentIndexInRecipe,numMakable, recipeData[3], recipeData[4])
|
contrebasse@111
|
96
|
contrebasse@111
|
97 -- Choose number or craft directly
|
contrebasse@111
|
98 if chooseNumberToCraft then
|
contrebasse@111
|
99 -- Store info to be able to run the function later
|
contrebasse@111
|
100 btn.ReagentMaker_reagentID = reagentID
|
contrebasse@111
|
101 btn.ReagentMaker_recipeData = recipeData
|
contrebasse@111
|
102
|
contrebasse@111
|
103 -- Open dialog
|
contrebasse@111
|
104 OpenStackSplitFrame(numMakable, btn, "TOP", "BOTTOM")
|
contrebasse@111
|
105
|
contrebasse@111
|
106 -- Fill in the number to make
|
contrebasse@111
|
107 numToMake = tostring(numToMake)
|
contrebasse@111
|
108 for i = 1,numToMake:len() do
|
contrebasse@111
|
109 StackSplitFrame_OnChar(StackSplitFrame,numToMake:gsub(i,i))
|
contrebasse@111
|
110 end
|
contrebasse@111
|
111 StackSplitFrame.typing = 0 -- reinit the frame so that the entered value will be erased on text entry
|
contrebasse@111
|
112 else
|
contrebasse@111
|
113 A.DoCraft(reagentID,recipeData,numToMake)
|
contrebasse@111
|
114 end -- if
|
contrebasse@111
|
115 end
|
contrebasse@111
|
116
|
contrebasse@111
|
117 -- Compute optimal number of items to craft
|
contrebasse@111
|
118 function A.numToMake(recipeIndex, reagentIndexInRecipe,numReagentMakable,minMade,maxMade)
|
contrebasse@111
|
119 -- Look at how many we need to make one item for the selected recipe
|
contrebasse@111
|
120 local numToMake = 1
|
contrebasse@111
|
121 local _, _, reagentCount, playerReagentCount = GetTradeSkillReagentInfo(recipeIndex, reagentIndexInRecipe)
|
contrebasse@111
|
122 -- make enough reagents to craft one more item
|
contrebasse@111
|
123 numToMake = min(floor(playerReagentCount/reagentCount+1)*reagentCount-playerReagentCount,numReagentMakable)
|
contrebasse@111
|
124
|
contrebasse@111
|
125 -- take into account that some recipe craft more than one item
|
contrebasse@111
|
126 -- use the mean between min and max, but make at least one...
|
contrebasse@111
|
127 if not minMade then
|
contrebasse@111
|
128 minMade = 1
|
contrebasse@111
|
129 elseif minMade<1 then
|
contrebasse@111
|
130 -- from the percentage, compute the mean number of crafts to make
|
contrebasse@111
|
131 minMade = 1/minMade
|
contrebasse@111
|
132 end
|
contrebasse@111
|
133 if not maxMade then
|
contrebasse@111
|
134 maxMade = minMade
|
contrebasse@111
|
135 end
|
contrebasse@111
|
136 numToMake = max(floor(2*numToMake/(maxMade+minMade)),1)
|
contrebasse@111
|
137 return numToMake
|
contrebasse@111
|
138 end
|
contrebasse@111
|
139
|
contrebasse@111
|
140 -- function used after choosing the number of reagent to craft
|
contrebasse@111
|
141 function A.SplitStack(owner,split)
|
contrebasse@111
|
142 A.DoCraft(owner.ReagentMaker_reagentID,owner.ReagentMaker_recipeData,split)
|
contrebasse@111
|
143 owner.ReagentMaker_reagentID = nil
|
contrebasse@111
|
144 owner.ReagentMaker_recipeData = nil
|
contrebasse@111
|
145 end
|
contrebasse@111
|
146
|
contrebasse@111
|
147 -- Find the recipe and do the crafting
|
contrebasse@111
|
148 function A.DoCraft(reagentID,recipeData,numToMake)
|
contrebasse@111
|
149 -- Remove filters
|
contrebasse@111
|
150 A.SaveActiveFilters(recipeData.header)
|
contrebasse@111
|
151
|
contrebasse@111
|
152 -- Find recipe index
|
contrebasse@111
|
153 local reagentIndex = A.findExactSkillIndex(reagentID,recipeData.spellLink) -- finds only the first recipe that creates the reagent, should check recipe name too
|
contrebasse@111
|
154
|
contrebasse@111
|
155 -- Error if not found
|
contrebasse@111
|
156 if not reagentIndex then
|
contrebasse@111
|
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."])
|
contrebasse@111
|
158 A.RestoreActiveFilters()
|
contrebasse@111
|
159 return
|
contrebasse@111
|
160 end
|
contrebasse@111
|
161
|
contrebasse@111
|
162 -- Craft the item, finally !
|
contrebasse@111
|
163 DoTradeSkill(reagentIndex,numToMake)
|
contrebasse@111
|
164
|
contrebasse@111
|
165 -- Restore Filters
|
contrebasse@111
|
166 A.RestoreActiveFilters()
|
contrebasse@111
|
167 end
|