From 7ad96e2e78fe41f8924d3f105b1683f7363c6fcb Mon Sep 17 00:00:00 2001 From: FileEX Date: Tue, 31 Dec 2024 00:38:05 +0100 Subject: [PATCH] Add new functions is/setElementOnFire (PR #3783, Fixes #3673) This commit deprecates setPedOnFire and isPedOnFire --- Client/game_sa/CEntitySA.h | 3 + Client/game_sa/CObjectSA.cpp | 34 +++++++++++ Client/game_sa/CObjectSA.h | 5 +- Client/game_sa/CPedSA.cpp | 61 ++++++++----------- Client/game_sa/CPedSA.h | 4 +- Client/game_sa/CVehicleSA.cpp | 34 +++++++++++ Client/game_sa/CVehicleSA.h | 5 +- Client/mods/deathmatch/logic/CClientEntity.h | 3 + Client/mods/deathmatch/logic/CClientObject.h | 3 + Client/mods/deathmatch/logic/CClientPed.cpp | 17 ++---- Client/mods/deathmatch/logic/CClientPed.h | 4 +- Client/mods/deathmatch/logic/CClientVehicle.h | 3 + Client/mods/deathmatch/logic/CNetAPI.cpp | 6 ++ .../logic/CStaticFunctionDefinitions.cpp | 3 + .../logic/luadefs/CLuaElementDefs.cpp | 18 ++++++ .../logic/luadefs/CLuaElementDefs.h | 2 + .../deathmatch/logic/rpc/CElementRPCs.cpp | 6 ++ .../mods/deathmatch/logic/rpc/CElementRPCs.h | 1 + Client/sdk/game/CEntity.h | 3 + Client/sdk/game/CObject.h | 1 + Client/sdk/game/CPed.h | 3 - Client/sdk/game/CVehicle.h | 1 + Server/mods/deathmatch/logic/CElement.h | 3 + Server/mods/deathmatch/logic/CPed.h | 4 +- .../logic/CPerfStat.RPCPacketUsage.cpp | 1 + .../deathmatch/logic/CResourceChecker.Data.h | 13 +++- .../logic/CStaticFunctionDefinitions.cpp | 17 ++++++ .../logic/CStaticFunctionDefinitions.h | 1 + Server/mods/deathmatch/logic/CVehicle.cpp | 1 + Server/mods/deathmatch/logic/CVehicle.h | 5 ++ .../logic/luadefs/CLuaElementDefs.cpp | 15 +++++ .../logic/luadefs/CLuaElementDefs.h | 2 + .../logic/net/CSimVehiclePuresyncPacket.cpp | 6 ++ .../logic/net/CSimVehiclePuresyncPacket.h | 2 + .../logic/packets/CVehiclePuresyncPacket.cpp | 6 ++ Shared/sdk/net/bitstream.h | 4 ++ Shared/sdk/net/rpc_enums.h | 3 + 37 files changed, 240 insertions(+), 63 deletions(-) diff --git a/Client/game_sa/CEntitySA.h b/Client/game_sa/CEntitySA.h index 205d5415f7..ead219d904 100644 --- a/Client/game_sa/CEntitySA.h +++ b/Client/game_sa/CEntitySA.h @@ -334,6 +334,9 @@ class CEntitySA : public virtual CEntity bool GetBonePosition(eBone boneId, CVector& position); bool SetBonePosition(eBone boneId, const CVector& position); + bool IsOnFire() override { return false; } + bool SetOnFire(bool onFire) override { return false; } + // CEntitySA interface virtual void OnChangingPosition(const CVector& vecNewPosition) {} diff --git a/Client/game_sa/CObjectSA.cpp b/Client/game_sa/CObjectSA.cpp index ef31e9b37a..83d2feef23 100644 --- a/Client/game_sa/CObjectSA.cpp +++ b/Client/game_sa/CObjectSA.cpp @@ -15,6 +15,7 @@ #include "CPoolsSA.h" #include "CRopesSA.h" #include "CWorldSA.h" +#include "CFireManagerSA.h" extern CGameSA* pGame; @@ -304,3 +305,36 @@ void CObjectSA::ResetScale() { SetScale(1.0f, 1.0f, 1.0f); } + +bool CObjectSA::SetOnFire(bool onFire) +{ + CObjectSAInterface* objectInterface = GetObjectInterface(); + if (onFire == !!objectInterface->pFire) + return false; + + auto* fireManager = static_cast(pGame->GetFireManager()); + + if (onFire) + { + CFire* fire = fireManager->StartFire(this, nullptr, static_cast(DEFAULT_FIRE_PARTICLE_SIZE)); + if (!fire) + return false; + + fire->SetTarget(this); + fire->SetStrength(1.0f); + fire->Ignite(); + fire->SetNumGenerationsAllowed(0); + + objectInterface->pFire = fire->GetInterface(); + } + else + { + CFire* fire = fireManager->GetFire(objectInterface->pFire); + if (!fire) + return false; + + fire->Extinguish(); + } + + return true; +} diff --git a/Client/game_sa/CObjectSA.h b/Client/game_sa/CObjectSA.h index 77b44772a7..5d15a30fb7 100644 --- a/Client/game_sa/CObjectSA.h +++ b/Client/game_sa/CObjectSA.h @@ -153,6 +153,9 @@ class CObjectSA : public virtual CObject, public virtual CPhysicalSA CVector* GetScale(); void ResetScale(); + bool IsOnFire() override { return GetObjectInterface()->pFire != nullptr; } + bool SetOnFire(bool onFire) override; + private: void CheckForGangTag(); -}; \ No newline at end of file +}; diff --git a/Client/game_sa/CPedSA.cpp b/Client/game_sa/CPedSA.cpp index 1ae9f942f8..3818e0cb4d 100644 --- a/Client/game_sa/CPedSA.cpp +++ b/Client/game_sa/CPedSA.cpp @@ -851,52 +851,39 @@ void CPedSA::SetBleeding(bool bBleeding) GetPedInterface()->pedFlags.bPedIsBleeding = bBleeding; } -bool CPedSA::IsOnFire() -{ - if (GetPedInterface()->pFireOnPed != NULL) - return true; - return false; -} - -void CPedSA::SetOnFire(bool bOnFire) +bool CPedSA::SetOnFire(bool onFire) { CPedSAInterface* pInterface = GetPedInterface(); + if (onFire == !!pInterface->pFireOnPed) + return false; - if (bOnFire) - { - // If we are already on fire, don't apply a new fire - if (pInterface->pFireOnPed == NULL) - { - CFireManagerSA* pFireManager = static_cast(pGame->GetFireManager()); - CFire* pFire = pFireManager->StartFire(this, NULL, (float)DEFAULT_FIRE_PARTICLE_SIZE); + auto* fireManager = static_cast(pGame->GetFireManager()); - if (pFire) - { - // Start the fire - pFire->SetTarget(this); - pFire->Ignite(); - pFire->SetStrength(1.0f); - // Attach the fire only to the player, do not let it - // create child fires when moving. - pFire->SetNumGenerationsAllowed(0); - pInterface->pFireOnPed = pFire->GetInterface(); - } - } + if (onFire) + { + CFire* fire = fireManager->StartFire(this, nullptr, static_cast(DEFAULT_FIRE_PARTICLE_SIZE)); + if (!fire) + return false; + + // Start the fire + fire->SetTarget(this); + fire->Ignite(); + fire->SetStrength(1.0f); + // Attach the fire only to the player, do not let it + // create child fires when moving. + fire->SetNumGenerationsAllowed(0); + pInterface->pFireOnPed = fire->GetInterface(); } else { - // Make sure that we have some attached fire - if (pInterface->pFireOnPed != NULL) - { - CFireManagerSA* pFireManager = static_cast(pGame->GetFireManager()); - CFire* pFire = pFireManager->GetFire(static_cast(pInterface->pFireOnPed)); + CFire* fire = fireManager->GetFire(static_cast(pInterface->pFireOnPed)); + if (!fire) + return false; - if (pFire) - { - pFire->Extinguish(); - } - } + fire->Extinguish(); } + + return true; } void CPedSA::SetStayInSamePlace(bool bStay) diff --git a/Client/game_sa/CPedSA.h b/Client/game_sa/CPedSA.h index ab16ea28f8..9989835472 100644 --- a/Client/game_sa/CPedSA.h +++ b/Client/game_sa/CPedSA.h @@ -389,8 +389,8 @@ class CPedSA : public virtual CPed, public virtual CPhysicalSA bool IsBleeding(); void SetBleeding(bool bBleeding); - bool IsOnFire(); - void SetOnFire(bool bOnFire); + bool IsOnFire() override { return GetPedInterface()->pFireOnPed != nullptr; } + bool SetOnFire(bool onFire) override; bool GetStayInSamePlace() { return GetPedInterface()->pedFlags.bStayInSamePlace; } void SetStayInSamePlace(bool bStay); diff --git a/Client/game_sa/CVehicleSA.cpp b/Client/game_sa/CVehicleSA.cpp index 5fe90c6e52..afb1bf0c42 100644 --- a/Client/game_sa/CVehicleSA.cpp +++ b/Client/game_sa/CVehicleSA.cpp @@ -26,6 +26,7 @@ #include "CVisibilityPluginsSA.h" #include "CWorldSA.h" #include "gamesa_renderware.h" +#include "CFireManagerSA.h" extern CGameSA* pGame; @@ -1925,6 +1926,39 @@ void CVehicleSA::OnChangingPosition(const CVector& vecNewPosition) } } +bool CVehicleSA::SetOnFire(bool onFire) +{ + CVehicleSAInterface* vehicleInterface = GetVehicleInterface(); + if (onFire == !!vehicleInterface->m_pFire) + return false; + + auto* fireManager = static_cast(pGame->GetFireManager()); + + if (onFire) + { + CFire* fire = fireManager->StartFire(this, nullptr, static_cast(DEFAULT_FIRE_PARTICLE_SIZE)); + if (!fire) + return false; + + fire->SetTarget(this); + fire->SetStrength(1.0f); + fire->Ignite(); + fire->SetNumGenerationsAllowed(0); + + vehicleInterface->m_pFire = fire->GetInterface(); + } + else + { + CFire* fire = fireManager->GetFire(vehicleInterface->m_pFire); + if (!fire) + return false; + + fire->Extinguish(); + } + + return true; +} + void CVehicleSA::StaticSetHooks() { // Setup vehicle sun glare hook diff --git a/Client/game_sa/CVehicleSA.h b/Client/game_sa/CVehicleSA.h index 9d2855e093..ca4f496c9b 100644 --- a/Client/game_sa/CVehicleSA.h +++ b/Client/game_sa/CVehicleSA.h @@ -310,7 +310,7 @@ class CVehicleSAInterface : public CPhysicalSAInterface unsigned char m_nSpecialColModel; CEntity* pEntityWeAreOnForVisibilityCheck; - CFire* m_pFire; + CFireSAInterface* m_pFire; float m_fSteerAngle; // +1172 float m_f2ndSteerAngle; // used for steering 2nd set of wheels or elevators etc.. @@ -694,6 +694,9 @@ class CVehicleSA : public virtual CVehicle, public virtual CPhysicalSA CVector* GetDummyPositions() { return m_dummyPositions.data(); } const CVector* GetDummyPositions() const override { return m_dummyPositions.data(); } + bool IsOnFire() override { return GetVehicleInterface()->m_pFire != nullptr; } + bool SetOnFire(bool onFire) override; + static void StaticSetHooks(); static void SetVehiclesSunGlareEnabled(bool bEnabled); static bool GetVehiclesSunGlareEnabled(); diff --git a/Client/mods/deathmatch/logic/CClientEntity.h b/Client/mods/deathmatch/logic/CClientEntity.h index 0d84526d8b..031c1418b8 100644 --- a/Client/mods/deathmatch/logic/CClientEntity.h +++ b/Client/mods/deathmatch/logic/CClientEntity.h @@ -331,6 +331,9 @@ class CClientEntity : public CClientEntityBase bool CanBeDestroyedByScript() { return m_canBeDestroyedByScript; } void SetCanBeDestroyedByScript(bool canBeDestroyedByScript) { m_canBeDestroyedByScript = canBeDestroyedByScript; } + virtual bool IsOnFire() { return false; } + virtual bool SetOnFire(bool onFire) { return false; } + protected: CClientManager* m_pManager; CClientEntity* m_pParent; diff --git a/Client/mods/deathmatch/logic/CClientObject.h b/Client/mods/deathmatch/logic/CClientObject.h index a016facd5c..03b37fbfbc 100644 --- a/Client/mods/deathmatch/logic/CClientObject.h +++ b/Client/mods/deathmatch/logic/CClientObject.h @@ -119,6 +119,9 @@ class CClientObject : public CClientStreamElement bool IsBeingRespawned() { return m_bBeingRespawned; }; void SetBeingRespawned(bool bBeingRespawned) { m_bBeingRespawned = bBeingRespawned; }; + bool IsOnFire() override { return m_pObject ? m_pObject->IsOnFire() : false; } + bool SetOnFire(bool onFire) override { return m_pObject ? m_pObject->SetOnFire(onFire) : false; }; + protected: void StreamIn(bool bInstantly); void StreamOut(); diff --git a/Client/mods/deathmatch/logic/CClientPed.cpp b/Client/mods/deathmatch/logic/CClientPed.cpp index b20189dd5e..c3d2f27f91 100644 --- a/Client/mods/deathmatch/logic/CClientPed.cpp +++ b/Client/mods/deathmatch/logic/CClientPed.cpp @@ -5902,22 +5902,13 @@ void CClientPed::SetBleeding(bool bBleeding) m_bBleeding = bBleeding; } -bool CClientPed::IsOnFire() +bool CClientPed::SetOnFire(bool bIsOnFire) { if (m_pPlayerPed) - { - return m_pPlayerPed->IsOnFire(); - } - return m_bIsOnFire; -} - -void CClientPed::SetOnFire(bool bIsOnFire) -{ - if (m_pPlayerPed) - { - m_pPlayerPed->SetOnFire(bIsOnFire); - } + return m_pPlayerPed->SetOnFire(bIsOnFire); + m_bIsOnFire = bIsOnFire; + return true; } void CClientPed::GetVoice(short* psVoiceType, short* psVoiceID) diff --git a/Client/mods/deathmatch/logic/CClientPed.h b/Client/mods/deathmatch/logic/CClientPed.h index 38cefbadfa..5c7b2cb4a6 100644 --- a/Client/mods/deathmatch/logic/CClientPed.h +++ b/Client/mods/deathmatch/logic/CClientPed.h @@ -483,8 +483,8 @@ class CClientPed : public CClientStreamElement, public CAntiCheatModule bool IsBleeding() const noexcept { return m_bBleeding; }; void SetBleeding(bool bBleeding); - bool IsOnFire(); - void SetOnFire(bool bOnFire); + bool IsOnFire() override { return m_pPlayerPed ? m_pPlayerPed->IsOnFire() : m_bIsOnFire; } + bool SetOnFire(bool bOnFire) override; void GetVoice(short* psVoiceType, short* psVoiceID); void GetVoice(const char** pszVoiceType, const char** pszVoice); diff --git a/Client/mods/deathmatch/logic/CClientVehicle.h b/Client/mods/deathmatch/logic/CClientVehicle.h index 4bb12c11f7..faeb4acfec 100644 --- a/Client/mods/deathmatch/logic/CClientVehicle.h +++ b/Client/mods/deathmatch/logic/CClientVehicle.h @@ -549,6 +549,9 @@ class CClientVehicle : public CClientStreamElement CVector GetEntryPoint(std::uint32_t entryPointIndex); + bool IsOnFire() override { return m_pVehicle ? m_pVehicle->IsOnFire() : false; } + bool SetOnFire(bool onFire) override { return m_pVehicle ? m_pVehicle->SetOnFire(onFire) : false; } + protected: void ConvertComponentRotationBase(const SString& vehicleComponent, CVector& vecInOutRotation, EComponentBaseType inputBase, EComponentBaseType outputBase); void ConvertComponentPositionBase(const SString& vehicleComponent, CVector& vecInOutPosition, EComponentBaseType inputBase, EComponentBaseType outputBase); diff --git a/Client/mods/deathmatch/logic/CNetAPI.cpp b/Client/mods/deathmatch/logic/CNetAPI.cpp index a6238512c7..ee4b9727b1 100644 --- a/Client/mods/deathmatch/logic/CNetAPI.cpp +++ b/Client/mods/deathmatch/logic/CNetAPI.cpp @@ -1541,6 +1541,9 @@ void CNetAPI::ReadVehiclePuresync(CClientPlayer* pPlayer, CClientVehicle* pVehic pPlayer->SetControllerState(ControllerState); + if (BitStream.Can(eBitStreamVersion::SetElementOnFire)) + pVehicle->SetOnFire(BitStream.ReadBit()); + // Remember now as the last puresync time CVector vecPosition; pVehicle->GetPosition(vecPosition); @@ -1766,6 +1769,9 @@ void CNetAPI::WriteVehiclePuresync(CClientPed* pPlayerModel, CClientVehicle* pVe BitStream.WriteBit(ControllerState.RightShoulder2 != 0); } + if (BitStream.Can(eBitStreamVersion::SetElementOnFire)) + BitStream.WriteBit(pVehicle->IsOnFire()); + // Write the sent position to the interpolator AddInterpolation(vecPosition); } diff --git a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp index c17a0d1c2b..87521a812a 100644 --- a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp +++ b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp @@ -2589,6 +2589,9 @@ bool CStaticFunctionDefinitions::SetPedOnFire(CClientEntity& Entity, bool bOnFir { if (IS_PED(&Entity)) { + if (!Entity.IsLocalEntity()) + return false; + CClientPed& Ped = static_cast(Entity); Ped.SetOnFire(bOnFire); return true; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaElementDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaElementDefs.cpp index ff4f9b3abb..daea88e46f 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaElementDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaElementDefs.cpp @@ -71,6 +71,7 @@ void CLuaElementDefs::LoadFunctions() {"isElementLowLOD", IsElementLowLod}, {"isElementCallPropagationEnabled", IsElementCallPropagationEnabled}, {"isElementWaitingForGroundToLoad", IsElementWaitingForGroundToLoad}, + {"isElementOnFire", ArgumentParser}, // Element set funcs {"createElement", CreateElement}, @@ -100,6 +101,7 @@ void CLuaElementDefs::LoadFunctions() {"setLowLODElement", ArgumentParser}, {"setElementCallPropagationEnabled", SetElementCallPropagationEnabled}, {"setElementLighting", ArgumentParser}, + {"setElementOnFire", ArgumentParser}, }; // Add functions @@ -170,6 +172,7 @@ void CLuaElementDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "getAttachedOffsets", "getElementAttachedOffsets"); lua_classfunction(luaVM, "getData", "getElementData"); lua_classfunction(luaVM, "getAllData", "getAllElementData"); + lua_classfunction(luaVM, "isOnFire", "isElementOnFire"); lua_classfunction(luaVM, "setAttachedOffsets", "setElementAttachedOffsets"); lua_classfunction(luaVM, "setData", "setElementData"); @@ -193,6 +196,7 @@ void CLuaElementDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "setCallPropagationEnabled", "setElementCallPropagationEnabled"); lua_classfunction(luaVM, "setStreamable", "setElementStreamable"); lua_classfunction(luaVM, "setLighting", "setElementLighting"); + lua_classfunction(luaVM, "setOnFire", "setElementOnFire"); lua_classvariable(luaVM, "callPropagationEnabled", "setElementCallPropagationEnabled", "isElementCallPropagationEnabled"); lua_classvariable(luaVM, "waitingForGroundToLoad", NULL, "isElementWaitingForGroundToLoad"); @@ -228,6 +232,7 @@ void CLuaElementDefs::AddClass(lua_State* luaVM) lua_classvariable(luaVM, "angularVelocity", SetElementAngularVelocity, OOP_GetElementTurnVelocity); lua_classvariable(luaVM, "isElement", NULL, "isElement"); lua_classvariable(luaVM, "lighting", "setElementLighting", "getElementLighting"); + lua_classvariable(luaVM, "onFire", "setElementOnFire", "isElementOnFire"); // TODO: Support element data: player.data["age"] = 1337; <=> setElementData(player, "age", 1337) lua_registerclass(luaVM, "Element"); @@ -2513,6 +2518,14 @@ bool CLuaElementDefs::SetLowLodElement(lua_State* luaVM, CClientEntity* pEntity, return CStaticFunctionDefinitions::SetLowLodElement(*pEntity, pLowLodEntity.value_or(nullptr)); } +bool CLuaElementDefs::SetElementOnFire(CClientEntity* entity, bool onFire) noexcept +{ + if (!entity->IsLocalEntity()) + return false; + + return entity->SetOnFire(onFire); +} + int CLuaElementDefs::IsElementLowLod(lua_State* luaVM) { // bool isElementLowLOD ( element theElement ) @@ -2646,3 +2659,8 @@ bool CLuaElementDefs::SetElementLighting(CClientEntity* entity, float lighting) return false; } + +bool CLuaElementDefs::IsElementOnFire(CClientEntity* entity) noexcept +{ + return entity->IsOnFire(); +} diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaElementDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaElementDefs.h index 87b8c42f64..3d82ddcb14 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaElementDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaElementDefs.h @@ -71,6 +71,7 @@ class CLuaElementDefs : public CLuaDefs LUA_DECLARE(IsElementLowLod); LUA_DECLARE(IsElementCallPropagationEnabled); LUA_DECLARE(IsElementWaitingForGroundToLoad); + static bool IsElementOnFire(CClientEntity* entity) noexcept; // Element set funcs LUA_DECLARE(CreateElement); @@ -100,4 +101,5 @@ class CLuaElementDefs : public CLuaDefs static bool SetLowLodElement(lua_State* luaVM, CClientEntity* pEntity, std::optional pLowLodEntity); LUA_DECLARE(SetElementCallPropagationEnabled); static bool SetElementLighting(CClientEntity* entity, float lighting); + static bool SetElementOnFire(CClientEntity* entity, bool onFire) noexcept; }; diff --git a/Client/mods/deathmatch/logic/rpc/CElementRPCs.cpp b/Client/mods/deathmatch/logic/rpc/CElementRPCs.cpp index 31fa52cae2..65eca46286 100644 --- a/Client/mods/deathmatch/logic/rpc/CElementRPCs.cpp +++ b/Client/mods/deathmatch/logic/rpc/CElementRPCs.cpp @@ -49,6 +49,7 @@ void CElementRPCs::LoadFunctions() AddHandler(SET_CUSTOM_WEAPON_FLAGS, SetWeaponConfig, "setWeaponFlags"); AddHandler(SET_PROPAGATE_CALLS_ENABLED, SetCallPropagationEnabled, "setCallPropagationEnabled"); AddHandler(SET_COLPOLYGON_HEIGHT, SetColPolygonHeight, "setColShapePolygonHeight"); + AddHandler(SET_ELEMENT_ON_FIRE, SetElementOnFire, "setElementOnFire"); } #define RUN_CHILDREN_SERVER(func) \ @@ -759,3 +760,8 @@ void CElementRPCs::SetColPolygonHeight(CClientEntity* pSource, NetBitStreamInter pColPolygon->SetHeight(fFloor, fCeil); } } + +void CElementRPCs::SetElementOnFire(CClientEntity* pSource, NetBitStreamInterface& bitStream) +{ + pSource->SetOnFire(bitStream.ReadBit()); +} diff --git a/Client/mods/deathmatch/logic/rpc/CElementRPCs.h b/Client/mods/deathmatch/logic/rpc/CElementRPCs.h index 52af6e7a3e..7a0d1f6f5c 100644 --- a/Client/mods/deathmatch/logic/rpc/CElementRPCs.h +++ b/Client/mods/deathmatch/logic/rpc/CElementRPCs.h @@ -50,4 +50,5 @@ class CElementRPCs : public CRPCFunctions DECLARE_ELEMENT_RPC(SetWeaponConfig); DECLARE_ELEMENT_RPC(SetCallPropagationEnabled); DECLARE_ELEMENT_RPC(SetColPolygonHeight); + DECLARE_ELEMENT_RPC(SetElementOnFire); }; diff --git a/Client/sdk/game/CEntity.h b/Client/sdk/game/CEntity.h index 32b803d544..ea21760fa6 100644 --- a/Client/sdk/game/CEntity.h +++ b/Client/sdk/game/CEntity.h @@ -117,4 +117,7 @@ class CEntity virtual bool SetBoneRotationQuat(eBone boneId, float x, float y, float z, float w) = 0; virtual bool GetBonePosition(eBone boneId, CVector& position) = 0; virtual bool SetBonePosition(eBone boneId, const CVector& position) = 0; + + virtual bool IsOnFire() = 0; + virtual bool SetOnFire(bool onFire) = 0; }; diff --git a/Client/sdk/game/CObject.h b/Client/sdk/game/CObject.h index cb04b499c3..1c9c0bff4c 100644 --- a/Client/sdk/game/CObject.h +++ b/Client/sdk/game/CObject.h @@ -41,4 +41,5 @@ class CObject : public virtual CPhysical virtual void SetScale(float fX, float fY, float fZ) = 0; virtual CVector* GetScale() = 0; virtual void ResetScale() = 0; + }; diff --git a/Client/sdk/game/CPed.h b/Client/sdk/game/CPed.h index 22fb276923..fb66f4d56a 100644 --- a/Client/sdk/game/CPed.h +++ b/Client/sdk/game/CPed.h @@ -260,9 +260,6 @@ class CPed : public virtual CPhysical virtual void SetFootBlood(unsigned int uiFootBlood) = 0; virtual unsigned int GetFootBlood() = 0; - virtual bool IsOnFire() = 0; - virtual void SetOnFire(bool bOnFire) = 0; - virtual bool GetStayInSamePlace() = 0; virtual void SetStayInSamePlace(bool bStay) = 0; diff --git a/Client/sdk/game/CVehicle.h b/Client/sdk/game/CVehicle.h index a64755fcfb..4e8a02c4af 100644 --- a/Client/sdk/game/CVehicle.h +++ b/Client/sdk/game/CVehicle.h @@ -327,4 +327,5 @@ class CVehicle : public virtual CPhysical virtual bool SetDummyPosition(eVehicleDummies dummy, const CVector& position) = 0; virtual const CVector* GetDummyPositions() const = 0; + }; diff --git a/Server/mods/deathmatch/logic/CElement.h b/Server/mods/deathmatch/logic/CElement.h index 802981cd5a..a036f2f9d1 100644 --- a/Server/mods/deathmatch/logic/CElement.h +++ b/Server/mods/deathmatch/logic/CElement.h @@ -226,6 +226,9 @@ class CElement bool IsDoubleSided() { return m_bDoubleSided; } void SetDoubleSided(bool bDoubleSided) { m_bDoubleSided = bDoubleSided; } + virtual bool IsOnFire() const noexcept { return false; } + virtual void SetOnFire(bool onFire) noexcept {} + // Spatial database virtual CSphere GetWorldBoundingSphere(); virtual void UpdateSpatialData(); diff --git a/Server/mods/deathmatch/logic/CPed.h b/Server/mods/deathmatch/logic/CPed.h index be3e590096..bf2f4901b7 100644 --- a/Server/mods/deathmatch/logic/CPed.h +++ b/Server/mods/deathmatch/logic/CPed.h @@ -154,8 +154,8 @@ class CPed : public CElement bool IsWearingGoggles() { return m_bWearingGoggles; }; void SetWearingGoggles(bool bWearingGoggles) { m_bWearingGoggles = bWearingGoggles; }; - bool IsOnFire() { return m_bIsOnFire; } - void SetOnFire(bool bOnFire) { m_bIsOnFire = bOnFire; } + bool IsOnFire() const noexcept override { return m_bIsOnFire; } + void SetOnFire(bool bOnFire) noexcept override { m_bIsOnFire = bOnFire; } CWeapon* GetWeapon(unsigned char ucSlot = 0xFF); unsigned char GetWeaponSlot() { return m_ucWeaponSlot; } diff --git a/Server/mods/deathmatch/logic/CPerfStat.RPCPacketUsage.cpp b/Server/mods/deathmatch/logic/CPerfStat.RPCPacketUsage.cpp index fd4bd0b8bc..f188cf4f50 100644 --- a/Server/mods/deathmatch/logic/CPerfStat.RPCPacketUsage.cpp +++ b/Server/mods/deathmatch/logic/CPerfStat.RPCPacketUsage.cpp @@ -231,6 +231,7 @@ ADD_ENUM1(RESPAWN_OBJECT) ADD_ENUM1(TOGGLE_OBJECT_RESPAWN) ADD_ENUM1(RESET_WORLD_PROPERTIES) ADD_ENUM1(SPAWN_VEHICLE_FLYING_COMPONENT) +ADD_ENUM1(SET_ELEMENT_ON_FIRE) IMPLEMENT_ENUM_END("eElementRPCFunctions") DECLARE_ENUM(CRPCFunctions::eRPCFunctions); diff --git a/Server/mods/deathmatch/logic/CResourceChecker.Data.h b/Server/mods/deathmatch/logic/CResourceChecker.Data.h index 630f70fd81..b5ace221e1 100644 --- a/Server/mods/deathmatch/logic/CResourceChecker.Data.h +++ b/Server/mods/deathmatch/logic/CResourceChecker.Data.h @@ -170,7 +170,11 @@ namespace {true, "base64Encode", "Please manually change this to encodeString (different syntax). Refer to the wiki for details"}, {true, "base64Decode", "Please manually change this to decodeString (different syntax). Refer to the wiki for details"}, - {false, "setHelicopterRotorSpeed", "setVehicleRotorSpeed"} + {false, "setHelicopterRotorSpeed", "setVehicleRotorSpeed"}, + {false, "getHelicopterRotorSpeed", "getVehicleRotorSpeed"}, + + {false, "setPedOnFire", "setElementOnFire"}, + {false, "isPedOnFire", "isElementOnFire"} }; SDeprecatedItem serverDeprecatedList[] = { @@ -246,6 +250,7 @@ namespace {false, "getPlayerOccupiedVehicleSeat", "getPedOccupiedVehicleSeat"}, {false, "isPlayerInVehicle", "isPedInVehicle"}, {false, "getPlayerFromNick", "getPlayerFromName"}, + // Client {false, "getClientName", "getPlayerName"}, {false, "getClientIP", "getPlayerIP"}, @@ -272,6 +277,10 @@ namespace // Base Encoding & Decoding {true, "base64Encode", "Please manually change this to encodeString (different syntax). Refer to the wiki for details"}, - {true, "base64Decode", "Please manually change this to decodeString (different syntax). Refer to the wiki for details"} + {true, "base64Decode", "Please manually change this to decodeString (different syntax). Refer to the wiki for details"}, + + // Ped + {false, "setPedOnFire", "setElementOnFire"}, + {false, "isPedOnFire", "isElementOnFire"} }; } // namespace diff --git a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp index c32ce504b6..2aaf1867bd 100644 --- a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp +++ b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp @@ -938,6 +938,23 @@ bool CStaticFunctionDefinitions::SetElementCallPropagationEnabled(CElement* pEle return false; } +bool CStaticFunctionDefinitions::SetElementOnFire(CElement* pElement, bool onFire) +{ + assert(pElement); + + if (!IS_PED(pElement) && !IS_VEHICLE(pElement) && !IS_OBJECT(pElement) && !IS_WEAPON(pElement)) + return false; + + RUN_CHILDREN(SetElementOnFire(*iter, onFire)); + + pElement->SetOnFire(onFire); + + CBitStream bitStream; + bitStream.pBitStream->WriteBit(onFire); + m_pPlayerManager->BroadcastOnlyJoined(CElementRPCPacket(pElement, SET_ELEMENT_ON_FIRE, *bitStream.pBitStream)); + return true; +} + bool CStaticFunctionDefinitions::SetElementID(CElement* pElement, const char* szID) { assert(pElement); diff --git a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h index ffb21fa804..ea178da19b 100644 --- a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h +++ b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h @@ -110,6 +110,7 @@ class CStaticFunctionDefinitions static bool SetElementFrozen(CElement* pElement, bool bFrozen); static bool SetLowLodElement(CElement* pElement, CElement* pLowLodElement); static bool SetElementCallPropagationEnabled(CElement* pElement, bool bEnable); + static bool SetElementOnFire(CElement* pElement, bool onFire); // Player get funcs static unsigned int GetPlayerCount(); diff --git a/Server/mods/deathmatch/logic/CVehicle.cpp b/Server/mods/deathmatch/logic/CVehicle.cpp index ff85b48823..23c388b020 100644 --- a/Server/mods/deathmatch/logic/CVehicle.cpp +++ b/Server/mods/deathmatch/logic/CVehicle.cpp @@ -86,6 +86,7 @@ CVehicle::CVehicle(CVehicleManager* pVehicleManager, CElement* pParent, unsigned m_bHandlingChanged = false; m_ucVariant = ucVariant; m_ucVariant2 = ucVariant2; + m_onFire = false; // Initialize the occupied Players for (int i = 0; i < MAX_VEHICLE_SEATS; i++) diff --git a/Server/mods/deathmatch/logic/CVehicle.h b/Server/mods/deathmatch/logic/CVehicle.h index 0e2ecbd278..01aa83d3b4 100644 --- a/Server/mods/deathmatch/logic/CVehicle.h +++ b/Server/mods/deathmatch/logic/CVehicle.h @@ -397,6 +397,9 @@ class CVehicle final : public CElement void SetBlowState(VehicleBlowState state); VehicleBlowState GetBlowState() const noexcept { return m_blowState; } + bool IsOnFire() const noexcept override { return m_onFire; } + void SetOnFire(bool onFire) noexcept override { m_onFire = onFire; } + void StopIdleTimer(); void RestartIdleTimer(); bool IsIdleTimerRunning(); @@ -491,6 +494,8 @@ class CVehicle final : public CElement unsigned char m_ucVariant; unsigned char m_ucVariant2; + bool m_onFire; + CTickCount m_LastPushedTime; CVector m_vecStationaryCheckPosition; bool m_bNeedsDimensionResync; diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaElementDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaElementDefs.cpp index f8effd7b89..6a5afcad58 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaElementDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaElementDefs.cpp @@ -61,6 +61,7 @@ void CLuaElementDefs::LoadFunctions() {"getElementSyncer", getElementSyncer}, {"getElementCollisionsEnabled", getElementCollisionsEnabled}, {"getLowLODElement", getLowLODElement}, + {"isElementOnFire", ArgumentParser}, // Attachement {"attachElements", attachElements}, @@ -102,6 +103,7 @@ void CLuaElementDefs::LoadFunctions() {"setElementCollisionsEnabled", setElementCollisionsEnabled}, {"setElementFrozen", setElementFrozen}, {"setLowLODElement", setLowLODElement}, + {"setElementOnFire", ArgumentParser}, }; // Add functions @@ -151,6 +153,7 @@ void CLuaElementDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "setLowLOD", "setLowLODElement"); lua_classfunction(luaVM, "setAttachedOffsets", "setElementAttachedOffsets"); lua_classfunction(luaVM, "setCallPropagationEnabled", "setElementCallPropagationEnabled"); + lua_classfunction(luaVM, "setOnFire", "setElementOnFire"); lua_classfunction(luaVM, "getAttachedOffsets", "getElementAttachedOffsets"); lua_classfunction(luaVM, "getChild", "getElementChild"); @@ -189,6 +192,7 @@ void CLuaElementDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "isVisibleTo", "isElementVisibleTo"); lua_classfunction(luaVM, "isLowLOD", "isElementLowLOD"); lua_classfunction(luaVM, "isAttached", "isElementAttached"); + lua_classfunction(luaVM, "isOnFire", "isElementOnFire"); lua_classvariable(luaVM, "id", "setElementID", "getElementID"); lua_classvariable(luaVM, "callPropagationEnabled", "setElementCallPropagationEnabled", "isElementCallPropagationEnabled"); @@ -217,6 +221,7 @@ void CLuaElementDefs::AddClass(lua_State* luaVM) lua_classvariable(luaVM, "velocity", "setElementVelocity", "getElementVelocity", setElementVelocity, OOP_getElementVelocity); lua_classvariable(luaVM, "angularVelocity", "setElementAngularVelocity", "getElementAngularVelocity", setElementTurnVelocity, OOP_getElementTurnVelocity); lua_classvariable(luaVM, "isElement", NULL, "isElement"); + lua_classvariable(luaVM, "onFire", "setElementOnFire", "isElementOnFire"); lua_registerclass(luaVM, "Element"); } @@ -2445,3 +2450,13 @@ int CLuaElementDefs::isElementCallPropagationEnabled(lua_State* luaVM) lua_pushboolean(luaVM, false); return 1; } + +bool CLuaElementDefs::IsElementOnFire(CElement* element) noexcept +{ + return element->IsOnFire(); +} + +bool CLuaElementDefs::SetElementOnFire(CElement* element, bool onFire) noexcept +{ + return CStaticFunctionDefinitions::SetElementOnFire(element, onFire); +} diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaElementDefs.h b/Server/mods/deathmatch/logic/luadefs/CLuaElementDefs.h index b58f613b59..565c1fc5c8 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaElementDefs.h +++ b/Server/mods/deathmatch/logic/luadefs/CLuaElementDefs.h @@ -77,6 +77,7 @@ class CLuaElementDefs : public CLuaDefs LUA_DECLARE(addElementDataSubscriber); LUA_DECLARE(removeElementDataSubscriber); LUA_DECLARE(hasElementDataSubscriber); + static bool IsElementOnFire(CElement* element) noexcept; // Attachement LUA_DECLARE(attachElements); @@ -106,4 +107,5 @@ class CLuaElementDefs : public CLuaDefs LUA_DECLARE(setElementFrozen); LUA_DECLARE(setLowLODElement); LUA_DECLARE(setElementCallPropagationEnabled); + static bool SetElementOnFire(CElement* element, bool onFire) noexcept; }; diff --git a/Server/mods/deathmatch/logic/net/CSimVehiclePuresyncPacket.cpp b/Server/mods/deathmatch/logic/net/CSimVehiclePuresyncPacket.cpp index a89d2d3c3c..dbfb098cf9 100644 --- a/Server/mods/deathmatch/logic/net/CSimVehiclePuresyncPacket.cpp +++ b/Server/mods/deathmatch/logic/net/CSimVehiclePuresyncPacket.cpp @@ -251,6 +251,9 @@ bool CSimVehiclePuresyncPacket::Read(NetBitStreamInterface& BitStream) m_sharedControllerState.RightShoulder2 = BitStream.ReadBit() * 255; } + if (BitStream.Can(eBitStreamVersion::SetElementOnFire)) + m_Cache.isOnFire = BitStream.ReadBit(); + // Success return true; } @@ -418,6 +421,9 @@ bool CSimVehiclePuresyncPacket::Write(NetBitStreamInterface& BitStream) const BitStream.Write(&damage); } + if (BitStream.Can(eBitStreamVersion::SetElementOnFire)) + BitStream.WriteBit(m_Cache.isOnFire); + // Success return true; } diff --git a/Server/mods/deathmatch/logic/net/CSimVehiclePuresyncPacket.h b/Server/mods/deathmatch/logic/net/CSimVehiclePuresyncPacket.h index ead28e54b7..16ebe3eb90 100644 --- a/Server/mods/deathmatch/logic/net/CSimVehiclePuresyncPacket.h +++ b/Server/mods/deathmatch/logic/net/CSimVehiclePuresyncPacket.h @@ -103,5 +103,7 @@ class CSimVehiclePuresyncPacket : public CSimPacket float fRailSpeed; SFixedArray fDoorOpenRatio; + + bool isOnFire{false}; } m_Cache; }; diff --git a/Server/mods/deathmatch/logic/packets/CVehiclePuresyncPacket.cpp b/Server/mods/deathmatch/logic/packets/CVehiclePuresyncPacket.cpp index 67bc9574be..bfab30f952 100644 --- a/Server/mods/deathmatch/logic/packets/CVehiclePuresyncPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CVehiclePuresyncPacket.cpp @@ -451,6 +451,9 @@ bool CVehiclePuresyncPacket::Read(NetBitStreamInterface& BitStream) pSourcePlayer->GetPad()->NewControllerState(ControllerState); + if (BitStream.Can(eBitStreamVersion::SetElementOnFire)) + pVehicle->SetOnFire(BitStream.ReadBit()); + // Success return true; } @@ -676,6 +679,9 @@ bool CVehiclePuresyncPacket::Write(NetBitStreamInterface& BitStream) const BitStream.Write(&damage); } + if (BitStream.Can(eBitStreamVersion::SetElementOnFire)) + BitStream.WriteBit(pVehicle->IsOnFire()); + // Success return true; } diff --git a/Shared/sdk/net/bitstream.h b/Shared/sdk/net/bitstream.h index f422739ad4..5c68ec2c2e 100644 --- a/Shared/sdk/net/bitstream.h +++ b/Shared/sdk/net/bitstream.h @@ -588,6 +588,10 @@ enum class eBitStreamVersion : unsigned short // 2024-11-26 WorldSpecialPropertyEvent, + // Add setElementOnFire function + // 2024-30-12 + SetElementOnFire, + // This allows us to automatically increment the BitStreamVersion when things are added to this enum. // Make sure you only add things above this comment. Next, diff --git a/Shared/sdk/net/rpc_enums.h b/Shared/sdk/net/rpc_enums.h index 08e18eb077..5f41b5bb07 100644 --- a/Shared/sdk/net/rpc_enums.h +++ b/Shared/sdk/net/rpc_enums.h @@ -288,7 +288,10 @@ enum eElementRPCFunctions RESET_WORLD_PROPERTIES, SPAWN_VEHICLE_FLYING_COMPONENT, + SET_VEHICLE_NITRO_ACTIVATED, + + SET_ELEMENT_ON_FIRE, NUM_RPC_FUNCS // Add above this line };