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