Add texture overriding

This commit is contained in:
rubenwardy 2015-03-30 11:55:29 +01:00 committed by est31
parent 43702ec6ac
commit 603297cc35
5 changed files with 111 additions and 5 deletions

35
doc/texture_overrides.txt Normal 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'. |

@ -1741,6 +1741,9 @@ void Client::afterContentReceived(IrrlichtDevice *device)
text = wgettext("Initializing nodes...");
draw_load_screen(text, device, guienv, 0, 72);
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->runNodeResolveCallbacks();
delete[] text;

@ -33,6 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "exceptions.h"
#include "debug.h"
#include "gamedef.h"
#include <fstream> // Used in applyTextureOverrides()
/*
NodeBox
@ -397,6 +398,7 @@ public:
virtual content_t set(const std::string &name, const ContentFeatures &def);
virtual content_t allocateDummy(const std::string &name);
virtual void updateAliases(IItemDefManager *idef);
virtual void applyTextureOverrides(const std::string &override_filepath);
virtual void updateTextures(IGameDef *gamedef,
void (*progress_cbk)(void *progress_args, u32 progress, u32 max_progress),
void *progress_cbk_args);
@ -670,7 +672,7 @@ content_t CNodeDefManager::set(const std::string &name, const ContentFeatures &d
j = m_group_to_items.find(group_name);
if (j == m_group_to_items.end()) {
m_group_to_items[group_name].push_back(
std::make_pair(id, i->second));
std::make_pair(id, i->second));
} else {
GroupItems &items = j->second;
items.push_back(std::make_pair(id, i->second));
@ -700,7 +702,66 @@ void CNodeDefManager::updateAliases(IItemDefManager *idef)
content_t id;
if (m_name_id_mapping.getId(convert_to, id)) {
m_name_id_mapping_with_aliases.insert(
std::make_pair(name, id));
std::make_pair(name, id));
}
}
}
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;
}
}
}

@ -335,6 +335,11 @@ public:
*/
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.
*/
@ -378,4 +383,3 @@ public:
};
#endif

@ -335,6 +335,11 @@ Server::Server(
// Apply item aliases in the node definition manager
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);
// Perform pending node name resolutions
@ -3397,5 +3402,3 @@ void dedicated_server_loop(Server &server, bool &kill)
}
}
}