1227 lines
38 KiB
Lua
1227 lines
38 KiB
Lua
|
|
storage_interface = {}
|
|
|
|
storage_interface.storage_nodes = {
|
|
"default:chest",
|
|
"default:chest_open",
|
|
"default:chest_locked",
|
|
"default:chest_locked_open"
|
|
}
|
|
|
|
storage_interface.connection_nodes = {
|
|
"storage_interface:storage_interface",
|
|
"storage_interface:storage_connector",
|
|
"storage_interface:storage_connector_embedded"
|
|
}
|
|
|
|
if minetest.get_modpath("technic_chests") then
|
|
table.insert(storage_interface.storage_nodes, "technic:iron_chest")
|
|
table.insert(storage_interface.storage_nodes, "technic:iron_locked_chest")
|
|
table.insert(storage_interface.storage_nodes, "technic:copper_chest")
|
|
table.insert(storage_interface.storage_nodes, "technic:copper_locked_chest")
|
|
table.insert(storage_interface.storage_nodes, "technic:silver_chest")
|
|
table.insert(storage_interface.storage_nodes, "technic:silver_locked_chest")
|
|
table.insert(storage_interface.storage_nodes, "technic:gold_chest")
|
|
table.insert(storage_interface.storage_nodes, "technic:gold_locked_chest")
|
|
table.insert(storage_interface.storage_nodes, "technic:mithril_chest")
|
|
table.insert(storage_interface.storage_nodes, "technic:mithril_locked_chest")
|
|
end
|
|
|
|
if minetest.get_modpath("connected_chests") then
|
|
table.insert(storage_interface.storage_nodes, "default:chest_connected_left")
|
|
table.insert(storage_interface.storage_nodes, "default:chest_locked_connected_left")
|
|
table.insert(storage_interface.connection_nodes, "default:chest_connected_right")
|
|
table.insert(storage_interface.connection_nodes, "default:chest_locked_connected_right")
|
|
end
|
|
|
|
-- helper functions
|
|
|
|
local function table_contains(t, v)
|
|
for _, i in ipairs(t) do
|
|
if i == v then
|
|
return true
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
local function table_contains_table(t, v)
|
|
for _, i in ipairs(t) do
|
|
local c = 0
|
|
local l = 0
|
|
for m, k in pairs(i) do
|
|
l = l+1
|
|
if v[m] == k then
|
|
c = c+1
|
|
end
|
|
end
|
|
if c == l then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
|
|
local function pos_to_string(pos)
|
|
return pos.x .. "," .. pos.y .. "," .. pos.z
|
|
end
|
|
|
|
local function create_changed_pos(pos, x, y, z)
|
|
local new_pos = table.copy(pos)
|
|
new_pos.x = new_pos.x + x
|
|
new_pos.y = new_pos.y + y
|
|
new_pos.z = new_pos.z + z
|
|
return new_pos
|
|
end
|
|
|
|
local function get_connected_nodes(pos, player)
|
|
local p1 = create_changed_pos(pos, 10, 10, 10)
|
|
local p2 = create_changed_pos(pos, -10, -10, -10)
|
|
local pos_table = {pos}
|
|
for _, tpos in ipairs(pos_table) do
|
|
local check_pos = {
|
|
create_changed_pos(tpos, 1, 0, 0),
|
|
create_changed_pos(tpos, -1, 0, 0),
|
|
create_changed_pos(tpos, 0, 1, 0),
|
|
create_changed_pos(tpos, 0, -1, 0),
|
|
create_changed_pos(tpos, 0, 0, 1),
|
|
create_changed_pos(tpos, 0, 0, -1)
|
|
}
|
|
for _, cpos in ipairs(check_pos) do
|
|
local nodename = minetest.get_node(cpos).name
|
|
if (table_contains(storage_interface.storage_nodes, nodename) or
|
|
table_contains(storage_interface.connection_nodes, nodename)) and
|
|
not table_contains_table(pos_table, cpos) then
|
|
table.insert(pos_table, cpos)
|
|
end
|
|
end
|
|
end
|
|
local rc = 0
|
|
for k = 1, #pos_table do
|
|
local kpos = pos_table[k - rc]
|
|
local owner = minetest.get_meta(kpos):get_string("owner")
|
|
if table_contains(storage_interface.connection_nodes, minetest.get_node(kpos).name) or
|
|
(owner ~= "" and owner ~= player and player ~= ".ignore_player") then
|
|
table.remove(pos_table, k - rc)
|
|
rc = rc + 1
|
|
end
|
|
end
|
|
return pos_table
|
|
end
|
|
|
|
local function match_filter(item_name, filter)
|
|
if filter == "" then
|
|
return true
|
|
end
|
|
local filter_table = string.split(filter, ",", false, -1)
|
|
for _, filter_string in ipairs(filter_table) do
|
|
if filter_string ~= "" then
|
|
if string.sub(filter_string, 1, 6) == "group:" then
|
|
if minetest.get_item_group(item_name, string.sub(filter_string, 7)) > 0 then
|
|
return true
|
|
end
|
|
elseif string.sub(filter_string, 1, 1) == '"' and
|
|
string.sub(filter_string, string.len(filter_string)) == '"' then
|
|
if string.sub(filter_string, 2, string.len(filter_string)-1) == item_name then
|
|
return true
|
|
end
|
|
else
|
|
if string.find(item_name, filter_string) then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
-- storage_inv functions
|
|
|
|
local function storage_remove_item(pos, stack, match_meta_and_wear, player)
|
|
local nodes = get_connected_nodes(pos, player)
|
|
local take_count = stack:get_count(stack)
|
|
local return_stack = ItemStack(nil)
|
|
local ostack = stack:get_name()
|
|
if match_meta_and_wear == true then
|
|
ostack = stack:peek_item(1):to_string()
|
|
end
|
|
for _, tpos in ipairs(nodes) do
|
|
local meta = minetest.get_meta(tpos)
|
|
local inv = meta:get_inventory()
|
|
for listname, list in pairs(inv:get_lists()) do
|
|
for i, istack in pairs(list) do
|
|
local oistack = istack:get_name()
|
|
if match_meta_and_wear == true then
|
|
oistack = istack:peek_item(1):to_string()
|
|
end
|
|
if ostack == oistack then
|
|
local available_count = istack:get_count()
|
|
|
|
if take_count <= available_count then
|
|
return_stack:add_item(istack:take_item(take_count))
|
|
inv:set_stack(listname, i, istack)
|
|
return return_stack
|
|
else
|
|
return_stack:add_item(istack:take_item(available_count))
|
|
inv:set_stack(listname, i, istack)
|
|
take_count = take_count - available_count
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if not return_stack:is_empty() then
|
|
return return_stack
|
|
end
|
|
return false
|
|
end
|
|
|
|
-- not perfect
|
|
local function storage_room_for_item(pos, stack, player)
|
|
local nodes = get_connected_nodes(pos, player)
|
|
for _, tpos in ipairs(nodes) do
|
|
local meta = minetest.get_meta(tpos)
|
|
local inv = meta:get_inventory()
|
|
local filter = meta:get_string("storage_interface_filter_string")
|
|
if match_filter(stack:get_name(), filter) then
|
|
for listname, _ in pairs(inv:get_lists()) do
|
|
if inv:room_for_item(listname, stack) then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
-- not perfect
|
|
local function storage_add_item(pos, stack, player)
|
|
local nodes = get_connected_nodes(pos, player)
|
|
local possible_destinations = {}
|
|
for _, tpos in ipairs(nodes) do
|
|
local meta = minetest.get_meta(tpos)
|
|
local inv = meta:get_inventory()
|
|
local filter = meta:get_string("storage_interface_filter_string")
|
|
if match_filter(stack:get_name(), filter) then
|
|
for listname, _ in pairs(inv:get_lists()) do
|
|
if inv:room_for_item(listname, stack) then
|
|
local priority = meta:get_int("storage_interface_priority") or 0
|
|
table.insert(possible_destinations, {pos = tpos, listname = listname, priority = priority})
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if not possible_destinations[1] then
|
|
return stack
|
|
end
|
|
table.sort(possible_destinations, function(e1, e2)
|
|
return e1.priority > e2.priority
|
|
end)
|
|
local meta = minetest.get_meta(possible_destinations[1].pos)
|
|
local inv = meta:get_inventory()
|
|
return inv:add_item(possible_destinations[1].listname, stack)
|
|
end
|
|
|
|
-- storage_table functions
|
|
|
|
local function get_storage_table(pos, player)
|
|
local pos_table = get_connected_nodes(pos, player)
|
|
local storage_table = {}
|
|
for _, tpos in ipairs(pos_table) do
|
|
local meta = minetest.get_meta(tpos)
|
|
local inv = meta:get_inventory()
|
|
for list, _ in pairs(inv:get_lists()) do
|
|
for i = 1, inv:get_size(list), 1 do
|
|
table.insert(storage_table, {
|
|
pos = tpos,
|
|
listname = list,
|
|
index = i,
|
|
itemstack = inv:get_stack(list, i),
|
|
priority = meta:get_int("storage_interface_priority") or 0,
|
|
filter = meta:get_string("storage_interface_filter_string") or ""
|
|
})
|
|
end
|
|
end
|
|
end
|
|
return storage_table
|
|
end
|
|
|
|
local function get_oikt_index(itemstack, ignore_wam)
|
|
local index = ""
|
|
if ignore_wam == "false" then
|
|
local itemstack_table = itemstack:to_table() or {}
|
|
itemstack_table.count = 1
|
|
index = ItemStack(itemstack_table):to_string()
|
|
else
|
|
index = itemstack:get_name()
|
|
end
|
|
return index
|
|
end
|
|
|
|
local function get_one_item_kind_table(storage_table, ignore_wam)
|
|
local out_table = {}
|
|
for _, entry in ipairs(storage_table) do
|
|
local name = get_oikt_index(entry.itemstack, ignore_wam)
|
|
out_table[name] = out_table[name] or {}
|
|
local stack_count = entry.itemstack:get_count()
|
|
local oikt_count = out_table[name].count or 0
|
|
local oc_stack_count = entry.count
|
|
if oc_stack_count then
|
|
out_table[name].count = oc_stack_count
|
|
else
|
|
out_table[name].count = stack_count + oikt_count
|
|
end
|
|
table.insert(out_table[name], entry)
|
|
|
|
end
|
|
for _, entry_table in pairs(out_table) do
|
|
table.sort(entry_table, function(entry1, entry2)
|
|
return entry1.itemstack:get_count() > entry2.itemstack:get_count()
|
|
end)
|
|
end
|
|
return out_table
|
|
end
|
|
|
|
local function sort_storage_table(storage_table, mode, ignore_wam)
|
|
if mode == "count" then
|
|
local oikt = get_one_item_kind_table(storage_table, ignore_wam)
|
|
for _, e in ipairs(storage_table) do
|
|
local name = get_oikt_index(e.itemstack, ignore_wam)
|
|
if not e.count then
|
|
if oikt[name] then
|
|
e.count = oikt[name].count
|
|
else
|
|
e.count = 0
|
|
end
|
|
end
|
|
end
|
|
local ioikt = {}
|
|
for _, ioikt_e in pairs(oikt) do
|
|
table.insert(ioikt, ioikt_e)
|
|
end
|
|
table.sort(ioikt, function(entry1, entry2)
|
|
local p1 = entry1.count
|
|
local p2 = entry2.count
|
|
if p1 == p2 then
|
|
local itemstack1 = entry1[1].itemstack
|
|
local itemstack2 = entry2[1].itemstack
|
|
local name1 = itemstack1:get_name()
|
|
local name2 = itemstack2:get_name()
|
|
if name1 == name2 then
|
|
p2 = itemstack1:get_wear()
|
|
p1 = itemstack2:get_wear()
|
|
else
|
|
local nst = {}
|
|
nst[1] = name1
|
|
nst[2] = name2
|
|
table.sort(nst)
|
|
if nst[1] == name1 and nst[2] == name2 then
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
end
|
|
return p1 > p2
|
|
end)
|
|
storage_table = {}
|
|
for _, entry_table in ipairs(ioikt) do
|
|
for _, entry in ipairs(entry_table) do
|
|
table.insert(storage_table, entry)
|
|
end
|
|
end
|
|
else
|
|
table.sort(storage_table, function(entry1, entry2)
|
|
local p1 = 0
|
|
local p2 = 0
|
|
local itemstack1 = entry1.itemstack
|
|
local itemstack2 = entry2.itemstack
|
|
local name1 = itemstack1:get_name()
|
|
local name2 = itemstack2:get_name()
|
|
if name1 == name2 then
|
|
p1 = itemstack2:get_count()
|
|
p2 = itemstack1:get_count()
|
|
if p1 == p2 then
|
|
p1 = itemstack1:get_wear()
|
|
p2 = itemstack2:get_wear()
|
|
end
|
|
else
|
|
local nst = {}
|
|
nst[1] = name1
|
|
nst[2] = name2
|
|
table.sort(nst)
|
|
if nst[1] == name1 and nst[2] == name2 then
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
return p1 < p2
|
|
end)
|
|
end
|
|
return storage_table
|
|
end
|
|
|
|
-- storage_interface functions
|
|
|
|
local function storage_table_to_formspec(storage_table, xpos, ypos, l, h, page)
|
|
local d_table = {}
|
|
local formspec = ""
|
|
local lc = 0
|
|
local hc = 1
|
|
for i = 1, l * h, 1 do
|
|
d_table[i] = storage_table[i + (page-1) * l * h]
|
|
end
|
|
for _, entry in ipairs(d_table) do
|
|
lc = lc + 1
|
|
if lc > l then
|
|
lc = 1
|
|
hc = hc + 1
|
|
if hc > h then
|
|
break
|
|
end
|
|
end
|
|
local string_pos = pos_to_string(entry.pos)
|
|
formspec = formspec .. "list[nodemeta:".. string_pos ..";"..
|
|
entry["listname"] ..";"..
|
|
xpos + lc - 1 ..",".. hc + ypos - 1 ..";"..
|
|
"1,1;".. entry.index -1 .."]" ..
|
|
"listring[nodemeta:" .. string_pos .. ";".. entry["listname"] .."]" ..
|
|
"listring[current_player;main]"..
|
|
"listring[current_player;nothing]"
|
|
end
|
|
return formspec
|
|
end
|
|
|
|
local function set_fake_inv(oikt, xpos, ypos, l, h, page, pos, sorting_mode, ignore_wam)
|
|
local storage_table = {}
|
|
for i, en in pairs(oikt) do
|
|
en[1].count = en.count
|
|
table.insert(storage_table, en[1])
|
|
end
|
|
storage_table = sort_storage_table(storage_table, sorting_mode, ignore_wam)
|
|
local d_table = {}
|
|
for i = 1, l * h, 1 do
|
|
d_table[i] = storage_table[i + (page-1) * l * h]
|
|
end
|
|
local meta = minetest.get_meta(pos)
|
|
local inv = meta:get_inventory()
|
|
local formspec = ""
|
|
local lc = 0
|
|
local hc = 1
|
|
for i, entry in ipairs(d_table) do
|
|
inv:set_stack("fake_inv", i, entry.itemstack)
|
|
local count = entry.count
|
|
local itemstack = inv:get_stack("fake_inv", i)
|
|
local max_scount = itemstack:get_stack_max()
|
|
if ignore_wam == "true" then
|
|
itemstack:get_meta():from_table(nil)
|
|
itemstack:set_wear(0)
|
|
end
|
|
if count > max_scount then
|
|
itemstack:set_count(max_scount)
|
|
else
|
|
itemstack:set_count(count)
|
|
end
|
|
inv:set_stack("fake_inv", i, itemstack)
|
|
lc = lc + 1
|
|
if lc > l then
|
|
lc = 1
|
|
hc = hc + 1
|
|
if hc > h then
|
|
break
|
|
end
|
|
end
|
|
local string_pos = pos_to_string(pos)
|
|
formspec = formspec ..
|
|
"label[".. xpos + lc - 0.9 ..",".. (hc + ypos - 0.4) * 1.4 ..";".. entry.count .."]" ..
|
|
"list[nodemeta:".. string_pos ..";"..
|
|
"fake_inv;".. xpos + lc - 1 ..",".. (hc + ypos - 1) * 1.4 ..";"..
|
|
"1,1;".. lc - 1 + (hc - 1) * l .."]" ..
|
|
"listring[nodemeta:" .. string_pos .. ";fake_inv]" ..
|
|
"listring[current_player;main]"..
|
|
"listring[current_player;nothing]"
|
|
end
|
|
return formspec
|
|
end
|
|
|
|
local function get_buttons(oikt, xpos, ypos, l, h, page, pos, sorting_mode, ignore_wam)
|
|
local ignore_wam = true
|
|
local storage_table = {}
|
|
for i, en in pairs(oikt) do
|
|
en[1].count = en.count
|
|
table.insert(storage_table, en[1])
|
|
end
|
|
storage_table = sort_storage_table(storage_table, sorting_mode, ignore_wam)
|
|
local d_table = {}
|
|
for i = 1, l * h, 1 do
|
|
d_table[i] = storage_table[i + (page-1) * l * h]
|
|
end
|
|
local formspec = ""
|
|
local lc = 0
|
|
local hc = 1
|
|
for i, entry in ipairs(d_table) do
|
|
lc = lc + 1
|
|
if lc > l then
|
|
lc = 1
|
|
hc = hc + 1
|
|
if hc > h then
|
|
break
|
|
end
|
|
end
|
|
local itemstack_name = entry.itemstack:get_name()
|
|
local string_pos = pos_to_string(pos)
|
|
formspec = formspec ..
|
|
"label[".. xpos + lc - 0.9 ..",".. (hc + ypos - 0.4) * 1.4 ..";".. entry.count .."]" ..
|
|
"item_image_button[".. xpos + lc - 1 ..",".. (hc + ypos - 1) * 1.4 ..
|
|
";1,1;".. itemstack_name ..";".. "storage_button_" .. itemstack_name ..";]"
|
|
end
|
|
return formspec
|
|
end
|
|
|
|
local function update_formspec(player, pos)
|
|
local meta = minetest.get_meta(pos)
|
|
local storage_table = get_storage_table(pos, player)
|
|
local page = meta:get_int("page") or 1
|
|
local max_page = 1
|
|
local mode = meta:get_string("mode") or "actual_inv"
|
|
|
|
local capacity = #storage_table
|
|
local empty_slots = 0
|
|
for i = 1, #storage_table, 1 do
|
|
local stitemstack = storage_table[i - empty_slots].itemstack
|
|
if stitemstack:is_empty() or stitemstack:get_name() == "" then
|
|
table.remove(storage_table, i - empty_slots)
|
|
empty_slots = empty_slots + 1
|
|
end
|
|
end
|
|
|
|
local sorting_mode = meta:get_string("sorting_mode") or "name"
|
|
local sorting_modedis = ""
|
|
if sorting_mode == "name" then
|
|
sorting_modedis = "Name"
|
|
elseif sorting_mode == "count" then
|
|
sorting_modedis = "Count"
|
|
end
|
|
|
|
local ignore_wam = meta:get_string("ignore_wam") or "true"
|
|
if mode == "buttons" then
|
|
ignore_wam = "true"
|
|
end
|
|
local ignore_wamdis = ""
|
|
if ignore_wam == "true" then
|
|
ignore_wamdis = "True"
|
|
elseif ignore_wam == "false" then
|
|
ignore_wamdis = "False"
|
|
end
|
|
|
|
local search_field = meta:get_string("search_field") or ""
|
|
do
|
|
local kept_table = {}
|
|
for si, se in ipairs(storage_table) do
|
|
kept_table[si] = match_filter(se.itemstack:get_name(), search_field)
|
|
end
|
|
local rc = 0
|
|
for i = 1, #storage_table, 1 do
|
|
if kept_table[i] ~= true then
|
|
table.remove(storage_table, i - rc)
|
|
rc = rc + 1
|
|
end
|
|
end
|
|
end
|
|
|
|
storage_table = sort_storage_table(storage_table, sorting_mode, ignore_wam)
|
|
|
|
local shown = meta:get_string("shown") or "everything"
|
|
local showndis = shown
|
|
if shown == "everything" then
|
|
showndis = "Everything"
|
|
elseif shown == "nodes" then
|
|
showndis = "Nodes"
|
|
local rc = 0
|
|
for i = 1, #storage_table, 1 do
|
|
if not minetest.registered_nodes[storage_table[i - rc].itemstack:get_name()] then
|
|
table.remove(storage_table, i - rc)
|
|
rc = rc + 1
|
|
end
|
|
end
|
|
elseif shown == "craftitems" then
|
|
showndis = "Craftitems"
|
|
local rc = 0
|
|
for i = 1, #storage_table, 1 do
|
|
if not minetest.registered_craftitems[storage_table[i - rc].itemstack:get_name()] then
|
|
table.remove(storage_table, i - rc)
|
|
rc = rc + 1
|
|
end
|
|
end
|
|
elseif shown == "tools" then
|
|
showndis = "Tools"
|
|
local rc = 0
|
|
for i = 1, #storage_table, 1 do
|
|
if not minetest.registered_tools[storage_table[i - rc].itemstack:get_name()] then
|
|
table.remove(storage_table, i - rc)
|
|
rc = rc + 1
|
|
end
|
|
end
|
|
end
|
|
|
|
local modedis = mode
|
|
local st_form = ""
|
|
if mode == "actual_inv" then
|
|
modedis = "Actual Inventory"
|
|
max_page = math.ceil(#storage_table/(15*7))
|
|
if max_page < 1 then
|
|
max_page = 1
|
|
end
|
|
if page > max_page then
|
|
page = max_page
|
|
meta:set_int("page", page)
|
|
end
|
|
if page < 1 then
|
|
page = 1
|
|
meta:set_int("page", page)
|
|
end
|
|
st_form = storage_table_to_formspec(storage_table, 0, 0, 15, 7, page)
|
|
elseif mode == "fake_inv" then
|
|
modedis = "Fake Inventory"
|
|
local oikt = get_one_item_kind_table(storage_table, ignore_wam)
|
|
local oiktl = 0
|
|
for _, _ in pairs(oikt) do
|
|
oiktl = oiktl + 1
|
|
end
|
|
max_page = math.ceil(oiktl/(15*5))
|
|
if max_page < 1 then
|
|
max_page = 1
|
|
end
|
|
if page > max_page then
|
|
page = max_page
|
|
meta:set_int("page", page)
|
|
end
|
|
if page < 1 then
|
|
page = 1
|
|
meta:set_int("page", page)
|
|
end
|
|
st_form = set_fake_inv(oikt, 0, 0, 15, 5, page, pos, sorting_mode, ignore_wam)
|
|
elseif mode == "buttons" then
|
|
modedis = "Buttons"
|
|
local oikt = get_one_item_kind_table(storage_table, ignore_wam)
|
|
local oiktl = 0
|
|
for _, _ in pairs(oikt) do
|
|
oiktl = oiktl + 1
|
|
end
|
|
max_page = math.ceil(oiktl/(15*5))
|
|
if max_page < 1 then
|
|
max_page = 1
|
|
end
|
|
if page > max_page then
|
|
page = max_page
|
|
meta:set_int("page", page)
|
|
end
|
|
if page < 1 then
|
|
page = 1
|
|
meta:set_int("page", page)
|
|
end
|
|
st_form = get_buttons(oikt, 0, 0, 15, 5, page, pos, sorting_mode, ignore_wam)
|
|
end
|
|
|
|
local rb_mode = meta:get_string("rb_mode") or "settings"
|
|
local rb_formspec = ""
|
|
if rb_mode == "crafting" then
|
|
rb_formspec = "label[13,7.2;Crafting]" ..
|
|
"list[current_player;craft;12,9.2;3,3;]" ..
|
|
"list[current_player;craftpreview;13,8;1,1;]" ..
|
|
"listring[current_player;craft]" ..
|
|
"listring[current_player;main]"
|
|
elseif rb_mode == "settings" then
|
|
local dbuttons = "label[11.6,10.3;Ignore meta and wear: ".. ignore_wamdis .."]" ..
|
|
"button[14,10.1;1,1;change_ignore_wam;Change]"
|
|
if mode == "buttons" then
|
|
local items_on_click = meta:get_string("items_on_click") or "one_stack"
|
|
local items_on_clickdis = items_on_click
|
|
if items_on_click == "one_stack" then
|
|
items_on_clickdis = "One stack"
|
|
elseif items_on_click == "all" then
|
|
items_on_clickdis = "All"
|
|
elseif items_on_click == "one_item" then
|
|
items_on_clickdis = "One item"
|
|
end
|
|
dbuttons = "label[11.6,10.3;Items on click: ".. items_on_clickdis .."]" ..
|
|
"button[14,10.1;1,1;change_items_on_click;Change]"
|
|
end
|
|
rb_formspec = "label[13,7.2;Settings]" ..
|
|
"label[11.6,8.2;Mode: ".. modedis .."]" ..
|
|
"button[14,8;1,1;change_mode;Change]" ..
|
|
"label[11.6,8.9;Shown: ".. showndis .."]" ..
|
|
"button[14,8.7;1,1;change_shown;Change]" ..
|
|
"label[11.6,9.6;Sorting Mode: ".. sorting_modedis .."]" ..
|
|
"button[14,9.4;1,1;change_sorting_mode;Change]" ..
|
|
dbuttons ..
|
|
"field[11.9,11.4;2,1;infotext;Infotext;".. meta:get_string("infotext") .."]" ..
|
|
"button[14,11.1;1,1;set_infotext;Set]" ..
|
|
"field_close_on_enter[infotext;false]"
|
|
end
|
|
|
|
local spos = pos_to_string(pos)
|
|
local formspec = "size[15,12]" ..
|
|
default.gui_bg ..
|
|
default.gui_bg_img ..
|
|
default.gui_slots ..
|
|
"list[nodemeta:" .. spos .. ";input;0,10.2;3,2;]" ..
|
|
"label[0,9.7;Input:]" ..
|
|
"listring[current_player;main]" ..
|
|
"listring[nodemeta:" .. spos .. ";input]" ..
|
|
"listring[current_player;nothing]" ..
|
|
st_form ..
|
|
|
|
"label[0,7.2;Page: ".. page .." of ".. max_page .."]" ..
|
|
"label[0,7.9;Capacity: ".. capacity - empty_slots .." of ".. capacity .."]" ..
|
|
"button[3.1,7;0.9,1;first;|<--]"..
|
|
"button[3.8,7;0.9,1;threeback;<<--]"..
|
|
"button[4.5,7;0.9,1;back;<--]"..
|
|
"button[5.2,7;0.9,1;next;-->]"..
|
|
"button[5.9,7;0.9,1;threenext;-->>]"..
|
|
"button[6.6,7;0.9,1;last;-->|]"..
|
|
|
|
"button[10.5,7;1,1;search;Search]"..
|
|
"button[11.4,7;1,1;reset;Reset]"..
|
|
"field[7.8,7.3;3,1;search_field;;".. search_field .."]" ..
|
|
"field_close_on_enter[search_field;false]"..
|
|
|
|
"button[0.5,8.6;2,1;sort_storage;Sort storage]"..
|
|
|
|
"list[current_player;main;3.5,8;8,1;]" ..
|
|
"list[current_player;main;3.5,9.2;8,3;8]" ..
|
|
|
|
"button[14,7;1,1;change_rb_mode;Change]"..
|
|
rb_formspec ..
|
|
default.get_hotbar_bg(3.5,8)
|
|
|
|
minetest.show_formspec(player, "storage_interface:storage_interface", formspec)
|
|
end
|
|
|
|
local function sort_storage(pos, player)
|
|
local meta = minetest.get_meta(pos)
|
|
local storage_table = get_storage_table(pos, player)
|
|
local sorted_storage_table = {}
|
|
for _, ste in ipairs(storage_table) do
|
|
local itemstack = ste.itemstack
|
|
local item_name = itemstack:get_name()
|
|
for _, sste in ipairs(sorted_storage_table) do
|
|
local new_itemstack = sste.itemstack
|
|
if new_itemstack:get_name() == item_name then
|
|
itemstack = new_itemstack:add_item(itemstack)
|
|
end
|
|
if itemstack:is_empty() then
|
|
break
|
|
end
|
|
end
|
|
if not itemstack:is_empty() then
|
|
table.insert(sorted_storage_table, ste)
|
|
end
|
|
end
|
|
sorted_storage_table = sort_storage_table(sorted_storage_table, meta:get_string("sorting_mode"), "false")
|
|
for i, e in ipairs(sorted_storage_table) do
|
|
for id, ed in ipairs(storage_table) do
|
|
if match_filter(e.itemstack:get_name(), ed.filter) and not storage_table[id].used then
|
|
sorted_storage_table[i].can_store = true
|
|
storage_table[id].used = true
|
|
break
|
|
end
|
|
end
|
|
if not sorted_storage_table[i].can_store then
|
|
minetest.chat_send_player(player, "Your storage is to small to sort it.")
|
|
return
|
|
end
|
|
end
|
|
for _, entry in ipairs(storage_table) do
|
|
local inv = minetest.get_meta(entry.pos):get_inventory()
|
|
inv:set_stack(entry.listname, entry.index, "")
|
|
end
|
|
for _, entry in ipairs(sorted_storage_table) do
|
|
storage_add_item(pos, entry.itemstack, player)
|
|
end
|
|
end
|
|
|
|
local formspec_pos_si = {}
|
|
|
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|
if formname ~= "storage_interface:storage_interface" then
|
|
return
|
|
end
|
|
local name = player:get_player_name()
|
|
local pos = formspec_pos_si[name]
|
|
if not pos then
|
|
return
|
|
end
|
|
local meta = minetest.get_meta(pos)
|
|
local page = meta:get_int("page")
|
|
if fields.first then
|
|
meta:set_int("page", 1)
|
|
elseif fields.last then
|
|
meta:set_int("page", 1000)
|
|
elseif fields.threenext then
|
|
meta:set_int("page", page + 3)
|
|
elseif fields.threeback then
|
|
meta:set_int("page", page - 3)
|
|
elseif fields.next then
|
|
meta:set_int("page", page + 1)
|
|
elseif fields.back then
|
|
meta:set_int("page", page - 1)
|
|
elseif fields.change_mode then
|
|
local mode = meta:get_string("mode")
|
|
if mode == "actual_inv" then
|
|
meta:set_string("mode", "fake_inv")
|
|
elseif mode == "fake_inv" then
|
|
meta:set_string("mode", "buttons")
|
|
elseif mode == "buttons" then
|
|
meta:set_string("mode", "actual_inv")
|
|
end
|
|
elseif fields.change_shown then
|
|
local shown = meta:get_string("shown")
|
|
if shown == "everything" then
|
|
meta:set_string("shown", "nodes")
|
|
elseif shown == "nodes" then
|
|
meta:set_string("shown", "craftitems")
|
|
elseif shown == "craftitems" then
|
|
meta:set_string("shown", "tools")
|
|
elseif shown == "tools" then
|
|
meta:set_string("shown", "everything")
|
|
end
|
|
elseif fields.change_rb_mode then
|
|
local rb_mode = meta:get_string("rb_mode")
|
|
if rb_mode == "crafting" then
|
|
meta:set_string("rb_mode", "settings")
|
|
elseif rb_mode == "settings" then
|
|
meta:set_string("rb_mode", "crafting")
|
|
end
|
|
elseif fields.change_sorting_mode then
|
|
local sorting_mode = meta:get_string("sorting_mode")
|
|
if sorting_mode == "name" then
|
|
meta:set_string("sorting_mode", "count")
|
|
elseif sorting_mode == "count" then
|
|
meta:set_string("sorting_mode", "name")
|
|
end
|
|
elseif fields.change_ignore_wam then
|
|
local ignore_wam = meta:get_string("ignore_wam")
|
|
if ignore_wam == "true" then
|
|
meta:set_string("ignore_wam", "false")
|
|
elseif ignore_wam == "false" then
|
|
meta:set_string("ignore_wam", "true")
|
|
end
|
|
elseif fields.change_items_on_click then
|
|
local items_on_click = meta:get_string("items_on_click")
|
|
if items_on_click == "one_stack" then
|
|
meta:set_string("items_on_click", "one_item")
|
|
elseif items_on_click == "one_item" then
|
|
meta:set_string("items_on_click", "all")
|
|
elseif items_on_click == "all" then
|
|
meta:set_string("items_on_click", "one_stack")
|
|
end
|
|
elseif fields.set_infotext or fields.key_enter_field == "infotext" then
|
|
meta:set_string("infotext", fields.infotext)
|
|
elseif fields.search or fields.key_enter_field == "search_field" then
|
|
meta:set_string("search_field", fields.search_field)
|
|
elseif fields.reset then
|
|
meta:set_string("search_field", "")
|
|
elseif fields.sort_storage then
|
|
sort_storage(pos, name)
|
|
elseif meta:get_string("mode") == "buttons" then
|
|
for fieldname, b in pairs(fields) do
|
|
if b and string.sub(fieldname, 1, 15) == "storage_button_" then
|
|
local playerinv = player:get_inventory()
|
|
local bitemstack = ItemStack(string.sub(fieldname, 16))
|
|
local items_on_click = meta:get_string("items_on_click") or "one_stack"
|
|
if items_on_click == "one_stack" then
|
|
bitemstack:set_count(bitemstack:get_stack_max())
|
|
if playerinv:room_for_item("main", bitemstack) then
|
|
local re_stack = storage_remove_item(pos, bitemstack, false, name)
|
|
if re_stack then
|
|
playerinv:add_item("main", re_stack)
|
|
end
|
|
end
|
|
elseif items_on_click == "one_item" then
|
|
bitemstack:set_count(1)
|
|
if playerinv:room_for_item("main", bitemstack) then
|
|
local re_stack = storage_remove_item(pos, bitemstack, false, name)
|
|
if re_stack then
|
|
playerinv:add_item("main", re_stack)
|
|
end
|
|
end
|
|
elseif items_on_click == "all" then
|
|
bitemstack:set_count(bitemstack:get_stack_max())
|
|
for i = 1, 4*8 do
|
|
local new_bitemstack = ItemStack(bitemstack:to_string())
|
|
if playerinv:room_for_item("main", bitemstack) then
|
|
local re_stack = storage_remove_item(pos, bitemstack, false, name)
|
|
if re_stack then
|
|
playerinv:add_item("main", re_stack)
|
|
else
|
|
break
|
|
end
|
|
else
|
|
break
|
|
end
|
|
end
|
|
end
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
if fields.quit then
|
|
return true
|
|
else
|
|
update_formspec(name, pos)
|
|
end
|
|
end)
|
|
|
|
local si_node_def = {
|
|
description = "Storage Interface",
|
|
tiles = {"default_chest_top.png", "default_chest_top.png",
|
|
"default_chest_top.png","default_chest_top.png",
|
|
"default_chest_top.png", "default_chest_top.png^storage_interface_front.png"},
|
|
paramtype2 = "facedir",
|
|
groups = {choppy = 2, oddly_breakable_by_hand = 2},
|
|
legacy_facedir_simple = true,
|
|
is_ground_content = false,
|
|
sounds = default.node_sound_wood_defaults(),
|
|
|
|
on_construct = function(pos)
|
|
local meta = minetest.get_meta(pos)
|
|
meta:set_int("page", 1)
|
|
meta:set_string("mode", "actual_inv")
|
|
meta:set_string("shown", "everything")
|
|
meta:set_string("rb_mode", "settings")
|
|
meta:set_string("sorting_mode", "name")
|
|
meta:set_string("search_field", "")
|
|
meta:set_string("ignore_wam", "false")
|
|
meta:set_string("infotext", "Storage Interface")
|
|
meta:set_string("items_on_click", "one_stack")
|
|
local inv = meta:get_inventory()
|
|
inv:set_size("input", 3*2)
|
|
inv:set_size("fake_inv", 15*7)
|
|
end,
|
|
|
|
can_dig = function(pos,player)
|
|
local meta = minetest.get_meta(pos);
|
|
local inv = meta:get_inventory()
|
|
return inv:is_empty("input")
|
|
end,
|
|
|
|
allow_metadata_inventory_move = function(pos, from_list, from_index,
|
|
to_list, to_index, count, player)
|
|
return 0
|
|
end,
|
|
|
|
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
|
|
if listname == "fake_inv" then
|
|
|
|
-- trigger only one time
|
|
local oldc_taken = player:get_attribute("storage_interface_taken")
|
|
if oldc_taken then
|
|
return oldc_taken
|
|
end
|
|
|
|
local meta = minetest.get_meta(pos)
|
|
local inv = meta:get_inventory()
|
|
local match_meta_and_wear = true
|
|
if meta:get_string("ignore_wam") == "true" then
|
|
match_meta_and_wear = false
|
|
end
|
|
local taken_stack = storage_remove_item(pos, stack, match_meta_and_wear, player:get_player_name())
|
|
if not taken_stack then
|
|
return 0
|
|
end
|
|
|
|
local count = taken_stack:get_count()
|
|
inv:set_stack("fake_inv", index, taken_stack)
|
|
player:set_attribute("storage_interface_taken", count)
|
|
return count
|
|
elseif listname == "input" then
|
|
return stack:get_count()
|
|
end
|
|
return 0
|
|
end,
|
|
|
|
on_metadata_inventory_take = function(pos, listname, index, stack, player)
|
|
if listname == "fake_inv" then
|
|
player:set_attribute("storage_interface_taken", nil)
|
|
|
|
-- Save items if a right-click swap has happened
|
|
local meta = minetest.get_meta(pos)
|
|
local inv = meta:get_inventory()
|
|
local new_stack = inv:get_stack(listname, index)
|
|
if not new_stack:item_fits(stack) then
|
|
local inv = player:get_inventory()
|
|
local overflow = inv:add_item("main", new_stack)
|
|
if overflow and not overflow:is_empty() then
|
|
minetest.item_drop(overflow, player, player:getpos())
|
|
end
|
|
end
|
|
|
|
end
|
|
update_formspec(player:get_player_name(), pos)
|
|
end,
|
|
|
|
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
|
|
if listname == "input" then
|
|
if storage_add_item(pos, stack, player:get_player_name()):is_empty() then
|
|
update_formspec(player:get_player_name(), pos)
|
|
return(-1)
|
|
end
|
|
end
|
|
return 0
|
|
end,
|
|
|
|
on_rightclick = function(pos, node, clicker)
|
|
local name = clicker:get_player_name()
|
|
formspec_pos_si[name] = pos
|
|
update_formspec(name, pos)
|
|
end,
|
|
|
|
on_blast = function(pos)
|
|
local drops = {}
|
|
default.get_inventory_drops(pos, "input", drops)
|
|
drops[#drops+1] = "storage_interface:storage_interface"
|
|
minetest.remove_node(pos)
|
|
return drops
|
|
end
|
|
}
|
|
|
|
if minetest.get_modpath("pipeworks") then
|
|
local tube_entry = "^pipeworks_tube_connection_wooden.png"
|
|
si_node_def.tiles[1] = si_node_def.tiles[1] .. tube_entry
|
|
si_node_def.tiles[2] = si_node_def.tiles[2] .. tube_entry
|
|
si_node_def.tiles[3] = si_node_def.tiles[3] .. tube_entry
|
|
si_node_def.tiles[4] = si_node_def.tiles[4] .. tube_entry
|
|
si_node_def.tiles[5] = si_node_def.tiles[5] .. tube_entry .. "^[transformFX"
|
|
si_node_def.groups.tubedevice = 1
|
|
si_node_def.groups.tubedevice_receiver = 1
|
|
si_node_def.after_place_node = pipeworks.after_place
|
|
si_node_def.after_dig_node = pipeworks.after_dig
|
|
si_node_def.tube = {
|
|
insert_object = function(pos, node, stack, direction)
|
|
return storage_add_item(pos, stack, ".ignore_player")
|
|
end,
|
|
can_insert = function(pos, node, stack, direction)
|
|
return storage_room_for_item(pos, stack, ".ignore_player")
|
|
end,
|
|
input_inventory = "input",
|
|
connect_sides = {left = 1, right = 1, back = 1, bottom = 1, top = 1},
|
|
}
|
|
end
|
|
|
|
-- sfit functions
|
|
|
|
local formspec_pos_sfit = {}
|
|
local sfit_local_filter_string = {}
|
|
|
|
local function use_sfit(player, pos)
|
|
local player_name = player:get_player_name()
|
|
local meta = minetest.get_meta(pos)
|
|
local old_filter_string = sfit_local_filter_string[player_name] or
|
|
meta:get_string("storage_interface_filter_string") or ""
|
|
sfit_local_filter_string[player_name] = old_filter_string
|
|
local old_priority = meta:get_int("storage_interface_priority") or 0
|
|
formspec_pos_sfit[player_name] = pos
|
|
minetest.create_detached_inventory("storage_interface:sfit", {
|
|
allow_put = function(inv, listname, index, stack, player)
|
|
local player_name = player:get_player_name()
|
|
local filter_string = sfit_local_filter_string[player_name]
|
|
local stack_name = stack:get_name()
|
|
if (not filter_string) or filter_string == "" then
|
|
filter_string = '"'.. stack_name ..'"'
|
|
else
|
|
local filter_string_table = string.split(filter_string, ",", false, -1)
|
|
for _, filter_stringi in ipairs(filter_string_table) do
|
|
if string.sub(filter_stringi, 2, string.len(filter_stringi)-1) == stack_name then
|
|
use_sfit(player, formspec_pos_sfit[player_name])
|
|
return 0
|
|
end
|
|
end
|
|
filter_string = filter_string ..',"'.. stack_name ..'"'
|
|
end
|
|
sfit_local_filter_string[player_name] = filter_string
|
|
use_sfit(player, formspec_pos_sfit[player_name])
|
|
return 0
|
|
end
|
|
}, player_name)
|
|
local inv = minetest.get_inventory({type="detached", name="storage_interface:sfit"})
|
|
inv:set_size("item_adder", 1)
|
|
local formspec =
|
|
"size[8,6]" ..
|
|
default.gui_bg ..
|
|
default.gui_bg_img ..
|
|
default.gui_slots ..
|
|
"list[detached:storage_interface:sfit;item_adder;2,0.5;1,1]" ..
|
|
"label[2,0.1;Scan item]" ..
|
|
"list[current_player;main;0,1.85;8,1;]" ..
|
|
"list[current_player;main;0,3.08;8,3;8]" ..
|
|
"listring[detached:storage_interface:sfit;item_adder]" ..
|
|
"listring[current_player;main]" ..
|
|
"field[3.3,0.8;3,1;sorting_filter_string;Sorting Filter String;".. old_filter_string .."]" ..
|
|
"field[6.3,0.8;1,1;priority;Priority;".. old_priority .."]" ..
|
|
"field_close_on_enter[sorting_filter_string;false]"..
|
|
"field_close_on_enter[priority;false]"..
|
|
"button[7,0.5;1,1;set_filter_string;Save]"..
|
|
"button[0,0.5;2,1;scan_inventory;Scan node inventory]"..
|
|
default.get_hotbar_bg(0,1.85)
|
|
minetest.show_formspec(player_name, "storage_interface:sfit", formspec)
|
|
end
|
|
|
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|
if formname ~= "storage_interface:sfit" then
|
|
return
|
|
end
|
|
local player_name = player:get_player_name()
|
|
local pos = formspec_pos_sfit[player_name]
|
|
sfit_local_filter_string[player_name] = fields.sorting_filter_string
|
|
if not pos then
|
|
return
|
|
end
|
|
local meta = minetest.get_meta(pos)
|
|
if fields.set_filter_string or
|
|
fields.key_enter_field == "sorting_filter_string" or
|
|
fields.key_enter_field == "priority" then
|
|
meta:set_string("storage_interface_filter_string", sfit_local_filter_string[player_name])
|
|
local priority = tonumber(fields.priority) or 0
|
|
meta:set_int("storage_interface_priority", priority)
|
|
minetest.chat_send_player(player_name, "Filter inscribed.")
|
|
sfit_local_filter_string[player_name] = nil
|
|
elseif fields.scan_inventory then
|
|
local inv_list = meta:get_inventory():get_lists()
|
|
local filter_string = sfit_local_filter_string[player_name]
|
|
for _, ilist in pairs(inv_list) do
|
|
for _, stack in ipairs(ilist) do
|
|
local stack_name = stack:get_name() or ""
|
|
if stack_name == "" then
|
|
elseif (not filter_string) or filter_string == "" then
|
|
filter_string = '"'.. stack_name ..'"'
|
|
else
|
|
local filter_string_table = string.split(filter_string, ",", false, -1)
|
|
local contains_name = false
|
|
for _, filter_stringi in ipairs(filter_string_table) do
|
|
if string.sub(filter_stringi, 2, string.len(filter_stringi)-1) == stack_name then
|
|
contains_name = true
|
|
end
|
|
end
|
|
if not contains_name then
|
|
filter_string = filter_string ..',"'.. stack_name ..'"'
|
|
end
|
|
end
|
|
end
|
|
end
|
|
sfit_local_filter_string[player_name] = filter_string
|
|
end
|
|
if fields.quit then
|
|
return true
|
|
else
|
|
use_sfit(player, pos)
|
|
end
|
|
end)
|
|
|
|
-- item registration
|
|
|
|
minetest.register_node("storage_interface:storage_interface", si_node_def)
|
|
|
|
local scnb_size = 3/16
|
|
local sc_connects_to = table.copy(storage_interface.storage_nodes)
|
|
for _, i in ipairs(storage_interface.connection_nodes) do
|
|
table.insert(sc_connects_to, i)
|
|
end
|
|
minetest.register_node("storage_interface:storage_connector", {
|
|
description = "Storage Connection Cable",
|
|
tiles = {"storage_interface_connector.png"},
|
|
inventory_image = "storage_interface_connector_inv.png",
|
|
wield_image = "storage_interface_connector_inv.png",
|
|
groups = {choppy = 2, oddly_breakable_by_hand = 2, wood = 1, storage_interface_connect = 1},
|
|
is_ground_content = false,
|
|
sunlight_propagates = true,
|
|
paramtype = "light",
|
|
sounds = default.node_sound_wood_defaults(),
|
|
drawtype = "nodebox",
|
|
node_box = {
|
|
type = "connected",
|
|
fixed = {-scnb_size, -scnb_size, -scnb_size, scnb_size, scnb_size, scnb_size},
|
|
connect_top = {-scnb_size, -scnb_size, -scnb_size, scnb_size, 0.5, scnb_size}, -- y+
|
|
connect_bottom = {-scnb_size, -0.5, -scnb_size, scnb_size, scnb_size, scnb_size}, -- y-
|
|
connect_front = {-scnb_size, -scnb_size, -0.5, scnb_size, scnb_size, scnb_size}, -- z-
|
|
connect_back = {-scnb_size, -scnb_size, scnb_size, scnb_size, scnb_size, 0.5 }, -- z+
|
|
connect_left = {-0.5, -scnb_size, -scnb_size, scnb_size, scnb_size, scnb_size}, -- x-
|
|
connect_right = {-scnb_size, -scnb_size, -scnb_size, 0.5, scnb_size, scnb_size}, -- x+
|
|
},
|
|
connects_to = sc_connects_to,
|
|
})
|
|
|
|
minetest.register_node("storage_interface:storage_connector_embedded", {
|
|
description = "Embedded Storage Connection Cable",
|
|
tiles = {"default_chest_top.png^storage_interface_connector_middle.png"},
|
|
groups = {choppy = 2, oddly_breakable_by_hand = 2, wood = 1},
|
|
is_ground_content = false,
|
|
sounds = default.node_sound_wood_defaults(),
|
|
})
|
|
|
|
minetest.register_craftitem("storage_interface:sfit", {
|
|
description = "Sorting Filter Inscribing Tool",
|
|
inventory_image = "storage_interface_sfit.png",
|
|
stack_max = 1,
|
|
on_use = function(itemstack, user, pointed_thing)
|
|
if not (pointed_thing and pointed_thing.type == "node" and user) then
|
|
return
|
|
end
|
|
local pos = pointed_thing.under
|
|
local player_name = user:get_player_name()
|
|
local node = minetest.get_node(pos).name
|
|
local meta = minetest.get_meta(pos)
|
|
local owner = meta:get_string("owner") or ""
|
|
if (owner ~= "" and owner ~= player_name) or minetest.is_protected(pos, player_name) then
|
|
minetest.chat_send_player(player_name, "You do not own this node.")
|
|
return
|
|
end
|
|
if table_contains(storage_interface.storage_nodes, node) then
|
|
sfit_local_filter_string[player_name] = nil
|
|
use_sfit(user, pos)
|
|
else
|
|
minetest.chat_send_player(player_name, "You can't inscribe this node.")
|
|
end
|
|
return
|
|
end,
|
|
})
|
|
|
|
-- craft registration
|
|
|
|
minetest.register_craft({
|
|
output = 'storage_interface:storage_interface',
|
|
recipe = {
|
|
{'default:steel_ingot', 'default:glass', 'default:steel_ingot'},
|
|
{'group:wood', 'default:mese', 'group:wood'},
|
|
{'group:wood', 'default:chest', 'group:wood'},
|
|
}
|
|
})
|
|
|
|
minetest.register_craft({
|
|
output = 'storage_interface:storage_connector 18',
|
|
recipe = {
|
|
{'group:stick', '', 'group:stick'},
|
|
{'default:chest', 'group:wood', 'default:chest'},
|
|
{'group:stick', '', 'group:stick'},
|
|
}
|
|
})
|
|
|
|
minetest.register_craft({
|
|
output = 'storage_interface:storage_connector_embedded 9',
|
|
recipe = {
|
|
{'group:wood', 'group:wood', 'group:wood'},
|
|
{'group:wood', 'storage_interface:storage_connector', 'group:wood'},
|
|
{'group:wood', 'group:wood', 'group:wood'},
|
|
}
|
|
})
|
|
|
|
minetest.register_craft({
|
|
output = 'storage_interface:sfit',
|
|
recipe = {
|
|
{'', 'default:mese_crystal_fragment', 'group:dye'},
|
|
{'default:steel_ingot', 'default:chest', 'default:mese_crystal_fragment'},
|
|
{'group:stick', 'default:steel_ingot', ''},
|
|
}
|
|
})
|