diff --git a/SilentPatch/StdAfx.h b/SilentPatch/StdAfx.h index d72b7dd..fff2905 100644 --- a/SilentPatch/StdAfx.h +++ b/SilentPatch/StdAfx.h @@ -13,4 +13,47 @@ #include "MemoryMgr.h" +class CVector +{ +public: + float x, y, z; + + CVector() + {} + + constexpr CVector(float fX, float fY, float fZ=0.0f) + : x(fX), y(fY), z(fZ) + {} + + CVector& operator+=(const CVector& vec) + { x += vec.x; y += vec.y; z += vec.z; + return *this; } + CVector& operator-=(const CVector& vec) + { x -= vec.x; y -= vec.y; z -= vec.z; + return *this; } + + inline float Magnitude() const + { return sqrt(x * x + y * y + z * z); } + inline constexpr float MagnitudeSqr() const + { return x * x + y * y + z * z; } + inline CVector& Normalize() + { float fInvLen = 1.0f / Magnitude(); x *= fInvLen; y *= fInvLen; z *= fInvLen; return *this; } + + friend inline float DotProduct(const CVector& vec1, const CVector& vec2) + { return vec1.x * vec2.x + vec1.x * vec2.y + vec1.z * vec2.z; } + friend inline CVector CrossProduct(const CVector& vec1, const CVector& vec2) + { return CVector( vec1.y * vec2.z - vec1.z * vec2.y, + vec1.z * vec2.x - vec1.x * vec2.z, + vec1.x * vec2.y - vec1.y * vec2.x); } + + friend inline CVector operator*(const CVector& in, float fMul) + { return CVector(in.x * fMul, in.y * fMul, in.z * fMul); } + friend inline CVector operator+(const CVector& vec1, const CVector& vec2) + { return CVector(vec1.x + vec2.x, vec1.y + vec2.y, vec1.z + vec2.z); } + friend inline CVector operator-(const CVector& vec1, const CVector& vec2) + { return CVector(vec1.x - vec2.x, vec1.y - vec2.y, vec1.z - vec2.z); } + friend inline CVector operator-(const CVector& vec) + { return CVector(-vec.x, -vec.y, -vec.z); } +}; + #define DISABLE_FLA_DONATION_WINDOW 0 diff --git a/SilentPatchVC/SilentPatchVC.cpp b/SilentPatchVC/SilentPatchVC.cpp index 73be1a3..4f609bd 100644 --- a/SilentPatchVC/SilentPatchVC.cpp +++ b/SilentPatchVC/SilentPatchVC.cpp @@ -188,6 +188,16 @@ void GaragesInit_SilentPatch() RespraysAreFree = false; } +static void (*orgPickNextNodeToChaseCar)(void*, float, float, void*); +static float PickNextNodeToChaseCarZ = 0.0f; +static void PickNextNodeToChaseCarXYZ( void* vehicle, const CVector& vec, void* chaseTarget ) +{ + PickNextNodeToChaseCarZ = vec.z; + orgPickNextNodeToChaseCar( vehicle, vec.x, vec.y, chaseTarget ); + PickNextNodeToChaseCarZ = 0.0f; +} + + static char aNoDesktopMode[64]; unsigned int __cdecl AutoPilotTimerCalculation_VC(unsigned int nTimer, int nScaleFactor, float fScaleCoef) @@ -648,6 +658,41 @@ void Patch_VC_Common() auto sum = get_pattern( "D9 9C 24 A8 00 00 00 8D 84 24 A8 00 00 00 50", -6 + 2 ); Patch( sum, &METERS_TO_MILES ); } + + // Improved pathfinding in PickNextNodeAccordingStrategy - PickNextNodeToChaseCar with XYZ coords + { + auto addr = pattern( "E8 ? ? ? ? 50 8D 44 24 10 50 E8" ).get_one(); + ReadCall( addr.get( 0x25 ), orgPickNextNodeToChaseCar ); + + const uintptr_t funcAddr = (uintptr_t)get_pattern( "8B 9C 24 BC 00 00 00 66 8B B3 A6 01 00 00 66 85 F6", -0xA ); + InjectHook( funcAddr - 5, PickNextNodeToChaseCarXYZ, PATCH_JUMP ); // For plugin-sdk + + // push PickNextNodeToChaseCarZ instead of 0.0f + // mov ecx, [PickNextNodeToChaseCarZ] + // mov [esp+0B8h+var_2C], ecx + Patch( funcAddr + 0x5D, { 0x8B, 0x0D } ); + Patch( funcAddr + 0x5D + 2, &PickNextNodeToChaseCarZ ); + Patch( funcAddr + 0x5D + 6, { 0x89, 0x8C, 0x24, 0x8C, 0x00, 0x00, 0x00 } ); + + // lea eax, [ecx+edx*4] -> lea eax, [edx+edx*4] + Patch( funcAddr + 0x6E + 2, 0x92 ); + + + // lea eax, [esp+20h+var_10] + // push eax + // nop... + Patch( addr.get( 0x10 ), { 0x83, 0xC4, 0x04, 0x8D, 0x44, 0x24, 0x10, 0x50, 0xEB, 0x0A } ); + InjectHook( addr.get( 0x25 ), PickNextNodeToChaseCarXYZ ); + Patch( addr.get( 0x2A + 2 ), 0xC ); + + // push edx + // nop... + Patch( addr.get( 0x3E ), 0x52 ); + Nop( addr.get( 0x3E + 1 ), 6 ); + InjectHook( addr.get( 0x46 ), PickNextNodeToChaseCarXYZ ); + Patch( addr.get( 0x4B + 2 ), 0xC ); + } + } BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)