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<256; i++)
147 if(i == CONTENT_IGNORE || i == CONTENT_AIR)
149 ContentFeatures *f = &g_content_features[i];
150 f->setAllTextures("unknown_block.png");
151 f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
155 Initialize mapnode content
157 content_mapnode_init();
161 v3s16 facedir_rotate(u8 facedir, v3s16 dir)
164 Face 2 (normally Z-) direction:
171 if(facedir==0) // Same
172 newdir = v3s16(dir.X, dir.Y, dir.Z);
173 else if(facedir == 1) // Face is taken from rotXZccv(-90)
174 newdir = v3s16(-dir.Z, dir.Y, dir.X);
175 else if(facedir == 2) // Face is taken from rotXZccv(180)
176 newdir = v3s16(-dir.X, dir.Y, -dir.Z);
177 else if(facedir == 3) // Face is taken from rotXZccv(90)
178 newdir = v3s16(dir.Z, dir.Y, -dir.X);
184 TileSpec MapNode::getTile(v3s16 dir)
186 if(content_features(d).param_type == CPT_FACEDIR_SIMPLE)
187 dir = facedir_rotate(param1, dir);
193 if(dir == v3s16(0,0,0))
195 else if(dir == v3s16(0,1,0))
197 else if(dir == v3s16(0,-1,0))
199 else if(dir == v3s16(1,0,0))
201 else if(dir == v3s16(-1,0,0))
203 else if(dir == v3s16(0,0,1))
205 else if(dir == v3s16(0,0,-1))
210 spec = content_features(d).tiles[0];
212 spec = content_features(d).tiles[dir_i];
215 If it contains some mineral, change texture id
217 if(content_features(d).param_type == CPT_MINERAL && g_texturesource)
219 u8 mineral = param & 0x1f;
220 std::string mineral_texture_name = mineral_block_texture(mineral);
221 if(mineral_texture_name != "")
223 u32 orig_id = spec.texture.id;
224 std::string texture_name = g_texturesource->getTextureName(orig_id);
225 //texture_name += "^blit:";
227 texture_name += mineral_texture_name;
228 u32 new_id = g_texturesource->getTextureId(texture_name);
229 spec.texture = g_texturesource->getTexture(new_id);
236 u8 MapNode::getMineral()
238 if(content_features(d).param_type == CPT_MINERAL)
246 u32 MapNode::serializedLength(u8 version)
248 if(!ser_ver_supported(version))
249 throw VersionMismatchException("ERROR: MapNode format not supported");
253 else if(version <= 9)
258 void MapNode::serialize(u8 *dest, u8 version)
260 if(!ser_ver_supported(version))
261 throw VersionMismatchException("ERROR: MapNode format not supported");
265 // Convert from new version to old
268 // In these versions, CONTENT_IGNORE and CONTENT_AIR
270 if(d == CONTENT_IGNORE)
272 else if(d == CONTENT_AIR)
280 else if(version <= 9)
292 void MapNode::deSerialize(u8 *source, u8 version)
294 if(!ser_ver_supported(version))
295 throw VersionMismatchException("ERROR: MapNode format not supported");
301 else if(version == 1)
304 // This version doesn't support saved lighting
305 if(light_propagates() || light_source() > 0)
310 else if(version <= 9)
321 // Convert from old version to new
324 // In these versions, CONTENT_IGNORE and CONTENT_AIR
335 Gets lighting value at face of node
337 Parameters must consist of air and !air.
338 Order doesn't matter.
340 If either of the nodes doesn't exist, light is 0.
343 daynight_ratio: 0...1000
345 n2: getNodeParent(p + face_dir)
346 face_dir: axis oriented unit vector from p to p2
348 returns encoded light value.
350 u8 getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2,
355 u8 l1 = n.getLightBlend(daynight_ratio);
356 u8 l2 = n2.getLightBlend(daynight_ratio);
362 // Make some nice difference to different sides
364 // This makes light come from a corner
365 /*if(face_dir.X == 1 || face_dir.Z == 1 || face_dir.Y == -1)
366 light = diminish_light(diminish_light(light));
367 else if(face_dir.X == -1 || face_dir.Z == -1)
368 light = diminish_light(light);*/
370 // All neighboring faces have different shade (like in minecraft)
371 if(face_dir.X == 1 || face_dir.X == -1 || face_dir.Y == -1)
372 light = diminish_light(diminish_light(light));
373 else if(face_dir.Z == 1 || face_dir.Z == -1)
374 light = diminish_light(light);
378 catch(InvalidPositionException &e)