From 87f69c7e501baaab3cc675a63d7701789737285b Mon Sep 17 00:00:00 2001
From: rei-2 <174158077+rei-2@users.noreply.github.com>
Date: Sun, 5 Oct 2025 18:12:23 -0400
Subject: [PATCH] changes to world material override
---
Amalgam/Amalgam.vcxproj | 1 +
Amalgam/Amalgam.vcxproj.filters | 1 +
Amalgam/src/Features/Visuals/Visuals.cpp | 42 +++++++++++--------
.../src/Hooks/IMaterialSystem_FindTexture.cpp | 29 +++++++++++++
Amalgam/src/SDK/Vars.h | 2 +-
5 files changed, 57 insertions(+), 18 deletions(-)
create mode 100644 Amalgam/src/Hooks/IMaterialSystem_FindTexture.cpp
diff --git a/Amalgam/Amalgam.vcxproj b/Amalgam/Amalgam.vcxproj
index 005fcdc2..3586c1f2 100644
--- a/Amalgam/Amalgam.vcxproj
+++ b/Amalgam/Amalgam.vcxproj
@@ -1043,6 +1043,7 @@
+
diff --git a/Amalgam/Amalgam.vcxproj.filters b/Amalgam/Amalgam.vcxproj.filters
index 3e70f97b..e3508866 100644
--- a/Amalgam/Amalgam.vcxproj.filters
+++ b/Amalgam/Amalgam.vcxproj.filters
@@ -198,6 +198,7 @@
+
diff --git a/Amalgam/src/Features/Visuals/Visuals.cpp b/Amalgam/src/Features/Visuals/Visuals.cpp
index 59a0e01d..afb721e3 100644
--- a/Amalgam/src/Features/Visuals/Visuals.cpp
+++ b/Amalgam/src/Features/Visuals/Visuals.cpp
@@ -859,8 +859,12 @@ void CVisuals::Store(CTFPlayer* pLocal)
void CVisuals::OverrideWorldTextures()
{
auto uHash = FNV1A::Hash32(Vars::Visuals::World::WorldTexture.Value.c_str());
- if (uHash == FNV1A::Hash32Const("Default"))
+ switch (uHash)
+ {
+ case FNV1A::Hash32Const("Default"):
+ case FNV1A::Hash32Const("Flat"):
return;
+ }
KeyValues* kv = new KeyValues("LightmappedGeneric");
if (!kv)
@@ -880,7 +884,7 @@ void CVisuals::OverrideWorldTextures()
case FNV1A::Hash32Const("White"):
kv->SetString("$basetexture", "patterns/combat/white");
break;
- case FNV1A::Hash32Const("Flat"):
+ case FNV1A::Hash32Const("Gray"):
kv->SetString("$basetexture", "vgui/white_additive");
kv->SetString("$color2", "[0.12 0.12 0.15]");
break;
@@ -891,22 +895,15 @@ void CVisuals::OverrideWorldTextures()
for (auto h = I::MaterialSystem->FirstMaterial(); h != I::MaterialSystem->InvalidMaterial(); h = I::MaterialSystem->NextMaterial(h))
{
auto pMaterial = I::MaterialSystem->GetMaterial(h);
- if (!pMaterial || pMaterial->IsErrorMaterial() || !pMaterial->IsPrecached() || pMaterial->IsTranslucent() || pMaterial->IsSpriteCard())
+ if (!pMaterial || pMaterial->IsErrorMaterial() || !pMaterial->IsPrecached() || pMaterial->IsTranslucent() || pMaterial->IsAlphaTested() || pMaterial->IsSpriteCard())
continue;
- std::string_view sGroup = pMaterial->GetTextureGroupName();
std::string_view sName = pMaterial->GetName();
-
- if (!sGroup._Starts_with("World")
- || sName.find("water") != std::string_view::npos || sName.find("glass") != std::string_view::npos
- || sName.find("door") != std::string_view::npos || sName.find("tools") != std::string_view::npos
- || sName.find("player") != std::string_view::npos || sName.find("chicken") != std::string_view::npos
- || sName.find("wall28") != std::string_view::npos || sName.find("wall26") != std::string_view::npos
- || sName.find("decal") != std::string_view::npos || sName.find("overlay") != std::string_view::npos
- || sName.find("hay") != std::string_view::npos)
- {
+ std::string_view sGroup = pMaterial->GetTextureGroupName();
+ if (!sGroup.starts_with(TEXTURE_GROUP_WORLD)
+ || sName.find("sky") != std::string_view::npos
+ || sName.find("water") != std::string_view::npos)
continue;
- }
pMaterial->SetShaderAndParams(kv);
}
@@ -920,9 +917,20 @@ static inline void ApplyModulation(Color_t tColor, bool bSky = false)
if (!pMaterial || pMaterial->IsErrorMaterial() || !pMaterial->IsPrecached())
continue;
- auto sGroup = std::string_view(pMaterial->GetTextureGroupName());
- if (!bSky ? !sGroup._Starts_with("World") : !sGroup._Starts_with("SkyBox"))
- continue;
+ std::string_view sName = pMaterial->GetName();
+ std::string_view sGroup = pMaterial->GetTextureGroupName();
+ if (!bSky)
+ {
+ if (!sGroup.starts_with(TEXTURE_GROUP_WORLD)
+ || sName.find("sky") != std::string_view::npos)
+ continue;
+ }
+ else
+ {
+ if (!sGroup.starts_with(TEXTURE_GROUP_SKYBOX)
+ && sName.find("sky") == std::string_view::npos)
+ continue;
+ }
pMaterial->ColorModulate(tColor.r / 255.f, tColor.g / 255.f, tColor.b / 255.f);
}
diff --git a/Amalgam/src/Hooks/IMaterialSystem_FindTexture.cpp b/Amalgam/src/Hooks/IMaterialSystem_FindTexture.cpp
new file mode 100644
index 00000000..3bb68c0a
--- /dev/null
+++ b/Amalgam/src/Hooks/IMaterialSystem_FindTexture.cpp
@@ -0,0 +1,29 @@
+#include "../SDK/SDK.h"
+
+MAKE_HOOK(IMaterialSystem_FindTexture, U::Memory.GetVirtual(I::MaterialSystem, 79), ITexture*,
+ void* rcx, char const* pTextureName, const char* pTextureGroupName, bool complain, int nAdditionalCreationFlags)
+{
+ auto pReturn = CALL_ORIGINAL(rcx, pTextureName, pTextureGroupName, complain, nAdditionalCreationFlags);
+
+ auto uHash = FNV1A::Hash32(Vars::Visuals::World::WorldTexture.Value.c_str());
+ if (uHash == FNV1A::Hash32Const("Flat"))
+ {
+ auto overrideTexture = [&]()
+ {
+ if (!pReturn || pReturn->IsTranslucent() || !pTextureName || !pTextureGroupName)
+ return;
+
+ std::string_view sName = pTextureName;
+ std::string_view sGroup = pTextureGroupName;
+ if (!sGroup.starts_with(TEXTURE_GROUP_WORLD))
+ return;
+
+ Vec3 vColor; pReturn->GetLowResColorSample(0.5f, 0.5f, &vColor.x);
+ Color_t tColor = { byte(vColor.x * 255), byte(vColor.y * 255), byte(vColor.z * 255), 255 };
+ pReturn = I::MaterialSystem->CreateTextureFromBits(1, 1, 1, IMAGE_FORMAT_RGBA8888, 4, &tColor.r);
+ };
+ overrideTexture();
+ }
+
+ return pReturn;
+}
diff --git a/Amalgam/src/SDK/Vars.h b/Amalgam/src/SDK/Vars.h
index 48caa50e..f6e4e5a7 100644
--- a/Amalgam/src/SDK/Vars.h
+++ b/Amalgam/src/SDK/Vars.h
@@ -600,7 +600,7 @@ namespace Vars
CVarValues(SkyboxChanger, "Skybox changer", std::string("Off"), VISUAL | DROPDOWN_CUSTOM, nullptr,
VA_LIST("Off"));
CVarValues(WorldTexture, "World texture", std::string("Default"), VISUAL | DROPDOWN_CUSTOM, nullptr,
- "Default", "Dev", "Camo", "Black", "White", "Flat");
+ "Default", "Dev", "Camo", "Black", "White", "Gray", "Flat");
CVar(NearPropFade, "Near prop fade", false, VISUAL);
CVar(NoPropFade, "No prop fade", false, VISUAL);
SUBNAMESPACE_END(World);