contrebasse@25: local addonName, A = ... contrebasse@25: contrebasse@25: -- @todo clean the A table contrebasse@25: -- @todo check local copy of globals functions contrebasse@25: -- @todo add support for dez ? contrebasse@41: -- @todo add support for hidden recipes, removing filtering contrebasse@25: -- @todo add support for cross tradeskill, like mining + forge/ingé contrebasse@49: -- @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: -- @todo scroll to the selected recipe on opening (usefull also for the previous todo) contrebasse@49: -- @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: -- @todo add a button to clear search contrebasse@81: -- @todo add a button to cast a campfire when coocking contrebasse@25: contrebasse@25: --------------------------------------------------- contrebasse@25: -- Variables contrebasse@25: --------------------------------------------------- contrebasse@25: -- Used by findglobals contrebasse@25: -- GLOBALS: _G, CreateFrame, DEFAULT_CHAT_FRAME contrebasse@25: contrebasse@25: -- Lua functions contrebasse@25: contrebasse@25: -- Wow functions contrebasse@25: contrebasse@25: -- constant vars contrebasse@25: contrebasse@25: --------------------------------------------------- contrebasse@25: -- Manage events contrebasse@25: --------------------------------------------------- contrebasse@25: A.EventsFrame = CreateFrame("Frame") contrebasse@25: contrebasse@25: local SCAN_DELAY = 0.2 contrebasse@25: local t_throttle = SCAN_DELAY contrebasse@25: local function throttleScan(self, t_elapsed) contrebasse@25: t_throttle = t_throttle - t_elapsed contrebasse@25: if t_throttle<0 then contrebasse@25: self:SetScript("OnUpdate", nil) contrebasse@25: contrebasse@25: -- Close the external window if the tradeskill changed contrebasse@25: if A.currentTradeSkill ~= GetTradeSkillLine() then contrebasse@25: A.MenuFrame:Hide() contrebasse@25: end contrebasse@25: if IsTradeSkillGuild() or IsTradeSkillLinked() then contrebasse@25: A.MenuFrame:Hide() contrebasse@25: return contrebasse@25: end contrebasse@25: contrebasse@25: -- Scan availabe recipes contrebasse@27: -- Rescan in case of problem contrebasse@27: if not A:ScanSimpleRecipes() then contrebasse@27: t_throttle = SCAN_DELAY contrebasse@27: self:SetScript("OnUpdate", throttleScan) contrebasse@27: end contrebasse@25: contrebasse@25: -- Show makables reagents contrebasse@25: A.updateCounts(GetTradeSkillSelectionIndex()) contrebasse@25: end contrebasse@25: end contrebasse@25: A.EventsFrame:SetScript("OnEvent", function(self, event) contrebasse@25: if event == "TRADE_SKILL_UPDATE" then contrebasse@25: t_throttle = SCAN_DELAY contrebasse@25: self:SetScript("OnUpdate", throttleScan) contrebasse@25: contrebasse@25: elseif event == "TRADE_SKILL_SHOW" then contrebasse@25: A:Initialize() contrebasse@25: A.EventsFrame:UnregisterEvent("TRADE_SKILL_SHOW") contrebasse@25: end -- if contrebasse@25: end) -- function contrebasse@25: A.EventsFrame:RegisterEvent("TRADE_SKILL_SHOW") contrebasse@25: A.EventsFrame:RegisterEvent("TRADE_SKILL_UPDATE") contrebasse@25: contrebasse@25: --------------------------------------------------- contrebasse@25: -- Initialize contrebasse@25: --------------------------------------------------- contrebasse@25: function A:Initialize() contrebasse@25: contrebasse@25: -- Register clics on reagent's buttons contrebasse@25: for i=1,7 do contrebasse@25: local btn = _G["TradeSkillReagent"..i] contrebasse@25: btn:HookScript("OnDoubleClick", A.ProcessReagent) contrebasse@25: btn:HookScript("OnEnter", A.btnEntered) contrebasse@25: btn:HookScript("OnLeave", A.btnLeft) contrebasse@25: btn.SplitStack = A.SplitStack contrebasse@25: contrebasse@25: local textureHighlight = btn:CreateTexture() contrebasse@25: textureHighlight:Hide() contrebasse@25: textureHighlight:SetTexture("Interface\\BUTTONS\\CheckButtonHilight") contrebasse@25: textureHighlight:SetBlendMode("ADD") contrebasse@25: textureHighlight:SetAllPoints("TradeSkillReagent"..i.."IconTexture") contrebasse@25: btn.textureHighlight = textureHighlight contrebasse@25: contrebasse@25: local label = btn:CreateFontString(nil,"ARTWORK","GameFontHighlight") contrebasse@25: label:SetSize(100,20) contrebasse@25: label:SetPoint("TOPLEFT",btn,"TOPLEFT",4,-4) contrebasse@25: label:SetJustifyH("LEFT") contrebasse@25: label:SetJustifyV("TOP") contrebasse@25: label:SetFont("Fonts\\FRIZQT__.TTF", 10, "OUTLINE") contrebasse@25: btn.label = label contrebasse@25: end -- for contrebasse@25: contrebasse@77: -- Secondary Tooltip contrebasse@25: A.tooltipRecipe = CreateFrame("GameTooltip", "ReagentMaker_tooltipRecipe",UIParent, "GameTooltipTemplate") contrebasse@25: A.tooltipRecipe:SetFrameStrata("TOOLTIP") contrebasse@25: A.tooltipRecipe:Hide() contrebasse@77: contrebasse@77: -- Button for enchanting directy on a scroll contrebasse@77: A.LoadEnchantOnScroll() contrebasse@25: end -- function contrebasse@25: contrebasse@25: -- Function run after selecting a item in the tradeskill window contrebasse@25: function A.ProcessReagent(btn, ...) contrebasse@25: contrebasse@25: -- Do not manage guild tradeskill contrebasse@25: if IsTradeSkillGuild() or IsTradeSkillLinked() then return end contrebasse@25: contrebasse@25: -- We want no modifiers, or shift to choose the number of reagent to craft contrebasse@25: if IsModifierKeyDown() and not IsShiftKeyDown() then return end contrebasse@25: local chooseNumberToCraft = IsShiftKeyDown() contrebasse@25: contrebasse@25: -- Index of the reagent in the recipe, taken from the button name contrebasse@25: local reagentRecipeIndex = A.buttonNumber(btn) contrebasse@25: contrebasse@25: -- ID of the reagent we want to craft contrebasse@46: local recipeIndex = GetTradeSkillSelectionIndex() contrebasse@46: local reagentID = A.link2ID(GetTradeSkillReagentItemLink(recipeIndex, reagentRecipeIndex)) contrebasse@25: contrebasse@25: -- Continue only if the reagent is known contrebasse@25: if not reagentID or not A.data[reagentID] then return end contrebasse@25: contrebasse@25: -- If only one recipe is known for the reagent, use it contrebasse@82: if #(A.data[reagentID]) == 1 and not A.data[reagentID][1].macro then contrebasse@25: local numMakable, reagentIndex = A.numMakable(reagentID) contrebasse@82: contrebasse@82: -- Try to show the recipe once if it was not found contrebasse@82: if not reagentIndex then contrebasse@82: A.SaveActiveFilters(A.data[reagentID][1].header) contrebasse@82: numMakable, reagentIndex = A.numMakable(reagentID) contrebasse@82: end contrebasse@82: contrebasse@82: if not numMakable then contrebasse@79: 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: return contrebasse@25: end contrebasse@25: if numMakable>0 then contrebasse@46: A.craft(recipeIndex,reagentRecipeIndex,reagentIndex,numMakable,chooseNumberToCraft) contrebasse@25: return contrebasse@25: end contrebasse@33: contrebasse@25: -- If we can make the item needed to make the reagent, open a window to make it contrebasse@25: -- one step recursion, enables to mill to create an ink contrebasse@70: if (not A.data[reagentID][1].manyReagents) and A.data[A.data[reagentID][1][1]] then contrebasse@76: if A.externalCraftWindow(A.data[reagentID][1][1],reagentID) ~= false then contrebasse@76: return contrebasse@76: end contrebasse@25: end contrebasse@76: contrebasse@76: A.Error(A.L["You do not have enough reagents to craft [%s]"]:format(GetItemInfo(reagentID) or "item #"..reagentID)) contrebasse@38: return contrebasse@25: else contrebasse@25: A.externalCraftWindow(reagentID) contrebasse@25: end -- if contrebasse@25: --A.RestoreActiveFilters() contrebasse@25: end -- function contrebasse@25: contrebasse@25: contrebasse@25: --------------------------------------------------- contrebasse@25: -- Craft items contrebasse@25: --------------------------------------------------- contrebasse@25: -- function used after choosing the number of reagent to craft contrebasse@25: function A.SplitStack(owner,split) contrebasse@25: DoTradeSkill(owner.ReagentMaker_reagentIndex,tonumber(split)) contrebasse@25: owner.ReagentMaker_reagentIndex = nil contrebasse@25: end contrebasse@25: contrebasse@25: -- Craft the reagent of an item, given it's position in the recipe contrebasse@46: function A.craft(recipeIndex,reagentRecipeIndex,reagentIndex,numReagentMakable,chooseNumber) contrebasse@25: -- Look at how many we need to make one item for the selected recipe contrebasse@25: local numToMake = 1 contrebasse@46: local _, _, reagentCount, playerReagentCount = GetTradeSkillReagentInfo(recipeIndex, reagentRecipeIndex) contrebasse@28: -- make enough reagents to craft one more item contrebasse@46: numToMake = math.min(math.floor(playerReagentCount/reagentCount+1)*reagentCount-playerReagentCount,numReagentMakable) contrebasse@25: contrebasse@46: -- take into account that some recipe craft more than one item contrebasse@46: -- use the mean between min and max, but make at least one... contrebasse@46: local minMade, maxMade = GetTradeSkillNumMade(reagentIndex) contrebasse@46: numToMake = math.max(math.floor(2*numToMake/(maxMade+minMade)),1) contrebasse@46: contrebasse@25: -- Choose number or craft directly contrebasse@46: if chooseNumber then contrebasse@25: -- the dialog window is linked to the reagent button contrebasse@25: local btn = _G["TradeSkillReagent"..reagentRecipeIndex] contrebasse@25: contrebasse@25: -- Store info to be able to run the function later contrebasse@25: btn.ReagentMaker_reagentIndex = reagentIndex contrebasse@25: contrebasse@25: -- Open dialog contrebasse@25: OpenStackSplitFrame(numReagentMakable, btn, "TOP", "BOTTOM") contrebasse@25: contrebasse@25: -- Fill in the number to make contrebasse@25: numToMake = tostring(numToMake) contrebasse@25: for i = 1,numToMake:len() do contrebasse@25: StackSplitFrame_OnChar(StackSplitFrame,numToMake:gsub(i,i)) contrebasse@25: end contrebasse@25: StackSplitFrame.typing = 0 -- reinit the frame so tha the entered value will be erased on text entry contrebasse@25: else contrebasse@25: DoTradeSkill(reagentIndex,numToMake) contrebasse@25: end -- if contrebasse@25: end -- function contrebasse@25: contrebasse@25: contrebasse@25: -- Button hovering contrebasse@25: function A.btnEntered(btn) contrebasse@25: -- Do not manage guild tradeskill contrebasse@25: if IsTradeSkillGuild() or IsTradeSkillLinked() then return end contrebasse@25: contrebasse@25: -- Index of the reagent in the recipe, taken from the button name contrebasse@25: local reagentRecipeIndex = A.buttonNumber(btn) contrebasse@25: contrebasse@25: -- ID of the reagent we want to craft contrebasse@25: local reagentLink = GetTradeSkillReagentItemLink(GetTradeSkillSelectionIndex(), reagentRecipeIndex) contrebasse@25: local reagentID = A.link2ID(reagentLink) contrebasse@25: contrebasse@25: -- Continue only if the reagent is known contrebasse@25: if not reagentID or not A.data[reagentID] then return end contrebasse@25: contrebasse@25: btn.textureHighlight:Show() contrebasse@25: contrebasse@70: -- Check if the item is made by only one recipe. If not, return contrebasse@73: if not A.isRecipeUnique(A.data[reagentID]) then return end contrebasse@70: contrebasse@25: -- Tooltips contrebasse@70: local link = A.data[reagentID][1].spellLink contrebasse@25: if link then contrebasse@25: A.tooltipRecipe:SetOwner(btn) contrebasse@25: A.tooltipRecipe:SetHyperlink(link) contrebasse@25: A.tooltipRecipe:Show() contrebasse@25: A.tooltipRecipe:ClearAllPoints() contrebasse@25: A.tooltipRecipe:SetPoint("BOTTOMLEFT",GameTooltip,"BOTTOMRIGHT") contrebasse@25: end contrebasse@25: end contrebasse@25: contrebasse@25: function A.btnLeft(btn) contrebasse@25: btn.textureHighlight:Hide() contrebasse@25: A.tooltipRecipe:Hide() contrebasse@25: end -- function contrebasse@25: contrebasse@25: function A.updateCounts(recipeIndex) contrebasse@25: -- Needs an argument contrebasse@25: if not recipeIndex then return end contrebasse@25: contrebasse@25: -- Do not manage guild tradeskill contrebasse@25: if IsTradeSkillGuild() or IsTradeSkillLinked() then contrebasse@25: for reagentRecipeIndex = 1,GetTradeSkillNumReagents(recipeIndex) do contrebasse@70: -- If the normal tradeskill hasn't been opened yet, the field 'label' doesn't exists yet contrebasse@70: local label = _G["TradeSkillReagent"..reagentRecipeIndex].label contrebasse@70: if label then contrebasse@70: label:Hide() contrebasse@70: end contrebasse@25: end contrebasse@25: return contrebasse@25: end contrebasse@25: contrebasse@25: -- Count makable items and show it contrebasse@25: for reagentRecipeIndex = 1,GetTradeSkillNumReagents(recipeIndex) do contrebasse@25: -- ID of the reagent we want to craft contrebasse@25: local reagentLink = GetTradeSkillReagentItemLink(recipeIndex, reagentRecipeIndex) contrebasse@25: local reagentID = A.link2ID(reagentLink) contrebasse@25: contrebasse@25: local label = _G["TradeSkillReagent"..reagentRecipeIndex].label contrebasse@70: if not label then break end -- Shouldn't happen... contrebasse@25: contrebasse@25: -- Continue only if the reagent is known contrebasse@70: if not reagentID or not A.data[reagentID] then contrebasse@25: label:Hide() contrebasse@25: else contrebasse@25: -- Count and show contrebasse@25: local numMakable = A.numMakable(reagentID) contrebasse@70: if not numMakable or #(A.data[reagentID]) ~= 1 or A.data[reagentID][1].macro then contrebasse@70: label:SetText("?") contrebasse@70: label:SetTextColor(0, 0.5, 1, 1) -- blue contrebasse@25: else contrebasse@70: label:SetText(numMakable) contrebasse@70: if numMakable==0 then contrebasse@70: label:SetTextColor(1, 0, 0, 1) -- red contrebasse@70: else contrebasse@70: label:SetTextColor(0, 1, 0, 1) -- green contrebasse@70: end contrebasse@25: end -- if contrebasse@25: label:Show() contrebasse@25: end -- if contrebasse@25: end -- for contrebasse@25: end -- function contrebasse@25: hooksecurefunc("SelectTradeSkill",A.updateCounts)