The change to recoil applied by "local recoilModifiers" is only noticeable at 0.00 sdjust the loacal and its functions to allow for finer adjustment of component recoil
local horizrecoils = {
[`weapon_mac10`] = 0.33,
[`weapon_ump`] = 0.25,
[`WEAPON_m16`] = 0.15,
[`WEAPON_glock18c`] = 0.35,
[`weapon_gusenberg`] = 0.4,
[`weapon_carbinerifle_mk2`] = 0.7,
[`WEAPON_GLOCKX13`] = 0.35,
[`WEAPON_MAK90`] = 0.17,
[`WEAPON_NSR9`] = 0.15,
[`WEAPON_M4A1`] = 0.15,
}
local vertrecoils = {
[`WEAPON_MAK90`] = 0.36,
[`WEAPON_NSR9`] = 0.35,
[`WEAPON_M4A1`] = 0.35,
[`WEAPON_mp5sd`] = 0.35,
}
-- Define weapon components that reduce recoil
local recoilModifiers = {
[`COMPONENT_M4A1_SUPP`] = 0.85, -- Foregrip: 15% less recoil
[`COMPONENT_SIGMCX_SUPP_01`] = 0.80, -- Muzzle Brake: 20% less recoil
[`COMPONENT_NSR9_SUPP`] = 0.75, -- Heavy Muzzle Brake: 25% less recoil
}
local storedRecoils = {}
-- Function to calculate final recoil modifier (multiplicative stacking)
local function GetRecoilModifier(weapon)
local modifier = 1.0 -- Default: No Reduction
for component, reduction in pairs(recoilModifiers) do
if HasPedGotWeaponComponent(PlayerPedId(), weapon, component) then
modifier = modifier * reduction -- Apply reduction (Multiplicative stacking)
end
end
return modifier
end
CreateThread(function()
local toggle = false
local direction = 1
local shotsFired = 0
local maxShotsBeforeDirectionChange = math.random(1, 5)
while true do
local ped = PlayerPedId()
local isShooting = IsPedShooting(ped)
local isDriveby = IsPedDoingDriveby(ped)
local isFreeAiming = IsPlayerFreeAiming(PlayerId())
local vehicle = GetVehiclePedIsIn(ped, false)
local inVehicle = vehicle ~= 0
-- Increase recoil shake when inside a vehicle
if inVehicle then
local _, weapon = GetCurrentPedWeapon(ped, true)
if not storedRecoils[weapon] then
storedRecoils[weapon] = GetWeaponRecoilShakeAmplitude(weapon)
SetWeaponRecoilShakeAmplitude(weapon, 4.5)
end
else
local _, weapon = GetCurrentPedWeapon(ped, true)
if storedRecoils[weapon] then
SetWeaponRecoilShakeAmplitude(weapon, storedRecoils[weapon])
storedRecoils[weapon] = nil
end
end
-- Handle horizontal recoil
if isShooting and not isDriveby then
local _, weap = GetCurrentPedWeapon(ped, true)
if horizrecoils[weap] and horizrecoils[weap] ~= 0 then
shotsFired = shotsFired + 1
Wait(10)
local currentYaw = GetGameplayCamRelativeHeading()
local attachmentRecoilModifier = GetRecoilModifier(weap) -- Apply component-based reduction
local recoilIntensity = horizrecoils[weap] * (isFreeAiming and 0.5 or 1) * attachmentRecoilModifier
local newYaw = currentYaw + (direction * recoilIntensity)
SetGameplayCamRelativeHeading(newYaw)
if shotsFired >= maxShotsBeforeDirectionChange then
direction = -direction
shotsFired = 0
maxShotsBeforeDirectionChange = math.random(2, 4)
end
end
end
Wait(20)
end
end)
-- Handle vertical recoil
Citizen.CreateThread(function()
while true do
Citizen.Wait(4)
local playerPed = PlayerPedId()
if IsPedShooting(playerPed) and not IsPedDoingDriveby(playerPed) then
local _, wep = GetCurrentPedWeapon(playerPed)
if vertrecoils[wep] and vertrecoils[wep] ~= 0 then
local tv = 0
local recoilMultiplier = 1.0
local aiming = IsPlayerFreeAiming(PlayerId())
if not aiming then
recoilMultiplier = 10.0
end
local vehicle = GetVehiclePedIsIn(playerPed, false)
local inVehicle = vehicle ~= 0
local vehicleRecoilMultiplier = inVehicle and 1.8 or 1.0
local attachmentRecoilModifier = GetRecoilModifier(wep) -- Apply component-based reduction
recoilMultiplier = recoilMultiplier * attachmentRecoilModifier
if GetFollowPedCamViewMode() ~= 4 then
repeat
Wait(1)
local p = GetGameplayCamRelativePitch()
local increment = 0.1 * recoilMultiplier * vehicleRecoilMultiplier
local shake = onXanax and 0.06 or 0.2
SetGameplayCamRelativePitch(p + increment, shake)
tv = tv + increment
until tv >= vertrecoils[wep] * vehicleRecoilMultiplier * attachmentRecoilModifier
end
end
end
end
end)