1 /*
2 mapnode.h
3 Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4 */
5 
6 /*
7 This file is part of Freeminer.
8 
9 Freeminer is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 Freeminer  is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Freeminer.  If not, see <http://www.gnu.org/licenses/>.
21 */
22 
23 #ifndef MAPNODE_HEADER
24 #define MAPNODE_HEADER
25 
26 #include "irrlichttypes.h"
27 #include "irr_v3d.h"
28 #include "irr_aabb3d.h"
29 #include "light.h"
30 #include <string>
31 #include <vector>
32 #include <list>
33 
34 class INodeDefManager;
35 
36 /*
37 	Naming scheme:
38 	- Material = irrlicht's Material class
39 	- Content = (content_t) content of a node
40 	- Tile = TileSpec at some side of a node of some content type
41 */
42 typedef u16 content_t;
43 
44 #define CONTENT_ID_CAPACITY (1 << (8 * sizeof(content_t)))
45 
46 /*
47 	The maximum node ID that can be registered by mods. This must
48 	be significantly lower than the maximum content_t value, so that
49 	there is enough room for dummy node IDs, which are created when
50 	a MapBlock containing unknown node names is loaded from disk.
51 */
52 #define MAX_REGISTERED_CONTENT 0x7fffU
53 
54 /*
55 	A solid walkable node with the texture unknown_node.png.
56 
57 	For example, used on the client to display unregistered node IDs
58 	(instead of expanding the vector of node definitions each time
59 	such a node is received).
60 */
61 #define CONTENT_UNKNOWN 125
62 
63 /*
64 	The common material through which the player can walk and which
65 	is transparent to light
66 */
67 #define CONTENT_AIR 126
68 
69 /*
70 	Ignored node.
71 
72 	Unloaded chunks are considered to consist of this. Several other
73 	methods return this when an error occurs. Also, during
74 	map generation this means the node has not been set yet.
75 
76 	Doesn't create faces with anything and is considered being
77 	out-of-map in the game map.
78 */
79 #define CONTENT_IGNORE 127
80 
81 enum LightBank
82 {
83 	LIGHTBANK_DAY,
84 	LIGHTBANK_NIGHT
85 };
86 
87 /*
88 	Simple rotation enum.
89 */
90 enum Rotation {
91 	ROTATE_0,
92 	ROTATE_90,
93 	ROTATE_180,
94 	ROTATE_270,
95 	ROTATE_RAND,
96 };
97 
98 /*
99 	Masks for MapNode.param2 of flowing liquids
100  */
101 #define LIQUID_LEVEL_MASK 0x07
102 #define LIQUID_FLOW_DOWN_MASK 0x40 //0b01000000 // only for _flowing liquid
103 
104 //#define LIQUID_LEVEL_MASK 0x3f // better finite water
105 //#define LIQUID_FLOW_DOWN_MASK 0x40 // not used when finite water
106 
107 /* maximum amount of liquid in a block */
108 #define LIQUID_LEVEL_MAX LIQUID_LEVEL_MASK
109 #define LIQUID_LEVEL_SOURCE (LIQUID_LEVEL_MAX+1)
110 
111 #define LIQUID_INFINITY_MASK 0x80 //0b10000000 // only for _source liquid
112 
113 // mask for param2, now as for liquid
114 #define LEVELED_MASK 0x3F
115 #define LEVELED_MAX LEVELED_MASK
116 
117 /*
118 	This is the stuff what the whole world consists of.
119 */
120 
121 
122 struct MapNode
123 {
124 	/*
125 		Main content
126 	*/
127 	u16 param0;
128 
129 	/*
130 		Misc parameter. Initialized to 0.
131 		- For light_propagates() blocks, this is light intensity,
132 		  stored logarithmically from 0 to LIGHT_MAX.
133 		  Sunlight is LIGHT_SUN, which is LIGHT_MAX+1.
134 		  - Contains 2 values, day- and night lighting. Each takes 4 bits.
135 		- Uhh... well, most blocks have light or nothing in here.
136 	*/
137 	u8 param1;
138 
139 	/*
140 		The second parameter. Initialized to 0.
141 		E.g. direction for torches and flowing water.
142 	*/
143 	u8 param2;
144 
MapNodeMapNode145 	MapNode(const MapNode & n)
146 	{
147 		*this = n;
148 	}
149 
150 	MapNode(content_t content=CONTENT_AIR, u8 a_param1=0, u8 a_param2=0)
151 	{
152 		param0 = content;
153 		param1 = a_param1;
154 		param2 = a_param2;
155 	}
156 
157 	// Create directly from a nodename
158 	// If name is unknown, sets CONTENT_IGNORE
159 	MapNode(INodeDefManager *ndef, const std::string &name,
160 			u8 a_param1=0, u8 a_param2=0);
161 
162 	bool operator==(const MapNode &other)
163 	{
164 		return (param0 == other.param0
165 				&& param1 == other.param1
166 				&& param2 == other.param2);
167 	}
168 
169 	// To be used everywhere
getContentMapNode170 	content_t getContent() const
171 	{
172 		return param0;
173 	}
setContentMapNode174 	void setContent(content_t c)
175 	{
176 		param0 = c;
177 	}
getParam1MapNode178 	u8 getParam1() const
179 	{
180 		return param1;
181 	}
setParam1MapNode182 	void setParam1(u8 p)
183 	{
184 		param1 = p;
185 	}
getParam2MapNode186 	u8 getParam2() const
187 	{
188 		return param2;
189 	}
setParam2MapNode190 	void setParam2(u8 p)
191 	{
192 		param2 = p;
193 	}
194 
195 	void setLight(enum LightBank bank, u8 a_light, INodeDefManager *nodemgr);
196 	u8 getLight(enum LightBank bank, INodeDefManager *nodemgr) const;
197 	bool getLightBanks(u8 &lightday, u8 &lightnight, INodeDefManager *nodemgr) const;
198 
199 	// 0 <= daylight_factor <= 1000
200 	// 0 <= return value <= LIGHT_SUN
getLightBlendMapNode201 	u8 getLightBlend(u32 daylight_factor, INodeDefManager *nodemgr) const
202 	{
203 		u8 lightday = 0;
204 		u8 lightnight = 0;
205 		getLightBanks(lightday, lightnight, nodemgr);
206 		return blend_light(daylight_factor, lightday, lightnight);
207 	}
208 
209 	// 0.0 <= daylight_factor <= 1.0
210 	// 0 <= return value <= LIGHT_SUN
getLightBlendF1MapNode211 	u8 getLightBlendF1(float daylight_factor, INodeDefManager *nodemgr) const
212 	{
213 		u8 lightday = 0;
214 		u8 lightnight = 0;
215 		getLightBanks(lightday, lightnight, nodemgr);
216 		return blend_light_f1(daylight_factor, lightday, lightnight);
217 	}
218 
219 	u8 getFaceDir(INodeDefManager *nodemgr) const;
220 	u8 getWallMounted(INodeDefManager *nodemgr) const;
221 	v3s16 getWallMountedDir(INodeDefManager *nodemgr) const;
222 
223 	void rotateAlongYAxis(INodeDefManager *nodemgr, Rotation rot);
224 
225 	/*
226 		Gets list of node boxes (used for rendering (NDT_NODEBOX))
227 	*/
228 	std::vector<aabb3f> getNodeBoxes(INodeDefManager *nodemgr) const;
229 
230 	/*
231 		Gets list of selection boxes
232 	*/
233 	std::vector<aabb3f> getSelectionBoxes(INodeDefManager *nodemgr) const;
234 
235 	/*
236 		Gets list of collision boxes
237 	*/
238 	std::vector<aabb3f> getCollisionBoxes(INodeDefManager *nodemgr) const;
239 
240 	/* Liquid helpers */
241 	u8 getMaxLevel(INodeDefManager *nodemgr, bool compress = 0) const;
242 	u8 getLevel(INodeDefManager *nodemgr) const;
243 	u8 setLevel(INodeDefManager *nodemgr, s8 level = 1, bool compress = 0);
244 	u8 addLevel(INodeDefManager *nodemgr, s8 add = 1, bool compress = 0);
245 	int freeze_melt(INodeDefManager *nodemgr, int direction = 0);
246 
247 	bool operator!() { return param0 == CONTENT_IGNORE; };
248 
249 	/*
250 		Serialization functions
251 	*/
252 
253 	static u32 serializedLength(u8 version);
254 	void serialize(u8 *dest, u8 version);
255 	void deSerialize(u8 *source, u8 version);
256 
257 	// Serializes or deserializes a list of nodes in bulk format (first the
258 	// content of all nodes, then the param1 of all nodes, then the param2
259 	// of all nodes).
260 	//   version = serialization version. Must be >= 22
261 	//   content_width = the number of bytes of content per node
262 	//   params_width = the number of bytes of params per node
263 	//   compressed = true to zlib-compress output
264 	static void serializeBulk(std::ostream &os, int version,
265 			const MapNode *nodes, u32 nodecount,
266 			u8 content_width, u8 params_width, bool compressed);
267 	static void deSerializeBulk(std::istream &is, int version,
268 			MapNode *nodes, u32 nodecount,
269 			u8 content_width, u8 params_width, bool compressed);
270 
271 private:
272 	// Deprecated serialization methods
273 	void deSerialize_pre22(u8 *source, u8 version);
274 };
275 
276 #endif
277 
278