3 Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "scriptapi.h"
33 #include "serverobject.h"
36 #include "luaentity_common.h"
37 #include "content_sao.h" // For LuaEntitySAO
41 #include "main.h" // For g_settings
42 #include "settings.h" // For accessing g_settings
46 - Random node triggers (like grass growth)
47 - All kinds of callbacks
48 - Object visual client-side stuff
50 - Spritesheets and animation
52 blockdef.metadata_name =
59 - Stores an inventory and stuff in a Settings object
60 meta.inventory_add_list("main")
61 blockdef.on_inventory_modified
62 meta.set("owner", playername)
64 - Item definition (actually, only CraftItem)
65 - (not scripting) Putting items in node metadata (virtual)
68 static void stackDump(lua_State *L, std::ostream &o)
71 int top = lua_gettop(L);
72 for (i = 1; i <= top; i++) { /* repeat for each level */
73 int t = lua_type(L, i);
76 case LUA_TSTRING: /* strings */
77 o<<"\""<<lua_tostring(L, i)<<"\"";
80 case LUA_TBOOLEAN: /* booleans */
81 o<<(lua_toboolean(L, i) ? "true" : "false");
84 case LUA_TNUMBER: /* numbers */ {
86 snprintf(buf, 10, "%g", lua_tonumber(L, i));
90 default: /* other values */
91 o<<lua_typename(L, t);
100 static void realitycheck(lua_State *L)
102 int top = lua_gettop(L);
104 dstream<<"Stack is over 30:"<<std::endl;
105 stackDump(L, dstream);
106 script_error(L, "Stack is over 30 (reality check)");
116 StackUnroller(lua_State *L):
120 m_original_top = lua_gettop(m_lua); // store stack height
124 lua_settop(m_lua, m_original_top); // restore stack height
128 static v3f readFloatPos(lua_State *L, int index)
131 luaL_checktype(L, index, LUA_TTABLE);
132 lua_getfield(L, index, "x");
133 pos.X = lua_tonumber(L, -1);
135 lua_getfield(L, index, "y");
136 pos.Y = lua_tonumber(L, -1);
138 lua_getfield(L, index, "z");
139 pos.Z = lua_tonumber(L, -1);
141 pos *= BS; // Scale to internal format
145 static void pushpos(lua_State *L, v3s16 p)
148 lua_pushnumber(L, p.X);
149 lua_setfield(L, -2, "x");
150 lua_pushnumber(L, p.Y);
151 lua_setfield(L, -2, "y");
152 lua_pushnumber(L, p.Z);
153 lua_setfield(L, -2, "z");
156 static v3s16 readpos(lua_State *L, int index)
158 // Correct rounding at <0
159 v3f pf = readFloatPos(L, index);
160 return floatToInt(pf, BS);
163 static void pushnode(lua_State *L, const MapNode &n, INodeDefManager *ndef)
166 lua_pushstring(L, ndef->get(n).name.c_str());
167 lua_setfield(L, -2, "name");
168 lua_pushnumber(L, n.getParam1());
169 lua_setfield(L, -2, "param1");
170 lua_pushnumber(L, n.getParam2());
171 lua_setfield(L, -2, "param2");
174 static MapNode readnode(lua_State *L, int index, INodeDefManager *ndef)
176 lua_getfield(L, index, "name");
177 const char *name = lua_tostring(L, -1);
180 lua_getfield(L, index, "param1");
184 param1 = lua_tonumber(L, -1);
187 lua_getfield(L, index, "param2");
191 param2 = lua_tonumber(L, -1);
193 return MapNode(ndef, name, param1, param2);
196 static video::SColor readARGB8(lua_State *L, int index)
199 luaL_checktype(L, index, LUA_TTABLE);
200 lua_getfield(L, index, "a");
201 if(lua_isnumber(L, -1))
202 color.setAlpha(lua_tonumber(L, -1));
204 lua_getfield(L, index, "r");
205 color.setRed(lua_tonumber(L, -1));
207 lua_getfield(L, index, "g");
208 color.setGreen(lua_tonumber(L, -1));
210 lua_getfield(L, index, "b");
211 color.setBlue(lua_tonumber(L, -1));
216 static core::aabbox3d<f32> read_aabbox3df32(lua_State *L, int index, f32 scale)
218 core::aabbox3d<f32> box;
219 if(lua_istable(L, -1)){
220 lua_rawgeti(L, -1, 1);
221 box.MinEdge.X = lua_tonumber(L, -1) * scale;
223 lua_rawgeti(L, -1, 2);
224 box.MinEdge.Y = lua_tonumber(L, -1) * scale;
226 lua_rawgeti(L, -1, 3);
227 box.MinEdge.Z = lua_tonumber(L, -1) * scale;
229 lua_rawgeti(L, -1, 4);
230 box.MaxEdge.X = lua_tonumber(L, -1) * scale;
232 lua_rawgeti(L, -1, 5);
233 box.MaxEdge.Y = lua_tonumber(L, -1) * scale;
235 lua_rawgeti(L, -1, 6);
236 box.MaxEdge.Z = lua_tonumber(L, -1) * scale;
242 static bool getstringfield(lua_State *L, int table,
243 const char *fieldname, std::string &result)
245 lua_getfield(L, table, fieldname);
247 if(lua_isstring(L, -1)){
248 result = lua_tostring(L, -1);
255 static bool getintfield(lua_State *L, int table,
256 const char *fieldname, int &result)
258 lua_getfield(L, table, fieldname);
260 if(lua_isnumber(L, -1)){
261 result = lua_tonumber(L, -1);
268 static bool getfloatfield(lua_State *L, int table,
269 const char *fieldname, float &result)
271 lua_getfield(L, table, fieldname);
273 if(lua_isnumber(L, -1)){
274 result = lua_tonumber(L, -1);
281 static bool getboolfield(lua_State *L, int table,
282 const char *fieldname, bool &result)
284 lua_getfield(L, table, fieldname);
286 if(lua_isboolean(L, -1)){
287 result = lua_toboolean(L, -1);
294 static std::string getstringfield_default(lua_State *L, int table,
295 const char *fieldname, const std::string &default_)
297 std::string result = default_;
298 getstringfield(L, table, fieldname, result);
302 static int getintfield_default(lua_State *L, int table,
303 const char *fieldname, int default_)
305 int result = default_;
306 getintfield(L, table, fieldname, result);
310 static bool getboolfield_default(lua_State *L, int table,
311 const char *fieldname, bool default_)
313 bool result = default_;
314 getboolfield(L, table, fieldname, result);
324 static bool string_to_enum(const EnumString *spec, int &result,
325 const std::string &str)
327 const EnumString *esp = spec;
329 if(str == std::string(esp->str)){
338 /*static bool enum_to_string(const EnumString *spec, std::string &result,
341 const EnumString *esp = spec;
352 static int getenumfield(lua_State *L, int table,
353 const char *fieldname, const EnumString *spec, int default_)
355 int result = default_;
356 string_to_enum(spec, result,
357 getstringfield_default(L, table, fieldname, ""));
361 struct EnumString es_DrawType[] =
363 {NDT_NORMAL, "normal"},
364 {NDT_AIRLIKE, "airlike"},
365 {NDT_LIQUID, "liquid"},
366 {NDT_FLOWINGLIQUID, "flowingliquid"},
367 {NDT_GLASSLIKE, "glasslike"},
368 {NDT_ALLFACES, "allfaces"},
369 {NDT_ALLFACES_OPTIONAL, "allfaces_optional"},
370 {NDT_TORCHLIKE, "torchlike"},
371 {NDT_SIGNLIKE, "signlike"},
372 {NDT_PLANTLIKE, "plantlike"},
373 {NDT_FENCELIKE, "fencelike"},
374 {NDT_RAILLIKE, "raillike"},
378 struct EnumString es_ContentParamType[] =
381 {CPT_LIGHT, "light"},
382 {CPT_MINERAL, "mineral"},
383 {CPT_FACEDIR_SIMPLE, "facedir_simple"},
386 struct EnumString es_LiquidType[] =
388 {LIQUID_NONE, "none"},
389 {LIQUID_FLOWING, "flowing"},
390 {LIQUID_SOURCE, "source"},
393 struct EnumString es_NodeBoxType[] =
395 {NODEBOX_REGULAR, "regular"},
396 {NODEBOX_FIXED, "fixed"},
397 {NODEBOX_WALLMOUNTED, "wallmounted"},
400 struct EnumString es_Diggability[] =
402 {DIGGABLE_NOT, "not"},
403 {DIGGABLE_NORMAL, "normal"},
404 {DIGGABLE_CONSTANT, "constant"},
411 static int l_register_nodedef_defaults(lua_State *L)
413 luaL_checktype(L, 1, LUA_TTABLE);
415 lua_pushvalue(L, 1); // Explicitly put parameter 1 on top of stack
416 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
421 // Register new object prototype
422 // register_entity(name, prototype)
423 static int l_register_entity(lua_State *L)
425 const char *name = luaL_checkstring(L, 1);
426 infostream<<"register_entity: "<<name<<std::endl;
427 luaL_checktype(L, 2, LUA_TTABLE);
429 // Get minetest.registered_entities
430 lua_getglobal(L, "minetest");
431 lua_getfield(L, -1, "registered_entities");
432 luaL_checktype(L, -1, LUA_TTABLE);
433 int registered_entities = lua_gettop(L);
434 lua_pushvalue(L, 2); // Object = param 2 -> stack top
435 // registered_entities[name] = object
436 lua_setfield(L, registered_entities, name);
438 // Get registered object to top of stack
441 // Set __index to point to itself
442 lua_pushvalue(L, -1);
443 lua_setfield(L, -2, "__index");
445 // Set metatable.__index = metatable
446 luaL_getmetatable(L, "minetest.entity");
447 lua_pushvalue(L, -1); // duplicate metatable
448 lua_setfield(L, -2, "__index");
449 // Set object metatable
450 lua_setmetatable(L, -2);
452 return 0; /* number of results */
455 // register_tool(name, {lots of stuff})
456 static int l_register_tool(lua_State *L)
458 const char *name = luaL_checkstring(L, 1);
459 infostream<<"register_tool: "<<name<<std::endl;
460 luaL_checktype(L, 2, LUA_TTABLE);
463 // Get server from registry
464 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
465 Server *server = (Server*)lua_touserdata(L, -1);
466 // And get the writable tool definition manager from the server
467 IWritableToolDefManager *tooldef =
468 server->getWritableToolDefManager();
472 getstringfield(L, table, "image", def.imagename);
473 getfloatfield(L, table, "basetime", def.properties.basetime);
474 getfloatfield(L, table, "dt_weight", def.properties.dt_weight);
475 getfloatfield(L, table, "dt_crackiness", def.properties.dt_crackiness);
476 getfloatfield(L, table, "dt_crumbliness", def.properties.dt_crumbliness);
477 getfloatfield(L, table, "dt_cuttability", def.properties.dt_cuttability);
478 getfloatfield(L, table, "basedurability", def.properties.basedurability);
479 getfloatfield(L, table, "dd_weight", def.properties.dd_weight);
480 getfloatfield(L, table, "dd_crackiness", def.properties.dd_crackiness);
481 getfloatfield(L, table, "dd_crumbliness", def.properties.dd_crumbliness);
482 getfloatfield(L, table, "dd_cuttability", def.properties.dd_cuttability);
484 tooldef->registerTool(name, def);
485 return 0; /* number of results */
488 // register_node(name, {lots of stuff})
489 static int l_register_node(lua_State *L)
491 const char *name = luaL_checkstring(L, 1);
492 infostream<<"register_node: "<<name<<std::endl;
493 luaL_checktype(L, 2, LUA_TTABLE);
494 int nodedef_table = 2;
496 // Get server from registry
497 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
498 Server *server = (Server*)lua_touserdata(L, -1);
499 // And get the writable node definition manager from the server
500 IWritableNodeDefManager *nodedef =
501 server->getWritableNodeDefManager();
503 // Get default node definition from registry
504 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
505 int nodedef_default = lua_gettop(L);
508 Add to minetest.registered_nodes with default as metatable
511 // Get the node definition table given as parameter
512 lua_pushvalue(L, nodedef_table);
514 // Set __index to point to itself
515 lua_pushvalue(L, -1);
516 lua_setfield(L, -2, "__index");
518 // Set nodedef_default as metatable for the definition
519 lua_pushvalue(L, nodedef_default);
520 lua_setmetatable(L, nodedef_table);
522 // minetest.registered_nodes[name] = nodedef
523 lua_getglobal(L, "minetest");
524 lua_getfield(L, -1, "registered_nodes");
525 luaL_checktype(L, -1, LUA_TTABLE);
526 lua_pushstring(L, name);
527 lua_pushvalue(L, nodedef_table);
536 // Default to getting the corresponding NodeItem when dug
537 f.dug_item = std::string("NodeItem \"")+name+"\" 1";
539 // Default to unknown_block.png as all textures
540 f.setAllTextures("unknown_block.png");
543 Read definiton from Lua
548 /* Visual definition */
550 f.drawtype = (NodeDrawType)getenumfield(L, nodedef_table, "drawtype", es_DrawType,
552 getfloatfield(L, nodedef_table, "visual_scale", f.visual_scale);
554 lua_getfield(L, nodedef_table, "tile_images");
555 if(lua_istable(L, -1)){
556 int table = lua_gettop(L);
559 while(lua_next(L, table) != 0){
560 // key at index -2 and value at index -1
561 if(lua_isstring(L, -1))
562 f.tname_tiles[i] = lua_tostring(L, -1);
564 f.tname_tiles[i] = "";
565 // removes value, keeps key for next iteration
573 // Copy last value to all remaining textures
575 std::string lastname = f.tname_tiles[i-1];
577 f.tname_tiles[i] = lastname;
584 getstringfield(L, nodedef_table, "inventory_image", f.tname_inventory);
586 lua_getfield(L, nodedef_table, "special_materials");
587 if(lua_istable(L, -1)){
588 int table = lua_gettop(L);
591 while(lua_next(L, table) != 0){
592 // key at index -2 and value at index -1
593 int smtable = lua_gettop(L);
594 std::string tname = getstringfield_default(
595 L, smtable, "image", "");
596 bool backface_culling = getboolfield_default(
597 L, smtable, "backface_culling", true);
598 MaterialSpec mspec(tname, backface_culling);
599 f.setSpecialMaterial(i, mspec);
600 // removes value, keeps key for next iteration
611 f.alpha = getintfield_default(L, nodedef_table, "alpha", 255);
615 lua_getfield(L, nodedef_table, "post_effect_color");
616 if(!lua_isnil(L, -1))
617 f.post_effect_color = readARGB8(L, -1);
620 f.param_type = (ContentParamType)getenumfield(L, nodedef_table, "paramtype",
621 es_ContentParamType, CPT_NONE);
623 // True for all ground-like things like stone and mud, false for eg. trees
624 getboolfield(L, nodedef_table, "is_ground_content", f.is_ground_content);
625 getboolfield(L, nodedef_table, "light_propagates", f.light_propagates);
626 getboolfield(L, nodedef_table, "sunlight_propagates", f.sunlight_propagates);
627 // This is used for collision detection.
628 // Also for general solidness queries.
629 getboolfield(L, nodedef_table, "walkable", f.walkable);
630 // Player can point to these
631 getboolfield(L, nodedef_table, "pointable", f.pointable);
632 // Player can dig these
633 getboolfield(L, nodedef_table, "diggable", f.diggable);
634 // Player can climb these
635 getboolfield(L, nodedef_table, "climbable", f.climbable);
636 // Player can build on these
637 getboolfield(L, nodedef_table, "buildable_to", f.buildable_to);
638 // If true, param2 is set to direction when placed. Used for torches.
639 // NOTE: the direction format is quite inefficient and should be changed
640 getboolfield(L, nodedef_table, "wall_mounted", f.wall_mounted);
641 // Whether this content type often contains mineral.
642 // Used for texture atlas creation.
643 // Currently only enabled for CONTENT_STONE.
644 getboolfield(L, nodedef_table, "often_contains_mineral", f.often_contains_mineral);
645 // Inventory item string as which the node appears in inventory when dug.
646 // Mineral overrides this.
647 getstringfield(L, nodedef_table, "dug_item", f.dug_item);
648 // Extra dug item and its rarity
649 getstringfield(L, nodedef_table, "extra_dug_item", f.extra_dug_item);
650 // Usual get interval for extra dug item
651 getintfield(L, nodedef_table, "extra_dug_item_rarity", f.extra_dug_item_rarity);
652 // Metadata name of node (eg. "furnace")
653 getstringfield(L, nodedef_table, "metadata_name", f.metadata_name);
654 // Whether the node is non-liquid, source liquid or flowing liquid
655 f.liquid_type = (LiquidType)getenumfield(L, nodedef_table, "liquidtype",
656 es_LiquidType, LIQUID_NONE);
657 // If the content is liquid, this is the flowing version of the liquid.
658 getstringfield(L, nodedef_table, "liquid_alternative_flowing",
659 f.liquid_alternative_flowing);
660 // If the content is liquid, this is the source version of the liquid.
661 getstringfield(L, nodedef_table, "liquid_alternative_source",
662 f.liquid_alternative_source);
663 // Viscosity for fluid flow, ranging from 1 to 7, with
664 // 1 giving almost instantaneous propagation and 7 being
665 // the slowest possible
666 f.liquid_viscosity = getintfield_default(L, nodedef_table,
667 "liquid_viscosity", f.liquid_viscosity);
668 // Amount of light the node emits
669 f.light_source = getintfield_default(L, nodedef_table,
670 "light_source", f.light_source);
671 f.damage_per_second = getintfield_default(L, nodedef_table,
672 "damage_per_second", f.damage_per_second);
674 lua_getfield(L, nodedef_table, "selection_box");
675 if(lua_istable(L, -1)){
676 f.selection_box.type = (NodeBoxType)getenumfield(L, -1, "type",
677 es_NodeBoxType, NODEBOX_REGULAR);
679 lua_getfield(L, -1, "fixed");
680 if(lua_istable(L, -1))
681 f.selection_box.fixed = read_aabbox3df32(L, -1, BS);
684 lua_getfield(L, -1, "wall_top");
685 if(lua_istable(L, -1))
686 f.selection_box.wall_top = read_aabbox3df32(L, -1, BS);
689 lua_getfield(L, -1, "wall_bottom");
690 if(lua_istable(L, -1))
691 f.selection_box.wall_bottom = read_aabbox3df32(L, -1, BS);
694 lua_getfield(L, -1, "wall_side");
695 if(lua_istable(L, -1))
696 f.selection_box.wall_side = read_aabbox3df32(L, -1, BS);
701 lua_getfield(L, nodedef_table, "material");
702 if(lua_istable(L, -1)){
703 f.material.diggability = (Diggability)getenumfield(L, -1, "diggability",
704 es_Diggability, DIGGABLE_NORMAL);
706 getfloatfield(L, -1, "constant_time", f.material.constant_time);
707 getfloatfield(L, -1, "weight", f.material.weight);
708 getfloatfield(L, -1, "crackiness", f.material.crackiness);
709 getfloatfield(L, -1, "crumbliness", f.material.crumbliness);
710 getfloatfield(L, -1, "cuttability", f.material.cuttability);
711 getfloatfield(L, -1, "flammability", f.material.flammability);
715 getstringfield(L, nodedef_table, "cookresult_item", f.cookresult_item);
716 getfloatfield(L, nodedef_table, "furnace_cooktime", f.furnace_cooktime);
717 getfloatfield(L, nodedef_table, "furnace_burntime", f.furnace_burntime);
723 nodedef->set(name, f);
725 return 0; /* number of results */
728 // register_craft({output=item, recipe={{item00,item10},{item01,item11}})
729 static int l_register_craft(lua_State *L)
731 infostream<<"register_craft"<<std::endl;
732 luaL_checktype(L, 1, LUA_TTABLE);
735 // Get server from registry
736 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
737 Server *server = (Server*)lua_touserdata(L, -1);
738 // And get the writable craft definition manager from the server
739 IWritableCraftDefManager *craftdef =
740 server->getWritableCraftDefManager();
744 std::vector<std::string> input;
746 lua_getfield(L, table0, "output");
747 luaL_checktype(L, -1, LUA_TSTRING);
748 if(lua_isstring(L, -1))
749 output = lua_tostring(L, -1);
752 lua_getfield(L, table0, "recipe");
753 luaL_checktype(L, -1, LUA_TTABLE);
754 if(lua_istable(L, -1)){
755 int table1 = lua_gettop(L);
758 while(lua_next(L, table1) != 0){
760 // key at index -2 and value at index -1
761 luaL_checktype(L, -1, LUA_TTABLE);
762 if(lua_istable(L, -1)){
763 int table2 = lua_gettop(L);
765 while(lua_next(L, table2) != 0){
766 // key at index -2 and value at index -1
767 luaL_checktype(L, -1, LUA_TSTRING);
768 input.push_back(lua_tostring(L, -1));
769 // removes value, keeps key for next iteration
777 if(colcount != width){
778 script_error(L, "error: %s\n", "Invalid crafting recipe");
781 // removes value, keeps key for next iteration
788 CraftDefinition def(output, width, input);
789 craftdef->registerCraft(def);
791 return 0; /* number of results */
794 static int register_lua_callback(lua_State *L, const char *tablename)
796 luaL_checktype(L, 1, LUA_TFUNCTION);
798 lua_getglobal(L, "table");
799 lua_getfield(L, -1, "insert");
800 int table_insert = lua_gettop(L);
801 // Get minetest.registered_globalsteps
802 lua_getglobal(L, "minetest");
803 lua_getfield(L, -1, tablename);
804 luaL_checktype(L, -1, LUA_TTABLE);
805 int registered = lua_gettop(L);
806 // table.insert(registered_globalsteps, func)
807 lua_pushvalue(L, table_insert);
808 lua_pushvalue(L, registered);
809 lua_pushvalue(L, 1); // push function from argument 1
811 if(lua_pcall(L, 2, 0, 0))
812 script_error(L, "error: %s\n", lua_tostring(L, -1));
814 return 0; /* number of results */
817 // Register a global step function
818 // register_globalstep(function)
819 static int l_register_globalstep(lua_State *L)
821 infostream<<"register_globalstep"<<std::endl;
822 return register_lua_callback(L, "registered_globalsteps");
825 // register_on_placenode(function)
826 static int l_register_on_placenode(lua_State *L)
828 infostream<<"register_on_placenode"<<std::endl;
829 return register_lua_callback(L, "registered_on_placenodes");
832 // register_on_dignode(function)
833 static int l_register_on_dignode(lua_State *L)
835 infostream<<"register_on_dignode"<<std::endl;
836 return register_lua_callback(L, "registered_on_dignodes");
839 // register_on_punchnode(function)
840 static int l_register_on_punchnode(lua_State *L)
842 infostream<<"register_on_punchnode"<<std::endl;
843 return register_lua_callback(L, "registered_on_punchnodes");
846 // register_on_newplayer(function)
847 static int l_register_on_newplayer(lua_State *L)
849 infostream<<"register_on_newplayer"<<std::endl;
850 return register_lua_callback(L, "registered_on_newplayers");
853 // register_on_respawnplayer(function)
854 static int l_register_on_respawnplayer(lua_State *L)
856 infostream<<"register_on_respawnplayer"<<std::endl;
857 return register_lua_callback(L, "registered_on_respawnplayers");
861 static int l_setting_get(lua_State *L)
863 const char *name = luaL_checkstring(L, 1);
865 std::string value = g_settings->get(name);
866 lua_pushstring(L, value.c_str());
867 } catch(SettingNotFoundException &e){
873 // setting_getbool(name)
874 static int l_setting_getbool(lua_State *L)
876 const char *name = luaL_checkstring(L, 1);
878 bool value = g_settings->getBool(name);
879 lua_pushboolean(L, value);
880 } catch(SettingNotFoundException &e){
886 static const struct luaL_Reg minetest_f [] = {
887 {"register_nodedef_defaults", l_register_nodedef_defaults},
888 {"register_entity", l_register_entity},
889 {"register_tool", l_register_tool},
890 {"register_node", l_register_node},
891 {"register_craft", l_register_craft},
892 {"register_globalstep", l_register_globalstep},
893 {"register_on_placenode", l_register_on_placenode},
894 {"register_on_dignode", l_register_on_dignode},
895 {"register_on_punchnode", l_register_on_punchnode},
896 {"register_on_newplayer", l_register_on_newplayer},
897 {"register_on_respawnplayer", l_register_on_respawnplayer},
898 {"setting_get", l_setting_get},
899 {"setting_getbool", l_setting_getbool},
907 static const struct luaL_Reg minetest_entity_m [] = {
912 Getters for stuff in main tables
915 static void objectref_get(lua_State *L, u16 id)
917 // Get minetest.object_refs[i]
918 lua_getglobal(L, "minetest");
919 lua_getfield(L, -1, "object_refs");
920 luaL_checktype(L, -1, LUA_TTABLE);
921 lua_pushnumber(L, id);
923 lua_remove(L, -2); // object_refs
924 lua_remove(L, -2); // minetest
927 static void luaentity_get(lua_State *L, u16 id)
929 // Get minetest.luaentities[i]
930 lua_getglobal(L, "minetest");
931 lua_getfield(L, -1, "luaentities");
932 luaL_checktype(L, -1, LUA_TTABLE);
933 lua_pushnumber(L, id);
935 lua_remove(L, -2); // luaentities
936 lua_remove(L, -2); // minetest
942 #define method(class, name) {#name, class::l_##name}
947 ServerEnvironment *m_env;
949 static const char className[];
950 static const luaL_reg methods[];
952 static EnvRef *checkobject(lua_State *L, int narg)
954 luaL_checktype(L, narg, LUA_TUSERDATA);
955 void *ud = luaL_checkudata(L, narg, className);
956 if(!ud) luaL_typerror(L, narg, className);
957 return *(EnvRef**)ud; // unbox pointer
960 // Exported functions
962 // EnvRef:add_node(pos, node)
963 // pos = {x=num, y=num, z=num}
964 static int l_add_node(lua_State *L)
966 infostream<<"EnvRef::l_add_node()"<<std::endl;
967 EnvRef *o = checkobject(L, 1);
968 ServerEnvironment *env = o->m_env;
969 if(env == NULL) return 0;
971 v3s16 pos = readpos(L, 2);
973 MapNode n = readnode(L, 3, env->getGameDef()->ndef());
975 bool succeeded = env->getMap().addNodeWithEvent(pos, n);
976 lua_pushboolean(L, succeeded);
980 // EnvRef:remove_node(pos)
981 // pos = {x=num, y=num, z=num}
982 static int l_remove_node(lua_State *L)
984 infostream<<"EnvRef::l_remove_node()"<<std::endl;
985 EnvRef *o = checkobject(L, 1);
986 ServerEnvironment *env = o->m_env;
987 if(env == NULL) return 0;
989 v3s16 pos = readpos(L, 2);
991 bool succeeded = env->getMap().removeNodeWithEvent(pos);
992 lua_pushboolean(L, succeeded);
996 // EnvRef:get_node(pos)
997 // pos = {x=num, y=num, z=num}
998 static int l_get_node(lua_State *L)
1000 infostream<<"EnvRef::l_get_node()"<<std::endl;
1001 EnvRef *o = checkobject(L, 1);
1002 ServerEnvironment *env = o->m_env;
1003 if(env == NULL) return 0;
1005 v3s16 pos = readpos(L, 2);
1007 MapNode n = env->getMap().getNodeNoEx(pos);
1009 pushnode(L, n, env->getGameDef()->ndef());
1013 // EnvRef:add_luaentity(pos, entityname)
1014 // pos = {x=num, y=num, z=num}
1015 static int l_add_luaentity(lua_State *L)
1017 infostream<<"EnvRef::l_add_luaentity()"<<std::endl;
1018 EnvRef *o = checkobject(L, 1);
1019 ServerEnvironment *env = o->m_env;
1020 if(env == NULL) return 0;
1022 v3f pos = readFloatPos(L, 2);
1024 const char *name = lua_tostring(L, 3);
1026 ServerActiveObject *obj = new LuaEntitySAO(env, pos, name, "");
1027 env->addActiveObject(obj);
1031 static int gc_object(lua_State *L) {
1032 EnvRef *o = *(EnvRef **)(lua_touserdata(L, 1));
1038 EnvRef(ServerEnvironment *env):
1041 infostream<<"EnvRef created"<<std::endl;
1046 infostream<<"EnvRef destructing"<<std::endl;
1049 // Creates an EnvRef and leaves it on top of stack
1050 // Not callable from Lua; all references are created on the C side.
1051 static void create(lua_State *L, ServerEnvironment *env)
1053 EnvRef *o = new EnvRef(env);
1054 //infostream<<"EnvRef::create: o="<<o<<std::endl;
1055 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1056 luaL_getmetatable(L, className);
1057 lua_setmetatable(L, -2);
1060 static void set_null(lua_State *L)
1062 EnvRef *o = checkobject(L, -1);
1066 static void Register(lua_State *L)
1069 int methodtable = lua_gettop(L);
1070 luaL_newmetatable(L, className);
1071 int metatable = lua_gettop(L);
1073 lua_pushliteral(L, "__metatable");
1074 lua_pushvalue(L, methodtable);
1075 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
1077 lua_pushliteral(L, "__index");
1078 lua_pushvalue(L, methodtable);
1079 lua_settable(L, metatable);
1081 lua_pushliteral(L, "__gc");
1082 lua_pushcfunction(L, gc_object);
1083 lua_settable(L, metatable);
1085 lua_pop(L, 1); // drop metatable
1087 luaL_openlib(L, 0, methods, 0); // fill methodtable
1088 lua_pop(L, 1); // drop methodtable
1090 // Cannot be created from Lua
1091 //lua_register(L, className, create_object);
1094 const char EnvRef::className[] = "EnvRef";
1095 const luaL_reg EnvRef::methods[] = {
1096 method(EnvRef, add_node),
1097 method(EnvRef, remove_node),
1098 method(EnvRef, get_node),
1099 method(EnvRef, add_luaentity),
1106 ServerActiveObject *m_object;
1108 static const char className[];
1109 static const luaL_reg methods[];
1111 static ObjectRef *checkobject(lua_State *L, int narg)
1113 luaL_checktype(L, narg, LUA_TUSERDATA);
1114 void *ud = luaL_checkudata(L, narg, className);
1115 if(!ud) luaL_typerror(L, narg, className);
1116 return *(ObjectRef**)ud; // unbox pointer
1119 static ServerActiveObject* getobject(ObjectRef *ref)
1121 ServerActiveObject *co = ref->m_object;
1125 static LuaEntitySAO* getluaobject(ObjectRef *ref)
1127 ServerActiveObject *obj = getobject(ref);
1130 if(obj->getType() != ACTIVEOBJECT_TYPE_LUAENTITY)
1132 return (LuaEntitySAO*)obj;
1135 // Exported functions
1137 // garbage collector
1138 static int gc_object(lua_State *L) {
1139 ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
1140 //infostream<<"ObjectRef::gc_object: o="<<o<<std::endl;
1146 static int l_remove(lua_State *L)
1148 ObjectRef *ref = checkobject(L, 1);
1149 ServerActiveObject *co = getobject(ref);
1150 if(co == NULL) return 0;
1151 infostream<<"ObjectRef::l_remove(): id="<<co->getId()<<std::endl;
1152 co->m_removed = true;
1157 // returns: {x=num, y=num, z=num}
1158 static int l_getpos(lua_State *L)
1160 ObjectRef *ref = checkobject(L, 1);
1161 ServerActiveObject *co = getobject(ref);
1162 if(co == NULL) return 0;
1163 v3f pos = co->getBasePosition() / BS;
1165 lua_pushnumber(L, pos.X);
1166 lua_setfield(L, -2, "x");
1167 lua_pushnumber(L, pos.Y);
1168 lua_setfield(L, -2, "y");
1169 lua_pushnumber(L, pos.Z);
1170 lua_setfield(L, -2, "z");
1174 // setpos(self, pos)
1175 static int l_setpos(lua_State *L)
1177 ObjectRef *ref = checkobject(L, 1);
1178 //LuaEntitySAO *co = getluaobject(ref);
1179 ServerActiveObject *co = getobject(ref);
1180 if(co == NULL) return 0;
1182 v3f pos = readFloatPos(L, 2);
1188 // moveto(self, pos, continuous=false)
1189 static int l_moveto(lua_State *L)
1191 ObjectRef *ref = checkobject(L, 1);
1192 //LuaEntitySAO *co = getluaobject(ref);
1193 ServerActiveObject *co = getobject(ref);
1194 if(co == NULL) return 0;
1196 v3f pos = readFloatPos(L, 2);
1198 bool continuous = lua_toboolean(L, 3);
1200 co->moveTo(pos, continuous);
1204 // setvelocity(self, velocity)
1205 static int l_setvelocity(lua_State *L)
1207 ObjectRef *ref = checkobject(L, 1);
1208 LuaEntitySAO *co = getluaobject(ref);
1209 if(co == NULL) return 0;
1211 v3f pos = readFloatPos(L, 2);
1213 co->setVelocity(pos);
1217 // setacceleration(self, acceleration)
1218 static int l_setacceleration(lua_State *L)
1220 ObjectRef *ref = checkobject(L, 1);
1221 LuaEntitySAO *co = getluaobject(ref);
1222 if(co == NULL) return 0;
1224 v3f pos = readFloatPos(L, 2);
1226 co->setAcceleration(pos);
1230 // add_to_inventory(self, itemstring)
1231 // returns: true if item was added, false otherwise
1232 static int l_add_to_inventory(lua_State *L)
1234 ObjectRef *ref = checkobject(L, 1);
1235 luaL_checkstring(L, 2);
1236 ServerActiveObject *co = getobject(ref);
1237 if(co == NULL) return 0;
1239 const char *itemstring = lua_tostring(L, 2);
1240 infostream<<"ObjectRef::l_add_to_inventory(): id="<<co->getId()
1241 <<" itemstring=\""<<itemstring<<"\""<<std::endl;
1243 std::istringstream is(itemstring, std::ios::binary);
1244 ServerEnvironment *env = co->getEnv();
1246 IGameDef *gamedef = env->getGameDef();
1247 InventoryItem *item = InventoryItem::deSerialize(is, gamedef);
1248 infostream<<"item="<<env<<std::endl;
1249 bool fits = co->addToInventory(item);
1251 lua_pushboolean(L, fits);
1255 // settexturemod(self, mod)
1256 static int l_settexturemod(lua_State *L)
1258 ObjectRef *ref = checkobject(L, 1);
1259 LuaEntitySAO *co = getluaobject(ref);
1260 if(co == NULL) return 0;
1262 std::string mod = lua_tostring(L, 2);
1263 co->setTextureMod(mod);
1268 ObjectRef(ServerActiveObject *object):
1271 //infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
1277 infostream<<"ObjectRef destructing for id="
1278 <<m_object->getId()<<std::endl;
1280 infostream<<"ObjectRef destructing for id=unknown"<<std::endl;*/
1283 // Creates an ObjectRef and leaves it on top of stack
1284 // Not callable from Lua; all references are created on the C side.
1285 static void create(lua_State *L, ServerActiveObject *object)
1287 ObjectRef *o = new ObjectRef(object);
1288 //infostream<<"ObjectRef::create: o="<<o<<std::endl;
1289 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1290 luaL_getmetatable(L, className);
1291 lua_setmetatable(L, -2);
1294 static void set_null(lua_State *L)
1296 ObjectRef *o = checkobject(L, -1);
1300 static void Register(lua_State *L)
1303 int methodtable = lua_gettop(L);
1304 luaL_newmetatable(L, className);
1305 int metatable = lua_gettop(L);
1307 lua_pushliteral(L, "__metatable");
1308 lua_pushvalue(L, methodtable);
1309 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
1311 lua_pushliteral(L, "__index");
1312 lua_pushvalue(L, methodtable);
1313 lua_settable(L, metatable);
1315 lua_pushliteral(L, "__gc");
1316 lua_pushcfunction(L, gc_object);
1317 lua_settable(L, metatable);
1319 lua_pop(L, 1); // drop metatable
1321 luaL_openlib(L, 0, methods, 0); // fill methodtable
1322 lua_pop(L, 1); // drop methodtable
1324 // Cannot be created from Lua
1325 //lua_register(L, className, create_object);
1328 const char ObjectRef::className[] = "ObjectRef";
1329 const luaL_reg ObjectRef::methods[] = {
1330 method(ObjectRef, remove),
1331 method(ObjectRef, getpos),
1332 method(ObjectRef, setpos),
1333 method(ObjectRef, moveto),
1334 method(ObjectRef, setvelocity),
1335 method(ObjectRef, setacceleration),
1336 method(ObjectRef, add_to_inventory),
1337 method(ObjectRef, settexturemod),
1341 // Creates a new anonymous reference if id=0
1342 static void objectref_get_or_create(lua_State *L,
1343 ServerActiveObject *cobj)
1345 if(cobj->getId() == 0){
1346 ObjectRef::create(L, cobj);
1348 objectref_get(L, cobj->getId());
1353 Main export function
1356 void scriptapi_export(lua_State *L, Server *server)
1359 assert(lua_checkstack(L, 20));
1360 infostream<<"scriptapi_export"<<std::endl;
1361 StackUnroller stack_unroller(L);
1363 // Store server as light userdata in registry
1364 lua_pushlightuserdata(L, server);
1365 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_server");
1367 // Store nil as minetest_nodedef_defaults in registry
1369 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
1371 // Register global functions in table minetest
1373 luaL_register(L, NULL, minetest_f);
1374 lua_setglobal(L, "minetest");
1376 // Get the main minetest table
1377 lua_getglobal(L, "minetest");
1379 // Add tables to minetest
1382 lua_setfield(L, -2, "registered_nodes");
1384 lua_setfield(L, -2, "registered_entities");
1386 lua_setfield(L, -2, "registered_globalsteps");
1388 lua_setfield(L, -2, "registered_on_placenodes");
1390 lua_setfield(L, -2, "registered_on_dignodes");
1392 lua_setfield(L, -2, "registered_on_punchnodes");
1394 lua_setfield(L, -2, "registered_on_newplayers");
1396 lua_setfield(L, -2, "registered_on_respawnplayers");
1399 lua_setfield(L, -2, "object_refs");
1401 lua_setfield(L, -2, "luaentities");
1403 // Create entity prototype
1404 luaL_newmetatable(L, "minetest.entity");
1405 // metatable.__index = metatable
1406 lua_pushvalue(L, -1); // Duplicate metatable
1407 lua_setfield(L, -2, "__index");
1408 // Put functions in metatable
1409 luaL_register(L, NULL, minetest_entity_m);
1410 // Put other stuff in metatable
1412 // Environment C reference
1413 EnvRef::Register(L);
1415 // Object C reference
1416 ObjectRef::Register(L);
1419 void scriptapi_add_environment(lua_State *L, ServerEnvironment *env)
1422 assert(lua_checkstack(L, 20));
1423 infostream<<"scriptapi_add_environment"<<std::endl;
1424 StackUnroller stack_unroller(L);
1426 // Create EnvRef on stack
1427 EnvRef::create(L, env);
1428 int envref = lua_gettop(L);
1430 // minetest.env = envref
1431 lua_getglobal(L, "minetest");
1432 luaL_checktype(L, -1, LUA_TTABLE);
1433 lua_pushvalue(L, envref);
1434 lua_setfield(L, -2, "env");
1438 // Dump stack top with the dump2 function
1439 static void dump2(lua_State *L, const char *name)
1441 // Dump object (debug)
1442 lua_getglobal(L, "dump2");
1443 luaL_checktype(L, -1, LUA_TFUNCTION);
1444 lua_pushvalue(L, -2); // Get previous stack top as first parameter
1445 lua_pushstring(L, name);
1446 if(lua_pcall(L, 2, 0, 0))
1447 script_error(L, "error: %s\n", lua_tostring(L, -1));
1455 void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj)
1458 assert(lua_checkstack(L, 20));
1459 infostream<<"scriptapi_add_object_reference: id="<<cobj->getId()<<std::endl;
1460 StackUnroller stack_unroller(L);
1462 // Create object on stack
1463 ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack
1464 int object = lua_gettop(L);
1466 // Get minetest.object_refs table
1467 lua_getglobal(L, "minetest");
1468 lua_getfield(L, -1, "object_refs");
1469 luaL_checktype(L, -1, LUA_TTABLE);
1470 int objectstable = lua_gettop(L);
1472 // object_refs[id] = object
1473 lua_pushnumber(L, cobj->getId()); // Push id
1474 lua_pushvalue(L, object); // Copy object to top of stack
1475 lua_settable(L, objectstable);
1478 void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj)
1481 assert(lua_checkstack(L, 20));
1482 infostream<<"scriptapi_rm_object_reference: id="<<cobj->getId()<<std::endl;
1483 StackUnroller stack_unroller(L);
1485 // Get minetest.object_refs table
1486 lua_getglobal(L, "minetest");
1487 lua_getfield(L, -1, "object_refs");
1488 luaL_checktype(L, -1, LUA_TTABLE);
1489 int objectstable = lua_gettop(L);
1491 // Get object_refs[id]
1492 lua_pushnumber(L, cobj->getId()); // Push id
1493 lua_gettable(L, objectstable);
1494 // Set object reference to NULL
1495 ObjectRef::set_null(L);
1496 lua_pop(L, 1); // pop object
1498 // Set object_refs[id] = nil
1499 lua_pushnumber(L, cobj->getId()); // Push id
1501 lua_settable(L, objectstable);
1509 void scriptapi_on_newplayer(lua_State *L, ServerActiveObject *player)
1512 assert(lua_checkstack(L, 20));
1513 StackUnroller stack_unroller(L);
1515 // Get minetest.registered_on_newplayers
1516 lua_getglobal(L, "minetest");
1517 lua_getfield(L, -1, "registered_on_newplayers");
1518 luaL_checktype(L, -1, LUA_TTABLE);
1519 int table = lua_gettop(L);
1522 while(lua_next(L, table) != 0){
1523 // key at index -2 and value at index -1
1524 luaL_checktype(L, -1, LUA_TFUNCTION);
1526 objectref_get_or_create(L, player);
1527 if(lua_pcall(L, 1, 0, 0))
1528 script_error(L, "error: %s\n", lua_tostring(L, -1));
1529 // value removed, keep key for next iteration
1532 bool scriptapi_on_respawnplayer(lua_State *L, ServerActiveObject *player)
1535 assert(lua_checkstack(L, 20));
1536 StackUnroller stack_unroller(L);
1538 bool positioning_handled_by_some = false;
1540 // Get minetest.registered_on_respawnplayers
1541 lua_getglobal(L, "minetest");
1542 lua_getfield(L, -1, "registered_on_respawnplayers");
1543 luaL_checktype(L, -1, LUA_TTABLE);
1544 int table = lua_gettop(L);
1547 while(lua_next(L, table) != 0){
1548 // key at index -2 and value at index -1
1549 luaL_checktype(L, -1, LUA_TFUNCTION);
1551 objectref_get_or_create(L, player);
1552 if(lua_pcall(L, 1, 1, 0))
1553 script_error(L, "error: %s\n", lua_tostring(L, -1));
1554 bool positioning_handled = lua_toboolean(L, -1);
1556 if(positioning_handled)
1557 positioning_handled_by_some = true;
1558 // value removed, keep key for next iteration
1560 return positioning_handled_by_some;
1567 void scriptapi_environment_step(lua_State *L, float dtime)
1570 assert(lua_checkstack(L, 20));
1571 //infostream<<"scriptapi_environment_step"<<std::endl;
1572 StackUnroller stack_unroller(L);
1574 // Get minetest.registered_globalsteps
1575 lua_getglobal(L, "minetest");
1576 lua_getfield(L, -1, "registered_globalsteps");
1577 luaL_checktype(L, -1, LUA_TTABLE);
1578 int table = lua_gettop(L);
1581 while(lua_next(L, table) != 0){
1582 // key at index -2 and value at index -1
1583 luaL_checktype(L, -1, LUA_TFUNCTION);
1585 lua_pushnumber(L, dtime);
1586 if(lua_pcall(L, 1, 0, 0))
1587 script_error(L, "error: %s\n", lua_tostring(L, -1));
1588 // value removed, keep key for next iteration
1592 void scriptapi_environment_on_placenode(lua_State *L, v3s16 p, MapNode newnode,
1593 ServerActiveObject *placer)
1596 assert(lua_checkstack(L, 20));
1597 //infostream<<"scriptapi_environment_on_placenode"<<std::endl;
1598 StackUnroller stack_unroller(L);
1600 // Get server from registry
1601 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1602 Server *server = (Server*)lua_touserdata(L, -1);
1603 // And get the writable node definition manager from the server
1604 IWritableNodeDefManager *ndef =
1605 server->getWritableNodeDefManager();
1607 // Get minetest.registered_on_placenodes
1608 lua_getglobal(L, "minetest");
1609 lua_getfield(L, -1, "registered_on_placenodes");
1610 luaL_checktype(L, -1, LUA_TTABLE);
1611 int table = lua_gettop(L);
1614 while(lua_next(L, table) != 0){
1615 // key at index -2 and value at index -1
1616 luaL_checktype(L, -1, LUA_TFUNCTION);
1619 pushnode(L, newnode, ndef);
1620 objectref_get_or_create(L, placer);
1621 if(lua_pcall(L, 3, 0, 0))
1622 script_error(L, "error: %s\n", lua_tostring(L, -1));
1623 // value removed, keep key for next iteration
1627 void scriptapi_environment_on_dignode(lua_State *L, v3s16 p, MapNode oldnode,
1628 ServerActiveObject *digger)
1631 assert(lua_checkstack(L, 20));
1632 //infostream<<"scriptapi_environment_on_dignode"<<std::endl;
1633 StackUnroller stack_unroller(L);
1635 // Get server from registry
1636 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1637 Server *server = (Server*)lua_touserdata(L, -1);
1638 // And get the writable node definition manager from the server
1639 IWritableNodeDefManager *ndef =
1640 server->getWritableNodeDefManager();
1642 // Get minetest.registered_on_dignodes
1643 lua_getglobal(L, "minetest");
1644 lua_getfield(L, -1, "registered_on_dignodes");
1645 luaL_checktype(L, -1, LUA_TTABLE);
1646 int table = lua_gettop(L);
1649 while(lua_next(L, table) != 0){
1650 // key at index -2 and value at index -1
1651 luaL_checktype(L, -1, LUA_TFUNCTION);
1654 pushnode(L, oldnode, ndef);
1655 objectref_get_or_create(L, digger);
1656 if(lua_pcall(L, 3, 0, 0))
1657 script_error(L, "error: %s\n", lua_tostring(L, -1));
1658 // value removed, keep key for next iteration
1662 void scriptapi_environment_on_punchnode(lua_State *L, v3s16 p, MapNode node,
1663 ServerActiveObject *puncher)
1666 assert(lua_checkstack(L, 20));
1667 //infostream<<"scriptapi_environment_on_punchnode"<<std::endl;
1668 StackUnroller stack_unroller(L);
1670 // Get server from registry
1671 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1672 Server *server = (Server*)lua_touserdata(L, -1);
1673 // And get the writable node definition manager from the server
1674 IWritableNodeDefManager *ndef =
1675 server->getWritableNodeDefManager();
1677 // Get minetest.registered_on_punchnodes
1678 lua_getglobal(L, "minetest");
1679 lua_getfield(L, -1, "registered_on_punchnodes");
1680 luaL_checktype(L, -1, LUA_TTABLE);
1681 int table = lua_gettop(L);
1684 while(lua_next(L, table) != 0){
1685 // key at index -2 and value at index -1
1686 luaL_checktype(L, -1, LUA_TFUNCTION);
1689 pushnode(L, node, ndef);
1690 objectref_get_or_create(L, puncher);
1691 if(lua_pcall(L, 3, 0, 0))
1692 script_error(L, "error: %s\n", lua_tostring(L, -1));
1693 // value removed, keep key for next iteration
1701 bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
1702 const std::string &staticdata)
1705 assert(lua_checkstack(L, 20));
1706 infostream<<"scriptapi_luaentity_add: id="<<id<<" name=\""
1707 <<name<<"\""<<std::endl;
1708 StackUnroller stack_unroller(L);
1710 // Get minetest.registered_entities[name]
1711 lua_getglobal(L, "minetest");
1712 lua_getfield(L, -1, "registered_entities");
1713 luaL_checktype(L, -1, LUA_TTABLE);
1714 lua_pushstring(L, name);
1715 lua_gettable(L, -2);
1716 // Should be a table, which we will use as a prototype
1717 //luaL_checktype(L, -1, LUA_TTABLE);
1718 if(lua_type(L, -1) != LUA_TTABLE){
1719 errorstream<<"LuaEntity name \""<<name<<"\" not defined"<<std::endl;
1722 int prototype_table = lua_gettop(L);
1723 //dump2(L, "prototype_table");
1725 // Create entity object
1727 int object = lua_gettop(L);
1729 // Set object metatable
1730 lua_pushvalue(L, prototype_table);
1731 lua_setmetatable(L, -2);
1733 // Add object reference
1734 // This should be userdata with metatable ObjectRef
1735 objectref_get(L, id);
1736 luaL_checktype(L, -1, LUA_TUSERDATA);
1737 if(!luaL_checkudata(L, -1, "ObjectRef"))
1738 luaL_typerror(L, -1, "ObjectRef");
1739 lua_setfield(L, -2, "object");
1741 // minetest.luaentities[id] = object
1742 lua_getglobal(L, "minetest");
1743 lua_getfield(L, -1, "luaentities");
1744 luaL_checktype(L, -1, LUA_TTABLE);
1745 lua_pushnumber(L, id); // Push id
1746 lua_pushvalue(L, object); // Copy object to top of stack
1747 lua_settable(L, -3);
1749 // Get on_activate function
1750 lua_pushvalue(L, object);
1751 lua_getfield(L, -1, "on_activate");
1752 if(!lua_isnil(L, -1)){
1753 luaL_checktype(L, -1, LUA_TFUNCTION);
1754 lua_pushvalue(L, object); // self
1755 lua_pushlstring(L, staticdata.c_str(), staticdata.size());
1756 // Call with 2 arguments, 0 results
1757 if(lua_pcall(L, 2, 0, 0))
1758 script_error(L, "error running function %s:on_activate: %s\n",
1759 name, lua_tostring(L, -1));
1765 void scriptapi_luaentity_rm(lua_State *L, u16 id)
1768 assert(lua_checkstack(L, 20));
1769 infostream<<"scriptapi_luaentity_rm: id="<<id<<std::endl;
1771 // Get minetest.luaentities table
1772 lua_getglobal(L, "minetest");
1773 lua_getfield(L, -1, "luaentities");
1774 luaL_checktype(L, -1, LUA_TTABLE);
1775 int objectstable = lua_gettop(L);
1777 // Set luaentities[id] = nil
1778 lua_pushnumber(L, id); // Push id
1780 lua_settable(L, objectstable);
1782 lua_pop(L, 2); // pop luaentities, minetest
1785 std::string scriptapi_luaentity_get_staticdata(lua_State *L, u16 id)
1788 assert(lua_checkstack(L, 20));
1789 infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl;
1790 StackUnroller stack_unroller(L);
1792 // Get minetest.luaentities[id]
1793 luaentity_get(L, id);
1794 int object = lua_gettop(L);
1796 // Get get_staticdata function
1797 lua_pushvalue(L, object);
1798 lua_getfield(L, -1, "get_staticdata");
1799 if(lua_isnil(L, -1))
1802 luaL_checktype(L, -1, LUA_TFUNCTION);
1803 lua_pushvalue(L, object); // self
1804 // Call with 1 arguments, 1 results
1805 if(lua_pcall(L, 1, 1, 0))
1806 script_error(L, "error running function get_staticdata: %s\n",
1807 lua_tostring(L, -1));
1810 const char *s = lua_tolstring(L, -1, &len);
1811 return std::string(s, len);
1814 void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
1815 LuaEntityProperties *prop)
1818 assert(lua_checkstack(L, 20));
1819 infostream<<"scriptapi_luaentity_get_properties: id="<<id<<std::endl;
1820 StackUnroller stack_unroller(L);
1822 // Get minetest.luaentities[id]
1823 luaentity_get(L, id);
1824 //int object = lua_gettop(L);
1826 lua_getfield(L, -1, "physical");
1827 if(lua_isboolean(L, -1))
1828 prop->physical = lua_toboolean(L, -1);
1831 lua_getfield(L, -1, "weight");
1832 prop->weight = lua_tonumber(L, -1);
1835 lua_getfield(L, -1, "collisionbox");
1836 if(lua_istable(L, -1))
1837 prop->collisionbox = read_aabbox3df32(L, -1, 1.0);
1840 lua_getfield(L, -1, "visual");
1841 if(lua_isstring(L, -1))
1842 prop->visual = lua_tostring(L, -1);
1845 lua_getfield(L, -1, "textures");
1846 if(lua_istable(L, -1)){
1847 prop->textures.clear();
1848 int table = lua_gettop(L);
1850 while(lua_next(L, table) != 0){
1851 // key at index -2 and value at index -1
1852 if(lua_isstring(L, -1))
1853 prop->textures.push_back(lua_tostring(L, -1));
1855 prop->textures.push_back("");
1856 // removes value, keeps key for next iteration
1864 void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime)
1867 assert(lua_checkstack(L, 20));
1868 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
1869 StackUnroller stack_unroller(L);
1871 // Get minetest.luaentities[id]
1872 luaentity_get(L, id);
1873 int object = lua_gettop(L);
1874 // State: object is at top of stack
1875 // Get step function
1876 lua_getfield(L, -1, "on_step");
1877 if(lua_isnil(L, -1))
1879 luaL_checktype(L, -1, LUA_TFUNCTION);
1880 lua_pushvalue(L, object); // self
1881 lua_pushnumber(L, dtime); // dtime
1882 // Call with 2 arguments, 0 results
1883 if(lua_pcall(L, 2, 0, 0))
1884 script_error(L, "error running function 'on_step': %s\n", lua_tostring(L, -1));
1887 // Calls entity:on_punch(ObjectRef puncher)
1888 void scriptapi_luaentity_punch(lua_State *L, u16 id,
1889 ServerActiveObject *puncher)
1892 assert(lua_checkstack(L, 20));
1893 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
1894 StackUnroller stack_unroller(L);
1896 // Get minetest.luaentities[id]
1897 luaentity_get(L, id);
1898 int object = lua_gettop(L);
1899 // State: object is at top of stack
1901 lua_getfield(L, -1, "on_punch");
1902 if(lua_isnil(L, -1))
1904 luaL_checktype(L, -1, LUA_TFUNCTION);
1905 lua_pushvalue(L, object); // self
1906 objectref_get_or_create(L, puncher); // Clicker reference
1907 // Call with 2 arguments, 0 results
1908 if(lua_pcall(L, 2, 0, 0))
1909 script_error(L, "error running function 'on_punch': %s\n", lua_tostring(L, -1));
1912 // Calls entity:on_rightclick(ObjectRef clicker)
1913 void scriptapi_luaentity_rightclick(lua_State *L, u16 id,
1914 ServerActiveObject *clicker)
1917 assert(lua_checkstack(L, 20));
1918 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
1919 StackUnroller stack_unroller(L);
1921 // Get minetest.luaentities[id]
1922 luaentity_get(L, id);
1923 int object = lua_gettop(L);
1924 // State: object is at top of stack
1926 lua_getfield(L, -1, "on_rightclick");
1927 if(lua_isnil(L, -1))
1929 luaL_checktype(L, -1, LUA_TFUNCTION);
1930 lua_pushvalue(L, object); // self
1931 objectref_get_or_create(L, clicker); // Clicker reference
1932 // Call with 2 arguments, 0 results
1933 if(lua_pcall(L, 2, 0, 0))
1934 script_error(L, "error running function 'on_rightclick': %s\n", lua_tostring(L, -1));