ropeboxes.lua 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. -- internationalization boilerplate
  2. local MP = minetest.get_modpath(minetest.get_current_modname())
  3. local S, NS = dofile(MP.."/intllib.lua")
  4. local function rope_box_tiles(count, tint)
  5. return {
  6. string.format("ropes_ropebox_front_%i.png^[colorize:%s^ropes_ropebox_front_%i.png^ropes_%i.png", count, tint, count, count),
  7. string.format("ropes_ropebox_front_%i.png^[colorize:%s^ropes_ropebox_front_%i.png^ropes_%i.png", count, tint, count, count),
  8. string.format("ropes_ropebox_side.png^[colorize:%s^ropes_ropebox_side.png", tint),
  9. string.format("ropes_ropebox_side.png^[colorize:%s^ropes_ropebox_side.png", tint),
  10. string.format("ropes_ropebox_front_%i.png^[colorize:%s^ropes_ropebox_front_%i.png^ropes_%i.png", count, tint, count, count),
  11. string.format("ropes_ropebox_front_%i.png^[colorize:%s^ropes_ropebox_front_%i.png^ropes_%i.png", count, tint, count, count),
  12. }
  13. end
  14. local rope_box_data = {
  15. {
  16. node={
  17. {-0.125, -0.125, -0.25, 0.125, 0.125, 0.25}, -- pulley
  18. {-0.125, -0.25, -0.125, 0.125, 0.25, 0.125}, -- pulley
  19. {-0.125, -0.1875, -0.1875, 0.125, 0.1875, 0.1875}, -- pulley_core
  20. {-0.1875, -0.5, -0.125, -0.125, 0.125, 0.125}, -- support
  21. {0.125, -0.5, -0.125, 0.1875, 0.125, 0.125}, -- support
  22. },
  23. --selection = {-0.1875, -0.5, -0.25, 0.1875, 0.25, 0.25}, -- selection
  24. tiles = 1,
  25. },
  26. {
  27. node={
  28. {-0.1875, -0.125, -0.25, 0.1875, 0.125, 0.25}, -- pulley
  29. {-0.1875, -0.25, -0.125, 0.1875, 0.25, 0.125}, -- pulley
  30. {-0.1875, -0.1875, -0.1875, 0.1875, 0.1875, 0.1875}, -- pulley_core
  31. {-0.25, -0.5, -0.125, -0.1875, 0.125, 0.125}, -- support
  32. {0.1875, -0.5, -0.125, 0.25, 0.125, 0.125}, -- support
  33. },
  34. --selection = {-0.1875, -0.5, -0.25, 0.1875, 0.25, 0.25}, -- selection
  35. tiles = 2,
  36. },
  37. {
  38. node={
  39. {-0.25, -0.125, -0.25, 0.25, 0.125, 0.25}, -- pulley
  40. {-0.25, -0.25, -0.125, 0.25, 0.25, 0.125}, -- pulley
  41. {-0.25, -0.1875, -0.1875, 0.25, 0.1875, 0.1875}, -- pulley_core
  42. {-0.3125, -0.5, -0.125, -0.25, 0.125, 0.125}, -- support
  43. {0.25, -0.5, -0.125, 0.3125, 0.125, 0.125}, -- support
  44. },
  45. --selection = {-0.3125, -0.5, -0.25, 0.3125, 0.25, 0.25}, -- selection
  46. tiles = 3,
  47. },
  48. {
  49. node={
  50. {-0.3125, -0.125, -0.25, 0.3125, 0.125, 0.25}, -- pulley
  51. {-0.3125, -0.25, -0.125, 0.3125, 0.25, 0.125}, -- pulley
  52. {-0.3125, -0.1875, -0.1875, 0.3125, 0.1875, 0.1875}, -- pulley_core
  53. {-0.375, -0.5, -0.125, -0.3125, 0.125, 0.125}, -- support
  54. {0.3125, -0.5, -0.125, 0.375, 0.125, 0.125}, -- support
  55. },
  56. --selection = {-0.375, -0.5, -0.25, 0.375, 0.25, 0.25}, -- selection
  57. tiles = 4,
  58. },
  59. {
  60. node={
  61. {-0.375, -0.125, -0.25, 0.375, 0.125, 0.25}, -- pulley
  62. {-0.375, -0.25, -0.125, 0.375, 0.25, 0.125}, -- pulley
  63. {-0.375, -0.1875, -0.1875, 0.375, 0.1875, 0.1875}, -- pulley_core
  64. {-0.4375, -0.5, -0.125, -0.375, 0.125, 0.125}, -- support
  65. {0.375, -0.5, -0.125, 0.4375, 0.125, 0.125}, -- support
  66. },
  67. --selection = {-0.4375, -0.5, -0.25, 0.4375, 0.25, 0.25}, -- selection
  68. tiles = 5,
  69. },
  70. {
  71. node={
  72. {-0.1875, -0.1875, -0.3125, 0.1875, 0.1875, 0.3125}, -- pulley
  73. {-0.1875, -0.3125, -0.1875, 0.1875, 0.3125, 0.1875}, -- pulley
  74. {-0.1875, -0.25, -0.25, 0.1875, 0.25, 0.25}, -- pulley_core
  75. {-0.25, -0.5, -0.125, -0.1875, 0.125, 0.125}, -- support
  76. {0.1875, -0.5, -0.125, 0.25, 0.125, 0.125}, -- support
  77. },
  78. --selection = {-0.1875, -0.5, -0.3125, 0.1875, 0.3125, 0.3125}, -- selection
  79. tiles = 2,
  80. },
  81. {
  82. node={
  83. {-0.25, -0.1875, -0.3125, 0.25, 0.1875, 0.3125}, -- pulley
  84. {-0.25, -0.3125, -0.1875, 0.25, 0.3125, 0.1875}, -- pulley
  85. {-0.25, -0.25, -0.25, 0.25, 0.25, 0.25}, -- pulley_core
  86. {-0.3125, -0.5, -0.125, -0.25, 0.125, 0.125}, -- support
  87. {0.25, -0.5, -0.125, 0.3125, 0.125, 0.125}, -- support
  88. },
  89. --selection = {-0.3125, -0.5, -0.3125, 0.3125, 0.3125, 0.3125}, -- selection
  90. tiles = 3,
  91. },
  92. {
  93. node={
  94. {-0.3125, -0.1875, -0.3125, 0.3125, 0.1875, 0.3125}, -- pulley
  95. {-0.3125, -0.3125, -0.1875, 0.3125, 0.3125, 0.1875}, -- pulley
  96. {-0.3125, -0.25, -0.25, 0.3125, 0.25, 0.25}, -- pulley_core
  97. {-0.375, -0.5, -0.125, -0.3125, 0.125, 0.125}, -- support
  98. {0.3125, -0.5, -0.125, 0.375, 0.125, 0.125}, -- support
  99. },
  100. --selection = {-0.375, -0.5, -0.3125, 0.375, 0.3125, 0.3125}, -- selection
  101. tiles = 4,
  102. },
  103. {
  104. node={
  105. {-0.375, -0.1875, -0.3125, 0.375, 0.1875, 0.3125}, -- pulley
  106. {-0.375, -0.3125, -0.1875, 0.375, 0.3125, 0.1875}, -- pulley
  107. {-0.375, -0.25, -0.25, 0.375, 0.25, 0.25}, -- pulley_core
  108. {-0.4375, -0.5, -0.125, -0.375, 0.125, 0.125}, -- support
  109. {0.375, -0.5, -0.125, 0.4375, 0.125, 0.125}, -- support
  110. },
  111. --selection_bottom = {-0.4375, -0.5, -0.3125, 0.4375, 0.3125, 0.3125}, -- selection
  112. tiles = 5,
  113. }
  114. }
  115. local function register_rope_block(multiple, max_multiple, name_prefix, node_prefix, tint, flammable)
  116. local node_name = string.format("ropes:%s%irope_block", node_prefix, multiple)
  117. local rope_block_def = {
  118. description = S("@1 Ropebox @2m", name_prefix, ropes.ropeLength*multiple),
  119. _doc_items_create_entry = false,
  120. drawtype="nodebox",
  121. sunlight_propagates = true,
  122. paramtype = "light",
  123. paramtype2 = "wallmounted",
  124. walkable = false,
  125. climbable = true,
  126. tiles = rope_box_tiles(rope_box_data[multiple].tiles, tint),
  127. node_box = {
  128. type = "fixed",
  129. fixed = rope_box_data[multiple].node
  130. },
  131. selection_box = {type="regular"},
  132. collision_box = {type="regular"},
  133. groups = {choppy=2, oddly_breakable_by_hand=1, rope_block = 1},
  134. on_place = function(itemstack, placer, pointed_thing)
  135. if pointed_thing.type == "node" then
  136. local target_node = minetest.get_node(pointed_thing.under)
  137. local target_def = minetest.registered_nodes[target_node.name]
  138. if target_def.walkable == false then
  139. return itemstack
  140. end
  141. end
  142. return minetest.item_place(itemstack, placer, pointed_thing)
  143. end,
  144. after_place_node = function(pos, placer)
  145. local pos_below = {x=pos.x, y=pos.y-1, z=pos.z}
  146. local placer_name = placer:get_player_name()
  147. if minetest.is_protected(pos_below, placer_name) and not minetest.check_player_privs(placer, "protection_bypass") then
  148. return
  149. end
  150. local node_below = minetest.get_node(pos_below)
  151. if node_below.name == "air" then
  152. minetest.add_node(pos_below, {name="ropes:rope_bottom"})
  153. local meta = minetest.get_meta(pos_below)
  154. meta:set_int("length_remaining", ropes.ropeLength*multiple)
  155. meta:set_string("placer", placer:get_player_name())
  156. end
  157. end,
  158. after_destruct = function(pos)
  159. local pos_below = {x=pos.x, y=pos.y-1, z=pos.z}
  160. ropes.destroy_rope(pos_below, {'ropes:rope', 'ropes:rope_bottom'})
  161. end
  162. }
  163. -- If this number is higher than permitted, we still want to register the block (in case
  164. -- some were already placed in-world) but we want to hide it from creative inventory
  165. -- and if someone digs it we want to disintegrate it into its component parts to prevent
  166. -- reuse.
  167. if multiple > max_multiple then
  168. rope_block_def.groups.not_in_creative_inventory = 1
  169. rope_block_def.drop = string.format("ropes:%s1rope_block %i", node_prefix, multiple)
  170. end
  171. if flammable then
  172. rope_block_def.groups.flammable = flammable
  173. minetest.register_craft({
  174. type = "fuel",
  175. recipe = node_name,
  176. burntime = ropes.rope_burn_time * multiple + ropes.wood_burn_time,
  177. })
  178. end
  179. minetest.register_node(node_name, rope_block_def)
  180. if (multiple ~= 1) then
  181. -- Only register a recipe to craft this if it's within the permitted multiple range
  182. if multiple <= max_multiple then
  183. for i = 1, multiple-1 do
  184. local rec = {string.format("ropes:%s%irope_block", node_prefix, i)}
  185. for n = 1, multiple-i do
  186. table.insert(rec, "ropes:ropesegment")
  187. end
  188. minetest.register_craft({
  189. output = node_name,
  190. type = "shapeless",
  191. recipe = rec
  192. })
  193. end
  194. end
  195. -- Always allow players to disintegrate this into component parts, in case
  196. -- there were some in inventory and the setting was changed.
  197. minetest.register_craft({
  198. output = "ropes:ropesegment",
  199. type = "shapeless",
  200. recipe = {
  201. node_name
  202. },
  203. replacements = {
  204. {node_name, string.format('ropes:%s%irope_block', node_prefix, multiple-1)},
  205. },
  206. })
  207. end
  208. if minetest.get_modpath("doc") then
  209. doc.add_entry_alias("nodes", "ropes:rope", "nodes", node_name)
  210. end
  211. end
  212. local rope_def = {
  213. description = S("Rope"),
  214. _doc_items_longdesc = ropes.doc.ropebox_longdesc,
  215. _doc_items_usagehelp = ropes.doc.ropebox_usage,
  216. walkable = false,
  217. climbable = true,
  218. sunlight_propagates = true,
  219. paramtype = "light",
  220. drop = "",
  221. tiles = { "ropes_3.png", "ropes_3.png", "ropes_3.png", "ropes_3.png", "ropes_5.png", "ropes_5.png" },
  222. groups = {choppy=2, flammable=2, not_in_creative_inventory=1},
  223. sounds = {
  224. footstep = {name = "ropes_creak", gain = 0.8, max_hear_distance = 6},
  225. dig = "__group",
  226. dug = "__group",
  227. },
  228. drawtype = "nodebox",
  229. node_box = {
  230. type = "connected",
  231. fixed = {-1/16, -1/2, -1/16, 1/16, 1/2, 1/16},
  232. connect_top = {-1/16, 1/2, -1/16, 1/16, 3/4, 1/16}
  233. },
  234. connects_to = {"group:rope_block"},
  235. connect_sides = {"top"},
  236. selection_box = {
  237. type = "fixed",
  238. fixed = {-1/8, -1/2, -1/8, 1/8, 1/2, 1/8},
  239. },
  240. after_destruct = function(pos)
  241. ropes.hanging_after_destruct(pos, "ropes:rope_top", "ropes:rope", "ropes:rope_bottom")
  242. end,
  243. }
  244. local rope_extension_timer = ropes.make_rope_on_timer("ropes:rope")
  245. local rope_bottom_def = {
  246. description = S("Rope"),
  247. _doc_items_create_entry = false,
  248. walkable = false,
  249. climbable = true,
  250. sunlight_propagates = true,
  251. paramtype = "light",
  252. drop = "",
  253. tiles = { "ropes_3.png", "ropes_3.png", "ropes_3.png", "ropes_3.png", "ropes_5.png", "ropes_5.png" },
  254. drawtype = "nodebox",
  255. groups = {choppy=2, flammable=2, not_in_creative_inventory=1},
  256. sounds = {
  257. footstep = {name = "ropes_creak", gain = 0.8, max_hear_distance = 6},
  258. dig = "__group",
  259. dug = "__group",
  260. },
  261. node_box = {
  262. type = "connected",
  263. fixed = {
  264. {-1/16, -3/8, -1/16, 1/16, 1/2, 1/16},
  265. {-2/16, -5/16, -2/16, 2/16, -1/16, 2/16},
  266. },
  267. connect_top = {-1/16, 1/2, -1/16, 1/16, 3/4, 1/16}
  268. },
  269. connects_to = {"group:rope_block"},
  270. connect_sides = {"top"},
  271. selection_box = {
  272. type = "fixed",
  273. fixed = {-1/8, -1/2, -1/8, 1/8, 1/2, 1/8},
  274. },
  275. on_construct = function( pos )
  276. local timer = minetest.get_node_timer( pos )
  277. timer:start( 1 )
  278. end,
  279. on_timer = rope_extension_timer,
  280. after_destruct = function(pos)
  281. ropes.hanging_after_destruct(pos, "ropes:rope_top", "ropes:rope", "ropes:rope_bottom")
  282. end,
  283. on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
  284. -- sometimes it just stops, tug on the end to restart the timer
  285. local timer = minetest.get_node_timer(pos)
  286. if timer:get_timeout() == 0 then
  287. -- timer is stopped, start it again
  288. timer:start(1)
  289. end
  290. end,
  291. }
  292. minetest.register_node("ropes:rope", rope_def)
  293. minetest.register_node("ropes:rope_bottom", rope_bottom_def)
  294. if ropes.woodRopeBoxMaxMultiple > 0 or ropes.create_all_definitions then
  295. if ropes.woodRopeBoxMaxMultiple > 0 then
  296. minetest.register_craft({
  297. output = "ropes:wood1rope_block",
  298. recipe = {
  299. {'group:wood'},
  300. {'group:vines'}
  301. }
  302. })
  303. end
  304. for i = 1,9 do
  305. if ropes.woodRopeBoxMaxMultiple >= i or ropes.create_all_definitions then
  306. register_rope_block(i, ropes.woodRopeBoxMaxMultiple, S("Wood"), "wood", "#86683a", 2)
  307. end
  308. end
  309. end
  310. if ropes.copperRopeBoxMaxMultiple > 0 or ropes.create_all_definitions then
  311. if ropes.copperRopeBoxMaxMultiple > 0 then
  312. minetest.register_craft({
  313. output = "ropes:copper1rope_block",
  314. recipe = {
  315. {'default:copper_ingot'},
  316. {'group:vines'}
  317. }
  318. })
  319. end
  320. for i = 1,9 do
  321. if ropes.copperRopeBoxMaxMultiple >= i or ropes.create_all_definitions then
  322. register_rope_block(i, ropes.copperRopeBoxMaxMultiple, S("Copper"), "copper", "#c88648")
  323. end
  324. end
  325. end
  326. if ropes.steelRopeBoxMaxMultiple > 0 or ropes.create_all_definitions then
  327. if ropes.steelRopeBoxMaxMultiple > 0 then
  328. minetest.register_craft({
  329. output = "ropes:steel1rope_block",
  330. recipe = {
  331. {'default:steel_ingot'},
  332. {'group:vines'}
  333. }
  334. })
  335. end
  336. for i = 1,9 do
  337. if ropes.steelRopeBoxMaxMultiple >= i or ropes.create_all_definitions then
  338. register_rope_block(i, ropes.steelRopeBoxMaxMultiple, S("Steel"), "steel", "#ffffff")
  339. end
  340. end
  341. end