Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- function save(tbl, name)
- local file = fs.open(name, "w")
- file.write(textutils.serialize(tbl))
- file.close()
- end
- function load(name)
- local file = fs.open(name, "r")
- if not file then
- if name == "open_positions" then
- save({{x=-5,y=3,z=-5,side="down"}}, name)
- else
- save({}, name)
- end
- return load(name)
- else
- local data = file.readAll()
- file.close()
- return textutils.unserialize(data)
- end
- end
- function clear_search_bar()
- term.setTextColor(colors.cyan)
- paintutils.drawFilledBox(1,screen_height,screen_width,screen_height,colors.gray)
- term.setCursorPos(1,screen_height)
- end
- function show_title(title)
- paintutils.drawLine(1,1,screen_width,1,colors.cyan)
- term.setCursorPos(1,1)
- term.write(title)
- clear_search_bar()
- end
- function empty_inventory(side)
- for i=1, 15 do
- inventory.pushItem(side, i)
- end
- end
- function condense_inventory()
- inventory.condenseItems()
- local inventory_items = inventory.getAllStacks()
- inventory.swapStacks(#inventory_items, 16)
- return inventory_items
- end
- function next_position(position)
- local new_position = {x = position.x, y = position.y, z = position.z, side = position.side}
- if position.side == "down" then
- new_position.side = "up"
- else
- new_position.side = "down"
- if position.x == 5 then
- new_position.x = -5
- if position.z == 5 then
- new_position.z = -5
- new_position.y = position.y + 3
- else
- new_position.z = position.z + 1
- end
- else
- if position.x == -1 and position.z == 0 then
- new_position.x = position.x + 2
- else
- new_position.x = position.x + 1
- end
- end
- end
- return new_position
- end
- function earliest_order(position_1, position_2)
- if position_1.y > position_2.y then
- return true
- elseif position_1.y == position_2.y then
- if position_1.z > position_2.z then
- return true
- elseif position_1.z == position_2.z then
- if position_1.x > position_2.x then
- return true
- elseif position_1.x == position_2.x then
- if position_1.side == "up" then
- return true
- end
- end
- end
- end
- end
- function next_open_position()
- if #open_positions > 1 then
- table.sort(open_positions, earliest_order)
- return table.remove(open_positions)
- else
- local position = table.remove(open_positions)
- table.insert(open_positions, next_position(position))
- return position
- end
- end
- function safe_string(text)
- local new_text = {}
- for i = 1, #text do
- local val = string.byte(text, i)
- new_text[i] = (val > 31 and val < 127) and val or 32
- end
- return string.char(unpack(new_text))
- end
- function register_item(stack)
- local string_id = stack.id..stack.dmg..stack.raw_name..stack.display_name
- stack.string_id = safe_string(string_id)
- for _, existing_item in ipairs(items) do
- if existing_item.string_id == stack.string_id then
- local item = existing_item
- break
- end
- end
- if not item then
- item = {}
- item.string_id = stack.string_id
- item.damage = stack.dmg
- item.max_damage = stack.max_dmg
- item.max_stack = stack.max_size
- item.recipes = {}
- item.quantity = 0
- item.position = next_open_position()
- item.slot = {}
- item.display_name = stack.display_name
- item.mod_name = stack.mod
- table.insert(items, item)
- end
- if item.position == nil then
- item.position = next_open_position()
- end
- save(items, "items")
- return item
- end
- function check_inventory(inventory_items)
- local items_to_store = {}
- for i = 1, #inventory_items - 1 do
- table.insert(items_to_store, register_item(inventory_items[i].basic()))
- end
- return items_to_store
- end
- function distance_away(position)
- local distance = math.abs(position.y - me.y)
- distance = distance + math.abs(me.x) + math.abs(me.z)
- distance = distance + math.abs(position.x) + math.abs(position.z)
- return distance
- end
- function closest_order(item_1, item_2)
- return distance_away(item_1.position) > distance_away(item_2.position)
- end
- function give_item_slots(items_to_store)
- for i = 1, #items_to_store do
- table.insert(items_to_store[i].slot, i)
- end
- end
- function go_to(target)
- if me.y ~= target.y then
- go_to({x = 0, y = me.y, z = 0})
- while me.y < target.y do
- if turtle.up() then me.y = me.y + 1 end
- end
- while me.y > target.y do
- if turtle.down() then me.y = me.y - 1 end
- end
- end
- if me.x < target.x then
- turtle.turnRight()
- while me.x < target.x do
- if turtle.forward() then me.x = me.x + 1 end
- end
- turtle.turnLeft()
- end
- if me.x > target.x then
- turtle.turnLeft()
- while me.x > target.x do
- if turtle.forward() then me.x = me.x - 1 end
- end
- turtle.turnRight()
- end
- while me.z < target.z do
- if turtle.forward() then me.z = me.z + 1 end
- end
- while me.z > target.z do
- if turtle.back() then me.z = me.z - 1 end
- end
- end
- function deposit_item(item)
- go_to(item.position)
- for _, slot_number in ipairs(item.slot) do
- local amount = inventory.pushItem(item.position.side, slot_number)
- item.quantity = item.quantity + amount
- end
- item.slot = {}
- save(items, "items")
- end
- function store_items(items_to_store)
- give_item_slots(items_to_store)
- while #items_to_store > 0 do
- table.sort(items_to_store, closest_order)
- local closest_item = items_to_store[#items_to_store]
- deposit_item(closest_item)
- table.remove(items_to_store)
- end
- end
- function store_inventory()
- show_title("Storing Inventory")
- inventory_items = condense_inventory()
- local items_to_store = check_inventory(inventory_items)
- store_items(items_to_store)
- end
- function search(s1, s2)
- local s1 = string.lower(string.gsub(string.gsub(s1, " ", ""), "_", ""))
- local s2 = string.lower(string.gsub(string.gsub(s2, " ", ""), "_", ""))
- return string.find(s1, s2)
- end
- function result_order(r1, r2)
- local alphabetical = string.lower(r1.display_name) < string.lower(r2.display_name)
- return alphabetical or r2.quantity == 0
- end
- function clear_window()
- paintutils.drawFilledBox(1,2,screen_width,screen_height-1,colors.black)
- clear_search_bar()
- end
- function side_number(n)
- term.setCursorPos(1, n+1)
- local spaces = {}
- n_string = tostring(n)
- for i=1, 2-#n_string do
- table.insert(spaces, " ")
- end
- term.setTextColor(colors.cyan)
- term.write(table.concat(spaces)..n_string)
- term.setTextColor(colors.white)
- end
- function list_items(items_list)
- clear_window()
- term.setCursorPos(1,2)
- for i, item in pairs(slice(items_list, 1, screen_height-2)) do
- side_number(i)
- print(" "..item.display_name)
- term.setTextColor(colors.lightGray)
- term.write(" #"..item.quantity)
- end
- clear_search_bar()
- end
- function select_item(search_term)
- show_title("Fetch: \""..search_term.."\"")
- local search_results = {}
- for _, item in ipairs(items) do
- local r = search(item.display_name, search_term)
- if r then
- table.insert(search_results, item)
- end
- end
- table.sort(search_results, result_order)
- list_items(search_results)
- local choice = io.read()
- while not tonumber(choice) and tonumber(choice) > #search_results do
- choice = io.read()
- end
- return search_results[tonumber(choice)]
- end
- function amount_in_chest()
- store_chest.condenseItems()
- return #store_chest.getAllStacks()
- end
- function get_enderchest(group)
- turtle.select(16)
- turtle.placeDown()
- turtle.select(1)
- end
- function start_store()
- go_to({x=0, y=me.y, z=0})
- local at_home = turtle.detectDown()
- condense_inventory()
- if not at_home then
- get_enderchest("deposit")
- end
- items_left = amount_in_chest()
- while items_left > 0 do
- go_to({x=0, y=me.y, z=0})
- get_enderchest("deposit")
- while turtle.suckDown() do end
- if not at_home then
- if inventory.getStackInSlot(16) then
- inventory.pushItem("down", 16)
- end
- end
- items_left = amount_in_chest()
- if not at_home then
- turtle.select(16)
- turtle.digDown()
- end
- store_inventory()
- end
- end
- function number_of_stacks(full_stack, amount)
- local stacks = math.floor(amount/full_stack)
- local remaining_items = amount % full_stack
- return stacks, remaining_items
- end
- function fetch_item(item)
- go_to(item.position)
- local amount_to_fetch = item.amount_to_fetch
- while amount_to_fetch > 0 do
- local amount = inventory.pullItem(item.position.side, 2, amount_to_fetch)
- item.quantity = item.quantity - amount
- amount_to_fetch = amount_to_fetch - amount
- end
- if item.quantity == 0 then
- table.insert(open_positions, item.position)
- save(open_positions, "open_positions")
- item.position = nil
- end
- save(items, "items")
- end
- function start_fetch()
- local items_to_fetch = queue.fetch
- while #items_to_fetch > 0 do
- table.sort(items_to_fetch, closest_order)
- fetch_item(items_to_fetch[#items_to_fetch])
- table.remove(items_to_fetch)
- end
- end
- function do_queue()
- empty_inventory("down")
- store_inventory()
- if #queue.fetch > 0 then
- start_fetch()
- end
- if queue.store then
- start_store()
- end
- queue = {fetch = {}, store = false}
- go_to(home)
- end
- function menu_fetch(search_term)
- local item_to_fetch = select_item(search_term)
- show_title("Fetch: "..item_to_fetch.display_name)
- local amount = io.read()
- while not tonumber(amount) do
- amount = io.read()
- end
- item_to_fetch.amount_to_fetch = amount
- table.insert(queue.fetch, item_to_fetch)
- end
- function menu_store()
- queue.store = true
- end
- function main_menu()
- local options = {
- ["store"] = menu_store,
- ["sort"] = menu_store,
- [">"] = menu_store,
- ["fetch"] = menu_fetch,
- ["get"] = menu_fetch,
- ["<"] = menu_fetch,
- ["start"] = do_queue,
- ["go"] = do_queue,
- [""] = do_queue
- }
- while true do
- show_title(os.getComputerLabel())
- local input = io.read()
- if options[input] then
- options[input](input)
- end
- end
- end
- function start()
- screen_width, screen_height = term.getSize()
- queue = {to_store=false,fetch={}}
- home = {x=0,y=0,z=0}
- me = {x=home.x,y=home.y,z=home.z}
- store_chest = peripheral.wrap("bottom")
- fetch_chest = peripheral.wrap("right")
- inventory = peripheral.wrap("left")
- items = load("items")
- open_positions = load("open_positions")
- main_menu()
- end
- start()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement