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 // getvelocity(self)
1932 static int l_getvelocity(lua_State *L)
1934 ObjectRef *ref = checkobject(L, 1);
1935 LuaEntitySAO *co = getluaobject(ref);
1936 if(co == NULL) return 0;
1938 v3f v = co->getVelocity();
1943 // setacceleration(self, {x=num, y=num, z=num})
1944 static int l_setacceleration(lua_State *L)
1946 ObjectRef *ref = checkobject(L, 1);
1947 LuaEntitySAO *co = getluaobject(ref);
1948 if(co == NULL) return 0;
1950 v3f pos = checkFloatPos(L, 2);
1952 co->setAcceleration(pos);
1956 // getacceleration(self)
1957 static int l_getacceleration(lua_State *L)
1959 ObjectRef *ref = checkobject(L, 1);
1960 LuaEntitySAO *co = getluaobject(ref);
1961 if(co == NULL) return 0;
1963 v3f v = co->getAcceleration();
1968 // setyaw(self, radians)
1969 static int l_setyaw(lua_State *L)
1971 ObjectRef *ref = checkobject(L, 1);
1972 LuaEntitySAO *co = getluaobject(ref);
1973 if(co == NULL) return 0;
1975 float yaw = luaL_checknumber(L, 2) * core::RADTODEG;
1982 static int l_getyaw(lua_State *L)
1984 ObjectRef *ref = checkobject(L, 1);
1985 LuaEntitySAO *co = getluaobject(ref);
1986 if(co == NULL) return 0;
1988 float yaw = co->getYaw() * core::DEGTORAD;
1989 lua_pushnumber(L, yaw);
1993 // settexturemod(self, mod)
1994 static int l_settexturemod(lua_State *L)
1996 ObjectRef *ref = checkobject(L, 1);
1997 LuaEntitySAO *co = getluaobject(ref);
1998 if(co == NULL) return 0;
2000 std::string mod = luaL_checkstring(L, 2);
2001 co->setTextureMod(mod);
2005 // setsprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2,
2006 // select_horiz_by_yawpitch=false)
2007 static int l_setsprite(lua_State *L)
2009 ObjectRef *ref = checkobject(L, 1);
2010 LuaEntitySAO *co = getluaobject(ref);
2011 if(co == NULL) return 0;
2014 if(!lua_isnil(L, 2))
2015 p = read_v2s16(L, 2);
2017 if(!lua_isnil(L, 3))
2018 num_frames = lua_tonumber(L, 3);
2019 float framelength = 0.2;
2020 if(!lua_isnil(L, 4))
2021 framelength = lua_tonumber(L, 4);
2022 bool select_horiz_by_yawpitch = false;
2023 if(!lua_isnil(L, 5))
2024 select_horiz_by_yawpitch = lua_toboolean(L, 5);
2025 co->setSprite(p, num_frames, framelength, select_horiz_by_yawpitch);
2029 // get_entity_name(self)
2030 static int l_get_entity_name(lua_State *L)
2032 ObjectRef *ref = checkobject(L, 1);
2033 LuaEntitySAO *co = getluaobject(ref);
2034 if(co == NULL) return 0;
2036 std::string name = co->getName();
2037 lua_pushstring(L, name.c_str());
2041 // get_luaentity(self)
2042 static int l_get_luaentity(lua_State *L)
2044 ObjectRef *ref = checkobject(L, 1);
2045 LuaEntitySAO *co = getluaobject(ref);
2046 if(co == NULL) return 0;
2048 luaentity_get(L, co->getId());
2054 // get_player_name(self)
2055 static int l_get_player_name(lua_State *L)
2057 ObjectRef *ref = checkobject(L, 1);
2058 ServerRemotePlayer *player = getplayer(ref);
2064 lua_pushstring(L, player->getName());
2068 // get_inventory(self)
2069 static int l_get_inventory(lua_State *L)
2071 ObjectRef *ref = checkobject(L, 1);
2072 ServerRemotePlayer *player = getplayer(ref);
2073 if(player == NULL) return 0;
2075 InvRef::createPlayer(L, player);
2079 // deprecated: inventory_set_list(self, name, {item1, item2, ...})
2080 static int l_inventory_set_list(lua_State *L)
2082 infostream<<"Deprecated: inventory_set_list"<<std::endl;
2083 ObjectRef *ref = checkobject(L, 1);
2084 ServerRemotePlayer *player = getplayer(ref);
2085 if(player == NULL) return 0;
2086 const char *name = luaL_checkstring(L, 2);
2088 inventory_set_list_from_lua(&player->inventory, name, L, 3,
2089 player->getEnv()->getGameDef(), PLAYER_INVENTORY_SIZE);
2090 player->m_inventory_not_sent = true;
2094 // deprecated: inventory_get_list(self, name)
2095 static int l_inventory_get_list(lua_State *L)
2097 infostream<<"Deprecated: inventory_get_list"<<std::endl;
2098 ObjectRef *ref = checkobject(L, 1);
2099 ServerRemotePlayer *player = getplayer(ref);
2100 if(player == NULL) return 0;
2101 const char *name = luaL_checkstring(L, 2);
2103 inventory_get_list_to_lua(&player->inventory, name, L);
2107 // get_wielded_itemstring(self)
2108 static int l_get_wielded_itemstring(lua_State *L)
2110 ObjectRef *ref = checkobject(L, 1);
2111 ServerRemotePlayer *player = getplayer(ref);
2112 if(player == NULL) return 0;
2114 InventoryItem *item = player->getWieldedItem();
2119 lua_pushstring(L, item->getItemString().c_str());
2123 // get_wielded_item(self)
2124 static int l_get_wielded_item(lua_State *L)
2126 ObjectRef *ref = checkobject(L, 1);
2127 ServerRemotePlayer *player = getplayer(ref);
2128 if(player == NULL) return 0;
2130 InventoryItem *item0 = player->getWieldedItem();
2131 push_stack_item(L, item0);
2135 // get_look_dir(self)
2136 static int l_get_look_dir(lua_State *L)
2138 ObjectRef *ref = checkobject(L, 1);
2139 ServerRemotePlayer *player = getplayer(ref);
2140 if(player == NULL) return 0;
2142 float pitch = player->getRadPitch();
2143 float yaw = player->getRadYaw();
2144 v3f v(cos(pitch)*cos(yaw), sin(pitch), cos(pitch)*sin(yaw));
2149 // get_look_pitch(self)
2150 static int l_get_look_pitch(lua_State *L)
2152 ObjectRef *ref = checkobject(L, 1);
2153 ServerRemotePlayer *player = getplayer(ref);
2154 if(player == NULL) return 0;
2156 lua_pushnumber(L, player->getRadPitch());
2160 // get_look_yaw(self)
2161 static int l_get_look_yaw(lua_State *L)
2163 ObjectRef *ref = checkobject(L, 1);
2164 ServerRemotePlayer *player = getplayer(ref);
2165 if(player == NULL) return 0;
2167 lua_pushnumber(L, player->getRadYaw());
2172 ObjectRef(ServerActiveObject *object):
2175 //infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
2181 infostream<<"ObjectRef destructing for id="
2182 <<m_object->getId()<<std::endl;
2184 infostream<<"ObjectRef destructing for id=unknown"<<std::endl;*/
2187 // Creates an ObjectRef and leaves it on top of stack
2188 // Not callable from Lua; all references are created on the C side.
2189 static void create(lua_State *L, ServerActiveObject *object)
2191 ObjectRef *o = new ObjectRef(object);
2192 //infostream<<"ObjectRef::create: o="<<o<<std::endl;
2193 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
2194 luaL_getmetatable(L, className);
2195 lua_setmetatable(L, -2);
2198 static void set_null(lua_State *L)
2200 ObjectRef *o = checkobject(L, -1);
2204 static void Register(lua_State *L)
2207 int methodtable = lua_gettop(L);
2208 luaL_newmetatable(L, className);
2209 int metatable = lua_gettop(L);
2211 lua_pushliteral(L, "__metatable");
2212 lua_pushvalue(L, methodtable);
2213 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
2215 lua_pushliteral(L, "__index");
2216 lua_pushvalue(L, methodtable);
2217 lua_settable(L, metatable);
2219 lua_pushliteral(L, "__gc");
2220 lua_pushcfunction(L, gc_object);
2221 lua_settable(L, metatable);
2223 lua_pop(L, 1); // drop metatable
2225 luaL_openlib(L, 0, methods, 0); // fill methodtable
2226 lua_pop(L, 1); // drop methodtable
2228 // Cannot be created from Lua
2229 //lua_register(L, className, create_object);
2232 const char ObjectRef::className[] = "ObjectRef";
2233 const luaL_reg ObjectRef::methods[] = {
2234 // ServerActiveObject
2235 method(ObjectRef, remove),
2236 method(ObjectRef, getpos),
2237 method(ObjectRef, setpos),
2238 method(ObjectRef, moveto),
2239 method(ObjectRef, punch),
2240 method(ObjectRef, right_click),
2241 method(ObjectRef, get_wield_digging_properties),
2242 method(ObjectRef, damage_wielded_item),
2243 method(ObjectRef, add_to_inventory),
2244 method(ObjectRef, add_to_inventory_later),
2245 method(ObjectRef, set_hp),
2246 method(ObjectRef, get_hp),
2247 // LuaEntitySAO-only
2248 method(ObjectRef, setvelocity),
2249 method(ObjectRef, getvelocity),
2250 method(ObjectRef, setacceleration),
2251 method(ObjectRef, getacceleration),
2252 method(ObjectRef, setyaw),
2253 method(ObjectRef, getyaw),
2254 method(ObjectRef, settexturemod),
2255 method(ObjectRef, setsprite),
2256 method(ObjectRef, get_entity_name),
2257 method(ObjectRef, get_luaentity),
2259 method(ObjectRef, get_player_name),
2260 method(ObjectRef, get_inventory),
2261 method(ObjectRef, inventory_set_list), // deprecated
2262 method(ObjectRef, inventory_get_list), // deprecated
2263 method(ObjectRef, get_wielded_itemstring),
2264 method(ObjectRef, get_wielded_item),
2265 method(ObjectRef, get_look_dir),
2266 method(ObjectRef, get_look_pitch),
2267 method(ObjectRef, get_look_yaw),
2271 // Creates a new anonymous reference if id=0
2272 static void objectref_get_or_create(lua_State *L,
2273 ServerActiveObject *cobj)
2275 if(cobj->getId() == 0){
2276 ObjectRef::create(L, cobj);
2278 objectref_get(L, cobj->getId());
2289 ServerEnvironment *m_env;
2291 static const char className[];
2292 static const luaL_reg methods[];
2294 static EnvRef *checkobject(lua_State *L, int narg)
2296 luaL_checktype(L, narg, LUA_TUSERDATA);
2297 void *ud = luaL_checkudata(L, narg, className);
2298 if(!ud) luaL_typerror(L, narg, className);
2299 return *(EnvRef**)ud; // unbox pointer
2302 // Exported functions
2304 // EnvRef:add_node(pos, node)
2305 // pos = {x=num, y=num, z=num}
2306 static int l_add_node(lua_State *L)
2308 //infostream<<"EnvRef::l_add_node()"<<std::endl;
2309 EnvRef *o = checkobject(L, 1);
2310 ServerEnvironment *env = o->m_env;
2311 if(env == NULL) return 0;
2313 v3s16 pos = read_v3s16(L, 2);
2315 MapNode n = readnode(L, 3, env->getGameDef()->ndef());
2317 bool succeeded = env->getMap().addNodeWithEvent(pos, n);
2318 lua_pushboolean(L, succeeded);
2322 // EnvRef:remove_node(pos)
2323 // pos = {x=num, y=num, z=num}
2324 static int l_remove_node(lua_State *L)
2326 //infostream<<"EnvRef::l_remove_node()"<<std::endl;
2327 EnvRef *o = checkobject(L, 1);
2328 ServerEnvironment *env = o->m_env;
2329 if(env == NULL) return 0;
2331 v3s16 pos = read_v3s16(L, 2);
2333 bool succeeded = env->getMap().removeNodeWithEvent(pos);
2334 lua_pushboolean(L, succeeded);
2338 // EnvRef:get_node(pos)
2339 // pos = {x=num, y=num, z=num}
2340 static int l_get_node(lua_State *L)
2342 //infostream<<"EnvRef::l_get_node()"<<std::endl;
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);
2349 MapNode n = env->getMap().getNodeNoEx(pos);
2351 pushnode(L, n, env->getGameDef()->ndef());
2355 // EnvRef:get_node_or_nil(pos)
2356 // pos = {x=num, y=num, z=num}
2357 static int l_get_node_or_nil(lua_State *L)
2359 //infostream<<"EnvRef::l_get_node()"<<std::endl;
2360 EnvRef *o = checkobject(L, 1);
2361 ServerEnvironment *env = o->m_env;
2362 if(env == NULL) return 0;
2364 v3s16 pos = read_v3s16(L, 2);
2367 MapNode n = env->getMap().getNode(pos);
2369 pushnode(L, n, env->getGameDef()->ndef());
2371 } catch(InvalidPositionException &e)
2378 // EnvRef:get_node_light(pos, timeofday)
2379 // pos = {x=num, y=num, z=num}
2380 // timeofday: nil = current time, 0 = night, 0.5 = day
2381 static int l_get_node_light(lua_State *L)
2383 EnvRef *o = checkobject(L, 1);
2384 ServerEnvironment *env = o->m_env;
2385 if(env == NULL) return 0;
2387 v3s16 pos = read_v3s16(L, 2);
2388 u32 time_of_day = env->getTimeOfDay();
2389 if(lua_isnumber(L, 3))
2390 time_of_day = 24000.0 * lua_tonumber(L, 3);
2391 time_of_day %= 24000;
2392 u32 dnr = time_to_daynight_ratio(time_of_day);
2393 MapNode n = env->getMap().getNodeNoEx(pos);
2395 MapNode n = env->getMap().getNode(pos);
2396 INodeDefManager *ndef = env->getGameDef()->ndef();
2397 lua_pushinteger(L, n.getLightBlend(dnr, ndef));
2399 } catch(InvalidPositionException &e)
2406 // EnvRef:add_entity(pos, entityname)
2407 // pos = {x=num, y=num, z=num}
2408 static int l_add_entity(lua_State *L)
2410 //infostream<<"EnvRef::l_add_entity()"<<std::endl;
2411 EnvRef *o = checkobject(L, 1);
2412 ServerEnvironment *env = o->m_env;
2413 if(env == NULL) return 0;
2415 v3f pos = checkFloatPos(L, 2);
2417 const char *name = luaL_checkstring(L, 3);
2419 ServerActiveObject *obj = new LuaEntitySAO(env, pos, name, "");
2420 int objectid = env->addActiveObject(obj);
2421 // If failed to add, return nothing (reads as nil)
2425 objectref_get_or_create(L, obj);
2429 // EnvRef:add_item(pos, inventorystring)
2430 // pos = {x=num, y=num, z=num}
2431 static int l_add_item(lua_State *L)
2433 infostream<<"EnvRef::l_add_item()"<<std::endl;
2434 EnvRef *o = checkobject(L, 1);
2435 ServerEnvironment *env = o->m_env;
2436 if(env == NULL) return 0;
2438 v3f pos = checkFloatPos(L, 2);
2440 const char *inventorystring = luaL_checkstring(L, 3);
2442 ServerActiveObject *obj = new ItemSAO(env, pos, inventorystring);
2443 env->addActiveObject(obj);
2447 // EnvRef:add_rat(pos)
2448 // pos = {x=num, y=num, z=num}
2449 static int l_add_rat(lua_State *L)
2451 infostream<<"EnvRef::l_add_rat()"<<std::endl;
2452 EnvRef *o = checkobject(L, 1);
2453 ServerEnvironment *env = o->m_env;
2454 if(env == NULL) return 0;
2456 v3f pos = checkFloatPos(L, 2);
2458 ServerActiveObject *obj = new RatSAO(env, pos);
2459 env->addActiveObject(obj);
2463 // EnvRef:add_firefly(pos)
2464 // pos = {x=num, y=num, z=num}
2465 static int l_add_firefly(lua_State *L)
2467 infostream<<"EnvRef::l_add_firefly()"<<std::endl;
2468 EnvRef *o = checkobject(L, 1);
2469 ServerEnvironment *env = o->m_env;
2470 if(env == NULL) return 0;
2472 v3f pos = checkFloatPos(L, 2);
2474 ServerActiveObject *obj = new FireflySAO(env, pos);
2475 env->addActiveObject(obj);
2479 // EnvRef:get_meta(pos)
2480 static int l_get_meta(lua_State *L)
2482 //infostream<<"EnvRef::l_get_meta()"<<std::endl;
2483 EnvRef *o = checkobject(L, 1);
2484 ServerEnvironment *env = o->m_env;
2485 if(env == NULL) return 0;
2487 v3s16 p = read_v3s16(L, 2);
2488 NodeMetaRef::create(L, p, env);
2492 // EnvRef:get_player_by_name(name)
2493 static int l_get_player_by_name(lua_State *L)
2495 EnvRef *o = checkobject(L, 1);
2496 ServerEnvironment *env = o->m_env;
2497 if(env == NULL) return 0;
2499 const char *name = luaL_checkstring(L, 2);
2500 ServerRemotePlayer *player =
2501 static_cast<ServerRemotePlayer*>(env->getPlayer(name));
2506 // Put player on stack
2507 objectref_get_or_create(L, player);
2511 // EnvRef:get_objects_inside_radius(pos, radius)
2512 static int l_get_objects_inside_radius(lua_State *L)
2514 // Get the table insert function
2515 lua_getglobal(L, "table");
2516 lua_getfield(L, -1, "insert");
2517 int table_insert = lua_gettop(L);
2519 EnvRef *o = checkobject(L, 1);
2520 ServerEnvironment *env = o->m_env;
2521 if(env == NULL) return 0;
2523 v3f pos = checkFloatPos(L, 2);
2524 float radius = luaL_checknumber(L, 3) * BS;
2525 std::set<u16> ids = env->getObjectsInsideRadius(pos, radius);
2527 int table = lua_gettop(L);
2528 for(std::set<u16>::const_iterator
2529 i = ids.begin(); i != ids.end(); i++){
2530 ServerActiveObject *obj = env->getActiveObject(*i);
2531 // Insert object reference into table
2532 lua_pushvalue(L, table_insert);
2533 lua_pushvalue(L, table);
2534 objectref_get_or_create(L, obj);
2535 if(lua_pcall(L, 2, 0, 0))
2536 script_error(L, "error: %s", lua_tostring(L, -1));
2541 static int gc_object(lua_State *L) {
2542 EnvRef *o = *(EnvRef **)(lua_touserdata(L, 1));
2548 EnvRef(ServerEnvironment *env):
2551 infostream<<"EnvRef created"<<std::endl;
2556 infostream<<"EnvRef destructing"<<std::endl;
2559 // Creates an EnvRef and leaves it on top of stack
2560 // Not callable from Lua; all references are created on the C side.
2561 static void create(lua_State *L, ServerEnvironment *env)
2563 EnvRef *o = new EnvRef(env);
2564 //infostream<<"EnvRef::create: o="<<o<<std::endl;
2565 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
2566 luaL_getmetatable(L, className);
2567 lua_setmetatable(L, -2);
2570 static void set_null(lua_State *L)
2572 EnvRef *o = checkobject(L, -1);
2576 static void Register(lua_State *L)
2579 int methodtable = lua_gettop(L);
2580 luaL_newmetatable(L, className);
2581 int metatable = lua_gettop(L);
2583 lua_pushliteral(L, "__metatable");
2584 lua_pushvalue(L, methodtable);
2585 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
2587 lua_pushliteral(L, "__index");
2588 lua_pushvalue(L, methodtable);
2589 lua_settable(L, metatable);
2591 lua_pushliteral(L, "__gc");
2592 lua_pushcfunction(L, gc_object);
2593 lua_settable(L, metatable);
2595 lua_pop(L, 1); // drop metatable
2597 luaL_openlib(L, 0, methods, 0); // fill methodtable
2598 lua_pop(L, 1); // drop methodtable
2600 // Cannot be created from Lua
2601 //lua_register(L, className, create_object);
2604 const char EnvRef::className[] = "EnvRef";
2605 const luaL_reg EnvRef::methods[] = {
2606 method(EnvRef, add_node),
2607 method(EnvRef, remove_node),
2608 method(EnvRef, get_node),
2609 method(EnvRef, get_node_or_nil),
2610 method(EnvRef, get_node_light),
2611 method(EnvRef, add_entity),
2612 method(EnvRef, add_item),
2613 method(EnvRef, add_rat),
2614 method(EnvRef, add_firefly),
2615 method(EnvRef, get_meta),
2616 method(EnvRef, get_player_by_name),
2617 method(EnvRef, get_objects_inside_radius),
2625 static int l_register_nodedef_defaults(lua_State *L)
2627 luaL_checktype(L, 1, LUA_TTABLE);
2629 lua_pushvalue(L, 1); // Explicitly put parameter 1 on top of stack
2630 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
2635 // Register new object prototype
2636 // register_entity(name, prototype)
2637 static int l_register_entity(lua_State *L)
2639 std::string name = luaL_checkstring(L, 1);
2640 check_modname_prefix(L, name);
2641 //infostream<<"register_entity: "<<name<<std::endl;
2642 luaL_checktype(L, 2, LUA_TTABLE);
2644 // Get minetest.registered_entities
2645 lua_getglobal(L, "minetest");
2646 lua_getfield(L, -1, "registered_entities");
2647 luaL_checktype(L, -1, LUA_TTABLE);
2648 int registered_entities = lua_gettop(L);
2649 lua_pushvalue(L, 2); // Object = param 2 -> stack top
2650 // registered_entities[name] = object
2651 lua_setfield(L, registered_entities, name.c_str());
2653 // Get registered object to top of stack
2654 lua_pushvalue(L, 2);
2657 lua_pushvalue(L, 1);
2658 lua_setfield(L, -2, "name");
2660 // Set __index to point to itself
2661 lua_pushvalue(L, -1);
2662 lua_setfield(L, -2, "__index");
2664 // Set metatable.__index = metatable
2665 luaL_getmetatable(L, "minetest.entity");
2666 lua_pushvalue(L, -1); // duplicate metatable
2667 lua_setfield(L, -2, "__index");
2668 // Set object metatable
2669 lua_setmetatable(L, -2);
2671 return 0; /* number of results */
2674 class LuaABM : public ActiveBlockModifier
2680 std::set<std::string> m_trigger_contents;
2681 std::set<std::string> m_required_neighbors;
2682 float m_trigger_interval;
2683 u32 m_trigger_chance;
2685 LuaABM(lua_State *L, int id,
2686 const std::set<std::string> &trigger_contents,
2687 const std::set<std::string> &required_neighbors,
2688 float trigger_interval, u32 trigger_chance):
2691 m_trigger_contents(trigger_contents),
2692 m_required_neighbors(required_neighbors),
2693 m_trigger_interval(trigger_interval),
2694 m_trigger_chance(trigger_chance)
2697 virtual std::set<std::string> getTriggerContents()
2699 return m_trigger_contents;
2701 virtual std::set<std::string> getRequiredNeighbors()
2703 return m_required_neighbors;
2705 virtual float getTriggerInterval()
2707 return m_trigger_interval;
2709 virtual u32 getTriggerChance()
2711 return m_trigger_chance;
2713 virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n,
2714 u32 active_object_count, u32 active_object_count_wider)
2716 lua_State *L = m_lua;
2719 assert(lua_checkstack(L, 20));
2720 StackUnroller stack_unroller(L);
2722 // Get minetest.registered_abms
2723 lua_getglobal(L, "minetest");
2724 lua_getfield(L, -1, "registered_abms");
2725 luaL_checktype(L, -1, LUA_TTABLE);
2726 int registered_abms = lua_gettop(L);
2728 // Get minetest.registered_abms[m_id]
2729 lua_pushnumber(L, m_id);
2730 lua_gettable(L, registered_abms);
2731 if(lua_isnil(L, -1))
2735 luaL_checktype(L, -1, LUA_TTABLE);
2736 lua_getfield(L, -1, "action");
2737 luaL_checktype(L, -1, LUA_TFUNCTION);
2739 pushnode(L, n, env->getGameDef()->ndef());
2740 lua_pushnumber(L, active_object_count);
2741 lua_pushnumber(L, active_object_count_wider);
2742 if(lua_pcall(L, 4, 0, 0))
2743 script_error(L, "error: %s", lua_tostring(L, -1));
2747 // register_abm({...})
2748 static int l_register_abm(lua_State *L)
2750 //infostream<<"register_abm"<<std::endl;
2751 luaL_checktype(L, 1, LUA_TTABLE);
2753 // Get minetest.registered_abms
2754 lua_getglobal(L, "minetest");
2755 lua_getfield(L, -1, "registered_abms");
2756 luaL_checktype(L, -1, LUA_TTABLE);
2757 int registered_abms = lua_gettop(L);
2762 lua_pushnumber(L, id);
2763 lua_gettable(L, registered_abms);
2764 if(lua_isnil(L, -1))
2771 infostream<<"register_abm: id="<<id<<std::endl;
2773 // registered_abms[id] = spec
2774 lua_pushnumber(L, id);
2775 lua_pushvalue(L, 1);
2776 lua_settable(L, registered_abms);
2778 return 0; /* number of results */
2781 // register_tool(name, {lots of stuff})
2782 static int l_register_tool(lua_State *L)
2784 std::string name = luaL_checkstring(L, 1);
2785 check_modname_prefix(L, name);
2786 //infostream<<"register_tool: "<<name<<std::endl;
2787 luaL_checktype(L, 2, LUA_TTABLE);
2790 // Get the writable tool definition manager from the server
2791 IWritableToolDefManager *tooldef =
2792 get_server(L)->getWritableToolDefManager();
2794 ToolDefinition def = read_tool_definition(L, table);
2796 tooldef->registerTool(name, def);
2797 return 0; /* number of results */
2800 // register_craftitem(name, {lots of stuff})
2801 static int l_register_craftitem(lua_State *L)
2803 std::string name = luaL_checkstring(L, 1);
2804 check_modname_prefix(L, name);
2805 //infostream<<"register_craftitem: "<<name<<std::endl;
2806 luaL_checktype(L, 2, LUA_TTABLE);
2809 // Get the writable CraftItem definition manager from the server
2810 IWritableCraftItemDefManager *craftitemdef =
2811 get_server(L)->getWritableCraftItemDefManager();
2813 // Check if on_drop is defined
2814 lua_getfield(L, table, "on_drop");
2815 bool got_on_drop = !lua_isnil(L, -1);
2818 // Check if on_use is defined
2819 lua_getfield(L, table, "on_use");
2820 bool got_on_use = !lua_isnil(L, -1);
2823 CraftItemDefinition def;
2825 getstringfield(L, table, "image", def.imagename);
2826 getstringfield(L, table, "cookresult_itemstring", def.cookresult_item);
2827 getfloatfield(L, table, "furnace_cooktime", def.furnace_cooktime);
2828 getfloatfield(L, table, "furnace_burntime", def.furnace_burntime);
2829 def.usable = getboolfield_default(L, table, "usable", got_on_use);
2830 getboolfield(L, table, "liquids_pointable", def.liquids_pointable);
2831 def.dropcount = getintfield_default(L, table, "dropcount", def.dropcount);
2832 def.stack_max = getintfield_default(L, table, "stack_max", def.stack_max);
2834 // If an on_drop callback is defined, force dropcount to 1
2839 craftitemdef->registerCraftItem(name, def);
2841 lua_pushvalue(L, table);
2842 scriptapi_add_craftitem(L, name.c_str());
2844 return 0; /* number of results */
2847 // register_node(name, {lots of stuff})
2848 static int l_register_node(lua_State *L)
2850 std::string name = luaL_checkstring(L, 1);
2851 check_modname_prefix(L, name);
2852 //infostream<<"register_node: "<<name<<std::endl;
2853 luaL_checktype(L, 2, LUA_TTABLE);
2854 int nodedef_table = 2;
2856 // Get the writable node definition manager from the server
2857 IWritableNodeDefManager *nodedef =
2858 get_server(L)->getWritableNodeDefManager();
2860 // Get default node definition from registry
2861 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
2862 int nodedef_default = lua_gettop(L);
2865 Add to minetest.registered_nodes with default as metatable
2868 // Get the node definition table given as parameter
2869 lua_pushvalue(L, nodedef_table);
2871 // Set __index to point to itself
2872 lua_pushvalue(L, -1);
2873 lua_setfield(L, -2, "__index");
2875 // Set nodedef_default as metatable for the definition
2876 lua_pushvalue(L, nodedef_default);
2877 lua_setmetatable(L, nodedef_table);
2879 // minetest.registered_nodes[name] = nodedef
2880 lua_getglobal(L, "minetest");
2881 lua_getfield(L, -1, "registered_nodes");
2882 luaL_checktype(L, -1, LUA_TTABLE);
2883 lua_pushstring(L, name.c_str());
2884 lua_pushvalue(L, nodedef_table);
2885 lua_settable(L, -3);
2893 // Default to getting the corresponding NodeItem when dug
2894 f.dug_item = std::string("NodeItem \"")+name+"\" 1";
2896 // Default to unknown_block.png as all textures
2897 f.setAllTextures("unknown_block.png");
2900 Read definiton from Lua
2905 /* Visual definition */
2907 f.drawtype = (NodeDrawType)getenumfield(L, nodedef_table, "drawtype", es_DrawType,
2909 getfloatfield(L, nodedef_table, "visual_scale", f.visual_scale);
2911 lua_getfield(L, nodedef_table, "tile_images");
2912 if(lua_istable(L, -1)){
2913 int table = lua_gettop(L);
2916 while(lua_next(L, table) != 0){
2917 // key at index -2 and value at index -1
2918 if(lua_isstring(L, -1))
2919 f.tname_tiles[i] = lua_tostring(L, -1);
2921 f.tname_tiles[i] = "";
2922 // removes value, keeps key for next iteration
2930 // Copy last value to all remaining textures
2932 std::string lastname = f.tname_tiles[i-1];
2934 f.tname_tiles[i] = lastname;
2941 getstringfield(L, nodedef_table, "inventory_image", f.tname_inventory);
2943 lua_getfield(L, nodedef_table, "special_materials");
2944 if(lua_istable(L, -1)){
2945 int table = lua_gettop(L);
2948 while(lua_next(L, table) != 0){
2949 // key at index -2 and value at index -1
2950 int smtable = lua_gettop(L);
2951 std::string tname = getstringfield_default(
2952 L, smtable, "image", "");
2953 bool backface_culling = getboolfield_default(
2954 L, smtable, "backface_culling", true);
2955 MaterialSpec mspec(tname, backface_culling);
2956 f.setSpecialMaterial(i, mspec);
2957 // removes value, keeps key for next iteration
2968 f.alpha = getintfield_default(L, nodedef_table, "alpha", 255);
2972 lua_getfield(L, nodedef_table, "post_effect_color");
2973 if(!lua_isnil(L, -1))
2974 f.post_effect_color = readARGB8(L, -1);
2977 f.param_type = (ContentParamType)getenumfield(L, nodedef_table, "paramtype",
2978 es_ContentParamType, CPT_NONE);
2980 // True for all ground-like things like stone and mud, false for eg. trees
2981 getboolfield(L, nodedef_table, "is_ground_content", f.is_ground_content);
2982 f.light_propagates = (f.param_type == CPT_LIGHT);
2983 warn_if_field_exists(L, nodedef_table, "light_propagates",
2984 "deprecated: determined from paramtype");
2985 getboolfield(L, nodedef_table, "sunlight_propagates", f.sunlight_propagates);
2986 // This is used for collision detection.
2987 // Also for general solidness queries.
2988 getboolfield(L, nodedef_table, "walkable", f.walkable);
2989 // Player can point to these
2990 getboolfield(L, nodedef_table, "pointable", f.pointable);
2991 // Player can dig these
2992 getboolfield(L, nodedef_table, "diggable", f.diggable);
2993 // Player can climb these
2994 getboolfield(L, nodedef_table, "climbable", f.climbable);
2995 // Player can build on these
2996 getboolfield(L, nodedef_table, "buildable_to", f.buildable_to);
2997 // If true, param2 is set to direction when placed. Used for torches.
2998 // NOTE: the direction format is quite inefficient and should be changed
2999 getboolfield(L, nodedef_table, "wall_mounted", f.wall_mounted);
3000 // Whether this content type often contains mineral.
3001 // Used for texture atlas creation.
3002 // Currently only enabled for CONTENT_STONE.
3003 getboolfield(L, nodedef_table, "often_contains_mineral", f.often_contains_mineral);
3004 // Inventory item string as which the node appears in inventory when dug.
3005 // Mineral overrides this.
3006 getstringfield(L, nodedef_table, "dug_item", f.dug_item);
3007 // Extra dug item and its rarity
3008 getstringfield(L, nodedef_table, "extra_dug_item", f.extra_dug_item);
3009 // Usual get interval for extra dug item
3010 getintfield(L, nodedef_table, "extra_dug_item_rarity", f.extra_dug_item_rarity);
3011 // Metadata name of node (eg. "furnace")
3012 getstringfield(L, nodedef_table, "metadata_name", f.metadata_name);
3013 // Whether the node is non-liquid, source liquid or flowing liquid
3014 f.liquid_type = (LiquidType)getenumfield(L, nodedef_table, "liquidtype",
3015 es_LiquidType, LIQUID_NONE);
3016 // If the content is liquid, this is the flowing version of the liquid.
3017 getstringfield(L, nodedef_table, "liquid_alternative_flowing",
3018 f.liquid_alternative_flowing);
3019 // If the content is liquid, this is the source version of the liquid.
3020 getstringfield(L, nodedef_table, "liquid_alternative_source",
3021 f.liquid_alternative_source);
3022 // Viscosity for fluid flow, ranging from 1 to 7, with
3023 // 1 giving almost instantaneous propagation and 7 being
3024 // the slowest possible
3025 f.liquid_viscosity = getintfield_default(L, nodedef_table,
3026 "liquid_viscosity", f.liquid_viscosity);
3027 // Amount of light the node emits
3028 f.light_source = getintfield_default(L, nodedef_table,
3029 "light_source", f.light_source);
3030 f.damage_per_second = getintfield_default(L, nodedef_table,
3031 "damage_per_second", f.damage_per_second);
3033 lua_getfield(L, nodedef_table, "selection_box");
3034 if(lua_istable(L, -1)){
3035 f.selection_box.type = (NodeBoxType)getenumfield(L, -1, "type",
3036 es_NodeBoxType, NODEBOX_REGULAR);
3038 lua_getfield(L, -1, "fixed");
3039 if(lua_istable(L, -1))
3040 f.selection_box.fixed = read_aabbox3df32(L, -1, BS);
3043 lua_getfield(L, -1, "wall_top");
3044 if(lua_istable(L, -1))
3045 f.selection_box.wall_top = read_aabbox3df32(L, -1, BS);
3048 lua_getfield(L, -1, "wall_bottom");
3049 if(lua_istable(L, -1))
3050 f.selection_box.wall_bottom = read_aabbox3df32(L, -1, BS);
3053 lua_getfield(L, -1, "wall_side");
3054 if(lua_istable(L, -1))
3055 f.selection_box.wall_side = read_aabbox3df32(L, -1, BS);
3060 lua_getfield(L, nodedef_table, "material");
3061 if(lua_istable(L, -1)){
3062 f.material.diggability = (Diggability)getenumfield(L, -1, "diggability",
3063 es_Diggability, DIGGABLE_NORMAL);
3065 getfloatfield(L, -1, "constant_time", f.material.constant_time);
3066 getfloatfield(L, -1, "weight", f.material.weight);
3067 getfloatfield(L, -1, "crackiness", f.material.crackiness);
3068 getfloatfield(L, -1, "crumbliness", f.material.crumbliness);
3069 getfloatfield(L, -1, "cuttability", f.material.cuttability);
3070 getfloatfield(L, -1, "flammability", f.material.flammability);
3074 getstringfield(L, nodedef_table, "cookresult_itemstring", f.cookresult_item);
3075 getfloatfield(L, nodedef_table, "furnace_cooktime", f.furnace_cooktime);
3076 getfloatfield(L, nodedef_table, "furnace_burntime", f.furnace_burntime);
3082 nodedef->set(name, f);
3084 return 0; /* number of results */
3087 // alias_node(name, convert_to_name)
3088 static int l_alias_node(lua_State *L)
3090 std::string name = luaL_checkstring(L, 1);
3091 std::string convert_to = luaL_checkstring(L, 2);
3093 // Get the writable node definition manager from the server
3094 IWritableNodeDefManager *nodedef =
3095 get_server(L)->getWritableNodeDefManager();
3097 nodedef->setAlias(name, convert_to);
3099 return 0; /* number of results */
3102 // alias_tool(name, convert_to_name)
3103 static int l_alias_tool(lua_State *L)
3105 std::string name = luaL_checkstring(L, 1);
3106 std::string convert_to = luaL_checkstring(L, 2);
3108 // Get the writable tool definition manager from the server
3109 IWritableToolDefManager *tooldef =
3110 get_server(L)->getWritableToolDefManager();
3112 tooldef->setAlias(name, convert_to);
3114 return 0; /* number of results */
3117 // alias_craftitem(name, convert_to_name)
3118 static int l_alias_craftitem(lua_State *L)
3120 std::string name = luaL_checkstring(L, 1);
3121 std::string convert_to = luaL_checkstring(L, 2);
3123 // Get the writable CraftItem definition manager from the server
3124 IWritableCraftItemDefManager *craftitemdef =
3125 get_server(L)->getWritableCraftItemDefManager();
3127 craftitemdef->setAlias(name, convert_to);
3129 return 0; /* number of results */
3132 // register_craft({output=item, recipe={{item00,item10},{item01,item11}})
3133 static int l_register_craft(lua_State *L)
3135 //infostream<<"register_craft"<<std::endl;
3136 luaL_checktype(L, 1, LUA_TTABLE);
3139 // Get the writable craft definition manager from the server
3140 IWritableCraftDefManager *craftdef =
3141 get_server(L)->getWritableCraftDefManager();
3145 std::vector<std::string> input;
3147 lua_getfield(L, table0, "output");
3148 luaL_checktype(L, -1, LUA_TSTRING);
3149 if(lua_isstring(L, -1))
3150 output = lua_tostring(L, -1);
3153 lua_getfield(L, table0, "recipe");
3154 luaL_checktype(L, -1, LUA_TTABLE);
3155 if(lua_istable(L, -1)){
3156 int table1 = lua_gettop(L);
3159 while(lua_next(L, table1) != 0){
3161 // key at index -2 and value at index -1
3162 luaL_checktype(L, -1, LUA_TTABLE);
3163 if(lua_istable(L, -1)){
3164 int table2 = lua_gettop(L);
3166 while(lua_next(L, table2) != 0){
3167 // key at index -2 and value at index -1
3168 luaL_checktype(L, -1, LUA_TSTRING);
3169 input.push_back(lua_tostring(L, -1));
3170 // removes value, keeps key for next iteration
3178 if(colcount != width){
3180 error += "Invalid crafting recipe (output=\""
3182 throw LuaError(L, error);
3185 // removes value, keeps key for next iteration
3192 CraftDefinition def(output, width, input);
3193 craftdef->registerCraft(def);
3195 return 0; /* number of results */
3198 // setting_get(name)
3199 static int l_setting_get(lua_State *L)
3201 const char *name = luaL_checkstring(L, 1);
3203 std::string value = g_settings->get(name);
3204 lua_pushstring(L, value.c_str());
3205 } catch(SettingNotFoundException &e){
3211 // setting_getbool(name)
3212 static int l_setting_getbool(lua_State *L)
3214 const char *name = luaL_checkstring(L, 1);
3216 bool value = g_settings->getBool(name);
3217 lua_pushboolean(L, value);
3218 } catch(SettingNotFoundException &e){
3224 // chat_send_all(text)
3225 static int l_chat_send_all(lua_State *L)
3227 const char *text = luaL_checkstring(L, 1);
3228 // Get server from registry
3229 Server *server = get_server(L);
3231 server->notifyPlayers(narrow_to_wide(text));
3235 // chat_send_player(name, text)
3236 static int l_chat_send_player(lua_State *L)
3238 const char *name = luaL_checkstring(L, 1);
3239 const char *text = luaL_checkstring(L, 2);
3240 // Get server from registry
3241 Server *server = get_server(L);
3243 server->notifyPlayer(name, narrow_to_wide(text));
3247 // get_player_privs(name, text)
3248 static int l_get_player_privs(lua_State *L)
3250 const char *name = luaL_checkstring(L, 1);
3251 // Get server from registry
3252 Server *server = get_server(L);
3255 int table = lua_gettop(L);
3256 u64 privs_i = server->getPlayerAuthPrivs(name);
3257 // Special case for the "name" setting (local player / server owner)
3258 if(name == g_settings->get("name"))
3260 std::set<std::string> privs_s = privsToSet(privs_i);
3261 for(std::set<std::string>::const_iterator
3262 i = privs_s.begin(); i != privs_s.end(); i++){
3263 lua_pushboolean(L, true);
3264 lua_setfield(L, table, i->c_str());
3266 lua_pushvalue(L, table);
3270 // get_inventory(location)
3271 static int l_get_inventory(lua_State *L)
3273 InventoryLocation loc;
3275 std::string type = checkstringfield(L, 1, "type");
3276 if(type == "player"){
3277 std::string name = checkstringfield(L, 1, "name");
3278 loc.setPlayer(name);
3279 } else if(type == "node"){
3280 lua_getfield(L, 1, "pos");
3281 v3s16 pos = check_v3s16(L, -1);
3282 loc.setNodeMeta(pos);
3285 if(get_server(L)->getInventory(loc) != NULL)
3286 InvRef::create(L, loc);
3292 // get_modpath(modname)
3293 static int l_get_modpath(lua_State *L)
3295 const char *modname = luaL_checkstring(L, 1);
3296 // Get server from registry
3297 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
3298 Server *server = (Server*)lua_touserdata(L, -1);
3300 const ModSpec *mod = server->getModSpec(modname);
3305 lua_pushstring(L, mod->path.c_str());
3309 static const struct luaL_Reg minetest_f [] = {
3310 {"register_nodedef_defaults", l_register_nodedef_defaults},
3311 {"register_entity", l_register_entity},
3312 {"register_tool", l_register_tool},
3313 {"register_craftitem", l_register_craftitem},
3314 {"register_node", l_register_node},
3315 {"register_craft", l_register_craft},
3316 {"register_abm", l_register_abm},
3317 {"alias_node", l_alias_node},
3318 {"alias_tool", l_alias_tool},
3319 {"alias_craftitem", l_alias_craftitem},
3320 {"setting_get", l_setting_get},
3321 {"setting_getbool", l_setting_getbool},
3322 {"chat_send_all", l_chat_send_all},
3323 {"chat_send_player", l_chat_send_player},
3324 {"get_player_privs", l_get_player_privs},
3325 {"get_inventory", l_get_inventory},
3326 {"get_modpath", l_get_modpath},
3334 static const struct luaL_Reg minetest_entity_m [] = {
3339 Main export function
3342 void scriptapi_export(lua_State *L, Server *server)
3345 assert(lua_checkstack(L, 20));
3346 infostream<<"scriptapi_export"<<std::endl;
3347 StackUnroller stack_unroller(L);
3349 // Store server as light userdata in registry
3350 lua_pushlightuserdata(L, server);
3351 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_server");
3353 // Store nil as minetest_nodedef_defaults in registry
3355 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
3357 // Register global functions in table minetest
3359 luaL_register(L, NULL, minetest_f);
3360 lua_setglobal(L, "minetest");
3362 // Get the main minetest table
3363 lua_getglobal(L, "minetest");
3365 // Add tables to minetest
3368 lua_setfield(L, -2, "registered_nodes");
3370 lua_setfield(L, -2, "registered_entities");
3372 lua_setfield(L, -2, "registered_craftitems");
3374 lua_setfield(L, -2, "registered_abms");
3377 lua_setfield(L, -2, "object_refs");
3379 lua_setfield(L, -2, "luaentities");
3381 // Create entity prototype
3382 luaL_newmetatable(L, "minetest.entity");
3383 // metatable.__index = metatable
3384 lua_pushvalue(L, -1); // Duplicate metatable
3385 lua_setfield(L, -2, "__index");
3386 // Put functions in metatable
3387 luaL_register(L, NULL, minetest_entity_m);
3388 // Put other stuff in metatable
3390 // Register wrappers
3391 ItemStack::Register(L);
3392 InvRef::Register(L);
3393 NodeMetaRef::Register(L);
3394 ObjectRef::Register(L);
3395 EnvRef::Register(L);
3398 bool scriptapi_loadmod(lua_State *L, const std::string &scriptpath,
3399 const std::string &modname)
3401 ModNameStorer modnamestorer(L, modname);
3403 if(!string_allowed(modname, "abcdefghijklmnopqrstuvwxyz"
3405 errorstream<<"Error loading mod \""<<modname
3406 <<"\": modname does not follow naming conventions: "
3407 <<"Only chararacters [a-z0-9_] are allowed."<<std::endl;
3411 bool success = false;
3414 success = script_load(L, scriptpath.c_str());
3417 errorstream<<"Error loading mod \""<<modname
3418 <<"\": "<<e.what()<<std::endl;
3424 void scriptapi_add_environment(lua_State *L, ServerEnvironment *env)
3427 assert(lua_checkstack(L, 20));
3428 infostream<<"scriptapi_add_environment"<<std::endl;
3429 StackUnroller stack_unroller(L);
3431 // Create EnvRef on stack
3432 EnvRef::create(L, env);
3433 int envref = lua_gettop(L);
3435 // minetest.env = envref
3436 lua_getglobal(L, "minetest");
3437 luaL_checktype(L, -1, LUA_TTABLE);
3438 lua_pushvalue(L, envref);
3439 lua_setfield(L, -2, "env");
3441 // Store environment as light userdata in registry
3442 lua_pushlightuserdata(L, env);
3443 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_env");
3446 Add ActiveBlockModifiers to environment
3449 // Get minetest.registered_abms
3450 lua_getglobal(L, "minetest");
3451 lua_getfield(L, -1, "registered_abms");
3452 luaL_checktype(L, -1, LUA_TTABLE);
3453 int registered_abms = lua_gettop(L);
3455 if(lua_istable(L, registered_abms)){
3456 int table = lua_gettop(L);
3458 while(lua_next(L, table) != 0){
3459 // key at index -2 and value at index -1
3460 int id = lua_tonumber(L, -2);
3461 int current_abm = lua_gettop(L);
3463 std::set<std::string> trigger_contents;
3464 lua_getfield(L, current_abm, "nodenames");
3465 if(lua_istable(L, -1)){
3466 int table = lua_gettop(L);
3468 while(lua_next(L, table) != 0){
3469 // key at index -2 and value at index -1
3470 luaL_checktype(L, -1, LUA_TSTRING);
3471 trigger_contents.insert(lua_tostring(L, -1));
3472 // removes value, keeps key for next iteration
3475 } else if(lua_isstring(L, -1)){
3476 trigger_contents.insert(lua_tostring(L, -1));
3480 std::set<std::string> required_neighbors;
3481 lua_getfield(L, current_abm, "neighbors");
3482 if(lua_istable(L, -1)){
3483 int table = lua_gettop(L);
3485 while(lua_next(L, table) != 0){
3486 // key at index -2 and value at index -1
3487 luaL_checktype(L, -1, LUA_TSTRING);
3488 required_neighbors.insert(lua_tostring(L, -1));
3489 // removes value, keeps key for next iteration
3492 } else if(lua_isstring(L, -1)){
3493 required_neighbors.insert(lua_tostring(L, -1));
3497 float trigger_interval = 10.0;
3498 getfloatfield(L, current_abm, "interval", trigger_interval);
3500 int trigger_chance = 50;
3501 getintfield(L, current_abm, "chance", trigger_chance);
3503 LuaABM *abm = new LuaABM(L, id, trigger_contents,
3504 required_neighbors, trigger_interval, trigger_chance);
3506 env->addActiveBlockModifier(abm);
3508 // removes value, keeps key for next iteration
3516 // Dump stack top with the dump2 function
3517 static void dump2(lua_State *L, const char *name)
3519 // Dump object (debug)
3520 lua_getglobal(L, "dump2");
3521 luaL_checktype(L, -1, LUA_TFUNCTION);
3522 lua_pushvalue(L, -2); // Get previous stack top as first parameter
3523 lua_pushstring(L, name);
3524 if(lua_pcall(L, 2, 0, 0))
3525 script_error(L, "error: %s", lua_tostring(L, -1));
3533 void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj)
3536 assert(lua_checkstack(L, 20));
3537 //infostream<<"scriptapi_add_object_reference: id="<<cobj->getId()<<std::endl;
3538 StackUnroller stack_unroller(L);
3540 // Create object on stack
3541 ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack
3542 int object = lua_gettop(L);
3544 // Get minetest.object_refs table
3545 lua_getglobal(L, "minetest");
3546 lua_getfield(L, -1, "object_refs");
3547 luaL_checktype(L, -1, LUA_TTABLE);
3548 int objectstable = lua_gettop(L);
3550 // object_refs[id] = object
3551 lua_pushnumber(L, cobj->getId()); // Push id
3552 lua_pushvalue(L, object); // Copy object to top of stack
3553 lua_settable(L, objectstable);
3556 void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj)
3559 assert(lua_checkstack(L, 20));
3560 //infostream<<"scriptapi_rm_object_reference: id="<<cobj->getId()<<std::endl;
3561 StackUnroller stack_unroller(L);
3563 // Get minetest.object_refs table
3564 lua_getglobal(L, "minetest");
3565 lua_getfield(L, -1, "object_refs");
3566 luaL_checktype(L, -1, LUA_TTABLE);
3567 int objectstable = lua_gettop(L);
3569 // Get object_refs[id]
3570 lua_pushnumber(L, cobj->getId()); // Push id
3571 lua_gettable(L, objectstable);
3572 // Set object reference to NULL
3573 ObjectRef::set_null(L);
3574 lua_pop(L, 1); // pop object
3576 // Set object_refs[id] = nil
3577 lua_pushnumber(L, cobj->getId()); // Push id
3579 lua_settable(L, objectstable);
3582 bool scriptapi_on_chat_message(lua_State *L, const std::string &name,
3583 const std::string &message)
3586 assert(lua_checkstack(L, 20));
3587 StackUnroller stack_unroller(L);
3589 // Get minetest.registered_on_chat_messages
3590 lua_getglobal(L, "minetest");
3591 lua_getfield(L, -1, "registered_on_chat_messages");
3592 luaL_checktype(L, -1, LUA_TTABLE);
3593 int table = lua_gettop(L);
3596 while(lua_next(L, table) != 0){
3597 // key at index -2 and value at index -1
3598 luaL_checktype(L, -1, LUA_TFUNCTION);
3600 lua_pushstring(L, name.c_str());
3601 lua_pushstring(L, message.c_str());
3602 if(lua_pcall(L, 2, 1, 0))
3603 script_error(L, "error: %s", lua_tostring(L, -1));
3604 bool ate = lua_toboolean(L, -1);
3608 // value removed, keep key for next iteration
3617 void scriptapi_on_newplayer(lua_State *L, ServerActiveObject *player)
3620 assert(lua_checkstack(L, 20));
3621 StackUnroller stack_unroller(L);
3623 // Get minetest.registered_on_newplayers
3624 lua_getglobal(L, "minetest");
3625 lua_getfield(L, -1, "registered_on_newplayers");
3626 luaL_checktype(L, -1, LUA_TTABLE);
3627 int table = lua_gettop(L);
3630 while(lua_next(L, table) != 0){
3631 // key at index -2 and value at index -1
3632 luaL_checktype(L, -1, LUA_TFUNCTION);
3634 objectref_get_or_create(L, player);
3635 if(lua_pcall(L, 1, 0, 0))
3636 script_error(L, "error: %s", lua_tostring(L, -1));
3637 // value removed, keep key for next iteration
3640 bool scriptapi_on_respawnplayer(lua_State *L, ServerActiveObject *player)
3643 assert(lua_checkstack(L, 20));
3644 StackUnroller stack_unroller(L);
3646 bool positioning_handled_by_some = false;
3648 // Get minetest.registered_on_respawnplayers
3649 lua_getglobal(L, "minetest");
3650 lua_getfield(L, -1, "registered_on_respawnplayers");
3651 luaL_checktype(L, -1, LUA_TTABLE);
3652 int table = lua_gettop(L);
3655 while(lua_next(L, table) != 0){
3656 // key at index -2 and value at index -1
3657 luaL_checktype(L, -1, LUA_TFUNCTION);
3659 objectref_get_or_create(L, player);
3660 if(lua_pcall(L, 1, 1, 0))
3661 script_error(L, "error: %s", lua_tostring(L, -1));
3662 bool positioning_handled = lua_toboolean(L, -1);
3664 if(positioning_handled)
3665 positioning_handled_by_some = true;
3666 // value removed, keep key for next iteration
3668 return positioning_handled_by_some;
3671 void scriptapi_get_creative_inventory(lua_State *L, ServerRemotePlayer *player)
3673 lua_getglobal(L, "minetest");
3674 lua_getfield(L, -1, "creative_inventory");
3675 luaL_checktype(L, -1, LUA_TTABLE);
3676 inventory_set_list_from_lua(&player->inventory, "main", L, -1,
3677 player->getEnv()->getGameDef(), PLAYER_INVENTORY_SIZE);
3684 static void pushPointedThing(lua_State *L, const PointedThing& pointed)
3687 if(pointed.type == POINTEDTHING_NODE)
3689 lua_pushstring(L, "node");
3690 lua_setfield(L, -2, "type");
3691 push_v3s16(L, pointed.node_undersurface);
3692 lua_setfield(L, -2, "under");
3693 push_v3s16(L, pointed.node_abovesurface);
3694 lua_setfield(L, -2, "above");
3696 else if(pointed.type == POINTEDTHING_OBJECT)
3698 lua_pushstring(L, "object");
3699 lua_setfield(L, -2, "type");
3700 objectref_get(L, pointed.object_id);
3701 lua_setfield(L, -2, "ref");
3705 lua_pushstring(L, "nothing");
3706 lua_setfield(L, -2, "type");
3710 void scriptapi_add_craftitem(lua_State *L, const char *name)
3712 StackUnroller stack_unroller(L);
3713 assert(lua_gettop(L) > 0);
3715 // Set minetest.registered_craftitems[name] = table on top of stack
3716 lua_getglobal(L, "minetest");
3717 lua_getfield(L, -1, "registered_craftitems");
3718 luaL_checktype(L, -1, LUA_TTABLE);
3719 lua_pushvalue(L, -3); // push another reference to the table to be registered
3720 lua_setfield(L, -2, name); // set minetest.registered_craftitems[name]
3723 static bool get_craftitem_callback(lua_State *L, const char *name,
3724 const char *callbackname)
3726 // Get minetest.registered_craftitems[name][callbackname]
3727 // If that is nil or on error, return false and stack is unchanged
3728 // If that is a function, returns true and pushes the
3729 // function onto the stack
3731 lua_getglobal(L, "minetest");
3732 lua_getfield(L, -1, "registered_craftitems");
3734 luaL_checktype(L, -1, LUA_TTABLE);
3735 lua_getfield(L, -1, name);
3737 // Should be a table
3738 if(lua_type(L, -1) != LUA_TTABLE)
3740 errorstream<<"CraftItem name \""<<name<<"\" not defined"<<std::endl;
3744 lua_getfield(L, -1, callbackname);
3746 // Should be a function or nil
3747 if(lua_type(L, -1) == LUA_TFUNCTION)
3751 else if(lua_isnil(L, -1))
3758 errorstream<<"CraftItem name \""<<name<<"\" callback \""
3759 <<callbackname<<" is not a function"<<std::endl;
3765 bool scriptapi_craftitem_on_drop(lua_State *L, const char *name,
3766 ServerActiveObject *dropper, v3f pos,
3767 bool &callback_exists)
3770 assert(lua_checkstack(L, 20));
3771 //infostream<<"scriptapi_craftitem_on_drop"<<std::endl;
3772 StackUnroller stack_unroller(L);
3774 bool result = false;
3775 callback_exists = get_craftitem_callback(L, name, "on_drop");
3779 lua_pushstring(L, name);
3780 objectref_get_or_create(L, dropper);
3781 pushFloatPos(L, pos);
3782 if(lua_pcall(L, 3, 1, 0))
3783 script_error(L, "error: %s", lua_tostring(L, -1));
3784 result = lua_toboolean(L, -1);
3789 bool scriptapi_craftitem_on_place_on_ground(lua_State *L, const char *name,
3790 ServerActiveObject *placer, v3f pos,
3791 bool &callback_exists)
3794 assert(lua_checkstack(L, 20));
3795 //infostream<<"scriptapi_craftitem_on_place_on_ground"<<std::endl;
3796 StackUnroller stack_unroller(L);
3798 bool result = false;
3799 callback_exists = get_craftitem_callback(L, name, "on_place_on_ground");
3803 lua_pushstring(L, name);
3804 objectref_get_or_create(L, placer);
3805 pushFloatPos(L, pos);
3806 if(lua_pcall(L, 3, 1, 0))
3807 script_error(L, "error: %s", lua_tostring(L, -1));
3808 result = lua_toboolean(L, -1);
3813 bool scriptapi_craftitem_on_use(lua_State *L, const char *name,
3814 ServerActiveObject *user, const PointedThing& pointed,
3815 bool &callback_exists)
3818 assert(lua_checkstack(L, 20));
3819 //infostream<<"scriptapi_craftitem_on_use"<<std::endl;
3820 StackUnroller stack_unroller(L);
3822 bool result = false;
3823 callback_exists = get_craftitem_callback(L, name, "on_use");
3827 lua_pushstring(L, name);
3828 objectref_get_or_create(L, user);
3829 pushPointedThing(L, pointed);
3830 if(lua_pcall(L, 3, 1, 0))
3831 script_error(L, "error: %s", lua_tostring(L, -1));
3832 result = lua_toboolean(L, -1);
3841 void scriptapi_environment_step(lua_State *L, float dtime)
3844 assert(lua_checkstack(L, 20));
3845 //infostream<<"scriptapi_environment_step"<<std::endl;
3846 StackUnroller stack_unroller(L);
3848 // Get minetest.registered_globalsteps
3849 lua_getglobal(L, "minetest");
3850 lua_getfield(L, -1, "registered_globalsteps");
3851 luaL_checktype(L, -1, LUA_TTABLE);
3852 int table = lua_gettop(L);
3855 while(lua_next(L, table) != 0){
3856 // key at index -2 and value at index -1
3857 luaL_checktype(L, -1, LUA_TFUNCTION);
3859 lua_pushnumber(L, dtime);
3860 if(lua_pcall(L, 1, 0, 0))
3861 script_error(L, "error: %s", lua_tostring(L, -1));
3862 // value removed, keep key for next iteration
3866 void scriptapi_environment_on_placenode(lua_State *L, v3s16 p, MapNode newnode,
3867 ServerActiveObject *placer)
3870 assert(lua_checkstack(L, 20));
3871 //infostream<<"scriptapi_environment_on_placenode"<<std::endl;
3872 StackUnroller stack_unroller(L);
3874 // Get the writable node definition manager from the server
3875 IWritableNodeDefManager *ndef =
3876 get_server(L)->getWritableNodeDefManager();
3878 // Get minetest.registered_on_placenodes
3879 lua_getglobal(L, "minetest");
3880 lua_getfield(L, -1, "registered_on_placenodes");
3881 luaL_checktype(L, -1, LUA_TTABLE);
3882 int table = lua_gettop(L);
3885 while(lua_next(L, table) != 0){
3886 // key at index -2 and value at index -1
3887 luaL_checktype(L, -1, LUA_TFUNCTION);
3890 pushnode(L, newnode, ndef);
3891 objectref_get_or_create(L, placer);
3892 if(lua_pcall(L, 3, 0, 0))
3893 script_error(L, "error: %s", lua_tostring(L, -1));
3894 // value removed, keep key for next iteration
3898 void scriptapi_environment_on_dignode(lua_State *L, v3s16 p, MapNode oldnode,
3899 ServerActiveObject *digger)
3902 assert(lua_checkstack(L, 20));
3903 //infostream<<"scriptapi_environment_on_dignode"<<std::endl;
3904 StackUnroller stack_unroller(L);
3906 // Get the writable node definition manager from the server
3907 IWritableNodeDefManager *ndef =
3908 get_server(L)->getWritableNodeDefManager();
3910 // Get minetest.registered_on_dignodes
3911 lua_getglobal(L, "minetest");
3912 lua_getfield(L, -1, "registered_on_dignodes");
3913 luaL_checktype(L, -1, LUA_TTABLE);
3914 int table = lua_gettop(L);
3917 while(lua_next(L, table) != 0){
3918 // key at index -2 and value at index -1
3919 luaL_checktype(L, -1, LUA_TFUNCTION);
3922 pushnode(L, oldnode, ndef);
3923 objectref_get_or_create(L, digger);
3924 if(lua_pcall(L, 3, 0, 0))
3925 script_error(L, "error: %s", lua_tostring(L, -1));
3926 // value removed, keep key for next iteration
3930 void scriptapi_environment_on_punchnode(lua_State *L, v3s16 p, MapNode node,
3931 ServerActiveObject *puncher)
3934 assert(lua_checkstack(L, 20));
3935 //infostream<<"scriptapi_environment_on_punchnode"<<std::endl;
3936 StackUnroller stack_unroller(L);
3938 // Get the writable node definition manager from the server
3939 IWritableNodeDefManager *ndef =
3940 get_server(L)->getWritableNodeDefManager();
3942 // Get minetest.registered_on_punchnodes
3943 lua_getglobal(L, "minetest");
3944 lua_getfield(L, -1, "registered_on_punchnodes");
3945 luaL_checktype(L, -1, LUA_TTABLE);
3946 int table = lua_gettop(L);
3949 while(lua_next(L, table) != 0){
3950 // key at index -2 and value at index -1
3951 luaL_checktype(L, -1, LUA_TFUNCTION);
3954 pushnode(L, node, ndef);
3955 objectref_get_or_create(L, puncher);
3956 if(lua_pcall(L, 3, 0, 0))
3957 script_error(L, "error: %s", lua_tostring(L, -1));
3958 // value removed, keep key for next iteration
3962 void scriptapi_environment_on_generated(lua_State *L, v3s16 minp, v3s16 maxp)
3965 assert(lua_checkstack(L, 20));
3966 //infostream<<"scriptapi_environment_on_generated"<<std::endl;
3967 StackUnroller stack_unroller(L);
3969 // Get minetest.registered_on_generateds
3970 lua_getglobal(L, "minetest");
3971 lua_getfield(L, -1, "registered_on_generateds");
3972 luaL_checktype(L, -1, LUA_TTABLE);
3973 int table = lua_gettop(L);
3976 while(lua_next(L, table) != 0){
3977 // key at index -2 and value at index -1
3978 luaL_checktype(L, -1, LUA_TFUNCTION);
3980 push_v3s16(L, minp);
3981 push_v3s16(L, maxp);
3982 if(lua_pcall(L, 2, 0, 0))
3983 script_error(L, "error: %s", lua_tostring(L, -1));
3984 // value removed, keep key for next iteration
3992 bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
3993 const std::string &staticdata)
3996 assert(lua_checkstack(L, 20));
3997 infostream<<"scriptapi_luaentity_add: id="<<id<<" name=\""
3998 <<name<<"\""<<std::endl;
3999 StackUnroller stack_unroller(L);
4001 // Get minetest.registered_entities[name]
4002 lua_getglobal(L, "minetest");
4003 lua_getfield(L, -1, "registered_entities");
4004 luaL_checktype(L, -1, LUA_TTABLE);
4005 lua_pushstring(L, name);
4006 lua_gettable(L, -2);
4007 // Should be a table, which we will use as a prototype
4008 //luaL_checktype(L, -1, LUA_TTABLE);
4009 if(lua_type(L, -1) != LUA_TTABLE){
4010 errorstream<<"LuaEntity name \""<<name<<"\" not defined"<<std::endl;
4013 int prototype_table = lua_gettop(L);
4014 //dump2(L, "prototype_table");
4016 // Create entity object
4018 int object = lua_gettop(L);
4020 // Set object metatable
4021 lua_pushvalue(L, prototype_table);
4022 lua_setmetatable(L, -2);
4024 // Add object reference
4025 // This should be userdata with metatable ObjectRef
4026 objectref_get(L, id);
4027 luaL_checktype(L, -1, LUA_TUSERDATA);
4028 if(!luaL_checkudata(L, -1, "ObjectRef"))
4029 luaL_typerror(L, -1, "ObjectRef");
4030 lua_setfield(L, -2, "object");
4032 // minetest.luaentities[id] = object
4033 lua_getglobal(L, "minetest");
4034 lua_getfield(L, -1, "luaentities");
4035 luaL_checktype(L, -1, LUA_TTABLE);
4036 lua_pushnumber(L, id); // Push id
4037 lua_pushvalue(L, object); // Copy object to top of stack
4038 lua_settable(L, -3);
4040 // Get on_activate function
4041 lua_pushvalue(L, object);
4042 lua_getfield(L, -1, "on_activate");
4043 if(!lua_isnil(L, -1)){
4044 luaL_checktype(L, -1, LUA_TFUNCTION);
4045 lua_pushvalue(L, object); // self
4046 lua_pushlstring(L, staticdata.c_str(), staticdata.size());
4047 // Call with 2 arguments, 0 results
4048 if(lua_pcall(L, 2, 0, 0))
4049 script_error(L, "error running function %s:on_activate: %s\n",
4050 name, lua_tostring(L, -1));
4056 void scriptapi_luaentity_rm(lua_State *L, u16 id)
4059 assert(lua_checkstack(L, 20));
4060 infostream<<"scriptapi_luaentity_rm: id="<<id<<std::endl;
4062 // Get minetest.luaentities table
4063 lua_getglobal(L, "minetest");
4064 lua_getfield(L, -1, "luaentities");
4065 luaL_checktype(L, -1, LUA_TTABLE);
4066 int objectstable = lua_gettop(L);
4068 // Set luaentities[id] = nil
4069 lua_pushnumber(L, id); // Push id
4071 lua_settable(L, objectstable);
4073 lua_pop(L, 2); // pop luaentities, minetest
4076 std::string scriptapi_luaentity_get_staticdata(lua_State *L, u16 id)
4079 assert(lua_checkstack(L, 20));
4080 infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl;
4081 StackUnroller stack_unroller(L);
4083 // Get minetest.luaentities[id]
4084 luaentity_get(L, id);
4085 int object = lua_gettop(L);
4087 // Get get_staticdata function
4088 lua_pushvalue(L, object);
4089 lua_getfield(L, -1, "get_staticdata");
4090 if(lua_isnil(L, -1))
4093 luaL_checktype(L, -1, LUA_TFUNCTION);
4094 lua_pushvalue(L, object); // self
4095 // Call with 1 arguments, 1 results
4096 if(lua_pcall(L, 1, 1, 0))
4097 script_error(L, "error running function get_staticdata: %s\n",
4098 lua_tostring(L, -1));
4101 const char *s = lua_tolstring(L, -1, &len);
4102 return std::string(s, len);
4105 void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
4106 LuaEntityProperties *prop)
4109 assert(lua_checkstack(L, 20));
4110 infostream<<"scriptapi_luaentity_get_properties: id="<<id<<std::endl;
4111 StackUnroller stack_unroller(L);
4113 // Get minetest.luaentities[id]
4114 luaentity_get(L, id);
4115 //int object = lua_gettop(L);
4119 getboolfield(L, -1, "physical", prop->physical);
4121 getfloatfield(L, -1, "weight", prop->weight);
4123 lua_getfield(L, -1, "collisionbox");
4124 if(lua_istable(L, -1))
4125 prop->collisionbox = read_aabbox3df32(L, -1, 1.0);
4128 getstringfield(L, -1, "visual", prop->visual);
4130 lua_getfield(L, -1, "visual_size");
4131 if(lua_istable(L, -1))
4132 prop->visual_size = read_v2f(L, -1);
4135 lua_getfield(L, -1, "textures");
4136 if(lua_istable(L, -1)){
4137 prop->textures.clear();
4138 int table = lua_gettop(L);
4140 while(lua_next(L, table) != 0){
4141 // key at index -2 and value at index -1
4142 if(lua_isstring(L, -1))
4143 prop->textures.push_back(lua_tostring(L, -1));
4145 prop->textures.push_back("");
4146 // removes value, keeps key for next iteration
4152 lua_getfield(L, -1, "spritediv");
4153 if(lua_istable(L, -1))
4154 prop->spritediv = read_v2s16(L, -1);
4157 lua_getfield(L, -1, "initial_sprite_basepos");
4158 if(lua_istable(L, -1))
4159 prop->initial_sprite_basepos = read_v2s16(L, -1);
4163 void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime)
4166 assert(lua_checkstack(L, 20));
4167 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
4168 StackUnroller stack_unroller(L);
4170 // Get minetest.luaentities[id]
4171 luaentity_get(L, id);
4172 int object = lua_gettop(L);
4173 // State: object is at top of stack
4174 // Get step function
4175 lua_getfield(L, -1, "on_step");
4176 if(lua_isnil(L, -1))
4178 luaL_checktype(L, -1, LUA_TFUNCTION);
4179 lua_pushvalue(L, object); // self
4180 lua_pushnumber(L, dtime); // dtime
4181 // Call with 2 arguments, 0 results
4182 if(lua_pcall(L, 2, 0, 0))
4183 script_error(L, "error running function 'on_step': %s\n", lua_tostring(L, -1));
4186 // Calls entity:on_punch(ObjectRef puncher, time_from_last_punch)
4187 void scriptapi_luaentity_punch(lua_State *L, u16 id,
4188 ServerActiveObject *puncher, float time_from_last_punch)
4191 assert(lua_checkstack(L, 20));
4192 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
4193 StackUnroller stack_unroller(L);
4195 // Get minetest.luaentities[id]
4196 luaentity_get(L, id);
4197 int object = lua_gettop(L);
4198 // State: object is at top of stack
4200 lua_getfield(L, -1, "on_punch");
4201 if(lua_isnil(L, -1))
4203 luaL_checktype(L, -1, LUA_TFUNCTION);
4204 lua_pushvalue(L, object); // self
4205 objectref_get_or_create(L, puncher); // Clicker reference
4206 lua_pushnumber(L, time_from_last_punch);
4207 // Call with 2 arguments, 0 results
4208 if(lua_pcall(L, 3, 0, 0))
4209 script_error(L, "error running function 'on_punch': %s\n", lua_tostring(L, -1));
4212 // Calls entity:on_rightclick(ObjectRef clicker)
4213 void scriptapi_luaentity_rightclick(lua_State *L, u16 id,
4214 ServerActiveObject *clicker)
4217 assert(lua_checkstack(L, 20));
4218 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
4219 StackUnroller stack_unroller(L);
4221 // Get minetest.luaentities[id]
4222 luaentity_get(L, id);
4223 int object = lua_gettop(L);
4224 // State: object is at top of stack
4226 lua_getfield(L, -1, "on_rightclick");
4227 if(lua_isnil(L, -1))
4229 luaL_checktype(L, -1, LUA_TFUNCTION);
4230 lua_pushvalue(L, object); // self
4231 objectref_get_or_create(L, clicker); // Clicker reference
4232 // Call with 2 arguments, 0 results
4233 if(lua_pcall(L, 2, 0, 0))
4234 script_error(L, "error running function 'on_rightclick': %s\n", lua_tostring(L, -1));