local ns = artifact local chests = {} minetest.register_entity(":artifact:chest_slot", { initial_properties = { static_save = false, visual = "mesh", mesh = "artifact_animator.gltf", selectionbox = {-0.2, -0.2, -0.2, 0.2, 0.2, 0.2} }, _interact_time = 0.25, on_activate = function(e, item) e._visual = minetest.add_entity(e.object:get_pos(), "display") e._visual:set_properties { visual = "item", wield_item = item, pointable = false } e._visual:set_attach(e.object, "root") -- That's _one_ way to get a unique ID... e._name = ""..math.random() end, on_deactivate = function(e) e._visual:remove() end, on_hover = function(e, m) e.object:set_bone_override("root", { scale = { vec = vector.new(0.15, 0.15, 0.15), interpolation = 0.2, absolute = true }, position = { vec = vector.new(0, 0.01, 0), interpolation = 0.2, absolute = true } }) end, on_unhover = function(e, m) e.object:set_bone_override("root", { scale = { vec = vector.new(0.1, 0.1, 0.1), interpolation = 0.2, absolute = true }, position = { vec = vector.new(0, 0.01, 0), interpolation = 0.2, absolute = true } }) end }) minetest.register_entity(":artifact:chest_display", { initial_properties = { visual = "mesh", mesh = "artifact_chest.gltf", textures = {"artifact_chest_wood.png"}, }, _interact_time = 0.6, _interact_marker_offset = function(e) return vector.new(0, 0, 0.5):rotate(e.object:get_rotation()) end, 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) chests[vector.to_string(e._pos)] = e end, on_deactivate = function(e) chests[vector.to_string(e._pos)] = nil end, get_staticdata = function(e) return minetest.serialize(e._pos) end, on_interact = function(e) e:open() end, on_step = function(e) if e._open then local found = false for obj in minetest.objects_inside_radius(e.object:get_pos(), 5) do if minetest.is_player(obj) then found = true break end end if not found then e:close() end end end, open = function(e) e._open = true e._no_interact = true e.object:set_properties{pointable = false} e.object:set_animation({x=0,y=0.5}, 1, 0.1, false) local pos = e.object:get_pos() local rot = e.object:get_rotation() e._slot_main = minetest.add_entity(pos +vector.new(0.2, 0.1, 0):rotate(rot), "artifact:chest_slot", "artifact:stone"):get_luaentity() e._slot_main.object:set_bone_override("root", { scale = { vec = vector.new(0.01, 0.01, 0.01), absolute = true }, position = { vec = vector.new(0, -5, 0), absolute = true } }) minetest.after(0, function() e._slot_main.object:set_bone_override("root", { scale = { vec = vector.new(0.1, 0.1, 0.1), interpolation = 0.4, absolute = true }, position = { vec = vector.new(0, 0.01, 0), interpolation = 0.4, absolute = true } }) end) e._slot_main.master = e e._slot_main.on_interact = function() end e._slot_cancel = minetest.add_entity(pos +vector.new(-0.2, 0.1, 0):rotate(rot), "artifact:chest_slot", "artifact:cancel"):get_luaentity() e._slot_cancel.object:set_bone_override("root", { scale = { vec = vector.new(0.01, 0.01, 0.01), absolute = true }, position = { vec = vector.new(0, -5, 0), absolute = true } }) minetest.after(0, function() e._slot_cancel.object:set_bone_override("root", { scale = { vec = vector.new(0.1, 0.1, 0.1), interpolation = 0.4, absolute = true }, position = { vec = vector.new(0, 0.01, 0), interpolation = 0.4, absolute = true } }) end) e._slot_cancel.master = e e._slot_cancel.on_interact = function() e:close() end end, close = function(e) e._open = false e._no_interact = nil e.object:set_properties{pointable = true} e.object:set_animation({x=0.5,y=1}, 1, 0.1, false) e._slot_main.object:remove() e._slot_cancel.object:remove() end }) artifact.register_node("chest", { drawtype = "airlike", paramtype = "light", paramtype2 = "facedir", pointable = false, groups = {call_on_load = 1}, on_construct = function(pos) local m = minetest.get_meta(pos) m:set_string("initialized", "true") local rot = minetest.facedir_to_dir(minetest.get_node(pos).param2):dir_to_rotation() rot.y = rot.y -math.pi minetest.add_entity(pos, "artifact:chest_display", minetest.serialize(pos)):set_rotation(rot) end, on_destruct = function(pos) chests[pos:to_string()].object:remove() chests[pos:to_string()] = nil end, on_load = function(pos) local m = minetest.get_meta(pos) -- Dynamically initialize chests that were mapgen'd in. if not m:contains("initialized") then m:set_string("initialized", "true") local rot = minetest.facedir_to_dir(minetest.get_node(pos).param2):dir_to_rotation() rot.y = rot.y -math.pi minetest.add_entity(pos, "artifact:chest_display", minetest.serialize(pos)):set_rotation(rot) end end })