#include "texture_override.h" // TextureOverride
#include "tileanimation.h"
-// PROTOCOL_VERSION >= 37
-static const u8 CONTENTFEATURES_VERSION = 13;
-
class IItemDefManager;
class ITextureSource;
class IShaderSource;
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,
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
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<aabb3f> fixed;
- // NODEBOX_WALLMOUNTED
- aabb3f wall_top;
- aabb3f wall_bottom;
- aabb3f wall_side; // being at the -X side
- // NODEBOX_CONNECTED
std::vector<aabb3f> connect_top;
std::vector<aabb3f> connect_bottom;
std::vector<aabb3f> connect_front;
std::vector<aabb3f> disconnected_right;
std::vector<aabb3f> disconnected;
std::vector<aabb3f> disconnected_sides;
+};
+
+struct NodeBox
+{
+ enum NodeBoxType type;
+ // NODEBOX_REGULAR (no parameters)
+ // NODEBOX_FIXED
+ std::vector<aabb3f> 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<NodeBoxConnected> connected;
NodeBox()
{ reset(); }
+ ~NodeBox() = default;
+
+ inline NodeBoxConnected &getConnected() {
+ if (!connected)
+ connected = std::make_shared<NodeBoxConnected>();
+ return *connected;
+ }
+ inline const NodeBoxConnected &getConnected() const {
+ assert(connected);
+ return *connected;
+ }
void reset();
void serialize(std::ostream &os, u16 protocol_version) const;
// 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,
// 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,
}
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
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
*/
// 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
bool has_on_destruct;
bool has_after_destruct;
+ // "float" group
+ bool floats;
+
/*
Actual data
*/
~ContentFeatures();
void reset();
void serialize(std::ostream &os, u16 protocol_version) const;
- void deSerialize(std::istream &is);
+ void deSerialize(std::istream &is, u16 protocol_version);
/*
Some handy methods
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
*/
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];
}
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
/*!
* 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;
* 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.
* Even constant NodeDefManager instances can register listeners.
*/
mutable std::vector<NodeResolver *> m_pending_resolve_callbacks;
+
+ /*!
+ * Fast cache of content lighting flags.
+ */
+ ContentLightingFlags m_content_lighting_flag_cache[CONTENT_MAX + 1L];
};
NodeDefManager *createNodeDefManager();