Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- require("stringtools")()
- local BAPI = require("button_api")
- local main = BAPI.Desktop()
- local task = require("taskmaster")
- local style = BAPI.Style
- local position = BAPI.Position
- local version = "v1.2"
- local width, height = term.getSize()
- if not fs.exists("list.json") then local a = fs.open("list.json","w") a.write("{}") a.close() end
- local item_knowledge_json = fs.open("list.json", "r")
- local item_knowledge = textutils.unserialiseJSON(item_knowledge_json.readAll())
- item_knowledge_json.close()
- local controller = peripheral.find("storagedrawers:controller")-- or peripheral.wrap("bottom")
- local vault = peripheral.find("create:item_vault") or peripheral.find("create_connected:item_silo") --or peripheral.wrap("top")
- local io_chest = peripheral.wrap("right")
- local time = 1
- -- tools
- local function reset()
- term.setTextColour(colors.white)
- paintutils.drawFilledBox(1,1,width,height, colors.black)
- term.clear()
- term.setCursorPos(1,1)
- end
- local function timer()
- repeat
- os.sleep(1)
- time = time + 1
- until time == 300
- reset()
- write("TIMED OUT.")
- os.sleep(2)
- end
- local function total_items(table)
- local total = 0
- for _ in pairs(table) do
- total = total + 1
- end
- return total
- end
- local function synth()
- reset()
- term.setCursorPos(string.centerX("SYNTHESIZING...", width), 1)
- write("SYNTHESIZING...")
- local new = {}
- -- Collect unique items from vault and controller inventories
- for _, inventory in ipairs({vault, controller}) do
- local list = inventory.list()
- local idx = 1
- local total = total_items(list)
- for slot, slot_obj in pairs(list) do
- if slot_obj and not new[slot_obj.name] then
- new[slot_obj.name] = inventory.getItemDetail(slot).displayName
- end
- term.setCursorPos(1,2)
- write(string.loadingBar(idx/total,width))
- idx = idx + 1
- end
- end
- -- Update item knowledge based on new findings
- for name, displayName in pairs(new) do
- item_knowledge[name] = item_knowledge[name] or displayName
- end
- for name in pairs(item_knowledge) do
- if not new[name] then
- item_knowledge[name] = nil
- end
- end
- -- Save updated item knowledge to JSON
- local t = fs.open("list.json", "w")
- t.write(textutils.serialiseJSON(item_knowledge))
- t.close()
- end
- local search_modes = {
- {
- name = "CLOSEST",
- exec = function(str)
- str = string.fracture(string.lower(str))
- local scores = {}
- for name, displayName in pairs(item_knowledge) do
- local score = 0
- for pointer, character in pairs(string.fracture(string.lower(displayName))) do
- if str[pointer] == character then
- score = score + 1
- else
- score = score - 1
- end
- end
- table.insert(scores,{
- name = name,
- displayName = displayName,
- score = score
- })
- end
- table.sort(scores,function(a,b)
- return a.score > b.score
- end)
- if next(scores) == nil then
- return nil
- end
- return scores[1].name, scores[1].displayName
- end
- },
- {
- name = "INCLUDES",
- exec = function(str)
- local found = {}
- for name, displayName in pairs(item_knowledge) do
- if string.find(string.lower(displayName), string.lower(str)) then
- table.insert(found, {name = name, displayName = displayName})
- end
- end
- local mx,my = term.getSize()
- local x, y = term.getCursorPos()
- local oy = y
- if next(found) == nil then
- return nil
- end
- for i, v in pairs(found) do
- write(i..". "..v.displayName.."\n")
- y = y + 1
- if y == my-1 then
- write("PRESS ANY TO CONTINUE")
- os.pullEvent("key")
- for j = oy, my-1, 1 do
- term.setCursorPos(1,j)
- term.clearLine()
- end
- term.setCursorPos(1,oy)
- y = oy
- end
- end
- term.setCursorPos(1,3)
- write("INSERT NUMBER: ")
- local selection = tonumber(read())
- if selection then
- for j = oy, my, 1 do
- term.setCursorPos(1,j)
- term.clearLine()
- end
- term.setCursorPos(1,oy)
- return found[selection].name, found[selection].displayName
- else
- return nil
- end
- end
- },
- {
- name = "EXACT",
- exec = function(str)
- for name, displayName in pairs(item_knowledge) do
- if string.lower(str) == string.lower(displayName) then
- return name, displayName
- end
- end
- return nil
- end
- }
- }
- local function get_total(name)
- local count = 0
- for _, inventory in ipairs({vault, controller}) do
- for slot, slot_obj in pairs(inventory.list()) do
- if slot_obj.name == name then
- count = count + slot_obj.count
- end
- end
- end
- return count
- end
- local function get_slots(name)
- local slots = {}
- for _, inventory in ipairs({vault, controller}) do
- for slot, slot_obj in pairs(inventory.list()) do
- if slot_obj.name == name then
- table.insert(slots, {inventory, slot})
- end
- end
- end
- return slots
- end
- local function pull(item, amount, to)
- local increase = 0
- for _, slot_info in pairs(get_slots(item)) do
- if amount <= 0 then
- return
- end
- local inventory, slot = table.unpack(slot_info)
- amount = amount - inventory.pushItems(peripheral.getName(to), slot, amount)
- end
- if amount ~= 0 then
- pull(item, amount, to)
- end
- end
- local function get_num_index(table, name_index)
- local index = 1
- for i, _ in ipairs(table) do
- if name_index == i then
- return index
- end
- index = index + 1
- end
- end
- local operations = {
- {
- name = "ORGANIZE INVENTORY",
- color = colors.yellow,
- exec = function()
- reset()
- term.setCursorPos(string.centerX("ORGANIZING...",width),1)
- write("ORGANIZING...")
- -- Seperate item into their inventory based on amount
- for _, inventory in ipairs({vault, controller}) do
- local list = inventory.list()
- local total_list = total_items(list)
- local idx = 1
- for slot, slot_obj in pairs(list) do
- local total = get_total(slot_obj.name)
- if total <= 64 then
- inventory.pushItems(peripheral.getName(vault), slot)
- else
- inventory.pushItems(peripheral.getName(controller), slot)
- end
- term.setCursorPos(1,2)
- write(string.loadingBar(idx/total_list,51))
- idx = idx + 1
- end
- end
- end
- },
- {
- name = "WITHDRAW ITEMS ",
- color = colors.orange,
- exec = function()
- local resetted = false
- local function run()
- local mode = 2
- while true do
- reset()
- main:render()
- resetted = true
- term.setCursorPos(1,1)
- term.setBackgroundColor(colors.black)
- write("INSERT ITEM SEARCH\nCURRENT MODE: "..search_modes[mode].name.."\n")
- local search, search_display;
- local function get_search()
- local r = read()
- search, search_display = search_modes[mode].exec(r)
- if not search then
- write("ITEM NOT FOUND")
- os.sleep(2)
- reset()
- main:render()
- term.setCursorPos(1,1)
- term.setBackgroundColor(colors.black)
- write("INSERT ITEM SEARCH\nCURRENT MODE: "..search_modes[mode].name.."\n")
- get_search()
- return
- end
- end
- local function mode_select()
- local x,y = term.getCursorPos()
- local _, key = os.pullEvent("key")
- if key == keys.right then
- mode = mode+1>#search_modes and 1 or mode+1
- elseif key == keys.left then
- mode = mode-1<1 and #search_modes or mode-1
- end
- term.setCursorPos(1,2)
- term.clearLine()
- write("CURRENT MODE: "..search_modes[mode].name.."\n")
- term.setCursorPos(x,y)
- mode_select()
- end
- parallel.waitForAny(get_search,mode_select)
- main:render()
- term.setBackgroundColor(colors.black)
- term.setCursorPos(1,1)
- term.clearLine()
- write("INSERT AMOUNT")
- local amount
- term.setCursorPos(1,3)
- term.clearLine()
- write("ITEM: "..search_display.."\n")
- local available = get_total(search)
- write("AVAILABLE: "..available.."\n")
- local function get_amount()
- local r = read()
- amount = tonumber(r)
- if amount == nil then
- --try to get a calculation
- local func, err = load("return "..r)
- amount = func()
- if not amount then
- term.setCursorPos(1,5)
- write("INVALID NUMBER/EQUATION")
- os.sleep(2)
- term.clearLine()
- term.setCursorPos(1,5)
- get_amount()
- return
- end
- end
- end
- get_amount()
- if search and amount then
- pull(search, amount, io_chest)
- write("ITEMS WITHDRAWN.")
- os.sleep(2)
- end
- time = 0
- end
- end
- local s = style(colors.red)
- s.text = "Exit"
- s.textColor = colors.white
- local p = position(width, height, "right", "bottom", "Exit",1)
- main.addButton(p,s,function() print("") end)
- task(run, function() main:awaitButtonClick() end):waitForAny()
- main.clearButtons()
- end
- },
- {
- name = "DEPOSIT ITEMS ",
- color = colors.red,
- exec = function()
- reset()
- term.setTextColor(colors.red)
- term.setCursorPos(string.centerX("ALL ITEMS IN THE CHEST SHALL BE DEPOSITED", 51),1)
- write("ALL ITEMS IN THE CHEST SHALL BE DEPOSITED")
- term.setCursorPos(string.centerX("CONTINUE?", 51),2)
- write("CONTINUE?")
- local s = style(colors.green)
- s.text = "Yes"
- s.textColor = colors.white
- local p = position(width, height, "centered", "centered", "Yes", 3,1)
- p.s_x = p.s_x - 11
- p.e_x = p.e_x - 11
- main.addButton(p,s, function()
- local inventory = io_chest.list()
- reset()
- term.setCursorPos(string.centerX("DEPOSITING...", 51),1)
- write("DEPOSITING...")
- local total = total_items(inventory)
- local idx = 1
- for slot, _ in pairs(inventory) do
- write(string.loadingBar(idx/total,width))
- local details = io_chest.getItemDetail(slot)
- local _,y = term.getCursorPos()
- idx = idx + 1
- term.setCursorPos(1,y)
- io_chest.pushItems(peripheral.getName(vault), slot)
- item_knowledge[details.name] = not item_knowledge[details.name] and details.displayName
- end
- reset()
- term.setCursorPos(string.centerX("DEPOSIT COMPLETE.", 51),1)
- write("DEPOSIT COMPLETE.")
- os.sleep(2)
- end)
- local s = style(colors.red)
- s.text = "No "
- s.textColor = colors.white
- local p = position(width, height, "centered", "centered", "No ", 3,1)
- p.s_x = p.s_x + 11
- p.e_x = p.e_x + 11
- main.addButton(p,s, function() print("t") end)
- main:render()
- main:awaitButtonClick()
- end
- }
- }
- -- execute
- local function main_loop()
- reset()
- write(" NSP SMART INVENTORY BY NUNOTO")
- local ops = {}
- for i, obj in pairs(operations) do
- local s = style(obj.color)
- s.text = obj.name
- s.textColor = colors.white
- local p = position(width+1, height, "left", "", obj.name,1,1)
- p.s_y = (i) * 4
- p.e_y = (i) * 4 + 2
- main.addButton(p,s,function() main.clearButtons() parallel.waitForAny(obj.exec,timer) main.clearButtons() end)
- end
- main:render()
- main:awaitButtonClick()
- main_loop()
- end
- item_knowledge = {}
- synth()
- reset()
- for i, obj in pairs(operations) do
- local s = style(obj.color)
- s.text = obj.name
- s.textColor = colors.white
- s.animate = true
- s.animationTime = 0.05
- local p = position(width+1, height, "left", "", obj.name,1,1)
- p.s_y = (i) * 4
- p.e_y = (i) * 4 + 2
- s.s_x = p.e_x
- main.addButton(p,s,obj.exec)
- end
- main:render()
- main.clearButtons()
- main_loop()
Add Comment
Please, Sign In to add comment