Skip to content

Commit 93e31ca

Browse files
Synchronize changes from 1.6 master branch [ci skip]
c7644f2 Impossible to stop helicopter rotor if it has a driver (PR #3621, Fixes #552) 808ddf0 Update client en_US pot
2 parents 00e02f7 + c7644f2 commit 93e31ca

File tree

8 files changed

+164
-37
lines changed

8 files changed

+164
-37
lines changed

Client/game_sa/CHeliSA.h

Lines changed: 31 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -16,40 +16,37 @@
1616
class CHeliSAInterface : public CAutomobileSAInterface
1717
{
1818
public:
19-
std::uint8_t m_heliFlags;
20-
21-
std::uint8_t _pad1[3];
22-
std::uint32_t m_leftRightSkid;
23-
std::uint32_t m_steeringUpDown;
24-
std::uint32_t m_steeringLeftRight;
25-
std::uint32_t m_accelerationBreakStatus;
26-
std::uint32_t field_99C;
27-
std::uint32_t m_rotorZ;
28-
std::uint32_t m_secondRotorZ;
29-
std::uint32_t m_maxAltitude;
30-
std::uint32_t field_9AC;
31-
std::uint32_t m_minAltitude;
32-
std::uint32_t field_9B4;
33-
std::uint8_t field_9B8;
34-
std::uint8_t m_numSwatOccupants;
35-
std::uint8_t m_swatIDs[4];
36-
37-
std::uint8_t _pad2[2];
38-
std::uint32_t field_9C0[4];
39-
std::uint32_t field_9D0;
40-
41-
std::uint32_t m_particlesList;
42-
std::uint8_t field_9D8[24];
43-
std::uint32_t field_9F0;
44-
CVector m_searchLightTarget;
45-
std::uint32_t m_searchLightIntensity;
46-
std::uint32_t field_A04;
47-
std::uint32_t field_A08;
48-
std::uint32_t m_gunflashFx;
49-
std::uint8_t m_firingMultiplier;
50-
std::uint8_t m_searchLightEnabled;
51-
std::uint8_t _pad3[2];
52-
std::uint32_t field_A14;
19+
std::uint8_t m_nHeliFlags; // 0x988
20+
std::uint8_t ___pad1[3]; // 0x989
21+
float m_fLeftRightSkid; // 0x98C
22+
float m_fSteeringUpDown; // 0x990
23+
float m_fSteeringLeftRight; // 0x994
24+
float m_fAccelerationBreakStatus; // 0x998
25+
std::int32_t field_99C; // 0x99C
26+
float m_fRotorZ; // 0x9A0
27+
float m_fSecondRotorZ; // 0x9A4
28+
float m_fMaxAltitude; // 0x9A8
29+
std::int32_t field_9AC; // 0x9AC
30+
float m_fMinAltitude; // 0x9B0
31+
std::int32_t field_9B4; // 0x9B4
32+
std::uint8_t field_9B8; // 0x9B8
33+
std::uint8_t m_nNumSwatOccupants; // 0x9B9
34+
std::uint8_t m_anSwatIDs[4]; // 0x9BA
35+
std::uint8_t ___pad2[2]; // 0x9BE
36+
std::uint32_t field_9C0[4]; // 0x9C0
37+
std::int32_t field_9D0; // 0x9D0
38+
FxSystem_c** m_pParticlesList; // 0x9D4
39+
std::uint8_t field_9D8[24]; // 0x9D8
40+
std::int32_t field_9F0; // 0x9F0
41+
CVector m_vecSearchLightTarget; // 0x9F4
42+
float m_fSearchLightIntensity; // 0xA00
43+
std::int32_t field_A04; // 0xA04
44+
std::int32_t field_A08; // 0xA08
45+
FxSystem_c** m_ppGunflashFx; // 0xA0C
46+
std::uint8_t m_nFiringMultiplier; // 0xA10
47+
bool m_bSearchLightEnabled; // 0xA11
48+
std::uint8_t ___pad3[2]; // 0xA12
49+
std::int32_t field_A14; // 0xA14
5350
};
5451
static_assert(sizeof(CHeliSAInterface) == 0xA18, "Invalid size for CHeliSAInterface");
5552

Client/game_sa/CVehicleSA.cpp

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "CProjectileInfoSA.h"
2121
#include "CTrainSA.h"
2222
#include "CPlaneSA.h"
23+
#include "CHeliSA.h"
2324
#include "CVehicleSA.h"
2425
#include "CBoatSA.h"
2526
#include "CVisibilityPluginsSA.h"
@@ -52,6 +53,62 @@ void _declspec(naked) HOOK_Vehicle_PreRender(void)
5253
}
5354
}
5455

