Fix relief mapping issues
[oweals/minetest.git] / games / minimal / mods / default / init.lua
1 -- default (Minetest 0.4 mod)
2 -- Most default stuff
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").."/mapgen.lua")
16
17 -- Set a noticeable inventory formspec for players
18 minetest.register_on_joinplayer(function(player)
19         local cb = function(player)
20                 minetest.chat_send_player(player:get_player_name(), "This is the [minimal] \"Minimal Development Test\" game. Use [minetest_game] for the real thing.")
21         end
22         minetest.after(2.0, cb, player)
23 end)
24
25 --
26 -- Tool definition
27 --
28
29 -- The hand
30 minetest.register_item(":", {
31         type = "none",
32         wield_image = "wieldhand.png",
33         wield_scale = {x=1,y=1,z=2.5},
34         tool_capabilities = {
35                 full_punch_interval = 1.0,
36                 max_drop_level = 0,
37                 groupcaps = {
38                         fleshy = {times={[2]=2.00, [3]=1.00}, uses=0, maxlevel=1},
39                         crumbly = {times={[2]=3.00, [3]=0.70}, uses=0, maxlevel=1},
40                         snappy = {times={[3]=0.40}, uses=0, maxlevel=1},
41                         oddly_breakable_by_hand = {times={[1]=7.00,[2]=4.00,[3]=1.40}, uses=0, maxlevel=3},
42                 }
43         }
44 })
45
46 minetest.register_tool("default:pick_wood", {
47         description = "Wooden Pickaxe",
48         inventory_image = "default_tool_woodpick.png",
49         tool_capabilities = {
50                 max_drop_level=0,
51                 groupcaps={
52                         cracky={times={[2]=2.00, [3]=1.20}, uses=10, maxlevel=1}
53                 }
54         },
55 })
56 minetest.register_tool("default:pick_stone", {
57         description = "Stone Pickaxe",
58         inventory_image = "default_tool_stonepick.png",
59         tool_capabilities = {
60                 max_drop_level=0,
61                 groupcaps={
62                         cracky={times={[1]=2.00, [2]=1.20, [3]=0.80}, uses=20, maxlevel=1}
63                 }
64         },
65 })
66 minetest.register_tool("default:pick_steel", {
67         description = "Steel Pickaxe",
68         inventory_image = "default_tool_steelpick.png",
69         tool_capabilities = {
70                 max_drop_level=1,
71                 groupcaps={
72                         cracky={times={[1]=4.00, [2]=1.60, [3]=1.00}, uses=10, maxlevel=2}
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 = 1.0,
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                 }
87         },
88 })
89 minetest.register_tool("default:shovel_wood", {
90         description = "Wooden Shovel",
91         inventory_image = "default_tool_woodshovel.png",
92         tool_capabilities = {
93                 max_drop_level=0,
94                 groupcaps={
95                         crumbly={times={[1]=2.00, [2]=0.80, [3]=0.50}, uses=10, maxlevel=1}
96                 }
97         },
98 })
99 minetest.register_tool("default:shovel_stone", {
100         description = "Stone Shovel",
101         inventory_image = "default_tool_stoneshovel.png",
102         tool_capabilities = {
103                 max_drop_level=0,
104                 groupcaps={
105                         crumbly={times={[1]=1.20, [2]=0.50, [3]=0.30}, uses=20, maxlevel=1}
106                 }
107         },
108 })
109 minetest.register_tool("default:shovel_steel", {
110         description = "Steel Shovel",
111         inventory_image = "default_tool_steelshovel.png",
112         tool_capabilities = {
113                 max_drop_level=1,
114                 groupcaps={
115                         crumbly={times={[1]=1.00, [2]=0.70, [3]=0.60}, uses=10, maxlevel=2}
116                 }
117         },
118 })
119 minetest.register_tool("default:axe_wood", {
120         description = "Wooden Axe",
121         inventory_image = "default_tool_woodaxe.png",
122         tool_capabilities = {
123                 max_drop_level=0,
124                 groupcaps={
125                         choppy={times={[2]=1.40, [3]=0.80}, uses=10, maxlevel=1},
126                         fleshy={times={[2]=1.50, [3]=0.80}, uses=10, maxlevel=1}
127                 }
128         },
129 })
130 minetest.register_tool("default:axe_stone", {
131         description = "Stone Axe",
132         inventory_image = "default_tool_stoneaxe.png",
133         tool_capabilities = {
134                 max_drop_level=0,
135                 groupcaps={
136                         choppy={times={[1]=1.50, [2]=1.00, [3]=0.60}, uses=20, maxlevel=1},
137                         fleshy={times={[2]=1.30, [3]=0.70}, uses=20, maxlevel=1}
138                 }
139         },
140 })
141 minetest.register_tool("default:axe_steel", {
142         description = "Steel Axe",
143         inventory_image = "default_tool_steelaxe.png",
144         tool_capabilities = {
145                 max_drop_level=1,
146                 groupcaps={
147                         choppy={times={[1]=2.00, [2]=1.60, [3]=1.00}, uses=10, maxlevel=2},
148                         fleshy={times={[2]=1.10, [3]=0.60}, uses=40, maxlevel=1}
149                 }
150         },
151 })
152 minetest.register_tool("default:sword_wood", {
153         description = "Wooden Sword",
154         inventory_image = "default_tool_woodsword.png",
155         tool_capabilities = {
156                 full_punch_interval = 1.0,
157                 max_drop_level=0,
158                 groupcaps={
159                         fleshy={times={[2]=1.10, [3]=0.60}, uses=10, maxlevel=1},
160                         snappy={times={[2]=1.00, [3]=0.50}, uses=10, maxlevel=1},
161                         choppy={times={[3]=1.00}, uses=20, maxlevel=0}
162                 }
163         }
164 })
165 minetest.register_tool("default:sword_stone", {
166         description = "Stone Sword",
167         inventory_image = "default_tool_stonesword.png",
168         tool_capabilities = {
169                 full_punch_interval = 1.0,
170                 max_drop_level=0,
171                 groupcaps={
172                         fleshy={times={[2]=0.80, [3]=0.40}, uses=20, maxlevel=1},
173                         snappy={times={[2]=0.80, [3]=0.40}, uses=20, maxlevel=1},
174                         choppy={times={[3]=0.90}, uses=20, maxlevel=0}
175                 }
176         }
177 })
178 minetest.register_tool("default:sword_steel", {
179         description = "Steel Sword",
180         inventory_image = "default_tool_steelsword.png",
181         tool_capabilities = {
182                 full_punch_interval = 1.0,
183                 max_drop_level=1,
184                 groupcaps={
185                         fleshy={times={[1]=2.00, [2]=0.80, [3]=0.40}, uses=10, maxlevel=2},
186                         snappy={times={[2]=0.70, [3]=0.30}, uses=40, maxlevel=1},
187                         choppy={times={[3]=0.70}, uses=40, maxlevel=0}
188                 }
189         }
190 })
191
192 --
193 -- Crafting definition
194 --
195
196 minetest.register_craft({
197         output = 'default:wood 4',
198         recipe = {
199                 {'default:tree'},
200         }
201 })
202
203 minetest.register_craft({
204         output = 'default:stick 4',
205         recipe = {
206                 {'default:wood'},
207         }
208 })
209
210 minetest.register_craft({
211         output = 'default:fence_wood 2',
212         recipe = {
213                 {'default:stick', 'default:stick', 'default:stick'},
214                 {'default:stick', 'default:stick', 'default:stick'},
215         }
216 })
217
218 minetest.register_craft({
219         output = 'default:sign_wall',
220         recipe = {
221                 {'default:wood', 'default:wood', 'default:wood'},
222                 {'default:wood', 'default:wood', 'default:wood'},
223                 {'', 'default:stick', ''},
224         }
225 })
226
227 minetest.register_craft({
228         output = 'default:torch 4',
229         recipe = {
230                 {'default:coal_lump'},
231                 {'default:stick'},
232         }
233 })
234
235 minetest.register_craft({
236         output = 'default:pick_wood',
237         recipe = {
238                 {'default:wood', 'default:wood', 'default:wood'},
239                 {'', 'default:stick', ''},
240                 {'', 'default:stick', ''},
241         }
242 })
243
244 minetest.register_craft({
245         output = 'default:pick_stone',
246         recipe = {
247                 {'default:cobble', 'default:cobble', 'default:cobble'},
248                 {'', 'default:stick', ''},
249                 {'', 'default:stick', ''},
250         }
251 })
252
253 minetest.register_craft({
254         output = 'default:pick_steel',
255         recipe = {
256                 {'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'},
257                 {'', 'default:stick', ''},
258                 {'', 'default:stick', ''},
259         }
260 })
261
262 minetest.register_craft({
263         output = 'default:pick_mese',
264         recipe = {
265                 {'default:mese', 'default:mese', 'default:mese'},
266                 {'', 'default:stick', ''},
267                 {'', 'default:stick', ''},
268         }
269 })
270
271 minetest.register_craft({
272         output = 'default:shovel_wood',
273         recipe = {
274                 {'default:wood'},
275                 {'default:stick'},
276                 {'default:stick'},
277         }
278 })
279
280 minetest.register_craft({
281         output = 'default:shovel_stone',
282         recipe = {
283                 {'default:cobble'},
284                 {'default:stick'},
285                 {'default:stick'},
286         }
287 })
288
289 minetest.register_craft({
290         output = 'default:shovel_steel',
291         recipe = {
292                 {'default:steel_ingot'},
293                 {'default:stick'},
294                 {'default:stick'},
295         }
296 })
297
298 minetest.register_craft({
299         output = 'default:axe_wood',
300         recipe = {
301                 {'default:wood', 'default:wood'},
302                 {'default:wood', 'default:stick'},
303                 {'', 'default:stick'},
304         }
305 })
306
307 minetest.register_craft({
308         output = 'default:axe_stone',
309         recipe = {
310                 {'default:cobble', 'default:cobble'},
311                 {'default:cobble', 'default:stick'},
312                 {'', 'default:stick'},
313         }
314 })
315
316 minetest.register_craft({
317         output = 'default:axe_steel',
318         recipe = {
319                 {'default:steel_ingot', 'default:steel_ingot'},
320                 {'default:steel_ingot', 'default:stick'},
321                 {'', 'default:stick'},
322         }
323 })
324
325 minetest.register_craft({
326         output = 'default:sword_wood',
327         recipe = {
328                 {'default:wood'},
329                 {'default:wood'},
330                 {'default:stick'},
331         }
332 })
333
334 minetest.register_craft({
335         output = 'default:sword_stone',
336         recipe = {
337                 {'default:cobble'},
338                 {'default:cobble'},
339                 {'default:stick'},
340         }
341 })
342
343 minetest.register_craft({
344         output = 'default:sword_steel',
345         recipe = {
346                 {'default:steel_ingot'},
347                 {'default:steel_ingot'},
348                 {'default:stick'},
349         }
350 })
351
352 minetest.register_craft({
353         output = 'default:rail 15',
354         recipe = {
355                 {'default:steel_ingot', '', 'default:steel_ingot'},
356                 {'default:steel_ingot', 'default:stick', 'default:steel_ingot'},
357                 {'default:steel_ingot', '', 'default:steel_ingot'},
358         }
359 })
360
361 minetest.register_craft({
362         output = 'default:chest',
363         recipe = {
364                 {'default:wood', 'default:wood', 'default:wood'},
365                 {'default:wood', '', 'default:wood'},
366                 {'default:wood', 'default:wood', 'default:wood'},
367         }
368 })
369
370 minetest.register_craft({
371         output = 'default:chest_locked',
372         recipe = {
373                 {'default:wood', 'default:wood', 'default:wood'},
374                 {'default:wood', 'default:steel_ingot', 'default:wood'},
375                 {'default:wood', 'default:wood', 'default:wood'},
376         }
377 })
378
379 minetest.register_craft({
380         output = 'default:furnace',
381         recipe = {
382                 {'default:cobble', 'default:cobble', 'default:cobble'},
383                 {'default:cobble', '', 'default:cobble'},
384                 {'default:cobble', 'default:cobble', 'default:cobble'},
385         }
386 })
387
388 minetest.register_craft({
389         output = 'default:steelblock',
390         recipe = {
391                 {'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'},
392                 {'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'},
393                 {'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'},
394         }
395 })
396
397 minetest.register_craft({
398         output = 'default:sandstone',
399         recipe = {
400                 {'default:sand', 'default:sand'},
401                 {'default:sand', 'default:sand'},
402         }
403 })
404
405 minetest.register_craft({
406         output = 'default:clay',
407         recipe = {
408                 {'default:clay_lump', 'default:clay_lump'},
409                 {'default:clay_lump', 'default:clay_lump'},
410         }
411 })
412
413 minetest.register_craft({
414         output = 'default:brick',
415         recipe = {
416                 {'default:clay_brick', 'default:clay_brick'},
417                 {'default:clay_brick', 'default:clay_brick'},
418         }
419 })
420
421 minetest.register_craft({
422         output = 'default:paper',
423         recipe = {
424                 {'default:papyrus', 'default:papyrus', 'default:papyrus'},
425         }
426 })
427
428 minetest.register_craft({
429         output = 'default:book',
430         recipe = {
431                 {'default:paper'},
432                 {'default:paper'},
433                 {'default:paper'},
434         }
435 })
436
437 minetest.register_craft({
438         output = 'default:bookshelf',
439         recipe = {
440                 {'default:wood', 'default:wood', 'default:wood'},
441                 {'default:book', 'default:book', 'default:book'},
442                 {'default:wood', 'default:wood', 'default:wood'},
443         }
444 })
445
446 minetest.register_craft({
447         output = 'default:ladder',
448         recipe = {
449                 {'default:stick', '', 'default:stick'},
450                 {'default:stick', 'default:stick', 'default:stick'},
451                 {'default:stick', '', 'default:stick'},
452         }
453 })
454
455 -- Tool repair
456 minetest.register_craft({
457         type = "toolrepair",
458         additional_wear = -0.02,
459 })
460
461 --
462 -- Cooking recipes
463 --
464
465 minetest.register_craft({
466         type = "cooking",
467         output = "default:glass",
468         recipe = "default:sand",
469 })
470
471 minetest.register_craft({
472         type = "cooking",
473         output = "default:coal_lump",
474         recipe = "default:tree",
475 })
476
477 minetest.register_craft({
478         type = "cooking",
479         output = "default:stone",
480         recipe = "default:cobble",
481 })
482
483 minetest.register_craft({
484         type = "cooking",
485         output = "default:steel_ingot",
486         recipe = "default:iron_lump",
487 })
488
489 minetest.register_craft({
490         type = "cooking",
491         output = "default:clay_brick",
492         recipe = "default:clay_lump",
493 })
494
495 --
496 -- Fuels
497 --
498
499 minetest.register_craft({
500         type = "fuel",
501         recipe = "default:tree",
502         burntime = 30,
503 })
504
505 minetest.register_craft({
506         type = "fuel",
507         recipe = "default:junglegrass",
508         burntime = 2,
509 })
510
511 minetest.register_craft({
512         type = "fuel",
513         recipe = "default:leaves",
514         burntime = 1,
515 })
516
517 minetest.register_craft({
518         type = "fuel",
519         recipe = "default:cactus",
520         burntime = 15,
521 })
522
523 minetest.register_craft({
524         type = "fuel",
525         recipe = "default:papyrus",
526         burntime = 1,
527 })
528
529 minetest.register_craft({
530         type = "fuel",
531         recipe = "default:bookshelf",
532         burntime = 30,
533 })
534
535 minetest.register_craft({
536         type = "fuel",
537         recipe = "default:fence_wood",
538         burntime = 15,
539 })
540
541 minetest.register_craft({
542         type = "fuel",
543         recipe = "default:ladder",
544         burntime = 5,
545 })
546
547 minetest.register_craft({
548         type = "fuel",
549         recipe = "default:wood",
550         burntime = 7,
551 })
552
553 minetest.register_craft({
554         type = "fuel",
555         recipe = "default:mese",
556         burntime = 30,
557 })
558
559 minetest.register_craft({
560         type = "fuel",
561         recipe = "default:lava_source",
562         burntime = 60,
563 })
564
565 minetest.register_craft({
566         type = "fuel",
567         recipe = "default:torch",
568         burntime = 4,
569 })
570
571 minetest.register_craft({
572         type = "fuel",
573         recipe = "default:sign_wall",
574         burntime = 10,
575 })
576
577 minetest.register_craft({
578         type = "fuel",
579         recipe = "default:chest",
580         burntime = 30,
581 })
582
583 minetest.register_craft({
584         type = "fuel",
585         recipe = "default:chest_locked",
586         burntime = 30,
587 })
588
589 minetest.register_craft({
590         type = "fuel",
591         recipe = "default:nyancat",
592         burntime = 1,
593 })
594
595 minetest.register_craft({
596         type = "fuel",
597         recipe = "default:nyancat_rainbow",
598         burntime = 1,
599 })
600
601 minetest.register_craft({
602         type = "fuel",
603         recipe = "default:sapling",
604         burntime = 10,
605 })
606
607 minetest.register_craft({
608         type = "fuel",
609         recipe = "default:apple",
610         burntime = 3,
611 })
612
613 minetest.register_craft({
614         type = "fuel",
615         recipe = "default:coal_lump",
616         burntime = 40,
617 })
618
619 --
620 -- Node definitions
621 --
622
623 -- Default node sounds
624
625 function default.node_sound_defaults(table)
626         table = table or {}
627         table.footstep = table.footstep or
628                         {name="", gain=1.0}
629         table.dug = table.dug or
630                         {name="default_dug_node", gain=1.0}
631         return table
632 end
633
634 function default.node_sound_stone_defaults(table)
635         table = table or {}
636         table.footstep = table.footstep or
637                         {name="default_hard_footstep", gain=0.2}
638         default.node_sound_defaults(table)
639         return table
640 end
641
642 function default.node_sound_dirt_defaults(table)
643         table = table or {}
644         table.footstep = table.footstep or
645                         {name="", gain=0.5}
646         --table.dug = table.dug or
647         --              {name="default_dirt_break", gain=0.5}
648         table.place = table.place or
649                         {name="default_grass_footstep", gain=0.5}
650         default.node_sound_defaults(table)
651         return table
652 end
653
654 function default.node_sound_sand_defaults(table)
655         table = table or {}
656         table.footstep = table.footstep or
657                         {name="default_grass_footstep", gain=0.25}
658         --table.dug = table.dug or
659         --              {name="default_dirt_break", gain=0.25}
660         table.dug = table.dug or
661                         {name="", gain=0.25}
662         default.node_sound_defaults(table)
663         return table
664 end
665
666 function default.node_sound_wood_defaults(table)
667         table = table or {}
668         table.footstep = table.footstep or
669                         {name="default_hard_footstep", gain=0.3}
670         default.node_sound_defaults(table)
671         return table
672 end
673
674 function default.node_sound_leaves_defaults(table)
675         table = table or {}
676         table.footstep = table.footstep or
677                         {name="default_grass_footstep", gain=0.25}
678         table.dig = table.dig or
679                         {name="default_dig_crumbly", gain=0.4}
680         table.dug = table.dug or
681                         {name="", gain=1.0}
682         default.node_sound_defaults(table)
683         return table
684 end
685
686 function default.node_sound_glass_defaults(table)
687         table = table or {}
688         table.footstep = table.footstep or
689                         {name="default_stone_footstep", gain=0.25}
690         table.dug = table.dug or
691                         {name="default_break_glass", gain=1.0}
692         default.node_sound_defaults(table)
693         return table
694 end
695
696 -- Register nodes
697
698 minetest.register_node("default:stone", {
699         description = "Stone",
700         tiles ={"default_stone.png"},
701         groups = {cracky=3},
702         drop = 'default:cobble',
703         legacy_mineral = true,
704         sounds = default.node_sound_stone_defaults(),
705 })
706
707 minetest.register_node("default:stone_with_coal", {
708         description = "Stone with coal",
709         tiles ={"default_stone.png^default_mineral_coal.png"},
710         groups = {cracky=3},
711         drop = 'default:coal_lump',
712         sounds = default.node_sound_stone_defaults(),
713 })
714
715 minetest.register_node("default:stone_with_iron", {
716         description = "Stone with iron",
717         tiles ={"default_stone.png^default_mineral_iron.png"},
718         groups = {cracky=3},
719         drop = 'default:iron_lump',
720         sounds = default.node_sound_stone_defaults(),
721 })
722
723 minetest.register_node("default:dirt_with_grass", {
724         description = "Dirt with grass",
725         tiles ={"default_grass.png", "default_dirt.png",
726                 {name = "default_dirt.png^default_grass_side.png",
727                 tileable_vertical = false}},
728         groups = {crumbly=3, soil=1},
729         drop = 'default:dirt',
730         sounds = default.node_sound_dirt_defaults({
731                 footstep = {name="default_grass_footstep", gain=0.4},
732         }),
733 })
734
735 minetest.register_node("default:dirt_with_grass_footsteps", {
736         description = "Dirt with grass and footsteps",
737         tiles ={"default_grass_footsteps.png", "default_dirt.png",
738                 {name = "default_dirt.png^default_grass_side.png",
739                 tileable_vertical = false}},
740         groups = {crumbly=3, soil=1},
741         drop = 'default:dirt',
742         sounds = default.node_sound_dirt_defaults({
743                 footstep = {name="default_grass_footstep", gain=0.4},
744         }),
745 })
746
747 minetest.register_node("default:dirt", {
748         description = "Dirt",
749         tiles ={"default_dirt.png"},
750         groups = {crumbly=3, soil=1},
751         sounds = default.node_sound_dirt_defaults(),
752 })
753
754 minetest.register_node("default:sand", {
755         description = "Sand",
756         tiles ={"default_sand.png"},
757         groups = {crumbly=3, falling_node=1},
758         sounds = default.node_sound_sand_defaults(),
759 })
760
761 minetest.register_node("default:gravel", {
762         description = "Gravel",
763         tiles ={"default_gravel.png"},
764         groups = {crumbly=2, falling_node=1},
765         sounds = default.node_sound_dirt_defaults({
766                 footstep = {name="default_gravel_footstep", gain=0.45},
767         }),
768 })
769
770 minetest.register_node("default:sandstone", {
771         description = "Sandstone",
772         tiles ={"default_sandstone.png"},
773         groups = {crumbly=2,cracky=2},
774         drop = 'default:sand',
775         sounds = default.node_sound_stone_defaults(),
776 })
777
778 minetest.register_node("default:clay", {
779         description = "Clay",
780         tiles ={"default_clay.png"},
781         groups = {crumbly=3},
782         drop = 'default:clay_lump 4',
783         sounds = default.node_sound_dirt_defaults({
784                 footstep = "",
785         }),
786 })
787
788 minetest.register_node("default:brick", {
789         description = "Brick",
790         tiles ={"default_brick.png"},
791         is_ground_content = false,
792         groups = {cracky=3},
793         drop = 'default:clay_brick 4',
794         sounds = default.node_sound_stone_defaults(),
795 })
796
797 minetest.register_node("default:tree", {
798         description = "Tree",
799         tiles ={"default_tree_top.png", "default_tree_top.png", "default_tree.png"},
800         is_ground_content = false,
801         groups = {snappy=2,choppy=2,oddly_breakable_by_hand=1},
802         sounds = default.node_sound_wood_defaults(),
803 })
804
805 minetest.register_node("default:junglegrass", {
806         description = "Jungle Grass",
807         drawtype = "plantlike",
808         visual_scale = 1.3,
809         tiles ={"default_junglegrass.png"},
810         inventory_image = "default_junglegrass.png",
811         wield_image = "default_junglegrass.png",
812         paramtype = "light",
813         walkable = false,
814         groups = {snappy=3,attached_node=1},
815         sounds = default.node_sound_leaves_defaults(),
816 })
817
818 minetest.register_node("default:leaves", {
819         description = "Leaves",
820         drawtype = "allfaces_optional",
821         visual_scale = 1.3,
822         tiles ={"default_leaves.png"},
823         paramtype = "light",
824         is_ground_content = false,
825         groups = {snappy=3},
826         drop = {
827                 max_items = 1,
828                 items = {
829                         {
830                                 -- player will get sapling with 1/20 chance
831                                 items = {'default:sapling'},
832                                 rarity = 20,
833                         },
834                         {
835                                 -- player will get leaves only if he get no saplings,
836                                 -- this is because max_items is 1
837                                 items = {'default:leaves'},
838                         }
839                 }
840         },
841         sounds = default.node_sound_leaves_defaults(),
842 })
843
844 minetest.register_node("default:cactus", {
845         description = "Cactus",
846         tiles ={"default_cactus_top.png", "default_cactus_top.png", "default_cactus_side.png"},
847         groups = {snappy=2,choppy=3},
848         sounds = default.node_sound_wood_defaults(),
849 })
850
851 minetest.register_node("default:papyrus", {
852         description = "Papyrus",
853         drawtype = "plantlike",
854         tiles ={"default_papyrus.png"},
855         inventory_image = "default_papyrus.png",
856         wield_image = "default_papyrus.png",
857         paramtype = "light",
858         walkable = false,
859         groups = {snappy=3},
860         sounds = default.node_sound_leaves_defaults(),
861 })
862
863 minetest.register_node("default:bookshelf", {
864         description = "Bookshelf",
865         tiles ={"default_wood.png", "default_wood.png", "default_bookshelf.png"},
866         is_ground_content = false,
867         groups = {snappy=2,choppy=3,oddly_breakable_by_hand=2},
868         sounds = default.node_sound_wood_defaults(),
869 })
870
871 minetest.register_node("default:glass", {
872         description = "Glass",
873         drawtype = "glasslike",
874         tiles ={"default_glass.png"},
875         paramtype = "light",
876         is_ground_content = false,
877         sunlight_propagates = true,
878         groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3},
879         sounds = default.node_sound_glass_defaults(),
880 })
881
882 minetest.register_node("default:fence_wood", {
883         description = "Wooden Fence",
884         drawtype = "fencelike",
885         tiles ={"default_wood.png"},
886         inventory_image = "default_fence.png",
887         wield_image = "default_fence.png",
888         paramtype = "light",
889         is_ground_content = false,
890         selection_box = {
891                 type = "fixed",
892                 fixed = {-1/7, -1/2, -1/7, 1/7, 1/2, 1/7},
893         },
894         groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2},
895         sounds = default.node_sound_wood_defaults(),
896 })
897
898 minetest.register_node("default:rail", {
899         description = "Rail",
900         drawtype = "raillike",
901         tiles ={"default_rail.png", "default_rail_curved.png", "default_rail_t_junction.png", "default_rail_crossing.png"},
902         inventory_image = "default_rail.png",
903         wield_image = "default_rail.png",
904         paramtype = "light",
905         is_ground_content = false,
906         walkable = false,
907         selection_box = {
908                 type = "fixed",
909                 fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
910         },
911         groups = {bendy=2,snappy=1,dig_immediate=2},
912 })
913
914 minetest.register_node("default:ladder", {
915         description = "Ladder",
916         drawtype = "signlike",
917         tiles ={"default_ladder.png"},
918         inventory_image = "default_ladder.png",
919         wield_image = "default_ladder.png",
920         paramtype = "light",
921         paramtype2 = "wallmounted",
922         is_ground_content = false,
923         walkable = false,
924         climbable = true,
925         selection_box = {
926                 type = "wallmounted",
927                 --wall_top = = <default>
928                 --wall_bottom = = <default>
929                 --wall_side = = <default>
930         },
931         groups = {snappy=2,choppy=2,oddly_breakable_by_hand=3},
932         legacy_wallmounted = true,
933         sounds = default.node_sound_wood_defaults(),
934 })
935
936 minetest.register_node("default:wood", {
937         description = "Wood",
938         tiles ={"default_wood.png"},
939         is_ground_content = false,
940         groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2},
941         sounds = default.node_sound_wood_defaults(),
942 })
943
944 minetest.register_node("default:mese", {
945         description = "Mese",
946         tiles ={"default_mese.png"},
947         groups = {cracky=1,level=2},
948         sounds = default.node_sound_defaults(),
949 })
950
951 minetest.register_node("default:cloud", {
952         description = "Cloud",
953         tiles ={"default_cloud.png"},
954         is_ground_content = false,
955         sounds = default.node_sound_defaults(),
956 })
957
958 minetest.register_node("default:water_flowing", {
959         description = "Water (flowing)",
960         inventory_image = minetest.inventorycube("default_water.png"),
961         drawtype = "flowingliquid",
962         tiles ={"default_water.png"},
963         special_tiles = {
964                 {name="default_water.png", backface_culling=false},
965                 {name="default_water.png", backface_culling=true},
966         },
967         alpha = WATER_ALPHA,
968         paramtype = "light",
969         walkable = false,
970         pointable = false,
971         diggable = false,
972         buildable_to = true,
973         is_ground_content = false,
974         drowning = 1,
975         liquidtype = "flowing",
976         liquid_alternative_flowing = "default:water_flowing",
977         liquid_alternative_source = "default:water_source",
978         liquid_viscosity = WATER_VISC,
979         post_effect_color = {a=64, r=100, g=100, b=200},
980         groups = {water=3, liquid=3},
981 })
982
983 minetest.register_node("default:water_source", {
984         description = "Water",
985         inventory_image = minetest.inventorycube("default_water.png"),
986         drawtype = "liquid",
987         tiles ={"default_water.png"},
988         special_tiles = {
989                 -- New-style water source material (mostly unused)
990                 {name="default_water.png", backface_culling=false},
991         },
992         alpha = WATER_ALPHA,
993         paramtype = "light",
994         walkable = false,
995         pointable = false,
996         diggable = false,
997         buildable_to = true,
998         is_ground_content = false,
999         drowning = 1,
1000         liquidtype = "source",
1001         liquid_alternative_flowing = "default:water_flowing",
1002         liquid_alternative_source = "default:water_source",
1003         liquid_viscosity = WATER_VISC,
1004         post_effect_color = {a=64, r=100, g=100, b=200},
1005         groups = {water=3, liquid=3},
1006 })
1007
1008 minetest.register_node("default:lava_flowing", {
1009         description = "Lava (flowing)",
1010         inventory_image = minetest.inventorycube("default_lava.png"),
1011         drawtype = "flowingliquid",
1012         tiles ={"default_lava.png"},
1013         special_tiles = {
1014                 {
1015                         image="default_lava_flowing_animated.png",
1016                         backface_culling=false,
1017                         animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.3}
1018                 },
1019                 {
1020                         image="default_lava_flowing_animated.png",
1021                         backface_culling=true,
1022                         animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.3}
1023                 },
1024         },
1025         paramtype = "light",
1026         light_source = LIGHT_MAX - 1,
1027         walkable = false,
1028         pointable = false,
1029         diggable = false,
1030         buildable_to = true,
1031         is_ground_content = false,
1032         drowning = 1,
1033         liquidtype = "flowing",
1034         liquid_alternative_flowing = "default:lava_flowing",
1035         liquid_alternative_source = "default:lava_source",
1036         liquid_viscosity = LAVA_VISC,
1037         damage_per_second = 4*2,
1038         post_effect_color = {a=192, r=255, g=64, b=0},
1039         groups = {lava=3, liquid=2, hot=3},
1040 })
1041
1042 minetest.register_node("default:lava_source", {
1043         description = "Lava",
1044         inventory_image = minetest.inventorycube("default_lava.png"),
1045         drawtype = "liquid",
1046         --tiles ={"default_lava.png"},
1047         tiles ={
1048                 {name="default_lava_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}}
1049         },
1050         special_tiles = {
1051                 -- New-style lava source material (mostly unused)
1052                 {name="default_lava.png", backface_culling=false},
1053         },
1054         paramtype = "light",
1055         light_source = LIGHT_MAX - 1,
1056         walkable = false,
1057         pointable = false,
1058         diggable = false,
1059         buildable_to = true,
1060         is_ground_content = false,
1061         drowning = 1,
1062         liquidtype = "source",
1063         liquid_alternative_flowing = "default:lava_flowing",
1064         liquid_alternative_source = "default:lava_source",
1065         liquid_viscosity = LAVA_VISC,
1066         damage_per_second = 4*2,
1067         post_effect_color = {a=192, r=255, g=64, b=0},
1068         groups = {lava=3, liquid=2, hot=3},
1069 })
1070
1071 minetest.register_node("default:torch", {
1072         description = "Torch",
1073         drawtype = "torchlike",
1074         tiles ={"default_torch_on_floor.png", "default_torch_on_ceiling.png", "default_torch.png"},
1075         inventory_image = "default_torch_on_floor.png",
1076         wield_image = "default_torch_on_floor.png",
1077         paramtype = "light",
1078         paramtype2 = "wallmounted",
1079         sunlight_propagates = true,
1080         is_ground_content = false,
1081         walkable = false,
1082         light_source = LIGHT_MAX-1,
1083         selection_box = {
1084                 type = "wallmounted",
1085                 wall_top = {-0.1, 0.5-0.6, -0.1, 0.1, 0.5, 0.1},
1086                 wall_bottom = {-0.1, -0.5, -0.1, 0.1, -0.5+0.6, 0.1},
1087                 wall_side = {-0.5, -0.3, -0.1, -0.5+0.3, 0.3, 0.1},
1088         },
1089         groups = {choppy=2,dig_immediate=3,attached_node=1},
1090         legacy_wallmounted = true,
1091         sounds = default.node_sound_defaults(),
1092 })
1093
1094 minetest.register_node("default:sign_wall", {
1095         description = "Sign",
1096         drawtype = "signlike",
1097         tiles ={"default_sign_wall.png"},
1098         inventory_image = "default_sign_wall.png",
1099         wield_image = "default_sign_wall.png",
1100         paramtype = "light",
1101         paramtype2 = "wallmounted",
1102         sunlight_propagates = true,
1103         is_ground_content = false,
1104         walkable = false,
1105         selection_box = {
1106                 type = "wallmounted",
1107                 --wall_top = <default>
1108                 --wall_bottom = <default>
1109                 --wall_side = <default>
1110         },
1111         groups = {choppy=2,dig_immediate=2,attached_node=1},
1112         legacy_wallmounted = true,
1113         sounds = default.node_sound_defaults(),
1114         on_construct = function(pos)
1115                 --local n = minetest.get_node(pos)
1116                 local meta = minetest.get_meta(pos)
1117                 meta:set_string("formspec", "field[text;;${text}]")
1118                 meta:set_string("infotext", "\"\"")
1119         end,
1120         on_receive_fields = function(pos, formname, fields, sender)
1121                 --print("Sign at "..minetest.pos_to_string(pos).." got "..dump(fields))
1122                 local meta = minetest.get_meta(pos)
1123                 fields.text = fields.text or ""
1124                 print((sender:get_player_name() or "").." wrote \""..fields.text..
1125                                 "\" to sign at "..minetest.pos_to_string(pos))
1126                 meta:set_string("text", fields.text)
1127                 meta:set_string("infotext", '"'..fields.text..'"')
1128         end,
1129 })
1130
1131 minetest.register_node("default:chest", {
1132         description = "Chest",
1133         tiles ={"default_chest_top.png", "default_chest_top.png", "default_chest_side.png",
1134                 "default_chest_side.png", "default_chest_side.png", "default_chest_front.png"},
1135         paramtype2 = "facedir",
1136         groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2},
1137         legacy_facedir_simple = true,
1138         is_ground_content = false,
1139         sounds = default.node_sound_wood_defaults(),
1140         on_construct = function(pos)
1141                 local meta = minetest.get_meta(pos)
1142                 meta:set_string("formspec",
1143                                 "size[8,9]"..
1144                                 "list[current_name;main;0,0;8,4;]"..
1145                                 "list[current_player;main;0,5;8,4;]" ..
1146                                 "listring[]")
1147                 meta:set_string("infotext", "Chest")
1148                 local inv = meta:get_inventory()
1149                 inv:set_size("main", 8*4)
1150         end,
1151         can_dig = function(pos,player)
1152                 local meta = minetest.get_meta(pos);
1153                 local inv = meta:get_inventory()
1154                 return inv:is_empty("main")
1155         end,
1156 })
1157
1158 local function has_locked_chest_privilege(meta, player)
1159         if player:get_player_name() ~= meta:get_string("owner") then
1160                 return false
1161         end
1162         return true
1163 end
1164
1165 minetest.register_node("default:chest_locked", {
1166         description = "Locked Chest",
1167         tiles ={"default_chest_top.png", "default_chest_top.png", "default_chest_side.png",
1168                 "default_chest_side.png", "default_chest_side.png", "default_chest_lock.png"},
1169         paramtype2 = "facedir",
1170         groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2},
1171         legacy_facedir_simple = true,
1172         is_ground_content = false,
1173         sounds = default.node_sound_wood_defaults(),
1174         after_place_node = function(pos, placer)
1175                 local meta = minetest.get_meta(pos)
1176                 meta:set_string("owner", placer:get_player_name() or "")
1177                 meta:set_string("infotext", "Locked Chest (owned by "..
1178                                 meta:get_string("owner")..")")
1179         end,
1180         on_construct = function(pos)
1181                 local meta = minetest.get_meta(pos)
1182                 meta:set_string("formspec",
1183                                 "size[8,9]"..
1184                                 "list[current_name;main;0,0;8,4;]"..
1185                                 "list[current_player;main;0,5;8,4;]" ..
1186                                 "listring[]")
1187                 meta:set_string("infotext", "Locked Chest")
1188                 meta:set_string("owner", "")
1189                 local inv = meta:get_inventory()
1190                 inv:set_size("main", 8*4)
1191         end,
1192         can_dig = function(pos,player)
1193                 local meta = minetest.get_meta(pos);
1194                 local inv = meta:get_inventory()
1195                 return inv:is_empty("main")
1196         end,
1197         allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
1198                 local meta = minetest.get_meta(pos)
1199                 if not has_locked_chest_privilege(meta, player) then
1200                         minetest.log("action", player:get_player_name()..
1201                                         " tried to access a locked chest belonging to "..
1202                                         meta:get_string("owner").." at "..
1203                                         minetest.pos_to_string(pos))
1204                         return 0
1205                 end
1206                 return count
1207         end,
1208     allow_metadata_inventory_put = function(pos, listname, index, stack, player)
1209                 local meta = minetest.get_meta(pos)
1210                 if not has_locked_chest_privilege(meta, player) then
1211                         minetest.log("action", player:get_player_name()..
1212                                         " tried to access a locked chest belonging to "..
1213                                         meta:get_string("owner").." at "..
1214                                         minetest.pos_to_string(pos))
1215                         return 0
1216                 end
1217                 return stack:get_count()
1218         end,
1219     allow_metadata_inventory_take = function(pos, listname, index, stack, player)
1220                 local meta = minetest.get_meta(pos)
1221                 if not has_locked_chest_privilege(meta, player) then
1222                         minetest.log("action", player:get_player_name()..
1223                                         " tried to access a locked chest belonging to "..
1224                                         meta:get_string("owner").." at "..
1225                                         minetest.pos_to_string(pos))
1226                         return 0
1227                 end
1228                 return stack:get_count()
1229         end,
1230         on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
1231                 minetest.log("action", player:get_player_name()..
1232                                 " moves stuff in locked chest at "..minetest.pos_to_string(pos))
1233         end,
1234     on_metadata_inventory_put = function(pos, listname, index, stack, player)
1235                 minetest.log("action", player:get_player_name()..
1236                                 " moves stuff to locked chest at "..minetest.pos_to_string(pos))
1237         end,
1238     on_metadata_inventory_take = function(pos, listname, index, stack, player)
1239                 minetest.log("action", player:get_player_name()..
1240                                 " takes stuff from locked chest at "..minetest.pos_to_string(pos))
1241         end,
1242 })
1243
1244 default.furnace_inactive_formspec =
1245         "size[8,9]"..
1246         "image[2,2;1,1;default_furnace_fire_bg.png]"..
1247         "list[current_name;fuel;2,3;1,1;]"..
1248         "list[current_name;src;2,1;1,1;]"..
1249         "list[current_name;dst;5,1;2,2;]"..
1250         "list[current_player;main;0,5;8,4;]" ..
1251         "listring[current_name;dst]" ..
1252         "listring[current_player;main]" ..
1253         "listring[current_name;src]" ..
1254         "listring[current_player;main]"
1255
1256 minetest.register_node("default:furnace", {
1257         description = "Furnace",
1258         tiles ={"default_furnace_side.png", "default_furnace_side.png", "default_furnace_side.png",
1259                 "default_furnace_side.png", "default_furnace_side.png", "default_furnace_front.png"},
1260         paramtype2 = "facedir",
1261         groups = {cracky=2},
1262         legacy_facedir_simple = true,
1263         is_ground_content = false,
1264         sounds = default.node_sound_stone_defaults(),
1265         on_construct = function(pos)
1266                 local meta = minetest.get_meta(pos)
1267                 meta:set_string("formspec", default.furnace_inactive_formspec)
1268                 meta:set_string("infotext", "Furnace")
1269                 local inv = meta:get_inventory()
1270                 inv:set_size("fuel", 1)
1271                 inv:set_size("src", 1)
1272                 inv:set_size("dst", 4)
1273         end,
1274         can_dig = function(pos,player)
1275                 local meta = minetest.get_meta(pos);
1276                 local inv = meta:get_inventory()
1277                 if not inv:is_empty("fuel") then
1278                         return false
1279                 elseif not inv:is_empty("dst") then
1280                         return false
1281                 elseif not inv:is_empty("src") then
1282                         return false
1283                 end
1284                 return true
1285         end,
1286 })
1287
1288 minetest.register_node("default:furnace_active", {
1289         description = "Furnace",
1290         tiles ={"default_furnace_side.png", "default_furnace_side.png", "default_furnace_side.png",
1291                 "default_furnace_side.png", "default_furnace_side.png", "default_furnace_front_active.png"},
1292         paramtype2 = "facedir",
1293         light_source = 8,
1294         drop = "default:furnace",
1295         groups = {cracky=2},
1296         legacy_facedir_simple = true,
1297         is_ground_content = false,
1298         sounds = default.node_sound_stone_defaults(),
1299         on_construct = function(pos)
1300                 local meta = minetest.get_meta(pos)
1301                 meta:set_string("formspec", default.furnace_inactive_formspec)
1302                 meta:set_string("infotext", "Furnace");
1303                 local inv = meta:get_inventory()
1304                 inv:set_size("fuel", 1)
1305                 inv:set_size("src", 1)
1306                 inv:set_size("dst", 4)
1307         end,
1308         can_dig = function(pos,player)
1309                 local meta = minetest.get_meta(pos);
1310                 local inv = meta:get_inventory()
1311                 if not inv:is_empty("fuel") then
1312                         return false
1313                 elseif not inv:is_empty("dst") then
1314                         return false
1315                 elseif not inv:is_empty("src") then
1316                         return false
1317                 end
1318                 return true
1319         end,
1320 })
1321
1322 function swap_node(pos,name)
1323         local node = minetest.get_node(pos)
1324         if node.name == name then
1325                 return
1326         end
1327         node.name = name
1328         minetest.swap_node(pos, node)
1329 end
1330
1331 minetest.register_abm({
1332         nodenames = {"default:furnace","default:furnace_active"},
1333         interval = 1.0,
1334         chance = 1,
1335         action = function(pos, node, active_object_count, active_object_count_wider)
1336                 local meta = minetest.get_meta(pos)
1337                 for i, name in ipairs({
1338                                 "fuel_totaltime",
1339                                 "fuel_time",
1340                                 "src_totaltime",
1341                                 "src_time"
1342                 }) do
1343                         if meta:get_string(name) == "" then
1344                                 meta:set_float(name, 0.0)
1345                         end
1346                 end
1347
1348                 local inv = meta:get_inventory()
1349
1350                 local srclist = inv:get_list("src")
1351                 local cooked = nil
1352                 
1353                 if srclist then
1354                         cooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
1355                 end
1356                 
1357                 local was_active = false
1358                 
1359                 if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
1360                         was_active = true
1361                         meta:set_float("fuel_time", meta:get_float("fuel_time") + 1)
1362                         meta:set_float("src_time", meta:get_float("src_time") + 1)
1363                         if cooked and cooked.item and meta:get_float("src_time") >= cooked.time then
1364                                 -- check if there's room for output in "dst" list
1365                                 if inv:room_for_item("dst",cooked.item) then
1366                                         -- Put result in "dst" list
1367                                         inv:add_item("dst", cooked.item)
1368                                         -- take stuff from "src" list
1369                                         srcstack = inv:get_stack("src", 1)
1370                                         srcstack:take_item()
1371                                         inv:set_stack("src", 1, srcstack)
1372                                 else
1373                                         print("Could not insert '"..cooked.item:to_string().."'")
1374                                 end
1375                                 meta:set_string("src_time", 0)
1376                         end
1377                 end
1378                 
1379                 if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
1380                         local percent = math.floor(meta:get_float("fuel_time") /
1381                                         meta:get_float("fuel_totaltime") * 100)
1382                         meta:set_string("infotext","Furnace active: "..percent.."%")
1383                         swap_node(pos,"default:furnace_active")
1384                         meta:set_string("formspec",
1385                                 "size[8,9]"..
1386                                 "image[2,2;1,1;default_furnace_fire_bg.png^[lowpart:"..
1387                                                 (100-percent)..":default_furnace_fire_fg.png]"..
1388                                 "list[current_name;fuel;2,3;1,1;]"..
1389                                 "list[current_name;src;2,1;1,1;]"..
1390                                 "list[current_name;dst;5,1;2,2;]"..
1391                                 "list[current_player;main;0,5;8,4;]" ..
1392                                 "listring[current_name;dst]" ..
1393                                 "listring[current_player;main]" ..
1394                                 "listring[current_name;src]" ..
1395                                 "listring[current_player;main]")
1396                         return
1397                 end
1398
1399                 local fuel = nil
1400                 local cooked = nil
1401                 local fuellist = inv:get_list("fuel")
1402                 local srclist = inv:get_list("src")
1403                 
1404                 if srclist then
1405                         cooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
1406                 end
1407                 if fuellist then
1408                         fuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist})
1409                 end
1410
1411                 if fuel.time <= 0 then
1412                         meta:set_string("infotext","Furnace out of fuel")
1413                         swap_node(pos,"default:furnace")
1414                         meta:set_string("formspec", default.furnace_inactive_formspec)
1415                         return
1416                 end
1417
1418                 if cooked.item:is_empty() then
1419                         if was_active then
1420                                 meta:set_string("infotext","Furnace is empty")
1421                                 swap_node(pos,"default:furnace")
1422                                 meta:set_string("formspec", default.furnace_inactive_formspec)
1423                         end
1424                         return
1425                 end
1426
1427                 meta:set_string("fuel_totaltime", fuel.time)
1428                 meta:set_string("fuel_time", 0)
1429                 
1430                 local stack = inv:get_stack("fuel", 1)
1431                 stack:take_item()
1432                 inv:set_stack("fuel", 1, stack)
1433         end,
1434 })
1435
1436 minetest.register_node("default:cobble", {
1437         description = "Cobble",
1438         tiles ={"default_cobble.png"},
1439         is_ground_content = false,
1440         groups = {cracky=3},
1441         sounds = default.node_sound_stone_defaults(),
1442 })
1443
1444 minetest.register_node("default:mossycobble", {
1445         description = "Mossy Cobble",
1446         tiles ={"default_mossycobble.png"},
1447         is_ground_content = false,
1448         groups = {cracky=3},
1449         sounds = default.node_sound_stone_defaults(),
1450 })
1451
1452 minetest.register_node("default:steelblock", {
1453         description = "Steel Block",
1454         tiles ={"default_steel_block.png"},
1455         is_ground_content = false,
1456         groups = {snappy=1,bendy=2},
1457         sounds = default.node_sound_stone_defaults(),
1458 })
1459
1460 minetest.register_node("default:nyancat", {
1461         description = "Nyancat",
1462         tiles ={"default_nc_side.png", "default_nc_side.png", "default_nc_side.png",
1463                 "default_nc_side.png", "default_nc_back.png", "default_nc_front.png"},
1464         inventory_image = "default_nc_front.png",
1465         paramtype2 = "facedir",
1466         groups = {cracky=2},
1467         legacy_facedir_simple = true,
1468         is_ground_content = false,
1469         sounds = default.node_sound_defaults(),
1470 })
1471
1472 minetest.register_node("default:nyancat_rainbow", {
1473         description = "Nyancat Rainbow",
1474         tiles ={"default_nc_rb.png"},
1475         inventory_image = "default_nc_rb.png",
1476         is_ground_content = false,
1477         groups = {cracky=2},
1478         sounds = default.node_sound_defaults(),
1479 })
1480
1481 minetest.register_node("default:sapling", {
1482         description = "Sapling",
1483         drawtype = "plantlike",
1484         visual_scale = 1.0,
1485         tiles ={"default_sapling.png"},
1486         inventory_image = "default_sapling.png",
1487         wield_image = "default_sapling.png",
1488         paramtype = "light",
1489         walkable = false,
1490         groups = {snappy=2,dig_immediate=3,attached_node=1},
1491         sounds = default.node_sound_defaults(),
1492 })
1493
1494 minetest.register_node("default:apple", {
1495         description = "Apple",
1496         drawtype = "plantlike",
1497         visual_scale = 1.0,
1498         tiles ={"default_apple.png"},
1499         inventory_image = "default_apple.png",
1500         paramtype = "light",
1501         is_ground_content = false,
1502         sunlight_propagates = true,
1503         walkable = false,
1504         groups = {fleshy=3,dig_immediate=3},
1505         on_use = minetest.item_eat(4),
1506         sounds = default.node_sound_defaults(),
1507 })
1508
1509 --
1510 -- Grow tree function
1511 --
1512
1513 local c_air = minetest.get_content_id("air")
1514 local c_ignore = minetest.get_content_id("ignore")
1515 local c_tree = minetest.get_content_id("default:tree")
1516 local c_leaves = minetest.get_content_id("default:leaves")
1517 local c_apple = minetest.get_content_id("default:apple")
1518 function default.grow_tree(data, a, pos, is_apple_tree, seed)
1519         --[[
1520                 NOTE: Tree-placing code is currently duplicated in the engine
1521                 and in games that have saplings; both are deprecated but not
1522                 replaced yet
1523         ]]--
1524         local pr = PseudoRandom(seed)
1525         local th = pr:next(4, 5)
1526         local x, y, z = pos.x, pos.y, pos.z
1527         for yy = y, y+th-1 do
1528                 local vi = a:index(x, yy, z)
1529                 if a:contains(x, yy, z) and (data[vi] == c_air or yy == y) then
1530                         data[vi] = c_tree
1531                 end
1532         end
1533         y = y+th-1 -- (x, y, z) is now last piece of trunk
1534         local leaves_a = VoxelArea:new{MinEdge={x=-2, y=-1, z=-2}, MaxEdge={x=2, y=2, z=2}}
1535         local leaves_buffer = {}
1536         
1537         -- Force leaves near the trunk
1538         local d = 1
1539         for xi = -d, d do
1540         for yi = -d, d do
1541         for zi = -d, d do
1542                 leaves_buffer[leaves_a:index(xi, yi, zi)] = true
1543         end
1544         end
1545         end
1546         
1547         -- Add leaves randomly
1548         for iii = 1, 8 do
1549                 local d = 1
1550                 local xx = pr:next(leaves_a.MinEdge.x, leaves_a.MaxEdge.x - d)
1551                 local yy = pr:next(leaves_a.MinEdge.y, leaves_a.MaxEdge.y - d)
1552                 local zz = pr:next(leaves_a.MinEdge.z, leaves_a.MaxEdge.z - d)
1553                 
1554                 for xi = 0, d do
1555                 for yi = 0, d do
1556                 for zi = 0, d do
1557                         leaves_buffer[leaves_a:index(xx+xi, yy+yi, zz+zi)] = true
1558                 end
1559                 end
1560                 end
1561         end
1562         
1563         -- Add the leaves
1564         for xi = leaves_a.MinEdge.x, leaves_a.MaxEdge.x do
1565         for yi = leaves_a.MinEdge.y, leaves_a.MaxEdge.y do
1566         for zi = leaves_a.MinEdge.z, leaves_a.MaxEdge.z do
1567                 if a:contains(x+xi, y+yi, z+zi) then
1568                         local vi = a:index(x+xi, y+yi, z+zi)
1569                         if data[vi] == c_air or data[vi] == c_ignore then
1570                                 if leaves_buffer[leaves_a:index(xi, yi, zi)] then
1571                                         if is_apple_tree and pr:next(1, 100) <=  10 then
1572                                                 data[vi] = c_apple
1573                                         else
1574                                                 data[vi] = c_leaves
1575                                         end
1576                                 end
1577                         end
1578                 end
1579         end
1580         end
1581         end
1582 end
1583
1584 --
1585 -- ABMs
1586 --
1587
1588 minetest.register_abm({
1589         nodenames = {"default:sapling"},
1590         interval = 10,
1591         chance = 50,
1592         action = function(pos, node)
1593                 if minetest.get_item_group(minetest.get_node(
1594                         {x = pos.x, y = pos.y - 1, z = pos.z}).name, "soil") == 0 then
1595                         return
1596                 end
1597                 print("A sapling grows into a tree at "..minetest.pos_to_string(pos))
1598                 local vm = minetest.get_voxel_manip()
1599                 local minp, maxp = vm:read_from_map({x=pos.x-16, y=pos.y, z=pos.z-16}, {x=pos.x+16, y=pos.y+16, z=pos.z+16})
1600                 local a = VoxelArea:new{MinEdge=minp, MaxEdge=maxp}
1601                 local data = vm:get_data()
1602                 default.grow_tree(data, a, pos, math.random(1, 4) == 1, math.random(1,100000))
1603                 vm:set_data(data)
1604                 vm:write_to_map(data)
1605                 vm:update_map()
1606         end
1607 })
1608
1609 minetest.register_abm({
1610         nodenames = {"default:dirt"},
1611         interval = 2,
1612         chance = 200,
1613         action = function(pos, node)
1614                 local above = {x=pos.x, y=pos.y+1, z=pos.z}
1615                 local name = minetest.get_node(above).name
1616                 local nodedef = minetest.registered_nodes[name]
1617                 if nodedef and (nodedef.sunlight_propagates or nodedef.paramtype == "light")
1618                                 and nodedef.liquidtype == "none"
1619                                 and (minetest.get_node_light(above) or 0) >= 13 then
1620                         if name == "default:snow" or name == "default:snowblock" then
1621                                 minetest.set_node(pos, {name = "default:dirt_with_snow"})
1622                         else
1623                                 minetest.set_node(pos, {name = "default:dirt_with_grass"})
1624                         end
1625                 end
1626         end
1627 })
1628
1629 minetest.register_abm({
1630         nodenames = {"default:dirt_with_grass"},
1631         interval = 2,
1632         chance = 20,
1633         action = function(pos, node)
1634                 local above = {x=pos.x, y=pos.y+1, z=pos.z}
1635                 local name = minetest.get_node(above).name
1636                 local nodedef = minetest.registered_nodes[name]
1637                 if name ~= "ignore" and nodedef
1638                                 and not ((nodedef.sunlight_propagates or nodedef.paramtype == "light")
1639                                 and nodedef.liquidtype == "none") then
1640                         minetest.set_node(pos, {name = "default:dirt"})
1641                 end
1642         end
1643 })
1644
1645 --
1646 -- Crafting items
1647 --
1648
1649 minetest.register_craftitem("default:stick", {
1650         description = "Stick",
1651         inventory_image = "default_stick.png",
1652 })
1653
1654 minetest.register_craftitem("default:paper", {
1655         description = "Paper",
1656         inventory_image = "default_paper.png",
1657 })
1658
1659 minetest.register_craftitem("default:book", {
1660         description = "Book",
1661         inventory_image = "default_book.png",
1662 })
1663
1664 minetest.register_craftitem("default:coal_lump", {
1665         description = "Lump of coal",
1666         inventory_image = "default_coal_lump.png",
1667 })
1668
1669 minetest.register_craftitem("default:iron_lump", {
1670         description = "Lump of iron",
1671         inventory_image = "default_iron_lump.png",
1672 })
1673
1674 minetest.register_craftitem("default:clay_lump", {
1675         description = "Lump of clay",
1676         inventory_image = "default_clay_lump.png",
1677 })
1678
1679 minetest.register_craftitem("default:steel_ingot", {
1680         description = "Steel ingot",
1681         inventory_image = "default_steel_ingot.png",
1682 })
1683
1684 minetest.register_craftitem("default:clay_brick", {
1685         description = "Clay brick",
1686         inventory_image = "default_steel_ingot.png",
1687         inventory_image = "default_clay_brick.png",
1688 })
1689
1690 minetest.register_craftitem("default:scorched_stuff", {
1691         description = "Scorched stuff",
1692         inventory_image = "default_scorched_stuff.png",
1693 })
1694
1695 --
1696 -- Support old code
1697 --
1698
1699 function default.spawn_falling_node(p, nodename)
1700         spawn_falling_node(p, nodename)
1701 end
1702
1703 -- Horrible crap to support old code
1704 -- Don't use this and never do what this does, it's completely wrong!
1705 -- (More specifically, the client and the C++ code doesn't get the group)
1706 function default.register_falling_node(nodename, texture)
1707         minetest.log("error", debug.traceback())
1708         minetest.log('error', "WARNING: default.register_falling_node is deprecated")
1709         if minetest.registered_nodes[nodename] then
1710                 minetest.registered_nodes[nodename].groups.falling_node = 1
1711         end
1712 end
1713
1714 --
1715 -- Global callbacks
1716 --
1717
1718 -- Global environment step function
1719 function on_step(dtime)
1720         -- print("on_step")
1721 end
1722 minetest.register_globalstep(on_step)
1723
1724 function on_placenode(p, node)
1725         --print("on_placenode")
1726 end
1727 minetest.register_on_placenode(on_placenode)
1728
1729 function on_dignode(p, node)
1730         --print("on_dignode")
1731 end
1732 minetest.register_on_dignode(on_dignode)
1733
1734 function on_punchnode(p, node)
1735 end
1736 minetest.register_on_punchnode(on_punchnode)
1737
1738 --
1739 -- Test some things
1740 --
1741
1742 local function test_get_craft_result()
1743         minetest.log("info", "test_get_craft_result()")
1744         -- normal
1745         local input = {
1746                 method = "normal",
1747                 width = 2,
1748                 items = {"", "default:coal_lump", "", "default:stick"}
1749         }
1750         minetest.log("info", "torch crafting input: "..dump(input))
1751         local output, decremented_input = minetest.get_craft_result(input)
1752         minetest.log("info", "torch crafting output: "..dump(output))
1753         minetest.log("info", "torch crafting decremented input: "..dump(decremented_input))
1754         assert(output.item)
1755         minetest.log("info", "torch crafting output.item:to_table(): "..dump(output.item:to_table()))
1756         assert(output.item:get_name() == "default:torch")
1757         assert(output.item:get_count() == 4)
1758         -- fuel
1759         local input = {
1760                 method = "fuel",
1761                 width = 1,
1762                 items = {"default:coal_lump"}
1763         }
1764         minetest.log("info", "coal fuel input: "..dump(input))
1765         local output, decremented_input = minetest.get_craft_result(input)
1766         minetest.log("info", "coal fuel output: "..dump(output))
1767         minetest.log("info", "coal fuel decremented input: "..dump(decremented_input))
1768         assert(output.time)
1769         assert(output.time > 0)
1770         -- cook
1771         local input = {
1772                 method = "cooking",
1773                 width = 1,
1774                 items = {"default:cobble"}
1775         }
1776         minetest.log("info", "cobble cooking input: "..dump(output))
1777         local output, decremented_input = minetest.get_craft_result(input)
1778         minetest.log("info", "cobble cooking output: "..dump(output))
1779         minetest.log("info", "cobble cooking decremented input: "..dump(decremented_input))
1780         assert(output.time)
1781         assert(output.time > 0)
1782         assert(output.item)
1783         minetest.log("info", "cobble cooking output.item:to_table(): "..dump(output.item:to_table()))
1784         assert(output.item:get_name() == "default:stone")
1785         assert(output.item:get_count() == 1)
1786 end
1787 test_get_craft_result()
1788
1789 --
1790 -- Done, print some random stuff
1791 --
1792
1793 --print("minetest.registered_entities:")
1794 --dump2(minetest.registered_entities)
1795
1796 -- END
1797