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 = (content_t) content of a node
36 - Tile = TileSpec at some side of a node of some content type
39 0x000...0x07f: param2 is fully usable
40 0x800...0xfff: param2 lower 4 bytes are free
42 typedef u16 content_t;
43 #define MAX_CONTENT 0xfff
46 Initializes all kind of stuff in here.
47 Many things depend on this.
49 This accesses g_texturesource; if it is non-NULL, textures are set.
51 Client first calls this with g_texturesource=NULL to run some
52 unit tests and stuff, then it runs this again with g_texturesource
53 defined to get the textures.
55 Server only calls this once with g_texturesource=NULL.
62 Anything that stores MapNodes doesn't have to preserve parameters
63 associated with this material.
65 Doesn't create faces with anything and is considered being
66 out-of-map in the game map.
68 //#define CONTENT_IGNORE 255
69 #define CONTENT_IGNORE 127
70 #define CONTENT_IGNORE_DEFAULT_PARAM 0
73 The common material through which the player can walk and which
74 is transparent to light
76 //#define CONTENT_AIR 254
77 #define CONTENT_AIR 126
88 // Direction for chests and furnaces and such
102 struct ContentFeatures
104 // Type of MapNode::param1
105 ContentParamType param_type;
117 video::ITexture *inventory_texture;
119 bool is_ground_content;
120 bool light_propagates;
121 bool sunlight_propagates;
122 u8 solidness; // Used when choosing which face is drawn
123 // This is used for collision detection.
124 // Also for general solidness queries.
126 // Player can point to these
128 // Player can dig these
130 // Player can build on these
132 // Whether the node has no liquid, source liquid or flowing liquid
133 enum LiquidType liquid_type;
134 // If true, param2 is set to direction when placed. Used for torches.
135 // NOTE: the direction format is quite inefficient and should be changed
137 // If true, node is equivalent to air. Torches are, air is. Water is not.
138 // Is used for example to check whether a mud block can have grass on.
141 // Inventory item string as which the node appears in inventory when dug.
142 // Mineral overrides this.
143 std::string dug_item;
145 // Initial metadata is cloned from this
146 NodeMetadata *initial_metadata;
148 // If the content is liquid, this is the flowing version of the liquid.
149 // If content is liquid, this is the same content.
150 content_t liquid_alternative_flowing;
152 // Amount of light the node emits
155 // Digging properties for different tools
156 DiggingPropertiesList digging_properties;
158 // NOTE: Move relevant properties to here from elsewhere
162 param_type = CPT_NONE;
163 inventory_texture = NULL;
164 is_ground_content = false;
165 light_propagates = false;
166 sunlight_propagates = false;
171 buildable_to = false;
172 liquid_type = LIQUID_NONE;
173 wall_mounted = false;
174 air_equivalent = false;
176 initial_metadata = NULL;
177 liquid_alternative_flowing = CONTENT_IGNORE;
179 digging_properties.clear();
190 Quickhands for simple materials
193 void setTexture(u16 i, std::string name, u8 alpha=255);
195 void setAllTextures(std::string name, u8 alpha=255)
197 for(u16 i=0; i<6; i++)
199 setTexture(i, name, alpha);
201 // Force inventory texture too
202 setInventoryTexture(name);
205 void setTile(u16 i, const TileSpec &tile)
209 void setAllTiles(const TileSpec &tile)
211 for(u16 i=0; i<6; i++)
217 void setInventoryTexture(std::string imgname);
219 void setInventoryTextureCube(std::string top,
220 std::string left, std::string right);
224 Call this to access the ContentFeature list
226 ContentFeatures & content_features(content_t i);
227 ContentFeatures & content_features(MapNode &n);
230 Here is a bunch of DEPRECATED functions.
234 If true, the material allows light propagation and brightness is stored
236 NOTE: Don't use, use "content_features(m).whatever" instead
238 inline bool light_propagates_content(content_t m)
240 return content_features(m).light_propagates;
243 If true, the material allows lossless sunlight propagation.
244 NOTE: It doesn't seem to go through torches regardlessly of this
245 NOTE: Don't use, use "content_features(m).whatever" instead
247 inline bool sunlight_propagates_content(content_t m)
249 return content_features(m).sunlight_propagates;
252 On a node-node surface, the material of the node with higher solidness
257 NOTE: Don't use, use "content_features(m).whatever" instead
259 inline u8 content_solidness(content_t m)
261 return content_features(m).solidness;
263 // Objects collide with walkable contents
264 // NOTE: Don't use, use "content_features(m).whatever" instead
265 inline bool content_walkable(content_t m)
267 return content_features(m).walkable;
269 // NOTE: Don't use, use "content_features(m).whatever" instead
270 inline bool content_liquid(content_t m)
272 return content_features(m).liquid_type != LIQUID_NONE;
274 // NOTE: Don't use, use "content_features(m).whatever" instead
275 inline bool content_flowing_liquid(content_t m)
277 return content_features(m).liquid_type == LIQUID_FLOWING;
279 // NOTE: Don't use, use "content_features(m).whatever" instead
280 inline bool content_liquid_source(content_t m)
282 return content_features(m).liquid_type == LIQUID_SOURCE;
284 // CONTENT_WATER || CONTENT_WATERSOURCE -> CONTENT_WATER
285 // CONTENT_LAVA || CONTENT_LAVASOURCE -> CONTENT_LAVA
286 // NOTE: Don't use, use "content_features(m).whatever" instead
287 inline content_t make_liquid_flowing(content_t m)
289 u8 c = content_features(m).liquid_alternative_flowing;
290 assert(c != CONTENT_IGNORE);
293 // Pointable contents can be pointed to in the map
294 // NOTE: Don't use, use "content_features(m).whatever" instead
295 inline bool content_pointable(content_t m)
297 return content_features(m).pointable;
299 // NOTE: Don't use, use "content_features(m).whatever" instead
300 inline bool content_diggable(content_t m)
302 return content_features(m).diggable;
304 // NOTE: Don't use, use "content_features(m).whatever" instead
305 inline bool content_buildable_to(content_t m)
307 return content_features(m).buildable_to;
311 Nodes make a face if contents differ and solidness differs.
314 1: Face uses m1's content
315 2: Face uses m2's content
317 inline u8 face_contents(content_t m1, content_t m2)
319 if(m1 == CONTENT_IGNORE || m2 == CONTENT_IGNORE)
322 bool contents_differ = (m1 != m2);
324 // Contents don't differ for different forms of same liquid
325 if(content_liquid(m1) && content_liquid(m2)
326 && make_liquid_flowing(m1) == make_liquid_flowing(m2))
327 contents_differ = false;
329 bool solidness_differs = (content_solidness(m1) != content_solidness(m2));
330 bool makes_face = contents_differ && solidness_differs;
332 if(makes_face == false)
335 if(content_solidness(m1) > content_solidness(m2))
342 Packs directions like (1,0,0), (1,-1,0)
344 inline u8 packDir(v3s16 dir)
365 inline v3s16 unpackDir(u8 b)
388 facedir: CPT_FACEDIR_SIMPLE param1 value
389 dir: The face for which stuff is wanted
390 return value: The face from which the stuff is actually found
392 v3s16 facedir_rotate(u8 facedir, v3s16 dir);
401 This is the stuff what the whole world consists of.
408 0x00-0x7f: Short content type
409 0x80-0xff: Long content type (param2>>4 makes up low bytes)
418 Misc parameter. Initialized to 0.
419 - For light_propagates() blocks, this is light intensity,
420 stored logarithmically from 0 to LIGHT_MAX.
421 Sunlight is LIGHT_SUN, which is LIGHT_MAX+1.
422 - Contains 2 values, day- and night lighting. Each takes 4 bits.
423 - Mineral content (should be removed from here)
424 - Uhh... well, most blocks have light or nothing in here.
433 The second parameter. Initialized to 0.
434 E.g. direction for torches and flowing water.
435 If param0 >= 0x80, bits 0xf0 of this is extended content type data
443 MapNode(const MapNode & n)
448 MapNode(content_t content=CONTENT_AIR, u8 a_param1=0, u8 a_param2=0)
453 // Set after other params because this needs to override part of param2
457 bool operator==(const MapNode &other)
459 return (param0 == other.param0
460 && param1 == other.param1
461 && param2 == other.param2);
464 // To be used everywhere
465 content_t getContent()
470 return (param0<<4) + (param2>>4);
472 void setContent(content_t c)
484 param2 |= (c&0x0f)<<4;
489 These four are DEPRECATED I guess. -c55
491 bool light_propagates()
493 return light_propagates_content(getContent());
495 bool sunlight_propagates()
497 return sunlight_propagates_content(getContent());
501 return content_solidness(getContent());
505 return content_features(*this).light_source;
508 u8 getLightBanksWithSource()
510 // Select the brightest of [light source, propagated light]
513 if(content_features(*this).param_type == CPT_LIGHT)
515 lightday = param1 & 0x0f;
516 lightnight = (param1>>4)&0x0f;
518 if(light_source() > lightday)
519 lightday = light_source();
520 if(light_source() > lightnight)
521 lightnight = light_source();
522 return (lightday&0x0f) | ((lightnight<<4)&0xf0);
525 u8 getLight(enum LightBank bank)
527 // Select the brightest of [light source, propagated light]
529 if(content_features(*this).param_type == CPT_LIGHT)
531 if(bank == LIGHTBANK_DAY)
532 light = param1 & 0x0f;
533 else if(bank == LIGHTBANK_NIGHT)
534 light = (param1>>4)&0x0f;
538 if(light_source() > light)
539 light = light_source();
543 // 0 <= daylight_factor <= 1000
544 // 0 <= return value <= LIGHT_SUN
545 u8 getLightBlend(u32 daylight_factor)
547 u8 l = ((daylight_factor * getLight(LIGHTBANK_DAY)
548 + (1000-daylight_factor) * getLight(LIGHTBANK_NIGHT))
551 if(getLight(LIGHTBANK_DAY) == LIGHT_SUN)
557 /*// 0 <= daylight_factor <= 1000
558 // 0 <= return value <= 255
559 u8 getLightBlend(u32 daylight_factor)
561 u8 daylight = decode_light(getLight(LIGHTBANK_DAY));
562 u8 nightlight = decode_light(getLight(LIGHTBANK_NIGHT));
563 u8 mix = ((daylight_factor * daylight
564 + (1000-daylight_factor) * nightlight)
569 void setLight(enum LightBank bank, u8 a_light)
571 // If node doesn't contain light data, ignore this
572 if(content_features(*this).param_type != CPT_LIGHT)
574 if(bank == LIGHTBANK_DAY)
577 param1 |= a_light & 0x0f;
579 else if(bank == LIGHTBANK_NIGHT)
582 param1 |= (a_light & 0x0f)<<4;
590 Get tile of a face of the node.
591 dir: direction of face
592 Returns: TileSpec. Can contain miscellaneous texture coordinates,
593 which must be obeyed so that the texture atlas can be used.
595 TileSpec getTile(v3s16 dir);
598 Gets mineral content of node, if there is any.
599 MINERAL_NONE if doesn't contain or isn't able to contain mineral.
604 Serialization functions
607 static u32 serializedLength(u8 version);
608 void serialize(u8 *dest, u8 version);
609 void deSerialize(u8 *source, u8 version);
614 Gets lighting value at face of node
616 Parameters must consist of air and !air.
617 Order doesn't matter.
619 If either of the nodes doesn't exist, light is 0.
622 daynight_ratio: 0...1000
624 n2: getNodeParent(p + face_dir)
625 face_dir: axis oriented unit vector from p to p2
627 returns encoded light value.
629 u8 getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2,