]> git.lizzy.rs Git - minetest.git/blob - src/mapnode.cpp
added simple skybox
[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                 // 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 }
351
352 v3s16 facedir_rotate(u8 facedir, v3s16 dir)
353 {
354         /*
355                 Face 2 (normally Z-) direction:
356                 facedir=0: Z-
357                 facedir=1: X-
358                 facedir=2: Z+
359                 facedir=3: X+
360         */
361         v3s16 newdir;
362         if(facedir==0) // Same
363                 newdir = v3s16(dir.X, dir.Y, dir.Z);
364         else if(facedir == 1) // Face is taken from rotXZccv(-90)
365                 newdir = v3s16(-dir.Z, dir.Y, dir.X);
366         else if(facedir == 2) // Face is taken from rotXZccv(180)
367                 newdir = v3s16(-dir.X, dir.Y, -dir.Z);
368         else if(facedir == 3) // Face is taken from rotXZccv(90)
369                 newdir = v3s16(dir.Z, dir.Y, -dir.X);
370         else
371                 newdir = dir;
372         return newdir;
373 }
374
375 TileSpec MapNode::getTile(v3s16 dir)
376 {
377         if(content_features(d).param_type == CPT_FACEDIR_SIMPLE)
378                 dir = facedir_rotate(param1, dir);
379         
380         TileSpec spec;
381         
382         s32 dir_i = -1;
383         
384         if(dir == v3s16(0,0,0))
385                 dir_i = -1;
386         else if(dir == v3s16(0,1,0))
387                 dir_i = 0;
388         else if(dir == v3s16(0,-1,0))
389                 dir_i = 1;
390         else if(dir == v3s16(1,0,0))
391                 dir_i = 2;
392         else if(dir == v3s16(-1,0,0))
393                 dir_i = 3;
394         else if(dir == v3s16(0,0,1))
395                 dir_i = 4;
396         else if(dir == v3s16(0,0,-1))
397                 dir_i = 5;
398         
399         if(dir_i == -1)
400                 // Non-directional
401                 spec = content_features(d).tiles[0];
402         else 
403                 spec = content_features(d).tiles[dir_i];
404         
405         /*
406                 If it contains some mineral, change texture id
407         */
408         if(content_features(d).param_type == CPT_MINERAL && g_texturesource)
409         {
410                 u8 mineral = param & 0x1f;
411                 std::string mineral_texture_name = mineral_block_texture(mineral);
412                 if(mineral_texture_name != "")
413                 {
414                         u32 orig_id = spec.texture.id;
415                         std::string texture_name = g_texturesource->getTextureName(orig_id);
416                         //texture_name += "^blit:";
417                         texture_name += "^";
418                         texture_name += mineral_texture_name;
419                         u32 new_id = g_texturesource->getTextureId(texture_name);
420                         spec.texture = g_texturesource->getTexture(new_id);
421                 }
422         }
423
424         return spec;
425 }
426
427 u8 MapNode::getMineral()
428 {
429         if(content_features(d).param_type == CPT_MINERAL)
430         {
431                 return param & 0x1f;
432         }
433
434         return MINERAL_NONE;
435 }
436
437 // Pointers to c_str()s g_content_features[i].inventory_image_path
438 //const char * g_content_inventory_texture_paths[USEFUL_CONTENT_COUNT] = {0};
439
440 void init_content_inventory_texture_paths()
441 {
442         dstream<<"DEPRECATED "<<__FUNCTION_NAME<<std::endl;
443         /*for(u16 i=0; i<USEFUL_CONTENT_COUNT; i++)
444         {
445                 g_content_inventory_texture_paths[i] =
446                                 g_content_features[i].inventory_image_path.c_str();
447         }*/
448 }
449