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