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 #pragma once 21 22 #include "irrlichttypes_bloated.h" 23 #include <string> 24 #include <iostream> 25 #include <map> 26 #include "mapnode.h" 27 #include "nameidmapping.h" 28 #ifndef SERVER 29 #include "client/tile.h" 30 #include <IMeshManipulator.h> 31 class Client; 32 #endif 33 #include "itemgroup.h" 34 #include "sound.h" // SimpleSoundSpec 35 #include "constants.h" // BS 36 #include "texture_override.h" // TextureOverride 37 #include "tileanimation.h" 38 39 // PROTOCOL_VERSION >= 37 40 static const u8 CONTENTFEATURES_VERSION = 13; 41 42 class IItemDefManager; 43 class ITextureSource; 44 class IShaderSource; 45 class IGameDef; 46 class NodeResolver; 47 48 enum ContentParamType 49 { 50 CPT_NONE, 51 CPT_LIGHT, 52 }; 53 54 enum ContentParamType2 55 { 56 CPT2_NONE, 57 // Need 8-bit param2 58 CPT2_FULL, 59 // Flowing liquid properties 60 CPT2_FLOWINGLIQUID, 61 // Direction for chests and furnaces and such 62 CPT2_FACEDIR, 63 // Direction for signs, torches and such 64 CPT2_WALLMOUNTED, 65 // Block level like FLOWINGLIQUID 66 CPT2_LEVELED, 67 // 2D rotation for things like plants 68 CPT2_DEGROTATE, 69 // Mesh options for plants 70 CPT2_MESHOPTIONS, 71 // Index for palette 72 CPT2_COLOR, 73 // 3 bits of palette index, then facedir 74 CPT2_COLORED_FACEDIR, 75 // 5 bits of palette index, then wallmounted 76 CPT2_COLORED_WALLMOUNTED, 77 // Glasslike framed drawtype internal liquid level, param2 values 0 to 63 78 CPT2_GLASSLIKE_LIQUID_LEVEL, 79 }; 80 81 enum LiquidType 82 { 83 LIQUID_NONE, 84 LIQUID_FLOWING, 85 LIQUID_SOURCE, 86 }; 87 88 enum NodeBoxType 89 { 90 NODEBOX_REGULAR, // Regular block; allows buildable_to 91 NODEBOX_FIXED, // Static separately defined box(es) 92 NODEBOX_WALLMOUNTED, // Box for wall mounted nodes; (top, bottom, side) 93 NODEBOX_LEVELED, // Same as fixed, but with dynamic height from param2. for snow, ... 94 NODEBOX_CONNECTED, // optionally draws nodeboxes if a neighbor node attaches 95 }; 96 97 struct NodeBox 98 { 99 enum NodeBoxType type; 100 // NODEBOX_REGULAR (no parameters) 101 // NODEBOX_FIXED 102 std::vector<aabb3f> fixed; 103 // NODEBOX_WALLMOUNTED 104 aabb3f wall_top; 105 aabb3f wall_bottom; 106 aabb3f wall_side; // being at the -X side 107 // NODEBOX_CONNECTED 108 std::vector<aabb3f> connect_top; 109 std::vector<aabb3f> connect_bottom; 110 std::vector<aabb3f> connect_front; 111 std::vector<aabb3f> connect_left; 112 std::vector<aabb3f> connect_back; 113 std::vector<aabb3f> connect_right; 114 std::vector<aabb3f> disconnected_top; 115 std::vector<aabb3f> disconnected_bottom; 116 std::vector<aabb3f> disconnected_front; 117 std::vector<aabb3f> disconnected_left; 118 std::vector<aabb3f> disconnected_back; 119 std::vector<aabb3f> disconnected_right; 120 std::vector<aabb3f> disconnected; 121 std::vector<aabb3f> disconnected_sides; 122 NodeBoxNodeBox123 NodeBox() 124 { reset(); } 125 126 void reset(); 127 void serialize(std::ostream &os, u16 protocol_version) const; 128 void deSerialize(std::istream &is); 129 }; 130 131 struct MapNode; 132 class NodeMetadata; 133 134 enum LeavesStyle { 135 LEAVES_FANCY, 136 LEAVES_SIMPLE, 137 LEAVES_OPAQUE, 138 }; 139 140 enum AutoScale : u8 { 141 AUTOSCALE_DISABLE, 142 AUTOSCALE_ENABLE, 143 AUTOSCALE_FORCE, 144 }; 145 146 enum WorldAlignMode : u8 { 147 WORLDALIGN_DISABLE, 148 WORLDALIGN_ENABLE, 149 WORLDALIGN_FORCE, 150 WORLDALIGN_FORCE_NODEBOX, 151 }; 152 153 class TextureSettings { 154 public: 155 LeavesStyle leaves_style; 156 WorldAlignMode world_aligned_mode; 157 AutoScale autoscale_mode; 158 int node_texture_size; 159 bool opaque_water; 160 bool connected_glass; 161 bool enable_mesh_cache; 162 bool enable_minimap; 163 164 TextureSettings() = default; 165 166 void readSettings(); 167 }; 168 169 enum NodeDrawType 170 { 171 // A basic solid block 172 NDT_NORMAL, 173 // Nothing is drawn 174 NDT_AIRLIKE, 175 // Do not draw face towards same kind of flowing/source liquid 176 NDT_LIQUID, 177 // A very special kind of thing 178 NDT_FLOWINGLIQUID, 179 // Glass-like, don't draw faces towards other glass 180 NDT_GLASSLIKE, 181 // Leaves-like, draw all faces no matter what 182 NDT_ALLFACES, 183 // Enabled -> ndt_allfaces, disabled -> ndt_normal 184 NDT_ALLFACES_OPTIONAL, 185 // Single plane perpendicular to a surface 186 NDT_TORCHLIKE, 187 // Single plane parallel to a surface 188 NDT_SIGNLIKE, 189 // 2 vertical planes in a 'X' shape diagonal to XZ axes. 190 // paramtype2 = "meshoptions" allows various forms, sizes and 191 // vertical and horizontal random offsets. 192 NDT_PLANTLIKE, 193 // Fenceposts that connect to neighbouring fenceposts with horizontal bars 194 NDT_FENCELIKE, 195 // Selects appropriate junction texture to connect like rails to 196 // neighbouring raillikes. 197 NDT_RAILLIKE, 198 // Custom Lua-definable structure of multiple cuboids 199 NDT_NODEBOX, 200 // Glass-like, draw connected frames and all visible faces. 201 // param2 > 0 defines 64 levels of internal liquid 202 // Uses 3 textures, one for frames, second for faces, 203 // optional third is a 'special tile' for the liquid. 204 NDT_GLASSLIKE_FRAMED, 205 // Draw faces slightly rotated and only on neighbouring nodes 206 NDT_FIRELIKE, 207 // Enabled -> ndt_glasslike_framed, disabled -> ndt_glasslike 208 NDT_GLASSLIKE_FRAMED_OPTIONAL, 209 // Uses static meshes 210 NDT_MESH, 211 // Combined plantlike-on-solid 212 NDT_PLANTLIKE_ROOTED, 213 }; 214 215 // Mesh options for NDT_PLANTLIKE with CPT2_MESHOPTIONS 216 static const u8 MO_MASK_STYLE = 0x07; 217 static const u8 MO_BIT_RANDOM_OFFSET = 0x08; 218 static const u8 MO_BIT_SCALE_SQRT2 = 0x10; 219 static const u8 MO_BIT_RANDOM_OFFSET_Y = 0x20; 220 enum PlantlikeStyle { 221 PLANT_STYLE_CROSS, 222 PLANT_STYLE_CROSS2, 223 PLANT_STYLE_STAR, 224 PLANT_STYLE_HASH, 225 PLANT_STYLE_HASH2, 226 }; 227 228 enum AlignStyle : u8 { 229 ALIGN_STYLE_NODE, 230 ALIGN_STYLE_WORLD, 231 ALIGN_STYLE_USER_DEFINED, 232 }; 233 234 enum AlphaMode : u8 { 235 ALPHAMODE_BLEND, 236 ALPHAMODE_CLIP, 237 ALPHAMODE_OPAQUE, 238 ALPHAMODE_LEGACY_COMPAT, /* means either opaque or clip */ 239 }; 240 241 242 /* 243 Stand-alone definition of a TileSpec (basically a server-side TileSpec) 244 */ 245 246 struct TileDef 247 { 248 std::string name = ""; 249 bool backface_culling = true; // Takes effect only in special cases 250 bool tileable_horizontal = true; 251 bool tileable_vertical = true; 252 //! If true, the tile has its own color. 253 bool has_color = false; 254 //! The color of the tile. 255 video::SColor color = video::SColor(0xFFFFFFFF); 256 AlignStyle align_style = ALIGN_STYLE_NODE; 257 u8 scale = 0; 258 259 struct TileAnimationParams animation; 260 TileDefTileDef261 TileDef() 262 { 263 animation.type = TAT_NONE; 264 } 265 266 void serialize(std::ostream &os, u16 protocol_version) const; 267 void deSerialize(std::istream &is, u8 contentfeatures_version, 268 NodeDrawType drawtype); 269 }; 270 271 // Defines the number of special tiles per nodedef 272 // 273 // NOTE: When changing this value, the enum entries of OverrideTarget and 274 // parser in TextureOverrideSource must be updated so that all special 275 // tiles can be overridden. 276 #define CF_SPECIAL_COUNT 6 277 278 struct ContentFeatures 279 { 280 /* 281 Cached stuff 282 */ 283 #ifndef SERVER 284 // 0 1 2 3 4 5 285 // up down right left back front 286 TileSpec tiles[6]; 287 // Special tiles 288 // - Currently used for flowing liquids 289 TileSpec special_tiles[CF_SPECIAL_COUNT]; 290 u8 solidness; // Used when choosing which face is drawn 291 u8 visual_solidness; // When solidness=0, this tells how it looks like 292 bool backface_culling; 293 #endif 294 295 // Server-side cached callback existence for fast skipping 296 bool has_on_construct; 297 bool has_on_destruct; 298 bool has_after_destruct; 299 300 /* 301 Actual data 302 */ 303 304 // --- GENERAL PROPERTIES --- 305 306 std::string name; // "" = undefined node 307 ItemGroupList groups; // Same as in itemdef 308 // Type of MapNode::param1 309 ContentParamType param_type; 310 // Type of MapNode::param2 311 ContentParamType2 param_type_2; 312 313 // --- VISUAL PROPERTIES --- 314 315 enum NodeDrawType drawtype; 316 std::string mesh; 317 #ifndef SERVER 318 scene::IMesh *mesh_ptr[24]; 319 video::SColor minimap_color; 320 #endif 321 float visual_scale; // Misc. scale parameter 322 TileDef tiledef[6]; 323 // These will be drawn over the base tiles. 324 TileDef tiledef_overlay[6]; 325 TileDef tiledef_special[CF_SPECIAL_COUNT]; // eg. flowing liquid 326 AlphaMode alpha; 327 // The color of the node. 328 video::SColor color; 329 std::string palette_name; 330 std::vector<video::SColor> *palette; 331 // Used for waving leaves/plants 332 u8 waving; 333 // for NDT_CONNECTED pairing 334 u8 connect_sides; 335 std::vector<std::string> connects_to; 336 std::vector<content_t> connects_to_ids; 337 // Post effect color, drawn when the camera is inside the node. 338 video::SColor post_effect_color; 339 // Flowing liquid or leveled nodebox, value = default level 340 u8 leveled; 341 // Maximum value for leveled nodes 342 u8 leveled_max; 343 344 // --- LIGHTING-RELATED --- 345 346 bool light_propagates; 347 bool sunlight_propagates; 348 // Amount of light the node emits 349 u8 light_source; 350 351 // --- MAP GENERATION --- 352 353 // True for all ground-like things like stone and mud, false for eg. trees 354 bool is_ground_content; 355 356 // --- INTERACTION PROPERTIES --- 357 358 // This is used for collision detection. 359 // Also for general solidness queries. 360 bool walkable; 361 // Player can point to these 362 bool pointable; 363 // Player can dig these 364 bool diggable; 365 // Player can climb these 366 bool climbable; 367 // Player can build on these 368 bool buildable_to; 369 // Player cannot build to these (placement prediction disabled) 370 bool rightclickable; 371 u32 damage_per_second; 372 // client dig prediction 373 std::string node_dig_prediction; 374 375 // --- LIQUID PROPERTIES --- 376 377 // Whether the node is non-liquid, source liquid or flowing liquid 378 enum LiquidType liquid_type; 379 // If the content is liquid, this is the flowing version of the liquid. 380 std::string liquid_alternative_flowing; 381 content_t liquid_alternative_flowing_id; 382 // If the content is liquid, this is the source version of the liquid. 383 std::string liquid_alternative_source; 384 content_t liquid_alternative_source_id; 385 // Viscosity for fluid flow, ranging from 1 to 7, with 386 // 1 giving almost instantaneous propagation and 7 being 387 // the slowest possible 388 u8 liquid_viscosity; 389 // Is liquid renewable (new liquid source will be created between 2 existing) 390 bool liquid_renewable; 391 // Number of flowing liquids surrounding source 392 u8 liquid_range; 393 u8 drowning; 394 // Liquids flow into and replace node 395 bool floodable; 396 397 // --- NODEBOXES --- 398 399 NodeBox node_box; 400 NodeBox selection_box; 401 NodeBox collision_box; 402 403 // --- SOUND PROPERTIES --- 404 405 SimpleSoundSpec sound_footstep; 406 SimpleSoundSpec sound_dig; 407 SimpleSoundSpec sound_dug; 408 409 // --- LEGACY --- 410 411 // Compatibility with old maps 412 // Set to true if paramtype used to be 'facedir_simple' 413 bool legacy_facedir_simple; 414 // Set to true if wall_mounted used to be set to true 415 bool legacy_wallmounted; 416 417 /* 418 Methods 419 */ 420 421 ContentFeatures(); 422 ~ContentFeatures(); 423 void reset(); 424 void serialize(std::ostream &os, u16 protocol_version) const; 425 void deSerialize(std::istream &is); 426 427 /* 428 Some handy methods 429 */ setDefaultAlphaModeContentFeatures430 void setDefaultAlphaMode() 431 { 432 switch (drawtype) { 433 case NDT_NORMAL: 434 case NDT_LIQUID: 435 case NDT_FLOWINGLIQUID: 436 alpha = ALPHAMODE_OPAQUE; 437 break; 438 case NDT_NODEBOX: 439 case NDT_MESH: 440 alpha = ALPHAMODE_LEGACY_COMPAT; // this should eventually be OPAQUE 441 break; 442 default: 443 alpha = ALPHAMODE_CLIP; 444 break; 445 } 446 } 447 needsBackfaceCullingContentFeatures448 bool needsBackfaceCulling() const 449 { 450 switch (drawtype) { 451 case NDT_TORCHLIKE: 452 case NDT_SIGNLIKE: 453 case NDT_FIRELIKE: 454 case NDT_RAILLIKE: 455 case NDT_PLANTLIKE: 456 case NDT_PLANTLIKE_ROOTED: 457 case NDT_MESH: 458 return false; 459 default: 460 return true; 461 } 462 } 463 isLiquidContentFeatures464 bool isLiquid() const{ 465 return (liquid_type != LIQUID_NONE); 466 } sameLiquidContentFeatures467 bool sameLiquid(const ContentFeatures &f) const{ 468 if(!isLiquid() || !f.isLiquid()) return false; 469 return (liquid_alternative_flowing_id == f.liquid_alternative_flowing_id); 470 } 471 getGroupContentFeatures472 int getGroup(const std::string &group) const 473 { 474 return itemgroup_get(groups, group); 475 } 476 477 #ifndef SERVER 478 void updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc, 479 scene::IMeshManipulator *meshmanip, Client *client, const TextureSettings &tsettings); 480 #endif 481 482 private: 483 #ifndef SERVER 484 /* 485 * Checks if any tile texture has any transparent pixels. 486 * Prints a warning and returns true if that is the case, false otherwise. 487 * This is supposed to be used for use_texture_alpha backwards compatibility. 488 */ 489 bool textureAlphaCheck(ITextureSource *tsrc, const TileDef *tiles, 490 int length); 491 #endif 492 493 void setAlphaFromLegacy(u8 legacy_alpha); 494 495 u8 getAlphaForLegacy() const; 496 }; 497 498 /*! 499 * @brief This class is for getting the actual properties of nodes from their 500 * content ID. 501 * 502 * @details The nodes on the map are represented by three numbers (see MapNode). 503 * The first number (param0) is the type of a node. All node types have own 504 * properties (see ContentFeatures). This class is for storing and getting the 505 * properties of nodes. 506 * The manager is first filled with registered nodes, then as the game begins, 507 * functions only get `const` pointers to it, to prevent modification of 508 * registered nodes. 509 */ 510 class NodeDefManager { 511 public: 512 /*! 513 * Creates a NodeDefManager, and registers three ContentFeatures: 514 * \ref CONTENT_AIR, \ref CONTENT_UNKNOWN and \ref CONTENT_IGNORE. 515 */ 516 NodeDefManager(); 517 ~NodeDefManager(); 518 519 /*! 520 * Returns the properties for the given content type. 521 * @param c content type of a node 522 * @return properties of the given content type, or \ref CONTENT_UNKNOWN 523 * if the given content type is not registered. 524 */ get(content_t c)525 inline const ContentFeatures& get(content_t c) const { 526 return 527 c < m_content_features.size() ? 528 m_content_features[c] : m_content_features[CONTENT_UNKNOWN]; 529 } 530 531 /*! 532 * Returns the properties of the given node. 533 * @param n a map node 534 * @return properties of the given node or @ref CONTENT_UNKNOWN if the 535 * given content type is not registered. 536 */ get(const MapNode & n)537 inline const ContentFeatures& get(const MapNode &n) const { 538 return get(n.getContent()); 539 } 540 541 /*! 542 * Returns the node properties for a node name. 543 * @param name name of a node 544 * @return properties of the given node or @ref CONTENT_UNKNOWN if 545 * not found 546 */ 547 const ContentFeatures& get(const std::string &name) const; 548 549 /*! 550 * Returns the content ID for the given name. 551 * @param name a node name 552 * @param[out] result will contain the content ID if found, otherwise 553 * remains unchanged 554 * @return true if the ID was found, false otherwise 555 */ 556 bool getId(const std::string &name, content_t &result) const; 557 558 /*! 559 * Returns the content ID for the given name. 560 * @param name a node name 561 * @return ID of the node or @ref CONTENT_IGNORE if not found 562 */ 563 content_t getId(const std::string &name) const; 564 565 /*! 566 * Returns the content IDs of the given node name or node group name. 567 * Group names start with "group:". 568 * @param name a node name or node group name 569 * @param[out] result will be appended with matching IDs 570 * @return true if `name` is a valid node name or a (not necessarily 571 * valid) group name 572 */ 573 bool getIds(const std::string &name, std::vector<content_t> &result) const; 574 575 /*! 576 * Returns the smallest box in integer node coordinates that 577 * contains all nodes' selection boxes. The returned box might be larger 578 * than the minimal size if the largest node is removed from the manager. 579 */ getSelectionBoxIntUnion()580 inline core::aabbox3d<s16> getSelectionBoxIntUnion() const { 581 return m_selection_box_int_union; 582 } 583 584 /*! 585 * Checks whether a node connects to an adjacent node. 586 * @param from the node to be checked 587 * @param to the adjacent node 588 * @param connect_face a bit field indicating which face of the node is 589 * adjacent to the other node. 590 * Bits: +y (least significant), -y, -z, -x, +z, +x (most significant). 591 * @return true if the node connects, false otherwise 592 */ 593 bool nodeboxConnects(MapNode from, MapNode to, 594 u8 connect_face) const; 595 596 /*! 597 * Registers a NodeResolver to wait for the registration of 598 * ContentFeatures. Once the node registration finishes, all 599 * listeners are notified. 600 */ 601 void pendNodeResolve(NodeResolver *nr) const; 602 603 /*! 604 * Stops listening to the NodeDefManager. 605 * @return true if the listener was registered before, false otherwise 606 */ 607 bool cancelNodeResolveCallback(NodeResolver *nr) const; 608 609 /*! 610 * Registers a new node type with the given name and allocates a new 611 * content ID. 612 * Should not be called with an already existing name. 613 * @param name name of the node, must match with `def.name`. 614 * @param def definition of the registered node type. 615 * @return ID of the registered node or @ref CONTENT_IGNORE if 616 * the function could not allocate an ID. 617 */ 618 content_t set(const std::string &name, const ContentFeatures &def); 619 620 /*! 621 * Allocates a blank node ID for the given name. 622 * @param name name of a node 623 * @return allocated ID or @ref CONTENT_IGNORE if could not allocate 624 * an ID. 625 */ 626 content_t allocateDummy(const std::string &name); 627 628 /*! 629 * Removes the given node name from the manager. 630 * The node ID will remain in the manager, but won't be linked to any name. 631 * @param name name to be removed 632 */ 633 void removeNode(const std::string &name); 634 635 /*! 636 * Regenerates the alias list (a map from names to node IDs). 637 * @param idef the item definition manager containing alias information 638 */ 639 void updateAliases(IItemDefManager *idef); 640 641 /*! 642 * Replaces the textures of registered nodes with the ones specified in 643 * the texturepack's override.txt file 644 * 645 * @param overrides the texture overrides 646 */ 647 void applyTextureOverrides(const std::vector<TextureOverride> &overrides); 648 649 /*! 650 * Only the client uses this. Loads textures and shaders required for 651 * rendering the nodes. 652 * @param gamedef must be a Client. 653 * @param progress_cbk called each time a node is loaded. Arguments: 654 * `progress_cbk_args`, number of loaded ContentFeatures, number of 655 * total ContentFeatures. 656 * @param progress_cbk_args passed to the callback function 657 */ 658 void updateTextures(IGameDef *gamedef, 659 void (*progress_cbk)(void *progress_args, u32 progress, u32 max_progress), 660 void *progress_cbk_args); 661 662 /*! 663 * Writes the content of this manager to the given output stream. 664 * @param protocol_version serialization version of ContentFeatures 665 */ 666 void serialize(std::ostream &os, u16 protocol_version) const; 667 668 /*! 669 * Restores the manager from a serialized stream. 670 * This clears the previous state. 671 * @param is input stream containing a serialized NodeDefManager 672 */ 673 void deSerialize(std::istream &is); 674 675 /*! 676 * Used to indicate that node registration has finished. 677 * @param completed tells whether registration is complete 678 */ setNodeRegistrationStatus(bool completed)679 inline void setNodeRegistrationStatus(bool completed) { 680 m_node_registration_complete = completed; 681 } 682 683 /*! 684 * Notifies the registered NodeResolver instances that node registration 685 * has finished, then unregisters all listeners. 686 * Must be called after node registration has finished! 687 */ 688 void runNodeResolveCallbacks(); 689 690 /*! 691 * Sets the registration completion flag to false and unregisters all 692 * NodeResolver instances listening to the manager. 693 */ 694 void resetNodeResolveState(); 695 696 /*! 697 * Resolves (caches the IDs) cross-references between nodes, 698 * like liquid alternatives. 699 * Must be called after node registration has finished! 700 */ 701 void resolveCrossrefs(); 702 703 private: 704 /*! 705 * Resets the manager to its initial state. 706 * See the documentation of the constructor. 707 */ 708 void clear(); 709 710 /*! 711 * Allocates a new content ID, and returns it. 712 * @return the allocated ID or \ref CONTENT_IGNORE if could not allocate 713 */ 714 content_t allocateId(); 715 716 /*! 717 * Binds the given content ID and node name. 718 * Registers them in \ref m_name_id_mapping and 719 * \ref m_name_id_mapping_with_aliases. 720 * @param i a content ID 721 * @param name a node name 722 */ 723 void addNameIdMapping(content_t i, std::string name); 724 725 /*! 726 * Removes a content ID from all groups. 727 * Erases content IDs from vectors in \ref m_group_to_items and 728 * removes empty vectors. 729 * @param id Content ID 730 */ 731 void eraseIdFromGroups(content_t id); 732 733 /*! 734 * Recalculates m_selection_box_int_union based on 735 * m_selection_box_union. 736 */ 737 void fixSelectionBoxIntUnion(); 738 739 //! Features indexed by ID. 740 std::vector<ContentFeatures> m_content_features; 741 742 //! A mapping for fast conversion between names and IDs 743 NameIdMapping m_name_id_mapping; 744 745 /*! 746 * Like @ref m_name_id_mapping, but maps only from names to IDs, and 747 * includes aliases too. Updated by \ref updateAliases(). 748 * Note: Not serialized. 749 */ 750 std::unordered_map<std::string, content_t> m_name_id_mapping_with_aliases; 751 752 /*! 753 * A mapping from group names to a vector of content types that belong 754 * to it. Necessary for a direct lookup in \ref getIds(). 755 * Note: Not serialized. 756 */ 757 std::unordered_map<std::string, std::vector<content_t>> m_group_to_items; 758 759 /*! 760 * The next ID that might be free to allocate. 761 * It can be allocated already, because \ref CONTENT_AIR, 762 * \ref CONTENT_UNKNOWN and \ref CONTENT_IGNORE are registered when the 763 * manager is initialized, and new IDs are allocated from 0. 764 */ 765 content_t m_next_id; 766 767 //! True if all nodes have been registered. 768 bool m_node_registration_complete; 769 770 /*! 771 * The union of all nodes' selection boxes. 772 * Might be larger if big nodes are removed from the manager. 773 */ 774 aabb3f m_selection_box_union; 775 776 /*! 777 * The smallest box in integer node coordinates that 778 * contains all nodes' selection boxes. 779 * Might be larger if big nodes are removed from the manager. 780 */ 781 core::aabbox3d<s16> m_selection_box_int_union; 782 783 /*! 784 * NodeResolver instances to notify once node registration has finished. 785 * Even constant NodeDefManager instances can register listeners. 786 */ 787 mutable std::vector<NodeResolver *> m_pending_resolve_callbacks; 788 }; 789 790 NodeDefManager *createNodeDefManager(); 791 792 class NodeResolver { 793 public: 794 NodeResolver(); 795 virtual ~NodeResolver(); 796 virtual void resolveNodeNames() = 0; 797 798 // required because this class is used as mixin for ObjDef 799 void cloneTo(NodeResolver *res) const; 800 801 bool getIdFromNrBacklog(content_t *result_out, 802 const std::string &node_alt, content_t c_fallback, 803 bool error_on_fallback = true); 804 bool getIdsFromNrBacklog(std::vector<content_t> *result_out, 805 bool all_required = false, content_t c_fallback = CONTENT_IGNORE); 806 807 void nodeResolveInternal(); 808 809 u32 m_nodenames_idx = 0; 810 u32 m_nnlistsizes_idx = 0; 811 std::vector<std::string> m_nodenames; 812 std::vector<size_t> m_nnlistsizes; 813 const NodeDefManager *m_ndef = nullptr; 814 bool m_resolve_done = false; 815 }; 816