Skip to content

Commit fa33d11

Browse files
committed
Fix bug
1 parent 6340b2b commit fa33d11

File tree

9 files changed

+159
-3
lines changed

9 files changed

+159
-3
lines changed

Client/game_sa/CHeliSA.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#include "StdInc.h"
1212
#include "CHeliSA.h"
1313

14-
CHeliSA::CHeliSA(CHeliSAInterface* pInterface)
14+
CHeliSA::CHeliSA(CHeliSAInterface* pInterface) : m_rotorState(true)
1515
{
1616
SetInterface(pInterface);
1717
Init();

Client/game_sa/CHeliSA.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,49 @@
1515

1616
class CHeliSAInterface : public CAutomobileSAInterface
1717
{
18+
public:
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
1850
};
1951

2052
class CHeliSA final : public virtual CHeli, public virtual CAutomobileSA
2153
{
2254
public:
2355
CHeliSA(CHeliSAInterface* pInterface);
56+
57+
// Not SA
58+
bool GetHeliRotorState() noexcept override { return m_rotorState; }
59+
void SetHeliRotorState(bool state) noexcept override { m_rotorState = state; }
60+
61+
private:
62+
bool m_rotorState;
2463
};

Client/game_sa/CVehicleSA.cpp

Lines changed: 54 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 "CVisibilityPluginsSA.h"
2526
#include "CWorldSA.h"
@@ -51,6 +52,44 @@ void _declspec(naked) HOOK_Vehicle_PreRender(void)
5152
}
5253
}
5354

55+
bool CanProcessFlyingCarStuff(CHeliSAInterface* heliInterface)
56+
{
57+
SClientEntity<CVehicleSA>* vehicle = pGame->GetPools()->GetVehicle((DWORD*)heliInterface);
58+
if (!vehicle || !vehicle->pEntity)
59+
return true;
60+
61+
auto* heli = reinterpret_cast<CHeliSA*>(vehicle->pEntity);
62+
if (!heli)
63+
return true;
64+
65+
return heli->GetHeliRotorState();
66+
}
67+
68+
void _declspec(naked) HOOK_CHeli_ProcessFlyingCarStuff()
69+
{
70+
_asm
71+
{
72+
mov esi, ecx
73+
mov al, [esi+36h]
74+
75+
pushad
76+
push ecx
77+
call CanProcessFlyingCarStuff
78+
add esp, 4
79+
80+
movzx eax, al
81+
test eax, eax
82+
jz skip
83+
84+
popad
85+
jmp CONTINUE_CHeli_ProcessFlyingCarStuff
86+
87+
skip:
88+
popad
89+
jmp RETURN_CHeli_ProcessFlyingCarStuff
90+
}
91+
}
92+
5493
namespace
5594
{
5695
bool ClumpDumpCB(RpAtomic* pAtomic, void* data)
@@ -489,6 +528,18 @@ void CVehicleSA::SetTrainSpeed(float fSpeed)
489528
pInterface->m_fTrainSpeed = fSpeed;
490529
}
491530

