7eda636e39163aa26bc769695d410858a5a7924c
[oweals/minetest.git] / src / scriptapi.cpp
1 /*
2 Minetest-c55
3 Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser 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 "object_properties.h"
37 #include "content_sao.h" // For LuaEntitySAO and PlayerSAO
38 #include "itemdef.h"
39 #include "nodedef.h"
40 #include "craftdef.h"
41 #include "main.h" // For g_settings
42 #include "settings.h" // For accessing g_settings
43 #include "nodemetadata.h"
44 #include "mapblock.h" // For getNodeBlockPos
45 #include "content_nodemeta.h"
46 #include "tool.h"
47 #include "daynightratio.h"
48 #include "noise.h" // PseudoRandom for LuaPseudoRandom
49 #include "util/pointedthing.h"
50 #include "rollback.h"
51
52 static void stackDump(lua_State *L, std::ostream &o)
53 {
54   int i;
55   int top = lua_gettop(L);
56   for (i = 1; i <= top; i++) {  /* repeat for each level */
57         int t = lua_type(L, i);
58         switch (t) {
59
60           case LUA_TSTRING:  /* strings */
61                 o<<"\""<<lua_tostring(L, i)<<"\"";
62                 break;
63
64           case LUA_TBOOLEAN:  /* booleans */
65                 o<<(lua_toboolean(L, i) ? "true" : "false");
66                 break;
67
68           case LUA_TNUMBER:  /* numbers */ {
69                 char buf[10];
70                 snprintf(buf, 10, "%g", lua_tonumber(L, i));
71                 o<<buf;
72                 break; }
73
74           default:  /* other values */
75                 o<<lua_typename(L, t);
76                 break;
77
78         }
79         o<<" ";
80   }
81   o<<std::endl;
82 }
83
84 static void realitycheck(lua_State *L)
85 {
86         int top = lua_gettop(L);
87         if(top >= 30){
88                 dstream<<"Stack is over 30:"<<std::endl;
89                 stackDump(L, dstream);
90                 script_error(L, "Stack is over 30 (reality check)");
91         }
92 }
93
94 class StackUnroller
95 {
96 private:
97         lua_State *m_lua;
98         int m_original_top;
99 public:
100         StackUnroller(lua_State *L):
101                 m_lua(L),
102                 m_original_top(-1)
103         {
104                 m_original_top = lua_gettop(m_lua); // store stack height
105         }
106         ~StackUnroller()
107         {
108                 lua_settop(m_lua, m_original_top); // restore stack height
109         }
110 };
111
112 class ModNameStorer
113 {
114 private:
115         lua_State *L;
116 public:
117         ModNameStorer(lua_State *L_, const std::string modname):
118                 L(L_)
119         {
120                 // Store current modname in registry
121                 lua_pushstring(L, modname.c_str());
122                 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
123         }
124         ~ModNameStorer()
125         {
126                 // Clear current modname in registry
127                 lua_pushnil(L);
128                 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
129         }
130 };
131
132 /*
133         Getters for stuff in main tables
134 */
135
136 static Server* get_server(lua_State *L)
137 {
138         // Get server from registry
139         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
140         Server *server = (Server*)lua_touserdata(L, -1);
141         lua_pop(L, 1);
142         return server;
143 }
144
145 static ServerEnvironment* get_env(lua_State *L)
146 {
147         // Get environment from registry
148         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_env");
149         ServerEnvironment *env = (ServerEnvironment*)lua_touserdata(L, -1);
150         lua_pop(L, 1);
151         return env;
152 }
153
154 static void objectref_get(lua_State *L, u16 id)
155 {
156         // Get minetest.object_refs[i]
157         lua_getglobal(L, "minetest");
158         lua_getfield(L, -1, "object_refs");
159         luaL_checktype(L, -1, LUA_TTABLE);
160         lua_pushnumber(L, id);
161         lua_gettable(L, -2);
162         lua_remove(L, -2); // object_refs
163         lua_remove(L, -2); // minetest
164 }
165
166 static void luaentity_get(lua_State *L, u16 id)
167 {
168         // Get minetest.luaentities[i]
169         lua_getglobal(L, "minetest");
170         lua_getfield(L, -1, "luaentities");
171         luaL_checktype(L, -1, LUA_TTABLE);
172         lua_pushnumber(L, id);
173         lua_gettable(L, -2);
174         lua_remove(L, -2); // luaentities
175         lua_remove(L, -2); // minetest
176 }
177
178 /*
179         Table field getters
180 */
181
182 static bool getstringfield(lua_State *L, int table,
183                 const char *fieldname, std::string &result)
184 {
185         lua_getfield(L, table, fieldname);
186         bool got = false;
187         if(lua_isstring(L, -1)){
188                 size_t len = 0;
189                 const char *ptr = lua_tolstring(L, -1, &len);
190                 result.assign(ptr, len);
191                 got = true;
192         }
193         lua_pop(L, 1);
194         return got;
195 }
196
197 static bool getintfield(lua_State *L, int table,
198                 const char *fieldname, int &result)
199 {
200         lua_getfield(L, table, fieldname);
201         bool got = false;
202         if(lua_isnumber(L, -1)){
203                 result = lua_tonumber(L, -1);
204                 got = true;
205         }
206         lua_pop(L, 1);
207         return got;
208 }
209
210 static bool getfloatfield(lua_State *L, int table,
211                 const char *fieldname, float &result)
212 {
213         lua_getfield(L, table, fieldname);
214         bool got = false;
215         if(lua_isnumber(L, -1)){
216                 result = lua_tonumber(L, -1);
217                 got = true;
218         }
219         lua_pop(L, 1);
220         return got;
221 }
222
223 static bool getboolfield(lua_State *L, int table,
224                 const char *fieldname, bool &result)
225 {
226         lua_getfield(L, table, fieldname);
227         bool got = false;
228         if(lua_isboolean(L, -1)){
229                 result = lua_toboolean(L, -1);
230                 got = true;
231         }
232         lua_pop(L, 1);
233         return got;
234 }
235
236 static std::string checkstringfield(lua_State *L, int table,
237                 const char *fieldname)
238 {
239         lua_getfield(L, table, fieldname);
240         std::string s = luaL_checkstring(L, -1);
241         lua_pop(L, 1);
242         return s;
243 }
244
245 static std::string getstringfield_default(lua_State *L, int table,
246                 const char *fieldname, const std::string &default_)
247 {
248         std::string result = default_;
249         getstringfield(L, table, fieldname, result);
250         return result;
251 }
252
253 static int getintfield_default(lua_State *L, int table,
254                 const char *fieldname, int default_)
255 {
256         int result = default_;
257         getintfield(L, table, fieldname, result);
258         return result;
259 }
260
261 static float getfloatfield_default(lua_State *L, int table,
262                 const char *fieldname, float default_)
263 {
264         float result = default_;
265         getfloatfield(L, table, fieldname, result);
266         return result;
267 }
268
269 static bool getboolfield_default(lua_State *L, int table,
270                 const char *fieldname, bool default_)
271 {
272         bool result = default_;
273         getboolfield(L, table, fieldname, result);
274         return result;
275 }
276
277 struct EnumString
278 {
279         int num;
280         const char *str;
281 };
282
283 static bool string_to_enum(const EnumString *spec, int &result,
284                 const std::string &str)
285 {
286         const EnumString *esp = spec;
287         while(esp->str){
288                 if(str == std::string(esp->str)){
289                         result = esp->num;
290                         return true;
291                 }
292                 esp++;
293         }
294         return false;
295 }
296
297 /*static bool enum_to_string(const EnumString *spec, std::string &result,
298                 int num)
299 {
300         const EnumString *esp = spec;
301         while(esp){
302                 if(num == esp->num){
303                         result = esp->str;
304                         return true;
305                 }
306                 esp++;
307         }
308         return false;
309 }*/
310
311 static int getenumfield(lua_State *L, int table,
312                 const char *fieldname, const EnumString *spec, int default_)
313 {
314         int result = default_;
315         string_to_enum(spec, result,
316                         getstringfield_default(L, table, fieldname, ""));
317         return result;
318 }
319
320 static void setintfield(lua_State *L, int table,
321                 const char *fieldname, int value)
322 {
323         lua_pushinteger(L, value);
324         if(table < 0)
325                 table -= 1;
326         lua_setfield(L, table, fieldname);
327 }
328
329 static void setfloatfield(lua_State *L, int table,
330                 const char *fieldname, float value)
331 {
332         lua_pushnumber(L, value);
333         if(table < 0)
334                 table -= 1;
335         lua_setfield(L, table, fieldname);
336 }
337
338 static void setboolfield(lua_State *L, int table,
339                 const char *fieldname, bool value)
340 {
341         lua_pushboolean(L, value);
342         if(table < 0)
343                 table -= 1;
344         lua_setfield(L, table, fieldname);
345 }
346
347 static void warn_if_field_exists(lua_State *L, int table,
348                 const char *fieldname, const std::string &message)
349 {
350         lua_getfield(L, table, fieldname);
351         if(!lua_isnil(L, -1)){
352                 infostream<<script_get_backtrace(L)<<std::endl;
353                 infostream<<"WARNING: field \""<<fieldname<<"\": "
354                                 <<message<<std::endl;
355         }
356         lua_pop(L, 1);
357 }
358
359 /*
360         EnumString definitions
361 */
362
363 struct EnumString es_ItemType[] =
364 {
365         {ITEM_NONE, "none"},
366         {ITEM_NODE, "node"},
367         {ITEM_CRAFT, "craft"},
368         {ITEM_TOOL, "tool"},
369         {0, NULL},
370 };
371
372 struct EnumString es_DrawType[] =
373 {
374         {NDT_NORMAL, "normal"},
375         {NDT_AIRLIKE, "airlike"},
376         {NDT_LIQUID, "liquid"},
377         {NDT_FLOWINGLIQUID, "flowingliquid"},
378         {NDT_GLASSLIKE, "glasslike"},
379         {NDT_ALLFACES, "allfaces"},
380         {NDT_ALLFACES_OPTIONAL, "allfaces_optional"},
381         {NDT_TORCHLIKE, "torchlike"},
382         {NDT_SIGNLIKE, "signlike"},
383         {NDT_PLANTLIKE, "plantlike"},
384         {NDT_FENCELIKE, "fencelike"},
385         {NDT_RAILLIKE, "raillike"},
386         {NDT_NODEBOX, "nodebox"},
387         {0, NULL},
388 };
389
390 struct EnumString es_ContentParamType[] =
391 {
392         {CPT_NONE, "none"},
393         {CPT_LIGHT, "light"},
394         {0, NULL},
395 };
396
397 struct EnumString es_ContentParamType2[] =
398 {
399         {CPT2_NONE, "none"},
400         {CPT2_FULL, "full"},
401         {CPT2_FLOWINGLIQUID, "flowingliquid"},
402         {CPT2_FACEDIR, "facedir"},
403         {CPT2_WALLMOUNTED, "wallmounted"},
404         {0, NULL},
405 };
406
407 struct EnumString es_LiquidType[] =
408 {
409         {LIQUID_NONE, "none"},
410         {LIQUID_FLOWING, "flowing"},
411         {LIQUID_SOURCE, "source"},
412         {0, NULL},
413 };
414
415 struct EnumString es_NodeBoxType[] =
416 {
417         {NODEBOX_REGULAR, "regular"},
418         {NODEBOX_FIXED, "fixed"},
419         {NODEBOX_WALLMOUNTED, "wallmounted"},
420         {0, NULL},
421 };
422
423 struct EnumString es_CraftMethod[] =
424 {
425         {CRAFT_METHOD_NORMAL, "normal"},
426         {CRAFT_METHOD_COOKING, "cooking"},
427         {CRAFT_METHOD_FUEL, "fuel"},
428         {0, NULL},
429 };
430
431 struct EnumString es_TileAnimationType[] =
432 {
433         {TAT_NONE, "none"},
434         {TAT_VERTICAL_FRAMES, "vertical_frames"},
435         {0, NULL},
436 };
437
438 /*
439         C struct <-> Lua table converter functions
440 */
441
442 static void push_v3f(lua_State *L, v3f p)
443 {
444         lua_newtable(L);
445         lua_pushnumber(L, p.X);
446         lua_setfield(L, -2, "x");
447         lua_pushnumber(L, p.Y);
448         lua_setfield(L, -2, "y");
449         lua_pushnumber(L, p.Z);
450         lua_setfield(L, -2, "z");
451 }
452
453 static v2s16 read_v2s16(lua_State *L, int index)
454 {
455         v2s16 p;
456         luaL_checktype(L, index, LUA_TTABLE);
457         lua_getfield(L, index, "x");
458         p.X = lua_tonumber(L, -1);
459         lua_pop(L, 1);
460         lua_getfield(L, index, "y");
461         p.Y = lua_tonumber(L, -1);
462         lua_pop(L, 1);
463         return p;
464 }
465
466 static v2f read_v2f(lua_State *L, int index)
467 {
468         v2f p;
469         luaL_checktype(L, index, LUA_TTABLE);
470         lua_getfield(L, index, "x");
471         p.X = lua_tonumber(L, -1);
472         lua_pop(L, 1);
473         lua_getfield(L, index, "y");
474         p.Y = lua_tonumber(L, -1);
475         lua_pop(L, 1);
476         return p;
477 }
478
479 static v3f read_v3f(lua_State *L, int index)
480 {
481         v3f pos;
482         luaL_checktype(L, index, LUA_TTABLE);
483         lua_getfield(L, index, "x");
484         pos.X = lua_tonumber(L, -1);
485         lua_pop(L, 1);
486         lua_getfield(L, index, "y");
487         pos.Y = lua_tonumber(L, -1);
488         lua_pop(L, 1);
489         lua_getfield(L, index, "z");
490         pos.Z = lua_tonumber(L, -1);
491         lua_pop(L, 1);
492         return pos;
493 }
494
495 static v3f check_v3f(lua_State *L, int index)
496 {
497         v3f pos;
498         luaL_checktype(L, index, LUA_TTABLE);
499         lua_getfield(L, index, "x");
500         pos.X = luaL_checknumber(L, -1);
501         lua_pop(L, 1);
502         lua_getfield(L, index, "y");
503         pos.Y = luaL_checknumber(L, -1);
504         lua_pop(L, 1);
505         lua_getfield(L, index, "z");
506         pos.Z = luaL_checknumber(L, -1);
507         lua_pop(L, 1);
508         return pos;
509 }
510
511 static void pushFloatPos(lua_State *L, v3f p)
512 {
513         p /= BS;
514         push_v3f(L, p);
515 }
516
517 static v3f checkFloatPos(lua_State *L, int index)
518 {
519         return check_v3f(L, index) * BS;
520 }
521
522 static void push_v3s16(lua_State *L, v3s16 p)
523 {
524         lua_newtable(L);
525         lua_pushnumber(L, p.X);
526         lua_setfield(L, -2, "x");
527         lua_pushnumber(L, p.Y);
528         lua_setfield(L, -2, "y");
529         lua_pushnumber(L, p.Z);
530         lua_setfield(L, -2, "z");
531 }
532
533 static v3s16 read_v3s16(lua_State *L, int index)
534 {
535         // Correct rounding at <0
536         v3f pf = read_v3f(L, index);
537         return floatToInt(pf, 1.0);
538 }
539
540 static v3s16 check_v3s16(lua_State *L, int index)
541 {
542         // Correct rounding at <0
543         v3f pf = check_v3f(L, index);
544         return floatToInt(pf, 1.0);
545 }
546
547 static void pushnode(lua_State *L, const MapNode &n, INodeDefManager *ndef)
548 {
549         lua_newtable(L);
550         lua_pushstring(L, ndef->get(n).name.c_str());
551         lua_setfield(L, -2, "name");
552         lua_pushnumber(L, n.getParam1());
553         lua_setfield(L, -2, "param1");
554         lua_pushnumber(L, n.getParam2());
555         lua_setfield(L, -2, "param2");
556 }
557
558 static MapNode readnode(lua_State *L, int index, INodeDefManager *ndef)
559 {
560         lua_getfield(L, index, "name");
561         const char *name = luaL_checkstring(L, -1);
562         lua_pop(L, 1);
563         u8 param1;
564         lua_getfield(L, index, "param1");
565         if(lua_isnil(L, -1))
566                 param1 = 0;
567         else
568                 param1 = lua_tonumber(L, -1);
569         lua_pop(L, 1);
570         u8 param2;
571         lua_getfield(L, index, "param2");
572         if(lua_isnil(L, -1))
573                 param2 = 0;
574         else
575                 param2 = lua_tonumber(L, -1);
576         lua_pop(L, 1);
577         return MapNode(ndef, name, param1, param2);
578 }
579
580 static video::SColor readARGB8(lua_State *L, int index)
581 {
582         video::SColor color;
583         luaL_checktype(L, index, LUA_TTABLE);
584         lua_getfield(L, index, "a");
585         if(lua_isnumber(L, -1))
586                 color.setAlpha(lua_tonumber(L, -1));
587         lua_pop(L, 1);
588         lua_getfield(L, index, "r");
589         color.setRed(lua_tonumber(L, -1));
590         lua_pop(L, 1);
591         lua_getfield(L, index, "g");
592         color.setGreen(lua_tonumber(L, -1));
593         lua_pop(L, 1);
594         lua_getfield(L, index, "b");
595         color.setBlue(lua_tonumber(L, -1));
596         lua_pop(L, 1);
597         return color;
598 }
599
600 static aabb3f read_aabb3f(lua_State *L, int index, f32 scale)
601 {
602         aabb3f box;
603         if(lua_istable(L, index)){
604                 lua_rawgeti(L, index, 1);
605                 box.MinEdge.X = lua_tonumber(L, -1) * scale;
606                 lua_pop(L, 1);
607                 lua_rawgeti(L, index, 2);
608                 box.MinEdge.Y = lua_tonumber(L, -1) * scale;
609                 lua_pop(L, 1);
610                 lua_rawgeti(L, index, 3);
611                 box.MinEdge.Z = lua_tonumber(L, -1) * scale;
612                 lua_pop(L, 1);
613                 lua_rawgeti(L, index, 4);
614                 box.MaxEdge.X = lua_tonumber(L, -1) * scale;
615                 lua_pop(L, 1);
616                 lua_rawgeti(L, index, 5);
617                 box.MaxEdge.Y = lua_tonumber(L, -1) * scale;
618                 lua_pop(L, 1);
619                 lua_rawgeti(L, index, 6);
620                 box.MaxEdge.Z = lua_tonumber(L, -1) * scale;
621                 lua_pop(L, 1);
622         }
623         return box;
624 }
625
626 static std::vector<aabb3f> read_aabb3f_vector(lua_State *L, int index, f32 scale)
627 {
628         std::vector<aabb3f> boxes;
629         if(lua_istable(L, index)){
630                 int n = lua_objlen(L, index);
631                 // Check if it's a single box or a list of boxes
632                 bool possibly_single_box = (n == 6);
633                 for(int i = 1; i <= n && possibly_single_box; i++){
634                         lua_rawgeti(L, index, i);
635                         if(!lua_isnumber(L, -1))
636                                 possibly_single_box = false;
637                         lua_pop(L, 1);
638                 }
639                 if(possibly_single_box){
640                         // Read a single box
641                         boxes.push_back(read_aabb3f(L, index, scale));
642                 } else {
643                         // Read a list of boxes
644                         for(int i = 1; i <= n; i++){
645                                 lua_rawgeti(L, index, i);
646                                 boxes.push_back(read_aabb3f(L, -1, scale));
647                                 lua_pop(L, 1);
648                         }
649                 }
650         }
651         return boxes;
652 }
653
654 static NodeBox read_nodebox(lua_State *L, int index)
655 {
656         NodeBox nodebox;
657         if(lua_istable(L, -1)){
658                 nodebox.type = (NodeBoxType)getenumfield(L, index, "type",
659                                 es_NodeBoxType, NODEBOX_REGULAR);
660
661                 lua_getfield(L, index, "fixed");
662                 if(lua_istable(L, -1))
663                         nodebox.fixed = read_aabb3f_vector(L, -1, BS);
664                 lua_pop(L, 1);
665
666                 lua_getfield(L, index, "wall_top");
667                 if(lua_istable(L, -1))
668                         nodebox.wall_top = read_aabb3f(L, -1, BS);
669                 lua_pop(L, 1);
670
671                 lua_getfield(L, index, "wall_bottom");
672                 if(lua_istable(L, -1))
673                         nodebox.wall_bottom = read_aabb3f(L, -1, BS);
674                 lua_pop(L, 1);
675
676                 lua_getfield(L, index, "wall_side");
677                 if(lua_istable(L, -1))
678                         nodebox.wall_side = read_aabb3f(L, -1, BS);
679                 lua_pop(L, 1);
680         }
681         return nodebox;
682 }
683
684 /*
685         Groups
686 */
687 static void read_groups(lua_State *L, int index,
688                 std::map<std::string, int> &result)
689 {
690         if (!lua_istable(L,index))
691                 return;
692         result.clear();
693         lua_pushnil(L);
694         if(index < 0)
695                 index -= 1;
696         while(lua_next(L, index) != 0){
697                 // key at index -2 and value at index -1
698                 std::string name = luaL_checkstring(L, -2);
699                 int rating = luaL_checkinteger(L, -1);
700                 result[name] = rating;
701                 // removes value, keeps key for next iteration
702                 lua_pop(L, 1);
703         }
704 }
705
706 /*
707         Privileges
708 */
709 static void read_privileges(lua_State *L, int index,
710                 std::set<std::string> &result)
711 {
712         result.clear();
713         lua_pushnil(L);
714         if(index < 0)
715                 index -= 1;
716         while(lua_next(L, index) != 0){
717                 // key at index -2 and value at index -1
718                 std::string key = luaL_checkstring(L, -2);
719                 bool value = lua_toboolean(L, -1);
720                 if(value)
721                         result.insert(key);
722                 // removes value, keeps key for next iteration
723                 lua_pop(L, 1);
724         }
725 }
726
727 /*
728         ToolCapabilities
729 */
730
731 static ToolCapabilities read_tool_capabilities(
732                 lua_State *L, int table)
733 {
734         ToolCapabilities toolcap;
735         getfloatfield(L, table, "full_punch_interval", toolcap.full_punch_interval);
736         getintfield(L, table, "max_drop_level", toolcap.max_drop_level);
737         lua_getfield(L, table, "groupcaps");
738         if(lua_istable(L, -1)){
739                 int table_groupcaps = lua_gettop(L);
740                 lua_pushnil(L);
741                 while(lua_next(L, table_groupcaps) != 0){
742                         // key at index -2 and value at index -1
743                         std::string groupname = luaL_checkstring(L, -2);
744                         if(lua_istable(L, -1)){
745                                 int table_groupcap = lua_gettop(L);
746                                 // This will be created
747                                 ToolGroupCap groupcap;
748                                 // Read simple parameters
749                                 getintfield(L, table_groupcap, "maxlevel", groupcap.maxlevel);
750                                 getintfield(L, table_groupcap, "uses", groupcap.uses);
751                                 // DEPRECATED: maxwear
752                                 float maxwear = 0;
753                                 if(getfloatfield(L, table_groupcap, "maxwear", maxwear)){
754                                         if(maxwear != 0)
755                                                 groupcap.uses = 1.0/maxwear;
756                                         else
757                                                 groupcap.uses = 0;
758                                         infostream<<script_get_backtrace(L)<<std::endl;
759                                         infostream<<"WARNING: field \"maxwear\" is deprecated; "
760                                                         <<"should replace with uses=1/maxwear"<<std::endl;
761                                 }
762                                 // Read "times" table
763                                 lua_getfield(L, table_groupcap, "times");
764                                 if(lua_istable(L, -1)){
765                                         int table_times = lua_gettop(L);
766                                         lua_pushnil(L);
767                                         while(lua_next(L, table_times) != 0){
768                                                 // key at index -2 and value at index -1
769                                                 int rating = luaL_checkinteger(L, -2);
770                                                 float time = luaL_checknumber(L, -1);
771                                                 groupcap.times[rating] = time;
772                                                 // removes value, keeps key for next iteration
773                                                 lua_pop(L, 1);
774                                         }
775                                 }
776                                 lua_pop(L, 1);
777                                 // Insert groupcap into toolcap
778                                 toolcap.groupcaps[groupname] = groupcap;
779                         }
780                         // removes value, keeps key for next iteration
781                         lua_pop(L, 1);
782                 }
783         }
784         lua_pop(L, 1);
785         return toolcap;
786 }
787
788 static void set_tool_capabilities(lua_State *L, int table,
789                 const ToolCapabilities &toolcap)
790 {
791         setfloatfield(L, table, "full_punch_interval", toolcap.full_punch_interval);
792         setintfield(L, table, "max_drop_level", toolcap.max_drop_level);
793         // Create groupcaps table
794         lua_newtable(L);
795         // For each groupcap
796         for(std::map<std::string, ToolGroupCap>::const_iterator
797                         i = toolcap.groupcaps.begin(); i != toolcap.groupcaps.end(); i++){
798                 // Create groupcap table
799                 lua_newtable(L);
800                 const std::string &name = i->first;
801                 const ToolGroupCap &groupcap = i->second;
802                 // Create subtable "times"
803                 lua_newtable(L);
804                 for(std::map<int, float>::const_iterator
805                                 i = groupcap.times.begin(); i != groupcap.times.end(); i++){
806                         int rating = i->first;
807                         float time = i->second;
808                         lua_pushinteger(L, rating);
809                         lua_pushnumber(L, time);
810                         lua_settable(L, -3);
811                 }
812                 // Set subtable "times"
813                 lua_setfield(L, -2, "times");
814                 // Set simple parameters
815                 setintfield(L, -1, "maxlevel", groupcap.maxlevel);
816                 setintfield(L, -1, "uses", groupcap.uses);
817                 // Insert groupcap table into groupcaps table
818                 lua_setfield(L, -2, name.c_str());
819         }
820         // Set groupcaps table
821         lua_setfield(L, -2, "groupcaps");
822 }
823
824 static void push_tool_capabilities(lua_State *L,
825                 const ToolCapabilities &prop)
826 {
827         lua_newtable(L);
828         set_tool_capabilities(L, -1, prop);
829 }
830
831 /*
832         DigParams
833 */
834
835 static void set_dig_params(lua_State *L, int table,
836                 const DigParams &params)
837 {
838         setboolfield(L, table, "diggable", params.diggable);
839         setfloatfield(L, table, "time", params.time);
840         setintfield(L, table, "wear", params.wear);
841 }
842
843 static void push_dig_params(lua_State *L,
844                 const DigParams &params)
845 {
846         lua_newtable(L);
847         set_dig_params(L, -1, params);
848 }
849
850 /*
851         HitParams
852 */
853
854 static void set_hit_params(lua_State *L, int table,
855                 const HitParams &params)
856 {
857         setintfield(L, table, "hp", params.hp);
858         setintfield(L, table, "wear", params.wear);
859 }
860
861 static void push_hit_params(lua_State *L,
862                 const HitParams &params)
863 {
864         lua_newtable(L);
865         set_hit_params(L, -1, params);
866 }
867
868 /*
869         PointedThing
870 */
871
872 static void push_pointed_thing(lua_State *L, const PointedThing& pointed)
873 {
874         lua_newtable(L);
875         if(pointed.type == POINTEDTHING_NODE)
876         {
877                 lua_pushstring(L, "node");
878                 lua_setfield(L, -2, "type");
879                 push_v3s16(L, pointed.node_undersurface);
880                 lua_setfield(L, -2, "under");
881                 push_v3s16(L, pointed.node_abovesurface);
882                 lua_setfield(L, -2, "above");
883         }
884         else if(pointed.type == POINTEDTHING_OBJECT)
885         {
886                 lua_pushstring(L, "object");
887                 lua_setfield(L, -2, "type");
888                 objectref_get(L, pointed.object_id);
889                 lua_setfield(L, -2, "ref");
890         }
891         else
892         {
893                 lua_pushstring(L, "nothing");
894                 lua_setfield(L, -2, "type");
895         }
896 }
897
898 /*
899         SimpleSoundSpec
900 */
901
902 static void read_soundspec(lua_State *L, int index, SimpleSoundSpec &spec)
903 {
904         if(index < 0)
905                 index = lua_gettop(L) + 1 + index;
906         if(lua_isnil(L, index)){
907         } else if(lua_istable(L, index)){
908                 getstringfield(L, index, "name", spec.name);
909                 getfloatfield(L, index, "gain", spec.gain);
910         } else if(lua_isstring(L, index)){
911                 spec.name = lua_tostring(L, index);
912         }
913 }
914
915 /*
916         ObjectProperties
917 */
918
919 static void read_object_properties(lua_State *L, int index,
920                 ObjectProperties *prop)
921 {
922         if(index < 0)
923                 index = lua_gettop(L) + 1 + index;
924         if(!lua_istable(L, index))
925                 return;
926
927         prop->hp_max = getintfield_default(L, -1, "hp_max", 10);
928
929         getboolfield(L, -1, "physical", prop->physical);
930
931         getfloatfield(L, -1, "weight", prop->weight);
932
933         lua_getfield(L, -1, "collisionbox");
934         if(lua_istable(L, -1))
935                 prop->collisionbox = read_aabb3f(L, -1, 1.0);
936         lua_pop(L, 1);
937
938         getstringfield(L, -1, "visual", prop->visual);
939
940         getstringfield(L, -1, "mesh", prop->mesh);
941         getstringfield(L, -1, "texture", prop->texture);
942         
943         lua_getfield(L, -1, "visual_size");
944         if(lua_istable(L, -1))
945                 prop->visual_size = read_v2f(L, -1);
946         lua_pop(L, 1);
947
948         lua_getfield(L, -1, "textures");
949         if(lua_istable(L, -1)){
950                 prop->textures.clear();
951                 int table = lua_gettop(L);
952                 lua_pushnil(L);
953                 while(lua_next(L, table) != 0){
954                         // key at index -2 and value at index -1
955                         if(lua_isstring(L, -1))
956                                 prop->textures.push_back(lua_tostring(L, -1));
957                         else
958                                 prop->textures.push_back("");
959                         // removes value, keeps key for next iteration
960                         lua_pop(L, 1);
961                 }
962         }
963         lua_pop(L, 1);
964         
965         lua_getfield(L, -1, "spritediv");
966         if(lua_istable(L, -1))
967                 prop->spritediv = read_v2s16(L, -1);
968         lua_pop(L, 1);
969
970         lua_getfield(L, -1, "initial_sprite_basepos");
971         if(lua_istable(L, -1))
972                 prop->initial_sprite_basepos = read_v2s16(L, -1);
973         lua_pop(L, 1);
974         
975         getboolfield(L, -1, "is_visible", prop->is_visible);
976         getboolfield(L, -1, "makes_footstep_sound", prop->makes_footstep_sound);
977         getfloatfield(L, -1, "automatic_rotate", prop->automatic_rotate);
978 }
979
980 /*
981         ItemDefinition
982 */
983
984 static ItemDefinition read_item_definition(lua_State *L, int index,
985                 ItemDefinition default_def = ItemDefinition())
986 {
987         if(index < 0)
988                 index = lua_gettop(L) + 1 + index;
989
990         // Read the item definition
991         ItemDefinition def = default_def;
992
993         def.type = (ItemType)getenumfield(L, index, "type",
994                         es_ItemType, ITEM_NONE);
995         getstringfield(L, index, "name", def.name);
996         getstringfield(L, index, "description", def.description);
997         getstringfield(L, index, "inventory_image", def.inventory_image);
998         getstringfield(L, index, "wield_image", def.wield_image);
999
1000         lua_getfield(L, index, "wield_scale");
1001         if(lua_istable(L, -1)){
1002                 def.wield_scale = check_v3f(L, -1);
1003         }
1004         lua_pop(L, 1);
1005
1006         def.stack_max = getintfield_default(L, index, "stack_max", def.stack_max);
1007         if(def.stack_max == 0)
1008                 def.stack_max = 1;
1009
1010         lua_getfield(L, index, "on_use");
1011         def.usable = lua_isfunction(L, -1);
1012         lua_pop(L, 1);
1013
1014         getboolfield(L, index, "liquids_pointable", def.liquids_pointable);
1015
1016         warn_if_field_exists(L, index, "tool_digging_properties",
1017                         "deprecated: use tool_capabilities");
1018         
1019         lua_getfield(L, index, "tool_capabilities");
1020         if(lua_istable(L, -1)){
1021                 def.tool_capabilities = new ToolCapabilities(
1022                                 read_tool_capabilities(L, -1));
1023         }
1024
1025         // If name is "" (hand), ensure there are ToolCapabilities
1026         // because it will be looked up there whenever any other item has
1027         // no ToolCapabilities
1028         if(def.name == "" && def.tool_capabilities == NULL){
1029                 def.tool_capabilities = new ToolCapabilities();
1030         }
1031
1032         lua_getfield(L, index, "groups");
1033         read_groups(L, -1, def.groups);
1034         lua_pop(L, 1);
1035
1036         // Client shall immediately place this node when player places the item.
1037         // Server will update the precise end result a moment later.
1038         // "" = no prediction
1039         getstringfield(L, index, "node_placement_prediction",
1040                         def.node_placement_prediction);
1041
1042         return def;
1043 }
1044
1045 /*
1046         TileDef
1047 */
1048
1049 static TileDef read_tiledef(lua_State *L, int index)
1050 {
1051         if(index < 0)
1052                 index = lua_gettop(L) + 1 + index;
1053         
1054         TileDef tiledef;
1055
1056         // key at index -2 and value at index
1057         if(lua_isstring(L, index)){
1058                 // "default_lava.png"
1059                 tiledef.name = lua_tostring(L, index);
1060         }
1061         else if(lua_istable(L, index))
1062         {
1063                 // {name="default_lava.png", animation={}}
1064                 tiledef.name = "";
1065                 getstringfield(L, index, "name", tiledef.name);
1066                 getstringfield(L, index, "image", tiledef.name); // MaterialSpec compat.
1067                 tiledef.backface_culling = getboolfield_default(
1068                                         L, index, "backface_culling", true);
1069                 // animation = {}
1070                 lua_getfield(L, index, "animation");
1071                 if(lua_istable(L, -1)){
1072                         // {type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}
1073                         tiledef.animation.type = (TileAnimationType)
1074                                         getenumfield(L, -1, "type", es_TileAnimationType,
1075                                         TAT_NONE);
1076                         tiledef.animation.aspect_w =
1077                                         getintfield_default(L, -1, "aspect_w", 16);
1078                         tiledef.animation.aspect_h =
1079                                         getintfield_default(L, -1, "aspect_h", 16);
1080                         tiledef.animation.length =
1081                                         getfloatfield_default(L, -1, "length", 1.0);
1082                 }
1083                 lua_pop(L, 1);
1084         }
1085
1086         return tiledef;
1087 }
1088
1089 /*
1090         ContentFeatures
1091 */
1092
1093 static ContentFeatures read_content_features(lua_State *L, int index)
1094 {
1095         if(index < 0)
1096                 index = lua_gettop(L) + 1 + index;
1097
1098         ContentFeatures f;
1099         
1100         /* Cache existence of some callbacks */
1101         lua_getfield(L, index, "on_construct");
1102         if(!lua_isnil(L, -1)) f.has_on_construct = true;
1103         lua_pop(L, 1);
1104         lua_getfield(L, index, "on_destruct");
1105         if(!lua_isnil(L, -1)) f.has_on_destruct = true;
1106         lua_pop(L, 1);
1107         lua_getfield(L, index, "after_destruct");
1108         if(!lua_isnil(L, -1)) f.has_after_destruct = true;
1109         lua_pop(L, 1);
1110
1111         /* Name */
1112         getstringfield(L, index, "name", f.name);
1113
1114         /* Groups */
1115         lua_getfield(L, index, "groups");
1116         read_groups(L, -1, f.groups);
1117         lua_pop(L, 1);
1118
1119         /* Visual definition */
1120
1121         f.drawtype = (NodeDrawType)getenumfield(L, index, "drawtype", es_DrawType,
1122                         NDT_NORMAL);
1123         getfloatfield(L, index, "visual_scale", f.visual_scale);
1124         
1125         // tiles = {}
1126         lua_getfield(L, index, "tiles");
1127         // If nil, try the deprecated name "tile_images" instead
1128         if(lua_isnil(L, -1)){
1129                 lua_pop(L, 1);
1130                 warn_if_field_exists(L, index, "tile_images",
1131                                 "Deprecated; new name is \"tiles\".");
1132                 lua_getfield(L, index, "tile_images");
1133         }
1134         if(lua_istable(L, -1)){
1135                 int table = lua_gettop(L);
1136                 lua_pushnil(L);
1137                 int i = 0;
1138                 while(lua_next(L, table) != 0){
1139                         // Read tiledef from value
1140                         f.tiledef[i] = read_tiledef(L, -1);
1141                         // removes value, keeps key for next iteration
1142                         lua_pop(L, 1);
1143                         i++;
1144                         if(i==6){
1145                                 lua_pop(L, 1);
1146                                 break;
1147                         }
1148                 }
1149                 // Copy last value to all remaining textures
1150                 if(i >= 1){
1151                         TileDef lasttile = f.tiledef[i-1];
1152                         while(i < 6){
1153                                 f.tiledef[i] = lasttile;
1154                                 i++;
1155                         }
1156                 }
1157         }
1158         lua_pop(L, 1);
1159         
1160         // special_tiles = {}
1161         lua_getfield(L, index, "special_tiles");
1162         // If nil, try the deprecated name "special_materials" instead
1163         if(lua_isnil(L, -1)){
1164                 lua_pop(L, 1);
1165                 warn_if_field_exists(L, index, "special_materials",
1166                                 "Deprecated; new name is \"special_tiles\".");
1167                 lua_getfield(L, index, "special_materials");
1168         }
1169         if(lua_istable(L, -1)){
1170                 int table = lua_gettop(L);
1171                 lua_pushnil(L);
1172                 int i = 0;
1173                 while(lua_next(L, table) != 0){
1174                         // Read tiledef from value
1175                         f.tiledef_special[i] = read_tiledef(L, -1);
1176                         // removes value, keeps key for next iteration
1177                         lua_pop(L, 1);
1178                         i++;
1179                         if(i==6){
1180                                 lua_pop(L, 1);
1181                                 break;
1182                         }
1183                 }
1184         }
1185         lua_pop(L, 1);
1186
1187         f.alpha = getintfield_default(L, index, "alpha", 255);
1188
1189         /* Other stuff */
1190         
1191         lua_getfield(L, index, "post_effect_color");
1192         if(!lua_isnil(L, -1))
1193                 f.post_effect_color = readARGB8(L, -1);
1194         lua_pop(L, 1);
1195
1196         f.param_type = (ContentParamType)getenumfield(L, index, "paramtype",
1197                         es_ContentParamType, CPT_NONE);
1198         f.param_type_2 = (ContentParamType2)getenumfield(L, index, "paramtype2",
1199                         es_ContentParamType2, CPT2_NONE);
1200
1201         // Warn about some deprecated fields
1202         warn_if_field_exists(L, index, "wall_mounted",
1203                         "deprecated: use paramtype2 = 'wallmounted'");
1204         warn_if_field_exists(L, index, "light_propagates",
1205                         "deprecated: determined from paramtype");
1206         warn_if_field_exists(L, index, "dug_item",
1207                         "deprecated: use 'drop' field");
1208         warn_if_field_exists(L, index, "extra_dug_item",
1209                         "deprecated: use 'drop' field");
1210         warn_if_field_exists(L, index, "extra_dug_item_rarity",
1211                         "deprecated: use 'drop' field");
1212         warn_if_field_exists(L, index, "metadata_name",
1213                         "deprecated: use on_add and metadata callbacks");
1214         
1215         // True for all ground-like things like stone and mud, false for eg. trees
1216         getboolfield(L, index, "is_ground_content", f.is_ground_content);
1217         f.light_propagates = (f.param_type == CPT_LIGHT);
1218         getboolfield(L, index, "sunlight_propagates", f.sunlight_propagates);
1219         // This is used for collision detection.
1220         // Also for general solidness queries.
1221         getboolfield(L, index, "walkable", f.walkable);
1222         // Player can point to these
1223         getboolfield(L, index, "pointable", f.pointable);
1224         // Player can dig these
1225         getboolfield(L, index, "diggable", f.diggable);
1226         // Player can climb these
1227         getboolfield(L, index, "climbable", f.climbable);
1228         // Player can build on these
1229         getboolfield(L, index, "buildable_to", f.buildable_to);
1230         // Whether the node is non-liquid, source liquid or flowing liquid
1231         f.liquid_type = (LiquidType)getenumfield(L, index, "liquidtype",
1232                         es_LiquidType, LIQUID_NONE);
1233         // If the content is liquid, this is the flowing version of the liquid.
1234         getstringfield(L, index, "liquid_alternative_flowing",
1235                         f.liquid_alternative_flowing);
1236         // If the content is liquid, this is the source version of the liquid.
1237         getstringfield(L, index, "liquid_alternative_source",
1238                         f.liquid_alternative_source);
1239         // Viscosity for fluid flow, ranging from 1 to 7, with
1240         // 1 giving almost instantaneous propagation and 7 being
1241         // the slowest possible
1242         f.liquid_viscosity = getintfield_default(L, index,
1243                         "liquid_viscosity", f.liquid_viscosity);
1244         getboolfield(L, index, "liquid_renewable", f.liquid_renewable);
1245         // Amount of light the node emits
1246         f.light_source = getintfield_default(L, index,
1247                         "light_source", f.light_source);
1248         f.damage_per_second = getintfield_default(L, index,
1249                         "damage_per_second", f.damage_per_second);
1250         
1251         lua_getfield(L, index, "node_box");
1252         if(lua_istable(L, -1))
1253                 f.node_box = read_nodebox(L, -1);
1254         lua_pop(L, 1);
1255
1256         lua_getfield(L, index, "selection_box");
1257         if(lua_istable(L, -1))
1258                 f.selection_box = read_nodebox(L, -1);
1259         lua_pop(L, 1);
1260
1261         // Set to true if paramtype used to be 'facedir_simple'
1262         getboolfield(L, index, "legacy_facedir_simple", f.legacy_facedir_simple);
1263         // Set to true if wall_mounted used to be set to true
1264         getboolfield(L, index, "legacy_wallmounted", f.legacy_wallmounted);
1265         
1266         // Sound table
1267         lua_getfield(L, index, "sounds");
1268         if(lua_istable(L, -1)){
1269                 lua_getfield(L, -1, "footstep");
1270                 read_soundspec(L, -1, f.sound_footstep);
1271                 lua_pop(L, 1);
1272                 lua_getfield(L, -1, "dig");
1273                 read_soundspec(L, -1, f.sound_dig);
1274                 lua_pop(L, 1);
1275                 lua_getfield(L, -1, "dug");
1276                 read_soundspec(L, -1, f.sound_dug);
1277                 lua_pop(L, 1);
1278         }
1279         lua_pop(L, 1);
1280
1281         return f;
1282 }
1283
1284 /*
1285         Inventory stuff
1286 */
1287
1288 static ItemStack read_item(lua_State *L, int index);
1289 static std::vector<ItemStack> read_items(lua_State *L, int index);
1290 // creates a table of ItemStacks
1291 static void push_items(lua_State *L, const std::vector<ItemStack> &items);
1292
1293 static void inventory_set_list_from_lua(Inventory *inv, const char *name,
1294                 lua_State *L, int tableindex, int forcesize=-1)
1295 {
1296         if(tableindex < 0)
1297                 tableindex = lua_gettop(L) + 1 + tableindex;
1298         // If nil, delete list
1299         if(lua_isnil(L, tableindex)){
1300                 inv->deleteList(name);
1301                 return;
1302         }
1303         // Otherwise set list
1304         std::vector<ItemStack> items = read_items(L, tableindex);
1305         int listsize = (forcesize != -1) ? forcesize : items.size();
1306         InventoryList *invlist = inv->addList(name, listsize);
1307         int index = 0;
1308         for(std::vector<ItemStack>::const_iterator
1309                         i = items.begin(); i != items.end(); i++){
1310                 if(forcesize != -1 && index == forcesize)
1311                         break;
1312                 invlist->changeItem(index, *i);
1313                 index++;
1314         }
1315         while(forcesize != -1 && index < forcesize){
1316                 invlist->deleteItem(index);
1317                 index++;
1318         }
1319 }
1320
1321 static void inventory_get_list_to_lua(Inventory *inv, const char *name,
1322                 lua_State *L)
1323 {
1324         InventoryList *invlist = inv->getList(name);
1325         if(invlist == NULL){
1326                 lua_pushnil(L);
1327                 return;
1328         }
1329         std::vector<ItemStack> items;
1330         for(u32 i=0; i<invlist->getSize(); i++)
1331                 items.push_back(invlist->getItem(i));
1332         push_items(L, items);
1333 }
1334
1335 /*
1336         Helpful macros for userdata classes
1337 */
1338
1339 #define method(class, name) {#name, class::l_##name}
1340
1341 /*
1342         LuaItemStack
1343 */
1344
1345 class LuaItemStack
1346 {
1347 private:
1348         ItemStack m_stack;
1349
1350         static const char className[];
1351         static const luaL_reg methods[];
1352
1353         // Exported functions
1354         
1355         // garbage collector
1356         static int gc_object(lua_State *L)
1357         {
1358                 LuaItemStack *o = *(LuaItemStack **)(lua_touserdata(L, 1));
1359                 delete o;
1360                 return 0;
1361         }
1362
1363         // is_empty(self) -> true/false
1364         static int l_is_empty(lua_State *L)
1365         {
1366                 LuaItemStack *o = checkobject(L, 1);
1367                 ItemStack &item = o->m_stack;
1368                 lua_pushboolean(L, item.empty());
1369                 return 1;
1370         }
1371
1372         // get_name(self) -> string
1373         static int l_get_name(lua_State *L)
1374         {
1375                 LuaItemStack *o = checkobject(L, 1);
1376                 ItemStack &item = o->m_stack;
1377                 lua_pushstring(L, item.name.c_str());
1378                 return 1;
1379         }
1380
1381         // get_count(self) -> number
1382         static int l_get_count(lua_State *L)
1383         {
1384                 LuaItemStack *o = checkobject(L, 1);
1385                 ItemStack &item = o->m_stack;
1386                 lua_pushinteger(L, item.count);
1387                 return 1;
1388         }
1389
1390         // get_wear(self) -> number
1391         static int l_get_wear(lua_State *L)
1392         {
1393                 LuaItemStack *o = checkobject(L, 1);
1394                 ItemStack &item = o->m_stack;
1395                 lua_pushinteger(L, item.wear);
1396                 return 1;
1397         }
1398
1399         // get_metadata(self) -> string
1400         static int l_get_metadata(lua_State *L)
1401         {
1402                 LuaItemStack *o = checkobject(L, 1);
1403                 ItemStack &item = o->m_stack;
1404                 lua_pushlstring(L, item.metadata.c_str(), item.metadata.size());
1405                 return 1;
1406         }
1407
1408         // clear(self) -> true
1409         static int l_clear(lua_State *L)
1410         {
1411                 LuaItemStack *o = checkobject(L, 1);
1412                 o->m_stack.clear();
1413                 lua_pushboolean(L, true);
1414                 return 1;
1415         }
1416
1417         // replace(self, itemstack or itemstring or table or nil) -> true
1418         static int l_replace(lua_State *L)
1419         {
1420                 LuaItemStack *o = checkobject(L, 1);
1421                 o->m_stack = read_item(L, 2);
1422                 lua_pushboolean(L, true);
1423                 return 1;
1424         }
1425
1426         // to_string(self) -> string
1427         static int l_to_string(lua_State *L)
1428         {
1429                 LuaItemStack *o = checkobject(L, 1);
1430                 std::string itemstring = o->m_stack.getItemString();
1431                 lua_pushstring(L, itemstring.c_str());
1432                 return 1;
1433         }
1434
1435         // to_table(self) -> table or nil
1436         static int l_to_table(lua_State *L)
1437         {
1438                 LuaItemStack *o = checkobject(L, 1);
1439                 const ItemStack &item = o->m_stack;
1440                 if(item.empty())
1441                 {
1442                         lua_pushnil(L);
1443                 }
1444                 else
1445                 {
1446                         lua_newtable(L);
1447                         lua_pushstring(L, item.name.c_str());
1448                         lua_setfield(L, -2, "name");
1449                         lua_pushinteger(L, item.count);
1450                         lua_setfield(L, -2, "count");
1451                         lua_pushinteger(L, item.wear);
1452                         lua_setfield(L, -2, "wear");
1453                         lua_pushlstring(L, item.metadata.c_str(), item.metadata.size());
1454                         lua_setfield(L, -2, "metadata");
1455                 }
1456                 return 1;
1457         }
1458
1459         // get_stack_max(self) -> number
1460         static int l_get_stack_max(lua_State *L)
1461         {
1462                 LuaItemStack *o = checkobject(L, 1);
1463                 ItemStack &item = o->m_stack;
1464                 lua_pushinteger(L, item.getStackMax(get_server(L)->idef()));
1465                 return 1;
1466         }
1467
1468         // get_free_space(self) -> number
1469         static int l_get_free_space(lua_State *L)
1470         {
1471                 LuaItemStack *o = checkobject(L, 1);
1472                 ItemStack &item = o->m_stack;
1473                 lua_pushinteger(L, item.freeSpace(get_server(L)->idef()));
1474                 return 1;
1475         }
1476
1477         // is_known(self) -> true/false
1478         // Checks if the item is defined.
1479         static int l_is_known(lua_State *L)
1480         {
1481                 LuaItemStack *o = checkobject(L, 1);
1482                 ItemStack &item = o->m_stack;
1483                 bool is_known = item.isKnown(get_server(L)->idef());
1484                 lua_pushboolean(L, is_known);
1485                 return 1;
1486         }
1487
1488         // get_definition(self) -> table
1489         // Returns the item definition table from minetest.registered_items,
1490         // or a fallback one (name="unknown")
1491         static int l_get_definition(lua_State *L)
1492         {
1493                 LuaItemStack *o = checkobject(L, 1);
1494                 ItemStack &item = o->m_stack;
1495
1496                 // Get minetest.registered_items[name]
1497                 lua_getglobal(L, "minetest");
1498                 lua_getfield(L, -1, "registered_items");
1499                 luaL_checktype(L, -1, LUA_TTABLE);
1500                 lua_getfield(L, -1, item.name.c_str());
1501                 if(lua_isnil(L, -1))
1502                 {
1503                         lua_pop(L, 1);
1504                         lua_getfield(L, -1, "unknown");
1505                 }
1506                 return 1;
1507         }
1508
1509         // get_tool_capabilities(self) -> table
1510         // Returns the effective tool digging properties.
1511         // Returns those of the hand ("") if this item has none associated.
1512         static int l_get_tool_capabilities(lua_State *L)
1513         {
1514                 LuaItemStack *o = checkobject(L, 1);
1515                 ItemStack &item = o->m_stack;
1516                 const ToolCapabilities &prop =
1517                         item.getToolCapabilities(get_server(L)->idef());
1518                 push_tool_capabilities(L, prop);
1519                 return 1;
1520         }
1521
1522         // add_wear(self, amount) -> true/false
1523         // The range for "amount" is [0,65535]. Wear is only added if the item
1524         // is a tool. Adding wear might destroy the item.
1525         // Returns true if the item is (or was) a tool.
1526         static int l_add_wear(lua_State *L)
1527         {
1528                 LuaItemStack *o = checkobject(L, 1);
1529                 ItemStack &item = o->m_stack;
1530                 int amount = lua_tointeger(L, 2);
1531                 bool result = item.addWear(amount, get_server(L)->idef());
1532                 lua_pushboolean(L, result);
1533                 return 1;
1534         }
1535
1536         // add_item(self, itemstack or itemstring or table or nil) -> itemstack
1537         // Returns leftover item stack
1538         static int l_add_item(lua_State *L)
1539         {
1540                 LuaItemStack *o = checkobject(L, 1);
1541                 ItemStack &item = o->m_stack;
1542                 ItemStack newitem = read_item(L, 2);
1543                 ItemStack leftover = item.addItem(newitem, get_server(L)->idef());
1544                 create(L, leftover);
1545                 return 1;
1546         }
1547
1548         // item_fits(self, itemstack or itemstring or table or nil) -> true/false, itemstack
1549         // First return value is true iff the new item fits fully into the stack
1550         // Second return value is the would-be-left-over item stack
1551         static int l_item_fits(lua_State *L)
1552         {
1553                 LuaItemStack *o = checkobject(L, 1);
1554                 ItemStack &item = o->m_stack;
1555                 ItemStack newitem = read_item(L, 2);
1556                 ItemStack restitem;
1557                 bool fits = item.itemFits(newitem, &restitem, get_server(L)->idef());
1558                 lua_pushboolean(L, fits);  // first return value
1559                 create(L, restitem);       // second return value
1560                 return 2;
1561         }
1562
1563         // take_item(self, takecount=1) -> itemstack
1564         static int l_take_item(lua_State *L)
1565         {
1566                 LuaItemStack *o = checkobject(L, 1);
1567                 ItemStack &item = o->m_stack;
1568                 u32 takecount = 1;
1569                 if(!lua_isnone(L, 2))
1570                         takecount = luaL_checkinteger(L, 2);
1571                 ItemStack taken = item.takeItem(takecount);
1572                 create(L, taken);
1573                 return 1;
1574         }
1575
1576         // peek_item(self, peekcount=1) -> itemstack
1577         static int l_peek_item(lua_State *L)
1578         {
1579                 LuaItemStack *o = checkobject(L, 1);
1580                 ItemStack &item = o->m_stack;
1581                 u32 peekcount = 1;
1582                 if(!lua_isnone(L, 2))
1583                         peekcount = lua_tointeger(L, 2);
1584                 ItemStack peekaboo = item.peekItem(peekcount);
1585                 create(L, peekaboo);
1586                 return 1;
1587         }
1588
1589 public:
1590         LuaItemStack(const ItemStack &item):
1591                 m_stack(item)
1592         {
1593         }
1594
1595         ~LuaItemStack()
1596         {
1597         }
1598
1599         const ItemStack& getItem() const
1600         {
1601                 return m_stack;
1602         }
1603         ItemStack& getItem()
1604         {
1605                 return m_stack;
1606         }
1607         
1608         // LuaItemStack(itemstack or itemstring or table or nil)
1609         // Creates an LuaItemStack and leaves it on top of stack
1610         static int create_object(lua_State *L)
1611         {
1612                 ItemStack item = read_item(L, 1);
1613                 LuaItemStack *o = new LuaItemStack(item);
1614                 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1615                 luaL_getmetatable(L, className);
1616                 lua_setmetatable(L, -2);
1617                 return 1;
1618         }
1619         // Not callable from Lua
1620         static int create(lua_State *L, const ItemStack &item)
1621         {
1622                 LuaItemStack *o = new LuaItemStack(item);
1623                 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1624                 luaL_getmetatable(L, className);
1625                 lua_setmetatable(L, -2);
1626                 return 1;
1627         }
1628
1629         static LuaItemStack* checkobject(lua_State *L, int narg)
1630         {
1631                 luaL_checktype(L, narg, LUA_TUSERDATA);
1632                 void *ud = luaL_checkudata(L, narg, className);
1633                 if(!ud) luaL_typerror(L, narg, className);
1634                 return *(LuaItemStack**)ud;  // unbox pointer
1635         }
1636
1637         static void Register(lua_State *L)
1638         {
1639                 lua_newtable(L);
1640                 int methodtable = lua_gettop(L);
1641                 luaL_newmetatable(L, className);
1642                 int metatable = lua_gettop(L);
1643
1644                 lua_pushliteral(L, "__metatable");
1645                 lua_pushvalue(L, methodtable);
1646                 lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
1647
1648                 lua_pushliteral(L, "__index");
1649                 lua_pushvalue(L, methodtable);
1650                 lua_settable(L, metatable);
1651
1652                 lua_pushliteral(L, "__gc");
1653                 lua_pushcfunction(L, gc_object);
1654                 lua_settable(L, metatable);
1655
1656                 lua_pop(L, 1);  // drop metatable
1657
1658                 luaL_openlib(L, 0, methods, 0);  // fill methodtable
1659                 lua_pop(L, 1);  // drop methodtable
1660
1661                 // Can be created from Lua (LuaItemStack(itemstack or itemstring or table or nil))
1662                 lua_register(L, className, create_object);
1663         }
1664 };
1665 const char LuaItemStack::className[] = "ItemStack";
1666 const luaL_reg LuaItemStack::methods[] = {
1667         method(LuaItemStack, is_empty),
1668         method(LuaItemStack, get_name),
1669         method(LuaItemStack, get_count),
1670         method(LuaItemStack, get_wear),
1671         method(LuaItemStack, get_metadata),
1672         method(LuaItemStack, clear),
1673         method(LuaItemStack, replace),
1674         method(LuaItemStack, to_string),
1675         method(LuaItemStack, to_table),
1676         method(LuaItemStack, get_stack_max),
1677         method(LuaItemStack, get_free_space),
1678         method(LuaItemStack, is_known),
1679         method(LuaItemStack, get_definition),
1680         method(LuaItemStack, get_tool_capabilities),
1681         method(LuaItemStack, add_wear),
1682         method(LuaItemStack, add_item),
1683         method(LuaItemStack, item_fits),
1684         method(LuaItemStack, take_item),
1685         method(LuaItemStack, peek_item),
1686         {0,0}
1687 };
1688
1689 static ItemStack read_item(lua_State *L, int index)
1690 {
1691         if(index < 0)
1692                 index = lua_gettop(L) + 1 + index;
1693
1694         if(lua_isnil(L, index))
1695         {
1696                 return ItemStack();
1697         }
1698         else if(lua_isuserdata(L, index))
1699         {
1700                 // Convert from LuaItemStack
1701                 LuaItemStack *o = LuaItemStack::checkobject(L, index);
1702                 return o->getItem();
1703         }
1704         else if(lua_isstring(L, index))
1705         {
1706                 // Convert from itemstring
1707                 std::string itemstring = lua_tostring(L, index);
1708                 IItemDefManager *idef = get_server(L)->idef();
1709                 try
1710                 {
1711                         ItemStack item;
1712                         item.deSerialize(itemstring, idef);
1713                         return item;
1714                 }
1715                 catch(SerializationError &e)
1716                 {
1717                         infostream<<"WARNING: unable to create item from itemstring"
1718                                         <<": "<<itemstring<<std::endl;
1719                         return ItemStack();
1720                 }
1721         }
1722         else if(lua_istable(L, index))
1723         {
1724                 // Convert from table
1725                 IItemDefManager *idef = get_server(L)->idef();
1726                 std::string name = getstringfield_default(L, index, "name", "");
1727                 int count = getintfield_default(L, index, "count", 1);
1728                 int wear = getintfield_default(L, index, "wear", 0);
1729                 std::string metadata = getstringfield_default(L, index, "metadata", "");
1730                 return ItemStack(name, count, wear, metadata, idef);
1731         }
1732         else
1733         {
1734                 throw LuaError(L, "Expecting itemstack, itemstring, table or nil");
1735         }
1736 }
1737
1738 static std::vector<ItemStack> read_items(lua_State *L, int index)
1739 {
1740         if(index < 0)
1741                 index = lua_gettop(L) + 1 + index;
1742
1743         std::vector<ItemStack> items;
1744         luaL_checktype(L, index, LUA_TTABLE);
1745         lua_pushnil(L);
1746         while(lua_next(L, index) != 0){
1747                 // key at index -2 and value at index -1
1748                 items.push_back(read_item(L, -1));
1749                 // removes value, keeps key for next iteration
1750                 lua_pop(L, 1);
1751         }
1752         return items;
1753 }
1754
1755 // creates a table of ItemStacks
1756 static void push_items(lua_State *L, const std::vector<ItemStack> &items)
1757 {
1758         // Get the table insert function
1759         lua_getglobal(L, "table");
1760         lua_getfield(L, -1, "insert");
1761         int table_insert = lua_gettop(L);
1762         // Create and fill table
1763         lua_newtable(L);
1764         int table = lua_gettop(L);
1765         for(u32 i=0; i<items.size(); i++){
1766                 ItemStack item = items[i];
1767                 lua_pushvalue(L, table_insert);
1768                 lua_pushvalue(L, table);
1769                 LuaItemStack::create(L, item);
1770                 if(lua_pcall(L, 2, 0, 0))
1771                         script_error(L, "error: %s", lua_tostring(L, -1));
1772         }
1773         lua_remove(L, -2); // Remove table
1774         lua_remove(L, -2); // Remove insert
1775 }
1776
1777 /*
1778         InvRef
1779 */
1780
1781 class InvRef
1782 {
1783 private:
1784         InventoryLocation m_loc;
1785
1786         static const char className[];
1787         static const luaL_reg methods[];
1788
1789         static InvRef *checkobject(lua_State *L, int narg)
1790         {
1791                 luaL_checktype(L, narg, LUA_TUSERDATA);
1792                 void *ud = luaL_checkudata(L, narg, className);
1793                 if(!ud) luaL_typerror(L, narg, className);
1794                 return *(InvRef**)ud;  // unbox pointer
1795         }
1796         
1797         static Inventory* getinv(lua_State *L, InvRef *ref)
1798         {
1799                 return get_server(L)->getInventory(ref->m_loc);
1800         }
1801
1802         static InventoryList* getlist(lua_State *L, InvRef *ref,
1803                         const char *listname)
1804         {
1805                 Inventory *inv = getinv(L, ref);
1806                 if(!inv)
1807                         return NULL;
1808                 return inv->getList(listname);
1809         }
1810
1811         static void reportInventoryChange(lua_State *L, InvRef *ref)
1812         {
1813                 // Inform other things that the inventory has changed
1814                 get_server(L)->setInventoryModified(ref->m_loc);
1815         }
1816         
1817         // Exported functions
1818         
1819         // garbage collector
1820         static int gc_object(lua_State *L) {
1821                 InvRef *o = *(InvRef **)(lua_touserdata(L, 1));
1822                 delete o;
1823                 return 0;
1824         }
1825
1826         // is_empty(self, listname) -> true/false
1827         static int l_is_empty(lua_State *L)
1828         {
1829                 InvRef *ref = checkobject(L, 1);
1830                 const char *listname = luaL_checkstring(L, 2);
1831                 InventoryList *list = getlist(L, ref, listname);
1832                 if(list && list->getUsedSlots() > 0){
1833                         lua_pushboolean(L, false);
1834                 } else {
1835                         lua_pushboolean(L, true);
1836                 }
1837                 return 1;
1838         }
1839
1840         // get_size(self, listname)
1841         static int l_get_size(lua_State *L)
1842         {
1843                 InvRef *ref = checkobject(L, 1);
1844                 const char *listname = luaL_checkstring(L, 2);
1845                 InventoryList *list = getlist(L, ref, listname);
1846                 if(list){
1847                         lua_pushinteger(L, list->getSize());
1848                 } else {
1849                         lua_pushinteger(L, 0);
1850                 }
1851                 return 1;
1852         }
1853
1854         // get_width(self, listname)
1855         static int l_get_width(lua_State *L)
1856         {
1857                 InvRef *ref = checkobject(L, 1);
1858                 const char *listname = luaL_checkstring(L, 2);
1859                 InventoryList *list = getlist(L, ref, listname);
1860                 if(list){
1861                         lua_pushinteger(L, list->getWidth());
1862                 } else {
1863                         lua_pushinteger(L, 0);
1864                 }
1865                 return 1;
1866         }
1867
1868         // set_size(self, listname, size)
1869         static int l_set_size(lua_State *L)
1870         {
1871                 InvRef *ref = checkobject(L, 1);
1872                 const char *listname = luaL_checkstring(L, 2);
1873                 int newsize = luaL_checknumber(L, 3);
1874                 Inventory *inv = getinv(L, ref);
1875                 if(newsize == 0){
1876                         inv->deleteList(listname);
1877                         reportInventoryChange(L, ref);
1878                         return 0;
1879                 }
1880                 InventoryList *list = inv->getList(listname);
1881                 if(list){
1882                         list->setSize(newsize);
1883                 } else {
1884                         list = inv->addList(listname, newsize);
1885                 }
1886                 reportInventoryChange(L, ref);
1887                 return 0;
1888         }
1889
1890         // set_width(self, listname, size)
1891         static int l_set_width(lua_State *L)
1892         {
1893                 InvRef *ref = checkobject(L, 1);
1894                 const char *listname = luaL_checkstring(L, 2);
1895                 int newwidth = luaL_checknumber(L, 3);
1896                 Inventory *inv = getinv(L, ref);
1897                 InventoryList *list = inv->getList(listname);
1898                 if(list){
1899                         list->setWidth(newwidth);
1900                 } else {
1901                         return 0;
1902                 }
1903                 reportInventoryChange(L, ref);
1904                 return 0;
1905         }
1906
1907         // get_stack(self, listname, i) -> itemstack
1908         static int l_get_stack(lua_State *L)
1909         {
1910                 InvRef *ref = checkobject(L, 1);
1911                 const char *listname = luaL_checkstring(L, 2);
1912                 int i = luaL_checknumber(L, 3) - 1;
1913                 InventoryList *list = getlist(L, ref, listname);
1914                 ItemStack item;
1915                 if(list != NULL && i >= 0 && i < (int) list->getSize())
1916                         item = list->getItem(i);
1917                 LuaItemStack::create(L, item);
1918                 return 1;
1919         }
1920
1921         // set_stack(self, listname, i, stack) -> true/false
1922         static int l_set_stack(lua_State *L)
1923         {
1924                 InvRef *ref = checkobject(L, 1);
1925                 const char *listname = luaL_checkstring(L, 2);
1926                 int i = luaL_checknumber(L, 3) - 1;
1927                 ItemStack newitem = read_item(L, 4);
1928                 InventoryList *list = getlist(L, ref, listname);
1929                 if(list != NULL && i >= 0 && i < (int) list->getSize()){
1930                         list->changeItem(i, newitem);
1931                         reportInventoryChange(L, ref);
1932                         lua_pushboolean(L, true);
1933                 } else {
1934                         lua_pushboolean(L, false);
1935                 }
1936                 return 1;
1937         }
1938
1939         // get_list(self, listname) -> list or nil
1940         static int l_get_list(lua_State *L)
1941         {
1942                 InvRef *ref = checkobject(L, 1);
1943                 const char *listname = luaL_checkstring(L, 2);
1944                 Inventory *inv = getinv(L, ref);
1945                 inventory_get_list_to_lua(inv, listname, L);
1946                 return 1;
1947         }
1948
1949         // set_list(self, listname, list)
1950         static int l_set_list(lua_State *L)
1951         {
1952                 InvRef *ref = checkobject(L, 1);
1953                 const char *listname = luaL_checkstring(L, 2);
1954                 Inventory *inv = getinv(L, ref);
1955                 InventoryList *list = inv->getList(listname);
1956                 if(list)
1957                         inventory_set_list_from_lua(inv, listname, L, 3,
1958                                         list->getSize());
1959                 else
1960                         inventory_set_list_from_lua(inv, listname, L, 3);
1961                 reportInventoryChange(L, ref);
1962                 return 0;
1963         }
1964
1965         // add_item(self, listname, itemstack or itemstring or table or nil) -> itemstack
1966         // Returns the leftover stack
1967         static int l_add_item(lua_State *L)
1968         {
1969                 InvRef *ref = checkobject(L, 1);
1970                 const char *listname = luaL_checkstring(L, 2);
1971                 ItemStack item = read_item(L, 3);
1972                 InventoryList *list = getlist(L, ref, listname);
1973                 if(list){
1974                         ItemStack leftover = list->addItem(item);
1975                         if(leftover.count != item.count)
1976                                 reportInventoryChange(L, ref);
1977                         LuaItemStack::create(L, leftover);
1978                 } else {
1979                         LuaItemStack::create(L, item);
1980                 }
1981                 return 1;
1982         }
1983
1984         // room_for_item(self, listname, itemstack or itemstring or table or nil) -> true/false
1985         // Returns true if the item completely fits into the list
1986         static int l_room_for_item(lua_State *L)
1987         {
1988                 InvRef *ref = checkobject(L, 1);
1989                 const char *listname = luaL_checkstring(L, 2);
1990                 ItemStack item = read_item(L, 3);
1991                 InventoryList *list = getlist(L, ref, listname);
1992                 if(list){
1993                         lua_pushboolean(L, list->roomForItem(item));
1994                 } else {
1995                         lua_pushboolean(L, false);
1996                 }
1997                 return 1;
1998         }
1999
2000         // contains_item(self, listname, itemstack or itemstring or table or nil) -> true/false
2001         // Returns true if the list contains the given count of the given item name
2002         static int l_contains_item(lua_State *L)
2003         {
2004                 InvRef *ref = checkobject(L, 1);
2005                 const char *listname = luaL_checkstring(L, 2);
2006                 ItemStack item = read_item(L, 3);
2007                 InventoryList *list = getlist(L, ref, listname);
2008                 if(list){
2009                         lua_pushboolean(L, list->containsItem(item));
2010                 } else {
2011                         lua_pushboolean(L, false);
2012                 }
2013                 return 1;
2014         }
2015
2016         // remove_item(self, listname, itemstack or itemstring or table or nil) -> itemstack
2017         // Returns the items that were actually removed
2018         static int l_remove_item(lua_State *L)
2019         {
2020                 InvRef *ref = checkobject(L, 1);
2021                 const char *listname = luaL_checkstring(L, 2);
2022                 ItemStack item = read_item(L, 3);
2023                 InventoryList *list = getlist(L, ref, listname);
2024                 if(list){
2025                         ItemStack removed = list->removeItem(item);
2026                         if(!removed.empty())
2027                                 reportInventoryChange(L, ref);
2028                         LuaItemStack::create(L, removed);
2029                 } else {
2030                         LuaItemStack::create(L, ItemStack());
2031                 }
2032                 return 1;
2033         }
2034
2035 public:
2036         InvRef(const InventoryLocation &loc):
2037                 m_loc(loc)
2038         {
2039         }
2040
2041         ~InvRef()
2042         {
2043         }
2044
2045         // Creates an InvRef and leaves it on top of stack
2046         // Not callable from Lua; all references are created on the C side.
2047         static void create(lua_State *L, const InventoryLocation &loc)
2048         {
2049                 InvRef *o = new InvRef(loc);
2050                 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
2051                 luaL_getmetatable(L, className);
2052                 lua_setmetatable(L, -2);
2053         }
2054         static void createPlayer(lua_State *L, Player *player)
2055         {
2056                 InventoryLocation loc;
2057                 loc.setPlayer(player->getName());
2058                 create(L, loc);
2059         }
2060         static void createNodeMeta(lua_State *L, v3s16 p)
2061         {
2062                 InventoryLocation loc;
2063                 loc.setNodeMeta(p);
2064                 create(L, loc);
2065         }
2066
2067         static void Register(lua_State *L)
2068         {
2069                 lua_newtable(L);
2070                 int methodtable = lua_gettop(L);
2071                 luaL_newmetatable(L, className);
2072                 int metatable = lua_gettop(L);
2073
2074                 lua_pushliteral(L, "__metatable");
2075                 lua_pushvalue(L, methodtable);
2076                 lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
2077
2078                 lua_pushliteral(L, "__index");
2079                 lua_pushvalue(L, methodtable);
2080                 lua_settable(L, metatable);
2081
2082                 lua_pushliteral(L, "__gc");
2083                 lua_pushcfunction(L, gc_object);
2084                 lua_settable(L, metatable);
2085
2086                 lua_pop(L, 1);  // drop metatable
2087
2088                 luaL_openlib(L, 0, methods, 0);  // fill methodtable
2089                 lua_pop(L, 1);  // drop methodtable
2090
2091                 // Cannot be created from Lua
2092                 //lua_register(L, className, create_object);
2093         }
2094 };
2095 const char InvRef::className[] = "InvRef";
2096 const luaL_reg InvRef::methods[] = {
2097         method(InvRef, is_empty),
2098         method(InvRef, get_size),
2099         method(InvRef, set_size),
2100         method(InvRef, get_width),
2101         method(InvRef, set_width),
2102         method(InvRef, get_stack),
2103         method(InvRef, set_stack),
2104         method(InvRef, get_list),
2105         method(InvRef, set_list),
2106         method(InvRef, add_item),
2107         method(InvRef, room_for_item),
2108         method(InvRef, contains_item),
2109         method(InvRef, remove_item),
2110         {0,0}
2111 };
2112
2113 /*
2114         NodeMetaRef
2115 */
2116
2117 class NodeMetaRef
2118 {
2119 private:
2120         v3s16 m_p;
2121         ServerEnvironment *m_env;
2122
2123         static const char className[];
2124         static const luaL_reg methods[];
2125
2126         static NodeMetaRef *checkobject(lua_State *L, int narg)
2127         {
2128                 luaL_checktype(L, narg, LUA_TUSERDATA);
2129                 void *ud = luaL_checkudata(L, narg, className);
2130                 if(!ud) luaL_typerror(L, narg, className);
2131                 return *(NodeMetaRef**)ud;  // unbox pointer
2132         }
2133         
2134         static NodeMetadata* getmeta(NodeMetaRef *ref, bool auto_create)
2135         {
2136                 NodeMetadata *meta = ref->m_env->getMap().getNodeMetadata(ref->m_p);
2137                 if(meta == NULL && auto_create)
2138                 {
2139                         meta = new NodeMetadata(ref->m_env->getGameDef());
2140                         ref->m_env->getMap().setNodeMetadata(ref->m_p, meta);
2141                 }
2142                 return meta;
2143         }
2144
2145         static void reportMetadataChange(NodeMetaRef *ref)
2146         {
2147                 // NOTE: This same code is in rollback_interface.cpp
2148                 // Inform other things that the metadata has changed
2149                 v3s16 blockpos = getNodeBlockPos(ref->m_p);
2150                 MapEditEvent event;
2151                 event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
2152                 event.p = blockpos;
2153                 ref->m_env->getMap().dispatchEvent(&event);
2154                 // Set the block to be saved
2155                 MapBlock *block = ref->m_env->getMap().getBlockNoCreateNoEx(blockpos);
2156                 if(block)
2157                         block->raiseModified(MOD_STATE_WRITE_NEEDED,
2158                                         "NodeMetaRef::reportMetadataChange");
2159         }
2160         
2161         // Exported functions
2162         
2163         // garbage collector
2164         static int gc_object(lua_State *L) {
2165                 NodeMetaRef *o = *(NodeMetaRef **)(lua_touserdata(L, 1));
2166                 delete o;
2167                 return 0;
2168         }
2169
2170         // get_string(self, name)
2171         static int l_get_string(lua_State *L)
2172         {
2173                 NodeMetaRef *ref = checkobject(L, 1);
2174                 std::string name = luaL_checkstring(L, 2);
2175
2176                 NodeMetadata *meta = getmeta(ref, false);
2177                 if(meta == NULL){
2178                         lua_pushlstring(L, "", 0);
2179                         return 1;
2180                 }
2181                 std::string str = meta->getString(name);
2182                 lua_pushlstring(L, str.c_str(), str.size());
2183                 return 1;
2184         }
2185
2186         // set_string(self, name, var)
2187         static int l_set_string(lua_State *L)
2188         {
2189                 NodeMetaRef *ref = checkobject(L, 1);
2190                 std::string name = luaL_checkstring(L, 2);
2191                 size_t len = 0;
2192                 const char *s = lua_tolstring(L, 3, &len);
2193                 std::string str(s, len);
2194
2195                 NodeMetadata *meta = getmeta(ref, !str.empty());
2196                 if(meta == NULL || str == meta->getString(name))
2197                         return 0;
2198                 meta->setString(name, str);
2199                 reportMetadataChange(ref);
2200                 return 0;
2201         }
2202
2203         // get_int(self, name)
2204         static int l_get_int(lua_State *L)
2205         {
2206                 NodeMetaRef *ref = checkobject(L, 1);
2207                 std::string name = lua_tostring(L, 2);
2208
2209                 NodeMetadata *meta = getmeta(ref, false);
2210                 if(meta == NULL){
2211                         lua_pushnumber(L, 0);
2212                         return 1;
2213                 }
2214                 std::string str = meta->getString(name);
2215                 lua_pushnumber(L, stoi(str));
2216                 return 1;
2217         }
2218
2219         // set_int(self, name, var)
2220         static int l_set_int(lua_State *L)
2221         {
2222                 NodeMetaRef *ref = checkobject(L, 1);
2223                 std::string name = lua_tostring(L, 2);
2224                 int a = lua_tointeger(L, 3);
2225                 std::string str = itos(a);
2226
2227                 NodeMetadata *meta = getmeta(ref, true);
2228                 if(meta == NULL || str == meta->getString(name))
2229                         return 0;
2230                 meta->setString(name, str);
2231                 reportMetadataChange(ref);
2232                 return 0;
2233         }
2234
2235         // get_float(self, name)
2236         static int l_get_float(lua_State *L)
2237         {
2238                 NodeMetaRef *ref = checkobject(L, 1);
2239                 std::string name = lua_tostring(L, 2);
2240
2241                 NodeMetadata *meta = getmeta(ref, false);
2242                 if(meta == NULL){
2243                         lua_pushnumber(L, 0);
2244                         return 1;
2245                 }
2246                 std::string str = meta->getString(name);
2247                 lua_pushnumber(L, stof(str));
2248                 return 1;
2249         }
2250
2251         // set_float(self, name, var)
2252         static int l_set_float(lua_State *L)
2253         {
2254                 NodeMetaRef *ref = checkobject(L, 1);
2255                 std::string name = lua_tostring(L, 2);
2256                 float a = lua_tonumber(L, 3);
2257                 std::string str = ftos(a);
2258
2259                 NodeMetadata *meta = getmeta(ref, true);
2260                 if(meta == NULL || str == meta->getString(name))
2261                         return 0;
2262                 meta->setString(name, str);
2263                 reportMetadataChange(ref);
2264                 return 0;
2265         }
2266
2267         // get_inventory(self)
2268         static int l_get_inventory(lua_State *L)
2269         {
2270                 NodeMetaRef *ref = checkobject(L, 1);
2271                 getmeta(ref, true);  // try to ensure the metadata exists
2272                 InvRef::createNodeMeta(L, ref->m_p);
2273                 return 1;
2274         }
2275         
2276         // to_table(self)
2277         static int l_to_table(lua_State *L)
2278         {
2279                 NodeMetaRef *ref = checkobject(L, 1);
2280
2281                 NodeMetadata *meta = getmeta(ref, true);
2282                 if(meta == NULL){
2283                         lua_pushnil(L);
2284                         return 1;
2285                 }
2286                 lua_newtable(L);
2287                 // fields
2288                 lua_newtable(L);
2289                 {
2290                         std::map<std::string, std::string> fields = meta->getStrings();
2291                         for(std::map<std::string, std::string>::const_iterator
2292                                         i = fields.begin(); i != fields.end(); i++){
2293                                 const std::string &name = i->first;
2294                                 const std::string &value = i->second;
2295                                 lua_pushlstring(L, name.c_str(), name.size());
2296                                 lua_pushlstring(L, value.c_str(), value.size());
2297                                 lua_settable(L, -3);
2298                         }
2299                 }
2300                 lua_setfield(L, -2, "fields");
2301                 // inventory
2302                 lua_newtable(L);
2303                 Inventory *inv = meta->getInventory();
2304                 if(inv){
2305                         std::vector<const InventoryList*> lists = inv->getLists();
2306                         for(std::vector<const InventoryList*>::const_iterator
2307                                         i = lists.begin(); i != lists.end(); i++){
2308                                 inventory_get_list_to_lua(inv, (*i)->getName().c_str(), L);
2309                                 lua_setfield(L, -2, (*i)->getName().c_str());
2310                         }
2311                 }
2312                 lua_setfield(L, -2, "inventory");
2313                 return 1;
2314         }
2315
2316         // from_table(self, table)
2317         static int l_from_table(lua_State *L)
2318         {
2319                 NodeMetaRef *ref = checkobject(L, 1);
2320                 int base = 2;
2321                 
2322                 if(lua_isnil(L, base)){
2323                         // No metadata
2324                         ref->m_env->getMap().removeNodeMetadata(ref->m_p);
2325                         lua_pushboolean(L, true);
2326                         return 1;
2327                 }
2328
2329                 // Has metadata; clear old one first
2330                 ref->m_env->getMap().removeNodeMetadata(ref->m_p);
2331                 // Create new metadata
2332                 NodeMetadata *meta = getmeta(ref, true);
2333                 // Set fields
2334                 lua_getfield(L, base, "fields");
2335                 int fieldstable = lua_gettop(L);
2336                 lua_pushnil(L);
2337                 while(lua_next(L, fieldstable) != 0){
2338                         // key at index -2 and value at index -1
2339                         std::string name = lua_tostring(L, -2);
2340                         size_t cl;
2341                         const char *cs = lua_tolstring(L, -1, &cl);
2342                         std::string value(cs, cl);
2343                         meta->setString(name, value);
2344                         lua_pop(L, 1); // removes value, keeps key for next iteration
2345                 }
2346                 // Set inventory
2347                 Inventory *inv = meta->getInventory();
2348                 lua_getfield(L, base, "inventory");
2349                 int inventorytable = lua_gettop(L);
2350                 lua_pushnil(L);
2351                 while(lua_next(L, inventorytable) != 0){
2352                         // key at index -2 and value at index -1
2353                         std::string name = lua_tostring(L, -2);
2354                         inventory_set_list_from_lua(inv, name.c_str(), L, -1);
2355                         lua_pop(L, 1); // removes value, keeps key for next iteration
2356                 }
2357                 reportMetadataChange(ref);
2358                 lua_pushboolean(L, true);
2359                 return 1;
2360         }
2361
2362 public:
2363         NodeMetaRef(v3s16 p, ServerEnvironment *env):
2364                 m_p(p),
2365                 m_env(env)
2366         {
2367         }
2368
2369         ~NodeMetaRef()
2370         {
2371         }
2372
2373         // Creates an NodeMetaRef and leaves it on top of stack
2374         // Not callable from Lua; all references are created on the C side.
2375         static void create(lua_State *L, v3s16 p, ServerEnvironment *env)
2376         {
2377                 NodeMetaRef *o = new NodeMetaRef(p, env);
2378                 //infostream<<"NodeMetaRef::create: o="<<o<<std::endl;
2379                 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
2380                 luaL_getmetatable(L, className);
2381                 lua_setmetatable(L, -2);
2382         }
2383
2384         static void Register(lua_State *L)
2385         {
2386                 lua_newtable(L);
2387                 int methodtable = lua_gettop(L);
2388                 luaL_newmetatable(L, className);
2389                 int metatable = lua_gettop(L);
2390
2391                 lua_pushliteral(L, "__metatable");
2392                 lua_pushvalue(L, methodtable);
2393                 lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
2394
2395                 lua_pushliteral(L, "__index");
2396                 lua_pushvalue(L, methodtable);
2397                 lua_settable(L, metatable);
2398
2399                 lua_pushliteral(L, "__gc");
2400                 lua_pushcfunction(L, gc_object);
2401                 lua_settable(L, metatable);
2402
2403                 lua_pop(L, 1);  // drop metatable
2404
2405                 luaL_openlib(L, 0, methods, 0);  // fill methodtable
2406                 lua_pop(L, 1);  // drop methodtable
2407
2408                 // Cannot be created from Lua
2409                 //lua_register(L, className, create_object);
2410         }
2411 };
2412 const char NodeMetaRef::className[] = "NodeMetaRef";
2413 const luaL_reg NodeMetaRef::methods[] = {
2414         method(NodeMetaRef, get_string),
2415         method(NodeMetaRef, set_string),
2416         method(NodeMetaRef, get_int),
2417         method(NodeMetaRef, set_int),
2418         method(NodeMetaRef, get_float),
2419         method(NodeMetaRef, set_float),
2420         method(NodeMetaRef, get_inventory),
2421         method(NodeMetaRef, to_table),
2422         method(NodeMetaRef, from_table),
2423         {0,0}
2424 };
2425
2426 /*
2427         ObjectRef
2428 */
2429
2430 class ObjectRef
2431 {
2432 private:
2433         ServerActiveObject *m_object;
2434
2435         static const char className[];
2436         static const luaL_reg methods[];
2437 public:
2438         static ObjectRef *checkobject(lua_State *L, int narg)
2439         {
2440                 luaL_checktype(L, narg, LUA_TUSERDATA);
2441                 void *ud = luaL_checkudata(L, narg, className);
2442                 if(!ud) luaL_typerror(L, narg, className);
2443                 return *(ObjectRef**)ud;  // unbox pointer
2444         }
2445         
2446         static ServerActiveObject* getobject(ObjectRef *ref)
2447         {
2448                 ServerActiveObject *co = ref->m_object;
2449                 return co;
2450         }
2451 private:
2452         static LuaEntitySAO* getluaobject(ObjectRef *ref)
2453         {
2454                 ServerActiveObject *obj = getobject(ref);
2455                 if(obj == NULL)
2456                         return NULL;
2457                 if(obj->getType() != ACTIVEOBJECT_TYPE_LUAENTITY)
2458                         return NULL;
2459                 return (LuaEntitySAO*)obj;
2460         }
2461         
2462         static PlayerSAO* getplayersao(ObjectRef *ref)
2463         {
2464                 ServerActiveObject *obj = getobject(ref);
2465                 if(obj == NULL)
2466                         return NULL;
2467                 if(obj->getType() != ACTIVEOBJECT_TYPE_PLAYER)
2468                         return NULL;
2469                 return (PlayerSAO*)obj;
2470         }
2471         
2472         static Player* getplayer(ObjectRef *ref)
2473         {
2474                 PlayerSAO *playersao = getplayersao(ref);
2475                 if(playersao == NULL)
2476                         return NULL;
2477                 return playersao->getPlayer();
2478         }
2479         
2480         // Exported functions
2481         
2482         // garbage collector
2483         static int gc_object(lua_State *L) {
2484                 ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
2485                 //infostream<<"ObjectRef::gc_object: o="<<o<<std::endl;
2486                 delete o;
2487                 return 0;
2488         }
2489
2490         // remove(self)
2491         static int l_remove(lua_State *L)
2492         {
2493                 ObjectRef *ref = checkobject(L, 1);
2494                 ServerActiveObject *co = getobject(ref);
2495                 if(co == NULL) return 0;
2496                 verbosestream<<"ObjectRef::l_remove(): id="<<co->getId()<<std::endl;
2497                 co->m_removed = true;
2498                 return 0;
2499         }
2500         
2501         // getpos(self)
2502         // returns: {x=num, y=num, z=num}
2503         static int l_getpos(lua_State *L)
2504         {
2505                 ObjectRef *ref = checkobject(L, 1);
2506                 ServerActiveObject *co = getobject(ref);
2507                 if(co == NULL) return 0;
2508                 v3f pos = co->getBasePosition() / BS;
2509                 lua_newtable(L);
2510                 lua_pushnumber(L, pos.X);
2511                 lua_setfield(L, -2, "x");
2512                 lua_pushnumber(L, pos.Y);
2513                 lua_setfield(L, -2, "y");
2514                 lua_pushnumber(L, pos.Z);
2515                 lua_setfield(L, -2, "z");
2516                 return 1;
2517         }
2518         
2519         // setpos(self, pos)
2520         static int l_setpos(lua_State *L)
2521         {
2522                 ObjectRef *ref = checkobject(L, 1);
2523                 //LuaEntitySAO *co = getluaobject(ref);
2524                 ServerActiveObject *co = getobject(ref);
2525                 if(co == NULL) return 0;
2526                 // pos
2527                 v3f pos = checkFloatPos(L, 2);
2528                 // Do it
2529                 co->setPos(pos);
2530                 return 0;
2531         }
2532         
2533         // moveto(self, pos, continuous=false)
2534         static int l_moveto(lua_State *L)
2535         {
2536                 ObjectRef *ref = checkobject(L, 1);
2537                 //LuaEntitySAO *co = getluaobject(ref);
2538                 ServerActiveObject *co = getobject(ref);
2539                 if(co == NULL) return 0;
2540                 // pos
2541                 v3f pos = checkFloatPos(L, 2);
2542                 // continuous
2543                 bool continuous = lua_toboolean(L, 3);
2544                 // Do it
2545                 co->moveTo(pos, continuous);
2546                 return 0;
2547         }
2548
2549         // punch(self, puncher, time_from_last_punch, tool_capabilities, dir)
2550         static int l_punch(lua_State *L)
2551         {
2552                 ObjectRef *ref = checkobject(L, 1);
2553                 ObjectRef *puncher_ref = checkobject(L, 2);
2554                 ServerActiveObject *co = getobject(ref);
2555                 ServerActiveObject *puncher = getobject(puncher_ref);
2556                 if(co == NULL) return 0;
2557                 if(puncher == NULL) return 0;
2558                 v3f dir;
2559                 if(lua_type(L, 5) != LUA_TTABLE)
2560                         dir = co->getBasePosition() - puncher->getBasePosition();
2561                 else
2562                         dir = read_v3f(L, 5);
2563                 float time_from_last_punch = 1000000;
2564                 if(lua_isnumber(L, 3))
2565                         time_from_last_punch = lua_tonumber(L, 3);
2566                 ToolCapabilities toolcap = read_tool_capabilities(L, 4);
2567                 dir.normalize();
2568                 // Do it
2569                 co->punch(dir, &toolcap, puncher, time_from_last_punch);
2570                 return 0;
2571         }
2572
2573         // right_click(self, clicker); clicker = an another ObjectRef
2574         static int l_right_click(lua_State *L)
2575         {
2576                 ObjectRef *ref = checkobject(L, 1);
2577                 ObjectRef *ref2 = checkobject(L, 2);
2578                 ServerActiveObject *co = getobject(ref);
2579                 ServerActiveObject *co2 = getobject(ref2);
2580                 if(co == NULL) return 0;
2581                 if(co2 == NULL) return 0;
2582                 // Do it
2583                 co->rightClick(co2);
2584                 return 0;
2585         }
2586
2587         // set_hp(self, hp)
2588         // hp = number of hitpoints (2 * number of hearts)
2589         // returns: nil
2590         static int l_set_hp(lua_State *L)
2591         {
2592                 ObjectRef *ref = checkobject(L, 1);
2593                 luaL_checknumber(L, 2);
2594                 ServerActiveObject *co = getobject(ref);
2595                 if(co == NULL) return 0;
2596                 int hp = lua_tonumber(L, 2);
2597                 /*infostream<<"ObjectRef::l_set_hp(): id="<<co->getId()
2598                                 <<" hp="<<hp<<std::endl;*/
2599                 // Do it
2600                 co->setHP(hp);
2601                 // Return
2602                 return 0;
2603         }
2604
2605         // get_hp(self)
2606         // returns: number of hitpoints (2 * number of hearts)
2607         // 0 if not applicable to this type of object
2608         static int l_get_hp(lua_State *L)
2609         {
2610                 ObjectRef *ref = checkobject(L, 1);
2611                 ServerActiveObject *co = getobject(ref);
2612                 if(co == NULL){
2613                         // Default hp is 1
2614                         lua_pushnumber(L, 1);
2615                         return 1;
2616                 }
2617                 int hp = co->getHP();
2618                 /*infostream<<"ObjectRef::l_get_hp(): id="<<co->getId()
2619                                 <<" hp="<<hp<<std::endl;*/
2620                 // Return
2621                 lua_pushnumber(L, hp);
2622                 return 1;
2623         }
2624
2625         // get_inventory(self)
2626         static int l_get_inventory(lua_State *L)
2627         {
2628                 ObjectRef *ref = checkobject(L, 1);
2629                 ServerActiveObject *co = getobject(ref);
2630                 if(co == NULL) return 0;
2631                 // Do it
2632                 InventoryLocation loc = co->getInventoryLocation();
2633                 if(get_server(L)->getInventory(loc) != NULL)
2634                         InvRef::create(L, loc);
2635                 else
2636                         lua_pushnil(L); // An object may have no inventory (nil)
2637                 return 1;
2638         }
2639
2640         // get_wield_list(self)
2641         static int l_get_wield_list(lua_State *L)
2642         {
2643                 ObjectRef *ref = checkobject(L, 1);
2644                 ServerActiveObject *co = getobject(ref);
2645                 if(co == NULL) return 0;
2646                 // Do it
2647                 lua_pushstring(L, co->getWieldList().c_str());
2648                 return 1;
2649         }
2650
2651         // get_wield_index(self)
2652         static int l_get_wield_index(lua_State *L)
2653         {
2654                 ObjectRef *ref = checkobject(L, 1);
2655                 ServerActiveObject *co = getobject(ref);
2656                 if(co == NULL) return 0;
2657                 // Do it
2658                 lua_pushinteger(L, co->getWieldIndex() + 1);
2659                 return 1;
2660         }
2661
2662         // get_wielded_item(self)
2663         static int l_get_wielded_item(lua_State *L)
2664         {
2665                 ObjectRef *ref = checkobject(L, 1);
2666                 ServerActiveObject *co = getobject(ref);
2667                 if(co == NULL){
2668                         // Empty ItemStack
2669                         LuaItemStack::create(L, ItemStack());
2670                         return 1;
2671                 }
2672                 // Do it
2673                 LuaItemStack::create(L, co->getWieldedItem());
2674                 return 1;
2675         }
2676
2677         // set_wielded_item(self, itemstack or itemstring or table or nil)
2678         static int l_set_wielded_item(lua_State *L)
2679         {
2680                 ObjectRef *ref = checkobject(L, 1);
2681                 ServerActiveObject *co = getobject(ref);
2682                 if(co == NULL) return 0;
2683                 // Do it
2684                 ItemStack item = read_item(L, 2);
2685                 bool success = co->setWieldedItem(item);
2686                 lua_pushboolean(L, success);
2687                 return 1;
2688         }
2689
2690         // set_armor_groups(self, groups)
2691         static int l_set_armor_groups(lua_State *L)
2692         {
2693                 ObjectRef *ref = checkobject(L, 1);
2694                 ServerActiveObject *co = getobject(ref);
2695                 if(co == NULL) return 0;
2696                 // Do it
2697                 ItemGroupList groups;
2698                 read_groups(L, 2, groups);
2699                 co->setArmorGroups(groups);
2700                 return 0;
2701         }
2702
2703         // set_properties(self, properties)
2704         static int l_set_properties(lua_State *L)
2705         {
2706                 ObjectRef *ref = checkobject(L, 1);
2707                 ServerActiveObject *co = getobject(ref);
2708                 if(co == NULL) return 0;
2709                 ObjectProperties *prop = co->accessObjectProperties();
2710                 if(!prop)
2711                         return 0;
2712                 read_object_properties(L, 2, prop);
2713                 co->notifyObjectPropertiesModified();
2714                 return 0;
2715         }
2716
2717         /* LuaEntitySAO-only */
2718
2719         // setvelocity(self, {x=num, y=num, z=num})
2720         static int l_setvelocity(lua_State *L)
2721         {
2722                 ObjectRef *ref = checkobject(L, 1);
2723                 LuaEntitySAO *co = getluaobject(ref);
2724                 if(co == NULL) return 0;
2725                 v3f pos = checkFloatPos(L, 2);
2726                 // Do it
2727                 co->setVelocity(pos);
2728                 return 0;
2729         }
2730         
2731         // getvelocity(self)
2732         static int l_getvelocity(lua_State *L)
2733         {
2734                 ObjectRef *ref = checkobject(L, 1);
2735                 LuaEntitySAO *co = getluaobject(ref);
2736                 if(co == NULL) return 0;
2737                 // Do it
2738                 v3f v = co->getVelocity();
2739                 pushFloatPos(L, v);
2740                 return 1;
2741         }
2742         
2743         // setacceleration(self, {x=num, y=num, z=num})
2744         static int l_setacceleration(lua_State *L)
2745         {
2746                 ObjectRef *ref = checkobject(L, 1);
2747                 LuaEntitySAO *co = getluaobject(ref);
2748                 if(co == NULL) return 0;
2749                 // pos
2750                 v3f pos = checkFloatPos(L, 2);
2751                 // Do it
2752                 co->setAcceleration(pos);
2753                 return 0;
2754         }
2755         
2756         // getacceleration(self)
2757         static int l_getacceleration(lua_State *L)
2758         {
2759                 ObjectRef *ref = checkobject(L, 1);
2760                 LuaEntitySAO *co = getluaobject(ref);
2761                 if(co == NULL) return 0;
2762                 // Do it
2763                 v3f v = co->getAcceleration();
2764                 pushFloatPos(L, v);
2765                 return 1;
2766         }
2767         
2768         // setyaw(self, radians)
2769         static int l_setyaw(lua_State *L)
2770         {
2771                 ObjectRef *ref = checkobject(L, 1);
2772                 LuaEntitySAO *co = getluaobject(ref);
2773                 if(co == NULL) return 0;
2774                 float yaw = luaL_checknumber(L, 2) * core::RADTODEG;
2775                 // Do it
2776                 co->setYaw(yaw);
2777                 return 0;
2778         }
2779         
2780         // getyaw(self)
2781         static int l_getyaw(lua_State *L)
2782         {
2783                 ObjectRef *ref = checkobject(L, 1);
2784                 LuaEntitySAO *co = getluaobject(ref);
2785                 if(co == NULL) return 0;
2786                 // Do it
2787                 float yaw = co->getYaw() * core::DEGTORAD;
2788                 lua_pushnumber(L, yaw);
2789                 return 1;
2790         }
2791         
2792         // settexturemod(self, mod)
2793         static int l_settexturemod(lua_State *L)
2794         {
2795                 ObjectRef *ref = checkobject(L, 1);
2796                 LuaEntitySAO *co = getluaobject(ref);
2797                 if(co == NULL) return 0;
2798                 // Do it
2799                 std::string mod = luaL_checkstring(L, 2);
2800                 co->setTextureMod(mod);
2801                 return 0;
2802         }
2803         
2804         // setsprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2,
2805         //           select_horiz_by_yawpitch=false)
2806         static int l_setsprite(lua_State *L)
2807         {
2808                 ObjectRef *ref = checkobject(L, 1);
2809                 LuaEntitySAO *co = getluaobject(ref);
2810                 if(co == NULL) return 0;
2811                 // Do it
2812                 v2s16 p(0,0);
2813                 if(!lua_isnil(L, 2))
2814                         p = read_v2s16(L, 2);
2815                 int num_frames = 1;
2816                 if(!lua_isnil(L, 3))
2817                         num_frames = lua_tonumber(L, 3);
2818                 float framelength = 0.2;
2819                 if(!lua_isnil(L, 4))
2820                         framelength = lua_tonumber(L, 4);
2821                 bool select_horiz_by_yawpitch = false;
2822                 if(!lua_isnil(L, 5))
2823                         select_horiz_by_yawpitch = lua_toboolean(L, 5);
2824                 co->setSprite(p, num_frames, framelength, select_horiz_by_yawpitch);
2825                 return 0;
2826         }
2827
2828         // DEPRECATED
2829         // get_entity_name(self)
2830         static int l_get_entity_name(lua_State *L)
2831         {
2832                 ObjectRef *ref = checkobject(L, 1);
2833                 LuaEntitySAO *co = getluaobject(ref);
2834                 if(co == NULL) return 0;
2835                 // Do it
2836                 std::string name = co->getName();
2837                 lua_pushstring(L, name.c_str());
2838                 return 1;
2839         }
2840         
2841         // get_luaentity(self)
2842         static int l_get_luaentity(lua_State *L)
2843         {
2844                 ObjectRef *ref = checkobject(L, 1);
2845                 LuaEntitySAO *co = getluaobject(ref);
2846                 if(co == NULL) return 0;
2847                 // Do it
2848                 luaentity_get(L, co->getId());
2849                 return 1;
2850         }
2851         
2852         /* Player-only */
2853
2854         // is_player(self)
2855         static int l_is_player(lua_State *L)
2856         {
2857                 ObjectRef *ref = checkobject(L, 1);
2858                 Player *player = getplayer(ref);
2859                 lua_pushboolean(L, (player != NULL));
2860                 return 1;
2861         }
2862         
2863         // get_player_name(self)
2864         static int l_get_player_name(lua_State *L)
2865         {
2866                 ObjectRef *ref = checkobject(L, 1);
2867                 Player *player = getplayer(ref);
2868                 if(player == NULL){
2869                         lua_pushlstring(L, "", 0);
2870                         return 1;
2871                 }
2872                 // Do it
2873                 lua_pushstring(L, player->getName());
2874                 return 1;
2875         }
2876         
2877         // get_look_dir(self)
2878         static int l_get_look_dir(lua_State *L)
2879         {
2880                 ObjectRef *ref = checkobject(L, 1);
2881                 Player *player = getplayer(ref);
2882                 if(player == NULL) return 0;
2883                 // Do it
2884                 float pitch = player->getRadPitch();
2885                 float yaw = player->getRadYaw();
2886                 v3f v(cos(pitch)*cos(yaw), sin(pitch), cos(pitch)*sin(yaw));
2887                 push_v3f(L, v);
2888                 return 1;
2889         }
2890
2891         // get_look_pitch(self)
2892         static int l_get_look_pitch(lua_State *L)
2893         {
2894                 ObjectRef *ref = checkobject(L, 1);
2895                 Player *player = getplayer(ref);
2896                 if(player == NULL) return 0;
2897                 // Do it
2898                 lua_pushnumber(L, player->getRadPitch());
2899                 return 1;
2900         }
2901
2902         // get_look_yaw(self)
2903         static int l_get_look_yaw(lua_State *L)
2904         {
2905                 ObjectRef *ref = checkobject(L, 1);
2906                 Player *player = getplayer(ref);
2907                 if(player == NULL) return 0;
2908                 // Do it
2909                 lua_pushnumber(L, player->getRadYaw());
2910                 return 1;
2911         }
2912
2913         // set_inventory_formspec(self, formspec)
2914         static int l_set_inventory_formspec(lua_State *L)
2915         {
2916                 ObjectRef *ref = checkobject(L, 1);
2917                 Player *player = getplayer(ref);
2918                 if(player == NULL) return 0;
2919                 std::string formspec = luaL_checkstring(L, 2);
2920
2921                 player->inventory_formspec = formspec;
2922                 get_server(L)->reportInventoryFormspecModified(player->getName());
2923                 lua_pushboolean(L, true);
2924                 return 1;
2925         }
2926
2927         // get_inventory_formspec(self) -> formspec
2928         static int l_get_inventory_formspec(lua_State *L)
2929         {
2930                 ObjectRef *ref = checkobject(L, 1);
2931                 Player *player = getplayer(ref);
2932                 if(player == NULL) return 0;
2933
2934                 std::string formspec = player->inventory_formspec;
2935                 lua_pushlstring(L, formspec.c_str(), formspec.size());
2936                 return 1;
2937         }
2938
2939 public:
2940         ObjectRef(ServerActiveObject *object):
2941                 m_object(object)
2942         {
2943                 //infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
2944         }
2945
2946         ~ObjectRef()
2947         {
2948                 /*if(m_object)
2949                         infostream<<"ObjectRef destructing for id="
2950                                         <<m_object->getId()<<std::endl;
2951                 else
2952                         infostream<<"ObjectRef destructing for id=unknown"<<std::endl;*/
2953         }
2954
2955         // Creates an ObjectRef and leaves it on top of stack
2956         // Not callable from Lua; all references are created on the C side.
2957         static void create(lua_State *L, ServerActiveObject *object)
2958         {
2959                 ObjectRef *o = new ObjectRef(object);
2960                 //infostream<<"ObjectRef::create: o="<<o<<std::endl;
2961                 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
2962                 luaL_getmetatable(L, className);
2963                 lua_setmetatable(L, -2);
2964         }
2965
2966         static void set_null(lua_State *L)
2967         {
2968                 ObjectRef *o = checkobject(L, -1);
2969                 o->m_object = NULL;
2970         }
2971         
2972         static void Register(lua_State *L)
2973         {
2974                 lua_newtable(L);
2975                 int methodtable = lua_gettop(L);
2976                 luaL_newmetatable(L, className);
2977                 int metatable = lua_gettop(L);
2978
2979                 lua_pushliteral(L, "__metatable");
2980                 lua_pushvalue(L, methodtable);
2981                 lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
2982
2983                 lua_pushliteral(L, "__index");
2984                 lua_pushvalue(L, methodtable);
2985                 lua_settable(L, metatable);
2986
2987                 lua_pushliteral(L, "__gc");
2988                 lua_pushcfunction(L, gc_object);
2989                 lua_settable(L, metatable);
2990
2991                 lua_pop(L, 1);  // drop metatable
2992
2993                 luaL_openlib(L, 0, methods, 0);  // fill methodtable
2994                 lua_pop(L, 1);  // drop methodtable
2995
2996                 // Cannot be created from Lua
2997                 //lua_register(L, className, create_object);
2998         }
2999 };
3000 const char ObjectRef::className[] = "ObjectRef";
3001 const luaL_reg ObjectRef::methods[] = {
3002         // ServerActiveObject
3003         method(ObjectRef, remove),
3004         method(ObjectRef, getpos),
3005         method(ObjectRef, setpos),
3006         method(ObjectRef, moveto),
3007         method(ObjectRef, punch),
3008         method(ObjectRef, right_click),
3009         method(ObjectRef, set_hp),
3010         method(ObjectRef, get_hp),
3011         method(ObjectRef, get_inventory),
3012         method(ObjectRef, get_wield_list),
3013         method(ObjectRef, get_wield_index),
3014         method(ObjectRef, get_wielded_item),
3015         method(ObjectRef, set_wielded_item),
3016         method(ObjectRef, set_armor_groups),
3017         method(ObjectRef, set_properties),
3018         // LuaEntitySAO-only
3019         method(ObjectRef, setvelocity),
3020         method(ObjectRef, getvelocity),
3021         method(ObjectRef, setacceleration),
3022         method(ObjectRef, getacceleration),
3023         method(ObjectRef, setyaw),
3024         method(ObjectRef, getyaw),
3025         method(ObjectRef, settexturemod),
3026         method(ObjectRef, setsprite),
3027         method(ObjectRef, get_entity_name),
3028         method(ObjectRef, get_luaentity),
3029         // Player-only
3030         method(ObjectRef, is_player),
3031         method(ObjectRef, get_player_name),
3032         method(ObjectRef, get_look_dir),
3033         method(ObjectRef, get_look_pitch),
3034         method(ObjectRef, get_look_yaw),
3035         method(ObjectRef, set_inventory_formspec),
3036         method(ObjectRef, get_inventory_formspec),
3037         {0,0}
3038 };
3039
3040 // Creates a new anonymous reference if cobj=NULL or id=0
3041 static void objectref_get_or_create(lua_State *L,
3042                 ServerActiveObject *cobj)
3043 {
3044         if(cobj == NULL || cobj->getId() == 0){
3045                 ObjectRef::create(L, cobj);
3046         } else {
3047                 objectref_get(L, cobj->getId());
3048         }
3049 }
3050
3051
3052 /*
3053   PerlinNoise
3054  */
3055
3056 class LuaPerlinNoise
3057 {
3058 private:
3059         int seed;
3060         int octaves;
3061         double persistence;
3062         double scale;
3063         static const char className[];
3064         static const luaL_reg methods[];
3065
3066         // Exported functions
3067
3068         // garbage collector
3069         static int gc_object(lua_State *L)
3070         {
3071                 LuaPerlinNoise *o = *(LuaPerlinNoise **)(lua_touserdata(L, 1));
3072                 delete o;
3073                 return 0;
3074         }
3075
3076         static int l_get2d(lua_State *L)
3077         {
3078                 LuaPerlinNoise *o = checkobject(L, 1);
3079                 v2f pos2d = read_v2f(L,2);
3080                 lua_Number val = noise2d_perlin(pos2d.X/o->scale, pos2d.Y/o->scale, o->seed, o->octaves, o->persistence);
3081                 lua_pushnumber(L, val);
3082                 return 1;
3083         }
3084         static int l_get3d(lua_State *L)
3085         {
3086                 LuaPerlinNoise *o = checkobject(L, 1);
3087                 v3f pos3d = read_v3f(L,2);
3088                 lua_Number val = noise3d_perlin(pos3d.X/o->scale, pos3d.Y/o->scale, pos3d.Z/o->scale, o->seed, o->octaves, o->persistence);
3089                 lua_pushnumber(L, val);
3090                 return 1;
3091         }
3092
3093 public:
3094         LuaPerlinNoise(int a_seed, int a_octaves, double a_persistence,
3095                         double a_scale):
3096                 seed(a_seed),
3097                 octaves(a_octaves),
3098                 persistence(a_persistence),
3099                 scale(a_scale)
3100         {
3101         }
3102
3103         ~LuaPerlinNoise()
3104         {
3105         }
3106
3107         // LuaPerlinNoise(seed, octaves, persistence, scale)
3108         // Creates an LuaPerlinNoise and leaves it on top of stack
3109         static int create_object(lua_State *L)
3110         {
3111                 int seed = luaL_checkint(L, 1);
3112                 int octaves = luaL_checkint(L, 2);
3113                 double persistence = luaL_checknumber(L, 3);
3114                 double scale = luaL_checknumber(L, 4);
3115                 LuaPerlinNoise *o = new LuaPerlinNoise(seed, octaves, persistence, scale);
3116                 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
3117                 luaL_getmetatable(L, className);
3118                 lua_setmetatable(L, -2);
3119                 return 1;
3120         }
3121
3122         static LuaPerlinNoise* checkobject(lua_State *L, int narg)
3123         {
3124                 luaL_checktype(L, narg, LUA_TUSERDATA);
3125                 void *ud = luaL_checkudata(L, narg, className);
3126                 if(!ud) luaL_typerror(L, narg, className);
3127                 return *(LuaPerlinNoise**)ud;  // unbox pointer
3128         }
3129
3130         static void Register(lua_State *L)
3131         {
3132                 lua_newtable(L);
3133                 int methodtable = lua_gettop(L);
3134                 luaL_newmetatable(L, className);
3135                 int metatable = lua_gettop(L);
3136
3137                 lua_pushliteral(L, "__metatable");
3138                 lua_pushvalue(L, methodtable);
3139                 lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
3140
3141                 lua_pushliteral(L, "__index");
3142                 lua_pushvalue(L, methodtable);
3143                 lua_settable(L, metatable);
3144
3145                 lua_pushliteral(L, "__gc");
3146                 lua_pushcfunction(L, gc_object);
3147                 lua_settable(L, metatable);
3148
3149                 lua_pop(L, 1);  // drop metatable
3150
3151                 luaL_openlib(L, 0, methods, 0);  // fill methodtable
3152                 lua_pop(L, 1);  // drop methodtable
3153
3154                 // Can be created from Lua (PerlinNoise(seed, octaves, persistence)
3155                 lua_register(L, className, create_object);
3156         }
3157 };
3158 const char LuaPerlinNoise::className[] = "PerlinNoise";
3159 const luaL_reg LuaPerlinNoise::methods[] = {
3160         method(LuaPerlinNoise, get2d),
3161         method(LuaPerlinNoise, get3d),
3162         {0,0}
3163 };
3164
3165 /*
3166         NodeTimerRef
3167 */
3168
3169 class NodeTimerRef
3170 {
3171 private:
3172         v3s16 m_p;
3173         ServerEnvironment *m_env;
3174
3175         static const char className[];
3176         static const luaL_reg methods[];
3177
3178         static int gc_object(lua_State *L) {
3179                 NodeTimerRef *o = *(NodeTimerRef **)(lua_touserdata(L, 1));
3180                 delete o;
3181                 return 0;
3182         }
3183
3184         static NodeTimerRef *checkobject(lua_State *L, int narg)
3185         {
3186                 luaL_checktype(L, narg, LUA_TUSERDATA);
3187                 void *ud = luaL_checkudata(L, narg, className);
3188                 if(!ud) luaL_typerror(L, narg, className);
3189                 return *(NodeTimerRef**)ud;  // unbox pointer
3190         }
3191         
3192         static int l_set(lua_State *L)
3193         {
3194                 NodeTimerRef *o = checkobject(L, 1);
3195                 ServerEnvironment *env = o->m_env;
3196                 if(env == NULL) return 0;
3197                 f32 t = luaL_checknumber(L,2);
3198                 f32 e = luaL_checknumber(L,3);
3199                 env->getMap().setNodeTimer(o->m_p,NodeTimer(t,e));
3200                 return 0;
3201         }
3202         
3203         static int l_start(lua_State *L)
3204         {
3205                 NodeTimerRef *o = checkobject(L, 1);
3206                 ServerEnvironment *env = o->m_env;
3207                 if(env == NULL) return 0;
3208                 f32 t = luaL_checknumber(L,2);
3209                 env->getMap().setNodeTimer(o->m_p,NodeTimer(t,0));
3210                 return 0;
3211         }
3212         
3213         static int l_stop(lua_State *L)
3214         {
3215                 NodeTimerRef *o = checkobject(L, 1);
3216                 ServerEnvironment *env = o->m_env;
3217                 if(env == NULL) return 0;
3218                 env->getMap().removeNodeTimer(o->m_p);
3219                 return 0;
3220         }
3221         
3222         static int l_is_started(lua_State *L)
3223         {
3224                 NodeTimerRef *o = checkobject(L, 1);
3225                 ServerEnvironment *env = o->m_env;
3226                 if(env == NULL) return 0;
3227
3228                 NodeTimer t = env->getMap().getNodeTimer(o->m_p);
3229                 lua_pushboolean(L,(t.timeout != 0));
3230                 return 1;
3231         }
3232         
3233         static int l_get_timeout(lua_State *L)
3234         {
3235                 NodeTimerRef *o = checkobject(L, 1);
3236                 ServerEnvironment *env = o->m_env;
3237                 if(env == NULL) return 0;
3238
3239                 NodeTimer t = env->getMap().getNodeTimer(o->m_p);
3240                 lua_pushnumber(L,t.timeout);
3241                 return 1;
3242         }
3243         
3244         static int l_get_elapsed(lua_State *L)
3245         {
3246                 NodeTimerRef *o = checkobject(L, 1);
3247                 ServerEnvironment *env = o->m_env;
3248                 if(env == NULL) return 0;
3249
3250                 NodeTimer t = env->getMap().getNodeTimer(o->m_p);
3251                 lua_pushnumber(L,t.elapsed);
3252                 return 1;
3253         }
3254
3255 public:
3256         NodeTimerRef(v3s16 p, ServerEnvironment *env):
3257                 m_p(p),
3258                 m_env(env)
3259         {
3260         }
3261
3262         ~NodeTimerRef()
3263         {
3264         }
3265
3266         // Creates an NodeTimerRef and leaves it on top of stack
3267         // Not callable from Lua; all references are created on the C side.
3268         static void create(lua_State *L, v3s16 p, ServerEnvironment *env)
3269         {
3270                 NodeTimerRef *o = new NodeTimerRef(p, env);
3271                 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
3272                 luaL_getmetatable(L, className);
3273                 lua_setmetatable(L, -2);
3274         }
3275
3276         static void set_null(lua_State *L)
3277         {
3278                 NodeTimerRef *o = checkobject(L, -1);
3279                 o->m_env = NULL;
3280         }
3281         
3282         static void Register(lua_State *L)
3283         {
3284                 lua_newtable(L);
3285                 int methodtable = lua_gettop(L);
3286                 luaL_newmetatable(L, className);
3287                 int metatable = lua_gettop(L);
3288
3289                 lua_pushliteral(L, "__metatable");
3290                 lua_pushvalue(L, methodtable);
3291                 lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
3292
3293                 lua_pushliteral(L, "__index");
3294                 lua_pushvalue(L, methodtable);
3295                 lua_settable(L, metatable);
3296
3297                 lua_pushliteral(L, "__gc");
3298                 lua_pushcfunction(L, gc_object);
3299                 lua_settable(L, metatable);
3300
3301                 lua_pop(L, 1);  // drop metatable
3302
3303                 luaL_openlib(L, 0, methods, 0);  // fill methodtable
3304                 lua_pop(L, 1);  // drop methodtable
3305
3306                 // Cannot be created from Lua
3307                 //lua_register(L, className, create_object);
3308         }
3309 };
3310 const char NodeTimerRef::className[] = "NodeTimerRef";
3311 const luaL_reg NodeTimerRef::methods[] = {
3312         method(NodeTimerRef, start),
3313         method(NodeTimerRef, set),
3314         method(NodeTimerRef, stop),
3315         method(NodeTimerRef, is_started),
3316         method(NodeTimerRef, get_timeout),
3317         method(NodeTimerRef, get_elapsed),
3318         {0,0}
3319 };
3320
3321 /*
3322         EnvRef
3323 */
3324
3325 class EnvRef
3326 {
3327 private:
3328         ServerEnvironment *m_env;
3329
3330         static const char className[];
3331         static const luaL_reg methods[];
3332
3333         static int gc_object(lua_State *L) {
3334                 EnvRef *o = *(EnvRef **)(lua_touserdata(L, 1));
3335                 delete o;
3336                 return 0;
3337         }
3338
3339         static EnvRef *checkobject(lua_State *L, int narg)
3340         {
3341                 luaL_checktype(L, narg, LUA_TUSERDATA);
3342                 void *ud = luaL_checkudata(L, narg, className);
3343                 if(!ud) luaL_typerror(L, narg, className);
3344                 return *(EnvRef**)ud;  // unbox pointer
3345         }
3346         
3347         // Exported functions
3348
3349         // EnvRef:set_node(pos, node)
3350         // pos = {x=num, y=num, z=num}
3351         static int l_set_node(lua_State *L)
3352         {
3353                 EnvRef *o = checkobject(L, 1);
3354                 ServerEnvironment *env = o->m_env;
3355                 if(env == NULL) return 0;
3356                 INodeDefManager *ndef = env->getGameDef()->ndef();
3357                 // parameters
3358                 v3s16 pos = read_v3s16(L, 2);
3359                 MapNode n = readnode(L, 3, ndef);
3360                 // Do it
3361                 MapNode n_old = env->getMap().getNodeNoEx(pos);
3362                 // Call destructor
3363                 if(ndef->get(n_old).has_on_destruct)
3364                         scriptapi_node_on_destruct(L, pos, n_old);
3365                 // Replace node
3366                 bool succeeded = env->getMap().addNodeWithEvent(pos, n);
3367                 if(succeeded){
3368                         // Call post-destructor
3369                         if(ndef->get(n_old).has_after_destruct)
3370                                 scriptapi_node_after_destruct(L, pos, n_old);
3371                         // Call constructor
3372                         if(ndef->get(n).has_on_construct)
3373                                 scriptapi_node_on_construct(L, pos, n);
3374                 }
3375                 lua_pushboolean(L, succeeded);
3376                 return 1;
3377         }
3378
3379         static int l_add_node(lua_State *L)
3380         {
3381                 return l_set_node(L);
3382         }
3383
3384         // EnvRef:remove_node(pos)
3385         // pos = {x=num, y=num, z=num}
3386         static int l_remove_node(lua_State *L)
3387         {
3388                 EnvRef *o = checkobject(L, 1);
3389                 ServerEnvironment *env = o->m_env;
3390                 if(env == NULL) return 0;
3391                 INodeDefManager *ndef = env->getGameDef()->ndef();
3392                 // parameters
3393                 v3s16 pos = read_v3s16(L, 2);
3394                 // Do it
3395                 MapNode n_old = env->getMap().getNodeNoEx(pos);
3396                 // Call destructor
3397                 if(ndef->get(n_old).has_on_destruct)
3398                         scriptapi_node_on_destruct(L, pos, n_old);
3399                 // Replace with air
3400                 // This is slightly optimized compared to addNodeWithEvent(air)
3401                 bool succeeded = env->getMap().removeNodeWithEvent(pos);
3402                 if(succeeded){
3403                         // Call post-destructor
3404                         if(ndef->get(n_old).has_after_destruct)
3405                                 scriptapi_node_after_destruct(L, pos, n_old);
3406                 }
3407                 lua_pushboolean(L, succeeded);
3408                 // Air doesn't require constructor
3409                 return 1;
3410         }
3411
3412         // EnvRef:get_node(pos)
3413         // pos = {x=num, y=num, z=num}
3414         static int l_get_node(lua_State *L)
3415         {
3416                 EnvRef *o = checkobject(L, 1);
3417                 ServerEnvironment *env = o->m_env;
3418                 if(env == NULL) return 0;
3419                 // pos
3420                 v3s16 pos = read_v3s16(L, 2);
3421                 // Do it
3422                 MapNode n = env->getMap().getNodeNoEx(pos);
3423                 // Return node
3424                 pushnode(L, n, env->getGameDef()->ndef());
3425                 return 1;
3426         }
3427
3428         // EnvRef:get_node_or_nil(pos)
3429         // pos = {x=num, y=num, z=num}
3430         static int l_get_node_or_nil(lua_State *L)
3431         {
3432                 EnvRef *o = checkobject(L, 1);
3433                 ServerEnvironment *env = o->m_env;
3434                 if(env == NULL) return 0;
3435                 // pos
3436                 v3s16 pos = read_v3s16(L, 2);
3437                 // Do it
3438                 try{
3439                         MapNode n = env->getMap().getNode(pos);
3440                         // Return node
3441                         pushnode(L, n, env->getGameDef()->ndef());
3442                         return 1;
3443                 } catch(InvalidPositionException &e)
3444                 {
3445                         lua_pushnil(L);
3446                         return 1;
3447                 }
3448         }
3449
3450         // EnvRef:get_node_light(pos, timeofday)
3451         // pos = {x=num, y=num, z=num}
3452         // timeofday: nil = current time, 0 = night, 0.5 = day
3453         static int l_get_node_light(lua_State *L)
3454         {
3455                 EnvRef *o = checkobject(L, 1);
3456                 ServerEnvironment *env = o->m_env;
3457                 if(env == NULL) return 0;
3458                 // Do it
3459                 v3s16 pos = read_v3s16(L, 2);
3460                 u32 time_of_day = env->getTimeOfDay();
3461                 if(lua_isnumber(L, 3))
3462                         time_of_day = 24000.0 * lua_tonumber(L, 3);
3463                 time_of_day %= 24000;
3464                 u32 dnr = time_to_daynight_ratio(time_of_day);
3465                 MapNode n = env->getMap().getNodeNoEx(pos);
3466                 try{
3467                         MapNode n = env->getMap().getNode(pos);
3468                         INodeDefManager *ndef = env->getGameDef()->ndef();
3469                         lua_pushinteger(L, n.getLightBlend(dnr, ndef));
3470                         return 1;
3471                 } catch(InvalidPositionException &e)
3472                 {
3473                         lua_pushnil(L);
3474                         return 1;
3475                 }
3476         }
3477
3478         // EnvRef:place_node(pos, node)
3479         // pos = {x=num, y=num, z=num}
3480         static int l_place_node(lua_State *L)
3481         {
3482                 EnvRef *o = checkobject(L, 1);
3483                 ServerEnvironment *env = o->m_env;
3484                 if(env == NULL) return 0;
3485                 v3s16 pos = read_v3s16(L, 2);
3486                 MapNode n = readnode(L, 3, env->getGameDef()->ndef());
3487
3488                 // Don't attempt to load non-loaded area as of now
3489                 MapNode n_old = env->getMap().getNodeNoEx(pos);
3490                 if(n_old.getContent() == CONTENT_IGNORE){
3491                         lua_pushboolean(L, false);
3492                         return 1;
3493                 }
3494                 // Create item to place
3495                 INodeDefManager *ndef = get_server(L)->ndef();
3496                 IItemDefManager *idef = get_server(L)->idef();
3497                 ItemStack item(ndef->get(n).name, 1, 0, "", idef);
3498                 // Make pointed position
3499                 PointedThing pointed;
3500                 pointed.type = POINTEDTHING_NODE;
3501                 pointed.node_abovesurface = pos;
3502                 pointed.node_undersurface = pos + v3s16(0,-1,0);
3503                 // Place it with a NULL placer (appears in Lua as a non-functional
3504                 // ObjectRef)
3505                 bool success = scriptapi_item_on_place(L, item, NULL, pointed);
3506                 lua_pushboolean(L, success);
3507                 return 1;
3508         }
3509
3510         // EnvRef:dig_node(pos)
3511         // pos = {x=num, y=num, z=num}
3512         static int l_dig_node(lua_State *L)
3513         {
3514                 EnvRef *o = checkobject(L, 1);
3515                 ServerEnvironment *env = o->m_env;
3516                 if(env == NULL) return 0;
3517                 v3s16 pos = read_v3s16(L, 2);
3518
3519                 // Don't attempt to load non-loaded area as of now
3520                 MapNode n = env->getMap().getNodeNoEx(pos);
3521                 if(n.getContent() == CONTENT_IGNORE){
3522                         lua_pushboolean(L, false);
3523                         return 1;
3524                 }
3525                 // Dig it out with a NULL digger (appears in Lua as a
3526                 // non-functional ObjectRef)
3527                 bool success = scriptapi_node_on_dig(L, pos, n, NULL);
3528                 lua_pushboolean(L, success);
3529                 return 1;
3530         }
3531
3532         // EnvRef:punch_node(pos)
3533         // pos = {x=num, y=num, z=num}
3534         static int l_punch_node(lua_State *L)
3535         {
3536                 EnvRef *o = checkobject(L, 1);
3537                 ServerEnvironment *env = o->m_env;
3538                 if(env == NULL) return 0;
3539                 v3s16 pos = read_v3s16(L, 2);
3540
3541                 // Don't attempt to load non-loaded area as of now
3542                 MapNode n = env->getMap().getNodeNoEx(pos);
3543                 if(n.getContent() == CONTENT_IGNORE){
3544                         lua_pushboolean(L, false);
3545                         return 1;
3546                 }
3547                 // Punch it with a NULL puncher (appears in Lua as a non-functional
3548                 // ObjectRef)
3549                 bool success = scriptapi_node_on_punch(L, pos, n, NULL);
3550                 lua_pushboolean(L, success);
3551                 return 1;
3552         }
3553
3554         // EnvRef:get_meta(pos)
3555         static int l_get_meta(lua_State *L)
3556         {
3557                 //infostream<<"EnvRef::l_get_meta()"<<std::endl;
3558                 EnvRef *o = checkobject(L, 1);
3559                 ServerEnvironment *env = o->m_env;
3560                 if(env == NULL) return 0;
3561                 // Do it
3562                 v3s16 p = read_v3s16(L, 2);
3563                 NodeMetaRef::create(L, p, env);
3564                 return 1;
3565         }
3566
3567         // EnvRef:get_node_timer(pos)
3568         static int l_get_node_timer(lua_State *L)
3569         {
3570                 EnvRef *o = checkobject(L, 1);
3571                 ServerEnvironment *env = o->m_env;
3572                 if(env == NULL) return 0;
3573                 // Do it
3574                 v3s16 p = read_v3s16(L, 2);
3575                 NodeTimerRef::create(L, p, env);
3576                 return 1;
3577         }
3578
3579         // EnvRef:add_entity(pos, entityname) -> ObjectRef or nil
3580         // pos = {x=num, y=num, z=num}
3581         static int l_add_entity(lua_State *L)
3582         {
3583                 //infostream<<"EnvRef::l_add_entity()"<<std::endl;
3584                 EnvRef *o = checkobject(L, 1);
3585                 ServerEnvironment *env = o->m_env;
3586                 if(env == NULL) return 0;
3587                 // pos
3588                 v3f pos = checkFloatPos(L, 2);
3589                 // content
3590                 const char *name = luaL_checkstring(L, 3);
3591                 // Do it
3592                 ServerActiveObject *obj = new LuaEntitySAO(env, pos, name, "");
3593                 int objectid = env->addActiveObject(obj);
3594                 // If failed to add, return nothing (reads as nil)
3595                 if(objectid == 0)
3596                         return 0;
3597                 // Return ObjectRef
3598                 objectref_get_or_create(L, obj);
3599                 return 1;
3600         }
3601
3602         // EnvRef:add_item(pos, itemstack or itemstring or table) -> ObjectRef or nil
3603         // pos = {x=num, y=num, z=num}
3604         static int l_add_item(lua_State *L)
3605         {
3606                 //infostream<<"EnvRef::l_add_item()"<<std::endl;
3607                 EnvRef *o = checkobject(L, 1);
3608                 ServerEnvironment *env = o->m_env;
3609                 if(env == NULL) return 0;
3610                 // pos
3611                 v3f pos = checkFloatPos(L, 2);
3612                 // item
3613                 ItemStack item = read_item(L, 3);
3614                 if(item.empty() || !item.isKnown(get_server(L)->idef()))
3615                         return 0;
3616                 // Use minetest.spawn_item to spawn a __builtin:item
3617                 lua_getglobal(L, "minetest");
3618                 lua_getfield(L, -1, "spawn_item");
3619                 if(lua_isnil(L, -1))
3620                         return 0;
3621                 lua_pushvalue(L, 2);
3622                 lua_pushstring(L, item.getItemString().c_str());
3623                 if(lua_pcall(L, 2, 1, 0))
3624                         script_error(L, "error: %s", lua_tostring(L, -1));
3625                 return 1;
3626                 /*lua_pushvalue(L, 1);
3627                 lua_pushstring(L, "__builtin:item");
3628                 lua_pushstring(L, item.getItemString().c_str());
3629                 return l_add_entity(L);*/
3630                 /*// Do it
3631                 ServerActiveObject *obj = createItemSAO(env, pos, item.getItemString());
3632                 int objectid = env->addActiveObject(obj);
3633                 // If failed to add, return nothing (reads as nil)
3634                 if(objectid == 0)
3635                         return 0;
3636                 // Return ObjectRef
3637                 objectref_get_or_create(L, obj);
3638                 return 1;*/
3639         }
3640
3641         // EnvRef:add_rat(pos)
3642         // pos = {x=num, y=num, z=num}
3643         static int l_add_rat(lua_State *L)
3644         {
3645                 infostream<<"EnvRef::l_add_rat(): C++ mobs have been removed."
3646                                 <<" Doing nothing."<<std::endl;
3647                 return 0;
3648         }
3649
3650         // EnvRef:add_firefly(pos)
3651         // pos = {x=num, y=num, z=num}
3652         static int l_add_firefly(lua_State *L)
3653         {
3654                 infostream<<"EnvRef::l_add_firefly(): C++ mobs have been removed."
3655                                 <<" Doing nothing."<<std::endl;
3656                 return 0;
3657         }
3658
3659         // EnvRef:get_player_by_name(name)
3660         static int l_get_player_by_name(lua_State *L)
3661         {
3662                 EnvRef *o = checkobject(L, 1);
3663                 ServerEnvironment *env = o->m_env;
3664                 if(env == NULL) return 0;
3665                 // Do it
3666                 const char *name = luaL_checkstring(L, 2);
3667                 Player *player = env->getPlayer(name);
3668                 if(player == NULL){
3669                         lua_pushnil(L);
3670                         return 1;
3671                 }
3672                 PlayerSAO *sao = player->getPlayerSAO();
3673                 if(sao == NULL){
3674                         lua_pushnil(L);
3675                         return 1;
3676                 }
3677                 // Put player on stack
3678                 objectref_get_or_create(L, sao);
3679                 return 1;
3680         }
3681
3682         // EnvRef:get_objects_inside_radius(pos, radius)
3683         static int l_get_objects_inside_radius(lua_State *L)
3684         {
3685                 // Get the table insert function
3686                 lua_getglobal(L, "table");
3687                 lua_getfield(L, -1, "insert");
3688                 int table_insert = lua_gettop(L);
3689                 // Get environemnt
3690                 EnvRef *o = checkobject(L, 1);
3691                 ServerEnvironment *env = o->m_env;
3692                 if(env == NULL) return 0;
3693                 // Do it
3694                 v3f pos = checkFloatPos(L, 2);
3695                 float radius = luaL_checknumber(L, 3) * BS;
3696                 std::set<u16> ids = env->getObjectsInsideRadius(pos, radius);
3697                 lua_newtable(L);
3698                 int table = lua_gettop(L);
3699                 for(std::set<u16>::const_iterator
3700                                 i = ids.begin(); i != ids.end(); i++){
3701                         ServerActiveObject *obj = env->getActiveObject(*i);
3702                         // Insert object reference into table
3703                         lua_pushvalue(L, table_insert);
3704                         lua_pushvalue(L, table);
3705                         objectref_get_or_create(L, obj);
3706                         if(lua_pcall(L, 2, 0, 0))
3707                                 script_error(L, "error: %s", lua_tostring(L, -1));
3708                 }
3709                 return 1;
3710         }
3711
3712         // EnvRef:set_timeofday(val)
3713         // val = 0...1
3714         static int l_set_timeofday(lua_State *L)
3715         {
3716                 EnvRef *o = checkobject(L, 1);
3717                 ServerEnvironment *env = o->m_env;
3718                 if(env == NULL) return 0;
3719                 // Do it
3720                 float timeofday_f = luaL_checknumber(L, 2);
3721                 assert(timeofday_f >= 0.0 && timeofday_f <= 1.0);
3722                 int timeofday_mh = (int)(timeofday_f * 24000.0);
3723                 // This should be set directly in the environment but currently
3724                 // such changes aren't immediately sent to the clients, so call
3725                 // the server instead.
3726                 //env->setTimeOfDay(timeofday_mh);
3727                 get_server(L)->setTimeOfDay(timeofday_mh);
3728                 return 0;
3729         }
3730
3731         // EnvRef:get_timeofday() -> 0...1
3732         static int l_get_timeofday(lua_State *L)
3733         {
3734                 EnvRef *o = checkobject(L, 1);
3735                 ServerEnvironment *env = o->m_env;
3736                 if(env == NULL) return 0;
3737                 // Do it
3738                 int timeofday_mh = env->getTimeOfDay();
3739                 float timeofday_f = (float)timeofday_mh / 24000.0;
3740                 lua_pushnumber(L, timeofday_f);
3741                 return 1;
3742         }
3743
3744
3745         // EnvRef:find_node_near(pos, radius, nodenames) -> pos or nil
3746         // nodenames: eg. {"ignore", "group:tree"} or "default:dirt"
3747         static int l_find_node_near(lua_State *L)
3748         {
3749                 EnvRef *o = checkobject(L, 1);
3750                 ServerEnvironment *env = o->m_env;
3751                 if(env == NULL) return 0;
3752                 INodeDefManager *ndef = get_server(L)->ndef();
3753                 v3s16 pos = read_v3s16(L, 2);
3754                 int radius = luaL_checkinteger(L, 3);
3755                 std::set<content_t> filter;
3756                 if(lua_istable(L, 4)){
3757                         int table = 4;
3758                         lua_pushnil(L);
3759                         while(lua_next(L, table) != 0){
3760                                 // key at index -2 and value at index -1
3761                                 luaL_checktype(L, -1, LUA_TSTRING);
3762                                 ndef->getIds(lua_tostring(L, -1), filter);
3763                                 // removes value, keeps key for next iteration
3764                                 lua_pop(L, 1);
3765                         }
3766                 } else if(lua_isstring(L, 4)){
3767                         ndef->getIds(lua_tostring(L, 4), filter);
3768                 }
3769
3770                 for(int d=1; d<=radius; d++){
3771                         core::list<v3s16> list;
3772                         getFacePositions(list, d);
3773                         for(core::list<v3s16>::Iterator i = list.begin();
3774                                         i != list.end(); i++){
3775                                 v3s16 p = pos + (*i);
3776                                 content_t c = env->getMap().getNodeNoEx(p).getContent();
3777                                 if(filter.count(c) != 0){
3778                                         push_v3s16(L, p);
3779                                         return 1;
3780                                 }
3781                         }
3782                 }
3783                 return 0;
3784         }
3785
3786         // EnvRef:find_nodes_in_area(minp, maxp, nodenames) -> list of positions
3787         // nodenames: eg. {"ignore", "group:tree"} or "default:dirt"
3788         static int l_find_nodes_in_area(lua_State *L)
3789         {
3790                 EnvRef *o = checkobject(L, 1);
3791                 ServerEnvironment *env = o->m_env;
3792                 if(env == NULL) return 0;
3793                 INodeDefManager *ndef = get_server(L)->ndef();
3794                 v3s16 minp = read_v3s16(L, 2);
3795                 v3s16 maxp = read_v3s16(L, 3);
3796                 std::set<content_t> filter;
3797                 if(lua_istable(L, 4)){
3798                         int table = 4;
3799                         lua_pushnil(L);
3800                         while(lua_next(L, table) != 0){
3801                                 // key at index -2 and value at index -1
3802                                 luaL_checktype(L, -1, LUA_TSTRING);
3803                                 ndef->getIds(lua_tostring(L, -1), filter);
3804                                 // removes value, keeps key for next iteration
3805                                 lua_pop(L, 1);
3806                         }
3807                 } else if(lua_isstring(L, 4)){
3808                         ndef->getIds(lua_tostring(L, 4), filter);
3809                 }
3810
3811                 // Get the table insert function
3812                 lua_getglobal(L, "table");
3813                 lua_getfield(L, -1, "insert");
3814                 int table_insert = lua_gettop(L);
3815                 
3816                 lua_newtable(L);
3817                 int table = lua_gettop(L);
3818                 for(s16 x=minp.X; x<=maxp.X; x++)
3819                 for(s16 y=minp.Y; y<=maxp.Y; y++)
3820                 for(s16 z=minp.Z; z<=maxp.Z; z++)
3821                 {
3822                         v3s16 p(x,y,z);
3823                         content_t c = env->getMap().getNodeNoEx(p).getContent();
3824                         if(filter.count(c) != 0){
3825                                 lua_pushvalue(L, table_insert);
3826                                 lua_pushvalue(L, table);
3827                                 push_v3s16(L, p);
3828                                 if(lua_pcall(L, 2, 0, 0))
3829                                         script_error(L, "error: %s", lua_tostring(L, -1));
3830                         }
3831                 }
3832                 return 1;
3833         }
3834
3835         //      EnvRef:get_perlin(seeddiff, octaves, persistence, scale)
3836         //  returns world-specific PerlinNoise
3837         static int l_get_perlin(lua_State *L)
3838         {
3839                 EnvRef *o = checkobject(L, 1);
3840                 ServerEnvironment *env = o->m_env;
3841                 if(env == NULL) return 0;
3842
3843                 int seeddiff = luaL_checkint(L, 2);
3844                 int octaves = luaL_checkint(L, 3);
3845                 double persistence = luaL_checknumber(L, 4);
3846                 double scale = luaL_checknumber(L, 5);
3847
3848                 LuaPerlinNoise *n = new LuaPerlinNoise(seeddiff + int(env->getServerMap().getSeed()), octaves, persistence, scale);
3849                 *(void **)(lua_newuserdata(L, sizeof(void *))) = n;
3850                 luaL_getmetatable(L, "PerlinNoise");
3851                 lua_setmetatable(L, -2);
3852                 return 1;
3853         }
3854
3855         // EnvRef:clear_objects()
3856         // clear all objects in the environment
3857         static int l_clear_objects(lua_State *L)
3858         {
3859                 EnvRef *o = checkobject(L, 1);
3860                 o->m_env->clearAllObjects();
3861                 return 0;
3862         }
3863
3864 public:
3865         EnvRef(ServerEnvironment *env):
3866                 m_env(env)
3867         {
3868                 //infostream<<"EnvRef created"<<std::endl;
3869         }
3870
3871         ~EnvRef()
3872         {
3873                 //infostream<<"EnvRef destructing"<<std::endl;
3874         }
3875
3876         // Creates an EnvRef and leaves it on top of stack
3877         // Not callable from Lua; all references are created on the C side.
3878         static void create(lua_State *L, ServerEnvironment *env)
3879         {
3880                 EnvRef *o = new EnvRef(env);
3881                 //infostream<<"EnvRef::create: o="<<o<<std::endl;
3882                 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
3883                 luaL_getmetatable(L, className);
3884                 lua_setmetatable(L, -2);
3885         }
3886
3887         static void set_null(lua_State *L)
3888         {
3889                 EnvRef *o = checkobject(L, -1);
3890                 o->m_env = NULL;
3891         }
3892         
3893         static void Register(lua_State *L)
3894         {
3895                 lua_newtable(L);
3896                 int methodtable = lua_gettop(L);
3897                 luaL_newmetatable(L, className);
3898                 int metatable = lua_gettop(L);
3899
3900                 lua_pushliteral(L, "__metatable");
3901                 lua_pushvalue(L, methodtable);
3902                 lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
3903
3904                 lua_pushliteral(L, "__index");
3905                 lua_pushvalue(L, methodtable);
3906                 lua_settable(L, metatable);
3907
3908                 lua_pushliteral(L, "__gc");
3909                 lua_pushcfunction(L, gc_object);
3910                 lua_settable(L, metatable);
3911
3912                 lua_pop(L, 1);  // drop metatable
3913
3914                 luaL_openlib(L, 0, methods, 0);  // fill methodtable
3915                 lua_pop(L, 1);  // drop methodtable
3916
3917                 // Cannot be created from Lua
3918                 //lua_register(L, className, create_object);
3919         }
3920 };
3921 const char EnvRef::className[] = "EnvRef";
3922 const luaL_reg EnvRef::methods[] = {
3923         method(EnvRef, set_node),
3924         method(EnvRef, add_node),
3925         method(EnvRef, remove_node),
3926         method(EnvRef, get_node),
3927         method(EnvRef, get_node_or_nil),
3928         method(EnvRef, get_node_light),
3929         method(EnvRef, place_node),
3930         method(EnvRef, dig_node),
3931         method(EnvRef, punch_node),
3932         method(EnvRef, add_entity),
3933         method(EnvRef, add_item),
3934         method(EnvRef, add_rat),
3935         method(EnvRef, add_firefly),
3936         method(EnvRef, get_meta),
3937         method(EnvRef, get_node_timer),
3938         method(EnvRef, get_player_by_name),
3939         method(EnvRef, get_objects_inside_radius),
3940         method(EnvRef, set_timeofday),
3941         method(EnvRef, get_timeofday),
3942         method(EnvRef, find_node_near),
3943         method(EnvRef, find_nodes_in_area),
3944         method(EnvRef, get_perlin),
3945         method(EnvRef, clear_objects),
3946         {0,0}
3947 };
3948
3949 /*
3950         LuaPseudoRandom
3951 */
3952
3953
3954 class LuaPseudoRandom
3955 {
3956 private:
3957         PseudoRandom m_pseudo;
3958
3959         static const char className[];
3960         static const luaL_reg methods[];
3961
3962         // Exported functions
3963         
3964         // garbage collector
3965         static int gc_object(lua_State *L)
3966         {
3967                 LuaPseudoRandom *o = *(LuaPseudoRandom **)(lua_touserdata(L, 1));
3968                 delete o;
3969                 return 0;
3970         }
3971
3972         // next(self, min=0, max=32767) -> get next value
3973         static int l_next(lua_State *L)
3974         {
3975                 LuaPseudoRandom *o = checkobject(L, 1);
3976                 int min = 0;
3977                 int max = 32767;
3978                 lua_settop(L, 3); // Fill 2 and 3 with nil if they don't exist
3979                 if(!lua_isnil(L, 2))
3980                         min = luaL_checkinteger(L, 2);
3981                 if(!lua_isnil(L, 3))
3982                         max = luaL_checkinteger(L, 3);
3983                 if(max < min){
3984                         errorstream<<"PseudoRandom.next(): max="<<max<<" min="<<min<<std::endl;
3985                         throw LuaError(L, "PseudoRandom.next(): max < min");
3986                 }
3987                 if(max - min != 32767 && max - min > 32767/5)
3988                         throw LuaError(L, "PseudoRandom.next() max-min is not 32767 and is > 32768/5. This is disallowed due to the bad random distribution the implementation would otherwise make.");
3989                 PseudoRandom &pseudo = o->m_pseudo;
3990                 int val = pseudo.next();
3991                 val = (val % (max-min+1)) + min;
3992                 lua_pushinteger(L, val);
3993                 return 1;
3994         }
3995
3996 public:
3997         LuaPseudoRandom(int seed):
3998                 m_pseudo(seed)
3999         {
4000         }
4001
4002         ~LuaPseudoRandom()
4003         {
4004         }
4005
4006         const PseudoRandom& getItem() const
4007         {
4008                 return m_pseudo;
4009         }
4010         PseudoRandom& getItem()
4011         {
4012                 return m_pseudo;
4013         }
4014         
4015         // LuaPseudoRandom(seed)
4016         // Creates an LuaPseudoRandom and leaves it on top of stack
4017         static int create_object(lua_State *L)
4018         {
4019                 int seed = luaL_checknumber(L, 1);
4020                 LuaPseudoRandom *o = new LuaPseudoRandom(seed);
4021                 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
4022                 luaL_getmetatable(L, className);
4023                 lua_setmetatable(L, -2);
4024                 return 1;
4025         }
4026
4027         static LuaPseudoRandom* checkobject(lua_State *L, int narg)
4028         {
4029                 luaL_checktype(L, narg, LUA_TUSERDATA);
4030                 void *ud = luaL_checkudata(L, narg, className);
4031                 if(!ud) luaL_typerror(L, narg, className);
4032                 return *(LuaPseudoRandom**)ud;  // unbox pointer
4033         }
4034
4035         static void Register(lua_State *L)
4036         {
4037                 lua_newtable(L);
4038                 int methodtable = lua_gettop(L);
4039                 luaL_newmetatable(L, className);
4040                 int metatable = lua_gettop(L);
4041
4042                 lua_pushliteral(L, "__metatable");
4043                 lua_pushvalue(L, methodtable);
4044                 lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
4045
4046                 lua_pushliteral(L, "__index");
4047                 lua_pushvalue(L, methodtable);
4048                 lua_settable(L, metatable);
4049
4050                 lua_pushliteral(L, "__gc");
4051                 lua_pushcfunction(L, gc_object);
4052                 lua_settable(L, metatable);
4053
4054                 lua_pop(L, 1);  // drop metatable
4055
4056                 luaL_openlib(L, 0, methods, 0);  // fill methodtable
4057                 lua_pop(L, 1);  // drop methodtable
4058
4059                 // Can be created from Lua (LuaPseudoRandom(seed))
4060                 lua_register(L, className, create_object);
4061         }
4062 };
4063 const char LuaPseudoRandom::className[] = "PseudoRandom";
4064 const luaL_reg LuaPseudoRandom::methods[] = {
4065         method(LuaPseudoRandom, next),
4066         {0,0}
4067 };
4068
4069
4070
4071 /*
4072         LuaABM
4073 */
4074
4075 class LuaABM : public ActiveBlockModifier
4076 {
4077 private:
4078         lua_State *m_lua;
4079         int m_id;
4080
4081         std::set<std::string> m_trigger_contents;
4082         std::set<std::string> m_required_neighbors;
4083         float m_trigger_interval;
4084         u32 m_trigger_chance;
4085 public:
4086         LuaABM(lua_State *L, int id,
4087                         const std::set<std::string> &trigger_contents,
4088                         const std::set<std::string> &required_neighbors,
4089                         float trigger_interval, u32 trigger_chance):
4090                 m_lua(L),
4091                 m_id(id),
4092                 m_trigger_contents(trigger_contents),
4093                 m_required_neighbors(required_neighbors),
4094                 m_trigger_interval(trigger_interval),
4095                 m_trigger_chance(trigger_chance)
4096         {
4097         }
4098         virtual std::set<std::string> getTriggerContents()
4099         {
4100                 return m_trigger_contents;
4101         }
4102         virtual std::set<std::string> getRequiredNeighbors()
4103         {
4104                 return m_required_neighbors;
4105         }
4106         virtual float getTriggerInterval()
4107         {
4108                 return m_trigger_interval;
4109         }
4110         virtual u32 getTriggerChance()
4111         {
4112                 return m_trigger_chance;
4113         }
4114         virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n,
4115                         u32 active_object_count, u32 active_object_count_wider)
4116         {
4117                 lua_State *L = m_lua;
4118         
4119                 realitycheck(L);
4120                 assert(lua_checkstack(L, 20));
4121                 StackUnroller stack_unroller(L);
4122
4123                 // Get minetest.registered_abms
4124                 lua_getglobal(L, "minetest");
4125                 lua_getfield(L, -1, "registered_abms");
4126                 luaL_checktype(L, -1, LUA_TTABLE);
4127                 int registered_abms = lua_gettop(L);
4128
4129                 // Get minetest.registered_abms[m_id]
4130                 lua_pushnumber(L, m_id);
4131                 lua_gettable(L, registered_abms);
4132                 if(lua_isnil(L, -1))
4133                         assert(0);
4134                 
4135                 // Call action
4136                 luaL_checktype(L, -1, LUA_TTABLE);
4137                 lua_getfield(L, -1, "action");
4138                 luaL_checktype(L, -1, LUA_TFUNCTION);
4139                 push_v3s16(L, p);
4140                 pushnode(L, n, env->getGameDef()->ndef());
4141                 lua_pushnumber(L, active_object_count);
4142                 lua_pushnumber(L, active_object_count_wider);
4143                 if(lua_pcall(L, 4, 0, 0))
4144                         script_error(L, "error: %s", lua_tostring(L, -1));
4145         }
4146 };
4147
4148 /*
4149         ServerSoundParams
4150 */
4151
4152 static void read_server_sound_params(lua_State *L, int index,
4153                 ServerSoundParams &params)
4154 {
4155         if(index < 0)
4156                 index = lua_gettop(L) + 1 + index;
4157         // Clear
4158         params = ServerSoundParams();
4159         if(lua_istable(L, index)){
4160                 getfloatfield(L, index, "gain", params.gain);
4161                 getstringfield(L, index, "to_player", params.to_player);
4162                 lua_getfield(L, index, "pos");
4163                 if(!lua_isnil(L, -1)){
4164                         v3f p = read_v3f(L, -1)*BS;
4165                         params.pos = p;
4166                         params.type = ServerSoundParams::SSP_POSITIONAL;
4167                 }
4168                 lua_pop(L, 1);
4169                 lua_getfield(L, index, "object");
4170                 if(!lua_isnil(L, -1)){
4171                         ObjectRef *ref = ObjectRef::checkobject(L, -1);
4172                         ServerActiveObject *sao = ObjectRef::getobject(ref);
4173                         if(sao){
4174                                 params.object = sao->getId();
4175                                 params.type = ServerSoundParams::SSP_OBJECT;
4176                         }
4177                 }
4178                 lua_pop(L, 1);
4179                 params.max_hear_distance = BS*getfloatfield_default(L, index,
4180                                 "max_hear_distance", params.max_hear_distance/BS);
4181                 getboolfield(L, index, "loop", params.loop);
4182         }
4183 }
4184
4185 /*
4186         Global functions
4187 */
4188
4189 // debug(text)
4190 // Writes a line to dstream
4191 static int l_debug(lua_State *L)
4192 {
4193         std::string text = lua_tostring(L, 1);
4194         dstream << text << std::endl;
4195         return 0;
4196 }
4197
4198 // log([level,] text)
4199 // Writes a line to the logger.
4200 // The one-argument version logs to infostream.
4201 // The two-argument version accept a log level: error, action, info, or verbose.
4202 static int l_log(lua_State *L)
4203 {
4204         std::string text;
4205         LogMessageLevel level = LMT_INFO;
4206         if(lua_isnone(L, 2))
4207         {
4208                 text = lua_tostring(L, 1);
4209         }
4210         else
4211         {
4212                 std::string levelname = lua_tostring(L, 1);
4213                 text = lua_tostring(L, 2);
4214                 if(levelname == "error")
4215                         level = LMT_ERROR;
4216                 else if(levelname == "action")
4217                         level = LMT_ACTION;
4218                 else if(levelname == "verbose")
4219                         level = LMT_VERBOSE;
4220         }
4221         log_printline(level, text);
4222         return 0;
4223 }
4224
4225 // request_shutdown()
4226 static int l_request_shutdown(lua_State *L)
4227 {
4228         get_server(L)->requestShutdown();
4229         return 0;
4230 }
4231
4232 // get_server_status()
4233 static int l_get_server_status(lua_State *L)
4234 {
4235         lua_pushstring(L, wide_to_narrow(get_server(L)->getStatusString()).c_str());
4236         return 1;
4237 }
4238
4239 // register_item_raw({lots of stuff})
4240 static int l_register_item_raw(lua_State *L)
4241 {
4242         luaL_checktype(L, 1, LUA_TTABLE);
4243         int table = 1;
4244
4245         // Get the writable item and node definition managers from the server
4246         IWritableItemDefManager *idef =
4247                         get_server(L)->getWritableItemDefManager();
4248         IWritableNodeDefManager *ndef =
4249                         get_server(L)->getWritableNodeDefManager();
4250
4251         // Check if name is defined
4252         std::string name;
4253         lua_getfield(L, table, "name");
4254         if(lua_isstring(L, -1)){
4255                 name = lua_tostring(L, -1);
4256                 verbosestream<<"register_item_raw: "<<name<<std::endl;
4257         } else {
4258                 throw LuaError(L, "register_item_raw: name is not defined or not a string");
4259         }
4260
4261         // Check if on_use is defined
4262
4263         ItemDefinition def;
4264         // Set a distinctive default value to check if this is set
4265         def.node_placement_prediction = "__default";
4266
4267         // Read the item definition
4268         def = read_item_definition(L, table, def);
4269
4270         // Default to having client-side placement prediction for nodes
4271         // ("" in item definition sets it off)
4272         if(def.node_placement_prediction == "__default"){
4273                 if(def.type == ITEM_NODE)
4274                         def.node_placement_prediction = name;
4275                 else
4276                         def.node_placement_prediction = "";
4277         }
4278         
4279         // Register item definition
4280         idef->registerItem(def);
4281
4282         // Read the node definition (content features) and register it
4283         if(def.type == ITEM_NODE)
4284         {
4285                 ContentFeatures f = read_content_features(L, table);
4286                 ndef->set(f.name, f);
4287         }
4288
4289         return 0; /* number of results */
4290 }
4291
4292 // register_alias_raw(name, convert_to_name)
4293 static int l_register_alias_raw(lua_State *L)
4294 {
4295         std::string name = luaL_checkstring(L, 1);
4296         std::string convert_to = luaL_checkstring(L, 2);
4297
4298         // Get the writable item definition manager from the server
4299         IWritableItemDefManager *idef =
4300                         get_server(L)->getWritableItemDefManager();
4301         
4302         idef->registerAlias(name, convert_to);
4303         
4304         return 0; /* number of results */
4305 }
4306
4307 // helper for register_craft
4308 static bool read_craft_recipe_shaped(lua_State *L, int index,
4309                 int &width, std::vector<std::string> &recipe)
4310 {
4311         if(index < 0)
4312                 index = lua_gettop(L) + 1 + index;
4313
4314         if(!lua_istable(L, index))
4315                 return false;
4316
4317         lua_pushnil(L);
4318         int rowcount = 0;
4319         while(lua_next(L, index) != 0){
4320                 int colcount = 0;
4321                 // key at index -2 and value at index -1
4322                 if(!lua_istable(L, -1))
4323                         return false;
4324                 int table2 = lua_gettop(L);
4325                 lua_pushnil(L);
4326                 while(lua_next(L, table2) != 0){
4327                         // key at index -2 and value at index -1
4328                         if(!lua_isstring(L, -1))
4329                                 return false;
4330                         recipe.push_back(lua_tostring(L, -1));
4331                         // removes value, keeps key for next iteration
4332                         lua_pop(L, 1);
4333                         colcount++;
4334                 }
4335                 if(rowcount == 0){
4336                         width = colcount;
4337                 } else {
4338                         if(colcount != width)
4339                                 return false;
4340                 }
4341                 // removes value, keeps key for next iteration
4342                 lua_pop(L, 1);
4343                 rowcount++;
4344         }
4345         return width != 0;
4346 }
4347
4348 // helper for register_craft
4349 static bool read_craft_recipe_shapeless(lua_State *L, int index,
4350                 std::vector<std::string> &recipe)
4351 {
4352         if(index < 0)
4353                 index = lua_gettop(L) + 1 + index;
4354
4355         if(!lua_istable(L, index))
4356                 return false;
4357
4358         lua_pushnil(L);
4359         while(lua_next(L, index) != 0){
4360                 // key at index -2 and value at index -1
4361                 if(!lua_isstring(L, -1))
4362                         return false;
4363                 recipe.push_back(lua_tostring(L, -1));
4364                 // removes value, keeps key for next iteration
4365                 lua_pop(L, 1);
4366         }
4367         return true;
4368 }
4369
4370 // helper for register_craft
4371 static bool read_craft_replacements(lua_State *L, int index,
4372                 CraftReplacements &replacements)
4373 {
4374         if(index < 0)
4375                 index = lua_gettop(L) + 1 + index;
4376
4377         if(!lua_istable(L, index))
4378                 return false;
4379
4380         lua_pushnil(L);
4381         while(lua_next(L, index) != 0){
4382                 // key at index -2 and value at index -1
4383                 if(!lua_istable(L, -1))
4384                         return false;
4385                 lua_rawgeti(L, -1, 1);
4386                 if(!lua_isstring(L, -1))
4387                         return false;
4388                 std::string replace_from = lua_tostring(L, -1);
4389                 lua_pop(L, 1);
4390                 lua_rawgeti(L, -1, 2);
4391                 if(!lua_isstring(L, -1))
4392                         return false;
4393                 std::string replace_to = lua_tostring(L, -1);
4394                 lua_pop(L, 1);
4395                 replacements.pairs.push_back(
4396                                 std::make_pair(replace_from, replace_to));
4397                 // removes value, keeps key for next iteration
4398                 lua_pop(L, 1);
4399         }
4400         return true;
4401 }
4402 // register_craft({output=item, recipe={{item00,item10},{item01,item11}})
4403 static int l_register_craft(lua_State *L)
4404 {
4405         //infostream<<"register_craft"<<std::endl;
4406         luaL_checktype(L, 1, LUA_TTABLE);
4407         int table = 1;
4408
4409         // Get the writable craft definition manager from the server
4410         IWritableCraftDefManager *craftdef =
4411                         get_server(L)->getWritableCraftDefManager();
4412         
4413         std::string type = getstringfield_default(L, table, "type", "shaped");
4414
4415         /*
4416                 CraftDefinitionShaped
4417         */
4418         if(type == "shaped"){
4419                 std::string output = getstringfield_default(L, table, "output", "");
4420                 if(output == "")
4421                         throw LuaError(L, "Crafting definition is missing an output");
4422
4423                 int width = 0;
4424                 std::vector<std::string> recipe;
4425                 lua_getfield(L, table, "recipe");
4426                 if(lua_isnil(L, -1))
4427                         throw LuaError(L, "Crafting definition is missing a recipe"
4428                                         " (output=\"" + output + "\")");
4429                 if(!read_craft_recipe_shaped(L, -1, width, recipe))
4430                         throw LuaError(L, "Invalid crafting recipe"
4431                                         " (output=\"" + output + "\")");
4432
4433                 CraftReplacements replacements;
4434                 lua_getfield(L, table, "replacements");
4435                 if(!lua_isnil(L, -1))
4436                 {
4437                         if(!read_craft_replacements(L, -1, replacements))
4438                                 throw LuaError(L, "Invalid replacements"
4439                                                 " (output=\"" + output + "\")");
4440                 }
4441
4442                 CraftDefinition *def = new CraftDefinitionShaped(
4443                                 output, width, recipe, replacements);
4444                 craftdef->registerCraft(def);
4445         }
4446         /*
4447                 CraftDefinitionShapeless
4448         */
4449         else if(type == "shapeless"){
4450                 std::string output = getstringfield_default(L, table, "output", "");
4451                 if(output == "")
4452                         throw LuaError(L, "Crafting definition (shapeless)"
4453                                         " is missing an output");
4454
4455                 std::vector<std::string> recipe;
4456                 lua_getfield(L, table, "recipe");
4457                 if(lua_isnil(L, -1))
4458                         throw LuaError(L, "Crafting definition (shapeless)"
4459                                         " is missing a recipe"
4460                                         " (output=\"" + output + "\")");
4461                 if(!read_craft_recipe_shapeless(L, -1, recipe))
4462                         throw LuaError(L, "Invalid crafting recipe"
4463                                         " (output=\"" + output + "\")");
4464
4465                 CraftReplacements replacements;
4466                 lua_getfield(L, table, "replacements");
4467                 if(!lua_isnil(L, -1))
4468                 {
4469                         if(!read_craft_replacements(L, -1, replacements))
4470                                 throw LuaError(L, "Invalid replacements"
4471                                                 " (output=\"" + output + "\")");
4472                 }
4473
4474                 CraftDefinition *def = new CraftDefinitionShapeless(
4475                                 output, recipe, replacements);
4476                 craftdef->registerCraft(def);
4477         }
4478         /*
4479                 CraftDefinitionToolRepair
4480         */
4481         else if(type == "toolrepair"){
4482                 float additional_wear = getfloatfield_default(L, table,
4483                                 "additional_wear", 0.0);
4484
4485                 CraftDefinition *def = new CraftDefinitionToolRepair(
4486                                 additional_wear);
4487                 craftdef->registerCraft(def);
4488         }
4489         /*
4490                 CraftDefinitionCooking
4491         */
4492         else if(type == "cooking"){
4493                 std::string output = getstringfield_default(L, table, "output", "");
4494                 if(output == "")
4495                         throw LuaError(L, "Crafting definition (cooking)"
4496                                         " is missing an output");
4497
4498                 std::string recipe = getstringfield_default(L, table, "recipe", "");
4499                 if(recipe == "")
4500                         throw LuaError(L, "Crafting definition (cooking)"
4501                                         " is missing a recipe"
4502                                         " (output=\"" + output + "\")");
4503
4504                 float cooktime = getfloatfield_default(L, table, "cooktime", 3.0);
4505
4506                 CraftReplacements replacements;
4507                 lua_getfield(L, table, "replacements");
4508                 if(!lua_isnil(L, -1))
4509                 {
4510                         if(!read_craft_replacements(L, -1, replacements))
4511                                 throw LuaError(L, "Invalid replacements"
4512                                                 " (cooking output=\"" + output + "\")");
4513                 }
4514
4515                 CraftDefinition *def = new CraftDefinitionCooking(
4516                                 output, recipe, cooktime, replacements);
4517                 craftdef->registerCraft(def);
4518         }
4519         /*
4520                 CraftDefinitionFuel
4521         */
4522         else if(type == "fuel"){
4523                 std::string recipe = getstringfield_default(L, table, "recipe", "");
4524                 if(recipe == "")
4525                         throw LuaError(L, "Crafting definition (fuel)"
4526                                         " is missing a recipe");
4527
4528                 float burntime = getfloatfield_default(L, table, "burntime", 1.0);
4529
4530                 CraftReplacements replacements;
4531                 lua_getfield(L, table, "replacements");
4532                 if(!lua_isnil(L, -1))
4533                 {
4534                         if(!read_craft_replacements(L, -1, replacements))
4535                                 throw LuaError(L, "Invalid replacements"
4536                                                 " (fuel recipe=\"" + recipe + "\")");
4537                 }
4538
4539                 CraftDefinition *def = new CraftDefinitionFuel(
4540                                 recipe, burntime, replacements);
4541                 craftdef->registerCraft(def);
4542         }
4543         else
4544         {
4545                 throw LuaError(L, "Unknown crafting definition type: \"" + type + "\"");
4546         }
4547
4548         lua_pop(L, 1);
4549         return 0; /* number of results */
4550 }
4551
4552 // setting_set(name, value)
4553 static int l_setting_set(lua_State *L)
4554 {
4555         const char *name = luaL_checkstring(L, 1);
4556         const char *value = luaL_checkstring(L, 2);
4557         g_settings->set(name, value);
4558         return 0;
4559 }
4560
4561 // setting_get(name)
4562 static int l_setting_get(lua_State *L)
4563 {
4564         const char *name = luaL_checkstring(L, 1);
4565         try{
4566                 std::string value = g_settings->get(name);
4567                 lua_pushstring(L, value.c_str());
4568         } catch(SettingNotFoundException &e){
4569                 lua_pushnil(L);
4570         }
4571         return 1;
4572 }
4573
4574 // setting_getbool(name)
4575 static int l_setting_getbool(lua_State *L)
4576 {
4577         const char *name = luaL_checkstring(L, 1);
4578         try{
4579                 bool value = g_settings->getBool(name);
4580                 lua_pushboolean(L, value);
4581         } catch(SettingNotFoundException &e){
4582                 lua_pushnil(L);
4583         }
4584         return 1;
4585 }
4586
4587 // chat_send_all(text)
4588 static int l_chat_send_all(lua_State *L)
4589 {
4590         const char *text = luaL_checkstring(L, 1);
4591         // Get server from registry
4592         Server *server = get_server(L);
4593         // Send
4594         server->notifyPlayers(narrow_to_wide(text));
4595         return 0;
4596 }
4597
4598 // chat_send_player(name, text)
4599 static int l_chat_send_player(lua_State *L)
4600 {
4601         const char *name = luaL_checkstring(L, 1);
4602         const char *text = luaL_checkstring(L, 2);
4603         // Get server from registry
4604         Server *server = get_server(L);
4605         // Send
4606         server->notifyPlayer(name, narrow_to_wide(text));
4607         return 0;
4608 }
4609
4610 // get_player_privs(name, text)
4611 static int l_get_player_privs(lua_State *L)
4612 {
4613         const char *name = luaL_checkstring(L, 1);
4614         // Get server from registry
4615         Server *server = get_server(L);
4616         // Do it
4617         lua_newtable(L);
4618         int table = lua_gettop(L);
4619         std::set<std::string> privs_s = server->getPlayerEffectivePrivs(name);
4620         for(std::set<std::string>::const_iterator
4621                         i = privs_s.begin(); i != privs_s.end(); i++){
4622                 lua_pushboolean(L, true);
4623                 lua_setfield(L, table, i->c_str());
4624         }
4625         lua_pushvalue(L, table);
4626         return 1;
4627 }
4628
4629 // get_ban_list()
4630 static int l_get_ban_list(lua_State *L)
4631 {
4632         lua_pushstring(L, get_server(L)->getBanDescription("").c_str());
4633         return 1;
4634 }
4635
4636 // get_ban_description()
4637 static int l_get_ban_description(lua_State *L)
4638 {
4639         const char * ip_or_name = luaL_checkstring(L, 1);
4640         lua_pushstring(L, get_server(L)->getBanDescription(std::string(ip_or_name)).c_str());
4641         return 1;
4642 }
4643
4644 // ban_player()
4645 static int l_ban_player(lua_State *L)
4646 {
4647         const char * name = luaL_checkstring(L, 1);
4648         Player *player = get_env(L)->getPlayer(name);
4649         if(player == NULL)
4650         {
4651                 lua_pushboolean(L, false); // no such player
4652                 return 1;
4653         }
4654         try
4655         {
4656                 Address addr = get_server(L)->getPeerAddress(get_env(L)->getPlayer(name)->peer_id);
4657                 std::string ip_str = addr.serializeString();
4658                 get_server(L)->setIpBanned(ip_str, name);
4659         }
4660         catch(con::PeerNotFoundException) // unlikely
4661         {
4662                 dstream << __FUNCTION_NAME << ": peer was not found" << std::endl;
4663                 lua_pushboolean(L, false); // error
4664                 return 1;
4665         }
4666         lua_pushboolean(L, true);
4667         return 1;
4668 }
4669
4670 // unban_player_or_ip()
4671 static int l_unban_player_of_ip(lua_State *L)
4672 {
4673         const char * ip_or_name = luaL_checkstring(L, 1);
4674         get_server(L)->unsetIpBanned(ip_or_name);
4675         lua_pushboolean(L, true);
4676         return 1;
4677 }
4678
4679 // get_inventory(location)
4680 static int l_get_inventory(lua_State *L)
4681 {
4682         InventoryLocation loc;
4683
4684         std::string type = checkstringfield(L, 1, "type");
4685         if(type == "player"){
4686                 std::string name = checkstringfield(L, 1, "name");
4687                 loc.setPlayer(name);
4688         } else if(type == "node"){
4689                 lua_getfield(L, 1, "pos");
4690                 v3s16 pos = check_v3s16(L, -1);
4691                 loc.setNodeMeta(pos);
4692         } else if(type == "detached"){
4693                 std::string name = checkstringfield(L, 1, "name");
4694                 loc.setDetached(name);
4695         }
4696         
4697         if(get_server(L)->getInventory(loc) != NULL)
4698                 InvRef::create(L, loc);
4699         else
4700                 lua_pushnil(L);
4701         return 1;
4702 }
4703
4704 // create_detached_inventory_raw(name)
4705 static int l_create_detached_inventory_raw(lua_State *L)
4706 {
4707         const char *name = luaL_checkstring(L, 1);
4708         if(get_server(L)->createDetachedInventory(name) != NULL){
4709                 InventoryLocation loc;
4710                 loc.setDetached(name);
4711                 InvRef::create(L, loc);
4712         }else{
4713                 lua_pushnil(L);
4714         }
4715         return 1;
4716 }
4717
4718 // get_dig_params(groups, tool_capabilities[, time_from_last_punch])
4719 static int l_get_dig_params(lua_State *L)
4720 {
4721         std::map<std::string, int> groups;
4722         read_groups(L, 1, groups);
4723         ToolCapabilities tp = read_tool_capabilities(L, 2);
4724         if(lua_isnoneornil(L, 3))
4725                 push_dig_params(L, getDigParams(groups, &tp));
4726         else
4727                 push_dig_params(L, getDigParams(groups, &tp,
4728                                         luaL_checknumber(L, 3)));
4729         return 1;
4730 }
4731
4732 // get_hit_params(groups, tool_capabilities[, time_from_last_punch])
4733 static int l_get_hit_params(lua_State *L)
4734 {
4735         std::map<std::string, int> groups;
4736         read_groups(L, 1, groups);
4737         ToolCapabilities tp = read_tool_capabilities(L, 2);
4738         if(lua_isnoneornil(L, 3))
4739                 push_hit_params(L, getHitParams(groups, &tp));
4740         else
4741                 push_hit_params(L, getHitParams(groups, &tp,
4742                                         luaL_checknumber(L, 3)));
4743         return 1;
4744 }
4745
4746 // get_current_modname()
4747 static int l_get_current_modname(lua_State *L)
4748 {
4749         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
4750         return 1;
4751 }
4752
4753 // get_modpath(modname)
4754 static int l_get_modpath(lua_State *L)
4755 {
4756         std::string modname = luaL_checkstring(L, 1);
4757         // Do it
4758         if(modname == "__builtin"){
4759                 std::string path = get_server(L)->getBuiltinLuaPath();
4760                 lua_pushstring(L, path.c_str());
4761                 return 1;
4762         }
4763         const ModSpec *mod = get_server(L)->getModSpec(modname);
4764         if(!mod){
4765                 lua_pushnil(L);
4766                 return 1;
4767         }
4768         lua_pushstring(L, mod->path.c_str());
4769         return 1;
4770 }
4771
4772 // get_modnames()
4773 // the returned list is sorted alphabetically for you
4774 static int l_get_modnames(lua_State *L)
4775 {
4776         // Get a list of mods
4777         core::list<std::string> mods_unsorted, mods_sorted;
4778         get_server(L)->getModNames(mods_unsorted);
4779
4780         // Take unsorted items from mods_unsorted and sort them into
4781         // mods_sorted; not great performance but the number of mods on a
4782         // server will likely be small.
4783         for(core::list<std::string>::Iterator i = mods_unsorted.begin();
4784             i != mods_unsorted.end(); i++)
4785         {
4786                 bool added = false;
4787                 for(core::list<std::string>::Iterator x = mods_sorted.begin();
4788                     x != mods_unsorted.end(); x++)
4789                 {
4790                         // I doubt anybody using Minetest will be using
4791                         // anything not ASCII based :)
4792                         if((*i).compare(*x) <= 0)
4793                         {
4794                                 mods_sorted.insert_before(x, *i);
4795                                 added = true;
4796                                 break;
4797                         }
4798                 }
4799                 if(!added)
4800                         mods_sorted.push_back(*i);
4801         }
4802
4803         // Get the table insertion function from Lua.
4804         lua_getglobal(L, "table");
4805         lua_getfield(L, -1, "insert");
4806         int insertion_func = lua_gettop(L);
4807
4808         // Package them up for Lua
4809         lua_newtable(L);
4810         int new_table = lua_gettop(L);
4811         core::list<std::string>::Iterator i = mods_sorted.begin();
4812         while(i != mods_sorted.end())
4813         {
4814                 lua_pushvalue(L, insertion_func);
4815                 lua_pushvalue(L, new_table);
4816                 lua_pushstring(L, (*i).c_str());
4817                 if(lua_pcall(L, 2, 0, 0) != 0)
4818                 {
4819                         script_error(L, "error: %s", lua_tostring(L, -1));
4820                 }
4821                 i++;
4822         }
4823         return 1;
4824 }
4825
4826 // get_worldpath()
4827 static int l_get_worldpath(lua_State *L)
4828 {
4829         std::string worldpath = get_server(L)->getWorldPath();
4830         lua_pushstring(L, worldpath.c_str());
4831         return 1;
4832 }
4833
4834 // sound_play(spec, parameters)
4835 static int l_sound_play(lua_State *L)
4836 {
4837         SimpleSoundSpec spec;
4838         read_soundspec(L, 1, spec);
4839         ServerSoundParams params;
4840         read_server_sound_params(L, 2, params);
4841         s32 handle = get_server(L)->playSound(spec, params);
4842         lua_pushinteger(L, handle);
4843         return 1;
4844 }
4845
4846 // sound_stop(handle)
4847 static int l_sound_stop(lua_State *L)
4848 {
4849         int handle = luaL_checkinteger(L, 1);
4850         get_server(L)->stopSound(handle);
4851         return 0;
4852 }
4853
4854 // is_singleplayer()
4855 static int l_is_singleplayer(lua_State *L)
4856 {
4857         lua_pushboolean(L, get_server(L)->isSingleplayer());
4858         return 1;
4859 }
4860
4861 // get_password_hash(name, raw_password)
4862 static int l_get_password_hash(lua_State *L)
4863 {
4864         std::string name = luaL_checkstring(L, 1);
4865         std::string raw_password = luaL_checkstring(L, 2);
4866         std::string hash = translatePassword(name,
4867                         narrow_to_wide(raw_password));
4868         lua_pushstring(L, hash.c_str());
4869         return 1;
4870 }
4871
4872 // notify_authentication_modified(name)
4873 static int l_notify_authentication_modified(lua_State *L)
4874 {
4875         std::string name = "";
4876         if(lua_isstring(L, 1))
4877                 name = lua_tostring(L, 1);
4878         get_server(L)->reportPrivsModified(name);
4879         return 0;
4880 }
4881
4882 // get_craft_result(input)
4883 static int l_get_craft_result(lua_State *L)
4884 {
4885         int input_i = 1;
4886         std::string method_s = getstringfield_default(L, input_i, "method", "normal");
4887         enum CraftMethod method = (CraftMethod)getenumfield(L, input_i, "method",
4888                                 es_CraftMethod, CRAFT_METHOD_NORMAL);
4889         int width = 1;
4890         lua_getfield(L, input_i, "width");
4891         if(lua_isnumber(L, -1))
4892                 width = luaL_checkinteger(L, -1);
4893         lua_pop(L, 1);
4894         lua_getfield(L, input_i, "items");
4895         std::vector<ItemStack> items = read_items(L, -1);
4896         lua_pop(L, 1); // items
4897         
4898         IGameDef *gdef = get_server(L);
4899         ICraftDefManager *cdef = gdef->cdef();
4900         CraftInput input(method, width, items);
4901         CraftOutput output;
4902         bool got = cdef->getCraftResult(input, output, true, gdef);
4903         lua_newtable(L); // output table
4904         if(got){
4905                 ItemStack item;
4906                 item.deSerialize(output.item, gdef->idef());
4907                 LuaItemStack::create(L, item);
4908                 lua_setfield(L, -2, "item");
4909                 setintfield(L, -1, "time", output.time);
4910         } else {
4911                 LuaItemStack::create(L, ItemStack());
4912                 lua_setfield(L, -2, "item");
4913                 setintfield(L, -1, "time", 0);
4914         }
4915         lua_newtable(L); // decremented input table
4916         lua_pushstring(L, method_s.c_str());
4917         lua_setfield(L, -2, "method");
4918         lua_pushinteger(L, width);
4919         lua_setfield(L, -2, "width");
4920         push_items(L, input.items);
4921         lua_setfield(L, -2, "items");
4922         return 2;
4923 }
4924
4925 // get_craft_recipe(result item)
4926 static int l_get_craft_recipe(lua_State *L)
4927 {
4928         int k = 0;
4929         char tmp[20];
4930         int input_i = 1;
4931         std::string o_item = luaL_checkstring(L,input_i);
4932         
4933         IGameDef *gdef = get_server(L);
4934         ICraftDefManager *cdef = gdef->cdef();
4935         CraftInput input;
4936         CraftOutput output(o_item,0);
4937         bool got = cdef->getCraftRecipe(input, output, gdef);
4938         lua_newtable(L); // output table
4939         if(got){
4940                 lua_newtable(L);
4941                 for(std::vector<ItemStack>::const_iterator
4942                         i = input.items.begin();
4943                         i != input.items.end(); i++, k++)
4944                 {
4945                         if (i->empty())
4946                         {
4947                                 continue;
4948                         }
4949                         sprintf(tmp,"%d",k);
4950                         lua_pushstring(L,tmp);
4951                         lua_pushstring(L,i->name.c_str());
4952                         lua_settable(L, -3);
4953                 }
4954                 lua_setfield(L, -2, "items");
4955                 setintfield(L, -1, "width", input.width);
4956                 switch (input.method) {
4957                 case CRAFT_METHOD_NORMAL:
4958                         lua_pushstring(L,"normal");
4959                         break;
4960                 case CRAFT_METHOD_COOKING:
4961                         lua_pushstring(L,"cooking");
4962                         break;
4963                 case CRAFT_METHOD_FUEL:
4964                         lua_pushstring(L,"fuel");
4965                         break;
4966                 default:
4967                         lua_pushstring(L,"unknown");
4968                 }
4969                 lua_setfield(L, -2, "type");
4970         } else {
4971                 lua_pushnil(L);
4972                 lua_setfield(L, -2, "items");
4973                 setintfield(L, -1, "width", 0);
4974         }
4975         return 1;
4976 }
4977
4978 // rollback_get_last_node_actor(p, range, seconds) -> actor, p, seconds
4979 static int l_rollback_get_last_node_actor(lua_State *L)
4980 {
4981         v3s16 p = read_v3s16(L, 1);
4982         int range = luaL_checknumber(L, 2);
4983         int seconds = luaL_checknumber(L, 3);
4984         Server *server = get_server(L);
4985         IRollbackManager *rollback = server->getRollbackManager();
4986         v3s16 act_p;
4987         int act_seconds = 0;
4988         std::string actor = rollback->getLastNodeActor(p, range, seconds, &act_p, &act_seconds);
4989         lua_pushstring(L, actor.c_str());
4990         push_v3s16(L, act_p);
4991         lua_pushnumber(L, act_seconds);
4992         return 3;
4993 }
4994
4995 // rollback_revert_actions_by(actor, seconds) -> bool, log messages
4996 static int l_rollback_revert_actions_by(lua_State *L)
4997 {
4998         std::string actor = luaL_checkstring(L, 1);
4999         int seconds = luaL_checknumber(L, 2);
5000         Server *server = get_server(L);
5001         IRollbackManager *rollback = server->getRollbackManager();
5002         std::list<RollbackAction> actions = rollback->getRevertActions(actor, seconds);
5003         std::list<std::string> log;
5004         bool success = server->rollbackRevertActions(actions, &log);
5005         // Push boolean result
5006         lua_pushboolean(L, success);
5007         // Get the table insert function and push the log table
5008         lua_getglobal(L, "table");
5009         lua_getfield(L, -1, "insert");
5010         int table_insert = lua_gettop(L);
5011         lua_newtable(L);
5012         int table = lua_gettop(L);
5013         for(std::list<std::string>::const_iterator i = log.begin();
5014                         i != log.end(); i++)
5015         {
5016                 lua_pushvalue(L, table_insert);
5017                 lua_pushvalue(L, table);
5018                 lua_pushstring(L, i->c_str());
5019                 if(lua_pcall(L, 2, 0, 0))
5020                         script_error(L, "error: %s", lua_tostring(L, -1));
5021         }
5022         lua_remove(L, -2); // Remove table
5023         lua_remove(L, -2); // Remove insert
5024         return 2;
5025 }
5026
5027 static const struct luaL_Reg minetest_f [] = {
5028         {"debug", l_debug},
5029         {"log", l_log},
5030         {"request_shutdown", l_request_shutdown},
5031         {"get_server_status", l_get_server_status},
5032         {"register_item_raw", l_register_item_raw},
5033         {"register_alias_raw", l_register_alias_raw},
5034         {"register_craft", l_register_craft},
5035         {"setting_set", l_setting_set},
5036         {"setting_get", l_setting_get},
5037         {"setting_getbool", l_setting_getbool},
5038         {"chat_send_all", l_chat_send_all},
5039         {"chat_send_player", l_chat_send_player},
5040         {"get_player_privs", l_get_player_privs},
5041         {"get_ban_list", l_get_ban_list},
5042         {"get_ban_description", l_get_ban_description},
5043         {"ban_player", l_ban_player},
5044         {"unban_player_or_ip", l_unban_player_of_ip},
5045         {"get_inventory", l_get_inventory},
5046         {"create_detached_inventory_raw", l_create_detached_inventory_raw},
5047         {"get_dig_params", l_get_dig_params},
5048         {"get_hit_params", l_get_hit_params},
5049         {"get_current_modname", l_get_current_modname},
5050         {"get_modpath", l_get_modpath},
5051         {"get_modnames", l_get_modnames},
5052         {"get_worldpath", l_get_worldpath},
5053         {"sound_play", l_sound_play},
5054         {"sound_stop", l_sound_stop},
5055         {"is_singleplayer", l_is_singleplayer},
5056         {"get_password_hash", l_get_password_hash},
5057         {"notify_authentication_modified", l_notify_authentication_modified},
5058         {"get_craft_result", l_get_craft_result},
5059         {"get_craft_recipe", l_get_craft_recipe},
5060         {"rollback_get_last_node_actor", l_rollback_get_last_node_actor},
5061         {"rollback_revert_actions_by", l_rollback_revert_actions_by},
5062         {NULL, NULL}
5063 };
5064
5065 /*
5066         Main export function
5067 */
5068
5069 void scriptapi_export(lua_State *L, Server *server)
5070 {
5071         realitycheck(L);
5072         assert(lua_checkstack(L, 20));
5073         verbosestream<<"scriptapi_export()"<<std::endl;
5074         StackUnroller stack_unroller(L);
5075
5076         // Store server as light userdata in registry
5077         lua_pushlightuserdata(L, server);
5078         lua_setfield(L, LUA_REGISTRYINDEX, "minetest_server");
5079
5080         // Register global functions in table minetest
5081         lua_newtable(L);
5082         luaL_register(L, NULL, minetest_f);
5083         lua_setglobal(L, "minetest");
5084         
5085         // Get the main minetest table
5086         lua_getglobal(L, "minetest");
5087
5088         // Add tables to minetest
5089         lua_newtable(L);
5090         lua_setfield(L, -2, "object_refs");
5091         lua_newtable(L);
5092         lua_setfield(L, -2, "luaentities");
5093
5094         // Register wrappers
5095         LuaItemStack::Register(L);
5096         InvRef::Register(L);
5097         NodeMetaRef::Register(L);
5098         NodeTimerRef::Register(L);
5099         ObjectRef::Register(L);
5100         EnvRef::Register(L);
5101         LuaPseudoRandom::Register(L);
5102         LuaPerlinNoise::Register(L);
5103 }
5104
5105 bool scriptapi_loadmod(lua_State *L, const std::string &scriptpath,
5106                 const std::string &modname)
5107 {
5108         ModNameStorer modnamestorer(L, modname);
5109
5110         if(!string_allowed(modname, "abcdefghijklmnopqrstuvwxyz"
5111                         "0123456789_")){
5112                 errorstream<<"Error loading mod \""<<modname
5113                                 <<"\": modname does not follow naming conventions: "
5114                                 <<"Only chararacters [a-z0-9_] are allowed."<<std::endl;
5115                 return false;
5116         }
5117         
5118         bool success = false;
5119
5120         try{
5121                 success = script_load(L, scriptpath.c_str());
5122         }
5123         catch(LuaError &e){
5124                 errorstream<<"Error loading mod \""<<modname
5125                                 <<"\": "<<e.what()<<std::endl;
5126         }
5127
5128         return success;
5129 }
5130
5131 void scriptapi_add_environment(lua_State *L, ServerEnvironment *env)
5132 {
5133         realitycheck(L);
5134         assert(lua_checkstack(L, 20));
5135         verbosestream<<"scriptapi_add_environment"<<std::endl;
5136         StackUnroller stack_unroller(L);
5137
5138         // Create EnvRef on stack
5139         EnvRef::create(L, env);
5140         int envref = lua_gettop(L);
5141
5142         // minetest.env = envref
5143         lua_getglobal(L, "minetest");
5144         luaL_checktype(L, -1, LUA_TTABLE);
5145         lua_pushvalue(L, envref);
5146         lua_setfield(L, -2, "env");
5147
5148         // Store environment as light userdata in registry
5149         lua_pushlightuserdata(L, env);
5150         lua_setfield(L, LUA_REGISTRYINDEX, "minetest_env");
5151
5152         /*
5153                 Add ActiveBlockModifiers to environment
5154         */
5155
5156         // Get minetest.registered_abms
5157         lua_getglobal(L, "minetest");
5158         lua_getfield(L, -1, "registered_abms");
5159         luaL_checktype(L, -1, LUA_TTABLE);
5160         int registered_abms = lua_gettop(L);
5161         
5162         if(lua_istable(L, registered_abms)){
5163                 int table = lua_gettop(L);
5164                 lua_pushnil(L);
5165                 while(lua_next(L, table) != 0){
5166                         // key at index -2 and value at index -1
5167                         int id = lua_tonumber(L, -2);
5168                         int current_abm = lua_gettop(L);
5169
5170                         std::set<std::string> trigger_contents;
5171                         lua_getfield(L, current_abm, "nodenames");
5172                         if(lua_istable(L, -1)){
5173                                 int table = lua_gettop(L);
5174                                 lua_pushnil(L);
5175                                 while(lua_next(L, table) != 0){
5176                                         // key at index -2 and value at index -1
5177                                         luaL_checktype(L, -1, LUA_TSTRING);
5178                                         trigger_contents.insert(lua_tostring(L, -1));
5179                                         // removes value, keeps key for next iteration
5180                                         lua_pop(L, 1);
5181                                 }
5182                         } else if(lua_isstring(L, -1)){
5183                                 trigger_contents.insert(lua_tostring(L, -1));
5184                         }
5185                         lua_pop(L, 1);
5186
5187                         std::set<std::string> required_neighbors;
5188                         lua_getfield(L, current_abm, "neighbors");
5189                         if(lua_istable(L, -1)){
5190                                 int table = lua_gettop(L);
5191                                 lua_pushnil(L);
5192                                 while(lua_next(L, table) != 0){
5193                                         // key at index -2 and value at index -1
5194                                         luaL_checktype(L, -1, LUA_TSTRING);
5195                                         required_neighbors.insert(lua_tostring(L, -1));
5196                                         // removes value, keeps key for next iteration
5197                                         lua_pop(L, 1);
5198                                 }
5199                         } else if(lua_isstring(L, -1)){
5200                                 required_neighbors.insert(lua_tostring(L, -1));
5201                         }
5202                         lua_pop(L, 1);
5203
5204                         float trigger_interval = 10.0;
5205                         getfloatfield(L, current_abm, "interval", trigger_interval);
5206
5207                         int trigger_chance = 50;
5208                         getintfield(L, current_abm, "chance", trigger_chance);
5209
5210                         LuaABM *abm = new LuaABM(L, id, trigger_contents,
5211                                         required_neighbors, trigger_interval, trigger_chance);
5212                         
5213                         env->addActiveBlockModifier(abm);
5214
5215                         // removes value, keeps key for next iteration
5216                         lua_pop(L, 1);
5217                 }
5218         }
5219         lua_pop(L, 1);
5220 }
5221
5222 #if 0
5223 // Dump stack top with the dump2 function
5224 static void dump2(lua_State *L, const char *name)
5225 {
5226         // Dump object (debug)
5227         lua_getglobal(L, "dump2");
5228         luaL_checktype(L, -1, LUA_TFUNCTION);
5229         lua_pushvalue(L, -2); // Get previous stack top as first parameter
5230         lua_pushstring(L, name);
5231         if(lua_pcall(L, 2, 0, 0))
5232                 script_error(L, "error: %s", lua_tostring(L, -1));
5233 }
5234 #endif
5235
5236 /*
5237         object_reference
5238 */
5239
5240 void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj)
5241 {
5242         realitycheck(L);
5243         assert(lua_checkstack(L, 20));
5244         //infostream<<"scriptapi_add_object_reference: id="<<cobj->getId()<<std::endl;
5245         StackUnroller stack_unroller(L);
5246
5247         // Create object on stack
5248         ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack
5249         int object = lua_gettop(L);
5250
5251         // Get minetest.object_refs table
5252         lua_getglobal(L, "minetest");
5253         lua_getfield(L, -1, "object_refs");
5254         luaL_checktype(L, -1, LUA_TTABLE);
5255         int objectstable = lua_gettop(L);
5256         
5257         // object_refs[id] = object
5258         lua_pushnumber(L, cobj->getId()); // Push id
5259         lua_pushvalue(L, object); // Copy object to top of stack
5260         lua_settable(L, objectstable);
5261 }
5262
5263 void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj)
5264 {
5265         realitycheck(L);
5266         assert(lua_checkstack(L, 20));
5267         //infostream<<"scriptapi_rm_object_reference: id="<<cobj->getId()<<std::endl;
5268         StackUnroller stack_unroller(L);
5269
5270         // Get minetest.object_refs table
5271         lua_getglobal(L, "minetest");
5272         lua_getfield(L, -1, "object_refs");
5273         luaL_checktype(L, -1, LUA_TTABLE);
5274         int objectstable = lua_gettop(L);
5275         
5276         // Get object_refs[id]
5277         lua_pushnumber(L, cobj->getId()); // Push id
5278         lua_gettable(L, objectstable);
5279         // Set object reference to NULL
5280         ObjectRef::set_null(L);
5281         lua_pop(L, 1); // pop object
5282
5283         // Set object_refs[id] = nil
5284         lua_pushnumber(L, cobj->getId()); // Push id
5285         lua_pushnil(L);
5286         lua_settable(L, objectstable);
5287 }
5288
5289 /*
5290         misc
5291 */
5292
5293 // What scriptapi_run_callbacks does with the return values of callbacks.
5294 // Regardless of the mode, if only one callback is defined,
5295 // its return value is the total return value.
5296 // Modes only affect the case where 0 or >= 2 callbacks are defined.
5297 enum RunCallbacksMode
5298 {
5299         // Returns the return value of the first callback
5300         // Returns nil if list of callbacks is empty
5301         RUN_CALLBACKS_MODE_FIRST,
5302         // Returns the return value of the last callback
5303         // Returns nil if list of callbacks is empty
5304         RUN_CALLBACKS_MODE_LAST,
5305         // If any callback returns a false value, the first such is returned
5306         // Otherwise, the first callback's return value (trueish) is returned
5307         // Returns true if list of callbacks is empty
5308         RUN_CALLBACKS_MODE_AND,
5309         // Like above, but stops calling callbacks (short circuit)
5310         // after seeing the first false value
5311         RUN_CALLBACKS_MODE_AND_SC,
5312         // If any callback returns a true value, the first such is returned
5313         // Otherwise, the first callback's return value (falseish) is returned
5314         // Returns false if list of callbacks is empty
5315         RUN_CALLBACKS_MODE_OR,
5316         // Like above, but stops calling callbacks (short circuit)
5317         // after seeing the first true value
5318         RUN_CALLBACKS_MODE_OR_SC,
5319         // Note: "a true value" and "a false value" refer to values that
5320         // are converted by lua_toboolean to true or false, respectively.
5321 };
5322
5323 // Push the list of callbacks (a lua table).
5324 // Then push nargs arguments.
5325 // Then call this function, which
5326 // - runs the callbacks
5327 // - removes the table and arguments from the lua stack
5328 // - pushes the return value, computed depending on mode
5329 static void scriptapi_run_callbacks(lua_State *L, int nargs,
5330                 RunCallbacksMode mode)
5331 {
5332         // Insert the return value into the lua stack, below the table
5333         assert(lua_gettop(L) >= nargs + 1);
5334         lua_pushnil(L);
5335         lua_insert(L, -(nargs + 1) - 1);
5336         // Stack now looks like this:
5337         // ... <return value = nil> <table> <arg#1> <arg#2> ... <arg#n>
5338
5339         int rv = lua_gettop(L) - nargs - 1;
5340         int table = rv + 1;
5341         int arg = table + 1;
5342
5343         luaL_checktype(L, table, LUA_TTABLE);
5344
5345         // Foreach
5346         lua_pushnil(L);
5347         bool first_loop = true;
5348         while(lua_next(L, table) != 0){
5349                 // key at index -2 and value at index -1
5350                 luaL_checktype(L, -1, LUA_TFUNCTION);
5351                 // Call function
5352                 for(int i = 0; i < nargs; i++)
5353                         lua_pushvalue(L, arg+i);
5354                 if(lua_pcall(L, nargs, 1, 0))
5355                         script_error(L, "error: %s", lua_tostring(L, -1));
5356
5357                 // Move return value to designated space in stack
5358                 // Or pop it
5359                 if(first_loop){
5360                         // Result of first callback is always moved
5361                         lua_replace(L, rv);
5362                         first_loop = false;
5363                 } else {
5364                         // Otherwise, what happens depends on the mode
5365                         if(mode == RUN_CALLBACKS_MODE_FIRST)
5366                                 lua_pop(L, 1);
5367                         else if(mode == RUN_CALLBACKS_MODE_LAST)
5368                                 lua_replace(L, rv);
5369                         else if(mode == RUN_CALLBACKS_MODE_AND ||
5370                                         mode == RUN_CALLBACKS_MODE_AND_SC){
5371                                 if(lua_toboolean(L, rv) == true &&
5372                                                 lua_toboolean(L, -1) == false)
5373                                         lua_replace(L, rv);
5374                                 else
5375                                         lua_pop(L, 1);
5376                         }
5377                         else if(mode == RUN_CALLBACKS_MODE_OR ||
5378                                         mode == RUN_CALLBACKS_MODE_OR_SC){
5379                                 if(lua_toboolean(L, rv) == false &&
5380                                                 lua_toboolean(L, -1) == true)
5381                                         lua_replace(L, rv);
5382                                 else
5383                                         lua_pop(L, 1);
5384                         }
5385                         else
5386                                 assert(0);
5387                 }
5388
5389                 // Handle short circuit modes
5390                 if(mode == RUN_CALLBACKS_MODE_AND_SC &&
5391                                 lua_toboolean(L, rv) == false)
5392                         break;
5393                 else if(mode == RUN_CALLBACKS_MODE_OR_SC &&
5394                                 lua_toboolean(L, rv) == true)
5395                         break;
5396
5397                 // value removed, keep key for next iteration
5398         }
5399
5400         // Remove stuff from stack, leaving only the return value
5401         lua_settop(L, rv);
5402
5403         // Fix return value in case no callbacks were called
5404         if(first_loop){
5405                 if(mode == RUN_CALLBACKS_MODE_AND ||
5406                                 mode == RUN_CALLBACKS_MODE_AND_SC){
5407                         lua_pop(L, 1);
5408                         lua_pushboolean(L, true);
5409                 }
5410                 else if(mode == RUN_CALLBACKS_MODE_OR ||
5411                                 mode == RUN_CALLBACKS_MODE_OR_SC){
5412                         lua_pop(L, 1);
5413                         lua_pushboolean(L, false);
5414                 }
5415         }
5416 }
5417
5418 bool scriptapi_on_chat_message(lua_State *L, const std::string &name,
5419                 const std::string &message)
5420 {
5421         realitycheck(L);
5422         assert(lua_checkstack(L, 20));
5423         StackUnroller stack_unroller(L);
5424
5425         // Get minetest.registered_on_chat_messages
5426         lua_getglobal(L, "minetest");
5427         lua_getfield(L, -1, "registered_on_chat_messages");
5428         // Call callbacks
5429         lua_pushstring(L, name.c_str());
5430         lua_pushstring(L, message.c_str());
5431         scriptapi_run_callbacks(L, 2, RUN_CALLBACKS_MODE_OR_SC);
5432         bool ate = lua_toboolean(L, -1);
5433         return ate;
5434 }
5435
5436 void scriptapi_on_newplayer(lua_State *L, ServerActiveObject *player)
5437 {
5438         realitycheck(L);
5439         assert(lua_checkstack(L, 20));
5440         StackUnroller stack_unroller(L);
5441
5442         // Get minetest.registered_on_newplayers
5443         lua_getglobal(L, "minetest");
5444         lua_getfield(L, -1, "registered_on_newplayers");
5445         // Call callbacks
5446         objectref_get_or_create(L, player);
5447         scriptapi_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
5448 }
5449
5450 void scriptapi_on_dieplayer(lua_State *L, ServerActiveObject *player)
5451 {
5452         realitycheck(L);
5453         assert(lua_checkstack(L, 20));
5454         StackUnroller stack_unroller(L);
5455
5456         // Get minetest.registered_on_dieplayers
5457         lua_getglobal(L, "minetest");
5458         lua_getfield(L, -1, "registered_on_dieplayers");
5459         // Call callbacks
5460         objectref_get_or_create(L, player);
5461         scriptapi_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
5462 }
5463
5464 bool scriptapi_on_respawnplayer(lua_State *L, ServerActiveObject *player)
5465 {
5466         realitycheck(L);
5467         assert(lua_checkstack(L, 20));
5468         StackUnroller stack_unroller(L);
5469
5470         // Get minetest.registered_on_respawnplayers
5471         lua_getglobal(L, "minetest");
5472         lua_getfield(L, -1, "registered_on_respawnplayers");
5473         // Call callbacks
5474         objectref_get_or_create(L, player);
5475         scriptapi_run_callbacks(L, 1, RUN_CALLBACKS_MODE_OR);
5476         bool positioning_handled_by_some = lua_toboolean(L, -1);
5477         return positioning_handled_by_some;
5478 }
5479
5480 void scriptapi_on_joinplayer(lua_State *L, ServerActiveObject *player)
5481 {
5482         realitycheck(L);
5483         assert(lua_checkstack(L, 20));
5484         StackUnroller stack_unroller(L);
5485
5486         // Get minetest.registered_on_joinplayers
5487         lua_getglobal(L, "minetest");
5488         lua_getfield(L, -1, "registered_on_joinplayers");
5489         // Call callbacks
5490         objectref_get_or_create(L, player);
5491         scriptapi_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
5492 }
5493
5494 void scriptapi_on_leaveplayer(lua_State *L, ServerActiveObject *player)
5495 {
5496         realitycheck(L);
5497         assert(lua_checkstack(L, 20));
5498         StackUnroller stack_unroller(L);
5499
5500         // Get minetest.registered_on_leaveplayers
5501         lua_getglobal(L, "minetest");
5502         lua_getfield(L, -1, "registered_on_leaveplayers");
5503         // Call callbacks
5504         objectref_get_or_create(L, player);
5505         scriptapi_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
5506 }
5507
5508 static void get_auth_handler(lua_State *L)
5509 {
5510         lua_getglobal(L, "minetest");
5511         lua_getfield(L, -1, "registered_auth_handler");
5512         if(lua_isnil(L, -1)){
5513                 lua_pop(L, 1);
5514                 lua_getfield(L, -1, "builtin_auth_handler");
5515         }
5516         if(lua_type(L, -1) != LUA_TTABLE)
5517                 throw LuaError(L, "Authentication handler table not valid");
5518 }
5519
5520 bool scriptapi_get_auth(lua_State *L, const std::string &playername,
5521                 std::string *dst_password, std::set<std::string> *dst_privs)
5522 {
5523         realitycheck(L);
5524         assert(lua_checkstack(L, 20));
5525         StackUnroller stack_unroller(L);
5526         
5527         get_auth_handler(L);
5528         lua_getfield(L, -1, "get_auth");
5529         if(lua_type(L, -1) != LUA_TFUNCTION)
5530                 throw LuaError(L, "Authentication handler missing get_auth");
5531         lua_pushstring(L, playername.c_str());
5532         if(lua_pcall(L, 1, 1, 0))
5533                 script_error(L, "error: %s", lua_tostring(L, -1));
5534         
5535         // nil = login not allowed
5536         if(lua_isnil(L, -1))
5537                 return false;
5538         luaL_checktype(L, -1, LUA_TTABLE);
5539         
5540         std::string password;
5541         bool found = getstringfield(L, -1, "password", password);
5542         if(!found)
5543                 throw LuaError(L, "Authentication handler didn't return password");
5544         if(dst_password)
5545                 *dst_password = password;
5546
5547         lua_getfield(L, -1, "privileges");
5548         if(!lua_istable(L, -1))
5549                 throw LuaError(L,
5550                                 "Authentication handler didn't return privilege table");
5551         if(dst_privs)
5552                 read_privileges(L, -1, *dst_privs);
5553         lua_pop(L, 1);
5554         
5555         return true;
5556 }
5557
5558 void scriptapi_create_auth(lua_State *L, const std::string &playername,
5559                 const std::string &password)
5560 {
5561         realitycheck(L);
5562         assert(lua_checkstack(L, 20));
5563         StackUnroller stack_unroller(L);
5564         
5565         get_auth_handler(L);
5566         lua_getfield(L, -1, "create_auth");
5567         if(lua_type(L, -1) != LUA_TFUNCTION)
5568                 throw LuaError(L, "Authentication handler missing create_auth");
5569         lua_pushstring(L, playername.c_str());
5570         lua_pushstring(L, password.c_str());
5571         if(lua_pcall(L, 2, 0, 0))
5572                 script_error(L, "error: %s", lua_tostring(L, -1));
5573 }
5574
5575 bool scriptapi_set_password(lua_State *L, const std::string &playername,
5576                 const std::string &password)
5577 {
5578         realitycheck(L);
5579         assert(lua_checkstack(L, 20));
5580         StackUnroller stack_unroller(L);
5581         
5582         get_auth_handler(L);
5583         lua_getfield(L, -1, "set_password");
5584         if(lua_type(L, -1) != LUA_TFUNCTION)
5585                 throw LuaError(L, "Authentication handler missing set_password");
5586         lua_pushstring(L, playername.c_str());
5587         lua_pushstring(L, password.c_str());
5588         if(lua_pcall(L, 2, 1, 0))
5589                 script_error(L, "error: %s", lua_tostring(L, -1));
5590         return lua_toboolean(L, -1);
5591 }
5592
5593 /*
5594         player
5595 */
5596
5597 void scriptapi_on_player_receive_fields(lua_State *L, 
5598                 ServerActiveObject *player,
5599                 const std::string &formname,
5600                 const std::map<std::string, std::string> &fields)
5601 {
5602         realitycheck(L);
5603         assert(lua_checkstack(L, 20));
5604         StackUnroller stack_unroller(L);
5605
5606         // Get minetest.registered_on_chat_messages
5607         lua_getglobal(L, "minetest");
5608         lua_getfield(L, -1, "registered_on_player_receive_fields");
5609         // Call callbacks
5610         // param 1
5611         objectref_get_or_create(L, player);
5612         // param 2
5613         lua_pushstring(L, formname.c_str());
5614         // param 3
5615         lua_newtable(L);
5616         for(std::map<std::string, std::string>::const_iterator
5617                         i = fields.begin(); i != fields.end(); i++){
5618                 const std::string &name = i->first;
5619                 const std::string &value = i->second;
5620                 lua_pushstring(L, name.c_str());
5621                 lua_pushlstring(L, value.c_str(), value.size());
5622                 lua_settable(L, -3);
5623         }
5624         scriptapi_run_callbacks(L, 3, RUN_CALLBACKS_MODE_OR_SC);
5625 }
5626
5627 /*
5628         item callbacks and node callbacks
5629 */
5630
5631 // Retrieves minetest.registered_items[name][callbackname]
5632 // If that is nil or on error, return false and stack is unchanged
5633 // If that is a function, returns true and pushes the
5634 // function onto the stack
5635 // If minetest.registered_items[name] doesn't exist, minetest.nodedef_default
5636 // is tried instead so unknown items can still be manipulated to some degree
5637 static bool get_item_callback(lua_State *L,
5638                 const char *name, const char *callbackname)
5639 {
5640         lua_getglobal(L, "minetest");
5641         lua_getfield(L, -1, "registered_items");
5642         lua_remove(L, -2);
5643         luaL_checktype(L, -1, LUA_TTABLE);
5644         lua_getfield(L, -1, name);
5645         lua_remove(L, -2);
5646         // Should be a table
5647         if(lua_type(L, -1) != LUA_TTABLE)
5648         {
5649                 // Report error and clean up
5650                 errorstream<<"Item \""<<name<<"\" not defined"<<std::endl;
5651                 lua_pop(L, 1);
5652
5653                 // Try minetest.nodedef_default instead
5654                 lua_getglobal(L, "minetest");
5655                 lua_getfield(L, -1, "nodedef_default");
5656                 lua_remove(L, -2);
5657                 luaL_checktype(L, -1, LUA_TTABLE);
5658         }
5659         lua_getfield(L, -1, callbackname);
5660         lua_remove(L, -2);
5661         // Should be a function or nil
5662         if(lua_type(L, -1) == LUA_TFUNCTION)
5663         {
5664                 return true;
5665         }
5666         else if(lua_isnil(L, -1))
5667         {
5668                 lua_pop(L, 1);
5669                 return false;
5670         }
5671         else
5672         {
5673                 errorstream<<"Item \""<<name<<"\" callback \""
5674                         <<callbackname<<" is not a function"<<std::endl;
5675                 lua_pop(L, 1);
5676                 return false;
5677         }
5678 }
5679
5680 bool scriptapi_item_on_drop(lua_State *L, ItemStack &item,
5681                 ServerActiveObject *dropper, v3f pos)
5682 {
5683         realitycheck(L);
5684         assert(lua_checkstack(L, 20));
5685         StackUnroller stack_unroller(L);
5686
5687         // Push callback function on stack
5688         if(!get_item_callback(L, item.name.c_str(), "on_drop"))
5689                 return false;
5690
5691         // Call function
5692         LuaItemStack::create(L, item);
5693         objectref_get_or_create(L, dropper);
5694         pushFloatPos(L, pos);
5695         if(lua_pcall(L, 3, 1, 0))
5696                 script_error(L, "error: %s", lua_tostring(L, -1));
5697         if(!lua_isnil(L, -1))
5698                 item = read_item(L, -1);
5699         return true;
5700 }
5701
5702 bool scriptapi_item_on_place(lua_State *L, ItemStack &item,
5703                 ServerActiveObject *placer, const PointedThing &pointed)
5704 {
5705         realitycheck(L);
5706         assert(lua_checkstack(L, 20));
5707         StackUnroller stack_unroller(L);
5708
5709         // Push callback function on stack
5710         if(!get_item_callback(L, item.name.c_str(), "on_place"))
5711                 return false;
5712
5713         // Call function
5714         LuaItemStack::create(L, item);
5715         objectref_get_or_create(L, placer);
5716         push_pointed_thing(L, pointed);
5717         if(lua_pcall(L, 3, 1, 0))
5718                 script_error(L, "error: %s", lua_tostring(L, -1));
5719         if(!lua_isnil(L, -1))
5720                 item = read_item(L, -1);
5721         return true;
5722 }
5723
5724 bool scriptapi_item_on_use(lua_State *L, ItemStack &item,
5725                 ServerActiveObject *user, const PointedThing &pointed)
5726 {
5727         realitycheck(L);
5728         assert(lua_checkstack(L, 20));
5729         StackUnroller stack_unroller(L);
5730
5731         // Push callback function on stack
5732         if(!get_item_callback(L, item.name.c_str(), "on_use"))
5733                 return false;
5734
5735         // Call function
5736         LuaItemStack::create(L, item);
5737         objectref_get_or_create(L, user);
5738         push_pointed_thing(L, pointed);
5739         if(lua_pcall(L, 3, 1, 0))
5740                 script_error(L, "error: %s", lua_tostring(L, -1));
5741         if(!lua_isnil(L, -1))
5742                 item = read_item(L, -1);
5743         return true;
5744 }
5745
5746 bool scriptapi_node_on_punch(lua_State *L, v3s16 p, MapNode node,
5747                 ServerActiveObject *puncher)
5748 {
5749         realitycheck(L);
5750         assert(lua_checkstack(L, 20));
5751         StackUnroller stack_unroller(L);
5752
5753         INodeDefManager *ndef = get_server(L)->ndef();
5754
5755         // Push callback function on stack
5756         if(!get_item_callback(L, ndef->get(node).name.c_str(), "on_punch"))
5757                 return false;
5758
5759         // Call function
5760         push_v3s16(L, p);
5761         pushnode(L, node, ndef);
5762         objectref_get_or_create(L, puncher);
5763         if(lua_pcall(L, 3, 0, 0))
5764                 script_error(L, "error: %s", lua_tostring(L, -1));
5765         return true;
5766 }
5767
5768 bool scriptapi_node_on_dig(lua_State *L, v3s16 p, MapNode node,
5769                 ServerActiveObject *digger)
5770 {
5771         realitycheck(L);
5772         assert(lua_checkstack(L, 20));
5773         StackUnroller stack_unroller(L);
5774
5775         INodeDefManager *ndef = get_server(L)->ndef();
5776
5777         // Push callback function on stack
5778         if(!get_item_callback(L, ndef->get(node).name.c_str(), "on_dig"))
5779                 return false;
5780
5781         // Call function
5782         push_v3s16(L, p);
5783         pushnode(L, node, ndef);
5784         objectref_get_or_create(L, digger);
5785         if(lua_pcall(L, 3, 0, 0))
5786                 script_error(L, "error: %s", lua_tostring(L, -1));
5787         return true;
5788 }
5789
5790 void scriptapi_node_on_construct(lua_State *L, v3s16 p, MapNode node)
5791 {
5792         realitycheck(L);
5793         assert(lua_checkstack(L, 20));
5794         StackUnroller stack_unroller(L);
5795
5796         INodeDefManager *ndef = get_server(L)->ndef();
5797
5798         // Push callback function on stack
5799         if(!get_item_callback(L, ndef->get(node).name.c_str(), "on_construct"))
5800                 return;
5801
5802         // Call function
5803         push_v3s16(L, p);
5804         if(lua_pcall(L, 1, 0, 0))
5805                 script_error(L, "error: %s", lua_tostring(L, -1));
5806 }
5807
5808 void scriptapi_node_on_destruct(lua_State *L, v3s16 p, MapNode node)
5809 {
5810         realitycheck(L);
5811         assert(lua_checkstack(L, 20));
5812         StackUnroller stack_unroller(L);
5813
5814         INodeDefManager *ndef = get_server(L)->ndef();
5815
5816         // Push callback function on stack
5817         if(!get_item_callback(L, ndef->get(node).name.c_str(), "on_destruct"))
5818                 return;
5819
5820         // Call function
5821         push_v3s16(L, p);
5822         if(lua_pcall(L, 1, 0, 0))
5823                 script_error(L, "error: %s", lua_tostring(L, -1));
5824 }
5825
5826 void scriptapi_node_after_destruct(lua_State *L, v3s16 p, MapNode node)
5827 {
5828         realitycheck(L);
5829         assert(lua_checkstack(L, 20));
5830         StackUnroller stack_unroller(L);
5831
5832         INodeDefManager *ndef = get_server(L)->ndef();
5833
5834         // Push callback function on stack
5835         if(!get_item_callback(L, ndef->get(node).name.c_str(), "after_destruct"))
5836                 return;
5837
5838         // Call function
5839         push_v3s16(L, p);
5840         pushnode(L, node, ndef);
5841         if(lua_pcall(L, 2, 0, 0))
5842                 script_error(L, "error: %s", lua_tostring(L, -1));
5843 }
5844
5845 bool scriptapi_node_on_timer(lua_State *L, v3s16 p, MapNode node, f32 dtime)
5846 {
5847         realitycheck(L);
5848         assert(lua_checkstack(L, 20));
5849         StackUnroller stack_unroller(L);
5850
5851         INodeDefManager *ndef = get_server(L)->ndef();
5852
5853         // Push callback function on stack
5854         if(!get_item_callback(L, ndef->get(node).name.c_str(), "on_timer"))
5855                 return false;
5856
5857         // Call function
5858         push_v3s16(L, p);
5859         lua_pushnumber(L,dtime);
5860         if(lua_pcall(L, 2, 1, 0))
5861                 script_error(L, "error: %s", lua_tostring(L, -1));
5862         if(lua_isboolean(L,-1) && lua_toboolean(L,-1) == true)
5863                 return true;
5864         
5865         return false;
5866 }
5867
5868 void scriptapi_node_on_receive_fields(lua_State *L, v3s16 p,
5869                 const std::string &formname,
5870                 const std::map<std::string, std::string> &fields,
5871                 ServerActiveObject *sender)
5872 {
5873         realitycheck(L);
5874         assert(lua_checkstack(L, 20));
5875         StackUnroller stack_unroller(L);
5876
5877         INodeDefManager *ndef = get_server(L)->ndef();
5878         
5879         // If node doesn't exist, we don't know what callback to call
5880         MapNode node = get_env(L)->getMap().getNodeNoEx(p);
5881         if(node.getContent() == CONTENT_IGNORE)
5882                 return;
5883
5884         // Push callback function on stack
5885         if(!get_item_callback(L, ndef->get(node).name.c_str(), "on_receive_fields"))
5886                 return;
5887
5888         // Call function
5889         // param 1
5890         push_v3s16(L, p);
5891         // param 2
5892         lua_pushstring(L, formname.c_str());
5893         // param 3
5894         lua_newtable(L);
5895         for(std::map<std::string, std::string>::const_iterator
5896                         i = fields.begin(); i != fields.end(); i++){
5897                 const std::string &name = i->first;
5898                 const std::string &value = i->second;
5899                 lua_pushstring(L, name.c_str());
5900                 lua_pushlstring(L, value.c_str(), value.size());
5901                 lua_settable(L, -3);
5902         }
5903         // param 4
5904         objectref_get_or_create(L, sender);
5905         if(lua_pcall(L, 4, 0, 0))
5906                 script_error(L, "error: %s", lua_tostring(L, -1));
5907 }
5908
5909 /*
5910         Node metadata inventory callbacks
5911 */
5912
5913 // Return number of accepted items to be moved
5914 int scriptapi_nodemeta_inventory_allow_move(lua_State *L, v3s16 p,
5915                 const std::string &from_list, int from_index,
5916                 const std::string &to_list, int to_index,
5917                 int count, ServerActiveObject *player)
5918 {
5919         realitycheck(L);
5920         assert(lua_checkstack(L, 20));
5921         StackUnroller stack_unroller(L);
5922
5923         INodeDefManager *ndef = get_server(L)->ndef();
5924
5925         // If node doesn't exist, we don't know what callback to call
5926         MapNode node = get_env(L)->getMap().getNodeNoEx(p);
5927         if(node.getContent() == CONTENT_IGNORE)
5928                 return 0;
5929
5930         // Push callback function on stack
5931         if(!get_item_callback(L, ndef->get(node).name.c_str(),
5932                         "allow_metadata_inventory_move"))
5933                 return count;
5934
5935         // function(pos, from_list, from_index, to_list, to_index, count, player)
5936         // pos
5937         push_v3s16(L, p);
5938         // from_list
5939         lua_pushstring(L, from_list.c_str());
5940         // from_index
5941         lua_pushinteger(L, from_index + 1);
5942         // to_list
5943         lua_pushstring(L, to_list.c_str());
5944         // to_index
5945         lua_pushinteger(L, to_index + 1);
5946         // count
5947         lua_pushinteger(L, count);
5948         // player
5949         objectref_get_or_create(L, player);
5950         if(lua_pcall(L, 7, 1, 0))
5951                 script_error(L, "error: %s", lua_tostring(L, -1));
5952         if(!lua_isnumber(L, -1))
5953                 throw LuaError(L, "allow_metadata_inventory_move should return a number");
5954         return luaL_checkinteger(L, -1);
5955 }
5956
5957 // Return number of accepted items to be put
5958 int scriptapi_nodemeta_inventory_allow_put(lua_State *L, v3s16 p,
5959                 const std::string &listname, int index, ItemStack &stack,
5960                 ServerActiveObject *player)
5961 {
5962         realitycheck(L);
5963         assert(lua_checkstack(L, 20));
5964         StackUnroller stack_unroller(L);
5965
5966         INodeDefManager *ndef = get_server(L)->ndef();
5967
5968         // If node doesn't exist, we don't know what callback to call
5969         MapNode node = get_env(L)->getMap().getNodeNoEx(p);
5970         if(node.getContent() == CONTENT_IGNORE)
5971                 return 0;
5972
5973         // Push callback function on stack
5974         if(!get_item_callback(L, ndef->get(node).name.c_str(),
5975                         "allow_metadata_inventory_put"))
5976                 return stack.count;
5977
5978         // Call function(pos, listname, index, stack, player)
5979         // pos
5980         push_v3s16(L, p);
5981         // listname
5982         lua_pushstring(L, listname.c_str());
5983         // index
5984         lua_pushinteger(L, index + 1);
5985         // stack
5986         LuaItemStack::create(L, stack);
5987         // player
5988         objectref_get_or_create(L, player);
5989         if(lua_pcall(L, 5, 1, 0))
5990                 script_error(L, "error: %s", lua_tostring(L, -1));
5991         if(!lua_isnumber(L, -1))
5992                 throw LuaError(L, "allow_metadata_inventory_put should return a number");
5993         return luaL_checkinteger(L, -1);
5994 }
5995
5996 // Return number of accepted items to be taken
5997 int scriptapi_nodemeta_inventory_allow_take(lua_State *L, v3s16 p,
5998                 const std::string &listname, int index, ItemStack &stack,
5999                 ServerActiveObject *player)
6000 {
6001         realitycheck(L);
6002         assert(lua_checkstack(L, 20));
6003         StackUnroller stack_unroller(L);
6004
6005         INodeDefManager *ndef = get_server(L)->ndef();
6006
6007         // If node doesn't exist, we don't know what callback to call
6008         MapNode node = get_env(L)->getMap().getNodeNoEx(p);
6009         if(node.getContent() == CONTENT_IGNORE)
6010                 return 0;
6011
6012         // Push callback function on stack
6013         if(!get_item_callback(L, ndef->get(node).name.c_str(),
6014                         "allow_metadata_inventory_take"))
6015                 return stack.count;
6016
6017         // Call function(pos, listname, index, count, player)
6018         // pos
6019         push_v3s16(L, p);
6020         // listname
6021         lua_pushstring(L, listname.c_str());
6022         // index
6023         lua_pushinteger(L, index + 1);
6024         // stack
6025         LuaItemStack::create(L, stack);
6026         // player
6027         objectref_get_or_create(L, player);
6028         if(lua_pcall(L, 5, 1, 0))
6029                 script_error(L, "error: %s", lua_tostring(L, -1));
6030         if(!lua_isnumber(L, -1))
6031                 throw LuaError(L, "allow_metadata_inventory_take should return a number");
6032         return luaL_checkinteger(L, -1);
6033 }
6034
6035 // Report moved items
6036 void scriptapi_nodemeta_inventory_on_move(lua_State *L, v3s16 p,
6037                 const std::string &from_list, int from_index,
6038                 const std::string &to_list, int to_index,
6039                 int count, ServerActiveObject *player)
6040 {
6041         realitycheck(L);
6042         assert(lua_checkstack(L, 20));
6043         StackUnroller stack_unroller(L);
6044
6045         INodeDefManager *ndef = get_server(L)->ndef();
6046
6047         // If node doesn't exist, we don't know what callback to call
6048         MapNode node = get_env(L)->getMap().getNodeNoEx(p);
6049         if(node.getContent() == CONTENT_IGNORE)
6050                 return;
6051
6052         // Push callback function on stack
6053         if(!get_item_callback(L, ndef->get(node).name.c_str(),
6054                         "on_metadata_inventory_move"))
6055                 return;
6056
6057         // function(pos, from_list, from_index, to_list, to_index, count, player)
6058         // pos
6059         push_v3s16(L, p);
6060         // from_list
6061         lua_pushstring(L, from_list.c_str());
6062         // from_index
6063         lua_pushinteger(L, from_index + 1);
6064         // to_list
6065         lua_pushstring(L, to_list.c_str());
6066         // to_index
6067         lua_pushinteger(L, to_index + 1);
6068         // count
6069         lua_pushinteger(L, count);
6070         // player
6071         objectref_get_or_create(L, player);
6072         if(lua_pcall(L, 7, 0, 0))
6073                 script_error(L, "error: %s", lua_tostring(L, -1));
6074 }
6075
6076 // Report put items
6077 void scriptapi_nodemeta_inventory_on_put(lua_State *L, v3s16 p,
6078                 const std::string &listname, int index, ItemStack &stack,
6079                 ServerActiveObject *player)
6080 {
6081         realitycheck(L);
6082         assert(lua_checkstack(L, 20));
6083         StackUnroller stack_unroller(L);
6084
6085         INodeDefManager *ndef = get_server(L)->ndef();
6086
6087         // If node doesn't exist, we don't know what callback to call
6088         MapNode node = get_env(L)->getMap().getNodeNoEx(p);
6089         if(node.getContent() == CONTENT_IGNORE)
6090                 return;
6091
6092         // Push callback function on stack
6093         if(!get_item_callback(L, ndef->get(node).name.c_str(),
6094                         "on_metadata_inventory_put"))
6095                 return;
6096
6097         // Call function(pos, listname, index, stack, player)
6098         // pos
6099         push_v3s16(L, p);
6100         // listname
6101         lua_pushstring(L, listname.c_str());
6102         // index
6103         lua_pushinteger(L, index + 1);
6104         // stack
6105         LuaItemStack::create(L, stack);
6106         // player
6107         objectref_get_or_create(L, player);
6108         if(lua_pcall(L, 5, 0, 0))
6109                 script_error(L, "error: %s", lua_tostring(L, -1));
6110 }
6111
6112 // Report taken items
6113 void scriptapi_nodemeta_inventory_on_take(lua_State *L, v3s16 p,
6114                 const std::string &listname, int index, ItemStack &stack,
6115                 ServerActiveObject *player)
6116 {
6117         realitycheck(L);
6118         assert(lua_checkstack(L, 20));
6119         StackUnroller stack_unroller(L);
6120
6121         INodeDefManager *ndef = get_server(L)->ndef();
6122
6123         // If node doesn't exist, we don't know what callback to call
6124         MapNode node = get_env(L)->getMap().getNodeNoEx(p);
6125         if(node.getContent() == CONTENT_IGNORE)
6126                 return;
6127
6128         // Push callback function on stack
6129         if(!get_item_callback(L, ndef->get(node).name.c_str(),
6130                         "on_metadata_inventory_take"))
6131                 return;
6132
6133         // Call function(pos, listname, index, stack, player)
6134         // pos
6135         push_v3s16(L, p);
6136         // listname
6137         lua_pushstring(L, listname.c_str());
6138         // index
6139         lua_pushinteger(L, index + 1);
6140         // stack
6141         LuaItemStack::create(L, stack);
6142         // player
6143         objectref_get_or_create(L, player);
6144         if(lua_pcall(L, 5, 0, 0))
6145                 script_error(L, "error: %s", lua_tostring(L, -1));
6146 }
6147
6148 /*
6149         Detached inventory callbacks
6150 */
6151
6152 // Retrieves minetest.detached_inventories[name][callbackname]
6153 // If that is nil or on error, return false and stack is unchanged
6154 // If that is a function, returns true and pushes the
6155 // function onto the stack
6156 static bool get_detached_inventory_callback(lua_State *L,
6157                 const std::string &name, const char *callbackname)
6158 {
6159         lua_getglobal(L, "minetest");
6160         lua_getfield(L, -1, "detached_inventories");
6161         lua_remove(L, -2);
6162         luaL_checktype(L, -1, LUA_TTABLE);
6163         lua_getfield(L, -1, name.c_str());
6164         lua_remove(L, -2);
6165         // Should be a table
6166         if(lua_type(L, -1) != LUA_TTABLE)
6167         {
6168                 errorstream<<"Item \""<<name<<"\" not defined"<<std::endl;
6169                 lua_pop(L, 1);
6170                 return false;
6171         }
6172         lua_getfield(L, -1, callbackname);
6173         lua_remove(L, -2);
6174         // Should be a function or nil
6175         if(lua_type(L, -1) == LUA_TFUNCTION)
6176         {
6177                 return true;
6178         }
6179         else if(lua_isnil(L, -1))
6180         {
6181                 lua_pop(L, 1);
6182                 return false;
6183         }
6184         else
6185         {
6186                 errorstream<<"Detached inventory \""<<name<<"\" callback \""
6187                         <<callbackname<<"\" is not a function"<<std::endl;
6188                 lua_pop(L, 1);
6189                 return false;
6190         }
6191 }
6192
6193 // Return number of accepted items to be moved
6194 int scriptapi_detached_inventory_allow_move(lua_State *L,
6195                 const std::string &name,
6196                 const std::string &from_list, int from_index,
6197                 const std::string &to_list, int to_index,
6198                 int count, ServerActiveObject *player)
6199 {
6200         realitycheck(L);
6201         assert(lua_checkstack(L, 20));
6202         StackUnroller stack_unroller(L);
6203
6204         // Push callback function on stack
6205         if(!get_detached_inventory_callback(L, name, "allow_move"))
6206                 return count;
6207
6208         // function(inv, from_list, from_index, to_list, to_index, count, player)
6209         // inv
6210         InventoryLocation loc;
6211         loc.setDetached(name);
6212         InvRef::create(L, loc);
6213         // from_list
6214         lua_pushstring(L, from_list.c_str());
6215         // from_index
6216         lua_pushinteger(L, from_index + 1);
6217         // to_list
6218         lua_pushstring(L, to_list.c_str());
6219         // to_index
6220         lua_pushinteger(L, to_index + 1);
6221         // count
6222         lua_pushinteger(L, count);
6223         // player
6224         objectref_get_or_create(L, player);
6225         if(lua_pcall(L, 7, 1, 0))
6226                 script_error(L, "error: %s", lua_tostring(L, -1));
6227         if(!lua_isnumber(L, -1))
6228                 throw LuaError(L, "allow_move should return a number");
6229         return luaL_checkinteger(L, -1);
6230 }
6231
6232 // Return number of accepted items to be put
6233 int scriptapi_detached_inventory_allow_put(lua_State *L,
6234                 const std::string &name,
6235                 const std::string &listname, int index, ItemStack &stack,
6236                 ServerActiveObject *player)
6237 {
6238         realitycheck(L);
6239         assert(lua_checkstack(L, 20));
6240         StackUnroller stack_unroller(L);
6241
6242         // Push callback function on stack
6243         if(!get_detached_inventory_callback(L, name, "allow_put"))
6244                 return stack.count; // All will be accepted
6245
6246         // Call function(inv, listname, index, stack, player)
6247         // inv
6248         InventoryLocation loc;
6249         loc.setDetached(name);
6250         InvRef::create(L, loc);
6251         // listname
6252         lua_pushstring(L, listname.c_str());
6253         // index
6254         lua_pushinteger(L, index + 1);
6255         // stack
6256         LuaItemStack::create(L, stack);
6257         // player
6258         objectref_get_or_create(L, player);
6259         if(lua_pcall(L, 5, 1, 0))
6260                 script_error(L, "error: %s", lua_tostring(L, -1));
6261         if(!lua_isnumber(L, -1))
6262                 throw LuaError(L, "allow_put should return a number");
6263         return luaL_checkinteger(L, -1);
6264 }
6265
6266 // Return number of accepted items to be taken
6267 int scriptapi_detached_inventory_allow_take(lua_State *L,
6268                 const std::string &name,
6269                 const std::string &listname, int index, ItemStack &stack,
6270                 ServerActiveObject *player)
6271 {
6272         realitycheck(L);
6273         assert(lua_checkstack(L, 20));
6274         StackUnroller stack_unroller(L);
6275
6276         // Push callback function on stack
6277         if(!get_detached_inventory_callback(L, name, "allow_take"))
6278                 return stack.count; // All will be accepted
6279
6280         // Call function(inv, listname, index, stack, player)
6281         // inv
6282         InventoryLocation loc;
6283         loc.setDetached(name);
6284         InvRef::create(L, loc);
6285         // listname
6286         lua_pushstring(L, listname.c_str());
6287         // index
6288         lua_pushinteger(L, index + 1);
6289         // stack
6290         LuaItemStack::create(L, stack);
6291         // player
6292         objectref_get_or_create(L, player);
6293         if(lua_pcall(L, 5, 1, 0))
6294                 script_error(L, "error: %s", lua_tostring(L, -1));
6295         if(!lua_isnumber(L, -1))
6296                 throw LuaError(L, "allow_take should return a number");
6297         return luaL_checkinteger(L, -1);
6298 }
6299
6300 // Report moved items
6301 void scriptapi_detached_inventory_on_move(lua_State *L,
6302                 const std::string &name,
6303                 const std::string &from_list, int from_index,
6304                 const std::string &to_list, int to_index,
6305                 int count, ServerActiveObject *player)
6306 {
6307         realitycheck(L);
6308         assert(lua_checkstack(L, 20));
6309         StackUnroller stack_unroller(L);
6310
6311         // Push callback function on stack
6312         if(!get_detached_inventory_callback(L, name, "on_move"))
6313                 return;
6314
6315         // function(inv, from_list, from_index, to_list, to_index, count, player)
6316         // inv
6317         InventoryLocation loc;
6318         loc.setDetached(name);
6319         InvRef::create(L, loc);
6320         // from_list
6321         lua_pushstring(L, from_list.c_str());
6322         // from_index
6323         lua_pushinteger(L, from_index + 1);
6324         // to_list
6325         lua_pushstring(L, to_list.c_str());
6326         // to_index
6327         lua_pushinteger(L, to_index + 1);
6328         // count
6329         lua_pushinteger(L, count);
6330         // player
6331         objectref_get_or_create(L, player);
6332         if(lua_pcall(L, 7, 0, 0))
6333                 script_error(L, "error: %s", lua_tostring(L, -1));
6334 }
6335
6336 // Report put items
6337 void scriptapi_detached_inventory_on_put(lua_State *L,
6338                 const std::string &name,
6339                 const std::string &listname, int index, ItemStack &stack,
6340                 ServerActiveObject *player)
6341 {
6342         realitycheck(L);
6343         assert(lua_checkstack(L, 20));
6344         StackUnroller stack_unroller(L);
6345
6346         // Push callback function on stack
6347         if(!get_detached_inventory_callback(L, name, "on_put"))
6348                 return;
6349
6350         // Call function(inv, listname, index, stack, player)
6351         // inv
6352         InventoryLocation loc;
6353         loc.setDetached(name);
6354         InvRef::create(L, loc);
6355         // listname
6356         lua_pushstring(L, listname.c_str());
6357         // index
6358         lua_pushinteger(L, index + 1);
6359         // stack
6360         LuaItemStack::create(L, stack);
6361         // player
6362         objectref_get_or_create(L, player);
6363         if(lua_pcall(L, 5, 0, 0))
6364                 script_error(L, "error: %s", lua_tostring(L, -1));
6365 }
6366
6367 // Report taken items
6368 void scriptapi_detached_inventory_on_take(lua_State *L,
6369                 const std::string &name,
6370                 const std::string &listname, int index, ItemStack &stack,
6371                 ServerActiveObject *player)
6372 {
6373         realitycheck(L);
6374         assert(lua_checkstack(L, 20));
6375         StackUnroller stack_unroller(L);
6376
6377         // Push callback function on stack
6378         if(!get_detached_inventory_callback(L, name, "on_take"))
6379                 return;
6380
6381         // Call function(inv, listname, index, stack, player)
6382         // inv
6383         InventoryLocation loc;
6384         loc.setDetached(name);
6385         InvRef::create(L, loc);
6386         // listname
6387         lua_pushstring(L, listname.c_str());
6388         // index
6389         lua_pushinteger(L, index + 1);
6390         // stack
6391         LuaItemStack::create(L, stack);
6392         // player
6393         objectref_get_or_create(L, player);
6394         if(lua_pcall(L, 5, 0, 0))
6395                 script_error(L, "error: %s", lua_tostring(L, -1));
6396 }
6397
6398 /*
6399         environment
6400 */
6401
6402 void scriptapi_environment_step(lua_State *L, float dtime)
6403 {
6404         realitycheck(L);
6405         assert(lua_checkstack(L, 20));
6406         //infostream<<"scriptapi_environment_step"<<std::endl;
6407         StackUnroller stack_unroller(L);
6408
6409         // Get minetest.registered_globalsteps
6410         lua_getglobal(L, "minetest");
6411         lua_getfield(L, -1, "registered_globalsteps");
6412         // Call callbacks
6413         lua_pushnumber(L, dtime);
6414         scriptapi_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
6415 }
6416
6417 void scriptapi_environment_on_generated(lua_State *L, v3s16 minp, v3s16 maxp,
6418                 u32 blockseed)
6419 {
6420         realitycheck(L);
6421         assert(lua_checkstack(L, 20));
6422         //infostream<<"scriptapi_environment_on_generated"<<std::endl;
6423         StackUnroller stack_unroller(L);
6424
6425         // Get minetest.registered_on_generateds
6426         lua_getglobal(L, "minetest");
6427         lua_getfield(L, -1, "registered_on_generateds");
6428         // Call callbacks
6429         push_v3s16(L, minp);
6430         push_v3s16(L, maxp);
6431         lua_pushnumber(L, blockseed);
6432         scriptapi_run_callbacks(L, 3, RUN_CALLBACKS_MODE_FIRST);
6433 }
6434
6435 /*
6436         luaentity
6437 */
6438
6439 bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name)
6440 {
6441         realitycheck(L);
6442         assert(lua_checkstack(L, 20));
6443         verbosestream<<"scriptapi_luaentity_add: id="<<id<<" name=\""
6444                         <<name<<"\""<<std::endl;
6445         StackUnroller stack_unroller(L);
6446         
6447         // Get minetest.registered_entities[name]
6448         lua_getglobal(L, "minetest");
6449         lua_getfield(L, -1, "registered_entities");
6450         luaL_checktype(L, -1, LUA_TTABLE);
6451         lua_pushstring(L, name);
6452         lua_gettable(L, -2);
6453         // Should be a table, which we will use as a prototype
6454         //luaL_checktype(L, -1, LUA_TTABLE);
6455         if(lua_type(L, -1) != LUA_TTABLE){
6456                 errorstream<<"LuaEntity name \""<<name<<"\" not defined"<<std::endl;
6457                 return false;
6458         }
6459         int prototype_table = lua_gettop(L);
6460         //dump2(L, "prototype_table");
6461         
6462         // Create entity object
6463         lua_newtable(L);
6464         int object = lua_gettop(L);
6465
6466         // Set object metatable
6467         lua_pushvalue(L, prototype_table);
6468         lua_setmetatable(L, -2);
6469         
6470         // Add object reference
6471         // This should be userdata with metatable ObjectRef
6472         objectref_get(L, id);
6473         luaL_checktype(L, -1, LUA_TUSERDATA);
6474         if(!luaL_checkudata(L, -1, "ObjectRef"))
6475                 luaL_typerror(L, -1, "ObjectRef");
6476         lua_setfield(L, -2, "object");
6477
6478         // minetest.luaentities[id] = object
6479         lua_getglobal(L, "minetest");
6480         lua_getfield(L, -1, "luaentities");
6481         luaL_checktype(L, -1, LUA_TTABLE);
6482         lua_pushnumber(L, id); // Push id
6483         lua_pushvalue(L, object); // Copy object to top of stack
6484         lua_settable(L, -3);
6485         
6486         return true;
6487 }
6488
6489 void scriptapi_luaentity_activate(lua_State *L, u16 id,
6490                 const std::string &staticdata, u32 dtime_s)
6491 {
6492         realitycheck(L);
6493         assert(lua_checkstack(L, 20));
6494         verbosestream<<"scriptapi_luaentity_activate: id="<<id<<std::endl;
6495         StackUnroller stack_unroller(L);
6496         
6497         // Get minetest.luaentities[id]
6498         luaentity_get(L, id);
6499         int object = lua_gettop(L);
6500         
6501         // Get on_activate function
6502         lua_pushvalue(L, object);
6503         lua_getfield(L, -1, "on_activate");
6504         if(!lua_isnil(L, -1)){
6505                 luaL_checktype(L, -1, LUA_TFUNCTION);
6506                 lua_pushvalue(L, object); // self
6507                 lua_pushlstring(L, staticdata.c_str(), staticdata.size());
6508                 lua_pushinteger(L, dtime_s);
6509                 // Call with 3 arguments, 0 results
6510                 if(lua_pcall(L, 3, 0, 0))
6511                         script_error(L, "error running function on_activate: %s\n",
6512                                         lua_tostring(L, -1));
6513         }
6514 }
6515
6516 void scriptapi_luaentity_rm(lua_State *L, u16 id)
6517 {
6518         realitycheck(L);
6519         assert(lua_checkstack(L, 20));
6520         verbosestream<<"scriptapi_luaentity_rm: id="<<id<<std::endl;
6521
6522         // Get minetest.luaentities table
6523         lua_getglobal(L, "minetest");
6524         lua_getfield(L, -1, "luaentities");
6525         luaL_checktype(L, -1, LUA_TTABLE);
6526         int objectstable = lua_gettop(L);
6527         
6528         // Set luaentities[id] = nil
6529         lua_pushnumber(L, id); // Push id
6530         lua_pushnil(L);
6531         lua_settable(L, objectstable);
6532         
6533         lua_pop(L, 2); // pop luaentities, minetest
6534 }
6535
6536 std::string scriptapi_luaentity_get_staticdata(lua_State *L, u16 id)
6537 {
6538         realitycheck(L);
6539         assert(lua_checkstack(L, 20));
6540         //infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl;
6541         StackUnroller stack_unroller(L);
6542
6543         // Get minetest.luaentities[id]
6544         luaentity_get(L, id);
6545         int object = lua_gettop(L);
6546         
6547         // Get get_staticdata function
6548         lua_pushvalue(L, object);
6549         lua_getfield(L, -1, "get_staticdata");
6550         if(lua_isnil(L, -1))
6551                 return "";
6552         
6553         luaL_checktype(L, -1, LUA_TFUNCTION);
6554         lua_pushvalue(L, object); // self
6555         // Call with 1 arguments, 1 results
6556         if(lua_pcall(L, 1, 1, 0))
6557                 script_error(L, "error running function get_staticdata: %s\n",
6558                                 lua_tostring(L, -1));
6559         
6560         size_t len=0;
6561         const char *s = lua_tolstring(L, -1, &len);
6562         return std::string(s, len);
6563 }
6564
6565 void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
6566                 ObjectProperties *prop)
6567 {
6568         realitycheck(L);
6569         assert(lua_checkstack(L, 20));
6570         //infostream<<"scriptapi_luaentity_get_properties: id="<<id<<std::endl;
6571         StackUnroller stack_unroller(L);
6572
6573         // Get minetest.luaentities[id]
6574         luaentity_get(L, id);
6575         //int object = lua_gettop(L);
6576
6577         // Set default values that differ from ObjectProperties defaults
6578         prop->hp_max = 10;
6579         
6580         /* Read stuff */
6581         
6582         prop->hp_max = getintfield_default(L, -1, "hp_max", 10);
6583
6584         getboolfield(L, -1, "physical", prop->physical);
6585
6586         getfloatfield(L, -1, "weight", prop->weight);
6587
6588         lua_getfield(L, -1, "collisionbox");
6589         if(lua_istable(L, -1))
6590                 prop->collisionbox = read_aabb3f(L, -1, 1.0);
6591         lua_pop(L, 1);
6592
6593         getstringfield(L, -1, "visual", prop->visual);
6594         
6595         // Deprecated: read object properties directly
6596         read_object_properties(L, -1, prop);
6597         
6598         // Read initial_properties
6599         lua_getfield(L, -1, "initial_properties");
6600         read_object_properties(L, -1, prop);
6601         lua_pop(L, 1);
6602 }
6603
6604 void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime)
6605 {
6606         realitycheck(L);
6607         assert(lua_checkstack(L, 20));
6608         //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
6609         StackUnroller stack_unroller(L);
6610
6611         // Get minetest.luaentities[id]
6612         luaentity_get(L, id);
6613         int object = lua_gettop(L);
6614         // State: object is at top of stack
6615         // Get step function
6616         lua_getfield(L, -1, "on_step");
6617         if(lua_isnil(L, -1))
6618                 return;
6619         luaL_checktype(L, -1, LUA_TFUNCTION);
6620         lua_pushvalue(L, object); // self
6621         lua_pushnumber(L, dtime); // dtime
6622         // Call with 2 arguments, 0 results
6623         if(lua_pcall(L, 2, 0, 0))
6624                 script_error(L, "error running function 'on_step': %s\n", lua_tostring(L, -1));
6625 }
6626
6627 // Calls entity:on_punch(ObjectRef puncher, time_from_last_punch,
6628 //                       tool_capabilities, direction)
6629 void scriptapi_luaentity_punch(lua_State *L, u16 id,
6630                 ServerActiveObject *puncher, float time_from_last_punch,
6631                 const ToolCapabilities *toolcap, v3f dir)
6632 {
6633         realitycheck(L);
6634         assert(lua_checkstack(L, 20));
6635         //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
6636         StackUnroller stack_unroller(L);
6637
6638         // Get minetest.luaentities[id]
6639         luaentity_get(L, id);
6640         int object = lua_gettop(L);
6641         // State: object is at top of stack
6642         // Get function
6643         lua_getfield(L, -1, "on_punch");
6644         if(lua_isnil(L, -1))
6645                 return;
6646         luaL_checktype(L, -1, LUA_TFUNCTION);
6647         lua_pushvalue(L, object); // self
6648         objectref_get_or_create(L, puncher); // Clicker reference
6649         lua_pushnumber(L, time_from_last_punch);
6650         push_tool_capabilities(L, *toolcap);
6651         push_v3f(L, dir);
6652         // Call with 5 arguments, 0 results
6653         if(lua_pcall(L, 5, 0, 0))
6654                 script_error(L, "error running function 'on_punch': %s\n", lua_tostring(L, -1));
6655 }
6656
6657 // Calls entity:on_rightclick(ObjectRef clicker)
6658 void scriptapi_luaentity_rightclick(lua_State *L, u16 id,
6659                 ServerActiveObject *clicker)
6660 {
6661         realitycheck(L);
6662         assert(lua_checkstack(L, 20));
6663         //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
6664         StackUnroller stack_unroller(L);
6665
6666         // Get minetest.luaentities[id]
6667         luaentity_get(L, id);
6668         int object = lua_gettop(L);
6669         // State: object is at top of stack
6670         // Get function
6671         lua_getfield(L, -1, "on_rightclick");
6672         if(lua_isnil(L, -1))
6673                 return;
6674         luaL_checktype(L, -1, LUA_TFUNCTION);
6675         lua_pushvalue(L, object); // self
6676         objectref_get_or_create(L, clicker); // Clicker reference
6677         // Call with 2 arguments, 0 results
6678         if(lua_pcall(L, 2, 0, 0))
6679                 script_error(L, "error running function 'on_rightclick': %s\n", lua_tostring(L, -1));
6680 }
6681