]> git.lizzy.rs Git - minetest.git/blob - src/content_mapnode.cpp
eda252dc178a25e6f4d06e3f98492682dab50ebf
[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.air_equivalent = false; // grass grows underneath
482         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
483         f.walkable = false;
484         setLeavesLikeMaterialProperties(f.material, 1.0);
485         f.furnace_burntime = 2;
486         nodemgr->set(i, f);
487
488         i = CONTENT_LEAVES;
489         f = ContentFeatures();
490         f.name = "leaves";
491         f.drawtype = NDT_ALLFACES_OPTIONAL;
492         f.setAllTextures("leaves.png");
493         //f.setAllTextures("[noalpha:leaves.png");
494         f.light_propagates = true;
495         f.param_type = CPT_LIGHT;
496         f.extra_dug_item = std::string("MaterialItem2 ")+itos(CONTENT_SAPLING)+" 1";
497         f.extra_dug_item_rarity = 20;
498         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
499         setLeavesLikeMaterialProperties(f.material, 1.0);
500         f.furnace_burntime = 1.0;
501         nodemgr->set(i, f);
502
503         i = CONTENT_CACTUS;
504         f = ContentFeatures();
505         f.name = "cactus";
506         f.setAllTextures("cactus_side.png");
507         f.setTexture(0, "cactus_top.png");
508         f.setTexture(1, "cactus_top.png");
509         f.setInventoryTextureCube("cactus_top.png", "cactus_side.png", "cactus_side.png");
510         f.param_type = CPT_MINERAL;
511         f.is_ground_content = true;
512         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
513         setWoodLikeMaterialProperties(f.material, 0.75);
514         f.furnace_burntime = 15;
515         nodemgr->set(i, f);
516
517         i = CONTENT_PAPYRUS;
518         f = ContentFeatures();
519         f.name = "papyrus";
520         f.drawtype = NDT_PLANTLIKE;
521         f.setAllTextures("papyrus.png");
522         f.setInventoryTexture("papyrus.png");
523         f.light_propagates = true;
524         f.param_type = CPT_LIGHT;
525         f.is_ground_content = true;
526         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
527         f.walkable = false;
528         setLeavesLikeMaterialProperties(f.material, 0.5);
529         f.furnace_burntime = 1;
530         nodemgr->set(i, f);
531
532         i = CONTENT_BOOKSHELF;
533         f = ContentFeatures();
534         f.name = "bookshelf";
535         f.setAllTextures("bookshelf.png");
536         f.setTexture(0, "wood.png");
537         f.setTexture(1, "wood.png");
538         // FIXME: setInventoryTextureCube() only cares for the first texture
539         f.setInventoryTextureCube("bookshelf.png", "bookshelf.png", "bookshelf.png");
540         //f.setInventoryTextureCube("wood.png", "bookshelf.png", "bookshelf.png");
541         f.param_type = CPT_MINERAL;
542         f.is_ground_content = true;
543         setWoodLikeMaterialProperties(f.material, 0.75);
544         f.furnace_burntime = 30;
545         nodemgr->set(i, f);
546
547         i = CONTENT_GLASS;
548         f = ContentFeatures();
549         f.name = "glass";
550         f.drawtype = NDT_GLASSLIKE;
551         f.setAllTextures("glass.png");
552         f.light_propagates = true;
553         f.sunlight_propagates = true;
554         f.param_type = CPT_LIGHT;
555         f.is_ground_content = true;
556         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
557         f.setInventoryTextureCube("glass.png", "glass.png", "glass.png");
558         setGlassLikeMaterialProperties(f.material, 1.0);
559         nodemgr->set(i, f);
560
561         i = CONTENT_FENCE;
562         f = ContentFeatures();
563         f.name = "wooden_fence";
564         f.drawtype = NDT_FENCELIKE;
565         f.setInventoryTexture("fence.png");
566         f.setTexture(0, "wood.png");
567         f.light_propagates = true;
568         f.param_type = CPT_LIGHT;
569         f.is_ground_content = true;
570         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
571         f.air_equivalent = true; // grass grows underneath
572         f.selection_box.type = NODEBOX_FIXED;
573         f.selection_box.fixed = core::aabbox3d<f32>(
574                         -BS/7, -BS/2, -BS/7, BS/7, BS/2, BS/7);
575         f.furnace_burntime = 30/2;
576         setWoodLikeMaterialProperties(f.material, 0.75);
577         nodemgr->set(i, f);
578
579         i = CONTENT_RAIL;
580         f = ContentFeatures();
581         f.name = "rail";
582         f.drawtype = NDT_RAILLIKE;
583         f.setInventoryTexture("rail.png");
584         f.setTexture(0, "rail.png");
585         f.setTexture(1, "rail_curved.png");
586         f.setTexture(2, "rail_t_junction.png");
587         f.setTexture(3, "rail_crossing.png");
588         f.light_propagates = true;
589         f.param_type = CPT_LIGHT;
590         f.is_ground_content = true;
591         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
592         f.air_equivalent = true; // grass grows underneath
593         f.walkable = false;
594         f.selection_box.type = NODEBOX_FIXED;
595         f.furnace_burntime = 5;
596         setDirtLikeMaterialProperties(f.material, 0.75);
597         nodemgr->set(i, f);
598
599         i = CONTENT_LADDER;
600         f = ContentFeatures();
601         f.name = "ladder";
602         f.drawtype = NDT_SIGNLIKE;
603         f.setAllTextures("ladder.png");
604         f.setInventoryTexture("ladder.png");
605         f.light_propagates = true;
606         f.param_type = CPT_LIGHT;
607         f.is_ground_content = true;
608         f.dug_item = std::string("MaterialItem ")+itos(i)+" 1";
609         f.wall_mounted = true;
610         f.air_equivalent = true;
611         f.walkable = false;
612         f.climbable = true;
613         f.selection_box.type = NODEBOX_WALLMOUNTED;
614         f.furnace_burntime = 5;
615         setWoodLikeMaterialProperties(f.material, 0.5);
616
617         nodemgr->set(i, f);
618
619         i = CONTENT_COALSTONE;
620         f = ContentFeatures();
621         f.name = "coalstone";
622         f.setAllTextures("stone.png^mineral_coal.png");
623         f.is_ground_content = true;
624         setStoneLikeMaterialProperties(f.material, 1.5);
625         nodemgr->set(i, f);
626
627         i = CONTENT_WOOD;
628         f = ContentFeatures();
629         f.name = "wood";
630         f.setAllTextures("wood.png");
631         f.setInventoryTextureCube("wood.png", "wood.png", "wood.png");
632         f.is_ground_content = true;
633         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
634         f.furnace_burntime = 30/4;
635         setWoodLikeMaterialProperties(f.material, 0.75);
636         nodemgr->set(i, f);
637
638         i = CONTENT_MESE;
639         f = ContentFeatures();
640         f.name = "mese";
641         f.setAllTextures("mese.png");
642         f.setInventoryTextureCube("mese.png", "mese.png", "mese.png");
643         f.is_ground_content = true;
644         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
645         f.furnace_burntime = 30;
646         setStoneLikeMaterialProperties(f.material, 0.5);
647         nodemgr->set(i, f);
648
649         i = CONTENT_CLOUD;
650         f = ContentFeatures();
651         f.name = "cloud";
652         f.setAllTextures("cloud.png");
653         f.setInventoryTextureCube("cloud.png", "cloud.png", "cloud.png");
654         f.is_ground_content = true;
655         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
656         nodemgr->set(i, f);
657
658         i = CONTENT_AIR;
659         f = ContentFeatures();
660         f.name = "air";
661         f.param_type = CPT_LIGHT;
662         f.light_propagates = true;
663         f.sunlight_propagates = true;
664         f.walkable = false;
665         f.pointable = false;
666         f.diggable = false;
667         f.buildable_to = true;
668         f.air_equivalent = true;
669         nodemgr->set(i, f);
670
671         i = CONTENT_WATER;
672         f = ContentFeatures();
673         f.name = "water_flowing";
674         f.drawtype = NDT_FLOWINGLIQUID;
675         f.setAllTextures("water.png");
676         f.alpha = WATER_ALPHA;
677         f.setInventoryTextureCube("water.png", "water.png", "water.png");
678         f.param_type = CPT_LIGHT;
679         f.light_propagates = true;
680         f.walkable = false;
681         f.pointable = false;
682         f.diggable = false;
683         f.buildable_to = true;
684         f.liquid_type = LIQUID_FLOWING;
685         f.liquid_alternative_flowing = CONTENT_WATER;
686         f.liquid_alternative_source = CONTENT_WATERSOURCE;
687         f.liquid_viscosity = WATER_VISC;
688         f.post_effect_color = video::SColor(64, 100, 100, 200);
689         f.setSpecialMaterial(0, MaterialSpec("water.png", false));
690         f.setSpecialMaterial(1, MaterialSpec("water.png", true));
691         nodemgr->set(i, f);
692
693         i = CONTENT_WATERSOURCE;
694         f = ContentFeatures();
695         f.name = "water_source";
696         f.drawtype = NDT_LIQUID;
697         f.setAllTextures("water.png");
698         f.alpha = WATER_ALPHA;
699         f.setInventoryTextureCube("water.png", "water.png", "water.png");
700         f.param_type = CPT_LIGHT;
701         f.light_propagates = true;
702         f.walkable = false;
703         f.pointable = false;
704         f.diggable = false;
705         f.buildable_to = true;
706         f.liquid_type = LIQUID_SOURCE;
707         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
708         f.liquid_alternative_flowing = CONTENT_WATER;
709         f.liquid_alternative_source = CONTENT_WATERSOURCE;
710         f.liquid_viscosity = WATER_VISC;
711         f.post_effect_color = video::SColor(64, 100, 100, 200);
712         // New-style water source material (mostly unused)
713         f.setSpecialMaterial(0, MaterialSpec("water.png", false));
714         nodemgr->set(i, f);
715
716         i = CONTENT_LAVA;
717         f = ContentFeatures();
718         f.name = "lava_flowing";
719         f.drawtype = NDT_FLOWINGLIQUID;
720         f.setAllTextures("lava.png");
721         f.setInventoryTextureCube("lava.png", "lava.png", "lava.png");
722         f.param_type = CPT_LIGHT;
723         f.light_propagates = false;
724         f.light_source = LIGHT_MAX-1;
725         f.walkable = false;
726         f.pointable = false;
727         f.diggable = false;
728         f.buildable_to = true;
729         f.liquid_type = LIQUID_FLOWING;
730         f.liquid_alternative_flowing = CONTENT_LAVA;
731         f.liquid_alternative_source = CONTENT_LAVASOURCE;
732         f.liquid_viscosity = LAVA_VISC;
733         f.damage_per_second = 4*2;
734         f.post_effect_color = video::SColor(192, 255, 64, 0);
735         f.setSpecialMaterial(0, MaterialSpec("lava.png", false));
736         f.setSpecialMaterial(1, MaterialSpec("lava.png", true));
737         nodemgr->set(i, f);
738
739         i = CONTENT_LAVASOURCE;
740         f = ContentFeatures();
741         f.name = "lava_source";
742         f.drawtype = NDT_LIQUID;
743         f.setAllTextures("lava.png");
744         f.setInventoryTextureCube("lava.png", "lava.png", "lava.png");
745         f.param_type = CPT_LIGHT;
746         f.light_propagates = false;
747         f.light_source = LIGHT_MAX-1;
748         f.walkable = false;
749         f.pointable = false;
750         f.diggable = false;
751         f.buildable_to = true;
752         f.liquid_type = LIQUID_SOURCE;
753         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
754         f.liquid_alternative_flowing = CONTENT_LAVA;
755         f.liquid_alternative_source = CONTENT_LAVASOURCE;
756         f.liquid_viscosity = LAVA_VISC;
757         f.damage_per_second = 4*2;
758         f.post_effect_color = video::SColor(192, 255, 64, 0);
759         // New-style lava source material (mostly unused)
760         f.setSpecialMaterial(0, MaterialSpec("lava.png", false));
761         f.furnace_burntime = 60;
762         nodemgr->set(i, f);
763
764         i = CONTENT_TORCH;
765         f = ContentFeatures();
766         f.name = "torch";
767         f.drawtype = NDT_TORCHLIKE;
768         f.setTexture(0, "torch_on_floor.png");
769         f.setTexture(1, "torch_on_ceiling.png");
770         f.setTexture(2, "torch.png");
771         f.setInventoryTexture("torch_on_floor.png");
772         f.param_type = CPT_LIGHT;
773         f.light_propagates = true;
774         f.sunlight_propagates = true;
775         f.walkable = false;
776         f.wall_mounted = true;
777         f.air_equivalent = true;
778         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
779         f.light_source = LIGHT_MAX-1;
780         f.selection_box.type = NODEBOX_WALLMOUNTED;
781         f.selection_box.wall_top = core::aabbox3d<f32>(
782                         -BS/10, BS/2-BS/3.333*2, -BS/10, BS/10, BS/2, BS/10);
783         f.selection_box.wall_bottom = core::aabbox3d<f32>(
784                         -BS/10, -BS/2, -BS/10, BS/10, -BS/2+BS/3.333*2, BS/10);
785         f.selection_box.wall_side = core::aabbox3d<f32>(
786                         -BS/2, -BS/3.333, -BS/10, -BS/2+BS/3.333, BS/3.333, BS/10);
787         setConstantMaterialProperties(f.material, 0.0);
788         f.furnace_burntime = 4;
789         nodemgr->set(i, f);
790
791         i = CONTENT_SIGN_WALL;
792         f = ContentFeatures();
793         f.name = "sign_wall";
794         f.drawtype = NDT_SIGNLIKE;
795         f.setAllTextures("sign_wall.png");
796         f.setInventoryTexture("sign_wall.png");
797         f.param_type = CPT_LIGHT;
798         f.light_propagates = true;
799         f.sunlight_propagates = true;
800         f.walkable = false;
801         f.wall_mounted = true;
802         f.air_equivalent = true;
803         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
804         f.metadata_name = "sign";
805         setConstantMaterialProperties(f.material, 0.5);
806         f.selection_box.type = NODEBOX_WALLMOUNTED;
807         f.furnace_burntime = 10;
808         nodemgr->set(i, f);
809
810         i = CONTENT_CHEST;
811         f = ContentFeatures();
812         f.name = "chest";
813         f.param_type = CPT_FACEDIR_SIMPLE;
814         f.setAllTextures("chest_side.png");
815         f.setTexture(0, "chest_top.png");
816         f.setTexture(1, "chest_top.png");
817         f.setTexture(5, "chest_front.png"); // Z-
818         f.setInventoryTexture("chest_top.png");
819         //f.setInventoryTextureCube("chest_top.png", "chest_side.png", "chest_side.png");
820         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
821         f.metadata_name = "chest";
822         setWoodLikeMaterialProperties(f.material, 1.0);
823         f.furnace_burntime = 30;
824         nodemgr->set(i, f);
825
826         i = CONTENT_LOCKABLE_CHEST;
827         f = ContentFeatures();
828         f.name = "locked_chest";
829         f.param_type = CPT_FACEDIR_SIMPLE;
830         f.setAllTextures("chest_side.png");
831         f.setTexture(0, "chest_top.png");
832         f.setTexture(1, "chest_top.png");
833         f.setTexture(5, "chest_lock.png"); // Z-
834         f.setInventoryTexture("chest_lock.png");
835         //f.setInventoryTextureCube("chest_top.png", "chest_side.png", "chest_side.png");
836         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
837         f.metadata_name = "locked_chest";
838         setWoodLikeMaterialProperties(f.material, 1.0);
839         f.furnace_burntime = 30;
840         nodemgr->set(i, f);
841
842         i = CONTENT_FURNACE;
843         f = ContentFeatures();
844         f.name = "furnace";
845         f.param_type = CPT_FACEDIR_SIMPLE;
846         f.setAllTextures("furnace_side.png");
847         f.setTexture(5, "furnace_front.png"); // Z-
848         f.setInventoryTexture("furnace_front.png");
849         //f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
850         f.dug_item = std::string("MaterialItem2 ")+itos(CONTENT_COBBLE)+" 6";
851         f.metadata_name = "furnace";
852         setStoneLikeMaterialProperties(f.material, 3.0);
853         nodemgr->set(i, f);
854
855         i = CONTENT_COBBLE;
856         f = ContentFeatures();
857         f.name = "cobble";
858         f.setAllTextures("cobble.png");
859         f.setInventoryTextureCube("cobble.png", "cobble.png", "cobble.png");
860         f.param_type = CPT_NONE;
861         f.is_ground_content = true;
862         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
863         f.cookresult_item = std::string("MaterialItem2 ")+itos(CONTENT_STONE)+" 1";
864         setStoneLikeMaterialProperties(f.material, 0.9);
865         nodemgr->set(i, f);
866
867         i = CONTENT_MOSSYCOBBLE;
868         f = ContentFeatures();
869         f.name = "mossycobble";
870         f.setAllTextures("mossycobble.png");
871         f.setInventoryTextureCube("mossycobble.png", "mossycobble.png", "mossycobble.png");
872         f.param_type = CPT_NONE;
873         f.is_ground_content = true;
874         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
875         setStoneLikeMaterialProperties(f.material, 0.8);
876         nodemgr->set(i, f);
877
878         i = CONTENT_STEEL;
879         f = ContentFeatures();
880         f.name = "steelblock";
881         f.setAllTextures("steel_block.png");
882         f.setInventoryTextureCube("steel_block.png", "steel_block.png",
883                         "steel_block.png");
884         f.param_type = CPT_NONE;
885         f.is_ground_content = true;
886         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
887         setStoneLikeMaterialProperties(f.material, 5.0);
888         nodemgr->set(i, f);
889
890         i = CONTENT_NC;
891         f = ContentFeatures();
892         f.name = "nyancat";
893         f.param_type = CPT_FACEDIR_SIMPLE;
894         f.setAllTextures("nc_side.png");
895         f.setTexture(5, "nc_front.png"); // Z-
896         f.setTexture(4, "nc_back.png"); // Z+
897         f.setInventoryTexture("nc_front.png");
898         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
899         setStoneLikeMaterialProperties(f.material, 3.0);
900         f.furnace_burntime = 1;
901         nodemgr->set(i, f);
902
903         i = CONTENT_NC_RB;
904         f = ContentFeatures();
905         f.name = "nyancat_rainbow";
906         f.setAllTextures("nc_rb.png");
907         f.setInventoryTexture("nc_rb.png");
908         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
909         setStoneLikeMaterialProperties(f.material, 3.0);
910         f.furnace_burntime = 1;
911         nodemgr->set(i, f);
912
913         i = CONTENT_SAPLING;
914         f = ContentFeatures();
915         f.name = "sapling";
916         f.drawtype = NDT_PLANTLIKE;
917         f.visual_scale = 1.0;
918         f.setAllTextures("sapling.png");
919         f.setInventoryTexture("sapling.png");
920         f.param_type = CPT_LIGHT;
921         f.dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
922         f.light_propagates = true;
923         f.air_equivalent = false;
924         f.walkable = false;
925         setConstantMaterialProperties(f.material, 0.0);
926         f.furnace_burntime = 10;
927         nodemgr->set(i, f);
928
929         i = CONTENT_APPLE;
930         f = ContentFeatures();
931         f.name = "apple";
932         f.drawtype = NDT_PLANTLIKE;
933         f.visual_scale = 1.0;
934         f.setAllTextures("apple.png");
935         f.setInventoryTexture("apple.png");
936         f.param_type = CPT_LIGHT;
937         f.light_propagates = true;
938         f.sunlight_propagates = true;
939         f.walkable = false;
940         f.air_equivalent = true;
941         f.dug_item = std::string("CraftItem apple 1");
942         setConstantMaterialProperties(f.material, 0.0);
943         f.furnace_burntime = 3;
944         nodemgr->set(i, f);
945 }
946
947