Up to 9 rope lengths, redid models to match Castle rope box look and feel

This change includes some extensive rewriting of the shared underlying
functions as well as the cosmetic changes. Rope destruction should
happen instantly down its entire length now. Rope boxes themselves are
now "climbable", making it easier to transfer from one rope to another.
There's also a new user setting for limiting the number of rope box
types available to the player.
This commit is contained in:
FaceDeer 2017-02-09 00:34:17 -07:00
parent 2bd5658bf8
commit 52a32fe1f2
24 changed files with 367 additions and 252 deletions

@ -3,3 +3,5 @@
## Features ## Features
- Rope blocks for spawning rope that slowly drops into the deep. - Rope blocks for spawning rope that slowly drops into the deep.
- Rope ladder that similarly descends 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.

14
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.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_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_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 = ropes.doc.ropebox_usage = rope_length_doc .. "\n\n" ..
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! 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("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" ..
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.") 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") doc.add_entry_alias("nodes", "ropes:ropeladder_top", "nodes", "ropes:ropeladder")

@ -1,49 +1,66 @@
local c_air = minetest.get_content_id("air") ropes.make_rope_on_timer = function(rope_node_name)
return function(pos, elapsed)
ropes.destroy_rope_starting = function(pos, targetnode, bottomnode, topnode ) local currentend = minetest.get_node(pos)
local node_name = minetest.get_node(pos).name local currentmeta = minetest.get_meta(pos)
if node_name ~= targetnode and node_name ~= bottomnode then local currentlength = currentmeta:get_int("length_remaining")
return local placer_name = currentmeta:get_string("placer")
end local newpos = {x=pos.x, y=pos.y-1, z=pos.z}
local y_top = pos.y local newnode = minetest.get_node(newpos)
local y_bottom = y_top local oldnode = minetest.get_node(pos)
local true_bottom = true if currentlength > 1 and (not minetest.is_protected(newpos, placer_name)
while true do or minetest.check_player_privs(placer_name, "protection_bypass")) then
minetest.debug("loop", y_bottom) if newnode.name == "air" then
node_name = minetest.get_node({x=pos.x, y=y_bottom - 1, z=pos.z}).name minetest.add_node(newpos, {name=currentend.name, param2=oldnode.param2})
if node_name == targetnode or node_name == bottomnode then local newmeta = minetest.get_meta(newpos)
y_bottom = y_bottom - 1 newmeta:set_int("length_remaining", currentlength-1)
elseif node_name == "ignore" then newmeta:set_string("placer", placer_name)
true_bottom = false minetest.set_node(pos, {name=rope_node_name, param2=oldnode.param2})
break ropes.move_players_down(pos, 1)
else else
break local timer = minetest.get_node_timer( pos )
timer:start( 1 )
end
end end
end end
end
local manip = minetest.get_voxel_manip() local data = {}
local pos_bottom = {x=pos.x, y=y_bottom, z=pos.z} local c_air = minetest.get_content_id("air")
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()
for i in area:iterp(pos_bottom, pos_top) do ropes.destroy_rope = function(pos, nodes)
nodes[i] = c_air local top = pos.y
end local bottom = pos.y-15
if not true_bottom then local voxel_manip = minetest.get_voxel_manip()
nodes[area:indexp(pos_bottom)] = minetest.get_content_id(topnode)
local finished = false
local ids_to_destroy = {}
for _, node in pairs(nodes) do
ids_to_destroy[minetest.get_content_id(node)] = true
end end
manip:set_data(nodes) while not finished do
manip:write_to_map() local emin, emax = voxel_manip:read_from_map({x=pos.x, y=bottom, z=pos.z}, {x=pos.x, y=top, z=pos.z})
manip:update_map() -- <— this takes time voxel_manip:get_data(data)
local voxel_area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
if not true_bottom then bottom = emin.y
minetest.get_node_timer(pos_bottom):start(1) 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
end end
ropes.hanging_after_destruct = function(pos, top_node, middle_node, bottom_node) ropes.hanging_after_destruct = function(pos, top_node, middle_node, bottom_node)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
if node.name == top_node or node.name == middle_node or node.name == bottom_node then 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 pos.y = pos.y - 2 -- one down
local node_below = minetest.get_node(pos) local node_below = minetest.get_node(pos)
if node_below.name == middle_node then 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 elseif node_below.name == bottom_node then
minetest.swap_node(pos, {name="air"}) minetest.swap_node(pos, {name="air"})
end end
end 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

