42
.luacheckrc
@ -10,29 +10,27 @@ globals = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
read_globals = {
|
read_globals = {
|
||||||
|
-- Lua
|
||||||
string = {fields = {"split", "trim"}},
|
string = {fields = {"split", "trim"}},
|
||||||
table = {fields = {"copy", "getn"}},
|
table = {fields = {"copy", "getn"}},
|
||||||
|
|
||||||
"intllib", "VoxelArea",
|
-- Minetest
|
||||||
"default", "stairsplus",
|
|
||||||
|
|
||||||
"PseudoRandom", "ItemStack",
|
"PseudoRandom", "ItemStack",
|
||||||
"mg", "tubelib", "vector",
|
"VoxelArea", "VoxelManip",
|
||||||
|
"Settings", "vector",
|
||||||
"moretrees", "bucket",
|
|
||||||
"unified_inventory", "digilines",
|
-- Mods
|
||||||
|
"default", "stairsplus",
|
||||||
"pipeworks", "screwdriver",
|
"screwdriver", "bucket",
|
||||||
"VoxelManip", "unifieddyes",
|
"digilines", "pipeworks",
|
||||||
|
"mesecon", "moretrees",
|
||||||
"Settings", "mesecon",
|
"unified_inventory", "protector",
|
||||||
"digiline_remote",
|
"unifieddyes", "digiline_remote",
|
||||||
|
"monitoring", "drawers", "mg",
|
||||||
"protector", "isprotect",
|
|
||||||
"homedecor_expect_infinite_stacks",
|
-- Only used in technic/machines/MV/lighting.lua (disabled)
|
||||||
"monitoring", "drawers"
|
"isprotect", "homedecor_expect_infinite_stacks",
|
||||||
|
|
||||||
|
-- TODO: Remove after translation update
|
||||||
|
"intllib"
|
||||||
}
|
}
|
||||||
|
|
||||||
-- Remove after chests update
|
|
||||||
files["technic_chests/register.lua"].ignore = { "fs_helpers", "name", "locked_after_place" }
|
|
||||||
files["technic_chests/register.lua"].max_line_length = false
|
|
||||||
|
152
technic_chests/chests.lua
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
|
||||||
|
local function register_chests(name, data)
|
||||||
|
for _,t in pairs({"", "_locked", "_protected"}) do
|
||||||
|
local data_copy = {}
|
||||||
|
for k, v in pairs(data) do
|
||||||
|
data_copy[k] = v
|
||||||
|
end
|
||||||
|
data_copy.locked = t == "_locked"
|
||||||
|
data_copy.protected = t == "_protected"
|
||||||
|
technic.chests.register_chest(name, data_copy)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function register_crafts(name, material, base_open, base_locked, base_protected)
|
||||||
|
name = name:lower()
|
||||||
|
if minetest.registered_items[material] then
|
||||||
|
if minetest.registered_items[base_open] then
|
||||||
|
minetest.register_craft({
|
||||||
|
output = "technic:"..name.."_chest",
|
||||||
|
recipe = {
|
||||||
|
{material, material, material},
|
||||||
|
{material, base_open, material},
|
||||||
|
{material, material, material},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
if minetest.registered_items[base_locked] then
|
||||||
|
minetest.register_craft({
|
||||||
|
output = "technic:"..name.."_locked_chest",
|
||||||
|
recipe = {
|
||||||
|
{material, material, material},
|
||||||
|
{material, base_locked, material},
|
||||||
|
{material, material, material},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
if minetest.registered_items[base_protected] then
|
||||||
|
minetest.register_craft({
|
||||||
|
output = "technic:"..name.."_protected_chest",
|
||||||
|
recipe = {
|
||||||
|
{material, material, material},
|
||||||
|
{material, base_protected, material},
|
||||||
|
{material, material, material},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
minetest.register_craft({
|
||||||
|
output = "technic:"..name.."_locked_chest",
|
||||||
|
type = "shapeless",
|
||||||
|
recipe = {"basic_materials:padlock","technic:"..name.."_chest"}
|
||||||
|
})
|
||||||
|
minetest.register_craft({
|
||||||
|
output = "technic:"..name.."_protected_chest",
|
||||||
|
type = "shapeless",
|
||||||
|
recipe = {"default:copper_ingot", "technic:"..name.."_chest"}
|
||||||
|
})
|
||||||
|
minetest.register_craft({
|
||||||
|
output = "technic:"..name.."_chest",
|
||||||
|
type = "shapeless",
|
||||||
|
recipe = {"technic:"..name.."_locked_chest"}
|
||||||
|
})
|
||||||
|
minetest.register_craft({
|
||||||
|
output = "technic:"..name.."_chest",
|
||||||
|
type = "shapeless",
|
||||||
|
recipe = {"technic:"..name.."_protected_chest"}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Iron
|
||||||
|
register_chests("Iron", {
|
||||||
|
width = 9,
|
||||||
|
height = 5,
|
||||||
|
sort = true,
|
||||||
|
infotext = true,
|
||||||
|
})
|
||||||
|
register_crafts(
|
||||||
|
"Iron",
|
||||||
|
minetest.get_modpath("technic_worldgen") and "technic:cast_iron_ingot" or "default:steel_ingot",
|
||||||
|
"default:chest",
|
||||||
|
"default:chest_locked",
|
||||||
|
"protector:chest"
|
||||||
|
)
|
||||||
|
|
||||||
|
-- Copper
|
||||||
|
register_chests("Copper", {
|
||||||
|
width = 12,
|
||||||
|
height = 5,
|
||||||
|
sort = true,
|
||||||
|
infotext = true,
|
||||||
|
autosort = true,
|
||||||
|
})
|
||||||
|
register_crafts(
|
||||||
|
"Copper",
|
||||||
|
"default:copper_ingot",
|
||||||
|
"technic:iron_chest",
|
||||||
|
"technic:iron_locked_chest",
|
||||||
|
"technic:iron_protected_chest"
|
||||||
|
)
|
||||||
|
|
||||||
|
-- Silver
|
||||||
|
register_chests("Silver", {
|
||||||
|
width = 12,
|
||||||
|
height = 6,
|
||||||
|
sort = true,
|
||||||
|
infotext = true,
|
||||||
|
autosort = true,
|
||||||
|
quickmove = true,
|
||||||
|
})
|
||||||
|
register_crafts(
|
||||||
|
"Silver",
|
||||||
|
"moreores:silver_ingot",
|
||||||
|
"technic:copper_chest",
|
||||||
|
"technic:copper_locked_chest",
|
||||||
|
"technic:copper_protected_chest"
|
||||||
|
)
|
||||||
|
|
||||||
|
-- Gold
|
||||||
|
register_chests("Gold", {
|
||||||
|
width = 15,
|
||||||
|
height = 6,
|
||||||
|
sort = true,
|
||||||
|
infotext = true,
|
||||||
|
autosort = true,
|
||||||
|
quickmove = true,
|
||||||
|
color = true,
|
||||||
|
})
|
||||||
|
register_crafts(
|
||||||
|
"Gold",
|
||||||
|
"default:gold_ingot",
|
||||||
|
minetest.get_modpath("moreores") and "technic:silver_chest" or "technic:copper_chest",
|
||||||
|
minetest.get_modpath("moreores") and "technic:silver_locked_chest" or "technic:copper_locked_chest",
|
||||||
|
minetest.get_modpath("moreores") and "technic:silver_protected_chest" or "technic:copper_protected_chest"
|
||||||
|
)
|
||||||
|
|
||||||
|
-- Mithril
|
||||||
|
register_chests("Mithril", {
|
||||||
|
width = 15,
|
||||||
|
height = 6,
|
||||||
|
sort = true,
|
||||||
|
infotext = true,
|
||||||
|
autosort = true,
|
||||||
|
quickmove = true,
|
||||||
|
digilines = true,
|
||||||
|
})
|
||||||
|
register_crafts(
|
||||||
|
"Mithril",
|
||||||
|
"moreores:mithril_ingot",
|
||||||
|
"technic:gold_chest",
|
||||||
|
"technic:gold_locked_chest",
|
||||||
|
"technic:gold_protected_chest"
|
||||||
|
)
|
@ -1,88 +0,0 @@
|
|||||||
technic.chests.groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2,
|
|
||||||
tubedevice=1, tubedevice_receiver=1}
|
|
||||||
technic.chests.groups_noinv = {snappy=2, choppy=2, oddly_breakable_by_hand=2,
|
|
||||||
tubedevice=1, tubedevice_receiver=1, not_in_creative_inventory=1}
|
|
||||||
|
|
||||||
technic.chests.tube = {
|
|
||||||
insert_object = function(pos, node, stack, direction)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
return inv:add_item("main",stack)
|
|
||||||
end,
|
|
||||||
can_insert = function(pos, node, stack, direction)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
if meta:get_int("splitstacks") == 1 then
|
|
||||||
stack = stack:peek_item(1)
|
|
||||||
end
|
|
||||||
return inv:room_for_item("main",stack)
|
|
||||||
end,
|
|
||||||
input_inventory = "main",
|
|
||||||
connect_sides = {left=1, right=1, front=1, back=1, top=1, bottom=1},
|
|
||||||
}
|
|
||||||
|
|
||||||
technic.chests.can_dig = function(pos, player)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
return inv:is_empty("main")
|
|
||||||
end
|
|
||||||
|
|
||||||
-- utils for locked chest
|
|
||||||
|
|
||||||
local function inv_change(pos, count, player)
|
|
||||||
-- Skip check for pipeworks (fake player)
|
|
||||||
if minetest.is_player(player) and
|
|
||||||
not default.can_interact_with_node(player, pos) then
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
return count
|
|
||||||
end
|
|
||||||
|
|
||||||
function technic.chests.inv_move(pos, from_list, from_index, to_list, to_index, count, player)
|
|
||||||
return inv_change(pos, count, player)
|
|
||||||
end
|
|
||||||
function technic.chests.inv_put(pos, listname, index, stack, player)
|
|
||||||
return inv_change(pos, stack:get_count(), player)
|
|
||||||
end
|
|
||||||
function technic.chests.inv_take(pos, listname, index, stack, player)
|
|
||||||
return inv_change(pos, stack:get_count(), player)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- utils for protected chest
|
|
||||||
|
|
||||||
local function inv_change_protected(pos, count, player)
|
|
||||||
if minetest.is_protected(pos, player:get_player_name()) then
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
return count
|
|
||||||
end
|
|
||||||
|
|
||||||
function technic.chests.inv_move_protected(pos, from_list, from_index, to_list, to_index, count, player)
|
|
||||||
return inv_change_protected(pos, count, player)
|
|
||||||
end
|
|
||||||
function technic.chests.inv_put_protected(pos, listname, index, stack, player)
|
|
||||||
return inv_change_protected(pos, stack:get_count(), player)
|
|
||||||
end
|
|
||||||
function technic.chests.inv_take_protected(pos, listname, index, stack, player)
|
|
||||||
return inv_change_protected(pos, stack:get_count(), player)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- logging utils
|
|
||||||
|
|
||||||
function technic.chests.on_inv_move(pos, from_list, from_index, to_list, to_index, count, player)
|
|
||||||
minetest.log("action", player:get_player_name()..
|
|
||||||
" moves stuff in chest at "
|
|
||||||
..minetest.pos_to_string(pos))
|
|
||||||
end
|
|
||||||
|
|
||||||
function technic.chests.on_inv_put(pos, listname, index, stack, player)
|
|
||||||
minetest.log("action", player:get_player_name() ..
|
|
||||||
" moves " .. stack:get_name() ..
|
|
||||||
" to chest at " .. minetest.pos_to_string(pos))
|
|
||||||
end
|
|
||||||
|
|
||||||
function technic.chests.on_inv_take(pos, listname, index, stack, player)
|
|
||||||
minetest.log("action", player:get_player_name() ..
|
|
||||||
" takes " .. stack:get_name() ..
|
|
||||||
" from chest at " .. minetest.pos_to_string(pos))
|
|
||||||
end
|
|
@ -1,46 +0,0 @@
|
|||||||
minetest.register_craft({
|
|
||||||
output = 'technic:copper_chest 1',
|
|
||||||
recipe = {
|
|
||||||
{'default:copper_ingot','default:copper_ingot','default:copper_ingot'},
|
|
||||||
{'default:copper_ingot','technic:iron_chest','default:copper_ingot'},
|
|
||||||
{'default:copper_ingot','default:copper_ingot','default:copper_ingot'},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = 'technic:copper_locked_chest 1',
|
|
||||||
recipe = {
|
|
||||||
{'default:copper_ingot','default:copper_ingot','default:copper_ingot'},
|
|
||||||
{'default:copper_ingot','technic:iron_locked_chest','default:copper_ingot'},
|
|
||||||
{'default:copper_ingot','default:copper_ingot','default:copper_ingot'},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = 'technic:copper_locked_chest 1',
|
|
||||||
type = "shapeless",
|
|
||||||
recipe = {
|
|
||||||
'basic_materials:padlock',
|
|
||||||
'technic:copper_chest',
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
technic.chests:register("Copper", {
|
|
||||||
width = 12,
|
|
||||||
height = 5,
|
|
||||||
sort = true,
|
|
||||||
autosort = true,
|
|
||||||
infotext = false,
|
|
||||||
color = false,
|
|
||||||
locked = false,
|
|
||||||
})
|
|
||||||
|
|
||||||
technic.chests:register("Copper", {
|
|
||||||
width = 12,
|
|
||||||
height = 5,
|
|
||||||
sort = true,
|
|
||||||
autosort = true,
|
|
||||||
infotext = false,
|
|
||||||
color = false,
|
|
||||||
locked = true,
|
|
||||||
})
|
|
@ -1,9 +0,0 @@
|
|||||||
default
|
|
||||||
basic_materials
|
|
||||||
moreblocks?
|
|
||||||
moreores?
|
|
||||||
pipeworks?
|
|
||||||
intllib?
|
|
||||||
protector?
|
|
||||||
areas?
|
|
||||||
tubelib?
|
|
93
technic_chests/digilines.lua
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
|
||||||
|
function technic.chests.send_digiline_message(pos, event, player, items)
|
||||||
|
local set_channel = minetest.get_meta(pos):get_string("channel")
|
||||||
|
local player_name = player and player:get_player_name() or ""
|
||||||
|
digilines.receptor_send(pos, digilines.rules.default, set_channel, {
|
||||||
|
event = event,
|
||||||
|
items = items,
|
||||||
|
player = player_name,
|
||||||
|
pos = pos
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
local function item_matches(item, stack)
|
||||||
|
-- Same macthing as pipeworks filter injector
|
||||||
|
local name = stack:get_name()
|
||||||
|
local wear = stack:get_wear()
|
||||||
|
return (not item.name or name == item.name)
|
||||||
|
and (not item.group or (type(item.group) == "string" and minetest.get_item_group(name, item.group) ~= 0))
|
||||||
|
and (not item.wear or (type(item.wear) == "number" and wear == item.wear) or (type(item.wear) == "table"
|
||||||
|
and (not item.wear[1] or (type(item.wear[1]) == "number" and item.wear[1] <= wear))
|
||||||
|
and (not item.wear[2] or (type(item.wear[2]) == "number" and wear < item.wear[2]))))
|
||||||
|
and (not item.metadata or (type(item.metadata) == "string" and stack:get_metadata() == item.metadata))
|
||||||
|
end
|
||||||
|
|
||||||
|
function technic.chests.digiline_effector(pos, _, channel, msg)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
local set_channel = meta:get_string("channel")
|
||||||
|
if channel ~= set_channel then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if type(msg) ~= "table" or not msg.command then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local inv = meta:get_inventory()
|
||||||
|
|
||||||
|
if msg.command == "sort" then
|
||||||
|
technic.chests.sort_inv(inv, meta:get_int("sort_mode"))
|
||||||
|
|
||||||
|
elseif msg.command == "is_empty" then
|
||||||
|
local empty = inv:is_empty("main")
|
||||||
|
digilines.receptor_send(pos, digilines.rules.default, set_channel, empty)
|
||||||
|
|
||||||
|
elseif msg.command == "get_list" then
|
||||||
|
local inv_table = {}
|
||||||
|
local list = inv:get_list("main")
|
||||||
|
if list then
|
||||||
|
for _,stack in ipairs(list) do
|
||||||
|
if not stack:is_empty() then
|
||||||
|
table.insert(inv_table, stack:get_name().." "..stack:get_count())
|
||||||
|
else
|
||||||
|
table.insert(inv_table, "")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
digilines.receptor_send(pos, digilines.rules.default, set_channel, inv_table)
|
||||||
|
|
||||||
|
elseif msg.command == "get_stack" and type(msg.index) == "number" then
|
||||||
|
local stack = inv:get_stack("main", msg.index):to_table()
|
||||||
|
digilines.receptor_send(pos, digilines.rules.default, set_channel, stack)
|
||||||
|
|
||||||
|
elseif msg.command == "contains_item" and (type(msg.item) == "string" or type(msg.item) == "table") then
|
||||||
|
local contains = inv:contains_item("main", msg.item)
|
||||||
|
digilines.receptor_send(pos, digilines.rules.default, set_channel, contains)
|
||||||
|
|
||||||
|
elseif msg.command == "room_for_item" and (type(msg.item) == "string" or type(msg.item) == "table") then
|
||||||
|
local room = inv:room_for_item("main", msg.item)
|
||||||
|
digilines.receptor_send(pos, digilines.rules.default, set_channel, room)
|
||||||
|
|
||||||
|
elseif msg.command == "count_item" and (type(msg.item) == "string" or type(msg.item) == "table") then
|
||||||
|
local count = 0
|
||||||
|
local list = inv:get_list("main")
|
||||||
|
if list then
|
||||||
|
if type(msg.item) == "string" then
|
||||||
|
local itemstack = ItemStack(msg.item)
|
||||||
|
msg.item = {
|
||||||
|
name = itemstack:get_name(),
|
||||||
|
count = itemstack:get_count(),
|
||||||
|
wear = string.match(msg.item, "%S*:%S*%s%d%s(%d)") and itemstack:get_wear(),
|
||||||
|
metadata = string.match(msg.item, "%S*:%S*%s%d%s%d(%s.*)") and itemstack:get_meta():get_string("")
|
||||||
|
}
|
||||||
|
end
|
||||||
|
for _,stack in pairs(list) do
|
||||||
|
if not stack:is_empty() and item_matches(msg.item, stack) then
|
||||||
|
count = count + stack:get_count()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if msg.item.count and type(msg.item.count) == "number" and msg.item.count > 1 then
|
||||||
|
count = math.floor(count / msg.item.count)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
digilines.receptor_send(pos, digilines.rules.default, set_channel, count)
|
||||||
|
end
|
||||||
|
end
|
252
technic_chests/formspec.lua
Normal file
@ -0,0 +1,252 @@
|
|||||||
|
|
||||||
|
local S = rawget(_G, "intllib") and intllib.Getter() or function(s) return s end
|
||||||
|
--local S = minetest.get_translator("technic_chests")
|
||||||
|
|
||||||
|
local has_pipeworks = minetest.get_modpath("pipeworks")
|
||||||
|
local has_digilines = minetest.get_modpath("digilines")
|
||||||
|
|
||||||
|
local function get_pipeworks_fs(x, y, meta)
|
||||||
|
-- Use a container to reposition the pipeworks button.
|
||||||
|
return "container["..x..","..(y - 4.3).."]"..
|
||||||
|
pipeworks.fs_helpers.cycling_button(
|
||||||
|
meta,
|
||||||
|
pipeworks.button_base,
|
||||||
|
"splitstacks",
|
||||||
|
{
|
||||||
|
pipeworks.button_off,
|
||||||
|
pipeworks.button_on
|
||||||
|
}
|
||||||
|
)..pipeworks.button_label.."container_end[]"
|
||||||
|
end
|
||||||
|
|
||||||
|
local function get_color_fs(x, y, meta)
|
||||||
|
local fs = ""
|
||||||
|
for a = 0, 3 do
|
||||||
|
for b = 0, 3 do
|
||||||
|
fs = fs.."image_button["..(x + b * 0.73)..","..(y + 0.1 + a * 0.79)..";0.8,0.8;"..
|
||||||
|
"technic_colorbutton"..(a * 4 + b)..".png;color_button"..(a * 4 + b + 1)..";]"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local selected = meta:get_int("color")
|
||||||
|
local color
|
||||||
|
if technic.chests.colors[selected] then
|
||||||
|
color = technic.chests.colors[selected][2]
|
||||||
|
else
|
||||||
|
color = S("None")
|
||||||
|
end
|
||||||
|
return fs.."label["..(x + 0.1)..","..(y + 3.4)..";"..S("Selected Color: %s"):format(color).."]"
|
||||||
|
end
|
||||||
|
|
||||||
|
local function get_quickmove_fs(x, y)
|
||||||
|
return "button["..x..","..y..";3,1;existing_to_chest;"..S("Move existing to Chest").."]"..
|
||||||
|
"label["..(x + 0.1)..","..(y + 1.15)..";"..S("Move specific")..":\n("..S("Drop to move")..")]"..
|
||||||
|
"list[context;quickmove;"..(x + 1.8)..","..(y + 1.15)..";1,1]"..
|
||||||
|
"button["..x..","..(y + 2.3)..";3,1;all_to_chest;"..S("Move all to Chest").."]"..
|
||||||
|
"button["..x..","..(y + 3.2)..";3,1;all_to_inv;"..S("Move all to Inventory").."]"
|
||||||
|
end
|
||||||
|
|
||||||
|
local function get_digilines_fs(x, y, meta)
|
||||||
|
local channel = minetest.formspec_escape(meta:get_string("channel"))
|
||||||
|
local put = meta:get_int("send_put") == 1 and "true" or "false"
|
||||||
|
local take = meta:get_int("send_take") == 1 and "true" or "false"
|
||||||
|
local inject = meta:get_int("send_inject") == 1 and "true" or "false"
|
||||||
|
local pull = meta:get_int("send_pull") == 1 and "true" or "false"
|
||||||
|
local overflow = meta:get_int("send_overflow") == 1 and "true" or "false"
|
||||||
|
return "field["..(x + 0.3)..","..(y + 0.5)..";3,1;channel;Digiline Channel:;"..channel.."]"..
|
||||||
|
"button["..(x + 0.5)..","..(y + 1.1)..";2,1;save_channel;Save Channel]"..
|
||||||
|
"checkbox["..(x + 0.1)..","..(y + 1.8)..";send_put;"..S("Send player put messages")..";"..put.."]"..
|
||||||
|
"checkbox["..(x + 0.1)..","..(y + 2.2)..";send_take;"..S("Send player take messages")..";"..take.."]"..
|
||||||
|
"checkbox["..(x + 0.1)..","..(y + 2.6)..";send_inject;"..S("Send tube inject messages")..";"..inject.."]"..
|
||||||
|
"checkbox["..(x + 0.1)..","..(y + 3.0)..";send_pull;"..S("Send tube pull messages")..";"..pull.."]"..
|
||||||
|
"checkbox["..(x + 0.1)..","..(y + 3.4)..";send_overflow;"..S("Send overflow messages")..";"..overflow.."]"
|
||||||
|
end
|
||||||
|
|
||||||
|
local function get_infotext_fs(editing, meta)
|
||||||
|
local infotext = minetest.formspec_escape(meta:get_string("infotext"))
|
||||||
|
if editing then
|
||||||
|
return "image_button[0,0.1;0.8,0.8;technic_checkmark_icon.png;save_infotext;]"..
|
||||||
|
"field[1,0.3;4,1;infotext;;"..infotext.."]"
|
||||||
|
else
|
||||||
|
return "image_button[0,0.1;0.8,0.8;technic_pencil_icon.png;edit_infotext;]"..
|
||||||
|
"label[1,0;"..infotext.."]"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function get_autosort_fs(x, meta)
|
||||||
|
if meta:get_int("autosort") == 1 then
|
||||||
|
return "button["..x..",0;2,1;autosort;"..S("Auto-sort is On").."]"
|
||||||
|
else
|
||||||
|
return "button["..x..",0;2,1;autosort;"..S("Auto-sort is Off").."]"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function get_sort_fs(x, meta)
|
||||||
|
local mode = meta:get_int("sort_mode")
|
||||||
|
local fs = "button["..(x + 2)..",0;1,1;sort;"..S("Sort").."]"
|
||||||
|
if mode == 1 then
|
||||||
|
return fs.."button["..x..",0;2,1;sort_mode;"..S("Sort by Quantity").."]"
|
||||||
|
elseif mode == 2 then
|
||||||
|
return fs.."button["..x..",0;2,1;sort_mode;"..S("Sort by Type").."]"
|
||||||
|
elseif mode == 3 then
|
||||||
|
return fs.."button["..x..",0;2,1;sort_mode;"..S("Sort by Wear").."]"
|
||||||
|
else
|
||||||
|
return fs.."button["..x..",0;2,1;sort_mode;"..S("Sort by Item").."]"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function technic.chests.get_formspec(data)
|
||||||
|
local formspec = {}
|
||||||
|
local top_width = (data.infotext and 6 or 0) + (data.autosort and 2 or 0) + (data.sort and 3 or 0)
|
||||||
|
local bottom_width = (data.quickmove and 3 or 0) + ((data.color or data.digilines) and 3 or 0) + 8
|
||||||
|
local width = math.max(top_width, bottom_width, data.width)
|
||||||
|
local padding = (width - bottom_width) / 2
|
||||||
|
if data.quickmove and (data.color or data.digilines) then
|
||||||
|
padding = (width - bottom_width) / 4
|
||||||
|
elseif data.quickmove or data.color or data.digilines then
|
||||||
|
padding = (width - bottom_width) / 3
|
||||||
|
end
|
||||||
|
local player_inv_left = padding
|
||||||
|
if data.quickmove then
|
||||||
|
player_inv_left = padding + 3 + padding
|
||||||
|
end
|
||||||
|
local player_inv_top = data.height + (has_pipeworks and 1.6 or 1.3)
|
||||||
|
local height = data.height + (has_pipeworks and 5.4 or 5.1)
|
||||||
|
local chest_inv_left = (width - data.width) / 2
|
||||||
|
formspec.base =
|
||||||
|
"size["..width..","..height.."]"..
|
||||||
|
"list[context;main;"..chest_inv_left..",1;"..data.width..","..data.height..";]"..
|
||||||
|
"list[current_player;main;"..player_inv_left..","..player_inv_top..";8,4;]"..
|
||||||
|
"listring[context;main]"..
|
||||||
|
"listring[current_player;main]"..
|
||||||
|
default.get_hotbar_bg(player_inv_left, player_inv_top)
|
||||||
|
if data.quickmove then
|
||||||
|
formspec.base = formspec.base..get_quickmove_fs(padding, data.height + 1.2)
|
||||||
|
end
|
||||||
|
formspec.padding = padding
|
||||||
|
formspec.width = width
|
||||||
|
return formspec
|
||||||
|
end
|
||||||
|
|
||||||
|
function technic.chests.update_formspec(pos, data, edit_infotext)
|
||||||
|
local formspec = data.formspec.base
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
if data.infotext then
|
||||||
|
formspec = formspec..get_infotext_fs(edit_infotext, meta)
|
||||||
|
end
|
||||||
|
if data.sort then
|
||||||
|
formspec = formspec..get_sort_fs(data.formspec.width - 3, meta)
|
||||||
|
if data.autosort then
|
||||||
|
formspec = formspec..get_autosort_fs(data.formspec.width - 5, meta)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if has_pipeworks then
|
||||||
|
local offset = data.quickmove and (data.formspec.padding * 2 + 3) or data.formspec.padding
|
||||||
|
formspec = formspec..get_pipeworks_fs(offset, data.height + 1, meta)
|
||||||
|
end
|
||||||
|
if data.color or (data.digilines and has_digilines) then
|
||||||
|
local offset = data.quickmove and (data.formspec.padding * 3 + 11) or (data.formspec.padding * 2 + 8)
|
||||||
|
if data.color then
|
||||||
|
formspec = formspec..get_color_fs(offset, data.height + 1.2, meta)
|
||||||
|
else
|
||||||
|
formspec = formspec..get_digilines_fs(offset, data.height + 1.2, meta)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
meta:set_string("formspec", formspec)
|
||||||
|
end
|
||||||
|
|
||||||
|
function technic.chests.get_receive_fields(data)
|
||||||
|
return function(pos, formname, fields, player)
|
||||||
|
if not fields or not player then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
local chest_inv = meta:get_inventory()
|
||||||
|
local player_inv = player:get_inventory()
|
||||||
|
if fields.quit then
|
||||||
|
if meta:get_int("autosort") == 1 then
|
||||||
|
technic.chests.sort_inv(chest_inv, meta:get_int("sort_mode"))
|
||||||
|
end
|
||||||
|
technic.chests.update_formspec(pos, data)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if not technic.chests.change_allowed(pos, player, data.locked, data.protected) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if has_pipeworks then
|
||||||
|
pipeworks.fs_helpers.on_receive_fields(pos, fields)
|
||||||
|
end
|
||||||
|
if data.sort then
|
||||||
|
if fields.sort then
|
||||||
|
technic.chests.sort_inv(chest_inv, meta:get_int("sort_mode"))
|
||||||
|
end
|
||||||
|
if fields.sort_mode then
|
||||||
|
local value = meta:get_int("sort_mode") + 1
|
||||||
|
if value < 0 or value > 3 then
|
||||||
|
value = 0
|
||||||
|
end
|
||||||
|
meta:set_int("sort_mode", value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if data.autosort and fields.autosort then
|
||||||
|
local value = meta:get_int("autosort") == 1 and 0 or 1
|
||||||
|
meta:set_int("autosort", value)
|
||||||
|
end
|
||||||
|
if data.quickmove then
|
||||||
|
if fields.all_to_chest then
|
||||||
|
local moved_items = technic.chests.move_inv(player_inv, chest_inv)
|
||||||
|
if has_digilines and meta:get_int("send_put") == 1 then
|
||||||
|
technic.chests.send_digiline_message(pos, "put", player, moved_items)
|
||||||
|
end
|
||||||
|
technic.chests.log_inv_change(pos, player:get_player_name(), "put", "stuff")
|
||||||
|
elseif fields.all_to_inv then
|
||||||
|
local moved_items = technic.chests.move_inv(chest_inv, player_inv)
|
||||||
|
if has_digilines and meta:get_int("send_take") == 1 then
|
||||||
|
technic.chests.send_digiline_message(pos, "take", player, moved_items)
|
||||||
|
end
|
||||||
|
technic.chests.log_inv_change(pos, player:get_player_name(), "take", "stuff")
|
||||||
|
elseif fields.existing_to_chest then
|
||||||
|
local items = technic.chests.get_inv_items(chest_inv)
|
||||||
|
local moved_items = technic.chests.move_inv(player_inv, chest_inv, items)
|
||||||
|
if has_digilines and meta:get_int("send_put") == 1 then
|
||||||
|
technic.chests.send_digiline_message(pos, "put", player, moved_items)
|
||||||
|
end
|
||||||
|
technic.chests.log_inv_change(pos, player:get_player_name(), "put", "stuff")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if data.color then
|
||||||
|
for i = 1, 16 do
|
||||||
|
if fields["color_button"..i] then
|
||||||
|
local node = minetest.get_node(pos)
|
||||||
|
if technic.chests.colors[i] then
|
||||||
|
node.name = data.node_name.."_"..technic.chests.colors[i][1]
|
||||||
|
else
|
||||||
|
node.name = data.node_name
|
||||||
|
end
|
||||||
|
minetest.swap_node(pos, node)
|
||||||
|
meta:set_string("color", i)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if data.digilines and has_digilines then
|
||||||
|
if fields.save_channel and fields.channel then
|
||||||
|
meta:set_string("channel", fields.channel)
|
||||||
|
end
|
||||||
|
for _,setting in pairs({"send_put", "send_take", "send_inject", "send_pull", "send_overflow"}) do
|
||||||
|
if fields[setting] then
|
||||||
|
local value = fields[setting] == "true" and 1 or 0
|
||||||
|
meta:set_int(setting, value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if data.infotext then
|
||||||
|
if fields.edit_infotext then
|
||||||
|
technic.chests.update_formspec(pos, data, true)
|
||||||
|
return
|
||||||
|
elseif fields.save_infotext and fields.infotext then
|
||||||
|
meta:set_string("infotext", fields.infotext)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
technic.chests.update_formspec(pos, data)
|
||||||
|
end
|
||||||
|
end
|
@ -1,57 +0,0 @@
|
|||||||
|
|
||||||
local material_list
|
|
||||||
if minetest.get_modpath("moreores") then
|
|
||||||
material_list = { 'silver' }
|
|
||||||
else
|
|
||||||
-- Make the gold chest obtainable for mere mortals (the silver chest is not obtainable)
|
|
||||||
material_list = { 'copper', 'silver' }
|
|
||||||
end
|
|
||||||
|
|
||||||
for _, material in ipairs(material_list) do
|
|
||||||
minetest.register_craft({
|
|
||||||
output = 'technic:gold_chest',
|
|
||||||
recipe = {
|
|
||||||
{'default:gold_ingot','default:gold_ingot','default:gold_ingot'},
|
|
||||||
{'default:gold_ingot',"technic:"..material.."_chest",'default:gold_ingot'},
|
|
||||||
{'default:gold_ingot','default:gold_ingot','default:gold_ingot'},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = 'technic:gold_locked_chest',
|
|
||||||
recipe = {
|
|
||||||
{'default:gold_ingot','default:gold_ingot','default:gold_ingot'},
|
|
||||||
{'default:gold_ingot',"technic:"..material.."_locked_chest",'default:gold_ingot'},
|
|
||||||
{'default:gold_ingot','default:gold_ingot','default:gold_ingot'},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = 'technic:gold_locked_chest',
|
|
||||||
type = "shapeless",
|
|
||||||
recipe = {
|
|
||||||
'basic_materials:padlock',
|
|
||||||
'technic:gold_chest',
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
technic.chests:register("Gold", {
|
|
||||||
width = 15,
|
|
||||||
height = 6,
|
|
||||||
sort = true,
|
|
||||||
autosort = true,
|
|
||||||
infotext = true,
|
|
||||||
color = true,
|
|
||||||
locked = false,
|
|
||||||
})
|
|
||||||
|
|
||||||
technic.chests:register("Gold", {
|
|
||||||
width = 15,
|
|
||||||
height = 6,
|
|
||||||
sort = true,
|
|
||||||
autosort = true,
|
|
||||||
infotext = true,
|
|
||||||
color = true,
|
|
||||||
locked = true,
|
|
||||||
})
|
|
@ -1,82 +1,83 @@
|
|||||||
-- Minetest 0.4.6 mod: technic_chests
|
|
||||||
-- namespace: technic
|
local S = rawget(_G, "intllib") and intllib.Getter() or function(s) return s end
|
||||||
-- (c) 2012-2013 by RealBadAngel <mk@realbadangel.pl>
|
--local S = minetest.get_translator("technic_chests")
|
||||||
|
|
||||||
local modpath = minetest.get_modpath("technic_chests")
|
local modpath = minetest.get_modpath("technic_chests")
|
||||||
|
|
||||||
technic = rawget(_G, "technic") or {}
|
technic = rawget(_G, "technic") or {}
|
||||||
technic.chests = {}
|
technic.chests = {}
|
||||||
|
|
||||||
dofile(modpath.."/common.lua")
|
technic.chests.colors = {
|
||||||
dofile(modpath.."/register.lua")
|
{"black", S("Black")},
|
||||||
dofile(modpath.."/iron_chest.lua")
|
{"blue", S("Blue")},
|
||||||
dofile(modpath.."/copper_chest.lua")
|
{"brown", S("Brown")},
|
||||||
dofile(modpath.."/silver_chest.lua")
|
{"cyan", S("Cyan")},
|
||||||
dofile(modpath.."/gold_chest.lua")
|
{"dark_green", S("Dark Green")},
|
||||||
dofile(modpath.."/mithril_chest.lua")
|
{"dark_grey", S("Dark Grey")},
|
||||||
|
{"green", S("Green")},
|
||||||
|
{"grey", S("Grey")},
|
||||||
|
{"magenta", S("Magenta")},
|
||||||
|
{"orange", S("Orange")},
|
||||||
|
{"pink", S("Pink")},
|
||||||
|
{"red", S("Red")},
|
||||||
|
{"violet", S("Violet")},
|
||||||
|
{"white", S("White")},
|
||||||
|
{"yellow", S("Yellow")},
|
||||||
|
}
|
||||||
|
|
||||||
-- undo all of the locked wooden chest recipes created by default and
|
function technic.chests.change_allowed(pos, player, owned, protected)
|
||||||
-- moreblocks, and just make them use a padlock.
|
if owned then
|
||||||
|
if minetest.is_player(player) and not default.can_interact_with_node(player, pos) then
|
||||||
if minetest.get_modpath("moreblocks") then
|
return false
|
||||||
minetest.clear_craft({
|
end
|
||||||
type = "shapeless",
|
elseif protected then
|
||||||
recipe = {
|
if minetest.is_protected(pos, player:get_player_name()) then
|
||||||
"default:chest",
|
return false
|
||||||
"default:gold_ingot",
|
end
|
||||||
}
|
end
|
||||||
})
|
return true
|
||||||
|
|
||||||
minetest.clear_craft({
|
|
||||||
type = "shapeless",
|
|
||||||
recipe = {
|
|
||||||
"default:chest",
|
|
||||||
"default:bronze_ingot",
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.clear_craft({
|
|
||||||
type = "shapeless",
|
|
||||||
recipe = {
|
|
||||||
"default:chest",
|
|
||||||
"default:copper_ingot",
|
|
||||||
}
|
|
||||||
})
|
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.clear_craft({
|
if minetest.get_modpath("digilines") then
|
||||||
type = "shapeless",
|
dofile(modpath.."/digilines.lua")
|
||||||
recipe = {
|
end
|
||||||
"default:chest",
|
|
||||||
"default:steel_ingot",
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.clear_craft({output = "default:chest_locked"})
|
dofile(modpath.."/formspec.lua")
|
||||||
|
dofile(modpath.."/inventory.lua")
|
||||||
|
dofile(modpath.."/register.lua")
|
||||||
|
dofile(modpath.."/chests.lua")
|
||||||
|
|
||||||
minetest.register_craft({
|
-- Undo all of the locked wooden chest recipes, and just make them use a padlock.
|
||||||
output = "default:chest_locked",
|
minetest.register_on_mods_loaded(function()
|
||||||
recipe = {
|
minetest.clear_craft({output = "default:chest_locked"})
|
||||||
{ "group:wood", "group:wood", "group:wood" },
|
minetest.register_craft({
|
||||||
{ "group:wood", "basic_materials:padlock", "group:wood" },
|
output = "default:chest_locked",
|
||||||
{ "group:wood", "group:wood", "group:wood" }
|
recipe = {
|
||||||
}
|
{ "group:wood", "group:wood", "group:wood" },
|
||||||
})
|
{ "group:wood", "basic_materials:padlock", "group:wood" },
|
||||||
|
{ "group:wood", "group:wood", "group:wood" }
|
||||||
minetest.register_craft({
|
}
|
||||||
output = "default:chest_locked",
|
})
|
||||||
type = "shapeless",
|
minetest.register_craft({
|
||||||
recipe = {
|
output = "default:chest_locked",
|
||||||
"default:chest",
|
type = "shapeless",
|
||||||
"basic_materials:padlock"
|
recipe = {
|
||||||
}
|
"default:chest",
|
||||||
})
|
"basic_materials:padlock"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- Conversion for old chests
|
||||||
minetest.register_lbm({
|
minetest.register_lbm({
|
||||||
name = "technic_chests:fix_wooden_chests",
|
name = "technic_chests:old_chest_conversion",
|
||||||
nodenames = {"default:chest"},
|
nodenames = {"group:technic_chest"},
|
||||||
|
run_at_every_load = false,
|
||||||
action = function(pos, node)
|
action = function(pos, node)
|
||||||
local meta = minetest.get_meta(pos)
|
-- Use `on_construct` function because that has data from register function
|
||||||
meta:set_string("formspec", "")
|
local def = minetest.registered_nodes[node.name]
|
||||||
end
|
if def and def.on_construct then
|
||||||
|
def.on_construct(pos)
|
||||||
|
end
|
||||||
|
end,
|
||||||
})
|
})
|
||||||
|
142
technic_chests/inventory.lua
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
|
||||||
|
-- Table to define order of type sorting
|
||||||
|
local itemtypes = {
|
||||||
|
node = 1,
|
||||||
|
tool = 2,
|
||||||
|
craft = 3,
|
||||||
|
none = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
function technic.chests.sort_inv(inv, mode)
|
||||||
|
local list = inv:get_list("main")
|
||||||
|
if not list then return end
|
||||||
|
local items = {}
|
||||||
|
for _,stack in pairs(list) do
|
||||||
|
if not stack:is_empty() then
|
||||||
|
local name = stack:get_name()
|
||||||
|
local wear = stack:get_wear()
|
||||||
|
local meta = stack:get_metadata()
|
||||||
|
local count = stack:get_count()
|
||||||
|
local def = minetest.registered_items[name]
|
||||||
|
local itemtype = (def and itemtypes[def.type]) and def.type or "none"
|
||||||
|
local key = string.format("%s %05d %s", name, wear, meta)
|
||||||
|
if not items[key] then
|
||||||
|
items[key] = {
|
||||||
|
stacks = {stack},
|
||||||
|
wear = wear,
|
||||||
|
count = count,
|
||||||
|
itemtype = itemtype,
|
||||||
|
key = key,
|
||||||
|
}
|
||||||
|
else
|
||||||
|
items[key].count = items[key].count + count
|
||||||
|
table.insert(items[key].stacks, stack)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local unique_items = {}
|
||||||
|
for k,v in pairs(items) do
|
||||||
|
table.insert(unique_items, v)
|
||||||
|
end
|
||||||
|
if mode == 1 then
|
||||||
|
-- Quantity
|
||||||
|
table.sort(unique_items, function(a, b)
|
||||||
|
if a.count ~= b.count then
|
||||||
|
return a.count > b.count
|
||||||
|
end
|
||||||
|
return a.key < b.key
|
||||||
|
end)
|
||||||
|
elseif mode == 2 then
|
||||||
|
-- Type
|
||||||
|
table.sort(unique_items, function(a, b)
|
||||||
|
if itemtypes[a.itemtype] ~= itemtypes[b.itemtype] then
|
||||||
|
return itemtypes[a.itemtype] < itemtypes[b.itemtype]
|
||||||
|
end
|
||||||
|
return a.key < b.key
|
||||||
|
end)
|
||||||
|
elseif mode == 3 then
|
||||||
|
-- Wear
|
||||||
|
table.sort(unique_items, function(a, b)
|
||||||
|
if a.itemtype == "tool" and b.itemtype == "tool" then
|
||||||
|
if a.wear ~= b.wear then
|
||||||
|
return a.wear < b.wear
|
||||||
|
end
|
||||||
|
return a.key < b.key
|
||||||
|
elseif a.itemtype == "tool" or b.itemtype == "tool" then
|
||||||
|
return a.itemtype == "tool"
|
||||||
|
end
|
||||||
|
return a.key < b.key
|
||||||
|
end)
|
||||||
|
else
|
||||||
|
-- Item
|
||||||
|
table.sort(unique_items, function(a, b)
|
||||||
|
return a.key < b.key
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
inv:set_list("main", {})
|
||||||
|
for _,item in ipairs(unique_items) do
|
||||||
|
for _,stack in ipairs(item.stacks) do
|
||||||
|
inv:add_item("main", stack)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function technic.chests.get_inv_items(inv)
|
||||||
|
local list = inv:get_list("main")
|
||||||
|
if not list then return {} end
|
||||||
|
local keys = {}
|
||||||
|
for _,stack in pairs(list) do
|
||||||
|
if not stack:is_empty() then
|
||||||
|
keys[stack:get_name()] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local items = {}
|
||||||
|
for k,_ in pairs(keys) do
|
||||||
|
items[#items + 1] = k
|
||||||
|
end
|
||||||
|
return items
|
||||||
|
end
|
||||||
|
|
||||||
|
function technic.chests.move_inv(from_inv, to_inv, filter)
|
||||||
|
local list = from_inv:get_list("main")
|
||||||
|
if not list then return {} end
|
||||||
|
local moved_items = {}
|
||||||
|
for i,stack in ipairs(list) do
|
||||||
|
if not stack:is_empty() then
|
||||||
|
local move_stack = false
|
||||||
|
local name = stack:get_name()
|
||||||
|
if name == filter or not filter then
|
||||||
|
move_stack = true
|
||||||
|
elseif type(filter) == "table" then
|
||||||
|
for _,k in pairs(filter) do
|
||||||
|
if name == k then
|
||||||
|
move_stack = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if move_stack then
|
||||||
|
local leftover = to_inv:add_item("main", stack)
|
||||||
|
if not leftover:is_empty() then
|
||||||
|
from_inv:set_stack("main", i, leftover)
|
||||||
|
stack:set_count(stack:get_count() - leftover:get_count())
|
||||||
|
else
|
||||||
|
from_inv:set_stack("main", i, "")
|
||||||
|
end
|
||||||
|
table.insert(moved_items, stack:to_table())
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return moved_items
|
||||||
|
end
|
||||||
|
|
||||||
|
function technic.chests.log_inv_change(pos, name, change, items)
|
||||||
|
local spos = minetest.pos_to_string(pos)
|
||||||
|
if change == "move" then
|
||||||
|
minetest.log("action", name.." moves "..items.." in chest at "..spos)
|
||||||
|
elseif change == "put" then
|
||||||
|
minetest.log("action", name.." puts "..items.." into chest at "..spos)
|
||||||
|
elseif change == "take" then
|
||||||
|
minetest.log("action", name.." takes "..items.." from chest at "..spos)
|
||||||
|
end
|
||||||
|
end
|
@ -1,53 +0,0 @@
|
|||||||
local cast_iron_ingot
|
|
||||||
if minetest.get_modpath("technic_worldgen") then
|
|
||||||
cast_iron_ingot = "technic:cast_iron_ingot"
|
|
||||||
else
|
|
||||||
cast_iron_ingot = "default:steel_ingot"
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = 'technic:iron_chest 1',
|
|
||||||
recipe = {
|
|
||||||
{cast_iron_ingot,cast_iron_ingot,cast_iron_ingot},
|
|
||||||
{cast_iron_ingot,'default:chest',cast_iron_ingot},
|
|
||||||
{cast_iron_ingot,cast_iron_ingot,cast_iron_ingot},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = 'technic:iron_locked_chest 1',
|
|
||||||
recipe = {
|
|
||||||
{cast_iron_ingot,cast_iron_ingot,cast_iron_ingot},
|
|
||||||
{cast_iron_ingot,'default:chest_locked',cast_iron_ingot},
|
|
||||||
{cast_iron_ingot,cast_iron_ingot,cast_iron_ingot},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = 'technic:iron_locked_chest 1',
|
|
||||||
type = "shapeless",
|
|
||||||
recipe = {
|
|
||||||
'basic_materials:padlock',
|
|
||||||
'technic:iron_chest',
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
technic.chests:register("Iron", {
|
|
||||||
width = 9,
|
|
||||||
height = 5,
|
|
||||||
sort = true,
|
|
||||||
autosort = false,
|
|
||||||
infotext = false,
|
|
||||||
color = false,
|
|
||||||
locked = false,
|
|
||||||
})
|
|
||||||
|
|
||||||
technic.chests:register("Iron", {
|
|
||||||
width = 9,
|
|
||||||
height = 5,
|
|
||||||
sort = true,
|
|
||||||
autosort = false,
|
|
||||||
infotext = false,
|
|
||||||
color = false,
|
|
||||||
locked = true,
|
|
||||||
})
|
|
@ -1,71 +0,0 @@
|
|||||||
if minetest.get_modpath("moreores") then
|
|
||||||
minetest.register_craft({
|
|
||||||
output = 'technic:mithril_chest 1',
|
|
||||||
recipe = {
|
|
||||||
{'moreores:mithril_ingot','moreores:mithril_ingot','moreores:mithril_ingot'},
|
|
||||||
{'moreores:mithril_ingot','technic:gold_chest','moreores:mithril_ingot'},
|
|
||||||
{'moreores:mithril_ingot','moreores:mithril_ingot','moreores:mithril_ingot'},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = 'technic:mithril_locked_chest 1',
|
|
||||||
recipe = {
|
|
||||||
{'moreores:mithril_ingot','moreores:mithril_ingot','moreores:mithril_ingot'},
|
|
||||||
{'moreores:mithril_ingot','technic:gold_locked_chest','moreores:mithril_ingot'},
|
|
||||||
{'moreores:mithril_ingot','moreores:mithril_ingot','moreores:mithril_ingot'},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = 'technic:mithril_locked_chest 1',
|
|
||||||
type = "shapeless",
|
|
||||||
recipe = {
|
|
||||||
'basic_materials:padlock',
|
|
||||||
'technic:mithril_chest',
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
-- plain chest
|
|
||||||
technic.chests:register("Mithril", {
|
|
||||||
width = 15,
|
|
||||||
height = 6,
|
|
||||||
sort = true,
|
|
||||||
autosort = true,
|
|
||||||
infotext = false,
|
|
||||||
color = false,
|
|
||||||
locked = false,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- owned locked chest
|
|
||||||
technic.chests:register("Mithril", {
|
|
||||||
width = 15,
|
|
||||||
height = 6,
|
|
||||||
sort = true,
|
|
||||||
autosort = true,
|
|
||||||
infotext = false,
|
|
||||||
color = false,
|
|
||||||
locked = true,
|
|
||||||
})
|
|
||||||
|
|
||||||
if minetest.get_modpath("protector") or minetest.get_modpath("areas") then
|
|
||||||
-- protected chest (works with any protection mod that overrides minetest.is_protected)
|
|
||||||
technic.chests:register("Mithril", {
|
|
||||||
width = 15,
|
|
||||||
height = 6,
|
|
||||||
sort = true,
|
|
||||||
autosort = true,
|
|
||||||
infotext = false,
|
|
||||||
color = false,
|
|
||||||
protected = true,
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = 'technic:mithril_protected_chest 1',
|
|
||||||
recipe = {
|
|
||||||
{'basic_materials:padlock'},
|
|
||||||
{'technic:mithril_locked_chest'},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
end
|
|
@ -1,3 +1,3 @@
|
|||||||
name = technic_chests
|
name = technic_chests
|
||||||
depends = default, basic_materials
|
depends = default, basic_materials
|
||||||
optional_depends = moreblocks, moreores, pipeworks, intllib, tubelib
|
optional_depends = moreores, pipeworks, protector, digilines, intllib
|
||||||
|
@ -1,452 +1,242 @@
|
|||||||
|
|
||||||
local S = rawget(_G, "intllib") and intllib.Getter() or function(s) return s end
|
local S = rawget(_G, "intllib") and intllib.Getter() or function(s) return s end
|
||||||
|
--local S = minetest.get_translator("technic_chests")
|
||||||
|
|
||||||
local pipeworks = rawget(_G, "pipeworks")
|
local has_pipeworks = minetest.get_modpath("pipeworks")
|
||||||
local fs_helpers = rawget(_G, "fs_helpers")
|
local has_digilines = minetest.get_modpath("digilines")
|
||||||
local tubelib_exists = minetest.global_exists("tubelib")
|
local has_protector = minetest.get_modpath("protector")
|
||||||
|
|
||||||
local has_protector_mod = minetest.get_modpath("protector")
|
local tube_entry = has_pipeworks and "^pipeworks_tube_connection_metallic.png" or ""
|
||||||
|
local protector_overlay = has_protector and "^protector_logo.png" or "^technic_protector_overlay.png"
|
||||||
|
|
||||||
local allow_label = ""
|
local node_groups = {
|
||||||
local tube_entry = ""
|
snappy = 2,
|
||||||
local shift_edit_field = 0
|
choppy = 2,
|
||||||
|
oddly_breakable_by_hand = 2,
|
||||||
if not minetest.get_modpath("pipeworks") then
|
tubedevice = 1,
|
||||||
-- Pipeworks is not installed. Simulate using a dummy table...
|
tubedevice_receiver = 1,
|
||||||
pipeworks = {}
|
technic_chest = 1,
|
||||||
fs_helpers = {}
|
|
||||||
local pipeworks_meta = {}
|
|
||||||
setmetatable(pipeworks, pipeworks_meta)
|
|
||||||
local dummy = function()
|
|
||||||
end
|
|
||||||
pipeworks_meta.__index = function(table, key)
|
|
||||||
print("[technic_chests] WARNING: variable or method '"..key.."' not present in dummy pipeworks table - assuming it is a method...")
|
|
||||||
pipeworks[key] = dummy
|
|
||||||
return dummy
|
|
||||||
end
|
|
||||||
pipeworks.after_place = dummy
|
|
||||||
pipeworks.after_dig = dummy
|
|
||||||
fs_helpers.cycling_button = function() return "" end
|
|
||||||
else
|
|
||||||
fs_helpers = pipeworks.fs_helpers
|
|
||||||
allow_label = "label[0.9,0.36;Allow splitting incoming stacks from tubes]"
|
|
||||||
shift_edit_field = 3
|
|
||||||
tube_entry = "^pipeworks_tube_connection_metallic.png"
|
|
||||||
end
|
|
||||||
|
|
||||||
local chest_mark_colors = {
|
|
||||||
{"black", S("Black")},
|
|
||||||
{"blue", S("Blue")},
|
|
||||||
{"brown", S("Brown")},
|
|
||||||
{"cyan", S("Cyan")},
|
|
||||||
{"dark_green", S("Dark Green")},
|
|
||||||
{"dark_grey", S("Dark Grey")},
|
|
||||||
{"green", S("Green")},
|
|
||||||
{"grey", S("Grey")},
|
|
||||||
{"magenta", S("Magenta")},
|
|
||||||
{"orange", S("Orange")},
|
|
||||||
{"pink", S("Pink")},
|
|
||||||
{"red", S("Red")},
|
|
||||||
{"violet", S("Violet")},
|
|
||||||
{"white", S("White")},
|
|
||||||
{"yellow", S("Yellow")},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local node_groups_no_inv = {
|
||||||
|
snappy = 2,
|
||||||
|
choppy = 2,
|
||||||
|
oddly_breakable_by_hand = 2,
|
||||||
|
tubedevice = 1,
|
||||||
|
tubedevice_receiver = 1,
|
||||||
|
technic_chest = 1,
|
||||||
|
not_in_creative_inventory = 1,
|
||||||
|
}
|
||||||
|
|
||||||
local function colorid_to_postfix(id)
|
local function get_tiles(name, data, color)
|
||||||
return chest_mark_colors[id] and "_"..chest_mark_colors[id][1] or ""
|
local tiles = {
|
||||||
|
"technic_"..name.."_chest_top.png"..tube_entry,
|
||||||
|
"technic_"..name.."_chest_top.png"..tube_entry,
|
||||||
|
"technic_"..name.."_chest_side.png"..tube_entry,
|
||||||
|
"technic_"..name.."_chest_side.png"..tube_entry,
|
||||||
|
"technic_"..name.."_chest_side.png"..tube_entry,
|
||||||
|
"technic_"..name.."_chest_front.png"
|
||||||
|
}
|
||||||
|
if data.color and color then
|
||||||
|
tiles[6] = tiles[6].."^technic_chest_overlay_"..technic.chests.colors[color][1]..".png"
|
||||||
|
end
|
||||||
|
if data.locked then
|
||||||
|
tiles[6] = tiles[6].."^technic_"..name.."_chest_lock_overlay.png"
|
||||||
|
elseif data.protected then
|
||||||
|
tiles[6] = tiles[6]..protector_overlay
|
||||||
|
end
|
||||||
|
return tiles
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function technic.chests.register_chest(name, data)
|
||||||
local function get_color_buttons(coleft, lotop)
|
|
||||||
local buttons_string = ""
|
|
||||||
for y = 0, 3 do
|
|
||||||
for x = 0, 3 do
|
|
||||||
local file_name = "technic_colorbutton"..(y * 4 + x)..".png"
|
|
||||||
buttons_string = buttons_string.."image_button["
|
|
||||||
..(coleft + 0.1 + x * 0.7)..","..(lotop + 0.1 + y * 0.7)
|
|
||||||
..";0.8,0.8;"..file_name..";color_button"
|
|
||||||
..(y * 4 + x + 1)..";]"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return buttons_string
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
local function check_color_buttons(pos, meta, chest_name, fields)
|
|
||||||
for i = 1, 16 do
|
|
||||||
if fields["color_button"..i] then
|
|
||||||
local node = minetest.get_node(pos)
|
|
||||||
node.name = chest_name..colorid_to_postfix(i)
|
|
||||||
minetest.swap_node(pos, node)
|
|
||||||
meta:set_string("color", i)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function set_formspec(pos, data, page)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local formspec = data.base_formspec
|
|
||||||
formspec = formspec..fs_helpers.cycling_button(
|
|
||||||
meta,
|
|
||||||
"image_button[0,0.35;1,0.6",
|
|
||||||
"splitstacks",
|
|
||||||
{
|
|
||||||
pipeworks.button_off,
|
|
||||||
pipeworks.button_on
|
|
||||||
}
|
|
||||||
)..allow_label
|
|
||||||
|
|
||||||
if data.autosort then
|
|
||||||
local status = meta:get_int("autosort")
|
|
||||||
formspec = formspec.."button["..(data.hileft+2)..","..(data.height+1.1)..";3,0.8;autosort_to_"..(1-status)..";"..S("Auto-sort is %s"):format(status == 1 and S("On") or S("Off")).."]"
|
|
||||||
end
|
|
||||||
if data.infotext then
|
|
||||||
local formspec_infotext = minetest.formspec_escape(meta:get_string("infotext"))
|
|
||||||
if page == "main" then
|
|
||||||
formspec = formspec.."image_button["..(shift_edit_field+data.hileft+2.1)..",0.1;0.8,0.8;"
|
|
||||||
.."technic_pencil_icon.png;edit_infotext;]"
|
|
||||||
.."label["..(shift_edit_field+data.hileft+3)..",0;"..formspec_infotext.."]"
|
|
||||||
elseif page == "edit_infotext" then
|
|
||||||
formspec = formspec.."image_button["..(shift_edit_field+data.hileft+2.1)..",0.1;0.8,0.8;"
|
|
||||||
.."technic_checkmark_icon.png;save_infotext;]"
|
|
||||||
.."field["..(shift_edit_field+data.hileft+3.3)..",0.2;4.8,1;"
|
|
||||||
.."infotext_box;"..S("Edit chest description:")..";"
|
|
||||||
..formspec_infotext.."]"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if data.color then
|
|
||||||
local colorID = meta:get_int("color")
|
|
||||||
local colorName
|
|
||||||
if chest_mark_colors[colorID] then
|
|
||||||
colorName = chest_mark_colors[colorID][2]
|
|
||||||
else
|
|
||||||
colorName = S("None")
|
|
||||||
end
|
|
||||||
formspec = formspec.."label["..(data.coleft+0.2)..","..(data.lotop+3)..";"..S("Color Filter: %s"):format(colorName).."]"
|
|
||||||
end
|
|
||||||
meta:set_string("formspec", formspec)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function sort_inventory(inv)
|
|
||||||
local inlist = inv:get_list("main")
|
|
||||||
local typecnt = {}
|
|
||||||
local typekeys = {}
|
|
||||||
for _, st in ipairs(inlist) do
|
|
||||||
if not st:is_empty() then
|
|
||||||
local n = st:get_name()
|
|
||||||
local w = st:get_wear()
|
|
||||||
local m = st:get_metadata()
|
|
||||||
local k = string.format("%s %05d %s", n, w, m)
|
|
||||||
if not typecnt[k] then
|
|
||||||
typecnt[k] = {st}
|
|
||||||
table.insert(typekeys, k)
|
|
||||||
else
|
|
||||||
table.insert(typecnt[k], st)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
table.sort(typekeys)
|
|
||||||
inv:set_list("main", {})
|
|
||||||
for _, k in ipairs(typekeys) do
|
|
||||||
for _, item in ipairs(typecnt[k]) do
|
|
||||||
inv:add_item("main", item)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function get_receive_fields(name, data, locked)
|
|
||||||
local lname = name:lower()
|
|
||||||
return function(pos, formname, fields, sender)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
|
|
||||||
if locked then
|
|
||||||
-- locked chest, check accessing player
|
|
||||||
local owner = meta:get_string("owner")
|
|
||||||
if owner ~= sender:get_player_name() then
|
|
||||||
-- non-owner, abort
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local page = "main"
|
|
||||||
|
|
||||||
local owner = meta:get_string("owner")
|
|
||||||
if owner ~= "" then
|
|
||||||
-- prevent modification of locked chests
|
|
||||||
if owner ~= sender:get_player_name() then return end
|
|
||||||
elseif not fields.quit then
|
|
||||||
-- prevent modification of protected chests
|
|
||||||
if minetest.is_protected(pos, sender:get_player_name()) then return end
|
|
||||||
end
|
|
||||||
|
|
||||||
if fields.sort or (data.autosort and fields.quit and meta:get_int("autosort") == 1) then
|
|
||||||
sort_inventory(meta:get_inventory())
|
|
||||||
end
|
|
||||||
if fields.edit_infotext then
|
|
||||||
page = "edit_infotext"
|
|
||||||
end
|
|
||||||
if fields.autosort_to_1 then meta:set_int("autosort", 1) end
|
|
||||||
if fields.autosort_to_0 then meta:set_int("autosort", 0) end
|
|
||||||
if fields.infotext_box then
|
|
||||||
meta:set_string("infotext", fields.infotext_box)
|
|
||||||
end
|
|
||||||
if data.color then
|
|
||||||
-- This sets the node
|
|
||||||
local nn = "technic:"..lname..(data.locked and "_locked" or "").."_chest"
|
|
||||||
check_color_buttons(pos, meta, nn, fields)
|
|
||||||
end
|
|
||||||
if fields["fs_helpers_cycling:0:splitstacks"]
|
|
||||||
or fields["fs_helpers_cycling:1:splitstacks"] then
|
|
||||||
if not pipeworks.may_configure(pos, sender) then return end
|
|
||||||
fs_helpers.on_receive_fields(pos, fields)
|
|
||||||
end
|
|
||||||
|
|
||||||
meta:get_inventory():set_size("main", data.width * data.height)
|
|
||||||
set_formspec(pos, data, page)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function technic.chests:definition(name, data)
|
|
||||||
local lname = name:lower()
|
local lname = name:lower()
|
||||||
name = S(name)
|
name = S(name)
|
||||||
local d = {}
|
|
||||||
for k, v in pairs(data) do d[k] = v end
|
|
||||||
data = d
|
|
||||||
|
|
||||||
data.lowidth = 8
|
|
||||||
data.ovwidth = math.max(data.lowidth, data.width)
|
|
||||||
data.hileft = (data.ovwidth - data.width) / 2
|
|
||||||
data.loleft = (data.ovwidth - data.lowidth) / 2
|
|
||||||
if data.color then
|
|
||||||
if data.lowidth + 3 <= data.ovwidth then
|
|
||||||
data.coleft = data.ovwidth - 3
|
|
||||||
if data.loleft + data.lowidth > data.coleft then
|
|
||||||
data.loleft = data.coleft - data.lowidth
|
|
||||||
end
|
|
||||||
else
|
|
||||||
data.loleft = 0
|
|
||||||
data.coleft = data.lowidth
|
|
||||||
data.ovwidth = data.lowidth + 3
|
|
||||||
end
|
|
||||||
end
|
|
||||||
data.lotop = data.height + 2
|
|
||||||
data.ovheight = data.lotop + 4
|
|
||||||
|
|
||||||
local locked_after_place = nil
|
|
||||||
local front = {"technic_"..lname.."_chest_front.png"}
|
|
||||||
data.base_formspec = "size["..data.ovwidth..","..data.ovheight.."]"..
|
|
||||||
"label[0,0;"..S("%s Chest"):format(name).."]"..
|
|
||||||
"list[context;main;"..data.hileft..",1;"..data.width..","..data.height..";]"..
|
|
||||||
"list[current_player;main;"..data.loleft..","..data.lotop..";8,4;]"..
|
|
||||||
"background[-0.19,-0.25;"..(data.ovwidth+0.4)..","..(data.ovheight+0.75)..";technic_chest_form_bg.png]"..
|
|
||||||
"background["..data.hileft..",1;"..data.width..","..data.height..";technic_"..lname.."_chest_inventory.png]"..
|
|
||||||
"background["..data.loleft..","..data.lotop..";8,4;technic_main_inventory.png]"..
|
|
||||||
"listring[]"
|
|
||||||
|
|
||||||
if data.sort then
|
|
||||||
data.base_formspec = data.base_formspec.."button["..data.hileft..","..(data.height+1.1)..";1,0.8;sort;"..S("Sort").."]"
|
|
||||||
end
|
|
||||||
if data.color then
|
|
||||||
data.base_formspec = data.base_formspec..get_color_buttons(data.coleft, data.lotop)
|
|
||||||
end
|
|
||||||
|
|
||||||
if data.locked then
|
if data.locked then
|
||||||
locked_after_place = function(pos, placer)
|
data.node_name = "technic:"..lname.."_locked_chest"
|
||||||
local meta = minetest.get_meta(pos)
|
data.description = S("%s Locked Chest"):format(name)
|
||||||
meta:set_string("owner", placer:get_player_name() or "")
|
|
||||||
meta:set_string("infotext",
|
|
||||||
S("%s Locked Chest (owned by %s)")
|
|
||||||
:format(name, meta:get_string("owner")))
|
|
||||||
pipeworks.after_place(pos)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
locked_after_place = pipeworks.after_place
|
|
||||||
end
|
|
||||||
|
|
||||||
if data.locked then
|
|
||||||
table.insert(front, "technic_"..lname.."_chest_lock_overlay.png")
|
|
||||||
end
|
|
||||||
|
|
||||||
if data.protected and has_protector_mod then
|
|
||||||
-- use overlay from protector mod
|
|
||||||
table.insert(front, "protector_logo.png")
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
local desc
|
|
||||||
if data.locked then
|
|
||||||
desc = S("%s Locked Chest"):format(name)
|
|
||||||
elseif data.protected then
|
elseif data.protected then
|
||||||
desc = S("%s Protected Chest"):format(name)
|
data.node_name = "technic:"..lname.."_protected_chest"
|
||||||
|
data.description = S("%s Protected Chest"):format(name)
|
||||||
else
|
else
|
||||||
desc = S("%s Chest"):format(name)
|
data.node_name = "technic:"..lname.."_chest"
|
||||||
end
|
data.description = S("%s Chest"):format(name)
|
||||||
|
|
||||||
local tentry = tube_entry
|
|
||||||
if tube_entry ~= "" then
|
|
||||||
if lname == "wooden" then
|
|
||||||
tentry = "^pipeworks_tube_connection_wooden.png"
|
|
||||||
elseif lname == "mithril" then
|
|
||||||
tentry = "^pipeworks_tube_connection_stony.png"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
data.formspec = technic.chests.get_formspec(data)
|
||||||
local def = {
|
local def = {
|
||||||
description = desc,
|
description = data.description,
|
||||||
tiles = {
|
tiles = get_tiles(lname, data),
|
||||||
"technic_"..lname.."_chest_top.png"..tentry,
|
|
||||||
"technic_"..lname.."_chest_top.png"..tentry,
|
|
||||||
"technic_"..lname.."_chest_side.png"..tentry,
|
|
||||||
"technic_"..lname.."_chest_side.png"..tentry,
|
|
||||||
"technic_"..lname.."_chest_side.png"..tentry,
|
|
||||||
table.concat(front, "^")
|
|
||||||
},
|
|
||||||
paramtype2 = "facedir",
|
paramtype2 = "facedir",
|
||||||
groups = self.groups,
|
|
||||||
tube = self.tube,
|
|
||||||
legacy_facedir_simple = true,
|
legacy_facedir_simple = true,
|
||||||
|
groups = node_groups,
|
||||||
sounds = default.node_sound_wood_defaults(),
|
sounds = default.node_sound_wood_defaults(),
|
||||||
after_place_node = locked_after_place,
|
drop = data.node_name,
|
||||||
after_dig_node = pipeworks.after_dig,
|
after_place_node = function(pos, placer)
|
||||||
|
|
||||||
on_construct = function(pos)
|
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
meta:set_string("infotext", S("%s Chest"):format(name))
|
if data.locked then
|
||||||
set_formspec(pos, data, "main")
|
local owner = placer:get_player_name() or ""
|
||||||
local inv = meta:get_inventory()
|
meta:set_string("owner", owner)
|
||||||
inv:set_size("main", data.width * data.height)
|
meta:set_string("infotext", S("%s Locked Chest (owned by %s)"):format(name, owner))
|
||||||
|
else
|
||||||
|
meta:set_string("infotext", data.description)
|
||||||
|
end
|
||||||
|
if has_pipeworks then
|
||||||
|
pipeworks.after_place(pos)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
after_dig_node = function(pos)
|
||||||
|
if has_pipeworks then
|
||||||
|
pipeworks.after_dig(pos)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
tube = {
|
||||||
|
insert_object = function(pos, node, stack)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
if data.digilines and has_digilines and meta:get_int("send_inject") then
|
||||||
|
technic.chests.send_digiline_message(pos, "inject", nil, {stack:to_table()})
|
||||||
|
end
|
||||||
|
technic.chests.log_inv_change(pos, "pipeworks tube", "put", stack:get_name())
|
||||||
|
return meta:get_inventory():add_item("main", stack)
|
||||||
|
end,
|
||||||
|
can_insert = function(pos, node, stack)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
if meta:get_int("splitstacks") == 1 then
|
||||||
|
stack = stack:peek_item(1)
|
||||||
|
end
|
||||||
|
local can_insert = meta:get_inventory():room_for_item("main", stack)
|
||||||
|
if not can_insert and data.digilines and has_digilines and meta:get_int("send_overflow") then
|
||||||
|
technic.chests.send_digiline_message(pos, "overflow", nil, {stack:to_table()})
|
||||||
|
end
|
||||||
|
return can_insert
|
||||||
|
end,
|
||||||
|
remove_items = function(pos, node, stack)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
local removed = meta:get_inventory():remove_item("main", stack)
|
||||||
|
if data.digilines and has_digilines and meta:get_int("send_pull") then
|
||||||
|
technic.chests.send_digiline_message(pos, "pull", nil, {removed:to_table()})
|
||||||
|
end
|
||||||
|
technic.chests.log_inv_change(pos, "pipeworks tube", "take", stack:get_name())
|
||||||
|
return removed
|
||||||
|
end,
|
||||||
|
input_inventory = "main",
|
||||||
|
connect_sides = {left=1, right=1, front=1, back=1, top=1, bottom=1},
|
||||||
|
},
|
||||||
|
on_construct = function(pos)
|
||||||
|
local inv = minetest.get_meta(pos):get_inventory()
|
||||||
|
inv:set_size("main", data.width * data.height)
|
||||||
|
if data.quickmove then
|
||||||
|
inv:set_size("quickmove", 1)
|
||||||
|
end
|
||||||
|
technic.chests.update_formspec(pos, data)
|
||||||
|
end,
|
||||||
|
can_dig = function(pos, player)
|
||||||
|
if not technic.chests.change_allowed(pos, player, data.locked, data.protected) then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
return minetest.get_meta(pos):get_inventory():is_empty("main")
|
||||||
|
end,
|
||||||
|
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
|
||||||
|
if not technic.chests.change_allowed(pos, player, data.locked, data.protected) then
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
if data.quickmove and to_list == "quickmove" then
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
local inv = meta:get_inventory()
|
||||||
|
local stack = inv:get_stack("main", from_index)
|
||||||
|
local moved_items = technic.chests.move_inv(inv, player:get_inventory(), stack:get_name())
|
||||||
|
if data.digilines and has_digilines and meta:get_int("send_take") == 1 then
|
||||||
|
technic.chests.send_digiline_message(pos, "take", player, moved_items)
|
||||||
|
end
|
||||||
|
technic.chests.log_inv_change(pos, player:get_player_name(), "take", "stuff")
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
return count
|
||||||
|
end,
|
||||||
|
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||||||
|
if not technic.chests.change_allowed(pos, player, data.locked, data.protected) then
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
if data.quickmove and listname == "quickmove" then
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
local inv = meta:get_inventory()
|
||||||
|
local moved_items = technic.chests.move_inv(player:get_inventory(), inv, stack:get_name())
|
||||||
|
if data.digilines and has_digilines and meta:get_int("send_put") == 1 then
|
||||||
|
technic.chests.send_digiline_message(pos, "put", player, moved_items)
|
||||||
|
end
|
||||||
|
technic.chests.log_inv_change(pos, player:get_player_name(), "put", "stuff")
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
return stack:get_count()
|
||||||
|
end,
|
||||||
|
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
|
||||||
|
if not technic.chests.change_allowed(pos, player, data.locked, data.protected) then
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
return stack:get_count()
|
||||||
|
end,
|
||||||
|
on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
|
||||||
|
technic.chests.log_inv_change(pos, player:get_player_name(), "move", "stuff")
|
||||||
|
end,
|
||||||
|
on_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||||||
|
if data.digilines and has_digilines and minetest.get_meta(pos):get_int("send_put") == 1 then
|
||||||
|
technic.chests.send_digiline_message(pos, "put", player, {stack:to_table()})
|
||||||
|
end
|
||||||
|
technic.chests.log_inv_change(pos, player:get_player_name(), "put", stack:get_name())
|
||||||
|
end,
|
||||||
|
on_metadata_inventory_take = function(pos, listname, index, stack, player)
|
||||||
|
if data.digilines and has_digilines and minetest.get_meta(pos):get_int("send_take") == 1 then
|
||||||
|
technic.chests.send_digiline_message(pos, "take", player, {stack:to_table()})
|
||||||
|
end
|
||||||
|
technic.chests.log_inv_change(pos, player:get_player_name(), "take", stack:get_name())
|
||||||
end,
|
end,
|
||||||
can_dig = self.can_dig,
|
|
||||||
on_receive_fields = get_receive_fields(name, data, data.locked),
|
|
||||||
on_metadata_inventory_move = self.on_inv_move,
|
|
||||||
on_metadata_inventory_put = self.on_inv_put,
|
|
||||||
on_metadata_inventory_take = self.on_inv_take,
|
|
||||||
on_blast = function(pos)
|
on_blast = function(pos)
|
||||||
|
if data.locked or data.protected then
|
||||||
|
return
|
||||||
|
end
|
||||||
local drops = {}
|
local drops = {}
|
||||||
default.get_inventory_drops(pos, "main", drops)
|
default.get_inventory_drops(pos, "main", drops)
|
||||||
drops[#drops+1] = "technic:"..name:lower()..(data.locked and "_locked" or "").."_chest"
|
drops[#drops+1] = data.node_name
|
||||||
minetest.remove_node(pos)
|
minetest.remove_node(pos)
|
||||||
return drops
|
return drops
|
||||||
end,
|
end,
|
||||||
|
on_receive_fields = technic.chests.get_receive_fields(data),
|
||||||
}
|
}
|
||||||
if data.locked then
|
if data.locked then
|
||||||
def.allow_metadata_inventory_move = self.inv_move
|
|
||||||
def.allow_metadata_inventory_put = self.inv_put
|
|
||||||
def.allow_metadata_inventory_take = self.inv_take
|
|
||||||
def.on_blast = function() end
|
|
||||||
def.can_dig = function(pos,player)
|
|
||||||
local meta = minetest.get_meta(pos);
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
return inv:is_empty("main") and player and player:is_player() and default.can_interact_with_node(player, pos)
|
|
||||||
end
|
|
||||||
def.on_skeleton_key_use = function(pos, player, newsecret)
|
def.on_skeleton_key_use = function(pos, player, newsecret)
|
||||||
|
-- Copied from default chests.lua
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
local owner = meta:get_string("owner")
|
local owner = meta:get_string("owner")
|
||||||
local name = player:get_player_name()
|
local player_name = player:get_player_name()
|
||||||
|
|
||||||
-- verify placer is owner of lockable chest
|
|
||||||
if owner ~= name then
|
if owner ~= name then
|
||||||
minetest.record_protection_violation(pos, name)
|
minetest.record_protection_violation(pos, player_name)
|
||||||
minetest.chat_send_player(name, "You do not own this chest.")
|
minetest.chat_send_player(player_name, "You do not own this chest.")
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
local secret = meta:get_string("key_lock_secret")
|
local secret = meta:get_string("key_lock_secret")
|
||||||
if secret == "" then
|
if secret == "" then
|
||||||
secret = newsecret
|
secret = newsecret
|
||||||
meta:set_string("key_lock_secret", secret)
|
meta:set_string("key_lock_secret", secret)
|
||||||
end
|
end
|
||||||
|
|
||||||
return secret, "a locked chest", owner
|
return secret, "a locked chest", owner
|
||||||
end
|
end
|
||||||
elseif data.protected then
|
|
||||||
def.allow_metadata_inventory_move = self.inv_move_protected
|
|
||||||
def.allow_metadata_inventory_put = self.inv_put_protected
|
|
||||||
def.allow_metadata_inventory_take = self.inv_take_protected
|
|
||||||
def.on_blast = function() end
|
|
||||||
def.can_dig = function(pos,player)
|
|
||||||
local meta = minetest.get_meta(pos);
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
return inv:is_empty("main") and not minetest.is_protected(pos, player:get_player_name())
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
return def
|
if data.digilines and has_digilines then
|
||||||
end
|
def.digiline = {
|
||||||
|
receptor = {},
|
||||||
local _TUBELIB_CALLBACKS = {
|
effector = {
|
||||||
on_pull_item = function(pos, side, player_name)
|
action = technic.chests.digiline_effector
|
||||||
if not minetest.is_protected(pos, player_name) then
|
},
|
||||||
local inv = minetest.get_meta(pos):get_inventory()
|
}
|
||||||
for _, stack in pairs(inv:get_list("main")) do
|
|
||||||
if not stack:is_empty() then
|
|
||||||
return inv:remove_item("main", stack:get_name())
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return nil
|
|
||||||
end,
|
|
||||||
on_push_item = function(pos, side, item, player_name)
|
|
||||||
local inv = minetest.get_meta(pos):get_inventory()
|
|
||||||
if inv:room_for_item("main", item) then
|
|
||||||
inv:add_item("main", item)
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end,
|
|
||||||
on_unpull_item = function(pos, side, item, player_name)
|
|
||||||
local inv = minetest.get_meta(pos):get_inventory()
|
|
||||||
if inv:room_for_item("main", item) then
|
|
||||||
inv:add_item("main", item)
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
function technic.chests:register(name, data)
|
|
||||||
local def = technic.chests:definition(name, data)
|
|
||||||
|
|
||||||
-- prefix
|
|
||||||
local nn = "technic:"..name:lower()
|
|
||||||
|
|
||||||
if data.locked then
|
|
||||||
-- locked chest
|
|
||||||
nn = nn .. "_locked"
|
|
||||||
|
|
||||||
elseif data.protected then
|
|
||||||
-- protected chest
|
|
||||||
nn = nn .. "_protected"
|
|
||||||
end
|
end
|
||||||
|
minetest.register_node(":"..data.node_name, def)
|
||||||
-- suffix
|
|
||||||
nn = nn .. "_chest"
|
|
||||||
|
|
||||||
minetest.register_node(":"..nn, def)
|
|
||||||
|
|
||||||
if tubelib_exists then
|
|
||||||
tubelib.register_node(nn, {}, _TUBELIB_CALLBACKS)
|
|
||||||
end
|
|
||||||
|
|
||||||
if data.color then
|
if data.color then
|
||||||
local mk_front
|
|
||||||
if string.find(def.tiles[6], "%^") then
|
|
||||||
mk_front = function (overlay) return def.tiles[6]:gsub("%^", "^"..overlay.."^") end
|
|
||||||
else
|
|
||||||
mk_front = function (overlay) return def.tiles[6].."^"..overlay end
|
|
||||||
end
|
|
||||||
for i = 1, 15 do
|
for i = 1, 15 do
|
||||||
local postfix = colorid_to_postfix(i)
|
|
||||||
local colordef = {}
|
local colordef = {}
|
||||||
for k, v in pairs(def) do
|
for k, v in pairs(def) do
|
||||||
colordef[k] = v
|
colordef[k] = v
|
||||||
end
|
end
|
||||||
colordef.drop = nn
|
colordef.groups = node_groups_no_inv
|
||||||
colordef.groups = self.groups_noinv
|
colordef.tiles = get_tiles(lname, data, i)
|
||||||
colordef.tiles = { def.tiles[1], def.tiles[2], def.tiles[3], def.tiles[4], def.tiles[5], mk_front("technic_chest_overlay"..postfix..".png") }
|
minetest.register_node(":"..data.node_name.."_"..technic.chests.colors[i][1], colordef)
|
||||||
minetest.register_node(":"..nn..postfix, colordef)
|
|
||||||
if tubelib_exists then
|
|
||||||
tubelib.register_node(nn..postfix, {}, _TUBELIB_CALLBACKS)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,48 +0,0 @@
|
|||||||
if minetest.get_modpath("moreores") then
|
|
||||||
minetest.register_craft({
|
|
||||||
output = 'technic:silver_chest',
|
|
||||||
recipe = {
|
|
||||||
{'moreores:silver_ingot','moreores:silver_ingot','moreores:silver_ingot'},
|
|
||||||
{'moreores:silver_ingot','technic:copper_chest','moreores:silver_ingot'},
|
|
||||||
{'moreores:silver_ingot','moreores:silver_ingot','moreores:silver_ingot'},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = 'technic:silver_locked_chest',
|
|
||||||
recipe = {
|
|
||||||
{'moreores:silver_ingot','moreores:silver_ingot','moreores:silver_ingot'},
|
|
||||||
{'moreores:silver_ingot','technic:copper_locked_chest','moreores:silver_ingot'},
|
|
||||||
{'moreores:silver_ingot','moreores:silver_ingot','moreores:silver_ingot'},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = 'technic:silver_locked_chest',
|
|
||||||
type = "shapeless",
|
|
||||||
recipe = {
|
|
||||||
'basic_materials:padlock',
|
|
||||||
'technic:silver_chest',
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
technic.chests:register("Silver", {
|
|
||||||
width = 12,
|
|
||||||
height = 6,
|
|
||||||
sort = true,
|
|
||||||
autosort = true,
|
|
||||||
infotext = true,
|
|
||||||
color = false,
|
|
||||||
locked = false,
|
|
||||||
})
|
|
||||||
|
|
||||||
technic.chests:register("Silver", {
|
|
||||||
width = 12,
|
|
||||||
height = 6,
|
|
||||||
sort = true,
|
|
||||||
autosort = true,
|
|
||||||
infotext = true,
|
|
||||||
color = false,
|
|
||||||
locked = true,
|
|
||||||
})
|
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 234 B After Width: | Height: | Size: 132 B |
Before Width: | Height: | Size: 234 B After Width: | Height: | Size: 132 B |
Before Width: | Height: | Size: 234 B After Width: | Height: | Size: 132 B |
Before Width: | Height: | Size: 234 B After Width: | Height: | Size: 132 B |
Before Width: | Height: | Size: 234 B After Width: | Height: | Size: 132 B |
Before Width: | Height: | Size: 234 B After Width: | Height: | Size: 132 B |
Before Width: | Height: | Size: 234 B After Width: | Height: | Size: 132 B |
Before Width: | Height: | Size: 234 B After Width: | Height: | Size: 132 B |
Before Width: | Height: | Size: 234 B After Width: | Height: | Size: 132 B |
Before Width: | Height: | Size: 234 B After Width: | Height: | Size: 132 B |
Before Width: | Height: | Size: 234 B After Width: | Height: | Size: 132 B |
Before Width: | Height: | Size: 234 B After Width: | Height: | Size: 132 B |
Before Width: | Height: | Size: 234 B After Width: | Height: | Size: 132 B |
Before Width: | Height: | Size: 234 B After Width: | Height: | Size: 132 B |
Before Width: | Height: | Size: 234 B After Width: | Height: | Size: 132 B |
Before Width: | Height: | Size: 105 B After Width: | Height: | Size: 120 B |
Before Width: | Height: | Size: 105 B After Width: | Height: | Size: 120 B |
Before Width: | Height: | Size: 105 B After Width: | Height: | Size: 120 B |
Before Width: | Height: | Size: 105 B After Width: | Height: | Size: 120 B |
Before Width: | Height: | Size: 105 B After Width: | Height: | Size: 120 B |
Before Width: | Height: | Size: 105 B After Width: | Height: | Size: 120 B |
Before Width: | Height: | Size: 105 B After Width: | Height: | Size: 120 B |
Before Width: | Height: | Size: 105 B After Width: | Height: | Size: 120 B |
Before Width: | Height: | Size: 89 B After Width: | Height: | Size: 120 B |
Before Width: | Height: | Size: 105 B After Width: | Height: | Size: 120 B |
Before Width: | Height: | Size: 105 B After Width: | Height: | Size: 120 B |
Before Width: | Height: | Size: 105 B After Width: | Height: | Size: 120 B |
Before Width: | Height: | Size: 105 B After Width: | Height: | Size: 120 B |
Before Width: | Height: | Size: 105 B After Width: | Height: | Size: 120 B |
Before Width: | Height: | Size: 105 B After Width: | Height: | Size: 120 B |
BIN
technic_chests/textures/technic_protector_overlay.png
Normal file
After Width: | Height: | Size: 138 B |