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