Advertisement
Tag365

Crafting API

May 1st, 2015
488
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.58 KB | None | 0 0
  1. ----------------------------
  2. -- Crafting API by Tag365 --
  3. ----------------------------
  4.  
  5. tCraftingTable = {1, 2, 3, 5, 6, 7, 9, 10, 11} -- This is the slots used for crafting.
  6. local tItemSlotsToDrop = {} -- This is used to determine which slots are not part of the crafting table to prevent other items from interfering from the list.
  7. recipes = {} -- The table holds recipes for items.
  8. nOutputSlot = 8 -- The final location of the crafted item.
  9. local loops = 0 -- This is used to determine when to print that the turtle is missing an item.
  10. local firstSlotEmpty = 0
  11. local currentRecipe = {}
  12. local tCraftCompletion = {}
  13. local turtleCraft = turtle.craft
  14. saveLocation = "recipes.list" -- This is the path where the recipe table will be stored.
  15.  
  16. -- Functions --
  17.  
  18. -- Downloads the recipes from the server.
  19. function updateRecipesFromServer()
  20. local url = "http://pastebin.com/raw.php?i=6gCgiaPg"
  21. if http then
  22. local hRecipes = http.get(url)
  23. local str = hRecipes.readAll()
  24. hRecipes.close()
  25. ok, recipes = pcall(textutils.unserialize, str)
  26. end
  27. end
  28.  
  29. -- Saves the recipe list.
  30. function saveRecipeList()
  31. local ok, str = pcall(textutils.serialize, recipes)
  32. if not ok then
  33. return false, str
  34. end
  35. local hFile = fs.open(saveLocation, "w")
  36. if hFile then
  37. hFile.write(str)
  38. hFile.close()
  39. return true
  40. end
  41. return false
  42. end
  43.  
  44. -- Loads the recipe list.
  45. function loadRecipeList()
  46. local hFile, ok = fs.open(saveLocation, "r")
  47. if hFile then
  48. local str = hFile.readAll()
  49. hFile.close()
  50. ok, recipes = pcall(textutils.unserialize, str)
  51. if type(recipes) ~= "table" then
  52. recipes = {}
  53. end
  54. return ok
  55. end
  56. return false
  57. end
  58.  
  59. -- Adds a new recipe to the table.
  60. function addNewRecipe(sItemName, nItemsGenerated, bIsShapeless, tResources)
  61. if type(bIsShapeless) == "nil" and type(tResources) == "nil" then
  62. tResources = nItemsGenerated
  63. bIsShapeless = false
  64. nItemsGenerated = 1
  65. elseif type(tResources) == "nil" then
  66. tResources = bIsShapeless
  67. bIsShapeless = false
  68. nItemsGenerated = 1
  69. end
  70. if type(sItemName) ~= "string" then
  71. error("bad argument #1 for addNewRecipe: string expected, got "..type(sItemName), 2)
  72. end
  73. if type(nItemsGenerated) ~= "number" then
  74. local newItemsGenerated = tonumber(nItemsGenerated)
  75. if type(nItemsGenerated) ~= "number" then
  76. error("bad argument #2 for addNewRecipe: number expected, got "..type(nItemsGenerated), 2)
  77. end
  78. nItemsGenerated = newItemsGenerated
  79. end
  80. if not recipes[sItemName] then
  81. recipes[sItemName] = {}
  82. end
  83. recipes[sItemName][#recipes[sItemName] + 1] = {}
  84. local tRecipe = recipes[sItemName][#recipes[sItemName]]
  85. tRecipe["ItemsGenerated"] = nItemsGenerated
  86. tRecipe["IsShapeless"] = bIsShapeless
  87. for k, v in pairs(tResources) do
  88. if not type(v) == "table" then
  89. error("bad argument #4 for addNewRecipe: multidimensional table expected, got "..type(v).." in item #"..k, 2)
  90. end
  91. tRecipe[k] = v
  92. end
  93. saveRecipeList()
  94. end
  95.  
  96. function updateFirstSlotEmpty()
  97. firstSlotEmpty = false
  98. for k, v in ipairs(tItemSlotsToDrop) do
  99. if turtle.getItemCount(v) == 0 then
  100. firstSlotEmpty = k
  101. break
  102. end
  103. end
  104. if not firstSlotEmpty then
  105. if not turtle.detectUp() then
  106. print("Warning: The turtle's inventory has filled up and the script has dropped items in the air. Items may be lost if left unattended.")
  107. end
  108. for k, v in ipairs(tItemSlotsToDrop) do
  109. selectSlot(v)
  110. turtle.dropUp(64)
  111. end
  112. slotsFilled = 0
  113. end
  114. end
  115.  
  116. -- Selects a slot if it is not the selected slot.
  117. function selectSlot(slot)
  118. if turtle.getSelectedSlot() ~= slot then
  119. turtle.select(slot)
  120. end
  121. end
  122.  
  123. -- Moves an item from the crafting grid to the inventory.
  124. function moveToInventory(slot, amount)
  125. updateFirstSlotEmpty()
  126. local remAmount = amount or turtle.getItemCount(slot) - 1
  127. selectSlot(slot)
  128. for k, v in ipairs(tItemSlotsToDrop) do
  129. if turtle.compareTo(v) then
  130. local added = math.min(turtle.getItemSpace(v) or 4, remAmount)
  131. turtle.transferTo(v, added)
  132. remAmount = remAmount - added
  133. if remAmount <= 0 then
  134. return
  135. end
  136. end
  137. end
  138. if tItemSlotsToDrop[firstSlotEmpty] then
  139. turtle.transferTo(tItemSlotsToDrop[firstSlotEmpty], math.min(turtle.getItemSpace(v), remAmount))
  140. end
  141. end
  142.  
  143. -- Moves an item from the inventory to the crafting grid.
  144. function moveFromInventory(slot, item, amount)
  145. local remAmount = amount or 1
  146. item = item or turtle.getItemDetail(slot)
  147. for k, v in ipairs(tItemSlotsToDrop) do
  148. local tCurrentItem = turtle.getItemDetail(v)
  149. if tCurrentItem then
  150. if tCurrentItem["name"] ~= item["name"] and tCurrentItem["name"] ~= item[1] then
  151. elseif tCurrentItem["damage"] ~= item["damage"] and tCurrentItem["damage"] ~= item[2] then
  152. else
  153. selectSlot(v)
  154. local added = math.min(turtle.getItemSpace(slot) or 1, remAmount)
  155. turtle.transferTo(slot, added)
  156. remAmount = remAmount - added
  157. if remAmount <= 0 then
  158. return true, 0
  159. end
  160. end
  161. end
  162. end
  163. return false, remAmount
  164. end
  165.  
  166. -- Checks if an item is the correct item.
  167. function checkCraftingSlot(k, v)
  168. loops = loops + 1
  169. if loops == 100 then
  170. print("Waiting for item #"..k.." to be given...")
  171. end
  172. if turtle.getItemCount(v) == 0 then
  173. if currentRecipe[k][1] == "" then
  174. return true
  175. else
  176. selectSlot(v)
  177. if not moveFromInventory(v, currentRecipe[k], 1) then
  178. turtle.suck(1)
  179. end
  180. end
  181. elseif turtle.getItemCount(v) > 1 then
  182. moveToInventory(v)
  183. end
  184. if currentRecipe[k][1] == "" then
  185. moveToInventory(v, 64)
  186. return true
  187. end
  188. local tCurrentItem = turtle.getItemDetail(v)
  189. if tCurrentItem then
  190. if currentRecipe[k][1] == "" then
  191. moveToInventory(v, 64)
  192. return true
  193. elseif tCurrentItem["name"] ~= currentRecipe[k][1] then
  194. elseif currentRecipe[k][2] and tCurrentItem["damage"] ~= currentRecipe[k][2] then
  195. else
  196. return true
  197. end
  198. end
  199. moveToInventory(v, 64)
  200. turtle.suck(64)
  201. return false
  202. end
  203.  
  204. -- When all items are available this function will break the while loop in craftItems.
  205. function craftingNotComplete()
  206. for k, v in ipairs(tCraftCompletion) do
  207. if v ~= true then
  208. return true
  209. end
  210. end
  211. return false
  212. end
  213.  
  214. -- When called this turtle will craft a recipe
  215. function craftItems(sItemName, nRecipeUsed, nItemsToCraft, nTurnTimes)
  216. nRecipeUsed = nRecipeUsed or 1
  217. nItemsToCraft = nItemsToCraft or 1
  218. nTurnTimes = nTurnTimes or 0
  219. local errLevel = 2
  220. if nItemsToCraft == -1 then errLevel = 3 end
  221. if not recipes[sItemName] then
  222. error("to craft '"..sItemName.."' you must first craft it using turtle.craft, or use crafting.addNewRecipe to add a recipe to the table.", errLevel)
  223. elseif not recipes[sItemName][nRecipeUsed] then
  224. nRecipeUsed = 1
  225. end
  226. currentRecipe = recipes[sItemName][nRecipeUsed]
  227. for k=1, 9 do
  228. tCraftCompletion[k] = false
  229. end
  230. if #tItemSlotsToDrop == 0 then
  231. local addToTable = true
  232. for k=1, 16 do
  233. addToTable = true
  234. for k2, v in pairs(tCraftingTable) do
  235. if k == v then
  236. addToTable = false
  237. break
  238. end
  239. end
  240. if addToTable then
  241. tItemSlotsToDrop[#tItemSlotsToDrop + 1] = k
  242. end
  243. end
  244. end
  245. local advance = false
  246. local loops = 0
  247. local firstSlotEmpty = 0
  248. while nItemsToCraft > 0 do
  249. loops = 0
  250. while craftingNotComplete() do
  251. for k, v in ipairs(tCraftingTable) do
  252. if not currentRecipe[k] then
  253. currentRecipe[k] = {""}
  254. end
  255. tCraftCompletion[k] = checkCraftingSlot(k, v)
  256. sleep()
  257. end
  258. end
  259. for k, v in ipairs(tItemSlotsToDrop) do
  260. if turtle.getItemCount(v) > 0 then -- This doesn't belong here according to ComputerCraft, so it needs to go.
  261. turtle.select(v)
  262. turtle.drop(64)
  263. end
  264. end
  265. turtle.select(nOutputSlot)
  266. local itemsGenerated = currentRecipe["ItemsGenerated"] or 1
  267. if turtle.craft(nItemsToCraft) then
  268. if nTurnTimes > 0 then
  269. for k=1, nTurnTimes do
  270. turtle.turnRight()
  271. end
  272. else
  273. for k=1, nTurnTimes do
  274. turtle.turnLeft()
  275. end
  276. end
  277. nItemsToCraft = nItemsToCraft - turtle.getItemCount(nOutputSlot)
  278. turtle.drop(64)
  279. if nTurnTimes > 0 then
  280. for k=1, nTurnTimes do
  281. turtle.turnLeft()
  282. end
  283. else
  284. for k=1, nTurnTimes do
  285. turtle.turnRight()
  286. end
  287. end
  288. end
  289. sleep()
  290. while turtle.suckUp(64) do
  291. turtle.drop(64)
  292. end
  293. end
  294. end
  295.  
  296. -- When called the turtle turns into an automatic crafting table that crafts the item you want.
  297. function autoCraftingTable(sItemName, nRecipeUsed, nTurnTimes)
  298. local advance = false
  299. while true do
  300. craftItems(sItemName, nRecipeUsed, -1, nTurnTimes)
  301. end
  302. end
  303.  
  304. -- Returns the full item name of an already available item.
  305. function getFullItemName(sItemNameSub)
  306. for k, v in pairs(recipes) do
  307. if string.find(string.lower(k), string.lower(sItemNameSub)) then
  308. return k
  309. end
  310. end
  311. return false
  312. end
  313.  
  314. -- Override the turtle.craft function with one that teaches the turtle a recipe.
  315. function turtle.craft(amount)
  316. amount = amount or 64
  317. local tItemsInCraftingGrid = {}
  318. for k, v in ipairs(tCraftingTable) do
  319. local item = turtle.getItemDetail(v)
  320. if item then
  321. tItemsInCraftingGrid[k] = {[1] = item["name"], [2] = item["damage"]}
  322. else
  323. tItemsInCraftingGrid[k] = {""}
  324. end
  325. end
  326. local returnVal = false
  327. if turtleCraft(math.min(amount, 64)) then
  328. returnVal = true
  329. if turtle.getItemDetail(turtle.getSelectedSlot()) then
  330. local item = turtle.getItemDetail(turtle.getSelectedSlot())
  331. if not recipes[item["name"]] then
  332. addNewRecipe(item["name"], 1, false, tItemsInCraftingGrid)
  333. end
  334. end
  335. end
  336. return returnVal
  337. end
  338.  
  339. -- Load the local recipes from the hard disk, or download the recipes from the server if possible.
  340. if not loadRecipeList() then
  341. updateRecipesFromServer()
  342. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement