From 93ecc589bc49a80187705f6e06df23a71263d3d7 Mon Sep 17 00:00:00 2001 From: Hugues Ross Date: Tue, 4 Aug 2020 14:12:47 -0400 Subject: [PATCH] Implement override.txt support for special tiles (#10140) Add override targets for all special_tiles entries in node definitions, allowing texture packs to replace these textures. This makes overrides work properly with a variety of drawtypes. The targets are named special1 through special6, covering the the current length of the special_tiles array. --- doc/texture_packs.txt | 18 +++++++++++++++++- src/nodedef.cpp | 21 +++++++++++++++++++++ src/nodedef.h | 5 +++++ src/texture_override.cpp | 38 ++++++++++++++++++++++++++------------ src/texture_override.h | 18 +++++++++++++++--- util/ci/lint.sh | 0 6 files changed, 84 insertions(+), 16 deletions(-) mode change 100644 => 100755 util/ci/lint.sh diff --git a/doc/texture_packs.txt b/doc/texture_packs.txt index 79d65a339..8af2cbad6 100644 --- a/doc/texture_packs.txt +++ b/doc/texture_packs.txt @@ -195,11 +195,27 @@ Here are targets you can choose from: | bottom | y- face | | sides | x-, x+, z-, z+ faces | | all | All faces. You can also use '*' instead of 'all'. | +| special1 | The first entry in the special_tiles list | +| special2 | The second entry in the special_tiles list | +| special3 | The third entry in the special_tiles list | +| special4 | The fourth entry in the special_tiles list | +| special5 | The fifth entry in the special_tiles list | +| special6 | The sixth entry in the special_tiles list | | inventory | The inventory texture | | wield | The texture used when held by the player | Nodes support all targets, but other items only support 'inventory' -and 'wield' +and 'wield'. + +### Using the special targets + +The special* targets only apply to specific drawtypes: + +* `flowingliquid`: special1 sets the top texture, special2 sets the side texture +* `allfaces_optional`: special1 is used by simple mode, see below +* `glasslike_framed`: When containing a liquid, special1 sets the liquid texture +* `glasslike_framed_optional`: Same as `glasslike_framed` +* `plantlike_rooted`: special1 sets the plant's texture Designing leaves textures for the leaves rendering options ---------------------------------------------------------- diff --git a/src/nodedef.cpp b/src/nodedef.cpp index e5cd2c2a7..82c4581fa 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -1337,6 +1337,7 @@ void NodeDefManager::applyTextureOverrides(const std::vector &o ContentFeatures &nodedef = m_content_features[id]; + // Override tiles if (texture_override.hasTarget(OverrideTarget::TOP)) nodedef.tiledef[0].name = texture_override.texture; @@ -1354,6 +1355,26 @@ void NodeDefManager::applyTextureOverrides(const std::vector &o if (texture_override.hasTarget(OverrideTarget::FRONT)) nodedef.tiledef[5].name = texture_override.texture; + + + // Override special tiles, if applicable + if (texture_override.hasTarget(OverrideTarget::SPECIAL_1)) + nodedef.tiledef_special[0].name = texture_override.texture; + + if (texture_override.hasTarget(OverrideTarget::SPECIAL_2)) + nodedef.tiledef_special[1].name = texture_override.texture; + + if (texture_override.hasTarget(OverrideTarget::SPECIAL_3)) + nodedef.tiledef_special[2].name = texture_override.texture; + + if (texture_override.hasTarget(OverrideTarget::SPECIAL_4)) + nodedef.tiledef_special[3].name = texture_override.texture; + + if (texture_override.hasTarget(OverrideTarget::SPECIAL_5)) + nodedef.tiledef_special[4].name = texture_override.texture; + + if (texture_override.hasTarget(OverrideTarget::SPECIAL_6)) + nodedef.tiledef_special[5].name = texture_override.texture; } } diff --git a/src/nodedef.h b/src/nodedef.h index ff52f976f..d0da367ee 100644 --- a/src/nodedef.h +++ b/src/nodedef.h @@ -261,6 +261,11 @@ struct TileDef NodeDrawType drawtype); }; +// 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 diff --git a/src/texture_override.cpp b/src/texture_override.cpp index 10d129b87..effdb0efd 100644 --- a/src/texture_override.cpp +++ b/src/texture_override.cpp @@ -24,6 +24,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include +#define override_cast static_cast + TextureOverrideSource::TextureOverrideSource(std::string filepath) { std::ifstream infile(filepath.c_str()); @@ -56,25 +58,37 @@ TextureOverrideSource::TextureOverrideSource(std::string filepath) std::vector targets = str_split(splitted[1], ','); for (const std::string &target : targets) { if (target == "top") - texture_override.target |= static_cast(OverrideTarget::TOP); + texture_override.target |= override_cast(OverrideTarget::TOP); else if (target == "bottom") - texture_override.target |= static_cast(OverrideTarget::BOTTOM); + texture_override.target |= override_cast(OverrideTarget::BOTTOM); else if (target == "left") - texture_override.target |= static_cast(OverrideTarget::LEFT); + texture_override.target |= override_cast(OverrideTarget::LEFT); else if (target == "right") - texture_override.target |= static_cast(OverrideTarget::RIGHT); + texture_override.target |= override_cast(OverrideTarget::RIGHT); else if (target == "front") - texture_override.target |= static_cast(OverrideTarget::FRONT); + texture_override.target |= override_cast(OverrideTarget::FRONT); else if (target == "back") - texture_override.target |= static_cast(OverrideTarget::BACK); + texture_override.target |= override_cast(OverrideTarget::BACK); else if (target == "inventory") - texture_override.target |= static_cast(OverrideTarget::INVENTORY); + texture_override.target |= override_cast(OverrideTarget::INVENTORY); else if (target == "wield") - texture_override.target |= static_cast(OverrideTarget::WIELD); + texture_override.target |= override_cast(OverrideTarget::WIELD); + else if (target == "special1") + texture_override.target |= override_cast(OverrideTarget::SPECIAL_1); + else if (target == "special2") + texture_override.target |= override_cast(OverrideTarget::SPECIAL_2); + else if (target == "special3") + texture_override.target |= override_cast(OverrideTarget::SPECIAL_3); + else if (target == "special4") + texture_override.target |= override_cast(OverrideTarget::SPECIAL_4); + else if (target == "special5") + texture_override.target |= override_cast(OverrideTarget::SPECIAL_5); + else if (target == "special6") + texture_override.target |= override_cast(OverrideTarget::SPECIAL_6); else if (target == "sides") - texture_override.target |= static_cast(OverrideTarget::SIDES); + texture_override.target |= override_cast(OverrideTarget::SIDES); else if (target == "all" || target == "*") - texture_override.target |= static_cast(OverrideTarget::ALL_FACES); + texture_override.target |= override_cast(OverrideTarget::ALL_FACES); else { // Report invalid target warningstream << filepath << ":" << line_index @@ -85,7 +99,7 @@ TextureOverrideSource::TextureOverrideSource(std::string filepath) } // If there are no valid targets, skip adding this override - if (texture_override.target == static_cast(OverrideTarget::INVALID)) { + if (texture_override.target == override_cast(OverrideTarget::INVALID)) { continue; } @@ -112,7 +126,7 @@ std::vector TextureOverrideSource::getNodeTileOverrides() std::vector found_overrides; for (const TextureOverride &texture_override : m_overrides) { - if (texture_override.hasTarget(OverrideTarget::ALL_FACES)) + if (texture_override.hasTarget(OverrideTarget::NODE_TARGETS)) found_overrides.push_back(texture_override); } diff --git a/src/texture_override.h b/src/texture_override.h index db03bd014..bdc95e732 100644 --- a/src/texture_override.h +++ b/src/texture_override.h @@ -23,8 +23,10 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include +typedef u16 override_t; + //! Bitmask enum specifying what a texture override should apply to -enum class OverrideTarget : u8 +enum class OverrideTarget : override_t { INVALID = 0, TOP = 1 << 0, @@ -35,23 +37,33 @@ enum class OverrideTarget : u8 BACK = 1 << 5, INVENTORY = 1 << 6, WIELD = 1 << 7, + SPECIAL_1 = 1 << 8, + SPECIAL_2 = 1 << 9, + SPECIAL_3 = 1 << 10, + SPECIAL_4 = 1 << 11, + SPECIAL_5 = 1 << 12, + SPECIAL_6 = 1 << 13, + // clang-format off SIDES = LEFT | RIGHT | FRONT | BACK, ALL_FACES = TOP | BOTTOM | SIDES, + ALL_SPECIAL = SPECIAL_1 | SPECIAL_2 | SPECIAL_3 | SPECIAL_4 | SPECIAL_5 | SPECIAL_6, + NODE_TARGETS = ALL_FACES | ALL_SPECIAL, ITEM_TARGETS = INVENTORY | WIELD, + // clang-format on }; struct TextureOverride { std::string id; std::string texture; - u8 target; + override_t target; // Helper function for checking if an OverrideTarget is found in // a TextureOverride without casting inline bool hasTarget(OverrideTarget overrideTarget) const { - return (target & static_cast(overrideTarget)) != 0; + return (target & static_cast(overrideTarget)) != 0; } }; diff --git a/util/ci/lint.sh b/util/ci/lint.sh old mode 100644 new mode 100755