1 -- mods/default/functions.lua
9 function default
.node_sound_defaults(table)
11 table.footstep
= table.footstep
or
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}
21 function default
.node_sound_stone_defaults(table)
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)
32 function default
.node_sound_dirt_defaults(table)
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)
45 function default
.node_sound_sand_defaults(table)
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)
58 function default
.node_sound_wood_defaults(table)
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)
69 function default
.node_sound_leaves_defaults(table)
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)
84 function default
.node_sound_glass_defaults(table)
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)
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
122 -- Global environment step function
123 function on_step(dtime
)
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
)
153 minetest
.register_abm({
154 nodenames
= {"default:sapling"},
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")
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))
172 vm
:write_to_map(data
)
178 minetest
.register_abm({
179 nodenames
= {"default:junglesapling"},
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")
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))
197 vm
:write_to_map(data
)
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"})
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"},
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
)
233 minetest
.register_abm({
234 nodenames
= {"default:lava_source"},
235 neighbors
= {"group:water"},
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
)
244 -- Stonetransformation
247 minetest
.register_abm({
248 nodenames
= {"default:stone"},
249 neighbors
= {"group:lava"},
252 action
= function(pos
, node
)
253 minetest
.set_node(pos
, {name
="default:desert_stone"})
257 minetest
.register_abm({
258 nodenames
= {"default:stone"},
261 action
= function(pos
, node
)
262 if minetest
.find_node_near(pos
, 2, {"group:water"}) == nil then
265 minetest
.set_node(pos
, {name
="default:mossystone"})
271 -- Tufftransformation
274 minetest
.register_abm({
275 nodenames
= {"default:tuff"},
276 neighbors
= {"group:lava"},
279 action
= function(pos
, node
)
280 minetest
.set_node(pos
, {name
="default:tuff_baked"})
284 minetest
.register_abm({
285 nodenames
= {"default:tuff"},
288 action
= function(pos
, node
)
289 if minetest
.find_node_near(pos
, 2, {"group:water"}) == nil then
292 minetest
.set_node(pos
, {name
="default:mossytuff"})
301 minetest
.register_abm({
302 nodenames
= {"default:chondrit"},
303 neighbors
= {"group:water"},
306 action
= function(pos
, node
)
307 if minetest
.find_node_near(pos
, 4, {"group:lava"}) == nil or pos
.y
> -500 then
310 minetest
.set_node(pos
, {name
="default:marble"})
320 minetest
.register_abm({
321 nodenames
= {"default:gravel_volcanic"},
322 neighbors
= {"group:lava"},
325 action
= function(pos
, node
)
326 if minetest
.find_node_near(pos
, 4, {"group:water"}) == nil or pos
.y
> -1000 then
329 minetest
.set_node(pos
, {name
="default:obsidian"})
335 -- Cobbletransformation
337 minetest
.register_abm({
338 nodenames
= {"default:cobble"},
339 neighbors
= {"group:water"},
342 action
= function(pos
, node
)
343 minetest
.set_node(pos
, {name
="default:mossycobble"})
347 minetest
.register_abm({
348 nodenames
= {"default:cobble"},
351 action
= function(pos
, node
)
352 if minetest
.find_node_near(pos
, 2, {"group:water"}) == nil then
355 minetest
.set_node(pos
, {name
="default:mossycobble"})
360 minetest
.register_abm({
361 nodenames
= {"default:mossycobble"},
362 neighbors
= {"default:water_flowing"},
365 action
= function(pos
, node
)
366 minetest
.set_node(pos
, {name
="default:gravel"})
372 -- Ash_leavetransformation
375 minetest
.register_abm({
376 nodenames
= {"default:sand"},
379 action
= function(pos
, node
)
380 if minetest
.find_node_near(pos
, 3, {"group:leaves"}) == nil then
384 if minetest
.get_node(pos
).name
== "default:cactus" then
388 minetest
.set_node(pos
, {name
="default:desert_sand"})
396 -- Sandtransformation
399 minetest
.register_abm({
400 nodenames
= {"default:desert_sand"},
401 neighbors
= {"group:water"},
404 action
= function(pos
, node
)
405 minetest
.set_node(pos
, {name
="default:dirt"})
409 minetest
.register_abm({
410 nodenames
= {"default:desert_sand"},
411 neighbors
= {"default:dirt", "default:dirt_with_grass"},
414 action
= function(pos
, node
)
415 if minetest
.find_node_near(pos
, 10, {"group:water"}) == nil then
418 minetest
.set_node(pos
, {name
="default:dirt"})
423 minetest
.register_abm({
424 nodenames
= {"default:sand"},
425 neighbors
= {"group:water"},
428 action
= function(pos
, node
)
429 minetest
.set_node(pos
, {name
="default:clay"})
434 -- Dirttransformation
437 minetest
.register_abm({
438 nodenames
= {"default:dirt"},
441 action
= function(pos
, node
)
442 local name
= minetest
.get_node(pos
).name
444 if minetest
.get_node(pos
).name
== "air" then
445 if minetest
.get_node_light(pos
) < 8 then
449 minetest
.set_node(pos
, {name
="default:dirt_with_grass"})
455 -- minetest.register_abm({
456 -- nodenames = {"default:dirt"},
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"})
468 -- minetest.register_abm({
469 -- nodenames = {"default:dirt_with_grass"},
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"})
481 minetest
.register_abm({
482 nodenames
= {"default:sugarcane"},
483 neighbors
= {"default:dirt", "default:dirt_with_grass"},
486 action
= function(pos
, node
)
488 local name
= minetest
.get_node(pos
).name
489 if name
== "default:dirt" or name
== "default:dirt_with_grass" then
492 while minetest
.get_node(pos
).name
== "default:sugarcane" and height
< 3 do
497 if minetest
.get_node(pos
).name
== "air" then
498 minetest
.set_node(pos
, {name
="default:sugarcane"})
505 minetest
.register_abm({
506 nodenames
= {"default:dirt_with_grass"},
507 neighbors
= {"default:papyrus"},
510 action
= function(pos
, node
)
511 if minetest
.find_node_near(pos
, 10, {"default:sugarcane"}) == nil then
513 if minetest
.get_node(pos
).name
== "air" then
514 minetest
.set_node(pos
, {name
="default:sugarcane"})
522 -- Papyrus and cactus growing
526 minetest
.register_abm({
527 nodenames
= {"default:cactus"},
528 neighbors
= {"group:sand"},
531 action
= function(pos
, node
)
533 local name
= minetest
.get_node(pos
).name
534 if minetest
.get_item_group(name
, "sand") ~= 0 then
537 while minetest
.get_node(pos
).name
== "default:cactus" and height
< 4 do
542 if minetest
.get_node(pos
).name
== "air" then
543 minetest
.set_node(pos
, {name
="default:cactus"})
551 minetest
.register_abm({
552 nodenames
= {"default:papyrus"},
553 neighbors
= {"default:dirt", "default:dirt_with_grass"},
556 action
= function(pos
, node
)
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
565 while minetest
.get_node(pos
).name
== "default:papyrus" and height
< 4 do
570 if minetest
.get_node(pos
).name
== "air" then
571 minetest
.set_node(pos
, {name
="default:papyrus"})
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
)
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
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
)
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
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")
639 local n0
= minetest
.get_node(p0
)
640 if n0
.param2
~= 0 then
641 --print("param2 ~= 0")
645 if default
.leafdecay_enable_cache
then
646 p0_hash
= minetest
.hash_node_position(p0
)
647 local trunkp
= default
.leafdecay_trunk_cache
[p0_hash
]
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")
656 --print("cached trunk is invalid")
658 table.remove(default
.leafdecay_trunk_cache
, p0_hash
)
661 if default
.leafdecay_trunk_find_allow_accumulator
<= 0 then
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"})
670 if default
.leafdecay_enable_cache
then
671 --print("caching 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
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
)
691 minetest
.remove_node(p0
)