ropeboxes.lua 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. local rope_timer_rate = 0.2
  2. local function register_rope_block(multiple, pixels)
  3. minetest.register_node(string.format("vines:%irope_block", multiple), {
  4. description = string.format("Rope (%i Meters)", vines.ropeLength*multiple),
  5. drawtype="nodebox",
  6. sunlight_propagates = true,
  7. paramtype = "light",
  8. paramtype2 = "wallmounted",
  9. tiles = {
  10. string.format("default_wood.png^vines_%irope.png", multiple),
  11. string.format("default_wood.png^vines_%irope.png", multiple),
  12. "default_wood.png^vines_side.png",
  13. "default_wood.png^vines_side.png",
  14. string.format("default_wood.png^vines_%irope_frontback.png", multiple),
  15. string.format("default_wood.png^vines_%irope_frontback.png", multiple),
  16. },
  17. node_box = {
  18. type = "fixed",
  19. fixed = {
  20. {-0.375, -0.1875, -0.3125, 0.375, 0.375, 0.3125}, -- Spool
  21. {-0.5, -0.5, -0.1875, -0.375, 0.25, 0.1875}, -- Support_arm
  22. {0.375, -0.5, -0.1875, 0.5, 0.25, 0.1875}, -- Support_arm
  23. {-0.375, -0.5, -0.1875, 0.375, -0.375, 0.1875}, -- Base
  24. {-0.0625*(pixels/2), -0.1875, -0.5, 0.0625*(pixels/2), 0.375, 0.5}, -- Longitudinal_rope
  25. {-0.0625*(pixels/2), -0.3125, -0.375, 0.0625*(pixels/2), 0.5, 0.375}, -- Vertical_rope
  26. },
  27. },
  28. selection_box = {type="regular"},
  29. collision_box = {type="regular"},
  30. groups = utility.dig_groups("furniture", {flammable=2}),
  31. after_place_node = function(pos)
  32. local p = {x=pos.x, y=pos.y-1, z=pos.z}
  33. local n = minetest.get_node(p)
  34. if n.name == "air" then
  35. minetest.add_node(p, {name="vines:rope_bottom"})
  36. local meta = minetest.get_meta(p)
  37. meta:set_int("length_remaining", vines.ropeLength*multiple)
  38. meta:mark_as_private("length_remaining")
  39. end
  40. end,
  41. on_punch = function(pos, node, puncher, pt)
  42. local p = {x=pos.x, y=pos.y-1, z=pos.z}
  43. local n = minetest.get_node(p)
  44. if n.name == "air" then
  45. minetest.add_node(p, {name="vines:rope_bottom"})
  46. local meta = minetest.get_meta(p)
  47. meta:set_int("length_remaining", vines.ropeLength*multiple)
  48. meta:mark_as_private("length_remaining")
  49. end
  50. end,
  51. after_destruct = function(pos)
  52. local p = {x=pos.x, y=pos.y-1, z=pos.z}
  53. vines.destroy_rope_starting(p, 'vines:rope', 'vines:rope_bottom', 'vines:rope_top')
  54. end
  55. })
  56. if (multiple == 1) then
  57. minetest.register_craft({
  58. output = "vines:1rope_block",
  59. recipe = {
  60. {'vines:ropesegment', 'group:wood', 'vines:ropesegment'},
  61. {'vines:ropesegment', 'vines:ropesegment', 'vines:ropesegment'},
  62. {'vines:ropesegment', 'vines:ropesegment', 'vines:ropesegment'},
  63. }
  64. })
  65. --
  66. else
  67. local rec = {}
  68. for i=1, multiple, 1 do
  69. rec[i] = "vines:1rope_block"
  70. end
  71. minetest.register_craft({
  72. output = string.format("vines:%irope_block", multiple),
  73. type = "shapeless",
  74. recipe = rec
  75. })
  76. minetest.register_craft({
  77. output = string.format("vines:1rope_block %i", multiple),
  78. recipe = {
  79. {string.format('vines:%irope_block', multiple)}
  80. }
  81. })
  82. end
  83. --]]
  84. end
  85. --creates rope blocks with length multiples 1-5.
  86. --second parameter sets how many pixels wide the rope texture is
  87. register_rope_block(1, 4)
  88. register_rope_block(2, 8)
  89. register_rope_block(3, 10)
  90. register_rope_block(4, 10)
  91. register_rope_block(5, 12)
  92. minetest.register_node("vines:rope", {
  93. description = "Rope",
  94. walkable = false,
  95. climbable = true,
  96. sunlight_propagates = true,
  97. paramtype = "light",
  98. drop = "",
  99. tiles = { "vines_rope.png" },
  100. drawtype = "plantlike",
  101. groups = utility.dig_groups("ignore", {flammable=2, not_in_creative_inventory=1, always_stable=1}),
  102. sounds = default.node_sound_leaves_defaults(),
  103. selection_box = {
  104. type = "fixed",
  105. fixed = {-1/7, -1/2, -1/7, 1/7, 1/2, 1/7},
  106. },
  107. movement_speed_multiplier = default.ROPE_SPEED,
  108. -- If rope has broken (middle rope piece with no middle or bottom piece below)
  109. -- then repair rope on punch.
  110. on_punch = function(pos, node, puncher, pt)
  111. local above = {x=pos.x, y=pos.y+1, z=pos.z}
  112. local n = minetest.get_node(above)
  113. if (string.find(n.name, "^vines:") and string.find(n.name, "rope_block$")) or n.name == "vines:rope" then
  114. -- Nothing.
  115. else
  116. -- No ropeblock above and no rope-middle-section, need to destroy rope!
  117. vines.destroy_rope_starting(pos, 'vines:rope', 'vines:rope_bottom', 'vines:rope_top')
  118. return
  119. end
  120. local under = {x=pos.x, y=pos.y-1, z=pos.z}
  121. local n = minetest.get_node(under)
  122. if n.name ~= "vines:rope" and n.name ~= "vines:rope_bottom" then
  123. minetest.swap_node(pos, {name="vines:rope_bottom"}) -- Do not erase meta.
  124. local timer = minetest.get_node_timer( pos )
  125. timer:start( rope_timer_rate )
  126. return
  127. end
  128. end,
  129. -- This is not called when rope is destroyed via voxelmanip.
  130. after_destruct = function(pos, oldnode)
  131. local p = {x=pos.x, y=pos.y-1, z=pos.z}
  132. vines.destroy_rope_starting(p, 'vines:rope', 'vines:rope_bottom', 'vines:rope_top')
  133. end,
  134. })
  135. minetest.register_node("vines:rope_bottom", {
  136. description = "Rope",
  137. walkable = true,
  138. climbable = true,
  139. sunlight_propagates = true,
  140. paramtype = "light",
  141. drop = "",
  142. tiles = { "vines_rope_bottom.png" },
  143. drawtype = "plantlike",
  144. groups = utility.dig_groups("ignore", {flammable=2, not_in_creative_inventory=1, always_stable=1}),
  145. sounds = default.node_sound_leaves_defaults(),
  146. selection_box = {
  147. type = "fixed",
  148. fixed = {-1/7, -1/2, -1/7, 1/7, 1/2, 1/7},
  149. },
  150. -- The bottom node has a collision box so that the player doesn't fall off the
  151. -- end when sliding downwards in darkness.
  152. collision_box = {
  153. type = "fixed",
  154. fixed = {-0.3, -0.5, -0.3, 0.3, -0.4, 0.3},
  155. },
  156. movement_speed_multiplier = default.ROPE_SPEED,
  157. on_construct = function( pos )
  158. local timer = minetest.get_node_timer( pos )
  159. timer:start( rope_timer_rate )
  160. end,
  161. on_timer = function( pos, elapsed )
  162. local currentend = minetest.get_node(pos)
  163. local currentmeta = minetest.get_meta(pos)
  164. local currentlength = currentmeta:get_int("length_remaining")
  165. local p = {x=pos.x, y=pos.y-1, z=pos.z}
  166. local n = minetest.get_node(p)
  167. if n.name == "air" and (currentlength > 1) then
  168. minetest.add_node(p, {name="vines:rope_bottom"})
  169. local newmeta = minetest.get_meta(p)
  170. newmeta:set_int("length_remaining", currentlength-1)
  171. newmeta:mark_as_private("length_remaining")
  172. minetest.swap_node(pos, {name="vines:rope"}) -- Do not erase meta.
  173. -- Check if there is another rope-middle node below, if so, combine ropes.
  174. local p2 = {x=pos.x, y=pos.y-2, z=pos.z}
  175. local n2 = minetest.get_node(p2)
  176. if n2.name == "vines:rope" then
  177. -- We have to swap the bottom node for a middle node, otherwise
  178. -- there will be a strangely collision box blockage in the middle of the rope
  179. -- for no apparent reason.
  180. minetest.swap_node(p, {name="vines:rope"}) -- Do not erase meta.
  181. end
  182. end
  183. end,
  184. -- If rope has fallen asleep, you can wake it up with a punch.
  185. on_punch = function(pos, node, puncher, pt)
  186. if not puncher or not puncher:is_player() then
  187. return
  188. end
  189. -- If the rope is protected, don't extend the rope any further.
  190. -- This lets players use ropes as secure entrances to forts.
  191. -- That is, only owner can let rope down, others cannot let it down.
  192. local pname = puncher:get_player_name()
  193. if minetest.test_protection(pos, pname) then
  194. return
  195. end
  196. local timer = minetest.get_node_timer( pos )
  197. timer:start( rope_timer_rate )
  198. end,
  199. })
  200. -- The top-rope-node is placed only when rope is being destroyed!
  201. minetest.register_node("vines:rope_top", {
  202. description = "Rope",
  203. walkable = false,
  204. climbable = true,
  205. sunlight_propagates = true,
  206. paramtype = "light",
  207. drop = "",
  208. tiles = { "vines_rope_top.png" },
  209. drawtype = "plantlike",
  210. groups = utility.dig_groups("ignore", {not_in_creative_inventory=1, always_stable=1}),
  211. sounds = default.node_sound_leaves_defaults(),
  212. selection_box = {
  213. type = "fixed",
  214. fixed = {-1/7, -1/2, -1/7, 1/7, 1/2, 1/7},
  215. },
  216. movement_speed_multiplier = default.ROPE_SPEED,
  217. on_construct = function( pos )
  218. local timer = minetest.get_node_timer( pos )
  219. timer:start( rope_timer_rate )
  220. end,
  221. on_timer = function( pos, elapsed )
  222. local p = {x=pos.x, y=pos.y-1, z=pos.z}
  223. local n = minetest.get_node(p)
  224. if (n.name ~= "ignore") then
  225. vines.destroy_rope_starting(p, 'vines:rope', 'vines:rope_bottom', 'vines:rope_top')
  226. minetest.add_node(pos, {name="air"})
  227. else
  228. local timer = minetest.get_node_timer( pos )
  229. timer:start( 3.0 )
  230. end
  231. end
  232. })