aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/texture_overrides.txt35
-rw-r--r--src/client.cpp3
-rw-r--r--src/nodedef.cpp65
-rw-r--r--src/nodedef.h6
-rw-r--r--src/server.cpp7
5 files changed, 111 insertions, 5 deletions
diff --git a/doc/texture_overrides.txt b/doc/texture_overrides.txt
new file mode 100644
index 000000000..559591184
--- /dev/null
+++ b/doc/texture_overrides.txt
@@ -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'. |
diff --git a/src/client.cpp b/src/client.cpp
index 780b07872..1d0245c45 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -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;
diff --git a/src/nodedef.cpp b/src/nodedef.cpp
index ac432d196..6c2e96c4f 100644
--- a/src/nodedef.cpp
+++ b/src/nodedef.cpp
@@ -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;
}
}
}
diff --git a/src/nodedef.h b/src/nodedef.h
index 68f6c8c37..3a5e5228d 100644
--- a/src/nodedef.h
+++ b/src/nodedef.h
@@ -336,6 +336,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.
*/
virtual void updateTextures(IGameDef *gamedef,
@@ -378,4 +383,3 @@ public:
};
#endif
-
diff --git a/src/server.cpp b/src/server.cpp
index 22b7d38f2..2a34c8675 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -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)
}
}
}
-
-