Initial NodeMetaRef stuff
[oweals/minetest.git] / src / scriptapi.cpp
1 /*
2 Minetest-c55
3 Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include "scriptapi.h"
21
22 #include <iostream>
23 extern "C" {
24 #include <lua.h>
25 #include <lualib.h>
26 #include <lauxlib.h>
27 }
28
29 #include "log.h"
30 #include "server.h"
31 #include "porting.h"
32 #include "filesys.h"
33 #include "serverobject.h"
34 #include "script.h"
35 //#include "luna.h"
36 #include "luaentity_common.h"
37 #include "content_sao.h" // For LuaEntitySAO
38 #include "tooldef.h"
39 #include "nodedef.h"
40 #include "craftdef.h"
41 #include "main.h" // For g_settings
42 #include "settings.h" // For accessing g_settings
43 #include "nodemetadata.h"
44 #include "mapblock.h" // For getNodeBlockPos
45
46 /*
47 TODO:
48 - All kinds of callbacks
49 - LuaNodeMetadata
50         blockdef.metadata_name =
51                 ""
52                 "sign"
53                 "furnace"
54                 "chest"
55                 "locked_chest"
56                 "lua"
57         - Stores an inventory and stuff in a Settings object
58         meta.inventory_add_list("main")
59         blockdef.on_inventory_modified
60         meta.set("owner", playername)
61         meta.get("owner")
62 - Item definition (actually, only CraftItem)
63 - Putting items in NodeMetadata (?)
64 */
65
66 static void stackDump(lua_State *L, std::ostream &o)
67 {
68   int i;
69   int top = lua_gettop(L);
70   for (i = 1; i <= top; i++) {  /* repeat for each level */
71         int t = lua_type(L, i);
72         switch (t) {
73
74           case LUA_TSTRING:  /* strings */
75                 o<<"\""<<lua_tostring(L, i)<<"\"";
76                 break;
77
78           case LUA_TBOOLEAN:  /* booleans */
79                 o<<(lua_toboolean(L, i) ? "true" : "false");
80                 break;
81
82           case LUA_TNUMBER:  /* numbers */ {
83                 char buf[10];
84                 snprintf(buf, 10, "%g", lua_tonumber(L, i));
85                 o<<buf;
86                 break; }
87
88           default:  /* other values */
89                 o<<lua_typename(L, t);
90                 break;
91
92         }
93         o<<" ";
94   }
95   o<<std::endl;
96 }
97
98 static void realitycheck(lua_State *L)
99 {
100         int top = lua_gettop(L);
101         if(top >= 30){
102                 dstream<<"Stack is over 30:"<<std::endl;
103                 stackDump(L, dstream);
104                 script_error(L, "Stack is over 30 (reality check)");
105         }
106 }
107
108 class StackUnroller
109 {
110 private:
111         lua_State *m_lua;
112         int m_original_top;
113 public:
114         StackUnroller(lua_State *L):
115                 m_lua(L),
116                 m_original_top(-1)
117         {
118                 m_original_top = lua_gettop(m_lua); // store stack height
119         }
120         ~StackUnroller()
121         {
122                 lua_settop(m_lua, m_original_top); // restore stack height
123         }
124 };
125
126 static v3f readFloatPos(lua_State *L, int index)
127 {
128         v3f pos;
129         luaL_checktype(L, index, LUA_TTABLE);
130         lua_getfield(L, index, "x");
131         pos.X = lua_tonumber(L, -1);
132         lua_pop(L, 1);
133         lua_getfield(L, index, "y");
134         pos.Y = lua_tonumber(L, -1);
135         lua_pop(L, 1);
136         lua_getfield(L, index, "z");
137         pos.Z = lua_tonumber(L, -1);
138         lua_pop(L, 1);
139         pos *= BS; // Scale to internal format
140         return pos;
141 }
142
143 static void pushFloatPos(lua_State *L, v3f p)
144 {
145         p /= BS;
146         lua_newtable(L);
147         lua_pushnumber(L, p.X);
148         lua_setfield(L, -2, "x");
149         lua_pushnumber(L, p.Y);
150         lua_setfield(L, -2, "y");
151         lua_pushnumber(L, p.Z);
152         lua_setfield(L, -2, "z");
153 }
154
155 static void pushpos(lua_State *L, v3s16 p)
156 {
157         lua_newtable(L);
158         lua_pushnumber(L, p.X);
159         lua_setfield(L, -2, "x");
160         lua_pushnumber(L, p.Y);
161         lua_setfield(L, -2, "y");
162         lua_pushnumber(L, p.Z);
163         lua_setfield(L, -2, "z");
164 }
165
166 static v3s16 readpos(lua_State *L, int index)
167 {
168         // Correct rounding at <0
169         v3f pf = readFloatPos(L, index);
170         return floatToInt(pf, BS);
171 }
172
173 static void pushnode(lua_State *L, const MapNode &n, INodeDefManager *ndef)
174 {
175         lua_newtable(L);
176         lua_pushstring(L, ndef->get(n).name.c_str());
177         lua_setfield(L, -2, "name");
178         lua_pushnumber(L, n.getParam1());
179         lua_setfield(L, -2, "param1");
180         lua_pushnumber(L, n.getParam2());
181         lua_setfield(L, -2, "param2");
182 }
183
184 static MapNode readnode(lua_State *L, int index, INodeDefManager *ndef)
185 {
186         lua_getfield(L, index, "name");
187         const char *name = lua_tostring(L, -1);
188         lua_pop(L, 1);
189         u8 param1;
190         lua_getfield(L, index, "param1");
191         if(lua_isnil(L, -1))
192                 param1 = 0;
193         else
194                 param1 = lua_tonumber(L, -1);
195         lua_pop(L, 1);
196         u8 param2;
197         lua_getfield(L, index, "param2");
198         if(lua_isnil(L, -1))
199                 param2 = 0;
200         else
201                 param2 = lua_tonumber(L, -1);
202         lua_pop(L, 1);
203         return MapNode(ndef, name, param1, param2);
204 }
205
206 static video::SColor readARGB8(lua_State *L, int index)
207 {
208         video::SColor color;
209         luaL_checktype(L, index, LUA_TTABLE);
210         lua_getfield(L, index, "a");
211         if(lua_isnumber(L, -1))
212                 color.setAlpha(lua_tonumber(L, -1));
213         lua_pop(L, 1);
214         lua_getfield(L, index, "r");
215         color.setRed(lua_tonumber(L, -1));
216         lua_pop(L, 1);
217         lua_getfield(L, index, "g");
218         color.setGreen(lua_tonumber(L, -1));
219         lua_pop(L, 1);
220         lua_getfield(L, index, "b");
221         color.setBlue(lua_tonumber(L, -1));
222         lua_pop(L, 1);
223         return color;
224 }
225
226 static core::aabbox3d<f32> read_aabbox3df32(lua_State *L, int index, f32 scale)
227 {
228         core::aabbox3d<f32> box;
229         if(lua_istable(L, -1)){
230                 lua_rawgeti(L, -1, 1);
231                 box.MinEdge.X = lua_tonumber(L, -1) * scale;
232                 lua_pop(L, 1);
233                 lua_rawgeti(L, -1, 2);
234                 box.MinEdge.Y = lua_tonumber(L, -1) * scale;
235                 lua_pop(L, 1);
236                 lua_rawgeti(L, -1, 3);
237                 box.MinEdge.Z = lua_tonumber(L, -1) * scale;
238                 lua_pop(L, 1);
239                 lua_rawgeti(L, -1, 4);
240                 box.MaxEdge.X = lua_tonumber(L, -1) * scale;
241                 lua_pop(L, 1);
242                 lua_rawgeti(L, -1, 5);
243                 box.MaxEdge.Y = lua_tonumber(L, -1) * scale;
244                 lua_pop(L, 1);
245                 lua_rawgeti(L, -1, 6);
246                 box.MaxEdge.Z = lua_tonumber(L, -1) * scale;
247                 lua_pop(L, 1);
248         }
249         return box;
250 }
251
252 static v2s16 read_v2s16(lua_State *L, int index)
253 {
254         v2s16 p;
255         luaL_checktype(L, index, LUA_TTABLE);
256         lua_getfield(L, index, "x");
257         p.X = lua_tonumber(L, -1);
258         lua_pop(L, 1);
259         lua_getfield(L, index, "y");
260         p.Y = lua_tonumber(L, -1);
261         lua_pop(L, 1);
262         return p;
263 }
264
265 static v2f read_v2f(lua_State *L, int index)
266 {
267         v2f p;
268         luaL_checktype(L, index, LUA_TTABLE);
269         lua_getfield(L, index, "x");
270         p.X = lua_tonumber(L, -1);
271         lua_pop(L, 1);
272         lua_getfield(L, index, "y");
273         p.Y = lua_tonumber(L, -1);
274         lua_pop(L, 1);
275         return p;
276 }
277
278 static bool getstringfield(lua_State *L, int table,
279                 const char *fieldname, std::string &result)
280 {
281         lua_getfield(L, table, fieldname);
282         bool got = false;
283         if(lua_isstring(L, -1)){
284                 result = lua_tostring(L, -1);
285                 got = true;
286         }
287         lua_pop(L, 1);
288         return got;
289 }
290
291 static bool getintfield(lua_State *L, int table,
292                 const char *fieldname, int &result)
293 {
294         lua_getfield(L, table, fieldname);
295         bool got = false;
296         if(lua_isnumber(L, -1)){
297                 result = lua_tonumber(L, -1);
298                 got = true;
299         }
300         lua_pop(L, 1);
301         return got;
302 }
303
304 static bool getfloatfield(lua_State *L, int table,
305                 const char *fieldname, float &result)
306 {
307         lua_getfield(L, table, fieldname);
308         bool got = false;
309         if(lua_isnumber(L, -1)){
310                 result = lua_tonumber(L, -1);
311                 got = true;
312         }
313         lua_pop(L, 1);
314         return got;
315 }
316
317 static bool getboolfield(lua_State *L, int table,
318                 const char *fieldname, bool &result)
319 {
320         lua_getfield(L, table, fieldname);
321         bool got = false;
322         if(lua_isboolean(L, -1)){
323                 result = lua_toboolean(L, -1);
324                 got = true;
325         }
326         lua_pop(L, 1);
327         return got;
328 }
329
330 static std::string getstringfield_default(lua_State *L, int table,
331                 const char *fieldname, const std::string &default_)
332 {
333         std::string result = default_;
334         getstringfield(L, table, fieldname, result);
335         return result;
336 }
337
338 static int getintfield_default(lua_State *L, int table,
339                 const char *fieldname, int default_)
340 {
341         int result = default_;
342         getintfield(L, table, fieldname, result);
343         return result;
344 }
345
346 /*static float getfloatfield_default(lua_State *L, int table,
347                 const char *fieldname, float default_)
348 {
349         float result = default_;
350         getfloatfield(L, table, fieldname, result);
351         return result;
352 }*/
353
354 static bool getboolfield_default(lua_State *L, int table,
355                 const char *fieldname, bool default_)
356 {
357         bool result = default_;
358         getboolfield(L, table, fieldname, result);
359         return result;
360 }
361
362 struct EnumString
363 {
364         int num;
365         const char *str;
366 };
367
368 static bool string_to_enum(const EnumString *spec, int &result,
369                 const std::string &str)
370 {
371         const EnumString *esp = spec;
372         while(esp->str){
373                 if(str == std::string(esp->str)){
374                         result = esp->num;
375                         return true;
376                 }
377                 esp++;
378         }
379         return false;
380 }
381
382 /*static bool enum_to_string(const EnumString *spec, std::string &result,
383                 int num)
384 {
385         const EnumString *esp = spec;
386         while(esp){
387                 if(num == esp->num){
388                         result = esp->str;
389                         return true;
390                 }
391                 esp++;
392         }
393         return false;
394 }*/
395
396 static int getenumfield(lua_State *L, int table,
397                 const char *fieldname, const EnumString *spec, int default_)
398 {
399         int result = default_;
400         string_to_enum(spec, result,
401                         getstringfield_default(L, table, fieldname, ""));
402         return result;
403 }
404
405 struct EnumString es_DrawType[] =
406 {
407         {NDT_NORMAL, "normal"},
408         {NDT_AIRLIKE, "airlike"},
409         {NDT_LIQUID, "liquid"},
410         {NDT_FLOWINGLIQUID, "flowingliquid"},
411         {NDT_GLASSLIKE, "glasslike"},
412         {NDT_ALLFACES, "allfaces"},
413         {NDT_ALLFACES_OPTIONAL, "allfaces_optional"},
414         {NDT_TORCHLIKE, "torchlike"},
415         {NDT_SIGNLIKE, "signlike"},
416         {NDT_PLANTLIKE, "plantlike"},
417         {NDT_FENCELIKE, "fencelike"},
418         {NDT_RAILLIKE, "raillike"},
419         {0, NULL},
420 };
421
422 struct EnumString es_ContentParamType[] =
423 {
424         {CPT_NONE, "none"},
425         {CPT_LIGHT, "light"},
426         {CPT_MINERAL, "mineral"},
427         {CPT_FACEDIR_SIMPLE, "facedir_simple"},
428 };
429
430 struct EnumString es_LiquidType[] =
431 {
432         {LIQUID_NONE, "none"},
433         {LIQUID_FLOWING, "flowing"},
434         {LIQUID_SOURCE, "source"},
435 };
436
437 struct EnumString es_NodeBoxType[] =
438 {
439         {NODEBOX_REGULAR, "regular"},
440         {NODEBOX_FIXED, "fixed"},
441         {NODEBOX_WALLMOUNTED, "wallmounted"},
442 };
443
444 struct EnumString es_Diggability[] =
445 {
446         {DIGGABLE_NOT, "not"},
447         {DIGGABLE_NORMAL, "normal"},
448         {DIGGABLE_CONSTANT, "constant"},
449 };
450
451 /*
452         Global functions
453 */
454
455 static int l_register_nodedef_defaults(lua_State *L)
456 {
457         luaL_checktype(L, 1, LUA_TTABLE);
458
459         lua_pushvalue(L, 1); // Explicitly put parameter 1 on top of stack
460         lua_setfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
461
462         return 0;
463 }
464
465 // Register new object prototype
466 // register_entity(name, prototype)
467 static int l_register_entity(lua_State *L)
468 {
469         const char *name = luaL_checkstring(L, 1);
470         infostream<<"register_entity: "<<name<<std::endl;
471         luaL_checktype(L, 2, LUA_TTABLE);
472
473         // Get minetest.registered_entities
474         lua_getglobal(L, "minetest");
475         lua_getfield(L, -1, "registered_entities");
476         luaL_checktype(L, -1, LUA_TTABLE);
477         int registered_entities = lua_gettop(L);
478         lua_pushvalue(L, 2); // Object = param 2 -> stack top
479         // registered_entities[name] = object
480         lua_setfield(L, registered_entities, name);
481         
482         // Get registered object to top of stack
483         lua_pushvalue(L, 2);
484         
485         // Set __index to point to itself
486         lua_pushvalue(L, -1);
487         lua_setfield(L, -2, "__index");
488
489         // Set metatable.__index = metatable
490         luaL_getmetatable(L, "minetest.entity");
491         lua_pushvalue(L, -1); // duplicate metatable
492         lua_setfield(L, -2, "__index");
493         // Set object metatable
494         lua_setmetatable(L, -2);
495
496         return 0; /* number of results */
497 }
498
499 class LuaABM : public ActiveBlockModifier
500 {
501 private:
502         lua_State *m_lua;
503         int m_id;
504
505         std::set<std::string> m_trigger_contents;
506         float m_trigger_interval;
507         u32 m_trigger_chance;
508 public:
509         LuaABM(lua_State *L, int id,
510                         const std::set<std::string> &trigger_contents,
511                         float trigger_interval, u32 trigger_chance):
512                 m_lua(L),
513                 m_id(id),
514                 m_trigger_contents(trigger_contents),
515                 m_trigger_interval(trigger_interval),
516                 m_trigger_chance(trigger_chance)
517         {
518         }
519         virtual std::set<std::string> getTriggerContents()
520         {
521                 return m_trigger_contents;
522         }
523         virtual float getTriggerInterval()
524         {
525                 return m_trigger_interval;
526         }
527         virtual u32 getTriggerChance()
528         {
529                 return m_trigger_chance;
530         }
531         virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n,
532                         u32 active_object_count, u32 active_object_count_wider)
533         {
534                 lua_State *L = m_lua;
535         
536                 realitycheck(L);
537                 assert(lua_checkstack(L, 20));
538                 StackUnroller stack_unroller(L);
539
540                 // Get minetest.registered_abms
541                 lua_getglobal(L, "minetest");
542                 lua_getfield(L, -1, "registered_abms");
543                 luaL_checktype(L, -1, LUA_TTABLE);
544                 int registered_abms = lua_gettop(L);
545
546                 // Get minetest.registered_abms[m_id]
547                 lua_pushnumber(L, m_id);
548                 lua_gettable(L, registered_abms);
549                 if(lua_isnil(L, -1))
550                         assert(0);
551                 
552                 // Call action
553                 luaL_checktype(L, -1, LUA_TTABLE);
554                 lua_getfield(L, -1, "action");
555                 luaL_checktype(L, -1, LUA_TFUNCTION);
556                 pushpos(L, p);
557                 pushnode(L, n, env->getGameDef()->ndef());
558                 lua_pushnumber(L, active_object_count);
559                 lua_pushnumber(L, active_object_count_wider);
560                 if(lua_pcall(L, 4, 0, 0))
561                         script_error(L, "error: %s\n", lua_tostring(L, -1));
562         }
563 };
564
565 // register_abm({...})
566 static int l_register_abm(lua_State *L)
567 {
568         infostream<<"register_abm"<<std::endl;
569         luaL_checktype(L, 1, LUA_TTABLE);
570
571         // Get minetest.registered_abms
572         lua_getglobal(L, "minetest");
573         lua_getfield(L, -1, "registered_abms");
574         luaL_checktype(L, -1, LUA_TTABLE);
575         int registered_abms = lua_gettop(L);
576
577         int id = 1;
578         // Find free id
579         for(;;){
580                 lua_pushnumber(L, id);
581                 lua_gettable(L, registered_abms);
582                 if(lua_isnil(L, -1))
583                         break;
584                 lua_pop(L, 1);
585                 id++;
586         }
587         lua_pop(L, 1);
588
589         infostream<<"register_abm: id="<<id<<std::endl;
590
591         // registered_abms[id] = spec
592         lua_pushnumber(L, id);
593         lua_pushvalue(L, 1);
594         lua_settable(L, registered_abms);
595         
596         return 0; /* number of results */
597 }
598
599 // register_tool(name, {lots of stuff})
600 static int l_register_tool(lua_State *L)
601 {
602         const char *name = luaL_checkstring(L, 1);
603         infostream<<"register_tool: "<<name<<std::endl;
604         luaL_checktype(L, 2, LUA_TTABLE);
605         int table = 2;
606
607         // Get server from registry
608         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
609         Server *server = (Server*)lua_touserdata(L, -1);
610         // And get the writable tool definition manager from the server
611         IWritableToolDefManager *tooldef =
612                         server->getWritableToolDefManager();
613         
614         ToolDefinition def;
615         
616         getstringfield(L, table, "image", def.imagename);
617         getfloatfield(L, table, "basetime", def.properties.basetime);
618         getfloatfield(L, table, "dt_weight", def.properties.dt_weight);
619         getfloatfield(L, table, "dt_crackiness", def.properties.dt_crackiness);
620         getfloatfield(L, table, "dt_crumbliness", def.properties.dt_crumbliness);
621         getfloatfield(L, table, "dt_cuttability", def.properties.dt_cuttability);
622         getfloatfield(L, table, "basedurability", def.properties.basedurability);
623         getfloatfield(L, table, "dd_weight", def.properties.dd_weight);
624         getfloatfield(L, table, "dd_crackiness", def.properties.dd_crackiness);
625         getfloatfield(L, table, "dd_crumbliness", def.properties.dd_crumbliness);
626         getfloatfield(L, table, "dd_cuttability", def.properties.dd_cuttability);
627
628         tooldef->registerTool(name, def);
629         return 0; /* number of results */
630 }
631
632 // register_node(name, {lots of stuff})
633 static int l_register_node(lua_State *L)
634 {
635         const char *name = luaL_checkstring(L, 1);
636         infostream<<"register_node: "<<name<<std::endl;
637         luaL_checktype(L, 2, LUA_TTABLE);
638         int nodedef_table = 2;
639
640         // Get server from registry
641         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
642         Server *server = (Server*)lua_touserdata(L, -1);
643         // And get the writable node definition manager from the server
644         IWritableNodeDefManager *nodedef =
645                         server->getWritableNodeDefManager();
646         
647         // Get default node definition from registry
648         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
649         int nodedef_default = lua_gettop(L);
650
651         /*
652                 Add to minetest.registered_nodes with default as metatable
653         */
654         
655         // Get the node definition table given as parameter
656         lua_pushvalue(L, nodedef_table);
657
658         // Set __index to point to itself
659         lua_pushvalue(L, -1);
660         lua_setfield(L, -2, "__index");
661
662         // Set nodedef_default as metatable for the definition
663         lua_pushvalue(L, nodedef_default);
664         lua_setmetatable(L, nodedef_table);
665         
666         // minetest.registered_nodes[name] = nodedef
667         lua_getglobal(L, "minetest");
668         lua_getfield(L, -1, "registered_nodes");
669         luaL_checktype(L, -1, LUA_TTABLE);
670         lua_pushstring(L, name);
671         lua_pushvalue(L, nodedef_table);
672         lua_settable(L, -3);
673
674         /*
675                 Create definition
676         */
677         
678         ContentFeatures f;
679
680         // Default to getting the corresponding NodeItem when dug
681         f.dug_item = std::string("NodeItem \"")+name+"\" 1";
682         
683         // Default to unknown_block.png as all textures
684         f.setAllTextures("unknown_block.png");
685
686         /*
687                 Read definiton from Lua
688         */
689
690         f.name = name;
691         
692         /* Visual definition */
693
694         f.drawtype = (NodeDrawType)getenumfield(L, nodedef_table, "drawtype", es_DrawType,
695                         NDT_NORMAL);
696         getfloatfield(L, nodedef_table, "visual_scale", f.visual_scale);
697
698         lua_getfield(L, nodedef_table, "tile_images");
699         if(lua_istable(L, -1)){
700                 int table = lua_gettop(L);
701                 lua_pushnil(L);
702                 int i = 0;
703                 while(lua_next(L, table) != 0){
704                         // key at index -2 and value at index -1
705                         if(lua_isstring(L, -1))
706                                 f.tname_tiles[i] = lua_tostring(L, -1);
707                         else
708                                 f.tname_tiles[i] = "";
709                         // removes value, keeps key for next iteration
710                         lua_pop(L, 1);
711                         i++;
712                         if(i==6){
713                                 lua_pop(L, 1);
714                                 break;
715                         }
716                 }
717                 // Copy last value to all remaining textures
718                 if(i >= 1){
719                         std::string lastname = f.tname_tiles[i-1];
720                         while(i < 6){
721                                 f.tname_tiles[i] = lastname;
722                                 i++;
723                         }
724                 }
725         }
726         lua_pop(L, 1);
727
728         getstringfield(L, nodedef_table, "inventory_image", f.tname_inventory);
729
730         lua_getfield(L, nodedef_table, "special_materials");
731         if(lua_istable(L, -1)){
732                 int table = lua_gettop(L);
733                 lua_pushnil(L);
734                 int i = 0;
735                 while(lua_next(L, table) != 0){
736                         // key at index -2 and value at index -1
737                         int smtable = lua_gettop(L);
738                         std::string tname = getstringfield_default(
739                                         L, smtable, "image", "");
740                         bool backface_culling = getboolfield_default(
741                                         L, smtable, "backface_culling", true);
742                         MaterialSpec mspec(tname, backface_culling);
743                         f.setSpecialMaterial(i, mspec);
744                         // removes value, keeps key for next iteration
745                         lua_pop(L, 1);
746                         i++;
747                         if(i==6){
748                                 lua_pop(L, 1);
749                                 break;
750                         }
751                 }
752         }
753         lua_pop(L, 1);
754
755         f.alpha = getintfield_default(L, nodedef_table, "alpha", 255);
756
757         /* Other stuff */
758         
759         lua_getfield(L, nodedef_table, "post_effect_color");
760         if(!lua_isnil(L, -1))
761                 f.post_effect_color = readARGB8(L, -1);
762         lua_pop(L, 1);
763
764         f.param_type = (ContentParamType)getenumfield(L, nodedef_table, "paramtype",
765                         es_ContentParamType, CPT_NONE);
766         
767         // True for all ground-like things like stone and mud, false for eg. trees
768         getboolfield(L, nodedef_table, "is_ground_content", f.is_ground_content);
769         getboolfield(L, nodedef_table, "light_propagates", f.light_propagates);
770         getboolfield(L, nodedef_table, "sunlight_propagates", f.sunlight_propagates);
771         // This is used for collision detection.
772         // Also for general solidness queries.
773         getboolfield(L, nodedef_table, "walkable", f.walkable);
774         // Player can point to these
775         getboolfield(L, nodedef_table, "pointable", f.pointable);
776         // Player can dig these
777         getboolfield(L, nodedef_table, "diggable", f.diggable);
778         // Player can climb these
779         getboolfield(L, nodedef_table, "climbable", f.climbable);
780         // Player can build on these
781         getboolfield(L, nodedef_table, "buildable_to", f.buildable_to);
782         // If true, param2 is set to direction when placed. Used for torches.
783         // NOTE: the direction format is quite inefficient and should be changed
784         getboolfield(L, nodedef_table, "wall_mounted", f.wall_mounted);
785         // Whether this content type often contains mineral.
786         // Used for texture atlas creation.
787         // Currently only enabled for CONTENT_STONE.
788         getboolfield(L, nodedef_table, "often_contains_mineral", f.often_contains_mineral);
789         // Inventory item string as which the node appears in inventory when dug.
790         // Mineral overrides this.
791         getstringfield(L, nodedef_table, "dug_item", f.dug_item);
792         // Extra dug item and its rarity
793         getstringfield(L, nodedef_table, "extra_dug_item", f.extra_dug_item);
794         // Usual get interval for extra dug item
795         getintfield(L, nodedef_table, "extra_dug_item_rarity", f.extra_dug_item_rarity);
796         // Metadata name of node (eg. "furnace")
797         getstringfield(L, nodedef_table, "metadata_name", f.metadata_name);
798         // Whether the node is non-liquid, source liquid or flowing liquid
799         f.liquid_type = (LiquidType)getenumfield(L, nodedef_table, "liquidtype",
800                         es_LiquidType, LIQUID_NONE);
801         // If the content is liquid, this is the flowing version of the liquid.
802         getstringfield(L, nodedef_table, "liquid_alternative_flowing",
803                         f.liquid_alternative_flowing);
804         // If the content is liquid, this is the source version of the liquid.
805         getstringfield(L, nodedef_table, "liquid_alternative_source",
806                         f.liquid_alternative_source);
807         // Viscosity for fluid flow, ranging from 1 to 7, with
808         // 1 giving almost instantaneous propagation and 7 being
809         // the slowest possible
810         f.liquid_viscosity = getintfield_default(L, nodedef_table,
811                         "liquid_viscosity", f.liquid_viscosity);
812         // Amount of light the node emits
813         f.light_source = getintfield_default(L, nodedef_table,
814                         "light_source", f.light_source);
815         f.damage_per_second = getintfield_default(L, nodedef_table,
816                         "damage_per_second", f.damage_per_second);
817         
818         lua_getfield(L, nodedef_table, "selection_box");
819         if(lua_istable(L, -1)){
820                 f.selection_box.type = (NodeBoxType)getenumfield(L, -1, "type",
821                                 es_NodeBoxType, NODEBOX_REGULAR);
822
823                 lua_getfield(L, -1, "fixed");
824                 if(lua_istable(L, -1))
825                         f.selection_box.fixed = read_aabbox3df32(L, -1, BS);
826                 lua_pop(L, 1);
827
828                 lua_getfield(L, -1, "wall_top");
829                 if(lua_istable(L, -1))
830                         f.selection_box.wall_top = read_aabbox3df32(L, -1, BS);
831                 lua_pop(L, 1);
832
833                 lua_getfield(L, -1, "wall_bottom");
834                 if(lua_istable(L, -1))
835                         f.selection_box.wall_bottom = read_aabbox3df32(L, -1, BS);
836                 lua_pop(L, 1);
837
838                 lua_getfield(L, -1, "wall_side");
839                 if(lua_istable(L, -1))
840                         f.selection_box.wall_side = read_aabbox3df32(L, -1, BS);
841                 lua_pop(L, 1);
842         }
843         lua_pop(L, 1);
844
845         lua_getfield(L, nodedef_table, "material");
846         if(lua_istable(L, -1)){
847                 f.material.diggability = (Diggability)getenumfield(L, -1, "diggability",
848                                 es_Diggability, DIGGABLE_NORMAL);
849                 
850                 getfloatfield(L, -1, "constant_time", f.material.constant_time);
851                 getfloatfield(L, -1, "weight", f.material.weight);
852                 getfloatfield(L, -1, "crackiness", f.material.crackiness);
853                 getfloatfield(L, -1, "crumbliness", f.material.crumbliness);
854                 getfloatfield(L, -1, "cuttability", f.material.cuttability);
855                 getfloatfield(L, -1, "flammability", f.material.flammability);
856         }
857         lua_pop(L, 1);
858
859         getstringfield(L, nodedef_table, "cookresult_item", f.cookresult_item);
860         getfloatfield(L, nodedef_table, "furnace_cooktime", f.furnace_cooktime);
861         getfloatfield(L, nodedef_table, "furnace_burntime", f.furnace_burntime);
862         
863         /*
864                 Register it
865         */
866         
867         nodedef->set(name, f);
868         
869         return 0; /* number of results */
870 }
871
872 // register_craft({output=item, recipe={{item00,item10},{item01,item11}})
873 static int l_register_craft(lua_State *L)
874 {
875         infostream<<"register_craft"<<std::endl;
876         luaL_checktype(L, 1, LUA_TTABLE);
877         int table0 = 1;
878
879         // Get server from registry
880         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
881         Server *server = (Server*)lua_touserdata(L, -1);
882         // And get the writable craft definition manager from the server
883         IWritableCraftDefManager *craftdef =
884                         server->getWritableCraftDefManager();
885         
886         std::string output;
887         int width = 0;
888         std::vector<std::string> input;
889
890         lua_getfield(L, table0, "output");
891         luaL_checktype(L, -1, LUA_TSTRING);
892         if(lua_isstring(L, -1))
893                 output = lua_tostring(L, -1);
894         lua_pop(L, 1);
895
896         lua_getfield(L, table0, "recipe");
897         luaL_checktype(L, -1, LUA_TTABLE);
898         if(lua_istable(L, -1)){
899                 int table1 = lua_gettop(L);
900                 lua_pushnil(L);
901                 int rowcount = 0;
902                 while(lua_next(L, table1) != 0){
903                         int colcount = 0;
904                         // key at index -2 and value at index -1
905                         luaL_checktype(L, -1, LUA_TTABLE);
906                         if(lua_istable(L, -1)){
907                                 int table2 = lua_gettop(L);
908                                 lua_pushnil(L);
909                                 while(lua_next(L, table2) != 0){
910                                         // key at index -2 and value at index -1
911                                         luaL_checktype(L, -1, LUA_TSTRING);
912                                         input.push_back(lua_tostring(L, -1));
913                                         // removes value, keeps key for next iteration
914                                         lua_pop(L, 1);
915                                         colcount++;
916                                 }
917                         }
918                         if(rowcount == 0){
919                                 width = colcount;
920                         } else {
921                                 if(colcount != width){
922                                         script_error(L, "error: %s\n", "Invalid crafting recipe");
923                                 }
924                         }
925                         // removes value, keeps key for next iteration
926                         lua_pop(L, 1);
927                         rowcount++;
928                 }
929         }
930         lua_pop(L, 1);
931
932         CraftDefinition def(output, width, input);
933         craftdef->registerCraft(def);
934
935         return 0; /* number of results */
936 }
937
938 // setting_get(name)
939 static int l_setting_get(lua_State *L)
940 {
941         const char *name = luaL_checkstring(L, 1);
942         try{
943                 std::string value = g_settings->get(name);
944                 lua_pushstring(L, value.c_str());
945         } catch(SettingNotFoundException &e){
946                 lua_pushnil(L);
947         }
948         return 1;
949 }
950
951 // setting_getbool(name)
952 static int l_setting_getbool(lua_State *L)
953 {
954         const char *name = luaL_checkstring(L, 1);
955         try{
956                 bool value = g_settings->getBool(name);
957                 lua_pushboolean(L, value);
958         } catch(SettingNotFoundException &e){
959                 lua_pushnil(L);
960         }
961         return 1;
962 }
963
964 // chat_send_all(text)
965 static int l_chat_send_all(lua_State *L)
966 {
967         const char *text = luaL_checkstring(L, 1);
968         // Get server from registry
969         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
970         Server *server = (Server*)lua_touserdata(L, -1);
971         // Send
972         server->notifyPlayers(narrow_to_wide(text));
973         return 0;
974 }
975
976 // chat_send_player(name, text)
977 static int l_chat_send_player(lua_State *L)
978 {
979         const char *name = luaL_checkstring(L, 1);
980         const char *text = luaL_checkstring(L, 2);
981         // Get server from registry
982         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
983         Server *server = (Server*)lua_touserdata(L, -1);
984         // Send
985         server->notifyPlayer(name, narrow_to_wide(text));
986         return 0;
987 }
988
989 static const struct luaL_Reg minetest_f [] = {
990         {"register_nodedef_defaults", l_register_nodedef_defaults},
991         {"register_entity", l_register_entity},
992         {"register_tool", l_register_tool},
993         {"register_node", l_register_node},
994         {"register_craft", l_register_craft},
995         {"register_abm", l_register_abm},
996         {"setting_get", l_setting_get},
997         {"setting_getbool", l_setting_getbool},
998         {"chat_send_all", l_chat_send_all},
999         {"chat_send_player", l_chat_send_player},
1000         {NULL, NULL}
1001 };
1002
1003 /*
1004         LuaEntity functions
1005 */
1006
1007 static const struct luaL_Reg minetest_entity_m [] = {
1008         {NULL, NULL}
1009 };
1010
1011 /*
1012         Getters for stuff in main tables
1013 */
1014
1015 static void objectref_get(lua_State *L, u16 id)
1016 {
1017         // Get minetest.object_refs[i]
1018         lua_getglobal(L, "minetest");
1019         lua_getfield(L, -1, "object_refs");
1020         luaL_checktype(L, -1, LUA_TTABLE);
1021         lua_pushnumber(L, id);
1022         lua_gettable(L, -2);
1023         lua_remove(L, -2); // object_refs
1024         lua_remove(L, -2); // minetest
1025 }
1026
1027 static void luaentity_get(lua_State *L, u16 id)
1028 {
1029         // Get minetest.luaentities[i]
1030         lua_getglobal(L, "minetest");
1031         lua_getfield(L, -1, "luaentities");
1032         luaL_checktype(L, -1, LUA_TTABLE);
1033         lua_pushnumber(L, id);
1034         lua_gettable(L, -2);
1035         lua_remove(L, -2); // luaentities
1036         lua_remove(L, -2); // minetest
1037 }
1038
1039 /*
1040         Reference wrappers
1041 */
1042
1043 #define method(class, name) {#name, class::l_##name}
1044
1045 /*
1046         NodeMetaRef
1047 */
1048
1049 class NodeMetaRef
1050 {
1051 private:
1052         v3s16 m_p;
1053         ServerEnvironment *m_env;
1054
1055         static const char className[];
1056         static const luaL_reg methods[];
1057
1058         static NodeMetaRef *checkobject(lua_State *L, int narg)
1059         {
1060                 luaL_checktype(L, narg, LUA_TUSERDATA);
1061                 void *ud = luaL_checkudata(L, narg, className);
1062                 if(!ud) luaL_typerror(L, narg, className);
1063                 return *(NodeMetaRef**)ud;  // unbox pointer
1064         }
1065         
1066         static NodeMetadata* getmeta(NodeMetaRef *ref)
1067         {
1068                 NodeMetadata *meta = ref->m_env->getMap().getNodeMetadata(ref->m_p);
1069                 return meta;
1070         }
1071
1072         static void reportMetadataChange(NodeMetaRef *ref)
1073         {
1074                 // Inform other things that the metadata has changed
1075                 v3s16 blockpos = getNodeBlockPos(ref->m_p);
1076                 MapEditEvent event;
1077                 event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
1078                 event.p = blockpos;
1079                 ref->m_env->getMap().dispatchEvent(&event);
1080                 // Set the block to be saved
1081                 MapBlock *block = ref->m_env->getMap().getBlockNoCreateNoEx(blockpos);
1082                 if(block)
1083                         block->raiseModified(MOD_STATE_WRITE_NEEDED, "l_settext");
1084         }
1085         
1086         // Exported functions
1087         
1088         // garbage collector
1089         static int gc_object(lua_State *L) {
1090                 NodeMetaRef *o = *(NodeMetaRef **)(lua_touserdata(L, 1));
1091                 delete o;
1092                 return 0;
1093         }
1094
1095         // settext(self, text)
1096         static int l_settext(lua_State *L)
1097         {
1098                 NodeMetaRef *ref = checkobject(L, 1);
1099                 NodeMetadata *meta = getmeta(ref);
1100                 if(meta == NULL) return 0;
1101                 // Do it
1102                 std::string text = lua_tostring(L, 2);
1103                 meta->setText(text);
1104                 // Inform other things that the metadata has changed
1105                 reportMetadataChange(ref);
1106                 return 0;
1107         }
1108
1109 public:
1110         NodeMetaRef(v3s16 p, ServerEnvironment *env):
1111                 m_p(p),
1112                 m_env(env)
1113         {
1114         }
1115
1116         ~NodeMetaRef()
1117         {
1118         }
1119
1120         // Creates an NodeMetaRef and leaves it on top of stack
1121         // Not callable from Lua; all references are created on the C side.
1122         static void create(lua_State *L, v3s16 p, ServerEnvironment *env)
1123         {
1124                 NodeMetaRef *o = new NodeMetaRef(p, env);
1125                 //infostream<<"NodeMetaRef::create: o="<<o<<std::endl;
1126                 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1127                 luaL_getmetatable(L, className);
1128                 lua_setmetatable(L, -2);
1129         }
1130
1131         static void Register(lua_State *L)
1132         {
1133                 lua_newtable(L);
1134                 int methodtable = lua_gettop(L);
1135                 luaL_newmetatable(L, className);
1136                 int metatable = lua_gettop(L);
1137
1138                 lua_pushliteral(L, "__metatable");
1139                 lua_pushvalue(L, methodtable);
1140                 lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
1141
1142                 lua_pushliteral(L, "__index");
1143                 lua_pushvalue(L, methodtable);
1144                 lua_settable(L, metatable);
1145
1146                 lua_pushliteral(L, "__gc");
1147                 lua_pushcfunction(L, gc_object);
1148                 lua_settable(L, metatable);
1149
1150                 lua_pop(L, 1);  // drop metatable
1151
1152                 luaL_openlib(L, 0, methods, 0);  // fill methodtable
1153                 lua_pop(L, 1);  // drop methodtable
1154
1155                 // Cannot be created from Lua
1156                 //lua_register(L, className, create_object);
1157         }
1158 };
1159 const char NodeMetaRef::className[] = "NodeMetaRef";
1160 const luaL_reg NodeMetaRef::methods[] = {
1161         method(NodeMetaRef, settext),
1162         {0,0}
1163 };
1164
1165 /*
1166         EnvRef
1167 */
1168
1169 class EnvRef
1170 {
1171 private:
1172         ServerEnvironment *m_env;
1173
1174         static const char className[];
1175         static const luaL_reg methods[];
1176
1177         static EnvRef *checkobject(lua_State *L, int narg)
1178         {
1179                 luaL_checktype(L, narg, LUA_TUSERDATA);
1180                 void *ud = luaL_checkudata(L, narg, className);
1181                 if(!ud) luaL_typerror(L, narg, className);
1182                 return *(EnvRef**)ud;  // unbox pointer
1183         }
1184         
1185         // Exported functions
1186
1187         // EnvRef:add_node(pos, node)
1188         // pos = {x=num, y=num, z=num}
1189         static int l_add_node(lua_State *L)
1190         {
1191                 infostream<<"EnvRef::l_add_node()"<<std::endl;
1192                 EnvRef *o = checkobject(L, 1);
1193                 ServerEnvironment *env = o->m_env;
1194                 if(env == NULL) return 0;
1195                 // pos
1196                 v3s16 pos = readpos(L, 2);
1197                 // content
1198                 MapNode n = readnode(L, 3, env->getGameDef()->ndef());
1199                 // Do it
1200                 bool succeeded = env->getMap().addNodeWithEvent(pos, n);
1201                 lua_pushboolean(L, succeeded);
1202                 return 1;
1203         }
1204
1205         // EnvRef:remove_node(pos)
1206         // pos = {x=num, y=num, z=num}
1207         static int l_remove_node(lua_State *L)
1208         {
1209                 infostream<<"EnvRef::l_remove_node()"<<std::endl;
1210                 EnvRef *o = checkobject(L, 1);
1211                 ServerEnvironment *env = o->m_env;
1212                 if(env == NULL) return 0;
1213                 // pos
1214                 v3s16 pos = readpos(L, 2);
1215                 // Do it
1216                 bool succeeded = env->getMap().removeNodeWithEvent(pos);
1217                 lua_pushboolean(L, succeeded);
1218                 return 1;
1219         }
1220
1221         // EnvRef:get_node(pos)
1222         // pos = {x=num, y=num, z=num}
1223         static int l_get_node(lua_State *L)
1224         {
1225                 infostream<<"EnvRef::l_get_node()"<<std::endl;
1226                 EnvRef *o = checkobject(L, 1);
1227                 ServerEnvironment *env = o->m_env;
1228                 if(env == NULL) return 0;
1229                 // pos
1230                 v3s16 pos = readpos(L, 2);
1231                 // Do it
1232                 MapNode n = env->getMap().getNodeNoEx(pos);
1233                 // Return node
1234                 pushnode(L, n, env->getGameDef()->ndef());
1235                 return 1;
1236         }
1237
1238         // EnvRef:add_luaentity(pos, entityname)
1239         // pos = {x=num, y=num, z=num}
1240         static int l_add_luaentity(lua_State *L)
1241         {
1242                 infostream<<"EnvRef::l_add_luaentity()"<<std::endl;
1243                 EnvRef *o = checkobject(L, 1);
1244                 ServerEnvironment *env = o->m_env;
1245                 if(env == NULL) return 0;
1246                 // pos
1247                 v3f pos = readFloatPos(L, 2);
1248                 // content
1249                 const char *name = lua_tostring(L, 3);
1250                 // Do it
1251                 ServerActiveObject *obj = new LuaEntitySAO(env, pos, name, "");
1252                 env->addActiveObject(obj);
1253                 return 0;
1254         }
1255
1256         // EnvRef:get_meta(pos)
1257         static int l_get_meta(lua_State *L)
1258         {
1259                 infostream<<"EnvRef::l_get_meta()"<<std::endl;
1260                 EnvRef *o = checkobject(L, 1);
1261                 ServerEnvironment *env = o->m_env;
1262                 if(env == NULL) return 0;
1263                 // Do it
1264                 v3s16 p = readpos(L, 2);
1265                 NodeMetaRef::create(L, p, env);
1266                 return 1;
1267         }
1268
1269         static int gc_object(lua_State *L) {
1270                 EnvRef *o = *(EnvRef **)(lua_touserdata(L, 1));
1271                 delete o;
1272                 return 0;
1273         }
1274
1275 public:
1276         EnvRef(ServerEnvironment *env):
1277                 m_env(env)
1278         {
1279                 infostream<<"EnvRef created"<<std::endl;
1280         }
1281
1282         ~EnvRef()
1283         {
1284                 infostream<<"EnvRef destructing"<<std::endl;
1285         }
1286
1287         // Creates an EnvRef and leaves it on top of stack
1288         // Not callable from Lua; all references are created on the C side.
1289         static void create(lua_State *L, ServerEnvironment *env)
1290         {
1291                 EnvRef *o = new EnvRef(env);
1292                 //infostream<<"EnvRef::create: o="<<o<<std::endl;
1293                 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1294                 luaL_getmetatable(L, className);
1295                 lua_setmetatable(L, -2);
1296         }
1297
1298         static void set_null(lua_State *L)
1299         {
1300                 EnvRef *o = checkobject(L, -1);
1301                 o->m_env = NULL;
1302         }
1303         
1304         static void Register(lua_State *L)
1305         {
1306                 lua_newtable(L);
1307                 int methodtable = lua_gettop(L);
1308                 luaL_newmetatable(L, className);
1309                 int metatable = lua_gettop(L);
1310
1311                 lua_pushliteral(L, "__metatable");
1312                 lua_pushvalue(L, methodtable);
1313                 lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
1314
1315                 lua_pushliteral(L, "__index");
1316                 lua_pushvalue(L, methodtable);
1317                 lua_settable(L, metatable);
1318
1319                 lua_pushliteral(L, "__gc");
1320                 lua_pushcfunction(L, gc_object);
1321                 lua_settable(L, metatable);
1322
1323                 lua_pop(L, 1);  // drop metatable
1324
1325                 luaL_openlib(L, 0, methods, 0);  // fill methodtable
1326                 lua_pop(L, 1);  // drop methodtable
1327
1328                 // Cannot be created from Lua
1329                 //lua_register(L, className, create_object);
1330         }
1331 };
1332 const char EnvRef::className[] = "EnvRef";
1333 const luaL_reg EnvRef::methods[] = {
1334         method(EnvRef, add_node),
1335         method(EnvRef, remove_node),
1336         method(EnvRef, get_node),
1337         method(EnvRef, add_luaentity),
1338         method(EnvRef, get_meta),
1339         {0,0}
1340 };
1341
1342 /*
1343         ObjectRef
1344 */
1345
1346 class ObjectRef
1347 {
1348 private:
1349         ServerActiveObject *m_object;
1350
1351         static const char className[];
1352         static const luaL_reg methods[];
1353
1354         static ObjectRef *checkobject(lua_State *L, int narg)
1355         {
1356                 luaL_checktype(L, narg, LUA_TUSERDATA);
1357                 void *ud = luaL_checkudata(L, narg, className);
1358                 if(!ud) luaL_typerror(L, narg, className);
1359                 return *(ObjectRef**)ud;  // unbox pointer
1360         }
1361         
1362         static ServerActiveObject* getobject(ObjectRef *ref)
1363         {
1364                 ServerActiveObject *co = ref->m_object;
1365                 return co;
1366         }
1367         
1368         static LuaEntitySAO* getluaobject(ObjectRef *ref)
1369         {
1370                 ServerActiveObject *obj = getobject(ref);
1371                 if(obj == NULL)
1372                         return NULL;
1373                 if(obj->getType() != ACTIVEOBJECT_TYPE_LUAENTITY)
1374                         return NULL;
1375                 return (LuaEntitySAO*)obj;
1376         }
1377         
1378         // Exported functions
1379         
1380         // garbage collector
1381         static int gc_object(lua_State *L) {
1382                 ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
1383                 //infostream<<"ObjectRef::gc_object: o="<<o<<std::endl;
1384                 delete o;
1385                 return 0;
1386         }
1387
1388         // remove(self)
1389         static int l_remove(lua_State *L)
1390         {
1391                 ObjectRef *ref = checkobject(L, 1);
1392                 ServerActiveObject *co = getobject(ref);
1393                 if(co == NULL) return 0;
1394                 infostream<<"ObjectRef::l_remove(): id="<<co->getId()<<std::endl;
1395                 co->m_removed = true;
1396                 return 0;
1397         }
1398         
1399         // getpos(self)
1400         // returns: {x=num, y=num, z=num}
1401         static int l_getpos(lua_State *L)
1402         {
1403                 ObjectRef *ref = checkobject(L, 1);
1404                 ServerActiveObject *co = getobject(ref);
1405                 if(co == NULL) return 0;
1406                 v3f pos = co->getBasePosition() / BS;
1407                 lua_newtable(L);
1408                 lua_pushnumber(L, pos.X);
1409                 lua_setfield(L, -2, "x");
1410                 lua_pushnumber(L, pos.Y);
1411                 lua_setfield(L, -2, "y");
1412                 lua_pushnumber(L, pos.Z);
1413                 lua_setfield(L, -2, "z");
1414                 return 1;
1415         }
1416         
1417         // setpos(self, pos)
1418         static int l_setpos(lua_State *L)
1419         {
1420                 ObjectRef *ref = checkobject(L, 1);
1421                 //LuaEntitySAO *co = getluaobject(ref);
1422                 ServerActiveObject *co = getobject(ref);
1423                 if(co == NULL) return 0;
1424                 // pos
1425                 v3f pos = readFloatPos(L, 2);
1426                 // Do it
1427                 co->setPos(pos);
1428                 return 0;
1429         }
1430         
1431         // moveto(self, pos, continuous=false)
1432         static int l_moveto(lua_State *L)
1433         {
1434                 ObjectRef *ref = checkobject(L, 1);
1435                 //LuaEntitySAO *co = getluaobject(ref);
1436                 ServerActiveObject *co = getobject(ref);
1437                 if(co == NULL) return 0;
1438                 // pos
1439                 v3f pos = readFloatPos(L, 2);
1440                 // continuous
1441                 bool continuous = lua_toboolean(L, 3);
1442                 // Do it
1443                 co->moveTo(pos, continuous);
1444                 return 0;
1445         }
1446
1447         // setvelocity(self, velocity)
1448         static int l_setvelocity(lua_State *L)
1449         {
1450                 ObjectRef *ref = checkobject(L, 1);
1451                 LuaEntitySAO *co = getluaobject(ref);
1452                 if(co == NULL) return 0;
1453                 // pos
1454                 v3f pos = readFloatPos(L, 2);
1455                 // Do it
1456                 co->setVelocity(pos);
1457                 return 0;
1458         }
1459         
1460         // setacceleration(self, acceleration)
1461         static int l_setacceleration(lua_State *L)
1462         {
1463                 ObjectRef *ref = checkobject(L, 1);
1464                 LuaEntitySAO *co = getluaobject(ref);
1465                 if(co == NULL) return 0;
1466                 // pos
1467                 v3f pos = readFloatPos(L, 2);
1468                 // Do it
1469                 co->setAcceleration(pos);
1470                 return 0;
1471         }
1472         
1473         // getacceleration(self)
1474         static int l_getacceleration(lua_State *L)
1475         {
1476                 ObjectRef *ref = checkobject(L, 1);
1477                 LuaEntitySAO *co = getluaobject(ref);
1478                 if(co == NULL) return 0;
1479                 // Do it
1480                 v3f v = co->getAcceleration();
1481                 pushFloatPos(L, v);
1482                 return 1;
1483         }
1484         
1485         // add_to_inventory(self, itemstring)
1486         // returns: true if item was added, false otherwise
1487         static int l_add_to_inventory(lua_State *L)
1488         {
1489                 ObjectRef *ref = checkobject(L, 1);
1490                 luaL_checkstring(L, 2);
1491                 ServerActiveObject *co = getobject(ref);
1492                 if(co == NULL) return 0;
1493                 // itemstring
1494                 const char *itemstring = lua_tostring(L, 2);
1495                 infostream<<"ObjectRef::l_add_to_inventory(): id="<<co->getId()
1496                                 <<" itemstring=\""<<itemstring<<"\""<<std::endl;
1497                 // Do it
1498                 std::istringstream is(itemstring, std::ios::binary);
1499                 ServerEnvironment *env = co->getEnv();
1500                 assert(env);
1501                 IGameDef *gamedef = env->getGameDef();
1502                 InventoryItem *item = InventoryItem::deSerialize(is, gamedef);
1503                 infostream<<"item="<<env<<std::endl;
1504                 bool fits = co->addToInventory(item);
1505                 // Return
1506                 lua_pushboolean(L, fits);
1507                 return 1;
1508         }
1509
1510         // settexturemod(self, mod)
1511         static int l_settexturemod(lua_State *L)
1512         {
1513                 ObjectRef *ref = checkobject(L, 1);
1514                 LuaEntitySAO *co = getluaobject(ref);
1515                 if(co == NULL) return 0;
1516                 // Do it
1517                 std::string mod = lua_tostring(L, 2);
1518                 co->setTextureMod(mod);
1519                 return 0;
1520         }
1521         
1522         // setsprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2,
1523         //           select_horiz_by_yawpitch=false)
1524         static int l_setsprite(lua_State *L)
1525         {
1526                 ObjectRef *ref = checkobject(L, 1);
1527                 LuaEntitySAO *co = getluaobject(ref);
1528                 if(co == NULL) return 0;
1529                 // Do it
1530                 v2s16 p(0,0);
1531                 if(!lua_isnil(L, 2))
1532                         p = read_v2s16(L, 2);
1533                 int num_frames = 1;
1534                 if(!lua_isnil(L, 3))
1535                         num_frames = lua_tonumber(L, 3);
1536                 float framelength = 0.2;
1537                 if(!lua_isnil(L, 4))
1538                         framelength = lua_tonumber(L, 4);
1539                 bool select_horiz_by_yawpitch = false;
1540                 if(!lua_isnil(L, 5))
1541                         select_horiz_by_yawpitch = lua_toboolean(L, 5);
1542                 co->setSprite(p, num_frames, framelength, select_horiz_by_yawpitch);
1543                 return 0;
1544         }
1545         
1546 public:
1547         ObjectRef(ServerActiveObject *object):
1548                 m_object(object)
1549         {
1550                 //infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
1551         }
1552
1553         ~ObjectRef()
1554         {
1555                 /*if(m_object)
1556                         infostream<<"ObjectRef destructing for id="
1557                                         <<m_object->getId()<<std::endl;
1558                 else
1559                         infostream<<"ObjectRef destructing for id=unknown"<<std::endl;*/
1560         }
1561
1562         // Creates an ObjectRef and leaves it on top of stack
1563         // Not callable from Lua; all references are created on the C side.
1564         static void create(lua_State *L, ServerActiveObject *object)
1565         {
1566                 ObjectRef *o = new ObjectRef(object);
1567                 //infostream<<"ObjectRef::create: o="<<o<<std::endl;
1568                 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1569                 luaL_getmetatable(L, className);
1570                 lua_setmetatable(L, -2);
1571         }
1572
1573         static void set_null(lua_State *L)
1574         {
1575                 ObjectRef *o = checkobject(L, -1);
1576                 o->m_object = NULL;
1577         }
1578         
1579         static void Register(lua_State *L)
1580         {
1581                 lua_newtable(L);
1582                 int methodtable = lua_gettop(L);
1583                 luaL_newmetatable(L, className);
1584                 int metatable = lua_gettop(L);
1585
1586                 lua_pushliteral(L, "__metatable");
1587                 lua_pushvalue(L, methodtable);
1588                 lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
1589
1590                 lua_pushliteral(L, "__index");
1591                 lua_pushvalue(L, methodtable);
1592                 lua_settable(L, metatable);
1593
1594                 lua_pushliteral(L, "__gc");
1595                 lua_pushcfunction(L, gc_object);
1596                 lua_settable(L, metatable);
1597
1598                 lua_pop(L, 1);  // drop metatable
1599
1600                 luaL_openlib(L, 0, methods, 0);  // fill methodtable
1601                 lua_pop(L, 1);  // drop methodtable
1602
1603                 // Cannot be created from Lua
1604                 //lua_register(L, className, create_object);
1605         }
1606 };
1607 const char ObjectRef::className[] = "ObjectRef";
1608 const luaL_reg ObjectRef::methods[] = {
1609         method(ObjectRef, remove),
1610         method(ObjectRef, getpos),
1611         method(ObjectRef, setpos),
1612         method(ObjectRef, moveto),
1613         method(ObjectRef, setvelocity),
1614         method(ObjectRef, setacceleration),
1615         method(ObjectRef, add_to_inventory),
1616         method(ObjectRef, settexturemod),
1617         method(ObjectRef, setsprite),
1618         {0,0}
1619 };
1620
1621 // Creates a new anonymous reference if id=0
1622 static void objectref_get_or_create(lua_State *L,
1623                 ServerActiveObject *cobj)
1624 {
1625         if(cobj->getId() == 0){
1626                 ObjectRef::create(L, cobj);
1627         } else {
1628                 objectref_get(L, cobj->getId());
1629         }
1630 }
1631
1632 /*
1633         Main export function
1634 */
1635
1636 void scriptapi_export(lua_State *L, Server *server)
1637 {
1638         realitycheck(L);
1639         assert(lua_checkstack(L, 20));
1640         infostream<<"scriptapi_export"<<std::endl;
1641         StackUnroller stack_unroller(L);
1642
1643         // Store server as light userdata in registry
1644         lua_pushlightuserdata(L, server);
1645         lua_setfield(L, LUA_REGISTRYINDEX, "minetest_server");
1646
1647         // Store nil as minetest_nodedef_defaults in registry
1648         lua_pushnil(L);
1649         lua_setfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
1650         
1651         // Register global functions in table minetest
1652         lua_newtable(L);
1653         luaL_register(L, NULL, minetest_f);
1654         lua_setglobal(L, "minetest");
1655         
1656         // Get the main minetest table
1657         lua_getglobal(L, "minetest");
1658
1659         // Add tables to minetest
1660         
1661         lua_newtable(L);
1662         lua_setfield(L, -2, "registered_nodes");
1663         lua_newtable(L);
1664         lua_setfield(L, -2, "registered_entities");
1665         lua_newtable(L);
1666         lua_setfield(L, -2, "registered_abms");
1667         
1668         lua_newtable(L);
1669         lua_setfield(L, -2, "object_refs");
1670         lua_newtable(L);
1671         lua_setfield(L, -2, "luaentities");
1672
1673         // Create entity prototype
1674         luaL_newmetatable(L, "minetest.entity");
1675         // metatable.__index = metatable
1676         lua_pushvalue(L, -1); // Duplicate metatable
1677         lua_setfield(L, -2, "__index");
1678         // Put functions in metatable
1679         luaL_register(L, NULL, minetest_entity_m);
1680         // Put other stuff in metatable
1681         
1682         // Register reference wrappers
1683         NodeMetaRef::Register(L);
1684         EnvRef::Register(L);
1685         ObjectRef::Register(L);
1686 }
1687
1688 void scriptapi_add_environment(lua_State *L, ServerEnvironment *env)
1689 {
1690         realitycheck(L);
1691         assert(lua_checkstack(L, 20));
1692         infostream<<"scriptapi_add_environment"<<std::endl;
1693         StackUnroller stack_unroller(L);
1694
1695         // Create EnvRef on stack
1696         EnvRef::create(L, env);
1697         int envref = lua_gettop(L);
1698
1699         // minetest.env = envref
1700         lua_getglobal(L, "minetest");
1701         luaL_checktype(L, -1, LUA_TTABLE);
1702         lua_pushvalue(L, envref);
1703         lua_setfield(L, -2, "env");
1704
1705         // Store environment as light userdata in registry
1706         lua_pushlightuserdata(L, env);
1707         lua_setfield(L, LUA_REGISTRYINDEX, "minetest_env");
1708
1709         /* Add ActiveBlockModifiers to environment */
1710
1711         // Get minetest.registered_abms
1712         lua_getglobal(L, "minetest");
1713         lua_getfield(L, -1, "registered_abms");
1714         luaL_checktype(L, -1, LUA_TTABLE);
1715         int registered_abms = lua_gettop(L);
1716         
1717         if(lua_istable(L, registered_abms)){
1718                 int table = lua_gettop(L);
1719                 lua_pushnil(L);
1720                 while(lua_next(L, table) != 0){
1721                         // key at index -2 and value at index -1
1722                         int id = lua_tonumber(L, -2);
1723                         int current_abm = lua_gettop(L);
1724
1725                         std::set<std::string> trigger_contents;
1726                         lua_getfield(L, current_abm, "nodenames");
1727                         if(lua_istable(L, -1)){
1728                                 int table = lua_gettop(L);
1729                                 lua_pushnil(L);
1730                                 while(lua_next(L, table) != 0){
1731                                         // key at index -2 and value at index -1
1732                                         luaL_checktype(L, -1, LUA_TSTRING);
1733                                         trigger_contents.insert(lua_tostring(L, -1));
1734                                         // removes value, keeps key for next iteration
1735                                         lua_pop(L, 1);
1736                                 }
1737                         }
1738                         lua_pop(L, 1);
1739
1740                         float trigger_interval = 10.0;
1741                         getfloatfield(L, current_abm, "interval", trigger_interval);
1742
1743                         int trigger_chance = 50;
1744                         getintfield(L, current_abm, "chance", trigger_chance);
1745
1746                         LuaABM *abm = new LuaABM(L, id, trigger_contents,
1747                                         trigger_interval, trigger_chance);
1748                         
1749                         env->addActiveBlockModifier(abm);
1750
1751                         // removes value, keeps key for next iteration
1752                         lua_pop(L, 1);
1753                 }
1754         }
1755         lua_pop(L, 1);
1756 }
1757
1758 #if 0
1759 // Dump stack top with the dump2 function
1760 static void dump2(lua_State *L, const char *name)
1761 {
1762         // Dump object (debug)
1763         lua_getglobal(L, "dump2");
1764         luaL_checktype(L, -1, LUA_TFUNCTION);
1765         lua_pushvalue(L, -2); // Get previous stack top as first parameter
1766         lua_pushstring(L, name);
1767         if(lua_pcall(L, 2, 0, 0))
1768                 script_error(L, "error: %s\n", lua_tostring(L, -1));
1769 }
1770 #endif
1771
1772 /*
1773         object_reference
1774 */
1775
1776 void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj)
1777 {
1778         realitycheck(L);
1779         assert(lua_checkstack(L, 20));
1780         infostream<<"scriptapi_add_object_reference: id="<<cobj->getId()<<std::endl;
1781         StackUnroller stack_unroller(L);
1782
1783         // Create object on stack
1784         ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack
1785         int object = lua_gettop(L);
1786
1787         // Get minetest.object_refs table
1788         lua_getglobal(L, "minetest");
1789         lua_getfield(L, -1, "object_refs");
1790         luaL_checktype(L, -1, LUA_TTABLE);
1791         int objectstable = lua_gettop(L);
1792         
1793         // object_refs[id] = object
1794         lua_pushnumber(L, cobj->getId()); // Push id
1795         lua_pushvalue(L, object); // Copy object to top of stack
1796         lua_settable(L, objectstable);
1797 }
1798
1799 void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj)
1800 {
1801         realitycheck(L);
1802         assert(lua_checkstack(L, 20));
1803         infostream<<"scriptapi_rm_object_reference: id="<<cobj->getId()<<std::endl;
1804         StackUnroller stack_unroller(L);
1805
1806         // Get minetest.object_refs table
1807         lua_getglobal(L, "minetest");
1808         lua_getfield(L, -1, "object_refs");
1809         luaL_checktype(L, -1, LUA_TTABLE);
1810         int objectstable = lua_gettop(L);
1811         
1812         // Get object_refs[id]
1813         lua_pushnumber(L, cobj->getId()); // Push id
1814         lua_gettable(L, objectstable);
1815         // Set object reference to NULL
1816         ObjectRef::set_null(L);
1817         lua_pop(L, 1); // pop object
1818
1819         // Set object_refs[id] = nil
1820         lua_pushnumber(L, cobj->getId()); // Push id
1821         lua_pushnil(L);
1822         lua_settable(L, objectstable);
1823 }
1824
1825 bool scriptapi_on_chat_message(lua_State *L, const std::string &name,
1826                 const std::string &message)
1827 {
1828         realitycheck(L);
1829         assert(lua_checkstack(L, 20));
1830         StackUnroller stack_unroller(L);
1831
1832         // Get minetest.registered_on_chat_messages
1833         lua_getglobal(L, "minetest");
1834         lua_getfield(L, -1, "registered_on_chat_messages");
1835         luaL_checktype(L, -1, LUA_TTABLE);
1836         int table = lua_gettop(L);
1837         // Foreach
1838         lua_pushnil(L);
1839         while(lua_next(L, table) != 0){
1840                 // key at index -2 and value at index -1
1841                 luaL_checktype(L, -1, LUA_TFUNCTION);
1842                 // Call function
1843                 lua_pushstring(L, name.c_str());
1844                 lua_pushstring(L, message.c_str());
1845                 if(lua_pcall(L, 2, 1, 0))
1846                         script_error(L, "error: %s\n", lua_tostring(L, -1));
1847                 bool ate = lua_toboolean(L, -1);
1848                 lua_pop(L, 1);
1849                 if(ate)
1850                         return true;
1851                 // value removed, keep key for next iteration
1852         }
1853         return false;
1854 }
1855
1856 /*
1857         misc
1858 */
1859
1860 void scriptapi_on_newplayer(lua_State *L, ServerActiveObject *player)
1861 {
1862         realitycheck(L);
1863         assert(lua_checkstack(L, 20));
1864         StackUnroller stack_unroller(L);
1865
1866         // Get minetest.registered_on_newplayers
1867         lua_getglobal(L, "minetest");
1868         lua_getfield(L, -1, "registered_on_newplayers");
1869         luaL_checktype(L, -1, LUA_TTABLE);
1870         int table = lua_gettop(L);
1871         // Foreach
1872         lua_pushnil(L);
1873         while(lua_next(L, table) != 0){
1874                 // key at index -2 and value at index -1
1875                 luaL_checktype(L, -1, LUA_TFUNCTION);
1876                 // Call function
1877                 objectref_get_or_create(L, player);
1878                 if(lua_pcall(L, 1, 0, 0))
1879                         script_error(L, "error: %s\n", lua_tostring(L, -1));
1880                 // value removed, keep key for next iteration
1881         }
1882 }
1883 bool scriptapi_on_respawnplayer(lua_State *L, ServerActiveObject *player)
1884 {
1885         realitycheck(L);
1886         assert(lua_checkstack(L, 20));
1887         StackUnroller stack_unroller(L);
1888
1889         bool positioning_handled_by_some = false;
1890
1891         // Get minetest.registered_on_respawnplayers
1892         lua_getglobal(L, "minetest");
1893         lua_getfield(L, -1, "registered_on_respawnplayers");
1894         luaL_checktype(L, -1, LUA_TTABLE);
1895         int table = lua_gettop(L);
1896         // Foreach
1897         lua_pushnil(L);
1898         while(lua_next(L, table) != 0){
1899                 // key at index -2 and value at index -1
1900                 luaL_checktype(L, -1, LUA_TFUNCTION);
1901                 // Call function
1902                 objectref_get_or_create(L, player);
1903                 if(lua_pcall(L, 1, 1, 0))
1904                         script_error(L, "error: %s\n", lua_tostring(L, -1));
1905                 bool positioning_handled = lua_toboolean(L, -1);
1906                 lua_pop(L, 1);
1907                 if(positioning_handled)
1908                         positioning_handled_by_some = true;
1909                 // value removed, keep key for next iteration
1910         }
1911         return positioning_handled_by_some;
1912 }
1913
1914 /*
1915         environment
1916 */
1917
1918 void scriptapi_environment_step(lua_State *L, float dtime)
1919 {
1920         realitycheck(L);
1921         assert(lua_checkstack(L, 20));
1922         //infostream<<"scriptapi_environment_step"<<std::endl;
1923         StackUnroller stack_unroller(L);
1924
1925         // Get minetest.registered_globalsteps
1926         lua_getglobal(L, "minetest");
1927         lua_getfield(L, -1, "registered_globalsteps");
1928         luaL_checktype(L, -1, LUA_TTABLE);
1929         int table = lua_gettop(L);
1930         // Foreach
1931         lua_pushnil(L);
1932         while(lua_next(L, table) != 0){
1933                 // key at index -2 and value at index -1
1934                 luaL_checktype(L, -1, LUA_TFUNCTION);
1935                 // Call function
1936                 lua_pushnumber(L, dtime);
1937                 if(lua_pcall(L, 1, 0, 0))
1938                         script_error(L, "error: %s\n", lua_tostring(L, -1));
1939                 // value removed, keep key for next iteration
1940         }
1941 }
1942
1943 void scriptapi_environment_on_placenode(lua_State *L, v3s16 p, MapNode newnode,
1944                 ServerActiveObject *placer)
1945 {
1946         realitycheck(L);
1947         assert(lua_checkstack(L, 20));
1948         //infostream<<"scriptapi_environment_on_placenode"<<std::endl;
1949         StackUnroller stack_unroller(L);
1950
1951         // Get server from registry
1952         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1953         Server *server = (Server*)lua_touserdata(L, -1);
1954         // And get the writable node definition manager from the server
1955         IWritableNodeDefManager *ndef =
1956                         server->getWritableNodeDefManager();
1957         
1958         // Get minetest.registered_on_placenodes
1959         lua_getglobal(L, "minetest");
1960         lua_getfield(L, -1, "registered_on_placenodes");
1961         luaL_checktype(L, -1, LUA_TTABLE);
1962         int table = lua_gettop(L);
1963         // Foreach
1964         lua_pushnil(L);
1965         while(lua_next(L, table) != 0){
1966                 // key at index -2 and value at index -1
1967                 luaL_checktype(L, -1, LUA_TFUNCTION);
1968                 // Call function
1969                 pushpos(L, p);
1970                 pushnode(L, newnode, ndef);
1971                 objectref_get_or_create(L, placer);
1972                 if(lua_pcall(L, 3, 0, 0))
1973                         script_error(L, "error: %s\n", lua_tostring(L, -1));
1974                 // value removed, keep key for next iteration
1975         }
1976 }
1977
1978 void scriptapi_environment_on_dignode(lua_State *L, v3s16 p, MapNode oldnode,
1979                 ServerActiveObject *digger)
1980 {
1981         realitycheck(L);
1982         assert(lua_checkstack(L, 20));
1983         //infostream<<"scriptapi_environment_on_dignode"<<std::endl;
1984         StackUnroller stack_unroller(L);
1985
1986         // Get server from registry
1987         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1988         Server *server = (Server*)lua_touserdata(L, -1);
1989         // And get the writable node definition manager from the server
1990         IWritableNodeDefManager *ndef =
1991                         server->getWritableNodeDefManager();
1992         
1993         // Get minetest.registered_on_dignodes
1994         lua_getglobal(L, "minetest");
1995         lua_getfield(L, -1, "registered_on_dignodes");
1996         luaL_checktype(L, -1, LUA_TTABLE);
1997         int table = lua_gettop(L);
1998         // Foreach
1999         lua_pushnil(L);
2000         while(lua_next(L, table) != 0){
2001                 // key at index -2 and value at index -1
2002                 luaL_checktype(L, -1, LUA_TFUNCTION);
2003                 // Call function
2004                 pushpos(L, p);
2005                 pushnode(L, oldnode, ndef);
2006                 objectref_get_or_create(L, digger);
2007                 if(lua_pcall(L, 3, 0, 0))
2008                         script_error(L, "error: %s\n", lua_tostring(L, -1));
2009                 // value removed, keep key for next iteration
2010         }
2011 }
2012
2013 void scriptapi_environment_on_punchnode(lua_State *L, v3s16 p, MapNode node,
2014                 ServerActiveObject *puncher)
2015 {
2016         realitycheck(L);
2017         assert(lua_checkstack(L, 20));
2018         //infostream<<"scriptapi_environment_on_punchnode"<<std::endl;
2019         StackUnroller stack_unroller(L);
2020
2021         // Get server from registry
2022         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
2023         Server *server = (Server*)lua_touserdata(L, -1);
2024         // And get the writable node definition manager from the server
2025         IWritableNodeDefManager *ndef =
2026                         server->getWritableNodeDefManager();
2027         
2028         // Get minetest.registered_on_punchnodes
2029         lua_getglobal(L, "minetest");
2030         lua_getfield(L, -1, "registered_on_punchnodes");
2031         luaL_checktype(L, -1, LUA_TTABLE);
2032         int table = lua_gettop(L);
2033         // Foreach
2034         lua_pushnil(L);
2035         while(lua_next(L, table) != 0){
2036                 // key at index -2 and value at index -1
2037                 luaL_checktype(L, -1, LUA_TFUNCTION);
2038                 // Call function
2039                 pushpos(L, p);
2040                 pushnode(L, node, ndef);
2041                 objectref_get_or_create(L, puncher);
2042                 if(lua_pcall(L, 3, 0, 0))
2043                         script_error(L, "error: %s\n", lua_tostring(L, -1));
2044                 // value removed, keep key for next iteration
2045         }
2046 }
2047
2048 void scriptapi_environment_on_generated(lua_State *L, v3s16 minp, v3s16 maxp)
2049 {
2050         realitycheck(L);
2051         assert(lua_checkstack(L, 20));
2052         //infostream<<"scriptapi_environment_on_generated"<<std::endl;
2053         StackUnroller stack_unroller(L);
2054
2055         // Get minetest.registered_on_generateds
2056         lua_getglobal(L, "minetest");
2057         lua_getfield(L, -1, "registered_on_generateds");
2058         luaL_checktype(L, -1, LUA_TTABLE);
2059         int table = lua_gettop(L);
2060         // Foreach
2061         lua_pushnil(L);
2062         while(lua_next(L, table) != 0){
2063                 // key at index -2 and value at index -1
2064                 luaL_checktype(L, -1, LUA_TFUNCTION);
2065                 // Call function
2066                 pushpos(L, minp);
2067                 pushpos(L, maxp);
2068                 if(lua_pcall(L, 2, 0, 0))
2069                         script_error(L, "error: %s\n", lua_tostring(L, -1));
2070                 // value removed, keep key for next iteration
2071         }
2072 }
2073
2074 /*
2075         luaentity
2076 */
2077
2078 bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
2079                 const std::string &staticdata)
2080 {
2081         realitycheck(L);
2082         assert(lua_checkstack(L, 20));
2083         infostream<<"scriptapi_luaentity_add: id="<<id<<" name=\""
2084                         <<name<<"\""<<std::endl;
2085         StackUnroller stack_unroller(L);
2086         
2087         // Get minetest.registered_entities[name]
2088         lua_getglobal(L, "minetest");
2089         lua_getfield(L, -1, "registered_entities");
2090         luaL_checktype(L, -1, LUA_TTABLE);
2091         lua_pushstring(L, name);
2092         lua_gettable(L, -2);
2093         // Should be a table, which we will use as a prototype
2094         //luaL_checktype(L, -1, LUA_TTABLE);
2095         if(lua_type(L, -1) != LUA_TTABLE){
2096                 errorstream<<"LuaEntity name \""<<name<<"\" not defined"<<std::endl;
2097                 return false;
2098         }
2099         int prototype_table = lua_gettop(L);
2100         //dump2(L, "prototype_table");
2101         
2102         // Create entity object
2103         lua_newtable(L);
2104         int object = lua_gettop(L);
2105
2106         // Set object metatable
2107         lua_pushvalue(L, prototype_table);
2108         lua_setmetatable(L, -2);
2109         
2110         // Add object reference
2111         // This should be userdata with metatable ObjectRef
2112         objectref_get(L, id);
2113         luaL_checktype(L, -1, LUA_TUSERDATA);
2114         if(!luaL_checkudata(L, -1, "ObjectRef"))
2115                 luaL_typerror(L, -1, "ObjectRef");
2116         lua_setfield(L, -2, "object");
2117
2118         // minetest.luaentities[id] = object
2119         lua_getglobal(L, "minetest");
2120         lua_getfield(L, -1, "luaentities");
2121         luaL_checktype(L, -1, LUA_TTABLE);
2122         lua_pushnumber(L, id); // Push id
2123         lua_pushvalue(L, object); // Copy object to top of stack
2124         lua_settable(L, -3);
2125         
2126         // Get on_activate function
2127         lua_pushvalue(L, object);
2128         lua_getfield(L, -1, "on_activate");
2129         if(!lua_isnil(L, -1)){
2130                 luaL_checktype(L, -1, LUA_TFUNCTION);
2131                 lua_pushvalue(L, object); // self
2132                 lua_pushlstring(L, staticdata.c_str(), staticdata.size());
2133                 // Call with 2 arguments, 0 results
2134                 if(lua_pcall(L, 2, 0, 0))
2135                         script_error(L, "error running function %s:on_activate: %s\n",
2136                                         name, lua_tostring(L, -1));
2137         }
2138         
2139         return true;
2140 }
2141
2142 void scriptapi_luaentity_rm(lua_State *L, u16 id)
2143 {
2144         realitycheck(L);
2145         assert(lua_checkstack(L, 20));
2146         infostream<<"scriptapi_luaentity_rm: id="<<id<<std::endl;
2147
2148         // Get minetest.luaentities table
2149         lua_getglobal(L, "minetest");
2150         lua_getfield(L, -1, "luaentities");
2151         luaL_checktype(L, -1, LUA_TTABLE);
2152         int objectstable = lua_gettop(L);
2153         
2154         // Set luaentities[id] = nil
2155         lua_pushnumber(L, id); // Push id
2156         lua_pushnil(L);
2157         lua_settable(L, objectstable);
2158         
2159         lua_pop(L, 2); // pop luaentities, minetest
2160 }
2161
2162 std::string scriptapi_luaentity_get_staticdata(lua_State *L, u16 id)
2163 {
2164         realitycheck(L);
2165         assert(lua_checkstack(L, 20));
2166         infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl;
2167         StackUnroller stack_unroller(L);
2168
2169         // Get minetest.luaentities[id]
2170         luaentity_get(L, id);
2171         int object = lua_gettop(L);
2172         
2173         // Get get_staticdata function
2174         lua_pushvalue(L, object);
2175         lua_getfield(L, -1, "get_staticdata");
2176         if(lua_isnil(L, -1))
2177                 return "";
2178         
2179         luaL_checktype(L, -1, LUA_TFUNCTION);
2180         lua_pushvalue(L, object); // self
2181         // Call with 1 arguments, 1 results
2182         if(lua_pcall(L, 1, 1, 0))
2183                 script_error(L, "error running function get_staticdata: %s\n",
2184                                 lua_tostring(L, -1));
2185         
2186         size_t len=0;
2187         const char *s = lua_tolstring(L, -1, &len);
2188         return std::string(s, len);
2189 }
2190
2191 void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
2192                 LuaEntityProperties *prop)
2193 {
2194         realitycheck(L);
2195         assert(lua_checkstack(L, 20));
2196         infostream<<"scriptapi_luaentity_get_properties: id="<<id<<std::endl;
2197         StackUnroller stack_unroller(L);
2198
2199         // Get minetest.luaentities[id]
2200         luaentity_get(L, id);
2201         //int object = lua_gettop(L);
2202
2203         /* Read stuff */
2204         
2205         getboolfield(L, -1, "physical", prop->physical);
2206
2207         getfloatfield(L, -1, "weight", prop->weight);
2208
2209         lua_getfield(L, -1, "collisionbox");
2210         if(lua_istable(L, -1))
2211                 prop->collisionbox = read_aabbox3df32(L, -1, 1.0);
2212         lua_pop(L, 1);
2213
2214         getstringfield(L, -1, "visual", prop->visual);
2215         
2216         lua_getfield(L, -1, "visual_size");
2217         if(lua_istable(L, -1))
2218                 prop->visual_size = read_v2f(L, -1);
2219         lua_pop(L, 1);
2220
2221         lua_getfield(L, -1, "textures");
2222         if(lua_istable(L, -1)){
2223                 prop->textures.clear();
2224                 int table = lua_gettop(L);
2225                 lua_pushnil(L);
2226                 while(lua_next(L, table) != 0){
2227                         // key at index -2 and value at index -1
2228                         if(lua_isstring(L, -1))
2229                                 prop->textures.push_back(lua_tostring(L, -1));
2230                         else
2231                                 prop->textures.push_back("");
2232                         // removes value, keeps key for next iteration
2233                         lua_pop(L, 1);
2234                 }
2235         }
2236         lua_pop(L, 1);
2237         
2238         lua_getfield(L, -1, "spritediv");
2239         if(lua_istable(L, -1))
2240                 prop->spritediv = read_v2s16(L, -1);
2241         lua_pop(L, 1);
2242
2243         lua_getfield(L, -1, "initial_sprite_basepos");
2244         if(lua_istable(L, -1))
2245                 prop->initial_sprite_basepos = read_v2s16(L, -1);
2246         lua_pop(L, 1);
2247 }
2248
2249 void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime)
2250 {
2251         realitycheck(L);
2252         assert(lua_checkstack(L, 20));
2253         //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
2254         StackUnroller stack_unroller(L);
2255
2256         // Get minetest.luaentities[id]
2257         luaentity_get(L, id);
2258         int object = lua_gettop(L);
2259         // State: object is at top of stack
2260         // Get step function
2261         lua_getfield(L, -1, "on_step");
2262         if(lua_isnil(L, -1))
2263                 return;
2264         luaL_checktype(L, -1, LUA_TFUNCTION);
2265         lua_pushvalue(L, object); // self
2266         lua_pushnumber(L, dtime); // dtime
2267         // Call with 2 arguments, 0 results
2268         if(lua_pcall(L, 2, 0, 0))
2269                 script_error(L, "error running function 'on_step': %s\n", lua_tostring(L, -1));
2270 }
2271
2272 // Calls entity:on_punch(ObjectRef puncher)
2273 void scriptapi_luaentity_punch(lua_State *L, u16 id,
2274                 ServerActiveObject *puncher)
2275 {
2276         realitycheck(L);
2277         assert(lua_checkstack(L, 20));
2278         //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
2279         StackUnroller stack_unroller(L);
2280
2281         // Get minetest.luaentities[id]
2282         luaentity_get(L, id);
2283         int object = lua_gettop(L);
2284         // State: object is at top of stack
2285         // Get function
2286         lua_getfield(L, -1, "on_punch");
2287         if(lua_isnil(L, -1))
2288                 return;
2289         luaL_checktype(L, -1, LUA_TFUNCTION);
2290         lua_pushvalue(L, object); // self
2291         objectref_get_or_create(L, puncher); // Clicker reference
2292         // Call with 2 arguments, 0 results
2293         if(lua_pcall(L, 2, 0, 0))
2294                 script_error(L, "error running function 'on_punch': %s\n", lua_tostring(L, -1));
2295 }
2296
2297 // Calls entity:on_rightclick(ObjectRef clicker)
2298 void scriptapi_luaentity_rightclick(lua_State *L, u16 id,
2299                 ServerActiveObject *clicker)
2300 {
2301         realitycheck(L);
2302         assert(lua_checkstack(L, 20));
2303         //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
2304         StackUnroller stack_unroller(L);
2305
2306         // Get minetest.luaentities[id]
2307         luaentity_get(L, id);
2308         int object = lua_gettop(L);
2309         // State: object is at top of stack
2310         // Get function
2311         lua_getfield(L, -1, "on_rightclick");
2312         if(lua_isnil(L, -1))
2313                 return;
2314         luaL_checktype(L, -1, LUA_TFUNCTION);
2315         lua_pushvalue(L, object); // self
2316         objectref_get_or_create(L, clicker); // Clicker reference
2317         // Call with 2 arguments, 0 results
2318         if(lua_pcall(L, 2, 0, 0))
2319                 script_error(L, "error running function 'on_rightclick': %s\n", lua_tostring(L, -1));
2320 }
2321