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"
51 static void stackDump(lua_State *L, std::ostream &o)
54 int top = lua_gettop(L);
55 for (i = 1; i <= top; i++) { /* repeat for each level */
56 int t = lua_type(L, i);
59 case LUA_TSTRING: /* strings */
60 o<<"\""<<lua_tostring(L, i)<<"\"";
63 case LUA_TBOOLEAN: /* booleans */
64 o<<(lua_toboolean(L, i) ? "true" : "false");
67 case LUA_TNUMBER: /* numbers */ {
69 snprintf(buf, 10, "%g", lua_tonumber(L, i));
73 default: /* other values */
74 o<<lua_typename(L, t);
83 static void realitycheck(lua_State *L)
85 int top = lua_gettop(L);
87 dstream<<"Stack is over 30:"<<std::endl;
88 stackDump(L, dstream);
89 script_error(L, "Stack is over 30 (reality check)");
99 StackUnroller(lua_State *L):
103 m_original_top = lua_gettop(m_lua); // store stack height
107 lua_settop(m_lua, m_original_top); // restore stack height
116 ModNameStorer(lua_State *L_, const std::string modname):
119 // Store current modname in registry
120 lua_pushstring(L, modname.c_str());
121 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
125 // Clear current modname in registry
127 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
132 Getters for stuff in main tables
135 static Server* get_server(lua_State *L)
137 // Get server from registry
138 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
139 Server *server = (Server*)lua_touserdata(L, -1);
144 static ServerEnvironment* get_env(lua_State *L)
146 // Get environment from registry
147 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_env");
148 ServerEnvironment *env = (ServerEnvironment*)lua_touserdata(L, -1);
153 static void objectref_get(lua_State *L, u16 id)
155 // Get minetest.object_refs[i]
156 lua_getglobal(L, "minetest");
157 lua_getfield(L, -1, "object_refs");
158 luaL_checktype(L, -1, LUA_TTABLE);
159 lua_pushnumber(L, id);
161 lua_remove(L, -2); // object_refs
162 lua_remove(L, -2); // minetest
165 static void luaentity_get(lua_State *L, u16 id)
167 // Get minetest.luaentities[i]
168 lua_getglobal(L, "minetest");
169 lua_getfield(L, -1, "luaentities");
170 luaL_checktype(L, -1, LUA_TTABLE);
171 lua_pushnumber(L, id);
173 lua_remove(L, -2); // luaentities
174 lua_remove(L, -2); // minetest
181 static bool getstringfield(lua_State *L, int table,
182 const char *fieldname, std::string &result)
184 lua_getfield(L, table, fieldname);
186 if(lua_isstring(L, -1)){
188 const char *ptr = lua_tolstring(L, -1, &len);
189 result.assign(ptr, len);
196 static bool getintfield(lua_State *L, int table,
197 const char *fieldname, int &result)
199 lua_getfield(L, table, fieldname);
201 if(lua_isnumber(L, -1)){
202 result = lua_tonumber(L, -1);
209 static bool getfloatfield(lua_State *L, int table,
210 const char *fieldname, float &result)
212 lua_getfield(L, table, fieldname);
214 if(lua_isnumber(L, -1)){
215 result = lua_tonumber(L, -1);
222 static bool getboolfield(lua_State *L, int table,
223 const char *fieldname, bool &result)
225 lua_getfield(L, table, fieldname);
227 if(lua_isboolean(L, -1)){
228 result = lua_toboolean(L, -1);
235 static std::string checkstringfield(lua_State *L, int table,
236 const char *fieldname)
238 lua_getfield(L, table, fieldname);
239 std::string s = luaL_checkstring(L, -1);
244 static std::string getstringfield_default(lua_State *L, int table,
245 const char *fieldname, const std::string &default_)
247 std::string result = default_;
248 getstringfield(L, table, fieldname, result);
252 static int getintfield_default(lua_State *L, int table,
253 const char *fieldname, int default_)
255 int result = default_;
256 getintfield(L, table, fieldname, result);
260 static float getfloatfield_default(lua_State *L, int table,
261 const char *fieldname, float default_)
263 float result = default_;
264 getfloatfield(L, table, fieldname, result);
268 static bool getboolfield_default(lua_State *L, int table,
269 const char *fieldname, bool default_)
271 bool result = default_;
272 getboolfield(L, table, fieldname, result);
282 static bool string_to_enum(const EnumString *spec, int &result,
283 const std::string &str)
285 const EnumString *esp = spec;
287 if(str == std::string(esp->str)){
296 /*static bool enum_to_string(const EnumString *spec, std::string &result,
299 const EnumString *esp = spec;
310 static int getenumfield(lua_State *L, int table,
311 const char *fieldname, const EnumString *spec, int default_)
313 int result = default_;
314 string_to_enum(spec, result,
315 getstringfield_default(L, table, fieldname, ""));
319 static void setintfield(lua_State *L, int table,
320 const char *fieldname, int value)
322 lua_pushinteger(L, value);
325 lua_setfield(L, table, fieldname);
328 static void setfloatfield(lua_State *L, int table,
329 const char *fieldname, float value)
331 lua_pushnumber(L, value);
334 lua_setfield(L, table, fieldname);
337 static void setboolfield(lua_State *L, int table,
338 const char *fieldname, bool value)
340 lua_pushboolean(L, value);
343 lua_setfield(L, table, fieldname);
346 static void warn_if_field_exists(lua_State *L, int table,
347 const char *fieldname, const std::string &message)
349 lua_getfield(L, table, fieldname);
350 if(!lua_isnil(L, -1)){
351 infostream<<script_get_backtrace(L)<<std::endl;
352 infostream<<"WARNING: field \""<<fieldname<<"\": "
353 <<message<<std::endl;
359 EnumString definitions
362 struct EnumString es_ItemType[] =
366 {ITEM_CRAFT, "craft"},
371 struct EnumString es_DrawType[] =
373 {NDT_NORMAL, "normal"},
374 {NDT_AIRLIKE, "airlike"},
375 {NDT_LIQUID, "liquid"},
376 {NDT_FLOWINGLIQUID, "flowingliquid"},
377 {NDT_GLASSLIKE, "glasslike"},
378 {NDT_ALLFACES, "allfaces"},
379 {NDT_ALLFACES_OPTIONAL, "allfaces_optional"},
380 {NDT_TORCHLIKE, "torchlike"},
381 {NDT_SIGNLIKE, "signlike"},
382 {NDT_PLANTLIKE, "plantlike"},
383 {NDT_FENCELIKE, "fencelike"},
384 {NDT_RAILLIKE, "raillike"},
385 {NDT_NODEBOX, "nodebox"},
389 struct EnumString es_ContentParamType[] =
392 {CPT_LIGHT, "light"},
396 struct EnumString es_ContentParamType2[] =
400 {CPT2_FLOWINGLIQUID, "flowingliquid"},
401 {CPT2_FACEDIR, "facedir"},
402 {CPT2_WALLMOUNTED, "wallmounted"},
406 struct EnumString es_LiquidType[] =
408 {LIQUID_NONE, "none"},
409 {LIQUID_FLOWING, "flowing"},
410 {LIQUID_SOURCE, "source"},
414 struct EnumString es_NodeBoxType[] =
416 {NODEBOX_REGULAR, "regular"},
417 {NODEBOX_FIXED, "fixed"},
418 {NODEBOX_WALLMOUNTED, "wallmounted"},
422 struct EnumString es_CraftMethod[] =
424 {CRAFT_METHOD_NORMAL, "normal"},
425 {CRAFT_METHOD_COOKING, "cooking"},
426 {CRAFT_METHOD_FUEL, "fuel"},
430 struct EnumString es_TileAnimationType[] =
433 {TAT_VERTICAL_FRAMES, "vertical_frames"},
438 C struct <-> Lua table converter functions
441 static void push_v3f(lua_State *L, v3f p)
444 lua_pushnumber(L, p.X);
445 lua_setfield(L, -2, "x");
446 lua_pushnumber(L, p.Y);
447 lua_setfield(L, -2, "y");
448 lua_pushnumber(L, p.Z);
449 lua_setfield(L, -2, "z");
452 static v2s16 read_v2s16(lua_State *L, int index)
455 luaL_checktype(L, index, LUA_TTABLE);
456 lua_getfield(L, index, "x");
457 p.X = lua_tonumber(L, -1);
459 lua_getfield(L, index, "y");
460 p.Y = lua_tonumber(L, -1);
465 static v2f read_v2f(lua_State *L, int index)
468 luaL_checktype(L, index, LUA_TTABLE);
469 lua_getfield(L, index, "x");
470 p.X = lua_tonumber(L, -1);
472 lua_getfield(L, index, "y");
473 p.Y = lua_tonumber(L, -1);
478 static v3f read_v3f(lua_State *L, int index)
481 luaL_checktype(L, index, LUA_TTABLE);
482 lua_getfield(L, index, "x");
483 pos.X = lua_tonumber(L, -1);
485 lua_getfield(L, index, "y");
486 pos.Y = lua_tonumber(L, -1);
488 lua_getfield(L, index, "z");
489 pos.Z = lua_tonumber(L, -1);
494 static v3f check_v3f(lua_State *L, int index)
497 luaL_checktype(L, index, LUA_TTABLE);
498 lua_getfield(L, index, "x");
499 pos.X = luaL_checknumber(L, -1);
501 lua_getfield(L, index, "y");
502 pos.Y = luaL_checknumber(L, -1);
504 lua_getfield(L, index, "z");
505 pos.Z = luaL_checknumber(L, -1);
510 static void pushFloatPos(lua_State *L, v3f p)
516 static v3f checkFloatPos(lua_State *L, int index)
518 return check_v3f(L, index) * BS;
521 static void push_v3s16(lua_State *L, v3s16 p)
524 lua_pushnumber(L, p.X);
525 lua_setfield(L, -2, "x");
526 lua_pushnumber(L, p.Y);
527 lua_setfield(L, -2, "y");
528 lua_pushnumber(L, p.Z);
529 lua_setfield(L, -2, "z");
532 static v3s16 read_v3s16(lua_State *L, int index)
534 // Correct rounding at <0
535 v3f pf = read_v3f(L, index);
536 return floatToInt(pf, 1.0);
539 static v3s16 check_v3s16(lua_State *L, int index)
541 // Correct rounding at <0
542 v3f pf = check_v3f(L, index);
543 return floatToInt(pf, 1.0);
546 static void pushnode(lua_State *L, const MapNode &n, INodeDefManager *ndef)
549 lua_pushstring(L, ndef->get(n).name.c_str());
550 lua_setfield(L, -2, "name");
551 lua_pushnumber(L, n.getParam1());
552 lua_setfield(L, -2, "param1");
553 lua_pushnumber(L, n.getParam2());
554 lua_setfield(L, -2, "param2");
557 static MapNode readnode(lua_State *L, int index, INodeDefManager *ndef)
559 lua_getfield(L, index, "name");
560 const char *name = luaL_checkstring(L, -1);
563 lua_getfield(L, index, "param1");
567 param1 = lua_tonumber(L, -1);
570 lua_getfield(L, index, "param2");
574 param2 = lua_tonumber(L, -1);
576 return MapNode(ndef, name, param1, param2);
579 static video::SColor readARGB8(lua_State *L, int index)
582 luaL_checktype(L, index, LUA_TTABLE);
583 lua_getfield(L, index, "a");
584 if(lua_isnumber(L, -1))
585 color.setAlpha(lua_tonumber(L, -1));
587 lua_getfield(L, index, "r");
588 color.setRed(lua_tonumber(L, -1));
590 lua_getfield(L, index, "g");
591 color.setGreen(lua_tonumber(L, -1));
593 lua_getfield(L, index, "b");
594 color.setBlue(lua_tonumber(L, -1));
599 static aabb3f read_aabb3f(lua_State *L, int index, f32 scale)
602 if(lua_istable(L, index)){
603 lua_rawgeti(L, index, 1);
604 box.MinEdge.X = lua_tonumber(L, -1) * scale;
606 lua_rawgeti(L, index, 2);
607 box.MinEdge.Y = lua_tonumber(L, -1) * scale;
609 lua_rawgeti(L, index, 3);
610 box.MinEdge.Z = lua_tonumber(L, -1) * scale;
612 lua_rawgeti(L, index, 4);
613 box.MaxEdge.X = lua_tonumber(L, -1) * scale;
615 lua_rawgeti(L, index, 5);
616 box.MaxEdge.Y = lua_tonumber(L, -1) * scale;
618 lua_rawgeti(L, index, 6);
619 box.MaxEdge.Z = lua_tonumber(L, -1) * scale;
625 static std::vector<aabb3f> read_aabb3f_vector(lua_State *L, int index, f32 scale)
627 std::vector<aabb3f> boxes;
628 if(lua_istable(L, index)){
629 int n = lua_objlen(L, index);
630 // Check if it's a single box or a list of boxes
631 bool possibly_single_box = (n == 6);
632 for(int i = 1; i <= n && possibly_single_box; i++){
633 lua_rawgeti(L, index, i);
634 if(!lua_isnumber(L, -1))
635 possibly_single_box = false;
638 if(possibly_single_box){
640 boxes.push_back(read_aabb3f(L, index, scale));
642 // Read a list of boxes
643 for(int i = 1; i <= n; i++){
644 lua_rawgeti(L, index, i);
645 boxes.push_back(read_aabb3f(L, -1, scale));
653 static NodeBox read_nodebox(lua_State *L, int index)
656 if(lua_istable(L, -1)){
657 nodebox.type = (NodeBoxType)getenumfield(L, index, "type",
658 es_NodeBoxType, NODEBOX_REGULAR);
660 lua_getfield(L, index, "fixed");
661 if(lua_istable(L, -1))
662 nodebox.fixed = read_aabb3f_vector(L, -1, BS);
665 lua_getfield(L, index, "wall_top");
666 if(lua_istable(L, -1))
667 nodebox.wall_top = read_aabb3f(L, -1, BS);
670 lua_getfield(L, index, "wall_bottom");
671 if(lua_istable(L, -1))
672 nodebox.wall_bottom = read_aabb3f(L, -1, BS);
675 lua_getfield(L, index, "wall_side");
676 if(lua_istable(L, -1))
677 nodebox.wall_side = read_aabb3f(L, -1, BS);
686 static void read_groups(lua_State *L, int index,
687 std::map<std::string, int> &result)
689 if (!lua_istable(L,index))
695 while(lua_next(L, index) != 0){
696 // key at index -2 and value at index -1
697 std::string name = luaL_checkstring(L, -2);
698 int rating = luaL_checkinteger(L, -1);
699 result[name] = rating;
700 // removes value, keeps key for next iteration
708 static void read_privileges(lua_State *L, int index,
709 std::set<std::string> &result)
715 while(lua_next(L, index) != 0){
716 // key at index -2 and value at index -1
717 std::string key = luaL_checkstring(L, -2);
718 bool value = lua_toboolean(L, -1);
721 // removes value, keeps key for next iteration
730 static ToolCapabilities read_tool_capabilities(
731 lua_State *L, int table)
733 ToolCapabilities toolcap;
734 getfloatfield(L, table, "full_punch_interval", toolcap.full_punch_interval);
735 getintfield(L, table, "max_drop_level", toolcap.max_drop_level);
736 lua_getfield(L, table, "groupcaps");
737 if(lua_istable(L, -1)){
738 int table_groupcaps = lua_gettop(L);
740 while(lua_next(L, table_groupcaps) != 0){
741 // key at index -2 and value at index -1
742 std::string groupname = luaL_checkstring(L, -2);
743 if(lua_istable(L, -1)){
744 int table_groupcap = lua_gettop(L);
745 // This will be created
746 ToolGroupCap groupcap;
747 // Read simple parameters
748 getintfield(L, table_groupcap, "maxlevel", groupcap.maxlevel);
749 getintfield(L, table_groupcap, "uses", groupcap.uses);
750 // DEPRECATED: maxwear
752 if(getfloatfield(L, table_groupcap, "maxwear", maxwear)){
754 groupcap.uses = 1.0/maxwear;
757 infostream<<script_get_backtrace(L)<<std::endl;
758 infostream<<"WARNING: field \"maxwear\" is deprecated; "
759 <<"should replace with uses=1/maxwear"<<std::endl;
761 // Read "times" table
762 lua_getfield(L, table_groupcap, "times");
763 if(lua_istable(L, -1)){
764 int table_times = lua_gettop(L);
766 while(lua_next(L, table_times) != 0){
767 // key at index -2 and value at index -1
768 int rating = luaL_checkinteger(L, -2);
769 float time = luaL_checknumber(L, -1);
770 groupcap.times[rating] = time;
771 // removes value, keeps key for next iteration
776 // Insert groupcap into toolcap
777 toolcap.groupcaps[groupname] = groupcap;
779 // removes value, keeps key for next iteration
787 static void set_tool_capabilities(lua_State *L, int table,
788 const ToolCapabilities &toolcap)
790 setfloatfield(L, table, "full_punch_interval", toolcap.full_punch_interval);
791 setintfield(L, table, "max_drop_level", toolcap.max_drop_level);
792 // Create groupcaps table
795 for(std::map<std::string, ToolGroupCap>::const_iterator
796 i = toolcap.groupcaps.begin(); i != toolcap.groupcaps.end(); i++){
797 // Create groupcap table
799 const std::string &name = i->first;
800 const ToolGroupCap &groupcap = i->second;
801 // Create subtable "times"
803 for(std::map<int, float>::const_iterator
804 i = groupcap.times.begin(); i != groupcap.times.end(); i++){
805 int rating = i->first;
806 float time = i->second;
807 lua_pushinteger(L, rating);
808 lua_pushnumber(L, time);
811 // Set subtable "times"
812 lua_setfield(L, -2, "times");
813 // Set simple parameters
814 setintfield(L, -1, "maxlevel", groupcap.maxlevel);
815 setintfield(L, -1, "uses", groupcap.uses);
816 // Insert groupcap table into groupcaps table
817 lua_setfield(L, -2, name.c_str());
819 // Set groupcaps table
820 lua_setfield(L, -2, "groupcaps");
823 static void push_tool_capabilities(lua_State *L,
824 const ToolCapabilities &prop)
827 set_tool_capabilities(L, -1, prop);
834 static void set_dig_params(lua_State *L, int table,
835 const DigParams ¶ms)
837 setboolfield(L, table, "diggable", params.diggable);
838 setfloatfield(L, table, "time", params.time);
839 setintfield(L, table, "wear", params.wear);
842 static void push_dig_params(lua_State *L,
843 const DigParams ¶ms)
846 set_dig_params(L, -1, params);
853 static void set_hit_params(lua_State *L, int table,
854 const HitParams ¶ms)
856 setintfield(L, table, "hp", params.hp);
857 setintfield(L, table, "wear", params.wear);
860 static void push_hit_params(lua_State *L,
861 const HitParams ¶ms)
864 set_hit_params(L, -1, params);
871 static void push_pointed_thing(lua_State *L, const PointedThing& pointed)
874 if(pointed.type == POINTEDTHING_NODE)
876 lua_pushstring(L, "node");
877 lua_setfield(L, -2, "type");
878 push_v3s16(L, pointed.node_undersurface);
879 lua_setfield(L, -2, "under");
880 push_v3s16(L, pointed.node_abovesurface);
881 lua_setfield(L, -2, "above");
883 else if(pointed.type == POINTEDTHING_OBJECT)
885 lua_pushstring(L, "object");
886 lua_setfield(L, -2, "type");
887 objectref_get(L, pointed.object_id);
888 lua_setfield(L, -2, "ref");
892 lua_pushstring(L, "nothing");
893 lua_setfield(L, -2, "type");
901 static void read_soundspec(lua_State *L, int index, SimpleSoundSpec &spec)
904 index = lua_gettop(L) + 1 + index;
905 if(lua_isnil(L, index)){
906 } else if(lua_istable(L, index)){
907 getstringfield(L, index, "name", spec.name);
908 getfloatfield(L, index, "gain", spec.gain);
909 } else if(lua_isstring(L, index)){
910 spec.name = lua_tostring(L, index);
918 static void read_object_properties(lua_State *L, int index,
919 ObjectProperties *prop)
922 index = lua_gettop(L) + 1 + index;
923 if(!lua_istable(L, index))
926 prop->hp_max = getintfield_default(L, -1, "hp_max", 10);
928 getboolfield(L, -1, "physical", prop->physical);
930 getfloatfield(L, -1, "weight", prop->weight);
932 lua_getfield(L, -1, "collisionbox");
933 if(lua_istable(L, -1))
934 prop->collisionbox = read_aabb3f(L, -1, 1.0);
937 getstringfield(L, -1, "visual", prop->visual);
939 lua_getfield(L, -1, "visual_size");
940 if(lua_istable(L, -1))
941 prop->visual_size = read_v2f(L, -1);
944 lua_getfield(L, -1, "textures");
945 if(lua_istable(L, -1)){
946 prop->textures.clear();
947 int table = lua_gettop(L);
949 while(lua_next(L, table) != 0){
950 // key at index -2 and value at index -1
951 if(lua_isstring(L, -1))
952 prop->textures.push_back(lua_tostring(L, -1));
954 prop->textures.push_back("");
955 // removes value, keeps key for next iteration
961 lua_getfield(L, -1, "spritediv");
962 if(lua_istable(L, -1))
963 prop->spritediv = read_v2s16(L, -1);
966 lua_getfield(L, -1, "initial_sprite_basepos");
967 if(lua_istable(L, -1))
968 prop->initial_sprite_basepos = read_v2s16(L, -1);
971 getboolfield(L, -1, "is_visible", prop->is_visible);
972 getboolfield(L, -1, "makes_footstep_sound", prop->makes_footstep_sound);
973 getfloatfield(L, -1, "automatic_rotate", prop->automatic_rotate);
980 static ItemDefinition read_item_definition(lua_State *L, int index,
981 ItemDefinition default_def = ItemDefinition())
984 index = lua_gettop(L) + 1 + index;
986 // Read the item definition
987 ItemDefinition def = default_def;
989 def.type = (ItemType)getenumfield(L, index, "type",
990 es_ItemType, ITEM_NONE);
991 getstringfield(L, index, "name", def.name);
992 getstringfield(L, index, "description", def.description);
993 getstringfield(L, index, "inventory_image", def.inventory_image);
994 getstringfield(L, index, "wield_image", def.wield_image);
996 lua_getfield(L, index, "wield_scale");
997 if(lua_istable(L, -1)){
998 def.wield_scale = check_v3f(L, -1);
1002 def.stack_max = getintfield_default(L, index, "stack_max", def.stack_max);
1003 if(def.stack_max == 0)
1006 lua_getfield(L, index, "on_use");
1007 def.usable = lua_isfunction(L, -1);
1010 getboolfield(L, index, "liquids_pointable", def.liquids_pointable);
1012 warn_if_field_exists(L, index, "tool_digging_properties",
1013 "deprecated: use tool_capabilities");
1015 lua_getfield(L, index, "tool_capabilities");
1016 if(lua_istable(L, -1)){
1017 def.tool_capabilities = new ToolCapabilities(
1018 read_tool_capabilities(L, -1));
1021 // If name is "" (hand), ensure there are ToolCapabilities
1022 // because it will be looked up there whenever any other item has
1023 // no ToolCapabilities
1024 if(def.name == "" && def.tool_capabilities == NULL){
1025 def.tool_capabilities = new ToolCapabilities();
1028 lua_getfield(L, index, "groups");
1029 read_groups(L, -1, def.groups);
1032 // Client shall immediately place this node when player places the item.
1033 // Server will update the precise end result a moment later.
1034 // "" = no prediction
1035 getstringfield(L, index, "node_placement_prediction",
1036 def.node_placement_prediction);
1045 static TileDef read_tiledef(lua_State *L, int index)
1048 index = lua_gettop(L) + 1 + index;
1052 // key at index -2 and value at index
1053 if(lua_isstring(L, index)){
1054 // "default_lava.png"
1055 tiledef.name = lua_tostring(L, index);
1057 else if(lua_istable(L, index))
1059 // {name="default_lava.png", animation={}}
1061 getstringfield(L, index, "name", tiledef.name);
1062 getstringfield(L, index, "image", tiledef.name); // MaterialSpec compat.
1063 tiledef.backface_culling = getboolfield_default(
1064 L, index, "backface_culling", true);
1066 lua_getfield(L, index, "animation");
1067 if(lua_istable(L, -1)){
1068 // {type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}
1069 tiledef.animation.type = (TileAnimationType)
1070 getenumfield(L, -1, "type", es_TileAnimationType,
1072 tiledef.animation.aspect_w =
1073 getintfield_default(L, -1, "aspect_w", 16);
1074 tiledef.animation.aspect_h =
1075 getintfield_default(L, -1, "aspect_h", 16);
1076 tiledef.animation.length =
1077 getfloatfield_default(L, -1, "length", 1.0);
1089 static ContentFeatures read_content_features(lua_State *L, int index)
1092 index = lua_gettop(L) + 1 + index;
1096 /* Cache existence of some callbacks */
1097 lua_getfield(L, index, "on_construct");
1098 if(!lua_isnil(L, -1)) f.has_on_construct = true;
1100 lua_getfield(L, index, "on_destruct");
1101 if(!lua_isnil(L, -1)) f.has_on_destruct = true;
1103 lua_getfield(L, index, "after_destruct");
1104 if(!lua_isnil(L, -1)) f.has_after_destruct = true;
1108 getstringfield(L, index, "name", f.name);
1111 lua_getfield(L, index, "groups");
1112 read_groups(L, -1, f.groups);
1115 /* Visual definition */
1117 f.drawtype = (NodeDrawType)getenumfield(L, index, "drawtype", es_DrawType,
1119 getfloatfield(L, index, "visual_scale", f.visual_scale);
1122 lua_getfield(L, index, "tiles");
1123 // If nil, try the deprecated name "tile_images" instead
1124 if(lua_isnil(L, -1)){
1126 warn_if_field_exists(L, index, "tile_images",
1127 "Deprecated; new name is \"tiles\".");
1128 lua_getfield(L, index, "tile_images");
1130 if(lua_istable(L, -1)){
1131 int table = lua_gettop(L);
1134 while(lua_next(L, table) != 0){
1135 // Read tiledef from value
1136 f.tiledef[i] = read_tiledef(L, -1);
1137 // removes value, keeps key for next iteration
1145 // Copy last value to all remaining textures
1147 TileDef lasttile = f.tiledef[i-1];
1149 f.tiledef[i] = lasttile;
1156 // special_tiles = {}
1157 lua_getfield(L, index, "special_tiles");
1158 // If nil, try the deprecated name "special_materials" instead
1159 if(lua_isnil(L, -1)){
1161 warn_if_field_exists(L, index, "special_materials",
1162 "Deprecated; new name is \"special_tiles\".");
1163 lua_getfield(L, index, "special_materials");
1165 if(lua_istable(L, -1)){
1166 int table = lua_gettop(L);
1169 while(lua_next(L, table) != 0){
1170 // Read tiledef from value
1171 f.tiledef_special[i] = read_tiledef(L, -1);
1172 // removes value, keeps key for next iteration
1183 f.alpha = getintfield_default(L, index, "alpha", 255);
1187 lua_getfield(L, index, "post_effect_color");
1188 if(!lua_isnil(L, -1))
1189 f.post_effect_color = readARGB8(L, -1);
1192 f.param_type = (ContentParamType)getenumfield(L, index, "paramtype",
1193 es_ContentParamType, CPT_NONE);
1194 f.param_type_2 = (ContentParamType2)getenumfield(L, index, "paramtype2",
1195 es_ContentParamType2, CPT2_NONE);
1197 // Warn about some deprecated fields
1198 warn_if_field_exists(L, index, "wall_mounted",
1199 "deprecated: use paramtype2 = 'wallmounted'");
1200 warn_if_field_exists(L, index, "light_propagates",
1201 "deprecated: determined from paramtype");
1202 warn_if_field_exists(L, index, "dug_item",
1203 "deprecated: use 'drop' field");
1204 warn_if_field_exists(L, index, "extra_dug_item",
1205 "deprecated: use 'drop' field");
1206 warn_if_field_exists(L, index, "extra_dug_item_rarity",
1207 "deprecated: use 'drop' field");
1208 warn_if_field_exists(L, index, "metadata_name",
1209 "deprecated: use on_add and metadata callbacks");
1211 // True for all ground-like things like stone and mud, false for eg. trees
1212 getboolfield(L, index, "is_ground_content", f.is_ground_content);
1213 f.light_propagates = (f.param_type == CPT_LIGHT);
1214 getboolfield(L, index, "sunlight_propagates", f.sunlight_propagates);
1215 // This is used for collision detection.
1216 // Also for general solidness queries.
1217 getboolfield(L, index, "walkable", f.walkable);
1218 // Player can point to these
1219 getboolfield(L, index, "pointable", f.pointable);
1220 // Player can dig these
1221 getboolfield(L, index, "diggable", f.diggable);
1222 // Player can climb these
1223 getboolfield(L, index, "climbable", f.climbable);
1224 // Player can build on these
1225 getboolfield(L, index, "buildable_to", f.buildable_to);
1226 // Whether the node is non-liquid, source liquid or flowing liquid
1227 f.liquid_type = (LiquidType)getenumfield(L, index, "liquidtype",
1228 es_LiquidType, LIQUID_NONE);
1229 // If the content is liquid, this is the flowing version of the liquid.
1230 getstringfield(L, index, "liquid_alternative_flowing",
1231 f.liquid_alternative_flowing);
1232 // If the content is liquid, this is the source version of the liquid.
1233 getstringfield(L, index, "liquid_alternative_source",
1234 f.liquid_alternative_source);
1235 // Viscosity for fluid flow, ranging from 1 to 7, with
1236 // 1 giving almost instantaneous propagation and 7 being
1237 // the slowest possible
1238 f.liquid_viscosity = getintfield_default(L, index,
1239 "liquid_viscosity", f.liquid_viscosity);
1240 // Amount of light the node emits
1241 f.light_source = getintfield_default(L, index,
1242 "light_source", f.light_source);
1243 f.damage_per_second = getintfield_default(L, index,
1244 "damage_per_second", f.damage_per_second);
1246 lua_getfield(L, index, "node_box");
1247 if(lua_istable(L, -1))
1248 f.node_box = read_nodebox(L, -1);
1251 lua_getfield(L, index, "selection_box");
1252 if(lua_istable(L, -1))
1253 f.selection_box = read_nodebox(L, -1);
1256 // Set to true if paramtype used to be 'facedir_simple'
1257 getboolfield(L, index, "legacy_facedir_simple", f.legacy_facedir_simple);
1258 // Set to true if wall_mounted used to be set to true
1259 getboolfield(L, index, "legacy_wallmounted", f.legacy_wallmounted);
1262 lua_getfield(L, index, "sounds");
1263 if(lua_istable(L, -1)){
1264 lua_getfield(L, -1, "footstep");
1265 read_soundspec(L, -1, f.sound_footstep);
1267 lua_getfield(L, -1, "dig");
1268 read_soundspec(L, -1, f.sound_dig);
1270 lua_getfield(L, -1, "dug");
1271 read_soundspec(L, -1, f.sound_dug);
1283 static ItemStack read_item(lua_State *L, int index);
1284 static std::vector<ItemStack> read_items(lua_State *L, int index);
1285 // creates a table of ItemStacks
1286 static void push_items(lua_State *L, const std::vector<ItemStack> &items);
1288 static void inventory_set_list_from_lua(Inventory *inv, const char *name,
1289 lua_State *L, int tableindex, int forcesize=-1)
1292 tableindex = lua_gettop(L) + 1 + tableindex;
1293 // If nil, delete list
1294 if(lua_isnil(L, tableindex)){
1295 inv->deleteList(name);
1298 // Otherwise set list
1299 std::vector<ItemStack> items = read_items(L, tableindex);
1300 int listsize = (forcesize != -1) ? forcesize : items.size();
1301 InventoryList *invlist = inv->addList(name, listsize);
1303 for(std::vector<ItemStack>::const_iterator
1304 i = items.begin(); i != items.end(); i++){
1305 if(forcesize != -1 && index == forcesize)
1307 invlist->changeItem(index, *i);
1310 while(forcesize != -1 && index < forcesize){
1311 invlist->deleteItem(index);
1316 static void inventory_get_list_to_lua(Inventory *inv, const char *name,
1319 InventoryList *invlist = inv->getList(name);
1320 if(invlist == NULL){
1324 std::vector<ItemStack> items;
1325 for(u32 i=0; i<invlist->getSize(); i++)
1326 items.push_back(invlist->getItem(i));
1327 push_items(L, items);
1331 Helpful macros for userdata classes
1334 #define method(class, name) {#name, class::l_##name}
1345 static const char className[];
1346 static const luaL_reg methods[];
1348 // Exported functions
1350 // garbage collector
1351 static int gc_object(lua_State *L)
1353 LuaItemStack *o = *(LuaItemStack **)(lua_touserdata(L, 1));
1358 // is_empty(self) -> true/false
1359 static int l_is_empty(lua_State *L)
1361 LuaItemStack *o = checkobject(L, 1);
1362 ItemStack &item = o->m_stack;
1363 lua_pushboolean(L, item.empty());
1367 // get_name(self) -> string
1368 static int l_get_name(lua_State *L)
1370 LuaItemStack *o = checkobject(L, 1);
1371 ItemStack &item = o->m_stack;
1372 lua_pushstring(L, item.name.c_str());
1376 // get_count(self) -> number
1377 static int l_get_count(lua_State *L)
1379 LuaItemStack *o = checkobject(L, 1);
1380 ItemStack &item = o->m_stack;
1381 lua_pushinteger(L, item.count);
1385 // get_wear(self) -> number
1386 static int l_get_wear(lua_State *L)
1388 LuaItemStack *o = checkobject(L, 1);
1389 ItemStack &item = o->m_stack;
1390 lua_pushinteger(L, item.wear);
1394 // get_metadata(self) -> string
1395 static int l_get_metadata(lua_State *L)
1397 LuaItemStack *o = checkobject(L, 1);
1398 ItemStack &item = o->m_stack;
1399 lua_pushlstring(L, item.metadata.c_str(), item.metadata.size());
1403 // clear(self) -> true
1404 static int l_clear(lua_State *L)
1406 LuaItemStack *o = checkobject(L, 1);
1408 lua_pushboolean(L, true);
1412 // replace(self, itemstack or itemstring or table or nil) -> true
1413 static int l_replace(lua_State *L)
1415 LuaItemStack *o = checkobject(L, 1);
1416 o->m_stack = read_item(L, 2);
1417 lua_pushboolean(L, true);
1421 // to_string(self) -> string
1422 static int l_to_string(lua_State *L)
1424 LuaItemStack *o = checkobject(L, 1);
1425 std::string itemstring = o->m_stack.getItemString();
1426 lua_pushstring(L, itemstring.c_str());
1430 // to_table(self) -> table or nil
1431 static int l_to_table(lua_State *L)
1433 LuaItemStack *o = checkobject(L, 1);
1434 const ItemStack &item = o->m_stack;
1442 lua_pushstring(L, item.name.c_str());
1443 lua_setfield(L, -2, "name");
1444 lua_pushinteger(L, item.count);
1445 lua_setfield(L, -2, "count");
1446 lua_pushinteger(L, item.wear);
1447 lua_setfield(L, -2, "wear");
1448 lua_pushlstring(L, item.metadata.c_str(), item.metadata.size());
1449 lua_setfield(L, -2, "metadata");
1454 // get_stack_max(self) -> number
1455 static int l_get_stack_max(lua_State *L)
1457 LuaItemStack *o = checkobject(L, 1);
1458 ItemStack &item = o->m_stack;
1459 lua_pushinteger(L, item.getStackMax(get_server(L)->idef()));
1463 // get_free_space(self) -> number
1464 static int l_get_free_space(lua_State *L)
1466 LuaItemStack *o = checkobject(L, 1);
1467 ItemStack &item = o->m_stack;
1468 lua_pushinteger(L, item.freeSpace(get_server(L)->idef()));
1472 // is_known(self) -> true/false
1473 // Checks if the item is defined.
1474 static int l_is_known(lua_State *L)
1476 LuaItemStack *o = checkobject(L, 1);
1477 ItemStack &item = o->m_stack;
1478 bool is_known = item.isKnown(get_server(L)->idef());
1479 lua_pushboolean(L, is_known);
1483 // get_definition(self) -> table
1484 // Returns the item definition table from minetest.registered_items,
1485 // or a fallback one (name="unknown")
1486 static int l_get_definition(lua_State *L)
1488 LuaItemStack *o = checkobject(L, 1);
1489 ItemStack &item = o->m_stack;
1491 // Get minetest.registered_items[name]
1492 lua_getglobal(L, "minetest");
1493 lua_getfield(L, -1, "registered_items");
1494 luaL_checktype(L, -1, LUA_TTABLE);
1495 lua_getfield(L, -1, item.name.c_str());
1496 if(lua_isnil(L, -1))
1499 lua_getfield(L, -1, "unknown");
1504 // get_tool_capabilities(self) -> table
1505 // Returns the effective tool digging properties.
1506 // Returns those of the hand ("") if this item has none associated.
1507 static int l_get_tool_capabilities(lua_State *L)
1509 LuaItemStack *o = checkobject(L, 1);
1510 ItemStack &item = o->m_stack;
1511 const ToolCapabilities &prop =
1512 item.getToolCapabilities(get_server(L)->idef());
1513 push_tool_capabilities(L, prop);
1517 // add_wear(self, amount) -> true/false
1518 // The range for "amount" is [0,65535]. Wear is only added if the item
1519 // is a tool. Adding wear might destroy the item.
1520 // Returns true if the item is (or was) a tool.
1521 static int l_add_wear(lua_State *L)
1523 LuaItemStack *o = checkobject(L, 1);
1524 ItemStack &item = o->m_stack;
1525 int amount = lua_tointeger(L, 2);
1526 bool result = item.addWear(amount, get_server(L)->idef());
1527 lua_pushboolean(L, result);
1531 // add_item(self, itemstack or itemstring or table or nil) -> itemstack
1532 // Returns leftover item stack
1533 static int l_add_item(lua_State *L)
1535 LuaItemStack *o = checkobject(L, 1);
1536 ItemStack &item = o->m_stack;
1537 ItemStack newitem = read_item(L, 2);
1538 ItemStack leftover = item.addItem(newitem, get_server(L)->idef());
1539 create(L, leftover);
1543 // item_fits(self, itemstack or itemstring or table or nil) -> true/false, itemstack
1544 // First return value is true iff the new item fits fully into the stack
1545 // Second return value is the would-be-left-over item stack
1546 static int l_item_fits(lua_State *L)
1548 LuaItemStack *o = checkobject(L, 1);
1549 ItemStack &item = o->m_stack;
1550 ItemStack newitem = read_item(L, 2);
1552 bool fits = item.itemFits(newitem, &restitem, get_server(L)->idef());
1553 lua_pushboolean(L, fits); // first return value
1554 create(L, restitem); // second return value
1558 // take_item(self, takecount=1) -> itemstack
1559 static int l_take_item(lua_State *L)
1561 LuaItemStack *o = checkobject(L, 1);
1562 ItemStack &item = o->m_stack;
1564 if(!lua_isnone(L, 2))
1565 takecount = luaL_checkinteger(L, 2);
1566 ItemStack taken = item.takeItem(takecount);
1571 // peek_item(self, peekcount=1) -> itemstack
1572 static int l_peek_item(lua_State *L)
1574 LuaItemStack *o = checkobject(L, 1);
1575 ItemStack &item = o->m_stack;
1577 if(!lua_isnone(L, 2))
1578 peekcount = lua_tointeger(L, 2);
1579 ItemStack peekaboo = item.peekItem(peekcount);
1580 create(L, peekaboo);
1585 LuaItemStack(const ItemStack &item):
1594 const ItemStack& getItem() const
1598 ItemStack& getItem()
1603 // LuaItemStack(itemstack or itemstring or table or nil)
1604 // Creates an LuaItemStack and leaves it on top of stack
1605 static int create_object(lua_State *L)
1607 ItemStack item = read_item(L, 1);
1608 LuaItemStack *o = new LuaItemStack(item);
1609 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1610 luaL_getmetatable(L, className);
1611 lua_setmetatable(L, -2);
1614 // Not callable from Lua
1615 static int create(lua_State *L, const ItemStack &item)
1617 LuaItemStack *o = new LuaItemStack(item);
1618 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1619 luaL_getmetatable(L, className);
1620 lua_setmetatable(L, -2);
1624 static LuaItemStack* checkobject(lua_State *L, int narg)
1626 luaL_checktype(L, narg, LUA_TUSERDATA);
1627 void *ud = luaL_checkudata(L, narg, className);
1628 if(!ud) luaL_typerror(L, narg, className);
1629 return *(LuaItemStack**)ud; // unbox pointer
1632 static void Register(lua_State *L)
1635 int methodtable = lua_gettop(L);
1636 luaL_newmetatable(L, className);
1637 int metatable = lua_gettop(L);
1639 lua_pushliteral(L, "__metatable");
1640 lua_pushvalue(L, methodtable);
1641 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
1643 lua_pushliteral(L, "__index");
1644 lua_pushvalue(L, methodtable);
1645 lua_settable(L, metatable);
1647 lua_pushliteral(L, "__gc");
1648 lua_pushcfunction(L, gc_object);
1649 lua_settable(L, metatable);
1651 lua_pop(L, 1); // drop metatable
1653 luaL_openlib(L, 0, methods, 0); // fill methodtable
1654 lua_pop(L, 1); // drop methodtable
1656 // Can be created from Lua (LuaItemStack(itemstack or itemstring or table or nil))
1657 lua_register(L, className, create_object);
1660 const char LuaItemStack::className[] = "ItemStack";
1661 const luaL_reg LuaItemStack::methods[] = {
1662 method(LuaItemStack, is_empty),
1663 method(LuaItemStack, get_name),
1664 method(LuaItemStack, get_count),
1665 method(LuaItemStack, get_wear),
1666 method(LuaItemStack, get_metadata),
1667 method(LuaItemStack, clear),
1668 method(LuaItemStack, replace),
1669 method(LuaItemStack, to_string),
1670 method(LuaItemStack, to_table),
1671 method(LuaItemStack, get_stack_max),
1672 method(LuaItemStack, get_free_space),
1673 method(LuaItemStack, is_known),
1674 method(LuaItemStack, get_definition),
1675 method(LuaItemStack, get_tool_capabilities),
1676 method(LuaItemStack, add_wear),
1677 method(LuaItemStack, add_item),
1678 method(LuaItemStack, item_fits),
1679 method(LuaItemStack, take_item),
1680 method(LuaItemStack, peek_item),
1684 static ItemStack read_item(lua_State *L, int index)
1687 index = lua_gettop(L) + 1 + index;
1689 if(lua_isnil(L, index))
1693 else if(lua_isuserdata(L, index))
1695 // Convert from LuaItemStack
1696 LuaItemStack *o = LuaItemStack::checkobject(L, index);
1697 return o->getItem();
1699 else if(lua_isstring(L, index))
1701 // Convert from itemstring
1702 std::string itemstring = lua_tostring(L, index);
1703 IItemDefManager *idef = get_server(L)->idef();
1707 item.deSerialize(itemstring, idef);
1710 catch(SerializationError &e)
1712 infostream<<"WARNING: unable to create item from itemstring"
1713 <<": "<<itemstring<<std::endl;
1717 else if(lua_istable(L, index))
1719 // Convert from table
1720 IItemDefManager *idef = get_server(L)->idef();
1721 std::string name = getstringfield_default(L, index, "name", "");
1722 int count = getintfield_default(L, index, "count", 1);
1723 int wear = getintfield_default(L, index, "wear", 0);
1724 std::string metadata = getstringfield_default(L, index, "metadata", "");
1725 return ItemStack(name, count, wear, metadata, idef);
1729 throw LuaError(L, "Expecting itemstack, itemstring, table or nil");
1733 static std::vector<ItemStack> read_items(lua_State *L, int index)
1736 index = lua_gettop(L) + 1 + index;
1738 std::vector<ItemStack> items;
1739 luaL_checktype(L, index, LUA_TTABLE);
1741 while(lua_next(L, index) != 0){
1742 // key at index -2 and value at index -1
1743 items.push_back(read_item(L, -1));
1744 // removes value, keeps key for next iteration
1750 // creates a table of ItemStacks
1751 static void push_items(lua_State *L, const std::vector<ItemStack> &items)
1753 // Get the table insert function
1754 lua_getglobal(L, "table");
1755 lua_getfield(L, -1, "insert");
1756 int table_insert = lua_gettop(L);
1757 // Create and fill table
1759 int table = lua_gettop(L);
1760 for(u32 i=0; i<items.size(); i++){
1761 ItemStack item = items[i];
1762 lua_pushvalue(L, table_insert);
1763 lua_pushvalue(L, table);
1764 LuaItemStack::create(L, item);
1765 if(lua_pcall(L, 2, 0, 0))
1766 script_error(L, "error: %s", lua_tostring(L, -1));
1768 lua_remove(L, -2); // Remove table
1769 lua_remove(L, -2); // Remove insert
1779 InventoryLocation m_loc;
1781 static const char className[];
1782 static const luaL_reg methods[];
1784 static InvRef *checkobject(lua_State *L, int narg)
1786 luaL_checktype(L, narg, LUA_TUSERDATA);
1787 void *ud = luaL_checkudata(L, narg, className);
1788 if(!ud) luaL_typerror(L, narg, className);
1789 return *(InvRef**)ud; // unbox pointer
1792 static Inventory* getinv(lua_State *L, InvRef *ref)
1794 return get_server(L)->getInventory(ref->m_loc);
1797 static InventoryList* getlist(lua_State *L, InvRef *ref,
1798 const char *listname)
1800 Inventory *inv = getinv(L, ref);
1803 return inv->getList(listname);
1806 static void reportInventoryChange(lua_State *L, InvRef *ref)
1808 // Inform other things that the inventory has changed
1809 get_server(L)->setInventoryModified(ref->m_loc);
1812 // Exported functions
1814 // garbage collector
1815 static int gc_object(lua_State *L) {
1816 InvRef *o = *(InvRef **)(lua_touserdata(L, 1));
1821 // is_empty(self, listname) -> true/false
1822 static int l_is_empty(lua_State *L)
1824 InvRef *ref = checkobject(L, 1);
1825 const char *listname = luaL_checkstring(L, 2);
1826 InventoryList *list = getlist(L, ref, listname);
1827 if(list && list->getUsedSlots() > 0){
1828 lua_pushboolean(L, false);
1830 lua_pushboolean(L, true);
1835 // get_size(self, listname)
1836 static int l_get_size(lua_State *L)
1838 InvRef *ref = checkobject(L, 1);
1839 const char *listname = luaL_checkstring(L, 2);
1840 InventoryList *list = getlist(L, ref, listname);
1842 lua_pushinteger(L, list->getSize());
1844 lua_pushinteger(L, 0);
1849 // set_size(self, listname, size)
1850 static int l_set_size(lua_State *L)
1852 InvRef *ref = checkobject(L, 1);
1853 const char *listname = luaL_checkstring(L, 2);
1854 int newsize = luaL_checknumber(L, 3);
1855 Inventory *inv = getinv(L, ref);
1857 inv->deleteList(listname);
1858 reportInventoryChange(L, ref);
1861 InventoryList *list = inv->getList(listname);
1863 list->setSize(newsize);
1865 list = inv->addList(listname, newsize);
1867 reportInventoryChange(L, ref);
1871 // get_stack(self, listname, i) -> itemstack
1872 static int l_get_stack(lua_State *L)
1874 InvRef *ref = checkobject(L, 1);
1875 const char *listname = luaL_checkstring(L, 2);
1876 int i = luaL_checknumber(L, 3) - 1;
1877 InventoryList *list = getlist(L, ref, listname);
1879 if(list != NULL && i >= 0 && i < (int) list->getSize())
1880 item = list->getItem(i);
1881 LuaItemStack::create(L, item);
1885 // set_stack(self, listname, i, stack) -> true/false
1886 static int l_set_stack(lua_State *L)
1888 InvRef *ref = checkobject(L, 1);
1889 const char *listname = luaL_checkstring(L, 2);
1890 int i = luaL_checknumber(L, 3) - 1;
1891 ItemStack newitem = read_item(L, 4);
1892 InventoryList *list = getlist(L, ref, listname);
1893 if(list != NULL && i >= 0 && i < (int) list->getSize()){
1894 list->changeItem(i, newitem);
1895 reportInventoryChange(L, ref);
1896 lua_pushboolean(L, true);
1898 lua_pushboolean(L, false);
1903 // get_list(self, listname) -> list or nil
1904 static int l_get_list(lua_State *L)
1906 InvRef *ref = checkobject(L, 1);
1907 const char *listname = luaL_checkstring(L, 2);
1908 Inventory *inv = getinv(L, ref);
1909 inventory_get_list_to_lua(inv, listname, L);
1913 // set_list(self, listname, list)
1914 static int l_set_list(lua_State *L)
1916 InvRef *ref = checkobject(L, 1);
1917 const char *listname = luaL_checkstring(L, 2);
1918 Inventory *inv = getinv(L, ref);
1919 InventoryList *list = inv->getList(listname);
1921 inventory_set_list_from_lua(inv, listname, L, 3,
1924 inventory_set_list_from_lua(inv, listname, L, 3);
1925 reportInventoryChange(L, ref);
1929 // add_item(self, listname, itemstack or itemstring or table or nil) -> itemstack
1930 // Returns the leftover stack
1931 static int l_add_item(lua_State *L)
1933 InvRef *ref = checkobject(L, 1);
1934 const char *listname = luaL_checkstring(L, 2);
1935 ItemStack item = read_item(L, 3);
1936 InventoryList *list = getlist(L, ref, listname);
1938 ItemStack leftover = list->addItem(item);
1939 if(leftover.count != item.count)
1940 reportInventoryChange(L, ref);
1941 LuaItemStack::create(L, leftover);
1943 LuaItemStack::create(L, item);
1948 // room_for_item(self, listname, itemstack or itemstring or table or nil) -> true/false
1949 // Returns true if the item completely fits into the list
1950 static int l_room_for_item(lua_State *L)
1952 InvRef *ref = checkobject(L, 1);
1953 const char *listname = luaL_checkstring(L, 2);
1954 ItemStack item = read_item(L, 3);
1955 InventoryList *list = getlist(L, ref, listname);
1957 lua_pushboolean(L, list->roomForItem(item));
1959 lua_pushboolean(L, false);
1964 // contains_item(self, listname, itemstack or itemstring or table or nil) -> true/false
1965 // Returns true if the list contains the given count of the given item name
1966 static int l_contains_item(lua_State *L)
1968 InvRef *ref = checkobject(L, 1);
1969 const char *listname = luaL_checkstring(L, 2);
1970 ItemStack item = read_item(L, 3);
1971 InventoryList *list = getlist(L, ref, listname);
1973 lua_pushboolean(L, list->containsItem(item));
1975 lua_pushboolean(L, false);
1980 // remove_item(self, listname, itemstack or itemstring or table or nil) -> itemstack
1981 // Returns the items that were actually removed
1982 static int l_remove_item(lua_State *L)
1984 InvRef *ref = checkobject(L, 1);
1985 const char *listname = luaL_checkstring(L, 2);
1986 ItemStack item = read_item(L, 3);
1987 InventoryList *list = getlist(L, ref, listname);
1989 ItemStack removed = list->removeItem(item);
1990 if(!removed.empty())
1991 reportInventoryChange(L, ref);
1992 LuaItemStack::create(L, removed);
1994 LuaItemStack::create(L, ItemStack());
2000 InvRef(const InventoryLocation &loc):
2009 // Creates an InvRef and leaves it on top of stack
2010 // Not callable from Lua; all references are created on the C side.
2011 static void create(lua_State *L, const InventoryLocation &loc)
2013 InvRef *o = new InvRef(loc);
2014 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
2015 luaL_getmetatable(L, className);
2016 lua_setmetatable(L, -2);
2018 static void createPlayer(lua_State *L, Player *player)
2020 InventoryLocation loc;
2021 loc.setPlayer(player->getName());
2024 static void createNodeMeta(lua_State *L, v3s16 p)
2026 InventoryLocation loc;
2031 static void Register(lua_State *L)
2034 int methodtable = lua_gettop(L);
2035 luaL_newmetatable(L, className);
2036 int metatable = lua_gettop(L);
2038 lua_pushliteral(L, "__metatable");
2039 lua_pushvalue(L, methodtable);
2040 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
2042 lua_pushliteral(L, "__index");
2043 lua_pushvalue(L, methodtable);
2044 lua_settable(L, metatable);
2046 lua_pushliteral(L, "__gc");
2047 lua_pushcfunction(L, gc_object);
2048 lua_settable(L, metatable);
2050 lua_pop(L, 1); // drop metatable
2052 luaL_openlib(L, 0, methods, 0); // fill methodtable
2053 lua_pop(L, 1); // drop methodtable
2055 // Cannot be created from Lua
2056 //lua_register(L, className, create_object);
2059 const char InvRef::className[] = "InvRef";
2060 const luaL_reg InvRef::methods[] = {
2061 method(InvRef, is_empty),
2062 method(InvRef, get_size),
2063 method(InvRef, set_size),
2064 method(InvRef, get_stack),
2065 method(InvRef, set_stack),
2066 method(InvRef, get_list),
2067 method(InvRef, set_list),
2068 method(InvRef, add_item),
2069 method(InvRef, room_for_item),
2070 method(InvRef, contains_item),
2071 method(InvRef, remove_item),
2083 ServerEnvironment *m_env;
2085 static const char className[];
2086 static const luaL_reg methods[];
2088 static NodeMetaRef *checkobject(lua_State *L, int narg)
2090 luaL_checktype(L, narg, LUA_TUSERDATA);
2091 void *ud = luaL_checkudata(L, narg, className);
2092 if(!ud) luaL_typerror(L, narg, className);
2093 return *(NodeMetaRef**)ud; // unbox pointer
2096 static NodeMetadata* getmeta(NodeMetaRef *ref, bool auto_create)
2098 NodeMetadata *meta = ref->m_env->getMap().getNodeMetadata(ref->m_p);
2099 if(meta == NULL && auto_create)
2101 meta = new NodeMetadata(ref->m_env->getGameDef());
2102 ref->m_env->getMap().setNodeMetadata(ref->m_p, meta);
2107 static void reportMetadataChange(NodeMetaRef *ref)
2109 // Inform other things that the metadata has changed
2110 v3s16 blockpos = getNodeBlockPos(ref->m_p);
2112 event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
2114 ref->m_env->getMap().dispatchEvent(&event);
2115 // Set the block to be saved
2116 MapBlock *block = ref->m_env->getMap().getBlockNoCreateNoEx(blockpos);
2118 block->raiseModified(MOD_STATE_WRITE_NEEDED,
2119 "NodeMetaRef::reportMetadataChange");
2122 // Exported functions
2124 // garbage collector
2125 static int gc_object(lua_State *L) {
2126 NodeMetaRef *o = *(NodeMetaRef **)(lua_touserdata(L, 1));
2131 // get_string(self, name)
2132 static int l_get_string(lua_State *L)
2134 NodeMetaRef *ref = checkobject(L, 1);
2135 std::string name = luaL_checkstring(L, 2);
2137 NodeMetadata *meta = getmeta(ref, false);
2139 lua_pushlstring(L, "", 0);
2142 std::string str = meta->getString(name);
2143 lua_pushlstring(L, str.c_str(), str.size());
2147 // set_string(self, name, var)
2148 static int l_set_string(lua_State *L)
2150 NodeMetaRef *ref = checkobject(L, 1);
2151 std::string name = luaL_checkstring(L, 2);
2153 const char *s = lua_tolstring(L, 3, &len);
2154 std::string str(s, len);
2156 NodeMetadata *meta = getmeta(ref, !str.empty());
2157 if(meta == NULL || str == meta->getString(name))
2159 meta->setString(name, str);
2160 reportMetadataChange(ref);
2164 // get_int(self, name)
2165 static int l_get_int(lua_State *L)
2167 NodeMetaRef *ref = checkobject(L, 1);
2168 std::string name = lua_tostring(L, 2);
2170 NodeMetadata *meta = getmeta(ref, false);
2172 lua_pushnumber(L, 0);
2175 std::string str = meta->getString(name);
2176 lua_pushnumber(L, stoi(str));
2180 // set_int(self, name, var)
2181 static int l_set_int(lua_State *L)
2183 NodeMetaRef *ref = checkobject(L, 1);
2184 std::string name = lua_tostring(L, 2);
2185 int a = lua_tointeger(L, 3);
2186 std::string str = itos(a);
2188 NodeMetadata *meta = getmeta(ref, true);
2189 if(meta == NULL || str == meta->getString(name))
2191 meta->setString(name, str);
2192 reportMetadataChange(ref);
2196 // get_float(self, name)
2197 static int l_get_float(lua_State *L)
2199 NodeMetaRef *ref = checkobject(L, 1);
2200 std::string name = lua_tostring(L, 2);
2202 NodeMetadata *meta = getmeta(ref, false);
2204 lua_pushnumber(L, 0);
2207 std::string str = meta->getString(name);
2208 lua_pushnumber(L, stof(str));
2212 // set_float(self, name, var)
2213 static int l_set_float(lua_State *L)
2215 NodeMetaRef *ref = checkobject(L, 1);
2216 std::string name = lua_tostring(L, 2);
2217 float a = lua_tonumber(L, 3);
2218 std::string str = ftos(a);
2220 NodeMetadata *meta = getmeta(ref, true);
2221 if(meta == NULL || str == meta->getString(name))
2223 meta->setString(name, str);
2224 reportMetadataChange(ref);
2228 // get_inventory(self)
2229 static int l_get_inventory(lua_State *L)
2231 NodeMetaRef *ref = checkobject(L, 1);
2232 getmeta(ref, true); // try to ensure the metadata exists
2233 InvRef::createNodeMeta(L, ref->m_p);
2238 static int l_to_table(lua_State *L)
2240 NodeMetaRef *ref = checkobject(L, 1);
2242 NodeMetadata *meta = getmeta(ref, true);
2251 std::map<std::string, std::string> fields = meta->getStrings();
2252 for(std::map<std::string, std::string>::const_iterator
2253 i = fields.begin(); i != fields.end(); i++){
2254 const std::string &name = i->first;
2255 const std::string &value = i->second;
2256 lua_pushlstring(L, name.c_str(), name.size());
2257 lua_pushlstring(L, value.c_str(), value.size());
2258 lua_settable(L, -3);
2261 lua_setfield(L, -2, "fields");
2264 Inventory *inv = meta->getInventory();
2266 std::vector<const InventoryList*> lists = inv->getLists();
2267 for(std::vector<const InventoryList*>::const_iterator
2268 i = lists.begin(); i != lists.end(); i++){
2269 inventory_get_list_to_lua(inv, (*i)->getName().c_str(), L);
2270 lua_setfield(L, -2, (*i)->getName().c_str());
2273 lua_setfield(L, -2, "inventory");
2277 // from_table(self, table)
2278 static int l_from_table(lua_State *L)
2280 NodeMetaRef *ref = checkobject(L, 1);
2283 if(lua_isnil(L, base)){
2285 ref->m_env->getMap().removeNodeMetadata(ref->m_p);
2286 lua_pushboolean(L, true);
2290 // Has metadata; clear old one first
2291 ref->m_env->getMap().removeNodeMetadata(ref->m_p);
2292 // Create new metadata
2293 NodeMetadata *meta = getmeta(ref, true);
2295 lua_getfield(L, base, "fields");
2296 int fieldstable = lua_gettop(L);
2298 while(lua_next(L, fieldstable) != 0){
2299 // key at index -2 and value at index -1
2300 std::string name = lua_tostring(L, -2);
2302 const char *cs = lua_tolstring(L, -1, &cl);
2303 std::string value(cs, cl);
2304 meta->setString(name, value);
2305 lua_pop(L, 1); // removes value, keeps key for next iteration
2308 Inventory *inv = meta->getInventory();
2309 lua_getfield(L, base, "inventory");
2310 int inventorytable = lua_gettop(L);
2312 while(lua_next(L, inventorytable) != 0){
2313 // key at index -2 and value at index -1
2314 std::string name = lua_tostring(L, -2);
2315 inventory_set_list_from_lua(inv, name.c_str(), L, -1);
2316 lua_pop(L, 1); // removes value, keeps key for next iteration
2318 reportMetadataChange(ref);
2319 lua_pushboolean(L, true);
2324 NodeMetaRef(v3s16 p, ServerEnvironment *env):
2334 // Creates an NodeMetaRef and leaves it on top of stack
2335 // Not callable from Lua; all references are created on the C side.
2336 static void create(lua_State *L, v3s16 p, ServerEnvironment *env)
2338 NodeMetaRef *o = new NodeMetaRef(p, env);
2339 //infostream<<"NodeMetaRef::create: o="<<o<<std::endl;
2340 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
2341 luaL_getmetatable(L, className);
2342 lua_setmetatable(L, -2);
2345 static void Register(lua_State *L)
2348 int methodtable = lua_gettop(L);
2349 luaL_newmetatable(L, className);
2350 int metatable = lua_gettop(L);
2352 lua_pushliteral(L, "__metatable");
2353 lua_pushvalue(L, methodtable);
2354 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
2356 lua_pushliteral(L, "__index");
2357 lua_pushvalue(L, methodtable);
2358 lua_settable(L, metatable);
2360 lua_pushliteral(L, "__gc");
2361 lua_pushcfunction(L, gc_object);
2362 lua_settable(L, metatable);
2364 lua_pop(L, 1); // drop metatable
2366 luaL_openlib(L, 0, methods, 0); // fill methodtable
2367 lua_pop(L, 1); // drop methodtable
2369 // Cannot be created from Lua
2370 //lua_register(L, className, create_object);
2373 const char NodeMetaRef::className[] = "NodeMetaRef";
2374 const luaL_reg NodeMetaRef::methods[] = {
2375 method(NodeMetaRef, get_string),
2376 method(NodeMetaRef, set_string),
2377 method(NodeMetaRef, get_int),
2378 method(NodeMetaRef, set_int),
2379 method(NodeMetaRef, get_float),
2380 method(NodeMetaRef, set_float),
2381 method(NodeMetaRef, get_inventory),
2382 method(NodeMetaRef, to_table),
2383 method(NodeMetaRef, from_table),
2394 ServerActiveObject *m_object;
2396 static const char className[];
2397 static const luaL_reg methods[];
2399 static ObjectRef *checkobject(lua_State *L, int narg)
2401 luaL_checktype(L, narg, LUA_TUSERDATA);
2402 void *ud = luaL_checkudata(L, narg, className);
2403 if(!ud) luaL_typerror(L, narg, className);
2404 return *(ObjectRef**)ud; // unbox pointer
2407 static ServerActiveObject* getobject(ObjectRef *ref)
2409 ServerActiveObject *co = ref->m_object;
2413 static LuaEntitySAO* getluaobject(ObjectRef *ref)
2415 ServerActiveObject *obj = getobject(ref);
2418 if(obj->getType() != ACTIVEOBJECT_TYPE_LUAENTITY)
2420 return (LuaEntitySAO*)obj;
2423 static PlayerSAO* getplayersao(ObjectRef *ref)
2425 ServerActiveObject *obj = getobject(ref);
2428 if(obj->getType() != ACTIVEOBJECT_TYPE_PLAYER)
2430 return (PlayerSAO*)obj;
2433 static Player* getplayer(ObjectRef *ref)
2435 PlayerSAO *playersao = getplayersao(ref);
2436 if(playersao == NULL)
2438 return playersao->getPlayer();
2441 // Exported functions
2443 // garbage collector
2444 static int gc_object(lua_State *L) {
2445 ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
2446 //infostream<<"ObjectRef::gc_object: o="<<o<<std::endl;
2452 static int l_remove(lua_State *L)
2454 ObjectRef *ref = checkobject(L, 1);
2455 ServerActiveObject *co = getobject(ref);
2456 if(co == NULL) return 0;
2457 verbosestream<<"ObjectRef::l_remove(): id="<<co->getId()<<std::endl;
2458 co->m_removed = true;
2463 // returns: {x=num, y=num, z=num}
2464 static int l_getpos(lua_State *L)
2466 ObjectRef *ref = checkobject(L, 1);
2467 ServerActiveObject *co = getobject(ref);
2468 if(co == NULL) return 0;
2469 v3f pos = co->getBasePosition() / BS;
2471 lua_pushnumber(L, pos.X);
2472 lua_setfield(L, -2, "x");
2473 lua_pushnumber(L, pos.Y);
2474 lua_setfield(L, -2, "y");
2475 lua_pushnumber(L, pos.Z);
2476 lua_setfield(L, -2, "z");
2480 // setpos(self, pos)
2481 static int l_setpos(lua_State *L)
2483 ObjectRef *ref = checkobject(L, 1);
2484 //LuaEntitySAO *co = getluaobject(ref);
2485 ServerActiveObject *co = getobject(ref);
2486 if(co == NULL) return 0;
2488 v3f pos = checkFloatPos(L, 2);
2494 // moveto(self, pos, continuous=false)
2495 static int l_moveto(lua_State *L)
2497 ObjectRef *ref = checkobject(L, 1);
2498 //LuaEntitySAO *co = getluaobject(ref);
2499 ServerActiveObject *co = getobject(ref);
2500 if(co == NULL) return 0;
2502 v3f pos = checkFloatPos(L, 2);
2504 bool continuous = lua_toboolean(L, 3);
2506 co->moveTo(pos, continuous);
2510 // punch(self, puncher, tool_capabilities, direction, time_from_last_punch)
2511 static int l_punch(lua_State *L)
2513 ObjectRef *ref = checkobject(L, 1);
2514 ObjectRef *puncher_ref = checkobject(L, 2);
2515 ServerActiveObject *co = getobject(ref);
2516 ServerActiveObject *puncher = getobject(puncher_ref);
2517 if(co == NULL) return 0;
2518 if(puncher == NULL) return 0;
2519 ToolCapabilities toolcap = read_tool_capabilities(L, 3);
2520 v3f dir = read_v3f(L, 4);
2521 float time_from_last_punch = 1000000;
2522 if(lua_isnumber(L, 5))
2523 time_from_last_punch = lua_tonumber(L, 5);
2525 puncher->punch(dir, &toolcap, puncher, time_from_last_punch);
2529 // right_click(self, clicker); clicker = an another ObjectRef
2530 static int l_right_click(lua_State *L)
2532 ObjectRef *ref = checkobject(L, 1);
2533 ObjectRef *ref2 = checkobject(L, 2);
2534 ServerActiveObject *co = getobject(ref);
2535 ServerActiveObject *co2 = getobject(ref2);
2536 if(co == NULL) return 0;
2537 if(co2 == NULL) return 0;
2539 co->rightClick(co2);
2544 // hp = number of hitpoints (2 * number of hearts)
2546 static int l_set_hp(lua_State *L)
2548 ObjectRef *ref = checkobject(L, 1);
2549 luaL_checknumber(L, 2);
2550 ServerActiveObject *co = getobject(ref);
2551 if(co == NULL) return 0;
2552 int hp = lua_tonumber(L, 2);
2553 /*infostream<<"ObjectRef::l_set_hp(): id="<<co->getId()
2554 <<" hp="<<hp<<std::endl;*/
2562 // returns: number of hitpoints (2 * number of hearts)
2563 // 0 if not applicable to this type of object
2564 static int l_get_hp(lua_State *L)
2566 ObjectRef *ref = checkobject(L, 1);
2567 ServerActiveObject *co = getobject(ref);
2570 lua_pushnumber(L, 1);
2573 int hp = co->getHP();
2574 /*infostream<<"ObjectRef::l_get_hp(): id="<<co->getId()
2575 <<" hp="<<hp<<std::endl;*/
2577 lua_pushnumber(L, hp);
2581 // get_inventory(self)
2582 static int l_get_inventory(lua_State *L)
2584 ObjectRef *ref = checkobject(L, 1);
2585 ServerActiveObject *co = getobject(ref);
2586 if(co == NULL) return 0;
2588 InventoryLocation loc = co->getInventoryLocation();
2589 if(get_server(L)->getInventory(loc) != NULL)
2590 InvRef::create(L, loc);
2592 lua_pushnil(L); // An object may have no inventory (nil)
2596 // get_wield_list(self)
2597 static int l_get_wield_list(lua_State *L)
2599 ObjectRef *ref = checkobject(L, 1);
2600 ServerActiveObject *co = getobject(ref);
2601 if(co == NULL) return 0;
2603 lua_pushstring(L, co->getWieldList().c_str());
2607 // get_wield_index(self)
2608 static int l_get_wield_index(lua_State *L)
2610 ObjectRef *ref = checkobject(L, 1);
2611 ServerActiveObject *co = getobject(ref);
2612 if(co == NULL) return 0;
2614 lua_pushinteger(L, co->getWieldIndex() + 1);
2618 // get_wielded_item(self)
2619 static int l_get_wielded_item(lua_State *L)
2621 ObjectRef *ref = checkobject(L, 1);
2622 ServerActiveObject *co = getobject(ref);
2625 LuaItemStack::create(L, ItemStack());
2629 LuaItemStack::create(L, co->getWieldedItem());
2633 // set_wielded_item(self, itemstack or itemstring or table or nil)
2634 static int l_set_wielded_item(lua_State *L)
2636 ObjectRef *ref = checkobject(L, 1);
2637 ServerActiveObject *co = getobject(ref);
2638 if(co == NULL) return 0;
2640 ItemStack item = read_item(L, 2);
2641 bool success = co->setWieldedItem(item);
2642 lua_pushboolean(L, success);
2646 // set_armor_groups(self, groups)
2647 static int l_set_armor_groups(lua_State *L)
2649 ObjectRef *ref = checkobject(L, 1);
2650 ServerActiveObject *co = getobject(ref);
2651 if(co == NULL) return 0;
2653 ItemGroupList groups;
2654 read_groups(L, 2, groups);
2655 co->setArmorGroups(groups);
2659 // set_properties(self, properties)
2660 static int l_set_properties(lua_State *L)
2662 ObjectRef *ref = checkobject(L, 1);
2663 ServerActiveObject *co = getobject(ref);
2664 if(co == NULL) return 0;
2665 ObjectProperties *prop = co->accessObjectProperties();
2668 read_object_properties(L, 2, prop);
2669 co->notifyObjectPropertiesModified();
2673 /* LuaEntitySAO-only */
2675 // setvelocity(self, {x=num, y=num, z=num})
2676 static int l_setvelocity(lua_State *L)
2678 ObjectRef *ref = checkobject(L, 1);
2679 LuaEntitySAO *co = getluaobject(ref);
2680 if(co == NULL) return 0;
2681 v3f pos = checkFloatPos(L, 2);
2683 co->setVelocity(pos);
2687 // getvelocity(self)
2688 static int l_getvelocity(lua_State *L)
2690 ObjectRef *ref = checkobject(L, 1);
2691 LuaEntitySAO *co = getluaobject(ref);
2692 if(co == NULL) return 0;
2694 v3f v = co->getVelocity();
2699 // setacceleration(self, {x=num, y=num, z=num})
2700 static int l_setacceleration(lua_State *L)
2702 ObjectRef *ref = checkobject(L, 1);
2703 LuaEntitySAO *co = getluaobject(ref);
2704 if(co == NULL) return 0;
2706 v3f pos = checkFloatPos(L, 2);
2708 co->setAcceleration(pos);
2712 // getacceleration(self)
2713 static int l_getacceleration(lua_State *L)
2715 ObjectRef *ref = checkobject(L, 1);
2716 LuaEntitySAO *co = getluaobject(ref);
2717 if(co == NULL) return 0;
2719 v3f v = co->getAcceleration();
2724 // setyaw(self, radians)
2725 static int l_setyaw(lua_State *L)
2727 ObjectRef *ref = checkobject(L, 1);
2728 LuaEntitySAO *co = getluaobject(ref);
2729 if(co == NULL) return 0;
2730 float yaw = luaL_checknumber(L, 2) * core::RADTODEG;
2737 static int l_getyaw(lua_State *L)
2739 ObjectRef *ref = checkobject(L, 1);
2740 LuaEntitySAO *co = getluaobject(ref);
2741 if(co == NULL) return 0;
2743 float yaw = co->getYaw() * core::DEGTORAD;
2744 lua_pushnumber(L, yaw);
2748 // settexturemod(self, mod)
2749 static int l_settexturemod(lua_State *L)
2751 ObjectRef *ref = checkobject(L, 1);
2752 LuaEntitySAO *co = getluaobject(ref);
2753 if(co == NULL) return 0;
2755 std::string mod = luaL_checkstring(L, 2);
2756 co->setTextureMod(mod);
2760 // setsprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2,
2761 // select_horiz_by_yawpitch=false)
2762 static int l_setsprite(lua_State *L)
2764 ObjectRef *ref = checkobject(L, 1);
2765 LuaEntitySAO *co = getluaobject(ref);
2766 if(co == NULL) return 0;
2769 if(!lua_isnil(L, 2))
2770 p = read_v2s16(L, 2);
2772 if(!lua_isnil(L, 3))
2773 num_frames = lua_tonumber(L, 3);
2774 float framelength = 0.2;
2775 if(!lua_isnil(L, 4))
2776 framelength = lua_tonumber(L, 4);
2777 bool select_horiz_by_yawpitch = false;
2778 if(!lua_isnil(L, 5))
2779 select_horiz_by_yawpitch = lua_toboolean(L, 5);
2780 co->setSprite(p, num_frames, framelength, select_horiz_by_yawpitch);
2785 // get_entity_name(self)
2786 static int l_get_entity_name(lua_State *L)
2788 ObjectRef *ref = checkobject(L, 1);
2789 LuaEntitySAO *co = getluaobject(ref);
2790 if(co == NULL) return 0;
2792 std::string name = co->getName();
2793 lua_pushstring(L, name.c_str());
2797 // get_luaentity(self)
2798 static int l_get_luaentity(lua_State *L)
2800 ObjectRef *ref = checkobject(L, 1);
2801 LuaEntitySAO *co = getluaobject(ref);
2802 if(co == NULL) return 0;
2804 luaentity_get(L, co->getId());
2811 static int l_is_player(lua_State *L)
2813 ObjectRef *ref = checkobject(L, 1);
2814 Player *player = getplayer(ref);
2815 lua_pushboolean(L, (player != NULL));
2819 // get_player_name(self)
2820 static int l_get_player_name(lua_State *L)
2822 ObjectRef *ref = checkobject(L, 1);
2823 Player *player = getplayer(ref);
2825 lua_pushlstring(L, "", 0);
2829 lua_pushstring(L, player->getName());
2833 // get_look_dir(self)
2834 static int l_get_look_dir(lua_State *L)
2836 ObjectRef *ref = checkobject(L, 1);
2837 Player *player = getplayer(ref);
2838 if(player == NULL) return 0;
2840 float pitch = player->getRadPitch();
2841 float yaw = player->getRadYaw();
2842 v3f v(cos(pitch)*cos(yaw), sin(pitch), cos(pitch)*sin(yaw));
2847 // get_look_pitch(self)
2848 static int l_get_look_pitch(lua_State *L)
2850 ObjectRef *ref = checkobject(L, 1);
2851 Player *player = getplayer(ref);
2852 if(player == NULL) return 0;
2854 lua_pushnumber(L, player->getRadPitch());
2858 // get_look_yaw(self)
2859 static int l_get_look_yaw(lua_State *L)
2861 ObjectRef *ref = checkobject(L, 1);
2862 Player *player = getplayer(ref);
2863 if(player == NULL) return 0;
2865 lua_pushnumber(L, player->getRadYaw());
2869 // set_inventory_formspec(self, formspec)
2870 static int l_set_inventory_formspec(lua_State *L)
2872 ObjectRef *ref = checkobject(L, 1);
2873 Player *player = getplayer(ref);
2874 if(player == NULL) return 0;
2875 std::string formspec = luaL_checkstring(L, 2);
2877 player->inventory_formspec = formspec;
2878 get_server(L)->reportInventoryFormspecModified(player->getName());
2879 lua_pushboolean(L, true);
2883 // get_inventory_formspec(self) -> formspec
2884 static int l_get_inventory_formspec(lua_State *L)
2886 ObjectRef *ref = checkobject(L, 1);
2887 Player *player = getplayer(ref);
2888 if(player == NULL) return 0;
2890 std::string formspec = player->inventory_formspec;
2891 lua_pushlstring(L, formspec.c_str(), formspec.size());
2896 ObjectRef(ServerActiveObject *object):
2899 //infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
2905 infostream<<"ObjectRef destructing for id="
2906 <<m_object->getId()<<std::endl;
2908 infostream<<"ObjectRef destructing for id=unknown"<<std::endl;*/
2911 // Creates an ObjectRef and leaves it on top of stack
2912 // Not callable from Lua; all references are created on the C side.
2913 static void create(lua_State *L, ServerActiveObject *object)
2915 ObjectRef *o = new ObjectRef(object);
2916 //infostream<<"ObjectRef::create: o="<<o<<std::endl;
2917 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
2918 luaL_getmetatable(L, className);
2919 lua_setmetatable(L, -2);
2922 static void set_null(lua_State *L)
2924 ObjectRef *o = checkobject(L, -1);
2928 static void Register(lua_State *L)
2931 int methodtable = lua_gettop(L);
2932 luaL_newmetatable(L, className);
2933 int metatable = lua_gettop(L);
2935 lua_pushliteral(L, "__metatable");
2936 lua_pushvalue(L, methodtable);
2937 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
2939 lua_pushliteral(L, "__index");
2940 lua_pushvalue(L, methodtable);
2941 lua_settable(L, metatable);
2943 lua_pushliteral(L, "__gc");
2944 lua_pushcfunction(L, gc_object);
2945 lua_settable(L, metatable);
2947 lua_pop(L, 1); // drop metatable
2949 luaL_openlib(L, 0, methods, 0); // fill methodtable
2950 lua_pop(L, 1); // drop methodtable
2952 // Cannot be created from Lua
2953 //lua_register(L, className, create_object);
2956 const char ObjectRef::className[] = "ObjectRef";
2957 const luaL_reg ObjectRef::methods[] = {
2958 // ServerActiveObject
2959 method(ObjectRef, remove),
2960 method(ObjectRef, getpos),
2961 method(ObjectRef, setpos),
2962 method(ObjectRef, moveto),
2963 method(ObjectRef, punch),
2964 method(ObjectRef, right_click),
2965 method(ObjectRef, set_hp),
2966 method(ObjectRef, get_hp),
2967 method(ObjectRef, get_inventory),
2968 method(ObjectRef, get_wield_list),
2969 method(ObjectRef, get_wield_index),
2970 method(ObjectRef, get_wielded_item),
2971 method(ObjectRef, set_wielded_item),
2972 method(ObjectRef, set_armor_groups),
2973 method(ObjectRef, set_properties),
2974 // LuaEntitySAO-only
2975 method(ObjectRef, setvelocity),
2976 method(ObjectRef, getvelocity),
2977 method(ObjectRef, setacceleration),
2978 method(ObjectRef, getacceleration),
2979 method(ObjectRef, setyaw),
2980 method(ObjectRef, getyaw),
2981 method(ObjectRef, settexturemod),
2982 method(ObjectRef, setsprite),
2983 method(ObjectRef, get_entity_name),
2984 method(ObjectRef, get_luaentity),
2986 method(ObjectRef, is_player),
2987 method(ObjectRef, get_player_name),
2988 method(ObjectRef, get_look_dir),
2989 method(ObjectRef, get_look_pitch),
2990 method(ObjectRef, get_look_yaw),
2991 method(ObjectRef, set_inventory_formspec),
2992 method(ObjectRef, get_inventory_formspec),
2996 // Creates a new anonymous reference if cobj=NULL or id=0
2997 static void objectref_get_or_create(lua_State *L,
2998 ServerActiveObject *cobj)
3000 if(cobj == NULL || cobj->getId() == 0){
3001 ObjectRef::create(L, cobj);
3003 objectref_get(L, cobj->getId());
3012 class LuaPerlinNoise
3019 static const char className[];
3020 static const luaL_reg methods[];
3022 // Exported functions
3024 // garbage collector
3025 static int gc_object(lua_State *L)
3027 LuaPerlinNoise *o = *(LuaPerlinNoise **)(lua_touserdata(L, 1));
3032 static int l_get2d(lua_State *L)
3034 LuaPerlinNoise *o = checkobject(L, 1);
3035 v2f pos2d = read_v2f(L,2);
3036 lua_Number val = noise2d_perlin(pos2d.X/o->scale, pos2d.Y/o->scale, o->seed, o->octaves, o->persistence);
3037 lua_pushnumber(L, val);
3040 static int l_get3d(lua_State *L)
3042 LuaPerlinNoise *o = checkobject(L, 1);
3043 v3f pos3d = read_v3f(L,2);
3044 lua_Number val = noise3d_perlin(pos3d.X/o->scale, pos3d.Y/o->scale, pos3d.Z/o->scale, o->seed, o->octaves, o->persistence);
3045 lua_pushnumber(L, val);
3050 LuaPerlinNoise(int a_seed, int a_octaves, double a_persistence,
3054 persistence(a_persistence),
3063 // LuaPerlinNoise(seed, octaves, persistence, scale)
3064 // Creates an LuaPerlinNoise and leaves it on top of stack
3065 static int create_object(lua_State *L)
3067 int seed = luaL_checkint(L, 1);
3068 int octaves = luaL_checkint(L, 2);
3069 double persistence = luaL_checknumber(L, 3);
3070 double scale = luaL_checknumber(L, 4);
3071 LuaPerlinNoise *o = new LuaPerlinNoise(seed, octaves, persistence, scale);
3072 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
3073 luaL_getmetatable(L, className);
3074 lua_setmetatable(L, -2);
3078 static LuaPerlinNoise* checkobject(lua_State *L, int narg)
3080 luaL_checktype(L, narg, LUA_TUSERDATA);
3081 void *ud = luaL_checkudata(L, narg, className);
3082 if(!ud) luaL_typerror(L, narg, className);
3083 return *(LuaPerlinNoise**)ud; // unbox pointer
3086 static void Register(lua_State *L)
3089 int methodtable = lua_gettop(L);
3090 luaL_newmetatable(L, className);
3091 int metatable = lua_gettop(L);
3093 lua_pushliteral(L, "__metatable");
3094 lua_pushvalue(L, methodtable);
3095 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
3097 lua_pushliteral(L, "__index");
3098 lua_pushvalue(L, methodtable);
3099 lua_settable(L, metatable);
3101 lua_pushliteral(L, "__gc");
3102 lua_pushcfunction(L, gc_object);
3103 lua_settable(L, metatable);
3105 lua_pop(L, 1); // drop metatable
3107 luaL_openlib(L, 0, methods, 0); // fill methodtable
3108 lua_pop(L, 1); // drop methodtable
3110 // Can be created from Lua (PerlinNoise(seed, octaves, persistence)
3111 lua_register(L, className, create_object);
3114 const char LuaPerlinNoise::className[] = "PerlinNoise";
3115 const luaL_reg LuaPerlinNoise::methods[] = {
3116 method(LuaPerlinNoise, get2d),
3117 method(LuaPerlinNoise, get3d),
3128 ServerEnvironment *m_env;
3130 static const char className[];
3131 static const luaL_reg methods[];
3133 static int gc_object(lua_State *L) {
3134 EnvRef *o = *(EnvRef **)(lua_touserdata(L, 1));
3139 static EnvRef *checkobject(lua_State *L, int narg)
3141 luaL_checktype(L, narg, LUA_TUSERDATA);
3142 void *ud = luaL_checkudata(L, narg, className);
3143 if(!ud) luaL_typerror(L, narg, className);
3144 return *(EnvRef**)ud; // unbox pointer
3147 // Exported functions
3149 // EnvRef:set_node(pos, node)
3150 // pos = {x=num, y=num, z=num}
3151 static int l_set_node(lua_State *L)
3153 EnvRef *o = checkobject(L, 1);
3154 ServerEnvironment *env = o->m_env;
3155 if(env == NULL) return 0;
3156 INodeDefManager *ndef = env->getGameDef()->ndef();
3158 v3s16 pos = read_v3s16(L, 2);
3159 MapNode n = readnode(L, 3, ndef);
3161 MapNode n_old = env->getMap().getNodeNoEx(pos);
3163 if(ndef->get(n_old).has_on_destruct)
3164 scriptapi_node_on_destruct(L, pos, n_old);
3166 bool succeeded = env->getMap().addNodeWithEvent(pos, n);
3168 // Call post-destructor
3169 if(ndef->get(n_old).has_after_destruct)
3170 scriptapi_node_after_destruct(L, pos, n_old);
3172 if(ndef->get(n).has_on_construct)
3173 scriptapi_node_on_construct(L, pos, n);
3175 lua_pushboolean(L, succeeded);
3179 static int l_add_node(lua_State *L)
3181 return l_set_node(L);
3184 // EnvRef:remove_node(pos)
3185 // pos = {x=num, y=num, z=num}
3186 static int l_remove_node(lua_State *L)
3188 EnvRef *o = checkobject(L, 1);
3189 ServerEnvironment *env = o->m_env;
3190 if(env == NULL) return 0;
3191 INodeDefManager *ndef = env->getGameDef()->ndef();
3193 v3s16 pos = read_v3s16(L, 2);
3195 MapNode n_old = env->getMap().getNodeNoEx(pos);
3197 if(ndef->get(n_old).has_on_destruct)
3198 scriptapi_node_on_destruct(L, pos, n_old);
3200 // This is slightly optimized compared to addNodeWithEvent(air)
3201 bool succeeded = env->getMap().removeNodeWithEvent(pos);
3203 // Call post-destructor
3204 if(ndef->get(n_old).has_after_destruct)
3205 scriptapi_node_after_destruct(L, pos, n_old);
3207 lua_pushboolean(L, succeeded);
3208 // Air doesn't require constructor
3212 // EnvRef:get_node(pos)
3213 // pos = {x=num, y=num, z=num}
3214 static int l_get_node(lua_State *L)
3216 EnvRef *o = checkobject(L, 1);
3217 ServerEnvironment *env = o->m_env;
3218 if(env == NULL) return 0;
3220 v3s16 pos = read_v3s16(L, 2);
3222 MapNode n = env->getMap().getNodeNoEx(pos);
3224 pushnode(L, n, env->getGameDef()->ndef());
3228 // EnvRef:get_node_or_nil(pos)
3229 // pos = {x=num, y=num, z=num}
3230 static int l_get_node_or_nil(lua_State *L)
3232 EnvRef *o = checkobject(L, 1);
3233 ServerEnvironment *env = o->m_env;
3234 if(env == NULL) return 0;
3236 v3s16 pos = read_v3s16(L, 2);
3239 MapNode n = env->getMap().getNode(pos);
3241 pushnode(L, n, env->getGameDef()->ndef());
3243 } catch(InvalidPositionException &e)
3250 // EnvRef:get_node_light(pos, timeofday)
3251 // pos = {x=num, y=num, z=num}
3252 // timeofday: nil = current time, 0 = night, 0.5 = day
3253 static int l_get_node_light(lua_State *L)
3255 EnvRef *o = checkobject(L, 1);
3256 ServerEnvironment *env = o->m_env;
3257 if(env == NULL) return 0;
3259 v3s16 pos = read_v3s16(L, 2);
3260 u32 time_of_day = env->getTimeOfDay();
3261 if(lua_isnumber(L, 3))
3262 time_of_day = 24000.0 * lua_tonumber(L, 3);
3263 time_of_day %= 24000;
3264 u32 dnr = time_to_daynight_ratio(time_of_day);
3265 MapNode n = env->getMap().getNodeNoEx(pos);
3267 MapNode n = env->getMap().getNode(pos);
3268 INodeDefManager *ndef = env->getGameDef()->ndef();
3269 lua_pushinteger(L, n.getLightBlend(dnr, ndef));
3271 } catch(InvalidPositionException &e)
3278 // EnvRef:place_node(pos, node)
3279 // pos = {x=num, y=num, z=num}
3280 static int l_place_node(lua_State *L)
3282 EnvRef *o = checkobject(L, 1);
3283 ServerEnvironment *env = o->m_env;
3284 if(env == NULL) return 0;
3285 v3s16 pos = read_v3s16(L, 2);
3286 MapNode n = readnode(L, 3, env->getGameDef()->ndef());
3288 // Don't attempt to load non-loaded area as of now
3289 MapNode n_old = env->getMap().getNodeNoEx(pos);
3290 if(n_old.getContent() == CONTENT_IGNORE){
3291 lua_pushboolean(L, false);
3294 // Create item to place
3295 INodeDefManager *ndef = get_server(L)->ndef();
3296 IItemDefManager *idef = get_server(L)->idef();
3297 ItemStack item(ndef->get(n).name, 1, 0, "", idef);
3298 // Make pointed position
3299 PointedThing pointed;
3300 pointed.type = POINTEDTHING_NODE;
3301 pointed.node_abovesurface = pos;
3302 pointed.node_undersurface = pos + v3s16(0,-1,0);
3303 // Place it with a NULL placer (appears in Lua as a non-functional
3305 bool success = scriptapi_item_on_place(L, item, NULL, pointed);
3306 lua_pushboolean(L, success);
3310 // EnvRef:dig_node(pos)
3311 // pos = {x=num, y=num, z=num}
3312 static int l_dig_node(lua_State *L)
3314 EnvRef *o = checkobject(L, 1);
3315 ServerEnvironment *env = o->m_env;
3316 if(env == NULL) return 0;
3317 v3s16 pos = read_v3s16(L, 2);
3319 // Don't attempt to load non-loaded area as of now
3320 MapNode n = env->getMap().getNodeNoEx(pos);
3321 if(n.getContent() == CONTENT_IGNORE){
3322 lua_pushboolean(L, false);
3325 // Dig it out with a NULL digger (appears in Lua as a
3326 // non-functional ObjectRef)
3327 bool success = scriptapi_node_on_dig(L, pos, n, NULL);
3328 lua_pushboolean(L, success);
3332 // EnvRef:punch_node(pos)
3333 // pos = {x=num, y=num, z=num}
3334 static int l_punch_node(lua_State *L)
3336 EnvRef *o = checkobject(L, 1);
3337 ServerEnvironment *env = o->m_env;
3338 if(env == NULL) return 0;
3339 v3s16 pos = read_v3s16(L, 2);
3341 // Don't attempt to load non-loaded area as of now
3342 MapNode n = env->getMap().getNodeNoEx(pos);
3343 if(n.getContent() == CONTENT_IGNORE){
3344 lua_pushboolean(L, false);
3347 // Punch it with a NULL puncher (appears in Lua as a non-functional
3349 bool success = scriptapi_node_on_punch(L, pos, n, NULL);
3350 lua_pushboolean(L, success);
3354 // EnvRef:add_entity(pos, entityname) -> ObjectRef or nil
3355 // pos = {x=num, y=num, z=num}
3356 static int l_add_entity(lua_State *L)
3358 //infostream<<"EnvRef::l_add_entity()"<<std::endl;
3359 EnvRef *o = checkobject(L, 1);
3360 ServerEnvironment *env = o->m_env;
3361 if(env == NULL) return 0;
3363 v3f pos = checkFloatPos(L, 2);
3365 const char *name = luaL_checkstring(L, 3);
3367 ServerActiveObject *obj = new LuaEntitySAO(env, pos, name, "");
3368 int objectid = env->addActiveObject(obj);
3369 // If failed to add, return nothing (reads as nil)
3373 objectref_get_or_create(L, obj);
3377 // EnvRef:add_item(pos, itemstack or itemstring or table) -> ObjectRef or nil
3378 // pos = {x=num, y=num, z=num}
3379 static int l_add_item(lua_State *L)
3381 //infostream<<"EnvRef::l_add_item()"<<std::endl;
3382 EnvRef *o = checkobject(L, 1);
3383 ServerEnvironment *env = o->m_env;
3384 if(env == NULL) return 0;
3386 v3f pos = checkFloatPos(L, 2);
3388 ItemStack item = read_item(L, 3);
3389 if(item.empty() || !item.isKnown(get_server(L)->idef()))
3391 // Use minetest.spawn_item to spawn a __builtin:item
3392 lua_getglobal(L, "minetest");
3393 lua_getfield(L, -1, "spawn_item");
3394 if(lua_isnil(L, -1))
3396 lua_pushvalue(L, 2);
3397 lua_pushstring(L, item.getItemString().c_str());
3398 if(lua_pcall(L, 2, 1, 0))
3399 script_error(L, "error: %s", lua_tostring(L, -1));
3401 /*lua_pushvalue(L, 1);
3402 lua_pushstring(L, "__builtin:item");
3403 lua_pushstring(L, item.getItemString().c_str());
3404 return l_add_entity(L);*/
3406 ServerActiveObject *obj = createItemSAO(env, pos, item.getItemString());
3407 int objectid = env->addActiveObject(obj);
3408 // If failed to add, return nothing (reads as nil)
3412 objectref_get_or_create(L, obj);
3416 // EnvRef:add_rat(pos)
3417 // pos = {x=num, y=num, z=num}
3418 static int l_add_rat(lua_State *L)
3420 infostream<<"EnvRef::l_add_rat(): C++ mobs have been removed."
3421 <<" Doing nothing."<<std::endl;
3425 // EnvRef:add_firefly(pos)
3426 // pos = {x=num, y=num, z=num}
3427 static int l_add_firefly(lua_State *L)
3429 infostream<<"EnvRef::l_add_firefly(): C++ mobs have been removed."
3430 <<" Doing nothing."<<std::endl;
3434 // EnvRef:get_meta(pos)
3435 static int l_get_meta(lua_State *L)
3437 //infostream<<"EnvRef::l_get_meta()"<<std::endl;
3438 EnvRef *o = checkobject(L, 1);
3439 ServerEnvironment *env = o->m_env;
3440 if(env == NULL) return 0;
3442 v3s16 p = read_v3s16(L, 2);
3443 NodeMetaRef::create(L, p, env);
3447 // EnvRef:get_player_by_name(name)
3448 static int l_get_player_by_name(lua_State *L)
3450 EnvRef *o = checkobject(L, 1);
3451 ServerEnvironment *env = o->m_env;
3452 if(env == NULL) return 0;
3454 const char *name = luaL_checkstring(L, 2);
3455 Player *player = env->getPlayer(name);
3460 PlayerSAO *sao = player->getPlayerSAO();
3465 // Put player on stack
3466 objectref_get_or_create(L, sao);
3470 // EnvRef:get_objects_inside_radius(pos, radius)
3471 static int l_get_objects_inside_radius(lua_State *L)
3473 // Get the table insert function
3474 lua_getglobal(L, "table");
3475 lua_getfield(L, -1, "insert");
3476 int table_insert = lua_gettop(L);
3478 EnvRef *o = checkobject(L, 1);
3479 ServerEnvironment *env = o->m_env;
3480 if(env == NULL) return 0;
3482 v3f pos = checkFloatPos(L, 2);
3483 float radius = luaL_checknumber(L, 3) * BS;
3484 std::set<u16> ids = env->getObjectsInsideRadius(pos, radius);
3486 int table = lua_gettop(L);
3487 for(std::set<u16>::const_iterator
3488 i = ids.begin(); i != ids.end(); i++){
3489 ServerActiveObject *obj = env->getActiveObject(*i);
3490 // Insert object reference into table
3491 lua_pushvalue(L, table_insert);
3492 lua_pushvalue(L, table);
3493 objectref_get_or_create(L, obj);
3494 if(lua_pcall(L, 2, 0, 0))
3495 script_error(L, "error: %s", lua_tostring(L, -1));
3500 // EnvRef:set_timeofday(val)
3502 static int l_set_timeofday(lua_State *L)
3504 EnvRef *o = checkobject(L, 1);
3505 ServerEnvironment *env = o->m_env;
3506 if(env == NULL) return 0;
3508 float timeofday_f = luaL_checknumber(L, 2);
3509 assert(timeofday_f >= 0.0 && timeofday_f <= 1.0);
3510 int timeofday_mh = (int)(timeofday_f * 24000.0);
3511 // This should be set directly in the environment but currently
3512 // such changes aren't immediately sent to the clients, so call
3513 // the server instead.
3514 //env->setTimeOfDay(timeofday_mh);
3515 get_server(L)->setTimeOfDay(timeofday_mh);
3519 // EnvRef:get_timeofday() -> 0...1
3520 static int l_get_timeofday(lua_State *L)
3522 EnvRef *o = checkobject(L, 1);
3523 ServerEnvironment *env = o->m_env;
3524 if(env == NULL) return 0;
3526 int timeofday_mh = env->getTimeOfDay();
3527 float timeofday_f = (float)timeofday_mh / 24000.0;
3528 lua_pushnumber(L, timeofday_f);
3533 // EnvRef:find_node_near(pos, radius, nodenames) -> pos or nil
3534 // nodenames: eg. {"ignore", "group:tree"} or "default:dirt"
3535 static int l_find_node_near(lua_State *L)
3537 EnvRef *o = checkobject(L, 1);
3538 ServerEnvironment *env = o->m_env;
3539 if(env == NULL) return 0;
3540 INodeDefManager *ndef = get_server(L)->ndef();
3541 v3s16 pos = read_v3s16(L, 2);
3542 int radius = luaL_checkinteger(L, 3);
3543 std::set<content_t> filter;
3544 if(lua_istable(L, 4)){
3547 while(lua_next(L, table) != 0){
3548 // key at index -2 and value at index -1
3549 luaL_checktype(L, -1, LUA_TSTRING);
3550 ndef->getIds(lua_tostring(L, -1), filter);
3551 // removes value, keeps key for next iteration
3554 } else if(lua_isstring(L, 4)){
3555 ndef->getIds(lua_tostring(L, 4), filter);
3558 for(int d=1; d<=radius; d++){
3559 core::list<v3s16> list;
3560 getFacePositions(list, d);
3561 for(core::list<v3s16>::Iterator i = list.begin();
3562 i != list.end(); i++){
3563 v3s16 p = pos + (*i);
3564 content_t c = env->getMap().getNodeNoEx(p).getContent();
3565 if(filter.count(c) != 0){
3574 // EnvRef:find_nodes_in_area(minp, maxp, nodenames) -> list of positions
3575 // nodenames: eg. {"ignore", "group:tree"} or "default:dirt"
3576 static int l_find_nodes_in_area(lua_State *L)
3578 EnvRef *o = checkobject(L, 1);
3579 ServerEnvironment *env = o->m_env;
3580 if(env == NULL) return 0;
3581 INodeDefManager *ndef = get_server(L)->ndef();
3582 v3s16 minp = read_v3s16(L, 2);
3583 v3s16 maxp = read_v3s16(L, 3);
3584 std::set<content_t> filter;
3585 if(lua_istable(L, 4)){
3588 while(lua_next(L, table) != 0){
3589 // key at index -2 and value at index -1
3590 luaL_checktype(L, -1, LUA_TSTRING);
3591 ndef->getIds(lua_tostring(L, -1), filter);
3592 // removes value, keeps key for next iteration
3595 } else if(lua_isstring(L, 4)){
3596 ndef->getIds(lua_tostring(L, 4), filter);
3599 // Get the table insert function
3600 lua_getglobal(L, "table");
3601 lua_getfield(L, -1, "insert");
3602 int table_insert = lua_gettop(L);
3605 int table = lua_gettop(L);
3606 for(s16 x=minp.X; x<=maxp.X; x++)
3607 for(s16 y=minp.Y; y<=maxp.Y; y++)
3608 for(s16 z=minp.Z; z<=maxp.Z; z++)
3611 content_t c = env->getMap().getNodeNoEx(p).getContent();
3612 if(filter.count(c) != 0){
3613 lua_pushvalue(L, table_insert);
3614 lua_pushvalue(L, table);
3616 if(lua_pcall(L, 2, 0, 0))
3617 script_error(L, "error: %s", lua_tostring(L, -1));
3623 // EnvRef:get_perlin(seeddiff, octaves, persistence, scale)
3624 // returns world-specific PerlinNoise
3625 static int l_get_perlin(lua_State *L)
3627 EnvRef *o = checkobject(L, 1);
3628 ServerEnvironment *env = o->m_env;
3629 if(env == NULL) return 0;
3631 int seeddiff = luaL_checkint(L, 2);
3632 int octaves = luaL_checkint(L, 3);
3633 double persistence = luaL_checknumber(L, 4);
3634 double scale = luaL_checknumber(L, 5);
3636 LuaPerlinNoise *n = new LuaPerlinNoise(seeddiff + int(env->getServerMap().getSeed()), octaves, persistence, scale);
3637 *(void **)(lua_newuserdata(L, sizeof(void *))) = n;
3638 luaL_getmetatable(L, "PerlinNoise");
3639 lua_setmetatable(L, -2);
3644 EnvRef(ServerEnvironment *env):
3647 //infostream<<"EnvRef created"<<std::endl;
3652 //infostream<<"EnvRef destructing"<<std::endl;
3655 // Creates an EnvRef and leaves it on top of stack
3656 // Not callable from Lua; all references are created on the C side.
3657 static void create(lua_State *L, ServerEnvironment *env)
3659 EnvRef *o = new EnvRef(env);
3660 //infostream<<"EnvRef::create: o="<<o<<std::endl;
3661 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
3662 luaL_getmetatable(L, className);
3663 lua_setmetatable(L, -2);
3666 static void set_null(lua_State *L)
3668 EnvRef *o = checkobject(L, -1);
3672 static void Register(lua_State *L)
3675 int methodtable = lua_gettop(L);
3676 luaL_newmetatable(L, className);
3677 int metatable = lua_gettop(L);
3679 lua_pushliteral(L, "__metatable");
3680 lua_pushvalue(L, methodtable);
3681 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
3683 lua_pushliteral(L, "__index");
3684 lua_pushvalue(L, methodtable);
3685 lua_settable(L, metatable);
3687 lua_pushliteral(L, "__gc");
3688 lua_pushcfunction(L, gc_object);
3689 lua_settable(L, metatable);
3691 lua_pop(L, 1); // drop metatable
3693 luaL_openlib(L, 0, methods, 0); // fill methodtable
3694 lua_pop(L, 1); // drop methodtable
3696 // Cannot be created from Lua
3697 //lua_register(L, className, create_object);
3700 const char EnvRef::className[] = "EnvRef";
3701 const luaL_reg EnvRef::methods[] = {
3702 method(EnvRef, set_node),
3703 method(EnvRef, add_node),
3704 method(EnvRef, remove_node),
3705 method(EnvRef, get_node),
3706 method(EnvRef, get_node_or_nil),
3707 method(EnvRef, get_node_light),
3708 method(EnvRef, place_node),
3709 method(EnvRef, dig_node),
3710 method(EnvRef, punch_node),
3711 method(EnvRef, add_entity),
3712 method(EnvRef, add_item),
3713 method(EnvRef, add_rat),
3714 method(EnvRef, add_firefly),
3715 method(EnvRef, get_meta),
3716 method(EnvRef, get_player_by_name),
3717 method(EnvRef, get_objects_inside_radius),
3718 method(EnvRef, set_timeofday),
3719 method(EnvRef, get_timeofday),
3720 method(EnvRef, find_node_near),
3721 method(EnvRef, find_nodes_in_area),
3722 method(EnvRef, get_perlin),
3731 class LuaPseudoRandom
3734 PseudoRandom m_pseudo;
3736 static const char className[];
3737 static const luaL_reg methods[];
3739 // Exported functions
3741 // garbage collector
3742 static int gc_object(lua_State *L)
3744 LuaPseudoRandom *o = *(LuaPseudoRandom **)(lua_touserdata(L, 1));
3749 // next(self, min=0, max=32767) -> get next value
3750 static int l_next(lua_State *L)
3752 LuaPseudoRandom *o = checkobject(L, 1);
3755 lua_settop(L, 3); // Fill 2 and 3 with nil if they don't exist
3756 if(!lua_isnil(L, 2))
3757 min = luaL_checkinteger(L, 2);
3758 if(!lua_isnil(L, 3))
3759 max = luaL_checkinteger(L, 3);
3760 if(max - min != 32767 && max - min > 32767/5)
3761 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.");
3762 PseudoRandom &pseudo = o->m_pseudo;
3763 int val = pseudo.next();
3764 val = (val % (max-min+1)) + min;
3765 lua_pushinteger(L, val);
3770 LuaPseudoRandom(int seed):
3779 const PseudoRandom& getItem() const
3783 PseudoRandom& getItem()
3788 // LuaPseudoRandom(seed)
3789 // Creates an LuaPseudoRandom and leaves it on top of stack
3790 static int create_object(lua_State *L)
3792 int seed = luaL_checknumber(L, 1);
3793 LuaPseudoRandom *o = new LuaPseudoRandom(seed);
3794 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
3795 luaL_getmetatable(L, className);
3796 lua_setmetatable(L, -2);
3800 static LuaPseudoRandom* checkobject(lua_State *L, int narg)
3802 luaL_checktype(L, narg, LUA_TUSERDATA);
3803 void *ud = luaL_checkudata(L, narg, className);
3804 if(!ud) luaL_typerror(L, narg, className);
3805 return *(LuaPseudoRandom**)ud; // unbox pointer
3808 static void Register(lua_State *L)
3811 int methodtable = lua_gettop(L);
3812 luaL_newmetatable(L, className);
3813 int metatable = lua_gettop(L);
3815 lua_pushliteral(L, "__metatable");
3816 lua_pushvalue(L, methodtable);
3817 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
3819 lua_pushliteral(L, "__index");
3820 lua_pushvalue(L, methodtable);
3821 lua_settable(L, metatable);
3823 lua_pushliteral(L, "__gc");
3824 lua_pushcfunction(L, gc_object);
3825 lua_settable(L, metatable);
3827 lua_pop(L, 1); // drop metatable
3829 luaL_openlib(L, 0, methods, 0); // fill methodtable
3830 lua_pop(L, 1); // drop methodtable
3832 // Can be created from Lua (LuaPseudoRandom(seed))
3833 lua_register(L, className, create_object);
3836 const char LuaPseudoRandom::className[] = "PseudoRandom";
3837 const luaL_reg LuaPseudoRandom::methods[] = {
3838 method(LuaPseudoRandom, next),
3848 class LuaABM : public ActiveBlockModifier
3854 std::set<std::string> m_trigger_contents;
3855 std::set<std::string> m_required_neighbors;
3856 float m_trigger_interval;
3857 u32 m_trigger_chance;
3859 LuaABM(lua_State *L, int id,
3860 const std::set<std::string> &trigger_contents,
3861 const std::set<std::string> &required_neighbors,
3862 float trigger_interval, u32 trigger_chance):
3865 m_trigger_contents(trigger_contents),
3866 m_required_neighbors(required_neighbors),
3867 m_trigger_interval(trigger_interval),
3868 m_trigger_chance(trigger_chance)
3871 virtual std::set<std::string> getTriggerContents()
3873 return m_trigger_contents;
3875 virtual std::set<std::string> getRequiredNeighbors()
3877 return m_required_neighbors;
3879 virtual float getTriggerInterval()
3881 return m_trigger_interval;
3883 virtual u32 getTriggerChance()
3885 return m_trigger_chance;
3887 virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n,
3888 u32 active_object_count, u32 active_object_count_wider)
3890 lua_State *L = m_lua;
3893 assert(lua_checkstack(L, 20));
3894 StackUnroller stack_unroller(L);
3896 // Get minetest.registered_abms
3897 lua_getglobal(L, "minetest");
3898 lua_getfield(L, -1, "registered_abms");
3899 luaL_checktype(L, -1, LUA_TTABLE);
3900 int registered_abms = lua_gettop(L);
3902 // Get minetest.registered_abms[m_id]
3903 lua_pushnumber(L, m_id);
3904 lua_gettable(L, registered_abms);
3905 if(lua_isnil(L, -1))
3909 luaL_checktype(L, -1, LUA_TTABLE);
3910 lua_getfield(L, -1, "action");
3911 luaL_checktype(L, -1, LUA_TFUNCTION);
3913 pushnode(L, n, env->getGameDef()->ndef());
3914 lua_pushnumber(L, active_object_count);
3915 lua_pushnumber(L, active_object_count_wider);
3916 if(lua_pcall(L, 4, 0, 0))
3917 script_error(L, "error: %s", lua_tostring(L, -1));
3925 static void read_server_sound_params(lua_State *L, int index,
3926 ServerSoundParams ¶ms)
3929 index = lua_gettop(L) + 1 + index;
3931 params = ServerSoundParams();
3932 if(lua_istable(L, index)){
3933 getfloatfield(L, index, "gain", params.gain);
3934 getstringfield(L, index, "to_player", params.to_player);
3935 lua_getfield(L, index, "pos");
3936 if(!lua_isnil(L, -1)){
3937 v3f p = read_v3f(L, -1)*BS;
3939 params.type = ServerSoundParams::SSP_POSITIONAL;
3942 lua_getfield(L, index, "object");
3943 if(!lua_isnil(L, -1)){
3944 ObjectRef *ref = ObjectRef::checkobject(L, -1);
3945 ServerActiveObject *sao = ObjectRef::getobject(ref);
3947 params.object = sao->getId();
3948 params.type = ServerSoundParams::SSP_OBJECT;
3952 params.max_hear_distance = BS*getfloatfield_default(L, index,
3953 "max_hear_distance", params.max_hear_distance/BS);
3954 getboolfield(L, index, "loop", params.loop);
3963 // Writes a line to dstream
3964 static int l_debug(lua_State *L)
3966 std::string text = lua_tostring(L, 1);
3967 dstream << text << std::endl;
3971 // log([level,] text)
3972 // Writes a line to the logger.
3973 // The one-argument version logs to infostream.
3974 // The two-argument version accept a log level: error, action, info, or verbose.
3975 static int l_log(lua_State *L)
3978 LogMessageLevel level = LMT_INFO;
3979 if(lua_isnone(L, 2))
3981 text = lua_tostring(L, 1);
3985 std::string levelname = lua_tostring(L, 1);
3986 text = lua_tostring(L, 2);
3987 if(levelname == "error")
3989 else if(levelname == "action")
3991 else if(levelname == "verbose")
3992 level = LMT_VERBOSE;
3994 log_printline(level, text);
3998 // register_item_raw({lots of stuff})
3999 static int l_register_item_raw(lua_State *L)
4001 luaL_checktype(L, 1, LUA_TTABLE);
4004 // Get the writable item and node definition managers from the server
4005 IWritableItemDefManager *idef =
4006 get_server(L)->getWritableItemDefManager();
4007 IWritableNodeDefManager *ndef =
4008 get_server(L)->getWritableNodeDefManager();
4010 // Check if name is defined
4012 lua_getfield(L, table, "name");
4013 if(lua_isstring(L, -1)){
4014 name = lua_tostring(L, -1);
4015 verbosestream<<"register_item_raw: "<<name<<std::endl;
4017 throw LuaError(L, "register_item_raw: name is not defined or not a string");
4020 // Check if on_use is defined
4023 // Set a distinctive default value to check if this is set
4024 def.node_placement_prediction = "__default";
4026 // Read the item definition
4027 def = read_item_definition(L, table, def);
4029 // Default to having client-side placement prediction for nodes
4030 // ("" in item definition sets it off)
4031 if(def.node_placement_prediction == "__default"){
4032 if(def.type == ITEM_NODE)
4033 def.node_placement_prediction = name;
4035 def.node_placement_prediction = "";
4038 // Register item definition
4039 idef->registerItem(def);
4041 // Read the node definition (content features) and register it
4042 if(def.type == ITEM_NODE)
4044 ContentFeatures f = read_content_features(L, table);
4045 ndef->set(f.name, f);
4048 return 0; /* number of results */
4051 // register_alias_raw(name, convert_to_name)
4052 static int l_register_alias_raw(lua_State *L)
4054 std::string name = luaL_checkstring(L, 1);
4055 std::string convert_to = luaL_checkstring(L, 2);
4057 // Get the writable item definition manager from the server
4058 IWritableItemDefManager *idef =
4059 get_server(L)->getWritableItemDefManager();
4061 idef->registerAlias(name, convert_to);
4063 return 0; /* number of results */
4066 // helper for register_craft
4067 static bool read_craft_recipe_shaped(lua_State *L, int index,
4068 int &width, std::vector<std::string> &recipe)
4071 index = lua_gettop(L) + 1 + index;
4073 if(!lua_istable(L, index))
4078 while(lua_next(L, index) != 0){
4080 // key at index -2 and value at index -1
4081 if(!lua_istable(L, -1))
4083 int table2 = lua_gettop(L);
4085 while(lua_next(L, table2) != 0){
4086 // key at index -2 and value at index -1
4087 if(!lua_isstring(L, -1))
4089 recipe.push_back(lua_tostring(L, -1));
4090 // removes value, keeps key for next iteration
4097 if(colcount != width)
4100 // removes value, keeps key for next iteration
4107 // helper for register_craft
4108 static bool read_craft_recipe_shapeless(lua_State *L, int index,
4109 std::vector<std::string> &recipe)
4112 index = lua_gettop(L) + 1 + index;
4114 if(!lua_istable(L, index))
4118 while(lua_next(L, index) != 0){
4119 // key at index -2 and value at index -1
4120 if(!lua_isstring(L, -1))
4122 recipe.push_back(lua_tostring(L, -1));
4123 // removes value, keeps key for next iteration
4129 // helper for register_craft
4130 static bool read_craft_replacements(lua_State *L, int index,
4131 CraftReplacements &replacements)
4134 index = lua_gettop(L) + 1 + index;
4136 if(!lua_istable(L, index))
4140 while(lua_next(L, index) != 0){
4141 // key at index -2 and value at index -1
4142 if(!lua_istable(L, -1))
4144 lua_rawgeti(L, -1, 1);
4145 if(!lua_isstring(L, -1))
4147 std::string replace_from = lua_tostring(L, -1);
4149 lua_rawgeti(L, -1, 2);
4150 if(!lua_isstring(L, -1))
4152 std::string replace_to = lua_tostring(L, -1);
4154 replacements.pairs.push_back(
4155 std::make_pair(replace_from, replace_to));
4156 // removes value, keeps key for next iteration
4161 // register_craft({output=item, recipe={{item00,item10},{item01,item11}})
4162 static int l_register_craft(lua_State *L)
4164 //infostream<<"register_craft"<<std::endl;
4165 luaL_checktype(L, 1, LUA_TTABLE);
4168 // Get the writable craft definition manager from the server
4169 IWritableCraftDefManager *craftdef =
4170 get_server(L)->getWritableCraftDefManager();
4172 std::string type = getstringfield_default(L, table, "type", "shaped");
4175 CraftDefinitionShaped
4177 if(type == "shaped"){
4178 std::string output = getstringfield_default(L, table, "output", "");
4180 throw LuaError(L, "Crafting definition is missing an output");
4183 std::vector<std::string> recipe;
4184 lua_getfield(L, table, "recipe");
4185 if(lua_isnil(L, -1))
4186 throw LuaError(L, "Crafting definition is missing a recipe"
4187 " (output=\"" + output + "\")");
4188 if(!read_craft_recipe_shaped(L, -1, width, recipe))
4189 throw LuaError(L, "Invalid crafting recipe"
4190 " (output=\"" + output + "\")");
4192 CraftReplacements replacements;
4193 lua_getfield(L, table, "replacements");
4194 if(!lua_isnil(L, -1))
4196 if(!read_craft_replacements(L, -1, replacements))
4197 throw LuaError(L, "Invalid replacements"
4198 " (output=\"" + output + "\")");
4201 CraftDefinition *def = new CraftDefinitionShaped(
4202 output, width, recipe, replacements);
4203 craftdef->registerCraft(def);
4206 CraftDefinitionShapeless
4208 else if(type == "shapeless"){
4209 std::string output = getstringfield_default(L, table, "output", "");
4211 throw LuaError(L, "Crafting definition (shapeless)"
4212 " is missing an output");
4214 std::vector<std::string> recipe;
4215 lua_getfield(L, table, "recipe");
4216 if(lua_isnil(L, -1))
4217 throw LuaError(L, "Crafting definition (shapeless)"
4218 " is missing a recipe"
4219 " (output=\"" + output + "\")");
4220 if(!read_craft_recipe_shapeless(L, -1, recipe))
4221 throw LuaError(L, "Invalid crafting recipe"
4222 " (output=\"" + output + "\")");
4224 CraftReplacements replacements;
4225 lua_getfield(L, table, "replacements");
4226 if(!lua_isnil(L, -1))
4228 if(!read_craft_replacements(L, -1, replacements))
4229 throw LuaError(L, "Invalid replacements"
4230 " (output=\"" + output + "\")");
4233 CraftDefinition *def = new CraftDefinitionShapeless(
4234 output, recipe, replacements);
4235 craftdef->registerCraft(def);
4238 CraftDefinitionToolRepair
4240 else if(type == "toolrepair"){
4241 float additional_wear = getfloatfield_default(L, table,
4242 "additional_wear", 0.0);
4244 CraftDefinition *def = new CraftDefinitionToolRepair(
4246 craftdef->registerCraft(def);
4249 CraftDefinitionCooking
4251 else if(type == "cooking"){
4252 std::string output = getstringfield_default(L, table, "output", "");
4254 throw LuaError(L, "Crafting definition (cooking)"
4255 " is missing an output");
4257 std::string recipe = getstringfield_default(L, table, "recipe", "");
4259 throw LuaError(L, "Crafting definition (cooking)"
4260 " is missing a recipe"
4261 " (output=\"" + output + "\")");
4263 float cooktime = getfloatfield_default(L, table, "cooktime", 3.0);
4265 CraftReplacements replacements;
4266 lua_getfield(L, table, "replacements");
4267 if(!lua_isnil(L, -1))
4269 if(!read_craft_replacements(L, -1, replacements))
4270 throw LuaError(L, "Invalid replacements"
4271 " (cooking output=\"" + output + "\")");
4274 CraftDefinition *def = new CraftDefinitionCooking(
4275 output, recipe, cooktime, replacements);
4276 craftdef->registerCraft(def);
4281 else if(type == "fuel"){
4282 std::string recipe = getstringfield_default(L, table, "recipe", "");
4284 throw LuaError(L, "Crafting definition (fuel)"
4285 " is missing a recipe");
4287 float burntime = getfloatfield_default(L, table, "burntime", 1.0);
4289 CraftReplacements replacements;
4290 lua_getfield(L, table, "replacements");
4291 if(!lua_isnil(L, -1))
4293 if(!read_craft_replacements(L, -1, replacements))
4294 throw LuaError(L, "Invalid replacements"
4295 " (fuel recipe=\"" + recipe + "\")");
4298 CraftDefinition *def = new CraftDefinitionFuel(
4299 recipe, burntime, replacements);
4300 craftdef->registerCraft(def);
4304 throw LuaError(L, "Unknown crafting definition type: \"" + type + "\"");
4308 return 0; /* number of results */
4311 // setting_set(name, value)
4312 static int l_setting_set(lua_State *L)
4314 const char *name = luaL_checkstring(L, 1);
4315 const char *value = luaL_checkstring(L, 2);
4316 g_settings->set(name, value);
4320 // setting_get(name)
4321 static int l_setting_get(lua_State *L)
4323 const char *name = luaL_checkstring(L, 1);
4325 std::string value = g_settings->get(name);
4326 lua_pushstring(L, value.c_str());
4327 } catch(SettingNotFoundException &e){
4333 // setting_getbool(name)
4334 static int l_setting_getbool(lua_State *L)
4336 const char *name = luaL_checkstring(L, 1);
4338 bool value = g_settings->getBool(name);
4339 lua_pushboolean(L, value);
4340 } catch(SettingNotFoundException &e){
4346 // chat_send_all(text)
4347 static int l_chat_send_all(lua_State *L)
4349 const char *text = luaL_checkstring(L, 1);
4350 // Get server from registry
4351 Server *server = get_server(L);
4353 server->notifyPlayers(narrow_to_wide(text));
4357 // chat_send_player(name, text)
4358 static int l_chat_send_player(lua_State *L)
4360 const char *name = luaL_checkstring(L, 1);
4361 const char *text = luaL_checkstring(L, 2);
4362 // Get server from registry
4363 Server *server = get_server(L);
4365 server->notifyPlayer(name, narrow_to_wide(text));
4369 // get_player_privs(name, text)
4370 static int l_get_player_privs(lua_State *L)
4372 const char *name = luaL_checkstring(L, 1);
4373 // Get server from registry
4374 Server *server = get_server(L);
4377 int table = lua_gettop(L);
4378 std::set<std::string> privs_s = server->getPlayerEffectivePrivs(name);
4379 for(std::set<std::string>::const_iterator
4380 i = privs_s.begin(); i != privs_s.end(); i++){
4381 lua_pushboolean(L, true);
4382 lua_setfield(L, table, i->c_str());
4384 lua_pushvalue(L, table);
4388 // get_inventory(location)
4389 static int l_get_inventory(lua_State *L)
4391 InventoryLocation loc;
4393 std::string type = checkstringfield(L, 1, "type");
4394 if(type == "player"){
4395 std::string name = checkstringfield(L, 1, "name");
4396 loc.setPlayer(name);
4397 } else if(type == "node"){
4398 lua_getfield(L, 1, "pos");
4399 v3s16 pos = check_v3s16(L, -1);
4400 loc.setNodeMeta(pos);
4403 if(get_server(L)->getInventory(loc) != NULL)
4404 InvRef::create(L, loc);
4410 // get_dig_params(groups, tool_capabilities[, time_from_last_punch])
4411 static int l_get_dig_params(lua_State *L)
4413 std::map<std::string, int> groups;
4414 read_groups(L, 1, groups);
4415 ToolCapabilities tp = read_tool_capabilities(L, 2);
4416 if(lua_isnoneornil(L, 3))
4417 push_dig_params(L, getDigParams(groups, &tp));
4419 push_dig_params(L, getDigParams(groups, &tp,
4420 luaL_checknumber(L, 3)));
4424 // get_hit_params(groups, tool_capabilities[, time_from_last_punch])
4425 static int l_get_hit_params(lua_State *L)
4427 std::map<std::string, int> groups;
4428 read_groups(L, 1, groups);
4429 ToolCapabilities tp = read_tool_capabilities(L, 2);
4430 if(lua_isnoneornil(L, 3))
4431 push_hit_params(L, getHitParams(groups, &tp));
4433 push_hit_params(L, getHitParams(groups, &tp,
4434 luaL_checknumber(L, 3)));
4438 // get_current_modname()
4439 static int l_get_current_modname(lua_State *L)
4441 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
4445 // get_modpath(modname)
4446 static int l_get_modpath(lua_State *L)
4448 std::string modname = luaL_checkstring(L, 1);
4450 if(modname == "__builtin"){
4451 std::string path = get_server(L)->getBuiltinLuaPath();
4452 lua_pushstring(L, path.c_str());
4455 const ModSpec *mod = get_server(L)->getModSpec(modname);
4460 lua_pushstring(L, mod->path.c_str());
4465 static int l_get_worldpath(lua_State *L)
4467 std::string worldpath = get_server(L)->getWorldPath();
4468 lua_pushstring(L, worldpath.c_str());
4472 // sound_play(spec, parameters)
4473 static int l_sound_play(lua_State *L)
4475 SimpleSoundSpec spec;
4476 read_soundspec(L, 1, spec);
4477 ServerSoundParams params;
4478 read_server_sound_params(L, 2, params);
4479 s32 handle = get_server(L)->playSound(spec, params);
4480 lua_pushinteger(L, handle);
4484 // sound_stop(handle)
4485 static int l_sound_stop(lua_State *L)
4487 int handle = luaL_checkinteger(L, 1);
4488 get_server(L)->stopSound(handle);
4492 // is_singleplayer()
4493 static int l_is_singleplayer(lua_State *L)
4495 lua_pushboolean(L, get_server(L)->isSingleplayer());
4499 // get_password_hash(name, raw_password)
4500 static int l_get_password_hash(lua_State *L)
4502 std::string name = luaL_checkstring(L, 1);
4503 std::string raw_password = luaL_checkstring(L, 2);
4504 std::string hash = translatePassword(name,
4505 narrow_to_wide(raw_password));
4506 lua_pushstring(L, hash.c_str());
4510 // notify_authentication_modified(name)
4511 static int l_notify_authentication_modified(lua_State *L)
4513 std::string name = "";
4514 if(lua_isstring(L, 1))
4515 name = lua_tostring(L, 1);
4516 get_server(L)->reportPrivsModified(name);
4520 // get_craft_result(input)
4521 static int l_get_craft_result(lua_State *L)
4524 std::string method_s = getstringfield_default(L, input_i, "method", "normal");
4525 enum CraftMethod method = (CraftMethod)getenumfield(L, input_i, "method",
4526 es_CraftMethod, CRAFT_METHOD_NORMAL);
4528 lua_getfield(L, input_i, "width");
4529 if(lua_isnumber(L, -1))
4530 width = luaL_checkinteger(L, -1);
4532 lua_getfield(L, input_i, "items");
4533 std::vector<ItemStack> items = read_items(L, -1);
4534 lua_pop(L, 1); // items
4536 IGameDef *gdef = get_server(L);
4537 ICraftDefManager *cdef = gdef->cdef();
4538 CraftInput input(method, width, items);
4540 bool got = cdef->getCraftResult(input, output, true, gdef);
4541 lua_newtable(L); // output table
4544 item.deSerialize(output.item, gdef->idef());
4545 LuaItemStack::create(L, item);
4546 lua_setfield(L, -2, "item");
4547 setintfield(L, -1, "time", output.time);
4549 LuaItemStack::create(L, ItemStack());
4550 lua_setfield(L, -2, "item");
4551 setintfield(L, -1, "time", 0);
4553 lua_newtable(L); // decremented input table
4554 lua_pushstring(L, method_s.c_str());
4555 lua_setfield(L, -2, "method");
4556 lua_pushinteger(L, width);
4557 lua_setfield(L, -2, "width");
4558 push_items(L, input.items);
4559 lua_setfield(L, -2, "items");
4563 // get_craft_recipe(result item)
4564 static int l_get_craft_recipe(lua_State *L)
4569 std::string o_item = luaL_checkstring(L,input_i);
4571 IGameDef *gdef = get_server(L);
4572 ICraftDefManager *cdef = gdef->cdef();
4574 CraftOutput output(o_item,0);
4575 bool got = cdef->getCraftRecipe(input, output, gdef);
4576 lua_newtable(L); // output table
4579 for(std::vector<ItemStack>::const_iterator
4580 i = input.items.begin();
4581 i != input.items.end(); i++, k++)
4587 sprintf(tmp,"%d",k);
4588 lua_pushstring(L,tmp);
4589 lua_pushstring(L,i->name.c_str());
4590 lua_settable(L, -3);
4592 lua_setfield(L, -2, "items");
4593 setintfield(L, -1, "width", input.width);
4594 switch (input.method) {
4595 case CRAFT_METHOD_NORMAL:
4596 lua_pushstring(L,"noraml");
4598 case CRAFT_METHOD_COOKING:
4599 lua_pushstring(L,"cooking");
4601 case CRAFT_METHOD_FUEL:
4602 lua_pushstring(L,"fuel");
4605 lua_pushstring(L,"unknown");
4607 lua_setfield(L, -2, "type");
4610 lua_setfield(L, -2, "items");
4611 setintfield(L, -1, "width", 0);
4616 static const struct luaL_Reg minetest_f [] = {
4619 {"register_item_raw", l_register_item_raw},
4620 {"register_alias_raw", l_register_alias_raw},
4621 {"register_craft", l_register_craft},
4622 {"setting_set", l_setting_set},
4623 {"setting_get", l_setting_get},
4624 {"setting_getbool", l_setting_getbool},
4625 {"chat_send_all", l_chat_send_all},
4626 {"chat_send_player", l_chat_send_player},
4627 {"get_player_privs", l_get_player_privs},
4628 {"get_inventory", l_get_inventory},
4629 {"get_dig_params", l_get_dig_params},
4630 {"get_hit_params", l_get_hit_params},
4631 {"get_current_modname", l_get_current_modname},
4632 {"get_modpath", l_get_modpath},
4633 {"get_worldpath", l_get_worldpath},
4634 {"sound_play", l_sound_play},
4635 {"sound_stop", l_sound_stop},
4636 {"is_singleplayer", l_is_singleplayer},
4637 {"get_password_hash", l_get_password_hash},
4638 {"notify_authentication_modified", l_notify_authentication_modified},
4639 {"get_craft_result", l_get_craft_result},
4640 {"get_craft_recipe", l_get_craft_recipe},
4645 Main export function
4648 void scriptapi_export(lua_State *L, Server *server)
4651 assert(lua_checkstack(L, 20));
4652 verbosestream<<"scriptapi_export()"<<std::endl;
4653 StackUnroller stack_unroller(L);
4655 // Store server as light userdata in registry
4656 lua_pushlightuserdata(L, server);
4657 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_server");
4659 // Register global functions in table minetest
4661 luaL_register(L, NULL, minetest_f);
4662 lua_setglobal(L, "minetest");
4664 // Get the main minetest table
4665 lua_getglobal(L, "minetest");
4667 // Add tables to minetest
4669 lua_setfield(L, -2, "object_refs");
4671 lua_setfield(L, -2, "luaentities");
4673 // Register wrappers
4674 LuaItemStack::Register(L);
4675 InvRef::Register(L);
4676 NodeMetaRef::Register(L);
4677 ObjectRef::Register(L);
4678 EnvRef::Register(L);
4679 LuaPseudoRandom::Register(L);
4680 LuaPerlinNoise::Register(L);
4683 bool scriptapi_loadmod(lua_State *L, const std::string &scriptpath,
4684 const std::string &modname)
4686 ModNameStorer modnamestorer(L, modname);
4688 if(!string_allowed(modname, "abcdefghijklmnopqrstuvwxyz"
4690 errorstream<<"Error loading mod \""<<modname
4691 <<"\": modname does not follow naming conventions: "
4692 <<"Only chararacters [a-z0-9_] are allowed."<<std::endl;
4696 bool success = false;
4699 success = script_load(L, scriptpath.c_str());
4702 errorstream<<"Error loading mod \""<<modname
4703 <<"\": "<<e.what()<<std::endl;
4709 void scriptapi_add_environment(lua_State *L, ServerEnvironment *env)
4712 assert(lua_checkstack(L, 20));
4713 verbosestream<<"scriptapi_add_environment"<<std::endl;
4714 StackUnroller stack_unroller(L);
4716 // Create EnvRef on stack
4717 EnvRef::create(L, env);
4718 int envref = lua_gettop(L);
4720 // minetest.env = envref
4721 lua_getglobal(L, "minetest");
4722 luaL_checktype(L, -1, LUA_TTABLE);
4723 lua_pushvalue(L, envref);
4724 lua_setfield(L, -2, "env");
4726 // Store environment as light userdata in registry
4727 lua_pushlightuserdata(L, env);
4728 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_env");
4731 Add ActiveBlockModifiers to environment
4734 // Get minetest.registered_abms
4735 lua_getglobal(L, "minetest");
4736 lua_getfield(L, -1, "registered_abms");
4737 luaL_checktype(L, -1, LUA_TTABLE);
4738 int registered_abms = lua_gettop(L);
4740 if(lua_istable(L, registered_abms)){
4741 int table = lua_gettop(L);
4743 while(lua_next(L, table) != 0){
4744 // key at index -2 and value at index -1
4745 int id = lua_tonumber(L, -2);
4746 int current_abm = lua_gettop(L);
4748 std::set<std::string> trigger_contents;
4749 lua_getfield(L, current_abm, "nodenames");
4750 if(lua_istable(L, -1)){
4751 int table = lua_gettop(L);
4753 while(lua_next(L, table) != 0){
4754 // key at index -2 and value at index -1
4755 luaL_checktype(L, -1, LUA_TSTRING);
4756 trigger_contents.insert(lua_tostring(L, -1));
4757 // removes value, keeps key for next iteration
4760 } else if(lua_isstring(L, -1)){
4761 trigger_contents.insert(lua_tostring(L, -1));
4765 std::set<std::string> required_neighbors;
4766 lua_getfield(L, current_abm, "neighbors");
4767 if(lua_istable(L, -1)){
4768 int table = lua_gettop(L);
4770 while(lua_next(L, table) != 0){
4771 // key at index -2 and value at index -1
4772 luaL_checktype(L, -1, LUA_TSTRING);
4773 required_neighbors.insert(lua_tostring(L, -1));
4774 // removes value, keeps key for next iteration
4777 } else if(lua_isstring(L, -1)){
4778 required_neighbors.insert(lua_tostring(L, -1));
4782 float trigger_interval = 10.0;
4783 getfloatfield(L, current_abm, "interval", trigger_interval);
4785 int trigger_chance = 50;
4786 getintfield(L, current_abm, "chance", trigger_chance);
4788 LuaABM *abm = new LuaABM(L, id, trigger_contents,
4789 required_neighbors, trigger_interval, trigger_chance);
4791 env->addActiveBlockModifier(abm);
4793 // removes value, keeps key for next iteration
4801 // Dump stack top with the dump2 function
4802 static void dump2(lua_State *L, const char *name)
4804 // Dump object (debug)
4805 lua_getglobal(L, "dump2");
4806 luaL_checktype(L, -1, LUA_TFUNCTION);
4807 lua_pushvalue(L, -2); // Get previous stack top as first parameter
4808 lua_pushstring(L, name);
4809 if(lua_pcall(L, 2, 0, 0))
4810 script_error(L, "error: %s", lua_tostring(L, -1));
4818 void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj)
4821 assert(lua_checkstack(L, 20));
4822 //infostream<<"scriptapi_add_object_reference: id="<<cobj->getId()<<std::endl;
4823 StackUnroller stack_unroller(L);
4825 // Create object on stack
4826 ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack
4827 int object = lua_gettop(L);
4829 // Get minetest.object_refs table
4830 lua_getglobal(L, "minetest");
4831 lua_getfield(L, -1, "object_refs");
4832 luaL_checktype(L, -1, LUA_TTABLE);
4833 int objectstable = lua_gettop(L);
4835 // object_refs[id] = object
4836 lua_pushnumber(L, cobj->getId()); // Push id
4837 lua_pushvalue(L, object); // Copy object to top of stack
4838 lua_settable(L, objectstable);
4841 void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj)
4844 assert(lua_checkstack(L, 20));
4845 //infostream<<"scriptapi_rm_object_reference: id="<<cobj->getId()<<std::endl;
4846 StackUnroller stack_unroller(L);
4848 // Get minetest.object_refs table
4849 lua_getglobal(L, "minetest");
4850 lua_getfield(L, -1, "object_refs");
4851 luaL_checktype(L, -1, LUA_TTABLE);
4852 int objectstable = lua_gettop(L);
4854 // Get object_refs[id]
4855 lua_pushnumber(L, cobj->getId()); // Push id
4856 lua_gettable(L, objectstable);
4857 // Set object reference to NULL
4858 ObjectRef::set_null(L);
4859 lua_pop(L, 1); // pop object
4861 // Set object_refs[id] = nil
4862 lua_pushnumber(L, cobj->getId()); // Push id
4864 lua_settable(L, objectstable);
4871 // What scriptapi_run_callbacks does with the return values of callbacks.
4872 // Regardless of the mode, if only one callback is defined,
4873 // its return value is the total return value.
4874 // Modes only affect the case where 0 or >= 2 callbacks are defined.
4875 enum RunCallbacksMode
4877 // Returns the return value of the first callback
4878 // Returns nil if list of callbacks is empty
4879 RUN_CALLBACKS_MODE_FIRST,
4880 // Returns the return value of the last callback
4881 // Returns nil if list of callbacks is empty
4882 RUN_CALLBACKS_MODE_LAST,
4883 // If any callback returns a false value, the first such is returned
4884 // Otherwise, the first callback's return value (trueish) is returned
4885 // Returns true if list of callbacks is empty
4886 RUN_CALLBACKS_MODE_AND,
4887 // Like above, but stops calling callbacks (short circuit)
4888 // after seeing the first false value
4889 RUN_CALLBACKS_MODE_AND_SC,
4890 // If any callback returns a true value, the first such is returned
4891 // Otherwise, the first callback's return value (falseish) is returned
4892 // Returns false if list of callbacks is empty
4893 RUN_CALLBACKS_MODE_OR,
4894 // Like above, but stops calling callbacks (short circuit)
4895 // after seeing the first true value
4896 RUN_CALLBACKS_MODE_OR_SC,
4897 // Note: "a true value" and "a false value" refer to values that
4898 // are converted by lua_toboolean to true or false, respectively.
4901 // Push the list of callbacks (a lua table).
4902 // Then push nargs arguments.
4903 // Then call this function, which
4904 // - runs the callbacks
4905 // - removes the table and arguments from the lua stack
4906 // - pushes the return value, computed depending on mode
4907 static void scriptapi_run_callbacks(lua_State *L, int nargs,
4908 RunCallbacksMode mode)
4910 // Insert the return value into the lua stack, below the table
4911 assert(lua_gettop(L) >= nargs + 1);
4913 lua_insert(L, -(nargs + 1) - 1);
4914 // Stack now looks like this:
4915 // ... <return value = nil> <table> <arg#1> <arg#2> ... <arg#n>
4917 int rv = lua_gettop(L) - nargs - 1;
4919 int arg = table + 1;
4921 luaL_checktype(L, table, LUA_TTABLE);
4925 bool first_loop = true;
4926 while(lua_next(L, table) != 0){
4927 // key at index -2 and value at index -1
4928 luaL_checktype(L, -1, LUA_TFUNCTION);
4930 for(int i = 0; i < nargs; i++)
4931 lua_pushvalue(L, arg+i);
4932 if(lua_pcall(L, nargs, 1, 0))
4933 script_error(L, "error: %s", lua_tostring(L, -1));
4935 // Move return value to designated space in stack
4938 // Result of first callback is always moved
4942 // Otherwise, what happens depends on the mode
4943 if(mode == RUN_CALLBACKS_MODE_FIRST)
4945 else if(mode == RUN_CALLBACKS_MODE_LAST)
4947 else if(mode == RUN_CALLBACKS_MODE_AND ||
4948 mode == RUN_CALLBACKS_MODE_AND_SC){
4949 if(lua_toboolean(L, rv) == true &&
4950 lua_toboolean(L, -1) == false)
4955 else if(mode == RUN_CALLBACKS_MODE_OR ||
4956 mode == RUN_CALLBACKS_MODE_OR_SC){
4957 if(lua_toboolean(L, rv) == false &&
4958 lua_toboolean(L, -1) == true)
4967 // Handle short circuit modes
4968 if(mode == RUN_CALLBACKS_MODE_AND_SC &&
4969 lua_toboolean(L, rv) == false)
4971 else if(mode == RUN_CALLBACKS_MODE_OR_SC &&
4972 lua_toboolean(L, rv) == true)
4975 // value removed, keep key for next iteration
4978 // Remove stuff from stack, leaving only the return value
4981 // Fix return value in case no callbacks were called
4983 if(mode == RUN_CALLBACKS_MODE_AND ||
4984 mode == RUN_CALLBACKS_MODE_AND_SC){
4986 lua_pushboolean(L, true);
4988 else if(mode == RUN_CALLBACKS_MODE_OR ||
4989 mode == RUN_CALLBACKS_MODE_OR_SC){
4991 lua_pushboolean(L, false);
4996 bool scriptapi_on_chat_message(lua_State *L, const std::string &name,
4997 const std::string &message)
5000 assert(lua_checkstack(L, 20));
5001 StackUnroller stack_unroller(L);
5003 // Get minetest.registered_on_chat_messages
5004 lua_getglobal(L, "minetest");
5005 lua_getfield(L, -1, "registered_on_chat_messages");
5007 lua_pushstring(L, name.c_str());
5008 lua_pushstring(L, message.c_str());
5009 scriptapi_run_callbacks(L, 2, RUN_CALLBACKS_MODE_OR_SC);
5010 bool ate = lua_toboolean(L, -1);
5014 void scriptapi_on_newplayer(lua_State *L, ServerActiveObject *player)
5017 assert(lua_checkstack(L, 20));
5018 StackUnroller stack_unroller(L);
5020 // Get minetest.registered_on_newplayers
5021 lua_getglobal(L, "minetest");
5022 lua_getfield(L, -1, "registered_on_newplayers");
5024 objectref_get_or_create(L, player);
5025 scriptapi_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
5028 void scriptapi_on_dieplayer(lua_State *L, ServerActiveObject *player)
5031 assert(lua_checkstack(L, 20));
5032 StackUnroller stack_unroller(L);
5034 // Get minetest.registered_on_dieplayers
5035 lua_getglobal(L, "minetest");
5036 lua_getfield(L, -1, "registered_on_dieplayers");
5038 objectref_get_or_create(L, player);
5039 scriptapi_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
5042 bool scriptapi_on_respawnplayer(lua_State *L, ServerActiveObject *player)
5045 assert(lua_checkstack(L, 20));
5046 StackUnroller stack_unroller(L);
5048 // Get minetest.registered_on_respawnplayers
5049 lua_getglobal(L, "minetest");
5050 lua_getfield(L, -1, "registered_on_respawnplayers");
5052 objectref_get_or_create(L, player);
5053 scriptapi_run_callbacks(L, 1, RUN_CALLBACKS_MODE_OR);
5054 bool positioning_handled_by_some = lua_toboolean(L, -1);
5055 return positioning_handled_by_some;
5058 void scriptapi_on_joinplayer(lua_State *L, ServerActiveObject *player)
5061 assert(lua_checkstack(L, 20));
5062 StackUnroller stack_unroller(L);
5064 // Get minetest.registered_on_joinplayers
5065 lua_getglobal(L, "minetest");
5066 lua_getfield(L, -1, "registered_on_joinplayers");
5068 objectref_get_or_create(L, player);
5069 scriptapi_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
5072 void scriptapi_on_leaveplayer(lua_State *L, ServerActiveObject *player)
5075 assert(lua_checkstack(L, 20));
5076 StackUnroller stack_unroller(L);
5078 // Get minetest.registered_on_leaveplayers
5079 lua_getglobal(L, "minetest");
5080 lua_getfield(L, -1, "registered_on_leaveplayers");
5082 objectref_get_or_create(L, player);
5083 scriptapi_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
5086 void scriptapi_get_creative_inventory(lua_State *L, ServerActiveObject *player)
5089 assert(lua_checkstack(L, 20));
5090 StackUnroller stack_unroller(L);
5092 Inventory *inv = player->getInventory();
5095 lua_getglobal(L, "minetest");
5096 lua_getfield(L, -1, "creative_inventory");
5097 luaL_checktype(L, -1, LUA_TTABLE);
5098 inventory_set_list_from_lua(inv, "main", L, -1, PLAYER_INVENTORY_SIZE);
5101 static void get_auth_handler(lua_State *L)
5103 lua_getglobal(L, "minetest");
5104 lua_getfield(L, -1, "registered_auth_handler");
5105 if(lua_isnil(L, -1)){
5107 lua_getfield(L, -1, "builtin_auth_handler");
5109 if(lua_type(L, -1) != LUA_TTABLE)
5110 throw LuaError(L, "Authentication handler table not valid");
5113 bool scriptapi_get_auth(lua_State *L, const std::string &playername,
5114 std::string *dst_password, std::set<std::string> *dst_privs)
5117 assert(lua_checkstack(L, 20));
5118 StackUnroller stack_unroller(L);
5120 get_auth_handler(L);
5121 lua_getfield(L, -1, "get_auth");
5122 if(lua_type(L, -1) != LUA_TFUNCTION)
5123 throw LuaError(L, "Authentication handler missing get_auth");
5124 lua_pushstring(L, playername.c_str());
5125 if(lua_pcall(L, 1, 1, 0))
5126 script_error(L, "error: %s", lua_tostring(L, -1));
5128 // nil = login not allowed
5129 if(lua_isnil(L, -1))
5131 luaL_checktype(L, -1, LUA_TTABLE);
5133 std::string password;
5134 bool found = getstringfield(L, -1, "password", password);
5136 throw LuaError(L, "Authentication handler didn't return password");
5138 *dst_password = password;
5140 lua_getfield(L, -1, "privileges");
5141 if(!lua_istable(L, -1))
5143 "Authentication handler didn't return privilege table");
5145 read_privileges(L, -1, *dst_privs);
5151 void scriptapi_create_auth(lua_State *L, const std::string &playername,
5152 const std::string &password)
5155 assert(lua_checkstack(L, 20));
5156 StackUnroller stack_unroller(L);
5158 get_auth_handler(L);
5159 lua_getfield(L, -1, "create_auth");
5160 if(lua_type(L, -1) != LUA_TFUNCTION)
5161 throw LuaError(L, "Authentication handler missing create_auth");
5162 lua_pushstring(L, playername.c_str());
5163 lua_pushstring(L, password.c_str());
5164 if(lua_pcall(L, 2, 0, 0))
5165 script_error(L, "error: %s", lua_tostring(L, -1));
5168 bool scriptapi_set_password(lua_State *L, const std::string &playername,
5169 const std::string &password)
5172 assert(lua_checkstack(L, 20));
5173 StackUnroller stack_unroller(L);
5175 get_auth_handler(L);
5176 lua_getfield(L, -1, "set_password");
5177 if(lua_type(L, -1) != LUA_TFUNCTION)
5178 throw LuaError(L, "Authentication handler missing set_password");
5179 lua_pushstring(L, playername.c_str());
5180 lua_pushstring(L, password.c_str());
5181 if(lua_pcall(L, 2, 1, 0))
5182 script_error(L, "error: %s", lua_tostring(L, -1));
5183 return lua_toboolean(L, -1);
5187 item callbacks and node callbacks
5190 // Retrieves minetest.registered_items[name][callbackname]
5191 // If that is nil or on error, return false and stack is unchanged
5192 // If that is a function, returns true and pushes the
5193 // function onto the stack
5194 static bool get_item_callback(lua_State *L,
5195 const char *name, const char *callbackname)
5197 lua_getglobal(L, "minetest");
5198 lua_getfield(L, -1, "registered_items");
5200 luaL_checktype(L, -1, LUA_TTABLE);
5201 lua_getfield(L, -1, name);
5203 // Should be a table
5204 if(lua_type(L, -1) != LUA_TTABLE)
5206 errorstream<<"Item \""<<name<<"\" not defined"<<std::endl;
5210 lua_getfield(L, -1, callbackname);
5212 // Should be a function or nil
5213 if(lua_type(L, -1) == LUA_TFUNCTION)
5217 else if(lua_isnil(L, -1))
5224 errorstream<<"Item \""<<name<<"\" callback \""
5225 <<callbackname<<" is not a function"<<std::endl;
5231 bool scriptapi_item_on_drop(lua_State *L, ItemStack &item,
5232 ServerActiveObject *dropper, v3f pos)
5235 assert(lua_checkstack(L, 20));
5236 StackUnroller stack_unroller(L);
5238 // Push callback function on stack
5239 if(!get_item_callback(L, item.name.c_str(), "on_drop"))
5243 LuaItemStack::create(L, item);
5244 objectref_get_or_create(L, dropper);
5245 pushFloatPos(L, pos);
5246 if(lua_pcall(L, 3, 1, 0))
5247 script_error(L, "error: %s", lua_tostring(L, -1));
5248 if(!lua_isnil(L, -1))
5249 item = read_item(L, -1);
5253 bool scriptapi_item_on_place(lua_State *L, ItemStack &item,
5254 ServerActiveObject *placer, const PointedThing &pointed)
5257 assert(lua_checkstack(L, 20));
5258 StackUnroller stack_unroller(L);
5260 // Push callback function on stack
5261 if(!get_item_callback(L, item.name.c_str(), "on_place"))
5265 LuaItemStack::create(L, item);
5266 objectref_get_or_create(L, placer);
5267 push_pointed_thing(L, pointed);
5268 if(lua_pcall(L, 3, 1, 0))
5269 script_error(L, "error: %s", lua_tostring(L, -1));
5270 if(!lua_isnil(L, -1))
5271 item = read_item(L, -1);
5275 bool scriptapi_item_on_use(lua_State *L, ItemStack &item,
5276 ServerActiveObject *user, const PointedThing &pointed)
5279 assert(lua_checkstack(L, 20));
5280 StackUnroller stack_unroller(L);
5282 // Push callback function on stack
5283 if(!get_item_callback(L, item.name.c_str(), "on_use"))
5287 LuaItemStack::create(L, item);
5288 objectref_get_or_create(L, user);
5289 push_pointed_thing(L, pointed);
5290 if(lua_pcall(L, 3, 1, 0))
5291 script_error(L, "error: %s", lua_tostring(L, -1));
5292 if(!lua_isnil(L, -1))
5293 item = read_item(L, -1);
5297 bool scriptapi_node_on_punch(lua_State *L, v3s16 p, MapNode node,
5298 ServerActiveObject *puncher)
5301 assert(lua_checkstack(L, 20));
5302 StackUnroller stack_unroller(L);
5304 INodeDefManager *ndef = get_server(L)->ndef();
5306 // Push callback function on stack
5307 if(!get_item_callback(L, ndef->get(node).name.c_str(), "on_punch"))
5312 pushnode(L, node, ndef);
5313 objectref_get_or_create(L, puncher);
5314 if(lua_pcall(L, 3, 0, 0))
5315 script_error(L, "error: %s", lua_tostring(L, -1));
5319 bool scriptapi_node_on_dig(lua_State *L, v3s16 p, MapNode node,
5320 ServerActiveObject *digger)
5323 assert(lua_checkstack(L, 20));
5324 StackUnroller stack_unroller(L);
5326 INodeDefManager *ndef = get_server(L)->ndef();
5328 // Push callback function on stack
5329 if(!get_item_callback(L, ndef->get(node).name.c_str(), "on_dig"))
5334 pushnode(L, node, ndef);
5335 objectref_get_or_create(L, digger);
5336 if(lua_pcall(L, 3, 0, 0))
5337 script_error(L, "error: %s", lua_tostring(L, -1));
5341 void scriptapi_node_on_construct(lua_State *L, v3s16 p, MapNode node)
5344 assert(lua_checkstack(L, 20));
5345 StackUnroller stack_unroller(L);
5347 INodeDefManager *ndef = get_server(L)->ndef();
5349 // Push callback function on stack
5350 if(!get_item_callback(L, ndef->get(node).name.c_str(), "on_construct"))
5355 if(lua_pcall(L, 1, 0, 0))
5356 script_error(L, "error: %s", lua_tostring(L, -1));
5359 void scriptapi_node_on_destruct(lua_State *L, v3s16 p, MapNode node)
5362 assert(lua_checkstack(L, 20));
5363 StackUnroller stack_unroller(L);
5365 INodeDefManager *ndef = get_server(L)->ndef();
5367 // Push callback function on stack
5368 if(!get_item_callback(L, ndef->get(node).name.c_str(), "on_destruct"))
5373 if(lua_pcall(L, 1, 0, 0))
5374 script_error(L, "error: %s", lua_tostring(L, -1));
5377 void scriptapi_node_after_destruct(lua_State *L, v3s16 p, MapNode node)
5380 assert(lua_checkstack(L, 20));
5381 StackUnroller stack_unroller(L);
5383 INodeDefManager *ndef = get_server(L)->ndef();
5385 // Push callback function on stack
5386 if(!get_item_callback(L, ndef->get(node).name.c_str(), "after_destruct"))
5391 pushnode(L, node, ndef);
5392 if(lua_pcall(L, 2, 0, 0))
5393 script_error(L, "error: %s", lua_tostring(L, -1));
5396 void scriptapi_node_on_receive_fields(lua_State *L, v3s16 p,
5397 const std::string &formname,
5398 const std::map<std::string, std::string> &fields,
5399 ServerActiveObject *sender)
5402 assert(lua_checkstack(L, 20));
5403 StackUnroller stack_unroller(L);
5405 INodeDefManager *ndef = get_server(L)->ndef();
5407 // If node doesn't exist, we don't know what callback to call
5408 MapNode node = get_env(L)->getMap().getNodeNoEx(p);
5409 if(node.getContent() == CONTENT_IGNORE)
5412 // Push callback function on stack
5413 if(!get_item_callback(L, ndef->get(node).name.c_str(), "on_receive_fields"))
5420 lua_pushstring(L, formname.c_str());
5423 for(std::map<std::string, std::string>::const_iterator
5424 i = fields.begin(); i != fields.end(); i++){
5425 const std::string &name = i->first;
5426 const std::string &value = i->second;
5427 lua_pushstring(L, name.c_str());
5428 lua_pushlstring(L, value.c_str(), value.size());
5429 lua_settable(L, -3);
5432 objectref_get_or_create(L, sender);
5433 if(lua_pcall(L, 4, 0, 0))
5434 script_error(L, "error: %s", lua_tostring(L, -1));
5437 void scriptapi_node_on_metadata_inventory_move(lua_State *L, v3s16 p,
5438 const std::string &from_list, int from_index,
5439 const std::string &to_list, int to_index,
5440 int count, ServerActiveObject *player)
5443 assert(lua_checkstack(L, 20));
5444 StackUnroller stack_unroller(L);
5446 INodeDefManager *ndef = get_server(L)->ndef();
5448 // If node doesn't exist, we don't know what callback to call
5449 MapNode node = get_env(L)->getMap().getNodeNoEx(p);
5450 if(node.getContent() == CONTENT_IGNORE)
5453 // Push callback function on stack
5454 if(!get_item_callback(L, ndef->get(node).name.c_str(),
5455 "on_metadata_inventory_move"))
5458 // function(pos, from_list, from_index, to_list, to_index, count, player)
5460 lua_pushstring(L, from_list.c_str());
5461 lua_pushinteger(L, from_index + 1);
5462 lua_pushstring(L, to_list.c_str());
5463 lua_pushinteger(L, to_index + 1);
5464 lua_pushinteger(L, count);
5465 objectref_get_or_create(L, player);
5466 if(lua_pcall(L, 7, 0, 0))
5467 script_error(L, "error: %s", lua_tostring(L, -1));
5470 ItemStack scriptapi_node_on_metadata_inventory_offer(lua_State *L, v3s16 p,
5471 const std::string &listname, int index, ItemStack &stack,
5472 ServerActiveObject *player)
5475 assert(lua_checkstack(L, 20));
5476 StackUnroller stack_unroller(L);
5478 INodeDefManager *ndef = get_server(L)->ndef();
5480 // If node doesn't exist, we don't know what callback to call
5481 MapNode node = get_env(L)->getMap().getNodeNoEx(p);
5482 if(node.getContent() == CONTENT_IGNORE)
5485 // Push callback function on stack
5486 if(!get_item_callback(L, ndef->get(node).name.c_str(),
5487 "on_metadata_inventory_offer"))
5490 // Call function(pos, listname, index, stack, player)
5492 lua_pushstring(L, listname.c_str());
5493 lua_pushinteger(L, index + 1);
5494 LuaItemStack::create(L, stack);
5495 objectref_get_or_create(L, player);
5496 if(lua_pcall(L, 5, 1, 0))
5497 script_error(L, "error: %s", lua_tostring(L, -1));
5498 return read_item(L, -1);
5501 ItemStack scriptapi_node_on_metadata_inventory_take(lua_State *L, v3s16 p,
5502 const std::string &listname, int index, int count,
5503 ServerActiveObject *player)
5506 assert(lua_checkstack(L, 20));
5507 StackUnroller stack_unroller(L);
5509 INodeDefManager *ndef = get_server(L)->ndef();
5511 // If node doesn't exist, we don't know what callback to call
5512 MapNode node = get_env(L)->getMap().getNodeNoEx(p);
5513 if(node.getContent() == CONTENT_IGNORE)
5516 // Push callback function on stack
5517 if(!get_item_callback(L, ndef->get(node).name.c_str(),
5518 "on_metadata_inventory_take"))
5521 // Call function(pos, listname, index, count, player)
5523 lua_pushstring(L, listname.c_str());
5524 lua_pushinteger(L, index + 1);
5525 lua_pushinteger(L, count);
5526 objectref_get_or_create(L, player);
5527 if(lua_pcall(L, 5, 1, 0))
5528 script_error(L, "error: %s", lua_tostring(L, -1));
5529 return read_item(L, -1);
5536 void scriptapi_environment_step(lua_State *L, float dtime)
5539 assert(lua_checkstack(L, 20));
5540 //infostream<<"scriptapi_environment_step"<<std::endl;
5541 StackUnroller stack_unroller(L);
5543 // Get minetest.registered_globalsteps
5544 lua_getglobal(L, "minetest");
5545 lua_getfield(L, -1, "registered_globalsteps");
5547 lua_pushnumber(L, dtime);
5548 scriptapi_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
5551 void scriptapi_environment_on_generated(lua_State *L, v3s16 minp, v3s16 maxp,
5555 assert(lua_checkstack(L, 20));
5556 //infostream<<"scriptapi_environment_on_generated"<<std::endl;
5557 StackUnroller stack_unroller(L);
5559 // Get minetest.registered_on_generateds
5560 lua_getglobal(L, "minetest");
5561 lua_getfield(L, -1, "registered_on_generateds");
5563 push_v3s16(L, minp);
5564 push_v3s16(L, maxp);
5565 lua_pushnumber(L, blockseed);
5566 scriptapi_run_callbacks(L, 3, RUN_CALLBACKS_MODE_FIRST);
5573 bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name)
5576 assert(lua_checkstack(L, 20));
5577 verbosestream<<"scriptapi_luaentity_add: id="<<id<<" name=\""
5578 <<name<<"\""<<std::endl;
5579 StackUnroller stack_unroller(L);
5581 // Get minetest.registered_entities[name]
5582 lua_getglobal(L, "minetest");
5583 lua_getfield(L, -1, "registered_entities");
5584 luaL_checktype(L, -1, LUA_TTABLE);
5585 lua_pushstring(L, name);
5586 lua_gettable(L, -2);
5587 // Should be a table, which we will use as a prototype
5588 //luaL_checktype(L, -1, LUA_TTABLE);
5589 if(lua_type(L, -1) != LUA_TTABLE){
5590 errorstream<<"LuaEntity name \""<<name<<"\" not defined"<<std::endl;
5593 int prototype_table = lua_gettop(L);
5594 //dump2(L, "prototype_table");
5596 // Create entity object
5598 int object = lua_gettop(L);
5600 // Set object metatable
5601 lua_pushvalue(L, prototype_table);
5602 lua_setmetatable(L, -2);
5604 // Add object reference
5605 // This should be userdata with metatable ObjectRef
5606 objectref_get(L, id);
5607 luaL_checktype(L, -1, LUA_TUSERDATA);
5608 if(!luaL_checkudata(L, -1, "ObjectRef"))
5609 luaL_typerror(L, -1, "ObjectRef");
5610 lua_setfield(L, -2, "object");
5612 // minetest.luaentities[id] = object
5613 lua_getglobal(L, "minetest");
5614 lua_getfield(L, -1, "luaentities");
5615 luaL_checktype(L, -1, LUA_TTABLE);
5616 lua_pushnumber(L, id); // Push id
5617 lua_pushvalue(L, object); // Copy object to top of stack
5618 lua_settable(L, -3);
5623 void scriptapi_luaentity_activate(lua_State *L, u16 id,
5624 const std::string &staticdata)
5627 assert(lua_checkstack(L, 20));
5628 verbosestream<<"scriptapi_luaentity_activate: id="<<id<<std::endl;
5629 StackUnroller stack_unroller(L);
5631 // Get minetest.luaentities[id]
5632 luaentity_get(L, id);
5633 int object = lua_gettop(L);
5635 // Get on_activate function
5636 lua_pushvalue(L, object);
5637 lua_getfield(L, -1, "on_activate");
5638 if(!lua_isnil(L, -1)){
5639 luaL_checktype(L, -1, LUA_TFUNCTION);
5640 lua_pushvalue(L, object); // self
5641 lua_pushlstring(L, staticdata.c_str(), staticdata.size());
5642 // Call with 2 arguments, 0 results
5643 if(lua_pcall(L, 2, 0, 0))
5644 script_error(L, "error running function on_activate: %s\n",
5645 lua_tostring(L, -1));
5649 void scriptapi_luaentity_rm(lua_State *L, u16 id)
5652 assert(lua_checkstack(L, 20));
5653 verbosestream<<"scriptapi_luaentity_rm: id="<<id<<std::endl;
5655 // Get minetest.luaentities table
5656 lua_getglobal(L, "minetest");
5657 lua_getfield(L, -1, "luaentities");
5658 luaL_checktype(L, -1, LUA_TTABLE);
5659 int objectstable = lua_gettop(L);
5661 // Set luaentities[id] = nil
5662 lua_pushnumber(L, id); // Push id
5664 lua_settable(L, objectstable);
5666 lua_pop(L, 2); // pop luaentities, minetest
5669 std::string scriptapi_luaentity_get_staticdata(lua_State *L, u16 id)
5672 assert(lua_checkstack(L, 20));
5673 //infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl;
5674 StackUnroller stack_unroller(L);
5676 // Get minetest.luaentities[id]
5677 luaentity_get(L, id);
5678 int object = lua_gettop(L);
5680 // Get get_staticdata function
5681 lua_pushvalue(L, object);
5682 lua_getfield(L, -1, "get_staticdata");
5683 if(lua_isnil(L, -1))
5686 luaL_checktype(L, -1, LUA_TFUNCTION);
5687 lua_pushvalue(L, object); // self
5688 // Call with 1 arguments, 1 results
5689 if(lua_pcall(L, 1, 1, 0))
5690 script_error(L, "error running function get_staticdata: %s\n",
5691 lua_tostring(L, -1));
5694 const char *s = lua_tolstring(L, -1, &len);
5695 return std::string(s, len);
5698 void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
5699 ObjectProperties *prop)
5702 assert(lua_checkstack(L, 20));
5703 //infostream<<"scriptapi_luaentity_get_properties: id="<<id<<std::endl;
5704 StackUnroller stack_unroller(L);
5706 // Get minetest.luaentities[id]
5707 luaentity_get(L, id);
5708 //int object = lua_gettop(L);
5710 // Set default values that differ from ObjectProperties defaults
5715 prop->hp_max = getintfield_default(L, -1, "hp_max", 10);
5717 getboolfield(L, -1, "physical", prop->physical);
5719 getfloatfield(L, -1, "weight", prop->weight);
5721 lua_getfield(L, -1, "collisionbox");
5722 if(lua_istable(L, -1))
5723 prop->collisionbox = read_aabb3f(L, -1, 1.0);
5726 getstringfield(L, -1, "visual", prop->visual);
5728 // Deprecated: read object properties directly
5729 read_object_properties(L, -1, prop);
5731 // Read initial_properties
5732 lua_getfield(L, -1, "initial_properties");
5733 read_object_properties(L, -1, prop);
5737 void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime)
5740 assert(lua_checkstack(L, 20));
5741 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
5742 StackUnroller stack_unroller(L);
5744 // Get minetest.luaentities[id]
5745 luaentity_get(L, id);
5746 int object = lua_gettop(L);
5747 // State: object is at top of stack
5748 // Get step function
5749 lua_getfield(L, -1, "on_step");
5750 if(lua_isnil(L, -1))
5752 luaL_checktype(L, -1, LUA_TFUNCTION);
5753 lua_pushvalue(L, object); // self
5754 lua_pushnumber(L, dtime); // dtime
5755 // Call with 2 arguments, 0 results
5756 if(lua_pcall(L, 2, 0, 0))
5757 script_error(L, "error running function 'on_step': %s\n", lua_tostring(L, -1));
5760 // Calls entity:on_punch(ObjectRef puncher, time_from_last_punch,
5761 // tool_capabilities, direction)
5762 void scriptapi_luaentity_punch(lua_State *L, u16 id,
5763 ServerActiveObject *puncher, float time_from_last_punch,
5764 const ToolCapabilities *toolcap, v3f dir)
5767 assert(lua_checkstack(L, 20));
5768 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
5769 StackUnroller stack_unroller(L);
5771 // Get minetest.luaentities[id]
5772 luaentity_get(L, id);
5773 int object = lua_gettop(L);
5774 // State: object is at top of stack
5776 lua_getfield(L, -1, "on_punch");
5777 if(lua_isnil(L, -1))
5779 luaL_checktype(L, -1, LUA_TFUNCTION);
5780 lua_pushvalue(L, object); // self
5781 objectref_get_or_create(L, puncher); // Clicker reference
5782 lua_pushnumber(L, time_from_last_punch);
5783 push_tool_capabilities(L, *toolcap);
5785 // Call with 5 arguments, 0 results
5786 if(lua_pcall(L, 5, 0, 0))
5787 script_error(L, "error running function 'on_punch': %s\n", lua_tostring(L, -1));
5790 // Calls entity:on_rightclick(ObjectRef clicker)
5791 void scriptapi_luaentity_rightclick(lua_State *L, u16 id,
5792 ServerActiveObject *clicker)
5795 assert(lua_checkstack(L, 20));
5796 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
5797 StackUnroller stack_unroller(L);
5799 // Get minetest.luaentities[id]
5800 luaentity_get(L, id);
5801 int object = lua_gettop(L);
5802 // State: object is at top of stack
5804 lua_getfield(L, -1, "on_rightclick");
5805 if(lua_isnil(L, -1))
5807 luaL_checktype(L, -1, LUA_TFUNCTION);
5808 lua_pushvalue(L, object); // self
5809 objectref_get_or_create(L, clicker); // Clicker reference
5810 // Call with 2 arguments, 0 results
5811 if(lua_pcall(L, 2, 0, 0))
5812 script_error(L, "error running function 'on_rightclick': %s\n", lua_tostring(L, -1));