dbc96381e9381581e868912396e4bad826220c77
[oweals/minetest.git] / data / mods / default / init.lua
1 function basic_dump2(o)
2         if type(o) == "number" then
3                 return tostring(o)
4         elseif type(o) == "string" then
5                 return string.format("%q", o)
6         elseif type(o) == "boolean" then
7                 return tostring(o)
8         elseif type(o) == "function" then
9                 return "<function>"
10         elseif type(o) == "userdata" then
11                 return "<userdata>"
12         elseif type(o) == "nil" then
13                 return "nil"
14         else
15                 error("cannot dump a " .. type(o))
16                 return nil
17         end
18 end
19
20 function dump2(o, name, dumped)
21         name = name or "_"
22         dumped = dumped or {}
23         io.write(name, " = ")
24         if type(o) == "number" or type(o) == "string" or type(o) == "boolean"
25                         or type(o) == "function" or type(o) == "nil"
26                         or type(o) == "userdata" then
27                 io.write(basic_dump2(o), "\n")
28         elseif type(o) == "table" then
29                 if dumped[o] then
30                         io.write(dumped[o], "\n")
31                 else
32                         dumped[o] = name
33                         io.write("{}\n") -- new table
34                         for k,v in pairs(o) do
35                                 local fieldname = string.format("%s[%s]", name, basic_dump2(k))
36                                 dump2(v, fieldname, dumped)
37                         end
38                 end
39         else
40                 error("cannot dump a " .. type(o))
41                 return nil
42         end
43 end
44
45 function dump(o, dumped)
46         dumped = dumped or {}
47         if type(o) == "number" then
48                 return tostring(o)
49         elseif type(o) == "string" then
50                 return string.format("%q", o)
51         elseif type(o) == "table" then
52                 if dumped[o] then
53                         return "<circular reference>"
54                 end
55                 dumped[o] = true
56                 local t = {}
57                 for k,v in pairs(o) do
58                         t[#t+1] = "" .. k .. " = " .. dump(v, dumped)
59                 end
60                 return "{" .. table.concat(t, ", ") .. "}"
61         elseif type(o) == "boolean" then
62                 return tostring(o)
63         elseif type(o) == "function" then
64                 return "<function>"
65         elseif type(o) == "userdata" then
66                 return "<userdata>"
67         elseif type(o) == "nil" then
68                 return "nil"
69         else
70                 error("cannot dump a " .. type(o))
71                 return nil
72         end
73 end
74
75 -- Textures:
76 -- Mods should prefix their textures with modname_, eg. given the mod
77 -- name "foomod", a texture could be called "foomod_superfurnace.png"
78 --
79 -- Global functions:
80 -- minetest.register_entity(name, prototype_table)
81 -- minetest.register_tool(name, {lots of stuff})
82 -- minetest.register_node(name, {lots of stuff})
83 -- minetest.register_craft({output=item, recipe={...})
84 -- minetest.register_globalstep(func)
85 -- minetest.register_on_placenode(func)
86 -- minetest.register_on_dignode(func)
87 --
88 -- Global objects:
89 -- minetest.env - environment reference
90 --
91 -- Global tables:
92 -- minetest.registered_entities
93 -- ^ List of registered entity prototypes, indexed by name
94 -- minetest.object_refs
95 -- ^ List of object references, indexed by active object id
96 -- minetest.luaentities
97 -- ^ List of lua entities, indexed by active object id
98 --
99 -- EnvRef is basically ServerEnvironment and ServerMap combined.
100 -- EnvRef methods:
101 -- - add_node(pos, node)
102 -- - remove_node(pos)
103 -- - get_node(pos)
104 -- - add_luaentity(pos, name)
105 --
106 -- ObjectRef is basically ServerActiveObject.
107 -- ObjectRef methods:
108 -- - remove(): remove object (after returning from Lua)
109 -- - getpos(): returns {x=num, y=num, z=num}
110 -- - setpos(pos); pos={x=num, y=num, z=num}
111 -- - moveto(pos, continuous=false): interpolated move
112 -- - add_to_inventory(itemstring): add an item to object inventory
113 --
114 -- Registered entities:
115 -- - Functions receive a "luaentity" as self:
116 --   - It has the member .object, which is an ObjectRef pointing to the object
117 --   - The original prototype stuff is visible directly via a metatable
118 -- - Callbacks:
119 --   - on_activate(self, staticdata)
120 --   - on_step(self, dtime)
121 --   - on_punch(self, hitter)
122 --   - on_rightclick(self, clicker)
123 --   - get_staticdata(self): return string
124 --
125 -- MapNode representation:
126 -- {name="name", param1=num, param2=num}
127 --
128 -- Position representation:
129 -- {x=num, y=num, z=num}
130 --
131
132 -- print("minetest dump: "..dump(minetest))
133
134 --
135 -- Tool definition
136 --
137
138 minetest.register_tool("WPick", {
139         image = "tool_woodpick.png",
140         basetime = 2.0,
141         dt_weight = 0,
142         dt_crackiness = -0.5,
143         dt_crumbliness = 2,
144         dt_cuttability = 0,
145         basedurability = 30,
146         dd_weight = 0,
147         dd_crackiness = 0,
148         dd_crumbliness = 0,
149         dd_cuttability = 0,
150 })
151 minetest.register_tool("STPick", {
152         image = "tool_stonepick.png",
153         basetime = 1.5,
154         dt_weight = 0,
155         dt_crackiness = -0.5,
156         dt_crumbliness = 2,
157         dt_cuttability = 0,
158         basedurability = 100,
159         dd_weight = 0,
160         dd_crackiness = 0,
161         dd_crumbliness = 0,
162         dd_cuttability = 0,
163 })
164 minetest.register_tool("SteelPick", {
165         image = "tool_steelpick.png",
166         basetime = 1.0,
167         dt_weight = 0,
168         dt_crackiness = -0.5,
169         dt_crumbliness = 2,
170         dt_cuttability = 0,
171         basedurability = 333,
172         dd_weight = 0,
173         dd_crackiness = 0,
174         dd_crumbliness = 0,
175         dd_cuttability = 0,
176 })
177 minetest.register_tool("MesePick", {
178         image = "tool_mesepick.png",
179         basetime = 0,
180         dt_weight = 0,
181         dt_crackiness = 0,
182         dt_crumbliness = 0,
183         dt_cuttability = 0,
184         basedurability = 1337,
185         dd_weight = 0,
186         dd_crackiness = 0,
187         dd_crumbliness = 0,
188         dd_cuttability = 0,
189 })
190 minetest.register_tool("WShovel", {
191         image = "tool_woodshovel.png",
192         basetime = 2.0,
193         dt_weight = 0.5,
194         dt_crackiness = 2,
195         dt_crumbliness = -1.5,
196         dt_cuttability = 0.3,
197         basedurability = 30,
198         dd_weight = 0,
199         dd_crackiness = 0,
200         dd_crumbliness = 0,
201         dd_cuttability = 0,
202 })
203 minetest.register_tool("STShovel", {
204         image = "tool_stoneshovel.png",
205         basetime = 1.5,
206         dt_weight = 0.5,
207         dt_crackiness = 2,
208         dt_crumbliness = -1.5,
209         dt_cuttability = 0.1,
210         basedurability = 100,
211         dd_weight = 0,
212         dd_crackiness = 0,
213         dd_crumbliness = 0,
214         dd_cuttability = 0,
215 })
216 minetest.register_tool("SteelShovel", {
217         image = "tool_steelshovel.png",
218         basetime = 1.0,
219         dt_weight = 0.5,
220         dt_crackiness = 2,
221         dt_crumbliness = -1.5,
222         dt_cuttability = 0.0,
223         basedurability = 330,
224         dd_weight = 0,
225         dd_crackiness = 0,
226         dd_crumbliness = 0,
227         dd_cuttability = 0,
228 })
229 minetest.register_tool("WAxe", {
230         image = "tool_woodaxe.png",
231         basetime = 2.0,
232         dt_weight = 0.5,
233         dt_crackiness = -0.2,
234         dt_crumbliness = 1,
235         dt_cuttability = -0.5,
236         basedurability = 30,
237         dd_weight = 0,
238         dd_crackiness = 0,
239         dd_crumbliness = 0,
240         dd_cuttability = 0,
241 })
242 minetest.register_tool("STAxe", {
243         image = "tool_stoneaxe.png",
244         basetime = 1.5,
245         dt_weight = 0.5,
246         dt_crackiness = -0.2,
247         dt_crumbliness = 1,
248         dt_cuttability = -0.5,
249         basedurability = 100,
250         dd_weight = 0,
251         dd_crackiness = 0,
252         dd_crumbliness = 0,
253         dd_cuttability = 0,
254 })
255 minetest.register_tool("SteelAxe", {
256         image = "tool_steelaxe.png",
257         basetime = 1.0,
258         dt_weight = 0.5,
259         dt_crackiness = -0.2,
260         dt_crumbliness = 1,
261         dt_cuttability = -0.5,
262         basedurability = 330,
263         dd_weight = 0,
264         dd_crackiness = 0,
265         dd_crumbliness = 0,
266         dd_cuttability = 0,
267 })
268 minetest.register_tool("WSword", {
269         image = "tool_woodsword.png",
270         basetime = 3.0,
271         dt_weight = 3,
272         dt_crackiness = 0,
273         dt_crumbliness = 1,
274         dt_cuttability = -1,
275         basedurability = 30,
276         dd_weight = 0,
277         dd_crackiness = 0,
278         dd_crumbliness = 0,
279         dd_cuttability = 0,
280 })
281 minetest.register_tool("STSword", {
282         image = "tool_stonesword.png",
283         basetime = 2.5,
284         dt_weight = 3,
285         dt_crackiness = 0,
286         dt_crumbliness = 1,
287         dt_cuttability = -1,
288         basedurability = 100,
289         dd_weight = 0,
290         dd_crackiness = 0,
291         dd_crumbliness = 0,
292         dd_cuttability = 0,
293 })
294 minetest.register_tool("SteelSword", {
295         image = "tool_steelsword.png",
296         basetime = 2.0,
297         dt_weight = 3,
298         dt_crackiness = 0,
299         dt_crumbliness = 1,
300         dt_cuttability = -1,
301         basedurability = 330,
302         dd_weight = 0,
303         dd_crackiness = 0,
304         dd_crumbliness = 0,
305         dd_cuttability = 0,
306 })
307 minetest.register_tool("", {
308         image = "",
309         basetime = 0.5,
310         dt_weight = 1,
311         dt_crackiness = 0,
312         dt_crumbliness = -1,
313         dt_cuttability = 0,
314         basedurability = 50,
315         dd_weight = 0,
316         dd_crackiness = 0,
317         dd_crumbliness = 0,
318         dd_cuttability = 0,
319 })
320
321 --[[
322 minetest.register_tool("horribletool", {
323         image = "lava.png",
324         basetime = 2.0
325         dt_weight = 0.2
326         dt_crackiness = 0.2
327         dt_crumbliness = 0.2
328         dt_cuttability = 0.2
329         basedurability = 50
330         dd_weight = -5
331         dd_crackiness = -5
332         dd_crumbliness = -5
333         dd_cuttability = -5
334 })
335 --]]
336
337 --
338 -- Crafting definition
339 --
340
341 minetest.register_craft({
342         output = 'NodeItem "wood" 4',
343         recipe = {
344                 {'NodeItem "tree"'},
345         }
346 })
347
348 minetest.register_craft({
349         output = 'CraftItem "Stick" 4',
350         recipe = {
351                 {'NodeItem "wood"'},
352         }
353 })
354
355 minetest.register_craft({
356         output = 'NodeItem "wooden_fence" 2',
357         recipe = {
358                 {'CraftItem "Stick"', 'CraftItem "Stick"', 'CraftItem "Stick"'},
359                 {'CraftItem "Stick"', 'CraftItem "Stick"', 'CraftItem "Stick"'},
360         }
361 })
362
363 minetest.register_craft({
364         output = 'NodeItem "sign_wall" 1',
365         recipe = {
366                 {'NodeItem "wood"', 'NodeItem "wood"', 'NodeItem "wood"'},
367                 {'NodeItem "wood"', 'NodeItem "wood"', 'NodeItem "wood"'},
368                 {'', 'CraftItem "Stick"', ''},
369         }
370 })
371
372 minetest.register_craft({
373         output = 'NodeItem "torch" 4',
374         recipe = {
375                 {'CraftItem "lump_of_coal"'},
376                 {'CraftItem "Stick"'},
377         }
378 })
379
380 minetest.register_craft({
381         output = 'ToolItem "WPick"',
382         recipe = {
383                 {'NodeItem "wood"', 'NodeItem "wood"', 'NodeItem "wood"'},
384                 {'', 'CraftItem "Stick"', ''},
385                 {'', 'CraftItem "Stick"', ''},
386         }
387 })
388
389 minetest.register_craft({
390         output = 'ToolItem "STPick"',
391         recipe = {
392                 {'NodeItem "cobble"', 'NodeItem "cobble"', 'NodeItem "cobble"'},
393                 {'', 'CraftItem "Stick"', ''},
394                 {'', 'CraftItem "Stick"', ''},
395         }
396 })
397
398 minetest.register_craft({
399         output = 'ToolItem "SteelPick"',
400         recipe = {
401                 {'CraftItem "steel_ingot"', 'CraftItem "steel_ingot"', 'CraftItem "steel_ingot"'},
402                 {'', 'CraftItem "Stick"', ''},
403                 {'', 'CraftItem "Stick"', ''},
404         }
405 })
406
407 minetest.register_craft({
408         output = 'ToolItem "MesePick"',
409         recipe = {
410                 {'NodeItem "mese"', 'NodeItem "mese"', 'NodeItem "mese"'},
411                 {'', 'CraftItem "Stick"', ''},
412                 {'', 'CraftItem "Stick"', ''},
413         }
414 })
415
416 minetest.register_craft({
417         output = 'ToolItem "WShovel"',
418         recipe = {
419                 {'NodeItem "wood"'},
420                 {'CraftItem "Stick"'},
421                 {'CraftItem "Stick"'},
422         }
423 })
424
425 minetest.register_craft({
426         output = 'ToolItem "STShovel"',
427         recipe = {
428                 {'NodeItem "cobble"'},
429                 {'CraftItem "Stick"'},
430                 {'CraftItem "Stick"'},
431         }
432 })
433
434 minetest.register_craft({
435         output = 'ToolItem "SteelShovel"',
436         recipe = {
437                 {'CraftItem "steel_ingot"'},
438                 {'CraftItem "Stick"'},
439                 {'CraftItem "Stick"'},
440         }
441 })
442
443 minetest.register_craft({
444         output = 'ToolItem "WAxe"',
445         recipe = {
446                 {'NodeItem "wood"', 'NodeItem "wood"'},
447                 {'NodeItem "wood"', 'CraftItem "Stick"'},
448                 {'', 'CraftItem "Stick"'},
449         }
450 })
451
452 minetest.register_craft({
453         output = 'ToolItem "STAxe"',
454         recipe = {
455                 {'NodeItem "cobble"', 'NodeItem "cobble"'},
456                 {'NodeItem "cobble"', 'CraftItem "Stick"'},
457                 {'', 'CraftItem "Stick"'},
458         }
459 })
460
461 minetest.register_craft({
462         output = 'ToolItem "SteelAxe"',
463         recipe = {
464                 {'CraftItem "steel_ingot"', 'CraftItem "steel_ingot"'},
465                 {'CraftItem "steel_ingot"', 'CraftItem "Stick"'},
466                 {'', 'CraftItem "Stick"'},
467         }
468 })
469
470 minetest.register_craft({
471         output = 'ToolItem "WSword"',
472         recipe = {
473                 {'NodeItem "wood"'},
474                 {'NodeItem "wood"'},
475                 {'CraftItem "Stick"'},
476         }
477 })
478
479 minetest.register_craft({
480         output = 'ToolItem "STSword"',
481         recipe = {
482                 {'NodeItem "cobble"'},
483                 {'NodeItem "cobble"'},
484                 {'CraftItem "Stick"'},
485         }
486 })
487
488 minetest.register_craft({
489         output = 'ToolItem "SteelSword"',
490         recipe = {
491                 {'CraftItem "steel_ingot"'},
492                 {'CraftItem "steel_ingot"'},
493                 {'CraftItem "Stick"'},
494         }
495 })
496
497 minetest.register_craft({
498         output = 'NodeItem "rail" 15',
499         recipe = {
500                 {'CraftItem "steel_ingot"', '', 'CraftItem "steel_ingot"'},
501                 {'CraftItem "steel_ingot"', 'CraftItem "Stick"', 'CraftItem "steel_ingot"'},
502                 {'CraftItem "steel_ingot"', '', 'CraftItem "steel_ingot"'},
503         }
504 })
505
506 minetest.register_craft({
507         output = 'NodeItem "chest" 1',
508         recipe = {
509                 {'NodeItem "wood"', 'NodeItem "wood"', 'NodeItem "wood"'},
510                 {'NodeItem "wood"', '', 'NodeItem "wood"'},
511                 {'NodeItem "wood"', 'NodeItem "wood"', 'NodeItem "wood"'},
512         }
513 })
514
515 minetest.register_craft({
516         output = 'NodeItem "locked_chest" 1',
517         recipe = {
518                 {'NodeItem "wood"', 'NodeItem "wood"', 'NodeItem "wood"'},
519                 {'NodeItem "wood"', 'CraftItem "steel_ingot"', 'NodeItem "wood"'},
520                 {'NodeItem "wood"', 'NodeItem "wood"', 'NodeItem "wood"'},
521         }
522 })
523
524 minetest.register_craft({
525         output = 'NodeItem "furnace" 1',
526         recipe = {
527                 {'NodeItem "cobble"', 'NodeItem "cobble"', 'NodeItem "cobble"'},
528                 {'NodeItem "cobble"', '', 'NodeItem "cobble"'},
529                 {'NodeItem "cobble"', 'NodeItem "cobble"', 'NodeItem "cobble"'},
530         }
531 })
532
533 minetest.register_craft({
534         output = 'NodeItem "steelblock" 1',
535         recipe = {
536                 {'CraftItem "steel_ingot"', 'CraftItem "steel_ingot"', 'CraftItem "steel_ingot"'},
537                 {'CraftItem "steel_ingot"', 'CraftItem "steel_ingot"', 'CraftItem "steel_ingot"'},
538                 {'CraftItem "steel_ingot"', 'CraftItem "steel_ingot"', 'CraftItem "steel_ingot"'},
539         }
540 })
541
542 minetest.register_craft({
543         output = 'NodeItem "sandstone" 1',
544         recipe = {
545                 {'NodeItem "sand"', 'NodeItem "sand"'},
546                 {'NodeItem "sand"', 'NodeItem "sand"'},
547         }
548 })
549
550 minetest.register_craft({
551         output = 'NodeItem "clay" 1',
552         recipe = {
553                 {'CraftItem "lump_of_clay"', 'CraftItem "lump_of_clay"'},
554                 {'CraftItem "lump_of_clay"', 'CraftItem "lump_of_clay"'},
555         }
556 })
557
558 minetest.register_craft({
559         output = 'NodeItem "brick" 1',
560         recipe = {
561                 {'CraftItem "clay_brick"', 'CraftItem "clay_brick"'},
562                 {'CraftItem "clay_brick"', 'CraftItem "clay_brick"'},
563         }
564 })
565
566 minetest.register_craft({
567         output = 'CraftItem "paper" 1',
568         recipe = {
569                 {'NodeItem "papyrus"', 'NodeItem "papyrus"', 'NodeItem "papyrus"'},
570         }
571 })
572
573 minetest.register_craft({
574         output = 'CraftItem "book" 1',
575         recipe = {
576                 {'CraftItem "paper"'},
577                 {'CraftItem "paper"'},
578                 {'CraftItem "paper"'},
579         }
580 })
581
582 minetest.register_craft({
583         output = 'NodeItem "bookshelf" 1',
584         recipe = {
585                 {'NodeItem "wood"', 'NodeItem "wood"', 'NodeItem "wood"'},
586                 {'CraftItem "book"', 'CraftItem "book"', 'CraftItem "book"'},
587                 {'NodeItem "wood"', 'NodeItem "wood"', 'NodeItem "wood"'},
588         }
589 })
590
591 minetest.register_craft({
592         output = 'NodeItem "ladder" 1',
593         recipe = {
594                 {'CraftItem "Stick"', '', 'CraftItem "Stick"'},
595                 {'CraftItem "Stick"', 'CraftItem "Stick"', 'CraftItem "Stick"'},
596                 {'CraftItem "Stick"', '', 'CraftItem "Stick"'},
597         }
598 })
599
600 minetest.register_craft({
601         output = 'CraftItem "apple_iron" 1',
602         recipe = {
603                 {'', 'CraftItem "steel_ingot"', ''},
604                 {'CraftItem "steel_ingot"', 'CraftItem "apple"', 'CraftItem "steel_ingot"'},
605                 {'', 'CraftItem "steel_ingot"', ''},
606         }
607 })
608
609 minetest.register_craft({
610         output = 'NodeItem "TNT" 4',
611         recipe = {
612                 {'NodeItem "wood" 1'},
613                 {'CraftItem "lump_of_coal" 1'},
614                 {'NodeItem "wood" 1'}
615         }
616 })
617
618 minetest.register_craft({
619         output = 'NodeItem "somenode" 4',
620         recipe = {
621                 {'CraftItem "Stick" 1'},
622         }
623 })
624
625 --
626 -- Node definitions
627 --
628
629 minetest.register_node("somenode", {
630         tile_images = {"lava.png", "mese.png", "stone.png", "grass.png", "cobble.png", "tree_top.png"},
631         inventory_image = "treeprop.png",
632         material = {
633                 diggability = "normal",
634                 weight = 0,
635                 crackiness = 0,
636                 crumbliness = 0,
637                 cuttability = 0,
638                 flammability = 0
639         },
640         metadata_name = "chest",
641 })
642
643 minetest.register_node("TNT", {
644         tile_images = {"tnt_top.png", "tnt_bottom.png", "tnt_side.png", "tnt_side.png", "tnt_side.png", "tnt_side.png"},
645         inventory_image = "tnt_side.png",
646         dug_item = '', -- Get nothing
647         material = {
648                 diggability = "not",
649         },
650 })
651
652 --
653 -- Some common functions
654 --
655
656 function nodeupdate_single(p)
657         n = minetest.env:get_node(p)
658         if n.name == "sand" or n.name == "gravel" then
659                 p_bottom = {x=p.x, y=p.y-1, z=p.z}
660                 n_bottom = minetest.env:get_node(p_bottom)
661                 if n_bottom.name == "air" then
662                         minetest.env:remove_node(p)
663                         minetest.env:add_luaentity(p, "falling_"..n.name)
664                         nodeupdate(p)
665                 end
666         end
667 end
668
669 function nodeupdate(p)
670         for x = -1,1 do
671         for y = -1,1 do
672         for z = -1,1 do
673                 p2 = {x=p.x+x, y=p.y+y, z=p.z+z}
674                 nodeupdate_single(p2)
675         end
676         end
677         end
678 end
679
680 --
681 -- TNT (not functional)
682 --
683
684 local TNT = {
685         -- Static definition
686         physical = true, -- Collides with things
687         -- weight = 5,
688         collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
689         visual = "cube",
690         textures = {"tnt_top.png","tnt_bottom.png","tnt_side.png","tnt_side.png","tnt_side.png","tnt_side.png"},
691         --visual = "single_sprite",
692         --textures = {"mese.png^[forcesingle"},
693         -- Initial value for our timer
694         timer = 0,
695         -- Number of punches required to defuse
696         health = 1,
697 }
698
699 -- Called when a TNT object is created
700 function TNT:on_activate(staticdata)
701         print("TNT:on_activate()")
702         self.object:setvelocity({x=0, y=2, z=0})
703         self.object:setacceleration({x=0, y=-10, z=0})
704 end
705
706 -- Called periodically
707 function TNT:on_step(dtime)
708         --print("TNT:on_step()")
709 end
710
711 -- Called when object is punched
712 function TNT:on_punch(hitter)
713         print("TNT:on_punch()")
714         self.health = self.health - 1
715         if self.health <= 0 then
716                 self.object:remove()
717                 hitter:add_to_inventory("NodeItem TNT 1")
718         end
719 end
720
721 -- Called when object is right-clicked
722 function TNT:on_rightclick(clicker)
723         --pos = self.object:getpos()
724         --pos = {x=pos.x, y=pos.y+0.1, z=pos.z}
725         --self.object:moveto(pos, false)
726 end
727
728 print("TNT dump: "..dump(TNT))
729
730 print("Registering TNT");
731 minetest.register_entity("TNT", TNT)
732
733 --
734 -- Falling stuff
735 --
736
737 function register_falling_node(nodename, texture)
738         minetest.register_entity("falling_"..nodename, {
739                 -- Static definition
740                 physical = true,
741                 collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
742                 visual = "cube",
743                 textures = {texture,texture,texture,texture,texture,texture},
744                 -- State
745                 -- Methods
746                 on_step = function(self, dtime)
747                         -- Set gravity
748                         self.object:setacceleration({x=0, y=-10, z=0})
749                         -- Turn to actual sand when collides to ground or just move
750                         local pos = self.object:getpos()
751                         local bcp = {x=pos.x, y=pos.y-0.7, z=pos.z} -- Position of bottom center point
752                         local bcn = minetest.env:get_node(bcp)
753                         if bcn.name ~= "air" then
754                                 -- Turn to a sand node
755                                 local np = {x=bcp.x, y=bcp.y+1, z=bcp.z}
756                                 minetest.env:add_node(np, {name=nodename})
757                                 self.object:remove()
758                         else
759                                 -- Do nothing
760                         end
761                 end
762         })
763 end
764
765 register_falling_node("sand", "sand.png")
766 register_falling_node("gravel", "gravel.png")
767
768 --[[
769 minetest.register_entity("falling_sand", {
770         -- Definition
771         collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
772         visual = "cube",
773         textures = {"sand.png","sand.png","sand.png","sand.png","sand.png","sand.png"},
774         -- State
775         fallspeed = 0,
776         -- Methods
777         on_step = function(self, dtime)
778                 -- Apply gravity
779                 self.fallspeed = self.fallspeed + dtime * 5
780                 fp = self.object:getpos()
781                 fp.y = fp.y - self.fallspeed * dtime
782                 self.object:moveto(fp)
783                 -- Turn to actual sand when collides to ground or just move
784                 bcp = {x=fp.x, y=fp.y-0.5, z=fp.z} -- Position of bottom center point
785                 bcn = minetest.env:get_node(bcp)
786                 if bcn.name ~= "air" then
787                         -- Turn to a sand node
788                         np = {x=bcp.x, y=bcp.y+1, z=bcp.z}
789                         minetest.env:add_node(np, {name="sand"})
790                         self.object:remove()
791                 else
792                         -- Do nothing
793                 end
794         end
795 })
796 --]]
797
798 --
799 -- Global callbacks
800 --
801
802 -- Global environment step function
803 function on_step(dtime)
804         -- print("on_step")
805 end
806 minetest.register_globalstep(on_step)
807
808 function on_placenode(p, node)
809         print("on_placenode")
810         nodeupdate(p)
811 end
812 minetest.register_on_placenode(on_placenode)
813
814 function on_dignode(p, node)
815         print("on_dignode")
816         nodeupdate(p)
817 end
818 minetest.register_on_dignode(on_dignode)
819
820 function on_punchnode(p, node)
821         print("on_punchnode")
822         if node.name == "TNT" then
823                 minetest.env:remove_node(p)
824                 minetest.env:add_luaentity(p, "TNT")
825                 nodeupdate(p)
826         end
827 end
828 minetest.register_on_punchnode(on_punchnode)
829
830 --
831 -- Done, print some random stuff
832 --
833
834 print("minetest.registered_entities:")
835 dump2(minetest.registered_entities)
836
837 --
838 -- Some random pre-implementation planning and drafting
839 --
840
841 --[[
842 function TNT:on_rightclick(clicker)
843         print("TNT:on_rightclick()")
844         print("self: "..dump(self))
845         print("getmetatable(self): "..dump(getmetatable(self)))
846         print("getmetatable(getmetatable(self)): "..dump(getmetatable(getmetatable(self))))
847         pos = self.object:getpos()
848         print("TNT:on_rightclick(): object position: "..dump(pos))
849         pos = {x=pos.x+0.5+1, y=pos.y+0.5, z=pos.z+0.5}
850         --minetest.env:add_node(pos, {name="stone")
851 end
852 --]]
853
854 --[=[
855
856 register_block(0, {
857         textures = "stone.png",
858         makefacetype = 0,
859         get_dig_duration = function(env, pos, digger)
860                 -- Check stuff like digger.current_tool
861                 return 1.5
862         end,
863         on_dig = function(env, pos, digger)
864                 env:remove_node(pos)
865                 digger.inventory.put("MaterialItem2 0");
866         end,
867 })
868
869 register_block(1, {
870         textures = {"grass.png","mud.png","mud_grass_side.png","mud_grass_side.png","mud_grass_side.png","mud_grass_side.png"},
871         makefacetype = 0,
872         get_dig_duration = function(env, pos, digger)
873                 -- Check stuff like digger.current_tool
874                 return 0.5
875         end,
876         on_dig = function(env, pos, digger)
877                 env:remove_node(pos)
878                 digger.inventory.put("MaterialItem2 1");
879         end,
880 })
881
882 -- Consider the "miscellaneous block namespace" to be 0xc00...0xfff = 3072...4095
883 register_block(3072, {
884         textures = {"tnt_top.png","tnt_bottom.png","tnt_side.png","tnt_side.png","tnt_side.png","tnt_side.png"},
885         makefacetype = 0,
886         get_dig_duration = function(env, pos, digger)
887                 -- Cannot be dug
888                 return nil
889         end,
890         -- on_dig = function(env, pos, digger) end, -- Not implemented
891         on_hit = function(env, pos, hitter)
892                 -- Replace with TNT object, which will explode after timer, follow gravity, blink and stuff
893                 env:add_object("tnt", pos)
894                 env:remove_node(pos)
895         end,
896 })
897 --]=]
898