1 function basic_dump2(o)
2 if type(o) == "number" then
4 elseif type(o) == "string" then
5 return string.format("%q", o)
6 elseif type(o) == "boolean" then
8 elseif type(o) == "function" then
10 elseif type(o) == "userdata" then
12 elseif type(o) == "nil" then
15 error("cannot dump a " .. type(o))
20 function dump2(o, name, dumped)
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
30 io.write(dumped[o], "\n")
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)
40 error("cannot dump a " .. type(o))
45 function dump(o, dumped)
47 if type(o) == "number" then
49 elseif type(o) == "string" then
50 return string.format("%q", o)
51 elseif type(o) == "table" then
53 return "<circular reference>"
57 for k,v in pairs(o) do
58 t[#t+1] = "" .. k .. " = " .. dump(v, dumped)
60 return "{" .. table.concat(t, ", ") .. "}"
61 elseif type(o) == "boolean" then
63 elseif type(o) == "function" then
65 elseif type(o) == "userdata" then
67 elseif type(o) == "nil" then
70 error("cannot dump a " .. type(o))
76 -- Mods should prefix their textures with modname_, eg. given the mod
77 -- name "foomod", a texture could be called "foomod_superfurnace.png"
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)
89 -- minetest.env - environment reference
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
99 -- EnvRef is basically ServerEnvironment and ServerMap combined.
101 -- - add_node(pos, node)
102 -- - remove_node(pos)
104 -- - add_luaentity(pos, name)
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
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
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
125 -- MapNode representation:
126 -- {name="name", param1=num, param2=num}
128 -- Position representation:
129 -- {x=num, y=num, z=num}
132 -- print("minetest dump: "..dump(minetest))
138 minetest.register_tool("WPick", {
139 image = "tool_woodpick.png",
142 dt_crackiness = -0.5,
151 minetest.register_tool("STPick", {
152 image = "tool_stonepick.png",
155 dt_crackiness = -0.5,
158 basedurability = 100,
164 minetest.register_tool("SteelPick", {
165 image = "tool_steelpick.png",
168 dt_crackiness = -0.5,
171 basedurability = 333,
177 minetest.register_tool("MesePick", {
178 image = "tool_mesepick.png",
184 basedurability = 1337,
190 minetest.register_tool("WShovel", {
191 image = "tool_woodshovel.png",
195 dt_crumbliness = -1.5,
196 dt_cuttability = 0.3,
203 minetest.register_tool("STShovel", {
204 image = "tool_stoneshovel.png",
208 dt_crumbliness = -1.5,
209 dt_cuttability = 0.1,
210 basedurability = 100,
216 minetest.register_tool("SteelShovel", {
217 image = "tool_steelshovel.png",
221 dt_crumbliness = -1.5,
222 dt_cuttability = 0.0,
223 basedurability = 330,
229 minetest.register_tool("WAxe", {
230 image = "tool_woodaxe.png",
233 dt_crackiness = -0.2,
235 dt_cuttability = -0.5,
242 minetest.register_tool("STAxe", {
243 image = "tool_stoneaxe.png",
246 dt_crackiness = -0.2,
248 dt_cuttability = -0.5,
249 basedurability = 100,
255 minetest.register_tool("SteelAxe", {
256 image = "tool_steelaxe.png",
259 dt_crackiness = -0.2,
261 dt_cuttability = -0.5,
262 basedurability = 330,
268 minetest.register_tool("WSword", {
269 image = "tool_woodsword.png",
281 minetest.register_tool("STSword", {
282 image = "tool_stonesword.png",
288 basedurability = 100,
294 minetest.register_tool("SteelSword", {
295 image = "tool_steelsword.png",
301 basedurability = 330,
307 minetest.register_tool("", {
322 minetest.register_tool("horribletool", {
338 -- Crafting definition
341 minetest.register_craft({
342 output = 'NodeItem "wood" 4',
348 minetest.register_craft({
349 output = 'CraftItem "Stick" 4',
355 minetest.register_craft({
356 output = 'NodeItem "wooden_fence" 2',
358 {'CraftItem "Stick"', 'CraftItem "Stick"', 'CraftItem "Stick"'},
359 {'CraftItem "Stick"', 'CraftItem "Stick"', 'CraftItem "Stick"'},
363 minetest.register_craft({
364 output = 'NodeItem "sign_wall" 1',
366 {'NodeItem "wood"', 'NodeItem "wood"', 'NodeItem "wood"'},
367 {'NodeItem "wood"', 'NodeItem "wood"', 'NodeItem "wood"'},
368 {'', 'CraftItem "Stick"', ''},
372 minetest.register_craft({
373 output = 'NodeItem "torch" 4',
375 {'CraftItem "lump_of_coal"'},
376 {'CraftItem "Stick"'},
380 minetest.register_craft({
381 output = 'ToolItem "WPick"',
383 {'NodeItem "wood"', 'NodeItem "wood"', 'NodeItem "wood"'},
384 {'', 'CraftItem "Stick"', ''},
385 {'', 'CraftItem "Stick"', ''},
389 minetest.register_craft({
390 output = 'ToolItem "STPick"',
392 {'NodeItem "cobble"', 'NodeItem "cobble"', 'NodeItem "cobble"'},
393 {'', 'CraftItem "Stick"', ''},
394 {'', 'CraftItem "Stick"', ''},
398 minetest.register_craft({
399 output = 'ToolItem "SteelPick"',
401 {'CraftItem "steel_ingot"', 'CraftItem "steel_ingot"', 'CraftItem "steel_ingot"'},
402 {'', 'CraftItem "Stick"', ''},
403 {'', 'CraftItem "Stick"', ''},
407 minetest.register_craft({
408 output = 'ToolItem "MesePick"',
410 {'NodeItem "mese"', 'NodeItem "mese"', 'NodeItem "mese"'},
411 {'', 'CraftItem "Stick"', ''},
412 {'', 'CraftItem "Stick"', ''},
416 minetest.register_craft({
417 output = 'ToolItem "WShovel"',
420 {'CraftItem "Stick"'},
421 {'CraftItem "Stick"'},
425 minetest.register_craft({
426 output = 'ToolItem "STShovel"',
428 {'NodeItem "cobble"'},
429 {'CraftItem "Stick"'},
430 {'CraftItem "Stick"'},
434 minetest.register_craft({
435 output = 'ToolItem "SteelShovel"',
437 {'CraftItem "steel_ingot"'},
438 {'CraftItem "Stick"'},
439 {'CraftItem "Stick"'},
443 minetest.register_craft({
444 output = 'ToolItem "WAxe"',
446 {'NodeItem "wood"', 'NodeItem "wood"'},
447 {'NodeItem "wood"', 'CraftItem "Stick"'},
448 {'', 'CraftItem "Stick"'},
452 minetest.register_craft({
453 output = 'ToolItem "STAxe"',
455 {'NodeItem "cobble"', 'NodeItem "cobble"'},
456 {'NodeItem "cobble"', 'CraftItem "Stick"'},
457 {'', 'CraftItem "Stick"'},
461 minetest.register_craft({
462 output = 'ToolItem "SteelAxe"',
464 {'CraftItem "steel_ingot"', 'CraftItem "steel_ingot"'},
465 {'CraftItem "steel_ingot"', 'CraftItem "Stick"'},
466 {'', 'CraftItem "Stick"'},
470 minetest.register_craft({
471 output = 'ToolItem "WSword"',
475 {'CraftItem "Stick"'},
479 minetest.register_craft({
480 output = 'ToolItem "STSword"',
482 {'NodeItem "cobble"'},
483 {'NodeItem "cobble"'},
484 {'CraftItem "Stick"'},
488 minetest.register_craft({
489 output = 'ToolItem "SteelSword"',
491 {'CraftItem "steel_ingot"'},
492 {'CraftItem "steel_ingot"'},
493 {'CraftItem "Stick"'},
497 minetest.register_craft({
498 output = 'NodeItem "rail" 15',
500 {'CraftItem "steel_ingot"', '', 'CraftItem "steel_ingot"'},
501 {'CraftItem "steel_ingot"', 'CraftItem "Stick"', 'CraftItem "steel_ingot"'},
502 {'CraftItem "steel_ingot"', '', 'CraftItem "steel_ingot"'},
506 minetest.register_craft({
507 output = 'NodeItem "chest" 1',
509 {'NodeItem "wood"', 'NodeItem "wood"', 'NodeItem "wood"'},
510 {'NodeItem "wood"', '', 'NodeItem "wood"'},
511 {'NodeItem "wood"', 'NodeItem "wood"', 'NodeItem "wood"'},
515 minetest.register_craft({
516 output = 'NodeItem "locked_chest" 1',
518 {'NodeItem "wood"', 'NodeItem "wood"', 'NodeItem "wood"'},
519 {'NodeItem "wood"', 'CraftItem "steel_ingot"', 'NodeItem "wood"'},
520 {'NodeItem "wood"', 'NodeItem "wood"', 'NodeItem "wood"'},
524 minetest.register_craft({
525 output = 'NodeItem "furnace" 1',
527 {'NodeItem "cobble"', 'NodeItem "cobble"', 'NodeItem "cobble"'},
528 {'NodeItem "cobble"', '', 'NodeItem "cobble"'},
529 {'NodeItem "cobble"', 'NodeItem "cobble"', 'NodeItem "cobble"'},
533 minetest.register_craft({
534 output = 'NodeItem "steelblock" 1',
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"'},
542 minetest.register_craft({
543 output = 'NodeItem "sandstone" 1',
545 {'NodeItem "sand"', 'NodeItem "sand"'},
546 {'NodeItem "sand"', 'NodeItem "sand"'},
550 minetest.register_craft({
551 output = 'NodeItem "clay" 1',
553 {'CraftItem "lump_of_clay"', 'CraftItem "lump_of_clay"'},
554 {'CraftItem "lump_of_clay"', 'CraftItem "lump_of_clay"'},
558 minetest.register_craft({
559 output = 'NodeItem "brick" 1',
561 {'CraftItem "clay_brick"', 'CraftItem "clay_brick"'},
562 {'CraftItem "clay_brick"', 'CraftItem "clay_brick"'},
566 minetest.register_craft({
567 output = 'CraftItem "paper" 1',
569 {'NodeItem "papyrus"', 'NodeItem "papyrus"', 'NodeItem "papyrus"'},
573 minetest.register_craft({
574 output = 'CraftItem "book" 1',
576 {'CraftItem "paper"'},
577 {'CraftItem "paper"'},
578 {'CraftItem "paper"'},
582 minetest.register_craft({
583 output = 'NodeItem "bookshelf" 1',
585 {'NodeItem "wood"', 'NodeItem "wood"', 'NodeItem "wood"'},
586 {'CraftItem "book"', 'CraftItem "book"', 'CraftItem "book"'},
587 {'NodeItem "wood"', 'NodeItem "wood"', 'NodeItem "wood"'},
591 minetest.register_craft({
592 output = 'NodeItem "ladder" 1',
594 {'CraftItem "Stick"', '', 'CraftItem "Stick"'},
595 {'CraftItem "Stick"', 'CraftItem "Stick"', 'CraftItem "Stick"'},
596 {'CraftItem "Stick"', '', 'CraftItem "Stick"'},
600 minetest.register_craft({
601 output = 'CraftItem "apple_iron" 1',
603 {'', 'CraftItem "steel_ingot"', ''},
604 {'CraftItem "steel_ingot"', 'CraftItem "apple"', 'CraftItem "steel_ingot"'},
605 {'', 'CraftItem "steel_ingot"', ''},
609 minetest.register_craft({
610 output = 'NodeItem "TNT" 4',
612 {'NodeItem "wood" 1'},
613 {'CraftItem "lump_of_coal" 1'},
614 {'NodeItem "wood" 1'}
618 minetest.register_craft({
619 output = 'NodeItem "somenode" 4',
621 {'CraftItem "Stick" 1'},
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",
633 diggability = "normal",
640 metadata_name = "chest",
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
653 -- Some common functions
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)
669 function nodeupdate(p)
673 p2 = {x=p.x+x, y=p.y+y, z=p.z+z}
674 nodeupdate_single(p2)
681 -- TNT (not functional)
686 physical = true, -- Collides with things
688 collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
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
695 -- Number of punches required to defuse
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})
706 -- Called periodically
707 function TNT:on_step(dtime)
708 --print("TNT:on_step()")
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
717 hitter:add_to_inventory("NodeItem TNT 1")
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)
728 print("TNT dump: "..dump(TNT))
730 print("Registering TNT");
731 minetest.register_entity("TNT", TNT)
737 function register_falling_node(nodename, texture)
738 minetest.register_entity("falling_"..nodename, {
741 collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
743 textures = {texture,texture,texture,texture,texture,texture},
746 on_step = function(self, dtime)
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})
765 register_falling_node("sand", "sand.png")
766 register_falling_node("gravel", "gravel.png")
769 minetest.register_entity("falling_sand", {
771 collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
773 textures = {"sand.png","sand.png","sand.png","sand.png","sand.png","sand.png"},
777 on_step = function(self, dtime)
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"})
802 -- Global environment step function
803 function on_step(dtime)
806 minetest.register_globalstep(on_step)
808 function on_placenode(p, node)
809 print("on_placenode")
812 minetest.register_on_placenode(on_placenode)
814 function on_dignode(p, node)
818 minetest.register_on_dignode(on_dignode)
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")
828 minetest.register_on_punchnode(on_punchnode)
831 -- Done, print some random stuff
834 print("minetest.registered_entities:")
835 dump2(minetest.registered_entities)
838 -- Some random pre-implementation planning and drafting
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")
857 textures = "stone.png",
859 get_dig_duration = function(env, pos, digger)
860 -- Check stuff like digger.current_tool
863 on_dig = function(env, pos, digger)
865 digger.inventory.put("MaterialItem2 0");
870 textures = {"grass.png","mud.png","mud_grass_side.png","mud_grass_side.png","mud_grass_side.png","mud_grass_side.png"},
872 get_dig_duration = function(env, pos, digger)
873 -- Check stuff like digger.current_tool
876 on_dig = function(env, pos, digger)
878 digger.inventory.put("MaterialItem2 1");
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"},
886 get_dig_duration = function(env, pos, digger)
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)