local doors = {} function artifact.rotate_selectionbox(box, rot) local a = vector.new(box[1], box[2], box[3]):rotate(rot) local b = vector.new(box[4], box[5], box[6]):rotate(rot) return { a.x, a.y, a.z, b.x, b.y, b.z } end minetest.register_entity(":artifact:door", { initial_properties = { visual = "mesh", mesh = "artifact_door.gltf", textures = {"artifact_door_wood.png"}, selectionbox = { -0.5, -0.5, -0.5, 0.5, 1.5, -6/16 } }, _interact_time = 0.2, _interact_marker_offset = function(e) return (e._open and vector.new(-0.5, 0.5, 0) or vector.new(0, 0.5, 0.5)):rotate(e.object:get_rotation()) end, on_activate = function(e, data) if not minetest.get_node(e.object:get_pos()).name:find "door" then e.object:remove() return end e.object:set_armor_groups{immortal = 1} extend(e, minetest.deserialize(data) or {}) if e.type == "iron" and e._locked == nil then e._locked = true e.object:set_properties { textures = {"artifact_door_iron.png"}, } end if e.rotation then e.rotation.y = e.rotation.y +math.pi e:rotate(e.rotation) end if e._locked then e._no_interact = true end e._name = ""..math.random() doors[e.object:get_pos():round():to_string()] = e end, on_deactivate = function(e) doors[e.object:get_pos():round():to_string()] = nil end, on_interact = function(e) if e._open then e._open = nil e._no_interact = true e._name = ""..math.random() e.object:set_animation({x=0.5,y=1}, 1.5, 0.1, false) minetest.after(0.1, function() local pos = e.object:get_pos():round() local node = minetest.get_node(pos) node.name = "door_"..e.type minetest.swap_node(pos, node) e.object:set_properties { selectionbox = artifact.rotate_selectionbox({ -0.5, -0.5, -0.5, 0.5, 1.5, -6/16 }, e.rotation) } end) minetest.after(0.25, function() e._no_interact = nil end) else e._open = true e._no_interact = true e._name = ""..math.random() e.object:set_animation({x=0,y=0.5}, 1.5, 0.1, false) minetest.after(0.1, function() local pos = e.object:get_pos():round() local node = minetest.get_node(pos) node.name = "door_"..e.type.."_open" minetest.swap_node(pos, node) e.object:set_properties { selectionbox = artifact.rotate_selectionbox({ 0.5, -0.5, -0.5, 6/16, 1.5, 0.5 }, e.rotation) } end) minetest.after(0.25, function() e._no_interact = nil end) end end, get_staticdata = function(e) return minetest.serialize{type = e.type, _locked = e._locked, rotation = e.rotation} end, unlock = function(e) if e._locked then e._locked = false e._no_interact = nil end end, rotate = function(e, rot) e.object:set_rotation(rot) rot.y = rot.y -math.pi e.rotation = rot e.object:set_properties { selectionbox = artifact.rotate_selectionbox(e.object:get_properties().selectionbox, e.rotation) } end }) local function register_basic_door(type) artifact.register_node("door_"..type, { drawtype = "nodebox", node_box = { type = "fixed", fixed = { -0.5, -0.5, -0.5, 0.5, 1.5, -6/16 } }, paramtype2 = "facedir", tiles = {"blank.png"}, use_texture_alpha = "clip", paramtype = "light", pointable = false, groups = {call_on_load = 1, whackable = type == "wood" and 1 or nil}, 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:door", minetest.serialize{type = type}):get_luaentity():rotate(rot) end, on_destruct = function(pos, reason) if reason == "whack" then -- TODO: Particles end doors[pos:to_string()].object:remove() doors[pos:to_string()] = nil end, on_load = function(pos) local m = minetest.get_meta(pos) -- Dynamically initialize doors 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:door", minetest.serialize{type = type}):get_luaentity():rotate(rot) end end }) artifact.register_node("door_"..type.."_open", { drawtype = "nodebox", node_box = { type = "fixed", fixed = { 0.5, -0.5, -0.5, 6/16, 1.5, 0.5 } }, paramtype2 = "facedir", tiles = {"blank.png"}, use_texture_alpha = "clip", paramtype = "light", pointable = false, groups = {call_on_load = 1, whackable = type == "wood" and 1 or nil}, 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:door", minetest.serialize{type = type}):get_luaentity():rotate(rot) end, on_destruct = function(pos) doors[pos:to_string()].object:remove() doors[pos:to_string()] = nil end, on_load = function(pos) local m = minetest.get_meta(pos) -- Dynamically initialize doors 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:door", minetest.serialize{type = type}):get_luaentity():rotate(rot) end end }) end register_basic_door("wood") register_basic_door("iron")