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