Advertisement
Shaka01

smartStockpile_brain

Feb 2nd, 2023 (edited)
761
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.64 KB | None | 0 0
  1. minStockedPercent = 90 -- at which percentage to start moving items
  2. sleeptime = 3 --- time in seconds for the computer to sleep between item requests
  3. scrollSpeed = 3 --- amount of items to scroll when touching monitor
  4. specialGuy = 1 -- id of turtle to save specialAmount items when receiving update
  5. specialAmount = 128
  6.  
  7. --initialize
  8. if fs.exists("addItem") == false then
  9. shell.run("pastebin", "get", "YUtHDsCC", "addItem")
  10. end
  11. inventory = nil
  12. fromInventories = {}
  13. monitor = nil
  14. if fs.exists("wanteditems.lua") then
  15. wantedItems = dofile("wanteditems.lua")
  16. else shell.run("addItem") end
  17. readCount = false
  18. local scroll = 1
  19. deviceCount = 0
  20. if fs.exists("API") == false then
  21. shell.run("pastebin", "get", "EzkfU5ZM", "API")
  22. end
  23. shaka = require("API")
  24. local sleeperTable = {}
  25. local notifyCount = 0
  26.  
  27. -- Connect peripherals
  28. local sides = {"left", "right", "top", "bottom", "front", "back"}
  29. for i, side in ipairs(sides) do
  30.     local device = peripheral.getType(side)
  31.     if device == "modem" then
  32.     modem = peripheral.wrap(side)
  33.     if modem.isWireless() then
  34.         wirelessModem = peripheral.wrap(side)
  35.         rednet.open(side)
  36.     else
  37.         wiredModem = peripheral.wrap(side)
  38.         rednet.close(side)
  39.     end
  40.     elseif device == "monitor" then
  41.         monitor = peripheral.wrap(side)
  42.     end
  43. end
  44.  
  45.  
  46. if monitor == nil then
  47.     window = shaka.centerWindow(40, 5, colors.red, colors.black)
  48.     term.clear()
  49.     window.clear()
  50.     shaka.centerText("No monitor connected!", 2, window)
  51.     shaka.changeColors(colors.red, colors.gray)
  52.     shaka.centerText("Connect one on any side to continue..", 4, window)
  53.     event, side = os.pullEvent("peripheral")
  54.     print("Rebooting.")
  55.     sleep(2)
  56.     os.reboot()
  57. end
  58.  
  59.  
  60. if rednet.isOpen() == false then
  61.     window = shaka.centerWindow(40, 5, colors.red, colors.black)
  62.     term.clear()
  63.     window.clear()
  64.     shaka.centerText("No wireless modem connected!", 2, window)
  65.     shaka.changeColors(colors.red, colors.gray)
  66.     shaka.centerText("Connect one on any side to continue..", 4, window)
  67.     event, side = os.pullEvent("peripheral")
  68.     print("Rebooting.")
  69.     sleep(2)
  70.     os.reboot()
  71. end
  72.  
  73. --connect inventories
  74. function tableContains(t, item)
  75.   for _, value in pairs(t) do
  76.     if value == item then
  77.       return true
  78.     end
  79.   end
  80.   return false
  81. end
  82.  
  83. if fs.exists("inventories") then
  84.     fromInventories = shaka.readFile("inventories")
  85. end
  86. local inventories = wiredModem.getNamesRemote()
  87. for _, inventoryName in ipairs(inventories) do
  88.   if shaka.stringFind(inventoryName, "turtle") == false and inventoryName ~= nil and shaka.stringFind(inventoryName, "computer") == false then
  89.     if not tableContains(fromInventories, inventoryName) then
  90.       table.insert(fromInventories, inventoryName)
  91.     end
  92.   end
  93. end
  94.  
  95. shaka.writeFile("inventories", fromInventories)
  96.  
  97. function centerText(monitor, y, text)
  98.   local w, h = monitor.getSize()
  99.   local x = math.floor((w - string.len(text) + 2) / 2)
  100.   monitor.setCursorPos(x , y)
  101.   print(text)
  102. end
  103.  
  104. function showDesktop()
  105. term.clear()
  106. term.setCursorPos(1,1)
  107. term.setTextColor(colors.lightGray)
  108. centerText(term, 5, "Click screen or hit space to view or add items.\n")
  109. centerText(term, 7,"No requests will be made while in menu.")
  110. local count = 0
  111. for _, items in pairs(wantedItems) do
  112.     count = count + #items
  113. end
  114. term.setTextColor(colors.green)
  115. centerText(term, 9, "Currently keeping " ..count.. " items in stock.")
  116. term.setTextColor(colors.white)
  117. end
  118. showDesktop()
  119.  
  120. ----functions
  121.  
  122. function split(s, delimiter)
  123.     result = {};
  124.     for match in (s..delimiter):gmatch("(.-)"..delimiter) do
  125.         table.insert(result, match);
  126.     end
  127.     return result;
  128. end
  129.  
  130. function showItems()
  131.     monitor.setTextScale(0.5)
  132.    
  133.     local items = {}
  134.     for channel, itemsData in pairs(wantedItems) do
  135.         for _, itemData in pairs(itemsData) do
  136.             local item = string.match(itemData[1], ":(.*)")
  137.             if item then
  138.                 item = string.gsub(item, "_", " ")
  139.                 table.insert(items, item .. ": " .. itemData[2])
  140.             end
  141.         end
  142.     end
  143.  
  144.     table.sort(items)
  145.  
  146.     local _, maxLines = monitor.getSize()
  147.     while true do
  148.         monitor.clear()
  149.         monitor.setCursorPos(1,1)
  150.         monitor.setTextColor(colors.yellow)
  151.         monitor.setBackgroundColor(colors.gray)
  152.         monitor.clearLine()
  153.         monitor.write("Monitored items:")
  154.         monitor.setBackgroundColor(colors.black)
  155.         monitor.setTextColor(colors.lightGray)
  156.         for i = scroll, scroll + maxLines - 2 do
  157.             monitor.setCursorPos(1, i - scroll + 2)
  158.             monitor.write(items[i] or "")
  159.         end
  160.         local event, side, x, y = os.pullEvent("monitor_touch")
  161.         if #items >= maxLines then
  162.             if y >= maxLines/2 then
  163.                 scroll = math.min(scroll + scrollSpeed, #items - maxLines + 2)
  164.             else
  165.                 scroll = math.max(scroll - scrollSpeed, 1)
  166.             end
  167.         end
  168.     end
  169. end
  170.  
  171.  
  172.  
  173. function scanInventory(var)
  174.     items = { }
  175.     for i= 1, #fromInventories do
  176.         invWrap = peripheral.wrap(fromInventories[i])
  177.         if invWrap == nil then
  178.             fromInventories[i] = nil
  179.             shaka.writeFile("inventories", fromInventories)
  180.             break
  181.         end
  182.         for k, v in pairs(invWrap.list()) do
  183.             for prop, value in pairs(v) do
  184.                 if prop == "name" then
  185.                     for channel, itemsData in pairs(var) do
  186.                         for _, itemData in pairs(itemsData) do
  187.                             if itemData[1] == value then
  188.                                 readCount = true
  189.                                 itemName = value
  190.                             end
  191.                         end
  192.                     end
  193.                 end
  194.                 -----add itemcount to table
  195.                 if prop == "count" and readCount == true then
  196.                     readCount = false
  197.                     if items[itemName] == nil then
  198.                         items[itemName] = 0
  199.                     end
  200.                     items[itemName] = items[itemName] + value
  201.                 end
  202.             end
  203.         end
  204.     end
  205. end
  206.  
  207.  
  208. function notifyComputer()
  209.     for channel, itemsData in pairs(wantedItems) do
  210.         for _, itemData in pairs(itemsData) do
  211.             local item = itemData[1]
  212.             local wantedCount = itemData[2]
  213.  
  214.             local currentCount = items[item] or 0
  215.             local restockCount = 0
  216.             if wantedCount > currentCount then
  217.                 restockCount = wantedCount - currentCount
  218.             end                    
  219.             local percent = 100 * (currentCount/wantedCount)
  220.             if percent < minStockedPercent and sleeperTable[item] ~= true then
  221.                 msg = table.concat({item, restockCount, wantedCount}, " ")
  222.                 BRmsg = table.concat({item, restockCount, channel}, " ")
  223.                 rednet.send(channel, msg, "stockpile")
  224.                 -- print(channel, msg)
  225.                 -- sleep(2)
  226.                 rednet.broadcast(BRmsg, "listen")
  227.                 sleep(0.5)
  228.             end
  229.         end
  230.     end
  231. end
  232.  
  233. -- Function to receive rednet message
  234. function receiveRednetMessage(protocolName)
  235.   local senderID, message, protocol = rednet.receive(protocolName)
  236.   -- print(message, protocol)
  237.   if protocol == "stockpileupdate" then
  238.     if message:find("saveItem ") == 1 then
  239.       local itemName = message:sub(10)
  240.       local itemExists = false
  241.       for id, items in pairs(wantedItems) do
  242.         for _, item in ipairs(items) do
  243.           if item[1] == itemName and id == senderID then
  244.             itemExists = true
  245.             break
  246.           end
  247.         end
  248.         if itemExists then
  249.             rednet.send(senderID, "nope", "stockPileConfirm")
  250.           break
  251.         end
  252.       end
  253.       if not itemExists then
  254.         if senderID == specialGuy then
  255.           addItem(senderID, itemName, specialAmount)
  256.         else
  257.           addItem(senderID, itemName, 1)
  258.         end
  259.         rednet.send(senderID, "gotcha", "stockPileConfirm")
  260.       end
  261.     end
  262.   elseif protocol == "tableUpdate" and message == "give" then
  263.     local serializedTable = textutils.serialize(wantedItems)
  264.     rednet.broadcast(serializedTable, "tableUpdate")
  265.   elseif protocol == "tableChange" then
  266.         split(message, " ")
  267.         local ID = tonumber(result[1])
  268.         local itemName = result[2]
  269.         local itemCount = tonumber(result[3])
  270.         removeItem(wantedItems, ID, tostring(itemName))
  271.         if itemCount ~= 0 then
  272.             addItem(ID, itemName, itemCount)
  273.         end
  274.         saveWantedItems()
  275.         local serializedTable = textutils.serialize(wantedItems)
  276.         rednet.broadcast("done", "tableConfirm")
  277.     elseif protocol == "giefIDplz" then
  278.         rednet.send(senderID, "here", "disBeID")
  279.     elseif protocol == "cantCraft" then
  280.         sleeperTable[message] = true
  281.     end
  282. end
  283.  
  284. ---remove items from table
  285. function removeItem(tableData, id, item)
  286.   local subTable = tableData[id]
  287.   if not subTable then
  288.     return
  289.   end
  290.   for i = #subTable, 1, -1 do
  291.     if subTable[i][1] == item then
  292.       table.remove(subTable, i)
  293.     end
  294.   end
  295.    if #subTable == 0 then
  296.     tableData[id] = nil
  297.   end
  298. end
  299.  
  300.  
  301. -- Function to add an item to the wanted items table
  302. function addItem(computerID, itemName, itemCount)
  303. if wantedItems[computerID] == nil then
  304. wantedItems[computerID] = {}
  305. end
  306. table.insert(wantedItems[computerID], {itemName, itemCount})
  307. saveWantedItems()
  308. end
  309.  
  310.  
  311. -- Function to save the wanted items
  312. function saveWantedItems()
  313.   for id, items in pairs(wantedItems) do
  314.     for _, item in ipairs(items) do
  315.       if not id or not item[1] or not item[2] then
  316.         print("Computer ID, item name, and item count must not be empty. Hit any button to try again.")
  317.         event, key = os.pullEvent("key")
  318.         return
  319.       end
  320.     end
  321.   end
  322.   file = fs.open("wanteditems.lua", "w")
  323.   file.write("return {\n")
  324.   for id, items in pairs(wantedItems) do
  325.     file.write((" [%d] = {\n"):format(id))
  326.     for _, item in ipairs(items) do
  327.       file.write((" {%q, %d},\n"):format(item[1], item[2]))
  328.     end
  329.     file.write(" },\n")
  330.   end
  331.   file.write("}\n")
  332.   file.close()
  333. end
  334.  
  335. function switchToMenu()
  336.     local event = os.pullEvent("mouse_click")
  337.     if event then
  338.         switchmenu = true
  339.     end
  340. end
  341.  
  342. function switchToMenu2()
  343.     local event, key = os.pullEvent("key")
  344.     if key == keys.space or key == keys.enter then
  345.         switchmenu = true
  346.     end
  347. end
  348.  
  349.  
  350. function dostuff()
  351.     sleep(sleeptime)
  352.     scanInventory(wantedItems)
  353.     notifyComputer()
  354.     notifyCount = notifyCount + 1
  355.     if notifyCount > 10 then
  356.         sleeperTable = {}
  357.         notifyCount = 0
  358.     end
  359. end
  360.  
  361. function receiveStockPile()
  362.     receiveRednetMessage("stockpileupdate")
  363. end
  364.  
  365. function receiveTableUpdate()
  366.     receiveRednetMessage("tableUpdate")
  367. end
  368.  
  369. function receiveTableChange()
  370.     receiveRednetMessage("tableChange")
  371. end
  372.  
  373. function receiveIdRequest()
  374.     receiveRednetMessage("giefIDplz")
  375. end
  376.  
  377. function receiveCraftUnable()
  378.     receiveRednetMessage("cantCraft")
  379.     -- print("cantCraft received")
  380. end
  381.  
  382.  
  383. while true do
  384. if switchmenu == true then
  385.     shell.run("addItem")
  386. end
  387. parallel.waitForAny(
  388. --general stuff
  389. dostuff, showItems, switchToMenu, switchToMenu2,
  390. --rednet protocols
  391. receiveStockPile, receiveTableUpdate, receiveTableChange, receiveIdRequest, receiveCraftUnable)
  392. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement