Add texture overriding

This commit is contained in:
rubenwardy 2015-03-30 11:55:29 +01:00 committed by OttoLidenbrock
parent a6835f98cf
commit eb4e791ea9
5 changed files with 111 additions and 5 deletions

35
doc/texture_overrides.txt Normal file
View File

@ -0,0 +1,35 @@
Texture Overrides
=================
You can override the textures of a node from a texture pack using
texture overrides. To do this, create a file in a texture pack
called override.txt
Basic Format
------------
Each line in an override.txt file is a rule. It consists of
nodename face-selector texture
For example,
default:dirt_with_grass sides default_stone.png
You can use ^ operators as usual:
default:dirt_with_grass sides default_stone.png^[brighten
Face Selectors
--------------
| face-selector | behavior |
|---------------|---------------------------------------------------|
| left | x- |
| right | x+ |
| front | z- |
| back | z+ |
| top | z+ |
| bottom | z- |
| sides | x-, x+, z-, z+ |
| all | All faces. You can also use '*' instead of 'all'. |

View File

@ -1741,6 +1741,9 @@ void Client::afterContentReceived(IrrlichtDevice *device)
text = wgettext("Initializing nodes..."); text = wgettext("Initializing nodes...");
draw_load_screen(text, device, guienv, 0, 72); draw_load_screen(text, device, guienv, 0, 72);
m_nodedef->updateAliases(m_itemdef); m_nodedef->updateAliases(m_itemdef);
std::string texture_path = g_settings->get("texture_path");
if (texture_path != "" && fs::IsDir(texture_path))
m_nodedef->applyTextureOverrides(texture_path + DIR_DELIM + "override.txt");
m_nodedef->setNodeRegistrationStatus(true); m_nodedef->setNodeRegistrationStatus(true);
m_nodedef->runNodeResolveCallbacks(); m_nodedef->runNodeResolveCallbacks();
delete[] text; delete[] text;

View File

@ -33,6 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "exceptions.h" #include "exceptions.h"
#include "debug.h" #include "debug.h"
#include "gamedef.h" #include "gamedef.h"
#include <fstream> // Used in applyTextureOverrides()
/* /*
NodeBox NodeBox
@ -397,6 +398,7 @@ public:
virtual content_t set(const std::string &name, const ContentFeatures &def); virtual content_t set(const std::string &name, const ContentFeatures &def);
virtual content_t allocateDummy(const std::string &name); virtual content_t allocateDummy(const std::string &name);
virtual void updateAliases(IItemDefManager *idef); virtual void updateAliases(IItemDefManager *idef);
virtual void applyTextureOverrides(const std::string &override_filepath);
virtual void updateTextures(IGameDef *gamedef, virtual void updateTextures(IGameDef *gamedef,
void (*progress_cbk)(void *progress_args, u32 progress, u32 max_progress), void (*progress_cbk)(void *progress_args, u32 progress, u32 max_progress),
void *progress_cbk_args); void *progress_cbk_args);
@ -705,6 +707,65 @@ void CNodeDefManager::updateAliases(IItemDefManager *idef)
} }
} }
void CNodeDefManager::applyTextureOverrides(const std::string &override_filepath)
{
infostream << "CNodeDefManager::applyTextureOverrides(): Applying "
"overrides to textures from " << override_filepath << std::endl;
std::ifstream infile(override_filepath.c_str());
std::string line;
int line_c = 0;
while (std::getline(infile, line)) {
line_c++;
if (trim(line) == "")
continue;
std::vector<std::string> splitted = str_split(line, ' ');
if (splitted.size() != 3) {
errorstream << override_filepath
<< ":" << line_c << " Could not apply texture override \""
<< line << "\": Syntax error" << std::endl;
continue;
}
content_t id;
if (!getId(splitted[0], id)) {
errorstream << override_filepath
<< ":" << line_c << " Could not apply texture override \""
<< line << "\": Unknown node \""
<< splitted[0] << "\"" << std::endl;
continue;
}
ContentFeatures &nodedef = m_content_features[id];
if (splitted[1] == "top")
nodedef.tiledef[0].name = splitted[2];
else if (splitted[1] == "bottom")
nodedef.tiledef[1].name = splitted[2];
else if (splitted[1] == "right")
nodedef.tiledef[2].name = splitted[2];
else if (splitted[1] == "left")
nodedef.tiledef[3].name = splitted[2];
else if (splitted[1] == "back")
nodedef.tiledef[4].name = splitted[2];
else if (splitted[1] == "front")
nodedef.tiledef[5].name = splitted[2];
else if (splitted[1] == "all" || splitted[1] == "*")
for (int i = 0; i < 6; i++)
nodedef.tiledef[i].name = splitted[2];
else if (splitted[1] == "sides")
for (int i = 2; i < 6; i++)
nodedef.tiledef[i].name = splitted[2];
else {
errorstream << override_filepath
<< ":" << line_c << " Could not apply texture override \""
<< line << "\": Unknown node side \""
<< splitted[1] << "\"" << std::endl;
continue;
}
}
}
void CNodeDefManager::updateTextures(IGameDef *gamedef, void CNodeDefManager::updateTextures(IGameDef *gamedef,
void (*progress_callback)(void *progress_args, u32 progress, u32 max_progress), void (*progress_callback)(void *progress_args, u32 progress, u32 max_progress),

View File

@ -335,6 +335,11 @@ public:
*/ */
virtual void updateAliases(IItemDefManager *idef)=0; virtual void updateAliases(IItemDefManager *idef)=0;
/*
Override textures from servers with ones specified in texturepack/override.txt
*/
virtual void applyTextureOverrides(const std::string &override_filepath)=0;
/* /*
Update tile textures to latest return values of TextueSource. Update tile textures to latest return values of TextueSource.
*/ */
@ -378,4 +383,3 @@ public:
}; };
#endif #endif

View File

@ -335,6 +335,11 @@ Server::Server(
// Apply item aliases in the node definition manager // Apply item aliases in the node definition manager
m_nodedef->updateAliases(m_itemdef); m_nodedef->updateAliases(m_itemdef);
// Apply texture overrides from texturepack/override.txt
std::string texture_path = g_settings->get("texture_path");
if (texture_path != "" && fs::IsDir(texture_path))
m_nodedef->applyTextureOverrides(texture_path + DIR_DELIM + "override.txt");
m_nodedef->setNodeRegistrationStatus(true); m_nodedef->setNodeRegistrationStatus(true);
// Perform pending node name resolutions // Perform pending node name resolutions
@ -3401,5 +3406,3 @@ void dedicated_server_loop(Server &server, bool &kill)
} }
} }
} }