paster
-
Автор темы
- #1
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
autowall.cpp
autowall.h
делать нехуй было решил с вейви под лв сделать автовалл
C++:
#include "../../hooks/hooks.hpp"
#include "autowall.h"
ReturnInfo_t autowall::Think(Vector pos, player_t* target, int specific_hitgroup, Vector eye_pos, player_t* start_ent)
{
ReturnInfo_t return_info = ReturnInfo_t(-1, -1, 4, false, 0.f, nullptr);
if (!start_ent)
return return_info;
auto cached_pos = pos;
for (int i = 0; i < scanned_points.size(); i++) {
if (cached_pos == scanned_points[i]) {
return_info.m_damage = scanned_damage[i];
return return_info;
}
}
Vector start = eye_pos;
FireBulletData_t fire_bullet_data;
fire_bullet_data.m_start = start;
fire_bullet_data.m_end = pos;
fire_bullet_data.m_current_position = start;
fire_bullet_data.m_penetration_count = 4;
math::AngleVectorszae(math::calculate_angle(start, pos), fire_bullet_data.m_direction);
static const auto filter_simple = *reinterpret_cast<uint32_t*>(reinterpret_cast<uint32_t>(
(void*)util::FindSignature(crypt_str("client.dll"),
crypt_str("55 8B EC 83 E4 F0 83 EC 7C 56 52"))) + 0x3d);
uint32_t dwFilter[4] = { filter_simple,
reinterpret_cast<uint32_t>(start_ent), 0, 0 };
fire_bullet_data.m_filter = (CTraceFilter*)(dwFilter);
auto weapon = start_ent->m_hActiveWeapon().Get();
if (!weapon)
return return_info;
auto weapon_info = weapon->get_csweapon_info();
if (!weapon_info)
return return_info;
float range = min(weapon_info->flRange, (start - pos).Length());
pos = start + (fire_bullet_data.m_direction * range);
fire_bullet_data.m_current_damage = weapon_info->iDamage;
while (fire_bullet_data.m_current_damage > 0 && fire_bullet_data.m_penetration_count > 0)
{
return_info.m_penetration_count = fire_bullet_data.m_penetration_count;
TraceLine(fire_bullet_data.m_current_position, pos, MASK_SHOT | CONTENTS_GRATE, start_ent, &fire_bullet_data.m_enter_trace);
{
Vector end = fire_bullet_data.m_current_position + (fire_bullet_data.m_direction * 40.f);
ClipTrace(fire_bullet_data.m_current_position, end, target, MASK_SHOT | CONTENTS_GRATE, fire_bullet_data.m_filter, &fire_bullet_data.m_enter_trace);
}
const float distance_traced = (fire_bullet_data.m_enter_trace.endpos - start).Length();
fire_bullet_data.m_current_damage *= pow(weapon_info->flRangeModifier, (distance_traced / 500.f));
if (fire_bullet_data.m_enter_trace.fraction == 1.f)
{
return_info.m_damage = fire_bullet_data.m_current_damage;
return_info.m_hitgroup = fire_bullet_data.m_enter_trace.hitgroup;
return_info.m_end = fire_bullet_data.m_enter_trace.endpos;
return_info.m_hit_entity = nullptr;
break;
}
if (fire_bullet_data.m_enter_trace.hitgroup > 0 && fire_bullet_data.m_enter_trace.hitgroup <= 8)
{
if (
(fire_bullet_data.m_enter_trace.hitgroup != specific_hitgroup)
||
(fire_bullet_data.m_enter_trace.hit_entity != target)
||
((player_t*)fire_bullet_data.m_enter_trace.hit_entity)->m_iTeamNum() == start_ent->m_iTeamNum())
{
return_info.m_damage = -1;
return return_info;
}
ScaleDamage((player_t*)fire_bullet_data.m_enter_trace.hit_entity, weapon_info, fire_bullet_data.m_enter_trace.hitgroup, fire_bullet_data.m_current_damage);
return_info.m_damage = fire_bullet_data.m_current_damage;
return_info.m_hitgroup = fire_bullet_data.m_enter_trace.hitgroup;
return_info.m_end = fire_bullet_data.m_enter_trace.endpos;
return_info.m_hit_entity = (player_t*)fire_bullet_data.m_enter_trace.hit_entity;
break;
}
if (!HandleBulletPenetration(weapon_info, fire_bullet_data))
break;
return_info.m_did_penetrate_wall = true;
}
scanned_damage.push_back(return_info.m_damage);
scanned_points.push_back(cached_pos);
return_info.m_penetration_count = fire_bullet_data.m_penetration_count;
return return_info;
}
float autowall::HitgroupDamage(int iHitGroup)
{
switch (iHitGroup)
{
case HITGROUP_HEAD:
return 4.f;
break;
case HITGROUP_CHEST:
case 8:
return 1.f;
break;
case HITGROUP_STOMACH:
return 1.25f;
break;
case HITGROUP_LEFTARM:
case HITGROUP_RIGHTARM:
return 1.f;
break;
case HITGROUP_LEFTLEG:
case HITGROUP_RIGHTLEG:
return 0.75f;
break;
default:
break;
}
return 1.f;
}
bool autowall::IsArmored(player_t* player, int hitgroup)
{
if (!player)
return false;
auto has_helmet = player->m_bHasHelmet();
auto armor_value = player->m_ArmorValue();
if (armor_value > 0)
{
switch (hitgroup)
{
case HITGROUP_GENERIC:
case HITGROUP_CHEST:
case HITGROUP_STOMACH:
case HITGROUP_LEFTARM:
case HITGROUP_RIGHTARM:
case 8:
return true;
break;
case HITGROUP_HEAD:
return has_helmet || player->m_bHasHeavyArmor();
break;
default:
return player->m_bHasHeavyArmor();
break;
}
}
return false;
}
void autowall::ScaleDamage(player_t* player, weapon_info_t* weapon_info, int hitgroup, float& damage)
{
if (!player)
return;
auto new_damage = damage;
const auto is_zeus = g_ctx.globals.weapon->m_iItemDefinitionIndex() == WEAPON_TASER;
static auto is_armored = [](player_t* player, int armor, int hitgroup) {
if (player && player->m_ArmorValue() > 0)
{
if (player->m_bHasHelmet() && hitgroup == HITGROUP_HEAD || (hitgroup >= HITGROUP_CHEST && hitgroup <= HITGROUP_RIGHTARM))
return true;
}
return false;
};
if (!is_zeus) {
switch (hitgroup)
{
case HITGROUP_HEAD:
new_damage *= 4.f;
break;
case HITGROUP_STOMACH:
new_damage *= 1.25f;
break;
case HITGROUP_LEFTLEG:
case HITGROUP_RIGHTLEG:
new_damage *= .75f;
break;
default:
break;
/*4.0; 1
1.0; 2
1.25; 3
1.0; 4
1.0; 5
0.75; 6
0.75; 7
1.0; 8*/
}
}
else
new_damage *= 0.92f;
auto weaponData = g_ctx.globals.weapon->get_csweapon_info();
if (!weaponData)
return;
if (is_armored(player, player->m_ArmorValue(), hitgroup))
{
float flHeavyRatio = 1.0f;
float flBonusRatio = 0.5f;
float flRatio = weaponData->flArmorRatio * 0.5f;
float flNewDamage;
if (!player->m_bHasHeavyArmor())
{
flNewDamage = new_damage * flRatio;
}
else
{
flBonusRatio = 0.33f;
flRatio = weaponData->flArmorRatio * 0.5f;
flHeavyRatio = 0.33f;
flNewDamage = (new_damage * (flRatio * 0.5)) * 0.85f;
}
int iArmor = player->m_ArmorValue();
if (((new_damage - flNewDamage) * (flBonusRatio * flHeavyRatio)) > iArmor)
flNewDamage = new_damage - (iArmor / flBonusRatio);
new_damage = flNewDamage;
}
damage = new_damage;
}
bool autowall::VectortoVectorVisible(Vector src, Vector point) {
CGameTrace TraceInit;
TraceLine(src, point, MASK_SOLID, g_ctx.local(), &TraceInit);
CGameTrace Trace;
TraceLine(src, point, MASK_SOLID, (player_t*)TraceInit.hit_entity, &Trace);
if (Trace.fraction == 1.0f || TraceInit.fraction == 1.0f)
return true;
return false;
};
bool autowall::HandleBulletPenetration(weapon_info_t* info, FireBulletData_t& data, bool extracheck, Vector point)
{
CGameTrace trace_exit;
surfacedata_t* enter_surface_data = m_physsurface()->GetSurfaceData(data.m_enter_trace.surface.surfaceProps);
int enter_material = enter_surface_data->game.material;
float enter_surf_penetration_modifier = enter_surface_data->game.flPenetrationModifier;
float final_damage_modifier = 0.18f;
float compined_penetration_modifier = 0.f;
auto nodraw = (data.m_enter_trace.surface.flags & SURF_NODRAW);
auto grate = (data.m_enter_trace.contents & CONTENTS_GRATE);
if (enter_surf_penetration_modifier < 0.1f)
return false;
if (!data.m_penetration_count && !nodraw && !grate && enter_material != CHAR_TEX_GRATE && enter_material != CHAR_TEX_GLASS)
return false;
if (info->flPenetration <= 0.f)
return false;
if (!TraceToExit(data.m_enter_trace, trace_exit, data.m_enter_trace.endpos, data.m_direction)) {
if (!(m_trace()->GetPointContents(data.m_enter_trace.endpos, MASK_SHOT_HULL) & MASK_SHOT_HULL))
return false;
}
surfacedata_t* exit_surface_data = m_physsurface()->GetSurfaceData(trace_exit.surface.surfaceProps);
int exit_material = exit_surface_data->game.material;
float exit_surf_penetration_modifier = exit_surface_data->game.flPenetrationModifier;
if (enter_material == CHAR_TEX_GRATE || enter_material == CHAR_TEX_GLASS) {
compined_penetration_modifier = 3.f;
final_damage_modifier = 0.06f;
}
else if (nodraw || grate)
{
compined_penetration_modifier = 1.f;
final_damage_modifier = 0.16f;
}
else {
compined_penetration_modifier = (enter_surf_penetration_modifier + exit_surf_penetration_modifier) * 0.5f;
final_damage_modifier = 0.16f;
}
if (enter_material == exit_material)
{
if (exit_material == CHAR_TEX_CARDBOARD || exit_material == CHAR_TEX_WOOD)
compined_penetration_modifier = 3.f;
else if (exit_material == CHAR_TEX_PLASTIC)
compined_penetration_modifier = 2.0f;
}
float thickness = (trace_exit.endpos - data.m_enter_trace.endpos).LengthSqr();
float modifier = fmaxf(1.f / compined_penetration_modifier, 0.f);
if (extracheck && !VectortoVectorVisible(trace_exit.endpos, point))
return false;
float lost_damage = fmaxf(((modifier * thickness) / 24.f) +
((data.m_current_damage * final_damage_modifier) +
(fmaxf(3.75f / info->flPenetration, 0.f) * 3.f * modifier)), 0.f);
if (lost_damage > data.m_current_damage)
return false;
if (lost_damage > 0.f)
data.m_current_damage -= lost_damage;
if (data.m_current_damage < 1.f)
return false;
data.m_current_position = trace_exit.endpos;
data.m_penetration_count--;
return true;
}
bool autowall::BreakableEntity(player_t* entity)
{
if (!entity)
return false;
ClientClass* pClass = (ClientClass*)entity->GetClientClass();
if (!pClass)
{
return false;
}
return pClass->m_ClassID == 30 || pClass->m_ClassID == 31;
}
bool autowall::TraceToExit(CGameTrace& enterTrace, CGameTrace& exitTrace, Vector startPosition, Vector direction)
{
Vector start = Vector(0, 0, 0);
Vector end = Vector(0, 0, 0);
float maxDistance = 90.f, rayExtension = 4.f, currentDistance = 0;
int firstContents = 0;
while (currentDistance <= maxDistance)
{
currentDistance += rayExtension;
start = startPosition + direction * currentDistance;
if (!firstContents)
{
firstContents = m_trace()->GetPointContents(start, MASK_SHOT_HULL | CONTENTS_HITBOX, nullptr);
}
int pointContents = m_trace()->GetPointContents(start, MASK_SHOT_HULL | CONTENTS_HITBOX, nullptr);
if (!(pointContents & MASK_SHOT_HULL) || (pointContents & CONTENTS_HITBOX && pointContents != firstContents))
{
end = start - (direction * rayExtension);
TraceLine(start, end, MASK_SHOT_HULL | CONTENTS_HITBOX, nullptr, &exitTrace);
if (exitTrace.startsolid && exitTrace.surface.flags & SURF_HITBOX)
{
TraceLine(start, startPosition, MASK_SHOT_HULL, (player_t*)exitTrace.hit_entity, &exitTrace);
if (exitTrace.DidHit() && !exitTrace.startsolid)
{
start = exitTrace.endpos;
return true;
}
continue;
}
if (exitTrace.DidHit() && !exitTrace.startsolid)
{
if (BreakableEntity((player_t*)enterTrace.hit_entity) && BreakableEntity((player_t*)exitTrace.hit_entity))
{
return true;
}
if (enterTrace.surface.flags & SURF_NODRAW || (!(exitTrace.surface.flags & SURF_NODRAW) && exitTrace.plane.normal.Dot(direction) <= 1.0f))
{
const float multAmount = exitTrace.fraction * 4.f;
start -= direction * multAmount;
return true;
}
continue;
}
if (!exitTrace.DidHit() || exitTrace.startsolid)
{
if (exitTrace.hit_entity && BreakableEntity((player_t*)enterTrace.hit_entity))
{
exitTrace = enterTrace;
exitTrace.endpos = start + direction;
return true;
}
continue;
}
}
}
return false;
}
void autowall::TraceLine(Vector& start, Vector& end, unsigned int mask, player_t* ignore, CGameTrace* trace)
{
Ray_t ray;
ray.Init(start, end);
CTraceFilter filter;
filter.pSkip = ignore;
m_trace()->TraceRay(ray, mask, &filter, trace);
}
void autowall::ClipTrace(Vector& start, Vector& end, player_t* e, unsigned int mask, CTraceFilter* filter, CGameTrace* old_trace)
{
if (!e)
return;
Vector mins = e->GetCollideable()->OBBMins(), maxs = e->GetCollideable()->OBBMaxs();
Vector dir(end - start);
dir = dir.Normalized();
Vector center = (maxs + mins) / 2, pos(center + e->m_vecOrigin());
Vector to = pos - start;
float range_along = dir.Dot(to);
float range;
if (range_along < 0.f)
{
range = -to.Length();
}
else if (range_along > dir.Length())
{
range = -(pos - end).Length();
}
else
{
auto ray(pos - (dir * range_along + start));
range = ray.Length();
}
if (range <= 60.f)
{
CGameTrace trace;
Ray_t ray;
ray.Init(start, end);
m_trace()->ClipRayToEntity(ray, mask, e, &trace);
if (old_trace->fraction > trace.fraction) *old_trace = trace;
}
}
bool autowall::CanHitFloatingPoint(const Vector& point, const Vector& source) {
FireBulletData_t data;
data.m_start = source;
data.m_filter = new CTraceFilter();
data.m_filter->pSkip = g_ctx.local();
Vector angles = math::calculate_angle(data.m_start, point);
math::AngleVectorszae(angles, data.m_direction);
data.m_direction = data.m_direction.NormalizeInPlacega();
data.m_penetration_count = 1;
auto weaponData = g_ctx.globals.weapon->get_csweapon_info();
if (!weaponData)
return false;
data.m_current_damage = (float)weaponData->iDamage;
Vector end = data.m_start + (data.m_direction * weaponData->flRange);
TraceLine(data.m_start, end, MASK_SHOT_HULL | CONTENTS_HITBOX, g_ctx.local(), &data.m_enter_trace);
if (VectortoVectorVisible(data.m_start, point) || HandleBulletPenetration(weaponData, data, true, point))
return true;
return false;
}
Код:
#pragma once
#include "..\..\includes.hpp"
class weapon_info_t;
class weapon_t;
struct fire_bullet_data
{
Vector src;
trace_t enter_trace;
Vector direction;
CTraceFilter filter;
float trace_length;
float trace_length_remaining;
float current_damage;
int penetrate_count;
};
#define DAMAGE_NO 0
#define DAMAGE_EVENTS_ONLY 1
#define DAMAGE_YES 2
#define DAMAGE_AIM 3
struct ReturnInfo_t
{
int m_damage;
int m_hitgroup;
int m_hitbox;
int m_penetration_count;
bool visible;
float m_thickness;
Vector m_end;
player_t* m_hit_entity;
ReturnInfo_t(int damage, int hitgroup, int penetration_count, float thickness, player_t* hit_entity)
{
m_damage = damage;
m_hitgroup = hitgroup;
m_penetration_count = penetration_count;
m_thickness = thickness;
m_hit_entity = hit_entity;
}
};
class autowall : public singleton <autowall>
{
public:
std::vector<std::pair<Vector, float>> scanned_points;
struct FireBulletData_t
{
Vector m_start;
Vector m_end;
Vector m_current_position;
Vector m_direction;
CTraceFilter* m_filter;
CGameTrace m_enter_trace;
float m_current_damage;
int m_penetration_count;
};
void ScaleDamage(player_t* e, weapon_info_t* weapon_info, int hitgroup, float& current_damage);
bool VectortoVectorVisible(Vector src, Vector point);
bool BreakableEntity(player_t* entity);
bool TraceToExit(CGameTrace& enterTrace, CGameTrace& exitTrace, Vector startPosition, Vector direction);
void TraceLine(Vector& start, Vector& end, unsigned int mask, player_t* ignore, CGameTrace* trace);
void ClipTrace(Vector& start, Vector& end, player_t* e, unsigned int mask, CTraceFilter* filter, CGameTrace* old_trace);
float HitgroupDamage(int iHitGroup);
bool IsArmored(player_t* player, int hitgroup);
inline void reset() {
scanned_points.clear();
}
bool HandleBulletPenetration(weapon_info_t* info, FireBulletData_t& data, bool extracheck = false, Vector point = Vector(0, 0, 0));
bool CanHitFloatingPoint(const Vector& point, const Vector& source);
ReturnInfo_t Think(Vector pos, player_t* target, int specific_hitgroup = -1, Vector eye_pos = ZERO, player_t* start_ent = nullptr);
};