3 Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
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.
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.
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.
20 #include "common_irrlicht.h"
28 #include "nodemetadata.h"
30 ContentFeatures::~ContentFeatures()
35 delete initial_metadata;
38 void ContentFeatures::setTexture(u16 i, std::string name, u8 alpha)
42 tiles[i].texture = g_texturesource->getTexture(name);
47 tiles[i].alpha = alpha;
48 tiles[i].material_type = MATERIAL_ALPHA_VERTEX;
51 if(inventory_texture == NULL)
52 setInventoryTexture(name);
55 void ContentFeatures::setInventoryTexture(std::string imgname)
57 if(g_texturesource == NULL)
60 imgname += "^[forcesingle";
62 inventory_texture = g_texturesource->getTextureRaw(imgname);
65 void ContentFeatures::setInventoryTextureCube(std::string top,
66 std::string left, std::string right)
68 if(g_texturesource == NULL)
71 str_replace_char(top, '^', '&');
72 str_replace_char(left, '^', '&');
73 str_replace_char(right, '^', '&');
75 std::string imgname_full;
76 imgname_full += "[inventorycube{";
81 imgname_full += right;
82 inventory_texture = g_texturesource->getTextureRaw(imgname_full);
85 struct ContentFeatures g_content_features[256];
87 ContentFeatures & content_features(u8 i)
89 return g_content_features[i];
93 See mapnode.h for description.
97 if(g_texturesource == NULL)
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;
106 dstream<<"INFO: Full run of init_mapnode with "
107 "g_texturesource!=NULL"<<std::endl;
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");
115 Initialize content feature table
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.
125 u8 initial_material_type = MATERIAL_ALPHA_SIMPLE;
126 /*if(new_style_leaves)
127 initial_material_type = MATERIAL_ALPHA_SIMPLE;
129 initial_material_type = MATERIAL_ALPHA_NONE;*/
130 for(u16 i=0; i<256; i++)
132 ContentFeatures *f = &g_content_features[i];
134 *f = ContentFeatures();
136 for(u16 j=0; j<6; j++)
137 f->tiles[j].material_type = initial_material_type;
141 ContentFeatures *f = NULL;
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";
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";
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";
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";
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";
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";
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");
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");
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";
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;
225 f->solidness = 0; // drawn separately, makes no faces
226 f->setInventoryTextureCube("leaves.png", "leaves.png", "leaves.png");
230 f->setAllTextures("[noalpha:leaves.png");
232 f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
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";
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
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;
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");
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
285 f = &g_content_features[i];
286 f->setInventoryTexture("rail.png");
287 f->light_propagates = true;
288 f->param_type = CPT_LIGHT;
289 f->is_ground_content = true;
290 f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
291 f->solidness = 0; // drawn separately, makes no faces
292 f->air_equivalent = true; // grass grows underneath
296 i = CONTENT_COALSTONE;
297 f = &g_content_features[i];
298 //f->translate_to = new MapNode(CONTENT_STONE, MINERAL_COAL);
299 f->setAllTextures("stone.png^mineral_coal.png");
300 f->is_ground_content = true;
303 f = &g_content_features[i];
304 f->setAllTextures("wood.png");
305 f->is_ground_content = true;
306 f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
309 f = &g_content_features[i];
310 f->setAllTextures("mese.png");
311 f->is_ground_content = true;
312 f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
315 f = &g_content_features[i];
316 f->setAllTextures("cloud.png");
317 f->is_ground_content = true;
318 f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
321 f = &g_content_features[i];
322 f->param_type = CPT_LIGHT;
323 f->light_propagates = true;
324 f->sunlight_propagates = true;
327 f->pointable = false;
329 f->buildable_to = true;
330 f->air_equivalent = true;
333 f = &g_content_features[i];
334 f->setInventoryTextureCube("water.png", "water.png", "water.png");
335 f->param_type = CPT_LIGHT;
336 f->light_propagates = true;
337 f->solidness = 0; // Drawn separately, makes no faces
339 f->pointable = false;
341 f->buildable_to = true;
342 f->liquid_type = LIQUID_FLOWING;
344 i = CONTENT_WATERSOURCE;
345 f = &g_content_features[i];
346 f->setInventoryTexture("water.png");
349 f->solidness = 0; // drawn separately, makes no faces
357 t.texture = g_texturesource->getTexture("water.png");
359 t.alpha = WATER_ALPHA;
360 t.material_type = MATERIAL_ALPHA_VERTEX;
361 t.material_flags &= ~MATERIAL_FLAG_BACKFACE_CULLING;
364 f->param_type = CPT_LIGHT;
365 f->light_propagates = true;
367 f->pointable = false;
369 f->buildable_to = true;
370 f->liquid_type = LIQUID_SOURCE;
371 f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
374 f = &g_content_features[i];
375 f->setInventoryTexture("torch_on_floor.png");
376 f->param_type = CPT_LIGHT;
377 f->light_propagates = true;
378 f->sunlight_propagates = true;
379 f->solidness = 0; // drawn separately, makes no faces
381 f->wall_mounted = true;
382 f->air_equivalent = true;
383 f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
385 i = CONTENT_SIGN_WALL;
386 f = &g_content_features[i];
387 f->setInventoryTexture("sign_wall.png");
388 f->param_type = CPT_LIGHT;
389 f->light_propagates = true;
390 f->sunlight_propagates = true;
391 f->solidness = 0; // drawn separately, makes no faces
393 f->wall_mounted = true;
394 f->air_equivalent = true;
395 f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
396 if(f->initial_metadata == NULL)
397 f->initial_metadata = new SignNodeMetadata("Some sign");
400 f = &g_content_features[i];
401 f->param_type = CPT_FACEDIR_SIMPLE;
402 f->setAllTextures("chest_side.png");
403 f->setTexture(0, "chest_top.png");
404 f->setTexture(1, "chest_top.png");
405 f->setTexture(5, "chest_front.png"); // Z-
406 f->setInventoryTexture("chest_top.png");
407 //f->setInventoryTextureCube("chest_top.png", "chest_side.png", "chest_side.png");
408 f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
409 if(f->initial_metadata == NULL)
410 f->initial_metadata = new ChestNodeMetadata();
413 f = &g_content_features[i];
414 f->param_type = CPT_FACEDIR_SIMPLE;
415 f->setAllTextures("furnace_side.png");
416 f->setTexture(5, "furnace_front.png"); // Z-
417 f->setInventoryTexture("furnace_front.png");
418 //f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
419 f->dug_item = std::string("MaterialItem ")+itos(CONTENT_COBBLE)+" 6";
420 if(f->initial_metadata == NULL)
421 f->initial_metadata = new FurnaceNodeMetadata();
424 f = &g_content_features[i];
425 f->setAllTextures("cobble.png");
426 f->setInventoryTextureCube("cobble.png", "cobble.png", "cobble.png");
427 f->param_type = CPT_NONE;
428 f->is_ground_content = true;
429 f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
432 f = &g_content_features[i];
433 f->setAllTextures("steel_block.png");
434 f->setInventoryTextureCube("steel_block.png", "steel_block.png",
436 f->param_type = CPT_NONE;
437 f->is_ground_content = true;
438 f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
440 // NOTE: Remember to add frequently used stuff to the texture atlas in tile.cpp
443 v3s16 facedir_rotate(u8 facedir, v3s16 dir)
446 Face 2 (normally Z-) direction:
453 if(facedir==0) // Same
454 newdir = v3s16(dir.X, dir.Y, dir.Z);
455 else if(facedir == 1) // Face is taken from rotXZccv(-90)
456 newdir = v3s16(-dir.Z, dir.Y, dir.X);
457 else if(facedir == 2) // Face is taken from rotXZccv(180)
458 newdir = v3s16(-dir.X, dir.Y, -dir.Z);
459 else if(facedir == 3) // Face is taken from rotXZccv(90)
460 newdir = v3s16(dir.Z, dir.Y, -dir.X);
466 TileSpec MapNode::getTile(v3s16 dir)
468 if(content_features(d).param_type == CPT_FACEDIR_SIMPLE)
469 dir = facedir_rotate(param1, dir);
475 if(dir == v3s16(0,0,0))
477 else if(dir == v3s16(0,1,0))
479 else if(dir == v3s16(0,-1,0))
481 else if(dir == v3s16(1,0,0))
483 else if(dir == v3s16(-1,0,0))
485 else if(dir == v3s16(0,0,1))
487 else if(dir == v3s16(0,0,-1))
492 spec = content_features(d).tiles[0];
494 spec = content_features(d).tiles[dir_i];
497 If it contains some mineral, change texture id
499 if(content_features(d).param_type == CPT_MINERAL && g_texturesource)
501 u8 mineral = param & 0x1f;
502 std::string mineral_texture_name = mineral_block_texture(mineral);
503 if(mineral_texture_name != "")
505 u32 orig_id = spec.texture.id;
506 std::string texture_name = g_texturesource->getTextureName(orig_id);
507 //texture_name += "^blit:";
509 texture_name += mineral_texture_name;
510 u32 new_id = g_texturesource->getTextureId(texture_name);
511 spec.texture = g_texturesource->getTexture(new_id);
518 u8 MapNode::getMineral()
520 if(content_features(d).param_type == CPT_MINERAL)
528 // Pointers to c_str()s g_content_features[i].inventory_image_path
529 //const char * g_content_inventory_texture_paths[USEFUL_CONTENT_COUNT] = {0};
531 void init_content_inventory_texture_paths()
533 dstream<<"DEPRECATED "<<__FUNCTION_NAME<<std::endl;
534 /*for(u16 i=0; i<USEFUL_CONTENT_COUNT; i++)
536 g_content_inventory_texture_paths[i] =
537 g_content_features[i].inventory_image_path.c_str();