]> git.lizzy.rs Git - minetest.git/blob - src/scriptapi.cpp
Do not broadcast an empty chat message when someone tries to log in with the wrong...
[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 #include <list>
24 extern "C" {
25 #include <lua.h>
26 #include <lualib.h>
27 #include <lauxlib.h>
28 }
29
30 #include "log.h"
31 #include "server.h"
32 #include "porting.h"
33 #include "filesys.h"
34 #include "serverobject.h"
35 #include "script.h"
36 //#include "luna.h"
37 #include "luaentity_common.h"
38 #include "content_sao.h" // For LuaEntitySAO
39 #include "tooldef.h"
40 #include "nodedef.h"
41 #include "craftdef.h"
42 #include "craftitemdef.h"
43 #include "main.h" // For g_settings
44 #include "settings.h" // For accessing g_settings
45 #include "nodemetadata.h"
46 #include "mapblock.h" // For getNodeBlockPos
47 #include "content_nodemeta.h"
48 #include "utility.h"
49
50 static void stackDump(lua_State *L, std::ostream &o)
51 {
52   int i;
53   int top = lua_gettop(L);
54   for (i = 1; i <= top; i++) {  /* repeat for each level */
55         int t = lua_type(L, i);
56         switch (t) {
57
58           case LUA_TSTRING:  /* strings */
59                 o<<"\""<<lua_tostring(L, i)<<"\"";
60                 break;
61
62           case LUA_TBOOLEAN:  /* booleans */
63                 o<<(lua_toboolean(L, i) ? "true" : "false");
64                 break;
65
66           case LUA_TNUMBER:  /* numbers */ {
67                 char buf[10];
68                 snprintf(buf, 10, "%g", lua_tonumber(L, i));
69                 o<<buf;
70                 break; }
71
72           default:  /* other values */
73                 o<<lua_typename(L, t);
74                 break;
75
76         }
77         o<<" ";
78   }
79   o<<std::endl;
80 }
81
82 static void realitycheck(lua_State *L)
83 {
84         int top = lua_gettop(L);
85         if(top >= 30){
86                 dstream<<"Stack is over 30:"<<std::endl;
87                 stackDump(L, dstream);
88                 script_error(L, "Stack is over 30 (reality check)");
89         }
90 }
91
92 class StackUnroller
93 {
94 private:
95         lua_State *m_lua;
96         int m_original_top;
97 public:
98         StackUnroller(lua_State *L):
99                 m_lua(L),
100                 m_original_top(-1)
101         {
102                 m_original_top = lua_gettop(m_lua); // store stack height
103         }
104         ~StackUnroller()
105         {
106                 lua_settop(m_lua, m_original_top); // restore stack height
107         }
108 };
109
110 class ModNameStorer
111 {
112 private:
113         lua_State *L;
114 public:
115         ModNameStorer(lua_State *L_, const std::string modname):
116                 L(L_)
117         {
118                 // Store current modname in registry
119                 lua_pushstring(L, modname.c_str());
120                 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
121         }
122         ~ModNameStorer()
123         {
124                 // Clear current modname in registry
125                 lua_pushnil(L);
126                 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
127         }
128 };
129
130 std::string get_current_modname(lua_State *L)
131 {
132         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
133         std::string modname = "";
134         if(lua_type(L, -1) == LUA_TSTRING)
135                 modname = lua_tostring(L, -1);
136         lua_pop(L, 1);
137         return modname;
138 }
139
140 void check_modname_prefix(lua_State *L, std::string &name)
141 {
142         if(name.size() == 0)
143                 throw LuaError(L, std::string("Name is empty"));
144         
145         if(name[0] == ':'){
146                 name = name.substr(1);
147                 return;
148         }
149         
150         std::string modname = get_current_modname(L);
151         assert(modname != "");
152         
153         // For __builtin, anything goes
154         if(modname == "__builtin")
155                 return;
156         
157         if(name.substr(0, modname.size()+1) != modname + ":")
158                 throw LuaError(L, std::string("Name \"")+name
159                                 +"\" does not follow naming conventions: "
160                                 +"\"modname:\" or \":\" prefix required)");
161         
162         std::string subname = name.substr(modname.size()+1);
163         if(!string_allowed(subname, "abcdefghijklmnopqrstuvwxyz"
164                         "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"))
165                 throw LuaError(L, std::string("Name \"")+name
166                                 +"\" does not follow naming conventions: "
167                                 +"\"contains unallowed characters)");
168 }
169
170 static v3f readFloatPos(lua_State *L, int index)
171 {
172         v3f pos;
173         luaL_checktype(L, index, LUA_TTABLE);
174         lua_getfield(L, index, "x");
175         pos.X = lua_tonumber(L, -1);
176         lua_pop(L, 1);
177         lua_getfield(L, index, "y");
178         pos.Y = lua_tonumber(L, -1);
179         lua_pop(L, 1);
180         lua_getfield(L, index, "z");
181         pos.Z = lua_tonumber(L, -1);
182         lua_pop(L, 1);
183         pos *= BS; // Scale to internal format
184         return pos;
185 }
186
187 static void pushFloatPos(lua_State *L, v3f p)
188 {
189         p /= BS;
190         lua_newtable(L);
191         lua_pushnumber(L, p.X);
192         lua_setfield(L, -2, "x");
193         lua_pushnumber(L, p.Y);
194         lua_setfield(L, -2, "y");
195         lua_pushnumber(L, p.Z);
196         lua_setfield(L, -2, "z");
197 }
198
199 static void pushpos(lua_State *L, v3s16 p)
200 {
201         lua_newtable(L);
202         lua_pushnumber(L, p.X);
203         lua_setfield(L, -2, "x");
204         lua_pushnumber(L, p.Y);
205         lua_setfield(L, -2, "y");
206         lua_pushnumber(L, p.Z);
207         lua_setfield(L, -2, "z");
208 }
209
210 static v3s16 readpos(lua_State *L, int index)
211 {
212         // Correct rounding at <0
213         v3f pf = readFloatPos(L, index);
214         return floatToInt(pf, BS);
215 }
216
217 static void pushnode(lua_State *L, const MapNode &n, INodeDefManager *ndef)
218 {
219         lua_newtable(L);
220         lua_pushstring(L, ndef->get(n).name.c_str());
221         lua_setfield(L, -2, "name");
222         lua_pushnumber(L, n.getParam1());
223         lua_setfield(L, -2, "param1");
224         lua_pushnumber(L, n.getParam2());
225         lua_setfield(L, -2, "param2");
226 }
227
228 static MapNode readnode(lua_State *L, int index, INodeDefManager *ndef)
229 {
230         lua_getfield(L, index, "name");
231         const char *name = lua_tostring(L, -1);
232         lua_pop(L, 1);
233         u8 param1;
234         lua_getfield(L, index, "param1");
235         if(lua_isnil(L, -1))
236                 param1 = 0;
237         else
238                 param1 = lua_tonumber(L, -1);
239         lua_pop(L, 1);
240         u8 param2;
241         lua_getfield(L, index, "param2");
242         if(lua_isnil(L, -1))
243                 param2 = 0;
244         else
245                 param2 = lua_tonumber(L, -1);
246         lua_pop(L, 1);
247         return MapNode(ndef, name, param1, param2);
248 }
249
250 static video::SColor readARGB8(lua_State *L, int index)
251 {
252         video::SColor color;
253         luaL_checktype(L, index, LUA_TTABLE);
254         lua_getfield(L, index, "a");
255         if(lua_isnumber(L, -1))
256                 color.setAlpha(lua_tonumber(L, -1));
257         lua_pop(L, 1);
258         lua_getfield(L, index, "r");
259         color.setRed(lua_tonumber(L, -1));
260         lua_pop(L, 1);
261         lua_getfield(L, index, "g");
262         color.setGreen(lua_tonumber(L, -1));
263         lua_pop(L, 1);
264         lua_getfield(L, index, "b");
265         color.setBlue(lua_tonumber(L, -1));
266         lua_pop(L, 1);
267         return color;
268 }
269
270 static core::aabbox3d<f32> read_aabbox3df32(lua_State *L, int index, f32 scale)
271 {
272         core::aabbox3d<f32> box;
273         if(lua_istable(L, -1)){
274                 lua_rawgeti(L, -1, 1);
275                 box.MinEdge.X = lua_tonumber(L, -1) * scale;
276                 lua_pop(L, 1);
277                 lua_rawgeti(L, -1, 2);
278                 box.MinEdge.Y = lua_tonumber(L, -1) * scale;
279                 lua_pop(L, 1);
280                 lua_rawgeti(L, -1, 3);
281                 box.MinEdge.Z = lua_tonumber(L, -1) * scale;
282                 lua_pop(L, 1);
283                 lua_rawgeti(L, -1, 4);
284                 box.MaxEdge.X = lua_tonumber(L, -1) * scale;
285                 lua_pop(L, 1);
286                 lua_rawgeti(L, -1, 5);
287                 box.MaxEdge.Y = lua_tonumber(L, -1) * scale;
288                 lua_pop(L, 1);
289                 lua_rawgeti(L, -1, 6);
290                 box.MaxEdge.Z = lua_tonumber(L, -1) * scale;
291                 lua_pop(L, 1);
292         }
293         return box;
294 }
295
296 static v2s16 read_v2s16(lua_State *L, int index)
297 {
298         v2s16 p;
299         luaL_checktype(L, index, LUA_TTABLE);
300         lua_getfield(L, index, "x");
301         p.X = lua_tonumber(L, -1);
302         lua_pop(L, 1);
303         lua_getfield(L, index, "y");
304         p.Y = lua_tonumber(L, -1);
305         lua_pop(L, 1);
306         return p;
307 }
308
309 static v2f read_v2f(lua_State *L, int index)
310 {
311         v2f p;
312         luaL_checktype(L, index, LUA_TTABLE);
313         lua_getfield(L, index, "x");
314         p.X = lua_tonumber(L, -1);
315         lua_pop(L, 1);
316         lua_getfield(L, index, "y");
317         p.Y = lua_tonumber(L, -1);
318         lua_pop(L, 1);
319         return p;
320 }
321
322 static bool getstringfield(lua_State *L, int table,
323                 const char *fieldname, std::string &result)
324 {
325         lua_getfield(L, table, fieldname);
326         bool got = false;
327         if(lua_isstring(L, -1)){
328                 result = lua_tostring(L, -1);
329                 got = true;
330         }
331         lua_pop(L, 1);
332         return got;
333 }
334
335 static bool getintfield(lua_State *L, int table,
336                 const char *fieldname, int &result)
337 {
338         lua_getfield(L, table, fieldname);
339         bool got = false;
340         if(lua_isnumber(L, -1)){
341                 result = lua_tonumber(L, -1);
342                 got = true;
343         }
344         lua_pop(L, 1);
345         return got;
346 }
347
348 static bool getfloatfield(lua_State *L, int table,
349                 const char *fieldname, float &result)
350 {
351         lua_getfield(L, table, fieldname);
352         bool got = false;
353         if(lua_isnumber(L, -1)){
354                 result = lua_tonumber(L, -1);
355                 got = true;
356         }
357         lua_pop(L, 1);
358         return got;
359 }
360
361 static bool getboolfield(lua_State *L, int table,
362                 const char *fieldname, bool &result)
363 {
364         lua_getfield(L, table, fieldname);
365         bool got = false;
366         if(lua_isboolean(L, -1)){
367                 result = lua_toboolean(L, -1);
368                 got = true;
369         }
370         lua_pop(L, 1);
371         return got;
372 }
373
374 static std::string getstringfield_default(lua_State *L, int table,
375                 const char *fieldname, const std::string &default_)
376 {
377         std::string result = default_;
378         getstringfield(L, table, fieldname, result);
379         return result;
380 }
381
382 static int getintfield_default(lua_State *L, int table,
383                 const char *fieldname, int default_)
384 {
385         int result = default_;
386         getintfield(L, table, fieldname, result);
387         return result;
388 }
389
390 /*static float getfloatfield_default(lua_State *L, int table,
391                 const char *fieldname, float default_)
392 {
393         float result = default_;
394         getfloatfield(L, table, fieldname, result);
395         return result;
396 }*/
397
398 static bool getboolfield_default(lua_State *L, int table,
399                 const char *fieldname, bool default_)
400 {
401         bool result = default_;
402         getboolfield(L, table, fieldname, result);
403         return result;
404 }
405
406 struct EnumString
407 {
408         int num;
409         const char *str;
410 };
411
412 static bool string_to_enum(const EnumString *spec, int &result,
413                 const std::string &str)
414 {
415         const EnumString *esp = spec;
416         while(esp->str){
417                 if(str == std::string(esp->str)){
418                         result = esp->num;
419                         return true;
420                 }
421                 esp++;
422         }
423         return false;
424 }
425
426 /*static bool enum_to_string(const EnumString *spec, std::string &result,
427                 int num)
428 {
429         const EnumString *esp = spec;
430         while(esp){
431                 if(num == esp->num){
432                         result = esp->str;
433                         return true;
434                 }
435                 esp++;
436         }
437         return false;
438 }*/
439
440 static int getenumfield(lua_State *L, int table,
441                 const char *fieldname, const EnumString *spec, int default_)
442 {
443         int result = default_;
444         string_to_enum(spec, result,
445                         getstringfield_default(L, table, fieldname, ""));
446         return result;
447 }
448
449 static void setfloatfield(lua_State *L, int table,
450                 const char *fieldname, float value)
451 {
452         lua_pushnumber(L, value);
453         if(table < 0)
454                 table -= 1;
455         lua_setfield(L, table, fieldname);
456 }
457
458 /*
459         Inventory stuff
460 */
461
462 static void inventory_set_list_from_lua(Inventory *inv, const char *name,
463                 lua_State *L, int tableindex, IGameDef *gamedef, int forcesize=-1)
464 {
465         if(tableindex < 0)
466                 tableindex = lua_gettop(L) + 1 + tableindex;
467         // If nil, delete list
468         if(lua_isnil(L, tableindex)){
469                 inv->deleteList(name);
470                 return;
471         }
472         // Otherwise set list
473         std::list<std::string> items;
474         luaL_checktype(L, tableindex, LUA_TTABLE);
475         int table = tableindex;
476         lua_pushnil(L);
477         while(lua_next(L, table) != 0){
478                 // key at index -2 and value at index -1
479                 luaL_checktype(L, -1, LUA_TSTRING);
480                 std::string itemstring = lua_tostring(L, -1);
481                 items.push_back(itemstring);
482                 // removes value, keeps key for next iteration
483                 lua_pop(L, 1);
484         }
485         int listsize = (forcesize != -1) ? forcesize : items.size();
486         InventoryList *invlist = inv->addList(name, listsize);
487         int index = 0;
488         for(std::list<std::string>::const_iterator
489                         i = items.begin(); i != items.end(); i++){
490                 if(forcesize != -1 && index == forcesize)
491                         break;
492                 const std::string &itemstring = *i;
493                 InventoryItem *newitem = NULL;
494                 if(itemstring != "")
495                         newitem = InventoryItem::deSerialize(itemstring,
496                                         gamedef);
497                 InventoryItem *olditem = invlist->changeItem(index, newitem);
498                 delete olditem;
499                 index++;
500         }
501         while(forcesize != -1 && index < forcesize){
502                 InventoryItem *olditem = invlist->changeItem(index, NULL);
503                 delete olditem;
504                 index++;
505         }
506 }
507
508 static void inventory_get_list_to_lua(Inventory *inv, const char *name,
509                 lua_State *L)
510 {
511         InventoryList *invlist = inv->getList(name);
512         if(invlist == NULL){
513                 lua_pushnil(L);
514                 return;
515         }
516         // Get the table insert function
517         lua_getglobal(L, "table");
518         lua_getfield(L, -1, "insert");
519         int table_insert = lua_gettop(L);
520         // Create and fill table
521         lua_newtable(L);
522         int table = lua_gettop(L);
523         for(u32 i=0; i<invlist->getSize(); i++){
524                 InventoryItem *item = invlist->getItem(i);
525                 lua_pushvalue(L, table_insert);
526                 lua_pushvalue(L, table);
527                 if(item == NULL){
528                         lua_pushstring(L, "");
529                 } else {
530                         lua_pushstring(L, item->getItemString().c_str());
531                 }
532                 if(lua_pcall(L, 2, 0, 0))
533                         script_error(L, "error: %s", lua_tostring(L, -1));
534         }
535 }
536
537 /*
538         ToolDiggingProperties
539 */
540
541 static ToolDiggingProperties read_tool_digging_properties(
542                 lua_State *L, int table)
543 {
544         ToolDiggingProperties prop;
545         getfloatfield(L, table, "full_punch_interval", prop.full_punch_interval);
546         getfloatfield(L, table, "basetime", prop.basetime);
547         getfloatfield(L, table, "dt_weight", prop.dt_weight);
548         getfloatfield(L, table, "dt_crackiness", prop.dt_crackiness);
549         getfloatfield(L, table, "dt_crumbliness", prop.dt_crumbliness);
550         getfloatfield(L, table, "dt_cuttability", prop.dt_cuttability);
551         getfloatfield(L, table, "basedurability", prop.basedurability);
552         getfloatfield(L, table, "dd_weight", prop.dd_weight);
553         getfloatfield(L, table, "dd_crackiness", prop.dd_crackiness);
554         getfloatfield(L, table, "dd_crumbliness", prop.dd_crumbliness);
555         getfloatfield(L, table, "dd_cuttability", prop.dd_cuttability);
556         return prop;
557 }
558
559 static void set_tool_digging_properties(lua_State *L, int table,
560                 const ToolDiggingProperties &prop)
561 {
562         setfloatfield(L, table, "full_punch_interval", prop.full_punch_interval);
563         setfloatfield(L, table, "basetime", prop.basetime);
564         setfloatfield(L, table, "dt_weight", prop.dt_weight);
565         setfloatfield(L, table, "dt_crackiness", prop.dt_crackiness);
566         setfloatfield(L, table, "dt_crumbliness", prop.dt_crumbliness);
567         setfloatfield(L, table, "dt_cuttability", prop.dt_cuttability);
568         setfloatfield(L, table, "basedurability", prop.basedurability);
569         setfloatfield(L, table, "dd_weight", prop.dd_weight);
570         setfloatfield(L, table, "dd_crackiness", prop.dd_crackiness);
571         setfloatfield(L, table, "dd_crumbliness", prop.dd_crumbliness);
572         setfloatfield(L, table, "dd_cuttability", prop.dd_cuttability);
573 }
574
575 static void push_tool_digging_properties(lua_State *L,
576                 const ToolDiggingProperties &prop)
577 {
578         lua_newtable(L);
579         set_tool_digging_properties(L, -1, prop);
580 }
581
582 /*
583         ToolDefinition
584 */
585
586 static ToolDefinition read_tool_definition(lua_State *L, int table)
587 {
588         ToolDefinition def;
589         getstringfield(L, table, "image", def.imagename);
590         def.properties = read_tool_digging_properties(L, table);
591         return def;
592 }
593
594 static void push_tool_definition(lua_State *L, const ToolDefinition &def)
595 {
596         lua_newtable(L);
597         lua_pushstring(L, def.imagename.c_str());
598         lua_setfield(L, -2, "image");
599         set_tool_digging_properties(L, -1, def.properties);
600 }
601
602 /*
603         EnumString definitions
604 */
605
606 struct EnumString es_DrawType[] =
607 {
608         {NDT_NORMAL, "normal"},
609         {NDT_AIRLIKE, "airlike"},
610         {NDT_LIQUID, "liquid"},
611         {NDT_FLOWINGLIQUID, "flowingliquid"},
612         {NDT_GLASSLIKE, "glasslike"},
613         {NDT_ALLFACES, "allfaces"},
614         {NDT_ALLFACES_OPTIONAL, "allfaces_optional"},
615         {NDT_TORCHLIKE, "torchlike"},
616         {NDT_SIGNLIKE, "signlike"},
617         {NDT_PLANTLIKE, "plantlike"},
618         {NDT_FENCELIKE, "fencelike"},
619         {NDT_RAILLIKE, "raillike"},
620         {0, NULL},
621 };
622
623 struct EnumString es_ContentParamType[] =
624 {
625         {CPT_NONE, "none"},
626         {CPT_LIGHT, "light"},
627         {CPT_MINERAL, "mineral"},
628         {CPT_FACEDIR_SIMPLE, "facedir_simple"},
629         {0, NULL},
630 };
631
632 struct EnumString es_LiquidType[] =
633 {
634         {LIQUID_NONE, "none"},
635         {LIQUID_FLOWING, "flowing"},
636         {LIQUID_SOURCE, "source"},
637         {0, NULL},
638 };
639
640 struct EnumString es_NodeBoxType[] =
641 {
642         {NODEBOX_REGULAR, "regular"},
643         {NODEBOX_FIXED, "fixed"},
644         {NODEBOX_WALLMOUNTED, "wallmounted"},
645         {0, NULL},
646 };
647
648 struct EnumString es_Diggability[] =
649 {
650         {DIGGABLE_NOT, "not"},
651         {DIGGABLE_NORMAL, "normal"},
652         {DIGGABLE_CONSTANT, "constant"},
653         {0, NULL},
654 };
655
656 /*
657         Global functions
658 */
659
660 static int l_register_nodedef_defaults(lua_State *L)
661 {
662         luaL_checktype(L, 1, LUA_TTABLE);
663
664         lua_pushvalue(L, 1); // Explicitly put parameter 1 on top of stack
665         lua_setfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
666
667         return 0;
668 }
669
670 // Register new object prototype
671 // register_entity(name, prototype)
672 static int l_register_entity(lua_State *L)
673 {
674         std::string name = luaL_checkstring(L, 1);
675         check_modname_prefix(L, name);
676         //infostream<<"register_entity: "<<name<<std::endl;
677         luaL_checktype(L, 2, LUA_TTABLE);
678
679         // Get minetest.registered_entities
680         lua_getglobal(L, "minetest");
681         lua_getfield(L, -1, "registered_entities");
682         luaL_checktype(L, -1, LUA_TTABLE);
683         int registered_entities = lua_gettop(L);
684         lua_pushvalue(L, 2); // Object = param 2 -> stack top
685         // registered_entities[name] = object
686         lua_setfield(L, registered_entities, name.c_str());
687         
688         // Get registered object to top of stack
689         lua_pushvalue(L, 2);
690         
691         // Set __index to point to itself
692         lua_pushvalue(L, -1);
693         lua_setfield(L, -2, "__index");
694
695         // Set metatable.__index = metatable
696         luaL_getmetatable(L, "minetest.entity");
697         lua_pushvalue(L, -1); // duplicate metatable
698         lua_setfield(L, -2, "__index");
699         // Set object metatable
700         lua_setmetatable(L, -2);
701
702         return 0; /* number of results */
703 }
704
705 class LuaABM : public ActiveBlockModifier
706 {
707 private:
708         lua_State *m_lua;
709         int m_id;
710
711         std::set<std::string> m_trigger_contents;
712         float m_trigger_interval;
713         u32 m_trigger_chance;
714 public:
715         LuaABM(lua_State *L, int id,
716                         const std::set<std::string> &trigger_contents,
717                         float trigger_interval, u32 trigger_chance):
718                 m_lua(L),
719                 m_id(id),
720                 m_trigger_contents(trigger_contents),
721                 m_trigger_interval(trigger_interval),
722                 m_trigger_chance(trigger_chance)
723         {
724         }
725         virtual std::set<std::string> getTriggerContents()
726         {
727                 return m_trigger_contents;
728         }
729         virtual float getTriggerInterval()
730         {
731                 return m_trigger_interval;
732         }
733         virtual u32 getTriggerChance()
734         {
735                 return m_trigger_chance;
736         }
737         virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n,
738                         u32 active_object_count, u32 active_object_count_wider)
739         {
740                 lua_State *L = m_lua;
741         
742                 realitycheck(L);
743                 assert(lua_checkstack(L, 20));
744                 StackUnroller stack_unroller(L);
745
746                 // Get minetest.registered_abms
747                 lua_getglobal(L, "minetest");
748                 lua_getfield(L, -1, "registered_abms");
749                 luaL_checktype(L, -1, LUA_TTABLE);
750                 int registered_abms = lua_gettop(L);
751
752                 // Get minetest.registered_abms[m_id]
753                 lua_pushnumber(L, m_id);
754                 lua_gettable(L, registered_abms);
755                 if(lua_isnil(L, -1))
756                         assert(0);
757                 
758                 // Call action
759                 luaL_checktype(L, -1, LUA_TTABLE);
760                 lua_getfield(L, -1, "action");
761                 luaL_checktype(L, -1, LUA_TFUNCTION);
762                 pushpos(L, p);
763                 pushnode(L, n, env->getGameDef()->ndef());
764                 lua_pushnumber(L, active_object_count);
765                 lua_pushnumber(L, active_object_count_wider);
766                 if(lua_pcall(L, 4, 0, 0))
767                         script_error(L, "error: %s", lua_tostring(L, -1));
768         }
769 };
770
771 // register_abm({...})
772 static int l_register_abm(lua_State *L)
773 {
774         //infostream<<"register_abm"<<std::endl;
775         luaL_checktype(L, 1, LUA_TTABLE);
776
777         // Get minetest.registered_abms
778         lua_getglobal(L, "minetest");
779         lua_getfield(L, -1, "registered_abms");
780         luaL_checktype(L, -1, LUA_TTABLE);
781         int registered_abms = lua_gettop(L);
782
783         int id = 1;
784         // Find free id
785         for(;;){
786                 lua_pushnumber(L, id);
787                 lua_gettable(L, registered_abms);
788                 if(lua_isnil(L, -1))
789                         break;
790                 lua_pop(L, 1);
791                 id++;
792         }
793         lua_pop(L, 1);
794
795         infostream<<"register_abm: id="<<id<<std::endl;
796
797         // registered_abms[id] = spec
798         lua_pushnumber(L, id);
799         lua_pushvalue(L, 1);
800         lua_settable(L, registered_abms);
801         
802         return 0; /* number of results */
803 }
804
805 // register_tool(name, {lots of stuff})
806 static int l_register_tool(lua_State *L)
807 {
808         std::string name = luaL_checkstring(L, 1);
809         check_modname_prefix(L, name);
810         //infostream<<"register_tool: "<<name<<std::endl;
811         luaL_checktype(L, 2, LUA_TTABLE);
812         int table = 2;
813
814         // Get server from registry
815         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
816         Server *server = (Server*)lua_touserdata(L, -1);
817         // And get the writable tool definition manager from the server
818         IWritableToolDefManager *tooldef =
819                         server->getWritableToolDefManager();
820         
821         ToolDefinition def = read_tool_definition(L, table);
822
823         tooldef->registerTool(name, def);
824         return 0; /* number of results */
825 }
826
827 // register_craftitem(name, {lots of stuff})
828 static int l_register_craftitem(lua_State *L)
829 {
830         std::string name = luaL_checkstring(L, 1);
831         check_modname_prefix(L, name);
832         //infostream<<"register_craftitem: "<<name<<std::endl;
833         luaL_checktype(L, 2, LUA_TTABLE);
834         int table = 2;
835
836         // Get server from registry
837         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
838         Server *server = (Server*)lua_touserdata(L, -1);
839         // And get the writable CraftItem definition manager from the server
840         IWritableCraftItemDefManager *craftitemdef =
841                         server->getWritableCraftItemDefManager();
842         
843         // Check if on_drop is defined
844         lua_getfield(L, table, "on_drop");
845         bool got_on_drop = !lua_isnil(L, -1);
846         lua_pop(L, 1);
847
848         // Check if on_use is defined
849         lua_getfield(L, table, "on_use");
850         bool got_on_use = !lua_isnil(L, -1);
851         lua_pop(L, 1);
852
853         CraftItemDefinition def;
854         
855         getstringfield(L, table, "image", def.imagename);
856         getstringfield(L, table, "cookresult_item", def.cookresult_item);
857         getfloatfield(L, table, "furnace_cooktime", def.furnace_cooktime);
858         getfloatfield(L, table, "furnace_burntime", def.furnace_burntime);
859         def.usable = getboolfield_default(L, table, "usable", got_on_use);
860         getboolfield(L, table, "liquids_pointable", def.liquids_pointable);
861         def.dropcount = getintfield_default(L, table, "dropcount", def.dropcount);
862         def.stack_max = getintfield_default(L, table, "stack_max", def.stack_max);
863
864         // If an on_drop callback is defined, force dropcount to 1
865         if (got_on_drop)
866                 def.dropcount = 1;
867
868         // Register it
869         craftitemdef->registerCraftItem(name, def);
870
871         lua_pushvalue(L, table);
872         scriptapi_add_craftitem(L, name.c_str());
873
874         return 0; /* number of results */
875 }
876
877 // register_node(name, {lots of stuff})
878 static int l_register_node(lua_State *L)
879 {
880         std::string name = luaL_checkstring(L, 1);
881         check_modname_prefix(L, name);
882         //infostream<<"register_node: "<<name<<std::endl;
883         luaL_checktype(L, 2, LUA_TTABLE);
884         int nodedef_table = 2;
885
886         // Get server from registry
887         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
888         Server *server = (Server*)lua_touserdata(L, -1);
889         // And get the writable node definition manager from the server
890         IWritableNodeDefManager *nodedef =
891                         server->getWritableNodeDefManager();
892         
893         // Get default node definition from registry
894         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
895         int nodedef_default = lua_gettop(L);
896
897         /*
898                 Add to minetest.registered_nodes with default as metatable
899         */
900         
901         // Get the node definition table given as parameter
902         lua_pushvalue(L, nodedef_table);
903
904         // Set __index to point to itself
905         lua_pushvalue(L, -1);
906         lua_setfield(L, -2, "__index");
907
908         // Set nodedef_default as metatable for the definition
909         lua_pushvalue(L, nodedef_default);
910         lua_setmetatable(L, nodedef_table);
911         
912         // minetest.registered_nodes[name] = nodedef
913         lua_getglobal(L, "minetest");
914         lua_getfield(L, -1, "registered_nodes");
915         luaL_checktype(L, -1, LUA_TTABLE);
916         lua_pushstring(L, name.c_str());
917         lua_pushvalue(L, nodedef_table);
918         lua_settable(L, -3);
919
920         /*
921                 Create definition
922         */
923         
924         ContentFeatures f;
925
926         // Default to getting the corresponding NodeItem when dug
927         f.dug_item = std::string("NodeItem \"")+name+"\" 1";
928         
929         // Default to unknown_block.png as all textures
930         f.setAllTextures("unknown_block.png");
931
932         /*
933                 Read definiton from Lua
934         */
935
936         f.name = name;
937         
938         /* Visual definition */
939
940         f.drawtype = (NodeDrawType)getenumfield(L, nodedef_table, "drawtype", es_DrawType,
941                         NDT_NORMAL);
942         getfloatfield(L, nodedef_table, "visual_scale", f.visual_scale);
943
944         lua_getfield(L, nodedef_table, "tile_images");
945         if(lua_istable(L, -1)){
946                 int table = lua_gettop(L);
947                 lua_pushnil(L);
948                 int i = 0;
949                 while(lua_next(L, table) != 0){
950                         // key at index -2 and value at index -1
951                         if(lua_isstring(L, -1))
952                                 f.tname_tiles[i] = lua_tostring(L, -1);
953                         else
954                                 f.tname_tiles[i] = "";
955                         // removes value, keeps key for next iteration
956                         lua_pop(L, 1);
957                         i++;
958                         if(i==6){
959                                 lua_pop(L, 1);
960                                 break;
961                         }
962                 }
963                 // Copy last value to all remaining textures
964                 if(i >= 1){
965                         std::string lastname = f.tname_tiles[i-1];
966                         while(i < 6){
967                                 f.tname_tiles[i] = lastname;
968                                 i++;
969                         }
970                 }
971         }
972         lua_pop(L, 1);
973
974         getstringfield(L, nodedef_table, "inventory_image", f.tname_inventory);
975
976         lua_getfield(L, nodedef_table, "special_materials");
977         if(lua_istable(L, -1)){
978                 int table = lua_gettop(L);
979                 lua_pushnil(L);
980                 int i = 0;
981                 while(lua_next(L, table) != 0){
982                         // key at index -2 and value at index -1
983                         int smtable = lua_gettop(L);
984                         std::string tname = getstringfield_default(
985                                         L, smtable, "image", "");
986                         bool backface_culling = getboolfield_default(
987                                         L, smtable, "backface_culling", true);
988                         MaterialSpec mspec(tname, backface_culling);
989                         f.setSpecialMaterial(i, mspec);
990                         // removes value, keeps key for next iteration
991                         lua_pop(L, 1);
992                         i++;
993                         if(i==6){
994                                 lua_pop(L, 1);
995                                 break;
996                         }
997                 }
998         }
999         lua_pop(L, 1);
1000
1001         f.alpha = getintfield_default(L, nodedef_table, "alpha", 255);
1002
1003         /* Other stuff */
1004         
1005         lua_getfield(L, nodedef_table, "post_effect_color");
1006         if(!lua_isnil(L, -1))
1007                 f.post_effect_color = readARGB8(L, -1);
1008         lua_pop(L, 1);
1009
1010         f.param_type = (ContentParamType)getenumfield(L, nodedef_table, "paramtype",
1011                         es_ContentParamType, CPT_NONE);
1012         
1013         // True for all ground-like things like stone and mud, false for eg. trees
1014         getboolfield(L, nodedef_table, "is_ground_content", f.is_ground_content);
1015         getboolfield(L, nodedef_table, "light_propagates", f.light_propagates);
1016         getboolfield(L, nodedef_table, "sunlight_propagates", f.sunlight_propagates);
1017         // This is used for collision detection.
1018         // Also for general solidness queries.
1019         getboolfield(L, nodedef_table, "walkable", f.walkable);
1020         // Player can point to these
1021         getboolfield(L, nodedef_table, "pointable", f.pointable);
1022         // Player can dig these
1023         getboolfield(L, nodedef_table, "diggable", f.diggable);
1024         // Player can climb these
1025         getboolfield(L, nodedef_table, "climbable", f.climbable);
1026         // Player can build on these
1027         getboolfield(L, nodedef_table, "buildable_to", f.buildable_to);
1028         // If true, param2 is set to direction when placed. Used for torches.
1029         // NOTE: the direction format is quite inefficient and should be changed
1030         getboolfield(L, nodedef_table, "wall_mounted", f.wall_mounted);
1031         // Whether this content type often contains mineral.
1032         // Used for texture atlas creation.
1033         // Currently only enabled for CONTENT_STONE.
1034         getboolfield(L, nodedef_table, "often_contains_mineral", f.often_contains_mineral);
1035         // Inventory item string as which the node appears in inventory when dug.
1036         // Mineral overrides this.
1037         getstringfield(L, nodedef_table, "dug_item", f.dug_item);
1038         // Extra dug item and its rarity
1039         getstringfield(L, nodedef_table, "extra_dug_item", f.extra_dug_item);
1040         // Usual get interval for extra dug item
1041         getintfield(L, nodedef_table, "extra_dug_item_rarity", f.extra_dug_item_rarity);
1042         // Metadata name of node (eg. "furnace")
1043         getstringfield(L, nodedef_table, "metadata_name", f.metadata_name);
1044         // Whether the node is non-liquid, source liquid or flowing liquid
1045         f.liquid_type = (LiquidType)getenumfield(L, nodedef_table, "liquidtype",
1046                         es_LiquidType, LIQUID_NONE);
1047         // If the content is liquid, this is the flowing version of the liquid.
1048         getstringfield(L, nodedef_table, "liquid_alternative_flowing",
1049                         f.liquid_alternative_flowing);
1050         // If the content is liquid, this is the source version of the liquid.
1051         getstringfield(L, nodedef_table, "liquid_alternative_source",
1052                         f.liquid_alternative_source);
1053         // Viscosity for fluid flow, ranging from 1 to 7, with
1054         // 1 giving almost instantaneous propagation and 7 being
1055         // the slowest possible
1056         f.liquid_viscosity = getintfield_default(L, nodedef_table,
1057                         "liquid_viscosity", f.liquid_viscosity);
1058         // Amount of light the node emits
1059         f.light_source = getintfield_default(L, nodedef_table,
1060                         "light_source", f.light_source);
1061         f.damage_per_second = getintfield_default(L, nodedef_table,
1062                         "damage_per_second", f.damage_per_second);
1063         
1064         lua_getfield(L, nodedef_table, "selection_box");
1065         if(lua_istable(L, -1)){
1066                 f.selection_box.type = (NodeBoxType)getenumfield(L, -1, "type",
1067                                 es_NodeBoxType, NODEBOX_REGULAR);
1068
1069                 lua_getfield(L, -1, "fixed");
1070                 if(lua_istable(L, -1))
1071                         f.selection_box.fixed = read_aabbox3df32(L, -1, BS);
1072                 lua_pop(L, 1);
1073
1074                 lua_getfield(L, -1, "wall_top");
1075                 if(lua_istable(L, -1))
1076                         f.selection_box.wall_top = read_aabbox3df32(L, -1, BS);
1077                 lua_pop(L, 1);
1078
1079                 lua_getfield(L, -1, "wall_bottom");
1080                 if(lua_istable(L, -1))
1081                         f.selection_box.wall_bottom = read_aabbox3df32(L, -1, BS);
1082                 lua_pop(L, 1);
1083
1084                 lua_getfield(L, -1, "wall_side");
1085                 if(lua_istable(L, -1))
1086                         f.selection_box.wall_side = read_aabbox3df32(L, -1, BS);
1087                 lua_pop(L, 1);
1088         }
1089         lua_pop(L, 1);
1090
1091         lua_getfield(L, nodedef_table, "material");
1092         if(lua_istable(L, -1)){
1093                 f.material.diggability = (Diggability)getenumfield(L, -1, "diggability",
1094                                 es_Diggability, DIGGABLE_NORMAL);
1095                 
1096                 getfloatfield(L, -1, "constant_time", f.material.constant_time);
1097                 getfloatfield(L, -1, "weight", f.material.weight);
1098                 getfloatfield(L, -1, "crackiness", f.material.crackiness);
1099                 getfloatfield(L, -1, "crumbliness", f.material.crumbliness);
1100                 getfloatfield(L, -1, "cuttability", f.material.cuttability);
1101                 getfloatfield(L, -1, "flammability", f.material.flammability);
1102         }
1103         lua_pop(L, 1);
1104
1105         getstringfield(L, nodedef_table, "cookresult_item", f.cookresult_item);
1106         getfloatfield(L, nodedef_table, "furnace_cooktime", f.furnace_cooktime);
1107         getfloatfield(L, nodedef_table, "furnace_burntime", f.furnace_burntime);
1108         
1109         /*
1110                 Register it
1111         */
1112         
1113         nodedef->set(name, f);
1114         
1115         return 0; /* number of results */
1116 }
1117
1118 // register_craft({output=item, recipe={{item00,item10},{item01,item11}})
1119 static int l_register_craft(lua_State *L)
1120 {
1121         //infostream<<"register_craft"<<std::endl;
1122         luaL_checktype(L, 1, LUA_TTABLE);
1123         int table0 = 1;
1124
1125         // Get server from registry
1126         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1127         Server *server = (Server*)lua_touserdata(L, -1);
1128         // And get the writable craft definition manager from the server
1129         IWritableCraftDefManager *craftdef =
1130                         server->getWritableCraftDefManager();
1131         
1132         std::string output;
1133         int width = 0;
1134         std::vector<std::string> input;
1135
1136         lua_getfield(L, table0, "output");
1137         luaL_checktype(L, -1, LUA_TSTRING);
1138         if(lua_isstring(L, -1))
1139                 output = lua_tostring(L, -1);
1140         lua_pop(L, 1);
1141
1142         lua_getfield(L, table0, "recipe");
1143         luaL_checktype(L, -1, LUA_TTABLE);
1144         if(lua_istable(L, -1)){
1145                 int table1 = lua_gettop(L);
1146                 lua_pushnil(L);
1147                 int rowcount = 0;
1148                 while(lua_next(L, table1) != 0){
1149                         int colcount = 0;
1150                         // key at index -2 and value at index -1
1151                         luaL_checktype(L, -1, LUA_TTABLE);
1152                         if(lua_istable(L, -1)){
1153                                 int table2 = lua_gettop(L);
1154                                 lua_pushnil(L);
1155                                 while(lua_next(L, table2) != 0){
1156                                         // key at index -2 and value at index -1
1157                                         luaL_checktype(L, -1, LUA_TSTRING);
1158                                         input.push_back(lua_tostring(L, -1));
1159                                         // removes value, keeps key for next iteration
1160                                         lua_pop(L, 1);
1161                                         colcount++;
1162                                 }
1163                         }
1164                         if(rowcount == 0){
1165                                 width = colcount;
1166                         } else {
1167                                 if(colcount != width){
1168                                         std::string error;
1169                                         error += "Invalid crafting recipe (output=\""
1170                                                         + output + "\")";
1171                                         throw LuaError(L, error);
1172                                 }
1173                         }
1174                         // removes value, keeps key for next iteration
1175                         lua_pop(L, 1);
1176                         rowcount++;
1177                 }
1178         }
1179         lua_pop(L, 1);
1180
1181         CraftDefinition def(output, width, input);
1182         craftdef->registerCraft(def);
1183
1184         return 0; /* number of results */
1185 }
1186
1187 // setting_get(name)
1188 static int l_setting_get(lua_State *L)
1189 {
1190         const char *name = luaL_checkstring(L, 1);
1191         try{
1192                 std::string value = g_settings->get(name);
1193                 lua_pushstring(L, value.c_str());
1194         } catch(SettingNotFoundException &e){
1195                 lua_pushnil(L);
1196         }
1197         return 1;
1198 }
1199
1200 // setting_getbool(name)
1201 static int l_setting_getbool(lua_State *L)
1202 {
1203         const char *name = luaL_checkstring(L, 1);
1204         try{
1205                 bool value = g_settings->getBool(name);
1206                 lua_pushboolean(L, value);
1207         } catch(SettingNotFoundException &e){
1208                 lua_pushnil(L);
1209         }
1210         return 1;
1211 }
1212
1213 // chat_send_all(text)
1214 static int l_chat_send_all(lua_State *L)
1215 {
1216         const char *text = luaL_checkstring(L, 1);
1217         // Get server from registry
1218         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1219         Server *server = (Server*)lua_touserdata(L, -1);
1220         // Send
1221         server->notifyPlayers(narrow_to_wide(text));
1222         return 0;
1223 }
1224
1225 // chat_send_player(name, text)
1226 static int l_chat_send_player(lua_State *L)
1227 {
1228         const char *name = luaL_checkstring(L, 1);
1229         const char *text = luaL_checkstring(L, 2);
1230         // Get server from registry
1231         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1232         Server *server = (Server*)lua_touserdata(L, -1);
1233         // Send
1234         server->notifyPlayer(name, narrow_to_wide(text));
1235         return 0;
1236 }
1237
1238 // get_player_privs(name, text)
1239 static int l_get_player_privs(lua_State *L)
1240 {
1241         const char *name = luaL_checkstring(L, 1);
1242         // Get server from registry
1243         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1244         Server *server = (Server*)lua_touserdata(L, -1);
1245         // Do it
1246         lua_newtable(L);
1247         int table = lua_gettop(L);
1248         u64 privs_i = server->getPlayerAuthPrivs(name);
1249         // Special case for the "name" setting (local player / server owner)
1250         if(name == g_settings->get("name"))
1251                 privs_i = PRIV_ALL;
1252         std::set<std::string> privs_s = privsToSet(privs_i);
1253         for(std::set<std::string>::const_iterator
1254                         i = privs_s.begin(); i != privs_s.end(); i++){
1255                 lua_pushboolean(L, true);
1256                 lua_setfield(L, table, i->c_str());
1257         }
1258         lua_pushvalue(L, table);
1259         return 1;
1260 }
1261
1262 static const struct luaL_Reg minetest_f [] = {
1263         {"register_nodedef_defaults", l_register_nodedef_defaults},
1264         {"register_entity", l_register_entity},
1265         {"register_tool", l_register_tool},
1266         {"register_craftitem", l_register_craftitem},
1267         {"register_node", l_register_node},
1268         {"register_craft", l_register_craft},
1269         {"register_abm", l_register_abm},
1270         {"setting_get", l_setting_get},
1271         {"setting_getbool", l_setting_getbool},
1272         {"chat_send_all", l_chat_send_all},
1273         {"chat_send_player", l_chat_send_player},
1274         {"get_player_privs", l_get_player_privs},
1275         {NULL, NULL}
1276 };
1277
1278 /*
1279         LuaEntity functions
1280 */
1281
1282 static const struct luaL_Reg minetest_entity_m [] = {
1283         {NULL, NULL}
1284 };
1285
1286 /*
1287         Getters for stuff in main tables
1288 */
1289
1290 static void objectref_get(lua_State *L, u16 id)
1291 {
1292         // Get minetest.object_refs[i]
1293         lua_getglobal(L, "minetest");
1294         lua_getfield(L, -1, "object_refs");
1295         luaL_checktype(L, -1, LUA_TTABLE);
1296         lua_pushnumber(L, id);
1297         lua_gettable(L, -2);
1298         lua_remove(L, -2); // object_refs
1299         lua_remove(L, -2); // minetest
1300 }
1301
1302 static void luaentity_get(lua_State *L, u16 id)
1303 {
1304         // Get minetest.luaentities[i]
1305         lua_getglobal(L, "minetest");
1306         lua_getfield(L, -1, "luaentities");
1307         luaL_checktype(L, -1, LUA_TTABLE);
1308         lua_pushnumber(L, id);
1309         lua_gettable(L, -2);
1310         lua_remove(L, -2); // luaentities
1311         lua_remove(L, -2); // minetest
1312 }
1313
1314 /*
1315         Reference wrappers
1316 */
1317
1318 #define method(class, name) {#name, class::l_##name}
1319
1320 /*
1321         NodeMetaRef
1322 */
1323
1324 class NodeMetaRef
1325 {
1326 private:
1327         v3s16 m_p;
1328         ServerEnvironment *m_env;
1329
1330         static const char className[];
1331         static const luaL_reg methods[];
1332
1333         static NodeMetaRef *checkobject(lua_State *L, int narg)
1334         {
1335                 luaL_checktype(L, narg, LUA_TUSERDATA);
1336                 void *ud = luaL_checkudata(L, narg, className);
1337                 if(!ud) luaL_typerror(L, narg, className);
1338                 return *(NodeMetaRef**)ud;  // unbox pointer
1339         }
1340         
1341         static NodeMetadata* getmeta(NodeMetaRef *ref)
1342         {
1343                 NodeMetadata *meta = ref->m_env->getMap().getNodeMetadata(ref->m_p);
1344                 return meta;
1345         }
1346
1347         /*static IGenericNodeMetadata* getgenericmeta(NodeMetaRef *ref)
1348         {
1349                 NodeMetadata *meta = getmeta(ref);
1350                 if(meta == NULL)
1351                         return NULL;
1352                 if(meta->typeId() != NODEMETA_GENERIC)
1353                         return NULL;
1354                 return (IGenericNodeMetadata*)meta;
1355         }*/
1356
1357         static void reportMetadataChange(NodeMetaRef *ref)
1358         {
1359                 // Inform other things that the metadata has changed
1360                 v3s16 blockpos = getNodeBlockPos(ref->m_p);
1361                 MapEditEvent event;
1362                 event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
1363                 event.p = blockpos;
1364                 ref->m_env->getMap().dispatchEvent(&event);
1365                 // Set the block to be saved
1366                 MapBlock *block = ref->m_env->getMap().getBlockNoCreateNoEx(blockpos);
1367                 if(block)
1368                         block->raiseModified(MOD_STATE_WRITE_NEEDED,
1369                                         "NodeMetaRef::reportMetadataChange");
1370         }
1371         
1372         // Exported functions
1373         
1374         // garbage collector
1375         static int gc_object(lua_State *L) {
1376                 NodeMetaRef *o = *(NodeMetaRef **)(lua_touserdata(L, 1));
1377                 delete o;
1378                 return 0;
1379         }
1380
1381         // get_type(self)
1382         static int l_get_type(lua_State *L)
1383         {
1384                 NodeMetaRef *ref = checkobject(L, 1);
1385                 NodeMetadata *meta = getmeta(ref);
1386                 if(meta == NULL){
1387                         lua_pushnil(L);
1388                         return 1;
1389                 }
1390                 // Do it
1391                 lua_pushstring(L, meta->typeName());
1392                 return 1;
1393         }
1394
1395         // allows_text_input(self)
1396         static int l_allows_text_input(lua_State *L)
1397         {
1398                 NodeMetaRef *ref = checkobject(L, 1);
1399                 NodeMetadata *meta = getmeta(ref);
1400                 if(meta == NULL) return 0;
1401                 // Do it
1402                 lua_pushboolean(L, meta->allowsTextInput());
1403                 return 1;
1404         }
1405
1406         // set_text(self, text)
1407         static int l_set_text(lua_State *L)
1408         {
1409                 NodeMetaRef *ref = checkobject(L, 1);
1410                 NodeMetadata *meta = getmeta(ref);
1411                 if(meta == NULL) return 0;
1412                 // Do it
1413                 std::string text = lua_tostring(L, 2);
1414                 meta->setText(text);
1415                 reportMetadataChange(ref);
1416                 return 0;
1417         }
1418
1419         // get_text(self)
1420         static int l_get_text(lua_State *L)
1421         {
1422                 NodeMetaRef *ref = checkobject(L, 1);
1423                 NodeMetadata *meta = getmeta(ref);
1424                 if(meta == NULL) return 0;
1425                 // Do it
1426                 std::string text = meta->getText();
1427                 lua_pushstring(L, text.c_str());
1428                 return 1;
1429         }
1430
1431         // get_owner(self)
1432         static int l_get_owner(lua_State *L)
1433         {
1434                 NodeMetaRef *ref = checkobject(L, 1);
1435                 NodeMetadata *meta = getmeta(ref);
1436                 if(meta == NULL) return 0;
1437                 // Do it
1438                 std::string owner = meta->getOwner();
1439                 lua_pushstring(L, owner.c_str());
1440                 return 1;
1441         }
1442
1443         /* IGenericNodeMetadata interface */
1444         
1445         // set_infotext(self, text)
1446         static int l_set_infotext(lua_State *L)
1447         {
1448                 infostream<<__FUNCTION_NAME<<std::endl;
1449                 NodeMetaRef *ref = checkobject(L, 1);
1450                 NodeMetadata *meta = getmeta(ref);
1451                 if(meta == NULL) return 0;
1452                 // Do it
1453                 std::string text = lua_tostring(L, 2);
1454                 meta->setInfoText(text);
1455                 reportMetadataChange(ref);
1456                 return 0;
1457         }
1458
1459         // inventory_set_list(self, name, {item1, item2, ...})
1460         static int l_inventory_set_list(lua_State *L)
1461         {
1462                 NodeMetaRef *ref = checkobject(L, 1);
1463                 NodeMetadata *meta = getmeta(ref);
1464                 if(meta == NULL) return 0;
1465                 // Do it
1466                 Inventory *inv = meta->getInventory();
1467                 const char *name = lua_tostring(L, 2);
1468                 inventory_set_list_from_lua(inv, name, L, 3,
1469                                 ref->m_env->getGameDef());
1470                 reportMetadataChange(ref);
1471                 return 0;
1472         }
1473
1474         // inventory_get_list(self, name)
1475         static int l_inventory_get_list(lua_State *L)
1476         {
1477                 NodeMetaRef *ref = checkobject(L, 1);
1478                 NodeMetadata *meta = getmeta(ref);
1479                 if(meta == NULL) return 0;
1480                 // Do it
1481                 Inventory *inv = meta->getInventory();
1482                 const char *name = lua_tostring(L, 2);
1483                 inventory_get_list_to_lua(inv, name, L);
1484                 return 1;
1485         }
1486
1487         // set_inventory_draw_spec(self, text)
1488         static int l_set_inventory_draw_spec(lua_State *L)
1489         {
1490                 NodeMetaRef *ref = checkobject(L, 1);
1491                 NodeMetadata *meta = getmeta(ref);
1492                 if(meta == NULL) return 0;
1493                 // Do it
1494                 std::string text = lua_tostring(L, 2);
1495                 meta->setInventoryDrawSpec(text);
1496                 reportMetadataChange(ref);
1497                 return 0;
1498         }
1499
1500         // set_allow_text_input(self, text)
1501         static int l_set_allow_text_input(lua_State *L)
1502         {
1503                 NodeMetaRef *ref = checkobject(L, 1);
1504                 NodeMetadata *meta = getmeta(ref);
1505                 if(meta == NULL) return 0;
1506                 // Do it
1507                 bool b = lua_toboolean(L, 2);
1508                 meta->setAllowTextInput(b);
1509                 reportMetadataChange(ref);
1510                 return 0;
1511         }
1512
1513         // set_allow_removal(self, text)
1514         static int l_set_allow_removal(lua_State *L)
1515         {
1516                 NodeMetaRef *ref = checkobject(L, 1);
1517                 NodeMetadata *meta = getmeta(ref);
1518                 if(meta == NULL) return 0;
1519                 // Do it
1520                 bool b = lua_toboolean(L, 2);
1521                 meta->setRemovalDisabled(!b);
1522                 reportMetadataChange(ref);
1523                 return 0;
1524         }
1525
1526         // set_enforce_owner(self, text)
1527         static int l_set_enforce_owner(lua_State *L)
1528         {
1529                 NodeMetaRef *ref = checkobject(L, 1);
1530                 NodeMetadata *meta = getmeta(ref);
1531                 if(meta == NULL) return 0;
1532                 // Do it
1533                 bool b = lua_toboolean(L, 2);
1534                 meta->setEnforceOwner(b);
1535                 reportMetadataChange(ref);
1536                 return 0;
1537         }
1538
1539         // is_inventory_modified(self)
1540         static int l_is_inventory_modified(lua_State *L)
1541         {
1542                 NodeMetaRef *ref = checkobject(L, 1);
1543                 NodeMetadata *meta = getmeta(ref);
1544                 if(meta == NULL) return 0;
1545                 // Do it
1546                 lua_pushboolean(L, meta->isInventoryModified());
1547                 return 1;
1548         }
1549
1550         // reset_inventory_modified(self)
1551         static int l_reset_inventory_modified(lua_State *L)
1552         {
1553                 NodeMetaRef *ref = checkobject(L, 1);
1554                 NodeMetadata *meta = getmeta(ref);
1555                 if(meta == NULL) return 0;
1556                 // Do it
1557                 meta->resetInventoryModified();
1558                 reportMetadataChange(ref);
1559                 return 0;
1560         }
1561
1562         // is_text_modified(self)
1563         static int l_is_text_modified(lua_State *L)
1564         {
1565                 NodeMetaRef *ref = checkobject(L, 1);
1566                 NodeMetadata *meta = getmeta(ref);
1567                 if(meta == NULL) return 0;
1568                 // Do it
1569                 lua_pushboolean(L, meta->isTextModified());
1570                 return 1;
1571         }
1572
1573         // reset_text_modified(self)
1574         static int l_reset_text_modified(lua_State *L)
1575         {
1576                 NodeMetaRef *ref = checkobject(L, 1);
1577                 NodeMetadata *meta = getmeta(ref);
1578                 if(meta == NULL) return 0;
1579                 // Do it
1580                 meta->resetTextModified();
1581                 reportMetadataChange(ref);
1582                 return 0;
1583         }
1584
1585         // set_string(self, name, var)
1586         static int l_set_string(lua_State *L)
1587         {
1588                 NodeMetaRef *ref = checkobject(L, 1);
1589                 NodeMetadata *meta = getmeta(ref);
1590                 if(meta == NULL) return 0;
1591                 // Do it
1592                 std::string name = lua_tostring(L, 2);
1593                 size_t len = 0;
1594                 const char *s = lua_tolstring(L, 3, &len);
1595                 std::string str(s, len);
1596                 meta->setString(name, str);
1597                 reportMetadataChange(ref);
1598                 return 0;
1599         }
1600
1601         // get_string(self, name)
1602         static int l_get_string(lua_State *L)
1603         {
1604                 NodeMetaRef *ref = checkobject(L, 1);
1605                 NodeMetadata *meta = getmeta(ref);
1606                 if(meta == NULL) return 0;
1607                 // Do it
1608                 std::string name = lua_tostring(L, 2);
1609                 std::string str = meta->getString(name);
1610                 lua_pushlstring(L, str.c_str(), str.size());
1611                 return 1;
1612         }
1613
1614 public:
1615         NodeMetaRef(v3s16 p, ServerEnvironment *env):
1616                 m_p(p),
1617                 m_env(env)
1618         {
1619         }
1620
1621         ~NodeMetaRef()
1622         {
1623         }
1624
1625         // Creates an NodeMetaRef and leaves it on top of stack
1626         // Not callable from Lua; all references are created on the C side.
1627         static void create(lua_State *L, v3s16 p, ServerEnvironment *env)
1628         {
1629                 NodeMetaRef *o = new NodeMetaRef(p, env);
1630                 //infostream<<"NodeMetaRef::create: o="<<o<<std::endl;
1631                 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1632                 luaL_getmetatable(L, className);
1633                 lua_setmetatable(L, -2);
1634         }
1635
1636         static void Register(lua_State *L)
1637         {
1638                 lua_newtable(L);
1639                 int methodtable = lua_gettop(L);
1640                 luaL_newmetatable(L, className);
1641                 int metatable = lua_gettop(L);
1642
1643                 lua_pushliteral(L, "__metatable");
1644                 lua_pushvalue(L, methodtable);
1645                 lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
1646
1647                 lua_pushliteral(L, "__index");
1648                 lua_pushvalue(L, methodtable);
1649                 lua_settable(L, metatable);
1650
1651                 lua_pushliteral(L, "__gc");
1652                 lua_pushcfunction(L, gc_object);
1653                 lua_settable(L, metatable);
1654
1655                 lua_pop(L, 1);  // drop metatable
1656
1657                 luaL_openlib(L, 0, methods, 0);  // fill methodtable
1658                 lua_pop(L, 1);  // drop methodtable
1659
1660                 // Cannot be created from Lua
1661                 //lua_register(L, className, create_object);
1662         }
1663 };
1664 const char NodeMetaRef::className[] = "NodeMetaRef";
1665 const luaL_reg NodeMetaRef::methods[] = {
1666         method(NodeMetaRef, get_type),
1667         method(NodeMetaRef, allows_text_input),
1668         method(NodeMetaRef, set_text),
1669         method(NodeMetaRef, get_text),
1670         method(NodeMetaRef, get_owner),
1671         method(NodeMetaRef, set_infotext),
1672         method(NodeMetaRef, inventory_set_list),
1673         method(NodeMetaRef, inventory_get_list),
1674         method(NodeMetaRef, set_inventory_draw_spec),
1675         method(NodeMetaRef, set_allow_text_input),
1676         method(NodeMetaRef, set_allow_removal),
1677         method(NodeMetaRef, set_enforce_owner),
1678         method(NodeMetaRef, is_inventory_modified),
1679         method(NodeMetaRef, reset_inventory_modified),
1680         method(NodeMetaRef, is_text_modified),
1681         method(NodeMetaRef, reset_text_modified),
1682         method(NodeMetaRef, set_string),
1683         method(NodeMetaRef, get_string),
1684         {0,0}
1685 };
1686
1687 /*
1688         ObjectRef
1689 */
1690
1691 class ObjectRef
1692 {
1693 private:
1694         ServerActiveObject *m_object;
1695
1696         static const char className[];
1697         static const luaL_reg methods[];
1698
1699         static ObjectRef *checkobject(lua_State *L, int narg)
1700         {
1701                 luaL_checktype(L, narg, LUA_TUSERDATA);
1702                 void *ud = luaL_checkudata(L, narg, className);
1703                 if(!ud) luaL_typerror(L, narg, className);
1704                 return *(ObjectRef**)ud;  // unbox pointer
1705         }
1706         
1707         static ServerActiveObject* getobject(ObjectRef *ref)
1708         {
1709                 ServerActiveObject *co = ref->m_object;
1710                 return co;
1711         }
1712         
1713         static LuaEntitySAO* getluaobject(ObjectRef *ref)
1714         {
1715                 ServerActiveObject *obj = getobject(ref);
1716                 if(obj == NULL)
1717                         return NULL;
1718                 if(obj->getType() != ACTIVEOBJECT_TYPE_LUAENTITY)
1719                         return NULL;
1720                 return (LuaEntitySAO*)obj;
1721         }
1722         
1723         static ServerRemotePlayer* getplayer(ObjectRef *ref)
1724         {
1725                 ServerActiveObject *obj = getobject(ref);
1726                 if(obj == NULL)
1727                         return NULL;
1728                 if(obj->getType() != ACTIVEOBJECT_TYPE_PLAYER)
1729                         return NULL;
1730                 return static_cast<ServerRemotePlayer*>(obj);
1731         }
1732         
1733         // Exported functions
1734         
1735         // garbage collector
1736         static int gc_object(lua_State *L) {
1737                 ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
1738                 //infostream<<"ObjectRef::gc_object: o="<<o<<std::endl;
1739                 delete o;
1740                 return 0;
1741         }
1742
1743         // remove(self)
1744         static int l_remove(lua_State *L)
1745         {
1746                 ObjectRef *ref = checkobject(L, 1);
1747                 ServerActiveObject *co = getobject(ref);
1748                 if(co == NULL) return 0;
1749                 infostream<<"ObjectRef::l_remove(): id="<<co->getId()<<std::endl;
1750                 co->m_removed = true;
1751                 return 0;
1752         }
1753         
1754         // getpos(self)
1755         // returns: {x=num, y=num, z=num}
1756         static int l_getpos(lua_State *L)
1757         {
1758                 ObjectRef *ref = checkobject(L, 1);
1759                 ServerActiveObject *co = getobject(ref);
1760                 if(co == NULL) return 0;
1761                 v3f pos = co->getBasePosition() / BS;
1762                 lua_newtable(L);
1763                 lua_pushnumber(L, pos.X);
1764                 lua_setfield(L, -2, "x");
1765                 lua_pushnumber(L, pos.Y);
1766                 lua_setfield(L, -2, "y");
1767                 lua_pushnumber(L, pos.Z);
1768                 lua_setfield(L, -2, "z");
1769                 return 1;
1770         }
1771         
1772         // setpos(self, pos)
1773         static int l_setpos(lua_State *L)
1774         {
1775                 ObjectRef *ref = checkobject(L, 1);
1776                 //LuaEntitySAO *co = getluaobject(ref);
1777                 ServerActiveObject *co = getobject(ref);
1778                 if(co == NULL) return 0;
1779                 // pos
1780                 v3f pos = readFloatPos(L, 2);
1781                 // Do it
1782                 co->setPos(pos);
1783                 return 0;
1784         }
1785         
1786         // moveto(self, pos, continuous=false)
1787         static int l_moveto(lua_State *L)
1788         {
1789                 ObjectRef *ref = checkobject(L, 1);
1790                 //LuaEntitySAO *co = getluaobject(ref);
1791                 ServerActiveObject *co = getobject(ref);
1792                 if(co == NULL) return 0;
1793                 // pos
1794                 v3f pos = readFloatPos(L, 2);
1795                 // continuous
1796                 bool continuous = lua_toboolean(L, 3);
1797                 // Do it
1798                 co->moveTo(pos, continuous);
1799                 return 0;
1800         }
1801
1802         // punch(self, puncher); puncher = an another ObjectRef
1803         static int l_punch(lua_State *L)
1804         {
1805                 ObjectRef *ref = checkobject(L, 1);
1806                 ObjectRef *ref2 = checkobject(L, 2);
1807                 ServerActiveObject *co = getobject(ref);
1808                 ServerActiveObject *co2 = getobject(ref2);
1809                 if(co == NULL) return 0;
1810                 if(co2 == NULL) return 0;
1811                 // Do it
1812                 co->punch(co2);
1813                 return 0;
1814         }
1815
1816         // right_click(self, clicker); clicker = an another ObjectRef
1817         static int l_right_click(lua_State *L)
1818         {
1819                 ObjectRef *ref = checkobject(L, 1);
1820                 ObjectRef *ref2 = checkobject(L, 2);
1821                 ServerActiveObject *co = getobject(ref);
1822                 ServerActiveObject *co2 = getobject(ref2);
1823                 if(co == NULL) return 0;
1824                 if(co2 == NULL) return 0;
1825                 // Do it
1826                 co->rightClick(co2);
1827                 return 0;
1828         }
1829
1830         // get_wield_digging_properties(self)
1831         static int l_get_wield_digging_properties(lua_State *L)
1832         {
1833                 ObjectRef *ref = checkobject(L, 1);
1834                 ServerActiveObject *co = getobject(ref);
1835                 if(co == NULL) return 0;
1836                 // Do it
1837                 ToolDiggingProperties prop;
1838                 co->getWieldDiggingProperties(&prop);
1839                 push_tool_digging_properties(L, prop);
1840                 return 1;
1841         }
1842
1843         // damage_wielded_item(self, amount)
1844         static int l_damage_wielded_item(lua_State *L)
1845         {
1846                 ObjectRef *ref = checkobject(L, 1);
1847                 ServerActiveObject *co = getobject(ref);
1848                 if(co == NULL) return 0;
1849                 // Do it
1850                 int amount = lua_tonumber(L, 2);
1851                 co->damageWieldedItem(amount);
1852                 return 0;
1853         }
1854
1855         // add_to_inventory(self, itemstring)
1856         // returns: true if item was added, (false, "reason") otherwise
1857         static int l_add_to_inventory(lua_State *L)
1858         {
1859                 ObjectRef *ref = checkobject(L, 1);
1860                 luaL_checkstring(L, 2);
1861                 ServerActiveObject *co = getobject(ref);
1862                 if(co == NULL) return 0;
1863                 // itemstring
1864                 const char *itemstring = lua_tostring(L, 2);
1865                 infostream<<"ObjectRef::l_add_to_inventory(): id="<<co->getId()
1866                                 <<" itemstring=\""<<itemstring<<"\""<<std::endl;
1867                 // Do it
1868                 std::istringstream is(itemstring, std::ios::binary);
1869                 ServerEnvironment *env = co->getEnv();
1870                 assert(env);
1871                 IGameDef *gamedef = env->getGameDef();
1872                 try{
1873                         InventoryItem *item = InventoryItem::deSerialize(is, gamedef);
1874                         if(item->getCount() == 0)
1875                                 item->setCount(1);
1876                         bool added = co->addToInventory(item);
1877                         // Return
1878                         lua_pushboolean(L, added);
1879                         if(!added)
1880                                 lua_pushstring(L, "failed to add item");
1881                         return 2;
1882                 } catch(SerializationError &e){
1883                         // Return
1884                         lua_pushboolean(L, false);
1885                         lua_pushstring(L, (std::string("Invalid item: ")
1886                                         + e.what()).c_str());
1887                         return 2;
1888                 }
1889         }
1890
1891         // add_to_inventory_later(self, itemstring)
1892         // returns: nil
1893         static int l_add_to_inventory_later(lua_State *L)
1894         {
1895                 ObjectRef *ref = checkobject(L, 1);
1896                 luaL_checkstring(L, 2);
1897                 ServerActiveObject *co = getobject(ref);
1898                 if(co == NULL) return 0;
1899                 // itemstring
1900                 const char *itemstring = lua_tostring(L, 2);
1901                 infostream<<"ObjectRef::l_add_to_inventory_later(): id="<<co->getId()
1902                                 <<" itemstring=\""<<itemstring<<"\""<<std::endl;
1903                 // Do it
1904                 std::istringstream is(itemstring, std::ios::binary);
1905                 ServerEnvironment *env = co->getEnv();
1906                 assert(env);
1907                 IGameDef *gamedef = env->getGameDef();
1908                 InventoryItem *item = InventoryItem::deSerialize(is, gamedef);
1909                 infostream<<"item="<<env<<std::endl;
1910                 co->addToInventoryLater(item);
1911                 // Return
1912                 return 0;
1913         }
1914
1915         // set_hp(self, hp)
1916         // hp = number of hitpoints (2 * number of hearts)
1917         // returns: nil
1918         static int l_set_hp(lua_State *L)
1919         {
1920                 ObjectRef *ref = checkobject(L, 1);
1921                 luaL_checknumber(L, 2);
1922                 ServerActiveObject *co = getobject(ref);
1923                 if(co == NULL) return 0;
1924                 int hp = lua_tonumber(L, 2);
1925                 infostream<<"ObjectRef::l_set_hp(): id="<<co->getId()
1926                                 <<" hp="<<hp<<std::endl;
1927                 // Do it
1928                 co->setHP(hp);
1929                 // Return
1930                 return 0;
1931         }
1932
1933         // get_hp(self)
1934         // returns: number of hitpoints (2 * number of hearts)
1935         // 0 if not applicable to this type of object
1936         static int l_get_hp(lua_State *L)
1937         {
1938                 ObjectRef *ref = checkobject(L, 1);
1939                 ServerActiveObject *co = getobject(ref);
1940                 if(co == NULL) return 0;
1941                 int hp = co->getHP();
1942                 infostream<<"ObjectRef::l_get_hp(): id="<<co->getId()
1943                                 <<" hp="<<hp<<std::endl;
1944                 // Return
1945                 lua_pushnumber(L, hp);
1946                 return 1;
1947         }
1948
1949         /* LuaEntitySAO-only */
1950
1951         // setvelocity(self, {x=num, y=num, z=num})
1952         static int l_setvelocity(lua_State *L)
1953         {
1954                 ObjectRef *ref = checkobject(L, 1);
1955                 LuaEntitySAO *co = getluaobject(ref);
1956                 if(co == NULL) return 0;
1957                 // pos
1958                 v3f pos = readFloatPos(L, 2);
1959                 // Do it
1960                 co->setVelocity(pos);
1961                 return 0;
1962         }
1963         
1964         // setacceleration(self, {x=num, y=num, z=num})
1965         static int l_setacceleration(lua_State *L)
1966         {
1967                 ObjectRef *ref = checkobject(L, 1);
1968                 LuaEntitySAO *co = getluaobject(ref);
1969                 if(co == NULL) return 0;
1970                 // pos
1971                 v3f pos = readFloatPos(L, 2);
1972                 // Do it
1973                 co->setAcceleration(pos);
1974                 return 0;
1975         }
1976         
1977         // getacceleration(self)
1978         static int l_getacceleration(lua_State *L)
1979         {
1980                 ObjectRef *ref = checkobject(L, 1);
1981                 LuaEntitySAO *co = getluaobject(ref);
1982                 if(co == NULL) return 0;
1983                 // Do it
1984                 v3f v = co->getAcceleration();
1985                 pushFloatPos(L, v);
1986                 return 1;
1987         }
1988         
1989         // settexturemod(self, mod)
1990         static int l_settexturemod(lua_State *L)
1991         {
1992                 ObjectRef *ref = checkobject(L, 1);
1993                 LuaEntitySAO *co = getluaobject(ref);
1994                 if(co == NULL) return 0;
1995                 // Do it
1996                 std::string mod = lua_tostring(L, 2);
1997                 co->setTextureMod(mod);
1998                 return 0;
1999         }
2000         
2001         // setsprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2,
2002         //           select_horiz_by_yawpitch=false)
2003         static int l_setsprite(lua_State *L)
2004         {
2005                 ObjectRef *ref = checkobject(L, 1);
2006                 LuaEntitySAO *co = getluaobject(ref);
2007                 if(co == NULL) return 0;
2008                 // Do it
2009                 v2s16 p(0,0);
2010                 if(!lua_isnil(L, 2))
2011                         p = read_v2s16(L, 2);
2012                 int num_frames = 1;
2013                 if(!lua_isnil(L, 3))
2014                         num_frames = lua_tonumber(L, 3);
2015                 float framelength = 0.2;
2016                 if(!lua_isnil(L, 4))
2017                         framelength = lua_tonumber(L, 4);
2018                 bool select_horiz_by_yawpitch = false;
2019                 if(!lua_isnil(L, 5))
2020                         select_horiz_by_yawpitch = lua_toboolean(L, 5);
2021                 co->setSprite(p, num_frames, framelength, select_horiz_by_yawpitch);
2022                 return 0;
2023         }
2024
2025         /* Player-only */
2026         
2027         // get_player_name(self)
2028         static int l_get_player_name(lua_State *L)
2029         {
2030                 ObjectRef *ref = checkobject(L, 1);
2031                 ServerRemotePlayer *player = getplayer(ref);
2032                 if(player == NULL){
2033                         lua_pushnil(L);
2034                         return 1;
2035                 }
2036                 // Do it
2037                 lua_pushstring(L, player->getName());
2038                 return 1;
2039         }
2040         
2041         // inventory_set_list(self, name, {item1, item2, ...})
2042         static int l_inventory_set_list(lua_State *L)
2043         {
2044                 ObjectRef *ref = checkobject(L, 1);
2045                 ServerRemotePlayer *player = getplayer(ref);
2046                 if(player == NULL) return 0;
2047                 const char *name = lua_tostring(L, 2);
2048                 // Do it
2049                 inventory_set_list_from_lua(&player->inventory, name, L, 3,
2050                                 player->getEnv()->getGameDef(), PLAYER_INVENTORY_SIZE);
2051                 player->m_inventory_not_sent = true;
2052                 return 0;
2053         }
2054
2055         // inventory_get_list(self, name)
2056         static int l_inventory_get_list(lua_State *L)
2057         {
2058                 ObjectRef *ref = checkobject(L, 1);
2059                 ServerRemotePlayer *player = getplayer(ref);
2060                 if(player == NULL) return 0;
2061                 const char *name = lua_tostring(L, 2);
2062                 // Do it
2063                 inventory_get_list_to_lua(&player->inventory, name, L);
2064                 return 1;
2065         }
2066
2067         // get_wielded_itemstring(self)
2068         static int l_get_wielded_itemstring(lua_State *L)
2069         {
2070                 ObjectRef *ref = checkobject(L, 1);
2071                 ServerRemotePlayer *player = getplayer(ref);
2072                 if(player == NULL) return 0;
2073                 // Do it
2074                 InventoryItem *item = player->getWieldedItem();
2075                 if(item == NULL){
2076                         lua_pushnil(L);
2077                         return 1;
2078                 }
2079                 lua_pushstring(L, item->getItemString().c_str());
2080                 return 1;
2081         }
2082
2083         // get_wielded_item(self)
2084         static int l_get_wielded_item(lua_State *L)
2085         {
2086                 ObjectRef *ref = checkobject(L, 1);
2087                 ServerRemotePlayer *player = getplayer(ref);
2088                 if(player == NULL) return 0;
2089                 // Do it
2090                 InventoryItem *item0 = player->getWieldedItem();
2091                 if(item0 == NULL){
2092                         lua_pushnil(L);
2093                         return 1;
2094                 }
2095                 if(std::string("MaterialItem") == item0->getName()){
2096                         MaterialItem *item = (MaterialItem*)item0;
2097                         lua_newtable(L);
2098                         lua_pushstring(L, "NodeItem");
2099                         lua_setfield(L, -2, "type");
2100                         lua_pushstring(L, item->getNodeName().c_str());
2101                         lua_setfield(L, -2, "name");
2102                 }
2103                 else if(std::string("CraftItem") == item0->getName()){
2104                         CraftItem *item = (CraftItem*)item0;
2105                         lua_newtable(L);
2106                         lua_pushstring(L, "CraftItem");
2107                         lua_setfield(L, -2, "type");
2108                         lua_pushstring(L, item->getSubName().c_str());
2109                         lua_setfield(L, -2, "name");
2110                 }
2111                 else if(std::string("ToolItem") == item0->getName()){
2112                         ToolItem *item = (ToolItem*)item0;
2113                         lua_newtable(L);
2114                         lua_pushstring(L, "ToolItem");
2115                         lua_setfield(L, -2, "type");
2116                         lua_pushstring(L, item->getToolName().c_str());
2117                         lua_setfield(L, -2, "name");
2118                         lua_pushstring(L, itos(item->getWear()).c_str());
2119                         lua_setfield(L, -2, "wear");
2120                 }
2121                 else{
2122                         errorstream<<"l_get_wielded_item: Unknown item name: \""
2123                                         <<item0->getName()<<"\""<<std::endl;
2124                         lua_pushnil(L);
2125                 }
2126                 return 1;
2127         }
2128
2129 public:
2130         ObjectRef(ServerActiveObject *object):
2131                 m_object(object)
2132         {
2133                 //infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
2134         }
2135
2136         ~ObjectRef()
2137         {
2138                 /*if(m_object)
2139                         infostream<<"ObjectRef destructing for id="
2140                                         <<m_object->getId()<<std::endl;
2141                 else
2142                         infostream<<"ObjectRef destructing for id=unknown"<<std::endl;*/
2143         }
2144
2145         // Creates an ObjectRef and leaves it on top of stack
2146         // Not callable from Lua; all references are created on the C side.
2147         static void create(lua_State *L, ServerActiveObject *object)
2148         {
2149                 ObjectRef *o = new ObjectRef(object);
2150                 //infostream<<"ObjectRef::create: o="<<o<<std::endl;
2151                 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
2152                 luaL_getmetatable(L, className);
2153                 lua_setmetatable(L, -2);
2154         }
2155
2156         static void set_null(lua_State *L)
2157         {
2158                 ObjectRef *o = checkobject(L, -1);
2159                 o->m_object = NULL;
2160         }
2161         
2162         static void Register(lua_State *L)
2163         {
2164                 lua_newtable(L);
2165                 int methodtable = lua_gettop(L);
2166                 luaL_newmetatable(L, className);
2167                 int metatable = lua_gettop(L);
2168
2169                 lua_pushliteral(L, "__metatable");
2170                 lua_pushvalue(L, methodtable);
2171                 lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
2172
2173                 lua_pushliteral(L, "__index");
2174                 lua_pushvalue(L, methodtable);
2175                 lua_settable(L, metatable);
2176
2177                 lua_pushliteral(L, "__gc");
2178                 lua_pushcfunction(L, gc_object);
2179                 lua_settable(L, metatable);
2180
2181                 lua_pop(L, 1);  // drop metatable
2182
2183                 luaL_openlib(L, 0, methods, 0);  // fill methodtable
2184                 lua_pop(L, 1);  // drop methodtable
2185
2186                 // Cannot be created from Lua
2187                 //lua_register(L, className, create_object);
2188         }
2189 };
2190 const char ObjectRef::className[] = "ObjectRef";
2191 const luaL_reg ObjectRef::methods[] = {
2192         // ServerActiveObject
2193         method(ObjectRef, remove),
2194         method(ObjectRef, getpos),
2195         method(ObjectRef, setpos),
2196         method(ObjectRef, moveto),
2197         method(ObjectRef, punch),
2198         method(ObjectRef, right_click),
2199         method(ObjectRef, get_wield_digging_properties),
2200         method(ObjectRef, damage_wielded_item),
2201         method(ObjectRef, add_to_inventory),
2202         method(ObjectRef, add_to_inventory_later),
2203         method(ObjectRef, set_hp),
2204         method(ObjectRef, get_hp),
2205         // LuaEntitySAO-only
2206         method(ObjectRef, setvelocity),
2207         method(ObjectRef, setacceleration),
2208         method(ObjectRef, getacceleration),
2209         method(ObjectRef, settexturemod),
2210         method(ObjectRef, setsprite),
2211         // Player-only
2212         method(ObjectRef, get_player_name),
2213         method(ObjectRef, inventory_set_list),
2214         method(ObjectRef, inventory_get_list),
2215         method(ObjectRef, get_wielded_itemstring),
2216         method(ObjectRef, get_wielded_item),
2217         {0,0}
2218 };
2219
2220 // Creates a new anonymous reference if id=0
2221 static void objectref_get_or_create(lua_State *L,
2222                 ServerActiveObject *cobj)
2223 {
2224         if(cobj->getId() == 0){
2225                 ObjectRef::create(L, cobj);
2226         } else {
2227                 objectref_get(L, cobj->getId());
2228         }
2229 }
2230
2231 /*
2232         EnvRef
2233 */
2234
2235 class EnvRef
2236 {
2237 private:
2238         ServerEnvironment *m_env;
2239
2240         static const char className[];
2241         static const luaL_reg methods[];
2242
2243         static EnvRef *checkobject(lua_State *L, int narg)
2244         {
2245                 luaL_checktype(L, narg, LUA_TUSERDATA);
2246                 void *ud = luaL_checkudata(L, narg, className);
2247                 if(!ud) luaL_typerror(L, narg, className);
2248                 return *(EnvRef**)ud;  // unbox pointer
2249         }
2250         
2251         // Exported functions
2252
2253         // EnvRef:add_node(pos, node)
2254         // pos = {x=num, y=num, z=num}
2255         static int l_add_node(lua_State *L)
2256         {
2257                 //infostream<<"EnvRef::l_add_node()"<<std::endl;
2258                 EnvRef *o = checkobject(L, 1);
2259                 ServerEnvironment *env = o->m_env;
2260                 if(env == NULL) return 0;
2261                 // pos
2262                 v3s16 pos = readpos(L, 2);
2263                 // content
2264                 MapNode n = readnode(L, 3, env->getGameDef()->ndef());
2265                 // Do it
2266                 bool succeeded = env->getMap().addNodeWithEvent(pos, n);
2267                 lua_pushboolean(L, succeeded);
2268                 return 1;
2269         }
2270
2271         // EnvRef:remove_node(pos)
2272         // pos = {x=num, y=num, z=num}
2273         static int l_remove_node(lua_State *L)
2274         {
2275                 //infostream<<"EnvRef::l_remove_node()"<<std::endl;
2276                 EnvRef *o = checkobject(L, 1);
2277                 ServerEnvironment *env = o->m_env;
2278                 if(env == NULL) return 0;
2279                 // pos
2280                 v3s16 pos = readpos(L, 2);
2281                 // Do it
2282                 bool succeeded = env->getMap().removeNodeWithEvent(pos);
2283                 lua_pushboolean(L, succeeded);
2284                 return 1;
2285         }
2286
2287         // EnvRef:get_node(pos)
2288         // pos = {x=num, y=num, z=num}
2289         static int l_get_node(lua_State *L)
2290         {
2291                 //infostream<<"EnvRef::l_get_node()"<<std::endl;
2292                 EnvRef *o = checkobject(L, 1);
2293                 ServerEnvironment *env = o->m_env;
2294                 if(env == NULL) return 0;
2295                 // pos
2296                 v3s16 pos = readpos(L, 2);
2297                 // Do it
2298                 MapNode n = env->getMap().getNodeNoEx(pos);
2299                 // Return node
2300                 pushnode(L, n, env->getGameDef()->ndef());
2301                 return 1;
2302         }
2303
2304         // EnvRef:add_luaentity(pos, entityname)
2305         // pos = {x=num, y=num, z=num}
2306         static int l_add_luaentity(lua_State *L)
2307         {
2308                 //infostream<<"EnvRef::l_add_luaentity()"<<std::endl;
2309                 EnvRef *o = checkobject(L, 1);
2310                 ServerEnvironment *env = o->m_env;
2311                 if(env == NULL) return 0;
2312                 // pos
2313                 v3f pos = readFloatPos(L, 2);
2314                 // content
2315                 const char *name = lua_tostring(L, 3);
2316                 // Do it
2317                 ServerActiveObject *obj = new LuaEntitySAO(env, pos, name, "");
2318                 env->addActiveObject(obj);
2319                 return 0;
2320         }
2321
2322         // EnvRef:add_item(pos, inventorystring)
2323         // pos = {x=num, y=num, z=num}
2324         static int l_add_item(lua_State *L)
2325         {
2326                 infostream<<"EnvRef::l_add_item()"<<std::endl;
2327                 EnvRef *o = checkobject(L, 1);
2328                 ServerEnvironment *env = o->m_env;
2329                 if(env == NULL) return 0;
2330                 // pos
2331                 v3f pos = readFloatPos(L, 2);
2332                 // inventorystring
2333                 const char *inventorystring = lua_tostring(L, 3);
2334                 // Do it
2335                 ServerActiveObject *obj = new ItemSAO(env, pos, inventorystring);
2336                 env->addActiveObject(obj);
2337                 return 0;
2338         }
2339
2340         // EnvRef:add_rat(pos)
2341         // pos = {x=num, y=num, z=num}
2342         static int l_add_rat(lua_State *L)
2343         {
2344                 infostream<<"EnvRef::l_add_rat()"<<std::endl;
2345                 EnvRef *o = checkobject(L, 1);
2346                 ServerEnvironment *env = o->m_env;
2347                 if(env == NULL) return 0;
2348                 // pos
2349                 v3f pos = readFloatPos(L, 2);
2350                 // Do it
2351                 ServerActiveObject *obj = new RatSAO(env, pos);
2352                 env->addActiveObject(obj);
2353                 return 0;
2354         }
2355
2356         // EnvRef:add_firefly(pos)
2357         // pos = {x=num, y=num, z=num}
2358         static int l_add_firefly(lua_State *L)
2359         {
2360                 infostream<<"EnvRef::l_add_firefly()"<<std::endl;
2361                 EnvRef *o = checkobject(L, 1);
2362                 ServerEnvironment *env = o->m_env;
2363                 if(env == NULL) return 0;
2364                 // pos
2365                 v3f pos = readFloatPos(L, 2);
2366                 // Do it
2367                 ServerActiveObject *obj = new FireflySAO(env, pos);
2368                 env->addActiveObject(obj);
2369                 return 0;
2370         }
2371
2372         // EnvRef:get_meta(pos)
2373         static int l_get_meta(lua_State *L)
2374         {
2375                 //infostream<<"EnvRef::l_get_meta()"<<std::endl;
2376                 EnvRef *o = checkobject(L, 1);
2377                 ServerEnvironment *env = o->m_env;
2378                 if(env == NULL) return 0;
2379                 // Do it
2380                 v3s16 p = readpos(L, 2);
2381                 NodeMetaRef::create(L, p, env);
2382                 return 1;
2383         }
2384
2385         // EnvRef:get_player_by_name(name)
2386         static int l_get_player_by_name(lua_State *L)
2387         {
2388                 EnvRef *o = checkobject(L, 1);
2389                 ServerEnvironment *env = o->m_env;
2390                 if(env == NULL) return 0;
2391                 // Do it
2392                 const char *name = lua_tostring(L, 2);
2393                 ServerRemotePlayer *player =
2394                                 static_cast<ServerRemotePlayer*>(env->getPlayer(name));
2395                 if(player == NULL){
2396                         lua_pushnil(L);
2397                         return 1;
2398                 }
2399                 // Put player on stack
2400                 objectref_get_or_create(L, player);
2401                 return 1;
2402         }
2403
2404         static int gc_object(lua_State *L) {
2405                 EnvRef *o = *(EnvRef **)(lua_touserdata(L, 1));
2406                 delete o;
2407                 return 0;
2408         }
2409
2410 public:
2411         EnvRef(ServerEnvironment *env):
2412                 m_env(env)
2413         {
2414                 infostream<<"EnvRef created"<<std::endl;
2415         }
2416
2417         ~EnvRef()
2418         {
2419                 infostream<<"EnvRef destructing"<<std::endl;
2420         }
2421
2422         // Creates an EnvRef and leaves it on top of stack
2423         // Not callable from Lua; all references are created on the C side.
2424         static void create(lua_State *L, ServerEnvironment *env)
2425         {
2426                 EnvRef *o = new EnvRef(env);
2427                 //infostream<<"EnvRef::create: o="<<o<<std::endl;
2428                 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
2429                 luaL_getmetatable(L, className);
2430                 lua_setmetatable(L, -2);
2431         }
2432
2433         static void set_null(lua_State *L)
2434         {
2435                 EnvRef *o = checkobject(L, -1);
2436                 o->m_env = NULL;
2437         }
2438         
2439         static void Register(lua_State *L)
2440         {
2441                 lua_newtable(L);
2442                 int methodtable = lua_gettop(L);
2443                 luaL_newmetatable(L, className);
2444                 int metatable = lua_gettop(L);
2445
2446                 lua_pushliteral(L, "__metatable");
2447                 lua_pushvalue(L, methodtable);
2448                 lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
2449
2450                 lua_pushliteral(L, "__index");
2451                 lua_pushvalue(L, methodtable);
2452                 lua_settable(L, metatable);
2453
2454                 lua_pushliteral(L, "__gc");
2455                 lua_pushcfunction(L, gc_object);
2456                 lua_settable(L, metatable);
2457
2458                 lua_pop(L, 1);  // drop metatable
2459
2460                 luaL_openlib(L, 0, methods, 0);  // fill methodtable
2461                 lua_pop(L, 1);  // drop methodtable
2462
2463                 // Cannot be created from Lua
2464                 //lua_register(L, className, create_object);
2465         }
2466 };
2467 const char EnvRef::className[] = "EnvRef";
2468 const luaL_reg EnvRef::methods[] = {
2469         method(EnvRef, add_node),
2470         method(EnvRef, remove_node),
2471         method(EnvRef, get_node),
2472         method(EnvRef, add_luaentity),
2473         method(EnvRef, add_item),
2474         method(EnvRef, add_rat),
2475         method(EnvRef, add_firefly),
2476         method(EnvRef, get_meta),
2477         method(EnvRef, get_player_by_name),
2478         {0,0}
2479 };
2480
2481 /*
2482         Main export function
2483 */
2484
2485 void scriptapi_export(lua_State *L, Server *server)
2486 {
2487         realitycheck(L);
2488         assert(lua_checkstack(L, 20));
2489         infostream<<"scriptapi_export"<<std::endl;
2490         StackUnroller stack_unroller(L);
2491
2492         // Store server as light userdata in registry
2493         lua_pushlightuserdata(L, server);
2494         lua_setfield(L, LUA_REGISTRYINDEX, "minetest_server");
2495
2496         // Store nil as minetest_nodedef_defaults in registry
2497         lua_pushnil(L);
2498         lua_setfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
2499         
2500         // Register global functions in table minetest
2501         lua_newtable(L);
2502         luaL_register(L, NULL, minetest_f);
2503         lua_setglobal(L, "minetest");
2504         
2505         // Get the main minetest table
2506         lua_getglobal(L, "minetest");
2507
2508         // Add tables to minetest
2509         
2510         lua_newtable(L);
2511         lua_setfield(L, -2, "registered_nodes");
2512         lua_newtable(L);
2513         lua_setfield(L, -2, "registered_entities");
2514         lua_newtable(L);
2515         lua_setfield(L, -2, "registered_craftitems");
2516         lua_newtable(L);
2517         lua_setfield(L, -2, "registered_abms");
2518         
2519         lua_newtable(L);
2520         lua_setfield(L, -2, "object_refs");
2521         lua_newtable(L);
2522         lua_setfield(L, -2, "luaentities");
2523
2524         // Create entity prototype
2525         luaL_newmetatable(L, "minetest.entity");
2526         // metatable.__index = metatable
2527         lua_pushvalue(L, -1); // Duplicate metatable
2528         lua_setfield(L, -2, "__index");
2529         // Put functions in metatable
2530         luaL_register(L, NULL, minetest_entity_m);
2531         // Put other stuff in metatable
2532         
2533         // Register reference wrappers
2534         NodeMetaRef::Register(L);
2535         EnvRef::Register(L);
2536         ObjectRef::Register(L);
2537 }
2538
2539 bool scriptapi_loadmod(lua_State *L, const std::string &scriptpath,
2540                 const std::string &modname)
2541 {
2542         ModNameStorer modnamestorer(L, modname);
2543
2544         bool success = false;
2545
2546         try{
2547                 success = script_load(L, scriptpath.c_str());
2548         }
2549         catch(LuaError &e){
2550                 errorstream<<"Error loading mod \""<<modname
2551                                 <<"\": "<<e.what()<<std::endl;
2552         }
2553
2554         return success;
2555 }
2556
2557 void scriptapi_add_environment(lua_State *L, ServerEnvironment *env)
2558 {
2559         realitycheck(L);
2560         assert(lua_checkstack(L, 20));
2561         infostream<<"scriptapi_add_environment"<<std::endl;
2562         StackUnroller stack_unroller(L);
2563
2564         // Create EnvRef on stack
2565         EnvRef::create(L, env);
2566         int envref = lua_gettop(L);
2567
2568         // minetest.env = envref
2569         lua_getglobal(L, "minetest");
2570         luaL_checktype(L, -1, LUA_TTABLE);
2571         lua_pushvalue(L, envref);
2572         lua_setfield(L, -2, "env");
2573
2574         // Store environment as light userdata in registry
2575         lua_pushlightuserdata(L, env);
2576         lua_setfield(L, LUA_REGISTRYINDEX, "minetest_env");
2577
2578         /* Add ActiveBlockModifiers to environment */
2579
2580         // Get minetest.registered_abms
2581         lua_getglobal(L, "minetest");
2582         lua_getfield(L, -1, "registered_abms");
2583         luaL_checktype(L, -1, LUA_TTABLE);
2584         int registered_abms = lua_gettop(L);
2585         
2586         if(lua_istable(L, registered_abms)){
2587                 int table = lua_gettop(L);
2588                 lua_pushnil(L);
2589                 while(lua_next(L, table) != 0){
2590                         // key at index -2 and value at index -1
2591                         int id = lua_tonumber(L, -2);
2592                         int current_abm = lua_gettop(L);
2593
2594                         std::set<std::string> trigger_contents;
2595                         lua_getfield(L, current_abm, "nodenames");
2596                         if(lua_istable(L, -1)){
2597                                 int table = lua_gettop(L);
2598                                 lua_pushnil(L);
2599                                 while(lua_next(L, table) != 0){
2600                                         // key at index -2 and value at index -1
2601                                         luaL_checktype(L, -1, LUA_TSTRING);
2602                                         trigger_contents.insert(lua_tostring(L, -1));
2603                                         // removes value, keeps key for next iteration
2604                                         lua_pop(L, 1);
2605                                 }
2606                         }
2607                         lua_pop(L, 1);
2608
2609                         float trigger_interval = 10.0;
2610                         getfloatfield(L, current_abm, "interval", trigger_interval);
2611
2612                         int trigger_chance = 50;
2613                         getintfield(L, current_abm, "chance", trigger_chance);
2614
2615                         LuaABM *abm = new LuaABM(L, id, trigger_contents,
2616                                         trigger_interval, trigger_chance);
2617                         
2618                         env->addActiveBlockModifier(abm);
2619
2620                         // removes value, keeps key for next iteration
2621                         lua_pop(L, 1);
2622                 }
2623         }
2624         lua_pop(L, 1);
2625 }
2626
2627 #if 0
2628 // Dump stack top with the dump2 function
2629 static void dump2(lua_State *L, const char *name)
2630 {
2631         // Dump object (debug)
2632         lua_getglobal(L, "dump2");
2633         luaL_checktype(L, -1, LUA_TFUNCTION);
2634         lua_pushvalue(L, -2); // Get previous stack top as first parameter
2635         lua_pushstring(L, name);
2636         if(lua_pcall(L, 2, 0, 0))
2637                 script_error(L, "error: %s", lua_tostring(L, -1));
2638 }
2639 #endif
2640
2641 /*
2642         object_reference
2643 */
2644
2645 void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj)
2646 {
2647         realitycheck(L);
2648         assert(lua_checkstack(L, 20));
2649         //infostream<<"scriptapi_add_object_reference: id="<<cobj->getId()<<std::endl;
2650         StackUnroller stack_unroller(L);
2651
2652         // Create object on stack
2653         ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack
2654         int object = lua_gettop(L);
2655
2656         // Get minetest.object_refs table
2657         lua_getglobal(L, "minetest");
2658         lua_getfield(L, -1, "object_refs");
2659         luaL_checktype(L, -1, LUA_TTABLE);
2660         int objectstable = lua_gettop(L);
2661         
2662         // object_refs[id] = object
2663         lua_pushnumber(L, cobj->getId()); // Push id
2664         lua_pushvalue(L, object); // Copy object to top of stack
2665         lua_settable(L, objectstable);
2666 }
2667
2668 void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj)
2669 {
2670         realitycheck(L);
2671         assert(lua_checkstack(L, 20));
2672         //infostream<<"scriptapi_rm_object_reference: id="<<cobj->getId()<<std::endl;
2673         StackUnroller stack_unroller(L);
2674
2675         // Get minetest.object_refs table
2676         lua_getglobal(L, "minetest");
2677         lua_getfield(L, -1, "object_refs");
2678         luaL_checktype(L, -1, LUA_TTABLE);
2679         int objectstable = lua_gettop(L);
2680         
2681         // Get object_refs[id]
2682         lua_pushnumber(L, cobj->getId()); // Push id
2683         lua_gettable(L, objectstable);
2684         // Set object reference to NULL
2685         ObjectRef::set_null(L);
2686         lua_pop(L, 1); // pop object
2687
2688         // Set object_refs[id] = nil
2689         lua_pushnumber(L, cobj->getId()); // Push id
2690         lua_pushnil(L);
2691         lua_settable(L, objectstable);
2692 }
2693
2694 bool scriptapi_on_chat_message(lua_State *L, const std::string &name,
2695                 const std::string &message)
2696 {
2697         realitycheck(L);
2698         assert(lua_checkstack(L, 20));
2699         StackUnroller stack_unroller(L);
2700
2701         // Get minetest.registered_on_chat_messages
2702         lua_getglobal(L, "minetest");
2703         lua_getfield(L, -1, "registered_on_chat_messages");
2704         luaL_checktype(L, -1, LUA_TTABLE);
2705         int table = lua_gettop(L);
2706         // Foreach
2707         lua_pushnil(L);
2708         while(lua_next(L, table) != 0){
2709                 // key at index -2 and value at index -1
2710                 luaL_checktype(L, -1, LUA_TFUNCTION);
2711                 // Call function
2712                 lua_pushstring(L, name.c_str());
2713                 lua_pushstring(L, message.c_str());
2714                 if(lua_pcall(L, 2, 1, 0))
2715                         script_error(L, "error: %s", lua_tostring(L, -1));
2716                 bool ate = lua_toboolean(L, -1);
2717                 lua_pop(L, 1);
2718                 if(ate)
2719                         return true;
2720                 // value removed, keep key for next iteration
2721         }
2722         return false;
2723 }
2724
2725 /*
2726         misc
2727 */
2728
2729 void scriptapi_on_newplayer(lua_State *L, ServerActiveObject *player)
2730 {
2731         realitycheck(L);
2732         assert(lua_checkstack(L, 20));
2733         StackUnroller stack_unroller(L);
2734
2735         // Get minetest.registered_on_newplayers
2736         lua_getglobal(L, "minetest");
2737         lua_getfield(L, -1, "registered_on_newplayers");
2738         luaL_checktype(L, -1, LUA_TTABLE);
2739         int table = lua_gettop(L);
2740         // Foreach
2741         lua_pushnil(L);
2742         while(lua_next(L, table) != 0){
2743                 // key at index -2 and value at index -1
2744                 luaL_checktype(L, -1, LUA_TFUNCTION);
2745                 // Call function
2746                 objectref_get_or_create(L, player);
2747                 if(lua_pcall(L, 1, 0, 0))
2748                         script_error(L, "error: %s", lua_tostring(L, -1));
2749                 // value removed, keep key for next iteration
2750         }
2751 }
2752 bool scriptapi_on_respawnplayer(lua_State *L, ServerActiveObject *player)
2753 {
2754         realitycheck(L);
2755         assert(lua_checkstack(L, 20));
2756         StackUnroller stack_unroller(L);
2757
2758         bool positioning_handled_by_some = false;
2759
2760         // Get minetest.registered_on_respawnplayers
2761         lua_getglobal(L, "minetest");
2762         lua_getfield(L, -1, "registered_on_respawnplayers");
2763         luaL_checktype(L, -1, LUA_TTABLE);
2764         int table = lua_gettop(L);
2765         // Foreach
2766         lua_pushnil(L);
2767         while(lua_next(L, table) != 0){
2768                 // key at index -2 and value at index -1
2769                 luaL_checktype(L, -1, LUA_TFUNCTION);
2770                 // Call function
2771                 objectref_get_or_create(L, player);
2772                 if(lua_pcall(L, 1, 1, 0))
2773                         script_error(L, "error: %s", lua_tostring(L, -1));
2774                 bool positioning_handled = lua_toboolean(L, -1);
2775                 lua_pop(L, 1);
2776                 if(positioning_handled)
2777                         positioning_handled_by_some = true;
2778                 // value removed, keep key for next iteration
2779         }
2780         return positioning_handled_by_some;
2781 }
2782
2783 void scriptapi_get_creative_inventory(lua_State *L, ServerRemotePlayer *player)
2784 {
2785         lua_getglobal(L, "minetest");
2786         lua_getfield(L, -1, "creative_inventory");
2787         luaL_checktype(L, -1, LUA_TTABLE);
2788         inventory_set_list_from_lua(&player->inventory, "main", L, -1,
2789                         player->getEnv()->getGameDef(), PLAYER_INVENTORY_SIZE);
2790 }
2791
2792 /*
2793         craftitem
2794 */
2795
2796 static void pushPointedThing(lua_State *L, const PointedThing& pointed)
2797 {
2798         lua_newtable(L);
2799         if(pointed.type == POINTEDTHING_NODE)
2800         {
2801                 lua_pushstring(L, "node");
2802                 lua_setfield(L, -2, "type");
2803                 pushpos(L, pointed.node_undersurface);
2804                 lua_setfield(L, -2, "under");
2805                 pushpos(L, pointed.node_abovesurface);
2806                 lua_setfield(L, -2, "above");
2807         }
2808         else if(pointed.type == POINTEDTHING_OBJECT)
2809         {
2810                 lua_pushstring(L, "object");
2811                 lua_setfield(L, -2, "type");
2812                 objectref_get(L, pointed.object_id);
2813                 lua_setfield(L, -2, "ref");
2814         }
2815         else
2816         {
2817                 lua_pushstring(L, "nothing");
2818                 lua_setfield(L, -2, "type");
2819         }
2820 }
2821
2822 void scriptapi_add_craftitem(lua_State *L, const char *name)
2823 {
2824         StackUnroller stack_unroller(L);
2825         assert(lua_gettop(L) > 0);
2826
2827         // Set minetest.registered_craftitems[name] = table on top of stack
2828         lua_getglobal(L, "minetest");
2829         lua_getfield(L, -1, "registered_craftitems");
2830         luaL_checktype(L, -1, LUA_TTABLE);
2831         lua_pushvalue(L, -3); // push another reference to the table to be registered
2832         lua_setfield(L, -2, name); // set minetest.registered_craftitems[name]
2833 }
2834
2835 static bool get_craftitem_callback(lua_State *L, const char *name,
2836                 const char *callbackname)
2837 {
2838         // Get minetest.registered_craftitems[name][callbackname]
2839         // If that is nil or on error, return false and stack is unchanged
2840         // If that is a function, returns true and pushes the
2841         // function onto the stack
2842
2843         lua_getglobal(L, "minetest");
2844         lua_getfield(L, -1, "registered_craftitems");
2845         lua_remove(L, -2);
2846         luaL_checktype(L, -1, LUA_TTABLE);
2847         lua_getfield(L, -1, name);
2848         lua_remove(L, -2);
2849         // Should be a table
2850         if(lua_type(L, -1) != LUA_TTABLE)
2851         {
2852                 errorstream<<"CraftItem name \""<<name<<"\" not defined"<<std::endl;
2853                 lua_pop(L, 1);
2854                 return false;
2855         }
2856         lua_getfield(L, -1, callbackname);
2857         lua_remove(L, -2);
2858         // Should be a function or nil
2859         if(lua_type(L, -1) == LUA_TFUNCTION)
2860         {
2861                 return true;
2862         }
2863         else if(lua_isnil(L, -1))
2864         {
2865                 lua_pop(L, 1);
2866                 return false;
2867         }
2868         else
2869         {
2870                 errorstream<<"CraftItem name \""<<name<<"\" callback \""
2871                         <<callbackname<<" is not a function"<<std::endl;
2872                 lua_pop(L, 1);
2873                 return false;
2874         }
2875 }
2876
2877 bool scriptapi_craftitem_on_drop(lua_State *L, const char *name,
2878                 ServerActiveObject *dropper, v3f pos,
2879                 bool &callback_exists)
2880 {
2881         realitycheck(L);
2882         assert(lua_checkstack(L, 20));
2883         //infostream<<"scriptapi_craftitem_on_drop"<<std::endl;
2884         StackUnroller stack_unroller(L);
2885
2886         bool result = false;
2887         callback_exists = get_craftitem_callback(L, name, "on_drop");
2888         if(callback_exists)
2889         {
2890                 // Call function
2891                 lua_pushstring(L, name);
2892                 objectref_get_or_create(L, dropper);
2893                 pushFloatPos(L, pos);
2894                 if(lua_pcall(L, 3, 1, 0))
2895                         script_error(L, "error: %s", lua_tostring(L, -1));
2896                 result = lua_toboolean(L, -1);
2897         }
2898         return result;
2899 }
2900
2901 bool scriptapi_craftitem_on_place_on_ground(lua_State *L, const char *name,
2902                 ServerActiveObject *placer, v3f pos,
2903                 bool &callback_exists)
2904 {
2905         realitycheck(L);
2906         assert(lua_checkstack(L, 20));
2907         //infostream<<"scriptapi_craftitem_on_place_on_ground"<<std::endl;
2908         StackUnroller stack_unroller(L);
2909
2910         bool result = false;
2911         callback_exists = get_craftitem_callback(L, name, "on_place_on_ground");
2912         if(callback_exists)
2913         {
2914                 // Call function
2915                 lua_pushstring(L, name);
2916                 objectref_get_or_create(L, placer);
2917                 pushFloatPos(L, pos);
2918                 if(lua_pcall(L, 3, 1, 0))
2919                         script_error(L, "error: %s", lua_tostring(L, -1));
2920                 result = lua_toboolean(L, -1);
2921         }
2922         return result;
2923 }
2924
2925 bool scriptapi_craftitem_on_use(lua_State *L, const char *name,
2926                 ServerActiveObject *user, const PointedThing& pointed,
2927                 bool &callback_exists)
2928 {
2929         realitycheck(L);
2930         assert(lua_checkstack(L, 20));
2931         //infostream<<"scriptapi_craftitem_on_use"<<std::endl;
2932         StackUnroller stack_unroller(L);
2933
2934         bool result = false;
2935         callback_exists = get_craftitem_callback(L, name, "on_use");
2936         if(callback_exists)
2937         {
2938                 // Call function
2939                 lua_pushstring(L, name);
2940                 objectref_get_or_create(L, user);
2941                 pushPointedThing(L, pointed);
2942                 if(lua_pcall(L, 3, 1, 0))
2943                         script_error(L, "error: %s", lua_tostring(L, -1));
2944                 result = lua_toboolean(L, -1);
2945         }
2946         return result;
2947 }
2948
2949 /*
2950         environment
2951 */
2952
2953 void scriptapi_environment_step(lua_State *L, float dtime)
2954 {
2955         realitycheck(L);
2956         assert(lua_checkstack(L, 20));
2957         //infostream<<"scriptapi_environment_step"<<std::endl;
2958         StackUnroller stack_unroller(L);
2959
2960         // Get minetest.registered_globalsteps
2961         lua_getglobal(L, "minetest");
2962         lua_getfield(L, -1, "registered_globalsteps");
2963         luaL_checktype(L, -1, LUA_TTABLE);
2964         int table = lua_gettop(L);
2965         // Foreach
2966         lua_pushnil(L);
2967         while(lua_next(L, table) != 0){
2968                 // key at index -2 and value at index -1
2969                 luaL_checktype(L, -1, LUA_TFUNCTION);
2970                 // Call function
2971                 lua_pushnumber(L, dtime);
2972                 if(lua_pcall(L, 1, 0, 0))
2973                         script_error(L, "error: %s", lua_tostring(L, -1));
2974                 // value removed, keep key for next iteration
2975         }
2976 }
2977
2978 void scriptapi_environment_on_placenode(lua_State *L, v3s16 p, MapNode newnode,
2979                 ServerActiveObject *placer)
2980 {
2981         realitycheck(L);
2982         assert(lua_checkstack(L, 20));
2983         //infostream<<"scriptapi_environment_on_placenode"<<std::endl;
2984         StackUnroller stack_unroller(L);
2985
2986         // Get server from registry
2987         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
2988         Server *server = (Server*)lua_touserdata(L, -1);
2989         // And get the writable node definition manager from the server
2990         IWritableNodeDefManager *ndef =
2991                         server->getWritableNodeDefManager();
2992         
2993         // Get minetest.registered_on_placenodes
2994         lua_getglobal(L, "minetest");
2995         lua_getfield(L, -1, "registered_on_placenodes");
2996         luaL_checktype(L, -1, LUA_TTABLE);
2997         int table = lua_gettop(L);
2998         // Foreach
2999         lua_pushnil(L);
3000         while(lua_next(L, table) != 0){
3001                 // key at index -2 and value at index -1
3002                 luaL_checktype(L, -1, LUA_TFUNCTION);
3003                 // Call function
3004                 pushpos(L, p);
3005                 pushnode(L, newnode, ndef);
3006                 objectref_get_or_create(L, placer);
3007                 if(lua_pcall(L, 3, 0, 0))
3008                         script_error(L, "error: %s", lua_tostring(L, -1));
3009                 // value removed, keep key for next iteration
3010         }
3011 }
3012
3013 void scriptapi_environment_on_dignode(lua_State *L, v3s16 p, MapNode oldnode,
3014                 ServerActiveObject *digger)
3015 {
3016         realitycheck(L);
3017         assert(lua_checkstack(L, 20));
3018         //infostream<<"scriptapi_environment_on_dignode"<<std::endl;
3019         StackUnroller stack_unroller(L);
3020
3021         // Get server from registry
3022         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
3023         Server *server = (Server*)lua_touserdata(L, -1);
3024         // And get the writable node definition manager from the server
3025         IWritableNodeDefManager *ndef =
3026                         server->getWritableNodeDefManager();
3027         
3028         // Get minetest.registered_on_dignodes
3029         lua_getglobal(L, "minetest");
3030         lua_getfield(L, -1, "registered_on_dignodes");
3031         luaL_checktype(L, -1, LUA_TTABLE);
3032         int table = lua_gettop(L);
3033         // Foreach
3034         lua_pushnil(L);
3035         while(lua_next(L, table) != 0){
3036                 // key at index -2 and value at index -1
3037                 luaL_checktype(L, -1, LUA_TFUNCTION);
3038                 // Call function
3039                 pushpos(L, p);
3040                 pushnode(L, oldnode, ndef);
3041                 objectref_get_or_create(L, digger);
3042                 if(lua_pcall(L, 3, 0, 0))
3043                         script_error(L, "error: %s", lua_tostring(L, -1));
3044                 // value removed, keep key for next iteration
3045         }
3046 }
3047
3048 void scriptapi_environment_on_punchnode(lua_State *L, v3s16 p, MapNode node,
3049                 ServerActiveObject *puncher)
3050 {
3051         realitycheck(L);
3052         assert(lua_checkstack(L, 20));
3053         //infostream<<"scriptapi_environment_on_punchnode"<<std::endl;
3054         StackUnroller stack_unroller(L);
3055
3056         // Get server from registry
3057         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
3058         Server *server = (Server*)lua_touserdata(L, -1);
3059         // And get the writable node definition manager from the server
3060         IWritableNodeDefManager *ndef =
3061                         server->getWritableNodeDefManager();
3062         
3063         // Get minetest.registered_on_punchnodes
3064         lua_getglobal(L, "minetest");
3065         lua_getfield(L, -1, "registered_on_punchnodes");
3066         luaL_checktype(L, -1, LUA_TTABLE);
3067         int table = lua_gettop(L);
3068         // Foreach
3069         lua_pushnil(L);
3070         while(lua_next(L, table) != 0){
3071                 // key at index -2 and value at index -1
3072                 luaL_checktype(L, -1, LUA_TFUNCTION);
3073                 // Call function
3074                 pushpos(L, p);
3075                 pushnode(L, node, ndef);
3076                 objectref_get_or_create(L, puncher);
3077                 if(lua_pcall(L, 3, 0, 0))
3078                         script_error(L, "error: %s", lua_tostring(L, -1));
3079                 // value removed, keep key for next iteration
3080         }
3081 }
3082
3083 void scriptapi_environment_on_generated(lua_State *L, v3s16 minp, v3s16 maxp)
3084 {
3085         realitycheck(L);
3086         assert(lua_checkstack(L, 20));
3087         //infostream<<"scriptapi_environment_on_generated"<<std::endl;
3088         StackUnroller stack_unroller(L);
3089
3090         // Get minetest.registered_on_generateds
3091         lua_getglobal(L, "minetest");
3092         lua_getfield(L, -1, "registered_on_generateds");
3093         luaL_checktype(L, -1, LUA_TTABLE);
3094         int table = lua_gettop(L);
3095         // Foreach
3096         lua_pushnil(L);
3097         while(lua_next(L, table) != 0){
3098                 // key at index -2 and value at index -1
3099                 luaL_checktype(L, -1, LUA_TFUNCTION);
3100                 // Call function
3101                 pushpos(L, minp);
3102                 pushpos(L, maxp);
3103                 if(lua_pcall(L, 2, 0, 0))
3104                         script_error(L, "error: %s", lua_tostring(L, -1));
3105                 // value removed, keep key for next iteration
3106         }
3107 }
3108
3109 /*
3110         luaentity
3111 */
3112
3113 bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
3114                 const std::string &staticdata)
3115 {
3116         realitycheck(L);
3117         assert(lua_checkstack(L, 20));
3118         infostream<<"scriptapi_luaentity_add: id="<<id<<" name=\""
3119                         <<name<<"\""<<std::endl;
3120         StackUnroller stack_unroller(L);
3121         
3122         // Get minetest.registered_entities[name]
3123         lua_getglobal(L, "minetest");
3124         lua_getfield(L, -1, "registered_entities");
3125         luaL_checktype(L, -1, LUA_TTABLE);
3126         lua_pushstring(L, name);
3127         lua_gettable(L, -2);
3128         // Should be a table, which we will use as a prototype
3129         //luaL_checktype(L, -1, LUA_TTABLE);
3130         if(lua_type(L, -1) != LUA_TTABLE){
3131                 errorstream<<"LuaEntity name \""<<name<<"\" not defined"<<std::endl;
3132                 return false;
3133         }
3134         int prototype_table = lua_gettop(L);
3135         //dump2(L, "prototype_table");
3136         
3137         // Create entity object
3138         lua_newtable(L);
3139         int object = lua_gettop(L);
3140
3141         // Set object metatable
3142         lua_pushvalue(L, prototype_table);
3143         lua_setmetatable(L, -2);
3144         
3145         // Add object reference
3146         // This should be userdata with metatable ObjectRef
3147         objectref_get(L, id);
3148         luaL_checktype(L, -1, LUA_TUSERDATA);
3149         if(!luaL_checkudata(L, -1, "ObjectRef"))
3150                 luaL_typerror(L, -1, "ObjectRef");
3151         lua_setfield(L, -2, "object");
3152
3153         // minetest.luaentities[id] = object
3154         lua_getglobal(L, "minetest");
3155         lua_getfield(L, -1, "luaentities");
3156         luaL_checktype(L, -1, LUA_TTABLE);
3157         lua_pushnumber(L, id); // Push id
3158         lua_pushvalue(L, object); // Copy object to top of stack
3159         lua_settable(L, -3);
3160         
3161         // Get on_activate function
3162         lua_pushvalue(L, object);
3163         lua_getfield(L, -1, "on_activate");
3164         if(!lua_isnil(L, -1)){
3165                 luaL_checktype(L, -1, LUA_TFUNCTION);
3166                 lua_pushvalue(L, object); // self
3167                 lua_pushlstring(L, staticdata.c_str(), staticdata.size());
3168                 // Call with 2 arguments, 0 results
3169                 if(lua_pcall(L, 2, 0, 0))
3170                         script_error(L, "error running function %s:on_activate: %s\n",
3171                                         name, lua_tostring(L, -1));
3172         }
3173         
3174         return true;
3175 }
3176
3177 void scriptapi_luaentity_rm(lua_State *L, u16 id)
3178 {
3179         realitycheck(L);
3180         assert(lua_checkstack(L, 20));
3181         infostream<<"scriptapi_luaentity_rm: id="<<id<<std::endl;
3182
3183         // Get minetest.luaentities table
3184         lua_getglobal(L, "minetest");
3185         lua_getfield(L, -1, "luaentities");
3186         luaL_checktype(L, -1, LUA_TTABLE);
3187         int objectstable = lua_gettop(L);
3188         
3189         // Set luaentities[id] = nil
3190         lua_pushnumber(L, id); // Push id
3191         lua_pushnil(L);
3192         lua_settable(L, objectstable);
3193         
3194         lua_pop(L, 2); // pop luaentities, minetest
3195 }
3196
3197 std::string scriptapi_luaentity_get_staticdata(lua_State *L, u16 id)
3198 {
3199         realitycheck(L);
3200         assert(lua_checkstack(L, 20));
3201         infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl;
3202         StackUnroller stack_unroller(L);
3203
3204         // Get minetest.luaentities[id]
3205         luaentity_get(L, id);
3206         int object = lua_gettop(L);
3207         
3208         // Get get_staticdata function
3209         lua_pushvalue(L, object);
3210         lua_getfield(L, -1, "get_staticdata");
3211         if(lua_isnil(L, -1))
3212                 return "";
3213         
3214         luaL_checktype(L, -1, LUA_TFUNCTION);
3215         lua_pushvalue(L, object); // self
3216         // Call with 1 arguments, 1 results
3217         if(lua_pcall(L, 1, 1, 0))
3218                 script_error(L, "error running function get_staticdata: %s\n",
3219                                 lua_tostring(L, -1));
3220         
3221         size_t len=0;
3222         const char *s = lua_tolstring(L, -1, &len);
3223         return std::string(s, len);
3224 }
3225
3226 void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
3227                 LuaEntityProperties *prop)
3228 {
3229         realitycheck(L);
3230         assert(lua_checkstack(L, 20));
3231         infostream<<"scriptapi_luaentity_get_properties: id="<<id<<std::endl;
3232         StackUnroller stack_unroller(L);
3233
3234         // Get minetest.luaentities[id]
3235         luaentity_get(L, id);
3236         //int object = lua_gettop(L);
3237
3238         /* Read stuff */
3239         
3240         getboolfield(L, -1, "physical", prop->physical);
3241
3242         getfloatfield(L, -1, "weight", prop->weight);
3243
3244         lua_getfield(L, -1, "collisionbox");
3245         if(lua_istable(L, -1))
3246                 prop->collisionbox = read_aabbox3df32(L, -1, 1.0);
3247         lua_pop(L, 1);
3248
3249         getstringfield(L, -1, "visual", prop->visual);
3250         
3251         lua_getfield(L, -1, "visual_size");
3252         if(lua_istable(L, -1))
3253                 prop->visual_size = read_v2f(L, -1);
3254         lua_pop(L, 1);
3255
3256         lua_getfield(L, -1, "textures");
3257         if(lua_istable(L, -1)){
3258                 prop->textures.clear();
3259                 int table = lua_gettop(L);
3260                 lua_pushnil(L);
3261                 while(lua_next(L, table) != 0){
3262                         // key at index -2 and value at index -1
3263                         if(lua_isstring(L, -1))
3264                                 prop->textures.push_back(lua_tostring(L, -1));
3265                         else
3266                                 prop->textures.push_back("");
3267                         // removes value, keeps key for next iteration
3268                         lua_pop(L, 1);
3269                 }
3270         }
3271         lua_pop(L, 1);
3272         
3273         lua_getfield(L, -1, "spritediv");
3274         if(lua_istable(L, -1))
3275                 prop->spritediv = read_v2s16(L, -1);
3276         lua_pop(L, 1);
3277
3278         lua_getfield(L, -1, "initial_sprite_basepos");
3279         if(lua_istable(L, -1))
3280                 prop->initial_sprite_basepos = read_v2s16(L, -1);
3281         lua_pop(L, 1);
3282 }
3283
3284 void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime)
3285 {
3286         realitycheck(L);
3287         assert(lua_checkstack(L, 20));
3288         //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
3289         StackUnroller stack_unroller(L);
3290
3291         // Get minetest.luaentities[id]
3292         luaentity_get(L, id);
3293         int object = lua_gettop(L);
3294         // State: object is at top of stack
3295         // Get step function
3296         lua_getfield(L, -1, "on_step");
3297         if(lua_isnil(L, -1))
3298                 return;
3299         luaL_checktype(L, -1, LUA_TFUNCTION);
3300         lua_pushvalue(L, object); // self
3301         lua_pushnumber(L, dtime); // dtime
3302         // Call with 2 arguments, 0 results
3303         if(lua_pcall(L, 2, 0, 0))
3304                 script_error(L, "error running function 'on_step': %s\n", lua_tostring(L, -1));
3305 }
3306
3307 // Calls entity:on_punch(ObjectRef puncher, time_from_last_punch)
3308 void scriptapi_luaentity_punch(lua_State *L, u16 id,
3309                 ServerActiveObject *puncher, float time_from_last_punch)
3310 {
3311         realitycheck(L);
3312         assert(lua_checkstack(L, 20));
3313         //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
3314         StackUnroller stack_unroller(L);
3315
3316         // Get minetest.luaentities[id]
3317         luaentity_get(L, id);
3318         int object = lua_gettop(L);
3319         // State: object is at top of stack
3320         // Get function
3321         lua_getfield(L, -1, "on_punch");
3322         if(lua_isnil(L, -1))
3323                 return;
3324         luaL_checktype(L, -1, LUA_TFUNCTION);
3325         lua_pushvalue(L, object); // self
3326         objectref_get_or_create(L, puncher); // Clicker reference
3327         lua_pushnumber(L, time_from_last_punch);
3328         // Call with 2 arguments, 0 results
3329         if(lua_pcall(L, 3, 0, 0))
3330                 script_error(L, "error running function 'on_punch': %s\n", lua_tostring(L, -1));
3331 }
3332
3333 // Calls entity:on_rightclick(ObjectRef clicker)
3334 void scriptapi_luaentity_rightclick(lua_State *L, u16 id,
3335                 ServerActiveObject *clicker)
3336 {
3337         realitycheck(L);
3338         assert(lua_checkstack(L, 20));
3339         //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
3340         StackUnroller stack_unroller(L);
3341
3342         // Get minetest.luaentities[id]
3343         luaentity_get(L, id);
3344         int object = lua_gettop(L);
3345         // State: object is at top of stack
3346         // Get function
3347         lua_getfield(L, -1, "on_rightclick");
3348         if(lua_isnil(L, -1))
3349                 return;
3350         luaL_checktype(L, -1, LUA_TFUNCTION);
3351         lua_pushvalue(L, object); // self
3352         objectref_get_or_create(L, clicker); // Clicker reference
3353         // Call with 2 arguments, 0 results
3354         if(lua_pcall(L, 2, 0, 0))
3355                 script_error(L, "error running function 'on_rightclick': %s\n", lua_tostring(L, -1));
3356 }
3357