annotate ReagentMaker.lua @ 96:e3147b41ea9d v1.0beta9

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