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()
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->setInventoryTextureCube("unknown_block.png", "unknown_block.png", "unknown_block.png");
150 f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
154 Initialize mapnode content
156 content_mapnode_init();
160 v3s16 facedir_rotate(u8 facedir, v3s16 dir)
163 Face 2 (normally Z-) direction:
170 if(facedir==0) // Same
171 newdir = v3s16(dir.X, dir.Y, dir.Z);
172 else if(facedir == 1) // Face is taken from rotXZccv(-90)
173 newdir = v3s16(-dir.Z, dir.Y, dir.X);
174 else if(facedir == 2) // Face is taken from rotXZccv(180)
175 newdir = v3s16(-dir.X, dir.Y, -dir.Z);
176 else if(facedir == 3) // Face is taken from rotXZccv(90)
177 newdir = v3s16(dir.Z, dir.Y, -dir.X);
183 TileSpec MapNode::getTile(v3s16 dir)
185 if(content_features(d).param_type == CPT_FACEDIR_SIMPLE)
186 dir = facedir_rotate(param1, dir);
192 if(dir == v3s16(0,0,0))
194 else if(dir == v3s16(0,1,0))
196 else if(dir == v3s16(0,-1,0))
198 else if(dir == v3s16(1,0,0))
200 else if(dir == v3s16(-1,0,0))
202 else if(dir == v3s16(0,0,1))
204 else if(dir == v3s16(0,0,-1))
209 spec = content_features(d).tiles[0];
211 spec = content_features(d).tiles[dir_i];
214 If it contains some mineral, change texture id
216 if(content_features(d).param_type == CPT_MINERAL && g_texturesource)
218 u8 mineral = param & 0x1f;
219 std::string mineral_texture_name = mineral_block_texture(mineral);
220 if(mineral_texture_name != "")
222 u32 orig_id = spec.texture.id;
223 std::string texture_name = g_texturesource->getTextureName(orig_id);
224 //texture_name += "^blit:";
226 texture_name += mineral_texture_name;
227 u32 new_id = g_texturesource->getTextureId(texture_name);
228 spec.texture = g_texturesource->getTexture(new_id);
235 u8 MapNode::getMineral()
237 if(content_features(d).param_type == CPT_MINERAL)
246 Gets lighting value at face of node
248 Parameters must consist of air and !air.
249 Order doesn't matter.
251 If either of the nodes doesn't exist, light is 0.
254 daynight_ratio: 0...1000
256 n2: getNodeParent(p + face_dir)
257 face_dir: axis oriented unit vector from p to p2
259 returns encoded light value.
261 u8 getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2,
266 u8 l1 = n.getLightBlend(daynight_ratio);
267 u8 l2 = n2.getLightBlend(daynight_ratio);
273 // Make some nice difference to different sides
275 // This makes light come from a corner
276 /*if(face_dir.X == 1 || face_dir.Z == 1 || face_dir.Y == -1)
277 light = diminish_light(diminish_light(light));
278 else if(face_dir.X == -1 || face_dir.Z == -1)
279 light = diminish_light(light);*/
281 // All neighboring faces have different shade (like in minecraft)
282 if(face_dir.X == 1 || face_dir.X == -1 || face_dir.Y == -1)
283 light = diminish_light(diminish_light(light));
284 else if(face_dir.Z == 1 || face_dir.Z == -1)
285 light = diminish_light(light);
289 catch(InvalidPositionException &e)