ropeboxes.lua 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  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. light_source = 1,
  104. selection_box = {
  105. type = "fixed",
  106. fixed = {-1/7, -1/2, -1/7, 1/7, 1/2, 1/7},
  107. },
  108. movement_speed_multiplier = default.ROPE_SPEED,
  109. _no_collapse_on_walkover = true,
  110. -- If rope has broken (middle rope piece with no middle or bottom piece below)
  111. -- then repair rope on punch.
  112. on_punch = function(pos, node, puncher, pt)
  113. local above = {x=pos.x, y=pos.y+1, z=pos.z}
  114. local n = minetest.get_node(above)
  115. if (string.find(n.name, "^vines:") and string.find(n.name, "rope_block$")) or n.name == "vines:rope" then
  116. -- Nothing.
  117. else
  118. -- No ropeblock above and no rope-middle-section, need to destroy rope!
  119. vines.destroy_rope_starting(pos, 'vines:rope', 'vines:rope_bottom', 'vines:rope_top')
  120. return
  121. end
  122. local under = {x=pos.x, y=pos.y-1, z=pos.z}
  123. local n = minetest.get_node(under)
  124. if n.name ~= "vines:rope" and n.name ~= "vines:rope_bottom" then
  125. minetest.swap_node(pos, {name="vines:rope_bottom"}) -- Do not erase meta.
  126. local timer = minetest.get_node_timer( pos )
  127. timer:start( rope_timer_rate )
  128. return
  129. end
  130. end,
  131. -- This is not called when rope is destroyed via voxelmanip.
  132. after_destruct = function(pos, oldnode)
  133. local p = {x=pos.x, y=pos.y-1, z=pos.z}
  134. vines.destroy_rope_starting(p, 'vines:rope', 'vines:rope_bottom', 'vines:rope_top')
  135. end,
  136. })
  137. minetest.register_node("vines:rope_bottom", {
  138. description = "Rope",
  139. walkable = true,
  140. climbable = true,
  141. sunlight_propagates = true,
  142. paramtype = "light",
  143. drop = "",
  144. tiles = { "vines_rope_bottom.png" },
  145. drawtype = "plantlike",
  146. groups = utility.dig_groups("ignore", {flammable=2, not_in_creative_inventory=1, always_stable=1}),
  147. sounds = default.node_sound_leaves_defaults(),
  148. selection_box = {
  149. type = "fixed",
  150. fixed = {-1/7, -1/2, -1/7, 1/7, 1/2, 1/7},
  151. },
  152. light_source = 1,
  153. -- The bottom node has a collision box so that the player doesn't fall off the
  154. -- end when sliding downwards in darkness.
  155. collision_box = {
  156. type = "fixed",
  157. fixed = {-0.3, -0.5, -0.3, 0.3, -0.4, 0.3},
  158. },
  159. movement_speed_multiplier = default.ROPE_SPEED,
  160. _no_collapse_on_walkover = true,
  161. on_construct = function( pos )
  162. local timer = minetest.get_node_timer( pos )
  163. timer:start( rope_timer_rate )
  164. end,
  165. on_timer = function( pos, elapsed )
  166. local currentend = minetest.get_node(pos)
  167. local currentmeta = minetest.get_meta(pos)
  168. local currentlength = currentmeta:get_int("length_remaining")
  169. local p = {x=pos.x, y=pos.y-1, z=pos.z}
  170. local n = minetest.get_node(p)
  171. if n.name == "air" and (currentlength > 1) then
  172. minetest.add_node(p, {name="vines:rope_bottom"})
  173. local newmeta = minetest.get_meta(p)
  174. newmeta:set_int("length_remaining", currentlength-1)
  175. newmeta:mark_as_private("length_remaining")
  176. minetest.swap_node(pos, {name="vines:rope"}) -- Do not erase meta.
  177. -- Check if there is another rope-middle node below, if so, combine ropes.
  178. local p2 = {x=pos.x, y=pos.y-2, z=pos.z}
  179. local n2 = minetest.get_node(p2)
  180. if n2.name == "vines:rope" then
  181. -- We have to swap the bottom node for a middle node, otherwise
  182. -- there will be a strangely collision box blockage in the middle of the rope
  183. -- for no apparent reason.
  184. minetest.swap_node(p, {name="vines:rope"}) -- Do not erase meta.
  185. end
  186. end
  187. end,
  188. -- If rope has fallen asleep, you can wake it up with a punch.
  189. on_punch = function(pos, node, puncher, pt)
  190. if not puncher or not puncher:is_player() then
  191. return
  192. end
  193. -- If the rope is protected, don't extend the rope any further.
  194. -- This lets players use ropes as secure entrances to forts.
  195. -- That is, only owner can let rope down, others cannot let it down.
  196. local pname = puncher:get_player_name()
  197. if minetest.test_protection(pos, pname) then
  198. return
  199. end
  200. local timer = minetest.get_node_timer( pos )
  201. timer:start( rope_timer_rate )
  202. end,
  203. })
  204. -- The top-rope-node is placed only when rope is being destroyed!
  205. minetest.register_node("vines:rope_top", {
  206. description = "Rope",
  207. walkable = false,
  208. climbable = true,
  209. sunlight_propagates = true,
  210. paramtype = "light",
  211. drop = "",
  212. tiles = { "vines_rope_top.png" },
  213. drawtype = "plantlike",
  214. groups = utility.dig_groups("ignore", {not_in_creative_inventory=1, always_stable=1}),
  215. sounds = default.node_sound_leaves_defaults(),
  216. light_source = 1,
  217. selection_box = {
  218. type = "fixed",
  219. fixed = {-1/7, -1/2, -1/7, 1/7, 1/2, 1/7},
  220. },
  221. movement_speed_multiplier = default.ROPE_SPEED,
  222. _no_collapse_on_walkover = true,
  223. on_construct = function( pos )
  224. local timer = minetest.get_node_timer( pos )
  225. timer:start( rope_timer_rate )
  226. end,
  227. on_timer = function( pos, elapsed )
  228. local p = {x=pos.x, y=pos.y-1, z=pos.z}
  229. local n = minetest.get_node(p)
  230. if (n.name ~= "ignore") then
  231. vines.destroy_rope_starting(p, 'vines:rope', 'vines:rope_bottom', 'vines:rope_top')
  232. minetest.add_node(pos, {name="air"})
  233. else
  234. local timer = minetest.get_node_timer( pos )
  235. timer:start( 3.0 )
  236. end
  237. end
  238. })