Skip to content

Commit c3eb37e

Browse files
committed
Add new world special property (vehenginemanualmode)
1 parent caabf63 commit c3eb37e

File tree

16 files changed

+117
-3
lines changed

16 files changed

+117
-3
lines changed

Client/game_sa/CGameSA.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -930,6 +930,20 @@ void CGameSA::SetVehicleBurnExplosionsEnabled(bool isEnabled)
930930
m_isVehicleBurnExplosionsEnabled = isEnabled;
931931
}
932932

933+
void CGameSA::SetVehicleEngineManualModeEnabled(bool isEnabled)
934+
{
935+
if (isEnabled)
936+
{
937+
MemSet((void*)0x64BC03, 0x90, 5); // prevent vehicle engine from turning on (driver enter)
938+
MemCpy((void*)0x6C4EA9, "\xE9\x15\x03\x00", 4); // prevent aircraft engine from turning off (driver exit)
939+
}
940+
else
941+
{
942+
MemCpy((void*)0x64BC03, "\x75\x05\x80\xC9\x10", 5);
943+
MemCpy((void*)0x6C4EA9, "\x8A\x86\x28\x04", 4);
944+
}
945+
}
946+
933947
bool CGameSA::PerformChecks()
934948
{
935949
std::map<std::string, SCheatSA*>::iterator it;

Client/game_sa/CGameSA.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,8 @@ class CGameSA : public CGame
262262
bool IsVehicleBurnExplosionsEnabled() const noexcept override { return m_isVehicleBurnExplosionsEnabled; }
263263
void SetVehicleBurnExplosionsEnabled(bool isEnabled) override;
264264

265+
void SetVehicleEngineManualModeEnabled(bool isEnabled) override;
266+
265267
unsigned long GetMinuteDuration();
266268
void SetMinuteDuration(unsigned long ulTime);
267269

Client/game_sa/CVehicleSA.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,39 @@ void _declspec(naked) HOOK_Vehicle_PreRender(void)
5454
}
5555
}
5656

57+
float& fTimeStep = *(float*)(0xB7CB5C);
5758
static bool __fastcall CanProcessFlyingCarStuff(CAutomobileSAInterface* vehicleInterface)
5859
{
5960
SClientEntity<CVehicleSA>* vehicle = pGame->GetPools()->GetVehicle((DWORD*)vehicleInterface);
6061
if (!vehicle || !vehicle->pEntity)
6162
return true;
6263

63-
return vehicle->pEntity->GetVehicleRotorState();
64+
if (vehicle->pEntity->GetVehicleRotorState())
65+
{
66+
if (*(unsigned char*)0x64BC03 == 0x75) // keep default behavior
67+
return true;
68+
69+
if (vehicle->pEntity->GetEntityStatus() != eEntityStatus::STATUS_PHYSICS && !vehicle->pEntity->IsBeingDriven())
70+
{
71+
vehicle->pEntity->SetEntityStatus(eEntityStatus::STATUS_PHYSICS); // this will make rotors spin without driver when engine is on
72+
return false;
73+
}
74+
if (!vehicle->pEntity->IsEngineOn())
75+
{
76+
// Smoothly change rotors speed to 0
77+
float speed = vehicle->pEntity->GetHeliRotorSpeed();
78+
if (speed > 0)
79+
vehicle->pEntity->SetHeliRotorSpeed(std::max(0.0f, speed - fTimeStep * 0.00055f)); // 0x6C4EB7
80+
81+
speed = vehicle->pEntity->GetPlaneRotorSpeed();
82+
if (speed > 0)
83+
vehicle->pEntity->SetPlaneRotorSpeed(std::max(0.0f, speed - fTimeStep * 0.003f)); // 0x6CC145
84+
85+
return false;
86+
}
87+
return true;
88+
}
89+
return false;
6490
}
6591

6692
static constexpr DWORD CONTINUE_CHeli_ProcessFlyingCarStuff = 0x6C4E82;

