3 Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "scriptapi.h"
34 #include "serverobject.h"
37 #include "luaentity_common.h"
38 #include "content_sao.h" // For LuaEntitySAO
42 #include "main.h" // For g_settings
43 #include "settings.h" // For accessing g_settings
44 #include "nodemetadata.h"
45 #include "mapblock.h" // For getNodeBlockPos
46 #include "content_nodemeta.h"
48 static void stackDump(lua_State *L, std::ostream &o)
51 int top = lua_gettop(L);
52 for (i = 1; i <= top; i++) { /* repeat for each level */
53 int t = lua_type(L, i);
56 case LUA_TSTRING: /* strings */
57 o<<"\""<<lua_tostring(L, i)<<"\"";
60 case LUA_TBOOLEAN: /* booleans */
61 o<<(lua_toboolean(L, i) ? "true" : "false");
64 case LUA_TNUMBER: /* numbers */ {
66 snprintf(buf, 10, "%g", lua_tonumber(L, i));
70 default: /* other values */
71 o<<lua_typename(L, t);
80 static void realitycheck(lua_State *L)
82 int top = lua_gettop(L);
84 dstream<<"Stack is over 30:"<<std::endl;
85 stackDump(L, dstream);
86 script_error(L, "Stack is over 30 (reality check)");
96 StackUnroller(lua_State *L):
100 m_original_top = lua_gettop(m_lua); // store stack height
104 lua_settop(m_lua, m_original_top); // restore stack height
108 static v3f readFloatPos(lua_State *L, int index)
111 luaL_checktype(L, index, LUA_TTABLE);
112 lua_getfield(L, index, "x");
113 pos.X = lua_tonumber(L, -1);
115 lua_getfield(L, index, "y");
116 pos.Y = lua_tonumber(L, -1);
118 lua_getfield(L, index, "z");
119 pos.Z = lua_tonumber(L, -1);
121 pos *= BS; // Scale to internal format
125 static void pushFloatPos(lua_State *L, v3f p)
129 lua_pushnumber(L, p.X);
130 lua_setfield(L, -2, "x");
131 lua_pushnumber(L, p.Y);
132 lua_setfield(L, -2, "y");
133 lua_pushnumber(L, p.Z);
134 lua_setfield(L, -2, "z");
137 static void pushpos(lua_State *L, v3s16 p)
140 lua_pushnumber(L, p.X);
141 lua_setfield(L, -2, "x");
142 lua_pushnumber(L, p.Y);
143 lua_setfield(L, -2, "y");
144 lua_pushnumber(L, p.Z);
145 lua_setfield(L, -2, "z");
148 static v3s16 readpos(lua_State *L, int index)
150 // Correct rounding at <0
151 v3f pf = readFloatPos(L, index);
152 return floatToInt(pf, BS);
155 static void pushnode(lua_State *L, const MapNode &n, INodeDefManager *ndef)
158 lua_pushstring(L, ndef->get(n).name.c_str());
159 lua_setfield(L, -2, "name");
160 lua_pushnumber(L, n.getParam1());
161 lua_setfield(L, -2, "param1");
162 lua_pushnumber(L, n.getParam2());
163 lua_setfield(L, -2, "param2");
166 static MapNode readnode(lua_State *L, int index, INodeDefManager *ndef)
168 lua_getfield(L, index, "name");
169 const char *name = lua_tostring(L, -1);
172 lua_getfield(L, index, "param1");
176 param1 = lua_tonumber(L, -1);
179 lua_getfield(L, index, "param2");
183 param2 = lua_tonumber(L, -1);
185 return MapNode(ndef, name, param1, param2);
188 static video::SColor readARGB8(lua_State *L, int index)
191 luaL_checktype(L, index, LUA_TTABLE);
192 lua_getfield(L, index, "a");
193 if(lua_isnumber(L, -1))
194 color.setAlpha(lua_tonumber(L, -1));
196 lua_getfield(L, index, "r");
197 color.setRed(lua_tonumber(L, -1));
199 lua_getfield(L, index, "g");
200 color.setGreen(lua_tonumber(L, -1));
202 lua_getfield(L, index, "b");
203 color.setBlue(lua_tonumber(L, -1));
208 static core::aabbox3d<f32> read_aabbox3df32(lua_State *L, int index, f32 scale)
210 core::aabbox3d<f32> box;
211 if(lua_istable(L, -1)){
212 lua_rawgeti(L, -1, 1);
213 box.MinEdge.X = lua_tonumber(L, -1) * scale;
215 lua_rawgeti(L, -1, 2);
216 box.MinEdge.Y = lua_tonumber(L, -1) * scale;
218 lua_rawgeti(L, -1, 3);
219 box.MinEdge.Z = lua_tonumber(L, -1) * scale;
221 lua_rawgeti(L, -1, 4);
222 box.MaxEdge.X = lua_tonumber(L, -1) * scale;
224 lua_rawgeti(L, -1, 5);
225 box.MaxEdge.Y = lua_tonumber(L, -1) * scale;
227 lua_rawgeti(L, -1, 6);
228 box.MaxEdge.Z = lua_tonumber(L, -1) * scale;
234 static v2s16 read_v2s16(lua_State *L, int index)
237 luaL_checktype(L, index, LUA_TTABLE);
238 lua_getfield(L, index, "x");
239 p.X = lua_tonumber(L, -1);
241 lua_getfield(L, index, "y");
242 p.Y = lua_tonumber(L, -1);
247 static v2f read_v2f(lua_State *L, int index)
250 luaL_checktype(L, index, LUA_TTABLE);
251 lua_getfield(L, index, "x");
252 p.X = lua_tonumber(L, -1);
254 lua_getfield(L, index, "y");
255 p.Y = lua_tonumber(L, -1);
260 static bool getstringfield(lua_State *L, int table,
261 const char *fieldname, std::string &result)
263 lua_getfield(L, table, fieldname);
265 if(lua_isstring(L, -1)){
266 result = lua_tostring(L, -1);
273 static bool getintfield(lua_State *L, int table,
274 const char *fieldname, int &result)
276 lua_getfield(L, table, fieldname);
278 if(lua_isnumber(L, -1)){
279 result = lua_tonumber(L, -1);
286 static bool getfloatfield(lua_State *L, int table,
287 const char *fieldname, float &result)
289 lua_getfield(L, table, fieldname);
291 if(lua_isnumber(L, -1)){
292 result = lua_tonumber(L, -1);
299 static bool getboolfield(lua_State *L, int table,
300 const char *fieldname, bool &result)
302 lua_getfield(L, table, fieldname);
304 if(lua_isboolean(L, -1)){
305 result = lua_toboolean(L, -1);
312 static std::string getstringfield_default(lua_State *L, int table,
313 const char *fieldname, const std::string &default_)
315 std::string result = default_;
316 getstringfield(L, table, fieldname, result);
320 static int getintfield_default(lua_State *L, int table,
321 const char *fieldname, int default_)
323 int result = default_;
324 getintfield(L, table, fieldname, result);
328 /*static float getfloatfield_default(lua_State *L, int table,
329 const char *fieldname, float default_)
331 float result = default_;
332 getfloatfield(L, table, fieldname, result);
336 static bool getboolfield_default(lua_State *L, int table,
337 const char *fieldname, bool default_)
339 bool result = default_;
340 getboolfield(L, table, fieldname, result);
350 static bool string_to_enum(const EnumString *spec, int &result,
351 const std::string &str)
353 const EnumString *esp = spec;
355 if(str == std::string(esp->str)){
364 /*static bool enum_to_string(const EnumString *spec, std::string &result,
367 const EnumString *esp = spec;
378 static int getenumfield(lua_State *L, int table,
379 const char *fieldname, const EnumString *spec, int default_)
381 int result = default_;
382 string_to_enum(spec, result,
383 getstringfield_default(L, table, fieldname, ""));
387 struct EnumString es_DrawType[] =
389 {NDT_NORMAL, "normal"},
390 {NDT_AIRLIKE, "airlike"},
391 {NDT_LIQUID, "liquid"},
392 {NDT_FLOWINGLIQUID, "flowingliquid"},
393 {NDT_GLASSLIKE, "glasslike"},
394 {NDT_ALLFACES, "allfaces"},
395 {NDT_ALLFACES_OPTIONAL, "allfaces_optional"},
396 {NDT_TORCHLIKE, "torchlike"},
397 {NDT_SIGNLIKE, "signlike"},
398 {NDT_PLANTLIKE, "plantlike"},
399 {NDT_FENCELIKE, "fencelike"},
400 {NDT_RAILLIKE, "raillike"},
404 struct EnumString es_ContentParamType[] =
407 {CPT_LIGHT, "light"},
408 {CPT_MINERAL, "mineral"},
409 {CPT_FACEDIR_SIMPLE, "facedir_simple"},
413 struct EnumString es_LiquidType[] =
415 {LIQUID_NONE, "none"},
416 {LIQUID_FLOWING, "flowing"},
417 {LIQUID_SOURCE, "source"},
421 struct EnumString es_NodeBoxType[] =
423 {NODEBOX_REGULAR, "regular"},
424 {NODEBOX_FIXED, "fixed"},
425 {NODEBOX_WALLMOUNTED, "wallmounted"},
429 struct EnumString es_Diggability[] =
431 {DIGGABLE_NOT, "not"},
432 {DIGGABLE_NORMAL, "normal"},
433 {DIGGABLE_CONSTANT, "constant"},
441 static int l_register_nodedef_defaults(lua_State *L)
443 luaL_checktype(L, 1, LUA_TTABLE);
445 lua_pushvalue(L, 1); // Explicitly put parameter 1 on top of stack
446 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
451 // Register new object prototype
452 // register_entity(name, prototype)
453 static int l_register_entity(lua_State *L)
455 const char *name = luaL_checkstring(L, 1);
456 infostream<<"register_entity: "<<name<<std::endl;
457 luaL_checktype(L, 2, LUA_TTABLE);
459 // Get minetest.registered_entities
460 lua_getglobal(L, "minetest");
461 lua_getfield(L, -1, "registered_entities");
462 luaL_checktype(L, -1, LUA_TTABLE);
463 int registered_entities = lua_gettop(L);
464 lua_pushvalue(L, 2); // Object = param 2 -> stack top
465 // registered_entities[name] = object
466 lua_setfield(L, registered_entities, name);
468 // Get registered object to top of stack
471 // Set __index to point to itself
472 lua_pushvalue(L, -1);
473 lua_setfield(L, -2, "__index");
475 // Set metatable.__index = metatable
476 luaL_getmetatable(L, "minetest.entity");
477 lua_pushvalue(L, -1); // duplicate metatable
478 lua_setfield(L, -2, "__index");
479 // Set object metatable
480 lua_setmetatable(L, -2);
482 return 0; /* number of results */
485 class LuaABM : public ActiveBlockModifier
491 std::set<std::string> m_trigger_contents;
492 float m_trigger_interval;
493 u32 m_trigger_chance;
495 LuaABM(lua_State *L, int id,
496 const std::set<std::string> &trigger_contents,
497 float trigger_interval, u32 trigger_chance):
500 m_trigger_contents(trigger_contents),
501 m_trigger_interval(trigger_interval),
502 m_trigger_chance(trigger_chance)
505 virtual std::set<std::string> getTriggerContents()
507 return m_trigger_contents;
509 virtual float getTriggerInterval()
511 return m_trigger_interval;
513 virtual u32 getTriggerChance()
515 return m_trigger_chance;
517 virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n,
518 u32 active_object_count, u32 active_object_count_wider)
520 lua_State *L = m_lua;
523 assert(lua_checkstack(L, 20));
524 StackUnroller stack_unroller(L);
526 // Get minetest.registered_abms
527 lua_getglobal(L, "minetest");
528 lua_getfield(L, -1, "registered_abms");
529 luaL_checktype(L, -1, LUA_TTABLE);
530 int registered_abms = lua_gettop(L);
532 // Get minetest.registered_abms[m_id]
533 lua_pushnumber(L, m_id);
534 lua_gettable(L, registered_abms);
539 luaL_checktype(L, -1, LUA_TTABLE);
540 lua_getfield(L, -1, "action");
541 luaL_checktype(L, -1, LUA_TFUNCTION);
543 pushnode(L, n, env->getGameDef()->ndef());
544 lua_pushnumber(L, active_object_count);
545 lua_pushnumber(L, active_object_count_wider);
546 if(lua_pcall(L, 4, 0, 0))
547 script_error(L, "error: %s\n", lua_tostring(L, -1));
551 // register_abm({...})
552 static int l_register_abm(lua_State *L)
554 infostream<<"register_abm"<<std::endl;
555 luaL_checktype(L, 1, LUA_TTABLE);
557 // Get minetest.registered_abms
558 lua_getglobal(L, "minetest");
559 lua_getfield(L, -1, "registered_abms");
560 luaL_checktype(L, -1, LUA_TTABLE);
561 int registered_abms = lua_gettop(L);
566 lua_pushnumber(L, id);
567 lua_gettable(L, registered_abms);
575 infostream<<"register_abm: id="<<id<<std::endl;
577 // registered_abms[id] = spec
578 lua_pushnumber(L, id);
580 lua_settable(L, registered_abms);
582 return 0; /* number of results */
585 // register_tool(name, {lots of stuff})
586 static int l_register_tool(lua_State *L)
588 const char *name = luaL_checkstring(L, 1);
589 infostream<<"register_tool: "<<name<<std::endl;
590 luaL_checktype(L, 2, LUA_TTABLE);
593 // Get server from registry
594 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
595 Server *server = (Server*)lua_touserdata(L, -1);
596 // And get the writable tool definition manager from the server
597 IWritableToolDefManager *tooldef =
598 server->getWritableToolDefManager();
602 getstringfield(L, table, "image", def.imagename);
603 getfloatfield(L, table, "basetime", def.properties.basetime);
604 getfloatfield(L, table, "dt_weight", def.properties.dt_weight);
605 getfloatfield(L, table, "dt_crackiness", def.properties.dt_crackiness);
606 getfloatfield(L, table, "dt_crumbliness", def.properties.dt_crumbliness);
607 getfloatfield(L, table, "dt_cuttability", def.properties.dt_cuttability);
608 getfloatfield(L, table, "basedurability", def.properties.basedurability);
609 getfloatfield(L, table, "dd_weight", def.properties.dd_weight);
610 getfloatfield(L, table, "dd_crackiness", def.properties.dd_crackiness);
611 getfloatfield(L, table, "dd_crumbliness", def.properties.dd_crumbliness);
612 getfloatfield(L, table, "dd_cuttability", def.properties.dd_cuttability);
614 tooldef->registerTool(name, def);
615 return 0; /* number of results */
618 // register_node(name, {lots of stuff})
619 static int l_register_node(lua_State *L)
621 const char *name = luaL_checkstring(L, 1);
622 infostream<<"register_node: "<<name<<std::endl;
623 luaL_checktype(L, 2, LUA_TTABLE);
624 int nodedef_table = 2;
626 // Get server from registry
627 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
628 Server *server = (Server*)lua_touserdata(L, -1);
629 // And get the writable node definition manager from the server
630 IWritableNodeDefManager *nodedef =
631 server->getWritableNodeDefManager();
633 // Get default node definition from registry
634 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
635 int nodedef_default = lua_gettop(L);
638 Add to minetest.registered_nodes with default as metatable
641 // Get the node definition table given as parameter
642 lua_pushvalue(L, nodedef_table);
644 // Set __index to point to itself
645 lua_pushvalue(L, -1);
646 lua_setfield(L, -2, "__index");
648 // Set nodedef_default as metatable for the definition
649 lua_pushvalue(L, nodedef_default);
650 lua_setmetatable(L, nodedef_table);
652 // minetest.registered_nodes[name] = nodedef
653 lua_getglobal(L, "minetest");
654 lua_getfield(L, -1, "registered_nodes");
655 luaL_checktype(L, -1, LUA_TTABLE);
656 lua_pushstring(L, name);
657 lua_pushvalue(L, nodedef_table);
666 // Default to getting the corresponding NodeItem when dug
667 f.dug_item = std::string("NodeItem \"")+name+"\" 1";
669 // Default to unknown_block.png as all textures
670 f.setAllTextures("unknown_block.png");
673 Read definiton from Lua
678 /* Visual definition */
680 f.drawtype = (NodeDrawType)getenumfield(L, nodedef_table, "drawtype", es_DrawType,
682 getfloatfield(L, nodedef_table, "visual_scale", f.visual_scale);
684 lua_getfield(L, nodedef_table, "tile_images");
685 if(lua_istable(L, -1)){
686 int table = lua_gettop(L);
689 while(lua_next(L, table) != 0){
690 // key at index -2 and value at index -1
691 if(lua_isstring(L, -1))
692 f.tname_tiles[i] = lua_tostring(L, -1);
694 f.tname_tiles[i] = "";
695 // removes value, keeps key for next iteration
703 // Copy last value to all remaining textures
705 std::string lastname = f.tname_tiles[i-1];
707 f.tname_tiles[i] = lastname;
714 getstringfield(L, nodedef_table, "inventory_image", f.tname_inventory);
716 lua_getfield(L, nodedef_table, "special_materials");
717 if(lua_istable(L, -1)){
718 int table = lua_gettop(L);
721 while(lua_next(L, table) != 0){
722 // key at index -2 and value at index -1
723 int smtable = lua_gettop(L);
724 std::string tname = getstringfield_default(
725 L, smtable, "image", "");
726 bool backface_culling = getboolfield_default(
727 L, smtable, "backface_culling", true);
728 MaterialSpec mspec(tname, backface_culling);
729 f.setSpecialMaterial(i, mspec);
730 // removes value, keeps key for next iteration
741 f.alpha = getintfield_default(L, nodedef_table, "alpha", 255);
745 lua_getfield(L, nodedef_table, "post_effect_color");
746 if(!lua_isnil(L, -1))
747 f.post_effect_color = readARGB8(L, -1);
750 f.param_type = (ContentParamType)getenumfield(L, nodedef_table, "paramtype",
751 es_ContentParamType, CPT_NONE);
753 // True for all ground-like things like stone and mud, false for eg. trees
754 getboolfield(L, nodedef_table, "is_ground_content", f.is_ground_content);
755 getboolfield(L, nodedef_table, "light_propagates", f.light_propagates);
756 getboolfield(L, nodedef_table, "sunlight_propagates", f.sunlight_propagates);
757 // This is used for collision detection.
758 // Also for general solidness queries.
759 getboolfield(L, nodedef_table, "walkable", f.walkable);
760 // Player can point to these
761 getboolfield(L, nodedef_table, "pointable", f.pointable);
762 // Player can dig these
763 getboolfield(L, nodedef_table, "diggable", f.diggable);
764 // Player can climb these
765 getboolfield(L, nodedef_table, "climbable", f.climbable);
766 // Player can build on these
767 getboolfield(L, nodedef_table, "buildable_to", f.buildable_to);
768 // If true, param2 is set to direction when placed. Used for torches.
769 // NOTE: the direction format is quite inefficient and should be changed
770 getboolfield(L, nodedef_table, "wall_mounted", f.wall_mounted);
771 // Whether this content type often contains mineral.
772 // Used for texture atlas creation.
773 // Currently only enabled for CONTENT_STONE.
774 getboolfield(L, nodedef_table, "often_contains_mineral", f.often_contains_mineral);
775 // Inventory item string as which the node appears in inventory when dug.
776 // Mineral overrides this.
777 getstringfield(L, nodedef_table, "dug_item", f.dug_item);
778 // Extra dug item and its rarity
779 getstringfield(L, nodedef_table, "extra_dug_item", f.extra_dug_item);
780 // Usual get interval for extra dug item
781 getintfield(L, nodedef_table, "extra_dug_item_rarity", f.extra_dug_item_rarity);
782 // Metadata name of node (eg. "furnace")
783 getstringfield(L, nodedef_table, "metadata_name", f.metadata_name);
784 // Whether the node is non-liquid, source liquid or flowing liquid
785 f.liquid_type = (LiquidType)getenumfield(L, nodedef_table, "liquidtype",
786 es_LiquidType, LIQUID_NONE);
787 // If the content is liquid, this is the flowing version of the liquid.
788 getstringfield(L, nodedef_table, "liquid_alternative_flowing",
789 f.liquid_alternative_flowing);
790 // If the content is liquid, this is the source version of the liquid.
791 getstringfield(L, nodedef_table, "liquid_alternative_source",
792 f.liquid_alternative_source);
793 // Viscosity for fluid flow, ranging from 1 to 7, with
794 // 1 giving almost instantaneous propagation and 7 being
795 // the slowest possible
796 f.liquid_viscosity = getintfield_default(L, nodedef_table,
797 "liquid_viscosity", f.liquid_viscosity);
798 // Amount of light the node emits
799 f.light_source = getintfield_default(L, nodedef_table,
800 "light_source", f.light_source);
801 f.damage_per_second = getintfield_default(L, nodedef_table,
802 "damage_per_second", f.damage_per_second);
804 lua_getfield(L, nodedef_table, "selection_box");
805 if(lua_istable(L, -1)){
806 f.selection_box.type = (NodeBoxType)getenumfield(L, -1, "type",
807 es_NodeBoxType, NODEBOX_REGULAR);
809 lua_getfield(L, -1, "fixed");
810 if(lua_istable(L, -1))
811 f.selection_box.fixed = read_aabbox3df32(L, -1, BS);
814 lua_getfield(L, -1, "wall_top");
815 if(lua_istable(L, -1))
816 f.selection_box.wall_top = read_aabbox3df32(L, -1, BS);
819 lua_getfield(L, -1, "wall_bottom");
820 if(lua_istable(L, -1))
821 f.selection_box.wall_bottom = read_aabbox3df32(L, -1, BS);
824 lua_getfield(L, -1, "wall_side");
825 if(lua_istable(L, -1))
826 f.selection_box.wall_side = read_aabbox3df32(L, -1, BS);
831 lua_getfield(L, nodedef_table, "material");
832 if(lua_istable(L, -1)){
833 f.material.diggability = (Diggability)getenumfield(L, -1, "diggability",
834 es_Diggability, DIGGABLE_NORMAL);
836 getfloatfield(L, -1, "constant_time", f.material.constant_time);
837 getfloatfield(L, -1, "weight", f.material.weight);
838 getfloatfield(L, -1, "crackiness", f.material.crackiness);
839 getfloatfield(L, -1, "crumbliness", f.material.crumbliness);
840 getfloatfield(L, -1, "cuttability", f.material.cuttability);
841 getfloatfield(L, -1, "flammability", f.material.flammability);
845 getstringfield(L, nodedef_table, "cookresult_item", f.cookresult_item);
846 getfloatfield(L, nodedef_table, "furnace_cooktime", f.furnace_cooktime);
847 getfloatfield(L, nodedef_table, "furnace_burntime", f.furnace_burntime);
853 nodedef->set(name, f);
855 return 0; /* number of results */
858 // register_craft({output=item, recipe={{item00,item10},{item01,item11}})
859 static int l_register_craft(lua_State *L)
861 infostream<<"register_craft"<<std::endl;
862 luaL_checktype(L, 1, LUA_TTABLE);
865 // Get server from registry
866 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
867 Server *server = (Server*)lua_touserdata(L, -1);
868 // And get the writable craft definition manager from the server
869 IWritableCraftDefManager *craftdef =
870 server->getWritableCraftDefManager();
874 std::vector<std::string> input;
876 lua_getfield(L, table0, "output");
877 luaL_checktype(L, -1, LUA_TSTRING);
878 if(lua_isstring(L, -1))
879 output = lua_tostring(L, -1);
882 lua_getfield(L, table0, "recipe");
883 luaL_checktype(L, -1, LUA_TTABLE);
884 if(lua_istable(L, -1)){
885 int table1 = lua_gettop(L);
888 while(lua_next(L, table1) != 0){
890 // key at index -2 and value at index -1
891 luaL_checktype(L, -1, LUA_TTABLE);
892 if(lua_istable(L, -1)){
893 int table2 = lua_gettop(L);
895 while(lua_next(L, table2) != 0){
896 // key at index -2 and value at index -1
897 luaL_checktype(L, -1, LUA_TSTRING);
898 input.push_back(lua_tostring(L, -1));
899 // removes value, keeps key for next iteration
907 if(colcount != width){
908 script_error(L, "error: %s\n", "Invalid crafting recipe");
911 // removes value, keeps key for next iteration
918 CraftDefinition def(output, width, input);
919 craftdef->registerCraft(def);
921 return 0; /* number of results */
925 static int l_setting_get(lua_State *L)
927 const char *name = luaL_checkstring(L, 1);
929 std::string value = g_settings->get(name);
930 lua_pushstring(L, value.c_str());
931 } catch(SettingNotFoundException &e){
937 // setting_getbool(name)
938 static int l_setting_getbool(lua_State *L)
940 const char *name = luaL_checkstring(L, 1);
942 bool value = g_settings->getBool(name);
943 lua_pushboolean(L, value);
944 } catch(SettingNotFoundException &e){
950 // chat_send_all(text)
951 static int l_chat_send_all(lua_State *L)
953 const char *text = luaL_checkstring(L, 1);
954 // Get server from registry
955 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
956 Server *server = (Server*)lua_touserdata(L, -1);
958 server->notifyPlayers(narrow_to_wide(text));
962 // chat_send_player(name, text)
963 static int l_chat_send_player(lua_State *L)
965 const char *name = luaL_checkstring(L, 1);
966 const char *text = luaL_checkstring(L, 2);
967 // Get server from registry
968 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
969 Server *server = (Server*)lua_touserdata(L, -1);
971 server->notifyPlayer(name, narrow_to_wide(text));
975 static const struct luaL_Reg minetest_f [] = {
976 {"register_nodedef_defaults", l_register_nodedef_defaults},
977 {"register_entity", l_register_entity},
978 {"register_tool", l_register_tool},
979 {"register_node", l_register_node},
980 {"register_craft", l_register_craft},
981 {"register_abm", l_register_abm},
982 {"setting_get", l_setting_get},
983 {"setting_getbool", l_setting_getbool},
984 {"chat_send_all", l_chat_send_all},
985 {"chat_send_player", l_chat_send_player},
993 static const struct luaL_Reg minetest_entity_m [] = {
998 Getters for stuff in main tables
1001 static void objectref_get(lua_State *L, u16 id)
1003 // Get minetest.object_refs[i]
1004 lua_getglobal(L, "minetest");
1005 lua_getfield(L, -1, "object_refs");
1006 luaL_checktype(L, -1, LUA_TTABLE);
1007 lua_pushnumber(L, id);
1008 lua_gettable(L, -2);
1009 lua_remove(L, -2); // object_refs
1010 lua_remove(L, -2); // minetest
1013 static void luaentity_get(lua_State *L, u16 id)
1015 // Get minetest.luaentities[i]
1016 lua_getglobal(L, "minetest");
1017 lua_getfield(L, -1, "luaentities");
1018 luaL_checktype(L, -1, LUA_TTABLE);
1019 lua_pushnumber(L, id);
1020 lua_gettable(L, -2);
1021 lua_remove(L, -2); // luaentities
1022 lua_remove(L, -2); // minetest
1029 #define method(class, name) {#name, class::l_##name}
1039 ServerEnvironment *m_env;
1041 static const char className[];
1042 static const luaL_reg methods[];
1044 static NodeMetaRef *checkobject(lua_State *L, int narg)
1046 luaL_checktype(L, narg, LUA_TUSERDATA);
1047 void *ud = luaL_checkudata(L, narg, className);
1048 if(!ud) luaL_typerror(L, narg, className);
1049 return *(NodeMetaRef**)ud; // unbox pointer
1052 static NodeMetadata* getmeta(NodeMetaRef *ref)
1054 NodeMetadata *meta = ref->m_env->getMap().getNodeMetadata(ref->m_p);
1058 /*static IGenericNodeMetadata* getgenericmeta(NodeMetaRef *ref)
1060 NodeMetadata *meta = getmeta(ref);
1063 if(meta->typeId() != NODEMETA_GENERIC)
1065 return (IGenericNodeMetadata*)meta;
1068 static void reportMetadataChange(NodeMetaRef *ref)
1070 // Inform other things that the metadata has changed
1071 v3s16 blockpos = getNodeBlockPos(ref->m_p);
1073 event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
1075 ref->m_env->getMap().dispatchEvent(&event);
1076 // Set the block to be saved
1077 MapBlock *block = ref->m_env->getMap().getBlockNoCreateNoEx(blockpos);
1079 block->raiseModified(MOD_STATE_WRITE_NEEDED,
1080 "NodeMetaRef::reportMetadataChange");
1083 // Exported functions
1085 // garbage collector
1086 static int gc_object(lua_State *L) {
1087 NodeMetaRef *o = *(NodeMetaRef **)(lua_touserdata(L, 1));
1093 static int l_get_type(lua_State *L)
1095 NodeMetaRef *ref = checkobject(L, 1);
1096 NodeMetadata *meta = getmeta(ref);
1102 lua_pushstring(L, meta->typeName());
1106 // allows_text_input(self)
1107 static int l_allows_text_input(lua_State *L)
1109 NodeMetaRef *ref = checkobject(L, 1);
1110 NodeMetadata *meta = getmeta(ref);
1111 if(meta == NULL) return 0;
1113 lua_pushboolean(L, meta->allowsTextInput());
1117 // set_text(self, text)
1118 static int l_set_text(lua_State *L)
1120 NodeMetaRef *ref = checkobject(L, 1);
1121 NodeMetadata *meta = getmeta(ref);
1122 if(meta == NULL) return 0;
1124 std::string text = lua_tostring(L, 2);
1125 meta->setText(text);
1126 reportMetadataChange(ref);
1131 static int l_get_text(lua_State *L)
1133 NodeMetaRef *ref = checkobject(L, 1);
1134 NodeMetadata *meta = getmeta(ref);
1135 if(meta == NULL) return 0;
1137 std::string text = meta->getText();
1138 lua_pushstring(L, text.c_str());
1143 static int l_get_owner(lua_State *L)
1145 NodeMetaRef *ref = checkobject(L, 1);
1146 NodeMetadata *meta = getmeta(ref);
1147 if(meta == NULL) return 0;
1149 std::string owner = meta->getOwner();
1150 lua_pushstring(L, owner.c_str());
1154 /* IGenericNodeMetadata interface */
1156 // set_infotext(self, text)
1157 static int l_set_infotext(lua_State *L)
1159 infostream<<__FUNCTION_NAME<<std::endl;
1160 NodeMetaRef *ref = checkobject(L, 1);
1161 NodeMetadata *meta = getmeta(ref);
1162 if(meta == NULL) return 0;
1164 std::string text = lua_tostring(L, 2);
1165 meta->setInfoText(text);
1166 reportMetadataChange(ref);
1170 // inventory_set_list(self, name, {item1, item2, ...})
1171 static int l_inventory_set_list(lua_State *L)
1173 NodeMetaRef *ref = checkobject(L, 1);
1174 NodeMetadata *meta = getmeta(ref);
1175 if(meta == NULL) return 0;
1177 Inventory *inv = meta->getInventory();
1178 std::string name = lua_tostring(L, 2);
1179 // If nil, delete list
1180 if(lua_isnil(L, 3)){
1181 inv->deleteList(name);
1184 // Otherwise set list
1185 std::list<std::string> items;
1186 luaL_checktype(L, 3, LUA_TTABLE);
1189 infostream<<"items: ";
1190 while(lua_next(L, table) != 0){
1191 // key at index -2 and value at index -1
1192 luaL_checktype(L, -1, LUA_TSTRING);
1193 std::string itemstring = lua_tostring(L, -1);
1194 infostream<<"\""<<itemstring<<"\" ";
1195 items.push_back(itemstring);
1196 // removes value, keeps key for next iteration
1199 infostream<<std::endl;
1200 InventoryList *invlist = inv->addList(name, items.size());
1202 for(std::list<std::string>::const_iterator
1203 i = items.begin(); i != items.end(); i++){
1204 const std::string &itemstring = *i;
1205 InventoryItem *newitem = NULL;
1206 if(itemstring != "")
1207 newitem = InventoryItem::deSerialize(itemstring,
1208 ref->m_env->getGameDef());
1209 InventoryItem *olditem = invlist->changeItem(index, newitem);
1213 reportMetadataChange(ref);
1217 // inventory_get_list(self, name)
1218 static int l_inventory_get_list(lua_State *L)
1220 NodeMetaRef *ref = checkobject(L, 1);
1221 NodeMetadata *meta = getmeta(ref);
1222 if(meta == NULL) return 0;
1224 Inventory *inv = meta->getInventory();
1225 std::string name = lua_tostring(L, 2);
1226 InventoryList *invlist = inv->getList(name);
1227 if(invlist == NULL){
1231 // Get the table insert function
1232 lua_getglobal(L, "table");
1233 lua_getfield(L, -1, "insert");
1234 int table_insert = lua_gettop(L);
1235 // Create and fill table
1237 int table = lua_gettop(L);
1238 for(u32 i=0; i<invlist->getSize(); i++){
1239 InventoryItem *item = invlist->getItem(i);
1240 lua_pushvalue(L, table_insert);
1241 lua_pushvalue(L, table);
1245 lua_pushstring(L, item->getItemString().c_str());
1247 if(lua_pcall(L, 2, 0, 0))
1248 script_error(L, "error: %s\n", lua_tostring(L, -1));
1253 // set_inventory_draw_spec(self, text)
1254 static int l_set_inventory_draw_spec(lua_State *L)
1256 NodeMetaRef *ref = checkobject(L, 1);
1257 NodeMetadata *meta = getmeta(ref);
1258 if(meta == NULL) return 0;
1260 std::string text = lua_tostring(L, 2);
1261 meta->setInventoryDrawSpec(text);
1262 reportMetadataChange(ref);
1266 // set_allow_text_input(self, text)
1267 static int l_set_allow_text_input(lua_State *L)
1269 NodeMetaRef *ref = checkobject(L, 1);
1270 NodeMetadata *meta = getmeta(ref);
1271 if(meta == NULL) return 0;
1273 bool b = lua_toboolean(L, 2);
1274 meta->setAllowTextInput(b);
1275 reportMetadataChange(ref);
1279 // set_allow_removal(self, text)
1280 static int l_set_allow_removal(lua_State *L)
1282 NodeMetaRef *ref = checkobject(L, 1);
1283 NodeMetadata *meta = getmeta(ref);
1284 if(meta == NULL) return 0;
1286 bool b = lua_toboolean(L, 2);
1287 meta->setRemovalDisabled(!b);
1288 reportMetadataChange(ref);
1292 // set_enforce_owner(self, text)
1293 static int l_set_enforce_owner(lua_State *L)
1295 NodeMetaRef *ref = checkobject(L, 1);
1296 NodeMetadata *meta = getmeta(ref);
1297 if(meta == NULL) return 0;
1299 bool b = lua_toboolean(L, 2);
1300 meta->setEnforceOwner(b);
1301 reportMetadataChange(ref);
1305 // is_inventory_modified(self)
1306 static int l_is_inventory_modified(lua_State *L)
1308 NodeMetaRef *ref = checkobject(L, 1);
1309 NodeMetadata *meta = getmeta(ref);
1310 if(meta == NULL) return 0;
1312 lua_pushboolean(L, meta->isInventoryModified());
1316 // reset_inventory_modified(self)
1317 static int l_reset_inventory_modified(lua_State *L)
1319 NodeMetaRef *ref = checkobject(L, 1);
1320 NodeMetadata *meta = getmeta(ref);
1321 if(meta == NULL) return 0;
1323 meta->resetInventoryModified();
1324 reportMetadataChange(ref);
1328 // is_text_modified(self)
1329 static int l_is_text_modified(lua_State *L)
1331 NodeMetaRef *ref = checkobject(L, 1);
1332 NodeMetadata *meta = getmeta(ref);
1333 if(meta == NULL) return 0;
1335 lua_pushboolean(L, meta->isTextModified());
1339 // reset_text_modified(self)
1340 static int l_reset_text_modified(lua_State *L)
1342 NodeMetaRef *ref = checkobject(L, 1);
1343 NodeMetadata *meta = getmeta(ref);
1344 if(meta == NULL) return 0;
1346 meta->resetTextModified();
1347 reportMetadataChange(ref);
1351 // set_string(self, name, var)
1352 static int l_set_string(lua_State *L)
1354 NodeMetaRef *ref = checkobject(L, 1);
1355 NodeMetadata *meta = getmeta(ref);
1356 if(meta == NULL) return 0;
1358 std::string name = lua_tostring(L, 2);
1360 const char *s = lua_tolstring(L, 3, &len);
1361 std::string str(s, len);
1362 meta->setString(name, str);
1363 reportMetadataChange(ref);
1367 // get_string(self, name)
1368 static int l_get_string(lua_State *L)
1370 NodeMetaRef *ref = checkobject(L, 1);
1371 NodeMetadata *meta = getmeta(ref);
1372 if(meta == NULL) return 0;
1374 std::string name = lua_tostring(L, 2);
1375 std::string str = meta->getString(name);
1376 lua_pushlstring(L, str.c_str(), str.size());
1381 NodeMetaRef(v3s16 p, ServerEnvironment *env):
1391 // Creates an NodeMetaRef and leaves it on top of stack
1392 // Not callable from Lua; all references are created on the C side.
1393 static void create(lua_State *L, v3s16 p, ServerEnvironment *env)
1395 NodeMetaRef *o = new NodeMetaRef(p, env);
1396 //infostream<<"NodeMetaRef::create: o="<<o<<std::endl;
1397 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1398 luaL_getmetatable(L, className);
1399 lua_setmetatable(L, -2);
1402 static void Register(lua_State *L)
1405 int methodtable = lua_gettop(L);
1406 luaL_newmetatable(L, className);
1407 int metatable = lua_gettop(L);
1409 lua_pushliteral(L, "__metatable");
1410 lua_pushvalue(L, methodtable);
1411 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
1413 lua_pushliteral(L, "__index");
1414 lua_pushvalue(L, methodtable);
1415 lua_settable(L, metatable);
1417 lua_pushliteral(L, "__gc");
1418 lua_pushcfunction(L, gc_object);
1419 lua_settable(L, metatable);
1421 lua_pop(L, 1); // drop metatable
1423 luaL_openlib(L, 0, methods, 0); // fill methodtable
1424 lua_pop(L, 1); // drop methodtable
1426 // Cannot be created from Lua
1427 //lua_register(L, className, create_object);
1430 const char NodeMetaRef::className[] = "NodeMetaRef";
1431 const luaL_reg NodeMetaRef::methods[] = {
1432 method(NodeMetaRef, get_type),
1433 method(NodeMetaRef, allows_text_input),
1434 method(NodeMetaRef, set_text),
1435 method(NodeMetaRef, get_text),
1436 method(NodeMetaRef, get_owner),
1437 method(NodeMetaRef, set_infotext),
1438 method(NodeMetaRef, inventory_set_list),
1439 method(NodeMetaRef, inventory_get_list),
1440 method(NodeMetaRef, set_inventory_draw_spec),
1441 method(NodeMetaRef, set_allow_text_input),
1442 method(NodeMetaRef, set_allow_removal),
1443 method(NodeMetaRef, set_enforce_owner),
1444 method(NodeMetaRef, is_inventory_modified),
1445 method(NodeMetaRef, reset_inventory_modified),
1446 method(NodeMetaRef, is_text_modified),
1447 method(NodeMetaRef, reset_text_modified),
1448 method(NodeMetaRef, set_string),
1449 method(NodeMetaRef, get_string),
1460 ServerEnvironment *m_env;
1462 static const char className[];
1463 static const luaL_reg methods[];
1465 static EnvRef *checkobject(lua_State *L, int narg)
1467 luaL_checktype(L, narg, LUA_TUSERDATA);
1468 void *ud = luaL_checkudata(L, narg, className);
1469 if(!ud) luaL_typerror(L, narg, className);
1470 return *(EnvRef**)ud; // unbox pointer
1473 // Exported functions
1475 // EnvRef:add_node(pos, node)
1476 // pos = {x=num, y=num, z=num}
1477 static int l_add_node(lua_State *L)
1479 //infostream<<"EnvRef::l_add_node()"<<std::endl;
1480 EnvRef *o = checkobject(L, 1);
1481 ServerEnvironment *env = o->m_env;
1482 if(env == NULL) return 0;
1484 v3s16 pos = readpos(L, 2);
1486 MapNode n = readnode(L, 3, env->getGameDef()->ndef());
1488 bool succeeded = env->getMap().addNodeWithEvent(pos, n);
1489 lua_pushboolean(L, succeeded);
1493 // EnvRef:remove_node(pos)
1494 // pos = {x=num, y=num, z=num}
1495 static int l_remove_node(lua_State *L)
1497 //infostream<<"EnvRef::l_remove_node()"<<std::endl;
1498 EnvRef *o = checkobject(L, 1);
1499 ServerEnvironment *env = o->m_env;
1500 if(env == NULL) return 0;
1502 v3s16 pos = readpos(L, 2);
1504 bool succeeded = env->getMap().removeNodeWithEvent(pos);
1505 lua_pushboolean(L, succeeded);
1509 // EnvRef:get_node(pos)
1510 // pos = {x=num, y=num, z=num}
1511 static int l_get_node(lua_State *L)
1513 //infostream<<"EnvRef::l_get_node()"<<std::endl;
1514 EnvRef *o = checkobject(L, 1);
1515 ServerEnvironment *env = o->m_env;
1516 if(env == NULL) return 0;
1518 v3s16 pos = readpos(L, 2);
1520 MapNode n = env->getMap().getNodeNoEx(pos);
1522 pushnode(L, n, env->getGameDef()->ndef());
1526 // EnvRef:add_luaentity(pos, entityname)
1527 // pos = {x=num, y=num, z=num}
1528 static int l_add_luaentity(lua_State *L)
1530 //infostream<<"EnvRef::l_add_luaentity()"<<std::endl;
1531 EnvRef *o = checkobject(L, 1);
1532 ServerEnvironment *env = o->m_env;
1533 if(env == NULL) return 0;
1535 v3f pos = readFloatPos(L, 2);
1537 const char *name = lua_tostring(L, 3);
1539 ServerActiveObject *obj = new LuaEntitySAO(env, pos, name, "");
1540 env->addActiveObject(obj);
1544 // EnvRef:get_meta(pos)
1545 static int l_get_meta(lua_State *L)
1547 //infostream<<"EnvRef::l_get_meta()"<<std::endl;
1548 EnvRef *o = checkobject(L, 1);
1549 ServerEnvironment *env = o->m_env;
1550 if(env == NULL) return 0;
1552 v3s16 p = readpos(L, 2);
1553 NodeMetaRef::create(L, p, env);
1557 static int gc_object(lua_State *L) {
1558 EnvRef *o = *(EnvRef **)(lua_touserdata(L, 1));
1564 EnvRef(ServerEnvironment *env):
1567 infostream<<"EnvRef created"<<std::endl;
1572 infostream<<"EnvRef destructing"<<std::endl;
1575 // Creates an EnvRef and leaves it on top of stack
1576 // Not callable from Lua; all references are created on the C side.
1577 static void create(lua_State *L, ServerEnvironment *env)
1579 EnvRef *o = new EnvRef(env);
1580 //infostream<<"EnvRef::create: o="<<o<<std::endl;
1581 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1582 luaL_getmetatable(L, className);
1583 lua_setmetatable(L, -2);
1586 static void set_null(lua_State *L)
1588 EnvRef *o = checkobject(L, -1);
1592 static void Register(lua_State *L)
1595 int methodtable = lua_gettop(L);
1596 luaL_newmetatable(L, className);
1597 int metatable = lua_gettop(L);
1599 lua_pushliteral(L, "__metatable");
1600 lua_pushvalue(L, methodtable);
1601 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
1603 lua_pushliteral(L, "__index");
1604 lua_pushvalue(L, methodtable);
1605 lua_settable(L, metatable);
1607 lua_pushliteral(L, "__gc");
1608 lua_pushcfunction(L, gc_object);
1609 lua_settable(L, metatable);
1611 lua_pop(L, 1); // drop metatable
1613 luaL_openlib(L, 0, methods, 0); // fill methodtable
1614 lua_pop(L, 1); // drop methodtable
1616 // Cannot be created from Lua
1617 //lua_register(L, className, create_object);
1620 const char EnvRef::className[] = "EnvRef";
1621 const luaL_reg EnvRef::methods[] = {
1622 method(EnvRef, add_node),
1623 method(EnvRef, remove_node),
1624 method(EnvRef, get_node),
1625 method(EnvRef, add_luaentity),
1626 method(EnvRef, get_meta),
1637 ServerActiveObject *m_object;
1639 static const char className[];
1640 static const luaL_reg methods[];
1642 static ObjectRef *checkobject(lua_State *L, int narg)
1644 luaL_checktype(L, narg, LUA_TUSERDATA);
1645 void *ud = luaL_checkudata(L, narg, className);
1646 if(!ud) luaL_typerror(L, narg, className);
1647 return *(ObjectRef**)ud; // unbox pointer
1650 static ServerActiveObject* getobject(ObjectRef *ref)
1652 ServerActiveObject *co = ref->m_object;
1656 static LuaEntitySAO* getluaobject(ObjectRef *ref)
1658 ServerActiveObject *obj = getobject(ref);
1661 if(obj->getType() != ACTIVEOBJECT_TYPE_LUAENTITY)
1663 return (LuaEntitySAO*)obj;
1666 // Exported functions
1668 // garbage collector
1669 static int gc_object(lua_State *L) {
1670 ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
1671 //infostream<<"ObjectRef::gc_object: o="<<o<<std::endl;
1677 static int l_remove(lua_State *L)
1679 ObjectRef *ref = checkobject(L, 1);
1680 ServerActiveObject *co = getobject(ref);
1681 if(co == NULL) return 0;
1682 infostream<<"ObjectRef::l_remove(): id="<<co->getId()<<std::endl;
1683 co->m_removed = true;
1688 // returns: {x=num, y=num, z=num}
1689 static int l_getpos(lua_State *L)
1691 ObjectRef *ref = checkobject(L, 1);
1692 ServerActiveObject *co = getobject(ref);
1693 if(co == NULL) return 0;
1694 v3f pos = co->getBasePosition() / BS;
1696 lua_pushnumber(L, pos.X);
1697 lua_setfield(L, -2, "x");
1698 lua_pushnumber(L, pos.Y);
1699 lua_setfield(L, -2, "y");
1700 lua_pushnumber(L, pos.Z);
1701 lua_setfield(L, -2, "z");
1705 // setpos(self, pos)
1706 static int l_setpos(lua_State *L)
1708 ObjectRef *ref = checkobject(L, 1);
1709 //LuaEntitySAO *co = getluaobject(ref);
1710 ServerActiveObject *co = getobject(ref);
1711 if(co == NULL) return 0;
1713 v3f pos = readFloatPos(L, 2);
1719 // moveto(self, pos, continuous=false)
1720 static int l_moveto(lua_State *L)
1722 ObjectRef *ref = checkobject(L, 1);
1723 //LuaEntitySAO *co = getluaobject(ref);
1724 ServerActiveObject *co = getobject(ref);
1725 if(co == NULL) return 0;
1727 v3f pos = readFloatPos(L, 2);
1729 bool continuous = lua_toboolean(L, 3);
1731 co->moveTo(pos, continuous);
1735 // setvelocity(self, velocity)
1736 static int l_setvelocity(lua_State *L)
1738 ObjectRef *ref = checkobject(L, 1);
1739 LuaEntitySAO *co = getluaobject(ref);
1740 if(co == NULL) return 0;
1742 v3f pos = readFloatPos(L, 2);
1744 co->setVelocity(pos);
1748 // setacceleration(self, acceleration)
1749 static int l_setacceleration(lua_State *L)
1751 ObjectRef *ref = checkobject(L, 1);
1752 LuaEntitySAO *co = getluaobject(ref);
1753 if(co == NULL) return 0;
1755 v3f pos = readFloatPos(L, 2);
1757 co->setAcceleration(pos);
1761 // getacceleration(self)
1762 static int l_getacceleration(lua_State *L)
1764 ObjectRef *ref = checkobject(L, 1);
1765 LuaEntitySAO *co = getluaobject(ref);
1766 if(co == NULL) return 0;
1768 v3f v = co->getAcceleration();
1773 // add_to_inventory(self, itemstring)
1774 // returns: true if item was added, false otherwise
1775 static int l_add_to_inventory(lua_State *L)
1777 ObjectRef *ref = checkobject(L, 1);
1778 luaL_checkstring(L, 2);
1779 ServerActiveObject *co = getobject(ref);
1780 if(co == NULL) return 0;
1782 const char *itemstring = lua_tostring(L, 2);
1783 infostream<<"ObjectRef::l_add_to_inventory(): id="<<co->getId()
1784 <<" itemstring=\""<<itemstring<<"\""<<std::endl;
1786 std::istringstream is(itemstring, std::ios::binary);
1787 ServerEnvironment *env = co->getEnv();
1789 IGameDef *gamedef = env->getGameDef();
1790 InventoryItem *item = InventoryItem::deSerialize(is, gamedef);
1791 infostream<<"item="<<env<<std::endl;
1792 bool fits = co->addToInventory(item);
1794 lua_pushboolean(L, fits);
1798 // settexturemod(self, mod)
1799 static int l_settexturemod(lua_State *L)
1801 ObjectRef *ref = checkobject(L, 1);
1802 LuaEntitySAO *co = getluaobject(ref);
1803 if(co == NULL) return 0;
1805 std::string mod = lua_tostring(L, 2);
1806 co->setTextureMod(mod);
1810 // setsprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2,
1811 // select_horiz_by_yawpitch=false)
1812 static int l_setsprite(lua_State *L)
1814 ObjectRef *ref = checkobject(L, 1);
1815 LuaEntitySAO *co = getluaobject(ref);
1816 if(co == NULL) return 0;
1819 if(!lua_isnil(L, 2))
1820 p = read_v2s16(L, 2);
1822 if(!lua_isnil(L, 3))
1823 num_frames = lua_tonumber(L, 3);
1824 float framelength = 0.2;
1825 if(!lua_isnil(L, 4))
1826 framelength = lua_tonumber(L, 4);
1827 bool select_horiz_by_yawpitch = false;
1828 if(!lua_isnil(L, 5))
1829 select_horiz_by_yawpitch = lua_toboolean(L, 5);
1830 co->setSprite(p, num_frames, framelength, select_horiz_by_yawpitch);
1835 ObjectRef(ServerActiveObject *object):
1838 //infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
1844 infostream<<"ObjectRef destructing for id="
1845 <<m_object->getId()<<std::endl;
1847 infostream<<"ObjectRef destructing for id=unknown"<<std::endl;*/
1850 // Creates an ObjectRef and leaves it on top of stack
1851 // Not callable from Lua; all references are created on the C side.
1852 static void create(lua_State *L, ServerActiveObject *object)
1854 ObjectRef *o = new ObjectRef(object);
1855 //infostream<<"ObjectRef::create: o="<<o<<std::endl;
1856 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1857 luaL_getmetatable(L, className);
1858 lua_setmetatable(L, -2);
1861 static void set_null(lua_State *L)
1863 ObjectRef *o = checkobject(L, -1);
1867 static void Register(lua_State *L)
1870 int methodtable = lua_gettop(L);
1871 luaL_newmetatable(L, className);
1872 int metatable = lua_gettop(L);
1874 lua_pushliteral(L, "__metatable");
1875 lua_pushvalue(L, methodtable);
1876 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
1878 lua_pushliteral(L, "__index");
1879 lua_pushvalue(L, methodtable);
1880 lua_settable(L, metatable);
1882 lua_pushliteral(L, "__gc");
1883 lua_pushcfunction(L, gc_object);
1884 lua_settable(L, metatable);
1886 lua_pop(L, 1); // drop metatable
1888 luaL_openlib(L, 0, methods, 0); // fill methodtable
1889 lua_pop(L, 1); // drop methodtable
1891 // Cannot be created from Lua
1892 //lua_register(L, className, create_object);
1895 const char ObjectRef::className[] = "ObjectRef";
1896 const luaL_reg ObjectRef::methods[] = {
1897 method(ObjectRef, remove),
1898 method(ObjectRef, getpos),
1899 method(ObjectRef, setpos),
1900 method(ObjectRef, moveto),
1901 method(ObjectRef, setvelocity),
1902 method(ObjectRef, setacceleration),
1903 method(ObjectRef, add_to_inventory),
1904 method(ObjectRef, settexturemod),
1905 method(ObjectRef, setsprite),
1909 // Creates a new anonymous reference if id=0
1910 static void objectref_get_or_create(lua_State *L,
1911 ServerActiveObject *cobj)
1913 if(cobj->getId() == 0){
1914 ObjectRef::create(L, cobj);
1916 objectref_get(L, cobj->getId());
1921 Main export function
1924 void scriptapi_export(lua_State *L, Server *server)
1927 assert(lua_checkstack(L, 20));
1928 infostream<<"scriptapi_export"<<std::endl;
1929 StackUnroller stack_unroller(L);
1931 // Store server as light userdata in registry
1932 lua_pushlightuserdata(L, server);
1933 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_server");
1935 // Store nil as minetest_nodedef_defaults in registry
1937 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
1939 // Register global functions in table minetest
1941 luaL_register(L, NULL, minetest_f);
1942 lua_setglobal(L, "minetest");
1944 // Get the main minetest table
1945 lua_getglobal(L, "minetest");
1947 // Add tables to minetest
1950 lua_setfield(L, -2, "registered_nodes");
1952 lua_setfield(L, -2, "registered_entities");
1954 lua_setfield(L, -2, "registered_abms");
1957 lua_setfield(L, -2, "object_refs");
1959 lua_setfield(L, -2, "luaentities");
1961 // Create entity prototype
1962 luaL_newmetatable(L, "minetest.entity");
1963 // metatable.__index = metatable
1964 lua_pushvalue(L, -1); // Duplicate metatable
1965 lua_setfield(L, -2, "__index");
1966 // Put functions in metatable
1967 luaL_register(L, NULL, minetest_entity_m);
1968 // Put other stuff in metatable
1970 // Register reference wrappers
1971 NodeMetaRef::Register(L);
1972 EnvRef::Register(L);
1973 ObjectRef::Register(L);
1976 void scriptapi_add_environment(lua_State *L, ServerEnvironment *env)
1979 assert(lua_checkstack(L, 20));
1980 infostream<<"scriptapi_add_environment"<<std::endl;
1981 StackUnroller stack_unroller(L);
1983 // Create EnvRef on stack
1984 EnvRef::create(L, env);
1985 int envref = lua_gettop(L);
1987 // minetest.env = envref
1988 lua_getglobal(L, "minetest");
1989 luaL_checktype(L, -1, LUA_TTABLE);
1990 lua_pushvalue(L, envref);
1991 lua_setfield(L, -2, "env");
1993 // Store environment as light userdata in registry
1994 lua_pushlightuserdata(L, env);
1995 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_env");
1997 /* Add ActiveBlockModifiers to environment */
1999 // Get minetest.registered_abms
2000 lua_getglobal(L, "minetest");
2001 lua_getfield(L, -1, "registered_abms");
2002 luaL_checktype(L, -1, LUA_TTABLE);
2003 int registered_abms = lua_gettop(L);
2005 if(lua_istable(L, registered_abms)){
2006 int table = lua_gettop(L);
2008 while(lua_next(L, table) != 0){
2009 // key at index -2 and value at index -1
2010 int id = lua_tonumber(L, -2);
2011 int current_abm = lua_gettop(L);
2013 std::set<std::string> trigger_contents;
2014 lua_getfield(L, current_abm, "nodenames");
2015 if(lua_istable(L, -1)){
2016 int table = lua_gettop(L);
2018 while(lua_next(L, table) != 0){
2019 // key at index -2 and value at index -1
2020 luaL_checktype(L, -1, LUA_TSTRING);
2021 trigger_contents.insert(lua_tostring(L, -1));
2022 // removes value, keeps key for next iteration
2028 float trigger_interval = 10.0;
2029 getfloatfield(L, current_abm, "interval", trigger_interval);
2031 int trigger_chance = 50;
2032 getintfield(L, current_abm, "chance", trigger_chance);
2034 LuaABM *abm = new LuaABM(L, id, trigger_contents,
2035 trigger_interval, trigger_chance);
2037 env->addActiveBlockModifier(abm);
2039 // removes value, keeps key for next iteration
2047 // Dump stack top with the dump2 function
2048 static void dump2(lua_State *L, const char *name)
2050 // Dump object (debug)
2051 lua_getglobal(L, "dump2");
2052 luaL_checktype(L, -1, LUA_TFUNCTION);
2053 lua_pushvalue(L, -2); // Get previous stack top as first parameter
2054 lua_pushstring(L, name);
2055 if(lua_pcall(L, 2, 0, 0))
2056 script_error(L, "error: %s\n", lua_tostring(L, -1));
2064 void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj)
2067 assert(lua_checkstack(L, 20));
2068 //infostream<<"scriptapi_add_object_reference: id="<<cobj->getId()<<std::endl;
2069 StackUnroller stack_unroller(L);
2071 // Create object on stack
2072 ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack
2073 int object = lua_gettop(L);
2075 // Get minetest.object_refs table
2076 lua_getglobal(L, "minetest");
2077 lua_getfield(L, -1, "object_refs");
2078 luaL_checktype(L, -1, LUA_TTABLE);
2079 int objectstable = lua_gettop(L);
2081 // object_refs[id] = object
2082 lua_pushnumber(L, cobj->getId()); // Push id
2083 lua_pushvalue(L, object); // Copy object to top of stack
2084 lua_settable(L, objectstable);
2087 void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj)
2090 assert(lua_checkstack(L, 20));
2091 //infostream<<"scriptapi_rm_object_reference: id="<<cobj->getId()<<std::endl;
2092 StackUnroller stack_unroller(L);
2094 // Get minetest.object_refs table
2095 lua_getglobal(L, "minetest");
2096 lua_getfield(L, -1, "object_refs");
2097 luaL_checktype(L, -1, LUA_TTABLE);
2098 int objectstable = lua_gettop(L);
2100 // Get object_refs[id]
2101 lua_pushnumber(L, cobj->getId()); // Push id
2102 lua_gettable(L, objectstable);
2103 // Set object reference to NULL
2104 ObjectRef::set_null(L);
2105 lua_pop(L, 1); // pop object
2107 // Set object_refs[id] = nil
2108 lua_pushnumber(L, cobj->getId()); // Push id
2110 lua_settable(L, objectstable);
2113 bool scriptapi_on_chat_message(lua_State *L, const std::string &name,
2114 const std::string &message)
2117 assert(lua_checkstack(L, 20));
2118 StackUnroller stack_unroller(L);
2120 // Get minetest.registered_on_chat_messages
2121 lua_getglobal(L, "minetest");
2122 lua_getfield(L, -1, "registered_on_chat_messages");
2123 luaL_checktype(L, -1, LUA_TTABLE);
2124 int table = lua_gettop(L);
2127 while(lua_next(L, table) != 0){
2128 // key at index -2 and value at index -1
2129 luaL_checktype(L, -1, LUA_TFUNCTION);
2131 lua_pushstring(L, name.c_str());
2132 lua_pushstring(L, message.c_str());
2133 if(lua_pcall(L, 2, 1, 0))
2134 script_error(L, "error: %s\n", lua_tostring(L, -1));
2135 bool ate = lua_toboolean(L, -1);
2139 // value removed, keep key for next iteration
2148 void scriptapi_on_newplayer(lua_State *L, ServerActiveObject *player)
2151 assert(lua_checkstack(L, 20));
2152 StackUnroller stack_unroller(L);
2154 // Get minetest.registered_on_newplayers
2155 lua_getglobal(L, "minetest");
2156 lua_getfield(L, -1, "registered_on_newplayers");
2157 luaL_checktype(L, -1, LUA_TTABLE);
2158 int table = lua_gettop(L);
2161 while(lua_next(L, table) != 0){
2162 // key at index -2 and value at index -1
2163 luaL_checktype(L, -1, LUA_TFUNCTION);
2165 objectref_get_or_create(L, player);
2166 if(lua_pcall(L, 1, 0, 0))
2167 script_error(L, "error: %s\n", lua_tostring(L, -1));
2168 // value removed, keep key for next iteration
2171 bool scriptapi_on_respawnplayer(lua_State *L, ServerActiveObject *player)
2174 assert(lua_checkstack(L, 20));
2175 StackUnroller stack_unroller(L);
2177 bool positioning_handled_by_some = false;
2179 // Get minetest.registered_on_respawnplayers
2180 lua_getglobal(L, "minetest");
2181 lua_getfield(L, -1, "registered_on_respawnplayers");
2182 luaL_checktype(L, -1, LUA_TTABLE);
2183 int table = lua_gettop(L);
2186 while(lua_next(L, table) != 0){
2187 // key at index -2 and value at index -1
2188 luaL_checktype(L, -1, LUA_TFUNCTION);
2190 objectref_get_or_create(L, player);
2191 if(lua_pcall(L, 1, 1, 0))
2192 script_error(L, "error: %s\n", lua_tostring(L, -1));
2193 bool positioning_handled = lua_toboolean(L, -1);
2195 if(positioning_handled)
2196 positioning_handled_by_some = true;
2197 // value removed, keep key for next iteration
2199 return positioning_handled_by_some;
2206 void scriptapi_environment_step(lua_State *L, float dtime)
2209 assert(lua_checkstack(L, 20));
2210 //infostream<<"scriptapi_environment_step"<<std::endl;
2211 StackUnroller stack_unroller(L);
2213 // Get minetest.registered_globalsteps
2214 lua_getglobal(L, "minetest");
2215 lua_getfield(L, -1, "registered_globalsteps");
2216 luaL_checktype(L, -1, LUA_TTABLE);
2217 int table = lua_gettop(L);
2220 while(lua_next(L, table) != 0){
2221 // key at index -2 and value at index -1
2222 luaL_checktype(L, -1, LUA_TFUNCTION);
2224 lua_pushnumber(L, dtime);
2225 if(lua_pcall(L, 1, 0, 0))
2226 script_error(L, "error: %s\n", lua_tostring(L, -1));
2227 // value removed, keep key for next iteration
2231 void scriptapi_environment_on_placenode(lua_State *L, v3s16 p, MapNode newnode,
2232 ServerActiveObject *placer)
2235 assert(lua_checkstack(L, 20));
2236 //infostream<<"scriptapi_environment_on_placenode"<<std::endl;
2237 StackUnroller stack_unroller(L);
2239 // Get server from registry
2240 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
2241 Server *server = (Server*)lua_touserdata(L, -1);
2242 // And get the writable node definition manager from the server
2243 IWritableNodeDefManager *ndef =
2244 server->getWritableNodeDefManager();
2246 // Get minetest.registered_on_placenodes
2247 lua_getglobal(L, "minetest");
2248 lua_getfield(L, -1, "registered_on_placenodes");
2249 luaL_checktype(L, -1, LUA_TTABLE);
2250 int table = lua_gettop(L);
2253 while(lua_next(L, table) != 0){
2254 // key at index -2 and value at index -1
2255 luaL_checktype(L, -1, LUA_TFUNCTION);
2258 pushnode(L, newnode, ndef);
2259 objectref_get_or_create(L, placer);
2260 if(lua_pcall(L, 3, 0, 0))
2261 script_error(L, "error: %s\n", lua_tostring(L, -1));
2262 // value removed, keep key for next iteration
2266 void scriptapi_environment_on_dignode(lua_State *L, v3s16 p, MapNode oldnode,
2267 ServerActiveObject *digger)
2270 assert(lua_checkstack(L, 20));
2271 //infostream<<"scriptapi_environment_on_dignode"<<std::endl;
2272 StackUnroller stack_unroller(L);
2274 // Get server from registry
2275 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
2276 Server *server = (Server*)lua_touserdata(L, -1);
2277 // And get the writable node definition manager from the server
2278 IWritableNodeDefManager *ndef =
2279 server->getWritableNodeDefManager();
2281 // Get minetest.registered_on_dignodes
2282 lua_getglobal(L, "minetest");
2283 lua_getfield(L, -1, "registered_on_dignodes");
2284 luaL_checktype(L, -1, LUA_TTABLE);
2285 int table = lua_gettop(L);
2288 while(lua_next(L, table) != 0){
2289 // key at index -2 and value at index -1
2290 luaL_checktype(L, -1, LUA_TFUNCTION);
2293 pushnode(L, oldnode, ndef);
2294 objectref_get_or_create(L, digger);
2295 if(lua_pcall(L, 3, 0, 0))
2296 script_error(L, "error: %s\n", lua_tostring(L, -1));
2297 // value removed, keep key for next iteration
2301 void scriptapi_environment_on_punchnode(lua_State *L, v3s16 p, MapNode node,
2302 ServerActiveObject *puncher)
2305 assert(lua_checkstack(L, 20));
2306 //infostream<<"scriptapi_environment_on_punchnode"<<std::endl;
2307 StackUnroller stack_unroller(L);
2309 // Get server from registry
2310 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
2311 Server *server = (Server*)lua_touserdata(L, -1);
2312 // And get the writable node definition manager from the server
2313 IWritableNodeDefManager *ndef =
2314 server->getWritableNodeDefManager();
2316 // Get minetest.registered_on_punchnodes
2317 lua_getglobal(L, "minetest");
2318 lua_getfield(L, -1, "registered_on_punchnodes");
2319 luaL_checktype(L, -1, LUA_TTABLE);
2320 int table = lua_gettop(L);
2323 while(lua_next(L, table) != 0){
2324 // key at index -2 and value at index -1
2325 luaL_checktype(L, -1, LUA_TFUNCTION);
2328 pushnode(L, node, ndef);
2329 objectref_get_or_create(L, puncher);
2330 if(lua_pcall(L, 3, 0, 0))
2331 script_error(L, "error: %s\n", lua_tostring(L, -1));
2332 // value removed, keep key for next iteration
2336 void scriptapi_environment_on_generated(lua_State *L, v3s16 minp, v3s16 maxp)
2339 assert(lua_checkstack(L, 20));
2340 //infostream<<"scriptapi_environment_on_generated"<<std::endl;
2341 StackUnroller stack_unroller(L);
2343 // Get minetest.registered_on_generateds
2344 lua_getglobal(L, "minetest");
2345 lua_getfield(L, -1, "registered_on_generateds");
2346 luaL_checktype(L, -1, LUA_TTABLE);
2347 int table = lua_gettop(L);
2350 while(lua_next(L, table) != 0){
2351 // key at index -2 and value at index -1
2352 luaL_checktype(L, -1, LUA_TFUNCTION);
2356 if(lua_pcall(L, 2, 0, 0))
2357 script_error(L, "error: %s\n", lua_tostring(L, -1));
2358 // value removed, keep key for next iteration
2366 bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
2367 const std::string &staticdata)
2370 assert(lua_checkstack(L, 20));
2371 infostream<<"scriptapi_luaentity_add: id="<<id<<" name=\""
2372 <<name<<"\""<<std::endl;
2373 StackUnroller stack_unroller(L);
2375 // Get minetest.registered_entities[name]
2376 lua_getglobal(L, "minetest");
2377 lua_getfield(L, -1, "registered_entities");
2378 luaL_checktype(L, -1, LUA_TTABLE);
2379 lua_pushstring(L, name);
2380 lua_gettable(L, -2);
2381 // Should be a table, which we will use as a prototype
2382 //luaL_checktype(L, -1, LUA_TTABLE);
2383 if(lua_type(L, -1) != LUA_TTABLE){
2384 errorstream<<"LuaEntity name \""<<name<<"\" not defined"<<std::endl;
2387 int prototype_table = lua_gettop(L);
2388 //dump2(L, "prototype_table");
2390 // Create entity object
2392 int object = lua_gettop(L);
2394 // Set object metatable
2395 lua_pushvalue(L, prototype_table);
2396 lua_setmetatable(L, -2);
2398 // Add object reference
2399 // This should be userdata with metatable ObjectRef
2400 objectref_get(L, id);
2401 luaL_checktype(L, -1, LUA_TUSERDATA);
2402 if(!luaL_checkudata(L, -1, "ObjectRef"))
2403 luaL_typerror(L, -1, "ObjectRef");
2404 lua_setfield(L, -2, "object");
2406 // minetest.luaentities[id] = object
2407 lua_getglobal(L, "minetest");
2408 lua_getfield(L, -1, "luaentities");
2409 luaL_checktype(L, -1, LUA_TTABLE);
2410 lua_pushnumber(L, id); // Push id
2411 lua_pushvalue(L, object); // Copy object to top of stack
2412 lua_settable(L, -3);
2414 // Get on_activate function
2415 lua_pushvalue(L, object);
2416 lua_getfield(L, -1, "on_activate");
2417 if(!lua_isnil(L, -1)){
2418 luaL_checktype(L, -1, LUA_TFUNCTION);
2419 lua_pushvalue(L, object); // self
2420 lua_pushlstring(L, staticdata.c_str(), staticdata.size());
2421 // Call with 2 arguments, 0 results
2422 if(lua_pcall(L, 2, 0, 0))
2423 script_error(L, "error running function %s:on_activate: %s\n",
2424 name, lua_tostring(L, -1));
2430 void scriptapi_luaentity_rm(lua_State *L, u16 id)
2433 assert(lua_checkstack(L, 20));
2434 infostream<<"scriptapi_luaentity_rm: id="<<id<<std::endl;
2436 // Get minetest.luaentities table
2437 lua_getglobal(L, "minetest");
2438 lua_getfield(L, -1, "luaentities");
2439 luaL_checktype(L, -1, LUA_TTABLE);
2440 int objectstable = lua_gettop(L);
2442 // Set luaentities[id] = nil
2443 lua_pushnumber(L, id); // Push id
2445 lua_settable(L, objectstable);
2447 lua_pop(L, 2); // pop luaentities, minetest
2450 std::string scriptapi_luaentity_get_staticdata(lua_State *L, u16 id)
2453 assert(lua_checkstack(L, 20));
2454 infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl;
2455 StackUnroller stack_unroller(L);
2457 // Get minetest.luaentities[id]
2458 luaentity_get(L, id);
2459 int object = lua_gettop(L);
2461 // Get get_staticdata function
2462 lua_pushvalue(L, object);
2463 lua_getfield(L, -1, "get_staticdata");
2464 if(lua_isnil(L, -1))
2467 luaL_checktype(L, -1, LUA_TFUNCTION);
2468 lua_pushvalue(L, object); // self
2469 // Call with 1 arguments, 1 results
2470 if(lua_pcall(L, 1, 1, 0))
2471 script_error(L, "error running function get_staticdata: %s\n",
2472 lua_tostring(L, -1));
2475 const char *s = lua_tolstring(L, -1, &len);
2476 return std::string(s, len);
2479 void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
2480 LuaEntityProperties *prop)
2483 assert(lua_checkstack(L, 20));
2484 infostream<<"scriptapi_luaentity_get_properties: id="<<id<<std::endl;
2485 StackUnroller stack_unroller(L);
2487 // Get minetest.luaentities[id]
2488 luaentity_get(L, id);
2489 //int object = lua_gettop(L);
2493 getboolfield(L, -1, "physical", prop->physical);
2495 getfloatfield(L, -1, "weight", prop->weight);
2497 lua_getfield(L, -1, "collisionbox");
2498 if(lua_istable(L, -1))
2499 prop->collisionbox = read_aabbox3df32(L, -1, 1.0);
2502 getstringfield(L, -1, "visual", prop->visual);
2504 lua_getfield(L, -1, "visual_size");
2505 if(lua_istable(L, -1))
2506 prop->visual_size = read_v2f(L, -1);
2509 lua_getfield(L, -1, "textures");
2510 if(lua_istable(L, -1)){
2511 prop->textures.clear();
2512 int table = lua_gettop(L);
2514 while(lua_next(L, table) != 0){
2515 // key at index -2 and value at index -1
2516 if(lua_isstring(L, -1))
2517 prop->textures.push_back(lua_tostring(L, -1));
2519 prop->textures.push_back("");
2520 // removes value, keeps key for next iteration
2526 lua_getfield(L, -1, "spritediv");
2527 if(lua_istable(L, -1))
2528 prop->spritediv = read_v2s16(L, -1);
2531 lua_getfield(L, -1, "initial_sprite_basepos");
2532 if(lua_istable(L, -1))
2533 prop->initial_sprite_basepos = read_v2s16(L, -1);
2537 void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime)
2540 assert(lua_checkstack(L, 20));
2541 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
2542 StackUnroller stack_unroller(L);
2544 // Get minetest.luaentities[id]
2545 luaentity_get(L, id);
2546 int object = lua_gettop(L);
2547 // State: object is at top of stack
2548 // Get step function
2549 lua_getfield(L, -1, "on_step");
2550 if(lua_isnil(L, -1))
2552 luaL_checktype(L, -1, LUA_TFUNCTION);
2553 lua_pushvalue(L, object); // self
2554 lua_pushnumber(L, dtime); // dtime
2555 // Call with 2 arguments, 0 results
2556 if(lua_pcall(L, 2, 0, 0))
2557 script_error(L, "error running function 'on_step': %s\n", lua_tostring(L, -1));
2560 // Calls entity:on_punch(ObjectRef puncher)
2561 void scriptapi_luaentity_punch(lua_State *L, u16 id,
2562 ServerActiveObject *puncher)
2565 assert(lua_checkstack(L, 20));
2566 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
2567 StackUnroller stack_unroller(L);
2569 // Get minetest.luaentities[id]
2570 luaentity_get(L, id);
2571 int object = lua_gettop(L);
2572 // State: object is at top of stack
2574 lua_getfield(L, -1, "on_punch");
2575 if(lua_isnil(L, -1))
2577 luaL_checktype(L, -1, LUA_TFUNCTION);
2578 lua_pushvalue(L, object); // self
2579 objectref_get_or_create(L, puncher); // Clicker reference
2580 // Call with 2 arguments, 0 results
2581 if(lua_pcall(L, 2, 0, 0))
2582 script_error(L, "error running function 'on_punch': %s\n", lua_tostring(L, -1));
2585 // Calls entity:on_rightclick(ObjectRef clicker)
2586 void scriptapi_luaentity_rightclick(lua_State *L, u16 id,
2587 ServerActiveObject *clicker)
2590 assert(lua_checkstack(L, 20));
2591 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
2592 StackUnroller stack_unroller(L);
2594 // Get minetest.luaentities[id]
2595 luaentity_get(L, id);
2596 int object = lua_gettop(L);
2597 // State: object is at top of stack
2599 lua_getfield(L, -1, "on_rightclick");
2600 if(lua_isnil(L, -1))
2602 luaL_checktype(L, -1, LUA_TFUNCTION);
2603 lua_pushvalue(L, object); // self
2604 objectref_get_or_create(L, clicker); // Clicker reference
2605 // Call with 2 arguments, 0 results
2606 if(lua_pcall(L, 2, 0, 0))
2607 script_error(L, "error running function 'on_rightclick': %s\n", lua_tostring(L, -1));