56+
static bool __fastcall CanProcessFlyingCarStuff(CAutomobileSAInterface* vehicleInterface)
57+
{
58+
SClientEntity<CVehicleSA>* vehicle = pGame->GetPools()->GetVehicle((DWORD*)vehicleInterface);
59+
if (!vehicle || !vehicle->pEntity)
60+
return true;
61+
62+
return vehicle->pEntity->GetVehicleRotorState();
63+
}
64+
65+
static constexpr DWORD CONTINUE_CHeli_ProcessFlyingCarStuff = 0x6C4E82;
66+
static constexpr DWORD RETURN_CHeli_ProcessFlyingCarStuff = 0x6C5404;
67+
static void _declspec(naked) HOOK_CHeli_ProcessFlyingCarStuff()
68+
{
69+
_asm
70+
{
71+
mov esi, ecx
72+
mov al, [esi+36h]
73+
74+
pushad
75+
call CanProcessFlyingCarStuff
76+
test al, al
77+
jz skip
78+
79+
popad
80+
jmp CONTINUE_CHeli_ProcessFlyingCarStuff
81+
82+
skip:
83+
popad
84+
jmp RETURN_CHeli_ProcessFlyingCarStuff
85+
}
86+
}
87+
88+
static constexpr DWORD CONTINUE_CPlane_ProcessFlyingCarStuff = 0x6CB7D7;
89+
static constexpr DWORD RETURN_CPlane_ProcessFlyingCarStuff = 0x6CC482;
90+
static void _declspec(naked) HOOK_CPlane_ProcessFlyingCarStuff()
91+
{
92+
_asm
93+
{
94+
push esi
95+
mov esi, ecx
96+
fnstsw ax
97+
98+
pushad
99+
call CanProcessFlyingCarStuff
100+
test al, al
101+
jz skip
102+
103+
popad
104+
jmp CONTINUE_CPlane_ProcessFlyingCarStuff
105+
106+
skip:
107+
popad
108+
jmp RETURN_CPlane_ProcessFlyingCarStuff
109+
}
110+
}
111+
55112
namespace
56113
{
57114
bool ClumpDumpCB(RpAtomic* pAtomic, void* data)
@@ -491,6 +548,29 @@ void CVehicleSA::SetTrainSpeed(float fSpeed)
491548
pInterface->m_fTrainSpeed = fSpeed;
492549
}
493550

