Mercurial > wow > reagentmaker
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 110:d60d6b4cab0c | 111:af23986010ef |
|---|---|
| 1 local addonName, A = ... | |
| 2 | |
| 3 -- GLOBALS: SPELL_FAILED_ERROR, OpenStackSplitFrame, StackSplitFrame_OnChar, StackSplitFrame | |
| 4 | |
| 5 -- Lua functions | |
| 6 local tostring = tostring | |
| 7 local min = math.min | |
| 8 local max = math.max | |
| 9 local floor = math.floor | |
| 10 | |
| 11 -- Wow functions | |
| 12 local IsTradeSkillGuild = IsTradeSkillGuild | |
| 13 local IsTradeSkillLinked = IsTradeSkillLinked | |
| 14 local IsModifierKeyDown = IsModifierKeyDown | |
| 15 local IsShiftKeyDown = IsShiftKeyDown | |
| 16 local GetTradeSkillSelectionIndex = GetTradeSkillSelectionIndex | |
| 17 local GetTradeSkillReagentItemLink = GetTradeSkillReagentItemLink | |
| 18 local GetTradeSkillReagentInfo = GetTradeSkillReagentInfo | |
| 19 local GetTradeSkillLine = GetTradeSkillLine | |
| 20 local GetItemInfo = GetItemInfo | |
| 21 local DoTradeSkill = DoTradeSkill | |
| 22 | |
| 23 --SPELL_FAILED_REAGENTS = "Missing reagent: %s"; | |
| 24 --ERR_SPELL_FAILED_REAGENTS_GENERIC = "Missing reagent"; | |
| 25 --ERR_INTERNAL_BAG_ERROR = "Internal Bag Error"; | |
| 26 --SPELL_FAILED_ERROR = "Internal error"; | |
| 27 | |
| 28 --------------------------------------------------- | |
| 29 -- Craft items | |
| 30 --------------------------------------------------- | |
| 31 -- Function run after selecting a item in the tradeskill window | |
| 32 -- It only "prefilters" the possibilities | |
| 33 function A.ProcessReagent(btn) | |
| 34 -- Do not manage guild or linked tradeskill | |
| 35 if IsTradeSkillGuild() or IsTradeSkillLinked() then return end | |
| 36 | |
| 37 -- We want no modifiers, or shift to choose the number of reagent to craft | |
| 38 if IsModifierKeyDown() and not IsShiftKeyDown() then return end | |
| 39 local chooseNumberToCraft = IsShiftKeyDown() | |
| 40 | |
| 41 -- Index of the reagent in the recipe, taken from the button name | |
| 42 local reagentIndexInRecipe = A.buttonNumber(btn) | |
| 43 | |
| 44 -- ID of the reagent we want to craft | |
| 45 local recipeIndex = GetTradeSkillSelectionIndex() | |
| 46 local reagentID = A.link2ID(GetTradeSkillReagentItemLink(recipeIndex, reagentIndexInRecipe)) | |
| 47 | |
| 48 -- Continue only if the reagent is known | |
| 49 if not reagentID or not A.data[reagentID] then return end | |
| 50 | |
| 51 -- If only one recipe is known for the reagent and it is an actual recipe, use it | |
| 52 if #(A.data[reagentID]) == 1 and not A.data[reagentID][1].macro then | |
| 53 A.CraftItemWithRecipe(recipeIndex,reagentID,A.data[reagentID][1],reagentIndexInRecipe,chooseNumberToCraft,btn) | |
| 54 | |
| 55 else -- Many recipes are known for this item, or it is not a standard tradeskill display them all | |
| 56 A.externalCraftWindow(reagentID,reagentIndexInRecipe) | |
| 57 end -- if | |
| 58 --A.RestoreActiveFilters() | |
| 59 end -- function | |
| 60 | |
| 61 -- Launch the procedure for a standard recipe | |
| 62 -- Can be called from the external window | |
| 63 function A.CraftItemWithRecipe(recipeIndex,reagentID,recipeData,reagentIndexInRecipe,chooseNumberToCraft,btn) | |
| 64 -- Check that it's the same tradeskill | |
| 65 if recipeData.tradeskillName ~= GetTradeSkillLine() then | |
| 66 A.Error(A.L["The recipe to make this reagent is in another tradeskill. Currently ReagentMaker can not manage such a case, sorry."]) | |
| 67 return | |
| 68 end | |
| 69 | |
| 70 -- Check how many times the recipe is makable | |
| 71 local numMakable = A.numRecipeMakable(recipeData[1],recipeData[2]) | |
| 72 if not numMakable then | |
| 73 A.Error(SPELL_FAILED_ERROR) | |
| 74 return | |
| 75 end | |
| 76 | |
| 77 if numMakable<=0 then | |
| 78 -- If not makable, try a one-step recursion | |
| 79 -- enables e.g. to mill to create an ink | |
| 80 -- need a unique reagent | |
| 81 if recipeData[1] and A.data[recipeData[1]] then | |
| 82 if A.externalCraftWindow(recipeData[1],reagentIndexInRecipe,reagentID) ~= false then | |
| 83 -- there was no problem opening the external window | |
| 84 return | |
| 85 end | |
| 86 end | |
| 87 | |
| 88 -- There isn't enough reagents | |
| 89 --@todo include name of reagent if unique | |
| 90 A.Error(A.L["You do not have enough reagents to craft [%s]"]:format(GetItemInfo(reagentID) or "item #"..reagentID)) | |
| 91 return | |
| 92 end | |
| 93 | |
| 94 -- Optimal number of items to craft | |
| 95 local numToMake = A.numToMake(recipeIndex, reagentIndexInRecipe,numMakable, recipeData[3], recipeData[4]) | |
| 96 | |
| 97 -- Choose number or craft directly | |
| 98 if chooseNumberToCraft then | |
| 99 -- Store info to be able to run the function later | |
| 100 btn.ReagentMaker_reagentID = reagentID | |
| 101 btn.ReagentMaker_recipeData = recipeData | |
| 102 | |
| 103 -- Open dialog | |
| 104 OpenStackSplitFrame(numMakable, btn, "TOP", "BOTTOM") | |
| 105 | |
| 106 -- Fill in the number to make | |
| 107 numToMake = tostring(numToMake) | |
| 108 for i = 1,numToMake:len() do | |
| 109 StackSplitFrame_OnChar(StackSplitFrame,numToMake:gsub(i,i)) | |
| 110 end | |
| 111 StackSplitFrame.typing = 0 -- reinit the frame so that the entered value will be erased on text entry | |
| 112 else | |
| 113 A.DoCraft(reagentID,recipeData,numToMake) | |
| 114 end -- if | |
| 115 end | |
| 116 | |
| 117 -- Compute optimal number of items to craft | |
| 118 function A.numToMake(recipeIndex, reagentIndexInRecipe,numReagentMakable,minMade,maxMade) | |
| 119 -- Look at how many we need to make one item for the selected recipe | |
| 120 local numToMake = 1 | |
| 121 local _, _, reagentCount, playerReagentCount = GetTradeSkillReagentInfo(recipeIndex, reagentIndexInRecipe) | |
| 122 -- make enough reagents to craft one more item | |
| 123 numToMake = min(floor(playerReagentCount/reagentCount+1)*reagentCount-playerReagentCount,numReagentMakable) | |
| 124 | |
| 125 -- take into account that some recipe craft more than one item | |
| 126 -- use the mean between min and max, but make at least one... | |
| 127 if not minMade then | |
| 128 minMade = 1 | |
| 129 elseif minMade<1 then | |
| 130 -- from the percentage, compute the mean number of crafts to make | |
| 131 minMade = 1/minMade | |
| 132 end | |
| 133 if not maxMade then | |
| 134 maxMade = minMade | |
| 135 end | |
| 136 numToMake = max(floor(2*numToMake/(maxMade+minMade)),1) | |
| 137 return numToMake | |
| 138 end | |
| 139 | |
| 140 -- function used after choosing the number of reagent to craft | |
| 141 function A.SplitStack(owner,split) | |
| 142 A.DoCraft(owner.ReagentMaker_reagentID,owner.ReagentMaker_recipeData,split) | |
| 143 owner.ReagentMaker_reagentID = nil | |
| 144 owner.ReagentMaker_recipeData = nil | |
| 145 end | |
| 146 | |
| 147 -- Find the recipe and do the crafting | |
| 148 function A.DoCraft(reagentID,recipeData,numToMake) | |
| 149 -- Remove filters | |
| 150 A.SaveActiveFilters(recipeData.header) | |
| 151 | |
| 152 -- Find recipe index | |
| 153 local reagentIndex = A.findExactSkillIndex(reagentID,recipeData.spellLink) -- finds only the first recipe that creates the reagent, should check recipe name too | |
| 154 | |
| 155 -- Error if not found | |
| 156 if not reagentIndex then | |
| 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."]) | |
| 158 A.RestoreActiveFilters() | |
| 159 return | |
| 160 end | |
| 161 | |
| 162 -- Craft the item, finally ! | |
| 163 DoTradeSkill(reagentIndex,numToMake) | |
| 164 | |
| 165 -- Restore Filters | |
| 166 A.RestoreActiveFilters() | |
| 167 end |
