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 "content_mapnode.h"
29 #include "nodemetadata.h"
31 ContentFeatures::~ContentFeatures()
34 delete translate_to;*/
36 delete initial_metadata;
39 void ContentFeatures::setTexture(u16 i, std::string name, u8 alpha)
43 tiles[i].texture = g_texturesource->getTexture(name);
48 tiles[i].alpha = alpha;
49 tiles[i].material_type = MATERIAL_ALPHA_VERTEX;
52 if(inventory_texture == NULL)
53 setInventoryTexture(name);
56 void ContentFeatures::setInventoryTexture(std::string imgname)
58 if(g_texturesource == NULL)
61 imgname += "^[forcesingle";
63 inventory_texture = g_texturesource->getTextureRaw(imgname);
66 void ContentFeatures::setInventoryTextureCube(std::string top,
67 std::string left, std::string right)
69 if(g_texturesource == NULL)
72 str_replace_char(top, '^', '&');
73 str_replace_char(left, '^', '&');
74 str_replace_char(right, '^', '&');
76 std::string imgname_full;
77 imgname_full += "[inventorycube{";
82 imgname_full += right;
83 inventory_texture = g_texturesource->getTextureRaw(imgname_full);
86 struct ContentFeatures g_content_features[256];
88 ContentFeatures & content_features(u8 i)
90 return g_content_features[i];
94 See mapnode.h for description.
98 if(g_texturesource == NULL)
100 dstream<<"INFO: Initial run of init_mapnode with "
101 "g_texturesource=NULL. If this segfaults, "
102 "there is a bug with something not checking for "
103 "the NULL value."<<std::endl;
107 dstream<<"INFO: Full run of init_mapnode with "
108 "g_texturesource!=NULL"<<std::endl;
111 /*// Read some settings
112 bool new_style_water = g_settings.getBool("new_style_water");
113 bool new_style_leaves = g_settings.getBool("new_style_leaves");*/
116 Initialize content feature table
120 Set initial material type to same in all tiles, so that the
121 same material can be used in more stuff.
122 This is set according to the leaves because they are the only
123 differing material to which all materials can be changed to
124 get this optimization.
126 u8 initial_material_type = MATERIAL_ALPHA_SIMPLE;
127 /*if(new_style_leaves)
128 initial_material_type = MATERIAL_ALPHA_SIMPLE;
130 initial_material_type = MATERIAL_ALPHA_NONE;*/
131 for(u16 i=0; i<256; i++)
133 ContentFeatures *f = &g_content_features[i];
137 for(u16 j=0; j<6; j++)
138 f->tiles[j].material_type = initial_material_type;
142 Initially set every block to be shown as an unknown block.
143 Don't touch CONTENT_IGNORE or CONTENT_AIR.
145 for(u16 i=0; i<=253; i++)
147 ContentFeatures *f = &g_content_features[i];
148 f->setAllTextures("unknown_block.png");
149 f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
153 Initialize mapnode content
155 content_mapnode_init();
159 v3s16 facedir_rotate(u8 facedir, v3s16 dir)
162 Face 2 (normally Z-) direction:
169 if(facedir==0) // Same
170 newdir = v3s16(dir.X, dir.Y, dir.Z);
171 else if(facedir == 1) // Face is taken from rotXZccv(-90)
172 newdir = v3s16(-dir.Z, dir.Y, dir.X);
173 else if(facedir == 2) // Face is taken from rotXZccv(180)
174 newdir = v3s16(-dir.X, dir.Y, -dir.Z);
175 else if(facedir == 3) // Face is taken from rotXZccv(90)
176 newdir = v3s16(dir.Z, dir.Y, -dir.X);
182 TileSpec MapNode::getTile(v3s16 dir)
184 if(content_features(d).param_type == CPT_FACEDIR_SIMPLE)
185 dir = facedir_rotate(param1, dir);
191 if(dir == v3s16(0,0,0))
193 else if(dir == v3s16(0,1,0))
195 else if(dir == v3s16(0,-1,0))
197 else if(dir == v3s16(1,0,0))
199 else if(dir == v3s16(-1,0,0))
201 else if(dir == v3s16(0,0,1))
203 else if(dir == v3s16(0,0,-1))
208 spec = content_features(d).tiles[0];
210 spec = content_features(d).tiles[dir_i];
213 If it contains some mineral, change texture id
215 if(content_features(d).param_type == CPT_MINERAL && g_texturesource)
217 u8 mineral = param & 0x1f;
218 std::string mineral_texture_name = mineral_block_texture(mineral);
219 if(mineral_texture_name != "")
221 u32 orig_id = spec.texture.id;
222 std::string texture_name = g_texturesource->getTextureName(orig_id);
223 //texture_name += "^blit:";
225 texture_name += mineral_texture_name;
226 u32 new_id = g_texturesource->getTextureId(texture_name);
227 spec.texture = g_texturesource->getTexture(new_id);
234 u8 MapNode::getMineral()
236 if(content_features(d).param_type == CPT_MINERAL)
244 u32 MapNode::serializedLength(u8 version)
246 if(!ser_ver_supported(version))
247 throw VersionMismatchException("ERROR: MapNode format not supported");
251 else if(version <= 9)
256 void MapNode::serialize(u8 *dest, u8 version)
258 if(!ser_ver_supported(version))
259 throw VersionMismatchException("ERROR: MapNode format not supported");
263 // Convert from new version to old
266 // In these versions, CONTENT_IGNORE and CONTENT_AIR
268 if(d == CONTENT_IGNORE)
270 else if(d == CONTENT_AIR)
278 else if(version <= 9)
290 void MapNode::deSerialize(u8 *source, u8 version)
292 if(!ser_ver_supported(version))
293 throw VersionMismatchException("ERROR: MapNode format not supported");
299 else if(version == 1)
302 // This version doesn't support saved lighting
303 if(light_propagates() || light_source() > 0)
308 else if(version <= 9)
319 // Convert from old version to new
322 // In these versions, CONTENT_IGNORE and CONTENT_AIR
333 Gets lighting value at face of node
335 Parameters must consist of air and !air.
336 Order doesn't matter.
338 If either of the nodes doesn't exist, light is 0.
341 daynight_ratio: 0...1000
343 n2: getNodeParent(p + face_dir)
344 face_dir: axis oriented unit vector from p to p2
346 returns encoded light value.
348 u8 getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2,
353 u8 l1 = n.getLightBlend(daynight_ratio);
354 u8 l2 = n2.getLightBlend(daynight_ratio);
360 // Make some nice difference to different sides
362 // This makes light come from a corner
363 /*if(face_dir.X == 1 || face_dir.Z == 1 || face_dir.Y == -1)
364 light = diminish_light(diminish_light(light));
365 else if(face_dir.X == -1 || face_dir.Z == -1)
366 light = diminish_light(light);*/
368 // All neighboring faces have different shade (like in minecraft)
369 if(face_dir.X == 1 || face_dir.X == -1 || face_dir.Y == -1)
370 light = diminish_light(diminish_light(light));
371 else if(face_dir.Z == 1 || face_dir.Z == -1)
372 light = diminish_light(light);
376 catch(InvalidPositionException &e)