]> git.lizzy.rs Git - minetest.git/blob - src/scriptapi.cpp
Duplicate last tile image automatically to all for lua node definitions
[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
42 /*
43 TODO:
44 - Node definition
45 - Random node triggers (like grass growth)
46 - Deterministic node triggers (like falling sand)
47 - Object visual client-side stuff
48         - Blink effect
49         - Spritesheets and animation
50 - LuaNodeMetadata
51         blockdef.metadata_name =
52                 ""
53                 "sign"
54                 "furnace"
55                 "chest"
56                 "locked_chest"
57                 "lua"
58         - Stores an inventory and stuff in a Settings object
59         meta.inventory_add_list("main")
60         blockdef.on_inventory_modified
61         meta.set("owner", playername)
62         meta.get("owner")
63 - Item definition (actually, only CraftItem)
64 - (not scripting) Putting items in node metadata (virtual)
65 */
66
67 static void stackDump(lua_State *L, std::ostream &o)
68 {
69   int i;
70   int top = lua_gettop(L);
71   for (i = 1; i <= top; i++) {  /* repeat for each level */
72         int t = lua_type(L, i);
73         switch (t) {
74
75           case LUA_TSTRING:  /* strings */
76                 o<<"\""<<lua_tostring(L, i)<<"\"";
77                 break;
78
79           case LUA_TBOOLEAN:  /* booleans */
80                 o<<(lua_toboolean(L, i) ? "true" : "false");
81                 break;
82
83           case LUA_TNUMBER:  /* numbers */ {
84                 char buf[10];
85                 snprintf(buf, 10, "%g", lua_tonumber(L, i));
86                 o<<buf;
87                 break; }
88
89           default:  /* other values */
90                 o<<lua_typename(L, t);
91                 break;
92
93         }
94         o<<" ";
95   }
96   o<<std::endl;
97 }
98
99 static void realitycheck(lua_State *L)
100 {
101         int top = lua_gettop(L);
102         if(top >= 30){
103                 dstream<<"Stack is over 30:"<<std::endl;
104                 stackDump(L, dstream);
105                 script_error(L, "Stack is over 30 (reality check)");
106         }
107 }
108
109 class StackUnroller
110 {
111 private:
112         lua_State *m_lua;
113         int m_original_top;
114 public:
115         StackUnroller(lua_State *L):
116                 m_lua(L),
117                 m_original_top(-1)
118         {
119                 m_original_top = lua_gettop(m_lua); // store stack height
120         }
121         ~StackUnroller()
122         {
123                 lua_settop(m_lua, m_original_top); // restore stack height
124         }
125 };
126
127 static v3f readFloatPos(lua_State *L, int index)
128 {
129         v3f pos;
130         luaL_checktype(L, index, LUA_TTABLE);
131         lua_getfield(L, index, "x");
132         pos.X = lua_tonumber(L, -1);
133         lua_pop(L, 1);
134         lua_getfield(L, index, "y");
135         pos.Y = lua_tonumber(L, -1);
136         lua_pop(L, 1);
137         lua_getfield(L, index, "z");
138         pos.Z = lua_tonumber(L, -1);
139         lua_pop(L, 1);
140         pos *= BS; // Scale to internal format
141         return pos;
142 }
143
144 static void pushpos(lua_State *L, v3s16 p)
145 {
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 v3s16 readpos(lua_State *L, int index)
156 {
157         // Correct rounding at <0
158         v3f pf = readFloatPos(L, index);
159         return floatToInt(pf, BS);
160 }
161
162 static void pushnode(lua_State *L, const MapNode &n, INodeDefManager *ndef)
163 {
164         lua_newtable(L);
165         lua_pushstring(L, ndef->get(n).name.c_str());
166         lua_setfield(L, -2, "name");
167         lua_pushnumber(L, n.getParam1());
168         lua_setfield(L, -2, "param1");
169         lua_pushnumber(L, n.getParam2());
170         lua_setfield(L, -2, "param2");
171 }
172
173 static MapNode readnode(lua_State *L, int index, INodeDefManager *ndef)
174 {
175         lua_getfield(L, index, "name");
176         const char *name = lua_tostring(L, -1);
177         lua_pop(L, 1);
178         u8 param1;
179         lua_getfield(L, index, "param1");
180         if(lua_isnil(L, -1))
181                 param1 = 0;
182         else
183                 param1 = lua_tonumber(L, -1);
184         lua_pop(L, 1);
185         u8 param2;
186         lua_getfield(L, index, "param2");
187         if(lua_isnil(L, -1))
188                 param2 = 0;
189         else
190                 param2 = lua_tonumber(L, -1);
191         lua_pop(L, 1);
192         return MapNode(ndef, name, param1, param2);
193 }
194
195 static video::SColor readARGB8(lua_State *L, int index)
196 {
197         video::SColor color;
198         luaL_checktype(L, index, LUA_TTABLE);
199         lua_getfield(L, index, "a");
200         if(lua_isnumber(L, -1))
201                 color.setAlpha(lua_tonumber(L, -1));
202         lua_pop(L, 1);
203         lua_getfield(L, index, "r");
204         color.setRed(lua_tonumber(L, -1));
205         lua_pop(L, 1);
206         lua_getfield(L, index, "g");
207         color.setGreen(lua_tonumber(L, -1));
208         lua_pop(L, 1);
209         lua_getfield(L, index, "b");
210         color.setBlue(lua_tonumber(L, -1));
211         lua_pop(L, 1);
212         return color;
213 }
214
215 static core::aabbox3d<f32> read_aabbox3df32(lua_State *L, int index)
216 {
217         core::aabbox3d<f32> box;
218         if(lua_istable(L, -1)){
219                 lua_rawgeti(L, -1, 1);
220                 box.MinEdge.X = lua_tonumber(L, -1);
221                 lua_pop(L, 1);
222                 lua_rawgeti(L, -1, 2);
223                 box.MinEdge.Y = lua_tonumber(L, -1);
224                 lua_pop(L, 1);
225                 lua_rawgeti(L, -1, 3);
226                 box.MinEdge.Z = lua_tonumber(L, -1);
227                 lua_pop(L, 1);
228                 lua_rawgeti(L, -1, 4);
229                 box.MaxEdge.X = lua_tonumber(L, -1);
230                 lua_pop(L, 1);
231                 lua_rawgeti(L, -1, 5);
232                 box.MaxEdge.Y = lua_tonumber(L, -1);
233                 lua_pop(L, 1);
234                 lua_rawgeti(L, -1, 6);
235                 box.MaxEdge.Z = lua_tonumber(L, -1);
236                 lua_pop(L, 1);
237         }
238         return box;
239 }
240
241 static bool getstringfield(lua_State *L, int table,
242                 const char *fieldname, std::string &result)
243 {
244         lua_getfield(L, table, fieldname);
245         bool got = false;
246         if(lua_isstring(L, -1)){
247                 result = lua_tostring(L, -1);
248                 got = true;
249         }
250         lua_pop(L, 1);
251         return got;
252 }
253
254 static bool getintfield(lua_State *L, int table,
255                 const char *fieldname, int &result)
256 {
257         lua_getfield(L, table, fieldname);
258         bool got = false;
259         if(lua_isnumber(L, -1)){
260                 result = lua_tonumber(L, -1);
261                 got = true;
262         }
263         lua_pop(L, 1);
264         return got;
265 }
266
267 static bool getfloatfield(lua_State *L, int table,
268                 const char *fieldname, float &result)
269 {
270         lua_getfield(L, table, fieldname);
271         bool got = false;
272         if(lua_isnumber(L, -1)){
273                 result = lua_tonumber(L, -1);
274                 got = true;
275         }
276         lua_pop(L, 1);
277         return got;
278 }
279
280 static bool getboolfield(lua_State *L, int table,
281                 const char *fieldname, bool &result)
282 {
283         lua_getfield(L, table, fieldname);
284         bool got = false;
285         if(lua_isboolean(L, -1)){
286                 result = lua_toboolean(L, -1);
287                 got = true;
288         }
289         lua_pop(L, 1);
290         return got;
291 }
292
293 static std::string getstringfield_default(lua_State *L, int table,
294                 const char *fieldname, const std::string &default_)
295 {
296         std::string result = default_;
297         getstringfield(L, table, fieldname, result);
298         return result;
299 }
300
301 static int getintfield_default(lua_State *L, int table,
302                 const char *fieldname, int default_)
303 {
304         int result = default_;
305         getintfield(L, table, fieldname, result);
306         return result;
307 }
308
309 static bool getboolfield_default(lua_State *L, int table,
310                 const char *fieldname, bool default_)
311 {
312         bool result = default_;
313         getboolfield(L, table, fieldname, result);
314         return result;
315 }
316
317 struct EnumString
318 {
319         int num;
320         const char *str;
321 };
322
323 static bool string_to_enum(const EnumString *spec, int &result,
324                 const std::string &str)
325 {
326         const EnumString *esp = spec;
327         while(esp->str){
328                 if(str == std::string(esp->str)){
329                         result = esp->num;
330                         return true;
331                 }
332                 esp++;
333         }
334         return false;
335 }
336
337 /*static bool enum_to_string(const EnumString *spec, std::string &result,
338                 int num)
339 {
340         const EnumString *esp = spec;
341         while(esp){
342                 if(num == esp->num){
343                         result = esp->str;
344                         return true;
345                 }
346                 esp++;
347         }
348         return false;
349 }*/
350
351 static int getenumfield(lua_State *L, int table,
352                 const char *fieldname, const EnumString *spec, int default_)
353 {
354         int result = default_;
355         string_to_enum(spec, result,
356                         getstringfield_default(L, table, fieldname, ""));
357         return result;
358 }
359
360 struct EnumString es_DrawType[] =
361 {
362         {NDT_NORMAL, "normal"},
363         {NDT_AIRLIKE, "airlike"},
364         {NDT_LIQUID, "liquid"},
365         {NDT_FLOWINGLIQUID, "flowingliquid"},
366         {NDT_GLASSLIKE, "glasslike"},
367         {NDT_ALLFACES, "allfaces"},
368         {NDT_ALLFACES_OPTIONAL, "allfaces_optional"},
369         {NDT_TORCHLIKE, "torchlike"},
370         {NDT_SIGNLIKE, "signlike"},
371         {NDT_PLANTLIKE, "plantlike"},
372         {NDT_FENCELIKE, "fencelike"},
373         {NDT_RAILLIKE, "raillike"},
374         {0, NULL},
375 };
376
377 struct EnumString es_ContentParamType[] =
378 {
379         {CPT_NONE, "none"},
380         {CPT_LIGHT, "light"},
381         {CPT_MINERAL, "mineral"},
382         {CPT_FACEDIR_SIMPLE, "facedir_simple"},
383 };
384
385 struct EnumString es_LiquidType[] =
386 {
387         {LIQUID_NONE, "none"},
388         {LIQUID_FLOWING, "flowing"},
389         {LIQUID_SOURCE, "source"},
390 };
391
392 struct EnumString es_NodeBoxType[] =
393 {
394         {NODEBOX_REGULAR, "regular"},
395         {NODEBOX_FIXED, "fixed"},
396         {NODEBOX_WALLMOUNTED, "wallmounted"},
397 };
398
399 struct EnumString es_Diggability[] =
400 {
401         {DIGGABLE_NOT, "not"},
402         {DIGGABLE_NORMAL, "normal"},
403         {DIGGABLE_CONSTANT, "constant"},
404 };
405
406 /*
407         Global functions
408 */
409
410 // Register new object prototype
411 // register_entity(name, prototype)
412 static int l_register_entity(lua_State *L)
413 {
414         const char *name = luaL_checkstring(L, 1);
415         infostream<<"register_entity: "<<name<<std::endl;
416         luaL_checktype(L, 2, LUA_TTABLE);
417
418         // Get minetest.registered_entities
419         lua_getglobal(L, "minetest");
420         lua_getfield(L, -1, "registered_entities");
421         luaL_checktype(L, -1, LUA_TTABLE);
422         int registered_entities = lua_gettop(L);
423         lua_pushvalue(L, 2); // Object = param 2 -> stack top
424         // registered_entities[name] = object
425         lua_setfield(L, registered_entities, name);
426         
427         // Get registered object to top of stack
428         lua_pushvalue(L, 2);
429         
430         // Set __index to point to itself
431         lua_pushvalue(L, -1);
432         lua_setfield(L, -2, "__index");
433
434         // Set metatable.__index = metatable
435         luaL_getmetatable(L, "minetest.entity");
436         lua_pushvalue(L, -1); // duplicate metatable
437         lua_setfield(L, -2, "__index");
438         // Set object metatable
439         lua_setmetatable(L, -2);
440
441         return 0; /* number of results */
442 }
443
444 // register_tool(name, {lots of stuff})
445 static int l_register_tool(lua_State *L)
446 {
447         const char *name = luaL_checkstring(L, 1);
448         infostream<<"register_tool: "<<name<<std::endl;
449         luaL_checktype(L, 2, LUA_TTABLE);
450         int table = 2;
451
452         // Get server from registry
453         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
454         Server *server = (Server*)lua_touserdata(L, -1);
455         // And get the writable tool definition manager from the server
456         IWritableToolDefManager *tooldef =
457                         server->getWritableToolDefManager();
458         
459         ToolDefinition def;
460         
461         getstringfield(L, table, "image", def.imagename);
462         getfloatfield(L, table, "basetime", def.properties.basetime);
463         getfloatfield(L, table, "dt_weight", def.properties.dt_weight);
464         getfloatfield(L, table, "dt_crackiness", def.properties.dt_crackiness);
465         getfloatfield(L, table, "dt_crumbliness", def.properties.dt_crumbliness);
466         getfloatfield(L, table, "dt_cuttability", def.properties.dt_cuttability);
467         getfloatfield(L, table, "basedurability", def.properties.basedurability);
468         getfloatfield(L, table, "dd_weight", def.properties.dd_weight);
469         getfloatfield(L, table, "dd_crackiness", def.properties.dd_crackiness);
470         getfloatfield(L, table, "dd_crumbliness", def.properties.dd_crumbliness);
471         getfloatfield(L, table, "dd_cuttability", def.properties.dd_cuttability);
472
473         tooldef->registerTool(name, def);
474         return 0; /* number of results */
475 }
476
477 // register_node(name, {lots of stuff})
478 static int l_register_node(lua_State *L)
479 {
480         const char *name = luaL_checkstring(L, 1);
481         infostream<<"register_node: "<<name<<std::endl;
482         luaL_checktype(L, 2, LUA_TTABLE);
483         int table0 = 2;
484
485         // Get server from registry
486         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
487         Server *server = (Server*)lua_touserdata(L, -1);
488         // And get the writable node definition manager from the server
489         IWritableNodeDefManager *nodedef =
490                         server->getWritableNodeDefManager();
491
492         /*
493                 Create definition
494         */
495         
496         ContentFeatures f;
497
498         // Default to getting the corresponding NodeItem when dug
499         f.dug_item = std::string("NodeItem \"")+name+"\" 1";
500
501         /*
502                 Read definiton from Lua
503         */
504
505         f.name = name;
506         
507         /* Visual definition */
508
509         f.drawtype = (NodeDrawType)getenumfield(L, table0, "drawtype", es_DrawType,
510                         NDT_NORMAL);
511         getfloatfield(L, table0, "visual_scale", f.visual_scale);
512
513         lua_getfield(L, table0, "tile_images");
514         if(lua_istable(L, -1)){
515                 int table = lua_gettop(L);
516                 lua_pushnil(L);
517                 int i = 0;
518                 while(lua_next(L, table) != 0){
519                         // key at index -2 and value at index -1
520                         if(lua_isstring(L, -1))
521                                 f.tname_tiles[i] = lua_tostring(L, -1);
522                         else
523                                 f.tname_tiles[i] = "";
524                         // removes value, keeps key for next iteration
525                         lua_pop(L, 1);
526                         i++;
527                         if(i==6){
528                                 lua_pop(L, 1);
529                                 break;
530                         }
531                 }
532                 // Copy last value to all remaining textures
533                 if(i >= 1){
534                         std::string lastname = f.tname_tiles[i-1];
535                         while(i < 6){
536                                 f.tname_tiles[i] = lastname;
537                                 i++;
538                         }
539                 }
540         }
541         lua_pop(L, 1);
542
543         getstringfield(L, table0, "inventory_image", f.tname_inventory);
544
545         lua_getfield(L, table0, "special_materials");
546         if(lua_istable(L, -1)){
547                 int table = lua_gettop(L);
548                 lua_pushnil(L);
549                 int i = 0;
550                 while(lua_next(L, table) != 0){
551                         // key at index -2 and value at index -1
552                         int smtable = lua_gettop(L);
553                         std::string tname = getstringfield_default(
554                                         L, smtable, "image", "");
555                         bool backface_culling = getboolfield_default(
556                                         L, smtable, "backface_culling", true);
557                         MaterialSpec mspec(tname, backface_culling);
558                         f.setSpecialMaterial(i, mspec);
559                         // removes value, keeps key for next iteration
560                         lua_pop(L, 1);
561                         i++;
562                         if(i==6){
563                                 lua_pop(L, 1);
564                                 break;
565                         }
566                 }
567         }
568         lua_pop(L, 1);
569
570         f.alpha = getintfield_default(L, table0, "alpha", 255);
571
572         /* Other stuff */
573         
574         lua_getfield(L, table0, "post_effect_color");
575         if(!lua_isnil(L, -1))
576                 f.post_effect_color = readARGB8(L, -1);
577         lua_pop(L, 1);
578
579         f.param_type = (ContentParamType)getenumfield(L, table0, "paramtype",
580                         es_ContentParamType, CPT_NONE);
581         
582         // True for all ground-like things like stone and mud, false for eg. trees
583         getboolfield(L, table0, "is_ground_content", f.is_ground_content);
584         getboolfield(L, table0, "light_propagates", f.light_propagates);
585         getboolfield(L, table0, "sunlight_propagates", f.sunlight_propagates);
586         // This is used for collision detection.
587         // Also for general solidness queries.
588         getboolfield(L, table0, "walkable", f.walkable);
589         // Player can point to these
590         getboolfield(L, table0, "pointable", f.pointable);
591         // Player can dig these
592         getboolfield(L, table0, "diggable", f.diggable);
593         // Player can climb these
594         getboolfield(L, table0, "climbable", f.climbable);
595         // Player can build on these
596         getboolfield(L, table0, "buildable_to", f.buildable_to);
597         // If true, param2 is set to direction when placed. Used for torches.
598         // NOTE: the direction format is quite inefficient and should be changed
599         getboolfield(L, table0, "wall_mounted", f.wall_mounted);
600         // If true, node is equivalent to air. Torches are, air is. Water is not.
601         // Is used for example to check whether a mud block can have grass on.
602         getboolfield(L, table0, "air_equivalent", f.air_equivalent);
603         // Whether this content type often contains mineral.
604         // Used for texture atlas creation.
605         // Currently only enabled for CONTENT_STONE.
606         getboolfield(L, table0, "often_contains_mineral", f.often_contains_mineral);
607         // Inventory item string as which the node appears in inventory when dug.
608         // Mineral overrides this.
609         getstringfield(L, table0, "dug_item", f.dug_item);
610         // Extra dug item and its rarity
611         getstringfield(L, table0, "extra_dug_item", f.extra_dug_item);
612         // Usual get interval for extra dug item
613         getintfield(L, table0, "extra_dug_item_rarity", f.extra_dug_item_rarity);
614         // Metadata name of node (eg. "furnace")
615         getstringfield(L, table0, "metadata_name", f.metadata_name);
616         // Whether the node is non-liquid, source liquid or flowing liquid
617         f.liquid_type = (LiquidType)getenumfield(L, table0, "liquidtype",
618                         es_LiquidType, LIQUID_NONE);
619         // If the content is liquid, this is the flowing version of the liquid.
620         getstringfield(L, table0, "liquid_alternative_flowing",
621                         f.liquid_alternative_flowing);
622         // If the content is liquid, this is the source version of the liquid.
623         getstringfield(L, table0, "liquid_alternative_source",
624                         f.liquid_alternative_source);
625         // Viscosity for fluid flow, ranging from 1 to 7, with
626         // 1 giving almost instantaneous propagation and 7 being
627         // the slowest possible
628         f.liquid_viscosity = getintfield_default(L, table0,
629                         "liquid_viscosity", f.liquid_viscosity);
630         // Amount of light the node emits
631         f.light_source = getintfield_default(L, table0,
632                         "light_source", f.light_source);
633         f.damage_per_second = getintfield_default(L, table0,
634                         "damage_per_second", f.damage_per_second);
635         
636         lua_getfield(L, table0, "selection_box");
637         if(lua_istable(L, -1)){
638                 f.selection_box.type = (NodeBoxType)getenumfield(L, -1, "type",
639                                 es_NodeBoxType, NODEBOX_REGULAR);
640
641                 lua_getfield(L, -1, "fixed");
642                 if(lua_istable(L, -1))
643                         f.selection_box.fixed = read_aabbox3df32(L, -1);
644                 lua_pop(L, 1);
645
646                 lua_getfield(L, -1, "wall_top");
647                 if(lua_istable(L, -1))
648                         f.selection_box.wall_top = read_aabbox3df32(L, -1);
649                 lua_pop(L, 1);
650
651                 lua_getfield(L, -1, "wall_bottom");
652                 if(lua_istable(L, -1))
653                         f.selection_box.wall_bottom = read_aabbox3df32(L, -1);
654                 lua_pop(L, 1);
655
656                 lua_getfield(L, -1, "wall_side");
657                 if(lua_istable(L, -1))
658                         f.selection_box.wall_side = read_aabbox3df32(L, -1);
659                 lua_pop(L, 1);
660         }
661         lua_pop(L, 1);
662
663         lua_getfield(L, table0, "material");
664         if(lua_istable(L, -1)){
665                 f.material.diggability = (Diggability)getenumfield(L, -1, "diggability",
666                                 es_Diggability, DIGGABLE_NORMAL);
667                 
668                 getfloatfield(L, -1, "constant_time", f.material.constant_time);
669                 getfloatfield(L, -1, "weight", f.material.weight);
670                 getfloatfield(L, -1, "crackiness", f.material.crackiness);
671                 getfloatfield(L, -1, "crumbliness", f.material.crumbliness);
672                 getfloatfield(L, -1, "cuttability", f.material.cuttability);
673                 getfloatfield(L, -1, "flammability", f.material.flammability);
674         }
675         lua_pop(L, 1);
676
677         getstringfield(L, table0, "cookresult_item", f.cookresult_item);
678         getfloatfield(L, table0, "furnace_cooktime", f.furnace_cooktime);
679         getfloatfield(L, table0, "furnace_burntime", f.furnace_burntime);
680         
681         /*
682                 Register it
683         */
684         
685         nodedef->set(name, f);
686         
687         return 0; /* number of results */
688 }
689
690 // register_craft({output=item, recipe={{item00,item10},{item01,item11}})
691 static int l_register_craft(lua_State *L)
692 {
693         infostream<<"register_craft"<<std::endl;
694         luaL_checktype(L, 1, LUA_TTABLE);
695         int table0 = 1;
696
697         // Get server from registry
698         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
699         Server *server = (Server*)lua_touserdata(L, -1);
700         // And get the writable craft definition manager from the server
701         IWritableCraftDefManager *craftdef =
702                         server->getWritableCraftDefManager();
703         
704         std::string output;
705         int width = 0;
706         std::vector<std::string> input;
707
708         lua_getfield(L, table0, "output");
709         luaL_checktype(L, -1, LUA_TSTRING);
710         if(lua_isstring(L, -1))
711                 output = lua_tostring(L, -1);
712         lua_pop(L, 1);
713
714         lua_getfield(L, table0, "recipe");
715         luaL_checktype(L, -1, LUA_TTABLE);
716         if(lua_istable(L, -1)){
717                 int table1 = lua_gettop(L);
718                 lua_pushnil(L);
719                 int rowcount = 0;
720                 while(lua_next(L, table1) != 0){
721                         int colcount = 0;
722                         // key at index -2 and value at index -1
723                         luaL_checktype(L, -1, LUA_TTABLE);
724                         if(lua_istable(L, -1)){
725                                 int table2 = lua_gettop(L);
726                                 lua_pushnil(L);
727                                 while(lua_next(L, table2) != 0){
728                                         // key at index -2 and value at index -1
729                                         luaL_checktype(L, -1, LUA_TSTRING);
730                                         input.push_back(lua_tostring(L, -1));
731                                         // removes value, keeps key for next iteration
732                                         lua_pop(L, 1);
733                                         colcount++;
734                                 }
735                         }
736                         if(rowcount == 0){
737                                 width = colcount;
738                         } else {
739                                 if(colcount != width){
740                                         script_error(L, "error: %s\n", "Invalid crafting recipe");
741                                 }
742                         }
743                         // removes value, keeps key for next iteration
744                         lua_pop(L, 1);
745                         rowcount++;
746                 }
747         }
748         lua_pop(L, 1);
749
750         CraftDefinition def(output, width, input);
751         craftdef->registerCraft(def);
752
753         return 0; /* number of results */
754 }
755
756 static int register_lua_callback(lua_State *L, const char *tablename)
757 {
758         luaL_checktype(L, 1, LUA_TFUNCTION);
759
760         lua_getglobal(L, "table");
761         lua_getfield(L, -1, "insert");
762         int table_insert = lua_gettop(L);
763         // Get minetest.registered_globalsteps
764         lua_getglobal(L, "minetest");
765         lua_getfield(L, -1, tablename);
766         luaL_checktype(L, -1, LUA_TTABLE);
767         int registered = lua_gettop(L);
768         // table.insert(registered_globalsteps, func)
769         lua_pushvalue(L, table_insert);
770         lua_pushvalue(L, registered);
771         lua_pushvalue(L, 1); // push function from argument 1
772         // Call insert
773         if(lua_pcall(L, 2, 0, 0))
774                 script_error(L, "error: %s\n", lua_tostring(L, -1));
775
776         return 0; /* number of results */
777 }
778
779 // Register a global step function
780 // register_globalstep(function)
781 static int l_register_globalstep(lua_State *L)
782 {
783         infostream<<"register_globalstep"<<std::endl;
784         return register_lua_callback(L, "registered_globalsteps");
785 }
786
787 // register_on_placenode(function)
788 static int l_register_on_placenode(lua_State *L)
789 {
790         infostream<<"register_on_placenode"<<std::endl;
791         return register_lua_callback(L, "registered_on_placenodes");
792 }
793
794 // register_on_dignode(function)
795 static int l_register_on_dignode(lua_State *L)
796 {
797         infostream<<"register_on_dignode"<<std::endl;
798         return register_lua_callback(L, "registered_on_dignodes");
799 }
800
801 // register_on_punchnode(function)
802 static int l_register_on_punchnode(lua_State *L)
803 {
804         infostream<<"register_on_punchnode"<<std::endl;
805         return register_lua_callback(L, "registered_on_punchnodes");
806 }
807
808 static const struct luaL_Reg minetest_f [] = {
809         {"register_entity", l_register_entity},
810         {"register_tool", l_register_tool},
811         {"register_node", l_register_node},
812         {"register_craft", l_register_craft},
813         {"register_globalstep", l_register_globalstep},
814         {"register_on_placenode", l_register_on_placenode},
815         {"register_on_dignode", l_register_on_dignode},
816         {"register_on_punchnode", l_register_on_punchnode},
817         {NULL, NULL}
818 };
819
820 /*
821         LuaEntity functions
822 */
823
824 static const struct luaL_Reg minetest_entity_m [] = {
825         {NULL, NULL}
826 };
827
828 /*
829         Getters for stuff in main tables
830 */
831
832 static void objectref_get(lua_State *L, u16 id)
833 {
834         // Get minetest.object_refs[i]
835         lua_getglobal(L, "minetest");
836         lua_getfield(L, -1, "object_refs");
837         luaL_checktype(L, -1, LUA_TTABLE);
838         lua_pushnumber(L, id);
839         lua_gettable(L, -2);
840         lua_remove(L, -2); // object_refs
841         lua_remove(L, -2); // minetest
842 }
843
844 static void luaentity_get(lua_State *L, u16 id)
845 {
846         // Get minetest.luaentities[i]
847         lua_getglobal(L, "minetest");
848         lua_getfield(L, -1, "luaentities");
849         luaL_checktype(L, -1, LUA_TTABLE);
850         lua_pushnumber(L, id);
851         lua_gettable(L, -2);
852         lua_remove(L, -2); // luaentities
853         lua_remove(L, -2); // minetest
854 }
855
856 /*
857         Reference objects
858 */
859 #define method(class, name) {#name, class::l_##name}
860
861 class EnvRef
862 {
863 private:
864         ServerEnvironment *m_env;
865
866         static const char className[];
867         static const luaL_reg methods[];
868
869         static EnvRef *checkobject(lua_State *L, int narg)
870         {
871                 luaL_checktype(L, narg, LUA_TUSERDATA);
872                 void *ud = luaL_checkudata(L, narg, className);
873                 if(!ud) luaL_typerror(L, narg, className);
874                 return *(EnvRef**)ud;  // unbox pointer
875         }
876         
877         // Exported functions
878
879         // EnvRef:add_node(pos, node)
880         // pos = {x=num, y=num, z=num}
881         static int l_add_node(lua_State *L)
882         {
883                 infostream<<"EnvRef::l_add_node()"<<std::endl;
884                 EnvRef *o = checkobject(L, 1);
885                 ServerEnvironment *env = o->m_env;
886                 if(env == NULL) return 0;
887                 // pos
888                 v3s16 pos = readpos(L, 2);
889                 // content
890                 MapNode n = readnode(L, 3, env->getGameDef()->ndef());
891                 // Do it
892                 bool succeeded = env->getMap().addNodeWithEvent(pos, n);
893                 lua_pushboolean(L, succeeded);
894                 return 1;
895         }
896
897         // EnvRef:remove_node(pos)
898         // pos = {x=num, y=num, z=num}
899         static int l_remove_node(lua_State *L)
900         {
901                 infostream<<"EnvRef::l_remove_node()"<<std::endl;
902                 EnvRef *o = checkobject(L, 1);
903                 ServerEnvironment *env = o->m_env;
904                 if(env == NULL) return 0;
905                 // pos
906                 v3s16 pos = readpos(L, 2);
907                 // Do it
908                 bool succeeded = env->getMap().removeNodeWithEvent(pos);
909                 lua_pushboolean(L, succeeded);
910                 return 1;
911         }
912
913         // EnvRef:get_node(pos)
914         // pos = {x=num, y=num, z=num}
915         static int l_get_node(lua_State *L)
916         {
917                 infostream<<"EnvRef::l_get_node()"<<std::endl;
918                 EnvRef *o = checkobject(L, 1);
919                 ServerEnvironment *env = o->m_env;
920                 if(env == NULL) return 0;
921                 // pos
922                 v3s16 pos = readpos(L, 2);
923                 // Do it
924                 MapNode n = env->getMap().getNodeNoEx(pos);
925                 // Return node
926                 pushnode(L, n, env->getGameDef()->ndef());
927                 return 1;
928         }
929
930         // EnvRef:add_luaentity(pos, entityname)
931         // pos = {x=num, y=num, z=num}
932         static int l_add_luaentity(lua_State *L)
933         {
934                 infostream<<"EnvRef::l_add_luaentity()"<<std::endl;
935                 EnvRef *o = checkobject(L, 1);
936                 ServerEnvironment *env = o->m_env;
937                 if(env == NULL) return 0;
938                 // pos
939                 v3f pos = readFloatPos(L, 2);
940                 // content
941                 const char *name = lua_tostring(L, 3);
942                 // Do it
943                 ServerActiveObject *obj = new LuaEntitySAO(env, pos, name, "");
944                 env->addActiveObject(obj);
945                 return 0;
946         }
947
948         static int gc_object(lua_State *L) {
949                 EnvRef *o = *(EnvRef **)(lua_touserdata(L, 1));
950                 delete o;
951                 return 0;
952         }
953
954 public:
955         EnvRef(ServerEnvironment *env):
956                 m_env(env)
957         {
958                 infostream<<"EnvRef created"<<std::endl;
959         }
960
961         ~EnvRef()
962         {
963                 infostream<<"EnvRef destructing"<<std::endl;
964         }
965
966         // Creates an EnvRef and leaves it on top of stack
967         // Not callable from Lua; all references are created on the C side.
968         static void create(lua_State *L, ServerEnvironment *env)
969         {
970                 EnvRef *o = new EnvRef(env);
971                 //infostream<<"EnvRef::create: o="<<o<<std::endl;
972                 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
973                 luaL_getmetatable(L, className);
974                 lua_setmetatable(L, -2);
975         }
976
977         static void set_null(lua_State *L)
978         {
979                 EnvRef *o = checkobject(L, -1);
980                 o->m_env = NULL;
981         }
982         
983         static void Register(lua_State *L)
984         {
985                 lua_newtable(L);
986                 int methodtable = lua_gettop(L);
987                 luaL_newmetatable(L, className);
988                 int metatable = lua_gettop(L);
989
990                 lua_pushliteral(L, "__metatable");
991                 lua_pushvalue(L, methodtable);
992                 lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
993
994                 lua_pushliteral(L, "__index");
995                 lua_pushvalue(L, methodtable);
996                 lua_settable(L, metatable);
997
998                 lua_pushliteral(L, "__gc");
999                 lua_pushcfunction(L, gc_object);
1000                 lua_settable(L, metatable);
1001
1002                 lua_pop(L, 1);  // drop metatable
1003
1004                 luaL_openlib(L, 0, methods, 0);  // fill methodtable
1005                 lua_pop(L, 1);  // drop methodtable
1006
1007                 // Cannot be created from Lua
1008                 //lua_register(L, className, create_object);
1009         }
1010 };
1011 const char EnvRef::className[] = "EnvRef";
1012 const luaL_reg EnvRef::methods[] = {
1013         method(EnvRef, add_node),
1014         method(EnvRef, remove_node),
1015         method(EnvRef, get_node),
1016         method(EnvRef, add_luaentity),
1017         {0,0}
1018 };
1019
1020 class ObjectRef
1021 {
1022 private:
1023         ServerActiveObject *m_object;
1024
1025         static const char className[];
1026         static const luaL_reg methods[];
1027
1028         static ObjectRef *checkobject(lua_State *L, int narg)
1029         {
1030                 luaL_checktype(L, narg, LUA_TUSERDATA);
1031                 void *ud = luaL_checkudata(L, narg, className);
1032                 if(!ud) luaL_typerror(L, narg, className);
1033                 return *(ObjectRef**)ud;  // unbox pointer
1034         }
1035         
1036         static ServerActiveObject* getobject(ObjectRef *ref)
1037         {
1038                 ServerActiveObject *co = ref->m_object;
1039                 return co;
1040         }
1041         
1042         static LuaEntitySAO* getluaobject(ObjectRef *ref)
1043         {
1044                 ServerActiveObject *obj = getobject(ref);
1045                 if(obj == NULL)
1046                         return NULL;
1047                 if(obj->getType() != ACTIVEOBJECT_TYPE_LUAENTITY)
1048                         return NULL;
1049                 return (LuaEntitySAO*)obj;
1050         }
1051         
1052         // Exported functions
1053         
1054         // garbage collector
1055         static int gc_object(lua_State *L) {
1056                 ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
1057                 //infostream<<"ObjectRef::gc_object: o="<<o<<std::endl;
1058                 delete o;
1059                 return 0;
1060         }
1061
1062         // remove(self)
1063         static int l_remove(lua_State *L)
1064         {
1065                 ObjectRef *ref = checkobject(L, 1);
1066                 ServerActiveObject *co = getobject(ref);
1067                 if(co == NULL) return 0;
1068                 infostream<<"ObjectRef::l_remove(): id="<<co->getId()<<std::endl;
1069                 co->m_removed = true;
1070                 return 0;
1071         }
1072         
1073         // getpos(self)
1074         // returns: {x=num, y=num, z=num}
1075         static int l_getpos(lua_State *L)
1076         {
1077                 ObjectRef *ref = checkobject(L, 1);
1078                 ServerActiveObject *co = getobject(ref);
1079                 if(co == NULL) return 0;
1080                 v3f pos = co->getBasePosition() / BS;
1081                 lua_newtable(L);
1082                 lua_pushnumber(L, pos.X);
1083                 lua_setfield(L, -2, "x");
1084                 lua_pushnumber(L, pos.Y);
1085                 lua_setfield(L, -2, "y");
1086                 lua_pushnumber(L, pos.Z);
1087                 lua_setfield(L, -2, "z");
1088                 return 1;
1089         }
1090         
1091         // setpos(self, pos)
1092         static int l_setpos(lua_State *L)
1093         {
1094                 ObjectRef *ref = checkobject(L, 1);
1095                 //LuaEntitySAO *co = getluaobject(ref);
1096                 ServerActiveObject *co = getobject(ref);
1097                 if(co == NULL) return 0;
1098                 // pos
1099                 v3f pos = readFloatPos(L, 2);
1100                 // Do it
1101                 co->setPos(pos);
1102                 return 0;
1103         }
1104         
1105         // moveto(self, pos, continuous=false)
1106         static int l_moveto(lua_State *L)
1107         {
1108                 ObjectRef *ref = checkobject(L, 1);
1109                 //LuaEntitySAO *co = getluaobject(ref);
1110                 ServerActiveObject *co = getobject(ref);
1111                 if(co == NULL) return 0;
1112                 // pos
1113                 v3f pos = readFloatPos(L, 2);
1114                 // continuous
1115                 bool continuous = lua_toboolean(L, 3);
1116                 // Do it
1117                 co->moveTo(pos, continuous);
1118                 return 0;
1119         }
1120
1121         // setvelocity(self, velocity)
1122         static int l_setvelocity(lua_State *L)
1123         {
1124                 ObjectRef *ref = checkobject(L, 1);
1125                 LuaEntitySAO *co = getluaobject(ref);
1126                 if(co == NULL) return 0;
1127                 // pos
1128                 v3f pos = readFloatPos(L, 2);
1129                 // Do it
1130                 co->setVelocity(pos);
1131                 return 0;
1132         }
1133         
1134         // setacceleration(self, acceleration)
1135         static int l_setacceleration(lua_State *L)
1136         {
1137                 ObjectRef *ref = checkobject(L, 1);
1138                 LuaEntitySAO *co = getluaobject(ref);
1139                 if(co == NULL) return 0;
1140                 // pos
1141                 v3f pos = readFloatPos(L, 2);
1142                 // Do it
1143                 co->setAcceleration(pos);
1144                 return 0;
1145         }
1146         
1147         // add_to_inventory(self, itemstring)
1148         // returns: true if item was added, false otherwise
1149         static int l_add_to_inventory(lua_State *L)
1150         {
1151                 ObjectRef *ref = checkobject(L, 1);
1152                 luaL_checkstring(L, 2);
1153                 ServerActiveObject *co = getobject(ref);
1154                 if(co == NULL) return 0;
1155                 // itemstring
1156                 const char *itemstring = lua_tostring(L, 2);
1157                 infostream<<"ObjectRef::l_add_to_inventory(): id="<<co->getId()
1158                                 <<" itemstring=\""<<itemstring<<"\""<<std::endl;
1159                 // Do it
1160                 std::istringstream is(itemstring, std::ios::binary);
1161                 ServerEnvironment *env = co->getEnv();
1162                 assert(env);
1163                 IGameDef *gamedef = env->getGameDef();
1164                 InventoryItem *item = InventoryItem::deSerialize(is, gamedef);
1165                 infostream<<"item="<<env<<std::endl;
1166                 bool fits = co->addToInventory(item);
1167                 // Return
1168                 lua_pushboolean(L, fits);
1169                 return 1;
1170         }
1171
1172 public:
1173         ObjectRef(ServerActiveObject *object):
1174                 m_object(object)
1175         {
1176                 //infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
1177         }
1178
1179         ~ObjectRef()
1180         {
1181                 /*if(m_object)
1182                         infostream<<"ObjectRef destructing for id="
1183                                         <<m_object->getId()<<std::endl;
1184                 else
1185                         infostream<<"ObjectRef destructing for id=unknown"<<std::endl;*/
1186         }
1187
1188         // Creates an ObjectRef and leaves it on top of stack
1189         // Not callable from Lua; all references are created on the C side.
1190         static void create(lua_State *L, ServerActiveObject *object)
1191         {
1192                 ObjectRef *o = new ObjectRef(object);
1193                 //infostream<<"ObjectRef::create: o="<<o<<std::endl;
1194                 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1195                 luaL_getmetatable(L, className);
1196                 lua_setmetatable(L, -2);
1197         }
1198
1199         static void set_null(lua_State *L)
1200         {
1201                 ObjectRef *o = checkobject(L, -1);
1202                 o->m_object = NULL;
1203         }
1204         
1205         static void Register(lua_State *L)
1206         {
1207                 lua_newtable(L);
1208                 int methodtable = lua_gettop(L);
1209                 luaL_newmetatable(L, className);
1210                 int metatable = lua_gettop(L);
1211
1212                 lua_pushliteral(L, "__metatable");
1213                 lua_pushvalue(L, methodtable);
1214                 lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
1215
1216                 lua_pushliteral(L, "__index");
1217                 lua_pushvalue(L, methodtable);
1218                 lua_settable(L, metatable);
1219
1220                 lua_pushliteral(L, "__gc");
1221                 lua_pushcfunction(L, gc_object);
1222                 lua_settable(L, metatable);
1223
1224                 lua_pop(L, 1);  // drop metatable
1225
1226                 luaL_openlib(L, 0, methods, 0);  // fill methodtable
1227                 lua_pop(L, 1);  // drop methodtable
1228
1229                 // Cannot be created from Lua
1230                 //lua_register(L, className, create_object);
1231         }
1232 };
1233 const char ObjectRef::className[] = "ObjectRef";
1234 const luaL_reg ObjectRef::methods[] = {
1235         method(ObjectRef, remove),
1236         method(ObjectRef, getpos),
1237         method(ObjectRef, setpos),
1238         method(ObjectRef, moveto),
1239         method(ObjectRef, setvelocity),
1240         method(ObjectRef, setacceleration),
1241         method(ObjectRef, add_to_inventory),
1242         {0,0}
1243 };
1244
1245 // Creates a new anonymous reference if id=0
1246 static void objectref_get_or_create(lua_State *L,
1247                 ServerActiveObject *cobj)
1248 {
1249         if(cobj->getId() == 0){
1250                 ObjectRef::create(L, cobj);
1251         } else {
1252                 objectref_get(L, cobj->getId());
1253         }
1254 }
1255
1256 /*
1257         Main export function
1258 */
1259
1260 void scriptapi_export(lua_State *L, Server *server)
1261 {
1262         realitycheck(L);
1263         assert(lua_checkstack(L, 20));
1264         infostream<<"scriptapi_export"<<std::endl;
1265         StackUnroller stack_unroller(L);
1266
1267         // Store server as light userdata in registry
1268         lua_pushlightuserdata(L, server);
1269         lua_setfield(L, LUA_REGISTRYINDEX, "minetest_server");
1270         
1271         // Register global functions in table minetest
1272         lua_newtable(L);
1273         luaL_register(L, NULL, minetest_f);
1274         lua_setglobal(L, "minetest");
1275         
1276         // Get the main minetest table
1277         lua_getglobal(L, "minetest");
1278
1279         // Add tables to minetest
1280         
1281         /*lua_newtable(L);
1282         lua_setfield(L, -2, "registered_blocks");*/
1283
1284         lua_newtable(L);
1285         lua_setfield(L, -2, "registered_entities");
1286
1287         lua_newtable(L);
1288         lua_setfield(L, -2, "registered_globalsteps");
1289
1290         lua_newtable(L);
1291         lua_setfield(L, -2, "registered_on_placenodes");
1292
1293         lua_newtable(L);
1294         lua_setfield(L, -2, "registered_on_dignodes");
1295
1296         lua_newtable(L);
1297         lua_setfield(L, -2, "registered_on_punchnodes");
1298
1299         lua_newtable(L);
1300         lua_setfield(L, -2, "object_refs");
1301
1302         lua_newtable(L);
1303         lua_setfield(L, -2, "luaentities");
1304
1305         // Create entity prototype
1306         luaL_newmetatable(L, "minetest.entity");
1307         // metatable.__index = metatable
1308         lua_pushvalue(L, -1); // Duplicate metatable
1309         lua_setfield(L, -2, "__index");
1310         // Put functions in metatable
1311         luaL_register(L, NULL, minetest_entity_m);
1312         // Put other stuff in metatable
1313
1314         // Environment C reference
1315         EnvRef::Register(L);
1316
1317         // Object C reference
1318         ObjectRef::Register(L);
1319 }
1320
1321 void scriptapi_add_environment(lua_State *L, ServerEnvironment *env)
1322 {
1323         realitycheck(L);
1324         assert(lua_checkstack(L, 20));
1325         infostream<<"scriptapi_add_environment"<<std::endl;
1326         StackUnroller stack_unroller(L);
1327
1328         // Create EnvRef on stack
1329         EnvRef::create(L, env);
1330         int envref = lua_gettop(L);
1331
1332         // minetest.env = envref
1333         lua_getglobal(L, "minetest");
1334         luaL_checktype(L, -1, LUA_TTABLE);
1335         lua_pushvalue(L, envref);
1336         lua_setfield(L, -2, "env");
1337 }
1338
1339 #if 0
1340 // Dump stack top with the dump2 function
1341 static void dump2(lua_State *L, const char *name)
1342 {
1343         // Dump object (debug)
1344         lua_getglobal(L, "dump2");
1345         luaL_checktype(L, -1, LUA_TFUNCTION);
1346         lua_pushvalue(L, -2); // Get previous stack top as first parameter
1347         lua_pushstring(L, name);
1348         if(lua_pcall(L, 2, 0, 0))
1349                 script_error(L, "error: %s\n", lua_tostring(L, -1));
1350 }
1351 #endif
1352
1353 /*
1354         object_reference
1355 */
1356
1357 void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj)
1358 {
1359         realitycheck(L);
1360         assert(lua_checkstack(L, 20));
1361         infostream<<"scriptapi_add_object_reference: id="<<cobj->getId()<<std::endl;
1362         StackUnroller stack_unroller(L);
1363
1364         // Create object on stack
1365         ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack
1366         int object = lua_gettop(L);
1367
1368         // Get minetest.object_refs table
1369         lua_getglobal(L, "minetest");
1370         lua_getfield(L, -1, "object_refs");
1371         luaL_checktype(L, -1, LUA_TTABLE);
1372         int objectstable = lua_gettop(L);
1373         
1374         // object_refs[id] = object
1375         lua_pushnumber(L, cobj->getId()); // Push id
1376         lua_pushvalue(L, object); // Copy object to top of stack
1377         lua_settable(L, objectstable);
1378 }
1379
1380 void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj)
1381 {
1382         realitycheck(L);
1383         assert(lua_checkstack(L, 20));
1384         infostream<<"scriptapi_rm_object_reference: id="<<cobj->getId()<<std::endl;
1385         StackUnroller stack_unroller(L);
1386
1387         // Get minetest.object_refs table
1388         lua_getglobal(L, "minetest");
1389         lua_getfield(L, -1, "object_refs");
1390         luaL_checktype(L, -1, LUA_TTABLE);
1391         int objectstable = lua_gettop(L);
1392         
1393         // Get object_refs[id]
1394         lua_pushnumber(L, cobj->getId()); // Push id
1395         lua_gettable(L, objectstable);
1396         // Set object reference to NULL
1397         ObjectRef::set_null(L);
1398         lua_pop(L, 1); // pop object
1399
1400         // Set object_refs[id] = nil
1401         lua_pushnumber(L, cobj->getId()); // Push id
1402         lua_pushnil(L);
1403         lua_settable(L, objectstable);
1404 }
1405
1406 /*
1407         environment
1408 */
1409
1410 void scriptapi_environment_step(lua_State *L, float dtime)
1411 {
1412         realitycheck(L);
1413         assert(lua_checkstack(L, 20));
1414         //infostream<<"scriptapi_environment_step"<<std::endl;
1415         StackUnroller stack_unroller(L);
1416
1417         // Get minetest.registered_globalsteps
1418         lua_getglobal(L, "minetest");
1419         lua_getfield(L, -1, "registered_globalsteps");
1420         luaL_checktype(L, -1, LUA_TTABLE);
1421         int table = lua_gettop(L);
1422         // Foreach
1423         lua_pushnil(L);
1424         while(lua_next(L, table) != 0){
1425                 // key at index -2 and value at index -1
1426                 luaL_checktype(L, -1, LUA_TFUNCTION);
1427                 // Call function
1428                 lua_pushnumber(L, dtime);
1429                 if(lua_pcall(L, 1, 0, 0))
1430                         script_error(L, "error: %s\n", lua_tostring(L, -1));
1431                 // value removed, keep key for next iteration
1432         }
1433 }
1434
1435 void scriptapi_environment_on_placenode(lua_State *L, v3s16 p, MapNode newnode)
1436 {
1437         realitycheck(L);
1438         assert(lua_checkstack(L, 20));
1439         //infostream<<"scriptapi_environment_on_placenode"<<std::endl;
1440         StackUnroller stack_unroller(L);
1441
1442         // Get server from registry
1443         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1444         Server *server = (Server*)lua_touserdata(L, -1);
1445         // And get the writable node definition manager from the server
1446         IWritableNodeDefManager *ndef =
1447                         server->getWritableNodeDefManager();
1448         
1449         // Get minetest.registered_on_placenodes
1450         lua_getglobal(L, "minetest");
1451         lua_getfield(L, -1, "registered_on_placenodes");
1452         luaL_checktype(L, -1, LUA_TTABLE);
1453         int table = lua_gettop(L);
1454         // Foreach
1455         lua_pushnil(L);
1456         while(lua_next(L, table) != 0){
1457                 // key at index -2 and value at index -1
1458                 luaL_checktype(L, -1, LUA_TFUNCTION);
1459                 // Call function
1460                 pushpos(L, p);
1461                 pushnode(L, newnode, ndef);
1462                 if(lua_pcall(L, 2, 0, 0))
1463                         script_error(L, "error: %s\n", lua_tostring(L, -1));
1464                 // value removed, keep key for next iteration
1465         }
1466 }
1467
1468 void scriptapi_environment_on_dignode(lua_State *L, v3s16 p, MapNode oldnode)
1469 {
1470         realitycheck(L);
1471         assert(lua_checkstack(L, 20));
1472         //infostream<<"scriptapi_environment_on_dignode"<<std::endl;
1473         StackUnroller stack_unroller(L);
1474
1475         // Get server from registry
1476         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1477         Server *server = (Server*)lua_touserdata(L, -1);
1478         // And get the writable node definition manager from the server
1479         IWritableNodeDefManager *ndef =
1480                         server->getWritableNodeDefManager();
1481         
1482         // Get minetest.registered_on_dignodes
1483         lua_getglobal(L, "minetest");
1484         lua_getfield(L, -1, "registered_on_dignodes");
1485         luaL_checktype(L, -1, LUA_TTABLE);
1486         int table = lua_gettop(L);
1487         // Foreach
1488         lua_pushnil(L);
1489         while(lua_next(L, table) != 0){
1490                 // key at index -2 and value at index -1
1491                 luaL_checktype(L, -1, LUA_TFUNCTION);
1492                 // Call function
1493                 pushpos(L, p);
1494                 pushnode(L, oldnode, ndef);
1495                 if(lua_pcall(L, 2, 0, 0))
1496                         script_error(L, "error: %s\n", lua_tostring(L, -1));
1497                 // value removed, keep key for next iteration
1498         }
1499 }
1500
1501 void scriptapi_environment_on_punchnode(lua_State *L, v3s16 p, MapNode oldnode)
1502 {
1503         realitycheck(L);
1504         assert(lua_checkstack(L, 20));
1505         //infostream<<"scriptapi_environment_on_punchnode"<<std::endl;
1506         StackUnroller stack_unroller(L);
1507
1508         // Get server from registry
1509         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1510         Server *server = (Server*)lua_touserdata(L, -1);
1511         // And get the writable node definition manager from the server
1512         IWritableNodeDefManager *ndef =
1513                         server->getWritableNodeDefManager();
1514         
1515         // Get minetest.registered_on_punchnodes
1516         lua_getglobal(L, "minetest");
1517         lua_getfield(L, -1, "registered_on_punchnodes");
1518         luaL_checktype(L, -1, LUA_TTABLE);
1519         int table = lua_gettop(L);
1520         // Foreach
1521         lua_pushnil(L);
1522         while(lua_next(L, table) != 0){
1523                 // key at index -2 and value at index -1
1524                 luaL_checktype(L, -1, LUA_TFUNCTION);
1525                 // Call function
1526                 pushpos(L, p);
1527                 pushnode(L, oldnode, ndef);
1528                 if(lua_pcall(L, 2, 0, 0))
1529                         script_error(L, "error: %s\n", lua_tostring(L, -1));
1530                 // value removed, keep key for next iteration
1531         }
1532 }
1533
1534 /*
1535         luaentity
1536 */
1537
1538 bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
1539                 const std::string &staticdata)
1540 {
1541         realitycheck(L);
1542         assert(lua_checkstack(L, 20));
1543         infostream<<"scriptapi_luaentity_add: id="<<id<<" name=\""
1544                         <<name<<"\""<<std::endl;
1545         StackUnroller stack_unroller(L);
1546         
1547         // Get minetest.registered_entities[name]
1548         lua_getglobal(L, "minetest");
1549         lua_getfield(L, -1, "registered_entities");
1550         luaL_checktype(L, -1, LUA_TTABLE);
1551         lua_pushstring(L, name);
1552         lua_gettable(L, -2);
1553         // Should be a table, which we will use as a prototype
1554         //luaL_checktype(L, -1, LUA_TTABLE);
1555         if(lua_type(L, -1) != LUA_TTABLE){
1556                 errorstream<<"LuaEntity name \""<<name<<"\" not defined"<<std::endl;
1557                 return false;
1558         }
1559         int prototype_table = lua_gettop(L);
1560         //dump2(L, "prototype_table");
1561         
1562         // Create entity object
1563         lua_newtable(L);
1564         int object = lua_gettop(L);
1565
1566         // Set object metatable
1567         lua_pushvalue(L, prototype_table);
1568         lua_setmetatable(L, -2);
1569         
1570         // Add object reference
1571         // This should be userdata with metatable ObjectRef
1572         objectref_get(L, id);
1573         luaL_checktype(L, -1, LUA_TUSERDATA);
1574         if(!luaL_checkudata(L, -1, "ObjectRef"))
1575                 luaL_typerror(L, -1, "ObjectRef");
1576         lua_setfield(L, -2, "object");
1577
1578         // minetest.luaentities[id] = object
1579         lua_getglobal(L, "minetest");
1580         lua_getfield(L, -1, "luaentities");
1581         luaL_checktype(L, -1, LUA_TTABLE);
1582         lua_pushnumber(L, id); // Push id
1583         lua_pushvalue(L, object); // Copy object to top of stack
1584         lua_settable(L, -3);
1585         
1586         // Get on_activate function
1587         lua_pushvalue(L, object);
1588         lua_getfield(L, -1, "on_activate");
1589         if(!lua_isnil(L, -1)){
1590                 luaL_checktype(L, -1, LUA_TFUNCTION);
1591                 lua_pushvalue(L, object); // self
1592                 lua_pushlstring(L, staticdata.c_str(), staticdata.size());
1593                 // Call with 2 arguments, 0 results
1594                 if(lua_pcall(L, 2, 0, 0))
1595                         script_error(L, "error running function %s:on_activate: %s\n",
1596                                         name, lua_tostring(L, -1));
1597         }
1598         
1599         return true;
1600 }
1601
1602 void scriptapi_luaentity_rm(lua_State *L, u16 id)
1603 {
1604         realitycheck(L);
1605         assert(lua_checkstack(L, 20));
1606         infostream<<"scriptapi_luaentity_rm: id="<<id<<std::endl;
1607
1608         // Get minetest.luaentities table
1609         lua_getglobal(L, "minetest");
1610         lua_getfield(L, -1, "luaentities");
1611         luaL_checktype(L, -1, LUA_TTABLE);
1612         int objectstable = lua_gettop(L);
1613         
1614         // Set luaentities[id] = nil
1615         lua_pushnumber(L, id); // Push id
1616         lua_pushnil(L);
1617         lua_settable(L, objectstable);
1618         
1619         lua_pop(L, 2); // pop luaentities, minetest
1620 }
1621
1622 std::string scriptapi_luaentity_get_staticdata(lua_State *L, u16 id)
1623 {
1624         realitycheck(L);
1625         assert(lua_checkstack(L, 20));
1626         infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl;
1627         StackUnroller stack_unroller(L);
1628
1629         // Get minetest.luaentities[id]
1630         luaentity_get(L, id);
1631         int object = lua_gettop(L);
1632         
1633         // Get get_staticdata function
1634         lua_pushvalue(L, object);
1635         lua_getfield(L, -1, "get_staticdata");
1636         if(lua_isnil(L, -1))
1637                 return "";
1638         
1639         luaL_checktype(L, -1, LUA_TFUNCTION);
1640         lua_pushvalue(L, object); // self
1641         // Call with 1 arguments, 1 results
1642         if(lua_pcall(L, 1, 1, 0))
1643                 script_error(L, "error running function get_staticdata: %s\n",
1644                                 lua_tostring(L, -1));
1645         
1646         size_t len=0;
1647         const char *s = lua_tolstring(L, -1, &len);
1648         return std::string(s, len);
1649 }
1650
1651 void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
1652                 LuaEntityProperties *prop)
1653 {
1654         realitycheck(L);
1655         assert(lua_checkstack(L, 20));
1656         infostream<<"scriptapi_luaentity_get_properties: id="<<id<<std::endl;
1657         StackUnroller stack_unroller(L);
1658
1659         // Get minetest.luaentities[id]
1660         luaentity_get(L, id);
1661         //int object = lua_gettop(L);
1662
1663         lua_getfield(L, -1, "physical");
1664         if(lua_isboolean(L, -1))
1665                 prop->physical = lua_toboolean(L, -1);
1666         lua_pop(L, 1);
1667         
1668         lua_getfield(L, -1, "weight");
1669         prop->weight = lua_tonumber(L, -1);
1670         lua_pop(L, 1);
1671
1672         lua_getfield(L, -1, "collisionbox");
1673         if(lua_istable(L, -1)){
1674                 lua_rawgeti(L, -1, 1);
1675                 prop->collisionbox.MinEdge.X = lua_tonumber(L, -1);
1676                 lua_pop(L, 1);
1677                 lua_rawgeti(L, -1, 2);
1678                 prop->collisionbox.MinEdge.Y = lua_tonumber(L, -1);
1679                 lua_pop(L, 1);
1680                 lua_rawgeti(L, -1, 3);
1681                 prop->collisionbox.MinEdge.Z = lua_tonumber(L, -1);
1682                 lua_pop(L, 1);
1683                 lua_rawgeti(L, -1, 4);
1684                 prop->collisionbox.MaxEdge.X = lua_tonumber(L, -1);
1685                 lua_pop(L, 1);
1686                 lua_rawgeti(L, -1, 5);
1687                 prop->collisionbox.MaxEdge.Y = lua_tonumber(L, -1);
1688                 lua_pop(L, 1);
1689                 lua_rawgeti(L, -1, 6);
1690                 prop->collisionbox.MaxEdge.Z = lua_tonumber(L, -1);
1691                 lua_pop(L, 1);
1692         }
1693         lua_pop(L, 1);
1694
1695         lua_getfield(L, -1, "visual");
1696         if(lua_isstring(L, -1))
1697                 prop->visual = lua_tostring(L, -1);
1698         lua_pop(L, 1);
1699         
1700         lua_getfield(L, -1, "textures");
1701         if(lua_istable(L, -1)){
1702                 prop->textures.clear();
1703                 int table = lua_gettop(L);
1704                 lua_pushnil(L);
1705                 while(lua_next(L, table) != 0){
1706                         // key at index -2 and value at index -1
1707                         if(lua_isstring(L, -1))
1708                                 prop->textures.push_back(lua_tostring(L, -1));
1709                         else
1710                                 prop->textures.push_back("");
1711                         // removes value, keeps key for next iteration
1712                         lua_pop(L, 1);
1713                 }
1714         }
1715         lua_pop(L, 1);
1716
1717 }
1718
1719 void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime)
1720 {
1721         realitycheck(L);
1722         assert(lua_checkstack(L, 20));
1723         //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
1724         StackUnroller stack_unroller(L);
1725
1726         // Get minetest.luaentities[id]
1727         luaentity_get(L, id);
1728         int object = lua_gettop(L);
1729         // State: object is at top of stack
1730         // Get step function
1731         lua_getfield(L, -1, "on_step");
1732         if(lua_isnil(L, -1))
1733                 return;
1734         luaL_checktype(L, -1, LUA_TFUNCTION);
1735         lua_pushvalue(L, object); // self
1736         lua_pushnumber(L, dtime); // dtime
1737         // Call with 2 arguments, 0 results
1738         if(lua_pcall(L, 2, 0, 0))
1739                 script_error(L, "error running function 'on_step': %s\n", lua_tostring(L, -1));
1740 }
1741
1742 // Calls entity:on_punch(ObjectRef puncher)
1743 void scriptapi_luaentity_punch(lua_State *L, u16 id,
1744                 ServerActiveObject *puncher)
1745 {
1746         realitycheck(L);
1747         assert(lua_checkstack(L, 20));
1748         //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
1749         StackUnroller stack_unroller(L);
1750
1751         // Get minetest.luaentities[id]
1752         luaentity_get(L, id);
1753         int object = lua_gettop(L);
1754         // State: object is at top of stack
1755         // Get function
1756         lua_getfield(L, -1, "on_punch");
1757         if(lua_isnil(L, -1))
1758                 return;
1759         luaL_checktype(L, -1, LUA_TFUNCTION);
1760         lua_pushvalue(L, object); // self
1761         objectref_get_or_create(L, puncher); // Clicker reference
1762         // Call with 2 arguments, 0 results
1763         if(lua_pcall(L, 2, 0, 0))
1764                 script_error(L, "error running function 'on_punch': %s\n", lua_tostring(L, -1));
1765 }
1766
1767 // Calls entity:on_rightclick(ObjectRef clicker)
1768 void scriptapi_luaentity_rightclick(lua_State *L, u16 id,
1769                 ServerActiveObject *clicker)
1770 {
1771         realitycheck(L);
1772         assert(lua_checkstack(L, 20));
1773         //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
1774         StackUnroller stack_unroller(L);
1775
1776         // Get minetest.luaentities[id]
1777         luaentity_get(L, id);
1778         int object = lua_gettop(L);
1779         // State: object is at top of stack
1780         // Get function
1781         lua_getfield(L, -1, "on_rightclick");
1782         if(lua_isnil(L, -1))
1783                 return;
1784         luaL_checktype(L, -1, LUA_TFUNCTION);
1785         lua_pushvalue(L, object); // self
1786         objectref_get_or_create(L, clicker); // Clicker reference
1787         // Call with 2 arguments, 0 results
1788         if(lua_pcall(L, 2, 0, 0))
1789                 script_error(L, "error running function 'on_rightclick': %s\n", lua_tostring(L, -1));
1790 }
1791