]> git.lizzy.rs Git - dragonfireclient.git/blob - data/mods/default/init.lua
afd22d6bbd3eb7ba907f00951e62a93d662b25c4
[dragonfireclient.git] / data / mods / default / init.lua
1 -- Helper functions defined by builtin.lua:
2 -- dump2(obj, name="_", dumped={})
3 -- dump(obj, dumped={})
4 --
5 -- Textures:
6 -- Mods should prefix their textures with modname_, eg. given the mod
7 -- name "foomod", a texture could be called "foomod_superfurnace.png"
8 -- Due to historical reasons, the default mod does not follow this rule.
9 --
10 -- MapNode representation:
11 -- {name="name", param1=num, param2=num}
12 --
13 -- Position representation:
14 -- {x=num, y=num, z=num}
15 --
16 -- stackstring/itemstring: A stack of items in serialized format.
17 -- eg. 'node "dirt" 5'
18 -- eg. 'tool "WPick" 21323'
19 -- eg. 'craft "apple" 2'
20 --
21 -- item: A single item in Lua table format.
22 -- eg. {type="node", name="dirt"} 
23 --     ^ a single dirt node
24 -- eg. {type="tool", name="WPick", wear=21323}
25 --     ^ a wooden pick about 1/3 weared out
26 -- eg. {type="craft", name="apple"}
27 --     ^ an apple.
28 --
29 -- Global functions:
30 -- minetest.register_entity(name, prototype table)
31 -- minetest.register_tool(name, tool definition)
32 -- minetest.register_node(name, node definition)
33 -- minetest.register_craftitem(name, craftitem definition)
34 -- minetest.register_craft(recipe)
35 -- minetest.register_globalstep(func(dtime))
36 -- minetest.register_on_placenode(func(pos, newnode, placer))
37 -- minetest.register_on_dignode(func(pos, oldnode, digger))
38 -- minetest.register_on_punchnode(func(pos, node, puncher))
39 -- minetest.register_on_generated(func(minp, maxp))
40 -- minetest.register_on_newplayer(func(ObjectRef))
41 -- minetest.register_on_respawnplayer(func(ObjectRef))
42 -- ^ return true in func to disable regular player placement
43 -- minetest.register_on_chat_message(func(name, message))
44 -- minetest.add_to_creative_inventory(itemstring)
45 -- minetest.setting_get(name) -> string or nil
46 -- minetest.setting_getbool(name) -> boolean value or nil
47 -- minetest.chat_send_all(text)
48 -- minetest.chat_send_player(name, text)
49 -- minetest.get_player_privs(name) -> set of privs
50 -- stackstring_take_item(stackstring) -> stackstring, item
51 -- stackstring_put_item(stackstring, item) -> stackstring, success
52 -- stackstring_put_stackstring(stackstring, stackstring) -> stackstring, success
53 --
54 -- Global objects:
55 -- minetest.env - environment reference
56 --
57 -- Global tables:
58 -- minetest.registered_nodes
59 -- ^ List of registered node definitions, indexed by name
60 -- minetest.registered_craftitems
61 -- ^ List of registered craft item definitions, indexed by name
62 -- minetest.registered_entities
63 -- ^ List of registered entity prototypes, indexed by name
64 -- minetest.object_refs
65 -- ^ List of object references, indexed by active object id
66 -- minetest.luaentities
67 -- ^ List of lua entities, indexed by active object id
68 --
69 -- EnvRef is basically ServerEnvironment and ServerMap combined.
70 -- EnvRef methods:
71 -- - add_node(pos, node)
72 -- - remove_node(pos)
73 -- - get_node(pos)
74 -- - add_luaentity(pos, name)
75 -- - add_item(pos, itemstring)
76 -- - add_rat(pos)
77 -- - add_firefly(pos)
78 -- - get_meta(pos) -- Get a NodeMetaRef at that position
79 -- - get_player_by_name(name) -- Get an ObjectRef to a player
80 --
81 -- NodeMetaRef
82 -- - get_type()
83 -- - allows_text_input()
84 -- - set_text(text) -- eg. set the text of a sign
85 -- - get_text()
86 -- - get_owner()
87 -- Generic node metadata specific:
88 -- - set_infotext(infotext)
89 -- - inventory_set_list(name, {item1, item2, ...})
90 -- - inventory_get_list(name)
91 -- - set_inventory_draw_spec(string)
92 -- - set_allow_text_input(bool)
93 -- - set_allow_removal(bool)
94 -- - set_enforce_owner(bool)
95 -- - is_inventory_modified()
96 -- - reset_inventory_modified()
97 -- - is_text_modified()
98 -- - reset_text_modified()
99 -- - set_string(name, value)
100 -- - get_string(name)
101 --
102 -- ObjectRef is basically ServerActiveObject.
103 -- ObjectRef methods:
104 -- - remove(): remove object (after returning from Lua)
105 -- - getpos() -> {x=num, y=num, z=num}
106 -- - setpos(pos); pos={x=num, y=num, z=num}
107 -- - moveto(pos, continuous=false): interpolated move
108 -- - punch(puncher, time_from_last_punch)
109 --   ^ puncher = an another ObjectRef,
110 --   ^ time_from_last_punch = time since last punch action of the puncher
111 -- - right_click(clicker); clicker = an another ObjectRef
112 -- - get_wield_digging_properties() -> digging property table
113 -- - add_to_inventory_later(itemstring): like above, but after callback returns (only allowed for craftitem callbacks)
114 -- - get_hp(): returns number of hitpoints (2 * number of hearts)
115 -- - set_hp(hp): set number of hitpoints (2 * number of hearts)
116 -- LuaEntitySAO-only:
117 -- - setvelocity({x=num, y=num, z=num})
118 -- - setacceleration({x=num, y=num, z=num})
119 -- - getacceleration() -> {x=num, y=num, z=num}
120 -- - settexturemod(mod)
121 -- - setsprite(p={x=0,y=0}, num_frames=1, framelength=0.2,
122 -- -           select_horiz_by_yawpitch=false)
123 -- Player-only:
124 -- - get_player_name(): will return nil if is not a player
125 -- - inventory_set_list(name, {item1, item2, ...})
126 -- - inventory_get_list(name) -> {item1, item2, ...}
127 -- - damage_wielded_item(num) (item damage/wear range is 0-65535)
128 -- - add_to_inventory(itemstring): add an item to object inventory
129 --
130 -- Registered entities:
131 -- - Functions receive a "luaentity" as self:
132 --   - It has the member .object, which is an ObjectRef pointing to the object
133 --   - The original prototype stuff is visible directly via a metatable
134 -- - Callbacks:
135 --   - on_activate(self, staticdata)
136 --   - on_step(self, dtime)
137 --   - on_punch(self, hitter)
138 --   - on_rightclick(self, clicker)
139 --   - get_staticdata(self)
140 --     ^ return string that will be passed to on_activate when the object
141 --       is created next time
142 --
143 -- Entity prototype table:
144 -- {
145 --     physical = true,
146 --     collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
147 --     visual = "cube",
148 --     textures = {texture,texture,texture,texture,texture,texture},
149 --     on_activate = function(self, staticdata),
150 --     on_step = function(self, dtime),
151 --     on_punch = function(self, hitter),
152 --     on_rightclick = function(self, clicker),
153 --     get_staticdata = function(self),
154 --     # Also you can define arbitrary member variables here
155 --     myvariable = whatever,
156 -- }
157 --
158 -- Tool definition:
159 -- {
160 --     image = "tool_steelaxe.png",
161 --     full_punch_interval = 1.0,
162 --     basetime = 1.0,
163 --     dt_weight = 0.5,
164 --     dt_crackiness = -0.2,
165 --     dt_crumbliness = 1,
166 --     dt_cuttability = -0.5,
167 --     basedurability = 330,
168 --     dd_weight = 0,
169 --     dd_crackiness = 0,
170 --     dd_crumbliness = 0,
171 --     dd_cuttability = 0,
172 -- }
173 --
174 -- Node definition options:
175 -- {
176 --     name = "somenode",
177 --     drawtype = "normal",
178 --     visual_scale = 1.0,
179 --     tile_images = {"unknown_block.png"},
180 --     inventory_image = "unknown_block.png",
181 --     special_materials = {
182 --         {image="", backface_culling=true},
183 --         {image="", backface_culling=true},
184 --     },
185 --     alpha = 255,
186 --     post_effect_color = {a=0, r=0, g=0, b=0},
187 --     paramtype = "none",
188 --     is_ground_content = false,
189 --     light_propagates = false,
190 --     sunlight_propagates = false,
191 --     walkable = true,
192 --     pointable = true,
193 --     diggable = true,
194 --     climbable = false,
195 --     buildable_to = false,
196 --     wall_mounted = false,
197 --     often_contains_mineral = false,
198 --     dug_item = "",
199 --     extra_dug_item = "",
200 --     extra_dug_item_rarity = 2,
201 --     metadata_name = "",
202 --     liquidtype = "none",
203 --     liquid_alternative_flowing = "",
204 --     liquid_alternative_source = "",
205 --     liquid_viscosity = 0,
206 --     light_source = 0,
207 --     damage_per_second = 0,
208 --     selection_box = {type="regular"},
209 --     material = {
210 --         diggablity = "normal",
211 --         weight = 0,
212 --         crackiness = 0,
213 --         crumbliness = 0,
214 --         cuttability = 0,
215 --         flammability = 0,
216 --     },
217 --     cookresult_item = "", -- Cannot be cooked
218 --     furnace_cooktime = 3.0,
219 --     furnace_burntime = -1, -- Cannot be used as fuel
220 -- }
221 --
222 -- Craftitem definition options:
223 -- minetest.register_craftitem("name", {
224 --     image = "image.png",
225 --     stack_max = <maximum number of items in stack>,
226 --     cookresult_item = itemstring (result of cooking),
227 --     furnace_cooktime = <cooking time>,
228 --     furnace_burntime = <time to burn as fuel in furnace>,
229 --     usable = <uh... some boolean value>,
230 --     dropcount = <amount of items to drop using drop action>
231 --     liquids_pointable = <whether can point liquids>,
232 --     on_drop = func(item, dropper, pos),
233 --     on_place_on_ground = func(item, placer, pos),
234 --     on_use = func(item, player, pointed_thing),
235 -- })
236 -- 
237 -- Recipe:
238 -- {
239 --     output = 'tool "STPick"',
240 --     recipe = {
241 --         {'node "cobble"', 'node "cobble"', 'node "cobble"'},
242 --         {'', 'craft "Stick"', ''},
243 --         {'', 'craft "Stick"', ''},
244 --     }
245 -- }
246 --
247
248 -- print("minetest dump: "..dump(minetest))
249
250 WATER_ALPHA = 160
251 WATER_VISC = 1
252 LAVA_VISC = 7
253 LIGHT_MAX = 14
254
255 --
256 -- Tool definition
257 --
258
259 minetest.register_tool("WPick", {
260         image = "tool_woodpick.png",
261         basetime = 2.0,
262         dt_weight = 0,
263         dt_crackiness = -0.5,
264         dt_crumbliness = 2,
265         dt_cuttability = 0,
266         basedurability = 30,
267         dd_weight = 0,
268         dd_crackiness = 0,
269         dd_crumbliness = 0,
270         dd_cuttability = 0,
271 })
272 minetest.register_tool("STPick", {
273         image = "tool_stonepick.png",
274         basetime = 1.5,
275         dt_weight = 0,
276         dt_crackiness = -0.5,
277         dt_crumbliness = 2,
278         dt_cuttability = 0,
279         basedurability = 100,
280         dd_weight = 0,
281         dd_crackiness = 0,
282         dd_crumbliness = 0,
283         dd_cuttability = 0,
284 })
285 minetest.register_tool("SteelPick", {
286         image = "tool_steelpick.png",
287         basetime = 1.0,
288         dt_weight = 0,
289         dt_crackiness = -0.5,
290         dt_crumbliness = 2,
291         dt_cuttability = 0,
292         basedurability = 333,
293         dd_weight = 0,
294         dd_crackiness = 0,
295         dd_crumbliness = 0,
296         dd_cuttability = 0,
297 })
298 minetest.register_tool("MesePick", {
299         image = "tool_mesepick.png",
300         basetime = 0,
301         dt_weight = 0,
302         dt_crackiness = 0,
303         dt_crumbliness = 0,
304         dt_cuttability = 0,
305         basedurability = 1337,
306         dd_weight = 0,
307         dd_crackiness = 0,
308         dd_crumbliness = 0,
309         dd_cuttability = 0,
310 })
311 minetest.register_tool("WShovel", {
312         image = "tool_woodshovel.png",
313         basetime = 2.0,
314         dt_weight = 0.5,
315         dt_crackiness = 2,
316         dt_crumbliness = -1.5,
317         dt_cuttability = 0.3,
318         basedurability = 30,
319         dd_weight = 0,
320         dd_crackiness = 0,
321         dd_crumbliness = 0,
322         dd_cuttability = 0,
323 })
324 minetest.register_tool("STShovel", {
325         image = "tool_stoneshovel.png",
326         basetime = 1.5,
327         dt_weight = 0.5,
328         dt_crackiness = 2,
329         dt_crumbliness = -1.5,
330         dt_cuttability = 0.1,
331         basedurability = 100,
332         dd_weight = 0,
333         dd_crackiness = 0,
334         dd_crumbliness = 0,
335         dd_cuttability = 0,
336 })
337 minetest.register_tool("SteelShovel", {
338         image = "tool_steelshovel.png",
339         basetime = 1.0,
340         dt_weight = 0.5,
341         dt_crackiness = 2,
342         dt_crumbliness = -1.5,
343         dt_cuttability = 0.0,
344         basedurability = 330,
345         dd_weight = 0,
346         dd_crackiness = 0,
347         dd_crumbliness = 0,
348         dd_cuttability = 0,
349 })
350 minetest.register_tool("WAxe", {
351         image = "tool_woodaxe.png",
352         basetime = 2.0,
353         dt_weight = 0.5,
354         dt_crackiness = -0.2,
355         dt_crumbliness = 1,
356         dt_cuttability = -0.5,
357         basedurability = 30,
358         dd_weight = 0,
359         dd_crackiness = 0,
360         dd_crumbliness = 0,
361         dd_cuttability = 0,
362 })
363 minetest.register_tool("STAxe", {
364         image = "tool_stoneaxe.png",
365         basetime = 1.5,
366         dt_weight = 0.5,
367         dt_crackiness = -0.2,
368         dt_crumbliness = 1,
369         dt_cuttability = -0.5,
370         basedurability = 100,
371         dd_weight = 0,
372         dd_crackiness = 0,
373         dd_crumbliness = 0,
374         dd_cuttability = 0,
375 })
376 minetest.register_tool("SteelAxe", {
377         image = "tool_steelaxe.png",
378         basetime = 1.0,
379         dt_weight = 0.5,
380         dt_crackiness = -0.2,
381         dt_crumbliness = 1,
382         dt_cuttability = -0.5,
383         basedurability = 330,
384         dd_weight = 0,
385         dd_crackiness = 0,
386         dd_crumbliness = 0,
387         dd_cuttability = 0,
388 })
389 minetest.register_tool("WSword", {
390         image = "tool_woodsword.png",
391         basetime = 3.0,
392         dt_weight = 3,
393         dt_crackiness = 0,
394         dt_crumbliness = 1,
395         dt_cuttability = -1,
396         basedurability = 30,
397         dd_weight = 0,
398         dd_crackiness = 0,
399         dd_crumbliness = 0,
400         dd_cuttability = 0,
401 })
402 minetest.register_tool("STSword", {
403         image = "tool_stonesword.png",
404         basetime = 2.5,
405         dt_weight = 3,
406         dt_crackiness = 0,
407         dt_crumbliness = 1,
408         dt_cuttability = -1,
409         basedurability = 100,
410         dd_weight = 0,
411         dd_crackiness = 0,
412         dd_crumbliness = 0,
413         dd_cuttability = 0,
414 })
415 minetest.register_tool("SteelSword", {
416         image = "tool_steelsword.png",
417         basetime = 2.0,
418         dt_weight = 3,
419         dt_crackiness = 0,
420         dt_crumbliness = 1,
421         dt_cuttability = -1,
422         basedurability = 330,
423         dd_weight = 0,
424         dd_crackiness = 0,
425         dd_crumbliness = 0,
426         dd_cuttability = 0,
427 })
428 -- The hand
429 minetest.register_tool("", {
430         image = "",
431         basetime = 0.5,
432         dt_weight = 1,
433         dt_crackiness = 0,
434         dt_crumbliness = -1,
435         dt_cuttability = 0,
436         basedurability = 50,
437         dd_weight = 0,
438         dd_crackiness = 0,
439         dd_crumbliness = 0,
440         dd_cuttability = 0,
441 })
442
443 --
444 -- Crafting definition
445 --
446
447 minetest.register_craft({
448         output = 'node "wood" 4',
449         recipe = {
450                 {'node "tree"'},
451         }
452 })
453
454 minetest.register_craft({
455         output = 'craft "Stick" 4',
456         recipe = {
457                 {'node "wood"'},
458         }
459 })
460
461 minetest.register_craft({
462         output = 'node "wooden_fence" 2',
463         recipe = {
464                 {'craft "Stick"', 'craft "Stick"', 'craft "Stick"'},
465                 {'craft "Stick"', 'craft "Stick"', 'craft "Stick"'},
466         }
467 })
468
469 minetest.register_craft({
470         output = 'node "sign_wall" 1',
471         recipe = {
472                 {'node "wood"', 'node "wood"', 'node "wood"'},
473                 {'node "wood"', 'node "wood"', 'node "wood"'},
474                 {'', 'craft "Stick"', ''},
475         }
476 })
477
478 minetest.register_craft({
479         output = 'node "torch" 4',
480         recipe = {
481                 {'craft "lump_of_coal"'},
482                 {'craft "Stick"'},
483         }
484 })
485
486 minetest.register_craft({
487         output = 'tool "WPick"',
488         recipe = {
489                 {'node "wood"', 'node "wood"', 'node "wood"'},
490                 {'', 'craft "Stick"', ''},
491                 {'', 'craft "Stick"', ''},
492         }
493 })
494
495 minetest.register_craft({
496         output = 'tool "STPick"',
497         recipe = {
498                 {'node "cobble"', 'node "cobble"', 'node "cobble"'},
499                 {'', 'craft "Stick"', ''},
500                 {'', 'craft "Stick"', ''},
501         }
502 })
503
504 minetest.register_craft({
505         output = 'tool "SteelPick"',
506         recipe = {
507                 {'craft "steel_ingot"', 'craft "steel_ingot"', 'craft "steel_ingot"'},
508                 {'', 'craft "Stick"', ''},
509                 {'', 'craft "Stick"', ''},
510         }
511 })
512
513 minetest.register_craft({
514         output = 'tool "MesePick"',
515         recipe = {
516                 {'node "mese"', 'node "mese"', 'node "mese"'},
517                 {'', 'craft "Stick"', ''},
518                 {'', 'craft "Stick"', ''},
519         }
520 })
521
522 minetest.register_craft({
523         output = 'tool "WShovel"',
524         recipe = {
525                 {'node "wood"'},
526                 {'craft "Stick"'},
527                 {'craft "Stick"'},
528         }
529 })
530
531 minetest.register_craft({
532         output = 'tool "STShovel"',
533         recipe = {
534                 {'node "cobble"'},
535                 {'craft "Stick"'},
536                 {'craft "Stick"'},
537         }
538 })
539
540 minetest.register_craft({
541         output = 'tool "SteelShovel"',
542         recipe = {
543                 {'craft "steel_ingot"'},
544                 {'craft "Stick"'},
545                 {'craft "Stick"'},
546         }
547 })
548
549 minetest.register_craft({
550         output = 'tool "WAxe"',
551         recipe = {
552                 {'node "wood"', 'node "wood"'},
553                 {'node "wood"', 'craft "Stick"'},
554                 {'', 'craft "Stick"'},
555         }
556 })
557
558 minetest.register_craft({
559         output = 'tool "STAxe"',
560         recipe = {
561                 {'node "cobble"', 'node "cobble"'},
562                 {'node "cobble"', 'craft "Stick"'},
563                 {'', 'craft "Stick"'},
564         }
565 })
566
567 minetest.register_craft({
568         output = 'tool "SteelAxe"',
569         recipe = {
570                 {'craft "steel_ingot"', 'craft "steel_ingot"'},
571                 {'craft "steel_ingot"', 'craft "Stick"'},
572                 {'', 'craft "Stick"'},
573         }
574 })
575
576 minetest.register_craft({
577         output = 'tool "WSword"',
578         recipe = {
579                 {'node "wood"'},
580                 {'node "wood"'},
581                 {'craft "Stick"'},
582         }
583 })
584
585 minetest.register_craft({
586         output = 'tool "STSword"',
587         recipe = {
588                 {'node "cobble"'},
589                 {'node "cobble"'},
590                 {'craft "Stick"'},
591         }
592 })
593
594 minetest.register_craft({
595         output = 'tool "SteelSword"',
596         recipe = {
597                 {'craft "steel_ingot"'},
598                 {'craft "steel_ingot"'},
599                 {'craft "Stick"'},
600         }
601 })
602
603 minetest.register_craft({
604         output = 'node "rail" 15',
605         recipe = {
606                 {'craft "steel_ingot"', '', 'craft "steel_ingot"'},
607                 {'craft "steel_ingot"', 'craft "Stick"', 'craft "steel_ingot"'},
608                 {'craft "steel_ingot"', '', 'craft "steel_ingot"'},
609         }
610 })
611
612 minetest.register_craft({
613         output = 'node "chest" 1',
614         recipe = {
615                 {'node "wood"', 'node "wood"', 'node "wood"'},
616                 {'node "wood"', '', 'node "wood"'},
617                 {'node "wood"', 'node "wood"', 'node "wood"'},
618         }
619 })
620
621 minetest.register_craft({
622         output = 'node "locked_chest" 1',
623         recipe = {
624                 {'node "wood"', 'node "wood"', 'node "wood"'},
625                 {'node "wood"', 'craft "steel_ingot"', 'node "wood"'},
626                 {'node "wood"', 'node "wood"', 'node "wood"'},
627         }
628 })
629
630 minetest.register_craft({
631         output = 'node "furnace" 1',
632         recipe = {
633                 {'node "cobble"', 'node "cobble"', 'node "cobble"'},
634                 {'node "cobble"', '', 'node "cobble"'},
635                 {'node "cobble"', 'node "cobble"', 'node "cobble"'},
636         }
637 })
638
639 minetest.register_craft({
640         output = 'node "steelblock" 1',
641         recipe = {
642                 {'craft "steel_ingot"', 'craft "steel_ingot"', 'craft "steel_ingot"'},
643                 {'craft "steel_ingot"', 'craft "steel_ingot"', 'craft "steel_ingot"'},
644                 {'craft "steel_ingot"', 'craft "steel_ingot"', 'craft "steel_ingot"'},
645         }
646 })
647
648 minetest.register_craft({
649         output = 'node "sandstone" 1',
650         recipe = {
651                 {'node "sand"', 'node "sand"'},
652                 {'node "sand"', 'node "sand"'},
653         }
654 })
655
656 minetest.register_craft({
657         output = 'node "clay" 1',
658         recipe = {
659                 {'craft "lump_of_clay"', 'craft "lump_of_clay"'},
660                 {'craft "lump_of_clay"', 'craft "lump_of_clay"'},
661         }
662 })
663
664 minetest.register_craft({
665         output = 'node "brick" 1',
666         recipe = {
667                 {'craft "clay_brick"', 'craft "clay_brick"'},
668                 {'craft "clay_brick"', 'craft "clay_brick"'},
669         }
670 })
671
672 minetest.register_craft({
673         output = 'craft "paper" 1',
674         recipe = {
675                 {'node "papyrus"', 'node "papyrus"', 'node "papyrus"'},
676         }
677 })
678
679 minetest.register_craft({
680         output = 'craft "book" 1',
681         recipe = {
682                 {'craft "paper"'},
683                 {'craft "paper"'},
684                 {'craft "paper"'},
685         }
686 })
687
688 minetest.register_craft({
689         output = 'node "bookshelf" 1',
690         recipe = {
691                 {'node "wood"', 'node "wood"', 'node "wood"'},
692                 {'craft "book"', 'craft "book"', 'craft "book"'},
693                 {'node "wood"', 'node "wood"', 'node "wood"'},
694         }
695 })
696
697 minetest.register_craft({
698         output = 'node "ladder" 1',
699         recipe = {
700                 {'craft "Stick"', '', 'craft "Stick"'},
701                 {'craft "Stick"', 'craft "Stick"', 'craft "Stick"'},
702                 {'craft "Stick"', '', 'craft "Stick"'},
703         }
704 })
705
706 minetest.register_craft({
707         output = 'craft "apple_iron" 1',
708         recipe = {
709                 {'', 'craft "steel_ingot"', ''},
710                 {'craft "steel_ingot"', 'craft "apple"', 'craft "steel_ingot"'},
711                 {'', 'craft "steel_ingot"', ''},
712         }
713 })
714
715 --
716 -- Node definitions
717 --
718
719 function digprop_constanttime(time)
720         return {
721                 diggability = "constant",
722                 constant_time = time,
723         }
724 end
725
726 function digprop_stonelike(toughness)
727         return {
728                 diggablity = "normal",
729                 weight = toughness * 5,
730                 crackiness = 1,
731                 crumbliness = -0.1,
732                 cuttability = -0.2,
733         }
734 end
735
736 function digprop_dirtlike(toughness)
737         return {
738                 diggablity = "normal",
739                 weight = toughness * 1.2,
740                 crackiness = 0,
741                 crumbliness = 1.2,
742                 cuttability = -0.4,
743         }
744 end
745
746 function digprop_gravellike(toughness)
747         return {
748                 diggablity = "normal",
749                 weight = toughness * 2,
750                 crackiness = 0.2,
751                 crumbliness = 1.5,
752                 cuttability = -1.0,
753         }
754 end
755
756 function digprop_woodlike(toughness)
757         return {
758                 diggablity = "normal",
759                 weight = toughness * 1.0,
760                 crackiness = 0.75,
761                 crumbliness = -1.0,
762                 cuttability = 1.5,
763         }
764 end
765
766 function digprop_leaveslike(toughness)
767         return {
768                 diggablity = "normal",
769                 weight = toughness * (-0.5),
770                 crackiness = 0,
771                 crumbliness = 0,
772                 cuttability = 2.0,
773         }
774 end
775
776 function digprop_glasslike(toughness)
777         return {
778                 diggablity = "normal",
779                 weight = toughness * 0.1,
780                 crackiness = 2.0,
781                 crumbliness = -1.0,
782                 cuttability = -1.0,
783         }
784 end
785
786 function inventorycube(img1, img2, img3)
787         img2 = img2 or img1
788         img3 = img3 or img1
789         return "[inventorycube"
790                         .. "{" .. img1:gsub("%^", "&")
791                         .. "{" .. img2:gsub("%^", "&")
792                         .. "{" .. img3:gsub("%^", "&")
793 end
794
795 -- Legacy nodes
796
797 minetest.register_node("stone", {
798         tile_images = {"stone.png"},
799         inventory_image = inventorycube("stone.png"),
800         paramtype = "mineral",
801         is_ground_content = true,
802         often_contains_mineral = true, -- Texture atlas hint
803         material = digprop_stonelike(1.0),
804         dug_item = 'node "cobble" 1',
805 })
806
807 minetest.register_node("dirt_with_grass", {
808         tile_images = {"grass.png", "mud.png", "mud.png^grass_side.png"},
809         inventory_image = inventorycube("mud.png^grass_side.png"),
810         is_ground_content = true,
811         material = digprop_dirtlike(1.0),
812         dug_item = 'node "dirt" 1',
813 })
814
815 minetest.register_node("dirt_with_grass_footsteps", {
816         tile_images = {"grass_footsteps.png", "mud.png", "mud.png^grass_side.png"},
817         inventory_image = "grass_footsteps.png",
818         is_ground_content = true,
819         material = digprop_dirtlike(1.0),
820         dug_item = 'node "dirt" 1',
821 })
822
823 minetest.register_node("dirt", {
824         tile_images = {"mud.png"},
825         inventory_image = inventorycube("mud.png"),
826         is_ground_content = true,
827         material = digprop_dirtlike(1.0),
828 })
829
830 minetest.register_node("sand", {
831         tile_images = {"sand.png"},
832         inventory_image = inventorycube("sand.png"),
833         is_ground_content = true,
834         material = digprop_dirtlike(1.0),
835         cookresult_item = 'node "glass" 1',
836 })
837
838 minetest.register_node("gravel", {
839         tile_images = {"gravel.png"},
840         inventory_image = inventorycube("gravel.png"),
841         is_ground_content = true,
842         material = digprop_gravellike(1.0),
843 })
844
845 minetest.register_node("sandstone", {
846         tile_images = {"sandstone.png"},
847         inventory_image = inventorycube("sandstone.png"),
848         is_ground_content = true,
849         material = digprop_dirtlike(1.0),  -- FIXME should this be stonelike?
850         dug_item = 'node "sand" 1',  -- FIXME is this intentional?
851 })
852
853 minetest.register_node("clay", {
854         tile_images = {"clay.png"},
855         inventory_image = inventorycube("clay.png"),
856         is_ground_content = true,
857         material = digprop_dirtlike(1.0),
858         dug_item = 'craft "lump_of_clay" 4',
859 })
860
861 minetest.register_node("brick", {
862         tile_images = {"brick.png"},
863         inventory_image = inventorycube("brick.png"),
864         is_ground_content = true,
865         material = digprop_stonelike(1.0),
866         dug_item = 'craft "clay_brick" 4',
867 })
868
869 minetest.register_node("tree", {
870         tile_images = {"tree_top.png", "tree_top.png", "tree.png"},
871         inventory_image = inventorycube("tree_top.png", "tree.png", "tree.png"),
872         is_ground_content = true,
873         material = digprop_woodlike(1.0),
874         cookresult_item = 'craft "lump_of_coal" 1',
875         furnace_burntime = 30,
876 })
877
878 minetest.register_node("jungletree", {
879         tile_images = {"jungletree_top.png", "jungletree_top.png", "jungletree.png"},
880         inventory_image = inventorycube("jungletree_top.png", "jungletree.png", "jungletree.png"),
881         is_ground_content = true,
882         material = digprop_woodlike(1.0),
883         cookresult_item = 'craft "lump_of_coal" 1',
884         furnace_burntime = 30,
885 })
886
887 minetest.register_node("junglegrass", {
888         drawtype = "plantlike",
889         visual_scale = 1.3,
890         tile_images = {"junglegrass.png"},
891         inventory_image = "junglegrass.png",
892         light_propagates = true,
893         paramtype = "light",
894         walkable = false,
895         material = digprop_leaveslike(1.0),
896         furnace_burntime = 2,
897 })
898
899 minetest.register_node("leaves", {
900         drawtype = "allfaces_optional",
901         visual_scale = 1.3,
902         tile_images = {"leaves.png"},
903         inventory_image = "leaves.png",
904         light_propagates = true,
905         paramtype = "light",
906         material = digprop_leaveslike(1.0),
907         extra_dug_item = 'node "sapling" 1',
908         extra_dug_item_rarity = 20,
909         furnace_burntime = 1,
910 })
911
912 minetest.register_node("cactus", {
913         tile_images = {"cactus_top.png", "cactus_top.png", "cactus_side.png"},
914         inventory_image = inventorycube("cactus_top.png", "cactus_side.png", "cactus_side.png"),
915         is_ground_content = true,
916         material = digprop_woodlike(0.75),
917         furnace_burntime = 15,
918 })
919
920 minetest.register_node("papyrus", {
921         drawtype = "plantlike",
922         tile_images = {"papyrus.png"},
923         inventory_image = "papyrus.png",
924         light_propagates = true,
925         paramtype = "light",
926         is_ground_content = true,
927         walkable = false,
928         material = digprop_leaveslike(0.5),
929         furnace_burntime = 1,
930 })
931
932 minetest.register_node("bookshelf", {
933         tile_images = {"wood.png", "wood.png", "bookshelf.png"},
934         -- FIXME: inventorycube only cares for the first texture
935         --inventory_image = inventorycube("wood.png", "bookshelf.png", "bookshelf.png")
936         inventory_image = inventorycube("bookshelf.png"),
937         is_ground_content = true,
938         material = digprop_woodlike(0.75),
939         furnace_burntime = 30,
940 })
941
942 minetest.register_node("glass", {
943         drawtype = "glasslike",
944         tile_images = {"glass.png"},
945         inventory_image = inventorycube("glass.png"),
946         light_propagates = true,
947         paramtype = "light",
948         sunlight_propagates = true,
949         is_ground_content = true,
950         material = digprop_glasslike(1.0),
951 })
952
953 minetest.register_node("wooden_fence", {
954         drawtype = "fencelike",
955         tile_images = {"wood.png"},
956         inventory_image = "fence.png",
957         light_propagates = true,
958         paramtype = "light",
959         is_ground_content = true,
960         selection_box = {
961                 type = "fixed",
962                 fixed = {-1/7, -1/2, -1/7, 1/7, 1/2, 1/7},
963         },
964         furnace_burntime = 15,
965         material = digprop_woodlike(0.75),
966 })
967
968 minetest.register_node("rail", {
969         drawtype = "raillike",
970         tile_images = {"rail.png", "rail_curved.png", "rail_t_junction.png", "rail_crossing.png"},
971         inventory_image = "rail.png",
972         light_propagates = true,
973         paramtype = "light",
974         is_ground_content = true,
975         walkable = false,
976         selection_box = {
977                 type = "fixed",
978                 --fixed = <default>
979         },
980         material = digprop_dirtlike(0.75),
981 })
982
983 minetest.register_node("ladder", {
984         drawtype = "signlike",
985         tile_images = {"ladder.png"},
986         inventory_image = "ladder.png",
987         light_propagates = true,
988         paramtype = "light",
989         is_ground_content = true,
990         wall_mounted = true,
991         walkable = false,
992         climbable = true,
993         selection_box = {
994                 type = "wallmounted",
995                 --wall_top = = <default>
996                 --wall_bottom = = <default>
997                 --wall_side = = <default>
998         },
999         furnace_burntime = 5,
1000         material = digprop_woodlike(0.5),
1001 })
1002
1003 minetest.register_node("coalstone", {
1004         tile_images = {"stone.png^mineral_coal.png"},
1005         inventory_image = "stone.png^mineral_coal.png",
1006         is_ground_content = true,
1007         material = digprop_stonelike(1.5),
1008 })
1009
1010 minetest.register_node("wood", {
1011         tile_images = {"wood.png"},
1012         inventory_image = inventorycube("wood.png"),
1013         is_ground_content = true,
1014         furnace_burntime = 7,
1015         material = digprop_woodlike(0.75),
1016 })
1017
1018 minetest.register_node("mese", {
1019         tile_images = {"mese.png"},
1020         inventory_image = inventorycube("mese.png"),
1021         is_ground_content = true,
1022         furnace_burntime = 30,
1023         material = digprop_stonelike(0.5),
1024 })
1025
1026 minetest.register_node("cloud", {
1027         tile_images = {"cloud.png"},
1028         inventory_image = inventorycube("cloud.png"),
1029         is_ground_content = true,
1030 })
1031
1032 minetest.register_node("water_flowing", {
1033         drawtype = "flowingliquid",
1034         tile_images = {"water.png"},
1035         alpha = WATER_ALPHA,
1036         inventory_image = inventorycube("water.png"),
1037         paramtype = "light",
1038         light_propagates = true,
1039         walkable = false,
1040         pointable = false,
1041         diggable = false,
1042         buildable_to = true,
1043         liquidtype = "flowing",
1044         liquid_alternative_flowing = "water_flowing",
1045         liquid_alternative_source = "water_source",
1046         liquid_viscosity = WATER_VISC,
1047         post_effect_color = {a=64, r=100, g=100, b=200},
1048         special_materials = {
1049                 {image="water.png", backface_culling=false},
1050                 {image="water.png", backface_culling=true},
1051         },
1052 })
1053
1054 minetest.register_node("water_source", {
1055         drawtype = "liquid",
1056         tile_images = {"water.png"},
1057         alpha = WATER_ALPHA,
1058         inventory_image = inventorycube("water.png"),
1059         paramtype = "light",
1060         light_propagates = true,
1061         walkable = false,
1062         pointable = false,
1063         diggable = false,
1064         buildable_to = true,
1065         liquidtype = "source",
1066         liquid_alternative_flowing = "water_flowing",
1067         liquid_alternative_source = "water_source",
1068         liquid_viscosity = WATER_VISC,
1069         post_effect_color = {a=64, r=100, g=100, b=200},
1070         special_materials = {
1071                 -- New-style water source material (mostly unused)
1072                 {image="water.png", backface_culling=false},
1073         },
1074 })
1075
1076 minetest.register_node("lava_flowing", {
1077         drawtype = "flowingliquid",
1078         tile_images = {"lava.png"},
1079         inventory_image = inventorycube("lava.png"),
1080         paramtype = "light",
1081         light_propagates = false,
1082         light_source = LIGHT_MAX - 1,
1083         walkable = false,
1084         pointable = false,
1085         diggable = false,
1086         buildable_to = true,
1087         liquidtype = "flowing",
1088         liquid_alternative_flowing = "lava_flowing",
1089         liquid_alternative_source = "lava_source",
1090         liquid_viscosity = LAVA_VISC,
1091         damage_per_second = 4*2,
1092         post_effect_color = {a=192, r=255, g=64, b=0},
1093         special_materials = {
1094                 {image="lava.png", backface_culling=false},
1095                 {image="lava.png", backface_culling=true},
1096         },
1097 })
1098
1099 minetest.register_node("lava_source", {
1100         drawtype = "liquid",
1101         tile_images = {"lava.png"},
1102         inventory_image = inventorycube("lava.png"),
1103         paramtype = "light",
1104         light_propagates = false,
1105         light_source = LIGHT_MAX - 1,
1106         walkable = false,
1107         pointable = false,
1108         diggable = false,
1109         buildable_to = true,
1110         liquidtype = "source",
1111         liquid_alternative_flowing = "lava_flowing",
1112         liquid_alternative_source = "lava_source",
1113         liquid_viscosity = LAVA_VISC,
1114         damage_per_second = 4*2,
1115         post_effect_color = {a=192, r=255, g=64, b=0},
1116         special_materials = {
1117                 -- New-style lava source material (mostly unused)
1118                 {image="lava.png", backface_culling=false},
1119         },
1120         furnace_burntime = 60,
1121 })
1122
1123 minetest.register_node("torch", {
1124         drawtype = "torchlike",
1125         tile_images = {"torch_on_floor.png", "torch_on_ceiling.png", "torch.png"},
1126         inventory_image = "torch_on_floor.png",
1127         paramtype = "light",
1128         light_propagates = true,
1129         sunlight_propagates = true,
1130         walkable = false,
1131         wall_mounted = true,
1132         light_source = LIGHT_MAX-1,
1133         selection_box = {
1134                 type = "wallmounted",
1135                 wall_top = {-0.1, 0.5-0.6, -0.1, 0.1, 0.5, 0.1},
1136                 wall_bottom = {-0.1, -0.5, -0.1, 0.1, -0.5+0.6, 0.1},
1137                 wall_side = {-0.5, -0.3, -0.1, -0.5+0.3, 0.3, 0.1},
1138         },
1139         material = digprop_constanttime(0.0),
1140         furnace_burntime = 4,
1141 })
1142
1143 minetest.register_node("sign_wall", {
1144         drawtype = "signlike",
1145         tile_images = {"sign_wall.png"},
1146         inventory_image = "sign_wall.png",
1147         paramtype = "light",
1148         light_propagates = true,
1149         sunlight_propagates = true,
1150         walkable = false,
1151         wall_mounted = true,
1152         metadata_name = "sign",
1153         selection_box = {
1154                 type = "wallmounted",
1155                 --wall_top = <default>
1156                 --wall_bottom = <default>
1157                 --wall_side = <default>
1158         },
1159         material = digprop_constanttime(0.5),
1160         furnace_burntime = 10,
1161 })
1162
1163 minetest.register_node("chest", {
1164         tile_images = {"chest_top.png", "chest_top.png", "chest_side.png",
1165                 "chest_side.png", "chest_side.png", "chest_front.png"},
1166         inventory_image = "chest_top.png",
1167         --inventory_image = inventorycube("chest_top.png", "chest_side.png", "chest_front.png"),
1168         paramtype = "facedir_simple",
1169         metadata_name = "chest",
1170         material = digprop_woodlike(1.0),
1171         furnace_burntime = 30,
1172 })
1173
1174 minetest.register_node("locked_chest", {
1175         tile_images = {"chest_top.png", "chest_top.png", "chest_side.png",
1176                 "chest_side.png", "chest_side.png", "chest_lock.png"},
1177         inventory_image = "chest_lock.png",
1178         paramtype = "facedir_simple",
1179         metadata_name = "locked_chest",
1180         material = digprop_woodlike(1.0),
1181         furnace_burntime = 30,
1182 })
1183
1184 minetest.register_node("furnace", {
1185         tile_images = {"furnace_side.png", "furnace_side.png", "furnace_side.png",
1186                 "furnace_side.png", "furnace_side.png", "furnace_front.png"},
1187         inventory_image = "furnace_front.png",
1188         paramtype = "facedir_simple",
1189         metadata_name = "furnace",
1190         material = digprop_stonelike(3.0),
1191 })
1192
1193 minetest.register_node("cobble", {
1194         tile_images = {"cobble.png"},
1195         inventory_image = inventorycube("cobble.png"),
1196         is_ground_content = true,
1197         cookresult_item = 'node "stone" 1',
1198         material = digprop_stonelike(0.9),
1199 })
1200
1201 minetest.register_node("mossycobble", {
1202         tile_images = {"mossycobble.png"},
1203         inventory_image = inventorycube("mossycobble.png"),
1204         is_ground_content = true,
1205         material = digprop_stonelike(0.8),
1206 })
1207
1208 minetest.register_node("steelblock", {
1209         tile_images = {"steel_block.png"},
1210         inventory_image = inventorycube("steel_block.png"),
1211         is_ground_content = true,
1212         material = digprop_stonelike(5.0),
1213 })
1214
1215 minetest.register_node("nyancat", {
1216         tile_images = {"nc_side.png", "nc_side.png", "nc_side.png",
1217                 "nc_side.png", "nc_back.png", "nc_front.png"},
1218         inventory_image = "nc_front.png",
1219         paramtype = "facedir_simple",
1220         material = digprop_stonelike(3.0),
1221         furnace_burntime = 1,
1222 })
1223
1224 minetest.register_node("nyancat_rainbow", {
1225         tile_images = {"nc_rb.png"},
1226         inventory_image = "nc_rb.png",
1227         material = digprop_stonelike(3.0),
1228         furnace_burntime = 1,
1229 })
1230
1231 minetest.register_node("sapling", {
1232         drawtype = "plantlike",
1233         visual_scale = 1.0,
1234         tile_images = {"sapling.png"},
1235         inventory_image = "sapling.png",
1236         paramtype = "light",
1237         light_propagates = true,
1238         walkable = false,
1239         material = digprop_constanttime(0.0),
1240         furnace_burntime = 10,
1241 })
1242
1243 minetest.register_node("apple", {
1244         drawtype = "plantlike",
1245         visual_scale = 1.0,
1246         tile_images = {"apple.png"},
1247         inventory_image = "apple.png",
1248         paramtype = "light",
1249         light_propagates = true,
1250         sunlight_propagates = true,
1251         walkable = false,
1252         dug_item = 'craft "apple" 1',
1253         material = digprop_constanttime(0.0),
1254         furnace_burntime = 3,
1255 })
1256
1257 --
1258 -- Crafting items
1259 --
1260
1261 minetest.register_craftitem("Stick", {
1262         image = "stick.png",
1263         --furnace_burntime = ...,
1264         on_place_on_ground = minetest.craftitem_place_item,
1265 })
1266
1267 minetest.register_craftitem("paper", {
1268         image = "paper.png",
1269         on_place_on_ground = minetest.craftitem_place_item,
1270 })
1271
1272 minetest.register_craftitem("book", {
1273         image = "book.png",
1274         on_place_on_ground = minetest.craftitem_place_item,
1275 })
1276
1277 minetest.register_craftitem("lump_of_coal", {
1278         image = "lump_of_coal.png",
1279         furnace_burntime = 40;
1280         on_place_on_ground = minetest.craftitem_place_item,
1281 })
1282
1283 minetest.register_craftitem("lump_of_iron", {
1284         image = "lump_of_iron.png",
1285         cookresult_item = 'craft "steel_ingot" 1',
1286         on_place_on_ground = minetest.craftitem_place_item,
1287 })
1288
1289 minetest.register_craftitem("lump_of_clay", {
1290         image = "lump_of_clay.png",
1291         cookresult_item = 'craft "clay_brick" 1',
1292         on_place_on_ground = minetest.craftitem_place_item,
1293 })
1294
1295 minetest.register_craftitem("steel_ingot", {
1296         image = "steel_ingot.png",
1297         on_place_on_ground = minetest.craftitem_place_item,
1298 })
1299
1300 minetest.register_craftitem("clay_brick", {
1301         image = "clay_brick.png",
1302         on_place_on_ground = minetest.craftitem_place_item,
1303 })
1304
1305 minetest.register_craftitem("rat", {
1306         image = "rat.png",
1307         cookresult_item = 'craft "cooked_rat" 1',
1308         on_drop = function(item, dropper, pos)
1309                 minetest.env:add_rat(pos)
1310                 return true
1311         end,
1312 })
1313
1314 minetest.register_craftitem("cooked_rat", {
1315         image = "cooked_rat.png",
1316         cookresult_item = 'craft "scorched_stuff" 1',
1317         on_place_on_ground = minetest.craftitem_place_item,
1318         on_use = minetest.craftitem_eat(6),
1319 })
1320
1321 minetest.register_craftitem("scorched_stuff", {
1322         image = "scorched_stuff.png",
1323         on_place_on_ground = minetest.craftitem_place_item,
1324 })
1325
1326 minetest.register_craftitem("firefly", {
1327         image = "firefly.png",
1328         on_drop = function(item, dropper, pos)
1329                 minetest.env:add_firefly(pos)
1330                 return true
1331         end,
1332 })
1333
1334 minetest.register_craftitem("apple", {
1335         image = "apple.png",
1336         on_place_on_ground = minetest.craftitem_place_item,
1337         on_use = minetest.craftitem_eat(4),
1338 })
1339
1340 minetest.register_craftitem("apple_iron", {
1341         image = "apple_iron.png",
1342         on_place_on_ground = minetest.craftitem_place_item,
1343         on_use = minetest.craftitem_eat(8),
1344 })
1345
1346 print(dump(minetest.registered_craftitems))
1347
1348 --
1349 -- Creative inventory
1350 --
1351
1352 minetest.add_to_creative_inventory('tool MesePick 0')
1353 minetest.add_to_creative_inventory('tool SteelPick 0')
1354 minetest.add_to_creative_inventory('tool SteelAxe 0')
1355 minetest.add_to_creative_inventory('tool SteelShovel 0')
1356
1357 minetest.add_to_creative_inventory('node torch 0')
1358 minetest.add_to_creative_inventory('node cobble 0')
1359 minetest.add_to_creative_inventory('node dirt 0')
1360 minetest.add_to_creative_inventory('node stone 0')
1361 minetest.add_to_creative_inventory('node sand 0')
1362 minetest.add_to_creative_inventory('node sandstone 0')
1363 minetest.add_to_creative_inventory('node clay 0')
1364 minetest.add_to_creative_inventory('node brick 0')
1365 minetest.add_to_creative_inventory('node tree 0')
1366 minetest.add_to_creative_inventory('node leaves 0')
1367 minetest.add_to_creative_inventory('node cactus 0')
1368 minetest.add_to_creative_inventory('node papyrus 0')
1369 minetest.add_to_creative_inventory('node bookshelf 0')
1370 minetest.add_to_creative_inventory('node glass 0')
1371 minetest.add_to_creative_inventory('node fence 0')
1372 minetest.add_to_creative_inventory('node rail 0')
1373 minetest.add_to_creative_inventory('node mese 0')
1374 minetest.add_to_creative_inventory('node chest 0')
1375 minetest.add_to_creative_inventory('node furnace 0')
1376 minetest.add_to_creative_inventory('node sign_wall 0')
1377 minetest.add_to_creative_inventory('node water_source 0')
1378 minetest.add_to_creative_inventory('node lava_source 0')
1379 minetest.add_to_creative_inventory('node ladder 0')
1380
1381 --
1382 -- Some common functions
1383 --
1384
1385 function nodeupdate_single(p)
1386         n = minetest.env:get_node(p)
1387         if n.name == "sand" or n.name == "gravel" then
1388                 p_bottom = {x=p.x, y=p.y-1, z=p.z}
1389                 n_bottom = minetest.env:get_node(p_bottom)
1390                 if n_bottom.name == "air" then
1391                         minetest.env:remove_node(p)
1392                         minetest.env:add_luaentity(p, "falling_"..n.name)
1393                         nodeupdate(p)
1394                 end
1395         end
1396 end
1397
1398 function nodeupdate(p)
1399         for x = -1,1 do
1400         for y = -1,1 do
1401         for z = -1,1 do
1402                 p2 = {x=p.x+x, y=p.y+y, z=p.z+z}
1403                 nodeupdate_single(p2)
1404         end
1405         end
1406         end
1407 end
1408
1409 --
1410 -- Falling stuff
1411 --
1412
1413 function register_falling_node(nodename, texture)
1414         minetest.register_entity("falling_"..nodename, {
1415                 -- Static definition
1416                 physical = true,
1417                 collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
1418                 visual = "cube",
1419                 textures = {texture,texture,texture,texture,texture,texture},
1420                 -- State
1421                 -- Methods
1422                 on_step = function(self, dtime)
1423                         -- Set gravity
1424                         self.object:setacceleration({x=0, y=-10, z=0})
1425                         -- Turn to actual sand when collides to ground or just move
1426                         local pos = self.object:getpos()
1427                         local bcp = {x=pos.x, y=pos.y-0.7, z=pos.z} -- Position of bottom center point
1428                         local bcn = minetest.env:get_node(bcp)
1429                         if bcn.name ~= "air" then
1430                                 -- Turn to a sand node
1431                                 local np = {x=bcp.x, y=bcp.y+1, z=bcp.z}
1432                                 minetest.env:add_node(np, {name=nodename})
1433                                 self.object:remove()
1434                         else
1435                                 -- Do nothing
1436                         end
1437                 end
1438         })
1439 end
1440
1441 register_falling_node("sand", "sand.png")
1442 register_falling_node("gravel", "gravel.png")
1443
1444 --
1445 -- Global callbacks
1446 --
1447
1448 -- Global environment step function
1449 function on_step(dtime)
1450         -- print("on_step")
1451 end
1452 minetest.register_globalstep(on_step)
1453
1454 function on_placenode(p, node)
1455         print("on_placenode")
1456         nodeupdate(p)
1457 end
1458 minetest.register_on_placenode(on_placenode)
1459
1460 function on_dignode(p, node)
1461         print("on_dignode")
1462         nodeupdate(p)
1463 end
1464 minetest.register_on_dignode(on_dignode)
1465
1466 function on_punchnode(p, node)
1467         print("on_punchnode")
1468         if node.name == "TNT" then
1469                 minetest.env:remove_node(p)
1470                 minetest.env:add_luaentity(p, "TNT")
1471                 --minetest.env:add_luaentity(p, "testentity")
1472                 --minetest.env:add_firefly(p)
1473                 nodeupdate(p)
1474         end
1475 end
1476 minetest.register_on_punchnode(on_punchnode)
1477
1478 minetest.register_on_chat_message(function(name, message)
1479         --print("default on_chat_message: name="..dump(name).." message="..dump(message))
1480         local cmd = "/giveme"
1481         if message:sub(0, #cmd) == cmd then
1482                 if not minetest.get_player_privs(name)["give"] then
1483                         minetest.chat_send_player(name, "you don't have permission to give")
1484                         return true -- Handled chat message
1485                 end
1486                 local stackstring = string.match(message, cmd.." (.*)")
1487                 if stackstring == nil then
1488                         minetest.chat_send_player(name, 'usage: '..cmd..' stackstring')
1489                         return true -- Handled chat message
1490                 end
1491                 print(cmd..' invoked, stackstring="'..stackstring..'"')
1492                 local player = minetest.env:get_player_by_name(name)
1493                 if player == nil then
1494                         minetest.chat_send_player(name, name2..' is not a known player')
1495                         return true -- Handled chat message
1496                 end
1497                 local added, error_msg = player:add_to_inventory(stackstring)
1498                 if added then
1499                         minetest.chat_send_player(name, '"'..stackstring
1500                                         ..'" added to inventory.');
1501                 else
1502                         minetest.chat_send_player(name, 'Could not give "'..stackstring
1503                                         ..'": '..error_msg);
1504                 end
1505                 return true -- Handled chat message
1506         end
1507         local cmd = "/give"
1508         if message:sub(0, #cmd) == cmd then
1509                 if not minetest.get_player_privs(name)["give"] then
1510                         minetest.chat_send_player(name, "you don't have permission to give")
1511                         return true -- Handled chat message
1512                 end
1513                 local name2, stackstring = string.match(message, cmd.." ([%a%d_-]+) (.*)")
1514                 if name == nil or stackstring == nil then
1515                         minetest.chat_send_player(name, 'usage: '..cmd..' name stackstring')
1516                         return true -- Handled chat message
1517                 end
1518                 print(cmd..' invoked, name2="'..name2
1519                                 ..'" stackstring="'..stackstring..'"')
1520                 local player = minetest.env:get_player_by_name(name2)
1521                 if player == nil then
1522                         minetest.chat_send_player(name, name2..' is not a known player')
1523                         return true -- Handled chat message
1524                 end
1525                 local added, error_msg = player:add_to_inventory(stackstring)
1526                 if added then
1527                         minetest.chat_send_player(name, '"'..stackstring
1528                                         ..'" added to '..name2..'\'s inventory.');
1529                         minetest.chat_send_player(name2, '"'..stackstring
1530                                         ..'" added to inventory.');
1531                 else
1532                         minetest.chat_send_player(name, 'Could not give "'..stackstring
1533                                         ..'": '..error_msg);
1534                 end
1535                 return true -- Handled chat message
1536         end
1537 end)
1538
1539 --
1540 -- Done, print some random stuff
1541 --
1542
1543 --print("minetest.registered_entities:")
1544 --dump2(minetest.registered_entities)
1545
1546 -- END