@@ -300,6 +300,9 @@ DWORD dwFUNC_CAEVehicleAudioEntity__ProcessAIProp = FUNC_CAEVehicleAudioEntity__
300300#define HOOKPOS_CTaskSimpleSwim_ProcessSwimmingResistance 0x68A4EF
301301DWORD RETURN_CTaskSimpleSwim_ProcessSwimmingResistance = 0x68A50E ;
302302
303+ #define HOOKPOS_CWaterCannon__Render 0x72932A
304+ static DWORD CONTINUE_CWaterCannon__Render = 0x72932F ;
305+ 303306CPed* pContextSwitchedPed = 0 ;
304307CVector vecCenterOfWorld;
305308FLOAT fFalseHeading ;
@@ -367,6 +370,7 @@ ObjectDamageHandler* m_pObjectDamageHandler = NULL;
367370ObjectBreakHandler* m_pObjectBreakHandler = NULL ;
368371FxSystemDestructionHandler* m_pFxSystemDestructionHandler = NULL ;
369372DrivebyAnimationHandler* m_pDrivebyAnimationHandler = NULL ;
373+ WaterCannonHitWorldHandler* m_pWaterCannonHitWorldHandler = nullptr ;
370374
371375CEntitySAInterface* dwSavedPlayerPointer = 0 ;
372376CEntitySAInterface* activeEntityForStreaming = 0 ; // the entity that the streaming system considers active
@@ -524,6 +528,8 @@ void HOOK_CAEVehicleAudioEntity__ProcessDummyProp();
524528
525529void HOOK_CTaskSimpleSwim_ProcessSwimmingResistance ();
526530
531+ static void HOOK_CWaterCannon__Render ();
532+ 527533CMultiplayerSA::CMultiplayerSA ()
528534{
529535 // Unprotect all of the GTASA code at once and leave it that way
@@ -757,6 +763,8 @@ void CMultiplayerSA::InitHooks()
757763 // Fix GTA:SA swimming speed problem on higher fps
758764 HookInstall (HOOKPOS_CTaskSimpleSwim_ProcessSwimmingResistance, (DWORD)HOOK_CTaskSimpleSwim_ProcessSwimmingResistance, 6 );
759765
766+ HookInstall (HOOKPOS_CWaterCannon__Render, (DWORD)HOOK_CWaterCannon__Render, 5 );
767+ 760768 // Disable GTA setting g_bGotFocus to false when we minimize
761769 MemSet ((void *)ADDR_GotFocus, 0x90 , pGameInterface->GetGameVersion () == VERSION_EU_10 ? 6 : 10 );
762770
@@ -1490,6 +1498,10 @@ void CMultiplayerSA::InitHooks()
14901498 // Allow to switch weapons while glued
14911499 MemSetFast ((void *)0x60D861 , 0x90 , 14 );
14921500
1501+ // Allow water cannon to hit objects and players visually
1502+ MemSet ((void *)0x72925D , 0x1 , 1 ); // objects
1503+ MemSet ((void *)0x729263 , 0x1 , 1 ); // players
1504+ 14931505 InitHooks_CrashFixHacks ();
14941506
14951507 // Init our 1.3 hooks.
@@ -2250,6 +2262,11 @@ void CMultiplayerSA::SetDrivebyAnimationHandler(DrivebyAnimationHandler* pHandle
22502262 m_pDrivebyAnimationHandler = pHandler;
22512263}
22522264
2265+ void CMultiplayerSA::SetWaterCannonHitWorldHandler (WaterCannonHitWorldHandler* pHandler)
2266+ {
2267+ m_pWaterCannonHitWorldHandler = pHandler;
2268+ }
2269+ 22532270// What we do here is check if the idle handler has been set
22542271bool CMultiplayerSA::IsConnected (void )
22552272{
@@ -6890,3 +6907,42 @@ void _declspec(naked) HOOK_CTaskSimpleSwim_ProcessSwimmingResistance()
68906907 jmp RETURN_CTaskSimpleSwim_ProcessSwimmingResistance
68916908 }
68926909}
6910+ 6911+ static void __cdecl WaterCannonHitWorld (CVehicleSAInterface* pGameVehicle, CColPointSAInterface* pColPoint, CEntitySAInterface** ppGameEntity)
6912+ {
6913+ if (m_pWaterCannonHitWorldHandler)
6914+ {
6915+ CEntitySAInterface* const pGameEntity = ppGameEntity ? *ppGameEntity : nullptr ;
6916+ const int iModel = pGameEntity ? pGameEntity->m_nModelIndex : -1 ;
6917+ 6918+ SWaterCannonHitEvent event = {
6919+ pGameVehicle,
6920+ pGameEntity,
6921+ pColPoint->Position ,
6922+ pColPoint->Normal ,
6923+ iModel,
6924+ pColPoint->ucSurfaceTypeB ,
6925+ };
6926+ 6927+ m_pWaterCannonHitWorldHandler (event);
6928+ }
6929+ }
6930+ 6931+ static void _declspec (naked) HOOK_CWaterCannon__Render()
6932+ {
6933+ _asm
6934+ {
6935+ pushad
6936+ mov eax, [ebx] // CVehicleSAInterface* CWaterCannon::m_pVehicle
6937+ lea ebx, [esp + 100h - 54h] // CColPointSAInterface*
6938+ lea ecx, [esp + 100h - 58h] // CEntitySAInterface**
6939+ push ecx // ppGameEntity
6940+ push ebx // pColPoint
6941+ push eax // pGameVehicle
6942+ call WaterCannonHitWorld
6943+ add esp, 12
6944+ popad
6945+ push 3E4CCCCDh
6946+ jmp CONTINUE_CWaterCannon__Render
6947+ }
6948+ }
0 commit comments