Add ObjectRef:punch and ObjectRef:right_click to Lua API
[oweals/minetest.git] / src / content_mapnode.cpp
1 /*
2 Minetest-c55
3 Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include "content_mapnode.h"
21
22 #include "irrlichttypes.h"
23 #include "mapnode.h"
24 #include "nodedef.h"
25 #include "utility.h"
26 #include "nameidmapping.h"
27 #include <map>
28
29 /*
30         Legacy node definitions
31 */
32
33 #define WATER_ALPHA 160
34
35 #define WATER_VISC 1
36 #define LAVA_VISC 7
37
38 void setConstantMaterialProperties(MaterialProperties &mprop, float time)
39 {
40         mprop.diggability = DIGGABLE_CONSTANT;
41         mprop.constant_time = time;
42 }
43
44 void setStoneLikeMaterialProperties(MaterialProperties &mprop, float toughness)
45 {
46         mprop.diggability = DIGGABLE_NORMAL;
47         mprop.weight = 5.0 * toughness;
48         mprop.crackiness = 1.0;
49         mprop.crumbliness = -0.1;
50         mprop.cuttability = -0.2;
51 }
52
53 void setDirtLikeMaterialProperties(MaterialProperties &mprop, float toughness)
54 {
55         mprop.diggability = DIGGABLE_NORMAL;
56         mprop.weight = toughness * 1.2;
57         mprop.crackiness = 0;
58         mprop.crumbliness = 1.2;
59         mprop.cuttability = -0.4;
60 }
61
62 void setGravelLikeMaterialProperties(MaterialProperties &mprop, float toughness)
63 {
64         mprop.diggability = DIGGABLE_NORMAL;
65         mprop.weight = toughness * 2.0;
66         mprop.crackiness = 0.2;
67         mprop.crumbliness = 1.5;
68         mprop.cuttability = -1.0;
69 }
70
71 void setWoodLikeMaterialProperties(MaterialProperties &mprop, float toughness)
72 {
73         mprop.diggability = DIGGABLE_NORMAL;
74         mprop.weight = toughness * 1.0;
75         mprop.crackiness = 0.75;
76         mprop.crumbliness = -1.0;
77         mprop.cuttability = 1.5;
78 }
79
80 void setLeavesLikeMaterialProperties(MaterialProperties &mprop, float toughness)
81 {
82         mprop.diggability = DIGGABLE_NORMAL;
83         mprop.weight = -0.5 * toughness;
84         mprop.crackiness = 0;
85         mprop.crumbliness = 0;
86         mprop.cuttability = 2.0;
87 }
88
89 void setGlassLikeMaterialProperties(MaterialProperties &mprop, float toughness)
90 {
91         mprop.diggability = DIGGABLE_NORMAL;
92         mprop.weight = 0.1 * toughness;
93         mprop.crackiness = 2.0;
94         mprop.crumbliness = -1.0;
95         mprop.cuttability = -1.0;
96 }
97
98 /*
99         Legacy node content type IDs
100         Ranges:
101         0x000...0x07f (0...127): param2 is fully usable
102         126 and 127 are reserved (CONTENT_AIR and CONTENT_IGNORE).
103         0x800...0xfff (2048...4095): higher 4 bytes of param2 are not usable
104 */
105 #define CONTENT_STONE 0
106 #define CONTENT_WATER 2
107 #define CONTENT_TORCH 3
108 #define CONTENT_WATERSOURCE 9
109 #define CONTENT_SIGN_WALL 14
110 #define CONTENT_CHEST 15
111 #define CONTENT_FURNACE 16
112 #define CONTENT_LOCKABLE_CHEST 17
113 #define CONTENT_FENCE 21
114 #define CONTENT_RAIL 30
115 #define CONTENT_LADDER 31
116 #define CONTENT_LAVA 32
117 #define CONTENT_LAVASOURCE 33
118 #define CONTENT_GRASS 0x800 //1
119 #define CONTENT_TREE 0x801 //4
120 #define CONTENT_LEAVES 0x802 //5
121 #define CONTENT_GRASS_FOOTSTEPS 0x803 //6
122 #define CONTENT_MESE 0x804 //7
123 #define CONTENT_MUD 0x805 //8
124 #define CONTENT_CLOUD 0x806 //10
125 #define CONTENT_COALSTONE 0x807 //11
126 #define CONTENT_WOOD 0x808 //12
127 #define CONTENT_SAND 0x809 //13
128 #define CONTENT_COBBLE 0x80a //18
129 #define CONTENT_STEEL 0x80b //19
130 #define CONTENT_GLASS 0x80c //20
131 #define CONTENT_MOSSYCOBBLE 0x80d //22
132 #define CONTENT_GRAVEL 0x80e //23
133 #define CONTENT_SANDSTONE 0x80f //24
134 #define CONTENT_CACTUS 0x810 //25
135 #define CONTENT_BRICK 0x811 //26
136 #define CONTENT_CLAY 0x812 //27
137 #define CONTENT_PAPYRUS 0x813 //28
138 #define CONTENT_BOOKSHELF 0x814 //29
139 #define CONTENT_JUNGLETREE 0x815
140 #define CONTENT_JUNGLEGRASS 0x816
141 #define CONTENT_NC 0x817
142 #define CONTENT_NC_RB 0x818
143 #define CONTENT_APPLE 0x819
144 #define CONTENT_SAPLING 0x820
145
146 /*
147         A conversion table for backwards compatibility.
148         Maps <=v19 content types to current ones.
149         Should never be touched.
150 */
151 content_t trans_table_19[21][2] = {
152         {CONTENT_GRASS, 1},
153         {CONTENT_TREE, 4},
154         {CONTENT_LEAVES, 5},
155         {CONTENT_GRASS_FOOTSTEPS, 6},
156         {CONTENT_MESE, 7},
157         {CONTENT_MUD, 8},
158         {CONTENT_CLOUD, 10},
159         {CONTENT_COALSTONE, 11},
160         {CONTENT_WOOD, 12},
161         {CONTENT_SAND, 13},
162         {CONTENT_COBBLE, 18},
163         {CONTENT_STEEL, 19},
164         {CONTENT_GLASS, 20},
165         {CONTENT_MOSSYCOBBLE, 22},
166         {CONTENT_GRAVEL, 23},
167         {CONTENT_SANDSTONE, 24},
168         {CONTENT_CACTUS, 25},
169         {CONTENT_BRICK, 26},
170         {CONTENT_CLAY, 27},
171         {CONTENT_PAPYRUS, 28},
172         {CONTENT_BOOKSHELF, 29},
173 };
174
175 MapNode mapnode_translate_from_internal(MapNode n_from, u8 version)
176 {
177         MapNode result = n_from;
178         if(version <= 19)
179         {
180                 content_t c_from = n_from.getContent();
181                 for(u32 i=0; i<sizeof(trans_table_19)/sizeof(trans_table_19[0]); i++)
182                 {
183                         if(trans_table_19[i][0] == c_from)
184                         {
185                                 result.setContent(trans_table_19[i][1]);
186                                 break;
187                         }
188                 }
189         }
190         return result;
191 }
192 MapNode mapnode_translate_to_internal(MapNode n_from, u8 version)
193 {
194         MapNode result = n_from;
195         if(version <= 19)
196         {
197                 content_t c_from = n_from.getContent();
198                 for(u32 i=0; i<sizeof(trans_table_19)/sizeof(trans_table_19[0]); i++)
199                 {
200                         if(trans_table_19[i][1] == c_from)
201                         {
202                                 result.setContent(trans_table_19[i][0]);
203                                 break;
204                         }
205                 }
206         }
207         return result;
208 }
209
210 void content_mapnode_get_name_id_mapping(NameIdMapping *nimap)
211 {
212         nimap->set(0, "stone");
213         nimap->set(2, "water_flowing");
214         nimap->set(3, "torch");
215         nimap->set(9, "water_source");
216         nimap->set(14, "sign_wall");
217         nimap->set(15, "chest");
218         nimap->set(16, "furnace");
219         nimap->set(17, "locked_chest");
220         nimap->set(21, "wooden_fence");
221         nimap->set(30, "rail");
222         nimap->set(31, "ladder");
223         nimap->set(32, "lava_flowing");
224         nimap->set(33, "lava_source");
225         nimap->set(0x800, "dirt_with_grass");
226         nimap->set(0x801, "tree");
227         nimap->set(0x802, "leaves");
228         nimap->set(0x803, "dirt_with_grass_footsteps");
229         nimap->set(0x804, "mese");
230         nimap->set(0x805, "dirt");
231         nimap->set(0x806, "cloud");
232         nimap->set(0x807, "coalstone");
233         nimap->set(0x808, "wood");
234         nimap->set(0x809, "sand");
235         nimap->set(0x80a, "cobble");
236         nimap->set(0x80b, "steel");
237         nimap->set(0x80c, "glass");
238         nimap->set(0x80d, "mossycobble");
239         nimap->set(0x80e, "gravel");
240         nimap->set(0x80f, "sandstone");
241         nimap->set(0x810, "cactus");
242         nimap->set(0x811, "brick");
243         nimap->set(0x812, "clay");
244         nimap->set(0x813, "papyrus");
245         nimap->set(0x814, "bookshelf");
246         nimap->set(0x815, "jungletree");
247         nimap->set(0x816, "junglegrass");
248         nimap->set(0x817, "nyancat");
249         nimap->set(0x818, "nyancat_rainbow");
250         nimap->set(0x819, "apple");
251         nimap->set(0x820, "sapling");
252         // Static types
253         nimap->set(CONTENT_IGNORE, "ignore");
254         nimap->set(CONTENT_AIR, "air");
255 }
256
257 class NewNameGetter
258 {
259 public:
260         NewNameGetter()
261         {
262                 old_to_new["CONTENT_STONE"] = "stone";
263                 old_to_new["CONTENT_WATER"] = "water_flowing";
264                 old_to_new["CONTENT_TORCH"] = "torch";
265                 old_to_new["CONTENT_WATERSOURCE"] = "water_source";
266                 old_to_new["CONTENT_SIGN_WALL"] = "sign_wall";
267                 old_to_new["CONTENT_CHEST"] = "chest";
268                 old_to_new["CONTENT_FURNACE"] = "furnace";
269                 old_to_new["CONTENT_LOCKABLE_CHEST"] = "locked_chest";
270                 old_to_new["CONTENT_FENCE"] = "wooden_fence";
271                 old_to_new["CONTENT_RAIL"] = "rail";
272                 old_to_new["CONTENT_LADDER"] = "ladder";
273                 old_to_new["CONTENT_LAVA"] = "lava_flowing";
274                 old_to_new["CONTENT_LAVASOURCE"] = "lava_source";
275                 old_to_new["CONTENT_GRASS"] = "dirt_with_grass";
276                 old_to_new["CONTENT_TREE"] = "tree";
277                 old_to_new["CONTENT_LEAVES"] = "leaves";
278                 old_to_new["CONTENT_GRASS_FOOTSTEPS"] = "dirt_with_grass_footsteps";
279                 old_to_new["CONTENT_MESE"] = "mese";
280                 old_to_new["CONTENT_MUD"] = "dirt";
281                 old_to_new["CONTENT_CLOUD"] = "cloud";
282                 old_to_new["CONTENT_COALSTONE"] = "coalstone";
283                 old_to_new["CONTENT_WOOD"] = "wood";
284                 old_to_new["CONTENT_SAND"] = "sand";
285                 old_to_new["CONTENT_COBBLE"] = "cobble";
286                 old_to_new["CONTENT_STEEL"] = "steel";
287                 old_to_new["CONTENT_GLASS"] = "glass";
288                 old_to_new["CONTENT_MOSSYCOBBLE"] = "mossycobble";
289                 old_to_new["CONTENT_GRAVEL"] = "gravel";
290                 old_to_new["CONTENT_SANDSTONE"] = "sandstone";
291                 old_to_new["CONTENT_CACTUS"] = "cactus";
292                 old_to_new["CONTENT_BRICK"] = "brick";
293                 old_to_new["CONTENT_CLAY"] = "clay";
294                 old_to_new["CONTENT_PAPYRUS"] = "papyrus";
295                 old_to_new["CONTENT_BOOKSHELF"] = "bookshelf";
296                 old_to_new["CONTENT_JUNGLETREE"] = "jungletree";
297                 old_to_new["CONTENT_JUNGLEGRASS"] = "junglegrass";
298                 old_to_new["CONTENT_NC"] = "nyancat";
299                 old_to_new["CONTENT_NC_RB"] = "nyancat_rainbow";
300                 old_to_new["CONTENT_APPLE"] = "apple";
301                 old_to_new["CONTENT_SAPLING"] = "sapling";
302                 // Just in case
303                 old_to_new["CONTENT_IGNORE"] = "ignore";
304                 old_to_new["CONTENT_AIR"] = "air";
305         }
306         std::string get(const std::string &old)
307         {
308                 std::map<std::string, std::string>::const_iterator i;
309                 i = old_to_new.find(old);
310                 if(i == old_to_new.end())
311                         return "";
312                 return i->second;
313         }
314 private:
315         std::map<std::string, std::string> old_to_new;
316 };
317
318 NewNameGetter newnamegetter;
319
320 std::string content_mapnode_get_new_name(const std::string &oldname)
321 {
322         return newnamegetter.get(oldname);
323 }
324
325 content_t legacy_get_id(const std::string &oldname, INodeDefManager *ndef)
326 {
327         std::string newname = content_mapnode_get_new_name(oldname);
328         if(newname == "")
329                 return CONTENT_IGNORE;
330         content_t id;
331         bool found = ndef->getId(newname, id);
332         if(!found)
333                 return CONTENT_IGNORE;
334         return id;
335 }
336
337 // Initialize default (legacy) node definitions
338 void content_mapnode_init(IWritableNodeDefManager *nodemgr)
339 {
340         content_t i;
341         ContentFeatures f;
342
343         i = CONTENT_STONE;
344         f = ContentFeatures();
345         f.name = "stone";
346         f.setAllTextures("stone.png");
347         f.setInventoryTextureCube("stone.png", "stone.png", "stone.png");
348         f.param_type = CPT_MINERAL;
349         f.is_ground_content = true;
350         f.often_contains_mineral = true;
351         f.dug_item = std::string("MaterialItem2 ")+itos(CONTENT_COBBLE)+" 1";
352         setStoneLikeMaterialProperties(f.material, 1.0);
353         nodemgr->set(i, f);
354
355         i = CONTENT_GRASS;
356         f = ContentFeatures();
357         f.name = "dirt_with_grass";
358         f.setAllTextures("mud.png^grass_side.png");
359         f.setTexture(0, "grass.png");
360         f.setTexture(1, "mud.png");
361         f.param_type = CPT_MINERAL;
362         f.is_ground_content = true;
363         f.dug_item = std::string("MaterialItem2 ")+itos(CONTENT_MUD)+" 1";
364         setDirtLikeMaterialProperties(f.material, 1.0);
365         nodemgr->set(i, f);
366
367         i = CONTENT_GRASS_FOOTSTEPS;
368         f = ContentFeatures();
369         f.name = "dirt_with_grass_footsteps";
370         f.setAllTextures("mud.png^grass_side.png");
371         f.setTexture(0, "grass_footsteps.png");
372         f.setTexture(1, "mud.png");
373         f.param_type = CPT_MINERAL;
374         f.is_ground_content = true;
375         f.dug_item = std::string("MaterialItem2 ")+itos(CONTENT_MUD)+" 1";
376         setDirtLikeMaterialProperties(f.material, 1.0);
377         nodemgr->set(i, f);
378
379         i = CONTENT_MUD;
380         f = ContentFeatures();
381         f.name = "dirt";
382         f.setAllTextures("mud.png");
383         f.setInventoryTextureCube("mud.png", "mud.png", "mud.png");
384         f.param_type = CPT_MINERAL;
385         f.is_ground_content = true;
386         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
387         setDirtLikeMaterialProperties(f.material, 1.0);
388         nodemgr->set(i, f);
389
390         i = CONTENT_SAND;
391         f = ContentFeatures();
392         f.name = "sand";
393         f.setAllTextures("sand.png");
394         f.setInventoryTextureCube("sand.png", "sand.png", "sand.png");
395         f.param_type = CPT_MINERAL;
396         f.is_ground_content = true;
397         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
398         f.cookresult_item = std::string("MaterialItem2 ")+itos(CONTENT_GLASS)+" 1";
399         setDirtLikeMaterialProperties(f.material, 1.0);
400         nodemgr->set(i, f);
401
402         i = CONTENT_GRAVEL;
403         f = ContentFeatures();
404         f.name = "gravel";
405         f.setAllTextures("gravel.png");
406         f.setInventoryTextureCube("gravel.png", "gravel.png", "gravel.png");
407         f.param_type = CPT_MINERAL;
408         f.is_ground_content = true;
409         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
410         setGravelLikeMaterialProperties(f.material, 1.0);
411         nodemgr->set(i, f);
412
413         i = CONTENT_SANDSTONE;
414         f = ContentFeatures();
415         f.name = "sandstone";
416         f.setAllTextures("sandstone.png");
417         f.setInventoryTextureCube("sandstone.png", "sandstone.png", "sandstone.png");
418         f.param_type = CPT_MINERAL;
419         f.is_ground_content = true;
420         f.dug_item = std::string("MaterialItem2 ")+itos(CONTENT_SAND)+" 1";
421         setDirtLikeMaterialProperties(f.material, 1.0);
422         nodemgr->set(i, f);
423
424         i = CONTENT_CLAY;
425         f = ContentFeatures();
426         f.name = "clay";
427         f.setAllTextures("clay.png");
428         f.setInventoryTextureCube("clay.png", "clay.png", "clay.png");
429         f.param_type = CPT_MINERAL;
430         f.is_ground_content = true;
431         f.dug_item = std::string("CraftItem lump_of_clay 4");
432         setDirtLikeMaterialProperties(f.material, 1.0);
433         nodemgr->set(i, f);
434
435         i = CONTENT_BRICK;
436         f = ContentFeatures();
437         f.name = "brick";
438         f.setAllTextures("brick.png");
439         f.setInventoryTextureCube("brick.png", "brick.png", "brick.png");
440         f.param_type = CPT_MINERAL;
441         f.is_ground_content = true;
442         f.dug_item = std::string("CraftItem clay_brick 4");
443         setStoneLikeMaterialProperties(f.material, 1.0);
444         nodemgr->set(i, f);
445
446         i = CONTENT_TREE;
447         f = ContentFeatures();
448         f.name = "tree";
449         f.setAllTextures("tree.png");
450         f.setTexture(0, "tree_top.png");
451         f.setTexture(1, "tree_top.png");
452         f.param_type = CPT_MINERAL;
453         f.is_ground_content = true;
454         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
455         f.cookresult_item = "CraftItem lump_of_coal 1";
456         f.furnace_burntime = 30;
457         setWoodLikeMaterialProperties(f.material, 1.0);
458         nodemgr->set(i, f);
459
460         i = CONTENT_JUNGLETREE;
461         f = ContentFeatures();
462         f.name = "jungletree";
463         f.setAllTextures("jungletree.png");
464         f.setTexture(0, "jungletree_top.png");
465         f.setTexture(1, "jungletree_top.png");
466         f.param_type = CPT_MINERAL;
467         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
468         f.furnace_burntime = 30;
469         setWoodLikeMaterialProperties(f.material, 1.0);
470         nodemgr->set(i, f);
471
472         i = CONTENT_JUNGLEGRASS;
473         f = ContentFeatures();
474         f.name = "junglegrass";
475         f.drawtype = NDT_PLANTLIKE;
476         f.visual_scale = 1.3;
477         f.setAllTextures("junglegrass.png");
478         f.setInventoryTexture("junglegrass.png");
479         f.light_propagates = true;
480         f.param_type = CPT_LIGHT;
481         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
482         f.walkable = false;
483         setLeavesLikeMaterialProperties(f.material, 1.0);
484         f.furnace_burntime = 2;
485         nodemgr->set(i, f);
486
487         i = CONTENT_LEAVES;
488         f = ContentFeatures();
489         f.name = "leaves";
490         f.drawtype = NDT_ALLFACES_OPTIONAL;
491         f.setAllTextures("leaves.png");
492         //f.setAllTextures("[noalpha:leaves.png");
493         f.light_propagates = true;
494         f.param_type = CPT_LIGHT;
495         f.extra_dug_item = std::string("MaterialItem2 ")+itos(CONTENT_SAPLING)+" 1";
496         f.extra_dug_item_rarity = 20;
497         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
498         setLeavesLikeMaterialProperties(f.material, 1.0);
499         f.furnace_burntime = 1.0;
500         nodemgr->set(i, f);
501
502         i = CONTENT_CACTUS;
503         f = ContentFeatures();
504         f.name = "cactus";
505         f.setAllTextures("cactus_side.png");
506         f.setTexture(0, "cactus_top.png");
507         f.setTexture(1, "cactus_top.png");
508         f.setInventoryTextureCube("cactus_top.png", "cactus_side.png", "cactus_side.png");
509         f.param_type = CPT_MINERAL;
510         f.is_ground_content = true;
511         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
512         setWoodLikeMaterialProperties(f.material, 0.75);
513         f.furnace_burntime = 15;
514         nodemgr->set(i, f);
515
516         i = CONTENT_PAPYRUS;
517         f = ContentFeatures();
518         f.name = "papyrus";
519         f.drawtype = NDT_PLANTLIKE;
520         f.setAllTextures("papyrus.png");
521         f.setInventoryTexture("papyrus.png");
522         f.light_propagates = true;
523         f.param_type = CPT_LIGHT;
524         f.is_ground_content = true;
525         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
526         f.walkable = false;
527         setLeavesLikeMaterialProperties(f.material, 0.5);
528         f.furnace_burntime = 1;
529         nodemgr->set(i, f);
530
531         i = CONTENT_BOOKSHELF;
532         f = ContentFeatures();
533         f.name = "bookshelf";
534         f.setAllTextures("bookshelf.png");
535         f.setTexture(0, "wood.png");
536         f.setTexture(1, "wood.png");
537         // FIXME: setInventoryTextureCube() only cares for the first texture
538         f.setInventoryTextureCube("bookshelf.png", "bookshelf.png", "bookshelf.png");
539         //f.setInventoryTextureCube("wood.png", "bookshelf.png", "bookshelf.png");
540         f.param_type = CPT_MINERAL;
541         f.is_ground_content = true;
542         setWoodLikeMaterialProperties(f.material, 0.75);
543         f.furnace_burntime = 30;
544         nodemgr->set(i, f);
545
546         i = CONTENT_GLASS;
547         f = ContentFeatures();
548         f.name = "glass";
549         f.drawtype = NDT_GLASSLIKE;
550         f.setAllTextures("glass.png");
551         f.light_propagates = true;
552         f.sunlight_propagates = true;
553         f.param_type = CPT_LIGHT;
554         f.is_ground_content = true;
555         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
556         f.setInventoryTextureCube("glass.png", "glass.png", "glass.png");
557         setGlassLikeMaterialProperties(f.material, 1.0);
558         nodemgr->set(i, f);
559
560         i = CONTENT_FENCE;
561         f = ContentFeatures();
562         f.name = "wooden_fence";
563         f.drawtype = NDT_FENCELIKE;
564         f.setInventoryTexture("fence.png");
565         f.setTexture(0, "wood.png");
566         f.light_propagates = true;
567         f.param_type = CPT_LIGHT;
568         f.is_ground_content = true;
569         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
570         f.selection_box.type = NODEBOX_FIXED;
571         f.selection_box.fixed = core::aabbox3d<f32>(
572                         -BS/7, -BS/2, -BS/7, BS/7, BS/2, BS/7);
573         f.furnace_burntime = 30/2;
574         setWoodLikeMaterialProperties(f.material, 0.75);
575         nodemgr->set(i, f);
576
577         i = CONTENT_RAIL;
578         f = ContentFeatures();
579         f.name = "rail";
580         f.drawtype = NDT_RAILLIKE;
581         f.setInventoryTexture("rail.png");
582         f.setTexture(0, "rail.png");
583         f.setTexture(1, "rail_curved.png");
584         f.setTexture(2, "rail_t_junction.png");
585         f.setTexture(3, "rail_crossing.png");
586         f.light_propagates = true;
587         f.param_type = CPT_LIGHT;
588         f.is_ground_content = true;
589         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
590         f.walkable = false;
591         f.selection_box.type = NODEBOX_FIXED;
592         f.furnace_burntime = 5;
593         setDirtLikeMaterialProperties(f.material, 0.75);
594         nodemgr->set(i, f);
595
596         i = CONTENT_LADDER;
597         f = ContentFeatures();
598         f.name = "ladder";
599         f.drawtype = NDT_SIGNLIKE;
600         f.setAllTextures("ladder.png");
601         f.setInventoryTexture("ladder.png");
602         f.light_propagates = true;
603         f.param_type = CPT_LIGHT;
604         f.is_ground_content = true;
605         f.dug_item = std::string("MaterialItem ")+itos(i)+" 1";
606         f.wall_mounted = true;
607         f.walkable = false;
608         f.climbable = true;
609         f.selection_box.type = NODEBOX_WALLMOUNTED;
610         f.furnace_burntime = 5;
611         setWoodLikeMaterialProperties(f.material, 0.5);
612
613         nodemgr->set(i, f);
614
615         i = CONTENT_COALSTONE;
616         f = ContentFeatures();
617         f.name = "coalstone";
618         f.setAllTextures("stone.png^mineral_coal.png");
619         f.is_ground_content = true;
620         setStoneLikeMaterialProperties(f.material, 1.5);
621         nodemgr->set(i, f);
622
623         i = CONTENT_WOOD;
624         f = ContentFeatures();
625         f.name = "wood";
626         f.setAllTextures("wood.png");
627         f.setInventoryTextureCube("wood.png", "wood.png", "wood.png");
628         f.is_ground_content = true;
629         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
630         f.furnace_burntime = 30/4;
631         setWoodLikeMaterialProperties(f.material, 0.75);
632         nodemgr->set(i, f);
633
634         i = CONTENT_MESE;
635         f = ContentFeatures();
636         f.name = "mese";
637         f.setAllTextures("mese.png");
638         f.setInventoryTextureCube("mese.png", "mese.png", "mese.png");
639         f.is_ground_content = true;
640         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
641         f.furnace_burntime = 30;
642         setStoneLikeMaterialProperties(f.material, 0.5);
643         nodemgr->set(i, f);
644
645         i = CONTENT_CLOUD;
646         f = ContentFeatures();
647         f.name = "cloud";
648         f.setAllTextures("cloud.png");
649         f.setInventoryTextureCube("cloud.png", "cloud.png", "cloud.png");
650         f.is_ground_content = true;
651         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
652         nodemgr->set(i, f);
653
654         i = CONTENT_AIR;
655         f = ContentFeatures();
656         f.name = "air";
657         f.param_type = CPT_LIGHT;
658         f.light_propagates = true;
659         f.sunlight_propagates = true;
660         f.walkable = false;
661         f.pointable = false;
662         f.diggable = false;
663         f.buildable_to = true;
664         nodemgr->set(i, f);
665
666         i = CONTENT_WATER;
667         f = ContentFeatures();
668         f.name = "water_flowing";
669         f.drawtype = NDT_FLOWINGLIQUID;
670         f.setAllTextures("water.png");
671         f.alpha = WATER_ALPHA;
672         f.setInventoryTextureCube("water.png", "water.png", "water.png");
673         f.param_type = CPT_LIGHT;
674         f.light_propagates = true;
675         f.walkable = false;
676         f.pointable = false;
677         f.diggable = false;
678         f.buildable_to = true;
679         f.liquid_type = LIQUID_FLOWING;
680         f.liquid_alternative_flowing = "water_flowing";
681         f.liquid_alternative_source = "water_source";
682         f.liquid_viscosity = WATER_VISC;
683         f.post_effect_color = video::SColor(64, 100, 100, 200);
684         f.setSpecialMaterial(0, MaterialSpec("water.png", false));
685         f.setSpecialMaterial(1, MaterialSpec("water.png", true));
686         nodemgr->set(i, f);
687
688         i = CONTENT_WATERSOURCE;
689         f = ContentFeatures();
690         f.name = "water_source";
691         f.drawtype = NDT_LIQUID;
692         f.setAllTextures("water.png");
693         f.alpha = WATER_ALPHA;
694         f.setInventoryTextureCube("water.png", "water.png", "water.png");
695         f.param_type = CPT_LIGHT;
696         f.light_propagates = true;
697         f.walkable = false;
698         f.pointable = false;
699         f.diggable = false;
700         f.buildable_to = true;
701         f.liquid_type = LIQUID_SOURCE;
702         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
703         f.liquid_alternative_flowing = "water_flowing";
704         f.liquid_alternative_source = "water_source";
705         f.liquid_viscosity = WATER_VISC;
706         f.post_effect_color = video::SColor(64, 100, 100, 200);
707         // New-style water source material (mostly unused)
708         f.setSpecialMaterial(0, MaterialSpec("water.png", false));
709         nodemgr->set(i, f);
710
711         i = CONTENT_LAVA;
712         f = ContentFeatures();
713         f.name = "lava_flowing";
714         f.drawtype = NDT_FLOWINGLIQUID;
715         f.setAllTextures("lava.png");
716         f.setInventoryTextureCube("lava.png", "lava.png", "lava.png");
717         f.param_type = CPT_LIGHT;
718         f.light_propagates = false;
719         f.light_source = LIGHT_MAX-1;
720         f.walkable = false;
721         f.pointable = false;
722         f.diggable = false;
723         f.buildable_to = true;
724         f.liquid_type = LIQUID_FLOWING;
725         f.liquid_alternative_flowing = "lava_flowing";
726         f.liquid_alternative_source = "lava_source";
727         f.liquid_viscosity = LAVA_VISC;
728         f.damage_per_second = 4*2;
729         f.post_effect_color = video::SColor(192, 255, 64, 0);
730         f.setSpecialMaterial(0, MaterialSpec("lava.png", false));
731         f.setSpecialMaterial(1, MaterialSpec("lava.png", true));
732         nodemgr->set(i, f);
733
734         i = CONTENT_LAVASOURCE;
735         f = ContentFeatures();
736         f.name = "lava_source";
737         f.drawtype = NDT_LIQUID;
738         f.setAllTextures("lava.png");
739         f.setInventoryTextureCube("lava.png", "lava.png", "lava.png");
740         f.param_type = CPT_LIGHT;
741         f.light_propagates = false;
742         f.light_source = LIGHT_MAX-1;
743         f.walkable = false;
744         f.pointable = false;
745         f.diggable = false;
746         f.buildable_to = true;
747         f.liquid_type = LIQUID_SOURCE;
748         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
749         f.liquid_alternative_flowing = "lava_flowing";
750         f.liquid_alternative_source = "lava_source";
751         f.liquid_viscosity = LAVA_VISC;
752         f.damage_per_second = 4*2;
753         f.post_effect_color = video::SColor(192, 255, 64, 0);
754         // New-style lava source material (mostly unused)
755         f.setSpecialMaterial(0, MaterialSpec("lava.png", false));
756         f.furnace_burntime = 60;
757         nodemgr->set(i, f);
758
759         i = CONTENT_TORCH;
760         f = ContentFeatures();
761         f.name = "torch";
762         f.drawtype = NDT_TORCHLIKE;
763         f.setTexture(0, "torch_on_floor.png");
764         f.setTexture(1, "torch_on_ceiling.png");
765         f.setTexture(2, "torch.png");
766         f.setInventoryTexture("torch_on_floor.png");
767         f.param_type = CPT_LIGHT;
768         f.light_propagates = true;
769         f.sunlight_propagates = true;
770         f.walkable = false;
771         f.wall_mounted = true;
772         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
773         f.light_source = LIGHT_MAX-1;
774         f.selection_box.type = NODEBOX_WALLMOUNTED;
775         f.selection_box.wall_top = core::aabbox3d<f32>(
776                         -BS/10, BS/2-BS/3.333*2, -BS/10, BS/10, BS/2, BS/10);
777         f.selection_box.wall_bottom = core::aabbox3d<f32>(
778                         -BS/10, -BS/2, -BS/10, BS/10, -BS/2+BS/3.333*2, BS/10);
779         f.selection_box.wall_side = core::aabbox3d<f32>(
780                         -BS/2, -BS/3.333, -BS/10, -BS/2+BS/3.333, BS/3.333, BS/10);
781         setConstantMaterialProperties(f.material, 0.0);
782         f.furnace_burntime = 4;
783         nodemgr->set(i, f);
784
785         i = CONTENT_SIGN_WALL;
786         f = ContentFeatures();
787         f.name = "sign_wall";
788         f.drawtype = NDT_SIGNLIKE;
789         f.setAllTextures("sign_wall.png");
790         f.setInventoryTexture("sign_wall.png");
791         f.param_type = CPT_LIGHT;
792         f.light_propagates = true;
793         f.sunlight_propagates = true;
794         f.walkable = false;
795         f.wall_mounted = true;
796         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
797         f.metadata_name = "sign";
798         setConstantMaterialProperties(f.material, 0.5);
799         f.selection_box.type = NODEBOX_WALLMOUNTED;
800         f.furnace_burntime = 10;
801         nodemgr->set(i, f);
802
803         i = CONTENT_CHEST;
804         f = ContentFeatures();
805         f.name = "chest";
806         f.param_type = CPT_FACEDIR_SIMPLE;
807         f.setAllTextures("chest_side.png");
808         f.setTexture(0, "chest_top.png");
809         f.setTexture(1, "chest_top.png");
810         f.setTexture(5, "chest_front.png"); // Z-
811         f.setInventoryTexture("chest_top.png");
812         //f.setInventoryTextureCube("chest_top.png", "chest_side.png", "chest_side.png");
813         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
814         f.metadata_name = "chest";
815         setWoodLikeMaterialProperties(f.material, 1.0);
816         f.furnace_burntime = 30;
817         nodemgr->set(i, f);
818
819         i = CONTENT_LOCKABLE_CHEST;
820         f = ContentFeatures();
821         f.name = "locked_chest";
822         f.param_type = CPT_FACEDIR_SIMPLE;
823         f.setAllTextures("chest_side.png");
824         f.setTexture(0, "chest_top.png");
825         f.setTexture(1, "chest_top.png");
826         f.setTexture(5, "chest_lock.png"); // Z-
827         f.setInventoryTexture("chest_lock.png");
828         //f.setInventoryTextureCube("chest_top.png", "chest_side.png", "chest_side.png");
829         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
830         f.metadata_name = "locked_chest";
831         setWoodLikeMaterialProperties(f.material, 1.0);
832         f.furnace_burntime = 30;
833         nodemgr->set(i, f);
834
835         i = CONTENT_FURNACE;
836         f = ContentFeatures();
837         f.name = "furnace";
838         f.param_type = CPT_FACEDIR_SIMPLE;
839         f.setAllTextures("furnace_side.png");
840         f.setTexture(5, "furnace_front.png"); // Z-
841         f.setInventoryTexture("furnace_front.png");
842         //f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
843         f.dug_item = std::string("MaterialItem2 ")+itos(CONTENT_COBBLE)+" 6";
844         f.metadata_name = "furnace";
845         setStoneLikeMaterialProperties(f.material, 3.0);
846         nodemgr->set(i, f);
847
848         i = CONTENT_COBBLE;
849         f = ContentFeatures();
850         f.name = "cobble";
851         f.setAllTextures("cobble.png");
852         f.setInventoryTextureCube("cobble.png", "cobble.png", "cobble.png");
853         f.param_type = CPT_NONE;
854         f.is_ground_content = true;
855         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
856         f.cookresult_item = std::string("MaterialItem2 ")+itos(CONTENT_STONE)+" 1";
857         setStoneLikeMaterialProperties(f.material, 0.9);
858         nodemgr->set(i, f);
859
860         i = CONTENT_MOSSYCOBBLE;
861         f = ContentFeatures();
862         f.name = "mossycobble";
863         f.setAllTextures("mossycobble.png");
864         f.setInventoryTextureCube("mossycobble.png", "mossycobble.png", "mossycobble.png");
865         f.param_type = CPT_NONE;
866         f.is_ground_content = true;
867         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
868         setStoneLikeMaterialProperties(f.material, 0.8);
869         nodemgr->set(i, f);
870
871         i = CONTENT_STEEL;
872         f = ContentFeatures();
873         f.name = "steelblock";
874         f.setAllTextures("steel_block.png");
875         f.setInventoryTextureCube("steel_block.png", "steel_block.png",
876                         "steel_block.png");
877         f.param_type = CPT_NONE;
878         f.is_ground_content = true;
879         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
880         setStoneLikeMaterialProperties(f.material, 5.0);
881         nodemgr->set(i, f);
882
883         i = CONTENT_NC;
884         f = ContentFeatures();
885         f.name = "nyancat";
886         f.param_type = CPT_FACEDIR_SIMPLE;
887         f.setAllTextures("nc_side.png");
888         f.setTexture(5, "nc_front.png"); // Z-
889         f.setTexture(4, "nc_back.png"); // Z+
890         f.setInventoryTexture("nc_front.png");
891         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
892         setStoneLikeMaterialProperties(f.material, 3.0);
893         f.furnace_burntime = 1;
894         nodemgr->set(i, f);
895
896         i = CONTENT_NC_RB;
897         f = ContentFeatures();
898         f.name = "nyancat_rainbow";
899         f.setAllTextures("nc_rb.png");
900         f.setInventoryTexture("nc_rb.png");
901         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
902         setStoneLikeMaterialProperties(f.material, 3.0);
903         f.furnace_burntime = 1;
904         nodemgr->set(i, f);
905
906         i = CONTENT_SAPLING;
907         f = ContentFeatures();
908         f.name = "sapling";
909         f.drawtype = NDT_PLANTLIKE;
910         f.visual_scale = 1.0;
911         f.setAllTextures("sapling.png");
912         f.setInventoryTexture("sapling.png");
913         f.param_type = CPT_LIGHT;
914         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
915         f.light_propagates = true;
916         f.walkable = false;
917         setConstantMaterialProperties(f.material, 0.0);
918         f.furnace_burntime = 10;
919         nodemgr->set(i, f);
920
921         i = CONTENT_APPLE;
922         f = ContentFeatures();
923         f.name = "apple";
924         f.drawtype = NDT_PLANTLIKE;
925         f.visual_scale = 1.0;
926         f.setAllTextures("apple.png");
927         f.setInventoryTexture("apple.png");
928         f.param_type = CPT_LIGHT;
929         f.light_propagates = true;
930         f.sunlight_propagates = true;
931         f.walkable = false;
932         f.dug_item = std::string("CraftItem apple 1");
933         setConstantMaterialProperties(f.material, 0.0);
934         f.furnace_burntime = 3;
935         nodemgr->set(i, f);
936 }
937
938