Fix possible crash with grass ABM.
[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 --
456 -- Crafting (tool repair)
457 --
458 minetest.register_craft({
459         type = "toolrepair",
460         additional_wear = -0.02,
461 })
462
463 --
464 -- Cooking recipes
465 --
466
467 minetest.register_craft({
468         type = "cooking",
469         output = "default:glass",
470         recipe = "default:sand",
471 })
472
473 minetest.register_craft({
474         type = "cooking",
475         output = "default:coal_lump",
476         recipe = "default:tree",
477 })
478
479 minetest.register_craft({
480         type = "cooking",
481         output = "default:coal_lump",
482         recipe = "default:jungletree",
483 })
484
485 minetest.register_craft({
486         type = "cooking",
487         output = "default:stone",
488         recipe = "default:cobble",
489 })
490
491 minetest.register_craft({
492         type = "cooking",
493         output = "default:steel_ingot",
494         recipe = "default:iron_lump",
495 })
496
497 minetest.register_craft({
498         type = "cooking",
499         output = "default:clay_brick",
500         recipe = "default:clay_lump",
501 })
502
503 --
504 -- Fuels
505 --
506
507 minetest.register_craft({
508         type = "fuel",
509         recipe = "default:tree",
510         burntime = 30,
511 })
512
513 minetest.register_craft({
514         type = "fuel",
515         recipe = "default:jungletree",
516         burntime = 30,
517 })
518
519 minetest.register_craft({
520         type = "fuel",
521         recipe = "default:junglegrass",
522         burntime = 2,
523 })
524
525 minetest.register_craft({
526         type = "fuel",
527         recipe = "default:leaves",
528         burntime = 1,
529 })
530
531 minetest.register_craft({
532         type = "fuel",
533         recipe = "default:cactus",
534         burntime = 15,
535 })
536
537 minetest.register_craft({
538         type = "fuel",
539         recipe = "default:papyrus",
540         burntime = 1,
541 })
542
543 minetest.register_craft({
544         type = "fuel",
545         recipe = "default:bookshelf",
546         burntime = 30,
547 })
548
549 minetest.register_craft({
550         type = "fuel",
551         recipe = "default:fence_wood",
552         burntime = 15,
553 })
554
555 minetest.register_craft({
556         type = "fuel",
557         recipe = "default:ladder",
558         burntime = 5,
559 })
560
561 minetest.register_craft({
562         type = "fuel",
563         recipe = "default:wood",
564         burntime = 7,
565 })
566
567 minetest.register_craft({
568         type = "fuel",
569         recipe = "default:mese",
570         burntime = 30,
571 })
572
573 minetest.register_craft({
574         type = "fuel",
575         recipe = "default:lava_source",
576         burntime = 60,
577 })
578
579 minetest.register_craft({
580         type = "fuel",
581         recipe = "default:torch",
582         burntime = 4,
583 })
584
585 minetest.register_craft({
586         type = "fuel",
587         recipe = "default:sign_wall",
588         burntime = 10,
589 })
590
591 minetest.register_craft({
592         type = "fuel",
593         recipe = "default:chest",
594         burntime = 30,
595 })
596
597 minetest.register_craft({
598         type = "fuel",
599         recipe = "default:chest_locked",
600         burntime = 30,
601 })
602
603 minetest.register_craft({
604         type = "fuel",
605         recipe = "default:nyancat",
606         burntime = 1,
607 })
608
609 minetest.register_craft({
610         type = "fuel",
611         recipe = "default:nyancat_rainbow",
612         burntime = 1,
613 })
614
615 minetest.register_craft({
616         type = "fuel",
617         recipe = "default:sapling",
618         burntime = 10,
619 })
620
621 minetest.register_craft({
622         type = "fuel",
623         recipe = "default:apple",
624         burntime = 3,
625 })
626
627 minetest.register_craft({
628         type = "fuel",
629         recipe = "default:coal_lump",
630         burntime = 40,
631 })
632
633 --
634 -- Node definitions
635 --
636
637 -- Default node sounds
638
639 function default.node_sound_defaults(table)
640         table = table or {}
641         table.footstep = table.footstep or
642                         {name="", gain=1.0}
643         table.dug = table.dug or
644                         {name="default_dug_node", gain=1.0}
645         return table
646 end
647
648 function default.node_sound_stone_defaults(table)
649         table = table or {}
650         table.footstep = table.footstep or
651                         {name="default_hard_footstep", gain=0.2}
652         default.node_sound_defaults(table)
653         return table
654 end
655
656 function default.node_sound_dirt_defaults(table)
657         table = table or {}
658         table.footstep = table.footstep or
659                         {name="", gain=0.5}
660         --table.dug = table.dug or
661         --              {name="default_dirt_break", gain=0.5}
662         table.place = table.place or
663                         {name="default_grass_footstep", gain=0.5}
664         default.node_sound_defaults(table)
665         return table
666 end
667
668 function default.node_sound_sand_defaults(table)
669         table = table or {}
670         table.footstep = table.footstep or
671                         {name="default_grass_footstep", gain=0.25}
672         --table.dug = table.dug or
673         --              {name="default_dirt_break", gain=0.25}
674         table.dug = table.dug or
675                         {name="", gain=0.25}
676         default.node_sound_defaults(table)
677         return table
678 end
679
680 function default.node_sound_wood_defaults(table)
681         table = table or {}
682         table.footstep = table.footstep or
683                         {name="default_hard_footstep", gain=0.3}
684         default.node_sound_defaults(table)
685         return table
686 end
687
688 function default.node_sound_leaves_defaults(table)
689         table = table or {}
690         table.footstep = table.footstep or
691                         {name="default_grass_footstep", gain=0.25}
692         table.dig = table.dig or
693                         {name="default_dig_crumbly", gain=0.4}
694         table.dug = table.dug or
695                         {name="", gain=1.0}
696         default.node_sound_defaults(table)
697         return table
698 end
699
700 function default.node_sound_glass_defaults(table)
701         table = table or {}
702         table.footstep = table.footstep or
703                         {name="default_stone_footstep", gain=0.25}
704         table.dug = table.dug or
705                         {name="default_break_glass", gain=1.0}
706         default.node_sound_defaults(table)
707         return table
708 end
709
710 --
711
712 minetest.register_node("default:stone", {
713         description = "Stone",
714         tiles ={"default_stone.png"},
715         is_ground_content = true,
716         groups = {cracky=3},
717         drop = 'default:cobble',
718         legacy_mineral = true,
719         sounds = default.node_sound_stone_defaults(),
720 })
721
722 minetest.register_node("default:stone_with_coal", {
723         description = "Stone with coal",
724         tiles ={"default_stone.png^default_mineral_coal.png"},
725         is_ground_content = true,
726         groups = {cracky=3},
727         drop = 'default:coal_lump',
728         sounds = default.node_sound_stone_defaults(),
729 })
730
731 minetest.register_node("default:stone_with_iron", {
732         description = "Stone with iron",
733         tiles ={"default_stone.png^default_mineral_iron.png"},
734         is_ground_content = true,
735         groups = {cracky=3},
736         drop = 'default:iron_lump',
737         sounds = default.node_sound_stone_defaults(),
738 })
739
740 minetest.register_node("default:dirt_with_grass", {
741         description = "Dirt with grass",
742         tiles ={"default_grass.png", "default_dirt.png", "default_dirt.png^default_grass_side.png"},
743         is_ground_content = true,
744         groups = {crumbly=3, soil=1},
745         drop = 'default:dirt',
746         sounds = default.node_sound_dirt_defaults({
747                 footstep = {name="default_grass_footstep", gain=0.4},
748         }),
749 })
750
751 minetest.register_node("default:dirt_with_grass_footsteps", {
752         description = "Dirt with grass and footsteps",
753         tiles ={"default_grass_footsteps.png", "default_dirt.png", "default_dirt.png^default_grass_side.png"},
754         is_ground_content = true,
755         groups = {crumbly=3, soil=1},
756         drop = 'default:dirt',
757         sounds = default.node_sound_dirt_defaults({
758                 footstep = {name="default_grass_footstep", gain=0.4},
759         }),
760 })
761
762 minetest.register_node("default:dirt", {
763         description = "Dirt",
764         tiles ={"default_dirt.png"},
765         is_ground_content = true,
766         groups = {crumbly=3, soil=1},
767         sounds = default.node_sound_dirt_defaults(),
768 })
769
770 minetest.register_node("default:sand", {
771         description = "Sand",
772         tiles ={"default_sand.png"},
773         is_ground_content = true,
774         groups = {crumbly=3, falling_node=1},
775         sounds = default.node_sound_sand_defaults(),
776 })
777
778 minetest.register_node("default:gravel", {
779         description = "Gravel",
780         tiles ={"default_gravel.png"},
781         is_ground_content = true,
782         groups = {crumbly=2, falling_node=1},
783         sounds = default.node_sound_dirt_defaults({
784                 footstep = {name="default_gravel_footstep", gain=0.45},
785         }),
786 })
787
788 minetest.register_node("default:sandstone", {
789         description = "Sandstone",
790         tiles ={"default_sandstone.png"},
791         is_ground_content = true,
792         groups = {crumbly=2,cracky=2},
793         drop = 'default:sand',
794         sounds = default.node_sound_stone_defaults(),
795 })
796
797 minetest.register_node("default:clay", {
798         description = "Clay",
799         tiles ={"default_clay.png"},
800         is_ground_content = true,
801         groups = {crumbly=3},
802         drop = 'default:clay_lump 4',
803         sounds = default.node_sound_dirt_defaults({
804                 footstep = "",
805         }),
806 })
807
808 minetest.register_node("default:brick", {
809         description = "Brick",
810         tiles ={"default_brick.png"},
811         is_ground_content = true,
812         groups = {cracky=3},
813         drop = 'default:clay_brick 4',
814         sounds = default.node_sound_stone_defaults(),
815 })
816
817 minetest.register_node("default:tree", {
818         description = "Tree",
819         tiles ={"default_tree_top.png", "default_tree_top.png", "default_tree.png"},
820         is_ground_content = true,
821         groups = {snappy=2,choppy=2,oddly_breakable_by_hand=1},
822         sounds = default.node_sound_wood_defaults(),
823 })
824
825 minetest.register_node("default:jungletree", {
826         description = "Jungle Tree",
827         tiles ={"default_jungletree_top.png", "default_jungletree_top.png", "default_jungletree.png"},
828         is_ground_content = true,
829         groups = {snappy=2,choppy=2,oddly_breakable_by_hand=1},
830         sounds = default.node_sound_wood_defaults(),
831 })
832
833 minetest.register_node("default:junglegrass", {
834         description = "Jungle Grass",
835         drawtype = "plantlike",
836         visual_scale = 1.3,
837         tiles ={"default_junglegrass.png"},
838         inventory_image = "default_junglegrass.png",
839         wield_image = "default_junglegrass.png",
840         paramtype = "light",
841         walkable = false,
842         groups = {snappy=3,attached_node=1},
843         sounds = default.node_sound_leaves_defaults(),
844 })
845
846 minetest.register_node("default:leaves", {
847         description = "Leaves",
848         drawtype = "allfaces_optional",
849         visual_scale = 1.3,
850         tiles ={"default_leaves.png"},
851         paramtype = "light",
852         groups = {snappy=3},
853         drop = {
854                 max_items = 1,
855                 items = {
856                         {
857                                 -- player will get sapling with 1/20 chance
858                                 items = {'default:sapling'},
859                                 rarity = 20,
860                         },
861                         {
862                                 -- player will get leaves only if he get no saplings,
863                                 -- this is because max_items is 1
864                                 items = {'default:leaves'},
865                         }
866                 }
867         },
868         sounds = default.node_sound_leaves_defaults(),
869 })
870
871 minetest.register_node("default:cactus", {
872         description = "Cactus",
873         tiles ={"default_cactus_top.png", "default_cactus_top.png", "default_cactus_side.png"},
874         is_ground_content = true,
875         groups = {snappy=2,choppy=3},
876         sounds = default.node_sound_wood_defaults(),
877 })
878
879 minetest.register_node("default:papyrus", {
880         description = "Papyrus",
881         drawtype = "plantlike",
882         tiles ={"default_papyrus.png"},
883         inventory_image = "default_papyrus.png",
884         wield_image = "default_papyrus.png",
885         paramtype = "light",
886         is_ground_content = true,
887         walkable = false,
888         groups = {snappy=3},
889         sounds = default.node_sound_leaves_defaults(),
890 })
891
892 minetest.register_node("default:bookshelf", {
893         description = "Bookshelf",
894         tiles ={"default_wood.png", "default_wood.png", "default_bookshelf.png"},
895         is_ground_content = true,
896         groups = {snappy=2,choppy=3,oddly_breakable_by_hand=2},
897         sounds = default.node_sound_wood_defaults(),
898 })
899
900 minetest.register_node("default:glass", {
901         description = "Glass",
902         drawtype = "glasslike",
903         tiles ={"default_glass.png"},
904         inventory_image = minetest.inventorycube("default_glass.png"),
905         paramtype = "light",
906         sunlight_propagates = true,
907         is_ground_content = true,
908         groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3},
909         sounds = default.node_sound_glass_defaults(),
910 })
911
912 minetest.register_node("default:fence_wood", {
913         description = "Wooden Fence",
914         drawtype = "fencelike",
915         tiles ={"default_wood.png"},
916         inventory_image = "default_fence.png",
917         wield_image = "default_fence.png",
918         paramtype = "light",
919         is_ground_content = true,
920         selection_box = {
921                 type = "fixed",
922                 fixed = {-1/7, -1/2, -1/7, 1/7, 1/2, 1/7},
923         },
924         groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2},
925         sounds = default.node_sound_wood_defaults(),
926 })
927
928 minetest.register_node("default:rail", {
929         description = "Rail",
930         drawtype = "raillike",
931         tiles ={"default_rail.png", "default_rail_curved.png", "default_rail_t_junction.png", "default_rail_crossing.png"},
932         inventory_image = "default_rail.png",
933         wield_image = "default_rail.png",
934         paramtype = "light",
935         is_ground_content = true,
936         walkable = false,
937         selection_box = {
938                 type = "fixed",
939                 fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
940         },
941         groups = {bendy=2,snappy=1,dig_immediate=2},
942 })
943
944 minetest.register_node("default:ladder", {
945         description = "Ladder",
946         drawtype = "signlike",
947         tiles ={"default_ladder.png"},
948         inventory_image = "default_ladder.png",
949         wield_image = "default_ladder.png",
950         paramtype = "light",
951         paramtype2 = "wallmounted",
952         is_ground_content = true,
953         walkable = false,
954         climbable = true,
955         selection_box = {
956                 type = "wallmounted",
957                 --wall_top = = <default>
958                 --wall_bottom = = <default>
959                 --wall_side = = <default>
960         },
961         groups = {snappy=2,choppy=2,oddly_breakable_by_hand=3},
962         legacy_wallmounted = true,
963         sounds = default.node_sound_wood_defaults(),
964 })
965
966 minetest.register_node("default:wood", {
967         description = "Wood",
968         tiles ={"default_wood.png"},
969         is_ground_content = true,
970         groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2},
971         sounds = default.node_sound_wood_defaults(),
972 })
973
974 minetest.register_node("default:mese", {
975         description = "Mese",
976         tiles ={"default_mese.png"},
977         is_ground_content = true,
978         groups = {cracky=1,level=2},
979         sounds = default.node_sound_defaults(),
980 })
981
982 minetest.register_node("default:cloud", {
983         description = "Cloud",
984         tiles ={"default_cloud.png"},
985         is_ground_content = true,
986         sounds = default.node_sound_defaults(),
987 })
988
989 minetest.register_node("default:water_flowing", {
990         description = "Water (flowing)",
991         inventory_image = minetest.inventorycube("default_water.png"),
992         drawtype = "flowingliquid",
993         tiles ={"default_water.png"},
994         special_tiles = {
995                 {name="default_water.png", backface_culling=false},
996                 {name="default_water.png", backface_culling=true},
997         },
998         alpha = WATER_ALPHA,
999         paramtype = "light",
1000         walkable = false,
1001         pointable = false,
1002         diggable = false,
1003         buildable_to = true,
1004         drowning = 1,
1005         liquidtype = "flowing",
1006         liquid_alternative_flowing = "default:water_flowing",
1007         liquid_alternative_source = "default:water_source",
1008         liquid_viscosity = WATER_VISC,
1009         post_effect_color = {a=64, r=100, g=100, b=200},
1010         groups = {water=3, liquid=3},
1011 })
1012
1013 minetest.register_node("default:water_source", {
1014         description = "Water",
1015         inventory_image = minetest.inventorycube("default_water.png"),
1016         drawtype = "liquid",
1017         tiles ={"default_water.png"},
1018         special_tiles = {
1019                 -- New-style water source material (mostly unused)
1020                 {name="default_water.png", backface_culling=false},
1021         },
1022         alpha = WATER_ALPHA,
1023         paramtype = "light",
1024         walkable = false,
1025         pointable = false,
1026         diggable = false,
1027         buildable_to = true,
1028         drowning = 1,
1029         liquidtype = "source",
1030         liquid_alternative_flowing = "default:water_flowing",
1031         liquid_alternative_source = "default:water_source",
1032         liquid_viscosity = WATER_VISC,
1033         post_effect_color = {a=64, r=100, g=100, b=200},
1034         groups = {water=3, liquid=3},
1035 })
1036
1037 minetest.register_node("default:lava_flowing", {
1038         description = "Lava (flowing)",
1039         inventory_image = minetest.inventorycube("default_lava.png"),
1040         drawtype = "flowingliquid",
1041         tiles ={"default_lava.png"},
1042         special_tiles = {
1043                 {
1044                         image="default_lava_flowing_animated.png",
1045                         backface_culling=false,
1046                         animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.3}
1047                 },
1048                 {
1049                         image="default_lava_flowing_animated.png",
1050                         backface_culling=true,
1051                         animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.3}
1052                 },
1053         },
1054         paramtype = "light",
1055         light_source = LIGHT_MAX - 1,
1056         walkable = false,
1057         pointable = false,
1058         diggable = false,
1059         buildable_to = true,
1060         drowning = 1,
1061         liquidtype = "flowing",
1062         liquid_alternative_flowing = "default:lava_flowing",
1063         liquid_alternative_source = "default:lava_source",
1064         liquid_viscosity = LAVA_VISC,
1065         damage_per_second = 4*2,
1066         post_effect_color = {a=192, r=255, g=64, b=0},
1067         groups = {lava=3, liquid=2, hot=3},
1068 })
1069
1070 minetest.register_node("default:lava_source", {
1071         description = "Lava",
1072         inventory_image = minetest.inventorycube("default_lava.png"),
1073         drawtype = "liquid",
1074         --tiles ={"default_lava.png"},
1075         tiles ={
1076                 {name="default_lava_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}}
1077         },
1078         special_tiles = {
1079                 -- New-style lava source material (mostly unused)
1080                 {name="default_lava.png", backface_culling=false},
1081         },
1082         paramtype = "light",
1083         light_source = LIGHT_MAX - 1,
1084         walkable = false,
1085         pointable = false,
1086         diggable = false,
1087         buildable_to = true,
1088         drowning = 1,
1089         liquidtype = "source",
1090         liquid_alternative_flowing = "default:lava_flowing",
1091         liquid_alternative_source = "default:lava_source",
1092         liquid_viscosity = LAVA_VISC,
1093         damage_per_second = 4*2,
1094         post_effect_color = {a=192, r=255, g=64, b=0},
1095         groups = {lava=3, liquid=2, hot=3},
1096 })
1097
1098 minetest.register_node("default:torch", {
1099         description = "Torch",
1100         drawtype = "torchlike",
1101         tiles ={"default_torch_on_floor.png", "default_torch_on_ceiling.png", "default_torch.png"},
1102         inventory_image = "default_torch_on_floor.png",
1103         wield_image = "default_torch_on_floor.png",
1104         paramtype = "light",
1105         paramtype2 = "wallmounted",
1106         sunlight_propagates = true,
1107         walkable = false,
1108         light_source = LIGHT_MAX-1,
1109         selection_box = {
1110                 type = "wallmounted",
1111                 wall_top = {-0.1, 0.5-0.6, -0.1, 0.1, 0.5, 0.1},
1112                 wall_bottom = {-0.1, -0.5, -0.1, 0.1, -0.5+0.6, 0.1},
1113                 wall_side = {-0.5, -0.3, -0.1, -0.5+0.3, 0.3, 0.1},
1114         },
1115         groups = {choppy=2,dig_immediate=3,attached_node=1},
1116         legacy_wallmounted = true,
1117         sounds = default.node_sound_defaults(),
1118 })
1119
1120 minetest.register_node("default:sign_wall", {
1121         description = "Sign",
1122         drawtype = "signlike",
1123         tiles ={"default_sign_wall.png"},
1124         inventory_image = "default_sign_wall.png",
1125         wield_image = "default_sign_wall.png",
1126         paramtype = "light",
1127         paramtype2 = "wallmounted",
1128         sunlight_propagates = true,
1129         walkable = false,
1130         selection_box = {
1131                 type = "wallmounted",
1132                 --wall_top = <default>
1133                 --wall_bottom = <default>
1134                 --wall_side = <default>
1135         },
1136         groups = {choppy=2,dig_immediate=2,attached_node=1},
1137         legacy_wallmounted = true,
1138         sounds = default.node_sound_defaults(),
1139         on_construct = function(pos)
1140                 --local n = minetest.get_node(pos)
1141                 local meta = minetest.get_meta(pos)
1142                 meta:set_string("formspec", "field[text;;${text}]")
1143                 meta:set_string("infotext", "\"\"")
1144         end,
1145         on_receive_fields = function(pos, formname, fields, sender)
1146                 --print("Sign at "..minetest.pos_to_string(pos).." got "..dump(fields))
1147                 local meta = minetest.get_meta(pos)
1148                 fields.text = fields.text or ""
1149                 print((sender:get_player_name() or "").." wrote \""..fields.text..
1150                                 "\" to sign at "..minetest.pos_to_string(pos))
1151                 meta:set_string("text", fields.text)
1152                 meta:set_string("infotext", '"'..fields.text..'"')
1153         end,
1154 })
1155
1156 minetest.register_node("default:chest", {
1157         description = "Chest",
1158         tiles ={"default_chest_top.png", "default_chest_top.png", "default_chest_side.png",
1159                 "default_chest_side.png", "default_chest_side.png", "default_chest_front.png"},
1160         paramtype2 = "facedir",
1161         groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2},
1162         legacy_facedir_simple = true,
1163         sounds = default.node_sound_wood_defaults(),
1164         on_construct = function(pos)
1165                 local meta = minetest.get_meta(pos)
1166                 meta:set_string("formspec",
1167                                 "size[8,9]"..
1168                                 "list[current_name;main;0,0;8,4;]"..
1169                                 "list[current_player;main;0,5;8,4;]")
1170                 meta:set_string("infotext", "Chest")
1171                 local inv = meta:get_inventory()
1172                 inv:set_size("main", 8*4)
1173         end,
1174         can_dig = function(pos,player)
1175                 local meta = minetest.get_meta(pos);
1176                 local inv = meta:get_inventory()
1177                 return inv:is_empty("main")
1178         end,
1179 })
1180
1181 local function has_locked_chest_privilege(meta, player)
1182         if player:get_player_name() ~= meta:get_string("owner") then
1183                 return false
1184         end
1185         return true
1186 end
1187
1188 minetest.register_node("default:chest_locked", {
1189         description = "Locked Chest",
1190         tiles ={"default_chest_top.png", "default_chest_top.png", "default_chest_side.png",
1191                 "default_chest_side.png", "default_chest_side.png", "default_chest_lock.png"},
1192         paramtype2 = "facedir",
1193         groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2},
1194         legacy_facedir_simple = true,
1195         sounds = default.node_sound_wood_defaults(),
1196         after_place_node = function(pos, placer)
1197                 local meta = minetest.get_meta(pos)
1198                 meta:set_string("owner", placer:get_player_name() or "")
1199                 meta:set_string("infotext", "Locked Chest (owned by "..
1200                                 meta:get_string("owner")..")")
1201         end,
1202         on_construct = function(pos)
1203                 local meta = minetest.get_meta(pos)
1204                 meta:set_string("formspec",
1205                                 "size[8,9]"..
1206                                 "list[current_name;main;0,0;8,4;]"..
1207                                 "list[current_player;main;0,5;8,4;]")
1208                 meta:set_string("infotext", "Locked Chest")
1209                 meta:set_string("owner", "")
1210                 local inv = meta:get_inventory()
1211                 inv:set_size("main", 8*4)
1212         end,
1213         can_dig = function(pos,player)
1214                 local meta = minetest.get_meta(pos);
1215                 local inv = meta:get_inventory()
1216                 return inv:is_empty("main")
1217         end,
1218         allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
1219                 local meta = minetest.get_meta(pos)
1220                 if not has_locked_chest_privilege(meta, player) then
1221                         minetest.log("action", player:get_player_name()..
1222                                         " tried to access a locked chest belonging to "..
1223                                         meta:get_string("owner").." at "..
1224                                         minetest.pos_to_string(pos))
1225                         return 0
1226                 end
1227                 return count
1228         end,
1229     allow_metadata_inventory_put = function(pos, listname, index, stack, player)
1230                 local meta = minetest.get_meta(pos)
1231                 if not has_locked_chest_privilege(meta, player) then
1232                         minetest.log("action", player:get_player_name()..
1233                                         " tried to access a locked chest belonging to "..
1234                                         meta:get_string("owner").." at "..
1235                                         minetest.pos_to_string(pos))
1236                         return 0
1237                 end
1238                 return stack:get_count()
1239         end,
1240     allow_metadata_inventory_take = function(pos, listname, index, stack, player)
1241                 local meta = minetest.get_meta(pos)
1242                 if not has_locked_chest_privilege(meta, player) then
1243                         minetest.log("action", player:get_player_name()..
1244                                         " tried to access a locked chest belonging to "..
1245                                         meta:get_string("owner").." at "..
1246                                         minetest.pos_to_string(pos))
1247                         return 0
1248                 end
1249                 return stack:get_count()
1250         end,
1251         on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
1252                 minetest.log("action", player:get_player_name()..
1253                                 " moves stuff in locked chest at "..minetest.pos_to_string(pos))
1254         end,
1255     on_metadata_inventory_put = function(pos, listname, index, stack, player)
1256                 minetest.log("action", player:get_player_name()..
1257                                 " moves stuff to locked chest at "..minetest.pos_to_string(pos))
1258         end,
1259     on_metadata_inventory_take = function(pos, listname, index, stack, player)
1260                 minetest.log("action", player:get_player_name()..
1261                                 " takes stuff from locked chest at "..minetest.pos_to_string(pos))
1262         end,
1263 })
1264
1265 default.furnace_inactive_formspec =
1266         "size[8,9]"..
1267         "image[2,2;1,1;default_furnace_fire_bg.png]"..
1268         "list[current_name;fuel;2,3;1,1;]"..
1269         "list[current_name;src;2,1;1,1;]"..
1270         "list[current_name;dst;5,1;2,2;]"..
1271         "list[current_player;main;0,5;8,4;]"
1272
1273 minetest.register_node("default:furnace", {
1274         description = "Furnace",
1275         tiles ={"default_furnace_side.png", "default_furnace_side.png", "default_furnace_side.png",
1276                 "default_furnace_side.png", "default_furnace_side.png", "default_furnace_front.png"},
1277         paramtype2 = "facedir",
1278         groups = {cracky=2},
1279         legacy_facedir_simple = true,
1280         sounds = default.node_sound_stone_defaults(),
1281         on_construct = function(pos)
1282                 local meta = minetest.get_meta(pos)
1283                 meta:set_string("formspec", default.furnace_inactive_formspec)
1284                 meta:set_string("infotext", "Furnace")
1285                 local inv = meta:get_inventory()
1286                 inv:set_size("fuel", 1)
1287                 inv:set_size("src", 1)
1288                 inv:set_size("dst", 4)
1289         end,
1290         can_dig = function(pos,player)
1291                 local meta = minetest.get_meta(pos);
1292                 local inv = meta:get_inventory()
1293                 if not inv:is_empty("fuel") then
1294                         return false
1295                 elseif not inv:is_empty("dst") then
1296                         return false
1297                 elseif not inv:is_empty("src") then
1298                         return false
1299                 end
1300                 return true
1301         end,
1302 })
1303
1304 minetest.register_node("default:furnace_active", {
1305         description = "Furnace",
1306         tiles ={"default_furnace_side.png", "default_furnace_side.png", "default_furnace_side.png",
1307                 "default_furnace_side.png", "default_furnace_side.png", "default_furnace_front_active.png"},
1308         paramtype2 = "facedir",
1309         light_source = 8,
1310         drop = "default:furnace",
1311         groups = {cracky=2},
1312         legacy_facedir_simple = true,
1313         sounds = default.node_sound_stone_defaults(),
1314         on_construct = function(pos)
1315                 local meta = minetest.get_meta(pos)
1316                 meta:set_string("formspec", default.furnace_inactive_formspec)
1317                 meta:set_string("infotext", "Furnace");
1318                 local inv = meta:get_inventory()
1319                 inv:set_size("fuel", 1)
1320                 inv:set_size("src", 1)
1321                 inv:set_size("dst", 4)
1322         end,
1323         can_dig = function(pos,player)
1324                 local meta = minetest.get_meta(pos);
1325                 local inv = meta:get_inventory()
1326                 if not inv:is_empty("fuel") then
1327                         return false
1328                 elseif not inv:is_empty("dst") then
1329                         return false
1330                 elseif not inv:is_empty("src") then
1331                         return false
1332                 end
1333                 return true
1334         end,
1335 })
1336
1337 function hacky_swap_node(pos,name)
1338         local node = minetest.get_node(pos)
1339         local meta = minetest.get_meta(pos)
1340         local meta0 = meta:to_table()
1341         if node.name == name then
1342                 return
1343         end
1344         node.name = name
1345         local meta0 = meta:to_table()
1346         minetest.set_node(pos,node)
1347         meta = minetest.get_meta(pos)
1348         meta:from_table(meta0)
1349 end
1350
1351 minetest.register_abm({
1352         nodenames = {"default:furnace","default:furnace_active"},
1353         interval = 1.0,
1354         chance = 1,
1355         action = function(pos, node, active_object_count, active_object_count_wider)
1356                 local meta = minetest.get_meta(pos)
1357                 for i, name in ipairs({
1358                                 "fuel_totaltime",
1359                                 "fuel_time",
1360                                 "src_totaltime",
1361                                 "src_time"
1362                 }) do
1363                         if meta:get_string(name) == "" then
1364                                 meta:set_float(name, 0.0)
1365                         end
1366                 end
1367
1368                 local inv = meta:get_inventory()
1369
1370                 local srclist = inv:get_list("src")
1371                 local cooked = nil
1372                 
1373                 if srclist then
1374                         cooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
1375                 end
1376                 
1377                 local was_active = false
1378                 
1379                 if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
1380                         was_active = true
1381                         meta:set_float("fuel_time", meta:get_float("fuel_time") + 1)
1382                         meta:set_float("src_time", meta:get_float("src_time") + 1)
1383                         if cooked and cooked.item and meta:get_float("src_time") >= cooked.time then
1384                                 -- check if there's room for output in "dst" list
1385                                 if inv:room_for_item("dst",cooked.item) then
1386                                         -- Put result in "dst" list
1387                                         inv:add_item("dst", cooked.item)
1388                                         -- take stuff from "src" list
1389                                         srcstack = inv:get_stack("src", 1)
1390                                         srcstack:take_item()
1391                                         inv:set_stack("src", 1, srcstack)
1392                                 else
1393                                         print("Could not insert '"..cooked.item:to_string().."'")
1394                                 end
1395                                 meta:set_string("src_time", 0)
1396                         end
1397                 end
1398                 
1399                 if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
1400                         local percent = math.floor(meta:get_float("fuel_time") /
1401                                         meta:get_float("fuel_totaltime") * 100)
1402                         meta:set_string("infotext","Furnace active: "..percent.."%")
1403                         hacky_swap_node(pos,"default:furnace_active")
1404                         meta:set_string("formspec",
1405                                 "size[8,9]"..
1406                                 "image[2,2;1,1;default_furnace_fire_bg.png^[lowpart:"..
1407                                                 (100-percent)..":default_furnace_fire_fg.png]"..
1408                                 "list[current_name;fuel;2,3;1,1;]"..
1409                                 "list[current_name;src;2,1;1,1;]"..
1410                                 "list[current_name;dst;5,1;2,2;]"..
1411                                 "list[current_player;main;0,5;8,4;]")
1412                         return
1413                 end
1414
1415                 local fuel = nil
1416                 local cooked = nil
1417                 local fuellist = inv:get_list("fuel")
1418                 local srclist = inv:get_list("src")
1419                 
1420                 if srclist then
1421                         cooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
1422                 end
1423                 if fuellist then
1424                         fuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist})
1425                 end
1426
1427                 if fuel.time <= 0 then
1428                         meta:set_string("infotext","Furnace out of fuel")
1429                         hacky_swap_node(pos,"default:furnace")
1430                         meta:set_string("formspec", default.furnace_inactive_formspec)
1431                         return
1432                 end
1433
1434                 if cooked.item:is_empty() then
1435                         if was_active then
1436                                 meta:set_string("infotext","Furnace is empty")
1437                                 hacky_swap_node(pos,"default:furnace")
1438                                 meta:set_string("formspec", default.furnace_inactive_formspec)
1439                         end
1440                         return
1441                 end
1442
1443                 meta:set_string("fuel_totaltime", fuel.time)
1444                 meta:set_string("fuel_time", 0)
1445                 
1446                 local stack = inv:get_stack("fuel", 1)
1447                 stack:take_item()
1448                 inv:set_stack("fuel", 1, stack)
1449         end,
1450 })
1451
1452 minetest.register_node("default:cobble", {
1453         description = "Cobble",
1454         tiles ={"default_cobble.png"},
1455         is_ground_content = true,
1456         groups = {cracky=3},
1457         sounds = default.node_sound_stone_defaults(),
1458 })
1459
1460 minetest.register_node("default:mossycobble", {
1461         description = "Mossy Cobble",
1462         tiles ={"default_mossycobble.png"},
1463         is_ground_content = true,
1464         groups = {cracky=3},
1465         sounds = default.node_sound_stone_defaults(),
1466 })
1467
1468 minetest.register_node("default:steelblock", {
1469         description = "Steel Block",
1470         tiles ={"default_steel_block.png"},
1471         is_ground_content = true,
1472         groups = {snappy=1,bendy=2},
1473         sounds = default.node_sound_stone_defaults(),
1474 })
1475
1476 minetest.register_node("default:nyancat", {
1477         description = "Nyancat",
1478         tiles ={"default_nc_side.png", "default_nc_side.png", "default_nc_side.png",
1479                 "default_nc_side.png", "default_nc_back.png", "default_nc_front.png"},
1480         inventory_image = "default_nc_front.png",
1481         paramtype2 = "facedir",
1482         groups = {cracky=2},
1483         legacy_facedir_simple = true,
1484         sounds = default.node_sound_defaults(),
1485 })
1486
1487 minetest.register_node("default:nyancat_rainbow", {
1488         description = "Nyancat Rainbow",
1489         tiles ={"default_nc_rb.png"},
1490         inventory_image = "default_nc_rb.png",
1491         groups = {cracky=2},
1492         sounds = default.node_sound_defaults(),
1493 })
1494
1495 minetest.register_node("default:sapling", {
1496         description = "Sapling",
1497         drawtype = "plantlike",
1498         visual_scale = 1.0,
1499         tiles ={"default_sapling.png"},
1500         inventory_image = "default_sapling.png",
1501         wield_image = "default_sapling.png",
1502         paramtype = "light",
1503         walkable = false,
1504         groups = {snappy=2,dig_immediate=3,attached_node=1},
1505         sounds = default.node_sound_defaults(),
1506 })
1507
1508 minetest.register_node("default:apple", {
1509         description = "Apple",
1510         drawtype = "plantlike",
1511         visual_scale = 1.0,
1512         tiles ={"default_apple.png"},
1513         inventory_image = "default_apple.png",
1514         paramtype = "light",
1515         sunlight_propagates = true,
1516         walkable = false,
1517         groups = {fleshy=3,dig_immediate=3},
1518         on_use = minetest.item_eat(4),
1519         sounds = default.node_sound_defaults(),
1520 })
1521
1522
1523 local c_air = minetest.get_content_id("air")
1524 local c_ignore = minetest.get_content_id("ignore")
1525 local c_tree = minetest.get_content_id("default:tree")
1526 local c_leaves = minetest.get_content_id("default:leaves")
1527 local c_apple = minetest.get_content_id("default:apple")
1528 function default.grow_tree(data, a, pos, is_apple_tree, seed)
1529         --[[
1530                 NOTE: Tree-placing code is currently duplicated in the engine
1531                 and in games that have saplings; both are deprecated but not
1532                 replaced yet
1533         ]]--
1534         local pr = PseudoRandom(seed)
1535         local th = pr:next(4, 5)
1536         local x, y, z = pos.x, pos.y, pos.z
1537         for yy = y, y+th-1 do
1538                 local vi = a:index(x, yy, z)
1539                 if a:contains(x, yy, z) and (data[vi] == c_air or yy == y) then
1540                         data[vi] = c_tree
1541                 end
1542         end
1543         y = y+th-1 -- (x, y, z) is now last piece of trunk
1544         local leaves_a = VoxelArea:new{MinEdge={x=-2, y=-1, z=-2}, MaxEdge={x=2, y=2, z=2}}
1545         local leaves_buffer = {}
1546         
1547         -- Force leaves near the trunk
1548         local d = 1
1549         for xi = -d, d do
1550         for yi = -d, d do
1551         for zi = -d, d do
1552                 leaves_buffer[leaves_a:index(xi, yi, zi)] = true
1553         end
1554         end
1555         end
1556         
1557         -- Add leaves randomly
1558         for iii = 1, 8 do
1559                 local d = 1
1560                 local xx = pr:next(leaves_a.MinEdge.x, leaves_a.MaxEdge.x - d)
1561                 local yy = pr:next(leaves_a.MinEdge.y, leaves_a.MaxEdge.y - d)
1562                 local zz = pr:next(leaves_a.MinEdge.z, leaves_a.MaxEdge.z - d)
1563                 
1564                 for xi = 0, d do
1565                 for yi = 0, d do
1566                 for zi = 0, d do
1567                         leaves_buffer[leaves_a:index(xx+xi, yy+yi, zz+zi)] = true
1568                 end
1569                 end
1570                 end
1571         end
1572         
1573         -- Add the leaves
1574         for xi = leaves_a.MinEdge.x, leaves_a.MaxEdge.x do
1575         for yi = leaves_a.MinEdge.y, leaves_a.MaxEdge.y do
1576         for zi = leaves_a.MinEdge.z, leaves_a.MaxEdge.z do
1577                 if a:contains(x+xi, y+yi, z+zi) then
1578                         local vi = a:index(x+xi, y+yi, z+zi)
1579                         if data[vi] == c_air or data[vi] == c_ignore then
1580                                 if leaves_buffer[leaves_a:index(xi, yi, zi)] then
1581                                         if is_apple_tree and pr:next(1, 100) <=  10 then
1582                                                 data[vi] = c_apple
1583                                         else
1584                                                 data[vi] = c_leaves
1585                                         end
1586                                 end
1587                         end
1588                 end
1589         end
1590         end
1591         end
1592 end
1593
1594 minetest.register_abm({
1595         nodenames = {"default:sapling"},
1596         interval = 10,
1597         chance = 50,
1598         action = function(pos, node)
1599                 local is_soil = minetest.registered_nodes[minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}).name].groups.soil
1600                 if is_soil == nil or is_soil == 0 then return end
1601                 print("A sapling grows into a tree at "..minetest.pos_to_string(pos))
1602                 local vm = minetest.get_voxel_manip()
1603                 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})
1604                 local a = VoxelArea:new{MinEdge=minp, MaxEdge=maxp}
1605                 local data = vm:get_data()
1606                 default.grow_tree(data, a, pos, math.random(1, 4) == 1, math.random(1,100000))
1607                 vm:set_data(data)
1608                 vm:write_to_map(data)
1609                 vm:update_map()
1610         end
1611 })
1612
1613 minetest.register_abm({
1614         nodenames = {"default:dirt"},
1615         interval = 2,
1616         chance = 200,
1617         action = function(pos, node)
1618                 local above = {x=pos.x, y=pos.y+1, z=pos.z}
1619                 local name = minetest.get_node(above).name
1620                 local nodedef = minetest.registered_nodes[name]
1621                 if nodedef and (nodedef.sunlight_propagates or nodedef.paramtype == "light")
1622                                 and nodedef.liquidtype == "none"
1623                                 and (minetest.get_node_light(above) or 0) >= 13 then
1624                         if name == "default:snow" or name == "default:snowblock" then
1625                                 minetest.set_node(pos, {name = "default:dirt_with_snow"})
1626                         else
1627                                 minetest.set_node(pos, {name = "default:dirt_with_grass"})
1628                         end
1629                 end
1630         end
1631 })
1632
1633 minetest.register_abm({
1634         nodenames = {"default:dirt_with_grass"},
1635         interval = 2,
1636         chance = 20,
1637         action = function(pos, node)
1638                 local above = {x=pos.x, y=pos.y+1, z=pos.z}
1639                 local name = minetest.get_node(above).name
1640                 local nodedef = minetest.registered_nodes[name]
1641                 if name ~= "ignore" and nodedef
1642                                 and not ((nodedef.sunlight_propagates or nodedef.paramtype == "light")
1643                                 and nodedef.liquidtype == "none") then
1644                         minetest.set_node(pos, {name = "default:dirt"})
1645                 end
1646         end
1647 })
1648
1649 --
1650 -- Crafting items
1651 --
1652
1653 minetest.register_craftitem("default:stick", {
1654         description = "Stick",
1655         inventory_image = "default_stick.png",
1656 })
1657
1658 minetest.register_craftitem("default:paper", {
1659         description = "Paper",
1660         inventory_image = "default_paper.png",
1661 })
1662
1663 minetest.register_craftitem("default:book", {
1664         description = "Book",
1665         inventory_image = "default_book.png",
1666 })
1667
1668 minetest.register_craftitem("default:coal_lump", {
1669         description = "Lump of coal",
1670         inventory_image = "default_coal_lump.png",
1671 })
1672
1673 minetest.register_craftitem("default:iron_lump", {
1674         description = "Lump of iron",
1675         inventory_image = "default_iron_lump.png",
1676 })
1677
1678 minetest.register_craftitem("default:clay_lump", {
1679         description = "Lump of clay",
1680         inventory_image = "default_clay_lump.png",
1681 })
1682
1683 minetest.register_craftitem("default:steel_ingot", {
1684         description = "Steel ingot",
1685         inventory_image = "default_steel_ingot.png",
1686 })
1687
1688 minetest.register_craftitem("default:clay_brick", {
1689         description = "Clay brick",
1690         inventory_image = "default_steel_ingot.png",
1691         inventory_image = "default_clay_brick.png",
1692 })
1693
1694 minetest.register_craftitem("default:scorched_stuff", {
1695         description = "Scorched stuff",
1696         inventory_image = "default_scorched_stuff.png",
1697 })
1698
1699 --
1700 -- Aliases for the current map generator outputs
1701 --
1702
1703 minetest.register_alias("mapgen_air", "air")
1704 minetest.register_alias("mapgen_stone", "default:stone")
1705 minetest.register_alias("mapgen_tree", "default:tree")
1706 minetest.register_alias("mapgen_leaves", "default:leaves")
1707 minetest.register_alias("mapgen_apple", "default:apple")
1708 minetest.register_alias("mapgen_water_source", "default:water_source")
1709 minetest.register_alias("mapgen_dirt", "default:dirt")
1710 minetest.register_alias("mapgen_sand", "default:sand")
1711 minetest.register_alias("mapgen_gravel", "default:gravel")
1712 minetest.register_alias("mapgen_clay", "default:clay")
1713 minetest.register_alias("mapgen_lava_source", "default:lava_source")
1714 minetest.register_alias("mapgen_cobble", "default:cobble")
1715 minetest.register_alias("mapgen_mossycobble", "default:mossycobble")
1716 minetest.register_alias("mapgen_dirt_with_grass", "default:dirt_with_grass")
1717 minetest.register_alias("mapgen_junglegrass", "default:junglegrass")
1718 minetest.register_alias("mapgen_stone_with_coal", "default:stone_with_coal")
1719 minetest.register_alias("mapgen_stone_with_iron", "default:stone_with_iron")
1720 minetest.register_alias("mapgen_mese", "default:mese")
1721
1722 -- Support old code
1723 function default.spawn_falling_node(p, nodename)
1724         spawn_falling_node(p, nodename)
1725 end
1726
1727 -- Horrible crap to support old code
1728 -- Don't use this and never do what this does, it's completely wrong!
1729 -- (More specifically, the client and the C++ code doesn't get the group)
1730 function default.register_falling_node(nodename, texture)
1731         minetest.log("error", debug.traceback())
1732         minetest.log('error', "WARNING: default.register_falling_node is deprecated")
1733         if minetest.registered_nodes[nodename] then
1734                 minetest.registered_nodes[nodename].groups.falling_node = 1
1735         end
1736 end
1737
1738 --
1739 -- Global callbacks
1740 --
1741
1742 -- Global environment step function
1743 function on_step(dtime)
1744         -- print("on_step")
1745 end
1746 minetest.register_globalstep(on_step)
1747
1748 function on_placenode(p, node)
1749         --print("on_placenode")
1750 end
1751 minetest.register_on_placenode(on_placenode)
1752
1753 function on_dignode(p, node)
1754         --print("on_dignode")
1755 end
1756 minetest.register_on_dignode(on_dignode)
1757
1758 function on_punchnode(p, node)
1759 end
1760 minetest.register_on_punchnode(on_punchnode)
1761
1762 --
1763 -- Test some things
1764 --
1765
1766 local function test_get_craft_result()
1767         minetest.log("info", "test_get_craft_result()")
1768         -- normal
1769         local input = {
1770                 method = "normal",
1771                 width = 2,
1772                 items = {"", "default:coal_lump", "", "default:stick"}
1773         }
1774         minetest.log("info", "torch crafting input: "..dump(input))
1775         local output, decremented_input = minetest.get_craft_result(input)
1776         minetest.log("info", "torch crafting output: "..dump(output))
1777         minetest.log("info", "torch crafting decremented input: "..dump(decremented_input))
1778         assert(output.item)
1779         minetest.log("info", "torch crafting output.item:to_table(): "..dump(output.item:to_table()))
1780         assert(output.item:get_name() == "default:torch")
1781         assert(output.item:get_count() == 4)
1782         -- fuel
1783         local input = {
1784                 method = "fuel",
1785                 width = 1,
1786                 items = {"default:coal_lump"}
1787         }
1788         minetest.log("info", "coal fuel input: "..dump(input))
1789         local output, decremented_input = minetest.get_craft_result(input)
1790         minetest.log("info", "coal fuel output: "..dump(output))
1791         minetest.log("info", "coal fuel decremented input: "..dump(decremented_input))
1792         assert(output.time)
1793         assert(output.time > 0)
1794         -- cook
1795         local input = {
1796                 method = "cooking",
1797                 width = 1,
1798                 items = {"default:cobble"}
1799         }
1800         minetest.log("info", "cobble cooking input: "..dump(output))
1801         local output, decremented_input = minetest.get_craft_result(input)
1802         minetest.log("info", "cobble cooking output: "..dump(output))
1803         minetest.log("info", "cobble cooking decremented input: "..dump(decremented_input))
1804         assert(output.time)
1805         assert(output.time > 0)
1806         assert(output.item)
1807         minetest.log("info", "cobble cooking output.item:to_table(): "..dump(output.item:to_table()))
1808         assert(output.item:get_name() == "default:stone")
1809         assert(output.item:get_count() == 1)
1810 end
1811 test_get_craft_result()
1812
1813 --
1814 -- Done, print some random stuff
1815 --
1816
1817 --print("minetest.registered_entities:")
1818 --dump2(minetest.registered_entities)
1819
1820 -- END