3 Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "scriptapi.h"
34 #include "serverobject.h"
37 #include "luaentity_common.h"
38 #include "content_sao.h" // For LuaEntitySAO
42 #include "craftitemdef.h"
43 #include "main.h" // For g_settings
44 #include "settings.h" // For accessing g_settings
45 #include "nodemetadata.h"
46 #include "mapblock.h" // For getNodeBlockPos
47 #include "content_nodemeta.h"
50 static void stackDump(lua_State *L, std::ostream &o)
53 int top = lua_gettop(L);
54 for (i = 1; i <= top; i++) { /* repeat for each level */
55 int t = lua_type(L, i);
58 case LUA_TSTRING: /* strings */
59 o<<"\""<<lua_tostring(L, i)<<"\"";
62 case LUA_TBOOLEAN: /* booleans */
63 o<<(lua_toboolean(L, i) ? "true" : "false");
66 case LUA_TNUMBER: /* numbers */ {
68 snprintf(buf, 10, "%g", lua_tonumber(L, i));
72 default: /* other values */
73 o<<lua_typename(L, t);
82 static void realitycheck(lua_State *L)
84 int top = lua_gettop(L);
86 dstream<<"Stack is over 30:"<<std::endl;
87 stackDump(L, dstream);
88 script_error(L, "Stack is over 30 (reality check)");
98 StackUnroller(lua_State *L):
102 m_original_top = lua_gettop(m_lua); // store stack height
106 lua_settop(m_lua, m_original_top); // restore stack height
110 static v3f readFloatPos(lua_State *L, int index)
113 luaL_checktype(L, index, LUA_TTABLE);
114 lua_getfield(L, index, "x");
115 pos.X = lua_tonumber(L, -1);
117 lua_getfield(L, index, "y");
118 pos.Y = lua_tonumber(L, -1);
120 lua_getfield(L, index, "z");
121 pos.Z = lua_tonumber(L, -1);
123 pos *= BS; // Scale to internal format
127 static void pushFloatPos(lua_State *L, v3f p)
131 lua_pushnumber(L, p.X);
132 lua_setfield(L, -2, "x");
133 lua_pushnumber(L, p.Y);
134 lua_setfield(L, -2, "y");
135 lua_pushnumber(L, p.Z);
136 lua_setfield(L, -2, "z");
139 static void pushpos(lua_State *L, v3s16 p)
142 lua_pushnumber(L, p.X);
143 lua_setfield(L, -2, "x");
144 lua_pushnumber(L, p.Y);
145 lua_setfield(L, -2, "y");
146 lua_pushnumber(L, p.Z);
147 lua_setfield(L, -2, "z");
150 static v3s16 readpos(lua_State *L, int index)
152 // Correct rounding at <0
153 v3f pf = readFloatPos(L, index);
154 return floatToInt(pf, BS);
157 static void pushnode(lua_State *L, const MapNode &n, INodeDefManager *ndef)
160 lua_pushstring(L, ndef->get(n).name.c_str());
161 lua_setfield(L, -2, "name");
162 lua_pushnumber(L, n.getParam1());
163 lua_setfield(L, -2, "param1");
164 lua_pushnumber(L, n.getParam2());
165 lua_setfield(L, -2, "param2");
168 static MapNode readnode(lua_State *L, int index, INodeDefManager *ndef)
170 lua_getfield(L, index, "name");
171 const char *name = lua_tostring(L, -1);
174 lua_getfield(L, index, "param1");
178 param1 = lua_tonumber(L, -1);
181 lua_getfield(L, index, "param2");
185 param2 = lua_tonumber(L, -1);
187 return MapNode(ndef, name, param1, param2);
190 static video::SColor readARGB8(lua_State *L, int index)
193 luaL_checktype(L, index, LUA_TTABLE);
194 lua_getfield(L, index, "a");
195 if(lua_isnumber(L, -1))
196 color.setAlpha(lua_tonumber(L, -1));
198 lua_getfield(L, index, "r");
199 color.setRed(lua_tonumber(L, -1));
201 lua_getfield(L, index, "g");
202 color.setGreen(lua_tonumber(L, -1));
204 lua_getfield(L, index, "b");
205 color.setBlue(lua_tonumber(L, -1));
210 static core::aabbox3d<f32> read_aabbox3df32(lua_State *L, int index, f32 scale)
212 core::aabbox3d<f32> box;
213 if(lua_istable(L, -1)){
214 lua_rawgeti(L, -1, 1);
215 box.MinEdge.X = lua_tonumber(L, -1) * scale;
217 lua_rawgeti(L, -1, 2);
218 box.MinEdge.Y = lua_tonumber(L, -1) * scale;
220 lua_rawgeti(L, -1, 3);
221 box.MinEdge.Z = lua_tonumber(L, -1) * scale;
223 lua_rawgeti(L, -1, 4);
224 box.MaxEdge.X = lua_tonumber(L, -1) * scale;
226 lua_rawgeti(L, -1, 5);
227 box.MaxEdge.Y = lua_tonumber(L, -1) * scale;
229 lua_rawgeti(L, -1, 6);
230 box.MaxEdge.Z = lua_tonumber(L, -1) * scale;
236 static v2s16 read_v2s16(lua_State *L, int index)
239 luaL_checktype(L, index, LUA_TTABLE);
240 lua_getfield(L, index, "x");
241 p.X = lua_tonumber(L, -1);
243 lua_getfield(L, index, "y");
244 p.Y = lua_tonumber(L, -1);
249 static v2f read_v2f(lua_State *L, int index)
252 luaL_checktype(L, index, LUA_TTABLE);
253 lua_getfield(L, index, "x");
254 p.X = lua_tonumber(L, -1);
256 lua_getfield(L, index, "y");
257 p.Y = lua_tonumber(L, -1);
262 static bool getstringfield(lua_State *L, int table,
263 const char *fieldname, std::string &result)
265 lua_getfield(L, table, fieldname);
267 if(lua_isstring(L, -1)){
268 result = lua_tostring(L, -1);
275 static bool getintfield(lua_State *L, int table,
276 const char *fieldname, int &result)
278 lua_getfield(L, table, fieldname);
280 if(lua_isnumber(L, -1)){
281 result = lua_tonumber(L, -1);
288 static bool getfloatfield(lua_State *L, int table,
289 const char *fieldname, float &result)
291 lua_getfield(L, table, fieldname);
293 if(lua_isnumber(L, -1)){
294 result = lua_tonumber(L, -1);
301 static bool getboolfield(lua_State *L, int table,
302 const char *fieldname, bool &result)
304 lua_getfield(L, table, fieldname);
306 if(lua_isboolean(L, -1)){
307 result = lua_toboolean(L, -1);
314 static std::string getstringfield_default(lua_State *L, int table,
315 const char *fieldname, const std::string &default_)
317 std::string result = default_;
318 getstringfield(L, table, fieldname, result);
322 static int getintfield_default(lua_State *L, int table,
323 const char *fieldname, int default_)
325 int result = default_;
326 getintfield(L, table, fieldname, result);
330 /*static float getfloatfield_default(lua_State *L, int table,
331 const char *fieldname, float default_)
333 float result = default_;
334 getfloatfield(L, table, fieldname, result);
338 static bool getboolfield_default(lua_State *L, int table,
339 const char *fieldname, bool default_)
341 bool result = default_;
342 getboolfield(L, table, fieldname, result);
352 static bool string_to_enum(const EnumString *spec, int &result,
353 const std::string &str)
355 const EnumString *esp = spec;
357 if(str == std::string(esp->str)){
366 /*static bool enum_to_string(const EnumString *spec, std::string &result,
369 const EnumString *esp = spec;
380 static int getenumfield(lua_State *L, int table,
381 const char *fieldname, const EnumString *spec, int default_)
383 int result = default_;
384 string_to_enum(spec, result,
385 getstringfield_default(L, table, fieldname, ""));
389 struct EnumString es_DrawType[] =
391 {NDT_NORMAL, "normal"},
392 {NDT_AIRLIKE, "airlike"},
393 {NDT_LIQUID, "liquid"},
394 {NDT_FLOWINGLIQUID, "flowingliquid"},
395 {NDT_GLASSLIKE, "glasslike"},
396 {NDT_ALLFACES, "allfaces"},
397 {NDT_ALLFACES_OPTIONAL, "allfaces_optional"},
398 {NDT_TORCHLIKE, "torchlike"},
399 {NDT_SIGNLIKE, "signlike"},
400 {NDT_PLANTLIKE, "plantlike"},
401 {NDT_FENCELIKE, "fencelike"},
402 {NDT_RAILLIKE, "raillike"},
406 struct EnumString es_ContentParamType[] =
409 {CPT_LIGHT, "light"},
410 {CPT_MINERAL, "mineral"},
411 {CPT_FACEDIR_SIMPLE, "facedir_simple"},
415 struct EnumString es_LiquidType[] =
417 {LIQUID_NONE, "none"},
418 {LIQUID_FLOWING, "flowing"},
419 {LIQUID_SOURCE, "source"},
423 struct EnumString es_NodeBoxType[] =
425 {NODEBOX_REGULAR, "regular"},
426 {NODEBOX_FIXED, "fixed"},
427 {NODEBOX_WALLMOUNTED, "wallmounted"},
431 struct EnumString es_Diggability[] =
433 {DIGGABLE_NOT, "not"},
434 {DIGGABLE_NORMAL, "normal"},
435 {DIGGABLE_CONSTANT, "constant"},
443 static int l_register_nodedef_defaults(lua_State *L)
445 luaL_checktype(L, 1, LUA_TTABLE);
447 lua_pushvalue(L, 1); // Explicitly put parameter 1 on top of stack
448 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
453 // Register new object prototype
454 // register_entity(name, prototype)
455 static int l_register_entity(lua_State *L)
457 const char *name = luaL_checkstring(L, 1);
458 infostream<<"register_entity: "<<name<<std::endl;
459 luaL_checktype(L, 2, LUA_TTABLE);
461 // Get minetest.registered_entities
462 lua_getglobal(L, "minetest");
463 lua_getfield(L, -1, "registered_entities");
464 luaL_checktype(L, -1, LUA_TTABLE);
465 int registered_entities = lua_gettop(L);
466 lua_pushvalue(L, 2); // Object = param 2 -> stack top
467 // registered_entities[name] = object
468 lua_setfield(L, registered_entities, name);
470 // Get registered object to top of stack
473 // Set __index to point to itself
474 lua_pushvalue(L, -1);
475 lua_setfield(L, -2, "__index");
477 // Set metatable.__index = metatable
478 luaL_getmetatable(L, "minetest.entity");
479 lua_pushvalue(L, -1); // duplicate metatable
480 lua_setfield(L, -2, "__index");
481 // Set object metatable
482 lua_setmetatable(L, -2);
484 return 0; /* number of results */
487 class LuaABM : public ActiveBlockModifier
493 std::set<std::string> m_trigger_contents;
494 float m_trigger_interval;
495 u32 m_trigger_chance;
497 LuaABM(lua_State *L, int id,
498 const std::set<std::string> &trigger_contents,
499 float trigger_interval, u32 trigger_chance):
502 m_trigger_contents(trigger_contents),
503 m_trigger_interval(trigger_interval),
504 m_trigger_chance(trigger_chance)
507 virtual std::set<std::string> getTriggerContents()
509 return m_trigger_contents;
511 virtual float getTriggerInterval()
513 return m_trigger_interval;
515 virtual u32 getTriggerChance()
517 return m_trigger_chance;
519 virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n,
520 u32 active_object_count, u32 active_object_count_wider)
522 lua_State *L = m_lua;
525 assert(lua_checkstack(L, 20));
526 StackUnroller stack_unroller(L);
528 // Get minetest.registered_abms
529 lua_getglobal(L, "minetest");
530 lua_getfield(L, -1, "registered_abms");
531 luaL_checktype(L, -1, LUA_TTABLE);
532 int registered_abms = lua_gettop(L);
534 // Get minetest.registered_abms[m_id]
535 lua_pushnumber(L, m_id);
536 lua_gettable(L, registered_abms);
541 luaL_checktype(L, -1, LUA_TTABLE);
542 lua_getfield(L, -1, "action");
543 luaL_checktype(L, -1, LUA_TFUNCTION);
545 pushnode(L, n, env->getGameDef()->ndef());
546 lua_pushnumber(L, active_object_count);
547 lua_pushnumber(L, active_object_count_wider);
548 if(lua_pcall(L, 4, 0, 0))
549 script_error(L, "error: %s\n", lua_tostring(L, -1));
553 // register_abm({...})
554 static int l_register_abm(lua_State *L)
556 infostream<<"register_abm"<<std::endl;
557 luaL_checktype(L, 1, LUA_TTABLE);
559 // Get minetest.registered_abms
560 lua_getglobal(L, "minetest");
561 lua_getfield(L, -1, "registered_abms");
562 luaL_checktype(L, -1, LUA_TTABLE);
563 int registered_abms = lua_gettop(L);
568 lua_pushnumber(L, id);
569 lua_gettable(L, registered_abms);
577 infostream<<"register_abm: id="<<id<<std::endl;
579 // registered_abms[id] = spec
580 lua_pushnumber(L, id);
582 lua_settable(L, registered_abms);
584 return 0; /* number of results */
587 // register_tool(name, {lots of stuff})
588 static int l_register_tool(lua_State *L)
590 const char *name = luaL_checkstring(L, 1);
591 infostream<<"register_tool: "<<name<<std::endl;
592 luaL_checktype(L, 2, LUA_TTABLE);
595 // Get server from registry
596 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
597 Server *server = (Server*)lua_touserdata(L, -1);
598 // And get the writable tool definition manager from the server
599 IWritableToolDefManager *tooldef =
600 server->getWritableToolDefManager();
604 getstringfield(L, table, "image", def.imagename);
605 getfloatfield(L, table, "basetime", def.properties.basetime);
606 getfloatfield(L, table, "dt_weight", def.properties.dt_weight);
607 getfloatfield(L, table, "dt_crackiness", def.properties.dt_crackiness);
608 getfloatfield(L, table, "dt_crumbliness", def.properties.dt_crumbliness);
609 getfloatfield(L, table, "dt_cuttability", def.properties.dt_cuttability);
610 getfloatfield(L, table, "basedurability", def.properties.basedurability);
611 getfloatfield(L, table, "dd_weight", def.properties.dd_weight);
612 getfloatfield(L, table, "dd_crackiness", def.properties.dd_crackiness);
613 getfloatfield(L, table, "dd_crumbliness", def.properties.dd_crumbliness);
614 getfloatfield(L, table, "dd_cuttability", def.properties.dd_cuttability);
616 tooldef->registerTool(name, def);
617 return 0; /* number of results */
620 // register_craftitem(name, {lots of stuff})
621 static int l_register_craftitem(lua_State *L)
623 const char *name = luaL_checkstring(L, 1);
624 infostream<<"register_craftitem: "<<name<<std::endl;
625 luaL_checktype(L, 2, LUA_TTABLE);
628 // Get server from registry
629 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
630 Server *server = (Server*)lua_touserdata(L, -1);
631 // And get the writable CraftItem definition manager from the server
632 IWritableCraftItemDefManager *craftitemdef =
633 server->getWritableCraftItemDefManager();
635 // Check if on_drop is defined
636 lua_getfield(L, table, "on_drop");
637 bool got_on_drop = !lua_isnil(L, -1);
640 // Check if on_use is defined
641 lua_getfield(L, table, "on_use");
642 bool got_on_use = !lua_isnil(L, -1);
645 CraftItemDefinition def;
647 getstringfield(L, table, "image", def.imagename);
648 getstringfield(L, table, "cookresult_item", def.cookresult_item);
649 getfloatfield(L, table, "furnace_cooktime", def.furnace_cooktime);
650 getfloatfield(L, table, "furnace_burntime", def.furnace_burntime);
651 def.usable = getboolfield_default(L, table, "usable", got_on_use);
652 getboolfield(L, table, "liquids_pointable", def.liquids_pointable);
653 def.dropcount = getintfield_default(L, table, "dropcount", def.dropcount);
654 def.stack_max = getintfield_default(L, table, "stack_max", def.stack_max);
656 // If an on_drop callback is defined, force dropcount to 1
661 craftitemdef->registerCraftItem(name, def);
663 lua_pushvalue(L, table);
664 scriptapi_add_craftitem(L, name);
666 return 0; /* number of results */
669 // register_node(name, {lots of stuff})
670 static int l_register_node(lua_State *L)
672 const char *name = luaL_checkstring(L, 1);
673 infostream<<"register_node: "<<name<<std::endl;
674 luaL_checktype(L, 2, LUA_TTABLE);
675 int nodedef_table = 2;
677 // Get server from registry
678 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
679 Server *server = (Server*)lua_touserdata(L, -1);
680 // And get the writable node definition manager from the server
681 IWritableNodeDefManager *nodedef =
682 server->getWritableNodeDefManager();
684 // Get default node definition from registry
685 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
686 int nodedef_default = lua_gettop(L);
689 Add to minetest.registered_nodes with default as metatable
692 // Get the node definition table given as parameter
693 lua_pushvalue(L, nodedef_table);
695 // Set __index to point to itself
696 lua_pushvalue(L, -1);
697 lua_setfield(L, -2, "__index");
699 // Set nodedef_default as metatable for the definition
700 lua_pushvalue(L, nodedef_default);
701 lua_setmetatable(L, nodedef_table);
703 // minetest.registered_nodes[name] = nodedef
704 lua_getglobal(L, "minetest");
705 lua_getfield(L, -1, "registered_nodes");
706 luaL_checktype(L, -1, LUA_TTABLE);
707 lua_pushstring(L, name);
708 lua_pushvalue(L, nodedef_table);
717 // Default to getting the corresponding NodeItem when dug
718 f.dug_item = std::string("NodeItem \"")+name+"\" 1";
720 // Default to unknown_block.png as all textures
721 f.setAllTextures("unknown_block.png");
724 Read definiton from Lua
729 /* Visual definition */
731 f.drawtype = (NodeDrawType)getenumfield(L, nodedef_table, "drawtype", es_DrawType,
733 getfloatfield(L, nodedef_table, "visual_scale", f.visual_scale);
735 lua_getfield(L, nodedef_table, "tile_images");
736 if(lua_istable(L, -1)){
737 int table = lua_gettop(L);
740 while(lua_next(L, table) != 0){
741 // key at index -2 and value at index -1
742 if(lua_isstring(L, -1))
743 f.tname_tiles[i] = lua_tostring(L, -1);
745 f.tname_tiles[i] = "";
746 // removes value, keeps key for next iteration
754 // Copy last value to all remaining textures
756 std::string lastname = f.tname_tiles[i-1];
758 f.tname_tiles[i] = lastname;
765 getstringfield(L, nodedef_table, "inventory_image", f.tname_inventory);
767 lua_getfield(L, nodedef_table, "special_materials");
768 if(lua_istable(L, -1)){
769 int table = lua_gettop(L);
772 while(lua_next(L, table) != 0){
773 // key at index -2 and value at index -1
774 int smtable = lua_gettop(L);
775 std::string tname = getstringfield_default(
776 L, smtable, "image", "");
777 bool backface_culling = getboolfield_default(
778 L, smtable, "backface_culling", true);
779 MaterialSpec mspec(tname, backface_culling);
780 f.setSpecialMaterial(i, mspec);
781 // removes value, keeps key for next iteration
792 f.alpha = getintfield_default(L, nodedef_table, "alpha", 255);
796 lua_getfield(L, nodedef_table, "post_effect_color");
797 if(!lua_isnil(L, -1))
798 f.post_effect_color = readARGB8(L, -1);
801 f.param_type = (ContentParamType)getenumfield(L, nodedef_table, "paramtype",
802 es_ContentParamType, CPT_NONE);
804 // True for all ground-like things like stone and mud, false for eg. trees
805 getboolfield(L, nodedef_table, "is_ground_content", f.is_ground_content);
806 getboolfield(L, nodedef_table, "light_propagates", f.light_propagates);
807 getboolfield(L, nodedef_table, "sunlight_propagates", f.sunlight_propagates);
808 // This is used for collision detection.
809 // Also for general solidness queries.
810 getboolfield(L, nodedef_table, "walkable", f.walkable);
811 // Player can point to these
812 getboolfield(L, nodedef_table, "pointable", f.pointable);
813 // Player can dig these
814 getboolfield(L, nodedef_table, "diggable", f.diggable);
815 // Player can climb these
816 getboolfield(L, nodedef_table, "climbable", f.climbable);
817 // Player can build on these
818 getboolfield(L, nodedef_table, "buildable_to", f.buildable_to);
819 // If true, param2 is set to direction when placed. Used for torches.
820 // NOTE: the direction format is quite inefficient and should be changed
821 getboolfield(L, nodedef_table, "wall_mounted", f.wall_mounted);
822 // Whether this content type often contains mineral.
823 // Used for texture atlas creation.
824 // Currently only enabled for CONTENT_STONE.
825 getboolfield(L, nodedef_table, "often_contains_mineral", f.often_contains_mineral);
826 // Inventory item string as which the node appears in inventory when dug.
827 // Mineral overrides this.
828 getstringfield(L, nodedef_table, "dug_item", f.dug_item);
829 // Extra dug item and its rarity
830 getstringfield(L, nodedef_table, "extra_dug_item", f.extra_dug_item);
831 // Usual get interval for extra dug item
832 getintfield(L, nodedef_table, "extra_dug_item_rarity", f.extra_dug_item_rarity);
833 // Metadata name of node (eg. "furnace")
834 getstringfield(L, nodedef_table, "metadata_name", f.metadata_name);
835 // Whether the node is non-liquid, source liquid or flowing liquid
836 f.liquid_type = (LiquidType)getenumfield(L, nodedef_table, "liquidtype",
837 es_LiquidType, LIQUID_NONE);
838 // If the content is liquid, this is the flowing version of the liquid.
839 getstringfield(L, nodedef_table, "liquid_alternative_flowing",
840 f.liquid_alternative_flowing);
841 // If the content is liquid, this is the source version of the liquid.
842 getstringfield(L, nodedef_table, "liquid_alternative_source",
843 f.liquid_alternative_source);
844 // Viscosity for fluid flow, ranging from 1 to 7, with
845 // 1 giving almost instantaneous propagation and 7 being
846 // the slowest possible
847 f.liquid_viscosity = getintfield_default(L, nodedef_table,
848 "liquid_viscosity", f.liquid_viscosity);
849 // Amount of light the node emits
850 f.light_source = getintfield_default(L, nodedef_table,
851 "light_source", f.light_source);
852 f.damage_per_second = getintfield_default(L, nodedef_table,
853 "damage_per_second", f.damage_per_second);
855 lua_getfield(L, nodedef_table, "selection_box");
856 if(lua_istable(L, -1)){
857 f.selection_box.type = (NodeBoxType)getenumfield(L, -1, "type",
858 es_NodeBoxType, NODEBOX_REGULAR);
860 lua_getfield(L, -1, "fixed");
861 if(lua_istable(L, -1))
862 f.selection_box.fixed = read_aabbox3df32(L, -1, BS);
865 lua_getfield(L, -1, "wall_top");
866 if(lua_istable(L, -1))
867 f.selection_box.wall_top = read_aabbox3df32(L, -1, BS);
870 lua_getfield(L, -1, "wall_bottom");
871 if(lua_istable(L, -1))
872 f.selection_box.wall_bottom = read_aabbox3df32(L, -1, BS);
875 lua_getfield(L, -1, "wall_side");
876 if(lua_istable(L, -1))
877 f.selection_box.wall_side = read_aabbox3df32(L, -1, BS);
882 lua_getfield(L, nodedef_table, "material");
883 if(lua_istable(L, -1)){
884 f.material.diggability = (Diggability)getenumfield(L, -1, "diggability",
885 es_Diggability, DIGGABLE_NORMAL);
887 getfloatfield(L, -1, "constant_time", f.material.constant_time);
888 getfloatfield(L, -1, "weight", f.material.weight);
889 getfloatfield(L, -1, "crackiness", f.material.crackiness);
890 getfloatfield(L, -1, "crumbliness", f.material.crumbliness);
891 getfloatfield(L, -1, "cuttability", f.material.cuttability);
892 getfloatfield(L, -1, "flammability", f.material.flammability);
896 getstringfield(L, nodedef_table, "cookresult_item", f.cookresult_item);
897 getfloatfield(L, nodedef_table, "furnace_cooktime", f.furnace_cooktime);
898 getfloatfield(L, nodedef_table, "furnace_burntime", f.furnace_burntime);
904 nodedef->set(name, f);
906 return 0; /* number of results */
909 // register_craft({output=item, recipe={{item00,item10},{item01,item11}})
910 static int l_register_craft(lua_State *L)
912 infostream<<"register_craft"<<std::endl;
913 luaL_checktype(L, 1, LUA_TTABLE);
916 // Get server from registry
917 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
918 Server *server = (Server*)lua_touserdata(L, -1);
919 // And get the writable craft definition manager from the server
920 IWritableCraftDefManager *craftdef =
921 server->getWritableCraftDefManager();
925 std::vector<std::string> input;
927 lua_getfield(L, table0, "output");
928 luaL_checktype(L, -1, LUA_TSTRING);
929 if(lua_isstring(L, -1))
930 output = lua_tostring(L, -1);
933 lua_getfield(L, table0, "recipe");
934 luaL_checktype(L, -1, LUA_TTABLE);
935 if(lua_istable(L, -1)){
936 int table1 = lua_gettop(L);
939 while(lua_next(L, table1) != 0){
941 // key at index -2 and value at index -1
942 luaL_checktype(L, -1, LUA_TTABLE);
943 if(lua_istable(L, -1)){
944 int table2 = lua_gettop(L);
946 while(lua_next(L, table2) != 0){
947 // key at index -2 and value at index -1
948 luaL_checktype(L, -1, LUA_TSTRING);
949 input.push_back(lua_tostring(L, -1));
950 // removes value, keeps key for next iteration
958 if(colcount != width){
959 script_error(L, "error: %s\n", "Invalid crafting recipe");
962 // removes value, keeps key for next iteration
969 CraftDefinition def(output, width, input);
970 craftdef->registerCraft(def);
972 return 0; /* number of results */
976 static int l_setting_get(lua_State *L)
978 const char *name = luaL_checkstring(L, 1);
980 std::string value = g_settings->get(name);
981 lua_pushstring(L, value.c_str());
982 } catch(SettingNotFoundException &e){
988 // setting_getbool(name)
989 static int l_setting_getbool(lua_State *L)
991 const char *name = luaL_checkstring(L, 1);
993 bool value = g_settings->getBool(name);
994 lua_pushboolean(L, value);
995 } catch(SettingNotFoundException &e){
1001 // chat_send_all(text)
1002 static int l_chat_send_all(lua_State *L)
1004 const char *text = luaL_checkstring(L, 1);
1005 // Get server from registry
1006 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1007 Server *server = (Server*)lua_touserdata(L, -1);
1009 server->notifyPlayers(narrow_to_wide(text));
1013 // chat_send_player(name, text)
1014 static int l_chat_send_player(lua_State *L)
1016 const char *name = luaL_checkstring(L, 1);
1017 const char *text = luaL_checkstring(L, 2);
1018 // Get server from registry
1019 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1020 Server *server = (Server*)lua_touserdata(L, -1);
1022 server->notifyPlayer(name, narrow_to_wide(text));
1026 // get_player_privs(name, text)
1027 static int l_get_player_privs(lua_State *L)
1029 const char *name = luaL_checkstring(L, 1);
1030 // Get server from registry
1031 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1032 Server *server = (Server*)lua_touserdata(L, -1);
1035 int table = lua_gettop(L);
1036 u64 privs_i = server->getPlayerAuthPrivs(name);
1037 // Special case for the "name" setting (local player / server owner)
1038 if(name == g_settings->get("name"))
1040 std::set<std::string> privs_s = privsToSet(privs_i);
1041 for(std::set<std::string>::const_iterator
1042 i = privs_s.begin(); i != privs_s.end(); i++){
1043 lua_pushboolean(L, true);
1044 lua_setfield(L, table, i->c_str());
1046 lua_pushvalue(L, table);
1050 static const struct luaL_Reg minetest_f [] = {
1051 {"register_nodedef_defaults", l_register_nodedef_defaults},
1052 {"register_entity", l_register_entity},
1053 {"register_tool", l_register_tool},
1054 {"register_craftitem", l_register_craftitem},
1055 {"register_node", l_register_node},
1056 {"register_craft", l_register_craft},
1057 {"register_abm", l_register_abm},
1058 {"setting_get", l_setting_get},
1059 {"setting_getbool", l_setting_getbool},
1060 {"chat_send_all", l_chat_send_all},
1061 {"chat_send_player", l_chat_send_player},
1062 {"get_player_privs", l_get_player_privs},
1070 static const struct luaL_Reg minetest_entity_m [] = {
1075 Getters for stuff in main tables
1078 static void objectref_get(lua_State *L, u16 id)
1080 // Get minetest.object_refs[i]
1081 lua_getglobal(L, "minetest");
1082 lua_getfield(L, -1, "object_refs");
1083 luaL_checktype(L, -1, LUA_TTABLE);
1084 lua_pushnumber(L, id);
1085 lua_gettable(L, -2);
1086 lua_remove(L, -2); // object_refs
1087 lua_remove(L, -2); // minetest
1090 static void luaentity_get(lua_State *L, u16 id)
1092 // Get minetest.luaentities[i]
1093 lua_getglobal(L, "minetest");
1094 lua_getfield(L, -1, "luaentities");
1095 luaL_checktype(L, -1, LUA_TTABLE);
1096 lua_pushnumber(L, id);
1097 lua_gettable(L, -2);
1098 lua_remove(L, -2); // luaentities
1099 lua_remove(L, -2); // minetest
1106 #define method(class, name) {#name, class::l_##name}
1116 ServerEnvironment *m_env;
1118 static const char className[];
1119 static const luaL_reg methods[];
1121 static NodeMetaRef *checkobject(lua_State *L, int narg)
1123 luaL_checktype(L, narg, LUA_TUSERDATA);
1124 void *ud = luaL_checkudata(L, narg, className);
1125 if(!ud) luaL_typerror(L, narg, className);
1126 return *(NodeMetaRef**)ud; // unbox pointer
1129 static NodeMetadata* getmeta(NodeMetaRef *ref)
1131 NodeMetadata *meta = ref->m_env->getMap().getNodeMetadata(ref->m_p);
1135 /*static IGenericNodeMetadata* getgenericmeta(NodeMetaRef *ref)
1137 NodeMetadata *meta = getmeta(ref);
1140 if(meta->typeId() != NODEMETA_GENERIC)
1142 return (IGenericNodeMetadata*)meta;
1145 static void reportMetadataChange(NodeMetaRef *ref)
1147 // Inform other things that the metadata has changed
1148 v3s16 blockpos = getNodeBlockPos(ref->m_p);
1150 event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
1152 ref->m_env->getMap().dispatchEvent(&event);
1153 // Set the block to be saved
1154 MapBlock *block = ref->m_env->getMap().getBlockNoCreateNoEx(blockpos);
1156 block->raiseModified(MOD_STATE_WRITE_NEEDED,
1157 "NodeMetaRef::reportMetadataChange");
1160 // Exported functions
1162 // garbage collector
1163 static int gc_object(lua_State *L) {
1164 NodeMetaRef *o = *(NodeMetaRef **)(lua_touserdata(L, 1));
1170 static int l_get_type(lua_State *L)
1172 NodeMetaRef *ref = checkobject(L, 1);
1173 NodeMetadata *meta = getmeta(ref);
1179 lua_pushstring(L, meta->typeName());
1183 // allows_text_input(self)
1184 static int l_allows_text_input(lua_State *L)
1186 NodeMetaRef *ref = checkobject(L, 1);
1187 NodeMetadata *meta = getmeta(ref);
1188 if(meta == NULL) return 0;
1190 lua_pushboolean(L, meta->allowsTextInput());
1194 // set_text(self, text)
1195 static int l_set_text(lua_State *L)
1197 NodeMetaRef *ref = checkobject(L, 1);
1198 NodeMetadata *meta = getmeta(ref);
1199 if(meta == NULL) return 0;
1201 std::string text = lua_tostring(L, 2);
1202 meta->setText(text);
1203 reportMetadataChange(ref);
1208 static int l_get_text(lua_State *L)
1210 NodeMetaRef *ref = checkobject(L, 1);
1211 NodeMetadata *meta = getmeta(ref);
1212 if(meta == NULL) return 0;
1214 std::string text = meta->getText();
1215 lua_pushstring(L, text.c_str());
1220 static int l_get_owner(lua_State *L)
1222 NodeMetaRef *ref = checkobject(L, 1);
1223 NodeMetadata *meta = getmeta(ref);
1224 if(meta == NULL) return 0;
1226 std::string owner = meta->getOwner();
1227 lua_pushstring(L, owner.c_str());
1231 /* IGenericNodeMetadata interface */
1233 // set_infotext(self, text)
1234 static int l_set_infotext(lua_State *L)
1236 infostream<<__FUNCTION_NAME<<std::endl;
1237 NodeMetaRef *ref = checkobject(L, 1);
1238 NodeMetadata *meta = getmeta(ref);
1239 if(meta == NULL) return 0;
1241 std::string text = lua_tostring(L, 2);
1242 meta->setInfoText(text);
1243 reportMetadataChange(ref);
1247 // inventory_set_list(self, name, {item1, item2, ...})
1248 static int l_inventory_set_list(lua_State *L)
1250 NodeMetaRef *ref = checkobject(L, 1);
1251 NodeMetadata *meta = getmeta(ref);
1252 if(meta == NULL) return 0;
1254 Inventory *inv = meta->getInventory();
1255 std::string name = lua_tostring(L, 2);
1256 // If nil, delete list
1257 if(lua_isnil(L, 3)){
1258 inv->deleteList(name);
1261 // Otherwise set list
1262 std::list<std::string> items;
1263 luaL_checktype(L, 3, LUA_TTABLE);
1266 infostream<<"items: ";
1267 while(lua_next(L, table) != 0){
1268 // key at index -2 and value at index -1
1269 luaL_checktype(L, -1, LUA_TSTRING);
1270 std::string itemstring = lua_tostring(L, -1);
1271 infostream<<"\""<<itemstring<<"\" ";
1272 items.push_back(itemstring);
1273 // removes value, keeps key for next iteration
1276 infostream<<std::endl;
1277 InventoryList *invlist = inv->addList(name, items.size());
1279 for(std::list<std::string>::const_iterator
1280 i = items.begin(); i != items.end(); i++){
1281 const std::string &itemstring = *i;
1282 InventoryItem *newitem = NULL;
1283 if(itemstring != "")
1284 newitem = InventoryItem::deSerialize(itemstring,
1285 ref->m_env->getGameDef());
1286 InventoryItem *olditem = invlist->changeItem(index, newitem);
1290 reportMetadataChange(ref);
1294 // inventory_get_list(self, name)
1295 static int l_inventory_get_list(lua_State *L)
1297 NodeMetaRef *ref = checkobject(L, 1);
1298 NodeMetadata *meta = getmeta(ref);
1299 if(meta == NULL) return 0;
1301 Inventory *inv = meta->getInventory();
1302 std::string name = lua_tostring(L, 2);
1303 InventoryList *invlist = inv->getList(name);
1304 if(invlist == NULL){
1308 // Get the table insert function
1309 lua_getglobal(L, "table");
1310 lua_getfield(L, -1, "insert");
1311 int table_insert = lua_gettop(L);
1312 // Create and fill table
1314 int table = lua_gettop(L);
1315 for(u32 i=0; i<invlist->getSize(); i++){
1316 InventoryItem *item = invlist->getItem(i);
1317 lua_pushvalue(L, table_insert);
1318 lua_pushvalue(L, table);
1322 lua_pushstring(L, item->getItemString().c_str());
1324 if(lua_pcall(L, 2, 0, 0))
1325 script_error(L, "error: %s\n", lua_tostring(L, -1));
1330 // set_inventory_draw_spec(self, text)
1331 static int l_set_inventory_draw_spec(lua_State *L)
1333 NodeMetaRef *ref = checkobject(L, 1);
1334 NodeMetadata *meta = getmeta(ref);
1335 if(meta == NULL) return 0;
1337 std::string text = lua_tostring(L, 2);
1338 meta->setInventoryDrawSpec(text);
1339 reportMetadataChange(ref);
1343 // set_allow_text_input(self, text)
1344 static int l_set_allow_text_input(lua_State *L)
1346 NodeMetaRef *ref = checkobject(L, 1);
1347 NodeMetadata *meta = getmeta(ref);
1348 if(meta == NULL) return 0;
1350 bool b = lua_toboolean(L, 2);
1351 meta->setAllowTextInput(b);
1352 reportMetadataChange(ref);
1356 // set_allow_removal(self, text)
1357 static int l_set_allow_removal(lua_State *L)
1359 NodeMetaRef *ref = checkobject(L, 1);
1360 NodeMetadata *meta = getmeta(ref);
1361 if(meta == NULL) return 0;
1363 bool b = lua_toboolean(L, 2);
1364 meta->setRemovalDisabled(!b);
1365 reportMetadataChange(ref);
1369 // set_enforce_owner(self, text)
1370 static int l_set_enforce_owner(lua_State *L)
1372 NodeMetaRef *ref = checkobject(L, 1);
1373 NodeMetadata *meta = getmeta(ref);
1374 if(meta == NULL) return 0;
1376 bool b = lua_toboolean(L, 2);
1377 meta->setEnforceOwner(b);
1378 reportMetadataChange(ref);
1382 // is_inventory_modified(self)
1383 static int l_is_inventory_modified(lua_State *L)
1385 NodeMetaRef *ref = checkobject(L, 1);
1386 NodeMetadata *meta = getmeta(ref);
1387 if(meta == NULL) return 0;
1389 lua_pushboolean(L, meta->isInventoryModified());
1393 // reset_inventory_modified(self)
1394 static int l_reset_inventory_modified(lua_State *L)
1396 NodeMetaRef *ref = checkobject(L, 1);
1397 NodeMetadata *meta = getmeta(ref);
1398 if(meta == NULL) return 0;
1400 meta->resetInventoryModified();
1401 reportMetadataChange(ref);
1405 // is_text_modified(self)
1406 static int l_is_text_modified(lua_State *L)
1408 NodeMetaRef *ref = checkobject(L, 1);
1409 NodeMetadata *meta = getmeta(ref);
1410 if(meta == NULL) return 0;
1412 lua_pushboolean(L, meta->isTextModified());
1416 // reset_text_modified(self)
1417 static int l_reset_text_modified(lua_State *L)
1419 NodeMetaRef *ref = checkobject(L, 1);
1420 NodeMetadata *meta = getmeta(ref);
1421 if(meta == NULL) return 0;
1423 meta->resetTextModified();
1424 reportMetadataChange(ref);
1428 // set_string(self, name, var)
1429 static int l_set_string(lua_State *L)
1431 NodeMetaRef *ref = checkobject(L, 1);
1432 NodeMetadata *meta = getmeta(ref);
1433 if(meta == NULL) return 0;
1435 std::string name = lua_tostring(L, 2);
1437 const char *s = lua_tolstring(L, 3, &len);
1438 std::string str(s, len);
1439 meta->setString(name, str);
1440 reportMetadataChange(ref);
1444 // get_string(self, name)
1445 static int l_get_string(lua_State *L)
1447 NodeMetaRef *ref = checkobject(L, 1);
1448 NodeMetadata *meta = getmeta(ref);
1449 if(meta == NULL) return 0;
1451 std::string name = lua_tostring(L, 2);
1452 std::string str = meta->getString(name);
1453 lua_pushlstring(L, str.c_str(), str.size());
1458 NodeMetaRef(v3s16 p, ServerEnvironment *env):
1468 // Creates an NodeMetaRef and leaves it on top of stack
1469 // Not callable from Lua; all references are created on the C side.
1470 static void create(lua_State *L, v3s16 p, ServerEnvironment *env)
1472 NodeMetaRef *o = new NodeMetaRef(p, env);
1473 //infostream<<"NodeMetaRef::create: o="<<o<<std::endl;
1474 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1475 luaL_getmetatable(L, className);
1476 lua_setmetatable(L, -2);
1479 static void Register(lua_State *L)
1482 int methodtable = lua_gettop(L);
1483 luaL_newmetatable(L, className);
1484 int metatable = lua_gettop(L);
1486 lua_pushliteral(L, "__metatable");
1487 lua_pushvalue(L, methodtable);
1488 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
1490 lua_pushliteral(L, "__index");
1491 lua_pushvalue(L, methodtable);
1492 lua_settable(L, metatable);
1494 lua_pushliteral(L, "__gc");
1495 lua_pushcfunction(L, gc_object);
1496 lua_settable(L, metatable);
1498 lua_pop(L, 1); // drop metatable
1500 luaL_openlib(L, 0, methods, 0); // fill methodtable
1501 lua_pop(L, 1); // drop methodtable
1503 // Cannot be created from Lua
1504 //lua_register(L, className, create_object);
1507 const char NodeMetaRef::className[] = "NodeMetaRef";
1508 const luaL_reg NodeMetaRef::methods[] = {
1509 method(NodeMetaRef, get_type),
1510 method(NodeMetaRef, allows_text_input),
1511 method(NodeMetaRef, set_text),
1512 method(NodeMetaRef, get_text),
1513 method(NodeMetaRef, get_owner),
1514 method(NodeMetaRef, set_infotext),
1515 method(NodeMetaRef, inventory_set_list),
1516 method(NodeMetaRef, inventory_get_list),
1517 method(NodeMetaRef, set_inventory_draw_spec),
1518 method(NodeMetaRef, set_allow_text_input),
1519 method(NodeMetaRef, set_allow_removal),
1520 method(NodeMetaRef, set_enforce_owner),
1521 method(NodeMetaRef, is_inventory_modified),
1522 method(NodeMetaRef, reset_inventory_modified),
1523 method(NodeMetaRef, is_text_modified),
1524 method(NodeMetaRef, reset_text_modified),
1525 method(NodeMetaRef, set_string),
1526 method(NodeMetaRef, get_string),
1537 ServerActiveObject *m_object;
1539 static const char className[];
1540 static const luaL_reg methods[];
1542 static ObjectRef *checkobject(lua_State *L, int narg)
1544 luaL_checktype(L, narg, LUA_TUSERDATA);
1545 void *ud = luaL_checkudata(L, narg, className);
1546 if(!ud) luaL_typerror(L, narg, className);
1547 return *(ObjectRef**)ud; // unbox pointer
1550 static ServerActiveObject* getobject(ObjectRef *ref)
1552 ServerActiveObject *co = ref->m_object;
1556 static LuaEntitySAO* getluaobject(ObjectRef *ref)
1558 ServerActiveObject *obj = getobject(ref);
1561 if(obj->getType() != ACTIVEOBJECT_TYPE_LUAENTITY)
1563 return (LuaEntitySAO*)obj;
1566 static ServerRemotePlayer* getplayer(ObjectRef *ref)
1568 ServerActiveObject *obj = getobject(ref);
1571 if(obj->getType() != ACTIVEOBJECT_TYPE_PLAYER)
1573 return static_cast<ServerRemotePlayer*>(obj);
1576 // Exported functions
1578 // garbage collector
1579 static int gc_object(lua_State *L) {
1580 ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
1581 //infostream<<"ObjectRef::gc_object: o="<<o<<std::endl;
1587 static int l_remove(lua_State *L)
1589 ObjectRef *ref = checkobject(L, 1);
1590 ServerActiveObject *co = getobject(ref);
1591 if(co == NULL) return 0;
1592 infostream<<"ObjectRef::l_remove(): id="<<co->getId()<<std::endl;
1593 co->m_removed = true;
1598 // returns: {x=num, y=num, z=num}
1599 static int l_getpos(lua_State *L)
1601 ObjectRef *ref = checkobject(L, 1);
1602 ServerActiveObject *co = getobject(ref);
1603 if(co == NULL) return 0;
1604 v3f pos = co->getBasePosition() / BS;
1606 lua_pushnumber(L, pos.X);
1607 lua_setfield(L, -2, "x");
1608 lua_pushnumber(L, pos.Y);
1609 lua_setfield(L, -2, "y");
1610 lua_pushnumber(L, pos.Z);
1611 lua_setfield(L, -2, "z");
1615 // setpos(self, pos)
1616 static int l_setpos(lua_State *L)
1618 ObjectRef *ref = checkobject(L, 1);
1619 //LuaEntitySAO *co = getluaobject(ref);
1620 ServerActiveObject *co = getobject(ref);
1621 if(co == NULL) return 0;
1623 v3f pos = readFloatPos(L, 2);
1629 // moveto(self, pos, continuous=false)
1630 static int l_moveto(lua_State *L)
1632 ObjectRef *ref = checkobject(L, 1);
1633 //LuaEntitySAO *co = getluaobject(ref);
1634 ServerActiveObject *co = getobject(ref);
1635 if(co == NULL) return 0;
1637 v3f pos = readFloatPos(L, 2);
1639 bool continuous = lua_toboolean(L, 3);
1641 co->moveTo(pos, continuous);
1645 // setvelocity(self, velocity)
1646 static int l_setvelocity(lua_State *L)
1648 ObjectRef *ref = checkobject(L, 1);
1649 LuaEntitySAO *co = getluaobject(ref);
1650 if(co == NULL) return 0;
1652 v3f pos = readFloatPos(L, 2);
1654 co->setVelocity(pos);
1658 // setacceleration(self, acceleration)
1659 static int l_setacceleration(lua_State *L)
1661 ObjectRef *ref = checkobject(L, 1);
1662 LuaEntitySAO *co = getluaobject(ref);
1663 if(co == NULL) return 0;
1665 v3f pos = readFloatPos(L, 2);
1667 co->setAcceleration(pos);
1671 // getacceleration(self)
1672 static int l_getacceleration(lua_State *L)
1674 ObjectRef *ref = checkobject(L, 1);
1675 LuaEntitySAO *co = getluaobject(ref);
1676 if(co == NULL) return 0;
1678 v3f v = co->getAcceleration();
1683 // add_to_inventory(self, itemstring)
1684 // returns: true if item was added, (false, "reason") otherwise
1685 static int l_add_to_inventory(lua_State *L)
1687 ObjectRef *ref = checkobject(L, 1);
1688 luaL_checkstring(L, 2);
1689 ServerActiveObject *co = getobject(ref);
1690 if(co == NULL) return 0;
1692 const char *itemstring = lua_tostring(L, 2);
1693 infostream<<"ObjectRef::l_add_to_inventory(): id="<<co->getId()
1694 <<" itemstring=\""<<itemstring<<"\""<<std::endl;
1696 std::istringstream is(itemstring, std::ios::binary);
1697 ServerEnvironment *env = co->getEnv();
1699 IGameDef *gamedef = env->getGameDef();
1701 InventoryItem *item = InventoryItem::deSerialize(is, gamedef);
1702 if(item->getCount() == 0)
1704 bool added = co->addToInventory(item);
1706 lua_pushboolean(L, added);
1708 lua_pushstring(L, "does not fit");
1710 } catch(SerializationError &e){
1712 lua_pushboolean(L, false);
1713 lua_pushstring(L, (std::string("Invalid item: ")
1714 + e.what()).c_str());
1719 // add_to_inventory_later(self, itemstring)
1721 static int l_add_to_inventory_later(lua_State *L)
1723 ObjectRef *ref = checkobject(L, 1);
1724 luaL_checkstring(L, 2);
1725 ServerActiveObject *co = getobject(ref);
1726 if(co == NULL) return 0;
1728 const char *itemstring = lua_tostring(L, 2);
1729 infostream<<"ObjectRef::l_add_to_inventory_later(): id="<<co->getId()
1730 <<" itemstring=\""<<itemstring<<"\""<<std::endl;
1732 std::istringstream is(itemstring, std::ios::binary);
1733 ServerEnvironment *env = co->getEnv();
1735 IGameDef *gamedef = env->getGameDef();
1736 InventoryItem *item = InventoryItem::deSerialize(is, gamedef);
1737 infostream<<"item="<<env<<std::endl;
1738 co->addToInventoryLater(item);
1744 // returns: number of hitpoints (2 * number of hearts)
1745 // 0 if not applicable to this type of object
1746 static int l_get_hp(lua_State *L)
1748 ObjectRef *ref = checkobject(L, 1);
1749 ServerActiveObject *co = getobject(ref);
1750 if(co == NULL) return 0;
1751 int hp = co->getHP();
1752 infostream<<"ObjectRef::l_get_hp(): id="<<co->getId()
1753 <<" hp="<<hp<<std::endl;
1755 lua_pushnumber(L, hp);
1760 // hp = number of hitpoints (2 * number of hearts)
1762 static int l_set_hp(lua_State *L)
1764 ObjectRef *ref = checkobject(L, 1);
1765 luaL_checknumber(L, 2);
1766 ServerActiveObject *co = getobject(ref);
1767 if(co == NULL) return 0;
1768 int hp = lua_tonumber(L, 2);
1769 infostream<<"ObjectRef::l_set_hp(): id="<<co->getId()
1770 <<" hp="<<hp<<std::endl;
1777 // settexturemod(self, mod)
1778 static int l_settexturemod(lua_State *L)
1780 ObjectRef *ref = checkobject(L, 1);
1781 LuaEntitySAO *co = getluaobject(ref);
1782 if(co == NULL) return 0;
1784 std::string mod = lua_tostring(L, 2);
1785 co->setTextureMod(mod);
1789 // setsprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2,
1790 // select_horiz_by_yawpitch=false)
1791 static int l_setsprite(lua_State *L)
1793 ObjectRef *ref = checkobject(L, 1);
1794 LuaEntitySAO *co = getluaobject(ref);
1795 if(co == NULL) return 0;
1798 if(!lua_isnil(L, 2))
1799 p = read_v2s16(L, 2);
1801 if(!lua_isnil(L, 3))
1802 num_frames = lua_tonumber(L, 3);
1803 float framelength = 0.2;
1804 if(!lua_isnil(L, 4))
1805 framelength = lua_tonumber(L, 4);
1806 bool select_horiz_by_yawpitch = false;
1807 if(!lua_isnil(L, 5))
1808 select_horiz_by_yawpitch = lua_toboolean(L, 5);
1809 co->setSprite(p, num_frames, framelength, select_horiz_by_yawpitch);
1814 ObjectRef(ServerActiveObject *object):
1817 //infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
1823 infostream<<"ObjectRef destructing for id="
1824 <<m_object->getId()<<std::endl;
1826 infostream<<"ObjectRef destructing for id=unknown"<<std::endl;*/
1829 // Creates an ObjectRef and leaves it on top of stack
1830 // Not callable from Lua; all references are created on the C side.
1831 static void create(lua_State *L, ServerActiveObject *object)
1833 ObjectRef *o = new ObjectRef(object);
1834 //infostream<<"ObjectRef::create: o="<<o<<std::endl;
1835 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1836 luaL_getmetatable(L, className);
1837 lua_setmetatable(L, -2);
1840 static void set_null(lua_State *L)
1842 ObjectRef *o = checkobject(L, -1);
1846 static void Register(lua_State *L)
1849 int methodtable = lua_gettop(L);
1850 luaL_newmetatable(L, className);
1851 int metatable = lua_gettop(L);
1853 lua_pushliteral(L, "__metatable");
1854 lua_pushvalue(L, methodtable);
1855 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
1857 lua_pushliteral(L, "__index");
1858 lua_pushvalue(L, methodtable);
1859 lua_settable(L, metatable);
1861 lua_pushliteral(L, "__gc");
1862 lua_pushcfunction(L, gc_object);
1863 lua_settable(L, metatable);
1865 lua_pop(L, 1); // drop metatable
1867 luaL_openlib(L, 0, methods, 0); // fill methodtable
1868 lua_pop(L, 1); // drop methodtable
1870 // Cannot be created from Lua
1871 //lua_register(L, className, create_object);
1874 const char ObjectRef::className[] = "ObjectRef";
1875 const luaL_reg ObjectRef::methods[] = {
1876 method(ObjectRef, remove),
1877 method(ObjectRef, getpos),
1878 method(ObjectRef, setpos),
1879 method(ObjectRef, moveto),
1880 method(ObjectRef, setvelocity),
1881 method(ObjectRef, setacceleration),
1882 method(ObjectRef, add_to_inventory),
1883 method(ObjectRef, add_to_inventory_later),
1884 method(ObjectRef, get_hp),
1885 method(ObjectRef, set_hp),
1886 method(ObjectRef, settexturemod),
1887 method(ObjectRef, setsprite),
1891 // Creates a new anonymous reference if id=0
1892 static void objectref_get_or_create(lua_State *L,
1893 ServerActiveObject *cobj)
1895 if(cobj->getId() == 0){
1896 ObjectRef::create(L, cobj);
1898 objectref_get(L, cobj->getId());
1909 ServerEnvironment *m_env;
1911 static const char className[];
1912 static const luaL_reg methods[];
1914 static EnvRef *checkobject(lua_State *L, int narg)
1916 luaL_checktype(L, narg, LUA_TUSERDATA);
1917 void *ud = luaL_checkudata(L, narg, className);
1918 if(!ud) luaL_typerror(L, narg, className);
1919 return *(EnvRef**)ud; // unbox pointer
1922 // Exported functions
1924 // EnvRef:add_node(pos, node)
1925 // pos = {x=num, y=num, z=num}
1926 static int l_add_node(lua_State *L)
1928 //infostream<<"EnvRef::l_add_node()"<<std::endl;
1929 EnvRef *o = checkobject(L, 1);
1930 ServerEnvironment *env = o->m_env;
1931 if(env == NULL) return 0;
1933 v3s16 pos = readpos(L, 2);
1935 MapNode n = readnode(L, 3, env->getGameDef()->ndef());
1937 bool succeeded = env->getMap().addNodeWithEvent(pos, n);
1938 lua_pushboolean(L, succeeded);
1942 // EnvRef:remove_node(pos)
1943 // pos = {x=num, y=num, z=num}
1944 static int l_remove_node(lua_State *L)
1946 //infostream<<"EnvRef::l_remove_node()"<<std::endl;
1947 EnvRef *o = checkobject(L, 1);
1948 ServerEnvironment *env = o->m_env;
1949 if(env == NULL) return 0;
1951 v3s16 pos = readpos(L, 2);
1953 bool succeeded = env->getMap().removeNodeWithEvent(pos);
1954 lua_pushboolean(L, succeeded);
1958 // EnvRef:get_node(pos)
1959 // pos = {x=num, y=num, z=num}
1960 static int l_get_node(lua_State *L)
1962 //infostream<<"EnvRef::l_get_node()"<<std::endl;
1963 EnvRef *o = checkobject(L, 1);
1964 ServerEnvironment *env = o->m_env;
1965 if(env == NULL) return 0;
1967 v3s16 pos = readpos(L, 2);
1969 MapNode n = env->getMap().getNodeNoEx(pos);
1971 pushnode(L, n, env->getGameDef()->ndef());
1975 // EnvRef:add_luaentity(pos, entityname)
1976 // pos = {x=num, y=num, z=num}
1977 static int l_add_luaentity(lua_State *L)
1979 //infostream<<"EnvRef::l_add_luaentity()"<<std::endl;
1980 EnvRef *o = checkobject(L, 1);
1981 ServerEnvironment *env = o->m_env;
1982 if(env == NULL) return 0;
1984 v3f pos = readFloatPos(L, 2);
1986 const char *name = lua_tostring(L, 3);
1988 ServerActiveObject *obj = new LuaEntitySAO(env, pos, name, "");
1989 env->addActiveObject(obj);
1993 // EnvRef:add_item(pos, inventorystring)
1994 // pos = {x=num, y=num, z=num}
1995 static int l_add_item(lua_State *L)
1997 infostream<<"EnvRef::l_add_item()"<<std::endl;
1998 EnvRef *o = checkobject(L, 1);
1999 ServerEnvironment *env = o->m_env;
2000 if(env == NULL) return 0;
2002 v3f pos = readFloatPos(L, 2);
2004 const char *inventorystring = lua_tostring(L, 3);
2006 ServerActiveObject *obj = new ItemSAO(env, pos, inventorystring);
2007 env->addActiveObject(obj);
2011 // EnvRef:add_rat(pos)
2012 // pos = {x=num, y=num, z=num}
2013 static int l_add_rat(lua_State *L)
2015 infostream<<"EnvRef::l_add_rat()"<<std::endl;
2016 EnvRef *o = checkobject(L, 1);
2017 ServerEnvironment *env = o->m_env;
2018 if(env == NULL) return 0;
2020 v3f pos = readFloatPos(L, 2);
2022 ServerActiveObject *obj = new RatSAO(env, pos);
2023 env->addActiveObject(obj);
2027 // EnvRef:add_firefly(pos)
2028 // pos = {x=num, y=num, z=num}
2029 static int l_add_firefly(lua_State *L)
2031 infostream<<"EnvRef::l_add_firefly()"<<std::endl;
2032 EnvRef *o = checkobject(L, 1);
2033 ServerEnvironment *env = o->m_env;
2034 if(env == NULL) return 0;
2036 v3f pos = readFloatPos(L, 2);
2038 ServerActiveObject *obj = new FireflySAO(env, pos);
2039 env->addActiveObject(obj);
2043 // EnvRef:get_meta(pos)
2044 static int l_get_meta(lua_State *L)
2046 //infostream<<"EnvRef::l_get_meta()"<<std::endl;
2047 EnvRef *o = checkobject(L, 1);
2048 ServerEnvironment *env = o->m_env;
2049 if(env == NULL) return 0;
2051 v3s16 p = readpos(L, 2);
2052 NodeMetaRef::create(L, p, env);
2056 // EnvRef:get_player_by_name(name)
2057 static int l_get_player_by_name(lua_State *L)
2059 EnvRef *o = checkobject(L, 1);
2060 ServerEnvironment *env = o->m_env;
2061 if(env == NULL) return 0;
2063 const char *name = lua_tostring(L, 2);
2064 ServerRemotePlayer *player =
2065 static_cast<ServerRemotePlayer*>(env->getPlayer(name));
2070 // Put player on stack
2071 objectref_get_or_create(L, player);
2075 static int gc_object(lua_State *L) {
2076 EnvRef *o = *(EnvRef **)(lua_touserdata(L, 1));
2082 EnvRef(ServerEnvironment *env):
2085 infostream<<"EnvRef created"<<std::endl;
2090 infostream<<"EnvRef destructing"<<std::endl;
2093 // Creates an EnvRef and leaves it on top of stack
2094 // Not callable from Lua; all references are created on the C side.
2095 static void create(lua_State *L, ServerEnvironment *env)
2097 EnvRef *o = new EnvRef(env);
2098 //infostream<<"EnvRef::create: o="<<o<<std::endl;
2099 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
2100 luaL_getmetatable(L, className);
2101 lua_setmetatable(L, -2);
2104 static void set_null(lua_State *L)
2106 EnvRef *o = checkobject(L, -1);
2110 static void Register(lua_State *L)
2113 int methodtable = lua_gettop(L);
2114 luaL_newmetatable(L, className);
2115 int metatable = lua_gettop(L);
2117 lua_pushliteral(L, "__metatable");
2118 lua_pushvalue(L, methodtable);
2119 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
2121 lua_pushliteral(L, "__index");
2122 lua_pushvalue(L, methodtable);
2123 lua_settable(L, metatable);
2125 lua_pushliteral(L, "__gc");
2126 lua_pushcfunction(L, gc_object);
2127 lua_settable(L, metatable);
2129 lua_pop(L, 1); // drop metatable
2131 luaL_openlib(L, 0, methods, 0); // fill methodtable
2132 lua_pop(L, 1); // drop methodtable
2134 // Cannot be created from Lua
2135 //lua_register(L, className, create_object);
2138 const char EnvRef::className[] = "EnvRef";
2139 const luaL_reg EnvRef::methods[] = {
2140 method(EnvRef, add_node),
2141 method(EnvRef, remove_node),
2142 method(EnvRef, get_node),
2143 method(EnvRef, add_luaentity),
2144 method(EnvRef, add_item),
2145 method(EnvRef, add_rat),
2146 method(EnvRef, add_firefly),
2147 method(EnvRef, get_meta),
2148 method(EnvRef, get_player_by_name),
2153 Main export function
2156 void scriptapi_export(lua_State *L, Server *server)
2159 assert(lua_checkstack(L, 20));
2160 infostream<<"scriptapi_export"<<std::endl;
2161 StackUnroller stack_unroller(L);
2163 // Store server as light userdata in registry
2164 lua_pushlightuserdata(L, server);
2165 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_server");
2167 // Store nil as minetest_nodedef_defaults in registry
2169 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
2171 // Register global functions in table minetest
2173 luaL_register(L, NULL, minetest_f);
2174 lua_setglobal(L, "minetest");
2176 // Get the main minetest table
2177 lua_getglobal(L, "minetest");
2179 // Add tables to minetest
2182 lua_setfield(L, -2, "registered_nodes");
2184 lua_setfield(L, -2, "registered_entities");
2186 lua_setfield(L, -2, "registered_craftitems");
2188 lua_setfield(L, -2, "registered_abms");
2191 lua_setfield(L, -2, "object_refs");
2193 lua_setfield(L, -2, "luaentities");
2195 // Create entity prototype
2196 luaL_newmetatable(L, "minetest.entity");
2197 // metatable.__index = metatable
2198 lua_pushvalue(L, -1); // Duplicate metatable
2199 lua_setfield(L, -2, "__index");
2200 // Put functions in metatable
2201 luaL_register(L, NULL, minetest_entity_m);
2202 // Put other stuff in metatable
2204 // Register reference wrappers
2205 NodeMetaRef::Register(L);
2206 EnvRef::Register(L);
2207 ObjectRef::Register(L);
2210 void scriptapi_add_environment(lua_State *L, ServerEnvironment *env)
2213 assert(lua_checkstack(L, 20));
2214 infostream<<"scriptapi_add_environment"<<std::endl;
2215 StackUnroller stack_unroller(L);
2217 // Create EnvRef on stack
2218 EnvRef::create(L, env);
2219 int envref = lua_gettop(L);
2221 // minetest.env = envref
2222 lua_getglobal(L, "minetest");
2223 luaL_checktype(L, -1, LUA_TTABLE);
2224 lua_pushvalue(L, envref);
2225 lua_setfield(L, -2, "env");
2227 // Store environment as light userdata in registry
2228 lua_pushlightuserdata(L, env);
2229 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_env");
2231 /* Add ActiveBlockModifiers to environment */
2233 // Get minetest.registered_abms
2234 lua_getglobal(L, "minetest");
2235 lua_getfield(L, -1, "registered_abms");
2236 luaL_checktype(L, -1, LUA_TTABLE);
2237 int registered_abms = lua_gettop(L);
2239 if(lua_istable(L, registered_abms)){
2240 int table = lua_gettop(L);
2242 while(lua_next(L, table) != 0){
2243 // key at index -2 and value at index -1
2244 int id = lua_tonumber(L, -2);
2245 int current_abm = lua_gettop(L);
2247 std::set<std::string> trigger_contents;
2248 lua_getfield(L, current_abm, "nodenames");
2249 if(lua_istable(L, -1)){
2250 int table = lua_gettop(L);
2252 while(lua_next(L, table) != 0){
2253 // key at index -2 and value at index -1
2254 luaL_checktype(L, -1, LUA_TSTRING);
2255 trigger_contents.insert(lua_tostring(L, -1));
2256 // removes value, keeps key for next iteration
2262 float trigger_interval = 10.0;
2263 getfloatfield(L, current_abm, "interval", trigger_interval);
2265 int trigger_chance = 50;
2266 getintfield(L, current_abm, "chance", trigger_chance);
2268 LuaABM *abm = new LuaABM(L, id, trigger_contents,
2269 trigger_interval, trigger_chance);
2271 env->addActiveBlockModifier(abm);
2273 // removes value, keeps key for next iteration
2281 // Dump stack top with the dump2 function
2282 static void dump2(lua_State *L, const char *name)
2284 // Dump object (debug)
2285 lua_getglobal(L, "dump2");
2286 luaL_checktype(L, -1, LUA_TFUNCTION);
2287 lua_pushvalue(L, -2); // Get previous stack top as first parameter
2288 lua_pushstring(L, name);
2289 if(lua_pcall(L, 2, 0, 0))
2290 script_error(L, "error: %s\n", lua_tostring(L, -1));
2298 void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj)
2301 assert(lua_checkstack(L, 20));
2302 //infostream<<"scriptapi_add_object_reference: id="<<cobj->getId()<<std::endl;
2303 StackUnroller stack_unroller(L);
2305 // Create object on stack
2306 ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack
2307 int object = lua_gettop(L);
2309 // Get minetest.object_refs table
2310 lua_getglobal(L, "minetest");
2311 lua_getfield(L, -1, "object_refs");
2312 luaL_checktype(L, -1, LUA_TTABLE);
2313 int objectstable = lua_gettop(L);
2315 // object_refs[id] = object
2316 lua_pushnumber(L, cobj->getId()); // Push id
2317 lua_pushvalue(L, object); // Copy object to top of stack
2318 lua_settable(L, objectstable);
2321 void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj)
2324 assert(lua_checkstack(L, 20));
2325 //infostream<<"scriptapi_rm_object_reference: id="<<cobj->getId()<<std::endl;
2326 StackUnroller stack_unroller(L);
2328 // Get minetest.object_refs table
2329 lua_getglobal(L, "minetest");
2330 lua_getfield(L, -1, "object_refs");
2331 luaL_checktype(L, -1, LUA_TTABLE);
2332 int objectstable = lua_gettop(L);
2334 // Get object_refs[id]
2335 lua_pushnumber(L, cobj->getId()); // Push id
2336 lua_gettable(L, objectstable);
2337 // Set object reference to NULL
2338 ObjectRef::set_null(L);
2339 lua_pop(L, 1); // pop object
2341 // Set object_refs[id] = nil
2342 lua_pushnumber(L, cobj->getId()); // Push id
2344 lua_settable(L, objectstable);
2347 bool scriptapi_on_chat_message(lua_State *L, const std::string &name,
2348 const std::string &message)
2351 assert(lua_checkstack(L, 20));
2352 StackUnroller stack_unroller(L);
2354 // Get minetest.registered_on_chat_messages
2355 lua_getglobal(L, "minetest");
2356 lua_getfield(L, -1, "registered_on_chat_messages");
2357 luaL_checktype(L, -1, LUA_TTABLE);
2358 int table = lua_gettop(L);
2361 while(lua_next(L, table) != 0){
2362 // key at index -2 and value at index -1
2363 luaL_checktype(L, -1, LUA_TFUNCTION);
2365 lua_pushstring(L, name.c_str());
2366 lua_pushstring(L, message.c_str());
2367 if(lua_pcall(L, 2, 1, 0))
2368 script_error(L, "error: %s\n", lua_tostring(L, -1));
2369 bool ate = lua_toboolean(L, -1);
2373 // value removed, keep key for next iteration
2382 void scriptapi_on_newplayer(lua_State *L, ServerActiveObject *player)
2385 assert(lua_checkstack(L, 20));
2386 StackUnroller stack_unroller(L);
2388 // Get minetest.registered_on_newplayers
2389 lua_getglobal(L, "minetest");
2390 lua_getfield(L, -1, "registered_on_newplayers");
2391 luaL_checktype(L, -1, LUA_TTABLE);
2392 int table = lua_gettop(L);
2395 while(lua_next(L, table) != 0){
2396 // key at index -2 and value at index -1
2397 luaL_checktype(L, -1, LUA_TFUNCTION);
2399 objectref_get_or_create(L, player);
2400 if(lua_pcall(L, 1, 0, 0))
2401 script_error(L, "error: %s\n", lua_tostring(L, -1));
2402 // value removed, keep key for next iteration
2405 bool scriptapi_on_respawnplayer(lua_State *L, ServerActiveObject *player)
2408 assert(lua_checkstack(L, 20));
2409 StackUnroller stack_unroller(L);
2411 bool positioning_handled_by_some = false;
2413 // Get minetest.registered_on_respawnplayers
2414 lua_getglobal(L, "minetest");
2415 lua_getfield(L, -1, "registered_on_respawnplayers");
2416 luaL_checktype(L, -1, LUA_TTABLE);
2417 int table = lua_gettop(L);
2420 while(lua_next(L, table) != 0){
2421 // key at index -2 and value at index -1
2422 luaL_checktype(L, -1, LUA_TFUNCTION);
2424 objectref_get_or_create(L, player);
2425 if(lua_pcall(L, 1, 1, 0))
2426 script_error(L, "error: %s\n", lua_tostring(L, -1));
2427 bool positioning_handled = lua_toboolean(L, -1);
2429 if(positioning_handled)
2430 positioning_handled_by_some = true;
2431 // value removed, keep key for next iteration
2433 return positioning_handled_by_some;
2440 static void pushPointedThing(lua_State *L, const PointedThing& pointed)
2443 if(pointed.type == POINTEDTHING_NODE)
2445 lua_pushstring(L, "node");
2446 lua_setfield(L, -2, "type");
2447 pushpos(L, pointed.node_undersurface);
2448 lua_setfield(L, -2, "under");
2449 pushpos(L, pointed.node_abovesurface);
2450 lua_setfield(L, -2, "above");
2452 else if(pointed.type == POINTEDTHING_OBJECT)
2454 lua_pushstring(L, "object");
2455 lua_setfield(L, -2, "type");
2456 objectref_get(L, pointed.object_id);
2457 lua_setfield(L, -2, "ref");
2461 lua_pushstring(L, "nothing");
2462 lua_setfield(L, -2, "type");
2466 void scriptapi_add_craftitem(lua_State *L, const char *name)
2468 StackUnroller stack_unroller(L);
2469 assert(lua_gettop(L) > 0);
2471 // Set minetest.registered_craftitems[name] = table on top of stack
2472 lua_getglobal(L, "minetest");
2473 lua_getfield(L, -1, "registered_craftitems");
2474 luaL_checktype(L, -1, LUA_TTABLE);
2475 lua_pushvalue(L, -3); // push another reference to the table to be registered
2476 lua_setfield(L, -2, name); // set minetest.registered_craftitems[name]
2479 static bool get_craftitem_callback(lua_State *L, const char *name,
2480 const char *callbackname)
2482 // Get minetest.registered_craftitems[name][callbackname]
2483 // If that is nil or on error, return false and stack is unchanged
2484 // If that is a function, returns true and pushes the
2485 // function onto the stack
2487 lua_getglobal(L, "minetest");
2488 lua_getfield(L, -1, "registered_craftitems");
2490 luaL_checktype(L, -1, LUA_TTABLE);
2491 lua_getfield(L, -1, name);
2493 // Should be a table
2494 if(lua_type(L, -1) != LUA_TTABLE)
2496 errorstream<<"CraftItem name \""<<name<<"\" not defined"<<std::endl;
2500 lua_getfield(L, -1, callbackname);
2502 // Should be a function or nil
2503 if(lua_type(L, -1) == LUA_TFUNCTION)
2507 else if(lua_isnil(L, -1))
2514 errorstream<<"CraftItem name \""<<name<<"\" callback \""
2515 <<callbackname<<" is not a function"<<std::endl;
2521 bool scriptapi_craftitem_on_drop(lua_State *L, const char *name,
2522 ServerActiveObject *dropper, v3f pos,
2523 bool &callback_exists)
2526 assert(lua_checkstack(L, 20));
2527 //infostream<<"scriptapi_craftitem_on_drop"<<std::endl;
2528 StackUnroller stack_unroller(L);
2530 bool result = false;
2531 callback_exists = get_craftitem_callback(L, name, "on_drop");
2535 lua_pushstring(L, name);
2536 objectref_get_or_create(L, dropper);
2537 pushFloatPos(L, pos);
2538 if(lua_pcall(L, 3, 1, 0))
2539 script_error(L, "error: %s\n", lua_tostring(L, -1));
2540 result = lua_toboolean(L, -1);
2545 bool scriptapi_craftitem_on_place_on_ground(lua_State *L, const char *name,
2546 ServerActiveObject *placer, v3f pos,
2547 bool &callback_exists)
2550 assert(lua_checkstack(L, 20));
2551 //infostream<<"scriptapi_craftitem_on_place_on_ground"<<std::endl;
2552 StackUnroller stack_unroller(L);
2554 bool result = false;
2555 callback_exists = get_craftitem_callback(L, name, "on_place_on_ground");
2559 lua_pushstring(L, name);
2560 objectref_get_or_create(L, placer);
2561 pushFloatPos(L, pos);
2562 if(lua_pcall(L, 3, 1, 0))
2563 script_error(L, "error: %s\n", lua_tostring(L, -1));
2564 result = lua_toboolean(L, -1);
2569 bool scriptapi_craftitem_on_use(lua_State *L, const char *name,
2570 ServerActiveObject *user, const PointedThing& pointed,
2571 bool &callback_exists)
2574 assert(lua_checkstack(L, 20));
2575 //infostream<<"scriptapi_craftitem_on_use"<<std::endl;
2576 StackUnroller stack_unroller(L);
2578 bool result = false;
2579 callback_exists = get_craftitem_callback(L, name, "on_use");
2583 lua_pushstring(L, name);
2584 objectref_get_or_create(L, user);
2585 pushPointedThing(L, pointed);
2586 if(lua_pcall(L, 3, 1, 0))
2587 script_error(L, "error: %s\n", lua_tostring(L, -1));
2588 result = lua_toboolean(L, -1);
2597 void scriptapi_environment_step(lua_State *L, float dtime)
2600 assert(lua_checkstack(L, 20));
2601 //infostream<<"scriptapi_environment_step"<<std::endl;
2602 StackUnroller stack_unroller(L);
2604 // Get minetest.registered_globalsteps
2605 lua_getglobal(L, "minetest");
2606 lua_getfield(L, -1, "registered_globalsteps");
2607 luaL_checktype(L, -1, LUA_TTABLE);
2608 int table = lua_gettop(L);
2611 while(lua_next(L, table) != 0){
2612 // key at index -2 and value at index -1
2613 luaL_checktype(L, -1, LUA_TFUNCTION);
2615 lua_pushnumber(L, dtime);
2616 if(lua_pcall(L, 1, 0, 0))
2617 script_error(L, "error: %s\n", lua_tostring(L, -1));
2618 // value removed, keep key for next iteration
2622 void scriptapi_environment_on_placenode(lua_State *L, v3s16 p, MapNode newnode,
2623 ServerActiveObject *placer)
2626 assert(lua_checkstack(L, 20));
2627 //infostream<<"scriptapi_environment_on_placenode"<<std::endl;
2628 StackUnroller stack_unroller(L);
2630 // Get server from registry
2631 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
2632 Server *server = (Server*)lua_touserdata(L, -1);
2633 // And get the writable node definition manager from the server
2634 IWritableNodeDefManager *ndef =
2635 server->getWritableNodeDefManager();
2637 // Get minetest.registered_on_placenodes
2638 lua_getglobal(L, "minetest");
2639 lua_getfield(L, -1, "registered_on_placenodes");
2640 luaL_checktype(L, -1, LUA_TTABLE);
2641 int table = lua_gettop(L);
2644 while(lua_next(L, table) != 0){
2645 // key at index -2 and value at index -1
2646 luaL_checktype(L, -1, LUA_TFUNCTION);
2649 pushnode(L, newnode, ndef);
2650 objectref_get_or_create(L, placer);
2651 if(lua_pcall(L, 3, 0, 0))
2652 script_error(L, "error: %s\n", lua_tostring(L, -1));
2653 // value removed, keep key for next iteration
2657 void scriptapi_environment_on_dignode(lua_State *L, v3s16 p, MapNode oldnode,
2658 ServerActiveObject *digger)
2661 assert(lua_checkstack(L, 20));
2662 //infostream<<"scriptapi_environment_on_dignode"<<std::endl;
2663 StackUnroller stack_unroller(L);
2665 // Get server from registry
2666 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
2667 Server *server = (Server*)lua_touserdata(L, -1);
2668 // And get the writable node definition manager from the server
2669 IWritableNodeDefManager *ndef =
2670 server->getWritableNodeDefManager();
2672 // Get minetest.registered_on_dignodes
2673 lua_getglobal(L, "minetest");
2674 lua_getfield(L, -1, "registered_on_dignodes");
2675 luaL_checktype(L, -1, LUA_TTABLE);
2676 int table = lua_gettop(L);
2679 while(lua_next(L, table) != 0){
2680 // key at index -2 and value at index -1
2681 luaL_checktype(L, -1, LUA_TFUNCTION);
2684 pushnode(L, oldnode, ndef);
2685 objectref_get_or_create(L, digger);
2686 if(lua_pcall(L, 3, 0, 0))
2687 script_error(L, "error: %s\n", lua_tostring(L, -1));
2688 // value removed, keep key for next iteration
2692 void scriptapi_environment_on_punchnode(lua_State *L, v3s16 p, MapNode node,
2693 ServerActiveObject *puncher)
2696 assert(lua_checkstack(L, 20));
2697 //infostream<<"scriptapi_environment_on_punchnode"<<std::endl;
2698 StackUnroller stack_unroller(L);
2700 // Get server from registry
2701 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
2702 Server *server = (Server*)lua_touserdata(L, -1);
2703 // And get the writable node definition manager from the server
2704 IWritableNodeDefManager *ndef =
2705 server->getWritableNodeDefManager();
2707 // Get minetest.registered_on_punchnodes
2708 lua_getglobal(L, "minetest");
2709 lua_getfield(L, -1, "registered_on_punchnodes");
2710 luaL_checktype(L, -1, LUA_TTABLE);
2711 int table = lua_gettop(L);
2714 while(lua_next(L, table) != 0){
2715 // key at index -2 and value at index -1
2716 luaL_checktype(L, -1, LUA_TFUNCTION);
2719 pushnode(L, node, ndef);
2720 objectref_get_or_create(L, puncher);
2721 if(lua_pcall(L, 3, 0, 0))
2722 script_error(L, "error: %s\n", lua_tostring(L, -1));
2723 // value removed, keep key for next iteration
2727 void scriptapi_environment_on_generated(lua_State *L, v3s16 minp, v3s16 maxp)
2730 assert(lua_checkstack(L, 20));
2731 //infostream<<"scriptapi_environment_on_generated"<<std::endl;
2732 StackUnroller stack_unroller(L);
2734 // Get minetest.registered_on_generateds
2735 lua_getglobal(L, "minetest");
2736 lua_getfield(L, -1, "registered_on_generateds");
2737 luaL_checktype(L, -1, LUA_TTABLE);
2738 int table = lua_gettop(L);
2741 while(lua_next(L, table) != 0){
2742 // key at index -2 and value at index -1
2743 luaL_checktype(L, -1, LUA_TFUNCTION);
2747 if(lua_pcall(L, 2, 0, 0))
2748 script_error(L, "error: %s\n", lua_tostring(L, -1));
2749 // value removed, keep key for next iteration
2757 bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
2758 const std::string &staticdata)
2761 assert(lua_checkstack(L, 20));
2762 infostream<<"scriptapi_luaentity_add: id="<<id<<" name=\""
2763 <<name<<"\""<<std::endl;
2764 StackUnroller stack_unroller(L);
2766 // Get minetest.registered_entities[name]
2767 lua_getglobal(L, "minetest");
2768 lua_getfield(L, -1, "registered_entities");
2769 luaL_checktype(L, -1, LUA_TTABLE);
2770 lua_pushstring(L, name);
2771 lua_gettable(L, -2);
2772 // Should be a table, which we will use as a prototype
2773 //luaL_checktype(L, -1, LUA_TTABLE);
2774 if(lua_type(L, -1) != LUA_TTABLE){
2775 errorstream<<"LuaEntity name \""<<name<<"\" not defined"<<std::endl;
2778 int prototype_table = lua_gettop(L);
2779 //dump2(L, "prototype_table");
2781 // Create entity object
2783 int object = lua_gettop(L);
2785 // Set object metatable
2786 lua_pushvalue(L, prototype_table);
2787 lua_setmetatable(L, -2);
2789 // Add object reference
2790 // This should be userdata with metatable ObjectRef
2791 objectref_get(L, id);
2792 luaL_checktype(L, -1, LUA_TUSERDATA);
2793 if(!luaL_checkudata(L, -1, "ObjectRef"))
2794 luaL_typerror(L, -1, "ObjectRef");
2795 lua_setfield(L, -2, "object");
2797 // minetest.luaentities[id] = object
2798 lua_getglobal(L, "minetest");
2799 lua_getfield(L, -1, "luaentities");
2800 luaL_checktype(L, -1, LUA_TTABLE);
2801 lua_pushnumber(L, id); // Push id
2802 lua_pushvalue(L, object); // Copy object to top of stack
2803 lua_settable(L, -3);
2805 // Get on_activate function
2806 lua_pushvalue(L, object);
2807 lua_getfield(L, -1, "on_activate");
2808 if(!lua_isnil(L, -1)){
2809 luaL_checktype(L, -1, LUA_TFUNCTION);
2810 lua_pushvalue(L, object); // self
2811 lua_pushlstring(L, staticdata.c_str(), staticdata.size());
2812 // Call with 2 arguments, 0 results
2813 if(lua_pcall(L, 2, 0, 0))
2814 script_error(L, "error running function %s:on_activate: %s\n",
2815 name, lua_tostring(L, -1));
2821 void scriptapi_luaentity_rm(lua_State *L, u16 id)
2824 assert(lua_checkstack(L, 20));
2825 infostream<<"scriptapi_luaentity_rm: id="<<id<<std::endl;
2827 // Get minetest.luaentities table
2828 lua_getglobal(L, "minetest");
2829 lua_getfield(L, -1, "luaentities");
2830 luaL_checktype(L, -1, LUA_TTABLE);
2831 int objectstable = lua_gettop(L);
2833 // Set luaentities[id] = nil
2834 lua_pushnumber(L, id); // Push id
2836 lua_settable(L, objectstable);
2838 lua_pop(L, 2); // pop luaentities, minetest
2841 std::string scriptapi_luaentity_get_staticdata(lua_State *L, u16 id)
2844 assert(lua_checkstack(L, 20));
2845 infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl;
2846 StackUnroller stack_unroller(L);
2848 // Get minetest.luaentities[id]
2849 luaentity_get(L, id);
2850 int object = lua_gettop(L);
2852 // Get get_staticdata function
2853 lua_pushvalue(L, object);
2854 lua_getfield(L, -1, "get_staticdata");
2855 if(lua_isnil(L, -1))
2858 luaL_checktype(L, -1, LUA_TFUNCTION);
2859 lua_pushvalue(L, object); // self
2860 // Call with 1 arguments, 1 results
2861 if(lua_pcall(L, 1, 1, 0))
2862 script_error(L, "error running function get_staticdata: %s\n",
2863 lua_tostring(L, -1));
2866 const char *s = lua_tolstring(L, -1, &len);
2867 return std::string(s, len);
2870 void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
2871 LuaEntityProperties *prop)
2874 assert(lua_checkstack(L, 20));
2875 infostream<<"scriptapi_luaentity_get_properties: id="<<id<<std::endl;
2876 StackUnroller stack_unroller(L);
2878 // Get minetest.luaentities[id]
2879 luaentity_get(L, id);
2880 //int object = lua_gettop(L);
2884 getboolfield(L, -1, "physical", prop->physical);
2886 getfloatfield(L, -1, "weight", prop->weight);
2888 lua_getfield(L, -1, "collisionbox");
2889 if(lua_istable(L, -1))
2890 prop->collisionbox = read_aabbox3df32(L, -1, 1.0);
2893 getstringfield(L, -1, "visual", prop->visual);
2895 lua_getfield(L, -1, "visual_size");
2896 if(lua_istable(L, -1))
2897 prop->visual_size = read_v2f(L, -1);
2900 lua_getfield(L, -1, "textures");
2901 if(lua_istable(L, -1)){
2902 prop->textures.clear();
2903 int table = lua_gettop(L);
2905 while(lua_next(L, table) != 0){
2906 // key at index -2 and value at index -1
2907 if(lua_isstring(L, -1))
2908 prop->textures.push_back(lua_tostring(L, -1));
2910 prop->textures.push_back("");
2911 // removes value, keeps key for next iteration
2917 lua_getfield(L, -1, "spritediv");
2918 if(lua_istable(L, -1))
2919 prop->spritediv = read_v2s16(L, -1);
2922 lua_getfield(L, -1, "initial_sprite_basepos");
2923 if(lua_istable(L, -1))
2924 prop->initial_sprite_basepos = read_v2s16(L, -1);
2928 void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime)
2931 assert(lua_checkstack(L, 20));
2932 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
2933 StackUnroller stack_unroller(L);
2935 // Get minetest.luaentities[id]
2936 luaentity_get(L, id);
2937 int object = lua_gettop(L);
2938 // State: object is at top of stack
2939 // Get step function
2940 lua_getfield(L, -1, "on_step");
2941 if(lua_isnil(L, -1))
2943 luaL_checktype(L, -1, LUA_TFUNCTION);
2944 lua_pushvalue(L, object); // self
2945 lua_pushnumber(L, dtime); // dtime
2946 // Call with 2 arguments, 0 results
2947 if(lua_pcall(L, 2, 0, 0))
2948 script_error(L, "error running function 'on_step': %s\n", lua_tostring(L, -1));
2951 // Calls entity:on_punch(ObjectRef puncher)
2952 void scriptapi_luaentity_punch(lua_State *L, u16 id,
2953 ServerActiveObject *puncher)
2956 assert(lua_checkstack(L, 20));
2957 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
2958 StackUnroller stack_unroller(L);
2960 // Get minetest.luaentities[id]
2961 luaentity_get(L, id);
2962 int object = lua_gettop(L);
2963 // State: object is at top of stack
2965 lua_getfield(L, -1, "on_punch");
2966 if(lua_isnil(L, -1))
2968 luaL_checktype(L, -1, LUA_TFUNCTION);
2969 lua_pushvalue(L, object); // self
2970 objectref_get_or_create(L, puncher); // Clicker reference
2971 // Call with 2 arguments, 0 results
2972 if(lua_pcall(L, 2, 0, 0))
2973 script_error(L, "error running function 'on_punch': %s\n", lua_tostring(L, -1));
2976 // Calls entity:on_rightclick(ObjectRef clicker)
2977 void scriptapi_luaentity_rightclick(lua_State *L, u16 id,
2978 ServerActiveObject *clicker)
2981 assert(lua_checkstack(L, 20));
2982 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
2983 StackUnroller stack_unroller(L);
2985 // Get minetest.luaentities[id]
2986 luaentity_get(L, id);
2987 int object = lua_gettop(L);
2988 // State: object is at top of stack
2990 lua_getfield(L, -1, "on_rightclick");
2991 if(lua_isnil(L, -1))
2993 luaL_checktype(L, -1, LUA_TFUNCTION);
2994 lua_pushvalue(L, object); // self
2995 objectref_get_or_create(L, clicker); // Clicker reference
2996 // Call with 2 arguments, 0 results
2997 if(lua_pcall(L, 2, 0, 0))
2998 script_error(L, "error running function 'on_rightclick': %s\n", lua_tostring(L, -1));