@ -6,17 +6,20 @@ ropes = {
local MP = minetest.get_modpath(minetest.get_current_modname()) local MP = minetest.get_modpath(minetest.get_current_modname())
local S, NS = dofile(MP.."/intllib.lua") local S, NS = dofile(MP.."/intllib.lua")
local rope_length = minetest.setting_get("ropes_rope_length") ropes.ropeLength = tonumber(minetest.setting_get("ropes_rope_length"))
if not rope_length then if not ropes.ropeLength then
rope_length = 50 ropes.ropeLength = 50
end end
ropes.ropeLength = rope_length
local rope_ladder_length = minetest.setting_get("ropes_rope_ladder_length") ropes.ropeLadderLength = tonumber(minetest.setting_get("ropes_rope_ladder_length"))
if not rope_ladder_length then if not ropes.ropeLadderLength then
rope_ladder_length = 50 ropes.ropeLadderLength = 50
end
ropes.ropeLengthMaxMultiple = tonumber(minetest.setting_get("ropes_rope_box_max_multiple"))
if not ropes.ropeLengthMaxMultiple then
ropes.ropeLengthMaxMultiple = 9
end end
ropes.ropeLadderLength = rope_ladder_length
dofile( minetest.get_modpath( ropes.name ) .. "/doc.lua" ) dofile( minetest.get_modpath( ropes.name ) .. "/doc.lua" )
dofile( minetest.get_modpath( ropes.name ) .. "/functions.lua" ) dofile( minetest.get_modpath( ropes.name ) .. "/functions.lua" )

@ -43,7 +43,7 @@ minetest.register_node("ropes:ropeladder_top", {
end, end,
after_destruct = function(pos) after_destruct = function(pos)
local pos_below = {x=pos.x, y=pos.y-1, z=pos.z} 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, end,
}) })
@ -75,6 +75,8 @@ minetest.register_node("ropes:ropeladder", {
end, end,
}) })
local ladder_extender = ropes.make_rope_on_timer("ropes:ropeladder")
minetest.register_node("ropes:ropeladder_bottom", { minetest.register_node("ropes:ropeladder_bottom", {
description = S("Rope Ladder"), description = S("Rope Ladder"),
_doc_items_create_entry = false, _doc_items_create_entry = false,
@ -102,28 +104,7 @@ minetest.register_node("ropes:ropeladder_bottom", {
local timer = minetest.get_node_timer( pos ) local timer = minetest.get_node_timer( pos )
timer:start( 1 ) timer:start( 1 )
end, end,
on_timer = function( pos, elapsed ) on_timer = ladder_extender,
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,
after_destruct = function(pos) after_destruct = function(pos)
ropes.hanging_after_destruct(pos, "ropes:ropeladder_falling", "ropes:ropeladder", "ropes:ropeladder_bottom") 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) local node_below = minetest.get_node(pos_below)
if (node_below.name ~= "ignore") then 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"}) minetest.swap_node(pos, {name="air"})
else else
local timer = minetest.get_node_timer( pos ) local timer = minetest.get_node_timer( pos )

@ -1,14 +1,14 @@
# Ropes mod. # SOME DESCRIPTIVE TITLE.
# Copyright (C) 2017 # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the ropes package. # This file is distributed under the same license as the PACKAGE package.
# FaceDeer. # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
# #
#, fuzzy #, fuzzy
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \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" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -16,8 +16,20 @@ msgstr ""
"Content-Type: text/plain; charset=CHARSET\n" "Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: crafts.lua:17 #: init.lua:57
msgid "Rope Segment" 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 "" msgstr ""
#: doc.lua:11 #: doc.lua:11
@ -35,47 +47,50 @@ msgid "A hanging rope ladder that automatically extends downward."
msgstr "" msgstr ""
#: doc.lua:15 #: doc.lua:15
#, c-format
msgid "" msgid ""
"After a rope ladder is placed on a vertical wall it will begin extending " "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 " "downward until it reaches its maximum length (@1 meters). If the rope ladder "
"removed all of the ladder below the point of removal will disappear. A rope " "is removed all of the ladder below the point of removal will disappear. A "
"ladder can be severed partway down using an axe or similar tool, and the " "rope ladder can be severed partway down using an axe or similar tool, and "
"ladder below the point where it is cut will collapse. No rope is actually " "the ladder below the point where it is cut will collapse. No rope is "
"lost in the process, though, and if the uppermost section of the ladder is " "actually lost in the process, though, and if the uppermost section of the "
"removed and replaced the ladder will re-extend to the same maximum length as " "ladder is removed and replaced the ladder will re-extend to the same maximum "
"before." "length as before."
msgstr "" 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 "" msgid ""
"Ropes are hung by placing rope boxes, which automatically lower a rope of " "Ropes are hung by placing rope boxes, which automatically lower a rope of "
"fixed length below them. They can be climbed and cut." "fixed length below them. They can be climbed and cut."
msgstr "" msgstr ""
#: doc.lua:19 #: doc.lua:26
#, 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
msgid "" msgid ""
"When a rope box is placed the rope will immediately begin lowering from it " "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 " "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 " "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 " "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 " "goes. Take care not to fall off the end! If you are near the bottom end of a "
"encounters and obstruction, but will resume lowering if the obstruction is " "rope that's extending you'll be automatically carried down with it. The rope "
"removed." "will stop when it encounters and obstruction, but will resume lowering if "
"the obstruction is removed."
msgstr "" msgstr ""
#: doc.lua:21 #: doc.lua:27
msgid "" msgid ""
"A rope can be severed midway using an axe or other similar tools. The " "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 " "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 " "it will still have the same maximum length of rope as before - no rope is "
"permnanently lost when a rope is severed like this." "permnanently lost when a rope is severed like this."
msgstr "" 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 ""

@ -2,71 +2,189 @@
local MP = minetest.get_modpath(minetest.get_current_modname()) local MP = minetest.get_modpath(minetest.get_current_modname())
local S, NS = dofile(MP.."/intllib.lua") local S, NS = dofile(MP.."/intllib.lua")
local function register_rope_block(multiple, pixels) local function rope_box_tiles(count)
minetest.register_node(string.format("ropes:%irope_block", multiple), { return {
description = string.format(S("Rope %im"), ropes.ropeLength*multiple), string.format("ropes_ropebox_front_%i.png", count),
_doc_items_create_entry = false, string.format("ropes_ropebox_front_%i.png", count),
drawtype="nodebox", "ropes_ropebox_side.png",
sunlight_propagates = true, "ropes_ropebox_side.png",
paramtype = "light", string.format("ropes_ropebox_front_%i.png", count),
paramtype2 = "wallmounted", string.format("ropes_ropebox_front_%i.png", count),
tiles = { }
string.format("default_wood.png^ropes_%irope.png", multiple), end
string.format("default_wood.png^ropes_%irope.png", multiple),
"default_wood.png^ropes_side.png", local rope_box_data = {
"default_wood.png^ropes_side.png", {
string.format("default_wood.png^(ropes_%irope.png^[mask:ropes_mask.png)", multiple), node={
string.format("default_wood.png^(ropes_%irope.png^[mask:ropes_mask.png)", multiple), {-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 = { --selection = {-0.1875, -0.5, -0.25, 0.1875, 0.25, 0.25}, -- selection
type = "fixed", tiles = rope_box_tiles(1),
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 node={
{0.375, -0.5, -0.1875, 0.5, 0.25, 0.1875}, -- Support_arm {-0.1875, -0.125, -0.25, 0.1875, 0.125, 0.25}, -- pulley
{-0.375, -0.5, -0.1875, 0.375, -0.375, 0.1875}, -- Base {-0.1875, -0.25, -0.125, 0.1875, 0.25, 0.125}, -- pulley
{-0.0625*(pixels/2), -0.1875, -0.5, 0.0625*(pixels/2), 0.375, 0.5}, -- Longitudinal_rope {-0.1875, -0.1875, -0.1875, 0.1875, 0.1875, 0.1875}, -- pulley_core
{-0.0625*(pixels/2), -0.3125, -0.375, 0.0625*(pixels/2), 0.5, 0.375}, -- Vertical_rope {-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"},
selection_box = {type="regular"}, collision_box = {type="regular"},
collision_box = {type="regular"}, groups = {flammable=2, choppy=2, oddly_breakable_by_hand=1, rope_block = 1},
groups = {flammable=2, choppy=2, oddly_breakable_by_hand=1},
after_place_node = function(pos, placer) after_place_node = function(pos, placer)
local pos_below = {x=pos.x, y=pos.y-1, z=pos.z} local pos_below = {x=pos.x, y=pos.y-1, z=pos.z}
local placer_name = placer:get_player_name() 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 if minetest.is_protected(pos_below, placer_name) and not minetest.check_player_privs(placer, "protection_bypass") then
return 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,
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
}
local node_below = minetest.get_node(pos_below) -- If this number is higher than permitted, we still want to register the block (in case
if node_below.name == "air" then -- some were already placed in-world) but we want to hide it from creative inventory
minetest.add_node(pos_below, {name="ropes:rope_bottom"}) -- and if someone digs it we want to disintegrate it into its component parts to prevent
local meta = minetest.get_meta(pos_below) -- reuse.
meta:set_int("length_remaining", ropes.ropeLength*multiple) if multiple > ropes.ropeLengthMaxMultiple then
meta:set_string("placer", placer:get_player_name()) rope_block_def.groups.not_in_creative_inventory = 1
end rope_block_def.drop = string.format("ropes:1rope_block %i", multiple)
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')
end end
})
minetest.register_node(string.format("ropes:%irope_block", multiple), rope_block_def)
if (multiple ~= 1) then if (multiple ~= 1) then
local rec = {} -- Only register a recipe to craft this if it's within the permitted multiple range
for i=1,multiple,1 do if multiple <= ropes.ropeLengthMaxMultiple then
rec[i] = "ropes:1rope_block" 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
})
end end
minetest.register_craft({ -- Always allow players to disintegrate this into component parts, in case
output = string.format("ropes:%irope_block", multiple), -- there were some in inventory and the setting was changed.
type = "shapeless",
recipe = rec
})
minetest.register_craft({ minetest.register_craft({
output = string.format("ropes:1rope_block %i", multiple), output = string.format("ropes:1rope_block %i", multiple),
recipe = { recipe = {
@ -80,15 +198,7 @@ local function register_rope_block(multiple, pixels)
end end
end end
--creates rope blocks with length multiples 1-5. local rope_def = {
--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", {
description = S("Rope"), description = S("Rope"),
_doc_items_longdesc = ropes.doc.ropebox_longdesc, _doc_items_longdesc = ropes.doc.ropebox_longdesc,
_doc_items_usagehelp = ropes.doc.ropebox_usage, _doc_items_usagehelp = ropes.doc.ropebox_usage,
@ -97,20 +207,29 @@ minetest.register_node("ropes:rope", {
sunlight_propagates = true, sunlight_propagates = true,
paramtype = "light", paramtype = "light",
drop = "", drop = "",
tiles = { "ropes_rope.png" }, tiles = { "ropes_ropebox_front_3.png" },
drawtype = "plantlike",
groups = {choppy=2, flammable=2, not_in_creative_inventory=1}, groups = {choppy=2, flammable=2, not_in_creative_inventory=1},
sounds = default.node_sound_leaves_defaults(), 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 = { selection_box = {
type = "fixed", 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) after_destruct = function(pos)
ropes.hanging_after_destruct(pos, "ropes:rope_top", "ropes:rope", "ropes:rope_bottom") ropes.hanging_after_destruct(pos, "ropes:rope_top", "ropes:rope", "ropes:rope_bottom")
end, 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"), description = S("Rope"),
_doc_items_create_entry = false, _doc_items_create_entry = false,
walkable = false, walkable = false,
@ -118,13 +237,23 @@ minetest.register_node("ropes:rope_bottom", {
sunlight_propagates = true, sunlight_propagates = true,
paramtype = "light", paramtype = "light",
drop = "", drop = "",
tiles = { "ropes_rope_bottom.png" }, tiles = { "ropes_ropebox_front_3.png" },
drawtype = "plantlike", drawtype = "nodebox",
groups = {choppy=2, flammable=2, not_in_creative_inventory=1}, groups = {choppy=2, flammable=2, not_in_creative_inventory=1},
sounds = default.node_sound_leaves_defaults(), 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 = { selection_box = {
type = "fixed", 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 ) on_construct = function( pos )
@ -132,65 +261,24 @@ minetest.register_node("ropes:rope_bottom", {
timer:start( 1 ) timer:start( 1 )
end, end,
on_timer = function( pos, elapsed ) on_timer = rope_extension_timer,
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,
after_destruct = function(pos) after_destruct = function(pos)
ropes.hanging_after_destruct(pos, "ropes:rope_top", "ropes:rope", "ropes:rope_bottom") ropes.hanging_after_destruct(pos, "ropes:rope_top", "ropes:rope", "ropes:rope_bottom")
end, end,
}) }
minetest.register_node("ropes:rope_top", { --creates rope blocks with length multiples 1-5.
description = S("Rope"), --second parameter sets how many pixels wide the rope texture is
_doc_items_create_entry = false, register_rope_block(1)
walkable = false, register_rope_block(2)
climbable = true, register_rope_block(3)
sunlight_propagates = true, register_rope_block(4)
paramtype = "light", register_rope_block(5)
drop = "", register_rope_block(6)
tiles = { "ropes_rope_bottom.png^[transformR180" }, register_rope_block(7)
drawtype = "plantlike", register_rope_block(8)
groups = {not_in_creative_inventory=1}, register_rope_block(9)
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 ) minetest.register_node("ropes:rope", rope_def)
local timer = minetest.get_node_timer( pos ) minetest.register_node("ropes:rope_bottom", rope_bottom_def)
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,
})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 188 KiB

After

Width:  |  Height:  |  Size: 107 KiB

@ -6,3 +6,9 @@ ropes_rope_length (Rope length) int 50 1 30000
#Rope ladders will extend this far at maximum. #Rope ladders will extend this far at maximum.
#Changing this value will not affect rope ladders that already exist in-world. #Changing this value will not affect rope ladders that already exist in-world.
ropes_rope_ladder_length (Rope ladder length) int 50 1 30000 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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 376 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 436 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 510 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 572 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 652 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 545 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 204 B