Client/mods/deathmatch/logic/CClientGame.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6057,6 +6057,9 @@ bool CClientGame::SetWorldSpecialProperty(const WorldSpecialProperty property, c
60576057
case WorldSpecialProperty::VEHICLEBURNEXPLOSIONS:
60586058
g_pGame->SetVehicleBurnExplosionsEnabled(enabled);
60596059
break;
6060+
case WorldSpecialProperty::VEHICLE_ENGINE_MANUAL_MODE:
6061+
SetVehicleEngineManualModeEnabled(enabled);
6062+
break;
60606063
default:
60616064
return false;
60626065
}
@@ -6103,6 +6106,8 @@ bool CClientGame::IsWorldSpecialProperty(const WorldSpecialProperty property)
61036106
return m_pVehicleManager->IsSpawnFlyingComponentEnabled();
61046107
case WorldSpecialProperty::VEHICLEBURNEXPLOSIONS:
61056108
return g_pGame->IsVehicleBurnExplosionsEnabled();
6109+
case WorldSpecialProperty::VEHICLE_ENGINE_MANUAL_MODE:
6110+
return IsVehicleEngineManualModeEnabled();
61066111
}
61076112

61086113
return false;
@@ -6138,6 +6143,17 @@ bool CClientGame::IsWeaponRenderEnabled() const
61386143
return g_pGame->IsWeaponRenderEnabled();
61396144
}
61406145

6146+
void CClientGame::SetVehicleEngineManualModeEnabled(bool isEnabled)
6147+
{
6148+
if (isEnabled == m_isVehEngineManualModeEnabled)
6149+
return;
6150+
6151+
g_pGame->SetVehicleEngineManualModeEnabled(isEnabled);
6152+
m_pVehicleManager->ResetNotControlledRotors(isEnabled);
6153+
6154+
m_isVehEngineManualModeEnabled = isEnabled;
6155+
}
6156+
61416157
#pragma code_seg(".text")
61426158
bool CClientGame::VerifySADataFiles(int iEnableClientChecks)
61436159
{
@@ -6823,6 +6839,7 @@ void CClientGame::ResetWorldProperties(const ResetWorldPropsInfo& resetPropsInfo
68236839
g_pGame->SetIgnoreFireStateEnabled(false);
68246840
m_pVehicleManager->SetSpawnFlyingComponentEnabled(true);
68256841
g_pGame->SetVehicleBurnExplosionsEnabled(true);
6842+
SetVehicleEngineManualModeEnabled(false);
68266843
}
68276844

68286845
// Reset all setWorldProperty to default

Client/mods/deathmatch/logic/CClientGame.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,9 @@ class CClientGame
426426
void SetWeaponRenderEnabled(bool enabled);
427427
bool IsWeaponRenderEnabled() const;
428428

429+
bool IsVehicleEngineManualModeEnabled() const noexcept { return m_isVehEngineManualModeEnabled; }
430+
void SetVehicleEngineManualModeEnabled(bool isEnabled);
431+
429432
void ResetWorldProperties(const ResetWorldPropsInfo& resetPropsInfo);
430433

431434
CTransferBox* GetTransferBox() { return m_pTransferBox; };
@@ -784,6 +787,8 @@ class CClientGame
784787
// Birds Enabled
785788
bool m_bBirdsEnabled;
786789

790+
bool m_isVehEngineManualModeEnabled{false};
791+
787792
unsigned long m_ulMinuteDuration;
788793

789794
CClientGUIElement* m_pClickedGUIElement;

Client/mods/deathmatch/logic/CClientVehicleManager.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -791,3 +791,20 @@ void CClientVehicleManager::RestreamVehicleUpgrades(unsigned short usModel)
791791
pVehicle->GetUpgrades()->RestreamVehicleUpgrades(usModel);
792792
}
793793
}
794+
795+
void CClientVehicleManager::ResetNotControlledRotors(bool isManualMode)
796+
{
797+
// Reset rotors to custom or original state for loaded vehicles without controller
798+
// Custom state allows rotors to spin without driver inside (if engine is on)
799+
eEntityStatus status = isManualMode ? eEntityStatus::STATUS_PHYSICS : eEntityStatus::STATUS_ABANDONED;
800+
for (auto& pVehicle : m_List)
801+
{
802+
if (pVehicle->GetGameEntity() && pVehicle->GetVehicleRotorState() && !pVehicle->IsDriven())
803+
{
804+
float speed = (isManualMode && pVehicle->IsEngineOn()) ? 0.001f : 0.0f;
805+
pVehicle->GetGameEntity()->SetEntityStatus(status);
806+
pVehicle->SetHeliRotorSpeed(speed);
807+
pVehicle->SetPlaneRotorSpeed(speed);
808+
}
809+
}
810+
}

