398 lines
18 KiB
Lua
398 lines
18 KiB
Lua
|
local QBCore = exports['qb-core']:GetCoreObject()
|
||
|
local NitrousActivated = false
|
||
|
local NitrousBoost = 18.0
|
||
|
local VehicleNitrous = {}
|
||
|
local Fxs = {}
|
||
|
local purgeflowrate = 0.1
|
||
|
local nitroflowrate = 1.0
|
||
|
|
||
|
local function trim(value)
|
||
|
if not value then return nil end
|
||
|
return (string.gsub(value, '^%s*(.-)%s*$', '%1'))
|
||
|
end
|
||
|
|
||
|
function tableHasKey(table, key)
|
||
|
return table[key] ~= nil
|
||
|
end
|
||
|
|
||
|
RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function()
|
||
|
QBCore.Functions.TriggerCallback('qb-nitro:GetNosLoadedVehs', function(vehs)
|
||
|
VehicleNitrous = vehs
|
||
|
while
|
||
|
VehicleNitrous == nil do
|
||
|
Wait(100)
|
||
|
end
|
||
|
end)
|
||
|
end)
|
||
|
|
||
|
AddEventHandler('onResourceStart', function(resource)
|
||
|
if GetCurrentResourceName() == resource then
|
||
|
QBCore.Functions.TriggerCallback('qb-nitro:GetNosLoadedVehs',
|
||
|
function(vehs)
|
||
|
VehicleNitrous = vehs
|
||
|
while VehicleNitrous == nil do Wait(100) end
|
||
|
end)
|
||
|
end
|
||
|
Wait(500)
|
||
|
end)
|
||
|
|
||
|
RegisterNetEvent('qb-nitro:client:ApplyNitrous', function()
|
||
|
local IsInVehicle = IsPedInAnyVehicle(PlayerPedId())
|
||
|
local ped = PlayerPedId()
|
||
|
local veh = GetVehiclePedIsIn(ped)
|
||
|
|
||
|
if QBCore.Functions.HasItem('nitrous') then
|
||
|
if IsToggleModOn(veh, 18) then
|
||
|
if not NitrousActivated then
|
||
|
if IsInVehicle and not IsThisModelABike(GetEntityModel(GetVehiclePedIsIn(ped))) then
|
||
|
if GetPedInVehicleSeat(veh, -1) == ped then
|
||
|
QBCore.Functions.Progressbar("use_nos", "Tilslutter NOS...", 1000, false, true, {
|
||
|
disableMovement = false,
|
||
|
disableCarMovement = false,
|
||
|
disableMouse = false,
|
||
|
disableCombat = true,
|
||
|
}, {}, {}, {}, function() -- Done
|
||
|
local CurrentVehicle = GetVehiclePedIsIn(PlayerPedId())
|
||
|
local Plate = trim(GetVehicleNumberPlateText(CurrentVehicle))
|
||
|
TriggerServerEvent('qb-nitro:server:LoadNitrous', Plate)
|
||
|
TriggerServerEvent('qb-nitro:server:AddEmptyNitrous')
|
||
|
end, function() -- Cancel
|
||
|
TriggerEvent("QBCore:Notify", "Failed", "error")
|
||
|
ClearPedTasks(ped)
|
||
|
end)
|
||
|
else
|
||
|
QBCore.Functions.Notify("Du kan ikke gøre det fra dette sæde!", "error")
|
||
|
end
|
||
|
else
|
||
|
QBCore.Functions.Notify('Du er ikke i en bil', 'error')
|
||
|
end
|
||
|
else
|
||
|
QBCore.Functions.Notify('NOS er allerede tilsluttet', 'error')
|
||
|
end
|
||
|
else
|
||
|
QBCore.Functions.Notify('Køretøjet skal have en turbo først!', 'error')
|
||
|
end
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
local nosupdated = false
|
||
|
local PurgeMode = false
|
||
|
local NitroMode = true
|
||
|
CreateThread(function()
|
||
|
while true do
|
||
|
local IsInVehicle = IsPedInAnyVehicle(PlayerPedId())
|
||
|
local CurrentVehicle = GetVehiclePedIsIn(PlayerPedId())
|
||
|
if IsInVehicle then
|
||
|
local Plate = trim(GetVehicleNumberPlateText(CurrentVehicle))
|
||
|
if VehicleNitrous[Plate] ~= nil then
|
||
|
if VehicleNitrous[Plate].hasnitro then
|
||
|
if NitroMode then
|
||
|
if IsControlJustPressed(0, 21) and GetPedInVehicleSeat(CurrentVehicle, -1) == PlayerPedId() then
|
||
|
SetVehicleEnginePowerMultiplier(CurrentVehicle, NitrousBoost)
|
||
|
SetVehicleEngineTorqueMultiplier(CurrentVehicle, NitrousBoost)
|
||
|
SetEntityMaxSpeed(CurrentVehicle, 999.0)
|
||
|
NitrousActivated = true
|
||
|
|
||
|
CreateThread(function()
|
||
|
while NitrousActivated do
|
||
|
if VehicleNitrous[Plate].level > 0 then
|
||
|
TriggerServerEvent('qb-nitro:server:UpdateNitroLevel', Plate,
|
||
|
(VehicleNitrous[Plate].level - 0.5))
|
||
|
TriggerEvent('hud:client:UpdateNitrous', Plate, VehicleNitrous[Plate].level)
|
||
|
elseif VehicleNitrous[Plate].level <= 0 then
|
||
|
TriggerServerEvent('qb-nitro:server:UnloadNitrous', Plate)
|
||
|
NitrousActivated = false
|
||
|
SetVehicleBoostActive(CurrentVehicle, 0)
|
||
|
SetVehicleEnginePowerMultiplier(CurrentVehicle, LastEngineMultiplier)
|
||
|
SetVehicleEngineTorqueMultiplier(CurrentVehicle, 1.0)
|
||
|
for index, _ in pairs(Fxs) do
|
||
|
StopParticleFxLooped(Fxs[index], 1)
|
||
|
TriggerServerEvent('qb-nitro:server:StopSync',
|
||
|
trim(GetVehicleNumberPlateText(CurrentVehicle)))
|
||
|
Fxs[index] = nil
|
||
|
end
|
||
|
end
|
||
|
Wait(100)
|
||
|
end
|
||
|
end)
|
||
|
end
|
||
|
elseif PurgeMode then
|
||
|
if IsControlPressed(0, 21) and GetPedInVehicleSeat(CurrentVehicle, -1) == PlayerPedId() then
|
||
|
if VehicleNitrous[Plate].level - 1 >= 0 then
|
||
|
TriggerServerEvent('qb-nitro:server:SyncPurge', VehToNet(CurrentVehicle), true)
|
||
|
if purgeflowrate >= 0.1 or purgeflowrate <= 0.3 then
|
||
|
TriggerServerEvent('qb-nitro:server:UpdateNitroLevel', Plate,
|
||
|
(VehicleNitrous[Plate].level - 0.3))
|
||
|
TriggerEvent('hud:client:UpdateNitrous', Plate, VehicleNitrous[Plate].level)
|
||
|
SetVehicleBoostActive(CurrentVehicle, 1) --Boost Sound
|
||
|
SetVehicleNitroPurgeEnabled(CurrentVehicle, true)
|
||
|
elseif purgeflowrate >= 0.4 or purgeflowrate <= 0.7 then
|
||
|
TriggerServerEvent('qb-nitro:server:UpdateNitroLevel', Plate,
|
||
|
(VehicleNitrous[Plate].level - 0.9))
|
||
|
TriggerEvent('hud:client:UpdateNitrous', Plate, VehicleNitrous[Plate].level)
|
||
|
SetVehicleBoostActive(CurrentVehicle, 1) --Boost Sound
|
||
|
SetVehicleNitroPurgeEnabled(CurrentVehicle, true)
|
||
|
elseif purgeflowrate >= 0.8 or purgeflowrate <= 1.0 then
|
||
|
TriggerServerEvent('qb-nitro:server:UpdateNitroLevel', Plate,
|
||
|
(VehicleNitrous[Plate].level - 1.5))
|
||
|
TriggerEvent('hud:client:UpdateNitrous', Plate, VehicleNitrous[Plate].level)
|
||
|
SetVehicleBoostActive(CurrentVehicle, 1) --Boost Sound
|
||
|
SetVehicleNitroPurgeEnabled(CurrentVehicle, true)
|
||
|
end
|
||
|
elseif VehicleNitrous[Plate].level <= 0 then
|
||
|
TriggerServerEvent('qb-nitro:server:UnloadNitrous', Plate)
|
||
|
SetVehicleNitroPurgeEnabled(CurrentVehicle, false)
|
||
|
SetVehicleBoostActive(CurrentVehicle, false)
|
||
|
TriggerServerEvent('qb-nitro:server:SyncPurge', VehToNet(CurrentVehicle), false)
|
||
|
end
|
||
|
Wait(100)
|
||
|
elseif IsControlJustPressed(0, 10) and purgeflowrate <= 0.9 then
|
||
|
purgeflowrate = purgeflowrate + 0.1
|
||
|
QBCore.Functions.Notify('Purge Spray Flowrate: ' .. purgeflowrate)
|
||
|
elseif IsControlJustPressed(0, 10) and purgeflowrate >= 0.9 then
|
||
|
QBCore.Functions.Notify('Purge Spray is on maximum Flowrate')
|
||
|
elseif IsControlJustPressed(0, 11) and purgeflowrate >= 0.2 then
|
||
|
purgeflowrate = purgeflowrate - 0.1
|
||
|
QBCore.Functions.Notify('Purge Spray Flowrate: ' .. purgeflowrate)
|
||
|
elseif IsControlJustPressed(0, 11) and purgeflowrate <= 0.2 then
|
||
|
QBCore.Functions.Notify('Purge Spray is on minimum Flowrate')
|
||
|
else
|
||
|
SetVehicleNitroPurgeEnabled(CurrentVehicle, false)
|
||
|
TriggerEvent('hud:client:UpdateNitrous', Plate, VehicleNitrous[Plate].level)
|
||
|
TriggerServerEvent('qb-nitro:server:SyncPurge', VehToNet(CurrentVehicle), false)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if IsControlJustPressed(0, 73) and GetPedInVehicleSeat(CurrentVehicle, -1) == PlayerPedId() then
|
||
|
if not PurgeMode and NitroMode then
|
||
|
PurgeMode = true
|
||
|
NitroMode = false
|
||
|
QBCore.Functions.Notify('Smoke Extraction Mode')
|
||
|
elseif not NitroMode and PurgeMode then
|
||
|
NitroMode = true
|
||
|
PurgeMode = false
|
||
|
QBCore.Functions.Notify('Nitro Mode')
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if IsControlJustReleased(0, 21) and GetPedInVehicleSeat(CurrentVehicle, -1) == PlayerPedId() then
|
||
|
if NitrousActivated then
|
||
|
local veh = GetVehiclePedIsIn(PlayerPedId())
|
||
|
SetVehicleBoostActive(veh, 0)
|
||
|
SetVehicleEnginePowerMultiplier(veh, LastEngineMultiplier)
|
||
|
SetVehicleEngineTorqueMultiplier(veh, 1.0)
|
||
|
for index, _ in pairs(Fxs) do
|
||
|
StopParticleFxLooped(Fxs[index], 1)
|
||
|
TriggerServerEvent('qb-nitro:server:StopSync', trim(GetVehicleNumberPlateText(veh)))
|
||
|
Fxs[index] = nil
|
||
|
end
|
||
|
TriggerEvent('hud:client:UpdateNitrous', Plate, VehicleNitrous[Plate].level)
|
||
|
TriggerServerEvent('qb-nitro:server:Update', { Plate, hasnitro, level })
|
||
|
TriggerServerEvent('qb-nitro:server:SyncPurge', VehToNet(CurrentVehicle), false)
|
||
|
NitrousActivated = false
|
||
|
end
|
||
|
end
|
||
|
else
|
||
|
TriggerServerEvent('qb-nitro:server:UnloadNitrous', Plate)
|
||
|
NitrousActivated = false
|
||
|
SetVehicleBoostActive(CurrentVehicle, 0)
|
||
|
SetVehicleEnginePowerMultiplier(CurrentVehicle, LastEngineMultiplier)
|
||
|
SetVehicleEngineTorqueMultiplier(CurrentVehicle, 1.0)
|
||
|
for index, _ in pairs(Fxs) do
|
||
|
StopParticleFxLooped(Fxs[index], 1)
|
||
|
TriggerServerEvent('qb-nitro:server:StopSync', trim(GetVehicleNumberPlateText(CurrentVehicle)))
|
||
|
Fxs[index] = nil
|
||
|
end
|
||
|
TriggerServerEvent('qb-nitro:server:SyncPurge', VehToNet(CurrentVehicle), false)
|
||
|
end
|
||
|
else
|
||
|
if not nosupdated then
|
||
|
TriggerEvent('hud:client:UpdateNitrous', Plate, 0)
|
||
|
nosupdated = true
|
||
|
end
|
||
|
end
|
||
|
else
|
||
|
if nosupdated then
|
||
|
nosupdated = true
|
||
|
end
|
||
|
Wait(1500)
|
||
|
end
|
||
|
Wait(3)
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
----------PURGE--------------
|
||
|
|
||
|
local vehicles = {}
|
||
|
local particles = {}
|
||
|
|
||
|
function IsVehicleNitroPurgeEnabled(vehicle)
|
||
|
return vehicles[vehicle] == true
|
||
|
end
|
||
|
|
||
|
RegisterNetEvent('qb-nitro:client:SyncPurge', function(netid, enabled)
|
||
|
SetVehicleNitroPurgeEnabled(NetToVeh(netid), enabled)
|
||
|
end)
|
||
|
|
||
|
function SetVehicleNitroPurgeEnabled(vehicle, enabled)
|
||
|
if IsVehicleNitroPurgeEnabled(vehicle) == enabled then
|
||
|
return
|
||
|
end
|
||
|
|
||
|
if enabled then
|
||
|
local boneleft = GetEntityBoneIndexByName(vehicle, 'wheel_lf')
|
||
|
local posleft = GetWorldPositionOfEntityBone(vehicle, boneleft)
|
||
|
local offleft = GetOffsetFromEntityGivenWorldCoords(vehicle, posleft.x, posleft.y, posleft.z)
|
||
|
local boneright = GetEntityBoneIndexByName(vehicle, 'wheel_rf')
|
||
|
local posright = GetWorldPositionOfEntityBone(vehicle, boneright)
|
||
|
local offright = GetOffsetFromEntityGivenWorldCoords(vehicle, posright.x, posright.y, posright.z)
|
||
|
local ptfxs = {}
|
||
|
|
||
|
for i = 0, 1 do
|
||
|
local leftPurge = CreateVehiclePurgeSpray(vehicle, offleft.x - 0.1, offleft.y + 0.5, offleft.z + 0.05, 30.0,
|
||
|
-50.0, 0.5, purgeflowrate)
|
||
|
local rightPurge = CreateVehiclePurgeSpray(vehicle, offright.x + 0.1, offright.y + 0.5, offright.z + 0.05,
|
||
|
30.0, 50.0, 0.5, purgeflowrate)
|
||
|
|
||
|
table.insert(ptfxs, leftPurge)
|
||
|
table.insert(ptfxs, rightPurge)
|
||
|
end
|
||
|
|
||
|
vehicles[vehicle] = true
|
||
|
particles[vehicle] = ptfxs
|
||
|
else
|
||
|
if particles[vehicle] and #particles[vehicle] > 0 then
|
||
|
for _, particleId in ipairs(particles[vehicle]) do
|
||
|
StopParticleFxLooped(particleId)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
vehicles[vehicle] = nil
|
||
|
particles[vehicle] = nil
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function CreateVehiclePurgeSpray(vehicle, xOffset, yOffset, zOffset, xRot, yRot, zRot, scale)
|
||
|
UseParticleFxAssetNextCall('core')
|
||
|
return StartParticleFxLoopedOnEntity('ent_sht_steam', vehicle, xOffset, yOffset, zOffset, xRot, yRot, zRot, scale,
|
||
|
false, false, false)
|
||
|
end
|
||
|
|
||
|
p_flame_location = {
|
||
|
"exhaust",
|
||
|
"exhaust_2",
|
||
|
"exhaust_3",
|
||
|
"exhaust_4",
|
||
|
"exhaust_5",
|
||
|
"exhaust_6",
|
||
|
"exhaust_7",
|
||
|
"exhaust_8",
|
||
|
"exhaust_9",
|
||
|
"exhaust_10",
|
||
|
"exhaust_11",
|
||
|
"exhaust_12",
|
||
|
"exhaust_13",
|
||
|
"exhaust_14",
|
||
|
"exhaust_15",
|
||
|
"exhaust_16",
|
||
|
}
|
||
|
|
||
|
ParticleDict = "veh_xs_vehicle_mods"
|
||
|
ParticleFx = "veh_nitrous"
|
||
|
ParticleSize = 1.3
|
||
|
|
||
|
CreateThread(function()
|
||
|
while true do
|
||
|
if NitrousActivated then
|
||
|
local veh = GetVehiclePedIsIn(PlayerPedId())
|
||
|
if veh ~= 0 then
|
||
|
TriggerServerEvent('qb-nitro:server:SyncFlames', VehToNet(veh))
|
||
|
SetVehicleBoostActive(veh, 1)
|
||
|
for _, bones in pairs(p_flame_location) do
|
||
|
if GetEntityBoneIndexByName(veh, bones) ~= -1 then
|
||
|
if Fxs[bones] == nil then
|
||
|
RequestNamedPtfxAsset(ParticleDict)
|
||
|
while not HasNamedPtfxAssetLoaded(ParticleDict) do
|
||
|
Wait(0)
|
||
|
end
|
||
|
SetPtfxAssetNextCall(ParticleDict)
|
||
|
UseParticleFxAssetNextCall(ParticleDict)
|
||
|
Fxs[bones] = StartParticleFxLoopedOnEntityBone(ParticleFx, veh, 0.0, -0.02, 0.0, 0.0, 0.0,
|
||
|
0.0, GetEntityBoneIndexByName(veh, bones), ParticleSize, 0.0, 0.0, 0.0)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
Wait(20)
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
local NOSPFX = {}
|
||
|
|
||
|
RegisterNetEvent('qb-nitro:client:SyncFlames', function(netid, nosid)
|
||
|
local veh = NetToVeh(netid)
|
||
|
if veh ~= 0 then
|
||
|
local myid = GetPlayerServerId(PlayerId())
|
||
|
if NOSPFX[trim(GetVehicleNumberPlateText(veh))] == nil then
|
||
|
NOSPFX[trim(GetVehicleNumberPlateText(veh))] = {}
|
||
|
end
|
||
|
if myid ~= nosid then
|
||
|
for _, bones in pairs(p_flame_location) do
|
||
|
if NOSPFX[trim(GetVehicleNumberPlateText(veh))][bones] == nil then
|
||
|
NOSPFX[trim(GetVehicleNumberPlateText(veh))][bones] = {}
|
||
|
end
|
||
|
if GetEntityBoneIndexByName(veh, bones) ~= -1 then
|
||
|
if NOSPFX[trim(GetVehicleNumberPlateText(veh))][bones].pfx == nil then
|
||
|
RequestNamedPtfxAsset(ParticleDict)
|
||
|
while not HasNamedPtfxAssetLoaded(ParticleDict) do
|
||
|
Wait(0)
|
||
|
end
|
||
|
SetPtfxAssetNextCall(ParticleDict)
|
||
|
UseParticleFxAssetNextCall(ParticleDict)
|
||
|
NOSPFX[trim(GetVehicleNumberPlateText(veh))][bones].pfx = StartParticleFxLoopedOnEntityBone(
|
||
|
ParticleFx, veh, 0.0, -0.05, 0.0, 0.0, 0.0, 0.0, GetEntityBoneIndexByName(veh, bones),
|
||
|
ParticleSize, 0.0, 0.0, 0.0)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
RegisterNetEvent('qb-nitro:client:StopSync', function(plate)
|
||
|
if NOSPFX[plate] then
|
||
|
for k, v in pairs(NOSPFX[plate]) do
|
||
|
StopParticleFxLooped(v.pfx, 1)
|
||
|
NOSPFX[plate][k].pfx = nil
|
||
|
end
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
RegisterNetEvent('qb-nitro:client:UpdateNitroLevel', function(Plate, level)
|
||
|
VehicleNitrous[Plate].level = level
|
||
|
TriggerServerEvent('qb-nitro:server:GetVehicleNos', level, Plate)
|
||
|
end)
|
||
|
|
||
|
RegisterNetEvent('qb-nitro:client:LoadNitrous', function(Plate)
|
||
|
VehicleNitrous[Plate] = {
|
||
|
hasnitro = true,
|
||
|
level = 100,
|
||
|
}
|
||
|
local CurrentVehicle = GetVehiclePedIsIn(PlayerPedId())
|
||
|
local CPlate = trim(GetVehicleNumberPlateText(CurrentVehicle))
|
||
|
if CPlate == Plate then
|
||
|
TriggerEvent('hud:client:UpdateNitrous', Plate, VehicleNitrous[Plate].level)
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
RegisterNetEvent('qb-nitro:client:UnloadNitrous', function(Plate)
|
||
|
VehicleNitrous[Plate] = nil
|
||
|
local CurrentVehicle = GetVehiclePedIsIn(PlayerPedId())
|
||
|
local CPlate = trim(GetVehicleNumberPlateText(CurrentVehicle))
|
||
|
if CPlate == Plate then
|
||
|
NitrousActivated = false
|
||
|
TriggerEvent('hud:client:UpdateNitrous', Plate, 0)
|
||
|
end
|
||
|
end)
|