3 Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "scriptapi.h"
34 #include "serverobject.h"
37 #include "luaentity_common.h"
38 #include "content_sao.h" // For LuaEntitySAO
42 #include "main.h" // For g_settings
43 #include "settings.h" // For accessing g_settings
44 #include "nodemetadata.h"
45 #include "mapblock.h" // For getNodeBlockPos
46 #include "content_nodemeta.h"
50 static void stackDump(lua_State *L, std::ostream &o)
53 int top = lua_gettop(L);
54 for (i = 1; i <= top; i++) { /* repeat for each level */
55 int t = lua_type(L, i);
58 case LUA_TSTRING: /* strings */
59 o<<"\""<<lua_tostring(L, i)<<"\"";
62 case LUA_TBOOLEAN: /* booleans */
63 o<<(lua_toboolean(L, i) ? "true" : "false");
66 case LUA_TNUMBER: /* numbers */ {
68 snprintf(buf, 10, "%g", lua_tonumber(L, i));
72 default: /* other values */
73 o<<lua_typename(L, t);
82 static void realitycheck(lua_State *L)
84 int top = lua_gettop(L);
86 dstream<<"Stack is over 30:"<<std::endl;
87 stackDump(L, dstream);
88 script_error(L, "Stack is over 30 (reality check)");
98 StackUnroller(lua_State *L):
102 m_original_top = lua_gettop(m_lua); // store stack height
106 lua_settop(m_lua, m_original_top); // restore stack height
115 ModNameStorer(lua_State *L_, const std::string modname):
118 // Store current modname in registry
119 lua_pushstring(L, modname.c_str());
120 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
124 // Clear current modname in registry
126 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
131 Getters for stuff in main tables
134 static Server* get_server(lua_State *L)
136 // Get server from registry
137 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
138 Server *server = (Server*)lua_touserdata(L, -1);
143 static ServerEnvironment* get_env(lua_State *L)
145 // Get environment from registry
146 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_env");
147 ServerEnvironment *env = (ServerEnvironment*)lua_touserdata(L, -1);
152 static void objectref_get(lua_State *L, u16 id)
154 // Get minetest.object_refs[i]
155 lua_getglobal(L, "minetest");
156 lua_getfield(L, -1, "object_refs");
157 luaL_checktype(L, -1, LUA_TTABLE);
158 lua_pushnumber(L, id);
160 lua_remove(L, -2); // object_refs
161 lua_remove(L, -2); // minetest
164 static void luaentity_get(lua_State *L, u16 id)
166 // Get minetest.luaentities[i]
167 lua_getglobal(L, "minetest");
168 lua_getfield(L, -1, "luaentities");
169 luaL_checktype(L, -1, LUA_TTABLE);
170 lua_pushnumber(L, id);
172 lua_remove(L, -2); // luaentities
173 lua_remove(L, -2); // minetest
180 static bool getstringfield(lua_State *L, int table,
181 const char *fieldname, std::string &result)
183 lua_getfield(L, table, fieldname);
185 if(lua_isstring(L, -1)){
187 const char *ptr = lua_tolstring(L, -1, &len);
188 result.assign(ptr, len);
195 static bool getintfield(lua_State *L, int table,
196 const char *fieldname, int &result)
198 lua_getfield(L, table, fieldname);
200 if(lua_isnumber(L, -1)){
201 result = lua_tonumber(L, -1);
208 static bool getfloatfield(lua_State *L, int table,
209 const char *fieldname, float &result)
211 lua_getfield(L, table, fieldname);
213 if(lua_isnumber(L, -1)){
214 result = lua_tonumber(L, -1);
221 static bool getboolfield(lua_State *L, int table,
222 const char *fieldname, bool &result)
224 lua_getfield(L, table, fieldname);
226 if(lua_isboolean(L, -1)){
227 result = lua_toboolean(L, -1);
234 static std::string checkstringfield(lua_State *L, int table,
235 const char *fieldname)
237 lua_getfield(L, table, fieldname);
238 std::string s = luaL_checkstring(L, -1);
243 static std::string getstringfield_default(lua_State *L, int table,
244 const char *fieldname, const std::string &default_)
246 std::string result = default_;
247 getstringfield(L, table, fieldname, result);
251 static int getintfield_default(lua_State *L, int table,
252 const char *fieldname, int default_)
254 int result = default_;
255 getintfield(L, table, fieldname, result);
259 static float getfloatfield_default(lua_State *L, int table,
260 const char *fieldname, float default_)
262 float result = default_;
263 getfloatfield(L, table, fieldname, result);
267 static bool getboolfield_default(lua_State *L, int table,
268 const char *fieldname, bool default_)
270 bool result = default_;
271 getboolfield(L, table, fieldname, result);
281 static bool string_to_enum(const EnumString *spec, int &result,
282 const std::string &str)
284 const EnumString *esp = spec;
286 if(str == std::string(esp->str)){
295 /*static bool enum_to_string(const EnumString *spec, std::string &result,
298 const EnumString *esp = spec;
309 static int getenumfield(lua_State *L, int table,
310 const char *fieldname, const EnumString *spec, int default_)
312 int result = default_;
313 string_to_enum(spec, result,
314 getstringfield_default(L, table, fieldname, ""));
318 static void setintfield(lua_State *L, int table,
319 const char *fieldname, int value)
321 lua_pushinteger(L, value);
324 lua_setfield(L, table, fieldname);
327 static void setfloatfield(lua_State *L, int table,
328 const char *fieldname, float value)
330 lua_pushnumber(L, value);
333 lua_setfield(L, table, fieldname);
336 static void setboolfield(lua_State *L, int table,
337 const char *fieldname, bool value)
339 lua_pushboolean(L, value);
342 lua_setfield(L, table, fieldname);
345 static void warn_if_field_exists(lua_State *L, int table,
346 const char *fieldname, const std::string &message)
348 lua_getfield(L, table, fieldname);
349 if(!lua_isnil(L, -1)){
350 infostream<<script_get_backtrace(L)<<std::endl;
351 infostream<<"WARNING: field \""<<fieldname<<"\": "
352 <<message<<std::endl;
358 EnumString definitions
361 struct EnumString es_ItemType[] =
365 {ITEM_CRAFT, "craft"},
370 struct EnumString es_DrawType[] =
372 {NDT_NORMAL, "normal"},
373 {NDT_AIRLIKE, "airlike"},
374 {NDT_LIQUID, "liquid"},
375 {NDT_FLOWINGLIQUID, "flowingliquid"},
376 {NDT_GLASSLIKE, "glasslike"},
377 {NDT_ALLFACES, "allfaces"},
378 {NDT_ALLFACES_OPTIONAL, "allfaces_optional"},
379 {NDT_TORCHLIKE, "torchlike"},
380 {NDT_SIGNLIKE, "signlike"},
381 {NDT_PLANTLIKE, "plantlike"},
382 {NDT_FENCELIKE, "fencelike"},
383 {NDT_RAILLIKE, "raillike"},
387 struct EnumString es_ContentParamType[] =
390 {CPT_LIGHT, "light"},
394 struct EnumString es_ContentParamType2[] =
398 {CPT2_FLOWINGLIQUID, "flowingliquid"},
399 {CPT2_FACEDIR, "facedir"},
400 {CPT2_WALLMOUNTED, "wallmounted"},
404 struct EnumString es_LiquidType[] =
406 {LIQUID_NONE, "none"},
407 {LIQUID_FLOWING, "flowing"},
408 {LIQUID_SOURCE, "source"},
412 struct EnumString es_NodeBoxType[] =
414 {NODEBOX_REGULAR, "regular"},
415 {NODEBOX_FIXED, "fixed"},
416 {NODEBOX_WALLMOUNTED, "wallmounted"},
421 C struct <-> Lua table converter functions
424 static void push_v3f(lua_State *L, v3f p)
427 lua_pushnumber(L, p.X);
428 lua_setfield(L, -2, "x");
429 lua_pushnumber(L, p.Y);
430 lua_setfield(L, -2, "y");
431 lua_pushnumber(L, p.Z);
432 lua_setfield(L, -2, "z");
435 static v2s16 read_v2s16(lua_State *L, int index)
438 luaL_checktype(L, index, LUA_TTABLE);
439 lua_getfield(L, index, "x");
440 p.X = lua_tonumber(L, -1);
442 lua_getfield(L, index, "y");
443 p.Y = lua_tonumber(L, -1);
448 static v2f read_v2f(lua_State *L, int index)
451 luaL_checktype(L, index, LUA_TTABLE);
452 lua_getfield(L, index, "x");
453 p.X = lua_tonumber(L, -1);
455 lua_getfield(L, index, "y");
456 p.Y = lua_tonumber(L, -1);
461 static v3f read_v3f(lua_State *L, int index)
464 luaL_checktype(L, index, LUA_TTABLE);
465 lua_getfield(L, index, "x");
466 pos.X = lua_tonumber(L, -1);
468 lua_getfield(L, index, "y");
469 pos.Y = lua_tonumber(L, -1);
471 lua_getfield(L, index, "z");
472 pos.Z = lua_tonumber(L, -1);
477 static v3f check_v3f(lua_State *L, int index)
480 luaL_checktype(L, index, LUA_TTABLE);
481 lua_getfield(L, index, "x");
482 pos.X = luaL_checknumber(L, -1);
484 lua_getfield(L, index, "y");
485 pos.Y = luaL_checknumber(L, -1);
487 lua_getfield(L, index, "z");
488 pos.Z = luaL_checknumber(L, -1);
493 static void pushFloatPos(lua_State *L, v3f p)
499 static v3f checkFloatPos(lua_State *L, int index)
501 return check_v3f(L, index) * BS;
504 static void push_v3s16(lua_State *L, v3s16 p)
507 lua_pushnumber(L, p.X);
508 lua_setfield(L, -2, "x");
509 lua_pushnumber(L, p.Y);
510 lua_setfield(L, -2, "y");
511 lua_pushnumber(L, p.Z);
512 lua_setfield(L, -2, "z");
515 static v3s16 read_v3s16(lua_State *L, int index)
517 // Correct rounding at <0
518 v3f pf = read_v3f(L, index);
519 return floatToInt(pf, 1.0);
522 static v3s16 check_v3s16(lua_State *L, int index)
524 // Correct rounding at <0
525 v3f pf = check_v3f(L, index);
526 return floatToInt(pf, 1.0);
529 static void pushnode(lua_State *L, const MapNode &n, INodeDefManager *ndef)
532 lua_pushstring(L, ndef->get(n).name.c_str());
533 lua_setfield(L, -2, "name");
534 lua_pushnumber(L, n.getParam1());
535 lua_setfield(L, -2, "param1");
536 lua_pushnumber(L, n.getParam2());
537 lua_setfield(L, -2, "param2");
540 static MapNode readnode(lua_State *L, int index, INodeDefManager *ndef)
542 lua_getfield(L, index, "name");
543 const char *name = luaL_checkstring(L, -1);
546 lua_getfield(L, index, "param1");
550 param1 = lua_tonumber(L, -1);
553 lua_getfield(L, index, "param2");
557 param2 = lua_tonumber(L, -1);
559 return MapNode(ndef, name, param1, param2);
562 static video::SColor readARGB8(lua_State *L, int index)
565 luaL_checktype(L, index, LUA_TTABLE);
566 lua_getfield(L, index, "a");
567 if(lua_isnumber(L, -1))
568 color.setAlpha(lua_tonumber(L, -1));
570 lua_getfield(L, index, "r");
571 color.setRed(lua_tonumber(L, -1));
573 lua_getfield(L, index, "g");
574 color.setGreen(lua_tonumber(L, -1));
576 lua_getfield(L, index, "b");
577 color.setBlue(lua_tonumber(L, -1));
582 static core::aabbox3d<f32> read_aabbox3df32(lua_State *L, int index, f32 scale)
584 core::aabbox3d<f32> box;
585 if(lua_istable(L, -1)){
586 lua_rawgeti(L, -1, 1);
587 box.MinEdge.X = lua_tonumber(L, -1) * scale;
589 lua_rawgeti(L, -1, 2);
590 box.MinEdge.Y = lua_tonumber(L, -1) * scale;
592 lua_rawgeti(L, -1, 3);
593 box.MinEdge.Z = lua_tonumber(L, -1) * scale;
595 lua_rawgeti(L, -1, 4);
596 box.MaxEdge.X = lua_tonumber(L, -1) * scale;
598 lua_rawgeti(L, -1, 5);
599 box.MaxEdge.Y = lua_tonumber(L, -1) * scale;
601 lua_rawgeti(L, -1, 6);
602 box.MaxEdge.Z = lua_tonumber(L, -1) * scale;
613 static MaterialProperties read_material_properties(
614 lua_State *L, int table)
616 MaterialProperties prop;
617 prop.diggability = (Diggability)getenumfield(L, -1, "diggability",
618 es_Diggability, DIGGABLE_NORMAL);
619 getfloatfield(L, -1, "constant_time", prop.constant_time);
620 getfloatfield(L, -1, "weight", prop.weight);
621 getfloatfield(L, -1, "crackiness", prop.crackiness);
622 getfloatfield(L, -1, "crumbliness", prop.crumbliness);
623 getfloatfield(L, -1, "cuttability", prop.cuttability);
624 getfloatfield(L, -1, "flammability", prop.flammability);
632 static void read_groups(lua_State *L, int index,
633 std::map<std::string, int> &result)
639 while(lua_next(L, index) != 0){
640 // key at index -2 and value at index -1
641 std::string name = luaL_checkstring(L, -2);
642 int rating = luaL_checkinteger(L, -1);
643 result[name] = rating;
644 // removes value, keeps key for next iteration
653 static ToolCapabilities read_tool_capabilities(
654 lua_State *L, int table)
656 ToolCapabilities toolcap;
657 getfloatfield(L, table, "full_punch_interval", toolcap.full_punch_interval);
658 getintfield(L, table, "max_drop_level", toolcap.max_drop_level);
659 lua_getfield(L, table, "groupcaps");
660 if(lua_istable(L, -1)){
661 int table_groupcaps = lua_gettop(L);
663 while(lua_next(L, table_groupcaps) != 0){
664 // key at index -2 and value at index -1
665 std::string groupname = luaL_checkstring(L, -2);
666 if(lua_istable(L, -1)){
667 int table_groupcap = lua_gettop(L);
668 // This will be created
669 ToolGroupCap groupcap;
670 // Read simple parameters
671 getfloatfield(L, table_groupcap, "maxwear", groupcap.maxwear);
672 getintfield(L, table_groupcap, "maxlevel", groupcap.maxlevel);
673 // Read "times" table
674 lua_getfield(L, table_groupcap, "times");
675 if(lua_istable(L, -1)){
676 int table_times = lua_gettop(L);
678 while(lua_next(L, table_times) != 0){
679 // key at index -2 and value at index -1
680 int rating = luaL_checkinteger(L, -2);
681 float time = luaL_checknumber(L, -1);
682 groupcap.times[rating] = time;
683 // removes value, keeps key for next iteration
688 // Insert groupcap into toolcap
689 toolcap.groupcaps[groupname] = groupcap;
691 // removes value, keeps key for next iteration
699 static void set_tool_capabilities(lua_State *L, int table,
700 const ToolCapabilities &toolcap)
702 setfloatfield(L, table, "full_punch_interval", toolcap.full_punch_interval);
703 setintfield(L, table, "max_drop_level", toolcap.max_drop_level);
704 // Create groupcaps table
707 for(std::map<std::string, ToolGroupCap>::const_iterator
708 i = toolcap.groupcaps.begin(); i != toolcap.groupcaps.end(); i++){
709 // Create groupcap table
711 const std::string &name = i->first;
712 const ToolGroupCap &groupcap = i->second;
713 // Create subtable "times"
715 for(std::map<int, float>::const_iterator
716 i = groupcap.times.begin(); i != groupcap.times.end(); i++){
717 int rating = i->first;
718 float time = i->second;
719 lua_pushinteger(L, rating);
720 lua_pushnumber(L, time);
723 // Set subtable "times"
724 lua_setfield(L, -2, "times");
725 // Set simple parameters
726 setfloatfield(L, -1, "maxwear", groupcap.maxwear);
727 setintfield(L, -1, "maxlevel", groupcap.maxlevel);
728 // Insert groupcap table into groupcaps table
729 lua_setfield(L, -2, name.c_str());
731 // Set groupcaps table
732 lua_setfield(L, -2, "groupcaps");
735 static void push_tool_capabilities(lua_State *L,
736 const ToolCapabilities &prop)
739 set_tool_capabilities(L, -1, prop);
746 static void set_dig_params(lua_State *L, int table,
747 const DigParams ¶ms)
749 setboolfield(L, table, "diggable", params.diggable);
750 setfloatfield(L, table, "time", params.time);
751 setintfield(L, table, "wear", params.wear);
754 static void push_dig_params(lua_State *L,
755 const DigParams ¶ms)
758 set_dig_params(L, -1, params);
765 static void set_hit_params(lua_State *L, int table,
766 const HitParams ¶ms)
768 setintfield(L, table, "hp", params.hp);
769 setintfield(L, table, "wear", params.wear);
772 static void push_hit_params(lua_State *L,
773 const HitParams ¶ms)
776 set_hit_params(L, -1, params);
783 static void push_pointed_thing(lua_State *L, const PointedThing& pointed)
786 if(pointed.type == POINTEDTHING_NODE)
788 lua_pushstring(L, "node");
789 lua_setfield(L, -2, "type");
790 push_v3s16(L, pointed.node_undersurface);
791 lua_setfield(L, -2, "under");
792 push_v3s16(L, pointed.node_abovesurface);
793 lua_setfield(L, -2, "above");
795 else if(pointed.type == POINTEDTHING_OBJECT)
797 lua_pushstring(L, "object");
798 lua_setfield(L, -2, "type");
799 objectref_get(L, pointed.object_id);
800 lua_setfield(L, -2, "ref");
804 lua_pushstring(L, "nothing");
805 lua_setfield(L, -2, "type");
813 static ItemDefinition read_item_definition(lua_State *L, int index)
816 index = lua_gettop(L) + 1 + index;
818 // Read the item definition
821 def.type = (ItemType)getenumfield(L, index, "type",
822 es_ItemType, ITEM_NONE);
823 getstringfield(L, index, "name", def.name);
824 getstringfield(L, index, "description", def.description);
825 getstringfield(L, index, "inventory_image", def.inventory_image);
826 getstringfield(L, index, "wield_image", def.wield_image);
828 lua_getfield(L, index, "wield_scale");
829 if(lua_istable(L, -1)){
830 def.wield_scale = check_v3f(L, -1);
834 def.stack_max = getintfield_default(L, index, "stack_max", def.stack_max);
835 if(def.stack_max == 0)
838 lua_getfield(L, index, "on_use");
839 def.usable = lua_isfunction(L, -1);
842 getboolfield(L, index, "liquids_pointable", def.liquids_pointable);
844 warn_if_field_exists(L, index, "tool_digging_properties",
845 "deprecated: use tool_capabilities");
847 lua_getfield(L, index, "tool_capabilities");
848 if(lua_istable(L, -1)){
849 def.tool_capabilities = new ToolCapabilities(
850 read_tool_capabilities(L, -1));
853 // If name is "" (hand), ensure there are ToolCapabilities
854 // because it will be looked up there whenever any other item has
855 // no ToolCapabilities
856 if(def.name == "" && def.tool_capabilities == NULL){
857 def.tool_capabilities = new ToolCapabilities();
860 lua_getfield(L, index, "groups");
861 read_groups(L, -1, def.groups);
871 static ContentFeatures read_content_features(lua_State *L, int index)
874 index = lua_gettop(L) + 1 + index;
878 getstringfield(L, index, "name", f.name);
881 lua_getfield(L, index, "groups");
882 read_groups(L, -1, f.groups);
885 /* Visual definition */
887 f.drawtype = (NodeDrawType)getenumfield(L, index, "drawtype", es_DrawType,
889 getfloatfield(L, index, "visual_scale", f.visual_scale);
891 lua_getfield(L, index, "tile_images");
892 if(lua_istable(L, -1)){
893 int table = lua_gettop(L);
896 while(lua_next(L, table) != 0){
897 // key at index -2 and value at index -1
898 if(lua_isstring(L, -1))
899 f.tname_tiles[i] = lua_tostring(L, -1);
901 f.tname_tiles[i] = "";
902 // removes value, keeps key for next iteration
910 // Copy last value to all remaining textures
912 std::string lastname = f.tname_tiles[i-1];
914 f.tname_tiles[i] = lastname;
921 lua_getfield(L, index, "special_materials");
922 if(lua_istable(L, -1)){
923 int table = lua_gettop(L);
926 while(lua_next(L, table) != 0){
927 // key at index -2 and value at index -1
928 int smtable = lua_gettop(L);
929 std::string tname = getstringfield_default(
930 L, smtable, "image", "");
931 bool backface_culling = getboolfield_default(
932 L, smtable, "backface_culling", true);
933 MaterialSpec mspec(tname, backface_culling);
934 f.mspec_special[i] = mspec;
935 // removes value, keeps key for next iteration
946 f.alpha = getintfield_default(L, index, "alpha", 255);
950 lua_getfield(L, index, "post_effect_color");
951 if(!lua_isnil(L, -1))
952 f.post_effect_color = readARGB8(L, -1);
955 f.param_type = (ContentParamType)getenumfield(L, index, "paramtype",
956 es_ContentParamType, CPT_NONE);
957 f.param_type_2 = (ContentParamType2)getenumfield(L, index, "paramtype2",
958 es_ContentParamType2, CPT2_NONE);
960 // Warn about some deprecated fields
961 warn_if_field_exists(L, index, "wall_mounted",
962 "deprecated: use paramtype2 = 'wallmounted'");
963 warn_if_field_exists(L, index, "light_propagates",
964 "deprecated: determined from paramtype");
965 warn_if_field_exists(L, index, "dug_item",
966 "deprecated: use 'drop' field");
967 warn_if_field_exists(L, index, "extra_dug_item",
968 "deprecated: use 'drop' field");
969 warn_if_field_exists(L, index, "extra_dug_item_rarity",
970 "deprecated: use 'drop' field");
972 // True for all ground-like things like stone and mud, false for eg. trees
973 getboolfield(L, index, "is_ground_content", f.is_ground_content);
974 f.light_propagates = (f.param_type == CPT_LIGHT);
975 getboolfield(L, index, "sunlight_propagates", f.sunlight_propagates);
976 // This is used for collision detection.
977 // Also for general solidness queries.
978 getboolfield(L, index, "walkable", f.walkable);
979 // Player can point to these
980 getboolfield(L, index, "pointable", f.pointable);
981 // Player can dig these
982 getboolfield(L, index, "diggable", f.diggable);
983 // Player can climb these
984 getboolfield(L, index, "climbable", f.climbable);
985 // Player can build on these
986 getboolfield(L, index, "buildable_to", f.buildable_to);
987 // Metadata name of node (eg. "furnace")
988 getstringfield(L, index, "metadata_name", f.metadata_name);
989 // Whether the node is non-liquid, source liquid or flowing liquid
990 f.liquid_type = (LiquidType)getenumfield(L, index, "liquidtype",
991 es_LiquidType, LIQUID_NONE);
992 // If the content is liquid, this is the flowing version of the liquid.
993 getstringfield(L, index, "liquid_alternative_flowing",
994 f.liquid_alternative_flowing);
995 // If the content is liquid, this is the source version of the liquid.
996 getstringfield(L, index, "liquid_alternative_source",
997 f.liquid_alternative_source);
998 // Viscosity for fluid flow, ranging from 1 to 7, with
999 // 1 giving almost instantaneous propagation and 7 being
1000 // the slowest possible
1001 f.liquid_viscosity = getintfield_default(L, index,
1002 "liquid_viscosity", f.liquid_viscosity);
1003 // Amount of light the node emits
1004 f.light_source = getintfield_default(L, index,
1005 "light_source", f.light_source);
1006 f.damage_per_second = getintfield_default(L, index,
1007 "damage_per_second", f.damage_per_second);
1009 lua_getfield(L, index, "selection_box");
1010 if(lua_istable(L, -1)){
1011 f.selection_box.type = (NodeBoxType)getenumfield(L, -1, "type",
1012 es_NodeBoxType, NODEBOX_REGULAR);
1014 lua_getfield(L, -1, "fixed");
1015 if(lua_istable(L, -1))
1016 f.selection_box.fixed = read_aabbox3df32(L, -1, BS);
1019 lua_getfield(L, -1, "wall_top");
1020 if(lua_istable(L, -1))
1021 f.selection_box.wall_top = read_aabbox3df32(L, -1, BS);
1024 lua_getfield(L, -1, "wall_bottom");
1025 if(lua_istable(L, -1))
1026 f.selection_box.wall_bottom = read_aabbox3df32(L, -1, BS);
1029 lua_getfield(L, -1, "wall_side");
1030 if(lua_istable(L, -1))
1031 f.selection_box.wall_side = read_aabbox3df32(L, -1, BS);
1036 // Set to true if paramtype used to be 'facedir_simple'
1037 getboolfield(L, index, "legacy_facedir_simple", f.legacy_facedir_simple);
1038 // Set to true if wall_mounted used to be set to true
1039 getboolfield(L, index, "legacy_wallmounted", f.legacy_wallmounted);
1048 static ItemStack read_item(lua_State *L, int index);
1050 static void inventory_set_list_from_lua(Inventory *inv, const char *name,
1051 lua_State *L, int tableindex, int forcesize=-1)
1053 dstream<<"inventory_set_list_from_lua\n";
1055 tableindex = lua_gettop(L) + 1 + tableindex;
1056 // If nil, delete list
1057 if(lua_isnil(L, tableindex)){
1058 inv->deleteList(name);
1061 // Otherwise set list
1062 std::vector<ItemStack> items;
1063 luaL_checktype(L, tableindex, LUA_TTABLE);
1065 while(lua_next(L, tableindex) != 0){
1066 // key at index -2 and value at index -1
1067 items.push_back(read_item(L, -1));
1068 // removes value, keeps key for next iteration
1071 int listsize = (forcesize != -1) ? forcesize : items.size();
1072 InventoryList *invlist = inv->addList(name, listsize);
1074 for(std::vector<ItemStack>::const_iterator
1075 i = items.begin(); i != items.end(); i++){
1076 if(forcesize != -1 && index == forcesize)
1078 invlist->changeItem(index, *i);
1081 while(forcesize != -1 && index < forcesize){
1082 invlist->deleteItem(index);
1085 dstream<<"inventory_set_list_from_lua done\n";
1088 static void inventory_get_list_to_lua(Inventory *inv, const char *name,
1091 InventoryList *invlist = inv->getList(name);
1092 if(invlist == NULL){
1096 // Get the table insert function
1097 lua_getglobal(L, "table");
1098 lua_getfield(L, -1, "insert");
1099 int table_insert = lua_gettop(L);
1100 // Create and fill table
1102 int table = lua_gettop(L);
1103 for(u32 i=0; i<invlist->getSize(); i++){
1104 ItemStack item = invlist->getItem(i);
1105 lua_pushvalue(L, table_insert);
1106 lua_pushvalue(L, table);
1107 lua_pushstring(L, item.getItemString().c_str());
1108 if(lua_pcall(L, 2, 0, 0))
1109 script_error(L, "error: %s", lua_tostring(L, -1));
1114 Helpful macros for userdata classes
1117 #define method(class, name) {#name, class::l_##name}
1128 static const char className[];
1129 static const luaL_reg methods[];
1131 // Exported functions
1133 // garbage collector
1134 static int gc_object(lua_State *L)
1136 LuaItemStack *o = *(LuaItemStack **)(lua_touserdata(L, 1));
1141 // is_empty(self) -> true/false
1142 static int l_is_empty(lua_State *L)
1144 LuaItemStack *o = checkobject(L, 1);
1145 ItemStack &item = o->m_stack;
1146 lua_pushboolean(L, item.empty());
1150 // get_name(self) -> string
1151 static int l_get_name(lua_State *L)
1153 LuaItemStack *o = checkobject(L, 1);
1154 ItemStack &item = o->m_stack;
1155 lua_pushstring(L, item.name.c_str());
1159 // get_count(self) -> number
1160 static int l_get_count(lua_State *L)
1162 LuaItemStack *o = checkobject(L, 1);
1163 ItemStack &item = o->m_stack;
1164 lua_pushinteger(L, item.count);
1168 // get_wear(self) -> number
1169 static int l_get_wear(lua_State *L)
1171 LuaItemStack *o = checkobject(L, 1);
1172 ItemStack &item = o->m_stack;
1173 lua_pushinteger(L, item.wear);
1177 // get_metadata(self) -> string
1178 static int l_get_metadata(lua_State *L)
1180 LuaItemStack *o = checkobject(L, 1);
1181 ItemStack &item = o->m_stack;
1182 lua_pushlstring(L, item.metadata.c_str(), item.metadata.size());
1186 // clear(self) -> true
1187 static int l_clear(lua_State *L)
1189 LuaItemStack *o = checkobject(L, 1);
1191 lua_pushboolean(L, true);
1195 // replace(self, itemstack or itemstring or table or nil) -> true
1196 static int l_replace(lua_State *L)
1198 LuaItemStack *o = checkobject(L, 1);
1199 o->m_stack = read_item(L, 2);
1200 lua_pushboolean(L, true);
1204 // to_string(self) -> string
1205 static int l_to_string(lua_State *L)
1207 LuaItemStack *o = checkobject(L, 1);
1208 std::string itemstring = o->m_stack.getItemString();
1209 lua_pushstring(L, itemstring.c_str());
1213 // to_table(self) -> table or nil
1214 static int l_to_table(lua_State *L)
1216 LuaItemStack *o = checkobject(L, 1);
1217 const ItemStack &item = o->m_stack;
1225 lua_pushstring(L, item.name.c_str());
1226 lua_setfield(L, -2, "name");
1227 lua_pushinteger(L, item.count);
1228 lua_setfield(L, -2, "count");
1229 lua_pushinteger(L, item.wear);
1230 lua_setfield(L, -2, "wear");
1231 lua_pushlstring(L, item.metadata.c_str(), item.metadata.size());
1232 lua_setfield(L, -2, "metadata");
1237 // get_stack_max(self) -> number
1238 static int l_get_stack_max(lua_State *L)
1240 LuaItemStack *o = checkobject(L, 1);
1241 ItemStack &item = o->m_stack;
1242 lua_pushinteger(L, item.getStackMax(get_server(L)->idef()));
1246 // get_free_space(self) -> number
1247 static int l_get_free_space(lua_State *L)
1249 LuaItemStack *o = checkobject(L, 1);
1250 ItemStack &item = o->m_stack;
1251 lua_pushinteger(L, item.freeSpace(get_server(L)->idef()));
1255 // is_known(self) -> true/false
1256 // Checks if the item is defined.
1257 static int l_is_known(lua_State *L)
1259 LuaItemStack *o = checkobject(L, 1);
1260 ItemStack &item = o->m_stack;
1261 bool is_known = item.isKnown(get_server(L)->idef());
1262 lua_pushboolean(L, is_known);
1266 // get_definition(self) -> table
1267 // Returns the item definition table from minetest.registered_items,
1268 // or a fallback one (name="unknown")
1269 static int l_get_definition(lua_State *L)
1271 LuaItemStack *o = checkobject(L, 1);
1272 ItemStack &item = o->m_stack;
1274 // Get minetest.registered_items[name]
1275 lua_getglobal(L, "minetest");
1276 lua_getfield(L, -1, "registered_items");
1277 luaL_checktype(L, -1, LUA_TTABLE);
1278 lua_getfield(L, -1, item.name.c_str());
1279 if(lua_isnil(L, -1))
1282 lua_getfield(L, -1, "unknown");
1287 // get_tool_capabilities(self) -> table
1288 // Returns the effective tool digging properties.
1289 // Returns those of the hand ("") if this item has none associated.
1290 static int l_get_tool_capabilities(lua_State *L)
1292 LuaItemStack *o = checkobject(L, 1);
1293 ItemStack &item = o->m_stack;
1294 const ToolCapabilities &prop =
1295 item.getToolCapabilities(get_server(L)->idef());
1296 push_tool_capabilities(L, prop);
1300 // add_wear(self, amount) -> true/false
1301 // The range for "amount" is [0,65535]. Wear is only added if the item
1302 // is a tool. Adding wear might destroy the item.
1303 // Returns true if the item is (or was) a tool.
1304 static int l_add_wear(lua_State *L)
1306 LuaItemStack *o = checkobject(L, 1);
1307 ItemStack &item = o->m_stack;
1308 int amount = lua_tointeger(L, 2);
1309 bool result = item.addWear(amount, get_server(L)->idef());
1310 lua_pushboolean(L, result);
1314 // add_item(self, itemstack or itemstring or table or nil) -> itemstack
1315 // Returns leftover item stack
1316 static int l_add_item(lua_State *L)
1318 LuaItemStack *o = checkobject(L, 1);
1319 ItemStack &item = o->m_stack;
1320 ItemStack newitem = read_item(L, 2);
1321 ItemStack leftover = item.addItem(newitem, get_server(L)->idef());
1322 create(L, leftover);
1326 // item_fits(self, itemstack or itemstring or table or nil) -> true/false, itemstack
1327 // First return value is true iff the new item fits fully into the stack
1328 // Second return value is the would-be-left-over item stack
1329 static int l_item_fits(lua_State *L)
1331 LuaItemStack *o = checkobject(L, 1);
1332 ItemStack &item = o->m_stack;
1333 ItemStack newitem = read_item(L, 2);
1335 bool fits = item.itemFits(newitem, &restitem, get_server(L)->idef());
1336 lua_pushboolean(L, fits); // first return value
1337 create(L, restitem); // second return value
1341 // take_item(self, takecount=1) -> itemstack
1342 static int l_take_item(lua_State *L)
1344 LuaItemStack *o = checkobject(L, 1);
1345 ItemStack &item = o->m_stack;
1347 if(!lua_isnone(L, 2))
1348 takecount = lua_tointeger(L, 2);
1349 ItemStack taken = item.takeItem(takecount);
1354 // peek_item(self, peekcount=1) -> itemstack
1355 static int l_peek_item(lua_State *L)
1357 LuaItemStack *o = checkobject(L, 1);
1358 ItemStack &item = o->m_stack;
1360 if(!lua_isnone(L, 2))
1361 peekcount = lua_tointeger(L, 2);
1362 ItemStack peekaboo = item.peekItem(peekcount);
1363 create(L, peekaboo);
1368 LuaItemStack(const ItemStack &item):
1377 const ItemStack& getItem() const
1381 ItemStack& getItem()
1386 // LuaItemStack(itemstack or itemstring or table or nil)
1387 // Creates an LuaItemStack and leaves it on top of stack
1388 static int create_object(lua_State *L)
1390 ItemStack item = read_item(L, 1);
1391 LuaItemStack *o = new LuaItemStack(item);
1392 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1393 luaL_getmetatable(L, className);
1394 lua_setmetatable(L, -2);
1397 // Not callable from Lua
1398 static int create(lua_State *L, const ItemStack &item)
1400 LuaItemStack *o = new LuaItemStack(item);
1401 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1402 luaL_getmetatable(L, className);
1403 lua_setmetatable(L, -2);
1407 static LuaItemStack* checkobject(lua_State *L, int narg)
1409 luaL_checktype(L, narg, LUA_TUSERDATA);
1410 void *ud = luaL_checkudata(L, narg, className);
1411 if(!ud) luaL_typerror(L, narg, className);
1412 return *(LuaItemStack**)ud; // unbox pointer
1415 static void Register(lua_State *L)
1418 int methodtable = lua_gettop(L);
1419 luaL_newmetatable(L, className);
1420 int metatable = lua_gettop(L);
1422 lua_pushliteral(L, "__metatable");
1423 lua_pushvalue(L, methodtable);
1424 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
1426 lua_pushliteral(L, "__index");
1427 lua_pushvalue(L, methodtable);
1428 lua_settable(L, metatable);
1430 lua_pushliteral(L, "__gc");
1431 lua_pushcfunction(L, gc_object);
1432 lua_settable(L, metatable);
1434 lua_pop(L, 1); // drop metatable
1436 luaL_openlib(L, 0, methods, 0); // fill methodtable
1437 lua_pop(L, 1); // drop methodtable
1439 // Can be created from Lua (LuaItemStack(itemstack or itemstring or table or nil))
1440 lua_register(L, className, create_object);
1443 const char LuaItemStack::className[] = "ItemStack";
1444 const luaL_reg LuaItemStack::methods[] = {
1445 method(LuaItemStack, is_empty),
1446 method(LuaItemStack, get_name),
1447 method(LuaItemStack, get_count),
1448 method(LuaItemStack, get_wear),
1449 method(LuaItemStack, get_metadata),
1450 method(LuaItemStack, clear),
1451 method(LuaItemStack, replace),
1452 method(LuaItemStack, to_string),
1453 method(LuaItemStack, to_table),
1454 method(LuaItemStack, get_stack_max),
1455 method(LuaItemStack, get_free_space),
1456 method(LuaItemStack, is_known),
1457 method(LuaItemStack, get_definition),
1458 method(LuaItemStack, get_tool_capabilities),
1459 method(LuaItemStack, add_wear),
1460 method(LuaItemStack, add_item),
1461 method(LuaItemStack, item_fits),
1462 method(LuaItemStack, take_item),
1463 method(LuaItemStack, peek_item),
1467 static ItemStack read_item(lua_State *L, int index)
1470 index = lua_gettop(L) + 1 + index;
1472 if(lua_isnil(L, index))
1476 else if(lua_isuserdata(L, index))
1478 // Convert from LuaItemStack
1479 LuaItemStack *o = LuaItemStack::checkobject(L, index);
1480 return o->getItem();
1482 else if(lua_isstring(L, index))
1484 // Convert from itemstring
1485 std::string itemstring = lua_tostring(L, index);
1486 IItemDefManager *idef = get_server(L)->idef();
1490 item.deSerialize(itemstring, idef);
1493 catch(SerializationError &e)
1495 infostream<<"WARNING: unable to create item from itemstring"
1496 <<": "<<itemstring<<std::endl;
1500 else if(lua_istable(L, index))
1502 // Convert from table
1503 IItemDefManager *idef = get_server(L)->idef();
1504 std::string name = getstringfield_default(L, index, "name", "");
1505 int count = getintfield_default(L, index, "count", 1);
1506 int wear = getintfield_default(L, index, "wear", 0);
1507 std::string metadata = getstringfield_default(L, index, "metadata", "");
1508 return ItemStack(name, count, wear, metadata, idef);
1512 throw LuaError(L, "Expecting itemstack, itemstring, table or nil");
1523 InventoryLocation m_loc;
1525 static const char className[];
1526 static const luaL_reg methods[];
1528 static InvRef *checkobject(lua_State *L, int narg)
1530 luaL_checktype(L, narg, LUA_TUSERDATA);
1531 void *ud = luaL_checkudata(L, narg, className);
1532 if(!ud) luaL_typerror(L, narg, className);
1533 return *(InvRef**)ud; // unbox pointer
1536 static Inventory* getinv(lua_State *L, InvRef *ref)
1538 return get_server(L)->getInventory(ref->m_loc);
1541 static InventoryList* getlist(lua_State *L, InvRef *ref,
1542 const char *listname)
1544 Inventory *inv = getinv(L, ref);
1547 return inv->getList(listname);
1550 static void reportInventoryChange(lua_State *L, InvRef *ref)
1552 // Inform other things that the inventory has changed
1553 get_server(L)->setInventoryModified(ref->m_loc);
1556 // Exported functions
1558 // garbage collector
1559 static int gc_object(lua_State *L) {
1560 InvRef *o = *(InvRef **)(lua_touserdata(L, 1));
1565 // get_size(self, listname)
1566 static int l_get_size(lua_State *L)
1568 InvRef *ref = checkobject(L, 1);
1569 const char *listname = luaL_checkstring(L, 2);
1570 InventoryList *list = getlist(L, ref, listname);
1572 lua_pushinteger(L, list->getSize());
1574 lua_pushinteger(L, 0);
1579 // set_size(self, listname, size)
1580 static int l_set_size(lua_State *L)
1582 InvRef *ref = checkobject(L, 1);
1583 const char *listname = luaL_checkstring(L, 2);
1584 int newsize = luaL_checknumber(L, 3);
1585 Inventory *inv = getinv(L, ref);
1587 inv->deleteList(listname);
1588 reportInventoryChange(L, ref);
1591 InventoryList *list = inv->getList(listname);
1593 list->setSize(newsize);
1595 list = inv->addList(listname, newsize);
1597 reportInventoryChange(L, ref);
1601 // get_stack(self, listname, i) -> itemstack
1602 static int l_get_stack(lua_State *L)
1604 InvRef *ref = checkobject(L, 1);
1605 const char *listname = luaL_checkstring(L, 2);
1606 int i = luaL_checknumber(L, 3) - 1;
1607 InventoryList *list = getlist(L, ref, listname);
1609 if(list != NULL && i >= 0 && i < (int) list->getSize())
1610 item = list->getItem(i);
1611 LuaItemStack::create(L, item);
1615 // set_stack(self, listname, i, stack) -> true/false
1616 static int l_set_stack(lua_State *L)
1618 InvRef *ref = checkobject(L, 1);
1619 const char *listname = luaL_checkstring(L, 2);
1620 int i = luaL_checknumber(L, 3) - 1;
1621 ItemStack newitem = read_item(L, 4);
1622 InventoryList *list = getlist(L, ref, listname);
1623 if(list != NULL && i >= 0 && i < (int) list->getSize()){
1624 list->changeItem(i, newitem);
1625 reportInventoryChange(L, ref);
1626 lua_pushboolean(L, true);
1628 lua_pushboolean(L, false);
1633 // get_list(self, listname) -> list or nil
1634 static int l_get_list(lua_State *L)
1636 InvRef *ref = checkobject(L, 1);
1637 const char *listname = luaL_checkstring(L, 2);
1638 Inventory *inv = getinv(L, ref);
1639 inventory_get_list_to_lua(inv, listname, L);
1643 // set_list(self, listname, list)
1644 static int l_set_list(lua_State *L)
1646 InvRef *ref = checkobject(L, 1);
1647 const char *listname = luaL_checkstring(L, 2);
1648 Inventory *inv = getinv(L, ref);
1649 InventoryList *list = inv->getList(listname);
1651 inventory_set_list_from_lua(inv, listname, L, 3,
1654 inventory_set_list_from_lua(inv, listname, L, 3);
1655 reportInventoryChange(L, ref);
1659 // add_item(self, listname, itemstack or itemstring or table or nil) -> itemstack
1660 // Returns the leftover stack
1661 static int l_add_item(lua_State *L)
1663 InvRef *ref = checkobject(L, 1);
1664 const char *listname = luaL_checkstring(L, 2);
1665 ItemStack item = read_item(L, 3);
1666 InventoryList *list = getlist(L, ref, listname);
1668 ItemStack leftover = list->addItem(item);
1669 if(leftover.count != item.count)
1670 reportInventoryChange(L, ref);
1671 LuaItemStack::create(L, leftover);
1673 LuaItemStack::create(L, item);
1678 // room_for_item(self, listname, itemstack or itemstring or table or nil) -> true/false
1679 // Returns true if the item completely fits into the list
1680 static int l_room_for_item(lua_State *L)
1682 InvRef *ref = checkobject(L, 1);
1683 const char *listname = luaL_checkstring(L, 2);
1684 ItemStack item = read_item(L, 3);
1685 InventoryList *list = getlist(L, ref, listname);
1687 lua_pushboolean(L, list->roomForItem(item));
1689 lua_pushboolean(L, false);
1694 // contains_item(self, listname, itemstack or itemstring or table or nil) -> true/false
1695 // Returns true if the list contains the given count of the given item name
1696 static int l_contains_item(lua_State *L)
1698 InvRef *ref = checkobject(L, 1);
1699 const char *listname = luaL_checkstring(L, 2);
1700 ItemStack item = read_item(L, 3);
1701 InventoryList *list = getlist(L, ref, listname);
1703 lua_pushboolean(L, list->containsItem(item));
1705 lua_pushboolean(L, false);
1710 // remove_item(self, listname, itemstack or itemstring or table or nil) -> itemstack
1711 // Returns the items that were actually removed
1712 static int l_remove_item(lua_State *L)
1714 InvRef *ref = checkobject(L, 1);
1715 const char *listname = luaL_checkstring(L, 2);
1716 ItemStack item = read_item(L, 3);
1717 InventoryList *list = getlist(L, ref, listname);
1719 ItemStack removed = list->removeItem(item);
1720 if(!removed.empty())
1721 reportInventoryChange(L, ref);
1722 LuaItemStack::create(L, removed);
1724 LuaItemStack::create(L, ItemStack());
1730 InvRef(const InventoryLocation &loc):
1739 // Creates an InvRef and leaves it on top of stack
1740 // Not callable from Lua; all references are created on the C side.
1741 static void create(lua_State *L, const InventoryLocation &loc)
1743 InvRef *o = new InvRef(loc);
1744 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1745 luaL_getmetatable(L, className);
1746 lua_setmetatable(L, -2);
1748 static void createPlayer(lua_State *L, Player *player)
1750 InventoryLocation loc;
1751 loc.setPlayer(player->getName());
1754 static void createNodeMeta(lua_State *L, v3s16 p)
1756 InventoryLocation loc;
1761 static void Register(lua_State *L)
1764 int methodtable = lua_gettop(L);
1765 luaL_newmetatable(L, className);
1766 int metatable = lua_gettop(L);
1768 lua_pushliteral(L, "__metatable");
1769 lua_pushvalue(L, methodtable);
1770 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
1772 lua_pushliteral(L, "__index");
1773 lua_pushvalue(L, methodtable);
1774 lua_settable(L, metatable);
1776 lua_pushliteral(L, "__gc");
1777 lua_pushcfunction(L, gc_object);
1778 lua_settable(L, metatable);
1780 lua_pop(L, 1); // drop metatable
1782 luaL_openlib(L, 0, methods, 0); // fill methodtable
1783 lua_pop(L, 1); // drop methodtable
1785 // Cannot be created from Lua
1786 //lua_register(L, className, create_object);
1789 const char InvRef::className[] = "InvRef";
1790 const luaL_reg InvRef::methods[] = {
1791 method(InvRef, get_size),
1792 method(InvRef, set_size),
1793 method(InvRef, get_stack),
1794 method(InvRef, set_stack),
1795 method(InvRef, get_list),
1796 method(InvRef, set_list),
1797 method(InvRef, add_item),
1798 method(InvRef, room_for_item),
1799 method(InvRef, contains_item),
1800 method(InvRef, remove_item),
1812 ServerEnvironment *m_env;
1814 static const char className[];
1815 static const luaL_reg methods[];
1817 static NodeMetaRef *checkobject(lua_State *L, int narg)
1819 luaL_checktype(L, narg, LUA_TUSERDATA);
1820 void *ud = luaL_checkudata(L, narg, className);
1821 if(!ud) luaL_typerror(L, narg, className);
1822 return *(NodeMetaRef**)ud; // unbox pointer
1825 static NodeMetadata* getmeta(NodeMetaRef *ref)
1827 NodeMetadata *meta = ref->m_env->getMap().getNodeMetadata(ref->m_p);
1831 /*static IGenericNodeMetadata* getgenericmeta(NodeMetaRef *ref)
1833 NodeMetadata *meta = getmeta(ref);
1836 if(meta->typeId() != NODEMETA_GENERIC)
1838 return (IGenericNodeMetadata*)meta;
1841 static void reportMetadataChange(NodeMetaRef *ref)
1843 // Inform other things that the metadata has changed
1844 v3s16 blockpos = getNodeBlockPos(ref->m_p);
1846 event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
1848 ref->m_env->getMap().dispatchEvent(&event);
1849 // Set the block to be saved
1850 MapBlock *block = ref->m_env->getMap().getBlockNoCreateNoEx(blockpos);
1852 block->raiseModified(MOD_STATE_WRITE_NEEDED,
1853 "NodeMetaRef::reportMetadataChange");
1856 // Exported functions
1858 // garbage collector
1859 static int gc_object(lua_State *L) {
1860 NodeMetaRef *o = *(NodeMetaRef **)(lua_touserdata(L, 1));
1866 static int l_get_type(lua_State *L)
1868 NodeMetaRef *ref = checkobject(L, 1);
1869 NodeMetadata *meta = getmeta(ref);
1875 lua_pushstring(L, meta->typeName());
1879 // allows_text_input(self)
1880 static int l_allows_text_input(lua_State *L)
1882 NodeMetaRef *ref = checkobject(L, 1);
1883 NodeMetadata *meta = getmeta(ref);
1884 if(meta == NULL) return 0;
1886 lua_pushboolean(L, meta->allowsTextInput());
1890 // set_text(self, text)
1891 static int l_set_text(lua_State *L)
1893 NodeMetaRef *ref = checkobject(L, 1);
1894 NodeMetadata *meta = getmeta(ref);
1895 if(meta == NULL) return 0;
1897 std::string text = luaL_checkstring(L, 2);
1898 meta->setText(text);
1899 reportMetadataChange(ref);
1904 static int l_get_text(lua_State *L)
1906 NodeMetaRef *ref = checkobject(L, 1);
1907 NodeMetadata *meta = getmeta(ref);
1908 if(meta == NULL) return 0;
1910 std::string text = meta->getText();
1911 lua_pushstring(L, text.c_str());
1916 static int l_get_owner(lua_State *L)
1918 NodeMetaRef *ref = checkobject(L, 1);
1919 NodeMetadata *meta = getmeta(ref);
1920 if(meta == NULL) return 0;
1922 std::string owner = meta->getOwner();
1923 lua_pushstring(L, owner.c_str());
1927 // set_owner(self, string)
1928 static int l_set_owner(lua_State *L)
1930 NodeMetaRef *ref = checkobject(L, 1);
1931 NodeMetadata *meta = getmeta(ref);
1932 if(meta == NULL) return 0;
1934 std::string owner = luaL_checkstring(L, 2);
1935 meta->setOwner(owner);
1936 reportMetadataChange(ref);
1940 // get_allow_removal(self)
1941 static int l_get_allow_removal(lua_State *L)
1943 NodeMetaRef *ref = checkobject(L, 1);
1944 NodeMetadata *meta = getmeta(ref);
1946 lua_pushboolean(L, true);
1950 lua_pushboolean(L, !meta->nodeRemovalDisabled());
1954 /* IGenericNodeMetadata interface */
1956 // set_infotext(self, text)
1957 static int l_set_infotext(lua_State *L)
1959 NodeMetaRef *ref = checkobject(L, 1);
1960 NodeMetadata *meta = getmeta(ref);
1961 if(meta == NULL) return 0;
1963 std::string text = luaL_checkstring(L, 2);
1964 meta->setInfoText(text);
1965 reportMetadataChange(ref);
1969 // get_inventory(self)
1970 static int l_get_inventory(lua_State *L)
1972 NodeMetaRef *ref = checkobject(L, 1);
1973 NodeMetadata *meta = getmeta(ref);
1974 if(meta == NULL) return 0;
1976 InvRef::createNodeMeta(L, ref->m_p);
1980 // set_inventory_draw_spec(self, text)
1981 static int l_set_inventory_draw_spec(lua_State *L)
1983 NodeMetaRef *ref = checkobject(L, 1);
1984 NodeMetadata *meta = getmeta(ref);
1985 if(meta == NULL) return 0;
1987 std::string text = luaL_checkstring(L, 2);
1988 meta->setInventoryDrawSpec(text);
1989 reportMetadataChange(ref);
1993 // set_allow_text_input(self, text)
1994 static int l_set_allow_text_input(lua_State *L)
1996 NodeMetaRef *ref = checkobject(L, 1);
1997 NodeMetadata *meta = getmeta(ref);
1998 if(meta == NULL) return 0;
2000 bool b = lua_toboolean(L, 2);
2001 meta->setAllowTextInput(b);
2002 reportMetadataChange(ref);
2006 // set_allow_removal(self, text)
2007 static int l_set_allow_removal(lua_State *L)
2009 NodeMetaRef *ref = checkobject(L, 1);
2010 NodeMetadata *meta = getmeta(ref);
2011 if(meta == NULL) return 0;
2013 bool b = lua_toboolean(L, 2);
2014 meta->setRemovalDisabled(!b);
2015 reportMetadataChange(ref);
2019 // set_enforce_owner(self, text)
2020 static int l_set_enforce_owner(lua_State *L)
2022 NodeMetaRef *ref = checkobject(L, 1);
2023 NodeMetadata *meta = getmeta(ref);
2024 if(meta == NULL) return 0;
2026 bool b = lua_toboolean(L, 2);
2027 meta->setEnforceOwner(b);
2028 reportMetadataChange(ref);
2032 // is_inventory_modified(self)
2033 static int l_is_inventory_modified(lua_State *L)
2035 NodeMetaRef *ref = checkobject(L, 1);
2036 NodeMetadata *meta = getmeta(ref);
2037 if(meta == NULL) return 0;
2039 lua_pushboolean(L, meta->isInventoryModified());
2043 // reset_inventory_modified(self)
2044 static int l_reset_inventory_modified(lua_State *L)
2046 NodeMetaRef *ref = checkobject(L, 1);
2047 NodeMetadata *meta = getmeta(ref);
2048 if(meta == NULL) return 0;
2050 meta->resetInventoryModified();
2051 reportMetadataChange(ref);
2055 // is_text_modified(self)
2056 static int l_is_text_modified(lua_State *L)
2058 NodeMetaRef *ref = checkobject(L, 1);
2059 NodeMetadata *meta = getmeta(ref);
2060 if(meta == NULL) return 0;
2062 lua_pushboolean(L, meta->isTextModified());
2066 // reset_text_modified(self)
2067 static int l_reset_text_modified(lua_State *L)
2069 NodeMetaRef *ref = checkobject(L, 1);
2070 NodeMetadata *meta = getmeta(ref);
2071 if(meta == NULL) return 0;
2073 meta->resetTextModified();
2074 reportMetadataChange(ref);
2078 // set_string(self, name, var)
2079 static int l_set_string(lua_State *L)
2081 NodeMetaRef *ref = checkobject(L, 1);
2082 NodeMetadata *meta = getmeta(ref);
2083 if(meta == NULL) return 0;
2085 std::string name = luaL_checkstring(L, 2);
2087 const char *s = lua_tolstring(L, 3, &len);
2088 std::string str(s, len);
2089 meta->setString(name, str);
2090 reportMetadataChange(ref);
2094 // get_string(self, name)
2095 static int l_get_string(lua_State *L)
2097 NodeMetaRef *ref = checkobject(L, 1);
2098 NodeMetadata *meta = getmeta(ref);
2099 if(meta == NULL) return 0;
2101 std::string name = luaL_checkstring(L, 2);
2102 std::string str = meta->getString(name);
2103 lua_pushlstring(L, str.c_str(), str.size());
2108 NodeMetaRef(v3s16 p, ServerEnvironment *env):
2118 // Creates an NodeMetaRef and leaves it on top of stack
2119 // Not callable from Lua; all references are created on the C side.
2120 static void create(lua_State *L, v3s16 p, ServerEnvironment *env)
2122 NodeMetaRef *o = new NodeMetaRef(p, env);
2123 //infostream<<"NodeMetaRef::create: o="<<o<<std::endl;
2124 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
2125 luaL_getmetatable(L, className);
2126 lua_setmetatable(L, -2);
2129 static void Register(lua_State *L)
2132 int methodtable = lua_gettop(L);
2133 luaL_newmetatable(L, className);
2134 int metatable = lua_gettop(L);
2136 lua_pushliteral(L, "__metatable");
2137 lua_pushvalue(L, methodtable);
2138 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
2140 lua_pushliteral(L, "__index");
2141 lua_pushvalue(L, methodtable);
2142 lua_settable(L, metatable);
2144 lua_pushliteral(L, "__gc");
2145 lua_pushcfunction(L, gc_object);
2146 lua_settable(L, metatable);
2148 lua_pop(L, 1); // drop metatable
2150 luaL_openlib(L, 0, methods, 0); // fill methodtable
2151 lua_pop(L, 1); // drop methodtable
2153 // Cannot be created from Lua
2154 //lua_register(L, className, create_object);
2157 const char NodeMetaRef::className[] = "NodeMetaRef";
2158 const luaL_reg NodeMetaRef::methods[] = {
2159 method(NodeMetaRef, get_type),
2160 method(NodeMetaRef, allows_text_input),
2161 method(NodeMetaRef, set_text),
2162 method(NodeMetaRef, get_text),
2163 method(NodeMetaRef, get_owner),
2164 method(NodeMetaRef, set_owner),
2165 method(NodeMetaRef, get_allow_removal),
2166 method(NodeMetaRef, set_infotext),
2167 method(NodeMetaRef, get_inventory),
2168 method(NodeMetaRef, set_inventory_draw_spec),
2169 method(NodeMetaRef, set_allow_text_input),
2170 method(NodeMetaRef, set_allow_removal),
2171 method(NodeMetaRef, set_enforce_owner),
2172 method(NodeMetaRef, is_inventory_modified),
2173 method(NodeMetaRef, reset_inventory_modified),
2174 method(NodeMetaRef, is_text_modified),
2175 method(NodeMetaRef, reset_text_modified),
2176 method(NodeMetaRef, set_string),
2177 method(NodeMetaRef, get_string),
2188 ServerActiveObject *m_object;
2190 static const char className[];
2191 static const luaL_reg methods[];
2193 static ObjectRef *checkobject(lua_State *L, int narg)
2195 luaL_checktype(L, narg, LUA_TUSERDATA);
2196 void *ud = luaL_checkudata(L, narg, className);
2197 if(!ud) luaL_typerror(L, narg, className);
2198 return *(ObjectRef**)ud; // unbox pointer
2201 static ServerActiveObject* getobject(ObjectRef *ref)
2203 ServerActiveObject *co = ref->m_object;
2207 static LuaEntitySAO* getluaobject(ObjectRef *ref)
2209 ServerActiveObject *obj = getobject(ref);
2212 if(obj->getType() != ACTIVEOBJECT_TYPE_LUAENTITY)
2214 return (LuaEntitySAO*)obj;
2217 static ServerRemotePlayer* getplayer(ObjectRef *ref)
2219 ServerActiveObject *obj = getobject(ref);
2222 if(obj->getType() != ACTIVEOBJECT_TYPE_PLAYER)
2224 return static_cast<ServerRemotePlayer*>(obj);
2227 // Exported functions
2229 // garbage collector
2230 static int gc_object(lua_State *L) {
2231 ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
2232 //infostream<<"ObjectRef::gc_object: o="<<o<<std::endl;
2238 static int l_remove(lua_State *L)
2240 ObjectRef *ref = checkobject(L, 1);
2241 ServerActiveObject *co = getobject(ref);
2242 if(co == NULL) return 0;
2243 infostream<<"ObjectRef::l_remove(): id="<<co->getId()<<std::endl;
2244 co->m_removed = true;
2249 // returns: {x=num, y=num, z=num}
2250 static int l_getpos(lua_State *L)
2252 ObjectRef *ref = checkobject(L, 1);
2253 ServerActiveObject *co = getobject(ref);
2254 if(co == NULL) return 0;
2255 v3f pos = co->getBasePosition() / BS;
2257 lua_pushnumber(L, pos.X);
2258 lua_setfield(L, -2, "x");
2259 lua_pushnumber(L, pos.Y);
2260 lua_setfield(L, -2, "y");
2261 lua_pushnumber(L, pos.Z);
2262 lua_setfield(L, -2, "z");
2266 // setpos(self, pos)
2267 static int l_setpos(lua_State *L)
2269 ObjectRef *ref = checkobject(L, 1);
2270 //LuaEntitySAO *co = getluaobject(ref);
2271 ServerActiveObject *co = getobject(ref);
2272 if(co == NULL) return 0;
2274 v3f pos = checkFloatPos(L, 2);
2277 // Move player if applicable
2278 ServerRemotePlayer *player = getplayer(ref);
2280 get_server(L)->SendMovePlayer(player);
2284 // moveto(self, pos, continuous=false)
2285 static int l_moveto(lua_State *L)
2287 ObjectRef *ref = checkobject(L, 1);
2288 //LuaEntitySAO *co = getluaobject(ref);
2289 ServerActiveObject *co = getobject(ref);
2290 if(co == NULL) return 0;
2292 v3f pos = checkFloatPos(L, 2);
2294 bool continuous = lua_toboolean(L, 3);
2296 co->moveTo(pos, continuous);
2300 // punch(self, puncher, tool_capabilities, direction, time_from_last_punch)
2301 static int l_punch(lua_State *L)
2303 ObjectRef *ref = checkobject(L, 1);
2304 ObjectRef *puncher_ref = checkobject(L, 2);
2305 ServerActiveObject *co = getobject(ref);
2306 ServerActiveObject *puncher = getobject(puncher_ref);
2307 if(co == NULL) return 0;
2308 if(puncher == NULL) return 0;
2309 ToolCapabilities toolcap = read_tool_capabilities(L, 3);
2310 v3f dir = read_v3f(L, 4);
2311 float time_from_last_punch = 1000000;
2312 if(lua_isnumber(L, 5))
2313 time_from_last_punch = lua_tonumber(L, 5);
2315 puncher->punch(dir, &toolcap, puncher, time_from_last_punch);
2319 // right_click(self, clicker); clicker = an another ObjectRef
2320 static int l_right_click(lua_State *L)
2322 ObjectRef *ref = checkobject(L, 1);
2323 ObjectRef *ref2 = checkobject(L, 2);
2324 ServerActiveObject *co = getobject(ref);
2325 ServerActiveObject *co2 = getobject(ref2);
2326 if(co == NULL) return 0;
2327 if(co2 == NULL) return 0;
2329 co->rightClick(co2);
2334 // hp = number of hitpoints (2 * number of hearts)
2336 static int l_set_hp(lua_State *L)
2338 ObjectRef *ref = checkobject(L, 1);
2339 luaL_checknumber(L, 2);
2340 ServerActiveObject *co = getobject(ref);
2341 if(co == NULL) return 0;
2342 int hp = lua_tonumber(L, 2);
2343 infostream<<"ObjectRef::l_set_hp(): id="<<co->getId()
2344 <<" hp="<<hp<<std::endl;
2352 // returns: number of hitpoints (2 * number of hearts)
2353 // 0 if not applicable to this type of object
2354 static int l_get_hp(lua_State *L)
2356 ObjectRef *ref = checkobject(L, 1);
2357 ServerActiveObject *co = getobject(ref);
2358 if(co == NULL) return 0;
2359 int hp = co->getHP();
2360 infostream<<"ObjectRef::l_get_hp(): id="<<co->getId()
2361 <<" hp="<<hp<<std::endl;
2363 lua_pushnumber(L, hp);
2367 // get_inventory(self)
2368 static int l_get_inventory(lua_State *L)
2370 ObjectRef *ref = checkobject(L, 1);
2371 ServerActiveObject *co = getobject(ref);
2372 if(co == NULL) return 0;
2374 InventoryLocation loc = co->getInventoryLocation();
2375 if(get_server(L)->getInventory(loc) != NULL)
2376 InvRef::create(L, loc);
2382 // get_wield_list(self)
2383 static int l_get_wield_list(lua_State *L)
2385 ObjectRef *ref = checkobject(L, 1);
2386 ServerActiveObject *co = getobject(ref);
2387 if(co == NULL) return 0;
2389 lua_pushstring(L, co->getWieldList().c_str());
2393 // get_wield_index(self)
2394 static int l_get_wield_index(lua_State *L)
2396 ObjectRef *ref = checkobject(L, 1);
2397 ServerActiveObject *co = getobject(ref);
2398 if(co == NULL) return 0;
2400 lua_pushinteger(L, co->getWieldIndex() + 1);
2404 // get_wielded_item(self)
2405 static int l_get_wielded_item(lua_State *L)
2407 ObjectRef *ref = checkobject(L, 1);
2408 ServerActiveObject *co = getobject(ref);
2409 if(co == NULL) return 0;
2411 LuaItemStack::create(L, co->getWieldedItem());
2415 // set_wielded_item(self, itemstack or itemstring or table or nil)
2416 static int l_set_wielded_item(lua_State *L)
2418 ObjectRef *ref = checkobject(L, 1);
2419 ServerActiveObject *co = getobject(ref);
2420 if(co == NULL) return 0;
2422 ItemStack item = read_item(L, 2);
2423 bool success = co->setWieldedItem(item);
2424 lua_pushboolean(L, success);
2428 /* LuaEntitySAO-only */
2430 // setvelocity(self, {x=num, y=num, z=num})
2431 static int l_setvelocity(lua_State *L)
2433 ObjectRef *ref = checkobject(L, 1);
2434 LuaEntitySAO *co = getluaobject(ref);
2435 if(co == NULL) return 0;
2437 v3f pos = checkFloatPos(L, 2);
2439 co->setVelocity(pos);
2443 // getvelocity(self)
2444 static int l_getvelocity(lua_State *L)
2446 ObjectRef *ref = checkobject(L, 1);
2447 LuaEntitySAO *co = getluaobject(ref);
2448 if(co == NULL) return 0;
2450 v3f v = co->getVelocity();
2455 // setacceleration(self, {x=num, y=num, z=num})
2456 static int l_setacceleration(lua_State *L)
2458 ObjectRef *ref = checkobject(L, 1);
2459 LuaEntitySAO *co = getluaobject(ref);
2460 if(co == NULL) return 0;
2462 v3f pos = checkFloatPos(L, 2);
2464 co->setAcceleration(pos);
2468 // getacceleration(self)
2469 static int l_getacceleration(lua_State *L)
2471 ObjectRef *ref = checkobject(L, 1);
2472 LuaEntitySAO *co = getluaobject(ref);
2473 if(co == NULL) return 0;
2475 v3f v = co->getAcceleration();
2480 // setyaw(self, radians)
2481 static int l_setyaw(lua_State *L)
2483 ObjectRef *ref = checkobject(L, 1);
2484 LuaEntitySAO *co = getluaobject(ref);
2485 if(co == NULL) return 0;
2487 float yaw = luaL_checknumber(L, 2) * core::RADTODEG;
2494 static int l_getyaw(lua_State *L)
2496 ObjectRef *ref = checkobject(L, 1);
2497 LuaEntitySAO *co = getluaobject(ref);
2498 if(co == NULL) return 0;
2500 float yaw = co->getYaw() * core::DEGTORAD;
2501 lua_pushnumber(L, yaw);
2505 // settexturemod(self, mod)
2506 static int l_settexturemod(lua_State *L)
2508 ObjectRef *ref = checkobject(L, 1);
2509 LuaEntitySAO *co = getluaobject(ref);
2510 if(co == NULL) return 0;
2512 std::string mod = luaL_checkstring(L, 2);
2513 co->setTextureMod(mod);
2517 // setsprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2,
2518 // select_horiz_by_yawpitch=false)
2519 static int l_setsprite(lua_State *L)
2521 ObjectRef *ref = checkobject(L, 1);
2522 LuaEntitySAO *co = getluaobject(ref);
2523 if(co == NULL) return 0;
2526 if(!lua_isnil(L, 2))
2527 p = read_v2s16(L, 2);
2529 if(!lua_isnil(L, 3))
2530 num_frames = lua_tonumber(L, 3);
2531 float framelength = 0.2;
2532 if(!lua_isnil(L, 4))
2533 framelength = lua_tonumber(L, 4);
2534 bool select_horiz_by_yawpitch = false;
2535 if(!lua_isnil(L, 5))
2536 select_horiz_by_yawpitch = lua_toboolean(L, 5);
2537 co->setSprite(p, num_frames, framelength, select_horiz_by_yawpitch);
2542 // get_entity_name(self)
2543 static int l_get_entity_name(lua_State *L)
2545 ObjectRef *ref = checkobject(L, 1);
2546 LuaEntitySAO *co = getluaobject(ref);
2547 if(co == NULL) return 0;
2549 std::string name = co->getName();
2550 lua_pushstring(L, name.c_str());
2554 // get_luaentity(self)
2555 static int l_get_luaentity(lua_State *L)
2557 ObjectRef *ref = checkobject(L, 1);
2558 LuaEntitySAO *co = getluaobject(ref);
2559 if(co == NULL) return 0;
2561 luaentity_get(L, co->getId());
2567 // get_player_name(self)
2568 static int l_get_player_name(lua_State *L)
2570 ObjectRef *ref = checkobject(L, 1);
2571 ServerRemotePlayer *player = getplayer(ref);
2577 lua_pushstring(L, player->getName());
2581 // get_look_dir(self)
2582 static int l_get_look_dir(lua_State *L)
2584 ObjectRef *ref = checkobject(L, 1);
2585 ServerRemotePlayer *player = getplayer(ref);
2586 if(player == NULL) return 0;
2588 float pitch = player->getRadPitch();
2589 float yaw = player->getRadYaw();
2590 v3f v(cos(pitch)*cos(yaw), sin(pitch), cos(pitch)*sin(yaw));
2595 // get_look_pitch(self)
2596 static int l_get_look_pitch(lua_State *L)
2598 ObjectRef *ref = checkobject(L, 1);
2599 ServerRemotePlayer *player = getplayer(ref);
2600 if(player == NULL) return 0;
2602 lua_pushnumber(L, player->getRadPitch());
2606 // get_look_yaw(self)
2607 static int l_get_look_yaw(lua_State *L)
2609 ObjectRef *ref = checkobject(L, 1);
2610 ServerRemotePlayer *player = getplayer(ref);
2611 if(player == NULL) return 0;
2613 lua_pushnumber(L, player->getRadYaw());
2618 ObjectRef(ServerActiveObject *object):
2621 //infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
2627 infostream<<"ObjectRef destructing for id="
2628 <<m_object->getId()<<std::endl;
2630 infostream<<"ObjectRef destructing for id=unknown"<<std::endl;*/
2633 // Creates an ObjectRef and leaves it on top of stack
2634 // Not callable from Lua; all references are created on the C side.
2635 static void create(lua_State *L, ServerActiveObject *object)
2637 ObjectRef *o = new ObjectRef(object);
2638 //infostream<<"ObjectRef::create: o="<<o<<std::endl;
2639 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
2640 luaL_getmetatable(L, className);
2641 lua_setmetatable(L, -2);
2644 static void set_null(lua_State *L)
2646 ObjectRef *o = checkobject(L, -1);
2650 static void Register(lua_State *L)
2653 int methodtable = lua_gettop(L);
2654 luaL_newmetatable(L, className);
2655 int metatable = lua_gettop(L);
2657 lua_pushliteral(L, "__metatable");
2658 lua_pushvalue(L, methodtable);
2659 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
2661 lua_pushliteral(L, "__index");
2662 lua_pushvalue(L, methodtable);
2663 lua_settable(L, metatable);
2665 lua_pushliteral(L, "__gc");
2666 lua_pushcfunction(L, gc_object);
2667 lua_settable(L, metatable);
2669 lua_pop(L, 1); // drop metatable
2671 luaL_openlib(L, 0, methods, 0); // fill methodtable
2672 lua_pop(L, 1); // drop methodtable
2674 // Cannot be created from Lua
2675 //lua_register(L, className, create_object);
2678 const char ObjectRef::className[] = "ObjectRef";
2679 const luaL_reg ObjectRef::methods[] = {
2680 // ServerActiveObject
2681 method(ObjectRef, remove),
2682 method(ObjectRef, getpos),
2683 method(ObjectRef, setpos),
2684 method(ObjectRef, moveto),
2685 method(ObjectRef, punch),
2686 method(ObjectRef, right_click),
2687 method(ObjectRef, set_hp),
2688 method(ObjectRef, get_hp),
2689 method(ObjectRef, get_inventory),
2690 method(ObjectRef, get_wield_list),
2691 method(ObjectRef, get_wield_index),
2692 method(ObjectRef, get_wielded_item),
2693 method(ObjectRef, set_wielded_item),
2694 // LuaEntitySAO-only
2695 method(ObjectRef, setvelocity),
2696 method(ObjectRef, getvelocity),
2697 method(ObjectRef, setacceleration),
2698 method(ObjectRef, getacceleration),
2699 method(ObjectRef, setyaw),
2700 method(ObjectRef, getyaw),
2701 method(ObjectRef, settexturemod),
2702 method(ObjectRef, setsprite),
2703 method(ObjectRef, get_entity_name),
2704 method(ObjectRef, get_luaentity),
2706 method(ObjectRef, get_player_name),
2707 method(ObjectRef, get_look_dir),
2708 method(ObjectRef, get_look_pitch),
2709 method(ObjectRef, get_look_yaw),
2713 // Creates a new anonymous reference if id=0
2714 static void objectref_get_or_create(lua_State *L,
2715 ServerActiveObject *cobj)
2717 if(cobj->getId() == 0){
2718 ObjectRef::create(L, cobj);
2720 objectref_get(L, cobj->getId());
2731 ServerEnvironment *m_env;
2733 static const char className[];
2734 static const luaL_reg methods[];
2736 static EnvRef *checkobject(lua_State *L, int narg)
2738 luaL_checktype(L, narg, LUA_TUSERDATA);
2739 void *ud = luaL_checkudata(L, narg, className);
2740 if(!ud) luaL_typerror(L, narg, className);
2741 return *(EnvRef**)ud; // unbox pointer
2744 // Exported functions
2746 // EnvRef:add_node(pos, node)
2747 // pos = {x=num, y=num, z=num}
2748 static int l_add_node(lua_State *L)
2750 //infostream<<"EnvRef::l_add_node()"<<std::endl;
2751 EnvRef *o = checkobject(L, 1);
2752 ServerEnvironment *env = o->m_env;
2753 if(env == NULL) return 0;
2755 v3s16 pos = read_v3s16(L, 2);
2757 MapNode n = readnode(L, 3, env->getGameDef()->ndef());
2759 bool succeeded = env->getMap().addNodeWithEvent(pos, n);
2760 lua_pushboolean(L, succeeded);
2764 // EnvRef:remove_node(pos)
2765 // pos = {x=num, y=num, z=num}
2766 static int l_remove_node(lua_State *L)
2768 //infostream<<"EnvRef::l_remove_node()"<<std::endl;
2769 EnvRef *o = checkobject(L, 1);
2770 ServerEnvironment *env = o->m_env;
2771 if(env == NULL) return 0;
2773 v3s16 pos = read_v3s16(L, 2);
2775 bool succeeded = env->getMap().removeNodeWithEvent(pos);
2776 lua_pushboolean(L, succeeded);
2780 // EnvRef:get_node(pos)
2781 // pos = {x=num, y=num, z=num}
2782 static int l_get_node(lua_State *L)
2784 //infostream<<"EnvRef::l_get_node()"<<std::endl;
2785 EnvRef *o = checkobject(L, 1);
2786 ServerEnvironment *env = o->m_env;
2787 if(env == NULL) return 0;
2789 v3s16 pos = read_v3s16(L, 2);
2791 MapNode n = env->getMap().getNodeNoEx(pos);
2793 pushnode(L, n, env->getGameDef()->ndef());
2797 // EnvRef:get_node_or_nil(pos)
2798 // pos = {x=num, y=num, z=num}
2799 static int l_get_node_or_nil(lua_State *L)
2801 //infostream<<"EnvRef::l_get_node()"<<std::endl;
2802 EnvRef *o = checkobject(L, 1);
2803 ServerEnvironment *env = o->m_env;
2804 if(env == NULL) return 0;
2806 v3s16 pos = read_v3s16(L, 2);
2809 MapNode n = env->getMap().getNode(pos);
2811 pushnode(L, n, env->getGameDef()->ndef());
2813 } catch(InvalidPositionException &e)
2820 // EnvRef:get_node_light(pos, timeofday)
2821 // pos = {x=num, y=num, z=num}
2822 // timeofday: nil = current time, 0 = night, 0.5 = day
2823 static int l_get_node_light(lua_State *L)
2825 EnvRef *o = checkobject(L, 1);
2826 ServerEnvironment *env = o->m_env;
2827 if(env == NULL) return 0;
2829 v3s16 pos = read_v3s16(L, 2);
2830 u32 time_of_day = env->getTimeOfDay();
2831 if(lua_isnumber(L, 3))
2832 time_of_day = 24000.0 * lua_tonumber(L, 3);
2833 time_of_day %= 24000;
2834 u32 dnr = time_to_daynight_ratio(time_of_day);
2835 MapNode n = env->getMap().getNodeNoEx(pos);
2837 MapNode n = env->getMap().getNode(pos);
2838 INodeDefManager *ndef = env->getGameDef()->ndef();
2839 lua_pushinteger(L, n.getLightBlend(dnr, ndef));
2841 } catch(InvalidPositionException &e)
2848 // EnvRef:add_entity(pos, entityname) -> ObjectRef or nil
2849 // pos = {x=num, y=num, z=num}
2850 static int l_add_entity(lua_State *L)
2852 //infostream<<"EnvRef::l_add_entity()"<<std::endl;
2853 EnvRef *o = checkobject(L, 1);
2854 ServerEnvironment *env = o->m_env;
2855 if(env == NULL) return 0;
2857 v3f pos = checkFloatPos(L, 2);
2859 const char *name = luaL_checkstring(L, 3);
2861 ServerActiveObject *obj = new LuaEntitySAO(env, pos, name, "");
2862 int objectid = env->addActiveObject(obj);
2863 // If failed to add, return nothing (reads as nil)
2867 objectref_get_or_create(L, obj);
2871 // EnvRef:add_item(pos, itemstack or itemstring or table) -> ObjectRef or nil
2872 // pos = {x=num, y=num, z=num}
2873 static int l_add_item(lua_State *L)
2875 //infostream<<"EnvRef::l_add_item()"<<std::endl;
2876 EnvRef *o = checkobject(L, 1);
2877 ServerEnvironment *env = o->m_env;
2878 if(env == NULL) return 0;
2880 v3f pos = checkFloatPos(L, 2);
2882 ItemStack item = read_item(L, 3);
2883 if(item.empty() || !item.isKnown(get_server(L)->idef()))
2886 ServerActiveObject *obj = createItemSAO(env, pos, item.getItemString());
2887 int objectid = env->addActiveObject(obj);
2888 // If failed to add, return nothing (reads as nil)
2892 objectref_get_or_create(L, obj);
2896 // EnvRef:add_rat(pos)
2897 // pos = {x=num, y=num, z=num}
2898 static int l_add_rat(lua_State *L)
2900 infostream<<"EnvRef::l_add_rat(): C++ mobs have been removed."
2901 <<" Doing nothing."<<std::endl;
2905 // EnvRef:add_firefly(pos)
2906 // pos = {x=num, y=num, z=num}
2907 static int l_add_firefly(lua_State *L)
2909 infostream<<"EnvRef::l_add_firefly(): C++ mobs have been removed."
2910 <<" Doing nothing."<<std::endl;
2914 // EnvRef:get_meta(pos)
2915 static int l_get_meta(lua_State *L)
2917 //infostream<<"EnvRef::l_get_meta()"<<std::endl;
2918 EnvRef *o = checkobject(L, 1);
2919 ServerEnvironment *env = o->m_env;
2920 if(env == NULL) return 0;
2922 v3s16 p = read_v3s16(L, 2);
2923 NodeMetaRef::create(L, p, env);
2927 // EnvRef:get_player_by_name(name)
2928 static int l_get_player_by_name(lua_State *L)
2930 EnvRef *o = checkobject(L, 1);
2931 ServerEnvironment *env = o->m_env;
2932 if(env == NULL) return 0;
2934 const char *name = luaL_checkstring(L, 2);
2935 ServerRemotePlayer *player =
2936 static_cast<ServerRemotePlayer*>(env->getPlayer(name));
2941 // Put player on stack
2942 objectref_get_or_create(L, player);
2946 // EnvRef:get_objects_inside_radius(pos, radius)
2947 static int l_get_objects_inside_radius(lua_State *L)
2949 // Get the table insert function
2950 lua_getglobal(L, "table");
2951 lua_getfield(L, -1, "insert");
2952 int table_insert = lua_gettop(L);
2954 EnvRef *o = checkobject(L, 1);
2955 ServerEnvironment *env = o->m_env;
2956 if(env == NULL) return 0;
2958 v3f pos = checkFloatPos(L, 2);
2959 float radius = luaL_checknumber(L, 3) * BS;
2960 std::set<u16> ids = env->getObjectsInsideRadius(pos, radius);
2962 int table = lua_gettop(L);
2963 for(std::set<u16>::const_iterator
2964 i = ids.begin(); i != ids.end(); i++){
2965 ServerActiveObject *obj = env->getActiveObject(*i);
2966 // Insert object reference into table
2967 lua_pushvalue(L, table_insert);
2968 lua_pushvalue(L, table);
2969 objectref_get_or_create(L, obj);
2970 if(lua_pcall(L, 2, 0, 0))
2971 script_error(L, "error: %s", lua_tostring(L, -1));
2976 // EnvRef:set_timeofday(val)
2978 static int l_set_timeofday(lua_State *L)
2980 EnvRef *o = checkobject(L, 1);
2981 ServerEnvironment *env = o->m_env;
2982 if(env == NULL) return 0;
2984 float timeofday_f = luaL_checknumber(L, 2);
2985 assert(timeofday_f >= 0.0 && timeofday_f <= 1.0);
2986 int timeofday_mh = (int)(timeofday_f * 24000.0);
2987 // This should be set directly in the environment but currently
2988 // such changes aren't immediately sent to the clients, so call
2989 // the server instead.
2990 //env->setTimeOfDay(timeofday_mh);
2991 get_server(L)->setTimeOfDay(timeofday_mh);
2995 // EnvRef:get_timeofday() -> 0...1
2996 static int l_get_timeofday(lua_State *L)
2998 EnvRef *o = checkobject(L, 1);
2999 ServerEnvironment *env = o->m_env;
3000 if(env == NULL) return 0;
3002 int timeofday_mh = env->getTimeOfDay();
3003 float timeofday_f = (float)timeofday_mh / 24000.0;
3004 lua_pushnumber(L, timeofday_f);
3008 static int gc_object(lua_State *L) {
3009 EnvRef *o = *(EnvRef **)(lua_touserdata(L, 1));
3015 EnvRef(ServerEnvironment *env):
3018 infostream<<"EnvRef created"<<std::endl;
3023 infostream<<"EnvRef destructing"<<std::endl;
3026 // Creates an EnvRef and leaves it on top of stack
3027 // Not callable from Lua; all references are created on the C side.
3028 static void create(lua_State *L, ServerEnvironment *env)
3030 EnvRef *o = new EnvRef(env);
3031 //infostream<<"EnvRef::create: o="<<o<<std::endl;
3032 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
3033 luaL_getmetatable(L, className);
3034 lua_setmetatable(L, -2);
3037 static void set_null(lua_State *L)
3039 EnvRef *o = checkobject(L, -1);
3043 static void Register(lua_State *L)
3046 int methodtable = lua_gettop(L);
3047 luaL_newmetatable(L, className);
3048 int metatable = lua_gettop(L);
3050 lua_pushliteral(L, "__metatable");
3051 lua_pushvalue(L, methodtable);
3052 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
3054 lua_pushliteral(L, "__index");
3055 lua_pushvalue(L, methodtable);
3056 lua_settable(L, metatable);
3058 lua_pushliteral(L, "__gc");
3059 lua_pushcfunction(L, gc_object);
3060 lua_settable(L, metatable);
3062 lua_pop(L, 1); // drop metatable
3064 luaL_openlib(L, 0, methods, 0); // fill methodtable
3065 lua_pop(L, 1); // drop methodtable
3067 // Cannot be created from Lua
3068 //lua_register(L, className, create_object);
3071 const char EnvRef::className[] = "EnvRef";
3072 const luaL_reg EnvRef::methods[] = {
3073 method(EnvRef, add_node),
3074 method(EnvRef, remove_node),
3075 method(EnvRef, get_node),
3076 method(EnvRef, get_node_or_nil),
3077 method(EnvRef, get_node_light),
3078 method(EnvRef, add_entity),
3079 method(EnvRef, add_item),
3080 method(EnvRef, add_rat),
3081 method(EnvRef, add_firefly),
3082 method(EnvRef, get_meta),
3083 method(EnvRef, get_player_by_name),
3084 method(EnvRef, get_objects_inside_radius),
3085 method(EnvRef, set_timeofday),
3086 method(EnvRef, get_timeofday),
3094 class LuaABM : public ActiveBlockModifier
3100 std::set<std::string> m_trigger_contents;
3101 std::set<std::string> m_required_neighbors;
3102 float m_trigger_interval;
3103 u32 m_trigger_chance;
3105 LuaABM(lua_State *L, int id,
3106 const std::set<std::string> &trigger_contents,
3107 const std::set<std::string> &required_neighbors,
3108 float trigger_interval, u32 trigger_chance):
3111 m_trigger_contents(trigger_contents),
3112 m_required_neighbors(required_neighbors),
3113 m_trigger_interval(trigger_interval),
3114 m_trigger_chance(trigger_chance)
3117 virtual std::set<std::string> getTriggerContents()
3119 return m_trigger_contents;
3121 virtual std::set<std::string> getRequiredNeighbors()
3123 return m_required_neighbors;
3125 virtual float getTriggerInterval()
3127 return m_trigger_interval;
3129 virtual u32 getTriggerChance()
3131 return m_trigger_chance;
3133 virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n,
3134 u32 active_object_count, u32 active_object_count_wider)
3136 lua_State *L = m_lua;
3139 assert(lua_checkstack(L, 20));
3140 StackUnroller stack_unroller(L);
3142 // Get minetest.registered_abms
3143 lua_getglobal(L, "minetest");
3144 lua_getfield(L, -1, "registered_abms");
3145 luaL_checktype(L, -1, LUA_TTABLE);
3146 int registered_abms = lua_gettop(L);
3148 // Get minetest.registered_abms[m_id]
3149 lua_pushnumber(L, m_id);
3150 lua_gettable(L, registered_abms);
3151 if(lua_isnil(L, -1))
3155 luaL_checktype(L, -1, LUA_TTABLE);
3156 lua_getfield(L, -1, "action");
3157 luaL_checktype(L, -1, LUA_TFUNCTION);
3159 pushnode(L, n, env->getGameDef()->ndef());
3160 lua_pushnumber(L, active_object_count);
3161 lua_pushnumber(L, active_object_count_wider);
3162 if(lua_pcall(L, 4, 0, 0))
3163 script_error(L, "error: %s", lua_tostring(L, -1));
3168 // Writes a line to dstream
3169 static int l_debug(lua_State *L)
3171 std::string text = lua_tostring(L, 1);
3172 dstream << text << std::endl;
3176 // log([level,] text)
3177 // Writes a line to the logger.
3178 // The one-argument version logs to infostream.
3179 // The two-argument version accept a log level: error, action, info, or verbose.
3180 static int l_log(lua_State *L)
3183 LogMessageLevel level = LMT_INFO;
3184 if(lua_isnone(L, 2))
3186 text = lua_tostring(L, 1);
3190 std::string levelname = lua_tostring(L, 1);
3191 text = lua_tostring(L, 2);
3192 if(levelname == "error")
3194 else if(levelname == "action")
3196 else if(levelname == "verbose")
3197 level = LMT_VERBOSE;
3199 log_printline(level, text);
3203 // register_item_raw({lots of stuff})
3204 static int l_register_item_raw(lua_State *L)
3206 luaL_checktype(L, 1, LUA_TTABLE);
3209 // Get the writable item and node definition managers from the server
3210 IWritableItemDefManager *idef =
3211 get_server(L)->getWritableItemDefManager();
3212 IWritableNodeDefManager *ndef =
3213 get_server(L)->getWritableNodeDefManager();
3215 // Check if name is defined
3216 lua_getfield(L, table, "name");
3217 if(lua_isstring(L, -1)){
3218 std::string name = lua_tostring(L, -1);
3219 infostream<<"register_item_raw: "<<name<<std::endl;
3221 throw LuaError(L, "register_item_raw: name is not defined or not a string");
3224 // Check if on_use is defined
3226 // Read the item definition and register it
3227 ItemDefinition def = read_item_definition(L, table);
3228 idef->registerItem(def);
3230 // Read the node definition (content features) and register it
3231 if(def.type == ITEM_NODE)
3233 ContentFeatures f = read_content_features(L, table);
3234 ndef->set(f.name, f);
3237 return 0; /* number of results */
3240 // register_alias_raw(name, convert_to_name)
3241 static int l_register_alias_raw(lua_State *L)
3243 std::string name = luaL_checkstring(L, 1);
3244 std::string convert_to = luaL_checkstring(L, 2);
3246 // Get the writable item definition manager from the server
3247 IWritableItemDefManager *idef =
3248 get_server(L)->getWritableItemDefManager();
3250 idef->registerAlias(name, convert_to);
3252 return 0; /* number of results */
3255 // helper for register_craft
3256 static bool read_craft_recipe_shaped(lua_State *L, int index,
3257 int &width, std::vector<std::string> &recipe)
3260 index = lua_gettop(L) + 1 + index;
3262 if(!lua_istable(L, index))
3267 while(lua_next(L, index) != 0){
3269 // key at index -2 and value at index -1
3270 if(!lua_istable(L, -1))
3272 int table2 = lua_gettop(L);
3274 while(lua_next(L, table2) != 0){
3275 // key at index -2 and value at index -1
3276 if(!lua_isstring(L, -1))
3278 recipe.push_back(lua_tostring(L, -1));
3279 // removes value, keeps key for next iteration
3286 if(colcount != width)
3289 // removes value, keeps key for next iteration
3296 // helper for register_craft
3297 static bool read_craft_recipe_shapeless(lua_State *L, int index,
3298 std::vector<std::string> &recipe)
3301 index = lua_gettop(L) + 1 + index;
3303 if(!lua_istable(L, index))
3307 while(lua_next(L, index) != 0){
3308 // key at index -2 and value at index -1
3309 if(!lua_isstring(L, -1))
3311 recipe.push_back(lua_tostring(L, -1));
3312 // removes value, keeps key for next iteration
3318 // helper for register_craft
3319 static bool read_craft_replacements(lua_State *L, int index,
3320 CraftReplacements &replacements)
3323 index = lua_gettop(L) + 1 + index;
3325 if(!lua_istable(L, index))
3329 while(lua_next(L, index) != 0){
3330 // key at index -2 and value at index -1
3331 if(!lua_istable(L, -1))
3333 lua_rawgeti(L, -1, 1);
3334 if(!lua_isstring(L, -1))
3336 std::string replace_from = lua_tostring(L, -1);
3338 lua_rawgeti(L, -1, 2);
3339 if(!lua_isstring(L, -1))
3341 std::string replace_to = lua_tostring(L, -1);
3343 replacements.pairs.push_back(
3344 std::make_pair(replace_from, replace_to));
3345 // removes value, keeps key for next iteration
3350 // register_craft({output=item, recipe={{item00,item10},{item01,item11}})
3351 static int l_register_craft(lua_State *L)
3353 //infostream<<"register_craft"<<std::endl;
3354 luaL_checktype(L, 1, LUA_TTABLE);
3357 // Get the writable craft definition manager from the server
3358 IWritableCraftDefManager *craftdef =
3359 get_server(L)->getWritableCraftDefManager();
3361 std::string type = getstringfield_default(L, table, "type", "shaped");
3364 CraftDefinitionShaped
3366 if(type == "shaped"){
3367 std::string output = getstringfield_default(L, table, "output", "");
3369 throw LuaError(L, "Crafting definition is missing an output");
3372 std::vector<std::string> recipe;
3373 lua_getfield(L, table, "recipe");
3374 if(lua_isnil(L, -1))
3375 throw LuaError(L, "Crafting definition is missing a recipe"
3376 " (output=\"" + output + "\")");
3377 if(!read_craft_recipe_shaped(L, -1, width, recipe))
3378 throw LuaError(L, "Invalid crafting recipe"
3379 " (output=\"" + output + "\")");
3381 CraftReplacements replacements;
3382 lua_getfield(L, table, "replacements");
3383 if(!lua_isnil(L, -1))
3385 if(!read_craft_replacements(L, -1, replacements))
3386 throw LuaError(L, "Invalid replacements"
3387 " (output=\"" + output + "\")");
3390 CraftDefinition *def = new CraftDefinitionShaped(
3391 output, width, recipe, replacements);
3392 craftdef->registerCraft(def);
3395 CraftDefinitionShapeless
3397 else if(type == "shapeless"){
3398 std::string output = getstringfield_default(L, table, "output", "");
3400 throw LuaError(L, "Crafting definition (shapeless)"
3401 " is missing an output");
3403 std::vector<std::string> recipe;
3404 lua_getfield(L, table, "recipe");
3405 if(lua_isnil(L, -1))
3406 throw LuaError(L, "Crafting definition (shapeless)"
3407 " is missing a recipe"
3408 " (output=\"" + output + "\")");
3409 if(!read_craft_recipe_shapeless(L, -1, recipe))
3410 throw LuaError(L, "Invalid crafting recipe"
3411 " (output=\"" + output + "\")");
3413 CraftReplacements replacements;
3414 lua_getfield(L, table, "replacements");
3415 if(!lua_isnil(L, -1))
3417 if(!read_craft_replacements(L, -1, replacements))
3418 throw LuaError(L, "Invalid replacements"
3419 " (output=\"" + output + "\")");
3422 CraftDefinition *def = new CraftDefinitionShapeless(
3423 output, recipe, replacements);
3424 craftdef->registerCraft(def);
3427 CraftDefinitionToolRepair
3429 else if(type == "toolrepair"){
3430 float additional_wear = getfloatfield_default(L, table,
3431 "additional_wear", 0.0);
3433 CraftDefinition *def = new CraftDefinitionToolRepair(
3435 craftdef->registerCraft(def);
3438 CraftDefinitionCooking
3440 else if(type == "cooking"){
3441 std::string output = getstringfield_default(L, table, "output", "");
3443 throw LuaError(L, "Crafting definition (cooking)"
3444 " is missing an output");
3446 std::string recipe = getstringfield_default(L, table, "recipe", "");
3448 throw LuaError(L, "Crafting definition (cooking)"
3449 " is missing a recipe"
3450 " (output=\"" + output + "\")");
3452 float cooktime = getfloatfield_default(L, table, "cooktime", 3.0);
3454 CraftDefinition *def = new CraftDefinitionCooking(
3455 output, recipe, cooktime);
3456 craftdef->registerCraft(def);
3461 else if(type == "fuel"){
3462 std::string recipe = getstringfield_default(L, table, "recipe", "");
3464 throw LuaError(L, "Crafting definition (fuel)"
3465 " is missing a recipe");
3467 float burntime = getfloatfield_default(L, table, "burntime", 1.0);
3469 CraftDefinition *def = new CraftDefinitionFuel(
3471 craftdef->registerCraft(def);
3475 throw LuaError(L, "Unknown crafting definition type: \"" + type + "\"");
3479 return 0; /* number of results */
3482 // setting_get(name)
3483 static int l_setting_get(lua_State *L)
3485 const char *name = luaL_checkstring(L, 1);
3487 std::string value = g_settings->get(name);
3488 lua_pushstring(L, value.c_str());
3489 } catch(SettingNotFoundException &e){
3495 // setting_getbool(name)
3496 static int l_setting_getbool(lua_State *L)
3498 const char *name = luaL_checkstring(L, 1);
3500 bool value = g_settings->getBool(name);
3501 lua_pushboolean(L, value);
3502 } catch(SettingNotFoundException &e){
3508 // chat_send_all(text)
3509 static int l_chat_send_all(lua_State *L)
3511 const char *text = luaL_checkstring(L, 1);
3512 // Get server from registry
3513 Server *server = get_server(L);
3515 server->notifyPlayers(narrow_to_wide(text));
3519 // chat_send_player(name, text)
3520 static int l_chat_send_player(lua_State *L)
3522 const char *name = luaL_checkstring(L, 1);
3523 const char *text = luaL_checkstring(L, 2);
3524 // Get server from registry
3525 Server *server = get_server(L);
3527 server->notifyPlayer(name, narrow_to_wide(text));
3531 // get_player_privs(name, text)
3532 static int l_get_player_privs(lua_State *L)
3534 const char *name = luaL_checkstring(L, 1);
3535 // Get server from registry
3536 Server *server = get_server(L);
3539 int table = lua_gettop(L);
3540 u64 privs_i = server->getPlayerAuthPrivs(name);
3541 // Special case for the "name" setting (local player / server owner)
3542 if(name == g_settings->get("name"))
3544 std::set<std::string> privs_s = privsToSet(privs_i);
3545 for(std::set<std::string>::const_iterator
3546 i = privs_s.begin(); i != privs_s.end(); i++){
3547 lua_pushboolean(L, true);
3548 lua_setfield(L, table, i->c_str());
3550 lua_pushvalue(L, table);
3554 // get_inventory(location)
3555 static int l_get_inventory(lua_State *L)
3557 InventoryLocation loc;
3559 std::string type = checkstringfield(L, 1, "type");
3560 if(type == "player"){
3561 std::string name = checkstringfield(L, 1, "name");
3562 loc.setPlayer(name);
3563 } else if(type == "node"){
3564 lua_getfield(L, 1, "pos");
3565 v3s16 pos = check_v3s16(L, -1);
3566 loc.setNodeMeta(pos);
3569 if(get_server(L)->getInventory(loc) != NULL)
3570 InvRef::create(L, loc);
3576 // get_dig_params(groups, tool_capabilities[, time_from_last_punch])
3577 static int l_get_dig_params(lua_State *L)
3579 std::map<std::string, int> groups;
3580 read_groups(L, 1, groups);
3581 ToolCapabilities tp = read_tool_capabilities(L, 2);
3582 if(lua_isnoneornil(L, 3))
3583 push_dig_params(L, getDigParams(groups, &tp));
3585 push_dig_params(L, getDigParams(groups, &tp,
3586 luaL_checknumber(L, 3)));
3590 // get_hit_params(groups, tool_capabilities[, time_from_last_punch])
3591 static int l_get_hit_params(lua_State *L)
3593 std::map<std::string, int> groups;
3594 read_groups(L, 1, groups);
3595 ToolCapabilities tp = read_tool_capabilities(L, 2);
3596 if(lua_isnoneornil(L, 3))
3597 push_hit_params(L, getHitParams(groups, &tp));
3599 push_hit_params(L, getHitParams(groups, &tp,
3600 luaL_checknumber(L, 3)));
3604 // get_current_modname()
3605 static int l_get_current_modname(lua_State *L)
3607 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
3611 // get_modpath(modname)
3612 static int l_get_modpath(lua_State *L)
3614 const char *modname = luaL_checkstring(L, 1);
3616 const ModSpec *mod = get_server(L)->getModSpec(modname);
3621 lua_pushstring(L, mod->path.c_str());
3626 static int l_get_worldpath(lua_State *L)
3628 std::string worldpath = get_server(L)->getWorldPath();
3629 lua_pushstring(L, worldpath.c_str());
3633 static const struct luaL_Reg minetest_f [] = {
3636 {"register_item_raw", l_register_item_raw},
3637 {"register_alias_raw", l_register_alias_raw},
3638 {"register_craft", l_register_craft},
3639 {"setting_get", l_setting_get},
3640 {"setting_getbool", l_setting_getbool},
3641 {"chat_send_all", l_chat_send_all},
3642 {"chat_send_player", l_chat_send_player},
3643 {"get_player_privs", l_get_player_privs},
3644 {"get_inventory", l_get_inventory},
3645 {"get_dig_params", l_get_dig_params},
3646 {"get_hit_params", l_get_hit_params},
3647 {"get_current_modname", l_get_current_modname},
3648 {"get_modpath", l_get_modpath},
3649 {"get_worldpath", l_get_worldpath},
3654 Main export function
3657 void scriptapi_export(lua_State *L, Server *server)
3660 assert(lua_checkstack(L, 20));
3661 infostream<<"scriptapi_export"<<std::endl;
3662 StackUnroller stack_unroller(L);
3664 // Store server as light userdata in registry
3665 lua_pushlightuserdata(L, server);
3666 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_server");
3668 // Register global functions in table minetest
3670 luaL_register(L, NULL, minetest_f);
3671 lua_setglobal(L, "minetest");
3673 // Get the main minetest table
3674 lua_getglobal(L, "minetest");
3676 // Add tables to minetest
3679 lua_setfield(L, -2, "object_refs");
3681 lua_setfield(L, -2, "luaentities");
3683 // Register wrappers
3684 LuaItemStack::Register(L);
3685 InvRef::Register(L);
3686 NodeMetaRef::Register(L);
3687 ObjectRef::Register(L);
3688 EnvRef::Register(L);
3691 bool scriptapi_loadmod(lua_State *L, const std::string &scriptpath,
3692 const std::string &modname)
3694 ModNameStorer modnamestorer(L, modname);
3696 if(!string_allowed(modname, "abcdefghijklmnopqrstuvwxyz"
3698 errorstream<<"Error loading mod \""<<modname
3699 <<"\": modname does not follow naming conventions: "
3700 <<"Only chararacters [a-z0-9_] are allowed."<<std::endl;
3704 bool success = false;
3707 success = script_load(L, scriptpath.c_str());
3710 errorstream<<"Error loading mod \""<<modname
3711 <<"\": "<<e.what()<<std::endl;
3717 void scriptapi_add_environment(lua_State *L, ServerEnvironment *env)
3720 assert(lua_checkstack(L, 20));
3721 infostream<<"scriptapi_add_environment"<<std::endl;
3722 StackUnroller stack_unroller(L);
3724 // Create EnvRef on stack
3725 EnvRef::create(L, env);
3726 int envref = lua_gettop(L);
3728 // minetest.env = envref
3729 lua_getglobal(L, "minetest");
3730 luaL_checktype(L, -1, LUA_TTABLE);
3731 lua_pushvalue(L, envref);
3732 lua_setfield(L, -2, "env");
3734 // Store environment as light userdata in registry
3735 lua_pushlightuserdata(L, env);
3736 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_env");
3739 Add ActiveBlockModifiers to environment
3742 // Get minetest.registered_abms
3743 lua_getglobal(L, "minetest");
3744 lua_getfield(L, -1, "registered_abms");
3745 luaL_checktype(L, -1, LUA_TTABLE);
3746 int registered_abms = lua_gettop(L);
3748 if(lua_istable(L, registered_abms)){
3749 int table = lua_gettop(L);
3751 while(lua_next(L, table) != 0){
3752 // key at index -2 and value at index -1
3753 int id = lua_tonumber(L, -2);
3754 int current_abm = lua_gettop(L);
3756 std::set<std::string> trigger_contents;
3757 lua_getfield(L, current_abm, "nodenames");
3758 if(lua_istable(L, -1)){
3759 int table = lua_gettop(L);
3761 while(lua_next(L, table) != 0){
3762 // key at index -2 and value at index -1
3763 luaL_checktype(L, -1, LUA_TSTRING);
3764 trigger_contents.insert(lua_tostring(L, -1));
3765 // removes value, keeps key for next iteration
3768 } else if(lua_isstring(L, -1)){
3769 trigger_contents.insert(lua_tostring(L, -1));
3773 std::set<std::string> required_neighbors;
3774 lua_getfield(L, current_abm, "neighbors");
3775 if(lua_istable(L, -1)){
3776 int table = lua_gettop(L);
3778 while(lua_next(L, table) != 0){
3779 // key at index -2 and value at index -1
3780 luaL_checktype(L, -1, LUA_TSTRING);
3781 required_neighbors.insert(lua_tostring(L, -1));
3782 // removes value, keeps key for next iteration
3785 } else if(lua_isstring(L, -1)){
3786 required_neighbors.insert(lua_tostring(L, -1));
3790 float trigger_interval = 10.0;
3791 getfloatfield(L, current_abm, "interval", trigger_interval);
3793 int trigger_chance = 50;
3794 getintfield(L, current_abm, "chance", trigger_chance);
3796 LuaABM *abm = new LuaABM(L, id, trigger_contents,
3797 required_neighbors, trigger_interval, trigger_chance);
3799 env->addActiveBlockModifier(abm);
3801 // removes value, keeps key for next iteration
3809 // Dump stack top with the dump2 function
3810 static void dump2(lua_State *L, const char *name)
3812 // Dump object (debug)
3813 lua_getglobal(L, "dump2");
3814 luaL_checktype(L, -1, LUA_TFUNCTION);
3815 lua_pushvalue(L, -2); // Get previous stack top as first parameter
3816 lua_pushstring(L, name);
3817 if(lua_pcall(L, 2, 0, 0))
3818 script_error(L, "error: %s", lua_tostring(L, -1));
3826 void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj)
3829 assert(lua_checkstack(L, 20));
3830 //infostream<<"scriptapi_add_object_reference: id="<<cobj->getId()<<std::endl;
3831 StackUnroller stack_unroller(L);
3833 // Create object on stack
3834 ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack
3835 int object = lua_gettop(L);
3837 // Get minetest.object_refs table
3838 lua_getglobal(L, "minetest");
3839 lua_getfield(L, -1, "object_refs");
3840 luaL_checktype(L, -1, LUA_TTABLE);
3841 int objectstable = lua_gettop(L);
3843 // object_refs[id] = object
3844 lua_pushnumber(L, cobj->getId()); // Push id
3845 lua_pushvalue(L, object); // Copy object to top of stack
3846 lua_settable(L, objectstable);
3849 void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj)
3852 assert(lua_checkstack(L, 20));
3853 //infostream<<"scriptapi_rm_object_reference: id="<<cobj->getId()<<std::endl;
3854 StackUnroller stack_unroller(L);
3856 // Get minetest.object_refs table
3857 lua_getglobal(L, "minetest");
3858 lua_getfield(L, -1, "object_refs");
3859 luaL_checktype(L, -1, LUA_TTABLE);
3860 int objectstable = lua_gettop(L);
3862 // Get object_refs[id]
3863 lua_pushnumber(L, cobj->getId()); // Push id
3864 lua_gettable(L, objectstable);
3865 // Set object reference to NULL
3866 ObjectRef::set_null(L);
3867 lua_pop(L, 1); // pop object
3869 // Set object_refs[id] = nil
3870 lua_pushnumber(L, cobj->getId()); // Push id
3872 lua_settable(L, objectstable);
3875 bool scriptapi_on_chat_message(lua_State *L, const std::string &name,
3876 const std::string &message)
3879 assert(lua_checkstack(L, 20));
3880 StackUnroller stack_unroller(L);
3882 // Get minetest.registered_on_chat_messages
3883 lua_getglobal(L, "minetest");
3884 lua_getfield(L, -1, "registered_on_chat_messages");
3885 luaL_checktype(L, -1, LUA_TTABLE);
3886 int table = lua_gettop(L);
3889 while(lua_next(L, table) != 0){
3890 // key at index -2 and value at index -1
3891 luaL_checktype(L, -1, LUA_TFUNCTION);
3893 lua_pushstring(L, name.c_str());
3894 lua_pushstring(L, message.c_str());
3895 if(lua_pcall(L, 2, 1, 0))
3896 script_error(L, "error: %s", lua_tostring(L, -1));
3897 bool ate = lua_toboolean(L, -1);
3901 // value removed, keep key for next iteration
3910 void scriptapi_on_newplayer(lua_State *L, ServerActiveObject *player)
3913 assert(lua_checkstack(L, 20));
3914 StackUnroller stack_unroller(L);
3916 // Get minetest.registered_on_newplayers
3917 lua_getglobal(L, "minetest");
3918 lua_getfield(L, -1, "registered_on_newplayers");
3919 luaL_checktype(L, -1, LUA_TTABLE);
3920 int table = lua_gettop(L);
3923 while(lua_next(L, table) != 0){
3924 // key at index -2 and value at index -1
3925 luaL_checktype(L, -1, LUA_TFUNCTION);
3927 objectref_get_or_create(L, player);
3928 if(lua_pcall(L, 1, 0, 0))
3929 script_error(L, "error: %s", lua_tostring(L, -1));
3930 // value removed, keep key for next iteration
3934 void scriptapi_on_dieplayer(lua_State *L, ServerActiveObject *player)
3937 assert(lua_checkstack(L, 20));
3938 StackUnroller stack_unroller(L);
3940 // Get minetest.registered_on_dieplayers
3941 lua_getglobal(L, "minetest");
3942 lua_getfield(L, -1, "registered_on_dieplayers");
3943 luaL_checktype(L, -1, LUA_TTABLE);
3944 int table = lua_gettop(L);
3947 while(lua_next(L, table) != 0){
3948 // key at index -2 and value at index -1
3949 luaL_checktype(L, -1, LUA_TFUNCTION);
3951 objectref_get_or_create(L, player);
3952 if(lua_pcall(L, 1, 0, 0))
3953 script_error(L, "error: %s", lua_tostring(L, -1));
3954 // value removed, keep key for next iteration
3959 bool scriptapi_on_respawnplayer(lua_State *L, ServerActiveObject *player)
3962 assert(lua_checkstack(L, 20));
3963 StackUnroller stack_unroller(L);
3965 dstream<<"player: "<<player<<" id: "<<player->getId()<<std::endl;
3967 bool positioning_handled_by_some = false;
3969 // Get minetest.registered_on_respawnplayers
3970 lua_getglobal(L, "minetest");
3971 lua_getfield(L, -1, "registered_on_respawnplayers");
3972 luaL_checktype(L, -1, LUA_TTABLE);
3973 int table = lua_gettop(L);
3976 while(lua_next(L, table) != 0){
3977 // key at index -2 and value at index -1
3978 luaL_checktype(L, -1, LUA_TFUNCTION);
3980 objectref_get_or_create(L, player);
3981 if(lua_pcall(L, 1, 1, 0))
3982 script_error(L, "error: %s", lua_tostring(L, -1));
3983 bool positioning_handled = lua_toboolean(L, -1);
3985 if(positioning_handled)
3986 positioning_handled_by_some = true;
3987 // value removed, keep key for next iteration
3989 return positioning_handled_by_some;
3992 void scriptapi_get_creative_inventory(lua_State *L, ServerRemotePlayer *player)
3994 lua_getglobal(L, "minetest");
3995 lua_getfield(L, -1, "creative_inventory");
3996 luaL_checktype(L, -1, LUA_TTABLE);
3997 inventory_set_list_from_lua(&player->inventory, "main", L, -1,
3998 PLAYER_INVENTORY_SIZE);
4002 item callbacks and node callbacks
4005 // Retrieves minetest.registered_items[name][callbackname]
4006 // If that is nil or on error, return false and stack is unchanged
4007 // If that is a function, returns true and pushes the
4008 // function onto the stack
4009 static bool get_item_callback(lua_State *L,
4010 const char *name, const char *callbackname)
4012 lua_getglobal(L, "minetest");
4013 lua_getfield(L, -1, "registered_items");
4015 luaL_checktype(L, -1, LUA_TTABLE);
4016 lua_getfield(L, -1, name);
4018 // Should be a table
4019 if(lua_type(L, -1) != LUA_TTABLE)
4021 errorstream<<"Item \""<<name<<"\" not defined"<<std::endl;
4025 lua_getfield(L, -1, callbackname);
4027 // Should be a function or nil
4028 if(lua_type(L, -1) == LUA_TFUNCTION)
4032 else if(lua_isnil(L, -1))
4039 errorstream<<"Item \""<<name<<"\" callback \""
4040 <<callbackname<<" is not a function"<<std::endl;
4046 bool scriptapi_item_on_drop(lua_State *L, ItemStack &item,
4047 ServerActiveObject *dropper, v3f pos)
4050 assert(lua_checkstack(L, 20));
4051 StackUnroller stack_unroller(L);
4053 // Push callback function on stack
4054 if(!get_item_callback(L, item.name.c_str(), "on_drop"))
4058 LuaItemStack::create(L, item);
4059 objectref_get_or_create(L, dropper);
4060 pushFloatPos(L, pos);
4061 if(lua_pcall(L, 3, 1, 0))
4062 script_error(L, "error: %s", lua_tostring(L, -1));
4063 if(!lua_isnil(L, -1))
4064 item = read_item(L, -1);
4068 bool scriptapi_item_on_place(lua_State *L, ItemStack &item,
4069 ServerActiveObject *placer, const PointedThing &pointed)
4072 assert(lua_checkstack(L, 20));
4073 StackUnroller stack_unroller(L);
4075 // Push callback function on stack
4076 if(!get_item_callback(L, item.name.c_str(), "on_place"))
4080 LuaItemStack::create(L, item);
4081 objectref_get_or_create(L, placer);
4082 push_pointed_thing(L, pointed);
4083 if(lua_pcall(L, 3, 1, 0))
4084 script_error(L, "error: %s", lua_tostring(L, -1));
4085 if(!lua_isnil(L, -1))
4086 item = read_item(L, -1);
4090 bool scriptapi_item_on_use(lua_State *L, ItemStack &item,
4091 ServerActiveObject *user, const PointedThing &pointed)
4094 assert(lua_checkstack(L, 20));
4095 StackUnroller stack_unroller(L);
4097 // Push callback function on stack
4098 if(!get_item_callback(L, item.name.c_str(), "on_use"))
4102 LuaItemStack::create(L, item);
4103 objectref_get_or_create(L, user);
4104 push_pointed_thing(L, pointed);
4105 if(lua_pcall(L, 3, 1, 0))
4106 script_error(L, "error: %s", lua_tostring(L, -1));
4107 if(!lua_isnil(L, -1))
4108 item = read_item(L, -1);
4112 bool scriptapi_node_on_punch(lua_State *L, v3s16 pos, MapNode node,
4113 ServerActiveObject *puncher)
4116 assert(lua_checkstack(L, 20));
4117 StackUnroller stack_unroller(L);
4119 INodeDefManager *ndef = get_server(L)->ndef();
4121 // Push callback function on stack
4122 if(!get_item_callback(L, ndef->get(node).name.c_str(), "on_punch"))
4127 pushnode(L, node, ndef);
4128 objectref_get_or_create(L, puncher);
4129 if(lua_pcall(L, 3, 0, 0))
4130 script_error(L, "error: %s", lua_tostring(L, -1));
4134 bool scriptapi_node_on_dig(lua_State *L, v3s16 pos, MapNode node,
4135 ServerActiveObject *digger)
4138 assert(lua_checkstack(L, 20));
4139 StackUnroller stack_unroller(L);
4141 INodeDefManager *ndef = get_server(L)->ndef();
4143 // Push callback function on stack
4144 if(!get_item_callback(L, ndef->get(node).name.c_str(), "on_dig"))
4149 pushnode(L, node, ndef);
4150 objectref_get_or_create(L, digger);
4151 if(lua_pcall(L, 3, 0, 0))
4152 script_error(L, "error: %s", lua_tostring(L, -1));
4160 void scriptapi_environment_step(lua_State *L, float dtime)
4163 assert(lua_checkstack(L, 20));
4164 //infostream<<"scriptapi_environment_step"<<std::endl;
4165 StackUnroller stack_unroller(L);
4167 // Get minetest.registered_globalsteps
4168 lua_getglobal(L, "minetest");
4169 lua_getfield(L, -1, "registered_globalsteps");
4170 luaL_checktype(L, -1, LUA_TTABLE);
4171 int table = lua_gettop(L);
4174 while(lua_next(L, table) != 0){
4175 // key at index -2 and value at index -1
4176 luaL_checktype(L, -1, LUA_TFUNCTION);
4178 lua_pushnumber(L, dtime);
4179 if(lua_pcall(L, 1, 0, 0))
4180 script_error(L, "error: %s", lua_tostring(L, -1));
4181 // value removed, keep key for next iteration
4185 void scriptapi_environment_on_generated(lua_State *L, v3s16 minp, v3s16 maxp)
4188 assert(lua_checkstack(L, 20));
4189 //infostream<<"scriptapi_environment_on_generated"<<std::endl;
4190 StackUnroller stack_unroller(L);
4192 // Get minetest.registered_on_generateds
4193 lua_getglobal(L, "minetest");
4194 lua_getfield(L, -1, "registered_on_generateds");
4195 luaL_checktype(L, -1, LUA_TTABLE);
4196 int table = lua_gettop(L);
4199 while(lua_next(L, table) != 0){
4200 // key at index -2 and value at index -1
4201 luaL_checktype(L, -1, LUA_TFUNCTION);
4203 push_v3s16(L, minp);
4204 push_v3s16(L, maxp);
4205 if(lua_pcall(L, 2, 0, 0))
4206 script_error(L, "error: %s", lua_tostring(L, -1));
4207 // value removed, keep key for next iteration
4215 bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
4216 const std::string &staticdata)
4219 assert(lua_checkstack(L, 20));
4220 infostream<<"scriptapi_luaentity_add: id="<<id<<" name=\""
4221 <<name<<"\""<<std::endl;
4222 StackUnroller stack_unroller(L);
4224 // Get minetest.registered_entities[name]
4225 lua_getglobal(L, "minetest");
4226 lua_getfield(L, -1, "registered_entities");
4227 luaL_checktype(L, -1, LUA_TTABLE);
4228 lua_pushstring(L, name);
4229 lua_gettable(L, -2);
4230 // Should be a table, which we will use as a prototype
4231 //luaL_checktype(L, -1, LUA_TTABLE);
4232 if(lua_type(L, -1) != LUA_TTABLE){
4233 errorstream<<"LuaEntity name \""<<name<<"\" not defined"<<std::endl;
4236 int prototype_table = lua_gettop(L);
4237 //dump2(L, "prototype_table");
4239 // Create entity object
4241 int object = lua_gettop(L);
4243 // Set object metatable
4244 lua_pushvalue(L, prototype_table);
4245 lua_setmetatable(L, -2);
4247 // Add object reference
4248 // This should be userdata with metatable ObjectRef
4249 objectref_get(L, id);
4250 luaL_checktype(L, -1, LUA_TUSERDATA);
4251 if(!luaL_checkudata(L, -1, "ObjectRef"))
4252 luaL_typerror(L, -1, "ObjectRef");
4253 lua_setfield(L, -2, "object");
4255 // minetest.luaentities[id] = object
4256 lua_getglobal(L, "minetest");
4257 lua_getfield(L, -1, "luaentities");
4258 luaL_checktype(L, -1, LUA_TTABLE);
4259 lua_pushnumber(L, id); // Push id
4260 lua_pushvalue(L, object); // Copy object to top of stack
4261 lua_settable(L, -3);
4263 // Get on_activate function
4264 lua_pushvalue(L, object);
4265 lua_getfield(L, -1, "on_activate");
4266 if(!lua_isnil(L, -1)){
4267 luaL_checktype(L, -1, LUA_TFUNCTION);
4268 lua_pushvalue(L, object); // self
4269 lua_pushlstring(L, staticdata.c_str(), staticdata.size());
4270 // Call with 2 arguments, 0 results
4271 if(lua_pcall(L, 2, 0, 0))
4272 script_error(L, "error running function %s:on_activate: %s\n",
4273 name, lua_tostring(L, -1));
4279 void scriptapi_luaentity_rm(lua_State *L, u16 id)
4282 assert(lua_checkstack(L, 20));
4283 infostream<<"scriptapi_luaentity_rm: id="<<id<<std::endl;
4285 // Get minetest.luaentities table
4286 lua_getglobal(L, "minetest");
4287 lua_getfield(L, -1, "luaentities");
4288 luaL_checktype(L, -1, LUA_TTABLE);
4289 int objectstable = lua_gettop(L);
4291 // Set luaentities[id] = nil
4292 lua_pushnumber(L, id); // Push id
4294 lua_settable(L, objectstable);
4296 lua_pop(L, 2); // pop luaentities, minetest
4299 std::string scriptapi_luaentity_get_staticdata(lua_State *L, u16 id)
4302 assert(lua_checkstack(L, 20));
4303 infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl;
4304 StackUnroller stack_unroller(L);
4306 // Get minetest.luaentities[id]
4307 luaentity_get(L, id);
4308 int object = lua_gettop(L);
4310 // Get get_staticdata function
4311 lua_pushvalue(L, object);
4312 lua_getfield(L, -1, "get_staticdata");
4313 if(lua_isnil(L, -1))
4316 luaL_checktype(L, -1, LUA_TFUNCTION);
4317 lua_pushvalue(L, object); // self
4318 // Call with 1 arguments, 1 results
4319 if(lua_pcall(L, 1, 1, 0))
4320 script_error(L, "error running function get_staticdata: %s\n",
4321 lua_tostring(L, -1));
4324 const char *s = lua_tolstring(L, -1, &len);
4325 return std::string(s, len);
4328 void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
4329 LuaEntityProperties *prop)
4332 assert(lua_checkstack(L, 20));
4333 infostream<<"scriptapi_luaentity_get_properties: id="<<id<<std::endl;
4334 StackUnroller stack_unroller(L);
4336 // Get minetest.luaentities[id]
4337 luaentity_get(L, id);
4338 //int object = lua_gettop(L);
4342 prop->hp_max = getintfield_default(L, -1, "hp_max", 10);
4344 getboolfield(L, -1, "physical", prop->physical);
4346 getfloatfield(L, -1, "weight", prop->weight);
4348 lua_getfield(L, -1, "collisionbox");
4349 if(lua_istable(L, -1))
4350 prop->collisionbox = read_aabbox3df32(L, -1, 1.0);
4353 getstringfield(L, -1, "visual", prop->visual);
4355 lua_getfield(L, -1, "visual_size");
4356 if(lua_istable(L, -1))
4357 prop->visual_size = read_v2f(L, -1);
4360 lua_getfield(L, -1, "textures");
4361 if(lua_istable(L, -1)){
4362 prop->textures.clear();
4363 int table = lua_gettop(L);
4365 while(lua_next(L, table) != 0){
4366 // key at index -2 and value at index -1
4367 if(lua_isstring(L, -1))
4368 prop->textures.push_back(lua_tostring(L, -1));
4370 prop->textures.push_back("");
4371 // removes value, keeps key for next iteration
4377 lua_getfield(L, -1, "spritediv");
4378 if(lua_istable(L, -1))
4379 prop->spritediv = read_v2s16(L, -1);
4382 lua_getfield(L, -1, "initial_sprite_basepos");
4383 if(lua_istable(L, -1))
4384 prop->initial_sprite_basepos = read_v2s16(L, -1);
4388 void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime)
4391 assert(lua_checkstack(L, 20));
4392 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
4393 StackUnroller stack_unroller(L);
4395 // Get minetest.luaentities[id]
4396 luaentity_get(L, id);
4397 int object = lua_gettop(L);
4398 // State: object is at top of stack
4399 // Get step function
4400 lua_getfield(L, -1, "on_step");
4401 if(lua_isnil(L, -1))
4403 luaL_checktype(L, -1, LUA_TFUNCTION);
4404 lua_pushvalue(L, object); // self
4405 lua_pushnumber(L, dtime); // dtime
4406 // Call with 2 arguments, 0 results
4407 if(lua_pcall(L, 2, 0, 0))
4408 script_error(L, "error running function 'on_step': %s\n", lua_tostring(L, -1));
4411 // Calls entity:on_punch(ObjectRef puncher, time_from_last_punch,
4412 // tool_capabilities, direction)
4413 void scriptapi_luaentity_punch(lua_State *L, u16 id,
4414 ServerActiveObject *puncher, float time_from_last_punch,
4415 const ToolCapabilities *toolcap, v3f dir)
4418 assert(lua_checkstack(L, 20));
4419 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
4420 StackUnroller stack_unroller(L);
4422 // Get minetest.luaentities[id]
4423 luaentity_get(L, id);
4424 int object = lua_gettop(L);
4425 // State: object is at top of stack
4427 lua_getfield(L, -1, "on_punch");
4428 if(lua_isnil(L, -1))
4430 luaL_checktype(L, -1, LUA_TFUNCTION);
4431 lua_pushvalue(L, object); // self
4432 objectref_get_or_create(L, puncher); // Clicker reference
4433 lua_pushnumber(L, time_from_last_punch);
4434 push_tool_capabilities(L, *toolcap);
4436 // Call with 5 arguments, 0 results
4437 if(lua_pcall(L, 5, 0, 0))
4438 script_error(L, "error running function 'on_punch': %s\n", lua_tostring(L, -1));
4441 // Calls entity:on_rightclick(ObjectRef clicker)
4442 void scriptapi_luaentity_rightclick(lua_State *L, u16 id,
4443 ServerActiveObject *clicker)
4446 assert(lua_checkstack(L, 20));
4447 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
4448 StackUnroller stack_unroller(L);
4450 // Get minetest.luaentities[id]
4451 luaentity_get(L, id);
4452 int object = lua_gettop(L);
4453 // State: object is at top of stack
4455 lua_getfield(L, -1, "on_rightclick");
4456 if(lua_isnil(L, -1))
4458 luaL_checktype(L, -1, LUA_TFUNCTION);
4459 lua_pushvalue(L, object); // self
4460 objectref_get_or_create(L, clicker); // Clicker reference
4461 // Call with 2 arguments, 0 results
4462 if(lua_pcall(L, 2, 0, 0))
4463 script_error(L, "error running function 'on_rightclick': %s\n", lua_tostring(L, -1));