local ns = rgt_world function ns.register_slab(def) def = table.copy(def) def._variants = nil rgt.register_node(def._name.."_slab", extend(def, { _base_node = def._name, drawtype = "nodebox", node_box = { type = "fixed", fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5} }, paramtype = "light", paramtype2 = "facedir", _variant = "slab" })) end function ns.update_stair(pos, basename, leaf) local node = minetest.get_node(pos) local neighbors = {} local dir local pipe for _, offset in ipairs(rgt.adjacent_horizontal_neighbor_offests) do pipe = minetest.get_node(pos +offset) if minetest.get_item_group(pipe.name, basename.."_stair") > 0 then neighbors[#neighbors +1] = offset end end if #neighbors == 1 then node.name = basename.."_stair" node.param2 = minetest.dir_to_facedir(-neighbors[1]:rotate(vector.new(0, math.pi /2, 0))) minetest.swap_node(pos, node) elseif #neighbors > 1 then -- Just use the first two neighbors. if neighbors[1].x ~= 0 and neighbors[2].x ~= 0 or neighbors[1].z ~= 0 and neighbors[2].z ~= 0 then node.name = basename.."_stair" node.param2 = minetest.dir_to_facedir(neighbors[1]) end minetest.swap_node(pos, node) end if not leaf then for _, x in ipairs(neighbors) do update_pipe(pos +x, true) end end end local function get_connection_dirs(dir, variant, orientation) if variant == "stair_inner" then if orientation == "back" then return dir:rotate(vector.new(0, math.pi, 0)), dir:rotate(vector.new(0, -math.pi /2, 0)) else return dir:rotate(vector.new(0, math.pi /2, 0)), dir end elseif variant == "stair_outer" then if orientation == "back" then return dir:rotate(vector.new(0, math.pi /2, 0)), dir else return dir:rotate(vector.new(0, math.pi, 0)), dir:rotate(vector.new(0, -math.pi /2, 0)) end elseif variant == "stair" then return dir:rotate(vector.new(0, math.pi /2, 0)), dir:rotate(vector.new(0, -math.pi /2, 0)) end return vector.zero(), vector.zero() end local function place_stair(s, p, pt) local m = rgt.players[p:get_player_name()] local def = s:get_definition() local out = ItemStack(s) local variant = def._variant local param2 s:set_name(def._base_node.."_stair") local invert = m.pointed_node.intersection_point.y -m.pointed_node.under.y > 0.5 local adjusted_yaw = (math.pi *2 -m.yaw) +(math.pi /4) if adjusted_yaw > math.pi *2 then adjusted_yaw = adjusted_yaw -(math.pi *2) end local yaw = math.floor(adjusted_yaw /(math.pi /2)) local dir = vector.new(yaw == 1 and 1 or yaw == 3 and -1 or 0, 0, yaw == 0 and 1 or yaw == 2 and -1 or 0) local dir_left = dir:rotate(vector.new(0, -math.pi /2, 0)) local dir_right = dir_left:rotate(vector.new(0, math.pi /2, 0)) -- local obj = minetest.add_entity(pt.above +dir, "display") -- obj:set_properties { -- visual = "cube", -- textures = {"rgt_glass.png^[multiply:#f99", "rgt_glass.png^[multiply:#f99", "rgt_glass.png^[multiply:#f99", "rgt_glass.png^[multiply:#f99", "rgt_glass.png^[multiply:#f99", "rgt_glass.png^[multiply:#f99"} -- } -- minetest.after(10, function() obj:remove() end) local front = minetest.get_node(pt.above +dir) local front_def = minetest.registered_nodes[front.name] local back = minetest.get_node(pt.above -dir) local back_def = minetest.registered_nodes[back.name] local left = minetest.get_node(pt.above +dir_left) local left_def = minetest.registered_nodes[left.name] local right = minetest.get_node(pt.above +dir_right) if (front_def._variant or "none"):find "stair" then local front_dir = minetest.facedir_to_dir(front.param2) local dir_a, dir_b = get_connection_dirs(front_dir, front_def._variant) if dir_a == dir then s:set_name(def._base_node.."_stair_outer") param2 = minetest.dir_to_facedir(dir_left) elseif dir_b == dir then s:set_name(def._base_node.."_stair_outer") param2 = minetest.dir_to_facedir(dir_right) end elseif (back_def._variant or "none"):find "stair" then local back_dir = minetest.facedir_to_dir(back.param2) local dir_a, dir_b = get_connection_dirs(back_dir, back_def._variant, "back") if dir_a == dir then s:set_name(def._base_node.."_stair_inner") param2 = minetest.dir_to_facedir(dir_left) elseif dir_b == dir then s:set_name(def._base_node.."_stair_inner") param2 = minetest.dir_to_facedir(dir_right) end end local stack = minetest.item_place_node(s, p, pt, param2) out:set_count(stack:get_count()) return out end function ns.register_stair(def) def = table.copy(def) def._variants = nil def.groups[def._name.."_stair"] = 1 rgt.register_node(def._name.."_stair", extend(table.copy(def), { _base_node = def._name, drawtype = "nodebox", node_box = { type = "fixed", fixed = { { -0.5, -0.5, -0.5, 0.5, 0, 0.5 }, { -0.5, -0.5, 0, 0.5, 0.5, 0.5 }, } }, paramtype = "light", paramtype2 = "facedir", _variant = "stair", on_place = place_stair, })) rgt.register_node(def._name.."_stair_inner", extend(table.copy(def), { _base_node = def._name, drawtype = "nodebox", node_box = { type = "fixed", fixed = { { -0.5, -0.5, -0.5, 0.5, 0, 0.5 }, { -0.5, -0.5, -0.5, 0, 0.5, 0.5 }, { -0.5, -0.5, 0, 0.5, 0.5, 0.5 }, } }, paramtype = "light", paramtype2 = "facedir", _variant = "stair_inner", on_place = place_stair, drop = def._name.."_stair", })) rgt.register_node(def._name.."_stair_outer", extend(def, { _base_node = def._name, drawtype = "nodebox", node_box = { type = "fixed", fixed = { { -0.5, -0.5, -0.5, 0.5, 0, 0.5 }, { -0.5, -0.5, 0.5, 0, 0.5, 0 } } }, paramtype = "light", paramtype2 = "facedir", _variant = "stair_outer", on_place = place_stair, drop = def._name.."_stair", })) end function ns.register_all(def) ns.register_slab(def) ns.register_stair(def) end