From 023a1c2427fa34d5a87e7234c0c322d56765082b Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Sat, 13 Aug 2022 08:52:16 +0200 Subject: [PATCH] Textures: introduce world-align overrides (#12540) Many games do not care about world align textures, however texture packs should have the capabilities to change that if they have suitable textures. This commmit now introduces a node property override for world-align in particular to force a certain scale on the selected override tiles. --- doc/texture_packs.txt | 3 ++ src/nodedef.cpp | 32 +++++++++------ src/texture_override.cpp | 85 ++++++++++++++++++++++------------------ src/texture_override.h | 3 +- 4 files changed, 71 insertions(+), 52 deletions(-) diff --git a/doc/texture_packs.txt b/doc/texture_packs.txt index f738032b6..2e92e56f2 100644 --- a/doc/texture_packs.txt +++ b/doc/texture_packs.txt @@ -204,10 +204,13 @@ Here are targets you can choose from: | special6 | The sixth entry in the special_tiles list | | inventory | The inventory texture | | wield | The texture used when held by the player | +| align_world=N | Overrides the "world align" behaviour of tiles ¹ | Nodes support all targets, but other items only support 'inventory' and 'wield'. +¹ : `N` is an integer [0,255]. Sets align_style = "world" and scale = N on the tile, refer to lua_api.txt for details. + ### Using the special targets The special* targets only apply to specific drawtypes: diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 4022ac835..733dbf07a 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -1445,44 +1445,52 @@ void NodeDefManager::applyTextureOverrides(const std::vector &o ContentFeatures &nodedef = m_content_features[id]; + auto apply = [&] (TileDef &tile) { + tile.name = texture_override.texture; + if (texture_override.world_scale > 0) { + tile.align_style = ALIGN_STYLE_WORLD; + tile.scale = texture_override.world_scale; + } + }; + // Override tiles if (texture_override.hasTarget(OverrideTarget::TOP)) - nodedef.tiledef[0].name = texture_override.texture; + apply(nodedef.tiledef[0]); if (texture_override.hasTarget(OverrideTarget::BOTTOM)) - nodedef.tiledef[1].name = texture_override.texture; + apply(nodedef.tiledef[1]); if (texture_override.hasTarget(OverrideTarget::RIGHT)) - nodedef.tiledef[2].name = texture_override.texture; + apply(nodedef.tiledef[2]); if (texture_override.hasTarget(OverrideTarget::LEFT)) - nodedef.tiledef[3].name = texture_override.texture; + apply(nodedef.tiledef[3]); if (texture_override.hasTarget(OverrideTarget::BACK)) - nodedef.tiledef[4].name = texture_override.texture; + apply(nodedef.tiledef[4]); if (texture_override.hasTarget(OverrideTarget::FRONT)) - nodedef.tiledef[5].name = texture_override.texture; + apply(nodedef.tiledef[5]); // Override special tiles, if applicable if (texture_override.hasTarget(OverrideTarget::SPECIAL_1)) - nodedef.tiledef_special[0].name = texture_override.texture; + apply(nodedef.tiledef_special[0]); if (texture_override.hasTarget(OverrideTarget::SPECIAL_2)) - nodedef.tiledef_special[1].name = texture_override.texture; + apply(nodedef.tiledef_special[1]); if (texture_override.hasTarget(OverrideTarget::SPECIAL_3)) - nodedef.tiledef_special[2].name = texture_override.texture; + apply(nodedef.tiledef_special[2]); if (texture_override.hasTarget(OverrideTarget::SPECIAL_4)) - nodedef.tiledef_special[3].name = texture_override.texture; + apply(nodedef.tiledef_special[3]); if (texture_override.hasTarget(OverrideTarget::SPECIAL_5)) - nodedef.tiledef_special[4].name = texture_override.texture; + apply(nodedef.tiledef_special[4]); if (texture_override.hasTarget(OverrideTarget::SPECIAL_6)) - nodedef.tiledef_special[5].name = texture_override.texture; + apply(nodedef.tiledef_special[5]); } } diff --git a/src/texture_override.cpp b/src/texture_override.cpp index effdb0efd..81c986ccf 100644 --- a/src/texture_override.cpp +++ b/src/texture_override.cpp @@ -26,6 +26,26 @@ with this program; if not, write to the Free Software Foundation, Inc., #define override_cast static_cast +static const std::map override_LUT = { + { "top", OverrideTarget::TOP }, + { "bottom", OverrideTarget::BOTTOM }, + { "left", OverrideTarget::LEFT }, + { "right", OverrideTarget::RIGHT }, + { "front", OverrideTarget::FRONT }, + { "back", OverrideTarget::BACK }, + { "inventory", OverrideTarget::INVENTORY }, + { "wield", OverrideTarget::WIELD }, + { "special1", OverrideTarget::SPECIAL_1 }, + { "special2", OverrideTarget::SPECIAL_2 }, + { "special3", OverrideTarget::SPECIAL_3 }, + { "special4", OverrideTarget::SPECIAL_4 }, + { "special5", OverrideTarget::SPECIAL_5 }, + { "special6", OverrideTarget::SPECIAL_6 }, + { "sides", OverrideTarget::SIDES }, + { "all", OverrideTarget::ALL_FACES }, + { "*", OverrideTarget::ALL_FACES } +}; + TextureOverrideSource::TextureOverrideSource(std::string filepath) { std::ifstream infile(filepath.c_str()); @@ -41,8 +61,9 @@ TextureOverrideSource::TextureOverrideSource(std::string filepath) if (line.empty() || line[0] == '#') continue; + // Format: mod_name:item_name target1[,...] texture_name.png std::vector splitted = str_split(line, ' '); - if (splitted.size() != 3) { + if (splitted.size() < 3) { warningstream << filepath << ":" << line_index << " Syntax error in texture override \"" << line << "\": Expected 3 arguments, got " << splitted.size() @@ -57,45 +78,31 @@ TextureOverrideSource::TextureOverrideSource(std::string filepath) // Parse the target mask std::vector targets = str_split(splitted[1], ','); for (const std::string &target : targets) { - if (target == "top") - texture_override.target |= override_cast(OverrideTarget::TOP); - else if (target == "bottom") - texture_override.target |= override_cast(OverrideTarget::BOTTOM); - else if (target == "left") - texture_override.target |= override_cast(OverrideTarget::LEFT); - else if (target == "right") - texture_override.target |= override_cast(OverrideTarget::RIGHT); - else if (target == "front") - texture_override.target |= override_cast(OverrideTarget::FRONT); - else if (target == "back") - texture_override.target |= override_cast(OverrideTarget::BACK); - else if (target == "inventory") - texture_override.target |= override_cast(OverrideTarget::INVENTORY); - else if (target == "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 |= override_cast(OverrideTarget::SIDES); - else if (target == "all" || target == "*") - texture_override.target |= override_cast(OverrideTarget::ALL_FACES); - else { - // Report invalid target - warningstream << filepath << ":" << line_index - << " Syntax error in texture override \"" << line - << "\": Unknown target \"" << target << "\"" - << std::endl; + std::vector kvpair = str_split(target, '='); + if (kvpair.size() == 2) { + // Key-value pairs + if (kvpair[0] == "align_world") { + // Global textures + texture_override.world_scale = stoi(kvpair[1], 0, U8_MAX); + continue; + } } + if (kvpair.size() == 1) { + // Regular override flags + auto pair = override_LUT.find(target); + + if (pair != override_LUT.end()) { + texture_override.target |= override_cast(pair->second); + continue; + } + } + + // Report invalid target + warningstream << filepath << ":" << line_index + << " Syntax error in texture override \"" << line + << "\": Unknown target \"" << target << "\"" + << std::endl; + } // If there are no valid targets, skip adding this override diff --git a/src/texture_override.h b/src/texture_override.h index bdc95e732..4c09fa540 100644 --- a/src/texture_override.h +++ b/src/texture_override.h @@ -57,7 +57,8 @@ struct TextureOverride { std::string id; std::string texture; - override_t target; + override_t target = 0; + u8 world_scale = 0; // Helper function for checking if an OverrideTarget is found in // a TextureOverride without casting