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