Generalize selection boxes
[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 // For g_settings
21 #include "main.h"
22
23 #include "content_mapnode.h"
24 #include "mapnode.h"
25 #include "content_nodemeta.h"
26 #include "settings.h"
27 #include "mapnode_contentfeatures.h"
28
29 #define WATER_ALPHA 160
30
31 #define WATER_VISC 1
32 #define LAVA_VISC 7
33
34 // TODO: Get rid of these and set up some attributes like toughness,
35 //       fluffyness, and a funciton to calculate time and durability loss
36 //       (and sound? and whatever else) from them
37 void setStoneLikeDiggingProperties(DiggingPropertiesList &list, float toughness);
38 void setDirtLikeDiggingProperties(DiggingPropertiesList &list, float toughness);
39 void setWoodLikeDiggingProperties(DiggingPropertiesList &list, float toughness);
40
41 /*
42         A conversion table for backwards compatibility.
43         Maps <=v19 content types to current ones.
44         Should never be touched.
45 */
46 content_t trans_table_19[21][2] = {
47         {CONTENT_GRASS, 1},
48         {CONTENT_TREE, 4},
49         {CONTENT_LEAVES, 5},
50         {CONTENT_GRASS_FOOTSTEPS, 6},
51         {CONTENT_MESE, 7},
52         {CONTENT_MUD, 8},
53         {CONTENT_CLOUD, 10},
54         {CONTENT_COALSTONE, 11},
55         {CONTENT_WOOD, 12},
56         {CONTENT_SAND, 13},
57         {CONTENT_COBBLE, 18},
58         {CONTENT_STEEL, 19},
59         {CONTENT_GLASS, 20},
60         {CONTENT_MOSSYCOBBLE, 22},
61         {CONTENT_GRAVEL, 23},
62         {CONTENT_SANDSTONE, 24},
63         {CONTENT_CACTUS, 25},
64         {CONTENT_BRICK, 26},
65         {CONTENT_CLAY, 27},
66         {CONTENT_PAPYRUS, 28},
67         {CONTENT_BOOKSHELF, 29},
68 };
69
70 MapNode mapnode_translate_from_internal(MapNode n_from, u8 version)
71 {
72         MapNode result = n_from;
73         if(version <= 19)
74         {
75                 content_t c_from = n_from.getContent();
76                 for(u32 i=0; i<sizeof(trans_table_19)/sizeof(trans_table_19[0]); i++)
77                 {
78                         if(trans_table_19[i][0] == c_from)
79                         {
80                                 result.setContent(trans_table_19[i][1]);
81                                 break;
82                         }
83                 }
84         }
85         return result;
86 }
87 MapNode mapnode_translate_to_internal(MapNode n_from, u8 version)
88 {
89         MapNode result = n_from;
90         if(version <= 19)
91         {
92                 content_t c_from = n_from.getContent();
93                 for(u32 i=0; i<sizeof(trans_table_19)/sizeof(trans_table_19[0]); i++)
94                 {
95                         if(trans_table_19[i][1] == c_from)
96                         {
97                                 result.setContent(trans_table_19[i][0]);
98                                 break;
99                         }
100                 }
101         }
102         return result;
103 }
104
105 // See header for description
106 void content_mapnode_init()
107 {
108         if(g_texturesource == NULL)
109                 dstream<<"INFO: Initial run of content_mapnode_init with "
110                                 "g_texturesource=NULL. If this segfaults, "
111                                 "there is a bug with something not checking for "
112                                 "the NULL value."<<std::endl;
113         else
114                 dstream<<"INFO: Full run of content_mapnode_init with "
115                                 "g_texturesource!=NULL"<<std::endl;
116
117         // Read some settings
118         bool new_style_water = g_settings->getBool("new_style_water");
119         bool new_style_leaves = g_settings->getBool("new_style_leaves");
120         bool invisible_stone = g_settings->getBool("invisible_stone");
121         bool opaque_water = g_settings->getBool("opaque_water");
122
123         content_t i;
124         ContentFeatures *f = NULL;
125
126         i = CONTENT_STONE;
127         f = &content_features(i);
128         f->setAllTextures("stone.png");
129         f->setInventoryTextureCube("stone.png", "stone.png", "stone.png");
130         f->param_type = CPT_MINERAL;
131         f->is_ground_content = true;
132         f->often_contains_mineral = true;
133         f->dug_item = std::string("MaterialItem2 ")+itos(CONTENT_COBBLE)+" 1";
134         setStoneLikeDiggingProperties(f->digging_properties, 1.0);
135         if(invisible_stone)
136                 f->solidness = 0; // For debugging, hides regular stone
137         
138         i = CONTENT_GRASS;
139         f = &content_features(i);
140         f->setAllTextures("mud.png^grass_side.png");
141         f->setTexture(0, "grass.png");
142         f->setTexture(1, "mud.png");
143         f->param_type = CPT_MINERAL;
144         f->is_ground_content = true;
145         f->dug_item = std::string("MaterialItem2 ")+itos(CONTENT_MUD)+" 1";
146         setDirtLikeDiggingProperties(f->digging_properties, 1.0);
147         
148         i = CONTENT_GRASS_FOOTSTEPS;
149         f = &content_features(i);
150         f->setAllTextures("mud.png^grass_side.png");
151         f->setTexture(0, "grass_footsteps.png");
152         f->setTexture(1, "mud.png");
153         f->param_type = CPT_MINERAL;
154         f->is_ground_content = true;
155         f->dug_item = std::string("MaterialItem2 ")+itos(CONTENT_MUD)+" 1";
156         setDirtLikeDiggingProperties(f->digging_properties, 1.0);
157         
158         i = CONTENT_MUD;
159         f = &content_features(i);
160         f->setAllTextures("mud.png");
161         f->setInventoryTextureCube("mud.png", "mud.png", "mud.png");
162         f->param_type = CPT_MINERAL;
163         f->is_ground_content = true;
164         f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
165         setDirtLikeDiggingProperties(f->digging_properties, 1.0);
166         
167         i = CONTENT_SAND;
168         f = &content_features(i);
169         f->setAllTextures("sand.png");
170         f->setInventoryTextureCube("sand.png", "sand.png", "sand.png");
171         f->param_type = CPT_MINERAL;
172         f->is_ground_content = true;
173         f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
174         setDirtLikeDiggingProperties(f->digging_properties, 1.0);
175         
176         i = CONTENT_GRAVEL;
177         f = &content_features(i);
178         f->setAllTextures("gravel.png");
179         f->setInventoryTextureCube("gravel.png", "gravel.png", "gravel.png");
180         f->param_type = CPT_MINERAL;
181         f->is_ground_content = true;
182         f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
183         setDirtLikeDiggingProperties(f->digging_properties, 1.75);
184         
185         i = CONTENT_SANDSTONE;
186         f = &content_features(i);
187         f->setAllTextures("sandstone.png");
188         f->setInventoryTextureCube("sandstone.png", "sandstone.png", "sandstone.png");
189         f->param_type = CPT_MINERAL;
190         f->is_ground_content = true;
191         f->dug_item = std::string("MaterialItem2 ")+itos(CONTENT_SAND)+" 1";
192         setDirtLikeDiggingProperties(f->digging_properties, 1.0);
193
194         i = CONTENT_CLAY;
195         f = &content_features(i);
196         f->setAllTextures("clay.png");
197         f->setInventoryTextureCube("clay.png", "clay.png", "clay.png");
198         f->param_type = CPT_MINERAL;
199         f->is_ground_content = true;
200         f->dug_item = std::string("CraftItem lump_of_clay 4");
201         setDirtLikeDiggingProperties(f->digging_properties, 1.0);
202
203         i = CONTENT_BRICK;
204         f = &content_features(i);
205         f->setAllTextures("brick.png");
206         f->setInventoryTextureCube("brick.png", "brick.png", "brick.png");
207         f->param_type = CPT_MINERAL;
208         f->is_ground_content = true;
209         f->dug_item = std::string("CraftItem clay_brick 4");
210         setStoneLikeDiggingProperties(f->digging_properties, 1.0);
211
212         i = CONTENT_TREE;
213         f = &content_features(i);
214         f->setAllTextures("tree.png");
215         f->setTexture(0, "tree_top.png");
216         f->setTexture(1, "tree_top.png");
217         f->param_type = CPT_MINERAL;
218         f->is_ground_content = true;
219         f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
220         setWoodLikeDiggingProperties(f->digging_properties, 1.0);
221         
222         i = CONTENT_JUNGLETREE;
223         f = &content_features(i);
224         f->setAllTextures("jungletree.png");
225         f->setTexture(0, "jungletree_top.png");
226         f->setTexture(1, "jungletree_top.png");
227         f->param_type = CPT_MINERAL;
228         //f->is_ground_content = true;
229         f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
230         setWoodLikeDiggingProperties(f->digging_properties, 1.0);
231         
232         i = CONTENT_JUNGLEGRASS;
233         f = &content_features(i);
234         f->setInventoryTexture("junglegrass.png");
235         f->used_texturenames["junglegrass.png"] = true;
236         f->light_propagates = true;
237         f->param_type = CPT_LIGHT;
238         //f->is_ground_content = true;
239         f->air_equivalent = false; // grass grows underneath
240         f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
241         f->solidness = 0; // drawn separately, makes no faces
242         f->walkable = false;
243         setWoodLikeDiggingProperties(f->digging_properties, 0.10);
244
245         i = CONTENT_LEAVES;
246         f = &content_features(i);
247         f->light_propagates = true;
248         //f->param_type = CPT_MINERAL;
249         f->param_type = CPT_LIGHT;
250         //f->is_ground_content = true;
251         if(new_style_leaves)
252         {
253                 f->solidness = 0; // drawn separately, makes no faces
254                 f->visual_solidness = 1;
255                 f->setAllTextures("leaves.png");
256                 f->setInventoryTextureCube("leaves.png", "leaves.png", "leaves.png");
257         }
258         else
259         {
260                 f->setAllTextures("[noalpha:leaves.png");
261         }
262         f->extra_dug_item = std::string("MaterialItem2 ")+itos(CONTENT_SAPLING)+" 1";
263         f->extra_dug_item_rarity = 20;
264         f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
265         setWoodLikeDiggingProperties(f->digging_properties, 0.15);
266
267         i = CONTENT_CACTUS;
268         f = &content_features(i);
269         f->setAllTextures("cactus_side.png");
270         f->setTexture(0, "cactus_top.png");
271         f->setTexture(1, "cactus_top.png");
272         f->setInventoryTextureCube("cactus_top.png", "cactus_side.png", "cactus_side.png");
273         f->param_type = CPT_MINERAL;
274         f->is_ground_content = true;
275         f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
276         setWoodLikeDiggingProperties(f->digging_properties, 0.75);
277
278         i = CONTENT_PAPYRUS;
279         f = &content_features(i);
280         f->setInventoryTexture("papyrus.png");
281         f->used_texturenames["papyrus.png"] = true;
282         f->light_propagates = true;
283         f->param_type = CPT_LIGHT;
284         f->is_ground_content = true;
285         f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
286         f->solidness = 0; // drawn separately, makes no faces
287         f->walkable = false;
288         setWoodLikeDiggingProperties(f->digging_properties, 0.25);
289
290         i = CONTENT_BOOKSHELF;
291         f = &content_features(i);
292         f->setAllTextures("bookshelf.png");
293         f->setTexture(0, "wood.png");
294         f->setTexture(1, "wood.png");
295         // FIXME: setInventoryTextureCube() only cares for the first texture
296         f->setInventoryTextureCube("bookshelf.png", "bookshelf.png", "bookshelf.png");
297         //f->setInventoryTextureCube("wood.png", "bookshelf.png", "bookshelf.png");
298         f->param_type = CPT_MINERAL;
299         f->is_ground_content = true;
300         setWoodLikeDiggingProperties(f->digging_properties, 0.75);
301
302         i = CONTENT_GLASS;
303         f = &content_features(i);
304         f->light_propagates = true;
305         f->sunlight_propagates = true;
306         f->param_type = CPT_LIGHT;
307         f->is_ground_content = true;
308         f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
309         f->solidness = 0; // drawn separately, makes no faces
310         f->visual_solidness = 1;
311         f->setAllTextures("glass.png");
312         f->setInventoryTextureCube("glass.png", "glass.png", "glass.png");
313         setWoodLikeDiggingProperties(f->digging_properties, 0.15);
314
315         i = CONTENT_FENCE;
316         f = &content_features(i);
317         f->light_propagates = true;
318         f->param_type = CPT_LIGHT;
319         f->is_ground_content = true;
320         f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
321         f->solidness = 0; // drawn separately, makes no faces
322         f->air_equivalent = true; // grass grows underneath
323         f->setInventoryTexture("fence.png");
324         f->used_texturenames["fence.png"] = true;
325         setWoodLikeDiggingProperties(f->digging_properties, 0.75);
326
327         i = CONTENT_RAIL;
328         f = &content_features(i);
329         f->setInventoryTexture("rail.png");
330         f->used_texturenames["rail.png"] = true;
331         f->light_propagates = true;
332         f->param_type = CPT_LIGHT;
333         f->is_ground_content = true;
334         f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
335         f->solidness = 0; // drawn separately, makes no faces
336         f->air_equivalent = true; // grass grows underneath
337         f->walkable = false;
338         f->selection_box.type = NODEBOX_FIXED;
339         setDirtLikeDiggingProperties(f->digging_properties, 0.75);
340
341         i = CONTENT_LADDER;
342         f = &content_features(i);
343         f->setInventoryTexture("ladder.png");
344         f->used_texturenames["ladder.png"] = true;
345         f->light_propagates = true;
346         f->param_type = CPT_LIGHT;
347         f->is_ground_content = true;
348         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
349         f->wall_mounted = true;
350         f->solidness = 0;
351         f->air_equivalent = true;
352         f->walkable = false;
353         f->climbable = true;
354         f->selection_box.type = NODEBOX_WALLMOUNTED;
355         setWoodLikeDiggingProperties(f->digging_properties, 0.5);
356
357         // Deprecated
358         i = CONTENT_COALSTONE;
359         f = &content_features(i);
360         f->setAllTextures("stone.png^mineral_coal.png");
361         f->is_ground_content = true;
362         setStoneLikeDiggingProperties(f->digging_properties, 1.5);
363         
364         i = CONTENT_WOOD;
365         f = &content_features(i);
366         f->setAllTextures("wood.png");
367         f->setInventoryTextureCube("wood.png", "wood.png", "wood.png");
368         f->is_ground_content = true;
369         f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
370         setWoodLikeDiggingProperties(f->digging_properties, 0.75);
371         
372         i = CONTENT_MESE;
373         f = &content_features(i);
374         f->setAllTextures("mese.png");
375         f->setInventoryTextureCube("mese.png", "mese.png", "mese.png");
376         f->is_ground_content = true;
377         f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
378         setStoneLikeDiggingProperties(f->digging_properties, 0.5);
379         
380         i = CONTENT_CLOUD;
381         f = &content_features(i);
382         f->setAllTextures("cloud.png");
383         f->setInventoryTextureCube("cloud.png", "cloud.png", "cloud.png");
384         f->is_ground_content = true;
385         f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
386         
387         i = CONTENT_AIR;
388         f = &content_features(i);
389         f->param_type = CPT_LIGHT;
390         f->light_propagates = true;
391         f->sunlight_propagates = true;
392         f->solidness = 0;
393         f->walkable = false;
394         f->pointable = false;
395         f->diggable = false;
396         f->buildable_to = true;
397         f->air_equivalent = true;
398         
399         i = CONTENT_WATER;
400         f = &content_features(i);
401         f->setInventoryTextureCube("water.png", "water.png", "water.png");
402         f->param_type = CPT_LIGHT;
403         f->light_propagates = true;
404         f->solidness = 0; // Drawn separately, makes no faces
405         f->visual_solidness = 1;
406         f->walkable = false;
407         f->pointable = false;
408         f->diggable = false;
409         f->buildable_to = true;
410         f->liquid_type = LIQUID_FLOWING;
411         f->liquid_alternative_flowing = CONTENT_WATER;
412         f->liquid_alternative_source = CONTENT_WATERSOURCE;
413         f->liquid_viscosity = WATER_VISC;
414 #ifndef SERVER
415         if(!opaque_water)
416                 f->vertex_alpha = WATER_ALPHA;
417         f->post_effect_color = video::SColor(64, 100, 100, 200);
418         if(f->special_material == NULL && g_texturesource)
419         {
420                 // Flowing water material
421                 f->special_material = new video::SMaterial;
422                 f->special_material->setFlag(video::EMF_LIGHTING, false);
423                 f->special_material->setFlag(video::EMF_BACK_FACE_CULLING, false);
424                 f->special_material->setFlag(video::EMF_BILINEAR_FILTER, false);
425                 f->special_material->setFlag(video::EMF_FOG_ENABLE, true);
426                 if(!opaque_water)
427                         f->special_material->MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
428                 AtlasPointer *pa_water1 = new AtlasPointer(g_texturesource->getTexture(
429                                 g_texturesource->getTextureId("water.png")));
430                 f->special_material->setTexture(0, pa_water1->atlas);
431
432                 // Flowing water material, backface culled
433                 f->special_material2 = new video::SMaterial;
434                 *f->special_material2 = *f->special_material;
435                 f->special_material2->setFlag(video::EMF_BACK_FACE_CULLING, true);
436                 
437                 f->special_atlas = pa_water1;
438         }
439 #endif
440         
441         i = CONTENT_WATERSOURCE;
442         f = &content_features(i);
443         //f->setInventoryTexture("water.png");
444         f->setInventoryTextureCube("water.png", "water.png", "water.png");
445         if(new_style_water)
446         {
447                 f->solidness = 0; // drawn separately, makes no faces
448         }
449         else // old style
450         {
451                 f->solidness = 1;
452 #ifndef SERVER
453                 TileSpec t;
454                 if(g_texturesource)
455                         t.texture = g_texturesource->getTexture("water.png");
456                 
457                 if(!opaque_water){
458                         t.alpha = WATER_ALPHA;
459                         t.material_type = MATERIAL_ALPHA_VERTEX;
460                 }
461                 t.material_flags &= ~MATERIAL_FLAG_BACKFACE_CULLING;
462                 f->setAllTiles(t);
463 #endif
464         }
465         f->param_type = CPT_LIGHT;
466         f->light_propagates = true;
467         f->walkable = false;
468         f->pointable = false;
469         f->diggable = false;
470         f->buildable_to = true;
471         f->liquid_type = LIQUID_SOURCE;
472         f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
473         f->liquid_alternative_flowing = CONTENT_WATER;
474         f->liquid_alternative_source = CONTENT_WATERSOURCE;
475         f->liquid_viscosity = WATER_VISC;
476 #ifndef SERVER
477         if(!opaque_water)
478                 f->vertex_alpha = WATER_ALPHA;
479         f->post_effect_color = video::SColor(64, 100, 100, 200);
480         if(f->special_material == NULL && g_texturesource)
481         {
482                 // New-style water source material (mostly unused)
483                 f->special_material = new video::SMaterial;
484                 f->special_material->setFlag(video::EMF_LIGHTING, false);
485                 f->special_material->setFlag(video::EMF_BACK_FACE_CULLING, false);
486                 f->special_material->setFlag(video::EMF_BILINEAR_FILTER, false);
487                 f->special_material->setFlag(video::EMF_FOG_ENABLE, true);
488                 f->special_material->MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
489                 AtlasPointer *pa_water1 = new AtlasPointer(g_texturesource->getTexture(
490                                 g_texturesource->getTextureId("water.png")));
491                 f->special_material->setTexture(0, pa_water1->atlas);
492                 f->special_atlas = pa_water1;
493         }
494 #endif
495         
496         i = CONTENT_LAVA;
497         f = &content_features(i);
498         f->setInventoryTextureCube("lava.png", "lava.png", "lava.png");
499         f->used_texturenames["lava.png"] = true;
500         f->param_type = CPT_LIGHT;
501         f->light_propagates = false;
502         f->light_source = LIGHT_MAX-1;
503         f->solidness = 0; // Drawn separately, makes no faces
504         f->visual_solidness = 1; // Does not completely cover block boundaries
505         f->walkable = false;
506         f->pointable = false;
507         f->diggable = false;
508         f->buildable_to = true;
509         f->liquid_type = LIQUID_FLOWING;
510         f->liquid_alternative_flowing = CONTENT_LAVA;
511         f->liquid_alternative_source = CONTENT_LAVASOURCE;
512         f->liquid_viscosity = LAVA_VISC;
513         f->damage_per_second = 4*2;
514 #ifndef SERVER
515         f->post_effect_color = video::SColor(192, 255, 64, 0);
516         if(f->special_material == NULL && g_texturesource)
517         {
518                 // Flowing lava material
519                 f->special_material = new video::SMaterial;
520                 f->special_material->setFlag(video::EMF_LIGHTING, false);
521                 f->special_material->setFlag(video::EMF_BACK_FACE_CULLING, false);
522                 f->special_material->setFlag(video::EMF_BILINEAR_FILTER, false);
523                 f->special_material->setFlag(video::EMF_FOG_ENABLE, true);
524                 f->special_material->MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
525
526                 AtlasPointer *pa_lava1 = new AtlasPointer(
527                         g_texturesource->getTexture(
528                                 g_texturesource->getTextureId("lava.png")));
529                 f->special_material->setTexture(0, pa_lava1->atlas);
530
531                 // Flowing lava material, backface culled
532                 f->special_material2 = new video::SMaterial;
533                 *f->special_material2 = *f->special_material;
534                 f->special_material2->setFlag(video::EMF_BACK_FACE_CULLING, true);
535
536                 f->special_atlas = pa_lava1;
537         }
538 #endif
539         
540         i = CONTENT_LAVASOURCE;
541         f = &content_features(i);
542         f->setInventoryTextureCube("lava.png", "lava.png", "lava.png");
543         f->used_texturenames["ladder.png"] = true;
544         if(new_style_water)
545         {
546                 f->solidness = 0; // drawn separately, makes no faces
547         }
548         else // old style
549         {
550                 f->solidness = 2;
551 #ifndef SERVER
552                 TileSpec t;
553                 if(g_texturesource)
554                         t.texture = g_texturesource->getTexture("lava.png");
555                 
556                 //t.alpha = 255;
557                 //t.material_type = MATERIAL_ALPHA_VERTEX;
558                 //t.material_flags &= ~MATERIAL_FLAG_BACKFACE_CULLING;
559                 f->setAllTiles(t);
560 #endif
561         }
562         f->param_type = CPT_LIGHT;
563         f->light_propagates = false;
564         f->light_source = LIGHT_MAX-1;
565         f->walkable = false;
566         f->pointable = false;
567         f->diggable = false;
568         f->buildable_to = true;
569         f->liquid_type = LIQUID_SOURCE;
570         f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
571         f->liquid_alternative_flowing = CONTENT_LAVA;
572         f->liquid_alternative_source = CONTENT_LAVASOURCE;
573         f->liquid_viscosity = LAVA_VISC;
574         f->damage_per_second = 4*2;
575 #ifndef SERVER
576         f->post_effect_color = video::SColor(192, 255, 64, 0);
577         if(f->special_material == NULL && g_texturesource)
578         {
579                 // New-style lava source material (mostly unused)
580                 f->special_material = new video::SMaterial;
581                 f->special_material->setFlag(video::EMF_LIGHTING, false);
582                 f->special_material->setFlag(video::EMF_BACK_FACE_CULLING, false);
583                 f->special_material->setFlag(video::EMF_BILINEAR_FILTER, false);
584                 f->special_material->setFlag(video::EMF_FOG_ENABLE, true);
585                 f->special_material->MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
586                 AtlasPointer *pa_lava1 = new AtlasPointer(
587                         g_texturesource->getTexture(
588                                 g_texturesource->getTextureId("lava.png")));
589                 f->special_material->setTexture(0, pa_lava1->atlas);
590
591                 f->special_atlas = pa_lava1;
592         }
593 #endif
594         
595         i = CONTENT_TORCH;
596         f = &content_features(i);
597         f->setInventoryTexture("torch_on_floor.png");
598         f->used_texturenames["torch_on_floor.png"] = true;
599         f->used_texturenames["torch_on_ceiling.png"] = true;
600         f->used_texturenames["torch_on_floor.png"] = true;
601         f->used_texturenames["torch.png"] = true;
602         f->param_type = CPT_LIGHT;
603         f->light_propagates = true;
604         f->sunlight_propagates = true;
605         f->solidness = 0; // drawn separately, makes no faces
606         f->walkable = false;
607         f->wall_mounted = true;
608         f->air_equivalent = true;
609         f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
610         f->light_source = LIGHT_MAX-1;
611         f->selection_box.type = NODEBOX_WALLMOUNTED;
612         f->selection_box.wall_top = core::aabbox3d<f32>(
613                         -BS/10, BS/2-BS/3.333*2, -BS/10, BS/10, BS/2, BS/10);
614         f->selection_box.wall_bottom = core::aabbox3d<f32>(
615                         -BS/10, -BS/2, -BS/10, BS/10, -BS/2+BS/3.333*2, BS/10);
616         f->selection_box.wall_side = core::aabbox3d<f32>(
617                         -BS/2, -BS/3.333, -BS/10, -BS/2+BS/3.333, BS/3.333, BS/10);
618         f->digging_properties.set("", DiggingProperties(true, 0.0, 0));
619         
620         i = CONTENT_SIGN_WALL;
621         f = &content_features(i);
622         f->setInventoryTexture("sign_wall.png");
623         f->used_texturenames["sign_wall.png"] = true;
624         f->param_type = CPT_LIGHT;
625         f->light_propagates = true;
626         f->sunlight_propagates = true;
627         f->solidness = 0; // drawn separately, makes no faces
628         f->walkable = false;
629         f->wall_mounted = true;
630         f->air_equivalent = true;
631         f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
632         if(f->initial_metadata == NULL)
633                 f->initial_metadata = new SignNodeMetadata("Some sign");
634         f->digging_properties.set("", DiggingProperties(true, 0.5, 0));
635         f->selection_box.type = NODEBOX_WALLMOUNTED;
636         
637         i = CONTENT_CHEST;
638         f = &content_features(i);
639         f->param_type = CPT_FACEDIR_SIMPLE;
640         f->setAllTextures("chest_side.png");
641         f->setTexture(0, "chest_top.png");
642         f->setTexture(1, "chest_top.png");
643         f->setTexture(5, "chest_front.png"); // Z-
644         f->setInventoryTexture("chest_top.png");
645         //f->setInventoryTextureCube("chest_top.png", "chest_side.png", "chest_side.png");
646         f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
647         if(f->initial_metadata == NULL)
648                 f->initial_metadata = new ChestNodeMetadata();
649         setWoodLikeDiggingProperties(f->digging_properties, 1.0);
650         
651         i = CONTENT_LOCKABLE_CHEST;
652         f = &content_features(i);
653         f->param_type = CPT_FACEDIR_SIMPLE;
654         f->setAllTextures("chest_side.png");
655         f->setTexture(0, "chest_top.png");
656         f->setTexture(1, "chest_top.png");
657         f->setTexture(5, "chest_lock.png"); // Z-
658         f->setInventoryTexture("chest_lock.png");
659         //f->setInventoryTextureCube("chest_top.png", "chest_side.png", "chest_side.png");
660         f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
661         if(f->initial_metadata == NULL)
662                 f->initial_metadata = new LockingChestNodeMetadata();
663         setWoodLikeDiggingProperties(f->digging_properties, 1.0);
664
665         i = CONTENT_FURNACE;
666         f = &content_features(i);
667         f->param_type = CPT_FACEDIR_SIMPLE;
668         f->setAllTextures("furnace_side.png");
669         f->setTexture(5, "furnace_front.png"); // Z-
670         f->setInventoryTexture("furnace_front.png");
671         //f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
672         f->dug_item = std::string("MaterialItem2 ")+itos(CONTENT_COBBLE)+" 6";
673         if(f->initial_metadata == NULL)
674                 f->initial_metadata = new FurnaceNodeMetadata();
675         setStoneLikeDiggingProperties(f->digging_properties, 3.0);
676         
677         i = CONTENT_COBBLE;
678         f = &content_features(i);
679         f->setAllTextures("cobble.png");
680         f->setInventoryTextureCube("cobble.png", "cobble.png", "cobble.png");
681         f->param_type = CPT_NONE;
682         f->is_ground_content = true;
683         f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
684         setStoneLikeDiggingProperties(f->digging_properties, 0.9);
685
686         i = CONTENT_MOSSYCOBBLE;
687         f = &content_features(i);
688         f->setAllTextures("mossycobble.png");
689         f->setInventoryTextureCube("mossycobble.png", "mossycobble.png", "mossycobble.png");
690         f->param_type = CPT_NONE;
691         f->is_ground_content = true;
692         f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
693         setStoneLikeDiggingProperties(f->digging_properties, 0.8);
694         
695         i = CONTENT_STEEL;
696         f = &content_features(i);
697         f->setAllTextures("steel_block.png");
698         f->setInventoryTextureCube("steel_block.png", "steel_block.png",
699                         "steel_block.png");
700         f->param_type = CPT_NONE;
701         f->is_ground_content = true;
702         f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
703         setStoneLikeDiggingProperties(f->digging_properties, 5.0);
704         
705         i = CONTENT_NC;
706         f = &content_features(i);
707         f->param_type = CPT_FACEDIR_SIMPLE;
708         f->setAllTextures("nc_side.png");
709         f->setTexture(5, "nc_front.png"); // Z-
710         f->setTexture(4, "nc_back.png"); // Z+
711         f->setInventoryTexture("nc_front.png");
712         f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
713         setStoneLikeDiggingProperties(f->digging_properties, 3.0);
714         
715         i = CONTENT_NC_RB;
716         f = &content_features(i);
717         f->setAllTextures("nc_rb.png");
718         f->setInventoryTexture("nc_rb.png");
719         f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
720         setStoneLikeDiggingProperties(f->digging_properties, 3.0);
721
722         i = CONTENT_SAPLING;
723         f = &content_features(i);
724         f->param_type = CPT_LIGHT;
725         f->setAllTextures("sapling.png");
726         f->setInventoryTexture("sapling.png");
727         f->used_texturenames["sapling.png"] = true;
728         f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
729         f->light_propagates = true;
730         f->air_equivalent = false;
731         f->solidness = 0; // drawn separately, makes no faces
732         f->walkable = false;
733         f->digging_properties.set("", DiggingProperties(true, 0.0, 0));
734         
735         i = CONTENT_APPLE;
736         f = &content_features(i);
737         f->setInventoryTexture("apple.png");
738         f->used_texturenames["apple.png"] = true;
739         f->param_type = CPT_LIGHT;
740         f->light_propagates = true;
741         f->sunlight_propagates = true;
742         f->solidness = 0; // drawn separately, makes no faces
743         f->walkable = false;
744         f->air_equivalent = true;
745         f->dug_item = std::string("CraftItem apple 1");
746         f->digging_properties.set("", DiggingProperties(true, 0.0, 0));
747         
748         // NOTE: Remember to add frequently used stuff to the texture atlas in tile.cpp
749         
750
751         /*
752                 Add MesePick to everything
753         */
754         for(u16 i=0; i<=MAX_CONTENT; i++)
755         {
756                 content_features(i).digging_properties.set("MesePick",
757                                 DiggingProperties(true, 0.0, 65535./1337));
758         }
759
760 }
761
762 void setStoneLikeDiggingProperties(DiggingPropertiesList &list, float toughness)
763 {
764         list.set("",
765                         DiggingProperties(true, 15.0*toughness, 0));
766         
767         list.set("WPick",
768                         DiggingProperties(true, 1.3*toughness, 65535./30.*toughness));
769         list.set("STPick",
770                         DiggingProperties(true, 0.75*toughness, 65535./100.*toughness));
771         list.set("SteelPick",
772                         DiggingProperties(true, 0.50*toughness, 65535./333.*toughness));
773
774         /*list.set("MesePick",
775                         DiggingProperties(true, 0.0*toughness, 65535./20.*toughness));*/
776 }
777
778 void setDirtLikeDiggingProperties(DiggingPropertiesList &list, float toughness)
779 {
780         list.set("",
781                         DiggingProperties(true, 0.75*toughness, 0));
782         
783         list.set("WShovel",
784                         DiggingProperties(true, 0.4*toughness, 65535./50.*toughness));
785         list.set("STShovel",
786                         DiggingProperties(true, 0.2*toughness, 65535./150.*toughness));
787         list.set("SteelShovel",
788                         DiggingProperties(true, 0.15*toughness, 65535./400.*toughness));
789 }
790
791 void setWoodLikeDiggingProperties(DiggingPropertiesList &list, float toughness)
792 {
793         list.set("",
794                         DiggingProperties(true, 3.0*toughness, 0));
795         
796         list.set("WAxe",
797                         DiggingProperties(true, 1.5*toughness, 65535./30.*toughness));
798         list.set("STAxe",
799                         DiggingProperties(true, 0.75*toughness, 65535./100.*toughness));
800         list.set("SteelAxe",
801                         DiggingProperties(true, 0.5*toughness, 65535./333.*toughness));
802 }
803
804