# HG changeset patch # User contrebasse # Date 1307048843 -7200 # Node ID af23986010ef080bd3f2ea558ed2a3ce7a73ec2b # Parent d60d6b4cab0cc480ebd0bd09cc10add0f3ad3b56 Rewrote the main part to clarify things, should have removed some hidden nasty bugs. diff -r d60d6b4cab0c -r af23986010ef CampFireButton.lua --- a/CampFireButton.lua Thu Jun 02 18:23:42 2011 +0200 +++ b/CampFireButton.lua Thu Jun 02 23:07:23 2011 +0200 @@ -7,6 +7,7 @@ local CooldownFrame_SetTimer = CooldownFrame_SetTimer local GetSpellCooldown = GetSpellCooldown +-- The cooldown info is not directly obtainable local function WaitCooldown(self) local start, duration, enable = GetSpellCooldown(CAMPFIRE_ID) if start>0 then @@ -19,7 +20,7 @@ function A.InitialiseCampFireBtn() if not GetTradeSkillLine() or InCombatLockdown() then return end - -- create the frame + -- Create the frame btn = CreateFrame("Button", nil, TradeSkillFrame, "SecureActionButtonTemplate") btn:SetNormalTexture(select(3,GetSpellInfo(CAMPFIRE_ID))) btn:SetHighlightTexture("Interface\\BUTTONS\\ButtonHilight-Square") @@ -67,6 +68,7 @@ -- Hide button function A.HideCampFireBtn() if btn then btn:Hide() end + btn:UnregisterAllEvents() end -- Show button if applicable diff -r d60d6b4cab0c -r af23986010ef Craft.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Craft.lua Thu Jun 02 23:07:23 2011 +0200 @@ -0,0 +1,167 @@ +local addonName, A = ... + +-- GLOBALS: SPELL_FAILED_ERROR, OpenStackSplitFrame, StackSplitFrame_OnChar, StackSplitFrame + +-- Lua functions +local tostring = tostring +local min = math.min +local max = math.max +local floor = math.floor + +-- Wow functions +local IsTradeSkillGuild = IsTradeSkillGuild +local IsTradeSkillLinked = IsTradeSkillLinked +local IsModifierKeyDown = IsModifierKeyDown +local IsShiftKeyDown = IsShiftKeyDown +local GetTradeSkillSelectionIndex = GetTradeSkillSelectionIndex +local GetTradeSkillReagentItemLink = GetTradeSkillReagentItemLink +local GetTradeSkillReagentInfo = GetTradeSkillReagentInfo +local GetTradeSkillLine = GetTradeSkillLine +local GetItemInfo = GetItemInfo +local DoTradeSkill = DoTradeSkill + +--SPELL_FAILED_REAGENTS = "Missing reagent: %s"; +--ERR_SPELL_FAILED_REAGENTS_GENERIC = "Missing reagent"; +--ERR_INTERNAL_BAG_ERROR = "Internal Bag Error"; +--SPELL_FAILED_ERROR = "Internal error"; + +--------------------------------------------------- +-- Craft items +--------------------------------------------------- +-- Function run after selecting a item in the tradeskill window +-- It only "prefilters" the possibilities +function A.ProcessReagent(btn) + -- Do not manage guild or linked tradeskill + if IsTradeSkillGuild() or IsTradeSkillLinked() then return end + + -- We want no modifiers, or shift to choose the number of reagent to craft + if IsModifierKeyDown() and not IsShiftKeyDown() then return end + local chooseNumberToCraft = IsShiftKeyDown() + + -- Index of the reagent in the recipe, taken from the button name + local reagentIndexInRecipe = A.buttonNumber(btn) + + -- ID of the reagent we want to craft + local recipeIndex = GetTradeSkillSelectionIndex() + local reagentID = A.link2ID(GetTradeSkillReagentItemLink(recipeIndex, reagentIndexInRecipe)) + + -- Continue only if the reagent is known + if not reagentID or not A.data[reagentID] then return end + + -- If only one recipe is known for the reagent and it is an actual recipe, use it + if #(A.data[reagentID]) == 1 and not A.data[reagentID][1].macro then + A.CraftItemWithRecipe(recipeIndex,reagentID,A.data[reagentID][1],reagentIndexInRecipe,chooseNumberToCraft,btn) + + else -- Many recipes are known for this item, or it is not a standard tradeskill display them all + A.externalCraftWindow(reagentID,reagentIndexInRecipe) + end -- if + --A.RestoreActiveFilters() +end -- function + +-- Launch the procedure for a standard recipe +-- Can be called from the external window +function A.CraftItemWithRecipe(recipeIndex,reagentID,recipeData,reagentIndexInRecipe,chooseNumberToCraft,btn) + -- Check that it's the same tradeskill + if recipeData.tradeskillName ~= GetTradeSkillLine() then + A.Error(A.L["The recipe to make this reagent is in another tradeskill. Currently ReagentMaker can not manage such a case, sorry."]) + return + end + + -- Check how many times the recipe is makable + local numMakable = A.numRecipeMakable(recipeData[1],recipeData[2]) + if not numMakable then + A.Error(SPELL_FAILED_ERROR) + return + end + + if numMakable<=0 then + -- If not makable, try a one-step recursion + -- enables e.g. to mill to create an ink + -- need a unique reagent + if recipeData[1] and A.data[recipeData[1]] then + if A.externalCraftWindow(recipeData[1],reagentIndexInRecipe,reagentID) ~= false then + -- there was no problem opening the external window + return + end + end + + -- There isn't enough reagents + --@todo include name of reagent if unique + A.Error(A.L["You do not have enough reagents to craft [%s]"]:format(GetItemInfo(reagentID) or "item #"..reagentID)) + return + end + + -- Optimal number of items to craft + local numToMake = A.numToMake(recipeIndex, reagentIndexInRecipe,numMakable, recipeData[3], recipeData[4]) + + -- Choose number or craft directly + if chooseNumberToCraft then + -- Store info to be able to run the function later + btn.ReagentMaker_reagentID = reagentID + btn.ReagentMaker_recipeData = recipeData + + -- Open dialog + OpenStackSplitFrame(numMakable, btn, "TOP", "BOTTOM") + + -- Fill in the number to make + numToMake = tostring(numToMake) + for i = 1,numToMake:len() do + StackSplitFrame_OnChar(StackSplitFrame,numToMake:gsub(i,i)) + end + StackSplitFrame.typing = 0 -- reinit the frame so that the entered value will be erased on text entry + else + A.DoCraft(reagentID,recipeData,numToMake) + end -- if +end + +-- Compute optimal number of items to craft +function A.numToMake(recipeIndex, reagentIndexInRecipe,numReagentMakable,minMade,maxMade) + -- Look at how many we need to make one item for the selected recipe + local numToMake = 1 + local _, _, reagentCount, playerReagentCount = GetTradeSkillReagentInfo(recipeIndex, reagentIndexInRecipe) + -- make enough reagents to craft one more item + numToMake = min(floor(playerReagentCount/reagentCount+1)*reagentCount-playerReagentCount,numReagentMakable) + + -- take into account that some recipe craft more than one item + -- use the mean between min and max, but make at least one... + if not minMade then + minMade = 1 + elseif minMade<1 then + -- from the percentage, compute the mean number of crafts to make + minMade = 1/minMade + end + if not maxMade then + maxMade = minMade + end + numToMake = max(floor(2*numToMake/(maxMade+minMade)),1) + return numToMake +end + +-- function used after choosing the number of reagent to craft +function A.SplitStack(owner,split) + A.DoCraft(owner.ReagentMaker_reagentID,owner.ReagentMaker_recipeData,split) + owner.ReagentMaker_reagentID = nil + owner.ReagentMaker_recipeData = nil +end + +-- Find the recipe and do the crafting +function A.DoCraft(reagentID,recipeData,numToMake) + -- Remove filters + A.SaveActiveFilters(recipeData.header) + + -- Find recipe index + local reagentIndex = A.findExactSkillIndex(reagentID,recipeData.spellLink) -- finds only the first recipe that creates the reagent, should check recipe name too + + -- Error if not found + if not reagentIndex then + 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."]) + A.RestoreActiveFilters() + return + end + + -- Craft the item, finally ! + DoTradeSkill(reagentIndex,numToMake) + + -- Restore Filters + A.RestoreActiveFilters() +end diff -r d60d6b4cab0c -r af23986010ef ReagentMaker.lua --- a/ReagentMaker.lua Thu Jun 02 18:23:42 2011 +0200 +++ b/ReagentMaker.lua Thu Jun 02 23:07:23 2011 +0200 @@ -1,30 +1,33 @@ local addonName, A = ... --- @todo clean the A table --- @todo check local copy of globals functions +-- @todo add support for cross tradeskill, like mining + forge/ingé -- @todo add support for dez ? --- @todo add support for hidden recipes, removing filtering => save the reagent count to be able to compute the number of craftable items --- @todo add support for cross tradeskill, like mining + forge/ingé --- @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) --- @todo scroll to the selected recipe on opening (usefull also for the previous todo) --- @todo shift+clic on a reagent name while the serachbar is focused fills the serachbar with the reagent name (idem with the crafted item) --- @todo add a button to clear search --- @todo add a button to cast a campfire when coocking +-- @todo scroll to the selected recipe on opening ? +-- @todo add a button to clear search ? + +-- @bug Enter when choosing number of crafts --------------------------------------------------- -- Variables --------------------------------------------------- -- Used by findglobals --- GLOBALS: _G, CreateFrame, DEFAULT_CHAT_FRAME +-- GLOBALS: _G, CreateFrame, DEFAULT_CHAT_FRAME, UIParent -- Lua functions -- Wow functions +local GetTradeSkillLine = GetTradeSkillLine +local IsTradeSkillGuild = IsTradeSkillGuild +local IsTradeSkillLinked = IsTradeSkillLinked +local GetTradeSkillSelectionIndex = GetTradeSkillSelectionIndex +local GetTradeSkillNumReagents = GetTradeSkillNumReagents +local GetTradeSkillReagentItemLink = GetTradeSkillReagentItemLink -- constant vars +local GameTooltip = GameTooltip --------------------------------------------------- --- Manage events +-- Manage events and throttling --------------------------------------------------- A.EventsFrame = CreateFrame("Frame") @@ -63,6 +66,7 @@ elseif event == "PLAYER_REGEN_DISABLED" then A.HideCampFireBtn() + elseif event == "PLAYER_REGEN_ENABLED" then A.ManageCampFireBtn() @@ -71,11 +75,14 @@ A.EventsFrame:UnregisterEvent("TRADE_SKILL_SHOW") end -- if end) -- function + +--@todo Unregister events when not needed A.EventsFrame:RegisterEvent("TRADE_SKILL_SHOW") A.EventsFrame:RegisterEvent("TRADE_SKILL_UPDATE") A.EventsFrame:RegisterEvent("PLAYER_REGEN_ENABLED") A.EventsFrame:RegisterEvent("PLAYER_REGEN_DISABLED") + --------------------------------------------------- -- Initialize --------------------------------------------------- @@ -115,136 +122,19 @@ A.LoadEnchantOnScroll() end -- function --- Function run after selecting a item in the tradeskill window -function A.ProcessReagent(btn, ...) - --SPELL_FAILED_REAGENTS = "Missing reagent: %s"; - --ERR_SPELL_FAILED_REAGENTS_GENERIC = "Missing reagent"; - --ERR_INTERNAL_BAG_ERROR = "Internal Bag Error"; - --SPELL_FAILED_ERROR = "Internal error"; - - -- Do not manage guild tradeskill - if IsTradeSkillGuild() or IsTradeSkillLinked() then return end - - -- We want no modifiers, or shift to choose the number of reagent to craft - if IsModifierKeyDown() and not IsShiftKeyDown() then return end - local chooseNumberToCraft = IsShiftKeyDown() - - -- Index of the reagent in the recipe, taken from the button name - local reagentRecipeIndex = A.buttonNumber(btn) - - -- ID of the reagent we want to craft - local recipeIndex = GetTradeSkillSelectionIndex() - local reagentID = A.link2ID(GetTradeSkillReagentItemLink(recipeIndex, reagentRecipeIndex)) - - -- Continue only if the reagent is known - if not reagentID or not A.data[reagentID] then return end - - -- If only one recipe is known for the reagent, use it - if #(A.data[reagentID]) == 1 and not A.data[reagentID][1].macro then - if A.data[reagentID][1].tradeskillName and A.data[reagentID][1].tradeskillName ~= GetTradeSkillLine() then - A.Error(A.L["The recipe to make this reagent is in another tradeskill. Currently ReagentMaker can not manage such a case, sorry."]) - return - end - - local reagentIndex = A.findSkillIndex(reagentID) -- finds only the first recipe that creates the reagent, should check recipe name too - - -- Try to show the recipe by removing filters once if it was not found - if not reagentIndex then - A.SaveActiveFilters(A.data[reagentID][1].header) - reagentIndex = A.findSkillIndex(reagentID) - end - if not reagentIndex then - 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."]) - A.RestoreActiveFilters() - return - end - - local numMakable = A.numMakable(reagentID) - if not numMakable then - A.Error(A.L["There was a problem while retrieving informations, please retry."]) - A.RestoreActiveFilters() - return - end - if numMakable>0 then - A.craft(recipeIndex,reagentRecipeIndex,reagentIndex,numMakable,chooseNumberToCraft) - A.RestoreActiveFilters() - return - end - - -- If we can make the item needed to make the reagent, open a window to make it - -- one step recursion, enables to mill to create an ink - if A.data[reagentID][1][1] and A.data[A.data[reagentID][1][1]] then - if A.externalCraftWindow(A.data[reagentID][1][1],reagentID) ~= false then - A.RestoreActiveFilters() - return - end - end - - A.Error(A.L["You do not have enough reagents to craft [%s]"]:format(GetItemInfo(reagentID) or "item #"..reagentID)) - A.RestoreActiveFilters() - return - else - A.externalCraftWindow(reagentID) - end -- if - --A.RestoreActiveFilters() -end -- function - - --------------------------------------------------- --- Craft items +-- Dynamic display --------------------------------------------------- --- function used after choosing the number of reagent to craft -function A.SplitStack(owner,split) - DoTradeSkill(owner.ReagentMaker_reagentIndex,tonumber(split)) - owner.ReagentMaker_reagentIndex = nil -end - --- Craft the reagent of an item, given it's position in the recipe -function A.craft(recipeIndex,reagentRecipeIndex,reagentIndex,numReagentMakable,chooseNumber) - -- Look at how many we need to make one item for the selected recipe - local numToMake = 1 - local _, _, reagentCount, playerReagentCount = GetTradeSkillReagentInfo(recipeIndex, reagentRecipeIndex) - -- make enough reagents to craft one more item - numToMake = math.min(math.floor(playerReagentCount/reagentCount+1)*reagentCount-playerReagentCount,numReagentMakable) - - -- take into account that some recipe craft more than one item - -- use the mean between min and max, but make at least one... - local minMade, maxMade = GetTradeSkillNumMade(reagentIndex) - numToMake = math.max(math.floor(2*numToMake/(maxMade+minMade)),1) - - -- Choose number or craft directly - if chooseNumber then - -- the dialog window is linked to the reagent button - local btn = _G["TradeSkillReagent"..reagentRecipeIndex] - - -- Store info to be able to run the function later - btn.ReagentMaker_reagentIndex = reagentIndex - - -- Open dialog - OpenStackSplitFrame(numReagentMakable, btn, "TOP", "BOTTOM") - - -- Fill in the number to make - numToMake = tostring(numToMake) - for i = 1,numToMake:len() do - StackSplitFrame_OnChar(StackSplitFrame,numToMake:gsub(i,i)) - end - StackSplitFrame.typing = 0 -- reinit the frame so that the entered value will be erased on text entry - else - DoTradeSkill(reagentIndex,numToMake) - end -- if -end -- function - - --- Button hovering +-- Button hovering (entered) function A.btnEntered(btn) -- Do not manage guild tradeskill if IsTradeSkillGuild() or IsTradeSkillLinked() then return end -- Index of the reagent in the recipe, taken from the button name - local reagentRecipeIndex = A.buttonNumber(btn) + local reagentIndexInRecipe = A.buttonNumber(btn) -- ID of the reagent we want to craft - local reagentLink = GetTradeSkillReagentItemLink(GetTradeSkillSelectionIndex(), reagentRecipeIndex) + local reagentLink = GetTradeSkillReagentItemLink(GetTradeSkillSelectionIndex(), reagentIndexInRecipe) local reagentID = A.link2ID(reagentLink) -- Continue only if the reagent is known @@ -266,20 +156,22 @@ end end +-- Button hovering (left) function A.btnLeft(btn) btn.textureHighlight:Hide() A.tooltipRecipe:Hide() end -- function +-- Show counts on buttons function A.updateCounts(recipeIndex) -- Needs an argument if not recipeIndex then return end -- Do not manage guild tradeskill if IsTradeSkillGuild() or IsTradeSkillLinked() then - for reagentRecipeIndex = 1,GetTradeSkillNumReagents(recipeIndex) do + for reagentIndexInRecipe = 1,GetTradeSkillNumReagents(recipeIndex) do -- If the normal tradeskill hasn't been opened yet, the field 'label' doesn't exists yet - local label = _G["TradeSkillReagent"..reagentRecipeIndex].label + local label = _G["TradeSkillReagent"..reagentIndexInRecipe].label if label then label:Hide() end @@ -288,33 +180,31 @@ end -- Count makable items and show it - for reagentRecipeIndex = 1,GetTradeSkillNumReagents(recipeIndex) do + for reagentIndexInRecipe = 1,GetTradeSkillNumReagents(recipeIndex) do -- ID of the reagent we want to craft - local reagentLink = GetTradeSkillReagentItemLink(recipeIndex, reagentRecipeIndex) - local reagentID = A.link2ID(reagentLink) + local reagentID = A.link2ID(GetTradeSkillReagentItemLink(recipeIndex, reagentIndexInRecipe)) - local label = _G["TradeSkillReagent"..reagentRecipeIndex].label - if not label then break end -- Shouldn't happen... - - -- Continue only if the reagent is known - if not reagentID or not A.data[reagentID] then - label:Hide() - else - -- Count and show - local numMakable = A.numMakable(reagentID) - --if not numMakable or #(A.data[reagentID]) ~= 1 or A.data[reagentID][1].macro then - if not numMakable then - label:SetText("?") - label:SetTextColor(0, 0.5, 1, 1) -- blue + local label = _G["TradeSkillReagent"..reagentIndexInRecipe].label + if label then + -- Continue only if the reagent is known + if not reagentID or not A.data[reagentID] then + label:Hide() else - label:SetText(numMakable) - if numMakable==0 then - label:SetTextColor(1, 0, 0, 1) -- red + -- Count and show + local numMakable = A.numMakable(reagentID) + if not numMakable then + label:SetText("?") + label:SetTextColor(0, 0.5, 1, 1) -- blue else - label:SetTextColor(0, 1, 0, 1) -- green - end + label:SetText(numMakable) + if numMakable==0 then + label:SetTextColor(1, 0, 0, 1) -- red + else + label:SetTextColor(0, 1, 0, 1) -- green + end + end -- if + label:Show() end -- if - label:Show() end -- if end -- for end -- function diff -r d60d6b4cab0c -r af23986010ef ReagentMaker.toc --- a/ReagentMaker.toc Thu Jun 02 18:23:42 2011 +0200 +++ b/ReagentMaker.toc Thu Jun 02 23:07:23 2011 +0200 @@ -11,8 +11,10 @@ MillingData.lua CampFireButton.lua + utils.lua data.lua +Craft.lua SecureMenu.lua ReagentMaker.lua diff -r d60d6b4cab0c -r af23986010ef SecureMenu.lua --- a/SecureMenu.lua Thu Jun 02 18:23:42 2011 +0200 +++ b/SecureMenu.lua Thu Jun 02 23:07:23 2011 +0200 @@ -1,5 +1,11 @@ local addonName, A = ... +-- Lua functions +local ipairs = ipairs +local type = type + +-- Wow variables + -- Create the menu frame local MenuFrame = CreateFrame("Frame","ReagentMaker_ExternalFrame",UIParent) MenuFrame:Hide() @@ -56,8 +62,8 @@ -- Hide frame when selecting a recipe which doesn't need this reagent hooksecurefunc("SelectTradeSkill",function() local selectedIndex = GetTradeSkillSelectionIndex() - for reagentRecipeIndex = 1,GetTradeSkillNumReagents(selectedIndex) do - local reagentID = A.link2ID(GetTradeSkillReagentItemLink(selectedIndex, reagentRecipeIndex)) + for reagentIndexInRecipe = 1,GetTradeSkillNumReagents(selectedIndex) do + local reagentID = A.link2ID(GetTradeSkillReagentItemLink(selectedIndex, reagentIndexInRecipe)) if reagentID == MenuFrame.itemID or (MenuFrame.superItemID and reagentID == MenuFrame.superItemID) then return end @@ -204,30 +210,14 @@ end local function CraftFromExternal(btn) - local chooseNumber = IsShiftKeyDown() - local numReagentMakable = A.numRecipeMakable(btn.reagentID,btn.reagentsForOneRecipe) - local reagentIndex = A.findExactSkillIndex(btn.itemID,btn.itemNameString) + local chooseNumberToCraft = IsShiftKeyDown() - -- to define - local numToMake = 1 - - -- Choose number or craft directly - if chooseNumber then - -- Store info to be able to run the function later - btn.ReagentMaker_reagentIndex = reagentIndex - - -- Open dialog - OpenStackSplitFrame(numReagentMakable, btn, "BOTTOMRIGHT", "TOP") - - -- Fill in the number to make - numToMake = tostring(numToMake) - for i = 1,numToMake:len() do - StackSplitFrame_OnChar(StackSplitFrame,numToMake:gsub(i,i)) - end - StackSplitFrame.typing = 0 -- reinit the frame so that the entered value will be erased on text entry - else - DoTradeSkill(reagentIndex,numToMake) - end -- if + A.CraftItemWithRecipe( GetTradeSkillSelectionIndex(), + btn.itemID, + btn.reagent, + MenuFrame.reagentIndexInRecipe, + IsShiftKeyDown(), + btn) end -- Update counts and button actions @@ -346,6 +336,7 @@ -- Save params btn.itemID = itemID + btn.reagent = reagent btn.reagentID = reagent[1] btn.reagentLink = link btn.reagentsForOneRecipe = reagent[2] @@ -368,11 +359,11 @@ MenuFrame:SetScript("OnUpdate",nil) -- reopen - A.externalCraftWindow(MenuFrame.itemID,MenuFrame.superItemID) + A.externalCraftWindow(MenuFrame.itemID,MenuFrame.reagentIndexInRecipe,MenuFrame.superItemID) end -- Fill the window and open it -function A.externalCraftWindow(itemID,superItemID) +function A.externalCraftWindow(itemID,reagentIndexInRecipe,superItemID) -- Do not open during combat if InCombatLockdown() then A.Error(SPELL_FAILED_AFFECTING_COMBAT) @@ -400,6 +391,7 @@ MenuFrame.reagentLink = link MenuFrame.spellLink = A.isRecipeUnique(A.data[itemID]) and A.data[itemID][1].spellLink MenuFrame.itemID = itemID + MenuFrame.reagentIndexInRecipe = reagentIndexInRecipe MenuFrame.superItemID = superItemID -- optional, will be nil if not set -- Loop over the available recipes diff -r d60d6b4cab0c -r af23986010ef utils.lua --- a/utils.lua Thu Jun 02 18:23:42 2011 +0200 +++ b/utils.lua Thu Jun 02 23:07:23 2011 +0200 @@ -1,17 +1,21 @@ local addonName, A = ... +-- GLOBALS: UIErrorsFrame, UIErrorsFrame_OnEvent + -- Lua functions local tonumber = tonumber local select = select local sfind = string.find +local min = math.min +local floor = math.floor +local pairs = pairs +local ipairs = ipairs +local wipe = wipe +local tinsert = tinsert +local tremove = tremove -- Wow functions - --- DEBUG Print -function A.DEBUG(msg) - -- GLOBALS: DEFAULT_CHAT_FRAME - DEFAULT_CHAT_FRAME:AddMessage(msg or "nil",1,0,0) -end -- function +local GetItemCount = GetItemCount -- Messages to the user function A.Warn(msg) @@ -41,21 +45,23 @@ local GetTradeSkillInfo = GetTradeSkillInfo local GetNumTradeSkills = GetNumTradeSkills local GetTradeSkillItemLink = GetTradeSkillItemLink + local GetTradeSkillRecipeLink = GetTradeSkillRecipeLink function A.numRecipeMakable(reagentIDIfUnique,reagents) + local itemCount if reagentIDIfUnique then -- only one reagent itemCount = GetItemCount(reagentIDIfUnique) if not itemCount then return end - return math.floor(itemCount/reagents) + return floor(itemCount/reagents) else -- many reagents local m for _,reagent in pairs(reagents) do itemCount = GetItemCount(reagent[1]) if not itemCount then return end if not m then - m = math.floor(itemCount/reagent[2]) + m = floor(itemCount/reagent[2]) else - m = math.min(m,math.floor(itemCount/reagent[2])) + m = min(m,floor(itemCount/reagent[2])) end if m==0 then break end end @@ -63,7 +69,7 @@ end -- if end - -- Gives the number of craftable objects + -- Gives the total number of craftable objects function A.numMakable(reagentID) -- No recipe if not A.data[reagentID] then return 0 end @@ -88,11 +94,10 @@ end -- function -- Find the exact tradeskill index of the recipe to make an item - function A.findExactSkillIndex(itemID,recipeName) - if not itemID or not recipeName then return end + function A.findExactSkillIndex(itemID,recipeLink) + if not itemID or not recipeLink then return end for i = 1,GetNumTradeSkills() do - local skillName, skillType = GetTradeSkillInfo(i) - if skillType ~= "header" and skillName==recipeName and A.link2ID(GetTradeSkillItemLink(i)) == itemID then + if select(2,GetTradeSkillInfo(i)) ~= "header" and GetTradeSkillRecipeLink(i)==recipeLink and A.link2ID(GetTradeSkillItemLink(i)) == itemID then return i end -- if end -- for @@ -119,6 +124,10 @@ function A.SaveActiveFilters(headerName) A.blockScan = true + -- Save position + filtersState.positionOffset = FauxScrollFrame_GetOffset(TradeSkillListScrollFrame) + filtersState.positionValue = TradeSkillListScrollFrameScrollBar:GetValue() + -- Save filters filtersState.text = GetTradeSkillItemNameFilter() filtersState.minLevel, filtersState.maxLevel = GetTradeSkillItemLevelFilter() @@ -143,9 +152,9 @@ if (skillType == "header") and skillName==headerName then if not isExpanded then ExpandTradeSkillSubClass(i) - table.insert(headersState,true) + tinsert(headersState,true) else - table.insert(headersState,false) + tinsert(headersState,false) end end end @@ -164,7 +173,7 @@ -- restore headers for i = GetNumTradeSkills(), 1, -1 do local skillName, skillType = GetTradeSkillInfo(i) - if (skillType == "header") and skillName==headersState.headerName and table.remove(headersState,1) then + if (skillType == "header") and skillName==headersState.headerName and tremove(headersState,1) then CollapseTradeSkillSubClass(i) end end @@ -179,6 +188,10 @@ TradeSkillFrame.filterTbl.slotValue = filtersState.slotValue ApplyFilters() + -- Re set position + FauxScrollFrame_SetOffset(TradeSkillListScrollFrame,filtersState.positionOffset) + TradeSkillListScrollFrameScrollBar:SetValue(filtersState.positionValue) + stateSaved = nil A.blockScan = nil