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