functions.lua 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. -- mods/default/functions.lua
  2. --
  3. -- Sounds
  4. --
  5. function default.node_sound_defaults(table)
  6. table = table or {}
  7. table.footstep = table.footstep or
  8. {name="", gain=1.0}
  9. table.dug = table.dug or
  10. {name="default_dug_node", gain=0.25}
  11. table.place = table.place or
  12. {name="default_place_node_hard", gain=1.0}
  13. return table
  14. end
  15. function default.node_sound_stone_defaults(table)
  16. table = table or {}
  17. table.footstep = table.footstep or
  18. {name="default_hard_footstep", gain=0.5}
  19. table.dug = table.dug or
  20. {name="default_hard_footstep", gain=1.0}
  21. default.node_sound_defaults(table)
  22. return table
  23. end
  24. function default.node_sound_dirt_defaults(table)
  25. table = table or {}
  26. table.footstep = table.footstep or
  27. {name="default_dirt_footstep", gain=1.0}
  28. table.dug = table.dug or
  29. {name="default_dirt_footstep", gain=1.5}
  30. table.place = table.place or
  31. {name="default_place_node", gain=1.0}
  32. default.node_sound_defaults(table)
  33. return table
  34. end
  35. function default.node_sound_sand_defaults(table)
  36. table = table or {}
  37. table.footstep = table.footstep or
  38. {name="default_sand_footstep", gain=0.2}
  39. table.dug = table.dug or
  40. {name="default_sand_footstep", gain=0.4}
  41. table.place = table.place or
  42. {name="default_place_node", gain=1.0}
  43. default.node_sound_defaults(table)
  44. return table
  45. end
  46. function default.node_sound_wood_defaults(table)
  47. table = table or {}
  48. table.footstep = table.footstep or
  49. {name="default_wood_footstep", gain=0.5}
  50. table.dug = table.dug or
  51. {name="default_wood_footstep", gain=1.0}
  52. default.node_sound_defaults(table)
  53. return table
  54. end
  55. function default.node_sound_leaves_defaults(table)
  56. table = table or {}
  57. table.footstep = table.footstep or
  58. {name="default_grass_footstep", gain=0.35}
  59. table.dug = table.dug or
  60. {name="default_grass_footstep", gain=0.7}
  61. table.dig = table.dig or
  62. {name="default_dig_crumbly", gain=0.4}
  63. table.place = table.place or
  64. {name="default_place_node", gain=1.0}
  65. default.node_sound_defaults(table)
  66. return table
  67. end
  68. function default.node_sound_glass_defaults(table)
  69. table = table or {}
  70. table.footstep = table.footstep or
  71. {name="default_glass_footstep", gain=0.5}
  72. table.dug = table.dug or
  73. {name="default_break_glass", gain=1.0}
  74. default.node_sound_defaults(table)
  75. return table
  76. end
  77. --
  78. -- Legacy
  79. --
  80. function default.spawn_falling_node(p, nodename)
  81. spawn_falling_node(p, nodename)
  82. end
  83. -- Horrible crap to support old code
  84. -- Don't use this and never do what this does, it's completely wrong!
  85. -- (More specifically, the client and the C++ code doesn't get the group)
  86. function default.register_falling_node(nodename, texture)
  87. minetest.log("error", debug.traceback())
  88. minetest.log('error', "WARNING: default.register_falling_node is deprecated")
  89. if minetest.registered_nodes[nodename] then
  90. minetest.registered_nodes[nodename].groups.falling_node = 1
  91. end
  92. end
  93. --
  94. -- Lavacooling
  95. --
  96. default.cool_lava_source = function(pos)
  97. minetest.set_node(pos, {name="default:obsidian"})
  98. minetest.sound_play("default_cool_lava", {pos = pos, gain = 0.25})
  99. end
  100. default.cool_lava_flowing = function(pos)
  101. minetest.set_node(pos, {name="default:stone"})
  102. minetest.sound_play("default_cool_lava", {pos = pos, gain = 0.25})
  103. end
  104. minetest.register_abm({
  105. nodenames = {"default:lava_flowing"},
  106. neighbors = {"group:water"},
  107. interval = 1,
  108. chance = 1,
  109. action = function(pos, node, active_object_count, active_object_count_wider)
  110. default.cool_lava_flowing(pos, node, active_object_count, active_object_count_wider)
  111. end,
  112. })
  113. minetest.register_abm({
  114. nodenames = {"default:lava_source"},
  115. neighbors = {"group:water"},
  116. interval = 1,
  117. chance = 1,
  118. action = function(pos, node, active_object_count, active_object_count_wider)
  119. default.cool_lava_source(pos, node, active_object_count, active_object_count_wider)
  120. end,
  121. })
  122. --
  123. -- Papyrus and cactus growing
  124. --
  125. minetest.register_abm({
  126. nodenames = {"default:cactus"},
  127. neighbors = {"group:sand"},
  128. interval = 50,
  129. chance = 20,
  130. action = function(pos, node)
  131. pos.y = pos.y-1
  132. local name = minetest.get_node(pos).name
  133. if minetest.get_item_group(name, "sand") ~= 0 then
  134. pos.y = pos.y+1
  135. local height = 0
  136. while minetest.get_node(pos).name == "default:cactus" and height < 4 do
  137. height = height+1
  138. pos.y = pos.y+1
  139. end
  140. if height < 4 then
  141. if minetest.get_node(pos).name == "air" then
  142. minetest.set_node(pos, {name="default:cactus"})
  143. end
  144. end
  145. end
  146. end,
  147. })
  148. minetest.register_abm({
  149. nodenames = {"default:papyrus"},
  150. neighbors = {"default:dirt", "default:dirt_with_grass"},
  151. interval = 50,
  152. chance = 20,
  153. action = function(pos, node)
  154. pos.y = pos.y-1
  155. local name = minetest.get_node(pos).name
  156. if name == "default:dirt" or name == "default:dirt_with_grass" then
  157. if minetest.find_node_near(pos, 3, {"group:water"}) == nil then
  158. return
  159. end
  160. pos.y = pos.y+1
  161. local height = 0
  162. while minetest.get_node(pos).name == "default:papyrus" and height < 4 do
  163. height = height+1
  164. pos.y = pos.y+1
  165. end
  166. if height < 4 then
  167. if minetest.get_node(pos).name == "air" then
  168. minetest.set_node(pos, {name="default:papyrus"})
  169. end
  170. end
  171. end
  172. end,
  173. })
  174. --
  175. -- dig upwards
  176. --
  177. function default.dig_up(pos, node, digger)
  178. if digger == nil then return end
  179. local np = {x = pos.x, y = pos.y + 1, z = pos.z}
  180. local nn = minetest.get_node(np)
  181. if nn.name == node.name then
  182. minetest.node_dig(np, nn, digger)
  183. end
  184. end
  185. --
  186. -- Leafdecay
  187. --
  188. default.leafdecay_trunk_cache = {}
  189. default.leafdecay_enable_cache = true
  190. -- Spread the load of finding trunks
  191. default.leafdecay_trunk_find_allow_accumulator = 0
  192. minetest.register_globalstep(function(dtime)
  193. local finds_per_second = 5000
  194. default.leafdecay_trunk_find_allow_accumulator =
  195. math.floor(dtime * finds_per_second)
  196. end)
  197. default.after_place_leaves = function(pos, placer, itemstack, pointed_thing)
  198. local node = minetest.get_node(pos)
  199. node.param2 = 1
  200. minetest.set_node(pos, node)
  201. end
  202. minetest.register_abm({
  203. nodenames = {"group:leafdecay"},
  204. neighbors = {"air", "group:liquid"},
  205. -- A low interval and a high inverse chance spreads the load
  206. interval = 2,
  207. chance = 5,
  208. action = function(p0, node, _, _)
  209. --print("leafdecay ABM at "..p0.x..", "..p0.y..", "..p0.z..")")
  210. local do_preserve = false
  211. local d = minetest.registered_nodes[node.name].groups.leafdecay
  212. if not d or d == 0 then
  213. --print("not groups.leafdecay")
  214. return
  215. end
  216. local n0 = minetest.get_node(p0)
  217. if n0.param2 ~= 0 then
  218. --print("param2 ~= 0")
  219. return
  220. end
  221. local p0_hash = nil
  222. if default.leafdecay_enable_cache then
  223. p0_hash = minetest.hash_node_position(p0)
  224. local trunkp = default.leafdecay_trunk_cache[p0_hash]
  225. if trunkp then
  226. local n = minetest.get_node(trunkp)
  227. local reg = minetest.registered_nodes[n.name]
  228. -- Assume ignore is a trunk, to make the thing work at the border of the active area
  229. if n.name == "ignore" or (reg and reg.groups.tree and reg.groups.tree ~= 0) then
  230. --print("cached trunk still exists")
  231. return
  232. end
  233. --print("cached trunk is invalid")
  234. -- Cache is invalid
  235. table.remove(default.leafdecay_trunk_cache, p0_hash)
  236. end
  237. end
  238. if default.leafdecay_trunk_find_allow_accumulator <= 0 then
  239. return
  240. end
  241. default.leafdecay_trunk_find_allow_accumulator =
  242. default.leafdecay_trunk_find_allow_accumulator - 1
  243. -- Assume ignore is a trunk, to make the thing work at the border of the active area
  244. local p1 = minetest.find_node_near(p0, d, {"ignore", "group:tree"})
  245. if p1 then
  246. do_preserve = true
  247. if default.leafdecay_enable_cache then
  248. --print("caching trunk")
  249. -- Cache the trunk
  250. default.leafdecay_trunk_cache[p0_hash] = p1
  251. end
  252. end
  253. if not do_preserve then
  254. -- Drop stuff other than the node itself
  255. local itemstacks = minetest.get_node_drops(n0.name)
  256. for _, itemname in ipairs(itemstacks) do
  257. if minetest.get_item_group(n0.name, "leafdecay_drop") ~= 0 or
  258. itemname ~= n0.name then
  259. local p_drop = {
  260. x = p0.x - 0.5 + math.random(),
  261. y = p0.y - 0.5 + math.random(),
  262. z = p0.z - 0.5 + math.random(),
  263. }
  264. minetest.add_item(p_drop, itemname)
  265. end
  266. end
  267. -- Remove node
  268. minetest.remove_node(p0)
  269. nodeupdate(p0)
  270. end
  271. end
  272. })
  273. --
  274. -- Grass growing
  275. --
  276. minetest.register_abm({
  277. nodenames = {"default:dirt"},
  278. interval = 2,
  279. chance = 200,
  280. action = function(pos, node)
  281. local above = {x=pos.x, y=pos.y+1, z=pos.z}
  282. local name = minetest.get_node(above).name
  283. local nodedef = minetest.registered_nodes[name]
  284. if nodedef and (nodedef.sunlight_propagates or nodedef.paramtype == "light")
  285. and nodedef.liquidtype == "none"
  286. and (minetest.get_node_light(above) or 0) >= 13 then
  287. if name == "default:snow" or name == "default:snowblock" then
  288. minetest.set_node(pos, {name = "default:dirt_with_snow"})
  289. else
  290. minetest.set_node(pos, {name = "default:dirt_with_grass"})
  291. end
  292. end
  293. end
  294. })
  295. minetest.register_abm({
  296. nodenames = {"default:dirt_with_grass"},
  297. interval = 2,
  298. chance = 20,
  299. action = function(pos, node)
  300. local above = {x=pos.x, y=pos.y+1, z=pos.z}
  301. local name = minetest.get_node(above).name
  302. local nodedef = minetest.registered_nodes[name]
  303. if name ~= "ignore" and nodedef
  304. and not ((nodedef.sunlight_propagates or nodedef.paramtype == "light")
  305. and nodedef.liquidtype == "none") then
  306. minetest.set_node(pos, {name = "default:dirt"})
  307. end
  308. end
  309. })