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"
33 #include "serverobject.h"
36 #include "luaentity_common.h"
37 #include "content_sao.h" // For LuaEntitySAO
41 #include "main.h" // For g_settings
42 #include "settings.h" // For accessing g_settings
43 #include "nodemetadata.h"
44 #include "mapblock.h" // For getNodeBlockPos
48 - All kinds of callbacks
50 blockdef.metadata_name =
57 - Stores an inventory and stuff in a Settings object
58 meta.inventory_add_list("main")
59 blockdef.on_inventory_modified
60 meta.set("owner", playername)
62 - Item definition (actually, only CraftItem)
63 - Putting items in NodeMetadata (?)
66 static void stackDump(lua_State *L, std::ostream &o)
69 int top = lua_gettop(L);
70 for (i = 1; i <= top; i++) { /* repeat for each level */
71 int t = lua_type(L, i);
74 case LUA_TSTRING: /* strings */
75 o<<"\""<<lua_tostring(L, i)<<"\"";
78 case LUA_TBOOLEAN: /* booleans */
79 o<<(lua_toboolean(L, i) ? "true" : "false");
82 case LUA_TNUMBER: /* numbers */ {
84 snprintf(buf, 10, "%g", lua_tonumber(L, i));
88 default: /* other values */
89 o<<lua_typename(L, t);
98 static void realitycheck(lua_State *L)
100 int top = lua_gettop(L);
102 dstream<<"Stack is over 30:"<<std::endl;
103 stackDump(L, dstream);
104 script_error(L, "Stack is over 30 (reality check)");
114 StackUnroller(lua_State *L):
118 m_original_top = lua_gettop(m_lua); // store stack height
122 lua_settop(m_lua, m_original_top); // restore stack height
126 static v3f readFloatPos(lua_State *L, int index)
129 luaL_checktype(L, index, LUA_TTABLE);
130 lua_getfield(L, index, "x");
131 pos.X = lua_tonumber(L, -1);
133 lua_getfield(L, index, "y");
134 pos.Y = lua_tonumber(L, -1);
136 lua_getfield(L, index, "z");
137 pos.Z = lua_tonumber(L, -1);
139 pos *= BS; // Scale to internal format
143 static void pushFloatPos(lua_State *L, v3f p)
147 lua_pushnumber(L, p.X);
148 lua_setfield(L, -2, "x");
149 lua_pushnumber(L, p.Y);
150 lua_setfield(L, -2, "y");
151 lua_pushnumber(L, p.Z);
152 lua_setfield(L, -2, "z");
155 static void pushpos(lua_State *L, v3s16 p)
158 lua_pushnumber(L, p.X);
159 lua_setfield(L, -2, "x");
160 lua_pushnumber(L, p.Y);
161 lua_setfield(L, -2, "y");
162 lua_pushnumber(L, p.Z);
163 lua_setfield(L, -2, "z");
166 static v3s16 readpos(lua_State *L, int index)
168 // Correct rounding at <0
169 v3f pf = readFloatPos(L, index);
170 return floatToInt(pf, BS);
173 static void pushnode(lua_State *L, const MapNode &n, INodeDefManager *ndef)
176 lua_pushstring(L, ndef->get(n).name.c_str());
177 lua_setfield(L, -2, "name");
178 lua_pushnumber(L, n.getParam1());
179 lua_setfield(L, -2, "param1");
180 lua_pushnumber(L, n.getParam2());
181 lua_setfield(L, -2, "param2");
184 static MapNode readnode(lua_State *L, int index, INodeDefManager *ndef)
186 lua_getfield(L, index, "name");
187 const char *name = lua_tostring(L, -1);
190 lua_getfield(L, index, "param1");
194 param1 = lua_tonumber(L, -1);
197 lua_getfield(L, index, "param2");
201 param2 = lua_tonumber(L, -1);
203 return MapNode(ndef, name, param1, param2);
206 static video::SColor readARGB8(lua_State *L, int index)
209 luaL_checktype(L, index, LUA_TTABLE);
210 lua_getfield(L, index, "a");
211 if(lua_isnumber(L, -1))
212 color.setAlpha(lua_tonumber(L, -1));
214 lua_getfield(L, index, "r");
215 color.setRed(lua_tonumber(L, -1));
217 lua_getfield(L, index, "g");
218 color.setGreen(lua_tonumber(L, -1));
220 lua_getfield(L, index, "b");
221 color.setBlue(lua_tonumber(L, -1));
226 static core::aabbox3d<f32> read_aabbox3df32(lua_State *L, int index, f32 scale)
228 core::aabbox3d<f32> box;
229 if(lua_istable(L, -1)){
230 lua_rawgeti(L, -1, 1);
231 box.MinEdge.X = lua_tonumber(L, -1) * scale;
233 lua_rawgeti(L, -1, 2);
234 box.MinEdge.Y = lua_tonumber(L, -1) * scale;
236 lua_rawgeti(L, -1, 3);
237 box.MinEdge.Z = lua_tonumber(L, -1) * scale;
239 lua_rawgeti(L, -1, 4);
240 box.MaxEdge.X = lua_tonumber(L, -1) * scale;
242 lua_rawgeti(L, -1, 5);
243 box.MaxEdge.Y = lua_tonumber(L, -1) * scale;
245 lua_rawgeti(L, -1, 6);
246 box.MaxEdge.Z = lua_tonumber(L, -1) * scale;
252 static v2s16 read_v2s16(lua_State *L, int index)
255 luaL_checktype(L, index, LUA_TTABLE);
256 lua_getfield(L, index, "x");
257 p.X = lua_tonumber(L, -1);
259 lua_getfield(L, index, "y");
260 p.Y = lua_tonumber(L, -1);
265 static v2f read_v2f(lua_State *L, int index)
268 luaL_checktype(L, index, LUA_TTABLE);
269 lua_getfield(L, index, "x");
270 p.X = lua_tonumber(L, -1);
272 lua_getfield(L, index, "y");
273 p.Y = lua_tonumber(L, -1);
278 static bool getstringfield(lua_State *L, int table,
279 const char *fieldname, std::string &result)
281 lua_getfield(L, table, fieldname);
283 if(lua_isstring(L, -1)){
284 result = lua_tostring(L, -1);
291 static bool getintfield(lua_State *L, int table,
292 const char *fieldname, int &result)
294 lua_getfield(L, table, fieldname);
296 if(lua_isnumber(L, -1)){
297 result = lua_tonumber(L, -1);
304 static bool getfloatfield(lua_State *L, int table,
305 const char *fieldname, float &result)
307 lua_getfield(L, table, fieldname);
309 if(lua_isnumber(L, -1)){
310 result = lua_tonumber(L, -1);
317 static bool getboolfield(lua_State *L, int table,
318 const char *fieldname, bool &result)
320 lua_getfield(L, table, fieldname);
322 if(lua_isboolean(L, -1)){
323 result = lua_toboolean(L, -1);
330 static std::string getstringfield_default(lua_State *L, int table,
331 const char *fieldname, const std::string &default_)
333 std::string result = default_;
334 getstringfield(L, table, fieldname, result);
338 static int getintfield_default(lua_State *L, int table,
339 const char *fieldname, int default_)
341 int result = default_;
342 getintfield(L, table, fieldname, result);
346 /*static float getfloatfield_default(lua_State *L, int table,
347 const char *fieldname, float default_)
349 float result = default_;
350 getfloatfield(L, table, fieldname, result);
354 static bool getboolfield_default(lua_State *L, int table,
355 const char *fieldname, bool default_)
357 bool result = default_;
358 getboolfield(L, table, fieldname, result);
368 static bool string_to_enum(const EnumString *spec, int &result,
369 const std::string &str)
371 const EnumString *esp = spec;
373 if(str == std::string(esp->str)){
382 /*static bool enum_to_string(const EnumString *spec, std::string &result,
385 const EnumString *esp = spec;
396 static int getenumfield(lua_State *L, int table,
397 const char *fieldname, const EnumString *spec, int default_)
399 int result = default_;
400 string_to_enum(spec, result,
401 getstringfield_default(L, table, fieldname, ""));
405 struct EnumString es_DrawType[] =
407 {NDT_NORMAL, "normal"},
408 {NDT_AIRLIKE, "airlike"},
409 {NDT_LIQUID, "liquid"},
410 {NDT_FLOWINGLIQUID, "flowingliquid"},
411 {NDT_GLASSLIKE, "glasslike"},
412 {NDT_ALLFACES, "allfaces"},
413 {NDT_ALLFACES_OPTIONAL, "allfaces_optional"},
414 {NDT_TORCHLIKE, "torchlike"},
415 {NDT_SIGNLIKE, "signlike"},
416 {NDT_PLANTLIKE, "plantlike"},
417 {NDT_FENCELIKE, "fencelike"},
418 {NDT_RAILLIKE, "raillike"},
422 struct EnumString es_ContentParamType[] =
425 {CPT_LIGHT, "light"},
426 {CPT_MINERAL, "mineral"},
427 {CPT_FACEDIR_SIMPLE, "facedir_simple"},
430 struct EnumString es_LiquidType[] =
432 {LIQUID_NONE, "none"},
433 {LIQUID_FLOWING, "flowing"},
434 {LIQUID_SOURCE, "source"},
437 struct EnumString es_NodeBoxType[] =
439 {NODEBOX_REGULAR, "regular"},
440 {NODEBOX_FIXED, "fixed"},
441 {NODEBOX_WALLMOUNTED, "wallmounted"},
444 struct EnumString es_Diggability[] =
446 {DIGGABLE_NOT, "not"},
447 {DIGGABLE_NORMAL, "normal"},
448 {DIGGABLE_CONSTANT, "constant"},
455 static int l_register_nodedef_defaults(lua_State *L)
457 luaL_checktype(L, 1, LUA_TTABLE);
459 lua_pushvalue(L, 1); // Explicitly put parameter 1 on top of stack
460 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
465 // Register new object prototype
466 // register_entity(name, prototype)
467 static int l_register_entity(lua_State *L)
469 const char *name = luaL_checkstring(L, 1);
470 infostream<<"register_entity: "<<name<<std::endl;
471 luaL_checktype(L, 2, LUA_TTABLE);
473 // Get minetest.registered_entities
474 lua_getglobal(L, "minetest");
475 lua_getfield(L, -1, "registered_entities");
476 luaL_checktype(L, -1, LUA_TTABLE);
477 int registered_entities = lua_gettop(L);
478 lua_pushvalue(L, 2); // Object = param 2 -> stack top
479 // registered_entities[name] = object
480 lua_setfield(L, registered_entities, name);
482 // Get registered object to top of stack
485 // Set __index to point to itself
486 lua_pushvalue(L, -1);
487 lua_setfield(L, -2, "__index");
489 // Set metatable.__index = metatable
490 luaL_getmetatable(L, "minetest.entity");
491 lua_pushvalue(L, -1); // duplicate metatable
492 lua_setfield(L, -2, "__index");
493 // Set object metatable
494 lua_setmetatable(L, -2);
496 return 0; /* number of results */
499 class LuaABM : public ActiveBlockModifier
505 std::set<std::string> m_trigger_contents;
506 float m_trigger_interval;
507 u32 m_trigger_chance;
509 LuaABM(lua_State *L, int id,
510 const std::set<std::string> &trigger_contents,
511 float trigger_interval, u32 trigger_chance):
514 m_trigger_contents(trigger_contents),
515 m_trigger_interval(trigger_interval),
516 m_trigger_chance(trigger_chance)
519 virtual std::set<std::string> getTriggerContents()
521 return m_trigger_contents;
523 virtual float getTriggerInterval()
525 return m_trigger_interval;
527 virtual u32 getTriggerChance()
529 return m_trigger_chance;
531 virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n,
532 u32 active_object_count, u32 active_object_count_wider)
534 lua_State *L = m_lua;
537 assert(lua_checkstack(L, 20));
538 StackUnroller stack_unroller(L);
540 // Get minetest.registered_abms
541 lua_getglobal(L, "minetest");
542 lua_getfield(L, -1, "registered_abms");
543 luaL_checktype(L, -1, LUA_TTABLE);
544 int registered_abms = lua_gettop(L);
546 // Get minetest.registered_abms[m_id]
547 lua_pushnumber(L, m_id);
548 lua_gettable(L, registered_abms);
553 luaL_checktype(L, -1, LUA_TTABLE);
554 lua_getfield(L, -1, "action");
555 luaL_checktype(L, -1, LUA_TFUNCTION);
557 pushnode(L, n, env->getGameDef()->ndef());
558 lua_pushnumber(L, active_object_count);
559 lua_pushnumber(L, active_object_count_wider);
560 if(lua_pcall(L, 4, 0, 0))
561 script_error(L, "error: %s\n", lua_tostring(L, -1));
565 // register_abm({...})
566 static int l_register_abm(lua_State *L)
568 infostream<<"register_abm"<<std::endl;
569 luaL_checktype(L, 1, LUA_TTABLE);
571 // Get minetest.registered_abms
572 lua_getglobal(L, "minetest");
573 lua_getfield(L, -1, "registered_abms");
574 luaL_checktype(L, -1, LUA_TTABLE);
575 int registered_abms = lua_gettop(L);
580 lua_pushnumber(L, id);
581 lua_gettable(L, registered_abms);
589 infostream<<"register_abm: id="<<id<<std::endl;
591 // registered_abms[id] = spec
592 lua_pushnumber(L, id);
594 lua_settable(L, registered_abms);
596 return 0; /* number of results */
599 // register_tool(name, {lots of stuff})
600 static int l_register_tool(lua_State *L)
602 const char *name = luaL_checkstring(L, 1);
603 infostream<<"register_tool: "<<name<<std::endl;
604 luaL_checktype(L, 2, LUA_TTABLE);
607 // Get server from registry
608 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
609 Server *server = (Server*)lua_touserdata(L, -1);
610 // And get the writable tool definition manager from the server
611 IWritableToolDefManager *tooldef =
612 server->getWritableToolDefManager();
616 getstringfield(L, table, "image", def.imagename);
617 getfloatfield(L, table, "basetime", def.properties.basetime);
618 getfloatfield(L, table, "dt_weight", def.properties.dt_weight);
619 getfloatfield(L, table, "dt_crackiness", def.properties.dt_crackiness);
620 getfloatfield(L, table, "dt_crumbliness", def.properties.dt_crumbliness);
621 getfloatfield(L, table, "dt_cuttability", def.properties.dt_cuttability);
622 getfloatfield(L, table, "basedurability", def.properties.basedurability);
623 getfloatfield(L, table, "dd_weight", def.properties.dd_weight);
624 getfloatfield(L, table, "dd_crackiness", def.properties.dd_crackiness);
625 getfloatfield(L, table, "dd_crumbliness", def.properties.dd_crumbliness);
626 getfloatfield(L, table, "dd_cuttability", def.properties.dd_cuttability);
628 tooldef->registerTool(name, def);
629 return 0; /* number of results */
632 // register_node(name, {lots of stuff})
633 static int l_register_node(lua_State *L)
635 const char *name = luaL_checkstring(L, 1);
636 infostream<<"register_node: "<<name<<std::endl;
637 luaL_checktype(L, 2, LUA_TTABLE);
638 int nodedef_table = 2;
640 // Get server from registry
641 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
642 Server *server = (Server*)lua_touserdata(L, -1);
643 // And get the writable node definition manager from the server
644 IWritableNodeDefManager *nodedef =
645 server->getWritableNodeDefManager();
647 // Get default node definition from registry
648 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
649 int nodedef_default = lua_gettop(L);
652 Add to minetest.registered_nodes with default as metatable
655 // Get the node definition table given as parameter
656 lua_pushvalue(L, nodedef_table);
658 // Set __index to point to itself
659 lua_pushvalue(L, -1);
660 lua_setfield(L, -2, "__index");
662 // Set nodedef_default as metatable for the definition
663 lua_pushvalue(L, nodedef_default);
664 lua_setmetatable(L, nodedef_table);
666 // minetest.registered_nodes[name] = nodedef
667 lua_getglobal(L, "minetest");
668 lua_getfield(L, -1, "registered_nodes");
669 luaL_checktype(L, -1, LUA_TTABLE);
670 lua_pushstring(L, name);
671 lua_pushvalue(L, nodedef_table);
680 // Default to getting the corresponding NodeItem when dug
681 f.dug_item = std::string("NodeItem \"")+name+"\" 1";
683 // Default to unknown_block.png as all textures
684 f.setAllTextures("unknown_block.png");
687 Read definiton from Lua
692 /* Visual definition */
694 f.drawtype = (NodeDrawType)getenumfield(L, nodedef_table, "drawtype", es_DrawType,
696 getfloatfield(L, nodedef_table, "visual_scale", f.visual_scale);
698 lua_getfield(L, nodedef_table, "tile_images");
699 if(lua_istable(L, -1)){
700 int table = lua_gettop(L);
703 while(lua_next(L, table) != 0){
704 // key at index -2 and value at index -1
705 if(lua_isstring(L, -1))
706 f.tname_tiles[i] = lua_tostring(L, -1);
708 f.tname_tiles[i] = "";
709 // removes value, keeps key for next iteration
717 // Copy last value to all remaining textures
719 std::string lastname = f.tname_tiles[i-1];
721 f.tname_tiles[i] = lastname;
728 getstringfield(L, nodedef_table, "inventory_image", f.tname_inventory);
730 lua_getfield(L, nodedef_table, "special_materials");
731 if(lua_istable(L, -1)){
732 int table = lua_gettop(L);
735 while(lua_next(L, table) != 0){
736 // key at index -2 and value at index -1
737 int smtable = lua_gettop(L);
738 std::string tname = getstringfield_default(
739 L, smtable, "image", "");
740 bool backface_culling = getboolfield_default(
741 L, smtable, "backface_culling", true);
742 MaterialSpec mspec(tname, backface_culling);
743 f.setSpecialMaterial(i, mspec);
744 // removes value, keeps key for next iteration
755 f.alpha = getintfield_default(L, nodedef_table, "alpha", 255);
759 lua_getfield(L, nodedef_table, "post_effect_color");
760 if(!lua_isnil(L, -1))
761 f.post_effect_color = readARGB8(L, -1);
764 f.param_type = (ContentParamType)getenumfield(L, nodedef_table, "paramtype",
765 es_ContentParamType, CPT_NONE);
767 // True for all ground-like things like stone and mud, false for eg. trees
768 getboolfield(L, nodedef_table, "is_ground_content", f.is_ground_content);
769 getboolfield(L, nodedef_table, "light_propagates", f.light_propagates);
770 getboolfield(L, nodedef_table, "sunlight_propagates", f.sunlight_propagates);
771 // This is used for collision detection.
772 // Also for general solidness queries.
773 getboolfield(L, nodedef_table, "walkable", f.walkable);
774 // Player can point to these
775 getboolfield(L, nodedef_table, "pointable", f.pointable);
776 // Player can dig these
777 getboolfield(L, nodedef_table, "diggable", f.diggable);
778 // Player can climb these
779 getboolfield(L, nodedef_table, "climbable", f.climbable);
780 // Player can build on these
781 getboolfield(L, nodedef_table, "buildable_to", f.buildable_to);
782 // If true, param2 is set to direction when placed. Used for torches.
783 // NOTE: the direction format is quite inefficient and should be changed
784 getboolfield(L, nodedef_table, "wall_mounted", f.wall_mounted);
785 // Whether this content type often contains mineral.
786 // Used for texture atlas creation.
787 // Currently only enabled for CONTENT_STONE.
788 getboolfield(L, nodedef_table, "often_contains_mineral", f.often_contains_mineral);
789 // Inventory item string as which the node appears in inventory when dug.
790 // Mineral overrides this.
791 getstringfield(L, nodedef_table, "dug_item", f.dug_item);
792 // Extra dug item and its rarity
793 getstringfield(L, nodedef_table, "extra_dug_item", f.extra_dug_item);
794 // Usual get interval for extra dug item
795 getintfield(L, nodedef_table, "extra_dug_item_rarity", f.extra_dug_item_rarity);
796 // Metadata name of node (eg. "furnace")
797 getstringfield(L, nodedef_table, "metadata_name", f.metadata_name);
798 // Whether the node is non-liquid, source liquid or flowing liquid
799 f.liquid_type = (LiquidType)getenumfield(L, nodedef_table, "liquidtype",
800 es_LiquidType, LIQUID_NONE);
801 // If the content is liquid, this is the flowing version of the liquid.
802 getstringfield(L, nodedef_table, "liquid_alternative_flowing",
803 f.liquid_alternative_flowing);
804 // If the content is liquid, this is the source version of the liquid.
805 getstringfield(L, nodedef_table, "liquid_alternative_source",
806 f.liquid_alternative_source);
807 // Viscosity for fluid flow, ranging from 1 to 7, with
808 // 1 giving almost instantaneous propagation and 7 being
809 // the slowest possible
810 f.liquid_viscosity = getintfield_default(L, nodedef_table,
811 "liquid_viscosity", f.liquid_viscosity);
812 // Amount of light the node emits
813 f.light_source = getintfield_default(L, nodedef_table,
814 "light_source", f.light_source);
815 f.damage_per_second = getintfield_default(L, nodedef_table,
816 "damage_per_second", f.damage_per_second);
818 lua_getfield(L, nodedef_table, "selection_box");
819 if(lua_istable(L, -1)){
820 f.selection_box.type = (NodeBoxType)getenumfield(L, -1, "type",
821 es_NodeBoxType, NODEBOX_REGULAR);
823 lua_getfield(L, -1, "fixed");
824 if(lua_istable(L, -1))
825 f.selection_box.fixed = read_aabbox3df32(L, -1, BS);
828 lua_getfield(L, -1, "wall_top");
829 if(lua_istable(L, -1))
830 f.selection_box.wall_top = read_aabbox3df32(L, -1, BS);
833 lua_getfield(L, -1, "wall_bottom");
834 if(lua_istable(L, -1))
835 f.selection_box.wall_bottom = read_aabbox3df32(L, -1, BS);
838 lua_getfield(L, -1, "wall_side");
839 if(lua_istable(L, -1))
840 f.selection_box.wall_side = read_aabbox3df32(L, -1, BS);
845 lua_getfield(L, nodedef_table, "material");
846 if(lua_istable(L, -1)){
847 f.material.diggability = (Diggability)getenumfield(L, -1, "diggability",
848 es_Diggability, DIGGABLE_NORMAL);
850 getfloatfield(L, -1, "constant_time", f.material.constant_time);
851 getfloatfield(L, -1, "weight", f.material.weight);
852 getfloatfield(L, -1, "crackiness", f.material.crackiness);
853 getfloatfield(L, -1, "crumbliness", f.material.crumbliness);
854 getfloatfield(L, -1, "cuttability", f.material.cuttability);
855 getfloatfield(L, -1, "flammability", f.material.flammability);
859 getstringfield(L, nodedef_table, "cookresult_item", f.cookresult_item);
860 getfloatfield(L, nodedef_table, "furnace_cooktime", f.furnace_cooktime);
861 getfloatfield(L, nodedef_table, "furnace_burntime", f.furnace_burntime);
867 nodedef->set(name, f);
869 return 0; /* number of results */
872 // register_craft({output=item, recipe={{item00,item10},{item01,item11}})
873 static int l_register_craft(lua_State *L)
875 infostream<<"register_craft"<<std::endl;
876 luaL_checktype(L, 1, LUA_TTABLE);
879 // Get server from registry
880 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
881 Server *server = (Server*)lua_touserdata(L, -1);
882 // And get the writable craft definition manager from the server
883 IWritableCraftDefManager *craftdef =
884 server->getWritableCraftDefManager();
888 std::vector<std::string> input;
890 lua_getfield(L, table0, "output");
891 luaL_checktype(L, -1, LUA_TSTRING);
892 if(lua_isstring(L, -1))
893 output = lua_tostring(L, -1);
896 lua_getfield(L, table0, "recipe");
897 luaL_checktype(L, -1, LUA_TTABLE);
898 if(lua_istable(L, -1)){
899 int table1 = lua_gettop(L);
902 while(lua_next(L, table1) != 0){
904 // key at index -2 and value at index -1
905 luaL_checktype(L, -1, LUA_TTABLE);
906 if(lua_istable(L, -1)){
907 int table2 = lua_gettop(L);
909 while(lua_next(L, table2) != 0){
910 // key at index -2 and value at index -1
911 luaL_checktype(L, -1, LUA_TSTRING);
912 input.push_back(lua_tostring(L, -1));
913 // removes value, keeps key for next iteration
921 if(colcount != width){
922 script_error(L, "error: %s\n", "Invalid crafting recipe");
925 // removes value, keeps key for next iteration
932 CraftDefinition def(output, width, input);
933 craftdef->registerCraft(def);
935 return 0; /* number of results */
939 static int l_setting_get(lua_State *L)
941 const char *name = luaL_checkstring(L, 1);
943 std::string value = g_settings->get(name);
944 lua_pushstring(L, value.c_str());
945 } catch(SettingNotFoundException &e){
951 // setting_getbool(name)
952 static int l_setting_getbool(lua_State *L)
954 const char *name = luaL_checkstring(L, 1);
956 bool value = g_settings->getBool(name);
957 lua_pushboolean(L, value);
958 } catch(SettingNotFoundException &e){
964 // chat_send_all(text)
965 static int l_chat_send_all(lua_State *L)
967 const char *text = luaL_checkstring(L, 1);
968 // Get server from registry
969 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
970 Server *server = (Server*)lua_touserdata(L, -1);
972 server->notifyPlayers(narrow_to_wide(text));
976 // chat_send_player(name, text)
977 static int l_chat_send_player(lua_State *L)
979 const char *name = luaL_checkstring(L, 1);
980 const char *text = luaL_checkstring(L, 2);
981 // Get server from registry
982 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
983 Server *server = (Server*)lua_touserdata(L, -1);
985 server->notifyPlayer(name, narrow_to_wide(text));
989 static const struct luaL_Reg minetest_f [] = {
990 {"register_nodedef_defaults", l_register_nodedef_defaults},
991 {"register_entity", l_register_entity},
992 {"register_tool", l_register_tool},
993 {"register_node", l_register_node},
994 {"register_craft", l_register_craft},
995 {"register_abm", l_register_abm},
996 {"setting_get", l_setting_get},
997 {"setting_getbool", l_setting_getbool},
998 {"chat_send_all", l_chat_send_all},
999 {"chat_send_player", l_chat_send_player},
1007 static const struct luaL_Reg minetest_entity_m [] = {
1012 Getters for stuff in main tables
1015 static void objectref_get(lua_State *L, u16 id)
1017 // Get minetest.object_refs[i]
1018 lua_getglobal(L, "minetest");
1019 lua_getfield(L, -1, "object_refs");
1020 luaL_checktype(L, -1, LUA_TTABLE);
1021 lua_pushnumber(L, id);
1022 lua_gettable(L, -2);
1023 lua_remove(L, -2); // object_refs
1024 lua_remove(L, -2); // minetest
1027 static void luaentity_get(lua_State *L, u16 id)
1029 // Get minetest.luaentities[i]
1030 lua_getglobal(L, "minetest");
1031 lua_getfield(L, -1, "luaentities");
1032 luaL_checktype(L, -1, LUA_TTABLE);
1033 lua_pushnumber(L, id);
1034 lua_gettable(L, -2);
1035 lua_remove(L, -2); // luaentities
1036 lua_remove(L, -2); // minetest
1043 #define method(class, name) {#name, class::l_##name}
1053 ServerEnvironment *m_env;
1055 static const char className[];
1056 static const luaL_reg methods[];
1058 static NodeMetaRef *checkobject(lua_State *L, int narg)
1060 luaL_checktype(L, narg, LUA_TUSERDATA);
1061 void *ud = luaL_checkudata(L, narg, className);
1062 if(!ud) luaL_typerror(L, narg, className);
1063 return *(NodeMetaRef**)ud; // unbox pointer
1066 static NodeMetadata* getmeta(NodeMetaRef *ref)
1068 NodeMetadata *meta = ref->m_env->getMap().getNodeMetadata(ref->m_p);
1072 static void reportMetadataChange(NodeMetaRef *ref)
1074 // Inform other things that the metadata has changed
1075 v3s16 blockpos = getNodeBlockPos(ref->m_p);
1077 event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
1079 ref->m_env->getMap().dispatchEvent(&event);
1080 // Set the block to be saved
1081 MapBlock *block = ref->m_env->getMap().getBlockNoCreateNoEx(blockpos);
1083 block->raiseModified(MOD_STATE_WRITE_NEEDED, "l_settext");
1086 // Exported functions
1088 // garbage collector
1089 static int gc_object(lua_State *L) {
1090 NodeMetaRef *o = *(NodeMetaRef **)(lua_touserdata(L, 1));
1095 // settext(self, text)
1096 static int l_settext(lua_State *L)
1098 NodeMetaRef *ref = checkobject(L, 1);
1099 NodeMetadata *meta = getmeta(ref);
1100 if(meta == NULL) return 0;
1102 std::string text = lua_tostring(L, 2);
1103 meta->setText(text);
1104 // Inform other things that the metadata has changed
1105 reportMetadataChange(ref);
1110 NodeMetaRef(v3s16 p, ServerEnvironment *env):
1120 // Creates an NodeMetaRef and leaves it on top of stack
1121 // Not callable from Lua; all references are created on the C side.
1122 static void create(lua_State *L, v3s16 p, ServerEnvironment *env)
1124 NodeMetaRef *o = new NodeMetaRef(p, env);
1125 //infostream<<"NodeMetaRef::create: o="<<o<<std::endl;
1126 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1127 luaL_getmetatable(L, className);
1128 lua_setmetatable(L, -2);
1131 static void Register(lua_State *L)
1134 int methodtable = lua_gettop(L);
1135 luaL_newmetatable(L, className);
1136 int metatable = lua_gettop(L);
1138 lua_pushliteral(L, "__metatable");
1139 lua_pushvalue(L, methodtable);
1140 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
1142 lua_pushliteral(L, "__index");
1143 lua_pushvalue(L, methodtable);
1144 lua_settable(L, metatable);
1146 lua_pushliteral(L, "__gc");
1147 lua_pushcfunction(L, gc_object);
1148 lua_settable(L, metatable);
1150 lua_pop(L, 1); // drop metatable
1152 luaL_openlib(L, 0, methods, 0); // fill methodtable
1153 lua_pop(L, 1); // drop methodtable
1155 // Cannot be created from Lua
1156 //lua_register(L, className, create_object);
1159 const char NodeMetaRef::className[] = "NodeMetaRef";
1160 const luaL_reg NodeMetaRef::methods[] = {
1161 method(NodeMetaRef, settext),
1172 ServerEnvironment *m_env;
1174 static const char className[];
1175 static const luaL_reg methods[];
1177 static EnvRef *checkobject(lua_State *L, int narg)
1179 luaL_checktype(L, narg, LUA_TUSERDATA);
1180 void *ud = luaL_checkudata(L, narg, className);
1181 if(!ud) luaL_typerror(L, narg, className);
1182 return *(EnvRef**)ud; // unbox pointer
1185 // Exported functions
1187 // EnvRef:add_node(pos, node)
1188 // pos = {x=num, y=num, z=num}
1189 static int l_add_node(lua_State *L)
1191 infostream<<"EnvRef::l_add_node()"<<std::endl;
1192 EnvRef *o = checkobject(L, 1);
1193 ServerEnvironment *env = o->m_env;
1194 if(env == NULL) return 0;
1196 v3s16 pos = readpos(L, 2);
1198 MapNode n = readnode(L, 3, env->getGameDef()->ndef());
1200 bool succeeded = env->getMap().addNodeWithEvent(pos, n);
1201 lua_pushboolean(L, succeeded);
1205 // EnvRef:remove_node(pos)
1206 // pos = {x=num, y=num, z=num}
1207 static int l_remove_node(lua_State *L)
1209 infostream<<"EnvRef::l_remove_node()"<<std::endl;
1210 EnvRef *o = checkobject(L, 1);
1211 ServerEnvironment *env = o->m_env;
1212 if(env == NULL) return 0;
1214 v3s16 pos = readpos(L, 2);
1216 bool succeeded = env->getMap().removeNodeWithEvent(pos);
1217 lua_pushboolean(L, succeeded);
1221 // EnvRef:get_node(pos)
1222 // pos = {x=num, y=num, z=num}
1223 static int l_get_node(lua_State *L)
1225 infostream<<"EnvRef::l_get_node()"<<std::endl;
1226 EnvRef *o = checkobject(L, 1);
1227 ServerEnvironment *env = o->m_env;
1228 if(env == NULL) return 0;
1230 v3s16 pos = readpos(L, 2);
1232 MapNode n = env->getMap().getNodeNoEx(pos);
1234 pushnode(L, n, env->getGameDef()->ndef());
1238 // EnvRef:add_luaentity(pos, entityname)
1239 // pos = {x=num, y=num, z=num}
1240 static int l_add_luaentity(lua_State *L)
1242 infostream<<"EnvRef::l_add_luaentity()"<<std::endl;
1243 EnvRef *o = checkobject(L, 1);
1244 ServerEnvironment *env = o->m_env;
1245 if(env == NULL) return 0;
1247 v3f pos = readFloatPos(L, 2);
1249 const char *name = lua_tostring(L, 3);
1251 ServerActiveObject *obj = new LuaEntitySAO(env, pos, name, "");
1252 env->addActiveObject(obj);
1256 // EnvRef:get_meta(pos)
1257 static int l_get_meta(lua_State *L)
1259 infostream<<"EnvRef::l_get_meta()"<<std::endl;
1260 EnvRef *o = checkobject(L, 1);
1261 ServerEnvironment *env = o->m_env;
1262 if(env == NULL) return 0;
1264 v3s16 p = readpos(L, 2);
1265 NodeMetaRef::create(L, p, env);
1269 static int gc_object(lua_State *L) {
1270 EnvRef *o = *(EnvRef **)(lua_touserdata(L, 1));
1276 EnvRef(ServerEnvironment *env):
1279 infostream<<"EnvRef created"<<std::endl;
1284 infostream<<"EnvRef destructing"<<std::endl;
1287 // Creates an EnvRef and leaves it on top of stack
1288 // Not callable from Lua; all references are created on the C side.
1289 static void create(lua_State *L, ServerEnvironment *env)
1291 EnvRef *o = new EnvRef(env);
1292 //infostream<<"EnvRef::create: o="<<o<<std::endl;
1293 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1294 luaL_getmetatable(L, className);
1295 lua_setmetatable(L, -2);
1298 static void set_null(lua_State *L)
1300 EnvRef *o = checkobject(L, -1);
1304 static void Register(lua_State *L)
1307 int methodtable = lua_gettop(L);
1308 luaL_newmetatable(L, className);
1309 int metatable = lua_gettop(L);
1311 lua_pushliteral(L, "__metatable");
1312 lua_pushvalue(L, methodtable);
1313 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
1315 lua_pushliteral(L, "__index");
1316 lua_pushvalue(L, methodtable);
1317 lua_settable(L, metatable);
1319 lua_pushliteral(L, "__gc");
1320 lua_pushcfunction(L, gc_object);
1321 lua_settable(L, metatable);
1323 lua_pop(L, 1); // drop metatable
1325 luaL_openlib(L, 0, methods, 0); // fill methodtable
1326 lua_pop(L, 1); // drop methodtable
1328 // Cannot be created from Lua
1329 //lua_register(L, className, create_object);
1332 const char EnvRef::className[] = "EnvRef";
1333 const luaL_reg EnvRef::methods[] = {
1334 method(EnvRef, add_node),
1335 method(EnvRef, remove_node),
1336 method(EnvRef, get_node),
1337 method(EnvRef, add_luaentity),
1338 method(EnvRef, get_meta),
1349 ServerActiveObject *m_object;
1351 static const char className[];
1352 static const luaL_reg methods[];
1354 static ObjectRef *checkobject(lua_State *L, int narg)
1356 luaL_checktype(L, narg, LUA_TUSERDATA);
1357 void *ud = luaL_checkudata(L, narg, className);
1358 if(!ud) luaL_typerror(L, narg, className);
1359 return *(ObjectRef**)ud; // unbox pointer
1362 static ServerActiveObject* getobject(ObjectRef *ref)
1364 ServerActiveObject *co = ref->m_object;
1368 static LuaEntitySAO* getluaobject(ObjectRef *ref)
1370 ServerActiveObject *obj = getobject(ref);
1373 if(obj->getType() != ACTIVEOBJECT_TYPE_LUAENTITY)
1375 return (LuaEntitySAO*)obj;
1378 // Exported functions
1380 // garbage collector
1381 static int gc_object(lua_State *L) {
1382 ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
1383 //infostream<<"ObjectRef::gc_object: o="<<o<<std::endl;
1389 static int l_remove(lua_State *L)
1391 ObjectRef *ref = checkobject(L, 1);
1392 ServerActiveObject *co = getobject(ref);
1393 if(co == NULL) return 0;
1394 infostream<<"ObjectRef::l_remove(): id="<<co->getId()<<std::endl;
1395 co->m_removed = true;
1400 // returns: {x=num, y=num, z=num}
1401 static int l_getpos(lua_State *L)
1403 ObjectRef *ref = checkobject(L, 1);
1404 ServerActiveObject *co = getobject(ref);
1405 if(co == NULL) return 0;
1406 v3f pos = co->getBasePosition() / BS;
1408 lua_pushnumber(L, pos.X);
1409 lua_setfield(L, -2, "x");
1410 lua_pushnumber(L, pos.Y);
1411 lua_setfield(L, -2, "y");
1412 lua_pushnumber(L, pos.Z);
1413 lua_setfield(L, -2, "z");
1417 // setpos(self, pos)
1418 static int l_setpos(lua_State *L)
1420 ObjectRef *ref = checkobject(L, 1);
1421 //LuaEntitySAO *co = getluaobject(ref);
1422 ServerActiveObject *co = getobject(ref);
1423 if(co == NULL) return 0;
1425 v3f pos = readFloatPos(L, 2);
1431 // moveto(self, pos, continuous=false)
1432 static int l_moveto(lua_State *L)
1434 ObjectRef *ref = checkobject(L, 1);
1435 //LuaEntitySAO *co = getluaobject(ref);
1436 ServerActiveObject *co = getobject(ref);
1437 if(co == NULL) return 0;
1439 v3f pos = readFloatPos(L, 2);
1441 bool continuous = lua_toboolean(L, 3);
1443 co->moveTo(pos, continuous);
1447 // setvelocity(self, velocity)
1448 static int l_setvelocity(lua_State *L)
1450 ObjectRef *ref = checkobject(L, 1);
1451 LuaEntitySAO *co = getluaobject(ref);
1452 if(co == NULL) return 0;
1454 v3f pos = readFloatPos(L, 2);
1456 co->setVelocity(pos);
1460 // setacceleration(self, acceleration)
1461 static int l_setacceleration(lua_State *L)
1463 ObjectRef *ref = checkobject(L, 1);
1464 LuaEntitySAO *co = getluaobject(ref);
1465 if(co == NULL) return 0;
1467 v3f pos = readFloatPos(L, 2);
1469 co->setAcceleration(pos);
1473 // getacceleration(self)
1474 static int l_getacceleration(lua_State *L)
1476 ObjectRef *ref = checkobject(L, 1);
1477 LuaEntitySAO *co = getluaobject(ref);
1478 if(co == NULL) return 0;
1480 v3f v = co->getAcceleration();
1485 // add_to_inventory(self, itemstring)
1486 // returns: true if item was added, false otherwise
1487 static int l_add_to_inventory(lua_State *L)
1489 ObjectRef *ref = checkobject(L, 1);
1490 luaL_checkstring(L, 2);
1491 ServerActiveObject *co = getobject(ref);
1492 if(co == NULL) return 0;
1494 const char *itemstring = lua_tostring(L, 2);
1495 infostream<<"ObjectRef::l_add_to_inventory(): id="<<co->getId()
1496 <<" itemstring=\""<<itemstring<<"\""<<std::endl;
1498 std::istringstream is(itemstring, std::ios::binary);
1499 ServerEnvironment *env = co->getEnv();
1501 IGameDef *gamedef = env->getGameDef();
1502 InventoryItem *item = InventoryItem::deSerialize(is, gamedef);
1503 infostream<<"item="<<env<<std::endl;
1504 bool fits = co->addToInventory(item);
1506 lua_pushboolean(L, fits);
1510 // settexturemod(self, mod)
1511 static int l_settexturemod(lua_State *L)
1513 ObjectRef *ref = checkobject(L, 1);
1514 LuaEntitySAO *co = getluaobject(ref);
1515 if(co == NULL) return 0;
1517 std::string mod = lua_tostring(L, 2);
1518 co->setTextureMod(mod);
1522 // setsprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2,
1523 // select_horiz_by_yawpitch=false)
1524 static int l_setsprite(lua_State *L)
1526 ObjectRef *ref = checkobject(L, 1);
1527 LuaEntitySAO *co = getluaobject(ref);
1528 if(co == NULL) return 0;
1531 if(!lua_isnil(L, 2))
1532 p = read_v2s16(L, 2);
1534 if(!lua_isnil(L, 3))
1535 num_frames = lua_tonumber(L, 3);
1536 float framelength = 0.2;
1537 if(!lua_isnil(L, 4))
1538 framelength = lua_tonumber(L, 4);
1539 bool select_horiz_by_yawpitch = false;
1540 if(!lua_isnil(L, 5))
1541 select_horiz_by_yawpitch = lua_toboolean(L, 5);
1542 co->setSprite(p, num_frames, framelength, select_horiz_by_yawpitch);
1547 ObjectRef(ServerActiveObject *object):
1550 //infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
1556 infostream<<"ObjectRef destructing for id="
1557 <<m_object->getId()<<std::endl;
1559 infostream<<"ObjectRef destructing for id=unknown"<<std::endl;*/
1562 // Creates an ObjectRef and leaves it on top of stack
1563 // Not callable from Lua; all references are created on the C side.
1564 static void create(lua_State *L, ServerActiveObject *object)
1566 ObjectRef *o = new ObjectRef(object);
1567 //infostream<<"ObjectRef::create: o="<<o<<std::endl;
1568 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1569 luaL_getmetatable(L, className);
1570 lua_setmetatable(L, -2);
1573 static void set_null(lua_State *L)
1575 ObjectRef *o = checkobject(L, -1);
1579 static void Register(lua_State *L)
1582 int methodtable = lua_gettop(L);
1583 luaL_newmetatable(L, className);
1584 int metatable = lua_gettop(L);
1586 lua_pushliteral(L, "__metatable");
1587 lua_pushvalue(L, methodtable);
1588 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
1590 lua_pushliteral(L, "__index");
1591 lua_pushvalue(L, methodtable);
1592 lua_settable(L, metatable);
1594 lua_pushliteral(L, "__gc");
1595 lua_pushcfunction(L, gc_object);
1596 lua_settable(L, metatable);
1598 lua_pop(L, 1); // drop metatable
1600 luaL_openlib(L, 0, methods, 0); // fill methodtable
1601 lua_pop(L, 1); // drop methodtable
1603 // Cannot be created from Lua
1604 //lua_register(L, className, create_object);
1607 const char ObjectRef::className[] = "ObjectRef";
1608 const luaL_reg ObjectRef::methods[] = {
1609 method(ObjectRef, remove),
1610 method(ObjectRef, getpos),
1611 method(ObjectRef, setpos),
1612 method(ObjectRef, moveto),
1613 method(ObjectRef, setvelocity),
1614 method(ObjectRef, setacceleration),
1615 method(ObjectRef, add_to_inventory),
1616 method(ObjectRef, settexturemod),
1617 method(ObjectRef, setsprite),
1621 // Creates a new anonymous reference if id=0
1622 static void objectref_get_or_create(lua_State *L,
1623 ServerActiveObject *cobj)
1625 if(cobj->getId() == 0){
1626 ObjectRef::create(L, cobj);
1628 objectref_get(L, cobj->getId());
1633 Main export function
1636 void scriptapi_export(lua_State *L, Server *server)
1639 assert(lua_checkstack(L, 20));
1640 infostream<<"scriptapi_export"<<std::endl;
1641 StackUnroller stack_unroller(L);
1643 // Store server as light userdata in registry
1644 lua_pushlightuserdata(L, server);
1645 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_server");
1647 // Store nil as minetest_nodedef_defaults in registry
1649 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
1651 // Register global functions in table minetest
1653 luaL_register(L, NULL, minetest_f);
1654 lua_setglobal(L, "minetest");
1656 // Get the main minetest table
1657 lua_getglobal(L, "minetest");
1659 // Add tables to minetest
1662 lua_setfield(L, -2, "registered_nodes");
1664 lua_setfield(L, -2, "registered_entities");
1666 lua_setfield(L, -2, "registered_abms");
1669 lua_setfield(L, -2, "object_refs");
1671 lua_setfield(L, -2, "luaentities");
1673 // Create entity prototype
1674 luaL_newmetatable(L, "minetest.entity");
1675 // metatable.__index = metatable
1676 lua_pushvalue(L, -1); // Duplicate metatable
1677 lua_setfield(L, -2, "__index");
1678 // Put functions in metatable
1679 luaL_register(L, NULL, minetest_entity_m);
1680 // Put other stuff in metatable
1682 // Register reference wrappers
1683 NodeMetaRef::Register(L);
1684 EnvRef::Register(L);
1685 ObjectRef::Register(L);
1688 void scriptapi_add_environment(lua_State *L, ServerEnvironment *env)
1691 assert(lua_checkstack(L, 20));
1692 infostream<<"scriptapi_add_environment"<<std::endl;
1693 StackUnroller stack_unroller(L);
1695 // Create EnvRef on stack
1696 EnvRef::create(L, env);
1697 int envref = lua_gettop(L);
1699 // minetest.env = envref
1700 lua_getglobal(L, "minetest");
1701 luaL_checktype(L, -1, LUA_TTABLE);
1702 lua_pushvalue(L, envref);
1703 lua_setfield(L, -2, "env");
1705 // Store environment as light userdata in registry
1706 lua_pushlightuserdata(L, env);
1707 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_env");
1709 /* Add ActiveBlockModifiers to environment */
1711 // Get minetest.registered_abms
1712 lua_getglobal(L, "minetest");
1713 lua_getfield(L, -1, "registered_abms");
1714 luaL_checktype(L, -1, LUA_TTABLE);
1715 int registered_abms = lua_gettop(L);
1717 if(lua_istable(L, registered_abms)){
1718 int table = lua_gettop(L);
1720 while(lua_next(L, table) != 0){
1721 // key at index -2 and value at index -1
1722 int id = lua_tonumber(L, -2);
1723 int current_abm = lua_gettop(L);
1725 std::set<std::string> trigger_contents;
1726 lua_getfield(L, current_abm, "nodenames");
1727 if(lua_istable(L, -1)){
1728 int table = lua_gettop(L);
1730 while(lua_next(L, table) != 0){
1731 // key at index -2 and value at index -1
1732 luaL_checktype(L, -1, LUA_TSTRING);
1733 trigger_contents.insert(lua_tostring(L, -1));
1734 // removes value, keeps key for next iteration
1740 float trigger_interval = 10.0;
1741 getfloatfield(L, current_abm, "interval", trigger_interval);
1743 int trigger_chance = 50;
1744 getintfield(L, current_abm, "chance", trigger_chance);
1746 LuaABM *abm = new LuaABM(L, id, trigger_contents,
1747 trigger_interval, trigger_chance);
1749 env->addActiveBlockModifier(abm);
1751 // removes value, keeps key for next iteration
1759 // Dump stack top with the dump2 function
1760 static void dump2(lua_State *L, const char *name)
1762 // Dump object (debug)
1763 lua_getglobal(L, "dump2");
1764 luaL_checktype(L, -1, LUA_TFUNCTION);
1765 lua_pushvalue(L, -2); // Get previous stack top as first parameter
1766 lua_pushstring(L, name);
1767 if(lua_pcall(L, 2, 0, 0))
1768 script_error(L, "error: %s\n", lua_tostring(L, -1));
1776 void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj)
1779 assert(lua_checkstack(L, 20));
1780 infostream<<"scriptapi_add_object_reference: id="<<cobj->getId()<<std::endl;
1781 StackUnroller stack_unroller(L);
1783 // Create object on stack
1784 ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack
1785 int object = lua_gettop(L);
1787 // Get minetest.object_refs table
1788 lua_getglobal(L, "minetest");
1789 lua_getfield(L, -1, "object_refs");
1790 luaL_checktype(L, -1, LUA_TTABLE);
1791 int objectstable = lua_gettop(L);
1793 // object_refs[id] = object
1794 lua_pushnumber(L, cobj->getId()); // Push id
1795 lua_pushvalue(L, object); // Copy object to top of stack
1796 lua_settable(L, objectstable);
1799 void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj)
1802 assert(lua_checkstack(L, 20));
1803 infostream<<"scriptapi_rm_object_reference: id="<<cobj->getId()<<std::endl;
1804 StackUnroller stack_unroller(L);
1806 // Get minetest.object_refs table
1807 lua_getglobal(L, "minetest");
1808 lua_getfield(L, -1, "object_refs");
1809 luaL_checktype(L, -1, LUA_TTABLE);
1810 int objectstable = lua_gettop(L);
1812 // Get object_refs[id]
1813 lua_pushnumber(L, cobj->getId()); // Push id
1814 lua_gettable(L, objectstable);
1815 // Set object reference to NULL
1816 ObjectRef::set_null(L);
1817 lua_pop(L, 1); // pop object
1819 // Set object_refs[id] = nil
1820 lua_pushnumber(L, cobj->getId()); // Push id
1822 lua_settable(L, objectstable);
1825 bool scriptapi_on_chat_message(lua_State *L, const std::string &name,
1826 const std::string &message)
1829 assert(lua_checkstack(L, 20));
1830 StackUnroller stack_unroller(L);
1832 // Get minetest.registered_on_chat_messages
1833 lua_getglobal(L, "minetest");
1834 lua_getfield(L, -1, "registered_on_chat_messages");
1835 luaL_checktype(L, -1, LUA_TTABLE);
1836 int table = lua_gettop(L);
1839 while(lua_next(L, table) != 0){
1840 // key at index -2 and value at index -1
1841 luaL_checktype(L, -1, LUA_TFUNCTION);
1843 lua_pushstring(L, name.c_str());
1844 lua_pushstring(L, message.c_str());
1845 if(lua_pcall(L, 2, 1, 0))
1846 script_error(L, "error: %s\n", lua_tostring(L, -1));
1847 bool ate = lua_toboolean(L, -1);
1851 // value removed, keep key for next iteration
1860 void scriptapi_on_newplayer(lua_State *L, ServerActiveObject *player)
1863 assert(lua_checkstack(L, 20));
1864 StackUnroller stack_unroller(L);
1866 // Get minetest.registered_on_newplayers
1867 lua_getglobal(L, "minetest");
1868 lua_getfield(L, -1, "registered_on_newplayers");
1869 luaL_checktype(L, -1, LUA_TTABLE);
1870 int table = lua_gettop(L);
1873 while(lua_next(L, table) != 0){
1874 // key at index -2 and value at index -1
1875 luaL_checktype(L, -1, LUA_TFUNCTION);
1877 objectref_get_or_create(L, player);
1878 if(lua_pcall(L, 1, 0, 0))
1879 script_error(L, "error: %s\n", lua_tostring(L, -1));
1880 // value removed, keep key for next iteration
1883 bool scriptapi_on_respawnplayer(lua_State *L, ServerActiveObject *player)
1886 assert(lua_checkstack(L, 20));
1887 StackUnroller stack_unroller(L);
1889 bool positioning_handled_by_some = false;
1891 // Get minetest.registered_on_respawnplayers
1892 lua_getglobal(L, "minetest");
1893 lua_getfield(L, -1, "registered_on_respawnplayers");
1894 luaL_checktype(L, -1, LUA_TTABLE);
1895 int table = lua_gettop(L);
1898 while(lua_next(L, table) != 0){
1899 // key at index -2 and value at index -1
1900 luaL_checktype(L, -1, LUA_TFUNCTION);
1902 objectref_get_or_create(L, player);
1903 if(lua_pcall(L, 1, 1, 0))
1904 script_error(L, "error: %s\n", lua_tostring(L, -1));
1905 bool positioning_handled = lua_toboolean(L, -1);
1907 if(positioning_handled)
1908 positioning_handled_by_some = true;
1909 // value removed, keep key for next iteration
1911 return positioning_handled_by_some;
1918 void scriptapi_environment_step(lua_State *L, float dtime)
1921 assert(lua_checkstack(L, 20));
1922 //infostream<<"scriptapi_environment_step"<<std::endl;
1923 StackUnroller stack_unroller(L);
1925 // Get minetest.registered_globalsteps
1926 lua_getglobal(L, "minetest");
1927 lua_getfield(L, -1, "registered_globalsteps");
1928 luaL_checktype(L, -1, LUA_TTABLE);
1929 int table = lua_gettop(L);
1932 while(lua_next(L, table) != 0){
1933 // key at index -2 and value at index -1
1934 luaL_checktype(L, -1, LUA_TFUNCTION);
1936 lua_pushnumber(L, dtime);
1937 if(lua_pcall(L, 1, 0, 0))
1938 script_error(L, "error: %s\n", lua_tostring(L, -1));
1939 // value removed, keep key for next iteration
1943 void scriptapi_environment_on_placenode(lua_State *L, v3s16 p, MapNode newnode,
1944 ServerActiveObject *placer)
1947 assert(lua_checkstack(L, 20));
1948 //infostream<<"scriptapi_environment_on_placenode"<<std::endl;
1949 StackUnroller stack_unroller(L);
1951 // Get server from registry
1952 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1953 Server *server = (Server*)lua_touserdata(L, -1);
1954 // And get the writable node definition manager from the server
1955 IWritableNodeDefManager *ndef =
1956 server->getWritableNodeDefManager();
1958 // Get minetest.registered_on_placenodes
1959 lua_getglobal(L, "minetest");
1960 lua_getfield(L, -1, "registered_on_placenodes");
1961 luaL_checktype(L, -1, LUA_TTABLE);
1962 int table = lua_gettop(L);
1965 while(lua_next(L, table) != 0){
1966 // key at index -2 and value at index -1
1967 luaL_checktype(L, -1, LUA_TFUNCTION);
1970 pushnode(L, newnode, ndef);
1971 objectref_get_or_create(L, placer);
1972 if(lua_pcall(L, 3, 0, 0))
1973 script_error(L, "error: %s\n", lua_tostring(L, -1));
1974 // value removed, keep key for next iteration
1978 void scriptapi_environment_on_dignode(lua_State *L, v3s16 p, MapNode oldnode,
1979 ServerActiveObject *digger)
1982 assert(lua_checkstack(L, 20));
1983 //infostream<<"scriptapi_environment_on_dignode"<<std::endl;
1984 StackUnroller stack_unroller(L);
1986 // Get server from registry
1987 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1988 Server *server = (Server*)lua_touserdata(L, -1);
1989 // And get the writable node definition manager from the server
1990 IWritableNodeDefManager *ndef =
1991 server->getWritableNodeDefManager();
1993 // Get minetest.registered_on_dignodes
1994 lua_getglobal(L, "minetest");
1995 lua_getfield(L, -1, "registered_on_dignodes");
1996 luaL_checktype(L, -1, LUA_TTABLE);
1997 int table = lua_gettop(L);
2000 while(lua_next(L, table) != 0){
2001 // key at index -2 and value at index -1
2002 luaL_checktype(L, -1, LUA_TFUNCTION);
2005 pushnode(L, oldnode, ndef);
2006 objectref_get_or_create(L, digger);
2007 if(lua_pcall(L, 3, 0, 0))
2008 script_error(L, "error: %s\n", lua_tostring(L, -1));
2009 // value removed, keep key for next iteration
2013 void scriptapi_environment_on_punchnode(lua_State *L, v3s16 p, MapNode node,
2014 ServerActiveObject *puncher)
2017 assert(lua_checkstack(L, 20));
2018 //infostream<<"scriptapi_environment_on_punchnode"<<std::endl;
2019 StackUnroller stack_unroller(L);
2021 // Get server from registry
2022 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
2023 Server *server = (Server*)lua_touserdata(L, -1);
2024 // And get the writable node definition manager from the server
2025 IWritableNodeDefManager *ndef =
2026 server->getWritableNodeDefManager();
2028 // Get minetest.registered_on_punchnodes
2029 lua_getglobal(L, "minetest");
2030 lua_getfield(L, -1, "registered_on_punchnodes");
2031 luaL_checktype(L, -1, LUA_TTABLE);
2032 int table = lua_gettop(L);
2035 while(lua_next(L, table) != 0){
2036 // key at index -2 and value at index -1
2037 luaL_checktype(L, -1, LUA_TFUNCTION);
2040 pushnode(L, node, ndef);
2041 objectref_get_or_create(L, puncher);
2042 if(lua_pcall(L, 3, 0, 0))
2043 script_error(L, "error: %s\n", lua_tostring(L, -1));
2044 // value removed, keep key for next iteration
2048 void scriptapi_environment_on_generated(lua_State *L, v3s16 minp, v3s16 maxp)
2051 assert(lua_checkstack(L, 20));
2052 //infostream<<"scriptapi_environment_on_generated"<<std::endl;
2053 StackUnroller stack_unroller(L);
2055 // Get minetest.registered_on_generateds
2056 lua_getglobal(L, "minetest");
2057 lua_getfield(L, -1, "registered_on_generateds");
2058 luaL_checktype(L, -1, LUA_TTABLE);
2059 int table = lua_gettop(L);
2062 while(lua_next(L, table) != 0){
2063 // key at index -2 and value at index -1
2064 luaL_checktype(L, -1, LUA_TFUNCTION);
2068 if(lua_pcall(L, 2, 0, 0))
2069 script_error(L, "error: %s\n", lua_tostring(L, -1));
2070 // value removed, keep key for next iteration
2078 bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
2079 const std::string &staticdata)
2082 assert(lua_checkstack(L, 20));
2083 infostream<<"scriptapi_luaentity_add: id="<<id<<" name=\""
2084 <<name<<"\""<<std::endl;
2085 StackUnroller stack_unroller(L);
2087 // Get minetest.registered_entities[name]
2088 lua_getglobal(L, "minetest");
2089 lua_getfield(L, -1, "registered_entities");
2090 luaL_checktype(L, -1, LUA_TTABLE);
2091 lua_pushstring(L, name);
2092 lua_gettable(L, -2);
2093 // Should be a table, which we will use as a prototype
2094 //luaL_checktype(L, -1, LUA_TTABLE);
2095 if(lua_type(L, -1) != LUA_TTABLE){
2096 errorstream<<"LuaEntity name \""<<name<<"\" not defined"<<std::endl;
2099 int prototype_table = lua_gettop(L);
2100 //dump2(L, "prototype_table");
2102 // Create entity object
2104 int object = lua_gettop(L);
2106 // Set object metatable
2107 lua_pushvalue(L, prototype_table);
2108 lua_setmetatable(L, -2);
2110 // Add object reference
2111 // This should be userdata with metatable ObjectRef
2112 objectref_get(L, id);
2113 luaL_checktype(L, -1, LUA_TUSERDATA);
2114 if(!luaL_checkudata(L, -1, "ObjectRef"))
2115 luaL_typerror(L, -1, "ObjectRef");
2116 lua_setfield(L, -2, "object");
2118 // minetest.luaentities[id] = object
2119 lua_getglobal(L, "minetest");
2120 lua_getfield(L, -1, "luaentities");
2121 luaL_checktype(L, -1, LUA_TTABLE);
2122 lua_pushnumber(L, id); // Push id
2123 lua_pushvalue(L, object); // Copy object to top of stack
2124 lua_settable(L, -3);
2126 // Get on_activate function
2127 lua_pushvalue(L, object);
2128 lua_getfield(L, -1, "on_activate");
2129 if(!lua_isnil(L, -1)){
2130 luaL_checktype(L, -1, LUA_TFUNCTION);
2131 lua_pushvalue(L, object); // self
2132 lua_pushlstring(L, staticdata.c_str(), staticdata.size());
2133 // Call with 2 arguments, 0 results
2134 if(lua_pcall(L, 2, 0, 0))
2135 script_error(L, "error running function %s:on_activate: %s\n",
2136 name, lua_tostring(L, -1));
2142 void scriptapi_luaentity_rm(lua_State *L, u16 id)
2145 assert(lua_checkstack(L, 20));
2146 infostream<<"scriptapi_luaentity_rm: id="<<id<<std::endl;
2148 // Get minetest.luaentities table
2149 lua_getglobal(L, "minetest");
2150 lua_getfield(L, -1, "luaentities");
2151 luaL_checktype(L, -1, LUA_TTABLE);
2152 int objectstable = lua_gettop(L);
2154 // Set luaentities[id] = nil
2155 lua_pushnumber(L, id); // Push id
2157 lua_settable(L, objectstable);
2159 lua_pop(L, 2); // pop luaentities, minetest
2162 std::string scriptapi_luaentity_get_staticdata(lua_State *L, u16 id)
2165 assert(lua_checkstack(L, 20));
2166 infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl;
2167 StackUnroller stack_unroller(L);
2169 // Get minetest.luaentities[id]
2170 luaentity_get(L, id);
2171 int object = lua_gettop(L);
2173 // Get get_staticdata function
2174 lua_pushvalue(L, object);
2175 lua_getfield(L, -1, "get_staticdata");
2176 if(lua_isnil(L, -1))
2179 luaL_checktype(L, -1, LUA_TFUNCTION);
2180 lua_pushvalue(L, object); // self
2181 // Call with 1 arguments, 1 results
2182 if(lua_pcall(L, 1, 1, 0))
2183 script_error(L, "error running function get_staticdata: %s\n",
2184 lua_tostring(L, -1));
2187 const char *s = lua_tolstring(L, -1, &len);
2188 return std::string(s, len);
2191 void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
2192 LuaEntityProperties *prop)
2195 assert(lua_checkstack(L, 20));
2196 infostream<<"scriptapi_luaentity_get_properties: id="<<id<<std::endl;
2197 StackUnroller stack_unroller(L);
2199 // Get minetest.luaentities[id]
2200 luaentity_get(L, id);
2201 //int object = lua_gettop(L);
2205 getboolfield(L, -1, "physical", prop->physical);
2207 getfloatfield(L, -1, "weight", prop->weight);
2209 lua_getfield(L, -1, "collisionbox");
2210 if(lua_istable(L, -1))
2211 prop->collisionbox = read_aabbox3df32(L, -1, 1.0);
2214 getstringfield(L, -1, "visual", prop->visual);
2216 lua_getfield(L, -1, "visual_size");
2217 if(lua_istable(L, -1))
2218 prop->visual_size = read_v2f(L, -1);
2221 lua_getfield(L, -1, "textures");
2222 if(lua_istable(L, -1)){
2223 prop->textures.clear();
2224 int table = lua_gettop(L);
2226 while(lua_next(L, table) != 0){
2227 // key at index -2 and value at index -1
2228 if(lua_isstring(L, -1))
2229 prop->textures.push_back(lua_tostring(L, -1));
2231 prop->textures.push_back("");
2232 // removes value, keeps key for next iteration
2238 lua_getfield(L, -1, "spritediv");
2239 if(lua_istable(L, -1))
2240 prop->spritediv = read_v2s16(L, -1);
2243 lua_getfield(L, -1, "initial_sprite_basepos");
2244 if(lua_istable(L, -1))
2245 prop->initial_sprite_basepos = read_v2s16(L, -1);
2249 void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime)
2252 assert(lua_checkstack(L, 20));
2253 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
2254 StackUnroller stack_unroller(L);
2256 // Get minetest.luaentities[id]
2257 luaentity_get(L, id);
2258 int object = lua_gettop(L);
2259 // State: object is at top of stack
2260 // Get step function
2261 lua_getfield(L, -1, "on_step");
2262 if(lua_isnil(L, -1))
2264 luaL_checktype(L, -1, LUA_TFUNCTION);
2265 lua_pushvalue(L, object); // self
2266 lua_pushnumber(L, dtime); // dtime
2267 // Call with 2 arguments, 0 results
2268 if(lua_pcall(L, 2, 0, 0))
2269 script_error(L, "error running function 'on_step': %s\n", lua_tostring(L, -1));
2272 // Calls entity:on_punch(ObjectRef puncher)
2273 void scriptapi_luaentity_punch(lua_State *L, u16 id,
2274 ServerActiveObject *puncher)
2277 assert(lua_checkstack(L, 20));
2278 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
2279 StackUnroller stack_unroller(L);
2281 // Get minetest.luaentities[id]
2282 luaentity_get(L, id);
2283 int object = lua_gettop(L);
2284 // State: object is at top of stack
2286 lua_getfield(L, -1, "on_punch");
2287 if(lua_isnil(L, -1))
2289 luaL_checktype(L, -1, LUA_TFUNCTION);
2290 lua_pushvalue(L, object); // self
2291 objectref_get_or_create(L, puncher); // Clicker reference
2292 // Call with 2 arguments, 0 results
2293 if(lua_pcall(L, 2, 0, 0))
2294 script_error(L, "error running function 'on_punch': %s\n", lua_tostring(L, -1));
2297 // Calls entity:on_rightclick(ObjectRef clicker)
2298 void scriptapi_luaentity_rightclick(lua_State *L, u16 id,
2299 ServerActiveObject *clicker)
2302 assert(lua_checkstack(L, 20));
2303 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
2304 StackUnroller stack_unroller(L);
2306 // Get minetest.luaentities[id]
2307 luaentity_get(L, id);
2308 int object = lua_gettop(L);
2309 // State: object is at top of stack
2311 lua_getfield(L, -1, "on_rightclick");
2312 if(lua_isnil(L, -1))
2314 luaL_checktype(L, -1, LUA_TFUNCTION);
2315 lua_pushvalue(L, object); // self
2316 objectref_get_or_create(L, clicker); // Clicker reference
2317 // Call with 2 arguments, 0 results
2318 if(lua_pcall(L, 2, 0, 0))
2319 script_error(L, "error running function 'on_rightclick': %s\n", lua_tostring(L, -1));