init.lua 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. -- Localize for performance.
  2. local math_random = math.random
  3. -- function to safely remove climbable air
  4. local function remove_air(pos, oldnode)
  5. local dir = minetest.facedir_to_dir(oldnode.param2)
  6. local airpos = vector.subtract(pos, dir)
  7. local north_node = minetest.get_node({x = airpos.x, y = airpos.y, z = airpos.z+1})
  8. local south_node = minetest.get_node({x = airpos.x, y = airpos.y, z = airpos.z-1})
  9. local east_node = minetest.get_node({x = airpos.x+1, y = airpos.y, z = airpos.z})
  10. local west_node = minetest.get_node({x = airpos.x-1, y = airpos.y, z = airpos.z})
  11. local keep_air =
  12. (minetest.get_item_group(north_node.name, "handholds") == 1 and
  13. north_node.param2 == 0) or
  14. (minetest.get_item_group(south_node.name, "handholds") == 1 and
  15. south_node.param2 == 2) or
  16. (minetest.get_item_group(east_node.name, "handholds") == 1 and
  17. east_node.param2 == 1) or
  18. (minetest.get_item_group(west_node.name, "handholds") == 1 and
  19. west_node.param2 == 3)
  20. if not keep_air then
  21. minetest.add_node(airpos, {name = "air"})
  22. end
  23. end
  24. -- remove handholds from nodes buried under falling nodes
  25. local function remove_handholds(pos)
  26. local north_pos = {x = pos.x, y = pos.y, z = pos.z+1}
  27. local south_pos = {x = pos.x, y = pos.y, z = pos.z-1}
  28. local east_pos = {x = pos.x+1, y = pos.y, z = pos.z}
  29. local west_pos = {x = pos.x-1, y = pos.y, z = pos.z}
  30. local north_node = minetest.get_node(north_pos)
  31. local south_node = minetest.get_node(south_pos)
  32. local east_node = minetest.get_node(east_pos)
  33. local west_node = minetest.get_node(west_pos)
  34. local node_pos
  35. if minetest.get_item_group(north_node.name, "handholds") == 1 and
  36. north_node.param2 == 0 then
  37. node_pos = north_pos
  38. elseif minetest.get_item_group(south_node.name, "handholds") == 1 and
  39. south_node.param2 == 2 then
  40. node_pos = south_pos
  41. elseif minetest.get_item_group(east_node.name, "handholds") == 1 and
  42. east_node.param2 == 1 then
  43. node_pos = east_pos
  44. elseif minetest.get_item_group(west_node.name, "handholds") == 1 and
  45. west_node.param2 == 3 then
  46. node_pos = west_pos
  47. end
  48. if node_pos then
  49. --local handholds_node = string.split(minetest.get_node(node_pos).name, ":")
  50. local nn = minetest.get_node(node_pos).name
  51. local def = minetest.registered_items[nn]
  52. if def and def._handholds_original then
  53. minetest.add_node(node_pos, {name = def._handholds_original})
  54. end
  55. end
  56. end
  57. -- climbable air!
  58. minetest.register_node("handholds:climbable_air", {
  59. description = "Air!",
  60. drawtype = "airlike",
  61. paramtype = "light",
  62. sunlight_propagates = true,
  63. walkable = false,
  64. pointable = false,
  65. diggable = false,
  66. climbable = true,
  67. buildable_to = true,
  68. floodable = true,
  69. drop = "",
  70. groups = {not_in_creative_inventory = 1},
  71. sounds = default.node_sound_stone_defaults(),
  72. on_destruct = function(pos)
  73. remove_handholds(pos)
  74. end,
  75. on_flood = function(pos)
  76. remove_handholds(pos)
  77. end,
  78. -- Player should not be able to obtain node.
  79. on_finish_collapse = function(pos, node)
  80. minetest.remove_node(pos)
  81. end,
  82. on_collapse_to_entity = function(pos, node)
  83. -- Do nothing.
  84. end,
  85. })
  86. -- handholds nodes
  87. minetest.register_node("handholds:stone", {
  88. description = "Stone Handholds",
  89. tiles = {
  90. "default_stone.png", "default_stone.png",
  91. "default_stone.png", "default_stone.png",
  92. "default_stone.png", "default_stone.png^handholds_holds.png"
  93. },
  94. paramtype2 = "facedir",
  95. on_rotate = function()
  96. return false
  97. end,
  98. groups = utility.dig_groups("stone", {not_in_creative_inventory = 1, handholds = 1}),
  99. drop = 'default:cobble',
  100. sounds = default.node_sound_stone_defaults(),
  101. after_destruct = function(pos, oldnode)
  102. remove_air(pos, oldnode)
  103. end,
  104. _handholds_original = "default:stone",
  105. })
  106. minetest.register_node("handholds:desert_stone", {
  107. description = "Desert Stone Handholds",
  108. tiles = {
  109. "default_desert_stone.png", "default_desert_stone.png",
  110. "default_desert_stone.png", "default_desert_stone.png",
  111. "default_desert_stone.png", "default_desert_stone.png^handholds_holds.png"
  112. },
  113. paramtype2 = "facedir",
  114. on_rotate = function()
  115. return false
  116. end,
  117. groups = utility.dig_groups("stone", {not_in_creative_inventory = 1, handholds = 1}),
  118. drop = 'default:desert_cobble2',
  119. sounds = default.node_sound_stone_defaults(),
  120. after_destruct = function(pos, oldnode)
  121. remove_air(pos, oldnode)
  122. end,
  123. _handholds_original = "default:desert_stone",
  124. })
  125. minetest.register_node("handholds:sandstone", {
  126. description = "Sandstone Handholds",
  127. tiles = {
  128. "default_sandstone.png", "default_sandstone.png",
  129. "default_sandstone.png", "default_sandstone.png",
  130. "default_sandstone.png", "default_sandstone.png^handholds_holds.png"
  131. },
  132. paramtype2 = "facedir",
  133. on_rotate = function()
  134. return false
  135. end,
  136. groups = utility.dig_groups("softstone", {not_in_creative_inventory = 1, handholds = 1}),
  137. drop = 'default:sandstone',
  138. sounds = default.node_sound_stone_defaults(),
  139. after_destruct = function(pos, oldnode)
  140. remove_air(pos, oldnode)
  141. end,
  142. _handholds_original = "default:sandstone",
  143. })
  144. minetest.register_node("handholds:ice", {
  145. description = "Ice Handholds",
  146. tiles = {
  147. "default_ice.png", "default_ice.png",
  148. "default_ice.png", "default_ice.png",
  149. "default_ice.png", "default_ice.png^handholds_holds.png"
  150. },
  151. paramtype2 = "facedir",
  152. on_rotate = function()
  153. return false
  154. end,
  155. groups = utility.dig_groups("ice", {
  156. puts_out_fire = 1, cools_lava = 1,
  157. not_in_creative_inventory = 1, handholds = 1
  158. }),
  159. drop = 'default:ice',
  160. sounds = default.node_sound_glass_defaults(),
  161. after_destruct = function(pos, oldnode)
  162. remove_air(pos, oldnode)
  163. end,
  164. _handholds_original = "default:ice",
  165. on_construct = function(pos)
  166. if rc.ice_melts_at_pos(pos) then
  167. minetest.get_node_timer(pos):start(math_random(ice.minmax_time()))
  168. end
  169. end,
  170. on_timer = function(pos, elapsed)
  171. if rc.ice_melts_at_pos(pos) then
  172. minetest.add_node(pos, {name="default:water_flowing"})
  173. end
  174. end,
  175. })
  176. minetest.register_node("handholds:rackstone", {
  177. description = "Rackstone Handholds",
  178. tiles = {
  179. "rackstone_rackstone.png", "rackstone_rackstone.png",
  180. "rackstone_rackstone.png", "rackstone_rackstone.png",
  181. "rackstone_rackstone.png", "rackstone_rackstone.png^handholds_holds_dark.png"
  182. },
  183. paramtype2 = "facedir",
  184. groups = utility.dig_groups("stone", {handholds=1}),
  185. sounds = default.node_sound_stone_defaults(),
  186. drop = 'rackstone:rackstone',
  187. on_rotate = function()
  188. return false
  189. end,
  190. after_destruct = function(pos, oldnode)
  191. remove_air(pos, oldnode)
  192. rackstone.destabilize_dauthsand(pos)
  193. end,
  194. _handholds_original = "rackstone:rackstone",
  195. })
  196. minetest.register_node("handholds:redrack", {
  197. description = "Netherack Handholds",
  198. tiles = {
  199. "rackstone_redrack.png", "rackstone_redrack.png",
  200. "rackstone_redrack.png", "rackstone_redrack.png",
  201. "rackstone_redrack.png", "rackstone_redrack.png^handholds_holds_very_dark.png"
  202. },
  203. paramtype2 = "facedir",
  204. groups = utility.dig_groups("netherack", {handholds=1}),
  205. sounds = rackstone.rackstone_sounds(),
  206. drop = 'rackstone:redrack',
  207. on_rotate = function()
  208. return false
  209. end,
  210. after_destruct = function(pos, oldnode)
  211. remove_air(pos, oldnode)
  212. rackstone.after_redrack_remove(pos, oldnode)
  213. rackstone.destabilize_dauthsand(pos, oldnode)
  214. end,
  215. on_construct = function(pos)
  216. rackstone.on_redrack_place(pos)
  217. end,
  218. _handholds_original = "rackstone:redrack",
  219. })
  220. -- handholds tool
  221. minetest.register_tool("handholds:climbing_pick", {
  222. description = "Climbing Pick",
  223. inventory_image = "handholds_tool.png",
  224. sound = {breaks = "default_tool_breaks"},
  225. on_use = function(itemstack, player, pointed_thing)
  226. if not pointed_thing or
  227. pointed_thing.type ~= "node" or
  228. minetest.is_protected(pointed_thing.under, player:get_player_name()) or
  229. minetest.is_protected(pointed_thing.above, player:get_player_name()) or
  230. pointed_thing.under.y + 1 == pointed_thing.above.y or
  231. pointed_thing.under.y - 1 == pointed_thing.above.y then
  232. return
  233. end
  234. local node_def =
  235. minetest.reg_ns_nodes[minetest.get_node(pointed_thing.above).name]
  236. if not node_def or not node_def.buildable_to then
  237. return
  238. end
  239. local node_name = minetest.get_node(pointed_thing.under).name
  240. local rotation = minetest.dir_to_facedir(
  241. vector.subtract(pointed_thing.under, pointed_thing.above))
  242. if node_name == "default:stone" then
  243. minetest.add_node(pointed_thing.under,
  244. {name = "handholds:stone", param2 = rotation})
  245. elseif node_name == "default:desert_stone" then
  246. minetest.add_node(pointed_thing.under,
  247. {name = "handholds:desert_stone", param2 = rotation})
  248. elseif node_name == "default:sandstone" then
  249. minetest.add_node(pointed_thing.under,
  250. {name = "handholds:sandstone", param2 = rotation})
  251. elseif node_name == "default:ice" then
  252. minetest.add_node(pointed_thing.under,
  253. {name = "handholds:ice", param2 = rotation})
  254. elseif node_name == "rackstone:rackstone" or node_name == "rackstone:mg_rackstone" then
  255. minetest.add_node(pointed_thing.under,
  256. {name = "handholds:rackstone", param2 = rotation})
  257. elseif node_name == "rackstone:redrack" or node_name == "rackstone:mg_redrack" then
  258. minetest.add_node(pointed_thing.under,
  259. {name = "handholds:redrack", param2 = rotation})
  260. else
  261. return
  262. end
  263. minetest.add_node(pointed_thing.above, {name = "handholds:climbable_air"})
  264. ambiance.sound_play("default_dig_cracky", pointed_thing.above, 0.5, 30)
  265. if not minetest.setting_getbool("creative_mode") then
  266. local wdef = itemstack:get_definition()
  267. itemstack:add_wear(256)
  268. if itemstack:get_count() == 0 and wdef.sound and wdef.sound.breaks then
  269. minetest.sound_play(wdef.sound.breaks,
  270. {pos = pointed_thing.above, gain = 0.5})
  271. end
  272. return itemstack
  273. end
  274. end
  275. })
  276. minetest.register_craft({
  277. output = "handholds:climbing_pick",
  278. recipe = {
  279. {'default:diamond', 'default:diamond', 'default:diamond'},
  280. {'group:stick', '', ''},
  281. {'group:stick', '', ''},
  282. },
  283. })