[CSM] Add function to get the definition of items (#5732)
[oweals/minetest.git] / src / script / common / c_content.cpp
1 /*
2 Minetest
3 Copyright (C) 2013 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 Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser 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 #include "common/c_content.h"
20 #include "common/c_converter.h"
21 #include "common/c_types.h"
22 #include "nodedef.h"
23 #include "object_properties.h"
24 #include "cpp_api/s_node.h"
25 #include "lua_api/l_object.h"
26 #include "lua_api/l_item.h"
27 #include "common/c_internal.h"
28 #include "server.h"
29 #include "log.h"
30 #include "tool.h"
31 #include "serverobject.h"
32 #include "porting.h"
33 #include "mg_schematic.h"
34 #include "noise.h"
35 #include "util/pointedthing.h"
36 #include "debug.h" // For FATAL_ERROR
37 #include <json/json.h>
38
39 struct EnumString es_TileAnimationType[] =
40 {
41         {TAT_NONE, "none"},
42         {TAT_VERTICAL_FRAMES, "vertical_frames"},
43         {TAT_SHEET_2D, "sheet_2d"},
44         {0, NULL},
45 };
46
47 /******************************************************************************/
48 void read_item_definition(lua_State* L, int index,
49                 const ItemDefinition &default_def, ItemDefinition &def)
50 {
51         if (index < 0)
52                 index = lua_gettop(L) + 1 + index;
53
54         def.type = (ItemType)getenumfield(L, index, "type",
55                         es_ItemType, ITEM_NONE);
56         getstringfield(L, index, "name", def.name);
57         getstringfield(L, index, "description", def.description);
58         getstringfield(L, index, "inventory_image", def.inventory_image);
59         getstringfield(L, index, "wield_image", def.wield_image);
60         getstringfield(L, index, "palette", def.palette_image);
61
62         // Read item color.
63         lua_getfield(L, index, "color");
64         read_color(L, -1, &def.color);
65         lua_pop(L, 1);
66
67         lua_getfield(L, index, "wield_scale");
68         if(lua_istable(L, -1)){
69                 def.wield_scale = check_v3f(L, -1);
70         }
71         lua_pop(L, 1);
72
73         int stack_max = getintfield_default(L, index, "stack_max", def.stack_max);
74         def.stack_max = rangelim(stack_max, 1, U16_MAX);
75
76         lua_getfield(L, index, "on_use");
77         def.usable = lua_isfunction(L, -1);
78         lua_pop(L, 1);
79
80         getboolfield(L, index, "liquids_pointable", def.liquids_pointable);
81
82         warn_if_field_exists(L, index, "tool_digging_properties",
83                         "Deprecated; use tool_capabilities");
84
85         lua_getfield(L, index, "tool_capabilities");
86         if(lua_istable(L, -1)){
87                 def.tool_capabilities = new ToolCapabilities(
88                                 read_tool_capabilities(L, -1));
89         }
90
91         // If name is "" (hand), ensure there are ToolCapabilities
92         // because it will be looked up there whenever any other item has
93         // no ToolCapabilities
94         if(def.name == "" && def.tool_capabilities == NULL){
95                 def.tool_capabilities = new ToolCapabilities();
96         }
97
98         lua_getfield(L, index, "groups");
99         read_groups(L, -1, def.groups);
100         lua_pop(L, 1);
101
102         lua_getfield(L, index, "sounds");
103         if(lua_istable(L, -1)){
104                 lua_getfield(L, -1, "place");
105                 read_soundspec(L, -1, def.sound_place);
106                 lua_pop(L, 1);
107                 lua_getfield(L, -1, "place_failed");
108                 read_soundspec(L, -1, def.sound_place_failed);
109                 lua_pop(L, 1);
110         }
111         lua_pop(L, 1);
112
113         def.range = getfloatfield_default(L, index, "range", def.range);
114
115         // Client shall immediately place this node when player places the item.
116         // Server will update the precise end result a moment later.
117         // "" = no prediction
118         getstringfield(L, index, "node_placement_prediction",
119                         def.node_placement_prediction);
120 }
121
122 /******************************************************************************/
123 void push_item_definition(lua_State *L, const ItemDefinition &i)
124 {
125         lua_newtable(L);
126         lua_pushstring(L, i.name.c_str());
127         lua_setfield(L, -2, "name");
128         lua_pushstring(L, i.description.c_str());
129         lua_setfield(L, -2, "description");
130 }
131
132 void push_item_definition_full(lua_State *L, const ItemDefinition &i)
133 {
134         std::string type(es_ItemType[(int)i.type].str);
135         
136         lua_newtable(L);
137         lua_pushstring(L, i.name.c_str());
138         lua_setfield(L, -2, "name");
139         lua_pushstring(L, i.description.c_str());
140         lua_setfield(L, -2, "description");
141         lua_pushstring(L, type.c_str());
142         lua_setfield(L, -2, "type");
143         lua_pushstring(L, i.inventory_image.c_str());
144         lua_setfield(L, -2, "inventory_image");
145         lua_pushstring(L, i.wield_image.c_str());
146         lua_setfield(L, -2, "wield_image");
147         lua_pushstring(L, i.palette_image.c_str());
148         lua_setfield(L, -2, "palette_image");
149         push_ARGB8(L, i.color);
150         lua_setfield(L, -2, "color");
151         push_v3f(L, i.wield_scale);
152         lua_setfield(L, -2, "wield_scale");
153         lua_pushinteger(L, i.stack_max);
154         lua_setfield(L, -2, "stack_max");
155         lua_pushboolean(L, i.usable);
156         lua_setfield(L, -2, "usable");
157         lua_pushboolean(L, i.liquids_pointable);
158         lua_setfield(L, -2, "liquids_pointable");
159         if (i.type == ITEM_TOOL) {
160                 push_tool_capabilities(L, ToolCapabilities(
161                         i.tool_capabilities->full_punch_interval,
162                         i.tool_capabilities->max_drop_level,
163                         i.tool_capabilities->groupcaps,
164                         i.tool_capabilities->damageGroups));
165                 lua_setfield(L, -2, "tool_capabilities");
166         }
167         push_groups(L, i.groups);
168         lua_setfield(L, -2, "groups");
169         push_soundspec(L, i.sound_place);
170         lua_setfield(L, -2, "sound_place");
171         push_soundspec(L, i.sound_place_failed);
172         lua_setfield(L, -2, "sound_place_failed");
173         lua_pushstring(L, i.node_placement_prediction.c_str());
174         lua_setfield(L, -2, "node_placement_prediction");
175 }
176
177 /******************************************************************************/
178 void read_object_properties(lua_State *L, int index,
179                 ObjectProperties *prop, IItemDefManager *idef)
180 {
181         if(index < 0)
182                 index = lua_gettop(L) + 1 + index;
183         if(!lua_istable(L, index))
184                 return;
185
186         prop->hp_max = getintfield_default(L, -1, "hp_max", 10);
187
188         getboolfield(L, -1, "physical", prop->physical);
189         getboolfield(L, -1, "collide_with_objects", prop->collideWithObjects);
190
191         getfloatfield(L, -1, "weight", prop->weight);
192
193         lua_getfield(L, -1, "collisionbox");
194         if(lua_istable(L, -1))
195                 prop->collisionbox = read_aabb3f(L, -1, 1.0);
196         lua_pop(L, 1);
197
198         getstringfield(L, -1, "visual", prop->visual);
199
200         getstringfield(L, -1, "mesh", prop->mesh);
201
202         lua_getfield(L, -1, "visual_size");
203         if(lua_istable(L, -1))
204                 prop->visual_size = read_v2f(L, -1);
205         lua_pop(L, 1);
206
207         lua_getfield(L, -1, "textures");
208         if(lua_istable(L, -1)){
209                 prop->textures.clear();
210                 int table = lua_gettop(L);
211                 lua_pushnil(L);
212                 while(lua_next(L, table) != 0){
213                         // key at index -2 and value at index -1
214                         if(lua_isstring(L, -1))
215                                 prop->textures.push_back(lua_tostring(L, -1));
216                         else
217                                 prop->textures.push_back("");
218                         // removes value, keeps key for next iteration
219                         lua_pop(L, 1);
220                 }
221         }
222         lua_pop(L, 1);
223
224         lua_getfield(L, -1, "colors");
225         if (lua_istable(L, -1)) {
226                 int table = lua_gettop(L);
227                 prop->colors.clear();
228                 for (lua_pushnil(L); lua_next(L, table); lua_pop(L, 1)) {
229                         video::SColor color(255, 255, 255, 255);
230                         read_color(L, -1, &color);
231                         prop->colors.push_back(color);
232                 }
233         }
234         lua_pop(L, 1);
235
236         lua_getfield(L, -1, "spritediv");
237         if(lua_istable(L, -1))
238                 prop->spritediv = read_v2s16(L, -1);
239         lua_pop(L, 1);
240
241         lua_getfield(L, -1, "initial_sprite_basepos");
242         if(lua_istable(L, -1))
243                 prop->initial_sprite_basepos = read_v2s16(L, -1);
244         lua_pop(L, 1);
245
246         getboolfield(L, -1, "is_visible", prop->is_visible);
247         getboolfield(L, -1, "makes_footstep_sound", prop->makes_footstep_sound);
248         getfloatfield(L, -1, "automatic_rotate", prop->automatic_rotate);
249         if (getfloatfield(L, -1, "stepheight", prop->stepheight))
250                 prop->stepheight *= BS;
251         lua_getfield(L, -1, "automatic_face_movement_dir");
252         if (lua_isnumber(L, -1)) {
253                 prop->automatic_face_movement_dir = true;
254                 prop->automatic_face_movement_dir_offset = luaL_checknumber(L, -1);
255         } else if (lua_isboolean(L, -1)) {
256                 prop->automatic_face_movement_dir = lua_toboolean(L, -1);
257                 prop->automatic_face_movement_dir_offset = 0.0;
258         }
259         lua_pop(L, 1);
260         getboolfield(L, -1, "backface_culling", prop->backface_culling);
261
262         getstringfield(L, -1, "nametag", prop->nametag);
263         lua_getfield(L, -1, "nametag_color");
264         if (!lua_isnil(L, -1)) {
265                 video::SColor color = prop->nametag_color;
266                 if (read_color(L, -1, &color))
267                         prop->nametag_color = color;
268         }
269         lua_pop(L, 1);
270
271         lua_getfield(L, -1, "automatic_face_movement_max_rotation_per_sec");
272         if (lua_isnumber(L, -1)) {
273                 prop->automatic_face_movement_max_rotation_per_sec = luaL_checknumber(L, -1);
274         }
275         lua_pop(L, 1);
276         getstringfield(L, -1, "infotext", prop->infotext);
277         lua_getfield(L, -1, "wield_item");
278         if (!lua_isnil(L, -1))
279                 prop->wield_item = read_item(L, -1, idef).getItemString();
280         lua_pop(L, 1);
281 }
282
283 /******************************************************************************/
284 void push_object_properties(lua_State *L, ObjectProperties *prop)
285 {
286         lua_newtable(L);
287         lua_pushnumber(L, prop->hp_max);
288         lua_setfield(L, -2, "hp_max");
289         lua_pushboolean(L, prop->physical);
290         lua_setfield(L, -2, "physical");
291         lua_pushboolean(L, prop->collideWithObjects);
292         lua_setfield(L, -2, "collide_with_objects");
293         lua_pushnumber(L, prop->weight);
294         lua_setfield(L, -2, "weight");
295         push_aabb3f(L, prop->collisionbox);
296         lua_setfield(L, -2, "collisionbox");
297         lua_pushlstring(L, prop->visual.c_str(), prop->visual.size());
298         lua_setfield(L, -2, "visual");
299         lua_pushlstring(L, prop->mesh.c_str(), prop->mesh.size());
300         lua_setfield(L, -2, "mesh");
301         push_v2f(L, prop->visual_size);
302         lua_setfield(L, -2, "visual_size");
303
304         lua_newtable(L);
305         u16 i = 1;
306         for (std::vector<std::string>::iterator it = prop->textures.begin();
307                         it != prop->textures.end(); ++it) {
308                 lua_pushlstring(L, it->c_str(), it->size());
309                 lua_rawseti(L, -2, i);
310         }
311         lua_setfield(L, -2, "textures");
312
313         lua_newtable(L);
314         i = 1;
315         for (std::vector<video::SColor>::iterator it = prop->colors.begin();
316                         it != prop->colors.end(); ++it) {
317                 push_ARGB8(L, *it);
318                 lua_rawseti(L, -2, i);
319         }
320         lua_setfield(L, -2, "colors");
321
322         push_v2s16(L, prop->spritediv);
323         lua_setfield(L, -2, "spritediv");
324         push_v2s16(L, prop->initial_sprite_basepos);
325         lua_setfield(L, -2, "initial_sprite_basepos");
326         lua_pushboolean(L, prop->is_visible);
327         lua_setfield(L, -2, "is_visible");
328         lua_pushboolean(L, prop->makes_footstep_sound);
329         lua_setfield(L, -2, "makes_footstep_sound");
330         lua_pushnumber(L, prop->automatic_rotate);
331         lua_setfield(L, -2, "automatic_rotate");
332         lua_pushnumber(L, prop->stepheight / BS);
333         lua_setfield(L, -2, "stepheight");
334         if (prop->automatic_face_movement_dir)
335                 lua_pushnumber(L, prop->automatic_face_movement_dir_offset);
336         else
337                 lua_pushboolean(L, false);
338         lua_setfield(L, -2, "automatic_face_movement_dir");
339         lua_pushboolean(L, prop->backface_culling);
340         lua_setfield(L, -2, "backface_culling");
341         lua_pushlstring(L, prop->nametag.c_str(), prop->nametag.size());
342         lua_setfield(L, -2, "nametag");
343         push_ARGB8(L, prop->nametag_color);
344         lua_setfield(L, -2, "nametag_color");
345         lua_pushnumber(L, prop->automatic_face_movement_max_rotation_per_sec);
346         lua_setfield(L, -2, "automatic_face_movement_max_rotation_per_sec");
347         lua_pushlstring(L, prop->infotext.c_str(), prop->infotext.size());
348         lua_setfield(L, -2, "infotext");
349         lua_pushlstring(L, prop->wield_item.c_str(), prop->wield_item.size());
350         lua_setfield(L, -2, "wield_item");
351 }
352
353 /******************************************************************************/
354 TileDef read_tiledef(lua_State *L, int index, u8 drawtype)
355 {
356         if(index < 0)
357                 index = lua_gettop(L) + 1 + index;
358
359         TileDef tiledef;
360
361         bool default_tiling = true;
362         bool default_culling = true;
363         switch (drawtype) {
364                 case NDT_PLANTLIKE:
365                 case NDT_FIRELIKE:
366                         default_tiling = false;
367                         // "break" is omitted here intentionaly, as PLANTLIKE
368                         // FIRELIKE drawtype both should default to having
369                         // backface_culling to false.
370                 case NDT_MESH:
371                 case NDT_LIQUID:
372                         default_culling = false;
373                         break;
374                 default:
375                         break;
376         }
377
378         // key at index -2 and value at index
379         if(lua_isstring(L, index)){
380                 // "default_lava.png"
381                 tiledef.name = lua_tostring(L, index);
382                 tiledef.tileable_vertical = default_tiling;
383                 tiledef.tileable_horizontal = default_tiling;
384                 tiledef.backface_culling = default_culling;
385         }
386         else if(lua_istable(L, index))
387         {
388                 // name="default_lava.png"
389                 tiledef.name = "";
390                 getstringfield(L, index, "name", tiledef.name);
391                 getstringfield(L, index, "image", tiledef.name); // MaterialSpec compat.
392                 tiledef.backface_culling = getboolfield_default(
393                         L, index, "backface_culling", default_culling);
394                 tiledef.tileable_horizontal = getboolfield_default(
395                         L, index, "tileable_horizontal", default_tiling);
396                 tiledef.tileable_vertical = getboolfield_default(
397                         L, index, "tileable_vertical", default_tiling);
398                 // color = ...
399                 lua_getfield(L, index, "color");
400                 tiledef.has_color = read_color(L, -1, &tiledef.color);
401                 lua_pop(L, 1);
402                 // animation = {}
403                 lua_getfield(L, index, "animation");
404                 tiledef.animation = read_animation_definition(L, -1);
405                 lua_pop(L, 1);
406         }
407
408         return tiledef;
409 }
410
411 /******************************************************************************/
412 ContentFeatures read_content_features(lua_State *L, int index)
413 {
414         if(index < 0)
415                 index = lua_gettop(L) + 1 + index;
416
417         ContentFeatures f;
418
419         /* Cache existence of some callbacks */
420         lua_getfield(L, index, "on_construct");
421         if(!lua_isnil(L, -1)) f.has_on_construct = true;
422         lua_pop(L, 1);
423         lua_getfield(L, index, "on_destruct");
424         if(!lua_isnil(L, -1)) f.has_on_destruct = true;
425         lua_pop(L, 1);
426         lua_getfield(L, index, "after_destruct");
427         if(!lua_isnil(L, -1)) f.has_after_destruct = true;
428         lua_pop(L, 1);
429
430         lua_getfield(L, index, "on_rightclick");
431         f.rightclickable = lua_isfunction(L, -1);
432         lua_pop(L, 1);
433
434         /* Name */
435         getstringfield(L, index, "name", f.name);
436
437         /* Groups */
438         lua_getfield(L, index, "groups");
439         read_groups(L, -1, f.groups);
440         lua_pop(L, 1);
441
442         /* Visual definition */
443
444         f.drawtype = (NodeDrawType)getenumfield(L, index, "drawtype",
445                         ScriptApiNode::es_DrawType,NDT_NORMAL);
446         getfloatfield(L, index, "visual_scale", f.visual_scale);
447
448         /* Meshnode model filename */
449         getstringfield(L, index, "mesh", f.mesh);
450
451         // tiles = {}
452         lua_getfield(L, index, "tiles");
453         // If nil, try the deprecated name "tile_images" instead
454         if(lua_isnil(L, -1)){
455                 lua_pop(L, 1);
456                 warn_if_field_exists(L, index, "tile_images",
457                                 "Deprecated; new name is \"tiles\".");
458                 lua_getfield(L, index, "tile_images");
459         }
460         if(lua_istable(L, -1)){
461                 int table = lua_gettop(L);
462                 lua_pushnil(L);
463                 int i = 0;
464                 while(lua_next(L, table) != 0){
465                         // Read tiledef from value
466                         f.tiledef[i] = read_tiledef(L, -1, f.drawtype);
467                         // removes value, keeps key for next iteration
468                         lua_pop(L, 1);
469                         i++;
470                         if(i==6){
471                                 lua_pop(L, 1);
472                                 break;
473                         }
474                 }
475                 // Copy last value to all remaining textures
476                 if(i >= 1){
477                         TileDef lasttile = f.tiledef[i-1];
478                         while(i < 6){
479                                 f.tiledef[i] = lasttile;
480                                 i++;
481                         }
482                 }
483         }
484         lua_pop(L, 1);
485
486         // overlay_tiles = {}
487         lua_getfield(L, index, "overlay_tiles");
488         if (lua_istable(L, -1)) {
489                 int table = lua_gettop(L);
490                 lua_pushnil(L);
491                 int i = 0;
492                 while (lua_next(L, table) != 0) {
493                         // Read tiledef from value
494                         f.tiledef_overlay[i] = read_tiledef(L, -1, f.drawtype);
495                         // removes value, keeps key for next iteration
496                         lua_pop(L, 1);
497                         i++;
498                         if (i == 6) {
499                                 lua_pop(L, 1);
500                                 break;
501                         }
502                 }
503                 // Copy last value to all remaining textures
504                 if (i >= 1) {
505                         TileDef lasttile = f.tiledef_overlay[i - 1];
506                         while (i < 6) {
507                                 f.tiledef_overlay[i] = lasttile;
508                                 i++;
509                         }
510                 }
511         }
512         lua_pop(L, 1);
513
514         // special_tiles = {}
515         lua_getfield(L, index, "special_tiles");
516         // If nil, try the deprecated name "special_materials" instead
517         if(lua_isnil(L, -1)){
518                 lua_pop(L, 1);
519                 warn_if_field_exists(L, index, "special_materials",
520                                 "Deprecated; new name is \"special_tiles\".");
521                 lua_getfield(L, index, "special_materials");
522         }
523         if(lua_istable(L, -1)){
524                 int table = lua_gettop(L);
525                 lua_pushnil(L);
526                 int i = 0;
527                 while(lua_next(L, table) != 0){
528                         // Read tiledef from value
529                         f.tiledef_special[i] = read_tiledef(L, -1, f.drawtype);
530                         // removes value, keeps key for next iteration
531                         lua_pop(L, 1);
532                         i++;
533                         if(i==CF_SPECIAL_COUNT){
534                                 lua_pop(L, 1);
535                                 break;
536                         }
537                 }
538         }
539         lua_pop(L, 1);
540
541         f.alpha = getintfield_default(L, index, "alpha", 255);
542
543         bool usealpha = getboolfield_default(L, index,
544                         "use_texture_alpha", false);
545         if (usealpha)
546                 f.alpha = 0;
547
548         // Read node color.
549         lua_getfield(L, index, "color");
550         read_color(L, -1, &f.color);
551         lua_pop(L, 1);
552
553         getstringfield(L, index, "palette", f.palette_name);
554
555         /* Other stuff */
556
557         lua_getfield(L, index, "post_effect_color");
558         read_color(L, -1, &f.post_effect_color);
559         lua_pop(L, 1);
560
561         f.param_type = (ContentParamType)getenumfield(L, index, "paramtype",
562                         ScriptApiNode::es_ContentParamType, CPT_NONE);
563         f.param_type_2 = (ContentParamType2)getenumfield(L, index, "paramtype2",
564                         ScriptApiNode::es_ContentParamType2, CPT2_NONE);
565
566         if (f.palette_name != "" &&
567                         !(f.param_type_2 == CPT2_COLOR ||
568                         f.param_type_2 == CPT2_COLORED_FACEDIR ||
569                         f.param_type_2 == CPT2_COLORED_WALLMOUNTED))
570                 warningstream << "Node " << f.name.c_str()
571                         << " has a palette, but not a suitable paramtype2." << std::endl;
572
573         // Warn about some deprecated fields
574         warn_if_field_exists(L, index, "wall_mounted",
575                         "Deprecated; use paramtype2 = 'wallmounted'");
576         warn_if_field_exists(L, index, "light_propagates",
577                         "Deprecated; determined from paramtype");
578         warn_if_field_exists(L, index, "dug_item",
579                         "Deprecated; use 'drop' field");
580         warn_if_field_exists(L, index, "extra_dug_item",
581                         "Deprecated; use 'drop' field");
582         warn_if_field_exists(L, index, "extra_dug_item_rarity",
583                         "Deprecated; use 'drop' field");
584         warn_if_field_exists(L, index, "metadata_name",
585                         "Deprecated; use on_add and metadata callbacks");
586
587         // True for all ground-like things like stone and mud, false for eg. trees
588         getboolfield(L, index, "is_ground_content", f.is_ground_content);
589         f.light_propagates = (f.param_type == CPT_LIGHT);
590         getboolfield(L, index, "sunlight_propagates", f.sunlight_propagates);
591         // This is used for collision detection.
592         // Also for general solidness queries.
593         getboolfield(L, index, "walkable", f.walkable);
594         // Player can point to these
595         getboolfield(L, index, "pointable", f.pointable);
596         // Player can dig these
597         getboolfield(L, index, "diggable", f.diggable);
598         // Player can climb these
599         getboolfield(L, index, "climbable", f.climbable);
600         // Player can build on these
601         getboolfield(L, index, "buildable_to", f.buildable_to);
602         // Liquids flow into and replace node
603         getboolfield(L, index, "floodable", f.floodable);
604         // Whether the node is non-liquid, source liquid or flowing liquid
605         f.liquid_type = (LiquidType)getenumfield(L, index, "liquidtype",
606                         ScriptApiNode::es_LiquidType, LIQUID_NONE);
607         // If the content is liquid, this is the flowing version of the liquid.
608         getstringfield(L, index, "liquid_alternative_flowing",
609                         f.liquid_alternative_flowing);
610         // If the content is liquid, this is the source version of the liquid.
611         getstringfield(L, index, "liquid_alternative_source",
612                         f.liquid_alternative_source);
613         // Viscosity for fluid flow, ranging from 1 to 7, with
614         // 1 giving almost instantaneous propagation and 7 being
615         // the slowest possible
616         f.liquid_viscosity = getintfield_default(L, index,
617                         "liquid_viscosity", f.liquid_viscosity);
618         f.liquid_range = getintfield_default(L, index,
619                         "liquid_range", f.liquid_range);
620         f.leveled = getintfield_default(L, index, "leveled", f.leveled);
621
622         getboolfield(L, index, "liquid_renewable", f.liquid_renewable);
623         f.drowning = getintfield_default(L, index,
624                         "drowning", f.drowning);
625         // Amount of light the node emits
626         f.light_source = getintfield_default(L, index,
627                         "light_source", f.light_source);
628         if (f.light_source > LIGHT_MAX) {
629                 warningstream << "Node " << f.name.c_str()
630                         << " had greater light_source than " << LIGHT_MAX
631                         << ", it was reduced." << std::endl;
632                 f.light_source = LIGHT_MAX;
633         }
634         f.damage_per_second = getintfield_default(L, index,
635                         "damage_per_second", f.damage_per_second);
636
637         lua_getfield(L, index, "node_box");
638         if(lua_istable(L, -1))
639                 f.node_box = read_nodebox(L, -1);
640         lua_pop(L, 1);
641
642         lua_getfield(L, index, "connects_to");
643         if (lua_istable(L, -1)) {
644                 int table = lua_gettop(L);
645                 lua_pushnil(L);
646                 while (lua_next(L, table) != 0) {
647                         // Value at -1
648                         f.connects_to.push_back(lua_tostring(L, -1));
649                         lua_pop(L, 1);
650                 }
651         }
652         lua_pop(L, 1);
653
654         lua_getfield(L, index, "connect_sides");
655         if (lua_istable(L, -1)) {
656                 int table = lua_gettop(L);
657                 lua_pushnil(L);
658                 while (lua_next(L, table) != 0) {
659                         // Value at -1
660                         std::string side(lua_tostring(L, -1));
661                         // Note faces are flipped to make checking easier
662                         if (side == "top")
663                                 f.connect_sides |= 2;
664                         else if (side == "bottom")
665                                 f.connect_sides |= 1;
666                         else if (side == "front")
667                                 f.connect_sides |= 16;
668                         else if (side == "left")
669                                 f.connect_sides |= 32;
670                         else if (side == "back")
671                                 f.connect_sides |= 4;
672                         else if (side == "right")
673                                 f.connect_sides |= 8;
674                         else
675                                 warningstream << "Unknown value for \"connect_sides\": "
676                                         << side << std::endl;
677                         lua_pop(L, 1);
678                 }
679         }
680         lua_pop(L, 1);
681
682         lua_getfield(L, index, "selection_box");
683         if(lua_istable(L, -1))
684                 f.selection_box = read_nodebox(L, -1);
685         lua_pop(L, 1);
686
687         lua_getfield(L, index, "collision_box");
688         if(lua_istable(L, -1))
689                 f.collision_box = read_nodebox(L, -1);
690         lua_pop(L, 1);
691
692         f.waving = getintfield_default(L, index,
693                         "waving", f.waving);
694
695         // Set to true if paramtype used to be 'facedir_simple'
696         getboolfield(L, index, "legacy_facedir_simple", f.legacy_facedir_simple);
697         // Set to true if wall_mounted used to be set to true
698         getboolfield(L, index, "legacy_wallmounted", f.legacy_wallmounted);
699
700         // Sound table
701         lua_getfield(L, index, "sounds");
702         if(lua_istable(L, -1)){
703                 lua_getfield(L, -1, "footstep");
704                 read_soundspec(L, -1, f.sound_footstep);
705                 lua_pop(L, 1);
706                 lua_getfield(L, -1, "dig");
707                 read_soundspec(L, -1, f.sound_dig);
708                 lua_pop(L, 1);
709                 lua_getfield(L, -1, "dug");
710                 read_soundspec(L, -1, f.sound_dug);
711                 lua_pop(L, 1);
712         }
713         lua_pop(L, 1);
714
715         return f;
716 }
717
718 void push_content_features(lua_State *L, const ContentFeatures &c)
719 {
720         std::string paramtype(ScriptApiNode::es_ContentParamType[(int)c.param_type].str);
721         std::string paramtype2(ScriptApiNode::es_ContentParamType2[(int)c.param_type_2].str);
722         std::string drawtype(ScriptApiNode::es_DrawType[(int)c.drawtype].str);
723         std::string liquid_type(ScriptApiNode::es_LiquidType[(int)c.liquid_type].str);
724         
725         /* Missing "tiles" because I don't see a usecase (at least not yet). */
726         
727         lua_newtable(L);
728         lua_pushboolean(L, c.has_on_construct);
729         lua_setfield(L, -2, "has_on_construct");
730         lua_pushboolean(L, c.has_on_destruct);
731         lua_setfield(L, -2, "has_on_destruct");
732         lua_pushboolean(L, c.has_after_destruct);
733         lua_setfield(L, -2, "has_after_destruct");
734         lua_pushstring(L, c.name.c_str());
735         lua_setfield(L, -2, "name");
736         push_groups(L, c.groups);
737         lua_setfield(L, -2, "groups");
738         lua_pushstring(L, paramtype.c_str());
739         lua_setfield(L, -2, "paramtype");
740         lua_pushstring(L, paramtype2.c_str());
741         lua_setfield(L, -2, "paramtype2");
742         lua_pushstring(L, drawtype.c_str());
743         lua_setfield(L, -2, "drawtype");
744         if (!c.mesh.empty()) {
745                 lua_pushstring(L, c.mesh.c_str());
746                 lua_setfield(L, -2, "mesh");
747         }
748 #ifndef SERVER
749         push_ARGB8(L, c.minimap_color);       // I know this is not set-able w/ register_node,
750         lua_setfield(L, -2, "minimap_color"); // but the people need to know!
751 #endif
752         lua_pushnumber(L, c.visual_scale);
753         lua_setfield(L, -2, "visual_scale");
754         lua_pushnumber(L, c.alpha);
755         lua_setfield(L, -2, "alpha");
756         if (!c.palette_name.empty()) {
757                 push_ARGB8(L, c.color);
758                 lua_setfield(L, -2, "color");
759                 
760                 lua_pushstring(L, c.palette_name.c_str());
761                 lua_setfield(L, -2, "palette_name");
762                 
763                 push_palette(L, c.palette);
764                 lua_setfield(L, -2, "palette");
765         }
766         lua_pushnumber(L, c.waving);
767         lua_setfield(L, -2, "waving");
768         lua_pushnumber(L, c.connect_sides);
769         lua_setfield(L, -2, "connect_sides");
770         
771         lua_newtable(L);
772         u16 i = 1;
773         for (std::vector<std::string>::const_iterator it = c.connects_to.begin();
774                         it != c.connects_to.end(); ++it) {
775                 lua_pushlstring(L, it->c_str(), it->size());
776                 lua_rawseti(L, -2, i);
777         }
778         lua_setfield(L, -2, "connects_to");
779         
780         push_ARGB8(L, c.post_effect_color);
781         lua_setfield(L, -2, "post_effect_color");
782         lua_pushnumber(L, c.leveled);
783         lua_setfield(L, -2, "leveled");
784         lua_pushboolean(L, c.sunlight_propagates);
785         lua_setfield(L, -2, "sunlight_propagates");
786         lua_pushnumber(L, c.light_source);
787         lua_setfield(L, -2, "light_source");
788         lua_pushboolean(L, c.is_ground_content);
789         lua_setfield(L, -2, "is_ground_content");
790         lua_pushboolean(L, c.walkable);
791         lua_setfield(L, -2, "walkable");
792         lua_pushboolean(L, c.pointable);
793         lua_setfield(L, -2, "pointable");
794         lua_pushboolean(L, c.diggable);
795         lua_setfield(L, -2, "diggable");
796         lua_pushboolean(L, c.climbable);
797         lua_setfield(L, -2, "climbable");
798         lua_pushboolean(L, c.buildable_to);
799         lua_setfield(L, -2, "buildable_to");
800         lua_pushboolean(L, c.rightclickable);
801         lua_setfield(L, -2, "rightclickable");
802         lua_pushnumber(L, c.damage_per_second);
803         lua_setfield(L, -2, "damage_per_second");
804         if (c.isLiquid()) {
805                 lua_pushstring(L, liquid_type.c_str());
806                 lua_setfield(L, -2, "liquid_type");
807                 lua_pushstring(L, c.liquid_alternative_flowing.c_str());
808                 lua_setfield(L, -2, "liquid_alternative_flowing");
809                 lua_pushstring(L, c.liquid_alternative_source.c_str());
810                 lua_setfield(L, -2, "liquid_alternative_source");
811                 lua_pushnumber(L, c.liquid_viscosity);
812                 lua_setfield(L, -2, "liquid_viscosity");
813                 lua_pushboolean(L, c.liquid_renewable);
814                 lua_setfield(L, -2, "liquid_renewable");
815                 lua_pushnumber(L, c.liquid_range);
816                 lua_setfield(L, -2, "liquid_range");
817         }
818         lua_pushnumber(L, c.drowning);
819         lua_setfield(L, -2, "drowning");
820         lua_pushboolean(L, c.floodable);
821         lua_setfield(L, -2, "floodable");
822         push_nodebox(L, c.node_box);
823         lua_setfield(L, -2, "node_box");
824         push_nodebox(L, c.selection_box);
825         lua_setfield(L, -2, "selection_box");
826         push_nodebox(L, c.collision_box);
827         lua_setfield(L, -2, "collision_box");
828         lua_newtable(L);
829         push_soundspec(L, c.sound_footstep);
830         lua_setfield(L, -2, "sound_footstep");
831         push_soundspec(L, c.sound_dig);
832         lua_setfield(L, -2, "sound_dig");
833         push_soundspec(L, c.sound_dug);
834         lua_setfield(L, -2, "sound_dug");
835         lua_setfield(L, -2, "sounds");
836         lua_pushboolean(L, c.legacy_facedir_simple);
837         lua_setfield(L, -2, "legacy_facedir_simple");
838         lua_pushboolean(L, c.legacy_wallmounted);
839         lua_setfield(L, -2, "legacy_wallmounted");
840 }
841
842 /******************************************************************************/
843 void push_nodebox(lua_State *L, const NodeBox &box)
844 {
845         lua_newtable(L);
846         switch (box.type)
847         {
848                 case NODEBOX_REGULAR:
849                         lua_pushstring(L, "regular");
850                         lua_setfield(L, -2, "type");
851                         break;
852                 case NODEBOX_LEVELED:
853                 case NODEBOX_FIXED:
854                         lua_pushstring(L, "fixed");
855                         lua_setfield(L, -2, "type");
856                         push_box(L, box.fixed);
857                         lua_setfield(L, -2, "fixed");
858                         break;
859                 case NODEBOX_WALLMOUNTED:
860                         lua_pushstring(L, "wallmounted");
861                         lua_setfield(L, -2, "type");
862                         push_aabb3f(L, box.wall_top);
863                         lua_setfield(L, -2, "wall_top");
864                         push_aabb3f(L, box.wall_bottom);
865                         lua_setfield(L, -2, "wall_bottom");
866                         push_aabb3f(L, box.wall_side);
867                         lua_setfield(L, -2, "wall_side");
868                         break;
869                 case NODEBOX_CONNECTED:
870                         lua_pushstring(L, "connected");
871                         lua_setfield(L, -2, "type");
872                         push_box(L, box.connect_top);
873                         lua_setfield(L, -2, "connect_top");
874                         push_box(L, box.connect_bottom);
875                         lua_setfield(L, -2, "connect_bottom");
876                         push_box(L, box.connect_front);
877                         lua_setfield(L, -2, "connect_front");
878                         push_box(L, box.connect_back);
879                         lua_setfield(L, -2, "connect_back");
880                         push_box(L, box.connect_left);
881                         lua_setfield(L, -2, "connect_left");
882                         push_box(L, box.connect_right);
883                         lua_setfield(L, -2, "connect_right");
884                         break;
885                 default:
886                         FATAL_ERROR("Invalid box.type");
887                         break;
888         }
889 }
890
891 void push_box(lua_State *L, const std::vector<aabb3f> &box)
892 {
893         lua_newtable(L);
894         u8 i = 1;
895         for (std::vector<aabb3f>::const_iterator it = box.begin();
896                         it != box.end(); ++it) {
897                 push_aabb3f(L, (*it));
898                 lua_rawseti(L, -2, i);
899         }
900 }
901
902 /******************************************************************************/
903 void push_palette(lua_State *L, const std::vector<video::SColor> *palette)
904 {
905         lua_createtable(L, palette->size(), 0);
906         int newTable = lua_gettop(L);
907         int index = 1;
908         std::vector<video::SColor>::const_iterator iter;
909         for (iter = palette->begin(); iter != palette->end(); ++iter) {
910                 push_ARGB8(L, (*iter));
911                 lua_rawseti(L, newTable, index);
912                 index++;
913         }
914 }
915
916 /******************************************************************************/
917 void read_server_sound_params(lua_State *L, int index,
918                 ServerSoundParams &params)
919 {
920         if(index < 0)
921                 index = lua_gettop(L) + 1 + index;
922         // Clear
923         params = ServerSoundParams();
924         if(lua_istable(L, index)){
925                 getfloatfield(L, index, "gain", params.gain);
926                 getstringfield(L, index, "to_player", params.to_player);
927                 getfloatfield(L, index, "fade", params.fade);
928                 lua_getfield(L, index, "pos");
929                 if(!lua_isnil(L, -1)){
930                         v3f p = read_v3f(L, -1)*BS;
931                         params.pos = p;
932                         params.type = ServerSoundParams::SSP_POSITIONAL;
933                 }
934                 lua_pop(L, 1);
935                 lua_getfield(L, index, "object");
936                 if(!lua_isnil(L, -1)){
937                         ObjectRef *ref = ObjectRef::checkobject(L, -1);
938                         ServerActiveObject *sao = ObjectRef::getobject(ref);
939                         if(sao){
940                                 params.object = sao->getId();
941                                 params.type = ServerSoundParams::SSP_OBJECT;
942                         }
943                 }
944                 lua_pop(L, 1);
945                 params.max_hear_distance = BS*getfloatfield_default(L, index,
946                                 "max_hear_distance", params.max_hear_distance/BS);
947                 getboolfield(L, index, "loop", params.loop);
948         }
949 }
950
951 /******************************************************************************/
952 void read_soundspec(lua_State *L, int index, SimpleSoundSpec &spec)
953 {
954         if(index < 0)
955                 index = lua_gettop(L) + 1 + index;
956         if(lua_isnil(L, index)){
957         } else if(lua_istable(L, index)){
958                 getstringfield(L, index, "name", spec.name);
959                 getfloatfield(L, index, "gain", spec.gain);
960                 getfloatfield(L, index, "fade", spec.fade);
961         } else if(lua_isstring(L, index)){
962                 spec.name = lua_tostring(L, index);
963         }
964 }
965
966 void push_soundspec(lua_State *L, const SimpleSoundSpec &spec)
967 {
968         lua_newtable(L);
969         lua_pushstring(L, spec.name.c_str());
970         lua_setfield(L, -2, "name");
971         lua_pushnumber(L, spec.gain);
972         lua_setfield(L, -2, "gain");
973         lua_pushnumber(L, spec.fade);
974         lua_setfield(L, -2, "fade");
975 }
976
977 /******************************************************************************/
978 NodeBox read_nodebox(lua_State *L, int index)
979 {
980         NodeBox nodebox;
981         if(lua_istable(L, -1)){
982                 nodebox.type = (NodeBoxType)getenumfield(L, index, "type",
983                                 ScriptApiNode::es_NodeBoxType, NODEBOX_REGULAR);
984
985 #define NODEBOXREAD(n, s) \
986         do { \
987                 lua_getfield(L, index, (s)); \
988                 if (lua_istable(L, -1)) \
989                         (n) = read_aabb3f(L, -1, BS); \
990                 lua_pop(L, 1); \
991         } while (0)
992
993 #define NODEBOXREADVEC(n, s) \
994         do { \
995                 lua_getfield(L, index, (s)); \
996                 if (lua_istable(L, -1)) \
997                         (n) = read_aabb3f_vector(L, -1, BS); \
998                 lua_pop(L, 1); \
999         } while (0)
1000                 NODEBOXREADVEC(nodebox.fixed, "fixed");
1001                 NODEBOXREAD(nodebox.wall_top, "wall_top");
1002                 NODEBOXREAD(nodebox.wall_bottom, "wall_bottom");
1003                 NODEBOXREAD(nodebox.wall_side, "wall_side");
1004                 NODEBOXREADVEC(nodebox.connect_top, "connect_top");
1005                 NODEBOXREADVEC(nodebox.connect_bottom, "connect_bottom");
1006                 NODEBOXREADVEC(nodebox.connect_front, "connect_front");
1007                 NODEBOXREADVEC(nodebox.connect_left, "connect_left");
1008                 NODEBOXREADVEC(nodebox.connect_back, "connect_back");
1009                 NODEBOXREADVEC(nodebox.connect_right, "connect_right");
1010         }
1011         return nodebox;
1012 }
1013
1014 /******************************************************************************/
1015 MapNode readnode(lua_State *L, int index, INodeDefManager *ndef)
1016 {
1017         lua_getfield(L, index, "name");
1018         if (!lua_isstring(L, -1))
1019                 throw LuaError("Node name is not set or is not a string!");
1020         const char *name = lua_tostring(L, -1);
1021         lua_pop(L, 1);
1022
1023         u8 param1 = 0;
1024         lua_getfield(L, index, "param1");
1025         if (!lua_isnil(L, -1))
1026                 param1 = lua_tonumber(L, -1);
1027         lua_pop(L, 1);
1028
1029         u8 param2 = 0;
1030         lua_getfield(L, index, "param2");
1031         if (!lua_isnil(L, -1))
1032                 param2 = lua_tonumber(L, -1);
1033         lua_pop(L, 1);
1034
1035         return MapNode(ndef, name, param1, param2);
1036 }
1037
1038 /******************************************************************************/
1039 void pushnode(lua_State *L, const MapNode &n, INodeDefManager *ndef)
1040 {
1041         lua_newtable(L);
1042         lua_pushstring(L, ndef->get(n).name.c_str());
1043         lua_setfield(L, -2, "name");
1044         lua_pushnumber(L, n.getParam1());
1045         lua_setfield(L, -2, "param1");
1046         lua_pushnumber(L, n.getParam2());
1047         lua_setfield(L, -2, "param2");
1048 }
1049
1050 /******************************************************************************/
1051 void warn_if_field_exists(lua_State *L, int table,
1052                 const char *name, const std::string &message)
1053 {
1054         lua_getfield(L, table, name);
1055         if (!lua_isnil(L, -1)) {
1056                 warningstream << "Field \"" << name << "\": "
1057                                 << message << std::endl;
1058                 infostream << script_get_backtrace(L) << std::endl;
1059         }
1060         lua_pop(L, 1);
1061 }
1062
1063 /******************************************************************************/
1064 int getenumfield(lua_State *L, int table,
1065                 const char *fieldname, const EnumString *spec, int default_)
1066 {
1067         int result = default_;
1068         string_to_enum(spec, result,
1069                         getstringfield_default(L, table, fieldname, ""));
1070         return result;
1071 }
1072
1073 /******************************************************************************/
1074 bool string_to_enum(const EnumString *spec, int &result,
1075                 const std::string &str)
1076 {
1077         const EnumString *esp = spec;
1078         while(esp->str){
1079                 if(str == std::string(esp->str)){
1080                         result = esp->num;
1081                         return true;
1082                 }
1083                 esp++;
1084         }
1085         return false;
1086 }
1087
1088 /******************************************************************************/
1089 ItemStack read_item(lua_State* L, int index, IItemDefManager *idef)
1090 {
1091         if(index < 0)
1092                 index = lua_gettop(L) + 1 + index;
1093
1094         if(lua_isnil(L, index))
1095         {
1096                 return ItemStack();
1097         }
1098         else if(lua_isuserdata(L, index))
1099         {
1100                 // Convert from LuaItemStack
1101                 LuaItemStack *o = LuaItemStack::checkobject(L, index);
1102                 return o->getItem();
1103         }
1104         else if(lua_isstring(L, index))
1105         {
1106                 // Convert from itemstring
1107                 std::string itemstring = lua_tostring(L, index);
1108                 try
1109                 {
1110                         ItemStack item;
1111                         item.deSerialize(itemstring, idef);
1112                         return item;
1113                 }
1114                 catch(SerializationError &e)
1115                 {
1116                         warningstream<<"unable to create item from itemstring"
1117                                         <<": "<<itemstring<<std::endl;
1118                         return ItemStack();
1119                 }
1120         }
1121         else if(lua_istable(L, index))
1122         {
1123                 // Convert from table
1124                 std::string name = getstringfield_default(L, index, "name", "");
1125                 int count = getintfield_default(L, index, "count", 1);
1126                 int wear = getintfield_default(L, index, "wear", 0);
1127
1128                 ItemStack istack(name, count, wear, idef);
1129
1130                 // BACKWARDS COMPATIBLITY
1131                 std::string value = getstringfield_default(L, index, "metadata", "");
1132                 istack.metadata.setString("", value);
1133
1134                 // Get meta
1135                 lua_getfield(L, index, "meta");
1136                 int fieldstable = lua_gettop(L);
1137                 if (lua_istable(L, fieldstable)) {
1138                         lua_pushnil(L);
1139                         while (lua_next(L, fieldstable) != 0) {
1140                                 // key at index -2 and value at index -1
1141                                 std::string key = lua_tostring(L, -2);
1142                                 size_t value_len;
1143                                 const char *value_cs = lua_tolstring(L, -1, &value_len);
1144                                 std::string value(value_cs, value_len);
1145                                 istack.metadata.setString(key, value);
1146                                 lua_pop(L, 1); // removes value, keeps key for next iteration
1147                         }
1148                 }
1149
1150                 return istack;
1151         } else {
1152                 throw LuaError("Expecting itemstack, itemstring, table or nil");
1153         }
1154 }
1155
1156 /******************************************************************************/
1157 void push_tool_capabilities(lua_State *L,
1158                 const ToolCapabilities &toolcap)
1159 {
1160         lua_newtable(L);
1161         setfloatfield(L, -1, "full_punch_interval", toolcap.full_punch_interval);
1162                 setintfield(L, -1, "max_drop_level", toolcap.max_drop_level);
1163                 // Create groupcaps table
1164                 lua_newtable(L);
1165                 // For each groupcap
1166                 for (ToolGCMap::const_iterator i = toolcap.groupcaps.begin();
1167                         i != toolcap.groupcaps.end(); ++i) {
1168                         // Create groupcap table
1169                         lua_newtable(L);
1170                         const std::string &name = i->first;
1171                         const ToolGroupCap &groupcap = i->second;
1172                         // Create subtable "times"
1173                         lua_newtable(L);
1174                         for (UNORDERED_MAP<int, float>::const_iterator
1175                                         i = groupcap.times.begin(); i != groupcap.times.end(); ++i) {
1176                                 lua_pushinteger(L, i->first);
1177                                 lua_pushnumber(L, i->second);
1178                                 lua_settable(L, -3);
1179                         }
1180                         // Set subtable "times"
1181                         lua_setfield(L, -2, "times");
1182                         // Set simple parameters
1183                         setintfield(L, -1, "maxlevel", groupcap.maxlevel);
1184                         setintfield(L, -1, "uses", groupcap.uses);
1185                         // Insert groupcap table into groupcaps table
1186                         lua_setfield(L, -2, name.c_str());
1187                 }
1188                 // Set groupcaps table
1189                 lua_setfield(L, -2, "groupcaps");
1190                 //Create damage_groups table
1191                 lua_newtable(L);
1192                 // For each damage group
1193                 for (DamageGroup::const_iterator i = toolcap.damageGroups.begin();
1194                         i != toolcap.damageGroups.end(); ++i) {
1195                         // Create damage group table
1196                         lua_pushinteger(L, i->second);
1197                         lua_setfield(L, -2, i->first.c_str());
1198                 }
1199                 lua_setfield(L, -2, "damage_groups");
1200 }
1201
1202 /******************************************************************************/
1203 void push_inventory_list(lua_State *L, Inventory *inv, const char *name)
1204 {
1205         InventoryList *invlist = inv->getList(name);
1206         if(invlist == NULL){
1207                 lua_pushnil(L);
1208                 return;
1209         }
1210         std::vector<ItemStack> items;
1211         for(u32 i=0; i<invlist->getSize(); i++)
1212                 items.push_back(invlist->getItem(i));
1213         push_items(L, items);
1214 }
1215
1216 /******************************************************************************/
1217 void read_inventory_list(lua_State *L, int tableindex,
1218                 Inventory *inv, const char *name, Server* srv, int forcesize)
1219 {
1220         if(tableindex < 0)
1221                 tableindex = lua_gettop(L) + 1 + tableindex;
1222         // If nil, delete list
1223         if(lua_isnil(L, tableindex)){
1224                 inv->deleteList(name);
1225                 return;
1226         }
1227         // Otherwise set list
1228         std::vector<ItemStack> items = read_items(L, tableindex,srv);
1229         int listsize = (forcesize != -1) ? forcesize : items.size();
1230         InventoryList *invlist = inv->addList(name, listsize);
1231         int index = 0;
1232         for(std::vector<ItemStack>::const_iterator
1233                         i = items.begin(); i != items.end(); ++i){
1234                 if(forcesize != -1 && index == forcesize)
1235                         break;
1236                 invlist->changeItem(index, *i);
1237                 index++;
1238         }
1239         while(forcesize != -1 && index < forcesize){
1240                 invlist->deleteItem(index);
1241                 index++;
1242         }
1243 }
1244
1245 /******************************************************************************/
1246 struct TileAnimationParams read_animation_definition(lua_State *L, int index)
1247 {
1248         if(index < 0)
1249                 index = lua_gettop(L) + 1 + index;
1250
1251         struct TileAnimationParams anim;
1252         anim.type = TAT_NONE;
1253         if (!lua_istable(L, index))
1254                 return anim;
1255
1256         anim.type = (TileAnimationType)
1257                 getenumfield(L, index, "type", es_TileAnimationType,
1258                 TAT_NONE);
1259         if (anim.type == TAT_VERTICAL_FRAMES) {
1260                 // {type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}
1261                 anim.vertical_frames.aspect_w =
1262                         getintfield_default(L, index, "aspect_w", 16);
1263                 anim.vertical_frames.aspect_h =
1264                         getintfield_default(L, index, "aspect_h", 16);
1265                 anim.vertical_frames.length =
1266                         getfloatfield_default(L, index, "length", 1.0);
1267         } else if (anim.type == TAT_SHEET_2D) {
1268                 // {type="sheet_2d", frames_w=5, frames_h=3, frame_length=0.5}
1269                 getintfield(L, index, "frames_w",
1270                         anim.sheet_2d.frames_w);
1271                 getintfield(L, index, "frames_h",
1272                         anim.sheet_2d.frames_h);
1273                 getfloatfield(L, index, "frame_length",
1274                         anim.sheet_2d.frame_length);
1275         }
1276
1277         return anim;
1278 }
1279
1280 /******************************************************************************/
1281 ToolCapabilities read_tool_capabilities(
1282                 lua_State *L, int table)
1283 {
1284         ToolCapabilities toolcap;
1285         getfloatfield(L, table, "full_punch_interval", toolcap.full_punch_interval);
1286         getintfield(L, table, "max_drop_level", toolcap.max_drop_level);
1287         lua_getfield(L, table, "groupcaps");
1288         if(lua_istable(L, -1)){
1289                 int table_groupcaps = lua_gettop(L);
1290                 lua_pushnil(L);
1291                 while(lua_next(L, table_groupcaps) != 0){
1292                         // key at index -2 and value at index -1
1293                         std::string groupname = luaL_checkstring(L, -2);
1294                         if(lua_istable(L, -1)){
1295                                 int table_groupcap = lua_gettop(L);
1296                                 // This will be created
1297                                 ToolGroupCap groupcap;
1298                                 // Read simple parameters
1299                                 getintfield(L, table_groupcap, "maxlevel", groupcap.maxlevel);
1300                                 getintfield(L, table_groupcap, "uses", groupcap.uses);
1301                                 // DEPRECATED: maxwear
1302                                 float maxwear = 0;
1303                                 if (getfloatfield(L, table_groupcap, "maxwear", maxwear)){
1304                                         if (maxwear != 0)
1305                                                 groupcap.uses = 1.0/maxwear;
1306                                         else
1307                                                 groupcap.uses = 0;
1308                                         warningstream << "Field \"maxwear\" is deprecated; "
1309                                                         << "replace with uses=1/maxwear" << std::endl;
1310                                         infostream << script_get_backtrace(L) << std::endl;
1311                                 }
1312                                 // Read "times" table
1313                                 lua_getfield(L, table_groupcap, "times");
1314                                 if(lua_istable(L, -1)){
1315                                         int table_times = lua_gettop(L);
1316                                         lua_pushnil(L);
1317                                         while(lua_next(L, table_times) != 0){
1318                                                 // key at index -2 and value at index -1
1319                                                 int rating = luaL_checkinteger(L, -2);
1320                                                 float time = luaL_checknumber(L, -1);
1321                                                 groupcap.times[rating] = time;
1322                                                 // removes value, keeps key for next iteration
1323                                                 lua_pop(L, 1);
1324                                         }
1325                                 }
1326                                 lua_pop(L, 1);
1327                                 // Insert groupcap into toolcap
1328                                 toolcap.groupcaps[groupname] = groupcap;
1329                         }
1330                         // removes value, keeps key for next iteration
1331                         lua_pop(L, 1);
1332                 }
1333         }
1334         lua_pop(L, 1);
1335
1336         lua_getfield(L, table, "damage_groups");
1337         if(lua_istable(L, -1)){
1338                 int table_damage_groups = lua_gettop(L);
1339                 lua_pushnil(L);
1340                 while(lua_next(L, table_damage_groups) != 0){
1341                         // key at index -2 and value at index -1
1342                         std::string groupname = luaL_checkstring(L, -2);
1343                         u16 value = luaL_checkinteger(L, -1);
1344                         toolcap.damageGroups[groupname] = value;
1345                         // removes value, keeps key for next iteration
1346                         lua_pop(L, 1);
1347                 }
1348         }
1349         lua_pop(L, 1);
1350         return toolcap;
1351 }
1352
1353 /******************************************************************************/
1354 void push_dig_params(lua_State *L,const DigParams &params)
1355 {
1356         lua_newtable(L);
1357         setboolfield(L, -1, "diggable", params.diggable);
1358         setfloatfield(L, -1, "time", params.time);
1359         setintfield(L, -1, "wear", params.wear);
1360 }
1361
1362 /******************************************************************************/
1363 void push_hit_params(lua_State *L,const HitParams &params)
1364 {
1365         lua_newtable(L);
1366         setintfield(L, -1, "hp", params.hp);
1367         setintfield(L, -1, "wear", params.wear);
1368 }
1369
1370 /******************************************************************************/
1371
1372 bool getflagsfield(lua_State *L, int table, const char *fieldname,
1373         FlagDesc *flagdesc, u32 *flags, u32 *flagmask)
1374 {
1375         lua_getfield(L, table, fieldname);
1376
1377         bool success = read_flags(L, -1, flagdesc, flags, flagmask);
1378
1379         lua_pop(L, 1);
1380
1381         return success;
1382 }
1383
1384 bool read_flags(lua_State *L, int index, FlagDesc *flagdesc,
1385         u32 *flags, u32 *flagmask)
1386 {
1387         if (lua_isstring(L, index)) {
1388                 std::string flagstr = lua_tostring(L, index);
1389                 *flags = readFlagString(flagstr, flagdesc, flagmask);
1390         } else if (lua_istable(L, index)) {
1391                 *flags = read_flags_table(L, index, flagdesc, flagmask);
1392         } else {
1393                 return false;
1394         }
1395
1396         return true;
1397 }
1398
1399 u32 read_flags_table(lua_State *L, int table, FlagDesc *flagdesc, u32 *flagmask)
1400 {
1401         u32 flags = 0, mask = 0;
1402         char fnamebuf[64] = "no";
1403
1404         for (int i = 0; flagdesc[i].name; i++) {
1405                 bool result;
1406
1407                 if (getboolfield(L, table, flagdesc[i].name, result)) {
1408                         mask |= flagdesc[i].flag;
1409                         if (result)
1410                                 flags |= flagdesc[i].flag;
1411                 }
1412
1413                 strlcpy(fnamebuf + 2, flagdesc[i].name, sizeof(fnamebuf) - 2);
1414                 if (getboolfield(L, table, fnamebuf, result))
1415                         mask |= flagdesc[i].flag;
1416         }
1417
1418         if (flagmask)
1419                 *flagmask = mask;
1420
1421         return flags;
1422 }
1423
1424 void push_flags_string(lua_State *L, FlagDesc *flagdesc, u32 flags, u32 flagmask)
1425 {
1426         std::string flagstring = writeFlagString(flags, flagdesc, flagmask);
1427         lua_pushlstring(L, flagstring.c_str(), flagstring.size());
1428 }
1429
1430 /******************************************************************************/
1431 /* Lua Stored data!                                                           */
1432 /******************************************************************************/
1433
1434 /******************************************************************************/
1435 void read_groups(lua_State *L, int index, ItemGroupList &result)
1436 {
1437         if (!lua_istable(L,index))
1438                 return;
1439         result.clear();
1440         lua_pushnil(L);
1441         if(index < 0)
1442                 index -= 1;
1443         while(lua_next(L, index) != 0){
1444                 // key at index -2 and value at index -1
1445                 std::string name = luaL_checkstring(L, -2);
1446                 int rating = luaL_checkinteger(L, -1);
1447                 result[name] = rating;
1448                 // removes value, keeps key for next iteration
1449                 lua_pop(L, 1);
1450         }
1451 }
1452
1453 /******************************************************************************/
1454 void push_groups(lua_State *L, const ItemGroupList &groups)
1455 {
1456         lua_newtable(L);
1457         for (ItemGroupList::const_iterator it = groups.begin(); it != groups.end(); ++it) {
1458                 lua_pushnumber(L, it->second);
1459                 lua_setfield(L, -2, it->first.c_str());
1460         }
1461 }
1462
1463 /******************************************************************************/
1464 void push_items(lua_State *L, const std::vector<ItemStack> &items)
1465 {
1466         lua_createtable(L, items.size(), 0);
1467         for (u32 i = 0; i != items.size(); i++) {
1468                 LuaItemStack::create(L, items[i]);
1469                 lua_rawseti(L, -2, i + 1);
1470         }
1471 }
1472
1473 /******************************************************************************/
1474 std::vector<ItemStack> read_items(lua_State *L, int index, Server *srv)
1475 {
1476         if(index < 0)
1477                 index = lua_gettop(L) + 1 + index;
1478
1479         std::vector<ItemStack> items;
1480         luaL_checktype(L, index, LUA_TTABLE);
1481         lua_pushnil(L);
1482         while (lua_next(L, index)) {
1483                 s32 key = luaL_checkinteger(L, -2);
1484                 if (key < 1) {
1485                         throw LuaError("Invalid inventory list index");
1486                 }
1487                 if (items.size() < (u32) key) {
1488                         items.resize(key);
1489                 }
1490                 items[key - 1] = read_item(L, -1, srv->idef());
1491                 lua_pop(L, 1);
1492         }
1493         return items;
1494 }
1495
1496 /******************************************************************************/
1497 void luaentity_get(lua_State *L, u16 id)
1498 {
1499         // Get luaentities[i]
1500         lua_getglobal(L, "core");
1501         lua_getfield(L, -1, "luaentities");
1502         luaL_checktype(L, -1, LUA_TTABLE);
1503         lua_pushnumber(L, id);
1504         lua_gettable(L, -2);
1505         lua_remove(L, -2); // Remove luaentities
1506         lua_remove(L, -2); // Remove core
1507 }
1508
1509 /******************************************************************************/
1510 bool read_noiseparams(lua_State *L, int index, NoiseParams *np)
1511 {
1512         if (index < 0)
1513                 index = lua_gettop(L) + 1 + index;
1514
1515         if (!lua_istable(L, index))
1516                 return false;
1517
1518         getfloatfield(L, index, "offset",      np->offset);
1519         getfloatfield(L, index, "scale",       np->scale);
1520         getfloatfield(L, index, "persist",     np->persist);
1521         getfloatfield(L, index, "persistence", np->persist);
1522         getfloatfield(L, index, "lacunarity",  np->lacunarity);
1523         getintfield(L,   index, "seed",        np->seed);
1524         getintfield(L,   index, "octaves",     np->octaves);
1525
1526         u32 flags    = 0;
1527         u32 flagmask = 0;
1528         np->flags = getflagsfield(L, index, "flags", flagdesc_noiseparams,
1529                 &flags, &flagmask) ? flags : NOISE_FLAG_DEFAULTS;
1530
1531         lua_getfield(L, index, "spread");
1532         np->spread  = read_v3f(L, -1);
1533         lua_pop(L, 1);
1534
1535         return true;
1536 }
1537
1538 void push_noiseparams(lua_State *L, NoiseParams *np)
1539 {
1540         lua_newtable(L);
1541         lua_pushnumber(L, np->offset);
1542         lua_setfield(L, -2, "offset");
1543         lua_pushnumber(L, np->scale);
1544         lua_setfield(L, -2, "scale");
1545         lua_pushnumber(L, np->persist);
1546         lua_setfield(L, -2, "persistence");
1547         lua_pushnumber(L, np->lacunarity);
1548         lua_setfield(L, -2, "lacunarity");
1549         lua_pushnumber(L, np->seed);
1550         lua_setfield(L, -2, "seed");
1551         lua_pushnumber(L, np->octaves);
1552         lua_setfield(L, -2, "octaves");
1553
1554         push_flags_string(L, flagdesc_noiseparams, np->flags,
1555                 np->flags);
1556         lua_setfield(L, -2, "flags");
1557
1558         push_v3f(L, np->spread);
1559         lua_setfield(L, -2, "spread");
1560 }
1561
1562 /******************************************************************************/
1563 // Returns depth of json value tree
1564 static int push_json_value_getdepth(const Json::Value &value)
1565 {
1566         if (!value.isArray() && !value.isObject())
1567                 return 1;
1568
1569         int maxdepth = 0;
1570         for (Json::Value::const_iterator it = value.begin();
1571                         it != value.end(); ++it) {
1572                 int elemdepth = push_json_value_getdepth(*it);
1573                 if (elemdepth > maxdepth)
1574                         maxdepth = elemdepth;
1575         }
1576         return maxdepth + 1;
1577 }
1578 // Recursive function to convert JSON --> Lua table
1579 static bool push_json_value_helper(lua_State *L, const Json::Value &value,
1580                 int nullindex)
1581 {
1582         switch(value.type()) {
1583                 case Json::nullValue:
1584                 default:
1585                         lua_pushvalue(L, nullindex);
1586                         break;
1587                 case Json::intValue:
1588                         lua_pushinteger(L, value.asInt());
1589                         break;
1590                 case Json::uintValue:
1591                         lua_pushinteger(L, value.asUInt());
1592                         break;
1593                 case Json::realValue:
1594                         lua_pushnumber(L, value.asDouble());
1595                         break;
1596                 case Json::stringValue:
1597                         {
1598                                 const char *str = value.asCString();
1599                                 lua_pushstring(L, str ? str : "");
1600                         }
1601                         break;
1602                 case Json::booleanValue:
1603                         lua_pushboolean(L, value.asInt());
1604                         break;
1605                 case Json::arrayValue:
1606                         lua_newtable(L);
1607                         for (Json::Value::const_iterator it = value.begin();
1608                                         it != value.end(); ++it) {
1609                                 push_json_value_helper(L, *it, nullindex);
1610                                 lua_rawseti(L, -2, it.index() + 1);
1611                         }
1612                         break;
1613                 case Json::objectValue:
1614                         lua_newtable(L);
1615                         for (Json::Value::const_iterator it = value.begin();
1616                                         it != value.end(); ++it) {
1617 #ifndef JSONCPP_STRING
1618                                 const char *str = it.memberName();
1619                                 lua_pushstring(L, str ? str : "");
1620 #else
1621                                 std::string str = it.name();
1622                                 lua_pushstring(L, str.c_str());
1623 #endif
1624                                 push_json_value_helper(L, *it, nullindex);
1625                                 lua_rawset(L, -3);
1626                         }
1627                         break;
1628         }
1629         return true;
1630 }
1631 // converts JSON --> Lua table; returns false if lua stack limit exceeded
1632 // nullindex: Lua stack index of value to use in place of JSON null
1633 bool push_json_value(lua_State *L, const Json::Value &value, int nullindex)
1634 {
1635         if(nullindex < 0)
1636                 nullindex = lua_gettop(L) + 1 + nullindex;
1637
1638         int depth = push_json_value_getdepth(value);
1639
1640         // The maximum number of Lua stack slots used at each recursion level
1641         // of push_json_value_helper is 2, so make sure there a depth * 2 slots
1642         if (lua_checkstack(L, depth * 2))
1643                 return push_json_value_helper(L, value, nullindex);
1644         else
1645                 return false;
1646 }
1647
1648 // Converts Lua table --> JSON
1649 void read_json_value(lua_State *L, Json::Value &root, int index, u8 recursion)
1650 {
1651         if (recursion > 16) {
1652                 throw SerializationError("Maximum recursion depth exceeded");
1653         }
1654         int type = lua_type(L, index);
1655         if (type == LUA_TBOOLEAN) {
1656                 root = (bool) lua_toboolean(L, index);
1657         } else if (type == LUA_TNUMBER) {
1658                 root = lua_tonumber(L, index);
1659         } else if (type == LUA_TSTRING) {
1660                 size_t len;
1661                 const char *str = lua_tolstring(L, index, &len);
1662                 root = std::string(str, len);
1663         } else if (type == LUA_TTABLE) {
1664                 lua_pushnil(L);
1665                 while (lua_next(L, index)) {
1666                         // Key is at -2 and value is at -1
1667                         Json::Value value;
1668                         read_json_value(L, value, lua_gettop(L), recursion + 1);
1669
1670                         Json::ValueType roottype = root.type();
1671                         int keytype = lua_type(L, -1);
1672                         if (keytype == LUA_TNUMBER) {
1673                                 lua_Number key = lua_tonumber(L, -1);
1674                                 if (roottype != Json::nullValue && roottype != Json::arrayValue) {
1675                                         throw SerializationError("Can't mix array and object values in JSON");
1676                                 } else if (key < 1) {
1677                                         throw SerializationError("Can't use zero-based or negative indexes in JSON");
1678                                 } else if (floor(key) != key) {
1679                                         throw SerializationError("Can't use indexes with a fractional part in JSON");
1680                                 }
1681                                 root[(Json::ArrayIndex) key - 1] = value;
1682                         } else if (keytype == LUA_TSTRING) {
1683                                 if (roottype != Json::nullValue && roottype != Json::objectValue) {
1684                                         throw SerializationError("Can't mix array and object values in JSON");
1685                                 }
1686                                 root[lua_tostring(L, -1)] = value;
1687                         } else {
1688                                 throw SerializationError("Lua key to convert to JSON is not a string or number");
1689                         }
1690                 }
1691         } else if (type == LUA_TNIL) {
1692                 root = Json::nullValue;
1693         } else {
1694                 throw SerializationError("Can only store booleans, numbers, strings, objects, arrays, and null in JSON");
1695         }
1696         lua_pop(L, 1); // Pop value
1697 }
1698
1699 void push_pointed_thing(lua_State *L, const PointedThing &pointed, bool csm)
1700 {
1701         lua_newtable(L);
1702         if (pointed.type == POINTEDTHING_NODE) {
1703                 lua_pushstring(L, "node");
1704                 lua_setfield(L, -2, "type");
1705                 push_v3s16(L, pointed.node_undersurface);
1706                 lua_setfield(L, -2, "under");
1707                 push_v3s16(L, pointed.node_abovesurface);
1708                 lua_setfield(L, -2, "above");
1709         } else if (pointed.type == POINTEDTHING_OBJECT) {
1710                 lua_pushstring(L, "object");
1711                 lua_setfield(L, -2, "type");
1712
1713                 if (csm) {
1714                         lua_pushinteger(L, pointed.object_id);
1715                         lua_setfield(L, -2, "id");
1716                 } else {
1717                         push_objectRef(L, pointed.object_id);
1718                         lua_setfield(L, -2, "ref");
1719                 }
1720         } else {
1721                 lua_pushstring(L, "nothing");
1722                 lua_setfield(L, -2, "type");
1723         }
1724 }
1725
1726 void push_objectRef(lua_State *L, const u16 id)
1727 {
1728         // Get core.object_refs[i]
1729         lua_getglobal(L, "core");
1730         lua_getfield(L, -1, "object_refs");
1731         luaL_checktype(L, -1, LUA_TTABLE);
1732         lua_pushnumber(L, id);
1733         lua_gettable(L, -2);
1734         lua_remove(L, -2); // object_refs
1735         lua_remove(L, -2); // core
1736 }