mirror of
https://github.com/minetest/minetest.git
synced 2024-12-23 14:42:24 +01:00
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.
This commit is contained in:
parent
d22fd6fc34
commit
93ecc589bc
@ -195,11 +195,27 @@ Here are targets you can choose from:
|
|||||||
| bottom | y- face |
|
| bottom | y- face |
|
||||||
| sides | x-, x+, z-, z+ faces |
|
| sides | x-, x+, z-, z+ faces |
|
||||||
| all | All faces. You can also use '*' instead of 'all'. |
|
| 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 |
|
| inventory | The inventory texture |
|
||||||
| wield | The texture used when held by the player |
|
| wield | The texture used when held by the player |
|
||||||
|
|
||||||
Nodes support all targets, but other items only support 'inventory'
|
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
|
Designing leaves textures for the leaves rendering options
|
||||||
----------------------------------------------------------
|
----------------------------------------------------------
|
||||||
|
@ -1337,6 +1337,7 @@ void NodeDefManager::applyTextureOverrides(const std::vector<TextureOverride> &o
|
|||||||
|
|
||||||
ContentFeatures &nodedef = m_content_features[id];
|
ContentFeatures &nodedef = m_content_features[id];
|
||||||
|
|
||||||
|
// Override tiles
|
||||||
if (texture_override.hasTarget(OverrideTarget::TOP))
|
if (texture_override.hasTarget(OverrideTarget::TOP))
|
||||||
nodedef.tiledef[0].name = texture_override.texture;
|
nodedef.tiledef[0].name = texture_override.texture;
|
||||||
|
|
||||||
@ -1354,6 +1355,26 @@ void NodeDefManager::applyTextureOverrides(const std::vector<TextureOverride> &o
|
|||||||
|
|
||||||
if (texture_override.hasTarget(OverrideTarget::FRONT))
|
if (texture_override.hasTarget(OverrideTarget::FRONT))
|
||||||
nodedef.tiledef[5].name = texture_override.texture;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,6 +261,11 @@ struct TileDef
|
|||||||
NodeDrawType drawtype);
|
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
|
#define CF_SPECIAL_COUNT 6
|
||||||
|
|
||||||
struct ContentFeatures
|
struct ContentFeatures
|
||||||
|
@ -24,6 +24,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
#define override_cast static_cast<override_t>
|
||||||
|
|
||||||
TextureOverrideSource::TextureOverrideSource(std::string filepath)
|
TextureOverrideSource::TextureOverrideSource(std::string filepath)
|
||||||
{
|
{
|
||||||
std::ifstream infile(filepath.c_str());
|
std::ifstream infile(filepath.c_str());
|
||||||
@ -56,25 +58,37 @@ TextureOverrideSource::TextureOverrideSource(std::string filepath)
|
|||||||
std::vector<std::string> targets = str_split(splitted[1], ',');
|
std::vector<std::string> targets = str_split(splitted[1], ',');
|
||||||
for (const std::string &target : targets) {
|
for (const std::string &target : targets) {
|
||||||
if (target == "top")
|
if (target == "top")
|
||||||
texture_override.target |= static_cast<u8>(OverrideTarget::TOP);
|
texture_override.target |= override_cast(OverrideTarget::TOP);
|
||||||
else if (target == "bottom")
|
else if (target == "bottom")
|
||||||
texture_override.target |= static_cast<u8>(OverrideTarget::BOTTOM);
|
texture_override.target |= override_cast(OverrideTarget::BOTTOM);
|
||||||
else if (target == "left")
|
else if (target == "left")
|
||||||
texture_override.target |= static_cast<u8>(OverrideTarget::LEFT);
|
texture_override.target |= override_cast(OverrideTarget::LEFT);
|
||||||
else if (target == "right")
|
else if (target == "right")
|
||||||
texture_override.target |= static_cast<u8>(OverrideTarget::RIGHT);
|
texture_override.target |= override_cast(OverrideTarget::RIGHT);
|
||||||
else if (target == "front")
|
else if (target == "front")
|
||||||
texture_override.target |= static_cast<u8>(OverrideTarget::FRONT);
|
texture_override.target |= override_cast(OverrideTarget::FRONT);
|
||||||
else if (target == "back")
|
else if (target == "back")
|
||||||
texture_override.target |= static_cast<u8>(OverrideTarget::BACK);
|
texture_override.target |= override_cast(OverrideTarget::BACK);
|
||||||
else if (target == "inventory")
|
else if (target == "inventory")
|
||||||
texture_override.target |= static_cast<u8>(OverrideTarget::INVENTORY);
|
texture_override.target |= override_cast(OverrideTarget::INVENTORY);
|
||||||
else if (target == "wield")
|
else if (target == "wield")
|
||||||
texture_override.target |= static_cast<u8>(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")
|
else if (target == "sides")
|
||||||
texture_override.target |= static_cast<u8>(OverrideTarget::SIDES);
|
texture_override.target |= override_cast(OverrideTarget::SIDES);
|
||||||
else if (target == "all" || target == "*")
|
else if (target == "all" || target == "*")
|
||||||
texture_override.target |= static_cast<u8>(OverrideTarget::ALL_FACES);
|
texture_override.target |= override_cast(OverrideTarget::ALL_FACES);
|
||||||
else {
|
else {
|
||||||
// Report invalid target
|
// Report invalid target
|
||||||
warningstream << filepath << ":" << line_index
|
warningstream << filepath << ":" << line_index
|
||||||
@ -85,7 +99,7 @@ TextureOverrideSource::TextureOverrideSource(std::string filepath)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If there are no valid targets, skip adding this override
|
// If there are no valid targets, skip adding this override
|
||||||
if (texture_override.target == static_cast<u8>(OverrideTarget::INVALID)) {
|
if (texture_override.target == override_cast(OverrideTarget::INVALID)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,7 +126,7 @@ std::vector<TextureOverride> TextureOverrideSource::getNodeTileOverrides()
|
|||||||
std::vector<TextureOverride> found_overrides;
|
std::vector<TextureOverride> found_overrides;
|
||||||
|
|
||||||
for (const TextureOverride &texture_override : m_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);
|
found_overrides.push_back(texture_override);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,8 +23,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
typedef u16 override_t;
|
||||||
|
|
||||||
//! Bitmask enum specifying what a texture override should apply to
|
//! Bitmask enum specifying what a texture override should apply to
|
||||||
enum class OverrideTarget : u8
|
enum class OverrideTarget : override_t
|
||||||
{
|
{
|
||||||
INVALID = 0,
|
INVALID = 0,
|
||||||
TOP = 1 << 0,
|
TOP = 1 << 0,
|
||||||
@ -35,23 +37,33 @@ enum class OverrideTarget : u8
|
|||||||
BACK = 1 << 5,
|
BACK = 1 << 5,
|
||||||
INVENTORY = 1 << 6,
|
INVENTORY = 1 << 6,
|
||||||
WIELD = 1 << 7,
|
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,
|
SIDES = LEFT | RIGHT | FRONT | BACK,
|
||||||
ALL_FACES = TOP | BOTTOM | SIDES,
|
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,
|
ITEM_TARGETS = INVENTORY | WIELD,
|
||||||
|
// clang-format on
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TextureOverride
|
struct TextureOverride
|
||||||
{
|
{
|
||||||
std::string id;
|
std::string id;
|
||||||
std::string texture;
|
std::string texture;
|
||||||
u8 target;
|
override_t target;
|
||||||
|
|
||||||
// Helper function for checking if an OverrideTarget is found in
|
// Helper function for checking if an OverrideTarget is found in
|
||||||
// a TextureOverride without casting
|
// a TextureOverride without casting
|
||||||
inline bool hasTarget(OverrideTarget overrideTarget) const
|
inline bool hasTarget(OverrideTarget overrideTarget) const
|
||||||
{
|
{
|
||||||
return (target & static_cast<u8>(overrideTarget)) != 0;
|
return (target & static_cast<override_t>(overrideTarget)) != 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
0
util/ci/lint.sh
Normal file → Executable file
0
util/ci/lint.sh
Normal file → Executable file
Loading…
Reference in New Issue
Block a user