diff --git a/SilentPatch/Maths.h b/SilentPatch/Maths.h index cef91ee..36245eb 100644 --- a/SilentPatch/Maths.h +++ b/SilentPatch/Maths.h @@ -1,10 +1,12 @@ -#ifndef __MATHS__H -#define __MATHS__H +#pragma once + +#define _USE_MATH_DEFINES +#include #include -constexpr double RAD_TO_DEG (180.0/3.1415926535897932385); -constexpr double DEG_TO_RAD (3.1415926535897932385/180.0); +constexpr double RAD_TO_DEG (180.0/M_PI); +constexpr double DEG_TO_RAD (M_PI/180.0); class CRGBA { @@ -515,4 +517,56 @@ inline CVector& CVector::FromMultiply3X3(const CMatrix& mat, const CVector& vec) return *this = Multiply3x3(mat, vec); } -#endif \ No newline at end of file +class CGeneral +{ +public: + static float GetRadianAngleBetweenPoints(float x1, float y1, float x2, float y2) + { + float x = x2 - x1; + float y = y2 - y1; + + if (y == 0.0f) + { + y = 0.0001f; + } + + if (x > 0.0f) + { + if (y > 0.0f) + { + return static_cast(M_PI - std::atan2(x / y, 1.0f)); + } + else + { + return -std::atan2(x / y, 1.0f); + } + } + else + { + if (y > 0.0f) + { + return -static_cast(M_PI + std::atan2(x / y, 1.0f)); + } + else + { + return -std::atan2(x / y, 1.0f); + } + } + } + + static float LimitRadianAngle(float angle) + { + while (angle >= M_PI) + { + angle -= static_cast(2.0f * M_PI); + } + + while (angle < -M_PI) + { + angle += static_cast(2.0f * M_PI); + } + + return angle; + } + +}; \ No newline at end of file diff --git a/SilentPatchIII/SilentPatchIII.cpp b/SilentPatchIII/SilentPatchIII.cpp index ffed668..1838b7c 100644 --- a/SilentPatchIII/SilentPatchIII.cpp +++ b/SilentPatchIII/SilentPatchIII.cpp @@ -544,6 +544,35 @@ namespace SkinTextureFilter } +// ============= Fix the evasive dive miscalculating the angle, resulting in peds diving towards the vehicle ============= +namespace EvasiveDiveFix +{ + static float CalculateAngle(float x, float y) + { + float angle = static_cast(CGeneral::GetRadianAngleBetweenPoints(x, y, 0.0f, 0.0f) - M_PI_2); + if ((rand() & 1) != 0) + { + angle += static_cast(M_PI); + } + return CGeneral::LimitRadianAngle(angle); + } + + __declspec(naked) void CalculateAngle_Hook() + { + _asm + { + push dword ptr [esi+7Ch] + push dword ptr [esi+78h] + call CalculateAngle + add esp, 8 + + mov ecx, ebp + retn + } + } +} + + void InjectDelayedPatches_III_Common( bool bHasDebugMenu, const wchar_t* wcModulePath ) { using namespace Memory; @@ -1353,6 +1382,17 @@ void Patch_III_Common() InterceptCall(setEnvironmentMap, CVehicleModelInfo::orgSetEnvironmentMap, &CVehicleModelInfo::SetEnvironmentMap_ExtraComps); } + + + // Fix the evasive dive miscalculating the angle, resulting in peds diving towards the vehicle + { + using namespace EvasiveDiveFix; + + auto setEvasiveDive = pattern("D9 44 24 10 89 E9 D9 9D ? ? ? ? E8 ? ? ? ? 89 E9 E8 ? ? ? ? 89 E9 E8 ? ? ? ? C7 85").get_one(); + + Nop(setEvasiveDive.get(), 1); + InjectHook(setEvasiveDive.get(1), &CalculateAngle_Hook, HookType::Call); + } } BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)