]> git.lizzy.rs Git - minetest.git/blob - src/nodedef.h
d9829c495de3cd25c9d959c3d7f891ffcc3ef093
[minetest.git] / src / nodedef.h
1 /*
2 Minetest
3 Copyright (C) 2010-2013 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 Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser 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 NODEDEF_HEADER
21 #define NODEDEF_HEADER
22
23 #include "irrlichttypes_bloated.h"
24 #include <string>
25 #include <iostream>
26 #include <map>
27 #include <list>
28 #include "mapnode.h"
29 #ifndef SERVER
30 #include "client/tile.h"
31 #include "shader.h"
32 #endif
33 #include "itemgroup.h"
34 #include "sound.h" // SimpleSoundSpec
35 #include "constants.h" // BS
36
37 class INodeDefManager;
38 class IItemDefManager;
39 class ITextureSource;
40 class IShaderSource;
41 class IGameDef;
42 class NodeResolver;
43
44 typedef std::list<std::pair<content_t, int> > GroupItems;
45
46 enum ContentParamType
47 {
48         CPT_NONE,
49         CPT_LIGHT,
50 };
51
52 enum ContentParamType2
53 {
54         CPT2_NONE,
55         // Need 8-bit param2
56         CPT2_FULL,
57         // Flowing liquid properties
58         CPT2_FLOWINGLIQUID,
59         // Direction for chests and furnaces and such
60         CPT2_FACEDIR,
61         // Direction for signs, torches and such
62         CPT2_WALLMOUNTED,
63         // Block level like FLOWINGLIQUID
64         CPT2_LEVELED,
65 };
66
67 enum LiquidType
68 {
69         LIQUID_NONE,
70         LIQUID_FLOWING,
71         LIQUID_SOURCE,
72 };
73
74 enum NodeBoxType
75 {
76         NODEBOX_REGULAR, // Regular block; allows buildable_to
77         NODEBOX_FIXED, // Static separately defined box(es)
78         NODEBOX_WALLMOUNTED, // Box for wall mounted nodes; (top, bottom, side)
79         NODEBOX_LEVELED, // Same as fixed, but with dynamic height from param2. for snow, ...
80 };
81
82 struct NodeBox
83 {
84         enum NodeBoxType type;
85         // NODEBOX_REGULAR (no parameters)
86         // NODEBOX_FIXED
87         std::vector<aabb3f> fixed;
88         // NODEBOX_WALLMOUNTED
89         aabb3f wall_top;
90         aabb3f wall_bottom;
91         aabb3f wall_side; // being at the -X side
92
93         NodeBox()
94         { reset(); }
95
96         void reset();
97         void serialize(std::ostream &os, u16 protocol_version) const;
98         void deSerialize(std::istream &is);
99 };
100
101 struct MapNode;
102 class NodeMetadata;
103
104 /*
105         Stand-alone definition of a TileSpec (basically a server-side TileSpec)
106 */
107 enum TileAnimationType{
108         TAT_NONE=0,
109         TAT_VERTICAL_FRAMES=1,
110 };
111 struct TileDef
112 {
113         std::string name;
114         bool backface_culling; // Takes effect only in special cases
115         struct{
116                 enum TileAnimationType type;
117                 int aspect_w; // width for aspect ratio
118                 int aspect_h; // height for aspect ratio
119                 float length; // seconds
120         } animation;
121
122         TileDef()
123         {
124                 name = "";
125                 backface_culling = true;
126                 animation.type = TAT_NONE;
127                 animation.aspect_w = 1;
128                 animation.aspect_h = 1;
129                 animation.length = 1.0;
130         }
131
132         void serialize(std::ostream &os, u16 protocol_version) const;
133         void deSerialize(std::istream &is);
134 };
135
136 enum NodeDrawType
137 {
138         NDT_NORMAL, // A basic solid block
139         NDT_AIRLIKE, // Nothing is drawn
140         NDT_LIQUID, // Do not draw face towards same kind of flowing/source liquid
141         NDT_FLOWINGLIQUID, // A very special kind of thing
142         NDT_GLASSLIKE, // Glass-like, don't draw faces towards other glass
143         NDT_ALLFACES, // Leaves-like, draw all faces no matter what
144         NDT_ALLFACES_OPTIONAL, // Fancy -> allfaces, fast -> normal
145         NDT_TORCHLIKE,
146         NDT_SIGNLIKE,
147         NDT_PLANTLIKE,
148         NDT_FENCELIKE,
149         NDT_RAILLIKE,
150         NDT_NODEBOX,
151         NDT_GLASSLIKE_FRAMED, // Glass-like, draw connected frames and all all
152                               // visible faces
153                                                   // uses 2 textures, one for frames, second for faces
154         NDT_FIRELIKE, // Draw faces slightly rotated and only on connecting nodes,
155         NDT_GLASSLIKE_FRAMED_OPTIONAL,  // enabled -> connected, disabled -> Glass-like
156                                                                         // uses 2 textures, one for frames, second for faces
157         NDT_MESH, // Uses static meshes
158 };
159
160 #define CF_SPECIAL_COUNT 6
161
162 struct ContentFeatures
163 {
164         /*
165                 Cached stuff
166         */
167 #ifndef SERVER
168         // 0     1     2     3     4     5
169         // up    down  right left  back  front
170         TileSpec tiles[6];
171         // Special tiles
172         // - Currently used for flowing liquids
173         TileSpec special_tiles[CF_SPECIAL_COUNT];
174         u8 solidness; // Used when choosing which face is drawn
175         u8 visual_solidness; // When solidness=0, this tells how it looks like
176         bool backface_culling;
177 #endif
178
179         // Server-side cached callback existence for fast skipping
180         bool has_on_construct;
181         bool has_on_destruct;
182         bool has_after_destruct;
183
184         /*
185                 Actual data
186         */
187
188         std::string name; // "" = undefined node
189         ItemGroupList groups; // Same as in itemdef
190
191         // Visual definition
192         enum NodeDrawType drawtype;
193         std::string mesh;
194 #ifndef SERVER
195         scene::IMesh *mesh_ptr[24];
196 #endif
197         float visual_scale; // Misc. scale parameter
198         TileDef tiledef[6];
199         TileDef tiledef_special[CF_SPECIAL_COUNT]; // eg. flowing liquid
200         u8 alpha;
201
202         // Post effect color, drawn when the camera is inside the node.
203         video::SColor post_effect_color;
204         // Type of MapNode::param1
205         ContentParamType param_type;
206         // Type of MapNode::param2
207         ContentParamType2 param_type_2;
208         // True for all ground-like things like stone and mud, false for eg. trees
209         bool is_ground_content;
210         bool light_propagates;
211         bool sunlight_propagates;
212         // This is used for collision detection.
213         // Also for general solidness queries.
214         bool walkable;
215         // Player can point to these
216         bool pointable;
217         // Player can dig these
218         bool diggable;
219         // Player can climb these
220         bool climbable;
221         // Player can build on these
222         bool buildable_to;
223         // Player cannot build to these (placement prediction disabled)
224         bool rightclickable;
225         // Flowing liquid or snow, value = default level
226         u8 leveled;
227         // Whether the node is non-liquid, source liquid or flowing liquid
228         enum LiquidType liquid_type;
229         // If the content is liquid, this is the flowing version of the liquid.
230         std::string liquid_alternative_flowing;
231         // If the content is liquid, this is the source version of the liquid.
232         std::string liquid_alternative_source;
233         // Viscosity for fluid flow, ranging from 1 to 7, with
234         // 1 giving almost instantaneous propagation and 7 being
235         // the slowest possible
236         u8 liquid_viscosity;
237         // Is liquid renewable (new liquid source will be created between 2 existing)
238         bool liquid_renewable;
239         // Number of flowing liquids surrounding source
240         u8 liquid_range;
241         u8 drowning;
242         // Amount of light the node emits
243         u8 light_source;
244         u32 damage_per_second;
245         NodeBox node_box;
246         NodeBox selection_box;
247         NodeBox collision_box;
248         // Used for waving leaves/plants
249         u8 waving;
250         // Compatibility with old maps
251         // Set to true if paramtype used to be 'facedir_simple'
252         bool legacy_facedir_simple;
253         // Set to true if wall_mounted used to be set to true
254         bool legacy_wallmounted;
255
256         // Sound properties
257         SimpleSoundSpec sound_footstep;
258         SimpleSoundSpec sound_dig;
259         SimpleSoundSpec sound_dug;
260
261         /*
262                 Methods
263         */
264
265         ContentFeatures();
266         ~ContentFeatures();
267         void reset();
268         void serialize(std::ostream &os, u16 protocol_version);
269         void deSerialize(std::istream &is);
270         void serializeOld(std::ostream &os, u16 protocol_version);
271         void deSerializeOld(std::istream &is, int version);
272
273         /*
274                 Some handy methods
275         */
276         bool isLiquid() const{
277                 return (liquid_type != LIQUID_NONE);
278         }
279         bool sameLiquid(const ContentFeatures &f) const{
280                 if(!isLiquid() || !f.isLiquid()) return false;
281                 return (liquid_alternative_flowing == f.liquid_alternative_flowing);
282         }
283 };
284
285 enum NodeResolveMethod {
286         NODE_RESOLVE_NONE,
287         NODE_RESOLVE_DIRECT,
288         NODE_RESOLVE_DEFERRED,
289 };
290
291 class INodeDefManager
292 {
293 public:
294         INodeDefManager(){}
295         virtual ~INodeDefManager(){}
296         // Get node definition
297         virtual const ContentFeatures& get(content_t c) const=0;
298         virtual const ContentFeatures& get(const MapNode &n) const=0;
299         virtual bool getId(const std::string &name, content_t &result) const=0;
300         virtual content_t getId(const std::string &name) const=0;
301         // Allows "group:name" in addition to regular node names
302         virtual void getIds(const std::string &name, std::set<content_t> &result)
303                         const=0;
304         virtual const ContentFeatures& get(const std::string &name) const=0;
305
306         virtual void serialize(std::ostream &os, u16 protocol_version)=0;
307
308         virtual bool getNodeRegistrationStatus() const=0;
309         virtual void setNodeRegistrationStatus(bool completed)=0;
310
311         virtual void pendNodeResolve(NodeResolver *nr, NodeResolveMethod how)=0;
312         virtual bool cancelNodeResolveCallback(NodeResolver *nr)=0;
313         virtual void runNodeResolveCallbacks()=0;
314 };
315
316 class IWritableNodeDefManager : public INodeDefManager
317 {
318 public:
319         IWritableNodeDefManager(){}
320         virtual ~IWritableNodeDefManager(){}
321         virtual IWritableNodeDefManager* clone()=0;
322         // Get node definition
323         virtual const ContentFeatures& get(content_t c) const=0;
324         virtual const ContentFeatures& get(const MapNode &n) const=0;
325         virtual bool getId(const std::string &name, content_t &result) const=0;
326         // If not found, returns CONTENT_IGNORE
327         virtual content_t getId(const std::string &name) const=0;
328         // Allows "group:name" in addition to regular node names
329         virtual void getIds(const std::string &name, std::set<content_t> &result)
330                         const=0;
331         // If not found, returns the features of CONTENT_UNKNOWN
332         virtual const ContentFeatures& get(const std::string &name) const=0;
333
334         // Register node definition by name (allocate an id)
335         // If returns CONTENT_IGNORE, could not allocate id
336         virtual content_t set(const std::string &name,
337                         const ContentFeatures &def)=0;
338         // If returns CONTENT_IGNORE, could not allocate id
339         virtual content_t allocateDummy(const std::string &name)=0;
340
341         /*
342                 Update item alias mapping.
343                 Call after updating item definitions.
344         */
345         virtual void updateAliases(IItemDefManager *idef)=0;
346
347         /*
348                 Update tile textures to latest return values of TextueSource.
349         */
350         virtual void updateTextures(IGameDef *gamedef,
351         /*argument: */void (*progress_callback)(void *progress_args, u32 progress, u32 max_progress),
352         /*argument: */void *progress_callback_args)=0;
353
354         virtual void serialize(std::ostream &os, u16 protocol_version)=0;
355         virtual void deSerialize(std::istream &is)=0;
356
357         virtual bool getNodeRegistrationStatus() const=0;
358         virtual void setNodeRegistrationStatus(bool completed)=0;
359
360         virtual void pendNodeResolve(NodeResolver *nr, NodeResolveMethod how)=0;
361         virtual bool cancelNodeResolveCallback(NodeResolver *nr)=0;
362         virtual void runNodeResolveCallbacks()=0;
363 };
364
365 IWritableNodeDefManager *createNodeDefManager();
366
367 class NodeResolver {
368 public:
369         NodeResolver();
370         virtual ~NodeResolver();
371         virtual void resolveNodeNames() = 0;
372
373         bool getIdFromNrBacklog(content_t *result_out,
374                 const std::string &node_alt, content_t c_fallback);
375         bool getIdsFromNrBacklog(std::vector<content_t> *result_out,
376                 bool all_required=false, content_t c_fallback=CONTENT_IGNORE);
377         const std::string &getNodeName(content_t c) const;
378
379         void nodeResolveInternal();
380
381         u32 m_nodenames_idx;
382         u32 m_nnlistsizes_idx;
383         std::vector<std::string> m_nodenames;
384         std::vector<size_t> m_nnlistsizes;
385         INodeDefManager *m_ndef;
386         bool m_resolve_done;
387 };
388
389 #endif
390