Allow server-side teleporting
[oweals/minetest.git] / src / scriptapi.cpp
1 /*
2 Minetest-c55
3 Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
4
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.
9
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.
14
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.
18 */
19
20 #include "scriptapi.h"
21
22 #include <iostream>
23 extern "C" {
24 #include <lua.h>
25 #include <lualib.h>
26 #include <lauxlib.h>
27 }
28
29 #include "log.h"
30 #include "server.h"
31 #include "porting.h"
32 #include "filesys.h"
33 #include "serverobject.h"
34 #include "script.h"
35 //#include "luna.h"
36 #include "luaentity_common.h"
37 #include "content_sao.h" // For LuaEntitySAO
38 #include "tooldef.h"
39 #include "nodedef.h"
40 #include "craftdef.h"
41 #include "main.h" // For g_settings
42 #include "settings.h" // For accessing g_settings
43
44 /*
45 TODO:
46 - Random node triggers (like grass growth)
47 - All kinds of callbacks
48 - Object visual client-side stuff
49         - Blink effect
50         - Spritesheets and animation
51 - LuaNodeMetadata
52         blockdef.metadata_name =
53                 ""
54                 "sign"
55                 "furnace"
56                 "chest"
57                 "locked_chest"
58                 "lua"
59         - Stores an inventory and stuff in a Settings object
60         meta.inventory_add_list("main")
61         blockdef.on_inventory_modified
62         meta.set("owner", playername)
63         meta.get("owner")
64 - Item definition (actually, only CraftItem)
65 - (not scripting) Putting items in node metadata (virtual)
66 */
67
68 static void stackDump(lua_State *L, std::ostream &o)
69 {
70   int i;
71   int top = lua_gettop(L);
72   for (i = 1; i <= top; i++) {  /* repeat for each level */
73         int t = lua_type(L, i);
74         switch (t) {
75
76           case LUA_TSTRING:  /* strings */
77                 o<<"\""<<lua_tostring(L, i)<<"\"";
78                 break;
79
80           case LUA_TBOOLEAN:  /* booleans */
81                 o<<(lua_toboolean(L, i) ? "true" : "false");
82                 break;
83
84           case LUA_TNUMBER:  /* numbers */ {
85                 char buf[10];
86                 snprintf(buf, 10, "%g", lua_tonumber(L, i));
87                 o<<buf;
88                 break; }
89
90           default:  /* other values */
91                 o<<lua_typename(L, t);
92                 break;
93
94         }
95         o<<" ";
96   }
97   o<<std::endl;
98 }
99
100 static void realitycheck(lua_State *L)
101 {
102         int top = lua_gettop(L);
103         if(top >= 30){
104                 dstream<<"Stack is over 30:"<<std::endl;
105                 stackDump(L, dstream);
106                 script_error(L, "Stack is over 30 (reality check)");
107         }
108 }
109
110 class StackUnroller
111 {
112 private:
113         lua_State *m_lua;
114         int m_original_top;
115 public:
116         StackUnroller(lua_State *L):
117                 m_lua(L),
118                 m_original_top(-1)
119         {
120                 m_original_top = lua_gettop(m_lua); // store stack height
121         }
122         ~StackUnroller()
123         {
124                 lua_settop(m_lua, m_original_top); // restore stack height
125         }
126 };
127
128 static v3f readFloatPos(lua_State *L, int index)
129 {
130         v3f pos;
131         luaL_checktype(L, index, LUA_TTABLE);
132         lua_getfield(L, index, "x");
133         pos.X = lua_tonumber(L, -1);
134         lua_pop(L, 1);
135         lua_getfield(L, index, "y");
136         pos.Y = lua_tonumber(L, -1);
137         lua_pop(L, 1);
138         lua_getfield(L, index, "z");
139         pos.Z = lua_tonumber(L, -1);
140         lua_pop(L, 1);
141         pos *= BS; // Scale to internal format
142         return pos;
143 }
144
145 static void pushFloatPos(lua_State *L, v3f p)
146 {
147         p /= BS;
148         lua_newtable(L);
149         lua_pushnumber(L, p.X);
150         lua_setfield(L, -2, "x");
151         lua_pushnumber(L, p.Y);
152         lua_setfield(L, -2, "y");
153         lua_pushnumber(L, p.Z);
154         lua_setfield(L, -2, "z");
155 }
156
157 static void pushpos(lua_State *L, v3s16 p)
158 {
159         lua_newtable(L);
160         lua_pushnumber(L, p.X);
161         lua_setfield(L, -2, "x");
162         lua_pushnumber(L, p.Y);
163         lua_setfield(L, -2, "y");
164         lua_pushnumber(L, p.Z);
165         lua_setfield(L, -2, "z");
166 }
167
168 static v3s16 readpos(lua_State *L, int index)
169 {
170         // Correct rounding at <0
171         v3f pf = readFloatPos(L, index);
172         return floatToInt(pf, BS);
173 }
174
175 static void pushnode(lua_State *L, const MapNode &n, INodeDefManager *ndef)
176 {
177         lua_newtable(L);
178         lua_pushstring(L, ndef->get(n).name.c_str());
179         lua_setfield(L, -2, "name");
180         lua_pushnumber(L, n.getParam1());
181         lua_setfield(L, -2, "param1");
182         lua_pushnumber(L, n.getParam2());
183         lua_setfield(L, -2, "param2");
184 }
185
186 static MapNode readnode(lua_State *L, int index, INodeDefManager *ndef)
187 {
188         lua_getfield(L, index, "name");
189         const char *name = lua_tostring(L, -1);
190         lua_pop(L, 1);
191         u8 param1;
192         lua_getfield(L, index, "param1");
193         if(lua_isnil(L, -1))
194                 param1 = 0;
195         else
196                 param1 = lua_tonumber(L, -1);
197         lua_pop(L, 1);
198         u8 param2;
199         lua_getfield(L, index, "param2");
200         if(lua_isnil(L, -1))
201                 param2 = 0;
202         else
203                 param2 = lua_tonumber(L, -1);
204         lua_pop(L, 1);
205         return MapNode(ndef, name, param1, param2);
206 }
207
208 static video::SColor readARGB8(lua_State *L, int index)
209 {
210         video::SColor color;
211         luaL_checktype(L, index, LUA_TTABLE);
212         lua_getfield(L, index, "a");
213         if(lua_isnumber(L, -1))
214                 color.setAlpha(lua_tonumber(L, -1));
215         lua_pop(L, 1);
216         lua_getfield(L, index, "r");
217         color.setRed(lua_tonumber(L, -1));
218         lua_pop(L, 1);
219         lua_getfield(L, index, "g");
220         color.setGreen(lua_tonumber(L, -1));
221         lua_pop(L, 1);
222         lua_getfield(L, index, "b");
223         color.setBlue(lua_tonumber(L, -1));
224         lua_pop(L, 1);
225         return color;
226 }
227
228 static core::aabbox3d<f32> read_aabbox3df32(lua_State *L, int index, f32 scale)
229 {
230         core::aabbox3d<f32> box;
231         if(lua_istable(L, -1)){
232                 lua_rawgeti(L, -1, 1);
233                 box.MinEdge.X = lua_tonumber(L, -1) * scale;
234                 lua_pop(L, 1);
235                 lua_rawgeti(L, -1, 2);
236                 box.MinEdge.Y = lua_tonumber(L, -1) * scale;
237                 lua_pop(L, 1);
238                 lua_rawgeti(L, -1, 3);
239                 box.MinEdge.Z = lua_tonumber(L, -1) * scale;
240                 lua_pop(L, 1);
241                 lua_rawgeti(L, -1, 4);
242                 box.MaxEdge.X = lua_tonumber(L, -1) * scale;
243                 lua_pop(L, 1);
244                 lua_rawgeti(L, -1, 5);
245                 box.MaxEdge.Y = lua_tonumber(L, -1) * scale;
246                 lua_pop(L, 1);
247                 lua_rawgeti(L, -1, 6);
248                 box.MaxEdge.Z = lua_tonumber(L, -1) * scale;
249                 lua_pop(L, 1);
250         }
251         return box;
252 }
253
254 static v2s16 read_v2s16(lua_State *L, int index)
255 {
256         v2s16 p;
257         luaL_checktype(L, index, LUA_TTABLE);
258         lua_getfield(L, index, "x");
259         p.X = lua_tonumber(L, -1);
260         lua_pop(L, 1);
261         lua_getfield(L, index, "y");
262         p.Y = lua_tonumber(L, -1);
263         lua_pop(L, 1);
264         return p;
265 }
266
267 static v2f read_v2f(lua_State *L, int index)
268 {
269         v2f p;
270         luaL_checktype(L, index, LUA_TTABLE);
271         lua_getfield(L, index, "x");
272         p.X = lua_tonumber(L, -1);
273         lua_pop(L, 1);
274         lua_getfield(L, index, "y");
275         p.Y = lua_tonumber(L, -1);
276         lua_pop(L, 1);
277         return p;
278 }
279
280 static bool getstringfield(lua_State *L, int table,
281                 const char *fieldname, std::string &result)
282 {
283         lua_getfield(L, table, fieldname);
284         bool got = false;
285         if(lua_isstring(L, -1)){
286                 result = lua_tostring(L, -1);
287                 got = true;
288         }
289         lua_pop(L, 1);
290         return got;
291 }
292
293 static bool getintfield(lua_State *L, int table,
294                 const char *fieldname, int &result)
295 {
296         lua_getfield(L, table, fieldname);
297         bool got = false;
298         if(lua_isnumber(L, -1)){
299                 result = lua_tonumber(L, -1);
300                 got = true;
301         }
302         lua_pop(L, 1);
303         return got;
304 }
305
306 static bool getfloatfield(lua_State *L, int table,
307                 const char *fieldname, float &result)
308 {
309         lua_getfield(L, table, fieldname);
310         bool got = false;
311         if(lua_isnumber(L, -1)){
312                 result = lua_tonumber(L, -1);
313                 got = true;
314         }
315         lua_pop(L, 1);
316         return got;
317 }
318
319 static bool getboolfield(lua_State *L, int table,
320                 const char *fieldname, bool &result)
321 {
322         lua_getfield(L, table, fieldname);
323         bool got = false;
324         if(lua_isboolean(L, -1)){
325                 result = lua_toboolean(L, -1);
326                 got = true;
327         }
328         lua_pop(L, 1);
329         return got;
330 }
331
332 static std::string getstringfield_default(lua_State *L, int table,
333                 const char *fieldname, const std::string &default_)
334 {
335         std::string result = default_;
336         getstringfield(L, table, fieldname, result);
337         return result;
338 }
339
340 static int getintfield_default(lua_State *L, int table,
341                 const char *fieldname, int default_)
342 {
343         int result = default_;
344         getintfield(L, table, fieldname, result);
345         return result;
346 }
347
348 /*static float getfloatfield_default(lua_State *L, int table,
349                 const char *fieldname, float default_)
350 {
351         float result = default_;
352         getfloatfield(L, table, fieldname, result);
353         return result;
354 }*/
355
356 static bool getboolfield_default(lua_State *L, int table,
357                 const char *fieldname, bool default_)
358 {
359         bool result = default_;
360         getboolfield(L, table, fieldname, result);
361         return result;
362 }
363
364 struct EnumString
365 {
366         int num;
367         const char *str;
368 };
369
370 static bool string_to_enum(const EnumString *spec, int &result,
371                 const std::string &str)
372 {
373         const EnumString *esp = spec;
374         while(esp->str){
375                 if(str == std::string(esp->str)){
376                         result = esp->num;
377                         return true;
378                 }
379                 esp++;
380         }
381         return false;
382 }
383
384 /*static bool enum_to_string(const EnumString *spec, std::string &result,
385                 int num)
386 {
387         const EnumString *esp = spec;
388         while(esp){
389                 if(num == esp->num){
390                         result = esp->str;
391                         return true;
392                 }
393                 esp++;
394         }
395         return false;
396 }*/
397
398 static int getenumfield(lua_State *L, int table,
399                 const char *fieldname, const EnumString *spec, int default_)
400 {
401         int result = default_;
402         string_to_enum(spec, result,
403                         getstringfield_default(L, table, fieldname, ""));
404         return result;
405 }
406
407 struct EnumString es_DrawType[] =
408 {
409         {NDT_NORMAL, "normal"},
410         {NDT_AIRLIKE, "airlike"},
411         {NDT_LIQUID, "liquid"},
412         {NDT_FLOWINGLIQUID, "flowingliquid"},
413         {NDT_GLASSLIKE, "glasslike"},
414         {NDT_ALLFACES, "allfaces"},
415         {NDT_ALLFACES_OPTIONAL, "allfaces_optional"},
416         {NDT_TORCHLIKE, "torchlike"},
417         {NDT_SIGNLIKE, "signlike"},
418         {NDT_PLANTLIKE, "plantlike"},
419         {NDT_FENCELIKE, "fencelike"},
420         {NDT_RAILLIKE, "raillike"},
421         {0, NULL},
422 };
423
424 struct EnumString es_ContentParamType[] =
425 {
426         {CPT_NONE, "none"},
427         {CPT_LIGHT, "light"},
428         {CPT_MINERAL, "mineral"},
429         {CPT_FACEDIR_SIMPLE, "facedir_simple"},
430 };
431
432 struct EnumString es_LiquidType[] =
433 {
434         {LIQUID_NONE, "none"},
435         {LIQUID_FLOWING, "flowing"},
436         {LIQUID_SOURCE, "source"},
437 };
438
439 struct EnumString es_NodeBoxType[] =
440 {
441         {NODEBOX_REGULAR, "regular"},
442         {NODEBOX_FIXED, "fixed"},
443         {NODEBOX_WALLMOUNTED, "wallmounted"},
444 };
445
446 struct EnumString es_Diggability[] =
447 {
448         {DIGGABLE_NOT, "not"},
449         {DIGGABLE_NORMAL, "normal"},
450         {DIGGABLE_CONSTANT, "constant"},
451 };
452
453 /*
454         Global functions
455 */
456
457 static int l_register_nodedef_defaults(lua_State *L)
458 {
459         luaL_checktype(L, 1, LUA_TTABLE);
460
461         lua_pushvalue(L, 1); // Explicitly put parameter 1 on top of stack
462         lua_setfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
463
464         return 0;
465 }
466
467 // Register new object prototype
468 // register_entity(name, prototype)
469 static int l_register_entity(lua_State *L)
470 {
471         const char *name = luaL_checkstring(L, 1);
472         infostream<<"register_entity: "<<name<<std::endl;
473         luaL_checktype(L, 2, LUA_TTABLE);
474
475         // Get minetest.registered_entities
476         lua_getglobal(L, "minetest");
477         lua_getfield(L, -1, "registered_entities");
478         luaL_checktype(L, -1, LUA_TTABLE);
479         int registered_entities = lua_gettop(L);
480         lua_pushvalue(L, 2); // Object = param 2 -> stack top
481         // registered_entities[name] = object
482         lua_setfield(L, registered_entities, name);
483         
484         // Get registered object to top of stack
485         lua_pushvalue(L, 2);
486         
487         // Set __index to point to itself
488         lua_pushvalue(L, -1);
489         lua_setfield(L, -2, "__index");
490
491         // Set metatable.__index = metatable
492         luaL_getmetatable(L, "minetest.entity");
493         lua_pushvalue(L, -1); // duplicate metatable
494         lua_setfield(L, -2, "__index");
495         // Set object metatable
496         lua_setmetatable(L, -2);
497
498         return 0; /* number of results */
499 }
500
501 // register_tool(name, {lots of stuff})
502 static int l_register_tool(lua_State *L)
503 {
504         const char *name = luaL_checkstring(L, 1);
505         infostream<<"register_tool: "<<name<<std::endl;
506         luaL_checktype(L, 2, LUA_TTABLE);
507         int table = 2;
508
509         // Get server from registry
510         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
511         Server *server = (Server*)lua_touserdata(L, -1);
512         // And get the writable tool definition manager from the server
513         IWritableToolDefManager *tooldef =
514                         server->getWritableToolDefManager();
515         
516         ToolDefinition def;
517         
518         getstringfield(L, table, "image", def.imagename);
519         getfloatfield(L, table, "basetime", def.properties.basetime);
520         getfloatfield(L, table, "dt_weight", def.properties.dt_weight);
521         getfloatfield(L, table, "dt_crackiness", def.properties.dt_crackiness);
522         getfloatfield(L, table, "dt_crumbliness", def.properties.dt_crumbliness);
523         getfloatfield(L, table, "dt_cuttability", def.properties.dt_cuttability);
524         getfloatfield(L, table, "basedurability", def.properties.basedurability);
525         getfloatfield(L, table, "dd_weight", def.properties.dd_weight);
526         getfloatfield(L, table, "dd_crackiness", def.properties.dd_crackiness);
527         getfloatfield(L, table, "dd_crumbliness", def.properties.dd_crumbliness);
528         getfloatfield(L, table, "dd_cuttability", def.properties.dd_cuttability);
529
530         tooldef->registerTool(name, def);
531         return 0; /* number of results */
532 }
533
534 // register_node(name, {lots of stuff})
535 static int l_register_node(lua_State *L)
536 {
537         const char *name = luaL_checkstring(L, 1);
538         infostream<<"register_node: "<<name<<std::endl;
539         luaL_checktype(L, 2, LUA_TTABLE);
540         int nodedef_table = 2;
541
542         // Get server from registry
543         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
544         Server *server = (Server*)lua_touserdata(L, -1);
545         // And get the writable node definition manager from the server
546         IWritableNodeDefManager *nodedef =
547                         server->getWritableNodeDefManager();
548         
549         // Get default node definition from registry
550         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
551         int nodedef_default = lua_gettop(L);
552
553         /*
554                 Add to minetest.registered_nodes with default as metatable
555         */
556         
557         // Get the node definition table given as parameter
558         lua_pushvalue(L, nodedef_table);
559
560         // Set __index to point to itself
561         lua_pushvalue(L, -1);
562         lua_setfield(L, -2, "__index");
563
564         // Set nodedef_default as metatable for the definition
565         lua_pushvalue(L, nodedef_default);
566         lua_setmetatable(L, nodedef_table);
567         
568         // minetest.registered_nodes[name] = nodedef
569         lua_getglobal(L, "minetest");
570         lua_getfield(L, -1, "registered_nodes");
571         luaL_checktype(L, -1, LUA_TTABLE);
572         lua_pushstring(L, name);
573         lua_pushvalue(L, nodedef_table);
574         lua_settable(L, -3);
575
576         /*
577                 Create definition
578         */
579         
580         ContentFeatures f;
581
582         // Default to getting the corresponding NodeItem when dug
583         f.dug_item = std::string("NodeItem \"")+name+"\" 1";
584         
585         // Default to unknown_block.png as all textures
586         f.setAllTextures("unknown_block.png");
587
588         /*
589                 Read definiton from Lua
590         */
591
592         f.name = name;
593         
594         /* Visual definition */
595
596         f.drawtype = (NodeDrawType)getenumfield(L, nodedef_table, "drawtype", es_DrawType,
597                         NDT_NORMAL);
598         getfloatfield(L, nodedef_table, "visual_scale", f.visual_scale);
599
600         lua_getfield(L, nodedef_table, "tile_images");
601         if(lua_istable(L, -1)){
602                 int table = lua_gettop(L);
603                 lua_pushnil(L);
604                 int i = 0;
605                 while(lua_next(L, table) != 0){
606                         // key at index -2 and value at index -1
607                         if(lua_isstring(L, -1))
608                                 f.tname_tiles[i] = lua_tostring(L, -1);
609                         else
610                                 f.tname_tiles[i] = "";
611                         // removes value, keeps key for next iteration
612                         lua_pop(L, 1);
613                         i++;
614                         if(i==6){
615                                 lua_pop(L, 1);
616                                 break;
617                         }
618                 }
619                 // Copy last value to all remaining textures
620                 if(i >= 1){
621                         std::string lastname = f.tname_tiles[i-1];
622                         while(i < 6){
623                                 f.tname_tiles[i] = lastname;
624                                 i++;
625                         }
626                 }
627         }
628         lua_pop(L, 1);
629
630         getstringfield(L, nodedef_table, "inventory_image", f.tname_inventory);
631
632         lua_getfield(L, nodedef_table, "special_materials");
633         if(lua_istable(L, -1)){
634                 int table = lua_gettop(L);
635                 lua_pushnil(L);
636                 int i = 0;
637                 while(lua_next(L, table) != 0){
638                         // key at index -2 and value at index -1
639                         int smtable = lua_gettop(L);
640                         std::string tname = getstringfield_default(
641                                         L, smtable, "image", "");
642                         bool backface_culling = getboolfield_default(
643                                         L, smtable, "backface_culling", true);
644                         MaterialSpec mspec(tname, backface_culling);
645                         f.setSpecialMaterial(i, mspec);
646                         // removes value, keeps key for next iteration
647                         lua_pop(L, 1);
648                         i++;
649                         if(i==6){
650                                 lua_pop(L, 1);
651                                 break;
652                         }
653                 }
654         }
655         lua_pop(L, 1);
656
657         f.alpha = getintfield_default(L, nodedef_table, "alpha", 255);
658
659         /* Other stuff */
660         
661         lua_getfield(L, nodedef_table, "post_effect_color");
662         if(!lua_isnil(L, -1))
663                 f.post_effect_color = readARGB8(L, -1);
664         lua_pop(L, 1);
665
666         f.param_type = (ContentParamType)getenumfield(L, nodedef_table, "paramtype",
667                         es_ContentParamType, CPT_NONE);
668         
669         // True for all ground-like things like stone and mud, false for eg. trees
670         getboolfield(L, nodedef_table, "is_ground_content", f.is_ground_content);
671         getboolfield(L, nodedef_table, "light_propagates", f.light_propagates);
672         getboolfield(L, nodedef_table, "sunlight_propagates", f.sunlight_propagates);
673         // This is used for collision detection.
674         // Also for general solidness queries.
675         getboolfield(L, nodedef_table, "walkable", f.walkable);
676         // Player can point to these
677         getboolfield(L, nodedef_table, "pointable", f.pointable);
678         // Player can dig these
679         getboolfield(L, nodedef_table, "diggable", f.diggable);
680         // Player can climb these
681         getboolfield(L, nodedef_table, "climbable", f.climbable);
682         // Player can build on these
683         getboolfield(L, nodedef_table, "buildable_to", f.buildable_to);
684         // If true, param2 is set to direction when placed. Used for torches.
685         // NOTE: the direction format is quite inefficient and should be changed
686         getboolfield(L, nodedef_table, "wall_mounted", f.wall_mounted);
687         // Whether this content type often contains mineral.
688         // Used for texture atlas creation.
689         // Currently only enabled for CONTENT_STONE.
690         getboolfield(L, nodedef_table, "often_contains_mineral", f.often_contains_mineral);
691         // Inventory item string as which the node appears in inventory when dug.
692         // Mineral overrides this.
693         getstringfield(L, nodedef_table, "dug_item", f.dug_item);
694         // Extra dug item and its rarity
695         getstringfield(L, nodedef_table, "extra_dug_item", f.extra_dug_item);
696         // Usual get interval for extra dug item
697         getintfield(L, nodedef_table, "extra_dug_item_rarity", f.extra_dug_item_rarity);
698         // Metadata name of node (eg. "furnace")
699         getstringfield(L, nodedef_table, "metadata_name", f.metadata_name);
700         // Whether the node is non-liquid, source liquid or flowing liquid
701         f.liquid_type = (LiquidType)getenumfield(L, nodedef_table, "liquidtype",
702                         es_LiquidType, LIQUID_NONE);
703         // If the content is liquid, this is the flowing version of the liquid.
704         getstringfield(L, nodedef_table, "liquid_alternative_flowing",
705                         f.liquid_alternative_flowing);
706         // If the content is liquid, this is the source version of the liquid.
707         getstringfield(L, nodedef_table, "liquid_alternative_source",
708                         f.liquid_alternative_source);
709         // Viscosity for fluid flow, ranging from 1 to 7, with
710         // 1 giving almost instantaneous propagation and 7 being
711         // the slowest possible
712         f.liquid_viscosity = getintfield_default(L, nodedef_table,
713                         "liquid_viscosity", f.liquid_viscosity);
714         // Amount of light the node emits
715         f.light_source = getintfield_default(L, nodedef_table,
716                         "light_source", f.light_source);
717         f.damage_per_second = getintfield_default(L, nodedef_table,
718                         "damage_per_second", f.damage_per_second);
719         
720         lua_getfield(L, nodedef_table, "selection_box");
721         if(lua_istable(L, -1)){
722                 f.selection_box.type = (NodeBoxType)getenumfield(L, -1, "type",
723                                 es_NodeBoxType, NODEBOX_REGULAR);
724
725                 lua_getfield(L, -1, "fixed");
726                 if(lua_istable(L, -1))
727                         f.selection_box.fixed = read_aabbox3df32(L, -1, BS);
728                 lua_pop(L, 1);
729
730                 lua_getfield(L, -1, "wall_top");
731                 if(lua_istable(L, -1))
732                         f.selection_box.wall_top = read_aabbox3df32(L, -1, BS);
733                 lua_pop(L, 1);
734
735                 lua_getfield(L, -1, "wall_bottom");
736                 if(lua_istable(L, -1))
737                         f.selection_box.wall_bottom = read_aabbox3df32(L, -1, BS);
738                 lua_pop(L, 1);
739
740                 lua_getfield(L, -1, "wall_side");
741                 if(lua_istable(L, -1))
742                         f.selection_box.wall_side = read_aabbox3df32(L, -1, BS);
743                 lua_pop(L, 1);
744         }
745         lua_pop(L, 1);
746
747         lua_getfield(L, nodedef_table, "material");
748         if(lua_istable(L, -1)){
749                 f.material.diggability = (Diggability)getenumfield(L, -1, "diggability",
750                                 es_Diggability, DIGGABLE_NORMAL);
751                 
752                 getfloatfield(L, -1, "constant_time", f.material.constant_time);
753                 getfloatfield(L, -1, "weight", f.material.weight);
754                 getfloatfield(L, -1, "crackiness", f.material.crackiness);
755                 getfloatfield(L, -1, "crumbliness", f.material.crumbliness);
756                 getfloatfield(L, -1, "cuttability", f.material.cuttability);
757                 getfloatfield(L, -1, "flammability", f.material.flammability);
758         }
759         lua_pop(L, 1);
760
761         getstringfield(L, nodedef_table, "cookresult_item", f.cookresult_item);
762         getfloatfield(L, nodedef_table, "furnace_cooktime", f.furnace_cooktime);
763         getfloatfield(L, nodedef_table, "furnace_burntime", f.furnace_burntime);
764         
765         /*
766                 Register it
767         */
768         
769         nodedef->set(name, f);
770         
771         return 0; /* number of results */
772 }
773
774 // register_craft({output=item, recipe={{item00,item10},{item01,item11}})
775 static int l_register_craft(lua_State *L)
776 {
777         infostream<<"register_craft"<<std::endl;
778         luaL_checktype(L, 1, LUA_TTABLE);
779         int table0 = 1;
780
781         // Get server from registry
782         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
783         Server *server = (Server*)lua_touserdata(L, -1);
784         // And get the writable craft definition manager from the server
785         IWritableCraftDefManager *craftdef =
786                         server->getWritableCraftDefManager();
787         
788         std::string output;
789         int width = 0;
790         std::vector<std::string> input;
791
792         lua_getfield(L, table0, "output");
793         luaL_checktype(L, -1, LUA_TSTRING);
794         if(lua_isstring(L, -1))
795                 output = lua_tostring(L, -1);
796         lua_pop(L, 1);
797
798         lua_getfield(L, table0, "recipe");
799         luaL_checktype(L, -1, LUA_TTABLE);
800         if(lua_istable(L, -1)){
801                 int table1 = lua_gettop(L);
802                 lua_pushnil(L);
803                 int rowcount = 0;
804                 while(lua_next(L, table1) != 0){
805                         int colcount = 0;
806                         // key at index -2 and value at index -1
807                         luaL_checktype(L, -1, LUA_TTABLE);
808                         if(lua_istable(L, -1)){
809                                 int table2 = lua_gettop(L);
810                                 lua_pushnil(L);
811                                 while(lua_next(L, table2) != 0){
812                                         // key at index -2 and value at index -1
813                                         luaL_checktype(L, -1, LUA_TSTRING);
814                                         input.push_back(lua_tostring(L, -1));
815                                         // removes value, keeps key for next iteration
816                                         lua_pop(L, 1);
817                                         colcount++;
818                                 }
819                         }
820                         if(rowcount == 0){
821                                 width = colcount;
822                         } else {
823                                 if(colcount != width){
824                                         script_error(L, "error: %s\n", "Invalid crafting recipe");
825                                 }
826                         }
827                         // removes value, keeps key for next iteration
828                         lua_pop(L, 1);
829                         rowcount++;
830                 }
831         }
832         lua_pop(L, 1);
833
834         CraftDefinition def(output, width, input);
835         craftdef->registerCraft(def);
836
837         return 0; /* number of results */
838 }
839
840 static int register_lua_callback(lua_State *L, const char *tablename)
841 {
842         luaL_checktype(L, 1, LUA_TFUNCTION);
843
844         lua_getglobal(L, "table");
845         lua_getfield(L, -1, "insert");
846         int table_insert = lua_gettop(L);
847         // Get minetest.registered_globalsteps
848         lua_getglobal(L, "minetest");
849         lua_getfield(L, -1, tablename);
850         luaL_checktype(L, -1, LUA_TTABLE);
851         int registered = lua_gettop(L);
852         // table.insert(registered_globalsteps, func)
853         lua_pushvalue(L, table_insert);
854         lua_pushvalue(L, registered);
855         lua_pushvalue(L, 1); // push function from argument 1
856         // Call insert
857         if(lua_pcall(L, 2, 0, 0))
858                 script_error(L, "error: %s\n", lua_tostring(L, -1));
859
860         return 0; /* number of results */
861 }
862
863 // Register a global step function
864 // register_globalstep(function)
865 static int l_register_globalstep(lua_State *L)
866 {
867         infostream<<"register_globalstep"<<std::endl;
868         return register_lua_callback(L, "registered_globalsteps");
869 }
870
871 // register_on_placenode(function)
872 static int l_register_on_placenode(lua_State *L)
873 {
874         infostream<<"register_on_placenode"<<std::endl;
875         return register_lua_callback(L, "registered_on_placenodes");
876 }
877
878 // register_on_dignode(function)
879 static int l_register_on_dignode(lua_State *L)
880 {
881         infostream<<"register_on_dignode"<<std::endl;
882         return register_lua_callback(L, "registered_on_dignodes");
883 }
884
885 // register_on_punchnode(function)
886 static int l_register_on_punchnode(lua_State *L)
887 {
888         infostream<<"register_on_punchnode"<<std::endl;
889         return register_lua_callback(L, "registered_on_punchnodes");
890 }
891
892 // register_on_generated(function)
893 static int l_register_on_generated(lua_State *L)
894 {
895         infostream<<"register_on_generated"<<std::endl;
896         return register_lua_callback(L, "registered_on_generateds");
897 }
898
899 // register_on_newplayer(function)
900 static int l_register_on_newplayer(lua_State *L)
901 {
902         infostream<<"register_on_newplayer"<<std::endl;
903         return register_lua_callback(L, "registered_on_newplayers");
904 }
905
906 // register_on_respawnplayer(function)
907 static int l_register_on_respawnplayer(lua_State *L)
908 {
909         infostream<<"register_on_respawnplayer"<<std::endl;
910         return register_lua_callback(L, "registered_on_respawnplayers");
911 }
912
913 // setting_get(name)
914 static int l_setting_get(lua_State *L)
915 {
916         const char *name = luaL_checkstring(L, 1);
917         try{
918                 std::string value = g_settings->get(name);
919                 lua_pushstring(L, value.c_str());
920         } catch(SettingNotFoundException &e){
921                 lua_pushnil(L);
922         }
923         return 1;
924 }
925
926 // setting_getbool(name)
927 static int l_setting_getbool(lua_State *L)
928 {
929         const char *name = luaL_checkstring(L, 1);
930         try{
931                 bool value = g_settings->getBool(name);
932                 lua_pushboolean(L, value);
933         } catch(SettingNotFoundException &e){
934                 lua_pushnil(L);
935         }
936         return 1;
937 }
938
939 static const struct luaL_Reg minetest_f [] = {
940         {"register_nodedef_defaults", l_register_nodedef_defaults},
941         {"register_entity", l_register_entity},
942         {"register_tool", l_register_tool},
943         {"register_node", l_register_node},
944         {"register_craft", l_register_craft},
945         {"register_globalstep", l_register_globalstep},
946         {"register_on_placenode", l_register_on_placenode},
947         {"register_on_dignode", l_register_on_dignode},
948         {"register_on_punchnode", l_register_on_punchnode},
949         {"register_on_generated", l_register_on_generated},
950         {"register_on_newplayer", l_register_on_newplayer},
951         {"register_on_respawnplayer", l_register_on_respawnplayer},
952         {"setting_get", l_setting_get},
953         {"setting_getbool", l_setting_getbool},
954         {NULL, NULL}
955 };
956
957 /*
958         LuaEntity functions
959 */
960
961 static const struct luaL_Reg minetest_entity_m [] = {
962         {NULL, NULL}
963 };
964
965 /*
966         Getters for stuff in main tables
967 */
968
969 static void objectref_get(lua_State *L, u16 id)
970 {
971         // Get minetest.object_refs[i]
972         lua_getglobal(L, "minetest");
973         lua_getfield(L, -1, "object_refs");
974         luaL_checktype(L, -1, LUA_TTABLE);
975         lua_pushnumber(L, id);
976         lua_gettable(L, -2);
977         lua_remove(L, -2); // object_refs
978         lua_remove(L, -2); // minetest
979 }
980
981 static void luaentity_get(lua_State *L, u16 id)
982 {
983         // Get minetest.luaentities[i]
984         lua_getglobal(L, "minetest");
985         lua_getfield(L, -1, "luaentities");
986         luaL_checktype(L, -1, LUA_TTABLE);
987         lua_pushnumber(L, id);
988         lua_gettable(L, -2);
989         lua_remove(L, -2); // luaentities
990         lua_remove(L, -2); // minetest
991 }
992
993 /*
994         Reference objects
995 */
996 #define method(class, name) {#name, class::l_##name}
997
998 class EnvRef
999 {
1000 private:
1001         ServerEnvironment *m_env;
1002
1003         static const char className[];
1004         static const luaL_reg methods[];
1005
1006         static EnvRef *checkobject(lua_State *L, int narg)
1007         {
1008                 luaL_checktype(L, narg, LUA_TUSERDATA);
1009                 void *ud = luaL_checkudata(L, narg, className);
1010                 if(!ud) luaL_typerror(L, narg, className);
1011                 return *(EnvRef**)ud;  // unbox pointer
1012         }
1013         
1014         // Exported functions
1015
1016         // EnvRef:add_node(pos, node)
1017         // pos = {x=num, y=num, z=num}
1018         static int l_add_node(lua_State *L)
1019         {
1020                 infostream<<"EnvRef::l_add_node()"<<std::endl;
1021                 EnvRef *o = checkobject(L, 1);
1022                 ServerEnvironment *env = o->m_env;
1023                 if(env == NULL) return 0;
1024                 // pos
1025                 v3s16 pos = readpos(L, 2);
1026                 // content
1027                 MapNode n = readnode(L, 3, env->getGameDef()->ndef());
1028                 // Do it
1029                 bool succeeded = env->getMap().addNodeWithEvent(pos, n);
1030                 lua_pushboolean(L, succeeded);
1031                 return 1;
1032         }
1033
1034         // EnvRef:remove_node(pos)
1035         // pos = {x=num, y=num, z=num}
1036         static int l_remove_node(lua_State *L)
1037         {
1038                 infostream<<"EnvRef::l_remove_node()"<<std::endl;
1039                 EnvRef *o = checkobject(L, 1);
1040                 ServerEnvironment *env = o->m_env;
1041                 if(env == NULL) return 0;
1042                 // pos
1043                 v3s16 pos = readpos(L, 2);
1044                 // Do it
1045                 bool succeeded = env->getMap().removeNodeWithEvent(pos);
1046                 lua_pushboolean(L, succeeded);
1047                 return 1;
1048         }
1049
1050         // EnvRef:get_node(pos)
1051         // pos = {x=num, y=num, z=num}
1052         static int l_get_node(lua_State *L)
1053         {
1054                 infostream<<"EnvRef::l_get_node()"<<std::endl;
1055                 EnvRef *o = checkobject(L, 1);
1056                 ServerEnvironment *env = o->m_env;
1057                 if(env == NULL) return 0;
1058                 // pos
1059                 v3s16 pos = readpos(L, 2);
1060                 // Do it
1061                 MapNode n = env->getMap().getNodeNoEx(pos);
1062                 // Return node
1063                 pushnode(L, n, env->getGameDef()->ndef());
1064                 return 1;
1065         }
1066
1067         // EnvRef:add_luaentity(pos, entityname)
1068         // pos = {x=num, y=num, z=num}
1069         static int l_add_luaentity(lua_State *L)
1070         {
1071                 infostream<<"EnvRef::l_add_luaentity()"<<std::endl;
1072                 EnvRef *o = checkobject(L, 1);
1073                 ServerEnvironment *env = o->m_env;
1074                 if(env == NULL) return 0;
1075                 // pos
1076                 v3f pos = readFloatPos(L, 2);
1077                 // content
1078                 const char *name = lua_tostring(L, 3);
1079                 // Do it
1080                 ServerActiveObject *obj = new LuaEntitySAO(env, pos, name, "");
1081                 env->addActiveObject(obj);
1082                 return 0;
1083         }
1084
1085         static int gc_object(lua_State *L) {
1086                 EnvRef *o = *(EnvRef **)(lua_touserdata(L, 1));
1087                 delete o;
1088                 return 0;
1089         }
1090
1091 public:
1092         EnvRef(ServerEnvironment *env):
1093                 m_env(env)
1094         {
1095                 infostream<<"EnvRef created"<<std::endl;
1096         }
1097
1098         ~EnvRef()
1099         {
1100                 infostream<<"EnvRef destructing"<<std::endl;
1101         }
1102
1103         // Creates an EnvRef and leaves it on top of stack
1104         // Not callable from Lua; all references are created on the C side.
1105         static void create(lua_State *L, ServerEnvironment *env)
1106         {
1107                 EnvRef *o = new EnvRef(env);
1108                 //infostream<<"EnvRef::create: o="<<o<<std::endl;
1109                 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1110                 luaL_getmetatable(L, className);
1111                 lua_setmetatable(L, -2);
1112         }
1113
1114         static void set_null(lua_State *L)
1115         {
1116                 EnvRef *o = checkobject(L, -1);
1117                 o->m_env = NULL;
1118         }
1119         
1120         static void Register(lua_State *L)
1121         {
1122                 lua_newtable(L);
1123                 int methodtable = lua_gettop(L);
1124                 luaL_newmetatable(L, className);
1125                 int metatable = lua_gettop(L);
1126
1127                 lua_pushliteral(L, "__metatable");
1128                 lua_pushvalue(L, methodtable);
1129                 lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
1130
1131                 lua_pushliteral(L, "__index");
1132                 lua_pushvalue(L, methodtable);
1133                 lua_settable(L, metatable);
1134
1135                 lua_pushliteral(L, "__gc");
1136                 lua_pushcfunction(L, gc_object);
1137                 lua_settable(L, metatable);
1138
1139                 lua_pop(L, 1);  // drop metatable
1140
1141                 luaL_openlib(L, 0, methods, 0);  // fill methodtable
1142                 lua_pop(L, 1);  // drop methodtable
1143
1144                 // Cannot be created from Lua
1145                 //lua_register(L, className, create_object);
1146         }
1147 };
1148 const char EnvRef::className[] = "EnvRef";
1149 const luaL_reg EnvRef::methods[] = {
1150         method(EnvRef, add_node),
1151         method(EnvRef, remove_node),
1152         method(EnvRef, get_node),
1153         method(EnvRef, add_luaentity),
1154         {0,0}
1155 };
1156
1157 class ObjectRef
1158 {
1159 private:
1160         ServerActiveObject *m_object;
1161
1162         static const char className[];
1163         static const luaL_reg methods[];
1164
1165         static ObjectRef *checkobject(lua_State *L, int narg)
1166         {
1167                 luaL_checktype(L, narg, LUA_TUSERDATA);
1168                 void *ud = luaL_checkudata(L, narg, className);
1169                 if(!ud) luaL_typerror(L, narg, className);
1170                 return *(ObjectRef**)ud;  // unbox pointer
1171         }
1172         
1173         static ServerActiveObject* getobject(ObjectRef *ref)
1174         {
1175                 ServerActiveObject *co = ref->m_object;
1176                 return co;
1177         }
1178         
1179         static LuaEntitySAO* getluaobject(ObjectRef *ref)
1180         {
1181                 ServerActiveObject *obj = getobject(ref);
1182                 if(obj == NULL)
1183                         return NULL;
1184                 if(obj->getType() != ACTIVEOBJECT_TYPE_LUAENTITY)
1185                         return NULL;
1186                 return (LuaEntitySAO*)obj;
1187         }
1188         
1189         // Exported functions
1190         
1191         // garbage collector
1192         static int gc_object(lua_State *L) {
1193                 ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
1194                 //infostream<<"ObjectRef::gc_object: o="<<o<<std::endl;
1195                 delete o;
1196                 return 0;
1197         }
1198
1199         // remove(self)
1200         static int l_remove(lua_State *L)
1201         {
1202                 ObjectRef *ref = checkobject(L, 1);
1203                 ServerActiveObject *co = getobject(ref);
1204                 if(co == NULL) return 0;
1205                 infostream<<"ObjectRef::l_remove(): id="<<co->getId()<<std::endl;
1206                 co->m_removed = true;
1207                 return 0;
1208         }
1209         
1210         // getpos(self)
1211         // returns: {x=num, y=num, z=num}
1212         static int l_getpos(lua_State *L)
1213         {
1214                 ObjectRef *ref = checkobject(L, 1);
1215                 ServerActiveObject *co = getobject(ref);
1216                 if(co == NULL) return 0;
1217                 v3f pos = co->getBasePosition() / BS;
1218                 lua_newtable(L);
1219                 lua_pushnumber(L, pos.X);
1220                 lua_setfield(L, -2, "x");
1221                 lua_pushnumber(L, pos.Y);
1222                 lua_setfield(L, -2, "y");
1223                 lua_pushnumber(L, pos.Z);
1224                 lua_setfield(L, -2, "z");
1225                 return 1;
1226         }
1227         
1228         // setpos(self, pos)
1229         static int l_setpos(lua_State *L)
1230         {
1231                 ObjectRef *ref = checkobject(L, 1);
1232                 //LuaEntitySAO *co = getluaobject(ref);
1233                 ServerActiveObject *co = getobject(ref);
1234                 if(co == NULL) return 0;
1235                 // pos
1236                 v3f pos = readFloatPos(L, 2);
1237                 // Do it
1238                 co->setPos(pos);
1239                 return 0;
1240         }
1241         
1242         // moveto(self, pos, continuous=false)
1243         static int l_moveto(lua_State *L)
1244         {
1245                 ObjectRef *ref = checkobject(L, 1);
1246                 //LuaEntitySAO *co = getluaobject(ref);
1247                 ServerActiveObject *co = getobject(ref);
1248                 if(co == NULL) return 0;
1249                 // pos
1250                 v3f pos = readFloatPos(L, 2);
1251                 // continuous
1252                 bool continuous = lua_toboolean(L, 3);
1253                 // Do it
1254                 co->moveTo(pos, continuous);
1255                 return 0;
1256         }
1257
1258         // setvelocity(self, velocity)
1259         static int l_setvelocity(lua_State *L)
1260         {
1261                 ObjectRef *ref = checkobject(L, 1);
1262                 LuaEntitySAO *co = getluaobject(ref);
1263                 if(co == NULL) return 0;
1264                 // pos
1265                 v3f pos = readFloatPos(L, 2);
1266                 // Do it
1267                 co->setVelocity(pos);
1268                 return 0;
1269         }
1270         
1271         // setacceleration(self, acceleration)
1272         static int l_setacceleration(lua_State *L)
1273         {
1274                 ObjectRef *ref = checkobject(L, 1);
1275                 LuaEntitySAO *co = getluaobject(ref);
1276                 if(co == NULL) return 0;
1277                 // pos
1278                 v3f pos = readFloatPos(L, 2);
1279                 // Do it
1280                 co->setAcceleration(pos);
1281                 return 0;
1282         }
1283         
1284         // getacceleration(self)
1285         static int l_getacceleration(lua_State *L)
1286         {
1287                 ObjectRef *ref = checkobject(L, 1);
1288                 LuaEntitySAO *co = getluaobject(ref);
1289                 if(co == NULL) return 0;
1290                 // Do it
1291                 v3f v = co->getAcceleration();
1292                 pushFloatPos(L, v);
1293                 return 1;
1294         }
1295         
1296         // add_to_inventory(self, itemstring)
1297         // returns: true if item was added, false otherwise
1298         static int l_add_to_inventory(lua_State *L)
1299         {
1300                 ObjectRef *ref = checkobject(L, 1);
1301                 luaL_checkstring(L, 2);
1302                 ServerActiveObject *co = getobject(ref);
1303                 if(co == NULL) return 0;
1304                 // itemstring
1305                 const char *itemstring = lua_tostring(L, 2);
1306                 infostream<<"ObjectRef::l_add_to_inventory(): id="<<co->getId()
1307                                 <<" itemstring=\""<<itemstring<<"\""<<std::endl;
1308                 // Do it
1309                 std::istringstream is(itemstring, std::ios::binary);
1310                 ServerEnvironment *env = co->getEnv();
1311                 assert(env);
1312                 IGameDef *gamedef = env->getGameDef();
1313                 InventoryItem *item = InventoryItem::deSerialize(is, gamedef);
1314                 infostream<<"item="<<env<<std::endl;
1315                 bool fits = co->addToInventory(item);
1316                 // Return
1317                 lua_pushboolean(L, fits);
1318                 return 1;
1319         }
1320
1321         // settexturemod(self, mod)
1322         static int l_settexturemod(lua_State *L)
1323         {
1324                 ObjectRef *ref = checkobject(L, 1);
1325                 LuaEntitySAO *co = getluaobject(ref);
1326                 if(co == NULL) return 0;
1327                 // Do it
1328                 std::string mod = lua_tostring(L, 2);
1329                 co->setTextureMod(mod);
1330                 return 0;
1331         }
1332         
1333         // setsprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2,
1334         //           select_horiz_by_yawpitch=false)
1335         static int l_setsprite(lua_State *L)
1336         {
1337                 ObjectRef *ref = checkobject(L, 1);
1338                 LuaEntitySAO *co = getluaobject(ref);
1339                 if(co == NULL) return 0;
1340                 // Do it
1341                 v2s16 p(0,0);
1342                 if(!lua_isnil(L, 2))
1343                         p = read_v2s16(L, 2);
1344                 int num_frames = 1;
1345                 if(!lua_isnil(L, 3))
1346                         num_frames = lua_tonumber(L, 3);
1347                 float framelength = 0.2;
1348                 if(!lua_isnil(L, 4))
1349                         framelength = lua_tonumber(L, 4);
1350                 bool select_horiz_by_yawpitch = false;
1351                 if(!lua_isnil(L, 5))
1352                         select_horiz_by_yawpitch = lua_toboolean(L, 5);
1353                 co->setSprite(p, num_frames, framelength, select_horiz_by_yawpitch);
1354                 return 0;
1355         }
1356         
1357 public:
1358         ObjectRef(ServerActiveObject *object):
1359                 m_object(object)
1360         {
1361                 //infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
1362         }
1363
1364         ~ObjectRef()
1365         {
1366                 /*if(m_object)
1367                         infostream<<"ObjectRef destructing for id="
1368                                         <<m_object->getId()<<std::endl;
1369                 else
1370                         infostream<<"ObjectRef destructing for id=unknown"<<std::endl;*/
1371         }
1372
1373         // Creates an ObjectRef and leaves it on top of stack
1374         // Not callable from Lua; all references are created on the C side.
1375         static void create(lua_State *L, ServerActiveObject *object)
1376         {
1377                 ObjectRef *o = new ObjectRef(object);
1378                 //infostream<<"ObjectRef::create: o="<<o<<std::endl;
1379                 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1380                 luaL_getmetatable(L, className);
1381                 lua_setmetatable(L, -2);
1382         }
1383
1384         static void set_null(lua_State *L)
1385         {
1386                 ObjectRef *o = checkobject(L, -1);
1387                 o->m_object = NULL;
1388         }
1389         
1390         static void Register(lua_State *L)
1391         {
1392                 lua_newtable(L);
1393                 int methodtable = lua_gettop(L);
1394                 luaL_newmetatable(L, className);
1395                 int metatable = lua_gettop(L);
1396
1397                 lua_pushliteral(L, "__metatable");
1398                 lua_pushvalue(L, methodtable);
1399                 lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
1400
1401                 lua_pushliteral(L, "__index");
1402                 lua_pushvalue(L, methodtable);
1403                 lua_settable(L, metatable);
1404
1405                 lua_pushliteral(L, "__gc");
1406                 lua_pushcfunction(L, gc_object);
1407                 lua_settable(L, metatable);
1408
1409                 lua_pop(L, 1);  // drop metatable
1410
1411                 luaL_openlib(L, 0, methods, 0);  // fill methodtable
1412                 lua_pop(L, 1);  // drop methodtable
1413
1414                 // Cannot be created from Lua
1415                 //lua_register(L, className, create_object);
1416         }
1417 };
1418 const char ObjectRef::className[] = "ObjectRef";
1419 const luaL_reg ObjectRef::methods[] = {
1420         method(ObjectRef, remove),
1421         method(ObjectRef, getpos),
1422         method(ObjectRef, setpos),
1423         method(ObjectRef, moveto),
1424         method(ObjectRef, setvelocity),
1425         method(ObjectRef, setacceleration),
1426         method(ObjectRef, add_to_inventory),
1427         method(ObjectRef, settexturemod),
1428         method(ObjectRef, setsprite),
1429         {0,0}
1430 };
1431
1432 // Creates a new anonymous reference if id=0
1433 static void objectref_get_or_create(lua_State *L,
1434                 ServerActiveObject *cobj)
1435 {
1436         if(cobj->getId() == 0){
1437                 ObjectRef::create(L, cobj);
1438         } else {
1439                 objectref_get(L, cobj->getId());
1440         }
1441 }
1442
1443 /*
1444         Main export function
1445 */
1446
1447 void scriptapi_export(lua_State *L, Server *server)
1448 {
1449         realitycheck(L);
1450         assert(lua_checkstack(L, 20));
1451         infostream<<"scriptapi_export"<<std::endl;
1452         StackUnroller stack_unroller(L);
1453
1454         // Store server as light userdata in registry
1455         lua_pushlightuserdata(L, server);
1456         lua_setfield(L, LUA_REGISTRYINDEX, "minetest_server");
1457
1458         // Store nil as minetest_nodedef_defaults in registry
1459         lua_pushnil(L);
1460         lua_setfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
1461         
1462         // Register global functions in table minetest
1463         lua_newtable(L);
1464         luaL_register(L, NULL, minetest_f);
1465         lua_setglobal(L, "minetest");
1466         
1467         // Get the main minetest table
1468         lua_getglobal(L, "minetest");
1469
1470         // Add tables to minetest
1471         
1472         lua_newtable(L);
1473         lua_setfield(L, -2, "registered_nodes");
1474         lua_newtable(L);
1475         lua_setfield(L, -2, "registered_entities");
1476         lua_newtable(L);
1477         lua_setfield(L, -2, "registered_globalsteps");
1478         lua_newtable(L);
1479         lua_setfield(L, -2, "registered_on_placenodes");
1480         lua_newtable(L);
1481         lua_setfield(L, -2, "registered_on_dignodes");
1482         lua_newtable(L);
1483         lua_setfield(L, -2, "registered_on_punchnodes");
1484         lua_newtable(L);
1485         lua_setfield(L, -2, "registered_on_generateds");
1486         lua_newtable(L);
1487         lua_setfield(L, -2, "registered_on_newplayers");
1488         lua_newtable(L);
1489         lua_setfield(L, -2, "registered_on_respawnplayers");
1490         
1491         lua_newtable(L);
1492         lua_setfield(L, -2, "object_refs");
1493         lua_newtable(L);
1494         lua_setfield(L, -2, "luaentities");
1495
1496         // Create entity prototype
1497         luaL_newmetatable(L, "minetest.entity");
1498         // metatable.__index = metatable
1499         lua_pushvalue(L, -1); // Duplicate metatable
1500         lua_setfield(L, -2, "__index");
1501         // Put functions in metatable
1502         luaL_register(L, NULL, minetest_entity_m);
1503         // Put other stuff in metatable
1504
1505         // Environment C reference
1506         EnvRef::Register(L);
1507
1508         // Object C reference
1509         ObjectRef::Register(L);
1510 }
1511
1512 void scriptapi_add_environment(lua_State *L, ServerEnvironment *env)
1513 {
1514         realitycheck(L);
1515         assert(lua_checkstack(L, 20));
1516         infostream<<"scriptapi_add_environment"<<std::endl;
1517         StackUnroller stack_unroller(L);
1518
1519         // Create EnvRef on stack
1520         EnvRef::create(L, env);
1521         int envref = lua_gettop(L);
1522
1523         // minetest.env = envref
1524         lua_getglobal(L, "minetest");
1525         luaL_checktype(L, -1, LUA_TTABLE);
1526         lua_pushvalue(L, envref);
1527         lua_setfield(L, -2, "env");
1528 }
1529
1530 #if 0
1531 // Dump stack top with the dump2 function
1532 static void dump2(lua_State *L, const char *name)
1533 {
1534         // Dump object (debug)
1535         lua_getglobal(L, "dump2");
1536         luaL_checktype(L, -1, LUA_TFUNCTION);
1537         lua_pushvalue(L, -2); // Get previous stack top as first parameter
1538         lua_pushstring(L, name);
1539         if(lua_pcall(L, 2, 0, 0))
1540                 script_error(L, "error: %s\n", lua_tostring(L, -1));
1541 }
1542 #endif
1543
1544 /*
1545         object_reference
1546 */
1547
1548 void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj)
1549 {
1550         realitycheck(L);
1551         assert(lua_checkstack(L, 20));
1552         infostream<<"scriptapi_add_object_reference: id="<<cobj->getId()<<std::endl;
1553         StackUnroller stack_unroller(L);
1554
1555         // Create object on stack
1556         ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack
1557         int object = lua_gettop(L);
1558
1559         // Get minetest.object_refs table
1560         lua_getglobal(L, "minetest");
1561         lua_getfield(L, -1, "object_refs");
1562         luaL_checktype(L, -1, LUA_TTABLE);
1563         int objectstable = lua_gettop(L);
1564         
1565         // object_refs[id] = object
1566         lua_pushnumber(L, cobj->getId()); // Push id
1567         lua_pushvalue(L, object); // Copy object to top of stack
1568         lua_settable(L, objectstable);
1569 }
1570
1571 void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj)
1572 {
1573         realitycheck(L);
1574         assert(lua_checkstack(L, 20));
1575         infostream<<"scriptapi_rm_object_reference: id="<<cobj->getId()<<std::endl;
1576         StackUnroller stack_unroller(L);
1577
1578         // Get minetest.object_refs table
1579         lua_getglobal(L, "minetest");
1580         lua_getfield(L, -1, "object_refs");
1581         luaL_checktype(L, -1, LUA_TTABLE);
1582         int objectstable = lua_gettop(L);
1583         
1584         // Get object_refs[id]
1585         lua_pushnumber(L, cobj->getId()); // Push id
1586         lua_gettable(L, objectstable);
1587         // Set object reference to NULL
1588         ObjectRef::set_null(L);
1589         lua_pop(L, 1); // pop object
1590
1591         // Set object_refs[id] = nil
1592         lua_pushnumber(L, cobj->getId()); // Push id
1593         lua_pushnil(L);
1594         lua_settable(L, objectstable);
1595 }
1596
1597
1598 /*
1599         misc
1600 */
1601
1602 void scriptapi_on_newplayer(lua_State *L, ServerActiveObject *player)
1603 {
1604         realitycheck(L);
1605         assert(lua_checkstack(L, 20));
1606         StackUnroller stack_unroller(L);
1607
1608         // Get minetest.registered_on_newplayers
1609         lua_getglobal(L, "minetest");
1610         lua_getfield(L, -1, "registered_on_newplayers");
1611         luaL_checktype(L, -1, LUA_TTABLE);
1612         int table = lua_gettop(L);
1613         // Foreach
1614         lua_pushnil(L);
1615         while(lua_next(L, table) != 0){
1616                 // key at index -2 and value at index -1
1617                 luaL_checktype(L, -1, LUA_TFUNCTION);
1618                 // Call function
1619                 objectref_get_or_create(L, player);
1620                 if(lua_pcall(L, 1, 0, 0))
1621                         script_error(L, "error: %s\n", lua_tostring(L, -1));
1622                 // value removed, keep key for next iteration
1623         }
1624 }
1625 bool scriptapi_on_respawnplayer(lua_State *L, ServerActiveObject *player)
1626 {
1627         realitycheck(L);
1628         assert(lua_checkstack(L, 20));
1629         StackUnroller stack_unroller(L);
1630
1631         bool positioning_handled_by_some = false;
1632
1633         // Get minetest.registered_on_respawnplayers
1634         lua_getglobal(L, "minetest");
1635         lua_getfield(L, -1, "registered_on_respawnplayers");
1636         luaL_checktype(L, -1, LUA_TTABLE);
1637         int table = lua_gettop(L);
1638         // Foreach
1639         lua_pushnil(L);
1640         while(lua_next(L, table) != 0){
1641                 // key at index -2 and value at index -1
1642                 luaL_checktype(L, -1, LUA_TFUNCTION);
1643                 // Call function
1644                 objectref_get_or_create(L, player);
1645                 if(lua_pcall(L, 1, 1, 0))
1646                         script_error(L, "error: %s\n", lua_tostring(L, -1));
1647                 bool positioning_handled = lua_toboolean(L, -1);
1648                 lua_pop(L, 1);
1649                 if(positioning_handled)
1650                         positioning_handled_by_some = true;
1651                 // value removed, keep key for next iteration
1652         }
1653         return positioning_handled_by_some;
1654 }
1655
1656 /*
1657         environment
1658 */
1659
1660 void scriptapi_environment_step(lua_State *L, float dtime)
1661 {
1662         realitycheck(L);
1663         assert(lua_checkstack(L, 20));
1664         //infostream<<"scriptapi_environment_step"<<std::endl;
1665         StackUnroller stack_unroller(L);
1666
1667         // Get minetest.registered_globalsteps
1668         lua_getglobal(L, "minetest");
1669         lua_getfield(L, -1, "registered_globalsteps");
1670         luaL_checktype(L, -1, LUA_TTABLE);
1671         int table = lua_gettop(L);
1672         // Foreach
1673         lua_pushnil(L);
1674         while(lua_next(L, table) != 0){
1675                 // key at index -2 and value at index -1
1676                 luaL_checktype(L, -1, LUA_TFUNCTION);
1677                 // Call function
1678                 lua_pushnumber(L, dtime);
1679                 if(lua_pcall(L, 1, 0, 0))
1680                         script_error(L, "error: %s\n", lua_tostring(L, -1));
1681                 // value removed, keep key for next iteration
1682         }
1683 }
1684
1685 void scriptapi_environment_on_placenode(lua_State *L, v3s16 p, MapNode newnode,
1686                 ServerActiveObject *placer)
1687 {
1688         realitycheck(L);
1689         assert(lua_checkstack(L, 20));
1690         //infostream<<"scriptapi_environment_on_placenode"<<std::endl;
1691         StackUnroller stack_unroller(L);
1692
1693         // Get server from registry
1694         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1695         Server *server = (Server*)lua_touserdata(L, -1);
1696         // And get the writable node definition manager from the server
1697         IWritableNodeDefManager *ndef =
1698                         server->getWritableNodeDefManager();
1699         
1700         // Get minetest.registered_on_placenodes
1701         lua_getglobal(L, "minetest");
1702         lua_getfield(L, -1, "registered_on_placenodes");
1703         luaL_checktype(L, -1, LUA_TTABLE);
1704         int table = lua_gettop(L);
1705         // Foreach
1706         lua_pushnil(L);
1707         while(lua_next(L, table) != 0){
1708                 // key at index -2 and value at index -1
1709                 luaL_checktype(L, -1, LUA_TFUNCTION);
1710                 // Call function
1711                 pushpos(L, p);
1712                 pushnode(L, newnode, ndef);
1713                 objectref_get_or_create(L, placer);
1714                 if(lua_pcall(L, 3, 0, 0))
1715                         script_error(L, "error: %s\n", lua_tostring(L, -1));
1716                 // value removed, keep key for next iteration
1717         }
1718 }
1719
1720 void scriptapi_environment_on_dignode(lua_State *L, v3s16 p, MapNode oldnode,
1721                 ServerActiveObject *digger)
1722 {
1723         realitycheck(L);
1724         assert(lua_checkstack(L, 20));
1725         //infostream<<"scriptapi_environment_on_dignode"<<std::endl;
1726         StackUnroller stack_unroller(L);
1727
1728         // Get server from registry
1729         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1730         Server *server = (Server*)lua_touserdata(L, -1);
1731         // And get the writable node definition manager from the server
1732         IWritableNodeDefManager *ndef =
1733                         server->getWritableNodeDefManager();
1734         
1735         // Get minetest.registered_on_dignodes
1736         lua_getglobal(L, "minetest");
1737         lua_getfield(L, -1, "registered_on_dignodes");
1738         luaL_checktype(L, -1, LUA_TTABLE);
1739         int table = lua_gettop(L);
1740         // Foreach
1741         lua_pushnil(L);
1742         while(lua_next(L, table) != 0){
1743                 // key at index -2 and value at index -1
1744                 luaL_checktype(L, -1, LUA_TFUNCTION);
1745                 // Call function
1746                 pushpos(L, p);
1747                 pushnode(L, oldnode, ndef);
1748                 objectref_get_or_create(L, digger);
1749                 if(lua_pcall(L, 3, 0, 0))
1750                         script_error(L, "error: %s\n", lua_tostring(L, -1));
1751                 // value removed, keep key for next iteration
1752         }
1753 }
1754
1755 void scriptapi_environment_on_punchnode(lua_State *L, v3s16 p, MapNode node,
1756                 ServerActiveObject *puncher)
1757 {
1758         realitycheck(L);
1759         assert(lua_checkstack(L, 20));
1760         //infostream<<"scriptapi_environment_on_punchnode"<<std::endl;
1761         StackUnroller stack_unroller(L);
1762
1763         // Get server from registry
1764         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1765         Server *server = (Server*)lua_touserdata(L, -1);
1766         // And get the writable node definition manager from the server
1767         IWritableNodeDefManager *ndef =
1768                         server->getWritableNodeDefManager();
1769         
1770         // Get minetest.registered_on_punchnodes
1771         lua_getglobal(L, "minetest");
1772         lua_getfield(L, -1, "registered_on_punchnodes");
1773         luaL_checktype(L, -1, LUA_TTABLE);
1774         int table = lua_gettop(L);
1775         // Foreach
1776         lua_pushnil(L);
1777         while(lua_next(L, table) != 0){
1778                 // key at index -2 and value at index -1
1779                 luaL_checktype(L, -1, LUA_TFUNCTION);
1780                 // Call function
1781                 pushpos(L, p);
1782                 pushnode(L, node, ndef);
1783                 objectref_get_or_create(L, puncher);
1784                 if(lua_pcall(L, 3, 0, 0))
1785                         script_error(L, "error: %s\n", lua_tostring(L, -1));
1786                 // value removed, keep key for next iteration
1787         }
1788 }
1789
1790 void scriptapi_environment_on_generated(lua_State *L, v3s16 minp, v3s16 maxp)
1791 {
1792         realitycheck(L);
1793         assert(lua_checkstack(L, 20));
1794         infostream<<"scriptapi_environment_on_generated"<<std::endl;
1795         StackUnroller stack_unroller(L);
1796
1797         // Get minetest.registered_on_generateds
1798         lua_getglobal(L, "minetest");
1799         lua_getfield(L, -1, "registered_on_generateds");
1800         luaL_checktype(L, -1, LUA_TTABLE);
1801         int table = lua_gettop(L);
1802         // Foreach
1803         lua_pushnil(L);
1804         while(lua_next(L, table) != 0){
1805                 // key at index -2 and value at index -1
1806                 luaL_checktype(L, -1, LUA_TFUNCTION);
1807                 // Call function
1808                 pushpos(L, minp);
1809                 pushpos(L, maxp);
1810                 if(lua_pcall(L, 2, 0, 0))
1811                         script_error(L, "error: %s\n", lua_tostring(L, -1));
1812                 // value removed, keep key for next iteration
1813         }
1814 }
1815
1816 /*
1817         luaentity
1818 */
1819
1820 bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
1821                 const std::string &staticdata)
1822 {
1823         realitycheck(L);
1824         assert(lua_checkstack(L, 20));
1825         infostream<<"scriptapi_luaentity_add: id="<<id<<" name=\""
1826                         <<name<<"\""<<std::endl;
1827         StackUnroller stack_unroller(L);
1828         
1829         // Get minetest.registered_entities[name]
1830         lua_getglobal(L, "minetest");
1831         lua_getfield(L, -1, "registered_entities");
1832         luaL_checktype(L, -1, LUA_TTABLE);
1833         lua_pushstring(L, name);
1834         lua_gettable(L, -2);
1835         // Should be a table, which we will use as a prototype
1836         //luaL_checktype(L, -1, LUA_TTABLE);
1837         if(lua_type(L, -1) != LUA_TTABLE){
1838                 errorstream<<"LuaEntity name \""<<name<<"\" not defined"<<std::endl;
1839                 return false;
1840         }
1841         int prototype_table = lua_gettop(L);
1842         //dump2(L, "prototype_table");
1843         
1844         // Create entity object
1845         lua_newtable(L);
1846         int object = lua_gettop(L);
1847
1848         // Set object metatable
1849         lua_pushvalue(L, prototype_table);
1850         lua_setmetatable(L, -2);
1851         
1852         // Add object reference
1853         // This should be userdata with metatable ObjectRef
1854         objectref_get(L, id);
1855         luaL_checktype(L, -1, LUA_TUSERDATA);
1856         if(!luaL_checkudata(L, -1, "ObjectRef"))
1857                 luaL_typerror(L, -1, "ObjectRef");
1858         lua_setfield(L, -2, "object");
1859
1860         // minetest.luaentities[id] = object
1861         lua_getglobal(L, "minetest");
1862         lua_getfield(L, -1, "luaentities");
1863         luaL_checktype(L, -1, LUA_TTABLE);
1864         lua_pushnumber(L, id); // Push id
1865         lua_pushvalue(L, object); // Copy object to top of stack
1866         lua_settable(L, -3);
1867         
1868         // Get on_activate function
1869         lua_pushvalue(L, object);
1870         lua_getfield(L, -1, "on_activate");
1871         if(!lua_isnil(L, -1)){
1872                 luaL_checktype(L, -1, LUA_TFUNCTION);
1873                 lua_pushvalue(L, object); // self
1874                 lua_pushlstring(L, staticdata.c_str(), staticdata.size());
1875                 // Call with 2 arguments, 0 results
1876                 if(lua_pcall(L, 2, 0, 0))
1877                         script_error(L, "error running function %s:on_activate: %s\n",
1878                                         name, lua_tostring(L, -1));
1879         }
1880         
1881         return true;
1882 }
1883
1884 void scriptapi_luaentity_rm(lua_State *L, u16 id)
1885 {
1886         realitycheck(L);
1887         assert(lua_checkstack(L, 20));
1888         infostream<<"scriptapi_luaentity_rm: id="<<id<<std::endl;
1889
1890         // Get minetest.luaentities table
1891         lua_getglobal(L, "minetest");
1892         lua_getfield(L, -1, "luaentities");
1893         luaL_checktype(L, -1, LUA_TTABLE);
1894         int objectstable = lua_gettop(L);
1895         
1896         // Set luaentities[id] = nil
1897         lua_pushnumber(L, id); // Push id
1898         lua_pushnil(L);
1899         lua_settable(L, objectstable);
1900         
1901         lua_pop(L, 2); // pop luaentities, minetest
1902 }
1903
1904 std::string scriptapi_luaentity_get_staticdata(lua_State *L, u16 id)
1905 {
1906         realitycheck(L);
1907         assert(lua_checkstack(L, 20));
1908         infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl;
1909         StackUnroller stack_unroller(L);
1910
1911         // Get minetest.luaentities[id]
1912         luaentity_get(L, id);
1913         int object = lua_gettop(L);
1914         
1915         // Get get_staticdata function
1916         lua_pushvalue(L, object);
1917         lua_getfield(L, -1, "get_staticdata");
1918         if(lua_isnil(L, -1))
1919                 return "";
1920         
1921         luaL_checktype(L, -1, LUA_TFUNCTION);
1922         lua_pushvalue(L, object); // self
1923         // Call with 1 arguments, 1 results
1924         if(lua_pcall(L, 1, 1, 0))
1925                 script_error(L, "error running function get_staticdata: %s\n",
1926                                 lua_tostring(L, -1));
1927         
1928         size_t len=0;
1929         const char *s = lua_tolstring(L, -1, &len);
1930         return std::string(s, len);
1931 }
1932
1933 void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
1934                 LuaEntityProperties *prop)
1935 {
1936         realitycheck(L);
1937         assert(lua_checkstack(L, 20));
1938         infostream<<"scriptapi_luaentity_get_properties: id="<<id<<std::endl;
1939         StackUnroller stack_unroller(L);
1940
1941         // Get minetest.luaentities[id]
1942         luaentity_get(L, id);
1943         //int object = lua_gettop(L);
1944
1945         /* Read stuff */
1946         
1947         getboolfield(L, -1, "physical", prop->physical);
1948
1949         getfloatfield(L, -1, "weight", prop->weight);
1950
1951         lua_getfield(L, -1, "collisionbox");
1952         if(lua_istable(L, -1))
1953                 prop->collisionbox = read_aabbox3df32(L, -1, 1.0);
1954         lua_pop(L, 1);
1955
1956         getstringfield(L, -1, "visual", prop->visual);
1957         
1958         lua_getfield(L, -1, "visual_size");
1959         if(lua_istable(L, -1))
1960                 prop->visual_size = read_v2f(L, -1);
1961         lua_pop(L, 1);
1962
1963         lua_getfield(L, -1, "textures");
1964         if(lua_istable(L, -1)){
1965                 prop->textures.clear();
1966                 int table = lua_gettop(L);
1967                 lua_pushnil(L);
1968                 while(lua_next(L, table) != 0){
1969                         // key at index -2 and value at index -1
1970                         if(lua_isstring(L, -1))
1971                                 prop->textures.push_back(lua_tostring(L, -1));
1972                         else
1973                                 prop->textures.push_back("");
1974                         // removes value, keeps key for next iteration
1975                         lua_pop(L, 1);
1976                 }
1977         }
1978         lua_pop(L, 1);
1979         
1980         lua_getfield(L, -1, "spritediv");
1981         if(lua_istable(L, -1))
1982                 prop->spritediv = read_v2s16(L, -1);
1983         lua_pop(L, 1);
1984
1985         lua_getfield(L, -1, "initial_sprite_basepos");
1986         if(lua_istable(L, -1))
1987                 prop->initial_sprite_basepos = read_v2s16(L, -1);
1988         lua_pop(L, 1);
1989 }
1990
1991 void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime)
1992 {
1993         realitycheck(L);
1994         assert(lua_checkstack(L, 20));
1995         //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
1996         StackUnroller stack_unroller(L);
1997
1998         // Get minetest.luaentities[id]
1999         luaentity_get(L, id);
2000         int object = lua_gettop(L);
2001         // State: object is at top of stack
2002         // Get step function
2003         lua_getfield(L, -1, "on_step");
2004         if(lua_isnil(L, -1))
2005                 return;
2006         luaL_checktype(L, -1, LUA_TFUNCTION);
2007         lua_pushvalue(L, object); // self
2008         lua_pushnumber(L, dtime); // dtime
2009         // Call with 2 arguments, 0 results
2010         if(lua_pcall(L, 2, 0, 0))
2011                 script_error(L, "error running function 'on_step': %s\n", lua_tostring(L, -1));
2012 }
2013
2014 // Calls entity:on_punch(ObjectRef puncher)
2015 void scriptapi_luaentity_punch(lua_State *L, u16 id,
2016                 ServerActiveObject *puncher)
2017 {
2018         realitycheck(L);
2019         assert(lua_checkstack(L, 20));
2020         //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
2021         StackUnroller stack_unroller(L);
2022
2023         // Get minetest.luaentities[id]
2024         luaentity_get(L, id);
2025         int object = lua_gettop(L);
2026         // State: object is at top of stack
2027         // Get function
2028         lua_getfield(L, -1, "on_punch");
2029         if(lua_isnil(L, -1))
2030                 return;
2031         luaL_checktype(L, -1, LUA_TFUNCTION);
2032         lua_pushvalue(L, object); // self
2033         objectref_get_or_create(L, puncher); // Clicker reference
2034         // Call with 2 arguments, 0 results
2035         if(lua_pcall(L, 2, 0, 0))
2036                 script_error(L, "error running function 'on_punch': %s\n", lua_tostring(L, -1));
2037 }
2038
2039 // Calls entity:on_rightclick(ObjectRef clicker)
2040 void scriptapi_luaentity_rightclick(lua_State *L, u16 id,
2041                 ServerActiveObject *clicker)
2042 {
2043         realitycheck(L);
2044         assert(lua_checkstack(L, 20));
2045         //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
2046         StackUnroller stack_unroller(L);
2047
2048         // Get minetest.luaentities[id]
2049         luaentity_get(L, id);
2050         int object = lua_gettop(L);
2051         // State: object is at top of stack
2052         // Get function
2053         lua_getfield(L, -1, "on_rightclick");
2054         if(lua_isnil(L, -1))
2055                 return;
2056         luaL_checktype(L, -1, LUA_TFUNCTION);
2057         lua_pushvalue(L, object); // self
2058         objectref_get_or_create(L, clicker); // Clicker reference
2059         // Call with 2 arguments, 0 results
2060         if(lua_pcall(L, 2, 0, 0))
2061                 script_error(L, "error running function 'on_rightclick': %s\n", lua_tostring(L, -1));
2062 }
2063