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