]> git.lizzy.rs Git - minetest.git/blob - src/mapnode.cpp
merged CiaranG's changes (player privileges)
[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         i = CONTENT_GLASS;
209         f = &g_content_features[i];
210         f->light_propagates = true;
211         f->param_type = CPT_LIGHT;
212         f->is_ground_content = true;
213         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
214         f->solidness = 0; // drawn separately, makes no faces
215         f->setInventoryTextureCube("glass.png", "glass.png", "glass.png");
216
217
218         // Deprecated
219         i = CONTENT_COALSTONE;
220         f = &g_content_features[i];
221         //f->translate_to = new MapNode(CONTENT_STONE, MINERAL_COAL);
222         f->setAllTextures("stone.png^mineral_coal.png");
223         f->is_ground_content = true;
224         
225         i = CONTENT_WOOD;
226         f = &g_content_features[i];
227         f->setAllTextures("wood.png");
228         f->is_ground_content = true;
229         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
230         
231         i = CONTENT_MESE;
232         f = &g_content_features[i];
233         f->setAllTextures("mese.png");
234         f->is_ground_content = true;
235         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
236         
237         i = CONTENT_CLOUD;
238         f = &g_content_features[i];
239         f->setAllTextures("cloud.png");
240         f->is_ground_content = true;
241         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
242         
243         i = CONTENT_AIR;
244         f = &g_content_features[i];
245         f->param_type = CPT_LIGHT;
246         f->light_propagates = true;
247         f->sunlight_propagates = true;
248         f->solidness = 0;
249         f->walkable = false;
250         f->pointable = false;
251         f->diggable = false;
252         f->buildable_to = true;
253         
254         i = CONTENT_WATER;
255         f = &g_content_features[i];
256         f->setInventoryTextureCube("water.png", "water.png", "water.png");
257         f->param_type = CPT_LIGHT;
258         f->light_propagates = true;
259         f->solidness = 0; // Drawn separately, makes no faces
260         f->walkable = false;
261         f->pointable = false;
262         f->diggable = false;
263         f->buildable_to = true;
264         f->liquid_type = LIQUID_FLOWING;
265         
266         i = CONTENT_WATERSOURCE;
267         f = &g_content_features[i];
268         f->setInventoryTexture("water.png");
269         if(new_style_water)
270         {
271                 f->solidness = 0; // drawn separately, makes no faces
272         }
273         else // old style
274         {
275                 f->solidness = 1;
276
277                 TileSpec t;
278                 if(g_texturesource)
279                         t.texture = g_texturesource->getTexture("water.png");
280                 
281                 t.alpha = WATER_ALPHA;
282                 t.material_type = MATERIAL_ALPHA_VERTEX;
283                 t.material_flags &= ~MATERIAL_FLAG_BACKFACE_CULLING;
284                 f->setAllTiles(t);
285         }
286         f->param_type = CPT_LIGHT;
287         f->light_propagates = true;
288         f->walkable = false;
289         f->pointable = false;
290         f->diggable = false;
291         f->buildable_to = true;
292         f->liquid_type = LIQUID_SOURCE;
293         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
294         
295         i = CONTENT_TORCH;
296         f = &g_content_features[i];
297         f->setInventoryTexture("torch_on_floor.png");
298         f->param_type = CPT_LIGHT;
299         f->light_propagates = true;
300         f->sunlight_propagates = true;
301         f->solidness = 0; // drawn separately, makes no faces
302         f->walkable = false;
303         f->wall_mounted = true;
304         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
305         
306         i = CONTENT_SIGN_WALL;
307         f = &g_content_features[i];
308         f->setInventoryTexture("sign_wall.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->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
316         if(f->initial_metadata == NULL)
317                 f->initial_metadata = new SignNodeMetadata("Some sign");
318         
319         i = CONTENT_CHEST;
320         f = &g_content_features[i];
321         f->param_type = CPT_FACEDIR_SIMPLE;
322         f->setAllTextures("chest_side.png");
323         f->setTexture(0, "chest_top.png");
324         f->setTexture(1, "chest_top.png");
325         f->setTexture(5, "chest_front.png"); // Z-
326         f->setInventoryTexture("chest_top.png");
327         //f->setInventoryTextureCube("chest_top.png", "chest_side.png", "chest_side.png");
328         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
329         if(f->initial_metadata == NULL)
330                 f->initial_metadata = new ChestNodeMetadata();
331         
332         i = CONTENT_FURNACE;
333         f = &g_content_features[i];
334         f->param_type = CPT_FACEDIR_SIMPLE;
335         f->setAllTextures("furnace_side.png");
336         f->setTexture(5, "furnace_front.png"); // Z-
337         f->setInventoryTexture("furnace_front.png");
338         //f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
339         f->dug_item = std::string("MaterialItem ")+itos(CONTENT_COBBLE)+" 6";
340         if(f->initial_metadata == NULL)
341                 f->initial_metadata = new FurnaceNodeMetadata();
342         
343         i = CONTENT_COBBLE;
344         f = &g_content_features[i];
345         f->setAllTextures("cobble.png");
346         f->setInventoryTextureCube("cobble.png", "cobble.png", "cobble.png");
347         f->param_type = CPT_NONE;
348         f->is_ground_content = true;
349         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
350         
351         i = CONTENT_STEEL;
352         f = &g_content_features[i];
353         f->setAllTextures("steel_block.png");
354         f->setInventoryTextureCube("steel_block.png", "steel_block.png",
355                         "steel_block.png");
356         f->param_type = CPT_NONE;
357         f->is_ground_content = true;
358         f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
359         
360         // NOTE: Remember to add frequently used stuff to the texture atlas in tile.cpp
361 }
362
363 v3s16 facedir_rotate(u8 facedir, v3s16 dir)
364 {
365         /*
366                 Face 2 (normally Z-) direction:
367                 facedir=0: Z-
368                 facedir=1: X-
369                 facedir=2: Z+
370                 facedir=3: X+
371         */
372         v3s16 newdir;
373         if(facedir==0) // Same
374                 newdir = v3s16(dir.X, dir.Y, dir.Z);
375         else if(facedir == 1) // Face is taken from rotXZccv(-90)
376                 newdir = v3s16(-dir.Z, dir.Y, dir.X);
377         else if(facedir == 2) // Face is taken from rotXZccv(180)
378                 newdir = v3s16(-dir.X, dir.Y, -dir.Z);
379         else if(facedir == 3) // Face is taken from rotXZccv(90)
380                 newdir = v3s16(dir.Z, dir.Y, -dir.X);
381         else
382                 newdir = dir;
383         return newdir;
384 }
385
386 TileSpec MapNode::getTile(v3s16 dir)
387 {
388         if(content_features(d).param_type == CPT_FACEDIR_SIMPLE)
389                 dir = facedir_rotate(param1, dir);
390         
391         TileSpec spec;
392         
393         s32 dir_i = -1;
394         
395         if(dir == v3s16(0,0,0))
396                 dir_i = -1;
397         else if(dir == v3s16(0,1,0))
398                 dir_i = 0;
399         else if(dir == v3s16(0,-1,0))
400                 dir_i = 1;
401         else if(dir == v3s16(1,0,0))
402                 dir_i = 2;
403         else if(dir == v3s16(-1,0,0))
404                 dir_i = 3;
405         else if(dir == v3s16(0,0,1))
406                 dir_i = 4;
407         else if(dir == v3s16(0,0,-1))
408                 dir_i = 5;
409         
410         if(dir_i == -1)
411                 // Non-directional
412                 spec = content_features(d).tiles[0];
413         else 
414                 spec = content_features(d).tiles[dir_i];
415         
416         /*
417                 If it contains some mineral, change texture id
418         */
419         if(content_features(d).param_type == CPT_MINERAL && g_texturesource)
420         {
421                 u8 mineral = param & 0x1f;
422                 std::string mineral_texture_name = mineral_block_texture(mineral);
423                 if(mineral_texture_name != "")
424                 {
425                         u32 orig_id = spec.texture.id;
426                         std::string texture_name = g_texturesource->getTextureName(orig_id);
427                         //texture_name += "^blit:";
428                         texture_name += "^";
429                         texture_name += mineral_texture_name;
430                         u32 new_id = g_texturesource->getTextureId(texture_name);
431                         spec.texture = g_texturesource->getTexture(new_id);
432                 }
433         }
434
435         return spec;
436 }
437
438 u8 MapNode::getMineral()
439 {
440         if(content_features(d).param_type == CPT_MINERAL)
441         {
442                 return param & 0x1f;
443         }
444
445         return MINERAL_NONE;
446 }
447
448 // Pointers to c_str()s g_content_features[i].inventory_image_path
449 //const char * g_content_inventory_texture_paths[USEFUL_CONTENT_COUNT] = {0};
450
451 void init_content_inventory_texture_paths()
452 {
453         dstream<<"DEPRECATED "<<__FUNCTION_NAME<<std::endl;
454         /*for(u16 i=0; i<USEFUL_CONTENT_COUNT; i++)
455         {
456                 g_content_inventory_texture_paths[i] =
457                                 g_content_features[i].inventory_image_path.c_str();
458         }*/
459 }
460