@@ -1281,22 +1281,32 @@ void _declspec(naked) HOOK_CVehicle_AddUpgrade()
12811281//
12821282// ////////////////////////////////////////////////////////////////////////////////////////
12831283#define HOOKPOS_CObject_Destructor_TrainCrossing_Check 0x59F7A8
1284- #define HOOKSIZE_CObject_Destructor_TrainCrossing_Check 5
1285- DWORD RETURN_CObject_Destructor_TrainCross_Check = 0x59F7AD ;
1286- DWORD RETURN_CObject_Destructor_TrainCross_INVALID = 0x59F811 ;
1287- void _declspec (naked) HOOK_CObject_Destructor_TrainCrossing_Check ()
1284+ #define HOOKPOS_CObject_ProcessTrainCrossingBehavior1 0x5A0C34
1285+ #define HOOKPOS_CObject_ProcessTrainCrossingBehavior2 0x5A0C54
1286+ #define RETURN_CObject_Destructor_TrainCrossing_Check 0x59F7AD
1287+ #define RETURN_CObject_Destructor_TrainCrossing_Invalid 0x59F811
1288+ #define RETURN_CObject_ProcessTrainCrossingBehavior1_Check 0x5A0C39
1289+ #define RETURN_CObject_ProcessTrainCrossingBehavior2_Check 0x5A0C59
1290+ #define RETURN_CObject_ProcessTrainCrossingBehavior_Invalid 0x5A0CBD
1291+
1292+ DWORD TrainCrossingFix_ReturnAddress, TrainCrossingFix_InvalidReturnAddress;
1293+ template <DWORD ReturnAddress, DWORD InvalidReturnAddress>
1294+ void _declspec (naked) HOOK_TrainCrossingBarrierCrashFix ()
12881295{
1296+ // We cannot use template parameters directly in inline assembly; the following instructions don't modify registers
1297+ TrainCrossingFix_ReturnAddress = ReturnAddress;
1298+ TrainCrossingFix_InvalidReturnAddress = InvalidReturnAddress;
1299+
12891300 _asm
12901301 {
12911302 test eax, eax // Check if pLinkedBarrierPost exists
12921303 jz jmp_invalid // Skip the barrier stuff
1293-
12941304 mov ecx, [eax+14h] // Execute replaced code
12951305 test ecx, ecx
1296- jmp RETURN_CObject_Destructor_TrainCross_Check
1306+ jmp TrainCrossingFix_ReturnAddress
12971307
1298- jmp_invalid:
1299- jmp RETURN_CObject_Destructor_TrainCross_INVALID
1308+ jmp_invalid:
1309+ jmp TrainCrossingFix_InvalidReturnAddress
13001310 }
13011311}
13021312
@@ -1501,9 +1511,16 @@ void CMultiplayerSA::InitHooks_CrashFixHacks ( void )
15011511 EZHookInstall ( CClumpModelInfo_GetFrameFromId );
15021512 EZHookInstallChecked ( CEntity_GetBoundRect );
15031513 EZHookInstallChecked ( CVehicle_AddUpgrade );
1504- EZHookInstall ( CObject_Destructor_TrainCrossing_Check );
15051514 EZHookInstall ( ResetFurnitureObjectCounter );
15061515 EZHookInstallChecked ( CVolumetricShadowMgr_Render );
15071516 EZHookInstallChecked ( CVolumetricShadowMgr_Update );
15081517 EZHookInstallChecked ( CAnimManager_CreateAnimAssocGroups );
1518+
1519+ // Install train crossing crashfix (the temporary variable is required for the template logic)
1520+ void (*temp)() = HOOK_TrainCrossingBarrierCrashFix<RETURN_CObject_Destructor_TrainCrossing_Check, RETURN_CObject_Destructor_TrainCrossing_Invalid>;
1521+ HookInstall ( HOOKPOS_CObject_Destructor_TrainCrossing_Check, (DWORD)temp, 5 );
1522+ temp = HOOK_TrainCrossingBarrierCrashFix<RETURN_CObject_ProcessTrainCrossingBehavior1_Check, RETURN_CObject_ProcessTrainCrossingBehavior_Invalid>;
1523+ HookInstall ( HOOKPOS_CObject_ProcessTrainCrossingBehavior1, (DWORD)temp, 5 );
1524+ temp = HOOK_TrainCrossingBarrierCrashFix<RETURN_CObject_ProcessTrainCrossingBehavior2_Check, RETURN_CObject_ProcessTrainCrossingBehavior_Invalid>;
1525+ HookInstall ( HOOKPOS_CObject_ProcessTrainCrossingBehavior2, (DWORD)temp, 5 );
15091526}
0 commit comments