514feb8d28c44c71eb41bc7589bc953c1fa0f0aa
[oweals/minetest_game.git] / mods / default / init.lua
1 -- Minetest 0.4 mod: default
2 -- See README.txt for licensing and other information.
3
4 -- The API documentation in here was moved into doc/lua_api.txt
5
6 WATER_ALPHA = 160
7 WATER_VISC = 1
8 LAVA_VISC = 7
9 LIGHT_MAX = 14
10
11 -- Definitions made by this mod that other mods can use too
12 default = {}
13
14 -- Load other files
15 dofile(minetest.get_modpath("default").."/player.lua")
16 dofile(minetest.get_modpath("default").."/mapgen.lua")
17 dofile(minetest.get_modpath("default").."/leafdecay.lua")
18
19 --
20 -- Tool definition
21 --
22
23 -- The hand
24 minetest.register_item(":", {
25         type = "none",
26         wield_image = "wieldhand.png",
27         wield_scale = {x=1,y=1,z=2.5},
28         tool_capabilities = {
29                 full_punch_interval = 0.9,
30                 max_drop_level = 0,
31                 groupcaps = {
32                         fleshy = {times={[2]=0.75, [3]=0.6}, uses=0, maxlevel=1},
33                         crumbly = {times={[2]=3.00, [3]=0.70}, uses=0, maxlevel=1},
34                         snappy = {times={[3]=0.40}, uses=0, maxlevel=1},
35                         oddly_breakable_by_hand = {times={[1]=7.00,[2]=4.00,[3]=1.40}, uses=0, maxlevel=3}
36                 }
37         }
38 })
39
40 minetest.register_tool("default:pick_wood", {
41         description = "Wooden Pickaxe",
42         inventory_image = "default_tool_woodpick.png",
43         tool_capabilities = {
44                 full_punch_interval = 1.2,
45                 max_drop_level=0,
46                 groupcaps={
47                         cracky = {times={[2]=2.00, [3]=1.20}, uses=10, maxlevel=1},
48                         fleshy = {times={[2]=0.95, [3]=0.6}, uses=15, maxlevel=1}
49                 }
50         },
51 })
52 minetest.register_tool("default:pick_stone", {
53         description = "Stone Pickaxe",
54         inventory_image = "default_tool_stonepick.png",
55         tool_capabilities = {
56                 full_punch_interval = 1.3,
57                 max_drop_level=0,
58                 groupcaps={
59                         cracky = {times={[1]=3.00, [2]=1.20, [3]=0.80}, uses=20, maxlevel=1},
60                         fleshy = {times={[2]=0.7, [3]=0.5}, uses=25, maxlevel=1}
61                 }
62         },
63 })
64 minetest.register_tool("default:pick_steel", {
65         description = "Steel Pickaxe",
66         inventory_image = "default_tool_steelpick.png",
67         tool_capabilities = {
68                 full_punch_interval = 1.0,
69                 max_drop_level=1,
70                 groupcaps={
71                         cracky = {times={[1]=4.00, [2]=1.60, [3]=1.00}, uses=30, maxlevel=2},
72                         fleshy = {times={[2]=0.6, [3]=0.35}, uses=35, maxlevel=1}
73                 }
74         },
75 })
76 minetest.register_tool("default:pick_mese", {
77         description = "Mese Pickaxe",
78         inventory_image = "default_tool_mesepick.png",
79         tool_capabilities = {
80                 full_punch_interval = 0.65,
81                 max_drop_level=3,
82                 groupcaps={
83                         cracky = {times={[1]=2.0, [2]=1.0, [3]=0.5}, uses=20, maxlevel=3},
84                         crumbly = {times={[1]=2.0, [2]=1.0, [3]=0.5}, uses=20, maxlevel=3},
85                         snappy = {times={[1]=2.0, [2]=1.0, [3]=0.5}, uses=20, maxlevel=3},
86                         fleshy = {times={[2]=0.6, [3]=0.5}, uses=80, maxlevel=1}
87                 }
88         },
89 })
90 minetest.register_tool("default:shovel_wood", {
91         description = "Wooden Shovel",
92         inventory_image = "default_tool_woodshovel.png",
93         wield_image = "default_tool_woodshovel.png^[transformR90",
94         tool_capabilities = {
95                 full_punch_interval = 1.2,
96                 max_drop_level=0,
97                 groupcaps={
98                         crumbly = {times={[1]=3.00, [2]=0.80, [3]=0.50}, uses=10, maxlevel=1},
99                         fleshy = {times={[2]=1.05, [3]=0.70}, uses=25, maxlevel=1}
100                 }
101         },
102 })
103 minetest.register_tool("default:shovel_stone", {
104         description = "Stone Shovel",
105         inventory_image = "default_tool_stoneshovel.png",
106         wield_image = "default_tool_stoneshovel.png^[transformR90",
107         tool_capabilities = {
108                 full_punch_interval = 1.4,
109                 max_drop_level=0,
110                 groupcaps={
111                         crumbly = {times={[1]=1.50, [2]=0.50, [3]=0.30}, uses=20, maxlevel=1},
112                         fleshy = {times={[2]=0.75, [3]=0.50}, uses=40, maxlevel=1}
113                 }
114         },
115 })
116 minetest.register_tool("default:shovel_steel", {
117         description = "Steel Shovel",
118         inventory_image = "default_tool_steelshovel.png",
119         wield_image = "default_tool_steelshovel.png^[transformR90",
120         tool_capabilities = {
121                 full_punch_interval = 1.1,
122                 max_drop_level=1,
123                 groupcaps={
124                         crumbly = {times={[1]=1.50, [2]=0.70, [3]=0.60}, uses=30, maxlevel=2},
125                         fleshy = {times={[2]=0.45, [3]=0.30}, uses=50, maxlevel=1}
126                 }
127         },
128 })
129 minetest.register_tool("default:axe_wood", {
130         description = "Wooden Axe",
131         inventory_image = "default_tool_woodaxe.png",
132         tool_capabilities = {
133                 full_punch_interval = 1.0,
134                 max_drop_level=0,
135                 groupcaps={
136                         choppy = {times={[2]=1.60, [3]=1.20}, uses=10, maxlevel=1},
137                         fleshy = {times={[2]=0.70, [3]=0.50}, uses=5, maxlevel=1}
138                 }
139         },
140 })
141 minetest.register_tool("default:axe_stone", {
142         description = "Stone Axe",
143         inventory_image = "default_tool_stoneaxe.png",
144         tool_capabilities = {
145                 full_punch_interval = 1.2,
146                 max_drop_level=0,
147                 groupcaps={
148                         choppy={times={[1]=3.00, [2]=1.40, [3]=1.00}, uses=20, maxlevel=1},
149                         fleshy={times={[2]=0.60, [3]=0.40}, uses=15, maxlevel=1}
150                 }
151         },
152 })
153 minetest.register_tool("default:axe_steel", {
154         description = "Steel Axe",
155         inventory_image = "default_tool_steelaxe.png",
156         tool_capabilities = {
157                 full_punch_interval = 0.9,
158                 max_drop_level=1,
159                 groupcaps={
160                         choppy={times={[1]=2.60, [2]=1.00, [3]=0.60}, uses=30, maxlevel=2},
161                         fleshy={times={[2]=0.40, [3]=0.25}, uses=25, maxlevel=1}
162                 }
163         },
164 })
165 minetest.register_tool("default:sword_wood", {
166         description = "Wooden Sword",
167         inventory_image = "default_tool_woodsword.png",
168         tool_capabilities = {
169                 full_punch_interval = 0.9,
170                 max_drop_level=0,
171                 groupcaps={
172                         fleshy={times={[2]=1.10, [3]=0.60}, uses=10, maxlevel=1},
173                         snappy={times={[2]=0.9, [3]=0.45}, uses=10, maxlevel=1},
174                         choppy={times={[3]=0.90}, uses=20, maxlevel=0}
175                 }
176         }
177 })
178 minetest.register_tool("default:sword_stone", {
179         description = "Stone Sword",
180         inventory_image = "default_tool_stonesword.png",
181         tool_capabilities = {
182                 full_punch_interval = 1.1,
183                 max_drop_level=0,
184                 groupcaps={
185                         fleshy={times={[2]=0.80, [3]=0.40}, uses=20, maxlevel=1},
186                         snappy={times={[2]=0.75, [3]=0.35}, uses=20, maxlevel=1},
187                         choppy={times={[3]=0.70}, uses=20, maxlevel=0}
188                 }
189         }
190 })
191 minetest.register_tool("default:sword_steel", {
192         description = "Steel Sword",
193         inventory_image = "default_tool_steelsword.png",
194         tool_capabilities = {
195                 full_punch_interval = 0.8,
196                 max_drop_level=1,
197                 groupcaps={
198                         fleshy={times={[1]=2.00, [2]=0.80, [3]=0.40}, uses=10, maxlevel=2},
199                         snappy={times={[2]=0.70, [3]=0.30}, uses=40, maxlevel=1},
200                         choppy={times={[3]=0.65}, uses=40, maxlevel=0}
201                 }
202         }
203 })
204
205 --
206 -- Crafting definition
207 --
208
209 minetest.register_craft({
210         output = 'default:wood 4',
211         recipe = {
212                 {'default:tree'},
213         }
214 })
215
216 minetest.register_craft({
217         output = 'default:junglewood 4',
218         recipe = {
219                 {'default:jungletree'},
220         }
221 })
222
223 minetest.register_craft({
224         output = 'default:stick 4',
225         recipe = {
226                 {'group:wood'},
227         }
228 })
229
230 minetest.register_craft({
231         output = 'default:fence_wood 2',
232         recipe = {
233                 {'default:stick', 'default:stick', 'default:stick'},
234                 {'default:stick', 'default:stick', 'default:stick'},
235         }
236 })
237
238 minetest.register_craft({
239         output = 'default:sign_wall',
240         recipe = {
241                 {'group:wood', 'group:wood', 'group:wood'},
242                 {'group:wood', 'group:wood', 'group:wood'},
243                 {'', 'default:stick', ''},
244         }
245 })
246
247 minetest.register_craft({
248         output = 'default:torch 4',
249         recipe = {
250                 {'default:coal_lump'},
251                 {'default:stick'},
252         }
253 })
254
255 minetest.register_craft({
256         output = 'default:pick_wood',
257         recipe = {
258                 {'group:wood', 'group:wood', 'group:wood'},
259                 {'', 'default:stick', ''},
260                 {'', 'default:stick', ''},
261         }
262 })
263
264 minetest.register_craft({
265         output = 'default:pick_stone',
266         recipe = {
267                 {'group:stone', 'group:stone', 'group:stone'},
268                 {'', 'default:stick', ''},
269                 {'', 'default:stick', ''},
270         }
271 })
272
273 minetest.register_craft({
274         output = 'default:pick_steel',
275         recipe = {
276                 {'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'},
277                 {'', 'default:stick', ''},
278                 {'', 'default:stick', ''},
279         }
280 })
281
282 minetest.register_craft({
283         output = 'default:pick_mese',
284         recipe = {
285                 {'default:mese_crystal', 'default:mese_crystal', 'default:mese_crystal'},
286                 {'', 'default:stick', ''},
287                 {'', 'default:stick', ''},
288         }
289 })
290
291 minetest.register_craft({
292         output = 'default:shovel_wood',
293         recipe = {
294                 {'group:wood'},
295                 {'default:stick'},
296                 {'default:stick'},
297         }
298 })
299
300 minetest.register_craft({
301         output = 'default:shovel_stone',
302         recipe = {
303                 {'group:stone'},
304                 {'default:stick'},
305                 {'default:stick'},
306         }
307 })
308
309 minetest.register_craft({
310         output = 'default:shovel_steel',
311         recipe = {
312                 {'default:steel_ingot'},
313                 {'default:stick'},
314                 {'default:stick'},
315         }
316 })
317
318 minetest.register_craft({
319         output = 'default:axe_wood',
320         recipe = {
321                 {'group:wood', 'group:wood'},
322                 {'group:wood', 'default:stick'},
323                 {'', 'default:stick'},
324         }
325 })
326
327 minetest.register_craft({
328         output = 'default:axe_stone',
329         recipe = {
330                 {'group:stone', 'group:stone'},
331                 {'group:stone', 'default:stick'},
332                 {'', 'default:stick'},
333         }
334 })
335
336 minetest.register_craft({
337         output = 'default:axe_steel',
338         recipe = {
339                 {'default:steel_ingot', 'default:steel_ingot'},
340                 {'default:steel_ingot', 'default:stick'},
341                 {'', 'default:stick'},
342         }
343 })
344
345 minetest.register_craft({
346         output = 'default:sword_wood',
347         recipe = {
348                 {'group:wood'},
349                 {'group:wood'},
350                 {'default:stick'},
351         }
352 })
353
354 minetest.register_craft({
355         output = 'default:sword_stone',
356         recipe = {
357                 {'group:stone'},
358                 {'group:stone'},
359                 {'default:stick'},
360         }
361 })
362
363 minetest.register_craft({
364         output = 'default:sword_steel',
365         recipe = {
366                 {'default:steel_ingot'},
367                 {'default:steel_ingot'},
368                 {'default:stick'},
369         }
370 })
371
372 minetest.register_craft({
373         output = 'default:rail 15',
374         recipe = {
375                 {'default:steel_ingot', '', 'default:steel_ingot'},
376                 {'default:steel_ingot', 'default:stick', 'default:steel_ingot'},
377                 {'default:steel_ingot', '', 'default:steel_ingot'},
378         }
379 })
380
381 minetest.register_craft({
382         output = 'default:chest',
383         recipe = {
384                 {'group:wood', 'group:wood', 'group:wood'},
385                 {'group:wood', '', 'group:wood'},
386                 {'group:wood', 'group:wood', 'group:wood'},
387         }
388 })
389
390 minetest.register_craft({
391         output = 'default:chest_locked',
392         recipe = {
393                 {'group:wood', 'group:wood', 'group:wood'},
394                 {'group:wood', 'default:steel_ingot', 'group:wood'},
395                 {'group:wood', 'group:wood', 'group:wood'},
396         }
397 })
398
399 minetest.register_craft({
400         output = 'default:furnace',
401         recipe = {
402                 {'group:stone', 'group:stone', 'group:stone'},
403                 {'group:stone', '', 'group:stone'},
404                 {'group:stone', 'group:stone', 'group:stone'},
405         }
406 })
407
408 minetest.register_craft({
409         output = 'default:steelblock',
410         recipe = {
411                 {'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'},
412                 {'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'},
413                 {'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'},
414         }
415 })
416
417 minetest.register_craft({
418         output = 'default:steel_ingot 9',
419         recipe = {
420                 {'default:steelblock'},
421         }
422 })
423
424 minetest.register_craft({
425         output = 'default:sandstone',
426         recipe = {
427                 {'group:sand', 'group:sand'},
428                 {'group:sand', 'group:sand'},
429         }
430 })
431
432 minetest.register_craft({
433         output = 'default:sand 4',
434         recipe = {
435                 {'default:sandstone'},
436         }
437 })
438
439 minetest.register_craft({
440         output = 'default:clay',
441         recipe = {
442                 {'default:clay_lump', 'default:clay_lump'},
443                 {'default:clay_lump', 'default:clay_lump'},
444         }
445 })
446
447 minetest.register_craft({
448         output = 'default:brick',
449         recipe = {
450                 {'default:clay_brick', 'default:clay_brick'},
451                 {'default:clay_brick', 'default:clay_brick'},
452         }
453 })
454
455 minetest.register_craft({
456         output = 'default:clay_brick 4',
457         recipe = {
458                 {'default:brick'},
459         }
460 })
461
462 minetest.register_craft({
463         output = 'default:paper',
464         recipe = {
465                 {'default:papyrus', 'default:papyrus', 'default:papyrus'},
466         }
467 })
468
469 minetest.register_craft({
470         output = 'default:book',
471         recipe = {
472                 {'default:paper'},
473                 {'default:paper'},
474                 {'default:paper'},
475         }
476 })
477
478 minetest.register_craft({
479         output = 'default:bookshelf',
480         recipe = {
481                 {'group:wood', 'group:wood', 'group:wood'},
482                 {'default:book', 'default:book', 'default:book'},
483                 {'group:wood', 'group:wood', 'group:wood'},
484         }
485 })
486
487 minetest.register_craft({
488         output = 'default:ladder',
489         recipe = {
490                 {'default:stick', '', 'default:stick'},
491                 {'default:stick', 'default:stick', 'default:stick'},
492                 {'default:stick', '', 'default:stick'},
493         }
494 })
495
496 minetest.register_craft({
497         output = 'default:mese',
498         recipe = {
499                 {'default:mese_crystal', 'default:mese_crystal', 'default:mese_crystal'},
500                 {'default:mese_crystal', 'default:mese_crystal', 'default:mese_crystal'},
501                 {'default:mese_crystal', 'default:mese_crystal', 'default:mese_crystal'},
502         }
503 })
504
505 minetest.register_craft({
506         output = 'default:mese_crystal 9',
507         recipe = {
508                 {'default:mese'},
509         }
510 })
511
512 minetest.register_craft({
513         output = 'default:mese_crystal_fragment 9',
514         recipe = {
515                 {'default:mese_crystal'},
516         }
517 })
518
519 minetest.register_craft({
520         output = 'default:obsidian_shard 9',
521         recipe = {
522                 {'default:obsidian'}
523         }
524 })
525
526 minetest.register_craft({
527         output = 'default:obsidian',
528         recipe = {
529                 {'default:obsidian_shard', 'default:obsidian_shard', 'default:obsidian_shard'},
530                 {'default:obsidian_shard', 'default:obsidian_shard', 'default:obsidian_shard'},
531                 {'default:obsidian_shard', 'default:obsidian_shard', 'default:obsidian_shard'},
532         }
533 })
534
535 minetest.register_craft({
536         output = 'default:stonebrick',
537         recipe = {
538                 {'default:stone', 'default:stone'},
539                 {'default:stone', 'default:stone'},
540         }
541 })
542
543 --
544 -- Crafting (tool repair)
545 --
546 minetest.register_craft({
547         type = "toolrepair",
548         additional_wear = -0.02,
549 })
550
551 --
552 -- Cooking recipes
553 --
554
555 minetest.register_craft({
556         type = "cooking",
557         output = "default:glass",
558         recipe = "group:sand",
559 })
560
561 minetest.register_craft({
562         type = "cooking",
563         output = "default:obsidian_glass",
564         recipe = "default:obsidian_shard",
565 })
566
567 minetest.register_craft({
568         type = "cooking",
569         output = "default:stone",
570         recipe = "default:cobble",
571 })
572
573 minetest.register_craft({
574         type = "cooking",
575         output = "default:steel_ingot",
576         recipe = "default:iron_lump",
577 })
578
579 minetest.register_craft({
580         type = "cooking",
581         output = "default:clay_brick",
582         recipe = "default:clay_lump",
583 })
584
585 --
586 -- Fuels
587 --
588
589 minetest.register_craft({
590         type = "fuel",
591         recipe = "group:tree",
592         burntime = 30,
593 })
594
595 minetest.register_craft({
596         type = "fuel",
597         recipe = "default:junglegrass",
598         burntime = 2,
599 })
600
601 minetest.register_craft({
602         type = "fuel",
603         recipe = "group:leaves",
604         burntime = 1,
605 })
606
607 minetest.register_craft({
608         type = "fuel",
609         recipe = "default:cactus",
610         burntime = 15,
611 })
612
613 minetest.register_craft({
614         type = "fuel",
615         recipe = "default:papyrus",
616         burntime = 1,
617 })
618
619 minetest.register_craft({
620         type = "fuel",
621         recipe = "default:bookshelf",
622         burntime = 30,
623 })
624
625 minetest.register_craft({
626         type = "fuel",
627         recipe = "default:fence_wood",
628         burntime = 15,
629 })
630
631 minetest.register_craft({
632         type = "fuel",
633         recipe = "default:ladder",
634         burntime = 5,
635 })
636
637 minetest.register_craft({
638         type = "fuel",
639         recipe = "group:wood",
640         burntime = 7,
641 })
642
643 minetest.register_craft({
644         type = "fuel",
645         recipe = "default:lava_source",
646         burntime = 60,
647 })
648
649 minetest.register_craft({
650         type = "fuel",
651         recipe = "default:torch",
652         burntime = 4,
653 })
654
655 minetest.register_craft({
656         type = "fuel",
657         recipe = "default:sign_wall",
658         burntime = 10,
659 })
660
661 minetest.register_craft({
662         type = "fuel",
663         recipe = "default:chest",
664         burntime = 30,
665 })
666
667 minetest.register_craft({
668         type = "fuel",
669         recipe = "default:chest_locked",
670         burntime = 30,
671 })
672
673 minetest.register_craft({
674         type = "fuel",
675         recipe = "default:nyancat",
676         burntime = 1,
677 })
678
679 minetest.register_craft({
680         type = "fuel",
681         recipe = "default:nyancat_rainbow",
682         burntime = 1,
683 })
684
685 minetest.register_craft({
686         type = "fuel",
687         recipe = "default:sapling",
688         burntime = 10,
689 })
690
691 minetest.register_craft({
692         type = "fuel",
693         recipe = "default:apple",
694         burntime = 3,
695 })
696
697 minetest.register_craft({
698         type = "fuel",
699         recipe = "default:coal_lump",
700         burntime = 40,
701 })
702
703 minetest.register_craft({
704         type = "fuel",
705         recipe = "default:junglesapling",
706         burntime = 10,
707 })
708
709 minetest.register_craft({
710         type = "fuel",
711         recipe = "default:grass_1",
712         burntime = 2,
713 })
714
715 --
716 -- Node definitions
717 --
718
719 -- Default node sounds
720
721 function default.node_sound_defaults(table)
722         table = table or {}
723         table.footstep = table.footstep or
724                         {name="", gain=1.0}
725         table.dug = table.dug or
726                         {name="default_dug_node", gain=1.0}
727         return table
728 end
729
730 function default.node_sound_stone_defaults(table)
731         table = table or {}
732         table.footstep = table.footstep or
733                         {name="default_hard_footstep", gain=0.2}
734         default.node_sound_defaults(table)
735         return table
736 end
737
738 function default.node_sound_dirt_defaults(table)
739         table = table or {}
740         table.footstep = table.footstep or
741                         {name="", gain=0.5}
742         --table.dug = table.dug or
743         --              {name="default_dirt_break", gain=0.5}
744         default.node_sound_defaults(table)
745         return table
746 end
747
748 function default.node_sound_sand_defaults(table)
749         table = table or {}
750         table.footstep = table.footstep or
751                         {name="default_grass_footstep", gain=0.25}
752         --table.dug = table.dug or
753         --              {name="default_dirt_break", gain=0.25}
754         table.dug = table.dug or
755                         {name="", gain=0.25}
756         default.node_sound_defaults(table)
757         return table
758 end
759
760 function default.node_sound_wood_defaults(table)
761         table = table or {}
762         table.footstep = table.footstep or
763                         {name="default_hard_footstep", gain=0.3}
764         default.node_sound_defaults(table)
765         return table
766 end
767
768 function default.node_sound_leaves_defaults(table)
769         table = table or {}
770         table.footstep = table.footstep or
771                         {name="default_grass_footstep", gain=0.25}
772         table.dig = table.dig or
773                         {name="default_dig_crumbly", gain=0.4}
774         table.dug = table.dug or
775                         {name="", gain=1.0}
776         default.node_sound_defaults(table)
777         return table
778 end
779
780 function default.node_sound_glass_defaults(table)
781         table = table or {}
782         table.footstep = table.footstep or
783                         {name="default_hard_footstep", gain=0.25}
784         table.dug = table.dug or
785                         {name="default_break_glass", gain=1.0}
786         default.node_sound_defaults(table)
787         return table
788 end
789
790 --
791
792 minetest.register_node("default:stone", {
793         description = "Stone",
794         tiles = {"default_stone.png"},
795         is_ground_content = true,
796         groups = {cracky=3, stone=1},
797         drop = 'default:cobble',
798         legacy_mineral = true,
799         sounds = default.node_sound_stone_defaults(),
800 })
801
802 minetest.register_node("default:desert_stone", {
803         description = "Desert Stone",
804         tiles = {"default_desert_stone.png"},
805         is_ground_content = true,
806         groups = {cracky=3, stone=1},
807         drop = 'default:desert_stone',
808         legacy_mineral = true,
809         sounds = default.node_sound_stone_defaults(),
810 })
811
812 minetest.register_node("default:stone_with_coal", {
813         description = "Coal Ore",
814         tiles = {"default_stone.png^default_mineral_coal.png"},
815         is_ground_content = true,
816         groups = {cracky=3},
817         drop = 'default:coal_lump',
818         sounds = default.node_sound_stone_defaults(),
819 })
820
821 minetest.register_node("default:stone_with_iron", {
822         description = "Iron Ore",
823         tiles = {"default_stone.png^default_mineral_iron.png"},
824         is_ground_content = true,
825         groups = {cracky=3},
826         drop = 'default:iron_lump',
827         sounds = default.node_sound_stone_defaults(),
828 })
829
830 minetest.register_node("default:stone_with_mese", {
831         description = "Mese Crystals in Stone",
832         tiles = {"default_stone.png^default_mineral_mese.png"},
833         is_ground_content = true,
834         groups = {cracky=1},
835         drop = "default:mese_crystal",
836         sounds = default.node_sound_stone_defaults(),
837 })
838
839 minetest.register_node("default:stonebrick", {
840         description = "Stone Brick",
841         tiles = {"default_stone_brick.png"},
842         is_ground_content = true,
843         groups = {cracky=3, stone=1},
844         sounds = default.node_sound_stone_defaults(),
845 })
846
847 minetest.register_node("default:dirt_with_grass", {
848         description = "Dirt with Grass",
849         tiles = {"default_grass.png", "default_dirt.png", "default_dirt.png^default_grass_side.png"},
850         is_ground_content = true,
851         groups = {crumbly=3},
852         drop = 'default:dirt',
853         sounds = default.node_sound_dirt_defaults({
854                 footstep = {name="default_grass_footstep", gain=0.4},
855         }),
856 })
857
858 minetest.register_node("default:dirt_with_grass_footsteps", {
859         description = "Dirt with Grass and Footsteps",
860         tiles = {"default_grass_footsteps.png", "default_dirt.png", "default_dirt.png^default_grass_side.png"},
861         is_ground_content = true,
862         groups = {crumbly=3, not_in_creative_inventory=1},
863         drop = 'default:dirt',
864         sounds = default.node_sound_dirt_defaults({
865                 footstep = {name="default_grass_footstep", gain=0.4},
866         }),
867 })
868
869 minetest.register_node("default:dirt", {
870         description = "Dirt",
871         tiles = {"default_dirt.png"},
872         is_ground_content = true,
873         groups = {crumbly=3},
874         sounds = default.node_sound_dirt_defaults(),
875 })
876
877 minetest.register_node("default:sand", {
878         description = "Sand",
879         tiles = {"default_sand.png"},
880         is_ground_content = true,
881         groups = {crumbly=3, falling_node=1, sand=1},
882         sounds = default.node_sound_sand_defaults(),
883 })
884
885 minetest.register_node("default:desert_sand", {
886         description = "Desert Sand",
887         tiles = {"default_desert_sand.png"},
888         is_ground_content = true,
889         groups = {crumbly=3, falling_node=1, sand=1},
890         sounds = default.node_sound_sand_defaults(),
891 })
892
893 minetest.register_node("default:gravel", {
894         description = "Gravel",
895         tiles = {"default_gravel.png"},
896         is_ground_content = true,
897         groups = {crumbly=2, falling_node=1},
898         sounds = default.node_sound_dirt_defaults({
899                 footstep = {name="default_gravel_footstep", gain=0.45},
900         }),
901 })
902
903 minetest.register_node("default:sandstone", {
904         description = "Sandstone",
905         tiles = {"default_sandstone.png"},
906         is_ground_content = true,
907         groups = {crumbly=2,cracky=2},
908         sounds = default.node_sound_stone_defaults(),
909 })
910
911 minetest.register_node("default:clay", {
912         description = "Clay",
913         tiles = {"default_clay.png"},
914         is_ground_content = true,
915         groups = {crumbly=3},
916         drop = 'default:clay_lump 4',
917         sounds = default.node_sound_dirt_defaults({
918                 footstep = "",
919         }),
920 })
921
922 minetest.register_node("default:brick", {
923         description = "Brick Block",
924         tiles = {"default_brick.png"},
925         is_ground_content = true,
926         groups = {cracky=3},
927         sounds = default.node_sound_stone_defaults(),
928 })
929
930 minetest.register_node("default:tree", {
931         description = "Tree",
932         tiles = {"default_tree_top.png", "default_tree_top.png", "default_tree.png"},
933         is_ground_content = true,
934         groups = {tree=1,snappy=1,choppy=2,oddly_breakable_by_hand=1,flammable=2},
935         sounds = default.node_sound_wood_defaults(),
936 })
937
938 minetest.register_node("default:jungletree", {
939         description = "Jungle Tree",
940         tiles = {"default_jungletree_top.png", "default_jungletree_top.png", "default_jungletree.png"},
941         is_ground_content = true,
942         groups = {tree=1,snappy=1,choppy=2,oddly_breakable_by_hand=1,flammable=2},
943         sounds = default.node_sound_wood_defaults(),
944 })
945
946 minetest.register_node("default:junglewood", {
947         description = "Junglewood Planks",
948         tiles = {"default_junglewood.png"},
949         is_ground_content = true,
950         groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3,wood=1},
951         sounds = default.node_sound_wood_defaults(),
952 })
953
954 minetest.register_node("default:jungleleaves", {
955         description = "Jungle Leaves",
956         drawtype = "allfaces_optional",
957         visual_scale = 1.3,
958         tiles = {"default_jungleleaves.png"},
959         paramtype = "light",
960         groups = {snappy=3, leafdecay=3, flammable=2, leaves=1},
961         drop = {
962                 max_items = 1,
963                 items = {
964                         {
965                                 -- player will get sapling with 1/20 chance
966                                 items = {'default:junglesapling'},
967                                 rarity = 20,
968                         },
969                         {
970                                 -- player will get leaves only if he get no saplings,
971                                 -- this is because max_items is 1
972                                 items = {'default:jungleleaves'},
973                         }
974                 }
975         },
976         sounds = default.node_sound_leaves_defaults(),
977 })
978
979 minetest.register_node("default:junglesapling", {
980         description = "Jungle Sapling",
981         drawtype = "plantlike",
982         visual_scale = 1.0,
983         tiles = {"default_junglesapling.png"},
984         inventory_image = "default_junglesapling.png",
985         wield_image = "default_junglesapling.png",
986         paramtype = "light",
987         walkable = false,
988         selection_box = {
989                 type = "fixed",
990                 fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3}
991         },
992         groups = {snappy=2,dig_immediate=3,flammable=2,attached_node=1},
993         sounds = default.node_sound_defaults(),
994 })
995 -- alias for tree growing abm in content_abm.cpp
996 minetest.register_alias("junglesapling", "default:junglesapling")
997
998 minetest.register_node("default:junglegrass", {
999         description = "Jungle Grass",
1000         drawtype = "plantlike",
1001         visual_scale = 1.3,
1002         tiles = {"default_junglegrass.png"},
1003         inventory_image = "default_junglegrass.png",
1004         wield_image = "default_junglegrass.png",
1005         paramtype = "light",
1006         walkable = false,
1007         groups = {snappy=3,flammable=2,attached_node=1},
1008         sounds = default.node_sound_leaves_defaults(),
1009         selection_box = {
1010                 type = "fixed",
1011                 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
1012         },
1013 })
1014
1015 minetest.register_node("default:leaves", {
1016         description = "Leaves",
1017         drawtype = "allfaces_optional",
1018         visual_scale = 1.3,
1019         tiles = {"default_leaves.png"},
1020         paramtype = "light",
1021         groups = {snappy=3, leafdecay=3, flammable=2, leaves=1},
1022         drop = {
1023                 max_items = 1,
1024                 items = {
1025                         {
1026                                 -- player will get sapling with 1/20 chance
1027                                 items = {'default:sapling'},
1028                                 rarity = 20,
1029                         },
1030                         {
1031                                 -- player will get leaves only if he get no saplings,
1032                                 -- this is because max_items is 1
1033                                 items = {'default:leaves'},
1034                         }
1035                 }
1036         },
1037         sounds = default.node_sound_leaves_defaults(),
1038 })
1039
1040 minetest.register_node("default:cactus", {
1041         description = "Cactus",
1042         tiles = {"default_cactus_top.png", "default_cactus_top.png", "default_cactus_side.png"},
1043         is_ground_content = true,
1044         groups = {snappy=2,choppy=3,flammable=2},
1045         sounds = default.node_sound_wood_defaults(),
1046 })
1047
1048 minetest.register_node("default:papyrus", {
1049         description = "Papyrus",
1050         drawtype = "plantlike",
1051         tiles = {"default_papyrus.png"},
1052         inventory_image = "default_papyrus.png",
1053         wield_image = "default_papyrus.png",
1054         paramtype = "light",
1055         is_ground_content = true,
1056         walkable = false,
1057         selection_box = {
1058                 type = "fixed",
1059                 fixed = {-0.3, -0.5, -0.3, 0.3, 0.5, 0.3}
1060         },
1061         groups = {snappy=3,flammable=2},
1062         sounds = default.node_sound_leaves_defaults(),
1063 })
1064
1065 minetest.register_node("default:bookshelf", {
1066         description = "Bookshelf",
1067         tiles = {"default_wood.png", "default_wood.png", "default_bookshelf.png"},
1068         is_ground_content = true,
1069         groups = {snappy=2,choppy=3,oddly_breakable_by_hand=2,flammable=3},
1070         sounds = default.node_sound_wood_defaults(),
1071 })
1072
1073 minetest.register_node("default:glass", {
1074         description = "Glass",
1075         drawtype = "glasslike",
1076         tiles = {"default_glass.png"},
1077         inventory_image = minetest.inventorycube("default_glass.png"),
1078         paramtype = "light",
1079         sunlight_propagates = true,
1080         is_ground_content = true,
1081         groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3},
1082         sounds = default.node_sound_glass_defaults(),
1083 })
1084
1085 minetest.register_node("default:fence_wood", {
1086         description = "Wooden Fence",
1087         drawtype = "fencelike",
1088         tiles = {"default_wood.png"},
1089         inventory_image = "default_fence.png",
1090         wield_image = "default_fence.png",
1091         paramtype = "light",
1092         is_ground_content = true,
1093         selection_box = {
1094                 type = "fixed",
1095                 fixed = {-1/7, -1/2, -1/7, 1/7, 1/2, 1/7},
1096         },
1097         groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=2},
1098         sounds = default.node_sound_wood_defaults(),
1099 })
1100
1101 minetest.register_node("default:rail", {
1102         description = "Rail",
1103         drawtype = "raillike",
1104         tiles = {"default_rail.png", "default_rail_curved.png", "default_rail_t_junction.png", "default_rail_crossing.png"},
1105         inventory_image = "default_rail.png",
1106         wield_image = "default_rail.png",
1107         paramtype = "light",
1108         is_ground_content = true,
1109         walkable = false,
1110         selection_box = {
1111                 type = "fixed",
1112                 -- but how to specify the dimensions for curved and sideways rails?
1113                 fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
1114         },
1115         groups = {bendy=2,snappy=1,dig_immediate=2,attached_node=1},
1116 })
1117
1118 minetest.register_node("default:ladder", {
1119         description = "Ladder",
1120         drawtype = "signlike",
1121         tiles = {"default_ladder.png"},
1122         inventory_image = "default_ladder.png",
1123         wield_image = "default_ladder.png",
1124         paramtype = "light",
1125         paramtype2 = "wallmounted",
1126         is_ground_content = true,
1127         walkable = false,
1128         climbable = true,
1129         selection_box = {
1130                 type = "wallmounted",
1131                 --wall_top = = <default>
1132                 --wall_bottom = = <default>
1133                 --wall_side = = <default>
1134         },
1135         groups = {snappy=1,choppy=2,oddly_breakable_by_hand=3,flammable=2},
1136         legacy_wallmounted = true,
1137         sounds = default.node_sound_wood_defaults(),
1138 })
1139
1140 minetest.register_node("default:wood", {
1141         description = "Wooden Planks",
1142         tiles = {"default_wood.png"},
1143         is_ground_content = true,
1144         groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3,wood=1},
1145         sounds = default.node_sound_wood_defaults(),
1146 })
1147
1148 minetest.register_node("default:cloud", {
1149         description = "Cloud",
1150         tiles = {"default_cloud.png"},
1151         is_ground_content = true,
1152         sounds = default.node_sound_defaults(),
1153         groups = {not_in_creative_inventory=1},
1154 })
1155
1156 minetest.register_node("default:water_flowing", {
1157         description = "Flowing Water",
1158         inventory_image = minetest.inventorycube("default_water.png"),
1159         drawtype = "flowingliquid",
1160         tiles = {"default_water.png"},
1161         special_tiles = {
1162                 {
1163                         image="default_water_flowing_animated.png",
1164                         backface_culling=false,
1165                         animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=0.8}
1166                 },
1167                 {
1168                         image="default_water_flowing_animated.png",
1169                         backface_culling=true,
1170                         animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=0.8}
1171                 },
1172         },
1173         alpha = WATER_ALPHA,
1174         paramtype = "light",
1175         walkable = false,
1176         pointable = false,
1177         diggable = false,
1178         buildable_to = true,
1179         drop = "",
1180         liquidtype = "flowing",
1181         liquid_alternative_flowing = "default:water_flowing",
1182         liquid_alternative_source = "default:water_source",
1183         liquid_viscosity = WATER_VISC,
1184         post_effect_color = {a=64, r=100, g=100, b=200},
1185         groups = {water=3, liquid=3, puts_out_fire=1, not_in_creative_inventory=1},
1186 })
1187
1188 minetest.register_node("default:water_source", {
1189         description = "Water Source",
1190         inventory_image = minetest.inventorycube("default_water.png"),
1191         drawtype = "liquid",
1192         tiles = {
1193                 {name="default_water_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}}
1194         },
1195         special_tiles = {
1196                 -- New-style water source material (mostly unused)
1197                 {
1198                         name="default_water_source_animated.png",
1199                         animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0},
1200                         backface_culling = false,
1201                 }
1202         },
1203         alpha = WATER_ALPHA,
1204         paramtype = "light",
1205         walkable = false,
1206         pointable = false,
1207         diggable = false,
1208         buildable_to = true,
1209         drop = "",
1210         liquidtype = "source",
1211         liquid_alternative_flowing = "default:water_flowing",
1212         liquid_alternative_source = "default:water_source",
1213         liquid_viscosity = WATER_VISC,
1214         post_effect_color = {a=64, r=100, g=100, b=200},
1215         groups = {water=3, liquid=3, puts_out_fire=1},
1216 })
1217
1218 minetest.register_node("default:lava_flowing", {
1219         description = "Flowing Lava",
1220         inventory_image = minetest.inventorycube("default_lava.png"),
1221         drawtype = "flowingliquid",
1222         tiles = {"default_lava.png"},
1223         special_tiles = {
1224                 {
1225                         image="default_lava_flowing_animated.png",
1226                         backface_culling=false,
1227                         animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.3}
1228                 },
1229                 {
1230                         image="default_lava_flowing_animated.png",
1231                         backface_culling=true,
1232                         animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.3}
1233                 },
1234         },
1235         paramtype = "light",
1236         light_source = LIGHT_MAX - 1,
1237         walkable = false,
1238         pointable = false,
1239         diggable = false,
1240         buildable_to = true,
1241         drop = "",
1242         liquidtype = "flowing",
1243         liquid_alternative_flowing = "default:lava_flowing",
1244         liquid_alternative_source = "default:lava_source",
1245         liquid_viscosity = LAVA_VISC,
1246         liquid_renewable = false,
1247         damage_per_second = 4*2,
1248         post_effect_color = {a=192, r=255, g=64, b=0},
1249         groups = {lava=3, liquid=2, hot=3, igniter=1, not_in_creative_inventory=1},
1250 })
1251
1252 minetest.register_node("default:lava_source", {
1253         description = "Lava Source",
1254         inventory_image = minetest.inventorycube("default_lava.png"),
1255         drawtype = "liquid",
1256         tiles = {
1257                 {name="default_lava_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}}
1258         },
1259         special_tiles = {
1260                 -- New-style lava source material (mostly unused)
1261                 {
1262                         name="default_lava_source_animated.png",
1263                         animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0},
1264                         backface_culling = false,
1265                 }
1266         },
1267         paramtype = "light",
1268         light_source = LIGHT_MAX - 1,
1269         walkable = false,
1270         pointable = false,
1271         diggable = false,
1272         buildable_to = true,
1273         drop = "",
1274         liquidtype = "source",
1275         liquid_alternative_flowing = "default:lava_flowing",
1276         liquid_alternative_source = "default:lava_source",
1277         liquid_viscosity = LAVA_VISC,
1278         liquid_renewable = false,
1279         damage_per_second = 4*2,
1280         post_effect_color = {a=192, r=255, g=64, b=0},
1281         groups = {lava=3, liquid=2, hot=3, igniter=1},
1282 })
1283
1284 minetest.register_node("default:torch", {
1285         description = "Torch",
1286         drawtype = "torchlike",
1287         --tiles = {"default_torch_on_floor.png", "default_torch_on_ceiling.png", "default_torch.png"},
1288         tiles = {
1289                 {name="default_torch_on_floor_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}},
1290                 {name="default_torch_on_ceiling_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}},
1291                 {name="default_torch_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}}
1292         },
1293         inventory_image = "default_torch_on_floor.png",
1294         wield_image = "default_torch_on_floor.png",
1295         paramtype = "light",
1296         paramtype2 = "wallmounted",
1297         sunlight_propagates = true,
1298         walkable = false,
1299         light_source = LIGHT_MAX-1,
1300         selection_box = {
1301                 type = "wallmounted",
1302                 wall_top = {-0.1, 0.5-0.6, -0.1, 0.1, 0.5, 0.1},
1303                 wall_bottom = {-0.1, -0.5, -0.1, 0.1, -0.5+0.6, 0.1},
1304                 wall_side = {-0.5, -0.3, -0.1, -0.5+0.3, 0.3, 0.1},
1305         },
1306         groups = {choppy=2,dig_immediate=3,flammable=1,attached_node=1},
1307         legacy_wallmounted = true,
1308         sounds = default.node_sound_defaults(),
1309 })
1310
1311 minetest.register_node("default:sign_wall", {
1312         description = "Sign",
1313         drawtype = "signlike",
1314         tiles = {"default_sign_wall.png"},
1315         inventory_image = "default_sign_wall.png",
1316         wield_image = "default_sign_wall.png",
1317         paramtype = "light",
1318         paramtype2 = "wallmounted",
1319         sunlight_propagates = true,
1320         walkable = false,
1321         selection_box = {
1322                 type = "wallmounted",
1323                 --wall_top = <default>
1324                 --wall_bottom = <default>
1325                 --wall_side = <default>
1326         },
1327         groups = {choppy=2,dig_immediate=2,attached_node=1},
1328         legacy_wallmounted = true,
1329         sounds = default.node_sound_defaults(),
1330         on_construct = function(pos)
1331                 --local n = minetest.env:get_node(pos)
1332                 local meta = minetest.env:get_meta(pos)
1333                 meta:set_string("formspec", "field[text;;${text}]")
1334                 meta:set_string("infotext", "\"\"")
1335         end,
1336         on_receive_fields = function(pos, formname, fields, sender)
1337                 --print("Sign at "..minetest.pos_to_string(pos).." got "..dump(fields))
1338                 local meta = minetest.env:get_meta(pos)
1339                 fields.text = fields.text or ""
1340                 print((sender:get_player_name() or "").." wrote \""..fields.text..
1341                                 "\" to sign at "..minetest.pos_to_string(pos))
1342                 meta:set_string("text", fields.text)
1343                 meta:set_string("infotext", '"'..fields.text..'"')
1344         end,
1345 })
1346
1347 minetest.register_node("default:chest", {
1348         description = "Chest",
1349         tiles = {"default_chest_top.png", "default_chest_top.png", "default_chest_side.png",
1350                 "default_chest_side.png", "default_chest_side.png", "default_chest_front.png"},
1351         paramtype2 = "facedir",
1352         groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2},
1353         legacy_facedir_simple = true,
1354         sounds = default.node_sound_wood_defaults(),
1355         on_construct = function(pos)
1356                 local meta = minetest.env:get_meta(pos)
1357                 meta:set_string("formspec",
1358                                 "size[8,9]"..
1359                                 "list[current_name;main;0,0;8,4;]"..
1360                                 "list[current_player;main;0,5;8,4;]")
1361                 meta:set_string("infotext", "Chest")
1362                 local inv = meta:get_inventory()
1363                 inv:set_size("main", 8*4)
1364         end,
1365         can_dig = function(pos,player)
1366                 local meta = minetest.env:get_meta(pos);
1367                 local inv = meta:get_inventory()
1368                 return inv:is_empty("main")
1369         end,
1370         on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
1371                 minetest.log("action", player:get_player_name()..
1372                                 " moves stuff in chest at "..minetest.pos_to_string(pos))
1373         end,
1374     on_metadata_inventory_put = function(pos, listname, index, stack, player)
1375                 minetest.log("action", player:get_player_name()..
1376                                 " moves stuff to chest at "..minetest.pos_to_string(pos))
1377         end,
1378     on_metadata_inventory_take = function(pos, listname, index, stack, player)
1379                 minetest.log("action", player:get_player_name()..
1380                                 " takes stuff from chest at "..minetest.pos_to_string(pos))
1381         end,
1382 })
1383
1384 local function has_locked_chest_privilege(meta, player)
1385         if player:get_player_name() ~= meta:get_string("owner") then
1386                 return false
1387         end
1388         return true
1389 end
1390
1391 minetest.register_node("default:chest_locked", {
1392         description = "Locked Chest",
1393         tiles = {"default_chest_top.png", "default_chest_top.png", "default_chest_side.png",
1394                 "default_chest_side.png", "default_chest_side.png", "default_chest_lock.png"},
1395         paramtype2 = "facedir",
1396         groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2},
1397         legacy_facedir_simple = true,
1398         sounds = default.node_sound_wood_defaults(),
1399         after_place_node = function(pos, placer)
1400                 local meta = minetest.env:get_meta(pos)
1401                 meta:set_string("owner", placer:get_player_name() or "")
1402                 meta:set_string("infotext", "Locked Chest (owned by "..
1403                                 meta:get_string("owner")..")")
1404         end,
1405         on_construct = function(pos)
1406                 local meta = minetest.env:get_meta(pos)
1407                 meta:set_string("infotext", "Locked Chest")
1408                 meta:set_string("owner", "")
1409                 local inv = meta:get_inventory()
1410                 inv:set_size("main", 8*4)
1411         end,
1412         can_dig = function(pos,player)
1413                 local meta = minetest.env:get_meta(pos);
1414                 local inv = meta:get_inventory()
1415                 return inv:is_empty("main")
1416         end,
1417         allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
1418                 local meta = minetest.env:get_meta(pos)
1419                 if not has_locked_chest_privilege(meta, player) then
1420                         minetest.log("action", player:get_player_name()..
1421                                         " tried to access a locked chest belonging to "..
1422                                         meta:get_string("owner").." at "..
1423                                         minetest.pos_to_string(pos))
1424                         return 0
1425                 end
1426                 return count
1427         end,
1428     allow_metadata_inventory_put = function(pos, listname, index, stack, player)
1429                 local meta = minetest.env:get_meta(pos)
1430                 if not has_locked_chest_privilege(meta, player) then
1431                         minetest.log("action", player:get_player_name()..
1432                                         " tried to access a locked chest belonging to "..
1433                                         meta:get_string("owner").." at "..
1434                                         minetest.pos_to_string(pos))
1435                         return 0
1436                 end
1437                 return stack:get_count()
1438         end,
1439     allow_metadata_inventory_take = function(pos, listname, index, stack, player)
1440                 local meta = minetest.env:get_meta(pos)
1441                 if not has_locked_chest_privilege(meta, player) then
1442                         minetest.log("action", player:get_player_name()..
1443                                         " tried to access a locked chest belonging to "..
1444                                         meta:get_string("owner").." at "..
1445                                         minetest.pos_to_string(pos))
1446                         return 0
1447                 end
1448                 return stack:get_count()
1449         end,
1450         on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
1451                 minetest.log("action", player:get_player_name()..
1452                                 " moves stuff in locked chest at "..minetest.pos_to_string(pos))
1453         end,
1454     on_metadata_inventory_put = function(pos, listname, index, stack, player)
1455                 minetest.log("action", player:get_player_name()..
1456                                 " moves stuff to locked chest at "..minetest.pos_to_string(pos))
1457         end,
1458     on_metadata_inventory_take = function(pos, listname, index, stack, player)
1459                 minetest.log("action", player:get_player_name()..
1460                                 " takes stuff from locked chest at "..minetest.pos_to_string(pos))
1461         end,
1462         on_rightclick = function(pos, node, clicker)
1463                 local meta = minetest.env:get_meta(pos)
1464                 if has_locked_chest_privilege(meta, clicker) then
1465                         local pos = pos.x .. "," .. pos.y .. "," ..pos.z
1466                         minetest.show_formspec(clicker:get_player_name(), "default:chest_locked",
1467                                 "size[8,9]"..
1468                                 "list[nodemeta:".. pos .. ";main;0,0;8,4;]"..
1469                                 "list[current_player;main;0,5;8,4;]")
1470                 end
1471         end,
1472 })
1473
1474 default.furnace_inactive_formspec =
1475         "size[8,9]"..
1476         "image[2,2;1,1;default_furnace_fire_bg.png]"..
1477         "list[current_name;fuel;2,3;1,1;]"..
1478         "list[current_name;src;2,1;1,1;]"..
1479         "list[current_name;dst;5,1;2,2;]"..
1480         "list[current_player;main;0,5;8,4;]"
1481
1482 minetest.register_node("default:furnace", {
1483         description = "Furnace",
1484         tiles = {"default_furnace_top.png", "default_furnace_bottom.png", "default_furnace_side.png",
1485                 "default_furnace_side.png", "default_furnace_side.png", "default_furnace_front.png"},
1486         paramtype2 = "facedir",
1487         groups = {cracky=2},
1488         legacy_facedir_simple = true,
1489         sounds = default.node_sound_stone_defaults(),
1490         on_construct = function(pos)
1491                 local meta = minetest.env:get_meta(pos)
1492                 meta:set_string("formspec", default.furnace_inactive_formspec)
1493                 meta:set_string("infotext", "Furnace")
1494                 local inv = meta:get_inventory()
1495                 inv:set_size("fuel", 1)
1496                 inv:set_size("src", 1)
1497                 inv:set_size("dst", 4)
1498         end,
1499         can_dig = function(pos,player)
1500                 local meta = minetest.env:get_meta(pos);
1501                 local inv = meta:get_inventory()
1502                 if not inv:is_empty("fuel") then
1503                         return false
1504                 elseif not inv:is_empty("dst") then
1505                         return false
1506                 elseif not inv:is_empty("src") then
1507                         return false
1508                 end
1509                 return true
1510         end,
1511         allow_metadata_inventory_put = function(pos, listname, index, stack, player)
1512                 if listname == "fuel" then
1513                         if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
1514                                 return stack:get_count()
1515                         else
1516                                 return 0
1517                         end
1518                 elseif listname == "src" then
1519                         return stack:get_count()
1520                 elseif listname == "dst" then
1521                         return 0
1522                 end
1523         end,
1524         allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
1525                 local stack = ItemStack(minetest.env:get_meta(pos):get_inventory():get_stack(from_list, from_index))
1526                 if to_list == "fuel" then
1527                         if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
1528                                 return count
1529                         else
1530                                 return 0
1531                         end
1532                 elseif to_list == "src" then
1533                         return count
1534                 elseif to_list == "dst" then
1535                         return 0
1536                 end
1537         end,
1538 })
1539
1540 minetest.register_node("default:furnace_active", {
1541         description = "Furnace",
1542         tiles = {"default_furnace_top.png", "default_furnace_bottom.png", "default_furnace_side.png",
1543                 "default_furnace_side.png", "default_furnace_side.png", "default_furnace_front_active.png"},
1544         paramtype2 = "facedir",
1545         light_source = 8,
1546         drop = "default:furnace",
1547         groups = {cracky=2, not_in_creative_inventory=1},
1548         legacy_facedir_simple = true,
1549         sounds = default.node_sound_stone_defaults(),
1550         on_construct = function(pos)
1551                 local meta = minetest.env:get_meta(pos)
1552                 meta:set_string("formspec", default.furnace_inactive_formspec)
1553                 meta:set_string("infotext", "Furnace");
1554                 local inv = meta:get_inventory()
1555                 inv:set_size("fuel", 1)
1556                 inv:set_size("src", 1)
1557                 inv:set_size("dst", 4)
1558         end,
1559         can_dig = function(pos,player)
1560                 local meta = minetest.env:get_meta(pos);
1561                 local inv = meta:get_inventory()
1562                 if not inv:is_empty("fuel") then
1563                         return false
1564                 elseif not inv:is_empty("dst") then
1565                         return false
1566                 elseif not inv:is_empty("src") then
1567                         return false
1568                 end
1569                 return true
1570         end,
1571         allow_metadata_inventory_put = function(pos, listname, index, stack, player)
1572                 if listname == "fuel" then
1573                         if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
1574                                 return stack:get_count()
1575                         else
1576                                 return 0
1577                         end
1578                 elseif listname == "src" then
1579                         return stack:get_count()
1580                 elseif listname == "dst" then
1581                         return 0
1582                 end
1583         end,
1584         allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
1585                 local stack = ItemStack(minetest.env:get_meta(pos):get_inventory():get_stack(from_list, from_index))
1586                 if to_list == "fuel" then
1587                         if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
1588                                 return count
1589                         else
1590                                 return 0
1591                         end
1592                 elseif to_list == "src" then
1593                         return count
1594                 elseif to_list == "dst" then
1595                         return 0
1596                 end
1597         end,
1598 })
1599
1600 function hacky_swap_node(pos,name)
1601         local node = minetest.env:get_node(pos)
1602         local meta = minetest.env:get_meta(pos)
1603         local meta0 = meta:to_table()
1604         if node.name == name then
1605                 return
1606         end
1607         node.name = name
1608         local meta0 = meta:to_table()
1609         minetest.env:set_node(pos,node)
1610         meta = minetest.env:get_meta(pos)
1611         meta:from_table(meta0)
1612 end
1613
1614 minetest.register_abm({
1615         nodenames = {"default:furnace","default:furnace_active"},
1616         interval = 1.0,
1617         chance = 1,
1618         action = function(pos, node, active_object_count, active_object_count_wider)
1619                 local meta = minetest.env:get_meta(pos)
1620                 for i, name in ipairs({
1621                                 "fuel_totaltime",
1622                                 "fuel_time",
1623                                 "src_totaltime",
1624                                 "src_time"
1625                 }) do
1626                         if meta:get_string(name) == "" then
1627                                 meta:set_float(name, 0.0)
1628                         end
1629                 end
1630
1631                 local inv = meta:get_inventory()
1632
1633                 local srclist = inv:get_list("src")
1634                 local cooked = nil
1635                 local aftercooked
1636                 
1637                 if srclist then
1638                         cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
1639                 end
1640                 
1641                 local was_active = false
1642                 
1643                 if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
1644                         was_active = true
1645                         meta:set_float("fuel_time", meta:get_float("fuel_time") + 1)
1646                         meta:set_float("src_time", meta:get_float("src_time") + 1)
1647                         if cooked and cooked.item and meta:get_float("src_time") >= cooked.time then
1648                                 -- check if there's room for output in "dst" list
1649                                 if inv:room_for_item("dst",cooked.item) then
1650                                         -- Put result in "dst" list
1651                                         inv:add_item("dst", cooked.item)
1652                                         -- take stuff from "src" list
1653                                         inv:set_stack("src", 1, aftercooked.items[1])
1654                                 else
1655                                         print("Could not insert '"..cooked.item:to_string().."'")
1656                                 end
1657                                 meta:set_string("src_time", 0)
1658                         end
1659                 end
1660                 
1661                 if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
1662                         local percent = math.floor(meta:get_float("fuel_time") /
1663                                         meta:get_float("fuel_totaltime") * 100)
1664                         meta:set_string("infotext","Furnace active: "..percent.."%")
1665                         hacky_swap_node(pos,"default:furnace_active")
1666                         meta:set_string("formspec",
1667                                 "size[8,9]"..
1668                                 "image[2,2;1,1;default_furnace_fire_bg.png^[lowpart:"..
1669                                                 (100-percent)..":default_furnace_fire_fg.png]"..
1670                                 "list[current_name;fuel;2,3;1,1;]"..
1671                                 "list[current_name;src;2,1;1,1;]"..
1672                                 "list[current_name;dst;5,1;2,2;]"..
1673                                 "list[current_player;main;0,5;8,4;]")
1674                         return
1675                 end
1676
1677                 local fuel = nil
1678                 local afterfuel
1679                 local cooked = nil
1680                 local fuellist = inv:get_list("fuel")
1681                 local srclist = inv:get_list("src")
1682                 
1683                 if srclist then
1684                         cooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
1685                 end
1686                 if fuellist then
1687                         fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist})
1688                 end
1689
1690                 if fuel.time <= 0 then
1691                         meta:set_string("infotext","Furnace out of fuel")
1692                         hacky_swap_node(pos,"default:furnace")
1693                         meta:set_string("formspec", default.furnace_inactive_formspec)
1694                         return
1695                 end
1696
1697                 if cooked.item:is_empty() then
1698                         if was_active then
1699                                 meta:set_string("infotext","Furnace is empty")
1700                                 hacky_swap_node(pos,"default:furnace")
1701                                 meta:set_string("formspec", default.furnace_inactive_formspec)
1702                         end
1703                         return
1704                 end
1705
1706                 meta:set_string("fuel_totaltime", fuel.time)
1707                 meta:set_string("fuel_time", 0)
1708                 
1709                 inv:set_stack("fuel", 1, afterfuel.items[1])
1710         end,
1711 })
1712
1713 minetest.register_node("default:cobble", {
1714         description = "Cobblestone",
1715         tiles = {"default_cobble.png"},
1716         is_ground_content = true,
1717         groups = {cracky=3, stone=2},
1718         sounds = default.node_sound_stone_defaults(),
1719 })
1720
1721 minetest.register_node("default:mossycobble", {
1722         description = "Mossy Cobblestone",
1723         tiles = {"default_mossycobble.png"},
1724         is_ground_content = true,
1725         groups = {cracky=3},
1726         sounds = default.node_sound_stone_defaults(),
1727 })
1728
1729 minetest.register_node("default:steelblock", {
1730         description = "Steel Block",
1731         tiles = {"default_steel_block.png"},
1732         is_ground_content = true,
1733         groups = {snappy=1,bendy=2,cracky=1,melty=2,level=2},
1734         sounds = default.node_sound_stone_defaults(),
1735 })
1736
1737 minetest.register_node("default:mese", {
1738         description = "Mese Block",
1739         tiles = {"default_mese_block.png"},
1740         is_ground_content = true,
1741         groups = {cracky=1},
1742         sounds = default.node_sound_stone_defaults(),
1743 })
1744 minetest.register_alias("default:mese_block", "default:mese")
1745
1746
1747 minetest.register_node("default:obsidian_glass", {
1748         description = "Obsidian Glass",
1749         drawtype = "glasslike",
1750         tiles = {"default_obsidian_glass.png"},
1751         is_ground_content = true,
1752         paramtype = "light",
1753         sunlight_propagates = true,
1754         sounds = default.node_sound_glass_defaults(),
1755         groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3},
1756 })
1757
1758 minetest.register_node("default:obsidian", {
1759         description = "Obsidian",
1760         tiles = {"default_obsidian.png"},
1761         is_ground_content = true,
1762         sounds = default.node_sound_stone_defaults(),
1763         groups = {cracky=1,level=2},
1764 })
1765
1766 minetest.register_node("default:nyancat", {
1767         description = "Nyan Cat",
1768         tiles = {"default_nc_side.png", "default_nc_side.png", "default_nc_side.png",
1769                 "default_nc_side.png", "default_nc_back.png", "default_nc_front.png"},
1770         paramtype2 = "facedir",
1771         groups = {cracky=2},
1772         legacy_facedir_simple = true,
1773         sounds = default.node_sound_defaults(),
1774 })
1775
1776 minetest.register_node("default:nyancat_rainbow", {
1777         description = "Nyan Cat Rainbow",
1778         tiles = {"default_nc_rb.png"},
1779         groups = {cracky=2},
1780         sounds = default.node_sound_defaults(),
1781 })
1782
1783 minetest.register_node("default:sapling", {
1784         description = "Sapling",
1785         drawtype = "plantlike",
1786         visual_scale = 1.0,
1787         tiles = {"default_sapling.png"},
1788         inventory_image = "default_sapling.png",
1789         wield_image = "default_sapling.png",
1790         paramtype = "light",
1791         walkable = false,
1792         selection_box = {
1793                 type = "fixed",
1794                 fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3}
1795         },
1796         groups = {snappy=2,dig_immediate=3,flammable=2,attached_node=1},
1797         sounds = default.node_sound_defaults(),
1798 })
1799
1800 minetest.register_node("default:apple", {
1801         description = "Apple",
1802         drawtype = "plantlike",
1803         visual_scale = 1.0,
1804         tiles = {"default_apple.png"},
1805         inventory_image = "default_apple.png",
1806         paramtype = "light",
1807         sunlight_propagates = true,
1808         walkable = false,
1809         selection_box = {
1810                 type = "fixed",
1811                 fixed = {-0.2, -0.5, -0.2, 0.2, 0, 0.2}
1812         },
1813         groups = {fleshy=3,dig_immediate=3,flammable=2},
1814         on_use = minetest.item_eat(4),
1815         sounds = default.node_sound_defaults(),
1816 })
1817
1818 minetest.register_node("default:dry_shrub", {
1819         description = "Dry Shrub",
1820         drawtype = "plantlike",
1821         visual_scale = 1.0,
1822         tiles = {"default_dry_shrub.png"},
1823         inventory_image = "default_dry_shrub.png",
1824         wield_image = "default_dry_shrub.png",
1825         paramtype = "light",
1826         walkable = false,
1827         groups = {snappy=3,flammable=3,attached_node=1},
1828         sounds = default.node_sound_leaves_defaults(),
1829         selection_box = {
1830                 type = "fixed",
1831                 fixed = {-1/3, -1/2, -1/3, 1/3, 1/6, 1/3},
1832         },
1833 })
1834
1835 minetest.register_node("default:grass_1", {
1836         description = "Grass",
1837         drawtype = "plantlike",
1838         tiles = {"default_grass_1.png"},
1839         -- use a bigger inventory image
1840         inventory_image = "default_grass_3.png",
1841         wield_image = "default_grass_3.png",
1842         paramtype = "light",
1843         walkable = false,
1844         groups = {snappy=3,flammable=3,attached_node=1},
1845         sounds = default.node_sound_leaves_defaults(),
1846         selection_box = {
1847                 type = "fixed",
1848                 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
1849         },
1850         on_place = function(itemstack, placer, pointed_thing)
1851                 -- place a random grass node
1852                 local stack = ItemStack("default:grass_"..math.random(1,5))
1853                 local ret = minetest.item_place(stack, placer, pointed_thing)
1854                 return ItemStack("default:grass_1 "..itemstack:get_count()-(1-ret:get_count()))
1855         end,
1856 })
1857
1858 minetest.register_node("default:grass_2", {
1859         description = "Grass",
1860         drawtype = "plantlike",
1861         tiles = {"default_grass_2.png"},
1862         inventory_image = "default_grass_2.png",
1863         wield_image = "default_grass_2.png",
1864         paramtype = "light",
1865         walkable = false,
1866         drop = "default:grass_1",
1867         groups = {snappy=3,flammable=3,attached_node=1,not_in_creative_inventory=1},
1868         sounds = default.node_sound_leaves_defaults(),
1869         selection_box = {
1870                 type = "fixed",
1871                 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
1872         },
1873 })
1874 minetest.register_node("default:grass_3", {
1875         description = "Grass",
1876         drawtype = "plantlike",
1877         tiles = {"default_grass_3.png"},
1878         inventory_image = "default_grass_3.png",
1879         wield_image = "default_grass_3.png",
1880         paramtype = "light",
1881         walkable = false,
1882         drop = "default:grass_1",
1883         groups = {snappy=3,flammable=3,attached_node=1,not_in_creative_inventory=1},
1884         sounds = default.node_sound_leaves_defaults(),
1885         selection_box = {
1886                 type = "fixed",
1887                 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
1888         },
1889 })
1890
1891 minetest.register_node("default:grass_4", {
1892         description = "Grass",
1893         drawtype = "plantlike",
1894         tiles = {"default_grass_4.png"},
1895         inventory_image = "default_grass_4.png",
1896         wield_image = "default_grass_4.png",
1897         paramtype = "light",
1898         walkable = false,
1899         drop = "default:grass_1",
1900         groups = {snappy=3,flammable=3,attached_node=1,not_in_creative_inventory=1},
1901         sounds = default.node_sound_leaves_defaults(),
1902         selection_box = {
1903                 type = "fixed",
1904                 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
1905         },
1906 })
1907
1908 minetest.register_node("default:grass_5", {
1909         description = "Grass",
1910         drawtype = "plantlike",
1911         tiles = {"default_grass_5.png"},
1912         inventory_image = "default_grass_5.png",
1913         wield_image = "default_grass_5.png",
1914         paramtype = "light",
1915         walkable = false,
1916         drop = "default:grass_1",
1917         groups = {snappy=3,flammable=3,attached_node=1,not_in_creative_inventory=1},
1918         sounds = default.node_sound_leaves_defaults(),
1919         selection_box = {
1920                 type = "fixed",
1921                 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
1922         },
1923 })
1924
1925 --
1926 -- Crafting items
1927 --
1928
1929 minetest.register_craftitem("default:stick", {
1930         description = "Stick",
1931         inventory_image = "default_stick.png",
1932 })
1933
1934 minetest.register_craftitem("default:paper", {
1935         description = "Paper",
1936         inventory_image = "default_paper.png",
1937 })
1938
1939 minetest.register_craftitem("default:book", {
1940         description = "Book",
1941         inventory_image = "default_book.png",
1942 })
1943
1944 minetest.register_craftitem("default:coal_lump", {
1945         description = "Coal Lump",
1946         inventory_image = "default_coal_lump.png",
1947 })
1948
1949 minetest.register_craftitem("default:iron_lump", {
1950         description = "Iron Lump",
1951         inventory_image = "default_iron_lump.png",
1952 })
1953
1954 minetest.register_craftitem("default:mese_crystal", {
1955         description = "Mese Crystal",
1956         inventory_image = "default_mese_crystal.png",
1957 })
1958
1959 minetest.register_craftitem("default:clay_lump", {
1960         description = "Clay Lump",
1961         inventory_image = "default_clay_lump.png",
1962 })
1963
1964 minetest.register_craftitem("default:steel_ingot", {
1965         description = "Steel Ingot",
1966         inventory_image = "default_steel_ingot.png",
1967 })
1968
1969 minetest.register_craftitem("default:mese_crystal_fragment", {
1970         description = "Mese Crystal Fragment",
1971         inventory_image = "default_mese_crystal_fragment.png",
1972 })
1973
1974 minetest.register_craftitem("default:clay_brick", {
1975         description = "Clay Brick",
1976         inventory_image = "default_clay_brick.png",
1977 })
1978
1979 minetest.register_craftitem("default:scorched_stuff", {
1980         description = "Scorched Stuff",
1981         inventory_image = "default_scorched_stuff.png",
1982 })
1983
1984 minetest.register_craftitem("default:obsidian_shard", {
1985         description = "Obsidian Shard",
1986         inventory_image = "default_obsidian_shard.png",
1987 })
1988
1989 -- Support old code
1990 function default.spawn_falling_node(p, nodename)
1991         spawn_falling_node(p, nodename)
1992 end
1993
1994 -- Horrible crap to support old code
1995 -- Don't use this and never do what this does, it's completely wrong!
1996 -- (More specifically, the client and the C++ code doesn't get the group)
1997 function default.register_falling_node(nodename, texture)
1998         minetest.log("error", debug.traceback())
1999         minetest.log('error', "WARNING: default.register_falling_node is deprecated")
2000         if minetest.registered_nodes[nodename] then
2001                 minetest.registered_nodes[nodename].groups.falling_node = 1
2002         end
2003 end
2004
2005 --
2006 -- Global callbacks
2007 --
2008
2009 -- Global environment step function
2010 function on_step(dtime)
2011         -- print("on_step")
2012 end
2013 minetest.register_globalstep(on_step)
2014
2015 function on_placenode(p, node)
2016         --print("on_placenode")
2017 end
2018 minetest.register_on_placenode(on_placenode)
2019
2020 function on_dignode(p, node)
2021         --print("on_dignode")
2022 end
2023 minetest.register_on_dignode(on_dignode)
2024
2025 function on_punchnode(p, node)
2026 end
2027 minetest.register_on_punchnode(on_punchnode)
2028
2029 --
2030 -- Lavacooling
2031 --
2032
2033 default.cool_lava_source = function(pos)
2034         minetest.env:set_node(pos, {name="default:obsidian"})
2035 end
2036
2037 default.cool_lava_flowing = function(pos)
2038         minetest.env:set_node(pos, {name="default:stone"})
2039 end
2040
2041 minetest.register_abm({
2042         nodenames = {"default:lava_flowing"},
2043         neighbors = {"group:water"},
2044         interval = 1,
2045         chance = 1,
2046         action = function(pos, node, active_object_count, active_object_count_wider)
2047                 default.cool_lava_flowing(pos, node, active_object_count, active_object_count_wider)
2048         end,
2049 })
2050
2051 minetest.register_abm({
2052         nodenames = {"default:lava_source"},
2053         neighbors = {"group:water"},
2054         interval = 1,
2055         chance = 1,
2056         action = function(pos, node, active_object_count, active_object_count_wider)
2057                 default.cool_lava_source(pos, node, active_object_count, active_object_count_wider)
2058         end,
2059 })
2060
2061 --
2062 -- Papyrus and cactus growing
2063 --
2064
2065 minetest.register_abm({
2066         nodenames = {"default:cactus"},
2067         neighbors = {"group:sand"},
2068         interval = 50,
2069         chance = 20,
2070         action = function(pos, node)
2071                 pos.y = pos.y-1
2072                 local name = minetest.env:get_node(pos).name
2073                 if minetest.get_item_group(name, "sand") ~= 0 then
2074                         pos.y = pos.y+1
2075                         local height = 0
2076                         while minetest.env:get_node(pos).name == "default:cactus" and height < 4 do
2077                                 height = height+1
2078                                 pos.y = pos.y+1
2079                         end
2080                         if height < 4 then
2081                                 if minetest.env:get_node(pos).name == "air" then
2082                                         minetest.env:set_node(pos, {name="default:cactus"})
2083                                 end
2084                         end
2085                 end
2086         end,
2087 })
2088
2089 minetest.register_abm({
2090         nodenames = {"default:papyrus"},
2091         neighbors = {"default:dirt", "default:dirt_with_grass"},
2092         interval = 50,
2093         chance = 20,
2094         action = function(pos, node)
2095                 pos.y = pos.y-1
2096                 local name = minetest.env:get_node(pos).name
2097                 if name == "default:dirt" or name == "default:dirt_with_grass" then
2098                         if minetest.env:find_node_near(pos, 3, {"group:water"}) == nil then
2099                                 return
2100                         end
2101                         pos.y = pos.y+1
2102                         local height = 0
2103                         while minetest.env:get_node(pos).name == "default:papyrus" and height < 4 do
2104                                 height = height+1
2105                                 pos.y = pos.y+1
2106                         end
2107                         if height < 4 then
2108                                 if minetest.env:get_node(pos).name == "air" then
2109                                         minetest.env:set_node(pos, {name="default:papyrus"})
2110                                 end
2111                         end
2112                 end
2113         end,
2114 })
2115
2116 -- END