Skip to content

Commit 2017aea

Browse files
committed
Support planes, trains and boats for onClientVehicleCollision (fixes #540)
Moved hooks to the ProcessControl functions to allow vehicle pointer overwrite there to avoid crashes
1 parent 705e0f1 commit 2017aea

File tree

4 files changed

+195
-133
lines changed

4 files changed

+195
-133
lines changed

Client/multiplayer_sa/CMultiplayerSA.cpp

Lines changed: 0 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -246,15 +246,6 @@ DWORD JMP_RETN_Cancelled_CPopulation_ConvertToDummyObject = 0x614715;
246246
#define HOOKPOS_CEntity_IsOnScreen_FixObjectsScale 0x534575
247247
DWORD JMP_CEntity_IsOnScreen_FixObjectsScale = 0x53457C;
248248

249-
#define HOOKPOS_CEventVehicleDamageCollision 0x6A7657
250-
DWORD JMP_CEventVehicleDamageCollision_RETN = 0x6A765D;
251-
252-
#define HOOKPOS_CEventVehicleDamageCollision_Plane 0x6CC4B3
253-
DWORD JMP_CEventVehicleDamageCollision_Plane_RETN = 0x6CC4B8;
254-
255-
#define HOOKPOS_CEventVehicleDamageCollision_Bike 0x6B8EC6
256-
DWORD JMP_CEventVehicleDamageCollision_Bike_RETN = 0x6B8ECC;
257-
258249
#define HOOKPOS_CClothes_RebuildPlayer 0x5A82C0
259250
DWORD RETURN_CClothes_RebuildPlayera = 0x5A82C8;
260251
DWORD RETURN_CClothes_RebuildPlayerb = 0x5A837F;
@@ -364,7 +355,6 @@ IdleHandler* m_pIdleHandler = NULL;
364355
PreFxRenderHandler* m_pPreFxRenderHandler = NULL;
365356
PreHudRenderHandler* m_pPreHudRenderHandler = NULL;
366357
ProcessCollisionHandler* m_pProcessCollisionHandler = NULL;
367-
VehicleCollisionHandler* m_pVehicleCollisionHandler = NULL;
368358
HeliKillHandler* m_pHeliKillHandler = NULL;
369359
ObjectDamageHandler* m_pObjectDamageHandler = NULL;
370360
ObjectBreakHandler* m_pObjectBreakHandler = NULL;
@@ -499,12 +489,6 @@ void Hook_CObject_DTR();
499489

500490
void HOOK_CEntity_IsOnScreen_FixObjectScale();
501491

502-
void HOOK_CEventVehicleDamageCollision();
503-
504-
void HOOK_CEventVehicleDamageCollision_Plane();
505-
506-
void HOOK_CEventVehicleDamageCollision_Bike();
507-
508492
void HOOK_CClothes_RebuildPlayer();
509493

510494
void HOOK_CProjectileInfo_Update_FindLocalPlayer_FindLocalPlayerVehicle();
@@ -720,14 +704,6 @@ void CMultiplayerSA::InitHooks()
720704
HookInstall(HOOKPOS_ConvertToObject_CPopulationManageDummy, (DWORD)HOOK_ConvertToObject_CPopulationManageDummy, 6);
721705
// End of building removal hooks
722706

723-
// Vehicle Collision Event Hooks
724-
HookInstall(HOOKPOS_CEventVehicleDamageCollision, (DWORD)HOOK_CEventVehicleDamageCollision, 6);
725-
726-
HookInstall(HOOKPOS_CEventVehicleDamageCollision_Plane, (DWORD)HOOK_CEventVehicleDamageCollision_Plane, 5);
727-
728-
HookInstall(HOOKPOS_CEventVehicleDamageCollision_Bike, (DWORD)HOOK_CEventVehicleDamageCollision_Bike, 6);
729-
// End of Vehicle Collision Event Hooks
730-
731707
// Spider CJ fix
732708
HookInstall(HOOKPOS_CClothes_RebuildPlayer, (DWORD)HOOK_CClothes_RebuildPlayer, 8);
733709

@@ -2251,11 +2227,6 @@ void CMultiplayerSA::SetProcessCollisionHandler(ProcessCollisionHandler* pHandle
22512227
m_pProcessCollisionHandler = pHandler;
22522228
}
22532229

2254-
void CMultiplayerSA::SetVehicleCollisionHandler(VehicleCollisionHandler* pHandler)
2255-
{
2256-
m_pVehicleCollisionHandler = pHandler;
2257-
}
2258-
22592230
void CMultiplayerSA::SetHeliKillHandler(HeliKillHandler* pHandler)
22602231
{
22612232
m_pHeliKillHandler = pHandler;
@@ -6196,111 +6167,7 @@ void _declspec(naked) HOOK_CEntity_IsOnScreen_FixObjectScale()
61966167
jmp JMP_CEntity_IsOnScreen_FixObjectsScale
61976168
}
61986169
}
6199-
CVehicleSAInterface* pCollisionVehicle = NULL;
6200-
void TriggerVehicleCollisionEvent()
6201-
{
6202-
if (pCollisionVehicle)
6203-
{
6204-
CEntitySAInterface* pEntity = pCollisionVehicle->m_pCollidedEntity;
6205-
if (pEntity)
6206-
{
6207-
// Not handled because it triggers too much
6208-
// if ( pEntity->nType != ENTITY_TYPE_BUILDING )
6209-
{
6210-
if (m_pVehicleCollisionHandler)
6211-
{
6212-
TIMING_CHECKPOINT("+TriggerVehColEvent");
6213-
if (pEntity->nType == ENTITY_TYPE_VEHICLE)
6214-
{
6215-
CVehicleSAInterface* pInterface = static_cast<CVehicleSAInterface*>(pEntity);
6216-
m_pVehicleCollisionHandler(pCollisionVehicle, pEntity, pEntity->m_nModelIndex, pCollisionVehicle->m_fDamageImpulseMagnitude,
6217-
pInterface->m_fDamageImpulseMagnitude, pCollisionVehicle->m_usPieceType,
6218-
pCollisionVehicle->m_vecCollisionPosition, pCollisionVehicle->m_vecCollisionImpactVelocity);
6219-
}
6220-
else
6221-
{
6222-
m_pVehicleCollisionHandler(pCollisionVehicle, pEntity, pEntity->m_nModelIndex, pCollisionVehicle->m_fDamageImpulseMagnitude, 0.0f,
6223-
pCollisionVehicle->m_usPieceType, pCollisionVehicle->m_vecCollisionPosition,
6224-
pCollisionVehicle->m_vecCollisionImpactVelocity);
6225-
}
6226-
TIMING_CHECKPOINT("-TriggerVehColEvent");
6227-
}
6228-
}
6229-
}
6230-
}
6231-
}
6232-
6233-
void _declspec(naked) HOOK_CEventVehicleDamageCollision()
6234-
{
6235-
// .006A7657 64 A1 00 00 00 00 mov eax, large fs:0 < Hook >
6236-
// .006A765D 50 push eax < Jmp Back >
6237-
6238-
// ecx = this ptr, copied from esi
6239-
// pVehicle->damageEntity = damage entity
6240-
_asm
6241-
{
6242-
pushad
6243-
mov pCollisionVehicle, ecx
6244-
}
6245-
6246-
TriggerVehicleCollisionEvent();
6247-
6248-
// do the replaced code and return back as if nothing happened.
6249-
_asm
6250-
{
6251-
popad
6252-
mov esi, pCollisionVehicle
6253-
mov eax, fs:0
6254-
jmp JMP_CEventVehicleDamageCollision_RETN
6255-
}
6256-
}
6257-
6258-
DWORD dwPlaneDamageThreadshold = 0x8D33E4;
6259-
void _declspec(naked) HOOK_CEventVehicleDamageCollision_Plane()
6260-
{
6261-
// .006CC4B3 A1 E4 33 8D 00 mov eax, ds:?PLANE_DAMAGE_THRESHHOLD@@3MA
6262-
// 006CC4B8 53 push ebx < Jmp Back >
62636170

6264-
// ecx = this ptr
6265-
// pVehicle->damageEntity = damage entity
6266-
_asm
6267-
{
6268-
pushad
6269-
mov pCollisionVehicle, ecx
6270-
}
6271-
TriggerVehicleCollisionEvent();
6272-
6273-
// do the replaced code and return back as if nothing happened.
6274-
_asm
6275-
{
6276-
popad
6277-
mov eax, DWORD PTR DS:[8D33E4h]
6278-
jmp JMP_CEventVehicleDamageCollision_Plane_RETN
6279-
}
6280-
}
6281-
6282-
void _declspec(naked) HOOK_CEventVehicleDamageCollision_Bike()
6283-
{
6284-
// .006B8EC6 DC 1D F8 9E 85 00 fcomp ds:__real@0000000000000000 < Hook >
6285-
// 006B8ECC 8B F1 mov esi, ecx < Jmp Back >
6286-
6287-
// ecx = this ptr
6288-
// pVehicle->damageEntity = damage entity
6289-
_asm
6290-
{
6291-
pushad
6292-
mov pCollisionVehicle, ecx
6293-
}
6294-
TriggerVehicleCollisionEvent();
6295-
6296-
// do the replaced code and return back as if nothing happened.
6297-
_asm
6298-
{
6299-
popad
6300-
fcomp DWORD PTR DS:[859EF8h]
6301-
jmp JMP_CEventVehicleDamageCollision_Bike_RETN
6302-
}
6303-
}
63046171
//////////////////////////////////////////////////////////////////////////////////////////
63056172
// Only allow rebuild player on CJ - Stops other models getting corrupted (spider CJ)
63066173
// hooked at 5A82C0 8 bytes

