diff --git a/Server/mods/deathmatch/logic/CGame.cpp b/Server/mods/deathmatch/logic/CGame.cpp index 0ed84294df..2b8ea0c8f9 100644 --- a/Server/mods/deathmatch/logic/CGame.cpp +++ b/Server/mods/deathmatch/logic/CGame.cpp @@ -2133,6 +2133,7 @@ void CGame::Packet_PlayerWasted(CPlayerWastedPacket& Packet) pPlayer->SetHealth(0.0f); pPlayer->SetArmor(0.0f); pPlayer->SetPosition(Packet.m_vecPosition); + pPlayer->SetHasJetPack(false); // Reset his vehicle action, but only if not jacking // If jacking we wait for him to reply with VEHICLE_NOTIFY_JACK_ABORT @@ -3363,6 +3364,10 @@ void CGame::Packet_Vehicle_InOut(CVehicleInOutPacket& Packet) // Mark him as successfully entered pPed->SetVehicleAction(CPed::VEHICLEACTION_NONE); + // Remove jetpack from him + if (pPed->IsPlayer() && pPed->HasJetPack()) + pPed->SetHasJetPack(false); + // Update our engine State if (g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::VEHICLE_ENGINE_AUTOSTART)) pVehicle->SetEngineOn(true); diff --git a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp index 2e1065bd89..f6d69918b4 100644 --- a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp +++ b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp @@ -4320,6 +4320,10 @@ bool CStaticFunctionDefinitions::WarpPedIntoVehicle(CPed* pPed, CVehicle* pVehic pPed->SetOccupiedVehicle(pVehicle, uiSeat); pPed->SetVehicleAction(CPed::VEHICLEACTION_NONE); + // Remove jetpack if he has one + if (pPed->IsPlayer() && pPed->HasJetPack()) + pPed->SetHasJetPack(false); + // If he's the driver, switch on the engine if (uiSeat == 0 && g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::VEHICLE_ENGINE_AUTOSTART)) pVehicle->SetEngineOn(true); diff --git a/Server/mods/deathmatch/logic/net/CSimPlayer.h b/Server/mods/deathmatch/logic/net/CSimPlayer.h index 16885e303a..58c851c7d0 100644 --- a/Server/mods/deathmatch/logic/net/CSimPlayer.h +++ b/Server/mods/deathmatch/logic/net/CSimPlayer.h @@ -50,6 +50,7 @@ class CSimPlayer ushort m_usLatency; uchar m_ucSyncTimeContext; uchar m_ucWeaponType; + bool m_hasJetPack; // Used in CSimVehiclePuresyncPacket ushort m_usVehicleModel; diff --git a/Server/mods/deathmatch/logic/net/CSimPlayerManager.cpp b/Server/mods/deathmatch/logic/net/CSimPlayerManager.cpp index e0f1e63113..9b0ea68ca0 100644 --- a/Server/mods/deathmatch/logic/net/CSimPlayerManager.cpp +++ b/Server/mods/deathmatch/logic/net/CSimPlayerManager.cpp @@ -141,6 +141,8 @@ void CSimPlayerManager::UpdateSimPlayer(CPlayer* pPlayer) pSim->m_bVehicleHasHydraulics = pVehicle ? pVehicle->GetUpgrades()->HasUpgrade(1087) : false; pSim->m_bVehicleIsPlaneOrHeli = pVehicle ? pVehicle->GetVehicleType() == VEHICLE_PLANE || pVehicle->GetVehicleType() == VEHICLE_HELI : false; pSim->m_sharedControllerState.Copy(pPlayer->GetPad()->GetCurrentControllerState()); + pSim->m_hasJetPack = pPlayer->HasJetPack(); + if (pVehicle) { pSim->m_uiVehicleDamageInfoSendPhase = pVehicle->m_uiDamageInfoSendPhase; @@ -239,7 +241,7 @@ bool CSimPlayerManager::HandlePlayerPureSync(const NetServerPlayerID& Socket, Ne // Read the incoming packet data CSimPlayerPuresyncPacket* pPacket = new CSimPlayerPuresyncPacket(pSourceSimPlayer->m_PlayerID, pSourceSimPlayer->m_usLatency, pSourceSimPlayer->m_ucSyncTimeContext, - pSourceSimPlayer->m_ucWeaponType, pSourceSimPlayer->m_fWeaponRange, pSourceSimPlayer->m_sharedControllerState); + pSourceSimPlayer->m_ucWeaponType, pSourceSimPlayer->m_fWeaponRange, pSourceSimPlayer->m_sharedControllerState, pSourceSimPlayer->m_hasJetPack); if (pPacket->Read(*BitStream)) { // Relay it to nearbyers diff --git a/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.cpp b/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.cpp index 69f2f5e3e6..d19669df48 100644 --- a/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.cpp +++ b/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.cpp @@ -13,14 +13,15 @@ #include "CWeaponNames.h" CSimPlayerPuresyncPacket::CSimPlayerPuresyncPacket(ElementID PlayerID, ushort PlayerLatency, uchar PlayerSyncTimeContext, uchar PlayerGotWeaponType, - float WeaponRange, CControllerState& sharedControllerState) + float WeaponRange, CControllerState& sharedControllerState, bool hasJetPack) : m_PlayerID(PlayerID), m_PlayerLatency(PlayerLatency), m_PlayerSyncTimeContext(PlayerSyncTimeContext), m_PlayerGotWeaponType(PlayerGotWeaponType), m_WeaponRange(WeaponRange), - m_sharedControllerState(sharedControllerState) + m_sharedControllerState(sharedControllerState), + m_hasJetPack(hasJetPack) { } @@ -179,6 +180,9 @@ bool CSimPlayerPuresyncPacket::Read(NetBitStreamInterface& BitStream) m_Cache.usTotalAmmo = 1; } + // Enforce we use server-side jetpack state + m_Cache.flags.data.bHasJetPack = m_hasJetPack; + // Success return true; } diff --git a/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.h b/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.h index aba98cb757..714b685e96 100644 --- a/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.h +++ b/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.h @@ -34,7 +34,7 @@ class CSimPlayerPuresyncPacket : public CSimPacket ZERO_ON_NEW CSimPlayerPuresyncPacket(ElementID PlayerID, ushort PlayerLatency, uchar PlayerSyncTimeContext, uchar PlayerGotWeaponType, float WeaponRange, - CControllerState& sharedControllerState); + CControllerState& sharedControllerState, bool hasJetPack); ePacketID GetPacketID() const { return PACKET_ID_PLAYER_PURESYNC; }; unsigned long GetFlags() const { return PACKET_MEDIUM_PRIORITY | PACKET_SEQUENCED; }; @@ -56,6 +56,7 @@ class CSimPlayerPuresyncPacket : public CSimPacket const uchar m_PlayerGotWeaponType; const float m_WeaponRange; CControllerState& m_sharedControllerState; + const bool m_hasJetPack; // Set in Read () struct diff --git a/Server/mods/deathmatch/logic/packets/CPlayerPuresyncPacket.cpp b/Server/mods/deathmatch/logic/packets/CPlayerPuresyncPacket.cpp index cd4f96cf74..cbf06446c2 100644 --- a/Server/mods/deathmatch/logic/packets/CPlayerPuresyncPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CPlayerPuresyncPacket.cpp @@ -54,7 +54,6 @@ bool CPlayerPuresyncPacket::Read(NetBitStreamInterface& BitStream) pSourcePlayer->SetInWater(flags.data.bIsInWater); pSourcePlayer->SetOnGround(flags.data.bIsOnGround); - pSourcePlayer->SetHasJetPack(flags.data.bHasJetPack); pSourcePlayer->SetDucked(flags.data.bIsDucked); pSourcePlayer->SetWearingGoggles(flags.data.bWearsGoogles); pSourcePlayer->SetChoking(flags.data.bIsChoking);