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