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(actual_d == CONTENT_IGNORE)
272 else if(actual_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)
322 // Convert from old version to new
325 // In these versions, CONTENT_IGNORE and CONTENT_AIR
332 // version 19 is fucked up with sometimes the old values and sometimes not
343 Gets lighting value at face of node
345 Parameters must consist of air and !air.
346 Order doesn't matter.
348 If either of the nodes doesn't exist, light is 0.
351 daynight_ratio: 0...1000
353 n2: getNodeParent(p + face_dir)
354 face_dir: axis oriented unit vector from p to p2
356 returns encoded light value.
358 u8 getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2,
363 u8 l1 = n.getLightBlend(daynight_ratio);
364 u8 l2 = n2.getLightBlend(daynight_ratio);
370 // Make some nice difference to different sides
372 // This makes light come from a corner
373 /*if(face_dir.X == 1 || face_dir.Z == 1 || face_dir.Y == -1)
374 light = diminish_light(diminish_light(light));
375 else if(face_dir.X == -1 || face_dir.Z == -1)
376 light = diminish_light(light);*/
378 // All neighboring faces have different shade (like in minecraft)
379 if(face_dir.X == 1 || face_dir.X == -1 || face_dir.Y == -1)
380 light = diminish_light(diminish_light(light));
381 else if(face_dir.Z == 1 || face_dir.Z == -1)
382 light = diminish_light(light);
386 catch(InvalidPositionException &e)