char __fastcall HandleBulletPenetration(
__int64 a1,
struct_trace *trace,
struct_a3 *a3,
int a4,
int *sv_showimpacts_penetration)
{
float current_distance; // xmm8_4
float v9; // xmm6_4
float v10; // xmm0_4
char result; // al
__int64 v12; // rbx
__int64 v13; // rsi
int v14; // eax
__int64 v15; // r9
__int64 *v16; // r14
__int64 v17; // r14
char v18; // al
__int64 v19; // rcx
__int64 v20; // rax
__int64 v21; // rax
__int64 v22; // rax
int enter_material; // r14d
float final_damage_bullet_pen; // xmm7_4
int penetration_count; // eax
char failed_penetrate; // si
float v27; // xmm12_4
float v28; // xmm13_4
float v29; // xmm11_4
float v30; // xmm8_4
float v31; // xmm9_4
float v32; // xmm6_4
float v33; // xmm10_4
float v34; // xmm7_4
float v35; // xmm10_4
__int64 v36; // rdx
float v37; // xmm0_4
int exit_material; // r12d
float *ff_damage_reduction_bullets; // rax
float *ff_damage_bullet_penetration; // rax
float *ff_damage_bullet_penetration_0; // rax
__int64 v42; // rsi
__int64 v43; // r14
__int64 v44; // rbx
__int64 v45; // rax
__int64 v46; // rax
float pen_mod; // xmm1_4
float pen_wep_mod; // xmm7_4
float total_lost_dmg; // xmm6_4
__int64 v50; // rdx
float v51; // ecx
float v52; // eax
float current_dmg; // xmm0_4
__int64 v54; // [rsp+28h] [rbp-E0h]
float v55; // [rsp+30h] [rbp-D8h]
__int64 filter_2; // [rsp+38h] [rbp-D0h] BYREF
__int64 v57; // [rsp+40h] [rbp-C8h]
__int64 v58; // [rsp+88h] [rbp-80h]
__int64 v59; // [rsp+90h] [rbp-78h]
__int64 v60; // [rsp+98h] [rbp-70h]
int v61; // [rsp+A0h] [rbp-68h]
int v62; // [rsp+A4h] [rbp-64h]
int v63; // [rsp+A8h] [rbp-60h]
__int64 v64; // [rsp+BCh] [rbp-4Ch]
float v65; // [rsp+C4h] [rbp-44h]
__int64 filter[13]; // [rsp+F8h] [rbp-10h] BYREF
int v67; // [rsp+160h] [rbp+58h]
int v68; // [rsp+164h] [rbp+5Ch]
int v69; // [rsp+168h] [rbp+60h]
__int64 v70; // [rsp+17Ch] [rbp+74h]
float v71; // [rsp+184h] [rbp+7Ch]
unsigned int v72; // [rsp+290h] [rbp+188h] BYREF
int v73; // [rsp+298h] [rbp+190h]
int v74; // [rsp+2A0h] [rbp+198h]
v74 = a4;
current_distance = trace->floatC * a3->float4;
if ( (a3->byte14 & 1) == 0 )
{
v9 = trace->float0;
v10 = V_powf();
result = 0;
trace->float0 = v10 * v9;
return result;
}
v12 = 0i64;
v13 = *(a1 + 8) + 48i64 * (a3->word10 & 0x7FFF);
v14 = *(v13 + 36);
if ( v14 != -1
&& qword_18176D428
&& v14 != -2
&& (v15 = *(qword_18176D428 + 8 * ((v14 & 0x7FFF) >> 9))) != 0
&& (v16 = (v15 + 120i64 * (v14 & 0x1FF))) != 0i64
&& *(v16 + 4) == v14 )
{
v17 = *v16;
}
else
{
v17 = 0i64;
}
v18 = *(v13 + 43);
if ( v18 == 1 )
{
if ( v17 && (*(*v17 + 416i64))(v17) )
(*(*v17 + 416i64))(v17);
}
else if ( !v18 )
{
v19 = *(v13 + 24);
if ( v19 )
(*(*v19 + 144i64))(v19);
}
v20 = (*(*qword_181970F80 + 136i64))(qword_181970F80);
v21 = (*(*v20 + 24i64))(v20, *(v13 + 40));
v22 = sub_1805EE840(v21);
enter_material = *(v22 + 20);
v73 = enter_material;
final_damage_bullet_pen = *(v22 + 8);
if ( current_distance > 3000.0 || final_damage_bullet_pen < 0.1 )
trace->penetration_count = 0;
penetration_count = trace->penetration_count;
if ( !penetration_count || (failed_penetrate = 0, penetration_count <= 0) )
failed_penetrate = 1;
memset(&filter[10], 0, 24);
v69 = 0x7000000; // mask
v67 = 0;
v68 = -1;
sub_180EAC730(filter);
TraceRay(a1, filter, a3->float0, (*(a1 + 8) + 48i64 * a3->unsigned___int1612));
v58 = 0i64;
v59 = 0i64;
v60 = 0i64;
v63 = 0x7000000;
v61 = 0;
v62 = -1;
sub_180EAC730(&filter_2);
TraceRay(a1, &filter_2, 0.0, (*(a1 + 8) + 48i64 * (a3->word10 & 0x7FFF)));
v27 = *&v70;
v28 = *(&v70 + 1);
v29 = v71;
v54 = v70;
v55 = v71;
if ( failed_penetrate == 1 )
{
// store some data for impacts
if ( sv_showimpacts_penetration )
{
v30 = *&v70 - *&v64;
v31 = *(&v70 + 1) - *(&v64 + 1);
v32 = v71 - v65;
v33 = 1.0 / final_damage_bullet_pen;
v34 = trace->float0 * 0.15000001;
v35 = fmaxf(v33, 0.0);
v36 = sub_180504B20(sv_showimpacts_penetration);
*v36 = v64;
*(v36 + 8) = v65;
*(v36 + 12) = v70;
*(v36 + 20) = v71;
*(v36 + 24) = fsqrt(
(((v29 - v65) * (v29 - v65)) + ((v28 - *(&v64 + 1)) * (v28 - *(&v64 + 1))))
+ ((v27 - *&v64) * (v27 - *&v64)));
*(v36 + 28) = trace->float0;
v37 = ((fmaxf(3.54 / trace->float4, 0.0) * v35) * 2.8) + v34;
*(v36 + 32) = v37;
*(v36 + 36) = (((((v31 * v31) + (v32 * v32)) + (v30 * v30)) * v35) * 0.041666668) + v37;
*(v36 + 40) = filter_2;
result = 1;
*(v36 + 48) = 0i64;
trace->failed = 1;
return result;
}
goto LABEL_54;
}
exit_material = *(sub_1805EE840(filter[0]) + 20);
if ( v57 && (*(*v57 + 1144i64))(v57) )
v12 = v57;
if ( enter_material != 70 )
goto LABEL_42;
ff_damage_reduction_bullets = sub_18105A2A0(&::ff_damage_reduction_bullets, -1);
if ( !ff_damage_reduction_bullets )
ff_damage_reduction_bullets = *(qword_1817D5198 + 8);
if ( *ff_damage_reduction_bullets == 0.0 && v12 && (sub_180D9B240(v12, &v72), !Player::IsEnemy(v72, v74)) )
{
ff_damage_bullet_penetration = sub_18105A2A0(&::ff_damage_bullet_penetration, -1);
if ( !ff_damage_bullet_penetration )
ff_damage_bullet_penetration = *(qword_1817D51B8 + 8);
if ( *ff_damage_bullet_penetration == 0.0 )
goto LABEL_54;
ff_damage_bullet_penetration_0 = sub_18105A2A0(&::ff_damage_bullet_penetration, -1);
if ( !ff_damage_bullet_penetration_0 )
ff_damage_bullet_penetration_0 = *(qword_1817D51B8 + 8);
final_damage_bullet_pen = *ff_damage_bullet_penetration_0;
}
else
{
LABEL_42:
v42 = a3->word10 & 0x7FFF;
if ( v42 <= a3->unsigned___int1612 )
{
v43 = 48 * v42;
do
{
v44 = *(a1 + 8);
v45 = (*(*qword_181970F80 + 136i64))(qword_181970F80);
v46 = (*(*v45 + 24i64))(v45, *(v43 + v44 + 40));
LODWORD(v42) = v42 + 1;
v43 += 48i64;
final_damage_bullet_pen = fminf(*(sub_1805EE840(v46) + 8), final_damage_bullet_pen);
}
while ( v42 <= a3->unsigned___int1612 );
enter_material = v73;
}
}
if ( enter_material == exit_material )
{
if ( ((exit_material - 85) & 0xFFFFFFFD) != 0 )
{
if ( exit_material == 76 )
final_damage_bullet_pen = 2.0;
}
else
{
final_damage_bullet_pen = 3.0;
}
}
pen_mod = fmaxf(1.0 / final_damage_bullet_pen, 0.0);
pen_wep_mod = ((fmaxf(3.75 / trace->float4, 0.0) * pen_mod) * 3.0) + (trace->float0 * 0.16);
total_lost_dmg = ((((((v71 - v65) * (v71 - v65)) + ((*(&v70 + 1) - *(&v64 + 1)) * (*(&v70 + 1) - *(&v64 + 1))))
+ ((*&v70 - *&v64) * (*&v70 - *&v64)))
* pen_mod)
* 0.041666668)
+ pen_wep_mod;
// store some data for impacts
if ( sv_showimpacts_penetration )
{
v50 = sub_180504B20(sv_showimpacts_penetration);
*v50 = v64;
v51 = v65;
*(v50 + 12) = v54;
*(v50 + 8) = v51;
*(v50 + 20) = v55;
*(v50 + 24) = fsqrt(
(((v29 - v65) * (v29 - v65)) + ((v28 - *(&v64 + 1)) * (v28 - *(&v64 + 1))))
+ ((v27 - *&v64) * (v27 - *&v64)));
v52 = trace->float0;
*(v50 + 32) = pen_wep_mod;
*(v50 + 36) = total_lost_dmg;
*(v50 + 28) = v52;
*(v50 + 40) = filter_2;
*(v50 + 48) = filter[0];
}
current_dmg = trace->float0 - fmaxf(total_lost_dmg, 0.0);
trace->float0 = current_dmg;
if ( current_dmg < 1.0 )
{
LABEL_54:
trace->failed = 1;
return 1;
}
--trace->penetration_count;
result = 0;
trace->failed = 0;
return result;
}