]> git.lizzy.rs Git - dragonfireclient.git/blob - src/script/common/c_content.cpp
SAPI: Accept either ARGB8 table or ColorString to specify colors
[dragonfireclient.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 "itemdef.h"
24 #include "object_properties.h"
25 #include "cpp_api/s_node.h"
26 #include "lua_api/l_object.h"
27 #include "lua_api/l_item.h"
28 #include "common/c_internal.h"
29 #include "server.h"
30 #include "log.h"
31 #include "tool.h"
32 #include "serverobject.h"
33 #include "porting.h"
34 #include "mg_schematic.h"
35 #include "noise.h"
36 #include "json/json.h"
37
38 struct EnumString es_TileAnimationType[] =
39 {
40         {TAT_NONE, "none"},
41         {TAT_VERTICAL_FRAMES, "vertical_frames"},
42         {0, NULL},
43 };
44
45 /******************************************************************************/
46 ItemDefinition read_item_definition(lua_State* L,int index,
47                 ItemDefinition default_def)
48 {
49         if(index < 0)
50                 index = lua_gettop(L) + 1 + index;
51
52         // Read the item definition
53         ItemDefinition def = default_def;
54
55         def.type = (ItemType)getenumfield(L, index, "type",
56                         es_ItemType, ITEM_NONE);
57         getstringfield(L, index, "name", def.name);
58         getstringfield(L, index, "description", def.description);
59         getstringfield(L, index, "inventory_image", def.inventory_image);
60         getstringfield(L, index, "wield_image", def.wield_image);
61
62         lua_getfield(L, index, "wield_scale");
63         if(lua_istable(L, -1)){
64                 def.wield_scale = check_v3f(L, -1);
65         }
66         lua_pop(L, 1);
67
68         def.stack_max = getintfield_default(L, index, "stack_max", def.stack_max);
69         if(def.stack_max == 0)
70                 def.stack_max = 1;
71
72         lua_getfield(L, index, "on_use");
73         def.usable = lua_isfunction(L, -1);
74         lua_pop(L, 1);
75
76         getboolfield(L, index, "liquids_pointable", def.liquids_pointable);
77
78         warn_if_field_exists(L, index, "tool_digging_properties",
79                         "deprecated: use tool_capabilities");
80
81         lua_getfield(L, index, "tool_capabilities");
82         if(lua_istable(L, -1)){
83                 def.tool_capabilities = new ToolCapabilities(
84                                 read_tool_capabilities(L, -1));
85         }
86
87         // If name is "" (hand), ensure there are ToolCapabilities
88         // because it will be looked up there whenever any other item has
89         // no ToolCapabilities
90         if(def.name == "" && def.tool_capabilities == NULL){
91                 def.tool_capabilities = new ToolCapabilities();
92         }
93
94         lua_getfield(L, index, "groups");
95         read_groups(L, -1, def.groups);
96         lua_pop(L, 1);
97
98         lua_getfield(L, index, "sounds");
99         if(lua_istable(L, -1)){
100                 lua_getfield(L, -1, "place");
101                 read_soundspec(L, -1, def.sound_place);
102                 lua_pop(L, 1);
103         }
104         lua_pop(L, 1);
105
106         def.range = getfloatfield_default(L, index, "range", def.range);
107
108         // Client shall immediately place this node when player places the item.
109         // Server will update the precise end result a moment later.
110         // "" = no prediction
111         getstringfield(L, index, "node_placement_prediction",
112                         def.node_placement_prediction);
113
114         return def;
115 }
116
117 /******************************************************************************/
118 void read_object_properties(lua_State *L, int index,
119                 ObjectProperties *prop)
120 {
121         if(index < 0)
122                 index = lua_gettop(L) + 1 + index;
123         if(!lua_istable(L, index))
124                 return;
125
126         prop->hp_max = getintfield_default(L, -1, "hp_max", 10);
127
128         getboolfield(L, -1, "physical", prop->physical);
129         getboolfield(L, -1, "collide_with_objects", prop->collideWithObjects);
130
131         getfloatfield(L, -1, "weight", prop->weight);
132
133         lua_getfield(L, -1, "collisionbox");
134         if(lua_istable(L, -1))
135                 prop->collisionbox = read_aabb3f(L, -1, 1.0);
136         lua_pop(L, 1);
137
138         getstringfield(L, -1, "visual", prop->visual);
139
140         getstringfield(L, -1, "mesh", prop->mesh);
141
142         lua_getfield(L, -1, "visual_size");
143         if(lua_istable(L, -1))
144                 prop->visual_size = read_v2f(L, -1);
145         lua_pop(L, 1);
146
147         lua_getfield(L, -1, "textures");
148         if(lua_istable(L, -1)){
149                 prop->textures.clear();
150                 int table = lua_gettop(L);
151                 lua_pushnil(L);
152                 while(lua_next(L, table) != 0){
153                         // key at index -2 and value at index -1
154                         if(lua_isstring(L, -1))
155                                 prop->textures.push_back(lua_tostring(L, -1));
156                         else
157                                 prop->textures.push_back("");
158                         // removes value, keeps key for next iteration
159                         lua_pop(L, 1);
160                 }
161         }
162         lua_pop(L, 1);
163
164         lua_getfield(L, -1, "colors");
165         if (lua_istable(L, -1)) {
166                 int table = lua_gettop(L);
167                 prop->colors.clear();
168                 for (lua_pushnil(L); lua_next(L, table); lua_pop(L, 1)) {
169                         video::SColor color(255, 255, 255, 255);
170                         read_color(L, -1, &color);
171                         prop->colors.push_back(color);
172                 }
173         }
174         lua_pop(L, 1);
175
176         lua_getfield(L, -1, "spritediv");
177         if(lua_istable(L, -1))
178                 prop->spritediv = read_v2s16(L, -1);
179         lua_pop(L, 1);
180
181         lua_getfield(L, -1, "initial_sprite_basepos");
182         if(lua_istable(L, -1))
183                 prop->initial_sprite_basepos = read_v2s16(L, -1);
184         lua_pop(L, 1);
185
186         getboolfield(L, -1, "is_visible", prop->is_visible);
187         getboolfield(L, -1, "makes_footstep_sound", prop->makes_footstep_sound);
188         getfloatfield(L, -1, "automatic_rotate", prop->automatic_rotate);
189         if (getfloatfield(L, -1, "stepheight", prop->stepheight))
190                 prop->stepheight *= BS;
191         lua_getfield(L, -1, "automatic_face_movement_dir");
192         if (lua_isnumber(L, -1)) {
193                 prop->automatic_face_movement_dir = true;
194                 prop->automatic_face_movement_dir_offset = luaL_checknumber(L, -1);
195         } else if (lua_isboolean(L, -1)) {
196                 prop->automatic_face_movement_dir = lua_toboolean(L, -1);
197                 prop->automatic_face_movement_dir_offset = 0.0;
198         }
199         lua_pop(L, 1);
200 }
201
202 /******************************************************************************/
203 TileDef read_tiledef(lua_State *L, int index)
204 {
205         if(index < 0)
206                 index = lua_gettop(L) + 1 + index;
207
208         TileDef tiledef;
209
210         // key at index -2 and value at index
211         if(lua_isstring(L, index)){
212                 // "default_lava.png"
213                 tiledef.name = lua_tostring(L, index);
214         }
215         else if(lua_istable(L, index))
216         {
217                 // {name="default_lava.png", animation={}}
218                 tiledef.name = "";
219                 getstringfield(L, index, "name", tiledef.name);
220                 getstringfield(L, index, "image", tiledef.name); // MaterialSpec compat.
221                 tiledef.backface_culling = getboolfield_default(
222                                         L, index, "backface_culling", true);
223                 // animation = {}
224                 lua_getfield(L, index, "animation");
225                 if(lua_istable(L, -1)){
226                         // {type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}
227                         tiledef.animation.type = (TileAnimationType)
228                                         getenumfield(L, -1, "type", es_TileAnimationType,
229                                         TAT_NONE);
230                         tiledef.animation.aspect_w =
231                                         getintfield_default(L, -1, "aspect_w", 16);
232                         tiledef.animation.aspect_h =
233                                         getintfield_default(L, -1, "aspect_h", 16);
234                         tiledef.animation.length =
235                                         getfloatfield_default(L, -1, "length", 1.0);
236                 }
237                 lua_pop(L, 1);
238         }
239
240         return tiledef;
241 }
242
243 /******************************************************************************/
244 ContentFeatures read_content_features(lua_State *L, int index)
245 {
246         if(index < 0)
247                 index = lua_gettop(L) + 1 + index;
248
249         ContentFeatures f;
250
251         /* Cache existence of some callbacks */
252         lua_getfield(L, index, "on_construct");
253         if(!lua_isnil(L, -1)) f.has_on_construct = true;
254         lua_pop(L, 1);
255         lua_getfield(L, index, "on_destruct");
256         if(!lua_isnil(L, -1)) f.has_on_destruct = true;
257         lua_pop(L, 1);
258         lua_getfield(L, index, "after_destruct");
259         if(!lua_isnil(L, -1)) f.has_after_destruct = true;
260         lua_pop(L, 1);
261
262         lua_getfield(L, index, "on_rightclick");
263         f.rightclickable = lua_isfunction(L, -1);
264         lua_pop(L, 1);
265
266         /* Name */
267         getstringfield(L, index, "name", f.name);
268
269         /* Groups */
270         lua_getfield(L, index, "groups");
271         read_groups(L, -1, f.groups);
272         lua_pop(L, 1);
273
274         /* Visual definition */
275
276         f.drawtype = (NodeDrawType)getenumfield(L, index, "drawtype",
277                         ScriptApiNode::es_DrawType,NDT_NORMAL);
278         getfloatfield(L, index, "visual_scale", f.visual_scale);
279
280         /* Meshnode model filename */
281         getstringfield(L, index, "mesh", f.mesh);
282
283         // tiles = {}
284         lua_getfield(L, index, "tiles");
285         // If nil, try the deprecated name "tile_images" instead
286         if(lua_isnil(L, -1)){
287                 lua_pop(L, 1);
288                 warn_if_field_exists(L, index, "tile_images",
289                                 "Deprecated; new name is \"tiles\".");
290                 lua_getfield(L, index, "tile_images");
291         }
292         if(lua_istable(L, -1)){
293                 int table = lua_gettop(L);
294                 lua_pushnil(L);
295                 int i = 0;
296                 while(lua_next(L, table) != 0){
297                         // Read tiledef from value
298                         f.tiledef[i] = read_tiledef(L, -1);
299                         // removes value, keeps key for next iteration
300                         lua_pop(L, 1);
301                         i++;
302                         if(i==6){
303                                 lua_pop(L, 1);
304                                 break;
305                         }
306                 }
307                 // Copy last value to all remaining textures
308                 if(i >= 1){
309                         TileDef lasttile = f.tiledef[i-1];
310                         while(i < 6){
311                                 f.tiledef[i] = lasttile;
312                                 i++;
313                         }
314                 }
315         }
316         lua_pop(L, 1);
317
318         // special_tiles = {}
319         lua_getfield(L, index, "special_tiles");
320         // If nil, try the deprecated name "special_materials" instead
321         if(lua_isnil(L, -1)){
322                 lua_pop(L, 1);
323                 warn_if_field_exists(L, index, "special_materials",
324                                 "Deprecated; new name is \"special_tiles\".");
325                 lua_getfield(L, index, "special_materials");
326         }
327         if(lua_istable(L, -1)){
328                 int table = lua_gettop(L);
329                 lua_pushnil(L);
330                 int i = 0;
331                 while(lua_next(L, table) != 0){
332                         // Read tiledef from value
333                         f.tiledef_special[i] = read_tiledef(L, -1);
334                         // removes value, keeps key for next iteration
335                         lua_pop(L, 1);
336                         i++;
337                         if(i==CF_SPECIAL_COUNT){
338                                 lua_pop(L, 1);
339                                 break;
340                         }
341                 }
342         }
343         lua_pop(L, 1);
344
345         f.alpha = getintfield_default(L, index, "alpha", 255);
346
347         bool usealpha = getboolfield_default(L, index,
348                         "use_texture_alpha", false);
349         if (usealpha)
350                 f.alpha = 0;
351
352         /* Other stuff */
353
354         lua_getfield(L, index, "post_effect_color");
355         read_color(L, -1, &f.post_effect_color);
356         lua_pop(L, 1);
357
358         f.param_type = (ContentParamType)getenumfield(L, index, "paramtype",
359                         ScriptApiNode::es_ContentParamType, CPT_NONE);
360         f.param_type_2 = (ContentParamType2)getenumfield(L, index, "paramtype2",
361                         ScriptApiNode::es_ContentParamType2, CPT2_NONE);
362
363         // Warn about some deprecated fields
364         warn_if_field_exists(L, index, "wall_mounted",
365                         "deprecated: use paramtype2 = 'wallmounted'");
366         warn_if_field_exists(L, index, "light_propagates",
367                         "deprecated: determined from paramtype");
368         warn_if_field_exists(L, index, "dug_item",
369                         "deprecated: use 'drop' field");
370         warn_if_field_exists(L, index, "extra_dug_item",
371                         "deprecated: use 'drop' field");
372         warn_if_field_exists(L, index, "extra_dug_item_rarity",
373                         "deprecated: use 'drop' field");
374         warn_if_field_exists(L, index, "metadata_name",
375                         "deprecated: use on_add and metadata callbacks");
376
377         // True for all ground-like things like stone and mud, false for eg. trees
378         getboolfield(L, index, "is_ground_content", f.is_ground_content);
379         f.light_propagates = (f.param_type == CPT_LIGHT);
380         getboolfield(L, index, "sunlight_propagates", f.sunlight_propagates);
381         // This is used for collision detection.
382         // Also for general solidness queries.
383         getboolfield(L, index, "walkable", f.walkable);
384         // Player can point to these
385         getboolfield(L, index, "pointable", f.pointable);
386         // Player can dig these
387         getboolfield(L, index, "diggable", f.diggable);
388         // Player can climb these
389         getboolfield(L, index, "climbable", f.climbable);
390         // Player can build on these
391         getboolfield(L, index, "buildable_to", f.buildable_to);
392         // Whether the node is non-liquid, source liquid or flowing liquid
393         f.liquid_type = (LiquidType)getenumfield(L, index, "liquidtype",
394                         ScriptApiNode::es_LiquidType, LIQUID_NONE);
395         // If the content is liquid, this is the flowing version of the liquid.
396         getstringfield(L, index, "liquid_alternative_flowing",
397                         f.liquid_alternative_flowing);
398         // If the content is liquid, this is the source version of the liquid.
399         getstringfield(L, index, "liquid_alternative_source",
400                         f.liquid_alternative_source);
401         // Viscosity for fluid flow, ranging from 1 to 7, with
402         // 1 giving almost instantaneous propagation and 7 being
403         // the slowest possible
404         f.liquid_viscosity = getintfield_default(L, index,
405                         "liquid_viscosity", f.liquid_viscosity);
406         f.liquid_range = getintfield_default(L, index,
407                         "liquid_range", f.liquid_range);
408         f.leveled = getintfield_default(L, index, "leveled", f.leveled);
409
410         getboolfield(L, index, "liquid_renewable", f.liquid_renewable);
411         f.drowning = getintfield_default(L, index,
412                         "drowning", f.drowning);
413         // Amount of light the node emits
414         f.light_source = getintfield_default(L, index,
415                         "light_source", f.light_source);
416         f.damage_per_second = getintfield_default(L, index,
417                         "damage_per_second", f.damage_per_second);
418
419         lua_getfield(L, index, "node_box");
420         if(lua_istable(L, -1))
421                 f.node_box = read_nodebox(L, -1);
422         lua_pop(L, 1);
423
424         lua_getfield(L, index, "selection_box");
425         if(lua_istable(L, -1))
426                 f.selection_box = read_nodebox(L, -1);
427         lua_pop(L, 1);
428
429         lua_getfield(L, index, "collision_box");
430         if(lua_istable(L, -1))
431                 f.collision_box = read_nodebox(L, -1);
432         lua_pop(L, 1);
433
434         f.waving = getintfield_default(L, index,
435                         "waving", f.waving);
436
437         // Set to true if paramtype used to be 'facedir_simple'
438         getboolfield(L, index, "legacy_facedir_simple", f.legacy_facedir_simple);
439         // Set to true if wall_mounted used to be set to true
440         getboolfield(L, index, "legacy_wallmounted", f.legacy_wallmounted);
441
442         // Sound table
443         lua_getfield(L, index, "sounds");
444         if(lua_istable(L, -1)){
445                 lua_getfield(L, -1, "footstep");
446                 read_soundspec(L, -1, f.sound_footstep);
447                 lua_pop(L, 1);
448                 lua_getfield(L, -1, "dig");
449                 read_soundspec(L, -1, f.sound_dig);
450                 lua_pop(L, 1);
451                 lua_getfield(L, -1, "dug");
452                 read_soundspec(L, -1, f.sound_dug);
453                 lua_pop(L, 1);
454         }
455         lua_pop(L, 1);
456
457         return f;
458 }
459
460 /******************************************************************************/
461 void read_server_sound_params(lua_State *L, int index,
462                 ServerSoundParams &params)
463 {
464         if(index < 0)
465                 index = lua_gettop(L) + 1 + index;
466         // Clear
467         params = ServerSoundParams();
468         if(lua_istable(L, index)){
469                 getfloatfield(L, index, "gain", params.gain);
470                 getstringfield(L, index, "to_player", params.to_player);
471                 lua_getfield(L, index, "pos");
472                 if(!lua_isnil(L, -1)){
473                         v3f p = read_v3f(L, -1)*BS;
474                         params.pos = p;
475                         params.type = ServerSoundParams::SSP_POSITIONAL;
476                 }
477                 lua_pop(L, 1);
478                 lua_getfield(L, index, "object");
479                 if(!lua_isnil(L, -1)){
480                         ObjectRef *ref = ObjectRef::checkobject(L, -1);
481                         ServerActiveObject *sao = ObjectRef::getobject(ref);
482                         if(sao){
483                                 params.object = sao->getId();
484                                 params.type = ServerSoundParams::SSP_OBJECT;
485                         }
486                 }
487                 lua_pop(L, 1);
488                 params.max_hear_distance = BS*getfloatfield_default(L, index,
489                                 "max_hear_distance", params.max_hear_distance/BS);
490                 getboolfield(L, index, "loop", params.loop);
491         }
492 }
493
494 /******************************************************************************/
495 void read_soundspec(lua_State *L, int index, SimpleSoundSpec &spec)
496 {
497         if(index < 0)
498                 index = lua_gettop(L) + 1 + index;
499         if(lua_isnil(L, index)){
500         } else if(lua_istable(L, index)){
501                 getstringfield(L, index, "name", spec.name);
502                 getfloatfield(L, index, "gain", spec.gain);
503         } else if(lua_isstring(L, index)){
504                 spec.name = lua_tostring(L, index);
505         }
506 }
507
508 /******************************************************************************/
509 NodeBox read_nodebox(lua_State *L, int index)
510 {
511         NodeBox nodebox;
512         if(lua_istable(L, -1)){
513                 nodebox.type = (NodeBoxType)getenumfield(L, index, "type",
514                                 ScriptApiNode::es_NodeBoxType, NODEBOX_REGULAR);
515
516                 lua_getfield(L, index, "fixed");
517                 if(lua_istable(L, -1))
518                         nodebox.fixed = read_aabb3f_vector(L, -1, BS);
519                 lua_pop(L, 1);
520
521                 lua_getfield(L, index, "wall_top");
522                 if(lua_istable(L, -1))
523                         nodebox.wall_top = read_aabb3f(L, -1, BS);
524                 lua_pop(L, 1);
525
526                 lua_getfield(L, index, "wall_bottom");
527                 if(lua_istable(L, -1))
528                         nodebox.wall_bottom = read_aabb3f(L, -1, BS);
529                 lua_pop(L, 1);
530
531                 lua_getfield(L, index, "wall_side");
532                 if(lua_istable(L, -1))
533                         nodebox.wall_side = read_aabb3f(L, -1, BS);
534                 lua_pop(L, 1);
535         }
536         return nodebox;
537 }
538
539 /******************************************************************************/
540 MapNode readnode(lua_State *L, int index, INodeDefManager *ndef)
541 {
542         lua_getfield(L, index, "name");
543         if (!lua_isstring(L, -1))
544                 throw LuaError("Node name is not set or is not a string!");
545         const char *name = lua_tostring(L, -1);
546         lua_pop(L, 1);
547
548         u8 param1 = 0;
549         lua_getfield(L, index, "param1");
550         if (!lua_isnil(L, -1))
551                 param1 = lua_tonumber(L, -1);
552         lua_pop(L, 1);
553
554         u8 param2 = 0;
555         lua_getfield(L, index, "param2");
556         if (!lua_isnil(L, -1))
557                 param2 = lua_tonumber(L, -1);
558         lua_pop(L, 1);
559
560         return MapNode(ndef, name, param1, param2);
561 }
562
563 /******************************************************************************/
564 void pushnode(lua_State *L, const MapNode &n, INodeDefManager *ndef)
565 {
566         lua_newtable(L);
567         lua_pushstring(L, ndef->get(n).name.c_str());
568         lua_setfield(L, -2, "name");
569         lua_pushnumber(L, n.getParam1());
570         lua_setfield(L, -2, "param1");
571         lua_pushnumber(L, n.getParam2());
572         lua_setfield(L, -2, "param2");
573 }
574
575 /******************************************************************************/
576 void warn_if_field_exists(lua_State *L, int table,
577                 const char *fieldname, const std::string &message)
578 {
579         lua_getfield(L, table, fieldname);
580         if(!lua_isnil(L, -1)){
581 //TODO find way to access backtrace fct from here
582                 //              infostream<<script_get_backtrace(L)<<std::endl;
583                 infostream<<"WARNING: field \""<<fieldname<<"\": "
584                                 <<message<<std::endl;
585         }
586         lua_pop(L, 1);
587 }
588
589 /******************************************************************************/
590 int getenumfield(lua_State *L, int table,
591                 const char *fieldname, const EnumString *spec, int default_)
592 {
593         int result = default_;
594         string_to_enum(spec, result,
595                         getstringfield_default(L, table, fieldname, ""));
596         return result;
597 }
598
599 /******************************************************************************/
600 bool string_to_enum(const EnumString *spec, int &result,
601                 const std::string &str)
602 {
603         const EnumString *esp = spec;
604         while(esp->str){
605                 if(str == std::string(esp->str)){
606                         result = esp->num;
607                         return true;
608                 }
609                 esp++;
610         }
611         return false;
612 }
613
614 /******************************************************************************/
615 ItemStack read_item(lua_State* L, int index,Server* srv)
616 {
617         if(index < 0)
618                 index = lua_gettop(L) + 1 + index;
619
620         if(lua_isnil(L, index))
621         {
622                 return ItemStack();
623         }
624         else if(lua_isuserdata(L, index))
625         {
626                 // Convert from LuaItemStack
627                 LuaItemStack *o = LuaItemStack::checkobject(L, index);
628                 return o->getItem();
629         }
630         else if(lua_isstring(L, index))
631         {
632                 // Convert from itemstring
633                 std::string itemstring = lua_tostring(L, index);
634                 IItemDefManager *idef = srv->idef();
635                 try
636                 {
637                         ItemStack item;
638                         item.deSerialize(itemstring, idef);
639                         return item;
640                 }
641                 catch(SerializationError &e)
642                 {
643                         infostream<<"WARNING: unable to create item from itemstring"
644                                         <<": "<<itemstring<<std::endl;
645                         return ItemStack();
646                 }
647         }
648         else if(lua_istable(L, index))
649         {
650                 // Convert from table
651                 IItemDefManager *idef = srv->idef();
652                 std::string name = getstringfield_default(L, index, "name", "");
653                 int count = getintfield_default(L, index, "count", 1);
654                 int wear = getintfield_default(L, index, "wear", 0);
655                 std::string metadata = getstringfield_default(L, index, "metadata", "");
656                 return ItemStack(name, count, wear, metadata, idef);
657         }
658         else
659         {
660                 throw LuaError("Expecting itemstack, itemstring, table or nil");
661         }
662 }
663
664 /******************************************************************************/
665 void push_tool_capabilities(lua_State *L,
666                 const ToolCapabilities &toolcap)
667 {
668         lua_newtable(L);
669         setfloatfield(L, -1, "full_punch_interval", toolcap.full_punch_interval);
670                 setintfield(L, -1, "max_drop_level", toolcap.max_drop_level);
671                 // Create groupcaps table
672                 lua_newtable(L);
673                 // For each groupcap
674                 for(std::map<std::string, ToolGroupCap>::const_iterator
675                                 i = toolcap.groupcaps.begin(); i != toolcap.groupcaps.end(); i++){
676                         // Create groupcap table
677                         lua_newtable(L);
678                         const std::string &name = i->first;
679                         const ToolGroupCap &groupcap = i->second;
680                         // Create subtable "times"
681                         lua_newtable(L);
682                         for(std::map<int, float>::const_iterator
683                                         i = groupcap.times.begin(); i != groupcap.times.end(); i++){
684                                 int rating = i->first;
685                                 float time = i->second;
686                                 lua_pushinteger(L, rating);
687                                 lua_pushnumber(L, time);
688                                 lua_settable(L, -3);
689                         }
690                         // Set subtable "times"
691                         lua_setfield(L, -2, "times");
692                         // Set simple parameters
693                         setintfield(L, -1, "maxlevel", groupcap.maxlevel);
694                         setintfield(L, -1, "uses", groupcap.uses);
695                         // Insert groupcap table into groupcaps table
696                         lua_setfield(L, -2, name.c_str());
697                 }
698                 // Set groupcaps table
699                 lua_setfield(L, -2, "groupcaps");
700                 //Create damage_groups table
701                 lua_newtable(L);
702                 // For each damage group
703                 for(std::map<std::string, s16>::const_iterator
704                                 i = toolcap.damageGroups.begin(); i != toolcap.damageGroups.end(); i++){
705                         // Create damage group table
706                         lua_pushinteger(L, i->second);
707                         lua_setfield(L, -2, i->first.c_str());
708                 }
709                 lua_setfield(L, -2, "damage_groups");
710 }
711
712 /******************************************************************************/
713 void push_inventory_list(lua_State *L, Inventory *inv, const char *name)
714 {
715         InventoryList *invlist = inv->getList(name);
716         if(invlist == NULL){
717                 lua_pushnil(L);
718                 return;
719         }
720         std::vector<ItemStack> items;
721         for(u32 i=0; i<invlist->getSize(); i++)
722                 items.push_back(invlist->getItem(i));
723         push_items(L, items);
724 }
725
726 /******************************************************************************/
727 void read_inventory_list(lua_State *L, int tableindex,
728                 Inventory *inv, const char *name, Server* srv, int forcesize)
729 {
730         if(tableindex < 0)
731                 tableindex = lua_gettop(L) + 1 + tableindex;
732         // If nil, delete list
733         if(lua_isnil(L, tableindex)){
734                 inv->deleteList(name);
735                 return;
736         }
737         // Otherwise set list
738         std::vector<ItemStack> items = read_items(L, tableindex,srv);
739         int listsize = (forcesize != -1) ? forcesize : items.size();
740         InventoryList *invlist = inv->addList(name, listsize);
741         int index = 0;
742         for(std::vector<ItemStack>::const_iterator
743                         i = items.begin(); i != items.end(); i++){
744                 if(forcesize != -1 && index == forcesize)
745                         break;
746                 invlist->changeItem(index, *i);
747                 index++;
748         }
749         while(forcesize != -1 && index < forcesize){
750                 invlist->deleteItem(index);
751                 index++;
752         }
753 }
754
755 /******************************************************************************/
756 ToolCapabilities read_tool_capabilities(
757                 lua_State *L, int table)
758 {
759         ToolCapabilities toolcap;
760         getfloatfield(L, table, "full_punch_interval", toolcap.full_punch_interval);
761         getintfield(L, table, "max_drop_level", toolcap.max_drop_level);
762         lua_getfield(L, table, "groupcaps");
763         if(lua_istable(L, -1)){
764                 int table_groupcaps = lua_gettop(L);
765                 lua_pushnil(L);
766                 while(lua_next(L, table_groupcaps) != 0){
767                         // key at index -2 and value at index -1
768                         std::string groupname = luaL_checkstring(L, -2);
769                         if(lua_istable(L, -1)){
770                                 int table_groupcap = lua_gettop(L);
771                                 // This will be created
772                                 ToolGroupCap groupcap;
773                                 // Read simple parameters
774                                 getintfield(L, table_groupcap, "maxlevel", groupcap.maxlevel);
775                                 getintfield(L, table_groupcap, "uses", groupcap.uses);
776                                 // DEPRECATED: maxwear
777                                 float maxwear = 0;
778                                 if(getfloatfield(L, table_groupcap, "maxwear", maxwear)){
779                                         if(maxwear != 0)
780                                                 groupcap.uses = 1.0/maxwear;
781                                         else
782                                                 groupcap.uses = 0;
783                                         infostream<<script_get_backtrace(L)<<std::endl;
784                                         infostream<<"WARNING: field \"maxwear\" is deprecated; "
785                                                         <<"should replace with uses=1/maxwear"<<std::endl;
786                                 }
787                                 // Read "times" table
788                                 lua_getfield(L, table_groupcap, "times");
789                                 if(lua_istable(L, -1)){
790                                         int table_times = lua_gettop(L);
791                                         lua_pushnil(L);
792                                         while(lua_next(L, table_times) != 0){
793                                                 // key at index -2 and value at index -1
794                                                 int rating = luaL_checkinteger(L, -2);
795                                                 float time = luaL_checknumber(L, -1);
796                                                 groupcap.times[rating] = time;
797                                                 // removes value, keeps key for next iteration
798                                                 lua_pop(L, 1);
799                                         }
800                                 }
801                                 lua_pop(L, 1);
802                                 // Insert groupcap into toolcap
803                                 toolcap.groupcaps[groupname] = groupcap;
804                         }
805                         // removes value, keeps key for next iteration
806                         lua_pop(L, 1);
807                 }
808         }
809         lua_pop(L, 1);
810
811         lua_getfield(L, table, "damage_groups");
812         if(lua_istable(L, -1)){
813                 int table_damage_groups = lua_gettop(L);
814                 lua_pushnil(L);
815                 while(lua_next(L, table_damage_groups) != 0){
816                         // key at index -2 and value at index -1
817                         std::string groupname = luaL_checkstring(L, -2);
818                         u16 value = luaL_checkinteger(L, -1);
819                         toolcap.damageGroups[groupname] = value;
820                         // removes value, keeps key for next iteration
821                         lua_pop(L, 1);
822                 }
823         }
824         lua_pop(L, 1);
825         return toolcap;
826 }
827
828 /******************************************************************************/
829 void push_dig_params(lua_State *L,const DigParams &params)
830 {
831         lua_newtable(L);
832         setboolfield(L, -1, "diggable", params.diggable);
833         setfloatfield(L, -1, "time", params.time);
834         setintfield(L, -1, "wear", params.wear);
835 }
836
837 /******************************************************************************/
838 void push_hit_params(lua_State *L,const HitParams &params)
839 {
840         lua_newtable(L);
841         setintfield(L, -1, "hp", params.hp);
842         setintfield(L, -1, "wear", params.wear);
843 }
844
845 /******************************************************************************/
846
847 bool getflagsfield(lua_State *L, int table, const char *fieldname,
848         FlagDesc *flagdesc, u32 *flags, u32 *flagmask)
849 {
850         lua_getfield(L, table, fieldname);
851
852         bool success = read_flags(L, -1, flagdesc, flags, flagmask);
853
854         lua_pop(L, 1);
855
856         return success;
857 }
858
859 bool read_flags(lua_State *L, int index, FlagDesc *flagdesc,
860         u32 *flags, u32 *flagmask)
861 {
862         if (lua_isstring(L, index)) {
863                 std::string flagstr = lua_tostring(L, index);
864                 *flags = readFlagString(flagstr, flagdesc, flagmask);
865         } else if (lua_istable(L, index)) {
866                 *flags = read_flags_table(L, index, flagdesc, flagmask);
867         } else {
868                 return false;
869         }
870
871         return true;
872 }
873
874 u32 read_flags_table(lua_State *L, int table, FlagDesc *flagdesc, u32 *flagmask)
875 {
876         u32 flags = 0, mask = 0;
877         char fnamebuf[64] = "no";
878
879         for (int i = 0; flagdesc[i].name; i++) {
880                 bool result;
881
882                 if (getboolfield(L, table, flagdesc[i].name, result)) {
883                         mask |= flagdesc[i].flag;
884                         if (result)
885                                 flags |= flagdesc[i].flag;
886                 }
887
888                 strlcpy(fnamebuf + 2, flagdesc[i].name, sizeof(fnamebuf) - 2);
889                 if (getboolfield(L, table, fnamebuf, result))
890                         mask |= flagdesc[i].flag;
891         }
892
893         if (flagmask)
894                 *flagmask = mask;
895
896         return flags;
897 }
898
899 /******************************************************************************/
900 /* Lua Stored data!                                                           */
901 /******************************************************************************/
902
903 /******************************************************************************/
904 void read_groups(lua_State *L, int index,
905                 std::map<std::string, int> &result)
906 {
907         if (!lua_istable(L,index))
908                 return;
909         result.clear();
910         lua_pushnil(L);
911         if(index < 0)
912                 index -= 1;
913         while(lua_next(L, index) != 0){
914                 // key at index -2 and value at index -1
915                 std::string name = luaL_checkstring(L, -2);
916                 int rating = luaL_checkinteger(L, -1);
917                 result[name] = rating;
918                 // removes value, keeps key for next iteration
919                 lua_pop(L, 1);
920         }
921 }
922
923 /******************************************************************************/
924 void push_items(lua_State *L, const std::vector<ItemStack> &items)
925 {
926         // Create and fill table
927         lua_createtable(L, items.size(), 0);
928         std::vector<ItemStack>::const_iterator iter = items.begin();
929         for (u32 i = 0; iter != items.end(); iter++) {
930                 LuaItemStack::create(L, *iter);
931                 lua_rawseti(L, -2, ++i);
932         }
933 }
934
935 /******************************************************************************/
936 std::vector<ItemStack> read_items(lua_State *L, int index, Server *srv)
937 {
938         if(index < 0)
939                 index = lua_gettop(L) + 1 + index;
940
941         std::vector<ItemStack> items;
942         luaL_checktype(L, index, LUA_TTABLE);
943         lua_pushnil(L);
944         while (lua_next(L, index)) {
945                 s32 key = luaL_checkinteger(L, -2);
946                 if (key < 1) {
947                         throw LuaError("Invalid inventory list index");
948                 }
949                 if (items.size() < (u32) key) {
950                         items.resize(key);
951                 }
952                 items[key - 1] = read_item(L, -1, srv);
953                 lua_pop(L, 1);
954         }
955         return items;
956 }
957
958 /******************************************************************************/
959 void luaentity_get(lua_State *L, u16 id)
960 {
961         // Get luaentities[i]
962         lua_getglobal(L, "core");
963         lua_getfield(L, -1, "luaentities");
964         luaL_checktype(L, -1, LUA_TTABLE);
965         lua_pushnumber(L, id);
966         lua_gettable(L, -2);
967         lua_remove(L, -2); // Remove luaentities
968         lua_remove(L, -2); // Remove core
969 }
970
971 /******************************************************************************/
972 bool read_noiseparams(lua_State *L, int index, NoiseParams *np)
973 {
974         if (index < 0)
975                 index = lua_gettop(L) + 1 + index;
976
977         if (!lua_istable(L, index))
978                 return false;
979
980         getfloatfield(L, index, "offset",      np->offset);
981         getfloatfield(L, index, "scale",       np->scale);
982         getfloatfield(L, index, "persist",     np->persist);
983         getfloatfield(L, index, "persistence", np->persist);
984         getfloatfield(L, index, "lacunarity",  np->lacunarity);
985         getintfield(L,   index, "seed",        np->seed);
986         getintfield(L,   index, "octaves",     np->octaves);
987
988         u32 flags    = 0;
989         u32 flagmask = 0;
990         np->flags = getflagsfield(L, index, "flags", flagdesc_noiseparams,
991                 &flags, &flagmask) ? flags : NOISE_FLAG_DEFAULTS;
992
993         lua_getfield(L, index, "spread");
994         np->spread  = read_v3f(L, -1);
995         lua_pop(L, 1);
996
997         return true;
998 }
999
1000 /******************************************************************************/
1001 // Returns depth of json value tree
1002 static int push_json_value_getdepth(const Json::Value &value)
1003 {
1004         if (!value.isArray() && !value.isObject())
1005                 return 1;
1006
1007         int maxdepth = 0;
1008         for (Json::Value::const_iterator it = value.begin();
1009                         it != value.end(); ++it) {
1010                 int elemdepth = push_json_value_getdepth(*it);
1011                 if (elemdepth > maxdepth)
1012                         maxdepth = elemdepth;
1013         }
1014         return maxdepth + 1;
1015 }
1016 // Recursive function to convert JSON --> Lua table
1017 static bool push_json_value_helper(lua_State *L, const Json::Value &value,
1018                 int nullindex)
1019 {
1020         switch(value.type()) {
1021                 case Json::nullValue:
1022                 default:
1023                         lua_pushvalue(L, nullindex);
1024                         break;
1025                 case Json::intValue:
1026                         lua_pushinteger(L, value.asInt());
1027                         break;
1028                 case Json::uintValue:
1029                         lua_pushinteger(L, value.asUInt());
1030                         break;
1031                 case Json::realValue:
1032                         lua_pushnumber(L, value.asDouble());
1033                         break;
1034                 case Json::stringValue:
1035                         {
1036                                 const char *str = value.asCString();
1037                                 lua_pushstring(L, str ? str : "");
1038                         }
1039                         break;
1040                 case Json::booleanValue:
1041                         lua_pushboolean(L, value.asInt());
1042                         break;
1043                 case Json::arrayValue:
1044                         lua_newtable(L);
1045                         for (Json::Value::const_iterator it = value.begin();
1046                                         it != value.end(); ++it) {
1047                                 push_json_value_helper(L, *it, nullindex);
1048                                 lua_rawseti(L, -2, it.index() + 1);
1049                         }
1050                         break;
1051                 case Json::objectValue:
1052                         lua_newtable(L);
1053                         for (Json::Value::const_iterator it = value.begin();
1054                                         it != value.end(); ++it) {
1055                                 const char *str = it.memberName();
1056                                 lua_pushstring(L, str ? str : "");
1057                                 push_json_value_helper(L, *it, nullindex);
1058                                 lua_rawset(L, -3);
1059                         }
1060                         break;
1061         }
1062         return true;
1063 }
1064 // converts JSON --> Lua table; returns false if lua stack limit exceeded
1065 // nullindex: Lua stack index of value to use in place of JSON null
1066 bool push_json_value(lua_State *L, const Json::Value &value, int nullindex)
1067 {
1068         if(nullindex < 0)
1069                 nullindex = lua_gettop(L) + 1 + nullindex;
1070
1071         int depth = push_json_value_getdepth(value);
1072
1073         // The maximum number of Lua stack slots used at each recursion level
1074         // of push_json_value_helper is 2, so make sure there a depth * 2 slots
1075         if (lua_checkstack(L, depth * 2))
1076                 return push_json_value_helper(L, value, nullindex);
1077         else
1078                 return false;
1079 }
1080
1081 // Converts Lua table --> JSON
1082 void read_json_value(lua_State *L, Json::Value &root, int index, u8 recursion)
1083 {
1084         if (recursion > 16) {
1085                 throw SerializationError("Maximum recursion depth exceeded");
1086         }
1087         int type = lua_type(L, index);
1088         if (type == LUA_TBOOLEAN) {
1089                 root = (bool) lua_toboolean(L, index);
1090         } else if (type == LUA_TNUMBER) {
1091                 root = lua_tonumber(L, index);
1092         } else if (type == LUA_TSTRING) {
1093                 size_t len;
1094                 const char *str = lua_tolstring(L, index, &len);
1095                 root = std::string(str, len);
1096         } else if (type == LUA_TTABLE) {
1097                 lua_pushnil(L);
1098                 while (lua_next(L, index)) {
1099                         // Key is at -2 and value is at -1
1100                         Json::Value value;
1101                         read_json_value(L, value, lua_gettop(L), recursion + 1);
1102
1103                         Json::ValueType roottype = root.type();
1104                         int keytype = lua_type(L, -1);
1105                         if (keytype == LUA_TNUMBER) {
1106                                 lua_Number key = lua_tonumber(L, -1);
1107                                 if (roottype != Json::nullValue && roottype != Json::arrayValue) {
1108                                         throw SerializationError("Can't mix array and object values in JSON");
1109                                 } else if (key < 1) {
1110                                         throw SerializationError("Can't use zero-based or negative indexes in JSON");
1111                                 } else if (floor(key) != key) {
1112                                         throw SerializationError("Can't use indexes with a fractional part in JSON");
1113                                 }
1114                                 root[(Json::ArrayIndex) key - 1] = value;
1115                         } else if (keytype == LUA_TSTRING) {
1116                                 if (roottype != Json::nullValue && roottype != Json::objectValue) {
1117                                         throw SerializationError("Can't mix array and object values in JSON");
1118                                 }
1119                                 root[lua_tostring(L, -1)] = value;
1120                         } else {
1121                                 throw SerializationError("Lua key to convert to JSON is not a string or number");
1122                         }
1123                 }
1124         } else if (type == LUA_TNIL) {
1125                 root = Json::nullValue;
1126         } else {
1127                 throw SerializationError("Can only store booleans, numbers, strings, objects, arrays, and null in JSON");
1128         }
1129         lua_pop(L, 1); // Pop value
1130 }
1131