local QBCore = exports['qb-core']:GetCoreObject() local pedInSameVehicleLast=false local vehicle local lastVehicle local vehicleClass local fCollisionDamageMult = 0.0 local fDeformationDamageMult = 0.0 local fEngineDamageMult = 0.0 local fBrakeForce = 1.0 local isBrakingForward = false local isBrakingReverse = false local healthEngineLast = 1000.0 local healthEngineCurrent = 1000.0 local healthEngineNew = 1000.0 local healthEngineDelta = 0.0 local healthEngineDeltaScaled = 0.0 local healthBodyLast = 1000.0 local healthBodyCurrent = 1000.0 local healthBodyNew = 1000.0 local healthBodyDelta = 0.0 local healthBodyDeltaScaled = 0.0 local healthPetrolTankLast = 1000.0 local healthPetrolTankCurrent = 1000.0 local healthPetrolTankNew = 1000.0 local healthPetrolTankDelta = 0.0 local healthPetrolTankDeltaScaled = 0.0 local tireBurstLuckyNumber local fixMessagePos = math.random(repairCfg.fixMessageCount) local noFixMessagePos = math.random(repairCfg.noFixMessageCount) local tireBurstMaxNumber = cfg.randomTireBurstInterval * 1200; if cfg.randomTireBurstInterval ~= 0 then tireBurstLuckyNumber = math.random(tireBurstMaxNumber) end local DamageComponents = { "radiator", "axle", "clutch", "fuel", "brakes", } -- Functions -- local function DamageRandomComponent() -- local dmgFctr = math.random() + math.random(0, 2) -- local randomComponent = DamageComponents[math.random(1, #DamageComponents)] -- local randomDamage = (math.random() + math.random(0, 1)) * dmgFctr -- exports['qb-mechanicjob']:SetVehicleStatus(QBCore.Functions.GetPlate(vehicle), randomComponent, exports['qb-mechanicjob']:GetVehicleStatus(QBCore.Functions.GetPlate(vehicle), randomComponent) - randomDamage) -- end local function CleanVehicle(veh) local ped = PlayerPedId() TaskStartScenarioInPlace(ped, "WORLD_HUMAN_MAID_CLEAN", 0, true) QBCore.Functions.Progressbar("cleaning_vehicle", Lang:t("progress.clean_veh"), math.random(10000, 20000), false, true, { disableMovement = true, disableCarMovement = true, disableMouse = false, disableCombat = true, }, {}, {}, {}, function() -- Done QBCore.Functions.Notify(Lang:t("success.cleaned_veh")) SetVehicleDirtLevel(veh, 0.1) SetVehicleUndriveable(veh, false) WashDecalsFromVehicle(veh, 1.0) TriggerServerEvent('qb-vehiclefailure:server:removewashingkit', veh) TriggerEvent('inventory:client:ItemBox', QBCore.Shared.Items["cleaningkit"], "remove") ClearAllPedProps(ped) ClearPedTasks(ped) end, function() -- Cancel QBCore.Functions.Notify(Lang:t("error.failed_notification"), "error") ClearAllPedProps(ped) ClearPedTasks(ped) end) end local function IsBackEngine(vehModel) if BackEngineVehicles[vehModel] then return true else return false end end local function RepairVehicleFull(veh) if (IsBackEngine(GetEntityModel(veh))) then SetVehicleDoorOpen(veh, 5, false, false) else SetVehicleDoorOpen(veh, 4, false, false) end QBCore.Functions.Progressbar("repair_vehicle", Lang:t("progress.repair_veh"), math.random(20000, 30000), false, true, { disableMovement = true, disableCarMovement = true, disableMouse = false, disableCombat = true, }, { animDict = "mini@repair", anim = "fixing_a_player", flags = 1, }, {}, {}, function() -- Done StopAnimTask(PlayerPedId(), "mini@repair", "fixing_a_player", 1.0) QBCore.Functions.Notify(Lang:t("success.repaired_veh")) SetVehicleEngineHealth(veh, 1000.0) SetVehicleEngineOn(veh, true, false) for i = 0, 5 do SetVehicleTyreFixed(veh, i) TriggerEvent('qb-vehiclefailure:client:TyreSync', veh, i) end if (IsBackEngine(GetEntityModel(veh))) then SetVehicleDoorShut(veh, 5, false) else SetVehicleDoorShut(veh, 4, false) end TriggerServerEvent('qb-vehiclefailure:removeItem', "advancedrepairkit") end, function() -- Cancel StopAnimTask(PlayerPedId(), "mini@repair", "fixing_a_player", 1.0) QBCore.Functions.Notify(Lang:t("error.failed_notification"), "error") if (IsBackEngine(GetEntityModel(veh))) then SetVehicleDoorShut(veh, 5, false) else SetVehicleDoorShut(veh, 4, false) end end) end local function RepairVehicle(veh) if (IsBackEngine(GetEntityModel(veh))) then SetVehicleDoorOpen(veh, 5, false, false) else SetVehicleDoorOpen(veh, 4, false, false) end QBCore.Functions.Progressbar("repair_vehicle", Lang:t("progress.repair_veh"), math.random(10000, 20000), false, true, { disableMovement = true, disableCarMovement = true, disableMouse = false, disableCombat = true, }, { animDict = "mini@repair", anim = "fixing_a_player", flags = 1, }, {}, {}, function() -- Done StopAnimTask(PlayerPedId(), "mini@repair", "fixing_a_player", 1.0) QBCore.Functions.Notify(Lang:t("success.repaired_veh")) SetVehicleEngineHealth(veh, 500.0) SetVehicleEngineOn(veh, true, false) for i = 0, 5 do SetVehicleTyreFixed(veh, i) TriggerEvent('qb-vehiclefailure:client:TyreSync', veh, i) end if (IsBackEngine(GetEntityModel(veh))) then SetVehicleDoorShut(veh, 5, false) else SetVehicleDoorShut(veh, 4, false) end TriggerServerEvent('qb-vehiclefailure:removeItem', "repairkit") end, function() -- Cancel StopAnimTask(PlayerPedId(), "mini@repair", "fixing_a_player", 1.0) QBCore.Functions.Notify(Lang:t("error.failed_notification"), "error") if (IsBackEngine(GetEntityModel(veh))) then SetVehicleDoorShut(veh, 5, false) else SetVehicleDoorShut(veh, 4, false) end end) end local function isPedDrivingAVehicle() local ped = PlayerPedId() vehicle = GetVehiclePedIsIn(ped, false) if IsPedInAnyVehicle(ped, false) then -- Check if ped is in driver seat if GetPedInVehicleSeat(vehicle, -1) == ped then local class = GetVehicleClass(vehicle) -- We don't want planes, helicopters, bicycles and trains if class ~= 15 and class ~= 16 and class ~=21 and class ~=13 then return true end end end return false end local function IsNearMechanic() local ped = PlayerPedId() local pedLocation = GetEntityCoords(ped, 0) for _, item in pairs(repairCfg.mechanics) do local distance = #(vector3(item.x, item.y, item.z) - pedLocation) if distance <= item.r then return true end end end local function fscale(inputValue, originalMin, originalMax, newBegin, newEnd, curve) local OriginalRange local NewRange local zeroRefCurVal local normalizedCurVal local rangedValue local invFlag = 0 if (curve > 10.0) then curve = 10.0 end if (curve < -10.0) then curve = -10.0 end curve = (curve * -.1) curve = 10.0 ^ curve if (inputValue < originalMin) then inputValue = originalMin end if inputValue > originalMax then inputValue = originalMax end OriginalRange = originalMax - originalMin if (newEnd > newBegin) then NewRange = newEnd - newBegin else NewRange = newBegin - newEnd invFlag = 1 end zeroRefCurVal = inputValue - originalMin normalizedCurVal = zeroRefCurVal / OriginalRange if (originalMin > originalMax ) then return 0 end if (invFlag == 0) then rangedValue = ((normalizedCurVal ^ curve) * NewRange) + newBegin else rangedValue = newBegin - ((normalizedCurVal ^ curve) * NewRange) end return rangedValue end local function tireBurstLottery() local tireBurstNumber = math.random(tireBurstMaxNumber) if tireBurstNumber == tireBurstLuckyNumber then -- We won the lottery, lets burst a tire. if GetVehicleTyresCanBurst(vehicle) == false then return end local numWheels = GetVehicleNumberOfWheels(vehicle) local affectedTire if numWheels == 2 then affectedTire = (math.random(2) - 1) * 4 -- wheel 0 or 4 elseif numWheels == 4 then affectedTire = (math.random(4) - 1) if affectedTire > 1 then affectedTire = affectedTire + 2 end -- 0, 1, 4, 5 elseif numWheels == 6 then affectedTire = (math.random(6) - 1) else affectedTire = 0 end SetVehicleTyreBurst(vehicle, affectedTire, false, 1000.0) tireBurstLuckyNumber = math.random(tireBurstMaxNumber) -- Select a new number to hit, just in case some numbers occur more often than others end end -- Events RegisterNetEvent('qb-vehiclefailure:client:RepairVehicle', function() local veh = QBCore.Functions.GetClosestVehicle() local engineHealth = GetVehicleEngineHealth(veh) --This is to prevent people from "repairing" a vehicle and setting engine health lower than what the vehicles engine health was before repairing. if veh ~= nil and veh ~= 0 and engineHealth < 500 then local ped = PlayerPedId() local pos = GetEntityCoords(ped) local vehpos = GetEntityCoords(veh) if #(pos - vehpos) < 5.0 and not IsPedInAnyVehicle(ped) then local drawpos = GetOffsetFromEntityInWorldCoords(veh, 0, 2.5, 0) if (IsBackEngine(GetEntityModel(veh))) then drawpos = GetOffsetFromEntityInWorldCoords(veh, 0, -2.5, 0) end if #(pos - drawpos) < 2.0 and not IsPedInAnyVehicle(ped) then RepairVehicle(veh) end else if #(pos - vehpos) > 4.9 then QBCore.Functions.Notify(Lang:t("error.out_range_veh"), "error") else QBCore.Functions.Notify(Lang:t("error.inside_veh"), "error") end end else if veh == nil or veh == 0 then QBCore.Functions.Notify(Lang:t("error.not_near_veh"), "error") else QBCore.Functions.Notify(Lang:t("error.healthy_veh"), "error") end end end) RegisterNetEvent('qb-vehiclefailure:client:SyncWash', function(veh) SetVehicleDirtLevel(veh, 0.1) SetVehicleUndriveable(veh, false) WashDecalsFromVehicle(veh, 1.0) end) RegisterNetEvent('qb-vehiclefailure:client:CleanVehicle', function() local veh = QBCore.Functions.GetClosestVehicle() if veh ~= nil and veh ~= 0 then local ped = PlayerPedId() local pos = GetEntityCoords(ped) local vehpos = GetEntityCoords(veh) if #(pos - vehpos) < 3.0 and not IsPedInAnyVehicle(ped) then CleanVehicle(veh) end end end) RegisterNetEvent('qb-vehiclefailure:client:TyreSync', function(veh, tyre) SetVehicleTyreFixed(veh, tyre) SetVehicleWheelHealth(veh, tyre, 100) end) RegisterNetEvent('qb-vehiclefailure:client:RepairVehicleFull', function() local veh = QBCore.Functions.GetClosestVehicle() if veh ~= nil and veh ~= 0 then local ped = PlayerPedId() local pos = GetEntityCoords(ped) local vehpos = GetEntityCoords(veh) if #(pos - vehpos) < 5.0 and not IsPedInAnyVehicle(ped) then local drawpos = GetOffsetFromEntityInWorldCoords(veh, 0, 2.5, 0) if (IsBackEngine(GetEntityModel(veh))) then drawpos = GetOffsetFromEntityInWorldCoords(veh, 0, -2.5, 0) end if #(pos - drawpos) < 2.0 and not IsPedInAnyVehicle(ped) then RepairVehicleFull(veh) end else if #(pos - vehpos) > 4.9 then QBCore.Functions.Notify(Lang:t("error.out_range_veh"), "error") else QBCore.Functions.Notify(Lang:t("error.inside_veh"), "error") end end else QBCore.Functions.Notify(Lang:t("error.not_near_veh"), "error") end end) RegisterNetEvent('iens:repaira', function() local ped = PlayerPedId() if IsPedInAnyVehicle(ped, false) or IsPedInAnyPlane(ped) then vehicle = GetVehiclePedIsIn(ped, false) SetVehicleDirtLevel(vehicle) SetVehicleUndriveable(vehicle, false) WashDecalsFromVehicle(vehicle, 1.0) QBCore.Functions.Notify(Lang:t("success.repaired_veh")) SetVehicleFixed(vehicle) healthBodyLast = 1000.0 healthEngineLast = 1000.0 healthPetrolTankLast = 1000.0 SetVehicleEngineOn(vehicle, true, false ) return true end QBCore.Functions.Notify(Lang:t("error.inside_veh_req")) end) RegisterNetEvent('iens:besked', function() QBCore.Functions.Notify(Lang:t("error.roadside_avail")) end) RegisterNetEvent('iens:notAllowed', function() QBCore.Functions.Notify(Lang:t("error.no_permission")) end) RegisterNetEvent('iens:repair', function() if isPedDrivingAVehicle() then local ped = PlayerPedId() vehicle = GetVehiclePedIsIn(ped, false) if IsNearMechanic() then return end if GetVehicleEngineHealth(vehicle) < cfg.cascadingFailureThreshold + 5 then if GetVehicleOilLevel(vehicle) > 0 then SetVehicleUndriveable(vehicle, false) SetVehicleEngineHealth(vehicle, cfg.cascadingFailureThreshold + 5) SetVehiclePetrolTankHealth(vehicle, 750.0) healthEngineLast=cfg.cascadingFailureThreshold +5 healthPetrolTankLast=750.0 SetVehicleEngineOn(vehicle, true, false ) SetVehicleOilLevel(vehicle,(GetVehicleOilLevel(vehicle)/3)-0.5) QBCore.Functions.Notify(Lang:t(('fix_message_%s'):format(fixMessagePos))) fixMessagePos = fixMessagePos + 1 if fixMessagePos > repairCfg.fixMessageCount then fixMessagePos = 1 end else QBCore.Functions.Notify(Lang:t("error.veh_damaged")) end else QBCore.Functions.Notify(Lang:t(('nofix_message_%s'):format(noFixMessagePos))) noFixMessagePos = noFixMessagePos + 1 if noFixMessagePos > repairCfg.noFixMessageCount then noFixMessagePos = 1 end end else QBCore.Functions.Notify(Lang:t("error.inside_veh_req")) end end) -- Threads CreateThread(function() if (cfg.displayBlips == true) then for _, item in pairs(repairCfg.mechanics) do item.blip = AddBlipForCoord(item.x, item.y, item.z) SetBlipSprite(item.blip, item.id) SetBlipScale(item.blip, 0.8) SetBlipAsShortRange(item.blip, true) BeginTextCommandSetBlipName("STRING") AddTextComponentString(item.name) EndTextCommandSetBlipName(item.blip) end end end) if cfg.torqueMultiplierEnabled or cfg.preventVehicleFlip or cfg.limpMode then CreateThread(function() while true do Wait(0) if cfg.torqueMultiplierEnabled or cfg.sundayDriver or cfg.limpMode then if pedInSameVehicleLast then local factor = 1.0 if cfg.torqueMultiplierEnabled and healthEngineNew < 900 then factor = (healthEngineNew+200.0) / 1100 end if cfg.sundayDriver and GetVehicleClass(vehicle) ~= 14 then -- Not for boats local accelerator = GetControlValue(2,71) local brake = GetControlValue(2,72) local speed = GetEntitySpeedVector(vehicle, true)['y'] -- Change Braking force local brk = fBrakeForce if speed >= 1.0 then -- Going forward if accelerator > 127 then -- Forward and accelerating local acc = fscale(accelerator, 127.0, 254.0, 0.1, 1.0, 10.0-(cfg.sundayDriverAcceleratorCurve*2.0)) factor = factor * acc end if brake > 127 then -- Forward and braking isBrakingForward = true brk = fscale(brake, 127.0, 254.0, 0.01, fBrakeForce, 10.0-(cfg.sundayDriverBrakeCurve*2.0)) --exports['qb-vehicletuning']:SetVehicleStatus(QBCore.Functions.GetPlate(vehicle), "brakes", exports['qb-vehicletuning']:GetVehicleStatus(QBCore.Functions.GetPlate(vehicle), "brakes") - 0.01) end elseif speed <= -1.0 then -- Going reverse if brake > 127 then -- Reversing and accelerating (using the brake) local rev = fscale(brake, 127.0, 254.0, 0.1, 1.0, 10.0-(cfg.sundayDriverAcceleratorCurve*2.0)) factor = factor * rev --exports['qb-vehicletuning']:SetVehicleStatus(QBCore.Functions.GetPlate(vehicle), "brakes", exports['qb-vehicletuning']:GetVehicleStatus(QBCore.Functions.GetPlate(vehicle), "brakes") - 0.01) end if accelerator > 127 then -- Reversing and braking (Using the accelerator) isBrakingReverse = true brk = fscale(accelerator, 127.0, 254.0, 0.01, fBrakeForce, 10.0 - (cfg.sundayDriverBrakeCurve * 2.0)) end else -- Stopped or almost stopped or sliding sideways local entitySpeed = GetEntitySpeed(vehicle) if entitySpeed < 1 then -- Not sliding sideways if isBrakingForward == true then --Stopped or going slightly forward while braking DisableControlAction(2, 72, true) -- Disable Brake until user lets go of brake SetVehicleForwardSpeed(vehicle, speed * 0.98) SetVehicleBrakeLights(vehicle, true) end if isBrakingReverse == true then --Stopped or going slightly in reverse while braking DisableControlAction(2, 71, true) -- Disable reverse Brake until user lets go of reverse brake (Accelerator) SetVehicleForwardSpeed(vehicle,speed*0.98) SetVehicleBrakeLights(vehicle,true) end if isBrakingForward == true and GetDisabledControlNormal(2, 72) == 0 then -- We let go of the brake isBrakingForward = false end if isBrakingReverse == true and GetDisabledControlNormal(2, 71) == 0 then -- We let go of the reverse brake (Accelerator) isBrakingReverse = false end end end if brk > fBrakeForce - 0.02 then brk = fBrakeForce end -- Make sure we can brake max. SetVehicleHandlingFloat(vehicle, 'CHandlingData', 'fBrakeForce', brk) -- Set new Brake Force multiplier end if cfg.limpMode == true and healthEngineNew < cfg.engineSafeGuard + 5 then factor = cfg.limpModeMultiplier end SetVehicleEngineTorqueMultiplier(vehicle, factor) end end if cfg.preventVehicleFlip then local roll = GetEntityRoll(vehicle) if (roll > 75.0 or roll < -75.0) and GetEntitySpeed(vehicle) < 2 then DisableControlAction(2, 59, true) -- Disable left/right DisableControlAction(2, 60, true) -- Disable up/down end end end end) end CreateThread(function() while true do Wait(50) local ped = PlayerPedId() if isPedDrivingAVehicle() then vehicle = GetVehiclePedIsIn(ped, false) vehicleClass = GetVehicleClass(vehicle) healthEngineCurrent = GetVehicleEngineHealth(vehicle) if healthEngineCurrent == 1000 then healthEngineLast = 1000.0 end healthEngineNew = healthEngineCurrent healthEngineDelta = healthEngineLast - healthEngineCurrent healthEngineDeltaScaled = healthEngineDelta * cfg.damageFactorEngine * cfg.classDamageMultiplier[vehicleClass] healthBodyCurrent = GetVehicleBodyHealth(vehicle) if healthBodyCurrent == 1000 then healthBodyLast = 1000.0 end healthBodyNew = healthBodyCurrent healthBodyDelta = healthBodyLast - healthBodyCurrent healthBodyDeltaScaled = healthBodyDelta * cfg.damageFactorBody * cfg.classDamageMultiplier[vehicleClass] healthPetrolTankCurrent = GetVehiclePetrolTankHealth(vehicle) if cfg.compatibilityMode and healthPetrolTankCurrent < 1 then -- SetVehiclePetrolTankHealth(vehicle, healthPetrolTankLast) -- healthPetrolTankCurrent = healthPetrolTankLast healthPetrolTankLast = healthPetrolTankCurrent end if healthPetrolTankCurrent == 1000 then healthPetrolTankLast = 1000.0 end healthPetrolTankNew = healthPetrolTankCurrent healthPetrolTankDelta = healthPetrolTankLast-healthPetrolTankCurrent healthPetrolTankDeltaScaled = healthPetrolTankDelta * cfg.damageFactorPetrolTank * cfg.classDamageMultiplier[vehicleClass] if healthEngineCurrent > cfg.engineSafeGuard+1 then SetVehicleUndriveable(vehicle,false) end if healthEngineCurrent <= cfg.engineSafeGuard+1 and cfg.limpMode == false then local vehpos = GetEntityCoords(vehicle) StartParticleFxLoopedAtCoord("ent_ray_heli_aprtmnt_l_fire", vehpos.x, vehpos.y, vehpos.z-0.7, 0.0, 0.0, 0.0, 1.0, false, false, false, false) SetVehicleUndriveable(vehicle,true) end -- If ped spawned a new vehicle while in a vehicle or teleported from one vehicle to another, handle as if we just entered the car if vehicle ~= lastVehicle then pedInSameVehicleLast = false end if pedInSameVehicleLast == true then -- Damage happened while in the car = can be multiplied -- Only do calculations if any damage is present on the car. Prevents weird behavior when fixing using trainer or other script if healthEngineCurrent ~= 1000.0 or healthBodyCurrent ~= 1000.0 or healthPetrolTankCurrent ~= 1000.0 then -- Combine the delta values (Get the largest of the three) local healthEngineCombinedDelta = math.max(healthEngineDeltaScaled, healthBodyDeltaScaled, healthPetrolTankDeltaScaled) -- If huge damage, scale back a bit if healthEngineCombinedDelta > (healthEngineCurrent - cfg.engineSafeGuard) then healthEngineCombinedDelta = healthEngineCombinedDelta * 0.7 end -- If complete damage, but not catastrophic (ie. explosion territory) pull back a bit, to give a couple of seconds og engine runtime before dying if healthEngineCombinedDelta > healthEngineCurrent then healthEngineCombinedDelta = healthEngineCurrent - (cfg.cascadingFailureThreshold / 5) end ------- Calculate new value healthEngineNew = healthEngineLast - healthEngineCombinedDelta ------- Sanity Check on new values and further manipulations -- If somewhat damaged, slowly degrade until slightly before cascading failure sets in, then stop if healthEngineNew > (cfg.cascadingFailureThreshold + 5) and healthEngineNew < cfg.degradingFailureThreshold then healthEngineNew = healthEngineNew-(0.038 * cfg.degradingHealthSpeedFactor) end -- If Damage is near catastrophic, cascade the failure if healthEngineNew < cfg.cascadingFailureThreshold then healthEngineNew = healthEngineNew-(0.1 * cfg.cascadingFailureSpeedFactor) end -- Prevent Engine going to or below zero. Ensures you can reenter a damaged car. if healthEngineNew < cfg.engineSafeGuard then healthEngineNew = cfg.engineSafeGuard end -- Prevent Explosions if cfg.compatibilityMode == false and healthPetrolTankCurrent < 750 then healthPetrolTankNew = 750.0 end -- Prevent negative body damage. if healthBodyNew < 0 then healthBodyNew = 0.0 end end else -- Just got in the vehicle. Damage can not be multiplied this round -- Set vehicle handling data fDeformationDamageMult = GetVehicleHandlingFloat(vehicle, 'CHandlingData', 'fDeformationDamageMult') fBrakeForce = GetVehicleHandlingFloat(vehicle, 'CHandlingData', 'fBrakeForce') local newFDeformationDamageMult = fDeformationDamageMult ^ cfg.deformationExponent -- Pull the handling file value closer to 1 if cfg.deformationMultiplier ~= -1 then SetVehicleHandlingFloat(vehicle, 'CHandlingData', 'fDeformationDamageMult', newFDeformationDamageMult * cfg.deformationMultiplier) end -- Multiply by our factor if cfg.weaponsDamageMultiplier ~= -1 then SetVehicleHandlingFloat(vehicle, 'CHandlingData', 'fWeaponDamageMult', cfg.weaponsDamageMultiplier/cfg.damageFactorBody) end -- Set weaponsDamageMultiplier and compensate for damageFactorBody --Get the CollisionDamageMultiplier fCollisionDamageMult = GetVehicleHandlingFloat(vehicle, 'CHandlingData', 'fCollisionDamageMult') --Modify it by pulling all number a towards 1.0 local newFCollisionDamageMultiplier = fCollisionDamageMult ^ cfg.collisionDamageExponent -- Pull the handling file value closer to 1 SetVehicleHandlingFloat(vehicle, 'CHandlingData', 'fCollisionDamageMult', newFCollisionDamageMultiplier) --Get the EngineDamageMultiplier fEngineDamageMult = GetVehicleHandlingFloat(vehicle, 'CHandlingData', 'fEngineDamageMult') --Modify it by pulling all number a towards 1.0 local newFEngineDamageMult = fEngineDamageMult ^ cfg.engineDamageExponent -- Pull the handling file value closer to 1 SetVehicleHandlingFloat(vehicle, 'CHandlingData', 'fEngineDamageMult', newFEngineDamageMult) -- If body damage catastrophic, reset somewhat so we can get new damage to multiply if healthBodyCurrent < cfg.cascadingFailureThreshold then healthBodyNew = cfg.cascadingFailureThreshold end pedInSameVehicleLast = true end -- set the actual new values if healthEngineNew ~= healthEngineCurrent then SetVehicleEngineHealth(vehicle, healthEngineNew) local dmgFactr = (healthEngineCurrent - healthEngineNew) if dmgFactr > 0.8 then if DamageRandomComponent ~= nil then DamageRandomComponent() end end end if healthBodyNew ~= healthBodyCurrent then SetVehicleBodyHealth(vehicle, healthBodyNew) if DamageRandomComponent ~= nil then DamageRandomComponent() end end if healthPetrolTankNew ~= healthPetrolTankCurrent then SetVehiclePetrolTankHealth(vehicle, healthPetrolTankNew) end -- Store current values, so we can calculate delta next time around healthEngineLast = healthEngineNew healthBodyLast = healthBodyNew healthPetrolTankLast = healthPetrolTankNew lastVehicle=vehicle if cfg.randomTireBurstInterval ~= 0 and GetEntitySpeed(vehicle) > 10 then tireBurstLottery() end else if pedInSameVehicleLast == true then -- We just got out of the vehicle lastVehicle = GetVehiclePedIsIn(ped, true) if cfg.deformationMultiplier ~= -1 then SetVehicleHandlingFloat(lastVehicle, 'CHandlingData', 'fDeformationDamageMult', fDeformationDamageMult) end -- Restore deformation multiplier SetVehicleHandlingFloat(lastVehicle, 'CHandlingData', 'fBrakeForce', fBrakeForce) -- Restore Brake Force multiplier if cfg.weaponsDamageMultiplier ~= -1 then SetVehicleHandlingFloat(lastVehicle, 'CHandlingData', 'fWeaponDamageMult', cfg.weaponsDamageMultiplier) end -- Since we are out of the vehicle, we should no longer compensate for bodyDamageFactor SetVehicleHandlingFloat(lastVehicle, 'CHandlingData', 'fCollisionDamageMult', fCollisionDamageMult) -- Restore the original CollisionDamageMultiplier SetVehicleHandlingFloat(lastVehicle, 'CHandlingData', 'fEngineDamageMult', fEngineDamageMult) -- Restore the original EngineDamageMultiplier end pedInSameVehicleLast = false end end end)