]> git.lizzy.rs Git - dragonfireclient.git/blob - src/nodedef.h
NodeResolver: Fix some comments and use const references for params
[dragonfireclient.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 "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 IItemDefManager;
38 class ITextureSource;
39 class IShaderSource;
40 class IGameDef;
41
42 typedef std::list<std::pair<content_t, int> > GroupItems;
43 typedef std::list<std::pair<std::string, std::vector<content_t> *> >
44         ContentVectorResolveList;
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         // Ice for water, water for ice
240         std::string freezemelt;
241         // Number of flowing liquids surrounding source
242         u8 liquid_range;
243         u8 drowning;
244         // Amount of light the node emits
245         u8 light_source;
246         u32 damage_per_second;
247         NodeBox node_box;
248         NodeBox selection_box;
249         NodeBox collision_box;
250         // Used for waving leaves/plants
251         u8 waving;
252         // Compatibility with old maps
253         // Set to true if paramtype used to be 'facedir_simple'
254         bool legacy_facedir_simple;
255         // Set to true if wall_mounted used to be set to true
256         bool legacy_wallmounted;
257
258         // Sound properties
259         SimpleSoundSpec sound_footstep;
260         SimpleSoundSpec sound_dig;
261         SimpleSoundSpec sound_dug;
262
263         /*
264                 Methods
265         */
266
267         ContentFeatures();
268         ~ContentFeatures();
269         void reset();
270         void serialize(std::ostream &os, u16 protocol_version);
271         void deSerialize(std::istream &is);
272         void serializeOld(std::ostream &os, u16 protocol_version);
273         void deSerializeOld(std::istream &is, int version);
274
275         /*
276                 Some handy methods
277         */
278         bool isLiquid() const{
279                 return (liquid_type != LIQUID_NONE);
280         }
281         bool sameLiquid(const ContentFeatures &f) const{
282                 if(!isLiquid() || !f.isLiquid()) return false;
283                 return (liquid_alternative_flowing == f.liquid_alternative_flowing);
284         }
285 };
286
287 struct NodeResolveInfo {
288         std::string n_wanted;
289         std::string n_alt;
290         content_t c_fallback;
291         content_t *output;
292 };
293
294 #define NR_STATUS_FAILURE 0
295 #define NR_STATUS_PENDING 1
296 #define NR_STATUS_SUCCESS 2
297
298 /**
299         NodeResolver
300
301         NodeResolver attempts to resolve node names to content ID integers. If the
302         node registration phase has not yet finished at the time the resolution
303         request is placed, the request is marked as pending and added to an internal
304         queue.  The name resolution request is later satisfied by writing directly
305         to the output location when the node registration phase has been completed.
306
307         This is primarily intended to be used for objects registered during script
308         initialization (i.e. while nodes are being registered) that reference
309         particular nodes.
310 */
311 class NodeResolver {
312 public:
313         NodeResolver(INodeDefManager *ndef);
314         ~NodeResolver();
315
316         /**
317                 Add a request to resolve the node n_wanted and set *content to the
318                 result, or alternatively, n_alt if n_wanted is not found.  If n_alt
319                 cannot be found either, or has not been specified, *content is set
320                 to c_fallback.
321
322                 If node registration is complete, the request is finished immediately
323                 and NR_STATUS_SUCCESS is returned (or NR_STATUS_FAILURE if no node can
324                 be found).  Otherwise, NR_STATUS_PENDING is returned and the resolution
325                 request is queued.
326
327                 N.B.  If the memory in which content is located has been deallocated
328                 before the pending request had been satisfied, cancelNode() must be
329                 called.
330
331                 @param n_wanted Name of node that is wanted.
332                 @param n_alt Name of node in case n_wanted could not be found.  Blank
333                         if no alternative node is desired.
334                 @param c_fallback Content ID that content is set to in case of node
335                         resolution failure (should be CONTENT_AIR, CONTENT_IGNORE, etc.)
336                 @param content Pointer to content_t that receives the result of the
337                         node name resolution.
338                 @return Status of node resolution request.
339         */
340         int addNode(const std::string &n_wanted, const std::string &n_alt,
341                 content_t c_fallback, content_t *content);
342
343         /**
344                 Add a request to resolve the node(s) specified by nodename.
345
346                 If node registration is complete, the request is finished immediately
347                 and NR_STATUS_SUCCESS is returned if at least one node is resolved; if
348                 zero were resolved, NR_STATUS_FAILURE.  Otherwise, NR_STATUS_PENDING is
349                 returned and the resolution request is queued.
350
351                 N.B.  If the memory in which content_vec is located has been deallocated
352                 before the pending request had been satisfied, cancelNodeList() must be
353                 called.
354
355                 @param nodename Name of node (or node group) to be resolved.
356                 @param content_vec Pointer to content_t vector onto which the results
357                         are added.
358
359                 @return Status of node resolution request.
360         */
361         int addNodeList(const std::string &nodename,
362                 std::vector<content_t> *content_vec);
363
364         /**
365                 Removes all pending requests from the resolution queue with the output
366                 address of 'content'.
367
368                 @param content Location of the content ID for the request being
369                         cancelled.
370                 @return Number of pending requests cancelled.
371         */
372         bool cancelNode(content_t *content);
373
374         /**
375                 Removes all pending requests from the resolution queue with the output
376                 address of 'content_vec'.
377
378                 @param content_vec Location of the content ID vector for requests being
379                         cancelled.
380                 @return Number of pending requests cancelled.
381         */
382         int cancelNodeList(std::vector<content_t> *content_vec);
383
384         /**
385                 Carries out all pending node resolution requests.  Call this when the
386                 node registration phase has completed.
387
388                 Internally marks node registration as complete.
389
390                 @return Number of failed pending requests.
391         */
392         int resolveNodes();
393
394         /**
395                 Returns the status of the node registration phase.
396
397                 @return Boolean of whether the registration phase is complete.
398         */
399         bool isNodeRegFinished() { return m_is_node_registration_complete; }
400
401 private:
402         INodeDefManager *m_ndef;
403         bool m_is_node_registration_complete;
404         std::list<NodeResolveInfo *> m_pending_contents;
405         ContentVectorResolveList m_pending_content_vecs;
406 };
407
408 class INodeDefManager
409 {
410 public:
411         INodeDefManager(){}
412         virtual ~INodeDefManager(){}
413         // Get node definition
414         virtual const ContentFeatures& get(content_t c) const=0;
415         virtual const ContentFeatures& get(const MapNode &n) const=0;
416         virtual bool getId(const std::string &name, content_t &result) const=0;
417         virtual content_t getId(const std::string &name) const=0;
418         // Allows "group:name" in addition to regular node names
419         virtual void getIds(const std::string &name, std::set<content_t> &result)
420                         const=0;
421         virtual const ContentFeatures& get(const std::string &name) const=0;
422
423         virtual void serialize(std::ostream &os, u16 protocol_version)=0;
424
425         virtual NodeResolver *getResolver()=0;
426 };
427
428 class IWritableNodeDefManager : public INodeDefManager
429 {
430 public:
431         IWritableNodeDefManager(){}
432         virtual ~IWritableNodeDefManager(){}
433         virtual IWritableNodeDefManager* clone()=0;
434         // Get node definition
435         virtual const ContentFeatures& get(content_t c) const=0;
436         virtual const ContentFeatures& get(const MapNode &n) const=0;
437         virtual bool getId(const std::string &name, content_t &result) const=0;
438         // If not found, returns CONTENT_IGNORE
439         virtual content_t getId(const std::string &name) const=0;
440         // Allows "group:name" in addition to regular node names
441         virtual void getIds(const std::string &name, std::set<content_t> &result)
442                         const=0;
443         // If not found, returns the features of CONTENT_UNKNOWN
444         virtual const ContentFeatures& get(const std::string &name) const=0;
445
446         // Register node definition by name (allocate an id)
447         // If returns CONTENT_IGNORE, could not allocate id
448         virtual content_t set(const std::string &name,
449                         const ContentFeatures &def)=0;
450         // If returns CONTENT_IGNORE, could not allocate id
451         virtual content_t allocateDummy(const std::string &name)=0;
452
453         /*
454                 Update item alias mapping.
455                 Call after updating item definitions.
456         */
457         virtual void updateAliases(IItemDefManager *idef)=0;
458
459         /*
460                 Update tile textures to latest return values of TextueSource.
461         */
462         virtual void updateTextures(IGameDef *gamedef)=0;
463
464         virtual void serialize(std::ostream &os, u16 protocol_version)=0;
465         virtual void deSerialize(std::istream &is)=0;
466
467         virtual NodeResolver *getResolver()=0;
468 };
469
470 IWritableNodeDefManager *createNodeDefManager();
471
472 #endif
473