-- a container item defines a 'container' structure listing its
-- inventories and their properties. a container object is created
-- in order to interact with a container
local lib = starsoul.mod.lib
starsoul.item.container = lib.class {
__name = 'starsoul:container';
construct = function(stack, inv, def)
local T,G = lib.marshal.t, lib.marshal.g
local cdef = stack:get_definition()._starsoul.container;
local sd = {}
for k,v in pairs(cdef.list) do
sd[k] = {
key = v.key;
type = T.inventoryList;
}
end
return {
stack = stack, inv = inv, pdef = def, cdef = cdef;
store = lib.marshal.metaStore(sd)(stack);
}
end;
__index = {
slot = function(self, id)
return string.format("%s_%s", self.pdef.pfx, id)
end;
clear = function(self) -- initialize or empty the metadata
self:update(function()
for k,v in pairs(self.cdef.list) do
if v.sz > 0 then
self.store.write(k, {})
end
end
end)
end;
list = function(self, k) return self.store.read(k) end;
read = function(self)
local lst = {}
for k,v in pairs(self.cdef.list) do
if v.sz > 0 then lst[k] = self:list(k) end
end
return lst
end;
pull = function(self) -- align the inventories with the metadata
for k,v in pairs(self.cdef.list) do
if v.sz > 0 then
local stacks = self:list(k)
local sid = self:slot(k)
self.inv:set_size(sid, v.sz)
self.inv:set_list(sid, stacks)
end
end
end;
update = function(self, fn)
local old = ItemStack(self.stack)
if fn then fn() end
if self.cdef.handle then
self.cdef.handle(self.stack, old)
end
end;
push = function(self) -- align the metadata with the inventories
self:update(function()
for k,v in pairs(self.cdef.list) do
if v.sz > 0 then
local sid = self:slot(k)
local lst = self.inv:get_list(sid)
self.store.write(k, lst)
end
end
end)
end;
drop = function(self) -- remove the inventories from the node/entity
for k,v in pairs(self.cdef.list) do
local sid = self:slot(k)
self.inv:set_size(sid, 0)
end
end;
slotAccepts = function(self, lst, slot, stack)
end;
};
}
function starsoul.item.container.dropPrefix(inv, pfx)
local lists = inv:get_lists()
for k,v in pairs(lists) do
if #k > #pfx then
if string.sub(k, 1, #pfx + 1) == pfx .. '_' then
inv:set_size(k, 0)
end
end
end
end