This commit is contained in:
Oscar
2025-07-25 22:49:56 +03:00
parent 03af6d458c
commit 860be9ac4c
470 changed files with 308020 additions and 436 deletions

View File

@@ -0,0 +1,500 @@
#include "chams.h"
// used: game's interfaces
#include "../../core/interfaces.h"
#include "../../sdk/interfaces/imaterialsystem.h"
#include "../../sdk/interfaces/igameresourceservice.h"
#include "../../sdk/interfaces/cgameentitysystem.h"
#include "../../core/sdk.h"
#include "../../sdk/entity.h"
#include "../cstrike/sdk/datatypes/resourceutils.h"
#include "../cstrike/sdk/datatypes/buf/utlbuffer.h"
#include <iostream>
// used: original call in hooked function
#include "../../core/hooks.h"
// used: cheat variables
#include"../cstrike/sdk/interfaces/imaterialsystem.h"
#include "../../core/variables.h"
#include <stdexcept>
inline bool(CS_FASTCALL* fnLoadBuffer)(CUtlBuffer*) = nullptr;
// custom material
struct custom_material_data_t {
material2_t* m_material;
material2_t* m_material_z;
};
// material list.
enum material_list_t {
material_white,
material_default,
material_illum,
material_size
};
// array
static custom_material_data_t array_materials[material_size]; // material max
material2_t* create_material_glow2_visible(const char* m_name) {
const char szVmatBuffer[] = R"#(<!-- kv3 encoding:text:version{e21c7f3c-8a33-41c5-9977-a76d3a32aa0d}
format:generic:version{7412167c-06e9-4698-aff2-e63eb59037e7} -->
{
shader = "solidcolor.vfx"
F_SELF_ILLUM = 1
F_PAINT_VERTEX_COLORS = 1
F_TRANSLUCENT = 1
F_IGNOREZ = 0
F_DISABLE_Z_WRITE = 0
F_DISABLE_Z_BUFFERING = 0
g_tColor = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tNormal = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tRoughness = resource:"materials/default/default_normal_tga_b3f4ec4c.vtex"
g_tMetalness = resource:"materials/default/default_normal_tga_b3f4ec4c.vtex"
g_tSelfIllumMask = resource:"materials/default/default_mask_tga_fde710a5.vtex"
TextureAmbientOcclusion = resource:"materials/debug/particleerror.vtex"
g_tAmbientOcclusion = resource:"materials/debug/particleerror.vtex"
g_vColorTint = [ 20.000000, 20.000000, 20.000000, 20.000000 ]
g_flSelfIllumScale = [ 5.000000, 5.000000, 5.000000, 5.000000 ]
g_flSelfIllumBrightness = [ 5.000000, 5.000000, 5.000000, 5.000000 ]
g_vSelfIllumTint = [ 10.000000, 10.000000, 10.000000, 10.000000 ]
} )#";
auto buffer = new unsigned char[0x100 + sizeof(CKeyValues3)];
CRT::MemorySet(buffer, 0, sizeof(buffer));
CKeyValues3* kv3 = (CKeyValues3*)(buffer + 0x100);
KV3IVD_t kv3ID;
kv3ID.szName = m_name;
kv3ID.unk0 = 0x469806E97412167C;
kv3ID.unk1 = 0xE73790B53EE6F2AF;
if (!MEM::load_key_value(kv3, nullptr, szVmatBuffer, &kv3ID, nullptr))
throw;
material2_t** custom_material;
MEM::fnCreateMaterial(nullptr, &custom_material, m_name, kv3, 0, 1);
return *custom_material;
}
material2_t* create_material_glow2_invisible(const char* m_name) {
const char szVmatBuffer[] = R"#(<!-- kv3 encoding:text:version{e21c7f3c-8a33-41c5-9977-a76d3a32aa0d}
format:generic:version{7412167c-06e9-4698-aff2-e63eb59037e7} -->
{
shader = "solidcolor.vfx"
F_SELF_ILLUM = 1
F_PAINT_VERTEX_COLORS = 1
F_TRANSLUCENT = 1
F_IGNOREZ = 1
F_DISABLE_Z_WRITE = 1
F_DISABLE_Z_BUFFERING = 1
g_tColor = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tNormal = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tRoughness = resource:"materials/default/default_normal_tga_b3f4ec4c.vtex"
g_tMetalness = resource:"materials/default/default_normal_tga_b3f4ec4c.vtex"
g_tSelfIllumMask = resource:"materials/default/default_mask_tga_fde710a5.vtex"
TextureAmbientOcclusion = resource:"materials/debug/particleerror.vtex"
g_tAmbientOcclusion = resource:"materials/debug/particleerror.vtex"
g_vColorTint = [ 20.000000, 20.000000, 20.000000, 20.000000 ]
g_flSelfIllumScale = [ 5.000000, 5.000000, 5.000000, 5.000000 ]
g_flSelfIllumBrightness = [ 5.000000, 5.000000, 5.000000, 5.000000 ]
g_vSelfIllumTint = [ 10.000000, 10.000000, 10.000000, 10.000000 ]
} )#";
auto buffer = new unsigned char[0x100 + sizeof(CKeyValues3)];
CRT::MemorySet(buffer, 0, sizeof(buffer));
CKeyValues3* kv3 = (CKeyValues3*)(buffer + 0x100);
KV3IVD_t kv3ID;
kv3ID.szName = m_name;
kv3ID.unk0 = 0x469806E97412167C;
kv3ID.unk1 = 0xE73790B53EE6F2AF;
if (!MEM::load_key_value(kv3, nullptr, szVmatBuffer, &kv3ID, nullptr))
throw;
material2_t** custom_material;
MEM::fnCreateMaterial(nullptr, &custom_material, m_name, kv3, 0, 1);
return *custom_material;
}
material2_t* create_material_default_visible(const char* m_name) {
const char szVmatBuffer[] = R"(<!-- kv3 encoding:text:version{e21c7f3c-8a33-41c5-9977-a76d3a32aa0d} format:generic:version{7412167c-06e9-4698-aff2-e63eb59037e7} -->
{
shader = "csgo_complex.vfx"
F_PAINT_VERTEX_COLORS = 1
F_TRANSLUCENT = 1
g_vColorTint = [1, 1, 1, 1]
TextureAmbientOcclusion = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tAmbientOcclusion = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tColor = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tNormal = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tTintMask = resource:"materials/default/default_mask_tga_fde710a5.vtex"
})";
auto buffer = new unsigned char[0x100 + sizeof(CKeyValues3)];
CRT::MemorySet(buffer, 0, sizeof(buffer));
CKeyValues3* kv3 = (CKeyValues3*)(buffer + 0x100);
KV3IVD_t kv3ID;
kv3ID.szName = m_name;
kv3ID.unk0 = 0x469806E97412167C;
kv3ID.unk1 = 0xE73790B53EE6F2AF;
if (!MEM::load_key_value(kv3, nullptr, szVmatBuffer, &kv3ID, nullptr))
throw;
material2_t** custom_material;
MEM::fnCreateMaterial(nullptr, &custom_material, m_name, kv3, 0, 1);
return *custom_material;
}
material2_t* create_material_default_invisible(const char* m_name) {
const char szVmatBuffer[] = R"(<!-- kv3 encoding:text:version{e21c7f3c-8a33-41c5-9977-a76d3a32aa0d} format:generic:version{7412167c-06e9-4698-aff2-e63eb59037e7} -->
{
shader = "csgo_complex.vfx"
F_PAINT_VERTEX_COLORS = 1
F_TRANSLUCENT = 1
F_DISABLE_Z_BUFFERING = 1
g_vColorTint = [1, 1, 1, 1]
TextureAmbientOcclusion = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tAmbientOcclusion = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tColor = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tNormal = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tTintMask = resource:"materials/default/default_mask_tga_fde710a5.vtex"
})";
auto buffer = new unsigned char[0x100 + sizeof(CKeyValues3)];
CRT::MemorySet(buffer, 0, sizeof(buffer));
CKeyValues3* kv3 = (CKeyValues3*)(buffer + 0x100);
KV3IVD_t kv3ID;
kv3ID.szName = m_name;
kv3ID.unk0 = 0x469806E97412167C;
kv3ID.unk1 = 0xE73790B53EE6F2AF;
if (!MEM::load_key_value(kv3, nullptr, szVmatBuffer, &kv3ID, nullptr))
throw;
material2_t** custom_material;
MEM::fnCreateMaterial(nullptr, &custom_material, m_name, kv3, 0, 1);
return *custom_material;
}
material2_t* create_material_flat_visible(const char* m_name) {
const char szVmatBuffer[] = R"(<!-- kv3 encoding:text:version{e21c7f3c-8a33-41c5-9977-a76d3a32aa0d} format:generic:version{7412167c-06e9-4698-aff2-e63eb59037e7} -->
{
shader = "csgo_unlitgeneric.vfx"
F_PAINT_VERTEX_COLORS = 1
F_TRANSLUCENT = 1
F_BLEND_MODE = 1
g_vColorTint = [1, 1, 1, 1]
TextureAmbientOcclusion = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tAmbientOcclusion = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tColor = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tNormal = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tTintMask = resource:"materials/default/default_mask_tga_fde710a5.vtex"
})";
auto buffer = new unsigned char[0x100 + sizeof(CKeyValues3)];
CRT::MemorySet(buffer, 0, sizeof(buffer));
CKeyValues3* kv3 = (CKeyValues3*)(buffer + 0x100);
KV3IVD_t kv3ID;
kv3ID.szName = m_name;
kv3ID.unk0 = 0x469806E97412167C;
kv3ID.unk1 = 0xE73790B53EE6F2AF;
if (!MEM::load_key_value(kv3, nullptr, szVmatBuffer, &kv3ID, nullptr))
throw;
material2_t** custom_material;
MEM::fnCreateMaterial(nullptr, &custom_material, m_name, kv3, 0, 1);
return *custom_material;
}
material2_t* create_material_flat_invisible(const char* m_name) {
const char szVmatBuffer[] = R"(<!-- kv3 encoding:text:version{e21c7f3c-8a33-41c5-9977-a76d3a32aa0d} format:generic:version{7412167c-06e9-4698-aff2-e63eb59037e7} -->
{
shader = "csgo_unlitgeneric.vfx"
F_PAINT_VERTEX_COLORS = 1
F_TRANSLUCENT = 1
F_BLEND_MODE = 1
F_DISABLE_Z_BUFFERING = 1
g_vColorTint = [1, 1, 1, 1]
TextureAmbientOcclusion = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tAmbientOcclusion = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tColor = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tNormal = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tTintMask = resource:"materials/default/default_mask_tga_fde710a5.vtex"
})";
auto buffer = new unsigned char[0x100 + sizeof(CKeyValues3)];
CRT::MemorySet(buffer, 0, sizeof(buffer));
CKeyValues3* kv3 = (CKeyValues3*)(buffer + 0x100);
KV3IVD_t kv3ID;
kv3ID.szName = m_name;
kv3ID.unk0 = 0x469806E97412167C;
kv3ID.unk1 = 0xE73790B53EE6F2AF;
if (!MEM::load_key_value(kv3, nullptr, szVmatBuffer, &kv3ID, nullptr))
throw;
material2_t** custom_material;
MEM::fnCreateMaterial(nullptr, &custom_material, m_name, kv3, 0, 1);
return *custom_material;
}
material2_t* create_material_illum_visible(const char* m_name) {
const char szVmatBuffer[] = R"(<!-- kv3 encoding:text:version{e21c7f3c-8a33-41c5-9977-a76d3a32aa0d} format:generic:version{7412167c-06e9-4698-aff2-e63eb59037e7} -->
{
shader = "csgo_complex.vfx"
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"
g_vColorTint = [ 20.000000, 20.000000, 20.000000, 20.000000 ]
g_flSelfIllumScale = [ 5.000000, 5.000000, 5.000000, 5.000000 ]
g_flSelfIllumBrightness = [ 5.000000, 5.000000, 5.000000, 5.000000 ]
g_vSelfIllumTint = [ 10.000000, 10.000000, 10.000000, 10.000000 ]
F_SELF_ILLUM = 1
F_PAINT_VERTEX_COLORS = 1
F_TRANSLUCENT = 1
})";
auto buffer = new unsigned char[0x100 + sizeof(CKeyValues3)];
CRT::MemorySet(buffer, 0, sizeof(buffer));
CKeyValues3* kv3 = (CKeyValues3*)(buffer + 0x100);
KV3IVD_t kv3ID;
kv3ID.szName = m_name;
kv3ID.unk0 = 0x469806E97412167C;
kv3ID.unk1 = 0xE73790B53EE6F2AF;
if (!MEM::load_key_value(kv3, nullptr, szVmatBuffer, &kv3ID, nullptr))
throw;
material2_t** custom_material;
MEM::fnCreateMaterial(nullptr, &custom_material, m_name, kv3, 0, 1);
return *custom_material;
}
material2_t* create_material_illum_invisible(const char* m_name) {
const char szVmatBuffer[] = R"(<!-- kv3 encoding:text:version{e21c7f3c-8a33-41c5-9977-a76d3a32aa0d} format:generic:version{7412167c-06e9-4698-aff2-e63eb59037e7} -->
{
shader = "csgo_complex.vfx"
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"
g_vColorTint = [ 20.000000, 20.000000, 20.000000, 20.000000 ]
g_flSelfIllumScale = [ 5.000000, 5.000000, 5.000000, 5.000000 ]
g_flSelfIllumBrightness = [ 5.000000, 5.000000, 5.000000, 5.000000 ]
g_vSelfIllumTint = [ 10.000000, 10.000000, 10.000000, 10.000000 ]
F_SELF_ILLUM = 1
F_PAINT_VERTEX_COLORS = 1
F_TRANSLUCENT = 1
F_DISABLE_Z_BUFFERING = 1
})";
auto buffer = new unsigned char[0x100 + sizeof(CKeyValues3)];
CRT::MemorySet(buffer, 0, sizeof(buffer));
CKeyValues3* kv3 = (CKeyValues3*)(buffer + 0x100);
KV3IVD_t kv3ID;
kv3ID.szName = m_name;
kv3ID.unk0 = 0x469806E97412167C;
kv3ID.unk1 = 0xE73790B53EE6F2AF;
if (!MEM::load_key_value(kv3, nullptr, szVmatBuffer, &kv3ID, nullptr))
throw;
material2_t** custom_material;
MEM::fnCreateMaterial(nullptr, &custom_material, m_name, kv3, 0, 1);
return *custom_material;
}
// other functions.
bool ams::chams_t::initialize() {
// first we have to check if this shit is alr initialized
if (this->m_initialized) {
return this->m_initialized;
}
// only initialize this for moment, later we're gonna init more
array_materials[material_list_t::material_white] = custom_material_data_t{
.m_material = CreateMaterial(CS_XOR("primary_white"), CS_XOR("materials/dev/primary_white.vmat"), CS_XOR("csgo_unlitgeneric.vfx"), true, true, false),
.m_material_z = CreateMaterial(CS_XOR("primary_white_invisible"), CS_XOR("materials/dev/primary_white.vmat"), CS_XOR("csgo_unlitgeneric.vfx"), true, true, true)
};
array_materials[material_list_t::material_default] = custom_material_data_t{
.m_material = CreateMaterial(CS_XOR("primary_white"), CS_XOR("materials/dev/primary_white.vmat"), CS_XOR("csgo_unlitgeneric.vfx"), true, true, false),
.m_material_z = CreateMaterial(CS_XOR("primary_white_invisible"), CS_XOR("materials/dev/primary_white.vmat"), CS_XOR("csgo_unlitgeneric.vfx"), true, true, true)
};
array_materials[material_list_t::material_illum] = custom_material_data_t{
.m_material = CreateMaterial(CS_XOR("primary_white"), CS_XOR("materials/dev/primary_white.vmat"), CS_XOR("csgo_unlitgeneric.vfx"), true, true, false),
.m_material_z = CreateMaterial(CS_XOR("primary_white_invisible"), CS_XOR("materials/dev/primary_white.vmat"), CS_XOR("csgo_unlitgeneric.vfx"), true, true, true)
};
// we initialized by now
this->m_initialized = true;
// iterate.
for (auto& [m_visible, m_invisible] : array_materials) {
if (m_visible == nullptr || m_invisible == nullptr)
this->m_initialized = false;
}
// finish and return value
return this->m_initialized;
}
void ams::chams_t::destroy() {
// nothing to destroy boss
}
bool ams::chams_t::draw_object(void* animatable_object, void* dx11, material_data_t* arr_material_data, int data_count,
void* scene_view, void* scene_layer, void* unk1, void* unk2) {
// check if we initialized.
if (!this->m_initialized) {
return false;
}
if (!C_GET(bool, Vars.bVisualChams))
{
return false;
}
if (!SDK::LocalPawn)
return false;
// no chams enable.
// return false
// no data on material
if (arr_material_data == nullptr) {
return false;
}
// no data on scene object.
if (arr_material_data->m_scene_animable == nullptr) {
return false;
}
// owner.
CBaseHandle m_owner = arr_material_data->m_scene_animable->m_owner;
// get entity.
auto m_entity = I::GameResourceService->pGameEntitySystem ->Get< C_BaseEntity >(m_owner);
if (m_entity == nullptr) {
return false;
}
// schema info
SchemaClassInfoData_t* m_class_info;
m_entity->GetSchemaClassInfo(&m_class_info);
if (m_class_info == nullptr) {
return false;
}
// compare string.
if (CRT::StringCompare(m_class_info->szName, CS_XOR("C_CSPlayerPawn")) != 0)
return false;
// get pawn.
auto m_pawn = I::GameResourceService->pGameEntitySystem->Get< C_CSPlayerPawn>(m_owner);
if (m_pawn == nullptr) {
return false;
}
// other entity
if (!m_pawn->IsOtherEnemy(SDK::LocalPawn)) {
return false;
}
// it is alive
if (m_pawn->GetHealth() <= 0) {
return false;
}
// we passed to everythign.
// please render material.
return this->override_material(animatable_object, dx11, arr_material_data, data_count,
scene_view, scene_layer, unk1, unk2);
}
material2_t* ams::chams_t::CreateMaterial(const char* szName, const char* szMaterialVMAT, const char* szShaderType, bool bBlendMode, bool bTranslucent, bool bDisableZBuffering)
{
material_data_t* pData = reinterpret_cast<material_data_t*>(static_cast<std::byte*>(MEM_STACKALLOC(0x200)) + 0x50);
material2_t** pMatPrototype;
I::MaterialSystem2->find_or_create_from_resource(&pMatPrototype, szMaterialVMAT);
if (pMatPrototype == nullptr)
return nullptr;
// @note: SetCreateDataByMaterial failed on release build idk why
#ifdef _DEBUG
I::MaterialSystem2->set_create_data_by_material(pData, &pMatPrototype);
pData->set_shader_type(szShaderType);
pData->set_material_function(CS_XOR("F_DISABLE_Z_BUFFERING"), bDisableZBuffering ? 1 : 0);
pData->set_material_function(CS_XOR("F_BLEND_MODE"), bBlendMode ? 1 : 0);
pData->set_material_function(CS_XOR("F_TRANSLUCENT"), bTranslucent ? 1 : 0);
material2_t** pMaterial;
I::MaterialSystem2->create_material(&pMaterial, szName, pData);
return *pMaterial;
#endif
return *pMatPrototype;
}
bool ams::chams_t::override_material(void* animatable_object, void* dx11, material_data_t* arr_material_data, int data_count,
void* scene_view, void* scene_layer, void* unk1, void* unk2) {
const auto original = H::hkDrawObject.GetOriginal();
const custom_material_data_t customMaterial = array_materials[C_GET(int, Vars.nVisualChamMaterial)];
if (C_GET(bool, Vars.bVisualChamsIgnoreZ))
{
arr_material_data->m_material = customMaterial.m_material_z;
arr_material_data->m_color = C_GET(ColorPickerVar_t, Vars.colVisualChamsIgnoreZ).colValue;
I::MaterialSystem2->set_color(arr_material_data, C_GET(ColorPickerVar_t, Vars.colVisualChamsIgnoreZ).colValue);
original(animatable_object, dx11, arr_material_data, data_count, scene_view, scene_layer, unk1, unk2);
}
arr_material_data->m_material = customMaterial.m_material;
arr_material_data->m_color = C_GET(ColorPickerVar_t, Vars.colVisualChams).colValue;
I::MaterialSystem2->set_color(arr_material_data, C_GET(ColorPickerVar_t, Vars.colVisualChams).colValue);
original(animatable_object, dx11, arr_material_data, data_count, scene_view, scene_layer, unk1, unk2);
return true;
}

