Started Inventory class; added item sorting

turtle-class^2
Jef Roosens 2020-12-31 09:11:32 +01:00
parent d5655734cb
commit 61b178535a
1 changed files with 150 additions and 0 deletions

View File

@ -0,0 +1,150 @@
-- 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}