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
115 ModNameStorer(lua_State *L_, const std::string modname):
118 // Store current modname in registry
119 lua_pushstring(L, modname.c_str());
120 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
124 // Clear current modname in registry
126 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
130 std::string get_current_modname(lua_State *L)
132 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
133 std::string modname = "";
134 if(lua_type(L, -1) == LUA_TSTRING)
135 modname = lua_tostring(L, -1);
140 void check_modname_prefix(lua_State *L, std::string &name)
143 throw LuaError(L, std::string("Name is empty"));
146 name = name.substr(1);
150 std::string modname = get_current_modname(L);
151 assert(modname != "");
153 // For __builtin, anything goes
154 if(modname == "__builtin")
157 if(name.substr(0, modname.size()+1) != modname + ":")
158 throw LuaError(L, std::string("Name \"")+name
159 +"\" does not follow naming conventions: "
160 +"\"modname:\" or \":\" prefix required)");
162 std::string subname = name.substr(modname.size()+1);
163 if(!string_allowed(subname, "abcdefghijklmnopqrstuvwxyz"
164 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"))
165 throw LuaError(L, std::string("Name \"")+name
166 +"\" does not follow naming conventions: "
167 +"\"contains unallowed characters");
170 static void push_v3f(lua_State *L, v3f p)
173 lua_pushnumber(L, p.X);
174 lua_setfield(L, -2, "x");
175 lua_pushnumber(L, p.Y);
176 lua_setfield(L, -2, "y");
177 lua_pushnumber(L, p.Z);
178 lua_setfield(L, -2, "z");
181 static v2s16 read_v2s16(lua_State *L, int index)
184 luaL_checktype(L, index, LUA_TTABLE);
185 lua_getfield(L, index, "x");
186 p.X = lua_tonumber(L, -1);
188 lua_getfield(L, index, "y");
189 p.Y = lua_tonumber(L, -1);
194 static v2f read_v2f(lua_State *L, int index)
197 luaL_checktype(L, index, LUA_TTABLE);
198 lua_getfield(L, index, "x");
199 p.X = lua_tonumber(L, -1);
201 lua_getfield(L, index, "y");
202 p.Y = lua_tonumber(L, -1);
207 static Server* get_server(lua_State *L)
209 // Get server from registry
210 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
211 return (Server*)lua_touserdata(L, -1);
214 static ServerEnvironment* get_env(lua_State *L)
216 // Get environment from registry
217 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_env");
218 return (ServerEnvironment*)lua_touserdata(L, -1);
221 static v3f read_v3f(lua_State *L, int index)
224 luaL_checktype(L, index, LUA_TTABLE);
225 lua_getfield(L, index, "x");
226 pos.X = lua_tonumber(L, -1);
228 lua_getfield(L, index, "y");
229 pos.Y = lua_tonumber(L, -1);
231 lua_getfield(L, index, "z");
232 pos.Z = lua_tonumber(L, -1);
237 static v3f check_v3f(lua_State *L, int index)
240 luaL_checktype(L, index, LUA_TTABLE);
241 lua_getfield(L, index, "x");
242 pos.X = luaL_checknumber(L, -1);
244 lua_getfield(L, index, "y");
245 pos.Y = luaL_checknumber(L, -1);
247 lua_getfield(L, index, "z");
248 pos.Z = luaL_checknumber(L, -1);
253 static void pushFloatPos(lua_State *L, v3f p)
259 static v3f checkFloatPos(lua_State *L, int index)
261 return check_v3f(L, index) * BS;
264 static void push_v3s16(lua_State *L, v3s16 p)
267 lua_pushnumber(L, p.X);
268 lua_setfield(L, -2, "x");
269 lua_pushnumber(L, p.Y);
270 lua_setfield(L, -2, "y");
271 lua_pushnumber(L, p.Z);
272 lua_setfield(L, -2, "z");
275 static v3s16 read_v3s16(lua_State *L, int index)
277 // Correct rounding at <0
278 v3f pf = read_v3f(L, index);
279 return floatToInt(pf, 1.0);
282 static v3s16 check_v3s16(lua_State *L, int index)
284 // Correct rounding at <0
285 v3f pf = check_v3f(L, index);
286 return floatToInt(pf, 1.0);
289 static void pushnode(lua_State *L, const MapNode &n, INodeDefManager *ndef)
292 lua_pushstring(L, ndef->get(n).name.c_str());
293 lua_setfield(L, -2, "name");
294 lua_pushnumber(L, n.getParam1());
295 lua_setfield(L, -2, "param1");
296 lua_pushnumber(L, n.getParam2());
297 lua_setfield(L, -2, "param2");
300 static MapNode readnode(lua_State *L, int index, INodeDefManager *ndef)
302 lua_getfield(L, index, "name");
303 const char *name = luaL_checkstring(L, -1);
306 lua_getfield(L, index, "param1");
310 param1 = lua_tonumber(L, -1);
313 lua_getfield(L, index, "param2");
317 param2 = lua_tonumber(L, -1);
319 return MapNode(ndef, name, param1, param2);
322 static video::SColor readARGB8(lua_State *L, int index)
325 luaL_checktype(L, index, LUA_TTABLE);
326 lua_getfield(L, index, "a");
327 if(lua_isnumber(L, -1))
328 color.setAlpha(lua_tonumber(L, -1));
330 lua_getfield(L, index, "r");
331 color.setRed(lua_tonumber(L, -1));
333 lua_getfield(L, index, "g");
334 color.setGreen(lua_tonumber(L, -1));
336 lua_getfield(L, index, "b");
337 color.setBlue(lua_tonumber(L, -1));
342 static core::aabbox3d<f32> read_aabbox3df32(lua_State *L, int index, f32 scale)
344 core::aabbox3d<f32> box;
345 if(lua_istable(L, -1)){
346 lua_rawgeti(L, -1, 1);
347 box.MinEdge.X = lua_tonumber(L, -1) * scale;
349 lua_rawgeti(L, -1, 2);
350 box.MinEdge.Y = lua_tonumber(L, -1) * scale;
352 lua_rawgeti(L, -1, 3);
353 box.MinEdge.Z = lua_tonumber(L, -1) * scale;
355 lua_rawgeti(L, -1, 4);
356 box.MaxEdge.X = lua_tonumber(L, -1) * scale;
358 lua_rawgeti(L, -1, 5);
359 box.MaxEdge.Y = lua_tonumber(L, -1) * scale;
361 lua_rawgeti(L, -1, 6);
362 box.MaxEdge.Z = lua_tonumber(L, -1) * scale;
368 static bool getstringfield(lua_State *L, int table,
369 const char *fieldname, std::string &result)
371 lua_getfield(L, table, fieldname);
373 if(lua_isstring(L, -1)){
374 result = lua_tostring(L, -1);
381 static bool getintfield(lua_State *L, int table,
382 const char *fieldname, int &result)
384 lua_getfield(L, table, fieldname);
386 if(lua_isnumber(L, -1)){
387 result = lua_tonumber(L, -1);
394 static bool getfloatfield(lua_State *L, int table,
395 const char *fieldname, float &result)
397 lua_getfield(L, table, fieldname);
399 if(lua_isnumber(L, -1)){
400 result = lua_tonumber(L, -1);
407 static bool getboolfield(lua_State *L, int table,
408 const char *fieldname, bool &result)
410 lua_getfield(L, table, fieldname);
412 if(lua_isboolean(L, -1)){
413 result = lua_toboolean(L, -1);
420 static std::string checkstringfield(lua_State *L, int table,
421 const char *fieldname)
423 lua_getfield(L, table, fieldname);
424 std::string s = luaL_checkstring(L, -1);
429 static std::string getstringfield_default(lua_State *L, int table,
430 const char *fieldname, const std::string &default_)
432 std::string result = default_;
433 getstringfield(L, table, fieldname, result);
437 static int getintfield_default(lua_State *L, int table,
438 const char *fieldname, int default_)
440 int result = default_;
441 getintfield(L, table, fieldname, result);
445 /*static float getfloatfield_default(lua_State *L, int table,
446 const char *fieldname, float default_)
448 float result = default_;
449 getfloatfield(L, table, fieldname, result);
453 static bool getboolfield_default(lua_State *L, int table,
454 const char *fieldname, bool default_)
456 bool result = default_;
457 getboolfield(L, table, fieldname, result);
467 static bool string_to_enum(const EnumString *spec, int &result,
468 const std::string &str)
470 const EnumString *esp = spec;
472 if(str == std::string(esp->str)){
481 /*static bool enum_to_string(const EnumString *spec, std::string &result,
484 const EnumString *esp = spec;
495 static int getenumfield(lua_State *L, int table,
496 const char *fieldname, const EnumString *spec, int default_)
498 int result = default_;
499 string_to_enum(spec, result,
500 getstringfield_default(L, table, fieldname, ""));
504 static void setfloatfield(lua_State *L, int table,
505 const char *fieldname, float value)
507 lua_pushnumber(L, value);
510 lua_setfield(L, table, fieldname);
513 static void warn_if_field_exists(lua_State *L, int table,
514 const char *fieldname, const std::string &message)
516 lua_getfield(L, table, fieldname);
517 if(!lua_isnil(L, -1)){
518 infostream<<script_get_backtrace(L)<<std::endl;
519 infostream<<"WARNING: field \""<<fieldname<<"\": "
520 <<message<<std::endl;
529 static void inventory_set_list_from_lua(Inventory *inv, const char *name,
530 lua_State *L, int tableindex, IGameDef *gamedef, int forcesize=-1)
533 tableindex = lua_gettop(L) + 1 + tableindex;
534 // If nil, delete list
535 if(lua_isnil(L, tableindex)){
536 inv->deleteList(name);
539 // Otherwise set list
540 std::list<std::string> items;
541 luaL_checktype(L, tableindex, LUA_TTABLE);
542 int table = tableindex;
544 while(lua_next(L, table) != 0){
545 // key at index -2 and value at index -1
546 luaL_checktype(L, -1, LUA_TSTRING);
547 std::string itemstring = luaL_checkstring(L, -1);
548 items.push_back(itemstring);
549 // removes value, keeps key for next iteration
552 int listsize = (forcesize != -1) ? forcesize : items.size();
553 InventoryList *invlist = inv->addList(name, listsize);
555 for(std::list<std::string>::const_iterator
556 i = items.begin(); i != items.end(); i++){
557 if(forcesize != -1 && index == forcesize)
559 const std::string &itemstring = *i;
560 InventoryItem *newitem = NULL;
562 newitem = InventoryItem::deSerialize(itemstring,
564 InventoryItem *olditem = invlist->changeItem(index, newitem);
568 while(forcesize != -1 && index < forcesize){
569 InventoryItem *olditem = invlist->changeItem(index, NULL);
575 static void inventory_get_list_to_lua(Inventory *inv, const char *name,
578 InventoryList *invlist = inv->getList(name);
583 // Get the table insert function
584 lua_getglobal(L, "table");
585 lua_getfield(L, -1, "insert");
586 int table_insert = lua_gettop(L);
587 // Create and fill table
589 int table = lua_gettop(L);
590 for(u32 i=0; i<invlist->getSize(); i++){
591 InventoryItem *item = invlist->getItem(i);
592 lua_pushvalue(L, table_insert);
593 lua_pushvalue(L, table);
595 lua_pushstring(L, "");
597 lua_pushstring(L, item->getItemString().c_str());
599 if(lua_pcall(L, 2, 0, 0))
600 script_error(L, "error: %s", lua_tostring(L, -1));
604 static void push_stack_item(lua_State *L, InventoryItem *item0)
609 else if(std::string("MaterialItem") == item0->getName()){
610 MaterialItem *item = (MaterialItem*)item0;
612 lua_pushstring(L, "node");
613 lua_setfield(L, -2, "type");
614 lua_pushstring(L, item->getNodeName().c_str());
615 lua_setfield(L, -2, "name");
617 else if(std::string("CraftItem") == item0->getName()){
618 CraftItem *item = (CraftItem*)item0;
620 lua_pushstring(L, "craft");
621 lua_setfield(L, -2, "type");
622 lua_pushstring(L, item->getSubName().c_str());
623 lua_setfield(L, -2, "name");
625 else if(std::string("ToolItem") == item0->getName()){
626 ToolItem *item = (ToolItem*)item0;
628 lua_pushstring(L, "tool");
629 lua_setfield(L, -2, "type");
630 lua_pushstring(L, item->getToolName().c_str());
631 lua_setfield(L, -2, "name");
632 lua_pushstring(L, itos(item->getWear()).c_str());
633 lua_setfield(L, -2, "wear");
636 errorstream<<"push_stack_item: Unknown item name: \""
637 <<item0->getName()<<"\""<<std::endl;
642 static InventoryItem* check_stack_item(lua_State *L, int index)
645 index = lua_gettop(L) + 1 + index;
646 if(lua_isnil(L, index))
648 if(!lua_istable(L, index))
649 throw LuaError(L, "check_stack_item: Item not nil or table");
650 // A very crappy implementation for now
651 // Will be replaced when unified namespace for items is made
652 std::string type = getstringfield_default(L, index, "type", "");
653 std::string name = getstringfield_default(L, index, "name", "");
654 std::string num = getstringfield_default(L, index, "wear", "_");
657 std::string itemstring = type + " \"" + name + "\" " + num;
659 return InventoryItem::deSerialize(itemstring, get_server(L));
660 }catch(SerializationError &e){
661 throw LuaError(L, std::string("check_stack_item: "
662 "internal error (itemstring=\"")+itemstring+"\")");
667 ToolDiggingProperties
670 static ToolDiggingProperties read_tool_digging_properties(
671 lua_State *L, int table)
673 ToolDiggingProperties prop;
674 getfloatfield(L, table, "full_punch_interval", prop.full_punch_interval);
675 getfloatfield(L, table, "basetime", prop.basetime);
676 getfloatfield(L, table, "dt_weight", prop.dt_weight);
677 getfloatfield(L, table, "dt_crackiness", prop.dt_crackiness);
678 getfloatfield(L, table, "dt_crumbliness", prop.dt_crumbliness);
679 getfloatfield(L, table, "dt_cuttability", prop.dt_cuttability);
680 getfloatfield(L, table, "basedurability", prop.basedurability);
681 getfloatfield(L, table, "dd_weight", prop.dd_weight);
682 getfloatfield(L, table, "dd_crackiness", prop.dd_crackiness);
683 getfloatfield(L, table, "dd_crumbliness", prop.dd_crumbliness);
684 getfloatfield(L, table, "dd_cuttability", prop.dd_cuttability);
688 static void set_tool_digging_properties(lua_State *L, int table,
689 const ToolDiggingProperties &prop)
691 setfloatfield(L, table, "full_punch_interval", prop.full_punch_interval);
692 setfloatfield(L, table, "basetime", prop.basetime);
693 setfloatfield(L, table, "dt_weight", prop.dt_weight);
694 setfloatfield(L, table, "dt_crackiness", prop.dt_crackiness);
695 setfloatfield(L, table, "dt_crumbliness", prop.dt_crumbliness);
696 setfloatfield(L, table, "dt_cuttability", prop.dt_cuttability);
697 setfloatfield(L, table, "basedurability", prop.basedurability);
698 setfloatfield(L, table, "dd_weight", prop.dd_weight);
699 setfloatfield(L, table, "dd_crackiness", prop.dd_crackiness);
700 setfloatfield(L, table, "dd_crumbliness", prop.dd_crumbliness);
701 setfloatfield(L, table, "dd_cuttability", prop.dd_cuttability);
704 static void push_tool_digging_properties(lua_State *L,
705 const ToolDiggingProperties &prop)
708 set_tool_digging_properties(L, -1, prop);
715 static ToolDefinition read_tool_definition(lua_State *L, int table)
718 getstringfield(L, table, "image", def.imagename);
719 def.properties = read_tool_digging_properties(L, table);
723 static void push_tool_definition(lua_State *L, const ToolDefinition &def)
726 lua_pushstring(L, def.imagename.c_str());
727 lua_setfield(L, -2, "image");
728 set_tool_digging_properties(L, -1, def.properties);
732 EnumString definitions
735 struct EnumString es_DrawType[] =
737 {NDT_NORMAL, "normal"},
738 {NDT_AIRLIKE, "airlike"},
739 {NDT_LIQUID, "liquid"},
740 {NDT_FLOWINGLIQUID, "flowingliquid"},
741 {NDT_GLASSLIKE, "glasslike"},
742 {NDT_ALLFACES, "allfaces"},
743 {NDT_ALLFACES_OPTIONAL, "allfaces_optional"},
744 {NDT_TORCHLIKE, "torchlike"},
745 {NDT_SIGNLIKE, "signlike"},
746 {NDT_PLANTLIKE, "plantlike"},
747 {NDT_FENCELIKE, "fencelike"},
748 {NDT_RAILLIKE, "raillike"},
752 struct EnumString es_ContentParamType[] =
755 {CPT_LIGHT, "light"},
756 {CPT_MINERAL, "mineral"},
757 {CPT_FACEDIR_SIMPLE, "facedir_simple"},
761 struct EnumString es_LiquidType[] =
763 {LIQUID_NONE, "none"},
764 {LIQUID_FLOWING, "flowing"},
765 {LIQUID_SOURCE, "source"},
769 struct EnumString es_NodeBoxType[] =
771 {NODEBOX_REGULAR, "regular"},
772 {NODEBOX_FIXED, "fixed"},
773 {NODEBOX_WALLMOUNTED, "wallmounted"},
777 struct EnumString es_Diggability[] =
779 {DIGGABLE_NOT, "not"},
780 {DIGGABLE_NORMAL, "normal"},
781 {DIGGABLE_CONSTANT, "constant"},
786 Getters for stuff in main tables
789 static void objectref_get(lua_State *L, u16 id)
791 // Get minetest.object_refs[i]
792 lua_getglobal(L, "minetest");
793 lua_getfield(L, -1, "object_refs");
794 luaL_checktype(L, -1, LUA_TTABLE);
795 lua_pushnumber(L, id);
797 lua_remove(L, -2); // object_refs
798 lua_remove(L, -2); // minetest
801 static void luaentity_get(lua_State *L, u16 id)
803 // Get minetest.luaentities[i]
804 lua_getglobal(L, "minetest");
805 lua_getfield(L, -1, "luaentities");
806 luaL_checktype(L, -1, LUA_TTABLE);
807 lua_pushnumber(L, id);
809 lua_remove(L, -2); // luaentities
810 lua_remove(L, -2); // minetest
817 #define method(class, name) {#name, class::l_##name}
826 InventoryItem *m_stack;
828 static const char className[];
829 static const luaL_reg methods[];
831 // Exported functions
834 static int gc_object(lua_State *L) {
835 ItemStack *o = *(ItemStack **)(lua_touserdata(L, 1));
841 static int l_peek_item(lua_State *L)
843 ItemStack *o = checkobject(L, 1);
844 push_stack_item(L, o->m_stack);
849 static int l_take_item(lua_State *L)
851 ItemStack *o = checkobject(L, 1);
852 push_stack_item(L, o->m_stack);
853 if(o->m_stack->getCount() <= 1){
857 o->m_stack->remove(1);
862 // put_item(self, item) -> true/false
863 static int l_put_item(lua_State *L)
865 ItemStack *o = checkobject(L, 1);
866 InventoryItem *item = check_stack_item(L, 2);
867 if(!item){ // nil can always be inserted
868 lua_pushboolean(L, true);
871 if(!item->addableTo(o->m_stack)){
872 lua_pushboolean(L, false);
877 lua_pushboolean(L, true);
881 // put_stackstring(self, stackstring) -> true/false
882 static int l_put_stackstring(lua_State *L)
884 ItemStack *o = checkobject(L, 1);
885 std::string stackstring = luaL_checkstring(L, 2);
887 InventoryItem *item = InventoryItem::deSerialize(stackstring,
889 if(!item->addableTo(o->m_stack)){
890 lua_pushboolean(L, false);
895 lua_pushboolean(L, true);
898 catch(SerializationError &e){
899 lua_pushboolean(L, false);
905 ItemStack(InventoryItem *item=NULL):
915 static ItemStack* checkobject(lua_State *L, int narg)
917 luaL_checktype(L, narg, LUA_TUSERDATA);
918 void *ud = luaL_checkudata(L, narg, className);
919 if(!ud) luaL_typerror(L, narg, className);
920 return *(ItemStack**)ud; // unbox pointer
923 InventoryItem* getItemCopy()
927 return m_stack->clone();
930 // Creates an ItemStack and leaves it on top of stack
931 static int create_object(lua_State *L)
933 InventoryItem *item = NULL;
934 if(lua_isstring(L, 1)){
935 std::string itemstring = lua_tostring(L, 1);
936 if(itemstring != ""){
938 IGameDef *gdef = get_server(L);
939 item = InventoryItem::deSerialize(itemstring, gdef);
940 }catch(SerializationError &e){
944 ItemStack *o = new ItemStack(item);
945 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
946 luaL_getmetatable(L, className);
947 lua_setmetatable(L, -2);
950 // Not callable from Lua
951 static int create(lua_State *L, InventoryItem *item)
953 ItemStack *o = new ItemStack(item);
954 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
955 luaL_getmetatable(L, className);
956 lua_setmetatable(L, -2);
960 static void Register(lua_State *L)
963 int methodtable = lua_gettop(L);
964 luaL_newmetatable(L, className);
965 int metatable = lua_gettop(L);
967 lua_pushliteral(L, "__metatable");
968 lua_pushvalue(L, methodtable);
969 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
971 lua_pushliteral(L, "__index");
972 lua_pushvalue(L, methodtable);
973 lua_settable(L, metatable);
975 lua_pushliteral(L, "__gc");
976 lua_pushcfunction(L, gc_object);
977 lua_settable(L, metatable);
979 lua_pop(L, 1); // drop metatable
981 luaL_openlib(L, 0, methods, 0); // fill methodtable
982 lua_pop(L, 1); // drop methodtable
984 // Can be created from Lua (ItemStack::create(itemstring))
985 lua_register(L, className, create_object);
988 const char ItemStack::className[] = "ItemStack";
989 const luaL_reg ItemStack::methods[] = {
990 method(ItemStack, peek_item),
991 method(ItemStack, take_item),
992 method(ItemStack, put_item),
993 method(ItemStack, put_stackstring),
1004 InventoryLocation m_loc;
1006 static const char className[];
1007 static const luaL_reg methods[];
1009 static InvRef *checkobject(lua_State *L, int narg)
1011 luaL_checktype(L, narg, LUA_TUSERDATA);
1012 void *ud = luaL_checkudata(L, narg, className);
1013 if(!ud) luaL_typerror(L, narg, className);
1014 return *(InvRef**)ud; // unbox pointer
1017 static Inventory* getinv(lua_State *L, InvRef *ref)
1019 return get_server(L)->getInventory(ref->m_loc);
1022 static InventoryList* getlist(lua_State *L, InvRef *ref,
1023 const char *listname)
1025 Inventory *inv = getinv(L, ref);
1028 return inv->getList(listname);
1031 static InventoryItem* getitem(lua_State *L, InvRef *ref,
1032 const char *listname, int i)
1034 InventoryList *list = getlist(L, ref, listname);
1037 return list->getItem(i);
1040 static void reportInventoryChange(lua_State *L, InvRef *ref)
1042 // Inform other things that the inventory has changed
1043 get_server(L)->setInventoryModified(ref->m_loc);
1046 // Exported functions
1048 // garbage collector
1049 static int gc_object(lua_State *L) {
1050 InvRef *o = *(InvRef **)(lua_touserdata(L, 1));
1055 // get_size(self, listname)
1056 static int l_get_size(lua_State *L)
1058 InvRef *ref = checkobject(L, 1);
1059 const char *listname = luaL_checkstring(L, 2);
1060 InventoryList *list = getlist(L, ref, listname);
1062 lua_pushinteger(L, list->getSize());
1064 lua_pushinteger(L, 0);
1069 // set_size(self, listname, size)
1070 static int l_set_size(lua_State *L)
1072 InvRef *ref = checkobject(L, 1);
1073 const char *listname = luaL_checkstring(L, 2);
1074 int newsize = luaL_checknumber(L, 3);
1075 Inventory *inv = getinv(L, ref);
1077 inv->deleteList(listname);
1078 reportInventoryChange(L, ref);
1081 InventoryList *list = inv->getList(listname);
1083 list->setSize(newsize);
1085 list = inv->addList(listname, newsize);
1087 reportInventoryChange(L, ref);
1091 // get_stack(self, listname, i)
1092 static int l_get_stack(lua_State *L)
1094 InvRef *ref = checkobject(L, 1);
1095 const char *listname = luaL_checkstring(L, 2);
1096 int i = luaL_checknumber(L, 3) - 1;
1097 InventoryItem *item = getitem(L, ref, listname, i);
1099 ItemStack::create(L, NULL);
1102 ItemStack::create(L, item->clone());
1106 // set_stack(self, listname, i, stack)
1107 static int l_set_stack(lua_State *L)
1109 InvRef *ref = checkobject(L, 1);
1110 const char *listname = luaL_checkstring(L, 2);
1111 int i = luaL_checknumber(L, 3) - 1;
1112 ItemStack *stack = ItemStack::checkobject(L, 4);
1113 InventoryList *list = getlist(L, ref, listname);
1115 lua_pushboolean(L, false);
1118 InventoryItem *newitem = stack->getItemCopy();
1119 InventoryItem *olditem = list->changeItem(i, newitem);
1120 bool success = (olditem != newitem);
1122 lua_pushboolean(L, success);
1123 reportInventoryChange(L, ref);
1127 // get_list(self, listname) -> list or nil
1128 static int l_get_list(lua_State *L)
1130 InvRef *ref = checkobject(L, 1);
1131 const char *listname = luaL_checkstring(L, 2);
1132 Inventory *inv = getinv(L, ref);
1133 inventory_get_list_to_lua(inv, listname, L);
1137 // set_list(self, listname, list)
1138 static int l_set_list(lua_State *L)
1140 InvRef *ref = checkobject(L, 1);
1141 const char *listname = luaL_checkstring(L, 2);
1142 Inventory *inv = getinv(L, ref);
1143 InventoryList *list = inv->getList(listname);
1145 inventory_set_list_from_lua(inv, listname, L, 3,
1146 get_server(L), list->getSize());
1148 inventory_set_list_from_lua(inv, listname, L, 3,
1150 reportInventoryChange(L, ref);
1154 // autoinsert_stack(self, listname, stack)
1155 static int l_autoinsert_stack(lua_State *L)
1157 InvRef *ref = checkobject(L, 1);
1158 const char *listname = luaL_checkstring(L, 2);
1159 ItemStack *stack = ItemStack::checkobject(L, 3);
1160 InventoryList *list = getlist(L, ref, listname);
1162 lua_pushboolean(L, false);
1165 InventoryItem *item = stack->getItemCopy();
1166 if(list->roomForItem(item)){
1167 delete list->addItem(item);
1168 lua_pushboolean(L, true);
1169 reportInventoryChange(L, ref);
1172 lua_pushboolean(L, false);
1177 // autoinsert_stackstring(self, listname, stackstring)
1178 static int l_autoinsert_stackstring(lua_State *L)
1180 InvRef *ref = checkobject(L, 1);
1181 const char *listname = luaL_checkstring(L, 2);
1182 const char *stackstring = luaL_checkstring(L, 3);
1183 InventoryList *list = getlist(L, ref, listname);
1185 lua_pushboolean(L, false);
1188 InventoryItem *item = InventoryItem::deSerialize(stackstring,
1190 if(list->roomForItem(item)){
1191 delete list->addItem(item);
1192 lua_pushboolean(L, true);
1193 reportInventoryChange(L, ref);
1196 lua_pushboolean(L, false);
1202 InvRef(const InventoryLocation &loc):
1211 // Creates an InvRef and leaves it on top of stack
1212 // Not callable from Lua; all references are created on the C side.
1213 static void create(lua_State *L, const InventoryLocation &loc)
1215 InvRef *o = new InvRef(loc);
1216 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1217 luaL_getmetatable(L, className);
1218 lua_setmetatable(L, -2);
1220 static void createPlayer(lua_State *L, Player *player)
1222 InventoryLocation loc;
1223 loc.setPlayer(player->getName());
1226 static void createNodeMeta(lua_State *L, v3s16 p)
1228 InventoryLocation loc;
1233 static void Register(lua_State *L)
1236 int methodtable = lua_gettop(L);
1237 luaL_newmetatable(L, className);
1238 int metatable = lua_gettop(L);
1240 lua_pushliteral(L, "__metatable");
1241 lua_pushvalue(L, methodtable);
1242 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
1244 lua_pushliteral(L, "__index");
1245 lua_pushvalue(L, methodtable);
1246 lua_settable(L, metatable);
1248 lua_pushliteral(L, "__gc");
1249 lua_pushcfunction(L, gc_object);
1250 lua_settable(L, metatable);
1252 lua_pop(L, 1); // drop metatable
1254 luaL_openlib(L, 0, methods, 0); // fill methodtable
1255 lua_pop(L, 1); // drop methodtable
1257 // Cannot be created from Lua
1258 //lua_register(L, className, create_object);
1261 const char InvRef::className[] = "InvRef";
1262 const luaL_reg InvRef::methods[] = {
1263 method(InvRef, get_size),
1264 method(InvRef, set_size),
1265 method(InvRef, get_stack),
1266 method(InvRef, set_stack),
1267 method(InvRef, get_list),
1268 method(InvRef, set_list),
1269 method(InvRef, autoinsert_stack),
1270 method(InvRef, autoinsert_stackstring),
1282 ServerEnvironment *m_env;
1284 static const char className[];
1285 static const luaL_reg methods[];
1287 static NodeMetaRef *checkobject(lua_State *L, int narg)
1289 luaL_checktype(L, narg, LUA_TUSERDATA);
1290 void *ud = luaL_checkudata(L, narg, className);
1291 if(!ud) luaL_typerror(L, narg, className);
1292 return *(NodeMetaRef**)ud; // unbox pointer
1295 static NodeMetadata* getmeta(NodeMetaRef *ref)
1297 NodeMetadata *meta = ref->m_env->getMap().getNodeMetadata(ref->m_p);
1301 /*static IGenericNodeMetadata* getgenericmeta(NodeMetaRef *ref)
1303 NodeMetadata *meta = getmeta(ref);
1306 if(meta->typeId() != NODEMETA_GENERIC)
1308 return (IGenericNodeMetadata*)meta;
1311 static void reportMetadataChange(NodeMetaRef *ref)
1313 // Inform other things that the metadata has changed
1314 v3s16 blockpos = getNodeBlockPos(ref->m_p);
1316 event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
1318 ref->m_env->getMap().dispatchEvent(&event);
1319 // Set the block to be saved
1320 MapBlock *block = ref->m_env->getMap().getBlockNoCreateNoEx(blockpos);
1322 block->raiseModified(MOD_STATE_WRITE_NEEDED,
1323 "NodeMetaRef::reportMetadataChange");
1326 // Exported functions
1328 // garbage collector
1329 static int gc_object(lua_State *L) {
1330 NodeMetaRef *o = *(NodeMetaRef **)(lua_touserdata(L, 1));
1336 static int l_get_type(lua_State *L)
1338 NodeMetaRef *ref = checkobject(L, 1);
1339 NodeMetadata *meta = getmeta(ref);
1345 lua_pushstring(L, meta->typeName());
1349 // allows_text_input(self)
1350 static int l_allows_text_input(lua_State *L)
1352 NodeMetaRef *ref = checkobject(L, 1);
1353 NodeMetadata *meta = getmeta(ref);
1354 if(meta == NULL) return 0;
1356 lua_pushboolean(L, meta->allowsTextInput());
1360 // set_text(self, text)
1361 static int l_set_text(lua_State *L)
1363 NodeMetaRef *ref = checkobject(L, 1);
1364 NodeMetadata *meta = getmeta(ref);
1365 if(meta == NULL) return 0;
1367 std::string text = luaL_checkstring(L, 2);
1368 meta->setText(text);
1369 reportMetadataChange(ref);
1374 static int l_get_text(lua_State *L)
1376 NodeMetaRef *ref = checkobject(L, 1);
1377 NodeMetadata *meta = getmeta(ref);
1378 if(meta == NULL) return 0;
1380 std::string text = meta->getText();
1381 lua_pushstring(L, text.c_str());
1386 static int l_get_owner(lua_State *L)
1388 NodeMetaRef *ref = checkobject(L, 1);
1389 NodeMetadata *meta = getmeta(ref);
1390 if(meta == NULL) return 0;
1392 std::string owner = meta->getOwner();
1393 lua_pushstring(L, owner.c_str());
1397 /* IGenericNodeMetadata interface */
1399 // set_infotext(self, text)
1400 static int l_set_infotext(lua_State *L)
1402 NodeMetaRef *ref = checkobject(L, 1);
1403 NodeMetadata *meta = getmeta(ref);
1404 if(meta == NULL) return 0;
1406 std::string text = luaL_checkstring(L, 2);
1407 meta->setInfoText(text);
1408 reportMetadataChange(ref);
1412 // get_inventory(self)
1413 static int l_get_inventory(lua_State *L)
1415 NodeMetaRef *ref = checkobject(L, 1);
1416 NodeMetadata *meta = getmeta(ref);
1417 if(meta == NULL) return 0;
1419 InvRef::createNodeMeta(L, ref->m_p);
1423 // deprecated: inventory_set_list(self, name, {item1, item2, ...})
1424 static int l_inventory_set_list(lua_State *L)
1426 infostream<<"Deprecated: inventory_set_list"<<std::endl;
1427 NodeMetaRef *ref = checkobject(L, 1);
1428 NodeMetadata *meta = getmeta(ref);
1429 if(meta == NULL) return 0;
1431 Inventory *inv = meta->getInventory();
1432 const char *name = luaL_checkstring(L, 2);
1433 inventory_set_list_from_lua(inv, name, L, 3,
1434 ref->m_env->getGameDef());
1435 reportMetadataChange(ref);
1439 // deprecated: inventory_get_list(self, name)
1440 static int l_inventory_get_list(lua_State *L)
1442 infostream<<"Deprecated: inventory_get_list"<<std::endl;
1443 NodeMetaRef *ref = checkobject(L, 1);
1444 NodeMetadata *meta = getmeta(ref);
1445 if(meta == NULL) return 0;
1447 Inventory *inv = meta->getInventory();
1448 const char *name = luaL_checkstring(L, 2);
1449 inventory_get_list_to_lua(inv, name, L);
1453 // set_inventory_draw_spec(self, text)
1454 static int l_set_inventory_draw_spec(lua_State *L)
1456 NodeMetaRef *ref = checkobject(L, 1);
1457 NodeMetadata *meta = getmeta(ref);
1458 if(meta == NULL) return 0;
1460 std::string text = luaL_checkstring(L, 2);
1461 meta->setInventoryDrawSpec(text);
1462 reportMetadataChange(ref);
1466 // set_allow_text_input(self, text)
1467 static int l_set_allow_text_input(lua_State *L)
1469 NodeMetaRef *ref = checkobject(L, 1);
1470 NodeMetadata *meta = getmeta(ref);
1471 if(meta == NULL) return 0;
1473 bool b = lua_toboolean(L, 2);
1474 meta->setAllowTextInput(b);
1475 reportMetadataChange(ref);
1479 // set_allow_removal(self, text)
1480 static int l_set_allow_removal(lua_State *L)
1482 NodeMetaRef *ref = checkobject(L, 1);
1483 NodeMetadata *meta = getmeta(ref);
1484 if(meta == NULL) return 0;
1486 bool b = lua_toboolean(L, 2);
1487 meta->setRemovalDisabled(!b);
1488 reportMetadataChange(ref);
1492 // set_enforce_owner(self, text)
1493 static int l_set_enforce_owner(lua_State *L)
1495 NodeMetaRef *ref = checkobject(L, 1);
1496 NodeMetadata *meta = getmeta(ref);
1497 if(meta == NULL) return 0;
1499 bool b = lua_toboolean(L, 2);
1500 meta->setEnforceOwner(b);
1501 reportMetadataChange(ref);
1505 // is_inventory_modified(self)
1506 static int l_is_inventory_modified(lua_State *L)
1508 NodeMetaRef *ref = checkobject(L, 1);
1509 NodeMetadata *meta = getmeta(ref);
1510 if(meta == NULL) return 0;
1512 lua_pushboolean(L, meta->isInventoryModified());
1516 // reset_inventory_modified(self)
1517 static int l_reset_inventory_modified(lua_State *L)
1519 NodeMetaRef *ref = checkobject(L, 1);
1520 NodeMetadata *meta = getmeta(ref);
1521 if(meta == NULL) return 0;
1523 meta->resetInventoryModified();
1524 reportMetadataChange(ref);
1528 // is_text_modified(self)
1529 static int l_is_text_modified(lua_State *L)
1531 NodeMetaRef *ref = checkobject(L, 1);
1532 NodeMetadata *meta = getmeta(ref);
1533 if(meta == NULL) return 0;
1535 lua_pushboolean(L, meta->isTextModified());
1539 // reset_text_modified(self)
1540 static int l_reset_text_modified(lua_State *L)
1542 NodeMetaRef *ref = checkobject(L, 1);
1543 NodeMetadata *meta = getmeta(ref);
1544 if(meta == NULL) return 0;
1546 meta->resetTextModified();
1547 reportMetadataChange(ref);
1551 // set_string(self, name, var)
1552 static int l_set_string(lua_State *L)
1554 NodeMetaRef *ref = checkobject(L, 1);
1555 NodeMetadata *meta = getmeta(ref);
1556 if(meta == NULL) return 0;
1558 std::string name = luaL_checkstring(L, 2);
1560 const char *s = lua_tolstring(L, 3, &len);
1561 std::string str(s, len);
1562 meta->setString(name, str);
1563 reportMetadataChange(ref);
1567 // get_string(self, name)
1568 static int l_get_string(lua_State *L)
1570 NodeMetaRef *ref = checkobject(L, 1);
1571 NodeMetadata *meta = getmeta(ref);
1572 if(meta == NULL) return 0;
1574 std::string name = luaL_checkstring(L, 2);
1575 std::string str = meta->getString(name);
1576 lua_pushlstring(L, str.c_str(), str.size());
1581 NodeMetaRef(v3s16 p, ServerEnvironment *env):
1591 // Creates an NodeMetaRef and leaves it on top of stack
1592 // Not callable from Lua; all references are created on the C side.
1593 static void create(lua_State *L, v3s16 p, ServerEnvironment *env)
1595 NodeMetaRef *o = new NodeMetaRef(p, env);
1596 //infostream<<"NodeMetaRef::create: o="<<o<<std::endl;
1597 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1598 luaL_getmetatable(L, className);
1599 lua_setmetatable(L, -2);
1602 static void Register(lua_State *L)
1605 int methodtable = lua_gettop(L);
1606 luaL_newmetatable(L, className);
1607 int metatable = lua_gettop(L);
1609 lua_pushliteral(L, "__metatable");
1610 lua_pushvalue(L, methodtable);
1611 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
1613 lua_pushliteral(L, "__index");
1614 lua_pushvalue(L, methodtable);
1615 lua_settable(L, metatable);
1617 lua_pushliteral(L, "__gc");
1618 lua_pushcfunction(L, gc_object);
1619 lua_settable(L, metatable);
1621 lua_pop(L, 1); // drop metatable
1623 luaL_openlib(L, 0, methods, 0); // fill methodtable
1624 lua_pop(L, 1); // drop methodtable
1626 // Cannot be created from Lua
1627 //lua_register(L, className, create_object);
1630 const char NodeMetaRef::className[] = "NodeMetaRef";
1631 const luaL_reg NodeMetaRef::methods[] = {
1632 method(NodeMetaRef, get_type),
1633 method(NodeMetaRef, allows_text_input),
1634 method(NodeMetaRef, set_text),
1635 method(NodeMetaRef, get_text),
1636 method(NodeMetaRef, get_owner),
1637 method(NodeMetaRef, set_infotext),
1638 method(NodeMetaRef, get_inventory),
1639 method(NodeMetaRef, inventory_set_list), // deprecated
1640 method(NodeMetaRef, inventory_get_list), // deprecated
1641 method(NodeMetaRef, set_inventory_draw_spec),
1642 method(NodeMetaRef, set_allow_text_input),
1643 method(NodeMetaRef, set_allow_removal),
1644 method(NodeMetaRef, set_enforce_owner),
1645 method(NodeMetaRef, is_inventory_modified),
1646 method(NodeMetaRef, reset_inventory_modified),
1647 method(NodeMetaRef, is_text_modified),
1648 method(NodeMetaRef, reset_text_modified),
1649 method(NodeMetaRef, set_string),
1650 method(NodeMetaRef, get_string),
1661 ServerActiveObject *m_object;
1663 static const char className[];
1664 static const luaL_reg methods[];
1666 static ObjectRef *checkobject(lua_State *L, int narg)
1668 luaL_checktype(L, narg, LUA_TUSERDATA);
1669 void *ud = luaL_checkudata(L, narg, className);
1670 if(!ud) luaL_typerror(L, narg, className);
1671 return *(ObjectRef**)ud; // unbox pointer
1674 static ServerActiveObject* getobject(ObjectRef *ref)
1676 ServerActiveObject *co = ref->m_object;
1680 static LuaEntitySAO* getluaobject(ObjectRef *ref)
1682 ServerActiveObject *obj = getobject(ref);
1685 if(obj->getType() != ACTIVEOBJECT_TYPE_LUAENTITY)
1687 return (LuaEntitySAO*)obj;
1690 static ServerRemotePlayer* getplayer(ObjectRef *ref)
1692 ServerActiveObject *obj = getobject(ref);
1695 if(obj->getType() != ACTIVEOBJECT_TYPE_PLAYER)
1697 return static_cast<ServerRemotePlayer*>(obj);
1700 // Exported functions
1702 // garbage collector
1703 static int gc_object(lua_State *L) {
1704 ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
1705 //infostream<<"ObjectRef::gc_object: o="<<o<<std::endl;
1711 static int l_remove(lua_State *L)
1713 ObjectRef *ref = checkobject(L, 1);
1714 ServerActiveObject *co = getobject(ref);
1715 if(co == NULL) return 0;
1716 infostream<<"ObjectRef::l_remove(): id="<<co->getId()<<std::endl;
1717 co->m_removed = true;
1722 // returns: {x=num, y=num, z=num}
1723 static int l_getpos(lua_State *L)
1725 ObjectRef *ref = checkobject(L, 1);
1726 ServerActiveObject *co = getobject(ref);
1727 if(co == NULL) return 0;
1728 v3f pos = co->getBasePosition() / BS;
1730 lua_pushnumber(L, pos.X);
1731 lua_setfield(L, -2, "x");
1732 lua_pushnumber(L, pos.Y);
1733 lua_setfield(L, -2, "y");
1734 lua_pushnumber(L, pos.Z);
1735 lua_setfield(L, -2, "z");
1739 // setpos(self, pos)
1740 static int l_setpos(lua_State *L)
1742 ObjectRef *ref = checkobject(L, 1);
1743 //LuaEntitySAO *co = getluaobject(ref);
1744 ServerActiveObject *co = getobject(ref);
1745 if(co == NULL) return 0;
1747 v3f pos = checkFloatPos(L, 2);
1753 // moveto(self, pos, continuous=false)
1754 static int l_moveto(lua_State *L)
1756 ObjectRef *ref = checkobject(L, 1);
1757 //LuaEntitySAO *co = getluaobject(ref);
1758 ServerActiveObject *co = getobject(ref);
1759 if(co == NULL) return 0;
1761 v3f pos = checkFloatPos(L, 2);
1763 bool continuous = lua_toboolean(L, 3);
1765 co->moveTo(pos, continuous);
1769 // punch(self, puncher); puncher = an another ObjectRef
1770 static int l_punch(lua_State *L)
1772 ObjectRef *ref = checkobject(L, 1);
1773 ObjectRef *ref2 = checkobject(L, 2);
1774 ServerActiveObject *co = getobject(ref);
1775 ServerActiveObject *co2 = getobject(ref2);
1776 if(co == NULL) return 0;
1777 if(co2 == NULL) return 0;
1783 // right_click(self, clicker); clicker = an another ObjectRef
1784 static int l_right_click(lua_State *L)
1786 ObjectRef *ref = checkobject(L, 1);
1787 ObjectRef *ref2 = checkobject(L, 2);
1788 ServerActiveObject *co = getobject(ref);
1789 ServerActiveObject *co2 = getobject(ref2);
1790 if(co == NULL) return 0;
1791 if(co2 == NULL) return 0;
1793 co->rightClick(co2);
1797 // get_wield_digging_properties(self)
1798 static int l_get_wield_digging_properties(lua_State *L)
1800 ObjectRef *ref = checkobject(L, 1);
1801 ServerActiveObject *co = getobject(ref);
1802 if(co == NULL) return 0;
1804 ToolDiggingProperties prop;
1805 co->getWieldDiggingProperties(&prop);
1806 push_tool_digging_properties(L, prop);
1810 // damage_wielded_item(self, amount)
1811 static int l_damage_wielded_item(lua_State *L)
1813 ObjectRef *ref = checkobject(L, 1);
1814 ServerActiveObject *co = getobject(ref);
1815 if(co == NULL) return 0;
1817 int amount = lua_tonumber(L, 2);
1818 co->damageWieldedItem(amount);
1822 // add_to_inventory(self, itemstring)
1823 // returns: true if item was added, (false, "reason") otherwise
1824 static int l_add_to_inventory(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 = luaL_checkstring(L, 2);
1832 infostream<<"ObjectRef::l_add_to_inventory(): 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();
1840 InventoryItem *item = InventoryItem::deSerialize(is, gamedef);
1841 if(item->getCount() == 0)
1843 bool added = co->addToInventory(item);
1845 lua_pushboolean(L, added);
1847 lua_pushstring(L, "failed to add item");
1849 } catch(SerializationError &e){
1851 lua_pushboolean(L, false);
1852 lua_pushstring(L, (std::string("Invalid item: ")
1853 + e.what()).c_str());
1858 // add_to_inventory_later(self, itemstring)
1860 static int l_add_to_inventory_later(lua_State *L)
1862 ObjectRef *ref = checkobject(L, 1);
1863 luaL_checkstring(L, 2);
1864 ServerActiveObject *co = getobject(ref);
1865 if(co == NULL) return 0;
1867 const char *itemstring = luaL_checkstring(L, 2);
1868 infostream<<"ObjectRef::l_add_to_inventory_later(): id="<<co->getId()
1869 <<" itemstring=\""<<itemstring<<"\""<<std::endl;
1871 std::istringstream is(itemstring, std::ios::binary);
1872 ServerEnvironment *env = co->getEnv();
1874 IGameDef *gamedef = env->getGameDef();
1875 InventoryItem *item = InventoryItem::deSerialize(is, gamedef);
1876 infostream<<"item="<<env<<std::endl;
1877 co->addToInventoryLater(item);
1883 // hp = number of hitpoints (2 * number of hearts)
1885 static int l_set_hp(lua_State *L)
1887 ObjectRef *ref = checkobject(L, 1);
1888 luaL_checknumber(L, 2);
1889 ServerActiveObject *co = getobject(ref);
1890 if(co == NULL) return 0;
1891 int hp = lua_tonumber(L, 2);
1892 infostream<<"ObjectRef::l_set_hp(): id="<<co->getId()
1893 <<" hp="<<hp<<std::endl;
1901 // returns: number of hitpoints (2 * number of hearts)
1902 // 0 if not applicable to this type of object
1903 static int l_get_hp(lua_State *L)
1905 ObjectRef *ref = checkobject(L, 1);
1906 ServerActiveObject *co = getobject(ref);
1907 if(co == NULL) return 0;
1908 int hp = co->getHP();
1909 infostream<<"ObjectRef::l_get_hp(): id="<<co->getId()
1910 <<" hp="<<hp<<std::endl;
1912 lua_pushnumber(L, hp);
1916 /* LuaEntitySAO-only */
1918 // setvelocity(self, {x=num, y=num, z=num})
1919 static int l_setvelocity(lua_State *L)
1921 ObjectRef *ref = checkobject(L, 1);
1922 LuaEntitySAO *co = getluaobject(ref);
1923 if(co == NULL) return 0;
1925 v3f pos = checkFloatPos(L, 2);
1927 co->setVelocity(pos);
1931 // setacceleration(self, {x=num, y=num, z=num})
1932 static int l_setacceleration(lua_State *L)
1934 ObjectRef *ref = checkobject(L, 1);
1935 LuaEntitySAO *co = getluaobject(ref);
1936 if(co == NULL) return 0;
1938 v3f pos = checkFloatPos(L, 2);
1940 co->setAcceleration(pos);
1944 // getacceleration(self)
1945 static int l_getacceleration(lua_State *L)
1947 ObjectRef *ref = checkobject(L, 1);
1948 LuaEntitySAO *co = getluaobject(ref);
1949 if(co == NULL) return 0;
1951 v3f v = co->getAcceleration();
1956 // settexturemod(self, mod)
1957 static int l_settexturemod(lua_State *L)
1959 ObjectRef *ref = checkobject(L, 1);
1960 LuaEntitySAO *co = getluaobject(ref);
1961 if(co == NULL) return 0;
1963 std::string mod = luaL_checkstring(L, 2);
1964 co->setTextureMod(mod);
1968 // setsprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2,
1969 // select_horiz_by_yawpitch=false)
1970 static int l_setsprite(lua_State *L)
1972 ObjectRef *ref = checkobject(L, 1);
1973 LuaEntitySAO *co = getluaobject(ref);
1974 if(co == NULL) return 0;
1977 if(!lua_isnil(L, 2))
1978 p = read_v2s16(L, 2);
1980 if(!lua_isnil(L, 3))
1981 num_frames = lua_tonumber(L, 3);
1982 float framelength = 0.2;
1983 if(!lua_isnil(L, 4))
1984 framelength = lua_tonumber(L, 4);
1985 bool select_horiz_by_yawpitch = false;
1986 if(!lua_isnil(L, 5))
1987 select_horiz_by_yawpitch = lua_toboolean(L, 5);
1988 co->setSprite(p, num_frames, framelength, select_horiz_by_yawpitch);
1992 // get_entity_name(self)
1993 static int l_get_entity_name(lua_State *L)
1995 ObjectRef *ref = checkobject(L, 1);
1996 LuaEntitySAO *co = getluaobject(ref);
1997 if(co == NULL) return 0;
1999 std::string name = co->getName();
2000 lua_pushstring(L, name.c_str());
2004 // get_luaentity(self)
2005 static int l_get_luaentity(lua_State *L)
2007 ObjectRef *ref = checkobject(L, 1);
2008 LuaEntitySAO *co = getluaobject(ref);
2009 if(co == NULL) return 0;
2011 luaentity_get(L, co->getId());
2017 // get_player_name(self)
2018 static int l_get_player_name(lua_State *L)
2020 ObjectRef *ref = checkobject(L, 1);
2021 ServerRemotePlayer *player = getplayer(ref);
2027 lua_pushstring(L, player->getName());
2031 // get_inventory(self)
2032 static int l_get_inventory(lua_State *L)
2034 ObjectRef *ref = checkobject(L, 1);
2035 ServerRemotePlayer *player = getplayer(ref);
2036 if(player == NULL) return 0;
2038 InvRef::createPlayer(L, player);
2042 // deprecated: inventory_set_list(self, name, {item1, item2, ...})
2043 static int l_inventory_set_list(lua_State *L)
2045 infostream<<"Deprecated: inventory_set_list"<<std::endl;
2046 ObjectRef *ref = checkobject(L, 1);
2047 ServerRemotePlayer *player = getplayer(ref);
2048 if(player == NULL) return 0;
2049 const char *name = luaL_checkstring(L, 2);
2051 inventory_set_list_from_lua(&player->inventory, name, L, 3,
2052 player->getEnv()->getGameDef(), PLAYER_INVENTORY_SIZE);
2053 player->m_inventory_not_sent = true;
2057 // deprecated: inventory_get_list(self, name)
2058 static int l_inventory_get_list(lua_State *L)
2060 infostream<<"Deprecated: inventory_get_list"<<std::endl;
2061 ObjectRef *ref = checkobject(L, 1);
2062 ServerRemotePlayer *player = getplayer(ref);
2063 if(player == NULL) return 0;
2064 const char *name = luaL_checkstring(L, 2);
2066 inventory_get_list_to_lua(&player->inventory, name, L);
2070 // get_wielded_itemstring(self)
2071 static int l_get_wielded_itemstring(lua_State *L)
2073 ObjectRef *ref = checkobject(L, 1);
2074 ServerRemotePlayer *player = getplayer(ref);
2075 if(player == NULL) return 0;
2077 InventoryItem *item = player->getWieldedItem();
2082 lua_pushstring(L, item->getItemString().c_str());
2086 // get_wielded_item(self)
2087 static int l_get_wielded_item(lua_State *L)
2089 ObjectRef *ref = checkobject(L, 1);
2090 ServerRemotePlayer *player = getplayer(ref);
2091 if(player == NULL) return 0;
2093 InventoryItem *item0 = player->getWieldedItem();
2094 push_stack_item(L, item0);
2098 // get_look_dir(self)
2099 static int l_get_look_dir(lua_State *L)
2101 ObjectRef *ref = checkobject(L, 1);
2102 ServerRemotePlayer *player = getplayer(ref);
2103 if(player == NULL) return 0;
2105 float pitch = player->getRadPitch();
2106 float yaw = player->getRadYaw();
2107 v3f v(cos(pitch)*cos(yaw), sin(pitch), cos(pitch)*sin(yaw));
2112 // get_look_pitch(self)
2113 static int l_get_look_pitch(lua_State *L)
2115 ObjectRef *ref = checkobject(L, 1);
2116 ServerRemotePlayer *player = getplayer(ref);
2117 if(player == NULL) return 0;
2119 lua_pushnumber(L, player->getRadPitch());
2123 // get_look_yaw(self)
2124 static int l_get_look_yaw(lua_State *L)
2126 ObjectRef *ref = checkobject(L, 1);
2127 ServerRemotePlayer *player = getplayer(ref);
2128 if(player == NULL) return 0;
2130 lua_pushnumber(L, player->getRadYaw());
2135 ObjectRef(ServerActiveObject *object):
2138 //infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
2144 infostream<<"ObjectRef destructing for id="
2145 <<m_object->getId()<<std::endl;
2147 infostream<<"ObjectRef destructing for id=unknown"<<std::endl;*/
2150 // Creates an ObjectRef and leaves it on top of stack
2151 // Not callable from Lua; all references are created on the C side.
2152 static void create(lua_State *L, ServerActiveObject *object)
2154 ObjectRef *o = new ObjectRef(object);
2155 //infostream<<"ObjectRef::create: o="<<o<<std::endl;
2156 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
2157 luaL_getmetatable(L, className);
2158 lua_setmetatable(L, -2);
2161 static void set_null(lua_State *L)
2163 ObjectRef *o = checkobject(L, -1);
2167 static void Register(lua_State *L)
2170 int methodtable = lua_gettop(L);
2171 luaL_newmetatable(L, className);
2172 int metatable = lua_gettop(L);
2174 lua_pushliteral(L, "__metatable");
2175 lua_pushvalue(L, methodtable);
2176 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
2178 lua_pushliteral(L, "__index");
2179 lua_pushvalue(L, methodtable);
2180 lua_settable(L, metatable);
2182 lua_pushliteral(L, "__gc");
2183 lua_pushcfunction(L, gc_object);
2184 lua_settable(L, metatable);
2186 lua_pop(L, 1); // drop metatable
2188 luaL_openlib(L, 0, methods, 0); // fill methodtable
2189 lua_pop(L, 1); // drop methodtable
2191 // Cannot be created from Lua
2192 //lua_register(L, className, create_object);
2195 const char ObjectRef::className[] = "ObjectRef";
2196 const luaL_reg ObjectRef::methods[] = {
2197 // ServerActiveObject
2198 method(ObjectRef, remove),
2199 method(ObjectRef, getpos),
2200 method(ObjectRef, setpos),
2201 method(ObjectRef, moveto),
2202 method(ObjectRef, punch),
2203 method(ObjectRef, right_click),
2204 method(ObjectRef, get_wield_digging_properties),
2205 method(ObjectRef, damage_wielded_item),
2206 method(ObjectRef, add_to_inventory),
2207 method(ObjectRef, add_to_inventory_later),
2208 method(ObjectRef, set_hp),
2209 method(ObjectRef, get_hp),
2210 // LuaEntitySAO-only
2211 method(ObjectRef, setvelocity),
2212 method(ObjectRef, setacceleration),
2213 method(ObjectRef, getacceleration),
2214 method(ObjectRef, settexturemod),
2215 method(ObjectRef, setsprite),
2216 method(ObjectRef, get_entity_name),
2217 method(ObjectRef, get_luaentity),
2219 method(ObjectRef, get_player_name),
2220 method(ObjectRef, get_inventory),
2221 method(ObjectRef, inventory_set_list), // deprecated
2222 method(ObjectRef, inventory_get_list), // deprecated
2223 method(ObjectRef, get_wielded_itemstring),
2224 method(ObjectRef, get_wielded_item),
2225 method(ObjectRef, get_look_dir),
2226 method(ObjectRef, get_look_pitch),
2227 method(ObjectRef, get_look_yaw),
2231 // Creates a new anonymous reference if id=0
2232 static void objectref_get_or_create(lua_State *L,
2233 ServerActiveObject *cobj)
2235 if(cobj->getId() == 0){
2236 ObjectRef::create(L, cobj);
2238 objectref_get(L, cobj->getId());
2249 ServerEnvironment *m_env;
2251 static const char className[];
2252 static const luaL_reg methods[];
2254 static EnvRef *checkobject(lua_State *L, int narg)
2256 luaL_checktype(L, narg, LUA_TUSERDATA);
2257 void *ud = luaL_checkudata(L, narg, className);
2258 if(!ud) luaL_typerror(L, narg, className);
2259 return *(EnvRef**)ud; // unbox pointer
2262 // Exported functions
2264 // EnvRef:add_node(pos, node)
2265 // pos = {x=num, y=num, z=num}
2266 static int l_add_node(lua_State *L)
2268 //infostream<<"EnvRef::l_add_node()"<<std::endl;
2269 EnvRef *o = checkobject(L, 1);
2270 ServerEnvironment *env = o->m_env;
2271 if(env == NULL) return 0;
2273 v3s16 pos = read_v3s16(L, 2);
2275 MapNode n = readnode(L, 3, env->getGameDef()->ndef());
2277 bool succeeded = env->getMap().addNodeWithEvent(pos, n);
2278 lua_pushboolean(L, succeeded);
2282 // EnvRef:remove_node(pos)
2283 // pos = {x=num, y=num, z=num}
2284 static int l_remove_node(lua_State *L)
2286 //infostream<<"EnvRef::l_remove_node()"<<std::endl;
2287 EnvRef *o = checkobject(L, 1);
2288 ServerEnvironment *env = o->m_env;
2289 if(env == NULL) return 0;
2291 v3s16 pos = read_v3s16(L, 2);
2293 bool succeeded = env->getMap().removeNodeWithEvent(pos);
2294 lua_pushboolean(L, succeeded);
2298 // EnvRef:get_node(pos)
2299 // pos = {x=num, y=num, z=num}
2300 static int l_get_node(lua_State *L)
2302 //infostream<<"EnvRef::l_get_node()"<<std::endl;
2303 EnvRef *o = checkobject(L, 1);
2304 ServerEnvironment *env = o->m_env;
2305 if(env == NULL) return 0;
2307 v3s16 pos = read_v3s16(L, 2);
2309 MapNode n = env->getMap().getNodeNoEx(pos);
2311 pushnode(L, n, env->getGameDef()->ndef());
2315 // EnvRef:get_node_or_nil(pos)
2316 // pos = {x=num, y=num, z=num}
2317 static int l_get_node_or_nil(lua_State *L)
2319 //infostream<<"EnvRef::l_get_node()"<<std::endl;
2320 EnvRef *o = checkobject(L, 1);
2321 ServerEnvironment *env = o->m_env;
2322 if(env == NULL) return 0;
2324 v3s16 pos = read_v3s16(L, 2);
2327 MapNode n = env->getMap().getNode(pos);
2329 pushnode(L, n, env->getGameDef()->ndef());
2331 } catch(InvalidPositionException &e)
2338 // EnvRef:get_node_light(pos, timeofday)
2339 // pos = {x=num, y=num, z=num}
2340 // timeofday: nil = current time, 0 = night, 0.5 = day
2341 static int l_get_node_light(lua_State *L)
2343 EnvRef *o = checkobject(L, 1);
2344 ServerEnvironment *env = o->m_env;
2345 if(env == NULL) return 0;
2347 v3s16 pos = read_v3s16(L, 2);
2348 u32 time_of_day = env->getTimeOfDay();
2349 if(lua_isnumber(L, 3))
2350 time_of_day = 24000.0 * lua_tonumber(L, 3);
2351 time_of_day %= 24000;
2352 u32 dnr = time_to_daynight_ratio(time_of_day);
2353 MapNode n = env->getMap().getNodeNoEx(pos);
2355 MapNode n = env->getMap().getNode(pos);
2356 INodeDefManager *ndef = env->getGameDef()->ndef();
2357 lua_pushinteger(L, n.getLightBlend(dnr, ndef));
2359 } catch(InvalidPositionException &e)
2366 // EnvRef:add_entity(pos, entityname)
2367 // pos = {x=num, y=num, z=num}
2368 static int l_add_entity(lua_State *L)
2370 //infostream<<"EnvRef::l_add_entity()"<<std::endl;
2371 EnvRef *o = checkobject(L, 1);
2372 ServerEnvironment *env = o->m_env;
2373 if(env == NULL) return 0;
2375 v3f pos = checkFloatPos(L, 2);
2377 const char *name = luaL_checkstring(L, 3);
2379 ServerActiveObject *obj = new LuaEntitySAO(env, pos, name, "");
2380 int objectid = env->addActiveObject(obj);
2381 // If failed to add, return nothing (reads as nil)
2385 objectref_get_or_create(L, obj);
2389 // EnvRef:add_item(pos, inventorystring)
2390 // pos = {x=num, y=num, z=num}
2391 static int l_add_item(lua_State *L)
2393 infostream<<"EnvRef::l_add_item()"<<std::endl;
2394 EnvRef *o = checkobject(L, 1);
2395 ServerEnvironment *env = o->m_env;
2396 if(env == NULL) return 0;
2398 v3f pos = checkFloatPos(L, 2);
2400 const char *inventorystring = luaL_checkstring(L, 3);
2402 ServerActiveObject *obj = new ItemSAO(env, pos, inventorystring);
2403 env->addActiveObject(obj);
2407 // EnvRef:add_rat(pos)
2408 // pos = {x=num, y=num, z=num}
2409 static int l_add_rat(lua_State *L)
2411 infostream<<"EnvRef::l_add_rat()"<<std::endl;
2412 EnvRef *o = checkobject(L, 1);
2413 ServerEnvironment *env = o->m_env;
2414 if(env == NULL) return 0;
2416 v3f pos = checkFloatPos(L, 2);
2418 ServerActiveObject *obj = new RatSAO(env, pos);
2419 env->addActiveObject(obj);
2423 // EnvRef:add_firefly(pos)
2424 // pos = {x=num, y=num, z=num}
2425 static int l_add_firefly(lua_State *L)
2427 infostream<<"EnvRef::l_add_firefly()"<<std::endl;
2428 EnvRef *o = checkobject(L, 1);
2429 ServerEnvironment *env = o->m_env;
2430 if(env == NULL) return 0;
2432 v3f pos = checkFloatPos(L, 2);
2434 ServerActiveObject *obj = new FireflySAO(env, pos);
2435 env->addActiveObject(obj);
2439 // EnvRef:get_meta(pos)
2440 static int l_get_meta(lua_State *L)
2442 //infostream<<"EnvRef::l_get_meta()"<<std::endl;
2443 EnvRef *o = checkobject(L, 1);
2444 ServerEnvironment *env = o->m_env;
2445 if(env == NULL) return 0;
2447 v3s16 p = read_v3s16(L, 2);
2448 NodeMetaRef::create(L, p, env);
2452 // EnvRef:get_player_by_name(name)
2453 static int l_get_player_by_name(lua_State *L)
2455 EnvRef *o = checkobject(L, 1);
2456 ServerEnvironment *env = o->m_env;
2457 if(env == NULL) return 0;
2459 const char *name = luaL_checkstring(L, 2);
2460 ServerRemotePlayer *player =
2461 static_cast<ServerRemotePlayer*>(env->getPlayer(name));
2466 // Put player on stack
2467 objectref_get_or_create(L, player);
2471 // EnvRef:get_objects_inside_radius(pos, radius)
2472 static int l_get_objects_inside_radius(lua_State *L)
2474 // Get the table insert function
2475 lua_getglobal(L, "table");
2476 lua_getfield(L, -1, "insert");
2477 int table_insert = lua_gettop(L);
2479 EnvRef *o = checkobject(L, 1);
2480 ServerEnvironment *env = o->m_env;
2481 if(env == NULL) return 0;
2483 v3f pos = checkFloatPos(L, 2);
2484 float radius = luaL_checknumber(L, 3) * BS;
2485 std::set<u16> ids = env->getObjectsInsideRadius(pos, radius);
2487 int table = lua_gettop(L);
2488 for(std::set<u16>::const_iterator
2489 i = ids.begin(); i != ids.end(); i++){
2490 ServerActiveObject *obj = env->getActiveObject(*i);
2491 // Insert object reference into table
2492 lua_pushvalue(L, table_insert);
2493 lua_pushvalue(L, table);
2494 objectref_get_or_create(L, obj);
2495 if(lua_pcall(L, 2, 0, 0))
2496 script_error(L, "error: %s", lua_tostring(L, -1));
2501 static int gc_object(lua_State *L) {
2502 EnvRef *o = *(EnvRef **)(lua_touserdata(L, 1));
2508 EnvRef(ServerEnvironment *env):
2511 infostream<<"EnvRef created"<<std::endl;
2516 infostream<<"EnvRef destructing"<<std::endl;
2519 // Creates an EnvRef and leaves it on top of stack
2520 // Not callable from Lua; all references are created on the C side.
2521 static void create(lua_State *L, ServerEnvironment *env)
2523 EnvRef *o = new EnvRef(env);
2524 //infostream<<"EnvRef::create: o="<<o<<std::endl;
2525 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
2526 luaL_getmetatable(L, className);
2527 lua_setmetatable(L, -2);
2530 static void set_null(lua_State *L)
2532 EnvRef *o = checkobject(L, -1);
2536 static void Register(lua_State *L)
2539 int methodtable = lua_gettop(L);
2540 luaL_newmetatable(L, className);
2541 int metatable = lua_gettop(L);
2543 lua_pushliteral(L, "__metatable");
2544 lua_pushvalue(L, methodtable);
2545 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
2547 lua_pushliteral(L, "__index");
2548 lua_pushvalue(L, methodtable);
2549 lua_settable(L, metatable);
2551 lua_pushliteral(L, "__gc");
2552 lua_pushcfunction(L, gc_object);
2553 lua_settable(L, metatable);
2555 lua_pop(L, 1); // drop metatable
2557 luaL_openlib(L, 0, methods, 0); // fill methodtable
2558 lua_pop(L, 1); // drop methodtable
2560 // Cannot be created from Lua
2561 //lua_register(L, className, create_object);
2564 const char EnvRef::className[] = "EnvRef";
2565 const luaL_reg EnvRef::methods[] = {
2566 method(EnvRef, add_node),
2567 method(EnvRef, remove_node),
2568 method(EnvRef, get_node),
2569 method(EnvRef, get_node_or_nil),
2570 method(EnvRef, get_node_light),
2571 method(EnvRef, add_entity),
2572 method(EnvRef, add_item),
2573 method(EnvRef, add_rat),
2574 method(EnvRef, add_firefly),
2575 method(EnvRef, get_meta),
2576 method(EnvRef, get_player_by_name),
2577 method(EnvRef, get_objects_inside_radius),
2585 static int l_register_nodedef_defaults(lua_State *L)
2587 luaL_checktype(L, 1, LUA_TTABLE);
2589 lua_pushvalue(L, 1); // Explicitly put parameter 1 on top of stack
2590 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
2595 // Register new object prototype
2596 // register_entity(name, prototype)
2597 static int l_register_entity(lua_State *L)
2599 std::string name = luaL_checkstring(L, 1);
2600 check_modname_prefix(L, name);
2601 //infostream<<"register_entity: "<<name<<std::endl;
2602 luaL_checktype(L, 2, LUA_TTABLE);
2604 // Get minetest.registered_entities
2605 lua_getglobal(L, "minetest");
2606 lua_getfield(L, -1, "registered_entities");
2607 luaL_checktype(L, -1, LUA_TTABLE);
2608 int registered_entities = lua_gettop(L);
2609 lua_pushvalue(L, 2); // Object = param 2 -> stack top
2610 // registered_entities[name] = object
2611 lua_setfield(L, registered_entities, name.c_str());
2613 // Get registered object to top of stack
2614 lua_pushvalue(L, 2);
2616 // Set __index to point to itself
2617 lua_pushvalue(L, -1);
2618 lua_setfield(L, -2, "__index");
2620 // Set metatable.__index = metatable
2621 luaL_getmetatable(L, "minetest.entity");
2622 lua_pushvalue(L, -1); // duplicate metatable
2623 lua_setfield(L, -2, "__index");
2624 // Set object metatable
2625 lua_setmetatable(L, -2);
2627 return 0; /* number of results */
2630 class LuaABM : public ActiveBlockModifier
2636 std::set<std::string> m_trigger_contents;
2637 std::set<std::string> m_required_neighbors;
2638 float m_trigger_interval;
2639 u32 m_trigger_chance;
2641 LuaABM(lua_State *L, int id,
2642 const std::set<std::string> &trigger_contents,
2643 const std::set<std::string> &required_neighbors,
2644 float trigger_interval, u32 trigger_chance):
2647 m_trigger_contents(trigger_contents),
2648 m_required_neighbors(required_neighbors),
2649 m_trigger_interval(trigger_interval),
2650 m_trigger_chance(trigger_chance)
2653 virtual std::set<std::string> getTriggerContents()
2655 return m_trigger_contents;
2657 virtual std::set<std::string> getRequiredNeighbors()
2659 return m_required_neighbors;
2661 virtual float getTriggerInterval()
2663 return m_trigger_interval;
2665 virtual u32 getTriggerChance()
2667 return m_trigger_chance;
2669 virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n,
2670 u32 active_object_count, u32 active_object_count_wider)
2672 lua_State *L = m_lua;
2675 assert(lua_checkstack(L, 20));
2676 StackUnroller stack_unroller(L);
2678 // Get minetest.registered_abms
2679 lua_getglobal(L, "minetest");
2680 lua_getfield(L, -1, "registered_abms");
2681 luaL_checktype(L, -1, LUA_TTABLE);
2682 int registered_abms = lua_gettop(L);
2684 // Get minetest.registered_abms[m_id]
2685 lua_pushnumber(L, m_id);
2686 lua_gettable(L, registered_abms);
2687 if(lua_isnil(L, -1))
2691 luaL_checktype(L, -1, LUA_TTABLE);
2692 lua_getfield(L, -1, "action");
2693 luaL_checktype(L, -1, LUA_TFUNCTION);
2695 pushnode(L, n, env->getGameDef()->ndef());
2696 lua_pushnumber(L, active_object_count);
2697 lua_pushnumber(L, active_object_count_wider);
2698 if(lua_pcall(L, 4, 0, 0))
2699 script_error(L, "error: %s", lua_tostring(L, -1));
2703 // register_abm({...})
2704 static int l_register_abm(lua_State *L)
2706 //infostream<<"register_abm"<<std::endl;
2707 luaL_checktype(L, 1, LUA_TTABLE);
2709 // Get minetest.registered_abms
2710 lua_getglobal(L, "minetest");
2711 lua_getfield(L, -1, "registered_abms");
2712 luaL_checktype(L, -1, LUA_TTABLE);
2713 int registered_abms = lua_gettop(L);
2718 lua_pushnumber(L, id);
2719 lua_gettable(L, registered_abms);
2720 if(lua_isnil(L, -1))
2727 infostream<<"register_abm: id="<<id<<std::endl;
2729 // registered_abms[id] = spec
2730 lua_pushnumber(L, id);
2731 lua_pushvalue(L, 1);
2732 lua_settable(L, registered_abms);
2734 return 0; /* number of results */
2737 // register_tool(name, {lots of stuff})
2738 static int l_register_tool(lua_State *L)
2740 std::string name = luaL_checkstring(L, 1);
2741 check_modname_prefix(L, name);
2742 //infostream<<"register_tool: "<<name<<std::endl;
2743 luaL_checktype(L, 2, LUA_TTABLE);
2746 // Get the writable tool definition manager from the server
2747 IWritableToolDefManager *tooldef =
2748 get_server(L)->getWritableToolDefManager();
2750 ToolDefinition def = read_tool_definition(L, table);
2752 tooldef->registerTool(name, def);
2753 return 0; /* number of results */
2756 // register_craftitem(name, {lots of stuff})
2757 static int l_register_craftitem(lua_State *L)
2759 std::string name = luaL_checkstring(L, 1);
2760 check_modname_prefix(L, name);
2761 //infostream<<"register_craftitem: "<<name<<std::endl;
2762 luaL_checktype(L, 2, LUA_TTABLE);
2765 // Get the writable CraftItem definition manager from the server
2766 IWritableCraftItemDefManager *craftitemdef =
2767 get_server(L)->getWritableCraftItemDefManager();
2769 // Check if on_drop is defined
2770 lua_getfield(L, table, "on_drop");
2771 bool got_on_drop = !lua_isnil(L, -1);
2774 // Check if on_use is defined
2775 lua_getfield(L, table, "on_use");
2776 bool got_on_use = !lua_isnil(L, -1);
2779 CraftItemDefinition def;
2781 getstringfield(L, table, "image", def.imagename);
2782 getstringfield(L, table, "cookresult_itemstring", def.cookresult_item);
2783 getfloatfield(L, table, "furnace_cooktime", def.furnace_cooktime);
2784 getfloatfield(L, table, "furnace_burntime", def.furnace_burntime);
2785 def.usable = getboolfield_default(L, table, "usable", got_on_use);
2786 getboolfield(L, table, "liquids_pointable", def.liquids_pointable);
2787 def.dropcount = getintfield_default(L, table, "dropcount", def.dropcount);
2788 def.stack_max = getintfield_default(L, table, "stack_max", def.stack_max);
2790 // If an on_drop callback is defined, force dropcount to 1
2795 craftitemdef->registerCraftItem(name, def);
2797 lua_pushvalue(L, table);
2798 scriptapi_add_craftitem(L, name.c_str());
2800 return 0; /* number of results */
2803 // register_node(name, {lots of stuff})
2804 static int l_register_node(lua_State *L)
2806 std::string name = luaL_checkstring(L, 1);
2807 check_modname_prefix(L, name);
2808 //infostream<<"register_node: "<<name<<std::endl;
2809 luaL_checktype(L, 2, LUA_TTABLE);
2810 int nodedef_table = 2;
2812 // Get the writable node definition manager from the server
2813 IWritableNodeDefManager *nodedef =
2814 get_server(L)->getWritableNodeDefManager();
2816 // Get default node definition from registry
2817 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
2818 int nodedef_default = lua_gettop(L);
2821 Add to minetest.registered_nodes with default as metatable
2824 // Get the node definition table given as parameter
2825 lua_pushvalue(L, nodedef_table);
2827 // Set __index to point to itself
2828 lua_pushvalue(L, -1);
2829 lua_setfield(L, -2, "__index");
2831 // Set nodedef_default as metatable for the definition
2832 lua_pushvalue(L, nodedef_default);
2833 lua_setmetatable(L, nodedef_table);
2835 // minetest.registered_nodes[name] = nodedef
2836 lua_getglobal(L, "minetest");
2837 lua_getfield(L, -1, "registered_nodes");
2838 luaL_checktype(L, -1, LUA_TTABLE);
2839 lua_pushstring(L, name.c_str());
2840 lua_pushvalue(L, nodedef_table);
2841 lua_settable(L, -3);
2849 // Default to getting the corresponding NodeItem when dug
2850 f.dug_item = std::string("NodeItem \"")+name+"\" 1";
2852 // Default to unknown_block.png as all textures
2853 f.setAllTextures("unknown_block.png");
2856 Read definiton from Lua
2861 /* Visual definition */
2863 f.drawtype = (NodeDrawType)getenumfield(L, nodedef_table, "drawtype", es_DrawType,
2865 getfloatfield(L, nodedef_table, "visual_scale", f.visual_scale);
2867 lua_getfield(L, nodedef_table, "tile_images");
2868 if(lua_istable(L, -1)){
2869 int table = lua_gettop(L);
2872 while(lua_next(L, table) != 0){
2873 // key at index -2 and value at index -1
2874 if(lua_isstring(L, -1))
2875 f.tname_tiles[i] = lua_tostring(L, -1);
2877 f.tname_tiles[i] = "";
2878 // removes value, keeps key for next iteration
2886 // Copy last value to all remaining textures
2888 std::string lastname = f.tname_tiles[i-1];
2890 f.tname_tiles[i] = lastname;
2897 getstringfield(L, nodedef_table, "inventory_image", f.tname_inventory);
2899 lua_getfield(L, nodedef_table, "special_materials");
2900 if(lua_istable(L, -1)){
2901 int table = lua_gettop(L);
2904 while(lua_next(L, table) != 0){
2905 // key at index -2 and value at index -1
2906 int smtable = lua_gettop(L);
2907 std::string tname = getstringfield_default(
2908 L, smtable, "image", "");
2909 bool backface_culling = getboolfield_default(
2910 L, smtable, "backface_culling", true);
2911 MaterialSpec mspec(tname, backface_culling);
2912 f.setSpecialMaterial(i, mspec);
2913 // removes value, keeps key for next iteration
2924 f.alpha = getintfield_default(L, nodedef_table, "alpha", 255);
2928 lua_getfield(L, nodedef_table, "post_effect_color");
2929 if(!lua_isnil(L, -1))
2930 f.post_effect_color = readARGB8(L, -1);
2933 f.param_type = (ContentParamType)getenumfield(L, nodedef_table, "paramtype",
2934 es_ContentParamType, CPT_NONE);
2936 // True for all ground-like things like stone and mud, false for eg. trees
2937 getboolfield(L, nodedef_table, "is_ground_content", f.is_ground_content);
2938 f.light_propagates = (f.param_type == CPT_LIGHT);
2939 warn_if_field_exists(L, nodedef_table, "light_propagates",
2940 "deprecated: determined from paramtype");
2941 getboolfield(L, nodedef_table, "sunlight_propagates", f.sunlight_propagates);
2942 // This is used for collision detection.
2943 // Also for general solidness queries.
2944 getboolfield(L, nodedef_table, "walkable", f.walkable);
2945 // Player can point to these
2946 getboolfield(L, nodedef_table, "pointable", f.pointable);
2947 // Player can dig these
2948 getboolfield(L, nodedef_table, "diggable", f.diggable);
2949 // Player can climb these
2950 getboolfield(L, nodedef_table, "climbable", f.climbable);
2951 // Player can build on these
2952 getboolfield(L, nodedef_table, "buildable_to", f.buildable_to);
2953 // If true, param2 is set to direction when placed. Used for torches.
2954 // NOTE: the direction format is quite inefficient and should be changed
2955 getboolfield(L, nodedef_table, "wall_mounted", f.wall_mounted);
2956 // Whether this content type often contains mineral.
2957 // Used for texture atlas creation.
2958 // Currently only enabled for CONTENT_STONE.
2959 getboolfield(L, nodedef_table, "often_contains_mineral", f.often_contains_mineral);
2960 // Inventory item string as which the node appears in inventory when dug.
2961 // Mineral overrides this.
2962 getstringfield(L, nodedef_table, "dug_item", f.dug_item);
2963 // Extra dug item and its rarity
2964 getstringfield(L, nodedef_table, "extra_dug_item", f.extra_dug_item);
2965 // Usual get interval for extra dug item
2966 getintfield(L, nodedef_table, "extra_dug_item_rarity", f.extra_dug_item_rarity);
2967 // Metadata name of node (eg. "furnace")
2968 getstringfield(L, nodedef_table, "metadata_name", f.metadata_name);
2969 // Whether the node is non-liquid, source liquid or flowing liquid
2970 f.liquid_type = (LiquidType)getenumfield(L, nodedef_table, "liquidtype",
2971 es_LiquidType, LIQUID_NONE);
2972 // If the content is liquid, this is the flowing version of the liquid.
2973 getstringfield(L, nodedef_table, "liquid_alternative_flowing",
2974 f.liquid_alternative_flowing);
2975 // If the content is liquid, this is the source version of the liquid.
2976 getstringfield(L, nodedef_table, "liquid_alternative_source",
2977 f.liquid_alternative_source);
2978 // Viscosity for fluid flow, ranging from 1 to 7, with
2979 // 1 giving almost instantaneous propagation and 7 being
2980 // the slowest possible
2981 f.liquid_viscosity = getintfield_default(L, nodedef_table,
2982 "liquid_viscosity", f.liquid_viscosity);
2983 // Amount of light the node emits
2984 f.light_source = getintfield_default(L, nodedef_table,
2985 "light_source", f.light_source);
2986 f.damage_per_second = getintfield_default(L, nodedef_table,
2987 "damage_per_second", f.damage_per_second);
2989 lua_getfield(L, nodedef_table, "selection_box");
2990 if(lua_istable(L, -1)){
2991 f.selection_box.type = (NodeBoxType)getenumfield(L, -1, "type",
2992 es_NodeBoxType, NODEBOX_REGULAR);
2994 lua_getfield(L, -1, "fixed");
2995 if(lua_istable(L, -1))
2996 f.selection_box.fixed = read_aabbox3df32(L, -1, BS);
2999 lua_getfield(L, -1, "wall_top");
3000 if(lua_istable(L, -1))
3001 f.selection_box.wall_top = read_aabbox3df32(L, -1, BS);
3004 lua_getfield(L, -1, "wall_bottom");
3005 if(lua_istable(L, -1))
3006 f.selection_box.wall_bottom = read_aabbox3df32(L, -1, BS);
3009 lua_getfield(L, -1, "wall_side");
3010 if(lua_istable(L, -1))
3011 f.selection_box.wall_side = read_aabbox3df32(L, -1, BS);
3016 lua_getfield(L, nodedef_table, "material");
3017 if(lua_istable(L, -1)){
3018 f.material.diggability = (Diggability)getenumfield(L, -1, "diggability",
3019 es_Diggability, DIGGABLE_NORMAL);
3021 getfloatfield(L, -1, "constant_time", f.material.constant_time);
3022 getfloatfield(L, -1, "weight", f.material.weight);
3023 getfloatfield(L, -1, "crackiness", f.material.crackiness);
3024 getfloatfield(L, -1, "crumbliness", f.material.crumbliness);
3025 getfloatfield(L, -1, "cuttability", f.material.cuttability);
3026 getfloatfield(L, -1, "flammability", f.material.flammability);
3030 getstringfield(L, nodedef_table, "cookresult_itemstring", f.cookresult_item);
3031 getfloatfield(L, nodedef_table, "furnace_cooktime", f.furnace_cooktime);
3032 getfloatfield(L, nodedef_table, "furnace_burntime", f.furnace_burntime);
3038 nodedef->set(name, f);
3040 return 0; /* number of results */
3043 // alias_node(name, convert_to_name)
3044 static int l_alias_node(lua_State *L)
3046 std::string name = luaL_checkstring(L, 1);
3047 std::string convert_to = luaL_checkstring(L, 2);
3049 // Get the writable node definition manager from the server
3050 IWritableNodeDefManager *nodedef =
3051 get_server(L)->getWritableNodeDefManager();
3053 nodedef->setAlias(name, convert_to);
3055 return 0; /* number of results */
3058 // alias_tool(name, convert_to_name)
3059 static int l_alias_tool(lua_State *L)
3061 std::string name = luaL_checkstring(L, 1);
3062 std::string convert_to = luaL_checkstring(L, 2);
3064 // Get the writable tool definition manager from the server
3065 IWritableToolDefManager *tooldef =
3066 get_server(L)->getWritableToolDefManager();
3068 tooldef->setAlias(name, convert_to);
3070 return 0; /* number of results */
3073 // alias_craftitem(name, convert_to_name)
3074 static int l_alias_craftitem(lua_State *L)
3076 std::string name = luaL_checkstring(L, 1);
3077 std::string convert_to = luaL_checkstring(L, 2);
3079 // Get the writable CraftItem definition manager from the server
3080 IWritableCraftItemDefManager *craftitemdef =
3081 get_server(L)->getWritableCraftItemDefManager();
3083 craftitemdef->setAlias(name, convert_to);
3085 return 0; /* number of results */
3088 // register_craft({output=item, recipe={{item00,item10},{item01,item11}})
3089 static int l_register_craft(lua_State *L)
3091 //infostream<<"register_craft"<<std::endl;
3092 luaL_checktype(L, 1, LUA_TTABLE);
3095 // Get the writable craft definition manager from the server
3096 IWritableCraftDefManager *craftdef =
3097 get_server(L)->getWritableCraftDefManager();
3101 std::vector<std::string> input;
3103 lua_getfield(L, table0, "output");
3104 luaL_checktype(L, -1, LUA_TSTRING);
3105 if(lua_isstring(L, -1))
3106 output = lua_tostring(L, -1);
3109 lua_getfield(L, table0, "recipe");
3110 luaL_checktype(L, -1, LUA_TTABLE);
3111 if(lua_istable(L, -1)){
3112 int table1 = lua_gettop(L);
3115 while(lua_next(L, table1) != 0){
3117 // key at index -2 and value at index -1
3118 luaL_checktype(L, -1, LUA_TTABLE);
3119 if(lua_istable(L, -1)){
3120 int table2 = lua_gettop(L);
3122 while(lua_next(L, table2) != 0){
3123 // key at index -2 and value at index -1
3124 luaL_checktype(L, -1, LUA_TSTRING);
3125 input.push_back(lua_tostring(L, -1));
3126 // removes value, keeps key for next iteration
3134 if(colcount != width){
3136 error += "Invalid crafting recipe (output=\""
3138 throw LuaError(L, error);
3141 // removes value, keeps key for next iteration
3148 CraftDefinition def(output, width, input);
3149 craftdef->registerCraft(def);
3151 return 0; /* number of results */
3154 // setting_get(name)
3155 static int l_setting_get(lua_State *L)
3157 const char *name = luaL_checkstring(L, 1);
3159 std::string value = g_settings->get(name);
3160 lua_pushstring(L, value.c_str());
3161 } catch(SettingNotFoundException &e){
3167 // setting_getbool(name)
3168 static int l_setting_getbool(lua_State *L)
3170 const char *name = luaL_checkstring(L, 1);
3172 bool value = g_settings->getBool(name);
3173 lua_pushboolean(L, value);
3174 } catch(SettingNotFoundException &e){
3180 // chat_send_all(text)
3181 static int l_chat_send_all(lua_State *L)
3183 const char *text = luaL_checkstring(L, 1);
3184 // Get server from registry
3185 Server *server = get_server(L);
3187 server->notifyPlayers(narrow_to_wide(text));
3191 // chat_send_player(name, text)
3192 static int l_chat_send_player(lua_State *L)
3194 const char *name = luaL_checkstring(L, 1);
3195 const char *text = luaL_checkstring(L, 2);
3196 // Get server from registry
3197 Server *server = get_server(L);
3199 server->notifyPlayer(name, narrow_to_wide(text));
3203 // get_player_privs(name, text)
3204 static int l_get_player_privs(lua_State *L)
3206 const char *name = luaL_checkstring(L, 1);
3207 // Get server from registry
3208 Server *server = get_server(L);
3211 int table = lua_gettop(L);
3212 u64 privs_i = server->getPlayerAuthPrivs(name);
3213 // Special case for the "name" setting (local player / server owner)
3214 if(name == g_settings->get("name"))
3216 std::set<std::string> privs_s = privsToSet(privs_i);
3217 for(std::set<std::string>::const_iterator
3218 i = privs_s.begin(); i != privs_s.end(); i++){
3219 lua_pushboolean(L, true);
3220 lua_setfield(L, table, i->c_str());
3222 lua_pushvalue(L, table);
3226 // get_inventory(location)
3227 static int l_get_inventory(lua_State *L)
3229 InventoryLocation loc;
3231 std::string type = checkstringfield(L, 1, "type");
3232 if(type == "player"){
3233 std::string name = checkstringfield(L, 1, "name");
3234 loc.setPlayer(name);
3235 } else if(type == "node"){
3236 lua_getfield(L, 1, "pos");
3237 v3s16 pos = check_v3s16(L, -1);
3238 loc.setNodeMeta(pos);
3241 if(get_server(L)->getInventory(loc) != NULL)
3242 InvRef::create(L, loc);
3248 // get_modpath(modname)
3249 static int l_get_modpath(lua_State *L)
3251 const char *modname = luaL_checkstring(L, 1);
3252 // Get server from registry
3253 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
3254 Server *server = (Server*)lua_touserdata(L, -1);
3256 const ModSpec *mod = server->getModSpec(modname);
3261 lua_pushstring(L, mod->path.c_str());
3265 static const struct luaL_Reg minetest_f [] = {
3266 {"register_nodedef_defaults", l_register_nodedef_defaults},
3267 {"register_entity", l_register_entity},
3268 {"register_tool", l_register_tool},
3269 {"register_craftitem", l_register_craftitem},
3270 {"register_node", l_register_node},
3271 {"register_craft", l_register_craft},
3272 {"register_abm", l_register_abm},
3273 {"alias_node", l_alias_node},
3274 {"alias_tool", l_alias_tool},
3275 {"alias_craftitem", l_alias_craftitem},
3276 {"setting_get", l_setting_get},
3277 {"setting_getbool", l_setting_getbool},
3278 {"chat_send_all", l_chat_send_all},
3279 {"chat_send_player", l_chat_send_player},
3280 {"get_player_privs", l_get_player_privs},
3281 {"get_inventory", l_get_inventory},
3282 {"get_modpath", l_get_modpath},
3290 static const struct luaL_Reg minetest_entity_m [] = {
3295 Main export function
3298 void scriptapi_export(lua_State *L, Server *server)
3301 assert(lua_checkstack(L, 20));
3302 infostream<<"scriptapi_export"<<std::endl;
3303 StackUnroller stack_unroller(L);
3305 // Store server as light userdata in registry
3306 lua_pushlightuserdata(L, server);
3307 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_server");
3309 // Store nil as minetest_nodedef_defaults in registry
3311 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
3313 // Register global functions in table minetest
3315 luaL_register(L, NULL, minetest_f);
3316 lua_setglobal(L, "minetest");
3318 // Get the main minetest table
3319 lua_getglobal(L, "minetest");
3321 // Add tables to minetest
3324 lua_setfield(L, -2, "registered_nodes");
3326 lua_setfield(L, -2, "registered_entities");
3328 lua_setfield(L, -2, "registered_craftitems");
3330 lua_setfield(L, -2, "registered_abms");
3333 lua_setfield(L, -2, "object_refs");
3335 lua_setfield(L, -2, "luaentities");
3337 // Create entity prototype
3338 luaL_newmetatable(L, "minetest.entity");
3339 // metatable.__index = metatable
3340 lua_pushvalue(L, -1); // Duplicate metatable
3341 lua_setfield(L, -2, "__index");
3342 // Put functions in metatable
3343 luaL_register(L, NULL, minetest_entity_m);
3344 // Put other stuff in metatable
3346 // Register wrappers
3347 ItemStack::Register(L);
3348 InvRef::Register(L);
3349 NodeMetaRef::Register(L);
3350 ObjectRef::Register(L);
3351 EnvRef::Register(L);
3354 bool scriptapi_loadmod(lua_State *L, const std::string &scriptpath,
3355 const std::string &modname)
3357 ModNameStorer modnamestorer(L, modname);
3359 if(!string_allowed(modname, "abcdefghijklmnopqrstuvwxyz"
3361 errorstream<<"Error loading mod \""<<modname
3362 <<"\": modname does not follow naming conventions: "
3363 <<"Only chararacters [a-z0-9_] are allowed."<<std::endl;
3367 bool success = false;
3370 success = script_load(L, scriptpath.c_str());
3373 errorstream<<"Error loading mod \""<<modname
3374 <<"\": "<<e.what()<<std::endl;
3380 void scriptapi_add_environment(lua_State *L, ServerEnvironment *env)
3383 assert(lua_checkstack(L, 20));
3384 infostream<<"scriptapi_add_environment"<<std::endl;
3385 StackUnroller stack_unroller(L);
3387 // Create EnvRef on stack
3388 EnvRef::create(L, env);
3389 int envref = lua_gettop(L);
3391 // minetest.env = envref
3392 lua_getglobal(L, "minetest");
3393 luaL_checktype(L, -1, LUA_TTABLE);
3394 lua_pushvalue(L, envref);
3395 lua_setfield(L, -2, "env");
3397 // Store environment as light userdata in registry
3398 lua_pushlightuserdata(L, env);
3399 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_env");
3402 Add ActiveBlockModifiers to environment
3405 // Get minetest.registered_abms
3406 lua_getglobal(L, "minetest");
3407 lua_getfield(L, -1, "registered_abms");
3408 luaL_checktype(L, -1, LUA_TTABLE);
3409 int registered_abms = lua_gettop(L);
3411 if(lua_istable(L, registered_abms)){
3412 int table = lua_gettop(L);
3414 while(lua_next(L, table) != 0){
3415 // key at index -2 and value at index -1
3416 int id = lua_tonumber(L, -2);
3417 int current_abm = lua_gettop(L);
3419 std::set<std::string> trigger_contents;
3420 lua_getfield(L, current_abm, "nodenames");
3421 if(lua_istable(L, -1)){
3422 int table = lua_gettop(L);
3424 while(lua_next(L, table) != 0){
3425 // key at index -2 and value at index -1
3426 luaL_checktype(L, -1, LUA_TSTRING);
3427 trigger_contents.insert(lua_tostring(L, -1));
3428 // removes value, keeps key for next iteration
3431 } else if(lua_isstring(L, -1)){
3432 trigger_contents.insert(lua_tostring(L, -1));
3436 std::set<std::string> required_neighbors;
3437 lua_getfield(L, current_abm, "neighbors");
3438 if(lua_istable(L, -1)){
3439 int table = lua_gettop(L);
3441 while(lua_next(L, table) != 0){
3442 // key at index -2 and value at index -1
3443 luaL_checktype(L, -1, LUA_TSTRING);
3444 required_neighbors.insert(lua_tostring(L, -1));
3445 // removes value, keeps key for next iteration
3448 } else if(lua_isstring(L, -1)){
3449 required_neighbors.insert(lua_tostring(L, -1));
3453 float trigger_interval = 10.0;
3454 getfloatfield(L, current_abm, "interval", trigger_interval);
3456 int trigger_chance = 50;
3457 getintfield(L, current_abm, "chance", trigger_chance);
3459 LuaABM *abm = new LuaABM(L, id, trigger_contents,
3460 required_neighbors, trigger_interval, trigger_chance);
3462 env->addActiveBlockModifier(abm);
3464 // removes value, keeps key for next iteration
3472 // Dump stack top with the dump2 function
3473 static void dump2(lua_State *L, const char *name)
3475 // Dump object (debug)
3476 lua_getglobal(L, "dump2");
3477 luaL_checktype(L, -1, LUA_TFUNCTION);
3478 lua_pushvalue(L, -2); // Get previous stack top as first parameter
3479 lua_pushstring(L, name);
3480 if(lua_pcall(L, 2, 0, 0))
3481 script_error(L, "error: %s", lua_tostring(L, -1));
3489 void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj)
3492 assert(lua_checkstack(L, 20));
3493 //infostream<<"scriptapi_add_object_reference: id="<<cobj->getId()<<std::endl;
3494 StackUnroller stack_unroller(L);
3496 // Create object on stack
3497 ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack
3498 int object = lua_gettop(L);
3500 // Get minetest.object_refs table
3501 lua_getglobal(L, "minetest");
3502 lua_getfield(L, -1, "object_refs");
3503 luaL_checktype(L, -1, LUA_TTABLE);
3504 int objectstable = lua_gettop(L);
3506 // object_refs[id] = object
3507 lua_pushnumber(L, cobj->getId()); // Push id
3508 lua_pushvalue(L, object); // Copy object to top of stack
3509 lua_settable(L, objectstable);
3512 void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj)
3515 assert(lua_checkstack(L, 20));
3516 //infostream<<"scriptapi_rm_object_reference: id="<<cobj->getId()<<std::endl;
3517 StackUnroller stack_unroller(L);
3519 // Get minetest.object_refs table
3520 lua_getglobal(L, "minetest");
3521 lua_getfield(L, -1, "object_refs");
3522 luaL_checktype(L, -1, LUA_TTABLE);
3523 int objectstable = lua_gettop(L);
3525 // Get object_refs[id]
3526 lua_pushnumber(L, cobj->getId()); // Push id
3527 lua_gettable(L, objectstable);
3528 // Set object reference to NULL
3529 ObjectRef::set_null(L);
3530 lua_pop(L, 1); // pop object
3532 // Set object_refs[id] = nil
3533 lua_pushnumber(L, cobj->getId()); // Push id
3535 lua_settable(L, objectstable);
3538 bool scriptapi_on_chat_message(lua_State *L, const std::string &name,
3539 const std::string &message)
3542 assert(lua_checkstack(L, 20));
3543 StackUnroller stack_unroller(L);
3545 // Get minetest.registered_on_chat_messages
3546 lua_getglobal(L, "minetest");
3547 lua_getfield(L, -1, "registered_on_chat_messages");
3548 luaL_checktype(L, -1, LUA_TTABLE);
3549 int table = lua_gettop(L);
3552 while(lua_next(L, table) != 0){
3553 // key at index -2 and value at index -1
3554 luaL_checktype(L, -1, LUA_TFUNCTION);
3556 lua_pushstring(L, name.c_str());
3557 lua_pushstring(L, message.c_str());
3558 if(lua_pcall(L, 2, 1, 0))
3559 script_error(L, "error: %s", lua_tostring(L, -1));
3560 bool ate = lua_toboolean(L, -1);
3564 // value removed, keep key for next iteration
3573 void scriptapi_on_newplayer(lua_State *L, ServerActiveObject *player)
3576 assert(lua_checkstack(L, 20));
3577 StackUnroller stack_unroller(L);
3579 // Get minetest.registered_on_newplayers
3580 lua_getglobal(L, "minetest");
3581 lua_getfield(L, -1, "registered_on_newplayers");
3582 luaL_checktype(L, -1, LUA_TTABLE);
3583 int table = lua_gettop(L);
3586 while(lua_next(L, table) != 0){
3587 // key at index -2 and value at index -1
3588 luaL_checktype(L, -1, LUA_TFUNCTION);
3590 objectref_get_or_create(L, player);
3591 if(lua_pcall(L, 1, 0, 0))
3592 script_error(L, "error: %s", lua_tostring(L, -1));
3593 // value removed, keep key for next iteration
3596 bool scriptapi_on_respawnplayer(lua_State *L, ServerActiveObject *player)
3599 assert(lua_checkstack(L, 20));
3600 StackUnroller stack_unroller(L);
3602 bool positioning_handled_by_some = false;
3604 // Get minetest.registered_on_respawnplayers
3605 lua_getglobal(L, "minetest");
3606 lua_getfield(L, -1, "registered_on_respawnplayers");
3607 luaL_checktype(L, -1, LUA_TTABLE);
3608 int table = lua_gettop(L);
3611 while(lua_next(L, table) != 0){
3612 // key at index -2 and value at index -1
3613 luaL_checktype(L, -1, LUA_TFUNCTION);
3615 objectref_get_or_create(L, player);
3616 if(lua_pcall(L, 1, 1, 0))
3617 script_error(L, "error: %s", lua_tostring(L, -1));
3618 bool positioning_handled = lua_toboolean(L, -1);
3620 if(positioning_handled)
3621 positioning_handled_by_some = true;
3622 // value removed, keep key for next iteration
3624 return positioning_handled_by_some;
3627 void scriptapi_get_creative_inventory(lua_State *L, ServerRemotePlayer *player)
3629 lua_getglobal(L, "minetest");
3630 lua_getfield(L, -1, "creative_inventory");
3631 luaL_checktype(L, -1, LUA_TTABLE);
3632 inventory_set_list_from_lua(&player->inventory, "main", L, -1,
3633 player->getEnv()->getGameDef(), PLAYER_INVENTORY_SIZE);
3640 static void pushPointedThing(lua_State *L, const PointedThing& pointed)
3643 if(pointed.type == POINTEDTHING_NODE)
3645 lua_pushstring(L, "node");
3646 lua_setfield(L, -2, "type");
3647 push_v3s16(L, pointed.node_undersurface);
3648 lua_setfield(L, -2, "under");
3649 push_v3s16(L, pointed.node_abovesurface);
3650 lua_setfield(L, -2, "above");
3652 else if(pointed.type == POINTEDTHING_OBJECT)
3654 lua_pushstring(L, "object");
3655 lua_setfield(L, -2, "type");
3656 objectref_get(L, pointed.object_id);
3657 lua_setfield(L, -2, "ref");
3661 lua_pushstring(L, "nothing");
3662 lua_setfield(L, -2, "type");
3666 void scriptapi_add_craftitem(lua_State *L, const char *name)
3668 StackUnroller stack_unroller(L);
3669 assert(lua_gettop(L) > 0);
3671 // Set minetest.registered_craftitems[name] = table on top of stack
3672 lua_getglobal(L, "minetest");
3673 lua_getfield(L, -1, "registered_craftitems");
3674 luaL_checktype(L, -1, LUA_TTABLE);
3675 lua_pushvalue(L, -3); // push another reference to the table to be registered
3676 lua_setfield(L, -2, name); // set minetest.registered_craftitems[name]
3679 static bool get_craftitem_callback(lua_State *L, const char *name,
3680 const char *callbackname)
3682 // Get minetest.registered_craftitems[name][callbackname]
3683 // If that is nil or on error, return false and stack is unchanged
3684 // If that is a function, returns true and pushes the
3685 // function onto the stack
3687 lua_getglobal(L, "minetest");
3688 lua_getfield(L, -1, "registered_craftitems");
3690 luaL_checktype(L, -1, LUA_TTABLE);
3691 lua_getfield(L, -1, name);
3693 // Should be a table
3694 if(lua_type(L, -1) != LUA_TTABLE)
3696 errorstream<<"CraftItem name \""<<name<<"\" not defined"<<std::endl;
3700 lua_getfield(L, -1, callbackname);
3702 // Should be a function or nil
3703 if(lua_type(L, -1) == LUA_TFUNCTION)
3707 else if(lua_isnil(L, -1))
3714 errorstream<<"CraftItem name \""<<name<<"\" callback \""
3715 <<callbackname<<" is not a function"<<std::endl;
3721 bool scriptapi_craftitem_on_drop(lua_State *L, const char *name,
3722 ServerActiveObject *dropper, v3f pos,
3723 bool &callback_exists)
3726 assert(lua_checkstack(L, 20));
3727 //infostream<<"scriptapi_craftitem_on_drop"<<std::endl;
3728 StackUnroller stack_unroller(L);
3730 bool result = false;
3731 callback_exists = get_craftitem_callback(L, name, "on_drop");
3735 lua_pushstring(L, name);
3736 objectref_get_or_create(L, dropper);
3737 pushFloatPos(L, pos);
3738 if(lua_pcall(L, 3, 1, 0))
3739 script_error(L, "error: %s", lua_tostring(L, -1));
3740 result = lua_toboolean(L, -1);
3745 bool scriptapi_craftitem_on_place_on_ground(lua_State *L, const char *name,
3746 ServerActiveObject *placer, v3f pos,
3747 bool &callback_exists)
3750 assert(lua_checkstack(L, 20));
3751 //infostream<<"scriptapi_craftitem_on_place_on_ground"<<std::endl;
3752 StackUnroller stack_unroller(L);
3754 bool result = false;
3755 callback_exists = get_craftitem_callback(L, name, "on_place_on_ground");
3759 lua_pushstring(L, name);
3760 objectref_get_or_create(L, placer);
3761 pushFloatPos(L, pos);
3762 if(lua_pcall(L, 3, 1, 0))
3763 script_error(L, "error: %s", lua_tostring(L, -1));
3764 result = lua_toboolean(L, -1);
3769 bool scriptapi_craftitem_on_use(lua_State *L, const char *name,
3770 ServerActiveObject *user, const PointedThing& pointed,
3771 bool &callback_exists)
3774 assert(lua_checkstack(L, 20));
3775 //infostream<<"scriptapi_craftitem_on_use"<<std::endl;
3776 StackUnroller stack_unroller(L);
3778 bool result = false;
3779 callback_exists = get_craftitem_callback(L, name, "on_use");
3783 lua_pushstring(L, name);
3784 objectref_get_or_create(L, user);
3785 pushPointedThing(L, pointed);
3786 if(lua_pcall(L, 3, 1, 0))
3787 script_error(L, "error: %s", lua_tostring(L, -1));
3788 result = lua_toboolean(L, -1);
3797 void scriptapi_environment_step(lua_State *L, float dtime)
3800 assert(lua_checkstack(L, 20));
3801 //infostream<<"scriptapi_environment_step"<<std::endl;
3802 StackUnroller stack_unroller(L);
3804 // Get minetest.registered_globalsteps
3805 lua_getglobal(L, "minetest");
3806 lua_getfield(L, -1, "registered_globalsteps");
3807 luaL_checktype(L, -1, LUA_TTABLE);
3808 int table = lua_gettop(L);
3811 while(lua_next(L, table) != 0){
3812 // key at index -2 and value at index -1
3813 luaL_checktype(L, -1, LUA_TFUNCTION);
3815 lua_pushnumber(L, dtime);
3816 if(lua_pcall(L, 1, 0, 0))
3817 script_error(L, "error: %s", lua_tostring(L, -1));
3818 // value removed, keep key for next iteration
3822 void scriptapi_environment_on_placenode(lua_State *L, v3s16 p, MapNode newnode,
3823 ServerActiveObject *placer)
3826 assert(lua_checkstack(L, 20));
3827 //infostream<<"scriptapi_environment_on_placenode"<<std::endl;
3828 StackUnroller stack_unroller(L);
3830 // Get the writable node definition manager from the server
3831 IWritableNodeDefManager *ndef =
3832 get_server(L)->getWritableNodeDefManager();
3834 // Get minetest.registered_on_placenodes
3835 lua_getglobal(L, "minetest");
3836 lua_getfield(L, -1, "registered_on_placenodes");
3837 luaL_checktype(L, -1, LUA_TTABLE);
3838 int table = lua_gettop(L);
3841 while(lua_next(L, table) != 0){
3842 // key at index -2 and value at index -1
3843 luaL_checktype(L, -1, LUA_TFUNCTION);
3846 pushnode(L, newnode, ndef);
3847 objectref_get_or_create(L, placer);
3848 if(lua_pcall(L, 3, 0, 0))
3849 script_error(L, "error: %s", lua_tostring(L, -1));
3850 // value removed, keep key for next iteration
3854 void scriptapi_environment_on_dignode(lua_State *L, v3s16 p, MapNode oldnode,
3855 ServerActiveObject *digger)
3858 assert(lua_checkstack(L, 20));
3859 //infostream<<"scriptapi_environment_on_dignode"<<std::endl;
3860 StackUnroller stack_unroller(L);
3862 // Get the writable node definition manager from the server
3863 IWritableNodeDefManager *ndef =
3864 get_server(L)->getWritableNodeDefManager();
3866 // Get minetest.registered_on_dignodes
3867 lua_getglobal(L, "minetest");
3868 lua_getfield(L, -1, "registered_on_dignodes");
3869 luaL_checktype(L, -1, LUA_TTABLE);
3870 int table = lua_gettop(L);
3873 while(lua_next(L, table) != 0){
3874 // key at index -2 and value at index -1
3875 luaL_checktype(L, -1, LUA_TFUNCTION);
3878 pushnode(L, oldnode, ndef);
3879 objectref_get_or_create(L, digger);
3880 if(lua_pcall(L, 3, 0, 0))
3881 script_error(L, "error: %s", lua_tostring(L, -1));
3882 // value removed, keep key for next iteration
3886 void scriptapi_environment_on_punchnode(lua_State *L, v3s16 p, MapNode node,
3887 ServerActiveObject *puncher)
3890 assert(lua_checkstack(L, 20));
3891 //infostream<<"scriptapi_environment_on_punchnode"<<std::endl;
3892 StackUnroller stack_unroller(L);
3894 // Get the writable node definition manager from the server
3895 IWritableNodeDefManager *ndef =
3896 get_server(L)->getWritableNodeDefManager();
3898 // Get minetest.registered_on_punchnodes
3899 lua_getglobal(L, "minetest");
3900 lua_getfield(L, -1, "registered_on_punchnodes");
3901 luaL_checktype(L, -1, LUA_TTABLE);
3902 int table = lua_gettop(L);
3905 while(lua_next(L, table) != 0){
3906 // key at index -2 and value at index -1
3907 luaL_checktype(L, -1, LUA_TFUNCTION);
3910 pushnode(L, node, ndef);
3911 objectref_get_or_create(L, puncher);
3912 if(lua_pcall(L, 3, 0, 0))
3913 script_error(L, "error: %s", lua_tostring(L, -1));
3914 // value removed, keep key for next iteration
3918 void scriptapi_environment_on_generated(lua_State *L, v3s16 minp, v3s16 maxp)
3921 assert(lua_checkstack(L, 20));
3922 //infostream<<"scriptapi_environment_on_generated"<<std::endl;
3923 StackUnroller stack_unroller(L);
3925 // Get minetest.registered_on_generateds
3926 lua_getglobal(L, "minetest");
3927 lua_getfield(L, -1, "registered_on_generateds");
3928 luaL_checktype(L, -1, LUA_TTABLE);
3929 int table = lua_gettop(L);
3932 while(lua_next(L, table) != 0){
3933 // key at index -2 and value at index -1
3934 luaL_checktype(L, -1, LUA_TFUNCTION);
3936 push_v3s16(L, minp);
3937 push_v3s16(L, maxp);
3938 if(lua_pcall(L, 2, 0, 0))
3939 script_error(L, "error: %s", lua_tostring(L, -1));
3940 // value removed, keep key for next iteration
3948 bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
3949 const std::string &staticdata)
3952 assert(lua_checkstack(L, 20));
3953 infostream<<"scriptapi_luaentity_add: id="<<id<<" name=\""
3954 <<name<<"\""<<std::endl;
3955 StackUnroller stack_unroller(L);
3957 // Get minetest.registered_entities[name]
3958 lua_getglobal(L, "minetest");
3959 lua_getfield(L, -1, "registered_entities");
3960 luaL_checktype(L, -1, LUA_TTABLE);
3961 lua_pushstring(L, name);
3962 lua_gettable(L, -2);
3963 // Should be a table, which we will use as a prototype
3964 //luaL_checktype(L, -1, LUA_TTABLE);
3965 if(lua_type(L, -1) != LUA_TTABLE){
3966 errorstream<<"LuaEntity name \""<<name<<"\" not defined"<<std::endl;
3969 int prototype_table = lua_gettop(L);
3970 //dump2(L, "prototype_table");
3972 // Create entity object
3974 int object = lua_gettop(L);
3976 // Set object metatable
3977 lua_pushvalue(L, prototype_table);
3978 lua_setmetatable(L, -2);
3980 // Add object reference
3981 // This should be userdata with metatable ObjectRef
3982 objectref_get(L, id);
3983 luaL_checktype(L, -1, LUA_TUSERDATA);
3984 if(!luaL_checkudata(L, -1, "ObjectRef"))
3985 luaL_typerror(L, -1, "ObjectRef");
3986 lua_setfield(L, -2, "object");
3988 // minetest.luaentities[id] = object
3989 lua_getglobal(L, "minetest");
3990 lua_getfield(L, -1, "luaentities");
3991 luaL_checktype(L, -1, LUA_TTABLE);
3992 lua_pushnumber(L, id); // Push id
3993 lua_pushvalue(L, object); // Copy object to top of stack
3994 lua_settable(L, -3);
3996 // Get on_activate function
3997 lua_pushvalue(L, object);
3998 lua_getfield(L, -1, "on_activate");
3999 if(!lua_isnil(L, -1)){
4000 luaL_checktype(L, -1, LUA_TFUNCTION);
4001 lua_pushvalue(L, object); // self
4002 lua_pushlstring(L, staticdata.c_str(), staticdata.size());
4003 // Call with 2 arguments, 0 results
4004 if(lua_pcall(L, 2, 0, 0))
4005 script_error(L, "error running function %s:on_activate: %s\n",
4006 name, lua_tostring(L, -1));
4012 void scriptapi_luaentity_rm(lua_State *L, u16 id)
4015 assert(lua_checkstack(L, 20));
4016 infostream<<"scriptapi_luaentity_rm: id="<<id<<std::endl;
4018 // Get minetest.luaentities table
4019 lua_getglobal(L, "minetest");
4020 lua_getfield(L, -1, "luaentities");
4021 luaL_checktype(L, -1, LUA_TTABLE);
4022 int objectstable = lua_gettop(L);
4024 // Set luaentities[id] = nil
4025 lua_pushnumber(L, id); // Push id
4027 lua_settable(L, objectstable);
4029 lua_pop(L, 2); // pop luaentities, minetest
4032 std::string scriptapi_luaentity_get_staticdata(lua_State *L, u16 id)
4035 assert(lua_checkstack(L, 20));
4036 infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl;
4037 StackUnroller stack_unroller(L);
4039 // Get minetest.luaentities[id]
4040 luaentity_get(L, id);
4041 int object = lua_gettop(L);
4043 // Get get_staticdata function
4044 lua_pushvalue(L, object);
4045 lua_getfield(L, -1, "get_staticdata");
4046 if(lua_isnil(L, -1))
4049 luaL_checktype(L, -1, LUA_TFUNCTION);
4050 lua_pushvalue(L, object); // self
4051 // Call with 1 arguments, 1 results
4052 if(lua_pcall(L, 1, 1, 0))
4053 script_error(L, "error running function get_staticdata: %s\n",
4054 lua_tostring(L, -1));
4057 const char *s = lua_tolstring(L, -1, &len);
4058 return std::string(s, len);
4061 void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
4062 LuaEntityProperties *prop)
4065 assert(lua_checkstack(L, 20));
4066 infostream<<"scriptapi_luaentity_get_properties: id="<<id<<std::endl;
4067 StackUnroller stack_unroller(L);
4069 // Get minetest.luaentities[id]
4070 luaentity_get(L, id);
4071 //int object = lua_gettop(L);
4075 getboolfield(L, -1, "physical", prop->physical);
4077 getfloatfield(L, -1, "weight", prop->weight);
4079 lua_getfield(L, -1, "collisionbox");
4080 if(lua_istable(L, -1))
4081 prop->collisionbox = read_aabbox3df32(L, -1, 1.0);
4084 getstringfield(L, -1, "visual", prop->visual);
4086 lua_getfield(L, -1, "visual_size");
4087 if(lua_istable(L, -1))
4088 prop->visual_size = read_v2f(L, -1);
4091 lua_getfield(L, -1, "textures");
4092 if(lua_istable(L, -1)){
4093 prop->textures.clear();
4094 int table = lua_gettop(L);
4096 while(lua_next(L, table) != 0){
4097 // key at index -2 and value at index -1
4098 if(lua_isstring(L, -1))
4099 prop->textures.push_back(lua_tostring(L, -1));
4101 prop->textures.push_back("");
4102 // removes value, keeps key for next iteration
4108 lua_getfield(L, -1, "spritediv");
4109 if(lua_istable(L, -1))
4110 prop->spritediv = read_v2s16(L, -1);
4113 lua_getfield(L, -1, "initial_sprite_basepos");
4114 if(lua_istable(L, -1))
4115 prop->initial_sprite_basepos = read_v2s16(L, -1);
4119 void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime)
4122 assert(lua_checkstack(L, 20));
4123 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
4124 StackUnroller stack_unroller(L);
4126 // Get minetest.luaentities[id]
4127 luaentity_get(L, id);
4128 int object = lua_gettop(L);
4129 // State: object is at top of stack
4130 // Get step function
4131 lua_getfield(L, -1, "on_step");
4132 if(lua_isnil(L, -1))
4134 luaL_checktype(L, -1, LUA_TFUNCTION);
4135 lua_pushvalue(L, object); // self
4136 lua_pushnumber(L, dtime); // dtime
4137 // Call with 2 arguments, 0 results
4138 if(lua_pcall(L, 2, 0, 0))
4139 script_error(L, "error running function 'on_step': %s\n", lua_tostring(L, -1));
4142 // Calls entity:on_punch(ObjectRef puncher, time_from_last_punch)
4143 void scriptapi_luaentity_punch(lua_State *L, u16 id,
4144 ServerActiveObject *puncher, float time_from_last_punch)
4147 assert(lua_checkstack(L, 20));
4148 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
4149 StackUnroller stack_unroller(L);
4151 // Get minetest.luaentities[id]
4152 luaentity_get(L, id);
4153 int object = lua_gettop(L);
4154 // State: object is at top of stack
4156 lua_getfield(L, -1, "on_punch");
4157 if(lua_isnil(L, -1))
4159 luaL_checktype(L, -1, LUA_TFUNCTION);
4160 lua_pushvalue(L, object); // self
4161 objectref_get_or_create(L, puncher); // Clicker reference
4162 lua_pushnumber(L, time_from_last_punch);
4163 // Call with 2 arguments, 0 results
4164 if(lua_pcall(L, 3, 0, 0))
4165 script_error(L, "error running function 'on_punch': %s\n", lua_tostring(L, -1));
4168 // Calls entity:on_rightclick(ObjectRef clicker)
4169 void scriptapi_luaentity_rightclick(lua_State *L, u16 id,
4170 ServerActiveObject *clicker)
4173 assert(lua_checkstack(L, 20));
4174 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
4175 StackUnroller stack_unroller(L);
4177 // Get minetest.luaentities[id]
4178 luaentity_get(L, id);
4179 int object = lua_gettop(L);
4180 // State: object is at top of stack
4182 lua_getfield(L, -1, "on_rightclick");
4183 if(lua_isnil(L, -1))
4185 luaL_checktype(L, -1, LUA_TFUNCTION);
4186 lua_pushvalue(L, object); // self
4187 objectref_get_or_create(L, clicker); // Clicker reference
4188 // Call with 2 arguments, 0 results
4189 if(lua_pcall(L, 2, 0, 0))
4190 script_error(L, "error running function 'on_rightclick': %s\n", lua_tostring(L, -1));