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"
49 static void stackDump(lua_State *L, std::ostream &o)
52 int top = lua_gettop(L);
53 for (i = 1; i <= top; i++) { /* repeat for each level */
54 int t = lua_type(L, i);
57 case LUA_TSTRING: /* strings */
58 o<<"\""<<lua_tostring(L, i)<<"\"";
61 case LUA_TBOOLEAN: /* booleans */
62 o<<(lua_toboolean(L, i) ? "true" : "false");
65 case LUA_TNUMBER: /* numbers */ {
67 snprintf(buf, 10, "%g", lua_tonumber(L, i));
71 default: /* other values */
72 o<<lua_typename(L, t);
81 static void realitycheck(lua_State *L)
83 int top = lua_gettop(L);
85 dstream<<"Stack is over 30:"<<std::endl;
86 stackDump(L, dstream);
87 script_error(L, "Stack is over 30 (reality check)");
97 StackUnroller(lua_State *L):
101 m_original_top = lua_gettop(m_lua); // store stack height
105 lua_settop(m_lua, m_original_top); // restore stack height
114 ModNameStorer(lua_State *L_, const std::string modname):
117 // Store current modname in registry
118 lua_pushstring(L, modname.c_str());
119 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
123 // Clear current modname in registry
125 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
130 Getters for stuff in main tables
133 static Server* get_server(lua_State *L)
135 // Get server from registry
136 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
137 Server *server = (Server*)lua_touserdata(L, -1);
142 static ServerEnvironment* get_env(lua_State *L)
144 // Get environment from registry
145 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_env");
146 ServerEnvironment *env = (ServerEnvironment*)lua_touserdata(L, -1);
151 static void objectref_get(lua_State *L, u16 id)
153 // Get minetest.object_refs[i]
154 lua_getglobal(L, "minetest");
155 lua_getfield(L, -1, "object_refs");
156 luaL_checktype(L, -1, LUA_TTABLE);
157 lua_pushnumber(L, id);
159 lua_remove(L, -2); // object_refs
160 lua_remove(L, -2); // minetest
163 static void luaentity_get(lua_State *L, u16 id)
165 // Get minetest.luaentities[i]
166 lua_getglobal(L, "minetest");
167 lua_getfield(L, -1, "luaentities");
168 luaL_checktype(L, -1, LUA_TTABLE);
169 lua_pushnumber(L, id);
171 lua_remove(L, -2); // luaentities
172 lua_remove(L, -2); // minetest
179 static bool getstringfield(lua_State *L, int table,
180 const char *fieldname, std::string &result)
182 lua_getfield(L, table, fieldname);
184 if(lua_isstring(L, -1)){
186 const char *ptr = lua_tolstring(L, -1, &len);
187 result.assign(ptr, len);
194 static bool getintfield(lua_State *L, int table,
195 const char *fieldname, int &result)
197 lua_getfield(L, table, fieldname);
199 if(lua_isnumber(L, -1)){
200 result = lua_tonumber(L, -1);
207 static bool getfloatfield(lua_State *L, int table,
208 const char *fieldname, float &result)
210 lua_getfield(L, table, fieldname);
212 if(lua_isnumber(L, -1)){
213 result = lua_tonumber(L, -1);
220 static bool getboolfield(lua_State *L, int table,
221 const char *fieldname, bool &result)
223 lua_getfield(L, table, fieldname);
225 if(lua_isboolean(L, -1)){
226 result = lua_toboolean(L, -1);
233 static std::string checkstringfield(lua_State *L, int table,
234 const char *fieldname)
236 lua_getfield(L, table, fieldname);
237 std::string s = luaL_checkstring(L, -1);
242 static std::string getstringfield_default(lua_State *L, int table,
243 const char *fieldname, const std::string &default_)
245 std::string result = default_;
246 getstringfield(L, table, fieldname, result);
250 static int getintfield_default(lua_State *L, int table,
251 const char *fieldname, int default_)
253 int result = default_;
254 getintfield(L, table, fieldname, result);
258 static float getfloatfield_default(lua_State *L, int table,
259 const char *fieldname, float default_)
261 float result = default_;
262 getfloatfield(L, table, fieldname, result);
266 static bool getboolfield_default(lua_State *L, int table,
267 const char *fieldname, bool default_)
269 bool result = default_;
270 getboolfield(L, table, fieldname, result);
280 static bool string_to_enum(const EnumString *spec, int &result,
281 const std::string &str)
283 const EnumString *esp = spec;
285 if(str == std::string(esp->str)){
294 /*static bool enum_to_string(const EnumString *spec, std::string &result,
297 const EnumString *esp = spec;
308 static int getenumfield(lua_State *L, int table,
309 const char *fieldname, const EnumString *spec, int default_)
311 int result = default_;
312 string_to_enum(spec, result,
313 getstringfield_default(L, table, fieldname, ""));
317 static void setintfield(lua_State *L, int table,
318 const char *fieldname, int value)
320 lua_pushinteger(L, value);
323 lua_setfield(L, table, fieldname);
326 static void setfloatfield(lua_State *L, int table,
327 const char *fieldname, float value)
329 lua_pushnumber(L, value);
332 lua_setfield(L, table, fieldname);
335 static void setboolfield(lua_State *L, int table,
336 const char *fieldname, bool value)
338 lua_pushboolean(L, value);
341 lua_setfield(L, table, fieldname);
344 static void warn_if_field_exists(lua_State *L, int table,
345 const char *fieldname, const std::string &message)
347 lua_getfield(L, table, fieldname);
348 if(!lua_isnil(L, -1)){
349 infostream<<script_get_backtrace(L)<<std::endl;
350 infostream<<"WARNING: field \""<<fieldname<<"\": "
351 <<message<<std::endl;
357 EnumString definitions
360 struct EnumString es_ItemType[] =
364 {ITEM_CRAFT, "craft"},
369 struct EnumString es_DrawType[] =
371 {NDT_NORMAL, "normal"},
372 {NDT_AIRLIKE, "airlike"},
373 {NDT_LIQUID, "liquid"},
374 {NDT_FLOWINGLIQUID, "flowingliquid"},
375 {NDT_GLASSLIKE, "glasslike"},
376 {NDT_ALLFACES, "allfaces"},
377 {NDT_ALLFACES_OPTIONAL, "allfaces_optional"},
378 {NDT_TORCHLIKE, "torchlike"},
379 {NDT_SIGNLIKE, "signlike"},
380 {NDT_PLANTLIKE, "plantlike"},
381 {NDT_FENCELIKE, "fencelike"},
382 {NDT_RAILLIKE, "raillike"},
386 struct EnumString es_ContentParamType[] =
389 {CPT_LIGHT, "light"},
393 struct EnumString es_ContentParamType2[] =
397 {CPT2_FLOWINGLIQUID, "flowingliquid"},
398 {CPT2_FACEDIR, "facedir"},
399 {CPT2_WALLMOUNTED, "wallmounted"},
403 struct EnumString es_LiquidType[] =
405 {LIQUID_NONE, "none"},
406 {LIQUID_FLOWING, "flowing"},
407 {LIQUID_SOURCE, "source"},
411 struct EnumString es_NodeBoxType[] =
413 {NODEBOX_REGULAR, "regular"},
414 {NODEBOX_FIXED, "fixed"},
415 {NODEBOX_WALLMOUNTED, "wallmounted"},
419 struct EnumString es_Diggability[] =
421 {DIGGABLE_NOT, "not"},
422 {DIGGABLE_NORMAL, "normal"},
423 {DIGGABLE_CONSTANT, "constant"},
428 C struct <-> Lua table converter functions
431 static void push_v3f(lua_State *L, v3f p)
434 lua_pushnumber(L, p.X);
435 lua_setfield(L, -2, "x");
436 lua_pushnumber(L, p.Y);
437 lua_setfield(L, -2, "y");
438 lua_pushnumber(L, p.Z);
439 lua_setfield(L, -2, "z");
442 static v2s16 read_v2s16(lua_State *L, int index)
445 luaL_checktype(L, index, LUA_TTABLE);
446 lua_getfield(L, index, "x");
447 p.X = lua_tonumber(L, -1);
449 lua_getfield(L, index, "y");
450 p.Y = lua_tonumber(L, -1);
455 static v2f read_v2f(lua_State *L, int index)
458 luaL_checktype(L, index, LUA_TTABLE);
459 lua_getfield(L, index, "x");
460 p.X = lua_tonumber(L, -1);
462 lua_getfield(L, index, "y");
463 p.Y = lua_tonumber(L, -1);
468 static v3f read_v3f(lua_State *L, int index)
471 luaL_checktype(L, index, LUA_TTABLE);
472 lua_getfield(L, index, "x");
473 pos.X = lua_tonumber(L, -1);
475 lua_getfield(L, index, "y");
476 pos.Y = lua_tonumber(L, -1);
478 lua_getfield(L, index, "z");
479 pos.Z = lua_tonumber(L, -1);
484 static v3f check_v3f(lua_State *L, int index)
487 luaL_checktype(L, index, LUA_TTABLE);
488 lua_getfield(L, index, "x");
489 pos.X = luaL_checknumber(L, -1);
491 lua_getfield(L, index, "y");
492 pos.Y = luaL_checknumber(L, -1);
494 lua_getfield(L, index, "z");
495 pos.Z = luaL_checknumber(L, -1);
500 static void pushFloatPos(lua_State *L, v3f p)
506 static v3f checkFloatPos(lua_State *L, int index)
508 return check_v3f(L, index) * BS;
511 static void push_v3s16(lua_State *L, v3s16 p)
514 lua_pushnumber(L, p.X);
515 lua_setfield(L, -2, "x");
516 lua_pushnumber(L, p.Y);
517 lua_setfield(L, -2, "y");
518 lua_pushnumber(L, p.Z);
519 lua_setfield(L, -2, "z");
522 static v3s16 read_v3s16(lua_State *L, int index)
524 // Correct rounding at <0
525 v3f pf = read_v3f(L, index);
526 return floatToInt(pf, 1.0);
529 static v3s16 check_v3s16(lua_State *L, int index)
531 // Correct rounding at <0
532 v3f pf = check_v3f(L, index);
533 return floatToInt(pf, 1.0);
536 static void pushnode(lua_State *L, const MapNode &n, INodeDefManager *ndef)
539 lua_pushstring(L, ndef->get(n).name.c_str());
540 lua_setfield(L, -2, "name");
541 lua_pushnumber(L, n.getParam1());
542 lua_setfield(L, -2, "param1");
543 lua_pushnumber(L, n.getParam2());
544 lua_setfield(L, -2, "param2");
547 static MapNode readnode(lua_State *L, int index, INodeDefManager *ndef)
549 lua_getfield(L, index, "name");
550 const char *name = luaL_checkstring(L, -1);
553 lua_getfield(L, index, "param1");
557 param1 = lua_tonumber(L, -1);
560 lua_getfield(L, index, "param2");
564 param2 = lua_tonumber(L, -1);
566 return MapNode(ndef, name, param1, param2);
569 static video::SColor readARGB8(lua_State *L, int index)
572 luaL_checktype(L, index, LUA_TTABLE);
573 lua_getfield(L, index, "a");
574 if(lua_isnumber(L, -1))
575 color.setAlpha(lua_tonumber(L, -1));
577 lua_getfield(L, index, "r");
578 color.setRed(lua_tonumber(L, -1));
580 lua_getfield(L, index, "g");
581 color.setGreen(lua_tonumber(L, -1));
583 lua_getfield(L, index, "b");
584 color.setBlue(lua_tonumber(L, -1));
589 static core::aabbox3d<f32> read_aabbox3df32(lua_State *L, int index, f32 scale)
591 core::aabbox3d<f32> box;
592 if(lua_istable(L, -1)){
593 lua_rawgeti(L, -1, 1);
594 box.MinEdge.X = lua_tonumber(L, -1) * scale;
596 lua_rawgeti(L, -1, 2);
597 box.MinEdge.Y = lua_tonumber(L, -1) * scale;
599 lua_rawgeti(L, -1, 3);
600 box.MinEdge.Z = lua_tonumber(L, -1) * scale;
602 lua_rawgeti(L, -1, 4);
603 box.MaxEdge.X = lua_tonumber(L, -1) * scale;
605 lua_rawgeti(L, -1, 5);
606 box.MaxEdge.Y = lua_tonumber(L, -1) * scale;
608 lua_rawgeti(L, -1, 6);
609 box.MaxEdge.Z = lua_tonumber(L, -1) * scale;
619 static MaterialProperties read_material_properties(
620 lua_State *L, int table)
622 MaterialProperties prop;
623 prop.diggability = (Diggability)getenumfield(L, -1, "diggability",
624 es_Diggability, DIGGABLE_NORMAL);
625 getfloatfield(L, -1, "constant_time", prop.constant_time);
626 getfloatfield(L, -1, "weight", prop.weight);
627 getfloatfield(L, -1, "crackiness", prop.crackiness);
628 getfloatfield(L, -1, "crumbliness", prop.crumbliness);
629 getfloatfield(L, -1, "cuttability", prop.cuttability);
630 getfloatfield(L, -1, "flammability", prop.flammability);
635 ToolDiggingProperties
638 static ToolDiggingProperties read_tool_digging_properties(
639 lua_State *L, int table)
641 ToolDiggingProperties prop;
642 getfloatfield(L, table, "full_punch_interval", prop.full_punch_interval);
643 getfloatfield(L, table, "basetime", prop.basetime);
644 getfloatfield(L, table, "dt_weight", prop.dt_weight);
645 getfloatfield(L, table, "dt_crackiness", prop.dt_crackiness);
646 getfloatfield(L, table, "dt_crumbliness", prop.dt_crumbliness);
647 getfloatfield(L, table, "dt_cuttability", prop.dt_cuttability);
648 getfloatfield(L, table, "basedurability", prop.basedurability);
649 getfloatfield(L, table, "dd_weight", prop.dd_weight);
650 getfloatfield(L, table, "dd_crackiness", prop.dd_crackiness);
651 getfloatfield(L, table, "dd_crumbliness", prop.dd_crumbliness);
652 getfloatfield(L, table, "dd_cuttability", prop.dd_cuttability);
656 static void set_tool_digging_properties(lua_State *L, int table,
657 const ToolDiggingProperties &prop)
659 setfloatfield(L, table, "full_punch_interval", prop.full_punch_interval);
660 setfloatfield(L, table, "basetime", prop.basetime);
661 setfloatfield(L, table, "dt_weight", prop.dt_weight);
662 setfloatfield(L, table, "dt_crackiness", prop.dt_crackiness);
663 setfloatfield(L, table, "dt_crumbliness", prop.dt_crumbliness);
664 setfloatfield(L, table, "dt_cuttability", prop.dt_cuttability);
665 setfloatfield(L, table, "basedurability", prop.basedurability);
666 setfloatfield(L, table, "dd_weight", prop.dd_weight);
667 setfloatfield(L, table, "dd_crackiness", prop.dd_crackiness);
668 setfloatfield(L, table, "dd_crumbliness", prop.dd_crumbliness);
669 setfloatfield(L, table, "dd_cuttability", prop.dd_cuttability);
672 static void push_tool_digging_properties(lua_State *L,
673 const ToolDiggingProperties &prop)
676 set_tool_digging_properties(L, -1, prop);
683 static void set_digging_properties(lua_State *L, int table,
684 const DiggingProperties &prop)
686 setboolfield(L, table, "diggable", prop.diggable);
687 setfloatfield(L, table, "time", prop.time);
688 setintfield(L, table, "wear", prop.wear);
691 static void push_digging_properties(lua_State *L,
692 const DiggingProperties &prop)
695 set_digging_properties(L, -1, prop);
702 static void set_hitting_properties(lua_State *L, int table,
703 const HittingProperties &prop)
705 setintfield(L, table, "hp", prop.hp);
706 setintfield(L, table, "wear", prop.wear);
709 static void push_hitting_properties(lua_State *L,
710 const HittingProperties &prop)
713 set_hitting_properties(L, -1, prop);
720 static void push_pointed_thing(lua_State *L, const PointedThing& pointed)
723 if(pointed.type == POINTEDTHING_NODE)
725 lua_pushstring(L, "node");
726 lua_setfield(L, -2, "type");
727 push_v3s16(L, pointed.node_undersurface);
728 lua_setfield(L, -2, "under");
729 push_v3s16(L, pointed.node_abovesurface);
730 lua_setfield(L, -2, "above");
732 else if(pointed.type == POINTEDTHING_OBJECT)
734 lua_pushstring(L, "object");
735 lua_setfield(L, -2, "type");
736 objectref_get(L, pointed.object_id);
737 lua_setfield(L, -2, "ref");
741 lua_pushstring(L, "nothing");
742 lua_setfield(L, -2, "type");
750 static ItemDefinition read_item_definition(lua_State *L, int index)
753 index = lua_gettop(L) + 1 + index;
755 // Read the item definition
758 def.type = (ItemType)getenumfield(L, index, "type",
759 es_ItemType, ITEM_NONE);
760 getstringfield(L, index, "name", def.name);
761 getstringfield(L, index, "description", def.description);
762 getstringfield(L, index, "inventory_image", def.inventory_image);
763 getstringfield(L, index, "wield_image", def.wield_image);
765 lua_getfield(L, index, "wield_scale");
766 if(lua_istable(L, -1)){
767 def.wield_scale = check_v3f(L, -1);
771 def.stack_max = getintfield_default(L, index, "stack_max", def.stack_max);
772 if(def.stack_max == 0)
775 lua_getfield(L, index, "on_use");
776 def.usable = lua_isfunction(L, -1);
779 getboolfield(L, index, "liquids_pointable", def.liquids_pointable);
781 lua_getfield(L, index, "tool_digging_properties");
782 if(lua_istable(L, -1)){
783 def.tool_digging_properties = new ToolDiggingProperties(
784 read_tool_digging_properties(L, -1));
788 // If name is "" (hand), ensure there are ToolDiggingProperties
789 // because it will be looked up there whenever any other item has
790 // no ToolDiggingProperties
791 if(def.name == "" && def.tool_digging_properties == NULL){
792 def.tool_digging_properties = new ToolDiggingProperties();
802 static ContentFeatures read_content_features(lua_State *L, int index)
805 index = lua_gettop(L) + 1 + index;
808 getstringfield(L, index, "name", f.name);
810 /* Visual definition */
812 f.drawtype = (NodeDrawType)getenumfield(L, index, "drawtype", es_DrawType,
814 getfloatfield(L, index, "visual_scale", f.visual_scale);
816 lua_getfield(L, index, "tile_images");
817 if(lua_istable(L, -1)){
818 int table = lua_gettop(L);
821 while(lua_next(L, table) != 0){
822 // key at index -2 and value at index -1
823 if(lua_isstring(L, -1))
824 f.tname_tiles[i] = lua_tostring(L, -1);
826 f.tname_tiles[i] = "";
827 // removes value, keeps key for next iteration
835 // Copy last value to all remaining textures
837 std::string lastname = f.tname_tiles[i-1];
839 f.tname_tiles[i] = lastname;
846 lua_getfield(L, index, "special_materials");
847 if(lua_istable(L, -1)){
848 int table = lua_gettop(L);
851 while(lua_next(L, table) != 0){
852 // key at index -2 and value at index -1
853 int smtable = lua_gettop(L);
854 std::string tname = getstringfield_default(
855 L, smtable, "image", "");
856 bool backface_culling = getboolfield_default(
857 L, smtable, "backface_culling", true);
858 MaterialSpec mspec(tname, backface_culling);
859 f.mspec_special[i] = mspec;
860 // removes value, keeps key for next iteration
871 f.alpha = getintfield_default(L, index, "alpha", 255);
875 lua_getfield(L, index, "post_effect_color");
876 if(!lua_isnil(L, -1))
877 f.post_effect_color = readARGB8(L, -1);
880 f.param_type = (ContentParamType)getenumfield(L, index, "paramtype",
881 es_ContentParamType, CPT_NONE);
882 f.param_type_2 = (ContentParamType2)getenumfield(L, index, "paramtype2",
883 es_ContentParamType2, CPT2_NONE);
885 // Warn about some deprecated fields
886 warn_if_field_exists(L, index, "wall_mounted",
887 "deprecated: use paramtype2 = 'wallmounted'");
888 warn_if_field_exists(L, index, "light_propagates",
889 "deprecated: determined from paramtype");
890 warn_if_field_exists(L, index, "dug_item",
891 "deprecated: use 'drop' field");
892 warn_if_field_exists(L, index, "extra_dug_item",
893 "deprecated: use 'drop' field");
894 warn_if_field_exists(L, index, "extra_dug_item_rarity",
895 "deprecated: use 'drop' field");
897 // True for all ground-like things like stone and mud, false for eg. trees
898 getboolfield(L, index, "is_ground_content", f.is_ground_content);
899 f.light_propagates = (f.param_type == CPT_LIGHT);
900 getboolfield(L, index, "sunlight_propagates", f.sunlight_propagates);
901 // This is used for collision detection.
902 // Also for general solidness queries.
903 getboolfield(L, index, "walkable", f.walkable);
904 // Player can point to these
905 getboolfield(L, index, "pointable", f.pointable);
906 // Player can dig these
907 getboolfield(L, index, "diggable", f.diggable);
908 // Player can climb these
909 getboolfield(L, index, "climbable", f.climbable);
910 // Player can build on these
911 getboolfield(L, index, "buildable_to", f.buildable_to);
912 // Metadata name of node (eg. "furnace")
913 getstringfield(L, index, "metadata_name", f.metadata_name);
914 // Whether the node is non-liquid, source liquid or flowing liquid
915 f.liquid_type = (LiquidType)getenumfield(L, index, "liquidtype",
916 es_LiquidType, LIQUID_NONE);
917 // If the content is liquid, this is the flowing version of the liquid.
918 getstringfield(L, index, "liquid_alternative_flowing",
919 f.liquid_alternative_flowing);
920 // If the content is liquid, this is the source version of the liquid.
921 getstringfield(L, index, "liquid_alternative_source",
922 f.liquid_alternative_source);
923 // Viscosity for fluid flow, ranging from 1 to 7, with
924 // 1 giving almost instantaneous propagation and 7 being
925 // the slowest possible
926 f.liquid_viscosity = getintfield_default(L, index,
927 "liquid_viscosity", f.liquid_viscosity);
928 // Amount of light the node emits
929 f.light_source = getintfield_default(L, index,
930 "light_source", f.light_source);
931 f.damage_per_second = getintfield_default(L, index,
932 "damage_per_second", f.damage_per_second);
934 lua_getfield(L, index, "selection_box");
935 if(lua_istable(L, -1)){
936 f.selection_box.type = (NodeBoxType)getenumfield(L, -1, "type",
937 es_NodeBoxType, NODEBOX_REGULAR);
939 lua_getfield(L, -1, "fixed");
940 if(lua_istable(L, -1))
941 f.selection_box.fixed = read_aabbox3df32(L, -1, BS);
944 lua_getfield(L, -1, "wall_top");
945 if(lua_istable(L, -1))
946 f.selection_box.wall_top = read_aabbox3df32(L, -1, BS);
949 lua_getfield(L, -1, "wall_bottom");
950 if(lua_istable(L, -1))
951 f.selection_box.wall_bottom = read_aabbox3df32(L, -1, BS);
954 lua_getfield(L, -1, "wall_side");
955 if(lua_istable(L, -1))
956 f.selection_box.wall_side = read_aabbox3df32(L, -1, BS);
961 lua_getfield(L, index, "material");
962 if(lua_istable(L, -1)){
963 f.material = read_material_properties(L, -1);
967 // Set to true if paramtype used to be 'facedir_simple'
968 getboolfield(L, index, "legacy_facedir_simple", f.legacy_facedir_simple);
969 // Set to true if wall_mounted used to be set to true
970 getboolfield(L, index, "legacy_wallmounted", f.legacy_wallmounted);
979 static ItemStack read_item(lua_State *L, int index);
981 static void inventory_set_list_from_lua(Inventory *inv, const char *name,
982 lua_State *L, int tableindex, int forcesize=-1)
984 dstream<<"inventory_set_list_from_lua\n";
986 tableindex = lua_gettop(L) + 1 + tableindex;
987 // If nil, delete list
988 if(lua_isnil(L, tableindex)){
989 inv->deleteList(name);
992 // Otherwise set list
993 std::vector<ItemStack> items;
994 luaL_checktype(L, tableindex, LUA_TTABLE);
996 while(lua_next(L, tableindex) != 0){
997 // key at index -2 and value at index -1
998 items.push_back(read_item(L, -1));
999 // removes value, keeps key for next iteration
1002 int listsize = (forcesize != -1) ? forcesize : items.size();
1003 InventoryList *invlist = inv->addList(name, listsize);
1005 for(std::vector<ItemStack>::const_iterator
1006 i = items.begin(); i != items.end(); i++){
1007 if(forcesize != -1 && index == forcesize)
1009 invlist->changeItem(index, *i);
1012 while(forcesize != -1 && index < forcesize){
1013 invlist->deleteItem(index);
1016 dstream<<"inventory_set_list_from_lua done\n";
1019 static void inventory_get_list_to_lua(Inventory *inv, const char *name,
1022 InventoryList *invlist = inv->getList(name);
1023 if(invlist == NULL){
1027 // Get the table insert function
1028 lua_getglobal(L, "table");
1029 lua_getfield(L, -1, "insert");
1030 int table_insert = lua_gettop(L);
1031 // Create and fill table
1033 int table = lua_gettop(L);
1034 for(u32 i=0; i<invlist->getSize(); i++){
1035 ItemStack item = invlist->getItem(i);
1036 lua_pushvalue(L, table_insert);
1037 lua_pushvalue(L, table);
1038 lua_pushstring(L, item.getItemString().c_str());
1039 if(lua_pcall(L, 2, 0, 0))
1040 script_error(L, "error: %s", lua_tostring(L, -1));
1045 Helpful macros for userdata classes
1048 #define method(class, name) {#name, class::l_##name}
1059 static const char className[];
1060 static const luaL_reg methods[];
1062 // Exported functions
1064 // garbage collector
1065 static int gc_object(lua_State *L)
1067 LuaItemStack *o = *(LuaItemStack **)(lua_touserdata(L, 1));
1072 // is_empty(self) -> true/false
1073 static int l_is_empty(lua_State *L)
1075 LuaItemStack *o = checkobject(L, 1);
1076 ItemStack &item = o->m_stack;
1077 lua_pushboolean(L, item.empty());
1081 // get_name(self) -> string
1082 static int l_get_name(lua_State *L)
1084 LuaItemStack *o = checkobject(L, 1);
1085 ItemStack &item = o->m_stack;
1086 lua_pushstring(L, item.name.c_str());
1090 // get_count(self) -> number
1091 static int l_get_count(lua_State *L)
1093 LuaItemStack *o = checkobject(L, 1);
1094 ItemStack &item = o->m_stack;
1095 lua_pushinteger(L, item.count);
1099 // get_wear(self) -> number
1100 static int l_get_wear(lua_State *L)
1102 LuaItemStack *o = checkobject(L, 1);
1103 ItemStack &item = o->m_stack;
1104 lua_pushinteger(L, item.wear);
1108 // get_metadata(self) -> string
1109 static int l_get_metadata(lua_State *L)
1111 LuaItemStack *o = checkobject(L, 1);
1112 ItemStack &item = o->m_stack;
1113 lua_pushlstring(L, item.metadata.c_str(), item.metadata.size());
1117 // clear(self) -> true
1118 static int l_clear(lua_State *L)
1120 LuaItemStack *o = checkobject(L, 1);
1122 lua_pushboolean(L, true);
1126 // replace(self, itemstack or itemstring or table or nil) -> true
1127 static int l_replace(lua_State *L)
1129 LuaItemStack *o = checkobject(L, 1);
1130 o->m_stack = read_item(L, 2);
1131 lua_pushboolean(L, true);
1135 // to_string(self) -> string
1136 static int l_to_string(lua_State *L)
1138 LuaItemStack *o = checkobject(L, 1);
1139 std::string itemstring = o->m_stack.getItemString();
1140 lua_pushstring(L, itemstring.c_str());
1144 // to_table(self) -> table or nil
1145 static int l_to_table(lua_State *L)
1147 LuaItemStack *o = checkobject(L, 1);
1148 const ItemStack &item = o->m_stack;
1156 lua_pushstring(L, item.name.c_str());
1157 lua_setfield(L, -2, "name");
1158 lua_pushinteger(L, item.count);
1159 lua_setfield(L, -2, "count");
1160 lua_pushinteger(L, item.wear);
1161 lua_setfield(L, -2, "wear");
1162 lua_pushlstring(L, item.metadata.c_str(), item.metadata.size());
1163 lua_setfield(L, -2, "metadata");
1168 // get_stack_max(self) -> number
1169 static int l_get_stack_max(lua_State *L)
1171 LuaItemStack *o = checkobject(L, 1);
1172 ItemStack &item = o->m_stack;
1173 lua_pushinteger(L, item.getStackMax(get_server(L)->idef()));
1177 // get_free_space(self) -> number
1178 static int l_get_free_space(lua_State *L)
1180 LuaItemStack *o = checkobject(L, 1);
1181 ItemStack &item = o->m_stack;
1182 lua_pushinteger(L, item.freeSpace(get_server(L)->idef()));
1186 // is_known(self) -> true/false
1187 // Checks if the item is defined.
1188 static int l_is_known(lua_State *L)
1190 LuaItemStack *o = checkobject(L, 1);
1191 ItemStack &item = o->m_stack;
1192 bool is_known = item.isKnown(get_server(L)->idef());
1193 lua_pushboolean(L, is_known);
1197 // get_definition(self) -> table
1198 // Returns the item definition table from minetest.registered_items,
1199 // or a fallback one (name="unknown")
1200 static int l_get_definition(lua_State *L)
1202 LuaItemStack *o = checkobject(L, 1);
1203 ItemStack &item = o->m_stack;
1205 // Get minetest.registered_items[name]
1206 lua_getglobal(L, "minetest");
1207 lua_getfield(L, -1, "registered_items");
1208 luaL_checktype(L, -1, LUA_TTABLE);
1209 lua_getfield(L, -1, item.name.c_str());
1210 if(lua_isnil(L, -1))
1213 lua_getfield(L, -1, "unknown");
1218 // get_tool_digging_properties(self) -> table
1219 // Returns the effective tool digging properties.
1220 // Returns those of the hand ("") if this item has none associated.
1221 static int l_get_tool_digging_properties(lua_State *L)
1223 LuaItemStack *o = checkobject(L, 1);
1224 ItemStack &item = o->m_stack;
1225 const ToolDiggingProperties &prop =
1226 item.getToolDiggingProperties(get_server(L)->idef());
1227 push_tool_digging_properties(L, prop);
1231 // add_wear(self, amount) -> true/false
1232 // The range for "amount" is [0,65535]. Wear is only added if the item
1233 // is a tool. Adding wear might destroy the item.
1234 // Returns true if the item is (or was) a tool.
1235 static int l_add_wear(lua_State *L)
1237 LuaItemStack *o = checkobject(L, 1);
1238 ItemStack &item = o->m_stack;
1239 int amount = lua_tointeger(L, 2);
1240 bool result = item.addWear(amount, get_server(L)->idef());
1241 lua_pushboolean(L, result);
1245 // add_item(self, itemstack or itemstring or table or nil) -> itemstack
1246 // Returns leftover item stack
1247 static int l_add_item(lua_State *L)
1249 LuaItemStack *o = checkobject(L, 1);
1250 ItemStack &item = o->m_stack;
1251 ItemStack newitem = read_item(L, 2);
1252 ItemStack leftover = item.addItem(newitem, get_server(L)->idef());
1253 create(L, leftover);
1257 // item_fits(self, itemstack or itemstring or table or nil) -> true/false, itemstack
1258 // First return value is true iff the new item fits fully into the stack
1259 // Second return value is the would-be-left-over item stack
1260 static int l_item_fits(lua_State *L)
1262 LuaItemStack *o = checkobject(L, 1);
1263 ItemStack &item = o->m_stack;
1264 ItemStack newitem = read_item(L, 2);
1266 bool fits = item.itemFits(newitem, &restitem, get_server(L)->idef());
1267 lua_pushboolean(L, fits); // first return value
1268 create(L, restitem); // second return value
1272 // take_item(self, takecount=1) -> itemstack
1273 static int l_take_item(lua_State *L)
1275 LuaItemStack *o = checkobject(L, 1);
1276 ItemStack &item = o->m_stack;
1278 if(!lua_isnone(L, 2))
1279 takecount = lua_tointeger(L, 2);
1280 ItemStack taken = item.takeItem(takecount);
1285 // peek_item(self, peekcount=1) -> itemstack
1286 static int l_peek_item(lua_State *L)
1288 LuaItemStack *o = checkobject(L, 1);
1289 ItemStack &item = o->m_stack;
1291 if(!lua_isnone(L, 2))
1292 peekcount = lua_tointeger(L, 2);
1293 ItemStack peekaboo = item.peekItem(peekcount);
1294 create(L, peekaboo);
1299 LuaItemStack(const ItemStack &item):
1308 const ItemStack& getItem() const
1312 ItemStack& getItem()
1317 // LuaItemStack(itemstack or itemstring or table or nil)
1318 // Creates an LuaItemStack and leaves it on top of stack
1319 static int create_object(lua_State *L)
1321 ItemStack item = read_item(L, 1);
1322 LuaItemStack *o = new LuaItemStack(item);
1323 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1324 luaL_getmetatable(L, className);
1325 lua_setmetatable(L, -2);
1328 // Not callable from Lua
1329 static int create(lua_State *L, const ItemStack &item)
1331 LuaItemStack *o = new LuaItemStack(item);
1332 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1333 luaL_getmetatable(L, className);
1334 lua_setmetatable(L, -2);
1338 static LuaItemStack* checkobject(lua_State *L, int narg)
1340 luaL_checktype(L, narg, LUA_TUSERDATA);
1341 void *ud = luaL_checkudata(L, narg, className);
1342 if(!ud) luaL_typerror(L, narg, className);
1343 return *(LuaItemStack**)ud; // unbox pointer
1346 static void Register(lua_State *L)
1349 int methodtable = lua_gettop(L);
1350 luaL_newmetatable(L, className);
1351 int metatable = lua_gettop(L);
1353 lua_pushliteral(L, "__metatable");
1354 lua_pushvalue(L, methodtable);
1355 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
1357 lua_pushliteral(L, "__index");
1358 lua_pushvalue(L, methodtable);
1359 lua_settable(L, metatable);
1361 lua_pushliteral(L, "__gc");
1362 lua_pushcfunction(L, gc_object);
1363 lua_settable(L, metatable);
1365 lua_pop(L, 1); // drop metatable
1367 luaL_openlib(L, 0, methods, 0); // fill methodtable
1368 lua_pop(L, 1); // drop methodtable
1370 // Can be created from Lua (LuaItemStack(itemstack or itemstring or table or nil))
1371 lua_register(L, className, create_object);
1374 const char LuaItemStack::className[] = "ItemStack";
1375 const luaL_reg LuaItemStack::methods[] = {
1376 method(LuaItemStack, is_empty),
1377 method(LuaItemStack, get_name),
1378 method(LuaItemStack, get_count),
1379 method(LuaItemStack, get_wear),
1380 method(LuaItemStack, get_metadata),
1381 method(LuaItemStack, clear),
1382 method(LuaItemStack, replace),
1383 method(LuaItemStack, to_string),
1384 method(LuaItemStack, to_table),
1385 method(LuaItemStack, get_stack_max),
1386 method(LuaItemStack, get_free_space),
1387 method(LuaItemStack, is_known),
1388 method(LuaItemStack, get_definition),
1389 method(LuaItemStack, get_tool_digging_properties),
1390 method(LuaItemStack, add_wear),
1391 method(LuaItemStack, add_item),
1392 method(LuaItemStack, item_fits),
1393 method(LuaItemStack, take_item),
1394 method(LuaItemStack, peek_item),
1398 static ItemStack read_item(lua_State *L, int index)
1401 index = lua_gettop(L) + 1 + index;
1403 if(lua_isnil(L, index))
1407 else if(lua_isuserdata(L, index))
1409 // Convert from LuaItemStack
1410 LuaItemStack *o = LuaItemStack::checkobject(L, index);
1411 return o->getItem();
1413 else if(lua_isstring(L, index))
1415 // Convert from itemstring
1416 std::string itemstring = lua_tostring(L, index);
1417 IItemDefManager *idef = get_server(L)->idef();
1421 item.deSerialize(itemstring, idef);
1424 catch(SerializationError &e)
1426 infostream<<"WARNING: unable to create item from itemstring"
1427 <<": "<<itemstring<<std::endl;
1431 else if(lua_istable(L, index))
1433 // Convert from table
1434 IItemDefManager *idef = get_server(L)->idef();
1435 std::string name = getstringfield_default(L, index, "name", "");
1436 int count = getintfield_default(L, index, "count", 1);
1437 int wear = getintfield_default(L, index, "wear", 0);
1438 std::string metadata = getstringfield_default(L, index, "metadata", "");
1439 return ItemStack(name, count, wear, metadata, idef);
1443 throw LuaError(L, "Expecting itemstack, itemstring, table or nil");
1454 InventoryLocation m_loc;
1456 static const char className[];
1457 static const luaL_reg methods[];
1459 static InvRef *checkobject(lua_State *L, int narg)
1461 luaL_checktype(L, narg, LUA_TUSERDATA);
1462 void *ud = luaL_checkudata(L, narg, className);
1463 if(!ud) luaL_typerror(L, narg, className);
1464 return *(InvRef**)ud; // unbox pointer
1467 static Inventory* getinv(lua_State *L, InvRef *ref)
1469 return get_server(L)->getInventory(ref->m_loc);
1472 static InventoryList* getlist(lua_State *L, InvRef *ref,
1473 const char *listname)
1475 Inventory *inv = getinv(L, ref);
1478 return inv->getList(listname);
1481 static void reportInventoryChange(lua_State *L, InvRef *ref)
1483 // Inform other things that the inventory has changed
1484 get_server(L)->setInventoryModified(ref->m_loc);
1487 // Exported functions
1489 // garbage collector
1490 static int gc_object(lua_State *L) {
1491 InvRef *o = *(InvRef **)(lua_touserdata(L, 1));
1496 // get_size(self, listname)
1497 static int l_get_size(lua_State *L)
1499 InvRef *ref = checkobject(L, 1);
1500 const char *listname = luaL_checkstring(L, 2);
1501 InventoryList *list = getlist(L, ref, listname);
1503 lua_pushinteger(L, list->getSize());
1505 lua_pushinteger(L, 0);
1510 // set_size(self, listname, size)
1511 static int l_set_size(lua_State *L)
1513 InvRef *ref = checkobject(L, 1);
1514 const char *listname = luaL_checkstring(L, 2);
1515 int newsize = luaL_checknumber(L, 3);
1516 Inventory *inv = getinv(L, ref);
1518 inv->deleteList(listname);
1519 reportInventoryChange(L, ref);
1522 InventoryList *list = inv->getList(listname);
1524 list->setSize(newsize);
1526 list = inv->addList(listname, newsize);
1528 reportInventoryChange(L, ref);
1532 // get_stack(self, listname, i) -> itemstack
1533 static int l_get_stack(lua_State *L)
1535 InvRef *ref = checkobject(L, 1);
1536 const char *listname = luaL_checkstring(L, 2);
1537 int i = luaL_checknumber(L, 3) - 1;
1538 InventoryList *list = getlist(L, ref, listname);
1540 if(list != NULL && i >= 0 && i < (int) list->getSize())
1541 item = list->getItem(i);
1542 LuaItemStack::create(L, item);
1546 // set_stack(self, listname, i, stack) -> true/false
1547 static int l_set_stack(lua_State *L)
1549 InvRef *ref = checkobject(L, 1);
1550 const char *listname = luaL_checkstring(L, 2);
1551 int i = luaL_checknumber(L, 3) - 1;
1552 ItemStack newitem = read_item(L, 4);
1553 InventoryList *list = getlist(L, ref, listname);
1554 if(list != NULL && i >= 0 && i < (int) list->getSize()){
1555 list->changeItem(i, newitem);
1556 reportInventoryChange(L, ref);
1557 lua_pushboolean(L, true);
1559 lua_pushboolean(L, false);
1564 // get_list(self, listname) -> list or nil
1565 static int l_get_list(lua_State *L)
1567 InvRef *ref = checkobject(L, 1);
1568 const char *listname = luaL_checkstring(L, 2);
1569 Inventory *inv = getinv(L, ref);
1570 inventory_get_list_to_lua(inv, listname, L);
1574 // set_list(self, listname, list)
1575 static int l_set_list(lua_State *L)
1577 InvRef *ref = checkobject(L, 1);
1578 const char *listname = luaL_checkstring(L, 2);
1579 Inventory *inv = getinv(L, ref);
1580 InventoryList *list = inv->getList(listname);
1582 inventory_set_list_from_lua(inv, listname, L, 3,
1585 inventory_set_list_from_lua(inv, listname, L, 3);
1586 reportInventoryChange(L, ref);
1590 // add_item(self, listname, itemstack or itemstring or table or nil) -> itemstack
1591 // Returns the leftover stack
1592 static int l_add_item(lua_State *L)
1594 InvRef *ref = checkobject(L, 1);
1595 const char *listname = luaL_checkstring(L, 2);
1596 ItemStack item = read_item(L, 3);
1597 InventoryList *list = getlist(L, ref, listname);
1599 ItemStack leftover = list->addItem(item);
1600 if(leftover.count != item.count)
1601 reportInventoryChange(L, ref);
1602 LuaItemStack::create(L, leftover);
1604 LuaItemStack::create(L, item);
1609 // room_for_item(self, listname, itemstack or itemstring or table or nil) -> true/false
1610 // Returns true if the item completely fits into the list
1611 static int l_room_for_item(lua_State *L)
1613 InvRef *ref = checkobject(L, 1);
1614 const char *listname = luaL_checkstring(L, 2);
1615 ItemStack item = read_item(L, 3);
1616 InventoryList *list = getlist(L, ref, listname);
1618 lua_pushboolean(L, list->roomForItem(item));
1620 lua_pushboolean(L, false);
1625 // contains_item(self, listname, itemstack or itemstring or table or nil) -> true/false
1626 // Returns true if the list contains the given count of the given item name
1627 static int l_contains_item(lua_State *L)
1629 InvRef *ref = checkobject(L, 1);
1630 const char *listname = luaL_checkstring(L, 2);
1631 ItemStack item = read_item(L, 3);
1632 InventoryList *list = getlist(L, ref, listname);
1634 lua_pushboolean(L, list->containsItem(item));
1636 lua_pushboolean(L, false);
1641 // remove_item(self, listname, itemstack or itemstring or table or nil) -> itemstack
1642 // Returns the items that were actually removed
1643 static int l_remove_item(lua_State *L)
1645 InvRef *ref = checkobject(L, 1);
1646 const char *listname = luaL_checkstring(L, 2);
1647 ItemStack item = read_item(L, 3);
1648 InventoryList *list = getlist(L, ref, listname);
1650 ItemStack removed = list->removeItem(item);
1651 if(!removed.empty())
1652 reportInventoryChange(L, ref);
1653 LuaItemStack::create(L, removed);
1655 LuaItemStack::create(L, ItemStack());
1661 InvRef(const InventoryLocation &loc):
1670 // Creates an InvRef and leaves it on top of stack
1671 // Not callable from Lua; all references are created on the C side.
1672 static void create(lua_State *L, const InventoryLocation &loc)
1674 InvRef *o = new InvRef(loc);
1675 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1676 luaL_getmetatable(L, className);
1677 lua_setmetatable(L, -2);
1679 static void createPlayer(lua_State *L, Player *player)
1681 InventoryLocation loc;
1682 loc.setPlayer(player->getName());
1685 static void createNodeMeta(lua_State *L, v3s16 p)
1687 InventoryLocation loc;
1692 static void Register(lua_State *L)
1695 int methodtable = lua_gettop(L);
1696 luaL_newmetatable(L, className);
1697 int metatable = lua_gettop(L);
1699 lua_pushliteral(L, "__metatable");
1700 lua_pushvalue(L, methodtable);
1701 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
1703 lua_pushliteral(L, "__index");
1704 lua_pushvalue(L, methodtable);
1705 lua_settable(L, metatable);
1707 lua_pushliteral(L, "__gc");
1708 lua_pushcfunction(L, gc_object);
1709 lua_settable(L, metatable);
1711 lua_pop(L, 1); // drop metatable
1713 luaL_openlib(L, 0, methods, 0); // fill methodtable
1714 lua_pop(L, 1); // drop methodtable
1716 // Cannot be created from Lua
1717 //lua_register(L, className, create_object);
1720 const char InvRef::className[] = "InvRef";
1721 const luaL_reg InvRef::methods[] = {
1722 method(InvRef, get_size),
1723 method(InvRef, set_size),
1724 method(InvRef, get_stack),
1725 method(InvRef, set_stack),
1726 method(InvRef, get_list),
1727 method(InvRef, set_list),
1728 method(InvRef, add_item),
1729 method(InvRef, room_for_item),
1730 method(InvRef, contains_item),
1731 method(InvRef, remove_item),
1743 ServerEnvironment *m_env;
1745 static const char className[];
1746 static const luaL_reg methods[];
1748 static NodeMetaRef *checkobject(lua_State *L, int narg)
1750 luaL_checktype(L, narg, LUA_TUSERDATA);
1751 void *ud = luaL_checkudata(L, narg, className);
1752 if(!ud) luaL_typerror(L, narg, className);
1753 return *(NodeMetaRef**)ud; // unbox pointer
1756 static NodeMetadata* getmeta(NodeMetaRef *ref)
1758 NodeMetadata *meta = ref->m_env->getMap().getNodeMetadata(ref->m_p);
1762 /*static IGenericNodeMetadata* getgenericmeta(NodeMetaRef *ref)
1764 NodeMetadata *meta = getmeta(ref);
1767 if(meta->typeId() != NODEMETA_GENERIC)
1769 return (IGenericNodeMetadata*)meta;
1772 static void reportMetadataChange(NodeMetaRef *ref)
1774 // Inform other things that the metadata has changed
1775 v3s16 blockpos = getNodeBlockPos(ref->m_p);
1777 event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
1779 ref->m_env->getMap().dispatchEvent(&event);
1780 // Set the block to be saved
1781 MapBlock *block = ref->m_env->getMap().getBlockNoCreateNoEx(blockpos);
1783 block->raiseModified(MOD_STATE_WRITE_NEEDED,
1784 "NodeMetaRef::reportMetadataChange");
1787 // Exported functions
1789 // garbage collector
1790 static int gc_object(lua_State *L) {
1791 NodeMetaRef *o = *(NodeMetaRef **)(lua_touserdata(L, 1));
1797 static int l_get_type(lua_State *L)
1799 NodeMetaRef *ref = checkobject(L, 1);
1800 NodeMetadata *meta = getmeta(ref);
1806 lua_pushstring(L, meta->typeName());
1810 // allows_text_input(self)
1811 static int l_allows_text_input(lua_State *L)
1813 NodeMetaRef *ref = checkobject(L, 1);
1814 NodeMetadata *meta = getmeta(ref);
1815 if(meta == NULL) return 0;
1817 lua_pushboolean(L, meta->allowsTextInput());
1821 // set_text(self, text)
1822 static int l_set_text(lua_State *L)
1824 NodeMetaRef *ref = checkobject(L, 1);
1825 NodeMetadata *meta = getmeta(ref);
1826 if(meta == NULL) return 0;
1828 std::string text = luaL_checkstring(L, 2);
1829 meta->setText(text);
1830 reportMetadataChange(ref);
1835 static int l_get_text(lua_State *L)
1837 NodeMetaRef *ref = checkobject(L, 1);
1838 NodeMetadata *meta = getmeta(ref);
1839 if(meta == NULL) return 0;
1841 std::string text = meta->getText();
1842 lua_pushstring(L, text.c_str());
1847 static int l_get_owner(lua_State *L)
1849 NodeMetaRef *ref = checkobject(L, 1);
1850 NodeMetadata *meta = getmeta(ref);
1851 if(meta == NULL) return 0;
1853 std::string owner = meta->getOwner();
1854 lua_pushstring(L, owner.c_str());
1858 // set_owner(self, string)
1859 static int l_set_owner(lua_State *L)
1861 NodeMetaRef *ref = checkobject(L, 1);
1862 NodeMetadata *meta = getmeta(ref);
1863 if(meta == NULL) return 0;
1865 std::string owner = luaL_checkstring(L, 2);
1866 meta->setOwner(owner);
1867 reportMetadataChange(ref);
1871 // get_allow_removal(self)
1872 static int l_get_allow_removal(lua_State *L)
1874 NodeMetaRef *ref = checkobject(L, 1);
1875 NodeMetadata *meta = getmeta(ref);
1877 lua_pushboolean(L, true);
1881 lua_pushboolean(L, !meta->nodeRemovalDisabled());
1885 /* IGenericNodeMetadata interface */
1887 // set_infotext(self, text)
1888 static int l_set_infotext(lua_State *L)
1890 NodeMetaRef *ref = checkobject(L, 1);
1891 NodeMetadata *meta = getmeta(ref);
1892 if(meta == NULL) return 0;
1894 std::string text = luaL_checkstring(L, 2);
1895 meta->setInfoText(text);
1896 reportMetadataChange(ref);
1900 // get_inventory(self)
1901 static int l_get_inventory(lua_State *L)
1903 NodeMetaRef *ref = checkobject(L, 1);
1904 NodeMetadata *meta = getmeta(ref);
1905 if(meta == NULL) return 0;
1907 InvRef::createNodeMeta(L, ref->m_p);
1911 // set_inventory_draw_spec(self, text)
1912 static int l_set_inventory_draw_spec(lua_State *L)
1914 NodeMetaRef *ref = checkobject(L, 1);
1915 NodeMetadata *meta = getmeta(ref);
1916 if(meta == NULL) return 0;
1918 std::string text = luaL_checkstring(L, 2);
1919 meta->setInventoryDrawSpec(text);
1920 reportMetadataChange(ref);
1924 // set_allow_text_input(self, text)
1925 static int l_set_allow_text_input(lua_State *L)
1927 NodeMetaRef *ref = checkobject(L, 1);
1928 NodeMetadata *meta = getmeta(ref);
1929 if(meta == NULL) return 0;
1931 bool b = lua_toboolean(L, 2);
1932 meta->setAllowTextInput(b);
1933 reportMetadataChange(ref);
1937 // set_allow_removal(self, text)
1938 static int l_set_allow_removal(lua_State *L)
1940 NodeMetaRef *ref = checkobject(L, 1);
1941 NodeMetadata *meta = getmeta(ref);
1942 if(meta == NULL) return 0;
1944 bool b = lua_toboolean(L, 2);
1945 meta->setRemovalDisabled(!b);
1946 reportMetadataChange(ref);
1950 // set_enforce_owner(self, text)
1951 static int l_set_enforce_owner(lua_State *L)
1953 NodeMetaRef *ref = checkobject(L, 1);
1954 NodeMetadata *meta = getmeta(ref);
1955 if(meta == NULL) return 0;
1957 bool b = lua_toboolean(L, 2);
1958 meta->setEnforceOwner(b);
1959 reportMetadataChange(ref);
1963 // is_inventory_modified(self)
1964 static int l_is_inventory_modified(lua_State *L)
1966 NodeMetaRef *ref = checkobject(L, 1);
1967 NodeMetadata *meta = getmeta(ref);
1968 if(meta == NULL) return 0;
1970 lua_pushboolean(L, meta->isInventoryModified());
1974 // reset_inventory_modified(self)
1975 static int l_reset_inventory_modified(lua_State *L)
1977 NodeMetaRef *ref = checkobject(L, 1);
1978 NodeMetadata *meta = getmeta(ref);
1979 if(meta == NULL) return 0;
1981 meta->resetInventoryModified();
1982 reportMetadataChange(ref);
1986 // is_text_modified(self)
1987 static int l_is_text_modified(lua_State *L)
1989 NodeMetaRef *ref = checkobject(L, 1);
1990 NodeMetadata *meta = getmeta(ref);
1991 if(meta == NULL) return 0;
1993 lua_pushboolean(L, meta->isTextModified());
1997 // reset_text_modified(self)
1998 static int l_reset_text_modified(lua_State *L)
2000 NodeMetaRef *ref = checkobject(L, 1);
2001 NodeMetadata *meta = getmeta(ref);
2002 if(meta == NULL) return 0;
2004 meta->resetTextModified();
2005 reportMetadataChange(ref);
2009 // set_string(self, name, var)
2010 static int l_set_string(lua_State *L)
2012 NodeMetaRef *ref = checkobject(L, 1);
2013 NodeMetadata *meta = getmeta(ref);
2014 if(meta == NULL) return 0;
2016 std::string name = luaL_checkstring(L, 2);
2018 const char *s = lua_tolstring(L, 3, &len);
2019 std::string str(s, len);
2020 meta->setString(name, str);
2021 reportMetadataChange(ref);
2025 // get_string(self, name)
2026 static int l_get_string(lua_State *L)
2028 NodeMetaRef *ref = checkobject(L, 1);
2029 NodeMetadata *meta = getmeta(ref);
2030 if(meta == NULL) return 0;
2032 std::string name = luaL_checkstring(L, 2);
2033 std::string str = meta->getString(name);
2034 lua_pushlstring(L, str.c_str(), str.size());
2039 NodeMetaRef(v3s16 p, ServerEnvironment *env):
2049 // Creates an NodeMetaRef and leaves it on top of stack
2050 // Not callable from Lua; all references are created on the C side.
2051 static void create(lua_State *L, v3s16 p, ServerEnvironment *env)
2053 NodeMetaRef *o = new NodeMetaRef(p, env);
2054 //infostream<<"NodeMetaRef::create: o="<<o<<std::endl;
2055 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
2056 luaL_getmetatable(L, className);
2057 lua_setmetatable(L, -2);
2060 static void Register(lua_State *L)
2063 int methodtable = lua_gettop(L);
2064 luaL_newmetatable(L, className);
2065 int metatable = lua_gettop(L);
2067 lua_pushliteral(L, "__metatable");
2068 lua_pushvalue(L, methodtable);
2069 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
2071 lua_pushliteral(L, "__index");
2072 lua_pushvalue(L, methodtable);
2073 lua_settable(L, metatable);
2075 lua_pushliteral(L, "__gc");
2076 lua_pushcfunction(L, gc_object);
2077 lua_settable(L, metatable);
2079 lua_pop(L, 1); // drop metatable
2081 luaL_openlib(L, 0, methods, 0); // fill methodtable
2082 lua_pop(L, 1); // drop methodtable
2084 // Cannot be created from Lua
2085 //lua_register(L, className, create_object);
2088 const char NodeMetaRef::className[] = "NodeMetaRef";
2089 const luaL_reg NodeMetaRef::methods[] = {
2090 method(NodeMetaRef, get_type),
2091 method(NodeMetaRef, allows_text_input),
2092 method(NodeMetaRef, set_text),
2093 method(NodeMetaRef, get_text),
2094 method(NodeMetaRef, get_owner),
2095 method(NodeMetaRef, set_owner),
2096 method(NodeMetaRef, get_allow_removal),
2097 method(NodeMetaRef, set_infotext),
2098 method(NodeMetaRef, get_inventory),
2099 method(NodeMetaRef, set_inventory_draw_spec),
2100 method(NodeMetaRef, set_allow_text_input),
2101 method(NodeMetaRef, set_allow_removal),
2102 method(NodeMetaRef, set_enforce_owner),
2103 method(NodeMetaRef, is_inventory_modified),
2104 method(NodeMetaRef, reset_inventory_modified),
2105 method(NodeMetaRef, is_text_modified),
2106 method(NodeMetaRef, reset_text_modified),
2107 method(NodeMetaRef, set_string),
2108 method(NodeMetaRef, get_string),
2119 ServerActiveObject *m_object;
2121 static const char className[];
2122 static const luaL_reg methods[];
2124 static ObjectRef *checkobject(lua_State *L, int narg)
2126 luaL_checktype(L, narg, LUA_TUSERDATA);
2127 void *ud = luaL_checkudata(L, narg, className);
2128 if(!ud) luaL_typerror(L, narg, className);
2129 return *(ObjectRef**)ud; // unbox pointer
2132 static ServerActiveObject* getobject(ObjectRef *ref)
2134 ServerActiveObject *co = ref->m_object;
2138 static LuaEntitySAO* getluaobject(ObjectRef *ref)
2140 ServerActiveObject *obj = getobject(ref);
2143 if(obj->getType() != ACTIVEOBJECT_TYPE_LUAENTITY)
2145 return (LuaEntitySAO*)obj;
2148 static ServerRemotePlayer* getplayer(ObjectRef *ref)
2150 ServerActiveObject *obj = getobject(ref);
2153 if(obj->getType() != ACTIVEOBJECT_TYPE_PLAYER)
2155 return static_cast<ServerRemotePlayer*>(obj);
2158 // Exported functions
2160 // garbage collector
2161 static int gc_object(lua_State *L) {
2162 ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
2163 //infostream<<"ObjectRef::gc_object: o="<<o<<std::endl;
2169 static int l_remove(lua_State *L)
2171 ObjectRef *ref = checkobject(L, 1);
2172 ServerActiveObject *co = getobject(ref);
2173 if(co == NULL) return 0;
2174 infostream<<"ObjectRef::l_remove(): id="<<co->getId()<<std::endl;
2175 co->m_removed = true;
2180 // returns: {x=num, y=num, z=num}
2181 static int l_getpos(lua_State *L)
2183 ObjectRef *ref = checkobject(L, 1);
2184 ServerActiveObject *co = getobject(ref);
2185 if(co == NULL) return 0;
2186 v3f pos = co->getBasePosition() / BS;
2188 lua_pushnumber(L, pos.X);
2189 lua_setfield(L, -2, "x");
2190 lua_pushnumber(L, pos.Y);
2191 lua_setfield(L, -2, "y");
2192 lua_pushnumber(L, pos.Z);
2193 lua_setfield(L, -2, "z");
2197 // setpos(self, pos)
2198 static int l_setpos(lua_State *L)
2200 ObjectRef *ref = checkobject(L, 1);
2201 //LuaEntitySAO *co = getluaobject(ref);
2202 ServerActiveObject *co = getobject(ref);
2203 if(co == NULL) return 0;
2205 v3f pos = checkFloatPos(L, 2);
2208 // Move player if applicable
2209 ServerRemotePlayer *player = getplayer(ref);
2211 get_server(L)->SendMovePlayer(player);
2215 // moveto(self, pos, continuous=false)
2216 static int l_moveto(lua_State *L)
2218 ObjectRef *ref = checkobject(L, 1);
2219 //LuaEntitySAO *co = getluaobject(ref);
2220 ServerActiveObject *co = getobject(ref);
2221 if(co == NULL) return 0;
2223 v3f pos = checkFloatPos(L, 2);
2225 bool continuous = lua_toboolean(L, 3);
2227 co->moveTo(pos, continuous);
2231 // punch(self, puncher); puncher = an another ObjectRef
2232 static int l_punch(lua_State *L)
2234 ObjectRef *ref = checkobject(L, 1);
2235 ObjectRef *ref2 = checkobject(L, 2);
2236 ServerActiveObject *co = getobject(ref);
2237 ServerActiveObject *co2 = getobject(ref2);
2238 if(co == NULL) return 0;
2239 if(co2 == NULL) return 0;
2245 // right_click(self, clicker); clicker = an another ObjectRef
2246 static int l_right_click(lua_State *L)
2248 ObjectRef *ref = checkobject(L, 1);
2249 ObjectRef *ref2 = checkobject(L, 2);
2250 ServerActiveObject *co = getobject(ref);
2251 ServerActiveObject *co2 = getobject(ref2);
2252 if(co == NULL) return 0;
2253 if(co2 == NULL) return 0;
2255 co->rightClick(co2);
2260 // hp = number of hitpoints (2 * number of hearts)
2262 static int l_set_hp(lua_State *L)
2264 ObjectRef *ref = checkobject(L, 1);
2265 luaL_checknumber(L, 2);
2266 ServerActiveObject *co = getobject(ref);
2267 if(co == NULL) return 0;
2268 int hp = lua_tonumber(L, 2);
2269 infostream<<"ObjectRef::l_set_hp(): id="<<co->getId()
2270 <<" hp="<<hp<<std::endl;
2278 // returns: number of hitpoints (2 * number of hearts)
2279 // 0 if not applicable to this type of object
2280 static int l_get_hp(lua_State *L)
2282 ObjectRef *ref = checkobject(L, 1);
2283 ServerActiveObject *co = getobject(ref);
2284 if(co == NULL) return 0;
2285 int hp = co->getHP();
2286 infostream<<"ObjectRef::l_get_hp(): id="<<co->getId()
2287 <<" hp="<<hp<<std::endl;
2289 lua_pushnumber(L, hp);
2293 // get_inventory(self)
2294 static int l_get_inventory(lua_State *L)
2296 ObjectRef *ref = checkobject(L, 1);
2297 ServerActiveObject *co = getobject(ref);
2298 if(co == NULL) return 0;
2300 InventoryLocation loc = co->getInventoryLocation();
2301 if(get_server(L)->getInventory(loc) != NULL)
2302 InvRef::create(L, loc);
2308 // get_wield_list(self)
2309 static int l_get_wield_list(lua_State *L)
2311 ObjectRef *ref = checkobject(L, 1);
2312 ServerActiveObject *co = getobject(ref);
2313 if(co == NULL) return 0;
2315 lua_pushstring(L, co->getWieldList().c_str());
2319 // get_wield_index(self)
2320 static int l_get_wield_index(lua_State *L)
2322 ObjectRef *ref = checkobject(L, 1);
2323 ServerActiveObject *co = getobject(ref);
2324 if(co == NULL) return 0;
2326 lua_pushinteger(L, co->getWieldIndex() + 1);
2330 // get_wielded_item(self)
2331 static int l_get_wielded_item(lua_State *L)
2333 ObjectRef *ref = checkobject(L, 1);
2334 ServerActiveObject *co = getobject(ref);
2335 if(co == NULL) return 0;
2337 LuaItemStack::create(L, co->getWieldedItem());
2341 // set_wielded_item(self, itemstack or itemstring or table or nil)
2342 static int l_set_wielded_item(lua_State *L)
2344 ObjectRef *ref = checkobject(L, 1);
2345 ServerActiveObject *co = getobject(ref);
2346 if(co == NULL) return 0;
2348 ItemStack item = read_item(L, 2);
2349 bool success = co->setWieldedItem(item);
2350 lua_pushboolean(L, success);
2354 /* LuaEntitySAO-only */
2356 // setvelocity(self, {x=num, y=num, z=num})
2357 static int l_setvelocity(lua_State *L)
2359 ObjectRef *ref = checkobject(L, 1);
2360 LuaEntitySAO *co = getluaobject(ref);
2361 if(co == NULL) return 0;
2363 v3f pos = checkFloatPos(L, 2);
2365 co->setVelocity(pos);
2369 // getvelocity(self)
2370 static int l_getvelocity(lua_State *L)
2372 ObjectRef *ref = checkobject(L, 1);
2373 LuaEntitySAO *co = getluaobject(ref);
2374 if(co == NULL) return 0;
2376 v3f v = co->getVelocity();
2381 // setacceleration(self, {x=num, y=num, z=num})
2382 static int l_setacceleration(lua_State *L)
2384 ObjectRef *ref = checkobject(L, 1);
2385 LuaEntitySAO *co = getluaobject(ref);
2386 if(co == NULL) return 0;
2388 v3f pos = checkFloatPos(L, 2);
2390 co->setAcceleration(pos);
2394 // getacceleration(self)
2395 static int l_getacceleration(lua_State *L)
2397 ObjectRef *ref = checkobject(L, 1);
2398 LuaEntitySAO *co = getluaobject(ref);
2399 if(co == NULL) return 0;
2401 v3f v = co->getAcceleration();
2406 // setyaw(self, radians)
2407 static int l_setyaw(lua_State *L)
2409 ObjectRef *ref = checkobject(L, 1);
2410 LuaEntitySAO *co = getluaobject(ref);
2411 if(co == NULL) return 0;
2413 float yaw = luaL_checknumber(L, 2) * core::RADTODEG;
2420 static int l_getyaw(lua_State *L)
2422 ObjectRef *ref = checkobject(L, 1);
2423 LuaEntitySAO *co = getluaobject(ref);
2424 if(co == NULL) return 0;
2426 float yaw = co->getYaw() * core::DEGTORAD;
2427 lua_pushnumber(L, yaw);
2431 // settexturemod(self, mod)
2432 static int l_settexturemod(lua_State *L)
2434 ObjectRef *ref = checkobject(L, 1);
2435 LuaEntitySAO *co = getluaobject(ref);
2436 if(co == NULL) return 0;
2438 std::string mod = luaL_checkstring(L, 2);
2439 co->setTextureMod(mod);
2443 // setsprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2,
2444 // select_horiz_by_yawpitch=false)
2445 static int l_setsprite(lua_State *L)
2447 ObjectRef *ref = checkobject(L, 1);
2448 LuaEntitySAO *co = getluaobject(ref);
2449 if(co == NULL) return 0;
2452 if(!lua_isnil(L, 2))
2453 p = read_v2s16(L, 2);
2455 if(!lua_isnil(L, 3))
2456 num_frames = lua_tonumber(L, 3);
2457 float framelength = 0.2;
2458 if(!lua_isnil(L, 4))
2459 framelength = lua_tonumber(L, 4);
2460 bool select_horiz_by_yawpitch = false;
2461 if(!lua_isnil(L, 5))
2462 select_horiz_by_yawpitch = lua_toboolean(L, 5);
2463 co->setSprite(p, num_frames, framelength, select_horiz_by_yawpitch);
2468 // get_entity_name(self)
2469 static int l_get_entity_name(lua_State *L)
2471 ObjectRef *ref = checkobject(L, 1);
2472 LuaEntitySAO *co = getluaobject(ref);
2473 if(co == NULL) return 0;
2475 std::string name = co->getName();
2476 lua_pushstring(L, name.c_str());
2480 // get_luaentity(self)
2481 static int l_get_luaentity(lua_State *L)
2483 ObjectRef *ref = checkobject(L, 1);
2484 LuaEntitySAO *co = getluaobject(ref);
2485 if(co == NULL) return 0;
2487 luaentity_get(L, co->getId());
2493 // get_player_name(self)
2494 static int l_get_player_name(lua_State *L)
2496 ObjectRef *ref = checkobject(L, 1);
2497 ServerRemotePlayer *player = getplayer(ref);
2503 lua_pushstring(L, player->getName());
2507 // get_look_dir(self)
2508 static int l_get_look_dir(lua_State *L)
2510 ObjectRef *ref = checkobject(L, 1);
2511 ServerRemotePlayer *player = getplayer(ref);
2512 if(player == NULL) return 0;
2514 float pitch = player->getRadPitch();
2515 float yaw = player->getRadYaw();
2516 v3f v(cos(pitch)*cos(yaw), sin(pitch), cos(pitch)*sin(yaw));
2521 // get_look_pitch(self)
2522 static int l_get_look_pitch(lua_State *L)
2524 ObjectRef *ref = checkobject(L, 1);
2525 ServerRemotePlayer *player = getplayer(ref);
2526 if(player == NULL) return 0;
2528 lua_pushnumber(L, player->getRadPitch());
2532 // get_look_yaw(self)
2533 static int l_get_look_yaw(lua_State *L)
2535 ObjectRef *ref = checkobject(L, 1);
2536 ServerRemotePlayer *player = getplayer(ref);
2537 if(player == NULL) return 0;
2539 lua_pushnumber(L, player->getRadYaw());
2544 ObjectRef(ServerActiveObject *object):
2547 //infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
2553 infostream<<"ObjectRef destructing for id="
2554 <<m_object->getId()<<std::endl;
2556 infostream<<"ObjectRef destructing for id=unknown"<<std::endl;*/
2559 // Creates an ObjectRef and leaves it on top of stack
2560 // Not callable from Lua; all references are created on the C side.
2561 static void create(lua_State *L, ServerActiveObject *object)
2563 ObjectRef *o = new ObjectRef(object);
2564 //infostream<<"ObjectRef::create: o="<<o<<std::endl;
2565 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
2566 luaL_getmetatable(L, className);
2567 lua_setmetatable(L, -2);
2570 static void set_null(lua_State *L)
2572 ObjectRef *o = checkobject(L, -1);
2576 static void Register(lua_State *L)
2579 int methodtable = lua_gettop(L);
2580 luaL_newmetatable(L, className);
2581 int metatable = lua_gettop(L);
2583 lua_pushliteral(L, "__metatable");
2584 lua_pushvalue(L, methodtable);
2585 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
2587 lua_pushliteral(L, "__index");
2588 lua_pushvalue(L, methodtable);
2589 lua_settable(L, metatable);
2591 lua_pushliteral(L, "__gc");
2592 lua_pushcfunction(L, gc_object);
2593 lua_settable(L, metatable);
2595 lua_pop(L, 1); // drop metatable
2597 luaL_openlib(L, 0, methods, 0); // fill methodtable
2598 lua_pop(L, 1); // drop methodtable
2600 // Cannot be created from Lua
2601 //lua_register(L, className, create_object);
2604 const char ObjectRef::className[] = "ObjectRef";
2605 const luaL_reg ObjectRef::methods[] = {
2606 // ServerActiveObject
2607 method(ObjectRef, remove),
2608 method(ObjectRef, getpos),
2609 method(ObjectRef, setpos),
2610 method(ObjectRef, moveto),
2611 method(ObjectRef, punch),
2612 method(ObjectRef, right_click),
2613 method(ObjectRef, set_hp),
2614 method(ObjectRef, get_hp),
2615 method(ObjectRef, get_inventory),
2616 method(ObjectRef, get_wield_list),
2617 method(ObjectRef, get_wield_index),
2618 method(ObjectRef, get_wielded_item),
2619 method(ObjectRef, set_wielded_item),
2620 // LuaEntitySAO-only
2621 method(ObjectRef, setvelocity),
2622 method(ObjectRef, getvelocity),
2623 method(ObjectRef, setacceleration),
2624 method(ObjectRef, getacceleration),
2625 method(ObjectRef, setyaw),
2626 method(ObjectRef, getyaw),
2627 method(ObjectRef, settexturemod),
2628 method(ObjectRef, setsprite),
2629 method(ObjectRef, get_entity_name),
2630 method(ObjectRef, get_luaentity),
2632 method(ObjectRef, get_player_name),
2633 method(ObjectRef, get_look_dir),
2634 method(ObjectRef, get_look_pitch),
2635 method(ObjectRef, get_look_yaw),
2639 // Creates a new anonymous reference if id=0
2640 static void objectref_get_or_create(lua_State *L,
2641 ServerActiveObject *cobj)
2643 if(cobj->getId() == 0){
2644 ObjectRef::create(L, cobj);
2646 objectref_get(L, cobj->getId());
2657 ServerEnvironment *m_env;
2659 static const char className[];
2660 static const luaL_reg methods[];
2662 static EnvRef *checkobject(lua_State *L, int narg)
2664 luaL_checktype(L, narg, LUA_TUSERDATA);
2665 void *ud = luaL_checkudata(L, narg, className);
2666 if(!ud) luaL_typerror(L, narg, className);
2667 return *(EnvRef**)ud; // unbox pointer
2670 // Exported functions
2672 // EnvRef:add_node(pos, node)
2673 // pos = {x=num, y=num, z=num}
2674 static int l_add_node(lua_State *L)
2676 //infostream<<"EnvRef::l_add_node()"<<std::endl;
2677 EnvRef *o = checkobject(L, 1);
2678 ServerEnvironment *env = o->m_env;
2679 if(env == NULL) return 0;
2681 v3s16 pos = read_v3s16(L, 2);
2683 MapNode n = readnode(L, 3, env->getGameDef()->ndef());
2685 bool succeeded = env->getMap().addNodeWithEvent(pos, n);
2686 lua_pushboolean(L, succeeded);
2690 // EnvRef:remove_node(pos)
2691 // pos = {x=num, y=num, z=num}
2692 static int l_remove_node(lua_State *L)
2694 //infostream<<"EnvRef::l_remove_node()"<<std::endl;
2695 EnvRef *o = checkobject(L, 1);
2696 ServerEnvironment *env = o->m_env;
2697 if(env == NULL) return 0;
2699 v3s16 pos = read_v3s16(L, 2);
2701 bool succeeded = env->getMap().removeNodeWithEvent(pos);
2702 lua_pushboolean(L, succeeded);
2706 // EnvRef:get_node(pos)
2707 // pos = {x=num, y=num, z=num}
2708 static int l_get_node(lua_State *L)
2710 //infostream<<"EnvRef::l_get_node()"<<std::endl;
2711 EnvRef *o = checkobject(L, 1);
2712 ServerEnvironment *env = o->m_env;
2713 if(env == NULL) return 0;
2715 v3s16 pos = read_v3s16(L, 2);
2717 MapNode n = env->getMap().getNodeNoEx(pos);
2719 pushnode(L, n, env->getGameDef()->ndef());
2723 // EnvRef:get_node_or_nil(pos)
2724 // pos = {x=num, y=num, z=num}
2725 static int l_get_node_or_nil(lua_State *L)
2727 //infostream<<"EnvRef::l_get_node()"<<std::endl;
2728 EnvRef *o = checkobject(L, 1);
2729 ServerEnvironment *env = o->m_env;
2730 if(env == NULL) return 0;
2732 v3s16 pos = read_v3s16(L, 2);
2735 MapNode n = env->getMap().getNode(pos);
2737 pushnode(L, n, env->getGameDef()->ndef());
2739 } catch(InvalidPositionException &e)
2746 // EnvRef:get_node_light(pos, timeofday)
2747 // pos = {x=num, y=num, z=num}
2748 // timeofday: nil = current time, 0 = night, 0.5 = day
2749 static int l_get_node_light(lua_State *L)
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);
2756 u32 time_of_day = env->getTimeOfDay();
2757 if(lua_isnumber(L, 3))
2758 time_of_day = 24000.0 * lua_tonumber(L, 3);
2759 time_of_day %= 24000;
2760 u32 dnr = time_to_daynight_ratio(time_of_day);
2761 MapNode n = env->getMap().getNodeNoEx(pos);
2763 MapNode n = env->getMap().getNode(pos);
2764 INodeDefManager *ndef = env->getGameDef()->ndef();
2765 lua_pushinteger(L, n.getLightBlend(dnr, ndef));
2767 } catch(InvalidPositionException &e)
2774 // EnvRef:add_entity(pos, entityname) -> ObjectRef or nil
2775 // pos = {x=num, y=num, z=num}
2776 static int l_add_entity(lua_State *L)
2778 //infostream<<"EnvRef::l_add_entity()"<<std::endl;
2779 EnvRef *o = checkobject(L, 1);
2780 ServerEnvironment *env = o->m_env;
2781 if(env == NULL) return 0;
2783 v3f pos = checkFloatPos(L, 2);
2785 const char *name = luaL_checkstring(L, 3);
2787 ServerActiveObject *obj = new LuaEntitySAO(env, pos, name, "");
2788 int objectid = env->addActiveObject(obj);
2789 // If failed to add, return nothing (reads as nil)
2793 objectref_get_or_create(L, obj);
2797 // EnvRef:add_item(pos, itemstack or itemstring or table) -> ObjectRef or nil
2798 // pos = {x=num, y=num, z=num}
2799 static int l_add_item(lua_State *L)
2801 //infostream<<"EnvRef::l_add_item()"<<std::endl;
2802 EnvRef *o = checkobject(L, 1);
2803 ServerEnvironment *env = o->m_env;
2804 if(env == NULL) return 0;
2806 v3f pos = checkFloatPos(L, 2);
2808 ItemStack item = read_item(L, 3);
2809 if(item.empty() || !item.isKnown(get_server(L)->idef()))
2812 ServerActiveObject *obj = new ItemSAO(env, pos, item.getItemString());
2813 int objectid = env->addActiveObject(obj);
2814 // If failed to add, return nothing (reads as nil)
2818 objectref_get_or_create(L, obj);
2822 // EnvRef:add_rat(pos)
2823 // pos = {x=num, y=num, z=num}
2824 static int l_add_rat(lua_State *L)
2826 infostream<<"EnvRef::l_add_rat()"<<std::endl;
2827 EnvRef *o = checkobject(L, 1);
2828 ServerEnvironment *env = o->m_env;
2829 if(env == NULL) return 0;
2831 v3f pos = checkFloatPos(L, 2);
2833 ServerActiveObject *obj = new RatSAO(env, pos);
2834 env->addActiveObject(obj);
2838 // EnvRef:add_firefly(pos)
2839 // pos = {x=num, y=num, z=num}
2840 static int l_add_firefly(lua_State *L)
2842 infostream<<"EnvRef::l_add_firefly()"<<std::endl;
2843 EnvRef *o = checkobject(L, 1);
2844 ServerEnvironment *env = o->m_env;
2845 if(env == NULL) return 0;
2847 v3f pos = checkFloatPos(L, 2);
2849 ServerActiveObject *obj = new FireflySAO(env, pos);
2850 env->addActiveObject(obj);
2854 // EnvRef:get_meta(pos)
2855 static int l_get_meta(lua_State *L)
2857 //infostream<<"EnvRef::l_get_meta()"<<std::endl;
2858 EnvRef *o = checkobject(L, 1);
2859 ServerEnvironment *env = o->m_env;
2860 if(env == NULL) return 0;
2862 v3s16 p = read_v3s16(L, 2);
2863 NodeMetaRef::create(L, p, env);
2867 // EnvRef:get_player_by_name(name)
2868 static int l_get_player_by_name(lua_State *L)
2870 EnvRef *o = checkobject(L, 1);
2871 ServerEnvironment *env = o->m_env;
2872 if(env == NULL) return 0;
2874 const char *name = luaL_checkstring(L, 2);
2875 ServerRemotePlayer *player =
2876 static_cast<ServerRemotePlayer*>(env->getPlayer(name));
2881 // Put player on stack
2882 objectref_get_or_create(L, player);
2886 // EnvRef:get_objects_inside_radius(pos, radius)
2887 static int l_get_objects_inside_radius(lua_State *L)
2889 // Get the table insert function
2890 lua_getglobal(L, "table");
2891 lua_getfield(L, -1, "insert");
2892 int table_insert = lua_gettop(L);
2894 EnvRef *o = checkobject(L, 1);
2895 ServerEnvironment *env = o->m_env;
2896 if(env == NULL) return 0;
2898 v3f pos = checkFloatPos(L, 2);
2899 float radius = luaL_checknumber(L, 3) * BS;
2900 std::set<u16> ids = env->getObjectsInsideRadius(pos, radius);
2902 int table = lua_gettop(L);
2903 for(std::set<u16>::const_iterator
2904 i = ids.begin(); i != ids.end(); i++){
2905 ServerActiveObject *obj = env->getActiveObject(*i);
2906 // Insert object reference into table
2907 lua_pushvalue(L, table_insert);
2908 lua_pushvalue(L, table);
2909 objectref_get_or_create(L, obj);
2910 if(lua_pcall(L, 2, 0, 0))
2911 script_error(L, "error: %s", lua_tostring(L, -1));
2916 // EnvRef:set_timeofday(val)
2918 static int l_set_timeofday(lua_State *L)
2920 EnvRef *o = checkobject(L, 1);
2921 ServerEnvironment *env = o->m_env;
2922 if(env == NULL) return 0;
2924 float timeofday_f = luaL_checknumber(L, 2);
2925 assert(timeofday_f >= 0.0 && timeofday_f <= 1.0);
2926 int timeofday_mh = (int)(timeofday_f * 24000.0);
2927 // This should be set directly in the environment but currently
2928 // such changes aren't immediately sent to the clients, so call
2929 // the server instead.
2930 //env->setTimeOfDay(timeofday_mh);
2931 get_server(L)->setTimeOfDay(timeofday_mh);
2935 // EnvRef:get_timeofday() -> 0...1
2936 static int l_get_timeofday(lua_State *L)
2938 EnvRef *o = checkobject(L, 1);
2939 ServerEnvironment *env = o->m_env;
2940 if(env == NULL) return 0;
2942 int timeofday_mh = env->getTimeOfDay();
2943 float timeofday_f = (float)timeofday_mh / 24000.0;
2944 lua_pushnumber(L, timeofday_f);
2948 static int gc_object(lua_State *L) {
2949 EnvRef *o = *(EnvRef **)(lua_touserdata(L, 1));
2955 EnvRef(ServerEnvironment *env):
2958 infostream<<"EnvRef created"<<std::endl;
2963 infostream<<"EnvRef destructing"<<std::endl;
2966 // Creates an EnvRef and leaves it on top of stack
2967 // Not callable from Lua; all references are created on the C side.
2968 static void create(lua_State *L, ServerEnvironment *env)
2970 EnvRef *o = new EnvRef(env);
2971 //infostream<<"EnvRef::create: o="<<o<<std::endl;
2972 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
2973 luaL_getmetatable(L, className);
2974 lua_setmetatable(L, -2);
2977 static void set_null(lua_State *L)
2979 EnvRef *o = checkobject(L, -1);
2983 static void Register(lua_State *L)
2986 int methodtable = lua_gettop(L);
2987 luaL_newmetatable(L, className);
2988 int metatable = lua_gettop(L);
2990 lua_pushliteral(L, "__metatable");
2991 lua_pushvalue(L, methodtable);
2992 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
2994 lua_pushliteral(L, "__index");
2995 lua_pushvalue(L, methodtable);
2996 lua_settable(L, metatable);
2998 lua_pushliteral(L, "__gc");
2999 lua_pushcfunction(L, gc_object);
3000 lua_settable(L, metatable);
3002 lua_pop(L, 1); // drop metatable
3004 luaL_openlib(L, 0, methods, 0); // fill methodtable
3005 lua_pop(L, 1); // drop methodtable
3007 // Cannot be created from Lua
3008 //lua_register(L, className, create_object);
3011 const char EnvRef::className[] = "EnvRef";
3012 const luaL_reg EnvRef::methods[] = {
3013 method(EnvRef, add_node),
3014 method(EnvRef, remove_node),
3015 method(EnvRef, get_node),
3016 method(EnvRef, get_node_or_nil),
3017 method(EnvRef, get_node_light),
3018 method(EnvRef, add_entity),
3019 method(EnvRef, add_item),
3020 method(EnvRef, add_rat),
3021 method(EnvRef, add_firefly),
3022 method(EnvRef, get_meta),
3023 method(EnvRef, get_player_by_name),
3024 method(EnvRef, get_objects_inside_radius),
3025 method(EnvRef, set_timeofday),
3026 method(EnvRef, get_timeofday),
3034 class LuaABM : public ActiveBlockModifier
3040 std::set<std::string> m_trigger_contents;
3041 std::set<std::string> m_required_neighbors;
3042 float m_trigger_interval;
3043 u32 m_trigger_chance;
3045 LuaABM(lua_State *L, int id,
3046 const std::set<std::string> &trigger_contents,
3047 const std::set<std::string> &required_neighbors,
3048 float trigger_interval, u32 trigger_chance):
3051 m_trigger_contents(trigger_contents),
3052 m_required_neighbors(required_neighbors),
3053 m_trigger_interval(trigger_interval),
3054 m_trigger_chance(trigger_chance)
3057 virtual std::set<std::string> getTriggerContents()
3059 return m_trigger_contents;
3061 virtual std::set<std::string> getRequiredNeighbors()
3063 return m_required_neighbors;
3065 virtual float getTriggerInterval()
3067 return m_trigger_interval;
3069 virtual u32 getTriggerChance()
3071 return m_trigger_chance;
3073 virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n,
3074 u32 active_object_count, u32 active_object_count_wider)
3076 lua_State *L = m_lua;
3079 assert(lua_checkstack(L, 20));
3080 StackUnroller stack_unroller(L);
3082 // Get minetest.registered_abms
3083 lua_getglobal(L, "minetest");
3084 lua_getfield(L, -1, "registered_abms");
3085 luaL_checktype(L, -1, LUA_TTABLE);
3086 int registered_abms = lua_gettop(L);
3088 // Get minetest.registered_abms[m_id]
3089 lua_pushnumber(L, m_id);
3090 lua_gettable(L, registered_abms);
3091 if(lua_isnil(L, -1))
3095 luaL_checktype(L, -1, LUA_TTABLE);
3096 lua_getfield(L, -1, "action");
3097 luaL_checktype(L, -1, LUA_TFUNCTION);
3099 pushnode(L, n, env->getGameDef()->ndef());
3100 lua_pushnumber(L, active_object_count);
3101 lua_pushnumber(L, active_object_count_wider);
3102 if(lua_pcall(L, 4, 0, 0))
3103 script_error(L, "error: %s", lua_tostring(L, -1));
3108 // Writes a line to dstream
3109 static int l_debug(lua_State *L)
3111 std::string text = lua_tostring(L, 1);
3112 dstream << text << std::endl;
3116 // log([level,] text)
3117 // Writes a line to the logger.
3118 // The one-argument version logs to infostream.
3119 // The two-argument version accept a log level: error, action, info, or verbose.
3120 static int l_log(lua_State *L)
3123 LogMessageLevel level = LMT_INFO;
3124 if(lua_isnone(L, 2))
3126 text = lua_tostring(L, 1);
3130 std::string levelname = lua_tostring(L, 1);
3131 text = lua_tostring(L, 2);
3132 if(levelname == "error")
3134 else if(levelname == "action")
3136 else if(levelname == "verbose")
3137 level = LMT_VERBOSE;
3139 log_printline(level, text);
3143 // register_item_raw({lots of stuff})
3144 static int l_register_item_raw(lua_State *L)
3146 luaL_checktype(L, 1, LUA_TTABLE);
3149 // Get the writable item and node definition managers from the server
3150 IWritableItemDefManager *idef =
3151 get_server(L)->getWritableItemDefManager();
3152 IWritableNodeDefManager *ndef =
3153 get_server(L)->getWritableNodeDefManager();
3155 // Check if name is defined
3156 lua_getfield(L, table, "name");
3157 if(lua_isstring(L, -1)){
3158 std::string name = lua_tostring(L, -1);
3159 infostream<<"register_item_raw: "<<name<<std::endl;
3161 throw LuaError(L, "register_item_raw: name is not defined or not a string");
3164 // Check if on_use is defined
3166 // Read the item definition and register it
3167 ItemDefinition def = read_item_definition(L, table);
3168 idef->registerItem(def);
3170 // Read the node definition (content features) and register it
3171 if(def.type == ITEM_NODE)
3173 ContentFeatures f = read_content_features(L, table);
3174 ndef->set(f.name, f);
3177 return 0; /* number of results */
3180 // register_alias_raw(name, convert_to_name)
3181 static int l_register_alias_raw(lua_State *L)
3183 std::string name = luaL_checkstring(L, 1);
3184 std::string convert_to = luaL_checkstring(L, 2);
3186 // Get the writable item definition manager from the server
3187 IWritableItemDefManager *idef =
3188 get_server(L)->getWritableItemDefManager();
3190 idef->registerAlias(name, convert_to);
3192 return 0; /* number of results */
3195 // helper for register_craft
3196 static bool read_craft_recipe_shaped(lua_State *L, int index,
3197 int &width, std::vector<std::string> &recipe)
3200 index = lua_gettop(L) + 1 + index;
3202 if(!lua_istable(L, index))
3207 while(lua_next(L, index) != 0){
3209 // key at index -2 and value at index -1
3210 if(!lua_istable(L, -1))
3212 int table2 = lua_gettop(L);
3214 while(lua_next(L, table2) != 0){
3215 // key at index -2 and value at index -1
3216 if(!lua_isstring(L, -1))
3218 recipe.push_back(lua_tostring(L, -1));
3219 // removes value, keeps key for next iteration
3226 if(colcount != width)
3229 // removes value, keeps key for next iteration
3236 // helper for register_craft
3237 static bool read_craft_recipe_shapeless(lua_State *L, int index,
3238 std::vector<std::string> &recipe)
3241 index = lua_gettop(L) + 1 + index;
3243 if(!lua_istable(L, index))
3247 while(lua_next(L, index) != 0){
3248 // key at index -2 and value at index -1
3249 if(!lua_isstring(L, -1))
3251 recipe.push_back(lua_tostring(L, -1));
3252 // removes value, keeps key for next iteration
3258 // helper for register_craft
3259 static bool read_craft_replacements(lua_State *L, int index,
3260 CraftReplacements &replacements)
3263 index = lua_gettop(L) + 1 + index;
3265 if(!lua_istable(L, index))
3269 while(lua_next(L, index) != 0){
3270 // key at index -2 and value at index -1
3271 if(!lua_istable(L, -1))
3273 lua_rawgeti(L, -1, 1);
3274 if(!lua_isstring(L, -1))
3276 std::string replace_from = lua_tostring(L, -1);
3278 lua_rawgeti(L, -1, 2);
3279 if(!lua_isstring(L, -1))
3281 std::string replace_to = lua_tostring(L, -1);
3283 replacements.pairs.push_back(
3284 std::make_pair(replace_from, replace_to));
3285 // removes value, keeps key for next iteration
3290 // register_craft({output=item, recipe={{item00,item10},{item01,item11}})
3291 static int l_register_craft(lua_State *L)
3293 //infostream<<"register_craft"<<std::endl;
3294 luaL_checktype(L, 1, LUA_TTABLE);
3297 // Get the writable craft definition manager from the server
3298 IWritableCraftDefManager *craftdef =
3299 get_server(L)->getWritableCraftDefManager();
3301 std::string type = getstringfield_default(L, table, "type", "shaped");
3304 CraftDefinitionShaped
3306 if(type == "shaped"){
3307 std::string output = getstringfield_default(L, table, "output", "");
3309 throw LuaError(L, "Crafting definition is missing an output");
3312 std::vector<std::string> recipe;
3313 lua_getfield(L, table, "recipe");
3314 if(lua_isnil(L, -1))
3315 throw LuaError(L, "Crafting definition is missing a recipe"
3316 " (output=\"" + output + "\")");
3317 if(!read_craft_recipe_shaped(L, -1, width, recipe))
3318 throw LuaError(L, "Invalid crafting recipe"
3319 " (output=\"" + output + "\")");
3321 CraftReplacements replacements;
3322 lua_getfield(L, table, "replacements");
3323 if(!lua_isnil(L, -1))
3325 if(!read_craft_replacements(L, -1, replacements))
3326 throw LuaError(L, "Invalid replacements"
3327 " (output=\"" + output + "\")");
3330 CraftDefinition *def = new CraftDefinitionShaped(
3331 output, width, recipe, replacements);
3332 craftdef->registerCraft(def);
3335 CraftDefinitionShapeless
3337 else if(type == "shapeless"){
3338 std::string output = getstringfield_default(L, table, "output", "");
3340 throw LuaError(L, "Crafting definition (shapeless)"
3341 " is missing an output");
3343 std::vector<std::string> recipe;
3344 lua_getfield(L, table, "recipe");
3345 if(lua_isnil(L, -1))
3346 throw LuaError(L, "Crafting definition (shapeless)"
3347 " is missing a recipe"
3348 " (output=\"" + output + "\")");
3349 if(!read_craft_recipe_shapeless(L, -1, recipe))
3350 throw LuaError(L, "Invalid crafting recipe"
3351 " (output=\"" + output + "\")");
3353 CraftReplacements replacements;
3354 lua_getfield(L, table, "replacements");
3355 if(!lua_isnil(L, -1))
3357 if(!read_craft_replacements(L, -1, replacements))
3358 throw LuaError(L, "Invalid replacements"
3359 " (output=\"" + output + "\")");
3362 CraftDefinition *def = new CraftDefinitionShapeless(
3363 output, recipe, replacements);
3364 craftdef->registerCraft(def);
3367 CraftDefinitionToolRepair
3369 else if(type == "toolrepair"){
3370 float additional_wear = getfloatfield_default(L, table,
3371 "additional_wear", 0.0);
3373 CraftDefinition *def = new CraftDefinitionToolRepair(
3375 craftdef->registerCraft(def);
3378 CraftDefinitionCooking
3380 else if(type == "cooking"){
3381 std::string output = getstringfield_default(L, table, "output", "");
3383 throw LuaError(L, "Crafting definition (cooking)"
3384 " is missing an output");
3386 std::string recipe = getstringfield_default(L, table, "recipe", "");
3388 throw LuaError(L, "Crafting definition (cooking)"
3389 " is missing a recipe"
3390 " (output=\"" + output + "\")");
3392 float cooktime = getfloatfield_default(L, table, "cooktime", 3.0);
3394 CraftDefinition *def = new CraftDefinitionCooking(
3395 output, recipe, cooktime);
3396 craftdef->registerCraft(def);
3401 else if(type == "fuel"){
3402 std::string recipe = getstringfield_default(L, table, "recipe", "");
3404 throw LuaError(L, "Crafting definition (fuel)"
3405 " is missing a recipe");
3407 float burntime = getfloatfield_default(L, table, "burntime", 1.0);
3409 CraftDefinition *def = new CraftDefinitionFuel(
3411 craftdef->registerCraft(def);
3415 throw LuaError(L, "Unknown crafting definition type: \"" + type + "\"");
3419 return 0; /* number of results */
3422 // setting_get(name)
3423 static int l_setting_get(lua_State *L)
3425 const char *name = luaL_checkstring(L, 1);
3427 std::string value = g_settings->get(name);
3428 lua_pushstring(L, value.c_str());
3429 } catch(SettingNotFoundException &e){
3435 // setting_getbool(name)
3436 static int l_setting_getbool(lua_State *L)
3438 const char *name = luaL_checkstring(L, 1);
3440 bool value = g_settings->getBool(name);
3441 lua_pushboolean(L, value);
3442 } catch(SettingNotFoundException &e){
3448 // chat_send_all(text)
3449 static int l_chat_send_all(lua_State *L)
3451 const char *text = luaL_checkstring(L, 1);
3452 // Get server from registry
3453 Server *server = get_server(L);
3455 server->notifyPlayers(narrow_to_wide(text));
3459 // chat_send_player(name, text)
3460 static int l_chat_send_player(lua_State *L)
3462 const char *name = luaL_checkstring(L, 1);
3463 const char *text = luaL_checkstring(L, 2);
3464 // Get server from registry
3465 Server *server = get_server(L);
3467 server->notifyPlayer(name, narrow_to_wide(text));
3471 // get_player_privs(name, text)
3472 static int l_get_player_privs(lua_State *L)
3474 const char *name = luaL_checkstring(L, 1);
3475 // Get server from registry
3476 Server *server = get_server(L);
3479 int table = lua_gettop(L);
3480 u64 privs_i = server->getPlayerAuthPrivs(name);
3481 // Special case for the "name" setting (local player / server owner)
3482 if(name == g_settings->get("name"))
3484 std::set<std::string> privs_s = privsToSet(privs_i);
3485 for(std::set<std::string>::const_iterator
3486 i = privs_s.begin(); i != privs_s.end(); i++){
3487 lua_pushboolean(L, true);
3488 lua_setfield(L, table, i->c_str());
3490 lua_pushvalue(L, table);
3494 // get_inventory(location)
3495 static int l_get_inventory(lua_State *L)
3497 InventoryLocation loc;
3499 std::string type = checkstringfield(L, 1, "type");
3500 if(type == "player"){
3501 std::string name = checkstringfield(L, 1, "name");
3502 loc.setPlayer(name);
3503 } else if(type == "node"){
3504 lua_getfield(L, 1, "pos");
3505 v3s16 pos = check_v3s16(L, -1);
3506 loc.setNodeMeta(pos);
3509 if(get_server(L)->getInventory(loc) != NULL)
3510 InvRef::create(L, loc);
3516 // get_digging_properties(material_properties, tool_digging_properties[, time_from_last_punch])
3517 static int l_get_digging_properties(lua_State *L)
3519 MaterialProperties mp = read_material_properties(L, 1);
3520 ToolDiggingProperties tp = read_tool_digging_properties(L, 2);
3521 if(lua_isnoneornil(L, 3))
3522 push_digging_properties(L, getDiggingProperties(&mp, &tp));
3524 push_digging_properties(L, getDiggingProperties(&mp, &tp,
3525 luaL_checknumber(L, 3)));
3529 // get_hitting_properties(material_properties, tool_digging_properties[, time_from_last_punch])
3530 static int l_get_hitting_properties(lua_State *L)
3532 MaterialProperties mp = read_material_properties(L, 1);
3533 ToolDiggingProperties tp = read_tool_digging_properties(L, 2);
3534 if(lua_isnoneornil(L, 3))
3535 push_hitting_properties(L, getHittingProperties(&mp, &tp));
3537 push_hitting_properties(L, getHittingProperties(&mp, &tp,
3538 luaL_checknumber(L, 3)));
3542 // get_current_modname()
3543 static int l_get_current_modname(lua_State *L)
3545 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
3549 // get_modpath(modname)
3550 static int l_get_modpath(lua_State *L)
3552 const char *modname = luaL_checkstring(L, 1);
3554 const ModSpec *mod = get_server(L)->getModSpec(modname);
3559 lua_pushstring(L, mod->path.c_str());
3564 static int l_get_worldpath(lua_State *L)
3566 std::string worldpath = get_server(L)->getWorldPath();
3567 lua_pushstring(L, worldpath.c_str());
3571 static const struct luaL_Reg minetest_f [] = {
3574 {"register_item_raw", l_register_item_raw},
3575 {"register_alias_raw", l_register_alias_raw},
3576 {"register_craft", l_register_craft},
3577 {"setting_get", l_setting_get},
3578 {"setting_getbool", l_setting_getbool},
3579 {"chat_send_all", l_chat_send_all},
3580 {"chat_send_player", l_chat_send_player},
3581 {"get_player_privs", l_get_player_privs},
3582 {"get_inventory", l_get_inventory},
3583 {"get_digging_properties", l_get_digging_properties},
3584 {"get_hitting_properties", l_get_hitting_properties},
3585 {"get_current_modname", l_get_current_modname},
3586 {"get_modpath", l_get_modpath},
3587 {"get_worldpath", l_get_worldpath},
3592 Main export function
3595 void scriptapi_export(lua_State *L, Server *server)
3598 assert(lua_checkstack(L, 20));
3599 infostream<<"scriptapi_export"<<std::endl;
3600 StackUnroller stack_unroller(L);
3602 // Store server as light userdata in registry
3603 lua_pushlightuserdata(L, server);
3604 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_server");
3606 // Register global functions in table minetest
3608 luaL_register(L, NULL, minetest_f);
3609 lua_setglobal(L, "minetest");
3611 // Get the main minetest table
3612 lua_getglobal(L, "minetest");
3614 // Add tables to minetest
3617 lua_setfield(L, -2, "object_refs");
3619 lua_setfield(L, -2, "luaentities");
3621 // Register wrappers
3622 LuaItemStack::Register(L);
3623 InvRef::Register(L);
3624 NodeMetaRef::Register(L);
3625 ObjectRef::Register(L);
3626 EnvRef::Register(L);
3629 bool scriptapi_loadmod(lua_State *L, const std::string &scriptpath,
3630 const std::string &modname)
3632 ModNameStorer modnamestorer(L, modname);
3634 if(!string_allowed(modname, "abcdefghijklmnopqrstuvwxyz"
3636 errorstream<<"Error loading mod \""<<modname
3637 <<"\": modname does not follow naming conventions: "
3638 <<"Only chararacters [a-z0-9_] are allowed."<<std::endl;
3642 bool success = false;
3645 success = script_load(L, scriptpath.c_str());
3648 errorstream<<"Error loading mod \""<<modname
3649 <<"\": "<<e.what()<<std::endl;
3655 void scriptapi_add_environment(lua_State *L, ServerEnvironment *env)
3658 assert(lua_checkstack(L, 20));
3659 infostream<<"scriptapi_add_environment"<<std::endl;
3660 StackUnroller stack_unroller(L);
3662 // Create EnvRef on stack
3663 EnvRef::create(L, env);
3664 int envref = lua_gettop(L);
3666 // minetest.env = envref
3667 lua_getglobal(L, "minetest");
3668 luaL_checktype(L, -1, LUA_TTABLE);
3669 lua_pushvalue(L, envref);
3670 lua_setfield(L, -2, "env");
3672 // Store environment as light userdata in registry
3673 lua_pushlightuserdata(L, env);
3674 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_env");
3677 Add ActiveBlockModifiers to environment
3680 // Get minetest.registered_abms
3681 lua_getglobal(L, "minetest");
3682 lua_getfield(L, -1, "registered_abms");
3683 luaL_checktype(L, -1, LUA_TTABLE);
3684 int registered_abms = lua_gettop(L);
3686 if(lua_istable(L, registered_abms)){
3687 int table = lua_gettop(L);
3689 while(lua_next(L, table) != 0){
3690 // key at index -2 and value at index -1
3691 int id = lua_tonumber(L, -2);
3692 int current_abm = lua_gettop(L);
3694 std::set<std::string> trigger_contents;
3695 lua_getfield(L, current_abm, "nodenames");
3696 if(lua_istable(L, -1)){
3697 int table = lua_gettop(L);
3699 while(lua_next(L, table) != 0){
3700 // key at index -2 and value at index -1
3701 luaL_checktype(L, -1, LUA_TSTRING);
3702 trigger_contents.insert(lua_tostring(L, -1));
3703 // removes value, keeps key for next iteration
3706 } else if(lua_isstring(L, -1)){
3707 trigger_contents.insert(lua_tostring(L, -1));
3711 std::set<std::string> required_neighbors;
3712 lua_getfield(L, current_abm, "neighbors");
3713 if(lua_istable(L, -1)){
3714 int table = lua_gettop(L);
3716 while(lua_next(L, table) != 0){
3717 // key at index -2 and value at index -1
3718 luaL_checktype(L, -1, LUA_TSTRING);
3719 required_neighbors.insert(lua_tostring(L, -1));
3720 // removes value, keeps key for next iteration
3723 } else if(lua_isstring(L, -1)){
3724 required_neighbors.insert(lua_tostring(L, -1));
3728 float trigger_interval = 10.0;
3729 getfloatfield(L, current_abm, "interval", trigger_interval);
3731 int trigger_chance = 50;
3732 getintfield(L, current_abm, "chance", trigger_chance);
3734 LuaABM *abm = new LuaABM(L, id, trigger_contents,
3735 required_neighbors, trigger_interval, trigger_chance);
3737 env->addActiveBlockModifier(abm);
3739 // removes value, keeps key for next iteration
3747 // Dump stack top with the dump2 function
3748 static void dump2(lua_State *L, const char *name)
3750 // Dump object (debug)
3751 lua_getglobal(L, "dump2");
3752 luaL_checktype(L, -1, LUA_TFUNCTION);
3753 lua_pushvalue(L, -2); // Get previous stack top as first parameter
3754 lua_pushstring(L, name);
3755 if(lua_pcall(L, 2, 0, 0))
3756 script_error(L, "error: %s", lua_tostring(L, -1));
3764 void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj)
3767 assert(lua_checkstack(L, 20));
3768 //infostream<<"scriptapi_add_object_reference: id="<<cobj->getId()<<std::endl;
3769 StackUnroller stack_unroller(L);
3771 // Create object on stack
3772 ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack
3773 int object = lua_gettop(L);
3775 // Get minetest.object_refs table
3776 lua_getglobal(L, "minetest");
3777 lua_getfield(L, -1, "object_refs");
3778 luaL_checktype(L, -1, LUA_TTABLE);
3779 int objectstable = lua_gettop(L);
3781 // object_refs[id] = object
3782 lua_pushnumber(L, cobj->getId()); // Push id
3783 lua_pushvalue(L, object); // Copy object to top of stack
3784 lua_settable(L, objectstable);
3787 void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj)
3790 assert(lua_checkstack(L, 20));
3791 //infostream<<"scriptapi_rm_object_reference: id="<<cobj->getId()<<std::endl;
3792 StackUnroller stack_unroller(L);
3794 // Get minetest.object_refs table
3795 lua_getglobal(L, "minetest");
3796 lua_getfield(L, -1, "object_refs");
3797 luaL_checktype(L, -1, LUA_TTABLE);
3798 int objectstable = lua_gettop(L);
3800 // Get object_refs[id]
3801 lua_pushnumber(L, cobj->getId()); // Push id
3802 lua_gettable(L, objectstable);
3803 // Set object reference to NULL
3804 ObjectRef::set_null(L);
3805 lua_pop(L, 1); // pop object
3807 // Set object_refs[id] = nil
3808 lua_pushnumber(L, cobj->getId()); // Push id
3810 lua_settable(L, objectstable);
3813 bool scriptapi_on_chat_message(lua_State *L, const std::string &name,
3814 const std::string &message)
3817 assert(lua_checkstack(L, 20));
3818 StackUnroller stack_unroller(L);
3820 // Get minetest.registered_on_chat_messages
3821 lua_getglobal(L, "minetest");
3822 lua_getfield(L, -1, "registered_on_chat_messages");
3823 luaL_checktype(L, -1, LUA_TTABLE);
3824 int table = lua_gettop(L);
3827 while(lua_next(L, table) != 0){
3828 // key at index -2 and value at index -1
3829 luaL_checktype(L, -1, LUA_TFUNCTION);
3831 lua_pushstring(L, name.c_str());
3832 lua_pushstring(L, message.c_str());
3833 if(lua_pcall(L, 2, 1, 0))
3834 script_error(L, "error: %s", lua_tostring(L, -1));
3835 bool ate = lua_toboolean(L, -1);
3839 // value removed, keep key for next iteration
3848 void scriptapi_on_newplayer(lua_State *L, ServerActiveObject *player)
3851 assert(lua_checkstack(L, 20));
3852 StackUnroller stack_unroller(L);
3854 // Get minetest.registered_on_newplayers
3855 lua_getglobal(L, "minetest");
3856 lua_getfield(L, -1, "registered_on_newplayers");
3857 luaL_checktype(L, -1, LUA_TTABLE);
3858 int table = lua_gettop(L);
3861 while(lua_next(L, table) != 0){
3862 // key at index -2 and value at index -1
3863 luaL_checktype(L, -1, LUA_TFUNCTION);
3865 objectref_get_or_create(L, player);
3866 if(lua_pcall(L, 1, 0, 0))
3867 script_error(L, "error: %s", lua_tostring(L, -1));
3868 // value removed, keep key for next iteration
3872 void scriptapi_on_dieplayer(lua_State *L, ServerActiveObject *player)
3875 assert(lua_checkstack(L, 20));
3876 StackUnroller stack_unroller(L);
3878 // Get minetest.registered_on_dieplayers
3879 lua_getglobal(L, "minetest");
3880 lua_getfield(L, -1, "registered_on_dieplayers");
3881 luaL_checktype(L, -1, LUA_TTABLE);
3882 int table = lua_gettop(L);
3885 while(lua_next(L, table) != 0){
3886 // key at index -2 and value at index -1
3887 luaL_checktype(L, -1, LUA_TFUNCTION);
3889 objectref_get_or_create(L, player);
3890 if(lua_pcall(L, 1, 0, 0))
3891 script_error(L, "error: %s", lua_tostring(L, -1));
3892 // value removed, keep key for next iteration
3897 bool scriptapi_on_respawnplayer(lua_State *L, ServerActiveObject *player)
3900 assert(lua_checkstack(L, 20));
3901 StackUnroller stack_unroller(L);
3903 dstream<<"player: "<<player<<" id: "<<player->getId()<<std::endl;
3905 bool positioning_handled_by_some = false;
3907 // Get minetest.registered_on_respawnplayers
3908 lua_getglobal(L, "minetest");
3909 lua_getfield(L, -1, "registered_on_respawnplayers");
3910 luaL_checktype(L, -1, LUA_TTABLE);
3911 int table = lua_gettop(L);
3914 while(lua_next(L, table) != 0){
3915 // key at index -2 and value at index -1
3916 luaL_checktype(L, -1, LUA_TFUNCTION);
3918 objectref_get_or_create(L, player);
3919 if(lua_pcall(L, 1, 1, 0))
3920 script_error(L, "error: %s", lua_tostring(L, -1));
3921 bool positioning_handled = lua_toboolean(L, -1);
3923 if(positioning_handled)
3924 positioning_handled_by_some = true;
3925 // value removed, keep key for next iteration
3927 return positioning_handled_by_some;
3930 void scriptapi_get_creative_inventory(lua_State *L, ServerRemotePlayer *player)
3932 lua_getglobal(L, "minetest");
3933 lua_getfield(L, -1, "creative_inventory");
3934 luaL_checktype(L, -1, LUA_TTABLE);
3935 inventory_set_list_from_lua(&player->inventory, "main", L, -1,
3936 PLAYER_INVENTORY_SIZE);
3940 item callbacks and node callbacks
3943 // Retrieves minetest.registered_items[name][callbackname]
3944 // If that is nil or on error, return false and stack is unchanged
3945 // If that is a function, returns true and pushes the
3946 // function onto the stack
3947 static bool get_item_callback(lua_State *L,
3948 const char *name, const char *callbackname)
3950 lua_getglobal(L, "minetest");
3951 lua_getfield(L, -1, "registered_items");
3953 luaL_checktype(L, -1, LUA_TTABLE);
3954 lua_getfield(L, -1, name);
3956 // Should be a table
3957 if(lua_type(L, -1) != LUA_TTABLE)
3959 errorstream<<"Item \""<<name<<"\" not defined"<<std::endl;
3963 lua_getfield(L, -1, callbackname);
3965 // Should be a function or nil
3966 if(lua_type(L, -1) == LUA_TFUNCTION)
3970 else if(lua_isnil(L, -1))
3977 errorstream<<"Item \""<<name<<"\" callback \""
3978 <<callbackname<<" is not a function"<<std::endl;
3984 bool scriptapi_item_on_drop(lua_State *L, ItemStack &item,
3985 ServerActiveObject *dropper, v3f pos)
3988 assert(lua_checkstack(L, 20));
3989 StackUnroller stack_unroller(L);
3991 // Push callback function on stack
3992 if(!get_item_callback(L, item.name.c_str(), "on_drop"))
3996 LuaItemStack::create(L, item);
3997 objectref_get_or_create(L, dropper);
3998 pushFloatPos(L, pos);
3999 if(lua_pcall(L, 3, 1, 0))
4000 script_error(L, "error: %s", lua_tostring(L, -1));
4001 if(!lua_isnil(L, -1))
4002 item = read_item(L, -1);
4006 bool scriptapi_item_on_place(lua_State *L, ItemStack &item,
4007 ServerActiveObject *placer, const PointedThing &pointed)
4010 assert(lua_checkstack(L, 20));
4011 StackUnroller stack_unroller(L);
4013 // Push callback function on stack
4014 if(!get_item_callback(L, item.name.c_str(), "on_place"))
4018 LuaItemStack::create(L, item);
4019 objectref_get_or_create(L, placer);
4020 push_pointed_thing(L, pointed);
4021 if(lua_pcall(L, 3, 1, 0))
4022 script_error(L, "error: %s", lua_tostring(L, -1));
4023 if(!lua_isnil(L, -1))
4024 item = read_item(L, -1);
4028 bool scriptapi_item_on_use(lua_State *L, ItemStack &item,
4029 ServerActiveObject *user, const PointedThing &pointed)
4032 assert(lua_checkstack(L, 20));
4033 StackUnroller stack_unroller(L);
4035 // Push callback function on stack
4036 if(!get_item_callback(L, item.name.c_str(), "on_use"))
4040 LuaItemStack::create(L, item);
4041 objectref_get_or_create(L, user);
4042 push_pointed_thing(L, pointed);
4043 if(lua_pcall(L, 3, 1, 0))
4044 script_error(L, "error: %s", lua_tostring(L, -1));
4045 if(!lua_isnil(L, -1))
4046 item = read_item(L, -1);
4050 bool scriptapi_node_on_punch(lua_State *L, v3s16 pos, MapNode node,
4051 ServerActiveObject *puncher)
4054 assert(lua_checkstack(L, 20));
4055 StackUnroller stack_unroller(L);
4057 INodeDefManager *ndef = get_server(L)->ndef();
4059 // Push callback function on stack
4060 if(!get_item_callback(L, ndef->get(node).name.c_str(), "on_punch"))
4065 pushnode(L, node, ndef);
4066 objectref_get_or_create(L, puncher);
4067 if(lua_pcall(L, 3, 0, 0))
4068 script_error(L, "error: %s", lua_tostring(L, -1));
4072 bool scriptapi_node_on_dig(lua_State *L, v3s16 pos, MapNode node,
4073 ServerActiveObject *digger)
4076 assert(lua_checkstack(L, 20));
4077 StackUnroller stack_unroller(L);
4079 INodeDefManager *ndef = get_server(L)->ndef();
4081 // Push callback function on stack
4082 if(!get_item_callback(L, ndef->get(node).name.c_str(), "on_dig"))
4087 pushnode(L, node, ndef);
4088 objectref_get_or_create(L, digger);
4089 if(lua_pcall(L, 3, 0, 0))
4090 script_error(L, "error: %s", lua_tostring(L, -1));
4098 void scriptapi_environment_step(lua_State *L, float dtime)
4101 assert(lua_checkstack(L, 20));
4102 //infostream<<"scriptapi_environment_step"<<std::endl;
4103 StackUnroller stack_unroller(L);
4105 // Get minetest.registered_globalsteps
4106 lua_getglobal(L, "minetest");
4107 lua_getfield(L, -1, "registered_globalsteps");
4108 luaL_checktype(L, -1, LUA_TTABLE);
4109 int table = lua_gettop(L);
4112 while(lua_next(L, table) != 0){
4113 // key at index -2 and value at index -1
4114 luaL_checktype(L, -1, LUA_TFUNCTION);
4116 lua_pushnumber(L, dtime);
4117 if(lua_pcall(L, 1, 0, 0))
4118 script_error(L, "error: %s", lua_tostring(L, -1));
4119 // value removed, keep key for next iteration
4123 void scriptapi_environment_on_generated(lua_State *L, v3s16 minp, v3s16 maxp)
4126 assert(lua_checkstack(L, 20));
4127 //infostream<<"scriptapi_environment_on_generated"<<std::endl;
4128 StackUnroller stack_unroller(L);
4130 // Get minetest.registered_on_generateds
4131 lua_getglobal(L, "minetest");
4132 lua_getfield(L, -1, "registered_on_generateds");
4133 luaL_checktype(L, -1, LUA_TTABLE);
4134 int table = lua_gettop(L);
4137 while(lua_next(L, table) != 0){
4138 // key at index -2 and value at index -1
4139 luaL_checktype(L, -1, LUA_TFUNCTION);
4141 push_v3s16(L, minp);
4142 push_v3s16(L, maxp);
4143 if(lua_pcall(L, 2, 0, 0))
4144 script_error(L, "error: %s", lua_tostring(L, -1));
4145 // value removed, keep key for next iteration
4153 bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
4154 const std::string &staticdata)
4157 assert(lua_checkstack(L, 20));
4158 infostream<<"scriptapi_luaentity_add: id="<<id<<" name=\""
4159 <<name<<"\""<<std::endl;
4160 StackUnroller stack_unroller(L);
4162 // Get minetest.registered_entities[name]
4163 lua_getglobal(L, "minetest");
4164 lua_getfield(L, -1, "registered_entities");
4165 luaL_checktype(L, -1, LUA_TTABLE);
4166 lua_pushstring(L, name);
4167 lua_gettable(L, -2);
4168 // Should be a table, which we will use as a prototype
4169 //luaL_checktype(L, -1, LUA_TTABLE);
4170 if(lua_type(L, -1) != LUA_TTABLE){
4171 errorstream<<"LuaEntity name \""<<name<<"\" not defined"<<std::endl;
4174 int prototype_table = lua_gettop(L);
4175 //dump2(L, "prototype_table");
4177 // Create entity object
4179 int object = lua_gettop(L);
4181 // Set object metatable
4182 lua_pushvalue(L, prototype_table);
4183 lua_setmetatable(L, -2);
4185 // Add object reference
4186 // This should be userdata with metatable ObjectRef
4187 objectref_get(L, id);
4188 luaL_checktype(L, -1, LUA_TUSERDATA);
4189 if(!luaL_checkudata(L, -1, "ObjectRef"))
4190 luaL_typerror(L, -1, "ObjectRef");
4191 lua_setfield(L, -2, "object");
4193 // minetest.luaentities[id] = object
4194 lua_getglobal(L, "minetest");
4195 lua_getfield(L, -1, "luaentities");
4196 luaL_checktype(L, -1, LUA_TTABLE);
4197 lua_pushnumber(L, id); // Push id
4198 lua_pushvalue(L, object); // Copy object to top of stack
4199 lua_settable(L, -3);
4201 // Get on_activate function
4202 lua_pushvalue(L, object);
4203 lua_getfield(L, -1, "on_activate");
4204 if(!lua_isnil(L, -1)){
4205 luaL_checktype(L, -1, LUA_TFUNCTION);
4206 lua_pushvalue(L, object); // self
4207 lua_pushlstring(L, staticdata.c_str(), staticdata.size());
4208 // Call with 2 arguments, 0 results
4209 if(lua_pcall(L, 2, 0, 0))
4210 script_error(L, "error running function %s:on_activate: %s\n",
4211 name, lua_tostring(L, -1));
4217 void scriptapi_luaentity_rm(lua_State *L, u16 id)
4220 assert(lua_checkstack(L, 20));
4221 infostream<<"scriptapi_luaentity_rm: id="<<id<<std::endl;
4223 // Get minetest.luaentities table
4224 lua_getglobal(L, "minetest");
4225 lua_getfield(L, -1, "luaentities");
4226 luaL_checktype(L, -1, LUA_TTABLE);
4227 int objectstable = lua_gettop(L);
4229 // Set luaentities[id] = nil
4230 lua_pushnumber(L, id); // Push id
4232 lua_settable(L, objectstable);
4234 lua_pop(L, 2); // pop luaentities, minetest
4237 std::string scriptapi_luaentity_get_staticdata(lua_State *L, u16 id)
4240 assert(lua_checkstack(L, 20));
4241 infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl;
4242 StackUnroller stack_unroller(L);
4244 // Get minetest.luaentities[id]
4245 luaentity_get(L, id);
4246 int object = lua_gettop(L);
4248 // Get get_staticdata function
4249 lua_pushvalue(L, object);
4250 lua_getfield(L, -1, "get_staticdata");
4251 if(lua_isnil(L, -1))
4254 luaL_checktype(L, -1, LUA_TFUNCTION);
4255 lua_pushvalue(L, object); // self
4256 // Call with 1 arguments, 1 results
4257 if(lua_pcall(L, 1, 1, 0))
4258 script_error(L, "error running function get_staticdata: %s\n",
4259 lua_tostring(L, -1));
4262 const char *s = lua_tolstring(L, -1, &len);
4263 return std::string(s, len);
4266 void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
4267 LuaEntityProperties *prop)
4270 assert(lua_checkstack(L, 20));
4271 infostream<<"scriptapi_luaentity_get_properties: id="<<id<<std::endl;
4272 StackUnroller stack_unroller(L);
4274 // Get minetest.luaentities[id]
4275 luaentity_get(L, id);
4276 //int object = lua_gettop(L);
4280 getboolfield(L, -1, "physical", prop->physical);
4282 getfloatfield(L, -1, "weight", prop->weight);
4284 lua_getfield(L, -1, "collisionbox");
4285 if(lua_istable(L, -1))
4286 prop->collisionbox = read_aabbox3df32(L, -1, 1.0);
4289 getstringfield(L, -1, "visual", prop->visual);
4291 lua_getfield(L, -1, "visual_size");
4292 if(lua_istable(L, -1))
4293 prop->visual_size = read_v2f(L, -1);
4296 lua_getfield(L, -1, "textures");
4297 if(lua_istable(L, -1)){
4298 prop->textures.clear();
4299 int table = lua_gettop(L);
4301 while(lua_next(L, table) != 0){
4302 // key at index -2 and value at index -1
4303 if(lua_isstring(L, -1))
4304 prop->textures.push_back(lua_tostring(L, -1));
4306 prop->textures.push_back("");
4307 // removes value, keeps key for next iteration
4313 lua_getfield(L, -1, "spritediv");
4314 if(lua_istable(L, -1))
4315 prop->spritediv = read_v2s16(L, -1);
4318 lua_getfield(L, -1, "initial_sprite_basepos");
4319 if(lua_istable(L, -1))
4320 prop->initial_sprite_basepos = read_v2s16(L, -1);
4324 void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime)
4327 assert(lua_checkstack(L, 20));
4328 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
4329 StackUnroller stack_unroller(L);
4331 // Get minetest.luaentities[id]
4332 luaentity_get(L, id);
4333 int object = lua_gettop(L);
4334 // State: object is at top of stack
4335 // Get step function
4336 lua_getfield(L, -1, "on_step");
4337 if(lua_isnil(L, -1))
4339 luaL_checktype(L, -1, LUA_TFUNCTION);
4340 lua_pushvalue(L, object); // self
4341 lua_pushnumber(L, dtime); // dtime
4342 // Call with 2 arguments, 0 results
4343 if(lua_pcall(L, 2, 0, 0))
4344 script_error(L, "error running function 'on_step': %s\n", lua_tostring(L, -1));
4347 // Calls entity:on_punch(ObjectRef puncher, time_from_last_punch)
4348 void scriptapi_luaentity_punch(lua_State *L, u16 id,
4349 ServerActiveObject *puncher, float time_from_last_punch)
4352 assert(lua_checkstack(L, 20));
4353 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
4354 StackUnroller stack_unroller(L);
4356 // Get minetest.luaentities[id]
4357 luaentity_get(L, id);
4358 int object = lua_gettop(L);
4359 // State: object is at top of stack
4361 lua_getfield(L, -1, "on_punch");
4362 if(lua_isnil(L, -1))
4364 luaL_checktype(L, -1, LUA_TFUNCTION);
4365 lua_pushvalue(L, object); // self
4366 objectref_get_or_create(L, puncher); // Clicker reference
4367 lua_pushnumber(L, time_from_last_punch);
4368 // Call with 2 arguments, 0 results
4369 if(lua_pcall(L, 3, 0, 0))
4370 script_error(L, "error running function 'on_punch': %s\n", lua_tostring(L, -1));
4373 // Calls entity:on_rightclick(ObjectRef clicker)
4374 void scriptapi_luaentity_rightclick(lua_State *L, u16 id,
4375 ServerActiveObject *clicker)
4378 assert(lua_checkstack(L, 20));
4379 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
4380 StackUnroller stack_unroller(L);
4382 // Get minetest.luaentities[id]
4383 luaentity_get(L, id);
4384 int object = lua_gettop(L);
4385 // State: object is at top of stack
4387 lua_getfield(L, -1, "on_rightclick");
4388 if(lua_isnil(L, -1))
4390 luaL_checktype(L, -1, LUA_TFUNCTION);
4391 lua_pushvalue(L, object); // self
4392 objectref_get_or_create(L, clicker); // Clicker reference
4393 // Call with 2 arguments, 0 results
4394 if(lua_pcall(L, 2, 0, 0))
4395 script_error(L, "error running function 'on_rightclick': %s\n", lua_tostring(L, -1));