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