-- Custom door implementation because I don't want to depend on other mods for content. -- Registers only 2 nodes per door. Relies on front and back faces being identical. Locked doors implemented via param2. local function can_interact(pos, player) local meta = minetest.get_meta(pos) local owner = meta:get_string("owner") -- Not locked, is owner, or has valid key return owner == "" or player:get_player_name() == owner or meta:get_string("secret") == player:get_wielded_item():get_meta():get_string("secret") end local function toggle_door(pos) local node = minetest.get_node(pos) local meta = minetest.get_meta(pos) local door, flip = node.name:match("^(.+_)(%w)$") local yaw = minetest.dir_to_yaw(minetest.facedir_to_dir(node.param2)) local rot = minetest.dir_to_facedir(minetest.yaw_to_dir(yaw + math.rad(flip == "a" and -90 or 90))) minetest.set_node({x = pos.x, y = pos.y + 1, z = pos.z}, {name = "greek:door_blank", param2 = rot}) minetest.swap_node(pos, {name = door .. (flip == "a" and "b" or "a"), param2 = rot + (meta:get_string("owner") ~= "" and 128 or 0)}) local state = (meta:get_int("state") + 1) % 2 meta:set_int("state", state) if minetest.get_modpath("doors") then minetest.sound_play("doors_door_" .. ({"close", "open"})[state + 1], {pos = pos}, true) end end minetest.register_node("greek:door_blank", { drawtype = "airlike", paramtype = "light", sunlight_propagates = true, paramtype2 = "facedir", walkable = true, pointable = false, diggable = false, buildable_to = false, floodable = false, drop = "", groups = {not_in_creative_inventory = 1}, collision_box = { type = "fixed", fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, -6 / 16}, }, }) local door_count = 4 for i = 1, door_count do local def = { description = "Blue Door " .. i, drawtype = "mesh", mesh = "greek_door.obj", tiles = {{name = "greek_door_" .. i .. ".png", backface_culling = true, color = "white"}}, overlay_tiles = {"greek_door_handle.png"}, paramtype = "light", sunlight_propagates = true, paramtype2 = "colorfacedir", palette = "greek_door_palette.png", selection_box = { type = "fixed", fixed = {-0.5, -0.5, -0.5, 0.5, 1.5, -6 / 16}, }, collision_box = { type = "fixed", fixed = {-0.5, -0.5, -0.5, 0.5, 1.5, -6 / 16}, }, groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2, door = 1}, on_rightclick = function(pos, _, clicker) if can_interact(pos, clicker) then toggle_door(pos) end end, on_key_use = function(pos, player) if can_interact(pos, player) then toggle_door(pos) end end, on_skeleton_key_use = function(pos, player, newsecret) local meta = minetest.get_meta(pos) local name = player:get_player_name() local owner = meta:get_string("owner") if owner ~= name then if owner ~= "" then minetest.chat_send_player(name, "You do not own this door.") end return end local secret = meta:get_string("secret") secret = secret ~= "" and secret or newsecret meta:set_string("secret", secret) return secret end, on_punch = function(pos, node, puncher, pointed) -- Allow binding a key to multiple doors local stack = puncher:get_wielded_item() print(stack:get_name()) if minetest.get_item_group(stack:get_name(), "key") == 1 then local meta = minetest.get_meta(pos) local name = puncher:get_player_name() if meta:get_string("owner") == name then local current = meta:get_string("secret") local new = stack:get_meta():get_string("secret") if current == "" then meta:set_string("secret", new) elseif current ~= new then minetest.chat_send_player(name, "This door has already been bound to a key.") end end end minetest.node_punch(pos, node, puncher, pointed) end, on_rotate = function() return false end, on_dig = function(pos, node, digger) minetest.remove_node({x = pos.x, y = pos.y + 1, z = pos.z}) minetest.set_node({x = pos.x, y = pos.y + 1, z = pos.z}, {name = "air"}) return minetest.node_dig(pos, node, digger) end, on_blast = function(pos) if minetest.get_meta(pos):get_string("owner") ~= "" then return end local name = minetest.get_node(pos).name minetest.remove_node(pos) minetest.remove_node({x = pos.x, y = pos.y + 1, z = pos.z}) return {name} end, } do -- Register normal version local defcopy = table.copy(def) -- Check for obstructions and place invisible node defcopy.on_place = function(itemstack, placer, pointed) local pos if pointed.type ~= "node" then return itemstack end local node = minetest.get_node(pointed.under) local pdef = minetest.registered_nodes[node.name] if pdef and pdef.on_rightclick and not placer:get_player_control().sneak then return pdef.on_rightclick(pointed.under, node, placer, itemstack, pointed) end if pdef and pdef.buildable_to then pos = pointed.under else pos = pointed.above node = minetest.get_node(pos) pdef = minetest.registered_nodes[node.name] if not pdef or not pdef.buildable_to then return itemstack end end local above = {x = pos.x, y = pos.y + 1, z = pos.z} local top_node = minetest.get_node_or_nil(above) local topdef = top_node and minetest.registered_nodes[top_node.name] if not topdef or not topdef.buildable_to then return itemstack end local pn = placer and placer:get_player_name() or "" if minetest.is_protected(pos, pn) or minetest.is_protected(above, pn) then return itemstack end return minetest.item_place_node(itemstack, placer, pointed) end -- Set metadata and rotate door defcopy.after_place_node = function(pos, placer) local node = minetest.get_node(pos) local meta = minetest.get_meta(pos) -- Check if door is locked if math.floor(node.param2 / 32) >= 4 then local name = placer:get_player_name() meta:set_string("owner", name) meta:set_string("infotext", "Blue Door\nOwned by " .. name) end meta:set_int("state", 0) local dir = node.param2 % 32 local ref = { {x = -1, y = 0, z = 0}, {x = 0, y = 0, z = 1}, {x = 1, y = 0, z = 0}, {x = 0, y = 0, z = -1}, } local aside = { x = pos.x + ref[dir + 1].x, y = pos.y + ref[dir + 1].y, z = pos.z + ref[dir + 1].z, } if minetest.get_item_group(minetest.get_node(aside).name, "door") == 1 then minetest.swap_node(pos, {name = node.name:match("^(.+_)%w$") .. "b", param2 = node.param2}) end minetest.set_node({x = pos.x, y = pos.y + 1, z = pos.z}, {name = "greek:door_blank", param2 = node.param2}) end defcopy.color = "#242424" -- Use overlay for door because it wont be colored defcopy.inventory_overlay = "greek_door_" .. i .. "_inv.png" defcopy.inventory_image = "greek_door_inv_handle.png" defcopy.wield_overlay = "greek_door_" .. i .. "_inv.png" defcopy.wield_image = "greek_door_inv_handle.png" minetest.register_node("greek:door_" .. i .. "_a", defcopy) end do -- Register mirrored version (should not be obtainable normally) local defcopy = table.copy(def) -- Fancy flipping local front = "([combine\\:16x32\\:0,0=%s\\^[transformFX)" local back = "([combine\\:16x32\\:-16,0=%s\\^[transformFX)" local sides = "([combine\\:4x32\\:-32,0=%s\\^[transformFX)" local tops = "([combine\\:2x32\\:-36,0=%s\\^[transformFX)" defcopy.tiles[1].name = (("[combine:38x32:0,0=%s:16,0=%s:32,0=%s:36,0=%s"):format(front, back, sides, tops):gsub("%%s", def.tiles[1].name)) defcopy.overlay_tiles = {(("[combine:38x32:0,0=([combine\\:16x32\\:0,0=%s\\^[transformFX):16,0=([combine\\:16x32\\:-16,0=%s\\^[transformFX)"):gsub("%%s", def.overlay_tiles[1]))} defcopy.groups.not_in_creative_inventory = 1 defcopy.drop = "greek:door_" .. i .. "_a" defcopy.preserve_metadata = function(_, node, oldmeta, drops) -- Preserve locked state if oldmeta.owner then local meta = drops[1]:get_meta() meta:set_int("palette_index", 128) meta:set_string("description", "Locked " .. minetest.registered_items[node.name].description) meta:set_string("color", "#dcdcdc") end end minetest.register_node("greek:door_" .. i .. "_b", defcopy) end end greek.register_craftring("greek:door_%s_a", door_count) for _, item in pairs(greek.settings_list("blue_wood")) do -- Only bother registering our own if it is used if item == "greek:blue_wood" then greek.register_node_and_stairs("greek:blue_wood", { description = "Blue Wood", tiles = {"greek_blue_wood.png"}, groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2, wood = 2}, sounds = greek.default_sounds("node_sound_wood_defaults"), }) minetest.register_craft({ output = "greek:blue_wood", recipe = {"group:wood", "dye:blue"}, type = "shapeless", }) end greek.add_group(item, "blue_wood") end minetest.register_craft({ output = "greek:door_1_a 2", recipe = { {"group:greek:blue_wood", "group:greek:blue_wood"}, {"group:greek:blue_wood", "group:greek:blue_wood"}, {"group:greek:blue_wood", "group:greek:blue_wood"}, }, }) for _, item in pairs(greek.settings_list("door_lock")) do greek.add_group(item, "door_lock") end minetest.register_craft({ output = ItemStack({ name = "greek:door_1_a", meta = { description = "Locked " .. minetest.registered_items["greek:door_1_a"].description, color = "#dcdcdc", palette_index = 128, }, }):to_string(), recipe = {"greek:door_1_a", "group:greek:door_lock"}, type = "shapeless", }) local shutter_count = 3 for i = 1, shutter_count do local def = { description = "Blue Shutters " .. i, drawtype = "mesh", mesh = "greek_shutters.obj", tiles = {{name = "greek_shutters_" .. i .. ".png", backface_culling = true}, "blank.png"}, paramtype = "light", sunlight_propagates = true, paramtype2 = "facedir", selection_box = { type = "fixed", fixed = {-0.5, -0.5, 6 / 16, 0.5, 0.5, 0.5}, }, collision_box = { type = "fixed", fixed = {-0.5, -0.5, 6 / 16, 0.5, 0.5, 0.5}, }, groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, on_rightclick = function(pos, node) minetest.swap_node(pos, {name = "greek:shutters_" .. i .. "_open", param2 = node.param2}) if minetest.get_modpath("doors") then minetest.sound_play("doors_door_open", {pos = pos}, true) end end, } minetest.register_node("greek:shutters_" .. i, def) def = table.copy(def) def.tiles = {"blank.png", def.tiles[1]} def.groups.not_in_creative_inventory = 1 def.drop = "greek:shutters_" .. i def.on_rightclick = function(pos, node) minetest.swap_node(pos, {name = "greek:shutters_" .. i, param2 = node.param2}) if minetest.get_modpath("doors") then minetest.sound_play("doors_door_close", {pos = pos}, true) end end minetest.register_node("greek:shutters_" .. i .. "_open", def) end greek.register_craftring("greek:shutters_%s", shutter_count) minetest.register_craft({ output = "greek:shutters_1 2", recipe = { {"group:greek:blue_wood", "", "group:greek:blue_wood"}, {"group:greek:blue_wood", "", "group:greek:blue_wood"}, }, })