comparison ReagentMaker.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 d60d6b4cab0c
children c79ab5443ee5
comparison
equal deleted inserted replaced
110:d60d6b4cab0c 111:af23986010ef
1 local addonName, A = ... 1 local addonName, A = ...
2 2
3 -- @todo clean the A table 3 -- @todo add support for cross tradeskill, like mining + forge/ingé
4 -- @todo check local copy of globals functions
5 -- @todo add support for dez ? 4 -- @todo add support for dez ?
6 -- @todo add support for hidden recipes, removing filtering => save the reagent count to be able to compute the number of craftable items 5 -- @todo scroll to the selected recipe on opening ?
7 -- @todo add support for cross tradeskill, like mining + forge/ingé 6 -- @todo add a button to clear search ?
8 -- @todo when a reagent can not be crafted and the recipe has many reagents, do like ReverseEngeneering and go to this recipe (with a one step return button) 7
9 -- @todo scroll to the selected recipe on opening (usefull also for the previous todo) 8 -- @bug Enter when choosing number of crafts
10 -- @todo shift+clic on a reagent name while the serachbar is focused fills the serachbar with the reagent name (idem with the crafted item)
11 -- @todo add a button to clear search
12 -- @todo add a button to cast a campfire when coocking
13 9
14 --------------------------------------------------- 10 ---------------------------------------------------
15 -- Variables 11 -- Variables
16 --------------------------------------------------- 12 ---------------------------------------------------
17 -- Used by findglobals 13 -- Used by findglobals
18 -- GLOBALS: _G, CreateFrame, DEFAULT_CHAT_FRAME 14 -- GLOBALS: _G, CreateFrame, DEFAULT_CHAT_FRAME, UIParent
19 15
20 -- Lua functions 16 -- Lua functions
21 17
22 -- Wow functions 18 -- Wow functions
19 local GetTradeSkillLine = GetTradeSkillLine
20 local IsTradeSkillGuild = IsTradeSkillGuild
21 local IsTradeSkillLinked = IsTradeSkillLinked
22 local GetTradeSkillSelectionIndex = GetTradeSkillSelectionIndex
23 local GetTradeSkillNumReagents = GetTradeSkillNumReagents
24 local GetTradeSkillReagentItemLink = GetTradeSkillReagentItemLink
23 25
24 -- constant vars 26 -- constant vars
25 27 local GameTooltip = GameTooltip
26 --------------------------------------------------- 28
27 -- Manage events 29 ---------------------------------------------------
30 -- Manage events and throttling
28 --------------------------------------------------- 31 ---------------------------------------------------
29 A.EventsFrame = CreateFrame("Frame") 32 A.EventsFrame = CreateFrame("Frame")
30 33
31 local SCAN_DELAY = 0.2 34 local SCAN_DELAY = 0.2
32 local t_throttle = SCAN_DELAY 35 local t_throttle = SCAN_DELAY
61 self:SetScript("OnUpdate", throttleScan) 64 self:SetScript("OnUpdate", throttleScan)
62 A.ManageCampFireBtn() 65 A.ManageCampFireBtn()
63 66
64 elseif event == "PLAYER_REGEN_DISABLED" then 67 elseif event == "PLAYER_REGEN_DISABLED" then
65 A.HideCampFireBtn() 68 A.HideCampFireBtn()
69
66 elseif event == "PLAYER_REGEN_ENABLED" then 70 elseif event == "PLAYER_REGEN_ENABLED" then
67 A.ManageCampFireBtn() 71 A.ManageCampFireBtn()
68 72
69 elseif event == "TRADE_SKILL_SHOW" then 73 elseif event == "TRADE_SKILL_SHOW" then
70 A:Initialize() 74 A:Initialize()
71 A.EventsFrame:UnregisterEvent("TRADE_SKILL_SHOW") 75 A.EventsFrame:UnregisterEvent("TRADE_SKILL_SHOW")
72 end -- if 76 end -- if
73 end) -- function 77 end) -- function
78
79 --@todo Unregister events when not needed
74 A.EventsFrame:RegisterEvent("TRADE_SKILL_SHOW") 80 A.EventsFrame:RegisterEvent("TRADE_SKILL_SHOW")
75 A.EventsFrame:RegisterEvent("TRADE_SKILL_UPDATE") 81 A.EventsFrame:RegisterEvent("TRADE_SKILL_UPDATE")
76 A.EventsFrame:RegisterEvent("PLAYER_REGEN_ENABLED") 82 A.EventsFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
77 A.EventsFrame:RegisterEvent("PLAYER_REGEN_DISABLED") 83 A.EventsFrame:RegisterEvent("PLAYER_REGEN_DISABLED")
84
78 85
79 --------------------------------------------------- 86 ---------------------------------------------------
80 -- Initialize 87 -- Initialize
81 --------------------------------------------------- 88 ---------------------------------------------------
82 function A:Initialize() 89 function A:Initialize()
113 120
114 -- Button for enchanting directy on a scroll 121 -- Button for enchanting directy on a scroll
115 A.LoadEnchantOnScroll() 122 A.LoadEnchantOnScroll()
116 end -- function 123 end -- function
117 124
118 -- Function run after selecting a item in the tradeskill window 125 ---------------------------------------------------
119 function A.ProcessReagent(btn, ...) 126 -- Dynamic display
120 --SPELL_FAILED_REAGENTS = "Missing reagent: %s"; 127 ---------------------------------------------------
121 --ERR_SPELL_FAILED_REAGENTS_GENERIC = "Missing reagent"; 128 -- Button hovering (entered)
122 --ERR_INTERNAL_BAG_ERROR = "Internal Bag Error";
123 --SPELL_FAILED_ERROR = "Internal error";
124
125 -- Do not manage guild tradeskill
126 if IsTradeSkillGuild() or IsTradeSkillLinked() then return end
127
128 -- We want no modifiers, or shift to choose the number of reagent to craft
129 if IsModifierKeyDown() and not IsShiftKeyDown() then return end
130 local chooseNumberToCraft = IsShiftKeyDown()
131
132 -- Index of the reagent in the recipe, taken from the button name
133 local reagentRecipeIndex = A.buttonNumber(btn)
134
135 -- ID of the reagent we want to craft
136 local recipeIndex = GetTradeSkillSelectionIndex()
137 local reagentID = A.link2ID(GetTradeSkillReagentItemLink(recipeIndex, reagentRecipeIndex))
138
139 -- Continue only if the reagent is known
140 if not reagentID or not A.data[reagentID] then return end
141
142 -- If only one recipe is known for the reagent, use it
143 if #(A.data[reagentID]) == 1 and not A.data[reagentID][1].macro then
144 if A.data[reagentID][1].tradeskillName and A.data[reagentID][1].tradeskillName ~= GetTradeSkillLine() then
145 A.Error(A.L["The recipe to make this reagent is in another tradeskill. Currently ReagentMaker can not manage such a case, sorry."])
146 return
147 end
148
149 local reagentIndex = A.findSkillIndex(reagentID) -- finds only the first recipe that creates the reagent, should check recipe name too
150
151 -- Try to show the recipe by removing filters once if it was not found
152 if not reagentIndex then
153 A.SaveActiveFilters(A.data[reagentID][1].header)
154 reagentIndex = A.findSkillIndex(reagentID)
155 end
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 local numMakable = A.numMakable(reagentID)
163 if not numMakable then
164 A.Error(A.L["There was a problem while retrieving informations, please retry."])
165 A.RestoreActiveFilters()
166 return
167 end
168 if numMakable>0 then
169 A.craft(recipeIndex,reagentRecipeIndex,reagentIndex,numMakable,chooseNumberToCraft)
170 A.RestoreActiveFilters()
171 return
172 end
173
174 -- If we can make the item needed to make the reagent, open a window to make it
175 -- one step recursion, enables to mill to create an ink
176 if A.data[reagentID][1][1] and A.data[A.data[reagentID][1][1]] then
177 if A.externalCraftWindow(A.data[reagentID][1][1],reagentID) ~= false then
178 A.RestoreActiveFilters()
179 return
180 end
181 end
182
183 A.Error(A.L["You do not have enough reagents to craft [%s]"]:format(GetItemInfo(reagentID) or "item #"..reagentID))
184 A.RestoreActiveFilters()
185 return
186 else
187 A.externalCraftWindow(reagentID)
188 end -- if
189 --A.RestoreActiveFilters()
190 end -- function
191
192
193 ---------------------------------------------------
194 -- Craft items
195 ---------------------------------------------------
196 -- function used after choosing the number of reagent to craft
197 function A.SplitStack(owner,split)
198 DoTradeSkill(owner.ReagentMaker_reagentIndex,tonumber(split))
199 owner.ReagentMaker_reagentIndex = nil
200 end
201
202 -- Craft the reagent of an item, given it's position in the recipe
203 function A.craft(recipeIndex,reagentRecipeIndex,reagentIndex,numReagentMakable,chooseNumber)
204 -- Look at how many we need to make one item for the selected recipe
205 local numToMake = 1
206 local _, _, reagentCount, playerReagentCount = GetTradeSkillReagentInfo(recipeIndex, reagentRecipeIndex)
207 -- make enough reagents to craft one more item
208 numToMake = math.min(math.floor(playerReagentCount/reagentCount+1)*reagentCount-playerReagentCount,numReagentMakable)
209
210 -- take into account that some recipe craft more than one item
211 -- use the mean between min and max, but make at least one...
212 local minMade, maxMade = GetTradeSkillNumMade(reagentIndex)
213 numToMake = math.max(math.floor(2*numToMake/(maxMade+minMade)),1)
214
215 -- Choose number or craft directly
216 if chooseNumber then
217 -- the dialog window is linked to the reagent button
218 local btn = _G["TradeSkillReagent"..reagentRecipeIndex]
219
220 -- Store info to be able to run the function later
221 btn.ReagentMaker_reagentIndex = reagentIndex
222
223 -- Open dialog
224 OpenStackSplitFrame(numReagentMakable, btn, "TOP", "BOTTOM")
225
226 -- Fill in the number to make
227 numToMake = tostring(numToMake)
228 for i = 1,numToMake:len() do
229 StackSplitFrame_OnChar(StackSplitFrame,numToMake:gsub(i,i))
230 end
231 StackSplitFrame.typing = 0 -- reinit the frame so that the entered value will be erased on text entry
232 else
233 DoTradeSkill(reagentIndex,numToMake)
234 end -- if
235 end -- function
236
237
238 -- Button hovering
239 function A.btnEntered(btn) 129 function A.btnEntered(btn)
240 -- Do not manage guild tradeskill 130 -- Do not manage guild tradeskill
241 if IsTradeSkillGuild() or IsTradeSkillLinked() then return end 131 if IsTradeSkillGuild() or IsTradeSkillLinked() then return end
242 132
243 -- Index of the reagent in the recipe, taken from the button name 133 -- Index of the reagent in the recipe, taken from the button name
244 local reagentRecipeIndex = A.buttonNumber(btn) 134 local reagentIndexInRecipe = A.buttonNumber(btn)
245 135
246 -- ID of the reagent we want to craft 136 -- ID of the reagent we want to craft
247 local reagentLink = GetTradeSkillReagentItemLink(GetTradeSkillSelectionIndex(), reagentRecipeIndex) 137 local reagentLink = GetTradeSkillReagentItemLink(GetTradeSkillSelectionIndex(), reagentIndexInRecipe)
248 local reagentID = A.link2ID(reagentLink) 138 local reagentID = A.link2ID(reagentLink)
249 139
250 -- Continue only if the reagent is known 140 -- Continue only if the reagent is known
251 if not reagentID or not A.data[reagentID] then return end 141 if not reagentID or not A.data[reagentID] then return end
252 142
264 A.tooltipRecipe:ClearAllPoints() 154 A.tooltipRecipe:ClearAllPoints()
265 A.tooltipRecipe:SetPoint("BOTTOMLEFT",GameTooltip,"BOTTOMRIGHT") 155 A.tooltipRecipe:SetPoint("BOTTOMLEFT",GameTooltip,"BOTTOMRIGHT")
266 end 156 end
267 end 157 end
268 158
159 -- Button hovering (left)
269 function A.btnLeft(btn) 160 function A.btnLeft(btn)
270 btn.textureHighlight:Hide() 161 btn.textureHighlight:Hide()
271 A.tooltipRecipe:Hide() 162 A.tooltipRecipe:Hide()
272 end -- function 163 end -- function
273 164
165 -- Show counts on buttons
274 function A.updateCounts(recipeIndex) 166 function A.updateCounts(recipeIndex)
275 -- Needs an argument 167 -- Needs an argument
276 if not recipeIndex then return end 168 if not recipeIndex then return end
277 169
278 -- Do not manage guild tradeskill 170 -- Do not manage guild tradeskill
279 if IsTradeSkillGuild() or IsTradeSkillLinked() then 171 if IsTradeSkillGuild() or IsTradeSkillLinked() then
280 for reagentRecipeIndex = 1,GetTradeSkillNumReagents(recipeIndex) do 172 for reagentIndexInRecipe = 1,GetTradeSkillNumReagents(recipeIndex) do
281 -- If the normal tradeskill hasn't been opened yet, the field 'label' doesn't exists yet 173 -- If the normal tradeskill hasn't been opened yet, the field 'label' doesn't exists yet
282 local label = _G["TradeSkillReagent"..reagentRecipeIndex].label 174 local label = _G["TradeSkillReagent"..reagentIndexInRecipe].label
283 if label then 175 if label then
284 label:Hide() 176 label:Hide()
285 end 177 end
286 end 178 end
287 return 179 return
288 end 180 end
289 181
290 -- Count makable items and show it 182 -- Count makable items and show it
291 for reagentRecipeIndex = 1,GetTradeSkillNumReagents(recipeIndex) do 183 for reagentIndexInRecipe = 1,GetTradeSkillNumReagents(recipeIndex) do
292 -- ID of the reagent we want to craft 184 -- ID of the reagent we want to craft
293 local reagentLink = GetTradeSkillReagentItemLink(recipeIndex, reagentRecipeIndex) 185 local reagentID = A.link2ID(GetTradeSkillReagentItemLink(recipeIndex, reagentIndexInRecipe))
294 local reagentID = A.link2ID(reagentLink) 186
295 187 local label = _G["TradeSkillReagent"..reagentIndexInRecipe].label
296 local label = _G["TradeSkillReagent"..reagentRecipeIndex].label 188 if label then
297 if not label then break end -- Shouldn't happen... 189 -- Continue only if the reagent is known
298 190 if not reagentID or not A.data[reagentID] then
299 -- Continue only if the reagent is known 191 label:Hide()
300 if not reagentID or not A.data[reagentID] then
301 label:Hide()
302 else
303 -- Count and show
304 local numMakable = A.numMakable(reagentID)
305 --if not numMakable or #(A.data[reagentID]) ~= 1 or A.data[reagentID][1].macro then
306 if not numMakable then
307 label:SetText("?")
308 label:SetTextColor(0, 0.5, 1, 1) -- blue
309 else 192 else
310 label:SetText(numMakable) 193 -- Count and show
311 if numMakable==0 then 194 local numMakable = A.numMakable(reagentID)
312 label:SetTextColor(1, 0, 0, 1) -- red 195 if not numMakable then
196 label:SetText("?")
197 label:SetTextColor(0, 0.5, 1, 1) -- blue
313 else 198 else
314 label:SetTextColor(0, 1, 0, 1) -- green 199 label:SetText(numMakable)
315 end 200 if numMakable==0 then
201 label:SetTextColor(1, 0, 0, 1) -- red
202 else
203 label:SetTextColor(0, 1, 0, 1) -- green
204 end
205 end -- if
206 label:Show()
316 end -- if 207 end -- if
317 label:Show()
318 end -- if 208 end -- if
319 end -- for 209 end -- for
320 end -- function 210 end -- function
321 hooksecurefunc("SelectTradeSkill",A.updateCounts) 211 hooksecurefunc("SelectTradeSkill",A.updateCounts)