From 435b8fe52e7564bfcf6ff32d36b0625316cbf12f Mon Sep 17 00:00:00 2001
From: erorcun <erorcunerorcun@hotmail.com.tr>
Date: Sat, 14 Aug 2021 22:11:33 +0300
Subject: Fix impossible bullets

---
 src/weapons/Weapon.cpp | 71 ++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 60 insertions(+), 11 deletions(-)

(limited to 'src/weapons/Weapon.cpp')

diff --git a/src/weapons/Weapon.cpp b/src/weapons/Weapon.cpp
index c0319a11..2d219e2d 100644
--- a/src/weapons/Weapon.cpp
+++ b/src/weapons/Weapon.cpp
@@ -49,6 +49,29 @@ bool CWeapon::bPhotographHasBeenTaken;
 int32 sniperPirateCheck = 0x00797743; // 'Cwy\0' ???
 #endif
 
+#ifdef FREE_CAM
+static bool
+Find3rdPersonCamTargetVectorFromCachedVectors(float dist, CVector pos, CVector& source, CVector& target, CVector camSource, CVector camFront, CVector camUp)
+{
+	if (CPad::GetPad(0)->GetLookBehindForPed()) {
+		source = pos;
+		target = dist * FindPlayerPed()->GetForward() + source;
+		return false;
+	} else {
+		float angleX = DEGTORAD((CCamera::m_f3rdPersonCHairMultX - 0.5f) * 1.8f * 0.5f * TheCamera.Cams[TheCamera.ActiveCam].FOV * CDraw::GetAspectRatio());
+		float angleY = DEGTORAD((0.5f - CCamera::m_f3rdPersonCHairMultY) * 1.8f * 0.5f * TheCamera.Cams[TheCamera.ActiveCam].FOV);
+		source = camSource;
+		target = camFront;
+		target += camUp * Tan(angleY);
+		target += CrossProduct(camFront, camUp) * Tan(angleX);
+		target.Normalise();
+		source += DotProduct(pos - source, target) * target;
+		target = dist * target + source;
+		return true;
+	}
+}
+#endif
+
 CWeaponInfo *
 CWeapon::GetInfo()
 {
@@ -943,17 +966,23 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
 	}
 	else if ( shooter == FindPlayerPed() && TheCamera.Cams[0].Using3rdPersonMouseCam()  )
 	{
-		TheCamera.Find3rdPersonCamTargetVector(info->m_fRange, *fireSource, source, target);
 #ifdef FREE_CAM
-		CPed *shooterPed = (CPed *)shooter;
-		if((shooterPed->m_pedIK.m_flags & CPedIK::GUN_POINTED_SUCCESSFULLY) == 0) {
-			target.x = info->m_fRange;
-			target.y = 0.0f;
-			target.z = 0.0f;
+		if (CCamera::bFreeCam) {
+			CPlayerPed* shooterPed = (CPlayerPed*)shooter;
+			Find3rdPersonCamTargetVectorFromCachedVectors(info->m_fRange, *fireSource, source, target, shooterPed->m_cachedCamSource, shooterPed->m_cachedCamFront, shooterPed->m_cachedCamUp);
 
-			shooterPed->TransformToNode(target, PED_HANDR);
-		}
+			if ((shooterPed->m_pedIK.m_flags & CPedIK::GUN_POINTED_SUCCESSFULLY) == 0) {
+				target.x = info->m_fRange;
+				target.y = 0.0f;
+				target.z = 0.0f;
+
+				shooterPed->TransformToNode(target, PED_HANDR);
+			}
+		} else
 #endif
+		{
+			TheCamera.Find3rdPersonCamTargetVector(info->m_fRange, *fireSource, source, target);
+		}
 
 #ifdef FIX_BUGS
 		// fix muzzleflash rotation
@@ -1708,8 +1737,19 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
 
 		if ( shooter == FindPlayerPed() && TheCamera.Cams[0].Using3rdPersonMouseCam() )
 		{
-			TheCamera.Find3rdPersonCamTargetVector(1.0f, *fireSource, source, target);
-			CVector Left = CrossProduct(TheCamera.Cams[TheCamera.ActiveCam].Front, TheCamera.Cams[TheCamera.ActiveCam].Up);
+			CVector Left;
+#ifdef FREE_CAM
+			if (CCamera::bFreeCam) {
+				CPlayerPed* shooterPed = (CPlayerPed*)shooter;
+				Find3rdPersonCamTargetVectorFromCachedVectors(1.0f, *fireSource, source, target, shooterPed->m_cachedCamSource, shooterPed->m_cachedCamFront, shooterPed->m_cachedCamUp);
+				Left = CrossProduct(shooterPed->m_cachedCamFront, shooterPed->m_cachedCamUp);
+			}
+			else
+#endif
+			{
+				TheCamera.Find3rdPersonCamTargetVector(1.0f, *fireSource, source, target);
+				Left = CrossProduct(TheCamera.Cams[TheCamera.ActiveCam].Front, TheCamera.Cams[TheCamera.ActiveCam].Up);
+			}
 
 			float f = (i - (shootsAtOnce / 2)) * angleBetweenTwoShot;
 			target  = f * Left + target - source;
@@ -2151,7 +2191,16 @@ CWeapon::FireAreaEffect(CEntity *shooter, CVector *fireSource)
 
 	if ( shooter == FindPlayerPed() && TheCamera.Cams[0].Using3rdPersonMouseCam() )
 	{
-		TheCamera.Find3rdPersonCamTargetVector(info->m_fRange, *fireSource, source, target);
+#ifdef FREE_CAM
+		if (CCamera::bFreeCam) {
+			CPlayerPed* shooterPed = (CPlayerPed*)shooter;
+			Find3rdPersonCamTargetVectorFromCachedVectors(info->m_fRange, *fireSource, source, target, shooterPed->m_cachedCamSource, shooterPed->m_cachedCamFront, shooterPed->m_cachedCamUp);
+		}
+		else
+#endif
+		{
+			TheCamera.Find3rdPersonCamTargetVector(info->m_fRange, *fireSource, source, target);
+		}
 		float norm = (1.0f / info->m_fRange);
 		dir = (target - source) * norm;
 	}
-- 
cgit v1.2.3