Advertisement
Robear9992

Robot Inventory Library - OpenComputers

Apr 27th, 2018
232
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.05 KB | None | 0 0
  1. --os.execute("./pastebin.lua get -f 0W0MeXti inventory.lua")
  2.  
  3. local inventory = {}
  4. inventory.__index = inventory;
  5.  
  6. local function abort(reason)
  7.     io.write(reason.."\n")
  8.     os.exit()
  9. end
  10.  
  11. local function err(reason)
  12.     return false, reason
  13. end
  14.  
  15. local component = require("component")
  16.  
  17. if not component.isAvailable("inventory_controller") then
  18.     abort("No inventory controller is installed")
  19. end
  20.  
  21. local robot = require("robot")
  22. local sides = require("sides")
  23. local inv = component.inventory_controller
  24.  
  25. -- Globals
  26. function stacksEqual(a,b)
  27.     if a == nil or b == nil then
  28.         return false
  29.     end
  30.     return
  31.         ((a.damage or 0) == (b.damage or 0))
  32.     and ((a.name or "nil") == (b.name or "nil"))
  33. end
  34.  
  35. function arrayContains(array, item)
  36.     for cindex, iarray in pairs(array) do
  37.         if stacksEqual(iarray, item) then
  38.             return true
  39.         end
  40.     end
  41.     return false
  42. end
  43.  
  44. -- Remote Inventory
  45. function inventory.getExternal(side)
  46.     if inv.getInventorySize(side) == nil then return nil end  
  47.  
  48.     local ex = {}
  49.     ex.__index = ex;
  50.  
  51.     ex.side = side
  52.  
  53.     function ex.getSize()
  54.         return inv.getInventorySize(ex.side)
  55.     end
  56.    
  57.     --Counts the number of items in the supplied SLOT number OR the number of items currently contained of SLOT as an item type {name,id,damage}
  58.     function ex.count(slot)
  59.         local INV_COUNT = inv.getInventorySize(ex.side)
  60.         if INV_COUNT == nil then return err("No remote inventory") end  
  61.  
  62.         local count = 0
  63.         if type(slot) == "number" then
  64.             local item = inv.getStackInSlot(ex.side, slot)
  65.             if item == nil then
  66.                 return 0
  67.             else
  68.                 return item.size
  69.             end
  70.         else
  71.             for n=1,INV_COUNT do
  72.                 local item = inv.getStackInSlot(ex.side, n)
  73.                 if item ~= nil then
  74.                     if stacksEqual(item, slot) then
  75.                         count = count + item.size
  76.                     end
  77.                 end
  78.             end
  79.         end
  80.         return count
  81.     end
  82.    
  83.     function ex.countEmpty()
  84.         local INV_COUNT = inv.getInventorySize(ex.side)
  85.         if INV_COUNT == nil then return err("No remote inventory") end  
  86.  
  87.         local count = 0
  88.         for n=1,INV_COUNT do
  89.             if inv.getStackInSlot(ex.side, n) == nil then count = count + 1 end
  90.         end
  91.         return count
  92.     end
  93.  
  94.  
  95.     -- Returns true if there are no empty slots remaining.
  96.     function ex.isFull()
  97.         return ex.countEmpty() == 0
  98.     end
  99.  
  100.     function ex.isEmpty()
  101.         return ex.countEmpty() == ex.getSize()
  102.     end
  103.  
  104.     function canPushPull()
  105.         return
  106.             ex.side == sides.bottom or
  107.             ex.side == sides.top or
  108.             ex.side == sides.front
  109.     end
  110.  
  111.  
  112.     function ex.depositAll()
  113.         local INV_COUNT = inv.getInventorySize(ex.side)
  114.         if INV_COUNT == nil then return err("No remote inventory") end  
  115.         if not canPushPull() then return err("Inventory must be at top, bottom, or in front") end  
  116.        
  117.         local count = 0
  118.         local success = true
  119.         for n=1,robot.inventorySize() do
  120.             robot.select(n)
  121.             ex.depositSelected()
  122.         end
  123.  
  124.         robot.select(1)
  125.         return success, count
  126.     end
  127.  
  128.     function ex.depositSelected()
  129.         if not canPushPull() then return err("Inventory must be at top, bottom, or in front") end  
  130.         local drop = robot.drop
  131.         if ex.side == sides.bottom then drop = robot.dropDown
  132.         elseif ex.side == sides.top then drop = robot.dropUp end
  133.  
  134.         local item = inv.getStackInInternalSlot(n);
  135.         if item ~= nil then
  136.             local num = item.size
  137.             if drop() then
  138.                 return true, num
  139.             else
  140.                 return false, 0
  141.             end
  142.         end
  143.     end
  144.  
  145.     function ex.deposit(itemToDeposit)
  146.         local INV_COUNT = inv.getInventorySize(ex.side)
  147.         if INV_COUNT == nil then return err("No remote inventory") end  
  148.  
  149.         local count = 0
  150.        
  151.         for n=1,robot.inventorySize() do
  152.             local item = inv.getStackInInternalSlot(n)
  153.             if item ~= nil then
  154.                 if stacksEqual(itemToDeposit, item) then
  155.                     robot.select(n)
  156.                     local success, num = ex.depositSelected()
  157.                     if not success then break end
  158.                     count = count + num
  159.                 end
  160.             end
  161.         end
  162.         robot.select(1)
  163.         return count  
  164.     end
  165.  
  166.     function ex.fetch(itemToPull,count)
  167.         local INV_COUNT = inv.getInventorySize(ex.side)
  168.         if INV_COUNT == nil then return err("No remote inventory") end  
  169.  
  170.         local remaining = count or 65536
  171.         for n=1,INV_COUNT do
  172.             local item = inv.getStackInSlot(ex.side,n)
  173.             if item ~= nil then
  174.                 if stacksEqual(item, itemToPull) then
  175.                     local toPull =  remaining > item.size and item.size or remaining
  176.                     if not inv.suckFromSlot(ex.side, n, toPull) then break end
  177.                     remaining = remaining - toPull
  178.                 end
  179.             end
  180.             if remaining <= 0 then break end
  181.         end
  182.         return remaining <= 0, remaining
  183.     end
  184.  
  185.     function ex.fetchAll()
  186.         local INV_COUNT = inv.getInventorySize(ex.side)
  187.         if INV_COUNT == nil then return err("No remote inventory") end  
  188.  
  189.         if canPushPull() then
  190.             local suck = robot.suck
  191.             if ex.side == sides.bottom then suck = robot.suckDown
  192.             elseif ex.side == sides.top then suck = robot.suckUp end
  193.  
  194.             while suck() do end
  195.             return ex.isEmpty()
  196.         else
  197.             for n=1,INV_COUNT do
  198.                 local item = inv.getStackInSlot(ex.side, n)
  199.                 if item ~= nil then
  200.                     if not inv.suckFromSlot(ex.side, n, item.size) then return false end
  201.                 end
  202.             end
  203.         end
  204.         return true
  205.     end
  206.  
  207.     return ex
  208. end
  209.  
  210.  
  211.  
  212. -- Local Inventory
  213. inventory.size = robot.inventorySize()
  214. function inventory.count(slot)
  215.     if type(slot) == "number" then
  216.         local item = inv.getStackInInternalSlot(n)
  217.         if item == nil then
  218.             return 0
  219.         else
  220.             return item.size
  221.         end
  222.     else
  223.         local count = 0
  224.         for n=1,inventory.size do
  225.             robot.select(n)
  226.             local item = inv.getStackInInternalSlot(n)
  227.             if stacksEqual(item,slot) then
  228.                 count = count + item.size
  229.             end
  230.         end
  231.     end
  232. end
  233.  
  234. function inventory.isFull()
  235.     for n=1,inventory.size do
  236.         if inv.getStackInInternalSlot(n) == nil then
  237.             return false
  238.         end
  239.     end
  240.     return true
  241. end
  242.  
  243. --Moves all items into the first available empty slot, ensuring that all empty slots are in the later slots
  244. function inventory.compact()
  245.     local source = inventory.size
  246.     local dest = 1
  247.        
  248.     repeat
  249.         if inventory.count(dest) > 0 then
  250.                 dest = dest + 1
  251.         elseif inventory.count(source) == 0 then
  252.                 source = source - 1
  253.         else
  254.             robot.select(source)
  255.             robot.transferTo(dest)
  256.             dest = dest + 1
  257.             source = source - 1
  258.         end
  259.     until source <= dest
  260.     robot.select(1)
  261. end
  262.  
  263. --Drops all items specified, or everything if items is nil. Places items into an inventory if one exists in front of the robot
  264. function inventory.drop(items)
  265.     local dropCount = 0
  266.    
  267.     if items == nil then
  268.         for n=1,inventory.size do
  269.             robot.select(n)
  270.             local item = inv.getStackInInternalSlot()
  271.             if item ~= nil then
  272.                 local num = item.size
  273.                 if robot.drop() then
  274.                     dropCount = dropCount + num
  275.                 end
  276.             end
  277.         end
  278.         robot.select(1)
  279.         return dropCount  
  280.     else
  281.         for n=1,inventory.size do
  282.             local item = inv.getStackInInternalSlot(n)
  283.             if item ~= nil then
  284.                 if arrayContains(items, item) then
  285.                     dropCount = dropCount + item.size
  286.                     robot.select(n)
  287.                     robot.drop()
  288.                 end
  289.             end
  290.         end
  291.         robot.select(1)
  292.         return dropCount  
  293.     end
  294. end
  295.  
  296. function inventory.select(itemToFind)
  297.     for n=1,inventory.size do
  298.         local item = inv.getStackInInternalSlot(n)
  299.         if item ~= nil then
  300.             if stacksEqual(item, itemToFind) then
  301.                 robot.select(n)
  302.                 return true
  303.             end
  304.         end
  305.     end
  306.     return false
  307. end
  308.  
  309. function inventory.count(itemToCount)
  310.     local count = 0
  311.     if type(itemToCount) == "number" then
  312.         local item = inv.getStackInInternalSlot(itemToCount)
  313.         if item == nil then
  314.             return 0
  315.         else
  316.             return item.size
  317.         end
  318.     else
  319.         for n=1,inventory.size do
  320.             local item = inv.getStackInInternalSlot(n)
  321.             if item ~= nil then
  322.                 if stacksEqual(item, itemToCount) then
  323.                     count = count + item.size
  324.                 end
  325.             end
  326.         end
  327.     end
  328.     return count
  329. end
  330.  
  331. function inventory.stock(side,item,count)
  332.     local ex = inventory.getExternal(side)
  333.     local existing = inventory.count(item)
  334.     local available = ex.count(item)
  335.  
  336.     if existing < count then
  337.         if available - existing < count then return err("Not enough items") end
  338.         ex.fetch(item, count - existing)
  339.     end
  340. end
  341.  
  342. function inventory.isContainer(side)
  343.     return inv.getInventorySize(side) ~= nil
  344. end
  345.  
  346. return inventory
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement