local S = ropes.S if ropes.extending_ladder_enabled then local wood_recipe = { {"group:stick", "", "group:stick"}, {"group:stick", "", "group:stick"}, {"group:stick", "group:stick", "group:stick"}, } local wood_name = S("Wooden Extendable Ladder") local steel_recipe = { {"default:steel_ingot", "", "default:steel_ingot"}, {"default:steel_ingot", "", "default:steel_ingot"}, {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, } local steel_name = S("Steel Extendable Ladder") -- Overlay texture: by 1F616EMO, CC0 local texture_overlay = "^ropes_ropeladder_overlay.png" if ropes.replace_default_ladders then minetest.unregister_item("default:ladder_wood") minetest.unregister_item("default:ladder_steel") minetest.clear_craft({output = "default:ladder_wood"}) minetest.clear_craft({output = "default:ladder_steel"}) local wallmounted_to_facedir = {[0] = 15, -- ceiling [1] = 13, -- floor [2] = 1, -- +X [3] = 3, -- -X [4] = 0, -- +Z [5] = 2, -- -Z } minetest.register_lbm({ label = "Switch from wallmounted default ladders to rope mod extending ladders", name = "ropes:wallmounted_ladder_to_facedir_ladder", nodenames = {"default:ladder_wood", "default:ladder_steel"}, run_at_every_load = false, action = function(pos, node) local new_node = {param2 = wallmounted_to_facedir[node.param2]} if (node.name == "default:ladder_wood") then new_node.name = "ropes:ladder_wood" else new_node.name = "ropes:ladder_steel" end minetest.set_node(pos, new_node) end, }) wood_recipe = { {"group:stick", "", "group:stick"}, {"group:stick", "group:stick", "group:stick"}, {"group:stick", "", "group:stick"}, } wood_name = S("Wooden Ladder") steel_recipe = { {'default:steel_ingot', '', 'default:steel_ingot'}, {'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'}, {'default:steel_ingot', '', 'default:steel_ingot'}, } steel_name = S("Steel Ladder") texture_overlay = "" else -- Swap between normal and extendable ladders minetest.register_craft({ type = "shapeless", output = "ropes:ladder_wood", recipe = {"default:ladder_wood"}, }) minetest.register_craft({ type = "shapeless", output = "ropes:ladder_steel", recipe = {"default:ladder_steel"}, }) end minetest.register_craft({ output = "ropes:ladder_wood 5", recipe = wood_recipe, }) minetest.register_craft({ output = 'ropes:ladder_steel 15', recipe = steel_recipe, }) local ladder_extender = function(pos, node, clicker, itemstack, pointed_thing, ladder_node, standing_limit) -- on_rightclick can be called by other mods, make sure we have all the parameters we need if pointed_thing == nil or itemstack == nil then return itemstack end local clicked_stack = ItemStack(itemstack) -- true if we're pointing up at the ladder from below and there's a buildable space below it -- this check allows us to extend ladders downward local pointing_directly_below = pointed_thing.above.x == pos.x and pointed_thing.above.z == pos.z and pointed_thing.above.y == pos.y - 1 and minetest.registered_nodes[minetest.get_node(pointed_thing.above).name].buildable_to if clicked_stack:get_name() == ladder_node and not pointing_directly_below then local param2 = minetest.get_node(pos).param2 local dir = minetest.facedir_to_dir(param2) local scan_limit = pos.y + 6 -- Only add ladder segments up to five nodes above the one clicked on pos.y = pos.y + 1 while pos.y < scan_limit and minetest.get_node(pos).name == ladder_node do param2 = minetest.get_node(pos).param2 pos.y = pos.y + 1 end if pos.y < scan_limit and minetest.registered_nodes[minetest.get_node(pos).name].buildable_to then -- scan downward behind the ladder to find support local behind_pos = vector.add(pos, minetest.facedir_to_dir(param2)) local target_height = pos.y - standing_limit - 1 while behind_pos.y > target_height and minetest.registered_nodes[minetest.get_node(behind_pos).name].buildable_to do behind_pos.y = behind_pos.y - 1 end -- If there's enough support, build a new ladder segment if behind_pos.y > target_height then if minetest.is_protected(pos, clicker:get_player_name()) then minetest.record_protection_violation(pos, clicker:get_player_name()) else minetest.set_node(pos, {name=ladder_node, param2=param2}) if not minetest.settings:get_bool("creative_mode") then clicked_stack:take_item(1) end end end end elseif clicked_stack:get_definition().type == "node" then return minetest.item_place_node(itemstack, clicker, pointed_thing) end return clicked_stack end minetest.register_node("ropes:ladder_wood", { description = wood_name, _doc_items_longdesc = ropes.doc.ladder_longdesc, _doc_items_usagehelp = ropes.doc.ladder_usagehelp, tiles = {"default_wood.png","default_wood.png","default_wood.png^[transformR270","default_wood.png^[transformR270","default_ladder_wood.png"}, use_texture_alpha = "clip", inventory_image = "default_ladder_wood.png" .. texture_overlay, wield_image = "default_ladder_wood.png", paramtype = "light", paramtype2 = "facedir", sunlight_propagates = true, walkable = false, climbable = true, is_ground_content = false, drawtype = "nodebox", paramtype = "light", node_box = { type = "fixed", fixed = { {-0.375, -0.5, 0.375, -0.25, 0.5, 0.5}, -- Upright1 {0.25, -0.5, 0.375, 0.375, 0.5, 0.5}, -- Upright2 {-0.4375, 0.3125, 0.4375, 0.4375, 0.4375, 0.5}, -- Rung_4 {-0.4375, -0.1875, 0.4375, 0.4375, -0.0625, 0.5}, -- Rung_2 {-0.4375, -0.4375, 0.4375, 0.4375, -0.3125, 0.5}, -- Rung_1 {-0.4375, 0.0625, 0.4375, 0.4375, 0.1875, 0.5}, -- Rung_3 } }, groups = {choppy = 2, oddly_breakable_by_hand = 3, flammable = 2, flow_through = 1}, sounds = default.node_sound_wood_defaults(), on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) return ladder_extender(pos, node, clicker, itemstack, pointed_thing, "ropes:ladder_wood", ropes.extending_wood_ladder_limit) end, }) minetest.register_node("ropes:ladder_steel", { description = steel_name, _doc_items_longdesc = ropes.doc.ladder_longdesc, _doc_items_usagehelp = ropes.doc.ladder_usagehelp, tiles = {"default_steel_block.png","default_steel_block.png","default_steel_block.png","default_steel_block.png","default_ladder_steel.png"}, use_texture_alpha = "clip", inventory_image = "default_ladder_steel.png" .. texture_overlay, wield_image = "default_ladder_steel.png", paramtype = "light", paramtype2 = "facedir", sunlight_propagates = true, walkable = false, climbable = true, is_ground_content = false, drawtype = "nodebox", node_box = { type = "fixed", fixed = { {-0.4375, -0.5, 0.3125, -0.25, 0.5, 0.5}, -- Upright1 {0.25, -0.5, 0.3125, 0.4375, 0.5, 0.5}, -- Upright2 {-0.25, 0.3125, 0.375, 0.25, 0.4375, 0.5}, -- Rung_4 {-0.25, -0.1875, 0.375, 0.25, -0.0625, 0.5}, -- Rung_2 {-0.25, -0.4375, 0.375, 0.25, -0.3125, 0.5}, -- Rung_1 {-0.25, 0.0625, 0.375, 0.25, 0.1875, 0.5}, -- Rung_3 } }, groups = {cracky = 2, flow_through = 1}, sounds = default.node_sound_metal_defaults(), on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) return ladder_extender(pos, node, clicker, itemstack, pointed_thing, "ropes:ladder_steel", ropes.extending_steel_ladder_limit) end, }) else -- Table of possible wallmounted values local facedir_to_wallmounted = { 4, -- +Z 2, -- +X 5, -- -Z 3, -- -X 1, -- -Y 0, -- +Y } -- Mapping from facedir value to index in facedir_to_dir. local facedir_to_wallmounted_map = { [0]=1, 2, 3, 4, 5, 2, 6, 4, 6, 2, 5, 4, 1, 5, 3, 6, 1, 6, 3, 5, 1, 4, 3, 2, } minetest.register_lbm({ label = "Switch from ropes ladders to wallmounted default ladders", name = "ropes:facedir_ladder_to_wallmounted_ladder", nodenames = {"ropes:ladder_wood", "ropes:ladder_steel"}, run_at_every_load = false, action = function(pos, node) local new_node = {param2 = facedir_to_wallmounted[facedir_to_wallmounted_map[node.param2 % 32]]} if (node.name == "ropes:ladder_wood") then new_node.name = "default:ladder_wood" else new_node.name = "default:ladder_steel" end minetest.set_node(pos, new_node) end, }) end