3 Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "scriptapi.h"
34 #include "serverobject.h"
37 #include "luaentity_common.h"
38 #include "content_sao.h" // For LuaEntitySAO
42 #include "craftitemdef.h"
43 #include "main.h" // For g_settings
44 #include "settings.h" // For accessing g_settings
45 #include "nodemetadata.h"
46 #include "mapblock.h" // For getNodeBlockPos
47 #include "content_nodemeta.h"
50 static void stackDump(lua_State *L, std::ostream &o)
53 int top = lua_gettop(L);
54 for (i = 1; i <= top; i++) { /* repeat for each level */
55 int t = lua_type(L, i);
58 case LUA_TSTRING: /* strings */
59 o<<"\""<<lua_tostring(L, i)<<"\"";
62 case LUA_TBOOLEAN: /* booleans */
63 o<<(lua_toboolean(L, i) ? "true" : "false");
66 case LUA_TNUMBER: /* numbers */ {
68 snprintf(buf, 10, "%g", lua_tonumber(L, i));
72 default: /* other values */
73 o<<lua_typename(L, t);
82 static void realitycheck(lua_State *L)
84 int top = lua_gettop(L);
86 dstream<<"Stack is over 30:"<<std::endl;
87 stackDump(L, dstream);
88 script_error(L, "Stack is over 30 (reality check)");
98 StackUnroller(lua_State *L):
102 m_original_top = lua_gettop(m_lua); // store stack height
106 lua_settop(m_lua, m_original_top); // restore stack height
110 static v3f readFloatPos(lua_State *L, int index)
113 luaL_checktype(L, index, LUA_TTABLE);
114 lua_getfield(L, index, "x");
115 pos.X = lua_tonumber(L, -1);
117 lua_getfield(L, index, "y");
118 pos.Y = lua_tonumber(L, -1);
120 lua_getfield(L, index, "z");
121 pos.Z = lua_tonumber(L, -1);
123 pos *= BS; // Scale to internal format
127 static void pushFloatPos(lua_State *L, v3f p)
131 lua_pushnumber(L, p.X);
132 lua_setfield(L, -2, "x");
133 lua_pushnumber(L, p.Y);
134 lua_setfield(L, -2, "y");
135 lua_pushnumber(L, p.Z);
136 lua_setfield(L, -2, "z");
139 static void pushpos(lua_State *L, v3s16 p)
142 lua_pushnumber(L, p.X);
143 lua_setfield(L, -2, "x");
144 lua_pushnumber(L, p.Y);
145 lua_setfield(L, -2, "y");
146 lua_pushnumber(L, p.Z);
147 lua_setfield(L, -2, "z");
150 static v3s16 readpos(lua_State *L, int index)
152 // Correct rounding at <0
153 v3f pf = readFloatPos(L, index);
154 return floatToInt(pf, BS);
157 static void pushnode(lua_State *L, const MapNode &n, INodeDefManager *ndef)
160 lua_pushstring(L, ndef->get(n).name.c_str());
161 lua_setfield(L, -2, "name");
162 lua_pushnumber(L, n.getParam1());
163 lua_setfield(L, -2, "param1");
164 lua_pushnumber(L, n.getParam2());
165 lua_setfield(L, -2, "param2");
168 static MapNode readnode(lua_State *L, int index, INodeDefManager *ndef)
170 lua_getfield(L, index, "name");
171 const char *name = lua_tostring(L, -1);
174 lua_getfield(L, index, "param1");
178 param1 = lua_tonumber(L, -1);
181 lua_getfield(L, index, "param2");
185 param2 = lua_tonumber(L, -1);
187 return MapNode(ndef, name, param1, param2);
190 static video::SColor readARGB8(lua_State *L, int index)
193 luaL_checktype(L, index, LUA_TTABLE);
194 lua_getfield(L, index, "a");
195 if(lua_isnumber(L, -1))
196 color.setAlpha(lua_tonumber(L, -1));
198 lua_getfield(L, index, "r");
199 color.setRed(lua_tonumber(L, -1));
201 lua_getfield(L, index, "g");
202 color.setGreen(lua_tonumber(L, -1));
204 lua_getfield(L, index, "b");
205 color.setBlue(lua_tonumber(L, -1));
210 static core::aabbox3d<f32> read_aabbox3df32(lua_State *L, int index, f32 scale)
212 core::aabbox3d<f32> box;
213 if(lua_istable(L, -1)){
214 lua_rawgeti(L, -1, 1);
215 box.MinEdge.X = lua_tonumber(L, -1) * scale;
217 lua_rawgeti(L, -1, 2);
218 box.MinEdge.Y = lua_tonumber(L, -1) * scale;
220 lua_rawgeti(L, -1, 3);
221 box.MinEdge.Z = lua_tonumber(L, -1) * scale;
223 lua_rawgeti(L, -1, 4);
224 box.MaxEdge.X = lua_tonumber(L, -1) * scale;
226 lua_rawgeti(L, -1, 5);
227 box.MaxEdge.Y = lua_tonumber(L, -1) * scale;
229 lua_rawgeti(L, -1, 6);
230 box.MaxEdge.Z = lua_tonumber(L, -1) * scale;
236 static v2s16 read_v2s16(lua_State *L, int index)
239 luaL_checktype(L, index, LUA_TTABLE);
240 lua_getfield(L, index, "x");
241 p.X = lua_tonumber(L, -1);
243 lua_getfield(L, index, "y");
244 p.Y = lua_tonumber(L, -1);
249 static v2f read_v2f(lua_State *L, int index)
252 luaL_checktype(L, index, LUA_TTABLE);
253 lua_getfield(L, index, "x");
254 p.X = lua_tonumber(L, -1);
256 lua_getfield(L, index, "y");
257 p.Y = lua_tonumber(L, -1);
262 static bool getstringfield(lua_State *L, int table,
263 const char *fieldname, std::string &result)
265 lua_getfield(L, table, fieldname);
267 if(lua_isstring(L, -1)){
268 result = lua_tostring(L, -1);
275 static bool getintfield(lua_State *L, int table,
276 const char *fieldname, int &result)
278 lua_getfield(L, table, fieldname);
280 if(lua_isnumber(L, -1)){
281 result = lua_tonumber(L, -1);
288 static bool getfloatfield(lua_State *L, int table,
289 const char *fieldname, float &result)
291 lua_getfield(L, table, fieldname);
293 if(lua_isnumber(L, -1)){
294 result = lua_tonumber(L, -1);
301 static bool getboolfield(lua_State *L, int table,
302 const char *fieldname, bool &result)
304 lua_getfield(L, table, fieldname);
306 if(lua_isboolean(L, -1)){
307 result = lua_toboolean(L, -1);
314 static std::string getstringfield_default(lua_State *L, int table,
315 const char *fieldname, const std::string &default_)
317 std::string result = default_;
318 getstringfield(L, table, fieldname, result);
322 static int getintfield_default(lua_State *L, int table,
323 const char *fieldname, int default_)
325 int result = default_;
326 getintfield(L, table, fieldname, result);
330 /*static float getfloatfield_default(lua_State *L, int table,
331 const char *fieldname, float default_)
333 float result = default_;
334 getfloatfield(L, table, fieldname, result);
338 static bool getboolfield_default(lua_State *L, int table,
339 const char *fieldname, bool default_)
341 bool result = default_;
342 getboolfield(L, table, fieldname, result);
352 static bool string_to_enum(const EnumString *spec, int &result,
353 const std::string &str)
355 const EnumString *esp = spec;
357 if(str == std::string(esp->str)){
366 /*static bool enum_to_string(const EnumString *spec, std::string &result,
369 const EnumString *esp = spec;
380 static int getenumfield(lua_State *L, int table,
381 const char *fieldname, const EnumString *spec, int default_)
383 int result = default_;
384 string_to_enum(spec, result,
385 getstringfield_default(L, table, fieldname, ""));
393 static void inventory_set_list_from_lua(Inventory *inv, const char *name,
394 lua_State *L, int tableindex, IGameDef *gamedef)
396 // If nil, delete list
397 if(lua_isnil(L, tableindex)){
398 inv->deleteList(name);
401 // Otherwise set list
402 std::list<std::string> items;
403 luaL_checktype(L, tableindex, LUA_TTABLE);
404 int table = tableindex;
406 while(lua_next(L, table) != 0){
407 // key at index -2 and value at index -1
408 luaL_checktype(L, -1, LUA_TSTRING);
409 std::string itemstring = lua_tostring(L, -1);
410 items.push_back(itemstring);
411 // removes value, keeps key for next iteration
414 InventoryList *invlist = inv->addList(name, items.size());
416 for(std::list<std::string>::const_iterator
417 i = items.begin(); i != items.end(); i++){
418 const std::string &itemstring = *i;
419 InventoryItem *newitem = NULL;
421 newitem = InventoryItem::deSerialize(itemstring,
423 InventoryItem *olditem = invlist->changeItem(index, newitem);
429 static void inventory_get_list_to_lua(Inventory *inv, const char *name,
432 InventoryList *invlist = inv->getList(name);
437 // Get the table insert function
438 lua_getglobal(L, "table");
439 lua_getfield(L, -1, "insert");
440 int table_insert = lua_gettop(L);
441 // Create and fill table
443 int table = lua_gettop(L);
444 for(u32 i=0; i<invlist->getSize(); i++){
445 InventoryItem *item = invlist->getItem(i);
446 lua_pushvalue(L, table_insert);
447 lua_pushvalue(L, table);
451 lua_pushstring(L, item->getItemString().c_str());
453 if(lua_pcall(L, 2, 0, 0))
454 script_error(L, "error: %s\n", lua_tostring(L, -1));
459 EnumString definitions
462 struct EnumString es_DrawType[] =
464 {NDT_NORMAL, "normal"},
465 {NDT_AIRLIKE, "airlike"},
466 {NDT_LIQUID, "liquid"},
467 {NDT_FLOWINGLIQUID, "flowingliquid"},
468 {NDT_GLASSLIKE, "glasslike"},
469 {NDT_ALLFACES, "allfaces"},
470 {NDT_ALLFACES_OPTIONAL, "allfaces_optional"},
471 {NDT_TORCHLIKE, "torchlike"},
472 {NDT_SIGNLIKE, "signlike"},
473 {NDT_PLANTLIKE, "plantlike"},
474 {NDT_FENCELIKE, "fencelike"},
475 {NDT_RAILLIKE, "raillike"},
479 struct EnumString es_ContentParamType[] =
482 {CPT_LIGHT, "light"},
483 {CPT_MINERAL, "mineral"},
484 {CPT_FACEDIR_SIMPLE, "facedir_simple"},
488 struct EnumString es_LiquidType[] =
490 {LIQUID_NONE, "none"},
491 {LIQUID_FLOWING, "flowing"},
492 {LIQUID_SOURCE, "source"},
496 struct EnumString es_NodeBoxType[] =
498 {NODEBOX_REGULAR, "regular"},
499 {NODEBOX_FIXED, "fixed"},
500 {NODEBOX_WALLMOUNTED, "wallmounted"},
504 struct EnumString es_Diggability[] =
506 {DIGGABLE_NOT, "not"},
507 {DIGGABLE_NORMAL, "normal"},
508 {DIGGABLE_CONSTANT, "constant"},
516 static int l_register_nodedef_defaults(lua_State *L)
518 luaL_checktype(L, 1, LUA_TTABLE);
520 lua_pushvalue(L, 1); // Explicitly put parameter 1 on top of stack
521 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
526 // Register new object prototype
527 // register_entity(name, prototype)
528 static int l_register_entity(lua_State *L)
530 const char *name = luaL_checkstring(L, 1);
531 infostream<<"register_entity: "<<name<<std::endl;
532 luaL_checktype(L, 2, LUA_TTABLE);
534 // Get minetest.registered_entities
535 lua_getglobal(L, "minetest");
536 lua_getfield(L, -1, "registered_entities");
537 luaL_checktype(L, -1, LUA_TTABLE);
538 int registered_entities = lua_gettop(L);
539 lua_pushvalue(L, 2); // Object = param 2 -> stack top
540 // registered_entities[name] = object
541 lua_setfield(L, registered_entities, name);
543 // Get registered object to top of stack
546 // Set __index to point to itself
547 lua_pushvalue(L, -1);
548 lua_setfield(L, -2, "__index");
550 // Set metatable.__index = metatable
551 luaL_getmetatable(L, "minetest.entity");
552 lua_pushvalue(L, -1); // duplicate metatable
553 lua_setfield(L, -2, "__index");
554 // Set object metatable
555 lua_setmetatable(L, -2);
557 return 0; /* number of results */
560 class LuaABM : public ActiveBlockModifier
566 std::set<std::string> m_trigger_contents;
567 float m_trigger_interval;
568 u32 m_trigger_chance;
570 LuaABM(lua_State *L, int id,
571 const std::set<std::string> &trigger_contents,
572 float trigger_interval, u32 trigger_chance):
575 m_trigger_contents(trigger_contents),
576 m_trigger_interval(trigger_interval),
577 m_trigger_chance(trigger_chance)
580 virtual std::set<std::string> getTriggerContents()
582 return m_trigger_contents;
584 virtual float getTriggerInterval()
586 return m_trigger_interval;
588 virtual u32 getTriggerChance()
590 return m_trigger_chance;
592 virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n,
593 u32 active_object_count, u32 active_object_count_wider)
595 lua_State *L = m_lua;
598 assert(lua_checkstack(L, 20));
599 StackUnroller stack_unroller(L);
601 // Get minetest.registered_abms
602 lua_getglobal(L, "minetest");
603 lua_getfield(L, -1, "registered_abms");
604 luaL_checktype(L, -1, LUA_TTABLE);
605 int registered_abms = lua_gettop(L);
607 // Get minetest.registered_abms[m_id]
608 lua_pushnumber(L, m_id);
609 lua_gettable(L, registered_abms);
614 luaL_checktype(L, -1, LUA_TTABLE);
615 lua_getfield(L, -1, "action");
616 luaL_checktype(L, -1, LUA_TFUNCTION);
618 pushnode(L, n, env->getGameDef()->ndef());
619 lua_pushnumber(L, active_object_count);
620 lua_pushnumber(L, active_object_count_wider);
621 if(lua_pcall(L, 4, 0, 0))
622 script_error(L, "error: %s\n", lua_tostring(L, -1));
626 // register_abm({...})
627 static int l_register_abm(lua_State *L)
629 infostream<<"register_abm"<<std::endl;
630 luaL_checktype(L, 1, LUA_TTABLE);
632 // Get minetest.registered_abms
633 lua_getglobal(L, "minetest");
634 lua_getfield(L, -1, "registered_abms");
635 luaL_checktype(L, -1, LUA_TTABLE);
636 int registered_abms = lua_gettop(L);
641 lua_pushnumber(L, id);
642 lua_gettable(L, registered_abms);
650 infostream<<"register_abm: id="<<id<<std::endl;
652 // registered_abms[id] = spec
653 lua_pushnumber(L, id);
655 lua_settable(L, registered_abms);
657 return 0; /* number of results */
660 // register_tool(name, {lots of stuff})
661 static int l_register_tool(lua_State *L)
663 const char *name = luaL_checkstring(L, 1);
664 infostream<<"register_tool: "<<name<<std::endl;
665 luaL_checktype(L, 2, LUA_TTABLE);
668 // Get server from registry
669 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
670 Server *server = (Server*)lua_touserdata(L, -1);
671 // And get the writable tool definition manager from the server
672 IWritableToolDefManager *tooldef =
673 server->getWritableToolDefManager();
677 getstringfield(L, table, "image", def.imagename);
678 getfloatfield(L, table, "basetime", def.properties.basetime);
679 getfloatfield(L, table, "dt_weight", def.properties.dt_weight);
680 getfloatfield(L, table, "dt_crackiness", def.properties.dt_crackiness);
681 getfloatfield(L, table, "dt_crumbliness", def.properties.dt_crumbliness);
682 getfloatfield(L, table, "dt_cuttability", def.properties.dt_cuttability);
683 getfloatfield(L, table, "basedurability", def.properties.basedurability);
684 getfloatfield(L, table, "dd_weight", def.properties.dd_weight);
685 getfloatfield(L, table, "dd_crackiness", def.properties.dd_crackiness);
686 getfloatfield(L, table, "dd_crumbliness", def.properties.dd_crumbliness);
687 getfloatfield(L, table, "dd_cuttability", def.properties.dd_cuttability);
689 tooldef->registerTool(name, def);
690 return 0; /* number of results */
693 // register_craftitem(name, {lots of stuff})
694 static int l_register_craftitem(lua_State *L)
696 const char *name = luaL_checkstring(L, 1);
697 infostream<<"register_craftitem: "<<name<<std::endl;
698 luaL_checktype(L, 2, LUA_TTABLE);
701 // Get server from registry
702 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
703 Server *server = (Server*)lua_touserdata(L, -1);
704 // And get the writable CraftItem definition manager from the server
705 IWritableCraftItemDefManager *craftitemdef =
706 server->getWritableCraftItemDefManager();
708 // Check if on_drop is defined
709 lua_getfield(L, table, "on_drop");
710 bool got_on_drop = !lua_isnil(L, -1);
713 // Check if on_use is defined
714 lua_getfield(L, table, "on_use");
715 bool got_on_use = !lua_isnil(L, -1);
718 CraftItemDefinition def;
720 getstringfield(L, table, "image", def.imagename);
721 getstringfield(L, table, "cookresult_item", def.cookresult_item);
722 getfloatfield(L, table, "furnace_cooktime", def.furnace_cooktime);
723 getfloatfield(L, table, "furnace_burntime", def.furnace_burntime);
724 def.usable = getboolfield_default(L, table, "usable", got_on_use);
725 getboolfield(L, table, "liquids_pointable", def.liquids_pointable);
726 def.dropcount = getintfield_default(L, table, "dropcount", def.dropcount);
727 def.stack_max = getintfield_default(L, table, "stack_max", def.stack_max);
729 // If an on_drop callback is defined, force dropcount to 1
734 craftitemdef->registerCraftItem(name, def);
736 lua_pushvalue(L, table);
737 scriptapi_add_craftitem(L, name);
739 return 0; /* number of results */
742 // register_node(name, {lots of stuff})
743 static int l_register_node(lua_State *L)
745 const char *name = luaL_checkstring(L, 1);
746 infostream<<"register_node: "<<name<<std::endl;
747 luaL_checktype(L, 2, LUA_TTABLE);
748 int nodedef_table = 2;
750 // Get server from registry
751 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
752 Server *server = (Server*)lua_touserdata(L, -1);
753 // And get the writable node definition manager from the server
754 IWritableNodeDefManager *nodedef =
755 server->getWritableNodeDefManager();
757 // Get default node definition from registry
758 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
759 int nodedef_default = lua_gettop(L);
762 Add to minetest.registered_nodes with default as metatable
765 // Get the node definition table given as parameter
766 lua_pushvalue(L, nodedef_table);
768 // Set __index to point to itself
769 lua_pushvalue(L, -1);
770 lua_setfield(L, -2, "__index");
772 // Set nodedef_default as metatable for the definition
773 lua_pushvalue(L, nodedef_default);
774 lua_setmetatable(L, nodedef_table);
776 // minetest.registered_nodes[name] = nodedef
777 lua_getglobal(L, "minetest");
778 lua_getfield(L, -1, "registered_nodes");
779 luaL_checktype(L, -1, LUA_TTABLE);
780 lua_pushstring(L, name);
781 lua_pushvalue(L, nodedef_table);
790 // Default to getting the corresponding NodeItem when dug
791 f.dug_item = std::string("NodeItem \"")+name+"\" 1";
793 // Default to unknown_block.png as all textures
794 f.setAllTextures("unknown_block.png");
797 Read definiton from Lua
802 /* Visual definition */
804 f.drawtype = (NodeDrawType)getenumfield(L, nodedef_table, "drawtype", es_DrawType,
806 getfloatfield(L, nodedef_table, "visual_scale", f.visual_scale);
808 lua_getfield(L, nodedef_table, "tile_images");
809 if(lua_istable(L, -1)){
810 int table = lua_gettop(L);
813 while(lua_next(L, table) != 0){
814 // key at index -2 and value at index -1
815 if(lua_isstring(L, -1))
816 f.tname_tiles[i] = lua_tostring(L, -1);
818 f.tname_tiles[i] = "";
819 // removes value, keeps key for next iteration
827 // Copy last value to all remaining textures
829 std::string lastname = f.tname_tiles[i-1];
831 f.tname_tiles[i] = lastname;
838 getstringfield(L, nodedef_table, "inventory_image", f.tname_inventory);
840 lua_getfield(L, nodedef_table, "special_materials");
841 if(lua_istable(L, -1)){
842 int table = lua_gettop(L);
845 while(lua_next(L, table) != 0){
846 // key at index -2 and value at index -1
847 int smtable = lua_gettop(L);
848 std::string tname = getstringfield_default(
849 L, smtable, "image", "");
850 bool backface_culling = getboolfield_default(
851 L, smtable, "backface_culling", true);
852 MaterialSpec mspec(tname, backface_culling);
853 f.setSpecialMaterial(i, mspec);
854 // removes value, keeps key for next iteration
865 f.alpha = getintfield_default(L, nodedef_table, "alpha", 255);
869 lua_getfield(L, nodedef_table, "post_effect_color");
870 if(!lua_isnil(L, -1))
871 f.post_effect_color = readARGB8(L, -1);
874 f.param_type = (ContentParamType)getenumfield(L, nodedef_table, "paramtype",
875 es_ContentParamType, CPT_NONE);
877 // True for all ground-like things like stone and mud, false for eg. trees
878 getboolfield(L, nodedef_table, "is_ground_content", f.is_ground_content);
879 getboolfield(L, nodedef_table, "light_propagates", f.light_propagates);
880 getboolfield(L, nodedef_table, "sunlight_propagates", f.sunlight_propagates);
881 // This is used for collision detection.
882 // Also for general solidness queries.
883 getboolfield(L, nodedef_table, "walkable", f.walkable);
884 // Player can point to these
885 getboolfield(L, nodedef_table, "pointable", f.pointable);
886 // Player can dig these
887 getboolfield(L, nodedef_table, "diggable", f.diggable);
888 // Player can climb these
889 getboolfield(L, nodedef_table, "climbable", f.climbable);
890 // Player can build on these
891 getboolfield(L, nodedef_table, "buildable_to", f.buildable_to);
892 // If true, param2 is set to direction when placed. Used for torches.
893 // NOTE: the direction format is quite inefficient and should be changed
894 getboolfield(L, nodedef_table, "wall_mounted", f.wall_mounted);
895 // Whether this content type often contains mineral.
896 // Used for texture atlas creation.
897 // Currently only enabled for CONTENT_STONE.
898 getboolfield(L, nodedef_table, "often_contains_mineral", f.often_contains_mineral);
899 // Inventory item string as which the node appears in inventory when dug.
900 // Mineral overrides this.
901 getstringfield(L, nodedef_table, "dug_item", f.dug_item);
902 // Extra dug item and its rarity
903 getstringfield(L, nodedef_table, "extra_dug_item", f.extra_dug_item);
904 // Usual get interval for extra dug item
905 getintfield(L, nodedef_table, "extra_dug_item_rarity", f.extra_dug_item_rarity);
906 // Metadata name of node (eg. "furnace")
907 getstringfield(L, nodedef_table, "metadata_name", f.metadata_name);
908 // Whether the node is non-liquid, source liquid or flowing liquid
909 f.liquid_type = (LiquidType)getenumfield(L, nodedef_table, "liquidtype",
910 es_LiquidType, LIQUID_NONE);
911 // If the content is liquid, this is the flowing version of the liquid.
912 getstringfield(L, nodedef_table, "liquid_alternative_flowing",
913 f.liquid_alternative_flowing);
914 // If the content is liquid, this is the source version of the liquid.
915 getstringfield(L, nodedef_table, "liquid_alternative_source",
916 f.liquid_alternative_source);
917 // Viscosity for fluid flow, ranging from 1 to 7, with
918 // 1 giving almost instantaneous propagation and 7 being
919 // the slowest possible
920 f.liquid_viscosity = getintfield_default(L, nodedef_table,
921 "liquid_viscosity", f.liquid_viscosity);
922 // Amount of light the node emits
923 f.light_source = getintfield_default(L, nodedef_table,
924 "light_source", f.light_source);
925 f.damage_per_second = getintfield_default(L, nodedef_table,
926 "damage_per_second", f.damage_per_second);
928 lua_getfield(L, nodedef_table, "selection_box");
929 if(lua_istable(L, -1)){
930 f.selection_box.type = (NodeBoxType)getenumfield(L, -1, "type",
931 es_NodeBoxType, NODEBOX_REGULAR);
933 lua_getfield(L, -1, "fixed");
934 if(lua_istable(L, -1))
935 f.selection_box.fixed = read_aabbox3df32(L, -1, BS);
938 lua_getfield(L, -1, "wall_top");
939 if(lua_istable(L, -1))
940 f.selection_box.wall_top = read_aabbox3df32(L, -1, BS);
943 lua_getfield(L, -1, "wall_bottom");
944 if(lua_istable(L, -1))
945 f.selection_box.wall_bottom = read_aabbox3df32(L, -1, BS);
948 lua_getfield(L, -1, "wall_side");
949 if(lua_istable(L, -1))
950 f.selection_box.wall_side = read_aabbox3df32(L, -1, BS);
955 lua_getfield(L, nodedef_table, "material");
956 if(lua_istable(L, -1)){
957 f.material.diggability = (Diggability)getenumfield(L, -1, "diggability",
958 es_Diggability, DIGGABLE_NORMAL);
960 getfloatfield(L, -1, "constant_time", f.material.constant_time);
961 getfloatfield(L, -1, "weight", f.material.weight);
962 getfloatfield(L, -1, "crackiness", f.material.crackiness);
963 getfloatfield(L, -1, "crumbliness", f.material.crumbliness);
964 getfloatfield(L, -1, "cuttability", f.material.cuttability);
965 getfloatfield(L, -1, "flammability", f.material.flammability);
969 getstringfield(L, nodedef_table, "cookresult_item", f.cookresult_item);
970 getfloatfield(L, nodedef_table, "furnace_cooktime", f.furnace_cooktime);
971 getfloatfield(L, nodedef_table, "furnace_burntime", f.furnace_burntime);
977 nodedef->set(name, f);
979 return 0; /* number of results */
982 // register_craft({output=item, recipe={{item00,item10},{item01,item11}})
983 static int l_register_craft(lua_State *L)
985 infostream<<"register_craft"<<std::endl;
986 luaL_checktype(L, 1, LUA_TTABLE);
989 // Get server from registry
990 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
991 Server *server = (Server*)lua_touserdata(L, -1);
992 // And get the writable craft definition manager from the server
993 IWritableCraftDefManager *craftdef =
994 server->getWritableCraftDefManager();
998 std::vector<std::string> input;
1000 lua_getfield(L, table0, "output");
1001 luaL_checktype(L, -1, LUA_TSTRING);
1002 if(lua_isstring(L, -1))
1003 output = lua_tostring(L, -1);
1006 lua_getfield(L, table0, "recipe");
1007 luaL_checktype(L, -1, LUA_TTABLE);
1008 if(lua_istable(L, -1)){
1009 int table1 = lua_gettop(L);
1012 while(lua_next(L, table1) != 0){
1014 // key at index -2 and value at index -1
1015 luaL_checktype(L, -1, LUA_TTABLE);
1016 if(lua_istable(L, -1)){
1017 int table2 = lua_gettop(L);
1019 while(lua_next(L, table2) != 0){
1020 // key at index -2 and value at index -1
1021 luaL_checktype(L, -1, LUA_TSTRING);
1022 input.push_back(lua_tostring(L, -1));
1023 // removes value, keeps key for next iteration
1031 if(colcount != width){
1032 script_error(L, "error: %s\n", "Invalid crafting recipe");
1035 // removes value, keeps key for next iteration
1042 CraftDefinition def(output, width, input);
1043 craftdef->registerCraft(def);
1045 return 0; /* number of results */
1048 // setting_get(name)
1049 static int l_setting_get(lua_State *L)
1051 const char *name = luaL_checkstring(L, 1);
1053 std::string value = g_settings->get(name);
1054 lua_pushstring(L, value.c_str());
1055 } catch(SettingNotFoundException &e){
1061 // setting_getbool(name)
1062 static int l_setting_getbool(lua_State *L)
1064 const char *name = luaL_checkstring(L, 1);
1066 bool value = g_settings->getBool(name);
1067 lua_pushboolean(L, value);
1068 } catch(SettingNotFoundException &e){
1074 // chat_send_all(text)
1075 static int l_chat_send_all(lua_State *L)
1077 const char *text = luaL_checkstring(L, 1);
1078 // Get server from registry
1079 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1080 Server *server = (Server*)lua_touserdata(L, -1);
1082 server->notifyPlayers(narrow_to_wide(text));
1086 // chat_send_player(name, text)
1087 static int l_chat_send_player(lua_State *L)
1089 const char *name = luaL_checkstring(L, 1);
1090 const char *text = luaL_checkstring(L, 2);
1091 // Get server from registry
1092 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1093 Server *server = (Server*)lua_touserdata(L, -1);
1095 server->notifyPlayer(name, narrow_to_wide(text));
1099 // get_player_privs(name, text)
1100 static int l_get_player_privs(lua_State *L)
1102 const char *name = luaL_checkstring(L, 1);
1103 // Get server from registry
1104 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1105 Server *server = (Server*)lua_touserdata(L, -1);
1108 int table = lua_gettop(L);
1109 u64 privs_i = server->getPlayerAuthPrivs(name);
1110 // Special case for the "name" setting (local player / server owner)
1111 if(name == g_settings->get("name"))
1113 std::set<std::string> privs_s = privsToSet(privs_i);
1114 for(std::set<std::string>::const_iterator
1115 i = privs_s.begin(); i != privs_s.end(); i++){
1116 lua_pushboolean(L, true);
1117 lua_setfield(L, table, i->c_str());
1119 lua_pushvalue(L, table);
1123 static const struct luaL_Reg minetest_f [] = {
1124 {"register_nodedef_defaults", l_register_nodedef_defaults},
1125 {"register_entity", l_register_entity},
1126 {"register_tool", l_register_tool},
1127 {"register_craftitem", l_register_craftitem},
1128 {"register_node", l_register_node},
1129 {"register_craft", l_register_craft},
1130 {"register_abm", l_register_abm},
1131 {"setting_get", l_setting_get},
1132 {"setting_getbool", l_setting_getbool},
1133 {"chat_send_all", l_chat_send_all},
1134 {"chat_send_player", l_chat_send_player},
1135 {"get_player_privs", l_get_player_privs},
1143 static const struct luaL_Reg minetest_entity_m [] = {
1148 Getters for stuff in main tables
1151 static void objectref_get(lua_State *L, u16 id)
1153 // Get minetest.object_refs[i]
1154 lua_getglobal(L, "minetest");
1155 lua_getfield(L, -1, "object_refs");
1156 luaL_checktype(L, -1, LUA_TTABLE);
1157 lua_pushnumber(L, id);
1158 lua_gettable(L, -2);
1159 lua_remove(L, -2); // object_refs
1160 lua_remove(L, -2); // minetest
1163 static void luaentity_get(lua_State *L, u16 id)
1165 // Get minetest.luaentities[i]
1166 lua_getglobal(L, "minetest");
1167 lua_getfield(L, -1, "luaentities");
1168 luaL_checktype(L, -1, LUA_TTABLE);
1169 lua_pushnumber(L, id);
1170 lua_gettable(L, -2);
1171 lua_remove(L, -2); // luaentities
1172 lua_remove(L, -2); // minetest
1179 #define method(class, name) {#name, class::l_##name}
1189 ServerEnvironment *m_env;
1191 static const char className[];
1192 static const luaL_reg methods[];
1194 static NodeMetaRef *checkobject(lua_State *L, int narg)
1196 luaL_checktype(L, narg, LUA_TUSERDATA);
1197 void *ud = luaL_checkudata(L, narg, className);
1198 if(!ud) luaL_typerror(L, narg, className);
1199 return *(NodeMetaRef**)ud; // unbox pointer
1202 static NodeMetadata* getmeta(NodeMetaRef *ref)
1204 NodeMetadata *meta = ref->m_env->getMap().getNodeMetadata(ref->m_p);
1208 /*static IGenericNodeMetadata* getgenericmeta(NodeMetaRef *ref)
1210 NodeMetadata *meta = getmeta(ref);
1213 if(meta->typeId() != NODEMETA_GENERIC)
1215 return (IGenericNodeMetadata*)meta;
1218 static void reportMetadataChange(NodeMetaRef *ref)
1220 // Inform other things that the metadata has changed
1221 v3s16 blockpos = getNodeBlockPos(ref->m_p);
1223 event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
1225 ref->m_env->getMap().dispatchEvent(&event);
1226 // Set the block to be saved
1227 MapBlock *block = ref->m_env->getMap().getBlockNoCreateNoEx(blockpos);
1229 block->raiseModified(MOD_STATE_WRITE_NEEDED,
1230 "NodeMetaRef::reportMetadataChange");
1233 // Exported functions
1235 // garbage collector
1236 static int gc_object(lua_State *L) {
1237 NodeMetaRef *o = *(NodeMetaRef **)(lua_touserdata(L, 1));
1243 static int l_get_type(lua_State *L)
1245 NodeMetaRef *ref = checkobject(L, 1);
1246 NodeMetadata *meta = getmeta(ref);
1252 lua_pushstring(L, meta->typeName());
1256 // allows_text_input(self)
1257 static int l_allows_text_input(lua_State *L)
1259 NodeMetaRef *ref = checkobject(L, 1);
1260 NodeMetadata *meta = getmeta(ref);
1261 if(meta == NULL) return 0;
1263 lua_pushboolean(L, meta->allowsTextInput());
1267 // set_text(self, text)
1268 static int l_set_text(lua_State *L)
1270 NodeMetaRef *ref = checkobject(L, 1);
1271 NodeMetadata *meta = getmeta(ref);
1272 if(meta == NULL) return 0;
1274 std::string text = lua_tostring(L, 2);
1275 meta->setText(text);
1276 reportMetadataChange(ref);
1281 static int l_get_text(lua_State *L)
1283 NodeMetaRef *ref = checkobject(L, 1);
1284 NodeMetadata *meta = getmeta(ref);
1285 if(meta == NULL) return 0;
1287 std::string text = meta->getText();
1288 lua_pushstring(L, text.c_str());
1293 static int l_get_owner(lua_State *L)
1295 NodeMetaRef *ref = checkobject(L, 1);
1296 NodeMetadata *meta = getmeta(ref);
1297 if(meta == NULL) return 0;
1299 std::string owner = meta->getOwner();
1300 lua_pushstring(L, owner.c_str());
1304 /* IGenericNodeMetadata interface */
1306 // set_infotext(self, text)
1307 static int l_set_infotext(lua_State *L)
1309 infostream<<__FUNCTION_NAME<<std::endl;
1310 NodeMetaRef *ref = checkobject(L, 1);
1311 NodeMetadata *meta = getmeta(ref);
1312 if(meta == NULL) return 0;
1314 std::string text = lua_tostring(L, 2);
1315 meta->setInfoText(text);
1316 reportMetadataChange(ref);
1320 // inventory_set_list(self, name, {item1, item2, ...})
1321 static int l_inventory_set_list(lua_State *L)
1323 NodeMetaRef *ref = checkobject(L, 1);
1324 NodeMetadata *meta = getmeta(ref);
1325 if(meta == NULL) return 0;
1327 Inventory *inv = meta->getInventory();
1328 const char *name = lua_tostring(L, 2);
1329 inventory_set_list_from_lua(inv, name, L, 3,
1330 ref->m_env->getGameDef());
1331 reportMetadataChange(ref);
1335 // inventory_get_list(self, name)
1336 static int l_inventory_get_list(lua_State *L)
1338 NodeMetaRef *ref = checkobject(L, 1);
1339 NodeMetadata *meta = getmeta(ref);
1340 if(meta == NULL) return 0;
1342 Inventory *inv = meta->getInventory();
1343 const char *name = lua_tostring(L, 2);
1344 inventory_get_list_to_lua(inv, name, L);
1348 // set_inventory_draw_spec(self, text)
1349 static int l_set_inventory_draw_spec(lua_State *L)
1351 NodeMetaRef *ref = checkobject(L, 1);
1352 NodeMetadata *meta = getmeta(ref);
1353 if(meta == NULL) return 0;
1355 std::string text = lua_tostring(L, 2);
1356 meta->setInventoryDrawSpec(text);
1357 reportMetadataChange(ref);
1361 // set_allow_text_input(self, text)
1362 static int l_set_allow_text_input(lua_State *L)
1364 NodeMetaRef *ref = checkobject(L, 1);
1365 NodeMetadata *meta = getmeta(ref);
1366 if(meta == NULL) return 0;
1368 bool b = lua_toboolean(L, 2);
1369 meta->setAllowTextInput(b);
1370 reportMetadataChange(ref);
1374 // set_allow_removal(self, text)
1375 static int l_set_allow_removal(lua_State *L)
1377 NodeMetaRef *ref = checkobject(L, 1);
1378 NodeMetadata *meta = getmeta(ref);
1379 if(meta == NULL) return 0;
1381 bool b = lua_toboolean(L, 2);
1382 meta->setRemovalDisabled(!b);
1383 reportMetadataChange(ref);
1387 // set_enforce_owner(self, text)
1388 static int l_set_enforce_owner(lua_State *L)
1390 NodeMetaRef *ref = checkobject(L, 1);
1391 NodeMetadata *meta = getmeta(ref);
1392 if(meta == NULL) return 0;
1394 bool b = lua_toboolean(L, 2);
1395 meta->setEnforceOwner(b);
1396 reportMetadataChange(ref);
1400 // is_inventory_modified(self)
1401 static int l_is_inventory_modified(lua_State *L)
1403 NodeMetaRef *ref = checkobject(L, 1);
1404 NodeMetadata *meta = getmeta(ref);
1405 if(meta == NULL) return 0;
1407 lua_pushboolean(L, meta->isInventoryModified());
1411 // reset_inventory_modified(self)
1412 static int l_reset_inventory_modified(lua_State *L)
1414 NodeMetaRef *ref = checkobject(L, 1);
1415 NodeMetadata *meta = getmeta(ref);
1416 if(meta == NULL) return 0;
1418 meta->resetInventoryModified();
1419 reportMetadataChange(ref);
1423 // is_text_modified(self)
1424 static int l_is_text_modified(lua_State *L)
1426 NodeMetaRef *ref = checkobject(L, 1);
1427 NodeMetadata *meta = getmeta(ref);
1428 if(meta == NULL) return 0;
1430 lua_pushboolean(L, meta->isTextModified());
1434 // reset_text_modified(self)
1435 static int l_reset_text_modified(lua_State *L)
1437 NodeMetaRef *ref = checkobject(L, 1);
1438 NodeMetadata *meta = getmeta(ref);
1439 if(meta == NULL) return 0;
1441 meta->resetTextModified();
1442 reportMetadataChange(ref);
1446 // set_string(self, name, var)
1447 static int l_set_string(lua_State *L)
1449 NodeMetaRef *ref = checkobject(L, 1);
1450 NodeMetadata *meta = getmeta(ref);
1451 if(meta == NULL) return 0;
1453 std::string name = lua_tostring(L, 2);
1455 const char *s = lua_tolstring(L, 3, &len);
1456 std::string str(s, len);
1457 meta->setString(name, str);
1458 reportMetadataChange(ref);
1462 // get_string(self, name)
1463 static int l_get_string(lua_State *L)
1465 NodeMetaRef *ref = checkobject(L, 1);
1466 NodeMetadata *meta = getmeta(ref);
1467 if(meta == NULL) return 0;
1469 std::string name = lua_tostring(L, 2);
1470 std::string str = meta->getString(name);
1471 lua_pushlstring(L, str.c_str(), str.size());
1476 NodeMetaRef(v3s16 p, ServerEnvironment *env):
1486 // Creates an NodeMetaRef and leaves it on top of stack
1487 // Not callable from Lua; all references are created on the C side.
1488 static void create(lua_State *L, v3s16 p, ServerEnvironment *env)
1490 NodeMetaRef *o = new NodeMetaRef(p, env);
1491 //infostream<<"NodeMetaRef::create: o="<<o<<std::endl;
1492 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1493 luaL_getmetatable(L, className);
1494 lua_setmetatable(L, -2);
1497 static void Register(lua_State *L)
1500 int methodtable = lua_gettop(L);
1501 luaL_newmetatable(L, className);
1502 int metatable = lua_gettop(L);
1504 lua_pushliteral(L, "__metatable");
1505 lua_pushvalue(L, methodtable);
1506 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
1508 lua_pushliteral(L, "__index");
1509 lua_pushvalue(L, methodtable);
1510 lua_settable(L, metatable);
1512 lua_pushliteral(L, "__gc");
1513 lua_pushcfunction(L, gc_object);
1514 lua_settable(L, metatable);
1516 lua_pop(L, 1); // drop metatable
1518 luaL_openlib(L, 0, methods, 0); // fill methodtable
1519 lua_pop(L, 1); // drop methodtable
1521 // Cannot be created from Lua
1522 //lua_register(L, className, create_object);
1525 const char NodeMetaRef::className[] = "NodeMetaRef";
1526 const luaL_reg NodeMetaRef::methods[] = {
1527 method(NodeMetaRef, get_type),
1528 method(NodeMetaRef, allows_text_input),
1529 method(NodeMetaRef, set_text),
1530 method(NodeMetaRef, get_text),
1531 method(NodeMetaRef, get_owner),
1532 method(NodeMetaRef, set_infotext),
1533 method(NodeMetaRef, inventory_set_list),
1534 method(NodeMetaRef, inventory_get_list),
1535 method(NodeMetaRef, set_inventory_draw_spec),
1536 method(NodeMetaRef, set_allow_text_input),
1537 method(NodeMetaRef, set_allow_removal),
1538 method(NodeMetaRef, set_enforce_owner),
1539 method(NodeMetaRef, is_inventory_modified),
1540 method(NodeMetaRef, reset_inventory_modified),
1541 method(NodeMetaRef, is_text_modified),
1542 method(NodeMetaRef, reset_text_modified),
1543 method(NodeMetaRef, set_string),
1544 method(NodeMetaRef, get_string),
1555 ServerActiveObject *m_object;
1557 static const char className[];
1558 static const luaL_reg methods[];
1560 static ObjectRef *checkobject(lua_State *L, int narg)
1562 luaL_checktype(L, narg, LUA_TUSERDATA);
1563 void *ud = luaL_checkudata(L, narg, className);
1564 if(!ud) luaL_typerror(L, narg, className);
1565 return *(ObjectRef**)ud; // unbox pointer
1568 static ServerActiveObject* getobject(ObjectRef *ref)
1570 ServerActiveObject *co = ref->m_object;
1574 static LuaEntitySAO* getluaobject(ObjectRef *ref)
1576 ServerActiveObject *obj = getobject(ref);
1579 if(obj->getType() != ACTIVEOBJECT_TYPE_LUAENTITY)
1581 return (LuaEntitySAO*)obj;
1584 static ServerRemotePlayer* getplayer(ObjectRef *ref)
1586 ServerActiveObject *obj = getobject(ref);
1589 if(obj->getType() != ACTIVEOBJECT_TYPE_PLAYER)
1591 return static_cast<ServerRemotePlayer*>(obj);
1594 // Exported functions
1596 // garbage collector
1597 static int gc_object(lua_State *L) {
1598 ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
1599 //infostream<<"ObjectRef::gc_object: o="<<o<<std::endl;
1605 static int l_remove(lua_State *L)
1607 ObjectRef *ref = checkobject(L, 1);
1608 ServerActiveObject *co = getobject(ref);
1609 if(co == NULL) return 0;
1610 infostream<<"ObjectRef::l_remove(): id="<<co->getId()<<std::endl;
1611 co->m_removed = true;
1616 // returns: {x=num, y=num, z=num}
1617 static int l_getpos(lua_State *L)
1619 ObjectRef *ref = checkobject(L, 1);
1620 ServerActiveObject *co = getobject(ref);
1621 if(co == NULL) return 0;
1622 v3f pos = co->getBasePosition() / BS;
1624 lua_pushnumber(L, pos.X);
1625 lua_setfield(L, -2, "x");
1626 lua_pushnumber(L, pos.Y);
1627 lua_setfield(L, -2, "y");
1628 lua_pushnumber(L, pos.Z);
1629 lua_setfield(L, -2, "z");
1633 // setpos(self, pos)
1634 static int l_setpos(lua_State *L)
1636 ObjectRef *ref = checkobject(L, 1);
1637 //LuaEntitySAO *co = getluaobject(ref);
1638 ServerActiveObject *co = getobject(ref);
1639 if(co == NULL) return 0;
1641 v3f pos = readFloatPos(L, 2);
1647 // moveto(self, pos, continuous=false)
1648 static int l_moveto(lua_State *L)
1650 ObjectRef *ref = checkobject(L, 1);
1651 //LuaEntitySAO *co = getluaobject(ref);
1652 ServerActiveObject *co = getobject(ref);
1653 if(co == NULL) return 0;
1655 v3f pos = readFloatPos(L, 2);
1657 bool continuous = lua_toboolean(L, 3);
1659 co->moveTo(pos, continuous);
1663 // punch(self, puncher); puncher = an another ObjectRef
1664 static int l_punch(lua_State *L)
1666 ObjectRef *ref = checkobject(L, 1);
1667 ObjectRef *ref2 = checkobject(L, 2);
1668 ServerActiveObject *co = getobject(ref);
1669 ServerActiveObject *co2 = getobject(ref2);
1670 if(co == NULL) return 0;
1671 if(co2 == NULL) return 0;
1677 // right_click(self, clicker); clicker = an another ObjectRef
1678 static int l_right_click(lua_State *L)
1680 ObjectRef *ref = checkobject(L, 1);
1681 ObjectRef *ref2 = checkobject(L, 2);
1682 ServerActiveObject *co = getobject(ref);
1683 ServerActiveObject *co2 = getobject(ref2);
1684 if(co == NULL) return 0;
1685 if(co2 == NULL) return 0;
1687 co->rightClick(co2);
1691 // get_wielded_itemstring(self)
1692 static int l_get_wielded_itemstring(lua_State *L)
1694 ObjectRef *ref = checkobject(L, 1);
1695 ServerActiveObject *co = getobject(ref);
1696 if(co == NULL) return 0;
1698 InventoryItem *item = co->getWieldedItem();
1703 lua_pushstring(L, item->getItemString().c_str());
1707 // get_wielded_item(self)
1708 static int l_get_wielded_item(lua_State *L)
1710 ObjectRef *ref = checkobject(L, 1);
1711 ServerActiveObject *co = getobject(ref);
1712 if(co == NULL) return 0;
1714 InventoryItem *item0 = co->getWieldedItem();
1719 if(std::string("MaterialItem") == item0->getName()){
1720 MaterialItem *item = (MaterialItem*)item0;
1722 lua_pushstring(L, "NodeItem");
1723 lua_setfield(L, -2, "type");
1724 lua_pushstring(L, item->getNodeName().c_str());
1725 lua_setfield(L, -2, "name");
1727 else if(std::string("CraftItem") == item0->getName()){
1728 CraftItem *item = (CraftItem*)item0;
1730 lua_pushstring(L, "CraftItem");
1731 lua_setfield(L, -2, "type");
1732 lua_pushstring(L, item->getSubName().c_str());
1733 lua_setfield(L, -2, "name");
1735 else if(std::string("ToolItem") == item0->getName()){
1736 ToolItem *item = (ToolItem*)item0;
1738 lua_pushstring(L, "ToolItem");
1739 lua_setfield(L, -2, "type");
1740 lua_pushstring(L, item->getToolName().c_str());
1741 lua_setfield(L, -2, "name");
1742 lua_pushstring(L, itos(item->getWear()).c_str());
1743 lua_setfield(L, -2, "wear");
1746 errorstream<<"l_get_wielded_item: Unknown item name: \""
1747 <<item0->getName()<<"\""<<std::endl;
1753 // damage_wielded_item(self, amount)
1754 static int l_damage_wielded_item(lua_State *L)
1756 ObjectRef *ref = checkobject(L, 1);
1757 ServerActiveObject *co = getobject(ref);
1758 if(co == NULL) return 0;
1760 int amount = lua_tonumber(L, 2);
1761 co->damageWieldedItem(amount);
1765 // add_to_inventory(self, itemstring)
1766 // returns: true if item was added, (false, "reason") otherwise
1767 static int l_add_to_inventory(lua_State *L)
1769 ObjectRef *ref = checkobject(L, 1);
1770 luaL_checkstring(L, 2);
1771 ServerActiveObject *co = getobject(ref);
1772 if(co == NULL) return 0;
1774 const char *itemstring = lua_tostring(L, 2);
1775 infostream<<"ObjectRef::l_add_to_inventory(): id="<<co->getId()
1776 <<" itemstring=\""<<itemstring<<"\""<<std::endl;
1778 std::istringstream is(itemstring, std::ios::binary);
1779 ServerEnvironment *env = co->getEnv();
1781 IGameDef *gamedef = env->getGameDef();
1783 InventoryItem *item = InventoryItem::deSerialize(is, gamedef);
1784 if(item->getCount() == 0)
1786 bool added = co->addToInventory(item);
1788 lua_pushboolean(L, added);
1790 lua_pushstring(L, "does not fit");
1792 } catch(SerializationError &e){
1794 lua_pushboolean(L, false);
1795 lua_pushstring(L, (std::string("Invalid item: ")
1796 + e.what()).c_str());
1801 // add_to_inventory_later(self, itemstring)
1803 static int l_add_to_inventory_later(lua_State *L)
1805 ObjectRef *ref = checkobject(L, 1);
1806 luaL_checkstring(L, 2);
1807 ServerActiveObject *co = getobject(ref);
1808 if(co == NULL) return 0;
1810 const char *itemstring = lua_tostring(L, 2);
1811 infostream<<"ObjectRef::l_add_to_inventory_later(): id="<<co->getId()
1812 <<" itemstring=\""<<itemstring<<"\""<<std::endl;
1814 std::istringstream is(itemstring, std::ios::binary);
1815 ServerEnvironment *env = co->getEnv();
1817 IGameDef *gamedef = env->getGameDef();
1818 InventoryItem *item = InventoryItem::deSerialize(is, gamedef);
1819 infostream<<"item="<<env<<std::endl;
1820 co->addToInventoryLater(item);
1826 // hp = number of hitpoints (2 * number of hearts)
1828 static int l_set_hp(lua_State *L)
1830 ObjectRef *ref = checkobject(L, 1);
1831 luaL_checknumber(L, 2);
1832 ServerActiveObject *co = getobject(ref);
1833 if(co == NULL) return 0;
1834 int hp = lua_tonumber(L, 2);
1835 infostream<<"ObjectRef::l_set_hp(): id="<<co->getId()
1836 <<" hp="<<hp<<std::endl;
1844 // returns: number of hitpoints (2 * number of hearts)
1845 // 0 if not applicable to this type of object
1846 static int l_get_hp(lua_State *L)
1848 ObjectRef *ref = checkobject(L, 1);
1849 ServerActiveObject *co = getobject(ref);
1850 if(co == NULL) return 0;
1851 int hp = co->getHP();
1852 infostream<<"ObjectRef::l_get_hp(): id="<<co->getId()
1853 <<" hp="<<hp<<std::endl;
1855 lua_pushnumber(L, hp);
1859 /* LuaEntitySAO-only */
1861 // setvelocity(self, {x=num, y=num, z=num})
1862 static int l_setvelocity(lua_State *L)
1864 ObjectRef *ref = checkobject(L, 1);
1865 LuaEntitySAO *co = getluaobject(ref);
1866 if(co == NULL) return 0;
1868 v3f pos = readFloatPos(L, 2);
1870 co->setVelocity(pos);
1874 // setacceleration(self, {x=num, y=num, z=num})
1875 static int l_setacceleration(lua_State *L)
1877 ObjectRef *ref = checkobject(L, 1);
1878 LuaEntitySAO *co = getluaobject(ref);
1879 if(co == NULL) return 0;
1881 v3f pos = readFloatPos(L, 2);
1883 co->setAcceleration(pos);
1887 // getacceleration(self)
1888 static int l_getacceleration(lua_State *L)
1890 ObjectRef *ref = checkobject(L, 1);
1891 LuaEntitySAO *co = getluaobject(ref);
1892 if(co == NULL) return 0;
1894 v3f v = co->getAcceleration();
1899 // settexturemod(self, mod)
1900 static int l_settexturemod(lua_State *L)
1902 ObjectRef *ref = checkobject(L, 1);
1903 LuaEntitySAO *co = getluaobject(ref);
1904 if(co == NULL) return 0;
1906 std::string mod = lua_tostring(L, 2);
1907 co->setTextureMod(mod);
1911 // setsprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2,
1912 // select_horiz_by_yawpitch=false)
1913 static int l_setsprite(lua_State *L)
1915 ObjectRef *ref = checkobject(L, 1);
1916 LuaEntitySAO *co = getluaobject(ref);
1917 if(co == NULL) return 0;
1920 if(!lua_isnil(L, 2))
1921 p = read_v2s16(L, 2);
1923 if(!lua_isnil(L, 3))
1924 num_frames = lua_tonumber(L, 3);
1925 float framelength = 0.2;
1926 if(!lua_isnil(L, 4))
1927 framelength = lua_tonumber(L, 4);
1928 bool select_horiz_by_yawpitch = false;
1929 if(!lua_isnil(L, 5))
1930 select_horiz_by_yawpitch = lua_toboolean(L, 5);
1931 co->setSprite(p, num_frames, framelength, select_horiz_by_yawpitch);
1937 // get_player_name(self)
1938 static int l_get_player_name(lua_State *L)
1940 ObjectRef *ref = checkobject(L, 1);
1941 ServerRemotePlayer *player = getplayer(ref);
1947 lua_pushstring(L, player->getName());
1951 // inventory_set_list(self, name, {item1, item2, ...})
1952 static int l_inventory_set_list(lua_State *L)
1954 ObjectRef *ref = checkobject(L, 1);
1955 ServerRemotePlayer *player = getplayer(ref);
1956 if(player == NULL) return 0;
1957 const char *name = lua_tostring(L, 2);
1959 inventory_set_list_from_lua(&player->inventory, name, L, 3,
1960 player->getEnv()->getGameDef());
1961 player->m_inventory_not_sent = true;
1965 // inventory_get_list(self, name)
1966 static int l_inventory_get_list(lua_State *L)
1968 ObjectRef *ref = checkobject(L, 1);
1969 ServerRemotePlayer *player = getplayer(ref);
1970 if(player == NULL) return 0;
1971 const char *name = lua_tostring(L, 2);
1973 inventory_get_list_to_lua(&player->inventory, name, L);
1978 ObjectRef(ServerActiveObject *object):
1981 //infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
1987 infostream<<"ObjectRef destructing for id="
1988 <<m_object->getId()<<std::endl;
1990 infostream<<"ObjectRef destructing for id=unknown"<<std::endl;*/
1993 // Creates an ObjectRef and leaves it on top of stack
1994 // Not callable from Lua; all references are created on the C side.
1995 static void create(lua_State *L, ServerActiveObject *object)
1997 ObjectRef *o = new ObjectRef(object);
1998 //infostream<<"ObjectRef::create: o="<<o<<std::endl;
1999 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
2000 luaL_getmetatable(L, className);
2001 lua_setmetatable(L, -2);
2004 static void set_null(lua_State *L)
2006 ObjectRef *o = checkobject(L, -1);
2010 static void Register(lua_State *L)
2013 int methodtable = lua_gettop(L);
2014 luaL_newmetatable(L, className);
2015 int metatable = lua_gettop(L);
2017 lua_pushliteral(L, "__metatable");
2018 lua_pushvalue(L, methodtable);
2019 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
2021 lua_pushliteral(L, "__index");
2022 lua_pushvalue(L, methodtable);
2023 lua_settable(L, metatable);
2025 lua_pushliteral(L, "__gc");
2026 lua_pushcfunction(L, gc_object);
2027 lua_settable(L, metatable);
2029 lua_pop(L, 1); // drop metatable
2031 luaL_openlib(L, 0, methods, 0); // fill methodtable
2032 lua_pop(L, 1); // drop methodtable
2034 // Cannot be created from Lua
2035 //lua_register(L, className, create_object);
2038 const char ObjectRef::className[] = "ObjectRef";
2039 const luaL_reg ObjectRef::methods[] = {
2040 // ServerActiveObject
2041 method(ObjectRef, remove),
2042 method(ObjectRef, getpos),
2043 method(ObjectRef, setpos),
2044 method(ObjectRef, moveto),
2045 method(ObjectRef, punch),
2046 method(ObjectRef, right_click),
2047 method(ObjectRef, get_wielded_itemstring),
2048 method(ObjectRef, get_wielded_item),
2049 method(ObjectRef, damage_wielded_item),
2050 method(ObjectRef, add_to_inventory),
2051 method(ObjectRef, add_to_inventory_later),
2052 method(ObjectRef, set_hp),
2053 method(ObjectRef, get_hp),
2054 // LuaEntitySAO-only
2055 method(ObjectRef, setvelocity),
2056 method(ObjectRef, setacceleration),
2057 method(ObjectRef, getacceleration),
2058 method(ObjectRef, settexturemod),
2059 method(ObjectRef, setsprite),
2061 method(ObjectRef, get_player_name),
2062 method(ObjectRef, inventory_set_list),
2063 method(ObjectRef, inventory_get_list),
2067 // Creates a new anonymous reference if id=0
2068 static void objectref_get_or_create(lua_State *L,
2069 ServerActiveObject *cobj)
2071 if(cobj->getId() == 0){
2072 ObjectRef::create(L, cobj);
2074 objectref_get(L, cobj->getId());
2085 ServerEnvironment *m_env;
2087 static const char className[];
2088 static const luaL_reg methods[];
2090 static EnvRef *checkobject(lua_State *L, int narg)
2092 luaL_checktype(L, narg, LUA_TUSERDATA);
2093 void *ud = luaL_checkudata(L, narg, className);
2094 if(!ud) luaL_typerror(L, narg, className);
2095 return *(EnvRef**)ud; // unbox pointer
2098 // Exported functions
2100 // EnvRef:add_node(pos, node)
2101 // pos = {x=num, y=num, z=num}
2102 static int l_add_node(lua_State *L)
2104 //infostream<<"EnvRef::l_add_node()"<<std::endl;
2105 EnvRef *o = checkobject(L, 1);
2106 ServerEnvironment *env = o->m_env;
2107 if(env == NULL) return 0;
2109 v3s16 pos = readpos(L, 2);
2111 MapNode n = readnode(L, 3, env->getGameDef()->ndef());
2113 bool succeeded = env->getMap().addNodeWithEvent(pos, n);
2114 lua_pushboolean(L, succeeded);
2118 // EnvRef:remove_node(pos)
2119 // pos = {x=num, y=num, z=num}
2120 static int l_remove_node(lua_State *L)
2122 //infostream<<"EnvRef::l_remove_node()"<<std::endl;
2123 EnvRef *o = checkobject(L, 1);
2124 ServerEnvironment *env = o->m_env;
2125 if(env == NULL) return 0;
2127 v3s16 pos = readpos(L, 2);
2129 bool succeeded = env->getMap().removeNodeWithEvent(pos);
2130 lua_pushboolean(L, succeeded);
2134 // EnvRef:get_node(pos)
2135 // pos = {x=num, y=num, z=num}
2136 static int l_get_node(lua_State *L)
2138 //infostream<<"EnvRef::l_get_node()"<<std::endl;
2139 EnvRef *o = checkobject(L, 1);
2140 ServerEnvironment *env = o->m_env;
2141 if(env == NULL) return 0;
2143 v3s16 pos = readpos(L, 2);
2145 MapNode n = env->getMap().getNodeNoEx(pos);
2147 pushnode(L, n, env->getGameDef()->ndef());
2151 // EnvRef:add_luaentity(pos, entityname)
2152 // pos = {x=num, y=num, z=num}
2153 static int l_add_luaentity(lua_State *L)
2155 //infostream<<"EnvRef::l_add_luaentity()"<<std::endl;
2156 EnvRef *o = checkobject(L, 1);
2157 ServerEnvironment *env = o->m_env;
2158 if(env == NULL) return 0;
2160 v3f pos = readFloatPos(L, 2);
2162 const char *name = lua_tostring(L, 3);
2164 ServerActiveObject *obj = new LuaEntitySAO(env, pos, name, "");
2165 env->addActiveObject(obj);
2169 // EnvRef:add_item(pos, inventorystring)
2170 // pos = {x=num, y=num, z=num}
2171 static int l_add_item(lua_State *L)
2173 infostream<<"EnvRef::l_add_item()"<<std::endl;
2174 EnvRef *o = checkobject(L, 1);
2175 ServerEnvironment *env = o->m_env;
2176 if(env == NULL) return 0;
2178 v3f pos = readFloatPos(L, 2);
2180 const char *inventorystring = lua_tostring(L, 3);
2182 ServerActiveObject *obj = new ItemSAO(env, pos, inventorystring);
2183 env->addActiveObject(obj);
2187 // EnvRef:add_rat(pos)
2188 // pos = {x=num, y=num, z=num}
2189 static int l_add_rat(lua_State *L)
2191 infostream<<"EnvRef::l_add_rat()"<<std::endl;
2192 EnvRef *o = checkobject(L, 1);
2193 ServerEnvironment *env = o->m_env;
2194 if(env == NULL) return 0;
2196 v3f pos = readFloatPos(L, 2);
2198 ServerActiveObject *obj = new RatSAO(env, pos);
2199 env->addActiveObject(obj);
2203 // EnvRef:add_firefly(pos)
2204 // pos = {x=num, y=num, z=num}
2205 static int l_add_firefly(lua_State *L)
2207 infostream<<"EnvRef::l_add_firefly()"<<std::endl;
2208 EnvRef *o = checkobject(L, 1);
2209 ServerEnvironment *env = o->m_env;
2210 if(env == NULL) return 0;
2212 v3f pos = readFloatPos(L, 2);
2214 ServerActiveObject *obj = new FireflySAO(env, pos);
2215 env->addActiveObject(obj);
2219 // EnvRef:get_meta(pos)
2220 static int l_get_meta(lua_State *L)
2222 //infostream<<"EnvRef::l_get_meta()"<<std::endl;
2223 EnvRef *o = checkobject(L, 1);
2224 ServerEnvironment *env = o->m_env;
2225 if(env == NULL) return 0;
2227 v3s16 p = readpos(L, 2);
2228 NodeMetaRef::create(L, p, env);
2232 // EnvRef:get_player_by_name(name)
2233 static int l_get_player_by_name(lua_State *L)
2235 EnvRef *o = checkobject(L, 1);
2236 ServerEnvironment *env = o->m_env;
2237 if(env == NULL) return 0;
2239 const char *name = lua_tostring(L, 2);
2240 ServerRemotePlayer *player =
2241 static_cast<ServerRemotePlayer*>(env->getPlayer(name));
2246 // Put player on stack
2247 objectref_get_or_create(L, player);
2251 static int gc_object(lua_State *L) {
2252 EnvRef *o = *(EnvRef **)(lua_touserdata(L, 1));
2258 EnvRef(ServerEnvironment *env):
2261 infostream<<"EnvRef created"<<std::endl;
2266 infostream<<"EnvRef destructing"<<std::endl;
2269 // Creates an EnvRef and leaves it on top of stack
2270 // Not callable from Lua; all references are created on the C side.
2271 static void create(lua_State *L, ServerEnvironment *env)
2273 EnvRef *o = new EnvRef(env);
2274 //infostream<<"EnvRef::create: o="<<o<<std::endl;
2275 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
2276 luaL_getmetatable(L, className);
2277 lua_setmetatable(L, -2);
2280 static void set_null(lua_State *L)
2282 EnvRef *o = checkobject(L, -1);
2286 static void Register(lua_State *L)
2289 int methodtable = lua_gettop(L);
2290 luaL_newmetatable(L, className);
2291 int metatable = lua_gettop(L);
2293 lua_pushliteral(L, "__metatable");
2294 lua_pushvalue(L, methodtable);
2295 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
2297 lua_pushliteral(L, "__index");
2298 lua_pushvalue(L, methodtable);
2299 lua_settable(L, metatable);
2301 lua_pushliteral(L, "__gc");
2302 lua_pushcfunction(L, gc_object);
2303 lua_settable(L, metatable);
2305 lua_pop(L, 1); // drop metatable
2307 luaL_openlib(L, 0, methods, 0); // fill methodtable
2308 lua_pop(L, 1); // drop methodtable
2310 // Cannot be created from Lua
2311 //lua_register(L, className, create_object);
2314 const char EnvRef::className[] = "EnvRef";
2315 const luaL_reg EnvRef::methods[] = {
2316 method(EnvRef, add_node),
2317 method(EnvRef, remove_node),
2318 method(EnvRef, get_node),
2319 method(EnvRef, add_luaentity),
2320 method(EnvRef, add_item),
2321 method(EnvRef, add_rat),
2322 method(EnvRef, add_firefly),
2323 method(EnvRef, get_meta),
2324 method(EnvRef, get_player_by_name),
2329 Main export function
2332 void scriptapi_export(lua_State *L, Server *server)
2335 assert(lua_checkstack(L, 20));
2336 infostream<<"scriptapi_export"<<std::endl;
2337 StackUnroller stack_unroller(L);
2339 // Store server as light userdata in registry
2340 lua_pushlightuserdata(L, server);
2341 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_server");
2343 // Store nil as minetest_nodedef_defaults in registry
2345 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
2347 // Register global functions in table minetest
2349 luaL_register(L, NULL, minetest_f);
2350 lua_setglobal(L, "minetest");
2352 // Get the main minetest table
2353 lua_getglobal(L, "minetest");
2355 // Add tables to minetest
2358 lua_setfield(L, -2, "registered_nodes");
2360 lua_setfield(L, -2, "registered_entities");
2362 lua_setfield(L, -2, "registered_craftitems");
2364 lua_setfield(L, -2, "registered_abms");
2367 lua_setfield(L, -2, "object_refs");
2369 lua_setfield(L, -2, "luaentities");
2371 // Create entity prototype
2372 luaL_newmetatable(L, "minetest.entity");
2373 // metatable.__index = metatable
2374 lua_pushvalue(L, -1); // Duplicate metatable
2375 lua_setfield(L, -2, "__index");
2376 // Put functions in metatable
2377 luaL_register(L, NULL, minetest_entity_m);
2378 // Put other stuff in metatable
2380 // Register reference wrappers
2381 NodeMetaRef::Register(L);
2382 EnvRef::Register(L);
2383 ObjectRef::Register(L);
2386 void scriptapi_add_environment(lua_State *L, ServerEnvironment *env)
2389 assert(lua_checkstack(L, 20));
2390 infostream<<"scriptapi_add_environment"<<std::endl;
2391 StackUnroller stack_unroller(L);
2393 // Create EnvRef on stack
2394 EnvRef::create(L, env);
2395 int envref = lua_gettop(L);
2397 // minetest.env = envref
2398 lua_getglobal(L, "minetest");
2399 luaL_checktype(L, -1, LUA_TTABLE);
2400 lua_pushvalue(L, envref);
2401 lua_setfield(L, -2, "env");
2403 // Store environment as light userdata in registry
2404 lua_pushlightuserdata(L, env);
2405 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_env");
2407 /* Add ActiveBlockModifiers to environment */
2409 // Get minetest.registered_abms
2410 lua_getglobal(L, "minetest");
2411 lua_getfield(L, -1, "registered_abms");
2412 luaL_checktype(L, -1, LUA_TTABLE);
2413 int registered_abms = lua_gettop(L);
2415 if(lua_istable(L, registered_abms)){
2416 int table = lua_gettop(L);
2418 while(lua_next(L, table) != 0){
2419 // key at index -2 and value at index -1
2420 int id = lua_tonumber(L, -2);
2421 int current_abm = lua_gettop(L);
2423 std::set<std::string> trigger_contents;
2424 lua_getfield(L, current_abm, "nodenames");
2425 if(lua_istable(L, -1)){
2426 int table = lua_gettop(L);
2428 while(lua_next(L, table) != 0){
2429 // key at index -2 and value at index -1
2430 luaL_checktype(L, -1, LUA_TSTRING);
2431 trigger_contents.insert(lua_tostring(L, -1));
2432 // removes value, keeps key for next iteration
2438 float trigger_interval = 10.0;
2439 getfloatfield(L, current_abm, "interval", trigger_interval);
2441 int trigger_chance = 50;
2442 getintfield(L, current_abm, "chance", trigger_chance);
2444 LuaABM *abm = new LuaABM(L, id, trigger_contents,
2445 trigger_interval, trigger_chance);
2447 env->addActiveBlockModifier(abm);
2449 // removes value, keeps key for next iteration
2457 // Dump stack top with the dump2 function
2458 static void dump2(lua_State *L, const char *name)
2460 // Dump object (debug)
2461 lua_getglobal(L, "dump2");
2462 luaL_checktype(L, -1, LUA_TFUNCTION);
2463 lua_pushvalue(L, -2); // Get previous stack top as first parameter
2464 lua_pushstring(L, name);
2465 if(lua_pcall(L, 2, 0, 0))
2466 script_error(L, "error: %s\n", lua_tostring(L, -1));
2474 void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj)
2477 assert(lua_checkstack(L, 20));
2478 //infostream<<"scriptapi_add_object_reference: id="<<cobj->getId()<<std::endl;
2479 StackUnroller stack_unroller(L);
2481 // Create object on stack
2482 ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack
2483 int object = lua_gettop(L);
2485 // Get minetest.object_refs table
2486 lua_getglobal(L, "minetest");
2487 lua_getfield(L, -1, "object_refs");
2488 luaL_checktype(L, -1, LUA_TTABLE);
2489 int objectstable = lua_gettop(L);
2491 // object_refs[id] = object
2492 lua_pushnumber(L, cobj->getId()); // Push id
2493 lua_pushvalue(L, object); // Copy object to top of stack
2494 lua_settable(L, objectstable);
2497 void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj)
2500 assert(lua_checkstack(L, 20));
2501 //infostream<<"scriptapi_rm_object_reference: id="<<cobj->getId()<<std::endl;
2502 StackUnroller stack_unroller(L);
2504 // Get minetest.object_refs table
2505 lua_getglobal(L, "minetest");
2506 lua_getfield(L, -1, "object_refs");
2507 luaL_checktype(L, -1, LUA_TTABLE);
2508 int objectstable = lua_gettop(L);
2510 // Get object_refs[id]
2511 lua_pushnumber(L, cobj->getId()); // Push id
2512 lua_gettable(L, objectstable);
2513 // Set object reference to NULL
2514 ObjectRef::set_null(L);
2515 lua_pop(L, 1); // pop object
2517 // Set object_refs[id] = nil
2518 lua_pushnumber(L, cobj->getId()); // Push id
2520 lua_settable(L, objectstable);
2523 bool scriptapi_on_chat_message(lua_State *L, const std::string &name,
2524 const std::string &message)
2527 assert(lua_checkstack(L, 20));
2528 StackUnroller stack_unroller(L);
2530 // Get minetest.registered_on_chat_messages
2531 lua_getglobal(L, "minetest");
2532 lua_getfield(L, -1, "registered_on_chat_messages");
2533 luaL_checktype(L, -1, LUA_TTABLE);
2534 int table = lua_gettop(L);
2537 while(lua_next(L, table) != 0){
2538 // key at index -2 and value at index -1
2539 luaL_checktype(L, -1, LUA_TFUNCTION);
2541 lua_pushstring(L, name.c_str());
2542 lua_pushstring(L, message.c_str());
2543 if(lua_pcall(L, 2, 1, 0))
2544 script_error(L, "error: %s\n", lua_tostring(L, -1));
2545 bool ate = lua_toboolean(L, -1);
2549 // value removed, keep key for next iteration
2558 void scriptapi_on_newplayer(lua_State *L, ServerActiveObject *player)
2561 assert(lua_checkstack(L, 20));
2562 StackUnroller stack_unroller(L);
2564 // Get minetest.registered_on_newplayers
2565 lua_getglobal(L, "minetest");
2566 lua_getfield(L, -1, "registered_on_newplayers");
2567 luaL_checktype(L, -1, LUA_TTABLE);
2568 int table = lua_gettop(L);
2571 while(lua_next(L, table) != 0){
2572 // key at index -2 and value at index -1
2573 luaL_checktype(L, -1, LUA_TFUNCTION);
2575 objectref_get_or_create(L, player);
2576 if(lua_pcall(L, 1, 0, 0))
2577 script_error(L, "error: %s\n", lua_tostring(L, -1));
2578 // value removed, keep key for next iteration
2581 bool scriptapi_on_respawnplayer(lua_State *L, ServerActiveObject *player)
2584 assert(lua_checkstack(L, 20));
2585 StackUnroller stack_unroller(L);
2587 bool positioning_handled_by_some = false;
2589 // Get minetest.registered_on_respawnplayers
2590 lua_getglobal(L, "minetest");
2591 lua_getfield(L, -1, "registered_on_respawnplayers");
2592 luaL_checktype(L, -1, LUA_TTABLE);
2593 int table = lua_gettop(L);
2596 while(lua_next(L, table) != 0){
2597 // key at index -2 and value at index -1
2598 luaL_checktype(L, -1, LUA_TFUNCTION);
2600 objectref_get_or_create(L, player);
2601 if(lua_pcall(L, 1, 1, 0))
2602 script_error(L, "error: %s\n", lua_tostring(L, -1));
2603 bool positioning_handled = lua_toboolean(L, -1);
2605 if(positioning_handled)
2606 positioning_handled_by_some = true;
2607 // value removed, keep key for next iteration
2609 return positioning_handled_by_some;
2616 static void pushPointedThing(lua_State *L, const PointedThing& pointed)
2619 if(pointed.type == POINTEDTHING_NODE)
2621 lua_pushstring(L, "node");
2622 lua_setfield(L, -2, "type");
2623 pushpos(L, pointed.node_undersurface);
2624 lua_setfield(L, -2, "under");
2625 pushpos(L, pointed.node_abovesurface);
2626 lua_setfield(L, -2, "above");
2628 else if(pointed.type == POINTEDTHING_OBJECT)
2630 lua_pushstring(L, "object");
2631 lua_setfield(L, -2, "type");
2632 objectref_get(L, pointed.object_id);
2633 lua_setfield(L, -2, "ref");
2637 lua_pushstring(L, "nothing");
2638 lua_setfield(L, -2, "type");
2642 void scriptapi_add_craftitem(lua_State *L, const char *name)
2644 StackUnroller stack_unroller(L);
2645 assert(lua_gettop(L) > 0);
2647 // Set minetest.registered_craftitems[name] = table on top of stack
2648 lua_getglobal(L, "minetest");
2649 lua_getfield(L, -1, "registered_craftitems");
2650 luaL_checktype(L, -1, LUA_TTABLE);
2651 lua_pushvalue(L, -3); // push another reference to the table to be registered
2652 lua_setfield(L, -2, name); // set minetest.registered_craftitems[name]
2655 static bool get_craftitem_callback(lua_State *L, const char *name,
2656 const char *callbackname)
2658 // Get minetest.registered_craftitems[name][callbackname]
2659 // If that is nil or on error, return false and stack is unchanged
2660 // If that is a function, returns true and pushes the
2661 // function onto the stack
2663 lua_getglobal(L, "minetest");
2664 lua_getfield(L, -1, "registered_craftitems");
2666 luaL_checktype(L, -1, LUA_TTABLE);
2667 lua_getfield(L, -1, name);
2669 // Should be a table
2670 if(lua_type(L, -1) != LUA_TTABLE)
2672 errorstream<<"CraftItem name \""<<name<<"\" not defined"<<std::endl;
2676 lua_getfield(L, -1, callbackname);
2678 // Should be a function or nil
2679 if(lua_type(L, -1) == LUA_TFUNCTION)
2683 else if(lua_isnil(L, -1))
2690 errorstream<<"CraftItem name \""<<name<<"\" callback \""
2691 <<callbackname<<" is not a function"<<std::endl;
2697 bool scriptapi_craftitem_on_drop(lua_State *L, const char *name,
2698 ServerActiveObject *dropper, v3f pos,
2699 bool &callback_exists)
2702 assert(lua_checkstack(L, 20));
2703 //infostream<<"scriptapi_craftitem_on_drop"<<std::endl;
2704 StackUnroller stack_unroller(L);
2706 bool result = false;
2707 callback_exists = get_craftitem_callback(L, name, "on_drop");
2711 lua_pushstring(L, name);
2712 objectref_get_or_create(L, dropper);
2713 pushFloatPos(L, pos);
2714 if(lua_pcall(L, 3, 1, 0))
2715 script_error(L, "error: %s\n", lua_tostring(L, -1));
2716 result = lua_toboolean(L, -1);
2721 bool scriptapi_craftitem_on_place_on_ground(lua_State *L, const char *name,
2722 ServerActiveObject *placer, v3f pos,
2723 bool &callback_exists)
2726 assert(lua_checkstack(L, 20));
2727 //infostream<<"scriptapi_craftitem_on_place_on_ground"<<std::endl;
2728 StackUnroller stack_unroller(L);
2730 bool result = false;
2731 callback_exists = get_craftitem_callback(L, name, "on_place_on_ground");
2735 lua_pushstring(L, name);
2736 objectref_get_or_create(L, placer);
2737 pushFloatPos(L, pos);
2738 if(lua_pcall(L, 3, 1, 0))
2739 script_error(L, "error: %s\n", lua_tostring(L, -1));
2740 result = lua_toboolean(L, -1);
2745 bool scriptapi_craftitem_on_use(lua_State *L, const char *name,
2746 ServerActiveObject *user, const PointedThing& pointed,
2747 bool &callback_exists)
2750 assert(lua_checkstack(L, 20));
2751 //infostream<<"scriptapi_craftitem_on_use"<<std::endl;
2752 StackUnroller stack_unroller(L);
2754 bool result = false;
2755 callback_exists = get_craftitem_callback(L, name, "on_use");
2759 lua_pushstring(L, name);
2760 objectref_get_or_create(L, user);
2761 pushPointedThing(L, pointed);
2762 if(lua_pcall(L, 3, 1, 0))
2763 script_error(L, "error: %s\n", lua_tostring(L, -1));
2764 result = lua_toboolean(L, -1);
2773 void scriptapi_environment_step(lua_State *L, float dtime)
2776 assert(lua_checkstack(L, 20));
2777 //infostream<<"scriptapi_environment_step"<<std::endl;
2778 StackUnroller stack_unroller(L);
2780 // Get minetest.registered_globalsteps
2781 lua_getglobal(L, "minetest");
2782 lua_getfield(L, -1, "registered_globalsteps");
2783 luaL_checktype(L, -1, LUA_TTABLE);
2784 int table = lua_gettop(L);
2787 while(lua_next(L, table) != 0){
2788 // key at index -2 and value at index -1
2789 luaL_checktype(L, -1, LUA_TFUNCTION);
2791 lua_pushnumber(L, dtime);
2792 if(lua_pcall(L, 1, 0, 0))
2793 script_error(L, "error: %s\n", lua_tostring(L, -1));
2794 // value removed, keep key for next iteration
2798 void scriptapi_environment_on_placenode(lua_State *L, v3s16 p, MapNode newnode,
2799 ServerActiveObject *placer)
2802 assert(lua_checkstack(L, 20));
2803 //infostream<<"scriptapi_environment_on_placenode"<<std::endl;
2804 StackUnroller stack_unroller(L);
2806 // Get server from registry
2807 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
2808 Server *server = (Server*)lua_touserdata(L, -1);
2809 // And get the writable node definition manager from the server
2810 IWritableNodeDefManager *ndef =
2811 server->getWritableNodeDefManager();
2813 // Get minetest.registered_on_placenodes
2814 lua_getglobal(L, "minetest");
2815 lua_getfield(L, -1, "registered_on_placenodes");
2816 luaL_checktype(L, -1, LUA_TTABLE);
2817 int table = lua_gettop(L);
2820 while(lua_next(L, table) != 0){
2821 // key at index -2 and value at index -1
2822 luaL_checktype(L, -1, LUA_TFUNCTION);
2825 pushnode(L, newnode, ndef);
2826 objectref_get_or_create(L, placer);
2827 if(lua_pcall(L, 3, 0, 0))
2828 script_error(L, "error: %s\n", lua_tostring(L, -1));
2829 // value removed, keep key for next iteration
2833 void scriptapi_environment_on_dignode(lua_State *L, v3s16 p, MapNode oldnode,
2834 ServerActiveObject *digger)
2837 assert(lua_checkstack(L, 20));
2838 //infostream<<"scriptapi_environment_on_dignode"<<std::endl;
2839 StackUnroller stack_unroller(L);
2841 // Get server from registry
2842 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
2843 Server *server = (Server*)lua_touserdata(L, -1);
2844 // And get the writable node definition manager from the server
2845 IWritableNodeDefManager *ndef =
2846 server->getWritableNodeDefManager();
2848 // Get minetest.registered_on_dignodes
2849 lua_getglobal(L, "minetest");
2850 lua_getfield(L, -1, "registered_on_dignodes");
2851 luaL_checktype(L, -1, LUA_TTABLE);
2852 int table = lua_gettop(L);
2855 while(lua_next(L, table) != 0){
2856 // key at index -2 and value at index -1
2857 luaL_checktype(L, -1, LUA_TFUNCTION);
2860 pushnode(L, oldnode, ndef);
2861 objectref_get_or_create(L, digger);
2862 if(lua_pcall(L, 3, 0, 0))
2863 script_error(L, "error: %s\n", lua_tostring(L, -1));
2864 // value removed, keep key for next iteration
2868 void scriptapi_environment_on_punchnode(lua_State *L, v3s16 p, MapNode node,
2869 ServerActiveObject *puncher)
2872 assert(lua_checkstack(L, 20));
2873 //infostream<<"scriptapi_environment_on_punchnode"<<std::endl;
2874 StackUnroller stack_unroller(L);
2876 // Get server from registry
2877 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
2878 Server *server = (Server*)lua_touserdata(L, -1);
2879 // And get the writable node definition manager from the server
2880 IWritableNodeDefManager *ndef =
2881 server->getWritableNodeDefManager();
2883 // Get minetest.registered_on_punchnodes
2884 lua_getglobal(L, "minetest");
2885 lua_getfield(L, -1, "registered_on_punchnodes");
2886 luaL_checktype(L, -1, LUA_TTABLE);
2887 int table = lua_gettop(L);
2890 while(lua_next(L, table) != 0){
2891 // key at index -2 and value at index -1
2892 luaL_checktype(L, -1, LUA_TFUNCTION);
2895 pushnode(L, node, ndef);
2896 objectref_get_or_create(L, puncher);
2897 if(lua_pcall(L, 3, 0, 0))
2898 script_error(L, "error: %s\n", lua_tostring(L, -1));
2899 // value removed, keep key for next iteration
2903 void scriptapi_environment_on_generated(lua_State *L, v3s16 minp, v3s16 maxp)
2906 assert(lua_checkstack(L, 20));
2907 //infostream<<"scriptapi_environment_on_generated"<<std::endl;
2908 StackUnroller stack_unroller(L);
2910 // Get minetest.registered_on_generateds
2911 lua_getglobal(L, "minetest");
2912 lua_getfield(L, -1, "registered_on_generateds");
2913 luaL_checktype(L, -1, LUA_TTABLE);
2914 int table = lua_gettop(L);
2917 while(lua_next(L, table) != 0){
2918 // key at index -2 and value at index -1
2919 luaL_checktype(L, -1, LUA_TFUNCTION);
2923 if(lua_pcall(L, 2, 0, 0))
2924 script_error(L, "error: %s\n", lua_tostring(L, -1));
2925 // value removed, keep key for next iteration
2933 bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
2934 const std::string &staticdata)
2937 assert(lua_checkstack(L, 20));
2938 infostream<<"scriptapi_luaentity_add: id="<<id<<" name=\""
2939 <<name<<"\""<<std::endl;
2940 StackUnroller stack_unroller(L);
2942 // Get minetest.registered_entities[name]
2943 lua_getglobal(L, "minetest");
2944 lua_getfield(L, -1, "registered_entities");
2945 luaL_checktype(L, -1, LUA_TTABLE);
2946 lua_pushstring(L, name);
2947 lua_gettable(L, -2);
2948 // Should be a table, which we will use as a prototype
2949 //luaL_checktype(L, -1, LUA_TTABLE);
2950 if(lua_type(L, -1) != LUA_TTABLE){
2951 errorstream<<"LuaEntity name \""<<name<<"\" not defined"<<std::endl;
2954 int prototype_table = lua_gettop(L);
2955 //dump2(L, "prototype_table");
2957 // Create entity object
2959 int object = lua_gettop(L);
2961 // Set object metatable
2962 lua_pushvalue(L, prototype_table);
2963 lua_setmetatable(L, -2);
2965 // Add object reference
2966 // This should be userdata with metatable ObjectRef
2967 objectref_get(L, id);
2968 luaL_checktype(L, -1, LUA_TUSERDATA);
2969 if(!luaL_checkudata(L, -1, "ObjectRef"))
2970 luaL_typerror(L, -1, "ObjectRef");
2971 lua_setfield(L, -2, "object");
2973 // minetest.luaentities[id] = object
2974 lua_getglobal(L, "minetest");
2975 lua_getfield(L, -1, "luaentities");
2976 luaL_checktype(L, -1, LUA_TTABLE);
2977 lua_pushnumber(L, id); // Push id
2978 lua_pushvalue(L, object); // Copy object to top of stack
2979 lua_settable(L, -3);
2981 // Get on_activate function
2982 lua_pushvalue(L, object);
2983 lua_getfield(L, -1, "on_activate");
2984 if(!lua_isnil(L, -1)){
2985 luaL_checktype(L, -1, LUA_TFUNCTION);
2986 lua_pushvalue(L, object); // self
2987 lua_pushlstring(L, staticdata.c_str(), staticdata.size());
2988 // Call with 2 arguments, 0 results
2989 if(lua_pcall(L, 2, 0, 0))
2990 script_error(L, "error running function %s:on_activate: %s\n",
2991 name, lua_tostring(L, -1));
2997 void scriptapi_luaentity_rm(lua_State *L, u16 id)
3000 assert(lua_checkstack(L, 20));
3001 infostream<<"scriptapi_luaentity_rm: id="<<id<<std::endl;
3003 // Get minetest.luaentities table
3004 lua_getglobal(L, "minetest");
3005 lua_getfield(L, -1, "luaentities");
3006 luaL_checktype(L, -1, LUA_TTABLE);
3007 int objectstable = lua_gettop(L);
3009 // Set luaentities[id] = nil
3010 lua_pushnumber(L, id); // Push id
3012 lua_settable(L, objectstable);
3014 lua_pop(L, 2); // pop luaentities, minetest
3017 std::string scriptapi_luaentity_get_staticdata(lua_State *L, u16 id)
3020 assert(lua_checkstack(L, 20));
3021 infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl;
3022 StackUnroller stack_unroller(L);
3024 // Get minetest.luaentities[id]
3025 luaentity_get(L, id);
3026 int object = lua_gettop(L);
3028 // Get get_staticdata function
3029 lua_pushvalue(L, object);
3030 lua_getfield(L, -1, "get_staticdata");
3031 if(lua_isnil(L, -1))
3034 luaL_checktype(L, -1, LUA_TFUNCTION);
3035 lua_pushvalue(L, object); // self
3036 // Call with 1 arguments, 1 results
3037 if(lua_pcall(L, 1, 1, 0))
3038 script_error(L, "error running function get_staticdata: %s\n",
3039 lua_tostring(L, -1));
3042 const char *s = lua_tolstring(L, -1, &len);
3043 return std::string(s, len);
3046 void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
3047 LuaEntityProperties *prop)
3050 assert(lua_checkstack(L, 20));
3051 infostream<<"scriptapi_luaentity_get_properties: id="<<id<<std::endl;
3052 StackUnroller stack_unroller(L);
3054 // Get minetest.luaentities[id]
3055 luaentity_get(L, id);
3056 //int object = lua_gettop(L);
3060 getboolfield(L, -1, "physical", prop->physical);
3062 getfloatfield(L, -1, "weight", prop->weight);
3064 lua_getfield(L, -1, "collisionbox");
3065 if(lua_istable(L, -1))
3066 prop->collisionbox = read_aabbox3df32(L, -1, 1.0);
3069 getstringfield(L, -1, "visual", prop->visual);
3071 lua_getfield(L, -1, "visual_size");
3072 if(lua_istable(L, -1))
3073 prop->visual_size = read_v2f(L, -1);
3076 lua_getfield(L, -1, "textures");
3077 if(lua_istable(L, -1)){
3078 prop->textures.clear();
3079 int table = lua_gettop(L);
3081 while(lua_next(L, table) != 0){
3082 // key at index -2 and value at index -1
3083 if(lua_isstring(L, -1))
3084 prop->textures.push_back(lua_tostring(L, -1));
3086 prop->textures.push_back("");
3087 // removes value, keeps key for next iteration
3093 lua_getfield(L, -1, "spritediv");
3094 if(lua_istable(L, -1))
3095 prop->spritediv = read_v2s16(L, -1);
3098 lua_getfield(L, -1, "initial_sprite_basepos");
3099 if(lua_istable(L, -1))
3100 prop->initial_sprite_basepos = read_v2s16(L, -1);
3104 void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime)
3107 assert(lua_checkstack(L, 20));
3108 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
3109 StackUnroller stack_unroller(L);
3111 // Get minetest.luaentities[id]
3112 luaentity_get(L, id);
3113 int object = lua_gettop(L);
3114 // State: object is at top of stack
3115 // Get step function
3116 lua_getfield(L, -1, "on_step");
3117 if(lua_isnil(L, -1))
3119 luaL_checktype(L, -1, LUA_TFUNCTION);
3120 lua_pushvalue(L, object); // self
3121 lua_pushnumber(L, dtime); // dtime
3122 // Call with 2 arguments, 0 results
3123 if(lua_pcall(L, 2, 0, 0))
3124 script_error(L, "error running function 'on_step': %s\n", lua_tostring(L, -1));
3127 // Calls entity:on_punch(ObjectRef puncher)
3128 void scriptapi_luaentity_punch(lua_State *L, u16 id,
3129 ServerActiveObject *puncher)
3132 assert(lua_checkstack(L, 20));
3133 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
3134 StackUnroller stack_unroller(L);
3136 // Get minetest.luaentities[id]
3137 luaentity_get(L, id);
3138 int object = lua_gettop(L);
3139 // State: object is at top of stack
3141 lua_getfield(L, -1, "on_punch");
3142 if(lua_isnil(L, -1))
3144 luaL_checktype(L, -1, LUA_TFUNCTION);
3145 lua_pushvalue(L, object); // self
3146 objectref_get_or_create(L, puncher); // Clicker reference
3147 // Call with 2 arguments, 0 results
3148 if(lua_pcall(L, 2, 0, 0))
3149 script_error(L, "error running function 'on_punch': %s\n", lua_tostring(L, -1));
3152 // Calls entity:on_rightclick(ObjectRef clicker)
3153 void scriptapi_luaentity_rightclick(lua_State *L, u16 id,
3154 ServerActiveObject *clicker)
3157 assert(lua_checkstack(L, 20));
3158 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
3159 StackUnroller stack_unroller(L);
3161 // Get minetest.luaentities[id]
3162 luaentity_get(L, id);
3163 int object = lua_gettop(L);
3164 // State: object is at top of stack
3166 lua_getfield(L, -1, "on_rightclick");
3167 if(lua_isnil(L, -1))
3169 luaL_checktype(L, -1, LUA_TFUNCTION);
3170 lua_pushvalue(L, object); // self
3171 objectref_get_or_create(L, clicker); // Clicker reference
3172 // Call with 2 arguments, 0 results
3173 if(lua_pcall(L, 2, 0, 0))
3174 script_error(L, "error running function 'on_rightclick': %s\n", lua_tostring(L, -1));