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