]> git.lizzy.rs Git - dragonfireclient.git/blob - src/mapnode.cpp
+ paper, book, bookshelf
[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_SANDSTONE;
185         f = &g_content_features[i];
186         f->setAllTextures("sandstone.png");
187         f->setInventoryTextureCube("sandstone.png", "sandstone.png", "sandstone.png");
188         f->param_type = CPT_MINERAL;
189         f->is_ground_content = true;
190         f->dug_item = std::string("MaterialItem ")+itos(CONTENT_SAND)+" 1";
191         
192         i = CONTENT_CLAY;
193         f = &g_content_features[i];
194         f->setAllTextures("clay.png");
195         f->setInventoryTextureCube("clay.png", "clay.png", "clay.png");
196         f->param_type = CPT_MINERAL;
197         f->is_ground_content = true;
198         f->dug_item = std::string("CraftItem lump_of_clay 4");
199         
200         i = CONTENT_BRICK;
201         f = &g_content_features[i];
202         f->setAllTextures("brick.png");
203         f->setInventoryTextureCube("brick.png", "brick.png", "brick.png");
204         f->param_type = CPT_MINERAL;
205         f->is_ground_content = true;
206         f->dug_item = std::string("CraftItem clay_brick 4");
207         
208         i = CONTENT_TREE;
209         f = &g_content_features[i];
210         f->setAllTextures("tree.png");
211         f->setTexture(0, "tree_top.png");
212         f->setTexture(1, "tree_top.png");
213         f->param_type = CPT_MINERAL;
214         f->is_ground_content = true;
215         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
216         
217         i = CONTENT_LEAVES;
218         f = &g_content_features[i];
219         f->light_propagates = true;
220         //f->param_type = CPT_MINERAL;
221         f->param_type = CPT_LIGHT;
222         f->is_ground_content = true;
223         if(new_style_leaves)
224         {
225                 f->solidness = 0; // drawn separately, makes no faces
226                 f->setInventoryTextureCube("leaves.png", "leaves.png", "leaves.png");
227         }
228         else
229         {
230                 f->setAllTextures("[noalpha:leaves.png");
231         }
232         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
233
234         i = CONTENT_CACTUS;
235         f = &g_content_features[i];
236         f->setAllTextures("cactus_side.png");
237         f->setTexture(0, "cactus_top.png");
238         f->setTexture(1, "cactus_top.png");
239         f->setInventoryTextureCube("cactus_top.png", "cactus_side.png", "cactus_side.png");
240         f->param_type = CPT_MINERAL;
241         f->is_ground_content = true;
242         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
243
244         i = CONTENT_PAPYRUS;
245         f = &g_content_features[i];
246         f->setInventoryTexture("papyrus.png");
247         f->light_propagates = true;
248         f->param_type = CPT_LIGHT;
249         f->is_ground_content = true;
250         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
251         f->solidness = 0; // drawn separately, makes no faces
252         f->walkable = false;
253
254         i = CONTENT_BOOKSHELF;
255         f = &g_content_features[i];
256         f->setAllTextures("bookshelf.png");
257         f->setTexture(0, "wood.png");
258         f->setTexture(1, "wood.png");
259         // FIXME: setInventoryTextureCube() only cares for the first texture
260         f->setInventoryTextureCube("bookshelf.png", "bookshelf.png", "bookshelf.png");
261         //f->setInventoryTextureCube("wood.png", "bookshelf.png", "bookshelf.png");
262         f->param_type = CPT_MINERAL;
263         f->is_ground_content = true;
264
265         i = CONTENT_GLASS;
266         f = &g_content_features[i];
267         f->light_propagates = true;
268         f->param_type = CPT_LIGHT;
269         f->is_ground_content = true;
270         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
271         f->solidness = 0; // drawn separately, makes no faces
272         f->setInventoryTextureCube("glass.png", "glass.png", "glass.png");
273
274         i = CONTENT_FENCE;
275         f = &g_content_features[i];
276         f->setInventoryTexture("fence.png");
277         f->light_propagates = true;
278         f->param_type = CPT_LIGHT;
279         f->is_ground_content = true;
280         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
281         f->solidness = 0; // drawn separately, makes no faces
282         f->air_equivalent = true; // grass grows underneath
283
284         // Deprecated
285         i = CONTENT_COALSTONE;
286         f = &g_content_features[i];
287         //f->translate_to = new MapNode(CONTENT_STONE, MINERAL_COAL);
288         f->setAllTextures("stone.png^mineral_coal.png");
289         f->is_ground_content = true;
290         
291         i = CONTENT_WOOD;
292         f = &g_content_features[i];
293         f->setAllTextures("wood.png");
294         f->is_ground_content = true;
295         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
296         
297         i = CONTENT_MESE;
298         f = &g_content_features[i];
299         f->setAllTextures("mese.png");
300         f->is_ground_content = true;
301         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
302         
303         i = CONTENT_CLOUD;
304         f = &g_content_features[i];
305         f->setAllTextures("cloud.png");
306         f->is_ground_content = true;
307         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
308         
309         i = CONTENT_AIR;
310         f = &g_content_features[i];
311         f->param_type = CPT_LIGHT;
312         f->light_propagates = true;
313         f->sunlight_propagates = true;
314         f->solidness = 0;
315         f->walkable = false;
316         f->pointable = false;
317         f->diggable = false;
318         f->buildable_to = true;
319         f->air_equivalent = true;
320         
321         i = CONTENT_WATER;
322         f = &g_content_features[i];
323         f->setInventoryTextureCube("water.png", "water.png", "water.png");
324         f->param_type = CPT_LIGHT;
325         f->light_propagates = true;
326         f->solidness = 0; // Drawn separately, makes no faces
327         f->walkable = false;
328         f->pointable = false;
329         f->diggable = false;
330         f->buildable_to = true;
331         f->liquid_type = LIQUID_FLOWING;
332         
333         i = CONTENT_WATERSOURCE;
334         f = &g_content_features[i];
335         f->setInventoryTexture("water.png");
336         if(new_style_water)
337         {
338                 f->solidness = 0; // drawn separately, makes no faces
339         }
340         else // old style
341         {
342                 f->solidness = 1;
343
344                 TileSpec t;
345                 if(g_texturesource)
346                         t.texture = g_texturesource->getTexture("water.png");
347                 
348                 t.alpha = WATER_ALPHA;
349                 t.material_type = MATERIAL_ALPHA_VERTEX;
350                 t.material_flags &= ~MATERIAL_FLAG_BACKFACE_CULLING;
351                 f->setAllTiles(t);
352         }
353         f->param_type = CPT_LIGHT;
354         f->light_propagates = true;
355         f->walkable = false;
356         f->pointable = false;
357         f->diggable = false;
358         f->buildable_to = true;
359         f->liquid_type = LIQUID_SOURCE;
360         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
361         
362         i = CONTENT_TORCH;
363         f = &g_content_features[i];
364         f->setInventoryTexture("torch_on_floor.png");
365         f->param_type = CPT_LIGHT;
366         f->light_propagates = true;
367         f->sunlight_propagates = true;
368         f->solidness = 0; // drawn separately, makes no faces
369         f->walkable = false;
370         f->wall_mounted = true;
371         f->air_equivalent = true;
372         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
373         
374         i = CONTENT_SIGN_WALL;
375         f = &g_content_features[i];
376         f->setInventoryTexture("sign_wall.png");
377         f->param_type = CPT_LIGHT;
378         f->light_propagates = true;
379         f->sunlight_propagates = true;
380         f->solidness = 0; // drawn separately, makes no faces
381         f->walkable = false;
382         f->wall_mounted = true;
383         f->air_equivalent = true;
384         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
385         if(f->initial_metadata == NULL)
386                 f->initial_metadata = new SignNodeMetadata("Some sign");
387         
388         i = CONTENT_CHEST;
389         f = &g_content_features[i];
390         f->param_type = CPT_FACEDIR_SIMPLE;
391         f->setAllTextures("chest_side.png");
392         f->setTexture(0, "chest_top.png");
393         f->setTexture(1, "chest_top.png");
394         f->setTexture(5, "chest_front.png"); // Z-
395         f->setInventoryTexture("chest_top.png");
396         //f->setInventoryTextureCube("chest_top.png", "chest_side.png", "chest_side.png");
397         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
398         if(f->initial_metadata == NULL)
399                 f->initial_metadata = new ChestNodeMetadata();
400         
401         i = CONTENT_FURNACE;
402         f = &g_content_features[i];
403         f->param_type = CPT_FACEDIR_SIMPLE;
404         f->setAllTextures("furnace_side.png");
405         f->setTexture(5, "furnace_front.png"); // Z-
406         f->setInventoryTexture("furnace_front.png");
407         //f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
408         f->dug_item = std::string("MaterialItem ")+itos(CONTENT_COBBLE)+" 6";
409         if(f->initial_metadata == NULL)
410                 f->initial_metadata = new FurnaceNodeMetadata();
411         
412         i = CONTENT_COBBLE;
413         f = &g_content_features[i];
414         f->setAllTextures("cobble.png");
415         f->setInventoryTextureCube("cobble.png", "cobble.png", "cobble.png");
416         f->param_type = CPT_NONE;
417         f->is_ground_content = true;
418         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
419         
420         i = CONTENT_STEEL;
421         f = &g_content_features[i];
422         f->setAllTextures("steel_block.png");
423         f->setInventoryTextureCube("steel_block.png", "steel_block.png",
424                         "steel_block.png");
425         f->param_type = CPT_NONE;
426         f->is_ground_content = true;
427         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
428         
429         // NOTE: Remember to add frequently used stuff to the texture atlas in tile.cpp
430 }
431
432 v3s16 facedir_rotate(u8 facedir, v3s16 dir)
433 {
434         /*
435                 Face 2 (normally Z-) direction:
436                 facedir=0: Z-
437                 facedir=1: X-
438                 facedir=2: Z+
439                 facedir=3: X+
440         */
441         v3s16 newdir;
442         if(facedir==0) // Same
443                 newdir = v3s16(dir.X, dir.Y, dir.Z);
444         else if(facedir == 1) // Face is taken from rotXZccv(-90)
445                 newdir = v3s16(-dir.Z, dir.Y, dir.X);
446         else if(facedir == 2) // Face is taken from rotXZccv(180)
447                 newdir = v3s16(-dir.X, dir.Y, -dir.Z);
448         else if(facedir == 3) // Face is taken from rotXZccv(90)
449                 newdir = v3s16(dir.Z, dir.Y, -dir.X);
450         else
451                 newdir = dir;
452         return newdir;
453 }
454
455 TileSpec MapNode::getTile(v3s16 dir)
456 {
457         if(content_features(d).param_type == CPT_FACEDIR_SIMPLE)
458                 dir = facedir_rotate(param1, dir);
459         
460         TileSpec spec;
461         
462         s32 dir_i = -1;
463         
464         if(dir == v3s16(0,0,0))
465                 dir_i = -1;
466         else if(dir == v3s16(0,1,0))
467                 dir_i = 0;
468         else if(dir == v3s16(0,-1,0))
469                 dir_i = 1;
470         else if(dir == v3s16(1,0,0))
471                 dir_i = 2;
472         else if(dir == v3s16(-1,0,0))
473                 dir_i = 3;
474         else if(dir == v3s16(0,0,1))
475                 dir_i = 4;
476         else if(dir == v3s16(0,0,-1))
477                 dir_i = 5;
478         
479         if(dir_i == -1)
480                 // Non-directional
481                 spec = content_features(d).tiles[0];
482         else 
483                 spec = content_features(d).tiles[dir_i];
484         
485         /*
486                 If it contains some mineral, change texture id
487         */
488         if(content_features(d).param_type == CPT_MINERAL && g_texturesource)
489         {
490                 u8 mineral = param & 0x1f;
491                 std::string mineral_texture_name = mineral_block_texture(mineral);
492                 if(mineral_texture_name != "")
493                 {
494                         u32 orig_id = spec.texture.id;
495                         std::string texture_name = g_texturesource->getTextureName(orig_id);
496                         //texture_name += "^blit:";
497                         texture_name += "^";
498                         texture_name += mineral_texture_name;
499                         u32 new_id = g_texturesource->getTextureId(texture_name);
500                         spec.texture = g_texturesource->getTexture(new_id);
501                 }
502         }
503
504         return spec;
505 }
506
507 u8 MapNode::getMineral()
508 {
509         if(content_features(d).param_type == CPT_MINERAL)
510         {
511                 return param & 0x1f;
512         }
513
514         return MINERAL_NONE;
515 }
516
517 // Pointers to c_str()s g_content_features[i].inventory_image_path
518 //const char * g_content_inventory_texture_paths[USEFUL_CONTENT_COUNT] = {0};
519
520 void init_content_inventory_texture_paths()
521 {
522         dstream<<"DEPRECATED "<<__FUNCTION_NAME<<std::endl;
523         /*for(u16 i=0; i<USEFUL_CONTENT_COUNT; i++)
524         {
525                 g_content_inventory_texture_paths[i] =
526                                 g_content_features[i].inventory_image_path.c_str();
527         }*/
528 }
529