mirror of
https://github.com/CookiePLMonster/SilentPatch.git
synced 2024-12-29 15:23:02 +05:00
Migrate to transactional patterns
This commit is contained in:
parent
6ee676400b
commit
d4374df50a
9 changed files with 706 additions and 439 deletions
|
@ -75,7 +75,6 @@
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<AdditionalIncludeDirectories>..\SilentPatch;..\DDraw;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\SilentPatch;..\DDraw;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<ExceptionHandling>false</ExceptionHandling>
|
|
||||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
<EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
|
<EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
|
||||||
<EnforceTypeConversionRules>true</EnforceTypeConversionRules>
|
<EnforceTypeConversionRules>true</EnforceTypeConversionRules>
|
||||||
|
@ -107,7 +106,6 @@ copy /y "$(TargetPath)" "D:\Steam\steamapps\common\Grand Theft Auto Vice City\dd
|
||||||
<AdditionalIncludeDirectories>..\SilentPatch;..\DDraw;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\SilentPatch;..\DDraw;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<StringPooling>true</StringPooling>
|
<StringPooling>true</StringPooling>
|
||||||
<ExceptionHandling>false</ExceptionHandling>
|
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
<EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
|
<EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
|
||||||
<EnforceTypeConversionRules>true</EnforceTypeConversionRules>
|
<EnforceTypeConversionRules>true</EnforceTypeConversionRules>
|
||||||
|
@ -141,7 +139,6 @@ copy /y "$(TargetPath)" "D:\Steam\steamapps\common\Grand Theft Auto Vice City\dd
|
||||||
<AdditionalIncludeDirectories>..\SilentPatch;..\DDraw;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\SilentPatch;..\DDraw;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>_HAS_EXCEPTIONS=0;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_HAS_EXCEPTIONS=0;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<StringPooling>true</StringPooling>
|
<StringPooling>true</StringPooling>
|
||||||
<ExceptionHandling>false</ExceptionHandling>
|
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
<EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
|
<EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
|
||||||
<EnforceTypeConversionRules>true</EnforceTypeConversionRules>
|
<EnforceTypeConversionRules>true</EnforceTypeConversionRules>
|
||||||
|
|
|
@ -208,30 +208,38 @@ namespace Common {
|
||||||
void III_VC_Common()
|
void III_VC_Common()
|
||||||
{
|
{
|
||||||
using namespace Memory;
|
using namespace Memory;
|
||||||
using namespace hook;
|
using namespace hook::txn;
|
||||||
|
|
||||||
// Delayed patching
|
// Delayed patching
|
||||||
|
try
|
||||||
{
|
{
|
||||||
using namespace DelayedPatches;
|
using namespace DelayedPatches;
|
||||||
|
|
||||||
auto addr_mssHook = get_pattern( "6A 00 6A 02 6A 10 68 00 7D 00 00", -6 + 2 );
|
auto addr_mssHook = get_pattern( "6A 00 6A 02 6A 10 68 00 7D 00 00", -6 + 2 );
|
||||||
|
auto addr_ualHook = get_pattern( "FF 15 ? ? ? ? 6A 00 6A 18", 0xA );
|
||||||
|
|
||||||
OldSetPreference = *static_cast<decltype(OldSetPreference)*>(addr_mssHook);
|
OldSetPreference = *static_cast<decltype(OldSetPreference)*>(addr_mssHook);
|
||||||
Patch( addr_mssHook, &pInjectMSS );
|
Patch( addr_mssHook, &pInjectMSS );
|
||||||
|
|
||||||
auto addr_ualHook = get_pattern( "FF 15 ? ? ? ? 6A 00 6A 18", 0xA );
|
|
||||||
ReadCall( addr_ualHook, RsEventHandler );
|
ReadCall( addr_ualHook, RsEventHandler );
|
||||||
InjectHook( addr_ualHook, Inject_UAL );
|
InjectHook( addr_ualHook, Inject_UAL );
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Fixed bomb ownership/bombs saving for bikes
|
// Fixed bomb ownership/bombs saving for bikes
|
||||||
|
try
|
||||||
{
|
{
|
||||||
auto addr = get_pattern( "83 3C 33 00 74 19 89 F9 E8", 8 );
|
auto addr = get_pattern( "83 3C 33 00 74 19 89 F9 E8", 8 );
|
||||||
|
|
||||||
ReadCall( addr, CStoredCar::orgRestoreCar );
|
ReadCall( addr, CStoredCar::orgRestoreCar );
|
||||||
InjectHook( addr, &CStoredCar::RestoreCar_SilentPatch );
|
InjectHook( addr, &CStoredCar::RestoreCar_SilentPatch );
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Fixed handling.cfg name matching (names don't need unique prefixes anymore)
|
// Fixed handling.cfg name matching (names don't need unique prefixes anymore)
|
||||||
|
try
|
||||||
{
|
{
|
||||||
using namespace HandlingNameLoadFix;
|
using namespace HandlingNameLoadFix;
|
||||||
|
|
||||||
|
@ -240,9 +248,11 @@ namespace Common {
|
||||||
InjectHook( findExactWord.get<void>( -5 ), strncpy_Fix );
|
InjectHook( findExactWord.get<void>( -5 ), strncpy_Fix );
|
||||||
InjectHook( findExactWord.get<void>( 0xD ), strncmp_Fix );
|
InjectHook( findExactWord.get<void>( 0xD ), strncmp_Fix );
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Fixed corona lines rendering on non-nvidia cards
|
// Fixed corona lines rendering on non-nvidia cards
|
||||||
|
try
|
||||||
{
|
{
|
||||||
using namespace CoronaLinesFix;
|
using namespace CoronaLinesFix;
|
||||||
|
|
||||||
|
@ -250,9 +260,11 @@ namespace Common {
|
||||||
|
|
||||||
InterceptCall(renderLine, orgRwIm2DRenderLine, RenderLine_SetRecipZ);
|
InterceptCall(renderLine, orgRwIm2DRenderLine, RenderLine_SetRecipZ);
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Fixed static shadows not rendering under fire and pickups
|
// Fixed static shadows not rendering under fire and pickups
|
||||||
|
try
|
||||||
{
|
{
|
||||||
using namespace StaticShadowAlphaFix;
|
using namespace StaticShadowAlphaFix;
|
||||||
|
|
||||||
|
@ -281,9 +293,11 @@ namespace Common {
|
||||||
HookEach_StoreAlphaTest(disableAlphaTestAndSetState, InterceptCall);
|
HookEach_StoreAlphaTest(disableAlphaTestAndSetState, InterceptCall);
|
||||||
HookEach_RestoreAlphaTest(setStateAndReenableAlphaTest, InterceptCall);
|
HookEach_RestoreAlphaTest(setStateAndReenableAlphaTest, InterceptCall);
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Reset requested extras if created vehicle has no extras
|
// Reset requested extras if created vehicle has no extras
|
||||||
|
try
|
||||||
{
|
{
|
||||||
using namespace CompsToUseFix;
|
using namespace CompsToUseFix;
|
||||||
|
|
||||||
|
@ -291,10 +305,12 @@ namespace Common {
|
||||||
InjectHook( resetComps.get<void>( -14 ), ResetCompsForNoExtras, HookType::Call );
|
InjectHook( resetComps.get<void>( -14 ), ResetCompsForNoExtras, HookType::Call );
|
||||||
Nop( resetComps.get<void>( -9 ), 9 );
|
Nop( resetComps.get<void>( -9 ), 9 );
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Rescale light switching randomness in CAutomobile::PreRender/CBike::PreRender for PC the randomness range
|
// Rescale light switching randomness in CAutomobile::PreRender/CBike::PreRender for PC the randomness range
|
||||||
// The original randomness was 50000 out of 65535, which is impossible to hit with PC's 32767 range
|
// The original randomness was 50000 out of 65535, which is impossible to hit with PC's 32767 range
|
||||||
|
try
|
||||||
{
|
{
|
||||||
// GTA III expects 2 matches, VC expects 4 due to the addition of CBike::PreRender
|
// GTA III expects 2 matches, VC expects 4 due to the addition of CBike::PreRender
|
||||||
#if _GTA_III
|
#if _GTA_III
|
||||||
|
@ -310,9 +326,11 @@ namespace Common {
|
||||||
Patch<const void*>(match.get<void>(2), &LightStatusRandomnessThreshold);
|
Patch<const void*>(match.get<void>(2), &LightStatusRandomnessThreshold);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Make script randomness 16-bit, like on PS2
|
// Make script randomness 16-bit, like on PS2
|
||||||
|
try
|
||||||
{
|
{
|
||||||
using namespace Rand16bit;
|
using namespace Rand16bit;
|
||||||
|
|
||||||
|
@ -323,6 +341,7 @@ namespace Common {
|
||||||
|
|
||||||
HookEach_Rand(rands, InterceptCall);
|
HookEach_Rand(rands, InterceptCall);
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
void III_VC_SetDelayedPatchesFunc( void(*func)() )
|
void III_VC_SetDelayedPatchesFunc( void(*func)() )
|
||||||
|
@ -333,24 +352,21 @@ namespace Common {
|
||||||
void III_VC_DelayedCommon( bool /*hasDebugMenu*/, const wchar_t* wcModulePath )
|
void III_VC_DelayedCommon( bool /*hasDebugMenu*/, const wchar_t* wcModulePath )
|
||||||
{
|
{
|
||||||
using namespace Memory;
|
using namespace Memory;
|
||||||
using namespace hook;
|
using namespace hook::txn;
|
||||||
|
|
||||||
ExtraCompSpecularity::ReadExtraCompSpecularityExceptions(wcModulePath);
|
ExtraCompSpecularity::ReadExtraCompSpecularityExceptions(wcModulePath);
|
||||||
|
|
||||||
// Corrected taxi light placement for Taxi
|
// Corrected taxi light placement for Taxi
|
||||||
if ( GetPrivateProfileIntW(L"SilentPatch", L"EnableVehicleCoronaFixes", -1, wcModulePath) == 1 )
|
if ( GetPrivateProfileIntW(L"SilentPatch", L"EnableVehicleCoronaFixes", -1, wcModulePath) == 1 ) try
|
||||||
{
|
{
|
||||||
using namespace TaxiCoronaFix;
|
using namespace TaxiCoronaFix;
|
||||||
|
|
||||||
auto getTaxiLightPos = pattern( "E8 ? ? ? ? D9 84 24 ? ? ? ? D8 84 24 ? ? ? ? 83 C4 0C FF 35" );
|
auto getTaxiLightPos = pattern( "E8 ? ? ? ? D9 84 24 ? ? ? ? D8 84 24 ? ? ? ? 83 C4 0C FF 35" ).get_one();
|
||||||
|
|
||||||
if ( getTaxiLightPos.count_hint(1).size() == 1 )
|
Patch<uint8_t>( getTaxiLightPos.get<void>( -15 ), 0x55 ); // push eax -> push ebp
|
||||||
{
|
InjectHook( getTaxiLightPos.get<void>(), GetTransformedCoronaPos );
|
||||||
auto match = getTaxiLightPos.get_one();
|
}
|
||||||
Patch<uint8_t>( match.get<void>( -15 ), 0x55 ); // push eax -> push ebp
|
TXN_CATCH();
|
||||||
InjectHook( match.get<void>(), GetTransformedCoronaPos );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -39,23 +39,35 @@ namespace Common {
|
||||||
|
|
||||||
namespace Patches {
|
namespace Patches {
|
||||||
|
|
||||||
bool FixRwcseg_Patterns()
|
bool FixRwcseg_Patterns() try
|
||||||
{
|
{
|
||||||
using namespace hook;
|
using namespace hook::txn;
|
||||||
|
|
||||||
auto begin = pattern( "55 8B EC 50 53 51 52 8B 5D 14 8B 4D 10 8B 45 0C 8B 55 08" );
|
// _rwcseg can be placed far after the code section, and the default pattern heuristics currently break with it
|
||||||
auto end = pattern( "9B D9 3D ? ? ? ? 81 25 ? ? ? ? FF FC FF FF 83 0D ? ? ? ? 3F" );
|
// (it's only using SizeOfCode instead of scanning all code sections).
|
||||||
|
// To fix this, explicitly scan the entire module
|
||||||
|
const uintptr_t module = reinterpret_cast<uintptr_t>(GetModuleHandle(nullptr));
|
||||||
|
PIMAGE_DOS_HEADER dosHeader = reinterpret_cast<PIMAGE_DOS_HEADER>(module);
|
||||||
|
PIMAGE_NT_HEADERS ntHeader = reinterpret_cast<PIMAGE_NT_HEADERS>(module + dosHeader->e_lfanew);
|
||||||
|
|
||||||
if ( begin.count_hint(1).size() == 1 && end.count_hint(1).size() == 1 )
|
const uintptr_t sizeOfHeaders = ntHeader->OptionalHeader.SizeOfHeaders;
|
||||||
{
|
const uintptr_t moduleBegin = module + sizeOfHeaders;
|
||||||
const ptrdiff_t size = (intptr_t)end.get_first( 24 ) - (intptr_t)begin.get_first();
|
const uintptr_t moduleEnd = module + (ntHeader->OptionalHeader.SizeOfImage - sizeOfHeaders);
|
||||||
|
|
||||||
|
auto begin = make_range_pattern(moduleBegin, moduleEnd, "55 8B EC 50 53 51 52 8B 5D 14 8B 4D 10 8B 45 0C 8B 55 08").get_first<void>();
|
||||||
|
auto end = make_range_pattern(moduleBegin, moduleEnd, "9B D9 3D ? ? ? ? 81 25 ? ? ? ? FF FC FF FF 83 0D ? ? ? ? 3F").get_first<void>(31);
|
||||||
|
|
||||||
|
const ptrdiff_t size = reinterpret_cast<uintptr_t>(end) - reinterpret_cast<uintptr_t>(begin);
|
||||||
if ( size > 0 )
|
if ( size > 0 )
|
||||||
{
|
{
|
||||||
DWORD dwProtect;
|
DWORD dwProtect;
|
||||||
VirtualProtect( begin.get_first(), size, PAGE_EXECUTE_READ, &dwProtect );
|
VirtualProtect( begin, size, PAGE_EXECUTE_READ, &dwProtect );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
catch (const hook::txn_exception&)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,38 +219,34 @@ namespace Common {
|
||||||
void DDraw_Common()
|
void DDraw_Common()
|
||||||
{
|
{
|
||||||
using namespace Memory;
|
using namespace Memory;
|
||||||
using namespace hook;
|
using namespace hook::txn;
|
||||||
|
|
||||||
// Remove FILE_FLAG_NO_BUFFERING from CdStreams
|
// Remove FILE_FLAG_NO_BUFFERING from CdStreams
|
||||||
|
try
|
||||||
{
|
{
|
||||||
auto mem = pattern( "81 7C 24 04 00 08 00 00" ).count_hint(1);
|
auto mem = get_pattern("81 7C 24 04 00 08 00 00", 0x12);
|
||||||
if ( mem.size() == 1 )
|
Patch<uint8_t>( mem, 0xEB );
|
||||||
{
|
|
||||||
Patch<uint8_t>( mem.get_first( 0x12 ), 0xEB );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// No censorships
|
// No censorships
|
||||||
|
try
|
||||||
{
|
{
|
||||||
auto addr = pattern( "83 FB 07 74 0A 83 FD 07 74 05 83 FE 07 75 15" ).count_hint(1);
|
auto addr = get_pattern( "83 FB 07 74 0A 83 FD 07 74 05 83 FE 07 75 15" );
|
||||||
if ( addr.size() == 1 )
|
Patch( addr, { 0xEB, 0x5E } );
|
||||||
{
|
|
||||||
Patch( addr.get_first(), { 0xEB, 0x5E } );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
// unnamed CdStream semaphore
|
// unnamed CdStream semaphore
|
||||||
|
try
|
||||||
{
|
{
|
||||||
auto mem = pattern( "8D 04 85 00 00 00 00 50 6A 40 FF 15" ).count_hint(1);
|
auto mem = pattern( "8D 04 85 00 00 00 00 50 6A 40 FF 15" ).get_one();
|
||||||
if ( mem.size() == 1 )
|
|
||||||
{
|
|
||||||
Patch( mem.get_first( 0x25 ), { 0x6A, 0x00 } ); // push 0 \ nop
|
|
||||||
Nop( mem.get_first( 0x25 + 2 ), 3 );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
Patch( mem.get<void>( 0x25 ), { 0x6A, 0x00 } ); // push 0 \ nop
|
||||||
|
Nop( mem.get<void>( 0x25 + 2 ), 3 );
|
||||||
|
}
|
||||||
|
TXN_CATCH();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -842,7 +842,7 @@ namespace SitInBoat
|
||||||
void InjectDelayedPatches_III_Common( bool bHasDebugMenu, const wchar_t* wcModulePath )
|
void InjectDelayedPatches_III_Common( bool bHasDebugMenu, const wchar_t* wcModulePath )
|
||||||
{
|
{
|
||||||
using namespace Memory;
|
using namespace Memory;
|
||||||
using namespace hook;
|
using namespace hook::txn;
|
||||||
|
|
||||||
const ModuleList moduleList;
|
const ModuleList moduleList;
|
||||||
|
|
||||||
|
@ -876,135 +876,124 @@ void InjectDelayedPatches_III_Common( bool bHasDebugMenu, const wchar_t* wcModul
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make crane be unable to lift Coach instead of Blista
|
// Make crane be unable to lift Coach instead of Blista
|
||||||
|
try
|
||||||
{
|
{
|
||||||
// There is a possible incompatibility with limit adjusters, so patch it in a delayed hook point and gracefully handle failure
|
// There is a possible incompatibility with limit adjusters, so patch it in a delayed hook point and gracefully handle failure
|
||||||
auto canPickBlista = pattern( "83 FA 66 74" ).count_hint(1);
|
auto canPickBlista = get_pattern("83 FA 66 74", 2);
|
||||||
if ( canPickBlista.size() == 1 )
|
Patch<int8_t>( canPickBlista, 127 ); // coach
|
||||||
{
|
|
||||||
Patch<int8_t>( canPickBlista.get_first<void>( 2 ), 127 ); // coach
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Corrected siren corona placement for emergency vehicles
|
// Corrected siren corona placement for emergency vehicles
|
||||||
if ( GetPrivateProfileIntW(L"SilentPatch", L"EnableVehicleCoronaFixes", -1, wcModulePath) == 1 )
|
if ( GetPrivateProfileIntW(L"SilentPatch", L"EnableVehicleCoronaFixes", -1, wcModulePath) == 1 )
|
||||||
{
|
{
|
||||||
// Other mods might be touching it, so only patch specific vehicles if their code has not been touched at all
|
// Other mods might be touching it, so only patch specific vehicles if their code has not been touched at all
|
||||||
|
try
|
||||||
{
|
{
|
||||||
auto firetruckX1 = pattern( "C7 84 24 9C 05 00 00 CD CC 8C 3F" );
|
auto firetruckX1 = get_pattern("C7 84 24 9C 05 00 00 CD CC 8C 3F", 7);
|
||||||
auto firetruckY1 = pattern( "C7 84 24 A4 05 00 00 9A 99 D9 3F" );
|
auto firetruckY1 = get_pattern("C7 84 24 A4 05 00 00 9A 99 D9 3F", 7);
|
||||||
auto firetruckZ1 = pattern( "C7 84 24 A8 05 00 00 00 00 00 40" );
|
auto firetruckZ1 = get_pattern("C7 84 24 A8 05 00 00 00 00 00 40", 7);
|
||||||
|
|
||||||
auto firetruckX2 = pattern( "C7 84 24 A8 05 00 00 CD CC 8C BF" );
|
auto firetruckX2 = get_pattern("C7 84 24 A8 05 00 00 CD CC 8C BF", 7);
|
||||||
auto firetruckY2 = pattern( "C7 84 24 B0 05 00 00 9A 99 D9 3F" );
|
auto firetruckY2 = get_pattern("C7 84 24 B0 05 00 00 9A 99 D9 3F", 7);
|
||||||
auto firetruckZ2 = pattern( "C7 84 24 B4 05 00 00 00 00 00 40" );
|
auto firetruckZ2 = get_pattern("C7 84 24 B4 05 00 00 00 00 00 40", 7);
|
||||||
|
|
||||||
if ( firetruckX1.count_hint(1).size() == 1 && firetruckY1.count_hint(1).size() == 1 && firetruckZ1.count_hint(1).size() == 1 &&
|
|
||||||
firetruckX2.count_hint(1).size() == 1 && firetruckY2.count_hint(1).size() == 1 && firetruckZ2.count_hint(1).size() == 1 )
|
|
||||||
{
|
|
||||||
constexpr CVector FIRETRUCK_SIREN_POS(0.95f, 3.2f, 1.4f);
|
constexpr CVector FIRETRUCK_SIREN_POS(0.95f, 3.2f, 1.4f);
|
||||||
|
|
||||||
Patch<float>( firetruckX1.get_first( 7 ), FIRETRUCK_SIREN_POS.x );
|
Patch<float>( firetruckX1, FIRETRUCK_SIREN_POS.x );
|
||||||
Patch<float>( firetruckY1.get_first( 7 ), FIRETRUCK_SIREN_POS.y );
|
Patch<float>( firetruckY1, FIRETRUCK_SIREN_POS.y );
|
||||||
Patch<float>( firetruckZ1.get_first( 7 ), FIRETRUCK_SIREN_POS.z );
|
Patch<float>( firetruckZ1, FIRETRUCK_SIREN_POS.z );
|
||||||
|
|
||||||
Patch<float>( firetruckX2.get_first( 7 ), -FIRETRUCK_SIREN_POS.x );
|
Patch<float>( firetruckX2, -FIRETRUCK_SIREN_POS.x );
|
||||||
Patch<float>( firetruckY2.get_first( 7 ), FIRETRUCK_SIREN_POS.y );
|
Patch<float>( firetruckY2, FIRETRUCK_SIREN_POS.y );
|
||||||
Patch<float>( firetruckZ2.get_first( 7 ), FIRETRUCK_SIREN_POS.z );
|
Patch<float>( firetruckZ2, FIRETRUCK_SIREN_POS.z );
|
||||||
}
|
}
|
||||||
}
|
TXN_CATCH();
|
||||||
{
|
|
||||||
auto ambulanceX1 = pattern( "C7 84 24 84 05 00 00 CD CC 8C 3F" );
|
|
||||||
auto ambulanceY1 = pattern( "C7 84 24 8C 05 00 00 66 66 66 3F" );
|
|
||||||
auto ambulanceZ1 = pattern( "C7 84 24 90 05 00 00 CD CC CC 3F" );
|
|
||||||
|
|
||||||
auto ambulanceX2 = pattern( "C7 84 24 90 05 00 00 CD CC 8C BF" );
|
try
|
||||||
auto ambulanceY2 = pattern( "C7 84 24 98 05 00 00 66 66 66 3F" );
|
|
||||||
auto ambulanceZ2 = pattern( "C7 84 24 9C 05 00 00 CD CC CC 3F" );
|
|
||||||
|
|
||||||
if ( ambulanceX1.count_hint(1).size() == 1 && ambulanceY1.count_hint(1).size() == 1 && ambulanceZ1.count_hint(1).size() == 1 &&
|
|
||||||
ambulanceX2.count_hint(1).size() == 1 && ambulanceY2.count_hint(1).size() == 1 && ambulanceZ2.count_hint(1).size() == 1 )
|
|
||||||
{
|
{
|
||||||
|
auto ambulanceX1 = get_pattern("C7 84 24 84 05 00 00 CD CC 8C 3F", 7);
|
||||||
|
auto ambulanceY1 = get_pattern("C7 84 24 8C 05 00 00 66 66 66 3F", 7);
|
||||||
|
auto ambulanceZ1 = get_pattern("C7 84 24 90 05 00 00 CD CC CC 3F", 7);
|
||||||
|
|
||||||
|
auto ambulanceX2 = get_pattern("C7 84 24 90 05 00 00 CD CC 8C BF", 7);
|
||||||
|
auto ambulanceY2 = get_pattern("C7 84 24 98 05 00 00 66 66 66 3F", 7);
|
||||||
|
auto ambulanceZ2 = get_pattern("C7 84 24 9C 05 00 00 CD CC CC 3F", 7);
|
||||||
|
|
||||||
constexpr CVector AMBULANCE_SIREN_POS(0.7f, 0.65f, 1.55f);
|
constexpr CVector AMBULANCE_SIREN_POS(0.7f, 0.65f, 1.55f);
|
||||||
|
|
||||||
Patch<float>( ambulanceX1.get_first( 7 ), AMBULANCE_SIREN_POS.x );
|
Patch<float>( ambulanceX1, AMBULANCE_SIREN_POS.x );
|
||||||
Patch<float>( ambulanceY1.get_first( 7 ), AMBULANCE_SIREN_POS.y );
|
Patch<float>( ambulanceY1, AMBULANCE_SIREN_POS.y );
|
||||||
Patch<float>( ambulanceZ1.get_first( 7 ), AMBULANCE_SIREN_POS.z );
|
Patch<float>( ambulanceZ1, AMBULANCE_SIREN_POS.z );
|
||||||
|
|
||||||
Patch<float>( ambulanceX2.get_first( 7 ), -AMBULANCE_SIREN_POS.x );
|
Patch<float>( ambulanceX2, -AMBULANCE_SIREN_POS.x );
|
||||||
Patch<float>( ambulanceY2.get_first( 7 ), AMBULANCE_SIREN_POS.y );
|
Patch<float>( ambulanceY2, AMBULANCE_SIREN_POS.y );
|
||||||
Patch<float>( ambulanceZ2.get_first( 7 ), AMBULANCE_SIREN_POS.z );
|
Patch<float>( ambulanceZ2, AMBULANCE_SIREN_POS.z );
|
||||||
}
|
}
|
||||||
}
|
TXN_CATCH();
|
||||||
{
|
|
||||||
auto enforcerX1 = pattern( "C7 84 24 6C 05 00 00 CD CC 8C 3F" );
|
|
||||||
auto enforcerY1 = pattern( "C7 84 24 74 05 00 00 CD CC 4C 3F" );
|
|
||||||
auto enforcerZ1 = pattern( "C7 84 24 78 05 00 00 9A 99 99 3F" );
|
|
||||||
|
|
||||||
auto enforcerX2 = pattern( "C7 84 24 78 05 00 00 CD CC 8C BF" );
|
try
|
||||||
auto enforcerY2 = pattern( "C7 84 24 80 05 00 00 CD CC 4C 3F" );
|
|
||||||
auto enforcerZ2 = pattern( "C7 84 24 84 05 00 00 9A 99 99 3F" );
|
|
||||||
|
|
||||||
if ( enforcerX1.count_hint(1).size() == 1 && enforcerY1.count_hint(1).size() == 1 && enforcerZ1.count_hint(1).size() == 1 &&
|
|
||||||
enforcerX2.count_hint(1).size() == 1 && enforcerY2.count_hint(1).size() == 1 && enforcerZ2.count_hint(1).size() == 1 )
|
|
||||||
{
|
{
|
||||||
|
auto enforcerX1 = get_pattern("C7 84 24 6C 05 00 00 CD CC 8C 3F", 7);
|
||||||
|
auto enforcerY1 = get_pattern("C7 84 24 74 05 00 00 CD CC 4C 3F", 7);
|
||||||
|
auto enforcerZ1 = get_pattern("C7 84 24 78 05 00 00 9A 99 99 3F", 7);
|
||||||
|
|
||||||
|
auto enforcerX2 = get_pattern("C7 84 24 78 05 00 00 CD CC 8C BF", 7);
|
||||||
|
auto enforcerY2 = get_pattern("C7 84 24 80 05 00 00 CD CC 4C 3F", 7);
|
||||||
|
auto enforcerZ2 = get_pattern("C7 84 24 84 05 00 00 9A 99 99 3F", 7);
|
||||||
|
|
||||||
constexpr CVector ENFORCER_SIREN_POS(0.6f, 1.05f, 1.4f);
|
constexpr CVector ENFORCER_SIREN_POS(0.6f, 1.05f, 1.4f);
|
||||||
|
|
||||||
Patch<float>( enforcerX1.get_first( 7 ), ENFORCER_SIREN_POS.x );
|
Patch<float>( enforcerX1, ENFORCER_SIREN_POS.x );
|
||||||
Patch<float>( enforcerY1.get_first( 7 ), ENFORCER_SIREN_POS.y );
|
Patch<float>( enforcerY1, ENFORCER_SIREN_POS.y );
|
||||||
Patch<float>( enforcerZ1.get_first( 7 ), ENFORCER_SIREN_POS.z );
|
Patch<float>( enforcerZ1, ENFORCER_SIREN_POS.z );
|
||||||
|
|
||||||
Patch<float>( enforcerX2.get_first( 7 ), -ENFORCER_SIREN_POS.x );
|
Patch<float>( enforcerX2, -ENFORCER_SIREN_POS.x );
|
||||||
Patch<float>( enforcerY2.get_first( 7 ), ENFORCER_SIREN_POS.y );
|
Patch<float>( enforcerY2, ENFORCER_SIREN_POS.y );
|
||||||
Patch<float>( enforcerZ2.get_first( 7 ), ENFORCER_SIREN_POS.z );
|
Patch<float>( enforcerZ2, ENFORCER_SIREN_POS.z );
|
||||||
}
|
}
|
||||||
}
|
TXN_CATCH();
|
||||||
{
|
|
||||||
auto chopper1 = pattern( "C7 44 24 44 00 00 E0 40 50 C7 44 24 4C 00 00 00 00" ); // Front light
|
|
||||||
|
|
||||||
if ( chopper1.count_hint(1).size() == 1 )
|
try
|
||||||
{
|
{
|
||||||
|
auto chopper1 = pattern("C7 44 24 44 00 00 E0 40 50 C7 44 24 4C 00 00 00 00").get_one(); // Front light
|
||||||
|
|
||||||
constexpr CVector CHOPPER_SEARCH_LIGHT_POS(0.0f, 3.0f, -1.25f);
|
constexpr CVector CHOPPER_SEARCH_LIGHT_POS(0.0f, 3.0f, -1.25f);
|
||||||
|
|
||||||
auto match = chopper1.get_one();
|
Patch( chopper1.get<float>( 4 ), CHOPPER_SEARCH_LIGHT_POS.y );
|
||||||
|
Patch( chopper1.get<float>( 9 + 4 ), CHOPPER_SEARCH_LIGHT_POS.z );
|
||||||
Patch( match.get<float>( 4 ), CHOPPER_SEARCH_LIGHT_POS.y );
|
|
||||||
Patch( match.get<float>( 9 + 4 ), CHOPPER_SEARCH_LIGHT_POS.z );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Corrected FBI Car secondary siren sound
|
// Corrected FBI Car secondary siren sound
|
||||||
|
try
|
||||||
{
|
{
|
||||||
using namespace SirenSwitchingFix;
|
using namespace SirenSwitchingFix;
|
||||||
|
|
||||||
// Other mods might be touching it, so only patch specific vehicles if their code has not been touched at all
|
// Other mods might be touching it, so only patch specific vehicles if their code has not been touched at all
|
||||||
auto usesSirenSwitching = pattern( "E8 ? ? ? ? 84 C0 74 12 83 C4 08" ).count_hint(1);
|
auto usesSirenSwitching = pattern("E8 ? ? ? ? 84 C0 74 12 83 C4 08").get_one();
|
||||||
if ( usesSirenSwitching.size() == 1 )
|
|
||||||
{
|
InterceptCall(usesSirenSwitching.get<void>(), orgUsesSirenSwitching, UsesSirenSwitching_FbiCar);
|
||||||
auto match = usesSirenSwitching.get_one();
|
|
||||||
ReadCall( match.get<void>(), orgUsesSirenSwitching );
|
|
||||||
InjectHook( match.get<void>(), UsesSirenSwitching_FbiCar );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Corrected CSimpleModelInfo::SetupBigBuilding minimum draw distance for big buildings without a matching model
|
// Corrected CSimpleModelInfo::SetupBigBuilding minimum draw distance for big buildings without a matching model
|
||||||
// Fixes cranes in Portland and bright windows in the city
|
// Fixes cranes in Portland and bright windows in the city
|
||||||
// By aap
|
// By aap
|
||||||
|
try
|
||||||
{
|
{
|
||||||
auto setupMinDist = pattern( "C7 43 44 00 00 C8 42" ).count_hint(1);
|
auto setupMinDist = pattern("C7 43 44 00 00 C8 42").get_one();
|
||||||
if ( setupMinDist.size() == 1 ) // In case of another mod or second instance of SP changing it
|
|
||||||
{
|
|
||||||
auto match = setupMinDist.get_one();
|
|
||||||
|
|
||||||
// mov ecx, ebx
|
// mov ecx, ebx
|
||||||
// call CSimpleModelInfo::SetNearDistanceForLOD
|
// call CSimpleModelInfo::SetNearDistanceForLOD
|
||||||
Patch( match.get<void>(), { 0x89, 0xD9 } );
|
Patch( setupMinDist.get<void>(), { 0x89, 0xD9 } );
|
||||||
InjectHook( match.get<void>( 2 ), &CSimpleModelInfo::SetNearDistanceForLOD_SilentPatch, HookType::Call );
|
InjectHook( setupMinDist.get<void>( 2 ), &CSimpleModelInfo::SetNearDistanceForLOD_SilentPatch, HookType::Call );
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
FLAUtils::Init(moduleList);
|
FLAUtils::Init(moduleList);
|
||||||
}
|
}
|
||||||
|
@ -1346,10 +1335,11 @@ void Patch_III_Steam(uint32_t width, uint32_t height)
|
||||||
void Patch_III_Common()
|
void Patch_III_Common()
|
||||||
{
|
{
|
||||||
using namespace Memory;
|
using namespace Memory;
|
||||||
using namespace hook;
|
using namespace hook::txn;
|
||||||
|
|
||||||
|
|
||||||
// New timers fix
|
// New timers fix
|
||||||
|
try
|
||||||
{
|
{
|
||||||
auto hookPoint = pattern( "83 E4 F8 89 44 24 08 C7 44 24 0C 00 00 00 00 DF 6C 24 08" ).get_one();
|
auto hookPoint = pattern( "83 E4 F8 89 44 24 08 C7 44 24 0C 00 00 00 00 DF 6C 24 08" ).get_one();
|
||||||
auto jmpPoint = get_pattern( "DD D8 E9 37 FF FF FF DD D8" );
|
auto jmpPoint = get_pattern( "DD D8 E9 37 FF FF FF DD D8" );
|
||||||
|
@ -1357,8 +1347,11 @@ void Patch_III_Common()
|
||||||
InjectHook( hookPoint.get<void>( 0x21 ), CTimer::Update_SilentPatch, HookType::Call );
|
InjectHook( hookPoint.get<void>( 0x21 ), CTimer::Update_SilentPatch, HookType::Call );
|
||||||
InjectHook( hookPoint.get<void>( 0x21 + 5 ), jmpPoint, HookType::Jump );
|
InjectHook( hookPoint.get<void>( 0x21 + 5 ), jmpPoint, HookType::Jump );
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Alt+F4
|
// Alt+F4
|
||||||
|
try
|
||||||
{
|
{
|
||||||
auto addr = pattern( "59 59 31 C0 83 C4 48 5D 5F 5E 5B C2 10 00" ).count(2);
|
auto addr = pattern( "59 59 31 C0 83 C4 48 5D 5F 5E 5B C2 10 00" ).count(2);
|
||||||
auto dest = get_pattern( "53 55 56 FF 74 24 68 FF 15" );
|
auto dest = get_pattern( "53 55 56 FF 74 24 68 FF 15" );
|
||||||
|
@ -1367,8 +1360,11 @@ void Patch_III_Common()
|
||||||
InjectHook( match.get<void>( 2 ), dest, HookType::Jump );
|
InjectHook( match.get<void>( 2 ), dest, HookType::Jump );
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Proper panels damage
|
// Proper panels damage
|
||||||
|
try
|
||||||
{
|
{
|
||||||
auto addr = pattern( "C6 43 09 03 C6 43 0A 03 C6 43 0B 03" ).get_one();
|
auto addr = pattern( "C6 43 09 03 C6 43 0A 03 C6 43 0B 03" ).get_one();
|
||||||
|
|
||||||
|
@ -1376,8 +1372,11 @@ void Patch_III_Common()
|
||||||
Patch<uint8_t>( addr.get<void>( 0x23 + 1 ), 6 );
|
Patch<uint8_t>( addr.get<void>( 0x23 + 1 ), 6 );
|
||||||
Nop( addr.get<void>( 0x3F ), 7 );
|
Nop( addr.get<void>( 0x3F ), 7 );
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Proper metric-imperial conversion constants
|
// Proper metric-imperial conversion constants
|
||||||
|
try
|
||||||
{
|
{
|
||||||
static const float METERS_TO_MILES = 0.0006213711922f;
|
static const float METERS_TO_MILES = 0.0006213711922f;
|
||||||
static const float METERS_TO_FEET = 3.280839895f;
|
static const float METERS_TO_FEET = 3.280839895f;
|
||||||
|
@ -1389,8 +1388,11 @@ void Patch_III_Common()
|
||||||
Patch<const void*>( addr.get(2).get<void>( 2 ), &METERS_TO_FEET );
|
Patch<const void*>( addr.get(2).get<void>( 2 ), &METERS_TO_FEET );
|
||||||
Patch<const void*>( addr.get(3).get<void>( 2 ), &METERS_TO_FEET );
|
Patch<const void*>( addr.get(3).get<void>( 2 ), &METERS_TO_FEET );
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Improved pathfinding in PickNextNodeAccordingStrategy - PickNextNodeToChaseCar with XYZ coords
|
// Improved pathfinding in PickNextNodeAccordingStrategy - PickNextNodeToChaseCar with XYZ coords
|
||||||
|
try
|
||||||
{
|
{
|
||||||
auto addr = pattern( "E8 ? ? ? ? 50 8D 44 24 10 50 E8" ).get_one();
|
auto addr = pattern( "E8 ? ? ? ? 50 8D 44 24 10 50 E8" ).get_one();
|
||||||
ReadCall( addr.get<void>( 0x25 ), orgPickNextNodeToChaseCar );
|
ReadCall( addr.get<void>( 0x25 ), orgPickNextNodeToChaseCar );
|
||||||
|
@ -1421,25 +1423,31 @@ void Patch_III_Common()
|
||||||
// Uncomment this to get rid of "treadable hack" in CCarCtrl::PickNextNodeToChaseCar (to mirror VC behaviour)
|
// Uncomment this to get rid of "treadable hack" in CCarCtrl::PickNextNodeToChaseCar (to mirror VC behaviour)
|
||||||
InjectHook( funcAddr + 0x2A, funcAddr + 0x182, HookType::Jump );
|
InjectHook( funcAddr + 0x2A, funcAddr + 0x182, HookType::Jump );
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// No censorships
|
// No censorships
|
||||||
|
try
|
||||||
{
|
{
|
||||||
auto addr = get_pattern( "8B 15 ? ? ? ? C6 05 ? ? ? ? 00 89 D0" );
|
auto addr = get_pattern( "8B 15 ? ? ? ? C6 05 ? ? ? ? 00 89 D0" );
|
||||||
Patch( addr, { 0x83, 0xC4, 0x08, 0xC3 } ); // add esp, 8 \ retn
|
Patch( addr, { 0x83, 0xC4, 0x08, 0xC3 } ); // add esp, 8 \ retn
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// 014C cargen counter fix (by spaceeinstein)
|
// 014C cargen counter fix (by spaceeinstein)
|
||||||
|
try
|
||||||
{
|
{
|
||||||
auto do_processing = pattern( "0F B7 45 28 83 F8 FF 7D 04 66 FF 4D 28" ).get_one();
|
auto do_processing = pattern( "0F B7 45 28 83 F8 FF 7D 04 66 FF 4D 28" ).get_one();
|
||||||
|
|
||||||
Patch<uint8_t>( do_processing.get<uint8_t*>(1), 0xBF ); // movzx eax, word ptr [ebx+28h] -> movsx eax, word ptr [ebx+28h]
|
Patch<uint8_t>( do_processing.get<uint8_t*>(1), 0xBF ); // movzx eax, word ptr [ebx+28h] -> movsx eax, word ptr [ebx+28h]
|
||||||
Patch<uint8_t>( do_processing.get<uint8_t*>(7), 0x74 ); // jge -> jz
|
Patch<uint8_t>( do_processing.get<uint8_t*>(7), 0x74 ); // jge -> jz
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Fixed ammo from SCM
|
// Fixed ammo from SCM
|
||||||
|
try
|
||||||
{
|
{
|
||||||
using namespace ZeroAmmoFix;
|
using namespace ZeroAmmoFix;
|
||||||
|
|
||||||
|
@ -1449,9 +1457,11 @@ void Patch_III_Common()
|
||||||
};
|
};
|
||||||
HookEach_GiveWeapon(give_weapon, InterceptCall);
|
HookEach_GiveWeapon(give_weapon, InterceptCall);
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Credits =)
|
// Credits =)
|
||||||
|
try
|
||||||
{
|
{
|
||||||
auto renderCredits = pattern( "83 C4 14 8D 45 F4 50 FF 35 ? ? ? ? E8 ? ? ? ? 59 59 8D 45 F4 50 FF 35 ? ? ? ? E8 ? ? ? ? 59 59 E8" ).get_one();
|
auto renderCredits = pattern( "83 C4 14 8D 45 F4 50 FF 35 ? ? ? ? E8 ? ? ? ? 59 59 8D 45 F4 50 FF 35 ? ? ? ? E8 ? ? ? ? 59 59 E8" ).get_one();
|
||||||
|
|
||||||
|
@ -1459,9 +1469,11 @@ void Patch_III_Common()
|
||||||
ReadCall( renderCredits.get<void>( -5 ), Credits::PrintCreditText_Hooked );
|
ReadCall( renderCredits.get<void>( -5 ), Credits::PrintCreditText_Hooked );
|
||||||
InjectHook( renderCredits.get<void>( -5 ), Credits::PrintSPCredits );
|
InjectHook( renderCredits.get<void>( -5 ), Credits::PrintSPCredits );
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Decreased keyboard input latency
|
// Decreased keyboard input latency
|
||||||
|
try
|
||||||
{
|
{
|
||||||
using namespace KeyboardInputFix;
|
using namespace KeyboardInputFix;
|
||||||
|
|
||||||
|
@ -1477,20 +1489,20 @@ void Patch_III_Common()
|
||||||
InjectHook( simButtonCheckers, ClearSimButtonPressCheckers );
|
InjectHook( simButtonCheckers, ClearSimButtonPressCheckers );
|
||||||
InjectHook( updatePads.get<void>( 10 ), jmpDest, HookType::Jump );
|
InjectHook( updatePads.get<void>( 10 ), jmpDest, HookType::Jump );
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Locale based metric/imperial system
|
// Locale based metric/imperial system
|
||||||
|
try
|
||||||
{
|
{
|
||||||
using namespace Localization;
|
using namespace Localization;
|
||||||
|
|
||||||
void* updateCompareFlag = get_pattern( "89 E9 6A 00 E8 ? ? ? ? 30 C0 83 C4 70 5D 5E 5B C2 04 00", 4 );
|
void* updateCompareFlag = get_pattern( "89 E9 6A 00 E8 ? ? ? ? 30 C0 83 C4 70 5D 5E 5B C2 04 00", 4 );
|
||||||
|
auto constructStatLine = pattern( "FF 24 9D ? ? ? ? 39 D0" ).get_one();
|
||||||
|
|
||||||
ReadCall( updateCompareFlag, orgUpdateCompareFlag_IsMetric );
|
ReadCall( updateCompareFlag, orgUpdateCompareFlag_IsMetric );
|
||||||
InjectHook( updateCompareFlag, UpdateCompareFlag_IsMetric );
|
InjectHook( updateCompareFlag, UpdateCompareFlag_IsMetric );
|
||||||
|
|
||||||
// Stats
|
|
||||||
auto constructStatLine = pattern( "FF 24 9D ? ? ? ? 39 D0" ).get_one();
|
|
||||||
|
|
||||||
// push eax
|
// push eax
|
||||||
// push edx
|
// push edx
|
||||||
// call IsMetric_LocaleBased
|
// call IsMetric_LocaleBased
|
||||||
|
@ -1503,25 +1515,29 @@ void Patch_III_Common()
|
||||||
Patch( constructStatLine.get<void>( -0xF + 7 ), { 0x0F, 0xB6, 0xD8, 0x5A, 0x58 } );
|
Patch( constructStatLine.get<void>( -0xF + 7 ), { 0x0F, 0xB6, 0xD8, 0x5A, 0x58 } );
|
||||||
Nop( constructStatLine.get<void>( -0xF + 12 ), 3 );
|
Nop( constructStatLine.get<void>( -0xF + 12 ), 3 );
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Add cDMAudio::IsAudioInitialised checks before constructing cAudioScriptObject, like in VC
|
// Add cDMAudio::IsAudioInitialised checks before constructing cAudioScriptObject, like in VC
|
||||||
|
try
|
||||||
{
|
{
|
||||||
using namespace AudioInitializedFix;
|
using namespace AudioInitializedFix;
|
||||||
|
|
||||||
auto processCommands300 = pattern( "E8 ? ? ? ? 85 C0 59 74 ? 89 C1 E8 ? ? ? ? D9 05" ).get_one();
|
auto processCommands300 = pattern( "E8 ? ? ? ? 85 C0 59 74 ? 89 C1 E8 ? ? ? ? D9 05" ).get_one();
|
||||||
|
auto processCommands300_2 = pattern( "6A 14 E8 ? ? ? ? 89 C3 59 85 DB 74" ).get_one();
|
||||||
|
auto bulletInfoUpdate_Switch = *get_pattern<uintptr_t*>( "FF 24 85 ? ? ? ? 6A 14", 3 );
|
||||||
|
auto playlayOneShotScriptObject = pattern( "6A 14 E8 ? ? ? ? 85 C0 59 74 ? 89 C1 E8 ? ? ? ? D9 03 D9 58 04" ).get_one();
|
||||||
|
auto loadAllAudioScriptObjects = get_pattern( "FF B5 78 FF FF FF E8 ? ? ? ? 59 59 8B 45 C8", 6 );
|
||||||
|
|
||||||
ReadCall( processCommands300.get<void>( 0 ), operatorNew );
|
ReadCall( processCommands300.get<void>( 0 ), operatorNew );
|
||||||
|
|
||||||
InjectHook( processCommands300.get<void>( 0 ), operatorNew_InitializedCheck );
|
InjectHook( processCommands300.get<void>( 0 ), operatorNew_InitializedCheck );
|
||||||
Patch<int8_t>( processCommands300.get<void>( 8 + 1 ), 0x440B62 - 0x440B24 );
|
Patch<int8_t>( processCommands300.get<void>( 8 + 1 ), 0x440B62 - 0x440B24 );
|
||||||
|
|
||||||
auto processCommands300_2 = pattern( "6A 14 E8 ? ? ? ? 89 C3 59 85 DB 74" ).get_one();
|
|
||||||
InjectHook( processCommands300_2.get<void>( 2 ), operatorNew_InitializedCheck );
|
InjectHook( processCommands300_2.get<void>( 2 ), operatorNew_InitializedCheck );
|
||||||
Patch<int8_t>( processCommands300_2.get<void>( 0xC + 1 ), 0x440BD7 - 0x440B8B );
|
Patch<int8_t>( processCommands300_2.get<void>( 0xC + 1 ), 0x440BD7 - 0x440B8B );
|
||||||
|
|
||||||
// We need to patch switch cases 0, 3, 4
|
// We need to patch switch cases 0, 3, 4
|
||||||
auto bulletInfoUpdate_Switch = *get_pattern<uintptr_t*>( "FF 24 85 ? ? ? ? 6A 14", 3 );
|
|
||||||
|
|
||||||
const uintptr_t bulletInfoUpdate_0 = bulletInfoUpdate_Switch[0];
|
const uintptr_t bulletInfoUpdate_0 = bulletInfoUpdate_Switch[0];
|
||||||
const uintptr_t bulletInfoUpdate_3 = bulletInfoUpdate_Switch[3];
|
const uintptr_t bulletInfoUpdate_3 = bulletInfoUpdate_Switch[3];
|
||||||
const uintptr_t bulletInfoUpdate_4 = bulletInfoUpdate_Switch[4];
|
const uintptr_t bulletInfoUpdate_4 = bulletInfoUpdate_Switch[4];
|
||||||
|
@ -1535,32 +1551,31 @@ void Patch_III_Common()
|
||||||
InjectHook( bulletInfoUpdate_4 + 2, operatorNew_InitializedCheck );
|
InjectHook( bulletInfoUpdate_4 + 2, operatorNew_InitializedCheck );
|
||||||
Patch<int8_t>( bulletInfoUpdate_4 + 0xA + 1, 0x558C19 - 0x558BE3 );
|
Patch<int8_t>( bulletInfoUpdate_4 + 0xA + 1, 0x558C19 - 0x558BE3 );
|
||||||
|
|
||||||
auto playlayOneShotScriptObject = pattern( "6A 14 E8 ? ? ? ? 85 C0 59 74 ? 89 C1 E8 ? ? ? ? D9 03 D9 58 04" ).get_one();
|
|
||||||
InjectHook( playlayOneShotScriptObject.get<void>( 2 ), operatorNew_InitializedCheck );
|
InjectHook( playlayOneShotScriptObject.get<void>( 2 ), operatorNew_InitializedCheck );
|
||||||
Patch<int8_t>( playlayOneShotScriptObject.get<void>( 0xA + 1 ), 0x57C633 - 0x57C601 );
|
Patch<int8_t>( playlayOneShotScriptObject.get<void>( 0xA + 1 ), 0x57C633 - 0x57C601 );
|
||||||
|
|
||||||
auto loadAllAudioScriptObjects = get_pattern( "FF B5 78 FF FF FF E8 ? ? ? ? 59 59 8B 45 C8", 6 );
|
|
||||||
ReadCall( loadAllAudioScriptObjects, orgLoadAllAudioScriptObjects );
|
ReadCall( loadAllAudioScriptObjects, orgLoadAllAudioScriptObjects );
|
||||||
InjectHook( loadAllAudioScriptObjects, LoadAllAudioScriptObjects_InitializedCheck );
|
InjectHook( loadAllAudioScriptObjects, LoadAllAudioScriptObjects_InitializedCheck );
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Give chopper/escape a properly sized collision bounding box instead of using ped's
|
// Give chopper/escape a properly sized collision bounding box instead of using ped's
|
||||||
|
try
|
||||||
{
|
{
|
||||||
auto initHelisPattern = pattern( "C6 40 2C 00 A1" ).count_hint(1);
|
auto initHelis = pattern( "C6 40 2C 00 A1" ).get_one();
|
||||||
if ( initHelisPattern.size() == 1 )
|
|
||||||
{
|
|
||||||
static constexpr CColModel colModelChopper( CColSphere( 8.5f, CVector(0.0f, -1.75f, 0.73f), 0, 0 ),
|
static constexpr CColModel colModelChopper( CColSphere( 8.5f, CVector(0.0f, -1.75f, 0.73f), 0, 0 ),
|
||||||
CColBox( CVector(-2.18f, -8.52f, -0.67f), CVector(-2.18f, 4.58f, 2.125f), 0, 0 ) );
|
CColBox( CVector(-2.18f, -8.52f, -0.67f), CVector(-2.18f, 4.58f, 2.125f), 0, 0 ) );
|
||||||
|
|
||||||
auto initHelis = initHelisPattern.get_one();
|
|
||||||
Patch( initHelis.get<void>( -7 + 3 ), &colModelChopper );
|
Patch( initHelis.get<void>( -7 + 3 ), &colModelChopper );
|
||||||
Patch( initHelis.get<void>( 9 + 3 ), &colModelChopper );
|
Patch( initHelis.get<void>( 9 + 3 ), &colModelChopper );
|
||||||
}
|
}
|
||||||
}
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Fixed vehicles exploding twice if the driver leaves the car while it's exploding
|
// Fixed vehicles exploding twice if the driver leaves the car while it's exploding
|
||||||
|
try
|
||||||
{
|
{
|
||||||
using namespace RemoveDriverStatusFix;
|
using namespace RemoveDriverStatusFix;
|
||||||
|
|
||||||
|
@ -1581,35 +1596,43 @@ void Patch_III_Common()
|
||||||
Nop(processCommands4, 3);
|
Nop(processCommands4, 3);
|
||||||
Nop(pedSetOutCar, 3);
|
Nop(pedSetOutCar, 3);
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Fixed an inverted condition in CCarCtrl::PickNextNodeRandomly
|
// Fixed an inverted condition in CCarCtrl::PickNextNodeRandomly
|
||||||
// leading to cars being unable to turn right from one way roads
|
// leading to cars being unable to turn right from one way roads
|
||||||
// By Nick007J
|
// By Nick007J
|
||||||
|
try
|
||||||
{
|
{
|
||||||
auto pickNodeRandomly = get_pattern("3B 44 24 24 74 09", 4);
|
auto pickNodeRandomly = get_pattern("3B 44 24 24 74 09", 4);
|
||||||
Patch<uint8_t>(pickNodeRandomly, 0x75);
|
Patch<uint8_t>(pickNodeRandomly, 0x75);
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Apply bilinear filtering on the player skin
|
// Apply bilinear filtering on the player skin
|
||||||
|
try
|
||||||
{
|
{
|
||||||
using namespace SkinTextureFilter;
|
using namespace SkinTextureFilter;
|
||||||
|
|
||||||
auto getSkinTexture = get_pattern("E8 ? ? ? ? 89 C3 59 55");
|
auto getSkinTexture = get_pattern("E8 ? ? ? ? 89 C3 59 55");
|
||||||
InterceptCall(getSkinTexture, orgRwTextureCreate, RwTextureCreate_SetLinearFilter);
|
InterceptCall(getSkinTexture, orgRwTextureCreate, RwTextureCreate_SetLinearFilter);
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Apply the environment mapping on extra components
|
// Apply the environment mapping on extra components
|
||||||
|
try
|
||||||
{
|
{
|
||||||
auto setEnvironmentMap = get_pattern("C7 83 D8 01 00 00 00 00 00 00 E8", 10);
|
auto setEnvironmentMap = get_pattern("C7 83 D8 01 00 00 00 00 00 00 E8", 10);
|
||||||
|
|
||||||
InterceptCall(setEnvironmentMap, CVehicleModelInfo::orgSetEnvironmentMap, &CVehicleModelInfo::SetEnvironmentMap_ExtraComps);
|
InterceptCall(setEnvironmentMap, CVehicleModelInfo::orgSetEnvironmentMap, &CVehicleModelInfo::SetEnvironmentMap_ExtraComps);
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Fix the evasive dive miscalculating the angle, resulting in peds diving towards the vehicle
|
// Fix the evasive dive miscalculating the angle, resulting in peds diving towards the vehicle
|
||||||
|
try
|
||||||
{
|
{
|
||||||
using namespace EvasiveDiveFix;
|
using namespace EvasiveDiveFix;
|
||||||
|
|
||||||
|
@ -1618,9 +1641,11 @@ void Patch_III_Common()
|
||||||
Nop(setEvasiveDive.get<void>(), 1);
|
Nop(setEvasiveDive.get<void>(), 1);
|
||||||
InjectHook(setEvasiveDive.get<void>(1), &CalculateAngle_Hook, HookType::Call);
|
InjectHook(setEvasiveDive.get<void>(1), &CalculateAngle_Hook, HookType::Call);
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Fix probabilities in CVehicle::InflictDamage incorrectly assuming a random range from 0 to 100.000
|
// Fix probabilities in CVehicle::InflictDamage incorrectly assuming a random range from 0 to 100.000
|
||||||
|
try
|
||||||
{
|
{
|
||||||
auto probability_do_nothing = get_pattern("66 81 7E 5A ? ? 73 50", 4);
|
auto probability_do_nothing = get_pattern("66 81 7E 5A ? ? 73 50", 4);
|
||||||
auto probability_flee = get_pattern("0F B7 46 5A 3D ? ? ? ? 0F 8E", 4 + 1);
|
auto probability_flee = get_pattern("0F B7 46 5A 3D ? ? ? ? 0F 8E", 4 + 1);
|
||||||
|
@ -1628,9 +1653,11 @@ void Patch_III_Common()
|
||||||
Patch<uint16_t>(probability_do_nothing, 35000u * 32767u / 100000u);
|
Patch<uint16_t>(probability_do_nothing, 35000u * 32767u / 100000u);
|
||||||
Patch<uint32_t>(probability_flee, 75000u * 32767u / 100000u);
|
Patch<uint32_t>(probability_flee, 75000u * 32767u / 100000u);
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Null terminate read lines in CPlane::LoadPath and CTrain::ReadAndInterpretTrackFile
|
// Null terminate read lines in CPlane::LoadPath and CTrain::ReadAndInterpretTrackFile
|
||||||
|
try
|
||||||
{
|
{
|
||||||
using namespace NullTerminatedLines;
|
using namespace NullTerminatedLines;
|
||||||
|
|
||||||
|
@ -1648,25 +1675,26 @@ void Patch_III_Common()
|
||||||
Nop(readTrackFile2.get<void>(), 2);
|
Nop(readTrackFile2.get<void>(), 2);
|
||||||
InjectHook(readTrackFile2.get<void>(2), ReadTrackFile_Terminate, HookType::Call);
|
InjectHook(readTrackFile2.get<void>(2), ReadTrackFile_Terminate, HookType::Call);
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Backport 1.1 Stats menu font fix to 1.0
|
// Backport 1.1 Stats menu font fix to 1.0
|
||||||
|
try
|
||||||
{
|
{
|
||||||
using namespace StatsMenuFont;
|
using namespace StatsMenuFont;
|
||||||
|
|
||||||
// This pattern fails by design on 1.1/Steam
|
// This pattern fails by design on 1.1/Steam
|
||||||
auto constructStatLine = pattern("E8 ? ? ? ? D9 05 ? ? ? ? DC 0D ? ? ? ? 89 C7").count_hint(1);
|
auto constructStatLine = pattern("E8 ? ? ? ? D9 05 ? ? ? ? DC 0D ? ? ? ? 89 C7").get_one();
|
||||||
if (constructStatLine.size() == 1)
|
|
||||||
{
|
|
||||||
auto setFontStyle = get_pattern("6A 00 E8 ? ? ? ? 83 3D ? ? ? ? ? 59 0F 84", 2);
|
auto setFontStyle = get_pattern("6A 00 E8 ? ? ? ? 83 3D ? ? ? ? ? 59 0F 84", 2);
|
||||||
|
|
||||||
ReadCall(setFontStyle, orgSetFontStyle);
|
ReadCall(setFontStyle, orgSetFontStyle);
|
||||||
InterceptCall(constructStatLine.get_first<void>(), orgConstructStatLine, ConstructStatLine_SetFontStyle);
|
InterceptCall(constructStatLine.get<void>(), orgConstructStatLine, ConstructStatLine_SetFontStyle);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Enable Dodo keyboard controls for all cars when the flying cars cheat is enabled
|
// Enable Dodo keyboard controls for all cars when the flying cars cheat is enabled
|
||||||
|
try
|
||||||
{
|
{
|
||||||
using namespace DodoKeyboardControls;
|
using namespace DodoKeyboardControls;
|
||||||
|
|
||||||
|
@ -1676,9 +1704,11 @@ void Patch_III_Common()
|
||||||
bAllDodosCheat = allDodosCheat;
|
bAllDodosCheat = allDodosCheat;
|
||||||
InterceptCall(findPlayerVehicle, orgFindPlayerVehicle, FindPlayerVehicle_DodoCheck);
|
InterceptCall(findPlayerVehicle, orgFindPlayerVehicle, FindPlayerVehicle_DodoCheck);
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Reset variables on New Game
|
// Reset variables on New Game
|
||||||
|
try
|
||||||
{
|
{
|
||||||
using namespace VariableResets;
|
using namespace VariableResets;
|
||||||
|
|
||||||
|
@ -1696,9 +1726,11 @@ void Patch_III_Common()
|
||||||
GameVariablesToReset.emplace_back(*get_pattern<int*>("7D 72 A1 ? ? ? ? 05", 2 + 1)); // LastTimeAmbulanceCreated
|
GameVariablesToReset.emplace_back(*get_pattern<int*>("7D 72 A1 ? ? ? ? 05", 2 + 1)); // LastTimeAmbulanceCreated
|
||||||
GameVariablesToReset.emplace_back(*get_pattern<int*>("74 7F A1 ? ? ? ? 05", 2 + 1)); // LastTimeFireTruckCreated
|
GameVariablesToReset.emplace_back(*get_pattern<int*>("74 7F A1 ? ? ? ? 05", 2 + 1)); // LastTimeFireTruckCreated
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Clean up the pickup object when reusing a temporary slot
|
// Clean up the pickup object when reusing a temporary slot
|
||||||
|
try
|
||||||
{
|
{
|
||||||
using namespace GenerateNewPickup_ReuseObjectFix;
|
using namespace GenerateNewPickup_ReuseObjectFix;
|
||||||
|
|
||||||
|
@ -1707,10 +1739,12 @@ void Patch_III_Common()
|
||||||
pPickupObject = *give_us_a_pick_up_object.get<void*>(7 + 2);
|
pPickupObject = *give_us_a_pick_up_object.get<void*>(7 + 2);
|
||||||
InterceptCall(give_us_a_pick_up_object.get<void>(2), orgGiveUsAPickUpObject, GiveUsAPickUpObject_CleanUpObject);
|
InterceptCall(give_us_a_pick_up_object.get<void>(2), orgGiveUsAPickUpObject, GiveUsAPickUpObject_CleanUpObject);
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Sitting in boat (Speeder), implemented as a special vehicle feature
|
// Sitting in boat (Speeder), implemented as a special vehicle feature
|
||||||
// Based off SitInBoat from Fire_Head, with extra improvements
|
// Based off SitInBoat from Fire_Head, with extra improvements
|
||||||
|
try
|
||||||
{
|
{
|
||||||
using namespace SitInBoat;
|
using namespace SitInBoat;
|
||||||
|
|
||||||
|
@ -1730,36 +1764,40 @@ void Patch_III_Common()
|
||||||
// This is intended - we don't actually need the original SetFinishCallback, only its parameters!
|
// This is intended - we don't actually need the original SetFinishCallback, only its parameters!
|
||||||
InjectHook(finish_callback, FinishCallback_CallImmediately);
|
InjectHook(finish_callback, FinishCallback_CallImmediately);
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Copy the atomic render CB in CloneAtomicToFrameCB instead of overriding it
|
// Copy the atomic render CB in CloneAtomicToFrameCB instead of overriding it
|
||||||
// Fixes detached limbs rendering the normal and LOD atomics together
|
// Fixes detached limbs rendering the normal and LOD atomics together
|
||||||
|
try
|
||||||
{
|
{
|
||||||
auto set_render_cb = get_pattern("55 E8 ? ? ? ? 89 D8 59", 1);
|
auto set_render_cb = get_pattern("55 E8 ? ? ? ? 89 D8 59", 1);
|
||||||
Nop(set_render_cb, 5);
|
Nop(set_render_cb, 5);
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Fix dark car reflections in the Steam EXE
|
// Fix dark car reflections in the Steam EXE
|
||||||
// Based off Sergenaur's fix
|
// Based off Sergenaur's fix
|
||||||
|
try
|
||||||
{
|
{
|
||||||
auto reflection = pattern("A1 ? ? ? ? 85 C0 74 34");
|
// This will only pass on the Steam EXE, and if Sergenaur's standalone fix isn't present
|
||||||
if (reflection.count_hint(1).size() == 1) // This will only pass on the Steam EXE, and if Sergenaur's standalone fix isn't present
|
auto reflection = pattern("A1 ? ? ? ? 85 C0 74 34").get_one();
|
||||||
{
|
|
||||||
auto match = reflection.get_one();
|
|
||||||
|
|
||||||
// xor eax, eax \ nop
|
// xor eax, eax \ nop
|
||||||
Patch(match.get<void>(), { 0x31, 0xC0 });
|
Patch(reflection.get<void>(), { 0x31, 0xC0 });
|
||||||
Nop(match.get<void>(2), 3);
|
Nop(reflection.get<void>(2), 3);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Don't override the color of the FBI car
|
// Don't override the color of the FBI car
|
||||||
|
try
|
||||||
{
|
{
|
||||||
auto spawn_one_car = get_pattern("83 7C 24 ? ? 75 0E C6 85", 5);
|
auto spawn_one_car = get_pattern("83 7C 24 ? ? 75 0E C6 85", 5);
|
||||||
Patch<uint8_t>(spawn_one_car, 0xEB);
|
Patch<uint8_t>(spawn_one_car, 0xEB);
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||||
|
|
|
@ -152,7 +152,6 @@
|
||||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
<EnforceTypeConversionRules>true</EnforceTypeConversionRules>
|
<EnforceTypeConversionRules>true</EnforceTypeConversionRules>
|
||||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||||
<ExceptionHandling>false</ExceptionHandling>
|
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
|
@ -186,7 +185,6 @@
|
||||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
<EnforceTypeConversionRules>true</EnforceTypeConversionRules>
|
<EnforceTypeConversionRules>true</EnforceTypeConversionRules>
|
||||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||||
<ExceptionHandling>false</ExceptionHandling>
|
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
@ -222,7 +220,6 @@
|
||||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
<EnforceTypeConversionRules>true</EnforceTypeConversionRules>
|
<EnforceTypeConversionRules>true</EnforceTypeConversionRules>
|
||||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||||
<ExceptionHandling>false</ExceptionHandling>
|
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -97,7 +97,6 @@
|
||||||
<EnforceTypeConversionRules>true</EnforceTypeConversionRules>
|
<EnforceTypeConversionRules>true</EnforceTypeConversionRules>
|
||||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
<ExceptionHandling>false</ExceptionHandling>
|
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
|
@ -137,7 +136,6 @@ copy /y "$(TargetPath)" "H:\Rockstar Games\Grand Theft Auto San Andreas\SilentPa
|
||||||
<EnforceTypeConversionRules>true</EnforceTypeConversionRules>
|
<EnforceTypeConversionRules>true</EnforceTypeConversionRules>
|
||||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
<ExceptionHandling>false</ExceptionHandling>
|
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
@ -179,7 +177,6 @@ copy /y "$(TargetPath)" "H:\Rockstar Games\Grand Theft Auto San Andreas\SilentPa
|
||||||
<EnforceTypeConversionRules>true</EnforceTypeConversionRules>
|
<EnforceTypeConversionRules>true</EnforceTypeConversionRules>
|
||||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
<ExceptionHandling>false</ExceptionHandling>
|
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
|
|
@ -717,7 +717,7 @@ namespace VariableResets
|
||||||
void InjectDelayedPatches_VC_Common( bool bHasDebugMenu, const wchar_t* wcModulePath )
|
void InjectDelayedPatches_VC_Common( bool bHasDebugMenu, const wchar_t* wcModulePath )
|
||||||
{
|
{
|
||||||
using namespace Memory;
|
using namespace Memory;
|
||||||
using namespace hook;
|
using namespace hook::txn;
|
||||||
|
|
||||||
const ModuleList moduleList;
|
const ModuleList moduleList;
|
||||||
|
|
||||||
|
@ -749,139 +749,124 @@ void InjectDelayedPatches_VC_Common( bool bHasDebugMenu, const wchar_t* wcModule
|
||||||
if ( GetPrivateProfileIntW(L"SilentPatch", L"EnableVehicleCoronaFixes", -1, wcModulePath) == 1 )
|
if ( GetPrivateProfileIntW(L"SilentPatch", L"EnableVehicleCoronaFixes", -1, wcModulePath) == 1 )
|
||||||
{
|
{
|
||||||
// Other mods might be touching it, so only patch specific vehicles if their code has not been touched at all
|
// Other mods might be touching it, so only patch specific vehicles if their code has not been touched at all
|
||||||
|
try
|
||||||
{
|
{
|
||||||
auto firetruck1 = pattern( "8D 8C 24 24 09 00 00 FF 35 ? ? ? ? FF 35 ? ? ? ? FF 35" );
|
auto firetruck1 = pattern("8D 8C 24 24 09 00 00 FF 35 ? ? ? ? FF 35 ? ? ? ? FF 35").get_one();
|
||||||
auto firetruck2 = pattern( "8D 8C 24 30 09 00 00 FF 35 ? ? ? ? FF 35 ? ? ? ? FF 35" );
|
auto firetruck2 = pattern("8D 8C 24 30 09 00 00 FF 35 ? ? ? ? FF 35 ? ? ? ? FF 35").get_one();
|
||||||
|
|
||||||
if ( firetruck1.count_hint(1).size() == 1 && firetruck2.count_hint(1).size() == 1 )
|
|
||||||
{
|
|
||||||
static const CVector FIRETRUCK_SIREN_POS(0.95f, 3.2f, 1.4f);
|
static const CVector FIRETRUCK_SIREN_POS(0.95f, 3.2f, 1.4f);
|
||||||
static const float FIRETRUCK_SIREN_MINUS_X = -FIRETRUCK_SIREN_POS.x;
|
static const float FIRETRUCK_SIREN_MINUS_X = -FIRETRUCK_SIREN_POS.x;
|
||||||
|
|
||||||
auto match1 = firetruck1.get_one();
|
Patch( firetruck1.get<float*>( 7 + 2 ), &FIRETRUCK_SIREN_POS.z );
|
||||||
auto match2 = firetruck2.get_one();
|
Patch( firetruck1.get<float*>( 7 + 2 + (6*1) ), &FIRETRUCK_SIREN_POS.y );
|
||||||
|
Patch( firetruck1.get<float*>( 7 + 2 + (6*2) ), &FIRETRUCK_SIREN_POS.x );
|
||||||
|
|
||||||
Patch( match1.get<float*>( 7 + 2 ), &FIRETRUCK_SIREN_POS.z );
|
Patch( firetruck2.get<float*>( 7 + 2 ), &FIRETRUCK_SIREN_POS.z );
|
||||||
Patch( match1.get<float*>( 7 + 2 + (6*1) ), &FIRETRUCK_SIREN_POS.y );
|
Patch( firetruck2.get<float*>( 7 + 2 + (6*1) ), &FIRETRUCK_SIREN_POS.y );
|
||||||
Patch( match1.get<float*>( 7 + 2 + (6*2) ), &FIRETRUCK_SIREN_POS.x );
|
Patch( firetruck2.get<float*>( 7 + 2 + (6*2) ), &FIRETRUCK_SIREN_MINUS_X );
|
||||||
|
|
||||||
Patch( match2.get<float*>( 7 + 2 ), &FIRETRUCK_SIREN_POS.z );
|
|
||||||
Patch( match2.get<float*>( 7 + 2 + (6*1) ), &FIRETRUCK_SIREN_POS.y );
|
|
||||||
Patch( match2.get<float*>( 7 + 2 + (6*2) ), &FIRETRUCK_SIREN_MINUS_X );
|
|
||||||
}
|
}
|
||||||
}
|
TXN_CATCH();
|
||||||
{
|
|
||||||
auto ambulan1 = pattern( "8D 8C 24 0C 09 00 00 FF 35 ? ? ? ? FF 35 ? ? ? ? FF 35" );
|
|
||||||
auto ambulan2 = pattern( "8D 8C 24 18 09 00 00 FF 35 ? ? ? ? FF 35 ? ? ? ? FF 35" );
|
|
||||||
|
|
||||||
if ( ambulan1.count_hint(1).size() == 1 && ambulan2.count_hint(1).size() == 1 )
|
try
|
||||||
{
|
{
|
||||||
|
auto ambulan1 = pattern("8D 8C 24 0C 09 00 00 FF 35 ? ? ? ? FF 35 ? ? ? ? FF 35").get_one();
|
||||||
|
auto ambulan2 = pattern("8D 8C 24 18 09 00 00 FF 35 ? ? ? ? FF 35 ? ? ? ? FF 35").get_one();
|
||||||
|
|
||||||
static const CVector AMBULANCE_SIREN_POS(0.7f, 0.65f, 1.55f);
|
static const CVector AMBULANCE_SIREN_POS(0.7f, 0.65f, 1.55f);
|
||||||
static const float AMBULANCE_SIREN_MINUS_X = -AMBULANCE_SIREN_POS.x;
|
static const float AMBULANCE_SIREN_MINUS_X = -AMBULANCE_SIREN_POS.x;
|
||||||
|
|
||||||
auto match1 = ambulan1.get_one();
|
Patch( ambulan1.get<float*>( 7 + 2 ), &AMBULANCE_SIREN_POS.z );
|
||||||
auto match2 = ambulan2.get_one();
|
Patch( ambulan1.get<float*>( 7 + 2 + (6*1) ), &AMBULANCE_SIREN_POS.y );
|
||||||
|
Patch( ambulan1.get<float*>( 7 + 2 + (6*2) ), &AMBULANCE_SIREN_POS.x );
|
||||||
|
|
||||||
Patch( match1.get<float*>( 7 + 2 ), &AMBULANCE_SIREN_POS.z );
|
Patch( ambulan2.get<float*>( 7 + 2 ), &AMBULANCE_SIREN_POS.z );
|
||||||
Patch( match1.get<float*>( 7 + 2 + (6*1) ), &AMBULANCE_SIREN_POS.y );
|
Patch( ambulan2.get<float*>( 7 + 2 + (6*1) ), &AMBULANCE_SIREN_POS.y );
|
||||||
Patch( match1.get<float*>( 7 + 2 + (6*2) ), &AMBULANCE_SIREN_POS.x );
|
Patch( ambulan2.get<float*>( 7 + 2 + (6*2) ), &AMBULANCE_SIREN_MINUS_X );
|
||||||
|
|
||||||
Patch( match2.get<float*>( 7 + 2 ), &AMBULANCE_SIREN_POS.z );
|
|
||||||
Patch( match2.get<float*>( 7 + 2 + (6*1) ), &AMBULANCE_SIREN_POS.y );
|
|
||||||
Patch( match2.get<float*>( 7 + 2 + (6*2) ), &AMBULANCE_SIREN_MINUS_X );
|
|
||||||
}
|
}
|
||||||
}
|
TXN_CATCH();
|
||||||
{
|
|
||||||
auto police1 = pattern( "8D 8C 24 DC 08 00 00 FF 35 ? ? ? ? FF 35 ? ? ? ? FF 35" );
|
|
||||||
auto police2 = pattern( "8D 8C 24 E8 08 00 00 FF 35 ? ? ? ? FF 35 ? ? ? ? FF 35" );
|
|
||||||
|
|
||||||
if ( police1.count_hint(1).size() == 1 && police2.count_hint(1).size() == 1 )
|
try
|
||||||
{
|
{
|
||||||
|
auto police1 = pattern("8D 8C 24 DC 08 00 00 FF 35 ? ? ? ? FF 35 ? ? ? ? FF 35").get_one();
|
||||||
|
auto police2 = pattern("8D 8C 24 E8 08 00 00 FF 35 ? ? ? ? FF 35 ? ? ? ? FF 35").get_one();
|
||||||
|
|
||||||
static const CVector POLICE_SIREN_POS(0.55f, -0.4f, 0.95f);
|
static const CVector POLICE_SIREN_POS(0.55f, -0.4f, 0.95f);
|
||||||
static const float POLICE_SIREN_MINUS_X = -POLICE_SIREN_POS.x;
|
static const float POLICE_SIREN_MINUS_X = -POLICE_SIREN_POS.x;
|
||||||
|
|
||||||
auto match1 = police1.get_one();
|
Patch( police1.get<float*>( 7 + 2 ), &POLICE_SIREN_POS.z );
|
||||||
auto match2 = police2.get_one();
|
Patch( police1.get<float*>( 7 + 2 + (6*1) ), &POLICE_SIREN_POS.y );
|
||||||
|
Patch( police1.get<float*>( 7 + 2 + (6*2) ), &POLICE_SIREN_POS.x );
|
||||||
|
|
||||||
Patch( match1.get<float*>( 7 + 2 ), &POLICE_SIREN_POS.z );
|
Patch( police2.get<float*>( 7 + 2 ), &POLICE_SIREN_POS.z );
|
||||||
Patch( match1.get<float*>( 7 + 2 + (6*1) ), &POLICE_SIREN_POS.y );
|
Patch( police2.get<float*>( 7 + 2 + (6*1) ), &POLICE_SIREN_POS.y );
|
||||||
Patch( match1.get<float*>( 7 + 2 + (6*2) ), &POLICE_SIREN_POS.x );
|
Patch( police2.get<float*>( 7 + 2 + (6*2) ), &POLICE_SIREN_MINUS_X );
|
||||||
|
|
||||||
Patch( match2.get<float*>( 7 + 2 ), &POLICE_SIREN_POS.z );
|
|
||||||
Patch( match2.get<float*>( 7 + 2 + (6*1) ), &POLICE_SIREN_POS.y );
|
|
||||||
Patch( match2.get<float*>( 7 + 2 + (6*2) ), &POLICE_SIREN_MINUS_X );
|
|
||||||
}
|
}
|
||||||
}
|
TXN_CATCH();
|
||||||
{
|
|
||||||
auto enforcer1 = pattern( "8D 8C 24 F4 08 00 00 FF 35 ? ? ? ? FF 35 ? ? ? ? FF 35" );
|
|
||||||
auto enforcer2 = pattern( "8D 8C 24 00 09 00 00 FF 35 ? ? ? ? FF 35 ? ? ? ? FF 35" );
|
|
||||||
|
|
||||||
if ( enforcer1.count_hint(1).size() == 1 && enforcer2.count_hint(1).size() == 1 )
|
try
|
||||||
{
|
{
|
||||||
|
auto enforcer1 = pattern("8D 8C 24 F4 08 00 00 FF 35 ? ? ? ? FF 35 ? ? ? ? FF 35").get_one();
|
||||||
|
auto enforcer2 = pattern("8D 8C 24 00 09 00 00 FF 35 ? ? ? ? FF 35 ? ? ? ? FF 35").get_one();
|
||||||
|
|
||||||
static const CVector ENFORCER_SIREN_POS(0.6f, 1.05f, 1.4f);
|
static const CVector ENFORCER_SIREN_POS(0.6f, 1.05f, 1.4f);
|
||||||
static const float ENFORCER_SIREN_MINUS_X = -ENFORCER_SIREN_POS.x;
|
static const float ENFORCER_SIREN_MINUS_X = -ENFORCER_SIREN_POS.x;
|
||||||
|
|
||||||
auto match1 = enforcer1.get_one();
|
Patch( enforcer1.get<float*>( 7 + 2 ), &ENFORCER_SIREN_POS.z );
|
||||||
auto match2 = enforcer2.get_one();
|
Patch( enforcer1.get<float*>( 7 + 2 + (6*1) ), &ENFORCER_SIREN_POS.y );
|
||||||
|
Patch( enforcer1.get<float*>( 7 + 2 + (6*2) ), &ENFORCER_SIREN_POS.x );
|
||||||
|
|
||||||
Patch( match1.get<float*>( 7 + 2 ), &ENFORCER_SIREN_POS.z );
|
Patch( enforcer2.get<float*>( 7 + 2 ), &ENFORCER_SIREN_POS.z );
|
||||||
Patch( match1.get<float*>( 7 + 2 + (6*1) ), &ENFORCER_SIREN_POS.y );
|
Patch( enforcer2.get<float*>( 7 + 2 + (6*1) ), &ENFORCER_SIREN_POS.y );
|
||||||
Patch( match1.get<float*>( 7 + 2 + (6*2) ), &ENFORCER_SIREN_POS.x );
|
Patch( enforcer2.get<float*>( 7 + 2 + (6*2) ), &ENFORCER_SIREN_MINUS_X );
|
||||||
|
|
||||||
Patch( match2.get<float*>( 7 + 2 ), &ENFORCER_SIREN_POS.z );
|
|
||||||
Patch( match2.get<float*>( 7 + 2 + (6*1) ), &ENFORCER_SIREN_POS.y );
|
|
||||||
Patch( match2.get<float*>( 7 + 2 + (6*2) ), &ENFORCER_SIREN_MINUS_X );
|
|
||||||
}
|
}
|
||||||
}
|
TXN_CATCH();
|
||||||
{
|
|
||||||
auto chopper1 = pattern( "C7 44 24 44 00 00 E0 40 50 C7 44 24 4C 00 00 00 00" ); // Front light
|
|
||||||
auto chopper2 = pattern( "C7 44 24 6C 00 00 10 C1 8D 44 24 5C C7 44 24 70 00 00 00 00" ); // Tail light
|
|
||||||
|
|
||||||
if ( chopper1.count_hint(1).size() == 1 )
|
|
||||||
{
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
auto chopper1 = pattern("C7 44 24 44 00 00 E0 40 50 C7 44 24 4C 00 00 00 00").get_one(); // Front light
|
||||||
|
|
||||||
constexpr CVector CHOPPER_SEARCH_LIGHT_POS(0.0f, 3.0f, -1.0f); // Same as in III Aircraft (not implemented there yet!)
|
constexpr CVector CHOPPER_SEARCH_LIGHT_POS(0.0f, 3.0f, -1.0f); // Same as in III Aircraft (not implemented there yet!)
|
||||||
|
|
||||||
auto match = chopper1.get_one();
|
Patch( chopper1.get<float>( 4 ), CHOPPER_SEARCH_LIGHT_POS.y );
|
||||||
|
Patch( chopper1.get<float>( 9 + 4 ), CHOPPER_SEARCH_LIGHT_POS.z );
|
||||||
Patch( match.get<float>( 4 ), CHOPPER_SEARCH_LIGHT_POS.y );
|
|
||||||
Patch( match.get<float>( 9 + 4 ), CHOPPER_SEARCH_LIGHT_POS.z );
|
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
if ( chopper2.count_hint(1).size() == 1 )
|
try
|
||||||
{
|
{
|
||||||
|
auto chopper2 = pattern("C7 44 24 6C 00 00 10 C1 8D 44 24 5C C7 44 24 70 00 00 00 00").get_one(); // Tail light
|
||||||
|
|
||||||
constexpr CVector CHOPPER_RED_LIGHT_POS(0.0f, -7.5f, 2.5f); // Same as in III Aircraft
|
constexpr CVector CHOPPER_RED_LIGHT_POS(0.0f, -7.5f, 2.5f); // Same as in III Aircraft
|
||||||
|
|
||||||
auto match = chopper2.get_one();
|
Patch( chopper2.get<float>( 4 ), CHOPPER_RED_LIGHT_POS.y );
|
||||||
|
Patch( chopper2.get<float>( 12 + 4 ), CHOPPER_RED_LIGHT_POS.z );
|
||||||
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
}
|
||||||
|
|
||||||
Patch( match.get<float>( 4 ), CHOPPER_RED_LIGHT_POS.y );
|
try
|
||||||
Patch( match.get<float>( 12 + 4 ), CHOPPER_RED_LIGHT_POS.z );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
using namespace FBISirenCoronaFix;
|
using namespace FBISirenCoronaFix;
|
||||||
|
|
||||||
auto hasFBISiren = pattern( "83 E9 04 0F 84 87 0A 00 00 83 E9 10" ); // Predicate for showing FBI/Vice Squad siren
|
auto viceCheetah = pattern("8D 8C 24 CC 09 00 00 FF 35 ? ? ? ? FF 35 ? ? ? ? FF 35 ? ? ? ? E8").get_one(); // Siren pos
|
||||||
auto viceCheetah = pattern( "8D 8C 24 CC 09 00 00 FF 35 ? ? ? ? FF 35 ? ? ? ? FF 35 ? ? ? ? E8" ); // Siren pos
|
|
||||||
|
|
||||||
if ( viceCheetah.count_hint(1).size() == 1 )
|
try
|
||||||
{
|
{
|
||||||
auto match = viceCheetah.get_one();
|
auto hasFBISiren = pattern("83 E9 04 0F 84 87 0A 00 00 83 E9 10").get_one(); // Predicate for showing FBI/Vice Squad siren
|
||||||
|
|
||||||
if ( hasFBISiren.count_hint(1).size() == 1 )
|
Patch<uint8_t>( hasFBISiren.get<void>(), 0x55 ); // push ebp
|
||||||
{
|
InjectHook( hasFBISiren.get<void>( 1 ), SetUpFBISiren, HookType::Call );
|
||||||
auto matchSiren = hasFBISiren.get_one();
|
Patch( hasFBISiren.get<void>( 1 + 5 ), { 0x83, 0xC4, 0x04, 0x84, 0xC0, 0x90 } ); // add esp, 4 / test al, al / nop
|
||||||
|
|
||||||
Patch<uint8_t>( matchSiren.get<void>(), 0x55 ); // push ebp
|
InjectHook( viceCheetah.get<void>( 0x19 ), SetUpVector );
|
||||||
InjectHook( matchSiren.get<void>( 1 ), SetUpFBISiren, HookType::Call );
|
|
||||||
Patch( matchSiren.get<void>( 1 + 5 ), { 0x83, 0xC4, 0x04, 0x84, 0xC0, 0x90 } ); // add esp, 4 / test al, al / nop
|
|
||||||
|
|
||||||
InjectHook( match.get<void>( 0x19 ), SetUpVector );
|
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
static const float VICE_CHEETAH_SIREN_POS_Z = 0.25f;
|
static const float VICE_CHEETAH_SIREN_POS_Z = 0.25f;
|
||||||
Patch( match.get<float*>( 7 + 2 ), &VICE_CHEETAH_SIREN_POS_Z );
|
Patch( viceCheetah.get<float*>( 7 + 2 ), &VICE_CHEETAH_SIREN_POS_Z );
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
FLAUtils::Init(moduleList);
|
FLAUtils::Init(moduleList);
|
||||||
|
@ -1180,9 +1165,10 @@ void Patch_VC_JP()
|
||||||
void Patch_VC_Common()
|
void Patch_VC_Common()
|
||||||
{
|
{
|
||||||
using namespace Memory;
|
using namespace Memory;
|
||||||
using namespace hook;
|
using namespace hook::txn;
|
||||||
|
|
||||||
// New timers fix
|
// New timers fix
|
||||||
|
try
|
||||||
{
|
{
|
||||||
auto hookPoint = pattern( "83 E4 F8 89 44 24 08 C7 44 24 0C 00 00 00 00 DF 6C 24 08" ).get_one();
|
auto hookPoint = pattern( "83 E4 F8 89 44 24 08 C7 44 24 0C 00 00 00 00 DF 6C 24 08" ).get_one();
|
||||||
auto jmpPoint = get_pattern( "DD D8 E9 31 FF FF FF" );
|
auto jmpPoint = get_pattern( "DD D8 E9 31 FF FF FF" );
|
||||||
|
@ -1190,8 +1176,11 @@ void Patch_VC_Common()
|
||||||
InjectHook( hookPoint.get<void>( 0x21 ), CTimer::Update_SilentPatch, HookType::Call );
|
InjectHook( hookPoint.get<void>( 0x21 ), CTimer::Update_SilentPatch, HookType::Call );
|
||||||
InjectHook( hookPoint.get<void>( 0x21 + 5 ), jmpPoint, HookType::Jump );
|
InjectHook( hookPoint.get<void>( 0x21 + 5 ), jmpPoint, HookType::Jump );
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Alt+F4
|
// Alt+F4
|
||||||
|
try
|
||||||
{
|
{
|
||||||
auto addr = pattern( "59 59 31 C0 83 C4 70 5D 5F 5E 5B C2 10 00" ).count(2);
|
auto addr = pattern( "59 59 31 C0 83 C4 70 5D 5F 5E 5B C2 10 00" ).count(2);
|
||||||
auto dest = get_pattern( "53 55 56 FF B4 24 90 00 00 00 FF 15" );
|
auto dest = get_pattern( "53 55 56 FF B4 24 90 00 00 00 FF 15" );
|
||||||
|
@ -1200,8 +1189,11 @@ void Patch_VC_Common()
|
||||||
InjectHook( match.get<void>( 2 ), dest, HookType::Jump );
|
InjectHook( match.get<void>( 2 ), dest, HookType::Jump );
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Proper panels damage
|
// Proper panels damage
|
||||||
|
try
|
||||||
{
|
{
|
||||||
auto addr = pattern( "C6 41 09 03 C6 41 0A 03 C6 41 0B 03" ).get_one();
|
auto addr = pattern( "C6 41 09 03 C6 41 0A 03 C6 41 0B 03" ).get_one();
|
||||||
|
|
||||||
|
@ -1212,20 +1204,27 @@ void Patch_VC_Common()
|
||||||
|
|
||||||
Nop( addr.get<void>( 0x33 ), 7 );
|
Nop( addr.get<void>( 0x33 ), 7 );
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Proper metric-imperial conversion constants
|
// Proper metric-imperial conversion constants
|
||||||
|
try
|
||||||
{
|
{
|
||||||
static const float METERS_TO_MILES = 0.0006213711922f;
|
static const float METERS_TO_MILES = 0.0006213711922f;
|
||||||
auto addr = pattern( "75 ? D9 05 ? ? ? ? D8 0D ? ? ? ? 6A 00 6A 00 D9 9C 24" ).count(6);
|
auto addr = pattern( "75 ? D9 05 ? ? ? ? D8 0D ? ? ? ? 6A 00 6A 00 D9 9C 24" ).count(6);
|
||||||
|
auto sum = get_pattern( "D9 9C 24 A8 00 00 00 8D 84 24 A8 00 00 00 50", -6 + 2 );
|
||||||
|
|
||||||
addr.for_each_result( [&]( pattern_match match ) {
|
addr.for_each_result( [&]( pattern_match match ) {
|
||||||
Patch<const void*>( match.get<void>( 0x8 + 2 ), &METERS_TO_MILES );
|
Patch<const void*>( match.get<void>( 0x8 + 2 ), &METERS_TO_MILES );
|
||||||
});
|
});
|
||||||
|
|
||||||
auto sum = get_pattern( "D9 9C 24 A8 00 00 00 8D 84 24 A8 00 00 00 50", -6 + 2 );
|
|
||||||
Patch<const void*>( sum, &METERS_TO_MILES );
|
Patch<const void*>( sum, &METERS_TO_MILES );
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Improved pathfinding in PickNextNodeAccordingStrategy - PickNextNodeToChaseCar with XYZ coords
|
// Improved pathfinding in PickNextNodeAccordingStrategy - PickNextNodeToChaseCar with XYZ coords
|
||||||
|
try
|
||||||
{
|
{
|
||||||
auto addr = pattern( "E8 ? ? ? ? 50 8D 44 24 10 50 E8" ).get_one();
|
auto addr = pattern( "E8 ? ? ? ? 50 8D 44 24 10 50 E8" ).get_one();
|
||||||
ReadCall( addr.get<void>( 0x25 ), orgPickNextNodeToChaseCar );
|
ReadCall( addr.get<void>( 0x25 ), orgPickNextNodeToChaseCar );
|
||||||
|
@ -1258,25 +1257,31 @@ void Patch_VC_Common()
|
||||||
InjectHook( addr.get<void>( 0x46 ), PickNextNodeToChaseCarXYZ );
|
InjectHook( addr.get<void>( 0x46 ), PickNextNodeToChaseCarXYZ );
|
||||||
Patch<uint8_t>( addr.get<void>( 0x4B + 2 ), 0xC );
|
Patch<uint8_t>( addr.get<void>( 0x4B + 2 ), 0xC );
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// No censorships
|
// No censorships
|
||||||
|
try
|
||||||
{
|
{
|
||||||
auto addr = get_pattern( "8B 43 50 85 C0 8B 53 50 74 2B 83 E8 01" );
|
auto addr = get_pattern( "8B 43 50 85 C0 8B 53 50 74 2B 83 E8 01" );
|
||||||
Patch( addr, { 0x83, 0xC4, 0x08, 0x5B, 0xC3 } ); // add esp, 8 \ pop ebx \ retn
|
Patch( addr, { 0x83, 0xC4, 0x08, 0x5B, 0xC3 } ); // add esp, 8 \ pop ebx \ retn
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// 014C cargen counter fix (by spaceeinstein)
|
// 014C cargen counter fix (by spaceeinstein)
|
||||||
|
try
|
||||||
{
|
{
|
||||||
auto do_processing = pattern( "0F B7 43 28 83 F8 FF 7D 04 66 FF 4B 28" ).get_one();
|
auto do_processing = pattern( "0F B7 43 28 83 F8 FF 7D 04 66 FF 4B 28" ).get_one();
|
||||||
|
|
||||||
Patch<uint8_t>( do_processing.get<uint8_t*>(1), 0xBF ); // movzx eax, word ptr [ebx+28h] -> movsx eax, word ptr [ebx+28h]
|
Patch<uint8_t>( do_processing.get<uint8_t*>(1), 0xBF ); // movzx eax, word ptr [ebx+28h] -> movsx eax, word ptr [ebx+28h]
|
||||||
Patch<uint8_t>( do_processing.get<uint8_t*>(7), 0x74 ); // jge -> jz
|
Patch<uint8_t>( do_processing.get<uint8_t*>(7), 0x74 ); // jge -> jz
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Fixed ammo from SCM
|
// Fixed ammo from SCM
|
||||||
|
try
|
||||||
{
|
{
|
||||||
using namespace ZeroAmmoFix;
|
using namespace ZeroAmmoFix;
|
||||||
|
|
||||||
|
@ -1286,16 +1291,20 @@ void Patch_VC_Common()
|
||||||
};
|
};
|
||||||
HookEach_GiveWeapon(give_weapon, InterceptCall);
|
HookEach_GiveWeapon(give_weapon, InterceptCall);
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Extras working correctly on bikes
|
// Extras working correctly on bikes
|
||||||
|
try
|
||||||
{
|
{
|
||||||
auto createInstance = get_pattern( "89 C1 8B 41 04" );
|
auto createInstance = get_pattern( "89 C1 8B 41 04" );
|
||||||
InjectHook( createInstance, CreateInstance_BikeFix, HookType::Call );
|
InjectHook( createInstance, CreateInstance_BikeFix, HookType::Call );
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Credits =)
|
// Credits =)
|
||||||
|
try
|
||||||
{
|
{
|
||||||
auto renderCredits = pattern( "8D 44 24 28 83 C4 14 50 FF 35 ? ? ? ? E8 ? ? ? ? 8D 44 24 1C 59 59 50 FF 35 ? ? ? ? E8 ? ? ? ? 59 59" ).get_one();
|
auto renderCredits = pattern( "8D 44 24 28 83 C4 14 50 FF 35 ? ? ? ? E8 ? ? ? ? 8D 44 24 1C 59 59 50 FF 35 ? ? ? ? E8 ? ? ? ? 59 59" ).get_one();
|
||||||
|
|
||||||
|
@ -1303,9 +1312,11 @@ void Patch_VC_Common()
|
||||||
ReadCall( renderCredits.get<void>( -5 ), Credits::PrintCreditText_Hooked );
|
ReadCall( renderCredits.get<void>( -5 ), Credits::PrintCreditText_Hooked );
|
||||||
InjectHook( renderCredits.get<void>( -5 ), Credits::PrintSPCredits );
|
InjectHook( renderCredits.get<void>( -5 ), Credits::PrintSPCredits );
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Decreased keyboard input latency
|
// Decreased keyboard input latency
|
||||||
|
try
|
||||||
{
|
{
|
||||||
using namespace KeyboardInputFix;
|
using namespace KeyboardInputFix;
|
||||||
|
|
||||||
|
@ -1321,42 +1332,44 @@ void Patch_VC_Common()
|
||||||
InjectHook( simButtonCheckers, ClearSimButtonPressCheckers );
|
InjectHook( simButtonCheckers, ClearSimButtonPressCheckers );
|
||||||
InjectHook( updatePads.get<void>( 9 ), jmpDest, HookType::Jump );
|
InjectHook( updatePads.get<void>( 9 ), jmpDest, HookType::Jump );
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Locale based metric/imperial system
|
// Locale based metric/imperial system
|
||||||
|
try
|
||||||
{
|
{
|
||||||
using namespace Localization;
|
using namespace Localization;
|
||||||
|
|
||||||
void* updateCompareFlag = get_pattern( "89 D9 6A 00 E8 ? ? ? ? 30 C0 83 C4 70 5D 5F 5E 5B C2 04 00", 4 );
|
void* updateCompareFlag = get_pattern( "89 D9 6A 00 E8 ? ? ? ? 30 C0 83 C4 70 5D 5F 5E 5B C2 04 00", 4 );
|
||||||
|
auto constructStatLine = pattern( "85 C0 74 11 83 E8 01 83 F8 03" ).get_one();
|
||||||
|
|
||||||
ReadCall( updateCompareFlag, orgUpdateCompareFlag_IsMetric );
|
ReadCall( updateCompareFlag, orgUpdateCompareFlag_IsMetric );
|
||||||
InjectHook( updateCompareFlag, UpdateCompareFlag_IsMetric );
|
InjectHook( updateCompareFlag, UpdateCompareFlag_IsMetric );
|
||||||
|
|
||||||
// Stats
|
// Stats
|
||||||
auto constructStatLine = pattern( "85 C0 74 11 83 E8 01 83 F8 03" ).get_one();
|
|
||||||
|
|
||||||
Nop( constructStatLine.get<void>( -11 ), 1 );
|
Nop( constructStatLine.get<void>( -11 ), 1 );
|
||||||
InjectHook( constructStatLine.get<void>( -11 + 1 ), PrefsLanguage_IsMetric, HookType::Call );
|
InjectHook( constructStatLine.get<void>( -11 + 1 ), PrefsLanguage_IsMetric, HookType::Call );
|
||||||
Nop( constructStatLine.get<void>( -2 ), 2 );
|
Nop( constructStatLine.get<void>( -2 ), 2 );
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Corrected FBI Washington sirens sound
|
// Corrected FBI Washington sirens sound
|
||||||
// Primary siren lower pitched like in FBI Rancher and secondary siren higher pitched
|
// Primary siren lower pitched like in FBI Rancher and secondary siren higher pitched
|
||||||
|
try
|
||||||
{
|
{
|
||||||
using namespace SirenSwitchingFix;
|
using namespace SirenSwitchingFix;
|
||||||
|
|
||||||
// Other mods might be touching it, so only patch specific vehicles if their code has not been touched at all
|
// Other mods might be touching it, so only patch specific vehicles if their code has not been touched at all
|
||||||
auto sirenPitch = pattern( "83 F8 17 74 32" ).count_hint(1);
|
auto sirenPitch = pattern( "83 F8 17 74 32" ).get_one();
|
||||||
if ( sirenPitch.size() == 1 )
|
|
||||||
{
|
|
||||||
auto match = sirenPitch.get_one();
|
|
||||||
|
|
||||||
InjectHook( match.get<void>( 5 ), IsFBIRanchOrFBICar, HookType::Call );
|
InjectHook( sirenPitch.get<void>( 5 ), IsFBIRanchOrFBICar, HookType::Call );
|
||||||
Patch( match.get<void>( 5 + 5 ), { 0x84, 0xC0 } ); // test al, al
|
Patch( sirenPitch.get<void>( 5 + 5 ), { 0x84, 0xC0 } ); // test al, al
|
||||||
Nop( match.get<void>( 5 + 5 + 2 ), 4 );
|
Nop( sirenPitch.get<void>( 5 + 5 + 2 ), 4 );
|
||||||
|
|
||||||
// Pitch shift FBI Washington primary siren
|
// Pitch shift FBI Washington primary siren
|
||||||
|
try
|
||||||
|
{
|
||||||
struct tVehicleSampleData {
|
struct tVehicleSampleData {
|
||||||
int m_nAccelerationSampleIndex;
|
int m_nAccelerationSampleIndex;
|
||||||
char m_bEngineSoundType;
|
char m_bEngineSoundType;
|
||||||
|
@ -1375,20 +1388,25 @@ void Patch_VC_Common()
|
||||||
dataTable[17].m_nSirenOrAlarmFrequency = dataTable[90].m_nSirenOrAlarmFrequency;
|
dataTable[17].m_nSirenOrAlarmFrequency = dataTable[90].m_nSirenOrAlarmFrequency;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Allow extra6 to be picked with component rule 4 (any)
|
// Allow extra6 to be picked with component rule 4 (any)
|
||||||
|
try
|
||||||
{
|
{
|
||||||
void* extraMult6 = get_pattern( "D8 0D ? ? ? ? D9 7C 24 04 8B 44 24 04 80 4C 24 05 0C D9 6C 24 04 89 44 24 04 DB 5C 24 08 D9 6C 24 04 8B 44 24 08 83 C4 10 5D", 2 );
|
void* extraMult6 = get_pattern( "D8 0D ? ? ? ? D9 7C 24 04 8B 44 24 04 80 4C 24 05 0C D9 6C 24 04 89 44 24 04 DB 5C 24 08 D9 6C 24 04 8B 44 24 08 83 C4 10 5D", 2 );
|
||||||
|
|
||||||
static const float MULT_6 = 6.0f;
|
static const float MULT_6 = 6.0f;
|
||||||
Patch( extraMult6, &MULT_6 );
|
Patch( extraMult6, &MULT_6 );
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Make drive-by one shot sounds owned by the driver instead of the car
|
// Make drive-by one shot sounds owned by the driver instead of the car
|
||||||
// Fixes incorrect weapon sound being used for drive-by
|
// Fixes incorrect weapon sound being used for drive-by
|
||||||
|
try
|
||||||
{
|
{
|
||||||
auto getDriverOneShot = pattern( "FF 35 ? ? ? ? 6A 37 50 E8 ? ? ? ? 83 7E 08 00" ).get_one();
|
auto getDriverOneShot = pattern( "FF 35 ? ? ? ? 6A 37 50 E8 ? ? ? ? 83 7E 08 00" ).get_one();
|
||||||
|
|
||||||
|
@ -1398,9 +1416,11 @@ void Patch_VC_Common()
|
||||||
Patch( getDriverOneShot.get<void>( -8 ), { 0x90, 0x89, 0xD9 } );
|
Patch( getDriverOneShot.get<void>( -8 ), { 0x90, 0x89, 0xD9 } );
|
||||||
InjectHook( getDriverOneShot.get<void>( -5 ), &CVehicle::GetOneShotOwnerID_SilentPatch, HookType::Call );
|
InjectHook( getDriverOneShot.get<void>( -5 ), &CVehicle::GetOneShotOwnerID_SilentPatch, HookType::Call );
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Fixed vehicles exploding twice if the driver leaves the car while it's exploding
|
// Fixed vehicles exploding twice if the driver leaves the car while it's exploding
|
||||||
|
try
|
||||||
{
|
{
|
||||||
using namespace RemoveDriverStatusFix;
|
using namespace RemoveDriverStatusFix;
|
||||||
|
|
||||||
|
@ -1419,9 +1439,11 @@ void Patch_VC_Common()
|
||||||
Nop(removeThisPed, 3);
|
Nop(removeThisPed, 3);
|
||||||
Nop(pedSetOutCar, 3);
|
Nop(pedSetOutCar, 3);
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Apply the environment mapping on extra components
|
// Apply the environment mapping on extra components
|
||||||
|
try
|
||||||
{
|
{
|
||||||
using namespace EnvMapsOnExtras;
|
using namespace EnvMapsOnExtras;
|
||||||
|
|
||||||
|
@ -1431,17 +1453,21 @@ void Patch_VC_Common()
|
||||||
Patch<uint8_t>(forAllAtomics.get<void>(), 0x53);
|
Patch<uint8_t>(forAllAtomics.get<void>(), 0x53);
|
||||||
InterceptCall(forAllAtomics.get<void>(1), orgRpClumpForAllAtomics, RpClumpForAllAtomics_ExtraComps);
|
InterceptCall(forAllAtomics.get<void>(1), orgRpClumpForAllAtomics, RpClumpForAllAtomics_ExtraComps);
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Fix probabilities in CVehicle::InflictDamage incorrectly assuming a random range from 0 to 100.000
|
// Fix probabilities in CVehicle::InflictDamage incorrectly assuming a random range from 0 to 100.000
|
||||||
|
try
|
||||||
{
|
{
|
||||||
auto probability = get_pattern("66 81 7B 5A ? ? 73 50", 4);
|
auto probability = get_pattern("66 81 7B 5A ? ? 73 50", 4);
|
||||||
|
|
||||||
Patch<uint16_t>(probability, 35000u / 2u);
|
Patch<uint16_t>(probability, 35000u / 2u);
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Null terminate read lines in CPlane::LoadPath
|
// Null terminate read lines in CPlane::LoadPath
|
||||||
|
try
|
||||||
{
|
{
|
||||||
using namespace NullTerminatedLines;
|
using namespace NullTerminatedLines;
|
||||||
|
|
||||||
|
@ -1449,9 +1475,11 @@ void Patch_VC_Common()
|
||||||
|
|
||||||
InterceptCall(loadPath, orgSscanf_LoadPath, sscanf1_LoadPath_Terminate);
|
InterceptCall(loadPath, orgSscanf_LoadPath, sscanf1_LoadPath_Terminate);
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Don't reset mouse sensitivity on New Game
|
// Don't reset mouse sensitivity on New Game
|
||||||
|
try
|
||||||
{
|
{
|
||||||
using namespace MouseSensNewGame;
|
using namespace MouseSensNewGame;
|
||||||
|
|
||||||
|
@ -1464,9 +1492,11 @@ void Patch_VC_Common()
|
||||||
Nop(cameraInit.get<void>(20), 10);
|
Nop(cameraInit.get<void>(20), 10);
|
||||||
InterceptCall(setDirMyDocuments, orgSetDirMyDocuments, SetDirMyDocuments_ResetMouse);
|
InterceptCall(setDirMyDocuments, orgSetDirMyDocuments, SetDirMyDocuments_ResetMouse);
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Fixed pickup effects
|
// Fixed pickup effects
|
||||||
|
try
|
||||||
{
|
{
|
||||||
using namespace PickupEffectsFixes;
|
using namespace PickupEffectsFixes;
|
||||||
|
|
||||||
|
@ -1479,22 +1509,24 @@ void Patch_VC_Common()
|
||||||
|
|
||||||
// Don't spawn the grenade together with the detonator in the pickup
|
// Don't spawn the grenade together with the detonator in the pickup
|
||||||
// FLA might be altering this due to the usage of 16-bit IDs? Just in case allow for graceful failure
|
// FLA might be altering this due to the usage of 16-bit IDs? Just in case allow for graceful failure
|
||||||
auto pickupExtraObject = pattern("75 04 66 8B 70 58").count_hint(1);
|
try
|
||||||
if (pickupExtraObject.size() == 1)
|
|
||||||
{
|
{
|
||||||
auto match = pickupExtraObject.get_one();
|
auto pickupExtraObject = pattern("75 04 66 8B 70 58").get_one();
|
||||||
|
|
||||||
Nop(match.get<void>(), 1);
|
Nop(pickupExtraObject.get<void>(), 1);
|
||||||
InjectHook(match.get<void>(1), &PickUpEffects_GiveUsAnObject, HookType::Call);
|
InjectHook(pickupExtraObject.get<void>(1), &PickUpEffects_GiveUsAnObject, HookType::Call);
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
InjectHook(bigDollarColor, &PickUpEffects_BigDollarColor, HookType::Call);
|
InjectHook(bigDollarColor, &PickUpEffects_BigDollarColor, HookType::Call);
|
||||||
InjectHook(minigun2Glow, &PickUpEffects_Minigun2Glow, HookType::Call);
|
InjectHook(minigun2Glow, &PickUpEffects_Minigun2Glow, HookType::Call);
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Fixed the muzzle flash facing the wrong direction
|
// Fixed the muzzle flash facing the wrong direction
|
||||||
// By Wesser
|
// By Wesser
|
||||||
|
try
|
||||||
{
|
{
|
||||||
auto fireInstantHit = pattern("D9 44 24 50 D8 44 24 44").get_one();
|
auto fireInstantHit = pattern("D9 44 24 50 D8 44 24 44").get_one();
|
||||||
|
|
||||||
|
@ -1503,11 +1535,13 @@ void Patch_VC_Common()
|
||||||
Patch(fireInstantHit.get<void>(15), { 0xD9, 0xEE, 0x90, 0x90 });
|
Patch(fireInstantHit.get<void>(15), { 0xD9, 0xEE, 0x90, 0x90 });
|
||||||
Patch(fireInstantHit.get<void>(30), { 0xD9, 0xEE, 0x90, 0x90 });
|
Patch(fireInstantHit.get<void>(30), { 0xD9, 0xEE, 0x90, 0x90 });
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Fixed IS_PLAYER_TARGETTING_CHAR incorrectly detecting targetting in Classic controls
|
// Fixed IS_PLAYER_TARGETTING_CHAR incorrectly detecting targetting in Classic controls
|
||||||
// when the player is not aiming
|
// when the player is not aiming
|
||||||
// By Wesser
|
// By Wesser
|
||||||
|
try
|
||||||
{
|
{
|
||||||
using namespace IsPlayerTargettingCharFix;
|
using namespace IsPlayerTargettingCharFix;
|
||||||
|
|
||||||
|
@ -1525,17 +1559,21 @@ void Patch_VC_Common()
|
||||||
memmove(isPlayerTargettingChar.get<void>(), isPlayerTargettingChar.get<void>(5), 5);
|
memmove(isPlayerTargettingChar.get<void>(), isPlayerTargettingChar.get<void>(5), 5);
|
||||||
InjectHook(isPlayerTargettingChar.get<void>(5), IsPlayerTargettingChar_ExtraChecks, HookType::Call);
|
InjectHook(isPlayerTargettingChar.get<void>(5), IsPlayerTargettingChar_ExtraChecks, HookType::Call);
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Use PS2 randomness for Rosenberg audio to hopefully bring the odds closer to PS2
|
// Use PS2 randomness for Rosenberg audio to hopefully bring the odds closer to PS2
|
||||||
// The functionality was never broken on PC - but the random distribution seemingly made it looks as if it was
|
// The functionality was never broken on PC - but the random distribution seemingly made it looks as if it was
|
||||||
|
try
|
||||||
{
|
{
|
||||||
auto busted_audio_rand = get_pattern("80 BB 48 01 00 00 00 0F 85 ? ? ? ? E8 ? ? ? ? 25 FF FF 00 00", 13);
|
auto busted_audio_rand = get_pattern("80 BB 48 01 00 00 00 0F 85 ? ? ? ? E8 ? ? ? ? 25 FF FF 00 00", 13);
|
||||||
InjectHook(busted_audio_rand, rand15_ps2);
|
InjectHook(busted_audio_rand, rand15_ps2);
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Reset variables on New Game
|
// Reset variables on New Game
|
||||||
|
try
|
||||||
{
|
{
|
||||||
using namespace VariableResets;
|
using namespace VariableResets;
|
||||||
|
|
||||||
|
@ -1553,30 +1591,28 @@ void Patch_VC_Common()
|
||||||
GameVariablesToReset.emplace_back(*get_pattern<int*>("7D 78 A1 ? ? ? ? 05", 2 + 1)); // LastTimeAmbulanceCreated
|
GameVariablesToReset.emplace_back(*get_pattern<int*>("7D 78 A1 ? ? ? ? 05", 2 + 1)); // LastTimeAmbulanceCreated
|
||||||
GameVariablesToReset.emplace_back(*get_pattern<int*>("A1 ? ? ? ? 05 ? ? ? ? 39 05 ? ? ? ? 0F 86 ? ? ? ? 8B 15", 1)); // LastTimeFireTruckCreated
|
GameVariablesToReset.emplace_back(*get_pattern<int*>("A1 ? ? ? ? 05 ? ? ? ? 39 05 ? ? ? ? 0F 86 ? ? ? ? 8B 15", 1)); // LastTimeFireTruckCreated
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Ped speech fix
|
// Ped speech fix
|
||||||
// Based off Sergenaur's fix
|
// Based off Sergenaur's fix
|
||||||
|
try
|
||||||
{
|
{
|
||||||
// Remove the artificial 6s delay between any ped speech samples
|
// Remove the artificial 6s delay between any ped speech samples
|
||||||
auto delay_check = pattern("80 BE ? ? ? ? ? 0F 85 ? ? ? ? B9");
|
auto delay_check = get_pattern("80 BE ? ? ? ? ? 0F 85 ? ? ? ? B9", 7);
|
||||||
auto comment_delay_id1 = pattern("0F B7 C2 DD D8 C1 E0 04");
|
auto comment_delay_id1 = get_pattern("0F B7 C2 DD D8 C1 E0 04");
|
||||||
auto comment_delay_id2 = pattern("0F B7 95 DA 05 00 00 D9 6C 24 04");
|
auto comment_delay_id2 = pattern("0F B7 95 DA 05 00 00 D9 6C 24 04").get_one();
|
||||||
|
|
||||||
// Make sure we don't conflict with Sergenaur's fix
|
Nop(delay_check, 6);
|
||||||
if (delay_check.count_hint(1).size() == 1 && comment_delay_id1.count_hint(1).size() == 1 && comment_delay_id2.count_hint(1).size() == 1)
|
|
||||||
{
|
|
||||||
Nop(delay_check.get_first<void>(7), 6);
|
|
||||||
|
|
||||||
// movzx eax, dx -> movzx eax, bx
|
// movzx eax, dx -> movzx eax, bx
|
||||||
Patch(comment_delay_id1.get_first<void>(), { 0x0F, 0xB7, 0xC3 });
|
Patch(comment_delay_id1, { 0x0F, 0xB7, 0xC3 });
|
||||||
|
|
||||||
// movzx edx, word ptr [ebp+5DAh] -> movzx edx, bx \ nop
|
// movzx edx, word ptr [ebp+5DAh] -> movzx edx, bx \ nop
|
||||||
auto delay_id2 = comment_delay_id2.get_one();
|
Patch(comment_delay_id2.get<void>(), { 0x0F, 0xB7, 0xD3 });
|
||||||
Patch(delay_id2.get<void>(), { 0x0F, 0xB7, 0xD3 });
|
Nop(comment_delay_id2.get<void>(3), 4);
|
||||||
Nop(delay_id2.get<void>(3), 4);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
TXN_CATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||||
|
|
|
@ -82,7 +82,6 @@
|
||||||
<EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
|
<EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
|
||||||
<AdditionalOptions>/Zc:threadSafeInit- /Zc:strictStrings %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/Zc:threadSafeInit- /Zc:strictStrings %(AdditionalOptions)</AdditionalOptions>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<ExceptionHandling>false</ExceptionHandling>
|
|
||||||
<EnforceTypeConversionRules>true</EnforceTypeConversionRules>
|
<EnforceTypeConversionRules>true</EnforceTypeConversionRules>
|
||||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
|
@ -114,7 +113,6 @@
|
||||||
<EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
|
<EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
|
||||||
<AdditionalOptions>/Zc:threadSafeInit- /Zc:strictStrings %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/Zc:threadSafeInit- /Zc:strictStrings %(AdditionalOptions)</AdditionalOptions>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<ExceptionHandling>false</ExceptionHandling>
|
|
||||||
<EnforceTypeConversionRules>true</EnforceTypeConversionRules>
|
<EnforceTypeConversionRules>true</EnforceTypeConversionRules>
|
||||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
|
@ -148,7 +146,6 @@
|
||||||
<EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
|
<EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
|
||||||
<AdditionalOptions>/Zc:threadSafeInit- /Zc:strictStrings %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/Zc:threadSafeInit- /Zc:strictStrings %(AdditionalOptions)</AdditionalOptions>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<ExceptionHandling>false</ExceptionHandling>
|
|
||||||
<EnforceTypeConversionRules>true</EnforceTypeConversionRules>
|
<EnforceTypeConversionRules>true</EnforceTypeConversionRules>
|
||||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
|
|
Loading…
Reference in a new issue