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 pushFloatPos(lua_State *L, v3f p)
149 lua_pushnumber(L, p.X);
150 lua_setfield(L, -2, "x");
151 lua_pushnumber(L, p.Y);
152 lua_setfield(L, -2, "y");
153 lua_pushnumber(L, p.Z);
154 lua_setfield(L, -2, "z");
157 static void pushpos(lua_State *L, v3s16 p)
160 lua_pushnumber(L, p.X);
161 lua_setfield(L, -2, "x");
162 lua_pushnumber(L, p.Y);
163 lua_setfield(L, -2, "y");
164 lua_pushnumber(L, p.Z);
165 lua_setfield(L, -2, "z");
168 static v3s16 readpos(lua_State *L, int index)
170 // Correct rounding at <0
171 v3f pf = readFloatPos(L, index);
172 return floatToInt(pf, BS);
175 static void pushnode(lua_State *L, const MapNode &n, INodeDefManager *ndef)
178 lua_pushstring(L, ndef->get(n).name.c_str());
179 lua_setfield(L, -2, "name");
180 lua_pushnumber(L, n.getParam1());
181 lua_setfield(L, -2, "param1");
182 lua_pushnumber(L, n.getParam2());
183 lua_setfield(L, -2, "param2");
186 static MapNode readnode(lua_State *L, int index, INodeDefManager *ndef)
188 lua_getfield(L, index, "name");
189 const char *name = lua_tostring(L, -1);
192 lua_getfield(L, index, "param1");
196 param1 = lua_tonumber(L, -1);
199 lua_getfield(L, index, "param2");
203 param2 = lua_tonumber(L, -1);
205 return MapNode(ndef, name, param1, param2);
208 static video::SColor readARGB8(lua_State *L, int index)
211 luaL_checktype(L, index, LUA_TTABLE);
212 lua_getfield(L, index, "a");
213 if(lua_isnumber(L, -1))
214 color.setAlpha(lua_tonumber(L, -1));
216 lua_getfield(L, index, "r");
217 color.setRed(lua_tonumber(L, -1));
219 lua_getfield(L, index, "g");
220 color.setGreen(lua_tonumber(L, -1));
222 lua_getfield(L, index, "b");
223 color.setBlue(lua_tonumber(L, -1));
228 static core::aabbox3d<f32> read_aabbox3df32(lua_State *L, int index, f32 scale)
230 core::aabbox3d<f32> box;
231 if(lua_istable(L, -1)){
232 lua_rawgeti(L, -1, 1);
233 box.MinEdge.X = lua_tonumber(L, -1) * scale;
235 lua_rawgeti(L, -1, 2);
236 box.MinEdge.Y = lua_tonumber(L, -1) * scale;
238 lua_rawgeti(L, -1, 3);
239 box.MinEdge.Z = lua_tonumber(L, -1) * scale;
241 lua_rawgeti(L, -1, 4);
242 box.MaxEdge.X = lua_tonumber(L, -1) * scale;
244 lua_rawgeti(L, -1, 5);
245 box.MaxEdge.Y = lua_tonumber(L, -1) * scale;
247 lua_rawgeti(L, -1, 6);
248 box.MaxEdge.Z = lua_tonumber(L, -1) * scale;
254 static v2s16 read_v2s16(lua_State *L, int index)
257 luaL_checktype(L, index, LUA_TTABLE);
258 lua_getfield(L, index, "x");
259 p.X = lua_tonumber(L, -1);
261 lua_getfield(L, index, "y");
262 p.Y = lua_tonumber(L, -1);
267 static v2f read_v2f(lua_State *L, int index)
270 luaL_checktype(L, index, LUA_TTABLE);
271 lua_getfield(L, index, "x");
272 p.X = lua_tonumber(L, -1);
274 lua_getfield(L, index, "y");
275 p.Y = lua_tonumber(L, -1);
280 static bool getstringfield(lua_State *L, int table,
281 const char *fieldname, std::string &result)
283 lua_getfield(L, table, fieldname);
285 if(lua_isstring(L, -1)){
286 result = lua_tostring(L, -1);
293 static bool getintfield(lua_State *L, int table,
294 const char *fieldname, int &result)
296 lua_getfield(L, table, fieldname);
298 if(lua_isnumber(L, -1)){
299 result = lua_tonumber(L, -1);
306 static bool getfloatfield(lua_State *L, int table,
307 const char *fieldname, float &result)
309 lua_getfield(L, table, fieldname);
311 if(lua_isnumber(L, -1)){
312 result = lua_tonumber(L, -1);
319 static bool getboolfield(lua_State *L, int table,
320 const char *fieldname, bool &result)
322 lua_getfield(L, table, fieldname);
324 if(lua_isboolean(L, -1)){
325 result = lua_toboolean(L, -1);
332 static std::string getstringfield_default(lua_State *L, int table,
333 const char *fieldname, const std::string &default_)
335 std::string result = default_;
336 getstringfield(L, table, fieldname, result);
340 static int getintfield_default(lua_State *L, int table,
341 const char *fieldname, int default_)
343 int result = default_;
344 getintfield(L, table, fieldname, result);
348 /*static float getfloatfield_default(lua_State *L, int table,
349 const char *fieldname, float default_)
351 float result = default_;
352 getfloatfield(L, table, fieldname, result);
356 static bool getboolfield_default(lua_State *L, int table,
357 const char *fieldname, bool default_)
359 bool result = default_;
360 getboolfield(L, table, fieldname, result);
370 static bool string_to_enum(const EnumString *spec, int &result,
371 const std::string &str)
373 const EnumString *esp = spec;
375 if(str == std::string(esp->str)){
384 /*static bool enum_to_string(const EnumString *spec, std::string &result,
387 const EnumString *esp = spec;
398 static int getenumfield(lua_State *L, int table,
399 const char *fieldname, const EnumString *spec, int default_)
401 int result = default_;
402 string_to_enum(spec, result,
403 getstringfield_default(L, table, fieldname, ""));
407 struct EnumString es_DrawType[] =
409 {NDT_NORMAL, "normal"},
410 {NDT_AIRLIKE, "airlike"},
411 {NDT_LIQUID, "liquid"},
412 {NDT_FLOWINGLIQUID, "flowingliquid"},
413 {NDT_GLASSLIKE, "glasslike"},
414 {NDT_ALLFACES, "allfaces"},
415 {NDT_ALLFACES_OPTIONAL, "allfaces_optional"},
416 {NDT_TORCHLIKE, "torchlike"},
417 {NDT_SIGNLIKE, "signlike"},
418 {NDT_PLANTLIKE, "plantlike"},
419 {NDT_FENCELIKE, "fencelike"},
420 {NDT_RAILLIKE, "raillike"},
424 struct EnumString es_ContentParamType[] =
427 {CPT_LIGHT, "light"},
428 {CPT_MINERAL, "mineral"},
429 {CPT_FACEDIR_SIMPLE, "facedir_simple"},
432 struct EnumString es_LiquidType[] =
434 {LIQUID_NONE, "none"},
435 {LIQUID_FLOWING, "flowing"},
436 {LIQUID_SOURCE, "source"},
439 struct EnumString es_NodeBoxType[] =
441 {NODEBOX_REGULAR, "regular"},
442 {NODEBOX_FIXED, "fixed"},
443 {NODEBOX_WALLMOUNTED, "wallmounted"},
446 struct EnumString es_Diggability[] =
448 {DIGGABLE_NOT, "not"},
449 {DIGGABLE_NORMAL, "normal"},
450 {DIGGABLE_CONSTANT, "constant"},
457 static int l_register_nodedef_defaults(lua_State *L)
459 luaL_checktype(L, 1, LUA_TTABLE);
461 lua_pushvalue(L, 1); // Explicitly put parameter 1 on top of stack
462 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
467 // Register new object prototype
468 // register_entity(name, prototype)
469 static int l_register_entity(lua_State *L)
471 const char *name = luaL_checkstring(L, 1);
472 infostream<<"register_entity: "<<name<<std::endl;
473 luaL_checktype(L, 2, LUA_TTABLE);
475 // Get minetest.registered_entities
476 lua_getglobal(L, "minetest");
477 lua_getfield(L, -1, "registered_entities");
478 luaL_checktype(L, -1, LUA_TTABLE);
479 int registered_entities = lua_gettop(L);
480 lua_pushvalue(L, 2); // Object = param 2 -> stack top
481 // registered_entities[name] = object
482 lua_setfield(L, registered_entities, name);
484 // Get registered object to top of stack
487 // Set __index to point to itself
488 lua_pushvalue(L, -1);
489 lua_setfield(L, -2, "__index");
491 // Set metatable.__index = metatable
492 luaL_getmetatable(L, "minetest.entity");
493 lua_pushvalue(L, -1); // duplicate metatable
494 lua_setfield(L, -2, "__index");
495 // Set object metatable
496 lua_setmetatable(L, -2);
498 return 0; /* number of results */
501 // register_tool(name, {lots of stuff})
502 static int l_register_tool(lua_State *L)
504 const char *name = luaL_checkstring(L, 1);
505 infostream<<"register_tool: "<<name<<std::endl;
506 luaL_checktype(L, 2, LUA_TTABLE);
509 // Get server from registry
510 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
511 Server *server = (Server*)lua_touserdata(L, -1);
512 // And get the writable tool definition manager from the server
513 IWritableToolDefManager *tooldef =
514 server->getWritableToolDefManager();
518 getstringfield(L, table, "image", def.imagename);
519 getfloatfield(L, table, "basetime", def.properties.basetime);
520 getfloatfield(L, table, "dt_weight", def.properties.dt_weight);
521 getfloatfield(L, table, "dt_crackiness", def.properties.dt_crackiness);
522 getfloatfield(L, table, "dt_crumbliness", def.properties.dt_crumbliness);
523 getfloatfield(L, table, "dt_cuttability", def.properties.dt_cuttability);
524 getfloatfield(L, table, "basedurability", def.properties.basedurability);
525 getfloatfield(L, table, "dd_weight", def.properties.dd_weight);
526 getfloatfield(L, table, "dd_crackiness", def.properties.dd_crackiness);
527 getfloatfield(L, table, "dd_crumbliness", def.properties.dd_crumbliness);
528 getfloatfield(L, table, "dd_cuttability", def.properties.dd_cuttability);
530 tooldef->registerTool(name, def);
531 return 0; /* number of results */
534 // register_node(name, {lots of stuff})
535 static int l_register_node(lua_State *L)
537 const char *name = luaL_checkstring(L, 1);
538 infostream<<"register_node: "<<name<<std::endl;
539 luaL_checktype(L, 2, LUA_TTABLE);
540 int nodedef_table = 2;
542 // Get server from registry
543 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
544 Server *server = (Server*)lua_touserdata(L, -1);
545 // And get the writable node definition manager from the server
546 IWritableNodeDefManager *nodedef =
547 server->getWritableNodeDefManager();
549 // Get default node definition from registry
550 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
551 int nodedef_default = lua_gettop(L);
554 Add to minetest.registered_nodes with default as metatable
557 // Get the node definition table given as parameter
558 lua_pushvalue(L, nodedef_table);
560 // Set __index to point to itself
561 lua_pushvalue(L, -1);
562 lua_setfield(L, -2, "__index");
564 // Set nodedef_default as metatable for the definition
565 lua_pushvalue(L, nodedef_default);
566 lua_setmetatable(L, nodedef_table);
568 // minetest.registered_nodes[name] = nodedef
569 lua_getglobal(L, "minetest");
570 lua_getfield(L, -1, "registered_nodes");
571 luaL_checktype(L, -1, LUA_TTABLE);
572 lua_pushstring(L, name);
573 lua_pushvalue(L, nodedef_table);
582 // Default to getting the corresponding NodeItem when dug
583 f.dug_item = std::string("NodeItem \"")+name+"\" 1";
585 // Default to unknown_block.png as all textures
586 f.setAllTextures("unknown_block.png");
589 Read definiton from Lua
594 /* Visual definition */
596 f.drawtype = (NodeDrawType)getenumfield(L, nodedef_table, "drawtype", es_DrawType,
598 getfloatfield(L, nodedef_table, "visual_scale", f.visual_scale);
600 lua_getfield(L, nodedef_table, "tile_images");
601 if(lua_istable(L, -1)){
602 int table = lua_gettop(L);
605 while(lua_next(L, table) != 0){
606 // key at index -2 and value at index -1
607 if(lua_isstring(L, -1))
608 f.tname_tiles[i] = lua_tostring(L, -1);
610 f.tname_tiles[i] = "";
611 // removes value, keeps key for next iteration
619 // Copy last value to all remaining textures
621 std::string lastname = f.tname_tiles[i-1];
623 f.tname_tiles[i] = lastname;
630 getstringfield(L, nodedef_table, "inventory_image", f.tname_inventory);
632 lua_getfield(L, nodedef_table, "special_materials");
633 if(lua_istable(L, -1)){
634 int table = lua_gettop(L);
637 while(lua_next(L, table) != 0){
638 // key at index -2 and value at index -1
639 int smtable = lua_gettop(L);
640 std::string tname = getstringfield_default(
641 L, smtable, "image", "");
642 bool backface_culling = getboolfield_default(
643 L, smtable, "backface_culling", true);
644 MaterialSpec mspec(tname, backface_culling);
645 f.setSpecialMaterial(i, mspec);
646 // removes value, keeps key for next iteration
657 f.alpha = getintfield_default(L, nodedef_table, "alpha", 255);
661 lua_getfield(L, nodedef_table, "post_effect_color");
662 if(!lua_isnil(L, -1))
663 f.post_effect_color = readARGB8(L, -1);
666 f.param_type = (ContentParamType)getenumfield(L, nodedef_table, "paramtype",
667 es_ContentParamType, CPT_NONE);
669 // True for all ground-like things like stone and mud, false for eg. trees
670 getboolfield(L, nodedef_table, "is_ground_content", f.is_ground_content);
671 getboolfield(L, nodedef_table, "light_propagates", f.light_propagates);
672 getboolfield(L, nodedef_table, "sunlight_propagates", f.sunlight_propagates);
673 // This is used for collision detection.
674 // Also for general solidness queries.
675 getboolfield(L, nodedef_table, "walkable", f.walkable);
676 // Player can point to these
677 getboolfield(L, nodedef_table, "pointable", f.pointable);
678 // Player can dig these
679 getboolfield(L, nodedef_table, "diggable", f.diggable);
680 // Player can climb these
681 getboolfield(L, nodedef_table, "climbable", f.climbable);
682 // Player can build on these
683 getboolfield(L, nodedef_table, "buildable_to", f.buildable_to);
684 // If true, param2 is set to direction when placed. Used for torches.
685 // NOTE: the direction format is quite inefficient and should be changed
686 getboolfield(L, nodedef_table, "wall_mounted", f.wall_mounted);
687 // Whether this content type often contains mineral.
688 // Used for texture atlas creation.
689 // Currently only enabled for CONTENT_STONE.
690 getboolfield(L, nodedef_table, "often_contains_mineral", f.often_contains_mineral);
691 // Inventory item string as which the node appears in inventory when dug.
692 // Mineral overrides this.
693 getstringfield(L, nodedef_table, "dug_item", f.dug_item);
694 // Extra dug item and its rarity
695 getstringfield(L, nodedef_table, "extra_dug_item", f.extra_dug_item);
696 // Usual get interval for extra dug item
697 getintfield(L, nodedef_table, "extra_dug_item_rarity", f.extra_dug_item_rarity);
698 // Metadata name of node (eg. "furnace")
699 getstringfield(L, nodedef_table, "metadata_name", f.metadata_name);
700 // Whether the node is non-liquid, source liquid or flowing liquid
701 f.liquid_type = (LiquidType)getenumfield(L, nodedef_table, "liquidtype",
702 es_LiquidType, LIQUID_NONE);
703 // If the content is liquid, this is the flowing version of the liquid.
704 getstringfield(L, nodedef_table, "liquid_alternative_flowing",
705 f.liquid_alternative_flowing);
706 // If the content is liquid, this is the source version of the liquid.
707 getstringfield(L, nodedef_table, "liquid_alternative_source",
708 f.liquid_alternative_source);
709 // Viscosity for fluid flow, ranging from 1 to 7, with
710 // 1 giving almost instantaneous propagation and 7 being
711 // the slowest possible
712 f.liquid_viscosity = getintfield_default(L, nodedef_table,
713 "liquid_viscosity", f.liquid_viscosity);
714 // Amount of light the node emits
715 f.light_source = getintfield_default(L, nodedef_table,
716 "light_source", f.light_source);
717 f.damage_per_second = getintfield_default(L, nodedef_table,
718 "damage_per_second", f.damage_per_second);
720 lua_getfield(L, nodedef_table, "selection_box");
721 if(lua_istable(L, -1)){
722 f.selection_box.type = (NodeBoxType)getenumfield(L, -1, "type",
723 es_NodeBoxType, NODEBOX_REGULAR);
725 lua_getfield(L, -1, "fixed");
726 if(lua_istable(L, -1))
727 f.selection_box.fixed = read_aabbox3df32(L, -1, BS);
730 lua_getfield(L, -1, "wall_top");
731 if(lua_istable(L, -1))
732 f.selection_box.wall_top = read_aabbox3df32(L, -1, BS);
735 lua_getfield(L, -1, "wall_bottom");
736 if(lua_istable(L, -1))
737 f.selection_box.wall_bottom = read_aabbox3df32(L, -1, BS);
740 lua_getfield(L, -1, "wall_side");
741 if(lua_istable(L, -1))
742 f.selection_box.wall_side = read_aabbox3df32(L, -1, BS);
747 lua_getfield(L, nodedef_table, "material");
748 if(lua_istable(L, -1)){
749 f.material.diggability = (Diggability)getenumfield(L, -1, "diggability",
750 es_Diggability, DIGGABLE_NORMAL);
752 getfloatfield(L, -1, "constant_time", f.material.constant_time);
753 getfloatfield(L, -1, "weight", f.material.weight);
754 getfloatfield(L, -1, "crackiness", f.material.crackiness);
755 getfloatfield(L, -1, "crumbliness", f.material.crumbliness);
756 getfloatfield(L, -1, "cuttability", f.material.cuttability);
757 getfloatfield(L, -1, "flammability", f.material.flammability);
761 getstringfield(L, nodedef_table, "cookresult_item", f.cookresult_item);
762 getfloatfield(L, nodedef_table, "furnace_cooktime", f.furnace_cooktime);
763 getfloatfield(L, nodedef_table, "furnace_burntime", f.furnace_burntime);
769 nodedef->set(name, f);
771 return 0; /* number of results */
774 // register_craft({output=item, recipe={{item00,item10},{item01,item11}})
775 static int l_register_craft(lua_State *L)
777 infostream<<"register_craft"<<std::endl;
778 luaL_checktype(L, 1, LUA_TTABLE);
781 // Get server from registry
782 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
783 Server *server = (Server*)lua_touserdata(L, -1);
784 // And get the writable craft definition manager from the server
785 IWritableCraftDefManager *craftdef =
786 server->getWritableCraftDefManager();
790 std::vector<std::string> input;
792 lua_getfield(L, table0, "output");
793 luaL_checktype(L, -1, LUA_TSTRING);
794 if(lua_isstring(L, -1))
795 output = lua_tostring(L, -1);
798 lua_getfield(L, table0, "recipe");
799 luaL_checktype(L, -1, LUA_TTABLE);
800 if(lua_istable(L, -1)){
801 int table1 = lua_gettop(L);
804 while(lua_next(L, table1) != 0){
806 // key at index -2 and value at index -1
807 luaL_checktype(L, -1, LUA_TTABLE);
808 if(lua_istable(L, -1)){
809 int table2 = lua_gettop(L);
811 while(lua_next(L, table2) != 0){
812 // key at index -2 and value at index -1
813 luaL_checktype(L, -1, LUA_TSTRING);
814 input.push_back(lua_tostring(L, -1));
815 // removes value, keeps key for next iteration
823 if(colcount != width){
824 script_error(L, "error: %s\n", "Invalid crafting recipe");
827 // removes value, keeps key for next iteration
834 CraftDefinition def(output, width, input);
835 craftdef->registerCraft(def);
837 return 0; /* number of results */
840 static int register_lua_callback(lua_State *L, const char *tablename)
842 luaL_checktype(L, 1, LUA_TFUNCTION);
844 lua_getglobal(L, "table");
845 lua_getfield(L, -1, "insert");
846 int table_insert = lua_gettop(L);
847 // Get minetest.registered_globalsteps
848 lua_getglobal(L, "minetest");
849 lua_getfield(L, -1, tablename);
850 luaL_checktype(L, -1, LUA_TTABLE);
851 int registered = lua_gettop(L);
852 // table.insert(registered_globalsteps, func)
853 lua_pushvalue(L, table_insert);
854 lua_pushvalue(L, registered);
855 lua_pushvalue(L, 1); // push function from argument 1
857 if(lua_pcall(L, 2, 0, 0))
858 script_error(L, "error: %s\n", lua_tostring(L, -1));
860 return 0; /* number of results */
863 // Register a global step function
864 // register_globalstep(function)
865 static int l_register_globalstep(lua_State *L)
867 infostream<<"register_globalstep"<<std::endl;
868 return register_lua_callback(L, "registered_globalsteps");
871 // register_on_placenode(function)
872 static int l_register_on_placenode(lua_State *L)
874 infostream<<"register_on_placenode"<<std::endl;
875 return register_lua_callback(L, "registered_on_placenodes");
878 // register_on_dignode(function)
879 static int l_register_on_dignode(lua_State *L)
881 infostream<<"register_on_dignode"<<std::endl;
882 return register_lua_callback(L, "registered_on_dignodes");
885 // register_on_punchnode(function)
886 static int l_register_on_punchnode(lua_State *L)
888 infostream<<"register_on_punchnode"<<std::endl;
889 return register_lua_callback(L, "registered_on_punchnodes");
892 // register_on_generated(function)
893 static int l_register_on_generated(lua_State *L)
895 infostream<<"register_on_generated"<<std::endl;
896 return register_lua_callback(L, "registered_on_generateds");
899 // register_on_newplayer(function)
900 static int l_register_on_newplayer(lua_State *L)
902 infostream<<"register_on_newplayer"<<std::endl;
903 return register_lua_callback(L, "registered_on_newplayers");
906 // register_on_respawnplayer(function)
907 static int l_register_on_respawnplayer(lua_State *L)
909 infostream<<"register_on_respawnplayer"<<std::endl;
910 return register_lua_callback(L, "registered_on_respawnplayers");
914 static int l_setting_get(lua_State *L)
916 const char *name = luaL_checkstring(L, 1);
918 std::string value = g_settings->get(name);
919 lua_pushstring(L, value.c_str());
920 } catch(SettingNotFoundException &e){
926 // setting_getbool(name)
927 static int l_setting_getbool(lua_State *L)
929 const char *name = luaL_checkstring(L, 1);
931 bool value = g_settings->getBool(name);
932 lua_pushboolean(L, value);
933 } catch(SettingNotFoundException &e){
939 static const struct luaL_Reg minetest_f [] = {
940 {"register_nodedef_defaults", l_register_nodedef_defaults},
941 {"register_entity", l_register_entity},
942 {"register_tool", l_register_tool},
943 {"register_node", l_register_node},
944 {"register_craft", l_register_craft},
945 {"register_globalstep", l_register_globalstep},
946 {"register_on_placenode", l_register_on_placenode},
947 {"register_on_dignode", l_register_on_dignode},
948 {"register_on_punchnode", l_register_on_punchnode},
949 {"register_on_generated", l_register_on_generated},
950 {"register_on_newplayer", l_register_on_newplayer},
951 {"register_on_respawnplayer", l_register_on_respawnplayer},
952 {"setting_get", l_setting_get},
953 {"setting_getbool", l_setting_getbool},
961 static const struct luaL_Reg minetest_entity_m [] = {
966 Getters for stuff in main tables
969 static void objectref_get(lua_State *L, u16 id)
971 // Get minetest.object_refs[i]
972 lua_getglobal(L, "minetest");
973 lua_getfield(L, -1, "object_refs");
974 luaL_checktype(L, -1, LUA_TTABLE);
975 lua_pushnumber(L, id);
977 lua_remove(L, -2); // object_refs
978 lua_remove(L, -2); // minetest
981 static void luaentity_get(lua_State *L, u16 id)
983 // Get minetest.luaentities[i]
984 lua_getglobal(L, "minetest");
985 lua_getfield(L, -1, "luaentities");
986 luaL_checktype(L, -1, LUA_TTABLE);
987 lua_pushnumber(L, id);
989 lua_remove(L, -2); // luaentities
990 lua_remove(L, -2); // minetest
996 #define method(class, name) {#name, class::l_##name}
1001 ServerEnvironment *m_env;
1003 static const char className[];
1004 static const luaL_reg methods[];
1006 static EnvRef *checkobject(lua_State *L, int narg)
1008 luaL_checktype(L, narg, LUA_TUSERDATA);
1009 void *ud = luaL_checkudata(L, narg, className);
1010 if(!ud) luaL_typerror(L, narg, className);
1011 return *(EnvRef**)ud; // unbox pointer
1014 // Exported functions
1016 // EnvRef:add_node(pos, node)
1017 // pos = {x=num, y=num, z=num}
1018 static int l_add_node(lua_State *L)
1020 infostream<<"EnvRef::l_add_node()"<<std::endl;
1021 EnvRef *o = checkobject(L, 1);
1022 ServerEnvironment *env = o->m_env;
1023 if(env == NULL) return 0;
1025 v3s16 pos = readpos(L, 2);
1027 MapNode n = readnode(L, 3, env->getGameDef()->ndef());
1029 bool succeeded = env->getMap().addNodeWithEvent(pos, n);
1030 lua_pushboolean(L, succeeded);
1034 // EnvRef:remove_node(pos)
1035 // pos = {x=num, y=num, z=num}
1036 static int l_remove_node(lua_State *L)
1038 infostream<<"EnvRef::l_remove_node()"<<std::endl;
1039 EnvRef *o = checkobject(L, 1);
1040 ServerEnvironment *env = o->m_env;
1041 if(env == NULL) return 0;
1043 v3s16 pos = readpos(L, 2);
1045 bool succeeded = env->getMap().removeNodeWithEvent(pos);
1046 lua_pushboolean(L, succeeded);
1050 // EnvRef:get_node(pos)
1051 // pos = {x=num, y=num, z=num}
1052 static int l_get_node(lua_State *L)
1054 infostream<<"EnvRef::l_get_node()"<<std::endl;
1055 EnvRef *o = checkobject(L, 1);
1056 ServerEnvironment *env = o->m_env;
1057 if(env == NULL) return 0;
1059 v3s16 pos = readpos(L, 2);
1061 MapNode n = env->getMap().getNodeNoEx(pos);
1063 pushnode(L, n, env->getGameDef()->ndef());
1067 // EnvRef:add_luaentity(pos, entityname)
1068 // pos = {x=num, y=num, z=num}
1069 static int l_add_luaentity(lua_State *L)
1071 infostream<<"EnvRef::l_add_luaentity()"<<std::endl;
1072 EnvRef *o = checkobject(L, 1);
1073 ServerEnvironment *env = o->m_env;
1074 if(env == NULL) return 0;
1076 v3f pos = readFloatPos(L, 2);
1078 const char *name = lua_tostring(L, 3);
1080 ServerActiveObject *obj = new LuaEntitySAO(env, pos, name, "");
1081 env->addActiveObject(obj);
1085 static int gc_object(lua_State *L) {
1086 EnvRef *o = *(EnvRef **)(lua_touserdata(L, 1));
1092 EnvRef(ServerEnvironment *env):
1095 infostream<<"EnvRef created"<<std::endl;
1100 infostream<<"EnvRef destructing"<<std::endl;
1103 // Creates an EnvRef and leaves it on top of stack
1104 // Not callable from Lua; all references are created on the C side.
1105 static void create(lua_State *L, ServerEnvironment *env)
1107 EnvRef *o = new EnvRef(env);
1108 //infostream<<"EnvRef::create: o="<<o<<std::endl;
1109 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1110 luaL_getmetatable(L, className);
1111 lua_setmetatable(L, -2);
1114 static void set_null(lua_State *L)
1116 EnvRef *o = checkobject(L, -1);
1120 static void Register(lua_State *L)
1123 int methodtable = lua_gettop(L);
1124 luaL_newmetatable(L, className);
1125 int metatable = lua_gettop(L);
1127 lua_pushliteral(L, "__metatable");
1128 lua_pushvalue(L, methodtable);
1129 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
1131 lua_pushliteral(L, "__index");
1132 lua_pushvalue(L, methodtable);
1133 lua_settable(L, metatable);
1135 lua_pushliteral(L, "__gc");
1136 lua_pushcfunction(L, gc_object);
1137 lua_settable(L, metatable);
1139 lua_pop(L, 1); // drop metatable
1141 luaL_openlib(L, 0, methods, 0); // fill methodtable
1142 lua_pop(L, 1); // drop methodtable
1144 // Cannot be created from Lua
1145 //lua_register(L, className, create_object);
1148 const char EnvRef::className[] = "EnvRef";
1149 const luaL_reg EnvRef::methods[] = {
1150 method(EnvRef, add_node),
1151 method(EnvRef, remove_node),
1152 method(EnvRef, get_node),
1153 method(EnvRef, add_luaentity),
1160 ServerActiveObject *m_object;
1162 static const char className[];
1163 static const luaL_reg methods[];
1165 static ObjectRef *checkobject(lua_State *L, int narg)
1167 luaL_checktype(L, narg, LUA_TUSERDATA);
1168 void *ud = luaL_checkudata(L, narg, className);
1169 if(!ud) luaL_typerror(L, narg, className);
1170 return *(ObjectRef**)ud; // unbox pointer
1173 static ServerActiveObject* getobject(ObjectRef *ref)
1175 ServerActiveObject *co = ref->m_object;
1179 static LuaEntitySAO* getluaobject(ObjectRef *ref)
1181 ServerActiveObject *obj = getobject(ref);
1184 if(obj->getType() != ACTIVEOBJECT_TYPE_LUAENTITY)
1186 return (LuaEntitySAO*)obj;
1189 // Exported functions
1191 // garbage collector
1192 static int gc_object(lua_State *L) {
1193 ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
1194 //infostream<<"ObjectRef::gc_object: o="<<o<<std::endl;
1200 static int l_remove(lua_State *L)
1202 ObjectRef *ref = checkobject(L, 1);
1203 ServerActiveObject *co = getobject(ref);
1204 if(co == NULL) return 0;
1205 infostream<<"ObjectRef::l_remove(): id="<<co->getId()<<std::endl;
1206 co->m_removed = true;
1211 // returns: {x=num, y=num, z=num}
1212 static int l_getpos(lua_State *L)
1214 ObjectRef *ref = checkobject(L, 1);
1215 ServerActiveObject *co = getobject(ref);
1216 if(co == NULL) return 0;
1217 v3f pos = co->getBasePosition() / BS;
1219 lua_pushnumber(L, pos.X);
1220 lua_setfield(L, -2, "x");
1221 lua_pushnumber(L, pos.Y);
1222 lua_setfield(L, -2, "y");
1223 lua_pushnumber(L, pos.Z);
1224 lua_setfield(L, -2, "z");
1228 // setpos(self, pos)
1229 static int l_setpos(lua_State *L)
1231 ObjectRef *ref = checkobject(L, 1);
1232 //LuaEntitySAO *co = getluaobject(ref);
1233 ServerActiveObject *co = getobject(ref);
1234 if(co == NULL) return 0;
1236 v3f pos = readFloatPos(L, 2);
1242 // moveto(self, pos, continuous=false)
1243 static int l_moveto(lua_State *L)
1245 ObjectRef *ref = checkobject(L, 1);
1246 //LuaEntitySAO *co = getluaobject(ref);
1247 ServerActiveObject *co = getobject(ref);
1248 if(co == NULL) return 0;
1250 v3f pos = readFloatPos(L, 2);
1252 bool continuous = lua_toboolean(L, 3);
1254 co->moveTo(pos, continuous);
1258 // setvelocity(self, velocity)
1259 static int l_setvelocity(lua_State *L)
1261 ObjectRef *ref = checkobject(L, 1);
1262 LuaEntitySAO *co = getluaobject(ref);
1263 if(co == NULL) return 0;
1265 v3f pos = readFloatPos(L, 2);
1267 co->setVelocity(pos);
1271 // setacceleration(self, acceleration)
1272 static int l_setacceleration(lua_State *L)
1274 ObjectRef *ref = checkobject(L, 1);
1275 LuaEntitySAO *co = getluaobject(ref);
1276 if(co == NULL) return 0;
1278 v3f pos = readFloatPos(L, 2);
1280 co->setAcceleration(pos);
1284 // getacceleration(self)
1285 static int l_getacceleration(lua_State *L)
1287 ObjectRef *ref = checkobject(L, 1);
1288 LuaEntitySAO *co = getluaobject(ref);
1289 if(co == NULL) return 0;
1291 v3f v = co->getAcceleration();
1296 // add_to_inventory(self, itemstring)
1297 // returns: true if item was added, false otherwise
1298 static int l_add_to_inventory(lua_State *L)
1300 ObjectRef *ref = checkobject(L, 1);
1301 luaL_checkstring(L, 2);
1302 ServerActiveObject *co = getobject(ref);
1303 if(co == NULL) return 0;
1305 const char *itemstring = lua_tostring(L, 2);
1306 infostream<<"ObjectRef::l_add_to_inventory(): id="<<co->getId()
1307 <<" itemstring=\""<<itemstring<<"\""<<std::endl;
1309 std::istringstream is(itemstring, std::ios::binary);
1310 ServerEnvironment *env = co->getEnv();
1312 IGameDef *gamedef = env->getGameDef();
1313 InventoryItem *item = InventoryItem::deSerialize(is, gamedef);
1314 infostream<<"item="<<env<<std::endl;
1315 bool fits = co->addToInventory(item);
1317 lua_pushboolean(L, fits);
1321 // settexturemod(self, mod)
1322 static int l_settexturemod(lua_State *L)
1324 ObjectRef *ref = checkobject(L, 1);
1325 LuaEntitySAO *co = getluaobject(ref);
1326 if(co == NULL) return 0;
1328 std::string mod = lua_tostring(L, 2);
1329 co->setTextureMod(mod);
1333 // setsprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2,
1334 // select_horiz_by_yawpitch=false)
1335 static int l_setsprite(lua_State *L)
1337 ObjectRef *ref = checkobject(L, 1);
1338 LuaEntitySAO *co = getluaobject(ref);
1339 if(co == NULL) return 0;
1342 if(!lua_isnil(L, 2))
1343 p = read_v2s16(L, 2);
1345 if(!lua_isnil(L, 3))
1346 num_frames = lua_tonumber(L, 3);
1347 float framelength = 0.2;
1348 if(!lua_isnil(L, 4))
1349 framelength = lua_tonumber(L, 4);
1350 bool select_horiz_by_yawpitch = false;
1351 if(!lua_isnil(L, 5))
1352 select_horiz_by_yawpitch = lua_toboolean(L, 5);
1353 co->setSprite(p, num_frames, framelength, select_horiz_by_yawpitch);
1358 ObjectRef(ServerActiveObject *object):
1361 //infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
1367 infostream<<"ObjectRef destructing for id="
1368 <<m_object->getId()<<std::endl;
1370 infostream<<"ObjectRef destructing for id=unknown"<<std::endl;*/
1373 // Creates an ObjectRef and leaves it on top of stack
1374 // Not callable from Lua; all references are created on the C side.
1375 static void create(lua_State *L, ServerActiveObject *object)
1377 ObjectRef *o = new ObjectRef(object);
1378 //infostream<<"ObjectRef::create: o="<<o<<std::endl;
1379 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1380 luaL_getmetatable(L, className);
1381 lua_setmetatable(L, -2);
1384 static void set_null(lua_State *L)
1386 ObjectRef *o = checkobject(L, -1);
1390 static void Register(lua_State *L)
1393 int methodtable = lua_gettop(L);
1394 luaL_newmetatable(L, className);
1395 int metatable = lua_gettop(L);
1397 lua_pushliteral(L, "__metatable");
1398 lua_pushvalue(L, methodtable);
1399 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
1401 lua_pushliteral(L, "__index");
1402 lua_pushvalue(L, methodtable);
1403 lua_settable(L, metatable);
1405 lua_pushliteral(L, "__gc");
1406 lua_pushcfunction(L, gc_object);
1407 lua_settable(L, metatable);
1409 lua_pop(L, 1); // drop metatable
1411 luaL_openlib(L, 0, methods, 0); // fill methodtable
1412 lua_pop(L, 1); // drop methodtable
1414 // Cannot be created from Lua
1415 //lua_register(L, className, create_object);
1418 const char ObjectRef::className[] = "ObjectRef";
1419 const luaL_reg ObjectRef::methods[] = {
1420 method(ObjectRef, remove),
1421 method(ObjectRef, getpos),
1422 method(ObjectRef, setpos),
1423 method(ObjectRef, moveto),
1424 method(ObjectRef, setvelocity),
1425 method(ObjectRef, setacceleration),
1426 method(ObjectRef, add_to_inventory),
1427 method(ObjectRef, settexturemod),
1428 method(ObjectRef, setsprite),
1432 // Creates a new anonymous reference if id=0
1433 static void objectref_get_or_create(lua_State *L,
1434 ServerActiveObject *cobj)
1436 if(cobj->getId() == 0){
1437 ObjectRef::create(L, cobj);
1439 objectref_get(L, cobj->getId());
1444 Main export function
1447 void scriptapi_export(lua_State *L, Server *server)
1450 assert(lua_checkstack(L, 20));
1451 infostream<<"scriptapi_export"<<std::endl;
1452 StackUnroller stack_unroller(L);
1454 // Store server as light userdata in registry
1455 lua_pushlightuserdata(L, server);
1456 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_server");
1458 // Store nil as minetest_nodedef_defaults in registry
1460 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
1462 // Register global functions in table minetest
1464 luaL_register(L, NULL, minetest_f);
1465 lua_setglobal(L, "minetest");
1467 // Get the main minetest table
1468 lua_getglobal(L, "minetest");
1470 // Add tables to minetest
1473 lua_setfield(L, -2, "registered_nodes");
1475 lua_setfield(L, -2, "registered_entities");
1477 lua_setfield(L, -2, "registered_globalsteps");
1479 lua_setfield(L, -2, "registered_on_placenodes");
1481 lua_setfield(L, -2, "registered_on_dignodes");
1483 lua_setfield(L, -2, "registered_on_punchnodes");
1485 lua_setfield(L, -2, "registered_on_generateds");
1487 lua_setfield(L, -2, "registered_on_newplayers");
1489 lua_setfield(L, -2, "registered_on_respawnplayers");
1492 lua_setfield(L, -2, "object_refs");
1494 lua_setfield(L, -2, "luaentities");
1496 // Create entity prototype
1497 luaL_newmetatable(L, "minetest.entity");
1498 // metatable.__index = metatable
1499 lua_pushvalue(L, -1); // Duplicate metatable
1500 lua_setfield(L, -2, "__index");
1501 // Put functions in metatable
1502 luaL_register(L, NULL, minetest_entity_m);
1503 // Put other stuff in metatable
1505 // Environment C reference
1506 EnvRef::Register(L);
1508 // Object C reference
1509 ObjectRef::Register(L);
1512 void scriptapi_add_environment(lua_State *L, ServerEnvironment *env)
1515 assert(lua_checkstack(L, 20));
1516 infostream<<"scriptapi_add_environment"<<std::endl;
1517 StackUnroller stack_unroller(L);
1519 // Create EnvRef on stack
1520 EnvRef::create(L, env);
1521 int envref = lua_gettop(L);
1523 // minetest.env = envref
1524 lua_getglobal(L, "minetest");
1525 luaL_checktype(L, -1, LUA_TTABLE);
1526 lua_pushvalue(L, envref);
1527 lua_setfield(L, -2, "env");
1531 // Dump stack top with the dump2 function
1532 static void dump2(lua_State *L, const char *name)
1534 // Dump object (debug)
1535 lua_getglobal(L, "dump2");
1536 luaL_checktype(L, -1, LUA_TFUNCTION);
1537 lua_pushvalue(L, -2); // Get previous stack top as first parameter
1538 lua_pushstring(L, name);
1539 if(lua_pcall(L, 2, 0, 0))
1540 script_error(L, "error: %s\n", lua_tostring(L, -1));
1548 void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj)
1551 assert(lua_checkstack(L, 20));
1552 infostream<<"scriptapi_add_object_reference: id="<<cobj->getId()<<std::endl;
1553 StackUnroller stack_unroller(L);
1555 // Create object on stack
1556 ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack
1557 int object = lua_gettop(L);
1559 // Get minetest.object_refs table
1560 lua_getglobal(L, "minetest");
1561 lua_getfield(L, -1, "object_refs");
1562 luaL_checktype(L, -1, LUA_TTABLE);
1563 int objectstable = lua_gettop(L);
1565 // object_refs[id] = object
1566 lua_pushnumber(L, cobj->getId()); // Push id
1567 lua_pushvalue(L, object); // Copy object to top of stack
1568 lua_settable(L, objectstable);
1571 void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj)
1574 assert(lua_checkstack(L, 20));
1575 infostream<<"scriptapi_rm_object_reference: id="<<cobj->getId()<<std::endl;
1576 StackUnroller stack_unroller(L);
1578 // Get minetest.object_refs table
1579 lua_getglobal(L, "minetest");
1580 lua_getfield(L, -1, "object_refs");
1581 luaL_checktype(L, -1, LUA_TTABLE);
1582 int objectstable = lua_gettop(L);
1584 // Get object_refs[id]
1585 lua_pushnumber(L, cobj->getId()); // Push id
1586 lua_gettable(L, objectstable);
1587 // Set object reference to NULL
1588 ObjectRef::set_null(L);
1589 lua_pop(L, 1); // pop object
1591 // Set object_refs[id] = nil
1592 lua_pushnumber(L, cobj->getId()); // Push id
1594 lua_settable(L, objectstable);
1602 void scriptapi_on_newplayer(lua_State *L, ServerActiveObject *player)
1605 assert(lua_checkstack(L, 20));
1606 StackUnroller stack_unroller(L);
1608 // Get minetest.registered_on_newplayers
1609 lua_getglobal(L, "minetest");
1610 lua_getfield(L, -1, "registered_on_newplayers");
1611 luaL_checktype(L, -1, LUA_TTABLE);
1612 int table = lua_gettop(L);
1615 while(lua_next(L, table) != 0){
1616 // key at index -2 and value at index -1
1617 luaL_checktype(L, -1, LUA_TFUNCTION);
1619 objectref_get_or_create(L, player);
1620 if(lua_pcall(L, 1, 0, 0))
1621 script_error(L, "error: %s\n", lua_tostring(L, -1));
1622 // value removed, keep key for next iteration
1625 bool scriptapi_on_respawnplayer(lua_State *L, ServerActiveObject *player)
1628 assert(lua_checkstack(L, 20));
1629 StackUnroller stack_unroller(L);
1631 bool positioning_handled_by_some = false;
1633 // Get minetest.registered_on_respawnplayers
1634 lua_getglobal(L, "minetest");
1635 lua_getfield(L, -1, "registered_on_respawnplayers");
1636 luaL_checktype(L, -1, LUA_TTABLE);
1637 int table = lua_gettop(L);
1640 while(lua_next(L, table) != 0){
1641 // key at index -2 and value at index -1
1642 luaL_checktype(L, -1, LUA_TFUNCTION);
1644 objectref_get_or_create(L, player);
1645 if(lua_pcall(L, 1, 1, 0))
1646 script_error(L, "error: %s\n", lua_tostring(L, -1));
1647 bool positioning_handled = lua_toboolean(L, -1);
1649 if(positioning_handled)
1650 positioning_handled_by_some = true;
1651 // value removed, keep key for next iteration
1653 return positioning_handled_by_some;
1660 void scriptapi_environment_step(lua_State *L, float dtime)
1663 assert(lua_checkstack(L, 20));
1664 //infostream<<"scriptapi_environment_step"<<std::endl;
1665 StackUnroller stack_unroller(L);
1667 // Get minetest.registered_globalsteps
1668 lua_getglobal(L, "minetest");
1669 lua_getfield(L, -1, "registered_globalsteps");
1670 luaL_checktype(L, -1, LUA_TTABLE);
1671 int table = lua_gettop(L);
1674 while(lua_next(L, table) != 0){
1675 // key at index -2 and value at index -1
1676 luaL_checktype(L, -1, LUA_TFUNCTION);
1678 lua_pushnumber(L, dtime);
1679 if(lua_pcall(L, 1, 0, 0))
1680 script_error(L, "error: %s\n", lua_tostring(L, -1));
1681 // value removed, keep key for next iteration
1685 void scriptapi_environment_on_placenode(lua_State *L, v3s16 p, MapNode newnode,
1686 ServerActiveObject *placer)
1689 assert(lua_checkstack(L, 20));
1690 //infostream<<"scriptapi_environment_on_placenode"<<std::endl;
1691 StackUnroller stack_unroller(L);
1693 // Get server from registry
1694 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1695 Server *server = (Server*)lua_touserdata(L, -1);
1696 // And get the writable node definition manager from the server
1697 IWritableNodeDefManager *ndef =
1698 server->getWritableNodeDefManager();
1700 // Get minetest.registered_on_placenodes
1701 lua_getglobal(L, "minetest");
1702 lua_getfield(L, -1, "registered_on_placenodes");
1703 luaL_checktype(L, -1, LUA_TTABLE);
1704 int table = lua_gettop(L);
1707 while(lua_next(L, table) != 0){
1708 // key at index -2 and value at index -1
1709 luaL_checktype(L, -1, LUA_TFUNCTION);
1712 pushnode(L, newnode, ndef);
1713 objectref_get_or_create(L, placer);
1714 if(lua_pcall(L, 3, 0, 0))
1715 script_error(L, "error: %s\n", lua_tostring(L, -1));
1716 // value removed, keep key for next iteration
1720 void scriptapi_environment_on_dignode(lua_State *L, v3s16 p, MapNode oldnode,
1721 ServerActiveObject *digger)
1724 assert(lua_checkstack(L, 20));
1725 //infostream<<"scriptapi_environment_on_dignode"<<std::endl;
1726 StackUnroller stack_unroller(L);
1728 // Get server from registry
1729 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1730 Server *server = (Server*)lua_touserdata(L, -1);
1731 // And get the writable node definition manager from the server
1732 IWritableNodeDefManager *ndef =
1733 server->getWritableNodeDefManager();
1735 // Get minetest.registered_on_dignodes
1736 lua_getglobal(L, "minetest");
1737 lua_getfield(L, -1, "registered_on_dignodes");
1738 luaL_checktype(L, -1, LUA_TTABLE);
1739 int table = lua_gettop(L);
1742 while(lua_next(L, table) != 0){
1743 // key at index -2 and value at index -1
1744 luaL_checktype(L, -1, LUA_TFUNCTION);
1747 pushnode(L, oldnode, ndef);
1748 objectref_get_or_create(L, digger);
1749 if(lua_pcall(L, 3, 0, 0))
1750 script_error(L, "error: %s\n", lua_tostring(L, -1));
1751 // value removed, keep key for next iteration
1755 void scriptapi_environment_on_punchnode(lua_State *L, v3s16 p, MapNode node,
1756 ServerActiveObject *puncher)
1759 assert(lua_checkstack(L, 20));
1760 //infostream<<"scriptapi_environment_on_punchnode"<<std::endl;
1761 StackUnroller stack_unroller(L);
1763 // Get server from registry
1764 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1765 Server *server = (Server*)lua_touserdata(L, -1);
1766 // And get the writable node definition manager from the server
1767 IWritableNodeDefManager *ndef =
1768 server->getWritableNodeDefManager();
1770 // Get minetest.registered_on_punchnodes
1771 lua_getglobal(L, "minetest");
1772 lua_getfield(L, -1, "registered_on_punchnodes");
1773 luaL_checktype(L, -1, LUA_TTABLE);
1774 int table = lua_gettop(L);
1777 while(lua_next(L, table) != 0){
1778 // key at index -2 and value at index -1
1779 luaL_checktype(L, -1, LUA_TFUNCTION);
1782 pushnode(L, node, ndef);
1783 objectref_get_or_create(L, puncher);
1784 if(lua_pcall(L, 3, 0, 0))
1785 script_error(L, "error: %s\n", lua_tostring(L, -1));
1786 // value removed, keep key for next iteration
1790 void scriptapi_environment_on_generated(lua_State *L, v3s16 minp, v3s16 maxp)
1793 assert(lua_checkstack(L, 20));
1794 infostream<<"scriptapi_environment_on_generated"<<std::endl;
1795 StackUnroller stack_unroller(L);
1797 // Get minetest.registered_on_generateds
1798 lua_getglobal(L, "minetest");
1799 lua_getfield(L, -1, "registered_on_generateds");
1800 luaL_checktype(L, -1, LUA_TTABLE);
1801 int table = lua_gettop(L);
1804 while(lua_next(L, table) != 0){
1805 // key at index -2 and value at index -1
1806 luaL_checktype(L, -1, LUA_TFUNCTION);
1810 if(lua_pcall(L, 2, 0, 0))
1811 script_error(L, "error: %s\n", lua_tostring(L, -1));
1812 // value removed, keep key for next iteration
1820 bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
1821 const std::string &staticdata)
1824 assert(lua_checkstack(L, 20));
1825 infostream<<"scriptapi_luaentity_add: id="<<id<<" name=\""
1826 <<name<<"\""<<std::endl;
1827 StackUnroller stack_unroller(L);
1829 // Get minetest.registered_entities[name]
1830 lua_getglobal(L, "minetest");
1831 lua_getfield(L, -1, "registered_entities");
1832 luaL_checktype(L, -1, LUA_TTABLE);
1833 lua_pushstring(L, name);
1834 lua_gettable(L, -2);
1835 // Should be a table, which we will use as a prototype
1836 //luaL_checktype(L, -1, LUA_TTABLE);
1837 if(lua_type(L, -1) != LUA_TTABLE){
1838 errorstream<<"LuaEntity name \""<<name<<"\" not defined"<<std::endl;
1841 int prototype_table = lua_gettop(L);
1842 //dump2(L, "prototype_table");
1844 // Create entity object
1846 int object = lua_gettop(L);
1848 // Set object metatable
1849 lua_pushvalue(L, prototype_table);
1850 lua_setmetatable(L, -2);
1852 // Add object reference
1853 // This should be userdata with metatable ObjectRef
1854 objectref_get(L, id);
1855 luaL_checktype(L, -1, LUA_TUSERDATA);
1856 if(!luaL_checkudata(L, -1, "ObjectRef"))
1857 luaL_typerror(L, -1, "ObjectRef");
1858 lua_setfield(L, -2, "object");
1860 // minetest.luaentities[id] = object
1861 lua_getglobal(L, "minetest");
1862 lua_getfield(L, -1, "luaentities");
1863 luaL_checktype(L, -1, LUA_TTABLE);
1864 lua_pushnumber(L, id); // Push id
1865 lua_pushvalue(L, object); // Copy object to top of stack
1866 lua_settable(L, -3);
1868 // Get on_activate function
1869 lua_pushvalue(L, object);
1870 lua_getfield(L, -1, "on_activate");
1871 if(!lua_isnil(L, -1)){
1872 luaL_checktype(L, -1, LUA_TFUNCTION);
1873 lua_pushvalue(L, object); // self
1874 lua_pushlstring(L, staticdata.c_str(), staticdata.size());
1875 // Call with 2 arguments, 0 results
1876 if(lua_pcall(L, 2, 0, 0))
1877 script_error(L, "error running function %s:on_activate: %s\n",
1878 name, lua_tostring(L, -1));
1884 void scriptapi_luaentity_rm(lua_State *L, u16 id)
1887 assert(lua_checkstack(L, 20));
1888 infostream<<"scriptapi_luaentity_rm: id="<<id<<std::endl;
1890 // Get minetest.luaentities table
1891 lua_getglobal(L, "minetest");
1892 lua_getfield(L, -1, "luaentities");
1893 luaL_checktype(L, -1, LUA_TTABLE);
1894 int objectstable = lua_gettop(L);
1896 // Set luaentities[id] = nil
1897 lua_pushnumber(L, id); // Push id
1899 lua_settable(L, objectstable);
1901 lua_pop(L, 2); // pop luaentities, minetest
1904 std::string scriptapi_luaentity_get_staticdata(lua_State *L, u16 id)
1907 assert(lua_checkstack(L, 20));
1908 infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl;
1909 StackUnroller stack_unroller(L);
1911 // Get minetest.luaentities[id]
1912 luaentity_get(L, id);
1913 int object = lua_gettop(L);
1915 // Get get_staticdata function
1916 lua_pushvalue(L, object);
1917 lua_getfield(L, -1, "get_staticdata");
1918 if(lua_isnil(L, -1))
1921 luaL_checktype(L, -1, LUA_TFUNCTION);
1922 lua_pushvalue(L, object); // self
1923 // Call with 1 arguments, 1 results
1924 if(lua_pcall(L, 1, 1, 0))
1925 script_error(L, "error running function get_staticdata: %s\n",
1926 lua_tostring(L, -1));
1929 const char *s = lua_tolstring(L, -1, &len);
1930 return std::string(s, len);
1933 void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
1934 LuaEntityProperties *prop)
1937 assert(lua_checkstack(L, 20));
1938 infostream<<"scriptapi_luaentity_get_properties: id="<<id<<std::endl;
1939 StackUnroller stack_unroller(L);
1941 // Get minetest.luaentities[id]
1942 luaentity_get(L, id);
1943 //int object = lua_gettop(L);
1947 getboolfield(L, -1, "physical", prop->physical);
1949 getfloatfield(L, -1, "weight", prop->weight);
1951 lua_getfield(L, -1, "collisionbox");
1952 if(lua_istable(L, -1))
1953 prop->collisionbox = read_aabbox3df32(L, -1, 1.0);
1956 getstringfield(L, -1, "visual", prop->visual);
1958 lua_getfield(L, -1, "visual_size");
1959 if(lua_istable(L, -1))
1960 prop->visual_size = read_v2f(L, -1);
1963 lua_getfield(L, -1, "textures");
1964 if(lua_istable(L, -1)){
1965 prop->textures.clear();
1966 int table = lua_gettop(L);
1968 while(lua_next(L, table) != 0){
1969 // key at index -2 and value at index -1
1970 if(lua_isstring(L, -1))
1971 prop->textures.push_back(lua_tostring(L, -1));
1973 prop->textures.push_back("");
1974 // removes value, keeps key for next iteration
1980 lua_getfield(L, -1, "spritediv");
1981 if(lua_istable(L, -1))
1982 prop->spritediv = read_v2s16(L, -1);
1985 lua_getfield(L, -1, "initial_sprite_basepos");
1986 if(lua_istable(L, -1))
1987 prop->initial_sprite_basepos = read_v2s16(L, -1);
1991 void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime)
1994 assert(lua_checkstack(L, 20));
1995 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
1996 StackUnroller stack_unroller(L);
1998 // Get minetest.luaentities[id]
1999 luaentity_get(L, id);
2000 int object = lua_gettop(L);
2001 // State: object is at top of stack
2002 // Get step function
2003 lua_getfield(L, -1, "on_step");
2004 if(lua_isnil(L, -1))
2006 luaL_checktype(L, -1, LUA_TFUNCTION);
2007 lua_pushvalue(L, object); // self
2008 lua_pushnumber(L, dtime); // dtime
2009 // Call with 2 arguments, 0 results
2010 if(lua_pcall(L, 2, 0, 0))
2011 script_error(L, "error running function 'on_step': %s\n", lua_tostring(L, -1));
2014 // Calls entity:on_punch(ObjectRef puncher)
2015 void scriptapi_luaentity_punch(lua_State *L, u16 id,
2016 ServerActiveObject *puncher)
2019 assert(lua_checkstack(L, 20));
2020 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
2021 StackUnroller stack_unroller(L);
2023 // Get minetest.luaentities[id]
2024 luaentity_get(L, id);
2025 int object = lua_gettop(L);
2026 // State: object is at top of stack
2028 lua_getfield(L, -1, "on_punch");
2029 if(lua_isnil(L, -1))
2031 luaL_checktype(L, -1, LUA_TFUNCTION);
2032 lua_pushvalue(L, object); // self
2033 objectref_get_or_create(L, puncher); // Clicker reference
2034 // Call with 2 arguments, 0 results
2035 if(lua_pcall(L, 2, 0, 0))
2036 script_error(L, "error running function 'on_punch': %s\n", lua_tostring(L, -1));
2039 // Calls entity:on_rightclick(ObjectRef clicker)
2040 void scriptapi_luaentity_rightclick(lua_State *L, u16 id,
2041 ServerActiveObject *clicker)
2044 assert(lua_checkstack(L, 20));
2045 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
2046 StackUnroller stack_unroller(L);
2048 // Get minetest.luaentities[id]
2049 luaentity_get(L, id);
2050 int object = lua_gettop(L);
2051 // State: object is at top of stack
2053 lua_getfield(L, -1, "on_rightclick");
2054 if(lua_isnil(L, -1))
2056 luaL_checktype(L, -1, LUA_TFUNCTION);
2057 lua_pushvalue(L, object); // self
2058 objectref_get_or_create(L, clicker); // Clicker reference
2059 // Call with 2 arguments, 0 results
2060 if(lua_pcall(L, 2, 0, 0))
2061 script_error(L, "error running function 'on_rightclick': %s\n", lua_tostring(L, -1));