3 Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "scriptapi.h"
34 #include "serverobject.h"
37 #include "luaentity_common.h"
38 #include "content_sao.h" // For LuaEntitySAO
42 #include "craftitemdef.h"
43 #include "main.h" // For g_settings
44 #include "settings.h" // For accessing g_settings
45 #include "nodemetadata.h"
46 #include "mapblock.h" // For getNodeBlockPos
47 #include "content_nodemeta.h"
50 static void stackDump(lua_State *L, std::ostream &o)
53 int top = lua_gettop(L);
54 for (i = 1; i <= top; i++) { /* repeat for each level */
55 int t = lua_type(L, i);
58 case LUA_TSTRING: /* strings */
59 o<<"\""<<lua_tostring(L, i)<<"\"";
62 case LUA_TBOOLEAN: /* booleans */
63 o<<(lua_toboolean(L, i) ? "true" : "false");
66 case LUA_TNUMBER: /* numbers */ {
68 snprintf(buf, 10, "%g", lua_tonumber(L, i));
72 default: /* other values */
73 o<<lua_typename(L, t);
82 static void realitycheck(lua_State *L)
84 int top = lua_gettop(L);
86 dstream<<"Stack is over 30:"<<std::endl;
87 stackDump(L, dstream);
88 script_error(L, "Stack is over 30 (reality check)");
98 StackUnroller(lua_State *L):
102 m_original_top = lua_gettop(m_lua); // store stack height
106 lua_settop(m_lua, m_original_top); // restore stack height
115 ModNameStorer(lua_State *L_, const std::string modname):
118 // Store current modname in registry
119 lua_pushstring(L, modname.c_str());
120 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
124 // Clear current modname in registry
126 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
130 std::string get_current_modname(lua_State *L)
132 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
133 std::string modname = "";
134 if(lua_type(L, -1) == LUA_TSTRING)
135 modname = lua_tostring(L, -1);
140 void check_modname_prefix(lua_State *L, std::string &name)
143 throw LuaError(L, std::string("Name is empty"));
146 name = name.substr(1);
150 std::string modname = get_current_modname(L);
151 assert(modname != "");
153 // For __builtin, anything goes
154 if(modname == "__builtin")
157 if(name.substr(0, modname.size()+1) != modname + ":")
158 throw LuaError(L, std::string("Name \"")+name
159 +"\" does not follow naming conventions: "
160 +"\"modname:\" or \":\" prefix required)");
162 std::string subname = name.substr(modname.size()+1);
163 if(!string_allowed(subname, "abcdefghijklmnopqrstuvwxyz"
164 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"))
165 throw LuaError(L, std::string("Name \"")+name
166 +"\" does not follow naming conventions: "
167 +"\"contains unallowed characters");
170 static void push_v3f(lua_State *L, v3f p)
173 lua_pushnumber(L, p.X);
174 lua_setfield(L, -2, "x");
175 lua_pushnumber(L, p.Y);
176 lua_setfield(L, -2, "y");
177 lua_pushnumber(L, p.Z);
178 lua_setfield(L, -2, "z");
181 static v2s16 read_v2s16(lua_State *L, int index)
184 luaL_checktype(L, index, LUA_TTABLE);
185 lua_getfield(L, index, "x");
186 p.X = lua_tonumber(L, -1);
188 lua_getfield(L, index, "y");
189 p.Y = lua_tonumber(L, -1);
194 static v2f read_v2f(lua_State *L, int index)
197 luaL_checktype(L, index, LUA_TTABLE);
198 lua_getfield(L, index, "x");
199 p.X = lua_tonumber(L, -1);
201 lua_getfield(L, index, "y");
202 p.Y = lua_tonumber(L, -1);
207 static Server* get_server(lua_State *L)
209 // Get server from registry
210 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
211 return (Server*)lua_touserdata(L, -1);
214 static ServerEnvironment* get_env(lua_State *L)
216 // Get environment from registry
217 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_env");
218 return (ServerEnvironment*)lua_touserdata(L, -1);
221 static v3f read_v3f(lua_State *L, int index)
224 luaL_checktype(L, index, LUA_TTABLE);
225 lua_getfield(L, index, "x");
226 pos.X = lua_tonumber(L, -1);
228 lua_getfield(L, index, "y");
229 pos.Y = lua_tonumber(L, -1);
231 lua_getfield(L, index, "z");
232 pos.Z = lua_tonumber(L, -1);
237 static v3f check_v3f(lua_State *L, int index)
240 luaL_checktype(L, index, LUA_TTABLE);
241 lua_getfield(L, index, "x");
242 pos.X = luaL_checknumber(L, -1);
244 lua_getfield(L, index, "y");
245 pos.Y = luaL_checknumber(L, -1);
247 lua_getfield(L, index, "z");
248 pos.Z = luaL_checknumber(L, -1);
253 static void pushFloatPos(lua_State *L, v3f p)
259 static v3f checkFloatPos(lua_State *L, int index)
261 return check_v3f(L, index) * BS;
264 static void push_v3s16(lua_State *L, v3s16 p)
267 lua_pushnumber(L, p.X);
268 lua_setfield(L, -2, "x");
269 lua_pushnumber(L, p.Y);
270 lua_setfield(L, -2, "y");
271 lua_pushnumber(L, p.Z);
272 lua_setfield(L, -2, "z");
275 static v3s16 read_v3s16(lua_State *L, int index)
277 // Correct rounding at <0
278 v3f pf = read_v3f(L, index);
279 return floatToInt(pf, 1.0);
282 static v3s16 check_v3s16(lua_State *L, int index)
284 // Correct rounding at <0
285 v3f pf = check_v3f(L, index);
286 return floatToInt(pf, 1.0);
289 static void pushnode(lua_State *L, const MapNode &n, INodeDefManager *ndef)
292 lua_pushstring(L, ndef->get(n).name.c_str());
293 lua_setfield(L, -2, "name");
294 lua_pushnumber(L, n.getParam1());
295 lua_setfield(L, -2, "param1");
296 lua_pushnumber(L, n.getParam2());
297 lua_setfield(L, -2, "param2");
300 static MapNode readnode(lua_State *L, int index, INodeDefManager *ndef)
302 lua_getfield(L, index, "name");
303 const char *name = luaL_checkstring(L, -1);
306 lua_getfield(L, index, "param1");
310 param1 = lua_tonumber(L, -1);
313 lua_getfield(L, index, "param2");
317 param2 = lua_tonumber(L, -1);
319 return MapNode(ndef, name, param1, param2);
322 static video::SColor readARGB8(lua_State *L, int index)
325 luaL_checktype(L, index, LUA_TTABLE);
326 lua_getfield(L, index, "a");
327 if(lua_isnumber(L, -1))
328 color.setAlpha(lua_tonumber(L, -1));
330 lua_getfield(L, index, "r");
331 color.setRed(lua_tonumber(L, -1));
333 lua_getfield(L, index, "g");
334 color.setGreen(lua_tonumber(L, -1));
336 lua_getfield(L, index, "b");
337 color.setBlue(lua_tonumber(L, -1));
342 static core::aabbox3d<f32> read_aabbox3df32(lua_State *L, int index, f32 scale)
344 core::aabbox3d<f32> box;
345 if(lua_istable(L, -1)){
346 lua_rawgeti(L, -1, 1);
347 box.MinEdge.X = lua_tonumber(L, -1) * scale;
349 lua_rawgeti(L, -1, 2);
350 box.MinEdge.Y = lua_tonumber(L, -1) * scale;
352 lua_rawgeti(L, -1, 3);
353 box.MinEdge.Z = lua_tonumber(L, -1) * scale;
355 lua_rawgeti(L, -1, 4);
356 box.MaxEdge.X = lua_tonumber(L, -1) * scale;
358 lua_rawgeti(L, -1, 5);
359 box.MaxEdge.Y = lua_tonumber(L, -1) * scale;
361 lua_rawgeti(L, -1, 6);
362 box.MaxEdge.Z = lua_tonumber(L, -1) * scale;
368 static bool getstringfield(lua_State *L, int table,
369 const char *fieldname, std::string &result)
371 lua_getfield(L, table, fieldname);
373 if(lua_isstring(L, -1)){
374 result = lua_tostring(L, -1);
381 static bool getintfield(lua_State *L, int table,
382 const char *fieldname, int &result)
384 lua_getfield(L, table, fieldname);
386 if(lua_isnumber(L, -1)){
387 result = lua_tonumber(L, -1);
394 static bool getfloatfield(lua_State *L, int table,
395 const char *fieldname, float &result)
397 lua_getfield(L, table, fieldname);
399 if(lua_isnumber(L, -1)){
400 result = lua_tonumber(L, -1);
407 static bool getboolfield(lua_State *L, int table,
408 const char *fieldname, bool &result)
410 lua_getfield(L, table, fieldname);
412 if(lua_isboolean(L, -1)){
413 result = lua_toboolean(L, -1);
420 static std::string checkstringfield(lua_State *L, int table,
421 const char *fieldname)
423 lua_getfield(L, table, fieldname);
424 std::string s = luaL_checkstring(L, -1);
429 static std::string getstringfield_default(lua_State *L, int table,
430 const char *fieldname, const std::string &default_)
432 std::string result = default_;
433 getstringfield(L, table, fieldname, result);
437 static int getintfield_default(lua_State *L, int table,
438 const char *fieldname, int default_)
440 int result = default_;
441 getintfield(L, table, fieldname, result);
445 /*static float getfloatfield_default(lua_State *L, int table,
446 const char *fieldname, float default_)
448 float result = default_;
449 getfloatfield(L, table, fieldname, result);
453 static bool getboolfield_default(lua_State *L, int table,
454 const char *fieldname, bool default_)
456 bool result = default_;
457 getboolfield(L, table, fieldname, result);
467 static bool string_to_enum(const EnumString *spec, int &result,
468 const std::string &str)
470 const EnumString *esp = spec;
472 if(str == std::string(esp->str)){
481 /*static bool enum_to_string(const EnumString *spec, std::string &result,
484 const EnumString *esp = spec;
495 static int getenumfield(lua_State *L, int table,
496 const char *fieldname, const EnumString *spec, int default_)
498 int result = default_;
499 string_to_enum(spec, result,
500 getstringfield_default(L, table, fieldname, ""));
504 static void setfloatfield(lua_State *L, int table,
505 const char *fieldname, float value)
507 lua_pushnumber(L, value);
510 lua_setfield(L, table, fieldname);
513 static void warn_if_field_exists(lua_State *L, int table,
514 const char *fieldname, const std::string &message)
516 lua_getfield(L, table, fieldname);
517 if(!lua_isnil(L, -1)){
518 infostream<<script_get_backtrace(L)<<std::endl;
519 infostream<<"WARNING: field \""<<fieldname<<"\": "
520 <<message<<std::endl;
529 static void inventory_set_list_from_lua(Inventory *inv, const char *name,
530 lua_State *L, int tableindex, IGameDef *gamedef, int forcesize=-1)
533 tableindex = lua_gettop(L) + 1 + tableindex;
534 // If nil, delete list
535 if(lua_isnil(L, tableindex)){
536 inv->deleteList(name);
539 // Otherwise set list
540 std::list<std::string> items;
541 luaL_checktype(L, tableindex, LUA_TTABLE);
542 int table = tableindex;
544 while(lua_next(L, table) != 0){
545 // key at index -2 and value at index -1
546 luaL_checktype(L, -1, LUA_TSTRING);
547 std::string itemstring = luaL_checkstring(L, -1);
548 items.push_back(itemstring);
549 // removes value, keeps key for next iteration
552 int listsize = (forcesize != -1) ? forcesize : items.size();
553 InventoryList *invlist = inv->addList(name, listsize);
555 for(std::list<std::string>::const_iterator
556 i = items.begin(); i != items.end(); i++){
557 if(forcesize != -1 && index == forcesize)
559 const std::string &itemstring = *i;
560 InventoryItem *newitem = NULL;
562 newitem = InventoryItem::deSerialize(itemstring,
564 InventoryItem *olditem = invlist->changeItem(index, newitem);
568 while(forcesize != -1 && index < forcesize){
569 InventoryItem *olditem = invlist->changeItem(index, NULL);
575 static void inventory_get_list_to_lua(Inventory *inv, const char *name,
578 InventoryList *invlist = inv->getList(name);
583 // Get the table insert function
584 lua_getglobal(L, "table");
585 lua_getfield(L, -1, "insert");
586 int table_insert = lua_gettop(L);
587 // Create and fill table
589 int table = lua_gettop(L);
590 for(u32 i=0; i<invlist->getSize(); i++){
591 InventoryItem *item = invlist->getItem(i);
592 lua_pushvalue(L, table_insert);
593 lua_pushvalue(L, table);
595 lua_pushstring(L, "");
597 lua_pushstring(L, item->getItemString().c_str());
599 if(lua_pcall(L, 2, 0, 0))
600 script_error(L, "error: %s", lua_tostring(L, -1));
604 static void push_stack_item(lua_State *L, InventoryItem *item0)
609 else if(std::string("MaterialItem") == item0->getName()){
610 MaterialItem *item = (MaterialItem*)item0;
612 lua_pushstring(L, "node");
613 lua_setfield(L, -2, "type");
614 lua_pushstring(L, item->getNodeName().c_str());
615 lua_setfield(L, -2, "name");
617 else if(std::string("CraftItem") == item0->getName()){
618 CraftItem *item = (CraftItem*)item0;
620 lua_pushstring(L, "craft");
621 lua_setfield(L, -2, "type");
622 lua_pushstring(L, item->getSubName().c_str());
623 lua_setfield(L, -2, "name");
625 else if(std::string("ToolItem") == item0->getName()){
626 ToolItem *item = (ToolItem*)item0;
628 lua_pushstring(L, "tool");
629 lua_setfield(L, -2, "type");
630 lua_pushstring(L, item->getToolName().c_str());
631 lua_setfield(L, -2, "name");
632 lua_pushstring(L, itos(item->getWear()).c_str());
633 lua_setfield(L, -2, "wear");
636 errorstream<<"push_stack_item: Unknown item name: \""
637 <<item0->getName()<<"\""<<std::endl;
642 static InventoryItem* check_stack_item(lua_State *L, int index)
645 index = lua_gettop(L) + 1 + index;
646 if(lua_isnil(L, index))
648 if(!lua_istable(L, index))
649 throw LuaError(L, "check_stack_item: Item not nil or table");
650 // A very crappy implementation for now
651 // Will be replaced when unified namespace for items is made
652 std::string type = getstringfield_default(L, index, "type", "");
653 std::string name = getstringfield_default(L, index, "name", "");
654 std::string num = getstringfield_default(L, index, "wear", "_");
657 std::string itemstring = type + " \"" + name + "\" " + num;
659 return InventoryItem::deSerialize(itemstring, get_server(L));
660 }catch(SerializationError &e){
661 throw LuaError(L, std::string("check_stack_item: "
662 "internal error (itemstring=\"")+itemstring+"\")");
667 ToolDiggingProperties
670 static ToolDiggingProperties read_tool_digging_properties(
671 lua_State *L, int table)
673 ToolDiggingProperties prop;
674 getfloatfield(L, table, "full_punch_interval", prop.full_punch_interval);
675 getfloatfield(L, table, "basetime", prop.basetime);
676 getfloatfield(L, table, "dt_weight", prop.dt_weight);
677 getfloatfield(L, table, "dt_crackiness", prop.dt_crackiness);
678 getfloatfield(L, table, "dt_crumbliness", prop.dt_crumbliness);
679 getfloatfield(L, table, "dt_cuttability", prop.dt_cuttability);
680 getfloatfield(L, table, "basedurability", prop.basedurability);
681 getfloatfield(L, table, "dd_weight", prop.dd_weight);
682 getfloatfield(L, table, "dd_crackiness", prop.dd_crackiness);
683 getfloatfield(L, table, "dd_crumbliness", prop.dd_crumbliness);
684 getfloatfield(L, table, "dd_cuttability", prop.dd_cuttability);
688 static void set_tool_digging_properties(lua_State *L, int table,
689 const ToolDiggingProperties &prop)
691 setfloatfield(L, table, "full_punch_interval", prop.full_punch_interval);
692 setfloatfield(L, table, "basetime", prop.basetime);
693 setfloatfield(L, table, "dt_weight", prop.dt_weight);
694 setfloatfield(L, table, "dt_crackiness", prop.dt_crackiness);
695 setfloatfield(L, table, "dt_crumbliness", prop.dt_crumbliness);
696 setfloatfield(L, table, "dt_cuttability", prop.dt_cuttability);
697 setfloatfield(L, table, "basedurability", prop.basedurability);
698 setfloatfield(L, table, "dd_weight", prop.dd_weight);
699 setfloatfield(L, table, "dd_crackiness", prop.dd_crackiness);
700 setfloatfield(L, table, "dd_crumbliness", prop.dd_crumbliness);
701 setfloatfield(L, table, "dd_cuttability", prop.dd_cuttability);
704 static void push_tool_digging_properties(lua_State *L,
705 const ToolDiggingProperties &prop)
708 set_tool_digging_properties(L, -1, prop);
715 static ToolDefinition read_tool_definition(lua_State *L, int table)
718 getstringfield(L, table, "image", def.imagename);
719 def.properties = read_tool_digging_properties(L, table);
723 static void push_tool_definition(lua_State *L, const ToolDefinition &def)
726 lua_pushstring(L, def.imagename.c_str());
727 lua_setfield(L, -2, "image");
728 set_tool_digging_properties(L, -1, def.properties);
732 EnumString definitions
735 struct EnumString es_DrawType[] =
737 {NDT_NORMAL, "normal"},
738 {NDT_AIRLIKE, "airlike"},
739 {NDT_LIQUID, "liquid"},
740 {NDT_FLOWINGLIQUID, "flowingliquid"},
741 {NDT_GLASSLIKE, "glasslike"},
742 {NDT_ALLFACES, "allfaces"},
743 {NDT_ALLFACES_OPTIONAL, "allfaces_optional"},
744 {NDT_TORCHLIKE, "torchlike"},
745 {NDT_SIGNLIKE, "signlike"},
746 {NDT_PLANTLIKE, "plantlike"},
747 {NDT_FENCELIKE, "fencelike"},
748 {NDT_RAILLIKE, "raillike"},
752 struct EnumString es_ContentParamType[] =
755 {CPT_LIGHT, "light"},
756 {CPT_MINERAL, "mineral"},
757 {CPT_FACEDIR_SIMPLE, "facedir_simple"},
761 struct EnumString es_LiquidType[] =
763 {LIQUID_NONE, "none"},
764 {LIQUID_FLOWING, "flowing"},
765 {LIQUID_SOURCE, "source"},
769 struct EnumString es_NodeBoxType[] =
771 {NODEBOX_REGULAR, "regular"},
772 {NODEBOX_FIXED, "fixed"},
773 {NODEBOX_WALLMOUNTED, "wallmounted"},
777 struct EnumString es_Diggability[] =
779 {DIGGABLE_NOT, "not"},
780 {DIGGABLE_NORMAL, "normal"},
781 {DIGGABLE_CONSTANT, "constant"},
786 Getters for stuff in main tables
789 static void objectref_get(lua_State *L, u16 id)
791 // Get minetest.object_refs[i]
792 lua_getglobal(L, "minetest");
793 lua_getfield(L, -1, "object_refs");
794 luaL_checktype(L, -1, LUA_TTABLE);
795 lua_pushnumber(L, id);
797 lua_remove(L, -2); // object_refs
798 lua_remove(L, -2); // minetest
801 static void luaentity_get(lua_State *L, u16 id)
803 // Get minetest.luaentities[i]
804 lua_getglobal(L, "minetest");
805 lua_getfield(L, -1, "luaentities");
806 luaL_checktype(L, -1, LUA_TTABLE);
807 lua_pushnumber(L, id);
809 lua_remove(L, -2); // luaentities
810 lua_remove(L, -2); // minetest
817 #define method(class, name) {#name, class::l_##name}
826 InventoryItem *m_stack;
828 static const char className[];
829 static const luaL_reg methods[];
831 // Exported functions
834 static int gc_object(lua_State *L) {
835 ItemStack *o = *(ItemStack **)(lua_touserdata(L, 1));
841 static int l_peek_item(lua_State *L)
843 ItemStack *o = checkobject(L, 1);
844 push_stack_item(L, o->m_stack);
849 static int l_take_item(lua_State *L)
851 ItemStack *o = checkobject(L, 1);
852 push_stack_item(L, o->m_stack);
853 if(o->m_stack->getCount() <= 1){
857 o->m_stack->remove(1);
862 // put_item(self, item) -> true/false
863 static int l_put_item(lua_State *L)
865 ItemStack *o = checkobject(L, 1);
866 InventoryItem *item = check_stack_item(L, 2);
867 if(!item){ // nil can always be inserted
868 lua_pushboolean(L, true);
871 if(!item->addableTo(o->m_stack)){
872 lua_pushboolean(L, false);
877 lua_pushboolean(L, true);
881 // put_stackstring(self, stackstring) -> true/false
882 static int l_put_stackstring(lua_State *L)
884 ItemStack *o = checkobject(L, 1);
885 std::string stackstring = luaL_checkstring(L, 2);
887 InventoryItem *item = InventoryItem::deSerialize(stackstring,
889 if(!item->addableTo(o->m_stack)){
890 lua_pushboolean(L, false);
895 lua_pushboolean(L, true);
898 catch(SerializationError &e){
899 lua_pushboolean(L, false);
905 ItemStack(InventoryItem *item=NULL):
915 static ItemStack* checkobject(lua_State *L, int narg)
917 luaL_checktype(L, narg, LUA_TUSERDATA);
918 void *ud = luaL_checkudata(L, narg, className);
919 if(!ud) luaL_typerror(L, narg, className);
920 return *(ItemStack**)ud; // unbox pointer
923 InventoryItem* getItemCopy()
927 return m_stack->clone();
930 // Creates an ItemStack and leaves it on top of stack
931 static int create_object(lua_State *L)
933 InventoryItem *item = NULL;
934 if(lua_isstring(L, 1)){
935 std::string itemstring = lua_tostring(L, 1);
936 if(itemstring != ""){
938 IGameDef *gdef = get_server(L);
939 item = InventoryItem::deSerialize(itemstring, gdef);
940 }catch(SerializationError &e){
944 ItemStack *o = new ItemStack(item);
945 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
946 luaL_getmetatable(L, className);
947 lua_setmetatable(L, -2);
950 // Not callable from Lua
951 static int create(lua_State *L, InventoryItem *item)
953 ItemStack *o = new ItemStack(item);
954 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
955 luaL_getmetatable(L, className);
956 lua_setmetatable(L, -2);
960 static void Register(lua_State *L)
963 int methodtable = lua_gettop(L);
964 luaL_newmetatable(L, className);
965 int metatable = lua_gettop(L);
967 lua_pushliteral(L, "__metatable");
968 lua_pushvalue(L, methodtable);
969 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
971 lua_pushliteral(L, "__index");
972 lua_pushvalue(L, methodtable);
973 lua_settable(L, metatable);
975 lua_pushliteral(L, "__gc");
976 lua_pushcfunction(L, gc_object);
977 lua_settable(L, metatable);
979 lua_pop(L, 1); // drop metatable
981 luaL_openlib(L, 0, methods, 0); // fill methodtable
982 lua_pop(L, 1); // drop methodtable
984 // Can be created from Lua (ItemStack::create(itemstring))
985 lua_register(L, className, create_object);
988 const char ItemStack::className[] = "ItemStack";
989 const luaL_reg ItemStack::methods[] = {
990 method(ItemStack, peek_item),
991 method(ItemStack, take_item),
992 method(ItemStack, put_item),
993 method(ItemStack, put_stackstring),
1004 InventoryLocation m_loc;
1006 static const char className[];
1007 static const luaL_reg methods[];
1009 static InvRef *checkobject(lua_State *L, int narg)
1011 luaL_checktype(L, narg, LUA_TUSERDATA);
1012 void *ud = luaL_checkudata(L, narg, className);
1013 if(!ud) luaL_typerror(L, narg, className);
1014 return *(InvRef**)ud; // unbox pointer
1017 static Inventory* getinv(lua_State *L, InvRef *ref)
1019 return get_server(L)->getInventory(ref->m_loc);
1022 static InventoryList* getlist(lua_State *L, InvRef *ref,
1023 const char *listname)
1025 Inventory *inv = getinv(L, ref);
1028 return inv->getList(listname);
1031 static InventoryItem* getitem(lua_State *L, InvRef *ref,
1032 const char *listname, int i)
1034 InventoryList *list = getlist(L, ref, listname);
1037 return list->getItem(i);
1040 static void reportInventoryChange(lua_State *L, InvRef *ref)
1042 // Inform other things that the inventory has changed
1043 get_server(L)->setInventoryModified(ref->m_loc);
1046 // Exported functions
1048 // garbage collector
1049 static int gc_object(lua_State *L) {
1050 InvRef *o = *(InvRef **)(lua_touserdata(L, 1));
1055 // get_size(self, listname)
1056 static int l_get_size(lua_State *L)
1058 InvRef *ref = checkobject(L, 1);
1059 const char *listname = luaL_checkstring(L, 2);
1060 InventoryList *list = getlist(L, ref, listname);
1062 lua_pushinteger(L, list->getSize());
1064 lua_pushinteger(L, 0);
1069 // set_size(self, listname, size)
1070 static int l_set_size(lua_State *L)
1072 InvRef *ref = checkobject(L, 1);
1073 const char *listname = luaL_checkstring(L, 2);
1074 int newsize = luaL_checknumber(L, 3);
1075 Inventory *inv = getinv(L, ref);
1077 inv->deleteList(listname);
1078 reportInventoryChange(L, ref);
1081 InventoryList *list = inv->getList(listname);
1083 list->setSize(newsize);
1085 list = inv->addList(listname, newsize);
1087 reportInventoryChange(L, ref);
1091 // get_stack(self, listname, i)
1092 static int l_get_stack(lua_State *L)
1094 InvRef *ref = checkobject(L, 1);
1095 const char *listname = luaL_checkstring(L, 2);
1096 int i = luaL_checknumber(L, 3) - 1;
1097 InventoryItem *item = getitem(L, ref, listname, i);
1099 ItemStack::create(L, NULL);
1102 ItemStack::create(L, item->clone());
1106 // set_stack(self, listname, i, stack)
1107 static int l_set_stack(lua_State *L)
1109 InvRef *ref = checkobject(L, 1);
1110 const char *listname = luaL_checkstring(L, 2);
1111 int i = luaL_checknumber(L, 3) - 1;
1112 ItemStack *stack = ItemStack::checkobject(L, 4);
1113 InventoryList *list = getlist(L, ref, listname);
1115 lua_pushboolean(L, false);
1118 InventoryItem *newitem = stack->getItemCopy();
1119 InventoryItem *olditem = list->changeItem(i, newitem);
1120 bool success = (olditem != newitem);
1122 lua_pushboolean(L, success);
1123 reportInventoryChange(L, ref);
1127 // get_list(self, listname) -> list or nil
1128 static int l_get_list(lua_State *L)
1130 InvRef *ref = checkobject(L, 1);
1131 const char *listname = luaL_checkstring(L, 2);
1132 Inventory *inv = getinv(L, ref);
1133 inventory_get_list_to_lua(inv, listname, L);
1137 // set_list(self, listname, list)
1138 static int l_set_list(lua_State *L)
1140 InvRef *ref = checkobject(L, 1);
1141 const char *listname = luaL_checkstring(L, 2);
1142 Inventory *inv = getinv(L, ref);
1143 InventoryList *list = inv->getList(listname);
1145 inventory_set_list_from_lua(inv, listname, L, 3,
1146 get_server(L), list->getSize());
1148 inventory_set_list_from_lua(inv, listname, L, 3,
1150 reportInventoryChange(L, ref);
1154 // autoinsert_stack(self, listname, stack)
1155 static int l_autoinsert_stack(lua_State *L)
1157 InvRef *ref = checkobject(L, 1);
1158 const char *listname = luaL_checkstring(L, 2);
1159 ItemStack *stack = ItemStack::checkobject(L, 3);
1160 InventoryList *list = getlist(L, ref, listname);
1162 lua_pushboolean(L, false);
1165 InventoryItem *item = stack->getItemCopy();
1166 if(list->roomForItem(item)){
1167 delete list->addItem(item);
1168 lua_pushboolean(L, true);
1169 reportInventoryChange(L, ref);
1172 lua_pushboolean(L, false);
1177 // autoinsert_stackstring(self, listname, stackstring)
1178 static int l_autoinsert_stackstring(lua_State *L)
1180 InvRef *ref = checkobject(L, 1);
1181 const char *listname = luaL_checkstring(L, 2);
1182 const char *stackstring = luaL_checkstring(L, 3);
1183 InventoryList *list = getlist(L, ref, listname);
1185 lua_pushboolean(L, false);
1188 InventoryItem *item = InventoryItem::deSerialize(stackstring,
1190 if(list->roomForItem(item)){
1191 delete list->addItem(item);
1192 lua_pushboolean(L, true);
1193 reportInventoryChange(L, ref);
1196 lua_pushboolean(L, false);
1202 InvRef(const InventoryLocation &loc):
1211 // Creates an InvRef and leaves it on top of stack
1212 // Not callable from Lua; all references are created on the C side.
1213 static void create(lua_State *L, const InventoryLocation &loc)
1215 InvRef *o = new InvRef(loc);
1216 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1217 luaL_getmetatable(L, className);
1218 lua_setmetatable(L, -2);
1220 static void createPlayer(lua_State *L, Player *player)
1222 InventoryLocation loc;
1223 loc.setPlayer(player->getName());
1226 static void createNodeMeta(lua_State *L, v3s16 p)
1228 InventoryLocation loc;
1233 static void Register(lua_State *L)
1236 int methodtable = lua_gettop(L);
1237 luaL_newmetatable(L, className);
1238 int metatable = lua_gettop(L);
1240 lua_pushliteral(L, "__metatable");
1241 lua_pushvalue(L, methodtable);
1242 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
1244 lua_pushliteral(L, "__index");
1245 lua_pushvalue(L, methodtable);
1246 lua_settable(L, metatable);
1248 lua_pushliteral(L, "__gc");
1249 lua_pushcfunction(L, gc_object);
1250 lua_settable(L, metatable);
1252 lua_pop(L, 1); // drop metatable
1254 luaL_openlib(L, 0, methods, 0); // fill methodtable
1255 lua_pop(L, 1); // drop methodtable
1257 // Cannot be created from Lua
1258 //lua_register(L, className, create_object);
1261 const char InvRef::className[] = "InvRef";
1262 const luaL_reg InvRef::methods[] = {
1263 method(InvRef, get_size),
1264 method(InvRef, set_size),
1265 method(InvRef, get_stack),
1266 method(InvRef, set_stack),
1267 method(InvRef, get_list),
1268 method(InvRef, set_list),
1269 method(InvRef, autoinsert_stack),
1270 method(InvRef, autoinsert_stackstring),
1282 ServerEnvironment *m_env;
1284 static const char className[];
1285 static const luaL_reg methods[];
1287 static NodeMetaRef *checkobject(lua_State *L, int narg)
1289 luaL_checktype(L, narg, LUA_TUSERDATA);
1290 void *ud = luaL_checkudata(L, narg, className);
1291 if(!ud) luaL_typerror(L, narg, className);
1292 return *(NodeMetaRef**)ud; // unbox pointer
1295 static NodeMetadata* getmeta(NodeMetaRef *ref)
1297 NodeMetadata *meta = ref->m_env->getMap().getNodeMetadata(ref->m_p);
1301 /*static IGenericNodeMetadata* getgenericmeta(NodeMetaRef *ref)
1303 NodeMetadata *meta = getmeta(ref);
1306 if(meta->typeId() != NODEMETA_GENERIC)
1308 return (IGenericNodeMetadata*)meta;
1311 static void reportMetadataChange(NodeMetaRef *ref)
1313 // Inform other things that the metadata has changed
1314 v3s16 blockpos = getNodeBlockPos(ref->m_p);
1316 event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
1318 ref->m_env->getMap().dispatchEvent(&event);
1319 // Set the block to be saved
1320 MapBlock *block = ref->m_env->getMap().getBlockNoCreateNoEx(blockpos);
1322 block->raiseModified(MOD_STATE_WRITE_NEEDED,
1323 "NodeMetaRef::reportMetadataChange");
1326 // Exported functions
1328 // garbage collector
1329 static int gc_object(lua_State *L) {
1330 NodeMetaRef *o = *(NodeMetaRef **)(lua_touserdata(L, 1));
1336 static int l_get_type(lua_State *L)
1338 NodeMetaRef *ref = checkobject(L, 1);
1339 NodeMetadata *meta = getmeta(ref);
1345 lua_pushstring(L, meta->typeName());
1349 // allows_text_input(self)
1350 static int l_allows_text_input(lua_State *L)
1352 NodeMetaRef *ref = checkobject(L, 1);
1353 NodeMetadata *meta = getmeta(ref);
1354 if(meta == NULL) return 0;
1356 lua_pushboolean(L, meta->allowsTextInput());
1360 // set_text(self, text)
1361 static int l_set_text(lua_State *L)
1363 NodeMetaRef *ref = checkobject(L, 1);
1364 NodeMetadata *meta = getmeta(ref);
1365 if(meta == NULL) return 0;
1367 std::string text = luaL_checkstring(L, 2);
1368 meta->setText(text);
1369 reportMetadataChange(ref);
1374 static int l_get_text(lua_State *L)
1376 NodeMetaRef *ref = checkobject(L, 1);
1377 NodeMetadata *meta = getmeta(ref);
1378 if(meta == NULL) return 0;
1380 std::string text = meta->getText();
1381 lua_pushstring(L, text.c_str());
1386 static int l_get_owner(lua_State *L)
1388 NodeMetaRef *ref = checkobject(L, 1);
1389 NodeMetadata *meta = getmeta(ref);
1390 if(meta == NULL) return 0;
1392 std::string owner = meta->getOwner();
1393 lua_pushstring(L, owner.c_str());
1397 /* IGenericNodeMetadata interface */
1399 // set_infotext(self, text)
1400 static int l_set_infotext(lua_State *L)
1402 NodeMetaRef *ref = checkobject(L, 1);
1403 NodeMetadata *meta = getmeta(ref);
1404 if(meta == NULL) return 0;
1406 std::string text = luaL_checkstring(L, 2);
1407 meta->setInfoText(text);
1408 reportMetadataChange(ref);
1412 // get_inventory(self)
1413 static int l_get_inventory(lua_State *L)
1415 NodeMetaRef *ref = checkobject(L, 1);
1416 NodeMetadata *meta = getmeta(ref);
1417 if(meta == NULL) return 0;
1419 InvRef::createNodeMeta(L, ref->m_p);
1423 // deprecated: inventory_set_list(self, name, {item1, item2, ...})
1424 static int l_inventory_set_list(lua_State *L)
1426 infostream<<"Deprecated: inventory_set_list"<<std::endl;
1427 NodeMetaRef *ref = checkobject(L, 1);
1428 NodeMetadata *meta = getmeta(ref);
1429 if(meta == NULL) return 0;
1431 Inventory *inv = meta->getInventory();
1432 const char *name = luaL_checkstring(L, 2);
1433 inventory_set_list_from_lua(inv, name, L, 3,
1434 ref->m_env->getGameDef());
1435 reportMetadataChange(ref);
1439 // deprecated: inventory_get_list(self, name)
1440 static int l_inventory_get_list(lua_State *L)
1442 infostream<<"Deprecated: inventory_get_list"<<std::endl;
1443 NodeMetaRef *ref = checkobject(L, 1);
1444 NodeMetadata *meta = getmeta(ref);
1445 if(meta == NULL) return 0;
1447 Inventory *inv = meta->getInventory();
1448 const char *name = luaL_checkstring(L, 2);
1449 inventory_get_list_to_lua(inv, name, L);
1453 // set_inventory_draw_spec(self, text)
1454 static int l_set_inventory_draw_spec(lua_State *L)
1456 NodeMetaRef *ref = checkobject(L, 1);
1457 NodeMetadata *meta = getmeta(ref);
1458 if(meta == NULL) return 0;
1460 std::string text = luaL_checkstring(L, 2);
1461 meta->setInventoryDrawSpec(text);
1462 reportMetadataChange(ref);
1466 // set_allow_text_input(self, text)
1467 static int l_set_allow_text_input(lua_State *L)
1469 NodeMetaRef *ref = checkobject(L, 1);
1470 NodeMetadata *meta = getmeta(ref);
1471 if(meta == NULL) return 0;
1473 bool b = lua_toboolean(L, 2);
1474 meta->setAllowTextInput(b);
1475 reportMetadataChange(ref);
1479 // set_allow_removal(self, text)
1480 static int l_set_allow_removal(lua_State *L)
1482 NodeMetaRef *ref = checkobject(L, 1);
1483 NodeMetadata *meta = getmeta(ref);
1484 if(meta == NULL) return 0;
1486 bool b = lua_toboolean(L, 2);
1487 meta->setRemovalDisabled(!b);
1488 reportMetadataChange(ref);
1492 // set_enforce_owner(self, text)
1493 static int l_set_enforce_owner(lua_State *L)
1495 NodeMetaRef *ref = checkobject(L, 1);
1496 NodeMetadata *meta = getmeta(ref);
1497 if(meta == NULL) return 0;
1499 bool b = lua_toboolean(L, 2);
1500 meta->setEnforceOwner(b);
1501 reportMetadataChange(ref);
1505 // is_inventory_modified(self)
1506 static int l_is_inventory_modified(lua_State *L)
1508 NodeMetaRef *ref = checkobject(L, 1);
1509 NodeMetadata *meta = getmeta(ref);
1510 if(meta == NULL) return 0;
1512 lua_pushboolean(L, meta->isInventoryModified());
1516 // reset_inventory_modified(self)
1517 static int l_reset_inventory_modified(lua_State *L)
1519 NodeMetaRef *ref = checkobject(L, 1);
1520 NodeMetadata *meta = getmeta(ref);
1521 if(meta == NULL) return 0;
1523 meta->resetInventoryModified();
1524 reportMetadataChange(ref);
1528 // is_text_modified(self)
1529 static int l_is_text_modified(lua_State *L)
1531 NodeMetaRef *ref = checkobject(L, 1);
1532 NodeMetadata *meta = getmeta(ref);
1533 if(meta == NULL) return 0;
1535 lua_pushboolean(L, meta->isTextModified());
1539 // reset_text_modified(self)
1540 static int l_reset_text_modified(lua_State *L)
1542 NodeMetaRef *ref = checkobject(L, 1);
1543 NodeMetadata *meta = getmeta(ref);
1544 if(meta == NULL) return 0;
1546 meta->resetTextModified();
1547 reportMetadataChange(ref);
1551 // set_string(self, name, var)
1552 static int l_set_string(lua_State *L)
1554 NodeMetaRef *ref = checkobject(L, 1);
1555 NodeMetadata *meta = getmeta(ref);
1556 if(meta == NULL) return 0;
1558 std::string name = luaL_checkstring(L, 2);
1560 const char *s = lua_tolstring(L, 3, &len);
1561 std::string str(s, len);
1562 meta->setString(name, str);
1563 reportMetadataChange(ref);
1567 // get_string(self, name)
1568 static int l_get_string(lua_State *L)
1570 NodeMetaRef *ref = checkobject(L, 1);
1571 NodeMetadata *meta = getmeta(ref);
1572 if(meta == NULL) return 0;
1574 std::string name = luaL_checkstring(L, 2);
1575 std::string str = meta->getString(name);
1576 lua_pushlstring(L, str.c_str(), str.size());
1581 NodeMetaRef(v3s16 p, ServerEnvironment *env):
1591 // Creates an NodeMetaRef and leaves it on top of stack
1592 // Not callable from Lua; all references are created on the C side.
1593 static void create(lua_State *L, v3s16 p, ServerEnvironment *env)
1595 NodeMetaRef *o = new NodeMetaRef(p, env);
1596 //infostream<<"NodeMetaRef::create: o="<<o<<std::endl;
1597 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1598 luaL_getmetatable(L, className);
1599 lua_setmetatable(L, -2);
1602 static void Register(lua_State *L)
1605 int methodtable = lua_gettop(L);
1606 luaL_newmetatable(L, className);
1607 int metatable = lua_gettop(L);
1609 lua_pushliteral(L, "__metatable");
1610 lua_pushvalue(L, methodtable);
1611 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
1613 lua_pushliteral(L, "__index");
1614 lua_pushvalue(L, methodtable);
1615 lua_settable(L, metatable);
1617 lua_pushliteral(L, "__gc");
1618 lua_pushcfunction(L, gc_object);
1619 lua_settable(L, metatable);
1621 lua_pop(L, 1); // drop metatable
1623 luaL_openlib(L, 0, methods, 0); // fill methodtable
1624 lua_pop(L, 1); // drop methodtable
1626 // Cannot be created from Lua
1627 //lua_register(L, className, create_object);
1630 const char NodeMetaRef::className[] = "NodeMetaRef";
1631 const luaL_reg NodeMetaRef::methods[] = {
1632 method(NodeMetaRef, get_type),
1633 method(NodeMetaRef, allows_text_input),
1634 method(NodeMetaRef, set_text),
1635 method(NodeMetaRef, get_text),
1636 method(NodeMetaRef, get_owner),
1637 method(NodeMetaRef, set_infotext),
1638 method(NodeMetaRef, get_inventory),
1639 method(NodeMetaRef, inventory_set_list), // deprecated
1640 method(NodeMetaRef, inventory_get_list), // deprecated
1641 method(NodeMetaRef, set_inventory_draw_spec),
1642 method(NodeMetaRef, set_allow_text_input),
1643 method(NodeMetaRef, set_allow_removal),
1644 method(NodeMetaRef, set_enforce_owner),
1645 method(NodeMetaRef, is_inventory_modified),
1646 method(NodeMetaRef, reset_inventory_modified),
1647 method(NodeMetaRef, is_text_modified),
1648 method(NodeMetaRef, reset_text_modified),
1649 method(NodeMetaRef, set_string),
1650 method(NodeMetaRef, get_string),
1661 ServerActiveObject *m_object;
1663 static const char className[];
1664 static const luaL_reg methods[];
1666 static ObjectRef *checkobject(lua_State *L, int narg)
1668 luaL_checktype(L, narg, LUA_TUSERDATA);
1669 void *ud = luaL_checkudata(L, narg, className);
1670 if(!ud) luaL_typerror(L, narg, className);
1671 return *(ObjectRef**)ud; // unbox pointer
1674 static ServerActiveObject* getobject(ObjectRef *ref)
1676 ServerActiveObject *co = ref->m_object;
1680 static LuaEntitySAO* getluaobject(ObjectRef *ref)
1682 ServerActiveObject *obj = getobject(ref);
1685 if(obj->getType() != ACTIVEOBJECT_TYPE_LUAENTITY)
1687 return (LuaEntitySAO*)obj;
1690 static ServerRemotePlayer* getplayer(ObjectRef *ref)
1692 ServerActiveObject *obj = getobject(ref);
1695 if(obj->getType() != ACTIVEOBJECT_TYPE_PLAYER)
1697 return static_cast<ServerRemotePlayer*>(obj);
1700 // Exported functions
1702 // garbage collector
1703 static int gc_object(lua_State *L) {
1704 ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
1705 //infostream<<"ObjectRef::gc_object: o="<<o<<std::endl;
1711 static int l_remove(lua_State *L)
1713 ObjectRef *ref = checkobject(L, 1);
1714 ServerActiveObject *co = getobject(ref);
1715 if(co == NULL) return 0;
1716 infostream<<"ObjectRef::l_remove(): id="<<co->getId()<<std::endl;
1717 co->m_removed = true;
1722 // returns: {x=num, y=num, z=num}
1723 static int l_getpos(lua_State *L)
1725 ObjectRef *ref = checkobject(L, 1);
1726 ServerActiveObject *co = getobject(ref);
1727 if(co == NULL) return 0;
1728 v3f pos = co->getBasePosition() / BS;
1730 lua_pushnumber(L, pos.X);
1731 lua_setfield(L, -2, "x");
1732 lua_pushnumber(L, pos.Y);
1733 lua_setfield(L, -2, "y");
1734 lua_pushnumber(L, pos.Z);
1735 lua_setfield(L, -2, "z");
1739 // setpos(self, pos)
1740 static int l_setpos(lua_State *L)
1742 ObjectRef *ref = checkobject(L, 1);
1743 //LuaEntitySAO *co = getluaobject(ref);
1744 ServerActiveObject *co = getobject(ref);
1745 if(co == NULL) return 0;
1747 v3f pos = checkFloatPos(L, 2);
1753 // moveto(self, pos, continuous=false)
1754 static int l_moveto(lua_State *L)
1756 ObjectRef *ref = checkobject(L, 1);
1757 //LuaEntitySAO *co = getluaobject(ref);
1758 ServerActiveObject *co = getobject(ref);
1759 if(co == NULL) return 0;
1761 v3f pos = checkFloatPos(L, 2);
1763 bool continuous = lua_toboolean(L, 3);
1765 co->moveTo(pos, continuous);
1769 // punch(self, puncher); puncher = an another ObjectRef
1770 static int l_punch(lua_State *L)
1772 ObjectRef *ref = checkobject(L, 1);
1773 ObjectRef *ref2 = checkobject(L, 2);
1774 ServerActiveObject *co = getobject(ref);
1775 ServerActiveObject *co2 = getobject(ref2);
1776 if(co == NULL) return 0;
1777 if(co2 == NULL) return 0;
1783 // right_click(self, clicker); clicker = an another ObjectRef
1784 static int l_right_click(lua_State *L)
1786 ObjectRef *ref = checkobject(L, 1);
1787 ObjectRef *ref2 = checkobject(L, 2);
1788 ServerActiveObject *co = getobject(ref);
1789 ServerActiveObject *co2 = getobject(ref2);
1790 if(co == NULL) return 0;
1791 if(co2 == NULL) return 0;
1793 co->rightClick(co2);
1797 // get_wield_digging_properties(self)
1798 static int l_get_wield_digging_properties(lua_State *L)
1800 ObjectRef *ref = checkobject(L, 1);
1801 ServerActiveObject *co = getobject(ref);
1802 if(co == NULL) return 0;
1804 ToolDiggingProperties prop;
1805 co->getWieldDiggingProperties(&prop);
1806 push_tool_digging_properties(L, prop);
1810 // damage_wielded_item(self, amount)
1811 static int l_damage_wielded_item(lua_State *L)
1813 ObjectRef *ref = checkobject(L, 1);
1814 ServerActiveObject *co = getobject(ref);
1815 if(co == NULL) return 0;
1817 int amount = lua_tonumber(L, 2);
1818 co->damageWieldedItem(amount);
1822 // add_to_inventory(self, itemstring)
1823 // returns: true if item was added, (false, "reason") otherwise
1824 static int l_add_to_inventory(lua_State *L)
1826 ObjectRef *ref = checkobject(L, 1);
1827 luaL_checkstring(L, 2);
1828 ServerActiveObject *co = getobject(ref);
1829 if(co == NULL) return 0;
1831 const char *itemstring = luaL_checkstring(L, 2);
1832 infostream<<"ObjectRef::l_add_to_inventory(): id="<<co->getId()
1833 <<" itemstring=\""<<itemstring<<"\""<<std::endl;
1835 std::istringstream is(itemstring, std::ios::binary);
1836 ServerEnvironment *env = co->getEnv();
1838 IGameDef *gamedef = env->getGameDef();
1840 InventoryItem *item = InventoryItem::deSerialize(is, gamedef);
1841 if(item->getCount() == 0)
1843 bool added = co->addToInventory(item);
1845 lua_pushboolean(L, added);
1847 lua_pushstring(L, "failed to add item");
1849 } catch(SerializationError &e){
1851 lua_pushboolean(L, false);
1852 lua_pushstring(L, (std::string("Invalid item: ")
1853 + e.what()).c_str());
1858 // add_to_inventory_later(self, itemstring)
1860 static int l_add_to_inventory_later(lua_State *L)
1862 ObjectRef *ref = checkobject(L, 1);
1863 luaL_checkstring(L, 2);
1864 ServerActiveObject *co = getobject(ref);
1865 if(co == NULL) return 0;
1867 const char *itemstring = luaL_checkstring(L, 2);
1868 infostream<<"ObjectRef::l_add_to_inventory_later(): id="<<co->getId()
1869 <<" itemstring=\""<<itemstring<<"\""<<std::endl;
1871 std::istringstream is(itemstring, std::ios::binary);
1872 ServerEnvironment *env = co->getEnv();
1874 IGameDef *gamedef = env->getGameDef();
1875 InventoryItem *item = InventoryItem::deSerialize(is, gamedef);
1876 infostream<<"item="<<env<<std::endl;
1877 co->addToInventoryLater(item);
1883 // hp = number of hitpoints (2 * number of hearts)
1885 static int l_set_hp(lua_State *L)
1887 ObjectRef *ref = checkobject(L, 1);
1888 luaL_checknumber(L, 2);
1889 ServerActiveObject *co = getobject(ref);
1890 if(co == NULL) return 0;
1891 int hp = lua_tonumber(L, 2);
1892 infostream<<"ObjectRef::l_set_hp(): id="<<co->getId()
1893 <<" hp="<<hp<<std::endl;
1901 // returns: number of hitpoints (2 * number of hearts)
1902 // 0 if not applicable to this type of object
1903 static int l_get_hp(lua_State *L)
1905 ObjectRef *ref = checkobject(L, 1);
1906 ServerActiveObject *co = getobject(ref);
1907 if(co == NULL) return 0;
1908 int hp = co->getHP();
1909 infostream<<"ObjectRef::l_get_hp(): id="<<co->getId()
1910 <<" hp="<<hp<<std::endl;
1912 lua_pushnumber(L, hp);
1916 /* LuaEntitySAO-only */
1918 // setvelocity(self, {x=num, y=num, z=num})
1919 static int l_setvelocity(lua_State *L)
1921 ObjectRef *ref = checkobject(L, 1);
1922 LuaEntitySAO *co = getluaobject(ref);
1923 if(co == NULL) return 0;
1925 v3f pos = checkFloatPos(L, 2);
1927 co->setVelocity(pos);
1931 // setacceleration(self, {x=num, y=num, z=num})
1932 static int l_setacceleration(lua_State *L)
1934 ObjectRef *ref = checkobject(L, 1);
1935 LuaEntitySAO *co = getluaobject(ref);
1936 if(co == NULL) return 0;
1938 v3f pos = checkFloatPos(L, 2);
1940 co->setAcceleration(pos);
1944 // getacceleration(self)
1945 static int l_getacceleration(lua_State *L)
1947 ObjectRef *ref = checkobject(L, 1);
1948 LuaEntitySAO *co = getluaobject(ref);
1949 if(co == NULL) return 0;
1951 v3f v = co->getAcceleration();
1956 // settexturemod(self, mod)
1957 static int l_settexturemod(lua_State *L)
1959 ObjectRef *ref = checkobject(L, 1);
1960 LuaEntitySAO *co = getluaobject(ref);
1961 if(co == NULL) return 0;
1963 std::string mod = luaL_checkstring(L, 2);
1964 co->setTextureMod(mod);
1968 // setsprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2,
1969 // select_horiz_by_yawpitch=false)
1970 static int l_setsprite(lua_State *L)
1972 ObjectRef *ref = checkobject(L, 1);
1973 LuaEntitySAO *co = getluaobject(ref);
1974 if(co == NULL) return 0;
1977 if(!lua_isnil(L, 2))
1978 p = read_v2s16(L, 2);
1980 if(!lua_isnil(L, 3))
1981 num_frames = lua_tonumber(L, 3);
1982 float framelength = 0.2;
1983 if(!lua_isnil(L, 4))
1984 framelength = lua_tonumber(L, 4);
1985 bool select_horiz_by_yawpitch = false;
1986 if(!lua_isnil(L, 5))
1987 select_horiz_by_yawpitch = lua_toboolean(L, 5);
1988 co->setSprite(p, num_frames, framelength, select_horiz_by_yawpitch);
1994 // get_player_name(self)
1995 static int l_get_player_name(lua_State *L)
1997 ObjectRef *ref = checkobject(L, 1);
1998 ServerRemotePlayer *player = getplayer(ref);
2004 lua_pushstring(L, player->getName());
2008 // get_inventory(self)
2009 static int l_get_inventory(lua_State *L)
2011 ObjectRef *ref = checkobject(L, 1);
2012 ServerRemotePlayer *player = getplayer(ref);
2013 if(player == NULL) return 0;
2015 InvRef::createPlayer(L, player);
2019 // deprecated: inventory_set_list(self, name, {item1, item2, ...})
2020 static int l_inventory_set_list(lua_State *L)
2022 infostream<<"Deprecated: inventory_set_list"<<std::endl;
2023 ObjectRef *ref = checkobject(L, 1);
2024 ServerRemotePlayer *player = getplayer(ref);
2025 if(player == NULL) return 0;
2026 const char *name = luaL_checkstring(L, 2);
2028 inventory_set_list_from_lua(&player->inventory, name, L, 3,
2029 player->getEnv()->getGameDef(), PLAYER_INVENTORY_SIZE);
2030 player->m_inventory_not_sent = true;
2034 // deprecated: inventory_get_list(self, name)
2035 static int l_inventory_get_list(lua_State *L)
2037 infostream<<"Deprecated: inventory_get_list"<<std::endl;
2038 ObjectRef *ref = checkobject(L, 1);
2039 ServerRemotePlayer *player = getplayer(ref);
2040 if(player == NULL) return 0;
2041 const char *name = luaL_checkstring(L, 2);
2043 inventory_get_list_to_lua(&player->inventory, name, L);
2047 // get_wielded_itemstring(self)
2048 static int l_get_wielded_itemstring(lua_State *L)
2050 ObjectRef *ref = checkobject(L, 1);
2051 ServerRemotePlayer *player = getplayer(ref);
2052 if(player == NULL) return 0;
2054 InventoryItem *item = player->getWieldedItem();
2059 lua_pushstring(L, item->getItemString().c_str());
2063 // get_wielded_item(self)
2064 static int l_get_wielded_item(lua_State *L)
2066 ObjectRef *ref = checkobject(L, 1);
2067 ServerRemotePlayer *player = getplayer(ref);
2068 if(player == NULL) return 0;
2070 InventoryItem *item0 = player->getWieldedItem();
2071 push_stack_item(L, item0);
2075 // get_look_dir(self)
2076 static int l_get_look_dir(lua_State *L)
2078 ObjectRef *ref = checkobject(L, 1);
2079 ServerRemotePlayer *player = getplayer(ref);
2080 if(player == NULL) return 0;
2082 float pitch = player->getRadPitch();
2083 float yaw = player->getRadYaw();
2084 v3f v(cos(pitch)*cos(yaw), sin(pitch), cos(pitch)*sin(yaw));
2089 // get_look_pitch(self)
2090 static int l_get_look_pitch(lua_State *L)
2092 ObjectRef *ref = checkobject(L, 1);
2093 ServerRemotePlayer *player = getplayer(ref);
2094 if(player == NULL) return 0;
2096 lua_pushnumber(L, player->getRadPitch());
2100 // get_look_yaw(self)
2101 static int l_get_look_yaw(lua_State *L)
2103 ObjectRef *ref = checkobject(L, 1);
2104 ServerRemotePlayer *player = getplayer(ref);
2105 if(player == NULL) return 0;
2107 lua_pushnumber(L, player->getRadYaw());
2112 ObjectRef(ServerActiveObject *object):
2115 //infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
2121 infostream<<"ObjectRef destructing for id="
2122 <<m_object->getId()<<std::endl;
2124 infostream<<"ObjectRef destructing for id=unknown"<<std::endl;*/
2127 // Creates an ObjectRef and leaves it on top of stack
2128 // Not callable from Lua; all references are created on the C side.
2129 static void create(lua_State *L, ServerActiveObject *object)
2131 ObjectRef *o = new ObjectRef(object);
2132 //infostream<<"ObjectRef::create: o="<<o<<std::endl;
2133 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
2134 luaL_getmetatable(L, className);
2135 lua_setmetatable(L, -2);
2138 static void set_null(lua_State *L)
2140 ObjectRef *o = checkobject(L, -1);
2144 static void Register(lua_State *L)
2147 int methodtable = lua_gettop(L);
2148 luaL_newmetatable(L, className);
2149 int metatable = lua_gettop(L);
2151 lua_pushliteral(L, "__metatable");
2152 lua_pushvalue(L, methodtable);
2153 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
2155 lua_pushliteral(L, "__index");
2156 lua_pushvalue(L, methodtable);
2157 lua_settable(L, metatable);
2159 lua_pushliteral(L, "__gc");
2160 lua_pushcfunction(L, gc_object);
2161 lua_settable(L, metatable);
2163 lua_pop(L, 1); // drop metatable
2165 luaL_openlib(L, 0, methods, 0); // fill methodtable
2166 lua_pop(L, 1); // drop methodtable
2168 // Cannot be created from Lua
2169 //lua_register(L, className, create_object);
2172 const char ObjectRef::className[] = "ObjectRef";
2173 const luaL_reg ObjectRef::methods[] = {
2174 // ServerActiveObject
2175 method(ObjectRef, remove),
2176 method(ObjectRef, getpos),
2177 method(ObjectRef, setpos),
2178 method(ObjectRef, moveto),
2179 method(ObjectRef, punch),
2180 method(ObjectRef, right_click),
2181 method(ObjectRef, get_wield_digging_properties),
2182 method(ObjectRef, damage_wielded_item),
2183 method(ObjectRef, add_to_inventory),
2184 method(ObjectRef, add_to_inventory_later),
2185 method(ObjectRef, set_hp),
2186 method(ObjectRef, get_hp),
2187 // LuaEntitySAO-only
2188 method(ObjectRef, setvelocity),
2189 method(ObjectRef, setacceleration),
2190 method(ObjectRef, getacceleration),
2191 method(ObjectRef, settexturemod),
2192 method(ObjectRef, setsprite),
2194 method(ObjectRef, get_player_name),
2195 method(ObjectRef, get_inventory),
2196 method(ObjectRef, inventory_set_list), // deprecated
2197 method(ObjectRef, inventory_get_list), // deprecated
2198 method(ObjectRef, get_wielded_itemstring),
2199 method(ObjectRef, get_wielded_item),
2200 method(ObjectRef, get_look_dir),
2201 method(ObjectRef, get_look_pitch),
2202 method(ObjectRef, get_look_yaw),
2206 // Creates a new anonymous reference if id=0
2207 static void objectref_get_or_create(lua_State *L,
2208 ServerActiveObject *cobj)
2210 if(cobj->getId() == 0){
2211 ObjectRef::create(L, cobj);
2213 objectref_get(L, cobj->getId());
2224 ServerEnvironment *m_env;
2226 static const char className[];
2227 static const luaL_reg methods[];
2229 static EnvRef *checkobject(lua_State *L, int narg)
2231 luaL_checktype(L, narg, LUA_TUSERDATA);
2232 void *ud = luaL_checkudata(L, narg, className);
2233 if(!ud) luaL_typerror(L, narg, className);
2234 return *(EnvRef**)ud; // unbox pointer
2237 // Exported functions
2239 // EnvRef:add_node(pos, node)
2240 // pos = {x=num, y=num, z=num}
2241 static int l_add_node(lua_State *L)
2243 //infostream<<"EnvRef::l_add_node()"<<std::endl;
2244 EnvRef *o = checkobject(L, 1);
2245 ServerEnvironment *env = o->m_env;
2246 if(env == NULL) return 0;
2248 v3s16 pos = read_v3s16(L, 2);
2250 MapNode n = readnode(L, 3, env->getGameDef()->ndef());
2252 bool succeeded = env->getMap().addNodeWithEvent(pos, n);
2253 lua_pushboolean(L, succeeded);
2257 // EnvRef:remove_node(pos)
2258 // pos = {x=num, y=num, z=num}
2259 static int l_remove_node(lua_State *L)
2261 //infostream<<"EnvRef::l_remove_node()"<<std::endl;
2262 EnvRef *o = checkobject(L, 1);
2263 ServerEnvironment *env = o->m_env;
2264 if(env == NULL) return 0;
2266 v3s16 pos = read_v3s16(L, 2);
2268 bool succeeded = env->getMap().removeNodeWithEvent(pos);
2269 lua_pushboolean(L, succeeded);
2273 // EnvRef:get_node(pos)
2274 // pos = {x=num, y=num, z=num}
2275 static int l_get_node(lua_State *L)
2277 //infostream<<"EnvRef::l_get_node()"<<std::endl;
2278 EnvRef *o = checkobject(L, 1);
2279 ServerEnvironment *env = o->m_env;
2280 if(env == NULL) return 0;
2282 v3s16 pos = read_v3s16(L, 2);
2284 MapNode n = env->getMap().getNodeNoEx(pos);
2286 pushnode(L, n, env->getGameDef()->ndef());
2290 // EnvRef:get_node_or_nil(pos)
2291 // pos = {x=num, y=num, z=num}
2292 static int l_get_node_or_nil(lua_State *L)
2294 //infostream<<"EnvRef::l_get_node()"<<std::endl;
2295 EnvRef *o = checkobject(L, 1);
2296 ServerEnvironment *env = o->m_env;
2297 if(env == NULL) return 0;
2299 v3s16 pos = read_v3s16(L, 2);
2302 MapNode n = env->getMap().getNode(pos);
2304 pushnode(L, n, env->getGameDef()->ndef());
2306 } catch(InvalidPositionException &e)
2313 // EnvRef:get_node_light(pos, timeofday)
2314 // pos = {x=num, y=num, z=num}
2315 // timeofday: nil = current time, 0 = night, 0.5 = day
2316 static int l_get_node_light(lua_State *L)
2318 EnvRef *o = checkobject(L, 1);
2319 ServerEnvironment *env = o->m_env;
2320 if(env == NULL) return 0;
2322 v3s16 pos = read_v3s16(L, 2);
2323 u32 time_of_day = env->getTimeOfDay();
2324 if(lua_isnumber(L, 3))
2325 time_of_day = 24000.0 * lua_tonumber(L, 3);
2326 time_of_day %= 24000;
2327 u32 dnr = time_to_daynight_ratio(time_of_day);
2328 MapNode n = env->getMap().getNodeNoEx(pos);
2330 MapNode n = env->getMap().getNode(pos);
2331 INodeDefManager *ndef = env->getGameDef()->ndef();
2332 lua_pushinteger(L, n.getLightBlend(dnr, ndef));
2334 } catch(InvalidPositionException &e)
2341 // EnvRef:add_entity(pos, entityname)
2342 // pos = {x=num, y=num, z=num}
2343 static int l_add_entity(lua_State *L)
2345 //infostream<<"EnvRef::l_add_entity()"<<std::endl;
2346 EnvRef *o = checkobject(L, 1);
2347 ServerEnvironment *env = o->m_env;
2348 if(env == NULL) return 0;
2350 v3f pos = checkFloatPos(L, 2);
2352 const char *name = luaL_checkstring(L, 3);
2354 ServerActiveObject *obj = new LuaEntitySAO(env, pos, name, "");
2355 int objectid = env->addActiveObject(obj);
2356 // If failed to add, return nothing (reads as nil)
2360 objectref_get_or_create(L, obj);
2364 // EnvRef:add_item(pos, inventorystring)
2365 // pos = {x=num, y=num, z=num}
2366 static int l_add_item(lua_State *L)
2368 infostream<<"EnvRef::l_add_item()"<<std::endl;
2369 EnvRef *o = checkobject(L, 1);
2370 ServerEnvironment *env = o->m_env;
2371 if(env == NULL) return 0;
2373 v3f pos = checkFloatPos(L, 2);
2375 const char *inventorystring = luaL_checkstring(L, 3);
2377 ServerActiveObject *obj = new ItemSAO(env, pos, inventorystring);
2378 env->addActiveObject(obj);
2382 // EnvRef:add_rat(pos)
2383 // pos = {x=num, y=num, z=num}
2384 static int l_add_rat(lua_State *L)
2386 infostream<<"EnvRef::l_add_rat()"<<std::endl;
2387 EnvRef *o = checkobject(L, 1);
2388 ServerEnvironment *env = o->m_env;
2389 if(env == NULL) return 0;
2391 v3f pos = checkFloatPos(L, 2);
2393 ServerActiveObject *obj = new RatSAO(env, pos);
2394 env->addActiveObject(obj);
2398 // EnvRef:add_firefly(pos)
2399 // pos = {x=num, y=num, z=num}
2400 static int l_add_firefly(lua_State *L)
2402 infostream<<"EnvRef::l_add_firefly()"<<std::endl;
2403 EnvRef *o = checkobject(L, 1);
2404 ServerEnvironment *env = o->m_env;
2405 if(env == NULL) return 0;
2407 v3f pos = checkFloatPos(L, 2);
2409 ServerActiveObject *obj = new FireflySAO(env, pos);
2410 env->addActiveObject(obj);
2414 // EnvRef:get_meta(pos)
2415 static int l_get_meta(lua_State *L)
2417 //infostream<<"EnvRef::l_get_meta()"<<std::endl;
2418 EnvRef *o = checkobject(L, 1);
2419 ServerEnvironment *env = o->m_env;
2420 if(env == NULL) return 0;
2422 v3s16 p = read_v3s16(L, 2);
2423 NodeMetaRef::create(L, p, env);
2427 // EnvRef:get_player_by_name(name)
2428 static int l_get_player_by_name(lua_State *L)
2430 EnvRef *o = checkobject(L, 1);
2431 ServerEnvironment *env = o->m_env;
2432 if(env == NULL) return 0;
2434 const char *name = luaL_checkstring(L, 2);
2435 ServerRemotePlayer *player =
2436 static_cast<ServerRemotePlayer*>(env->getPlayer(name));
2441 // Put player on stack
2442 objectref_get_or_create(L, player);
2446 // EnvRef:get_objects_inside_radius(pos, radius)
2447 static int l_get_objects_inside_radius(lua_State *L)
2449 // Get the table insert function
2450 lua_getglobal(L, "table");
2451 lua_getfield(L, -1, "insert");
2452 int table_insert = lua_gettop(L);
2454 EnvRef *o = checkobject(L, 1);
2455 ServerEnvironment *env = o->m_env;
2456 if(env == NULL) return 0;
2458 v3f pos = checkFloatPos(L, 2);
2459 float radius = luaL_checknumber(L, 3) * BS;
2460 std::set<u16> ids = env->getObjectsInsideRadius(pos, radius);
2462 int table = lua_gettop(L);
2463 for(std::set<u16>::const_iterator
2464 i = ids.begin(); i != ids.end(); i++){
2465 ServerActiveObject *obj = env->getActiveObject(*i);
2466 // Insert object reference into table
2467 lua_pushvalue(L, table_insert);
2468 lua_pushvalue(L, table);
2469 objectref_get_or_create(L, obj);
2470 if(lua_pcall(L, 2, 0, 0))
2471 script_error(L, "error: %s", lua_tostring(L, -1));
2476 static int gc_object(lua_State *L) {
2477 EnvRef *o = *(EnvRef **)(lua_touserdata(L, 1));
2483 EnvRef(ServerEnvironment *env):
2486 infostream<<"EnvRef created"<<std::endl;
2491 infostream<<"EnvRef destructing"<<std::endl;
2494 // Creates an EnvRef and leaves it on top of stack
2495 // Not callable from Lua; all references are created on the C side.
2496 static void create(lua_State *L, ServerEnvironment *env)
2498 EnvRef *o = new EnvRef(env);
2499 //infostream<<"EnvRef::create: o="<<o<<std::endl;
2500 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
2501 luaL_getmetatable(L, className);
2502 lua_setmetatable(L, -2);
2505 static void set_null(lua_State *L)
2507 EnvRef *o = checkobject(L, -1);
2511 static void Register(lua_State *L)
2514 int methodtable = lua_gettop(L);
2515 luaL_newmetatable(L, className);
2516 int metatable = lua_gettop(L);
2518 lua_pushliteral(L, "__metatable");
2519 lua_pushvalue(L, methodtable);
2520 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
2522 lua_pushliteral(L, "__index");
2523 lua_pushvalue(L, methodtable);
2524 lua_settable(L, metatable);
2526 lua_pushliteral(L, "__gc");
2527 lua_pushcfunction(L, gc_object);
2528 lua_settable(L, metatable);
2530 lua_pop(L, 1); // drop metatable
2532 luaL_openlib(L, 0, methods, 0); // fill methodtable
2533 lua_pop(L, 1); // drop methodtable
2535 // Cannot be created from Lua
2536 //lua_register(L, className, create_object);
2539 const char EnvRef::className[] = "EnvRef";
2540 const luaL_reg EnvRef::methods[] = {
2541 method(EnvRef, add_node),
2542 method(EnvRef, remove_node),
2543 method(EnvRef, get_node),
2544 method(EnvRef, get_node_or_nil),
2545 method(EnvRef, get_node_light),
2546 method(EnvRef, add_entity),
2547 method(EnvRef, add_item),
2548 method(EnvRef, add_rat),
2549 method(EnvRef, add_firefly),
2550 method(EnvRef, get_meta),
2551 method(EnvRef, get_player_by_name),
2552 method(EnvRef, get_objects_inside_radius),
2560 static int l_register_nodedef_defaults(lua_State *L)
2562 luaL_checktype(L, 1, LUA_TTABLE);
2564 lua_pushvalue(L, 1); // Explicitly put parameter 1 on top of stack
2565 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
2570 // Register new object prototype
2571 // register_entity(name, prototype)
2572 static int l_register_entity(lua_State *L)
2574 std::string name = luaL_checkstring(L, 1);
2575 check_modname_prefix(L, name);
2576 //infostream<<"register_entity: "<<name<<std::endl;
2577 luaL_checktype(L, 2, LUA_TTABLE);
2579 // Get minetest.registered_entities
2580 lua_getglobal(L, "minetest");
2581 lua_getfield(L, -1, "registered_entities");
2582 luaL_checktype(L, -1, LUA_TTABLE);
2583 int registered_entities = lua_gettop(L);
2584 lua_pushvalue(L, 2); // Object = param 2 -> stack top
2585 // registered_entities[name] = object
2586 lua_setfield(L, registered_entities, name.c_str());
2588 // Get registered object to top of stack
2589 lua_pushvalue(L, 2);
2591 // Set __index to point to itself
2592 lua_pushvalue(L, -1);
2593 lua_setfield(L, -2, "__index");
2595 // Set metatable.__index = metatable
2596 luaL_getmetatable(L, "minetest.entity");
2597 lua_pushvalue(L, -1); // duplicate metatable
2598 lua_setfield(L, -2, "__index");
2599 // Set object metatable
2600 lua_setmetatable(L, -2);
2602 return 0; /* number of results */
2605 class LuaABM : public ActiveBlockModifier
2611 std::set<std::string> m_trigger_contents;
2612 std::set<std::string> m_required_neighbors;
2613 float m_trigger_interval;
2614 u32 m_trigger_chance;
2616 LuaABM(lua_State *L, int id,
2617 const std::set<std::string> &trigger_contents,
2618 const std::set<std::string> &required_neighbors,
2619 float trigger_interval, u32 trigger_chance):
2622 m_trigger_contents(trigger_contents),
2623 m_required_neighbors(required_neighbors),
2624 m_trigger_interval(trigger_interval),
2625 m_trigger_chance(trigger_chance)
2628 virtual std::set<std::string> getTriggerContents()
2630 return m_trigger_contents;
2632 virtual std::set<std::string> getRequiredNeighbors()
2634 return m_required_neighbors;
2636 virtual float getTriggerInterval()
2638 return m_trigger_interval;
2640 virtual u32 getTriggerChance()
2642 return m_trigger_chance;
2644 virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n,
2645 u32 active_object_count, u32 active_object_count_wider)
2647 lua_State *L = m_lua;
2650 assert(lua_checkstack(L, 20));
2651 StackUnroller stack_unroller(L);
2653 // Get minetest.registered_abms
2654 lua_getglobal(L, "minetest");
2655 lua_getfield(L, -1, "registered_abms");
2656 luaL_checktype(L, -1, LUA_TTABLE);
2657 int registered_abms = lua_gettop(L);
2659 // Get minetest.registered_abms[m_id]
2660 lua_pushnumber(L, m_id);
2661 lua_gettable(L, registered_abms);
2662 if(lua_isnil(L, -1))
2666 luaL_checktype(L, -1, LUA_TTABLE);
2667 lua_getfield(L, -1, "action");
2668 luaL_checktype(L, -1, LUA_TFUNCTION);
2670 pushnode(L, n, env->getGameDef()->ndef());
2671 lua_pushnumber(L, active_object_count);
2672 lua_pushnumber(L, active_object_count_wider);
2673 if(lua_pcall(L, 4, 0, 0))
2674 script_error(L, "error: %s", lua_tostring(L, -1));
2678 // register_abm({...})
2679 static int l_register_abm(lua_State *L)
2681 //infostream<<"register_abm"<<std::endl;
2682 luaL_checktype(L, 1, LUA_TTABLE);
2684 // Get minetest.registered_abms
2685 lua_getglobal(L, "minetest");
2686 lua_getfield(L, -1, "registered_abms");
2687 luaL_checktype(L, -1, LUA_TTABLE);
2688 int registered_abms = lua_gettop(L);
2693 lua_pushnumber(L, id);
2694 lua_gettable(L, registered_abms);
2695 if(lua_isnil(L, -1))
2702 infostream<<"register_abm: id="<<id<<std::endl;
2704 // registered_abms[id] = spec
2705 lua_pushnumber(L, id);
2706 lua_pushvalue(L, 1);
2707 lua_settable(L, registered_abms);
2709 return 0; /* number of results */
2712 // register_tool(name, {lots of stuff})
2713 static int l_register_tool(lua_State *L)
2715 std::string name = luaL_checkstring(L, 1);
2716 check_modname_prefix(L, name);
2717 //infostream<<"register_tool: "<<name<<std::endl;
2718 luaL_checktype(L, 2, LUA_TTABLE);
2721 // Get the writable tool definition manager from the server
2722 IWritableToolDefManager *tooldef =
2723 get_server(L)->getWritableToolDefManager();
2725 ToolDefinition def = read_tool_definition(L, table);
2727 tooldef->registerTool(name, def);
2728 return 0; /* number of results */
2731 // register_craftitem(name, {lots of stuff})
2732 static int l_register_craftitem(lua_State *L)
2734 std::string name = luaL_checkstring(L, 1);
2735 check_modname_prefix(L, name);
2736 //infostream<<"register_craftitem: "<<name<<std::endl;
2737 luaL_checktype(L, 2, LUA_TTABLE);
2740 // Get the writable CraftItem definition manager from the server
2741 IWritableCraftItemDefManager *craftitemdef =
2742 get_server(L)->getWritableCraftItemDefManager();
2744 // Check if on_drop is defined
2745 lua_getfield(L, table, "on_drop");
2746 bool got_on_drop = !lua_isnil(L, -1);
2749 // Check if on_use is defined
2750 lua_getfield(L, table, "on_use");
2751 bool got_on_use = !lua_isnil(L, -1);
2754 CraftItemDefinition def;
2756 getstringfield(L, table, "image", def.imagename);
2757 getstringfield(L, table, "cookresult_itemstring", def.cookresult_item);
2758 getfloatfield(L, table, "furnace_cooktime", def.furnace_cooktime);
2759 getfloatfield(L, table, "furnace_burntime", def.furnace_burntime);
2760 def.usable = getboolfield_default(L, table, "usable", got_on_use);
2761 getboolfield(L, table, "liquids_pointable", def.liquids_pointable);
2762 def.dropcount = getintfield_default(L, table, "dropcount", def.dropcount);
2763 def.stack_max = getintfield_default(L, table, "stack_max", def.stack_max);
2765 // If an on_drop callback is defined, force dropcount to 1
2770 craftitemdef->registerCraftItem(name, def);
2772 lua_pushvalue(L, table);
2773 scriptapi_add_craftitem(L, name.c_str());
2775 return 0; /* number of results */
2778 // register_node(name, {lots of stuff})
2779 static int l_register_node(lua_State *L)
2781 std::string name = luaL_checkstring(L, 1);
2782 check_modname_prefix(L, name);
2783 //infostream<<"register_node: "<<name<<std::endl;
2784 luaL_checktype(L, 2, LUA_TTABLE);
2785 int nodedef_table = 2;
2787 // Get the writable node definition manager from the server
2788 IWritableNodeDefManager *nodedef =
2789 get_server(L)->getWritableNodeDefManager();
2791 // Get default node definition from registry
2792 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
2793 int nodedef_default = lua_gettop(L);
2796 Add to minetest.registered_nodes with default as metatable
2799 // Get the node definition table given as parameter
2800 lua_pushvalue(L, nodedef_table);
2802 // Set __index to point to itself
2803 lua_pushvalue(L, -1);
2804 lua_setfield(L, -2, "__index");
2806 // Set nodedef_default as metatable for the definition
2807 lua_pushvalue(L, nodedef_default);
2808 lua_setmetatable(L, nodedef_table);
2810 // minetest.registered_nodes[name] = nodedef
2811 lua_getglobal(L, "minetest");
2812 lua_getfield(L, -1, "registered_nodes");
2813 luaL_checktype(L, -1, LUA_TTABLE);
2814 lua_pushstring(L, name.c_str());
2815 lua_pushvalue(L, nodedef_table);
2816 lua_settable(L, -3);
2824 // Default to getting the corresponding NodeItem when dug
2825 f.dug_item = std::string("NodeItem \"")+name+"\" 1";
2827 // Default to unknown_block.png as all textures
2828 f.setAllTextures("unknown_block.png");
2831 Read definiton from Lua
2836 /* Visual definition */
2838 f.drawtype = (NodeDrawType)getenumfield(L, nodedef_table, "drawtype", es_DrawType,
2840 getfloatfield(L, nodedef_table, "visual_scale", f.visual_scale);
2842 lua_getfield(L, nodedef_table, "tile_images");
2843 if(lua_istable(L, -1)){
2844 int table = lua_gettop(L);
2847 while(lua_next(L, table) != 0){
2848 // key at index -2 and value at index -1
2849 if(lua_isstring(L, -1))
2850 f.tname_tiles[i] = lua_tostring(L, -1);
2852 f.tname_tiles[i] = "";
2853 // removes value, keeps key for next iteration
2861 // Copy last value to all remaining textures
2863 std::string lastname = f.tname_tiles[i-1];
2865 f.tname_tiles[i] = lastname;
2872 getstringfield(L, nodedef_table, "inventory_image", f.tname_inventory);
2874 lua_getfield(L, nodedef_table, "special_materials");
2875 if(lua_istable(L, -1)){
2876 int table = lua_gettop(L);
2879 while(lua_next(L, table) != 0){
2880 // key at index -2 and value at index -1
2881 int smtable = lua_gettop(L);
2882 std::string tname = getstringfield_default(
2883 L, smtable, "image", "");
2884 bool backface_culling = getboolfield_default(
2885 L, smtable, "backface_culling", true);
2886 MaterialSpec mspec(tname, backface_culling);
2887 f.setSpecialMaterial(i, mspec);
2888 // removes value, keeps key for next iteration
2899 f.alpha = getintfield_default(L, nodedef_table, "alpha", 255);
2903 lua_getfield(L, nodedef_table, "post_effect_color");
2904 if(!lua_isnil(L, -1))
2905 f.post_effect_color = readARGB8(L, -1);
2908 f.param_type = (ContentParamType)getenumfield(L, nodedef_table, "paramtype",
2909 es_ContentParamType, CPT_NONE);
2911 // True for all ground-like things like stone and mud, false for eg. trees
2912 getboolfield(L, nodedef_table, "is_ground_content", f.is_ground_content);
2913 f.light_propagates = (f.param_type == CPT_LIGHT);
2914 warn_if_field_exists(L, nodedef_table, "light_propagates",
2915 "deprecated: determined from paramtype");
2916 getboolfield(L, nodedef_table, "sunlight_propagates", f.sunlight_propagates);
2917 // This is used for collision detection.
2918 // Also for general solidness queries.
2919 getboolfield(L, nodedef_table, "walkable", f.walkable);
2920 // Player can point to these
2921 getboolfield(L, nodedef_table, "pointable", f.pointable);
2922 // Player can dig these
2923 getboolfield(L, nodedef_table, "diggable", f.diggable);
2924 // Player can climb these
2925 getboolfield(L, nodedef_table, "climbable", f.climbable);
2926 // Player can build on these
2927 getboolfield(L, nodedef_table, "buildable_to", f.buildable_to);
2928 // If true, param2 is set to direction when placed. Used for torches.
2929 // NOTE: the direction format is quite inefficient and should be changed
2930 getboolfield(L, nodedef_table, "wall_mounted", f.wall_mounted);
2931 // Whether this content type often contains mineral.
2932 // Used for texture atlas creation.
2933 // Currently only enabled for CONTENT_STONE.
2934 getboolfield(L, nodedef_table, "often_contains_mineral", f.often_contains_mineral);
2935 // Inventory item string as which the node appears in inventory when dug.
2936 // Mineral overrides this.
2937 getstringfield(L, nodedef_table, "dug_item", f.dug_item);
2938 // Extra dug item and its rarity
2939 getstringfield(L, nodedef_table, "extra_dug_item", f.extra_dug_item);
2940 // Usual get interval for extra dug item
2941 getintfield(L, nodedef_table, "extra_dug_item_rarity", f.extra_dug_item_rarity);
2942 // Metadata name of node (eg. "furnace")
2943 getstringfield(L, nodedef_table, "metadata_name", f.metadata_name);
2944 // Whether the node is non-liquid, source liquid or flowing liquid
2945 f.liquid_type = (LiquidType)getenumfield(L, nodedef_table, "liquidtype",
2946 es_LiquidType, LIQUID_NONE);
2947 // If the content is liquid, this is the flowing version of the liquid.
2948 getstringfield(L, nodedef_table, "liquid_alternative_flowing",
2949 f.liquid_alternative_flowing);
2950 // If the content is liquid, this is the source version of the liquid.
2951 getstringfield(L, nodedef_table, "liquid_alternative_source",
2952 f.liquid_alternative_source);
2953 // Viscosity for fluid flow, ranging from 1 to 7, with
2954 // 1 giving almost instantaneous propagation and 7 being
2955 // the slowest possible
2956 f.liquid_viscosity = getintfield_default(L, nodedef_table,
2957 "liquid_viscosity", f.liquid_viscosity);
2958 // Amount of light the node emits
2959 f.light_source = getintfield_default(L, nodedef_table,
2960 "light_source", f.light_source);
2961 f.damage_per_second = getintfield_default(L, nodedef_table,
2962 "damage_per_second", f.damage_per_second);
2964 lua_getfield(L, nodedef_table, "selection_box");
2965 if(lua_istable(L, -1)){
2966 f.selection_box.type = (NodeBoxType)getenumfield(L, -1, "type",
2967 es_NodeBoxType, NODEBOX_REGULAR);
2969 lua_getfield(L, -1, "fixed");
2970 if(lua_istable(L, -1))
2971 f.selection_box.fixed = read_aabbox3df32(L, -1, BS);
2974 lua_getfield(L, -1, "wall_top");
2975 if(lua_istable(L, -1))
2976 f.selection_box.wall_top = read_aabbox3df32(L, -1, BS);
2979 lua_getfield(L, -1, "wall_bottom");
2980 if(lua_istable(L, -1))
2981 f.selection_box.wall_bottom = read_aabbox3df32(L, -1, BS);
2984 lua_getfield(L, -1, "wall_side");
2985 if(lua_istable(L, -1))
2986 f.selection_box.wall_side = read_aabbox3df32(L, -1, BS);
2991 lua_getfield(L, nodedef_table, "material");
2992 if(lua_istable(L, -1)){
2993 f.material.diggability = (Diggability)getenumfield(L, -1, "diggability",
2994 es_Diggability, DIGGABLE_NORMAL);
2996 getfloatfield(L, -1, "constant_time", f.material.constant_time);
2997 getfloatfield(L, -1, "weight", f.material.weight);
2998 getfloatfield(L, -1, "crackiness", f.material.crackiness);
2999 getfloatfield(L, -1, "crumbliness", f.material.crumbliness);
3000 getfloatfield(L, -1, "cuttability", f.material.cuttability);
3001 getfloatfield(L, -1, "flammability", f.material.flammability);
3005 getstringfield(L, nodedef_table, "cookresult_itemstring", f.cookresult_item);
3006 getfloatfield(L, nodedef_table, "furnace_cooktime", f.furnace_cooktime);
3007 getfloatfield(L, nodedef_table, "furnace_burntime", f.furnace_burntime);
3013 nodedef->set(name, f);
3015 return 0; /* number of results */
3018 // alias_node(name, convert_to_name)
3019 static int l_alias_node(lua_State *L)
3021 std::string name = luaL_checkstring(L, 1);
3022 std::string convert_to = luaL_checkstring(L, 2);
3024 // Get the writable node definition manager from the server
3025 IWritableNodeDefManager *nodedef =
3026 get_server(L)->getWritableNodeDefManager();
3028 nodedef->setAlias(name, convert_to);
3030 return 0; /* number of results */
3033 // alias_tool(name, convert_to_name)
3034 static int l_alias_tool(lua_State *L)
3036 std::string name = luaL_checkstring(L, 1);
3037 std::string convert_to = luaL_checkstring(L, 2);
3039 // Get the writable tool definition manager from the server
3040 IWritableToolDefManager *tooldef =
3041 get_server(L)->getWritableToolDefManager();
3043 tooldef->setAlias(name, convert_to);
3045 return 0; /* number of results */
3048 // alias_craftitem(name, convert_to_name)
3049 static int l_alias_craftitem(lua_State *L)
3051 std::string name = luaL_checkstring(L, 1);
3052 std::string convert_to = luaL_checkstring(L, 2);
3054 // Get the writable CraftItem definition manager from the server
3055 IWritableCraftItemDefManager *craftitemdef =
3056 get_server(L)->getWritableCraftItemDefManager();
3058 craftitemdef->setAlias(name, convert_to);
3060 return 0; /* number of results */
3063 // register_craft({output=item, recipe={{item00,item10},{item01,item11}})
3064 static int l_register_craft(lua_State *L)
3066 //infostream<<"register_craft"<<std::endl;
3067 luaL_checktype(L, 1, LUA_TTABLE);
3070 // Get the writable craft definition manager from the server
3071 IWritableCraftDefManager *craftdef =
3072 get_server(L)->getWritableCraftDefManager();
3076 std::vector<std::string> input;
3078 lua_getfield(L, table0, "output");
3079 luaL_checktype(L, -1, LUA_TSTRING);
3080 if(lua_isstring(L, -1))
3081 output = lua_tostring(L, -1);
3084 lua_getfield(L, table0, "recipe");
3085 luaL_checktype(L, -1, LUA_TTABLE);
3086 if(lua_istable(L, -1)){
3087 int table1 = lua_gettop(L);
3090 while(lua_next(L, table1) != 0){
3092 // key at index -2 and value at index -1
3093 luaL_checktype(L, -1, LUA_TTABLE);
3094 if(lua_istable(L, -1)){
3095 int table2 = lua_gettop(L);
3097 while(lua_next(L, table2) != 0){
3098 // key at index -2 and value at index -1
3099 luaL_checktype(L, -1, LUA_TSTRING);
3100 input.push_back(lua_tostring(L, -1));
3101 // removes value, keeps key for next iteration
3109 if(colcount != width){
3111 error += "Invalid crafting recipe (output=\""
3113 throw LuaError(L, error);
3116 // removes value, keeps key for next iteration
3123 CraftDefinition def(output, width, input);
3124 craftdef->registerCraft(def);
3126 return 0; /* number of results */
3129 // setting_get(name)
3130 static int l_setting_get(lua_State *L)
3132 const char *name = luaL_checkstring(L, 1);
3134 std::string value = g_settings->get(name);
3135 lua_pushstring(L, value.c_str());
3136 } catch(SettingNotFoundException &e){
3142 // setting_getbool(name)
3143 static int l_setting_getbool(lua_State *L)
3145 const char *name = luaL_checkstring(L, 1);
3147 bool value = g_settings->getBool(name);
3148 lua_pushboolean(L, value);
3149 } catch(SettingNotFoundException &e){
3155 // chat_send_all(text)
3156 static int l_chat_send_all(lua_State *L)
3158 const char *text = luaL_checkstring(L, 1);
3159 // Get server from registry
3160 Server *server = get_server(L);
3162 server->notifyPlayers(narrow_to_wide(text));
3166 // chat_send_player(name, text)
3167 static int l_chat_send_player(lua_State *L)
3169 const char *name = luaL_checkstring(L, 1);
3170 const char *text = luaL_checkstring(L, 2);
3171 // Get server from registry
3172 Server *server = get_server(L);
3174 server->notifyPlayer(name, narrow_to_wide(text));
3178 // get_player_privs(name, text)
3179 static int l_get_player_privs(lua_State *L)
3181 const char *name = luaL_checkstring(L, 1);
3182 // Get server from registry
3183 Server *server = get_server(L);
3186 int table = lua_gettop(L);
3187 u64 privs_i = server->getPlayerAuthPrivs(name);
3188 // Special case for the "name" setting (local player / server owner)
3189 if(name == g_settings->get("name"))
3191 std::set<std::string> privs_s = privsToSet(privs_i);
3192 for(std::set<std::string>::const_iterator
3193 i = privs_s.begin(); i != privs_s.end(); i++){
3194 lua_pushboolean(L, true);
3195 lua_setfield(L, table, i->c_str());
3197 lua_pushvalue(L, table);
3201 // get_inventory(location)
3202 static int l_get_inventory(lua_State *L)
3204 InventoryLocation loc;
3206 std::string type = checkstringfield(L, 1, "type");
3207 if(type == "player"){
3208 std::string name = checkstringfield(L, 1, "name");
3209 loc.setPlayer(name);
3210 } else if(type == "node"){
3211 lua_getfield(L, 1, "pos");
3212 v3s16 pos = check_v3s16(L, -1);
3213 loc.setNodeMeta(pos);
3216 if(get_server(L)->getInventory(loc) != NULL)
3217 InvRef::create(L, loc);
3223 // get_modpath(modname)
3224 static int l_get_modpath(lua_State *L)
3226 const char *modname = luaL_checkstring(L, 1);
3227 // Get server from registry
3228 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
3229 Server *server = (Server*)lua_touserdata(L, -1);
3231 const ModSpec *mod = server->getModSpec(modname);
3236 lua_pushstring(L, mod->path.c_str());
3240 static const struct luaL_Reg minetest_f [] = {
3241 {"register_nodedef_defaults", l_register_nodedef_defaults},
3242 {"register_entity", l_register_entity},
3243 {"register_tool", l_register_tool},
3244 {"register_craftitem", l_register_craftitem},
3245 {"register_node", l_register_node},
3246 {"register_craft", l_register_craft},
3247 {"register_abm", l_register_abm},
3248 {"alias_node", l_alias_node},
3249 {"alias_tool", l_alias_tool},
3250 {"alias_craftitem", l_alias_craftitem},
3251 {"setting_get", l_setting_get},
3252 {"setting_getbool", l_setting_getbool},
3253 {"chat_send_all", l_chat_send_all},
3254 {"chat_send_player", l_chat_send_player},
3255 {"get_player_privs", l_get_player_privs},
3256 {"get_inventory", l_get_inventory},
3257 {"get_modpath", l_get_modpath},
3265 static const struct luaL_Reg minetest_entity_m [] = {
3270 Main export function
3273 void scriptapi_export(lua_State *L, Server *server)
3276 assert(lua_checkstack(L, 20));
3277 infostream<<"scriptapi_export"<<std::endl;
3278 StackUnroller stack_unroller(L);
3280 // Store server as light userdata in registry
3281 lua_pushlightuserdata(L, server);
3282 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_server");
3284 // Store nil as minetest_nodedef_defaults in registry
3286 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
3288 // Register global functions in table minetest
3290 luaL_register(L, NULL, minetest_f);
3291 lua_setglobal(L, "minetest");
3293 // Get the main minetest table
3294 lua_getglobal(L, "minetest");
3296 // Add tables to minetest
3299 lua_setfield(L, -2, "registered_nodes");
3301 lua_setfield(L, -2, "registered_entities");
3303 lua_setfield(L, -2, "registered_craftitems");
3305 lua_setfield(L, -2, "registered_abms");
3308 lua_setfield(L, -2, "object_refs");
3310 lua_setfield(L, -2, "luaentities");
3312 // Create entity prototype
3313 luaL_newmetatable(L, "minetest.entity");
3314 // metatable.__index = metatable
3315 lua_pushvalue(L, -1); // Duplicate metatable
3316 lua_setfield(L, -2, "__index");
3317 // Put functions in metatable
3318 luaL_register(L, NULL, minetest_entity_m);
3319 // Put other stuff in metatable
3321 // Register wrappers
3322 ItemStack::Register(L);
3323 InvRef::Register(L);
3324 NodeMetaRef::Register(L);
3325 ObjectRef::Register(L);
3326 EnvRef::Register(L);
3329 bool scriptapi_loadmod(lua_State *L, const std::string &scriptpath,
3330 const std::string &modname)
3332 ModNameStorer modnamestorer(L, modname);
3334 if(!string_allowed(modname, "abcdefghijklmnopqrstuvwxyz"
3336 errorstream<<"Error loading mod \""<<modname
3337 <<"\": modname does not follow naming conventions: "
3338 <<"Only chararacters [a-z0-9_] are allowed."<<std::endl;
3342 bool success = false;
3345 success = script_load(L, scriptpath.c_str());
3348 errorstream<<"Error loading mod \""<<modname
3349 <<"\": "<<e.what()<<std::endl;
3355 void scriptapi_add_environment(lua_State *L, ServerEnvironment *env)
3358 assert(lua_checkstack(L, 20));
3359 infostream<<"scriptapi_add_environment"<<std::endl;
3360 StackUnroller stack_unroller(L);
3362 // Create EnvRef on stack
3363 EnvRef::create(L, env);
3364 int envref = lua_gettop(L);
3366 // minetest.env = envref
3367 lua_getglobal(L, "minetest");
3368 luaL_checktype(L, -1, LUA_TTABLE);
3369 lua_pushvalue(L, envref);
3370 lua_setfield(L, -2, "env");
3372 // Store environment as light userdata in registry
3373 lua_pushlightuserdata(L, env);
3374 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_env");
3377 Add ActiveBlockModifiers to environment
3380 // Get minetest.registered_abms
3381 lua_getglobal(L, "minetest");
3382 lua_getfield(L, -1, "registered_abms");
3383 luaL_checktype(L, -1, LUA_TTABLE);
3384 int registered_abms = lua_gettop(L);
3386 if(lua_istable(L, registered_abms)){
3387 int table = lua_gettop(L);
3389 while(lua_next(L, table) != 0){
3390 // key at index -2 and value at index -1
3391 int id = lua_tonumber(L, -2);
3392 int current_abm = lua_gettop(L);
3394 std::set<std::string> trigger_contents;
3395 lua_getfield(L, current_abm, "nodenames");
3396 if(lua_istable(L, -1)){
3397 int table = lua_gettop(L);
3399 while(lua_next(L, table) != 0){
3400 // key at index -2 and value at index -1
3401 luaL_checktype(L, -1, LUA_TSTRING);
3402 trigger_contents.insert(lua_tostring(L, -1));
3403 // removes value, keeps key for next iteration
3406 } else if(lua_isstring(L, -1)){
3407 trigger_contents.insert(lua_tostring(L, -1));
3411 std::set<std::string> required_neighbors;
3412 lua_getfield(L, current_abm, "neighbors");
3413 if(lua_istable(L, -1)){
3414 int table = lua_gettop(L);
3416 while(lua_next(L, table) != 0){
3417 // key at index -2 and value at index -1
3418 luaL_checktype(L, -1, LUA_TSTRING);
3419 required_neighbors.insert(lua_tostring(L, -1));
3420 // removes value, keeps key for next iteration
3423 } else if(lua_isstring(L, -1)){
3424 required_neighbors.insert(lua_tostring(L, -1));
3428 float trigger_interval = 10.0;
3429 getfloatfield(L, current_abm, "interval", trigger_interval);
3431 int trigger_chance = 50;
3432 getintfield(L, current_abm, "chance", trigger_chance);
3434 LuaABM *abm = new LuaABM(L, id, trigger_contents,
3435 required_neighbors, trigger_interval, trigger_chance);
3437 env->addActiveBlockModifier(abm);
3439 // removes value, keeps key for next iteration
3447 // Dump stack top with the dump2 function
3448 static void dump2(lua_State *L, const char *name)
3450 // Dump object (debug)
3451 lua_getglobal(L, "dump2");
3452 luaL_checktype(L, -1, LUA_TFUNCTION);
3453 lua_pushvalue(L, -2); // Get previous stack top as first parameter
3454 lua_pushstring(L, name);
3455 if(lua_pcall(L, 2, 0, 0))
3456 script_error(L, "error: %s", lua_tostring(L, -1));
3464 void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj)
3467 assert(lua_checkstack(L, 20));
3468 //infostream<<"scriptapi_add_object_reference: id="<<cobj->getId()<<std::endl;
3469 StackUnroller stack_unroller(L);
3471 // Create object on stack
3472 ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack
3473 int object = lua_gettop(L);
3475 // Get minetest.object_refs table
3476 lua_getglobal(L, "minetest");
3477 lua_getfield(L, -1, "object_refs");
3478 luaL_checktype(L, -1, LUA_TTABLE);
3479 int objectstable = lua_gettop(L);
3481 // object_refs[id] = object
3482 lua_pushnumber(L, cobj->getId()); // Push id
3483 lua_pushvalue(L, object); // Copy object to top of stack
3484 lua_settable(L, objectstable);
3487 void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj)
3490 assert(lua_checkstack(L, 20));
3491 //infostream<<"scriptapi_rm_object_reference: id="<<cobj->getId()<<std::endl;
3492 StackUnroller stack_unroller(L);
3494 // Get minetest.object_refs table
3495 lua_getglobal(L, "minetest");
3496 lua_getfield(L, -1, "object_refs");
3497 luaL_checktype(L, -1, LUA_TTABLE);
3498 int objectstable = lua_gettop(L);
3500 // Get object_refs[id]
3501 lua_pushnumber(L, cobj->getId()); // Push id
3502 lua_gettable(L, objectstable);
3503 // Set object reference to NULL
3504 ObjectRef::set_null(L);
3505 lua_pop(L, 1); // pop object
3507 // Set object_refs[id] = nil
3508 lua_pushnumber(L, cobj->getId()); // Push id
3510 lua_settable(L, objectstable);
3513 bool scriptapi_on_chat_message(lua_State *L, const std::string &name,
3514 const std::string &message)
3517 assert(lua_checkstack(L, 20));
3518 StackUnroller stack_unroller(L);
3520 // Get minetest.registered_on_chat_messages
3521 lua_getglobal(L, "minetest");
3522 lua_getfield(L, -1, "registered_on_chat_messages");
3523 luaL_checktype(L, -1, LUA_TTABLE);
3524 int table = lua_gettop(L);
3527 while(lua_next(L, table) != 0){
3528 // key at index -2 and value at index -1
3529 luaL_checktype(L, -1, LUA_TFUNCTION);
3531 lua_pushstring(L, name.c_str());
3532 lua_pushstring(L, message.c_str());
3533 if(lua_pcall(L, 2, 1, 0))
3534 script_error(L, "error: %s", lua_tostring(L, -1));
3535 bool ate = lua_toboolean(L, -1);
3539 // value removed, keep key for next iteration
3548 void scriptapi_on_newplayer(lua_State *L, ServerActiveObject *player)
3551 assert(lua_checkstack(L, 20));
3552 StackUnroller stack_unroller(L);
3554 // Get minetest.registered_on_newplayers
3555 lua_getglobal(L, "minetest");
3556 lua_getfield(L, -1, "registered_on_newplayers");
3557 luaL_checktype(L, -1, LUA_TTABLE);
3558 int table = lua_gettop(L);
3561 while(lua_next(L, table) != 0){
3562 // key at index -2 and value at index -1
3563 luaL_checktype(L, -1, LUA_TFUNCTION);
3565 objectref_get_or_create(L, player);
3566 if(lua_pcall(L, 1, 0, 0))
3567 script_error(L, "error: %s", lua_tostring(L, -1));
3568 // value removed, keep key for next iteration
3571 bool scriptapi_on_respawnplayer(lua_State *L, ServerActiveObject *player)
3574 assert(lua_checkstack(L, 20));
3575 StackUnroller stack_unroller(L);
3577 bool positioning_handled_by_some = false;
3579 // Get minetest.registered_on_respawnplayers
3580 lua_getglobal(L, "minetest");
3581 lua_getfield(L, -1, "registered_on_respawnplayers");
3582 luaL_checktype(L, -1, LUA_TTABLE);
3583 int table = lua_gettop(L);
3586 while(lua_next(L, table) != 0){
3587 // key at index -2 and value at index -1
3588 luaL_checktype(L, -1, LUA_TFUNCTION);
3590 objectref_get_or_create(L, player);
3591 if(lua_pcall(L, 1, 1, 0))
3592 script_error(L, "error: %s", lua_tostring(L, -1));
3593 bool positioning_handled = lua_toboolean(L, -1);
3595 if(positioning_handled)
3596 positioning_handled_by_some = true;
3597 // value removed, keep key for next iteration
3599 return positioning_handled_by_some;
3602 void scriptapi_get_creative_inventory(lua_State *L, ServerRemotePlayer *player)
3604 lua_getglobal(L, "minetest");
3605 lua_getfield(L, -1, "creative_inventory");
3606 luaL_checktype(L, -1, LUA_TTABLE);
3607 inventory_set_list_from_lua(&player->inventory, "main", L, -1,
3608 player->getEnv()->getGameDef(), PLAYER_INVENTORY_SIZE);
3615 static void pushPointedThing(lua_State *L, const PointedThing& pointed)
3618 if(pointed.type == POINTEDTHING_NODE)
3620 lua_pushstring(L, "node");
3621 lua_setfield(L, -2, "type");
3622 push_v3s16(L, pointed.node_undersurface);
3623 lua_setfield(L, -2, "under");
3624 push_v3s16(L, pointed.node_abovesurface);
3625 lua_setfield(L, -2, "above");
3627 else if(pointed.type == POINTEDTHING_OBJECT)
3629 lua_pushstring(L, "object");
3630 lua_setfield(L, -2, "type");
3631 objectref_get(L, pointed.object_id);
3632 lua_setfield(L, -2, "ref");
3636 lua_pushstring(L, "nothing");
3637 lua_setfield(L, -2, "type");
3641 void scriptapi_add_craftitem(lua_State *L, const char *name)
3643 StackUnroller stack_unroller(L);
3644 assert(lua_gettop(L) > 0);
3646 // Set minetest.registered_craftitems[name] = table on top of stack
3647 lua_getglobal(L, "minetest");
3648 lua_getfield(L, -1, "registered_craftitems");
3649 luaL_checktype(L, -1, LUA_TTABLE);
3650 lua_pushvalue(L, -3); // push another reference to the table to be registered
3651 lua_setfield(L, -2, name); // set minetest.registered_craftitems[name]
3654 static bool get_craftitem_callback(lua_State *L, const char *name,
3655 const char *callbackname)
3657 // Get minetest.registered_craftitems[name][callbackname]
3658 // If that is nil or on error, return false and stack is unchanged
3659 // If that is a function, returns true and pushes the
3660 // function onto the stack
3662 lua_getglobal(L, "minetest");
3663 lua_getfield(L, -1, "registered_craftitems");
3665 luaL_checktype(L, -1, LUA_TTABLE);
3666 lua_getfield(L, -1, name);
3668 // Should be a table
3669 if(lua_type(L, -1) != LUA_TTABLE)
3671 errorstream<<"CraftItem name \""<<name<<"\" not defined"<<std::endl;
3675 lua_getfield(L, -1, callbackname);
3677 // Should be a function or nil
3678 if(lua_type(L, -1) == LUA_TFUNCTION)
3682 else if(lua_isnil(L, -1))
3689 errorstream<<"CraftItem name \""<<name<<"\" callback \""
3690 <<callbackname<<" is not a function"<<std::endl;
3696 bool scriptapi_craftitem_on_drop(lua_State *L, const char *name,
3697 ServerActiveObject *dropper, v3f pos,
3698 bool &callback_exists)
3701 assert(lua_checkstack(L, 20));
3702 //infostream<<"scriptapi_craftitem_on_drop"<<std::endl;
3703 StackUnroller stack_unroller(L);
3705 bool result = false;
3706 callback_exists = get_craftitem_callback(L, name, "on_drop");
3710 lua_pushstring(L, name);
3711 objectref_get_or_create(L, dropper);
3712 pushFloatPos(L, pos);
3713 if(lua_pcall(L, 3, 1, 0))
3714 script_error(L, "error: %s", lua_tostring(L, -1));
3715 result = lua_toboolean(L, -1);
3720 bool scriptapi_craftitem_on_place_on_ground(lua_State *L, const char *name,
3721 ServerActiveObject *placer, v3f pos,
3722 bool &callback_exists)
3725 assert(lua_checkstack(L, 20));
3726 //infostream<<"scriptapi_craftitem_on_place_on_ground"<<std::endl;
3727 StackUnroller stack_unroller(L);
3729 bool result = false;
3730 callback_exists = get_craftitem_callback(L, name, "on_place_on_ground");
3734 lua_pushstring(L, name);
3735 objectref_get_or_create(L, placer);
3736 pushFloatPos(L, pos);
3737 if(lua_pcall(L, 3, 1, 0))
3738 script_error(L, "error: %s", lua_tostring(L, -1));
3739 result = lua_toboolean(L, -1);
3744 bool scriptapi_craftitem_on_use(lua_State *L, const char *name,
3745 ServerActiveObject *user, const PointedThing& pointed,
3746 bool &callback_exists)
3749 assert(lua_checkstack(L, 20));
3750 //infostream<<"scriptapi_craftitem_on_use"<<std::endl;
3751 StackUnroller stack_unroller(L);
3753 bool result = false;
3754 callback_exists = get_craftitem_callback(L, name, "on_use");
3758 lua_pushstring(L, name);
3759 objectref_get_or_create(L, user);
3760 pushPointedThing(L, pointed);
3761 if(lua_pcall(L, 3, 1, 0))
3762 script_error(L, "error: %s", lua_tostring(L, -1));
3763 result = lua_toboolean(L, -1);
3772 void scriptapi_environment_step(lua_State *L, float dtime)
3775 assert(lua_checkstack(L, 20));
3776 //infostream<<"scriptapi_environment_step"<<std::endl;
3777 StackUnroller stack_unroller(L);
3779 // Get minetest.registered_globalsteps
3780 lua_getglobal(L, "minetest");
3781 lua_getfield(L, -1, "registered_globalsteps");
3782 luaL_checktype(L, -1, LUA_TTABLE);
3783 int table = lua_gettop(L);
3786 while(lua_next(L, table) != 0){
3787 // key at index -2 and value at index -1
3788 luaL_checktype(L, -1, LUA_TFUNCTION);
3790 lua_pushnumber(L, dtime);
3791 if(lua_pcall(L, 1, 0, 0))
3792 script_error(L, "error: %s", lua_tostring(L, -1));
3793 // value removed, keep key for next iteration
3797 void scriptapi_environment_on_placenode(lua_State *L, v3s16 p, MapNode newnode,
3798 ServerActiveObject *placer)
3801 assert(lua_checkstack(L, 20));
3802 //infostream<<"scriptapi_environment_on_placenode"<<std::endl;
3803 StackUnroller stack_unroller(L);
3805 // Get the writable node definition manager from the server
3806 IWritableNodeDefManager *ndef =
3807 get_server(L)->getWritableNodeDefManager();
3809 // Get minetest.registered_on_placenodes
3810 lua_getglobal(L, "minetest");
3811 lua_getfield(L, -1, "registered_on_placenodes");
3812 luaL_checktype(L, -1, LUA_TTABLE);
3813 int table = lua_gettop(L);
3816 while(lua_next(L, table) != 0){
3817 // key at index -2 and value at index -1
3818 luaL_checktype(L, -1, LUA_TFUNCTION);
3821 pushnode(L, newnode, ndef);
3822 objectref_get_or_create(L, placer);
3823 if(lua_pcall(L, 3, 0, 0))
3824 script_error(L, "error: %s", lua_tostring(L, -1));
3825 // value removed, keep key for next iteration
3829 void scriptapi_environment_on_dignode(lua_State *L, v3s16 p, MapNode oldnode,
3830 ServerActiveObject *digger)
3833 assert(lua_checkstack(L, 20));
3834 //infostream<<"scriptapi_environment_on_dignode"<<std::endl;
3835 StackUnroller stack_unroller(L);
3837 // Get the writable node definition manager from the server
3838 IWritableNodeDefManager *ndef =
3839 get_server(L)->getWritableNodeDefManager();
3841 // Get minetest.registered_on_dignodes
3842 lua_getglobal(L, "minetest");
3843 lua_getfield(L, -1, "registered_on_dignodes");
3844 luaL_checktype(L, -1, LUA_TTABLE);
3845 int table = lua_gettop(L);
3848 while(lua_next(L, table) != 0){
3849 // key at index -2 and value at index -1
3850 luaL_checktype(L, -1, LUA_TFUNCTION);
3853 pushnode(L, oldnode, ndef);
3854 objectref_get_or_create(L, digger);
3855 if(lua_pcall(L, 3, 0, 0))
3856 script_error(L, "error: %s", lua_tostring(L, -1));
3857 // value removed, keep key for next iteration
3861 void scriptapi_environment_on_punchnode(lua_State *L, v3s16 p, MapNode node,
3862 ServerActiveObject *puncher)
3865 assert(lua_checkstack(L, 20));
3866 //infostream<<"scriptapi_environment_on_punchnode"<<std::endl;
3867 StackUnroller stack_unroller(L);
3869 // Get the writable node definition manager from the server
3870 IWritableNodeDefManager *ndef =
3871 get_server(L)->getWritableNodeDefManager();
3873 // Get minetest.registered_on_punchnodes
3874 lua_getglobal(L, "minetest");
3875 lua_getfield(L, -1, "registered_on_punchnodes");
3876 luaL_checktype(L, -1, LUA_TTABLE);
3877 int table = lua_gettop(L);
3880 while(lua_next(L, table) != 0){
3881 // key at index -2 and value at index -1
3882 luaL_checktype(L, -1, LUA_TFUNCTION);
3885 pushnode(L, node, ndef);
3886 objectref_get_or_create(L, puncher);
3887 if(lua_pcall(L, 3, 0, 0))
3888 script_error(L, "error: %s", lua_tostring(L, -1));
3889 // value removed, keep key for next iteration
3893 void scriptapi_environment_on_generated(lua_State *L, v3s16 minp, v3s16 maxp)
3896 assert(lua_checkstack(L, 20));
3897 //infostream<<"scriptapi_environment_on_generated"<<std::endl;
3898 StackUnroller stack_unroller(L);
3900 // Get minetest.registered_on_generateds
3901 lua_getglobal(L, "minetest");
3902 lua_getfield(L, -1, "registered_on_generateds");
3903 luaL_checktype(L, -1, LUA_TTABLE);
3904 int table = lua_gettop(L);
3907 while(lua_next(L, table) != 0){
3908 // key at index -2 and value at index -1
3909 luaL_checktype(L, -1, LUA_TFUNCTION);
3911 push_v3s16(L, minp);
3912 push_v3s16(L, maxp);
3913 if(lua_pcall(L, 2, 0, 0))
3914 script_error(L, "error: %s", lua_tostring(L, -1));
3915 // value removed, keep key for next iteration
3923 bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
3924 const std::string &staticdata)
3927 assert(lua_checkstack(L, 20));
3928 infostream<<"scriptapi_luaentity_add: id="<<id<<" name=\""
3929 <<name<<"\""<<std::endl;
3930 StackUnroller stack_unroller(L);
3932 // Get minetest.registered_entities[name]
3933 lua_getglobal(L, "minetest");
3934 lua_getfield(L, -1, "registered_entities");
3935 luaL_checktype(L, -1, LUA_TTABLE);
3936 lua_pushstring(L, name);
3937 lua_gettable(L, -2);
3938 // Should be a table, which we will use as a prototype
3939 //luaL_checktype(L, -1, LUA_TTABLE);
3940 if(lua_type(L, -1) != LUA_TTABLE){
3941 errorstream<<"LuaEntity name \""<<name<<"\" not defined"<<std::endl;
3944 int prototype_table = lua_gettop(L);
3945 //dump2(L, "prototype_table");
3947 // Create entity object
3949 int object = lua_gettop(L);
3951 // Set object metatable
3952 lua_pushvalue(L, prototype_table);
3953 lua_setmetatable(L, -2);
3955 // Add object reference
3956 // This should be userdata with metatable ObjectRef
3957 objectref_get(L, id);
3958 luaL_checktype(L, -1, LUA_TUSERDATA);
3959 if(!luaL_checkudata(L, -1, "ObjectRef"))
3960 luaL_typerror(L, -1, "ObjectRef");
3961 lua_setfield(L, -2, "object");
3963 // minetest.luaentities[id] = object
3964 lua_getglobal(L, "minetest");
3965 lua_getfield(L, -1, "luaentities");
3966 luaL_checktype(L, -1, LUA_TTABLE);
3967 lua_pushnumber(L, id); // Push id
3968 lua_pushvalue(L, object); // Copy object to top of stack
3969 lua_settable(L, -3);
3971 // Get on_activate function
3972 lua_pushvalue(L, object);
3973 lua_getfield(L, -1, "on_activate");
3974 if(!lua_isnil(L, -1)){
3975 luaL_checktype(L, -1, LUA_TFUNCTION);
3976 lua_pushvalue(L, object); // self
3977 lua_pushlstring(L, staticdata.c_str(), staticdata.size());
3978 // Call with 2 arguments, 0 results
3979 if(lua_pcall(L, 2, 0, 0))
3980 script_error(L, "error running function %s:on_activate: %s\n",
3981 name, lua_tostring(L, -1));
3987 void scriptapi_luaentity_rm(lua_State *L, u16 id)
3990 assert(lua_checkstack(L, 20));
3991 infostream<<"scriptapi_luaentity_rm: id="<<id<<std::endl;
3993 // Get minetest.luaentities table
3994 lua_getglobal(L, "minetest");
3995 lua_getfield(L, -1, "luaentities");
3996 luaL_checktype(L, -1, LUA_TTABLE);
3997 int objectstable = lua_gettop(L);
3999 // Set luaentities[id] = nil
4000 lua_pushnumber(L, id); // Push id
4002 lua_settable(L, objectstable);
4004 lua_pop(L, 2); // pop luaentities, minetest
4007 std::string scriptapi_luaentity_get_staticdata(lua_State *L, u16 id)
4010 assert(lua_checkstack(L, 20));
4011 infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl;
4012 StackUnroller stack_unroller(L);
4014 // Get minetest.luaentities[id]
4015 luaentity_get(L, id);
4016 int object = lua_gettop(L);
4018 // Get get_staticdata function
4019 lua_pushvalue(L, object);
4020 lua_getfield(L, -1, "get_staticdata");
4021 if(lua_isnil(L, -1))
4024 luaL_checktype(L, -1, LUA_TFUNCTION);
4025 lua_pushvalue(L, object); // self
4026 // Call with 1 arguments, 1 results
4027 if(lua_pcall(L, 1, 1, 0))
4028 script_error(L, "error running function get_staticdata: %s\n",
4029 lua_tostring(L, -1));
4032 const char *s = lua_tolstring(L, -1, &len);
4033 return std::string(s, len);
4036 void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
4037 LuaEntityProperties *prop)
4040 assert(lua_checkstack(L, 20));
4041 infostream<<"scriptapi_luaentity_get_properties: id="<<id<<std::endl;
4042 StackUnroller stack_unroller(L);
4044 // Get minetest.luaentities[id]
4045 luaentity_get(L, id);
4046 //int object = lua_gettop(L);
4050 getboolfield(L, -1, "physical", prop->physical);
4052 getfloatfield(L, -1, "weight", prop->weight);
4054 lua_getfield(L, -1, "collisionbox");
4055 if(lua_istable(L, -1))
4056 prop->collisionbox = read_aabbox3df32(L, -1, 1.0);
4059 getstringfield(L, -1, "visual", prop->visual);
4061 lua_getfield(L, -1, "visual_size");
4062 if(lua_istable(L, -1))
4063 prop->visual_size = read_v2f(L, -1);
4066 lua_getfield(L, -1, "textures");
4067 if(lua_istable(L, -1)){
4068 prop->textures.clear();
4069 int table = lua_gettop(L);
4071 while(lua_next(L, table) != 0){
4072 // key at index -2 and value at index -1
4073 if(lua_isstring(L, -1))
4074 prop->textures.push_back(lua_tostring(L, -1));
4076 prop->textures.push_back("");
4077 // removes value, keeps key for next iteration
4083 lua_getfield(L, -1, "spritediv");
4084 if(lua_istable(L, -1))
4085 prop->spritediv = read_v2s16(L, -1);
4088 lua_getfield(L, -1, "initial_sprite_basepos");
4089 if(lua_istable(L, -1))
4090 prop->initial_sprite_basepos = read_v2s16(L, -1);
4094 void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime)
4097 assert(lua_checkstack(L, 20));
4098 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
4099 StackUnroller stack_unroller(L);
4101 // Get minetest.luaentities[id]
4102 luaentity_get(L, id);
4103 int object = lua_gettop(L);
4104 // State: object is at top of stack
4105 // Get step function
4106 lua_getfield(L, -1, "on_step");
4107 if(lua_isnil(L, -1))
4109 luaL_checktype(L, -1, LUA_TFUNCTION);
4110 lua_pushvalue(L, object); // self
4111 lua_pushnumber(L, dtime); // dtime
4112 // Call with 2 arguments, 0 results
4113 if(lua_pcall(L, 2, 0, 0))
4114 script_error(L, "error running function 'on_step': %s\n", lua_tostring(L, -1));
4117 // Calls entity:on_punch(ObjectRef puncher, time_from_last_punch)
4118 void scriptapi_luaentity_punch(lua_State *L, u16 id,
4119 ServerActiveObject *puncher, float time_from_last_punch)
4122 assert(lua_checkstack(L, 20));
4123 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
4124 StackUnroller stack_unroller(L);
4126 // Get minetest.luaentities[id]
4127 luaentity_get(L, id);
4128 int object = lua_gettop(L);
4129 // State: object is at top of stack
4131 lua_getfield(L, -1, "on_punch");
4132 if(lua_isnil(L, -1))
4134 luaL_checktype(L, -1, LUA_TFUNCTION);
4135 lua_pushvalue(L, object); // self
4136 objectref_get_or_create(L, puncher); // Clicker reference
4137 lua_pushnumber(L, time_from_last_punch);
4138 // Call with 2 arguments, 0 results
4139 if(lua_pcall(L, 3, 0, 0))
4140 script_error(L, "error running function 'on_punch': %s\n", lua_tostring(L, -1));
4143 // Calls entity:on_rightclick(ObjectRef clicker)
4144 void scriptapi_luaentity_rightclick(lua_State *L, u16 id,
4145 ServerActiveObject *clicker)
4148 assert(lua_checkstack(L, 20));
4149 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
4150 StackUnroller stack_unroller(L);
4152 // Get minetest.luaentities[id]
4153 luaentity_get(L, id);
4154 int object = lua_gettop(L);
4155 // State: object is at top of stack
4157 lua_getfield(L, -1, "on_rightclick");
4158 if(lua_isnil(L, -1))
4160 luaL_checktype(L, -1, LUA_TFUNCTION);
4161 lua_pushvalue(L, object); // self
4162 objectref_get_or_create(L, clicker); // Clicker reference
4163 // Call with 2 arguments, 0 results
4164 if(lua_pcall(L, 2, 0, 0))
4165 script_error(L, "error running function 'on_rightclick': %s\n", lua_tostring(L, -1));