Client/mods/deathmatch/logic/CClientVehicleManager.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ class CClientVehicleManager
7373
bool IsSpawnFlyingComponentEnabled() const noexcept { return m_spawnFlyingComponentsDuringRecreate; }
7474
void SetSpawnFlyingComponentEnabled(bool isEnabled) noexcept { m_spawnFlyingComponentsDuringRecreate = isEnabled; }
7575

76+
void ResetNotControlledRotors(bool isManualMode);
77+
7678
protected:
7779
CClientManager* m_pManager;
7880
bool m_bCanRemoveFromList;

Client/mods/deathmatch/logic/CPacketHandler.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2402,6 +2402,7 @@ void CPacketHandler::Packet_MapInfo(NetBitStreamInterface& bitStream)
24022402
g_pClientGame->SetWorldSpecialProperty(WorldSpecialProperty::IGNOREFIRESTATE, wsProps.data6.ignoreFireState);
24032403
g_pClientGame->SetWorldSpecialProperty(WorldSpecialProperty::FLYINGCOMPONENTS, wsProps.data7.flyingcomponents);
24042404
g_pClientGame->SetWorldSpecialProperty(WorldSpecialProperty::VEHICLEBURNEXPLOSIONS, wsProps.data8.vehicleburnexplosions);
2405+
g_pClientGame->SetWorldSpecialProperty(WorldSpecialProperty::VEHICLE_ENGINE_MANUAL_MODE, wsProps.data9.vehEngineManualMode);
24052406

24062407
float fJetpackMaxHeight = 100;
24072408
if (!bitStream.Read(fJetpackMaxHeight))

Client/sdk/game/CGame.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,8 @@ class __declspec(novtable) CGame
241241
virtual bool IsVehicleBurnExplosionsEnabled() const noexcept = 0;
242242
virtual void SetVehicleBurnExplosionsEnabled(bool isEnabled) = 0;
243243

244+
virtual void SetVehicleEngineManualModeEnabled(bool isEnabled) = 0;
245+
244246
virtual CWeapon* CreateWeapon() = 0;
245247
virtual CWeaponStat* CreateWeaponStat(eWeaponType weaponType, eWeaponSkill weaponSkill) = 0;
246248

Server/mods/deathmatch/logic/CGame.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ CGame::CGame() : m_FloodProtect(4, 30000, 30000) // Max of 4 connecti
263263
m_WorldSpecialProps[WorldSpecialProperty::IGNOREFIRESTATE] = false;
264264
m_WorldSpecialProps[WorldSpecialProperty::FLYINGCOMPONENTS] = true;
265265
m_WorldSpecialProps[WorldSpecialProperty::VEHICLEBURNEXPLOSIONS] = true;
266+
m_WorldSpecialProps[WorldSpecialProperty::VEHICLE_ENGINE_MANUAL_MODE] = false;
266267

267268
m_JetpackWeapons[WEAPONTYPE_MICRO_UZI] = true;
268269
m_JetpackWeapons[WEAPONTYPE_TEC9] = true;
@@ -3405,7 +3406,8 @@ void CGame::Packet_Vehicle_InOut(CVehicleInOutPacket& Packet)
34053406
pPed->SetVehicleAction(CPed::VEHICLEACTION_NONE);
34063407

34073408
// Update our engine State
3408-
pVehicle->SetEngineOn(true);
3409+
if (!g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::VEHICLE_ENGINE_MANUAL_MODE))
3410+
pVehicle->SetEngineOn(true);
34093411

34103412
// Tell everyone he's in (they should warp him in)
34113413
CVehicleInOutPacket Reply(PedID, VehicleID, ucOccupiedSeat, VEHICLE_NOTIFY_IN_RETURN);
@@ -4524,6 +4526,7 @@ void CGame::ResetWorldProperties(const ResetWorldPropsInfo& resetPropsInfo)
45244526
g_pGame->SetWorldSpecialPropertyEnabled(WorldSpecialProperty::IGNOREFIRESTATE, false);
45254527
g_pGame->SetWorldSpecialPropertyEnabled(WorldSpecialProperty::FLYINGCOMPONENTS, true);
45264528
g_pGame->SetWorldSpecialPropertyEnabled(WorldSpecialProperty::VEHICLEBURNEXPLOSIONS, true);
4529+
g_pGame->SetWorldSpecialPropertyEnabled(WorldSpecialProperty::VEHICLE_ENGINE_MANUAL_MODE, false);
45274530
}
45284531

45294532
// Reset all weather stuff like heat haze, wind velocity etc

0 commit comments

Comments
 (0)