diff --git a/Server/mods/deathmatch/logic/CGame.cpp b/Server/mods/deathmatch/logic/CGame.cpp index dd40af53e0c..1076cad353f 100644 --- a/Server/mods/deathmatch/logic/CGame.cpp +++ b/Server/mods/deathmatch/logic/CGame.cpp @@ -1549,6 +1549,7 @@ void CGame::AddBuiltInEvents() m_Events.AddEvent("onVehicleEnter", "player, seat, jacked", NULL, false); m_Events.AddEvent("onVehicleExit", "player, seat, jacker", NULL, false); m_Events.AddEvent("onVehicleExplode", "", NULL, false); + m_Events.AddEvent("onElementWaterInteract", "bWaterInOrOut", nullptr, false); // Console events m_Events.AddEvent("onConsole", "text", NULL, false); diff --git a/Server/mods/deathmatch/logic/CObject.h b/Server/mods/deathmatch/logic/CObject.h index ea170408c40..175ac02d839 100644 --- a/Server/mods/deathmatch/logic/CObject.h +++ b/Server/mods/deathmatch/logic/CObject.h @@ -71,6 +71,9 @@ class CObject : public CElement CPlayer* GetSyncer() { return m_pSyncer; } void SetSyncer(CPlayer* pPlayer); + float GetLastSyncedIsInWater() { return m_bLastSyncedIsInWater; }; + void setLastSyncedIsInWater(bool bIsInWater) { m_bLastSyncedIsInWater = bIsInWater; }; + bool IsLowLod(); bool SetLowLodObject(CObject* pLowLodObject); CObject* GetLowLodObject(); @@ -103,4 +106,5 @@ class CObject : public CElement public: CPositionRotationAnimation* m_pMoveAnimation; + bool m_bLastSyncedIsInWater = false; }; diff --git a/Server/mods/deathmatch/logic/CObjectSync.cpp b/Server/mods/deathmatch/logic/CObjectSync.cpp index 75604d85e7d..72a0ce2765c 100644 --- a/Server/mods/deathmatch/logic/CObjectSync.cpp +++ b/Server/mods/deathmatch/logic/CObjectSync.cpp @@ -211,6 +211,15 @@ void CObjectSync::Packet_ObjectSync(CObjectSyncPacket& Packet) if (pData->ucFlags & 0x4) pObject->SetHealth(pData->fHealth); + bool bInWater = pObject->IsInWater(); + if (bInWater != pObject->GetLastSyncedIsInWater()) + { + CLuaArguments Arguments; + Arguments.PushBoolean(bInWater); + pPed->CallEvent("onElementWaterInteract", Arguments); + } + pPed->setLastSyncedIsInWater(bInWater); + // Send this sync pData->bSend = true; } diff --git a/Server/mods/deathmatch/logic/CPed.h b/Server/mods/deathmatch/logic/CPed.h index 0a1e0bbe359..3eb368d0e7b 100644 --- a/Server/mods/deathmatch/logic/CPed.h +++ b/Server/mods/deathmatch/logic/CPed.h @@ -257,6 +257,8 @@ class CPed : public CElement bool IsSyncable() { return m_bSyncable; }; void SetSyncable(bool bSynced) { m_bSyncable = bSynced; }; + float GetLastSyncedIsInWater() { return m_bLastSyncedIsInWater; }; + void setLastSyncedIsInWater(bool bIsInWater) { m_bLastSyncedIsInWater = bIsInWater; }; CPlayer* m_pSyncer; bool IsStealthAiming() { return m_bStealthAiming; } @@ -312,4 +314,5 @@ class CPed : public CElement private: CPedManager* m_pPedManager; + bool m_bLastSyncedIsInWater = false; }; diff --git a/Server/mods/deathmatch/logic/CPedSync.cpp b/Server/mods/deathmatch/logic/CPedSync.cpp index 490a137de44..88e5b495856 100644 --- a/Server/mods/deathmatch/logic/CPedSync.cpp +++ b/Server/mods/deathmatch/logic/CPedSync.cpp @@ -251,6 +251,15 @@ void CPedSync::Packet_PedSync(CPedSyncPacket& Packet) if (pData->ucFlags & 0x40 && pPlayer->GetBitStreamVersion() >= 0x55) pPed->SetInWater(pData->bIsInWater); + bool bInWater = pPed->IsInWater(); + if (bInWater != pPed->GetLastSyncedIsInWater()) + { + CLuaArguments Arguments; + Arguments.PushBoolean(bInWater); + pPed->CallEvent("onElementWaterInteract", Arguments); + } + pPed->setLastSyncedIsInWater(bInWater); + // Send this sync pData->bSend = true; } diff --git a/Server/mods/deathmatch/logic/CUnoccupiedVehicleSync.cpp b/Server/mods/deathmatch/logic/CUnoccupiedVehicleSync.cpp index 7da1c780c8c..5c9558190dd 100644 --- a/Server/mods/deathmatch/logic/CUnoccupiedVehicleSync.cpp +++ b/Server/mods/deathmatch/logic/CUnoccupiedVehicleSync.cpp @@ -417,6 +417,15 @@ void CUnoccupiedVehicleSync::Packet_UnoccupiedVehicleSync(CUnoccupiedVehicleSync bool bDerailed = pVehicle->IsDerailed(); bool bInWater = pVehicle->IsInWater(); + if (bInWater != pVehicle->GetLastSyncedIsInWater()) + { + // Call the event once in water + CLuaArguments Arguments; + Arguments.PushBoolean(bInWater); + pVehicle->CallEvent("onElementWaterInteract", Arguments); + } + pVehicle->setLastSyncedIsInWater(bInWater); + // Turn the engine on if it's on pVehicle->SetEngineOn(vehicle.data.bEngineOn); diff --git a/Server/mods/deathmatch/logic/CVehicle.h b/Server/mods/deathmatch/logic/CVehicle.h index 4d894578922..b36cb0e4269 100644 --- a/Server/mods/deathmatch/logic/CVehicle.h +++ b/Server/mods/deathmatch/logic/CVehicle.h @@ -23,7 +23,6 @@ class CVehicle; #define MAX_VEHICLE_SEATS 9 #define DEFAULT_VEHICLE_HEALTH 1000 #define MAX_VEHICLE_HEALTH 10000 - enum eWheelStatus { DT_WHEEL_INTACT = 0, @@ -188,6 +187,8 @@ class CVehicle : public CElement void SetHealth(float fHealth) { m_fHealth = fHealth; }; float GetLastSyncedHealth() { return m_fLastSyncedHealthHealth; }; void SetLastSyncedHealth(float fHealth) { m_fLastSyncedHealthHealth = fHealth; }; + float GetLastSyncedIsInWater() { return m_bLastSyncedIsInWater; }; + void setLastSyncedIsInWater(bool bIsInWater) { m_bLastSyncedIsInWater = bIsInWater; }; CVehicleColor& RandomizeColor(); @@ -364,6 +365,7 @@ class CVehicle : public CElement CVector m_vecTurnSpeed; float m_fHealth; float m_fLastSyncedHealthHealth; + bool m_bLastSyncedIsInWater = false; CTickCount m_llBlowTime; CTickCount m_llIdleTime; diff --git a/Server/mods/deathmatch/logic/packets/CPlayerPuresyncPacket.cpp b/Server/mods/deathmatch/logic/packets/CPlayerPuresyncPacket.cpp index 04f0912d661..287d5380ded 100644 --- a/Server/mods/deathmatch/logic/packets/CPlayerPuresyncPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CPlayerPuresyncPacket.cpp @@ -263,6 +263,16 @@ bool CPlayerPuresyncPacket::Read(NetBitStreamInterface& BitStream) pSourcePlayer->CallEvent("onPlayerDamage", Arguments); } + bool bInWater = pSourcePlayer->IsInWater(); + if (bInWater != pSourcePlayer->GetLastSyncedIsInWater()) + { + // Call the event once in water + CLuaArguments Arguments; + Arguments.PushBoolean(bInWater); + pSourcePlayer->CallEvent("onElementWaterInteract", Arguments); + } + pSourcePlayer->setLastSyncedIsInWater(bInWater); + // Success return true; } diff --git a/Server/mods/deathmatch/logic/packets/CVehiclePuresyncPacket.cpp b/Server/mods/deathmatch/logic/packets/CVehiclePuresyncPacket.cpp index caf12098440..6d97efdb3e7 100644 --- a/Server/mods/deathmatch/logic/packets/CVehiclePuresyncPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CVehiclePuresyncPacket.cpp @@ -154,6 +154,16 @@ bool CVehiclePuresyncPacket::Read(NetBitStreamInterface& BitStream) // - Caz pVehicle->SetLastSyncedHealth(fHealth); + bool bInWater = pVehicle->IsInWater(); + if (bInWater != pVehicle->GetLastSyncedIsInWater()) + { + // Call the event once in water + CLuaArguments Arguments; + Arguments.PushBoolean(bInWater); + pVehicle->CallEvent("onElementWaterInteract", Arguments); + } + pVehicle->setLastSyncedIsInWater(bInWater); + // Trailer chain CVehicle* pTowedByVehicle = pVehicle; ElementID TrailerID;