Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Recipe Recorder Program with Graphical Display and Duplicate Check
- local turtleName = "turtle_2"
- local fromInventories = {}
- -- Load API
- if not fs.exists("API") then
- shell.run("pastebin", "get", "EzkfU5ZM", "API")
- end
- shaka = require("API")
- fromInventories = shaka.readFile("inventories")
- -- Fixed slots
- local inputSlots = {5, 6, 7, 9, 10, 11, 13, 14, 15}
- local outputSlot = 16
- local readyToGo = false
- local errorCheck = false
- local filename = "items_list.lua"
- local duplicates = false
- -- Function to check if a table contains a value
- local function containsValue(tbl, value)
- for _, v in ipairs(tbl) do
- if v == value then
- return true
- end
- end
- return false
- end
- local function getInventories()
- if not wiredModem then
- print("No wired modem detected. Cannot fetch inventories.")
- return
- end
- local remotePeripherals = wiredModem.getNamesRemote()
- for _, inventoryName in ipairs(remotePeripherals) do
- if inventoryName and not shaka.stringFind(inventoryName, "turtle") and not shaka.stringFind(inventoryName, "computer") then
- if not tableContains(fromInventories, inventoryName) then
- table.insert(fromInventories, inventoryName)
- end
- end
- end
- shaka.writeFile("inventories", fromInventories)
- end
- getInventories()
- -- Function to read the state of the slots
- local function getSlotStates()
- local states = {}
- for slot = 1, 16 do
- states[slot] = turtle.getItemDetail(slot) ~= nil
- end
- return states
- end
- -- Function to read the list from the file
- local function readList()
- local list = {}
- if fs.exists(filename) then
- local file = fs.open(filename, "r") -- Open file in read mode
- local content = file.readAll() -- Read the content of the file
- file.close()
- -- Check if content is valid
- if content then
- -- Deserialize the content into a Lua table
- local success, result = pcall(load("return " .. content))
- if success and type(result) == "table" then
- list = result -- Assign the loaded table to 'list'
- print("List loaded successfully.") -- Debugging line
- else
- print("Error: Loaded content is not a valid table.") -- Debugging line
- end
- end
- else
- print("File not found.") -- Debugging line if file doesn't exist
- end
- return list
- end
- -- Adjusted function to make the grid fit better
- local function drawDisplay(states)
- term.clear()
- term.setCursorPos(1, 1)
- -- Define grid layout with 1 row per slot
- local grid = {
- {1, 2, 3, 4},
- {5, 6, 7, 8},
- {9, 10, 11, 12},
- {13, 14, 15, 16},
- }
- local squareSize = 3 -- Square size reduced to 3 for better fit
- local columnSpacing = 1 -- Small space between columns
- local rowSpacing = 0 -- Reduced space between rows to 0 for a tighter fit
- -- Draw the grid with small spacing
- for rowIndex, row in ipairs(grid) do
- for colIndex, slot in ipairs(row) do
- local x = (colIndex - 1) * (squareSize + columnSpacing) + 2
- local y = (rowIndex - 1) * (squareSize + rowSpacing) + 2
- term.setCursorPos(x, y)
- -- Determine square color
- if containsValue(inputSlots, slot) then
- term.setBackgroundColor(states[slot] and colors.green or colors.lightGray)
- elseif slot == outputSlot then
- term.setBackgroundColor(states[slot] and colors.cyan or colors.orange)
- else
- term.setBackgroundColor(states[slot] and colors.red or colors.gray)
- end
- -- Draw the square (3 spaces wide and tall)
- term.write(string.rep(" ", squareSize)) -- 3 spaces wide for the square
- term.setCursorPos(x, y + 1)
- term.write(string.rep(" ", squareSize)) -- 3 spaces tall for the square
- term.setBackgroundColor(colors.black) -- Reset color
- end
- end
- -- Move the explanation back to the bottom
- term.setCursorPos(22, 11)
- term.setTextColor(colors.cyan)
- write("Input")
- term.setCursorPos(22, 12) -- Position the explanation at the bottom
- term.setTextColor(colors.blue)
- write("Output")
- term.setCursorPos(22, 3)
- term.setTextColor(colors.green)
- write("C to save recipe")
- term.setCursorPos(22, 5)
- term.setTextColor(colors.orange)
- write("Q to quit")
- end
- -- Function to load existing recipes
- local function loadRecipes(filePath)
- if fs.exists(filePath) then
- local file = fs.open(filePath, "r")
- local content = file.readAll()
- file.close()
- if content and content ~= "" then
- return textutils.unserialize(content) or {}
- end
- end
- return {}
- end
- -- Function to check for duplicate recipes
- local function isDuplicateRecipe(outputItem, recipes)
- for _, recipe in ipairs(recipes) do
- local existingOutput = recipe.output[1]
- if existingOutput.name == outputItem.name and existingOutput.count == outputItem.count then
- return true
- end
- end
- return false
- end
- -- Function to record a crafting recipe
- local function recordRecipe(inputItems, outputItem)
- local recipe = {
- input = inputItems,
- output = {
- {
- name = outputItem.name,
- count = outputItem.count,
- },
- },
- }
- -- File path for recipes
- local filePath = "recipes/recipes.lua"
- -- Load existing recipes
- local recipes = loadRecipes(filePath)
- -- Check for duplicates
- if isDuplicateRecipe(outputItem, recipes) then
- shaka.clearScreen()
- term.setTextColor(colors.red)
- print("This recipe already exists.\nSkipping save.")
- sleep(1)
- drawDisplay(getSlotStates())
- duplicates = true
- return
- end
- -- Add the new recipe to the recipes table
- table.insert(recipes, recipe)
- -- Save the updated recipes back to the file
- local file = fs.open(filePath, "w")
- file.write(textutils.serialize(recipes))
- file.close()
- -- shaka.clearScreen()
- -- print("Recipe saved for "..outputItem.name)
- -- sleep(1)
- -- drawDisplay(getSlotStates())
- end
- -- Function to read items from fixed slots
- local function getInputItems()
- local inputItems = {}
- for _, slot in ipairs(inputSlots) do
- local item = turtle.getItemDetail(slot)
- if item then
- table.insert(inputItems, {slot = slot, name = item.name})
- else
- table.insert(inputItems, {slot = slot, type = "empty"})
- end
- end
- return inputItems
- end
- -- Function to read item from the fixed output slot
- local function getOutputItem()
- local item = turtle.getItemDetail(outputSlot)
- if item then
- return {slot = outputSlot, name = item.name, count = item.count}
- else
- return nil
- end
- end
- -- Function to create a recipe
- local function createRecipe()
- local inputItems = getInputItems()
- local outputItem = getOutputItem()
- if not outputItem then
- shaka.clearScreen()
- print("Error: No item in output slot (16). Place the resulting item there.")
- sleep(2)
- errorCheck = true
- drawDisplay(getSlotStates())
- return
- end
- local emptyInputs = true
- for _, item in ipairs(inputItems) do
- if item.name then
- emptyInputs = false
- break
- end
- end
- if emptyInputs then
- shaka.clearScreen()
- print("Error: No items in input slots (5, 6, 7, 9, 10, 11, 13, 14, 15). Place the input items there.")
- sleep(2)
- errorCheck = true
- drawDisplay(getSlotStates())
- return
- end
- recordRecipe(inputItems, outputItem)
- end
- function findAvailableDrop(slot)
- local tasks = {}
- for i = 1, #fromInventories do
- local invWrap = peripheral.wrap(fromInventories[i])
- tasks[#tasks+1] = function()
- invWrap.pullItems(turtleName, slot)
- end
- end
- parallel.waitForAll(unpack(tasks))
- end
- function dropInventory()
- local tasks = {}
- for i = 1, 16 do
- if turtle.getItemCount(i) > 0 then
- tasks[#tasks+1] = function()
- repeat
- findAvailableDrop(i)
- until turtle.getItemCount(i) == 0
- end
- end
- end
- parallel.waitForAll(unpack(tasks))
- end
- function proceedAfterCraft()
- if duplicates == true then
- return
- end
- local product = getOutputItem()
- -- Handle case where product might be nil
- if not product or not product.name then
- error("No product found. Unable to proceed.")
- end
- local options = {
- "- Add item to autocraft list",
- "- Record next recipe",
- }
- local selected = 1
- -- Function to render the UI
- local function renderUI()
- shaka.clearScreen()
- setTextStyle(colors.gray, colors.green)
- term.clearLine()
- shaka.centerText("Added recipe for:")
- -- Display product name
- setTextStyle(colors.gray, colors.green)
- term.setCursorPos(1, 3)
- shaka.centerText(shaka.prettyName(product.name))
- -- Display options
- for i, option in ipairs(options) do
- if i == selected then
- setTextStyle(colors.black, colors.yellow) -- Highlight selected option
- else
- setTextStyle(colors.black, colors.lightGray) -- Normal style
- end
- term.setCursorPos(1, 5 + i)
- print(option)
- end
- end
- -- Function to handle input
- local function handleInput()
- while true do
- local event, param1, param2, param3 = os.pullEvent()
- if event == "key" then
- local key = param1
- if key == keys.w or key == keys.up then
- selected = selected - 1
- if selected < 1 then
- selected = #options
- end
- renderUI()
- elseif key == keys.s or key == keys.down then
- selected = selected + 1
- if selected > #options then
- selected = 1
- end
- renderUI()
- elseif key == keys.enter or key == keys.space then
- return selected
- end
- elseif event == "mouse_scroll" then
- local direction = param1
- selected = selected + direction
- if selected < 1 then
- selected = #options
- elseif selected > #options then
- selected = 1
- end
- renderUI()
- elseif event == "mouse_click" then
- local button, x, y = param1, param2, param3
- for i = 1, #options do
- if y == 4 + i then -- Check if the click is on an option
- selected = i
- renderUI()
- if button == 1 then -- Left-click confirms
- return selected
- end
- end
- end
- end
- end
- end
- -- Helper function for setting text style
- function setTextStyle(background, text)
- shaka.changeColors(background, text)
- end
- -- Initial render and input loop
- renderUI()
- local choice = handleInput()
- -- Act based on the choice
- if choice == 1 then
- local craftList = shaka.readFile(filename)
- shaka.changeColors(colors.gray, colors.white)
- term.clearLine()
- shaka.nextLine()
- shaka.changeColors(colors.black, colors.white)
- write("Amount:")
- shaka.changeColors(colors.black, colors.yellow)
- local amount = tonumber(read())
- if amount ~= nil then
- table.insert(craftList, {name = product.name, amount = amount})
- shaka.changeColors(colors.black, colors.green)
- print("Added ", shaka.prettyName(product.name), " x ", amount)
- shaka.writeFile(filename, craftList)
- dropInventory()
- sleep(1)
- drawDisplay(getSlotStates())
- else
- term.setTextColor(colors.red)
- print("Invalid entry, try again.")
- sleep(1)
- proceedAfterCraft()
- end
- elseif choice == 2 then
- print("Recording next recipe...")
- dropInventory()
- sleep(1)
- drawDisplay(getSlotStates())
- -- Add functionality for this choice
- end
- end
- -- Function to monitor inventory changes and handle input
- local function monitorAndSave()
- while true do
- local event, key = os.pullEvent()
- if event == "turtle_inventory" then
- local states = getSlotStates()
- drawDisplay(states)
- elseif event == "key" then
- if key == keys.c or key == keys.enter then
- duplicates = false
- createRecipe()
- if errorCheck == false then
- proceedAfterCraft()
- end
- elseif key == keys.q then
- os.reboot()
- break
- end
- end
- end
- end
- -- Main function
- local function main()
- drawDisplay(getSlotStates())
- monitorAndSave()
- end
- -- Execute the main function
- main()
- -- proceedAfterCraft()
Add Comment
Please, Sign In to add comment