#include "csgostructs.hpp"
#include "../helpers/math.hpp"
#include "../helpers/utils.hpp"
bool C_BaseEntity::IsPlayer()
{
return CallVFunction<bool(__thiscall*)(C_BaseEntity*)>(this, 151)(this); //152
}
bool C_BaseEntity::IsWeapon()
{
return CallVFunction<bool(__thiscall*)(C_BaseEntity*)>(this, 159)(this); //160
}
bool C_BaseEntity::IsPlantedC4()
{
return GetClientClass()->m_ClassID == ClassId_CPlantedC4;
}
bool C_BaseEntity::IsDefuseKit()
{
return GetClientClass()->m_ClassID == ClassId_CBaseAnimating;
}
CCSWeaponInfo* C_BaseCombatWeapon::GetCSWeaponData()
{
return CallVFunction<CCSWeaponInfo*(__thiscall*)(void*)>(this, 444)(this); //445
}
bool C_BaseCombatWeapon::HasBullets()
{
return !IsReloading() && m_iClip1() > 0;
}
bool C_BaseCombatWeapon::CanFire()
{
if(IsReloading() || m_iClip1() <= 0)
return false;
if(!g_LocalPlayer)
return false;
const float server_time = g_LocalPlayer->m_nTickBase() * g_GlobalVars->interval_per_tick;
return m_flNextPrimaryAttack() <= server_time;
}
bool C_BaseCombatWeapon::IsGrenade()
{
return GetCSWeaponData()->WeaponType == WEAPONTYPE_GRENADE;
}
bool C_BaseCombatWeapon::IsKnife()
{
return GetCSWeaponData()->WeaponType == WEAPONTYPE_KNIFE;
}
bool C_BaseCombatWeapon::IsRifle()
{
switch (GetCSWeaponData()->WeaponType)
{
case WEAPONTYPE_RIFLE:
case WEAPONTYPE_SHOTGUN:
case WEAPONTYPE_SUBMACHINEGUN:
case WEAPONTYPE_MACHINEGUN:
return true;
default:
return false;
}
}
bool C_BaseCombatWeapon::IsPistol()
{
return GetCSWeaponData()->WeaponType == WEAPONTYPE_PISTOL;
}
bool C_BaseCombatWeapon::IsSniper()
{
return GetCSWeaponData()->WeaponType == WEAPONTYPE_SNIPER_RIFLE;
}
bool C_BaseCombatWeapon::IsReloading()
{
static auto inReload = *reinterpret_cast<uint32_t*>(Utils::PatternScan("client_panorama.dll", "C6 87 ? ? ? ? ? 8B 06 8B CE FF 90") + 2);
return *reinterpret_cast<bool*>(uintptr_t(this) + inReload);
}
float C_BaseCombatWeapon::GetInaccuracy()
{
return CallVFunction<float(__thiscall*)(void*)>(this, 467)(this); //468
}
float C_BaseCombatWeapon::GetSpread()
{
return CallVFunction<float(__thiscall*)(void*)>(this, 436)(this); //437
}
void C_BaseCombatWeapon::UpdateAccuracyPenalty()
{
CallVFunction<void(__thiscall*)(void*)>(this, 468)(this); //469
}
CUserCmd*& C_BasePlayer::m_pCurrentCommand()
{
static auto current_сommand = *reinterpret_cast<uint32_t*>(Utils::PatternScan("client_panorama.dll", "C6 87 ? ? ? ? ? 8B 06 8B CE FF 90") + 2);
return *reinterpret_cast<CUserCmd**>(uintptr_t(this) + current_сommand);
}
Vector C_BasePlayer::GetEyePos()
{
return m_vecOrigin() + m_vecViewOffset();
}
player_info_t C_BasePlayer::GetPlayerInfo()
{
player_info_t info;
g_EngineClient->GetPlayerInfo(EntIndex(), &info);
return info;
}
bool C_BasePlayer::IsAlive()
{
return m_lifeState() == LIFE_ALIVE;
}
bool C_BasePlayer::HasC4()
{
static auto fnHasC4 = reinterpret_cast<bool(__thiscall*)(void*)>(Utils::PatternScan("client_panorama.dll", "56 8B F1 85 F6 74 31"));
return fnHasC4(this);
}
Vector C_BasePlayer::GetHitboxPos(int hitbox_id)
{
matrix3x4_t boneMatrix[MAXSTUDIOBONES];
if(SetupBones(boneMatrix, MAXSTUDIOBONES, BONE_USED_BY_HITBOX, 0.0f)) {
auto studio_model = g_MdlInfo->GetStudiomodel(GetModel());
if(studio_model) {
const auto hitbox = studio_model->GetHitboxSet(0)->GetHitbox(hitbox_id);
if(hitbox) {
auto
min = Vector{},
max = Vector{};
Math::VectorTransform(hitbox->bbmin, boneMatrix[hitbox->bone], min);
Math::VectorTransform(hitbox->bbmax, boneMatrix[hitbox->bone], max);
return (min + max) / 2.0f;
}
}
}
return Vector{};
}
bool C_BasePlayer::GetHitboxPos(int hitbox, Vector &output)
{
if(hitbox >= HITBOX_MAX)
return false;
const model_t *model = this->GetModel();
if(!model)
return false;
studiohdr_t *studioHdr = g_MdlInfo->GetStudiomodel(model);
if(!studioHdr)
return false;
matrix3x4_t matrix[MAXSTUDIOBONES];
if(!this->SetupBones(matrix, MAXSTUDIOBONES, 0x100, 0))
return false;
mstudiobbox_t *studioBox = studioHdr->GetHitboxSet(0)->GetHitbox(hitbox);
if(!studioBox)
return false;
Vector min, max;
Math::VectorTransform(studioBox->bbmin, matrix[studioBox->bone], min);
Math::VectorTransform(studioBox->bbmax, matrix[studioBox->bone], max);
output = (min + max) * 0.5f;
return true;
}
Vector C_BasePlayer::GetBonePos(int bone)
{
matrix3x4_t boneMatrix[MAXSTUDIOBONES];
if(SetupBones(boneMatrix, MAXSTUDIOBONES, BONE_USED_BY_ANYTHING, 0.0f)) {
return boneMatrix[bone].at(3);
}
return Vector{};
}
bool C_BasePlayer::CanSeePlayer(C_BasePlayer* player, int hitbox)
{
return CanSeePlayer(player, player->GetHitboxPos(hitbox));
}
bool C_BasePlayer::CanSeePlayer(C_BasePlayer* player, const Vector& pos)
{
CGameTrace tr;
Ray_t ray;
CTraceFilter filter;
filter.pSkip = this;
ray.Init(GetEyePos(), pos);
g_EngineTrace->TraceRay(ray, MASK_SHOT | CONTENTS_GRATE, &filter, &tr);
return tr.hit_entity == player || tr.fraction > 0.97f;
}
int C_BasePlayer::m_nMoveType()
{
return *reinterpret_cast<int*>(uintptr_t(this) + 0x258);
}
C_BasePlayer* C_BasePlayer::GetPlayerOrObserver()
{
if (IsAlive())
return this;
if (!m_hObserverTarget())
return nullptr;
auto player = dynamic_cast<C_BasePlayer*>(g_EntityList->GetClientEntityFromHandle(m_hObserverTarget()));
return player->IsAlive() ? player : nullptr;
}