dbbaf3dc9493477a49d427621d8547abaf6f36ba
[oweals/minetest.git] / src / scriptapi.cpp
1 /*
2 Minetest-c55
3 Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include "scriptapi.h"
21
22 #include <iostream>
23 #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         // getvelocity(self)
1932         static int l_getvelocity(lua_State *L)
1933         {
1934                 ObjectRef *ref = checkobject(L, 1);
1935                 LuaEntitySAO *co = getluaobject(ref);
1936                 if(co == NULL) return 0;
1937                 // Do it
1938                 v3f v = co->getVelocity();
1939                 pushFloatPos(L, v);
1940                 return 1;
1941         }
1942         
1943         // setacceleration(self, {x=num, y=num, z=num})
1944         static int l_setacceleration(lua_State *L)
1945         {
1946                 ObjectRef *ref = checkobject(L, 1);
1947                 LuaEntitySAO *co = getluaobject(ref);
1948                 if(co == NULL) return 0;
1949                 // pos
1950                 v3f pos = checkFloatPos(L, 2);
1951                 // Do it
1952                 co->setAcceleration(pos);
1953                 return 0;
1954         }
1955         
1956         // getacceleration(self)
1957         static int l_getacceleration(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                 v3f v = co->getAcceleration();
1964                 pushFloatPos(L, v);
1965                 return 1;
1966         }
1967         
1968         // setyaw(self, radians)
1969         static int l_setyaw(lua_State *L)
1970         {
1971                 ObjectRef *ref = checkobject(L, 1);
1972                 LuaEntitySAO *co = getluaobject(ref);
1973                 if(co == NULL) return 0;
1974                 // pos
1975                 float yaw = luaL_checknumber(L, 2) * core::RADTODEG;
1976                 // Do it
1977                 co->setYaw(yaw);
1978                 return 0;
1979         }
1980         
1981         // getyaw(self)
1982         static int l_getyaw(lua_State *L)
1983         {
1984                 ObjectRef *ref = checkobject(L, 1);
1985                 LuaEntitySAO *co = getluaobject(ref);
1986                 if(co == NULL) return 0;
1987                 // Do it
1988                 float yaw = co->getYaw() * core::DEGTORAD;
1989                 lua_pushnumber(L, yaw);
1990                 return 1;
1991         }
1992         
1993         // settexturemod(self, mod)
1994         static int l_settexturemod(lua_State *L)
1995         {
1996                 ObjectRef *ref = checkobject(L, 1);
1997                 LuaEntitySAO *co = getluaobject(ref);
1998                 if(co == NULL) return 0;
1999                 // Do it
2000                 std::string mod = luaL_checkstring(L, 2);
2001                 co->setTextureMod(mod);
2002                 return 0;
2003         }
2004         
2005         // setsprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2,
2006         //           select_horiz_by_yawpitch=false)
2007         static int l_setsprite(lua_State *L)
2008         {
2009                 ObjectRef *ref = checkobject(L, 1);
2010                 LuaEntitySAO *co = getluaobject(ref);
2011                 if(co == NULL) return 0;
2012                 // Do it
2013                 v2s16 p(0,0);
2014                 if(!lua_isnil(L, 2))
2015                         p = read_v2s16(L, 2);
2016                 int num_frames = 1;
2017                 if(!lua_isnil(L, 3))
2018                         num_frames = lua_tonumber(L, 3);
2019                 float framelength = 0.2;
2020                 if(!lua_isnil(L, 4))
2021                         framelength = lua_tonumber(L, 4);
2022                 bool select_horiz_by_yawpitch = false;
2023                 if(!lua_isnil(L, 5))
2024                         select_horiz_by_yawpitch = lua_toboolean(L, 5);
2025                 co->setSprite(p, num_frames, framelength, select_horiz_by_yawpitch);
2026                 return 0;
2027         }
2028
2029         // get_entity_name(self)
2030         static int l_get_entity_name(lua_State *L)
2031         {
2032                 ObjectRef *ref = checkobject(L, 1);
2033                 LuaEntitySAO *co = getluaobject(ref);
2034                 if(co == NULL) return 0;
2035                 // Do it
2036                 std::string name = co->getName();
2037                 lua_pushstring(L, name.c_str());
2038                 return 1;
2039         }
2040         
2041         // get_luaentity(self)
2042         static int l_get_luaentity(lua_State *L)
2043         {
2044                 ObjectRef *ref = checkobject(L, 1);
2045                 LuaEntitySAO *co = getluaobject(ref);
2046                 if(co == NULL) return 0;
2047                 // Do it
2048                 luaentity_get(L, co->getId());
2049                 return 1;
2050         }
2051         
2052         /* Player-only */
2053         
2054         // get_player_name(self)
2055         static int l_get_player_name(lua_State *L)
2056         {
2057                 ObjectRef *ref = checkobject(L, 1);
2058                 ServerRemotePlayer *player = getplayer(ref);
2059                 if(player == NULL){
2060                         lua_pushnil(L);
2061                         return 1;
2062                 }
2063                 // Do it
2064                 lua_pushstring(L, player->getName());
2065                 return 1;
2066         }
2067         
2068         // get_inventory(self)
2069         static int l_get_inventory(lua_State *L)
2070         {
2071                 ObjectRef *ref = checkobject(L, 1);
2072                 ServerRemotePlayer *player = getplayer(ref);
2073                 if(player == NULL) return 0;
2074                 // Do it
2075                 InvRef::createPlayer(L, player);
2076                 return 1;
2077         }
2078
2079         // deprecated: inventory_set_list(self, name, {item1, item2, ...})
2080         static int l_inventory_set_list(lua_State *L)
2081         {
2082                 infostream<<"Deprecated: inventory_set_list"<<std::endl;
2083                 ObjectRef *ref = checkobject(L, 1);
2084                 ServerRemotePlayer *player = getplayer(ref);
2085                 if(player == NULL) return 0;
2086                 const char *name = luaL_checkstring(L, 2);
2087                 // Do it
2088                 inventory_set_list_from_lua(&player->inventory, name, L, 3,
2089                                 player->getEnv()->getGameDef(), PLAYER_INVENTORY_SIZE);
2090                 player->m_inventory_not_sent = true;
2091                 return 0;
2092         }
2093
2094         // deprecated: inventory_get_list(self, name)
2095         static int l_inventory_get_list(lua_State *L)
2096         {
2097                 infostream<<"Deprecated: inventory_get_list"<<std::endl;
2098                 ObjectRef *ref = checkobject(L, 1);
2099                 ServerRemotePlayer *player = getplayer(ref);
2100                 if(player == NULL) return 0;
2101                 const char *name = luaL_checkstring(L, 2);
2102                 // Do it
2103                 inventory_get_list_to_lua(&player->inventory, name, L);
2104                 return 1;
2105         }
2106
2107         // get_wielded_itemstring(self)
2108         static int l_get_wielded_itemstring(lua_State *L)
2109         {
2110                 ObjectRef *ref = checkobject(L, 1);
2111                 ServerRemotePlayer *player = getplayer(ref);
2112                 if(player == NULL) return 0;
2113                 // Do it
2114                 InventoryItem *item = player->getWieldedItem();
2115                 if(item == NULL){
2116                         lua_pushnil(L);
2117                         return 1;
2118                 }
2119                 lua_pushstring(L, item->getItemString().c_str());
2120                 return 1;
2121         }
2122
2123         // get_wielded_item(self)
2124         static int l_get_wielded_item(lua_State *L)
2125         {
2126                 ObjectRef *ref = checkobject(L, 1);
2127                 ServerRemotePlayer *player = getplayer(ref);
2128                 if(player == NULL) return 0;
2129                 // Do it
2130                 InventoryItem *item0 = player->getWieldedItem();
2131                 push_stack_item(L, item0);
2132                 return 1;
2133         }
2134
2135         // get_look_dir(self)
2136         static int l_get_look_dir(lua_State *L)
2137         {
2138                 ObjectRef *ref = checkobject(L, 1);
2139                 ServerRemotePlayer *player = getplayer(ref);
2140                 if(player == NULL) return 0;
2141                 // Do it
2142                 float pitch = player->getRadPitch();
2143                 float yaw = player->getRadYaw();
2144                 v3f v(cos(pitch)*cos(yaw), sin(pitch), cos(pitch)*sin(yaw));
2145                 push_v3f(L, v);
2146                 return 1;
2147         }
2148
2149         // get_look_pitch(self)
2150         static int l_get_look_pitch(lua_State *L)
2151         {
2152                 ObjectRef *ref = checkobject(L, 1);
2153                 ServerRemotePlayer *player = getplayer(ref);
2154                 if(player == NULL) return 0;
2155                 // Do it
2156                 lua_pushnumber(L, player->getRadPitch());
2157                 return 1;
2158         }
2159
2160         // get_look_yaw(self)
2161         static int l_get_look_yaw(lua_State *L)
2162         {
2163                 ObjectRef *ref = checkobject(L, 1);
2164                 ServerRemotePlayer *player = getplayer(ref);
2165                 if(player == NULL) return 0;
2166                 // Do it
2167                 lua_pushnumber(L, player->getRadYaw());
2168                 return 1;
2169         }
2170
2171 public:
2172         ObjectRef(ServerActiveObject *object):
2173                 m_object(object)
2174         {
2175                 //infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
2176         }
2177
2178         ~ObjectRef()
2179         {
2180                 /*if(m_object)
2181                         infostream<<"ObjectRef destructing for id="
2182                                         <<m_object->getId()<<std::endl;
2183                 else
2184                         infostream<<"ObjectRef destructing for id=unknown"<<std::endl;*/
2185         }
2186
2187         // Creates an ObjectRef and leaves it on top of stack
2188         // Not callable from Lua; all references are created on the C side.
2189         static void create(lua_State *L, ServerActiveObject *object)
2190         {
2191                 ObjectRef *o = new ObjectRef(object);
2192                 //infostream<<"ObjectRef::create: o="<<o<<std::endl;
2193                 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
2194                 luaL_getmetatable(L, className);
2195                 lua_setmetatable(L, -2);
2196         }
2197
2198         static void set_null(lua_State *L)
2199         {
2200                 ObjectRef *o = checkobject(L, -1);
2201                 o->m_object = NULL;
2202         }
2203         
2204         static void Register(lua_State *L)
2205         {
2206                 lua_newtable(L);
2207                 int methodtable = lua_gettop(L);
2208                 luaL_newmetatable(L, className);
2209                 int metatable = lua_gettop(L);
2210
2211                 lua_pushliteral(L, "__metatable");
2212                 lua_pushvalue(L, methodtable);
2213                 lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
2214
2215                 lua_pushliteral(L, "__index");
2216                 lua_pushvalue(L, methodtable);
2217                 lua_settable(L, metatable);
2218
2219                 lua_pushliteral(L, "__gc");
2220                 lua_pushcfunction(L, gc_object);
2221                 lua_settable(L, metatable);
2222
2223                 lua_pop(L, 1);  // drop metatable
2224
2225                 luaL_openlib(L, 0, methods, 0);  // fill methodtable
2226                 lua_pop(L, 1);  // drop methodtable
2227
2228                 // Cannot be created from Lua
2229                 //lua_register(L, className, create_object);
2230         }
2231 };
2232 const char ObjectRef::className[] = "ObjectRef";
2233 const luaL_reg ObjectRef::methods[] = {
2234         // ServerActiveObject
2235         method(ObjectRef, remove),
2236         method(ObjectRef, getpos),
2237         method(ObjectRef, setpos),
2238         method(ObjectRef, moveto),
2239         method(ObjectRef, punch),
2240         method(ObjectRef, right_click),
2241         method(ObjectRef, get_wield_digging_properties),
2242         method(ObjectRef, damage_wielded_item),
2243         method(ObjectRef, add_to_inventory),
2244         method(ObjectRef, add_to_inventory_later),
2245         method(ObjectRef, set_hp),
2246         method(ObjectRef, get_hp),
2247         // LuaEntitySAO-only
2248         method(ObjectRef, setvelocity),
2249         method(ObjectRef, getvelocity),
2250         method(ObjectRef, setacceleration),
2251         method(ObjectRef, getacceleration),
2252         method(ObjectRef, setyaw),
2253         method(ObjectRef, getyaw),
2254         method(ObjectRef, settexturemod),
2255         method(ObjectRef, setsprite),
2256         method(ObjectRef, get_entity_name),
2257         method(ObjectRef, get_luaentity),
2258         // Player-only
2259         method(ObjectRef, get_player_name),
2260         method(ObjectRef, get_inventory),
2261         method(ObjectRef, inventory_set_list), // deprecated
2262         method(ObjectRef, inventory_get_list), // deprecated
2263         method(ObjectRef, get_wielded_itemstring),
2264         method(ObjectRef, get_wielded_item),
2265         method(ObjectRef, get_look_dir),
2266         method(ObjectRef, get_look_pitch),
2267         method(ObjectRef, get_look_yaw),
2268         {0,0}
2269 };
2270
2271 // Creates a new anonymous reference if id=0
2272 static void objectref_get_or_create(lua_State *L,
2273                 ServerActiveObject *cobj)
2274 {
2275         if(cobj->getId() == 0){
2276                 ObjectRef::create(L, cobj);
2277         } else {
2278                 objectref_get(L, cobj->getId());
2279         }
2280 }
2281
2282 /*
2283         EnvRef
2284 */
2285
2286 class EnvRef
2287 {
2288 private:
2289         ServerEnvironment *m_env;
2290
2291         static const char className[];
2292         static const luaL_reg methods[];
2293
2294         static EnvRef *checkobject(lua_State *L, int narg)
2295         {
2296                 luaL_checktype(L, narg, LUA_TUSERDATA);
2297                 void *ud = luaL_checkudata(L, narg, className);
2298                 if(!ud) luaL_typerror(L, narg, className);
2299                 return *(EnvRef**)ud;  // unbox pointer
2300         }
2301         
2302         // Exported functions
2303
2304         // EnvRef:add_node(pos, node)
2305         // pos = {x=num, y=num, z=num}
2306         static int l_add_node(lua_State *L)
2307         {
2308                 //infostream<<"EnvRef::l_add_node()"<<std::endl;
2309                 EnvRef *o = checkobject(L, 1);
2310                 ServerEnvironment *env = o->m_env;
2311                 if(env == NULL) return 0;
2312                 // pos
2313                 v3s16 pos = read_v3s16(L, 2);
2314                 // content
2315                 MapNode n = readnode(L, 3, env->getGameDef()->ndef());
2316                 // Do it
2317                 bool succeeded = env->getMap().addNodeWithEvent(pos, n);
2318                 lua_pushboolean(L, succeeded);
2319                 return 1;
2320         }
2321
2322         // EnvRef:remove_node(pos)
2323         // pos = {x=num, y=num, z=num}
2324         static int l_remove_node(lua_State *L)
2325         {
2326                 //infostream<<"EnvRef::l_remove_node()"<<std::endl;
2327                 EnvRef *o = checkobject(L, 1);
2328                 ServerEnvironment *env = o->m_env;
2329                 if(env == NULL) return 0;
2330                 // pos
2331                 v3s16 pos = read_v3s16(L, 2);
2332                 // Do it
2333                 bool succeeded = env->getMap().removeNodeWithEvent(pos);
2334                 lua_pushboolean(L, succeeded);
2335                 return 1;
2336         }
2337
2338         // EnvRef:get_node(pos)
2339         // pos = {x=num, y=num, z=num}
2340         static int l_get_node(lua_State *L)
2341         {
2342                 //infostream<<"EnvRef::l_get_node()"<<std::endl;
2343                 EnvRef *o = checkobject(L, 1);
2344                 ServerEnvironment *env = o->m_env;
2345                 if(env == NULL) return 0;
2346                 // pos
2347                 v3s16 pos = read_v3s16(L, 2);
2348                 // Do it
2349                 MapNode n = env->getMap().getNodeNoEx(pos);
2350                 // Return node
2351                 pushnode(L, n, env->getGameDef()->ndef());
2352                 return 1;
2353         }
2354
2355         // EnvRef:get_node_or_nil(pos)
2356         // pos = {x=num, y=num, z=num}
2357         static int l_get_node_or_nil(lua_State *L)
2358         {
2359                 //infostream<<"EnvRef::l_get_node()"<<std::endl;
2360                 EnvRef *o = checkobject(L, 1);
2361                 ServerEnvironment *env = o->m_env;
2362                 if(env == NULL) return 0;
2363                 // pos
2364                 v3s16 pos = read_v3s16(L, 2);
2365                 // Do it
2366                 try{
2367                         MapNode n = env->getMap().getNode(pos);
2368                         // Return node
2369                         pushnode(L, n, env->getGameDef()->ndef());
2370                         return 1;
2371                 } catch(InvalidPositionException &e)
2372                 {
2373                         lua_pushnil(L);
2374                         return 1;
2375                 }
2376         }
2377
2378         // EnvRef:get_node_light(pos, timeofday)
2379         // pos = {x=num, y=num, z=num}
2380         // timeofday: nil = current time, 0 = night, 0.5 = day
2381         static int l_get_node_light(lua_State *L)
2382         {
2383                 EnvRef *o = checkobject(L, 1);
2384                 ServerEnvironment *env = o->m_env;
2385                 if(env == NULL) return 0;
2386                 // Do it
2387                 v3s16 pos = read_v3s16(L, 2);
2388                 u32 time_of_day = env->getTimeOfDay();
2389                 if(lua_isnumber(L, 3))
2390                         time_of_day = 24000.0 * lua_tonumber(L, 3);
2391                 time_of_day %= 24000;
2392                 u32 dnr = time_to_daynight_ratio(time_of_day);
2393                 MapNode n = env->getMap().getNodeNoEx(pos);
2394                 try{
2395                         MapNode n = env->getMap().getNode(pos);
2396                         INodeDefManager *ndef = env->getGameDef()->ndef();
2397                         lua_pushinteger(L, n.getLightBlend(dnr, ndef));
2398                         return 1;
2399                 } catch(InvalidPositionException &e)
2400                 {
2401                         lua_pushnil(L);
2402                         return 1;
2403                 }
2404         }
2405
2406         // EnvRef:add_entity(pos, entityname)
2407         // pos = {x=num, y=num, z=num}
2408         static int l_add_entity(lua_State *L)
2409         {
2410                 //infostream<<"EnvRef::l_add_entity()"<<std::endl;
2411                 EnvRef *o = checkobject(L, 1);
2412                 ServerEnvironment *env = o->m_env;
2413                 if(env == NULL) return 0;
2414                 // pos
2415                 v3f pos = checkFloatPos(L, 2);
2416                 // content
2417                 const char *name = luaL_checkstring(L, 3);
2418                 // Do it
2419                 ServerActiveObject *obj = new LuaEntitySAO(env, pos, name, "");
2420                 int objectid = env->addActiveObject(obj);
2421                 // If failed to add, return nothing (reads as nil)
2422                 if(objectid == 0)
2423                         return 0;
2424                 // Return ObjectRef
2425                 objectref_get_or_create(L, obj);
2426                 return 1;
2427         }
2428
2429         // EnvRef:add_item(pos, inventorystring)
2430         // pos = {x=num, y=num, z=num}
2431         static int l_add_item(lua_State *L)
2432         {
2433                 infostream<<"EnvRef::l_add_item()"<<std::endl;
2434                 EnvRef *o = checkobject(L, 1);
2435                 ServerEnvironment *env = o->m_env;
2436                 if(env == NULL) return 0;
2437                 // pos
2438                 v3f pos = checkFloatPos(L, 2);
2439                 // inventorystring
2440                 const char *inventorystring = luaL_checkstring(L, 3);
2441                 // Do it
2442                 ServerActiveObject *obj = new ItemSAO(env, pos, inventorystring);
2443                 env->addActiveObject(obj);
2444                 return 0;
2445         }
2446
2447         // EnvRef:add_rat(pos)
2448         // pos = {x=num, y=num, z=num}
2449         static int l_add_rat(lua_State *L)
2450         {
2451                 infostream<<"EnvRef::l_add_rat()"<<std::endl;
2452                 EnvRef *o = checkobject(L, 1);
2453                 ServerEnvironment *env = o->m_env;
2454                 if(env == NULL) return 0;
2455                 // pos
2456                 v3f pos = checkFloatPos(L, 2);
2457                 // Do it
2458                 ServerActiveObject *obj = new RatSAO(env, pos);
2459                 env->addActiveObject(obj);
2460                 return 0;
2461         }
2462
2463         // EnvRef:add_firefly(pos)
2464         // pos = {x=num, y=num, z=num}
2465         static int l_add_firefly(lua_State *L)
2466         {
2467                 infostream<<"EnvRef::l_add_firefly()"<<std::endl;
2468                 EnvRef *o = checkobject(L, 1);
2469                 ServerEnvironment *env = o->m_env;
2470                 if(env == NULL) return 0;
2471                 // pos
2472                 v3f pos = checkFloatPos(L, 2);
2473                 // Do it
2474                 ServerActiveObject *obj = new FireflySAO(env, pos);
2475                 env->addActiveObject(obj);
2476                 return 0;
2477         }
2478
2479         // EnvRef:get_meta(pos)
2480         static int l_get_meta(lua_State *L)
2481         {
2482                 //infostream<<"EnvRef::l_get_meta()"<<std::endl;
2483                 EnvRef *o = checkobject(L, 1);
2484                 ServerEnvironment *env = o->m_env;
2485                 if(env == NULL) return 0;
2486                 // Do it
2487                 v3s16 p = read_v3s16(L, 2);
2488                 NodeMetaRef::create(L, p, env);
2489                 return 1;
2490         }
2491
2492         // EnvRef:get_player_by_name(name)
2493         static int l_get_player_by_name(lua_State *L)
2494         {
2495                 EnvRef *o = checkobject(L, 1);
2496                 ServerEnvironment *env = o->m_env;
2497                 if(env == NULL) return 0;
2498                 // Do it
2499                 const char *name = luaL_checkstring(L, 2);
2500                 ServerRemotePlayer *player =
2501                                 static_cast<ServerRemotePlayer*>(env->getPlayer(name));
2502                 if(player == NULL){
2503                         lua_pushnil(L);
2504                         return 1;
2505                 }
2506                 // Put player on stack
2507                 objectref_get_or_create(L, player);
2508                 return 1;
2509         }
2510
2511         // EnvRef:get_objects_inside_radius(pos, radius)
2512         static int l_get_objects_inside_radius(lua_State *L)
2513         {
2514                 // Get the table insert function
2515                 lua_getglobal(L, "table");
2516                 lua_getfield(L, -1, "insert");
2517                 int table_insert = lua_gettop(L);
2518                 // Get environemnt
2519                 EnvRef *o = checkobject(L, 1);
2520                 ServerEnvironment *env = o->m_env;
2521                 if(env == NULL) return 0;
2522                 // Do it
2523                 v3f pos = checkFloatPos(L, 2);
2524                 float radius = luaL_checknumber(L, 3) * BS;
2525                 std::set<u16> ids = env->getObjectsInsideRadius(pos, radius);
2526                 lua_newtable(L);
2527                 int table = lua_gettop(L);
2528                 for(std::set<u16>::const_iterator
2529                                 i = ids.begin(); i != ids.end(); i++){
2530                         ServerActiveObject *obj = env->getActiveObject(*i);
2531                         // Insert object reference into table
2532                         lua_pushvalue(L, table_insert);
2533                         lua_pushvalue(L, table);
2534                         objectref_get_or_create(L, obj);
2535                         if(lua_pcall(L, 2, 0, 0))
2536                                 script_error(L, "error: %s", lua_tostring(L, -1));
2537                 }
2538                 return 1;
2539         }
2540
2541         static int gc_object(lua_State *L) {
2542                 EnvRef *o = *(EnvRef **)(lua_touserdata(L, 1));
2543                 delete o;
2544                 return 0;
2545         }
2546
2547 public:
2548         EnvRef(ServerEnvironment *env):
2549                 m_env(env)
2550         {
2551                 infostream<<"EnvRef created"<<std::endl;
2552         }
2553
2554         ~EnvRef()
2555         {
2556                 infostream<<"EnvRef destructing"<<std::endl;
2557         }
2558
2559         // Creates an EnvRef and leaves it on top of stack
2560         // Not callable from Lua; all references are created on the C side.
2561         static void create(lua_State *L, ServerEnvironment *env)
2562         {
2563                 EnvRef *o = new EnvRef(env);
2564                 //infostream<<"EnvRef::create: o="<<o<<std::endl;
2565                 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
2566                 luaL_getmetatable(L, className);
2567                 lua_setmetatable(L, -2);
2568         }
2569
2570         static void set_null(lua_State *L)
2571         {
2572                 EnvRef *o = checkobject(L, -1);
2573                 o->m_env = NULL;
2574         }
2575         
2576         static void Register(lua_State *L)
2577         {
2578                 lua_newtable(L);
2579                 int methodtable = lua_gettop(L);
2580                 luaL_newmetatable(L, className);
2581                 int metatable = lua_gettop(L);
2582
2583                 lua_pushliteral(L, "__metatable");
2584                 lua_pushvalue(L, methodtable);
2585                 lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
2586
2587                 lua_pushliteral(L, "__index");
2588                 lua_pushvalue(L, methodtable);
2589                 lua_settable(L, metatable);
2590
2591                 lua_pushliteral(L, "__gc");
2592                 lua_pushcfunction(L, gc_object);
2593                 lua_settable(L, metatable);
2594
2595                 lua_pop(L, 1);  // drop metatable
2596
2597                 luaL_openlib(L, 0, methods, 0);  // fill methodtable
2598                 lua_pop(L, 1);  // drop methodtable
2599
2600                 // Cannot be created from Lua
2601                 //lua_register(L, className, create_object);
2602         }
2603 };
2604 const char EnvRef::className[] = "EnvRef";
2605 const luaL_reg EnvRef::methods[] = {
2606         method(EnvRef, add_node),
2607         method(EnvRef, remove_node),
2608         method(EnvRef, get_node),
2609         method(EnvRef, get_node_or_nil),
2610         method(EnvRef, get_node_light),
2611         method(EnvRef, add_entity),
2612         method(EnvRef, add_item),
2613         method(EnvRef, add_rat),
2614         method(EnvRef, add_firefly),
2615         method(EnvRef, get_meta),
2616         method(EnvRef, get_player_by_name),
2617         method(EnvRef, get_objects_inside_radius),
2618         {0,0}
2619 };
2620
2621 /*
2622         Global functions
2623 */
2624
2625 static int l_register_nodedef_defaults(lua_State *L)
2626 {
2627         luaL_checktype(L, 1, LUA_TTABLE);
2628
2629         lua_pushvalue(L, 1); // Explicitly put parameter 1 on top of stack
2630         lua_setfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
2631
2632         return 0;
2633 }
2634
2635 // Register new object prototype
2636 // register_entity(name, prototype)
2637 static int l_register_entity(lua_State *L)
2638 {
2639         std::string name = luaL_checkstring(L, 1);
2640         check_modname_prefix(L, name);
2641         //infostream<<"register_entity: "<<name<<std::endl;
2642         luaL_checktype(L, 2, LUA_TTABLE);
2643
2644         // Get minetest.registered_entities
2645         lua_getglobal(L, "minetest");
2646         lua_getfield(L, -1, "registered_entities");
2647         luaL_checktype(L, -1, LUA_TTABLE);
2648         int registered_entities = lua_gettop(L);
2649         lua_pushvalue(L, 2); // Object = param 2 -> stack top
2650         // registered_entities[name] = object
2651         lua_setfield(L, registered_entities, name.c_str());
2652         
2653         // Get registered object to top of stack
2654         lua_pushvalue(L, 2);
2655
2656         // Set name field
2657         lua_pushvalue(L, 1);
2658         lua_setfield(L, -2, "name");
2659         
2660         // Set __index to point to itself
2661         lua_pushvalue(L, -1);
2662         lua_setfield(L, -2, "__index");
2663
2664         // Set metatable.__index = metatable
2665         luaL_getmetatable(L, "minetest.entity");
2666         lua_pushvalue(L, -1); // duplicate metatable
2667         lua_setfield(L, -2, "__index");
2668         // Set object metatable
2669         lua_setmetatable(L, -2);
2670
2671         return 0; /* number of results */
2672 }
2673
2674 class LuaABM : public ActiveBlockModifier
2675 {
2676 private:
2677         lua_State *m_lua;
2678         int m_id;
2679
2680         std::set<std::string> m_trigger_contents;
2681         std::set<std::string> m_required_neighbors;
2682         float m_trigger_interval;
2683         u32 m_trigger_chance;
2684 public:
2685         LuaABM(lua_State *L, int id,
2686                         const std::set<std::string> &trigger_contents,
2687                         const std::set<std::string> &required_neighbors,
2688                         float trigger_interval, u32 trigger_chance):
2689                 m_lua(L),
2690                 m_id(id),
2691                 m_trigger_contents(trigger_contents),
2692                 m_required_neighbors(required_neighbors),
2693                 m_trigger_interval(trigger_interval),
2694                 m_trigger_chance(trigger_chance)
2695         {
2696         }
2697         virtual std::set<std::string> getTriggerContents()
2698         {
2699                 return m_trigger_contents;
2700         }
2701         virtual std::set<std::string> getRequiredNeighbors()
2702         {
2703                 return m_required_neighbors;
2704         }
2705         virtual float getTriggerInterval()
2706         {
2707                 return m_trigger_interval;
2708         }
2709         virtual u32 getTriggerChance()
2710         {
2711                 return m_trigger_chance;
2712         }
2713         virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n,
2714                         u32 active_object_count, u32 active_object_count_wider)
2715         {
2716                 lua_State *L = m_lua;
2717         
2718                 realitycheck(L);
2719                 assert(lua_checkstack(L, 20));
2720                 StackUnroller stack_unroller(L);
2721
2722                 // Get minetest.registered_abms
2723                 lua_getglobal(L, "minetest");
2724                 lua_getfield(L, -1, "registered_abms");
2725                 luaL_checktype(L, -1, LUA_TTABLE);
2726                 int registered_abms = lua_gettop(L);
2727
2728                 // Get minetest.registered_abms[m_id]
2729                 lua_pushnumber(L, m_id);
2730                 lua_gettable(L, registered_abms);
2731                 if(lua_isnil(L, -1))
2732                         assert(0);
2733                 
2734                 // Call action
2735                 luaL_checktype(L, -1, LUA_TTABLE);
2736                 lua_getfield(L, -1, "action");
2737                 luaL_checktype(L, -1, LUA_TFUNCTION);
2738                 push_v3s16(L, p);
2739                 pushnode(L, n, env->getGameDef()->ndef());
2740                 lua_pushnumber(L, active_object_count);
2741                 lua_pushnumber(L, active_object_count_wider);
2742                 if(lua_pcall(L, 4, 0, 0))
2743                         script_error(L, "error: %s", lua_tostring(L, -1));
2744         }
2745 };
2746
2747 // register_abm({...})
2748 static int l_register_abm(lua_State *L)
2749 {
2750         //infostream<<"register_abm"<<std::endl;
2751         luaL_checktype(L, 1, LUA_TTABLE);
2752
2753         // Get minetest.registered_abms
2754         lua_getglobal(L, "minetest");
2755         lua_getfield(L, -1, "registered_abms");
2756         luaL_checktype(L, -1, LUA_TTABLE);
2757         int registered_abms = lua_gettop(L);
2758
2759         int id = 1;
2760         // Find free id
2761         for(;;){
2762                 lua_pushnumber(L, id);
2763                 lua_gettable(L, registered_abms);
2764                 if(lua_isnil(L, -1))
2765                         break;
2766                 lua_pop(L, 1);
2767                 id++;
2768         }
2769         lua_pop(L, 1);
2770
2771         infostream<<"register_abm: id="<<id<<std::endl;
2772
2773         // registered_abms[id] = spec
2774         lua_pushnumber(L, id);
2775         lua_pushvalue(L, 1);
2776         lua_settable(L, registered_abms);
2777         
2778         return 0; /* number of results */
2779 }
2780
2781 // register_tool(name, {lots of stuff})
2782 static int l_register_tool(lua_State *L)
2783 {
2784         std::string name = luaL_checkstring(L, 1);
2785         check_modname_prefix(L, name);
2786         //infostream<<"register_tool: "<<name<<std::endl;
2787         luaL_checktype(L, 2, LUA_TTABLE);
2788         int table = 2;
2789
2790         // Get the writable tool definition manager from the server
2791         IWritableToolDefManager *tooldef =
2792                         get_server(L)->getWritableToolDefManager();
2793         
2794         ToolDefinition def = read_tool_definition(L, table);
2795
2796         tooldef->registerTool(name, def);
2797         return 0; /* number of results */
2798 }
2799
2800 // register_craftitem(name, {lots of stuff})
2801 static int l_register_craftitem(lua_State *L)
2802 {
2803         std::string name = luaL_checkstring(L, 1);
2804         check_modname_prefix(L, name);
2805         //infostream<<"register_craftitem: "<<name<<std::endl;
2806         luaL_checktype(L, 2, LUA_TTABLE);
2807         int table = 2;
2808
2809         // Get the writable CraftItem definition manager from the server
2810         IWritableCraftItemDefManager *craftitemdef =
2811                         get_server(L)->getWritableCraftItemDefManager();
2812         
2813         // Check if on_drop is defined
2814         lua_getfield(L, table, "on_drop");
2815         bool got_on_drop = !lua_isnil(L, -1);
2816         lua_pop(L, 1);
2817
2818         // Check if on_use is defined
2819         lua_getfield(L, table, "on_use");
2820         bool got_on_use = !lua_isnil(L, -1);
2821         lua_pop(L, 1);
2822
2823         CraftItemDefinition def;
2824         
2825         getstringfield(L, table, "image", def.imagename);
2826         getstringfield(L, table, "cookresult_itemstring", def.cookresult_item);
2827         getfloatfield(L, table, "furnace_cooktime", def.furnace_cooktime);
2828         getfloatfield(L, table, "furnace_burntime", def.furnace_burntime);
2829         def.usable = getboolfield_default(L, table, "usable", got_on_use);
2830         getboolfield(L, table, "liquids_pointable", def.liquids_pointable);
2831         def.dropcount = getintfield_default(L, table, "dropcount", def.dropcount);
2832         def.stack_max = getintfield_default(L, table, "stack_max", def.stack_max);
2833
2834         // If an on_drop callback is defined, force dropcount to 1
2835         if (got_on_drop)
2836                 def.dropcount = 1;
2837
2838         // Register it
2839         craftitemdef->registerCraftItem(name, def);
2840
2841         lua_pushvalue(L, table);
2842         scriptapi_add_craftitem(L, name.c_str());
2843
2844         return 0; /* number of results */
2845 }
2846
2847 // register_node(name, {lots of stuff})
2848 static int l_register_node(lua_State *L)
2849 {
2850         std::string name = luaL_checkstring(L, 1);
2851         check_modname_prefix(L, name);
2852         //infostream<<"register_node: "<<name<<std::endl;
2853         luaL_checktype(L, 2, LUA_TTABLE);
2854         int nodedef_table = 2;
2855
2856         // Get the writable node definition manager from the server
2857         IWritableNodeDefManager *nodedef =
2858                         get_server(L)->getWritableNodeDefManager();
2859         
2860         // Get default node definition from registry
2861         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
2862         int nodedef_default = lua_gettop(L);
2863
2864         /*
2865                 Add to minetest.registered_nodes with default as metatable
2866         */
2867         
2868         // Get the node definition table given as parameter
2869         lua_pushvalue(L, nodedef_table);
2870
2871         // Set __index to point to itself
2872         lua_pushvalue(L, -1);
2873         lua_setfield(L, -2, "__index");
2874
2875         // Set nodedef_default as metatable for the definition
2876         lua_pushvalue(L, nodedef_default);
2877         lua_setmetatable(L, nodedef_table);
2878         
2879         // minetest.registered_nodes[name] = nodedef
2880         lua_getglobal(L, "minetest");
2881         lua_getfield(L, -1, "registered_nodes");
2882         luaL_checktype(L, -1, LUA_TTABLE);
2883         lua_pushstring(L, name.c_str());
2884         lua_pushvalue(L, nodedef_table);
2885         lua_settable(L, -3);
2886
2887         /*
2888                 Create definition
2889         */
2890         
2891         ContentFeatures f;
2892
2893         // Default to getting the corresponding NodeItem when dug
2894         f.dug_item = std::string("NodeItem \"")+name+"\" 1";
2895         
2896         // Default to unknown_block.png as all textures
2897         f.setAllTextures("unknown_block.png");
2898
2899         /*
2900                 Read definiton from Lua
2901         */
2902
2903         f.name = name;
2904         
2905         /* Visual definition */
2906
2907         f.drawtype = (NodeDrawType)getenumfield(L, nodedef_table, "drawtype", es_DrawType,
2908                         NDT_NORMAL);
2909         getfloatfield(L, nodedef_table, "visual_scale", f.visual_scale);
2910
2911         lua_getfield(L, nodedef_table, "tile_images");
2912         if(lua_istable(L, -1)){
2913                 int table = lua_gettop(L);
2914                 lua_pushnil(L);
2915                 int i = 0;
2916                 while(lua_next(L, table) != 0){
2917                         // key at index -2 and value at index -1
2918                         if(lua_isstring(L, -1))
2919                                 f.tname_tiles[i] = lua_tostring(L, -1);
2920                         else
2921                                 f.tname_tiles[i] = "";
2922                         // removes value, keeps key for next iteration
2923                         lua_pop(L, 1);
2924                         i++;
2925                         if(i==6){
2926                                 lua_pop(L, 1);
2927                                 break;
2928                         }
2929                 }
2930                 // Copy last value to all remaining textures
2931                 if(i >= 1){
2932                         std::string lastname = f.tname_tiles[i-1];
2933                         while(i < 6){
2934                                 f.tname_tiles[i] = lastname;
2935                                 i++;
2936                         }
2937                 }
2938         }
2939         lua_pop(L, 1);
2940
2941         getstringfield(L, nodedef_table, "inventory_image", f.tname_inventory);
2942
2943         lua_getfield(L, nodedef_table, "special_materials");
2944         if(lua_istable(L, -1)){
2945                 int table = lua_gettop(L);
2946                 lua_pushnil(L);
2947                 int i = 0;
2948                 while(lua_next(L, table) != 0){
2949                         // key at index -2 and value at index -1
2950                         int smtable = lua_gettop(L);
2951                         std::string tname = getstringfield_default(
2952                                         L, smtable, "image", "");
2953                         bool backface_culling = getboolfield_default(
2954                                         L, smtable, "backface_culling", true);
2955                         MaterialSpec mspec(tname, backface_culling);
2956                         f.setSpecialMaterial(i, mspec);
2957                         // removes value, keeps key for next iteration
2958                         lua_pop(L, 1);
2959                         i++;
2960                         if(i==6){
2961                                 lua_pop(L, 1);
2962                                 break;
2963                         }
2964                 }
2965         }
2966         lua_pop(L, 1);
2967
2968         f.alpha = getintfield_default(L, nodedef_table, "alpha", 255);
2969
2970         /* Other stuff */
2971         
2972         lua_getfield(L, nodedef_table, "post_effect_color");
2973         if(!lua_isnil(L, -1))
2974                 f.post_effect_color = readARGB8(L, -1);
2975         lua_pop(L, 1);
2976
2977         f.param_type = (ContentParamType)getenumfield(L, nodedef_table, "paramtype",
2978                         es_ContentParamType, CPT_NONE);
2979         
2980         // True for all ground-like things like stone and mud, false for eg. trees
2981         getboolfield(L, nodedef_table, "is_ground_content", f.is_ground_content);
2982         f.light_propagates = (f.param_type == CPT_LIGHT);
2983         warn_if_field_exists(L, nodedef_table, "light_propagates",
2984                         "deprecated: determined from paramtype");
2985         getboolfield(L, nodedef_table, "sunlight_propagates", f.sunlight_propagates);
2986         // This is used for collision detection.
2987         // Also for general solidness queries.
2988         getboolfield(L, nodedef_table, "walkable", f.walkable);
2989         // Player can point to these
2990         getboolfield(L, nodedef_table, "pointable", f.pointable);
2991         // Player can dig these
2992         getboolfield(L, nodedef_table, "diggable", f.diggable);
2993         // Player can climb these
2994         getboolfield(L, nodedef_table, "climbable", f.climbable);
2995         // Player can build on these
2996         getboolfield(L, nodedef_table, "buildable_to", f.buildable_to);
2997         // If true, param2 is set to direction when placed. Used for torches.
2998         // NOTE: the direction format is quite inefficient and should be changed
2999         getboolfield(L, nodedef_table, "wall_mounted", f.wall_mounted);
3000         // Whether this content type often contains mineral.
3001         // Used for texture atlas creation.
3002         // Currently only enabled for CONTENT_STONE.
3003         getboolfield(L, nodedef_table, "often_contains_mineral", f.often_contains_mineral);
3004         // Inventory item string as which the node appears in inventory when dug.
3005         // Mineral overrides this.
3006         getstringfield(L, nodedef_table, "dug_item", f.dug_item);
3007         // Extra dug item and its rarity
3008         getstringfield(L, nodedef_table, "extra_dug_item", f.extra_dug_item);
3009         // Usual get interval for extra dug item
3010         getintfield(L, nodedef_table, "extra_dug_item_rarity", f.extra_dug_item_rarity);
3011         // Metadata name of node (eg. "furnace")
3012         getstringfield(L, nodedef_table, "metadata_name", f.metadata_name);
3013         // Whether the node is non-liquid, source liquid or flowing liquid
3014         f.liquid_type = (LiquidType)getenumfield(L, nodedef_table, "liquidtype",
3015                         es_LiquidType, LIQUID_NONE);
3016         // If the content is liquid, this is the flowing version of the liquid.
3017         getstringfield(L, nodedef_table, "liquid_alternative_flowing",
3018                         f.liquid_alternative_flowing);
3019         // If the content is liquid, this is the source version of the liquid.
3020         getstringfield(L, nodedef_table, "liquid_alternative_source",
3021                         f.liquid_alternative_source);
3022         // Viscosity for fluid flow, ranging from 1 to 7, with
3023         // 1 giving almost instantaneous propagation and 7 being
3024         // the slowest possible
3025         f.liquid_viscosity = getintfield_default(L, nodedef_table,
3026                         "liquid_viscosity", f.liquid_viscosity);
3027         // Amount of light the node emits
3028         f.light_source = getintfield_default(L, nodedef_table,
3029                         "light_source", f.light_source);
3030         f.damage_per_second = getintfield_default(L, nodedef_table,
3031                         "damage_per_second", f.damage_per_second);
3032         
3033         lua_getfield(L, nodedef_table, "selection_box");
3034         if(lua_istable(L, -1)){
3035                 f.selection_box.type = (NodeBoxType)getenumfield(L, -1, "type",
3036                                 es_NodeBoxType, NODEBOX_REGULAR);
3037
3038                 lua_getfield(L, -1, "fixed");
3039                 if(lua_istable(L, -1))
3040                         f.selection_box.fixed = read_aabbox3df32(L, -1, BS);
3041                 lua_pop(L, 1);
3042
3043                 lua_getfield(L, -1, "wall_top");
3044                 if(lua_istable(L, -1))
3045                         f.selection_box.wall_top = read_aabbox3df32(L, -1, BS);
3046                 lua_pop(L, 1);
3047
3048                 lua_getfield(L, -1, "wall_bottom");
3049                 if(lua_istable(L, -1))
3050                         f.selection_box.wall_bottom = read_aabbox3df32(L, -1, BS);
3051                 lua_pop(L, 1);
3052
3053                 lua_getfield(L, -1, "wall_side");
3054                 if(lua_istable(L, -1))
3055                         f.selection_box.wall_side = read_aabbox3df32(L, -1, BS);
3056                 lua_pop(L, 1);
3057         }
3058         lua_pop(L, 1);
3059
3060         lua_getfield(L, nodedef_table, "material");
3061         if(lua_istable(L, -1)){
3062                 f.material.diggability = (Diggability)getenumfield(L, -1, "diggability",
3063                                 es_Diggability, DIGGABLE_NORMAL);
3064                 
3065                 getfloatfield(L, -1, "constant_time", f.material.constant_time);
3066                 getfloatfield(L, -1, "weight", f.material.weight);
3067                 getfloatfield(L, -1, "crackiness", f.material.crackiness);
3068                 getfloatfield(L, -1, "crumbliness", f.material.crumbliness);
3069                 getfloatfield(L, -1, "cuttability", f.material.cuttability);
3070                 getfloatfield(L, -1, "flammability", f.material.flammability);
3071         }
3072         lua_pop(L, 1);
3073
3074         getstringfield(L, nodedef_table, "cookresult_itemstring", f.cookresult_item);
3075         getfloatfield(L, nodedef_table, "furnace_cooktime", f.furnace_cooktime);
3076         getfloatfield(L, nodedef_table, "furnace_burntime", f.furnace_burntime);
3077         
3078         /*
3079                 Register it
3080         */
3081         
3082         nodedef->set(name, f);
3083         
3084         return 0; /* number of results */
3085 }
3086
3087 // alias_node(name, convert_to_name)
3088 static int l_alias_node(lua_State *L)
3089 {
3090         std::string name = luaL_checkstring(L, 1);
3091         std::string convert_to = luaL_checkstring(L, 2);
3092
3093         // Get the writable node definition manager from the server
3094         IWritableNodeDefManager *nodedef =
3095                         get_server(L)->getWritableNodeDefManager();
3096         
3097         nodedef->setAlias(name, convert_to);
3098         
3099         return 0; /* number of results */
3100 }
3101
3102 // alias_tool(name, convert_to_name)
3103 static int l_alias_tool(lua_State *L)
3104 {
3105         std::string name = luaL_checkstring(L, 1);
3106         std::string convert_to = luaL_checkstring(L, 2);
3107
3108         // Get the writable tool definition manager from the server
3109         IWritableToolDefManager *tooldef =
3110                         get_server(L)->getWritableToolDefManager();
3111         
3112         tooldef->setAlias(name, convert_to);
3113
3114         return 0; /* number of results */
3115 }
3116
3117 // alias_craftitem(name, convert_to_name)
3118 static int l_alias_craftitem(lua_State *L)
3119 {
3120         std::string name = luaL_checkstring(L, 1);
3121         std::string convert_to = luaL_checkstring(L, 2);
3122
3123         // Get the writable CraftItem definition manager from the server
3124         IWritableCraftItemDefManager *craftitemdef =
3125                         get_server(L)->getWritableCraftItemDefManager();
3126         
3127         craftitemdef->setAlias(name, convert_to);
3128
3129         return 0; /* number of results */
3130 }
3131
3132 // register_craft({output=item, recipe={{item00,item10},{item01,item11}})
3133 static int l_register_craft(lua_State *L)
3134 {
3135         //infostream<<"register_craft"<<std::endl;
3136         luaL_checktype(L, 1, LUA_TTABLE);
3137         int table0 = 1;
3138
3139         // Get the writable craft definition manager from the server
3140         IWritableCraftDefManager *craftdef =
3141                         get_server(L)->getWritableCraftDefManager();
3142         
3143         std::string output;
3144         int width = 0;
3145         std::vector<std::string> input;
3146
3147         lua_getfield(L, table0, "output");
3148         luaL_checktype(L, -1, LUA_TSTRING);
3149         if(lua_isstring(L, -1))
3150                 output = lua_tostring(L, -1);
3151         lua_pop(L, 1);
3152
3153         lua_getfield(L, table0, "recipe");
3154         luaL_checktype(L, -1, LUA_TTABLE);
3155         if(lua_istable(L, -1)){
3156                 int table1 = lua_gettop(L);
3157                 lua_pushnil(L);
3158                 int rowcount = 0;
3159                 while(lua_next(L, table1) != 0){
3160                         int colcount = 0;
3161                         // key at index -2 and value at index -1
3162                         luaL_checktype(L, -1, LUA_TTABLE);
3163                         if(lua_istable(L, -1)){
3164                                 int table2 = lua_gettop(L);
3165                                 lua_pushnil(L);
3166                                 while(lua_next(L, table2) != 0){
3167                                         // key at index -2 and value at index -1
3168                                         luaL_checktype(L, -1, LUA_TSTRING);
3169                                         input.push_back(lua_tostring(L, -1));
3170                                         // removes value, keeps key for next iteration
3171                                         lua_pop(L, 1);
3172                                         colcount++;
3173                                 }
3174                         }
3175                         if(rowcount == 0){
3176                                 width = colcount;
3177                         } else {
3178                                 if(colcount != width){
3179                                         std::string error;
3180                                         error += "Invalid crafting recipe (output=\""
3181                                                         + output + "\")";
3182                                         throw LuaError(L, error);
3183                                 }
3184                         }
3185                         // removes value, keeps key for next iteration
3186                         lua_pop(L, 1);
3187                         rowcount++;
3188                 }
3189         }
3190         lua_pop(L, 1);
3191
3192         CraftDefinition def(output, width, input);
3193         craftdef->registerCraft(def);
3194
3195         return 0; /* number of results */
3196 }
3197
3198 // setting_get(name)
3199 static int l_setting_get(lua_State *L)
3200 {
3201         const char *name = luaL_checkstring(L, 1);
3202         try{
3203                 std::string value = g_settings->get(name);
3204                 lua_pushstring(L, value.c_str());
3205         } catch(SettingNotFoundException &e){
3206                 lua_pushnil(L);
3207         }
3208         return 1;
3209 }
3210
3211 // setting_getbool(name)
3212 static int l_setting_getbool(lua_State *L)
3213 {
3214         const char *name = luaL_checkstring(L, 1);
3215         try{
3216                 bool value = g_settings->getBool(name);
3217                 lua_pushboolean(L, value);
3218         } catch(SettingNotFoundException &e){
3219                 lua_pushnil(L);
3220         }
3221         return 1;
3222 }
3223
3224 // chat_send_all(text)
3225 static int l_chat_send_all(lua_State *L)
3226 {
3227         const char *text = luaL_checkstring(L, 1);
3228         // Get server from registry
3229         Server *server = get_server(L);
3230         // Send
3231         server->notifyPlayers(narrow_to_wide(text));
3232         return 0;
3233 }
3234
3235 // chat_send_player(name, text)
3236 static int l_chat_send_player(lua_State *L)
3237 {
3238         const char *name = luaL_checkstring(L, 1);
3239         const char *text = luaL_checkstring(L, 2);
3240         // Get server from registry
3241         Server *server = get_server(L);
3242         // Send
3243         server->notifyPlayer(name, narrow_to_wide(text));
3244         return 0;
3245 }
3246
3247 // get_player_privs(name, text)
3248 static int l_get_player_privs(lua_State *L)
3249 {
3250         const char *name = luaL_checkstring(L, 1);
3251         // Get server from registry
3252         Server *server = get_server(L);
3253         // Do it
3254         lua_newtable(L);
3255         int table = lua_gettop(L);
3256         u64 privs_i = server->getPlayerAuthPrivs(name);
3257         // Special case for the "name" setting (local player / server owner)
3258         if(name == g_settings->get("name"))
3259                 privs_i = PRIV_ALL;
3260         std::set<std::string> privs_s = privsToSet(privs_i);
3261         for(std::set<std::string>::const_iterator
3262                         i = privs_s.begin(); i != privs_s.end(); i++){
3263                 lua_pushboolean(L, true);
3264                 lua_setfield(L, table, i->c_str());
3265         }
3266         lua_pushvalue(L, table);
3267         return 1;
3268 }
3269
3270 // get_inventory(location)
3271 static int l_get_inventory(lua_State *L)
3272 {
3273         InventoryLocation loc;
3274
3275         std::string type = checkstringfield(L, 1, "type");
3276         if(type == "player"){
3277                 std::string name = checkstringfield(L, 1, "name");
3278                 loc.setPlayer(name);
3279         } else if(type == "node"){
3280                 lua_getfield(L, 1, "pos");
3281                 v3s16 pos = check_v3s16(L, -1);
3282                 loc.setNodeMeta(pos);
3283         }
3284         
3285         if(get_server(L)->getInventory(loc) != NULL)
3286                 InvRef::create(L, loc);
3287         else
3288                 lua_pushnil(L);
3289         return 1;
3290 }
3291
3292 // get_modpath(modname)
3293 static int l_get_modpath(lua_State *L)
3294 {
3295         const char *modname = luaL_checkstring(L, 1);
3296         // Get server from registry
3297         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
3298         Server *server = (Server*)lua_touserdata(L, -1);
3299         // Do it
3300         const ModSpec *mod = server->getModSpec(modname);
3301         if(!mod){
3302                 lua_pushnil(L);
3303                 return 1;
3304         }
3305         lua_pushstring(L, mod->path.c_str());
3306         return 1;
3307 }
3308
3309 static const struct luaL_Reg minetest_f [] = {
3310         {"register_nodedef_defaults", l_register_nodedef_defaults},
3311         {"register_entity", l_register_entity},
3312         {"register_tool", l_register_tool},
3313         {"register_craftitem", l_register_craftitem},
3314         {"register_node", l_register_node},
3315         {"register_craft", l_register_craft},
3316         {"register_abm", l_register_abm},
3317         {"alias_node", l_alias_node},
3318         {"alias_tool", l_alias_tool},
3319         {"alias_craftitem", l_alias_craftitem},
3320         {"setting_get", l_setting_get},
3321         {"setting_getbool", l_setting_getbool},
3322         {"chat_send_all", l_chat_send_all},
3323         {"chat_send_player", l_chat_send_player},
3324         {"get_player_privs", l_get_player_privs},
3325         {"get_inventory", l_get_inventory},
3326         {"get_modpath", l_get_modpath},
3327         {NULL, NULL}
3328 };
3329
3330 /*
3331         LuaEntity functions
3332 */
3333
3334 static const struct luaL_Reg minetest_entity_m [] = {
3335         {NULL, NULL}
3336 };
3337
3338 /*
3339         Main export function
3340 */
3341
3342 void scriptapi_export(lua_State *L, Server *server)
3343 {
3344         realitycheck(L);
3345         assert(lua_checkstack(L, 20));
3346         infostream<<"scriptapi_export"<<std::endl;
3347         StackUnroller stack_unroller(L);
3348
3349         // Store server as light userdata in registry
3350         lua_pushlightuserdata(L, server);
3351         lua_setfield(L, LUA_REGISTRYINDEX, "minetest_server");
3352
3353         // Store nil as minetest_nodedef_defaults in registry
3354         lua_pushnil(L);
3355         lua_setfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
3356         
3357         // Register global functions in table minetest
3358         lua_newtable(L);
3359         luaL_register(L, NULL, minetest_f);
3360         lua_setglobal(L, "minetest");
3361         
3362         // Get the main minetest table
3363         lua_getglobal(L, "minetest");
3364
3365         // Add tables to minetest
3366         
3367         lua_newtable(L);
3368         lua_setfield(L, -2, "registered_nodes");
3369         lua_newtable(L);
3370         lua_setfield(L, -2, "registered_entities");
3371         lua_newtable(L);
3372         lua_setfield(L, -2, "registered_craftitems");
3373         lua_newtable(L);
3374         lua_setfield(L, -2, "registered_abms");
3375         
3376         lua_newtable(L);
3377         lua_setfield(L, -2, "object_refs");
3378         lua_newtable(L);
3379         lua_setfield(L, -2, "luaentities");
3380
3381         // Create entity prototype
3382         luaL_newmetatable(L, "minetest.entity");
3383         // metatable.__index = metatable
3384         lua_pushvalue(L, -1); // Duplicate metatable
3385         lua_setfield(L, -2, "__index");
3386         // Put functions in metatable
3387         luaL_register(L, NULL, minetest_entity_m);
3388         // Put other stuff in metatable
3389         
3390         // Register wrappers
3391         ItemStack::Register(L);
3392         InvRef::Register(L);
3393         NodeMetaRef::Register(L);
3394         ObjectRef::Register(L);
3395         EnvRef::Register(L);
3396 }
3397
3398 bool scriptapi_loadmod(lua_State *L, const std::string &scriptpath,
3399                 const std::string &modname)
3400 {
3401         ModNameStorer modnamestorer(L, modname);
3402
3403         if(!string_allowed(modname, "abcdefghijklmnopqrstuvwxyz"
3404                         "0123456789_")){
3405                 errorstream<<"Error loading mod \""<<modname
3406                                 <<"\": modname does not follow naming conventions: "
3407                                 <<"Only chararacters [a-z0-9_] are allowed."<<std::endl;
3408                 return false;
3409         }
3410         
3411         bool success = false;
3412
3413         try{
3414                 success = script_load(L, scriptpath.c_str());
3415         }
3416         catch(LuaError &e){
3417                 errorstream<<"Error loading mod \""<<modname
3418                                 <<"\": "<<e.what()<<std::endl;
3419         }
3420
3421         return success;
3422 }
3423
3424 void scriptapi_add_environment(lua_State *L, ServerEnvironment *env)
3425 {
3426         realitycheck(L);
3427         assert(lua_checkstack(L, 20));
3428         infostream<<"scriptapi_add_environment"<<std::endl;
3429         StackUnroller stack_unroller(L);
3430
3431         // Create EnvRef on stack
3432         EnvRef::create(L, env);
3433         int envref = lua_gettop(L);
3434
3435         // minetest.env = envref
3436         lua_getglobal(L, "minetest");
3437         luaL_checktype(L, -1, LUA_TTABLE);
3438         lua_pushvalue(L, envref);
3439         lua_setfield(L, -2, "env");
3440
3441         // Store environment as light userdata in registry
3442         lua_pushlightuserdata(L, env);
3443         lua_setfield(L, LUA_REGISTRYINDEX, "minetest_env");
3444
3445         /*
3446                 Add ActiveBlockModifiers to environment
3447         */
3448
3449         // Get minetest.registered_abms
3450         lua_getglobal(L, "minetest");
3451         lua_getfield(L, -1, "registered_abms");
3452         luaL_checktype(L, -1, LUA_TTABLE);
3453         int registered_abms = lua_gettop(L);
3454         
3455         if(lua_istable(L, registered_abms)){
3456                 int table = lua_gettop(L);
3457                 lua_pushnil(L);
3458                 while(lua_next(L, table) != 0){
3459                         // key at index -2 and value at index -1
3460                         int id = lua_tonumber(L, -2);
3461                         int current_abm = lua_gettop(L);
3462
3463                         std::set<std::string> trigger_contents;
3464                         lua_getfield(L, current_abm, "nodenames");
3465                         if(lua_istable(L, -1)){
3466                                 int table = lua_gettop(L);
3467                                 lua_pushnil(L);
3468                                 while(lua_next(L, table) != 0){
3469                                         // key at index -2 and value at index -1
3470                                         luaL_checktype(L, -1, LUA_TSTRING);
3471                                         trigger_contents.insert(lua_tostring(L, -1));
3472                                         // removes value, keeps key for next iteration
3473                                         lua_pop(L, 1);
3474                                 }
3475                         } else if(lua_isstring(L, -1)){
3476                                 trigger_contents.insert(lua_tostring(L, -1));
3477                         }
3478                         lua_pop(L, 1);
3479
3480                         std::set<std::string> required_neighbors;
3481                         lua_getfield(L, current_abm, "neighbors");
3482                         if(lua_istable(L, -1)){
3483                                 int table = lua_gettop(L);
3484                                 lua_pushnil(L);
3485                                 while(lua_next(L, table) != 0){
3486                                         // key at index -2 and value at index -1
3487                                         luaL_checktype(L, -1, LUA_TSTRING);
3488                                         required_neighbors.insert(lua_tostring(L, -1));
3489                                         // removes value, keeps key for next iteration
3490                                         lua_pop(L, 1);
3491                                 }
3492                         } else if(lua_isstring(L, -1)){
3493                                 required_neighbors.insert(lua_tostring(L, -1));
3494                         }
3495                         lua_pop(L, 1);
3496
3497                         float trigger_interval = 10.0;
3498                         getfloatfield(L, current_abm, "interval", trigger_interval);
3499
3500                         int trigger_chance = 50;
3501                         getintfield(L, current_abm, "chance", trigger_chance);
3502
3503                         LuaABM *abm = new LuaABM(L, id, trigger_contents,
3504                                         required_neighbors, trigger_interval, trigger_chance);
3505                         
3506                         env->addActiveBlockModifier(abm);
3507
3508                         // removes value, keeps key for next iteration
3509                         lua_pop(L, 1);
3510                 }
3511         }
3512         lua_pop(L, 1);
3513 }
3514
3515 #if 0
3516 // Dump stack top with the dump2 function
3517 static void dump2(lua_State *L, const char *name)
3518 {
3519         // Dump object (debug)
3520         lua_getglobal(L, "dump2");
3521         luaL_checktype(L, -1, LUA_TFUNCTION);
3522         lua_pushvalue(L, -2); // Get previous stack top as first parameter
3523         lua_pushstring(L, name);
3524         if(lua_pcall(L, 2, 0, 0))
3525                 script_error(L, "error: %s", lua_tostring(L, -1));
3526 }
3527 #endif
3528
3529 /*
3530         object_reference
3531 */
3532
3533 void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj)
3534 {
3535         realitycheck(L);
3536         assert(lua_checkstack(L, 20));
3537         //infostream<<"scriptapi_add_object_reference: id="<<cobj->getId()<<std::endl;
3538         StackUnroller stack_unroller(L);
3539
3540         // Create object on stack
3541         ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack
3542         int object = lua_gettop(L);
3543
3544         // Get minetest.object_refs table
3545         lua_getglobal(L, "minetest");
3546         lua_getfield(L, -1, "object_refs");
3547         luaL_checktype(L, -1, LUA_TTABLE);
3548         int objectstable = lua_gettop(L);
3549         
3550         // object_refs[id] = object
3551         lua_pushnumber(L, cobj->getId()); // Push id
3552         lua_pushvalue(L, object); // Copy object to top of stack
3553         lua_settable(L, objectstable);
3554 }
3555
3556 void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj)
3557 {
3558         realitycheck(L);
3559         assert(lua_checkstack(L, 20));
3560         //infostream<<"scriptapi_rm_object_reference: id="<<cobj->getId()<<std::endl;
3561         StackUnroller stack_unroller(L);
3562
3563         // Get minetest.object_refs table
3564         lua_getglobal(L, "minetest");
3565         lua_getfield(L, -1, "object_refs");
3566         luaL_checktype(L, -1, LUA_TTABLE);
3567         int objectstable = lua_gettop(L);
3568         
3569         // Get object_refs[id]
3570         lua_pushnumber(L, cobj->getId()); // Push id
3571         lua_gettable(L, objectstable);
3572         // Set object reference to NULL
3573         ObjectRef::set_null(L);
3574         lua_pop(L, 1); // pop object
3575
3576         // Set object_refs[id] = nil
3577         lua_pushnumber(L, cobj->getId()); // Push id
3578         lua_pushnil(L);
3579         lua_settable(L, objectstable);
3580 }
3581
3582 bool scriptapi_on_chat_message(lua_State *L, const std::string &name,
3583                 const std::string &message)
3584 {
3585         realitycheck(L);
3586         assert(lua_checkstack(L, 20));
3587         StackUnroller stack_unroller(L);
3588
3589         // Get minetest.registered_on_chat_messages
3590         lua_getglobal(L, "minetest");
3591         lua_getfield(L, -1, "registered_on_chat_messages");
3592         luaL_checktype(L, -1, LUA_TTABLE);
3593         int table = lua_gettop(L);
3594         // Foreach
3595         lua_pushnil(L);
3596         while(lua_next(L, table) != 0){
3597                 // key at index -2 and value at index -1
3598                 luaL_checktype(L, -1, LUA_TFUNCTION);
3599                 // Call function
3600                 lua_pushstring(L, name.c_str());
3601                 lua_pushstring(L, message.c_str());
3602                 if(lua_pcall(L, 2, 1, 0))
3603                         script_error(L, "error: %s", lua_tostring(L, -1));
3604                 bool ate = lua_toboolean(L, -1);
3605                 lua_pop(L, 1);
3606                 if(ate)
3607                         return true;
3608                 // value removed, keep key for next iteration
3609         }
3610         return false;
3611 }
3612
3613 /*
3614         misc
3615 */
3616
3617 void scriptapi_on_newplayer(lua_State *L, ServerActiveObject *player)
3618 {
3619         realitycheck(L);
3620         assert(lua_checkstack(L, 20));
3621         StackUnroller stack_unroller(L);
3622
3623         // Get minetest.registered_on_newplayers
3624         lua_getglobal(L, "minetest");
3625         lua_getfield(L, -1, "registered_on_newplayers");
3626         luaL_checktype(L, -1, LUA_TTABLE);
3627         int table = lua_gettop(L);
3628         // Foreach
3629         lua_pushnil(L);
3630         while(lua_next(L, table) != 0){
3631                 // key at index -2 and value at index -1
3632                 luaL_checktype(L, -1, LUA_TFUNCTION);
3633                 // Call function
3634                 objectref_get_or_create(L, player);
3635                 if(lua_pcall(L, 1, 0, 0))
3636                         script_error(L, "error: %s", lua_tostring(L, -1));
3637                 // value removed, keep key for next iteration
3638         }
3639 }
3640 bool scriptapi_on_respawnplayer(lua_State *L, ServerActiveObject *player)
3641 {
3642         realitycheck(L);
3643         assert(lua_checkstack(L, 20));
3644         StackUnroller stack_unroller(L);
3645
3646         bool positioning_handled_by_some = false;
3647
3648         // Get minetest.registered_on_respawnplayers
3649         lua_getglobal(L, "minetest");
3650         lua_getfield(L, -1, "registered_on_respawnplayers");
3651         luaL_checktype(L, -1, LUA_TTABLE);
3652         int table = lua_gettop(L);
3653         // Foreach
3654         lua_pushnil(L);
3655         while(lua_next(L, table) != 0){
3656                 // key at index -2 and value at index -1
3657                 luaL_checktype(L, -1, LUA_TFUNCTION);
3658                 // Call function
3659                 objectref_get_or_create(L, player);
3660                 if(lua_pcall(L, 1, 1, 0))
3661                         script_error(L, "error: %s", lua_tostring(L, -1));
3662                 bool positioning_handled = lua_toboolean(L, -1);
3663                 lua_pop(L, 1);
3664                 if(positioning_handled)
3665                         positioning_handled_by_some = true;
3666                 // value removed, keep key for next iteration
3667         }
3668         return positioning_handled_by_some;
3669 }
3670
3671 void scriptapi_get_creative_inventory(lua_State *L, ServerRemotePlayer *player)
3672 {
3673         lua_getglobal(L, "minetest");
3674         lua_getfield(L, -1, "creative_inventory");
3675         luaL_checktype(L, -1, LUA_TTABLE);
3676         inventory_set_list_from_lua(&player->inventory, "main", L, -1,
3677                         player->getEnv()->getGameDef(), PLAYER_INVENTORY_SIZE);
3678 }
3679
3680 /*
3681         craftitem
3682 */
3683
3684 static void pushPointedThing(lua_State *L, const PointedThing& pointed)
3685 {
3686         lua_newtable(L);
3687         if(pointed.type == POINTEDTHING_NODE)
3688         {
3689                 lua_pushstring(L, "node");
3690                 lua_setfield(L, -2, "type");
3691                 push_v3s16(L, pointed.node_undersurface);
3692                 lua_setfield(L, -2, "under");
3693                 push_v3s16(L, pointed.node_abovesurface);
3694                 lua_setfield(L, -2, "above");
3695         }
3696         else if(pointed.type == POINTEDTHING_OBJECT)
3697         {
3698                 lua_pushstring(L, "object");
3699                 lua_setfield(L, -2, "type");
3700                 objectref_get(L, pointed.object_id);
3701                 lua_setfield(L, -2, "ref");
3702         }
3703         else
3704         {
3705                 lua_pushstring(L, "nothing");
3706                 lua_setfield(L, -2, "type");
3707         }
3708 }
3709
3710 void scriptapi_add_craftitem(lua_State *L, const char *name)
3711 {
3712         StackUnroller stack_unroller(L);
3713         assert(lua_gettop(L) > 0);
3714
3715         // Set minetest.registered_craftitems[name] = table on top of stack
3716         lua_getglobal(L, "minetest");
3717         lua_getfield(L, -1, "registered_craftitems");
3718         luaL_checktype(L, -1, LUA_TTABLE);
3719         lua_pushvalue(L, -3); // push another reference to the table to be registered
3720         lua_setfield(L, -2, name); // set minetest.registered_craftitems[name]
3721 }
3722
3723 static bool get_craftitem_callback(lua_State *L, const char *name,
3724                 const char *callbackname)
3725 {
3726         // Get minetest.registered_craftitems[name][callbackname]
3727         // If that is nil or on error, return false and stack is unchanged
3728         // If that is a function, returns true and pushes the
3729         // function onto the stack
3730
3731         lua_getglobal(L, "minetest");
3732         lua_getfield(L, -1, "registered_craftitems");
3733         lua_remove(L, -2);
3734         luaL_checktype(L, -1, LUA_TTABLE);
3735         lua_getfield(L, -1, name);
3736         lua_remove(L, -2);
3737         // Should be a table
3738         if(lua_type(L, -1) != LUA_TTABLE)
3739         {
3740                 errorstream<<"CraftItem name \""<<name<<"\" not defined"<<std::endl;
3741                 lua_pop(L, 1);
3742                 return false;
3743         }
3744         lua_getfield(L, -1, callbackname);
3745         lua_remove(L, -2);
3746         // Should be a function or nil
3747         if(lua_type(L, -1) == LUA_TFUNCTION)
3748         {
3749                 return true;
3750         }
3751         else if(lua_isnil(L, -1))
3752         {
3753                 lua_pop(L, 1);
3754                 return false;
3755         }
3756         else
3757         {
3758                 errorstream<<"CraftItem name \""<<name<<"\" callback \""
3759                         <<callbackname<<" is not a function"<<std::endl;
3760                 lua_pop(L, 1);
3761                 return false;
3762         }
3763 }
3764
3765 bool scriptapi_craftitem_on_drop(lua_State *L, const char *name,
3766                 ServerActiveObject *dropper, v3f pos,
3767                 bool &callback_exists)
3768 {
3769         realitycheck(L);
3770         assert(lua_checkstack(L, 20));
3771         //infostream<<"scriptapi_craftitem_on_drop"<<std::endl;
3772         StackUnroller stack_unroller(L);
3773
3774         bool result = false;
3775         callback_exists = get_craftitem_callback(L, name, "on_drop");
3776         if(callback_exists)
3777         {
3778                 // Call function
3779                 lua_pushstring(L, name);
3780                 objectref_get_or_create(L, dropper);
3781                 pushFloatPos(L, pos);
3782                 if(lua_pcall(L, 3, 1, 0))
3783                         script_error(L, "error: %s", lua_tostring(L, -1));
3784                 result = lua_toboolean(L, -1);
3785         }
3786         return result;
3787 }
3788
3789 bool scriptapi_craftitem_on_place_on_ground(lua_State *L, const char *name,
3790                 ServerActiveObject *placer, v3f pos,
3791                 bool &callback_exists)
3792 {
3793         realitycheck(L);
3794         assert(lua_checkstack(L, 20));
3795         //infostream<<"scriptapi_craftitem_on_place_on_ground"<<std::endl;
3796         StackUnroller stack_unroller(L);
3797
3798         bool result = false;
3799         callback_exists = get_craftitem_callback(L, name, "on_place_on_ground");
3800         if(callback_exists)
3801         {
3802                 // Call function
3803                 lua_pushstring(L, name);
3804                 objectref_get_or_create(L, placer);
3805                 pushFloatPos(L, pos);
3806                 if(lua_pcall(L, 3, 1, 0))
3807                         script_error(L, "error: %s", lua_tostring(L, -1));
3808                 result = lua_toboolean(L, -1);
3809         }
3810         return result;
3811 }
3812
3813 bool scriptapi_craftitem_on_use(lua_State *L, const char *name,
3814                 ServerActiveObject *user, const PointedThing& pointed,
3815                 bool &callback_exists)
3816 {
3817         realitycheck(L);
3818         assert(lua_checkstack(L, 20));
3819         //infostream<<"scriptapi_craftitem_on_use"<<std::endl;
3820         StackUnroller stack_unroller(L);
3821
3822         bool result = false;
3823         callback_exists = get_craftitem_callback(L, name, "on_use");
3824         if(callback_exists)
3825         {
3826                 // Call function
3827                 lua_pushstring(L, name);
3828                 objectref_get_or_create(L, user);
3829                 pushPointedThing(L, pointed);
3830                 if(lua_pcall(L, 3, 1, 0))
3831                         script_error(L, "error: %s", lua_tostring(L, -1));
3832                 result = lua_toboolean(L, -1);
3833         }
3834         return result;
3835 }
3836
3837 /*
3838         environment
3839 */
3840
3841 void scriptapi_environment_step(lua_State *L, float dtime)
3842 {
3843         realitycheck(L);
3844         assert(lua_checkstack(L, 20));
3845         //infostream<<"scriptapi_environment_step"<<std::endl;
3846         StackUnroller stack_unroller(L);
3847
3848         // Get minetest.registered_globalsteps
3849         lua_getglobal(L, "minetest");
3850         lua_getfield(L, -1, "registered_globalsteps");
3851         luaL_checktype(L, -1, LUA_TTABLE);
3852         int table = lua_gettop(L);
3853         // Foreach
3854         lua_pushnil(L);
3855         while(lua_next(L, table) != 0){
3856                 // key at index -2 and value at index -1
3857                 luaL_checktype(L, -1, LUA_TFUNCTION);
3858                 // Call function
3859                 lua_pushnumber(L, dtime);
3860                 if(lua_pcall(L, 1, 0, 0))
3861                         script_error(L, "error: %s", lua_tostring(L, -1));
3862                 // value removed, keep key for next iteration
3863         }
3864 }
3865
3866 void scriptapi_environment_on_placenode(lua_State *L, v3s16 p, MapNode newnode,
3867                 ServerActiveObject *placer)
3868 {
3869         realitycheck(L);
3870         assert(lua_checkstack(L, 20));
3871         //infostream<<"scriptapi_environment_on_placenode"<<std::endl;
3872         StackUnroller stack_unroller(L);
3873
3874         // Get the writable node definition manager from the server
3875         IWritableNodeDefManager *ndef =
3876                         get_server(L)->getWritableNodeDefManager();
3877         
3878         // Get minetest.registered_on_placenodes
3879         lua_getglobal(L, "minetest");
3880         lua_getfield(L, -1, "registered_on_placenodes");
3881         luaL_checktype(L, -1, LUA_TTABLE);
3882         int table = lua_gettop(L);
3883         // Foreach
3884         lua_pushnil(L);
3885         while(lua_next(L, table) != 0){
3886                 // key at index -2 and value at index -1
3887                 luaL_checktype(L, -1, LUA_TFUNCTION);
3888                 // Call function
3889                 push_v3s16(L, p);
3890                 pushnode(L, newnode, ndef);
3891                 objectref_get_or_create(L, placer);
3892                 if(lua_pcall(L, 3, 0, 0))
3893                         script_error(L, "error: %s", lua_tostring(L, -1));
3894                 // value removed, keep key for next iteration
3895         }
3896 }
3897
3898 void scriptapi_environment_on_dignode(lua_State *L, v3s16 p, MapNode oldnode,
3899                 ServerActiveObject *digger)
3900 {
3901         realitycheck(L);
3902         assert(lua_checkstack(L, 20));
3903         //infostream<<"scriptapi_environment_on_dignode"<<std::endl;
3904         StackUnroller stack_unroller(L);
3905
3906         // Get the writable node definition manager from the server
3907         IWritableNodeDefManager *ndef =
3908                         get_server(L)->getWritableNodeDefManager();
3909         
3910         // Get minetest.registered_on_dignodes
3911         lua_getglobal(L, "minetest");
3912         lua_getfield(L, -1, "registered_on_dignodes");
3913         luaL_checktype(L, -1, LUA_TTABLE);
3914         int table = lua_gettop(L);
3915         // Foreach
3916         lua_pushnil(L);
3917         while(lua_next(L, table) != 0){
3918                 // key at index -2 and value at index -1
3919                 luaL_checktype(L, -1, LUA_TFUNCTION);
3920                 // Call function
3921                 push_v3s16(L, p);
3922                 pushnode(L, oldnode, ndef);
3923                 objectref_get_or_create(L, digger);
3924                 if(lua_pcall(L, 3, 0, 0))
3925                         script_error(L, "error: %s", lua_tostring(L, -1));
3926                 // value removed, keep key for next iteration
3927         }
3928 }
3929
3930 void scriptapi_environment_on_punchnode(lua_State *L, v3s16 p, MapNode node,
3931                 ServerActiveObject *puncher)
3932 {
3933         realitycheck(L);
3934         assert(lua_checkstack(L, 20));
3935         //infostream<<"scriptapi_environment_on_punchnode"<<std::endl;
3936         StackUnroller stack_unroller(L);
3937
3938         // Get the writable node definition manager from the server
3939         IWritableNodeDefManager *ndef =
3940                         get_server(L)->getWritableNodeDefManager();
3941         
3942         // Get minetest.registered_on_punchnodes
3943         lua_getglobal(L, "minetest");
3944         lua_getfield(L, -1, "registered_on_punchnodes");
3945         luaL_checktype(L, -1, LUA_TTABLE);
3946         int table = lua_gettop(L);
3947         // Foreach
3948         lua_pushnil(L);
3949         while(lua_next(L, table) != 0){
3950                 // key at index -2 and value at index -1
3951                 luaL_checktype(L, -1, LUA_TFUNCTION);
3952                 // Call function
3953                 push_v3s16(L, p);
3954                 pushnode(L, node, ndef);
3955                 objectref_get_or_create(L, puncher);
3956                 if(lua_pcall(L, 3, 0, 0))
3957                         script_error(L, "error: %s", lua_tostring(L, -1));
3958                 // value removed, keep key for next iteration
3959         }
3960 }
3961
3962 void scriptapi_environment_on_generated(lua_State *L, v3s16 minp, v3s16 maxp)
3963 {
3964         realitycheck(L);
3965         assert(lua_checkstack(L, 20));
3966         //infostream<<"scriptapi_environment_on_generated"<<std::endl;
3967         StackUnroller stack_unroller(L);
3968
3969         // Get minetest.registered_on_generateds
3970         lua_getglobal(L, "minetest");
3971         lua_getfield(L, -1, "registered_on_generateds");
3972         luaL_checktype(L, -1, LUA_TTABLE);
3973         int table = lua_gettop(L);
3974         // Foreach
3975         lua_pushnil(L);
3976         while(lua_next(L, table) != 0){
3977                 // key at index -2 and value at index -1
3978                 luaL_checktype(L, -1, LUA_TFUNCTION);
3979                 // Call function
3980                 push_v3s16(L, minp);
3981                 push_v3s16(L, maxp);
3982                 if(lua_pcall(L, 2, 0, 0))
3983                         script_error(L, "error: %s", lua_tostring(L, -1));
3984                 // value removed, keep key for next iteration
3985         }
3986 }
3987
3988 /*
3989         luaentity
3990 */
3991
3992 bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
3993                 const std::string &staticdata)
3994 {
3995         realitycheck(L);
3996         assert(lua_checkstack(L, 20));
3997         infostream<<"scriptapi_luaentity_add: id="<<id<<" name=\""
3998                         <<name<<"\""<<std::endl;
3999         StackUnroller stack_unroller(L);
4000         
4001         // Get minetest.registered_entities[name]
4002         lua_getglobal(L, "minetest");
4003         lua_getfield(L, -1, "registered_entities");
4004         luaL_checktype(L, -1, LUA_TTABLE);
4005         lua_pushstring(L, name);
4006         lua_gettable(L, -2);
4007         // Should be a table, which we will use as a prototype
4008         //luaL_checktype(L, -1, LUA_TTABLE);
4009         if(lua_type(L, -1) != LUA_TTABLE){
4010                 errorstream<<"LuaEntity name \""<<name<<"\" not defined"<<std::endl;
4011                 return false;
4012         }
4013         int prototype_table = lua_gettop(L);
4014         //dump2(L, "prototype_table");
4015         
4016         // Create entity object
4017         lua_newtable(L);
4018         int object = lua_gettop(L);
4019
4020         // Set object metatable
4021         lua_pushvalue(L, prototype_table);
4022         lua_setmetatable(L, -2);
4023         
4024         // Add object reference
4025         // This should be userdata with metatable ObjectRef
4026         objectref_get(L, id);
4027         luaL_checktype(L, -1, LUA_TUSERDATA);
4028         if(!luaL_checkudata(L, -1, "ObjectRef"))
4029                 luaL_typerror(L, -1, "ObjectRef");
4030         lua_setfield(L, -2, "object");
4031
4032         // minetest.luaentities[id] = object
4033         lua_getglobal(L, "minetest");
4034         lua_getfield(L, -1, "luaentities");
4035         luaL_checktype(L, -1, LUA_TTABLE);
4036         lua_pushnumber(L, id); // Push id
4037         lua_pushvalue(L, object); // Copy object to top of stack
4038         lua_settable(L, -3);
4039         
4040         // Get on_activate function
4041         lua_pushvalue(L, object);
4042         lua_getfield(L, -1, "on_activate");
4043         if(!lua_isnil(L, -1)){
4044                 luaL_checktype(L, -1, LUA_TFUNCTION);
4045                 lua_pushvalue(L, object); // self
4046                 lua_pushlstring(L, staticdata.c_str(), staticdata.size());
4047                 // Call with 2 arguments, 0 results
4048                 if(lua_pcall(L, 2, 0, 0))
4049                         script_error(L, "error running function %s:on_activate: %s\n",
4050                                         name, lua_tostring(L, -1));
4051         }
4052         
4053         return true;
4054 }
4055
4056 void scriptapi_luaentity_rm(lua_State *L, u16 id)
4057 {
4058         realitycheck(L);
4059         assert(lua_checkstack(L, 20));
4060         infostream<<"scriptapi_luaentity_rm: id="<<id<<std::endl;
4061
4062         // Get minetest.luaentities table
4063         lua_getglobal(L, "minetest");
4064         lua_getfield(L, -1, "luaentities");
4065         luaL_checktype(L, -1, LUA_TTABLE);
4066         int objectstable = lua_gettop(L);
4067         
4068         // Set luaentities[id] = nil
4069         lua_pushnumber(L, id); // Push id
4070         lua_pushnil(L);
4071         lua_settable(L, objectstable);
4072         
4073         lua_pop(L, 2); // pop luaentities, minetest
4074 }
4075
4076 std::string scriptapi_luaentity_get_staticdata(lua_State *L, u16 id)
4077 {
4078         realitycheck(L);
4079         assert(lua_checkstack(L, 20));
4080         infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl;
4081         StackUnroller stack_unroller(L);
4082
4083         // Get minetest.luaentities[id]
4084         luaentity_get(L, id);
4085         int object = lua_gettop(L);
4086         
4087         // Get get_staticdata function
4088         lua_pushvalue(L, object);
4089         lua_getfield(L, -1, "get_staticdata");
4090         if(lua_isnil(L, -1))
4091                 return "";
4092         
4093         luaL_checktype(L, -1, LUA_TFUNCTION);
4094         lua_pushvalue(L, object); // self
4095         // Call with 1 arguments, 1 results
4096         if(lua_pcall(L, 1, 1, 0))
4097                 script_error(L, "error running function get_staticdata: %s\n",
4098                                 lua_tostring(L, -1));
4099         
4100         size_t len=0;
4101         const char *s = lua_tolstring(L, -1, &len);
4102         return std::string(s, len);
4103 }
4104
4105 void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
4106                 LuaEntityProperties *prop)
4107 {
4108         realitycheck(L);
4109         assert(lua_checkstack(L, 20));
4110         infostream<<"scriptapi_luaentity_get_properties: id="<<id<<std::endl;
4111         StackUnroller stack_unroller(L);
4112
4113         // Get minetest.luaentities[id]
4114         luaentity_get(L, id);
4115         //int object = lua_gettop(L);
4116
4117         /* Read stuff */
4118         
4119         getboolfield(L, -1, "physical", prop->physical);
4120
4121         getfloatfield(L, -1, "weight", prop->weight);
4122
4123         lua_getfield(L, -1, "collisionbox");
4124         if(lua_istable(L, -1))
4125                 prop->collisionbox = read_aabbox3df32(L, -1, 1.0);
4126         lua_pop(L, 1);
4127
4128         getstringfield(L, -1, "visual", prop->visual);
4129         
4130         lua_getfield(L, -1, "visual_size");
4131         if(lua_istable(L, -1))
4132                 prop->visual_size = read_v2f(L, -1);
4133         lua_pop(L, 1);
4134
4135         lua_getfield(L, -1, "textures");
4136         if(lua_istable(L, -1)){
4137                 prop->textures.clear();
4138                 int table = lua_gettop(L);
4139                 lua_pushnil(L);
4140                 while(lua_next(L, table) != 0){
4141                         // key at index -2 and value at index -1
4142                         if(lua_isstring(L, -1))
4143                                 prop->textures.push_back(lua_tostring(L, -1));
4144                         else
4145                                 prop->textures.push_back("");
4146                         // removes value, keeps key for next iteration
4147                         lua_pop(L, 1);
4148                 }
4149         }
4150         lua_pop(L, 1);
4151         
4152         lua_getfield(L, -1, "spritediv");
4153         if(lua_istable(L, -1))
4154                 prop->spritediv = read_v2s16(L, -1);
4155         lua_pop(L, 1);
4156
4157         lua_getfield(L, -1, "initial_sprite_basepos");
4158         if(lua_istable(L, -1))
4159                 prop->initial_sprite_basepos = read_v2s16(L, -1);
4160         lua_pop(L, 1);
4161 }
4162
4163 void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime)
4164 {
4165         realitycheck(L);
4166         assert(lua_checkstack(L, 20));
4167         //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
4168         StackUnroller stack_unroller(L);
4169
4170         // Get minetest.luaentities[id]
4171         luaentity_get(L, id);
4172         int object = lua_gettop(L);
4173         // State: object is at top of stack
4174         // Get step function
4175         lua_getfield(L, -1, "on_step");
4176         if(lua_isnil(L, -1))
4177                 return;
4178         luaL_checktype(L, -1, LUA_TFUNCTION);
4179         lua_pushvalue(L, object); // self
4180         lua_pushnumber(L, dtime); // dtime
4181         // Call with 2 arguments, 0 results
4182         if(lua_pcall(L, 2, 0, 0))
4183                 script_error(L, "error running function 'on_step': %s\n", lua_tostring(L, -1));
4184 }
4185
4186 // Calls entity:on_punch(ObjectRef puncher, time_from_last_punch)
4187 void scriptapi_luaentity_punch(lua_State *L, u16 id,
4188                 ServerActiveObject *puncher, float time_from_last_punch)
4189 {
4190         realitycheck(L);
4191         assert(lua_checkstack(L, 20));
4192         //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
4193         StackUnroller stack_unroller(L);
4194
4195         // Get minetest.luaentities[id]
4196         luaentity_get(L, id);
4197         int object = lua_gettop(L);
4198         // State: object is at top of stack
4199         // Get function
4200         lua_getfield(L, -1, "on_punch");
4201         if(lua_isnil(L, -1))
4202                 return;
4203         luaL_checktype(L, -1, LUA_TFUNCTION);
4204         lua_pushvalue(L, object); // self
4205         objectref_get_or_create(L, puncher); // Clicker reference
4206         lua_pushnumber(L, time_from_last_punch);
4207         // Call with 2 arguments, 0 results
4208         if(lua_pcall(L, 3, 0, 0))
4209                 script_error(L, "error running function 'on_punch': %s\n", lua_tostring(L, -1));
4210 }
4211
4212 // Calls entity:on_rightclick(ObjectRef clicker)
4213 void scriptapi_luaentity_rightclick(lua_State *L, u16 id,
4214                 ServerActiveObject *clicker)
4215 {
4216         realitycheck(L);
4217         assert(lua_checkstack(L, 20));
4218         //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
4219         StackUnroller stack_unroller(L);
4220
4221         // Get minetest.luaentities[id]
4222         luaentity_get(L, id);
4223         int object = lua_gettop(L);
4224         // State: object is at top of stack
4225         // Get function
4226         lua_getfield(L, -1, "on_rightclick");
4227         if(lua_isnil(L, -1))
4228                 return;
4229         luaL_checktype(L, -1, LUA_TFUNCTION);
4230         lua_pushvalue(L, object); // self
4231         objectref_get_or_create(L, clicker); // Clicker reference
4232         // Call with 2 arguments, 0 results
4233         if(lua_pcall(L, 2, 0, 0))
4234                 script_error(L, "error running function 'on_rightclick': %s\n", lua_tostring(L, -1));
4235 }
4236