551+
float CVehicleSA::GetHeliRotorSpeed() const
552+
{
553+
return static_cast<CHeliSAInterface*>(m_pInterface)->m_wheelSpeed[1];
554+
}
555+
556+
void CVehicleSA::SetHeliRotorSpeed(float speed)
557+
{
558+
static_cast<CHeliSAInterface*>(GetInterface())->m_wheelSpeed[1] = speed;
559+
}
560+
561+
void CVehicleSA::SetVehicleRotorState(bool state, bool stopRotor, bool isHeli) noexcept
562+
{
563+
m_rotorState = state;
564+
565+
if (state || !stopRotor)
566+
return;
567+
568+
if (isHeli)
569+
SetHeliRotorSpeed(0.0f);
570+
else
571+
SetPlaneRotorSpeed(0.0f);
572+
}
573+
494574
void CVehicleSA::SetPlaneRotorSpeed(float fSpeed)
495575
{
496576
auto pInterface = static_cast<CPlaneSAInterface*>(GetInterface());
@@ -1849,6 +1929,10 @@ void CVehicleSA::StaticSetHooks()
18491929
{
18501930
// Setup vehicle sun glare hook
18511931
HookInstall(FUNC_CAutomobile_OnVehiclePreRender, (DWORD)HOOK_Vehicle_PreRender, 5);
1932+
1933+
// Setup hooks to handle setVehicleRotorState function
1934+
HookInstall(FUNC_CHeli_ProcessFlyingCarStuff, (DWORD)HOOK_CHeli_ProcessFlyingCarStuff, 5);
1935+
HookInstall(FUNC_CPlane_ProcessFlyingCarStuff, (DWORD)HOOK_CPlane_ProcessFlyingCarStuff, 5);
18521936
}
18531937

18541938
void CVehicleSA::SetVehiclesSunGlareEnabled(bool bEnabled)

Client/game_sa/CVehicleSA.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ struct RwTexture;
9494
#define FUNC_CAutomobile_OnVehiclePreRender 0x6ABCFD
9595
#define FUNC_CVehicle_DoSunGlare 0x6DD6F0
9696

97+
#define FUNC_CHeli_ProcessFlyingCarStuff 0x6C4E7D
98+
#define FUNC_CPlane_ProcessFlyingCarStuff 0x6CB7D2
99+
97100
// CClumpModelInfo::GetFrameFromName
98101
#define FUNC_CClumpModelInfo_GetFrameFromName 0x4C5400
99102

@@ -422,6 +425,7 @@ class CVehicleSA : public virtual CVehicle, public virtual CPhysicalSA
422425
unsigned char m_ucVariant2;
423426
unsigned char m_ucVariantCount{0};
424427
bool m_doorsUndamageable{false};
428+
bool m_rotorState{true};
425429

426430
std::array<CVector, VEHICLE_DUMMY_COUNT> m_dummyPositions;
427431

@@ -552,7 +556,8 @@ class CVehicleSA : public virtual CVehicle, public virtual CPhysicalSA
552556
bool GetTakeLessDamage() { return GetVehicleInterface()->m_nVehicleFlags.bTakeLessDamage; };
553557
bool GetTyresDontBurst() { return GetVehicleInterface()->m_nVehicleFlags.bTyresDontBurst; };
554558
unsigned short GetAdjustablePropertyValue() { return *reinterpret_cast<unsigned short*>(reinterpret_cast<unsigned long>(m_pInterface) + 2156); };
555-
float GetHeliRotorSpeed() { return *reinterpret_cast<float*>(reinterpret_cast<unsigned int>(m_pInterface) + 2124); };
559+
float GetHeliRotorSpeed() const;
560+
bool GetVehicleRotorState() const noexcept override { return m_rotorState; }
556561
float GetPlaneRotorSpeed();
557562

558563
unsigned long GetExplodeTime() { return *reinterpret_cast<unsigned long*>(reinterpret_cast<unsigned int>(m_pInterface) + 1240); };
@@ -578,7 +583,8 @@ class CVehicleSA : public virtual CVehicle, public virtual CPhysicalSA
578583
{
579584
*reinterpret_cast<unsigned short*>(reinterpret_cast<unsigned int>(m_pInterface) + 2156) = usAdjustableProperty;
580585
};
581-
void SetHeliRotorSpeed(float fSpeed) { *reinterpret_cast<float*>(reinterpret_cast<unsigned int>(m_pInterface) + 2124) = fSpeed; };
586+
void SetHeliRotorSpeed(float speed);
587+
void SetVehicleRotorState(bool state, bool stopRotor, bool isHeli) noexcept override;
582588
void SetPlaneRotorSpeed(float fSpeed);
583589
bool SetVehicleWheelRotation(float fWheelRot1, float fWheelRot2, float fWheelRot3, float fWheelRot4) noexcept;
584590
void SetExplodeTime(unsigned long ulTime) { *reinterpret_cast<unsigned long*>(reinterpret_cast<unsigned int>(m_pInterface) + 1240) = ulTime; };

Client/mods/deathmatch/logic/CClientVehicle.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1572,6 +1572,19 @@ void CClientVehicle::SetHeliRotorSpeed(float fSpeed)
15721572
m_fHeliRotorSpeed = fSpeed;
15731573
}
15741574

