3 Copyright (C) 2010-2011 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 #ifndef MAPNODE_HEADER
21 #define MAPNODE_HEADER
24 #include "common_irrlicht.h"
27 #include "exceptions.h"
28 #include "serialization.h"
30 #include "materials.h"
34 - Material = irrlicht's Material class
35 - Content = (u8) content of a node
36 - Tile = TileSpec at some side of a node of some content type
40 Initializes all kind of stuff in here.
41 Many things depend on this.
43 This accesses g_texturesource; if it is non-NULL, textures are set.
45 Client first calls this with g_texturesource=NULL to run some
46 unit tests and stuff, then it runs this again with g_texturesource
47 defined to get the textures.
49 Server only calls this once with g_texturesource=NULL.
56 Anything that stores MapNodes doesn't have to preserve parameters
57 associated with this material.
59 Doesn't create faces with anything and is considered being
60 out-of-map in the game map.
62 #define CONTENT_IGNORE 255
63 #define CONTENT_IGNORE_DEFAULT_PARAM 0
66 The common material through which the player can walk and which
67 is transparent to light
69 #define CONTENT_AIR 254
80 // Direction for chests and furnaces and such
94 struct ContentFeatures
96 // If non-NULL, content is translated to this when deserialized
97 MapNode *translate_to;
99 // Type of MapNode::param
100 ContentParamType param_type;
112 video::ITexture *inventory_texture;
114 bool is_ground_content;
115 bool light_propagates;
116 bool sunlight_propagates;
117 u8 solidness; // Used when choosing which face is drawn
118 // This is used for collision detection.
119 // Also for general solidness queries.
121 // Player can point to these
123 // Player can dig these
125 // Player can build on these
127 // Whether the node has no liquid, source liquid or flowing liquid
128 enum LiquidType liquid_type;
129 // If true, param2 is set to direction when placed. Used for torches.
130 // NOTE: the direction format is quite inefficient and should be changed
132 // If true, node is equivalent to air. Torches are, air is. Water is not.
133 // Is used for example to check whether a mud block can have grass on.
136 // Inventory item string as which the node appears in inventory when dug.
137 // Mineral overrides this.
138 std::string dug_item;
140 // Initial metadata is cloned from this
141 NodeMetadata *initial_metadata;
143 // If the content is liquid, this is the flowing version of the liquid.
144 // If content is liquid, this is the same content.
145 u8 liquid_alternative_flowing;
147 // Amount of light the node emits
150 // Digging properties for different tools
151 DiggingPropertiesList digging_properties;
153 // NOTE: Move relevant properties to here from elsewhere
158 param_type = CPT_NONE;
159 inventory_texture = NULL;
160 is_ground_content = false;
161 light_propagates = false;
162 sunlight_propagates = false;
167 buildable_to = false;
168 liquid_type = LIQUID_NONE;
169 wall_mounted = false;
170 air_equivalent = false;
172 initial_metadata = NULL;
173 liquid_alternative_flowing = CONTENT_IGNORE;
175 digging_properties.clear();
186 Quickhands for simple materials
189 void setTexture(u16 i, std::string name, u8 alpha=255);
191 void setAllTextures(std::string name, u8 alpha=255)
193 for(u16 i=0; i<6; i++)
195 setTexture(i, name, alpha);
199 void setTile(u16 i, const TileSpec &tile)
203 void setAllTiles(const TileSpec &tile)
205 for(u16 i=0; i<6; i++)
211 void setInventoryTexture(std::string imgname);
213 void setInventoryTextureCube(std::string top,
214 std::string left, std::string right);
218 Call this to access the ContentFeature list
220 ContentFeatures & content_features(u8 i);
224 Here is a bunch of DEPRECATED functions.
228 If true, the material allows light propagation and brightness is stored
230 NOTE: Don't use, use "content_features(m).whatever" instead
232 inline bool light_propagates_content(u8 m)
234 return content_features(m).light_propagates;
237 If true, the material allows lossless sunlight propagation.
238 NOTE: It doesn't seem to go through torches regardlessly of this
239 NOTE: Don't use, use "content_features(m).whatever" instead
241 inline bool sunlight_propagates_content(u8 m)
243 return content_features(m).sunlight_propagates;
246 On a node-node surface, the material of the node with higher solidness
251 NOTE: Don't use, use "content_features(m).whatever" instead
253 inline u8 content_solidness(u8 m)
255 return content_features(m).solidness;
257 // Objects collide with walkable contents
258 // NOTE: Don't use, use "content_features(m).whatever" instead
259 inline bool content_walkable(u8 m)
261 return content_features(m).walkable;
263 // NOTE: Don't use, use "content_features(m).whatever" instead
264 inline bool content_liquid(u8 m)
266 return content_features(m).liquid_type != LIQUID_NONE;
268 // NOTE: Don't use, use "content_features(m).whatever" instead
269 inline bool content_flowing_liquid(u8 m)
271 return content_features(m).liquid_type == LIQUID_FLOWING;
273 // NOTE: Don't use, use "content_features(m).whatever" instead
274 inline bool content_liquid_source(u8 m)
276 return content_features(m).liquid_type == LIQUID_SOURCE;
278 // CONTENT_WATER || CONTENT_WATERSOURCE -> CONTENT_WATER
279 // CONTENT_LAVA || CONTENT_LAVASOURCE -> CONTENT_LAVA
280 // NOTE: Don't use, use "content_features(m).whatever" instead
281 inline u8 make_liquid_flowing(u8 m)
283 u8 c = content_features(m).liquid_alternative_flowing;
284 assert(c != CONTENT_IGNORE);
287 // Pointable contents can be pointed to in the map
288 // NOTE: Don't use, use "content_features(m).whatever" instead
289 inline bool content_pointable(u8 m)
291 return content_features(m).pointable;
293 // NOTE: Don't use, use "content_features(m).whatever" instead
294 inline bool content_diggable(u8 m)
296 return content_features(m).diggable;
298 // NOTE: Don't use, use "content_features(m).whatever" instead
299 inline bool content_buildable_to(u8 m)
301 return content_features(m).buildable_to;
305 Nodes make a face if contents differ and solidness differs.
308 1: Face uses m1's content
309 2: Face uses m2's content
311 inline u8 face_contents(u8 m1, u8 m2)
313 if(m1 == CONTENT_IGNORE || m2 == CONTENT_IGNORE)
316 bool contents_differ = (m1 != m2);
318 // Contents don't differ for different forms of same liquid
319 if(content_liquid(m1) && content_liquid(m2)
320 && make_liquid_flowing(m1) == make_liquid_flowing(m2))
321 contents_differ = false;
323 bool solidness_differs = (content_solidness(m1) != content_solidness(m2));
324 bool makes_face = contents_differ && solidness_differs;
326 if(makes_face == false)
329 if(content_solidness(m1) > content_solidness(m2))
336 Packs directions like (1,0,0), (1,-1,0)
338 inline u8 packDir(v3s16 dir)
359 inline v3s16 unpackDir(u8 b)
382 facedir: CPT_FACEDIR_SIMPLE param1 value
383 dir: The face for which stuff is wanted
384 return value: The face from which the stuff is actually found
386 v3s16 facedir_rotate(u8 facedir, v3s16 dir);
395 This is the stuff what the whole world consists of.
404 Misc parameter. Initialized to 0.
405 - For light_propagates() blocks, this is light intensity,
406 stored logarithmically from 0 to LIGHT_MAX.
407 Sunlight is LIGHT_SUN, which is LIGHT_MAX+1.
408 - Contains 2 values, day- and night lighting. Each takes 4 bits.
417 The second parameter. Initialized to 0.
418 E.g. direction for torches and flowing water.
426 MapNode(const MapNode & n)
431 MapNode(u8 data=CONTENT_AIR, u8 a_param=0, u8 a_param2=0)
438 /*MapNode & operator=(const MapNode &other)
442 param2 = other.param2;
446 bool operator==(const MapNode &other)
449 && param == other.param
450 && param2 == other.param2);
454 These four are DEPRECATED I guess. -c55
456 bool light_propagates()
458 return light_propagates_content(d);
460 bool sunlight_propagates()
462 return sunlight_propagates_content(d);
466 return content_solidness(d);
470 return content_features(d).light_source;
473 u8 getLightBanksWithSource()
475 // Select the brightest of [light source, propagated light]
478 if(content_features(d).param_type == CPT_LIGHT)
480 lightday = param & 0x0f;
481 lightnight = (param>>4)&0x0f;
483 if(light_source() > lightday)
484 lightday = light_source();
485 if(light_source() > lightnight)
486 lightnight = light_source();
487 return (lightday&0x0f) | ((lightnight<<4)&0xf0);
490 u8 getLight(enum LightBank bank)
492 // Select the brightest of [light source, propagated light]
494 if(content_features(d).param_type == CPT_LIGHT)
496 if(bank == LIGHTBANK_DAY)
497 light = param & 0x0f;
498 else if(bank == LIGHTBANK_NIGHT)
499 light = (param>>4)&0x0f;
503 if(light_source() > light)
504 light = light_source();
508 // 0 <= daylight_factor <= 1000
509 // 0 <= return value <= LIGHT_SUN
510 u8 getLightBlend(u32 daylight_factor)
512 u8 l = ((daylight_factor * getLight(LIGHTBANK_DAY)
513 + (1000-daylight_factor) * getLight(LIGHTBANK_NIGHT))
516 if(getLight(LIGHTBANK_DAY) == LIGHT_SUN)
522 /*// 0 <= daylight_factor <= 1000
523 // 0 <= return value <= 255
524 u8 getLightBlend(u32 daylight_factor)
526 u8 daylight = decode_light(getLight(LIGHTBANK_DAY));
527 u8 nightlight = decode_light(getLight(LIGHTBANK_NIGHT));
528 u8 mix = ((daylight_factor * daylight
529 + (1000-daylight_factor) * nightlight)
534 void setLight(enum LightBank bank, u8 a_light)
536 // If node doesn't contain light data, ignore this
537 if(content_features(d).param_type != CPT_LIGHT)
539 if(bank == LIGHTBANK_DAY)
542 param |= a_light & 0x0f;
544 else if(bank == LIGHTBANK_NIGHT)
547 param |= (a_light & 0x0f)<<4;
555 Get tile of a face of the node.
556 dir: direction of face
557 Returns: TileSpec. Can contain miscellaneous texture coordinates,
558 which must be obeyed so that the texture atlas can be used.
560 TileSpec getTile(v3s16 dir);
563 Gets mineral content of node, if there is any.
564 MINERAL_NONE if doesn't contain or isn't able to contain mineral.
569 These serialization functions are used when informing client
570 of a single node add.
572 NOTE: When loading a MapBlock, these are not used. Should they?
575 static u32 serializedLength(u8 version)
577 if(!ser_ver_supported(version))
578 throw VersionMismatchException("ERROR: MapNode format not supported");
582 else if(version <= 9)
587 void serialize(u8 *dest, u8 version)
589 if(!ser_ver_supported(version))
590 throw VersionMismatchException("ERROR: MapNode format not supported");
596 else if(version <= 9)
608 void deSerialize(u8 *source, u8 version)
610 if(!ser_ver_supported(version))
611 throw VersionMismatchException("ERROR: MapNode format not supported");
617 else if(version == 1)
620 // This version doesn't support saved lighting
621 if(light_propagates() || light_source() > 0)
626 else if(version <= 9)
638 // Translate deprecated stuff
639 // NOTE: This doesn't get used because MapBlock handles node
640 // parameters directly
641 MapNode *translate_to = content_features(d).translate_to;
644 dstream<<"MapNode: WARNING: Translating "<<d<<" to "
645 <<translate_to->d<<std::endl;
646 *this = *translate_to;
652 Gets lighting value at face of node
654 Parameters must consist of air and !air.
655 Order doesn't matter.
657 If either of the nodes doesn't exist, light is 0.
660 daynight_ratio: 0...1000
662 n2: getNodeParent(p + face_dir)
663 face_dir: axis oriented unit vector from p to p2
665 returns encoded light value.
667 u8 getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2,