Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local component = require("component")
- local robot = require("robot")
- local inventory_controller = component.inventory_controller
- local crafting = component.crafting
- local fs = require("filesystem")
- local os = require("os")
- local LABELS_FILE = "/home/labels.txt"
- local TEMPLATES_FOLDER = "/home/templates"
- local function mysplit (inputstr, sep)
- if sep == nil then
- sep = "%s"
- end
- local t={}
- for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
- table.insert(t, str)
- end
- return t
- end
- local function readFile(path)
- if not fs.exists(path) then
- return false
- else
- local f_h = fs.open(path, "r")
- local rtn = f_h:read(fs.size(path))
- f_h:close()
- return rtn
- end
- end
- local function readFileLines(path)
- if not fs.exists(path) then
- return false
- end
- local rtn = {}
- local f_h = fs.open(path, "r")
- local curr_char = f_h:read(1)
- local curr_line_contents = ""
- while curr_char do
- if curr_char == "\n" then
- rtn[#rtn+1] = curr_line_contents
- curr_line_contents = ""
- else
- curr_line_contents = curr_line_contents .. curr_char
- end
- curr_char = f_h:read(1)
- end
- rtn[#rtn+1] = curr_line_contents
- curr_line_contents = ""
- f_h:close()
- return rtn
- end
- local function writeFile(path, data_string)
- local f_h = fs.open(path, "w")
- f_h:write(data_string)
- f_h:close()
- end
- local function getInventorySize()
- return inventory_controller.getInventorySize(3)
- end
- local function getStackInSlot(slot)
- return inventory_controller.getStackInSlot(3, slot)
- end
- local function getStackInInternalSlot(slot)
- return inventory_controller.getStackInInternalSlot(slot)
- end
- local function suckFromSlot(slot, amount)
- return inventory_controller.suckFromSlot(3, slot, amount)
- end
- local function searchChestForItem(item_label, complex)
- for s=1, 54 do
- local stack_info = getStackInSlot(s)
- if stack_info then
- if stack_info["label"] == item_label then
- if complex then
- local rtn = {}
- rtn["slot"] = s
- rtn["amount"] = stack_info["size"]
- return rtn
- else
- return s
- end
- end
- end
- if (s % 5 == 0) then
- os.sleep(0.1)
- end
- end
- return false
- end
- local function chestContainsItemAmount(item_label, amount)
- local current_amount = 0
- for s=1, 54 do
- local stack_info = getStackInSlot(s)
- if stack_info then
- if stack_info["label"] == item_label then
- current_amount = current_amount + stack_info["size"]
- end
- end
- if current_amount >= amount then
- return true
- end
- if (s % 5 == 0) then
- os.sleep(0.1)
- end
- end
- return false
- end
- local function getCraftingSlot(slot)
- if slot <= 3 then
- return slot
- elseif slot <= 6 then
- return slot + 1
- else
- return slot + 2
- end
- end
- local item_labels = {}
- local function loadItemLabels()
- item_labels = {}
- if not fs.exists(LABELS_FILE) then
- writeFile(LABELS_FILE, "")
- return
- end
- local label_lines = readFileLines(LABELS_FILE)
- for l=1, #label_lines do
- item_labels[l] = label_lines[l]
- end
- end
- local function getIdByLabel(label)
- for l=1, #item_labels do
- if item_labels[l] == label then
- return l
- end
- end
- local labels_raw = readFile(LABELS_FILE)
- if not labels_raw then
- labels_raw = ""
- end
- if not (labels_raw == "") then
- labels_raw = labels_raw .. "\n"
- end
- labels_raw = labels_raw .. label
- writeFile(LABELS_FILE, labels_raw)
- item_labels[#item_labels+1] = label
- return #item_labels
- end
- local CRAFT_TEMPLATE_SLOTS = {1, 2, 3, 10, 11, 12, 19, 20, 21}
- local CRAFT_TEMPLATE_RESULT_SLOT = 4
- local function getTemplateSlotItems()
- local rtn = {}
- for i=1, #CRAFT_TEMPLATE_SLOTS do
- if CRAFT_TEMPLATE_SLOTS[i] then
- local stack_info = getStackInSlot(CRAFT_TEMPLATE_SLOTS[i])
- if stack_info then
- rtn[i] = getIdByLabel(stack_info["label"])
- else
- rtn[i] = getIdByLabel("none")
- end
- end
- end
- return rtn
- end
- local function saveCraftTemplate(result_label_arg)
- if not fs.exists(TEMPLATES_FOLDER) then
- fs.makeDirectory(TEMPLATES_FOLDER)
- end
- local result_label = result_label_arg
- if not result_label_arg then
- result_label = getStackInSlot(CRAFT_TEMPLATE_RESULT_SLOT)["label"]
- end
- local result_item = getIdByLabel(result_label)
- local template_file = TEMPLATES_FOLDER .. "/" .. tostring(result_item) .. ".txt"
- if fs.exists(template_file) then
- print("ERROR: Template with name " .. result_label .. " (" .. tostring(result_item) .. ") already exists!")
- return
- end
- local slot_items = getTemplateSlotItems()
- local template_raw = ""
- for s=1, 9 do
- template_raw = template_raw .. tostring(slot_items[s]) .. "\n"
- end
- writeFile(template_file, template_raw)
- end
- local pending_craft_templates = {}
- local function templateExists(item_id)
- return fs.exists(TEMPLATES_FOLDER .. "/" .. tostring(item_id) .. ".txt")
- end
- local function getTemplateItemTotals(template_id)
- local rtn = {}
- local rtn_map = {}
- local template_lines = readFileLines(TEMPLATES_FOLDER .. "/" .. tostring(template_id) .. ".txt")
- local noneId = getIdByLabel("none")
- for s=1, 9 do
- if not (tonumber(template_lines[s]) == noneId) then
- local item_id_str = "id:" .. template_lines[s]
- if rtn_map[item_id_str] then
- rtn[rtn_map[item_id_str]]["total"] = rtn[rtn_map[item_id_str]]["total"] + 1
- rtn[rtn_map[item_id_str]]["slots"][#rtn[rtn_map[item_id_str]]["slots"]+1] = s
- else
- local new_obj = {}
- new_obj["id"] = tonumber(template_lines[s])
- new_obj["slots"] = {s}
- new_obj["total"] = 1
- rtn[#rtn+1] = new_obj
- rtn_map[item_id_str] = #rtn
- end
- end
- end
- return rtn
- end
- local function collectItemFromChest(item_label, amount)
- robot.select(16)
- local collected_amount = 0
- while collected_amount < amount do
- local item_slot = searchChestForItem(item_label)
- if item_slot then
- suckFromSlot(item_slot, amount)
- else
- if robot.count(16) > 0 then
- robot.drop()
- end
- return false
- end
- collected_amount = robot.count(16)
- end
- return true
- end
- local function requiredTemplateItems(template_id)
- local template_items = getTemplateItemTotals(template_id)
- local rtn = {}
- for i=1, #template_items do
- local chest_contains_items = chestContainsItemAmount(item_labels[template_items[i]["id"]], template_items[i]["total"])
- if not chest_contains_items then
- rtn[#rtn+1] = template_items[i]
- end
- end
- return rtn
- end
- local function craftItem(item_id)
- if not templateExists(item_id) then
- print("ERROR: Not enough un-craftable " .. item_labels[item_id] .. " for operation!")
- os.exit()
- end
- local required_items = requiredTemplateItems(item_id)
- while #required_items > 0 do
- for r=1, #required_items do
- -- local pending_id = "id:" .. tostring(required_items[r]["id"])
- -- if not pending_craft_templates[pending_id] then
- craftItem(required_items[r]["id"])
- -- pending_craft_templates[pending_id] = true
- -- end
- end
- required_items = requiredTemplateItems(item_id)
- end
- robot.select(16)
- local template_items = getTemplateItemTotals(item_id)
- for i=1, #template_items do
- collectItemFromChest(item_labels[template_items[i]["id"]], template_items[i]["total"])
- for s=1, #template_items[i]["slots"] do
- robot.transferTo(getCraftingSlot(template_items[i]["slots"][s]), 1)
- end
- end
- crafting.craft()
- robot.drop()
- -- if pending_craft_templates["id:" .. tostring(item_id)] then
- -- pending_craft_templates["id:" .. tostring(item_id)] = false
- -- end
- end
- loadItemLabels()
- local argv = {...}
- local mode = argv[1] -- "template" or "craft" or "search"
- if mode == "template" then -- "template" to get the result from the chest, "template result_label" to manually set the label.
- saveCraftTemplate(argv[2])
- elseif mode == "craft" then -- "craft template_id amount_number"
- robot.turnLeft()
- argv[3] = argv[3] or 1
- for i=1, tonumber(argv[3]) do
- craftItem(tonumber(argv[2]))
- end
- robot.turnRight()
- elseif mode == "search" then -- "search search_string_here"
- if not argv[2] then
- print("ERROR: Invalid search string!")
- else
- local search_results = ""
- for i=1, #item_labels do
- if string.find(item_labels[i]:lower(), argv[2]:lower()) then
- search_results = search_results .. "[" .. tostring(i) .. "] " .. item_labels[i] .. "\n"
- end
- end
- if search_results == "" then
- print("No templates matched item " .. argv[2])
- else
- print(search_results)
- end
- end
- elseif mode then
- print("ERROR: Mode " .. mode .. " is invalid!")
- end
Add Comment
Please, Sign In to add comment