1717
1818#include < StdInc.h>
1919int g_iDamageEventLimit = -1 ;
20+ extern float g_fApplyDamageLastAmount;
21+ extern CClientPed* g_pApplyDamageLastDamagedPed;
2022
2123CClientPlayer::CClientPlayer ( CClientManager* pManager, ElementID ID, bool bIsLocalPlayer ) : ClassInit ( this ), CClientPed ( pManager, 0 , ID, bIsLocalPlayer )
2224{
@@ -259,10 +261,13 @@ void CClientPlayer::SetNametagText ( const char * szText )
259261}
260262
261263
262- void CClientPlayer::DischargeWeapon ( eWeaponType weaponType, const CVector& vecStart, const CVector& vecEnd )
264+ void CClientPlayer::DischargeWeapon ( eWeaponType weaponType, const CVector& vecStart, const CVector& vecEnd, float fBackupDamage , uchar ucBackupHitZone, CClientPlayer* pBackupDamagedPlayer )
263265{
264266 if ( m_pPlayerPed )
265267 {
268+ g_pApplyDamageLastDamagedPed = NULL ;
269+ g_fApplyDamageLastAmount = 0 ;
270+
266271 // Check weapon matches and is enabled for bullet sync
267272 if ( weaponType == GetCurrentWeaponType () &&
268273 g_pClientGame->GetWeaponTypeUsesBulletSync ( weaponType ) )
@@ -280,6 +285,40 @@ void CClientPlayer::DischargeWeapon ( eWeaponType weaponType, const CVector& vec
280285
281286 m_shotSyncData->m_bRemoteBulletSyncVectorsValid = false ;
282287 }
288+
289+ // Apply extra damage if player has bad network
290+ if ( pBackupDamagedPlayer && pBackupDamagedPlayer->GetGamePlayer () && pBackupDamagedPlayer->GetWasRecentlyInNetworkInterruption ( 1000 ) )
291+ {
292+ // Subtract any damage that did get applied during FireBullet
293+ if ( pBackupDamagedPlayer == g_pApplyDamageLastDamagedPed )
294+ fBackupDamage -= g_fApplyDamageLastAmount;
295+
296+ if ( fBackupDamage > 0 )
297+ {
298+ // Apply left over damage like what the game would:
299+ // CClientPlayer has pre damage health/armor
300+ // CPlayerPed has post damage health/armor
301+
302+ float fPreviousHealth = pBackupDamagedPlayer->m_fHealth ;
303+ float fPreviousArmor = pBackupDamagedPlayer->m_fArmor ;
304+
305+ // Calculate how much damage should be applied to health/armor
306+ float fArmorDamage = Min ( fBackupDamage , pBackupDamagedPlayer->m_fArmor );
307+ float fHealthDamage = Min ( fBackupDamage - fArmorDamage , pBackupDamagedPlayer->m_fHealth );
308+
309+ float fNewArmor = pBackupDamagedPlayer->m_fArmor - fArmorDamage ;
310+ float fNewHealth = pBackupDamagedPlayer->m_fHealth - fHealthDamage ;
311+
312+ // Ensure CPlayerPed has post damage health/armor
313+ pBackupDamagedPlayer->GetGamePlayer ()->SetHealth ( fNewHealth );
314+ pBackupDamagedPlayer->GetGamePlayer ()->SetArmor ( fNewArmor );
315+
316+ g_pClientGame->ApplyPedDamageFromGame ( weaponType, fBackupDamage , ucBackupHitZone, pBackupDamagedPlayer, this , NULL );
317+
318+ SString strMessage ( " Applied %0.2f damage to %s (from %s) due to network interruption" , fBackupDamage , pBackupDamagedPlayer->GetNick (), GetNick () );
319+ g_pClientGame->TellServerSomethingImportant ( 1010 , strMessage, false );
320+ }
321+ }
283322 }
284323}
285324
@@ -299,3 +338,17 @@ uint CClientPlayer::GetRemoteBuildNumber ( void )
299338{
300339 return m_uiRemoteBuildNumber;
301340}
341+
342+ bool CClientPlayer::GetWasRecentlyInNetworkInterruption ( uint uiMaxTicksAgo )
343+ {
344+ if ( m_bInNetworkInterruption )
345+ return true ;
346+ return m_TimeSinceNetworkInterruptionEnded.Get () < uiMaxTicksAgo;
347+ }
348+
349+ void CClientPlayer::SetIsInNetworkInterruption ( bool bBegan )
350+ {
351+ m_bInNetworkInterruption = bBegan;
352+ if ( !bBegan )
353+ m_TimeSinceNetworkInterruptionEnded.Reset ();
354+ }
0 commit comments