MapNode constructor to allow ndef+name
[oweals/minetest.git] / src / mapnode.h
1 /*
2 Minetest-c55
3 Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
4
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.
9
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.
14
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.
18 */
19
20 #ifndef MAPNODE_HEADER
21 #define MAPNODE_HEADER
22
23 #include "irrlichttypes.h"
24 #include "light.h"
25
26 class INodeDefManager;
27
28 /*
29         Naming scheme:
30         - Material = irrlicht's Material class
31         - Content = (content_t) content of a node
32         - Tile = TileSpec at some side of a node of some content type
33
34         Content ranges:
35                 0x000...0x07f: param2 is fully usable
36                 0x800...0xfff: param2 lower 4 bytes are free
37 */
38 typedef u16 content_t;
39 #define MAX_CONTENT 0xfff
40
41 /*
42         Ignored node.
43
44         Anything that stores MapNodes doesn't have to preserve parameters
45         associated with this material.
46         
47         Doesn't create faces with anything and is considered being
48         out-of-map in the game map.
49 */
50 #define CONTENT_IGNORE 127
51 #define CONTENT_IGNORE_DEFAULT_PARAM 0
52
53 /*
54         The common material through which the player can walk and which
55         is transparent to light
56 */
57 #define CONTENT_AIR 126
58
59 #ifndef SERVER
60 /*
61         Nodes make a face if contents differ and solidness differs.
62         Return value:
63                 0: No face
64                 1: Face uses m1's content
65                 2: Face uses m2's content
66         equivalent: Whether the blocks share the same face (eg. water and glass)
67 */
68 u8 face_contents(content_t m1, content_t m2, bool *equivalent,
69                 INodeDefManager *nodemgr);
70 #endif
71
72 /*
73         Packs directions like (1,0,0), (1,-1,0) in six bits.
74         NOTE: This wastes way too much space for most purposes.
75 */
76 u8 packDir(v3s16 dir);
77 v3s16 unpackDir(u8 b);
78
79 /*
80         facedir: CPT_FACEDIR_SIMPLE param1 value
81         dir: The face for which stuff is wanted
82         return value: The face from which the stuff is actually found
83
84         NOTE: Currently this uses 2 bits for Z-,X-,Z+,X+, should there be Y+
85               and Y- too?
86 */
87 v3s16 facedir_rotate(u8 facedir, v3s16 dir);
88
89 enum LightBank
90 {
91         LIGHTBANK_DAY,
92         LIGHTBANK_NIGHT
93 };
94
95 /*
96         Masks for MapNode.param2 of flowing liquids
97  */
98 #define LIQUID_LEVEL_MASK 0x07
99 #define LIQUID_FLOW_DOWN_MASK 0x08
100
101 /* maximum amount of liquid in a block */
102 #define LIQUID_LEVEL_MAX LIQUID_LEVEL_MASK
103 #define LIQUID_LEVEL_SOURCE (LIQUID_LEVEL_MAX+1)
104
105 /*
106         This is the stuff what the whole world consists of.
107 */
108
109
110 struct MapNode
111 {
112         /*
113                 Main content
114                 0x00-0x7f: Short content type
115                 0x80-0xff: Long content type (param2>>4 makes up low bytes)
116         */
117         u8 param0;
118
119         /*
120                 Misc parameter. Initialized to 0.
121                 - For light_propagates() blocks, this is light intensity,
122                   stored logarithmically from 0 to LIGHT_MAX.
123                   Sunlight is LIGHT_SUN, which is LIGHT_MAX+1.
124                   - Contains 2 values, day- and night lighting. Each takes 4 bits.
125                 - Mineral content (should be removed from here)
126                 - Uhh... well, most blocks have light or nothing in here.
127         */
128         u8 param1;
129         
130         /*
131                 The second parameter. Initialized to 0.
132                 E.g. direction for torches and flowing water.
133                 If param0 >= 0x80, bits 0xf0 of this is extended content type data
134         */
135         u8 param2;
136
137         MapNode(const MapNode & n)
138         {
139                 *this = n;
140         }
141         
142         MapNode(content_t content=CONTENT_AIR, u8 a_param1=0, u8 a_param2=0)
143         {
144                 param1 = a_param1;
145                 param2 = a_param2;
146                 // Set content (param0 and (param2&0xf0)) after other params
147                 // because this needs to override part of param2
148                 setContent(content);
149         }
150         
151         // Create directly from a nodename
152         // If name is unknown, sets CONTENT_IGNORE
153         MapNode(INodeDefManager *ndef, const std::string &name,
154                         u8 a_param1=0, u8 a_param2=0);
155
156         bool operator==(const MapNode &other)
157         {
158                 return (param0 == other.param0
159                                 && param1 == other.param1
160                                 && param2 == other.param2);
161         }
162         
163         // To be used everywhere
164         content_t getContent() const
165         {
166                 if(param0 < 0x80)
167                         return param0;
168                 else
169                         return (param0<<4) + (param2>>4);
170         }
171         void setContent(content_t c)
172         {
173                 if(c < 0x80)
174                 {
175                         if(param0 >= 0x80)
176                                 param2 &= ~(0xf0);
177                         param0 = c;
178                 }
179                 else
180                 {
181                         param0 = c>>4;
182                         param2 &= ~(0xf0);
183                         param2 |= (c&0x0f)<<4;
184                 }
185         }
186         
187         void setLight(enum LightBank bank, u8 a_light, INodeDefManager *nodemgr);
188         u8 getLight(enum LightBank bank, INodeDefManager *nodemgr) const;
189         u8 getLightBanksWithSource(INodeDefManager *nodemgr) const;
190         
191         // 0 <= daylight_factor <= 1000
192         // 0 <= return value <= LIGHT_SUN
193         u8 getLightBlend(u32 daylight_factor, INodeDefManager *nodemgr) const
194         {
195                 u8 l = ((daylight_factor * getLight(LIGHTBANK_DAY, nodemgr)
196                         + (1000-daylight_factor) * getLight(LIGHTBANK_NIGHT, nodemgr))
197                         )/1000;
198                 u8 max = LIGHT_MAX;
199                 if(getLight(LIGHTBANK_DAY, nodemgr) == LIGHT_SUN)
200                         max = LIGHT_SUN;
201                 if(l > max)
202                         l = max;
203                 return l;
204         }
205         /*// 0 <= daylight_factor <= 1000
206         // 0 <= return value <= 255
207         u8 getLightBlend(u32 daylight_factor, INodeDefManager *nodemgr)
208         {
209                 u8 daylight = decode_light(getLight(LIGHTBANK_DAY, nodemgr));
210                 u8 nightlight = decode_light(getLight(LIGHTBANK_NIGHT, nodemgr));
211                 u8 mix = ((daylight_factor * daylight
212                         + (1000-daylight_factor) * nightlight)
213                         )/1000;
214                 return mix;
215         }*/
216
217         /*
218                 Gets mineral content of node, if there is any.
219                 MINERAL_NONE if doesn't contain or isn't able to contain mineral.
220         */
221         u8 getMineral(INodeDefManager *nodemgr) const;
222         
223         /*
224                 Serialization functions
225         */
226
227         static u32 serializedLength(u8 version);
228         void serialize(u8 *dest, u8 version);
229         void deSerialize(u8 *source, u8 version);
230         
231 };
232
233 /*
234         Gets lighting value at face of node
235         
236         Parameters must consist of air and !air.
237         Order doesn't matter.
238
239         If either of the nodes doesn't exist, light is 0.
240         
241         parameters:
242                 daynight_ratio: 0...1000
243                 n: getNode(p) (uses only the lighting value)
244                 n2: getNode(p + face_dir) (uses only the lighting value)
245                 face_dir: axis oriented unit vector from p to p2
246         
247         returns encoded light value.
248 */
249 u8 getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2,
250                 v3s16 face_dir, INodeDefManager *nodemgr);
251
252 #endif
253