diff --git a/Client/mods/deathmatch/logic/CClientVehicle.cpp b/Client/mods/deathmatch/logic/CClientVehicle.cpp index a892924d6e..cba541562f 100644 --- a/Client/mods/deathmatch/logic/CClientVehicle.cpp +++ b/Client/mods/deathmatch/logic/CClientVehicle.cpp @@ -2653,6 +2653,9 @@ void CClientVehicle::Create() m_pVehicle->SetHeliSearchLightVisible(m_bHeliSearchLightVisible); } + if (m_eVehicleType == CLIENTVEHICLE_HELI || m_eVehicleType == CLIENTVEHICLE_PLANE) + m_pVehicle->SetVehicleRotorState(m_rotorState, true, m_eVehicleType == CLIENTVEHICLE_HELI); + m_pVehicle->SetUnderwater(IsBelowWater()); // HACK: temp fix until windows are fixed using setAlpha diff --git a/Client/mods/deathmatch/logic/CNetAPI.cpp b/Client/mods/deathmatch/logic/CNetAPI.cpp index cdd0204f03..ea28659e39 100644 --- a/Client/mods/deathmatch/logic/CNetAPI.cpp +++ b/Client/mods/deathmatch/logic/CNetAPI.cpp @@ -1541,6 +1541,14 @@ void CNetAPI::ReadVehiclePuresync(CClientPlayer* pPlayer, CClientVehicle* pVehic { ControllerState.LeftShoulder2 = BitStream.ReadBit() * 255; ControllerState.RightShoulder2 = BitStream.ReadBit() * 255; + + // Read rotor speed + SFloatSync<2, 14> rotorSpeed; + BitStream.Read(&rotorSpeed); + pVehicle->SetRotorSpeed(rotorSpeed.data.fValue); + + // Read rotor state + pVehicle->SetVehicleRotorState(BitStream.ReadBit(), true); } // Read parts state @@ -1740,6 +1748,14 @@ void CNetAPI::WriteVehiclePuresync(CClientPed* pPlayerModel, CClientVehicle* pVe { BitStream.WriteBit(ControllerState.LeftShoulder2 != 0); BitStream.WriteBit(ControllerState.RightShoulder2 != 0); + + // Write rotor speed + SFloatSync<2, 14> rotorSpeed; + pVehicle->GetRotorSpeed(rotorSpeed.data.fValue); + BitStream.Write(&rotorSpeed); + + // Write rotor state + BitStream.WriteBit(pVehicle->GetVehicleRotorState()); } BitStream.WriteBit(pVehicle->IsOnFire()); diff --git a/Client/mods/deathmatch/logic/CPacketHandler.cpp b/Client/mods/deathmatch/logic/CPacketHandler.cpp index d86e4c1f90..7004c08501 100644 --- a/Client/mods/deathmatch/logic/CPacketHandler.cpp +++ b/Client/mods/deathmatch/logic/CPacketHandler.cpp @@ -3453,6 +3453,13 @@ void CPacketHandler::Packet_EntityAdd(NetBitStreamInterface& bitStream) bool bTrainDirection = bitStream.ReadBit(); bool bTaxiLightState = bitStream.ReadBit(); + // Read rotor state for helicopters and planes + eClientVehicleType vehicleType = pVehicle->GetVehicleType(); + if (vehicleType == CLIENTVEHICLE_HELI || vehicleType == CLIENTVEHICLE_PLANE) + { + pVehicle->SetVehicleRotorState(bitStream.ReadBit(), true); + } + // If the vehicle has a landing gear, set landing gear state if (CClientVehicleManager::HasLandingGears(usModel)) { diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp index 94945f0fbc..9d5ddfe4d4 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp @@ -219,6 +219,7 @@ void CLuaVehicleDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "getPlateText", "getVehiclePlateText"); lua_classfunction(luaVM, "getOccupants", "getVehicleOccupants"); lua_classfunction(luaVM, "getHelicopterRotorSpeed", "getHelicopterRotorSpeed"); + lua_classfunction(luaVM, "getRotorSpeed", "getVehicleRotorSpeed"); lua_classfunction(luaVM, "areHeliBladeCollisionsEnabled", "getHeliBladeCollisionsEnabled"); lua_classfunction(luaVM, "getPaintjob", "getVehiclePaintjob"); lua_classfunction(luaVM, "getTurretPosition", "getVehicleTurretPosition"); @@ -325,6 +326,7 @@ void CLuaVehicleDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "removeUpgrade", "removeVehicleUpgrade"); lua_classfunction(luaVM, "spawnFlyingComponent", "spawnVehicleFlyingComponent"); + lua_classfunction(luaVM, "setRotorSpeed", "setVehicleRotorSpeed"); lua_classvariable(luaVM, "locked", "setVehicleLocked", "isVehicleLocked"); lua_classvariable(luaVM, "controller", NULL, "getVehicleController"); @@ -372,6 +374,7 @@ void CLuaVehicleDefs::AddClass(lua_State* luaVM) lua_classvariable(luaVM, "gravity", SetVehicleGravity, OOP_GetVehicleGravity); lua_classvariable(luaVM, "turnVelocity", SetVehicleTurnVelocity, OOP_GetVehicleTurnVelocity); lua_classvariable(luaVM, "wheelScale", "setVehicleWheelScale", "getVehicleWheelScale"); + lua_classvariable(luaVM, "rotorSpeed", "setVehicleRotorSpeed", "getVehicleRotorSpeed"); lua_classvariable(luaVM, "rotorState", "setVehicleRotorState", "getVehicleRotorState"); lua_classvariable(luaVM, "audioSettings", nullptr, "getVehicleAudioSettings"); diff --git a/Client/mods/deathmatch/logic/rpc/CVehicleRPCs.cpp b/Client/mods/deathmatch/logic/rpc/CVehicleRPCs.cpp index 0d318c7546..b4227fed05 100644 --- a/Client/mods/deathmatch/logic/rpc/CVehicleRPCs.cpp +++ b/Client/mods/deathmatch/logic/rpc/CVehicleRPCs.cpp @@ -24,7 +24,8 @@ void CVehicleRPCs::LoadFunctions() AddHandler(SET_VEHICLE_DOORS_UNDAMAGEABLE, SetVehicleDoorsUndamageable, ""); AddHandler(SET_VEHICLE_SIRENE_ON, SetVehicleSireneOn, "SetVehicleSireneOn"); AddHandler(SET_VEHICLE_LANDING_GEAR_DOWN, SetVehicleLandingGearDown, "SetVehicleLandingGearDown"); - AddHandler(SET_HELICOPTER_ROTOR_SPEED, SetHelicopterRotorSpeed, "SetHelicopterRotorSpeed"); + AddHandler(SET_VEHICLE_ROTOR_SPEED, SetVehicleRotorSpeed, "SetVehicleRotorSpeed"); + AddHandler(SET_VEHICLE_ROTOR_STATE, SetVehicleRotorState, "SetVehicleRotorState"); AddHandler(ADD_VEHICLE_UPGRADE, AddVehicleUpgrade, "AddVehicleUpgrade"); AddHandler(ADD_ALL_VEHICLE_UPGRADES, AddAllVehicleUpgrades, "AddAllVehicleUpgrades"); AddHandler(REMOVE_VEHICLE_UPGRADE, RemoveVehicleUpgrade, "RemoveVehicleUpgrade"); @@ -237,21 +238,6 @@ void CVehicleRPCs::SetVehicleLandingGearDown(CClientEntity* pSource, NetBitStrea } } -void CVehicleRPCs::SetHelicopterRotorSpeed(CClientEntity* pSource, NetBitStreamInterface& bitStream) -{ - CClientVehicle* pVehicle = m_pVehicleManager->Get(pSource->GetID()); - if (pVehicle) - { - unsigned char ucRotorSpeed; - if (bitStream.Read(ucRotorSpeed)) - { - // Convert the given rotor speed from between 0-100 to 0-0.22 - float fRotorSpeed = (static_cast(ucRotorSpeed) / 100.0f * 0.22f); - pVehicle->SetHeliRotorSpeed(fRotorSpeed); - } - } -} - void CVehicleRPCs::AddVehicleUpgrade(CClientEntity* pSource, NetBitStreamInterface& bitStream) { CClientVehicle* pVehicle = m_pVehicleManager->Get(pSource->GetID()); @@ -693,3 +679,27 @@ void CVehicleRPCs::SetVehicleNitroActivated(CClientEntity* pSourceEntity, NetBit vehicle->SetNitroLevel(vehicle->GetNitroLevel() + 1.0001f); } +void CVehicleRPCs::SetVehicleRotorSpeed(CClientEntity* pSource, NetBitStreamInterface& bitStream) +{ + CClientVehicle* pVehicle = m_pVehicleManager->Get(pSource->GetID()); + if (pVehicle) + { + SFloatSync<2, 14> rotorSpeed; + if (bitStream.Read(&rotorSpeed)) + { + pVehicle->SetRotorSpeed(rotorSpeed.data.fValue); + } + } +} + +void CVehicleRPCs::SetVehicleRotorState(CClientEntity* pSource, NetBitStreamInterface& bitStream) +{ + CClientVehicle* pVehicle = m_pVehicleManager->Get(pSource->GetID()); + if (pVehicle) + { + bool rotorState = bitStream.ReadBit(); + bool stopRotor = bitStream.ReadBit(); + + pVehicle->SetVehicleRotorState(rotorState, stopRotor); + } +} diff --git a/Client/mods/deathmatch/logic/rpc/CVehicleRPCs.h b/Client/mods/deathmatch/logic/rpc/CVehicleRPCs.h index c1649abd4b..8f0912c455 100644 --- a/Client/mods/deathmatch/logic/rpc/CVehicleRPCs.h +++ b/Client/mods/deathmatch/logic/rpc/CVehicleRPCs.h @@ -29,7 +29,7 @@ class CVehicleRPCs : public CRPCFunctions DECLARE_ELEMENT_RPC(SetVehicleDoorsUndamageable); DECLARE_ELEMENT_RPC(SetVehicleSireneOn); DECLARE_ELEMENT_RPC(SetVehicleLandingGearDown); - DECLARE_ELEMENT_RPC(SetHelicopterRotorSpeed); + DECLARE_ELEMENT_RPC(SetVehicleRotorSpeed); DECLARE_ELEMENT_RPC(AddVehicleUpgrade); DECLARE_ELEMENT_RPC(AddAllVehicleUpgrades); DECLARE_ELEMENT_RPC(RemoveVehicleUpgrade); @@ -59,4 +59,5 @@ class CVehicleRPCs : public CRPCFunctions DECLARE_ELEMENT_RPC(SetVehiclePlateText); DECLARE_ELEMENT_RPC(SpawnVehicleFlyingComponent); DECLARE_ELEMENT_RPC(SetVehicleNitroActivated); + DECLARE_ELEMENT_RPC(SetVehicleRotorState); }; diff --git a/Server/mods/deathmatch/logic/CPerfStat.RPCPacketUsage.cpp b/Server/mods/deathmatch/logic/CPerfStat.RPCPacketUsage.cpp index cdebcedcc2..45f7e2489c 100644 --- a/Server/mods/deathmatch/logic/CPerfStat.RPCPacketUsage.cpp +++ b/Server/mods/deathmatch/logic/CPerfStat.RPCPacketUsage.cpp @@ -70,7 +70,7 @@ ADD_ENUM1(SET_VEHICLE_LOCKED) ADD_ENUM1(SET_VEHICLE_DOORS_UNDAMAGEABLE) ADD_ENUM1(SET_VEHICLE_SIRENE_ON) ADD_ENUM1(SET_VEHICLE_LANDING_GEAR_DOWN) -ADD_ENUM1(SET_HELICOPTER_ROTOR_SPEED) +ADD_ENUM1(SET_VEHICLE_ROTOR_SPEED) ADD_ENUM1(ADD_VEHICLE_UPGRADE) ADD_ENUM1(ADD_ALL_VEHICLE_UPGRADES) ADD_ENUM1(REMOVE_VEHICLE_UPGRADE) @@ -232,6 +232,7 @@ ADD_ENUM1(TOGGLE_OBJECT_RESPAWN) ADD_ENUM1(RESET_WORLD_PROPERTIES) ADD_ENUM1(SPAWN_VEHICLE_FLYING_COMPONENT) ADD_ENUM1(SET_ELEMENT_ON_FIRE) +ADD_ENUM1(SET_VEHICLE_ROTOR_STATE) IMPLEMENT_ENUM_END("eElementRPCFunctions") DECLARE_ENUM(CRPCFunctions::eRPCFunctions); diff --git a/Server/mods/deathmatch/logic/CVehicle.h b/Server/mods/deathmatch/logic/CVehicle.h index 8c24363d65..3f64833743 100644 --- a/Server/mods/deathmatch/logic/CVehicle.h +++ b/Server/mods/deathmatch/logic/CVehicle.h @@ -264,6 +264,12 @@ class CVehicle final : public CElement bool IsLandingGearDown() { return m_bLandingGearDown; }; void SetLandingGearDown(bool bLandingGearDown) { m_bLandingGearDown = bLandingGearDown; }; + float GetRotorSpeed() const noexcept { return m_rotorSpeed; }; + void SetRotorSpeed(float rotorSpeed) noexcept { m_rotorSpeed = rotorSpeed; }; + + bool GetRotorState() const noexcept { return m_rotorState; }; + void SetRotorState(bool rotorState) noexcept { m_rotorState = rotorState; }; + unsigned short GetAdjustableProperty() { return m_usAdjustableProperty; }; void SetAdjustableProperty(unsigned short usAdjustable) { m_usAdjustableProperty = usAdjustable; }; @@ -485,6 +491,8 @@ class CVehicle final : public CElement bool m_bSirenActive; bool m_bTaxiLightState; bool m_bLandingGearDown; + float m_rotorSpeed{0.0f}; + bool m_rotorState{true}; unsigned short m_usAdjustableProperty; bool m_bCollisionsEnabled; diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp index 13d72615fc..47952f2366 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp @@ -40,6 +40,8 @@ void CLuaVehicleDefs::LoadFunctions() {"getVehicleTurnVelocity", GetVehicleTurnVelocity}, {"getVehicleTurretPosition", GetVehicleTurretPosition}, {"getVehicleMaxPassengers", GetVehicleMaxPassengers}, + {"getVehicleRotorSpeed", ArgumentParser}, + {"getVehicleRotorState", ArgumentParser}, {"isVehicleLocked", IsVehicleLocked}, {"getVehiclesOfType", GetVehiclesOfType}, {"getVehicleUpgradeOnSlot", GetVehicleUpgradeOnSlot}, @@ -77,6 +79,8 @@ void CLuaVehicleDefs::LoadFunctions() {"setVehicleTurnVelocity", SetVehicleTurnVelocity}, {"setVehicleColor", SetVehicleColor}, {"setVehicleLandingGearDown", SetVehicleLandingGearDown}, + {"setVehicleRotorSpeed", ArgumentParser}, + {"setVehicleRotorState", ArgumentParser}, {"setVehicleLocked", SetVehicleLocked}, {"setVehicleDoorsUndamageable", SetVehicleDoorsUndamageable}, {"setVehicleSirensOn", SetVehicleSirensOn}, @@ -161,6 +165,8 @@ void CLuaVehicleDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "toggleRespawn", "toggleVehicleRespawn"); lua_classfunction(luaVM, "removeSirens", "removeVehicleSirens"); lua_classfunction(luaVM, "addSirens", "addVehicleSirens"); + lua_classfunction(luaVM, "getRotorSpeed", "getVehicleRotorSpeed"); + lua_classfunction(luaVM, "getRotorState", "getVehicleRotorState"); lua_classfunction(luaVM, "isDamageProof", "isVehicleDamageProof"); lua_classfunction(luaVM, "isFuelTankExplodable", "isVehicleFuelTankExplodable"); @@ -244,6 +250,8 @@ void CLuaVehicleDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "setTrainPosition", "setTrainPosition"); lua_classfunction(luaVM, "setTrainSpeed", "setTrainSpeed"); // Reduce confusion lua_classfunction(luaVM, "spawnFlyingComponent", "spawnVehicleFlyingComponent"); + lua_classfunction(luaVM, "setRotorSpeed", "setVehicleRotorSpeed"); + lua_classfunction(luaVM, "setRotorState", "setVehicleRotorState"); lua_classvariable(luaVM, "damageProof", "setVehicleDamageProof", "isVehicleDamageProof"); lua_classvariable(luaVM, "locked", "setVehicleLocked", "isVehicleLocked"); @@ -286,6 +294,8 @@ void CLuaVehicleDefs::AddClass(lua_State* luaVM) lua_classvariable(luaVM, "sirens", NULL, "getVehicleSirens"); lua_classvariable(luaVM, "handling", nullptr, "getVehicleHandling"); lua_classvariable(luaVM, "occupant", NULL, "getVehicleOccupant"); + lua_classvariable(luaVM, "rotorSpeed", "setVehicleRotorSpeed", "getVehicleRotorSpeed"); + lua_classvariable(luaVM, "rotorState", "setVehicleRotorState", "getVehicleRotorState"); lua_registerclass(luaVM, "Vehicle", "Element"); } @@ -3059,4 +3069,59 @@ bool CLuaVehicleDefs::SetVehicleNitroActivated(CVehicle* vehicle, bool state) no m_pPlayerManager->BroadcastOnlyJoined(CElementRPCPacket(vehicle, SET_VEHICLE_NITRO_ACTIVATED, *BitStream.pBitStream)); return true; -} \ No newline at end of file +} + +float CLuaVehicleDefs::GetVehicleRotorSpeed(CVehicle* vehicle) +{ + if (!vehicle) + return 0.0f; + + return vehicle->GetRotorSpeed(); +} + +bool CLuaVehicleDefs::SetVehicleRotorSpeed(CVehicle* vehicle, float rotorSpeed) +{ + if (!vehicle) + return false; + + eVehicleType vehicleType = vehicle->GetVehicleType(); + if (vehicleType != VEHICLE_HELI && vehicleType != VEHICLE_PLANE) + return false; + + vehicle->SetRotorSpeed(rotorSpeed); + + CBitStream BitStream; + SFloatSync<2, 14> syncRotorSpeed; + syncRotorSpeed.data.fValue = rotorSpeed; + BitStream.pBitStream->Write(&syncRotorSpeed); + + m_pPlayerManager->BroadcastOnlyJoined(CElementRPCPacket(vehicle, SET_VEHICLE_ROTOR_SPEED, *BitStream.pBitStream)); + + return true; +} + +bool CLuaVehicleDefs::GetVehicleRotorState(CVehicle* vehicle) +{ + if (!vehicle) + return false; + + return vehicle->GetRotorState(); +} + +bool CLuaVehicleDefs::SetVehicleRotorState(CVehicle* vehicle, bool rotorState, std::optional stopRotor) +{ + if (!vehicle) + return false; + + eVehicleType vehicleType = vehicle->GetVehicleType(); + if (vehicleType != VEHICLE_HELI && vehicleType != VEHICLE_PLANE) + return false; + + vehicle->SetRotorState(rotorState); + + CBitStream BitStream; + BitStream.pBitStream->WriteBit(rotorState); + BitStream.pBitStream->WriteBit(stopRotor.value_or(true)); + m_pPlayerManager->BroadcastOnlyJoined(CElementRPCPacket(vehicle, SET_VEHICLE_ROTOR_STATE, *BitStream.pBitStream)); + return true; +} diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.h b/Server/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.h index 38652371c0..baf35f291b 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.h +++ b/Server/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.h @@ -128,4 +128,9 @@ class CLuaVehicleDefs : public CLuaDefs static bool SpawnVehicleFlyingComponent(CVehicle* const vehicle, std::uint8_t nodeIndex, std::optional componentCollisionType, std::optional removalTime); static bool SetVehicleNitroActivated(CVehicle* vehicle, bool state) noexcept; + + static float GetVehicleRotorSpeed(CVehicle* vehicle); + static bool SetVehicleRotorSpeed(CVehicle* vehicle, float rotorSpeed); + static bool GetVehicleRotorState(CVehicle* vehicle); + static bool SetVehicleRotorState(CVehicle* vehicle, bool rotorState, std::optional stopRotor); }; diff --git a/Server/mods/deathmatch/logic/packets/CEntityAddPacket.cpp b/Server/mods/deathmatch/logic/packets/CEntityAddPacket.cpp index f87a776f1e..7a36d19ec8 100644 --- a/Server/mods/deathmatch/logic/packets/CEntityAddPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CEntityAddPacket.cpp @@ -578,6 +578,10 @@ bool CEntityAddPacket::Write(NetBitStreamInterface& BitStream) const BitStream.WriteBit(pVehicle->GetTrainDirection()); BitStream.WriteBit(pVehicle->IsTaxiLightOn()); + // Write rotor state for helicopters and planes + if (pVehicle->GetVehicleType() == VEHICLE_HELI || pVehicle->GetVehicleType() == VEHICLE_PLANE) + BitStream.WriteBit(pVehicle->GetRotorState()); + // Write alpha SEntityAlphaSync alpha; alpha.data.ucAlpha = pVehicle->GetAlpha(); diff --git a/Server/mods/deathmatch/logic/packets/CVehiclePuresyncPacket.cpp b/Server/mods/deathmatch/logic/packets/CVehiclePuresyncPacket.cpp index bfc22904a4..d6e3e41652 100644 --- a/Server/mods/deathmatch/logic/packets/CVehiclePuresyncPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CVehiclePuresyncPacket.cpp @@ -397,6 +397,15 @@ bool CVehiclePuresyncPacket::Read(NetBitStreamInterface& BitStream) { ControllerState.LeftShoulder2 = BitStream.ReadBit() * 255; ControllerState.RightShoulder2 = BitStream.ReadBit() * 255; + + // Read rotor speed + SFloatSync<2, 14> rotorSpeed; + if (!BitStream.Read(&rotorSpeed)) + return false; + pVehicle->SetRotorSpeed(rotorSpeed.data.fValue); + + // Read rotor state + pVehicle->SetRotorState(BitStream.ReadBit()); } pSourcePlayer->GetPad()->NewControllerState(ControllerState); @@ -605,6 +614,14 @@ bool CVehiclePuresyncPacket::Write(NetBitStreamInterface& BitStream) const { BitStream.WriteBit(ControllerState.LeftShoulder2 != 0); BitStream.WriteBit(ControllerState.RightShoulder2 != 0); + + // Write rotor speed + SFloatSync<2, 14> rotorSpeed; + rotorSpeed.data.fValue = pVehicle->GetRotorSpeed(); + BitStream.Write(&rotorSpeed); + + // Write rotor state + BitStream.WriteBit(pVehicle->GetRotorState()); } // Write parts state diff --git a/Shared/sdk/net/rpc_enums.h b/Shared/sdk/net/rpc_enums.h index 84c7518bc4..6407f3d49c 100644 --- a/Shared/sdk/net/rpc_enums.h +++ b/Shared/sdk/net/rpc_enums.h @@ -78,7 +78,7 @@ enum eElementRPCFunctions SET_VEHICLE_DOORS_UNDAMAGEABLE, SET_VEHICLE_SIRENE_ON, SET_VEHICLE_LANDING_GEAR_DOWN, - SET_HELICOPTER_ROTOR_SPEED, + SET_VEHICLE_ROTOR_SPEED, ADD_VEHICLE_UPGRADE, ADD_ALL_VEHICLE_UPGRADES, REMOVE_VEHICLE_UPGRADE, @@ -293,5 +293,7 @@ enum eElementRPCFunctions SET_ELEMENT_ON_FIRE, + SET_VEHICLE_ROTOR_STATE, + NUM_RPC_FUNCS // Add above this line };