diff --git a/README.md b/README.md index 78f5bc7..58421ac 100644 --- a/README.md +++ b/README.md @@ -3,3 +3,5 @@ ## Features - Rope blocks for spawning rope that slowly drops into the deep. - Rope ladder that similarly descends into the deep. + +Includes in-game documentation via the "doc" mod and configurable settings that allow the server admin to set what lengths of rope are available. \ No newline at end of file diff --git a/doc.lua b/doc.lua index 50bfad5..35f1cdc 100644 --- a/doc.lua +++ b/doc.lua @@ -12,12 +12,18 @@ ropes.doc.ropesegment_longdesc = S("Rope segments are bundles of fibre twisted i ropes.doc.ropesegment_usage = S("This craft item is useful for creating rope ladders, or for spooling on wooden spindles to hang and climb upon.") ropes.doc.ropeladder_longdesc = S("A hanging rope ladder that automatically extends downward.") -ropes.doc.ropeladder_usage = string.format(S("After a rope ladder is placed on a vertical wall it will begin extending downward until it reaches its maximum length (%dm). If the rope ladder is removed all of the ladder below the point of removal will disappear. A rope ladder can be severed partway down using an axe or similar tool, and the ladder below the point where it is cut will collapse. No rope is actually lost in the process, though, and if the uppermost section of the ladder is removed and replaced the ladder will re-extend to the same maximum length as before."), ropes.ropeLadderLength) +ropes.doc.ropeladder_usage = S("After a rope ladder is placed on a vertical wall it will begin extending downward until it reaches its maximum length (@1 meters). If the rope ladder is removed all of the ladder below the point of removal will disappear. A rope ladder can be severed partway down using an axe or similar tool, and the ladder below the point where it is cut will collapse. No rope is actually lost in the process, though, and if the uppermost section of the ladder is removed and replaced the ladder will re-extend to the same maximum length as before.", ropes.ropeLadderLength) + +local rope_length_doc +if ropes.ropeLengthMaxMultiple > 1 then + rope_length_doc = S("Rope boxes have a certain amount of rope contained within them specified in the name of the node. They come in @1 standard lengths (from @2 meters to @3 meters in multiples of @2 meters) that can be crafted by combining and splitting up rope boxes in the crafting grid. For example, you can craft a @4m rope box by combining two @2m rope boxes, and the two @2m rope boxes can be recovered by splitting the @4m rope box back up in the crafting grid.", ropes.ropeLengthMaxMultiple, ropes.ropeLength, ropes.ropeLength*ropes.ropeLengthMaxMultiple, ropes.ropeLength*2) +else + rope_length_doc = S("Rope boxes contain @1 meters of rope.", ropes.ropeLength) +end ropes.doc.ropebox_longdesc = S("Ropes are hung by placing rope boxes, which automatically lower a rope of fixed length below them. They can be climbed and cut.") -ropes.doc.ropebox_usage = - string.format(S("Rope boxes have a certain amount of rope contained within them specified in the name of the node. They come in five standard lengths (%dm, %dm, %dm, %dm and %dm) that can be crafted by combining and splitting up rope boxes in the crafting grid. For example, you can craft a %dm rope box by combining two %dm rope boxes, and the two %dm rope boxes can be recovered by splitting the %dm rope box back up in the crafting grid."), ropes.ropeLength, ropes.ropeLength*2, ropes.ropeLength*3, ropes.ropeLength*4, ropes.ropeLength*5, ropes.ropeLength*2, ropes.ropeLength, ropes.ropeLength, ropes.ropeLength*2) .. "\n\n" .. - S("When a rope box is placed the rope will immediately begin lowering from it at one meter per second. The rope will only descend when its end is in the vicinity of an active player, suspending its journey when no players are nearby, so a long descent may require a player to climb down the rope as it goes. Take care not to fall off the end! The rope will stop when it encounters and obstruction, but will resume lowering if the obstruction is removed.") .. "\n\n" .. +ropes.doc.ropebox_usage = rope_length_doc .. "\n\n" .. + S("When a rope box is placed the rope will immediately begin lowering from it at one meter per second. The rope will only descend when its end is in the vicinity of an active player, suspending its journey when no players are nearby, so a long descent may require a player to climb down the rope as it goes. Take care not to fall off the end! If you are near the bottom end of a rope that's extending you'll be automatically carried down with it. The rope will stop when it encounters and obstruction, but will resume lowering if the obstruction is removed.") .. "\n\n" .. S("A rope can be severed midway using an axe or other similar tools. The section of rope below the cut will collapse and disappear, potentially causing players who were hanging on to it to fall. The remaining rope will not resume descent on its own, but the rope box at the top of the rope \"remembers\" how long the rope was and if it is deconstructed and replaced it will still have the same maximum length of rope as before - no rope is permnanently lost when a rope is severed like this.") doc.add_entry_alias("nodes", "ropes:ropeladder_top", "nodes", "ropes:ropeladder") diff --git a/functions.lua b/functions.lua index 799f43c..4ce5e62 100644 --- a/functions.lua +++ b/functions.lua @@ -1,49 +1,66 @@ -local c_air = minetest.get_content_id("air") - -ropes.destroy_rope_starting = function(pos, targetnode, bottomnode, topnode ) - local node_name = minetest.get_node(pos).name - if node_name ~= targetnode and node_name ~= bottomnode then - return - end - local y_top = pos.y - local y_bottom = y_top - local true_bottom = true - while true do - minetest.debug("loop", y_bottom) - node_name = minetest.get_node({x=pos.x, y=y_bottom - 1, z=pos.z}).name - if node_name == targetnode or node_name == bottomnode then - y_bottom = y_bottom - 1 - elseif node_name == "ignore" then - true_bottom = false - break - else - break +ropes.make_rope_on_timer = function(rope_node_name) + return function(pos, elapsed) + local currentend = minetest.get_node(pos) + local currentmeta = minetest.get_meta(pos) + local currentlength = currentmeta:get_int("length_remaining") + local placer_name = currentmeta:get_string("placer") + local newpos = {x=pos.x, y=pos.y-1, z=pos.z} + local newnode = minetest.get_node(newpos) + local oldnode = minetest.get_node(pos) + if currentlength > 1 and (not minetest.is_protected(newpos, placer_name) + or minetest.check_player_privs(placer_name, "protection_bypass")) then + if newnode.name == "air" then + minetest.add_node(newpos, {name=currentend.name, param2=oldnode.param2}) + local newmeta = minetest.get_meta(newpos) + newmeta:set_int("length_remaining", currentlength-1) + newmeta:set_string("placer", placer_name) + minetest.set_node(pos, {name=rope_node_name, param2=oldnode.param2}) + ropes.move_players_down(pos, 1) + else + local timer = minetest.get_node_timer( pos ) + timer:start( 1 ) + end end end +end - local manip = minetest.get_voxel_manip() - local pos_bottom = {x=pos.x, y=y_bottom, z=pos.z} - local pos_top = {x=pos.x, y=y_top, z=pos.z} - local pos1, pos2 = manip:read_from_map(pos_bottom, pos_top) - local area = VoxelArea:new({MinEdge=pos1, MaxEdge=pos2}) - local nodes = manip:get_data() +local data = {} +local c_air = minetest.get_content_id("air") - for i in area:iterp(pos_bottom, pos_top) do - nodes[i] = c_air +ropes.destroy_rope = function(pos, nodes) + local top = pos.y + local bottom = pos.y-15 + local voxel_manip = minetest.get_voxel_manip() + + local finished = false + local ids_to_destroy = {} + for _, node in pairs(nodes) do + ids_to_destroy[minetest.get_content_id(node)] = true end - if not true_bottom then - nodes[area:indexp(pos_bottom)] = minetest.get_content_id(topnode) - end - - manip:set_data(nodes) - manip:write_to_map() - manip:update_map() -- <— this takes time - if not true_bottom then - minetest.get_node_timer(pos_bottom):start(1) + while not finished do + local emin, emax = voxel_manip:read_from_map({x=pos.x, y=bottom, z=pos.z}, {x=pos.x, y=top, z=pos.z}) + voxel_manip:get_data(data) + local voxel_area = VoxelArea:new{MinEdge=emin, MaxEdge=emax} + bottom = emin.y + for y = top, bottom, -1 do + local index = voxel_area:index(pos.x, y, pos.z) + if ids_to_destroy[data[index]] then + data[index] = c_air + else + finished = true + break + end + end + voxel_manip:set_data(data) + voxel_manip:write_to_map() + voxel_manip:update_map() + top = bottom - 1 + bottom = bottom - 15 end end + ropes.hanging_after_destruct = function(pos, top_node, middle_node, bottom_node) local node = minetest.get_node(pos) if node.name == top_node or node.name == middle_node or node.name == bottom_node then @@ -59,8 +76,22 @@ ropes.hanging_after_destruct = function(pos, top_node, middle_node, bottom_node) pos.y = pos.y - 2 -- one down local node_below = minetest.get_node(pos) if node_below.name == middle_node then - ropes.destroy_rope_starting(pos, middle_node, bottom_node, top_node) + ropes.destroy_rope(pos, {middle_node, bottom_node}) elseif node_below.name == bottom_node then minetest.swap_node(pos, {name="air"}) end -end \ No newline at end of file +end + +ropes.move_players_down = function(pos, radius) + local all_objects = minetest.get_objects_inside_radius({x=pos.x, y=pos.y+radius, z=pos.z}, radius) + local players = {} + local _,obj + for _,obj in pairs(all_objects) do + if obj:is_player() then + local obj_pos = obj:getpos() + if math.abs(obj_pos.x-pos.x) < 0.5 and math.abs(obj_pos.z-pos.z) < 0.5 then + obj:moveto({x=obj_pos.x, y=obj_pos.y-1, z=obj_pos.z}, true) + end + end + end +end diff --git a/init.lua b/init.lua index c80acd1..65374cf 100644 --- a/init.lua +++ b/init.lua @@ -6,17 +6,20 @@ ropes = { local MP = minetest.get_modpath(minetest.get_current_modname()) local S, NS = dofile(MP.."/intllib.lua") -local rope_length = minetest.setting_get("ropes_rope_length") -if not rope_length then - rope_length = 50 +ropes.ropeLength = tonumber(minetest.setting_get("ropes_rope_length")) +if not ropes.ropeLength then + ropes.ropeLength = 50 end -ropes.ropeLength = rope_length -local rope_ladder_length = minetest.setting_get("ropes_rope_ladder_length") -if not rope_ladder_length then - rope_ladder_length = 50 +ropes.ropeLadderLength = tonumber(minetest.setting_get("ropes_rope_ladder_length")) +if not ropes.ropeLadderLength then + ropes.ropeLadderLength = 50 +end + +ropes.ropeLengthMaxMultiple = tonumber(minetest.setting_get("ropes_rope_box_max_multiple")) +if not ropes.ropeLengthMaxMultiple then + ropes.ropeLengthMaxMultiple = 9 end -ropes.ropeLadderLength = rope_ladder_length dofile( minetest.get_modpath( ropes.name ) .. "/doc.lua" ) dofile( minetest.get_modpath( ropes.name ) .. "/functions.lua" ) diff --git a/ladder.lua b/ladder.lua index 7b8515a..cb9f343 100644 --- a/ladder.lua +++ b/ladder.lua @@ -43,7 +43,7 @@ minetest.register_node("ropes:ropeladder_top", { end, after_destruct = function(pos) local pos_below = {x=pos.x, y=pos.y-1, z=pos.z} - ropes.destroy_rope_starting(pos_below, "ropes:ropeladder", "ropes:ropeladder_bottom", "ropes:ropeladder_falling") + ropes.destroy_rope(pos_below, {"ropes:ropeladder", "ropes:ropeladder_bottom", "ropes:ropeladder_falling"}) end, }) @@ -75,6 +75,8 @@ minetest.register_node("ropes:ropeladder", { end, }) +local ladder_extender = ropes.make_rope_on_timer("ropes:ropeladder") + minetest.register_node("ropes:ropeladder_bottom", { description = S("Rope Ladder"), _doc_items_create_entry = false, @@ -102,28 +104,7 @@ minetest.register_node("ropes:ropeladder_bottom", { local timer = minetest.get_node_timer( pos ) timer:start( 1 ) end, - on_timer = function( pos, elapsed ) - local currentend = minetest.get_node(pos) - local currentmeta = minetest.get_meta(pos) - local currentlength = currentmeta:get_int("length_remaining") - local placer_name = currentmeta:get_string("placer") - local newpos = {x=pos.x, y=pos.y-1, z=pos.z} - local newnode = minetest.get_node(newpos) - local oldnode = minetest.get_node(pos) - if currentlength > 1 and (not minetest.is_protected(newpos, placer_name) - or minetest.check_player_privs(placer_name, "protection_bypass")) then - if newnode.name == "air" then - minetest.add_node(newpos, {name="ropes:ropeladder_bottom", param2=oldnode.param2}) - local newmeta = minetest.get_meta(newpos) - newmeta:set_int("length_remaining", currentlength-1) - newmeta:set_string("placer", placer_name) - minetest.set_node(pos, {name="ropes:ropeladder", param2=oldnode.param2}) - else - local timer = minetest.get_node_timer( pos ) - timer:start( 1 ) - end - end - end, + on_timer = ladder_extender, after_destruct = function(pos) ropes.hanging_after_destruct(pos, "ropes:ropeladder_falling", "ropes:ropeladder", "ropes:ropeladder_bottom") @@ -162,7 +143,7 @@ minetest.register_node("ropes:ropeladder_falling", { local node_below = minetest.get_node(pos_below) if (node_below.name ~= "ignore") then - ropes.destroy_rope_starting(pos_below, 'ropes:ropeladder', 'ropes:ropeladder_bottom', 'ropes:ropeladder_falling') + ropes.destroy_rope(pos_below, {'ropes:ropeladder', 'ropes:ropeladder_bottom', 'ropes:ropeladder_falling'}) minetest.swap_node(pos, {name="air"}) else local timer = minetest.get_node_timer( pos ) diff --git a/locale/template.pot b/locale/template.pot index 972b867..28ebcbf 100644 --- a/locale/template.pot +++ b/locale/template.pot @@ -1,14 +1,14 @@ -# Ropes mod. -# Copyright (C) 2017 -# This file is distributed under the same license as the ropes package. -# FaceDeer. +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-02-03 00:18-0700\n" +"POT-Creation-Date: 2017-02-09 00:20-0700\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -16,8 +16,20 @@ msgstr "" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: crafts.lua:17 -msgid "Rope Segment" +#: init.lua:57 +msgid "[Ropes] Loaded!" +msgstr "" + +#: ropeboxes.lua:120 +msgid "Rope @1m" +msgstr "" + +#: ropeboxes.lua:202 ropeboxes.lua:233 +msgid "Rope" +msgstr "" + +#: ladder.lua:6 ladder.lua:51 ladder.lua:81 ladder.lua:115 +msgid "Rope Ladder" msgstr "" #: doc.lua:11 @@ -35,47 +47,50 @@ msgid "A hanging rope ladder that automatically extends downward." msgstr "" #: doc.lua:15 -#, c-format msgid "" "After a rope ladder is placed on a vertical wall it will begin extending " -"downward until it reaches its maximum length (%dm). If the rope ladder is " -"removed all of the ladder below the point of removal will disappear. A rope " -"ladder can be severed partway down using an axe or similar tool, and the " -"ladder below the point where it is cut will collapse. No rope is actually " -"lost in the process, though, and if the uppermost section of the ladder is " -"removed and replaced the ladder will re-extend to the same maximum length as " -"before." +"downward until it reaches its maximum length (@1 meters). If the rope ladder " +"is removed all of the ladder below the point of removal will disappear. A " +"rope ladder can be severed partway down using an axe or similar tool, and " +"the ladder below the point where it is cut will collapse. No rope is " +"actually lost in the process, though, and if the uppermost section of the " +"ladder is removed and replaced the ladder will re-extend to the same maximum " +"length as before." msgstr "" -#: doc.lua:17 +#: doc.lua:19 +msgid "" +"Rope boxes have a certain amount of rope contained within them specified in " +"the name of the node. They come in @1 standard lengths (from @2 meters to @3 " +"meters in multiples of @2 meters) that can be crafted by combining and " +"splitting up rope boxes in the crafting grid. For example, you can craft a " +"@4m rope box by combining two @2m rope boxes, and the two @2m rope boxes can " +"be recovered by splitting the @4m rope box back up in the crafting grid." +msgstr "" + +#: doc.lua:21 +msgid "Rope boxes contain @1 meters of rope." +msgstr "" + +#: doc.lua:24 msgid "" "Ropes are hung by placing rope boxes, which automatically lower a rope of " "fixed length below them. They can be climbed and cut." msgstr "" -#: doc.lua:19 -#, c-format -msgid "" -"Rope boxes have a certain amount of rope contained within them specified in " -"the name of the node. They come in five standard lengths (%dm, %dm, %dm, %dm " -"and %dm) that can be crafted by combining and splitting up rope boxes in the " -"crafting grid. For example, you can craft a %dm rope box by combining two %" -"dm rope boxes, and the two %dm rope boxes can be recovered by splitting the %" -"dm rope box back up in the crafting grid." -msgstr "" - -#: doc.lua:20 +#: doc.lua:26 msgid "" "When a rope box is placed the rope will immediately begin lowering from it " "at one meter per second. The rope will only descend when its end is in the " "vicinity of an active player, suspending its journey when no players are " "nearby, so a long descent may require a player to climb down the rope as it " -"goes. Take care not to fall off the end! The rope will stop when it " -"encounters and obstruction, but will resume lowering if the obstruction is " -"removed." +"goes. Take care not to fall off the end! If you are near the bottom end of a " +"rope that's extending you'll be automatically carried down with it. The rope " +"will stop when it encounters and obstruction, but will resume lowering if " +"the obstruction is removed." msgstr "" -#: doc.lua:21 +#: doc.lua:27 msgid "" "A rope can be severed midway using an axe or other similar tools. The " "section of rope below the cut will collapse and disappear, potentially " @@ -85,20 +100,3 @@ msgid "" "it will still have the same maximum length of rope as before - no rope is " "permnanently lost when a rope is severed like this." msgstr "" - -#: init.lua:52 -msgid "[Ropes] Loaded!" -msgstr "" - -#: ladder.lua:6 ladder.lua:49 ladder.lua:77 ladder.lua:131 -msgid "Rope Ladder" -msgstr "" - -#: ropeboxes.lua:7 -#, c-format -msgid "Rope %im" -msgstr "" - -#: ropeboxes.lua:92 ropeboxes.lua:114 ropeboxes.lua:160 -msgid "Rope" -msgstr "" diff --git a/ropeboxes.lua b/ropeboxes.lua index 392ce06..d96f8d4 100644 --- a/ropeboxes.lua +++ b/ropeboxes.lua @@ -2,71 +2,189 @@ local MP = minetest.get_modpath(minetest.get_current_modname()) local S, NS = dofile(MP.."/intllib.lua") -local function register_rope_block(multiple, pixels) - minetest.register_node(string.format("ropes:%irope_block", multiple), { - description = string.format(S("Rope %im"), ropes.ropeLength*multiple), - _doc_items_create_entry = false, - drawtype="nodebox", - sunlight_propagates = true, - paramtype = "light", - paramtype2 = "wallmounted", - tiles = { - string.format("default_wood.png^ropes_%irope.png", multiple), - string.format("default_wood.png^ropes_%irope.png", multiple), - "default_wood.png^ropes_side.png", - "default_wood.png^ropes_side.png", - string.format("default_wood.png^(ropes_%irope.png^[mask:ropes_mask.png)", multiple), - string.format("default_wood.png^(ropes_%irope.png^[mask:ropes_mask.png)", multiple), +local function rope_box_tiles(count) + return { + string.format("ropes_ropebox_front_%i.png", count), + string.format("ropes_ropebox_front_%i.png", count), + "ropes_ropebox_side.png", + "ropes_ropebox_side.png", + string.format("ropes_ropebox_front_%i.png", count), + string.format("ropes_ropebox_front_%i.png", count), + } +end + +local rope_box_data = { +{ + node={ + {-0.125, -0.125, -0.25, 0.125, 0.125, 0.25}, -- pulley + {-0.125, -0.25, -0.125, 0.125, 0.25, 0.125}, -- pulley + {-0.125, -0.1875, -0.1875, 0.125, 0.1875, 0.1875}, -- pulley_core + {-0.1875, -0.5, -0.125, -0.125, 0.125, 0.125}, -- support + {0.125, -0.5, -0.125, 0.1875, 0.125, 0.125}, -- support }, - node_box = { - type = "fixed", - fixed = { - {-0.375, -0.1875, -0.3125, 0.375, 0.375, 0.3125}, -- Spool - {-0.5, -0.5, -0.1875, -0.375, 0.25, 0.1875}, -- Support_arm - {0.375, -0.5, -0.1875, 0.5, 0.25, 0.1875}, -- Support_arm - {-0.375, -0.5, -0.1875, 0.375, -0.375, 0.1875}, -- Base - {-0.0625*(pixels/2), -0.1875, -0.5, 0.0625*(pixels/2), 0.375, 0.5}, -- Longitudinal_rope - {-0.0625*(pixels/2), -0.3125, -0.375, 0.0625*(pixels/2), 0.5, 0.375}, -- Vertical_rope + --selection = {-0.1875, -0.5, -0.25, 0.1875, 0.25, 0.25}, -- selection + tiles = rope_box_tiles(1), +}, +{ + node={ + {-0.1875, -0.125, -0.25, 0.1875, 0.125, 0.25}, -- pulley + {-0.1875, -0.25, -0.125, 0.1875, 0.25, 0.125}, -- pulley + {-0.1875, -0.1875, -0.1875, 0.1875, 0.1875, 0.1875}, -- pulley_core + {-0.25, -0.5, -0.125, -0.1875, 0.125, 0.125}, -- support + {0.1875, -0.5, -0.125, 0.25, 0.125, 0.125}, -- support + }, + --selection = {-0.1875, -0.5, -0.25, 0.1875, 0.25, 0.25}, -- selection + tiles = rope_box_tiles(2), +}, +{ + node={ + {-0.25, -0.125, -0.25, 0.25, 0.125, 0.25}, -- pulley + {-0.25, -0.25, -0.125, 0.25, 0.25, 0.125}, -- pulley + {-0.25, -0.1875, -0.1875, 0.25, 0.1875, 0.1875}, -- pulley_core + {-0.3125, -0.5, -0.125, -0.25, 0.125, 0.125}, -- support + {0.25, -0.5, -0.125, 0.3125, 0.125, 0.125}, -- support + }, + --selection = {-0.3125, -0.5, -0.25, 0.3125, 0.25, 0.25}, -- selection + tiles = rope_box_tiles(3), +}, +{ + node={ + {-0.3125, -0.125, -0.25, 0.3125, 0.125, 0.25}, -- pulley + {-0.3125, -0.25, -0.125, 0.3125, 0.25, 0.125}, -- pulley + {-0.3125, -0.1875, -0.1875, 0.3125, 0.1875, 0.1875}, -- pulley_core + {-0.375, -0.5, -0.125, -0.3125, 0.125, 0.125}, -- support + {0.3125, -0.5, -0.125, 0.375, 0.125, 0.125}, -- support + }, + --selection = {-0.375, -0.5, -0.25, 0.375, 0.25, 0.25}, -- selection + tiles = rope_box_tiles(4), +}, +{ + node={ + {-0.375, -0.125, -0.25, 0.375, 0.125, 0.25}, -- pulley + {-0.375, -0.25, -0.125, 0.375, 0.25, 0.125}, -- pulley + {-0.375, -0.1875, -0.1875, 0.375, 0.1875, 0.1875}, -- pulley_core + {-0.4375, -0.5, -0.125, -0.375, 0.125, 0.125}, -- support + {0.375, -0.5, -0.125, 0.4375, 0.125, 0.125}, -- support + }, + --selection = {-0.4375, -0.5, -0.25, 0.4375, 0.25, 0.25}, -- selection + tiles = rope_box_tiles(5), +}, +{ + node={ + {-0.1875, -0.1875, -0.3125, 0.1875, 0.1875, 0.3125}, -- pulley + {-0.1875, -0.3125, -0.1875, 0.1875, 0.3125, 0.1875}, -- pulley + {-0.1875, -0.25, -0.25, 0.1875, 0.25, 0.25}, -- pulley_core + {-0.25, -0.5, -0.125, -0.1875, 0.125, 0.125}, -- support + {0.1875, -0.5, -0.125, 0.25, 0.125, 0.125}, -- support + }, + --selection = {-0.1875, -0.5, -0.3125, 0.1875, 0.3125, 0.3125}, -- selection + tiles = rope_box_tiles(2), +}, +{ + node={ + {-0.25, -0.1875, -0.3125, 0.25, 0.1875, 0.3125}, -- pulley + {-0.25, -0.3125, -0.1875, 0.25, 0.3125, 0.1875}, -- pulley + {-0.25, -0.25, -0.25, 0.25, 0.25, 0.25}, -- pulley_core + {-0.3125, -0.5, -0.125, -0.25, 0.125, 0.125}, -- support + {0.25, -0.5, -0.125, 0.3125, 0.125, 0.125}, -- support + }, + --selection = {-0.3125, -0.5, -0.3125, 0.3125, 0.3125, 0.3125}, -- selection + tiles = rope_box_tiles(3), +}, +{ + node={ + {-0.3125, -0.1875, -0.3125, 0.3125, 0.1875, 0.3125}, -- pulley + {-0.3125, -0.3125, -0.1875, 0.3125, 0.3125, 0.1875}, -- pulley + {-0.3125, -0.25, -0.25, 0.3125, 0.25, 0.25}, -- pulley_core + {-0.375, -0.5, -0.125, -0.3125, 0.125, 0.125}, -- support + {0.3125, -0.5, -0.125, 0.375, 0.125, 0.125}, -- support + }, + --selection = {-0.375, -0.5, -0.3125, 0.375, 0.3125, 0.3125}, -- selection + tiles = rope_box_tiles(4), +}, +{ + node={ + {-0.375, -0.1875, -0.3125, 0.375, 0.1875, 0.3125}, -- pulley + {-0.375, -0.3125, -0.1875, 0.375, 0.3125, 0.1875}, -- pulley + {-0.375, -0.25, -0.25, 0.375, 0.25, 0.25}, -- pulley_core + {-0.4375, -0.5, -0.125, -0.375, 0.125, 0.125}, -- support + {0.375, -0.5, -0.125, 0.4375, 0.125, 0.125}, -- support + }, + --selection_bottom = {-0.4375, -0.5, -0.3125, 0.4375, 0.3125, 0.3125}, -- selection + tiles = rope_box_tiles(5), +} +} + +local function register_rope_block(multiple) + local rope_block_def = { + description = S("Rope @1m", ropes.ropeLength*multiple), + _doc_items_create_entry = false, + drawtype="nodebox", + sunlight_propagates = true, + paramtype = "light", + paramtype2 = "wallmounted", + walkable = false, + climbable = true, + tiles = rope_box_data[multiple].tiles, + node_box = { + type = "fixed", + fixed = rope_box_data[multiple].node }, - }, - selection_box = {type="regular"}, - collision_box = {type="regular"}, - groups = {flammable=2, choppy=2, oddly_breakable_by_hand=1}, + selection_box = {type="regular"}, + collision_box = {type="regular"}, + groups = {flammable=2, choppy=2, oddly_breakable_by_hand=1, rope_block = 1}, - after_place_node = function(pos, placer) - local pos_below = {x=pos.x, y=pos.y-1, z=pos.z} - local placer_name = placer:get_player_name() + after_place_node = function(pos, placer) + local pos_below = {x=pos.x, y=pos.y-1, z=pos.z} + local placer_name = placer:get_player_name() + + if minetest.is_protected(pos_below, placer_name) and not minetest.check_player_privs(placer, "protection_bypass") then + return + end - if minetest.is_protected(pos_below, placer_name) and not minetest.check_player_privs(placer, "protection_bypass") then - return - end + local node_below = minetest.get_node(pos_below) + if node_below.name == "air" then + minetest.add_node(pos_below, {name="ropes:rope_bottom"}) + local meta = minetest.get_meta(pos_below) + meta:set_int("length_remaining", ropes.ropeLength*multiple) + meta:set_string("placer", placer:get_player_name()) + end + end, - local node_below = minetest.get_node(pos_below) - if node_below.name == "air" then - minetest.add_node(pos_below, {name="ropes:rope_bottom"}) - local meta = minetest.get_meta(pos_below) - meta:set_int("length_remaining", ropes.ropeLength*multiple) - meta:set_string("placer", placer:get_player_name()) + after_destruct = function(pos) + local pos_below = {x=pos.x, y=pos.y-1, z=pos.z} + ropes.destroy_rope(pos_below, {'ropes:rope', 'ropes:rope_bottom'}) end - end, - after_destruct = function(pos) - local pos_below = {x=pos.x, y=pos.y-1, z=pos.z} - ropes.destroy_rope_starting(pos_below, 'ropes:rope', 'ropes:rope_bottom', 'ropes:rope_top') + } + + -- If this number is higher than permitted, we still want to register the block (in case + -- some were already placed in-world) but we want to hide it from creative inventory + -- and if someone digs it we want to disintegrate it into its component parts to prevent + -- reuse. + if multiple > ropes.ropeLengthMaxMultiple then + rope_block_def.groups.not_in_creative_inventory = 1 + rope_block_def.drop = string.format("ropes:1rope_block %i", multiple) end - }) + + minetest.register_node(string.format("ropes:%irope_block", multiple), rope_block_def) if (multiple ~= 1) then - local rec = {} - for i=1,multiple,1 do - rec[i] = "ropes:1rope_block" - end + -- Only register a recipe to craft this if it's within the permitted multiple range + if multiple <= ropes.ropeLengthMaxMultiple then + local rec = {} + for i=1,multiple,1 do + rec[i] = "ropes:1rope_block" + end - minetest.register_craft({ - output = string.format("ropes:%irope_block", multiple), - type = "shapeless", - recipe = rec - }) + minetest.register_craft({ + output = string.format("ropes:%irope_block", multiple), + type = "shapeless", + recipe = rec + }) + end + -- Always allow players to disintegrate this into component parts, in case + -- there were some in inventory and the setting was changed. minetest.register_craft({ output = string.format("ropes:1rope_block %i", multiple), recipe = { @@ -80,15 +198,7 @@ local function register_rope_block(multiple, pixels) end end ---creates rope blocks with length multiples 1-5. ---second parameter sets how many pixels wide the rope texture is -register_rope_block(1, 4) -register_rope_block(2, 8) -register_rope_block(3, 10) -register_rope_block(4, 10) -register_rope_block(5, 12) - -minetest.register_node("ropes:rope", { +local rope_def = { description = S("Rope"), _doc_items_longdesc = ropes.doc.ropebox_longdesc, _doc_items_usagehelp = ropes.doc.ropebox_usage, @@ -97,20 +207,29 @@ minetest.register_node("ropes:rope", { sunlight_propagates = true, paramtype = "light", drop = "", - tiles = { "ropes_rope.png" }, - drawtype = "plantlike", + tiles = { "ropes_ropebox_front_3.png" }, groups = {choppy=2, flammable=2, not_in_creative_inventory=1}, sounds = default.node_sound_leaves_defaults(), + drawtype = "nodebox", + node_box = { + type = "connected", + fixed = {-1/16, -1/2, -1/16, 1/16, 1/2, 1/16}, + connect_top = {-1/16, 1/2, -1/16, 1/16, 3/4, 1/16} + }, + connects_to = {"group:rope_block"}, + connect_sides = {"top"}, selection_box = { type = "fixed", - fixed = {-1/7, -1/2, -1/7, 1/7, 1/2, 1/7}, + fixed = {-1/8, -1/2, -1/8, 1/8, 1/2, 1/8}, }, after_destruct = function(pos) ropes.hanging_after_destruct(pos, "ropes:rope_top", "ropes:rope", "ropes:rope_bottom") end, -}) +} -minetest.register_node("ropes:rope_bottom", { +local rope_extension_timer = ropes.make_rope_on_timer("ropes:rope") + +local rope_bottom_def = { description = S("Rope"), _doc_items_create_entry = false, walkable = false, @@ -118,13 +237,23 @@ minetest.register_node("ropes:rope_bottom", { sunlight_propagates = true, paramtype = "light", drop = "", - tiles = { "ropes_rope_bottom.png" }, - drawtype = "plantlike", + tiles = { "ropes_ropebox_front_3.png" }, + drawtype = "nodebox", groups = {choppy=2, flammable=2, not_in_creative_inventory=1}, sounds = default.node_sound_leaves_defaults(), + node_box = { + type = "connected", + fixed = { + {-1/16, -3/8, -1/16, 1/16, 1/2, 1/16}, + {-2/16, -5/16, -2/16, 2/16, -1/16, 2/16}, + }, + connect_top = {-1/16, 1/2, -1/16, 1/16, 3/4, 1/16} + }, + connects_to = {"group:rope_block"}, + connect_sides = {"top"}, selection_box = { type = "fixed", - fixed = {-1/7, -1/2, -1/7, 1/7, 1/2, 1/7}, + fixed = {-1/8, -1/2, -1/8, 1/8, 1/2, 1/8}, }, on_construct = function( pos ) @@ -132,65 +261,24 @@ minetest.register_node("ropes:rope_bottom", { timer:start( 1 ) end, - on_timer = function( pos, elapsed ) - local currentend = minetest.get_node(pos) - local currentmeta = minetest.get_meta(pos) - local currentlength = currentmeta:get_int("length_remaining") - local placer_name = currentmeta:get_string("placer") - local pos_below = {x=pos.x, y=pos.y-1, z=pos.z} - local node_below = minetest.get_node(pos_below) - if node_below.name == "air" - and (currentlength > 1) - and (not minetest.is_protected(pos_below, placer_name) or - minetest.check_player_privs(placer_name, "protection_bypass")) then - minetest.add_node(pos_below, {name="ropes:rope_bottom"}) - local newmeta = minetest.get_meta(pos_below) - newmeta:set_int("length_remaining", currentlength-1) - newmeta:set_string("placer", placer_name) - minetest.set_node(pos, {name="ropes:rope"}) - else - local timer = minetest.get_node_timer( pos ) - timer:start( 1 ) - end - end, + on_timer = rope_extension_timer, after_destruct = function(pos) ropes.hanging_after_destruct(pos, "ropes:rope_top", "ropes:rope", "ropes:rope_bottom") end, -}) +} -minetest.register_node("ropes:rope_top", { - description = S("Rope"), - _doc_items_create_entry = false, - walkable = false, - climbable = true, - sunlight_propagates = true, - paramtype = "light", - drop = "", - tiles = { "ropes_rope_bottom.png^[transformR180" }, - drawtype = "plantlike", - groups = {not_in_creative_inventory=1}, - sounds = default.node_sound_leaves_defaults(), - selection_box = { - type = "fixed", - fixed = {-1/7, -1/2, -1/7, 1/7, 1/2, 1/7}, - }, - - on_construct = function( pos ) - local timer = minetest.get_node_timer( pos ) - timer:start( 1 ) - end, - - on_timer = function( pos, elapsed ) - local p = {x=pos.x, y=pos.y-1, z=pos.z} - local n = minetest.get_node(p) - - if (n.name ~= "ignore") then - ropes.destroy_rope_starting(p, 'ropes:rope', 'ropes:rope_bottom', 'ropes:rope_top') - minetest.swap_node(pos, {name="air"}) - else - local timer = minetest.get_node_timer( pos ) - timer:start( 1 ) - end - end, -}) +--creates rope blocks with length multiples 1-5. +--second parameter sets how many pixels wide the rope texture is +register_rope_block(1) +register_rope_block(2) +register_rope_block(3) +register_rope_block(4) +register_rope_block(5) +register_rope_block(6) +register_rope_block(7) +register_rope_block(8) +register_rope_block(9) + +minetest.register_node("ropes:rope", rope_def) +minetest.register_node("ropes:rope_bottom", rope_bottom_def) \ No newline at end of file diff --git a/screenshot.png b/screenshot.png index fbb3058..1366a4f 100644 Binary files a/screenshot.png and b/screenshot.png differ diff --git a/settingtypes.txt b/settingtypes.txt index e101304..bb0ad2a 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -6,3 +6,9 @@ ropes_rope_length (Rope length) int 50 1 30000 #Rope ladders will extend this far at maximum. #Changing this value will not affect rope ladders that already exist in-world. ropes_rope_ladder_length (Rope ladder length) int 50 1 30000 + +#Sets the maximum length multiple rope box permitted to be crafted. +#So for example if the rope length is set to 50 and this is set to 5, +#the longest possible rope box a player can craft has 250 meters of rope. +#Allowed values run from 1 to 9 +ropes_rope_box_max_multiple (Maximum rope box multiple) int 9 1 9 \ No newline at end of file diff --git a/textures/ropes_1rope.png b/textures/ropes_1rope.png deleted file mode 100644 index b2852a3..0000000 Binary files a/textures/ropes_1rope.png and /dev/null differ diff --git a/textures/ropes_2rope.png b/textures/ropes_2rope.png deleted file mode 100644 index b7694dc..0000000 Binary files a/textures/ropes_2rope.png and /dev/null differ diff --git a/textures/ropes_3rope.png b/textures/ropes_3rope.png deleted file mode 100644 index e425185..0000000 Binary files a/textures/ropes_3rope.png and /dev/null differ diff --git a/textures/ropes_4rope.png b/textures/ropes_4rope.png deleted file mode 100644 index 697a379..0000000 Binary files a/textures/ropes_4rope.png and /dev/null differ diff --git a/textures/ropes_5rope.png b/textures/ropes_5rope.png deleted file mode 100644 index 3009ff3..0000000 Binary files a/textures/ropes_5rope.png and /dev/null differ diff --git a/textures/ropes_mask.png b/textures/ropes_mask.png deleted file mode 100644 index 41626f6..0000000 Binary files a/textures/ropes_mask.png and /dev/null differ diff --git a/textures/ropes_rope.png b/textures/ropes_rope.png deleted file mode 100644 index 0045c4c..0000000 Binary files a/textures/ropes_rope.png and /dev/null differ diff --git a/textures/ropes_rope_bottom.png b/textures/ropes_rope_bottom.png deleted file mode 100644 index faf2c71..0000000 Binary files a/textures/ropes_rope_bottom.png and /dev/null differ diff --git a/textures/ropes_ropebox_front_1.png b/textures/ropes_ropebox_front_1.png new file mode 100644 index 0000000..8387095 Binary files /dev/null and b/textures/ropes_ropebox_front_1.png differ diff --git a/textures/ropes_ropebox_front_2.png b/textures/ropes_ropebox_front_2.png new file mode 100644 index 0000000..b391b57 Binary files /dev/null and b/textures/ropes_ropebox_front_2.png differ diff --git a/textures/ropes_ropebox_front_3.png b/textures/ropes_ropebox_front_3.png new file mode 100644 index 0000000..e047485 Binary files /dev/null and b/textures/ropes_ropebox_front_3.png differ diff --git a/textures/ropes_ropebox_front_4.png b/textures/ropes_ropebox_front_4.png new file mode 100644 index 0000000..56b5723 Binary files /dev/null and b/textures/ropes_ropebox_front_4.png differ diff --git a/textures/ropes_ropebox_front_5.png b/textures/ropes_ropebox_front_5.png new file mode 100644 index 0000000..b81a4f1 Binary files /dev/null and b/textures/ropes_ropebox_front_5.png differ diff --git a/textures/ropes_ropebox_side.png b/textures/ropes_ropebox_side.png new file mode 100644 index 0000000..5584b54 Binary files /dev/null and b/textures/ropes_ropebox_side.png differ diff --git a/textures/ropes_side.png b/textures/ropes_side.png deleted file mode 100644 index 045d887..0000000 Binary files a/textures/ropes_side.png and /dev/null differ