diff --git a/SilentPatchIII/SilentPatchIII.cpp b/SilentPatchIII/SilentPatchIII.cpp index 171bcef..9e7b99d 100644 --- a/SilentPatchIII/SilentPatchIII.cpp +++ b/SilentPatchIII/SilentPatchIII.cpp @@ -361,16 +361,6 @@ int NewFrameRender(int nEvent, void* pParam) return RsEventHandler(nEvent, pParam); } -static signed int& LastTimeFireTruckCreated = **(int**)Memory::DynBaseAddress(0x41D2E5); -static signed int& LastTimeAmbulanceCreated = **(int**)Memory::DynBaseAddress(0x41D2F9); -static void (*orgCarCtrlReInit)(); -void CarCtrlReInit_SilentPatch() -{ - orgCarCtrlReInit(); - LastTimeFireTruckCreated = 0; - LastTimeAmbulanceCreated = 0; -} - static void (*orgPickNextNodeToChaseCar)(void*, float, float, void*); static float PickNextNodeToChaseCarZ = 0.0f; static void PickNextNodeToChaseCarXYZ( void* vehicle, const CVector& vec, void* chaseTarget ) @@ -695,6 +685,49 @@ namespace DodoKeyboardControls } +// ============= Resetting stats and variables on New Game ============= +namespace VariableResets +{ + static auto TimerInitialise = reinterpret_cast(hook::get_pattern("83 E4 F8 68 ? ? ? ? E8", -6)); + + using VarVariant = std::variant< bool*, int* >; + std::vector GameVariablesToReset; + + static void ReInitOurVariables() + { + for ( const auto& var : GameVariablesToReset ) + { + std::visit( []( auto&& v ) { + *v = {}; + }, var ); + } + + // Functions that should have been called by the game but aren't... + TimerInitialise(); + PurpleNinesGlitchFix(); + } + + template + static void (*orgReInitGameObjectVariables)(); + + template + void ReInitGameObjectVariables() + { + // First reinit "our" variables in case stock ones rely on those during resetting + ReInitOurVariables(); + orgReInitGameObjectVariables(); + } + HOOK_EACH_FUNC(ReInitGameObjectVariables, orgReInitGameObjectVariables, ReInitGameObjectVariables); + + static void (*orgGameInitialise)(const char*); + void GameInitialise(const char* path) + { + ReInitOurVariables(); + orgGameInitialise(path); + } +} + + void InjectDelayedPatches_III_Common( bool bHasDebugMenu, const wchar_t* wcModulePath ) { using namespace Memory; @@ -973,21 +1006,6 @@ void Patch_III_10(uint32_t width, uint32_t height) InjectHook(0x582EFD, NewFrameRender); InjectHook(0x582EA4, GetTimeSinceLastFrame); - // Reinit CCarCtrl fields (firetruck and ambulance generation) - ReadCall( 0x48C4FB, orgCarCtrlReInit ); - InjectHook(0x48C4FB, CarCtrlReInit_SilentPatch); - - - // Reinit free resprays flag - // add esp, 38h - // mov CGarages::RespraysAreFree, 0 - // retn - bool* pFreeResprays = *(bool**)DynBaseAddress(0x4224A4); - Patch(0x421E06, 0x38); - Patch(0x421E07, 0x05C6); - Patch(0x421E09, pFreeResprays); - Patch(0x421E0E, 0xC3); - // Radar blips bounds check InjectHook(0x4A55B2, RadarBoundsCheckCoordBlip, HookType::Jump); @@ -1106,22 +1124,6 @@ void Patch_III_11(uint32_t width, uint32_t height) InjectHook(0x5831E4, GetTimeSinceLastFrame); - // Reinit CCarCtrl fields (firetruck and ambulance generation) - ReadCall( 0x48C5FB, orgCarCtrlReInit ); - InjectHook(0x48C5FB, CarCtrlReInit_SilentPatch); - - - // Reinit free resprays flag - // add esp, 38h - // mov CGarages::RespraysAreFree, 0 - // retn - bool* pFreeResprays = *(bool**)DynBaseAddress(0x4224A4); - Patch(0x421E06, 0x38); - Patch(0x421E07, 0x05C6); - Patch(0x421E09, pFreeResprays); - Patch(0x421E0E, 0xC3); - - // Radar blips bounds check InjectHook(0x4A56A2, RadarBoundsCheckCoordBlip, HookType::Jump); InjectHook(0x4A5748, RadarBoundsCheckEntityBlip, HookType::Jump); @@ -1224,21 +1226,6 @@ void Patch_III_Steam(uint32_t width, uint32_t height) InjectHook(0x58312D, NewFrameRender); InjectHook(0x5830D4, GetTimeSinceLastFrame); - // Reinit CCarCtrl fields (firetruck and ambulance generation) - ReadCall( 0x48C58B, orgCarCtrlReInit ); - InjectHook(0x48C58B, CarCtrlReInit_SilentPatch); - - - // Reinit free resprays flag - // add esp, 38h - // mov CGarages::RespraysAreFree, 0 - // retn - bool* pFreeResprays = *(bool**)DynBaseAddress(0x4224A4); - Patch(0x421E06, 0x38); - Patch(0x421E07, 0x05C6); - Patch(0x421E09, pFreeResprays); - Patch(0x421E0E, 0xC3); - // Radar blips bounds check InjectHook(0x4A5632, RadarBoundsCheckCoordBlip, HookType::Jump); @@ -1255,11 +1242,6 @@ void Patch_III_Common() using namespace Memory; using namespace hook; - // Purple Nines Glitch fix - { - auto addr = get_pattern( "0F BF 4C 24 04 8B 44 24 08 C1 E1 04 89 81", -0xC ); - InjectHook( addr, PurpleNinesGlitchFix, HookType::Jump ); - } // New timers fix { @@ -1588,6 +1570,26 @@ void Patch_III_Common() bAllDodosCheat = allDodosCheat; InterceptCall(findPlayerVehicle, orgFindPlayerVehicle, FindPlayerVehicle_DodoCheck); } + + + // Reset variables on New Game + { + using namespace VariableResets; + + auto game_initialise = get_pattern("6A 00 E8 ? ? ? ? 83 C4 0C 68 ? ? ? ? E8 ? ? ? ? 59 C3", 15); + std::array reinit_game_object_variables = { + get_pattern("E8 ? ? ? ? 80 3D ? ? ? ? ? 75 6B"), + get_pattern("C6 05 ? ? ? ? ? E8 ? ? ? ? C7 05", 7) + }; + + InterceptCall(game_initialise, orgGameInitialise, GameInitialise); + HookEach_ReInitGameObjectVariables(reinit_game_object_variables, InterceptCall); + + // Variables to reset + GameVariablesToReset.emplace_back(*get_pattern("80 3D ? ? ? ? ? 74 2A", 2)); // Free resprays + GameVariablesToReset.emplace_back(*get_pattern("7D 72 A1 ? ? ? ? 05", 2 + 1)); // LastTimeAmbulanceCreated + GameVariablesToReset.emplace_back(*get_pattern("74 7F A1 ? ? ? ? 05", 2 + 1)); // LastTimeFireTruckCreated + } } BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) diff --git a/SilentPatchVC/SilentPatchVC.cpp b/SilentPatchVC/SilentPatchVC.cpp index 381b179..89cae46 100644 --- a/SilentPatchVC/SilentPatchVC.cpp +++ b/SilentPatchVC/SilentPatchVC.cpp @@ -235,22 +235,6 @@ int NewFrameRender(int nEvent, void* pParam) } -static signed int& LastTimeFireTruckCreated = **AddressByVersion(0x429435, 0x429435, 0x429405); -static signed int& LastTimeAmbulanceCreated = **AddressByVersion(0x429449, 0x429449, 0x429419); -static void (*orgCarCtrlReInit)(); -void CarCtrlReInit_SilentPatch() -{ - orgCarCtrlReInit(); - LastTimeFireTruckCreated = 0; - LastTimeAmbulanceCreated = 0; -} - -static bool& RespraysAreFree = **AddressByVersion(0x430D17, 0x430D17, 0x430CE7); -void GaragesInit_SilentPatch() -{ - RespraysAreFree = false; -} - static void (*orgPickNextNodeToChaseCar)(void*, float, float, void*); static float PickNextNodeToChaseCarZ = 0.0f; static void PickNextNodeToChaseCarXYZ( void* vehicle, const CVector& vec, void* chaseTarget ) @@ -686,6 +670,49 @@ namespace IsPlayerTargettingCharFix } } + +// ============= Resetting stats and variables on New Game ============= +namespace VariableResets +{ + static auto TimerInitialise = reinterpret_cast(hook::get_pattern("83 E4 F8 68 ? ? ? ? E8", -6)); + + using VarVariant = std::variant< bool*, int* >; + std::vector GameVariablesToReset; + + static void ReInitOurVariables() + { + for ( const auto& var : GameVariablesToReset ) + { + std::visit( []( auto&& v ) { + *v = {}; + }, var ); + } + + // Functions that should have been called by the game but aren't... + TimerInitialise(); + } + + template + static void (*orgReInitGameObjectVariables)(); + + template + void ReInitGameObjectVariables() + { + // First reinit "our" variables in case stock ones rely on those during resetting + ReInitOurVariables(); + orgReInitGameObjectVariables(); + } + HOOK_EACH_FUNC(ReInitGameObjectVariables, orgReInitGameObjectVariables, ReInitGameObjectVariables); + + static void (*orgGameInitialise)(const char*); + void GameInitialise(const char* path) + { + ReInitOurVariables(); + orgGameInitialise(path); + } +} + + void InjectDelayedPatches_VC_Common( bool bHasDebugMenu, const wchar_t* wcModulePath ) { using namespace Memory; @@ -951,14 +978,6 @@ void Patch_VC_10(uint32_t width, uint32_t height) Patch(0x5FDDDB, 0xC5); - // Reinit CCarCtrl fields (firetruck and ambulance generation) - ReadCall( 0x4A489B, orgCarCtrlReInit ); - InjectHook(0x4A489B, CarCtrlReInit_SilentPatch); - - - // Reinit free resprays flag - InjectHook(0x4349BB, GaragesInit_SilentPatch, HookType::Jump); - // Fixed ammo for melee weapons in cheats Patch(0x4AED14+1, 1); // katana Patch(0x4AEB74+1, 1); // chainsaw @@ -1056,15 +1075,6 @@ void Patch_VC_11(uint32_t width, uint32_t height) Patch(0x5FDDFB, 0xC5); - // Reinit CCarCtrl fields (firetruck and ambulance generation) - ReadCall( 0x4A48BB, orgCarCtrlReInit ); - InjectHook(0x4A48BB, CarCtrlReInit_SilentPatch); - - - // Reinit free resprays flag - InjectHook(0x4349BB, GaragesInit_SilentPatch, HookType::Jump); - - // Fixed ammo for melee weapons in cheats Patch(0x4AED34+1, 1); // katana Patch(0x4AEB94+1, 1); // chainsaw @@ -1151,15 +1161,6 @@ void Patch_VC_Steam(uint32_t width, uint32_t height) Patch(0x5FDA3B, 0xC5); - // Reinit CCarCtrl fields (firetruck and ambulance generation) - ReadCall( 0x4A475B, orgCarCtrlReInit ); - InjectHook(0x4A475B, CarCtrlReInit_SilentPatch); - - - // Reinit free resprays flag - InjectHook(0x43497B, GaragesInit_SilentPatch, HookType::Jump); - - // Fixed ammo for melee weapons in cheats Patch(0x4AEA44+1, 1); // katana Patch(0x4AEBE4+1, 1); // chainsaw @@ -1539,6 +1540,26 @@ void Patch_VC_Common() 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); } + + + // Reset variables on New Game + { + using namespace VariableResets; + + auto game_initialise = get_pattern("6A 00 E8 ? ? ? ? 83 C4 0C 68 ? ? ? ? E8 ? ? ? ? 59 C3", 15); + std::array reinit_game_object_variables = { + get_pattern("74 05 E8 ? ? ? ? E8 ? ? ? ? 80 3D", 7), + get_pattern("C6 05 ? ? ? ? ? E8 ? ? ? ? C7 05", 7) + }; + + InterceptCall(game_initialise, orgGameInitialise, GameInitialise); + HookEach_ReInitGameObjectVariables(reinit_game_object_variables, InterceptCall); + + // Variables to reset + GameVariablesToReset.emplace_back(*get_pattern("7D 09 80 3D ? ? ? ? ? 74 32", 2 + 2)); // Free resprays + GameVariablesToReset.emplace_back(*get_pattern("7D 78 A1 ? ? ? ? 05", 2 + 1)); // LastTimeAmbulanceCreated + GameVariablesToReset.emplace_back(*get_pattern("A1 ? ? ? ? 05 ? ? ? ? 39 05 ? ? ? ? 0F 86 ? ? ? ? 8B 15", 1)); // LastTimeFireTruckCreated + } } BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)