From e6a75282e13bc9b85ce3b1b090d2f3041860c920 Mon Sep 17 00:00:00 2001 From: FileEX Date: Mon, 15 Jul 2024 20:11:15 +0200 Subject: [PATCH 1/7] spawnFlyingComponent --- Client/game_sa/CDamageManagerSA.cpp | 12 ++++---- Client/game_sa/CDamageManagerSA.h | 4 +-- .../mods/deathmatch/logic/CClientVehicle.cpp | 6 ++-- Client/mods/deathmatch/logic/CClientVehicle.h | 2 +- Client/mods/deathmatch/logic/CNetAPI.cpp | 2 +- .../mods/deathmatch/logic/CPacketHandler.cpp | 4 +-- .../logic/CStaticFunctionDefinitions.cpp | 6 ++-- .../logic/CStaticFunctionDefinitions.h | 2 +- .../logic/luadefs/CLuaVehicleDefs.cpp | 4 ++- .../deathmatch/logic/rpc/CVehicleRPCs.cpp | 6 +++- .../CMultiplayerSA_Vehicles.cpp | 28 +++++++++++++++++++ Client/sdk/game/CDamageManager.h | 4 +-- .../logic/CStaticFunctionDefinitions.cpp | 5 ++-- .../logic/CStaticFunctionDefinitions.h | 2 +- .../logic/luadefs/CLuaVehicleDefs.cpp | 4 ++- Shared/sdk/net/bitstream.h | 3 ++ 16 files changed, 68 insertions(+), 26 deletions(-) diff --git a/Client/game_sa/CDamageManagerSA.cpp b/Client/game_sa/CDamageManagerSA.cpp index 372dcaeaa57..b6ffca65740 100644 --- a/Client/game_sa/CDamageManagerSA.cpp +++ b/Client/game_sa/CDamageManagerSA.cpp @@ -98,7 +98,7 @@ void CDamageManagerSA::SetWheelStatus(eWheelPosition bWheel, BYTE bTireStatus) } } -void CDamageManagerSA::SetPanelStatus(BYTE bPanel, BYTE bPanelStatus) +void CDamageManagerSA::SetPanelStatus(BYTE bPanel, BYTE bPanelStatus, bool spawnFlyingComponent) { // Valid index? if (bPanel < MAX_PANELS && bPanelStatus <= 3) @@ -142,11 +142,13 @@ void CDamageManagerSA::SetPanelStatus(BYTE bPanel, BYTE bPanelStatus) // Call CAutomobile::SetPanelDamage to update the vehicle dwFunction = 0x6B1480; dwThis = (DWORD)internalEntityInterface; - bool bUnknown = false; + bool windscreenShatter = bPanel == ePanels::WINDSCREEN_PANEL && spawnFlyingComponent; + bool quiet = !spawnFlyingComponent; _asm { mov ecx, dwThis - push bUnknown + push quiet + push windscreenShatter push dwPanel call dwFunction } @@ -155,13 +157,13 @@ void CDamageManagerSA::SetPanelStatus(BYTE bPanel, BYTE bPanelStatus) } } -void CDamageManagerSA::SetPanelStatus(unsigned long ulStatus) +void CDamageManagerSA::SetPanelStatus(unsigned long ulStatus, bool spawnFlyingComponent) { unsigned int uiIndex; for (uiIndex = 0; uiIndex < MAX_PANELS; uiIndex++) { - SetPanelStatus(static_cast(uiIndex), static_cast(ulStatus)); + SetPanelStatus(static_cast(uiIndex), static_cast(ulStatus), spawnFlyingComponent); ulStatus >>= 4; } } diff --git a/Client/game_sa/CDamageManagerSA.h b/Client/game_sa/CDamageManagerSA.h index 33f72aeccc8..44e30d69665 100644 --- a/Client/game_sa/CDamageManagerSA.h +++ b/Client/game_sa/CDamageManagerSA.h @@ -51,8 +51,8 @@ class CDamageManagerSA : public CDamageManager void SetWheelStatus(eWheelPosition bWheel, BYTE bTireStatus); BYTE GetPanelStatus(BYTE bPanel); unsigned long GetPanelStatus(); - void SetPanelStatus(BYTE bPanel, BYTE bPanelStatus); - void SetPanelStatus(unsigned long ulStatus); + void SetPanelStatus(BYTE bPanel, BYTE bPanelStatus, bool spawnFlyingComponent); + void SetPanelStatus(unsigned long ulStatus, bool spawnFlyingComponent); BYTE GetLightStatus(BYTE bLight); unsigned char GetLightStatus(); void SetLightStatus(BYTE bLight, BYTE bLightStatus); diff --git a/Client/mods/deathmatch/logic/CClientVehicle.cpp b/Client/mods/deathmatch/logic/CClientVehicle.cpp index 42b2215adcf..88f1158f0fa 100644 --- a/Client/mods/deathmatch/logic/CClientVehicle.cpp +++ b/Client/mods/deathmatch/logic/CClientVehicle.cpp @@ -814,7 +814,7 @@ void CClientVehicle::Fix() for (int i = 0; i < MAX_DOORS; i++) SetDoorStatus(i, ucDoorStates[i], true); for (int i = 0; i < MAX_PANELS; i++) - SetPanelStatus(i, 0); + SetPanelStatus(i, 0, true); for (int i = 0; i < MAX_LIGHTS; i++) SetLightStatus(i, 0); for (int i = 0; i < MAX_WHEELS; i++) @@ -1524,12 +1524,12 @@ bool CClientVehicle::GetWheelMissing(unsigned char ucWheel, const SString& strWh return false; } -void CClientVehicle::SetPanelStatus(unsigned char ucPanel, unsigned char ucStatus) +void CClientVehicle::SetPanelStatus(unsigned char ucPanel, unsigned char ucStatus, bool spawnFlyingComponent) { if (ucPanel < MAX_PANELS) { if (m_pVehicle && HasDamageModel()) - m_pVehicle->GetDamageManager()->SetPanelStatus(static_cast(ucPanel), ucStatus); + m_pVehicle->GetDamageManager()->SetPanelStatus(static_cast(ucPanel), ucStatus, spawnFlyingComponent); m_ucPanelStates[ucPanel] = ucStatus; } diff --git a/Client/mods/deathmatch/logic/CClientVehicle.h b/Client/mods/deathmatch/logic/CClientVehicle.h index ff87ef00dc2..6bdadbd1f4f 100644 --- a/Client/mods/deathmatch/logic/CClientVehicle.h +++ b/Client/mods/deathmatch/logic/CClientVehicle.h @@ -292,7 +292,7 @@ class CClientVehicle : public CClientStreamElement void SetDoorStatus(unsigned char ucDoor, unsigned char ucStatus, bool spawnFlyingComponent); void SetWheelStatus(unsigned char ucWheel, unsigned char ucStatus, bool bSilent = true); - void SetPanelStatus(unsigned char ucPanel, unsigned char ucStatus); + void SetPanelStatus(unsigned char ucPanel, unsigned char ucStatus, bool spawnFlyingComponent); void SetLightStatus(unsigned char ucLight, unsigned char ucStatus); bool GetWheelMissing(unsigned char ucWheel, const SString& strWheelName = ""); diff --git a/Client/mods/deathmatch/logic/CNetAPI.cpp b/Client/mods/deathmatch/logic/CNetAPI.cpp index a6238512c7d..1f8b6783e2d 100644 --- a/Client/mods/deathmatch/logic/CNetAPI.cpp +++ b/Client/mods/deathmatch/logic/CNetAPI.cpp @@ -2245,7 +2245,7 @@ void CNetAPI::ReadVehiclePartsState(CClientVehicle* pVehicle, NetBitStreamInterf if (damage.data.bSyncPanels) for (unsigned int i = 0; i < MAX_PANELS; ++i) - pVehicle->SetPanelStatus(i, damage.data.panels.data.ucStates[i]); + pVehicle->SetPanelStatus(i, damage.data.panels.data.ucStates[i], true); if (damage.data.bSyncLights) for (unsigned int i = 0; i < MAX_LIGHTS; ++i) diff --git a/Client/mods/deathmatch/logic/CPacketHandler.cpp b/Client/mods/deathmatch/logic/CPacketHandler.cpp index 5b640aa655f..ad4d3f2808e 100644 --- a/Client/mods/deathmatch/logic/CPacketHandler.cpp +++ b/Client/mods/deathmatch/logic/CPacketHandler.cpp @@ -1635,7 +1635,7 @@ void CPacketHandler::Packet_VehicleDamageSync(NetBitStreamInterface& bitStream) for (unsigned int i = 0; i < MAX_PANELS; ++i) { if (damage.data.bPanelStatesChanged[i]) - pVehicle->SetPanelStatus(i, damage.data.ucPanelStates[i]); + pVehicle->SetPanelStatus(i, damage.data.ucPanelStates[i], true); } for (unsigned int i = 0; i < MAX_LIGHTS; ++i) { @@ -3386,7 +3386,7 @@ void CPacketHandler::Packet_EntityAdd(NetBitStreamInterface& bitStream) for (int i = 0; i < MAX_WHEELS; i++) pVehicle->SetWheelStatus(i, damage.data.ucWheelStates[i]); for (int i = 0; i < MAX_PANELS; i++) - pVehicle->SetPanelStatus(i, damage.data.ucPanelStates[i]); + pVehicle->SetPanelStatus(i, damage.data.ucPanelStates[i], true); for (int i = 0; i < MAX_LIGHTS; i++) pVehicle->SetLightStatus(i, damage.data.ucLightStates[i]); pVehicle->ResetDamageModelSync(); diff --git a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp index 87e99ac4ca5..b078f3a8cf0 100644 --- a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp +++ b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp @@ -3201,9 +3201,9 @@ bool CStaticFunctionDefinitions::SetVehicleLightState(CClientEntity& Entity, uns return false; } -bool CStaticFunctionDefinitions::SetVehiclePanelState(CClientEntity& Entity, unsigned char ucPanel, unsigned char ucState) +bool CStaticFunctionDefinitions::SetVehiclePanelState(CClientEntity& Entity, unsigned char ucPanel, unsigned char ucState, bool spawnFlyingComponent) { - RUN_CHILDREN(SetVehiclePanelState(**iter, ucPanel, ucState)) + RUN_CHILDREN(SetVehiclePanelState(**iter, ucPanel, ucState, spawnFlyingComponent)) if (IS_VEHICLE(&Entity)) { @@ -3211,7 +3211,7 @@ bool CStaticFunctionDefinitions::SetVehiclePanelState(CClientEntity& Entity, uns if (ucPanel < 7) { - Vehicle.SetPanelStatus(ucPanel, ucState); + Vehicle.SetPanelStatus(ucPanel, ucState, spawnFlyingComponent); return true; } } diff --git a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h index 2ffe1ff0a52..fa798ffd25c 100644 --- a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h +++ b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h @@ -241,7 +241,7 @@ class CStaticFunctionDefinitions static bool SetVehicleDoorState(CClientEntity& Entity, unsigned char ucDoor, unsigned char ucState, bool spawnFlyingComponent); static bool SetVehicleWheelStates(CClientEntity& Entity, int iFrontLeft, int iRearLeft = -1, int iFrontRight = -1, int iRearRight = -1); static bool SetVehicleLightState(CClientEntity& Entity, unsigned char ucLight, unsigned char ucState); - static bool SetVehiclePanelState(CClientEntity& Entity, unsigned char ucPanel, unsigned char ucState); + static bool SetVehiclePanelState(CClientEntity& Entity, unsigned char ucPanel, unsigned char ucState, bool spawnFlyingComponent); static bool SetVehicleOverrideLights(CClientEntity& Entity, unsigned char ucLights); static bool AttachTrailerToVehicle(CClientVehicle& Vehicle, CClientVehicle& Trailer, const CVector& vecRotationOffsetDegrees); static bool DetachTrailerFromVehicle(CClientVehicle& Vehicle, CClientVehicle* pTrailer = NULL); diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp index b26b2163e42..9f889e720d2 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp @@ -1939,14 +1939,16 @@ int CLuaVehicleDefs::SetVehiclePanelState(lua_State* luaVM) { CClientEntity* pEntity = NULL; unsigned char ucPanel = 0, ucState = 0; + bool spawnFlyingComponent; CScriptArgReader argStream(luaVM); argStream.ReadUserData(pEntity); argStream.ReadNumber(ucPanel); argStream.ReadNumber(ucState); + argStream.ReadBool(spawnFlyingComponent, true); if (!argStream.HasErrors()) { - if (CStaticFunctionDefinitions::SetVehiclePanelState(*pEntity, ucPanel, ucState)) + if (CStaticFunctionDefinitions::SetVehiclePanelState(*pEntity, ucPanel, ucState, spawnFlyingComponent)) { lua_pushboolean(luaVM, true); return 1; diff --git a/Client/mods/deathmatch/logic/rpc/CVehicleRPCs.cpp b/Client/mods/deathmatch/logic/rpc/CVehicleRPCs.cpp index be586965db3..9de51e05893 100644 --- a/Client/mods/deathmatch/logic/rpc/CVehicleRPCs.cpp +++ b/Client/mods/deathmatch/logic/rpc/CVehicleRPCs.cpp @@ -350,7 +350,11 @@ void CVehicleRPCs::SetVehicleDamageState(CClientEntity* pSource, NetBitStreamInt unsigned char ucPanel, ucState; if (bitStream.Read(ucPanel) && bitStream.Read(ucState)) { - pVehicle->SetPanelStatus(ucPanel, ucState); + bool spawnFlyingComponent = true; + if (bitStream.Can(eBitStreamVersion::SetVehiclePanelState_SpawnFlyingComponent)) + bitStream.ReadBit(spawnFlyingComponent); + + pVehicle->SetPanelStatus(ucPanel, ucState, spawnFlyingComponent); } } default: diff --git a/Client/multiplayer_sa/CMultiplayerSA_Vehicles.cpp b/Client/multiplayer_sa/CMultiplayerSA_Vehicles.cpp index 88b0b11eb8a..9884e8e658c 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_Vehicles.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_Vehicles.cpp @@ -107,6 +107,33 @@ static void _declspec(naked) HOOK_CAEVehicleAudioEntity__Initialise() } } +////////////////////////////////////////////////////////////////////////////////////////// +// CAutomobile::SetPanelDamage +// +// This hook allows determining whether flying components should be spawned +////////////////////////////////////////////////////////////////////////////////////////// +#define HOOKPOS_CAutomobile_SetPanelDamage 0x6B15BE +#define HOOKSIZE_CAutomobile_SetPanelDamage 5 +static DWORD SPAWN_FLYING_COMPONENTS = 0x6B15C3; +static DWORD SKIP_FLYING_COMPONENTS = 0x6B15DA; +static void _declspec(naked) HOOK_CAutomobile_SetPanelDamage() +{ + _asm + { + mov al, byte ptr [esp+1Ch] + test al, al + jnz skipFlyingComponents + + push 5 + push ebp + mov ecx, esi + jmp SPAWN_FLYING_COMPONENTS + + skipFlyingComponents: + jmp SKIP_FLYING_COMPONENTS + } +} + ////////////////////////////////////////////////////////////////////////////////////////// // // CMultiplayerSA::InitHooks_Vehicles @@ -118,4 +145,5 @@ void CMultiplayerSA::InitHooks_Vehicles() { EZHookInstall(CDamageManager__ProgressDoorDamage); EZHookInstall(CAEVehicleAudioEntity__Initialise); + EZHookInstall(CAutomobile_SetPanelDamage); } diff --git a/Client/sdk/game/CDamageManager.h b/Client/sdk/game/CDamageManager.h index 81fda712678..d3eec78db0e 100644 --- a/Client/sdk/game/CDamageManager.h +++ b/Client/sdk/game/CDamageManager.h @@ -132,8 +132,8 @@ class CDamageManager virtual void SetWheelStatus(eWheelPosition bTire, BYTE bTireStatus) = 0; virtual BYTE GetPanelStatus(BYTE bPanel) = 0; virtual unsigned long GetPanelStatus() = 0; - virtual void SetPanelStatus(BYTE bPanel, BYTE bPanelStatus) = 0; - virtual void SetPanelStatus(unsigned long ulStatus) = 0; + virtual void SetPanelStatus(BYTE bPanel, BYTE bPanelStatus, bool spawnFlyingComponent) = 0; + virtual void SetPanelStatus(unsigned long ulStatus, bool spawnFlyingComponent) = 0; virtual BYTE GetLightStatus(BYTE bLight) = 0; virtual unsigned char GetLightStatus() = 0; virtual void SetLightStatus(BYTE bLight, BYTE bLightStatus) = 0; diff --git a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp index cbfb4809b53..15d1d5aea17 100644 --- a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp +++ b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp @@ -6732,10 +6732,10 @@ bool CStaticFunctionDefinitions::SetVehicleLightState(CElement* pElement, unsign return false; } -bool CStaticFunctionDefinitions::SetVehiclePanelState(CElement* pElement, unsigned char ucPanel, unsigned char ucState) +bool CStaticFunctionDefinitions::SetVehiclePanelState(CElement* pElement, unsigned char ucPanel, unsigned char ucState, bool spawnFlyingComponent) { assert(pElement); - RUN_CHILDREN(SetVehiclePanelState(*iter, ucPanel, ucState)) + RUN_CHILDREN(SetVehiclePanelState(*iter, ucPanel, ucState, spawnFlyingComponent)) if (IS_VEHICLE(pElement)) { @@ -6752,6 +6752,7 @@ bool CStaticFunctionDefinitions::SetVehiclePanelState(CElement* pElement, unsign BitStream.pBitStream->Write(ucObject); BitStream.pBitStream->Write(ucPanel); BitStream.pBitStream->Write(ucState); + BitStream.pBitStream->WriteBit(spawnFlyingComponent); m_pPlayerManager->BroadcastOnlyJoined(CElementRPCPacket(pVehicle, SET_VEHICLE_DAMAGE_STATE, *BitStream.pBitStream)); return true; } diff --git a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h index db6fb1874e8..41262ee0e04 100644 --- a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h +++ b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h @@ -311,7 +311,7 @@ class CStaticFunctionDefinitions static bool SetVehicleDoorState(CElement* pElement, unsigned char ucDoor, unsigned char ucState, bool spawnFlyingComponent); static bool SetVehicleWheelStates(CElement* pElement, int iFrontLeft, int iRearLeft = -1, int iFrontRight = -1, int iRearRight = -1); static bool SetVehicleLightState(CElement* pElement, unsigned char ucLight, unsigned char ucState); - static bool SetVehiclePanelState(CElement* pElement, unsigned char ucPanel, unsigned char ucState); + static bool SetVehiclePanelState(CElement* pElement, unsigned char ucPanel, unsigned char ucState, bool spawnFlyingComponent); static bool SetVehicleIdleRespawnDelay(CElement* pElement, unsigned long ulTime); static bool SetVehicleRespawnDelay(CElement* pElement, unsigned long ulTime); static bool GetVehicleRespawnPosition(CElement* pElement, CVector& vecPosition); diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp index 294ea7310cb..c88731522d1 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp @@ -2122,15 +2122,17 @@ int CLuaVehicleDefs::SetVehiclePanelState(lua_State* luaVM) CElement* pElement; unsigned char ucPanel; unsigned char ucState; + bool spawnFlyingComponent; CScriptArgReader argStream(luaVM); argStream.ReadUserData(pElement); argStream.ReadNumber(ucPanel); argStream.ReadNumber(ucState); + argStream.ReadBool(spawnFlyingComponent, true); if (!argStream.HasErrors()) { - if (CStaticFunctionDefinitions::SetVehiclePanelState(pElement, ucPanel, ucState)) + if (CStaticFunctionDefinitions::SetVehiclePanelState(pElement, ucPanel, ucState, spawnFlyingComponent)) { lua_pushboolean(luaVM, true); return 1; diff --git a/Shared/sdk/net/bitstream.h b/Shared/sdk/net/bitstream.h index e0de0f91720..38e653ec5b1 100644 --- a/Shared/sdk/net/bitstream.h +++ b/Shared/sdk/net/bitstream.h @@ -560,6 +560,9 @@ enum class eBitStreamVersion : unsigned short // 2024-06-30 WorldSpecialProperty_TunnelWeatherBlend, + // Add "spawnFlyingComponent" to setVehiclePanelState + // 2024-07-15 + SetVehiclePanelState_SpawnFlyingComponent, // This allows us to automatically increment the BitStreamVersion when things are added to this enum. // Make sure you only add things above this comment. From dda9018a6fef4f6873b8b947dfa5f93de7eca697 Mon Sep 17 00:00:00 2001 From: FileEX Date: Wed, 17 Jul 2024 16:16:39 +0200 Subject: [PATCH 2/7] Add breakGlass argument --- Client/game_sa/CDamageManagerSA.cpp | 8 ++++---- Client/game_sa/CDamageManagerSA.h | 4 ++-- Client/mods/deathmatch/logic/CClientVehicle.cpp | 6 +++--- Client/mods/deathmatch/logic/CClientVehicle.h | 2 +- Client/mods/deathmatch/logic/CNetAPI.cpp | 2 +- Client/mods/deathmatch/logic/CPacketHandler.cpp | 4 ++-- .../mods/deathmatch/logic/CStaticFunctionDefinitions.cpp | 6 +++--- Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h | 2 +- Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp | 5 +++-- Client/mods/deathmatch/logic/rpc/CVehicleRPCs.cpp | 6 +++++- Client/sdk/game/CDamageManager.h | 4 ++-- .../mods/deathmatch/logic/CStaticFunctionDefinitions.cpp | 5 +++-- Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h | 2 +- Server/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp | 4 +++- 14 files changed, 34 insertions(+), 26 deletions(-) diff --git a/Client/game_sa/CDamageManagerSA.cpp b/Client/game_sa/CDamageManagerSA.cpp index b6ffca65740..e98ad933936 100644 --- a/Client/game_sa/CDamageManagerSA.cpp +++ b/Client/game_sa/CDamageManagerSA.cpp @@ -98,7 +98,7 @@ void CDamageManagerSA::SetWheelStatus(eWheelPosition bWheel, BYTE bTireStatus) } } -void CDamageManagerSA::SetPanelStatus(BYTE bPanel, BYTE bPanelStatus, bool spawnFlyingComponent) +void CDamageManagerSA::SetPanelStatus(BYTE bPanel, BYTE bPanelStatus, bool spawnFlyingComponent, bool breakGlass) { // Valid index? if (bPanel < MAX_PANELS && bPanelStatus <= 3) @@ -142,7 +142,7 @@ void CDamageManagerSA::SetPanelStatus(BYTE bPanel, BYTE bPanelStatus, bool spawn // Call CAutomobile::SetPanelDamage to update the vehicle dwFunction = 0x6B1480; dwThis = (DWORD)internalEntityInterface; - bool windscreenShatter = bPanel == ePanels::WINDSCREEN_PANEL && spawnFlyingComponent; + bool windscreenShatter = bPanel == ePanels::WINDSCREEN_PANEL && breakGlass; bool quiet = !spawnFlyingComponent; _asm { @@ -157,13 +157,13 @@ void CDamageManagerSA::SetPanelStatus(BYTE bPanel, BYTE bPanelStatus, bool spawn } } -void CDamageManagerSA::SetPanelStatus(unsigned long ulStatus, bool spawnFlyingComponent) +void CDamageManagerSA::SetPanelStatus(unsigned long ulStatus, bool spawnFlyingComponent, bool breakGlass) { unsigned int uiIndex; for (uiIndex = 0; uiIndex < MAX_PANELS; uiIndex++) { - SetPanelStatus(static_cast(uiIndex), static_cast(ulStatus), spawnFlyingComponent); + SetPanelStatus(static_cast(uiIndex), static_cast(ulStatus), spawnFlyingComponent, breakGlass); ulStatus >>= 4; } } diff --git a/Client/game_sa/CDamageManagerSA.h b/Client/game_sa/CDamageManagerSA.h index 44e30d69665..00651f68b5e 100644 --- a/Client/game_sa/CDamageManagerSA.h +++ b/Client/game_sa/CDamageManagerSA.h @@ -51,8 +51,8 @@ class CDamageManagerSA : public CDamageManager void SetWheelStatus(eWheelPosition bWheel, BYTE bTireStatus); BYTE GetPanelStatus(BYTE bPanel); unsigned long GetPanelStatus(); - void SetPanelStatus(BYTE bPanel, BYTE bPanelStatus, bool spawnFlyingComponent); - void SetPanelStatus(unsigned long ulStatus, bool spawnFlyingComponent); + void SetPanelStatus(BYTE bPanel, BYTE bPanelStatus, bool spawnFlyingComponent = true, bool breakGlass = false); + void SetPanelStatus(unsigned long ulStatus, bool spawnFlyingComponent = true, bool breakGlass = false); BYTE GetLightStatus(BYTE bLight); unsigned char GetLightStatus(); void SetLightStatus(BYTE bLight, BYTE bLightStatus); diff --git a/Client/mods/deathmatch/logic/CClientVehicle.cpp b/Client/mods/deathmatch/logic/CClientVehicle.cpp index 88f1158f0fa..1564204e0de 100644 --- a/Client/mods/deathmatch/logic/CClientVehicle.cpp +++ b/Client/mods/deathmatch/logic/CClientVehicle.cpp @@ -814,7 +814,7 @@ void CClientVehicle::Fix() for (int i = 0; i < MAX_DOORS; i++) SetDoorStatus(i, ucDoorStates[i], true); for (int i = 0; i < MAX_PANELS; i++) - SetPanelStatus(i, 0, true); + SetPanelStatus(i, 0); for (int i = 0; i < MAX_LIGHTS; i++) SetLightStatus(i, 0); for (int i = 0; i < MAX_WHEELS; i++) @@ -1524,12 +1524,12 @@ bool CClientVehicle::GetWheelMissing(unsigned char ucWheel, const SString& strWh return false; } -void CClientVehicle::SetPanelStatus(unsigned char ucPanel, unsigned char ucStatus, bool spawnFlyingComponent) +void CClientVehicle::SetPanelStatus(unsigned char ucPanel, unsigned char ucStatus, bool spawnFlyingComponent, bool breakGlass) { if (ucPanel < MAX_PANELS) { if (m_pVehicle && HasDamageModel()) - m_pVehicle->GetDamageManager()->SetPanelStatus(static_cast(ucPanel), ucStatus, spawnFlyingComponent); + m_pVehicle->GetDamageManager()->SetPanelStatus(static_cast(ucPanel), ucStatus, spawnFlyingComponent, breakGlass); m_ucPanelStates[ucPanel] = ucStatus; } diff --git a/Client/mods/deathmatch/logic/CClientVehicle.h b/Client/mods/deathmatch/logic/CClientVehicle.h index 6bdadbd1f4f..f5bc422e870 100644 --- a/Client/mods/deathmatch/logic/CClientVehicle.h +++ b/Client/mods/deathmatch/logic/CClientVehicle.h @@ -292,7 +292,7 @@ class CClientVehicle : public CClientStreamElement void SetDoorStatus(unsigned char ucDoor, unsigned char ucStatus, bool spawnFlyingComponent); void SetWheelStatus(unsigned char ucWheel, unsigned char ucStatus, bool bSilent = true); - void SetPanelStatus(unsigned char ucPanel, unsigned char ucStatus, bool spawnFlyingComponent); + void SetPanelStatus(unsigned char ucPanel, unsigned char ucStatus, bool spawnFlyingComponent = true, bool breakGlass = false); void SetLightStatus(unsigned char ucLight, unsigned char ucStatus); bool GetWheelMissing(unsigned char ucWheel, const SString& strWheelName = ""); diff --git a/Client/mods/deathmatch/logic/CNetAPI.cpp b/Client/mods/deathmatch/logic/CNetAPI.cpp index 1f8b6783e2d..a6238512c7d 100644 --- a/Client/mods/deathmatch/logic/CNetAPI.cpp +++ b/Client/mods/deathmatch/logic/CNetAPI.cpp @@ -2245,7 +2245,7 @@ void CNetAPI::ReadVehiclePartsState(CClientVehicle* pVehicle, NetBitStreamInterf if (damage.data.bSyncPanels) for (unsigned int i = 0; i < MAX_PANELS; ++i) - pVehicle->SetPanelStatus(i, damage.data.panels.data.ucStates[i], true); + pVehicle->SetPanelStatus(i, damage.data.panels.data.ucStates[i]); if (damage.data.bSyncLights) for (unsigned int i = 0; i < MAX_LIGHTS; ++i) diff --git a/Client/mods/deathmatch/logic/CPacketHandler.cpp b/Client/mods/deathmatch/logic/CPacketHandler.cpp index 9fe0d17caa7..ed8ba623c1e 100644 --- a/Client/mods/deathmatch/logic/CPacketHandler.cpp +++ b/Client/mods/deathmatch/logic/CPacketHandler.cpp @@ -1637,7 +1637,7 @@ void CPacketHandler::Packet_VehicleDamageSync(NetBitStreamInterface& bitStream) for (unsigned int i = 0; i < MAX_PANELS; ++i) { if (damage.data.bPanelStatesChanged[i]) - pVehicle->SetPanelStatus(i, damage.data.ucPanelStates[i], true); + pVehicle->SetPanelStatus(i, damage.data.ucPanelStates[i]); } for (unsigned int i = 0; i < MAX_LIGHTS; ++i) { @@ -3388,7 +3388,7 @@ void CPacketHandler::Packet_EntityAdd(NetBitStreamInterface& bitStream) for (int i = 0; i < MAX_WHEELS; i++) pVehicle->SetWheelStatus(i, damage.data.ucWheelStates[i]); for (int i = 0; i < MAX_PANELS; i++) - pVehicle->SetPanelStatus(i, damage.data.ucPanelStates[i], true); + pVehicle->SetPanelStatus(i, damage.data.ucPanelStates[i]); for (int i = 0; i < MAX_LIGHTS; i++) pVehicle->SetLightStatus(i, damage.data.ucLightStates[i]); pVehicle->ResetDamageModelSync(); diff --git a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp index 8dc1eb0e093..e54c38be657 100644 --- a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp +++ b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp @@ -3202,9 +3202,9 @@ bool CStaticFunctionDefinitions::SetVehicleLightState(CClientEntity& Entity, uns return false; } -bool CStaticFunctionDefinitions::SetVehiclePanelState(CClientEntity& Entity, unsigned char ucPanel, unsigned char ucState, bool spawnFlyingComponent) +bool CStaticFunctionDefinitions::SetVehiclePanelState(CClientEntity& Entity, unsigned char ucPanel, unsigned char ucState, bool spawnFlyingComponent, bool breakGlass) { - RUN_CHILDREN(SetVehiclePanelState(**iter, ucPanel, ucState, spawnFlyingComponent)) + RUN_CHILDREN(SetVehiclePanelState(**iter, ucPanel, ucState, spawnFlyingComponent, breakGlass)) if (IS_VEHICLE(&Entity)) { @@ -3212,7 +3212,7 @@ bool CStaticFunctionDefinitions::SetVehiclePanelState(CClientEntity& Entity, uns if (ucPanel < 7) { - Vehicle.SetPanelStatus(ucPanel, ucState, spawnFlyingComponent); + Vehicle.SetPanelStatus(ucPanel, ucState, spawnFlyingComponent, breakGlass); return true; } } diff --git a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h index 420bc346349..7bcc2152e83 100644 --- a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h +++ b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h @@ -241,7 +241,7 @@ class CStaticFunctionDefinitions static bool SetVehicleDoorState(CClientEntity& Entity, unsigned char ucDoor, unsigned char ucState, bool spawnFlyingComponent); static bool SetVehicleWheelStates(CClientEntity& Entity, int iFrontLeft, int iRearLeft = -1, int iFrontRight = -1, int iRearRight = -1); static bool SetVehicleLightState(CClientEntity& Entity, unsigned char ucLight, unsigned char ucState); - static bool SetVehiclePanelState(CClientEntity& Entity, unsigned char ucPanel, unsigned char ucState, bool spawnFlyingComponent); + static bool SetVehiclePanelState(CClientEntity& Entity, unsigned char ucPanel, unsigned char ucState, bool spawnFlyingComponent = true, bool breakGlass = false); static bool SetVehicleOverrideLights(CClientEntity& Entity, unsigned char ucLights); static bool AttachTrailerToVehicle(CClientVehicle& Vehicle, CClientVehicle& Trailer, const CVector& vecRotationOffsetDegrees); static bool DetachTrailerFromVehicle(CClientVehicle& Vehicle, CClientVehicle* pTrailer = NULL); diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp index 9f889e720d2..30a05856cd5 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp @@ -1939,16 +1939,17 @@ int CLuaVehicleDefs::SetVehiclePanelState(lua_State* luaVM) { CClientEntity* pEntity = NULL; unsigned char ucPanel = 0, ucState = 0; - bool spawnFlyingComponent; + bool spawnFlyingComponent, breakGlass; CScriptArgReader argStream(luaVM); argStream.ReadUserData(pEntity); argStream.ReadNumber(ucPanel); argStream.ReadNumber(ucState); argStream.ReadBool(spawnFlyingComponent, true); + argStream.ReadBool(breakGlass, false); if (!argStream.HasErrors()) { - if (CStaticFunctionDefinitions::SetVehiclePanelState(*pEntity, ucPanel, ucState, spawnFlyingComponent)) + if (CStaticFunctionDefinitions::SetVehiclePanelState(*pEntity, ucPanel, ucState, spawnFlyingComponent, breakGlass)) { lua_pushboolean(luaVM, true); return 1; diff --git a/Client/mods/deathmatch/logic/rpc/CVehicleRPCs.cpp b/Client/mods/deathmatch/logic/rpc/CVehicleRPCs.cpp index 9de51e05893..c470bbbbaff 100644 --- a/Client/mods/deathmatch/logic/rpc/CVehicleRPCs.cpp +++ b/Client/mods/deathmatch/logic/rpc/CVehicleRPCs.cpp @@ -351,10 +351,14 @@ void CVehicleRPCs::SetVehicleDamageState(CClientEntity* pSource, NetBitStreamInt if (bitStream.Read(ucPanel) && bitStream.Read(ucState)) { bool spawnFlyingComponent = true; + bool breakGlass = false; if (bitStream.Can(eBitStreamVersion::SetVehiclePanelState_SpawnFlyingComponent)) + { bitStream.ReadBit(spawnFlyingComponent); + bitStream.ReadBit(breakGlass); + } - pVehicle->SetPanelStatus(ucPanel, ucState, spawnFlyingComponent); + pVehicle->SetPanelStatus(ucPanel, ucState, spawnFlyingComponent, breakGlass); } } default: diff --git a/Client/sdk/game/CDamageManager.h b/Client/sdk/game/CDamageManager.h index d3eec78db0e..df6511b052c 100644 --- a/Client/sdk/game/CDamageManager.h +++ b/Client/sdk/game/CDamageManager.h @@ -132,8 +132,8 @@ class CDamageManager virtual void SetWheelStatus(eWheelPosition bTire, BYTE bTireStatus) = 0; virtual BYTE GetPanelStatus(BYTE bPanel) = 0; virtual unsigned long GetPanelStatus() = 0; - virtual void SetPanelStatus(BYTE bPanel, BYTE bPanelStatus, bool spawnFlyingComponent) = 0; - virtual void SetPanelStatus(unsigned long ulStatus, bool spawnFlyingComponent) = 0; + virtual void SetPanelStatus(BYTE bPanel, BYTE bPanelStatus, bool spawnFlyingComponent = true, bool breakGlass = false) = 0; + virtual void SetPanelStatus(unsigned long ulStatus, bool spawnFlyingComponent = true, bool breakGlass = false) = 0; virtual BYTE GetLightStatus(BYTE bLight) = 0; virtual unsigned char GetLightStatus() = 0; virtual void SetLightStatus(BYTE bLight, BYTE bLightStatus) = 0; diff --git a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp index 4ff7f74d70c..366be40f0ce 100644 --- a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp +++ b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp @@ -6734,10 +6734,10 @@ bool CStaticFunctionDefinitions::SetVehicleLightState(CElement* pElement, unsign return false; } -bool CStaticFunctionDefinitions::SetVehiclePanelState(CElement* pElement, unsigned char ucPanel, unsigned char ucState, bool spawnFlyingComponent) +bool CStaticFunctionDefinitions::SetVehiclePanelState(CElement* pElement, unsigned char ucPanel, unsigned char ucState, bool spawnFlyingComponent, bool breakGlass) { assert(pElement); - RUN_CHILDREN(SetVehiclePanelState(*iter, ucPanel, ucState, spawnFlyingComponent)) + RUN_CHILDREN(SetVehiclePanelState(*iter, ucPanel, ucState, spawnFlyingComponent, breakGlass)) if (IS_VEHICLE(pElement)) { @@ -6755,6 +6755,7 @@ bool CStaticFunctionDefinitions::SetVehiclePanelState(CElement* pElement, unsign BitStream.pBitStream->Write(ucPanel); BitStream.pBitStream->Write(ucState); BitStream.pBitStream->WriteBit(spawnFlyingComponent); + BitStream.pBitStream->WriteBit(breakGlass); m_pPlayerManager->BroadcastOnlyJoined(CElementRPCPacket(pVehicle, SET_VEHICLE_DAMAGE_STATE, *BitStream.pBitStream)); return true; } diff --git a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h index 3f1cadaee42..2ed33b93b26 100644 --- a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h +++ b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h @@ -311,7 +311,7 @@ class CStaticFunctionDefinitions static bool SetVehicleDoorState(CElement* pElement, unsigned char ucDoor, unsigned char ucState, bool spawnFlyingComponent); static bool SetVehicleWheelStates(CElement* pElement, int iFrontLeft, int iRearLeft = -1, int iFrontRight = -1, int iRearRight = -1); static bool SetVehicleLightState(CElement* pElement, unsigned char ucLight, unsigned char ucState); - static bool SetVehiclePanelState(CElement* pElement, unsigned char ucPanel, unsigned char ucState, bool spawnFlyingComponent); + static bool SetVehiclePanelState(CElement* pElement, unsigned char ucPanel, unsigned char ucState, bool spawnFlyingComponent = true, bool breakGlass = false); static bool SetVehicleIdleRespawnDelay(CElement* pElement, unsigned long ulTime); static bool SetVehicleRespawnDelay(CElement* pElement, unsigned long ulTime); static bool GetVehicleRespawnPosition(CElement* pElement, CVector& vecPosition); diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp index c88731522d1..529c7e7e436 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp @@ -2123,16 +2123,18 @@ int CLuaVehicleDefs::SetVehiclePanelState(lua_State* luaVM) unsigned char ucPanel; unsigned char ucState; bool spawnFlyingComponent; + bool breakGlass; CScriptArgReader argStream(luaVM); argStream.ReadUserData(pElement); argStream.ReadNumber(ucPanel); argStream.ReadNumber(ucState); argStream.ReadBool(spawnFlyingComponent, true); + argStream.ReadBool(breakGlass, false); if (!argStream.HasErrors()) { - if (CStaticFunctionDefinitions::SetVehiclePanelState(pElement, ucPanel, ucState, spawnFlyingComponent)) + if (CStaticFunctionDefinitions::SetVehiclePanelState(pElement, ucPanel, ucState, spawnFlyingComponent, breakGlass)) { lua_pushboolean(luaVM, true); return 1; From 17d68d0400b67cfbe78c58bf1beec11565dcf881 Mon Sep 17 00:00:00 2001 From: FileEX Date: Sat, 5 Oct 2024 18:05:46 +0200 Subject: [PATCH 3/7] Review --- Client/game_sa/CDamageManagerSA.cpp | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/Client/game_sa/CDamageManagerSA.cpp b/Client/game_sa/CDamageManagerSA.cpp index e98ad933936..6f5ae8f81ef 100644 --- a/Client/game_sa/CDamageManagerSA.cpp +++ b/Client/game_sa/CDamageManagerSA.cpp @@ -140,18 +140,7 @@ void CDamageManagerSA::SetPanelStatus(BYTE bPanel, BYTE bPanelStatus, bool spawn else { // Call CAutomobile::SetPanelDamage to update the vehicle - dwFunction = 0x6B1480; - dwThis = (DWORD)internalEntityInterface; - bool windscreenShatter = bPanel == ePanels::WINDSCREEN_PANEL && breakGlass; - bool quiet = !spawnFlyingComponent; - _asm - { - mov ecx, dwThis - push quiet - push windscreenShatter - push dwPanel - call dwFunction - } + ((void(__thiscall*)(CEntitySAInterface*, int, bool, bool))0x6B1480)(internalEntityInterface, dwPanel, bPanel == ePanels::WINDSCREEN_PANEL && breakGlass, !spawnFlyingComponent); } } } From d69ee4c1702051392e2123231ae47ee6c592c076 Mon Sep 17 00:00:00 2001 From: FileEX Date: Thu, 2 Jan 2025 04:08:50 +0100 Subject: [PATCH 4/7] New approach --- Client/game_sa/CAEVehicleAudioEntitySA.h | 5 + Client/game_sa/CAutomobileSA.cpp | 70 ++++++++++++++ Client/game_sa/CAutomobileSA.h | 12 +++ Client/game_sa/CDamageManagerSA.cpp | 56 ++++++------ Client/game_sa/CDamageManagerSA.h | 10 ++ Client/game_sa/CModelInfoSA.cpp | 5 + Client/game_sa/CModelInfoSA.h | 91 +++++++++++-------- Client/game_sa/CVehicleSA.cpp | 2 +- Client/game_sa/CVehicleSA.h | 5 + .../CMultiplayerSA_Vehicles.cpp | 28 ------ Client/sdk/game/CDamageManager.h | 8 +- Shared/sdk/SharedUtil.Math.h | 5 + 12 files changed, 202 insertions(+), 95 deletions(-) diff --git a/Client/game_sa/CAEVehicleAudioEntitySA.h b/Client/game_sa/CAEVehicleAudioEntitySA.h index cb4ff8699de..45f169299cd 100644 --- a/Client/game_sa/CAEVehicleAudioEntitySA.h +++ b/Client/game_sa/CAEVehicleAudioEntitySA.h @@ -73,6 +73,11 @@ static_assert(sizeof(CAETwinLoopSoundEntity) == 0xA8, "Invalid size for CAETwinL class CAEVehicleAudioEntitySAInterface : public CAEAudioEntity { public: + void AddAudioEvent(int eventId, float volume) + { + ((void(__thiscall*)(CAEVehicleAudioEntitySAInterface*, int, float))0x4F6420)(this, eventId, volume); + } + short unk1; // +124 char unk2[2]; // +126 tVehicleAudioSettings m_nSettings; // +128 diff --git a/Client/game_sa/CAutomobileSA.cpp b/Client/game_sa/CAutomobileSA.cpp index 59205e86e10..f110da88eec 100644 --- a/Client/game_sa/CAutomobileSA.cpp +++ b/Client/game_sa/CAutomobileSA.cpp @@ -11,9 +11,79 @@ #include "StdInc.h" #include "CAutomobileSA.h" +#include "CGameSA.h" + +extern CGameSA* pGame; CAutomobileSA::CAutomobileSA(CAutomobileSAInterface* pInterface) { SetInterface(pInterface); Init(); } + +void CAutomobileSAInterface::SetPanelDamage(std::uint8_t panelId, bool breakGlass, bool spawnFlyingComponent) +{ + int nodeId = CDamageManagerSA::GetCarNodeIndexFromPanel(panelId); + eCarNodes node = static_cast(nodeId); + + RwFrame* frame = m_aCarNodes[nodeId]; + if (!frame) + return; + + CVehicleModelInfoSAInterface* vehicleInfo = nullptr; + if (auto* mi = pGame->GetModelInfo(m_nModelIndex)) + vehicleInfo = static_cast(mi->GetInterface()); + + if (!vehicleInfo || !vehicleInfo->IsComponentDamageable(nodeId)) + return; + + switch (m_damageManager.GetPanelStatus(panelId)) + { + case DT_PANEL_DAMAGED: + { + if ((pHandlingData->uiModelFlags & 0x10000000) != 0) // check bouncePanels flag + return; + + if (node != eCarNodes::WINDSCREEN && node != eCarNodes::WING_LF && node != eCarNodes::WING_RF) + { + // Get free bouncing panel + CBouncingPanelSAInterface* panelInterface = nullptr; + for (auto& panel : m_panels) + { + if (panel.m_nFrameId == static_cast(-1)) + { + panelInterface = &panel; + break; + } + } + + panelInterface->SetPanel(nodeId, 1, GetRandomNumberInRange(-0.2f, -0.5f)); + } + + SetComponentVisibility(frame, 2); // ATOMIC_IS_DAM_STATE + break; + } + case DT_PANEL_OPENED: + { + if (panelId == WINDSCREEN_PANEL) + m_VehicleAudioEntity.AddAudioEvent(91, 0.0f); + + SetComponentVisibility(frame, 2); // ATOMIC_IS_DAM_STATE + break; + } + case DT_PANEL_OPENED_DAMAGED: + { + if (panelId == WINDSCREEN_PANEL) + { + if (breakGlass) + ((void(__cdecl*)(CAutomobileSAInterface*))0x71C2B0)(this); // Call CGlass::CarWindscreenShatters + } + + if (spawnFlyingComponent && (panelId != WINDSCREEN_PANEL || (panelId == WINDSCREEN_PANEL && !breakGlass))) + SpawnFlyingComponent(node, eCarComponentCollisionTypes::COL_NODE_PANEL); + + SetComponentVisibility(frame, 0); // ATOMIC_IS_NOT_PRESENT + break; + } + } +} diff --git a/Client/game_sa/CAutomobileSA.h b/Client/game_sa/CAutomobileSA.h index 921c6638b3c..b2fc09417cc 100644 --- a/Client/game_sa/CAutomobileSA.h +++ b/Client/game_sa/CAutomobileSA.h @@ -24,6 +24,11 @@ class CBouncingPanelSAInterface { public: + void SetPanel(std::int16_t frameId, std::int16_t axis, float angleLimit) + { + ((void(__thiscall*)(CBouncingPanelSAInterface*, std::int16_t, std::int16_t, float))0x6F4920)(this, frameId, axis, angleLimit); + } + unsigned short m_nFrameId; unsigned short m_nAxis; float m_fAngleLimit; @@ -35,6 +40,13 @@ static_assert(sizeof(CBouncingPanelSAInterface) == 0x20, "Invalid size for CBoun class CAutomobileSAInterface : public CVehicleSAInterface { public: + void SetPanelDamage(std::uint8_t panelId, bool breakGlass, bool spawnFlyingComponent = true); + + CObjectSAInterface* SpawnFlyingComponent(const eCarNodes& nodeId, const eCarComponentCollisionTypes& collType) + { + return ((CObjectSAInterface*(__thiscall*)(CAutomobileSAInterface*, eCarNodes, eCarComponentCollisionTypes))0x6a8580)(this, nodeId, collType); + } + CDamageManagerSAInterface m_damageManager; CDoorSAInterface m_doors[MAX_DOORS]; RwFrame* m_aCarNodes[static_cast(eCarNodes::NUM_NODES)]; diff --git a/Client/game_sa/CDamageManagerSA.cpp b/Client/game_sa/CDamageManagerSA.cpp index 6f5ae8f81ef..66e29cddc0d 100644 --- a/Client/game_sa/CDamageManagerSA.cpp +++ b/Client/game_sa/CDamageManagerSA.cpp @@ -11,6 +11,7 @@ #include "StdInc.h" #include "CDamageManagerSA.h" +#include "CAutomobileSA.h" BYTE CDamageManagerSA::GetEngineStatus() { @@ -122,13 +123,10 @@ void CDamageManagerSA::SetPanelStatus(BYTE bPanel, BYTE bPanelStatus, bool spawn // Intact? if (bPanelStatus == DT_PANEL_INTACT) { - // Grab the car node index for the given panel - static int s_iCarNodeIndexes[7] = {0x0F, 0x0E, 0x00 /*?*/, 0x00 /*?*/, 0x12, 0x0C, 0x0D}; - // Call CAutomobile::FixPanel to update the vehicle dwFunction = 0x6A3670; dwThis = (DWORD)internalEntityInterface; - int iCarNodeIndex = s_iCarNodeIndexes[bPanel]; + int iCarNodeIndex = GetCarNodeIndexFromPanel(bPanel); _asm { mov ecx, dwThis @@ -138,10 +136,7 @@ void CDamageManagerSA::SetPanelStatus(BYTE bPanel, BYTE bPanelStatus, bool spawn } } else - { - // Call CAutomobile::SetPanelDamage to update the vehicle - ((void(__thiscall*)(CEntitySAInterface*, int, bool, bool))0x6B1480)(internalEntityInterface, dwPanel, bPanel == ePanels::WINDSCREEN_PANEL && breakGlass, !spawnFlyingComponent); - } + reinterpret_cast(internalEntityInterface)->SetPanelDamage(dwPanel, breakGlass, spawnFlyingComponent); } } } @@ -159,24 +154,7 @@ void CDamageManagerSA::SetPanelStatus(unsigned long ulStatus, bool spawnFlyingCo BYTE CDamageManagerSA::GetPanelStatus(BYTE bPanel) { - if (bPanel < MAX_PANELS) - { - DWORD dwFunction = FUNC_GetPanelStatus; - DWORD dwPointer = (DWORD)internalInterface; - BYTE bReturn = 0; - DWORD dwPanel = bPanel; - _asm - { - mov ecx, dwPointer - push dwPanel - call dwFunction - mov bReturn, al - } - - return bReturn; - } - - return 0; + return internalInterface->GetPanelStatus(bPanel); } unsigned long CDamageManagerSA::GetPanelStatus() @@ -266,3 +244,29 @@ void CDamageManagerSA::FuckCarCompletely(bool bKeepWheels) call dwFunc } } + +int CDamageManagerSA::GetCarNodeIndexFromPanel(std::uint8_t panelId) +{ + int index = -1; + + switch (panelId) + { + case 0: + index = 15; // PANEL_WING_LF + break; + case 1: + index = 14; // PANEL_WING_RF + break; + case 4: + index = 18; // PANEL_WINDSCREEN + break; + case 5: + index = 12; // BUMP_FRONT + break; + case 6: + index = 13; // BUMP_REAR + break; + } + + return index; +} diff --git a/Client/game_sa/CDamageManagerSA.h b/Client/game_sa/CDamageManagerSA.h index 00651f68b5e..ee1f2e5dafd 100644 --- a/Client/game_sa/CDamageManagerSA.h +++ b/Client/game_sa/CDamageManagerSA.h @@ -27,6 +27,14 @@ class CDamageManagerSAInterface // 28 bytes due to the way its packed (24 containing actual data) { public: + std::uint8_t GetPanelStatus(std::uint8_t panelId) + { + if (panelId >= MAX_PANELS) + return 0; + + return ((std::uint8_t(__thiscall*)(CDamageManagerSAInterface*, std::uint8_t))FUNC_GetPanelStatus)(this, panelId); + } + float fWheelDamageEffect; BYTE bEngineStatus; // old - wont be used BYTE Wheel[MAX_WHEELS]; @@ -62,6 +70,8 @@ class CDamageManagerSA : public CDamageManager void FuckCarCompletely(bool bKeepWheels); + static int GetCarNodeIndexFromPanel(std::uint8_t panelId); + CDamageManagerSA(class CEntitySAInterface* intEntityInterface, CDamageManagerSAInterface* intInterface) { internalEntityInterface = intEntityInterface; diff --git a/Client/game_sa/CModelInfoSA.cpp b/Client/game_sa/CModelInfoSA.cpp index 0b5ff312b32..5eb12b99709 100644 --- a/Client/game_sa/CModelInfoSA.cpp +++ b/Client/game_sa/CModelInfoSA.cpp @@ -2126,3 +2126,8 @@ bool CModelInfoSA::ForceUnload() return true; } + +bool CVehicleModelInfoSAInterface::IsComponentDamageable(int componentIndex) const +{ + return pVisualInfo->m_maskComponentDamagable & (1 << componentIndex); +} diff --git a/Client/game_sa/CModelInfoSA.h b/Client/game_sa/CModelInfoSA.h index 6fc7b04811a..50d0f5dce8f 100644 --- a/Client/game_sa/CModelInfoSA.h +++ b/Client/game_sa/CModelInfoSA.h @@ -14,6 +14,7 @@ #include #include #include "CRenderWareSA.h" +#include "game/RenderWare.h" class CPedModelInfoSA; class CPedModelInfoSAInterface; @@ -259,54 +260,72 @@ class CTimeModelInfoSAInterface : public CBaseModelInfoSAInterface CTimeInfoSAInterface timeInfo; }; +class CVehicleModelUpgradePosnDesc +{ + CVector m_vPosition; + RtQuat m_vRotation; + int m_iParentId; +}; +static_assert(sizeof(CVehicleModelUpgradePosnDesc) == 0x20, "Invalid size of CVehicleModelUpgradePosnDesc class"); + class CVehicleModelVisualInfoSAInterface // Not sure about this name. If somebody knows more, please change { public: - CVector vecDummies[15]; - char m_sUpgrade[18]; + CVector vecDummies[15]; + CVehicleModelUpgradePosnDesc m_sUpgrade[18]; + RpAtomic* m_pExtra[6]; + std::uint8_t m_numExtras; + std::uint8_t _pad[3]; + int m_maskComponentDamagable; }; +static_assert(sizeof(CVehicleModelVisualInfoSAInterface) == 0x314, "Invalid size of CVehicleModelVisualInfoSAInterface class"); -class CVehicleModelInfoSAInterface : public CBaseModelInfoSAInterface +class CVehicleModelInfoSAInterface : public CClumpModelInfoSAInterface { public: - uint32 pad1; // +32 - RpMaterial* pPlateMaterial; // +36 + bool IsComponentDamageable(int componentIndex) const; + + RpMaterial* pPlateMaterial; char plateText[8]; - char pad[2]; + std::uint8_t field_30; + std::uint8_t plateType; char gameName[8]; - char pad2[2]; - unsigned int uiVehicleType; + std::uint8_t field_3A[2]; + std::uint32_t vehicleType; float fWheelSizeFront; float fWheelSizeRear; - short sWheelModel; - short sHandlingID; - byte ucNumDoors; - byte ucVehicleList; - byte ucVehicleFlags; - byte ucWheelUpgradeClass; - byte ucTimesUsed; - short sVehFrequency; - unsigned int uiComponentRules; - float fSteeringAngle; - CVehicleModelVisualInfoSAInterface* pVisualInfo; // +92 - char pad3[464]; - char pDirtMaterial[64]; // *RwMaterial - char pad4[64]; - char primColors[8]; - char secondColors[8]; - char treeColors[8]; - char fourColors[8]; - unsigned char ucNumOfColorVariations; - unsigned char ucLastColorVariation; - unsigned char ucPrimColor; - unsigned char ucSecColor; - unsigned char ucTertColor; - unsigned char ucQuatColor; - char upgrades[36]; - char anRemapTXDs[8]; - char pad5[2]; - char pAnimBlock[4]; + std::int16_t wheelModelID; + std::int16_t handlingID; + std::uint8_t numDoors; + std::uint8_t vehicleClass; + std::uint8_t vehicleFlags; + std::uint8_t wheelUpgradeClass; + std::uint8_t timesUsed; + std::uint8_t field_51; + std::int16_t vehFrequency; + std::uint32_t componentRules; + float bikeSteeringAngle; + CVehicleModelVisualInfoSAInterface* pVisualInfo; // vehicleStruct + std::uint8_t field_60[464]; + RpMaterial** m_dirtMaterials; + std::size_t m_numDirtMaterials; + RpMaterial* m_staticDirtMaterials[30]; + std::uint8_t primColors[8]; + std::uint8_t secondColors[8]; + std::uint8_t treeColors[8]; + std::uint8_t fourColors[8]; + std::uint8_t numOfColorVariations; + std::uint8_t lastColorVariation; + std::uint8_t primColor; + std::uint8_t secColor; + std::uint8_t tertColor; + std::uint8_t quatColor; + std::uint8_t upgrades[36]; + std::uint8_t anRemapTXDs[8]; + std::uint8_t field_302[2]; + void* pAnimBlock; // CAnimBlock* }; +static_assert(sizeof(CVehicleModelInfoSAInterface) == 0x308, "Invalid size of CVehicleModelInfoSAInterface class"); class CModelInfoSA : public CModelInfo { diff --git a/Client/game_sa/CVehicleSA.cpp b/Client/game_sa/CVehicleSA.cpp index afb1bf0c42d..898add2961f 100644 --- a/Client/game_sa/CVehicleSA.cpp +++ b/Client/game_sa/CVehicleSA.cpp @@ -1666,7 +1666,7 @@ bool CVehicleSA::SpawnFlyingComponent(const eCarNodes& nodeIndex, const eCarComp MemPut(0x6A85B3, nodesOffset); MemPut(0x6A8631, nodesOffset); - auto* componentObject = ((CObjectSAInterface * (__thiscall*)(CVehicleSAInterface*, int, int)) FUNC_CAutomobile__SpawnFlyingComponent)(GetVehicleInterface(), static_cast(nodeIndex), static_cast(collisionType)); + auto* componentObject = reinterpret_cast(GetInterface())->SpawnFlyingComponent(nodeIndex, collisionType); // Restore default nodes array in CAutomobile::SpawnFlyingComponent // CAutomobile::m_aCarNodes offset diff --git a/Client/game_sa/CVehicleSA.h b/Client/game_sa/CVehicleSA.h index ca4f496c9b7..5c4b332b7c1 100644 --- a/Client/game_sa/CVehicleSA.h +++ b/Client/game_sa/CVehicleSA.h @@ -274,6 +274,11 @@ class CAutoPilot class CVehicleSAInterface : public CPhysicalSAInterface { public: + void SetComponentVisibility(RwFrame* component, std::uint32_t state) + { + ((void(__thiscall*)(CVehicleSAInterface*, RwFrame*, std::uint32_t))0x6D2700)(this, component, state); + } + CAEVehicleAudioEntitySAInterface m_VehicleAudioEntity; // 312 tHandlingDataSA* pHandlingData; // +900 diff --git a/Client/multiplayer_sa/CMultiplayerSA_Vehicles.cpp b/Client/multiplayer_sa/CMultiplayerSA_Vehicles.cpp index 9884e8e658c..88b0b11eb8a 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_Vehicles.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_Vehicles.cpp @@ -107,33 +107,6 @@ static void _declspec(naked) HOOK_CAEVehicleAudioEntity__Initialise() } } -////////////////////////////////////////////////////////////////////////////////////////// -// CAutomobile::SetPanelDamage -// -// This hook allows determining whether flying components should be spawned -////////////////////////////////////////////////////////////////////////////////////////// -#define HOOKPOS_CAutomobile_SetPanelDamage 0x6B15BE -#define HOOKSIZE_CAutomobile_SetPanelDamage 5 -static DWORD SPAWN_FLYING_COMPONENTS = 0x6B15C3; -static DWORD SKIP_FLYING_COMPONENTS = 0x6B15DA; -static void _declspec(naked) HOOK_CAutomobile_SetPanelDamage() -{ - _asm - { - mov al, byte ptr [esp+1Ch] - test al, al - jnz skipFlyingComponents - - push 5 - push ebp - mov ecx, esi - jmp SPAWN_FLYING_COMPONENTS - - skipFlyingComponents: - jmp SKIP_FLYING_COMPONENTS - } -} - ////////////////////////////////////////////////////////////////////////////////////////// // // CMultiplayerSA::InitHooks_Vehicles @@ -145,5 +118,4 @@ void CMultiplayerSA::InitHooks_Vehicles() { EZHookInstall(CDamageManager__ProgressDoorDamage); EZHookInstall(CAEVehicleAudioEntity__Initialise); - EZHookInstall(CAutomobile_SetPanelDamage); } diff --git a/Client/sdk/game/CDamageManager.h b/Client/sdk/game/CDamageManager.h index 7b48148f4b5..befb5264fac 100644 --- a/Client/sdk/game/CDamageManager.h +++ b/Client/sdk/game/CDamageManager.h @@ -55,12 +55,12 @@ enum ePlaneComponentStatus DT_PLANE_MISSING }; -enum eComponentStatus +enum eComponentStatus : std::uint8_t { DT_PANEL_INTACT = 0, - // DT_PANEL_SHIFTED, - DT_PANEL_BASHED, - DT_PANEL_BASHED2, + DT_PANEL_OPENED, + DT_PANEL_DAMAGED, + DT_PANEL_OPENED_DAMAGED, DT_PANEL_MISSING }; diff --git a/Shared/sdk/SharedUtil.Math.h b/Shared/sdk/SharedUtil.Math.h index 32677d4e0ce..48e98b1bb04 100644 --- a/Shared/sdk/SharedUtil.Math.h +++ b/Shared/sdk/SharedUtil.Math.h @@ -104,4 +104,9 @@ namespace SharedUtil } inline float DegreesToRadians(float fValue) { return fValue * 0.017453292f; } + + inline float GetRandomNumberInRange(float minRange, float maxRange) + { + return Lerp(minRange, maxRange, static_cast(std::rand() * static_cast(1.0f / RAND_MAX))); + } } // namespace SharedUtil From 0e8649956847dcb7ead42a4c7f0fae74857e39fd Mon Sep 17 00:00:00 2001 From: FileEX Date: Fri, 3 Jan 2025 00:30:54 +0100 Subject: [PATCH 5/7] Review --- Client/game_sa/CAutomobileSA.cpp | 10 +++++----- Client/game_sa/CDamageManagerSA.cpp | 9 ++++++--- Client/game_sa/CDamageManagerSA.h | 4 ++-- Shared/sdk/SharedUtil.Math.h | 6 +++++- 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/Client/game_sa/CAutomobileSA.cpp b/Client/game_sa/CAutomobileSA.cpp index f110da88eec..268df61309c 100644 --- a/Client/game_sa/CAutomobileSA.cpp +++ b/Client/game_sa/CAutomobileSA.cpp @@ -24,6 +24,9 @@ CAutomobileSA::CAutomobileSA(CAutomobileSAInterface* pInterface) void CAutomobileSAInterface::SetPanelDamage(std::uint8_t panelId, bool breakGlass, bool spawnFlyingComponent) { int nodeId = CDamageManagerSA::GetCarNodeIndexFromPanel(panelId); + if (nodeId < 0) + return; + eCarNodes node = static_cast(nodeId); RwFrame* frame = m_aCarNodes[nodeId]; @@ -47,17 +50,14 @@ void CAutomobileSAInterface::SetPanelDamage(std::uint8_t panelId, bool breakGlas if (node != eCarNodes::WINDSCREEN && node != eCarNodes::WING_LF && node != eCarNodes::WING_RF) { // Get free bouncing panel - CBouncingPanelSAInterface* panelInterface = nullptr; for (auto& panel : m_panels) { - if (panel.m_nFrameId == static_cast(-1)) + if (panel.m_nFrameId == (std::uint16_t)0xFFFF) { - panelInterface = &panel; + panel.SetPanel(nodeId, 1, GetRandomNumberInRange(-0.2f, -0.5f)); break; } } - - panelInterface->SetPanel(nodeId, 1, GetRandomNumberInRange(-0.2f, -0.5f)); } SetComponentVisibility(frame, 2); // ATOMIC_IS_DAM_STATE diff --git a/Client/game_sa/CDamageManagerSA.cpp b/Client/game_sa/CDamageManagerSA.cpp index 66e29cddc0d..37209745ea8 100644 --- a/Client/game_sa/CDamageManagerSA.cpp +++ b/Client/game_sa/CDamageManagerSA.cpp @@ -126,12 +126,15 @@ void CDamageManagerSA::SetPanelStatus(BYTE bPanel, BYTE bPanelStatus, bool spawn // Call CAutomobile::FixPanel to update the vehicle dwFunction = 0x6A3670; dwThis = (DWORD)internalEntityInterface; - int iCarNodeIndex = GetCarNodeIndexFromPanel(bPanel); + int carNodeIndex = GetCarNodeIndexFromPanel(bPanel); + if (carNodeIndex < 0) + return; + _asm { mov ecx, dwThis push dwPanel - push iCarNodeIndex + push carNodeIndex call dwFunction } } @@ -245,7 +248,7 @@ void CDamageManagerSA::FuckCarCompletely(bool bKeepWheels) } } -int CDamageManagerSA::GetCarNodeIndexFromPanel(std::uint8_t panelId) +int CDamageManagerSA::GetCarNodeIndexFromPanel(std::uint8_t panelId) noexcept { int index = -1; diff --git a/Client/game_sa/CDamageManagerSA.h b/Client/game_sa/CDamageManagerSA.h index ee1f2e5dafd..5fc38046793 100644 --- a/Client/game_sa/CDamageManagerSA.h +++ b/Client/game_sa/CDamageManagerSA.h @@ -27,7 +27,7 @@ class CDamageManagerSAInterface // 28 bytes due to the way its packed (24 containing actual data) { public: - std::uint8_t GetPanelStatus(std::uint8_t panelId) + std::uint8_t GetPanelStatus(std::uint8_t panelId) const { if (panelId >= MAX_PANELS) return 0; @@ -70,7 +70,7 @@ class CDamageManagerSA : public CDamageManager void FuckCarCompletely(bool bKeepWheels); - static int GetCarNodeIndexFromPanel(std::uint8_t panelId); + static int GetCarNodeIndexFromPanel(std::uint8_t panelId) noexcept; CDamageManagerSA(class CEntitySAInterface* intEntityInterface, CDamageManagerSAInterface* intInterface) { diff --git a/Shared/sdk/SharedUtil.Math.h b/Shared/sdk/SharedUtil.Math.h index 48e98b1bb04..73c7c532df6 100644 --- a/Shared/sdk/SharedUtil.Math.h +++ b/Shared/sdk/SharedUtil.Math.h @@ -12,6 +12,7 @@ #include #include "SharedUtil.Misc.h" +#include namespace SharedUtil { @@ -105,8 +106,11 @@ namespace SharedUtil inline float DegreesToRadians(float fValue) { return fValue * 0.017453292f; } + static std::random_device randomDevice; + static std::mt19937 randomEngine(randomDevice()); + inline float GetRandomNumberInRange(float minRange, float maxRange) { - return Lerp(minRange, maxRange, static_cast(std::rand() * static_cast(1.0f / RAND_MAX))); + return std::uniform_real_distribution{minRange, maxRange}(randomEngine); } } // namespace SharedUtil From 401f0de84f70953a6fd884e6b069e0c428b096e1 Mon Sep 17 00:00:00 2001 From: FileEX Date: Fri, 3 Jan 2025 00:43:02 +0100 Subject: [PATCH 6/7] Update CAutomobileSA.cpp --- Client/game_sa/CAutomobileSA.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Client/game_sa/CAutomobileSA.cpp b/Client/game_sa/CAutomobileSA.cpp index 268df61309c..800b5163b7b 100644 --- a/Client/game_sa/CAutomobileSA.cpp +++ b/Client/game_sa/CAutomobileSA.cpp @@ -76,7 +76,7 @@ void CAutomobileSAInterface::SetPanelDamage(std::uint8_t panelId, bool breakGlas if (panelId == WINDSCREEN_PANEL) { if (breakGlass) - ((void(__cdecl*)(CAutomobileSAInterface*))0x71C2B0)(this); // Call CGlass::CarWindscreenShatters + ((void(__cdecl*)(CAutomobileSAInterface*))0x71C2B0)(this, false); // Call CGlass::CarWindscreenShatters } if (spawnFlyingComponent && (panelId != WINDSCREEN_PANEL || (panelId == WINDSCREEN_PANEL && !breakGlass))) From 6e48a97101266679534feaf60faea5297d556baa Mon Sep 17 00:00:00 2001 From: FileEX Date: Fri, 3 Jan 2025 01:00:04 +0100 Subject: [PATCH 7/7] Fix build --- Client/game_sa/CAutomobileSA.cpp | 2 +- Client/game_sa/CDamageManagerSA.cpp | 2 +- Client/game_sa/CDamageManagerSA.h | 4 ++-- Client/sdk/game/CDamageManager.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Client/game_sa/CAutomobileSA.cpp b/Client/game_sa/CAutomobileSA.cpp index 800b5163b7b..0dc82e6b1bd 100644 --- a/Client/game_sa/CAutomobileSA.cpp +++ b/Client/game_sa/CAutomobileSA.cpp @@ -76,7 +76,7 @@ void CAutomobileSAInterface::SetPanelDamage(std::uint8_t panelId, bool breakGlas if (panelId == WINDSCREEN_PANEL) { if (breakGlass) - ((void(__cdecl*)(CAutomobileSAInterface*))0x71C2B0)(this, false); // Call CGlass::CarWindscreenShatters + ((void(__cdecl*)(CAutomobileSAInterface*, bool))0x71C2B0)(this, false); // Call CGlass::CarWindscreenShatters } if (spawnFlyingComponent && (panelId != WINDSCREEN_PANEL || (panelId == WINDSCREEN_PANEL && !breakGlass))) diff --git a/Client/game_sa/CDamageManagerSA.cpp b/Client/game_sa/CDamageManagerSA.cpp index 37209745ea8..d659330afcd 100644 --- a/Client/game_sa/CDamageManagerSA.cpp +++ b/Client/game_sa/CDamageManagerSA.cpp @@ -155,7 +155,7 @@ void CDamageManagerSA::SetPanelStatus(unsigned long ulStatus, bool spawnFlyingCo } } -BYTE CDamageManagerSA::GetPanelStatus(BYTE bPanel) +BYTE CDamageManagerSA::GetPanelStatus(BYTE bPanel) const { return internalInterface->GetPanelStatus(bPanel); } diff --git a/Client/game_sa/CDamageManagerSA.h b/Client/game_sa/CDamageManagerSA.h index 5fc38046793..b3fbb72900a 100644 --- a/Client/game_sa/CDamageManagerSA.h +++ b/Client/game_sa/CDamageManagerSA.h @@ -27,7 +27,7 @@ class CDamageManagerSAInterface // 28 bytes due to the way its packed (24 containing actual data) { public: - std::uint8_t GetPanelStatus(std::uint8_t panelId) const + std::uint8_t GetPanelStatus(std::uint8_t panelId) { if (panelId >= MAX_PANELS) return 0; @@ -57,7 +57,7 @@ class CDamageManagerSA : public CDamageManager void SetDoorStatus(eDoors bDoor, BYTE bDoorStatus, bool spawnFlyingComponent); BYTE GetWheelStatus(eWheelPosition bWheel); void SetWheelStatus(eWheelPosition bWheel, BYTE bTireStatus); - BYTE GetPanelStatus(BYTE bPanel); + BYTE GetPanelStatus(BYTE bPanel) const; unsigned long GetPanelStatus(); void SetPanelStatus(BYTE bPanel, BYTE bPanelStatus, bool spawnFlyingComponent = true, bool breakGlass = false); void SetPanelStatus(unsigned long ulStatus, bool spawnFlyingComponent = true, bool breakGlass = false); diff --git a/Client/sdk/game/CDamageManager.h b/Client/sdk/game/CDamageManager.h index befb5264fac..a764467a5aa 100644 --- a/Client/sdk/game/CDamageManager.h +++ b/Client/sdk/game/CDamageManager.h @@ -173,7 +173,7 @@ class CDamageManager virtual void SetDoorStatus(eDoors bDoor, BYTE bDoorStatus, bool spawnFlyingComponent) = 0; virtual BYTE GetWheelStatus(eWheelPosition bTire) = 0; virtual void SetWheelStatus(eWheelPosition bTire, BYTE bTireStatus) = 0; - virtual BYTE GetPanelStatus(BYTE bPanel) = 0; + virtual BYTE GetPanelStatus(BYTE bPanel) const = 0; virtual unsigned long GetPanelStatus() = 0; virtual void SetPanelStatus(BYTE bPanel, BYTE bPanelStatus, bool spawnFlyingComponent = true, bool breakGlass = false) = 0; virtual void SetPanelStatus(unsigned long ulStatus, bool spawnFlyingComponent = true, bool breakGlass = false) = 0;