26e02ed5f733ebed9a79c98d3dbfc941a1802ff8
[oweals/minetest_game.git] / mods / default / nodes.lua
1 -- mods/default/nodes.lua
2
3 minetest.register_node("default:stone", {
4         description = "Stone",
5         tiles = {"default_stone.png"},
6         is_ground_content = true,
7         groups = {cracky=3, stone=1},
8         drop = 'default:cobble',
9         legacy_mineral = true,
10         sounds = default.node_sound_stone_defaults(),
11 })
12
13 minetest.register_node("default:desert_stone", {
14         description = "Desert Stone",
15         tiles = {"default_desert_stone.png"},
16         is_ground_content = true,
17         groups = {cracky=3, stone=1},
18         drop = 'default:desert_stone',
19         legacy_mineral = true,
20         sounds = default.node_sound_stone_defaults(),
21 })
22
23 minetest.register_node("default:stone_with_coal", {
24         description = "Coal Ore",
25         tiles = {"default_stone.png^default_mineral_coal.png"},
26         is_ground_content = true,
27         groups = {cracky=3},
28         drop = 'default:coal_lump',
29         sounds = default.node_sound_stone_defaults(),
30 })
31
32 minetest.register_node("default:stone_with_iron", {
33         description = "Iron Ore",
34         tiles = {"default_stone.png^default_mineral_iron.png"},
35         is_ground_content = true,
36         groups = {cracky=2},
37         drop = 'default:iron_lump',
38         sounds = default.node_sound_stone_defaults(),
39 })
40
41 minetest.register_node("default:stone_with_copper", {
42         description = "Copper Ore",
43         tiles = {"default_stone.png^default_mineral_copper.png"},
44         is_ground_content = true,
45         groups = {cracky=2},
46         drop = 'default:copper_lump',
47         sounds = default.node_sound_stone_defaults(),
48 })
49
50 minetest.register_node("default:stone_with_mese", {
51         description = "Mese Crystals in Stone",
52         tiles = {"default_stone.png^default_mineral_mese.png"},
53         is_ground_content = true,
54         groups = {cracky=1},
55         drop = "default:mese_crystal",
56         sounds = default.node_sound_stone_defaults(),
57 })
58
59 minetest.register_node("default:stone_with_gold", {
60         description = "Gold Ore",
61         tiles = {"default_stone.png^default_mineral_gold.png"},
62         is_ground_content = true,
63         groups = {cracky=2},
64         drop = "default:gold_lump",
65         sounds = default.node_sound_stone_defaults(),
66 })
67         
68 minetest.register_node("default:stone_with_diamond", {
69         description = "Diamonds in Stone",
70         tiles = {"default_stone.png^default_mineral_diamond.png"},
71         is_ground_content = true,
72         groups = {cracky=1},
73         drop = "default:diamond",
74         sounds = default.node_sound_stone_defaults(),
75 })
76
77 minetest.register_node("default:stonebrick", {
78         description = "Stone Brick",
79         tiles = {"default_stone_brick.png"},
80         groups = {cracky=2, stone=1},
81         sounds = default.node_sound_stone_defaults(),
82 })
83
84 minetest.register_node("default:desert_stonebrick", {
85         description = "Desert Stone Brick",
86         tiles = {"default_desert_stone_brick.png"},
87         groups = {cracky=2, stone=1},
88         sounds = default.node_sound_stone_defaults(),
89 })
90
91 minetest.register_node("default:dirt_with_grass", {
92         description = "Dirt with Grass",
93         tiles = {"default_grass.png", "default_dirt.png", "default_dirt.png^default_grass_side.png"},
94         is_ground_content = true,
95         groups = {crumbly=3,soil=1},
96         drop = 'default:dirt',
97         sounds = default.node_sound_dirt_defaults({
98                 footstep = {name="default_grass_footstep", gain=0.4},
99         }),
100 })
101
102 minetest.register_node("default:dirt_with_grass_footsteps", {
103         description = "Dirt with Grass and Footsteps",
104         tiles = {"default_grass_footsteps.png", "default_dirt.png", "default_dirt.png^default_grass_side.png"},
105         is_ground_content = true,
106         groups = {crumbly=3,soil=1,not_in_creative_inventory=1},
107         drop = 'default:dirt',
108         sounds = default.node_sound_dirt_defaults({
109                 footstep = {name="default_grass_footstep", gain=0.4},
110         }),
111 })
112
113 minetest.register_node("default:dirt_with_snow", {
114         description = "Dirt with Snow",
115         tiles = {"default_snow.png", "default_dirt.png", "default_dirt.png^default_snow_side.png"},
116         is_ground_content = true,
117         groups = {crumbly=3},
118         drop = 'default:dirt',
119         sounds = default.node_sound_dirt_defaults({
120                 footstep = {name="default_grass_footstep", gain=0.4},
121         }),
122 })
123 minetest.register_alias("dirt_with_snow", "default:dirt_with_snow")
124
125 minetest.register_node("default:dirt", {
126         description = "Dirt",
127         tiles = {"default_dirt.png"},
128         is_ground_content = true,
129         groups = {crumbly=3,soil=1},
130         sounds = default.node_sound_dirt_defaults(),
131 })
132
133 minetest.register_node("default:sand", {
134         description = "Sand",
135         tiles = {"default_sand.png"},
136         is_ground_content = true,
137         groups = {crumbly=3, falling_node=1, sand=1},
138         sounds = default.node_sound_sand_defaults(),
139 })
140
141 minetest.register_node("default:desert_sand", {
142         description = "Desert Sand",
143         tiles = {"default_desert_sand.png"},
144         is_ground_content = true,
145         groups = {crumbly=3, falling_node=1, sand=1},
146         sounds = default.node_sound_sand_defaults(),
147 })
148
149 minetest.register_node("default:gravel", {
150         description = "Gravel",
151         tiles = {"default_gravel.png"},
152         is_ground_content = true,
153         groups = {crumbly=2, falling_node=1},
154         sounds = default.node_sound_dirt_defaults({
155                 footstep = {name="default_gravel_footstep", gain=0.45},
156         }),
157 })
158
159 minetest.register_node("default:sandstone", {
160         description = "Sandstone",
161         tiles = {"default_sandstone.png"},
162         is_ground_content = true,
163         groups = {crumbly=2,cracky=3},
164         sounds = default.node_sound_stone_defaults(),
165 })
166
167 minetest.register_node("default:sandstonebrick", {
168         description = "Sandstone Brick",
169         tiles = {"default_sandstone_brick.png"},
170         is_ground_content = true,
171         groups = {cracky=2},
172         sounds = default.node_sound_stone_defaults(),
173 })
174
175 minetest.register_node("default:clay", {
176         description = "Clay",
177         tiles = {"default_clay.png"},
178         is_ground_content = true,
179         groups = {crumbly=3},
180         drop = 'default:clay_lump 4',
181         sounds = default.node_sound_dirt_defaults({
182                 footstep = "",
183         }),
184 })
185
186 minetest.register_node("default:brick", {
187         description = "Brick Block",
188         tiles = {"default_brick.png"},
189         groups = {cracky=3},
190         sounds = default.node_sound_stone_defaults(),
191 })
192
193 minetest.register_node("default:tree", {
194         description = "Tree",
195         tiles = {"default_tree_top.png", "default_tree_top.png", "default_tree.png"},
196         groups = {tree=1,choppy=2,oddly_breakable_by_hand=1,flammable=2},
197         sounds = default.node_sound_wood_defaults(),
198 })
199
200 minetest.register_node("default:jungletree", {
201         description = "Jungle Tree",
202         tiles = {"default_jungletree_top.png", "default_jungletree_top.png", "default_jungletree.png"},
203         groups = {tree=1,choppy=2,oddly_breakable_by_hand=1,flammable=2},
204         sounds = default.node_sound_wood_defaults(),
205 })
206
207 minetest.register_node("default:junglewood", {
208         description = "Junglewood Planks",
209         tiles = {"default_junglewood.png"},
210         groups = {choppy=2,oddly_breakable_by_hand=2,flammable=3,wood=1},
211         sounds = default.node_sound_wood_defaults(),
212 })
213
214 minetest.register_node("default:jungleleaves", {
215         description = "Jungle Leaves",
216         drawtype = "allfaces_optional",
217         visual_scale = 1.3,
218         tiles = {"default_jungleleaves.png"},
219         paramtype = "light",
220         groups = {snappy=3, leafdecay=3, flammable=2, leaves=1},
221         drop = {
222                 max_items = 1,
223                 items = {
224                         {
225                                 -- player will get sapling with 1/20 chance
226                                 items = {'default:junglesapling'},
227                                 rarity = 20,
228                         },
229                         {
230                                 -- player will get leaves only if he get no saplings,
231                                 -- this is because max_items is 1
232                                 items = {'default:jungleleaves'},
233                         }
234                 }
235         },
236         sounds = default.node_sound_leaves_defaults(),
237 })
238
239 minetest.register_node("default:junglesapling", {
240         description = "Jungle Sapling",
241         drawtype = "plantlike",
242         visual_scale = 1.0,
243         tiles = {"default_junglesapling.png"},
244         inventory_image = "default_junglesapling.png",
245         wield_image = "default_junglesapling.png",
246         paramtype = "light",
247         walkable = false,
248         selection_box = {
249                 type = "fixed",
250                 fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3}
251         },
252         groups = {snappy=2,dig_immediate=3,flammable=2,attached_node=1},
253         sounds = default.node_sound_defaults(),
254 })
255 -- aliases for tree growing abm in content_abm.cpp
256 minetest.register_alias("sapling", "default:sapling")
257 minetest.register_alias("junglesapling", "default:junglesapling")
258
259 minetest.register_node("default:junglegrass", {
260         description = "Jungle Grass",
261         drawtype = "plantlike",
262         visual_scale = 1.3,
263         tiles = {"default_junglegrass.png"},
264         inventory_image = "default_junglegrass.png",
265         wield_image = "default_junglegrass.png",
266         paramtype = "light",
267         walkable = false,
268         buildable_to = true,
269         is_ground_content = true,
270         groups = {snappy=3,flammable=2,flora=1,attached_node=1},
271         sounds = default.node_sound_leaves_defaults(),
272         selection_box = {
273                 type = "fixed",
274                 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
275         },
276 })
277
278 minetest.register_node("default:leaves", {
279         description = "Leaves",
280         drawtype = "allfaces_optional",
281         visual_scale = 1.3,
282         tiles = {"default_leaves.png"},
283         paramtype = "light",
284         groups = {snappy=3, leafdecay=3, flammable=2, leaves=1},
285         drop = {
286                 max_items = 1,
287                 items = {
288                         {
289                                 -- player will get sapling with 1/20 chance
290                                 items = {'default:sapling'},
291                                 rarity = 20,
292                         },
293                         {
294                                 -- player will get leaves only if he get no saplings,
295                                 -- this is because max_items is 1
296                                 items = {'default:leaves'},
297                         }
298                 }
299         },
300         sounds = default.node_sound_leaves_defaults(),
301 })
302
303 minetest.register_node("default:cactus", {
304         description = "Cactus",
305         tiles = {"default_cactus_top.png", "default_cactus_top.png", "default_cactus_side.png"},
306         is_ground_content = true,
307         groups = {snappy=1,choppy=3,flammable=2},
308         sounds = default.node_sound_wood_defaults(),
309 })
310
311 minetest.register_node("default:papyrus", {
312         description = "Papyrus",
313         drawtype = "plantlike",
314         tiles = {"default_papyrus.png"},
315         inventory_image = "default_papyrus.png",
316         wield_image = "default_papyrus.png",
317         paramtype = "light",
318         walkable = false,
319         is_ground_content = true,
320         selection_box = {
321                 type = "fixed",
322                 fixed = {-0.3, -0.5, -0.3, 0.3, 0.5, 0.3}
323         },
324         groups = {snappy=3,flammable=2},
325         sounds = default.node_sound_leaves_defaults(),
326 })
327
328 minetest.register_node("default:bookshelf", {
329         description = "Bookshelf",
330         tiles = {"default_wood.png", "default_wood.png", "default_bookshelf.png"},
331         groups = {choppy=3,oddly_breakable_by_hand=2,flammable=3},
332         sounds = default.node_sound_wood_defaults(),
333 })
334
335 minetest.register_node("default:glass", {
336         description = "Glass",
337         drawtype = "glasslike",
338         tiles = {"default_glass.png"},
339         inventory_image = minetest.inventorycube("default_glass.png"),
340         paramtype = "light",
341         sunlight_propagates = true,
342         groups = {cracky=3,oddly_breakable_by_hand=3},
343         sounds = default.node_sound_glass_defaults(),
344 })
345
346 minetest.register_node("default:fence_wood", {
347         description = "Wooden Fence",
348         drawtype = "fencelike",
349         tiles = {"default_wood.png"},
350         inventory_image = "default_fence.png",
351         wield_image = "default_fence.png",
352         paramtype = "light",
353         selection_box = {
354                 type = "fixed",
355                 fixed = {-1/7, -1/2, -1/7, 1/7, 1/2, 1/7},
356         },
357         groups = {choppy=2,oddly_breakable_by_hand=2,flammable=2},
358         sounds = default.node_sound_wood_defaults(),
359 })
360
361 minetest.register_node("default:rail", {
362         description = "Rail",
363         drawtype = "raillike",
364         tiles = {"default_rail.png", "default_rail_curved.png", "default_rail_t_junction.png", "default_rail_crossing.png"},
365         inventory_image = "default_rail.png",
366         wield_image = "default_rail.png",
367         paramtype = "light",
368         walkable = false,
369         selection_box = {
370                 type = "fixed",
371                 -- but how to specify the dimensions for curved and sideways rails?
372                 fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
373         },
374         groups = {bendy=2,dig_immediate=2,attached_node=1},
375 })
376
377 minetest.register_node("default:ladder", {
378         description = "Ladder",
379         drawtype = "signlike",
380         tiles = {"default_ladder.png"},
381         inventory_image = "default_ladder.png",
382         wield_image = "default_ladder.png",
383         paramtype = "light",
384         paramtype2 = "wallmounted",
385         walkable = false,
386         climbable = true,
387         selection_box = {
388                 type = "wallmounted",
389                 --wall_top = = <default>
390                 --wall_bottom = = <default>
391                 --wall_side = = <default>
392         },
393         groups = {choppy=2,oddly_breakable_by_hand=3,flammable=2},
394         legacy_wallmounted = true,
395         sounds = default.node_sound_wood_defaults(),
396 })
397
398 minetest.register_node("default:wood", {
399         description = "Wooden Planks",
400         tiles = {"default_wood.png"},
401         groups = {choppy=2,oddly_breakable_by_hand=2,flammable=3,wood=1},
402         sounds = default.node_sound_wood_defaults(),
403 })
404
405 minetest.register_node("default:cloud", {
406         description = "Cloud",
407         tiles = {"default_cloud.png"},
408         sounds = default.node_sound_defaults(),
409         groups = {not_in_creative_inventory=1},
410 })
411
412 minetest.register_node("default:water_flowing", {
413         description = "Flowing Water",
414         inventory_image = minetest.inventorycube("default_water.png"),
415         drawtype = "flowingliquid",
416         tiles = {"default_water.png"},
417         special_tiles = {
418                 {
419                         image="default_water_flowing_animated.png",
420                         backface_culling=false,
421                         animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=0.8}
422                 },
423                 {
424                         image="default_water_flowing_animated.png",
425                         backface_culling=true,
426                         animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=0.8}
427                 },
428         },
429         alpha = WATER_ALPHA,
430         paramtype = "light",
431         walkable = false,
432         pointable = false,
433         diggable = false,
434         buildable_to = true,
435         drop = "",
436         liquidtype = "flowing",
437         liquid_alternative_flowing = "default:water_flowing",
438         liquid_alternative_source = "default:water_source",
439         liquid_viscosity = WATER_VISC,
440         post_effect_color = {a=64, r=100, g=100, b=200},
441         groups = {water=3, liquid=3, puts_out_fire=1, not_in_creative_inventory=1},
442 })
443
444 minetest.register_node("default:water_source", {
445         description = "Water Source",
446         inventory_image = minetest.inventorycube("default_water.png"),
447         drawtype = "liquid",
448         tiles = {
449                 {name="default_water_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}}
450         },
451         special_tiles = {
452                 -- New-style water source material (mostly unused)
453                 {
454                         name="default_water_source_animated.png",
455                         animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0},
456                         backface_culling = false,
457                 }
458         },
459         alpha = WATER_ALPHA,
460         paramtype = "light",
461         walkable = false,
462         pointable = false,
463         diggable = false,
464         buildable_to = true,
465         drop = "",
466         liquidtype = "source",
467         liquid_alternative_flowing = "default:water_flowing",
468         liquid_alternative_source = "default:water_source",
469         liquid_viscosity = WATER_VISC,
470         post_effect_color = {a=64, r=100, g=100, b=200},
471         groups = {water=3, liquid=3, puts_out_fire=1},
472 })
473
474 minetest.register_node("default:lava_flowing", {
475         description = "Flowing Lava",
476         inventory_image = minetest.inventorycube("default_lava.png"),
477         drawtype = "flowingliquid",
478         tiles = {"default_lava.png"},
479         special_tiles = {
480                 {
481                         image="default_lava_flowing_animated.png",
482                         backface_culling=false,
483                         animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.3}
484                 },
485                 {
486                         image="default_lava_flowing_animated.png",
487                         backface_culling=true,
488                         animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.3}
489                 },
490         },
491         paramtype = "light",
492         light_source = LIGHT_MAX - 1,
493         walkable = false,
494         pointable = false,
495         diggable = false,
496         buildable_to = true,
497         drop = "",
498         liquidtype = "flowing",
499         liquid_alternative_flowing = "default:lava_flowing",
500         liquid_alternative_source = "default:lava_source",
501         liquid_viscosity = LAVA_VISC,
502         liquid_renewable = false,
503         damage_per_second = 4*2,
504         post_effect_color = {a=192, r=255, g=64, b=0},
505         groups = {lava=3, liquid=2, hot=3, igniter=1, not_in_creative_inventory=1},
506 })
507
508 minetest.register_node("default:lava_source", {
509         description = "Lava Source",
510         inventory_image = minetest.inventorycube("default_lava.png"),
511         drawtype = "liquid",
512         tiles = {
513                 {name="default_lava_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}}
514         },
515         special_tiles = {
516                 -- New-style lava source material (mostly unused)
517                 {
518                         name="default_lava_source_animated.png",
519                         animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0},
520                         backface_culling = false,
521                 }
522         },
523         paramtype = "light",
524         light_source = LIGHT_MAX - 1,
525         walkable = false,
526         pointable = false,
527         diggable = false,
528         buildable_to = true,
529         drop = "",
530         liquidtype = "source",
531         liquid_alternative_flowing = "default:lava_flowing",
532         liquid_alternative_source = "default:lava_source",
533         liquid_viscosity = LAVA_VISC,
534         liquid_renewable = false,
535         damage_per_second = 4*2,
536         post_effect_color = {a=192, r=255, g=64, b=0},
537         groups = {lava=3, liquid=2, hot=3, igniter=1},
538 })
539
540 minetest.register_node("default:torch", {
541         description = "Torch",
542         drawtype = "torchlike",
543         --tiles = {"default_torch_on_floor.png", "default_torch_on_ceiling.png", "default_torch.png"},
544         tiles = {
545                 {name="default_torch_on_floor_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}},
546                 {name="default_torch_on_ceiling_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}},
547                 {name="default_torch_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}}
548         },
549         inventory_image = "default_torch_on_floor.png",
550         wield_image = "default_torch_on_floor.png",
551         paramtype = "light",
552         paramtype2 = "wallmounted",
553         sunlight_propagates = true,
554         walkable = false,
555         light_source = LIGHT_MAX-1,
556         selection_box = {
557                 type = "wallmounted",
558                 wall_top = {-0.1, 0.5-0.6, -0.1, 0.1, 0.5, 0.1},
559                 wall_bottom = {-0.1, -0.5, -0.1, 0.1, -0.5+0.6, 0.1},
560                 wall_side = {-0.5, -0.3, -0.1, -0.5+0.3, 0.3, 0.1},
561         },
562         groups = {choppy=2,dig_immediate=3,flammable=1,attached_node=1},
563         legacy_wallmounted = true,
564         sounds = default.node_sound_defaults(),
565 })
566
567 minetest.register_node("default:sign_wall", {
568         description = "Sign",
569         drawtype = "signlike",
570         tiles = {"default_sign_wall.png"},
571         inventory_image = "default_sign_wall.png",
572         wield_image = "default_sign_wall.png",
573         paramtype = "light",
574         paramtype2 = "wallmounted",
575         sunlight_propagates = true,
576         walkable = false,
577         selection_box = {
578                 type = "wallmounted",
579                 --wall_top = <default>
580                 --wall_bottom = <default>
581                 --wall_side = <default>
582         },
583         groups = {choppy=2,dig_immediate=2,attached_node=1},
584         legacy_wallmounted = true,
585         sounds = default.node_sound_defaults(),
586         on_construct = function(pos)
587                 --local n = minetest.env:get_node(pos)
588                 local meta = minetest.env:get_meta(pos)
589                 meta:set_string("formspec", "field[text;;${text}]")
590                 meta:set_string("infotext", "\"\"")
591         end,
592         on_receive_fields = function(pos, formname, fields, sender)
593                 --print("Sign at "..minetest.pos_to_string(pos).." got "..dump(fields))
594                 local meta = minetest.env:get_meta(pos)
595                 fields.text = fields.text or ""
596                 print((sender:get_player_name() or "").." wrote \""..fields.text..
597                                 "\" to sign at "..minetest.pos_to_string(pos))
598                 meta:set_string("text", fields.text)
599                 meta:set_string("infotext", '"'..fields.text..'"')
600         end,
601 })
602
603 minetest.register_node("default:chest", {
604         description = "Chest",
605         tiles = {"default_chest_top.png", "default_chest_top.png", "default_chest_side.png",
606                 "default_chest_side.png", "default_chest_side.png", "default_chest_front.png"},
607         paramtype2 = "facedir",
608         groups = {choppy=2,oddly_breakable_by_hand=2},
609         legacy_facedir_simple = true,
610         sounds = default.node_sound_wood_defaults(),
611         on_construct = function(pos)
612                 local meta = minetest.env:get_meta(pos)
613                 meta:set_string("formspec",
614                                 "size[8,9]"..
615                                 "list[current_name;main;0,0;8,4;]"..
616                                 "list[current_player;main;0,5;8,4;]")
617                 meta:set_string("infotext", "Chest")
618                 local inv = meta:get_inventory()
619                 inv:set_size("main", 8*4)
620         end,
621         can_dig = function(pos,player)
622                 local meta = minetest.env:get_meta(pos);
623                 local inv = meta:get_inventory()
624                 return inv:is_empty("main")
625         end,
626         on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
627                 minetest.log("action", player:get_player_name()..
628                                 " moves stuff in chest at "..minetest.pos_to_string(pos))
629         end,
630     on_metadata_inventory_put = function(pos, listname, index, stack, player)
631                 minetest.log("action", player:get_player_name()..
632                                 " moves stuff to chest at "..minetest.pos_to_string(pos))
633         end,
634     on_metadata_inventory_take = function(pos, listname, index, stack, player)
635                 minetest.log("action", player:get_player_name()..
636                                 " takes stuff from chest at "..minetest.pos_to_string(pos))
637         end,
638 })
639
640 local function has_locked_chest_privilege(meta, player)
641         if player:get_player_name() ~= meta:get_string("owner") then
642                 return false
643         end
644         return true
645 end
646
647 minetest.register_node("default:chest_locked", {
648         description = "Locked Chest",
649         tiles = {"default_chest_top.png", "default_chest_top.png", "default_chest_side.png",
650                 "default_chest_side.png", "default_chest_side.png", "default_chest_lock.png"},
651         paramtype2 = "facedir",
652         groups = {choppy=2,oddly_breakable_by_hand=2},
653         legacy_facedir_simple = true,
654         sounds = default.node_sound_wood_defaults(),
655         after_place_node = function(pos, placer)
656                 local meta = minetest.env:get_meta(pos)
657                 meta:set_string("owner", placer:get_player_name() or "")
658                 meta:set_string("infotext", "Locked Chest (owned by "..
659                                 meta:get_string("owner")..")")
660         end,
661         on_construct = function(pos)
662                 local meta = minetest.env:get_meta(pos)
663                 meta:set_string("infotext", "Locked Chest")
664                 meta:set_string("owner", "")
665                 local inv = meta:get_inventory()
666                 inv:set_size("main", 8*4)
667         end,
668         can_dig = function(pos,player)
669                 local meta = minetest.env:get_meta(pos);
670                 local inv = meta:get_inventory()
671                 return inv:is_empty("main") and has_locked_chest_privilege(meta, player)
672         end,
673         allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
674                 local meta = minetest.env:get_meta(pos)
675                 if not has_locked_chest_privilege(meta, player) then
676                         minetest.log("action", player:get_player_name()..
677                                         " tried to access a locked chest belonging to "..
678                                         meta:get_string("owner").." at "..
679                                         minetest.pos_to_string(pos))
680                         return 0
681                 end
682                 return count
683         end,
684     allow_metadata_inventory_put = function(pos, listname, index, stack, player)
685                 local meta = minetest.env:get_meta(pos)
686                 if not has_locked_chest_privilege(meta, player) then
687                         minetest.log("action", player:get_player_name()..
688                                         " tried to access a locked chest belonging to "..
689                                         meta:get_string("owner").." at "..
690                                         minetest.pos_to_string(pos))
691                         return 0
692                 end
693                 return stack:get_count()
694         end,
695     allow_metadata_inventory_take = function(pos, listname, index, stack, player)
696                 local meta = minetest.env:get_meta(pos)
697                 if not has_locked_chest_privilege(meta, player) then
698                         minetest.log("action", player:get_player_name()..
699                                         " tried to access a locked chest belonging to "..
700                                         meta:get_string("owner").." at "..
701                                         minetest.pos_to_string(pos))
702                         return 0
703                 end
704                 return stack:get_count()
705         end,
706         on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
707                 minetest.log("action", player:get_player_name()..
708                                 " moves stuff in locked chest at "..minetest.pos_to_string(pos))
709         end,
710     on_metadata_inventory_put = function(pos, listname, index, stack, player)
711                 minetest.log("action", player:get_player_name()..
712                                 " moves stuff to locked chest at "..minetest.pos_to_string(pos))
713         end,
714     on_metadata_inventory_take = function(pos, listname, index, stack, player)
715                 minetest.log("action", player:get_player_name()..
716                                 " takes stuff from locked chest at "..minetest.pos_to_string(pos))
717         end,
718         on_rightclick = function(pos, node, clicker)
719                 local meta = minetest.env:get_meta(pos)
720                 if has_locked_chest_privilege(meta, clicker) then
721                         local pos = pos.x .. "," .. pos.y .. "," ..pos.z
722                         minetest.show_formspec(clicker:get_player_name(), "default:chest_locked",
723                                 "size[8,9]"..
724                                 "list[nodemeta:".. pos .. ";main;0,0;8,4;]"..
725                                 "list[current_player;main;0,5;8,4;]")
726                 end
727         end,
728 })
729
730 default.furnace_inactive_formspec =
731         "size[8,9]"..
732         "image[2,2;1,1;default_furnace_fire_bg.png]"..
733         "list[current_name;fuel;2,3;1,1;]"..
734         "list[current_name;src;2,1;1,1;]"..
735         "list[current_name;dst;5,1;2,2;]"..
736         "list[current_player;main;0,5;8,4;]"
737
738 minetest.register_node("default:furnace", {
739         description = "Furnace",
740         tiles = {"default_furnace_top.png", "default_furnace_bottom.png", "default_furnace_side.png",
741                 "default_furnace_side.png", "default_furnace_side.png", "default_furnace_front.png"},
742         paramtype2 = "facedir",
743         groups = {cracky=2},
744         legacy_facedir_simple = true,
745         sounds = default.node_sound_stone_defaults(),
746         on_construct = function(pos)
747                 local meta = minetest.env:get_meta(pos)
748                 meta:set_string("formspec", default.furnace_inactive_formspec)
749                 meta:set_string("infotext", "Furnace")
750                 local inv = meta:get_inventory()
751                 inv:set_size("fuel", 1)
752                 inv:set_size("src", 1)
753                 inv:set_size("dst", 4)
754         end,
755         can_dig = function(pos,player)
756                 local meta = minetest.env:get_meta(pos);
757                 local inv = meta:get_inventory()
758                 if not inv:is_empty("fuel") then
759                         return false
760                 elseif not inv:is_empty("dst") then
761                         return false
762                 elseif not inv:is_empty("src") then
763                         return false
764                 end
765                 return true
766         end,
767         allow_metadata_inventory_put = function(pos, listname, index, stack, player)
768                 local meta = minetest.env:get_meta(pos)
769                 local inv = meta:get_inventory()
770                 if listname == "fuel" then
771                         if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
772                                 if inv:is_empty("src") then
773                                         meta:set_string("infotext","Furnace is empty")
774                                 end
775                                 return stack:get_count()
776                         else
777                                 return 0
778                         end
779                 elseif listname == "src" then
780                         return stack:get_count()
781                 elseif listname == "dst" then
782                         return 0
783                 end
784         end,
785         allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
786                 local meta = minetest.env:get_meta(pos)
787                 local inv = meta:get_inventory()
788                 local stack = inv:get_stack(from_list, from_index)
789                 if to_list == "fuel" then
790                         if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
791                                 if inv:is_empty("src") then
792                                         meta:set_string("infotext","Furnace is empty")
793                                 end
794                                 return count
795                         else
796                                 return 0
797                         end
798                 elseif to_list == "src" then
799                         return count
800                 elseif to_list == "dst" then
801                         return 0
802                 end
803         end,
804 })
805
806 minetest.register_node("default:furnace_active", {
807         description = "Furnace",
808         tiles = {"default_furnace_top.png", "default_furnace_bottom.png", "default_furnace_side.png",
809                 "default_furnace_side.png", "default_furnace_side.png", "default_furnace_front_active.png"},
810         paramtype2 = "facedir",
811         light_source = 8,
812         drop = "default:furnace",
813         groups = {cracky=2, not_in_creative_inventory=1},
814         legacy_facedir_simple = true,
815         sounds = default.node_sound_stone_defaults(),
816         on_construct = function(pos)
817                 local meta = minetest.env:get_meta(pos)
818                 meta:set_string("formspec", default.furnace_inactive_formspec)
819                 meta:set_string("infotext", "Furnace");
820                 local inv = meta:get_inventory()
821                 inv:set_size("fuel", 1)
822                 inv:set_size("src", 1)
823                 inv:set_size("dst", 4)
824         end,
825         can_dig = function(pos,player)
826                 local meta = minetest.env:get_meta(pos);
827                 local inv = meta:get_inventory()
828                 if not inv:is_empty("fuel") then
829                         return false
830                 elseif not inv:is_empty("dst") then
831                         return false
832                 elseif not inv:is_empty("src") then
833                         return false
834                 end
835                 return true
836         end,
837         allow_metadata_inventory_put = function(pos, listname, index, stack, player)
838                 local meta = minetest.env:get_meta(pos)
839                 local inv = meta:get_inventory()
840                 if listname == "fuel" then
841                         if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
842                                 if inv:is_empty("src") then
843                                         meta:set_string("infotext","Furnace is empty")
844                                 end
845                                 return stack:get_count()
846                         else
847                                 return 0
848                         end
849                 elseif listname == "src" then
850                         return stack:get_count()
851                 elseif listname == "dst" then
852                         return 0
853                 end
854         end,
855         allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
856                 local meta = minetest.env:get_meta(pos)
857                 local inv = meta:get_inventory()
858                 local stack = inv:get_stack(from_list, from_index)
859                 if to_list == "fuel" then
860                         if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
861                                 if inv:is_empty("src") then
862                                         meta:set_string("infotext","Furnace is empty")
863                                 end
864                                 return count
865                         else
866                                 return 0
867                         end
868                 elseif to_list == "src" then
869                         return count
870                 elseif to_list == "dst" then
871                         return 0
872                 end
873         end,
874 })
875
876 function hacky_swap_node(pos,name)
877         local node = minetest.env:get_node(pos)
878         local meta = minetest.env:get_meta(pos)
879         local meta0 = meta:to_table()
880         if node.name == name then
881                 return
882         end
883         node.name = name
884         local meta0 = meta:to_table()
885         minetest.env:set_node(pos,node)
886         meta = minetest.env:get_meta(pos)
887         meta:from_table(meta0)
888 end
889
890 minetest.register_abm({
891         nodenames = {"default:furnace","default:furnace_active"},
892         interval = 1.0,
893         chance = 1,
894         action = function(pos, node, active_object_count, active_object_count_wider)
895                 local meta = minetest.env:get_meta(pos)
896                 for i, name in ipairs({
897                                 "fuel_totaltime",
898                                 "fuel_time",
899                                 "src_totaltime",
900                                 "src_time"
901                 }) do
902                         if meta:get_string(name) == "" then
903                                 meta:set_float(name, 0.0)
904                         end
905                 end
906
907                 local inv = meta:get_inventory()
908
909                 local srclist = inv:get_list("src")
910                 local cooked = nil
911                 local aftercooked
912                 
913                 if srclist then
914                         cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
915                 end
916                 
917                 local was_active = false
918                 
919                 if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
920                         was_active = true
921                         meta:set_float("fuel_time", meta:get_float("fuel_time") + 1)
922                         meta:set_float("src_time", meta:get_float("src_time") + 1)
923                         if cooked and cooked.item and meta:get_float("src_time") >= cooked.time then
924                                 -- check if there's room for output in "dst" list
925                                 if inv:room_for_item("dst",cooked.item) then
926                                         -- Put result in "dst" list
927                                         inv:add_item("dst", cooked.item)
928                                         -- take stuff from "src" list
929                                         inv:set_stack("src", 1, aftercooked.items[1])
930                                 else
931                                         print("Could not insert '"..cooked.item:to_string().."'")
932                                 end
933                                 meta:set_string("src_time", 0)
934                         end
935                 end
936                 
937                 if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
938                         local percent = math.floor(meta:get_float("fuel_time") /
939                                         meta:get_float("fuel_totaltime") * 100)
940                         meta:set_string("infotext","Furnace active: "..percent.."%")
941                         hacky_swap_node(pos,"default:furnace_active")
942                         meta:set_string("formspec",
943                                 "size[8,9]"..
944                                 "image[2,2;1,1;default_furnace_fire_bg.png^[lowpart:"..
945                                                 (100-percent)..":default_furnace_fire_fg.png]"..
946                                 "list[current_name;fuel;2,3;1,1;]"..
947                                 "list[current_name;src;2,1;1,1;]"..
948                                 "list[current_name;dst;5,1;2,2;]"..
949                                 "list[current_player;main;0,5;8,4;]")
950                         return
951                 end
952
953                 local fuel = nil
954                 local afterfuel
955                 local cooked = nil
956                 local fuellist = inv:get_list("fuel")
957                 local srclist = inv:get_list("src")
958                 
959                 if srclist then
960                         cooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
961                 end
962                 if fuellist then
963                         fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist})
964                 end
965
966                 if fuel.time <= 0 then
967                         meta:set_string("infotext","Furnace out of fuel")
968                         hacky_swap_node(pos,"default:furnace")
969                         meta:set_string("formspec", default.furnace_inactive_formspec)
970                         return
971                 end
972
973                 if cooked.item:is_empty() then
974                         if was_active then
975                                 meta:set_string("infotext","Furnace is empty")
976                                 hacky_swap_node(pos,"default:furnace")
977                                 meta:set_string("formspec", default.furnace_inactive_formspec)
978                         end
979                         return
980                 end
981
982                 meta:set_string("fuel_totaltime", fuel.time)
983                 meta:set_string("fuel_time", 0)
984                 
985                 inv:set_stack("fuel", 1, afterfuel.items[1])
986         end,
987 })
988
989 minetest.register_node("default:cobble", {
990         description = "Cobblestone",
991         tiles = {"default_cobble.png"},
992         is_ground_content = true,
993         groups = {cracky=3, stone=2},
994         sounds = default.node_sound_stone_defaults(),
995 })
996
997 minetest.register_node("default:mossycobble", {
998         description = "Mossy Cobblestone",
999         tiles = {"default_mossycobble.png"},
1000         is_ground_content = true,
1001         groups = {cracky=3},
1002         sounds = default.node_sound_stone_defaults(),
1003 })
1004
1005 minetest.register_node("default:coalblock", {
1006         description = "Coal Block",
1007         tiles = {"default_coal_block.png"},
1008         is_ground_content = true,
1009         groups = {cracky=3},
1010         sounds = default.node_sound_stone_defaults(),
1011 })
1012
1013 minetest.register_node("default:steelblock", {
1014         description = "Steel Block",
1015         tiles = {"default_steel_block.png"},
1016         is_ground_content = true,
1017         groups = {cracky=1,level=2},
1018         sounds = default.node_sound_stone_defaults(),
1019 })
1020
1021 minetest.register_node("default:copperblock", {
1022         description = "Copper Block",
1023         tiles = {"default_copper_block.png"},
1024         is_ground_content = true,
1025         groups = {cracky=1,level=2},
1026         sounds = default.node_sound_stone_defaults(),
1027 })
1028
1029 minetest.register_node("default:bronzeblock", {
1030         description = "Bronze Block",
1031         tiles = {"default_bronze_block.png"},
1032         is_ground_content = true,
1033         groups = {cracky=1,level=2},
1034         sounds = default.node_sound_stone_defaults(),
1035 })
1036
1037 minetest.register_node("default:mese", {
1038         description = "Mese Block",
1039         tiles = {"default_mese_block.png"},
1040         is_ground_content = true,
1041         groups = {cracky=1,level=2},
1042         sounds = default.node_sound_stone_defaults(),
1043 })
1044 minetest.register_alias("default:mese_block", "default:mese")
1045
1046 minetest.register_node("default:goldblock", {
1047         description = "Gold Block",
1048         tiles = {"default_gold_block.png"},
1049         is_ground_content = true,
1050         groups = {cracky=1},
1051         sounds = default.node_sound_stone_defaults(),
1052 })
1053
1054 minetest.register_node("default:diamondblock", {
1055         description = "Diamond Block",
1056         tiles = {"default_diamond_block.png"},
1057         is_ground_content = true,
1058         groups = {cracky=1,level=3},
1059         sounds = default.node_sound_stone_defaults(),
1060 })
1061
1062 minetest.register_node("default:obsidian_glass", {
1063         description = "Obsidian Glass",
1064         drawtype = "glasslike",
1065         tiles = {"default_obsidian_glass.png"},
1066         paramtype = "light",
1067         sunlight_propagates = true,
1068         sounds = default.node_sound_glass_defaults(),
1069         groups = {cracky=3,oddly_breakable_by_hand=3},
1070 })
1071
1072 minetest.register_node("default:obsidian", {
1073         description = "Obsidian",
1074         tiles = {"default_obsidian.png"},
1075         is_ground_content = true,
1076         sounds = default.node_sound_stone_defaults(),
1077         groups = {cracky=1,level=2},
1078 })
1079
1080 minetest.register_node("default:nyancat", {
1081         description = "Nyan Cat",
1082         tiles = {"default_nc_side.png", "default_nc_side.png", "default_nc_side.png",
1083                 "default_nc_side.png", "default_nc_back.png", "default_nc_front.png"},
1084         paramtype2 = "facedir",
1085         groups = {cracky=2},
1086         legacy_facedir_simple = true,
1087         sounds = default.node_sound_defaults(),
1088 })
1089
1090 minetest.register_node("default:nyancat_rainbow", {
1091         description = "Nyan Cat Rainbow",
1092         tiles = {"default_nc_rb.png"},
1093         groups = {cracky=2},
1094         sounds = default.node_sound_defaults(),
1095 })
1096
1097 minetest.register_node("default:sapling", {
1098         description = "Sapling",
1099         drawtype = "plantlike",
1100         visual_scale = 1.0,
1101         tiles = {"default_sapling.png"},
1102         inventory_image = "default_sapling.png",
1103         wield_image = "default_sapling.png",
1104         paramtype = "light",
1105         walkable = false,
1106         selection_box = {
1107                 type = "fixed",
1108                 fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3}
1109         },
1110         groups = {snappy=2,dig_immediate=3,flammable=2,attached_node=1},
1111         sounds = default.node_sound_defaults(),
1112 })
1113
1114 minetest.register_node("default:apple", {
1115         description = "Apple",
1116         drawtype = "plantlike",
1117         visual_scale = 1.0,
1118         tiles = {"default_apple.png"},
1119         inventory_image = "default_apple.png",
1120         paramtype = "light",
1121         sunlight_propagates = true,
1122         walkable = false,
1123         selection_box = {
1124                 type = "fixed",
1125                 fixed = {-0.2, -0.5, -0.2, 0.2, 0, 0.2}
1126         },
1127         groups = {fleshy=3,dig_immediate=3,flammable=2},
1128         on_use = minetest.item_eat(4),
1129         sounds = default.node_sound_defaults(),
1130 })
1131
1132 minetest.register_node("default:dry_shrub", {
1133         description = "Dry Shrub",
1134         drawtype = "plantlike",
1135         visual_scale = 1.0,
1136         tiles = {"default_dry_shrub.png"},
1137         inventory_image = "default_dry_shrub.png",
1138         wield_image = "default_dry_shrub.png",
1139         paramtype = "light",
1140         walkable = false,
1141         groups = {snappy=3,flammable=3,attached_node=1},
1142         sounds = default.node_sound_leaves_defaults(),
1143         selection_box = {
1144                 type = "fixed",
1145                 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
1146         },
1147 })
1148
1149 minetest.register_node("default:grass_1", {
1150         description = "Grass",
1151         drawtype = "plantlike",
1152         tiles = {"default_grass_1.png"},
1153         -- use a bigger inventory image
1154         inventory_image = "default_grass_3.png",
1155         wield_image = "default_grass_3.png",
1156         paramtype = "light",
1157         walkable = false,
1158         buildable_to = true,
1159         groups = {snappy=3,flammable=3,flora=1,attached_node=1},
1160         sounds = default.node_sound_leaves_defaults(),
1161         selection_box = {
1162                 type = "fixed",
1163                 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
1164         },
1165         on_place = function(itemstack, placer, pointed_thing)
1166                 -- place a random grass node
1167                 local stack = ItemStack("default:grass_"..math.random(1,5))
1168                 local ret = minetest.item_place(stack, placer, pointed_thing)
1169                 return ItemStack("default:grass_1 "..itemstack:get_count()-(1-ret:get_count()))
1170         end,
1171 })
1172
1173 minetest.register_node("default:grass_2", {
1174         description = "Grass",
1175         drawtype = "plantlike",
1176         tiles = {"default_grass_2.png"},
1177         inventory_image = "default_grass_2.png",
1178         wield_image = "default_grass_2.png",
1179         paramtype = "light",
1180         walkable = false,
1181         buildable_to = true,
1182         is_ground_content = true,
1183         drop = "default:grass_1",
1184         groups = {snappy=3,flammable=3,flora=1,attached_node=1,not_in_creative_inventory=1},
1185         sounds = default.node_sound_leaves_defaults(),
1186         selection_box = {
1187                 type = "fixed",
1188                 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
1189         },
1190 })
1191 minetest.register_node("default:grass_3", {
1192         description = "Grass",
1193         drawtype = "plantlike",
1194         tiles = {"default_grass_3.png"},
1195         inventory_image = "default_grass_3.png",
1196         wield_image = "default_grass_3.png",
1197         paramtype = "light",
1198         walkable = false,
1199         buildable_to = true,
1200         is_ground_content = true,
1201         drop = "default:grass_1",
1202         groups = {snappy=3,flammable=3,flora=1,attached_node=1,not_in_creative_inventory=1},
1203         sounds = default.node_sound_leaves_defaults(),
1204         selection_box = {
1205                 type = "fixed",
1206                 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
1207         },
1208 })
1209
1210 minetest.register_node("default:grass_4", {
1211         description = "Grass",
1212         drawtype = "plantlike",
1213         tiles = {"default_grass_4.png"},
1214         inventory_image = "default_grass_4.png",
1215         wield_image = "default_grass_4.png",
1216         paramtype = "light",
1217         walkable = false,
1218         buildable_to = true,
1219         is_ground_content = true,
1220         drop = "default:grass_1",
1221         groups = {snappy=3,flammable=3,flora=1,attached_node=1,not_in_creative_inventory=1},
1222         sounds = default.node_sound_leaves_defaults(),
1223         selection_box = {
1224                 type = "fixed",
1225                 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
1226         },
1227 })
1228
1229 minetest.register_node("default:grass_5", {
1230         description = "Grass",
1231         drawtype = "plantlike",
1232         tiles = {"default_grass_5.png"},
1233         inventory_image = "default_grass_5.png",
1234         wield_image = "default_grass_5.png",
1235         paramtype = "light",
1236         walkable = false,
1237         buildable_to = true,
1238         is_ground_content = true,
1239         drop = "default:grass_1",
1240         groups = {snappy=3,flammable=3,flora=1,attached_node=1,not_in_creative_inventory=1},
1241         sounds = default.node_sound_leaves_defaults(),
1242         selection_box = {
1243                 type = "fixed",
1244                 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
1245         },
1246 })
1247
1248 minetest.register_node("default:ice", {
1249         description = "Ice",
1250         tiles = {"default_ice.png"},
1251         is_ground_content = true,
1252         paramtype = "light",
1253         groups = {cracky=3},
1254         sounds = default.node_sound_glass_defaults(),
1255 })
1256
1257 minetest.register_node("default:snow", {
1258         description = "Snow",
1259         tiles = {"default_snow.png"},
1260         inventory_image = "default_snowball.png",
1261         wield_image = "default_snowball.png",
1262         is_ground_content = true,
1263         paramtype = "light",
1264         buildable_to = true,
1265         drawtype = "nodebox",
1266         node_box = {
1267                 type = "fixed",
1268                 fixed = {
1269                         {-0.5, -0.5, -0.5,  0.5, -0.5+2/16, 0.5},
1270                 },
1271         },
1272         groups = {crumbly=3,falling_node=1},
1273         sounds = default.node_sound_dirt_defaults({
1274                 footstep = {name="default_grass_footstep", gain=0.4},
1275         }),
1276         on_construct = function(pos)
1277                 pos.y = pos.y - 1
1278                 if minetest.env:get_node(pos).name == "default:dirt_with_grass" then
1279                         minetest.env:set_node(pos, {name="default:dirt_with_snow"})
1280                 end
1281         end,
1282 })
1283 minetest.register_alias("snow", "default:snow")
1284
1285 minetest.register_node("default:snowblock", {
1286         description = "Snow Block",
1287         tiles = {"default_snow.png"},
1288         is_ground_content = true,
1289         groups = {crumbly=3},
1290         sounds = default.node_sound_dirt_defaults({
1291                 footstep = {name="default_grass_footstep", gain=0.4},
1292         }),
1293 })