2026-04-14 17:41:39 +02:00

341 lines
9.9 KiB
Lua

local isNitrousActive = false
local isBoostEffectActive = false
local isPurgeEffectActive = false
local localPlayerVehicle = 0
local function isVehicleInWater(ped, vehicle)
if GetPedInVehicleSeat(vehicle, -1) == ped and IsEntityInWater(vehicle) then
return true
end
return false
end
local function startNitrousEffects(vehicle, isRemote)
if isVehicleElectric(GetEntityArchetypeName(vehicle)) then
return
end
if isBoostEffectActive then
return
end
isBoostEffectActive = true
local tailLightBones = { "taillight_l", "taillight_r" }
local particleEffectName = "veh_light_red_trail"
local particleScale = 1.0
RequestNamedPtfxAsset("veh_xs_vehicle_mods")
while not HasNamedPtfxAssetLoaded("veh_xs_vehicle_mods") do
Wait(1)
end
SetVehicleNitroEnabled(vehicle, true)
SetVehicleRocketBoostPercentage(vehicle, 100)
SetVehicleRocketBoostRefillTime(vehicle, 0.1)
SetVehicleRocketBoostActive(vehicle, true)
SetVehicleBoostActive(vehicle, true)
if not isRemote then
if Config.NitrousScreenEffects then
SetTimecycleModifier("RaceTurboFlash")
SetTimecycleModifierStrength(0.8)
ShakeGameplayCam("SKY_DIVING_SHAKE", 0.25)
end
if Config.NitrousRearLightTrails then
for _, boneName in ipairs(tailLightBones) do
local boneIndex = GetEntityBoneIndexByName(vehicle, boneName)
UseParticleFxAssetNextCall("core")
local particleHandle = StartParticleFxLoopedOnEntityBone(
particleEffectName,
vehicle,
0.0, 0.0, 0.0,
0.0, 0.0, 0.0,
boneIndex,
particleScale,
false, false, false
)
SetParticleFxLoopedEvolution(particleHandle, "speed", 2.0, false)
end
end
Entity(vehicle).state:set("nitrousFx", "nitrous", true)
end
CreateThread(function()
while not isRemote and isBoostEffectActive do
local powerMultiplier = Config.NitrousPowerIncreaseMult or 2.0
SetVehicleCheatPowerIncrease(vehicle, powerMultiplier)
Wait(0)
end
end)
end
local function stopNitrousEffects(vehicle, isRemote)
isBoostEffectActive = false
SetVehicleNitroEnabled(vehicle, false)
SetVehicleRocketBoostActive(vehicle, false)
SetVehicleBoostActive(vehicle, false)
SetVehicleCheatPowerIncrease(vehicle, 1.0)
if not isRemote then
if Config.NitrousScreenEffects then
ClearTimecycleModifier()
StopGameplayCamShaking(true)
end
if Config.NitrousRearLightTrails then
RemoveParticleFxFromEntity(vehicle)
end
Entity(vehicle).state:set("nitrousFx", false, true)
end
end
local function startPurgeEffects(vehicle, isRemote)
if isPurgeEffectActive then
return
end
isPurgeEffectActive = true
RemoveParticleFxFromEntity(vehicle)
local wheelBones = { "wheel_lf", "wheel_rf" }
local particleScale = 1.0
local particleEffectName = "ent_sht_steam"
for _, boneName in ipairs(wheelBones) do
local boneIndex = GetEntityBoneIndexByName(vehicle, boneName)
local boneWorldPos = GetWorldPositionOfEntityBone(vehicle, boneIndex)
local boneOffset = GetOffsetFromEntityGivenWorldCoords(vehicle, boneWorldPos.x, boneWorldPos.y, boneWorldPos.z)
UseParticleFxAssetNextCall("core")
StartParticleFxLoopedOnEntity(
particleEffectName,
vehicle,
boneOffset.x + 0.03,
boneOffset.y + 0.1,
boneOffset.z + 0.2,
20.0, 0.0, 0.5,
particleScale,
false, false, false
)
end
SetVehicleBoostActive(vehicle, true)
if not isRemote then
Entity(vehicle).state:set("nitrousFx", "purge", true)
end
end
local function stopPurgeEffects(vehicle, isRemote)
isPurgeEffectActive = false
RemoveParticleFxFromEntity(vehicle)
SetVehicleBoostActive(vehicle, false)
if not isRemote then
Entity(vehicle).state:set("nitrousFx", false, true)
end
end
local function updateNitrousHud(vehicle, isUsing, isCooldown, capacity)
local vehicleState = Entity(vehicle).state
if not vehicleState then
return
end
local filledBottles = vehicleState.nitrousFilledBottles or 0
local isEmpty = filledBottles == 0 and capacity <= 0
SendNUIMessage({
nitrousHudData = {
using = isUsing,
cooldown = isCooldown,
installedBottles = vehicleState.nitrousInstalledBottles,
filledBottles = filledBottles,
capacity = capacity,
maxCapacity = Config.NitrousBottleDuration,
empty = isEmpty,
},
})
end
RegisterCommand("+nitrousKeymap", function()
local playerPed = cache.ped
local vehicle = GetVehiclePedIsIn(playerPed, false)
if not vehicle then
return
end
local vehicleState = Entity(vehicle).state
if not vehicleState.nitrousInstalledBottles or vehicleState.nitrousInstalledBottles == 0 then
return
end
if vehicleState.nitrousCooldown then
updateNitrousHud(vehicle, false, true, 0)
return
end
if vehicleState.nitrousFilledBottles == 0 and vehicleState.nitrousCapacity <= 0 then
updateNitrousHud(vehicle, false, false, 0)
return
end
isNitrousActive = true
local nitrousCapacity = vehicleState.nitrousCapacity or 0.0
local filledBottles = vehicleState.nitrousFilledBottles
if nitrousCapacity <= 0 and filledBottles > 0 then
local maxCapacity = Config.NitrousBottleDuration or 10.0
filledBottles = filledBottles - 1
nitrousCapacity = maxCapacity
setVehicleStatebag(vehicle, "nitrousCapacity", nitrousCapacity, false)
setVehicleStatebag(vehicle, "nitrousFilledBottles", filledBottles, true)
end
CreateThread(function()
while isNitrousActive do
if isVehicleInWater(playerPed, vehicle) or not (nitrousCapacity > 0) then
break
end
localPlayerVehicle = vehicle
if IsControlPressed(0, 71) or GetVehicleThrottleOffset(vehicle) > 0.05 then
if isPurgeEffectActive then
stopPurgeEffects(vehicle, false)
end
startNitrousEffects(vehicle, false)
nitrousCapacity = round(nitrousCapacity - 0.1, 2)
updateNitrousHud(vehicle, true, false, nitrousCapacity)
else
if isBoostEffectActive then
stopNitrousEffects(vehicle, false)
end
startPurgeEffects(vehicle, false)
local purgeDrainRate = Config.NitrousPurgeDrainRate or 1
nitrousCapacity = round(nitrousCapacity - (0.1 * purgeDrainRate), 2)
updateNitrousHud(vehicle, true, false, nitrousCapacity)
end
Wait(100)
end
stopNitrousEffects(vehicle, false)
stopPurgeEffects(vehicle, false)
if nitrousCapacity < 0 then
nitrousCapacity = 0
end
setVehicleStatebag(vehicle, "nitrousCapacity", nitrousCapacity, true)
if nitrousCapacity <= 0 then
setVehicleStatebag(vehicle, "nitrousCooldown", true, true)
updateNitrousHud(vehicle, false, true, 0)
CreateThread(function()
local cooldownTime = (Config.NitrousBottleCooldown or 10) * 1000
Wait(cooldownTime)
setVehicleStatebag(vehicle, "nitrousCooldown", false, true)
updateNitrousHud(vehicle, false, false, 0)
end)
end
end)
end, false)
RegisterCommand("-nitrousKeymap", function()
local vehicle = GetVehiclePedIsIn(cache.ped, false)
if not vehicle then
return
end
local vehicleState = Entity(vehicle).state
if not vehicleState.nitrousInstalledBottles or vehicleState.nitrousInstalledBottles == 0 then
return
end
if isNitrousActive then
isNitrousActive = false
stopNitrousEffects(vehicle, false)
stopPurgeEffects(vehicle, false)
end
end, false)
RegisterKeyMapping("+nitrousKeymap", "Use installed nitrous", "keyboard", Config.NitrousDefaultKeyMapping)
AddStateBagChangeHandler("nitrousFx", "", function(bagName, key, value)
local entity = GetEntityFromStateBagName(bagName)
if not entity or not DoesEntityExist(entity) then
return
end
if entity == localPlayerVehicle then
return
end
if value == "nitrous" then
startNitrousEffects(entity, true)
elseif value == "purge" then
startPurgeEffects(entity, true)
else
stopNitrousEffects(entity, true)
stopPurgeEffects(entity, true)
end
end)
RegisterNUICallback("install-new-bottle", function(data, cb)
local connectedVehicle = LocalPlayer.state.tabletConnectedVehicle and LocalPlayer.state.tabletConnectedVehicle.vehicleEntity
if not connectedVehicle or not DoesEntityExist(connectedVehicle) then
return cb(false)
end
local model = GetEntityModel(connectedVehicle)
if not IsThisModelACar(model) and not IsThisModelAQuadbike(model) then
return cb(false)
end
if isVehicleElectric(GetEntityArchetypeName(connectedVehicle)) then
return cb(false)
end
playMinigame(connectedVehicle, "prop", { prop = "canister" }, function(success)
showTabletAfterInteractionPrompt()
SetNuiFocus(true, true)
if not success then
return cb(false)
end
local itemAdded = lib.callback.await("jg-mechanic:server:install-new-bottle", false)
if not itemAdded then
return cb(false)
end
Framework.Client.Notify(Locale.nitrousBottleInstalled, "success")
cb(true)
end)
end)
RegisterNUICallback("refill-bottle", function(data, cb)
Framework.Client.ProgressBar(Locale.refillingBottle, 5000, false, false, function()
cb(lib.callback.await("jg-mechanic:server:refill-nitrous-bottle", false))
end, function()
cb(false)
end)
end)
RegisterNetEvent("jg-mechanic:client:use-nitrous-bottle")
AddEventHandler("jg-mechanic:client:use-nitrous-bottle", function()
local canRefill = lib.callback.await("jg-mechanic:server:can-refill-bottle-in-current-vehicle", false)
if not canRefill then
return
end
Framework.Client.ProgressBar(Locale.refillingBottle, 2500, false, false, function()
TriggerServerEvent("jg-mechanic:server:use-nitrous-bottle")
end, function()
end)
end)