annotate ReagentMaker.lua @ 110:d60d6b4cab0c

Tradeskill in external window should now be functional
author contrebasse
date Thu, 02 Jun 2011 18:23:42 +0200
parents 618163a6d970
children af23986010ef
rev   line source
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@110 95 --textureHighlight:SetTexture("Interface\\BUTTONS\\ButtonHilight-Square")
contrebasse@98 96 textureHighlight:SetBlendMode("ADD")
contrebasse@98 97 textureHighlight:SetAllPoints("TradeSkillReagent"..i.."IconTexture")
contrebasse@98 98 btn.textureHighlight = textureHighlight
contrebasse@98 99
contrebasse@98 100 local label = btn:CreateFontString(nil,"ARTWORK","GameFontHighlight")
contrebasse@98 101 label:SetSize(100,20)
contrebasse@98 102 label:SetPoint("TOPLEFT",btn,"TOPLEFT",4,-4)
contrebasse@98 103 label:SetJustifyH("LEFT")
contrebasse@98 104 label:SetJustifyV("TOP")
contrebasse@98 105 label:SetFont("Fonts\\FRIZQT__.TTF", 10, "OUTLINE")
contrebasse@98 106 btn.label = label
contrebasse@98 107 end -- for
contrebasse@98 108
contrebasse@98 109 -- Secondary Tooltip
contrebasse@98 110 A.tooltipRecipe = CreateFrame("GameTooltip", "ReagentMaker_tooltipRecipe",UIParent, "GameTooltipTemplate")
contrebasse@98 111 A.tooltipRecipe:SetFrameStrata("TOOLTIP")
contrebasse@98 112 A.tooltipRecipe:Hide()
contrebasse@101 113
contrebasse@98 114 -- Button for enchanting directy on a scroll
contrebasse@98 115 A.LoadEnchantOnScroll()
contrebasse@98 116 end -- function
contrebasse@98 117
contrebasse@98 118 -- Function run after selecting a item in the tradeskill window
contrebasse@98 119 function A.ProcessReagent(btn, ...)
contrebasse@108 120 --SPELL_FAILED_REAGENTS = "Missing reagent: %s";
contrebasse@108 121 --ERR_SPELL_FAILED_REAGENTS_GENERIC = "Missing reagent";
contrebasse@108 122 --ERR_INTERNAL_BAG_ERROR = "Internal Bag Error";
contrebasse@108 123 --SPELL_FAILED_ERROR = "Internal error";
contrebasse@98 124
contrebasse@98 125 -- Do not manage guild tradeskill
contrebasse@98 126 if IsTradeSkillGuild() or IsTradeSkillLinked() then return end
contrebasse@98 127
contrebasse@98 128 -- We want no modifiers, or shift to choose the number of reagent to craft
contrebasse@98 129 if IsModifierKeyDown() and not IsShiftKeyDown() then return end
contrebasse@98 130 local chooseNumberToCraft = IsShiftKeyDown()
contrebasse@98 131
contrebasse@98 132 -- Index of the reagent in the recipe, taken from the button name
contrebasse@98 133 local reagentRecipeIndex = A.buttonNumber(btn)
contrebasse@98 134
contrebasse@98 135 -- ID of the reagent we want to craft
contrebasse@98 136 local recipeIndex = GetTradeSkillSelectionIndex()
contrebasse@98 137 local reagentID = A.link2ID(GetTradeSkillReagentItemLink(recipeIndex, reagentRecipeIndex))
contrebasse@98 138
contrebasse@98 139 -- Continue only if the reagent is known
contrebasse@98 140 if not reagentID or not A.data[reagentID] then return end
contrebasse@98 141
contrebasse@98 142 -- If only one recipe is known for the reagent, use it
contrebasse@98 143 if #(A.data[reagentID]) == 1 and not A.data[reagentID][1].macro then
contrebasse@110 144 if A.data[reagentID][1].tradeskillName and A.data[reagentID][1].tradeskillName ~= GetTradeSkillLine() then
contrebasse@98 145 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 146 return
contrebasse@98 147 end
contrebasse@98 148
contrebasse@108 149 local reagentIndex = A.findSkillIndex(reagentID) -- finds only the first recipe that creates the reagent, should check recipe name too
contrebasse@98 150
contrebasse@98 151 -- Try to show the recipe by removing filters once if it was not found
contrebasse@98 152 if not reagentIndex then
contrebasse@98 153 A.SaveActiveFilters(A.data[reagentID][1].header)
contrebasse@108 154 reagentIndex = A.findSkillIndex(reagentID)
contrebasse@108 155 end
contrebasse@108 156 if not reagentIndex then
contrebasse@108 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@108 158 A.RestoreActiveFilters()
contrebasse@108 159 return
contrebasse@98 160 end
contrebasse@98 161
contrebasse@108 162 local numMakable = A.numMakable(reagentID)
contrebasse@98 163 if not numMakable then
contrebasse@108 164 A.Error(A.L["There was a problem while retrieving informations, please retry."])
contrebasse@107 165 A.RestoreActiveFilters()
contrebasse@98 166 return
contrebasse@98 167 end
contrebasse@98 168 if numMakable>0 then
contrebasse@98 169 A.craft(recipeIndex,reagentRecipeIndex,reagentIndex,numMakable,chooseNumberToCraft)
contrebasse@107 170 A.RestoreActiveFilters()
contrebasse@98 171 return
contrebasse@98 172 end
contrebasse@98 173
contrebasse@98 174 -- If we can make the item needed to make the reagent, open a window to make it
contrebasse@98 175 -- one step recursion, enables to mill to create an ink
contrebasse@98 176 if A.data[reagentID][1][1] and A.data[A.data[reagentID][1][1]] then
contrebasse@98 177 if A.externalCraftWindow(A.data[reagentID][1][1],reagentID) ~= false then
contrebasse@107 178 A.RestoreActiveFilters()
contrebasse@98 179 return
contrebasse@98 180 end
contrebasse@98 181 end
contrebasse@98 182
contrebasse@98 183 A.Error(A.L["You do not have enough reagents to craft [%s]"]:format(GetItemInfo(reagentID) or "item #"..reagentID))
contrebasse@107 184 A.RestoreActiveFilters()
contrebasse@98 185 return
contrebasse@98 186 else
contrebasse@98 187 A.externalCraftWindow(reagentID)
contrebasse@98 188 end -- if
contrebasse@98 189 --A.RestoreActiveFilters()
contrebasse@98 190 end -- function
contrebasse@98 191
contrebasse@98 192
contrebasse@98 193 ---------------------------------------------------
contrebasse@98 194 -- Craft items
contrebasse@98 195 ---------------------------------------------------
contrebasse@98 196 -- function used after choosing the number of reagent to craft
contrebasse@98 197 function A.SplitStack(owner,split)
contrebasse@98 198 DoTradeSkill(owner.ReagentMaker_reagentIndex,tonumber(split))
contrebasse@98 199 owner.ReagentMaker_reagentIndex = nil
contrebasse@98 200 end
contrebasse@98 201
contrebasse@98 202 -- Craft the reagent of an item, given it's position in the recipe
contrebasse@98 203 function A.craft(recipeIndex,reagentRecipeIndex,reagentIndex,numReagentMakable,chooseNumber)
contrebasse@98 204 -- Look at how many we need to make one item for the selected recipe
contrebasse@98 205 local numToMake = 1
contrebasse@98 206 local _, _, reagentCount, playerReagentCount = GetTradeSkillReagentInfo(recipeIndex, reagentRecipeIndex)
contrebasse@98 207 -- make enough reagents to craft one more item
contrebasse@98 208 numToMake = math.min(math.floor(playerReagentCount/reagentCount+1)*reagentCount-playerReagentCount,numReagentMakable)
contrebasse@98 209
contrebasse@98 210 -- take into account that some recipe craft more than one item
contrebasse@98 211 -- use the mean between min and max, but make at least one...
contrebasse@98 212 local minMade, maxMade = GetTradeSkillNumMade(reagentIndex)
contrebasse@98 213 numToMake = math.max(math.floor(2*numToMake/(maxMade+minMade)),1)
contrebasse@101 214
contrebasse@98 215 -- Choose number or craft directly
contrebasse@98 216 if chooseNumber then
contrebasse@98 217 -- the dialog window is linked to the reagent button
contrebasse@98 218 local btn = _G["TradeSkillReagent"..reagentRecipeIndex]
contrebasse@98 219
contrebasse@98 220 -- Store info to be able to run the function later
contrebasse@98 221 btn.ReagentMaker_reagentIndex = reagentIndex
contrebasse@98 222
contrebasse@98 223 -- Open dialog
contrebasse@98 224 OpenStackSplitFrame(numReagentMakable, btn, "TOP", "BOTTOM")
contrebasse@98 225
contrebasse@98 226 -- Fill in the number to make
contrebasse@98 227 numToMake = tostring(numToMake)
contrebasse@98 228 for i = 1,numToMake:len() do
contrebasse@98 229 StackSplitFrame_OnChar(StackSplitFrame,numToMake:gsub(i,i))
contrebasse@98 230 end
contrebasse@110 231 StackSplitFrame.typing = 0 -- reinit the frame so that the entered value will be erased on text entry
contrebasse@98 232 else
contrebasse@98 233 DoTradeSkill(reagentIndex,numToMake)
contrebasse@98 234 end -- if
contrebasse@98 235 end -- function
contrebasse@98 236
contrebasse@98 237
contrebasse@98 238 -- Button hovering
contrebasse@98 239 function A.btnEntered(btn)
contrebasse@98 240 -- Do not manage guild tradeskill
contrebasse@98 241 if IsTradeSkillGuild() or IsTradeSkillLinked() then return end
contrebasse@98 242
contrebasse@98 243 -- Index of the reagent in the recipe, taken from the button name
contrebasse@98 244 local reagentRecipeIndex = A.buttonNumber(btn)
contrebasse@98 245
contrebasse@98 246 -- ID of the reagent we want to craft
contrebasse@98 247 local reagentLink = GetTradeSkillReagentItemLink(GetTradeSkillSelectionIndex(), reagentRecipeIndex)
contrebasse@98 248 local reagentID = A.link2ID(reagentLink)
contrebasse@98 249
contrebasse@98 250 -- Continue only if the reagent is known
contrebasse@98 251 if not reagentID or not A.data[reagentID] then return end
contrebasse@98 252
contrebasse@98 253 btn.textureHighlight:Show()
contrebasse@98 254
contrebasse@98 255 -- Check if the item is made by only one recipe. If not, return
contrebasse@98 256 if not A.isRecipeUnique(A.data[reagentID]) then return end
contrebasse@98 257
contrebasse@98 258 -- Tooltips
contrebasse@98 259 local link = A.data[reagentID][1].spellLink
contrebasse@98 260 if link then
contrebasse@98 261 A.tooltipRecipe:SetOwner(btn)
contrebasse@98 262 A.tooltipRecipe:SetHyperlink(link)
contrebasse@98 263 A.tooltipRecipe:Show()
contrebasse@98 264 A.tooltipRecipe:ClearAllPoints()
contrebasse@98 265 A.tooltipRecipe:SetPoint("BOTTOMLEFT",GameTooltip,"BOTTOMRIGHT")
contrebasse@98 266 end
contrebasse@98 267 end
contrebasse@98 268
contrebasse@98 269 function A.btnLeft(btn)
contrebasse@98 270 btn.textureHighlight:Hide()
contrebasse@98 271 A.tooltipRecipe:Hide()
contrebasse@98 272 end -- function
contrebasse@98 273
contrebasse@98 274 function A.updateCounts(recipeIndex)
contrebasse@98 275 -- Needs an argument
contrebasse@98 276 if not recipeIndex then return end
contrebasse@98 277
contrebasse@98 278 -- Do not manage guild tradeskill
contrebasse@98 279 if IsTradeSkillGuild() or IsTradeSkillLinked() then
contrebasse@98 280 for reagentRecipeIndex = 1,GetTradeSkillNumReagents(recipeIndex) do
contrebasse@98 281 -- If the normal tradeskill hasn't been opened yet, the field 'label' doesn't exists yet
contrebasse@98 282 local label = _G["TradeSkillReagent"..reagentRecipeIndex].label
contrebasse@98 283 if label then
contrebasse@98 284 label:Hide()
contrebasse@98 285 end
contrebasse@98 286 end
contrebasse@98 287 return
contrebasse@98 288 end
contrebasse@98 289
contrebasse@98 290 -- Count makable items and show it
contrebasse@98 291 for reagentRecipeIndex = 1,GetTradeSkillNumReagents(recipeIndex) do
contrebasse@98 292 -- ID of the reagent we want to craft
contrebasse@98 293 local reagentLink = GetTradeSkillReagentItemLink(recipeIndex, reagentRecipeIndex)
contrebasse@98 294 local reagentID = A.link2ID(reagentLink)
contrebasse@98 295
contrebasse@98 296 local label = _G["TradeSkillReagent"..reagentRecipeIndex].label
contrebasse@98 297 if not label then break end -- Shouldn't happen...
contrebasse@98 298
contrebasse@98 299 -- Continue only if the reagent is known
contrebasse@98 300 if not reagentID or not A.data[reagentID] then
contrebasse@98 301 label:Hide()
contrebasse@98 302 else
contrebasse@98 303 -- Count and show
contrebasse@98 304 local numMakable = A.numMakable(reagentID)
contrebasse@108 305 --if not numMakable or #(A.data[reagentID]) ~= 1 or A.data[reagentID][1].macro then
contrebasse@108 306 if not numMakable then
contrebasse@98 307 label:SetText("?")
contrebasse@98 308 label:SetTextColor(0, 0.5, 1, 1) -- blue
contrebasse@98 309 else
contrebasse@98 310 label:SetText(numMakable)
contrebasse@98 311 if numMakable==0 then
contrebasse@98 312 label:SetTextColor(1, 0, 0, 1) -- red
contrebasse@98 313 else
contrebasse@98 314 label:SetTextColor(0, 1, 0, 1) -- green
contrebasse@98 315 end
contrebasse@98 316 end -- if
contrebasse@98 317 label:Show()
contrebasse@98 318 end -- if
contrebasse@98 319 end -- for
contrebasse@98 320 end -- function
contrebasse@98 321 hooksecurefunc("SelectTradeSkill",A.updateCounts)