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