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