Advertisement
Ubidibity

Ultimate Crafting Turtle (ENG) v.5

Jan 5th, 2024
1,017
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- Adapted from Marval's pastebin b2fc4912 but converted to English via ChatGPT
  2. -- All credit goes to Marval.  This v.5 is untested as of yet, and likely needs some post-AI tweaking.
  3.  
  4. -- Initialize the peripheral analyzer on the right side of the turtle
  5. local analyzer = peripheral.wrap("right")
  6.  
  7. -- Define crafting slot positions
  8. local craftingSlots = {1,2,3,5,6,7,9,10,11}
  9.  
  10. -- Initialize the tables
  11. local x = {}
  12. local tCraft = {}
  13.  
  14. -- Function to drop all items from the turtle's inventory
  15. local function dropAllItems()
  16.     for i = 1, 16 do
  17.         if turtle.getItemCount(i) > 0 then
  18.             turtle.select(i)
  19.             turtle.drop()
  20.         end
  21.     end
  22. end
  23.  
  24. -- Function to count items in the crafting grid
  25. local function countItems(craftingGrid)
  26.     local countList = {}
  27.     for i = 1, 9 do
  28.         countList[i] = {ID = nil, META = nil, COUNT = 0}
  29.     end
  30.  
  31.     -- Find the first non-empty slot
  32.     local startIndex = 0
  33.     for i = 1, 9 do
  34.         if craftingGrid[i][1] ~= nil then
  35.             countList[1].ID = craftingGrid[i][1]
  36.             countList[1].META = craftingGrid[i][2]
  37.             countList[1].COUNT = 1
  38.             startIndex = i
  39.             break
  40.         end
  41.     end
  42.  
  43.     -- Count the rest of the items
  44.     local itemCount = 1
  45.     for i = startIndex + 1, 9 do
  46.         local itemFound = false
  47.         if craftingGrid[i][1] ~= nil then
  48.             local itemId = craftingGrid[i][1]
  49.             local itemMeta = craftingGrid[i][2]
  50.  
  51.             for j = 1, itemCount do
  52.                 if itemId == countList[j].ID and itemMeta == countList[j].META then
  53.                     countList[j].COUNT = countList[j].COUNT + 1
  54.                     itemFound = true
  55.                     break
  56.                 end
  57.             end
  58.  
  59.             if not itemFound then
  60.                 itemCount = itemCount + 1
  61.                 countList[itemCount].ID = itemId
  62.                 countList[itemCount].META = itemMeta
  63.                 countList[itemCount].COUNT = 1
  64.             end
  65.         end
  66.     end
  67.  
  68.     return countList, itemCount
  69. end
  70. -- Function to check if all required items are available
  71. local function checkAvailability(items, recordCount)
  72.     local isAvailable = true
  73.     local missingItem = nil
  74.  
  75.     for i = 1, recordCount do
  76.         local slot = 0
  77.         local itemId = 0
  78.         local itemMeta = 0
  79.         local itemCount = 0
  80.  
  81.         repeat
  82.             slot = slot + 1
  83.             itemId = analyzer.getBlockIdAt(slot)
  84.             itemMeta = analyzer.getBlockMetadataAt(slot)
  85.  
  86.             if itemId == items[i].ID and (items[i].META == nil or itemMeta == items[i].META) then
  87.                 itemCount = itemCount + analyzer.getBlockCountAt(slot)
  88.             end
  89.         until slot == 109
  90.  
  91.         if itemCount < items[i].COUNT then
  92.             isAvailable = false
  93.             missingItem = items[i].META == nil and items[i].ID or (items[i].ID .. ":" .. items[i].META)
  94.             print("Missing item ID: " .. missingItem .. " in quantity: " .. items[i].COUNT - itemCount)
  95.             break
  96.         end
  97.     end
  98.  
  99.     return isAvailable, missingItem
  100. end
  101.  
  102. -- Function to perform the crafting operation
  103. local function craft(items)
  104.     for i = 1, 9 do
  105.         if items[i][1] ~= nil then
  106.             local slot = 0
  107.             repeat
  108.                 slot = slot + 1
  109.                 local itemId = analyzer.getBlockIdAt(slot)
  110.                 local itemMeta = analyzer.getBlockMetadataAt(slot)
  111.             until (itemId == items[i][1] and (items[i][2] == nil or itemMeta == items[i][2]))
  112.  
  113.             local itemCount = analyzer.getBlockCountAt(slot)
  114.             turtle.select(craftingSlots[i])
  115.             analyzer.takeAt(slot)
  116.             turtle.drop(itemCount - 1)
  117.         end
  118.     end
  119.  
  120.     turtle.craft()
  121.     dropAllItems()
  122. end
  123.  
  124. -- Function to manage the crafting process
  125. local function manageCrafting(recipe)
  126.     print("Crafting " .. b)
  127.     local isReadyToCraft = false
  128.  
  129.     while not isReadyToCraft do
  130.         local countList, _ = countItems(recipe)
  131.         isReadyToCraft, missingItem = checkAvailability(countList)
  132.  
  133.         if not isReadyToCraft then
  134.             print("Missing " .. missingItem)
  135.             missingItem = tostring(missingItem)
  136.             -- Assuming 'crafting' is a function that handles missing items
  137.             crafting()
  138.         else
  139.             craft(recipe)
  140.         end
  141.     end
  142. end
  143.  
  144. -- Function to handle crafting based on user input
  145. local function crafting()
  146.     if tCraft[b] then
  147.         manageCrafting(tCraft[b])
  148.     else
  149.         print("Missing: " .. b)
  150.         os.pullEvent() -- Wait for an event, possibly user input
  151.     end
  152. end
  153.  
  154. -- Function to start the crafting process
  155. local function startCrafting()
  156.     local file = io.open("receptury", "r") -- Open the recipe file
  157.     while true do
  158.         local line = file:read()
  159.         if line == nil then break end
  160.  
  161.         -- Parse the recipe line
  162.         local item, recipeParts = string.match(line, "([%w%:]+)=(.+)")
  163.  
  164.         -- Store the parsed recipe
  165.         tCraft[item] = {}
  166.         for i = 1, 9 do
  167.             local part = select(i, string.match(recipeParts, "([^;]+)"))
  168.             if part == "0" then
  169.                 tCraft[item][i] = {nil}
  170.             elseif string.find(part, ":") then
  171.                 local id, meta = string.match(part, "(%d+):(%d+)")
  172.                 tCraft[item][i] = {tonumber(id), tonumber(meta)}
  173.             else
  174.                 tCraft[item][i] = {tonumber(part)}
  175.             end
  176.         end
  177.     end
  178.     file:close()
  179.  
  180.     -- Ask user for the item to craft and the quantity
  181.     print("What to craft? Enter ID or ID:META")
  182.     b = read()
  183.     local originalItem = b
  184.     print("How many?")
  185.     local quantity = tonumber(read())
  186.  
  187.     -- Craft the specified quantity of the item
  188.     for zz = 1, quantity do
  189.         crafting()
  190.         b = originalItem
  191.     end
  192. end
  193.  
  194. -- Function to display the main menu
  195. local function displayMenu()
  196.     term.clear() -- Clear the terminal screen
  197.     local option = 2 -- Initialize the default selected option
  198.  
  199.     -- Set the cursor position and write menu options
  200.     term.setCursorPos(1, 1)
  201.     term.write("Ultimate Crafting Program")
  202.     term.setCursorPos(1, 2)
  203.     term.write("[ ] Start Crafting") -- "Craftuj" translates to "Start Crafting"
  204.     term.setCursorPos(1, 3)
  205.     term.write("[ ] Add Recipe by Scanning") -- "Dodaj recepture przez skanowanie"
  206.     term.setCursorPos(1, 4)
  207.     term.write("[ ] Add Recipe Manually") -- "Dodaj recepture przez wpisanie"
  208. end
  209.  
  210. -- Function to refresh the menu display
  211. local function refreshMenu()
  212.     -- Assume 'option' is a global or externally managed variable
  213.     for i = 2, 10 do
  214.         term.setCursorPos(2, i)
  215.         term.write(" ")
  216.     end
  217.     term.setCursorPos(2, option) -- Update the display to show the selected option
  218.     term.write("X")
  219. end
  220.  
  221. -- Function to scan and save a new crafting recipe
  222. local function saveScannedRecipe()
  223.     print("Arrange the recipe in the turtle's inventory")
  224.     os.pullEvent() -- Wait for an event, likely user arrangement of items
  225.     local recipe = {}
  226.    
  227.     for i = 1, 9 do
  228.         turtle.select(craftingSlots[i]) -- Select slot
  229.         local id = analyzer.getBlockId() -- Get block id
  230.         if id then
  231.             recipe[i] = {ID = id, META = analyzer.getBlockMetadata()} -- Assign id and meta
  232.         else
  233.             recipe[i] = {ID = nil} -- Assign nil if empty
  234.         end
  235.     end
  236.  
  237.     -- Convert the recipe to a string format
  238.     local recipeString = {}
  239.     for i = 1, 9 do
  240.         if recipe[i].ID == nil then
  241.             recipeString[i] = "0"
  242.         elseif recipe[i].META == nil then
  243.             recipeString[i] = tostring(recipe[i].ID)
  244.         else
  245.             recipeString[i] = recipe[i].ID .. ":" .. recipe[i].META
  246.         end
  247.     end
  248.  
  249.     turtle.craft()
  250.     turtle.select(11)
  251.     local craftedItem = analyzer.getBlockId() .. ":" .. analyzer.getBlockMetadata()
  252.     local file = io.open("receptury", "a") -- Open file for appending
  253.     file:write(string.format("%s=%s;%s;%s;%s;%s;%s;%s;%s;%s\n", craftedItem, unpack(recipeString)))
  254.     file:close()
  255. end
  256.  
  257. -- Function to manually input and save a new recipe
  258. local function inputAndSaveRecipe()
  259.     term.clear()
  260.     print("Enter the recipe in the format: ")
  261.     print("ID:META=ID:META;ID:META; ... ;ID:META")
  262.     print("You can also input IDs without metadata")
  263.     local newRecipe = read()
  264.  
  265.     local file = io.open("receptury", "a") -- Open file for appending
  266.     file:write(newRecipe .. "\n")
  267.     file:close()
  268. end
  269.  
  270. -- Main loop for menu navigation and action selection
  271. displayMenu()
  272. refreshMenu()
  273.  
  274. while true do
  275.     local event, keyCode = os.pullEvent("key")
  276.  
  277.     -- Navigate through the menu
  278.     if keyCode == 208 and option < 4 then -- Arrow Down
  279.         option = option + 1
  280.     elseif keyCode == 200 and option > 2 then -- Arrow Up
  281.         option = option - 1
  282.     end
  283.  
  284.     -- Select a menu option
  285.     if keyCode == 28 then -- Enter key
  286.         term.clear()
  287.         term.setCursorPos(1, 1)
  288.         if option == 2 then
  289.             startCrafting()
  290.         elseif option == 3 then
  291.             saveScannedRecipe()
  292.         elseif option == 4 then
  293.             inputAndSaveRecipe()
  294.         end
  295.         displayMenu()
  296.         refreshMenu()
  297.     end
  298. end
  299.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement