Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --os.execute("./pastebin.lua get -f 0W0MeXti inventory.lua")
- local inventory = {}
- inventory.__index = inventory;
- local function abort(reason)
- io.write(reason.."\n")
- os.exit()
- end
- local function err(reason)
- return false, reason
- end
- local component = require("component")
- if not component.isAvailable("inventory_controller") then
- abort("No inventory controller is installed")
- end
- local robot = require("robot")
- local sides = require("sides")
- local inv = component.inventory_controller
- -- Globals
- function stacksEqual(a,b)
- if a == nil or b == nil then
- return false
- end
- return
- ((a.damage or 0) == (b.damage or 0))
- and ((a.name or "nil") == (b.name or "nil"))
- end
- function arrayContains(array, item)
- for cindex, iarray in pairs(array) do
- if stacksEqual(iarray, item) then
- return true
- end
- end
- return false
- end
- -- Remote Inventory
- function inventory.getExternal(side)
- if inv.getInventorySize(side) == nil then return nil end
- local ex = {}
- ex.__index = ex;
- ex.side = side
- function ex.getSize()
- return inv.getInventorySize(ex.side)
- end
- --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}
- function ex.count(slot)
- local INV_COUNT = inv.getInventorySize(ex.side)
- if INV_COUNT == nil then return err("No remote inventory") end
- local count = 0
- if type(slot) == "number" then
- local item = inv.getStackInSlot(ex.side, slot)
- if item == nil then
- return 0
- else
- return item.size
- end
- else
- for n=1,INV_COUNT do
- local item = inv.getStackInSlot(ex.side, n)
- if item ~= nil then
- if stacksEqual(item, slot) then
- count = count + item.size
- end
- end
- end
- end
- return count
- end
- function ex.countEmpty()
- local INV_COUNT = inv.getInventorySize(ex.side)
- if INV_COUNT == nil then return err("No remote inventory") end
- local count = 0
- for n=1,INV_COUNT do
- if inv.getStackInSlot(ex.side, n) == nil then count = count + 1 end
- end
- return count
- end
- -- Returns true if there are no empty slots remaining.
- function ex.isFull()
- return ex.countEmpty() == 0
- end
- function ex.isEmpty()
- return ex.countEmpty() == ex.getSize()
- end
- function canPushPull()
- return
- ex.side == sides.bottom or
- ex.side == sides.top or
- ex.side == sides.front
- end
- function ex.depositAll()
- local INV_COUNT = inv.getInventorySize(ex.side)
- if INV_COUNT == nil then return err("No remote inventory") end
- if not canPushPull() then return err("Inventory must be at top, bottom, or in front") end
- local count = 0
- local success = true
- for n=1,robot.inventorySize() do
- robot.select(n)
- ex.depositSelected()
- end
- robot.select(1)
- return success, count
- end
- function ex.depositSelected()
- if not canPushPull() then return err("Inventory must be at top, bottom, or in front") end
- local drop = robot.drop
- if ex.side == sides.bottom then drop = robot.dropDown
- elseif ex.side == sides.top then drop = robot.dropUp end
- local item = inv.getStackInInternalSlot(n);
- if item ~= nil then
- local num = item.size
- if drop() then
- return true, num
- else
- return false, 0
- end
- end
- end
- function ex.deposit(itemToDeposit)
- local INV_COUNT = inv.getInventorySize(ex.side)
- if INV_COUNT == nil then return err("No remote inventory") end
- local count = 0
- for n=1,robot.inventorySize() do
- local item = inv.getStackInInternalSlot(n)
- if item ~= nil then
- if stacksEqual(itemToDeposit, item) then
- robot.select(n)
- local success, num = ex.depositSelected()
- if not success then break end
- count = count + num
- end
- end
- end
- robot.select(1)
- return count
- end
- function ex.fetch(itemToPull,count)
- local INV_COUNT = inv.getInventorySize(ex.side)
- if INV_COUNT == nil then return err("No remote inventory") end
- local remaining = count or 65536
- for n=1,INV_COUNT do
- local item = inv.getStackInSlot(ex.side,n)
- if item ~= nil then
- if stacksEqual(item, itemToPull) then
- local toPull = remaining > item.size and item.size or remaining
- if not inv.suckFromSlot(ex.side, n, toPull) then break end
- remaining = remaining - toPull
- end
- end
- if remaining <= 0 then break end
- end
- return remaining <= 0, remaining
- end
- function ex.fetchAll()
- local INV_COUNT = inv.getInventorySize(ex.side)
- if INV_COUNT == nil then return err("No remote inventory") end
- if canPushPull() then
- local suck = robot.suck
- if ex.side == sides.bottom then suck = robot.suckDown
- elseif ex.side == sides.top then suck = robot.suckUp end
- while suck() do end
- return ex.isEmpty()
- else
- for n=1,INV_COUNT do
- local item = inv.getStackInSlot(ex.side, n)
- if item ~= nil then
- if not inv.suckFromSlot(ex.side, n, item.size) then return false end
- end
- end
- end
- return true
- end
- return ex
- end
- -- Local Inventory
- inventory.size = robot.inventorySize()
- function inventory.count(slot)
- if type(slot) == "number" then
- local item = inv.getStackInInternalSlot(n)
- if item == nil then
- return 0
- else
- return item.size
- end
- else
- local count = 0
- for n=1,inventory.size do
- robot.select(n)
- local item = inv.getStackInInternalSlot(n)
- if stacksEqual(item,slot) then
- count = count + item.size
- end
- end
- end
- end
- function inventory.isFull()
- for n=1,inventory.size do
- if inv.getStackInInternalSlot(n) == nil then
- return false
- end
- end
- return true
- end
- --Moves all items into the first available empty slot, ensuring that all empty slots are in the later slots
- function inventory.compact()
- local source = inventory.size
- local dest = 1
- repeat
- if inventory.count(dest) > 0 then
- dest = dest + 1
- elseif inventory.count(source) == 0 then
- source = source - 1
- else
- robot.select(source)
- robot.transferTo(dest)
- dest = dest + 1
- source = source - 1
- end
- until source <= dest
- robot.select(1)
- end
- --Drops all items specified, or everything if items is nil. Places items into an inventory if one exists in front of the robot
- function inventory.drop(items)
- local dropCount = 0
- if items == nil then
- for n=1,inventory.size do
- robot.select(n)
- local item = inv.getStackInInternalSlot()
- if item ~= nil then
- local num = item.size
- if robot.drop() then
- dropCount = dropCount + num
- end
- end
- end
- robot.select(1)
- return dropCount
- else
- for n=1,inventory.size do
- local item = inv.getStackInInternalSlot(n)
- if item ~= nil then
- if arrayContains(items, item) then
- dropCount = dropCount + item.size
- robot.select(n)
- robot.drop()
- end
- end
- end
- robot.select(1)
- return dropCount
- end
- end
- function inventory.select(itemToFind)
- for n=1,inventory.size do
- local item = inv.getStackInInternalSlot(n)
- if item ~= nil then
- if stacksEqual(item, itemToFind) then
- robot.select(n)
- return true
- end
- end
- end
- return false
- end
- function inventory.count(itemToCount)
- local count = 0
- if type(itemToCount) == "number" then
- local item = inv.getStackInInternalSlot(itemToCount)
- if item == nil then
- return 0
- else
- return item.size
- end
- else
- for n=1,inventory.size do
- local item = inv.getStackInInternalSlot(n)
- if item ~= nil then
- if stacksEqual(item, itemToCount) then
- count = count + item.size
- end
- end
- end
- end
- return count
- end
- function inventory.stock(side,item,count)
- local ex = inventory.getExternal(side)
- local existing = inventory.count(item)
- local available = ex.count(item)
- if existing < count then
- if available - existing < count then return err("Not enough items") end
- ex.fetch(item, count - existing)
- end
- end
- function inventory.isContainer(side)
- return inv.getInventorySize(side) ~= nil
- end
- return inventory
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement