]> git.lizzy.rs Git - minetest.git/blob - src/mapnode.cpp
Fixed error reported by cppcheck:
[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 #include "nodemetadata.h"
29
30 ContentFeatures::~ContentFeatures()
31 {
32         if(translate_to)
33                 delete translate_to;
34 }
35
36 void ContentFeatures::setTexture(u16 i, std::string name, u8 alpha)
37 {
38         if(g_texturesource)
39         {
40                 tiles[i].texture = g_texturesource->getTexture(name);
41         }
42         
43         if(alpha != 255)
44         {
45                 tiles[i].alpha = alpha;
46                 tiles[i].material_type = MATERIAL_ALPHA_VERTEX;
47         }
48
49         if(inventory_texture == NULL)
50                 setInventoryTexture(name);
51 }
52
53 void ContentFeatures::setInventoryTexture(std::string imgname)
54 {
55         if(g_texturesource == NULL)
56                 return;
57         
58         imgname += "^[forcesingle";
59         
60         inventory_texture = g_texturesource->getTextureRaw(imgname);
61 }
62
63 void ContentFeatures::setInventoryTextureCube(std::string top,
64                 std::string left, std::string right)
65 {
66         if(g_texturesource == NULL)
67                 return;
68         
69         str_replace_char(top, '^', '&');
70         str_replace_char(left, '^', '&');
71         str_replace_char(right, '^', '&');
72
73         std::string imgname_full;
74         imgname_full += "[inventorycube{";
75         imgname_full += top;
76         imgname_full += "{";
77         imgname_full += left;
78         imgname_full += "{";
79         imgname_full += right;
80         inventory_texture = g_texturesource->getTextureRaw(imgname_full);
81 }
82
83 struct ContentFeatures g_content_features[256];
84
85 ContentFeatures & content_features(u8 i)
86 {
87         return g_content_features[i];
88 }
89
90 /*
91         See mapnode.h for description.
92 */
93 void init_mapnode()
94 {
95         if(g_texturesource == NULL)
96         {
97                 dstream<<"INFO: Initial run of init_mapnode with "
98                                 "g_texturesource=NULL. If this segfaults, "
99                                 "there is a bug with something not checking for "
100                                 "the NULL value."<<std::endl;
101         }
102         else
103         {
104                 dstream<<"INFO: Full run of init_mapnode with "
105                                 "g_texturesource!=NULL"<<std::endl;
106         }
107
108         // Read some settings
109         bool new_style_water = g_settings.getBool("new_style_water");
110         bool new_style_leaves = g_settings.getBool("new_style_leaves");
111
112         /*
113                 Initialize content feature table
114         */
115         
116         /*
117                 Set initial material type to same in all tiles, so that the
118                 same material can be used in more stuff.
119                 This is set according to the leaves because they are the only
120                 differing material to which all materials can be changed to
121                 get this optimization.
122         */
123         u8 initial_material_type = MATERIAL_ALPHA_SIMPLE;
124         /*if(new_style_leaves)
125                 initial_material_type = MATERIAL_ALPHA_SIMPLE;
126         else
127                 initial_material_type = MATERIAL_ALPHA_NONE;*/
128         for(u16 i=0; i<256; i++)
129         {
130                 ContentFeatures *f = &g_content_features[i];
131                 for(u16 j=0; j<6; j++)
132                         f->tiles[j].material_type = initial_material_type;
133         }
134         
135         u8 i;
136         ContentFeatures *f = NULL;
137
138         i = CONTENT_STONE;
139         f = &g_content_features[i];
140         f->setAllTextures("stone.png");
141         f->setInventoryTextureCube("stone.png", "stone.png", "stone.png");
142         f->param_type = CPT_MINERAL;
143         f->is_ground_content = true;
144         f->dug_item = std::string("MaterialItem ")+itos(CONTENT_COBBLE)+" 1";
145         
146         i = CONTENT_GRASS;
147         f = &g_content_features[i];
148         f->setAllTextures("mud.png^grass_side.png");
149         f->setTexture(0, "grass.png");
150         f->setTexture(1, "mud.png");
151         f->param_type = CPT_MINERAL;
152         f->is_ground_content = true;
153         f->dug_item = std::string("MaterialItem ")+itos(CONTENT_MUD)+" 1";
154         
155         i = CONTENT_GRASS_FOOTSTEPS;
156         f = &g_content_features[i];
157         f->setAllTextures("mud.png^grass_side.png");
158         f->setTexture(0, "grass_footsteps.png");
159         f->setTexture(1, "mud.png");
160         f->param_type = CPT_MINERAL;
161         f->is_ground_content = true;
162         f->dug_item = std::string("MaterialItem ")+itos(CONTENT_MUD)+" 1";
163         
164         i = CONTENT_MUD;
165         f = &g_content_features[i];
166         f->setAllTextures("mud.png");
167         f->setInventoryTextureCube("mud.png", "mud.png", "mud.png");
168         f->param_type = CPT_MINERAL;
169         f->is_ground_content = true;
170         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
171         
172         i = CONTENT_SAND;
173         f = &g_content_features[i];
174         f->setAllTextures("sand.png");
175         f->param_type = CPT_MINERAL;
176         f->is_ground_content = true;
177         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
178         
179         i = CONTENT_TREE;
180         f = &g_content_features[i];
181         f->setAllTextures("tree.png");
182         f->setTexture(0, "tree_top.png");
183         f->setTexture(1, "tree_top.png");
184         f->param_type = CPT_MINERAL;
185         f->is_ground_content = true;
186         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
187         
188         i = CONTENT_LEAVES;
189         f = &g_content_features[i];
190         f->light_propagates = true;
191         //f->param_type = CPT_MINERAL;
192         f->param_type = CPT_LIGHT;
193         f->is_ground_content = true;
194         if(new_style_leaves)
195         {
196                 f->solidness = 0; // drawn separately, makes no faces
197                 f->setInventoryTextureCube("leaves.png", "leaves.png", "leaves.png");
198         }
199         else
200         {
201                 f->setAllTextures("[noalpha:leaves.png");
202         }
203         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
204         
205         // Deprecated
206         i = CONTENT_COALSTONE;
207         f = &g_content_features[i];
208         //f->translate_to = new MapNode(CONTENT_STONE, MINERAL_COAL);
209         f->setAllTextures("stone.png^mineral_coal.png");
210         f->is_ground_content = true;
211         
212         i = CONTENT_WOOD;
213         f = &g_content_features[i];
214         f->setAllTextures("wood.png");
215         f->is_ground_content = true;
216         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
217         
218         i = CONTENT_MESE;
219         f = &g_content_features[i];
220         f->setAllTextures("mese.png");
221         f->is_ground_content = true;
222         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
223         
224         i = CONTENT_CLOUD;
225         f = &g_content_features[i];
226         f->setAllTextures("cloud.png");
227         f->is_ground_content = true;
228         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
229         
230         i = CONTENT_AIR;
231         f = &g_content_features[i];
232         f->param_type = CPT_LIGHT;
233         f->light_propagates = true;
234         f->sunlight_propagates = true;
235         f->solidness = 0;
236         f->walkable = false;
237         f->pointable = false;
238         f->diggable = false;
239         f->buildable_to = true;
240         
241         i = CONTENT_WATER;
242         f = &g_content_features[i];
243         f->setInventoryTextureCube("water.png", "water.png", "water.png");
244         f->param_type = CPT_LIGHT;
245         f->light_propagates = true;
246         f->solidness = 0; // Drawn separately, makes no faces
247         f->walkable = false;
248         f->pointable = false;
249         f->diggable = false;
250         f->buildable_to = true;
251         f->liquid_type = LIQUID_FLOWING;
252         
253         i = CONTENT_WATERSOURCE;
254         f = &g_content_features[i];
255         f->setInventoryTexture("water.png");
256         if(new_style_water)
257         {
258                 f->solidness = 0; // drawn separately, makes no faces
259         }
260         else // old style
261         {
262                 f->solidness = 1;
263
264                 TileSpec t;
265                 if(g_texturesource)
266                         t.texture = g_texturesource->getTexture("water.png");
267                 
268                 t.alpha = WATER_ALPHA;
269                 t.material_type = MATERIAL_ALPHA_VERTEX;
270                 t.material_flags &= ~MATERIAL_FLAG_BACKFACE_CULLING;
271                 f->setAllTiles(t);
272         }
273         f->param_type = CPT_LIGHT;
274         f->light_propagates = true;
275         f->walkable = false;
276         f->pointable = false;
277         f->diggable = false;
278         f->buildable_to = true;
279         f->liquid_type = LIQUID_SOURCE;
280         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
281         
282         i = CONTENT_TORCH;
283         f = &g_content_features[i];
284         f->setInventoryTexture("torch_on_floor.png");
285         f->param_type = CPT_LIGHT;
286         f->light_propagates = true;
287         f->sunlight_propagates = true;
288         f->solidness = 0; // drawn separately, makes no faces
289         f->walkable = false;
290         f->wall_mounted = true;
291         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
292         
293         i = CONTENT_SIGN_WALL;
294         f = &g_content_features[i];
295         f->setInventoryTexture("sign_wall.png");
296         f->param_type = CPT_LIGHT;
297         f->light_propagates = true;
298         f->sunlight_propagates = true;
299         f->solidness = 0; // drawn separately, makes no faces
300         f->walkable = false;
301         f->wall_mounted = true;
302         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
303         if(f->initial_metadata == NULL)
304                 f->initial_metadata = new SignNodeMetadata("Some sign");
305         
306         i = CONTENT_CHEST;
307         f = &g_content_features[i];
308         f->param_type = CPT_FACEDIR_SIMPLE;
309         f->setAllTextures("chest_side.png");
310         f->setTexture(0, "chest_top.png");
311         f->setTexture(1, "chest_top.png");
312         f->setTexture(5, "chest_front.png"); // Z-
313         f->setInventoryTexture("chest_top.png");
314         //f->setInventoryTextureCube("chest_top.png", "chest_side.png", "chest_side.png");
315         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
316         if(f->initial_metadata == NULL)
317                 f->initial_metadata = new ChestNodeMetadata();
318         
319         i = CONTENT_FURNACE;
320         f = &g_content_features[i];
321         f->param_type = CPT_FACEDIR_SIMPLE;
322         f->setAllTextures("furnace_side.png");
323         f->setTexture(5, "furnace_front.png"); // Z-
324         f->setInventoryTexture("furnace_front.png");
325         //f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
326         f->dug_item = std::string("MaterialItem ")+itos(CONTENT_COBBLE)+" 6";
327         if(f->initial_metadata == NULL)
328                 f->initial_metadata = new FurnaceNodeMetadata();
329         
330         i = CONTENT_COBBLE;
331         f = &g_content_features[i];
332         f->setAllTextures("cobble.png");
333         f->setInventoryTextureCube("cobble.png", "cobble.png", "cobble.png");
334         f->param_type = CPT_NONE;
335         f->is_ground_content = true;
336         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
337         
338         i = CONTENT_STEEL;
339         f = &g_content_features[i];
340         f->setAllTextures("steel_block.png");
341         f->setInventoryTextureCube("steel_block.png", "steel_block.png",
342                         "steel_block.png");
343         f->param_type = CPT_NONE;
344         f->is_ground_content = true;
345         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
346         
347 }
348
349 v3s16 facedir_rotate(u8 facedir, v3s16 dir)
350 {
351         /*
352                 Face 2 (normally Z-) direction:
353                 facedir=0: Z-
354                 facedir=1: X-
355                 facedir=2: Z+
356                 facedir=3: X+
357         */
358         v3s16 newdir;
359         if(facedir==0) // Same
360                 newdir = v3s16(dir.X, dir.Y, dir.Z);
361         else if(facedir == 1) // Face is taken from rotXZccv(-90)
362                 newdir = v3s16(-dir.Z, dir.Y, dir.X);
363         else if(facedir == 2) // Face is taken from rotXZccv(180)
364                 newdir = v3s16(-dir.X, dir.Y, -dir.Z);
365         else if(facedir == 3) // Face is taken from rotXZccv(90)
366                 newdir = v3s16(dir.Z, dir.Y, -dir.X);
367         else
368                 newdir = dir;
369         return newdir;
370 }
371
372 TileSpec MapNode::getTile(v3s16 dir)
373 {
374         if(content_features(d).param_type == CPT_FACEDIR_SIMPLE)
375                 dir = facedir_rotate(param1, dir);
376         
377         TileSpec spec;
378         
379         s32 dir_i = -1;
380         
381         if(dir == v3s16(0,0,0))
382                 dir_i = -1;
383         else if(dir == v3s16(0,1,0))
384                 dir_i = 0;
385         else if(dir == v3s16(0,-1,0))
386                 dir_i = 1;
387         else if(dir == v3s16(1,0,0))
388                 dir_i = 2;
389         else if(dir == v3s16(-1,0,0))
390                 dir_i = 3;
391         else if(dir == v3s16(0,0,1))
392                 dir_i = 4;
393         else if(dir == v3s16(0,0,-1))
394                 dir_i = 5;
395         
396         if(dir_i == -1)
397                 // Non-directional
398                 spec = content_features(d).tiles[0];
399         else 
400                 spec = content_features(d).tiles[dir_i];
401         
402         /*
403                 If it contains some mineral, change texture id
404         */
405         if(content_features(d).param_type == CPT_MINERAL && g_texturesource)
406         {
407                 u8 mineral = param & 0x1f;
408                 std::string mineral_texture_name = mineral_block_texture(mineral);
409                 if(mineral_texture_name != "")
410                 {
411                         u32 orig_id = spec.texture.id;
412                         std::string texture_name = g_texturesource->getTextureName(orig_id);
413                         //texture_name += "^blit:";
414                         texture_name += "^";
415                         texture_name += mineral_texture_name;
416                         u32 new_id = g_texturesource->getTextureId(texture_name);
417                         spec.texture = g_texturesource->getTexture(new_id);
418                 }
419         }
420
421         return spec;
422 }
423
424 u8 MapNode::getMineral()
425 {
426         if(content_features(d).param_type == CPT_MINERAL)
427         {
428                 return param & 0x1f;
429         }
430
431         return MINERAL_NONE;
432 }
433
434 // Pointers to c_str()s g_content_features[i].inventory_image_path
435 //const char * g_content_inventory_texture_paths[USEFUL_CONTENT_COUNT] = {0};
436
437 void init_content_inventory_texture_paths()
438 {
439         dstream<<"DEPRECATED "<<__FUNCTION_NAME<<std::endl;
440         /*for(u16 i=0; i<USEFUL_CONTENT_COUNT; i++)
441         {
442                 g_content_inventory_texture_paths[i] =
443                                 g_content_features[i].inventory_image_path.c_str();
444         }*/
445 }
446