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