Client/multiplayer_sa/CMultiplayerSA.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class CMultiplayerSA : public CMultiplayer
6666
void InitHooks_Files(void);
6767
void InitHooks_Weapons(void);
6868
void InitHooks_Peds();
69+
void InitHooks_VehicleCollision();
6970
void InitHooks_Rendering(void);
7071
void InitHooks_LicensePlate(void);
7172
void InitHooks_VehicleLights(void);

Client/multiplayer_sa/CMultiplayerSA_1.3.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ void CMultiplayerSA::InitHooks_13(void)
206206
InitHooks_Files();
207207
InitHooks_Weapons();
208208
InitHooks_Peds();
209+
InitHooks_VehicleCollision();
209210
InitHooks_Rendering();
210211
}
211212

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
/*****************************************************************************
2+
*
3+
* PROJECT: Multi Theft Auto
4+
* LICENSE: See LICENSE in the top level directory
5+
* FILE: multiplayer_sa/CMultiplayerSA_VehicleCollision.cpp
6+
*
7+
* Multi Theft Auto is available from https://www.multitheftauto.com/
8+
*
9+
*****************************************************************************/
10+
#include "StdInc.h"
11+
12+
extern CCoreInterface* g_pCore;
13+
14+
static CVehicleSAInterface* pCollisionVehicle = nullptr;
15+
static VehicleCollisionHandler* pVehicleCollisionHandler = nullptr;
16+
17+
void CMultiplayerSA::SetVehicleCollisionHandler(VehicleCollisionHandler* pHandler)
18+
{
19+
pVehicleCollisionHandler = pHandler;
20+
}
21+
22+
void TriggerVehicleCollisionEvent()
23+
{
24+
if (!pVehicleCollisionHandler || !pCollisionVehicle)
25+
return;
26+
27+
CEntitySAInterface* pEntity = pCollisionVehicle->m_pCollidedEntity;
28+
29+
if (!pEntity)
30+
return;
31+
32+
TIMING_CHECKPOINT("+TriggerVehColEvent");
33+
if (pEntity->nType == ENTITY_TYPE_VEHICLE)
34+
{
35+
auto pInterface = static_cast<CVehicleSAInterface*>(pEntity);
36+
37+
pVehicleCollisionHandler(pCollisionVehicle, pEntity, pEntity->m_nModelIndex, pCollisionVehicle->m_fDamageImpulseMagnitude,
38+
pInterface->m_fDamageImpulseMagnitude, pCollisionVehicle->m_usPieceType,
39+
pCollisionVehicle->m_vecCollisionPosition, pCollisionVehicle->m_vecCollisionImpactVelocity);
40+
}
41+
else
42+
{
43+
pVehicleCollisionHandler(pCollisionVehicle, pEntity, pEntity->m_nModelIndex, pCollisionVehicle->m_fDamageImpulseMagnitude, 0.0f,
44+
pCollisionVehicle->m_usPieceType, pCollisionVehicle->m_vecCollisionPosition,
45+
pCollisionVehicle->m_vecCollisionImpactVelocity);
46+
}
47+
TIMING_CHECKPOINT("-TriggerVehColEvent");
48+
}
49+
50+
//////////////////////////////////////////////////////////////////////////////////////////
51+
//
52+
// CAutomobile::ProcessControl
53+
//
54+
// Trigger onClientVehicleCollision for:
55+
// CAutomobile, CPlane, CHeli, CMonsterTruck, CQuadBike, CTrailer
56+
//
57+
//////////////////////////////////////////////////////////////////////////////////////////
58+
#define HOOKPOS_CAutomobile_ProcessControl_VehicleDamage 0x6B1F3B
59+
#define HOOKSIZE_CAutomobile_ProcessControl_VehicleDamage 6
60+
static const DWORD CONTINUE_CAutomobile_ProcessControl_VehicleDamage = 0x6B1F41;
61+
62+
static void _declspec(naked) HOOK_CAutomobile_ProcessControl_VehicleDamage()
63+
{
64+
_asm
65+
{
66+
pushad
67+
mov pCollisionVehicle, ecx
68+
}
69+
70+
TriggerVehicleCollisionEvent();
71+
72+
_asm
73+
{
74+
popad
75+
mov ecx, pCollisionVehicle
76+
mov esi, pCollisionVehicle
77+
mov eax, [esi]
78+
call dword ptr[eax + 0E0h]
79+
jmp CONTINUE_CAutomobile_ProcessControl_VehicleDamage
80+
}
81+
}
82+
83+
//////////////////////////////////////////////////////////////////////////////////////////
84+
//
85+
// CBike::ProcessControl
86+
//
87+
// Trigger onClientVehicleCollision for:
88+
// CBike, CBmx
89+
//
90+
//////////////////////////////////////////////////////////////////////////////////////////
91+
#define HOOKPOS_CBike_ProcessControl_VehicleDamage 0x6B9AA5
92+
#define HOOKSIZE_CBike_ProcessControl_VehicleDamage 6
93+
static const DWORD CONTINUE_CBike_ProcessControl_VehicleDamage = 0x6B9AAB;
94+
95+
static void _declspec(naked) HOOK_CBike_ProcessControl_VehicleDamage()
96+
{
97+
_asm
98+
{
99+
pushad
100+
mov pCollisionVehicle, ecx
101+
}
102+
103+
TriggerVehicleCollisionEvent();
104+
105+
_asm
106+
{
107+
popad
108+
mov ecx, pCollisionVehicle
109+
mov esi, pCollisionVehicle
110+
mov eax, [esi]
111+
call dword ptr[eax + 0E0h]
112+
jmp CONTINUE_CBike_ProcessControl_VehicleDamage
113+
}
114+
}
115+
116+
//////////////////////////////////////////////////////////////////////////////////////////
117+
//
118+
// CBoat::ProcessControl
119+
//
120+
// Trigger onClientVehicleCollision for:
121+
// CBoat
122+
//
123+
//////////////////////////////////////////////////////////////////////////////////////////
124+
#define HOOKPOS_CBoat_ProcessControl_VehicleDamage 0x6F1864
125+
#define HOOKSIZE_CBoat_ProcessControl_VehicleDamage 5
126+
static const DWORD CONTINUE_CBoat_ProcessControl_VehicleDamage = 0x6F1869;
127+
static const DWORD FUNC_CVehicle_ProcessCarAlarm = 0x6D21F0;
128+
129+
static void _declspec(naked) HOOK_CBoat_ProcessControl_VehicleDamage()
130+
{
131+
_asm
132+
{
133+
pushad
134+
mov pCollisionVehicle, ecx
135+
}
136+
137+
TriggerVehicleCollisionEvent();
138+
139+
_asm
140+
{
141+
popad
142+
mov ecx, pCollisionVehicle
143+
mov esi, pCollisionVehicle
144+
call FUNC_CVehicle_ProcessCarAlarm
145+
jmp CONTINUE_CBoat_ProcessControl_VehicleDamage
146+
}
147+
}
148+
149+
//////////////////////////////////////////////////////////////////////////////////////////
150+
//
151+
// CTrain::ProcessControl
152+
//
153+
// Trigger onClientVehicleCollision for:
154+
// CTrain
155+
//
156+
//////////////////////////////////////////////////////////////////////////////////////////
157+
#define HOOKPOS_CTrain_ProcessControl_VehicleDamage 0x6F86BB
158+
#define HOOKSIZE_CTrain_ProcessControl_VehicleDamage 5
159+
static const DWORD CONTINUE_CTrain_ProcessControl_VehicleDamage = 0x6F86C0;
160+
161+
static void _declspec(naked) HOOK_CTrain_ProcessControl_VehicleDamage()
162+
{
163+
_asm
164+
{
165+
pushad
166+
mov pCollisionVehicle, esi
167+
}
168+
169+
TriggerVehicleCollisionEvent();
170+
171+
_asm
172+
{
173+
popad
174+
mov esi, pCollisionVehicle
175+
mov al, ds:[0BA6728h]
176+
jmp CONTINUE_CTrain_ProcessControl_VehicleDamage
177+
}
178+
}
179+
180+
//////////////////////////////////////////////////////////////////////////////////////////
181+
//
182+
// CMultiplayerSA::InitHooks_VehicleCollision
183+
//
184+
// Setup hooks
185+
//
186+
//////////////////////////////////////////////////////////////////////////////////////////
187+
void CMultiplayerSA::InitHooks_VehicleCollision()
188+
{
189+
EZHookInstall(CAutomobile_ProcessControl_VehicleDamage);
190+
EZHookInstall(CBike_ProcessControl_VehicleDamage);
191+
EZHookInstall(CBoat_ProcessControl_VehicleDamage);
192+
EZHookInstall(CTrain_ProcessControl_VehicleDamage);
193+
}

0 commit comments

Comments
 (0)