1575+
bool CClientVehicle::GetVehicleRotorState() const noexcept
1576+
{
1577+
return m_pVehicle && (m_eVehicleType == CLIENTVEHICLE_HELI || m_eVehicleType == CLIENTVEHICLE_PLANE) ? m_pVehicle->GetVehicleRotorState() : m_rotorState;
1578+
}
1579+
1580+
void CClientVehicle::SetVehicleRotorState(bool state, bool stopRotor) noexcept
1581+
{
1582+
if (m_pVehicle && (m_eVehicleType == CLIENTVEHICLE_HELI || m_eVehicleType == CLIENTVEHICLE_PLANE))
1583+
m_pVehicle->SetVehicleRotorState(state, stopRotor, GetVehicleType() == CLIENTVEHICLE_HELI);
1584+
1585+
m_rotorState = state;
1586+
}
1587+
15751588
void CClientVehicle::SetPlaneRotorSpeed(float fSpeed)
15761589
{
15771590
if (m_pVehicle && m_eVehicleType == CLIENTVEHICLE_PLANE)

Client/mods/deathmatch/logic/CClientVehicle.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,10 +299,12 @@ class CClientVehicle : public CClientStreamElement
299299
// TODO: Make the class remember on virtualization
300300
float GetHeliRotorSpeed();
301301
float GetPlaneRotorSpeed();
302+
bool GetVehicleRotorState() const noexcept;
302303

303304
bool GetRotorSpeed(float&);
304305
bool SetRotorSpeed(float);
305306
bool SetWheelsRotation(float fRot1, float fRot2, float fRot3, float fRot4) noexcept;
307+
void SetVehicleRotorState(bool state, bool stopRotor) noexcept;
306308
void SetHeliRotorSpeed(float fSpeed);
307309
void SetPlaneRotorSpeed(float fSpeed);
308310
bool IsHeliSearchLightVisible();
@@ -673,6 +675,7 @@ class CClientVehicle : public CClientStreamElement
673675
uchar m_ucTrackID;
674676
bool m_bJustStreamedIn;
675677
bool m_bWheelScaleChanged;
678+
bool m_rotorState{true};
676679

677680
// Time dependent error compensation interpolation
678681
struct

Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ void CLuaVehicleDefs::LoadFunctions()
9494
{"getVehicleWheelFrictionState", ArgumentParser<GetVehicleWheelFrictionState>},
9595
{"getVehicleEntryPoints", ArgumentParser<GetVehicleEntryPoints>},
9696
{"isVehicleSmokeTrailEnabled", ArgumentParser<IsSmokeTrailEnabled>},
97+
{"getVehicleRotorState", ArgumentParser<GetVehicleRotorState>},
9798

9899
// Vehicle set funcs
99100
{"createVehicle", CreateVehicle},
@@ -161,6 +162,7 @@ void CLuaVehicleDefs::LoadFunctions()
161162
{"setVehicleModelWheelSize", ArgumentParser<SetVehicleModelWheelSize>},
162163
{"spawnVehicleFlyingComponent", ArgumentParser<SpawnVehicleFlyingComponent>},
163164
{"setVehicleSmokeTrailEnabled", ArgumentParser<SetSmokeTrailEnabled>},
165+
{"setVehicleRotorState", ArgumentParser<SetVehicleRotorState>},
164166
};
165167

166168
// Add functions
@@ -250,6 +252,7 @@ void CLuaVehicleDefs::AddClass(lua_State* luaVM)
250252
lua_classfunction(luaVM, "getWheelFrictionState", "getVehicleWheelFrictionState");
251253
lua_classfunction(luaVM, "getEntryPoints", ArgumentParser<OOP_GetVehicleEntryPoints>);
252254
lua_classfunction(luaVM, "isSmokeTrailEnabled", "isVehicleSmokeTrailEnabled");
255+
lua_classfunction(luaVM, "getRotorState", "getVehicleRotorState");
253256

254257
lua_classfunction(luaVM, "setComponentVisible", "setVehicleComponentVisible");
255258
lua_classfunction(luaVM, "setSirensOn", "setVehicleSirensOn");
@@ -299,6 +302,7 @@ void CLuaVehicleDefs::AddClass(lua_State* luaVM)
299302
lua_classfunction(luaVM, "setWheelScale", "setVehicleWheelScale");
300303
lua_classfunction(luaVM, "setModelWheelSize", "setVehicleModelWheelSize");
301304
lua_classfunction(luaVM, "setSmokeTrailEnabled", "setVehicleSmokeTrailEnabled");
305+
lua_classfunction(luaVM, "setRotorState", "setVehicleRotorState");
302306

