diff --git a/Extended_Interface.hpp b/Extended_Interface.hpp index 69662fd..0e6db9e 100755 --- a/Extended_Interface.hpp +++ b/Extended_Interface.hpp @@ -25,6 +25,8 @@ Interface_Structure Interface_Penetrate_Teammates; Interface_Structure Interface_Aim_Intersection; +Interface_Structure Interface_Penetration_Damage; + Interface_Structure Interface_Equipment_Distance; Interface_Structure Interface_Storm_Rotation_Radius; @@ -64,6 +66,8 @@ void Implement_Extended_Interface() Create_Console_Interface(Pointer_Name(Interface_Aim_Intersection), (char*)"1", nullptr); + Create_Console_Interface(Pointer_Name(Interface_Penetration_Damage), (char*)"25", nullptr); + Create_Console_Interface(Pointer_Name(Interface_Equipment_Distance), (char*)"2048", nullptr); Create_Console_Interface(Pointer_Name(Interface_Storm_Rotation_Radius), (char*)"24", nullptr); diff --git a/Perform_Shove_Trace.hpp b/Perform_Shove_Trace.hpp index c2e0689..efdbd40 100755 --- a/Perform_Shove_Trace.hpp +++ b/Perform_Shove_Trace.hpp @@ -12,12 +12,12 @@ void* Original_Perform_Shove_Trace_Caller; void __declspec(naked) Redirected_Perform_Shove_Trace() { - asm("lea -304(%ebp), %eax"); - asm("push %eax"); - asm("call *%edx"); - asm("pusha"); - asm("mov %esp, %ecx"); + asm("leal -304(%ebp), %eax"); + asm("pushl %eax"); + asm("calll *%edx"); + asm("pushal"); + asm("movl %esp, %ecx"); asm("calll %0" : : "m"(Perform_Shove_Trace)); - asm("popa"); - asm("jmp *%0" : : "m"(Original_Perform_Shove_Trace_Caller)); + asm("popal"); + asm("jmpl *%0" : : "m"(Original_Perform_Shove_Trace_Caller)); } \ No newline at end of file diff --git a/Perform_Trace.hpp b/Perform_Trace.hpp index 31bdf1c..cf9b8fc 100755 --- a/Perform_Trace.hpp +++ b/Perform_Trace.hpp @@ -1,5 +1,24 @@ void* Perform_Trace_Target; +__declspec(noinline) float Calculate_Damage(void* Weapon_Data, float Distance) +{ + static void* Calculate_Damage = (void*)((unsigned __int32)GetModuleHandleW(L"server.dll") + 3950416); + + float Damage; + + asm("pushl %esi"); + asm("movl %0, %%esi" : : "m"(Weapon_Data)); + asm("subl $16, %esp"); + asm("movss %0, %%xmm0" : : "m"(Distance) : "esp"); + asm("movdqu %xmm0, (%esp)"); + asm("calll *%0" : : "m"(Calculate_Damage)); + asm("movd %%xmm0, %0" : "=m"(Damage)); + asm("addl $16, %esp"); + asm("popl %esi"); + + return Damage; +} + float Vector_Normalize(float* Vector) { using Vector_Normalize_Type = float(__thiscall*)(float* Vector); @@ -33,22 +52,97 @@ void __thiscall Perform_Trace(void* Stack) if (Entity == (void*)((unsigned __int32)Perform_Trace_Target ^ 1)) { + __int32 Group = *(__int32*)((unsigned __int32)Stack + 304); + if (Interface_Aim_Intersection.Integer == 0) { - if (*(__int32*)((unsigned __int32)Stack + 304) != 1) + if (Group != 1) { return; } } + float* End = (float*)((unsigned __int32)Stack + 248); + void* Trace_Information = *(void**)((unsigned __int32)Stack + 36); + if (Interface_Penetration_Damage.Integer != 0) //that's very cutted version of actual function [*::TraceAttack] + { + float* Start = (float*)((unsigned __int32)Stack + 236); + + float Damage = Calculate_Damage(*(void**)((unsigned __int32)Trace_Information + 4), __builtin_sqrtf(__builtin_powf(End[0] - Start[0], 2) + __builtin_powf(End[1] - Start[1], 2) + __builtin_powf(End[2] - Start[2], 2))); + + __int32 Identifier = Get_Identifier(Entity, 1, 0); + + auto Apply_Difficulty_Scaling = [&]() -> void + { + using Get_Difficulty_Type = __int32(__cdecl*)(); + + //z_non_head_damage_factor_* (non-replicated unfortunately) + //assuming "z_use_next_difficulty_damage_factor" is "1" and "maxplayers" is not "1" + float Multipliers[4] = { 0.8f, 0.7f, 0.6f, 1.f }; + + Damage *= Multipliers[Get_Difficulty_Type((unsigned __int32)Client_Module + 2650448)()]; + }; + + if (Identifier == 277) //special scaling used by witches + { + if (Group != 1) + { + Apply_Difficulty_Scaling(); + } + } + else + { + if (Identifier == 264) //special scaling used by common infected + { + if (Identifier * Group == 264) //these are killed instantly on headshot + { + Damage = FLT_MAX; + } + else + { + Apply_Difficulty_Scaling(); + + //tbi: some guns are using special scaling (e.g. deagle) + } + } + else //special scaling used by non-common infected + { + if (*(__int32*)((unsigned __int32)Trace_Information + 36) != -2139094974) //explosives are doing "radial" damage instead + { + if (Identifier != 276) //tanks aren't scaled + { + Damage *= 1.f + 3.f * (Group == 1) + 0.25f * (Group == 3) - 0.25f * (Group == 7); //or: 0.25f * ((Group == 3) + -(Group == 7)) + + if (Identifier * Group == 270) //killed instantly on **hooked** headshot + { + if (*(void**)((unsigned __int32)Entity + 8040) != INVALID_HANDLE_VALUE) + { + Damage = FLT_MAX; + } + } + } + } + + Damage = (__int32)(Damage + 1.f * (Damage < 1)); //rounding isn't applied to common infected or witches. make sure damage isn't zero before rounding + } + + //actual shotgun multiplications (z_shotgun_bonus_damage_multiplier, z_shotgun_bonus_damage_range) would require extraneous tracing... so they're not here for moment + } + + wprintf(L"hitgroup %d -> damage %f\n", Group, Damage); //compared to 'picker' output (along with nb_stop 1), since it's unfinished feature + + if (Damage < Interface_Penetration_Damage.Floating_Point) + { + return; + } + } + if ((*(__int32*)((unsigned __int32)Trace_Information + 36) & 255) + *(__int32*)((unsigned __int32)Entity + 52) == 17) { float Inflictor_Direction[3]; - float* End = (float*)((unsigned __int32)Stack + 248); - using Get_Center_Type = float*(__thiscall*)(void* Entity); float* Start = Get_Center_Type((unsigned __int32)Client_Module + 114400)(*(void**)Trace_Information); @@ -89,9 +183,9 @@ void* Original_Perform_Trace_Caller; void __declspec(naked) Redirected_Perform_Trace() { - asm("pusha"); - asm("mov %esp, %ecx"); + asm("pushal"); + asm("movl %esp, %ecx"); asm("calll %0" : : "m"(Perform_Trace)); - asm("popa"); - asm("jmp *%0" : : "m"(Original_Perform_Trace_Caller)); + asm("popal"); + asm("jmpl *%0" : : "m"(Original_Perform_Trace_Caller)); } \ No newline at end of file