-- Created by Jef Roosens -- Manages the inventory local Inventory = { selected = nil, -- Currently selected slot slots = nil, -- table containing contents of all slots items = nil, -- table containing items and their slots (fast lookup) free = nil, -- table containing free slots } function Inventory:new(o) o = o or {} setmetatable(o, self) self.__index = self o.selected = selected or turtle.getSelectedSlot() -- Update inventory if no data is provided -- Empty tables are also truethy if o.slots == nil or o.items == nil then o:update() end return o end -- Select the given slot if valid -- -- @param slot slot to select function Inventory:select(slot) -- Exit if needed if self.selected == slot or slot < 1 or slot > 16 then return end turtle.select(slot) self.selected = slot end -- Transfer items between slots. -- -- @param from slot to transfer from -- @param to slot to transfer to -- @param count amount of items to transfer. If count is not specified or count -- is greater than the possible transfer, the maximum transfer will be done. -- @return wether all items were transferred function Inventory:transfer(from, to, count) -- Exit if from is empty if not self.slots[from] then return true end count = count or self.slots[from].count local return_value = true -- If to isn't empty, check if we can fit it all and if they're the same -- item type if self.slots[to] then -- Exit if it's a differen item type or if there's no space left if self.slots[to].name ~= self.slots[from].name or self.slots[to].count == 64 then return false end count = math.min(count, 64 - self.slots[to].count) return_value = count == self.slots[from].count end -- Transfer the items self:select(from) turtle.transferTo(to, count) self:update() return return_value end -- Scan inventory and store updates function Inventory:update() local slots, items = {}, {} for i = 1, 16 do local data = turtle.getItemDetail(i) if data then slots[i] = data if items[data.name] then table.insert(items[data.name], i) else items[data.name] = {i} end end end self.slots = slots self.items = items end -- Returns wether or not the inventory contains the given item -- -- @param item_name item name to look for -- @return bool wether or not the item is in the inventory function Inventory:has(item_name) return self.items[item_name] ~= nil end -- Returns wether the requested slot is free -- -- @param slot slot to check function Inventory:is_free(slot) return self.slots[slot] == nil end -- Compact an item in the inventory; this means moving as much of the items to -- as little of the used slots as possible -- -- @param item_name item to compact function Inventory:sort_item(item_name) -- atm we assume the item is in the inventory local slots = self.items[item_name] local i, j = 1, 2 while j <= #slots do if self:transfer(slots[j], slots[i]) then j = j + 1 else i = i + 1 j = i + 1 end end end -- Compact the inventory; this means moving all items to the lowest possible -- slots function Inventory:sort() -- Sort all items for item, _ in pairs(self.items) do self:sort_item(item) end -- Move them all to lowest slots -- TODO implement this end return {Inventory=Inventory}