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