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