2025-07-17 13:52:06 +03:00

281 lines
12 KiB
C++

#include <algorithm>
#include <iostream>
#include "chams.h"
#include "../../hooks/hooks.h"
#include "../../config/config.h"
#include "../../../../external/imgui/imgui.h"
#include "../../utils/math/utlstronghandle/utlstronghandle.h"
#include "../../../cs2/entity/C_Material/C_Material.h"
#include "../../interfaces/interfaces.h"
#include "../../interfaces/CGameEntitySystem/CGameEntitySystem.h"
#include "../../../cs2/datatypes/keyvalues/keyvalues.h"
#include "../../../cs2/datatypes/cutlbuffer/cutlbuffer.h"
CStrongHandle<CMaterial2> chams::create(const char* name, const char szVmatBuffer[])
{
CKeyValues3* pKeyValues3 = nullptr;
pKeyValues3 = pKeyValues3->create_material_from_resource();
pKeyValues3->LoadFromBuffer(szVmatBuffer);
CStrongHandle<CMaterial2> pCustomMaterial = {};
I::CreateMaterial(nullptr, &pCustomMaterial, name, pKeyValues3, 0, 1);
return pCustomMaterial;
}
struct resource_material_t
{
CStrongHandle<CMaterial2> mat;
CStrongHandle<CMaterial2> mat_invs;
};
static resource_material_t resourceMaterials[ChamsType::MAXCOUNT];
bool loaded_materials = false;
bool chams::Materials::init()
{
// flat
resourceMaterials[FLAT] = resource_material_t{
.mat = create("materials/dev/flat.vmat", R"(<!-- kv3 encoding:text:version{e21c7f3c-8a33-41c5-9977-a76d3a32aa0d} format:generic:version{7412167c-06e9-4698-aff2-e63eb59037e7} -->
{
Shader = "csgo_unlitgeneric.vfx"
F_IGNOREZ = 0
F_DISABLE_Z_WRITE = 0
F_DISABLE_Z_BUFFERING = 0
F_BLEND_MODE = 1
F_TRANSLUCENT = 1
F_RENDER_BACKFACES = 0
g_vColorTint = [1.000000, 1.000000, 1.000000, 1.000000]
g_vGlossinessRange = [0.000000, 1.000000, 0.000000, 0.000000]
g_vNormalTexCoordScale = [1.000000, 1.000000, 0.000000, 0.000000]
g_vTexCoordOffset = [0.000000, 0.000000, 0.000000, 0.000000]
g_vTexCoordScale = [1.000000, 1.000000, 0.000000, 0.000000]
g_tColor = resource:"materials/dev/primary_white_color_tga_f7b257f6.vtex"
g_tNormal = resource:"materials/default/default_normal_tga_7652cb.vtex"
})"),
.mat_invs = create("materials/dev/flat_i.vmat", R"(<!-- kv3 encoding:text:version{e21c7f3c-8a33-41c5-9977-a76d3a32aa0d} format:generic:version{7412167c-06e9-4698-aff2-e63eb59037e7} -->
{
Shader = "csgo_unlitgeneric.vfx"
F_IGNOREZ = 1
F_DISABLE_Z_WRITE = 1
F_DISABLE_Z_BUFFERING = 1
F_BLEND_MODE = 1
F_TRANSLUCENT = 1
g_vColorTint = [1.000000, 1.000000, 1.000000, 0.000000]
g_vGlossinessRange = [0.000000, 1.000000, 0.000000, 0.000000]
g_vNormalTexCoordScale = [1.000000, 1.000000, 0.000000, 0.000000]
g_vTexCoordOffset = [0.000000, 0.000000, 0.000000, 0.000000]
g_vTexCoordScale = [1.000000, 1.000000, 0.000000, 0.000000]
g_tColor = resource:"materials/dev/primary_white_color_tga_f7b257f6.vtex"
g_tNormal = resource:"materials/default/default_normal_tga_7652cb.vtex"
})")
};
resourceMaterials[ILLUMINATE] = resource_material_t{
.mat = create("materials/dev/primary_white.vmat", R"(<!-- kv3 encoding:text:version{e21c7f3c-8a33-41c5-9977-a76d3a32aa0d} format:generic:version{7412167c-06e9-4698-aff2-e63eb59037e7} -->
{
shader = "csgo_complex.vfx"
F_SELF_ILLUM = 1
F_PAINT_VERTEX_COLORS = 1
F_TRANSLUCENT = 1
g_vColorTint = [ 1.000000, 1.000000, 1.000000, 1.000000 ]
g_flSelfIllumScale = [ 3.000000, 3.000000, 3.000000, 3.000000 ]
g_flSelfIllumBrightness = [ 3.000000, 3.000000, 3.000000, 3.000000 ]
g_vSelfIllumTint = [ 10.000000, 10.000000, 10.000000, 10.000000 ]
g_tColor = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tNormal = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tSelfIllumMask = resource:"materials/default/default_mask_tga_fde710a5.vtex"
TextureAmbientOcclusion = resource:"materials/debug/particleerror.vtex"
g_tAmbientOcclusion = resource:"materials/debug/particleerror.vtex"
})"),
.mat_invs = create("materials/dev/primary_white.vmat", R"(<!-- kv3 encoding:text:version{e21c7f3c-8a33-41c5-9977-a76d3a32aa0d} format:generic:version{7412167c-06e9-4698-aff2-e63eb59037e7} -->
{
shader = "csgo_complex.vfx"
F_SELF_ILLUM = 1
F_PAINT_VERTEX_COLORS = 1
F_TRANSLUCENT = 1
F_DISABLE_Z_BUFFERING = 1
g_vColorTint = [ 1.000000, 1.000000, 1.000000, 1.000000 ]
g_flSelfIllumScale = [ 3.000000, 3.000000, 3.000000, 3.000000 ]
g_flSelfIllumBrightness = [ 3.000000, 3.000000, 3.000000, 3.000000 ]
g_vSelfIllumTint = [ 10.000000, 10.000000, 10.000000, 10.000000 ]
g_tColor = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tNormal = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tSelfIllumMask = resource:"materials/default/default_mask_tga_fde710a5.vtex"
TextureAmbientOcclusion = resource:"materials/debug/particleerror.vtex"
g_tAmbientOcclusion = resource:"materials/debug/particleerror.vtex"
})")
};
resourceMaterials[GLOW] = resource_material_t{
.mat = create("materials/dev/primary_white.vmat", R"(<!-- kv3 encoding:text:version{e21c7f3c-8a33-41c5-9977-a76d3a32aa0d} format:generic:version{7412167c-06e9-4698-aff2-e63eb59037e7} -->
{
shader = "csgo_effects.vfx"
g_flFresnelExponent = 7.0
g_flFresnelFalloff = 10.0
g_flFresnelMax = 0.1
g_flFresnelMin = 1.0
g_tColor = resource:"materials/dev/primary_white_color_tga_21186c76.vtex"
g_tMask1 = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tMask2 = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tMask3 = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tSceneDepth = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_flToolsVisCubemapReflectionRoughness = 1.0
g_flBeginMixingRoughness = 1.0
g_vColorTint = [ 1.000000, 1.000000, 1.000000, 0 ]
F_IGNOREZ = 0
F_TRANSLUCENT = 1
F_DISABLE_Z_WRITE = 0
F_DISABLE_Z_BUFFERING = 1
F_RENDER_BACKFACES = 0
})"),
.mat_invs = create("materials/dev/primary_white.vmat", R"(<!-- kv3 encoding:text:version{e21c7f3c-8a33-41c5-9977-a76d3a32aa0d} format:generic:version{7412167c-06e9-4698-aff2-e63eb59037e7} -->
{
shader = "csgo_effects.vfx"
g_flFresnelExponent = 7.0
g_flFresnelFalloff = 10.0
g_flFresnelMax = 0.1
g_flFresnelMin = 1.0
g_tColor = resource:"materials/dev/primary_white_color_tga_21186c76.vtex"
g_tMask1 = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tMask2 = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tMask3 = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tSceneDepth = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_flToolsVisCubemapReflectionRoughness = 1.0
g_flBeginMixingRoughness = 1.0
g_vColorTint = [ 1.000000, 1.000000, 1.000000, 0 ]
F_IGNOREZ = 1
F_TRANSLUCENT = 1
F_DISABLE_Z_WRITE = 1
F_DISABLE_Z_BUFFERING = 1
F_RENDER_BACKFACES = 0
})")
};
return true;
}
ChamsEntity chams::GetTargetType(C_BaseEntity* render_ent) noexcept {
auto local = H::oGetLocalPlayer(0);
if (!local)
return ChamsEntity::INVALID;
if (render_ent->IsViewmodelAttachment())
return ChamsEntity::HANDS;
if (render_ent->IsViewmodel())
return ChamsEntity::VIEWMODEL;
if (!render_ent->IsBasePlayer() && !render_ent->IsPlayerController())
return ChamsEntity::INVALID;
auto player = (C_CSPlayerPawn*)render_ent;
if (!player)
return ChamsEntity::INVALID;
auto alive = player->m_iHealth() > 0;
if (!alive)
return ChamsEntity::INVALID;
if (player->m_iTeamNum() == local->m_iTeamNum())
return ChamsEntity::INVALID;
return ChamsEntity::ENEMY;
}
CMaterial2* GetMaterial(int type, bool invisible) { return invisible ? resourceMaterials[type].mat_invs : resourceMaterials[type].mat; }
void __fastcall chams::hook(void* a1, void* a2, CMeshData* pMeshScene, int nMeshCount, void* pSceneView, void* pSceneLayer, void* pUnk, void* pUnk2)
{
static auto original = H::DrawArray.GetOriginal();
if (!I::EngineClient->valid())
return original(a1, a2, pMeshScene, nMeshCount, pSceneView, pSceneLayer, pUnk, pUnk2);
auto local_player = H::oGetLocalPlayer(0);
if (!local_player)
return original(a1, a2, pMeshScene, nMeshCount, pSceneView, pSceneLayer, pUnk, pUnk2);
if (!pMeshScene)
return original(a1, a2, pMeshScene, nMeshCount, pSceneView, pSceneLayer, pUnk, pUnk2);
if (!pMeshScene->pSceneAnimatableObject)
return original(a1, a2, pMeshScene, nMeshCount, pSceneView, pSceneLayer, pUnk, pUnk2);
if (nMeshCount < 1)
return original(a1, a2, pMeshScene, nMeshCount, pSceneView, pSceneLayer, pUnk, pUnk2);
CMeshData* render_data = pMeshScene;
if (!render_data)
return original(a1, a2, pMeshScene, nMeshCount, pSceneView, pSceneLayer, pUnk, pUnk2);
if (!render_data->pSceneAnimatableObject)
return original(a1, a2, pMeshScene, nMeshCount, pSceneView, pSceneLayer, pUnk, pUnk2);
auto render_ent = render_data->pSceneAnimatableObject->Owner();
if (!render_ent.valid())
return original(a1, a2, pMeshScene, nMeshCount, pSceneView, pSceneLayer, pUnk, pUnk2);
auto entity = I::GameEntity->Instance->Get(render_ent);
if (!entity)
return original(a1, a2, pMeshScene, nMeshCount, pSceneView, pSceneLayer, pUnk, pUnk2);
const auto target = GetTargetType(entity);
if (target == ChamsEntity::VIEWMODEL && Config::viewmodelChams) {
pMeshScene->pMaterial = GetMaterial(Config::chamsMaterial, false);
pMeshScene->color.r = static_cast<uint8_t>(Config::colViewmodelChams.x * 255.0f);
pMeshScene->color.g = static_cast<uint8_t>(Config::colViewmodelChams.y * 255.0f);
pMeshScene->color.b = static_cast<uint8_t>(Config::colViewmodelChams.z * 255.0f);
pMeshScene->color.a = static_cast<uint8_t>(Config::colViewmodelChams.w * 255.0f);
return original(a1, a2, pMeshScene, nMeshCount, pSceneView, pSceneLayer, pUnk, pUnk2);
}
if (target == ChamsEntity::HANDS && Config::armChams) {
pMeshScene->pMaterial = GetMaterial(Config::chamsMaterial, false);
pMeshScene->color.r = static_cast<uint8_t>(Config::colArmChams.x * 255.0f);
pMeshScene->color.g = static_cast<uint8_t>(Config::colArmChams.y * 255.0f);
pMeshScene->color.b = static_cast<uint8_t>(Config::colArmChams.z * 255.0f);
pMeshScene->color.a = static_cast<uint8_t>(Config::colArmChams.w * 255.0f);
return original(a1, a2, pMeshScene, nMeshCount, pSceneView, pSceneLayer, pUnk, pUnk2);
}
if (target != ENEMY)
return original(a1, a2, pMeshScene, nMeshCount, pSceneView, pSceneLayer, pUnk, pUnk2);
bool og = !Config::enemyChams && !Config::enemyChamsInvisible;
if (og)
return original(a1, a2, pMeshScene, nMeshCount, pSceneView, pSceneLayer, pUnk, pUnk2);
if (Config::enemyChamsInvisible) {
pMeshScene->pMaterial = GetMaterial(Config::chamsMaterial, true);
pMeshScene->color.r = static_cast<uint8_t>(Config::colVisualChamsIgnoreZ.x * 255.0f);
pMeshScene->color.g = static_cast<uint8_t>(Config::colVisualChamsIgnoreZ.y * 255.0f);
pMeshScene->color.b = static_cast<uint8_t>(Config::colVisualChamsIgnoreZ.z * 255.0f);
pMeshScene->color.a = static_cast<uint8_t>(Config::colVisualChamsIgnoreZ.w * 255.0f);
original(a1, a2, pMeshScene, nMeshCount, pSceneView, pSceneLayer, pUnk, pUnk2);
}
if (Config::enemyChams) {
pMeshScene->pMaterial = GetMaterial(Config::chamsMaterial, false);
pMeshScene->color.r = static_cast<uint8_t>(Config::colVisualChams.x * 255.0f);
pMeshScene->color.g = static_cast<uint8_t>(Config::colVisualChams.y * 255.0f);
pMeshScene->color.b = static_cast<uint8_t>(Config::colVisualChams.z * 255.0f);
pMeshScene->color.a = static_cast<uint8_t>(Config::colVisualChams.w * 255.0f);
return original(a1, a2, pMeshScene, nMeshCount, pSceneView, pSceneLayer, pUnk, pUnk2);
}
// If we get here, neither chams type is enabled, so just render normally
return original(a1, a2, pMeshScene, nMeshCount, pSceneView, pSceneLayer, pUnk, pUnk2);
}