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"
34 #include "serverobject.h"
37 #include "luaentity_common.h"
38 #include "content_sao.h" // For LuaEntitySAO
42 #include "craftitemdef.h"
43 #include "main.h" // For g_settings
44 #include "settings.h" // For accessing g_settings
45 #include "nodemetadata.h"
46 #include "mapblock.h" // For getNodeBlockPos
47 #include "content_nodemeta.h"
50 static void stackDump(lua_State *L, std::ostream &o)
53 int top = lua_gettop(L);
54 for (i = 1; i <= top; i++) { /* repeat for each level */
55 int t = lua_type(L, i);
58 case LUA_TSTRING: /* strings */
59 o<<"\""<<lua_tostring(L, i)<<"\"";
62 case LUA_TBOOLEAN: /* booleans */
63 o<<(lua_toboolean(L, i) ? "true" : "false");
66 case LUA_TNUMBER: /* numbers */ {
68 snprintf(buf, 10, "%g", lua_tonumber(L, i));
72 default: /* other values */
73 o<<lua_typename(L, t);
82 static void realitycheck(lua_State *L)
84 int top = lua_gettop(L);
86 dstream<<"Stack is over 30:"<<std::endl;
87 stackDump(L, dstream);
88 script_error(L, "Stack is over 30 (reality check)");
98 StackUnroller(lua_State *L):
102 m_original_top = lua_gettop(m_lua); // store stack height
106 lua_settop(m_lua, m_original_top); // restore stack height
110 static v3f readFloatPos(lua_State *L, int index)
113 luaL_checktype(L, index, LUA_TTABLE);
114 lua_getfield(L, index, "x");
115 pos.X = lua_tonumber(L, -1);
117 lua_getfield(L, index, "y");
118 pos.Y = lua_tonumber(L, -1);
120 lua_getfield(L, index, "z");
121 pos.Z = lua_tonumber(L, -1);
123 pos *= BS; // Scale to internal format
127 static void pushFloatPos(lua_State *L, v3f p)
131 lua_pushnumber(L, p.X);
132 lua_setfield(L, -2, "x");
133 lua_pushnumber(L, p.Y);
134 lua_setfield(L, -2, "y");
135 lua_pushnumber(L, p.Z);
136 lua_setfield(L, -2, "z");
139 static void pushpos(lua_State *L, v3s16 p)
142 lua_pushnumber(L, p.X);
143 lua_setfield(L, -2, "x");
144 lua_pushnumber(L, p.Y);
145 lua_setfield(L, -2, "y");
146 lua_pushnumber(L, p.Z);
147 lua_setfield(L, -2, "z");
150 static v3s16 readpos(lua_State *L, int index)
152 // Correct rounding at <0
153 v3f pf = readFloatPos(L, index);
154 return floatToInt(pf, BS);
157 static void pushnode(lua_State *L, const MapNode &n, INodeDefManager *ndef)
160 lua_pushstring(L, ndef->get(n).name.c_str());
161 lua_setfield(L, -2, "name");
162 lua_pushnumber(L, n.getParam1());
163 lua_setfield(L, -2, "param1");
164 lua_pushnumber(L, n.getParam2());
165 lua_setfield(L, -2, "param2");
168 static MapNode readnode(lua_State *L, int index, INodeDefManager *ndef)
170 lua_getfield(L, index, "name");
171 const char *name = lua_tostring(L, -1);
174 lua_getfield(L, index, "param1");
178 param1 = lua_tonumber(L, -1);
181 lua_getfield(L, index, "param2");
185 param2 = lua_tonumber(L, -1);
187 return MapNode(ndef, name, param1, param2);
190 static video::SColor readARGB8(lua_State *L, int index)
193 luaL_checktype(L, index, LUA_TTABLE);
194 lua_getfield(L, index, "a");
195 if(lua_isnumber(L, -1))
196 color.setAlpha(lua_tonumber(L, -1));
198 lua_getfield(L, index, "r");
199 color.setRed(lua_tonumber(L, -1));
201 lua_getfield(L, index, "g");
202 color.setGreen(lua_tonumber(L, -1));
204 lua_getfield(L, index, "b");
205 color.setBlue(lua_tonumber(L, -1));
210 static core::aabbox3d<f32> read_aabbox3df32(lua_State *L, int index, f32 scale)
212 core::aabbox3d<f32> box;
213 if(lua_istable(L, -1)){
214 lua_rawgeti(L, -1, 1);
215 box.MinEdge.X = lua_tonumber(L, -1) * scale;
217 lua_rawgeti(L, -1, 2);
218 box.MinEdge.Y = lua_tonumber(L, -1) * scale;
220 lua_rawgeti(L, -1, 3);
221 box.MinEdge.Z = lua_tonumber(L, -1) * scale;
223 lua_rawgeti(L, -1, 4);
224 box.MaxEdge.X = lua_tonumber(L, -1) * scale;
226 lua_rawgeti(L, -1, 5);
227 box.MaxEdge.Y = lua_tonumber(L, -1) * scale;
229 lua_rawgeti(L, -1, 6);
230 box.MaxEdge.Z = lua_tonumber(L, -1) * scale;
236 static v2s16 read_v2s16(lua_State *L, int index)
239 luaL_checktype(L, index, LUA_TTABLE);
240 lua_getfield(L, index, "x");
241 p.X = lua_tonumber(L, -1);
243 lua_getfield(L, index, "y");
244 p.Y = lua_tonumber(L, -1);
249 static v2f read_v2f(lua_State *L, int index)
252 luaL_checktype(L, index, LUA_TTABLE);
253 lua_getfield(L, index, "x");
254 p.X = lua_tonumber(L, -1);
256 lua_getfield(L, index, "y");
257 p.Y = lua_tonumber(L, -1);
262 static bool getstringfield(lua_State *L, int table,
263 const char *fieldname, std::string &result)
265 lua_getfield(L, table, fieldname);
267 if(lua_isstring(L, -1)){
268 result = lua_tostring(L, -1);
275 static bool getintfield(lua_State *L, int table,
276 const char *fieldname, int &result)
278 lua_getfield(L, table, fieldname);
280 if(lua_isnumber(L, -1)){
281 result = lua_tonumber(L, -1);
288 static bool getfloatfield(lua_State *L, int table,
289 const char *fieldname, float &result)
291 lua_getfield(L, table, fieldname);
293 if(lua_isnumber(L, -1)){
294 result = lua_tonumber(L, -1);
301 static bool getboolfield(lua_State *L, int table,
302 const char *fieldname, bool &result)
304 lua_getfield(L, table, fieldname);
306 if(lua_isboolean(L, -1)){
307 result = lua_toboolean(L, -1);
314 static std::string getstringfield_default(lua_State *L, int table,
315 const char *fieldname, const std::string &default_)
317 std::string result = default_;
318 getstringfield(L, table, fieldname, result);
322 static int getintfield_default(lua_State *L, int table,
323 const char *fieldname, int default_)
325 int result = default_;
326 getintfield(L, table, fieldname, result);
330 /*static float getfloatfield_default(lua_State *L, int table,
331 const char *fieldname, float default_)
333 float result = default_;
334 getfloatfield(L, table, fieldname, result);
338 static bool getboolfield_default(lua_State *L, int table,
339 const char *fieldname, bool default_)
341 bool result = default_;
342 getboolfield(L, table, fieldname, result);
352 static bool string_to_enum(const EnumString *spec, int &result,
353 const std::string &str)
355 const EnumString *esp = spec;
357 if(str == std::string(esp->str)){
366 /*static bool enum_to_string(const EnumString *spec, std::string &result,
369 const EnumString *esp = spec;
380 static int getenumfield(lua_State *L, int table,
381 const char *fieldname, const EnumString *spec, int default_)
383 int result = default_;
384 string_to_enum(spec, result,
385 getstringfield_default(L, table, fieldname, ""));
389 static void setfloatfield(lua_State *L, int table,
390 const char *fieldname, float value)
392 lua_pushnumber(L, value);
395 lua_setfield(L, table, fieldname);
402 static void inventory_set_list_from_lua(Inventory *inv, const char *name,
403 lua_State *L, int tableindex, IGameDef *gamedef, int forcesize=-1)
405 // If nil, delete list
406 if(lua_isnil(L, tableindex)){
407 inv->deleteList(name);
410 // Otherwise set list
411 std::list<std::string> items;
412 luaL_checktype(L, tableindex, LUA_TTABLE);
413 int table = tableindex;
415 while(lua_next(L, table) != 0){
416 // key at index -2 and value at index -1
417 luaL_checktype(L, -1, LUA_TSTRING);
418 std::string itemstring = lua_tostring(L, -1);
419 items.push_back(itemstring);
420 // removes value, keeps key for next iteration
423 int listsize = (forcesize != -1) ? forcesize : items.size();
424 InventoryList *invlist = inv->addList(name, listsize);
426 for(std::list<std::string>::const_iterator
427 i = items.begin(); i != items.end(); i++){
428 if(forcesize != -1 && index == forcesize)
430 const std::string &itemstring = *i;
431 InventoryItem *newitem = NULL;
433 newitem = InventoryItem::deSerialize(itemstring,
435 InventoryItem *olditem = invlist->changeItem(index, newitem);
439 while(forcesize != -1 && index < forcesize){
440 InventoryItem *olditem = invlist->changeItem(index, NULL);
446 static void inventory_get_list_to_lua(Inventory *inv, const char *name,
449 InventoryList *invlist = inv->getList(name);
454 // Get the table insert function
455 lua_getglobal(L, "table");
456 lua_getfield(L, -1, "insert");
457 int table_insert = lua_gettop(L);
458 // Create and fill table
460 int table = lua_gettop(L);
461 for(u32 i=0; i<invlist->getSize(); i++){
462 InventoryItem *item = invlist->getItem(i);
463 lua_pushvalue(L, table_insert);
464 lua_pushvalue(L, table);
466 lua_pushstring(L, "");
468 lua_pushstring(L, item->getItemString().c_str());
470 if(lua_pcall(L, 2, 0, 0))
471 script_error(L, "error: %s\n", lua_tostring(L, -1));
476 ToolDiggingProperties
479 static ToolDiggingProperties read_tool_digging_properties(
480 lua_State *L, int table)
482 ToolDiggingProperties prop;
483 getfloatfield(L, table, "full_punch_interval", prop.full_punch_interval);
484 getfloatfield(L, table, "basetime", prop.basetime);
485 getfloatfield(L, table, "dt_weight", prop.dt_weight);
486 getfloatfield(L, table, "dt_crackiness", prop.dt_crackiness);
487 getfloatfield(L, table, "dt_crumbliness", prop.dt_crumbliness);
488 getfloatfield(L, table, "dt_cuttability", prop.dt_cuttability);
489 getfloatfield(L, table, "basedurability", prop.basedurability);
490 getfloatfield(L, table, "dd_weight", prop.dd_weight);
491 getfloatfield(L, table, "dd_crackiness", prop.dd_crackiness);
492 getfloatfield(L, table, "dd_crumbliness", prop.dd_crumbliness);
493 getfloatfield(L, table, "dd_cuttability", prop.dd_cuttability);
497 static void set_tool_digging_properties(lua_State *L, int table,
498 const ToolDiggingProperties &prop)
500 setfloatfield(L, table, "full_punch_interval", prop.full_punch_interval);
501 setfloatfield(L, table, "basetime", prop.basetime);
502 setfloatfield(L, table, "dt_weight", prop.dt_weight);
503 setfloatfield(L, table, "dt_crackiness", prop.dt_crackiness);
504 setfloatfield(L, table, "dt_crumbliness", prop.dt_crumbliness);
505 setfloatfield(L, table, "dt_cuttability", prop.dt_cuttability);
506 setfloatfield(L, table, "basedurability", prop.basedurability);
507 setfloatfield(L, table, "dd_weight", prop.dd_weight);
508 setfloatfield(L, table, "dd_crackiness", prop.dd_crackiness);
509 setfloatfield(L, table, "dd_crumbliness", prop.dd_crumbliness);
510 setfloatfield(L, table, "dd_cuttability", prop.dd_cuttability);
513 static void push_tool_digging_properties(lua_State *L,
514 const ToolDiggingProperties &prop)
517 set_tool_digging_properties(L, -1, prop);
524 static ToolDefinition read_tool_definition(lua_State *L, int table)
527 getstringfield(L, table, "image", def.imagename);
528 def.properties = read_tool_digging_properties(L, table);
532 static void push_tool_definition(lua_State *L, const ToolDefinition &def)
535 lua_pushstring(L, def.imagename.c_str());
536 lua_setfield(L, -2, "image");
537 set_tool_digging_properties(L, -1, def.properties);
541 EnumString definitions
544 struct EnumString es_DrawType[] =
546 {NDT_NORMAL, "normal"},
547 {NDT_AIRLIKE, "airlike"},
548 {NDT_LIQUID, "liquid"},
549 {NDT_FLOWINGLIQUID, "flowingliquid"},
550 {NDT_GLASSLIKE, "glasslike"},
551 {NDT_ALLFACES, "allfaces"},
552 {NDT_ALLFACES_OPTIONAL, "allfaces_optional"},
553 {NDT_TORCHLIKE, "torchlike"},
554 {NDT_SIGNLIKE, "signlike"},
555 {NDT_PLANTLIKE, "plantlike"},
556 {NDT_FENCELIKE, "fencelike"},
557 {NDT_RAILLIKE, "raillike"},
561 struct EnumString es_ContentParamType[] =
564 {CPT_LIGHT, "light"},
565 {CPT_MINERAL, "mineral"},
566 {CPT_FACEDIR_SIMPLE, "facedir_simple"},
570 struct EnumString es_LiquidType[] =
572 {LIQUID_NONE, "none"},
573 {LIQUID_FLOWING, "flowing"},
574 {LIQUID_SOURCE, "source"},
578 struct EnumString es_NodeBoxType[] =
580 {NODEBOX_REGULAR, "regular"},
581 {NODEBOX_FIXED, "fixed"},
582 {NODEBOX_WALLMOUNTED, "wallmounted"},
586 struct EnumString es_Diggability[] =
588 {DIGGABLE_NOT, "not"},
589 {DIGGABLE_NORMAL, "normal"},
590 {DIGGABLE_CONSTANT, "constant"},
598 static int l_register_nodedef_defaults(lua_State *L)
600 luaL_checktype(L, 1, LUA_TTABLE);
602 lua_pushvalue(L, 1); // Explicitly put parameter 1 on top of stack
603 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
608 // Register new object prototype
609 // register_entity(name, prototype)
610 static int l_register_entity(lua_State *L)
612 const char *name = luaL_checkstring(L, 1);
613 infostream<<"register_entity: "<<name<<std::endl;
614 luaL_checktype(L, 2, LUA_TTABLE);
616 // Get minetest.registered_entities
617 lua_getglobal(L, "minetest");
618 lua_getfield(L, -1, "registered_entities");
619 luaL_checktype(L, -1, LUA_TTABLE);
620 int registered_entities = lua_gettop(L);
621 lua_pushvalue(L, 2); // Object = param 2 -> stack top
622 // registered_entities[name] = object
623 lua_setfield(L, registered_entities, name);
625 // Get registered object to top of stack
628 // Set __index to point to itself
629 lua_pushvalue(L, -1);
630 lua_setfield(L, -2, "__index");
632 // Set metatable.__index = metatable
633 luaL_getmetatable(L, "minetest.entity");
634 lua_pushvalue(L, -1); // duplicate metatable
635 lua_setfield(L, -2, "__index");
636 // Set object metatable
637 lua_setmetatable(L, -2);
639 return 0; /* number of results */
642 class LuaABM : public ActiveBlockModifier
648 std::set<std::string> m_trigger_contents;
649 float m_trigger_interval;
650 u32 m_trigger_chance;
652 LuaABM(lua_State *L, int id,
653 const std::set<std::string> &trigger_contents,
654 float trigger_interval, u32 trigger_chance):
657 m_trigger_contents(trigger_contents),
658 m_trigger_interval(trigger_interval),
659 m_trigger_chance(trigger_chance)
662 virtual std::set<std::string> getTriggerContents()
664 return m_trigger_contents;
666 virtual float getTriggerInterval()
668 return m_trigger_interval;
670 virtual u32 getTriggerChance()
672 return m_trigger_chance;
674 virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n,
675 u32 active_object_count, u32 active_object_count_wider)
677 lua_State *L = m_lua;
680 assert(lua_checkstack(L, 20));
681 StackUnroller stack_unroller(L);
683 // Get minetest.registered_abms
684 lua_getglobal(L, "minetest");
685 lua_getfield(L, -1, "registered_abms");
686 luaL_checktype(L, -1, LUA_TTABLE);
687 int registered_abms = lua_gettop(L);
689 // Get minetest.registered_abms[m_id]
690 lua_pushnumber(L, m_id);
691 lua_gettable(L, registered_abms);
696 luaL_checktype(L, -1, LUA_TTABLE);
697 lua_getfield(L, -1, "action");
698 luaL_checktype(L, -1, LUA_TFUNCTION);
700 pushnode(L, n, env->getGameDef()->ndef());
701 lua_pushnumber(L, active_object_count);
702 lua_pushnumber(L, active_object_count_wider);
703 if(lua_pcall(L, 4, 0, 0))
704 script_error(L, "error: %s\n", lua_tostring(L, -1));
708 // register_abm({...})
709 static int l_register_abm(lua_State *L)
711 infostream<<"register_abm"<<std::endl;
712 luaL_checktype(L, 1, LUA_TTABLE);
714 // Get minetest.registered_abms
715 lua_getglobal(L, "minetest");
716 lua_getfield(L, -1, "registered_abms");
717 luaL_checktype(L, -1, LUA_TTABLE);
718 int registered_abms = lua_gettop(L);
723 lua_pushnumber(L, id);
724 lua_gettable(L, registered_abms);
732 infostream<<"register_abm: id="<<id<<std::endl;
734 // registered_abms[id] = spec
735 lua_pushnumber(L, id);
737 lua_settable(L, registered_abms);
739 return 0; /* number of results */
742 // register_tool(name, {lots of stuff})
743 static int l_register_tool(lua_State *L)
745 const char *name = luaL_checkstring(L, 1);
746 infostream<<"register_tool: "<<name<<std::endl;
747 luaL_checktype(L, 2, LUA_TTABLE);
750 // Get server from registry
751 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
752 Server *server = (Server*)lua_touserdata(L, -1);
753 // And get the writable tool definition manager from the server
754 IWritableToolDefManager *tooldef =
755 server->getWritableToolDefManager();
757 ToolDefinition def = read_tool_definition(L, table);
759 tooldef->registerTool(name, def);
760 return 0; /* number of results */
763 // register_craftitem(name, {lots of stuff})
764 static int l_register_craftitem(lua_State *L)
766 const char *name = luaL_checkstring(L, 1);
767 infostream<<"register_craftitem: "<<name<<std::endl;
768 luaL_checktype(L, 2, LUA_TTABLE);
771 // Get server from registry
772 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
773 Server *server = (Server*)lua_touserdata(L, -1);
774 // And get the writable CraftItem definition manager from the server
775 IWritableCraftItemDefManager *craftitemdef =
776 server->getWritableCraftItemDefManager();
778 // Check if on_drop is defined
779 lua_getfield(L, table, "on_drop");
780 bool got_on_drop = !lua_isnil(L, -1);
783 // Check if on_use is defined
784 lua_getfield(L, table, "on_use");
785 bool got_on_use = !lua_isnil(L, -1);
788 CraftItemDefinition def;
790 getstringfield(L, table, "image", def.imagename);
791 getstringfield(L, table, "cookresult_item", def.cookresult_item);
792 getfloatfield(L, table, "furnace_cooktime", def.furnace_cooktime);
793 getfloatfield(L, table, "furnace_burntime", def.furnace_burntime);
794 def.usable = getboolfield_default(L, table, "usable", got_on_use);
795 getboolfield(L, table, "liquids_pointable", def.liquids_pointable);
796 def.dropcount = getintfield_default(L, table, "dropcount", def.dropcount);
797 def.stack_max = getintfield_default(L, table, "stack_max", def.stack_max);
799 // If an on_drop callback is defined, force dropcount to 1
804 craftitemdef->registerCraftItem(name, def);
806 lua_pushvalue(L, table);
807 scriptapi_add_craftitem(L, name);
809 return 0; /* number of results */
812 // register_node(name, {lots of stuff})
813 static int l_register_node(lua_State *L)
815 const char *name = luaL_checkstring(L, 1);
816 infostream<<"register_node: "<<name<<std::endl;
817 luaL_checktype(L, 2, LUA_TTABLE);
818 int nodedef_table = 2;
820 // Get server from registry
821 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
822 Server *server = (Server*)lua_touserdata(L, -1);
823 // And get the writable node definition manager from the server
824 IWritableNodeDefManager *nodedef =
825 server->getWritableNodeDefManager();
827 // Get default node definition from registry
828 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
829 int nodedef_default = lua_gettop(L);
832 Add to minetest.registered_nodes with default as metatable
835 // Get the node definition table given as parameter
836 lua_pushvalue(L, nodedef_table);
838 // Set __index to point to itself
839 lua_pushvalue(L, -1);
840 lua_setfield(L, -2, "__index");
842 // Set nodedef_default as metatable for the definition
843 lua_pushvalue(L, nodedef_default);
844 lua_setmetatable(L, nodedef_table);
846 // minetest.registered_nodes[name] = nodedef
847 lua_getglobal(L, "minetest");
848 lua_getfield(L, -1, "registered_nodes");
849 luaL_checktype(L, -1, LUA_TTABLE);
850 lua_pushstring(L, name);
851 lua_pushvalue(L, nodedef_table);
860 // Default to getting the corresponding NodeItem when dug
861 f.dug_item = std::string("NodeItem \"")+name+"\" 1";
863 // Default to unknown_block.png as all textures
864 f.setAllTextures("unknown_block.png");
867 Read definiton from Lua
872 /* Visual definition */
874 f.drawtype = (NodeDrawType)getenumfield(L, nodedef_table, "drawtype", es_DrawType,
876 getfloatfield(L, nodedef_table, "visual_scale", f.visual_scale);
878 lua_getfield(L, nodedef_table, "tile_images");
879 if(lua_istable(L, -1)){
880 int table = lua_gettop(L);
883 while(lua_next(L, table) != 0){
884 // key at index -2 and value at index -1
885 if(lua_isstring(L, -1))
886 f.tname_tiles[i] = lua_tostring(L, -1);
888 f.tname_tiles[i] = "";
889 // removes value, keeps key for next iteration
897 // Copy last value to all remaining textures
899 std::string lastname = f.tname_tiles[i-1];
901 f.tname_tiles[i] = lastname;
908 getstringfield(L, nodedef_table, "inventory_image", f.tname_inventory);
910 lua_getfield(L, nodedef_table, "special_materials");
911 if(lua_istable(L, -1)){
912 int table = lua_gettop(L);
915 while(lua_next(L, table) != 0){
916 // key at index -2 and value at index -1
917 int smtable = lua_gettop(L);
918 std::string tname = getstringfield_default(
919 L, smtable, "image", "");
920 bool backface_culling = getboolfield_default(
921 L, smtable, "backface_culling", true);
922 MaterialSpec mspec(tname, backface_culling);
923 f.setSpecialMaterial(i, mspec);
924 // removes value, keeps key for next iteration
935 f.alpha = getintfield_default(L, nodedef_table, "alpha", 255);
939 lua_getfield(L, nodedef_table, "post_effect_color");
940 if(!lua_isnil(L, -1))
941 f.post_effect_color = readARGB8(L, -1);
944 f.param_type = (ContentParamType)getenumfield(L, nodedef_table, "paramtype",
945 es_ContentParamType, CPT_NONE);
947 // True for all ground-like things like stone and mud, false for eg. trees
948 getboolfield(L, nodedef_table, "is_ground_content", f.is_ground_content);
949 getboolfield(L, nodedef_table, "light_propagates", f.light_propagates);
950 getboolfield(L, nodedef_table, "sunlight_propagates", f.sunlight_propagates);
951 // This is used for collision detection.
952 // Also for general solidness queries.
953 getboolfield(L, nodedef_table, "walkable", f.walkable);
954 // Player can point to these
955 getboolfield(L, nodedef_table, "pointable", f.pointable);
956 // Player can dig these
957 getboolfield(L, nodedef_table, "diggable", f.diggable);
958 // Player can climb these
959 getboolfield(L, nodedef_table, "climbable", f.climbable);
960 // Player can build on these
961 getboolfield(L, nodedef_table, "buildable_to", f.buildable_to);
962 // If true, param2 is set to direction when placed. Used for torches.
963 // NOTE: the direction format is quite inefficient and should be changed
964 getboolfield(L, nodedef_table, "wall_mounted", f.wall_mounted);
965 // Whether this content type often contains mineral.
966 // Used for texture atlas creation.
967 // Currently only enabled for CONTENT_STONE.
968 getboolfield(L, nodedef_table, "often_contains_mineral", f.often_contains_mineral);
969 // Inventory item string as which the node appears in inventory when dug.
970 // Mineral overrides this.
971 getstringfield(L, nodedef_table, "dug_item", f.dug_item);
972 // Extra dug item and its rarity
973 getstringfield(L, nodedef_table, "extra_dug_item", f.extra_dug_item);
974 // Usual get interval for extra dug item
975 getintfield(L, nodedef_table, "extra_dug_item_rarity", f.extra_dug_item_rarity);
976 // Metadata name of node (eg. "furnace")
977 getstringfield(L, nodedef_table, "metadata_name", f.metadata_name);
978 // Whether the node is non-liquid, source liquid or flowing liquid
979 f.liquid_type = (LiquidType)getenumfield(L, nodedef_table, "liquidtype",
980 es_LiquidType, LIQUID_NONE);
981 // If the content is liquid, this is the flowing version of the liquid.
982 getstringfield(L, nodedef_table, "liquid_alternative_flowing",
983 f.liquid_alternative_flowing);
984 // If the content is liquid, this is the source version of the liquid.
985 getstringfield(L, nodedef_table, "liquid_alternative_source",
986 f.liquid_alternative_source);
987 // Viscosity for fluid flow, ranging from 1 to 7, with
988 // 1 giving almost instantaneous propagation and 7 being
989 // the slowest possible
990 f.liquid_viscosity = getintfield_default(L, nodedef_table,
991 "liquid_viscosity", f.liquid_viscosity);
992 // Amount of light the node emits
993 f.light_source = getintfield_default(L, nodedef_table,
994 "light_source", f.light_source);
995 f.damage_per_second = getintfield_default(L, nodedef_table,
996 "damage_per_second", f.damage_per_second);
998 lua_getfield(L, nodedef_table, "selection_box");
999 if(lua_istable(L, -1)){
1000 f.selection_box.type = (NodeBoxType)getenumfield(L, -1, "type",
1001 es_NodeBoxType, NODEBOX_REGULAR);
1003 lua_getfield(L, -1, "fixed");
1004 if(lua_istable(L, -1))
1005 f.selection_box.fixed = read_aabbox3df32(L, -1, BS);
1008 lua_getfield(L, -1, "wall_top");
1009 if(lua_istable(L, -1))
1010 f.selection_box.wall_top = read_aabbox3df32(L, -1, BS);
1013 lua_getfield(L, -1, "wall_bottom");
1014 if(lua_istable(L, -1))
1015 f.selection_box.wall_bottom = read_aabbox3df32(L, -1, BS);
1018 lua_getfield(L, -1, "wall_side");
1019 if(lua_istable(L, -1))
1020 f.selection_box.wall_side = read_aabbox3df32(L, -1, BS);
1025 lua_getfield(L, nodedef_table, "material");
1026 if(lua_istable(L, -1)){
1027 f.material.diggability = (Diggability)getenumfield(L, -1, "diggability",
1028 es_Diggability, DIGGABLE_NORMAL);
1030 getfloatfield(L, -1, "constant_time", f.material.constant_time);
1031 getfloatfield(L, -1, "weight", f.material.weight);
1032 getfloatfield(L, -1, "crackiness", f.material.crackiness);
1033 getfloatfield(L, -1, "crumbliness", f.material.crumbliness);
1034 getfloatfield(L, -1, "cuttability", f.material.cuttability);
1035 getfloatfield(L, -1, "flammability", f.material.flammability);
1039 getstringfield(L, nodedef_table, "cookresult_item", f.cookresult_item);
1040 getfloatfield(L, nodedef_table, "furnace_cooktime", f.furnace_cooktime);
1041 getfloatfield(L, nodedef_table, "furnace_burntime", f.furnace_burntime);
1047 nodedef->set(name, f);
1049 return 0; /* number of results */
1052 // register_craft({output=item, recipe={{item00,item10},{item01,item11}})
1053 static int l_register_craft(lua_State *L)
1055 infostream<<"register_craft"<<std::endl;
1056 luaL_checktype(L, 1, LUA_TTABLE);
1059 // Get server from registry
1060 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1061 Server *server = (Server*)lua_touserdata(L, -1);
1062 // And get the writable craft definition manager from the server
1063 IWritableCraftDefManager *craftdef =
1064 server->getWritableCraftDefManager();
1068 std::vector<std::string> input;
1070 lua_getfield(L, table0, "output");
1071 luaL_checktype(L, -1, LUA_TSTRING);
1072 if(lua_isstring(L, -1))
1073 output = lua_tostring(L, -1);
1076 lua_getfield(L, table0, "recipe");
1077 luaL_checktype(L, -1, LUA_TTABLE);
1078 if(lua_istable(L, -1)){
1079 int table1 = lua_gettop(L);
1082 while(lua_next(L, table1) != 0){
1084 // key at index -2 and value at index -1
1085 luaL_checktype(L, -1, LUA_TTABLE);
1086 if(lua_istable(L, -1)){
1087 int table2 = lua_gettop(L);
1089 while(lua_next(L, table2) != 0){
1090 // key at index -2 and value at index -1
1091 luaL_checktype(L, -1, LUA_TSTRING);
1092 input.push_back(lua_tostring(L, -1));
1093 // removes value, keeps key for next iteration
1101 if(colcount != width){
1102 script_error(L, "error: %s\n", "Invalid crafting recipe");
1105 // removes value, keeps key for next iteration
1112 CraftDefinition def(output, width, input);
1113 craftdef->registerCraft(def);
1115 return 0; /* number of results */
1118 // setting_get(name)
1119 static int l_setting_get(lua_State *L)
1121 const char *name = luaL_checkstring(L, 1);
1123 std::string value = g_settings->get(name);
1124 lua_pushstring(L, value.c_str());
1125 } catch(SettingNotFoundException &e){
1131 // setting_getbool(name)
1132 static int l_setting_getbool(lua_State *L)
1134 const char *name = luaL_checkstring(L, 1);
1136 bool value = g_settings->getBool(name);
1137 lua_pushboolean(L, value);
1138 } catch(SettingNotFoundException &e){
1144 // chat_send_all(text)
1145 static int l_chat_send_all(lua_State *L)
1147 const char *text = luaL_checkstring(L, 1);
1148 // Get server from registry
1149 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1150 Server *server = (Server*)lua_touserdata(L, -1);
1152 server->notifyPlayers(narrow_to_wide(text));
1156 // chat_send_player(name, text)
1157 static int l_chat_send_player(lua_State *L)
1159 const char *name = luaL_checkstring(L, 1);
1160 const char *text = luaL_checkstring(L, 2);
1161 // Get server from registry
1162 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1163 Server *server = (Server*)lua_touserdata(L, -1);
1165 server->notifyPlayer(name, narrow_to_wide(text));
1169 // get_player_privs(name, text)
1170 static int l_get_player_privs(lua_State *L)
1172 const char *name = luaL_checkstring(L, 1);
1173 // Get server from registry
1174 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1175 Server *server = (Server*)lua_touserdata(L, -1);
1178 int table = lua_gettop(L);
1179 u64 privs_i = server->getPlayerAuthPrivs(name);
1180 // Special case for the "name" setting (local player / server owner)
1181 if(name == g_settings->get("name"))
1183 std::set<std::string> privs_s = privsToSet(privs_i);
1184 for(std::set<std::string>::const_iterator
1185 i = privs_s.begin(); i != privs_s.end(); i++){
1186 lua_pushboolean(L, true);
1187 lua_setfield(L, table, i->c_str());
1189 lua_pushvalue(L, table);
1193 static const struct luaL_Reg minetest_f [] = {
1194 {"register_nodedef_defaults", l_register_nodedef_defaults},
1195 {"register_entity", l_register_entity},
1196 {"register_tool", l_register_tool},
1197 {"register_craftitem", l_register_craftitem},
1198 {"register_node", l_register_node},
1199 {"register_craft", l_register_craft},
1200 {"register_abm", l_register_abm},
1201 {"setting_get", l_setting_get},
1202 {"setting_getbool", l_setting_getbool},
1203 {"chat_send_all", l_chat_send_all},
1204 {"chat_send_player", l_chat_send_player},
1205 {"get_player_privs", l_get_player_privs},
1213 static const struct luaL_Reg minetest_entity_m [] = {
1218 Getters for stuff in main tables
1221 static void objectref_get(lua_State *L, u16 id)
1223 // Get minetest.object_refs[i]
1224 lua_getglobal(L, "minetest");
1225 lua_getfield(L, -1, "object_refs");
1226 luaL_checktype(L, -1, LUA_TTABLE);
1227 lua_pushnumber(L, id);
1228 lua_gettable(L, -2);
1229 lua_remove(L, -2); // object_refs
1230 lua_remove(L, -2); // minetest
1233 static void luaentity_get(lua_State *L, u16 id)
1235 // Get minetest.luaentities[i]
1236 lua_getglobal(L, "minetest");
1237 lua_getfield(L, -1, "luaentities");
1238 luaL_checktype(L, -1, LUA_TTABLE);
1239 lua_pushnumber(L, id);
1240 lua_gettable(L, -2);
1241 lua_remove(L, -2); // luaentities
1242 lua_remove(L, -2); // minetest
1249 #define method(class, name) {#name, class::l_##name}
1259 ServerEnvironment *m_env;
1261 static const char className[];
1262 static const luaL_reg methods[];
1264 static NodeMetaRef *checkobject(lua_State *L, int narg)
1266 luaL_checktype(L, narg, LUA_TUSERDATA);
1267 void *ud = luaL_checkudata(L, narg, className);
1268 if(!ud) luaL_typerror(L, narg, className);
1269 return *(NodeMetaRef**)ud; // unbox pointer
1272 static NodeMetadata* getmeta(NodeMetaRef *ref)
1274 NodeMetadata *meta = ref->m_env->getMap().getNodeMetadata(ref->m_p);
1278 /*static IGenericNodeMetadata* getgenericmeta(NodeMetaRef *ref)
1280 NodeMetadata *meta = getmeta(ref);
1283 if(meta->typeId() != NODEMETA_GENERIC)
1285 return (IGenericNodeMetadata*)meta;
1288 static void reportMetadataChange(NodeMetaRef *ref)
1290 // Inform other things that the metadata has changed
1291 v3s16 blockpos = getNodeBlockPos(ref->m_p);
1293 event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
1295 ref->m_env->getMap().dispatchEvent(&event);
1296 // Set the block to be saved
1297 MapBlock *block = ref->m_env->getMap().getBlockNoCreateNoEx(blockpos);
1299 block->raiseModified(MOD_STATE_WRITE_NEEDED,
1300 "NodeMetaRef::reportMetadataChange");
1303 // Exported functions
1305 // garbage collector
1306 static int gc_object(lua_State *L) {
1307 NodeMetaRef *o = *(NodeMetaRef **)(lua_touserdata(L, 1));
1313 static int l_get_type(lua_State *L)
1315 NodeMetaRef *ref = checkobject(L, 1);
1316 NodeMetadata *meta = getmeta(ref);
1322 lua_pushstring(L, meta->typeName());
1326 // allows_text_input(self)
1327 static int l_allows_text_input(lua_State *L)
1329 NodeMetaRef *ref = checkobject(L, 1);
1330 NodeMetadata *meta = getmeta(ref);
1331 if(meta == NULL) return 0;
1333 lua_pushboolean(L, meta->allowsTextInput());
1337 // set_text(self, text)
1338 static int l_set_text(lua_State *L)
1340 NodeMetaRef *ref = checkobject(L, 1);
1341 NodeMetadata *meta = getmeta(ref);
1342 if(meta == NULL) return 0;
1344 std::string text = lua_tostring(L, 2);
1345 meta->setText(text);
1346 reportMetadataChange(ref);
1351 static int l_get_text(lua_State *L)
1353 NodeMetaRef *ref = checkobject(L, 1);
1354 NodeMetadata *meta = getmeta(ref);
1355 if(meta == NULL) return 0;
1357 std::string text = meta->getText();
1358 lua_pushstring(L, text.c_str());
1363 static int l_get_owner(lua_State *L)
1365 NodeMetaRef *ref = checkobject(L, 1);
1366 NodeMetadata *meta = getmeta(ref);
1367 if(meta == NULL) return 0;
1369 std::string owner = meta->getOwner();
1370 lua_pushstring(L, owner.c_str());
1374 /* IGenericNodeMetadata interface */
1376 // set_infotext(self, text)
1377 static int l_set_infotext(lua_State *L)
1379 infostream<<__FUNCTION_NAME<<std::endl;
1380 NodeMetaRef *ref = checkobject(L, 1);
1381 NodeMetadata *meta = getmeta(ref);
1382 if(meta == NULL) return 0;
1384 std::string text = lua_tostring(L, 2);
1385 meta->setInfoText(text);
1386 reportMetadataChange(ref);
1390 // inventory_set_list(self, name, {item1, item2, ...})
1391 static int l_inventory_set_list(lua_State *L)
1393 NodeMetaRef *ref = checkobject(L, 1);
1394 NodeMetadata *meta = getmeta(ref);
1395 if(meta == NULL) return 0;
1397 Inventory *inv = meta->getInventory();
1398 const char *name = lua_tostring(L, 2);
1399 inventory_set_list_from_lua(inv, name, L, 3,
1400 ref->m_env->getGameDef());
1401 reportMetadataChange(ref);
1405 // inventory_get_list(self, name)
1406 static int l_inventory_get_list(lua_State *L)
1408 NodeMetaRef *ref = checkobject(L, 1);
1409 NodeMetadata *meta = getmeta(ref);
1410 if(meta == NULL) return 0;
1412 Inventory *inv = meta->getInventory();
1413 const char *name = lua_tostring(L, 2);
1414 inventory_get_list_to_lua(inv, name, L);
1418 // set_inventory_draw_spec(self, text)
1419 static int l_set_inventory_draw_spec(lua_State *L)
1421 NodeMetaRef *ref = checkobject(L, 1);
1422 NodeMetadata *meta = getmeta(ref);
1423 if(meta == NULL) return 0;
1425 std::string text = lua_tostring(L, 2);
1426 meta->setInventoryDrawSpec(text);
1427 reportMetadataChange(ref);
1431 // set_allow_text_input(self, text)
1432 static int l_set_allow_text_input(lua_State *L)
1434 NodeMetaRef *ref = checkobject(L, 1);
1435 NodeMetadata *meta = getmeta(ref);
1436 if(meta == NULL) return 0;
1438 bool b = lua_toboolean(L, 2);
1439 meta->setAllowTextInput(b);
1440 reportMetadataChange(ref);
1444 // set_allow_removal(self, text)
1445 static int l_set_allow_removal(lua_State *L)
1447 NodeMetaRef *ref = checkobject(L, 1);
1448 NodeMetadata *meta = getmeta(ref);
1449 if(meta == NULL) return 0;
1451 bool b = lua_toboolean(L, 2);
1452 meta->setRemovalDisabled(!b);
1453 reportMetadataChange(ref);
1457 // set_enforce_owner(self, text)
1458 static int l_set_enforce_owner(lua_State *L)
1460 NodeMetaRef *ref = checkobject(L, 1);
1461 NodeMetadata *meta = getmeta(ref);
1462 if(meta == NULL) return 0;
1464 bool b = lua_toboolean(L, 2);
1465 meta->setEnforceOwner(b);
1466 reportMetadataChange(ref);
1470 // is_inventory_modified(self)
1471 static int l_is_inventory_modified(lua_State *L)
1473 NodeMetaRef *ref = checkobject(L, 1);
1474 NodeMetadata *meta = getmeta(ref);
1475 if(meta == NULL) return 0;
1477 lua_pushboolean(L, meta->isInventoryModified());
1481 // reset_inventory_modified(self)
1482 static int l_reset_inventory_modified(lua_State *L)
1484 NodeMetaRef *ref = checkobject(L, 1);
1485 NodeMetadata *meta = getmeta(ref);
1486 if(meta == NULL) return 0;
1488 meta->resetInventoryModified();
1489 reportMetadataChange(ref);
1493 // is_text_modified(self)
1494 static int l_is_text_modified(lua_State *L)
1496 NodeMetaRef *ref = checkobject(L, 1);
1497 NodeMetadata *meta = getmeta(ref);
1498 if(meta == NULL) return 0;
1500 lua_pushboolean(L, meta->isTextModified());
1504 // reset_text_modified(self)
1505 static int l_reset_text_modified(lua_State *L)
1507 NodeMetaRef *ref = checkobject(L, 1);
1508 NodeMetadata *meta = getmeta(ref);
1509 if(meta == NULL) return 0;
1511 meta->resetTextModified();
1512 reportMetadataChange(ref);
1516 // set_string(self, name, var)
1517 static int l_set_string(lua_State *L)
1519 NodeMetaRef *ref = checkobject(L, 1);
1520 NodeMetadata *meta = getmeta(ref);
1521 if(meta == NULL) return 0;
1523 std::string name = lua_tostring(L, 2);
1525 const char *s = lua_tolstring(L, 3, &len);
1526 std::string str(s, len);
1527 meta->setString(name, str);
1528 reportMetadataChange(ref);
1532 // get_string(self, name)
1533 static int l_get_string(lua_State *L)
1535 NodeMetaRef *ref = checkobject(L, 1);
1536 NodeMetadata *meta = getmeta(ref);
1537 if(meta == NULL) return 0;
1539 std::string name = lua_tostring(L, 2);
1540 std::string str = meta->getString(name);
1541 lua_pushlstring(L, str.c_str(), str.size());
1546 NodeMetaRef(v3s16 p, ServerEnvironment *env):
1556 // Creates an NodeMetaRef and leaves it on top of stack
1557 // Not callable from Lua; all references are created on the C side.
1558 static void create(lua_State *L, v3s16 p, ServerEnvironment *env)
1560 NodeMetaRef *o = new NodeMetaRef(p, env);
1561 //infostream<<"NodeMetaRef::create: o="<<o<<std::endl;
1562 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1563 luaL_getmetatable(L, className);
1564 lua_setmetatable(L, -2);
1567 static void Register(lua_State *L)
1570 int methodtable = lua_gettop(L);
1571 luaL_newmetatable(L, className);
1572 int metatable = lua_gettop(L);
1574 lua_pushliteral(L, "__metatable");
1575 lua_pushvalue(L, methodtable);
1576 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
1578 lua_pushliteral(L, "__index");
1579 lua_pushvalue(L, methodtable);
1580 lua_settable(L, metatable);
1582 lua_pushliteral(L, "__gc");
1583 lua_pushcfunction(L, gc_object);
1584 lua_settable(L, metatable);
1586 lua_pop(L, 1); // drop metatable
1588 luaL_openlib(L, 0, methods, 0); // fill methodtable
1589 lua_pop(L, 1); // drop methodtable
1591 // Cannot be created from Lua
1592 //lua_register(L, className, create_object);
1595 const char NodeMetaRef::className[] = "NodeMetaRef";
1596 const luaL_reg NodeMetaRef::methods[] = {
1597 method(NodeMetaRef, get_type),
1598 method(NodeMetaRef, allows_text_input),
1599 method(NodeMetaRef, set_text),
1600 method(NodeMetaRef, get_text),
1601 method(NodeMetaRef, get_owner),
1602 method(NodeMetaRef, set_infotext),
1603 method(NodeMetaRef, inventory_set_list),
1604 method(NodeMetaRef, inventory_get_list),
1605 method(NodeMetaRef, set_inventory_draw_spec),
1606 method(NodeMetaRef, set_allow_text_input),
1607 method(NodeMetaRef, set_allow_removal),
1608 method(NodeMetaRef, set_enforce_owner),
1609 method(NodeMetaRef, is_inventory_modified),
1610 method(NodeMetaRef, reset_inventory_modified),
1611 method(NodeMetaRef, is_text_modified),
1612 method(NodeMetaRef, reset_text_modified),
1613 method(NodeMetaRef, set_string),
1614 method(NodeMetaRef, get_string),
1625 ServerActiveObject *m_object;
1627 static const char className[];
1628 static const luaL_reg methods[];
1630 static ObjectRef *checkobject(lua_State *L, int narg)
1632 luaL_checktype(L, narg, LUA_TUSERDATA);
1633 void *ud = luaL_checkudata(L, narg, className);
1634 if(!ud) luaL_typerror(L, narg, className);
1635 return *(ObjectRef**)ud; // unbox pointer
1638 static ServerActiveObject* getobject(ObjectRef *ref)
1640 ServerActiveObject *co = ref->m_object;
1644 static LuaEntitySAO* getluaobject(ObjectRef *ref)
1646 ServerActiveObject *obj = getobject(ref);
1649 if(obj->getType() != ACTIVEOBJECT_TYPE_LUAENTITY)
1651 return (LuaEntitySAO*)obj;
1654 static ServerRemotePlayer* getplayer(ObjectRef *ref)
1656 ServerActiveObject *obj = getobject(ref);
1659 if(obj->getType() != ACTIVEOBJECT_TYPE_PLAYER)
1661 return static_cast<ServerRemotePlayer*>(obj);
1664 // Exported functions
1666 // garbage collector
1667 static int gc_object(lua_State *L) {
1668 ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
1669 //infostream<<"ObjectRef::gc_object: o="<<o<<std::endl;
1675 static int l_remove(lua_State *L)
1677 ObjectRef *ref = checkobject(L, 1);
1678 ServerActiveObject *co = getobject(ref);
1679 if(co == NULL) return 0;
1680 infostream<<"ObjectRef::l_remove(): id="<<co->getId()<<std::endl;
1681 co->m_removed = true;
1686 // returns: {x=num, y=num, z=num}
1687 static int l_getpos(lua_State *L)
1689 ObjectRef *ref = checkobject(L, 1);
1690 ServerActiveObject *co = getobject(ref);
1691 if(co == NULL) return 0;
1692 v3f pos = co->getBasePosition() / BS;
1694 lua_pushnumber(L, pos.X);
1695 lua_setfield(L, -2, "x");
1696 lua_pushnumber(L, pos.Y);
1697 lua_setfield(L, -2, "y");
1698 lua_pushnumber(L, pos.Z);
1699 lua_setfield(L, -2, "z");
1703 // setpos(self, pos)
1704 static int l_setpos(lua_State *L)
1706 ObjectRef *ref = checkobject(L, 1);
1707 //LuaEntitySAO *co = getluaobject(ref);
1708 ServerActiveObject *co = getobject(ref);
1709 if(co == NULL) return 0;
1711 v3f pos = readFloatPos(L, 2);
1717 // moveto(self, pos, continuous=false)
1718 static int l_moveto(lua_State *L)
1720 ObjectRef *ref = checkobject(L, 1);
1721 //LuaEntitySAO *co = getluaobject(ref);
1722 ServerActiveObject *co = getobject(ref);
1723 if(co == NULL) return 0;
1725 v3f pos = readFloatPos(L, 2);
1727 bool continuous = lua_toboolean(L, 3);
1729 co->moveTo(pos, continuous);
1733 // punch(self, puncher); puncher = an another ObjectRef
1734 static int l_punch(lua_State *L)
1736 ObjectRef *ref = checkobject(L, 1);
1737 ObjectRef *ref2 = checkobject(L, 2);
1738 ServerActiveObject *co = getobject(ref);
1739 ServerActiveObject *co2 = getobject(ref2);
1740 if(co == NULL) return 0;
1741 if(co2 == NULL) return 0;
1747 // right_click(self, clicker); clicker = an another ObjectRef
1748 static int l_right_click(lua_State *L)
1750 ObjectRef *ref = checkobject(L, 1);
1751 ObjectRef *ref2 = checkobject(L, 2);
1752 ServerActiveObject *co = getobject(ref);
1753 ServerActiveObject *co2 = getobject(ref2);
1754 if(co == NULL) return 0;
1755 if(co2 == NULL) return 0;
1757 co->rightClick(co2);
1761 // get_wield_digging_properties(self)
1762 static int l_get_wield_digging_properties(lua_State *L)
1764 ObjectRef *ref = checkobject(L, 1);
1765 ServerActiveObject *co = getobject(ref);
1766 if(co == NULL) return 0;
1768 ToolDiggingProperties prop;
1769 co->getWieldDiggingProperties(&prop);
1770 push_tool_digging_properties(L, prop);
1774 // damage_wielded_item(self, amount)
1775 static int l_damage_wielded_item(lua_State *L)
1777 ObjectRef *ref = checkobject(L, 1);
1778 ServerActiveObject *co = getobject(ref);
1779 if(co == NULL) return 0;
1781 int amount = lua_tonumber(L, 2);
1782 co->damageWieldedItem(amount);
1786 // add_to_inventory(self, itemstring)
1787 // returns: true if item was added, (false, "reason") otherwise
1788 static int l_add_to_inventory(lua_State *L)
1790 ObjectRef *ref = checkobject(L, 1);
1791 luaL_checkstring(L, 2);
1792 ServerActiveObject *co = getobject(ref);
1793 if(co == NULL) return 0;
1795 const char *itemstring = lua_tostring(L, 2);
1796 infostream<<"ObjectRef::l_add_to_inventory(): id="<<co->getId()
1797 <<" itemstring=\""<<itemstring<<"\""<<std::endl;
1799 std::istringstream is(itemstring, std::ios::binary);
1800 ServerEnvironment *env = co->getEnv();
1802 IGameDef *gamedef = env->getGameDef();
1804 InventoryItem *item = InventoryItem::deSerialize(is, gamedef);
1805 if(item->getCount() == 0)
1807 bool added = co->addToInventory(item);
1809 lua_pushboolean(L, added);
1811 lua_pushstring(L, "does not fit");
1813 } catch(SerializationError &e){
1815 lua_pushboolean(L, false);
1816 lua_pushstring(L, (std::string("Invalid item: ")
1817 + e.what()).c_str());
1822 // add_to_inventory_later(self, itemstring)
1824 static int l_add_to_inventory_later(lua_State *L)
1826 ObjectRef *ref = checkobject(L, 1);
1827 luaL_checkstring(L, 2);
1828 ServerActiveObject *co = getobject(ref);
1829 if(co == NULL) return 0;
1831 const char *itemstring = lua_tostring(L, 2);
1832 infostream<<"ObjectRef::l_add_to_inventory_later(): id="<<co->getId()
1833 <<" itemstring=\""<<itemstring<<"\""<<std::endl;
1835 std::istringstream is(itemstring, std::ios::binary);
1836 ServerEnvironment *env = co->getEnv();
1838 IGameDef *gamedef = env->getGameDef();
1839 InventoryItem *item = InventoryItem::deSerialize(is, gamedef);
1840 infostream<<"item="<<env<<std::endl;
1841 co->addToInventoryLater(item);
1847 // hp = number of hitpoints (2 * number of hearts)
1849 static int l_set_hp(lua_State *L)
1851 ObjectRef *ref = checkobject(L, 1);
1852 luaL_checknumber(L, 2);
1853 ServerActiveObject *co = getobject(ref);
1854 if(co == NULL) return 0;
1855 int hp = lua_tonumber(L, 2);
1856 infostream<<"ObjectRef::l_set_hp(): id="<<co->getId()
1857 <<" hp="<<hp<<std::endl;
1865 // returns: number of hitpoints (2 * number of hearts)
1866 // 0 if not applicable to this type of object
1867 static int l_get_hp(lua_State *L)
1869 ObjectRef *ref = checkobject(L, 1);
1870 ServerActiveObject *co = getobject(ref);
1871 if(co == NULL) return 0;
1872 int hp = co->getHP();
1873 infostream<<"ObjectRef::l_get_hp(): id="<<co->getId()
1874 <<" hp="<<hp<<std::endl;
1876 lua_pushnumber(L, hp);
1880 /* LuaEntitySAO-only */
1882 // setvelocity(self, {x=num, y=num, z=num})
1883 static int l_setvelocity(lua_State *L)
1885 ObjectRef *ref = checkobject(L, 1);
1886 LuaEntitySAO *co = getluaobject(ref);
1887 if(co == NULL) return 0;
1889 v3f pos = readFloatPos(L, 2);
1891 co->setVelocity(pos);
1895 // setacceleration(self, {x=num, y=num, z=num})
1896 static int l_setacceleration(lua_State *L)
1898 ObjectRef *ref = checkobject(L, 1);
1899 LuaEntitySAO *co = getluaobject(ref);
1900 if(co == NULL) return 0;
1902 v3f pos = readFloatPos(L, 2);
1904 co->setAcceleration(pos);
1908 // getacceleration(self)
1909 static int l_getacceleration(lua_State *L)
1911 ObjectRef *ref = checkobject(L, 1);
1912 LuaEntitySAO *co = getluaobject(ref);
1913 if(co == NULL) return 0;
1915 v3f v = co->getAcceleration();
1920 // settexturemod(self, mod)
1921 static int l_settexturemod(lua_State *L)
1923 ObjectRef *ref = checkobject(L, 1);
1924 LuaEntitySAO *co = getluaobject(ref);
1925 if(co == NULL) return 0;
1927 std::string mod = lua_tostring(L, 2);
1928 co->setTextureMod(mod);
1932 // setsprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2,
1933 // select_horiz_by_yawpitch=false)
1934 static int l_setsprite(lua_State *L)
1936 ObjectRef *ref = checkobject(L, 1);
1937 LuaEntitySAO *co = getluaobject(ref);
1938 if(co == NULL) return 0;
1941 if(!lua_isnil(L, 2))
1942 p = read_v2s16(L, 2);
1944 if(!lua_isnil(L, 3))
1945 num_frames = lua_tonumber(L, 3);
1946 float framelength = 0.2;
1947 if(!lua_isnil(L, 4))
1948 framelength = lua_tonumber(L, 4);
1949 bool select_horiz_by_yawpitch = false;
1950 if(!lua_isnil(L, 5))
1951 select_horiz_by_yawpitch = lua_toboolean(L, 5);
1952 co->setSprite(p, num_frames, framelength, select_horiz_by_yawpitch);
1958 // get_player_name(self)
1959 static int l_get_player_name(lua_State *L)
1961 ObjectRef *ref = checkobject(L, 1);
1962 ServerRemotePlayer *player = getplayer(ref);
1968 lua_pushstring(L, player->getName());
1972 // inventory_set_list(self, name, {item1, item2, ...})
1973 static int l_inventory_set_list(lua_State *L)
1975 ObjectRef *ref = checkobject(L, 1);
1976 ServerRemotePlayer *player = getplayer(ref);
1977 if(player == NULL) return 0;
1978 const char *name = lua_tostring(L, 2);
1980 inventory_set_list_from_lua(&player->inventory, name, L, 3,
1981 player->getEnv()->getGameDef(), PLAYER_INVENTORY_SIZE);
1982 player->m_inventory_not_sent = true;
1986 // inventory_get_list(self, name)
1987 static int l_inventory_get_list(lua_State *L)
1989 ObjectRef *ref = checkobject(L, 1);
1990 ServerRemotePlayer *player = getplayer(ref);
1991 if(player == NULL) return 0;
1992 const char *name = lua_tostring(L, 2);
1994 inventory_get_list_to_lua(&player->inventory, name, L);
1998 // get_wielded_itemstring(self)
1999 static int l_get_wielded_itemstring(lua_State *L)
2001 ObjectRef *ref = checkobject(L, 1);
2002 ServerRemotePlayer *player = getplayer(ref);
2003 if(player == NULL) return 0;
2005 InventoryItem *item = player->getWieldedItem();
2010 lua_pushstring(L, item->getItemString().c_str());
2014 // get_wielded_item(self)
2015 static int l_get_wielded_item(lua_State *L)
2017 ObjectRef *ref = checkobject(L, 1);
2018 ServerRemotePlayer *player = getplayer(ref);
2019 if(player == NULL) return 0;
2021 InventoryItem *item0 = player->getWieldedItem();
2026 if(std::string("MaterialItem") == item0->getName()){
2027 MaterialItem *item = (MaterialItem*)item0;
2029 lua_pushstring(L, "NodeItem");
2030 lua_setfield(L, -2, "type");
2031 lua_pushstring(L, item->getNodeName().c_str());
2032 lua_setfield(L, -2, "name");
2034 else if(std::string("CraftItem") == item0->getName()){
2035 CraftItem *item = (CraftItem*)item0;
2037 lua_pushstring(L, "CraftItem");
2038 lua_setfield(L, -2, "type");
2039 lua_pushstring(L, item->getSubName().c_str());
2040 lua_setfield(L, -2, "name");
2042 else if(std::string("ToolItem") == item0->getName()){
2043 ToolItem *item = (ToolItem*)item0;
2045 lua_pushstring(L, "ToolItem");
2046 lua_setfield(L, -2, "type");
2047 lua_pushstring(L, item->getToolName().c_str());
2048 lua_setfield(L, -2, "name");
2049 lua_pushstring(L, itos(item->getWear()).c_str());
2050 lua_setfield(L, -2, "wear");
2053 errorstream<<"l_get_wielded_item: Unknown item name: \""
2054 <<item0->getName()<<"\""<<std::endl;
2061 ObjectRef(ServerActiveObject *object):
2064 //infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
2070 infostream<<"ObjectRef destructing for id="
2071 <<m_object->getId()<<std::endl;
2073 infostream<<"ObjectRef destructing for id=unknown"<<std::endl;*/
2076 // Creates an ObjectRef and leaves it on top of stack
2077 // Not callable from Lua; all references are created on the C side.
2078 static void create(lua_State *L, ServerActiveObject *object)
2080 ObjectRef *o = new ObjectRef(object);
2081 //infostream<<"ObjectRef::create: o="<<o<<std::endl;
2082 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
2083 luaL_getmetatable(L, className);
2084 lua_setmetatable(L, -2);
2087 static void set_null(lua_State *L)
2089 ObjectRef *o = checkobject(L, -1);
2093 static void Register(lua_State *L)
2096 int methodtable = lua_gettop(L);
2097 luaL_newmetatable(L, className);
2098 int metatable = lua_gettop(L);
2100 lua_pushliteral(L, "__metatable");
2101 lua_pushvalue(L, methodtable);
2102 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
2104 lua_pushliteral(L, "__index");
2105 lua_pushvalue(L, methodtable);
2106 lua_settable(L, metatable);
2108 lua_pushliteral(L, "__gc");
2109 lua_pushcfunction(L, gc_object);
2110 lua_settable(L, metatable);
2112 lua_pop(L, 1); // drop metatable
2114 luaL_openlib(L, 0, methods, 0); // fill methodtable
2115 lua_pop(L, 1); // drop methodtable
2117 // Cannot be created from Lua
2118 //lua_register(L, className, create_object);
2121 const char ObjectRef::className[] = "ObjectRef";
2122 const luaL_reg ObjectRef::methods[] = {
2123 // ServerActiveObject
2124 method(ObjectRef, remove),
2125 method(ObjectRef, getpos),
2126 method(ObjectRef, setpos),
2127 method(ObjectRef, moveto),
2128 method(ObjectRef, punch),
2129 method(ObjectRef, right_click),
2130 method(ObjectRef, get_wield_digging_properties),
2131 method(ObjectRef, damage_wielded_item),
2132 method(ObjectRef, add_to_inventory),
2133 method(ObjectRef, add_to_inventory_later),
2134 method(ObjectRef, set_hp),
2135 method(ObjectRef, get_hp),
2136 // LuaEntitySAO-only
2137 method(ObjectRef, setvelocity),
2138 method(ObjectRef, setacceleration),
2139 method(ObjectRef, getacceleration),
2140 method(ObjectRef, settexturemod),
2141 method(ObjectRef, setsprite),
2143 method(ObjectRef, get_player_name),
2144 method(ObjectRef, inventory_set_list),
2145 method(ObjectRef, inventory_get_list),
2146 method(ObjectRef, get_wielded_itemstring),
2147 method(ObjectRef, get_wielded_item),
2151 // Creates a new anonymous reference if id=0
2152 static void objectref_get_or_create(lua_State *L,
2153 ServerActiveObject *cobj)
2155 if(cobj->getId() == 0){
2156 ObjectRef::create(L, cobj);
2158 objectref_get(L, cobj->getId());
2169 ServerEnvironment *m_env;
2171 static const char className[];
2172 static const luaL_reg methods[];
2174 static EnvRef *checkobject(lua_State *L, int narg)
2176 luaL_checktype(L, narg, LUA_TUSERDATA);
2177 void *ud = luaL_checkudata(L, narg, className);
2178 if(!ud) luaL_typerror(L, narg, className);
2179 return *(EnvRef**)ud; // unbox pointer
2182 // Exported functions
2184 // EnvRef:add_node(pos, node)
2185 // pos = {x=num, y=num, z=num}
2186 static int l_add_node(lua_State *L)
2188 //infostream<<"EnvRef::l_add_node()"<<std::endl;
2189 EnvRef *o = checkobject(L, 1);
2190 ServerEnvironment *env = o->m_env;
2191 if(env == NULL) return 0;
2193 v3s16 pos = readpos(L, 2);
2195 MapNode n = readnode(L, 3, env->getGameDef()->ndef());
2197 bool succeeded = env->getMap().addNodeWithEvent(pos, n);
2198 lua_pushboolean(L, succeeded);
2202 // EnvRef:remove_node(pos)
2203 // pos = {x=num, y=num, z=num}
2204 static int l_remove_node(lua_State *L)
2206 //infostream<<"EnvRef::l_remove_node()"<<std::endl;
2207 EnvRef *o = checkobject(L, 1);
2208 ServerEnvironment *env = o->m_env;
2209 if(env == NULL) return 0;
2211 v3s16 pos = readpos(L, 2);
2213 bool succeeded = env->getMap().removeNodeWithEvent(pos);
2214 lua_pushboolean(L, succeeded);
2218 // EnvRef:get_node(pos)
2219 // pos = {x=num, y=num, z=num}
2220 static int l_get_node(lua_State *L)
2222 //infostream<<"EnvRef::l_get_node()"<<std::endl;
2223 EnvRef *o = checkobject(L, 1);
2224 ServerEnvironment *env = o->m_env;
2225 if(env == NULL) return 0;
2227 v3s16 pos = readpos(L, 2);
2229 MapNode n = env->getMap().getNodeNoEx(pos);
2231 pushnode(L, n, env->getGameDef()->ndef());
2235 // EnvRef:add_luaentity(pos, entityname)
2236 // pos = {x=num, y=num, z=num}
2237 static int l_add_luaentity(lua_State *L)
2239 //infostream<<"EnvRef::l_add_luaentity()"<<std::endl;
2240 EnvRef *o = checkobject(L, 1);
2241 ServerEnvironment *env = o->m_env;
2242 if(env == NULL) return 0;
2244 v3f pos = readFloatPos(L, 2);
2246 const char *name = lua_tostring(L, 3);
2248 ServerActiveObject *obj = new LuaEntitySAO(env, pos, name, "");
2249 env->addActiveObject(obj);
2253 // EnvRef:add_item(pos, inventorystring)
2254 // pos = {x=num, y=num, z=num}
2255 static int l_add_item(lua_State *L)
2257 infostream<<"EnvRef::l_add_item()"<<std::endl;
2258 EnvRef *o = checkobject(L, 1);
2259 ServerEnvironment *env = o->m_env;
2260 if(env == NULL) return 0;
2262 v3f pos = readFloatPos(L, 2);
2264 const char *inventorystring = lua_tostring(L, 3);
2266 ServerActiveObject *obj = new ItemSAO(env, pos, inventorystring);
2267 env->addActiveObject(obj);
2271 // EnvRef:add_rat(pos)
2272 // pos = {x=num, y=num, z=num}
2273 static int l_add_rat(lua_State *L)
2275 infostream<<"EnvRef::l_add_rat()"<<std::endl;
2276 EnvRef *o = checkobject(L, 1);
2277 ServerEnvironment *env = o->m_env;
2278 if(env == NULL) return 0;
2280 v3f pos = readFloatPos(L, 2);
2282 ServerActiveObject *obj = new RatSAO(env, pos);
2283 env->addActiveObject(obj);
2287 // EnvRef:add_firefly(pos)
2288 // pos = {x=num, y=num, z=num}
2289 static int l_add_firefly(lua_State *L)
2291 infostream<<"EnvRef::l_add_firefly()"<<std::endl;
2292 EnvRef *o = checkobject(L, 1);
2293 ServerEnvironment *env = o->m_env;
2294 if(env == NULL) return 0;
2296 v3f pos = readFloatPos(L, 2);
2298 ServerActiveObject *obj = new FireflySAO(env, pos);
2299 env->addActiveObject(obj);
2303 // EnvRef:get_meta(pos)
2304 static int l_get_meta(lua_State *L)
2306 //infostream<<"EnvRef::l_get_meta()"<<std::endl;
2307 EnvRef *o = checkobject(L, 1);
2308 ServerEnvironment *env = o->m_env;
2309 if(env == NULL) return 0;
2311 v3s16 p = readpos(L, 2);
2312 NodeMetaRef::create(L, p, env);
2316 // EnvRef:get_player_by_name(name)
2317 static int l_get_player_by_name(lua_State *L)
2319 EnvRef *o = checkobject(L, 1);
2320 ServerEnvironment *env = o->m_env;
2321 if(env == NULL) return 0;
2323 const char *name = lua_tostring(L, 2);
2324 ServerRemotePlayer *player =
2325 static_cast<ServerRemotePlayer*>(env->getPlayer(name));
2330 // Put player on stack
2331 objectref_get_or_create(L, player);
2335 static int gc_object(lua_State *L) {
2336 EnvRef *o = *(EnvRef **)(lua_touserdata(L, 1));
2342 EnvRef(ServerEnvironment *env):
2345 infostream<<"EnvRef created"<<std::endl;
2350 infostream<<"EnvRef destructing"<<std::endl;
2353 // Creates an EnvRef and leaves it on top of stack
2354 // Not callable from Lua; all references are created on the C side.
2355 static void create(lua_State *L, ServerEnvironment *env)
2357 EnvRef *o = new EnvRef(env);
2358 //infostream<<"EnvRef::create: o="<<o<<std::endl;
2359 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
2360 luaL_getmetatable(L, className);
2361 lua_setmetatable(L, -2);
2364 static void set_null(lua_State *L)
2366 EnvRef *o = checkobject(L, -1);
2370 static void Register(lua_State *L)
2373 int methodtable = lua_gettop(L);
2374 luaL_newmetatable(L, className);
2375 int metatable = lua_gettop(L);
2377 lua_pushliteral(L, "__metatable");
2378 lua_pushvalue(L, methodtable);
2379 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
2381 lua_pushliteral(L, "__index");
2382 lua_pushvalue(L, methodtable);
2383 lua_settable(L, metatable);
2385 lua_pushliteral(L, "__gc");
2386 lua_pushcfunction(L, gc_object);
2387 lua_settable(L, metatable);
2389 lua_pop(L, 1); // drop metatable
2391 luaL_openlib(L, 0, methods, 0); // fill methodtable
2392 lua_pop(L, 1); // drop methodtable
2394 // Cannot be created from Lua
2395 //lua_register(L, className, create_object);
2398 const char EnvRef::className[] = "EnvRef";
2399 const luaL_reg EnvRef::methods[] = {
2400 method(EnvRef, add_node),
2401 method(EnvRef, remove_node),
2402 method(EnvRef, get_node),
2403 method(EnvRef, add_luaentity),
2404 method(EnvRef, add_item),
2405 method(EnvRef, add_rat),
2406 method(EnvRef, add_firefly),
2407 method(EnvRef, get_meta),
2408 method(EnvRef, get_player_by_name),
2413 Main export function
2416 void scriptapi_export(lua_State *L, Server *server)
2419 assert(lua_checkstack(L, 20));
2420 infostream<<"scriptapi_export"<<std::endl;
2421 StackUnroller stack_unroller(L);
2423 // Store server as light userdata in registry
2424 lua_pushlightuserdata(L, server);
2425 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_server");
2427 // Store nil as minetest_nodedef_defaults in registry
2429 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
2431 // Register global functions in table minetest
2433 luaL_register(L, NULL, minetest_f);
2434 lua_setglobal(L, "minetest");
2436 // Get the main minetest table
2437 lua_getglobal(L, "minetest");
2439 // Add tables to minetest
2442 lua_setfield(L, -2, "registered_nodes");
2444 lua_setfield(L, -2, "registered_entities");
2446 lua_setfield(L, -2, "registered_craftitems");
2448 lua_setfield(L, -2, "registered_abms");
2451 lua_setfield(L, -2, "object_refs");
2453 lua_setfield(L, -2, "luaentities");
2455 // Create entity prototype
2456 luaL_newmetatable(L, "minetest.entity");
2457 // metatable.__index = metatable
2458 lua_pushvalue(L, -1); // Duplicate metatable
2459 lua_setfield(L, -2, "__index");
2460 // Put functions in metatable
2461 luaL_register(L, NULL, minetest_entity_m);
2462 // Put other stuff in metatable
2464 // Register reference wrappers
2465 NodeMetaRef::Register(L);
2466 EnvRef::Register(L);
2467 ObjectRef::Register(L);
2470 void scriptapi_add_environment(lua_State *L, ServerEnvironment *env)
2473 assert(lua_checkstack(L, 20));
2474 infostream<<"scriptapi_add_environment"<<std::endl;
2475 StackUnroller stack_unroller(L);
2477 // Create EnvRef on stack
2478 EnvRef::create(L, env);
2479 int envref = lua_gettop(L);
2481 // minetest.env = envref
2482 lua_getglobal(L, "minetest");
2483 luaL_checktype(L, -1, LUA_TTABLE);
2484 lua_pushvalue(L, envref);
2485 lua_setfield(L, -2, "env");
2487 // Store environment as light userdata in registry
2488 lua_pushlightuserdata(L, env);
2489 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_env");
2491 /* Add ActiveBlockModifiers to environment */
2493 // Get minetest.registered_abms
2494 lua_getglobal(L, "minetest");
2495 lua_getfield(L, -1, "registered_abms");
2496 luaL_checktype(L, -1, LUA_TTABLE);
2497 int registered_abms = lua_gettop(L);
2499 if(lua_istable(L, registered_abms)){
2500 int table = lua_gettop(L);
2502 while(lua_next(L, table) != 0){
2503 // key at index -2 and value at index -1
2504 int id = lua_tonumber(L, -2);
2505 int current_abm = lua_gettop(L);
2507 std::set<std::string> trigger_contents;
2508 lua_getfield(L, current_abm, "nodenames");
2509 if(lua_istable(L, -1)){
2510 int table = lua_gettop(L);
2512 while(lua_next(L, table) != 0){
2513 // key at index -2 and value at index -1
2514 luaL_checktype(L, -1, LUA_TSTRING);
2515 trigger_contents.insert(lua_tostring(L, -1));
2516 // removes value, keeps key for next iteration
2522 float trigger_interval = 10.0;
2523 getfloatfield(L, current_abm, "interval", trigger_interval);
2525 int trigger_chance = 50;
2526 getintfield(L, current_abm, "chance", trigger_chance);
2528 LuaABM *abm = new LuaABM(L, id, trigger_contents,
2529 trigger_interval, trigger_chance);
2531 env->addActiveBlockModifier(abm);
2533 // removes value, keeps key for next iteration
2541 // Dump stack top with the dump2 function
2542 static void dump2(lua_State *L, const char *name)
2544 // Dump object (debug)
2545 lua_getglobal(L, "dump2");
2546 luaL_checktype(L, -1, LUA_TFUNCTION);
2547 lua_pushvalue(L, -2); // Get previous stack top as first parameter
2548 lua_pushstring(L, name);
2549 if(lua_pcall(L, 2, 0, 0))
2550 script_error(L, "error: %s\n", lua_tostring(L, -1));
2558 void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj)
2561 assert(lua_checkstack(L, 20));
2562 //infostream<<"scriptapi_add_object_reference: id="<<cobj->getId()<<std::endl;
2563 StackUnroller stack_unroller(L);
2565 // Create object on stack
2566 ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack
2567 int object = lua_gettop(L);
2569 // Get minetest.object_refs table
2570 lua_getglobal(L, "minetest");
2571 lua_getfield(L, -1, "object_refs");
2572 luaL_checktype(L, -1, LUA_TTABLE);
2573 int objectstable = lua_gettop(L);
2575 // object_refs[id] = object
2576 lua_pushnumber(L, cobj->getId()); // Push id
2577 lua_pushvalue(L, object); // Copy object to top of stack
2578 lua_settable(L, objectstable);
2581 void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj)
2584 assert(lua_checkstack(L, 20));
2585 //infostream<<"scriptapi_rm_object_reference: id="<<cobj->getId()<<std::endl;
2586 StackUnroller stack_unroller(L);
2588 // Get minetest.object_refs table
2589 lua_getglobal(L, "minetest");
2590 lua_getfield(L, -1, "object_refs");
2591 luaL_checktype(L, -1, LUA_TTABLE);
2592 int objectstable = lua_gettop(L);
2594 // Get object_refs[id]
2595 lua_pushnumber(L, cobj->getId()); // Push id
2596 lua_gettable(L, objectstable);
2597 // Set object reference to NULL
2598 ObjectRef::set_null(L);
2599 lua_pop(L, 1); // pop object
2601 // Set object_refs[id] = nil
2602 lua_pushnumber(L, cobj->getId()); // Push id
2604 lua_settable(L, objectstable);
2607 bool scriptapi_on_chat_message(lua_State *L, const std::string &name,
2608 const std::string &message)
2611 assert(lua_checkstack(L, 20));
2612 StackUnroller stack_unroller(L);
2614 // Get minetest.registered_on_chat_messages
2615 lua_getglobal(L, "minetest");
2616 lua_getfield(L, -1, "registered_on_chat_messages");
2617 luaL_checktype(L, -1, LUA_TTABLE);
2618 int table = lua_gettop(L);
2621 while(lua_next(L, table) != 0){
2622 // key at index -2 and value at index -1
2623 luaL_checktype(L, -1, LUA_TFUNCTION);
2625 lua_pushstring(L, name.c_str());
2626 lua_pushstring(L, message.c_str());
2627 if(lua_pcall(L, 2, 1, 0))
2628 script_error(L, "error: %s\n", lua_tostring(L, -1));
2629 bool ate = lua_toboolean(L, -1);
2633 // value removed, keep key for next iteration
2642 void scriptapi_on_newplayer(lua_State *L, ServerActiveObject *player)
2645 assert(lua_checkstack(L, 20));
2646 StackUnroller stack_unroller(L);
2648 // Get minetest.registered_on_newplayers
2649 lua_getglobal(L, "minetest");
2650 lua_getfield(L, -1, "registered_on_newplayers");
2651 luaL_checktype(L, -1, LUA_TTABLE);
2652 int table = lua_gettop(L);
2655 while(lua_next(L, table) != 0){
2656 // key at index -2 and value at index -1
2657 luaL_checktype(L, -1, LUA_TFUNCTION);
2659 objectref_get_or_create(L, player);
2660 if(lua_pcall(L, 1, 0, 0))
2661 script_error(L, "error: %s\n", lua_tostring(L, -1));
2662 // value removed, keep key for next iteration
2665 bool scriptapi_on_respawnplayer(lua_State *L, ServerActiveObject *player)
2668 assert(lua_checkstack(L, 20));
2669 StackUnroller stack_unroller(L);
2671 bool positioning_handled_by_some = false;
2673 // Get minetest.registered_on_respawnplayers
2674 lua_getglobal(L, "minetest");
2675 lua_getfield(L, -1, "registered_on_respawnplayers");
2676 luaL_checktype(L, -1, LUA_TTABLE);
2677 int table = lua_gettop(L);
2680 while(lua_next(L, table) != 0){
2681 // key at index -2 and value at index -1
2682 luaL_checktype(L, -1, LUA_TFUNCTION);
2684 objectref_get_or_create(L, player);
2685 if(lua_pcall(L, 1, 1, 0))
2686 script_error(L, "error: %s\n", lua_tostring(L, -1));
2687 bool positioning_handled = lua_toboolean(L, -1);
2689 if(positioning_handled)
2690 positioning_handled_by_some = true;
2691 // value removed, keep key for next iteration
2693 return positioning_handled_by_some;
2700 static void pushPointedThing(lua_State *L, const PointedThing& pointed)
2703 if(pointed.type == POINTEDTHING_NODE)
2705 lua_pushstring(L, "node");
2706 lua_setfield(L, -2, "type");
2707 pushpos(L, pointed.node_undersurface);
2708 lua_setfield(L, -2, "under");
2709 pushpos(L, pointed.node_abovesurface);
2710 lua_setfield(L, -2, "above");
2712 else if(pointed.type == POINTEDTHING_OBJECT)
2714 lua_pushstring(L, "object");
2715 lua_setfield(L, -2, "type");
2716 objectref_get(L, pointed.object_id);
2717 lua_setfield(L, -2, "ref");
2721 lua_pushstring(L, "nothing");
2722 lua_setfield(L, -2, "type");
2726 void scriptapi_add_craftitem(lua_State *L, const char *name)
2728 StackUnroller stack_unroller(L);
2729 assert(lua_gettop(L) > 0);
2731 // Set minetest.registered_craftitems[name] = table on top of stack
2732 lua_getglobal(L, "minetest");
2733 lua_getfield(L, -1, "registered_craftitems");
2734 luaL_checktype(L, -1, LUA_TTABLE);
2735 lua_pushvalue(L, -3); // push another reference to the table to be registered
2736 lua_setfield(L, -2, name); // set minetest.registered_craftitems[name]
2739 static bool get_craftitem_callback(lua_State *L, const char *name,
2740 const char *callbackname)
2742 // Get minetest.registered_craftitems[name][callbackname]
2743 // If that is nil or on error, return false and stack is unchanged
2744 // If that is a function, returns true and pushes the
2745 // function onto the stack
2747 lua_getglobal(L, "minetest");
2748 lua_getfield(L, -1, "registered_craftitems");
2750 luaL_checktype(L, -1, LUA_TTABLE);
2751 lua_getfield(L, -1, name);
2753 // Should be a table
2754 if(lua_type(L, -1) != LUA_TTABLE)
2756 errorstream<<"CraftItem name \""<<name<<"\" not defined"<<std::endl;
2760 lua_getfield(L, -1, callbackname);
2762 // Should be a function or nil
2763 if(lua_type(L, -1) == LUA_TFUNCTION)
2767 else if(lua_isnil(L, -1))
2774 errorstream<<"CraftItem name \""<<name<<"\" callback \""
2775 <<callbackname<<" is not a function"<<std::endl;
2781 bool scriptapi_craftitem_on_drop(lua_State *L, const char *name,
2782 ServerActiveObject *dropper, v3f pos,
2783 bool &callback_exists)
2786 assert(lua_checkstack(L, 20));
2787 //infostream<<"scriptapi_craftitem_on_drop"<<std::endl;
2788 StackUnroller stack_unroller(L);
2790 bool result = false;
2791 callback_exists = get_craftitem_callback(L, name, "on_drop");
2795 lua_pushstring(L, name);
2796 objectref_get_or_create(L, dropper);
2797 pushFloatPos(L, pos);
2798 if(lua_pcall(L, 3, 1, 0))
2799 script_error(L, "error: %s\n", lua_tostring(L, -1));
2800 result = lua_toboolean(L, -1);
2805 bool scriptapi_craftitem_on_place_on_ground(lua_State *L, const char *name,
2806 ServerActiveObject *placer, v3f pos,
2807 bool &callback_exists)
2810 assert(lua_checkstack(L, 20));
2811 //infostream<<"scriptapi_craftitem_on_place_on_ground"<<std::endl;
2812 StackUnroller stack_unroller(L);
2814 bool result = false;
2815 callback_exists = get_craftitem_callback(L, name, "on_place_on_ground");
2819 lua_pushstring(L, name);
2820 objectref_get_or_create(L, placer);
2821 pushFloatPos(L, pos);
2822 if(lua_pcall(L, 3, 1, 0))
2823 script_error(L, "error: %s\n", lua_tostring(L, -1));
2824 result = lua_toboolean(L, -1);
2829 bool scriptapi_craftitem_on_use(lua_State *L, const char *name,
2830 ServerActiveObject *user, const PointedThing& pointed,
2831 bool &callback_exists)
2834 assert(lua_checkstack(L, 20));
2835 //infostream<<"scriptapi_craftitem_on_use"<<std::endl;
2836 StackUnroller stack_unroller(L);
2838 bool result = false;
2839 callback_exists = get_craftitem_callback(L, name, "on_use");
2843 lua_pushstring(L, name);
2844 objectref_get_or_create(L, user);
2845 pushPointedThing(L, pointed);
2846 if(lua_pcall(L, 3, 1, 0))
2847 script_error(L, "error: %s\n", lua_tostring(L, -1));
2848 result = lua_toboolean(L, -1);
2857 void scriptapi_environment_step(lua_State *L, float dtime)
2860 assert(lua_checkstack(L, 20));
2861 //infostream<<"scriptapi_environment_step"<<std::endl;
2862 StackUnroller stack_unroller(L);
2864 // Get minetest.registered_globalsteps
2865 lua_getglobal(L, "minetest");
2866 lua_getfield(L, -1, "registered_globalsteps");
2867 luaL_checktype(L, -1, LUA_TTABLE);
2868 int table = lua_gettop(L);
2871 while(lua_next(L, table) != 0){
2872 // key at index -2 and value at index -1
2873 luaL_checktype(L, -1, LUA_TFUNCTION);
2875 lua_pushnumber(L, dtime);
2876 if(lua_pcall(L, 1, 0, 0))
2877 script_error(L, "error: %s\n", lua_tostring(L, -1));
2878 // value removed, keep key for next iteration
2882 void scriptapi_environment_on_placenode(lua_State *L, v3s16 p, MapNode newnode,
2883 ServerActiveObject *placer)
2886 assert(lua_checkstack(L, 20));
2887 //infostream<<"scriptapi_environment_on_placenode"<<std::endl;
2888 StackUnroller stack_unroller(L);
2890 // Get server from registry
2891 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
2892 Server *server = (Server*)lua_touserdata(L, -1);
2893 // And get the writable node definition manager from the server
2894 IWritableNodeDefManager *ndef =
2895 server->getWritableNodeDefManager();
2897 // Get minetest.registered_on_placenodes
2898 lua_getglobal(L, "minetest");
2899 lua_getfield(L, -1, "registered_on_placenodes");
2900 luaL_checktype(L, -1, LUA_TTABLE);
2901 int table = lua_gettop(L);
2904 while(lua_next(L, table) != 0){
2905 // key at index -2 and value at index -1
2906 luaL_checktype(L, -1, LUA_TFUNCTION);
2909 pushnode(L, newnode, ndef);
2910 objectref_get_or_create(L, placer);
2911 if(lua_pcall(L, 3, 0, 0))
2912 script_error(L, "error: %s\n", lua_tostring(L, -1));
2913 // value removed, keep key for next iteration
2917 void scriptapi_environment_on_dignode(lua_State *L, v3s16 p, MapNode oldnode,
2918 ServerActiveObject *digger)
2921 assert(lua_checkstack(L, 20));
2922 //infostream<<"scriptapi_environment_on_dignode"<<std::endl;
2923 StackUnroller stack_unroller(L);
2925 // Get server from registry
2926 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
2927 Server *server = (Server*)lua_touserdata(L, -1);
2928 // And get the writable node definition manager from the server
2929 IWritableNodeDefManager *ndef =
2930 server->getWritableNodeDefManager();
2932 // Get minetest.registered_on_dignodes
2933 lua_getglobal(L, "minetest");
2934 lua_getfield(L, -1, "registered_on_dignodes");
2935 luaL_checktype(L, -1, LUA_TTABLE);
2936 int table = lua_gettop(L);
2939 while(lua_next(L, table) != 0){
2940 // key at index -2 and value at index -1
2941 luaL_checktype(L, -1, LUA_TFUNCTION);
2944 pushnode(L, oldnode, ndef);
2945 objectref_get_or_create(L, digger);
2946 if(lua_pcall(L, 3, 0, 0))
2947 script_error(L, "error: %s\n", lua_tostring(L, -1));
2948 // value removed, keep key for next iteration
2952 void scriptapi_environment_on_punchnode(lua_State *L, v3s16 p, MapNode node,
2953 ServerActiveObject *puncher)
2956 assert(lua_checkstack(L, 20));
2957 //infostream<<"scriptapi_environment_on_punchnode"<<std::endl;
2958 StackUnroller stack_unroller(L);
2960 // Get server from registry
2961 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
2962 Server *server = (Server*)lua_touserdata(L, -1);
2963 // And get the writable node definition manager from the server
2964 IWritableNodeDefManager *ndef =
2965 server->getWritableNodeDefManager();
2967 // Get minetest.registered_on_punchnodes
2968 lua_getglobal(L, "minetest");
2969 lua_getfield(L, -1, "registered_on_punchnodes");
2970 luaL_checktype(L, -1, LUA_TTABLE);
2971 int table = lua_gettop(L);
2974 while(lua_next(L, table) != 0){
2975 // key at index -2 and value at index -1
2976 luaL_checktype(L, -1, LUA_TFUNCTION);
2979 pushnode(L, node, ndef);
2980 objectref_get_or_create(L, puncher);
2981 if(lua_pcall(L, 3, 0, 0))
2982 script_error(L, "error: %s\n", lua_tostring(L, -1));
2983 // value removed, keep key for next iteration
2987 void scriptapi_environment_on_generated(lua_State *L, v3s16 minp, v3s16 maxp)
2990 assert(lua_checkstack(L, 20));
2991 //infostream<<"scriptapi_environment_on_generated"<<std::endl;
2992 StackUnroller stack_unroller(L);
2994 // Get minetest.registered_on_generateds
2995 lua_getglobal(L, "minetest");
2996 lua_getfield(L, -1, "registered_on_generateds");
2997 luaL_checktype(L, -1, LUA_TTABLE);
2998 int table = lua_gettop(L);
3001 while(lua_next(L, table) != 0){
3002 // key at index -2 and value at index -1
3003 luaL_checktype(L, -1, LUA_TFUNCTION);
3007 if(lua_pcall(L, 2, 0, 0))
3008 script_error(L, "error: %s\n", lua_tostring(L, -1));
3009 // value removed, keep key for next iteration
3017 bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
3018 const std::string &staticdata)
3021 assert(lua_checkstack(L, 20));
3022 infostream<<"scriptapi_luaentity_add: id="<<id<<" name=\""
3023 <<name<<"\""<<std::endl;
3024 StackUnroller stack_unroller(L);
3026 // Get minetest.registered_entities[name]
3027 lua_getglobal(L, "minetest");
3028 lua_getfield(L, -1, "registered_entities");
3029 luaL_checktype(L, -1, LUA_TTABLE);
3030 lua_pushstring(L, name);
3031 lua_gettable(L, -2);
3032 // Should be a table, which we will use as a prototype
3033 //luaL_checktype(L, -1, LUA_TTABLE);
3034 if(lua_type(L, -1) != LUA_TTABLE){
3035 errorstream<<"LuaEntity name \""<<name<<"\" not defined"<<std::endl;
3038 int prototype_table = lua_gettop(L);
3039 //dump2(L, "prototype_table");
3041 // Create entity object
3043 int object = lua_gettop(L);
3045 // Set object metatable
3046 lua_pushvalue(L, prototype_table);
3047 lua_setmetatable(L, -2);
3049 // Add object reference
3050 // This should be userdata with metatable ObjectRef
3051 objectref_get(L, id);
3052 luaL_checktype(L, -1, LUA_TUSERDATA);
3053 if(!luaL_checkudata(L, -1, "ObjectRef"))
3054 luaL_typerror(L, -1, "ObjectRef");
3055 lua_setfield(L, -2, "object");
3057 // minetest.luaentities[id] = object
3058 lua_getglobal(L, "minetest");
3059 lua_getfield(L, -1, "luaentities");
3060 luaL_checktype(L, -1, LUA_TTABLE);
3061 lua_pushnumber(L, id); // Push id
3062 lua_pushvalue(L, object); // Copy object to top of stack
3063 lua_settable(L, -3);
3065 // Get on_activate function
3066 lua_pushvalue(L, object);
3067 lua_getfield(L, -1, "on_activate");
3068 if(!lua_isnil(L, -1)){
3069 luaL_checktype(L, -1, LUA_TFUNCTION);
3070 lua_pushvalue(L, object); // self
3071 lua_pushlstring(L, staticdata.c_str(), staticdata.size());
3072 // Call with 2 arguments, 0 results
3073 if(lua_pcall(L, 2, 0, 0))
3074 script_error(L, "error running function %s:on_activate: %s\n",
3075 name, lua_tostring(L, -1));
3081 void scriptapi_luaentity_rm(lua_State *L, u16 id)
3084 assert(lua_checkstack(L, 20));
3085 infostream<<"scriptapi_luaentity_rm: id="<<id<<std::endl;
3087 // Get minetest.luaentities table
3088 lua_getglobal(L, "minetest");
3089 lua_getfield(L, -1, "luaentities");
3090 luaL_checktype(L, -1, LUA_TTABLE);
3091 int objectstable = lua_gettop(L);
3093 // Set luaentities[id] = nil
3094 lua_pushnumber(L, id); // Push id
3096 lua_settable(L, objectstable);
3098 lua_pop(L, 2); // pop luaentities, minetest
3101 std::string scriptapi_luaentity_get_staticdata(lua_State *L, u16 id)
3104 assert(lua_checkstack(L, 20));
3105 infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl;
3106 StackUnroller stack_unroller(L);
3108 // Get minetest.luaentities[id]
3109 luaentity_get(L, id);
3110 int object = lua_gettop(L);
3112 // Get get_staticdata function
3113 lua_pushvalue(L, object);
3114 lua_getfield(L, -1, "get_staticdata");
3115 if(lua_isnil(L, -1))
3118 luaL_checktype(L, -1, LUA_TFUNCTION);
3119 lua_pushvalue(L, object); // self
3120 // Call with 1 arguments, 1 results
3121 if(lua_pcall(L, 1, 1, 0))
3122 script_error(L, "error running function get_staticdata: %s\n",
3123 lua_tostring(L, -1));
3126 const char *s = lua_tolstring(L, -1, &len);
3127 return std::string(s, len);
3130 void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
3131 LuaEntityProperties *prop)
3134 assert(lua_checkstack(L, 20));
3135 infostream<<"scriptapi_luaentity_get_properties: id="<<id<<std::endl;
3136 StackUnroller stack_unroller(L);
3138 // Get minetest.luaentities[id]
3139 luaentity_get(L, id);
3140 //int object = lua_gettop(L);
3144 getboolfield(L, -1, "physical", prop->physical);
3146 getfloatfield(L, -1, "weight", prop->weight);
3148 lua_getfield(L, -1, "collisionbox");
3149 if(lua_istable(L, -1))
3150 prop->collisionbox = read_aabbox3df32(L, -1, 1.0);
3153 getstringfield(L, -1, "visual", prop->visual);
3155 lua_getfield(L, -1, "visual_size");
3156 if(lua_istable(L, -1))
3157 prop->visual_size = read_v2f(L, -1);
3160 lua_getfield(L, -1, "textures");
3161 if(lua_istable(L, -1)){
3162 prop->textures.clear();
3163 int table = lua_gettop(L);
3165 while(lua_next(L, table) != 0){
3166 // key at index -2 and value at index -1
3167 if(lua_isstring(L, -1))
3168 prop->textures.push_back(lua_tostring(L, -1));
3170 prop->textures.push_back("");
3171 // removes value, keeps key for next iteration
3177 lua_getfield(L, -1, "spritediv");
3178 if(lua_istable(L, -1))
3179 prop->spritediv = read_v2s16(L, -1);
3182 lua_getfield(L, -1, "initial_sprite_basepos");
3183 if(lua_istable(L, -1))
3184 prop->initial_sprite_basepos = read_v2s16(L, -1);
3188 void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime)
3191 assert(lua_checkstack(L, 20));
3192 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
3193 StackUnroller stack_unroller(L);
3195 // Get minetest.luaentities[id]
3196 luaentity_get(L, id);
3197 int object = lua_gettop(L);
3198 // State: object is at top of stack
3199 // Get step function
3200 lua_getfield(L, -1, "on_step");
3201 if(lua_isnil(L, -1))
3203 luaL_checktype(L, -1, LUA_TFUNCTION);
3204 lua_pushvalue(L, object); // self
3205 lua_pushnumber(L, dtime); // dtime
3206 // Call with 2 arguments, 0 results
3207 if(lua_pcall(L, 2, 0, 0))
3208 script_error(L, "error running function 'on_step': %s\n", lua_tostring(L, -1));
3211 // Calls entity:on_punch(ObjectRef puncher, time_from_last_punch)
3212 void scriptapi_luaentity_punch(lua_State *L, u16 id,
3213 ServerActiveObject *puncher, float time_from_last_punch)
3216 assert(lua_checkstack(L, 20));
3217 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
3218 StackUnroller stack_unroller(L);
3220 // Get minetest.luaentities[id]
3221 luaentity_get(L, id);
3222 int object = lua_gettop(L);
3223 // State: object is at top of stack
3225 lua_getfield(L, -1, "on_punch");
3226 if(lua_isnil(L, -1))
3228 luaL_checktype(L, -1, LUA_TFUNCTION);
3229 lua_pushvalue(L, object); // self
3230 objectref_get_or_create(L, puncher); // Clicker reference
3231 lua_pushnumber(L, time_from_last_punch);
3232 // Call with 2 arguments, 0 results
3233 if(lua_pcall(L, 3, 0, 0))
3234 script_error(L, "error running function 'on_punch': %s\n", lua_tostring(L, -1));
3237 // Calls entity:on_rightclick(ObjectRef clicker)
3238 void scriptapi_luaentity_rightclick(lua_State *L, u16 id,
3239 ServerActiveObject *clicker)
3242 assert(lua_checkstack(L, 20));
3243 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
3244 StackUnroller stack_unroller(L);
3246 // Get minetest.luaentities[id]
3247 luaentity_get(L, id);
3248 int object = lua_gettop(L);
3249 // State: object is at top of stack
3251 lua_getfield(L, -1, "on_rightclick");
3252 if(lua_isnil(L, -1))
3254 luaL_checktype(L, -1, LUA_TFUNCTION);
3255 lua_pushvalue(L, object); // self
3256 objectref_get_or_create(L, clicker); // Clicker reference
3257 // Call with 2 arguments, 0 results
3258 if(lua_pcall(L, 2, 0, 0))
3259 script_error(L, "error running function 'on_rightclick': %s\n", lua_tostring(L, -1));