Disable treespawning on mapgen
[minetest_hades.git] / mods / default / functions.lua
bloba863d266995c73c1a81bb03432cba979fc73a30a
1 -- mods/default/functions.lua
4 --
5 -- Sounds
6 --
9 function default.node_sound_defaults(table)
10 table = table or {}
11 table.footstep = table.footstep or
12 {name="", gain=1.0}
13 table.dug = table.dug or
14 {name="default_dug_node", gain=0.25}
15 table.place = table.place or
16 {name="default_place_node_hard", gain=1.0}
17 return table
18 end
21 function default.node_sound_stone_defaults(table)
22 table = table or {}
23 table.footstep = table.footstep or
24 {name="default_hard_footstep", gain=0.5}
25 table.dug = table.dug or
26 {name="default_hard_footstep", gain=1.0}
27 default.node_sound_defaults(table)
28 return table
29 end
32 function default.node_sound_dirt_defaults(table)
33 table = table or {}
34 table.footstep = table.footstep or
35 {name="default_dirt_footstep", gain=1.0}
36 table.dug = table.dug or
37 {name="default_dirt_footstep", gain=1.5}
38 table.place = table.place or
39 {name="default_place_node", gain=1.0}
40 default.node_sound_defaults(table)
41 return table
42 end
45 function default.node_sound_sand_defaults(table)
46 table = table or {}
47 table.footstep = table.footstep or
48 {name="default_sand_footstep", gain=0.5}
49 table.dug = table.dug or
50 {name="default_sand_footstep", gain=1.0}
51 table.place = table.place or
52 {name="default_place_node", gain=1.0}
53 default.node_sound_defaults(table)
54 return table
55 end
58 function default.node_sound_wood_defaults(table)
59 table = table or {}
60 table.footstep = table.footstep or
61 {name="default_wood_footstep", gain=0.5}
62 table.dug = table.dug or
63 {name="default_wood_footstep", gain=1.0}
64 default.node_sound_defaults(table)
65 return table
66 end
69 function default.node_sound_leaves_defaults(table)
70 table = table or {}
71 table.footstep = table.footstep or
72 {name="default_grass_footstep", gain=0.35}
73 table.dug = table.dug or
74 {name="default_grass_footstep", gain=0.85}
75 table.dig = table.dig or
76 {name="default_dig_crumbly", gain=0.4}
77 table.place = table.place or
78 {name="default_place_node", gain=1.0}
79 default.node_sound_defaults(table)
80 return table
81 end
84 function default.node_sound_glass_defaults(table)
85 table = table or {}
86 table.footstep = table.footstep or
87 {name="default_glass_footstep", gain=0.5}
88 table.dug = table.dug or
89 {name="default_break_glass", gain=1.0}
90 default.node_sound_defaults(table)
91 return table
92 end
96 -- Legacy
100 function default.spawn_falling_node(p, nodename)
101 spawn_falling_node(p, nodename)
105 -- Horrible crap to support old code
106 -- Don't use this and never do what this does, it's completely wrong!
107 -- (More specifically, the client and the C++ code doesn't get the group)
108 function default.register_falling_node(nodename, texture)
109 minetest.log("error", debug.traceback())
110 minetest.log('error', "WARNING: default.register_falling_node is deprecated")
111 if minetest.registered_nodes[nodename] then
112 minetest.registered_nodes[nodename].groups.falling_node = 1
118 -- Global callbacks
122 -- Global environment step function
123 function on_step(dtime)
124 -- print("on_step")
126 minetest.register_globalstep(on_step)
129 function on_placenode(p, node)
130 --print("on_placenode")
132 minetest.register_on_placenode(on_placenode)
135 function on_dignode(p, node)
136 --print("on_dignode")
138 minetest.register_on_dignode(on_dignode)
141 function on_punchnode(p, node)
143 minetest.register_on_punchnode(on_punchnode)
149 -- Grow trees
153 minetest.register_abm({
154 nodenames = {"default:sapling"},
155 interval = 20,
156 chance = 50,
157 action = function(pos, node)
158 local nu = minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}).name
159 local is_soil = minetest.get_item_group(nu, "soil")
160 if is_soil == 0 then
161 return
165 minetest.log("action", "A sapling grows into a tree at "..minetest.pos_to_string(pos))
166 local vm = minetest.get_voxel_manip()
167 local minp, maxp = vm:read_from_map({x=pos.x-16, y=pos.y, z=pos.z-16}, {x=pos.x+16, y=pos.y+16, z=pos.z+16})
168 local a = VoxelArea:new{MinEdge=minp, MaxEdge=maxp}
169 local data = vm:get_data()
170 default.grow_tree(data, a, pos, math.random(1, 4) == 1, math.random(1,100000))
171 vm:set_data(data)
172 vm:write_to_map(data)
173 vm:update_map()
178 minetest.register_abm({
179 nodenames = {"default:junglesapling"},
180 interval = 20,
181 chance = 50,
182 action = function(pos, node)
183 local nu = minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}).name
184 local is_soil = minetest.get_item_group(nu, "soil")
185 if is_soil == 0 then
186 return
190 minetest.log("action", "A jungle sapling grows into a tree at "..minetest.pos_to_string(pos))
191 local vm = minetest.get_voxel_manip()
192 local minp, maxp = vm:read_from_map({x=pos.x-16, y=pos.y-1, z=pos.z-16}, {x=pos.x+16, y=pos.y+16, z=pos.z+16})
193 local a = VoxelArea:new{MinEdge=minp, MaxEdge=maxp}
194 local data = vm:get_data()
195 default.grow_jungletree(data, a, pos, math.random(1,100000))
196 vm:set_data(data)
197 vm:write_to_map(data)
198 vm:update_map()
204 -- Lavacooling
208 default.cool_lava_source = function(pos)
209 if minetest.find_node_near(pos, 5, {"default:water_flowing"}) == nil then
210 minetest.set_node(pos, {name="default:tuff"})
211 else
212 minetest.set_node(pos, {name="default:water_source"})
217 default.cool_lava_flowing = function(pos)
218 minetest.set_node(pos, {name="default:gravel_volcanic"})
222 minetest.register_abm({
223 nodenames = {"default:lava_flowing"},
224 neighbors = {"group:water"},
225 interval = 1,
226 chance = 1,
227 action = function(pos, node, active_object_count, active_object_count_wider)
228 default.cool_lava_flowing(pos, node, active_object_count, active_object_count_wider)
229 end,
233 minetest.register_abm({
234 nodenames = {"default:lava_source"},
235 neighbors = {"group:water"},
236 interval = 1,
237 chance = 1,
238 action = function(pos, node, active_object_count, active_object_count_wider)
239 default.cool_lava_source(pos, node, active_object_count, active_object_count_wider)
240 end,
244 -- Stonetransformation
247 minetest.register_abm({
248 nodenames = {"default:stone"},
249 neighbors = {"group:lava"},
250 interval = 25,
251 chance = 15,
252 action = function(pos, node)
253 minetest.set_node(pos, {name="default:desert_stone"})
254 end,
257 minetest.register_abm({
258 nodenames = {"default:stone"},
259 interval = 600,
260 chance = 65,
261 action = function(pos, node)
262 if minetest.find_node_near(pos, 2, {"group:water"}) == nil then
263 return
264 else
265 minetest.set_node(pos, {name="default:mossystone"})
267 end,
271 -- Tufftransformation
274 minetest.register_abm({
275 nodenames = {"default:tuff"},
276 neighbors = {"group:lava"},
277 interval = 25,
278 chance = 15,
279 action = function(pos, node)
280 minetest.set_node(pos, {name="default:tuff_baked"})
281 end,
284 minetest.register_abm({
285 nodenames = {"default:tuff"},
286 interval = 600,
287 chance = 65,
288 action = function(pos, node)
289 if minetest.find_node_near(pos, 2, {"group:water"}) == nil then
290 return
291 else
292 minetest.set_node(pos, {name="default:mossytuff"})
294 end,
298 -- Marble
301 minetest.register_abm({
302 nodenames = {"default:chondrit"},
303 neighbors = {"group:water"},
304 interval = 200,
305 chance = 55,
306 action = function(pos, node)
307 if minetest.find_node_near(pos, 4, {"group:lava"}) == nil or pos.y > -500 then
308 return
309 else
310 minetest.set_node(pos, {name="default:marble"})
312 end,
317 -- Obsidian
320 minetest.register_abm({
321 nodenames = {"default:gravel_volcanic"},
322 neighbors = {"group:lava"},
323 interval = 1111,
324 chance = 65,
325 action = function(pos, node)
326 if minetest.find_node_near(pos, 4, {"group:water"}) == nil or pos.y > -1000 then
327 return
328 else
329 minetest.set_node(pos, {name="default:obsidian"})
331 end,
335 -- Cobbletransformation
337 minetest.register_abm({
338 nodenames = {"default:cobble"},
339 neighbors = {"group:water"},
340 interval = 500,
341 chance = 35,
342 action = function(pos, node)
343 minetest.set_node(pos, {name="default:mossycobble"})
344 end,
347 minetest.register_abm({
348 nodenames = {"default:cobble"},
349 interval = 500,
350 chance = 55,
351 action = function(pos, node)
352 if minetest.find_node_near(pos, 2, {"group:water"}) == nil then
353 return
354 else
355 minetest.set_node(pos, {name="default:mossycobble"})
357 end,
360 minetest.register_abm({
361 nodenames = {"default:mossycobble"},
362 neighbors = {"default:water_flowing"},
363 interval = 500,
364 chance = 75,
365 action = function(pos, node)
366 minetest.set_node(pos, {name="default:gravel"})
367 end,
372 -- Ash_leavetransformation
375 minetest.register_abm({
376 nodenames = {"default:sand"},
377 interval = 550,
378 chance = 35,
379 action = function(pos, node)
380 if minetest.find_node_near(pos, 3, {"group:leaves"}) == nil then
381 return
382 else
383 pos.y = pos.y+1
384 if minetest.get_node(pos).name == "default:cactus" then
385 return
386 else
387 pos.y = pos.y-1
388 minetest.set_node(pos, {name="default:desert_sand"})
391 end,
396 -- Sandtransformation
399 minetest.register_abm({
400 nodenames = {"default:desert_sand"},
401 neighbors = {"group:water"},
402 interval = 25,
403 chance = 5,
404 action = function(pos, node)
405 minetest.set_node(pos, {name="default:dirt"})
406 end,
409 minetest.register_abm({
410 nodenames = {"default:desert_sand"},
411 neighbors = {"default:dirt", "default:dirt_with_grass"},
412 interval = 50,
413 chance = 5,
414 action = function(pos, node)
415 if minetest.find_node_near(pos, 10, {"group:water"}) == nil then
416 return
417 else
418 minetest.set_node(pos, {name="default:dirt"})
420 end,
423 minetest.register_abm({
424 nodenames = {"default:sand"},
425 neighbors = {"group:water"},
426 interval = 700,
427 chance = 75,
428 action = function(pos, node)
429 minetest.set_node(pos, {name="default:clay"})
430 end,
434 -- Dirttransformation
437 minetest.register_abm({
438 nodenames = {"default:dirt"},
439 interval = 50,
440 chance = 20,
441 action = function(pos, node)
442 local name = minetest.get_node(pos).name
443 pos.y = pos.y+1
444 if minetest.get_node(pos).name == "air" then
445 if minetest.get_node_light(pos) < 8 then
446 return
447 else
448 pos.y = pos.y-1
449 minetest.set_node(pos, {name="default:dirt_with_grass"})
452 end,
455 -- minetest.register_abm({
456 -- nodenames = {"default:dirt"},
457 -- interval = 50,
458 -- chance = 20,
459 -- action = function(pos, node)
460 -- if minetest.find_node_near(pos, 10, {"group:water"}) == nil then
461 -- minetest.set_node(pos, {name="default:desert_sand"})
462 -- else
463 -- return
464 -- end
465 -- end,
466 -- })
468 -- minetest.register_abm({
469 -- nodenames = {"default:dirt_with_grass"},
470 -- interval = 50,
471 -- chance = 20,
472 -- action = function(pos, node)
473 -- if minetest.find_node_near(pos, 10, {"group:water"}) == nil then
474 -- minetest.set_node(pos, {name="default:dirt"})
475 -- else
476 -- return
477 -- end
478 -- end,
479 -- })
480 -- sugarcane
481 minetest.register_abm({
482 nodenames = {"default:sugarcane"},
483 neighbors = {"default:dirt", "default:dirt_with_grass"},
484 interval = 55,
485 chance = 35,
486 action = function(pos, node)
487 pos.y = pos.y-1
488 local name = minetest.get_node(pos).name
489 if name == "default:dirt" or name == "default:dirt_with_grass" then
490 pos.y = pos.y+1
491 local height = 0
492 while minetest.get_node(pos).name == "default:sugarcane" and height < 3 do
493 height = height+1
494 pos.y = pos.y+1
496 if height < 3 then
497 if minetest.get_node(pos).name == "air" then
498 minetest.set_node(pos, {name="default:sugarcane"})
502 end,
505 minetest.register_abm({
506 nodenames = {"default:dirt_with_grass"},
507 neighbors = {"default:papyrus"},
508 interval = 500,
509 chance = 25,
510 action = function(pos, node)
511 if minetest.find_node_near(pos, 10, {"default:sugarcane"}) == nil then
512 pos.y = pos.y+1
513 if minetest.get_node(pos).name == "air" then
514 minetest.set_node(pos, {name="default:sugarcane"})
516 else
517 return
518 end
519 end,
522 -- Papyrus and cactus growing
526 minetest.register_abm({
527 nodenames = {"default:cactus"},
528 neighbors = {"group:sand"},
529 interval = 50,
530 chance = 20,
531 action = function(pos, node)
532 pos.y = pos.y-1
533 local name = minetest.get_node(pos).name
534 if minetest.get_item_group(name, "sand") ~= 0 then
535 pos.y = pos.y+1
536 local height = 0
537 while minetest.get_node(pos).name == "default:cactus" and height < 4 do
538 height = height+1
539 pos.y = pos.y+1
541 if height < 3 then
542 if minetest.get_node(pos).name == "air" then
543 minetest.set_node(pos, {name="default:cactus"})
547 end,
551 minetest.register_abm({
552 nodenames = {"default:papyrus"},
553 neighbors = {"default:dirt", "default:dirt_with_grass"},
554 interval = 50,
555 chance = 20,
556 action = function(pos, node)
557 pos.y = pos.y-1
558 local name = minetest.get_node(pos).name
559 if name == "default:dirt" or name == "default:dirt_with_grass" then
560 if minetest.find_node_near(pos, 3, {"group:water"}) == nil then
561 return
563 pos.y = pos.y+1
564 local height = 0
565 while minetest.get_node(pos).name == "default:papyrus" and height < 4 do
566 height = height+1
567 pos.y = pos.y+1
569 if height < 4 then
570 if minetest.get_node(pos).name == "air" then
571 minetest.set_node(pos, {name="default:papyrus"})
575 end,
580 -- dig upwards
583 function default.dig_up(pos, node, digger)
584 if digger == nil then return end
585 local np = {x = pos.x, y = pos.y + 1, z = pos.z}
586 local nn = minetest.get_node(np)
587 if nn.name == node.name then
588 minetest.node_dig(np, nn, digger)
594 -- Leafdecay
598 -- To enable leaf decay for a node, add it to the "leafdecay" group.
600 -- The rating of the group determines how far from a node in the group "tree"
601 -- the node can be without decaying.
603 -- If param2 of the node is ~= 0, the node will always be preserved. Thus, if
604 -- the player places a node of that kind, you will want to set param2=1 or so.
606 -- If the node is in the leafdecay_drop group then the it will always be dropped
607 -- as an item
610 default.leafdecay_trunk_cache = {}
611 default.leafdecay_enable_cache = true
612 -- Spread the load of finding trunks
613 default.leafdecay_trunk_find_allow_accumulator = 0
616 minetest.register_globalstep(function(dtime)
617 local finds_per_second = 5000
618 default.leafdecay_trunk_find_allow_accumulator =
619 math.floor(dtime * finds_per_second)
620 end)
623 minetest.register_abm({
624 nodenames = {"group:leafdecay"},
625 neighbors = {"air", "group:liquid"},
626 -- A low interval and a high inverse chance spreads the load
627 interval = 2,
628 chance = 5,
631 action = function(p0, node, _, _)
632 --print("leafdecay ABM at "..p0.x..", "..p0.y..", "..p0.z..")")
633 local do_preserve = false
634 local d = minetest.registered_nodes[node.name].groups.leafdecay
635 if not d or d == 0 then
636 --print("not groups.leafdecay")
637 return
639 local n0 = minetest.get_node(p0)
640 if n0.param2 ~= 0 then
641 --print("param2 ~= 0")
642 return
644 local p0_hash = nil
645 if default.leafdecay_enable_cache then
646 p0_hash = minetest.hash_node_position(p0)
647 local trunkp = default.leafdecay_trunk_cache[p0_hash]
648 if trunkp then
649 local n = minetest.get_node(trunkp)
650 local reg = minetest.registered_nodes[n.name]
651 -- Assume ignore is a trunk, to make the thing work at the border of the active area
652 if n.name == "ignore" or (reg and reg.groups.tree and reg.groups.tree ~= 0) then
653 --print("cached trunk still exists")
654 return
656 --print("cached trunk is invalid")
657 -- Cache is invalid
658 table.remove(default.leafdecay_trunk_cache, p0_hash)
661 if default.leafdecay_trunk_find_allow_accumulator <= 0 then
662 return
664 default.leafdecay_trunk_find_allow_accumulator =
665 default.leafdecay_trunk_find_allow_accumulator - 1
666 -- Assume ignore is a trunk, to make the thing work at the border of the active area
667 local p1 = minetest.find_node_near(p0, d, {"ignore", "group:tree"})
668 if p1 then
669 do_preserve = true
670 if default.leafdecay_enable_cache then
671 --print("caching trunk")
672 -- Cache the trunk
673 default.leafdecay_trunk_cache[p0_hash] = p1
676 if not do_preserve then
677 -- Drop stuff other than the node itself
678 itemstacks = minetest.get_node_drops(n0.name)
679 for _, itemname in ipairs(itemstacks) do
680 if minetest.get_item_group(n0.name, "leafdecay_drop") ~= 0 or
681 itemname ~= n0.name then
682 local p_drop = {
683 x = p0.x - 0.5 + math.random(),
684 y = p0.y - 0.5 + math.random(),
685 z = p0.z - 0.5 + math.random(),
687 minetest.add_item(p_drop, itemname)
690 -- Remove node
691 minetest.remove_node(p0)
692 nodeupdate(p0)