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 Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser 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"
36 #include "object_properties.h"
37 #include "content_sao.h" // For LuaEntitySAO and PlayerSAO
41 #include "main.h" // For g_settings
42 #include "settings.h" // For accessing g_settings
43 #include "nodemetadata.h"
44 #include "mapblock.h" // For getNodeBlockPos
45 #include "content_nodemeta.h"
47 #include "daynightratio.h"
48 #include "noise.h" // PseudoRandom for LuaPseudoRandom
49 #include "util/pointedthing.h"
52 static void stackDump(lua_State *L, std::ostream &o)
55 int top = lua_gettop(L);
56 for (i = 1; i <= top; i++) { /* repeat for each level */
57 int t = lua_type(L, i);
60 case LUA_TSTRING: /* strings */
61 o<<"\""<<lua_tostring(L, i)<<"\"";
64 case LUA_TBOOLEAN: /* booleans */
65 o<<(lua_toboolean(L, i) ? "true" : "false");
68 case LUA_TNUMBER: /* numbers */ {
70 snprintf(buf, 10, "%g", lua_tonumber(L, i));
74 default: /* other values */
75 o<<lua_typename(L, t);
84 static void realitycheck(lua_State *L)
86 int top = lua_gettop(L);
88 dstream<<"Stack is over 30:"<<std::endl;
89 stackDump(L, dstream);
90 script_error(L, "Stack is over 30 (reality check)");
100 StackUnroller(lua_State *L):
104 m_original_top = lua_gettop(m_lua); // store stack height
108 lua_settop(m_lua, m_original_top); // restore stack height
117 ModNameStorer(lua_State *L_, const std::string modname):
120 // Store current modname in registry
121 lua_pushstring(L, modname.c_str());
122 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
126 // Clear current modname in registry
128 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
133 Getters for stuff in main tables
136 static Server* get_server(lua_State *L)
138 // Get server from registry
139 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
140 Server *server = (Server*)lua_touserdata(L, -1);
145 static ServerEnvironment* get_env(lua_State *L)
147 // Get environment from registry
148 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_env");
149 ServerEnvironment *env = (ServerEnvironment*)lua_touserdata(L, -1);
154 static void objectref_get(lua_State *L, u16 id)
156 // Get minetest.object_refs[i]
157 lua_getglobal(L, "minetest");
158 lua_getfield(L, -1, "object_refs");
159 luaL_checktype(L, -1, LUA_TTABLE);
160 lua_pushnumber(L, id);
162 lua_remove(L, -2); // object_refs
163 lua_remove(L, -2); // minetest
166 static void luaentity_get(lua_State *L, u16 id)
168 // Get minetest.luaentities[i]
169 lua_getglobal(L, "minetest");
170 lua_getfield(L, -1, "luaentities");
171 luaL_checktype(L, -1, LUA_TTABLE);
172 lua_pushnumber(L, id);
174 lua_remove(L, -2); // luaentities
175 lua_remove(L, -2); // minetest
182 static bool getstringfield(lua_State *L, int table,
183 const char *fieldname, std::string &result)
185 lua_getfield(L, table, fieldname);
187 if(lua_isstring(L, -1)){
189 const char *ptr = lua_tolstring(L, -1, &len);
190 result.assign(ptr, len);
197 static bool getintfield(lua_State *L, int table,
198 const char *fieldname, int &result)
200 lua_getfield(L, table, fieldname);
202 if(lua_isnumber(L, -1)){
203 result = lua_tonumber(L, -1);
210 static bool getfloatfield(lua_State *L, int table,
211 const char *fieldname, float &result)
213 lua_getfield(L, table, fieldname);
215 if(lua_isnumber(L, -1)){
216 result = lua_tonumber(L, -1);
223 static bool getboolfield(lua_State *L, int table,
224 const char *fieldname, bool &result)
226 lua_getfield(L, table, fieldname);
228 if(lua_isboolean(L, -1)){
229 result = lua_toboolean(L, -1);
236 static std::string checkstringfield(lua_State *L, int table,
237 const char *fieldname)
239 lua_getfield(L, table, fieldname);
240 std::string s = luaL_checkstring(L, -1);
245 static std::string getstringfield_default(lua_State *L, int table,
246 const char *fieldname, const std::string &default_)
248 std::string result = default_;
249 getstringfield(L, table, fieldname, result);
253 static int getintfield_default(lua_State *L, int table,
254 const char *fieldname, int default_)
256 int result = default_;
257 getintfield(L, table, fieldname, result);
261 static float getfloatfield_default(lua_State *L, int table,
262 const char *fieldname, float default_)
264 float result = default_;
265 getfloatfield(L, table, fieldname, result);
269 static bool getboolfield_default(lua_State *L, int table,
270 const char *fieldname, bool default_)
272 bool result = default_;
273 getboolfield(L, table, fieldname, result);
283 static bool string_to_enum(const EnumString *spec, int &result,
284 const std::string &str)
286 const EnumString *esp = spec;
288 if(str == std::string(esp->str)){
297 /*static bool enum_to_string(const EnumString *spec, std::string &result,
300 const EnumString *esp = spec;
311 static int getenumfield(lua_State *L, int table,
312 const char *fieldname, const EnumString *spec, int default_)
314 int result = default_;
315 string_to_enum(spec, result,
316 getstringfield_default(L, table, fieldname, ""));
320 static void setintfield(lua_State *L, int table,
321 const char *fieldname, int value)
323 lua_pushinteger(L, value);
326 lua_setfield(L, table, fieldname);
329 static void setfloatfield(lua_State *L, int table,
330 const char *fieldname, float value)
332 lua_pushnumber(L, value);
335 lua_setfield(L, table, fieldname);
338 static void setboolfield(lua_State *L, int table,
339 const char *fieldname, bool value)
341 lua_pushboolean(L, value);
344 lua_setfield(L, table, fieldname);
347 static void warn_if_field_exists(lua_State *L, int table,
348 const char *fieldname, const std::string &message)
350 lua_getfield(L, table, fieldname);
351 if(!lua_isnil(L, -1)){
352 infostream<<script_get_backtrace(L)<<std::endl;
353 infostream<<"WARNING: field \""<<fieldname<<"\": "
354 <<message<<std::endl;
360 EnumString definitions
363 struct EnumString es_ItemType[] =
367 {ITEM_CRAFT, "craft"},
372 struct EnumString es_DrawType[] =
374 {NDT_NORMAL, "normal"},
375 {NDT_AIRLIKE, "airlike"},
376 {NDT_LIQUID, "liquid"},
377 {NDT_FLOWINGLIQUID, "flowingliquid"},
378 {NDT_GLASSLIKE, "glasslike"},
379 {NDT_ALLFACES, "allfaces"},
380 {NDT_ALLFACES_OPTIONAL, "allfaces_optional"},
381 {NDT_TORCHLIKE, "torchlike"},
382 {NDT_SIGNLIKE, "signlike"},
383 {NDT_PLANTLIKE, "plantlike"},
384 {NDT_FENCELIKE, "fencelike"},
385 {NDT_RAILLIKE, "raillike"},
386 {NDT_NODEBOX, "nodebox"},
390 struct EnumString es_ContentParamType[] =
393 {CPT_LIGHT, "light"},
397 struct EnumString es_ContentParamType2[] =
401 {CPT2_FLOWINGLIQUID, "flowingliquid"},
402 {CPT2_FACEDIR, "facedir"},
403 {CPT2_WALLMOUNTED, "wallmounted"},
407 struct EnumString es_LiquidType[] =
409 {LIQUID_NONE, "none"},
410 {LIQUID_FLOWING, "flowing"},
411 {LIQUID_SOURCE, "source"},
415 struct EnumString es_NodeBoxType[] =
417 {NODEBOX_REGULAR, "regular"},
418 {NODEBOX_FIXED, "fixed"},
419 {NODEBOX_WALLMOUNTED, "wallmounted"},
423 struct EnumString es_CraftMethod[] =
425 {CRAFT_METHOD_NORMAL, "normal"},
426 {CRAFT_METHOD_COOKING, "cooking"},
427 {CRAFT_METHOD_FUEL, "fuel"},
431 struct EnumString es_TileAnimationType[] =
434 {TAT_VERTICAL_FRAMES, "vertical_frames"},
439 C struct <-> Lua table converter functions
442 static void push_v3f(lua_State *L, v3f p)
445 lua_pushnumber(L, p.X);
446 lua_setfield(L, -2, "x");
447 lua_pushnumber(L, p.Y);
448 lua_setfield(L, -2, "y");
449 lua_pushnumber(L, p.Z);
450 lua_setfield(L, -2, "z");
453 static v2s16 read_v2s16(lua_State *L, int index)
456 luaL_checktype(L, index, LUA_TTABLE);
457 lua_getfield(L, index, "x");
458 p.X = lua_tonumber(L, -1);
460 lua_getfield(L, index, "y");
461 p.Y = lua_tonumber(L, -1);
466 static v2f read_v2f(lua_State *L, int index)
469 luaL_checktype(L, index, LUA_TTABLE);
470 lua_getfield(L, index, "x");
471 p.X = lua_tonumber(L, -1);
473 lua_getfield(L, index, "y");
474 p.Y = lua_tonumber(L, -1);
479 static v3f read_v3f(lua_State *L, int index)
482 luaL_checktype(L, index, LUA_TTABLE);
483 lua_getfield(L, index, "x");
484 pos.X = lua_tonumber(L, -1);
486 lua_getfield(L, index, "y");
487 pos.Y = lua_tonumber(L, -1);
489 lua_getfield(L, index, "z");
490 pos.Z = lua_tonumber(L, -1);
495 static v3f check_v3f(lua_State *L, int index)
498 luaL_checktype(L, index, LUA_TTABLE);
499 lua_getfield(L, index, "x");
500 pos.X = luaL_checknumber(L, -1);
502 lua_getfield(L, index, "y");
503 pos.Y = luaL_checknumber(L, -1);
505 lua_getfield(L, index, "z");
506 pos.Z = luaL_checknumber(L, -1);
511 static void pushFloatPos(lua_State *L, v3f p)
517 static v3f checkFloatPos(lua_State *L, int index)
519 return check_v3f(L, index) * BS;
522 static void push_v3s16(lua_State *L, v3s16 p)
525 lua_pushnumber(L, p.X);
526 lua_setfield(L, -2, "x");
527 lua_pushnumber(L, p.Y);
528 lua_setfield(L, -2, "y");
529 lua_pushnumber(L, p.Z);
530 lua_setfield(L, -2, "z");
533 static v3s16 read_v3s16(lua_State *L, int index)
535 // Correct rounding at <0
536 v3f pf = read_v3f(L, index);
537 return floatToInt(pf, 1.0);
540 static v3s16 check_v3s16(lua_State *L, int index)
542 // Correct rounding at <0
543 v3f pf = check_v3f(L, index);
544 return floatToInt(pf, 1.0);
547 static void pushnode(lua_State *L, const MapNode &n, INodeDefManager *ndef)
550 lua_pushstring(L, ndef->get(n).name.c_str());
551 lua_setfield(L, -2, "name");
552 lua_pushnumber(L, n.getParam1());
553 lua_setfield(L, -2, "param1");
554 lua_pushnumber(L, n.getParam2());
555 lua_setfield(L, -2, "param2");
558 static MapNode readnode(lua_State *L, int index, INodeDefManager *ndef)
560 lua_getfield(L, index, "name");
561 const char *name = luaL_checkstring(L, -1);
564 lua_getfield(L, index, "param1");
568 param1 = lua_tonumber(L, -1);
571 lua_getfield(L, index, "param2");
575 param2 = lua_tonumber(L, -1);
577 return MapNode(ndef, name, param1, param2);
580 static video::SColor readARGB8(lua_State *L, int index)
583 luaL_checktype(L, index, LUA_TTABLE);
584 lua_getfield(L, index, "a");
585 if(lua_isnumber(L, -1))
586 color.setAlpha(lua_tonumber(L, -1));
588 lua_getfield(L, index, "r");
589 color.setRed(lua_tonumber(L, -1));
591 lua_getfield(L, index, "g");
592 color.setGreen(lua_tonumber(L, -1));
594 lua_getfield(L, index, "b");
595 color.setBlue(lua_tonumber(L, -1));
600 static aabb3f read_aabb3f(lua_State *L, int index, f32 scale)
603 if(lua_istable(L, index)){
604 lua_rawgeti(L, index, 1);
605 box.MinEdge.X = lua_tonumber(L, -1) * scale;
607 lua_rawgeti(L, index, 2);
608 box.MinEdge.Y = lua_tonumber(L, -1) * scale;
610 lua_rawgeti(L, index, 3);
611 box.MinEdge.Z = lua_tonumber(L, -1) * scale;
613 lua_rawgeti(L, index, 4);
614 box.MaxEdge.X = lua_tonumber(L, -1) * scale;
616 lua_rawgeti(L, index, 5);
617 box.MaxEdge.Y = lua_tonumber(L, -1) * scale;
619 lua_rawgeti(L, index, 6);
620 box.MaxEdge.Z = lua_tonumber(L, -1) * scale;
626 static std::vector<aabb3f> read_aabb3f_vector(lua_State *L, int index, f32 scale)
628 std::vector<aabb3f> boxes;
629 if(lua_istable(L, index)){
630 int n = lua_objlen(L, index);
631 // Check if it's a single box or a list of boxes
632 bool possibly_single_box = (n == 6);
633 for(int i = 1; i <= n && possibly_single_box; i++){
634 lua_rawgeti(L, index, i);
635 if(!lua_isnumber(L, -1))
636 possibly_single_box = false;
639 if(possibly_single_box){
641 boxes.push_back(read_aabb3f(L, index, scale));
643 // Read a list of boxes
644 for(int i = 1; i <= n; i++){
645 lua_rawgeti(L, index, i);
646 boxes.push_back(read_aabb3f(L, -1, scale));
654 static NodeBox read_nodebox(lua_State *L, int index)
657 if(lua_istable(L, -1)){
658 nodebox.type = (NodeBoxType)getenumfield(L, index, "type",
659 es_NodeBoxType, NODEBOX_REGULAR);
661 lua_getfield(L, index, "fixed");
662 if(lua_istable(L, -1))
663 nodebox.fixed = read_aabb3f_vector(L, -1, BS);
666 lua_getfield(L, index, "wall_top");
667 if(lua_istable(L, -1))
668 nodebox.wall_top = read_aabb3f(L, -1, BS);
671 lua_getfield(L, index, "wall_bottom");
672 if(lua_istable(L, -1))
673 nodebox.wall_bottom = read_aabb3f(L, -1, BS);
676 lua_getfield(L, index, "wall_side");
677 if(lua_istable(L, -1))
678 nodebox.wall_side = read_aabb3f(L, -1, BS);
687 static void read_groups(lua_State *L, int index,
688 std::map<std::string, int> &result)
690 if (!lua_istable(L,index))
696 while(lua_next(L, index) != 0){
697 // key at index -2 and value at index -1
698 std::string name = luaL_checkstring(L, -2);
699 int rating = luaL_checkinteger(L, -1);
700 result[name] = rating;
701 // removes value, keeps key for next iteration
709 static void read_privileges(lua_State *L, int index,
710 std::set<std::string> &result)
716 while(lua_next(L, index) != 0){
717 // key at index -2 and value at index -1
718 std::string key = luaL_checkstring(L, -2);
719 bool value = lua_toboolean(L, -1);
722 // removes value, keeps key for next iteration
731 static ToolCapabilities read_tool_capabilities(
732 lua_State *L, int table)
734 ToolCapabilities toolcap;
735 getfloatfield(L, table, "full_punch_interval", toolcap.full_punch_interval);
736 getintfield(L, table, "max_drop_level", toolcap.max_drop_level);
737 lua_getfield(L, table, "groupcaps");
738 if(lua_istable(L, -1)){
739 int table_groupcaps = lua_gettop(L);
741 while(lua_next(L, table_groupcaps) != 0){
742 // key at index -2 and value at index -1
743 std::string groupname = luaL_checkstring(L, -2);
744 if(lua_istable(L, -1)){
745 int table_groupcap = lua_gettop(L);
746 // This will be created
747 ToolGroupCap groupcap;
748 // Read simple parameters
749 getintfield(L, table_groupcap, "maxlevel", groupcap.maxlevel);
750 getintfield(L, table_groupcap, "uses", groupcap.uses);
751 // DEPRECATED: maxwear
753 if(getfloatfield(L, table_groupcap, "maxwear", maxwear)){
755 groupcap.uses = 1.0/maxwear;
758 infostream<<script_get_backtrace(L)<<std::endl;
759 infostream<<"WARNING: field \"maxwear\" is deprecated; "
760 <<"should replace with uses=1/maxwear"<<std::endl;
762 // Read "times" table
763 lua_getfield(L, table_groupcap, "times");
764 if(lua_istable(L, -1)){
765 int table_times = lua_gettop(L);
767 while(lua_next(L, table_times) != 0){
768 // key at index -2 and value at index -1
769 int rating = luaL_checkinteger(L, -2);
770 float time = luaL_checknumber(L, -1);
771 groupcap.times[rating] = time;
772 // removes value, keeps key for next iteration
777 // Insert groupcap into toolcap
778 toolcap.groupcaps[groupname] = groupcap;
780 // removes value, keeps key for next iteration
788 static void set_tool_capabilities(lua_State *L, int table,
789 const ToolCapabilities &toolcap)
791 setfloatfield(L, table, "full_punch_interval", toolcap.full_punch_interval);
792 setintfield(L, table, "max_drop_level", toolcap.max_drop_level);
793 // Create groupcaps table
796 for(std::map<std::string, ToolGroupCap>::const_iterator
797 i = toolcap.groupcaps.begin(); i != toolcap.groupcaps.end(); i++){
798 // Create groupcap table
800 const std::string &name = i->first;
801 const ToolGroupCap &groupcap = i->second;
802 // Create subtable "times"
804 for(std::map<int, float>::const_iterator
805 i = groupcap.times.begin(); i != groupcap.times.end(); i++){
806 int rating = i->first;
807 float time = i->second;
808 lua_pushinteger(L, rating);
809 lua_pushnumber(L, time);
812 // Set subtable "times"
813 lua_setfield(L, -2, "times");
814 // Set simple parameters
815 setintfield(L, -1, "maxlevel", groupcap.maxlevel);
816 setintfield(L, -1, "uses", groupcap.uses);
817 // Insert groupcap table into groupcaps table
818 lua_setfield(L, -2, name.c_str());
820 // Set groupcaps table
821 lua_setfield(L, -2, "groupcaps");
824 static void push_tool_capabilities(lua_State *L,
825 const ToolCapabilities &prop)
828 set_tool_capabilities(L, -1, prop);
835 static void set_dig_params(lua_State *L, int table,
836 const DigParams ¶ms)
838 setboolfield(L, table, "diggable", params.diggable);
839 setfloatfield(L, table, "time", params.time);
840 setintfield(L, table, "wear", params.wear);
843 static void push_dig_params(lua_State *L,
844 const DigParams ¶ms)
847 set_dig_params(L, -1, params);
854 static void set_hit_params(lua_State *L, int table,
855 const HitParams ¶ms)
857 setintfield(L, table, "hp", params.hp);
858 setintfield(L, table, "wear", params.wear);
861 static void push_hit_params(lua_State *L,
862 const HitParams ¶ms)
865 set_hit_params(L, -1, params);
872 static void push_pointed_thing(lua_State *L, const PointedThing& pointed)
875 if(pointed.type == POINTEDTHING_NODE)
877 lua_pushstring(L, "node");
878 lua_setfield(L, -2, "type");
879 push_v3s16(L, pointed.node_undersurface);
880 lua_setfield(L, -2, "under");
881 push_v3s16(L, pointed.node_abovesurface);
882 lua_setfield(L, -2, "above");
884 else if(pointed.type == POINTEDTHING_OBJECT)
886 lua_pushstring(L, "object");
887 lua_setfield(L, -2, "type");
888 objectref_get(L, pointed.object_id);
889 lua_setfield(L, -2, "ref");
893 lua_pushstring(L, "nothing");
894 lua_setfield(L, -2, "type");
902 static void read_soundspec(lua_State *L, int index, SimpleSoundSpec &spec)
905 index = lua_gettop(L) + 1 + index;
906 if(lua_isnil(L, index)){
907 } else if(lua_istable(L, index)){
908 getstringfield(L, index, "name", spec.name);
909 getfloatfield(L, index, "gain", spec.gain);
910 } else if(lua_isstring(L, index)){
911 spec.name = lua_tostring(L, index);
919 static void read_object_properties(lua_State *L, int index,
920 ObjectProperties *prop)
923 index = lua_gettop(L) + 1 + index;
924 if(!lua_istable(L, index))
927 prop->hp_max = getintfield_default(L, -1, "hp_max", 10);
929 getboolfield(L, -1, "physical", prop->physical);
931 getfloatfield(L, -1, "weight", prop->weight);
933 lua_getfield(L, -1, "collisionbox");
934 if(lua_istable(L, -1))
935 prop->collisionbox = read_aabb3f(L, -1, 1.0);
938 getstringfield(L, -1, "visual", prop->visual);
940 getstringfield(L, -1, "mesh", prop->mesh);
942 lua_getfield(L, -1, "visual_size");
943 if(lua_istable(L, -1))
944 prop->visual_size = read_v2f(L, -1);
947 lua_getfield(L, -1, "animation_bone_position");
948 if(lua_istable(L, -1))
950 lua_rawgeti (L, -1, 1);
951 lua_rawgeti (L, -2, 2);
952 std::string bone_name = lua_tostring(L, -2);
953 v3f bone_pos = read_v3f(L, -1);
954 prop->animation_bone_position[bone_name] = bone_pos;
959 lua_getfield(L, -1, "animation_bone_rotation");
960 if(lua_istable(L, -1))
962 lua_rawgeti (L, -1, 1);
963 lua_rawgeti (L, -2, 2);
964 std::string bone_name = lua_tostring(L, -2);
965 v3f bone_rot = read_v3f(L, -1);
966 prop->animation_bone_rotation[bone_name] = bone_rot;
971 lua_getfield(L, -1, "textures");
972 if(lua_istable(L, -1)){
973 prop->textures.clear();
974 int table = lua_gettop(L);
976 while(lua_next(L, table) != 0){
977 // key at index -2 and value at index -1
978 if(lua_isstring(L, -1))
979 prop->textures.push_back(lua_tostring(L, -1));
981 prop->textures.push_back("");
982 // removes value, keeps key for next iteration
988 lua_getfield(L, -1, "spritediv");
989 if(lua_istable(L, -1))
990 prop->spritediv = read_v2s16(L, -1);
993 lua_getfield(L, -1, "initial_sprite_basepos");
994 if(lua_istable(L, -1))
995 prop->initial_sprite_basepos = read_v2s16(L, -1);
998 getboolfield(L, -1, "is_visible", prop->is_visible);
999 getboolfield(L, -1, "makes_footstep_sound", prop->makes_footstep_sound);
1000 getfloatfield(L, -1, "automatic_rotate", prop->automatic_rotate);
1007 static ItemDefinition read_item_definition(lua_State *L, int index,
1008 ItemDefinition default_def = ItemDefinition())
1011 index = lua_gettop(L) + 1 + index;
1013 // Read the item definition
1014 ItemDefinition def = default_def;
1016 def.type = (ItemType)getenumfield(L, index, "type",
1017 es_ItemType, ITEM_NONE);
1018 getstringfield(L, index, "name", def.name);
1019 getstringfield(L, index, "description", def.description);
1020 getstringfield(L, index, "inventory_image", def.inventory_image);
1021 getstringfield(L, index, "wield_image", def.wield_image);
1023 lua_getfield(L, index, "wield_scale");
1024 if(lua_istable(L, -1)){
1025 def.wield_scale = check_v3f(L, -1);
1029 def.stack_max = getintfield_default(L, index, "stack_max", def.stack_max);
1030 if(def.stack_max == 0)
1033 lua_getfield(L, index, "on_use");
1034 def.usable = lua_isfunction(L, -1);
1037 getboolfield(L, index, "liquids_pointable", def.liquids_pointable);
1039 warn_if_field_exists(L, index, "tool_digging_properties",
1040 "deprecated: use tool_capabilities");
1042 lua_getfield(L, index, "tool_capabilities");
1043 if(lua_istable(L, -1)){
1044 def.tool_capabilities = new ToolCapabilities(
1045 read_tool_capabilities(L, -1));
1048 // If name is "" (hand), ensure there are ToolCapabilities
1049 // because it will be looked up there whenever any other item has
1050 // no ToolCapabilities
1051 if(def.name == "" && def.tool_capabilities == NULL){
1052 def.tool_capabilities = new ToolCapabilities();
1055 lua_getfield(L, index, "groups");
1056 read_groups(L, -1, def.groups);
1059 // Client shall immediately place this node when player places the item.
1060 // Server will update the precise end result a moment later.
1061 // "" = no prediction
1062 getstringfield(L, index, "node_placement_prediction",
1063 def.node_placement_prediction);
1072 static TileDef read_tiledef(lua_State *L, int index)
1075 index = lua_gettop(L) + 1 + index;
1079 // key at index -2 and value at index
1080 if(lua_isstring(L, index)){
1081 // "default_lava.png"
1082 tiledef.name = lua_tostring(L, index);
1084 else if(lua_istable(L, index))
1086 // {name="default_lava.png", animation={}}
1088 getstringfield(L, index, "name", tiledef.name);
1089 getstringfield(L, index, "image", tiledef.name); // MaterialSpec compat.
1090 tiledef.backface_culling = getboolfield_default(
1091 L, index, "backface_culling", true);
1093 lua_getfield(L, index, "animation");
1094 if(lua_istable(L, -1)){
1095 // {type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}
1096 tiledef.animation.type = (TileAnimationType)
1097 getenumfield(L, -1, "type", es_TileAnimationType,
1099 tiledef.animation.aspect_w =
1100 getintfield_default(L, -1, "aspect_w", 16);
1101 tiledef.animation.aspect_h =
1102 getintfield_default(L, -1, "aspect_h", 16);
1103 tiledef.animation.length =
1104 getfloatfield_default(L, -1, "length", 1.0);
1116 static ContentFeatures read_content_features(lua_State *L, int index)
1119 index = lua_gettop(L) + 1 + index;
1123 /* Cache existence of some callbacks */
1124 lua_getfield(L, index, "on_construct");
1125 if(!lua_isnil(L, -1)) f.has_on_construct = true;
1127 lua_getfield(L, index, "on_destruct");
1128 if(!lua_isnil(L, -1)) f.has_on_destruct = true;
1130 lua_getfield(L, index, "after_destruct");
1131 if(!lua_isnil(L, -1)) f.has_after_destruct = true;
1135 getstringfield(L, index, "name", f.name);
1138 lua_getfield(L, index, "groups");
1139 read_groups(L, -1, f.groups);
1142 /* Visual definition */
1144 f.drawtype = (NodeDrawType)getenumfield(L, index, "drawtype", es_DrawType,
1146 getfloatfield(L, index, "visual_scale", f.visual_scale);
1149 lua_getfield(L, index, "tiles");
1150 // If nil, try the deprecated name "tile_images" instead
1151 if(lua_isnil(L, -1)){
1153 warn_if_field_exists(L, index, "tile_images",
1154 "Deprecated; new name is \"tiles\".");
1155 lua_getfield(L, index, "tile_images");
1157 if(lua_istable(L, -1)){
1158 int table = lua_gettop(L);
1161 while(lua_next(L, table) != 0){
1162 // Read tiledef from value
1163 f.tiledef[i] = read_tiledef(L, -1);
1164 // removes value, keeps key for next iteration
1172 // Copy last value to all remaining textures
1174 TileDef lasttile = f.tiledef[i-1];
1176 f.tiledef[i] = lasttile;
1183 // special_tiles = {}
1184 lua_getfield(L, index, "special_tiles");
1185 // If nil, try the deprecated name "special_materials" instead
1186 if(lua_isnil(L, -1)){
1188 warn_if_field_exists(L, index, "special_materials",
1189 "Deprecated; new name is \"special_tiles\".");
1190 lua_getfield(L, index, "special_materials");
1192 if(lua_istable(L, -1)){
1193 int table = lua_gettop(L);
1196 while(lua_next(L, table) != 0){
1197 // Read tiledef from value
1198 f.tiledef_special[i] = read_tiledef(L, -1);
1199 // removes value, keeps key for next iteration
1210 f.alpha = getintfield_default(L, index, "alpha", 255);
1214 lua_getfield(L, index, "post_effect_color");
1215 if(!lua_isnil(L, -1))
1216 f.post_effect_color = readARGB8(L, -1);
1219 f.param_type = (ContentParamType)getenumfield(L, index, "paramtype",
1220 es_ContentParamType, CPT_NONE);
1221 f.param_type_2 = (ContentParamType2)getenumfield(L, index, "paramtype2",
1222 es_ContentParamType2, CPT2_NONE);
1224 // Warn about some deprecated fields
1225 warn_if_field_exists(L, index, "wall_mounted",
1226 "deprecated: use paramtype2 = 'wallmounted'");
1227 warn_if_field_exists(L, index, "light_propagates",
1228 "deprecated: determined from paramtype");
1229 warn_if_field_exists(L, index, "dug_item",
1230 "deprecated: use 'drop' field");
1231 warn_if_field_exists(L, index, "extra_dug_item",
1232 "deprecated: use 'drop' field");
1233 warn_if_field_exists(L, index, "extra_dug_item_rarity",
1234 "deprecated: use 'drop' field");
1235 warn_if_field_exists(L, index, "metadata_name",
1236 "deprecated: use on_add and metadata callbacks");
1238 // True for all ground-like things like stone and mud, false for eg. trees
1239 getboolfield(L, index, "is_ground_content", f.is_ground_content);
1240 f.light_propagates = (f.param_type == CPT_LIGHT);
1241 getboolfield(L, index, "sunlight_propagates", f.sunlight_propagates);
1242 // This is used for collision detection.
1243 // Also for general solidness queries.
1244 getboolfield(L, index, "walkable", f.walkable);
1245 // Player can point to these
1246 getboolfield(L, index, "pointable", f.pointable);
1247 // Player can dig these
1248 getboolfield(L, index, "diggable", f.diggable);
1249 // Player can climb these
1250 getboolfield(L, index, "climbable", f.climbable);
1251 // Player can build on these
1252 getboolfield(L, index, "buildable_to", f.buildable_to);
1253 // Whether the node is non-liquid, source liquid or flowing liquid
1254 f.liquid_type = (LiquidType)getenumfield(L, index, "liquidtype",
1255 es_LiquidType, LIQUID_NONE);
1256 // If the content is liquid, this is the flowing version of the liquid.
1257 getstringfield(L, index, "liquid_alternative_flowing",
1258 f.liquid_alternative_flowing);
1259 // If the content is liquid, this is the source version of the liquid.
1260 getstringfield(L, index, "liquid_alternative_source",
1261 f.liquid_alternative_source);
1262 // Viscosity for fluid flow, ranging from 1 to 7, with
1263 // 1 giving almost instantaneous propagation and 7 being
1264 // the slowest possible
1265 f.liquid_viscosity = getintfield_default(L, index,
1266 "liquid_viscosity", f.liquid_viscosity);
1267 getboolfield(L, index, "liquid_renewable", f.liquid_renewable);
1268 // Amount of light the node emits
1269 f.light_source = getintfield_default(L, index,
1270 "light_source", f.light_source);
1271 f.damage_per_second = getintfield_default(L, index,
1272 "damage_per_second", f.damage_per_second);
1274 lua_getfield(L, index, "node_box");
1275 if(lua_istable(L, -1))
1276 f.node_box = read_nodebox(L, -1);
1279 lua_getfield(L, index, "selection_box");
1280 if(lua_istable(L, -1))
1281 f.selection_box = read_nodebox(L, -1);
1284 // Set to true if paramtype used to be 'facedir_simple'
1285 getboolfield(L, index, "legacy_facedir_simple", f.legacy_facedir_simple);
1286 // Set to true if wall_mounted used to be set to true
1287 getboolfield(L, index, "legacy_wallmounted", f.legacy_wallmounted);
1290 lua_getfield(L, index, "sounds");
1291 if(lua_istable(L, -1)){
1292 lua_getfield(L, -1, "footstep");
1293 read_soundspec(L, -1, f.sound_footstep);
1295 lua_getfield(L, -1, "dig");
1296 read_soundspec(L, -1, f.sound_dig);
1298 lua_getfield(L, -1, "dug");
1299 read_soundspec(L, -1, f.sound_dug);
1311 static ItemStack read_item(lua_State *L, int index);
1312 static std::vector<ItemStack> read_items(lua_State *L, int index);
1313 // creates a table of ItemStacks
1314 static void push_items(lua_State *L, const std::vector<ItemStack> &items);
1316 static void inventory_set_list_from_lua(Inventory *inv, const char *name,
1317 lua_State *L, int tableindex, int forcesize=-1)
1320 tableindex = lua_gettop(L) + 1 + tableindex;
1321 // If nil, delete list
1322 if(lua_isnil(L, tableindex)){
1323 inv->deleteList(name);
1326 // Otherwise set list
1327 std::vector<ItemStack> items = read_items(L, tableindex);
1328 int listsize = (forcesize != -1) ? forcesize : items.size();
1329 InventoryList *invlist = inv->addList(name, listsize);
1331 for(std::vector<ItemStack>::const_iterator
1332 i = items.begin(); i != items.end(); i++){
1333 if(forcesize != -1 && index == forcesize)
1335 invlist->changeItem(index, *i);
1338 while(forcesize != -1 && index < forcesize){
1339 invlist->deleteItem(index);
1344 static void inventory_get_list_to_lua(Inventory *inv, const char *name,
1347 InventoryList *invlist = inv->getList(name);
1348 if(invlist == NULL){
1352 std::vector<ItemStack> items;
1353 for(u32 i=0; i<invlist->getSize(); i++)
1354 items.push_back(invlist->getItem(i));
1355 push_items(L, items);
1359 Helpful macros for userdata classes
1362 #define method(class, name) {#name, class::l_##name}
1373 static const char className[];
1374 static const luaL_reg methods[];
1376 // Exported functions
1378 // garbage collector
1379 static int gc_object(lua_State *L)
1381 LuaItemStack *o = *(LuaItemStack **)(lua_touserdata(L, 1));
1386 // is_empty(self) -> true/false
1387 static int l_is_empty(lua_State *L)
1389 LuaItemStack *o = checkobject(L, 1);
1390 ItemStack &item = o->m_stack;
1391 lua_pushboolean(L, item.empty());
1395 // get_name(self) -> string
1396 static int l_get_name(lua_State *L)
1398 LuaItemStack *o = checkobject(L, 1);
1399 ItemStack &item = o->m_stack;
1400 lua_pushstring(L, item.name.c_str());
1404 // get_count(self) -> number
1405 static int l_get_count(lua_State *L)
1407 LuaItemStack *o = checkobject(L, 1);
1408 ItemStack &item = o->m_stack;
1409 lua_pushinteger(L, item.count);
1413 // get_wear(self) -> number
1414 static int l_get_wear(lua_State *L)
1416 LuaItemStack *o = checkobject(L, 1);
1417 ItemStack &item = o->m_stack;
1418 lua_pushinteger(L, item.wear);
1422 // get_metadata(self) -> string
1423 static int l_get_metadata(lua_State *L)
1425 LuaItemStack *o = checkobject(L, 1);
1426 ItemStack &item = o->m_stack;
1427 lua_pushlstring(L, item.metadata.c_str(), item.metadata.size());
1431 // clear(self) -> true
1432 static int l_clear(lua_State *L)
1434 LuaItemStack *o = checkobject(L, 1);
1436 lua_pushboolean(L, true);
1440 // replace(self, itemstack or itemstring or table or nil) -> true
1441 static int l_replace(lua_State *L)
1443 LuaItemStack *o = checkobject(L, 1);
1444 o->m_stack = read_item(L, 2);
1445 lua_pushboolean(L, true);
1449 // to_string(self) -> string
1450 static int l_to_string(lua_State *L)
1452 LuaItemStack *o = checkobject(L, 1);
1453 std::string itemstring = o->m_stack.getItemString();
1454 lua_pushstring(L, itemstring.c_str());
1458 // to_table(self) -> table or nil
1459 static int l_to_table(lua_State *L)
1461 LuaItemStack *o = checkobject(L, 1);
1462 const ItemStack &item = o->m_stack;
1470 lua_pushstring(L, item.name.c_str());
1471 lua_setfield(L, -2, "name");
1472 lua_pushinteger(L, item.count);
1473 lua_setfield(L, -2, "count");
1474 lua_pushinteger(L, item.wear);
1475 lua_setfield(L, -2, "wear");
1476 lua_pushlstring(L, item.metadata.c_str(), item.metadata.size());
1477 lua_setfield(L, -2, "metadata");
1482 // get_stack_max(self) -> number
1483 static int l_get_stack_max(lua_State *L)
1485 LuaItemStack *o = checkobject(L, 1);
1486 ItemStack &item = o->m_stack;
1487 lua_pushinteger(L, item.getStackMax(get_server(L)->idef()));
1491 // get_free_space(self) -> number
1492 static int l_get_free_space(lua_State *L)
1494 LuaItemStack *o = checkobject(L, 1);
1495 ItemStack &item = o->m_stack;
1496 lua_pushinteger(L, item.freeSpace(get_server(L)->idef()));
1500 // is_known(self) -> true/false
1501 // Checks if the item is defined.
1502 static int l_is_known(lua_State *L)
1504 LuaItemStack *o = checkobject(L, 1);
1505 ItemStack &item = o->m_stack;
1506 bool is_known = item.isKnown(get_server(L)->idef());
1507 lua_pushboolean(L, is_known);
1511 // get_definition(self) -> table
1512 // Returns the item definition table from minetest.registered_items,
1513 // or a fallback one (name="unknown")
1514 static int l_get_definition(lua_State *L)
1516 LuaItemStack *o = checkobject(L, 1);
1517 ItemStack &item = o->m_stack;
1519 // Get minetest.registered_items[name]
1520 lua_getglobal(L, "minetest");
1521 lua_getfield(L, -1, "registered_items");
1522 luaL_checktype(L, -1, LUA_TTABLE);
1523 lua_getfield(L, -1, item.name.c_str());
1524 if(lua_isnil(L, -1))
1527 lua_getfield(L, -1, "unknown");
1532 // get_tool_capabilities(self) -> table
1533 // Returns the effective tool digging properties.
1534 // Returns those of the hand ("") if this item has none associated.
1535 static int l_get_tool_capabilities(lua_State *L)
1537 LuaItemStack *o = checkobject(L, 1);
1538 ItemStack &item = o->m_stack;
1539 const ToolCapabilities &prop =
1540 item.getToolCapabilities(get_server(L)->idef());
1541 push_tool_capabilities(L, prop);
1545 // add_wear(self, amount) -> true/false
1546 // The range for "amount" is [0,65535]. Wear is only added if the item
1547 // is a tool. Adding wear might destroy the item.
1548 // Returns true if the item is (or was) a tool.
1549 static int l_add_wear(lua_State *L)
1551 LuaItemStack *o = checkobject(L, 1);
1552 ItemStack &item = o->m_stack;
1553 int amount = lua_tointeger(L, 2);
1554 bool result = item.addWear(amount, get_server(L)->idef());
1555 lua_pushboolean(L, result);
1559 // add_item(self, itemstack or itemstring or table or nil) -> itemstack
1560 // Returns leftover item stack
1561 static int l_add_item(lua_State *L)
1563 LuaItemStack *o = checkobject(L, 1);
1564 ItemStack &item = o->m_stack;
1565 ItemStack newitem = read_item(L, 2);
1566 ItemStack leftover = item.addItem(newitem, get_server(L)->idef());
1567 create(L, leftover);
1571 // item_fits(self, itemstack or itemstring or table or nil) -> true/false, itemstack
1572 // First return value is true iff the new item fits fully into the stack
1573 // Second return value is the would-be-left-over item stack
1574 static int l_item_fits(lua_State *L)
1576 LuaItemStack *o = checkobject(L, 1);
1577 ItemStack &item = o->m_stack;
1578 ItemStack newitem = read_item(L, 2);
1580 bool fits = item.itemFits(newitem, &restitem, get_server(L)->idef());
1581 lua_pushboolean(L, fits); // first return value
1582 create(L, restitem); // second return value
1586 // take_item(self, takecount=1) -> itemstack
1587 static int l_take_item(lua_State *L)
1589 LuaItemStack *o = checkobject(L, 1);
1590 ItemStack &item = o->m_stack;
1592 if(!lua_isnone(L, 2))
1593 takecount = luaL_checkinteger(L, 2);
1594 ItemStack taken = item.takeItem(takecount);
1599 // peek_item(self, peekcount=1) -> itemstack
1600 static int l_peek_item(lua_State *L)
1602 LuaItemStack *o = checkobject(L, 1);
1603 ItemStack &item = o->m_stack;
1605 if(!lua_isnone(L, 2))
1606 peekcount = lua_tointeger(L, 2);
1607 ItemStack peekaboo = item.peekItem(peekcount);
1608 create(L, peekaboo);
1613 LuaItemStack(const ItemStack &item):
1622 const ItemStack& getItem() const
1626 ItemStack& getItem()
1631 // LuaItemStack(itemstack or itemstring or table or nil)
1632 // Creates an LuaItemStack and leaves it on top of stack
1633 static int create_object(lua_State *L)
1635 ItemStack item = read_item(L, 1);
1636 LuaItemStack *o = new LuaItemStack(item);
1637 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1638 luaL_getmetatable(L, className);
1639 lua_setmetatable(L, -2);
1642 // Not callable from Lua
1643 static int create(lua_State *L, const ItemStack &item)
1645 LuaItemStack *o = new LuaItemStack(item);
1646 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1647 luaL_getmetatable(L, className);
1648 lua_setmetatable(L, -2);
1652 static LuaItemStack* checkobject(lua_State *L, int narg)
1654 luaL_checktype(L, narg, LUA_TUSERDATA);
1655 void *ud = luaL_checkudata(L, narg, className);
1656 if(!ud) luaL_typerror(L, narg, className);
1657 return *(LuaItemStack**)ud; // unbox pointer
1660 static void Register(lua_State *L)
1663 int methodtable = lua_gettop(L);
1664 luaL_newmetatable(L, className);
1665 int metatable = lua_gettop(L);
1667 lua_pushliteral(L, "__metatable");
1668 lua_pushvalue(L, methodtable);
1669 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
1671 lua_pushliteral(L, "__index");
1672 lua_pushvalue(L, methodtable);
1673 lua_settable(L, metatable);
1675 lua_pushliteral(L, "__gc");
1676 lua_pushcfunction(L, gc_object);
1677 lua_settable(L, metatable);
1679 lua_pop(L, 1); // drop metatable
1681 luaL_openlib(L, 0, methods, 0); // fill methodtable
1682 lua_pop(L, 1); // drop methodtable
1684 // Can be created from Lua (LuaItemStack(itemstack or itemstring or table or nil))
1685 lua_register(L, className, create_object);
1688 const char LuaItemStack::className[] = "ItemStack";
1689 const luaL_reg LuaItemStack::methods[] = {
1690 method(LuaItemStack, is_empty),
1691 method(LuaItemStack, get_name),
1692 method(LuaItemStack, get_count),
1693 method(LuaItemStack, get_wear),
1694 method(LuaItemStack, get_metadata),
1695 method(LuaItemStack, clear),
1696 method(LuaItemStack, replace),
1697 method(LuaItemStack, to_string),
1698 method(LuaItemStack, to_table),
1699 method(LuaItemStack, get_stack_max),
1700 method(LuaItemStack, get_free_space),
1701 method(LuaItemStack, is_known),
1702 method(LuaItemStack, get_definition),
1703 method(LuaItemStack, get_tool_capabilities),
1704 method(LuaItemStack, add_wear),
1705 method(LuaItemStack, add_item),
1706 method(LuaItemStack, item_fits),
1707 method(LuaItemStack, take_item),
1708 method(LuaItemStack, peek_item),
1712 static ItemStack read_item(lua_State *L, int index)
1715 index = lua_gettop(L) + 1 + index;
1717 if(lua_isnil(L, index))
1721 else if(lua_isuserdata(L, index))
1723 // Convert from LuaItemStack
1724 LuaItemStack *o = LuaItemStack::checkobject(L, index);
1725 return o->getItem();
1727 else if(lua_isstring(L, index))
1729 // Convert from itemstring
1730 std::string itemstring = lua_tostring(L, index);
1731 IItemDefManager *idef = get_server(L)->idef();
1735 item.deSerialize(itemstring, idef);
1738 catch(SerializationError &e)
1740 infostream<<"WARNING: unable to create item from itemstring"
1741 <<": "<<itemstring<<std::endl;
1745 else if(lua_istable(L, index))
1747 // Convert from table
1748 IItemDefManager *idef = get_server(L)->idef();
1749 std::string name = getstringfield_default(L, index, "name", "");
1750 int count = getintfield_default(L, index, "count", 1);
1751 int wear = getintfield_default(L, index, "wear", 0);
1752 std::string metadata = getstringfield_default(L, index, "metadata", "");
1753 return ItemStack(name, count, wear, metadata, idef);
1757 throw LuaError(L, "Expecting itemstack, itemstring, table or nil");
1761 static std::vector<ItemStack> read_items(lua_State *L, int index)
1764 index = lua_gettop(L) + 1 + index;
1766 std::vector<ItemStack> items;
1767 luaL_checktype(L, index, LUA_TTABLE);
1769 while(lua_next(L, index) != 0){
1770 // key at index -2 and value at index -1
1771 items.push_back(read_item(L, -1));
1772 // removes value, keeps key for next iteration
1778 // creates a table of ItemStacks
1779 static void push_items(lua_State *L, const std::vector<ItemStack> &items)
1781 // Get the table insert function
1782 lua_getglobal(L, "table");
1783 lua_getfield(L, -1, "insert");
1784 int table_insert = lua_gettop(L);
1785 // Create and fill table
1787 int table = lua_gettop(L);
1788 for(u32 i=0; i<items.size(); i++){
1789 ItemStack item = items[i];
1790 lua_pushvalue(L, table_insert);
1791 lua_pushvalue(L, table);
1792 LuaItemStack::create(L, item);
1793 if(lua_pcall(L, 2, 0, 0))
1794 script_error(L, "error: %s", lua_tostring(L, -1));
1796 lua_remove(L, -2); // Remove table
1797 lua_remove(L, -2); // Remove insert
1807 InventoryLocation m_loc;
1809 static const char className[];
1810 static const luaL_reg methods[];
1812 static InvRef *checkobject(lua_State *L, int narg)
1814 luaL_checktype(L, narg, LUA_TUSERDATA);
1815 void *ud = luaL_checkudata(L, narg, className);
1816 if(!ud) luaL_typerror(L, narg, className);
1817 return *(InvRef**)ud; // unbox pointer
1820 static Inventory* getinv(lua_State *L, InvRef *ref)
1822 return get_server(L)->getInventory(ref->m_loc);
1825 static InventoryList* getlist(lua_State *L, InvRef *ref,
1826 const char *listname)
1828 Inventory *inv = getinv(L, ref);
1831 return inv->getList(listname);
1834 static void reportInventoryChange(lua_State *L, InvRef *ref)
1836 // Inform other things that the inventory has changed
1837 get_server(L)->setInventoryModified(ref->m_loc);
1840 // Exported functions
1842 // garbage collector
1843 static int gc_object(lua_State *L) {
1844 InvRef *o = *(InvRef **)(lua_touserdata(L, 1));
1849 // is_empty(self, listname) -> true/false
1850 static int l_is_empty(lua_State *L)
1852 InvRef *ref = checkobject(L, 1);
1853 const char *listname = luaL_checkstring(L, 2);
1854 InventoryList *list = getlist(L, ref, listname);
1855 if(list && list->getUsedSlots() > 0){
1856 lua_pushboolean(L, false);
1858 lua_pushboolean(L, true);
1863 // get_size(self, listname)
1864 static int l_get_size(lua_State *L)
1866 InvRef *ref = checkobject(L, 1);
1867 const char *listname = luaL_checkstring(L, 2);
1868 InventoryList *list = getlist(L, ref, listname);
1870 lua_pushinteger(L, list->getSize());
1872 lua_pushinteger(L, 0);
1877 // get_width(self, listname)
1878 static int l_get_width(lua_State *L)
1880 InvRef *ref = checkobject(L, 1);
1881 const char *listname = luaL_checkstring(L, 2);
1882 InventoryList *list = getlist(L, ref, listname);
1884 lua_pushinteger(L, list->getWidth());
1886 lua_pushinteger(L, 0);
1891 // set_size(self, listname, size)
1892 static int l_set_size(lua_State *L)
1894 InvRef *ref = checkobject(L, 1);
1895 const char *listname = luaL_checkstring(L, 2);
1896 int newsize = luaL_checknumber(L, 3);
1897 Inventory *inv = getinv(L, ref);
1899 inv->deleteList(listname);
1900 reportInventoryChange(L, ref);
1903 InventoryList *list = inv->getList(listname);
1905 list->setSize(newsize);
1907 list = inv->addList(listname, newsize);
1909 reportInventoryChange(L, ref);
1913 // set_width(self, listname, size)
1914 static int l_set_width(lua_State *L)
1916 InvRef *ref = checkobject(L, 1);
1917 const char *listname = luaL_checkstring(L, 2);
1918 int newwidth = luaL_checknumber(L, 3);
1919 Inventory *inv = getinv(L, ref);
1920 InventoryList *list = inv->getList(listname);
1922 list->setWidth(newwidth);
1926 reportInventoryChange(L, ref);
1930 // get_stack(self, listname, i) -> itemstack
1931 static int l_get_stack(lua_State *L)
1933 InvRef *ref = checkobject(L, 1);
1934 const char *listname = luaL_checkstring(L, 2);
1935 int i = luaL_checknumber(L, 3) - 1;
1936 InventoryList *list = getlist(L, ref, listname);
1938 if(list != NULL && i >= 0 && i < (int) list->getSize())
1939 item = list->getItem(i);
1940 LuaItemStack::create(L, item);
1944 // set_stack(self, listname, i, stack) -> true/false
1945 static int l_set_stack(lua_State *L)
1947 InvRef *ref = checkobject(L, 1);
1948 const char *listname = luaL_checkstring(L, 2);
1949 int i = luaL_checknumber(L, 3) - 1;
1950 ItemStack newitem = read_item(L, 4);
1951 InventoryList *list = getlist(L, ref, listname);
1952 if(list != NULL && i >= 0 && i < (int) list->getSize()){
1953 list->changeItem(i, newitem);
1954 reportInventoryChange(L, ref);
1955 lua_pushboolean(L, true);
1957 lua_pushboolean(L, false);
1962 // get_list(self, listname) -> list or nil
1963 static int l_get_list(lua_State *L)
1965 InvRef *ref = checkobject(L, 1);
1966 const char *listname = luaL_checkstring(L, 2);
1967 Inventory *inv = getinv(L, ref);
1968 inventory_get_list_to_lua(inv, listname, L);
1972 // set_list(self, listname, list)
1973 static int l_set_list(lua_State *L)
1975 InvRef *ref = checkobject(L, 1);
1976 const char *listname = luaL_checkstring(L, 2);
1977 Inventory *inv = getinv(L, ref);
1978 InventoryList *list = inv->getList(listname);
1980 inventory_set_list_from_lua(inv, listname, L, 3,
1983 inventory_set_list_from_lua(inv, listname, L, 3);
1984 reportInventoryChange(L, ref);
1988 // add_item(self, listname, itemstack or itemstring or table or nil) -> itemstack
1989 // Returns the leftover stack
1990 static int l_add_item(lua_State *L)
1992 InvRef *ref = checkobject(L, 1);
1993 const char *listname = luaL_checkstring(L, 2);
1994 ItemStack item = read_item(L, 3);
1995 InventoryList *list = getlist(L, ref, listname);
1997 ItemStack leftover = list->addItem(item);
1998 if(leftover.count != item.count)
1999 reportInventoryChange(L, ref);
2000 LuaItemStack::create(L, leftover);
2002 LuaItemStack::create(L, item);
2007 // room_for_item(self, listname, itemstack or itemstring or table or nil) -> true/false
2008 // Returns true if the item completely fits into the list
2009 static int l_room_for_item(lua_State *L)
2011 InvRef *ref = checkobject(L, 1);
2012 const char *listname = luaL_checkstring(L, 2);
2013 ItemStack item = read_item(L, 3);
2014 InventoryList *list = getlist(L, ref, listname);
2016 lua_pushboolean(L, list->roomForItem(item));
2018 lua_pushboolean(L, false);
2023 // contains_item(self, listname, itemstack or itemstring or table or nil) -> true/false
2024 // Returns true if the list contains the given count of the given item name
2025 static int l_contains_item(lua_State *L)
2027 InvRef *ref = checkobject(L, 1);
2028 const char *listname = luaL_checkstring(L, 2);
2029 ItemStack item = read_item(L, 3);
2030 InventoryList *list = getlist(L, ref, listname);
2032 lua_pushboolean(L, list->containsItem(item));
2034 lua_pushboolean(L, false);
2039 // remove_item(self, listname, itemstack or itemstring or table or nil) -> itemstack
2040 // Returns the items that were actually removed
2041 static int l_remove_item(lua_State *L)
2043 InvRef *ref = checkobject(L, 1);
2044 const char *listname = luaL_checkstring(L, 2);
2045 ItemStack item = read_item(L, 3);
2046 InventoryList *list = getlist(L, ref, listname);
2048 ItemStack removed = list->removeItem(item);
2049 if(!removed.empty())
2050 reportInventoryChange(L, ref);
2051 LuaItemStack::create(L, removed);
2053 LuaItemStack::create(L, ItemStack());
2059 InvRef(const InventoryLocation &loc):
2068 // Creates an InvRef and leaves it on top of stack
2069 // Not callable from Lua; all references are created on the C side.
2070 static void create(lua_State *L, const InventoryLocation &loc)
2072 InvRef *o = new InvRef(loc);
2073 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
2074 luaL_getmetatable(L, className);
2075 lua_setmetatable(L, -2);
2077 static void createPlayer(lua_State *L, Player *player)
2079 InventoryLocation loc;
2080 loc.setPlayer(player->getName());
2083 static void createNodeMeta(lua_State *L, v3s16 p)
2085 InventoryLocation loc;
2090 static void Register(lua_State *L)
2093 int methodtable = lua_gettop(L);
2094 luaL_newmetatable(L, className);
2095 int metatable = lua_gettop(L);
2097 lua_pushliteral(L, "__metatable");
2098 lua_pushvalue(L, methodtable);
2099 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
2101 lua_pushliteral(L, "__index");
2102 lua_pushvalue(L, methodtable);
2103 lua_settable(L, metatable);
2105 lua_pushliteral(L, "__gc");
2106 lua_pushcfunction(L, gc_object);
2107 lua_settable(L, metatable);
2109 lua_pop(L, 1); // drop metatable
2111 luaL_openlib(L, 0, methods, 0); // fill methodtable
2112 lua_pop(L, 1); // drop methodtable
2114 // Cannot be created from Lua
2115 //lua_register(L, className, create_object);
2118 const char InvRef::className[] = "InvRef";
2119 const luaL_reg InvRef::methods[] = {
2120 method(InvRef, is_empty),
2121 method(InvRef, get_size),
2122 method(InvRef, set_size),
2123 method(InvRef, get_width),
2124 method(InvRef, set_width),
2125 method(InvRef, get_stack),
2126 method(InvRef, set_stack),
2127 method(InvRef, get_list),
2128 method(InvRef, set_list),
2129 method(InvRef, add_item),
2130 method(InvRef, room_for_item),
2131 method(InvRef, contains_item),
2132 method(InvRef, remove_item),
2144 ServerEnvironment *m_env;
2146 static const char className[];
2147 static const luaL_reg methods[];
2149 static NodeMetaRef *checkobject(lua_State *L, int narg)
2151 luaL_checktype(L, narg, LUA_TUSERDATA);
2152 void *ud = luaL_checkudata(L, narg, className);
2153 if(!ud) luaL_typerror(L, narg, className);
2154 return *(NodeMetaRef**)ud; // unbox pointer
2157 static NodeMetadata* getmeta(NodeMetaRef *ref, bool auto_create)
2159 NodeMetadata *meta = ref->m_env->getMap().getNodeMetadata(ref->m_p);
2160 if(meta == NULL && auto_create)
2162 meta = new NodeMetadata(ref->m_env->getGameDef());
2163 ref->m_env->getMap().setNodeMetadata(ref->m_p, meta);
2168 static void reportMetadataChange(NodeMetaRef *ref)
2170 // NOTE: This same code is in rollback_interface.cpp
2171 // Inform other things that the metadata has changed
2172 v3s16 blockpos = getNodeBlockPos(ref->m_p);
2174 event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
2176 ref->m_env->getMap().dispatchEvent(&event);
2177 // Set the block to be saved
2178 MapBlock *block = ref->m_env->getMap().getBlockNoCreateNoEx(blockpos);
2180 block->raiseModified(MOD_STATE_WRITE_NEEDED,
2181 "NodeMetaRef::reportMetadataChange");
2184 // Exported functions
2186 // garbage collector
2187 static int gc_object(lua_State *L) {
2188 NodeMetaRef *o = *(NodeMetaRef **)(lua_touserdata(L, 1));
2193 // get_string(self, name)
2194 static int l_get_string(lua_State *L)
2196 NodeMetaRef *ref = checkobject(L, 1);
2197 std::string name = luaL_checkstring(L, 2);
2199 NodeMetadata *meta = getmeta(ref, false);
2201 lua_pushlstring(L, "", 0);
2204 std::string str = meta->getString(name);
2205 lua_pushlstring(L, str.c_str(), str.size());
2209 // set_string(self, name, var)
2210 static int l_set_string(lua_State *L)
2212 NodeMetaRef *ref = checkobject(L, 1);
2213 std::string name = luaL_checkstring(L, 2);
2215 const char *s = lua_tolstring(L, 3, &len);
2216 std::string str(s, len);
2218 NodeMetadata *meta = getmeta(ref, !str.empty());
2219 if(meta == NULL || str == meta->getString(name))
2221 meta->setString(name, str);
2222 reportMetadataChange(ref);
2226 // get_int(self, name)
2227 static int l_get_int(lua_State *L)
2229 NodeMetaRef *ref = checkobject(L, 1);
2230 std::string name = lua_tostring(L, 2);
2232 NodeMetadata *meta = getmeta(ref, false);
2234 lua_pushnumber(L, 0);
2237 std::string str = meta->getString(name);
2238 lua_pushnumber(L, stoi(str));
2242 // set_int(self, name, var)
2243 static int l_set_int(lua_State *L)
2245 NodeMetaRef *ref = checkobject(L, 1);
2246 std::string name = lua_tostring(L, 2);
2247 int a = lua_tointeger(L, 3);
2248 std::string str = itos(a);
2250 NodeMetadata *meta = getmeta(ref, true);
2251 if(meta == NULL || str == meta->getString(name))
2253 meta->setString(name, str);
2254 reportMetadataChange(ref);
2258 // get_float(self, name)
2259 static int l_get_float(lua_State *L)
2261 NodeMetaRef *ref = checkobject(L, 1);
2262 std::string name = lua_tostring(L, 2);
2264 NodeMetadata *meta = getmeta(ref, false);
2266 lua_pushnumber(L, 0);
2269 std::string str = meta->getString(name);
2270 lua_pushnumber(L, stof(str));
2274 // set_float(self, name, var)
2275 static int l_set_float(lua_State *L)
2277 NodeMetaRef *ref = checkobject(L, 1);
2278 std::string name = lua_tostring(L, 2);
2279 float a = lua_tonumber(L, 3);
2280 std::string str = ftos(a);
2282 NodeMetadata *meta = getmeta(ref, true);
2283 if(meta == NULL || str == meta->getString(name))
2285 meta->setString(name, str);
2286 reportMetadataChange(ref);
2290 // get_inventory(self)
2291 static int l_get_inventory(lua_State *L)
2293 NodeMetaRef *ref = checkobject(L, 1);
2294 getmeta(ref, true); // try to ensure the metadata exists
2295 InvRef::createNodeMeta(L, ref->m_p);
2300 static int l_to_table(lua_State *L)
2302 NodeMetaRef *ref = checkobject(L, 1);
2304 NodeMetadata *meta = getmeta(ref, true);
2313 std::map<std::string, std::string> fields = meta->getStrings();
2314 for(std::map<std::string, std::string>::const_iterator
2315 i = fields.begin(); i != fields.end(); i++){
2316 const std::string &name = i->first;
2317 const std::string &value = i->second;
2318 lua_pushlstring(L, name.c_str(), name.size());
2319 lua_pushlstring(L, value.c_str(), value.size());
2320 lua_settable(L, -3);
2323 lua_setfield(L, -2, "fields");
2326 Inventory *inv = meta->getInventory();
2328 std::vector<const InventoryList*> lists = inv->getLists();
2329 for(std::vector<const InventoryList*>::const_iterator
2330 i = lists.begin(); i != lists.end(); i++){
2331 inventory_get_list_to_lua(inv, (*i)->getName().c_str(), L);
2332 lua_setfield(L, -2, (*i)->getName().c_str());
2335 lua_setfield(L, -2, "inventory");
2339 // from_table(self, table)
2340 static int l_from_table(lua_State *L)
2342 NodeMetaRef *ref = checkobject(L, 1);
2345 if(lua_isnil(L, base)){
2347 ref->m_env->getMap().removeNodeMetadata(ref->m_p);
2348 lua_pushboolean(L, true);
2352 // Has metadata; clear old one first
2353 ref->m_env->getMap().removeNodeMetadata(ref->m_p);
2354 // Create new metadata
2355 NodeMetadata *meta = getmeta(ref, true);
2357 lua_getfield(L, base, "fields");
2358 int fieldstable = lua_gettop(L);
2360 while(lua_next(L, fieldstable) != 0){
2361 // key at index -2 and value at index -1
2362 std::string name = lua_tostring(L, -2);
2364 const char *cs = lua_tolstring(L, -1, &cl);
2365 std::string value(cs, cl);
2366 meta->setString(name, value);
2367 lua_pop(L, 1); // removes value, keeps key for next iteration
2370 Inventory *inv = meta->getInventory();
2371 lua_getfield(L, base, "inventory");
2372 int inventorytable = lua_gettop(L);
2374 while(lua_next(L, inventorytable) != 0){
2375 // key at index -2 and value at index -1
2376 std::string name = lua_tostring(L, -2);
2377 inventory_set_list_from_lua(inv, name.c_str(), L, -1);
2378 lua_pop(L, 1); // removes value, keeps key for next iteration
2380 reportMetadataChange(ref);
2381 lua_pushboolean(L, true);
2386 NodeMetaRef(v3s16 p, ServerEnvironment *env):
2396 // Creates an NodeMetaRef and leaves it on top of stack
2397 // Not callable from Lua; all references are created on the C side.
2398 static void create(lua_State *L, v3s16 p, ServerEnvironment *env)
2400 NodeMetaRef *o = new NodeMetaRef(p, env);
2401 //infostream<<"NodeMetaRef::create: o="<<o<<std::endl;
2402 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
2403 luaL_getmetatable(L, className);
2404 lua_setmetatable(L, -2);
2407 static void Register(lua_State *L)
2410 int methodtable = lua_gettop(L);
2411 luaL_newmetatable(L, className);
2412 int metatable = lua_gettop(L);
2414 lua_pushliteral(L, "__metatable");
2415 lua_pushvalue(L, methodtable);
2416 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
2418 lua_pushliteral(L, "__index");
2419 lua_pushvalue(L, methodtable);
2420 lua_settable(L, metatable);
2422 lua_pushliteral(L, "__gc");
2423 lua_pushcfunction(L, gc_object);
2424 lua_settable(L, metatable);
2426 lua_pop(L, 1); // drop metatable
2428 luaL_openlib(L, 0, methods, 0); // fill methodtable
2429 lua_pop(L, 1); // drop methodtable
2431 // Cannot be created from Lua
2432 //lua_register(L, className, create_object);
2435 const char NodeMetaRef::className[] = "NodeMetaRef";
2436 const luaL_reg NodeMetaRef::methods[] = {
2437 method(NodeMetaRef, get_string),
2438 method(NodeMetaRef, set_string),
2439 method(NodeMetaRef, get_int),
2440 method(NodeMetaRef, set_int),
2441 method(NodeMetaRef, get_float),
2442 method(NodeMetaRef, set_float),
2443 method(NodeMetaRef, get_inventory),
2444 method(NodeMetaRef, to_table),
2445 method(NodeMetaRef, from_table),
2456 ServerActiveObject *m_object;
2458 static const char className[];
2459 static const luaL_reg methods[];
2461 static ObjectRef *checkobject(lua_State *L, int narg)
2463 luaL_checktype(L, narg, LUA_TUSERDATA);
2464 void *ud = luaL_checkudata(L, narg, className);
2465 if(!ud) luaL_typerror(L, narg, className);
2466 return *(ObjectRef**)ud; // unbox pointer
2469 static ServerActiveObject* getobject(ObjectRef *ref)
2471 ServerActiveObject *co = ref->m_object;
2475 static LuaEntitySAO* getluaobject(ObjectRef *ref)
2477 ServerActiveObject *obj = getobject(ref);
2480 if(obj->getType() != ACTIVEOBJECT_TYPE_LUAENTITY)
2482 return (LuaEntitySAO*)obj;
2485 static PlayerSAO* getplayersao(ObjectRef *ref)
2487 ServerActiveObject *obj = getobject(ref);
2490 if(obj->getType() != ACTIVEOBJECT_TYPE_PLAYER)
2492 return (PlayerSAO*)obj;
2495 static Player* getplayer(ObjectRef *ref)
2497 PlayerSAO *playersao = getplayersao(ref);
2498 if(playersao == NULL)
2500 return playersao->getPlayer();
2503 // Exported functions
2505 // garbage collector
2506 static int gc_object(lua_State *L) {
2507 ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
2508 //infostream<<"ObjectRef::gc_object: o="<<o<<std::endl;
2514 static int l_remove(lua_State *L)
2516 ObjectRef *ref = checkobject(L, 1);
2517 ServerActiveObject *co = getobject(ref);
2518 if(co == NULL) return 0;
2519 verbosestream<<"ObjectRef::l_remove(): id="<<co->getId()<<std::endl;
2520 co->m_removed = true;
2525 // returns: {x=num, y=num, z=num}
2526 static int l_getpos(lua_State *L)
2528 ObjectRef *ref = checkobject(L, 1);
2529 ServerActiveObject *co = getobject(ref);
2530 if(co == NULL) return 0;
2531 v3f pos = co->getBasePosition() / BS;
2533 lua_pushnumber(L, pos.X);
2534 lua_setfield(L, -2, "x");
2535 lua_pushnumber(L, pos.Y);
2536 lua_setfield(L, -2, "y");
2537 lua_pushnumber(L, pos.Z);
2538 lua_setfield(L, -2, "z");
2542 // setpos(self, pos)
2543 static int l_setpos(lua_State *L)
2545 ObjectRef *ref = checkobject(L, 1);
2546 //LuaEntitySAO *co = getluaobject(ref);
2547 ServerActiveObject *co = getobject(ref);
2548 if(co == NULL) return 0;
2550 v3f pos = checkFloatPos(L, 2);
2556 // moveto(self, pos, continuous=false)
2557 static int l_moveto(lua_State *L)
2559 ObjectRef *ref = checkobject(L, 1);
2560 //LuaEntitySAO *co = getluaobject(ref);
2561 ServerActiveObject *co = getobject(ref);
2562 if(co == NULL) return 0;
2564 v3f pos = checkFloatPos(L, 2);
2566 bool continuous = lua_toboolean(L, 3);
2568 co->moveTo(pos, continuous);
2572 // punch(self, puncher, time_from_last_punch, tool_capabilities, dir)
2573 static int l_punch(lua_State *L)
2575 ObjectRef *ref = checkobject(L, 1);
2576 ObjectRef *puncher_ref = checkobject(L, 2);
2577 ServerActiveObject *co = getobject(ref);
2578 ServerActiveObject *puncher = getobject(puncher_ref);
2579 if(co == NULL) return 0;
2580 if(puncher == NULL) return 0;
2582 if(lua_type(L, 5) != LUA_TTABLE)
2583 dir = co->getBasePosition() - puncher->getBasePosition();
2585 dir = read_v3f(L, 5);
2586 float time_from_last_punch = 1000000;
2587 if(lua_isnumber(L, 3))
2588 time_from_last_punch = lua_tonumber(L, 3);
2589 ToolCapabilities toolcap = read_tool_capabilities(L, 4);
2592 co->punch(dir, &toolcap, puncher, time_from_last_punch);
2596 // right_click(self, clicker); clicker = an another ObjectRef
2597 static int l_right_click(lua_State *L)
2599 ObjectRef *ref = checkobject(L, 1);
2600 ObjectRef *ref2 = checkobject(L, 2);
2601 ServerActiveObject *co = getobject(ref);
2602 ServerActiveObject *co2 = getobject(ref2);
2603 if(co == NULL) return 0;
2604 if(co2 == NULL) return 0;
2606 co->rightClick(co2);
2611 // hp = number of hitpoints (2 * number of hearts)
2613 static int l_set_hp(lua_State *L)
2615 ObjectRef *ref = checkobject(L, 1);
2616 luaL_checknumber(L, 2);
2617 ServerActiveObject *co = getobject(ref);
2618 if(co == NULL) return 0;
2619 int hp = lua_tonumber(L, 2);
2620 /*infostream<<"ObjectRef::l_set_hp(): id="<<co->getId()
2621 <<" hp="<<hp<<std::endl;*/
2629 // returns: number of hitpoints (2 * number of hearts)
2630 // 0 if not applicable to this type of object
2631 static int l_get_hp(lua_State *L)
2633 ObjectRef *ref = checkobject(L, 1);
2634 ServerActiveObject *co = getobject(ref);
2637 lua_pushnumber(L, 1);
2640 int hp = co->getHP();
2641 /*infostream<<"ObjectRef::l_get_hp(): id="<<co->getId()
2642 <<" hp="<<hp<<std::endl;*/
2644 lua_pushnumber(L, hp);
2648 // get_inventory(self)
2649 static int l_get_inventory(lua_State *L)
2651 ObjectRef *ref = checkobject(L, 1);
2652 ServerActiveObject *co = getobject(ref);
2653 if(co == NULL) return 0;
2655 InventoryLocation loc = co->getInventoryLocation();
2656 if(get_server(L)->getInventory(loc) != NULL)
2657 InvRef::create(L, loc);
2659 lua_pushnil(L); // An object may have no inventory (nil)
2663 // get_wield_list(self)
2664 static int l_get_wield_list(lua_State *L)
2666 ObjectRef *ref = checkobject(L, 1);
2667 ServerActiveObject *co = getobject(ref);
2668 if(co == NULL) return 0;
2670 lua_pushstring(L, co->getWieldList().c_str());
2674 // get_wield_index(self)
2675 static int l_get_wield_index(lua_State *L)
2677 ObjectRef *ref = checkobject(L, 1);
2678 ServerActiveObject *co = getobject(ref);
2679 if(co == NULL) return 0;
2681 lua_pushinteger(L, co->getWieldIndex() + 1);
2685 // get_wielded_item(self)
2686 static int l_get_wielded_item(lua_State *L)
2688 ObjectRef *ref = checkobject(L, 1);
2689 ServerActiveObject *co = getobject(ref);
2692 LuaItemStack::create(L, ItemStack());
2696 LuaItemStack::create(L, co->getWieldedItem());
2700 // set_wielded_item(self, itemstack or itemstring or table or nil)
2701 static int l_set_wielded_item(lua_State *L)
2703 ObjectRef *ref = checkobject(L, 1);
2704 ServerActiveObject *co = getobject(ref);
2705 if(co == NULL) return 0;
2707 ItemStack item = read_item(L, 2);
2708 bool success = co->setWieldedItem(item);
2709 lua_pushboolean(L, success);
2713 // set_armor_groups(self, groups)
2714 static int l_set_armor_groups(lua_State *L)
2716 ObjectRef *ref = checkobject(L, 1);
2717 ServerActiveObject *co = getobject(ref);
2718 if(co == NULL) return 0;
2720 ItemGroupList groups;
2721 read_groups(L, 2, groups);
2722 co->setArmorGroups(groups);
2726 // set_properties(self, properties)
2727 static int l_set_properties(lua_State *L)
2729 ObjectRef *ref = checkobject(L, 1);
2730 ServerActiveObject *co = getobject(ref);
2731 if(co == NULL) return 0;
2732 ObjectProperties *prop = co->accessObjectProperties();
2735 read_object_properties(L, 2, prop);
2736 co->notifyObjectPropertiesModified();
2740 /* LuaEntitySAO-only */
2742 // setvelocity(self, {x=num, y=num, z=num})
2743 static int l_setvelocity(lua_State *L)
2745 ObjectRef *ref = checkobject(L, 1);
2746 LuaEntitySAO *co = getluaobject(ref);
2747 if(co == NULL) return 0;
2748 v3f pos = checkFloatPos(L, 2);
2750 co->setVelocity(pos);
2754 // getvelocity(self)
2755 static int l_getvelocity(lua_State *L)
2757 ObjectRef *ref = checkobject(L, 1);
2758 LuaEntitySAO *co = getluaobject(ref);
2759 if(co == NULL) return 0;
2761 v3f v = co->getVelocity();
2766 // setacceleration(self, {x=num, y=num, z=num})
2767 static int l_setacceleration(lua_State *L)
2769 ObjectRef *ref = checkobject(L, 1);
2770 LuaEntitySAO *co = getluaobject(ref);
2771 if(co == NULL) return 0;
2773 v3f pos = checkFloatPos(L, 2);
2775 co->setAcceleration(pos);
2779 // getacceleration(self)
2780 static int l_getacceleration(lua_State *L)
2782 ObjectRef *ref = checkobject(L, 1);
2783 LuaEntitySAO *co = getluaobject(ref);
2784 if(co == NULL) return 0;
2786 v3f v = co->getAcceleration();
2791 // setyaw(self, radians)
2792 static int l_setyaw(lua_State *L)
2794 ObjectRef *ref = checkobject(L, 1);
2795 LuaEntitySAO *co = getluaobject(ref);
2796 if(co == NULL) return 0;
2797 float yaw = luaL_checknumber(L, 2) * core::RADTODEG;
2804 static int l_getyaw(lua_State *L)
2806 ObjectRef *ref = checkobject(L, 1);
2807 LuaEntitySAO *co = getluaobject(ref);
2808 if(co == NULL) return 0;
2810 float yaw = co->getYaw() * core::DEGTORAD;
2811 lua_pushnumber(L, yaw);
2815 // settexturemod(self, mod)
2816 static int l_settexturemod(lua_State *L)
2818 ObjectRef *ref = checkobject(L, 1);
2819 LuaEntitySAO *co = getluaobject(ref);
2820 if(co == NULL) return 0;
2822 std::string mod = luaL_checkstring(L, 2);
2823 co->setTextureMod(mod);
2827 // setsprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2,
2828 // select_horiz_by_yawpitch=false)
2829 static int l_setsprite(lua_State *L)
2831 ObjectRef *ref = checkobject(L, 1);
2832 LuaEntitySAO *co = getluaobject(ref);
2833 if(co == NULL) return 0;
2836 if(!lua_isnil(L, 2))
2837 p = read_v2s16(L, 2);
2839 if(!lua_isnil(L, 3))
2840 num_frames = lua_tonumber(L, 3);
2841 float framelength = 0.2;
2842 if(!lua_isnil(L, 4))
2843 framelength = lua_tonumber(L, 4);
2844 bool select_horiz_by_yawpitch = false;
2845 if(!lua_isnil(L, 5))
2846 select_horiz_by_yawpitch = lua_toboolean(L, 5);
2847 co->setSprite(p, num_frames, framelength, select_horiz_by_yawpitch);
2851 // setanimations(self, mod)
2852 static int l_setanimations(lua_State *L)
2854 ObjectRef *ref = checkobject(L, 1);
2855 LuaEntitySAO *co = getluaobject(ref);
2856 if(co == NULL) return 0;
2859 int frame_start = 0;
2860 if(!lua_isnil(L, 2))
2861 frame_start = lua_tonumber(L, 2);
2863 if(!lua_isnil(L, 3))
2864 frame_end = lua_tonumber(L, 3);
2865 float frame_speed = 15;
2866 if(!lua_isnil(L, 4))
2867 frame_speed = lua_tonumber(L, 4);
2868 float frame_blend = 0;
2869 if(!lua_isnil(L, 5))
2870 frame_blend = lua_tonumber(L, 5);
2871 co->setAnimations(frame_start, frame_end, frame_speed, frame_blend);
2876 // get_entity_name(self)
2877 static int l_get_entity_name(lua_State *L)
2879 ObjectRef *ref = checkobject(L, 1);
2880 LuaEntitySAO *co = getluaobject(ref);
2881 if(co == NULL) return 0;
2883 std::string name = co->getName();
2884 lua_pushstring(L, name.c_str());
2888 // get_luaentity(self)
2889 static int l_get_luaentity(lua_State *L)
2891 ObjectRef *ref = checkobject(L, 1);
2892 LuaEntitySAO *co = getluaobject(ref);
2893 if(co == NULL) return 0;
2895 luaentity_get(L, co->getId());
2902 static int l_is_player(lua_State *L)
2904 ObjectRef *ref = checkobject(L, 1);
2905 Player *player = getplayer(ref);
2906 lua_pushboolean(L, (player != NULL));
2910 // get_player_name(self)
2911 static int l_get_player_name(lua_State *L)
2913 ObjectRef *ref = checkobject(L, 1);
2914 Player *player = getplayer(ref);
2916 lua_pushlstring(L, "", 0);
2920 lua_pushstring(L, player->getName());
2924 // get_look_dir(self)
2925 static int l_get_look_dir(lua_State *L)
2927 ObjectRef *ref = checkobject(L, 1);
2928 Player *player = getplayer(ref);
2929 if(player == NULL) return 0;
2931 float pitch = player->getRadPitch();
2932 float yaw = player->getRadYaw();
2933 v3f v(cos(pitch)*cos(yaw), sin(pitch), cos(pitch)*sin(yaw));
2938 // get_look_pitch(self)
2939 static int l_get_look_pitch(lua_State *L)
2941 ObjectRef *ref = checkobject(L, 1);
2942 Player *player = getplayer(ref);
2943 if(player == NULL) return 0;
2945 lua_pushnumber(L, player->getRadPitch());
2949 // get_look_yaw(self)
2950 static int l_get_look_yaw(lua_State *L)
2952 ObjectRef *ref = checkobject(L, 1);
2953 Player *player = getplayer(ref);
2954 if(player == NULL) return 0;
2956 lua_pushnumber(L, player->getRadYaw());
2960 // set_inventory_formspec(self, formspec)
2961 static int l_set_inventory_formspec(lua_State *L)
2963 ObjectRef *ref = checkobject(L, 1);
2964 Player *player = getplayer(ref);
2965 if(player == NULL) return 0;
2966 std::string formspec = luaL_checkstring(L, 2);
2968 player->inventory_formspec = formspec;
2969 get_server(L)->reportInventoryFormspecModified(player->getName());
2970 lua_pushboolean(L, true);
2974 // get_inventory_formspec(self) -> formspec
2975 static int l_get_inventory_formspec(lua_State *L)
2977 ObjectRef *ref = checkobject(L, 1);
2978 Player *player = getplayer(ref);
2979 if(player == NULL) return 0;
2981 std::string formspec = player->inventory_formspec;
2982 lua_pushlstring(L, formspec.c_str(), formspec.size());
2987 ObjectRef(ServerActiveObject *object):
2990 //infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
2996 infostream<<"ObjectRef destructing for id="
2997 <<m_object->getId()<<std::endl;
2999 infostream<<"ObjectRef destructing for id=unknown"<<std::endl;*/
3002 // Creates an ObjectRef and leaves it on top of stack
3003 // Not callable from Lua; all references are created on the C side.
3004 static void create(lua_State *L, ServerActiveObject *object)
3006 ObjectRef *o = new ObjectRef(object);
3007 //infostream<<"ObjectRef::create: o="<<o<<std::endl;
3008 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
3009 luaL_getmetatable(L, className);
3010 lua_setmetatable(L, -2);
3013 static void set_null(lua_State *L)
3015 ObjectRef *o = checkobject(L, -1);
3019 static void Register(lua_State *L)
3022 int methodtable = lua_gettop(L);
3023 luaL_newmetatable(L, className);
3024 int metatable = lua_gettop(L);
3026 lua_pushliteral(L, "__metatable");
3027 lua_pushvalue(L, methodtable);
3028 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
3030 lua_pushliteral(L, "__index");
3031 lua_pushvalue(L, methodtable);
3032 lua_settable(L, metatable);
3034 lua_pushliteral(L, "__gc");
3035 lua_pushcfunction(L, gc_object);
3036 lua_settable(L, metatable);
3038 lua_pop(L, 1); // drop metatable
3040 luaL_openlib(L, 0, methods, 0); // fill methodtable
3041 lua_pop(L, 1); // drop methodtable
3043 // Cannot be created from Lua
3044 //lua_register(L, className, create_object);
3047 const char ObjectRef::className[] = "ObjectRef";
3048 const luaL_reg ObjectRef::methods[] = {
3049 // ServerActiveObject
3050 method(ObjectRef, remove),
3051 method(ObjectRef, getpos),
3052 method(ObjectRef, setpos),
3053 method(ObjectRef, moveto),
3054 method(ObjectRef, punch),
3055 method(ObjectRef, right_click),
3056 method(ObjectRef, set_hp),
3057 method(ObjectRef, get_hp),
3058 method(ObjectRef, get_inventory),
3059 method(ObjectRef, get_wield_list),
3060 method(ObjectRef, get_wield_index),
3061 method(ObjectRef, get_wielded_item),
3062 method(ObjectRef, set_wielded_item),
3063 method(ObjectRef, set_armor_groups),
3064 method(ObjectRef, set_properties),
3065 // LuaEntitySAO-only
3066 method(ObjectRef, setvelocity),
3067 method(ObjectRef, getvelocity),
3068 method(ObjectRef, setacceleration),
3069 method(ObjectRef, getacceleration),
3070 method(ObjectRef, setyaw),
3071 method(ObjectRef, getyaw),
3072 method(ObjectRef, settexturemod),
3073 method(ObjectRef, setsprite),
3074 method(ObjectRef, setanimations),
3075 method(ObjectRef, get_entity_name),
3076 method(ObjectRef, get_luaentity),
3078 method(ObjectRef, is_player),
3079 method(ObjectRef, get_player_name),
3080 method(ObjectRef, get_look_dir),
3081 method(ObjectRef, get_look_pitch),
3082 method(ObjectRef, get_look_yaw),
3083 method(ObjectRef, set_inventory_formspec),
3084 method(ObjectRef, get_inventory_formspec),
3088 // Creates a new anonymous reference if cobj=NULL or id=0
3089 static void objectref_get_or_create(lua_State *L,
3090 ServerActiveObject *cobj)
3092 if(cobj == NULL || cobj->getId() == 0){
3093 ObjectRef::create(L, cobj);
3095 objectref_get(L, cobj->getId());
3104 class LuaPerlinNoise
3111 static const char className[];
3112 static const luaL_reg methods[];
3114 // Exported functions
3116 // garbage collector
3117 static int gc_object(lua_State *L)
3119 LuaPerlinNoise *o = *(LuaPerlinNoise **)(lua_touserdata(L, 1));
3124 static int l_get2d(lua_State *L)
3126 LuaPerlinNoise *o = checkobject(L, 1);
3127 v2f pos2d = read_v2f(L,2);
3128 lua_Number val = noise2d_perlin(pos2d.X/o->scale, pos2d.Y/o->scale, o->seed, o->octaves, o->persistence);
3129 lua_pushnumber(L, val);
3132 static int l_get3d(lua_State *L)
3134 LuaPerlinNoise *o = checkobject(L, 1);
3135 v3f pos3d = read_v3f(L,2);
3136 lua_Number val = noise3d_perlin(pos3d.X/o->scale, pos3d.Y/o->scale, pos3d.Z/o->scale, o->seed, o->octaves, o->persistence);
3137 lua_pushnumber(L, val);
3142 LuaPerlinNoise(int a_seed, int a_octaves, double a_persistence,
3146 persistence(a_persistence),
3155 // LuaPerlinNoise(seed, octaves, persistence, scale)
3156 // Creates an LuaPerlinNoise and leaves it on top of stack
3157 static int create_object(lua_State *L)
3159 int seed = luaL_checkint(L, 1);
3160 int octaves = luaL_checkint(L, 2);
3161 double persistence = luaL_checknumber(L, 3);
3162 double scale = luaL_checknumber(L, 4);
3163 LuaPerlinNoise *o = new LuaPerlinNoise(seed, octaves, persistence, scale);
3164 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
3165 luaL_getmetatable(L, className);
3166 lua_setmetatable(L, -2);
3170 static LuaPerlinNoise* checkobject(lua_State *L, int narg)
3172 luaL_checktype(L, narg, LUA_TUSERDATA);
3173 void *ud = luaL_checkudata(L, narg, className);
3174 if(!ud) luaL_typerror(L, narg, className);
3175 return *(LuaPerlinNoise**)ud; // unbox pointer
3178 static void Register(lua_State *L)
3181 int methodtable = lua_gettop(L);
3182 luaL_newmetatable(L, className);
3183 int metatable = lua_gettop(L);
3185 lua_pushliteral(L, "__metatable");
3186 lua_pushvalue(L, methodtable);
3187 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
3189 lua_pushliteral(L, "__index");
3190 lua_pushvalue(L, methodtable);
3191 lua_settable(L, metatable);
3193 lua_pushliteral(L, "__gc");
3194 lua_pushcfunction(L, gc_object);
3195 lua_settable(L, metatable);
3197 lua_pop(L, 1); // drop metatable
3199 luaL_openlib(L, 0, methods, 0); // fill methodtable
3200 lua_pop(L, 1); // drop methodtable
3202 // Can be created from Lua (PerlinNoise(seed, octaves, persistence)
3203 lua_register(L, className, create_object);
3206 const char LuaPerlinNoise::className[] = "PerlinNoise";
3207 const luaL_reg LuaPerlinNoise::methods[] = {
3208 method(LuaPerlinNoise, get2d),
3209 method(LuaPerlinNoise, get3d),
3221 ServerEnvironment *m_env;
3223 static const char className[];
3224 static const luaL_reg methods[];
3226 static int gc_object(lua_State *L) {
3227 NodeTimerRef *o = *(NodeTimerRef **)(lua_touserdata(L, 1));
3232 static NodeTimerRef *checkobject(lua_State *L, int narg)
3234 luaL_checktype(L, narg, LUA_TUSERDATA);
3235 void *ud = luaL_checkudata(L, narg, className);
3236 if(!ud) luaL_typerror(L, narg, className);
3237 return *(NodeTimerRef**)ud; // unbox pointer
3240 static int l_set(lua_State *L)
3242 NodeTimerRef *o = checkobject(L, 1);
3243 ServerEnvironment *env = o->m_env;
3244 if(env == NULL) return 0;
3245 f32 t = luaL_checknumber(L,2);
3246 f32 e = luaL_checknumber(L,3);
3247 env->getMap().setNodeTimer(o->m_p,NodeTimer(t,e));
3251 static int l_start(lua_State *L)
3253 NodeTimerRef *o = checkobject(L, 1);
3254 ServerEnvironment *env = o->m_env;
3255 if(env == NULL) return 0;
3256 f32 t = luaL_checknumber(L,2);
3257 env->getMap().setNodeTimer(o->m_p,NodeTimer(t,0));
3261 static int l_stop(lua_State *L)
3263 NodeTimerRef *o = checkobject(L, 1);
3264 ServerEnvironment *env = o->m_env;
3265 if(env == NULL) return 0;
3266 env->getMap().removeNodeTimer(o->m_p);
3270 static int l_is_started(lua_State *L)
3272 NodeTimerRef *o = checkobject(L, 1);
3273 ServerEnvironment *env = o->m_env;
3274 if(env == NULL) return 0;
3276 NodeTimer t = env->getMap().getNodeTimer(o->m_p);
3277 lua_pushboolean(L,(t.timeout != 0));
3281 static int l_get_timeout(lua_State *L)
3283 NodeTimerRef *o = checkobject(L, 1);
3284 ServerEnvironment *env = o->m_env;
3285 if(env == NULL) return 0;
3287 NodeTimer t = env->getMap().getNodeTimer(o->m_p);
3288 lua_pushnumber(L,t.timeout);
3292 static int l_get_elapsed(lua_State *L)
3294 NodeTimerRef *o = checkobject(L, 1);
3295 ServerEnvironment *env = o->m_env;
3296 if(env == NULL) return 0;
3298 NodeTimer t = env->getMap().getNodeTimer(o->m_p);
3299 lua_pushnumber(L,t.elapsed);
3304 NodeTimerRef(v3s16 p, ServerEnvironment *env):
3314 // Creates an NodeTimerRef and leaves it on top of stack
3315 // Not callable from Lua; all references are created on the C side.
3316 static void create(lua_State *L, v3s16 p, ServerEnvironment *env)
3318 NodeTimerRef *o = new NodeTimerRef(p, env);
3319 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
3320 luaL_getmetatable(L, className);
3321 lua_setmetatable(L, -2);
3324 static void set_null(lua_State *L)
3326 NodeTimerRef *o = checkobject(L, -1);
3330 static void Register(lua_State *L)
3333 int methodtable = lua_gettop(L);
3334 luaL_newmetatable(L, className);
3335 int metatable = lua_gettop(L);
3337 lua_pushliteral(L, "__metatable");
3338 lua_pushvalue(L, methodtable);
3339 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
3341 lua_pushliteral(L, "__index");
3342 lua_pushvalue(L, methodtable);
3343 lua_settable(L, metatable);
3345 lua_pushliteral(L, "__gc");
3346 lua_pushcfunction(L, gc_object);
3347 lua_settable(L, metatable);
3349 lua_pop(L, 1); // drop metatable
3351 luaL_openlib(L, 0, methods, 0); // fill methodtable
3352 lua_pop(L, 1); // drop methodtable
3354 // Cannot be created from Lua
3355 //lua_register(L, className, create_object);
3358 const char NodeTimerRef::className[] = "NodeTimerRef";
3359 const luaL_reg NodeTimerRef::methods[] = {
3360 method(NodeTimerRef, start),
3361 method(NodeTimerRef, set),
3362 method(NodeTimerRef, stop),
3363 method(NodeTimerRef, is_started),
3364 method(NodeTimerRef, get_timeout),
3365 method(NodeTimerRef, get_elapsed),
3376 ServerEnvironment *m_env;
3378 static const char className[];
3379 static const luaL_reg methods[];
3381 static int gc_object(lua_State *L) {
3382 EnvRef *o = *(EnvRef **)(lua_touserdata(L, 1));
3387 static EnvRef *checkobject(lua_State *L, int narg)
3389 luaL_checktype(L, narg, LUA_TUSERDATA);
3390 void *ud = luaL_checkudata(L, narg, className);
3391 if(!ud) luaL_typerror(L, narg, className);
3392 return *(EnvRef**)ud; // unbox pointer
3395 // Exported functions
3397 // EnvRef:set_node(pos, node)
3398 // pos = {x=num, y=num, z=num}
3399 static int l_set_node(lua_State *L)
3401 EnvRef *o = checkobject(L, 1);
3402 ServerEnvironment *env = o->m_env;
3403 if(env == NULL) return 0;
3404 INodeDefManager *ndef = env->getGameDef()->ndef();
3406 v3s16 pos = read_v3s16(L, 2);
3407 MapNode n = readnode(L, 3, ndef);
3409 MapNode n_old = env->getMap().getNodeNoEx(pos);
3411 if(ndef->get(n_old).has_on_destruct)
3412 scriptapi_node_on_destruct(L, pos, n_old);
3414 bool succeeded = env->getMap().addNodeWithEvent(pos, n);
3416 // Call post-destructor
3417 if(ndef->get(n_old).has_after_destruct)
3418 scriptapi_node_after_destruct(L, pos, n_old);
3420 if(ndef->get(n).has_on_construct)
3421 scriptapi_node_on_construct(L, pos, n);
3423 lua_pushboolean(L, succeeded);
3427 static int l_add_node(lua_State *L)
3429 return l_set_node(L);
3432 // EnvRef:remove_node(pos)
3433 // pos = {x=num, y=num, z=num}
3434 static int l_remove_node(lua_State *L)
3436 EnvRef *o = checkobject(L, 1);
3437 ServerEnvironment *env = o->m_env;
3438 if(env == NULL) return 0;
3439 INodeDefManager *ndef = env->getGameDef()->ndef();
3441 v3s16 pos = read_v3s16(L, 2);
3443 MapNode n_old = env->getMap().getNodeNoEx(pos);
3445 if(ndef->get(n_old).has_on_destruct)
3446 scriptapi_node_on_destruct(L, pos, n_old);
3448 // This is slightly optimized compared to addNodeWithEvent(air)
3449 bool succeeded = env->getMap().removeNodeWithEvent(pos);
3451 // Call post-destructor
3452 if(ndef->get(n_old).has_after_destruct)
3453 scriptapi_node_after_destruct(L, pos, n_old);
3455 lua_pushboolean(L, succeeded);
3456 // Air doesn't require constructor
3460 // EnvRef:get_node(pos)
3461 // pos = {x=num, y=num, z=num}
3462 static int l_get_node(lua_State *L)
3464 EnvRef *o = checkobject(L, 1);
3465 ServerEnvironment *env = o->m_env;
3466 if(env == NULL) return 0;
3468 v3s16 pos = read_v3s16(L, 2);
3470 MapNode n = env->getMap().getNodeNoEx(pos);
3472 pushnode(L, n, env->getGameDef()->ndef());
3476 // EnvRef:get_node_or_nil(pos)
3477 // pos = {x=num, y=num, z=num}
3478 static int l_get_node_or_nil(lua_State *L)
3480 EnvRef *o = checkobject(L, 1);
3481 ServerEnvironment *env = o->m_env;
3482 if(env == NULL) return 0;
3484 v3s16 pos = read_v3s16(L, 2);
3487 MapNode n = env->getMap().getNode(pos);
3489 pushnode(L, n, env->getGameDef()->ndef());
3491 } catch(InvalidPositionException &e)
3498 // EnvRef:get_node_light(pos, timeofday)
3499 // pos = {x=num, y=num, z=num}
3500 // timeofday: nil = current time, 0 = night, 0.5 = day
3501 static int l_get_node_light(lua_State *L)
3503 EnvRef *o = checkobject(L, 1);
3504 ServerEnvironment *env = o->m_env;
3505 if(env == NULL) return 0;
3507 v3s16 pos = read_v3s16(L, 2);
3508 u32 time_of_day = env->getTimeOfDay();
3509 if(lua_isnumber(L, 3))
3510 time_of_day = 24000.0 * lua_tonumber(L, 3);
3511 time_of_day %= 24000;
3512 u32 dnr = time_to_daynight_ratio(time_of_day);
3513 MapNode n = env->getMap().getNodeNoEx(pos);
3515 MapNode n = env->getMap().getNode(pos);
3516 INodeDefManager *ndef = env->getGameDef()->ndef();
3517 lua_pushinteger(L, n.getLightBlend(dnr, ndef));
3519 } catch(InvalidPositionException &e)
3526 // EnvRef:place_node(pos, node)
3527 // pos = {x=num, y=num, z=num}
3528 static int l_place_node(lua_State *L)
3530 EnvRef *o = checkobject(L, 1);
3531 ServerEnvironment *env = o->m_env;
3532 if(env == NULL) return 0;
3533 v3s16 pos = read_v3s16(L, 2);
3534 MapNode n = readnode(L, 3, env->getGameDef()->ndef());
3536 // Don't attempt to load non-loaded area as of now
3537 MapNode n_old = env->getMap().getNodeNoEx(pos);
3538 if(n_old.getContent() == CONTENT_IGNORE){
3539 lua_pushboolean(L, false);
3542 // Create item to place
3543 INodeDefManager *ndef = get_server(L)->ndef();
3544 IItemDefManager *idef = get_server(L)->idef();
3545 ItemStack item(ndef->get(n).name, 1, 0, "", idef);
3546 // Make pointed position
3547 PointedThing pointed;
3548 pointed.type = POINTEDTHING_NODE;
3549 pointed.node_abovesurface = pos;
3550 pointed.node_undersurface = pos + v3s16(0,-1,0);
3551 // Place it with a NULL placer (appears in Lua as a non-functional
3553 bool success = scriptapi_item_on_place(L, item, NULL, pointed);
3554 lua_pushboolean(L, success);
3558 // EnvRef:dig_node(pos)
3559 // pos = {x=num, y=num, z=num}
3560 static int l_dig_node(lua_State *L)
3562 EnvRef *o = checkobject(L, 1);
3563 ServerEnvironment *env = o->m_env;
3564 if(env == NULL) return 0;
3565 v3s16 pos = read_v3s16(L, 2);
3567 // Don't attempt to load non-loaded area as of now
3568 MapNode n = env->getMap().getNodeNoEx(pos);
3569 if(n.getContent() == CONTENT_IGNORE){
3570 lua_pushboolean(L, false);
3573 // Dig it out with a NULL digger (appears in Lua as a
3574 // non-functional ObjectRef)
3575 bool success = scriptapi_node_on_dig(L, pos, n, NULL);
3576 lua_pushboolean(L, success);
3580 // EnvRef:punch_node(pos)
3581 // pos = {x=num, y=num, z=num}
3582 static int l_punch_node(lua_State *L)
3584 EnvRef *o = checkobject(L, 1);
3585 ServerEnvironment *env = o->m_env;
3586 if(env == NULL) return 0;
3587 v3s16 pos = read_v3s16(L, 2);
3589 // Don't attempt to load non-loaded area as of now
3590 MapNode n = env->getMap().getNodeNoEx(pos);
3591 if(n.getContent() == CONTENT_IGNORE){
3592 lua_pushboolean(L, false);
3595 // Punch it with a NULL puncher (appears in Lua as a non-functional
3597 bool success = scriptapi_node_on_punch(L, pos, n, NULL);
3598 lua_pushboolean(L, success);
3602 // EnvRef:get_meta(pos)
3603 static int l_get_meta(lua_State *L)
3605 //infostream<<"EnvRef::l_get_meta()"<<std::endl;
3606 EnvRef *o = checkobject(L, 1);
3607 ServerEnvironment *env = o->m_env;
3608 if(env == NULL) return 0;
3610 v3s16 p = read_v3s16(L, 2);
3611 NodeMetaRef::create(L, p, env);
3615 // EnvRef:get_node_timer(pos)
3616 static int l_get_node_timer(lua_State *L)
3618 EnvRef *o = checkobject(L, 1);
3619 ServerEnvironment *env = o->m_env;
3620 if(env == NULL) return 0;
3622 v3s16 p = read_v3s16(L, 2);
3623 NodeTimerRef::create(L, p, env);
3627 // EnvRef:add_entity(pos, entityname) -> ObjectRef or nil
3628 // pos = {x=num, y=num, z=num}
3629 static int l_add_entity(lua_State *L)
3631 //infostream<<"EnvRef::l_add_entity()"<<std::endl;
3632 EnvRef *o = checkobject(L, 1);
3633 ServerEnvironment *env = o->m_env;
3634 if(env == NULL) return 0;
3636 v3f pos = checkFloatPos(L, 2);
3638 const char *name = luaL_checkstring(L, 3);
3640 ServerActiveObject *obj = new LuaEntitySAO(env, pos, name, "");
3641 int objectid = env->addActiveObject(obj);
3642 // If failed to add, return nothing (reads as nil)
3646 objectref_get_or_create(L, obj);
3650 // EnvRef:add_item(pos, itemstack or itemstring or table) -> ObjectRef or nil
3651 // pos = {x=num, y=num, z=num}
3652 static int l_add_item(lua_State *L)
3654 //infostream<<"EnvRef::l_add_item()"<<std::endl;
3655 EnvRef *o = checkobject(L, 1);
3656 ServerEnvironment *env = o->m_env;
3657 if(env == NULL) return 0;
3659 v3f pos = checkFloatPos(L, 2);
3661 ItemStack item = read_item(L, 3);
3662 if(item.empty() || !item.isKnown(get_server(L)->idef()))
3664 // Use minetest.spawn_item to spawn a __builtin:item
3665 lua_getglobal(L, "minetest");
3666 lua_getfield(L, -1, "spawn_item");
3667 if(lua_isnil(L, -1))
3669 lua_pushvalue(L, 2);
3670 lua_pushstring(L, item.getItemString().c_str());
3671 if(lua_pcall(L, 2, 1, 0))
3672 script_error(L, "error: %s", lua_tostring(L, -1));
3674 /*lua_pushvalue(L, 1);
3675 lua_pushstring(L, "__builtin:item");
3676 lua_pushstring(L, item.getItemString().c_str());
3677 return l_add_entity(L);*/
3679 ServerActiveObject *obj = createItemSAO(env, pos, item.getItemString());
3680 int objectid = env->addActiveObject(obj);
3681 // If failed to add, return nothing (reads as nil)
3685 objectref_get_or_create(L, obj);
3689 // EnvRef:add_rat(pos)
3690 // pos = {x=num, y=num, z=num}
3691 static int l_add_rat(lua_State *L)
3693 infostream<<"EnvRef::l_add_rat(): C++ mobs have been removed."
3694 <<" Doing nothing."<<std::endl;
3698 // EnvRef:add_firefly(pos)
3699 // pos = {x=num, y=num, z=num}
3700 static int l_add_firefly(lua_State *L)
3702 infostream<<"EnvRef::l_add_firefly(): C++ mobs have been removed."
3703 <<" Doing nothing."<<std::endl;
3707 // EnvRef:get_player_by_name(name)
3708 static int l_get_player_by_name(lua_State *L)
3710 EnvRef *o = checkobject(L, 1);
3711 ServerEnvironment *env = o->m_env;
3712 if(env == NULL) return 0;
3714 const char *name = luaL_checkstring(L, 2);
3715 Player *player = env->getPlayer(name);
3720 PlayerSAO *sao = player->getPlayerSAO();
3725 // Put player on stack
3726 objectref_get_or_create(L, sao);
3730 // EnvRef:get_objects_inside_radius(pos, radius)
3731 static int l_get_objects_inside_radius(lua_State *L)
3733 // Get the table insert function
3734 lua_getglobal(L, "table");
3735 lua_getfield(L, -1, "insert");
3736 int table_insert = lua_gettop(L);
3738 EnvRef *o = checkobject(L, 1);
3739 ServerEnvironment *env = o->m_env;
3740 if(env == NULL) return 0;
3742 v3f pos = checkFloatPos(L, 2);
3743 float radius = luaL_checknumber(L, 3) * BS;
3744 std::set<u16> ids = env->getObjectsInsideRadius(pos, radius);
3746 int table = lua_gettop(L);
3747 for(std::set<u16>::const_iterator
3748 i = ids.begin(); i != ids.end(); i++){
3749 ServerActiveObject *obj = env->getActiveObject(*i);
3750 // Insert object reference into table
3751 lua_pushvalue(L, table_insert);
3752 lua_pushvalue(L, table);
3753 objectref_get_or_create(L, obj);
3754 if(lua_pcall(L, 2, 0, 0))
3755 script_error(L, "error: %s", lua_tostring(L, -1));
3760 // EnvRef:set_timeofday(val)
3762 static int l_set_timeofday(lua_State *L)
3764 EnvRef *o = checkobject(L, 1);
3765 ServerEnvironment *env = o->m_env;
3766 if(env == NULL) return 0;
3768 float timeofday_f = luaL_checknumber(L, 2);
3769 assert(timeofday_f >= 0.0 && timeofday_f <= 1.0);
3770 int timeofday_mh = (int)(timeofday_f * 24000.0);
3771 // This should be set directly in the environment but currently
3772 // such changes aren't immediately sent to the clients, so call
3773 // the server instead.
3774 //env->setTimeOfDay(timeofday_mh);
3775 get_server(L)->setTimeOfDay(timeofday_mh);
3779 // EnvRef:get_timeofday() -> 0...1
3780 static int l_get_timeofday(lua_State *L)
3782 EnvRef *o = checkobject(L, 1);
3783 ServerEnvironment *env = o->m_env;
3784 if(env == NULL) return 0;
3786 int timeofday_mh = env->getTimeOfDay();
3787 float timeofday_f = (float)timeofday_mh / 24000.0;
3788 lua_pushnumber(L, timeofday_f);
3793 // EnvRef:find_node_near(pos, radius, nodenames) -> pos or nil
3794 // nodenames: eg. {"ignore", "group:tree"} or "default:dirt"
3795 static int l_find_node_near(lua_State *L)
3797 EnvRef *o = checkobject(L, 1);
3798 ServerEnvironment *env = o->m_env;
3799 if(env == NULL) return 0;
3800 INodeDefManager *ndef = get_server(L)->ndef();
3801 v3s16 pos = read_v3s16(L, 2);
3802 int radius = luaL_checkinteger(L, 3);
3803 std::set<content_t> filter;
3804 if(lua_istable(L, 4)){
3807 while(lua_next(L, table) != 0){
3808 // key at index -2 and value at index -1
3809 luaL_checktype(L, -1, LUA_TSTRING);
3810 ndef->getIds(lua_tostring(L, -1), filter);
3811 // removes value, keeps key for next iteration
3814 } else if(lua_isstring(L, 4)){
3815 ndef->getIds(lua_tostring(L, 4), filter);
3818 for(int d=1; d<=radius; d++){
3819 core::list<v3s16> list;
3820 getFacePositions(list, d);
3821 for(core::list<v3s16>::Iterator i = list.begin();
3822 i != list.end(); i++){
3823 v3s16 p = pos + (*i);
3824 content_t c = env->getMap().getNodeNoEx(p).getContent();
3825 if(filter.count(c) != 0){
3834 // EnvRef:find_nodes_in_area(minp, maxp, nodenames) -> list of positions
3835 // nodenames: eg. {"ignore", "group:tree"} or "default:dirt"
3836 static int l_find_nodes_in_area(lua_State *L)
3838 EnvRef *o = checkobject(L, 1);
3839 ServerEnvironment *env = o->m_env;
3840 if(env == NULL) return 0;
3841 INodeDefManager *ndef = get_server(L)->ndef();
3842 v3s16 minp = read_v3s16(L, 2);
3843 v3s16 maxp = read_v3s16(L, 3);
3844 std::set<content_t> filter;
3845 if(lua_istable(L, 4)){
3848 while(lua_next(L, table) != 0){
3849 // key at index -2 and value at index -1
3850 luaL_checktype(L, -1, LUA_TSTRING);
3851 ndef->getIds(lua_tostring(L, -1), filter);
3852 // removes value, keeps key for next iteration
3855 } else if(lua_isstring(L, 4)){
3856 ndef->getIds(lua_tostring(L, 4), filter);
3859 // Get the table insert function
3860 lua_getglobal(L, "table");
3861 lua_getfield(L, -1, "insert");
3862 int table_insert = lua_gettop(L);
3865 int table = lua_gettop(L);
3866 for(s16 x=minp.X; x<=maxp.X; x++)
3867 for(s16 y=minp.Y; y<=maxp.Y; y++)
3868 for(s16 z=minp.Z; z<=maxp.Z; z++)
3871 content_t c = env->getMap().getNodeNoEx(p).getContent();
3872 if(filter.count(c) != 0){
3873 lua_pushvalue(L, table_insert);
3874 lua_pushvalue(L, table);
3876 if(lua_pcall(L, 2, 0, 0))
3877 script_error(L, "error: %s", lua_tostring(L, -1));
3883 // EnvRef:get_perlin(seeddiff, octaves, persistence, scale)
3884 // returns world-specific PerlinNoise
3885 static int l_get_perlin(lua_State *L)
3887 EnvRef *o = checkobject(L, 1);
3888 ServerEnvironment *env = o->m_env;
3889 if(env == NULL) return 0;
3891 int seeddiff = luaL_checkint(L, 2);
3892 int octaves = luaL_checkint(L, 3);
3893 double persistence = luaL_checknumber(L, 4);
3894 double scale = luaL_checknumber(L, 5);
3896 LuaPerlinNoise *n = new LuaPerlinNoise(seeddiff + int(env->getServerMap().getSeed()), octaves, persistence, scale);
3897 *(void **)(lua_newuserdata(L, sizeof(void *))) = n;
3898 luaL_getmetatable(L, "PerlinNoise");
3899 lua_setmetatable(L, -2);
3903 // EnvRef:clear_objects()
3904 // clear all objects in the environment
3905 static int l_clear_objects(lua_State *L)
3907 EnvRef *o = checkobject(L, 1);
3908 o->m_env->clearAllObjects();
3913 EnvRef(ServerEnvironment *env):
3916 //infostream<<"EnvRef created"<<std::endl;
3921 //infostream<<"EnvRef destructing"<<std::endl;
3924 // Creates an EnvRef and leaves it on top of stack
3925 // Not callable from Lua; all references are created on the C side.
3926 static void create(lua_State *L, ServerEnvironment *env)
3928 EnvRef *o = new EnvRef(env);
3929 //infostream<<"EnvRef::create: o="<<o<<std::endl;
3930 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
3931 luaL_getmetatable(L, className);
3932 lua_setmetatable(L, -2);
3935 static void set_null(lua_State *L)
3937 EnvRef *o = checkobject(L, -1);
3941 static void Register(lua_State *L)
3944 int methodtable = lua_gettop(L);
3945 luaL_newmetatable(L, className);
3946 int metatable = lua_gettop(L);
3948 lua_pushliteral(L, "__metatable");
3949 lua_pushvalue(L, methodtable);
3950 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
3952 lua_pushliteral(L, "__index");
3953 lua_pushvalue(L, methodtable);
3954 lua_settable(L, metatable);
3956 lua_pushliteral(L, "__gc");
3957 lua_pushcfunction(L, gc_object);
3958 lua_settable(L, metatable);
3960 lua_pop(L, 1); // drop metatable
3962 luaL_openlib(L, 0, methods, 0); // fill methodtable
3963 lua_pop(L, 1); // drop methodtable
3965 // Cannot be created from Lua
3966 //lua_register(L, className, create_object);
3969 const char EnvRef::className[] = "EnvRef";
3970 const luaL_reg EnvRef::methods[] = {
3971 method(EnvRef, set_node),
3972 method(EnvRef, add_node),
3973 method(EnvRef, remove_node),
3974 method(EnvRef, get_node),
3975 method(EnvRef, get_node_or_nil),
3976 method(EnvRef, get_node_light),
3977 method(EnvRef, place_node),
3978 method(EnvRef, dig_node),
3979 method(EnvRef, punch_node),
3980 method(EnvRef, add_entity),
3981 method(EnvRef, add_item),
3982 method(EnvRef, add_rat),
3983 method(EnvRef, add_firefly),
3984 method(EnvRef, get_meta),
3985 method(EnvRef, get_node_timer),
3986 method(EnvRef, get_player_by_name),
3987 method(EnvRef, get_objects_inside_radius),
3988 method(EnvRef, set_timeofday),
3989 method(EnvRef, get_timeofday),
3990 method(EnvRef, find_node_near),
3991 method(EnvRef, find_nodes_in_area),
3992 method(EnvRef, get_perlin),
3993 method(EnvRef, clear_objects),
4002 class LuaPseudoRandom
4005 PseudoRandom m_pseudo;
4007 static const char className[];
4008 static const luaL_reg methods[];
4010 // Exported functions
4012 // garbage collector
4013 static int gc_object(lua_State *L)
4015 LuaPseudoRandom *o = *(LuaPseudoRandom **)(lua_touserdata(L, 1));
4020 // next(self, min=0, max=32767) -> get next value
4021 static int l_next(lua_State *L)
4023 LuaPseudoRandom *o = checkobject(L, 1);
4026 lua_settop(L, 3); // Fill 2 and 3 with nil if they don't exist
4027 if(!lua_isnil(L, 2))
4028 min = luaL_checkinteger(L, 2);
4029 if(!lua_isnil(L, 3))
4030 max = luaL_checkinteger(L, 3);
4032 errorstream<<"PseudoRandom.next(): max="<<max<<" min="<<min<<std::endl;
4033 throw LuaError(L, "PseudoRandom.next(): max < min");
4035 if(max - min != 32767 && max - min > 32767/5)
4036 throw LuaError(L, "PseudoRandom.next() max-min is not 32767 and is > 32768/5. This is disallowed due to the bad random distribution the implementation would otherwise make.");
4037 PseudoRandom &pseudo = o->m_pseudo;
4038 int val = pseudo.next();
4039 val = (val % (max-min+1)) + min;
4040 lua_pushinteger(L, val);
4045 LuaPseudoRandom(int seed):
4054 const PseudoRandom& getItem() const
4058 PseudoRandom& getItem()
4063 // LuaPseudoRandom(seed)
4064 // Creates an LuaPseudoRandom and leaves it on top of stack
4065 static int create_object(lua_State *L)
4067 int seed = luaL_checknumber(L, 1);
4068 LuaPseudoRandom *o = new LuaPseudoRandom(seed);
4069 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
4070 luaL_getmetatable(L, className);
4071 lua_setmetatable(L, -2);
4075 static LuaPseudoRandom* checkobject(lua_State *L, int narg)
4077 luaL_checktype(L, narg, LUA_TUSERDATA);
4078 void *ud = luaL_checkudata(L, narg, className);
4079 if(!ud) luaL_typerror(L, narg, className);
4080 return *(LuaPseudoRandom**)ud; // unbox pointer
4083 static void Register(lua_State *L)
4086 int methodtable = lua_gettop(L);
4087 luaL_newmetatable(L, className);
4088 int metatable = lua_gettop(L);
4090 lua_pushliteral(L, "__metatable");
4091 lua_pushvalue(L, methodtable);
4092 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
4094 lua_pushliteral(L, "__index");
4095 lua_pushvalue(L, methodtable);
4096 lua_settable(L, metatable);
4098 lua_pushliteral(L, "__gc");
4099 lua_pushcfunction(L, gc_object);
4100 lua_settable(L, metatable);
4102 lua_pop(L, 1); // drop metatable
4104 luaL_openlib(L, 0, methods, 0); // fill methodtable
4105 lua_pop(L, 1); // drop methodtable
4107 // Can be created from Lua (LuaPseudoRandom(seed))
4108 lua_register(L, className, create_object);
4111 const char LuaPseudoRandom::className[] = "PseudoRandom";
4112 const luaL_reg LuaPseudoRandom::methods[] = {
4113 method(LuaPseudoRandom, next),
4123 class LuaABM : public ActiveBlockModifier
4129 std::set<std::string> m_trigger_contents;
4130 std::set<std::string> m_required_neighbors;
4131 float m_trigger_interval;
4132 u32 m_trigger_chance;
4134 LuaABM(lua_State *L, int id,
4135 const std::set<std::string> &trigger_contents,
4136 const std::set<std::string> &required_neighbors,
4137 float trigger_interval, u32 trigger_chance):
4140 m_trigger_contents(trigger_contents),
4141 m_required_neighbors(required_neighbors),
4142 m_trigger_interval(trigger_interval),
4143 m_trigger_chance(trigger_chance)
4146 virtual std::set<std::string> getTriggerContents()
4148 return m_trigger_contents;
4150 virtual std::set<std::string> getRequiredNeighbors()
4152 return m_required_neighbors;
4154 virtual float getTriggerInterval()
4156 return m_trigger_interval;
4158 virtual u32 getTriggerChance()
4160 return m_trigger_chance;
4162 virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n,
4163 u32 active_object_count, u32 active_object_count_wider)
4165 lua_State *L = m_lua;
4168 assert(lua_checkstack(L, 20));
4169 StackUnroller stack_unroller(L);
4171 // Get minetest.registered_abms
4172 lua_getglobal(L, "minetest");
4173 lua_getfield(L, -1, "registered_abms");
4174 luaL_checktype(L, -1, LUA_TTABLE);
4175 int registered_abms = lua_gettop(L);
4177 // Get minetest.registered_abms[m_id]
4178 lua_pushnumber(L, m_id);
4179 lua_gettable(L, registered_abms);
4180 if(lua_isnil(L, -1))
4184 luaL_checktype(L, -1, LUA_TTABLE);
4185 lua_getfield(L, -1, "action");
4186 luaL_checktype(L, -1, LUA_TFUNCTION);
4188 pushnode(L, n, env->getGameDef()->ndef());
4189 lua_pushnumber(L, active_object_count);
4190 lua_pushnumber(L, active_object_count_wider);
4191 if(lua_pcall(L, 4, 0, 0))
4192 script_error(L, "error: %s", lua_tostring(L, -1));
4200 static void read_server_sound_params(lua_State *L, int index,
4201 ServerSoundParams ¶ms)
4204 index = lua_gettop(L) + 1 + index;
4206 params = ServerSoundParams();
4207 if(lua_istable(L, index)){
4208 getfloatfield(L, index, "gain", params.gain);
4209 getstringfield(L, index, "to_player", params.to_player);
4210 lua_getfield(L, index, "pos");
4211 if(!lua_isnil(L, -1)){
4212 v3f p = read_v3f(L, -1)*BS;
4214 params.type = ServerSoundParams::SSP_POSITIONAL;
4217 lua_getfield(L, index, "object");
4218 if(!lua_isnil(L, -1)){
4219 ObjectRef *ref = ObjectRef::checkobject(L, -1);
4220 ServerActiveObject *sao = ObjectRef::getobject(ref);
4222 params.object = sao->getId();
4223 params.type = ServerSoundParams::SSP_OBJECT;
4227 params.max_hear_distance = BS*getfloatfield_default(L, index,
4228 "max_hear_distance", params.max_hear_distance/BS);
4229 getboolfield(L, index, "loop", params.loop);
4238 // Writes a line to dstream
4239 static int l_debug(lua_State *L)
4241 std::string text = lua_tostring(L, 1);
4242 dstream << text << std::endl;
4246 // log([level,] text)
4247 // Writes a line to the logger.
4248 // The one-argument version logs to infostream.
4249 // The two-argument version accept a log level: error, action, info, or verbose.
4250 static int l_log(lua_State *L)
4253 LogMessageLevel level = LMT_INFO;
4254 if(lua_isnone(L, 2))
4256 text = lua_tostring(L, 1);
4260 std::string levelname = lua_tostring(L, 1);
4261 text = lua_tostring(L, 2);
4262 if(levelname == "error")
4264 else if(levelname == "action")
4266 else if(levelname == "verbose")
4267 level = LMT_VERBOSE;
4269 log_printline(level, text);
4273 // request_shutdown()
4274 static int l_request_shutdown(lua_State *L)
4276 get_server(L)->requestShutdown();
4280 // get_server_status()
4281 static int l_get_server_status(lua_State *L)
4283 lua_pushstring(L, wide_to_narrow(get_server(L)->getStatusString()).c_str());
4287 // register_item_raw({lots of stuff})
4288 static int l_register_item_raw(lua_State *L)
4290 luaL_checktype(L, 1, LUA_TTABLE);
4293 // Get the writable item and node definition managers from the server
4294 IWritableItemDefManager *idef =
4295 get_server(L)->getWritableItemDefManager();
4296 IWritableNodeDefManager *ndef =
4297 get_server(L)->getWritableNodeDefManager();
4299 // Check if name is defined
4301 lua_getfield(L, table, "name");
4302 if(lua_isstring(L, -1)){
4303 name = lua_tostring(L, -1);
4304 verbosestream<<"register_item_raw: "<<name<<std::endl;
4306 throw LuaError(L, "register_item_raw: name is not defined or not a string");
4309 // Check if on_use is defined
4312 // Set a distinctive default value to check if this is set
4313 def.node_placement_prediction = "__default";
4315 // Read the item definition
4316 def = read_item_definition(L, table, def);
4318 // Default to having client-side placement prediction for nodes
4319 // ("" in item definition sets it off)
4320 if(def.node_placement_prediction == "__default"){
4321 if(def.type == ITEM_NODE)
4322 def.node_placement_prediction = name;
4324 def.node_placement_prediction = "";
4327 // Register item definition
4328 idef->registerItem(def);
4330 // Read the node definition (content features) and register it
4331 if(def.type == ITEM_NODE)
4333 ContentFeatures f = read_content_features(L, table);
4334 ndef->set(f.name, f);
4337 return 0; /* number of results */
4340 // register_alias_raw(name, convert_to_name)
4341 static int l_register_alias_raw(lua_State *L)
4343 std::string name = luaL_checkstring(L, 1);
4344 std::string convert_to = luaL_checkstring(L, 2);
4346 // Get the writable item definition manager from the server
4347 IWritableItemDefManager *idef =
4348 get_server(L)->getWritableItemDefManager();
4350 idef->registerAlias(name, convert_to);
4352 return 0; /* number of results */
4355 // helper for register_craft
4356 static bool read_craft_recipe_shaped(lua_State *L, int index,
4357 int &width, std::vector<std::string> &recipe)
4360 index = lua_gettop(L) + 1 + index;
4362 if(!lua_istable(L, index))
4367 while(lua_next(L, index) != 0){
4369 // key at index -2 and value at index -1
4370 if(!lua_istable(L, -1))
4372 int table2 = lua_gettop(L);
4374 while(lua_next(L, table2) != 0){
4375 // key at index -2 and value at index -1
4376 if(!lua_isstring(L, -1))
4378 recipe.push_back(lua_tostring(L, -1));
4379 // removes value, keeps key for next iteration
4386 if(colcount != width)
4389 // removes value, keeps key for next iteration
4396 // helper for register_craft
4397 static bool read_craft_recipe_shapeless(lua_State *L, int index,
4398 std::vector<std::string> &recipe)
4401 index = lua_gettop(L) + 1 + index;
4403 if(!lua_istable(L, index))
4407 while(lua_next(L, index) != 0){
4408 // key at index -2 and value at index -1
4409 if(!lua_isstring(L, -1))
4411 recipe.push_back(lua_tostring(L, -1));
4412 // removes value, keeps key for next iteration
4418 // helper for register_craft
4419 static bool read_craft_replacements(lua_State *L, int index,
4420 CraftReplacements &replacements)
4423 index = lua_gettop(L) + 1 + index;
4425 if(!lua_istable(L, index))
4429 while(lua_next(L, index) != 0){
4430 // key at index -2 and value at index -1
4431 if(!lua_istable(L, -1))
4433 lua_rawgeti(L, -1, 1);
4434 if(!lua_isstring(L, -1))
4436 std::string replace_from = lua_tostring(L, -1);
4438 lua_rawgeti(L, -1, 2);
4439 if(!lua_isstring(L, -1))
4441 std::string replace_to = lua_tostring(L, -1);
4443 replacements.pairs.push_back(
4444 std::make_pair(replace_from, replace_to));
4445 // removes value, keeps key for next iteration
4450 // register_craft({output=item, recipe={{item00,item10},{item01,item11}})
4451 static int l_register_craft(lua_State *L)
4453 //infostream<<"register_craft"<<std::endl;
4454 luaL_checktype(L, 1, LUA_TTABLE);
4457 // Get the writable craft definition manager from the server
4458 IWritableCraftDefManager *craftdef =
4459 get_server(L)->getWritableCraftDefManager();
4461 std::string type = getstringfield_default(L, table, "type", "shaped");
4464 CraftDefinitionShaped
4466 if(type == "shaped"){
4467 std::string output = getstringfield_default(L, table, "output", "");
4469 throw LuaError(L, "Crafting definition is missing an output");
4472 std::vector<std::string> recipe;
4473 lua_getfield(L, table, "recipe");
4474 if(lua_isnil(L, -1))
4475 throw LuaError(L, "Crafting definition is missing a recipe"
4476 " (output=\"" + output + "\")");
4477 if(!read_craft_recipe_shaped(L, -1, width, recipe))
4478 throw LuaError(L, "Invalid crafting recipe"
4479 " (output=\"" + output + "\")");
4481 CraftReplacements replacements;
4482 lua_getfield(L, table, "replacements");
4483 if(!lua_isnil(L, -1))
4485 if(!read_craft_replacements(L, -1, replacements))
4486 throw LuaError(L, "Invalid replacements"
4487 " (output=\"" + output + "\")");
4490 CraftDefinition *def = new CraftDefinitionShaped(
4491 output, width, recipe, replacements);
4492 craftdef->registerCraft(def);
4495 CraftDefinitionShapeless
4497 else if(type == "shapeless"){
4498 std::string output = getstringfield_default(L, table, "output", "");
4500 throw LuaError(L, "Crafting definition (shapeless)"
4501 " is missing an output");
4503 std::vector<std::string> recipe;
4504 lua_getfield(L, table, "recipe");
4505 if(lua_isnil(L, -1))
4506 throw LuaError(L, "Crafting definition (shapeless)"
4507 " is missing a recipe"
4508 " (output=\"" + output + "\")");
4509 if(!read_craft_recipe_shapeless(L, -1, recipe))
4510 throw LuaError(L, "Invalid crafting recipe"
4511 " (output=\"" + output + "\")");
4513 CraftReplacements replacements;
4514 lua_getfield(L, table, "replacements");
4515 if(!lua_isnil(L, -1))
4517 if(!read_craft_replacements(L, -1, replacements))
4518 throw LuaError(L, "Invalid replacements"
4519 " (output=\"" + output + "\")");
4522 CraftDefinition *def = new CraftDefinitionShapeless(
4523 output, recipe, replacements);
4524 craftdef->registerCraft(def);
4527 CraftDefinitionToolRepair
4529 else if(type == "toolrepair"){
4530 float additional_wear = getfloatfield_default(L, table,
4531 "additional_wear", 0.0);
4533 CraftDefinition *def = new CraftDefinitionToolRepair(
4535 craftdef->registerCraft(def);
4538 CraftDefinitionCooking
4540 else if(type == "cooking"){
4541 std::string output = getstringfield_default(L, table, "output", "");
4543 throw LuaError(L, "Crafting definition (cooking)"
4544 " is missing an output");
4546 std::string recipe = getstringfield_default(L, table, "recipe", "");
4548 throw LuaError(L, "Crafting definition (cooking)"
4549 " is missing a recipe"
4550 " (output=\"" + output + "\")");
4552 float cooktime = getfloatfield_default(L, table, "cooktime", 3.0);
4554 CraftReplacements replacements;
4555 lua_getfield(L, table, "replacements");
4556 if(!lua_isnil(L, -1))
4558 if(!read_craft_replacements(L, -1, replacements))
4559 throw LuaError(L, "Invalid replacements"
4560 " (cooking output=\"" + output + "\")");
4563 CraftDefinition *def = new CraftDefinitionCooking(
4564 output, recipe, cooktime, replacements);
4565 craftdef->registerCraft(def);
4570 else if(type == "fuel"){
4571 std::string recipe = getstringfield_default(L, table, "recipe", "");
4573 throw LuaError(L, "Crafting definition (fuel)"
4574 " is missing a recipe");
4576 float burntime = getfloatfield_default(L, table, "burntime", 1.0);
4578 CraftReplacements replacements;
4579 lua_getfield(L, table, "replacements");
4580 if(!lua_isnil(L, -1))
4582 if(!read_craft_replacements(L, -1, replacements))
4583 throw LuaError(L, "Invalid replacements"
4584 " (fuel recipe=\"" + recipe + "\")");
4587 CraftDefinition *def = new CraftDefinitionFuel(
4588 recipe, burntime, replacements);
4589 craftdef->registerCraft(def);
4593 throw LuaError(L, "Unknown crafting definition type: \"" + type + "\"");
4597 return 0; /* number of results */
4600 // setting_set(name, value)
4601 static int l_setting_set(lua_State *L)
4603 const char *name = luaL_checkstring(L, 1);
4604 const char *value = luaL_checkstring(L, 2);
4605 g_settings->set(name, value);
4609 // setting_get(name)
4610 static int l_setting_get(lua_State *L)
4612 const char *name = luaL_checkstring(L, 1);
4614 std::string value = g_settings->get(name);
4615 lua_pushstring(L, value.c_str());
4616 } catch(SettingNotFoundException &e){
4622 // setting_getbool(name)
4623 static int l_setting_getbool(lua_State *L)
4625 const char *name = luaL_checkstring(L, 1);
4627 bool value = g_settings->getBool(name);
4628 lua_pushboolean(L, value);
4629 } catch(SettingNotFoundException &e){
4635 // chat_send_all(text)
4636 static int l_chat_send_all(lua_State *L)
4638 const char *text = luaL_checkstring(L, 1);
4639 // Get server from registry
4640 Server *server = get_server(L);
4642 server->notifyPlayers(narrow_to_wide(text));
4646 // chat_send_player(name, text)
4647 static int l_chat_send_player(lua_State *L)
4649 const char *name = luaL_checkstring(L, 1);
4650 const char *text = luaL_checkstring(L, 2);
4651 // Get server from registry
4652 Server *server = get_server(L);
4654 server->notifyPlayer(name, narrow_to_wide(text));
4658 // get_player_privs(name, text)
4659 static int l_get_player_privs(lua_State *L)
4661 const char *name = luaL_checkstring(L, 1);
4662 // Get server from registry
4663 Server *server = get_server(L);
4666 int table = lua_gettop(L);
4667 std::set<std::string> privs_s = server->getPlayerEffectivePrivs(name);
4668 for(std::set<std::string>::const_iterator
4669 i = privs_s.begin(); i != privs_s.end(); i++){
4670 lua_pushboolean(L, true);
4671 lua_setfield(L, table, i->c_str());
4673 lua_pushvalue(L, table);
4678 static int l_get_ban_list(lua_State *L)
4680 lua_pushstring(L, get_server(L)->getBanDescription("").c_str());
4684 // get_ban_description()
4685 static int l_get_ban_description(lua_State *L)
4687 const char * ip_or_name = luaL_checkstring(L, 1);
4688 lua_pushstring(L, get_server(L)->getBanDescription(std::string(ip_or_name)).c_str());
4693 static int l_ban_player(lua_State *L)
4695 const char * name = luaL_checkstring(L, 1);
4696 Player *player = get_env(L)->getPlayer(name);
4699 lua_pushboolean(L, false); // no such player
4704 Address addr = get_server(L)->getPeerAddress(get_env(L)->getPlayer(name)->peer_id);
4705 std::string ip_str = addr.serializeString();
4706 get_server(L)->setIpBanned(ip_str, name);
4708 catch(con::PeerNotFoundException) // unlikely
4710 dstream << __FUNCTION_NAME << ": peer was not found" << std::endl;
4711 lua_pushboolean(L, false); // error
4714 lua_pushboolean(L, true);
4718 // unban_player_or_ip()
4719 static int l_unban_player_of_ip(lua_State *L)
4721 const char * ip_or_name = luaL_checkstring(L, 1);
4722 get_server(L)->unsetIpBanned(ip_or_name);
4723 lua_pushboolean(L, true);
4727 // get_inventory(location)
4728 static int l_get_inventory(lua_State *L)
4730 InventoryLocation loc;
4732 std::string type = checkstringfield(L, 1, "type");
4733 if(type == "player"){
4734 std::string name = checkstringfield(L, 1, "name");
4735 loc.setPlayer(name);
4736 } else if(type == "node"){
4737 lua_getfield(L, 1, "pos");
4738 v3s16 pos = check_v3s16(L, -1);
4739 loc.setNodeMeta(pos);
4740 } else if(type == "detached"){
4741 std::string name = checkstringfield(L, 1, "name");
4742 loc.setDetached(name);
4745 if(get_server(L)->getInventory(loc) != NULL)
4746 InvRef::create(L, loc);
4752 // create_detached_inventory_raw(name)
4753 static int l_create_detached_inventory_raw(lua_State *L)
4755 const char *name = luaL_checkstring(L, 1);
4756 if(get_server(L)->createDetachedInventory(name) != NULL){
4757 InventoryLocation loc;
4758 loc.setDetached(name);
4759 InvRef::create(L, loc);
4766 // get_dig_params(groups, tool_capabilities[, time_from_last_punch])
4767 static int l_get_dig_params(lua_State *L)
4769 std::map<std::string, int> groups;
4770 read_groups(L, 1, groups);
4771 ToolCapabilities tp = read_tool_capabilities(L, 2);
4772 if(lua_isnoneornil(L, 3))
4773 push_dig_params(L, getDigParams(groups, &tp));
4775 push_dig_params(L, getDigParams(groups, &tp,
4776 luaL_checknumber(L, 3)));
4780 // get_hit_params(groups, tool_capabilities[, time_from_last_punch])
4781 static int l_get_hit_params(lua_State *L)
4783 std::map<std::string, int> groups;
4784 read_groups(L, 1, groups);
4785 ToolCapabilities tp = read_tool_capabilities(L, 2);
4786 if(lua_isnoneornil(L, 3))
4787 push_hit_params(L, getHitParams(groups, &tp));
4789 push_hit_params(L, getHitParams(groups, &tp,
4790 luaL_checknumber(L, 3)));
4794 // get_current_modname()
4795 static int l_get_current_modname(lua_State *L)
4797 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
4801 // get_modpath(modname)
4802 static int l_get_modpath(lua_State *L)
4804 std::string modname = luaL_checkstring(L, 1);
4806 if(modname == "__builtin"){
4807 std::string path = get_server(L)->getBuiltinLuaPath();
4808 lua_pushstring(L, path.c_str());
4811 const ModSpec *mod = get_server(L)->getModSpec(modname);
4816 lua_pushstring(L, mod->path.c_str());
4821 // the returned list is sorted alphabetically for you
4822 static int l_get_modnames(lua_State *L)
4824 // Get a list of mods
4825 core::list<std::string> mods_unsorted, mods_sorted;
4826 get_server(L)->getModNames(mods_unsorted);
4828 // Take unsorted items from mods_unsorted and sort them into
4829 // mods_sorted; not great performance but the number of mods on a
4830 // server will likely be small.
4831 for(core::list<std::string>::Iterator i = mods_unsorted.begin();
4832 i != mods_unsorted.end(); i++)
4835 for(core::list<std::string>::Iterator x = mods_sorted.begin();
4836 x != mods_unsorted.end(); x++)
4838 // I doubt anybody using Minetest will be using
4839 // anything not ASCII based :)
4840 if((*i).compare(*x) <= 0)
4842 mods_sorted.insert_before(x, *i);
4848 mods_sorted.push_back(*i);
4851 // Get the table insertion function from Lua.
4852 lua_getglobal(L, "table");
4853 lua_getfield(L, -1, "insert");
4854 int insertion_func = lua_gettop(L);
4856 // Package them up for Lua
4858 int new_table = lua_gettop(L);
4859 core::list<std::string>::Iterator i = mods_sorted.begin();
4860 while(i != mods_sorted.end())
4862 lua_pushvalue(L, insertion_func);
4863 lua_pushvalue(L, new_table);
4864 lua_pushstring(L, (*i).c_str());
4865 if(lua_pcall(L, 2, 0, 0) != 0)
4867 script_error(L, "error: %s", lua_tostring(L, -1));
4875 static int l_get_worldpath(lua_State *L)
4877 std::string worldpath = get_server(L)->getWorldPath();
4878 lua_pushstring(L, worldpath.c_str());
4882 // sound_play(spec, parameters)
4883 static int l_sound_play(lua_State *L)
4885 SimpleSoundSpec spec;
4886 read_soundspec(L, 1, spec);
4887 ServerSoundParams params;
4888 read_server_sound_params(L, 2, params);
4889 s32 handle = get_server(L)->playSound(spec, params);
4890 lua_pushinteger(L, handle);
4894 // sound_stop(handle)
4895 static int l_sound_stop(lua_State *L)
4897 int handle = luaL_checkinteger(L, 1);
4898 get_server(L)->stopSound(handle);
4902 // is_singleplayer()
4903 static int l_is_singleplayer(lua_State *L)
4905 lua_pushboolean(L, get_server(L)->isSingleplayer());
4909 // get_password_hash(name, raw_password)
4910 static int l_get_password_hash(lua_State *L)
4912 std::string name = luaL_checkstring(L, 1);
4913 std::string raw_password = luaL_checkstring(L, 2);
4914 std::string hash = translatePassword(name,
4915 narrow_to_wide(raw_password));
4916 lua_pushstring(L, hash.c_str());
4920 // notify_authentication_modified(name)
4921 static int l_notify_authentication_modified(lua_State *L)
4923 std::string name = "";
4924 if(lua_isstring(L, 1))
4925 name = lua_tostring(L, 1);
4926 get_server(L)->reportPrivsModified(name);
4930 // get_craft_result(input)
4931 static int l_get_craft_result(lua_State *L)
4934 std::string method_s = getstringfield_default(L, input_i, "method", "normal");
4935 enum CraftMethod method = (CraftMethod)getenumfield(L, input_i, "method",
4936 es_CraftMethod, CRAFT_METHOD_NORMAL);
4938 lua_getfield(L, input_i, "width");
4939 if(lua_isnumber(L, -1))
4940 width = luaL_checkinteger(L, -1);
4942 lua_getfield(L, input_i, "items");
4943 std::vector<ItemStack> items = read_items(L, -1);
4944 lua_pop(L, 1); // items
4946 IGameDef *gdef = get_server(L);
4947 ICraftDefManager *cdef = gdef->cdef();
4948 CraftInput input(method, width, items);
4950 bool got = cdef->getCraftResult(input, output, true, gdef);
4951 lua_newtable(L); // output table
4954 item.deSerialize(output.item, gdef->idef());
4955 LuaItemStack::create(L, item);
4956 lua_setfield(L, -2, "item");
4957 setintfield(L, -1, "time", output.time);
4959 LuaItemStack::create(L, ItemStack());
4960 lua_setfield(L, -2, "item");
4961 setintfield(L, -1, "time", 0);
4963 lua_newtable(L); // decremented input table
4964 lua_pushstring(L, method_s.c_str());
4965 lua_setfield(L, -2, "method");
4966 lua_pushinteger(L, width);
4967 lua_setfield(L, -2, "width");
4968 push_items(L, input.items);
4969 lua_setfield(L, -2, "items");
4973 // get_craft_recipe(result item)
4974 static int l_get_craft_recipe(lua_State *L)
4979 std::string o_item = luaL_checkstring(L,input_i);
4981 IGameDef *gdef = get_server(L);
4982 ICraftDefManager *cdef = gdef->cdef();
4984 CraftOutput output(o_item,0);
4985 bool got = cdef->getCraftRecipe(input, output, gdef);
4986 lua_newtable(L); // output table
4989 for(std::vector<ItemStack>::const_iterator
4990 i = input.items.begin();
4991 i != input.items.end(); i++, k++)
4997 sprintf(tmp,"%d",k);
4998 lua_pushstring(L,tmp);
4999 lua_pushstring(L,i->name.c_str());
5000 lua_settable(L, -3);
5002 lua_setfield(L, -2, "items");
5003 setintfield(L, -1, "width", input.width);
5004 switch (input.method) {
5005 case CRAFT_METHOD_NORMAL:
5006 lua_pushstring(L,"normal");
5008 case CRAFT_METHOD_COOKING:
5009 lua_pushstring(L,"cooking");
5011 case CRAFT_METHOD_FUEL:
5012 lua_pushstring(L,"fuel");
5015 lua_pushstring(L,"unknown");
5017 lua_setfield(L, -2, "type");
5020 lua_setfield(L, -2, "items");
5021 setintfield(L, -1, "width", 0);
5026 // rollback_get_last_node_actor(p, range, seconds) -> actor, p, seconds
5027 static int l_rollback_get_last_node_actor(lua_State *L)
5029 v3s16 p = read_v3s16(L, 1);
5030 int range = luaL_checknumber(L, 2);
5031 int seconds = luaL_checknumber(L, 3);
5032 Server *server = get_server(L);
5033 IRollbackManager *rollback = server->getRollbackManager();
5035 int act_seconds = 0;
5036 std::string actor = rollback->getLastNodeActor(p, range, seconds, &act_p, &act_seconds);
5037 lua_pushstring(L, actor.c_str());
5038 push_v3s16(L, act_p);
5039 lua_pushnumber(L, act_seconds);
5043 // rollback_revert_actions_by(actor, seconds) -> bool, log messages
5044 static int l_rollback_revert_actions_by(lua_State *L)
5046 std::string actor = luaL_checkstring(L, 1);
5047 int seconds = luaL_checknumber(L, 2);
5048 Server *server = get_server(L);
5049 IRollbackManager *rollback = server->getRollbackManager();
5050 std::list<RollbackAction> actions = rollback->getRevertActions(actor, seconds);
5051 std::list<std::string> log;
5052 bool success = server->rollbackRevertActions(actions, &log);
5053 // Push boolean result
5054 lua_pushboolean(L, success);
5055 // Get the table insert function and push the log table
5056 lua_getglobal(L, "table");
5057 lua_getfield(L, -1, "insert");
5058 int table_insert = lua_gettop(L);
5060 int table = lua_gettop(L);
5061 for(std::list<std::string>::const_iterator i = log.begin();
5062 i != log.end(); i++)
5064 lua_pushvalue(L, table_insert);
5065 lua_pushvalue(L, table);
5066 lua_pushstring(L, i->c_str());
5067 if(lua_pcall(L, 2, 0, 0))
5068 script_error(L, "error: %s", lua_tostring(L, -1));
5070 lua_remove(L, -2); // Remove table
5071 lua_remove(L, -2); // Remove insert
5075 static const struct luaL_Reg minetest_f [] = {
5078 {"request_shutdown", l_request_shutdown},
5079 {"get_server_status", l_get_server_status},
5080 {"register_item_raw", l_register_item_raw},
5081 {"register_alias_raw", l_register_alias_raw},
5082 {"register_craft", l_register_craft},
5083 {"setting_set", l_setting_set},
5084 {"setting_get", l_setting_get},
5085 {"setting_getbool", l_setting_getbool},
5086 {"chat_send_all", l_chat_send_all},
5087 {"chat_send_player", l_chat_send_player},
5088 {"get_player_privs", l_get_player_privs},
5089 {"get_ban_list", l_get_ban_list},
5090 {"get_ban_description", l_get_ban_description},
5091 {"ban_player", l_ban_player},
5092 {"unban_player_or_ip", l_unban_player_of_ip},
5093 {"get_inventory", l_get_inventory},
5094 {"create_detached_inventory_raw", l_create_detached_inventory_raw},
5095 {"get_dig_params", l_get_dig_params},
5096 {"get_hit_params", l_get_hit_params},
5097 {"get_current_modname", l_get_current_modname},
5098 {"get_modpath", l_get_modpath},
5099 {"get_modnames", l_get_modnames},
5100 {"get_worldpath", l_get_worldpath},
5101 {"sound_play", l_sound_play},
5102 {"sound_stop", l_sound_stop},
5103 {"is_singleplayer", l_is_singleplayer},
5104 {"get_password_hash", l_get_password_hash},
5105 {"notify_authentication_modified", l_notify_authentication_modified},
5106 {"get_craft_result", l_get_craft_result},
5107 {"get_craft_recipe", l_get_craft_recipe},
5108 {"rollback_get_last_node_actor", l_rollback_get_last_node_actor},
5109 {"rollback_revert_actions_by", l_rollback_revert_actions_by},
5114 Main export function
5117 void scriptapi_export(lua_State *L, Server *server)
5120 assert(lua_checkstack(L, 20));
5121 verbosestream<<"scriptapi_export()"<<std::endl;
5122 StackUnroller stack_unroller(L);
5124 // Store server as light userdata in registry
5125 lua_pushlightuserdata(L, server);
5126 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_server");
5128 // Register global functions in table minetest
5130 luaL_register(L, NULL, minetest_f);
5131 lua_setglobal(L, "minetest");
5133 // Get the main minetest table
5134 lua_getglobal(L, "minetest");
5136 // Add tables to minetest
5138 lua_setfield(L, -2, "object_refs");
5140 lua_setfield(L, -2, "luaentities");
5142 // Register wrappers
5143 LuaItemStack::Register(L);
5144 InvRef::Register(L);
5145 NodeMetaRef::Register(L);
5146 NodeTimerRef::Register(L);
5147 ObjectRef::Register(L);
5148 EnvRef::Register(L);
5149 LuaPseudoRandom::Register(L);
5150 LuaPerlinNoise::Register(L);
5153 bool scriptapi_loadmod(lua_State *L, const std::string &scriptpath,
5154 const std::string &modname)
5156 ModNameStorer modnamestorer(L, modname);
5158 if(!string_allowed(modname, "abcdefghijklmnopqrstuvwxyz"
5160 errorstream<<"Error loading mod \""<<modname
5161 <<"\": modname does not follow naming conventions: "
5162 <<"Only chararacters [a-z0-9_] are allowed."<<std::endl;
5166 bool success = false;
5169 success = script_load(L, scriptpath.c_str());
5172 errorstream<<"Error loading mod \""<<modname
5173 <<"\": "<<e.what()<<std::endl;
5179 void scriptapi_add_environment(lua_State *L, ServerEnvironment *env)
5182 assert(lua_checkstack(L, 20));
5183 verbosestream<<"scriptapi_add_environment"<<std::endl;
5184 StackUnroller stack_unroller(L);
5186 // Create EnvRef on stack
5187 EnvRef::create(L, env);
5188 int envref = lua_gettop(L);
5190 // minetest.env = envref
5191 lua_getglobal(L, "minetest");
5192 luaL_checktype(L, -1, LUA_TTABLE);
5193 lua_pushvalue(L, envref);
5194 lua_setfield(L, -2, "env");
5196 // Store environment as light userdata in registry
5197 lua_pushlightuserdata(L, env);
5198 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_env");
5201 Add ActiveBlockModifiers to environment
5204 // Get minetest.registered_abms
5205 lua_getglobal(L, "minetest");
5206 lua_getfield(L, -1, "registered_abms");
5207 luaL_checktype(L, -1, LUA_TTABLE);
5208 int registered_abms = lua_gettop(L);
5210 if(lua_istable(L, registered_abms)){
5211 int table = lua_gettop(L);
5213 while(lua_next(L, table) != 0){
5214 // key at index -2 and value at index -1
5215 int id = lua_tonumber(L, -2);
5216 int current_abm = lua_gettop(L);
5218 std::set<std::string> trigger_contents;
5219 lua_getfield(L, current_abm, "nodenames");
5220 if(lua_istable(L, -1)){
5221 int table = lua_gettop(L);
5223 while(lua_next(L, table) != 0){
5224 // key at index -2 and value at index -1
5225 luaL_checktype(L, -1, LUA_TSTRING);
5226 trigger_contents.insert(lua_tostring(L, -1));
5227 // removes value, keeps key for next iteration
5230 } else if(lua_isstring(L, -1)){
5231 trigger_contents.insert(lua_tostring(L, -1));
5235 std::set<std::string> required_neighbors;
5236 lua_getfield(L, current_abm, "neighbors");
5237 if(lua_istable(L, -1)){
5238 int table = lua_gettop(L);
5240 while(lua_next(L, table) != 0){
5241 // key at index -2 and value at index -1
5242 luaL_checktype(L, -1, LUA_TSTRING);
5243 required_neighbors.insert(lua_tostring(L, -1));
5244 // removes value, keeps key for next iteration
5247 } else if(lua_isstring(L, -1)){
5248 required_neighbors.insert(lua_tostring(L, -1));
5252 float trigger_interval = 10.0;
5253 getfloatfield(L, current_abm, "interval", trigger_interval);
5255 int trigger_chance = 50;
5256 getintfield(L, current_abm, "chance", trigger_chance);
5258 LuaABM *abm = new LuaABM(L, id, trigger_contents,
5259 required_neighbors, trigger_interval, trigger_chance);
5261 env->addActiveBlockModifier(abm);
5263 // removes value, keeps key for next iteration
5271 // Dump stack top with the dump2 function
5272 static void dump2(lua_State *L, const char *name)
5274 // Dump object (debug)
5275 lua_getglobal(L, "dump2");
5276 luaL_checktype(L, -1, LUA_TFUNCTION);
5277 lua_pushvalue(L, -2); // Get previous stack top as first parameter
5278 lua_pushstring(L, name);
5279 if(lua_pcall(L, 2, 0, 0))
5280 script_error(L, "error: %s", lua_tostring(L, -1));
5288 void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj)
5291 assert(lua_checkstack(L, 20));
5292 //infostream<<"scriptapi_add_object_reference: id="<<cobj->getId()<<std::endl;
5293 StackUnroller stack_unroller(L);
5295 // Create object on stack
5296 ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack
5297 int object = lua_gettop(L);
5299 // Get minetest.object_refs table
5300 lua_getglobal(L, "minetest");
5301 lua_getfield(L, -1, "object_refs");
5302 luaL_checktype(L, -1, LUA_TTABLE);
5303 int objectstable = lua_gettop(L);
5305 // object_refs[id] = object
5306 lua_pushnumber(L, cobj->getId()); // Push id
5307 lua_pushvalue(L, object); // Copy object to top of stack
5308 lua_settable(L, objectstable);
5311 void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj)
5314 assert(lua_checkstack(L, 20));
5315 //infostream<<"scriptapi_rm_object_reference: id="<<cobj->getId()<<std::endl;
5316 StackUnroller stack_unroller(L);
5318 // Get minetest.object_refs table
5319 lua_getglobal(L, "minetest");
5320 lua_getfield(L, -1, "object_refs");
5321 luaL_checktype(L, -1, LUA_TTABLE);
5322 int objectstable = lua_gettop(L);
5324 // Get object_refs[id]
5325 lua_pushnumber(L, cobj->getId()); // Push id
5326 lua_gettable(L, objectstable);
5327 // Set object reference to NULL
5328 ObjectRef::set_null(L);
5329 lua_pop(L, 1); // pop object
5331 // Set object_refs[id] = nil
5332 lua_pushnumber(L, cobj->getId()); // Push id
5334 lua_settable(L, objectstable);
5341 // What scriptapi_run_callbacks does with the return values of callbacks.
5342 // Regardless of the mode, if only one callback is defined,
5343 // its return value is the total return value.
5344 // Modes only affect the case where 0 or >= 2 callbacks are defined.
5345 enum RunCallbacksMode
5347 // Returns the return value of the first callback
5348 // Returns nil if list of callbacks is empty
5349 RUN_CALLBACKS_MODE_FIRST,
5350 // Returns the return value of the last callback
5351 // Returns nil if list of callbacks is empty
5352 RUN_CALLBACKS_MODE_LAST,
5353 // If any callback returns a false value, the first such is returned
5354 // Otherwise, the first callback's return value (trueish) is returned
5355 // Returns true if list of callbacks is empty
5356 RUN_CALLBACKS_MODE_AND,
5357 // Like above, but stops calling callbacks (short circuit)
5358 // after seeing the first false value
5359 RUN_CALLBACKS_MODE_AND_SC,
5360 // If any callback returns a true value, the first such is returned
5361 // Otherwise, the first callback's return value (falseish) is returned
5362 // Returns false if list of callbacks is empty
5363 RUN_CALLBACKS_MODE_OR,
5364 // Like above, but stops calling callbacks (short circuit)
5365 // after seeing the first true value
5366 RUN_CALLBACKS_MODE_OR_SC,
5367 // Note: "a true value" and "a false value" refer to values that
5368 // are converted by lua_toboolean to true or false, respectively.
5371 // Push the list of callbacks (a lua table).
5372 // Then push nargs arguments.
5373 // Then call this function, which
5374 // - runs the callbacks
5375 // - removes the table and arguments from the lua stack
5376 // - pushes the return value, computed depending on mode
5377 static void scriptapi_run_callbacks(lua_State *L, int nargs,
5378 RunCallbacksMode mode)
5380 // Insert the return value into the lua stack, below the table
5381 assert(lua_gettop(L) >= nargs + 1);
5383 lua_insert(L, -(nargs + 1) - 1);
5384 // Stack now looks like this:
5385 // ... <return value = nil> <table> <arg#1> <arg#2> ... <arg#n>
5387 int rv = lua_gettop(L) - nargs - 1;
5389 int arg = table + 1;
5391 luaL_checktype(L, table, LUA_TTABLE);
5395 bool first_loop = true;
5396 while(lua_next(L, table) != 0){
5397 // key at index -2 and value at index -1
5398 luaL_checktype(L, -1, LUA_TFUNCTION);
5400 for(int i = 0; i < nargs; i++)
5401 lua_pushvalue(L, arg+i);
5402 if(lua_pcall(L, nargs, 1, 0))
5403 script_error(L, "error: %s", lua_tostring(L, -1));
5405 // Move return value to designated space in stack
5408 // Result of first callback is always moved
5412 // Otherwise, what happens depends on the mode
5413 if(mode == RUN_CALLBACKS_MODE_FIRST)
5415 else if(mode == RUN_CALLBACKS_MODE_LAST)
5417 else if(mode == RUN_CALLBACKS_MODE_AND ||
5418 mode == RUN_CALLBACKS_MODE_AND_SC){
5419 if(lua_toboolean(L, rv) == true &&
5420 lua_toboolean(L, -1) == false)
5425 else if(mode == RUN_CALLBACKS_MODE_OR ||
5426 mode == RUN_CALLBACKS_MODE_OR_SC){
5427 if(lua_toboolean(L, rv) == false &&
5428 lua_toboolean(L, -1) == true)
5437 // Handle short circuit modes
5438 if(mode == RUN_CALLBACKS_MODE_AND_SC &&
5439 lua_toboolean(L, rv) == false)
5441 else if(mode == RUN_CALLBACKS_MODE_OR_SC &&
5442 lua_toboolean(L, rv) == true)
5445 // value removed, keep key for next iteration
5448 // Remove stuff from stack, leaving only the return value
5451 // Fix return value in case no callbacks were called
5453 if(mode == RUN_CALLBACKS_MODE_AND ||
5454 mode == RUN_CALLBACKS_MODE_AND_SC){
5456 lua_pushboolean(L, true);
5458 else if(mode == RUN_CALLBACKS_MODE_OR ||
5459 mode == RUN_CALLBACKS_MODE_OR_SC){
5461 lua_pushboolean(L, false);
5466 bool scriptapi_on_chat_message(lua_State *L, const std::string &name,
5467 const std::string &message)
5470 assert(lua_checkstack(L, 20));
5471 StackUnroller stack_unroller(L);
5473 // Get minetest.registered_on_chat_messages
5474 lua_getglobal(L, "minetest");
5475 lua_getfield(L, -1, "registered_on_chat_messages");
5477 lua_pushstring(L, name.c_str());
5478 lua_pushstring(L, message.c_str());
5479 scriptapi_run_callbacks(L, 2, RUN_CALLBACKS_MODE_OR_SC);
5480 bool ate = lua_toboolean(L, -1);
5484 void scriptapi_on_newplayer(lua_State *L, ServerActiveObject *player)
5487 assert(lua_checkstack(L, 20));
5488 StackUnroller stack_unroller(L);
5490 // Get minetest.registered_on_newplayers
5491 lua_getglobal(L, "minetest");
5492 lua_getfield(L, -1, "registered_on_newplayers");
5494 objectref_get_or_create(L, player);
5495 scriptapi_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
5498 void scriptapi_on_dieplayer(lua_State *L, ServerActiveObject *player)
5501 assert(lua_checkstack(L, 20));
5502 StackUnroller stack_unroller(L);
5504 // Get minetest.registered_on_dieplayers
5505 lua_getglobal(L, "minetest");
5506 lua_getfield(L, -1, "registered_on_dieplayers");
5508 objectref_get_or_create(L, player);
5509 scriptapi_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
5512 bool scriptapi_on_respawnplayer(lua_State *L, ServerActiveObject *player)
5515 assert(lua_checkstack(L, 20));
5516 StackUnroller stack_unroller(L);
5518 // Get minetest.registered_on_respawnplayers
5519 lua_getglobal(L, "minetest");
5520 lua_getfield(L, -1, "registered_on_respawnplayers");
5522 objectref_get_or_create(L, player);
5523 scriptapi_run_callbacks(L, 1, RUN_CALLBACKS_MODE_OR);
5524 bool positioning_handled_by_some = lua_toboolean(L, -1);
5525 return positioning_handled_by_some;
5528 void scriptapi_on_joinplayer(lua_State *L, ServerActiveObject *player)
5531 assert(lua_checkstack(L, 20));
5532 StackUnroller stack_unroller(L);
5534 // Get minetest.registered_on_joinplayers
5535 lua_getglobal(L, "minetest");
5536 lua_getfield(L, -1, "registered_on_joinplayers");
5538 objectref_get_or_create(L, player);
5539 scriptapi_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
5542 void scriptapi_on_leaveplayer(lua_State *L, ServerActiveObject *player)
5545 assert(lua_checkstack(L, 20));
5546 StackUnroller stack_unroller(L);
5548 // Get minetest.registered_on_leaveplayers
5549 lua_getglobal(L, "minetest");
5550 lua_getfield(L, -1, "registered_on_leaveplayers");
5552 objectref_get_or_create(L, player);
5553 scriptapi_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
5556 static void get_auth_handler(lua_State *L)
5558 lua_getglobal(L, "minetest");
5559 lua_getfield(L, -1, "registered_auth_handler");
5560 if(lua_isnil(L, -1)){
5562 lua_getfield(L, -1, "builtin_auth_handler");
5564 if(lua_type(L, -1) != LUA_TTABLE)
5565 throw LuaError(L, "Authentication handler table not valid");
5568 bool scriptapi_get_auth(lua_State *L, const std::string &playername,
5569 std::string *dst_password, std::set<std::string> *dst_privs)
5572 assert(lua_checkstack(L, 20));
5573 StackUnroller stack_unroller(L);
5575 get_auth_handler(L);
5576 lua_getfield(L, -1, "get_auth");
5577 if(lua_type(L, -1) != LUA_TFUNCTION)
5578 throw LuaError(L, "Authentication handler missing get_auth");
5579 lua_pushstring(L, playername.c_str());
5580 if(lua_pcall(L, 1, 1, 0))
5581 script_error(L, "error: %s", lua_tostring(L, -1));
5583 // nil = login not allowed
5584 if(lua_isnil(L, -1))
5586 luaL_checktype(L, -1, LUA_TTABLE);
5588 std::string password;
5589 bool found = getstringfield(L, -1, "password", password);
5591 throw LuaError(L, "Authentication handler didn't return password");
5593 *dst_password = password;
5595 lua_getfield(L, -1, "privileges");
5596 if(!lua_istable(L, -1))
5598 "Authentication handler didn't return privilege table");
5600 read_privileges(L, -1, *dst_privs);
5606 void scriptapi_create_auth(lua_State *L, const std::string &playername,
5607 const std::string &password)
5610 assert(lua_checkstack(L, 20));
5611 StackUnroller stack_unroller(L);
5613 get_auth_handler(L);
5614 lua_getfield(L, -1, "create_auth");
5615 if(lua_type(L, -1) != LUA_TFUNCTION)
5616 throw LuaError(L, "Authentication handler missing create_auth");
5617 lua_pushstring(L, playername.c_str());
5618 lua_pushstring(L, password.c_str());
5619 if(lua_pcall(L, 2, 0, 0))
5620 script_error(L, "error: %s", lua_tostring(L, -1));
5623 bool scriptapi_set_password(lua_State *L, const std::string &playername,
5624 const std::string &password)
5627 assert(lua_checkstack(L, 20));
5628 StackUnroller stack_unroller(L);
5630 get_auth_handler(L);
5631 lua_getfield(L, -1, "set_password");
5632 if(lua_type(L, -1) != LUA_TFUNCTION)
5633 throw LuaError(L, "Authentication handler missing set_password");
5634 lua_pushstring(L, playername.c_str());
5635 lua_pushstring(L, password.c_str());
5636 if(lua_pcall(L, 2, 1, 0))
5637 script_error(L, "error: %s", lua_tostring(L, -1));
5638 return lua_toboolean(L, -1);
5645 void scriptapi_on_player_receive_fields(lua_State *L,
5646 ServerActiveObject *player,
5647 const std::string &formname,
5648 const std::map<std::string, std::string> &fields)
5651 assert(lua_checkstack(L, 20));
5652 StackUnroller stack_unroller(L);
5654 // Get minetest.registered_on_chat_messages
5655 lua_getglobal(L, "minetest");
5656 lua_getfield(L, -1, "registered_on_player_receive_fields");
5659 objectref_get_or_create(L, player);
5661 lua_pushstring(L, formname.c_str());
5664 for(std::map<std::string, std::string>::const_iterator
5665 i = fields.begin(); i != fields.end(); i++){
5666 const std::string &name = i->first;
5667 const std::string &value = i->second;
5668 lua_pushstring(L, name.c_str());
5669 lua_pushlstring(L, value.c_str(), value.size());
5670 lua_settable(L, -3);
5672 scriptapi_run_callbacks(L, 3, RUN_CALLBACKS_MODE_OR_SC);
5676 item callbacks and node callbacks
5679 // Retrieves minetest.registered_items[name][callbackname]
5680 // If that is nil or on error, return false and stack is unchanged
5681 // If that is a function, returns true and pushes the
5682 // function onto the stack
5683 // If minetest.registered_items[name] doesn't exist, minetest.nodedef_default
5684 // is tried instead so unknown items can still be manipulated to some degree
5685 static bool get_item_callback(lua_State *L,
5686 const char *name, const char *callbackname)
5688 lua_getglobal(L, "minetest");
5689 lua_getfield(L, -1, "registered_items");
5691 luaL_checktype(L, -1, LUA_TTABLE);
5692 lua_getfield(L, -1, name);
5694 // Should be a table
5695 if(lua_type(L, -1) != LUA_TTABLE)
5697 // Report error and clean up
5698 errorstream<<"Item \""<<name<<"\" not defined"<<std::endl;
5701 // Try minetest.nodedef_default instead
5702 lua_getglobal(L, "minetest");
5703 lua_getfield(L, -1, "nodedef_default");
5705 luaL_checktype(L, -1, LUA_TTABLE);
5707 lua_getfield(L, -1, callbackname);
5709 // Should be a function or nil
5710 if(lua_type(L, -1) == LUA_TFUNCTION)
5714 else if(lua_isnil(L, -1))
5721 errorstream<<"Item \""<<name<<"\" callback \""
5722 <<callbackname<<" is not a function"<<std::endl;
5728 bool scriptapi_item_on_drop(lua_State *L, ItemStack &item,
5729 ServerActiveObject *dropper, v3f pos)
5732 assert(lua_checkstack(L, 20));
5733 StackUnroller stack_unroller(L);
5735 // Push callback function on stack
5736 if(!get_item_callback(L, item.name.c_str(), "on_drop"))
5740 LuaItemStack::create(L, item);
5741 objectref_get_or_create(L, dropper);
5742 pushFloatPos(L, pos);
5743 if(lua_pcall(L, 3, 1, 0))
5744 script_error(L, "error: %s", lua_tostring(L, -1));
5745 if(!lua_isnil(L, -1))
5746 item = read_item(L, -1);
5750 bool scriptapi_item_on_place(lua_State *L, ItemStack &item,
5751 ServerActiveObject *placer, const PointedThing &pointed)
5754 assert(lua_checkstack(L, 20));
5755 StackUnroller stack_unroller(L);
5757 // Push callback function on stack
5758 if(!get_item_callback(L, item.name.c_str(), "on_place"))
5762 LuaItemStack::create(L, item);
5763 objectref_get_or_create(L, placer);
5764 push_pointed_thing(L, pointed);
5765 if(lua_pcall(L, 3, 1, 0))
5766 script_error(L, "error: %s", lua_tostring(L, -1));
5767 if(!lua_isnil(L, -1))
5768 item = read_item(L, -1);
5772 bool scriptapi_item_on_use(lua_State *L, ItemStack &item,
5773 ServerActiveObject *user, const PointedThing &pointed)
5776 assert(lua_checkstack(L, 20));
5777 StackUnroller stack_unroller(L);
5779 // Push callback function on stack
5780 if(!get_item_callback(L, item.name.c_str(), "on_use"))
5784 LuaItemStack::create(L, item);
5785 objectref_get_or_create(L, user);
5786 push_pointed_thing(L, pointed);
5787 if(lua_pcall(L, 3, 1, 0))
5788 script_error(L, "error: %s", lua_tostring(L, -1));
5789 if(!lua_isnil(L, -1))
5790 item = read_item(L, -1);
5794 bool scriptapi_node_on_punch(lua_State *L, v3s16 p, MapNode node,
5795 ServerActiveObject *puncher)
5798 assert(lua_checkstack(L, 20));
5799 StackUnroller stack_unroller(L);
5801 INodeDefManager *ndef = get_server(L)->ndef();
5803 // Push callback function on stack
5804 if(!get_item_callback(L, ndef->get(node).name.c_str(), "on_punch"))
5809 pushnode(L, node, ndef);
5810 objectref_get_or_create(L, puncher);
5811 if(lua_pcall(L, 3, 0, 0))
5812 script_error(L, "error: %s", lua_tostring(L, -1));
5816 bool scriptapi_node_on_dig(lua_State *L, v3s16 p, MapNode node,
5817 ServerActiveObject *digger)
5820 assert(lua_checkstack(L, 20));
5821 StackUnroller stack_unroller(L);
5823 INodeDefManager *ndef = get_server(L)->ndef();
5825 // Push callback function on stack
5826 if(!get_item_callback(L, ndef->get(node).name.c_str(), "on_dig"))
5831 pushnode(L, node, ndef);
5832 objectref_get_or_create(L, digger);
5833 if(lua_pcall(L, 3, 0, 0))
5834 script_error(L, "error: %s", lua_tostring(L, -1));
5838 void scriptapi_node_on_construct(lua_State *L, v3s16 p, MapNode node)
5841 assert(lua_checkstack(L, 20));
5842 StackUnroller stack_unroller(L);
5844 INodeDefManager *ndef = get_server(L)->ndef();
5846 // Push callback function on stack
5847 if(!get_item_callback(L, ndef->get(node).name.c_str(), "on_construct"))
5852 if(lua_pcall(L, 1, 0, 0))
5853 script_error(L, "error: %s", lua_tostring(L, -1));
5856 void scriptapi_node_on_destruct(lua_State *L, v3s16 p, MapNode node)
5859 assert(lua_checkstack(L, 20));
5860 StackUnroller stack_unroller(L);
5862 INodeDefManager *ndef = get_server(L)->ndef();
5864 // Push callback function on stack
5865 if(!get_item_callback(L, ndef->get(node).name.c_str(), "on_destruct"))
5870 if(lua_pcall(L, 1, 0, 0))
5871 script_error(L, "error: %s", lua_tostring(L, -1));
5874 void scriptapi_node_after_destruct(lua_State *L, v3s16 p, MapNode node)
5877 assert(lua_checkstack(L, 20));
5878 StackUnroller stack_unroller(L);
5880 INodeDefManager *ndef = get_server(L)->ndef();
5882 // Push callback function on stack
5883 if(!get_item_callback(L, ndef->get(node).name.c_str(), "after_destruct"))
5888 pushnode(L, node, ndef);
5889 if(lua_pcall(L, 2, 0, 0))
5890 script_error(L, "error: %s", lua_tostring(L, -1));
5893 bool scriptapi_node_on_timer(lua_State *L, v3s16 p, MapNode node, f32 dtime)
5896 assert(lua_checkstack(L, 20));
5897 StackUnroller stack_unroller(L);
5899 INodeDefManager *ndef = get_server(L)->ndef();
5901 // Push callback function on stack
5902 if(!get_item_callback(L, ndef->get(node).name.c_str(), "on_timer"))
5907 lua_pushnumber(L,dtime);
5908 if(lua_pcall(L, 2, 1, 0))
5909 script_error(L, "error: %s", lua_tostring(L, -1));
5910 if(lua_isboolean(L,-1) && lua_toboolean(L,-1) == true)
5916 void scriptapi_node_on_receive_fields(lua_State *L, v3s16 p,
5917 const std::string &formname,
5918 const std::map<std::string, std::string> &fields,
5919 ServerActiveObject *sender)
5922 assert(lua_checkstack(L, 20));
5923 StackUnroller stack_unroller(L);
5925 INodeDefManager *ndef = get_server(L)->ndef();
5927 // If node doesn't exist, we don't know what callback to call
5928 MapNode node = get_env(L)->getMap().getNodeNoEx(p);
5929 if(node.getContent() == CONTENT_IGNORE)
5932 // Push callback function on stack
5933 if(!get_item_callback(L, ndef->get(node).name.c_str(), "on_receive_fields"))
5940 lua_pushstring(L, formname.c_str());
5943 for(std::map<std::string, std::string>::const_iterator
5944 i = fields.begin(); i != fields.end(); i++){
5945 const std::string &name = i->first;
5946 const std::string &value = i->second;
5947 lua_pushstring(L, name.c_str());
5948 lua_pushlstring(L, value.c_str(), value.size());
5949 lua_settable(L, -3);
5952 objectref_get_or_create(L, sender);
5953 if(lua_pcall(L, 4, 0, 0))
5954 script_error(L, "error: %s", lua_tostring(L, -1));
5958 Node metadata inventory callbacks
5961 // Return number of accepted items to be moved
5962 int scriptapi_nodemeta_inventory_allow_move(lua_State *L, v3s16 p,
5963 const std::string &from_list, int from_index,
5964 const std::string &to_list, int to_index,
5965 int count, ServerActiveObject *player)
5968 assert(lua_checkstack(L, 20));
5969 StackUnroller stack_unroller(L);
5971 INodeDefManager *ndef = get_server(L)->ndef();
5973 // If node doesn't exist, we don't know what callback to call
5974 MapNode node = get_env(L)->getMap().getNodeNoEx(p);
5975 if(node.getContent() == CONTENT_IGNORE)
5978 // Push callback function on stack
5979 if(!get_item_callback(L, ndef->get(node).name.c_str(),
5980 "allow_metadata_inventory_move"))
5983 // function(pos, from_list, from_index, to_list, to_index, count, player)
5987 lua_pushstring(L, from_list.c_str());
5989 lua_pushinteger(L, from_index + 1);
5991 lua_pushstring(L, to_list.c_str());
5993 lua_pushinteger(L, to_index + 1);
5995 lua_pushinteger(L, count);
5997 objectref_get_or_create(L, player);
5998 if(lua_pcall(L, 7, 1, 0))
5999 script_error(L, "error: %s", lua_tostring(L, -1));
6000 if(!lua_isnumber(L, -1))
6001 throw LuaError(L, "allow_metadata_inventory_move should return a number");
6002 return luaL_checkinteger(L, -1);
6005 // Return number of accepted items to be put
6006 int scriptapi_nodemeta_inventory_allow_put(lua_State *L, v3s16 p,
6007 const std::string &listname, int index, ItemStack &stack,
6008 ServerActiveObject *player)
6011 assert(lua_checkstack(L, 20));
6012 StackUnroller stack_unroller(L);
6014 INodeDefManager *ndef = get_server(L)->ndef();
6016 // If node doesn't exist, we don't know what callback to call
6017 MapNode node = get_env(L)->getMap().getNodeNoEx(p);
6018 if(node.getContent() == CONTENT_IGNORE)
6021 // Push callback function on stack
6022 if(!get_item_callback(L, ndef->get(node).name.c_str(),
6023 "allow_metadata_inventory_put"))
6026 // Call function(pos, listname, index, stack, player)
6030 lua_pushstring(L, listname.c_str());
6032 lua_pushinteger(L, index + 1);
6034 LuaItemStack::create(L, stack);
6036 objectref_get_or_create(L, player);
6037 if(lua_pcall(L, 5, 1, 0))
6038 script_error(L, "error: %s", lua_tostring(L, -1));
6039 if(!lua_isnumber(L, -1))
6040 throw LuaError(L, "allow_metadata_inventory_put should return a number");
6041 return luaL_checkinteger(L, -1);
6044 // Return number of accepted items to be taken
6045 int scriptapi_nodemeta_inventory_allow_take(lua_State *L, v3s16 p,
6046 const std::string &listname, int index, ItemStack &stack,
6047 ServerActiveObject *player)
6050 assert(lua_checkstack(L, 20));
6051 StackUnroller stack_unroller(L);
6053 INodeDefManager *ndef = get_server(L)->ndef();
6055 // If node doesn't exist, we don't know what callback to call
6056 MapNode node = get_env(L)->getMap().getNodeNoEx(p);
6057 if(node.getContent() == CONTENT_IGNORE)
6060 // Push callback function on stack
6061 if(!get_item_callback(L, ndef->get(node).name.c_str(),
6062 "allow_metadata_inventory_take"))
6065 // Call function(pos, listname, index, count, player)
6069 lua_pushstring(L, listname.c_str());
6071 lua_pushinteger(L, index + 1);
6073 LuaItemStack::create(L, stack);
6075 objectref_get_or_create(L, player);
6076 if(lua_pcall(L, 5, 1, 0))
6077 script_error(L, "error: %s", lua_tostring(L, -1));
6078 if(!lua_isnumber(L, -1))
6079 throw LuaError(L, "allow_metadata_inventory_take should return a number");
6080 return luaL_checkinteger(L, -1);
6083 // Report moved items
6084 void scriptapi_nodemeta_inventory_on_move(lua_State *L, v3s16 p,
6085 const std::string &from_list, int from_index,
6086 const std::string &to_list, int to_index,
6087 int count, ServerActiveObject *player)
6090 assert(lua_checkstack(L, 20));
6091 StackUnroller stack_unroller(L);
6093 INodeDefManager *ndef = get_server(L)->ndef();
6095 // If node doesn't exist, we don't know what callback to call
6096 MapNode node = get_env(L)->getMap().getNodeNoEx(p);
6097 if(node.getContent() == CONTENT_IGNORE)
6100 // Push callback function on stack
6101 if(!get_item_callback(L, ndef->get(node).name.c_str(),
6102 "on_metadata_inventory_move"))
6105 // function(pos, from_list, from_index, to_list, to_index, count, player)
6109 lua_pushstring(L, from_list.c_str());
6111 lua_pushinteger(L, from_index + 1);
6113 lua_pushstring(L, to_list.c_str());
6115 lua_pushinteger(L, to_index + 1);
6117 lua_pushinteger(L, count);
6119 objectref_get_or_create(L, player);
6120 if(lua_pcall(L, 7, 0, 0))
6121 script_error(L, "error: %s", lua_tostring(L, -1));
6125 void scriptapi_nodemeta_inventory_on_put(lua_State *L, v3s16 p,
6126 const std::string &listname, int index, ItemStack &stack,
6127 ServerActiveObject *player)
6130 assert(lua_checkstack(L, 20));
6131 StackUnroller stack_unroller(L);
6133 INodeDefManager *ndef = get_server(L)->ndef();
6135 // If node doesn't exist, we don't know what callback to call
6136 MapNode node = get_env(L)->getMap().getNodeNoEx(p);
6137 if(node.getContent() == CONTENT_IGNORE)
6140 // Push callback function on stack
6141 if(!get_item_callback(L, ndef->get(node).name.c_str(),
6142 "on_metadata_inventory_put"))
6145 // Call function(pos, listname, index, stack, player)
6149 lua_pushstring(L, listname.c_str());
6151 lua_pushinteger(L, index + 1);
6153 LuaItemStack::create(L, stack);
6155 objectref_get_or_create(L, player);
6156 if(lua_pcall(L, 5, 0, 0))
6157 script_error(L, "error: %s", lua_tostring(L, -1));
6160 // Report taken items
6161 void scriptapi_nodemeta_inventory_on_take(lua_State *L, v3s16 p,
6162 const std::string &listname, int index, ItemStack &stack,
6163 ServerActiveObject *player)
6166 assert(lua_checkstack(L, 20));
6167 StackUnroller stack_unroller(L);
6169 INodeDefManager *ndef = get_server(L)->ndef();
6171 // If node doesn't exist, we don't know what callback to call
6172 MapNode node = get_env(L)->getMap().getNodeNoEx(p);
6173 if(node.getContent() == CONTENT_IGNORE)
6176 // Push callback function on stack
6177 if(!get_item_callback(L, ndef->get(node).name.c_str(),
6178 "on_metadata_inventory_take"))
6181 // Call function(pos, listname, index, stack, player)
6185 lua_pushstring(L, listname.c_str());
6187 lua_pushinteger(L, index + 1);
6189 LuaItemStack::create(L, stack);
6191 objectref_get_or_create(L, player);
6192 if(lua_pcall(L, 5, 0, 0))
6193 script_error(L, "error: %s", lua_tostring(L, -1));
6197 Detached inventory callbacks
6200 // Retrieves minetest.detached_inventories[name][callbackname]
6201 // If that is nil or on error, return false and stack is unchanged
6202 // If that is a function, returns true and pushes the
6203 // function onto the stack
6204 static bool get_detached_inventory_callback(lua_State *L,
6205 const std::string &name, const char *callbackname)
6207 lua_getglobal(L, "minetest");
6208 lua_getfield(L, -1, "detached_inventories");
6210 luaL_checktype(L, -1, LUA_TTABLE);
6211 lua_getfield(L, -1, name.c_str());
6213 // Should be a table
6214 if(lua_type(L, -1) != LUA_TTABLE)
6216 errorstream<<"Item \""<<name<<"\" not defined"<<std::endl;
6220 lua_getfield(L, -1, callbackname);
6222 // Should be a function or nil
6223 if(lua_type(L, -1) == LUA_TFUNCTION)
6227 else if(lua_isnil(L, -1))
6234 errorstream<<"Detached inventory \""<<name<<"\" callback \""
6235 <<callbackname<<"\" is not a function"<<std::endl;
6241 // Return number of accepted items to be moved
6242 int scriptapi_detached_inventory_allow_move(lua_State *L,
6243 const std::string &name,
6244 const std::string &from_list, int from_index,
6245 const std::string &to_list, int to_index,
6246 int count, ServerActiveObject *player)
6249 assert(lua_checkstack(L, 20));
6250 StackUnroller stack_unroller(L);
6252 // Push callback function on stack
6253 if(!get_detached_inventory_callback(L, name, "allow_move"))
6256 // function(inv, from_list, from_index, to_list, to_index, count, player)
6258 InventoryLocation loc;
6259 loc.setDetached(name);
6260 InvRef::create(L, loc);
6262 lua_pushstring(L, from_list.c_str());
6264 lua_pushinteger(L, from_index + 1);
6266 lua_pushstring(L, to_list.c_str());
6268 lua_pushinteger(L, to_index + 1);
6270 lua_pushinteger(L, count);
6272 objectref_get_or_create(L, player);
6273 if(lua_pcall(L, 7, 1, 0))
6274 script_error(L, "error: %s", lua_tostring(L, -1));
6275 if(!lua_isnumber(L, -1))
6276 throw LuaError(L, "allow_move should return a number");
6277 return luaL_checkinteger(L, -1);
6280 // Return number of accepted items to be put
6281 int scriptapi_detached_inventory_allow_put(lua_State *L,
6282 const std::string &name,
6283 const std::string &listname, int index, ItemStack &stack,
6284 ServerActiveObject *player)
6287 assert(lua_checkstack(L, 20));
6288 StackUnroller stack_unroller(L);
6290 // Push callback function on stack
6291 if(!get_detached_inventory_callback(L, name, "allow_put"))
6292 return stack.count; // All will be accepted
6294 // Call function(inv, listname, index, stack, player)
6296 InventoryLocation loc;
6297 loc.setDetached(name);
6298 InvRef::create(L, loc);
6300 lua_pushstring(L, listname.c_str());
6302 lua_pushinteger(L, index + 1);
6304 LuaItemStack::create(L, stack);
6306 objectref_get_or_create(L, player);
6307 if(lua_pcall(L, 5, 1, 0))
6308 script_error(L, "error: %s", lua_tostring(L, -1));
6309 if(!lua_isnumber(L, -1))
6310 throw LuaError(L, "allow_put should return a number");
6311 return luaL_checkinteger(L, -1);
6314 // Return number of accepted items to be taken
6315 int scriptapi_detached_inventory_allow_take(lua_State *L,
6316 const std::string &name,
6317 const std::string &listname, int index, ItemStack &stack,
6318 ServerActiveObject *player)
6321 assert(lua_checkstack(L, 20));
6322 StackUnroller stack_unroller(L);
6324 // Push callback function on stack
6325 if(!get_detached_inventory_callback(L, name, "allow_take"))
6326 return stack.count; // All will be accepted
6328 // Call function(inv, listname, index, stack, player)
6330 InventoryLocation loc;
6331 loc.setDetached(name);
6332 InvRef::create(L, loc);
6334 lua_pushstring(L, listname.c_str());
6336 lua_pushinteger(L, index + 1);
6338 LuaItemStack::create(L, stack);
6340 objectref_get_or_create(L, player);
6341 if(lua_pcall(L, 5, 1, 0))
6342 script_error(L, "error: %s", lua_tostring(L, -1));
6343 if(!lua_isnumber(L, -1))
6344 throw LuaError(L, "allow_take should return a number");
6345 return luaL_checkinteger(L, -1);
6348 // Report moved items
6349 void scriptapi_detached_inventory_on_move(lua_State *L,
6350 const std::string &name,
6351 const std::string &from_list, int from_index,
6352 const std::string &to_list, int to_index,
6353 int count, ServerActiveObject *player)
6356 assert(lua_checkstack(L, 20));
6357 StackUnroller stack_unroller(L);
6359 // Push callback function on stack
6360 if(!get_detached_inventory_callback(L, name, "on_move"))
6363 // function(inv, from_list, from_index, to_list, to_index, count, player)
6365 InventoryLocation loc;
6366 loc.setDetached(name);
6367 InvRef::create(L, loc);
6369 lua_pushstring(L, from_list.c_str());
6371 lua_pushinteger(L, from_index + 1);
6373 lua_pushstring(L, to_list.c_str());
6375 lua_pushinteger(L, to_index + 1);
6377 lua_pushinteger(L, count);
6379 objectref_get_or_create(L, player);
6380 if(lua_pcall(L, 7, 0, 0))
6381 script_error(L, "error: %s", lua_tostring(L, -1));
6385 void scriptapi_detached_inventory_on_put(lua_State *L,
6386 const std::string &name,
6387 const std::string &listname, int index, ItemStack &stack,
6388 ServerActiveObject *player)
6391 assert(lua_checkstack(L, 20));
6392 StackUnroller stack_unroller(L);
6394 // Push callback function on stack
6395 if(!get_detached_inventory_callback(L, name, "on_put"))
6398 // Call function(inv, listname, index, stack, player)
6400 InventoryLocation loc;
6401 loc.setDetached(name);
6402 InvRef::create(L, loc);
6404 lua_pushstring(L, listname.c_str());
6406 lua_pushinteger(L, index + 1);
6408 LuaItemStack::create(L, stack);
6410 objectref_get_or_create(L, player);
6411 if(lua_pcall(L, 5, 0, 0))
6412 script_error(L, "error: %s", lua_tostring(L, -1));
6415 // Report taken items
6416 void scriptapi_detached_inventory_on_take(lua_State *L,
6417 const std::string &name,
6418 const std::string &listname, int index, ItemStack &stack,
6419 ServerActiveObject *player)
6422 assert(lua_checkstack(L, 20));
6423 StackUnroller stack_unroller(L);
6425 // Push callback function on stack
6426 if(!get_detached_inventory_callback(L, name, "on_take"))
6429 // Call function(inv, listname, index, stack, player)
6431 InventoryLocation loc;
6432 loc.setDetached(name);
6433 InvRef::create(L, loc);
6435 lua_pushstring(L, listname.c_str());
6437 lua_pushinteger(L, index + 1);
6439 LuaItemStack::create(L, stack);
6441 objectref_get_or_create(L, player);
6442 if(lua_pcall(L, 5, 0, 0))
6443 script_error(L, "error: %s", lua_tostring(L, -1));
6450 void scriptapi_environment_step(lua_State *L, float dtime)
6453 assert(lua_checkstack(L, 20));
6454 //infostream<<"scriptapi_environment_step"<<std::endl;
6455 StackUnroller stack_unroller(L);
6457 // Get minetest.registered_globalsteps
6458 lua_getglobal(L, "minetest");
6459 lua_getfield(L, -1, "registered_globalsteps");
6461 lua_pushnumber(L, dtime);
6462 scriptapi_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
6465 void scriptapi_environment_on_generated(lua_State *L, v3s16 minp, v3s16 maxp,
6469 assert(lua_checkstack(L, 20));
6470 //infostream<<"scriptapi_environment_on_generated"<<std::endl;
6471 StackUnroller stack_unroller(L);
6473 // Get minetest.registered_on_generateds
6474 lua_getglobal(L, "minetest");
6475 lua_getfield(L, -1, "registered_on_generateds");
6477 push_v3s16(L, minp);
6478 push_v3s16(L, maxp);
6479 lua_pushnumber(L, blockseed);
6480 scriptapi_run_callbacks(L, 3, RUN_CALLBACKS_MODE_FIRST);
6487 bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name)
6490 assert(lua_checkstack(L, 20));
6491 verbosestream<<"scriptapi_luaentity_add: id="<<id<<" name=\""
6492 <<name<<"\""<<std::endl;
6493 StackUnroller stack_unroller(L);
6495 // Get minetest.registered_entities[name]
6496 lua_getglobal(L, "minetest");
6497 lua_getfield(L, -1, "registered_entities");
6498 luaL_checktype(L, -1, LUA_TTABLE);
6499 lua_pushstring(L, name);
6500 lua_gettable(L, -2);
6501 // Should be a table, which we will use as a prototype
6502 //luaL_checktype(L, -1, LUA_TTABLE);
6503 if(lua_type(L, -1) != LUA_TTABLE){
6504 errorstream<<"LuaEntity name \""<<name<<"\" not defined"<<std::endl;
6507 int prototype_table = lua_gettop(L);
6508 //dump2(L, "prototype_table");
6510 // Create entity object
6512 int object = lua_gettop(L);
6514 // Set object metatable
6515 lua_pushvalue(L, prototype_table);
6516 lua_setmetatable(L, -2);
6518 // Add object reference
6519 // This should be userdata with metatable ObjectRef
6520 objectref_get(L, id);
6521 luaL_checktype(L, -1, LUA_TUSERDATA);
6522 if(!luaL_checkudata(L, -1, "ObjectRef"))
6523 luaL_typerror(L, -1, "ObjectRef");
6524 lua_setfield(L, -2, "object");
6526 // minetest.luaentities[id] = object
6527 lua_getglobal(L, "minetest");
6528 lua_getfield(L, -1, "luaentities");
6529 luaL_checktype(L, -1, LUA_TTABLE);
6530 lua_pushnumber(L, id); // Push id
6531 lua_pushvalue(L, object); // Copy object to top of stack
6532 lua_settable(L, -3);
6537 void scriptapi_luaentity_activate(lua_State *L, u16 id,
6538 const std::string &staticdata, u32 dtime_s)
6541 assert(lua_checkstack(L, 20));
6542 verbosestream<<"scriptapi_luaentity_activate: id="<<id<<std::endl;
6543 StackUnroller stack_unroller(L);
6545 // Get minetest.luaentities[id]
6546 luaentity_get(L, id);
6547 int object = lua_gettop(L);
6549 // Get on_activate function
6550 lua_pushvalue(L, object);
6551 lua_getfield(L, -1, "on_activate");
6552 if(!lua_isnil(L, -1)){
6553 luaL_checktype(L, -1, LUA_TFUNCTION);
6554 lua_pushvalue(L, object); // self
6555 lua_pushlstring(L, staticdata.c_str(), staticdata.size());
6556 lua_pushinteger(L, dtime_s);
6557 // Call with 3 arguments, 0 results
6558 if(lua_pcall(L, 3, 0, 0))
6559 script_error(L, "error running function on_activate: %s\n",
6560 lua_tostring(L, -1));
6564 void scriptapi_luaentity_rm(lua_State *L, u16 id)
6567 assert(lua_checkstack(L, 20));
6568 verbosestream<<"scriptapi_luaentity_rm: id="<<id<<std::endl;
6570 // Get minetest.luaentities table
6571 lua_getglobal(L, "minetest");
6572 lua_getfield(L, -1, "luaentities");
6573 luaL_checktype(L, -1, LUA_TTABLE);
6574 int objectstable = lua_gettop(L);
6576 // Set luaentities[id] = nil
6577 lua_pushnumber(L, id); // Push id
6579 lua_settable(L, objectstable);
6581 lua_pop(L, 2); // pop luaentities, minetest
6584 std::string scriptapi_luaentity_get_staticdata(lua_State *L, u16 id)
6587 assert(lua_checkstack(L, 20));
6588 //infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl;
6589 StackUnroller stack_unroller(L);
6591 // Get minetest.luaentities[id]
6592 luaentity_get(L, id);
6593 int object = lua_gettop(L);
6595 // Get get_staticdata function
6596 lua_pushvalue(L, object);
6597 lua_getfield(L, -1, "get_staticdata");
6598 if(lua_isnil(L, -1))
6601 luaL_checktype(L, -1, LUA_TFUNCTION);
6602 lua_pushvalue(L, object); // self
6603 // Call with 1 arguments, 1 results
6604 if(lua_pcall(L, 1, 1, 0))
6605 script_error(L, "error running function get_staticdata: %s\n",
6606 lua_tostring(L, -1));
6609 const char *s = lua_tolstring(L, -1, &len);
6610 return std::string(s, len);
6613 void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
6614 ObjectProperties *prop)
6617 assert(lua_checkstack(L, 20));
6618 //infostream<<"scriptapi_luaentity_get_properties: id="<<id<<std::endl;
6619 StackUnroller stack_unroller(L);
6621 // Get minetest.luaentities[id]
6622 luaentity_get(L, id);
6623 //int object = lua_gettop(L);
6625 // Set default values that differ from ObjectProperties defaults
6630 prop->hp_max = getintfield_default(L, -1, "hp_max", 10);
6632 getboolfield(L, -1, "physical", prop->physical);
6634 getfloatfield(L, -1, "weight", prop->weight);
6636 lua_getfield(L, -1, "collisionbox");
6637 if(lua_istable(L, -1))
6638 prop->collisionbox = read_aabb3f(L, -1, 1.0);
6641 getstringfield(L, -1, "visual", prop->visual);
6643 getstringfield(L, -1, "mesh", prop->mesh);
6645 // Deprecated: read object properties directly
6646 read_object_properties(L, -1, prop);
6648 // Read initial_properties
6649 lua_getfield(L, -1, "initial_properties");
6650 read_object_properties(L, -1, prop);
6654 void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime)
6657 assert(lua_checkstack(L, 20));
6658 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
6659 StackUnroller stack_unroller(L);
6661 // Get minetest.luaentities[id]
6662 luaentity_get(L, id);
6663 int object = lua_gettop(L);
6664 // State: object is at top of stack
6665 // Get step function
6666 lua_getfield(L, -1, "on_step");
6667 if(lua_isnil(L, -1))
6669 luaL_checktype(L, -1, LUA_TFUNCTION);
6670 lua_pushvalue(L, object); // self
6671 lua_pushnumber(L, dtime); // dtime
6672 // Call with 2 arguments, 0 results
6673 if(lua_pcall(L, 2, 0, 0))
6674 script_error(L, "error running function 'on_step': %s\n", lua_tostring(L, -1));
6677 // Calls entity:on_punch(ObjectRef puncher, time_from_last_punch,
6678 // tool_capabilities, direction)
6679 void scriptapi_luaentity_punch(lua_State *L, u16 id,
6680 ServerActiveObject *puncher, float time_from_last_punch,
6681 const ToolCapabilities *toolcap, v3f dir)
6684 assert(lua_checkstack(L, 20));
6685 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
6686 StackUnroller stack_unroller(L);
6688 // Get minetest.luaentities[id]
6689 luaentity_get(L, id);
6690 int object = lua_gettop(L);
6691 // State: object is at top of stack
6693 lua_getfield(L, -1, "on_punch");
6694 if(lua_isnil(L, -1))
6696 luaL_checktype(L, -1, LUA_TFUNCTION);
6697 lua_pushvalue(L, object); // self
6698 objectref_get_or_create(L, puncher); // Clicker reference
6699 lua_pushnumber(L, time_from_last_punch);
6700 push_tool_capabilities(L, *toolcap);
6702 // Call with 5 arguments, 0 results
6703 if(lua_pcall(L, 5, 0, 0))
6704 script_error(L, "error running function 'on_punch': %s\n", lua_tostring(L, -1));
6707 // Calls entity:on_rightclick(ObjectRef clicker)
6708 void scriptapi_luaentity_rightclick(lua_State *L, u16 id,
6709 ServerActiveObject *clicker)
6712 assert(lua_checkstack(L, 20));
6713 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
6714 StackUnroller stack_unroller(L);
6716 // Get minetest.luaentities[id]
6717 luaentity_get(L, id);
6718 int object = lua_gettop(L);
6719 // State: object is at top of stack
6721 lua_getfield(L, -1, "on_rightclick");
6722 if(lua_isnil(L, -1))
6724 luaL_checktype(L, -1, LUA_TFUNCTION);
6725 lua_pushvalue(L, object); // self
6726 objectref_get_or_create(L, clicker); // Clicker reference
6727 // Call with 2 arguments, 0 results
6728 if(lua_pcall(L, 2, 0, 0))
6729 script_error(L, "error running function 'on_rightclick': %s\n", lua_tostring(L, -1));