AssortedBrunoz

ME system v.1.25

Oct 11th, 2024 (edited)
575
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 14.95 KB | None | 0 0
  1. require("stringtools")()
  2. local BAPI = require("button_api")
  3. local main = BAPI.Desktop()
  4. local task = require("taskmaster")
  5. local style = BAPI.Style
  6. local position = BAPI.Position
  7. local version = "v1.2"
  8. local width, height = term.getSize()
  9. if not fs.exists("list.json") then local a = fs.open("list.json","w") a.write("{}") a.close() end
  10. local item_knowledge_json = fs.open("list.json", "r")
  11. local item_knowledge = textutils.unserialiseJSON(item_knowledge_json.readAll())
  12. item_knowledge_json.close()
  13.  
  14. local controller = peripheral.find("storagedrawers:controller")-- or peripheral.wrap("bottom")
  15. local vault = peripheral.find("create:item_vault") or peripheral.find("create_connected:item_silo") --or peripheral.wrap("top")
  16. local io_chest = peripheral.wrap("right")
  17. local time = 1
  18. -- tools
  19.  
  20. local function reset()
  21.     term.setTextColour(colors.white)
  22.     paintutils.drawFilledBox(1,1,width,height, colors.black)
  23.     term.clear()
  24.     term.setCursorPos(1,1)
  25. end
  26.  
  27. local function timer()
  28.     repeat
  29.         os.sleep(1)
  30.         time = time + 1
  31.     until time == 300
  32.     reset()
  33.     write("TIMED OUT.")
  34.     os.sleep(2)
  35. end
  36.  
  37. local function total_items(table)
  38.     local total = 0
  39.     for _ in pairs(table) do
  40.         total = total + 1
  41.     end
  42.     return total
  43. end
  44.  
  45. local function synth()
  46.     reset()
  47.     term.setCursorPos(string.centerX("SYNTHESIZING...", width), 1)
  48.     write("SYNTHESIZING...")
  49.  
  50.     local new = {}
  51.  
  52.     -- Collect unique items from vault and controller inventories
  53.     for _, inventory in ipairs({vault, controller}) do
  54.         local list = inventory.list()
  55.         local idx = 1
  56.         local total = total_items(list)
  57.         for slot, slot_obj in pairs(list) do
  58.             if slot_obj and not new[slot_obj.name] then
  59.                 new[slot_obj.name] = inventory.getItemDetail(slot).displayName
  60.             end
  61.             term.setCursorPos(1,2)
  62.             write(string.loadingBar(idx/total,width))
  63.             idx = idx + 1
  64.         end
  65.     end
  66.  
  67.     -- Update item knowledge based on new findings
  68.     for name, displayName in pairs(new) do
  69.         item_knowledge[name] = item_knowledge[name] or displayName
  70.     end
  71.     for name in pairs(item_knowledge) do
  72.         if not new[name] then
  73.             item_knowledge[name] = nil
  74.         end
  75.     end
  76.    
  77.     -- Save updated item knowledge to JSON
  78.     local t = fs.open("list.json", "w")
  79.     t.write(textutils.serialiseJSON(item_knowledge))
  80.     t.close()
  81. end
  82.  
  83. local search_modes = {
  84.     {
  85.         name = "CLOSEST",
  86.         exec = function(str)
  87.             str = string.fracture(string.lower(str))
  88.             local scores = {}
  89.             for name, displayName in pairs(item_knowledge) do
  90.                 local score = 0
  91.                 for pointer, character in pairs(string.fracture(string.lower(displayName))) do
  92.                     if str[pointer] == character then
  93.                         score = score + 1
  94.                     else
  95.                         score = score - 1
  96.                     end
  97.                 end
  98.                 table.insert(scores,{
  99.                     name = name,
  100.                     displayName = displayName,
  101.                     score = score
  102.                 })
  103.             end
  104.             table.sort(scores,function(a,b)
  105.                 return a.score > b.score
  106.             end)
  107.             if next(scores) == nil then
  108.                 return nil
  109.             end
  110.             return scores[1].name, scores[1].displayName
  111.         end
  112.     },
  113.     {
  114.         name = "INCLUDES",
  115.         exec = function(str)
  116.             local found = {}
  117.             for name, displayName in pairs(item_knowledge) do
  118.                 if string.find(string.lower(displayName), string.lower(str)) then
  119.                     table.insert(found, {name = name, displayName = displayName})
  120.                 end
  121.             end
  122.             local mx,my = term.getSize()
  123.             local x, y = term.getCursorPos()
  124.             local oy = y
  125.             if next(found) == nil then
  126.                 return nil
  127.             end
  128.             for i, v in pairs(found) do
  129.                 write(i..". "..v.displayName.."\n")
  130.                 y = y + 1
  131.                 if y == my-1 then
  132.                     write("PRESS ANY TO CONTINUE")
  133.                     os.pullEvent("key")
  134.                     for j = oy, my-1, 1 do
  135.                         term.setCursorPos(1,j)
  136.                         term.clearLine()
  137.                     end
  138.                     term.setCursorPos(1,oy)
  139.                     y = oy
  140.                 end
  141.             end
  142.             term.setCursorPos(1,3)
  143.             write("INSERT NUMBER: ")
  144.             local selection = tonumber(read())
  145.  
  146.             if selection then
  147.                 for j = oy, my, 1 do
  148.                     term.setCursorPos(1,j)
  149.                     term.clearLine()
  150.                 end
  151.                 term.setCursorPos(1,oy)
  152.                 return found[selection].name, found[selection].displayName
  153.             else
  154.                 return nil
  155.             end
  156.         end
  157.     },
  158.     {
  159.         name = "EXACT",
  160.         exec = function(str)
  161.             for name, displayName in pairs(item_knowledge) do
  162.                 if string.lower(str) == string.lower(displayName) then
  163.                     return name, displayName
  164.                 end
  165.             end
  166.             return nil
  167.         end
  168.     }
  169. }
  170.  
  171. local function get_total(name)
  172.     local count = 0
  173.     for _, inventory in ipairs({vault, controller}) do
  174.         for slot, slot_obj in pairs(inventory.list()) do
  175.             if slot_obj.name == name then
  176.                 count = count + slot_obj.count
  177.             end
  178.         end
  179.     end
  180.     return count
  181. end
  182.  
  183. local function get_slots(name)
  184.     local slots = {}
  185.     for _, inventory in ipairs({vault, controller}) do
  186.         for slot, slot_obj in pairs(inventory.list()) do
  187.             if slot_obj.name == name then
  188.                 table.insert(slots, {inventory, slot})
  189.             end
  190.         end
  191.     end
  192.     return slots
  193. end
  194.  
  195. local function pull(item, amount, to)
  196.     local increase = 0
  197.     for _, slot_info in pairs(get_slots(item)) do
  198.         if amount <= 0 then
  199.             return
  200.         end
  201.         local inventory, slot = table.unpack(slot_info)
  202.         amount = amount - inventory.pushItems(peripheral.getName(to), slot, amount)
  203.     end
  204.     if amount ~= 0 then
  205.         pull(item, amount, to)
  206.     end
  207. end
  208.  
  209. local function get_num_index(table, name_index)
  210.     local index = 1
  211.     for i, _ in ipairs(table) do
  212.         if name_index == i then
  213.             return index
  214.         end
  215.         index = index + 1
  216.     end
  217. end
  218.  
  219. local operations = {
  220.     {
  221.         name = "ORGANIZE INVENTORY",
  222.         color = colors.yellow,
  223.         exec = function()
  224.             reset()
  225.             term.setCursorPos(string.centerX("ORGANIZING...",width),1)
  226.             write("ORGANIZING...")
  227.             -- Seperate item into their inventory based on amount
  228.             for _, inventory in ipairs({vault, controller}) do
  229.                 local list = inventory.list()
  230.                 local total_list = total_items(list)
  231.                 local idx = 1
  232.                 for slot, slot_obj in pairs(list) do
  233.                     local total = get_total(slot_obj.name)
  234.                     if total <= 64 then
  235.                         inventory.pushItems(peripheral.getName(vault), slot)
  236.                     else
  237.                         inventory.pushItems(peripheral.getName(controller), slot)
  238.                     end
  239.                     term.setCursorPos(1,2)
  240.                     write(string.loadingBar(idx/total_list,51))
  241.                     idx = idx + 1
  242.                 end
  243.             end
  244.         end
  245.     },
  246.     {
  247.         name = "WITHDRAW ITEMS  ",
  248.         color = colors.orange,
  249.         exec = function()
  250.             local resetted = false
  251.             local function run()
  252.                 local mode = 2
  253.                 while true do
  254.                     reset()
  255.                     main:render()
  256.                     resetted = true
  257.                     term.setCursorPos(1,1)
  258.                     term.setBackgroundColor(colors.black)
  259.                     write("INSERT ITEM SEARCH\nCURRENT MODE: "..search_modes[mode].name.."\n")
  260.                     local search, search_display;
  261.                    
  262.                     local function get_search()
  263.                         local r = read()
  264.                         search, search_display = search_modes[mode].exec(r)
  265.                        
  266.                         if not search then
  267.                             write("ITEM NOT FOUND")
  268.                             os.sleep(2)
  269.                             reset()
  270.                             main:render()
  271.                             term.setCursorPos(1,1)
  272.                             term.setBackgroundColor(colors.black)
  273.                             write("INSERT ITEM SEARCH\nCURRENT MODE: "..search_modes[mode].name.."\n")
  274.                             get_search()
  275.                             return
  276.                         end
  277.                     end
  278.                     local function mode_select()
  279.                         local x,y = term.getCursorPos()
  280.  
  281.                         local _, key = os.pullEvent("key")
  282.  
  283.                         if key == keys.right then
  284.                             mode = mode+1>#search_modes and 1 or mode+1
  285.                         elseif key == keys.left then
  286.                             mode = mode-1<1 and #search_modes or mode-1
  287.                         end
  288.                         term.setCursorPos(1,2)
  289.                         term.clearLine()
  290.                         write("CURRENT MODE: "..search_modes[mode].name.."\n")
  291.  
  292.                         term.setCursorPos(x,y)
  293.                         mode_select()
  294.                     end
  295.  
  296.                     parallel.waitForAny(get_search,mode_select)
  297.                     main:render()
  298.                     term.setBackgroundColor(colors.black)
  299.  
  300.                     term.setCursorPos(1,1)
  301.                     term.clearLine()
  302.                     write("INSERT AMOUNT")
  303.                     local amount
  304.                     term.setCursorPos(1,3)
  305.                     term.clearLine()
  306.                     write("ITEM: "..search_display.."\n")
  307.                     local available = get_total(search)
  308.                     write("AVAILABLE: "..available.."\n")
  309.                     local function get_amount()
  310.                         local r = read()
  311.                         amount = tonumber(r)
  312.                        
  313.                         if amount == nil then
  314.                             --try to get a calculation
  315.                             local func, err = load("return "..r)
  316.                             amount = func()
  317.  
  318.                             if not amount then
  319.                                 term.setCursorPos(1,5)
  320.                                 write("INVALID NUMBER/EQUATION")
  321.                                 os.sleep(2)
  322.                                 term.clearLine()
  323.                                 term.setCursorPos(1,5)
  324.                                 get_amount()
  325.                                 return
  326.                             end
  327.                            
  328.                         end
  329.  
  330.                     end
  331.  
  332.                     get_amount()
  333.  
  334.                     if search and amount then
  335.                         pull(search, amount, io_chest)
  336.                         write("ITEMS WITHDRAWN.")
  337.                         os.sleep(2)
  338.                     end
  339.                     time = 0
  340.                 end
  341.             end
  342.             local s = style(colors.red)
  343.             s.text = "Exit"
  344.             s.textColor = colors.white
  345.  
  346.             local p = position(width, height, "right", "bottom", "Exit",1)
  347.  
  348.             main.addButton(p,s,function() print("") end)
  349.  
  350.             task(run, function() main:awaitButtonClick() end):waitForAny()
  351.  
  352.             main.clearButtons()
  353.         end
  354.     },
  355.     {
  356.         name = "DEPOSIT ITEMS ",
  357.         color = colors.red,
  358.         exec = function()
  359.             reset()
  360.             term.setTextColor(colors.red)
  361.             term.setCursorPos(string.centerX("ALL ITEMS IN THE CHEST SHALL BE DEPOSITED", 51),1)
  362.             write("ALL ITEMS IN THE CHEST SHALL BE DEPOSITED")
  363.             term.setCursorPos(string.centerX("CONTINUE?", 51),2)
  364.             write("CONTINUE?")
  365.  
  366.             local s = style(colors.green)
  367.             s.text = "Yes"
  368.             s.textColor = colors.white
  369.  
  370.             local p = position(width, height, "centered", "centered", "Yes", 3,1)
  371.             p.s_x = p.s_x - 11
  372.             p.e_x = p.e_x - 11
  373.  
  374.  
  375.             main.addButton(p,s, function()
  376.                 local inventory = io_chest.list()
  377.                 reset()
  378.                 term.setCursorPos(string.centerX("DEPOSITING...", 51),1)
  379.                 write("DEPOSITING...")
  380.                 local total = total_items(inventory)
  381.                 local idx = 1
  382.                 for slot, _ in pairs(inventory) do
  383.                     write(string.loadingBar(idx/total,width))
  384.                     local details = io_chest.getItemDetail(slot)
  385.                     local _,y = term.getCursorPos()
  386.                     idx = idx + 1
  387.                     term.setCursorPos(1,y)
  388.  
  389.                     io_chest.pushItems(peripheral.getName(vault), slot)
  390.                     item_knowledge[details.name] = not item_knowledge[details.name] and details.displayName
  391.                 end
  392.  
  393.                 reset()
  394.                 term.setCursorPos(string.centerX("DEPOSIT COMPLETE.", 51),1)
  395.                 write("DEPOSIT COMPLETE.")
  396.                 os.sleep(2)
  397.             end)
  398.  
  399.             local s = style(colors.red)
  400.             s.text = "No "
  401.             s.textColor = colors.white
  402.  
  403.             local p = position(width, height, "centered", "centered", "No ", 3,1)
  404.             p.s_x = p.s_x + 11
  405.             p.e_x = p.e_x + 11
  406.  
  407.  
  408.             main.addButton(p,s, function() print("t") end)
  409.  
  410.             main:render()
  411.  
  412.             main:awaitButtonClick()
  413.         end
  414.     }
  415. }
  416.  
  417. -- execute
  418.  
  419. local function main_loop()
  420.  
  421.     reset()
  422.     write("          NSP SMART INVENTORY BY NUNOTO")
  423.  
  424.     local ops = {}
  425.  
  426.     for i, obj in pairs(operations) do
  427.         local s = style(obj.color)
  428.         s.text = obj.name
  429.         s.textColor = colors.white
  430.  
  431.         local p = position(width+1, height, "left", "", obj.name,1,1)
  432.         p.s_y = (i) * 4
  433.         p.e_y = (i) * 4 + 2
  434.  
  435.         main.addButton(p,s,function() main.clearButtons() parallel.waitForAny(obj.exec,timer) main.clearButtons() end)
  436.     end
  437.    
  438.     main:render()
  439.  
  440.     main:awaitButtonClick()
  441.    
  442.     main_loop()
  443. end
  444.  
  445. item_knowledge = {}
  446. synth()
  447. reset()
  448. for i, obj in pairs(operations) do
  449.     local s = style(obj.color)
  450.     s.text = obj.name
  451.     s.textColor = colors.white
  452.     s.animate = true
  453.     s.animationTime = 0.05
  454.  
  455.     local p = position(width+1, height, "left", "", obj.name,1,1)
  456.     p.s_y = (i) * 4
  457.     p.e_y = (i) * 4 + 2
  458.  
  459.     s.s_x = p.e_x
  460.  
  461.     main.addButton(p,s,obj.exec)
  462. end
  463.  
  464. main:render()
  465.  
  466. main.clearButtons()
  467.  
  468. main_loop()
Add Comment
Please, Sign In to add comment