From 86b44ecd8280d8304aa26a600fc004d40a970020 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Wed, 20 Oct 2021 19:50:16 +0000 Subject: [PATCH] Add no_texture.png as fallback for unspecified textures --- doc/texture_packs.txt | 3 ++- games/devtest/mods/broken/init.lua | 11 +++++++++++ games/devtest/mods/broken/mod.conf | 2 ++ src/client/content_cao.cpp | 10 +++++----- src/client/game.cpp | 5 ++--- src/client/hud.cpp | 25 ++++++++++++++++++------- src/client/wieldmesh.cpp | 11 ++++++++--- src/nodedef.cpp | 17 ++++++++++++++--- src/object_properties.cpp | 2 +- src/server/luaentity_sao.cpp | 5 +++++ textures/base/pack/no_texture.png | Bin 0 -> 281 bytes 11 files changed, 68 insertions(+), 23 deletions(-) create mode 100644 games/devtest/mods/broken/init.lua create mode 100644 games/devtest/mods/broken/mod.conf create mode 100644 textures/base/pack/no_texture.png diff --git a/doc/texture_packs.txt b/doc/texture_packs.txt index 8af2cbad6..f738032b6 100644 --- a/doc/texture_packs.txt +++ b/doc/texture_packs.txt @@ -90,9 +90,10 @@ by texture packs. All existing fallback textures can be found in the directory * `minimap_mask_square.png`: mask used for the square minimap * `minimap_overlay_round.png`: overlay texture for the round minimap * `minimap_overlay_square.png`: overlay texture for the square minimap -* `no_texture_airlike.png`: fallback inventory image for airlike nodes * `object_marker_red.png`: texture for players on the minimap * `player_marker.png`: texture for the own player on the square minimap +* `no_texture_airlike.png`: fallback inventory image for airlike nodes +* `no_texture.png`: fallback image for unspecified textures * `player.png`: front texture of the 2D upright sprite player * `player_back.png`: back texture of the 2D upright sprite player diff --git a/games/devtest/mods/broken/init.lua b/games/devtest/mods/broken/init.lua new file mode 100644 index 000000000..04993ca16 --- /dev/null +++ b/games/devtest/mods/broken/init.lua @@ -0,0 +1,11 @@ +-- Register stuff with empty definitions to test if Minetest fallback options +-- for these things work properly. + +-- The itemstrings are deliberately kept descriptive to keep them easy to +-- recognize. + +minetest.register_node("broken:node_with_empty_definition", {}) +minetest.register_tool("broken:tool_with_empty_definition", {}) +minetest.register_craftitem("broken:craftitem_with_empty_definition", {}) + +minetest.register_entity("broken:entity_with_empty_definition", {}) diff --git a/games/devtest/mods/broken/mod.conf b/games/devtest/mods/broken/mod.conf new file mode 100644 index 000000000..a24378a34 --- /dev/null +++ b/games/devtest/mods/broken/mod.conf @@ -0,0 +1,2 @@ +name = broken +description = Register items and an entity with empty definitions to test fallback diff --git a/src/client/content_cao.cpp b/src/client/content_cao.cpp index da78cae7c..1e79d00c9 100644 --- a/src/client/content_cao.cpp +++ b/src/client/content_cao.cpp @@ -647,7 +647,7 @@ void GenericCAO::addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr) m_matrixnode, v2f(1, 1), v3f(0,0,0), -1); m_spritenode->grab(); m_spritenode->setMaterialTexture(0, - tsrc->getTextureForMesh("unknown_node.png")); + tsrc->getTextureForMesh("no_texture.png")); setSceneNodeMaterial(m_spritenode); @@ -1288,7 +1288,7 @@ void GenericCAO::updateTextures(std::string mod) if (m_spritenode) { if (m_prop.visual == "sprite") { - std::string texturestring = "unknown_node.png"; + std::string texturestring = "no_texture.png"; if (!m_prop.textures.empty()) texturestring = m_prop.textures[0]; texturestring += mod; @@ -1367,7 +1367,7 @@ void GenericCAO::updateTextures(std::string mod) { for (u32 i = 0; i < 6; ++i) { - std::string texturestring = "unknown_node.png"; + std::string texturestring = "no_texture.png"; if(m_prop.textures.size() > i) texturestring = m_prop.textures[i]; texturestring += mod; @@ -1400,7 +1400,7 @@ void GenericCAO::updateTextures(std::string mod) } else if (m_prop.visual == "upright_sprite") { scene::IMesh *mesh = m_meshnode->getMesh(); { - std::string tname = "unknown_object.png"; + std::string tname = "no_texture.png"; if (!m_prop.textures.empty()) tname = m_prop.textures[0]; tname += mod; @@ -1422,7 +1422,7 @@ void GenericCAO::updateTextures(std::string mod) buf->getMaterial().setFlag(video::EMF_ANISOTROPIC_FILTER, use_anisotropic_filter); } { - std::string tname = "unknown_object.png"; + std::string tname = "no_texture.png"; if (m_prop.textures.size() >= 2) tname = m_prop.textures[1]; else if (!m_prop.textures.empty()) diff --git a/src/client/game.cpp b/src/client/game.cpp index a6448f40d..57951dc95 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -3331,9 +3331,8 @@ void Game::handlePointingAtNode(const PointedThing &pointed, } else { MapNode n = map.getNode(nodepos); - if (nodedef_manager->get(n).tiledef[0].name == "unknown_node.png") { - m_game_ui->setInfoText(L"Unknown node: " + - utf8_to_wide(nodedef_manager->get(n).name)); + if (nodedef_manager->get(n).name == "unknown") { + m_game_ui->setInfoText(L"Unknown node"); } } diff --git a/src/client/hud.cpp b/src/client/hud.cpp index 0620759da..e08d2ef02 100644 --- a/src/client/hud.cpp +++ b/src/client/hud.cpp @@ -1007,11 +1007,15 @@ void drawItemStack( bool draw_overlay = false; + bool has_mesh = false; + ItemMesh *imesh; + // Render as mesh if animated or no inventory image if ((enable_animations && rotation_kind < IT_ROT_NONE) || def.inventory_image.empty()) { - ItemMesh *imesh = client->idef()->getWieldMesh(def.name, client); - if (!imesh || !imesh->mesh) - return; + imesh = client->idef()->getWieldMesh(def.name, client); + has_mesh = imesh && imesh->mesh; + } + if (has_mesh) { scene::IMesh *mesh = imesh->mesh; driver->clearBuffers(video::ECBF_DEPTH); s32 delta = 0; @@ -1103,10 +1107,17 @@ void drawItemStack( draw_overlay = def.type == ITEM_NODE && def.inventory_image.empty(); } else { // Otherwise just draw as 2D video::ITexture *texture = client->idef()->getInventoryTexture(def.name, client); - if (!texture) - return; - video::SColor color = - client->idef()->getItemstackColor(item, client); + video::SColor color; + if (texture) { + color = client->idef()->getItemstackColor(item, client); + } else { + color = video::SColor(255, 255, 255, 255); + ITextureSource *tsrc = client->getTextureSource(); + texture = tsrc->getTexture("no_texture.png"); + if (!texture) + return; + } + const video::SColor colors[] = { color, color, color, color }; draw2DImageFilterScaled(driver, texture, rect, diff --git a/src/client/wieldmesh.cpp b/src/client/wieldmesh.cpp index 6beed3f3a..0a4cb3b86 100644 --- a/src/client/wieldmesh.cpp +++ b/src/client/wieldmesh.cpp @@ -458,9 +458,14 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client, bool che material.setFlag(video::EMF_TRILINEAR_FILTER, m_trilinear_filter); } return; - } else if (!def.inventory_image.empty()) { - setExtruded(def.inventory_image, def.inventory_overlay, def.wield_scale, - tsrc, 1); + } else { + if (!def.inventory_image.empty()) { + setExtruded(def.inventory_image, def.inventory_overlay, def.wield_scale, + tsrc, 1); + } else { + setExtruded("no_texture.png", "", def.wield_scale, tsrc, 1); + } + m_colors.emplace_back(); // overlay is white, if present m_colors.emplace_back(true, video::SColor(0xFFFFFFFF)); diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 703df4dee..f0e0024be 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -796,8 +796,10 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc TileDef tdef[6]; for (u32 j = 0; j < 6; j++) { tdef[j] = tiledef[j]; - if (tdef[j].name.empty()) - tdef[j].name = "unknown_node.png"; + if (tdef[j].name.empty()) { + tdef[j].name = "no_texture.png"; + tdef[j].backface_culling = false; + } } // also the overlay tiles TileDef tdef_overlay[6]; @@ -805,8 +807,13 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc tdef_overlay[j] = tiledef_overlay[j]; // also the special tiles TileDef tdef_spec[6]; - for (u32 j = 0; j < CF_SPECIAL_COUNT; j++) + for (u32 j = 0; j < CF_SPECIAL_COUNT; j++) { tdef_spec[j] = tiledef_special[j]; + if (tdef_spec[j].name.empty()) { + tdef_spec[j].name = "no_texture.png"; + tdef_spec[j].backface_culling = false; + } + } bool is_liquid = false; @@ -1052,6 +1059,10 @@ void NodeDefManager::clear() { ContentFeatures f; f.name = "unknown"; + TileDef unknownTile; + unknownTile.name = "unknown_node.png"; + for (int t = 0; t < 6; t++) + f.tiledef[t] = unknownTile; // Insert directly into containers content_t c = CONTENT_UNKNOWN; m_content_features[c] = f; diff --git a/src/object_properties.cpp b/src/object_properties.cpp index db06f8930..c7f6becf0 100644 --- a/src/object_properties.cpp +++ b/src/object_properties.cpp @@ -28,7 +28,7 @@ static const video::SColor NULL_BGCOLOR{0, 1, 1, 1}; ObjectProperties::ObjectProperties() { - textures.emplace_back("unknown_object.png"); + textures.emplace_back("no_texture.png"); colors.emplace_back(255,255,255,255); } diff --git a/src/server/luaentity_sao.cpp b/src/server/luaentity_sao.cpp index 3bcbe107b..1d65ac306 100644 --- a/src/server/luaentity_sao.cpp +++ b/src/server/luaentity_sao.cpp @@ -108,7 +108,12 @@ void LuaEntitySAO::addedToEnvironment(u32 dtime_s) m_env->getScriptIface()-> luaentity_Activate(m_id, m_init_state, dtime_s); } else { + // It's an unknown object + // Use entitystring as infotext for debugging m_prop.infotext = m_init_name; + // Set unknown object texture + m_prop.textures.clear(); + m_prop.textures.emplace_back("unknown_object.png"); } } diff --git a/textures/base/pack/no_texture.png b/textures/base/pack/no_texture.png new file mode 100644 index 0000000000000000000000000000000000000000..681b810820fc21ad7269147beddbcc419e0daf46 GIT binary patch literal 281 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Y)RhkE|14;~Xv*;X`O+`b-bgbfeS0-coAET; zzMw#_XBo^<>rPjOEPQ$^sBogkzcU6u?)~UwTRY9FVFs&Y!9};@TKl%1i0%Dcl5HCH zcit7X*7WK3{D1DAq%B$@@bmQ!wQr?6Ue;|gc)Z}Q37`1snQw3YY}aL#+#JF)i|rn} XXw|Dr-?)>3E@tp_^>bP0l+XkK)@y7& literal 0 HcmV?d00001