mirror of
https://github.com/OgelGames/fakelib.git
synced 2024-11-13 07:20:17 +01:00
303 lines
6.6 KiB
Lua
303 lines
6.6 KiB
Lua
|
|
local fake_inventory = {}
|
|
local identifier = "fakelib:inventory"
|
|
local check, secure_table = ...
|
|
|
|
-- API functions
|
|
----------------------------------------
|
|
|
|
function fakelib.is_inventory(x)
|
|
if type(x) == "userdata" and x.get_lists then
|
|
return true
|
|
elseif type(x) == "table" and getmetatable(x) == identifier then
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
|
|
function fakelib.create_inventory(sizes)
|
|
local lists = {}
|
|
if type(sizes) == "table" then
|
|
for listname, size in pairs(sizes) do
|
|
if type(listname) == "string" and type(size) == "number" and size > 0 then
|
|
local list = {}
|
|
for i=1, size do
|
|
list[i] = ItemStack()
|
|
end
|
|
lists[listname] = list
|
|
end
|
|
end
|
|
end
|
|
return secure_table({lists = lists}, fake_inventory, identifier)
|
|
end
|
|
|
|
-- Helper functions
|
|
----------------------------------------
|
|
|
|
local function copy_list(list)
|
|
local copy = {}
|
|
for i=1, #list do
|
|
copy[i] = ItemStack(list[i])
|
|
end
|
|
return copy
|
|
end
|
|
|
|
local function stack_matches(a, b, match_meta)
|
|
if a:get_name() ~= b:get_name() then
|
|
return false
|
|
end
|
|
if match_meta then
|
|
if a:get_wear() ~= b:get_wear() then
|
|
return false
|
|
end
|
|
return a:get_meta():equals(b:get_meta())
|
|
end
|
|
return true
|
|
end
|
|
|
|
-- Inventory functions
|
|
----------------------------------------
|
|
|
|
function fake_inventory:is_empty(listname)
|
|
check(1, listname, "string", "number")
|
|
local list = self.lists[tostring(listname)]
|
|
if not list or #list == 0 then
|
|
return true
|
|
end
|
|
for _,stack in ipairs(list) do
|
|
if not stack:is_empty() then
|
|
return false
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
|
|
function fake_inventory:get_size(listname)
|
|
check(1, listname, "string", "number")
|
|
local list = self.lists[tostring(listname)]
|
|
return list and #list or 0
|
|
end
|
|
|
|
function fake_inventory:set_size(listname, size)
|
|
check(1, listname, "string", "number")
|
|
check(2, size, "number")
|
|
listname = tostring(listname)
|
|
if size ~= size or size < 0 then
|
|
return false
|
|
end
|
|
size = math.floor(size)
|
|
if size == 0 then
|
|
self.lists[listname] = nil
|
|
return true
|
|
end
|
|
local list = self.lists[listname] or {}
|
|
if #list < size then
|
|
for i=#list+1, size do
|
|
list[i] = ItemStack()
|
|
end
|
|
elseif #list > size then
|
|
for i=size+1, #list do
|
|
list[i] = nil
|
|
end
|
|
end
|
|
self.lists[listname] = list
|
|
return true
|
|
end
|
|
|
|
function fake_inventory:get_width(listname)
|
|
check(1, listname, "string", "number")
|
|
local list = self.lists[tostring(listname)]
|
|
return list and list.width or 0
|
|
end
|
|
|
|
function fake_inventory:set_width(listname, width)
|
|
check(1, listname, "string", "number")
|
|
check(2, width, "number")
|
|
local list = self.lists[tostring(listname)]
|
|
if not list or width ~= width or width < 0 then
|
|
return false
|
|
end
|
|
width = math.floor(width)
|
|
list.width = width > 0 and width or nil
|
|
return true
|
|
end
|
|
|
|
function fake_inventory:get_stack(listname, i)
|
|
check(1, listname, "string", "number")
|
|
check(2, i, "number")
|
|
i = math.floor(i)
|
|
local list = self.lists[tostring(listname)]
|
|
if not list or not list[i] then
|
|
return ItemStack()
|
|
end
|
|
return ItemStack(list[i])
|
|
end
|
|
|
|
function fake_inventory:set_stack(listname, i, stack)
|
|
check(1, listname, "string", "number")
|
|
check(2, i, "number")
|
|
stack = ItemStack(stack)
|
|
i = math.floor(i)
|
|
local list = self.lists[tostring(listname)]
|
|
if not list or not list[i] or stack:is_empty() then
|
|
return false
|
|
end
|
|
list[i] = stack
|
|
return true
|
|
end
|
|
|
|
function fake_inventory:get_list(listname)
|
|
check(1, listname, "string", "number")
|
|
local list = self.lists[tostring(listname)]
|
|
return list and copy_list(list) or nil
|
|
end
|
|
|
|
function fake_inventory:set_list(listname, list)
|
|
check(1, listname, "string", "number")
|
|
listname = tostring(listname)
|
|
if list == nil then
|
|
self.lists[listname] = nil
|
|
return
|
|
end
|
|
check(2, list, "table")
|
|
local new_list, size = {}, 0
|
|
for i,s in pairs(list) do
|
|
check(4, i, "number")
|
|
if i > size then
|
|
size = i
|
|
end
|
|
new_list[i] = ItemStack(s)
|
|
end
|
|
for i=1, size do
|
|
if not new_list[i] then
|
|
new_list[i] = ItemStack()
|
|
end
|
|
end
|
|
self.lists[listname] = new_list
|
|
end
|
|
|
|
function fake_inventory:get_lists()
|
|
local lists = {}
|
|
for listname, list in pairs(self.lists) do
|
|
lists[listname] = copy_list(list)
|
|
end
|
|
return lists
|
|
end
|
|
|
|
function fake_inventory:set_lists(lists)
|
|
check(1, lists, "table")
|
|
local new_lists = {}
|
|
for listname, list in pairs(lists) do
|
|
check(3, listname, "string", "number")
|
|
check(3, list, "table")
|
|
listname = tostring(listname)
|
|
local new_list, size = {}, 0
|
|
for i,s in pairs(list) do
|
|
check(5, i, "number")
|
|
if i > size then
|
|
size = i
|
|
end
|
|
new_list[i] = ItemStack(s)
|
|
end
|
|
for i=1, size do
|
|
if not new_list[i] then
|
|
new_list[i] = ItemStack()
|
|
end
|
|
end
|
|
new_lists[listname] = new_list
|
|
end
|
|
self.lists = new_lists
|
|
end
|
|
|
|
function fake_inventory:add_item(listname, stack)
|
|
check(1, listname, "string", "number")
|
|
stack = ItemStack(stack)
|
|
local list = self.lists[tostring(listname)]
|
|
if not list or #list == 0 or stack:is_empty() then
|
|
return stack
|
|
end
|
|
local empty = {}
|
|
for _,s in ipairs(list) do
|
|
if s:is_empty() then
|
|
table.insert(empty, s)
|
|
else
|
|
stack = s:add_item(stack)
|
|
if stack:is_empty() then
|
|
return stack
|
|
end
|
|
end
|
|
end
|
|
for _,s in ipairs(empty) do
|
|
stack = s:add_item(stack)
|
|
if stack:is_empty() then
|
|
return stack
|
|
end
|
|
end
|
|
return stack
|
|
end
|
|
|
|
function fake_inventory:room_for_item(listname, stack)
|
|
check(1, listname, "string", "number")
|
|
stack = ItemStack(stack)
|
|
local list = self.lists[tostring(listname)]
|
|
if not list or #list == 0 or stack:is_empty() then
|
|
return false
|
|
end
|
|
for _,s in ipairs(copy_list(list)) do
|
|
stack = s:add_item(stack)
|
|
if stack:is_empty() then
|
|
return true
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
function fake_inventory:contains_item(listname, stack, match_meta)
|
|
check(1, listname, "string", "number")
|
|
stack = ItemStack(stack)
|
|
local list = self.lists[tostring(listname)]
|
|
if not list or stack:is_empty() or stack:is_empty() then
|
|
return false
|
|
end
|
|
local count = stack:get_count()
|
|
for _,s in ipairs(list) do
|
|
if stack_matches(stack, s, match_meta) then
|
|
count = count - s:get_count()
|
|
if count <= 0 then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
function fake_inventory:remove_item(listname, stack)
|
|
check(1, listname, "string", "number")
|
|
stack = ItemStack(stack)
|
|
local list = self.lists[tostring(listname)]
|
|
if not list or #list == 0 or stack:is_empty() then
|
|
return ItemStack()
|
|
end
|
|
local name, remaining, removed = stack:get_name(), stack:get_count()
|
|
for i=#list, 1, -1 do
|
|
local s = list[i]
|
|
if s:get_name() == name then
|
|
s = s:take_item(remaining)
|
|
remaining = remaining - s:get_count()
|
|
if not removed then
|
|
removed = s
|
|
else
|
|
removed:set_count(removed:get_count() + s:get_count())
|
|
end
|
|
if remaining == 0 then
|
|
break
|
|
end
|
|
end
|
|
end
|
|
return removed or ItemStack()
|
|
end
|
|
|
|
function fake_inventory.get_location()
|
|
return {type = "undefined"}
|
|
end
|