diff --git a/Client/game_sa/CPedSA.cpp b/Client/game_sa/CPedSA.cpp index cb9798600e..5da8c9f947 100644 --- a/Client/game_sa/CPedSA.cpp +++ b/Client/game_sa/CPedSA.cpp @@ -1027,6 +1027,18 @@ int CPedSA::GetCustomMoveAnim() return m_iCustomMoveAnim; } +bool CPedSA::IsDoingGangDriveby() +{ + auto pTaskManager = m_pPedIntelligence->GetTaskManager(); + CTask* pTask = pTaskManager->GetTask(TASK_PRIORITY_PRIMARY); + if (pTask && pTask->GetTaskType() == TASK_SIMPLE_GANG_DRIVEBY) + { + return true; + } + + return false; +} + /* bool CPedSA::CanPedReturnToState ( ) { diff --git a/Client/game_sa/CPedSA.h b/Client/game_sa/CPedSA.h index f119f5ca75..d78dde230b 100644 --- a/Client/game_sa/CPedSA.h +++ b/Client/game_sa/CPedSA.h @@ -447,6 +447,7 @@ class CPedSA : public virtual CPed, public virtual CPhysicalSA void AddWeaponAudioEvent(EPedWeaponAudioEventType audioEventType); virtual int GetCustomMoveAnim(); + bool IsDoingGangDriveby(); static void StaticSetHooks(); }; diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index 109d96e49b..d54c9fc1d3 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -3053,7 +3053,7 @@ void CClientGame::DrawPlayerDetails(CClientPlayer* pPlayer) pPlayer->GetAim(fAimX, fAimY); const CVector& vecAimSource = pPlayer->GetAimSource(); const CVector& vecAimTarget = pPlayer->GetAimTarget(); - unsigned char ucDrivebyAim = pPlayer->GetVehicleAimAnim(); + eVehicleAimDirection ucDrivebyAim = pPlayer->GetVehicleAimAnim(); g_pCore->GetGraphics()->DrawLine3DQueued(vecAimSource, vecAimTarget, 1.0f, 0x10DE1212, true); g_pCore->GetGraphics()->DrawLine3DQueued(vecAimSource, vecAimTarget, 1.0f, 0x90DE1212, false); @@ -3222,7 +3222,7 @@ void CClientGame::UpdateMimics() m_pLocalPlayer->GetShotData(&vecOrigin, &vecTarget); float fAimX = pShotSync->m_fArmDirectionX; float fAimY = pShotSync->m_fArmDirectionY; - char cVehicleAimDirection = pShotSync->m_cInVehicleAimDirection; + eVehicleAimDirection cVehicleAimDirection = pShotSync->m_cInVehicleAimDirection; bool bAkimboUp = g_pMultiplayer->GetAkimboTargetUp(); /* diff --git a/Client/mods/deathmatch/logic/CClientPed.cpp b/Client/mods/deathmatch/logic/CClientPed.cpp index 838599ac65..6b53f77e1d 100644 --- a/Client/mods/deathmatch/logic/CClientPed.cpp +++ b/Client/mods/deathmatch/logic/CClientPed.cpp @@ -2556,7 +2556,7 @@ CVector CClientPed::GetAim() const return CVector(); } -void CClientPed::SetAim(float fArmDirectionX, float fArmDirectionY, unsigned char cInVehicleAimAnim) +void CClientPed::SetAim(float fArmDirectionX, float fArmDirectionY, eVehicleAimDirection cInVehicleAimAnim) { if (!m_bIsLocalPlayer) { @@ -2568,7 +2568,7 @@ void CClientPed::SetAim(float fArmDirectionX, float fArmDirectionY, unsigned cha } } -void CClientPed::SetAimInterpolated(unsigned long ulDelay, float fArmDirectionX, float fArmDirectionY, bool bAkimboAimUp, unsigned char cInVehicleAimAnim) +void CClientPed::SetAimInterpolated(unsigned long ulDelay, float fArmDirectionX, float fArmDirectionY, bool bAkimboAimUp, eVehicleAimDirection cInVehicleAimAnim) { if (!m_bIsLocalPlayer) { @@ -2587,7 +2587,7 @@ void CClientPed::SetAimInterpolated(unsigned long ulDelay, float fArmDirectionX, } } -void CClientPed::SetAimingData(unsigned long ulDelay, const CVector& vecTargetPosition, float fArmDirectionX, float fArmDirectionY, char cInVehicleAimAnim, +void CClientPed::SetAimingData(unsigned long ulDelay, const CVector& vecTargetPosition, float fArmDirectionX, float fArmDirectionY, eVehicleAimDirection cInVehicleAimAnim, CVector* pSource, bool bInterpolateAim) { if (!m_bIsLocalPlayer) diff --git a/Client/mods/deathmatch/logic/CClientPed.h b/Client/mods/deathmatch/logic/CClientPed.h index 595c862558..4218d80224 100644 --- a/Client/mods/deathmatch/logic/CClientPed.h +++ b/Client/mods/deathmatch/logic/CClientPed.h @@ -321,10 +321,10 @@ class CClientPed : public CClientStreamElement, public CAntiCheatModule CVector GetAim() const; const CVector& GetAimSource() { return m_shotSyncData->m_vecShotOrigin; }; const CVector& GetAimTarget() { return m_shotSyncData->m_vecShotTarget; }; - unsigned char GetVehicleAimAnim() { return m_shotSyncData->m_cInVehicleAimDirection; }; - void SetAim(float fArmDirectionX, float fArmDirectionY, unsigned char cInVehicleAimAnim); - void SetAimInterpolated(unsigned long ulDelay, float fArmDirectionX, float fArmDirectionY, bool bAkimboAimUp, unsigned char cInVehicleAimAnim); - void SetAimingData(unsigned long ulDelay, const CVector& vecTargetPosition, float fArmDirectionX, float fArmDirectionY, char cInVehicleAimAnim, + eVehicleAimDirection GetVehicleAimAnim() { return m_shotSyncData->m_cInVehicleAimDirection; }; + void SetAim(float fArmDirectionX, float fArmDirectionY, eVehicleAimDirection cInVehicleAimAnim); + void SetAimInterpolated(unsigned long ulDelay, float fArmDirectionX, float fArmDirectionY, bool bAkimboAimUp, eVehicleAimDirection cInVehicleAimAnim); + void SetAimingData(unsigned long ulDelay, const CVector& vecTargetPosition, float fArmDirectionX, float fArmDirectionY, eVehicleAimDirection cInVehicleAimAnim, CVector* pSource, bool bInterpolateAim); unsigned long GetMemoryValue(unsigned long ulOffset) { return (m_pPlayerPed) ? *m_pPlayerPed->GetMemoryValue(ulOffset) : 0; }; diff --git a/Client/mods/deathmatch/logic/CNetAPI.cpp b/Client/mods/deathmatch/logic/CNetAPI.cpp index 6da6b12a6f..1bfb78db5e 100644 --- a/Client/mods/deathmatch/logic/CNetAPI.cpp +++ b/Client/mods/deathmatch/logic/CNetAPI.cpp @@ -625,8 +625,8 @@ void CNetAPI::ReadKeysync(CClientPlayer* pPlayer, NetBitStreamInterface& BitStre BitStream.Read(&aim); // Read out the driveby direction - unsigned char ucDriveByAim; - BitStream.Read(ucDriveByAim); + eVehicleAimDirection ucDriveByAim; + BitStream.Read(*reinterpret_cast(&ucDriveByAim)); // Set the aim data (immediately if in vehicle, otherwize delayed/interpolated) if (pVehicle) @@ -763,7 +763,7 @@ void CNetAPI::WriteKeysync(CClientPed* pPlayerModel, NetBitStreamInterface& BitS // Write the driveby direction CShotSyncData* pShotsyncData = g_pMultiplayer->GetLocalShotSyncData(); - BitStream.Write(pShotsyncData->m_cInVehicleAimDirection); + BitStream.Write(static_cast(pShotsyncData->m_cInVehicleAimDirection)); } } else @@ -928,7 +928,7 @@ void CNetAPI::ReadPlayerPuresync(CClientPlayer* pPlayer, NetBitStreamInterface& BitStream.Read(&aim); // Interpolate the aiming - pPlayer->SetAimInterpolated(TICK_RATE_AIM, rotation.data.fRotation, aim.data.fArm, flags.data.bAkimboTargetUp, 0); + pPlayer->SetAimInterpolated(TICK_RATE_AIM, rotation.data.fRotation, aim.data.fArm, flags.data.bAkimboTargetUp, eVehicleAimDirection::FORWARDS); // Read the aim data only if he's shooting or aiming if (aim.isFull()) @@ -1484,9 +1484,10 @@ void CNetAPI::ReadVehiclePuresync(CClientPlayer* pPlayer, CClientVehicle* pVehic // Read out the driveby direction SDrivebyDirectionSync driveby; BitStream.Read(&driveby); + eVehicleAimDirection ucDirection = static_cast(driveby.data.ucDirection); // Set the aiming - pPlayer->SetAimingData(TICK_RATE, aim.data.vecTarget, aim.data.fArm, 0.0f, driveby.data.ucDirection, &aim.data.vecOrigin, false); + pPlayer->SetAimingData(TICK_RATE, aim.data.vecTarget, aim.data.fArm, 0.0f, ucDirection, &aim.data.vecOrigin, false); } else { @@ -1727,7 +1728,7 @@ void CNetAPI::WriteVehiclePuresync(CClientPed* pPlayerModel, CClientVehicle* pVe // Sync driveby direction CShotSyncData* pShotsyncData = g_pMultiplayer->GetLocalShotSyncData(); SDrivebyDirectionSync driveby; - driveby.data.ucDirection = static_cast(pShotsyncData->m_cInVehicleAimDirection); + driveby.data.ucDirection = pShotsyncData->m_cInVehicleAimDirection; BitStream.Write(&driveby); } } diff --git a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp index b6b1fa1b6c..b5f56406e0 100644 --- a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp +++ b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp @@ -2415,8 +2415,7 @@ bool CStaticFunctionDefinitions::SetPedAimTarget(CClientEntity& Entity, CVector& if (Ped.IsInVehicle()) { // Driveby aim animation - // 0 = forwards, 1 = left, 2 = back, 3 = right - unsigned char cInVehicleAimAnim = 0; + eVehicleAimDirection cInVehicleAimAnim = eVehicleAimDirection::FORWARDS; // Ped rotation CVector vecRot; @@ -2439,21 +2438,21 @@ bool CStaticFunctionDefinitions::SetPedAimTarget(CClientEntity& Entity, CVector& if (fRotDiff > PI * 0.25 && fRotDiff < PI * 0.75) { // Facing left - cInVehicleAimAnim = 1; + cInVehicleAimAnim = eVehicleAimDirection::LEFT; fArmX = fArmX - PI / 2; fArmY = -fArmY; } else if (fRotDiff > PI * 0.75 || fRotDiff < -PI * 0.75) { // Facing backwards - cInVehicleAimAnim = 2; + cInVehicleAimAnim = eVehicleAimDirection::BACKWARDS; fArmX = fArmX + PI; fArmY = -fArmY; } else if (fRotDiff < -PI * 0.25 && fRotDiff > -PI * 0.75) { // Facing right - cInVehicleAimAnim = 3; + cInVehicleAimAnim = eVehicleAimDirection::RIGHT; fArmX = fArmX + PI / 2; } else @@ -2468,7 +2467,7 @@ bool CStaticFunctionDefinitions::SetPedAimTarget(CClientEntity& Entity, CVector& else { Ped.SetTargetTarget(TICK_RATE, vecOrigin, vecTarget); - Ped.SetAim(fArmX, fArmY, 0); + Ped.SetAim(fArmX, fArmY, eVehicleAimDirection::FORWARDS); } return true; diff --git a/Client/multiplayer_sa/multiplayer_shotsync.cpp b/Client/multiplayer_sa/multiplayer_shotsync.cpp index e0a483828d..8596775a53 100644 --- a/Client/multiplayer_sa/multiplayer_shotsync.cpp +++ b/Client/multiplayer_sa/multiplayer_shotsync.cpp @@ -15,6 +15,7 @@ #include "../game_sa/CPedSA.h" #include "../game_sa/CEventDamageSA.h" #include "../game_sa/CColPointSA.h" +#include extern CMultiplayerSA* pMultiplayer; @@ -49,7 +50,7 @@ CVector vecLastOrigin; CVector vecLastLocalPlayerBulletStart; CVector vecLastLocalPlayerBulletEnd; -char cTempGunDirection; +eVehicleAimDirection cTempGunDirection; DWORD vecTargetPosition; DWORD vecAltPos; @@ -138,9 +139,15 @@ bool IsLocalPlayer(CPedSAInterface* pPedInterface) return false; } -VOID WriteGunDirectionDataForPed(CPedSAInterface* pPedInterface, float* fGunDirectionX, float* fGunDirectionY, char* cGunDirection) +VOID WriteGunDirectionDataForPed(CPedSAInterface* pPedInterface, float* fGunDirectionX, float* fGunDirectionY, eVehicleAimDirection* cGunDirection) { - if (!IsLocalPlayer(pPedInterface)) + SClientEntity* pPedClientEntity = m_pools->GetPed((DWORD*)pPedInterface); + CPed* pAimingPed = pPedClientEntity ? pPedClientEntity->pEntity : nullptr; + + if (!pAimingPed) + return; + + if (!IsLocalPlayer(pAimingPed)) { CRemoteDataStorageSA* data = CRemoteDataSA::GetRemoteDataStorage(pPedInterface); if (data) @@ -168,6 +175,18 @@ VOID WriteGunDirectionDataForPed(CPedSAInterface* pPedInterface, float* fGunDire // Make sure our pitch is updated (fixes first-person weapons not moving) *fGunDirectionY = pGameInterface->GetCamera()->Find3rdPersonQuickAimPitch(); + if (pAimingPed->IsDoingGangDriveby()) + { + // Fix pitch in driveby when facing left or backwards + switch (LocalShotSyncData.m_cInVehicleAimDirection) + { + case eVehicleAimDirection::LEFT: + case eVehicleAimDirection::BACKWARDS: + *fGunDirectionY = -*fGunDirectionY; + break; + } + } + LocalShotSyncData.m_fArmDirectionX = *fGunDirectionX; LocalShotSyncData.m_fArmDirectionY = *fGunDirectionY; } diff --git a/Client/multiplayer_sa/multiplayer_shotsync.h b/Client/multiplayer_sa/multiplayer_shotsync.h index 235b8dd377..b92a9e5652 100644 --- a/Client/multiplayer_sa/multiplayer_shotsync.h +++ b/Client/multiplayer_sa/multiplayer_shotsync.h @@ -43,7 +43,7 @@ // our stuff VOID InitShotsyncHooks(); CShotSyncData* GetLocalPedShotSyncData(); -VOID WriteGunDirectionDataForPed(class CPedSAInterface* pPedInterface, float* fGunDirectionX, float* fGunDirectionY, char* cGunDirection); +VOID WriteGunDirectionDataForPed(class CPedSAInterface* pPedInterface, float* fGunDirectionX, float* fGunDirectionY, eVehicleAimDirection* cGunDirection); bool IsLocalPlayer(CPedSAInterface* pPedInterface); // hooks diff --git a/Client/sdk/game/CPed.h b/Client/sdk/game/CPed.h index 8c97899c26..f750d9aad5 100644 --- a/Client/sdk/game/CPed.h +++ b/Client/sdk/game/CPed.h @@ -269,4 +269,5 @@ class CPed : public virtual CPhysical virtual void AddWeaponAudioEvent(EPedWeaponAudioEventType audioEventType) = 0; virtual int GetCustomMoveAnim() = 0; + virtual bool IsDoingGangDriveby() = 0; }; diff --git a/Client/sdk/multiplayer/CMultiplayer.h b/Client/sdk/multiplayer/CMultiplayer.h index 0e1cebcbdd..fc2b1da346 100644 --- a/Client/sdk/multiplayer/CMultiplayer.h +++ b/Client/sdk/multiplayer/CMultiplayer.h @@ -123,6 +123,8 @@ typedef void(PedStepHandler)(CPedSAInterface* pPed, bool bFoot); using VehicleWeaponHitHandler = void(SVehicleWeaponHitEvent& event); +enum class eVehicleAimDirection : unsigned char; + /** * This class contains information used for shot syncing, one exists per player. */ @@ -135,7 +137,7 @@ class CShotSyncData float m_fArmDirectionX; float m_fArmDirectionY; // only for in-vehicle shooting - char m_cInVehicleAimDirection; // 0 = forwards, 1 = left, 2 = back, 3 = right + eVehicleAimDirection m_cInVehicleAimDirection; // use origin bool m_bUseOrigin; diff --git a/Server/mods/deathmatch/logic/CPlayer.cpp b/Server/mods/deathmatch/logic/CPlayer.cpp index e27f899e14..5facce4f92 100644 --- a/Server/mods/deathmatch/logic/CPlayer.cpp +++ b/Server/mods/deathmatch/logic/CPlayer.cpp @@ -39,7 +39,7 @@ CPlayer::CPlayer(CPlayerManager* pPlayerManager, class CScriptDebugging* pScript m_fRotation = 0.0f; m_fAimDirection = 0.0f; - m_ucDriveByDirection = 0; + m_ucDriveByDirection = eVehicleAimDirection::FORWARDS; m_bAkimboArmUp = false; m_VoiceState = VOICESTATE_IDLE; diff --git a/Server/mods/deathmatch/logic/CPlayer.h b/Server/mods/deathmatch/logic/CPlayer.h index d46d725fcf..878325bb0e 100644 --- a/Server/mods/deathmatch/logic/CPlayer.h +++ b/Server/mods/deathmatch/logic/CPlayer.h @@ -25,6 +25,7 @@ class CPlayer; #include "packets/CPlayerStatsPacket.h" class CKeyBinds; class CPlayerCamera; +enum class eVehicleAimDirection : unsigned char; enum eVoiceState { @@ -121,8 +122,8 @@ class CPlayer : public CPed, public CClient void SetTargettingVector(const CVector& vecTarget) { m_vecTargetting = vecTarget; }; float GetAimDirection() { return m_fAimDirection; }; void SetAimDirection(float fDirection) { m_fAimDirection = fDirection; }; - unsigned char GetDriveByDirection() { return m_ucDriveByDirection; }; - void SetDriveByDirection(unsigned char ucDirection) { m_ucDriveByDirection = ucDirection; }; + eVehicleAimDirection GetDriveByDirection() { return m_ucDriveByDirection; }; + void SetDriveByDirection(eVehicleAimDirection ucDirection) { m_ucDriveByDirection = ucDirection; }; bool IsAkimboArmUp() { return m_bAkimboArmUp; }; void SetAkimboArmUp(bool bUp) { m_bAkimboArmUp = bUp; }; @@ -372,7 +373,7 @@ class CPlayer : public CPed, public CClient CVector m_vecSniperSource; CVector m_vecTargetting; float m_fAimDirection; - unsigned char m_ucDriveByDirection; + eVehicleAimDirection m_ucDriveByDirection; bool m_bAkimboArmUp; diff --git a/Server/mods/deathmatch/logic/net/CSimVehiclePuresyncPacket.h b/Server/mods/deathmatch/logic/net/CSimVehiclePuresyncPacket.h index 2c0249ebf8..485225bdf2 100644 --- a/Server/mods/deathmatch/logic/net/CSimVehiclePuresyncPacket.h +++ b/Server/mods/deathmatch/logic/net/CSimVehiclePuresyncPacket.h @@ -14,6 +14,8 @@ struct STrailerInfo CVector m_TrailerRotationDeg; }; +enum class eVehicleAimDirection : unsigned char; + class CSimVehiclePuresyncPacket : public CSimPacket { public: @@ -85,7 +87,7 @@ class CSimVehiclePuresyncPacket : public CSimPacket CVector vecSniperSource; CVector vecTargetting; - uchar ucDriveByDirection; + eVehicleAimDirection ucDriveByDirection; float fTurretX; float fTurretY; diff --git a/Server/mods/deathmatch/logic/packets/CKeysyncPacket.cpp b/Server/mods/deathmatch/logic/packets/CKeysyncPacket.cpp index ca4bcdb862..ec311b96b8 100644 --- a/Server/mods/deathmatch/logic/packets/CKeysyncPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CKeysyncPacket.cpp @@ -108,8 +108,8 @@ bool CKeysyncPacket::Read(NetBitStreamInterface& BitStream) } // Read out the driveby direction - unsigned char ucDriveByDirection; - if (!BitStream.Read(ucDriveByDirection)) + eVehicleAimDirection ucDriveByDirection; + if (!BitStream.Read(*reinterpret_cast*>(&ucDriveByDirection))) return false; pSourcePlayer->SetDriveByDirection(ucDriveByDirection); } @@ -216,7 +216,7 @@ bool CKeysyncPacket::Write(NetBitStreamInterface& BitStream) const BitStream.Write(&aim); // Write the driveby aim directoin - BitStream.Write(pSourcePlayer->GetDriveByDirection()); + BitStream.Write(static_cast>(pSourcePlayer->GetDriveByDirection())); } else { diff --git a/Shared/sdk/net/SyncStructures.h b/Shared/sdk/net/SyncStructures.h index 2afb5e566e..9981531eda 100644 --- a/Shared/sdk/net/SyncStructures.h +++ b/Shared/sdk/net/SyncStructures.h @@ -678,6 +678,15 @@ struct SVehiclePuresyncFlags : public ISyncStructure } data; }; + +enum class eVehicleAimDirection : unsigned char +{ + FORWARDS = 0, + LEFT, + BACKWARDS, + RIGHT, +}; + struct SDrivebyDirectionSync : public ISyncStructure { enum @@ -690,7 +699,7 @@ struct SDrivebyDirectionSync : public ISyncStructure struct { - unsigned char ucDirection : 2; + eVehicleAimDirection ucDirection : 2; } data; };