303307
lua_classfunction(luaVM, "resetComponentPosition", "resetVehicleComponentPosition");
304308
lua_classfunction(luaVM, "resetComponentRotation", "resetVehicleComponentRotation");
@@ -357,6 +361,7 @@ void CLuaVehicleDefs::AddClass(lua_State* luaVM)
357361
lua_classvariable(luaVM, "gravity", SetVehicleGravity, OOP_GetVehicleGravity);
358362
lua_classvariable(luaVM, "turnVelocity", SetVehicleTurnVelocity, OOP_GetVehicleTurnVelocity);
359363
lua_classvariable(luaVM, "wheelScale", "setVehicleWheelScale", "getVehicleWheelScale");
364+
lua_classvariable(luaVM, "rotorState", "setVehicleRotorState", "getVehicleRotorState");
360365

361366
lua_registerclass(luaVM, "Vehicle", "Element");
362367
}
@@ -4398,3 +4403,17 @@ bool CLuaVehicleDefs::IsSmokeTrailEnabled(CClientVehicle* vehicle) noexcept
43984403
{
43994404
return vehicle->IsSmokeTrailEnabled();
44004405
}
4406+
4407+
bool CLuaVehicleDefs::SetVehicleRotorState(CClientVehicle* vehicle, bool state, std::optional<bool> stopRotor) noexcept
4408+
{
4409+
if (vehicle->GetVehicleType() != eClientVehicleType::CLIENTVEHICLE_HELI && vehicle->GetVehicleType() != eClientVehicleType::CLIENTVEHICLE_PLANE)
4410+
return false;
4411+
4412+
vehicle->SetVehicleRotorState(state, stopRotor.value_or(true));
4413+
return true;
4414+
}
4415+
4416+
bool CLuaVehicleDefs::GetVehicleRotorState(CClientVehicle* vehicle) noexcept
4417+
{
4418+
return vehicle->GetVehicleRotorState();
4419+
}

Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,9 @@ class CLuaVehicleDefs : public CLuaDefs
166166
static bool SetVehicleModelWheelSize(const unsigned short usModel, const eResizableVehicleWheelGroup eWheelGroup, const float fWheelSize);
167167
static int GetVehicleWheelFrictionState(CClientVehicle* pVehicle, unsigned char wheel);
168168

169+
static bool SetVehicleRotorState(CClientVehicle* const vehicle, bool state, std::optional<bool> stopRotor) noexcept;
170+
static bool GetVehicleRotorState(CClientVehicle* const vehicle) noexcept;
171+
169172
static bool AddVehicleSirens(CClientVehicle* vehicle, std::uint8_t sirenType, std::uint8_t sirenCount, std::optional<bool> enable360, std::optional<bool> enableLOSCheck, std::optional<bool> enableRandomiser, std::optional<bool> enableSilent) noexcept;
170173
static bool RemoveVehicleSirens(CClientVehicle* vehicle) noexcept;
171174

Client/sdk/game/CVehicle.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,8 @@ class CVehicle : public virtual CPhysical
198198
virtual bool GetTakeLessDamage() = 0;
199199
virtual bool GetTyresDontBurst() = 0;
200200
virtual unsigned short GetAdjustablePropertyValue() = 0;
201-
virtual float GetHeliRotorSpeed() = 0;
201+
virtual float GetHeliRotorSpeed() const = 0;
202+
virtual bool GetVehicleRotorState() const noexcept = 0;
202203
virtual float GetPlaneRotorSpeed() = 0;
203204
virtual unsigned long GetExplodeTime() = 0;
204205

@@ -220,6 +221,7 @@ class CVehicle : public virtual CPhysical
220221
virtual void SetTyresDontBurst(bool bTyresDontBurst) = 0;
221222
virtual void SetAdjustablePropertyValue(unsigned short usAdjustableProperty) = 0;
222223
virtual void SetHeliRotorSpeed(float fSpeed) = 0;
224+
virtual void SetVehicleRotorState(bool state, bool stopRotor, bool isHeli) noexcept = 0;
223225
virtual void SetPlaneRotorSpeed(float fSpeed) = 0;
224226
virtual bool SetVehicleWheelRotation(float fRot1, float fRot2, float fRot3, float fRot4) noexcept = 0;
225227
virtual void SetTaxiLightOn(bool bLightState) = 0;

0 commit comments

Comments
 (0)