531+
float CVehicleSA::GetHeliRotorSpeed()
532+
{
533+
auto* heliInterface = static_cast<CHeliSAInterface*>(GetInterface());
534+
return heliInterface->m_wheelSpeed[1];
535+
}
536+
537+
void CVehicleSA::SetHeliRotorSpeed(float speed)
538+
{
539+
auto* heliInterface = static_cast<CHeliSAInterface*>(GetInterface());
540+
heliInterface->m_wheelSpeed[1] = speed;
541+
}
542+
492543
void CVehicleSA::SetPlaneRotorSpeed(float fSpeed)
493544
{
494545
auto pInterface = static_cast<CPlaneSAInterface*>(GetInterface());
@@ -1774,6 +1825,9 @@ void CVehicleSA::StaticSetHooks()
17741825
{
17751826
// Setup vehicle sun glare hook
17761827
HookInstall(FUNC_CAutomobile_OnVehiclePreRender, (DWORD)HOOK_Vehicle_PreRender, 5);
1828+
1829+
//
1830+
HookInstall(FUNC_CHeli_ProcessFlyingCarStuff, (DWORD)HOOK_CHeli_ProcessFlyingCarStuff, 5);
17771831
}
17781832

17791833
void CVehicleSA::SetVehiclesSunGlareEnabled(bool bEnabled)

Client/game_sa/CVehicleSA.h

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

97+
#define FUNC_CHeli_ProcessFlyingCarStuff 0x6C4E7D
98+
99+
static constexpr DWORD CONTINUE_CHeli_ProcessFlyingCarStuff = 0x6C4E82;
100+
static constexpr DWORD RETURN_CHeli_ProcessFlyingCarStuff = 0x6C5404;
101+
97102
struct SRailNodeSA
98103
{
99104
short sX; // x coordinate times 8
@@ -540,7 +545,7 @@ class CVehicleSA : public virtual CVehicle, public virtual CPhysicalSA
540545
bool GetTakeLessDamage() { return GetVehicleInterface()->m_nVehicleFlags.bTakeLessDamage; };
541546
bool GetTyresDontBurst() { return GetVehicleInterface()->m_nVehicleFlags.bTyresDontBurst; };
542547
unsigned short GetAdjustablePropertyValue() { return *reinterpret_cast<unsigned short*>(reinterpret_cast<unsigned long>(m_pInterface) + 2156); };
543-
float GetHeliRotorSpeed() { return *reinterpret_cast<float*>(reinterpret_cast<unsigned int>(m_pInterface) + 2124); };
548+
float GetHeliRotorSpeed();
544549
float GetPlaneRotorSpeed();
545550

546551
unsigned long GetExplodeTime() { return *reinterpret_cast<unsigned long*>(reinterpret_cast<unsigned int>(m_pInterface) + 1240); };
@@ -566,7 +571,7 @@ class CVehicleSA : public virtual CVehicle, public virtual CPhysicalSA
566571
{
567572
*reinterpret_cast<unsigned short*>(reinterpret_cast<unsigned int>(m_pInterface) + 2156) = usAdjustableProperty;
568573
};
569-
void SetHeliRotorSpeed(float fSpeed) { *reinterpret_cast<float*>(reinterpret_cast<unsigned int>(m_pInterface) + 2124) = fSpeed; };
574+
void SetHeliRotorSpeed(float speed);
570575
void SetPlaneRotorSpeed(float fSpeed);
571576
bool SetVehicleWheelRotation(float fWheelRot1, float fWheelRot2, float fWheelRot3, float fWheelRot4) noexcept;
572577
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: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <game/CHandlingEntry.h>
2020
#include <game/CHandlingManager.h>
2121
#include <game/CStreaming.h>
22+
#include <game/CHeli.h>
2223

2324
using std::list;
2425

@@ -170,6 +171,7 @@ CClientVehicle::CClientVehicle(CClientManager* pManager, ElementID ID, unsigned
170171
m_fNitroLevel = 1.0f;
171172
m_cNitroCount = 0;
172173
m_fWheelScale = 1.0f;
174+
m_heliRotorState = m_eVehicleType == CLIENTVEHICLE_HELI;
173175

174176
for (unsigned int i = 0; i < MAX_WINDOWS; ++i)
175177
{
@@ -1576,6 +1578,34 @@ void CClientVehicle::SetHeliRotorSpeed(float fSpeed)
15761578
m_fHeliRotorSpeed = fSpeed;
15771579
}
15781580

1581+
bool CClientVehicle::GetHeliRotorState()
1582+
{
1583+
if (m_pVehicle && m_eVehicleType == CLIENTVEHICLE_HELI)
1584+
{
1585+
auto* heli = reinterpret_cast<CHeli*>(m_pVehicle);
1586+
if (heli)
1587+
return heli->GetHeliRotorState();
1588+
}
1589+
1590+
return m_heliRotorState;
1591+
}
1592+
1593+
void CClientVehicle::SetHeliRotorState(bool state)
1594+
{
1595+
if (m_pVehicle && m_eVehicleType == CLIENTVEHICLE_HELI)
1596+
{
1597+
auto* heli = reinterpret_cast<CHeli*>(m_pVehicle);
1598+
if (heli)
1599+
{
1600+
heli->SetHeliRotorState(state);
1601+
if (!state)
1602+
heli->SetHeliRotorSpeed(0.0f);
1603+
}
1604+
}
1605+
1606+
m_heliRotorState = state;
1607+
}
1608+
15791609
void CClientVehicle::SetPlaneRotorSpeed(float fSpeed)
15801610
{
15811611
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 GetHeliRotorState();
302303

303304
bool GetRotorSpeed(float&);
304305
bool SetRotorSpeed(float);
305306
bool SetWheelsRotation(float fRot1, float fRot2, float fRot3, float fRot4) noexcept;
307+
void SetHeliRotorState(bool state);
306308
void SetHeliRotorSpeed(float fSpeed);
307309
void SetPlaneRotorSpeed(float fSpeed);
308310
bool IsHeliSearchLightVisible();
@@ -671,6 +673,7 @@ class CClientVehicle : public CClientStreamElement
671673
uchar m_ucTrackID;
672674
bool m_bJustStreamedIn;
673675
bool m_bWheelScaleChanged;
676+
bool m_heliRotorState;
674677

675678
// Time dependent error compensation interpolation
676679
struct

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ void CLuaVehicleDefs::LoadFunctions()
9292
{"getVehicleModelWheelSize", ArgumentParser<GetVehicleModelWheelSize>},
9393
{"getVehicleWheelFrictionState", ArgumentParser<GetVehicleWheelFrictionState>},
9494
{"getVehicleEntryPoints", ArgumentParser<GetVehicleEntryPoints>},
95+
{"getHelicopterRotorState", ArgumentParser<GetHeliRotorState>},
9596

9697
// Vehicle set funcs
9798
{"createVehicle", CreateVehicle},
@@ -155,6 +156,7 @@ void CLuaVehicleDefs::LoadFunctions()
155156
{"setVehicleVariant", ArgumentParser<SetVehicleVariant>},
156157
{"setVehicleWheelScale", ArgumentParser<SetVehicleWheelScale>},
157158
{"setVehicleModelWheelSize", ArgumentParser<SetVehicleModelWheelSize>},
159+
{"setHelicopterRotorState", ArgumentParser<SetHeliRotorState>},
158160
};
159161

160162
// Add functions
@@ -243,6 +245,7 @@ void CLuaVehicleDefs::AddClass(lua_State* luaVM)
243245
lua_classfunction(luaVM, "getModelWheelSize", "getVehicleModelWheelSize");
244246
lua_classfunction(luaVM, "getWheelFrictionState", "getVehicleWheelFrictionState");
245247
lua_classfunction(luaVM, "getEntryPoints", ArgumentParser<OOP_GetVehicleEntryPoints>);
248+
lua_classfunction(luaVM, "getRotorState", "getHelicopterRotorState");
246249

247250
lua_classfunction(luaVM, "setComponentVisible", "setVehicleComponentVisible");
248251
lua_classfunction(luaVM, "setSirensOn", "setVehicleSirensOn");
@@ -291,6 +294,7 @@ void CLuaVehicleDefs::AddClass(lua_State* luaVM)
291294
lua_classfunction(luaVM, "setVariant", "setVehicleVariant");
292295
lua_classfunction(luaVM, "setWheelScale", "setVehicleWheelScale");
293296
lua_classfunction(luaVM, "setModelWheelSize", "setVehicleModelWheelSize");
297+
lua_classfunction(luaVM, "setRotorState", "setHelicopterRotorState");
294298

295299
lua_classfunction(luaVM, "resetComponentPosition", "resetVehicleComponentPosition");
296300
lua_classfunction(luaVM, "resetComponentRotation", "resetVehicleComponentRotation");
@@ -347,6 +351,7 @@ void CLuaVehicleDefs::AddClass(lua_State* luaVM)
347351
lua_classvariable(luaVM, "gravity", SetVehicleGravity, OOP_GetVehicleGravity);
348352
lua_classvariable(luaVM, "turnVelocity", SetVehicleTurnVelocity, OOP_GetVehicleTurnVelocity);
349353
lua_classvariable(luaVM, "wheelScale", "setVehicleWheelScale", "getVehicleWheelScale");
354+
lua_classvariable(luaVM, "rotorState", "setHelicopterRotorState", "getHelicopterRotorState");
350355

351356
lua_registerclass(luaVM, "Vehicle", "Element");
352357
}
@@ -4273,3 +4278,17 @@ std::variant<bool, std::array<CVector, 4>> CLuaVehicleDefs::OOP_GetVehicleEntryP
42734278

42744279
return entryPoints;
42754280
}
4281+
4282+
bool CLuaVehicleDefs::SetHeliRotorState(CClientVehicle* vehicle, bool state)
4283+
{
4284+
if (vehicle->GetVehicleType() != eClientVehicleType::CLIENTVEHICLE_HELI)
4285+
return false;
4286+
4287+
vehicle->SetHeliRotorState(state);
4288+
return true;
4289+
}
4290+
4291+
bool CLuaVehicleDefs::GetHeliRotorState(CClientVehicle* vehicle)
4292+
{
4293+
return vehicle->GetHeliRotorState();
4294+
}

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 SetHeliRotorState(CClientVehicle* const vehicle, bool state);
170+
static bool GetHeliRotorState(CClientVehicle* const vehicle);
171+
169172
// Components
170173
LUA_DECLARE(SetVehicleComponentPosition);
171174
LUA_DECLARE_OOP(GetVehicleComponentPosition);

Client/sdk/game/CHeli.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,7 @@ class CHeli : public virtual CAutomobile
1616
{
1717
public:
1818
virtual ~CHeli(){};
19+
20+
virtual void SetHeliRotorState(bool state) = 0;
21+
virtual bool GetHeliRotorState() = 0;
1922
};

0 commit comments

Comments
 (0)