local rgt_chests = { chests = {} } local ns = rgt_chests minetest.register_entity(":red_glazed_terracotta:chest_display", { initial_properties = { visual = "mesh", mesh = "rgt_chest.gltf", textures = {"rgt_chest.png"}, pointable = false, -- static_save = false }, on_activate = function(e, data) if not minetest.get_node(e.object:get_pos()).name:find "chest" then e.object:remove() return end e.object:set_armor_groups{immortal = 1} e._pos = minetest.deserialize(data) ns.chests[vector.to_string(e._pos)] = e e.users = {} e.object:set_animation({x=0,y=0}, 1, 0.1, false) end, on_deactivate = function(e) ns.chests[vector.to_string(e._pos)] = nil e.object:set_animation({x=0,y=0}, 1, 0.1, false) end, get_staticdata = function(e) return minetest.serialize(e._pos) end }) local function make_chest_entity(pos, rot) local e = minetest.add_entity(pos, "red_glazed_terracotta:chest_display", minetest.serialize(pos)) e:set_rotation(rot) return e end -- This node is a hack to allow for a pretty wielditem while having an airlike drawtype on the actual underlying node. rgt.register_node("chest", { drawtype = "mesh", paramtype = "light", sunlight_propagates = true, paramtype2 = "4dir", mesh = "rgt_chest.gltf", tiles = {"rgt_chest.png"}, on_construct = function(pos) local node = minetest.get_node(pos) node.name = "real_chest" minetest.set_node(pos, node) end }) rgt.register_node("real_chest", { drawtype = "airlike", paramtype = "light", sunlight_propagates = true, paramtype2 = "4dir", selection_box = { type = "fixed", fixed = { -7/16, -0.5, -7/16, 7/16, 6/16, 7/16 } }, groups = { dig_immediate = 3, }, drop = "chest", on_construct = function(pos) make_chest_entity(pos, minetest.fourdir_to_dir(minetest.get_node(pos).param2):dir_to_rotation()) local m = minetest.get_meta(pos) local inv = m:get_inventory() inv:set_size("inv", 8*3) local fs = {"\ formspec_version[10]\ size[12,11]\ style_type[button,image_button;border=false]\ "} for x = 0, 7 do for y = 0, 2 do fs[#fs +1] = "\ image["..(x *1.25 +1.125 -0.0625)..","..(y *1.25 +1 -0.0625)..";1.14,1.14;rgt_other_button_bg.png;8,8]\ " end end for x = 0, 7 do for y = 0, 3 do fs[#fs +1] = "\ image["..(x *1.25 +1.125 -0.0625)..","..(y *1.25 +5.5 -0.0625)..";1.14,1.14;rgt_other_button_bg.png;8,8]\ " end end fs[#fs +1] = "\ list[context;inv;1.125,1;8,3;]\ list[current_player;main;1.125,5.5;8,4;]\ listring[]\ " m:set_string("formspec", table.concat(fs)) end, on_destruct = function(pos) local e = ns.chests[pos:to_string()] local m = minetest.get_meta(pos) local inv = m:get_inventory() for i = 1, inv:get_size("inv") do local item = minetest.add_item(pos, inv:get_stack("inv", i)) if item then item:set_velocity(vector.random_direction() *math.random(2, 3)) end end e.object:remove() end, on_rightclick = function(pos, node, p, s, pt) local e = ns.chests[pos:to_string()] if not e.open then e.open = true e.object:set_animation({x=0,y=0.5}, 1, 0.1, false) end e.users[p:get_player_name()] = true end, on_receive_fields = function(pos, _, data, p) local e = ns.chests[pos:to_string()] if data.quit then e.users[p:get_player_name()] = nil if not next(e.users) then e.open = false e.object:set_animation({x=0.5,y=1}, 1, 0.1, false) end end end })