View File

@@ -0,0 +1,33 @@
#pragma once
#pragma once
#include "../../common.h"
#include <memory>
#include "../cstrike/sdk/datatypes/stronghandle.hpp"
#pragma once
class material_data_t;
class material2_t;
namespace ams {
class chams_t {
public:
bool initialize();
void destroy();
public:
bool draw_object(void* animatable_object, void* dx11, material_data_t* arr_material_data, int data_count,
void* scene_view, void* scene_layer, void* unk1, void* unk2);
bool override_material(void* animatable_object, void* dx11, material_data_t* arr_material_data, int data_count,
void* scene_view, void* scene_layer, void* unk1, void* unk2);
public:
material2_t* CreateMaterial(const char* szName, const char* szMaterialVMAT, const char* szShaderType, bool bBlendMode, bool bTranslucent, bool bDisableZBuffering);
material2_t* create_material(const char* m_name, const char* material_vmat, const char* shader_type, bool blend_mode,
bool transfluscent, bool disable_buffering);
private:
bool m_initialized = false;
};
const auto chams = std::make_unique<chams_t>();
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,183 @@
#pragma once
#include "../../common.h"
// used: draw system
#include "../../utilities/draw.h"
#include "../../sdk/datatypes/vector.h"
#include "../../sdk/datatypes/transform.h"
class CCSPlayerController;
class C_BaseEntity;
class C_CSPlayerPawn;
class CBaseHandle;
class CEntityInstance;
namespace F::VISUALS::OVERLAY
{
enum EAlignSide : std::uint8_t
{
SIDE_LEFT = 0U,
SIDE_TOP,
SIDE_RIGHT,
SIDE_BOTTOM,
SIDE_MAX
};
enum EAlignDirection : std::uint8_t
{
DIR_LEFT = 0U,
DIR_TOP,
DIR_RIGHT,
DIR_BOTTOM,
DIR_MAX = 4U // @todo: rework stuff based on this cuz one component can have only 3 possible directions at same time. vertical side: left & right + top | bottom, horizontal side: top & bottom + left | right
};
class CBaseComponent
{
public:
[[nodiscard]] virtual ImVec2 GetBasePosition(const ImVec4& box) const;
[[nodiscard]] virtual bool IsDirectional() const
{
return false;
}
virtual void Render(ImDrawList* pDrawList, const ImVec2& vecPosition) = 0;
EAlignSide nSide = SIDE_TOP;
ImVec2 vecOffset = {};
ImVec2 vecSize = {};
};
class CBaseDirectionalComponent : public CBaseComponent
{
public:
[[nodiscard]] ImVec2 GetBasePosition(const ImVec4& box) const final;
[[nodiscard]] bool IsDirectional() const final
{
return true;
}
EAlignDirection nDirection = DIR_TOP;
};
class CBarComponent : public CBaseComponent
{
public:
CBarComponent(const bool bIsMenuItem, const EAlignSide nAlignSide, const ImVec4& vecBox, const float max_limit, const float flProgressFactor, const std::size_t uOverlayVarIndex, const float alphaMultiplier = 1.f);
void Render(ImDrawList* pDrawList, const ImVec2& vecPosition) final;
private:
bool bIsMenuItem = false;
float alphaMultiplier = 1.f;
// bar progress
float flProgressFactor = 0.0f;
//maxlimit
float max_limit = 0.0f;
std::string value_sz;
int value;
// hovered state for context menu
bool bIsHovered = false;
// config variables
std::size_t uOverlayVarIndex = 0ULL;
};
class CTextComponent : public CBaseDirectionalComponent
{
public:
CTextComponent(const bool bIsMenuItem, const bool bIcon, const EAlignSide nAlignSide, const EAlignDirection nAlignDirection, const ImFont* pFont, const char* szText, const std::size_t uOverlayVarIndex, const float alphaM = 1.f);
~CTextComponent();
void Render(ImDrawList* pDrawList, const ImVec2& vecPosition) final;
private:
float alphaMultiplier = 1.f;
bool bIsMenuItem = false;
bool bIcon = false;
// font & text for displaying
const ImFont* pFont = nullptr;
char* szText = nullptr;
// hovered state for context menu
bool bIsHovered = false;
// config variables
std::size_t uOverlayVarIndex = 0ULL;
};
/*
* overlay component auto-positioning system
* @note: was designed to support the reordering of components that can be implemented with minimal effort
*
* currently supported next sides and sub-directions:
*
* DIR_TOP
* ^
* |
* DIR_LEFT <-o-> DIR_RIGHT
* DIR_LEFT <-o *---------* o-> DIR_RIGHT
* | | | |
* v | | v
* DIR_BOTTOM | | DIR_BOTTOM
* | |
* DIR_TOP | | DIR_TOP
* ^ | | ^
* | | | |
* o *---------* o
* DIR_LEFT <-o-> DIR_RIGHT
* |
* v
* DIR_BOTTOM
*/
struct Context_t
{
/* @section: special case components */
/// add the box component to overlay
/// @remarks: current implementation expects this to be first component, it's an immediate rendering component
/// @return: if the box component is hovered
bool AddBoxComponent(ImDrawList* pDrawList, const ImVec4& vecBox, const int nType, float flThickness, float flRounding, const Color_t& colPrimary, const Color_t& colOutline , const float alpha = 1.f);
/// add the frame component to overlay
/// @remarks: current implementation expects this to be added after components that should be inside it, it's an immediate rendering component
/// @returns: size constraints of the added frame
ImVec4 AddFrameComponent(ImDrawList* pDrawList, const ImVec2& vecScreen, const EAlignSide nSide, const Color_t& colBackground, const float flRounding, const ImDrawFlags nRoundingCorners);
/* @section: common components */
/// add new component to overlay
/// @param[in] pComponent pointer to the one of supported component types
void AddComponent(CBaseComponent* pComponent);
/* @section: get */
/// @returns: size of the all directional components currently assigned to @a'nSide'
[[nodiscard]] ImVec2 GetTotalDirectionalSize(const EAlignSide nSide) const;
// calculate final position of components and render them
void Render(ImDrawList* pDrawList, const ImVec4& vecBox) const;
private:
// storage of all components
std::vector<CBaseComponent*> vecComponents = {};
// additional spacing between components
float flComponentSpacing = 1.0f;
// summary padding of all align sides
float arrSidePaddings[SIDE_MAX] = {};
// summary padding for all align directions of all align sides
float arrSideDirectionPaddings[SIDE_MAX][DIR_MAX] = {};
};
/* @section: callbacks */
void OnFrameStageNotify(CCSPlayerController* pLocalController);
/* @section: main */
// draw box, bars, text infos, etc at player position
void Render();
void CalculateBoundingBoxes();
void CalculateSkeleton(Context_t ctx, CCSPlayerController* pPlayerController, C_CSPlayerPawn* pPlayer, const ImVec4& out);
void OnPlayer(CCSPlayerController* pEntity, const ImVec4& out);
bool IsValid(CCSPlayerController* pEntity);
}