1e0381d03ef2e8a77c7fd70b589410b97da7b2e2
[oweals/minetest.git] / src / mapnode.cpp
1 /*
2 Minetest-c55
3 Copyright (C) 2010 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 "common_irrlicht.h"
21 #include "mapnode.h"
22 #include "tile.h"
23 #include "porting.h"
24 #include <string>
25 #include "mineral.h"
26 // For g_settings
27 #include "main.h"
28
29 ContentFeatures::~ContentFeatures()
30 {
31         if(translate_to)
32                 delete translate_to;
33 }
34
35 void ContentFeatures::setTexture(u16 i, std::string name, u8 alpha)
36 {
37         if(g_texturesource)
38         {
39                 tiles[i].texture = g_texturesource->getTexture(name);
40         }
41         
42         if(alpha != 255)
43         {
44                 tiles[i].alpha = alpha;
45                 tiles[i].material_type = MATERIAL_ALPHA_VERTEX;
46         }
47
48         if(inventory_texture == NULL)
49                 setInventoryTexture(name);
50 }
51
52 void ContentFeatures::setInventoryTexture(std::string imgname)
53 {
54         if(g_texturesource == NULL)
55                 return;
56         
57         imgname += "^[forcesingle";
58         
59         inventory_texture = g_texturesource->getTextureRaw(imgname);
60 }
61
62 void ContentFeatures::setInventoryTextureCube(std::string top,
63                 std::string left, std::string right)
64 {
65         if(g_texturesource == NULL)
66                 return;
67         
68         str_replace_char(top, '^', '&');
69         str_replace_char(left, '^', '&');
70         str_replace_char(right, '^', '&');
71
72         std::string imgname_full;
73         imgname_full += "[inventorycube{";
74         imgname_full += top;
75         imgname_full += "{";
76         imgname_full += left;
77         imgname_full += "{";
78         imgname_full += right;
79         inventory_texture = g_texturesource->getTextureRaw(imgname_full);
80 }
81
82 struct ContentFeatures g_content_features[256];
83
84 ContentFeatures & content_features(u8 i)
85 {
86         return g_content_features[i];
87 }
88
89 /*
90         See mapnode.h for description.
91 */
92 void init_mapnode()
93 {
94         if(g_texturesource == NULL)
95         {
96                 dstream<<"INFO: Initial run of init_mapnode with "
97                                 "g_texturesource=NULL. If this segfaults, "
98                                 "there is a bug with something not checking for "
99                                 "the NULL value."<<std::endl;
100         }
101         else
102         {
103                 dstream<<"INFO: Full run of init_mapnode with "
104                                 "g_texturesource!=NULL"<<std::endl;
105         }
106
107         // Read some settings
108         bool new_style_water = g_settings.getBool("new_style_water");
109         bool new_style_leaves = g_settings.getBool("new_style_leaves");
110
111         /*
112                 Initialize content feature table
113         */
114         
115         /*
116                 Set initial material type to same in all tiles, so that the
117                 same material can be used in more stuff.
118                 This is set according to the leaves because they are the only
119                 differing material to which all materials can be changed to
120                 get this optimization.
121         */
122         u8 initial_material_type = MATERIAL_ALPHA_SIMPLE;
123         /*if(new_style_leaves)
124                 initial_material_type = MATERIAL_ALPHA_SIMPLE;
125         else
126                 initial_material_type = MATERIAL_ALPHA_NONE;*/
127         for(u16 i=0; i<256; i++)
128         {
129                 ContentFeatures *f = &g_content_features[i];
130                 for(u16 j=0; j<6; j++)
131                         f->tiles[j].material_type = initial_material_type;
132         }
133         
134         u8 i;
135         ContentFeatures *f = NULL;
136
137         i = CONTENT_STONE;
138         f = &g_content_features[i];
139         f->setAllTextures("stone.png");
140         f->setInventoryTextureCube("stone.png", "stone.png", "stone.png");
141         f->param_type = CPT_MINERAL;
142         f->is_ground_content = true;
143         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
144         
145         i = CONTENT_GRASS;
146         f = &g_content_features[i];
147         f->setAllTextures("mud.png^grass_side.png");
148         f->setTexture(0, "grass.png");
149         f->setTexture(1, "mud.png");
150         f->param_type = CPT_MINERAL;
151         f->is_ground_content = true;
152         f->dug_item = std::string("MaterialItem ")+itos(CONTENT_MUD)+" 1";
153         
154         i = CONTENT_GRASS_FOOTSTEPS;
155         f = &g_content_features[i];
156         f->setAllTextures("mud.png^grass_side.png");
157         f->setTexture(0, "grass_footsteps.png");
158         f->setTexture(1, "mud.png");
159         f->param_type = CPT_MINERAL;
160         f->is_ground_content = true;
161         f->dug_item = std::string("MaterialItem ")+itos(CONTENT_MUD)+" 1";
162         
163         i = CONTENT_MUD;
164         f = &g_content_features[i];
165         f->setAllTextures("mud.png");
166         f->param_type = CPT_MINERAL;
167         f->is_ground_content = true;
168         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
169         
170         i = CONTENT_SAND;
171         f = &g_content_features[i];
172         f->setAllTextures("sand.png");
173         f->param_type = CPT_MINERAL;
174         f->is_ground_content = true;
175         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
176         
177         i = CONTENT_TREE;
178         f = &g_content_features[i];
179         f->setAllTextures("tree.png");
180         f->setTexture(0, "tree_top.png");
181         f->setTexture(1, "tree_top.png");
182         f->param_type = CPT_MINERAL;
183         f->is_ground_content = true;
184         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
185         
186         i = CONTENT_LEAVES;
187         f = &g_content_features[i];
188         f->light_propagates = true;
189         //f->param_type = CPT_MINERAL;
190         f->param_type = CPT_LIGHT;
191         f->is_ground_content = true;
192         if(new_style_leaves)
193         {
194                 f->solidness = 0; // drawn separately, makes no faces
195                 f->setInventoryTextureCube("leaves.png", "leaves.png", "leaves.png");
196         }
197         else
198         {
199                 f->setAllTextures("[noalpha:leaves.png");
200         }
201         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
202         
203         i = CONTENT_COALSTONE;
204         f = &g_content_features[i];
205         //f->translate_to = new MapNode(CONTENT_STONE, MINERAL_COAL);
206         f->setAllTextures("stone.png^mineral_coal.png");
207         f->is_ground_content = true;
208         
209         i = CONTENT_WOOD;
210         f = &g_content_features[i];
211         f->setAllTextures("wood.png");
212         f->is_ground_content = true;
213         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
214         
215         i = CONTENT_MESE;
216         f = &g_content_features[i];
217         f->setAllTextures("mese.png");
218         f->is_ground_content = true;
219         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
220         
221         i = CONTENT_CLOUD;
222         f = &g_content_features[i];
223         f->setAllTextures("cloud.png");
224         f->is_ground_content = true;
225         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
226         
227         i = CONTENT_AIR;
228         f = &g_content_features[i];
229         f->param_type = CPT_LIGHT;
230         f->light_propagates = true;
231         f->sunlight_propagates = true;
232         f->solidness = 0;
233         f->walkable = false;
234         f->pointable = false;
235         f->diggable = false;
236         f->buildable_to = true;
237         
238         i = CONTENT_WATER;
239         f = &g_content_features[i];
240         f->setInventoryTextureCube("water.png", "water.png", "water.png");
241         f->param_type = CPT_LIGHT;
242         f->light_propagates = true;
243         f->solidness = 0; // Drawn separately, makes no faces
244         f->walkable = false;
245         f->pointable = false;
246         f->diggable = false;
247         f->buildable_to = true;
248         f->liquid_type = LIQUID_FLOWING;
249         
250         i = CONTENT_WATERSOURCE;
251         f = &g_content_features[i];
252         f->setInventoryTexture("water.png");
253         if(new_style_water)
254         {
255                 f->solidness = 0; // drawn separately, makes no faces
256         }
257         else // old style
258         {
259                 f->solidness = 1;
260
261                 TileSpec t;
262                 if(g_texturesource)
263                         t.texture = g_texturesource->getTexture("water.png");
264                 
265                 t.alpha = WATER_ALPHA;
266                 t.material_type = MATERIAL_ALPHA_VERTEX;
267                 t.material_flags &= ~MATERIAL_FLAG_BACKFACE_CULLING;
268                 f->setAllTiles(t);
269         }
270         f->param_type = CPT_LIGHT;
271         f->light_propagates = true;
272         f->walkable = false;
273         f->pointable = false;
274         f->diggable = false;
275         f->buildable_to = true;
276         f->liquid_type = LIQUID_SOURCE;
277         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
278         
279         i = CONTENT_TORCH;
280         f = &g_content_features[i];
281         f->setInventoryTexture("torch_on_floor.png");
282         f->param_type = CPT_LIGHT;
283         f->light_propagates = true;
284         f->solidness = 0; // drawn separately, makes no faces
285         f->walkable = false;
286         f->wall_mounted = true;
287         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
288         
289 }
290
291 TileSpec MapNode::getTile(v3s16 dir)
292 {
293         TileSpec spec;
294         
295         s32 dir_i = -1;
296         
297         if(dir == v3s16(0,0,0))
298                 dir_i = -1;
299         else if(dir == v3s16(0,1,0))
300                 dir_i = 0;
301         else if(dir == v3s16(0,-1,0))
302                 dir_i = 1;
303         else if(dir == v3s16(1,0,0))
304                 dir_i = 2;
305         else if(dir == v3s16(-1,0,0))
306                 dir_i = 3;
307         else if(dir == v3s16(0,0,1))
308                 dir_i = 4;
309         else if(dir == v3s16(0,0,-1))
310                 dir_i = 5;
311         
312         if(dir_i == -1)
313                 // Non-directional
314                 spec = content_features(d).tiles[0];
315         else 
316                 spec = content_features(d).tiles[dir_i];
317         
318         /*
319                 If it contains some mineral, change texture id
320         */
321         if(content_features(d).param_type == CPT_MINERAL && g_texturesource)
322         {
323                 u8 mineral = param & 0x1f;
324                 std::string mineral_texture_name = mineral_block_texture(mineral);
325                 if(mineral_texture_name != "")
326                 {
327                         u32 orig_id = spec.texture.id;
328                         std::string texture_name = g_texturesource->getTextureName(orig_id);
329                         //texture_name += "^blit:";
330                         texture_name += "^";
331                         texture_name += mineral_texture_name;
332                         u32 new_id = g_texturesource->getTextureId(texture_name);
333                         spec.texture = g_texturesource->getTexture(new_id);
334                 }
335         }
336
337         return spec;
338 }
339
340 u8 MapNode::getMineral()
341 {
342         if(content_features(d).param_type == CPT_MINERAL)
343         {
344                 return param & 0x1f;
345         }
346
347         return MINERAL_NONE;
348 }
349
350 // Pointers to c_str()s g_content_features[i].inventory_image_path
351 //const char * g_content_inventory_texture_paths[USEFUL_CONTENT_COUNT] = {0};
352
353 void init_content_inventory_texture_paths()
354 {
355         dstream<<"DEPRECATED "<<__FUNCTION_NAME<<std::endl;
356         /*for(u16 i=0; i<USEFUL_CONTENT_COUNT; i++)
357         {
358                 g_content_inventory_texture_paths[i] =
359                                 g_content_features[i].inventory_image_path.c_str();
360         }*/
361 }
362