Mercurial > wow > reagentmaker
diff Craft.lua @ 111:af23986010ef v1.1beta0
Rewrote the main part to clarify things, should have removed some hidden nasty bugs.
author | contrebasse |
---|---|
date | Thu, 02 Jun 2011 23:07:23 +0200 |
parents | |
children | 3854c682bb4a |
line wrap: on
line diff
--- /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