X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fnodedef.h;h=288d09dd836a4c1238635579d318842938d005d6;hb=e84d259ec7fcc00466bd947070cb4ed77cd83c52;hp=cf03abaae8b493b552d0875973f6de97888cb4f9;hpb=c6422e087257d661a30ee2cd281ccec91f2f90ca;p=minetest.git diff --git a/src/nodedef.h b/src/nodedef.h index cf03abaae..288d09dd8 100644 --- a/src/nodedef.h +++ b/src/nodedef.h @@ -36,14 +36,14 @@ class Client; #include "texture_override.h" // TextureOverride #include "tileanimation.h" -// PROTOCOL_VERSION >= 37 -static const u8 CONTENTFEATURES_VERSION = 13; - class IItemDefManager; class ITextureSource; class IShaderSource; class IGameDef; class NodeResolver; +#if BUILD_UNITTESTS +class TestSchematic; +#endif enum ContentParamType { @@ -58,13 +58,13 @@ enum ContentParamType2 CPT2_FULL, // Flowing liquid properties CPT2_FLOWINGLIQUID, - // Direction for chests and furnaces and such + // Direction for chests and furnaces and such (with axis rotation) CPT2_FACEDIR, // Direction for signs, torches and such CPT2_WALLMOUNTED, // Block level like FLOWINGLIQUID CPT2_LEVELED, - // 2D rotation for things like plants + // 2D rotation CPT2_DEGROTATE, // Mesh options for plants CPT2_MESHOPTIONS, @@ -76,6 +76,12 @@ enum ContentParamType2 CPT2_COLORED_WALLMOUNTED, // Glasslike framed drawtype internal liquid level, param2 values 0 to 63 CPT2_GLASSLIKE_LIQUID_LEVEL, + // 3 bits of palette index, then degrotate + CPT2_COLORED_DEGROTATE, + // Simplified direction for chests and furnaces and such (4 directions) + CPT2_4DIR, + // 6 bits of palette index, then 4dir + CPT2_COLORED_4DIR, }; enum LiquidType @@ -94,17 +100,8 @@ enum NodeBoxType NODEBOX_CONNECTED, // optionally draws nodeboxes if a neighbor node attaches }; -struct NodeBox +struct NodeBoxConnected { - enum NodeBoxType type; - // NODEBOX_REGULAR (no parameters) - // NODEBOX_FIXED - std::vector fixed; - // NODEBOX_WALLMOUNTED - aabb3f wall_top; - aabb3f wall_bottom; - aabb3f wall_side; // being at the -X side - // NODEBOX_CONNECTED std::vector connect_top; std::vector connect_bottom; std::vector connect_front; @@ -119,9 +116,35 @@ struct NodeBox std::vector disconnected_right; std::vector disconnected; std::vector disconnected_sides; +}; + +struct NodeBox +{ + enum NodeBoxType type; + // NODEBOX_REGULAR (no parameters) + // NODEBOX_FIXED + std::vector fixed; + // NODEBOX_WALLMOUNTED + aabb3f wall_top; + aabb3f wall_bottom; + aabb3f wall_side; // being at the -X side + // NODEBOX_CONNECTED + // (kept externally to not bloat the structure) + std::shared_ptr connected; NodeBox() { reset(); } + ~NodeBox() = default; + + inline NodeBoxConnected &getConnected() { + if (!connected) + connected = std::make_shared(); + return *connected; + } + inline const NodeBoxConnected &getConnected() const { + assert(connected); + return *connected; + } void reset(); void serialize(std::ostream &os, u16 protocol_version) const; @@ -158,7 +181,6 @@ class TextureSettings { int node_texture_size; bool opaque_water; bool connected_glass; - bool use_normal_texture; bool enable_mesh_cache; bool enable_minimap; @@ -191,10 +213,10 @@ enum NodeDrawType // paramtype2 = "meshoptions" allows various forms, sizes and // vertical and horizontal random offsets. NDT_PLANTLIKE, - // Fenceposts that connect to neighbouring fenceposts with horizontal bars + // Fenceposts that connect to neighboring fenceposts with horizontal bars NDT_FENCELIKE, // Selects appropriate junction texture to connect like rails to - // neighbouring raillikes. + // neighboring raillikes. NDT_RAILLIKE, // Custom Lua-definable structure of multiple cuboids NDT_NODEBOX, @@ -203,7 +225,7 @@ enum NodeDrawType // Uses 3 textures, one for frames, second for faces, // optional third is a 'special tile' for the liquid. NDT_GLASSLIKE_FRAMED, - // Draw faces slightly rotated and only on neighbouring nodes + // Draw faces slightly rotated and only on neighboring nodes NDT_FIRELIKE, // Enabled -> ndt_glasslike_framed, disabled -> ndt_glasslike NDT_GLASSLIKE_FRAMED_OPTIONAL, @@ -232,6 +254,14 @@ enum AlignStyle : u8 { ALIGN_STYLE_USER_DEFINED, }; +enum AlphaMode : u8 { + ALPHAMODE_BLEND, + ALPHAMODE_CLIP, + ALPHAMODE_OPAQUE, + ALPHAMODE_LEGACY_COMPAT, /* means either opaque or clip */ +}; + + /* Stand-alone definition of a TileSpec (basically a server-side TileSpec) */ @@ -257,14 +287,22 @@ struct TileDef } void serialize(std::ostream &os, u16 protocol_version) const; - void deSerialize(std::istream &is, u8 contentfeatures_version, - NodeDrawType drawtype); + void deSerialize(std::istream &is, NodeDrawType drawtype, u16 protocol_version); }; +// Defines the number of special tiles per nodedef +// +// NOTE: When changing this value, the enum entries of OverrideTarget and +// parser in TextureOverrideSource must be updated so that all special +// tiles can be overridden. #define CF_SPECIAL_COUNT 6 struct ContentFeatures { + // PROTOCOL_VERSION >= 37. This is legacy and should not be increased anymore, + // write checks that depend directly on the protocol version instead. + static const u8 CONTENTFEATURES_VERSION = 13; + /* Cached stuff */ @@ -273,7 +311,6 @@ struct ContentFeatures // up down right left back front TileSpec tiles[6]; // Special tiles - // - Currently used for flowing liquids TileSpec special_tiles[CF_SPECIAL_COUNT]; u8 solidness; // Used when choosing which face is drawn u8 visual_solidness; // When solidness=0, this tells how it looks like @@ -285,6 +322,9 @@ struct ContentFeatures bool has_on_destruct; bool has_after_destruct; + // "float" group + bool floats; + /* Actual data */ @@ -311,9 +351,7 @@ struct ContentFeatures // These will be drawn over the base tiles. TileDef tiledef_overlay[6]; TileDef tiledef_special[CF_SPECIAL_COUNT]; // eg. flowing liquid - // If 255, the node is opaque. - // Otherwise it uses texture alpha. - u8 alpha; + AlphaMode alpha; // The color of the node. video::SColor color; std::string palette_name; @@ -361,11 +399,15 @@ struct ContentFeatures u32 damage_per_second; // client dig prediction std::string node_dig_prediction; + // how slow players move through + u8 move_resistance = 0; // --- LIQUID PROPERTIES --- // Whether the node is non-liquid, source liquid or flowing liquid enum LiquidType liquid_type; + // If true, movement (e.g. of players) inside this node is liquid-like. + bool liquid_move_physics; // If the content is liquid, this is the flowing version of the liquid. std::string liquid_alternative_flowing; content_t liquid_alternative_flowing_id; @@ -412,25 +454,67 @@ struct ContentFeatures ~ContentFeatures(); void reset(); void serialize(std::ostream &os, u16 protocol_version) const; - void deSerialize(std::istream &is); - /*! - * Since vertex alpha is no longer supported, this method - * adds opacity directly to the texture pixels. - * - * \param tiles array of the tile definitions. - * \param length length of tiles - */ - void correctAlpha(TileDef *tiles, int length); + void deSerialize(std::istream &is, u16 protocol_version); /* Some handy methods */ + void setDefaultAlphaMode() + { + switch (drawtype) { + case NDT_NORMAL: + case NDT_LIQUID: + case NDT_FLOWINGLIQUID: + alpha = ALPHAMODE_OPAQUE; + break; + case NDT_NODEBOX: + case NDT_MESH: + alpha = ALPHAMODE_LEGACY_COMPAT; // this should eventually be OPAQUE + break; + default: + alpha = ALPHAMODE_CLIP; + break; + } + } + + bool needsBackfaceCulling() const + { + switch (drawtype) { + case NDT_TORCHLIKE: + case NDT_SIGNLIKE: + case NDT_FIRELIKE: + case NDT_RAILLIKE: + case NDT_PLANTLIKE: + case NDT_PLANTLIKE_ROOTED: + case NDT_MESH: + return false; + default: + return true; + } + } + bool isLiquid() const{ return (liquid_type != LIQUID_NONE); } - bool sameLiquid(const ContentFeatures &f) const{ - if(!isLiquid() || !f.isLiquid()) return false; - return (liquid_alternative_flowing_id == f.liquid_alternative_flowing_id); + + bool isLiquidRender() const { + return (drawtype == NDT_LIQUID || drawtype == NDT_FLOWINGLIQUID); + } + + bool sameLiquidRender(const ContentFeatures &f) const { + if (!isLiquidRender() || !f.isLiquidRender()) + return false; + return liquid_alternative_flowing_id == f.liquid_alternative_flowing_id && + liquid_alternative_source_id == f.liquid_alternative_source_id; + } + + ContentLightingFlags getLightingFlags() const { + ContentLightingFlags flags; + flags.has_light = param_type == CPT_LIGHT; + flags.light_propagates = light_propagates; + flags.sunlight_propagates = sunlight_propagates; + flags.light_source = light_source; + return flags; } int getGroup(const std::string &group) const @@ -442,6 +526,21 @@ struct ContentFeatures void updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc, scene::IMeshManipulator *meshmanip, Client *client, const TextureSettings &tsettings); #endif + +private: +#ifndef SERVER + /* + * Checks if any tile texture has any transparent pixels. + * Prints a warning and returns true if that is the case, false otherwise. + * This is supposed to be used for use_texture_alpha backwards compatibility. + */ + bool textureAlphaCheck(ITextureSource *tsrc, const TileDef *tiles, + int length); +#endif + + void setAlphaFromLegacy(u8 legacy_alpha); + + u8 getAlphaForLegacy() const; }; /*! @@ -473,7 +572,7 @@ class NodeDefManager { */ inline const ContentFeatures& get(content_t c) const { return - c < m_content_features.size() ? + (c < m_content_features.size() && !m_content_features[c].name.empty()) ? m_content_features[c] : m_content_features[CONTENT_UNKNOWN]; } @@ -487,6 +586,15 @@ class NodeDefManager { return get(n.getContent()); } + inline ContentLightingFlags getLightingFlags(content_t c) const { + // No bound check is necessary, since the array's length is CONTENT_MAX + 1. + return m_content_lighting_flag_cache[c]; + } + + inline ContentLightingFlags getLightingFlags(const MapNode &n) const { + return getLightingFlags(n.getContent()); + } + /*! * Returns the node properties for a node name. * @param name name of a node @@ -604,13 +712,11 @@ class NodeDefManager { * total ContentFeatures. * @param progress_cbk_args passed to the callback function */ - void updateTextures(IGameDef *gamedef, - void (*progress_cbk)(void *progress_args, u32 progress, u32 max_progress), - void *progress_cbk_args); + void updateTextures(IGameDef *gamedef, void *progress_cbk_args); /*! * Writes the content of this manager to the given output stream. - * @param protocol_version serialization version of ContentFeatures + * @param protocol_version Active network protocol version */ void serialize(std::ostream &os, u16 protocol_version) const; @@ -618,8 +724,9 @@ class NodeDefManager { * Restores the manager from a serialized stream. * This clears the previous state. * @param is input stream containing a serialized NodeDefManager + * @param protocol_version Active network protocol version */ - void deSerialize(std::istream &is); + void deSerialize(std::istream &is, u16 protocol_version); /*! * Used to indicate that node registration has finished. @@ -669,7 +776,7 @@ class NodeDefManager { * @param i a content ID * @param name a node name */ - void addNameIdMapping(content_t i, std::string name); + void addNameIdMapping(content_t i, const std::string &name); /*! * Removes a content ID from all groups. @@ -734,14 +841,22 @@ class NodeDefManager { * Even constant NodeDefManager instances can register listeners. */ mutable std::vector m_pending_resolve_callbacks; + + /*! + * Fast cache of content lighting flags. + */ + ContentLightingFlags m_content_lighting_flag_cache[CONTENT_MAX + 1L]; }; NodeDefManager *createNodeDefManager(); +// NodeResolver: Queue for node names which are then translated +// to content_t after the NodeDefManager was initialized class NodeResolver { public: NodeResolver(); virtual ~NodeResolver(); + // Callback which is run as soon NodeDefManager is ready virtual void resolveNodeNames() = 0; // required because this class is used as mixin for ObjDef @@ -753,12 +868,31 @@ class NodeResolver { bool getIdsFromNrBacklog(std::vector *result_out, bool all_required = false, content_t c_fallback = CONTENT_IGNORE); - void nodeResolveInternal(); + inline bool isResolveDone() const { return m_resolve_done; } + void reset(bool resolve_done = false); - u32 m_nodenames_idx = 0; - u32 m_nnlistsizes_idx = 0; + // Vector containing all node names in the resolve "queue" std::vector m_nodenames; + // Specifies the "set size" of node names which are to be processed + // this is used for getIdsFromNrBacklog + // TODO: replace or remove std::vector m_nnlistsizes; + +protected: + friend class NodeDefManager; // m_ndef + const NodeDefManager *m_ndef = nullptr; + // Index of the next "m_nodenames" entry to resolve + u32 m_nodenames_idx = 0; + +private: +#if BUILD_UNITTESTS + // Unittest requires access to m_resolve_done + friend class TestSchematic; +#endif + void nodeResolveInternal(); + + // Index of the next "m_nnlistsizes" entry to process + u32 m_nnlistsizes_idx = 0; bool m_resolve_done = false; };