]> git.lizzy.rs Git - dragonfireclient.git/blob - src/mapnode.cpp
random comment updates
[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 }
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                 // Re-initialize
132                 *f = ContentFeatures();
133
134                 for(u16 j=0; j<6; j++)
135                         f->tiles[j].material_type = initial_material_type;
136         }
137         
138         u8 i;
139         ContentFeatures *f = NULL;
140
141         i = CONTENT_STONE;
142         f = &g_content_features[i];
143         f->setAllTextures("stone.png");
144         f->setInventoryTextureCube("stone.png", "stone.png", "stone.png");
145         f->param_type = CPT_MINERAL;
146         f->is_ground_content = true;
147         f->dug_item = std::string("MaterialItem ")+itos(CONTENT_COBBLE)+" 1";
148         
149         i = CONTENT_GRASS;
150         f = &g_content_features[i];
151         f->setAllTextures("mud.png^grass_side.png");
152         f->setTexture(0, "grass.png");
153         f->setTexture(1, "mud.png");
154         f->param_type = CPT_MINERAL;
155         f->is_ground_content = true;
156         f->dug_item = std::string("MaterialItem ")+itos(CONTENT_MUD)+" 1";
157         
158         i = CONTENT_GRASS_FOOTSTEPS;
159         f = &g_content_features[i];
160         f->setAllTextures("mud.png^grass_side.png");
161         f->setTexture(0, "grass_footsteps.png");
162         f->setTexture(1, "mud.png");
163         f->param_type = CPT_MINERAL;
164         f->is_ground_content = true;
165         f->dug_item = std::string("MaterialItem ")+itos(CONTENT_MUD)+" 1";
166         
167         i = CONTENT_MUD;
168         f = &g_content_features[i];
169         f->setAllTextures("mud.png");
170         f->setInventoryTextureCube("mud.png", "mud.png", "mud.png");
171         f->param_type = CPT_MINERAL;
172         f->is_ground_content = true;
173         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
174         
175         i = CONTENT_SAND;
176         f = &g_content_features[i];
177         f->setAllTextures("sand.png");
178         f->param_type = CPT_MINERAL;
179         f->is_ground_content = true;
180         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
181         
182         i = CONTENT_TREE;
183         f = &g_content_features[i];
184         f->setAllTextures("tree.png");
185         f->setTexture(0, "tree_top.png");
186         f->setTexture(1, "tree_top.png");
187         f->param_type = CPT_MINERAL;
188         f->is_ground_content = true;
189         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
190         
191         i = CONTENT_LEAVES;
192         f = &g_content_features[i];
193         f->light_propagates = true;
194         //f->param_type = CPT_MINERAL;
195         f->param_type = CPT_LIGHT;
196         f->is_ground_content = true;
197         if(new_style_leaves)
198         {
199                 f->solidness = 0; // drawn separately, makes no faces
200                 f->setInventoryTextureCube("leaves.png", "leaves.png", "leaves.png");
201         }
202         else
203         {
204                 f->setAllTextures("[noalpha:leaves.png");
205         }
206         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
207         
208         // Deprecated
209         i = CONTENT_COALSTONE;
210         f = &g_content_features[i];
211         //f->translate_to = new MapNode(CONTENT_STONE, MINERAL_COAL);
212         f->setAllTextures("stone.png^mineral_coal.png");
213         f->is_ground_content = true;
214         
215         i = CONTENT_WOOD;
216         f = &g_content_features[i];
217         f->setAllTextures("wood.png");
218         f->is_ground_content = true;
219         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
220         
221         i = CONTENT_MESE;
222         f = &g_content_features[i];
223         f->setAllTextures("mese.png");
224         f->is_ground_content = true;
225         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
226         
227         i = CONTENT_CLOUD;
228         f = &g_content_features[i];
229         f->setAllTextures("cloud.png");
230         f->is_ground_content = true;
231         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
232         
233         i = CONTENT_AIR;
234         f = &g_content_features[i];
235         f->param_type = CPT_LIGHT;
236         f->light_propagates = true;
237         f->sunlight_propagates = true;
238         f->solidness = 0;
239         f->walkable = false;
240         f->pointable = false;
241         f->diggable = false;
242         f->buildable_to = true;
243         
244         i = CONTENT_WATER;
245         f = &g_content_features[i];
246         f->setInventoryTextureCube("water.png", "water.png", "water.png");
247         f->param_type = CPT_LIGHT;
248         f->light_propagates = true;
249         f->solidness = 0; // Drawn separately, makes no faces
250         f->walkable = false;
251         f->pointable = false;
252         f->diggable = false;
253         f->buildable_to = true;
254         f->liquid_type = LIQUID_FLOWING;
255         
256         i = CONTENT_WATERSOURCE;
257         f = &g_content_features[i];
258         f->setInventoryTexture("water.png");
259         if(new_style_water)
260         {
261                 f->solidness = 0; // drawn separately, makes no faces
262         }
263         else // old style
264         {
265                 f->solidness = 1;
266
267                 TileSpec t;
268                 if(g_texturesource)
269                         t.texture = g_texturesource->getTexture("water.png");
270                 
271                 t.alpha = WATER_ALPHA;
272                 t.material_type = MATERIAL_ALPHA_VERTEX;
273                 t.material_flags &= ~MATERIAL_FLAG_BACKFACE_CULLING;
274                 f->setAllTiles(t);
275         }
276         f->param_type = CPT_LIGHT;
277         f->light_propagates = true;
278         f->walkable = false;
279         f->pointable = false;
280         f->diggable = false;
281         f->buildable_to = true;
282         f->liquid_type = LIQUID_SOURCE;
283         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
284         
285         i = CONTENT_TORCH;
286         f = &g_content_features[i];
287         f->setInventoryTexture("torch_on_floor.png");
288         f->param_type = CPT_LIGHT;
289         f->light_propagates = true;
290         f->sunlight_propagates = true;
291         f->solidness = 0; // drawn separately, makes no faces
292         f->walkable = false;
293         f->wall_mounted = true;
294         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
295         
296         i = CONTENT_SIGN_WALL;
297         f = &g_content_features[i];
298         f->setInventoryTexture("sign_wall.png");
299         f->param_type = CPT_LIGHT;
300         f->light_propagates = true;
301         f->sunlight_propagates = true;
302         f->solidness = 0; // drawn separately, makes no faces
303         f->walkable = false;
304         f->wall_mounted = true;
305         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
306         if(f->initial_metadata == NULL)
307                 f->initial_metadata = new SignNodeMetadata("Some sign");
308         
309         i = CONTENT_CHEST;
310         f = &g_content_features[i];
311         f->param_type = CPT_FACEDIR_SIMPLE;
312         f->setAllTextures("chest_side.png");
313         f->setTexture(0, "chest_top.png");
314         f->setTexture(1, "chest_top.png");
315         f->setTexture(5, "chest_front.png"); // Z-
316         f->setInventoryTexture("chest_top.png");
317         //f->setInventoryTextureCube("chest_top.png", "chest_side.png", "chest_side.png");
318         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
319         if(f->initial_metadata == NULL)
320                 f->initial_metadata = new ChestNodeMetadata();
321         
322         i = CONTENT_FURNACE;
323         f = &g_content_features[i];
324         f->param_type = CPT_FACEDIR_SIMPLE;
325         f->setAllTextures("furnace_side.png");
326         f->setTexture(5, "furnace_front.png"); // Z-
327         f->setInventoryTexture("furnace_front.png");
328         //f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
329         f->dug_item = std::string("MaterialItem ")+itos(CONTENT_COBBLE)+" 6";
330         if(f->initial_metadata == NULL)
331                 f->initial_metadata = new FurnaceNodeMetadata();
332         
333         i = CONTENT_COBBLE;
334         f = &g_content_features[i];
335         f->setAllTextures("cobble.png");
336         f->setInventoryTextureCube("cobble.png", "cobble.png", "cobble.png");
337         f->param_type = CPT_NONE;
338         f->is_ground_content = true;
339         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
340         
341         i = CONTENT_STEEL;
342         f = &g_content_features[i];
343         f->setAllTextures("steel_block.png");
344         f->setInventoryTextureCube("steel_block.png", "steel_block.png",
345                         "steel_block.png");
346         f->param_type = CPT_NONE;
347         f->is_ground_content = true;
348         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
349         
350         // NOTE: Remember to add frequently used stuff to the texture atlas in tile.cpp
351 }
352
353 v3s16 facedir_rotate(u8 facedir, v3s16 dir)
354 {
355         /*
356                 Face 2 (normally Z-) direction:
357                 facedir=0: Z-
358                 facedir=1: X-
359                 facedir=2: Z+
360                 facedir=3: X+
361         */
362         v3s16 newdir;
363         if(facedir==0) // Same
364                 newdir = v3s16(dir.X, dir.Y, dir.Z);
365         else if(facedir == 1) // Face is taken from rotXZccv(-90)
366                 newdir = v3s16(-dir.Z, dir.Y, dir.X);
367         else if(facedir == 2) // Face is taken from rotXZccv(180)
368                 newdir = v3s16(-dir.X, dir.Y, -dir.Z);
369         else if(facedir == 3) // Face is taken from rotXZccv(90)
370                 newdir = v3s16(dir.Z, dir.Y, -dir.X);
371         else
372                 newdir = dir;
373         return newdir;
374 }
375
376 TileSpec MapNode::getTile(v3s16 dir)
377 {
378         if(content_features(d).param_type == CPT_FACEDIR_SIMPLE)
379                 dir = facedir_rotate(param1, dir);
380         
381         TileSpec spec;
382         
383         s32 dir_i = -1;
384         
385         if(dir == v3s16(0,0,0))
386                 dir_i = -1;
387         else if(dir == v3s16(0,1,0))
388                 dir_i = 0;
389         else if(dir == v3s16(0,-1,0))
390                 dir_i = 1;
391         else if(dir == v3s16(1,0,0))
392                 dir_i = 2;
393         else if(dir == v3s16(-1,0,0))
394                 dir_i = 3;
395         else if(dir == v3s16(0,0,1))
396                 dir_i = 4;
397         else if(dir == v3s16(0,0,-1))
398                 dir_i = 5;
399         
400         if(dir_i == -1)
401                 // Non-directional
402                 spec = content_features(d).tiles[0];
403         else 
404                 spec = content_features(d).tiles[dir_i];
405         
406         /*
407                 If it contains some mineral, change texture id
408         */
409         if(content_features(d).param_type == CPT_MINERAL && g_texturesource)
410         {
411                 u8 mineral = param & 0x1f;
412                 std::string mineral_texture_name = mineral_block_texture(mineral);
413                 if(mineral_texture_name != "")
414                 {
415                         u32 orig_id = spec.texture.id;
416                         std::string texture_name = g_texturesource->getTextureName(orig_id);
417                         //texture_name += "^blit:";
418                         texture_name += "^";
419                         texture_name += mineral_texture_name;
420                         u32 new_id = g_texturesource->getTextureId(texture_name);
421                         spec.texture = g_texturesource->getTexture(new_id);
422                 }
423         }
424
425         return spec;
426 }
427
428 u8 MapNode::getMineral()
429 {
430         if(content_features(d).param_type == CPT_MINERAL)
431         {
432                 return param & 0x1f;
433         }
434
435         return MINERAL_NONE;
436 }
437
438 // Pointers to c_str()s g_content_features[i].inventory_image_path
439 //const char * g_content_inventory_texture_paths[USEFUL_CONTENT_COUNT] = {0};
440
441 void init_content_inventory_texture_paths()
442 {
443         dstream<<"DEPRECATED "<<__FUNCTION_NAME<<std::endl;
444         /*for(u16 i=0; i<USEFUL_CONTENT_COUNT; i++)
445         {
446                 g_content_inventory_texture_paths[i] =
447                                 g_content_features[i].inventory_image_path.c_str();
448         }*/
449 }
450