]> git.lizzy.rs Git - dragonfireclient.git/blob - src/nodedef.h
Merge pull request #1825 from Zeno-/control_key_cache
[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
44 enum ContentParamType
45 {
46         CPT_NONE,
47         CPT_LIGHT,
48 };
49
50 enum ContentParamType2
51 {
52         CPT2_NONE,
53         // Need 8-bit param2
54         CPT2_FULL,
55         // Flowing liquid properties
56         CPT2_FLOWINGLIQUID,
57         // Direction for chests and furnaces and such
58         CPT2_FACEDIR,
59         // Direction for signs, torches and such
60         CPT2_WALLMOUNTED,
61         // Block level like FLOWINGLIQUID
62         CPT2_LEVELED,
63 };
64
65 enum LiquidType
66 {
67         LIQUID_NONE,
68         LIQUID_FLOWING,
69         LIQUID_SOURCE,
70 };
71
72 enum NodeBoxType
73 {
74         NODEBOX_REGULAR, // Regular block; allows buildable_to
75         NODEBOX_FIXED, // Static separately defined box(es)
76         NODEBOX_WALLMOUNTED, // Box for wall mounted nodes; (top, bottom, side)
77         NODEBOX_LEVELED, // Same as fixed, but with dynamic height from param2. for snow, ...
78 };
79
80 struct NodeBox
81 {
82         enum NodeBoxType type;
83         // NODEBOX_REGULAR (no parameters)
84         // NODEBOX_FIXED
85         std::vector<aabb3f> fixed;
86         // NODEBOX_WALLMOUNTED
87         aabb3f wall_top;
88         aabb3f wall_bottom;
89         aabb3f wall_side; // being at the -X side
90
91         NodeBox()
92         { reset(); }
93
94         void reset();
95         void serialize(std::ostream &os, u16 protocol_version) const;
96         void deSerialize(std::istream &is);
97 };
98
99 struct MapNode;
100 class NodeMetadata;
101
102 /*
103         Stand-alone definition of a TileSpec (basically a server-side TileSpec)
104 */
105 enum TileAnimationType{
106         TAT_NONE=0,
107         TAT_VERTICAL_FRAMES=1,
108 };
109 struct TileDef
110 {
111         std::string name;
112         bool backface_culling; // Takes effect only in special cases
113         struct{
114                 enum TileAnimationType type;
115                 int aspect_w; // width for aspect ratio
116                 int aspect_h; // height for aspect ratio
117                 float length; // seconds
118         } animation;
119
120         TileDef()
121         {
122                 name = "";
123                 backface_culling = true;
124                 animation.type = TAT_NONE;
125                 animation.aspect_w = 1;
126                 animation.aspect_h = 1;
127                 animation.length = 1.0;
128         }
129
130         void serialize(std::ostream &os, u16 protocol_version) const;
131         void deSerialize(std::istream &is);
132 };
133
134 enum NodeDrawType
135 {
136         NDT_NORMAL, // A basic solid block
137         NDT_AIRLIKE, // Nothing is drawn
138         NDT_LIQUID, // Do not draw face towards same kind of flowing/source liquid
139         NDT_FLOWINGLIQUID, // A very special kind of thing
140         NDT_GLASSLIKE, // Glass-like, don't draw faces towards other glass
141         NDT_ALLFACES, // Leaves-like, draw all faces no matter what
142         NDT_ALLFACES_OPTIONAL, // Fancy -> allfaces, fast -> normal
143         NDT_TORCHLIKE,
144         NDT_SIGNLIKE,
145         NDT_PLANTLIKE,
146         NDT_FENCELIKE,
147         NDT_RAILLIKE,
148         NDT_NODEBOX,
149         NDT_GLASSLIKE_FRAMED, // Glass-like, draw connected frames and all all
150                               // visible faces
151                                                   // uses 2 textures, one for frames, second for faces
152         NDT_FIRELIKE, // Draw faces slightly rotated and only on connecting nodes,
153         NDT_GLASSLIKE_FRAMED_OPTIONAL,  // enabled -> connected, disabled -> Glass-like
154                                                                         // uses 2 textures, one for frames, second for faces
155         NDT_MESH, // Uses static meshes
156 };
157
158 #define CF_SPECIAL_COUNT 6
159
160 struct ContentFeatures
161 {
162         /*
163                 Cached stuff
164         */
165 #ifndef SERVER
166         // 0     1     2     3     4     5
167         // up    down  right left  back  front 
168         TileSpec tiles[6];
169         // Special tiles
170         // - Currently used for flowing liquids
171         TileSpec special_tiles[CF_SPECIAL_COUNT];
172         u8 solidness; // Used when choosing which face is drawn
173         u8 visual_solidness; // When solidness=0, this tells how it looks like
174         bool backface_culling;
175 #endif
176
177         // Server-side cached callback existence for fast skipping
178         bool has_on_construct;
179         bool has_on_destruct;
180         bool has_after_destruct;
181
182         /*
183                 Actual data
184         */
185
186         std::string name; // "" = undefined node
187         ItemGroupList groups; // Same as in itemdef
188
189         // Visual definition
190         enum NodeDrawType drawtype;
191         std::string mesh;
192 #ifndef SERVER
193         scene::IMesh *mesh_ptr[24];
194 #endif  
195         float visual_scale; // Misc. scale parameter
196         TileDef tiledef[6];
197         TileDef tiledef_special[CF_SPECIAL_COUNT]; // eg. flowing liquid
198         u8 alpha;
199
200         // Post effect color, drawn when the camera is inside the node.
201         video::SColor post_effect_color;
202         // Type of MapNode::param1
203         ContentParamType param_type;
204         // Type of MapNode::param2
205         ContentParamType2 param_type_2;
206         // True for all ground-like things like stone and mud, false for eg. trees
207         bool is_ground_content;
208         bool light_propagates;
209         bool sunlight_propagates;
210         // This is used for collision detection.
211         // Also for general solidness queries.
212         bool walkable;
213         // Player can point to these
214         bool pointable;
215         // Player can dig these
216         bool diggable;
217         // Player can climb these
218         bool climbable;
219         // Player can build on these
220         bool buildable_to;
221         // Player cannot build to these (placement prediction disabled)
222         bool rightclickable;
223         // Flowing liquid or snow, value = default level
224         u8 leveled;
225         // Whether the node is non-liquid, source liquid or flowing liquid
226         enum LiquidType liquid_type;
227         // If the content is liquid, this is the flowing version of the liquid.
228         std::string liquid_alternative_flowing;
229         // If the content is liquid, this is the source version of the liquid.
230         std::string liquid_alternative_source;
231         // Viscosity for fluid flow, ranging from 1 to 7, with
232         // 1 giving almost instantaneous propagation and 7 being
233         // the slowest possible
234         u8 liquid_viscosity;
235         // Is liquid renewable (new liquid source will be created between 2 existing)
236         bool liquid_renewable;
237         // Ice for water, water for ice
238         std::string freezemelt;
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 struct NodeResolveInfo {
286         std::string n_wanted;
287         std::string n_alt;
288         content_t c_fallback;
289         content_t *output;
290 };
291
292 #define NR_STATUS_FAILURE 0
293 #define NR_STATUS_PENDING 1
294 #define NR_STATUS_SUCCESS 2
295
296 /**
297         NodeResolver
298
299         NodeResolver attempts to resolve node names to content ID integers. If the
300         node registration phase has not yet finished at the time the resolution
301         request is placed, the request is marked as pending and added to an internal
302         queue.  The name resolution request is later satisfied by writing directly
303         to the output location when the node registration phase has been completed.
304
305         This is primarily intended to be used for objects registered during script
306         initialization (i.e. while nodes are being registered) that reference
307         particular nodes.
308 */
309 class NodeResolver {
310 public:
311         NodeResolver(INodeDefManager *ndef);
312         ~NodeResolver();
313
314         /**
315                 Add a request to resolve the node n_wanted and set *content to the
316                 result, or alternatively, n_alt if n_wanted is not found.  If n_alt
317                 cannot be found either, or has not been specified, *content is set
318                 to c_fallback.
319
320                 If node registration is complete, the request is finished immediately
321                 and NR_STATUS_SUCCESS is returned (or NR_STATUS_FAILURE if no node can
322                 be found).  Otherwise, NR_STATUS_PENDING is returned and the resolution
323                 request is queued.
324
325                 N.B.  If the memory in which content is located has been deallocated
326                 before the pending request had been satisfied, cancelNode() must be
327                 called.
328
329                 @param n_wanted Name of node that is wanted.
330                 @param n_alt Name of node in case n_wanted could not be found.  Blank
331                         if no alternative node is desired.
332                 @param c_fallback Content ID that content is set to in case of node
333                         resolution failure (should be CONTENT_AIR, CONTENT_IGNORE, etc.)
334                 @param content Pointer to content_t that receives the result of the
335                         node name resolution.
336                 @return Status of node resolution request.
337         */
338         int addNode(std::string n_wanted, std::string n_alt,
339                 content_t c_fallback, content_t *content);
340
341         /**
342                 Add a request to resolve the node(s) specified by nodename.
343
344                 If node registration is complete, the request is finished immediately
345                 and NR_STATUS_SUCCESS is returned if at least one node is resolved; if
346                 zero were resolved, NR_STATUS_FAILURE.  Otherwise, NR_STATUS_PENDING is
347                 returned and the resolution request is queued.
348
349                 N.B.  If the memory in which content_vec is located has been deallocated
350                 before the pending request had been satisfied, cancelNodeList() must be
351                 called.
352
353                 @param nodename Name of node (or node group) to be resolved.
354                 @param content_vec Pointer to content_t vector onto which the results
355                         are added.
356
357                 @return Status of node resolution request.
358         */
359         int addNodeList(const char *nodename, std::vector<content_t> *content_vec);
360
361         /**
362                 Removes all pending requests from the resolution queue to be satisfied
363                 to content.
364
365                 @param content Location of the content ID for the request being
366                         cancelled.
367                 @return Number of pending requests cancelled.
368         */
369         bool cancelNode(content_t *content);
370
371         /**
372                 Removes all pending requests from the resolution queue to be satisfied
373                 to content_vec.
374
375                 @param content_vec Location of the content ID vector for requests being
376                         cancelled.
377                 @return Number of pending requests cancelled.
378         */
379         int cancelNodeList(std::vector<content_t> *content_vec);
380
381         /**
382                 Carries out all pending node resolution requests.  Call this when the
383                 node registration phase has completed.
384
385                 Internally marks node registration as complete.
386
387                 @return Number of failed pending requests.
388         */
389         int resolveNodes();
390
391         /**
392                 Returns the status of the node registration phase.
393
394                 @return Boolean of whether the registration phase is complete.
395         */
396         bool isNodeRegFinished() { return m_is_node_registration_complete; }
397
398 private:
399         INodeDefManager *m_ndef;
400         bool m_is_node_registration_complete;
401         std::list<NodeResolveInfo *> m_pending_contents;
402         std::list<std::pair<std::string, std::vector<content_t> *> > m_pending_content_vecs;
403 };
404
405 class INodeDefManager
406 {
407 public:
408         INodeDefManager(){}
409         virtual ~INodeDefManager(){}
410         // Get node definition
411         virtual const ContentFeatures& get(content_t c) const=0;
412         virtual const ContentFeatures& get(const MapNode &n) const=0;
413         virtual bool getId(const std::string &name, content_t &result) const=0;
414         virtual content_t getId(const std::string &name) const=0;
415         // Allows "group:name" in addition to regular node names
416         virtual void getIds(const std::string &name, std::set<content_t> &result)
417                         const=0;
418         virtual const ContentFeatures& get(const std::string &name) const=0;
419         
420         virtual void serialize(std::ostream &os, u16 protocol_version)=0;
421
422         virtual NodeResolver *getResolver()=0;
423 };
424
425 class IWritableNodeDefManager : public INodeDefManager
426 {
427 public:
428         IWritableNodeDefManager(){}
429         virtual ~IWritableNodeDefManager(){}
430         virtual IWritableNodeDefManager* clone()=0;
431         // Get node definition
432         virtual const ContentFeatures& get(content_t c) const=0;
433         virtual const ContentFeatures& get(const MapNode &n) const=0;
434         virtual bool getId(const std::string &name, content_t &result) const=0;
435         // If not found, returns CONTENT_IGNORE
436         virtual content_t getId(const std::string &name) const=0;
437         // Allows "group:name" in addition to regular node names
438         virtual void getIds(const std::string &name, std::set<content_t> &result)
439                         const=0;
440         // If not found, returns the features of CONTENT_UNKNOWN
441         virtual const ContentFeatures& get(const std::string &name) const=0;
442
443         // Register node definition by name (allocate an id)
444         // If returns CONTENT_IGNORE, could not allocate id
445         virtual content_t set(const std::string &name,
446                         const ContentFeatures &def)=0;
447         // If returns CONTENT_IGNORE, could not allocate id
448         virtual content_t allocateDummy(const std::string &name)=0;
449
450         /*
451                 Update item alias mapping.
452                 Call after updating item definitions.
453         */
454         virtual void updateAliases(IItemDefManager *idef)=0;
455
456         /*
457                 Update tile textures to latest return values of TextueSource.
458         */
459         virtual void updateTextures(IGameDef *gamedef)=0;
460
461         virtual void serialize(std::ostream &os, u16 protocol_version)=0;
462         virtual void deSerialize(std::istream &is)=0;
463
464         virtual NodeResolver *getResolver()=0;
465 };
466
467 IWritableNodeDefManager *createNodeDefManager();
468
469 #endif
470