From 49df428d95a7c443d418d5b7e2a93af599b54f76 Mon Sep 17 00:00:00 2001 From: salmonik Date: Wed, 4 Nov 2026 17:51:20 +0100 Subject: Add chams - Hook IVModelRender::DrawModelExecute (VEngineModel016 slot 19) and force models/debug/debugwhite for NPC models, identified by ModelRenderInfo_t::entity_index. - Two passes: MATERIAL_VAR_IGNOREZ through walls, then normal depth, with IMaterial::ColorModulate for the configured colour; restore the shared material's flag/colour afterwards. - Material lookup via the IMaterialSystem list, FindMaterial fallback. - New Chams feature/card with Through walls and colour; [chams] config. - Remove the temporary ammo/projectile/fuse diagnostics. --- src/world.cpp | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'src/world.cpp') diff --git a/src/world.cpp b/src/world.cpp index 2fa1fc4..ab0c134 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -999,3 +999,50 @@ void skybox_update() { g_sky_retry_at = now + 1.0; } } + +// Find a loaded material by its full name (e.g. "models/debug/debugwhite"). +// Used by chams; walks the material list like the tint code and falls back to +// FindMaterial if the material is not currently resident. +void *world_find_material(const char *name) { + if (!name || !*name) + return nullptr; + void *ms = material_system(); + if (!ms) + return nullptr; + using FirstFn = unsigned short (*)(void *); + using NextFn = unsigned short (*)(void *, unsigned short); + using InvalidFn = unsigned short (*)(void *); + using GetFn = void *(*)(void *, unsigned short); + using CountFn = int (*)(void *); + using NameFn = const char *(*)(void *); + FirstFn first = (FirstFn)vfunc(ms, 73); + NextFn next = (NextFn)vfunc(ms, 74); + InvalidFn invalid = (InvalidFn)vfunc(ms, 75); + GetFn get = (GetFn)vfunc(ms, 76); + CountFn count = (CountFn)vfunc(ms, 77); + int total = count ? count(ms) : 0; + if (total > 0 && total < 200000) { + unsigned short h = first(ms); + unsigned short inv = invalid(ms); + for (int i = 0; i < total && h != inv; i++) { + void *mat = get(ms, h); + if (mat) { + NameFn mat_name = (NameFn)vfunc(mat, 0); + const char *n = mat_name(mat); + if (n && strcmp(n, name) == 0) + return mat; + } + h = next(ms, h); + } + } + // Not resident yet: let the material system load it. FindMaterial is slot + // 71 (IsMaterialLoaded is 72, FirstMaterial 73). + using FindFn = void *(*)(void *, const char *, const char *, bool, + const char *); + void *mat = vfunc(ms, 71)(ms, name, "Model textures", false, nullptr); + if (!mat) + return nullptr; + NameFn mat_name = (NameFn)vfunc(mat, 0); + const char *n = mat_name(mat); + return (n && strcmp(n, name) == 0) ? mat : nullptr; +} -- cgit v1.2.3