-- Variables
local QBCore = exports[Config.Core]:GetCoreObject()
local fuelSynced = false
local inGasStation = false
local inBlacklisted = false
local holdingnozzle = false
local Stations = {}
local props = {
"prop_gas_pump_1d",
"prop_gas_pump_1a",
"prop_gas_pump_1b",
"prop_gas_pump_1c",
"prop_vintage_pump",
"prop_gas_pump_old2",
"prop_gas_pump_old3",
"denis3d_prop_gas_pump", -- Gabz Ballas Gas Station Pump.
}
local refueling = false
local GasStationBlips = {} -- Used for managing blips on the client, so labels can be updated.
local RefuelingType = nil
local PlayerInSpecialFuelZone = false
local Rope = nil
local CachedFuelPrice = nil
-- Debug ---
if Config.FuelDebug then
RegisterCommand('setfuel', function(source, args)
if args[1] == nil then print("You forgot to put a fuel level!") return end
local vehicle = GetClosestVehicle()
SetFuel(vehicle, tonumber(args[1]))
QBCore.Functions.Notify(Lang:t("set_fuel_debug")..' '..args[1]..'L', 'success')
end, false)
RegisterCommand('getCachedFuelPrice', function()
print(CachedFuelPrice)
end, false)
RegisterCommand('getVehNameForBlacklist', function()
local veh = GetVehiclePedIsIn(PlayerPedId(), false)
if veh ~= 0 then
print(string.lower(GetDisplayNameFromVehicleModel(GetEntityModel(veh))))
end
end, false)
end
-- Functions
function GetClosestPump(coords, isElectric)
if isElectric then
local electricPump = nil
electricPump = GetClosestObjectOfType(coords.x, coords.y, coords.z, 3.0, joaat("electric_charger"), true, true, true)
local pumpCoords = GetEntityCoords(electricPump)
if Config.FuelDebug then
print(electricPump, pumpCoords)
end
return pumpCoords, electricPump
else
local pump = nil
local pumpCoords
for i = 1, #props, 1 do
local currentPumpModel = props[i]
pump = GetClosestObjectOfType(coords.x, coords.y, coords.z, 3.0, joaat(currentPumpModel), true, true, true)
pumpCoords = GetEntityCoords(pump)
if Config.FuelDebug then print("Gas Pump: ".. pump, "Pump Coords: "..pumpCoords) end
if pump ~= 0 then break end
end
return pumpCoords, pump
end
end
local function FetchStationInfo(info)
if not Config.PlayerOwnedGasStationsEnabled then ReserveLevels = 1000 StationFuelPrice = Config.CostMultiplier return end
if Config.FuelDebug then print("Fetching Information for Location #" ..CurrentLocation) end
QBCore.Functions.TriggerCallback('cdn-fuel:server:fetchinfo', function(result)
if result then
for _, v in pairs(result) do
-- Reserves --
if info == "all" or info == "reserves" then
Currentreserveamount = math.floor(v.fuel)
ReserveLevels = tonumber(Currentreserveamount)
if Config.FuelDebug then print("Fetched Reserve Levels: "..ReserveLevels.." Liters!") end
if Currentreserveamount < Config.MaxFuelReserves then
ReservesNotBuyable = false
else
ReservesNotBuyable = true
end
if Config.UnlimitedFuel then ReservesNotBuyable = true if Config.FuelDebug then print("Reserves are not buyable, because Config.UnlimitedFuel is set to true.") end end
end
-- Fuel Price --
if info == "all" or info == "fuelprice" then
StationFuelPrice = v.fuelprice
end
-- Balance --
if info == "all" or info == "balance" then
StationBalance = v.balance
if info == "balance" then
return StationBalance
end
end
----------------
end
else
if Config.FuelDebug then print("Error, fetching information failed.") end
end
end, CurrentLocation)
end exports(FetchStationInfo, FetchStationInfo)
local function HandleFuelConsumption(vehicle)
if not DecorExistOn(vehicle, Config.FuelDecor) then
SetFuel(vehicle, math.random(200, 800) / 10)
elseif not fuelSynced then
SetFuel(vehicle, GetFuel(vehicle))
fuelSynced = true
end
if IsVehicleEngineOn(vehicle) then
SetFuel(vehicle, GetVehicleFuelLevel(vehicle) - Config.FuelUsage[Round(GetVehicleCurrentRpm(vehicle), 1)] * (Config.Classes[GetVehicleClass(vehicle)] or 1.0) / 10)
end
end
local function CanAfford(price, purchasetype)
local purchasetype = purchasetype
if purchasetype == "bank" then Money = QBCore.Functions.GetPlayerData().money['bank'] elseif purchasetype == 'cash' then Money = QBCore.Functions.GetPlayerData().money['cash'] end
if Money < price then
return false
else
return true
end
end
function FetchCurrentLocation()
if Config.FuelDebug then print("Fetching Current Location") end
return CurrentLocation
end
function IsInGasStation()
return inGasStation
end
-- Thread Stuff --
if Config.LeaveEngineRunning then
CreateThread(function()
while true do
Wait(100)
local ped = PlayerPedId()
if IsPedInAnyVehicle(ped, false) and IsControlPressed(2, 75) and not IsEntityDead(ped) then
local vehicle = GetVehiclePedIsIn(ped, true)
local enginerunning = GetIsVehicleEngineRunning(vehicle)
if Config.FuelDebug then if enginerunning then print('Engine is running!') else print('Engine is not running!') end end
Wait(900)
if IsPedInAnyVehicle(ped, false) and IsControlPressed(2, 75) and not IsEntityDead(ped) and GetPedInVehicleSeat(GetVehiclePedIsIn(PlayerPedId()), -1) == PlayerPedId() then
if enginerunning then SetVehicleEngineOn(vehicle, true, true, false) enginerunning = false end
TaskLeaveVehicle(ped, veh, keepDooRopen and 256 or 0)
end
end
end
end)
end
if Config.ShowNearestGasStationOnly then
RegisterNetEvent('cdn-fuel:client:updatestationlabels', function(location, newLabel)
if not location then if Config.FuelDebug then print('location is nil') end return end
if not newLabel then if Config.FuelDebug then print('newLabel is nil') end return end
if Config.FuelDebug then print("Changing Label for Location #"..location..' to '..newLabel) end
Config.GasStations[location].label = newLabel
end)
CreateThread(function()
if Config.PlayerOwnedGasStationsEnabled then
TriggerServerEvent('cdn-fuel:server:updatelocationlabels')
end
Wait(1000)
local currentGasBlip = 0
while true do
local coords = GetEntityCoords(PlayerPedId())
local closest = 1000
local closestCoords
local closestLocation
local location = 0
local label = "Gas Station" -- Prevent nil just in case, set default name.
for _, ourCoords in pairs(Config.GasStations) do
location = location + 1
if not (location > #Config.GasStations) then -- Make sure we are not going over the amount of locations available.
local gasStationCoords = vector3(Config.GasStations[location].pedcoords.x, Config.GasStations[location].pedcoords.y, Config.GasStations[location].pedcoords.z)
local dstcheck = #(coords - gasStationCoords)
if dstcheck < closest then
closest = dstcheck
closestCoords = gasStationCoords
closestLocation = location
label = Config.GasStations[closestLocation].label
end
else
break
end
end
if DoesBlipExist(currentGasBlip) then
RemoveBlip(currentGasBlip)
end
currentGasBlip = CreateBlip(closestCoords, label)
Wait(10000)
end
end)
else
RegisterNetEvent('cdn-fuel:client:updatestationlabels', function(location, newLabel)
if not location then if Config.FuelDebug then print('location is nil') end return end
if not newLabel then if Config.FuelDebug then print('newLabel is nil') end return end
if Config.FuelDebug then print("Changing Label for Location #"..location..' to '..newLabel) end
Config.GasStations[location].label = newLabel
local coords = vector3(Config.GasStations[location].pedcoords.x, Config.GasStations[location].pedcoords.y, Config.GasStations[location].pedcoords.z)
RemoveBlip(GasStationBlips[location])
GasStationBlips[location] = CreateBlip(coords, Config.GasStations[location].label)
end)
CreateThread(function()
TriggerServerEvent('cdn-fuel:server:updatelocationlabels')
Wait(1000)
local gasStationCoords
for i = 1, #Config.GasStations, 1 do
local location = i
gasStationCoords = vector3(Config.GasStations[location].pedcoords.x, Config.GasStations[location].pedcoords.y, Config.GasStations[location].pedcoords.z)
GasStationBlips[location] = CreateBlip(gasStationCoords, Config.GasStations[location].label)
end
end)
end
CreateThread(function()
for station_id = 1, #Config.GasStations, 1 do
Stations[station_id] = PolyZone:Create(Config.GasStations[station_id].zones, {
name = "CDN_FUEL_GAS_STATION_"..station_id,
minZ = Config.GasStations[station_id].minz,
maxZ = Config.GasStations[station_id].maxz,
debugPoly = Config.PolyDebug
})
Stations[station_id]:onPlayerInOut(function(isPointInside)
if isPointInside then
inGasStation = true
CurrentLocation = station_id
if Config.FuelDebug then print("New Location: "..station_id) end
if Config.PlayerOwnedGasStationsEnabled then
TriggerEvent('cdn-fuel:stations:updatelocation', station_id)
end
else
TriggerEvent('cdn-fuel:stations:updatelocation', nil)
inGasStation = false
end
end)
end
end)
CreateThread(function()
DecorRegister(Config.FuelDecor, 1)
while true do
Wait(1000)
local ped = PlayerPedId()
-- Blacklist Electric Vehicles, if you disables the Config.ElectricVehicleCharging or put the vehicle in Config.NoFuelUsage!
if IsPedInAnyVehicle(ped) then
local vehicle = GetVehiclePedIsIn(ped)
inBlacklisted = IsVehicleBlacklisted(vehicle)
if not inBlacklisted and GetPedInVehicleSeat(vehicle, -1) == ped then
HandleFuelConsumption(vehicle)
end
else
if fuelSynced then fuelSynced = false end
if inBlacklisted then inBlacklisted = false end
Wait(500)
end
end
end)
-- Client Events
if Config.RenewedPhonePayment then
RegisterNetEvent('cdn-fuel:client:phone:PayForFuel', function(amount)
if Config.PlayerOwnedGasStationsEnabled and RefuelingType ~= 'special' then
FetchStationInfo("fuelprice")
Wait(100)
else
FuelPrice = Config.CostMultiplier
end
if Config.AirAndWaterVehicleFueling['enabled'] then
local vehClass = GetVehicleClass(vehicle)
if vehClass == 14 then
FuelPrice = Config.AirAndWaterVehicleFueling['water_fuel_price']
elseif vehClass == 15 or vehClass == 16 then
FuelPrice = Config.AirAndWaterVehicleFueling['air_fuel_price']
end
end
-- Police Discount Math --
if Config.EmergencyServicesDiscount['enabled'] == true then
local discountedJobs = Config.EmergencyServicesDiscount['job']
local plyJob = QBCore.Functions.GetPlayerData().job.name
local shouldRecieveDiscount = false
if type(discountedJobs) == "table" then
for i = 1, #discountedJobs, 1 do
if plyJob == discountedJobs[i] then
shouldRecieveDiscount = true
break
end
end
elseif plyJob == discountedJobs then
shouldRecieveDiscount = true
end
if shouldRecieveDiscount == true and not QBCore.Functions.GetPlayerData().job.onduty and Config.EmergencyServicesDiscount['ondutyonly'] then
QBCore.Functions.Notify(Lang:t("you_are_discount_eligible"), 'primary', 7500)
shouldRecieveDiscount = false
end
if shouldRecieveDiscount then
local discount = Config.EmergencyServicesDiscount['discount']
if discount > 100 then
discount = 100
else
if discount <= 0 then discount = 0 end
end
if discount ~= 0 then
if discount == 100 then
CachedFuelPrice = FuelPrice
FuelPrice = 0
if Config.FuelDebug then
print("Your discount for Emergency Services is set @ "..discount.."% so fuel is free!")
end
else
discount = discount / 100
if Config.FuelDebug then
print(FuelPrice, FuelPrice*discount)
end
CachedFuelPrice = FuelPrice
FuelPrice = FuelPrice - (FuelPrice*discount)
if Config.FuelDebug then
print("Your discount for Emergency Services is set @ "..discount.."%. Setting new price to: $"..FuelPrice)
end
end
else
if Config.FuelDebug then
print("Your discount for Emergency Services is set @ "..discount.."%. It cannot be 0 or < 0!")
end
end
end
end
local cost = amount * FuelPrice
local tax = GlobalTax(cost)
local total = math.ceil(cost + tax)
local success = exports['qb-phone']:PhoneNotification(Lang:t("fuel_phone_header"), Lang:t("phone_notification")..total, 'fas fa-gas-pump', '#9f0e63', "NONE", 'fas fa-check-circle', 'fas fa-times-circle')
if success then
if QBCore.Functions.GetPlayerData().money['bank'] <= total then
QBCore.Functions.Notify(Lang:t("not_enough_money"), "error")
else
TriggerServerEvent('cdn-fuel:server:PayForFuel', total, "bank", FuelPrice, false, CachedFuelPrice)
RefuelPossible = true
RefuelPossibleAmount = amount
RefuelCancelledFuelCost = FuelPrice
RefuelPurchaseType = "bank"
RefuelCancelled = false
end
end
end)
end
if Config.Ox.Inventory then
if LocalPlayer.state['isLoggedIn'] then
exports.ox_inventory:displayMetadata({
cdn_fuel = "Fuel",
})
end
AddEventHandler("QBCore:Client:OnPlayerLoaded", function()
if GetResourceState('ox_inventory'):match("start") then
exports.ox_inventory:displayMetadata({
cdn_fuel = "Fuel",
})
end
end)
end
if Config.Ox.Menu then
RegisterNetEvent('cdn-fuel:client:OpenContextMenu', function(total, fuelamounttotal, purchasetype)
if Config.FuelDebug then print("OpenContextMenu for OX sent from server.") end
lib.registerContext({
id = 'cdnconfirmationmenu',
title = Lang:t("menu_purchase_station_header_1")..math.ceil(total)..Lang:t("menu_purchase_station_header_2"),
options = {
{
title = Lang:t("menu_purchase_station_confirm_header"),
description = Lang:t("menu_refuel_accept"),
icon = "fas fa-check-circle",
arrow = false, -- puts arrow to the right
event = 'cdn-fuel:client:RefuelVehicle',
args = {
fuelamounttotal = fuelamounttotal,
purchasetype = purchasetype,
}
},
{
title = Lang:t("menu_header_close"),
description = Lang:t("menu_refuel_cancel"),
icon = "fas fa-times-circle",
arrow = false, -- puts arrow to the right
onSelect = function()
lib.hideContext()
end,
},
},
})
lib.showContext('cdnconfirmationmenu')
end)
end
RegisterNetEvent('cdn-fuel:client:RefuelMenu', function(type)
if Config.FuelDebug then print("cdn-fuel:client:refuelmenu") end
if not type then type = nil end
if Config.RenewedPhonePayment then
if not RefuelPossible then
TriggerEvent('cdn-fuel:client:SendMenuToServer', type)
else
if not Cancelledrefuel and not RefuelCancelled then
if RefuelPossibleAmount then
local purchasetype = "bank"
local fuelamounttotal = tonumber(RefuelPossibleAmount)
TriggerEvent('cdn-fuel:client:RefuelVehicle', purchasetype, fuelamounttotal)
else
if Config.FuelDebug then
print("RefuelMenu: MORE THAN ZERO!")
end
QBCore.Functions.Notify(Lang:t("more_than_zero"), 'error', 7500)
end
end
end
else
TriggerEvent('cdn-fuel:client:SendMenuToServer', type)
end
end)
RegisterNetEvent('cdn-fuel:client:grabnozzle', function()
if Config.PlayerOwnedGasStationsEnabled then
ShutOff = false
Wait(50)
QBCore.Functions.TriggerCallback('cdn-fuel:server:checkshutoff', function(result)
if result == true then
QBCore.Functions.Notify(Lang:t("emergency_shutoff_active"), 'error', 7500) ShutOff = true return
else
ShutOff = false
end
end, CurrentLocation)
Wait(50)
else
ShutOff = false
Wait(50)
end
if not ShutOff then
local ped = PlayerPedId()
if holdingnozzle then return end
LoadAnimDict("anim@am_hold_up@male")
TaskPlayAnim(ped, "anim@am_hold_up@male", "shoplift_high", 2.0, 8.0, -1, 50, 0, 0, 0, 0)
TriggerServerEvent("InteractSound_SV:PlayOnSource", "pickupnozzle", 0.4)
Wait(300)
StopAnimTask(ped, "anim@am_hold_up@male", "shoplift_high", 1.0)
fuelnozzle = CreateObject(joaat('prop_cs_fuel_nozle'), 1.0, 1.0, 1.0, true, true, false)
local lefthand = GetPedBoneIndex(ped, 18905)
AttachEntityToEntity(fuelnozzle, ped, lefthand, 0.13, 0.04, 0.01, -42.0, -115.0, -63.42, 0, 1, 0, 1, 0, 1)
local grabbednozzlecoords = GetEntityCoords(ped)
if Config.PumpHose then
local pumpCoords, pump = GetClosestPump(grabbednozzlecoords)
-- Load Rope Textures
RopeLoadTextures()
while not RopeAreTexturesLoaded() do
Wait(0)
RopeLoadTextures()
end
-- Wait for Pump to exist.
while not pump do
Wait(0)
end
Rope = AddRope(pumpCoords.x, pumpCoords.y, pumpCoords.z, 0.0, 0.0, 0.0, 3.0, Config.RopeType['fuel'], 8.0 --[[ DO NOT SET THIS TO 0.0!!! GAME WILL CRASH!]], 0.0, 1.0, false, false, false, 1.0, true)
while not Rope do
Wait(0)
end
ActivatePhysics(Rope)
Wait(100)
local nozzlePos = GetEntityCoords(fuelnozzle)
if Config.FuelDebug then print("NOZZLE POS ".. nozzlePos) end
nozzlePos = GetOffsetFromEntityInWorldCoords(fuelnozzle, 0.0, -0.033, -0.195)
local PumpHeightAdd = nil
if Config.FuelDebug then
print("Grabbing Hose @ Location: #"..CurrentLocation)
if Config.GasStations[CurrentLocation].pumpheightadd ~= nil then
PumpHeightAdd = Config.GasStations[CurrentLocation].pumpheightadd
print("Pump Height Add: "..Config.GasStations[CurrentLocation].pumpheightadd)
end
end
if PumpHeightAdd == nil then
PumpHeightAdd = 2.1
if Config.FuelDebug then
print("PumpHeightAdd was not configured for location: #"..CurrentLocation.." so, we are defaulting to 2.0!")
end
end
AttachEntitiesToRope(Rope, pump, fuelnozzle, pumpCoords.x, pumpCoords.y, pumpCoords.z + PumpHeightAdd, nozzlePos.x, nozzlePos.y, nozzlePos.z, length, false, false, nil, nil)
if Config.FuelDebug then
print("Hose Properties:")
print(Rope, pump, fuelnozzle, pumpCoords.x, pumpCoords.y, pumpCoords.z, nozzlePos.x, nozzlePos.y, nozzlePos.z, length)
SetEntityDrawOutline(fuelnozzle --[[ Entity ]], true --[[ boolean ]])
end
end
holdingnozzle = true
CreateThread(function()
while holdingnozzle do
local currentcoords = GetEntityCoords(ped)
local dist = #(grabbednozzlecoords - currentcoords)
if not TargetCreated then if Config.FuelTargetExport then exports[Config.TargetResource]:AllowRefuel(true) end end
TargetCreated = true
if dist > 7.5 then
if TargetCreated then if Config.FuelTargetExport then exports[Config.TargetResource]:AllowRefuel(false) end end
TargetCreated = true
holdingnozzle = false
DeleteObject(fuelnozzle)
QBCore.Functions.Notify(Lang:t("nozzle_cannot_reach"), 'error')
if Config.PumpHose == true then
RopeUnloadTextures()
DeleteRope(Rope)
end
if Config.FuelNozzleExplosion then
AddExplosion(grabbednozzlecoords.x, grabbednozzlecoords.y, grabbednozzlecoords.z, 'EXP_TAG_PROPANE', 1.0, true,false, 5.0)
StartScriptFire(grabbednozzlecoords.x, grabbednozzlecoords.y, grabbednozzlecoords.z - 1,25,false)
SetFireSpreadRate(10.0)
Wait(5000)
StopFireInRange(grabbednozzlecoords.x, grabbednozzlecoords.y, grabbednozzlecoords.z - 1, 3.0)
end
end
Wait(2500)
end
end)
end
end)
RegisterNetEvent('cdn-fuel:client:returnnozzle', function()
if Config.ElectricVehicleCharging then
if IsHoldingElectricNozzle() then
SetElectricNozzle("putback")
else
holdingnozzle = false
TargetCreated = false
TriggerServerEvent("InteractSound_SV:PlayOnSource", "putbacknozzle", 0.4)
Wait(250)
if Config.FuelTargetExport then exports[Config.TargetResource]:AllowRefuel(false) end
DeleteObject(fuelnozzle)
end
else
holdingnozzle = false
TargetCreated = false
TriggerServerEvent("InteractSound_SV:PlayOnSource", "putbacknozzle", 0.4)
Wait(250)
if Config.FuelTargetExport then exports[Config.TargetResource]:AllowRefuel(false) end
DeleteObject(fuelnozzle)
end
if Config.PumpHose then
if Config.FuelDebug then print("Removing Hose.") end
RopeUnloadTextures()
DeleteRope(Rope)
end
end)
AddEventHandler('onResourceStop', function(resource)
if resource == GetCurrentResourceName() then
DeleteObject(fuelnozzle)
DeleteObject(SpecialFuelNozzleObj)
if Config.PumpHose then
RopeUnloadTextures()
DeleteObject(Rope)
end
if Config.TargetResource == 'qb-target' then
exports.qb-target:removeGlobalVehicle('cdn-fuel:options:1')
exports.qb-target:removeGlobalVehicle('cdn-fuel:options:2')
end
-- Remove Blips from map so they dont double up.
for i = 1, #GasStationBlips, 1 do
RemoveBlip(GasStationBlips[i])
end
end
end)
RegisterNetEvent('cdn-fuel:client:FinalMenu', function(purchasetype)
if Config.FuelDebug then
print('cdn-fuel:client:FinalMenu', purchasetype)
end
if RefuelingType == nil then
FetchStationInfo("all")
Wait(Config.WaitTime)
if Config.PlayerOwnedGasStationsEnabled and not Config.UnlimitedFuel then
if ReserveLevels < 1 then
QBCore.Functions.Notify(Lang:t("station_no_fuel"), 'error', 7500) return
end
end
if Config.PlayerOwnedGasStationsEnabled then
FuelPrice = (1 * StationFuelPrice)
end
end
local money = nil
if purchasetype == "bank" then money = QBCore.Functions.GetPlayerData().money['bank'] elseif purchasetype == 'cash' then money = QBCore.Functions.GetPlayerData().money['cash'] end
if not Config.PlayerOwnedGasStationsEnabled then
FuelPrice = (1 * Config.CostMultiplier)
end
local vehicle = GetClosestVehicle()
local curfuel = GetFuel(vehicle)
local finalfuel
if curfuel < 10 then finalfuel = string.sub(curfuel, 1, 1) else finalfuel = string.sub(curfuel, 1, 2) end
local maxfuel = (100 - finalfuel - 1)
if Config.AirAndWaterVehicleFueling['enabled'] then
local vehClass = GetVehicleClass(vehicle)
if vehClass == 14 then
FuelPrice = Config.AirAndWaterVehicleFueling['water_fuel_price']
RefuelingType = 'special'
elseif vehClass == 15 or vehClass == 16 then
FuelPrice = Config.AirAndWaterVehicleFueling['air_fuel_price']
RefuelingType = 'special'
end
end
-- Police Discount Math --
if Config.EmergencyServicesDiscount['enabled'] == true and (Config.EmergencyServicesDiscount['emergency_vehicles_only'] == false or (Config.EmergencyServicesDiscount['emergency_vehicles_only'] == true and GetVehicleClass(vehicle) == 18)) then
local discountedJobs = Config.EmergencyServicesDiscount['job']
local plyJob = QBCore.Functions.GetPlayerData().job.name
local shouldRecieveDiscount = false
if type(discountedJobs) == "table" then
for i = 1, #discountedJobs, 1 do
if plyJob == discountedJobs[i] then
shouldRecieveDiscount = true
break
end
end
elseif plyJob == discountedJobs then
shouldRecieveDiscount = true
end
if shouldRecieveDiscount == true and not QBCore.Functions.GetPlayerData().job.onduty and Config.EmergencyServicesDiscount['ondutyonly'] then
QBCore.Functions.Notify(Lang:t("you_are_discount_eligible"), 'primary', 7500)
shouldRecieveDiscount = false
end
if shouldRecieveDiscount then
local discount = Config.EmergencyServicesDiscount['discount']
if discount > 100 then
discount = 100
else
if discount <= 0 then discount = 0 end
end
if Config.FuelDebug then print("Before we apply the discount the FuelPrice is: $"..FuelPrice) end
if discount ~= 0 then
if discount == 100 then
CachedFuelPrice = FuelPrice
FuelPrice = 0
if Config.FuelDebug then
print("Your discount for Emergency Services is set @ "..discount.."% so fuel is free!")
end
else
discount = discount / 100
if Config.FuelDebug then
print("Math( Current Fuel Price: "..FuelPrice.. " - " ..FuelPrice * discount.. "<<-- FuelPrice * Discount)")
end
CachedFuelPrice = FuelPrice
FuelPrice = (FuelPrice) - (FuelPrice*discount)
if Config.FuelDebug then
print("Your discount for Emergency Services is set @ "..discount.."%. Setting new price to: $"..FuelPrice)
end
end
else
if Config.FuelDebug then
print("Your discount for Emergency Services is set @ "..discount.."%. It cannot be 0 or < 0!")
end
end
end
end
local wholetankcost = (tonumber(FuelPrice) * maxfuel)
local wholetankcostwithtax = math.ceil(tonumber(FuelPrice) * maxfuel + GlobalTax(wholetankcost))
if Config.Ox.Input then
if Config.PlayerOwnedGasStationsEnabled and not Config.UnlimitedFuel and not RefuelingType == 'special' then
if ReserveLevels < maxfuel then
local wholetankcost = (tonumber(FuelPrice) * ReserveLevels)
local wholetankcostwithtax = math.ceil(tonumber(FuelPrice) * ReserveLevels + GlobalTax(wholetankcost))
fuel = lib.inputDialog('Gas Station', {
{ type = "input", label = 'Gasoline Price', default = '$'.. FuelPrice .. ' Per Liter', disabled = true },
{ type = "input", label = 'Current Fuel', default = finalfuel .. ' Per Liter', disabled = true },
{ type = "input", label = 'Required Full Tank', default = maxfuel .. 'Per Liter', disabled = true },
{ type = "input", label = 'Stations Available Gasoline', default = ReserveLevels, disabled = true },
{ type = "slider", label = 'Full Tank Cost: $' ..wholetankcostwithtax.. '',default = ReserveLevels, min = 0, max = ReserveLevels},
})
if not fuel then if Config.FuelDebug then print("Fuel Is Nil! #1") end return end
fuelAmount = tonumber(fuel[5])
else
fuel = lib.inputDialog('Gas Station', {
{ type = "input", label = 'Gasoline Price', default = '$'.. FuelPrice .. ' Per Liter', disabled = true },
{ type = "input", label = 'Current Fuel', default = finalfuel .. ' Per Liter', disabled = true },
{ type = "input", label = 'Required For A Full Tank', default = maxfuel, disabled = true },
{ type = "slider", label = 'Full Tank Cost: $' ..wholetankcostwithtax.. '', default = maxfuel, min = 0, max = maxfuel },
})
if not fuel then if Config.FuelDebug then print("Fuel Is Nil! #2") end return end
fuelAmount = tonumber(fuel[4])
end
else
fuel = lib.inputDialog('Gas Station', {
{ type = "input", label = 'Gasoline Price', default = '$'.. FuelPrice .. ' Per Liter',disabled = true },
{ type = "input", label = 'Current Fuel', default = finalfuel .. ' Per Liter',disabled = true },
{ type = "input", label = 'Required For A Full Tank', default = maxfuel, disabled = true },
{ type = "slider", label = 'Full Tank Cost: $' ..wholetankcostwithtax.. '', default = maxfuel, min = 0, max = maxfuel},
})
if not fuel then if Config.FuelDebug then print("Fuel Is Nil! #3") end return end
fuelAmount = tonumber(fuel[4])
end
if fuel then
if not fuelAmount then print("Fuel Amount Nil") return end
if not holdingnozzle and RefuelingType ~= 'special' then QBCore.Functions.Notify(Lang:t("no_nozzle"), 'error') return end
if Config.PlayerOwnedGasStationsEnabled and not Config.UnlimitedFuel and not RefuelingType == "special" then
if tonumber(fuelAmount) > tonumber(ReserveLevels) then
QBCore.Functions.Notify(Lang:t("station_not_enough_fuel"), "error") return
end
end
if (fuelAmount + finalfuel) >= 100 then
QBCore.Functions.Notify(Lang:t("tank_cannot_fit"), "error")
else
if GlobalTax(fuelAmount * FuelPrice) + (fuelAmount * FuelPrice) <= money then
TriggerServerEvent('cdn-fuel:server:OpenMenu', fuelAmount, inGasStation, false, purchasetype, tonumber(FuelPrice))
else
QBCore.Functions.Notify(Lang:t("not_enough_money"), 'error', 7500)
end
end
else
if Config.FuelDebug then
print("Fuel is nil!")
end
end
else
if Config.PlayerOwnedGasStationsEnabled and not Config.UnlimitedFuel and not RefuelingType == 'special' then
if ReserveLevels < maxfuel then
local wholetankcost = (FuelPrice * ReserveLevels)
local wholetankcostwithtax = math.ceil(FuelPrice * ReserveLevels + GlobalTax(wholetankcost))
fuel = exports['qb-input']:ShowInput({
header = "Select the Amount of Fuel<br>Current Price: $" ..
FuelPrice .. " / Liter <br> Current Fuel: " .. finalfuel .. " Liters <br> Full Tank Cost: $" ..
wholetankcostwithtax .. "",
submitText = Lang:t("input_insert_nozzle"),
inputs = { {
type = 'number',
isRequired = true,
name = 'amount',
text = 'Only '..ReserveLevels..' Liters are available.'
}}
})
else
fuel = exports['qb-input']:ShowInput({
header = "Select the Amount of Fuel<br>Current Price: $" ..
FuelPrice .. " / Liter <br> Current Fuel: " .. finalfuel .. " Liters <br> Full Tank Cost: $" ..
wholetankcostwithtax .. "",
submitText = Lang:t("input_insert_nozzle"),
inputs = { {
type = 'number',
isRequired = true,
name = 'amount',
text = 'The Tank Can Hold ' .. maxfuel .. ' More Liters.'
}}
})
end
else
fuel = exports['qb-input']:ShowInput({
header = "Select the Amount of Fuel<br>Current Price: $" ..
FuelPrice .. " / Liter <br> Current Fuel: " .. finalfuel .. " Liters <br> Full Tank Cost: $" ..
wholetankcostwithtax .. "",
submitText = Lang:t("input_insert_nozzle"),
inputs = { {
type = 'number',
isRequired = true,
name = 'amount',
text = 'The Tank Can Hold ' .. maxfuel .. ' More Liters.'
}}
})
end
if fuel then
if not fuel.amount then if Config.FuelDebug then print("fuel.amount = nil") end return end
if not holdingnozzle and RefuelingType ~= 'special' then QBCore.Functions.Notify(Lang:t("no_nozzle")) return end
if Config.PlayerOwnedGasStationsEnabled and not Config.UnlimitedFuel and not RefuelingType == 'special' then
if tonumber(fuel.amount) > tonumber(ReserveLevels) then
QBCore.Functions.Notify(Lang:t("station_not_enough_fuel"), "error") return
end
end
if (fuel.amount + finalfuel) >= 100 then
QBCore.Functions.Notify(Lang:t("tank_cannot_fit"), "error")
else
if GlobalTax(fuel.amount * FuelPrice) + (fuel.amount * FuelPrice) <= money then
if Config.FuelDebug then
print("Player is getting "..fuel.amount.."L of Fuel @ "..FuelPrice..'/L, Total Cost: '..GlobalTax(fuel.amount * FuelPrice) + (fuel.amount * FuelPrice))
end
TriggerServerEvent('cdn-fuel:server:OpenMenu', fuel.amount, inGasStation, false, purchasetype, tonumber(FuelPrice))
else
QBCore.Functions.Notify(Lang:t("not_enough_money"), 'error', 7500)
end
end
end
end
end)
RegisterNetEvent('cdn-fuel:client:SendMenuToServer', function(type)
local vehicle = GetClosestVehicle()
local NotElectric = false
if Config.ElectricVehicleCharging then
local isElectric = GetCurrentVehicleType(vehicle)
if isElectric == 'electricvehicle' then
QBCore.Functions.Notify(Lang:t("need_electric_charger"), 'error', 7500) return
end
NotElectric = true
else
NotElectric = true
end
Wait(50)
if NotElectric then
local CurFuel = GetVehicleFuelLevel(vehicle)
local playercashamount = QBCore.Functions.GetPlayerData().money['cash']
if not holdingnozzle and not type == 'special' then return end
local header
if type == 'special' then
header = "Refuel Vehicle"
RefuelingType = 'special'
else
header = Config.GasStations[CurrentLocation].label
end
if CurFuel < 95 then
if Config.Ox.Menu then
lib.registerContext({
id = 'cdnfueldmainmenu',
title = 'Gas Station',
icon = "fas fa-gas-pump",
options = {
{
title = Lang:t("menu_header_cash"),
description = Lang:t("menu_pay_with_cash") .. playercashamount,
icon = "fas fa-usd",
arrow = false, -- puts arrow to the right
onSelect = function ()
TriggerEvent('cdn-fuel:client:FinalMenu', 'cash')
end,
},
{
title = Lang:t("menu_header_bank"),
description = Lang:t("menu_pay_with_bank"),
icon = "fas fa-credit-card",
arrow = false, -- puts arrow to the right
onSelect = function ()
TriggerEvent('cdn-fuel:client:FinalMenu', 'bank')
end,
},
{
title = Lang:t("menu_header_close"),
description = Lang:t("menu_refuel_cancel"),
icon = "fas fa-times-circle",
arrow = false, -- puts arrow to the right
onSelect = function()
lib.hideContext()
end,
},
},
})
lib.showContext('cdnfueldmainmenu')
else
exports['qb-menu']:openMenu({
{
header = header,
isMenuHeader = true,
icon = "fas fa-gas-pump",
},
{
header = Lang:t("menu_header_cash"),
txt = Lang:t("menu_pay_with_cash") .. playercashamount,
icon = "fas fa-usd",
params = {
event = "cdn-fuel:client:FinalMenu",
args = 'cash',
}
},
{
header = Lang:t("menu_header_bank"),
txt = Lang:t("menu_pay_with_bank"),
icon = "fas fa-credit-card",
params = {
event = "cdn-fuel:client:FinalMenu",
args = 'bank',
}
},
{
header = Lang:t("menu_header_close"),
txt = Lang:t("menu_refuel_cancel"),
icon = "fas fa-times-circle",
params = {
event = "qb-menu:closeMenu",
}
},
})
end
else
QBCore.Functions.Notify(Lang:t("tank_already_full"), 'error')
end
else
QBCore.Functions.Notify(Lang:t("need_electric_charger"), 'error', 7500)
end
end)
RegisterNetEvent('cdn-fuel:client:RefuelVehicle', function(data)
if RefuelingType == nil then
FetchStationInfo("all")
Wait(100)
end
local purchasetype, amount, fuelamount
if not Config.RenewedPhonePayment then
purchasetype = data.purchasetype
elseif data.purchasetype == "cash" then
purchasetype = "cash"
else
purchasetype = RefuelPurchaseType
end
if Config.FuelDebug then print("Purchase Type: "..purchasetype) end
if not Config.RenewedPhonePayment then
amount = data.fuelamounttotal
elseif data.purchasetype == "cash" then
amount = data.fuelamounttotal
elseif not data.fuelamounttotal then
amount = RefuelPossibleAmount
end
if Config.PlayerOwnedGasStationsEnabled and RefuelingType == nil then
FuelPrice = (1 * StationFuelPrice)
else
FuelPrice = (1 * Config.CostMultiplier)
end
if not holdingnozzle and RefuelingType == nil then return end
amount = tonumber(amount)
if amount < 1 then return end
if amount < 10 then fuelamount = string.sub(amount, 1, 1) else fuelamount = string.sub(amount, 1, 2) end
local vehicle = GetClosestVehicle()
if Config.AirAndWaterVehicleFueling['enabled'] then
local vehClass = GetVehicleClass(vehicle)
if vehClass == 14 then
FuelPrice = Config.AirAndWaterVehicleFueling['water_fuel_price']
elseif vehClass == 15 or vehClass == 16 then
FuelPrice = Config.AirAndWaterVehicleFueling['air_fuel_price']
end
end
-- Police Discount Math --
if Config.EmergencyServicesDiscount['enabled'] == true and (Config.EmergencyServicesDiscount['emergency_vehicles_only'] == false or (Config.EmergencyServicesDiscount['emergency_vehicles_only'] == true and GetVehicleClass(vehicle) == 18)) then
local discountedJobs = Config.EmergencyServicesDiscount['job']
local plyJob = QBCore.Functions.GetPlayerData().job.name
local shouldRecieveDiscount = false
if type(discountedJobs) == "table" then
for i = 1, #discountedJobs, 1 do
if plyJob == discountedJobs[i] then
shouldRecieveDiscount = true
break
end
end
elseif plyJob == discountedJobs then
shouldRecieveDiscount = true
end
if shouldRecieveDiscount == true and not QBCore.Functions.GetPlayerData().job.onduty and Config.EmergencyServicesDiscount['ondutyonly'] then
QBCore.Functions.Notify(Lang:t("you_are_discount_eligible"), 'primary', 7500)
shouldRecieveDiscount = false
end
if shouldRecieveDiscount then
local discount = Config.EmergencyServicesDiscount['discount']
if discount > 100 then
discount = 100
else
if discount <= 0 then discount = 0 end
end
if Config.FuelDebug then print("Before we apply the discount the FuelPrice is: $"..FuelPrice) end
if discount ~= 0 then
if discount == 100 then
CachedFuelPrice = FuelPrice
FuelPrice = 0
if Config.FuelDebug then
print("Your discount for Emergency Services is set @ | "..discount.."% | so fuel is free!")
end
else
discount = discount / 100
if Config.FuelDebug then
print("Math( Current Fuel Price: "..FuelPrice.. " - " ..FuelPrice * discount.. "<<-- FuelPrice * Discount)")
end
CachedFuelPrice = FuelPrice
FuelPrice = FuelPrice - (FuelPrice*discount)
if Config.FuelDebug then
print("Your discount for Emergency Services is set @ "..discount.."%. Setting new price to: $"..FuelPrice)
end
end
else
if Config.FuelDebug then
print("Your discount for Emergency Services is set @ "..discount.."%. It cannot be 0 or < 0!")
end
end
end
end
local refillCost = (amount * FuelPrice) + GlobalTax(amount * FuelPrice)
local ped = PlayerPedId()
local time = amount * Config.RefuelTime
if amount < 10 then time = 10 * Config.RefuelTime end
local vehicleCoords = GetEntityCoords(vehicle)
if inGasStation then
if IsPlayerNearVehicle() then
RequestAnimDict(Config.RefuelAnimationDictionary)
while not HasAnimDictLoaded(Config.RefuelAnimationDictionary) do Wait(100) end
if GetIsVehicleEngineRunning(vehicle) and Config.VehicleBlowUp then
local Chance = math.random(1, 100)
if Chance <= Config.BlowUpChance then
AddExplosion(vehicleCoords, 5, 50.0, true, false, true)
return
end
end
if Config.FaceTowardsVehicle and RefuelingType ~= 'special' then
local bootBoneIndex = GetEntityBoneIndexByName(vehicle --[[ Entity ]], 'boot' --[[ string ]])
local vehBootCoords = GetWorldPositionOfEntityBone(vehicle --[[ Entity ]], joaat(bootBoneIndex)--[[ integer ]])
if Config.FuelDebug then
print("Vehicle Boot Bone Coords: "..vehBootCoords.x, vehBootCoords.y, vehBootCoords.z)
end
TaskTurnPedToFaceCoord(PlayerPedId(), vehBootCoords, 500)
Wait(500)
end
TaskPlayAnim(ped, Config.RefuelAnimationDictionary, Config.RefuelAnimation, 8.0, 1.0, -1, 1, 0, 0, 0, 0)
refueling = true
Refuelamount = 0
CreateThread(function()
while refueling do
if Refuelamount == nil then Refuelamount = 0 end
Wait(Config.RefuelTime)
Refuelamount = Refuelamount + 1
if Cancelledrefuel then
local finalrefuelamount = math.floor(Refuelamount)
local refillCost = (finalrefuelamount * FuelPrice) + GlobalTax(finalrefuelamount * FuelPrice)
if Config.RenewedPhonePayment and purchasetype == "bank" then
local remainingamount = (amount - Refuelamount)
MoneyToGiveBack = (GlobalTax(remainingamount * RefuelCancelledFuelCost) + (remainingamount * RefuelCancelledFuelCost))
TriggerServerEvent("cdn-fuel:server:phone:givebackmoney", MoneyToGiveBack)
CachedFuelPrice = nil
else
TriggerServerEvent('cdn-fuel:server:PayForFuel', refillCost, purchasetype, FuelPrice, false, CachedFuelPrice)
CachedFuelPrice = nil
end
if RefuelingType == nil then
if Config.PlayerOwnedGasStationsEnabled and not Config.UnlimitedFuel then
TriggerServerEvent('cdn-fuel:station:server:updatereserves', "remove", finalrefuelamount, ReserveLevels, CurrentLocation)
if CachedFuelPrice ~= nil then
if Config.FuelDebug then
print("We have a cached price: $"..CachedFuelPrice..", we will credit this to the gas station.")
end
TriggerServerEvent('cdn-fuel:station:server:updatebalance', "add", finalrefuelamount, StationBalance, CurrentLocation, CachedFuelPrice)
CachedFuelPrice = nil
else
TriggerServerEvent('cdn-fuel:station:server:updatebalance', "add", finalrefuelamount, StationBalance, CurrentLocation, FuelPrice)
end
end
end
local curfuel = GetFuel(vehicle)
local finalfuel = (curfuel + Refuelamount)
if finalfuel >= 98 and finalfuel < 100 then
SetFuel(vehicle, 100)
else
SetFuel(vehicle, finalfuel)
end
if Config.RenewedPhonePayment then
RefuelCancelled = true
RefuelPossibleAmount = 0
RefuelPossible = false
RefuelCancelledFuelCost = 0
end
Cancelledrefuel = false
end
end
end)
TriggerServerEvent("InteractSound_SV:PlayOnSource", "refuel", 0.3)
if Config.Ox.Progress then
if lib.progressCircle({
duration = time,
label = Lang:t("prog_refueling_vehicle"),
position = 'bottom',
useWhileDead = false,
canCancel = true,
disable = {
move = true,
combat = true
},
}) then
refueling = false
if purchasetype == "cash" then
TriggerServerEvent('cdn-fuel:server:PayForFuel', refillCost, purchasetype, FuelPrice, false, CachedFuelPrice)
elseif purchasetype == "bank" then
if not Config.RenewedPhonePayment or purchasetype == "cash" then
TriggerServerEvent('cdn-fuel:server:PayForFuel', refillCost, purchasetype, FuelPrice, false, CachedFuelPrice)
end
end
local curfuel = GetFuel(vehicle)
local finalfuel = (curfuel + fuelamount)
if finalfuel > 99 and finalfuel < 100 then
SetFuel(vehicle, 100)
else
SetFuel(vehicle, finalfuel)
end
if RefuelingType == nil then
if Config.PlayerOwnedGasStationsEnabled and not Config.UnlimitedFuel then
TriggerServerEvent('cdn-fuel:station:server:updatereserves', "remove", fuelamount, ReserveLevels, CurrentLocation)
if CachedFuelPrice ~= nil then
if Config.FuelDebug then
print("We have a cached price: $"..CachedFuelPrice..", we will credit this to the gas station.")
end
TriggerServerEvent('cdn-fuel:station:server:updatebalance', "add", fuelamount, StationBalance, CurrentLocation, CachedFuelPrice)
CachedFuelPrice = nil
else
TriggerServerEvent('cdn-fuel:station:server:updatebalance', "add", fuelamount, StationBalance, CurrentLocation, FuelPrice)
end
else
if Config.FuelDebug then print("Config.PlayerOwnedGasStationsEnabled == false or Config.UnlimitedFuel == true, this means reserves will not be changed.") end
end
if Config.FuelDebug then print("Config.PlayerOwnedGasStationsEnabled == false or Config.UnlimitedFuel == true, this means reserves will not be changed.") end
end
StopAnimTask(ped, Config.RefuelAnimationDictionary, Config.RefuelAnimation, 3.0, 3.0, -1, 2, 0, 0, 0, 0)
TriggerServerEvent("InteractSound_SV:PlayOnSource", "fuelstop", 0.4)
if Config.RenewedPhonePayment then
RefuelPossible = false
RefuelPossibleAmount = 0
RefuelPurchaseType = "bank"
end
else
refueling = false
Cancelledrefuel = true
StopAnimTask(ped, Config.RefuelAnimationDictionary, Config.RefuelAnimation, 3.0, 3.0, -1, 2, 0, 0, 0, 0)
TriggerServerEvent("InteractSound_SV:PlayOnSource", "fuelstop", 0.4)
end
else
QBCore.Functions.Progressbar("refuel-car", Lang:t("prog_refueling_vehicle"), time, false, true, {
disableMovement = true,
disableCarMovement = true,
disableMouse = false,
disableCombat = true,
}, {}, {}, {}, function()
refueling = false
if not Config.RenewedPhonePayment or purchasetype == "cash" then
TriggerServerEvent('cdn-fuel:server:PayForFuel', refillCost, purchasetype, FuelPrice)
end
local curfuel = GetFuel(vehicle)
local finalfuel = (curfuel + fuelamount)
if finalfuel > 99 and finalfuel < 100 then
SetFuel(vehicle, 100)
else
SetFuel(vehicle, finalfuel)
end
if RefuelingType == nil then
if Config.PlayerOwnedGasStationsEnabled and not Config.UnlimitedFuel then
TriggerServerEvent('cdn-fuel:station:server:updatereserves', "remove", fuelamount, ReserveLevels, CurrentLocation)
if CachedFuelPrice ~= nil then
if Config.FuelDebug then
print("We have a cached price: $"..CachedFuelPrice..", we will credit this to the gas station.")
end
TriggerServerEvent('cdn-fuel:station:server:updatebalance', "add", fuelamount, StationBalance, CurrentLocation, CachedFuelPrice)
CachedFuelPrice = nil
else
TriggerServerEvent('cdn-fuel:station:server:updatebalance', "add", fuelamount, StationBalance, CurrentLocation, FuelPrice)
end
else
if Config.FuelDebug then print("Config.PlayerOwnedGasStationsEnabled == false or Config.UnlimitedFuel == true, this means reserves will not be changed.") end
end
end
StopAnimTask(ped, Config.RefuelAnimationDictionary, Config.RefuelAnimation, 3.0, 3.0, -1, 2, 0, 0, 0, 0)
TriggerServerEvent("InteractSound_SV:PlayOnSource", "fuelstop", 0.4)
if Config.RenewedPhonePayment then
RefuelPossible = false
RefuelPossibleAmount = 0
RefuelPurchaseType = "bank"
end
end, function()
refueling = false
Cancelledrefuel = true
StopAnimTask(ped, Config.RefuelAnimationDictionary, Config.RefuelAnimation, 3.0, 3.0, -1, 2, 0, 0, 0, 0)
TriggerServerEvent("InteractSound_SV:PlayOnSource", "fuelstop", 0.4)
end, "fas fa-gas-pump")
end
end
else
return
end
end)
-- Jerry Can --
RegisterNetEvent('cdn-fuel:jerrycan:refuelmenu', function(itemData)
if IsPedInAnyVehicle(PlayerPedId(), false) then QBCore.Functions.Notify(Lang:t("cannot_refuel_inside"), 'error') return end
if Config.FuelDebug then print("Item Data: " .. json.encode(itemData)) end
local vehicle = GetClosestVehicle()
local vehiclecoords = GetEntityCoords(vehicle)
local pedcoords = GetEntityCoords(PlayerPedId())
if GetVehicleBodyHealth(vehicle) < 100 then QBCore.Functions.Notify(Lang:t("vehicle_is_damaged"), 'error') return end
local jerrycanamount
if Config.Ox.Inventory then
jerrycanamount = tonumber(itemData.metadata.cdn_fuel)
else
jerrycanamount = itemData.info.gasamount
end
if Config.Ox.Menu then
if holdingnozzle then
local fulltank
if jerrycanamount == Config.JerryCanCap then fulltank = true
GasString = Lang:t("menu_jerry_can_footer_full_gas")
else fulltank = false
GasString = Lang:t("menu_jerry_can_footer_refuel_gas")
end
lib.registerContext({
id = 'cdnrefuelmenu',
title = Lang:t("menu_header_jerry_can"),
options = {
{
title = Lang:t("menu_header_refuel_jerry_can"),
event = 'cdn-fuel:jerrycan:refueljerrycan',
args = {itemData = itemData},
disabled = fulltank
},
},
})
lib.showContext('cdnrefuelmenu')
else
if #(vehiclecoords - pedcoords) > 2.5 then return end
local nogas
if jerrycanamount < 1 then nogas = true
GasString = Lang:t("menu_jerry_can_footer_no_gas")
else nogas = false
GasString = Lang:t("menu_jerry_can_footer_use_gas")
end
lib.registerContext({
id = 'cdnrefuelmenu2',
title = Lang:t("menu_header_jerry_can"),
options = {
{
title = Lang:t("menu_header_refuel_vehicle"),
event = 'cdn-fuel:jerrycan:refuelvehicle',
args = {itemData = itemData},
disabled = nogas,
},
},
})
lib.showContext('cdnrefuelmenu2')
end
else
if holdingnozzle then
local fulltank
if jerrycanamount == Config.JerryCanCap then
fulltank = true
GasString = Lang:t("menu_jerry_can_footer_full_gas")
else
fulltank = false
GasString = Lang:t("menu_jerry_can_footer_refuel_gas")
end
exports['qb-menu']:openMenu({
{
header = Lang:t("menu_header_jerry_can"),
isMenuHeader = true,
},
{
header = Lang:t("menu_header_refuel_jerry_can"),
txt = GasString,
icon = "fas fa-gas-pump",
params = {
event = "cdn-fuel:jerrycan:refueljerrycan",
args = {
itemData = itemData,
},
},
disabled = fulltank,
},
{
header = Lang:t("menu_header_close"),
txt = Lang:t("menu_jerry_can_close"),
icon = "fas fa-times-circle",
params = {
event = "qb-menu:closeMenu",
}
},
})
else
if #(vehiclecoords - pedcoords) > 2.5 then return end
local nogas
if jerrycanamount < 1 then nogas = true
GasString = Lang:t("menu_jerry_can_footer_no_gas")
else nogas = false
GasString = Lang:t("menu_jerry_can_footer_use_gas")
end
exports['qb-menu']:openMenu({
{
header = Lang:t("menu_header_jerry_can"),
isMenuHeader = true,
},
{
header = Lang:t("menu_header_refuel_vehicle"),
txt = GasString,
icon = "fas fa-gas-pump",
params = {
event = "cdn-fuel:jerrycan:refuelvehicle",
args = {
itemData = itemData,
},
},
disabled = nogas,
},
{
header = Lang:t("menu_header_close"),
txt = Lang:t("menu_jerry_can_close"),
icon = "fas fa-times-circle",
params = {
event = "qb-menu:closeMenu",
}
},
})
end
end
end)
RegisterNetEvent('cdn-fuel:client:jerrycanfinalmenu', function(purchasetype)
Moneyamount = nil
if purchasetype == 'bank' then
Moneyamount = QBCore.Functions.GetPlayerData().money['bank']
elseif purchasetype == 'cash' then
Moneyamount = QBCore.Functions.GetPlayerData().money['cash']
end
if Moneyamount > math.ceil(Config.JerryCanPrice + GlobalTax(Config.JerryCanPrice)) then
TriggerServerEvent('cdn-fuel:server:purchase:jerrycan', purchasetype)
else
if purchasetype == 'bank' then QBCore.Functions.Notify(Lang:t("not_enough_money_in_bank"), 'error') end
if purchasetype == "cash" then QBCore.Functions.Notify(Lang:t("not_enough_money_in_cash"), 'error') end
end
end)
RegisterNetEvent('cdn-fuel:client:purchasejerrycan', function()
local playercashamount = QBCore.Functions.GetPlayerData().money['cash']
if Config.Ox.Menu then
lib.registerContext({
id = 'purchasejerrycan',
title = Lang:t("menu_jerry_can_purchase_header")..(math.ceil(Config.JerryCanPrice + GlobalTax(Config.JerryCanPrice))),
options = {
{
title = Lang:t("menu_header_cash"),
description = Lang:t("menu_pay_with_cash") .. playercashamount,
icon = "fas fa-usd",
event = 'cdn-fuel:client:jerrycanfinalmenu',
args = 'cash',
},
{
title = Lang:t("menu_header_bank"),
description = Lang:t("menu_pay_with_bank"),
icon = "fas fa-credit-card",
event = 'cdn-fuel:client:jerrycanfinalmenu',
args = 'bank',
},
{
title = Lang:t("menu_header_close"),
description = Lang:t("menu_jerry_can_close"),
icon = "fas fa-times-circle",
onSelect = function()
lib.hideContext()
end,
},
},
})
lib.showContext('purchasejerrycan')
else
exports['qb-menu']:openMenu({
{
header = Lang:t("menu_jerry_can_purchase_header")..(math.ceil(Config.JerryCanPrice + GlobalTax(Config.JerryCanPrice))),
isMenuHeader = true,
icon = "fas fa-fire-flame-simple",
},
{
header = Lang:t("menu_header_cash"),
txt = Lang:t("menu_pay_with_cash") .. playercashamount,
icon = "fas fa-usd",
params = {
event = "cdn-fuel:client:jerrycanfinalmenu",
args = 'cash',
}
},
{
header = Lang:t("menu_header_bank"),
txt = Lang:t("menu_pay_with_bank"),
icon = "fas fa-credit-card",
params = {
event = "cdn-fuel:client:jerrycanfinalmenu",
args = 'bank',
}
},
{
header = Lang:t("menu_header_close"),
txt = Lang:t("menu_jerry_can_footer_close"),
icon = "fas fa-times-circle",
params = {
event = "qb-menu:closeMenu",
}
},
})
end
end)
RegisterNetEvent('cdn-fuel:jerrycan:refuelvehicle', function(data)
local ped = PlayerPedId()
local vehicle = GetClosestVehicle()
local vehfuel = math.floor(GetFuel(vehicle))
local maxvehrefuel = (100 - math.ceil(vehfuel))
local itemData = data.itemData
local jerrycanfuelamount
if Config.Ox.Inventory then
jerrycanfuelamount = tonumber(itemData.metadata.cdn_fuel)
else
jerrycanfuelamount = itemData.info.gasamount
end
local vehicle = GetClosestVehicle()
local NotElectric = false
if Config.ElectricVehicleCharging then
local isElectric = GetCurrentVehicleType(vehicle)
if isElectric == 'electricvehicle' then
QBCore.Functions.Notify(Lang:t("need_electric_charger"), 'error', 7500) return
end
NotElectric = true
else
NotElectric = true
end
Wait(50)
if NotElectric then
if maxvehrefuel < Config.JerryCanCap then
maxvehrefuel = maxvehrefuel
else
maxvehrefuel = Config.JerryCanCap
end
if maxvehrefuel >= jerrycanfuelamount then maxvehrefuel = jerrycanfuelamount elseif maxvehrefuel < jerrycanfuelamount then maxvehrefuel = maxvehrefuel end
-- Need to Convert to OX --
if Config.Ox.Input then
local refuel = lib.inputDialog(Lang:t("input_select_refuel_header"), {Lang:t("input_max_fuel_footer_1") .. maxvehrefuel .. Lang:t("input_max_fuel_footer_2")})
if not refuel then return end
local refuelAmount = tonumber(refuel[1])
--
if refuel and refuelAmount then
if tonumber(refuelAmount) == 0 then QBCore.Functions.Notify(Lang:t("more_than_zero"), 'error') return elseif tonumber(refuelAmount) < 0 then QBCore.Functions.Notify(Lang:t("more_than_zero"), 'error') return end
if tonumber(refuelAmount) > jerrycanfuelamount then QBCore.Functions.Notify(Lang:t("jerry_can_not_enough_fuel"), 'error') return end
local refueltimer = Config.RefuelTime * tonumber(refuelAmount)
if tonumber(refuelAmount) < 10 then refueltimer = Config.RefuelTime * 10 end
if vehfuel + tonumber(refuelAmount) > 100 then QBCore.Functions.Notify(Lang:t("tank_cannot_fit"), 'error') return end
local refuelAmount = tonumber(refuelAmount)
JerrycanProp = CreateObject(joaat('w_am_jerrycan'), 1.0, 1.0, 1.0, true, true, false)
local lefthand = GetPedBoneIndex(ped, 18905)
AttachEntityToEntity(JerrycanProp, ped, lefthand, 0.11 --[[Left - Right (Kind of)]] , 0.0 --[[Up - Down]], 0.25 --[[Forward - Backward]], 15.0, 170.0, 90.42, 0, 1, 0, 1, 0, 1)
if Config.Ox.Progress then
if lib.progressCircle({
duration = refueltimer,
label = Lang:t("prog_refueling_vehicle"),
position = 'bottom',
useWhileDead = false,
canCancel = true,
disable = {
car = true,
move = true,
combat = true
},
anim = {
dict = Config.JerryCanAnimDict,
clip = Config.JerryCanAnim
},
}) then
DeleteObject(JerrycanProp)
StopAnimTask(ped, Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0)
QBCore.Functions.Notify(Lang:t("jerry_can_success_vehicle"), 'success')
local JerryCanItemData = data.itemData
local srcPlayerData = QBCore.Functions.GetPlayerData()
TriggerServerEvent('cdn-fuel:info', "remove", tonumber(refuelAmount), srcPlayerData, JerryCanItemData)
SetFuel(vehicle, (vehfuel + refuelAmount))
else
DeleteObject(JerrycanProp)
StopAnimTask(ped, Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0)
QBCore.Functions.Notify(Lang:t("cancelled"), 'error')
end
else
QBCore.Functions.Progressbar('refuel_gas', Lang:t("prog_refueling_vehicle"), refueltimer, false, true, { -- Name | Label | Time | useWhileDead | canCancel
disableMovement = true,
disableCarMovement = true,
disableMouse = false,
disableCombat = true,
}, {
animDict = Config.JerryCanAnimDict,
anim = Config.JerryCanAnim,
flags = 17,
}, {}, {}, function() -- Play When Done
DeleteObject(JerrycanProp)
StopAnimTask(ped, Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0)
QBCore.Functions.Notify(Lang:t("jerry_can_success_vehicle"), 'success')
local JerryCanItemData = data.itemData
local srcPlayerData = QBCore.Functions.GetPlayerData()
TriggerServerEvent('cdn-fuel:info', "remove", tonumber(refuelAmount), srcPlayerData, JerryCanItemData)
SetFuel(vehicle, (vehfuel + refuelAmount))
end, function() -- Play When Cancel
DeleteObject(JerrycanProp)
StopAnimTask(ped, Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0)
QBCore.Functions.Notify(Lang:t("cancelled"), 'error')
end, "jerrycan")
end
end
else
local refuel = exports['qb-input']:ShowInput({
header = Lang:t("input_select_refuel_header"),
submitText = Lang:t("input_refuel_submit"),
inputs = {
{
type = 'number',
isRequired = true,
name = 'amount',
text = Lang:t("input_max_fuel_footer_1") .. maxvehrefuel .. Lang:t("input_max_fuel_footer_2")
}
}
})
if refuel then
if tonumber(refuel.amount) == 0 then QBCore.Functions.Notify(Lang:t("more_than_zero"), 'error') return elseif tonumber(refuel.amount) < 0 then QBCore.Functions.Notify(Lang:t("more_than_zero"), 'error') return end
if tonumber(refuel.amount) > jerrycanfuelamount then QBCore.Functions.Notify(Lang:t("jerry_can_not_enough_fuel"), 'error') return end
local refueltimer = Config.RefuelTime * tonumber(refuel.amount)
if tonumber(refuel.amount) < 10 then refueltimer = Config.RefuelTime * 10 end
if vehfuel + tonumber(refuel.amount) > 100 then QBCore.Functions.Notify(Lang:t("tank_cannot_fit"), 'error') return end
JerrycanProp = CreateObject(joaat('w_am_jerrycan'), 1.0, 1.0, 1.0, true, true, false)
local lefthand = GetPedBoneIndex(ped, 18905)
AttachEntityToEntity(JerrycanProp, ped, lefthand, 0.11 --[[Left - Right (Kind of)]] , 0.0 --[[Up - Down]], 0.25 --[[Forward - Backward]], 15.0, 170.0, 90.42, 0, 1, 0, 1, 0, 1)
if Config.Ox.Progress then
if lib.progressCircle({
duration = refueltimer,
label = Lang:t("prog_refueling_vehicle"),
position = 'bottom',
useWhileDead = false,
canCancel = true,
disable = {
car = true,
move = true,
combat = true
},
anim = {
dict = Config.JerryCanAnimDict,
clip = Config.JerryCanAnim
},
}) then
DeleteObject(JerrycanProp)
StopAnimTask(ped, Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0)
QBCore.Functions.Notify(Lang:t("jerry_can_success_vehicle"), 'success')
local JerryCanItemData = data.itemData
local srcPlayerData = QBCore.Functions.GetPlayerData()
TriggerServerEvent('cdn-fuel:info', "remove", tonumber(refuel.amount), srcPlayerData, JerryCanItemData)
SetFuel(vehicle, (vehfuel + refuel.amount))
else
DeleteObject(JerrycanProp)
StopAnimTask(ped, Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0)
QBCore.Functions.Notify(Lang:t("cancelled"), 'error')
end
else
QBCore.Functions.Progressbar('refuel_gas', Lang:t("prog_refueling_vehicle"), refueltimer, false, true, { -- Name | Label | Time | useWhileDead | canCancel
disableMovement = true,
disableCarMovement = true,
disableMouse = false,
disableCombat = true,
}, {
animDict = Config.JerryCanAnimDict,
anim = Config.JerryCanAnim,
flags = 17,
}, {}, {}, function() -- Play When Done
DeleteObject(JerrycanProp)
StopAnimTask(ped, Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0)
QBCore.Functions.Notify(Lang:t("jerry_can_success_vehicle"), 'success')
local JerryCanItemData = data.itemData
local srcPlayerData = QBCore.Functions.GetPlayerData()
TriggerServerEvent('cdn-fuel:info', "remove", tonumber(refuel.amount), srcPlayerData, JerryCanItemData)
SetFuel(vehicle, (vehfuel + refuel.amount))
end, function() -- Play When Cancel
DeleteObject(JerrycanProp)
StopAnimTask(ped, Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0)
QBCore.Functions.Notify(Lang:t("cancelled"), 'error')
end, "jerrycan")
end
end
end
else
QBCore.Functions.Notify(Lang:t("need_electric_charger"), 'error', 7500) return
end
end)
RegisterNetEvent('cdn-fuel:jerrycan:refueljerrycan', function(data)
FetchStationInfo('all')
Wait(100)
if Config.PlayerOwnedGasStationsEnabled then
FuelPrice = (1 * StationFuelPrice)
else
FuelPrice = (1 * Config.CostMultiplier)
end
local itemData = data.itemData
local jerrycanfuelamount
if Config.Ox.Inventory then
jerrycanfuelamount = tonumber(itemData.metadata.cdn_fuel)
else
jerrycanfuelamount = itemData.info.gasamount
end
local ped = PlayerPedId()
if Config.Ox.Input then
local JerryCanMaxRefuel = (Config.JerryCanCap - jerrycanfuelamount)
local refuel = lib.inputDialog(Lang:t("input_select_refuel_header"), {Lang:t("input_max_fuel_footer_1") .. JerryCanMaxRefuel .. Lang:t("input_max_fuel_footer_2")})
if not refuel then return end
local refuelAmount = tonumber(refuel[1])
if refuel then
if tonumber(refuelAmount) == 0 then QBCore.Functions.Notify(Lang:t("more_than_zero"), 'error') return elseif tonumber(refuelAmount) < 0 then QBCore.Functions.Notify(Lang:t("more_than_zero"), 'error') return end
if tonumber(refuelAmount) + tonumber(jerrycanfuelamount) > Config.JerryCanCap then QBCore.Functions.Notify(Lang:t("jerry_can_not_fit_fuel"), 'error') return end
if tonumber(refuelAmount) > Config.JerryCanCap then QBCore.Functions.Notify(Lang:t("jerry_can_not_fit_fuel"), 'error') return end
local refueltimer = Config.RefuelTime * tonumber(refuelAmount)
if tonumber(refuelAmount) < 10 then refueltimer = Config.RefuelTime * 10 end
local price = (tonumber(refuelAmount) * FuelPrice) + GlobalTax(tonumber(refuelAmount) * FuelPrice)
if not CanAfford(price, "cash") then QBCore.Functions.Notify(Lang:t("not_enough_money_in_cash"), 'error') return end
JerrycanProp = CreateObject(joaat('w_am_jerrycan'), 1.0, 1.0, 1.0, true, true, false)
local lefthand = GetPedBoneIndex(ped, 18905)
AttachEntityToEntity(JerrycanProp, ped, lefthand, 0.11 --[[Left - Right]] , 0.05--[[Up - Down]], 0.27 --[[Forward - Backward]], -15.0, 170.0, -90.42, 0, 1, 0, 1, 0, 1)
SetEntityVisible(fuelnozzle, false, 0)
if lib.progressCircle({
duration = refueltimer,
label = Lang:t("prog_jerry_can_refuel"),
position = 'bottom',
useWhileDead = false,
canCancel = true,
disable = {
car = true,
move = true,
combat = true
},
anim = {
dict = Config.JerryCanAnimDict,
clip = Config.JerryCanAnim
},
}) then
SetEntityVisible(fuelnozzle, true, 0)
DeleteObject(JerrycanProp)
StopAnimTask(ped, Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0)
QBCore.Functions.Notify(Lang:t("jerry_can_success"), 'success')
local srcPlayerData = QBCore.Functions.GetPlayerData()
if Config.Ox.Inventory then
TriggerServerEvent('cdn-fuel:info', "add", tonumber(refuelAmount), srcPlayerData, itemData)
else
TriggerServerEvent('cdn-fuel:info', "add", tonumber(refuelAmount), srcPlayerData, itemData)
end
if Config.PlayerOwnedGasStationsEnabled and not Config.UnlimitedFuel then
TriggerServerEvent('cdn-fuel:station:server:updatereserves', "remove", tonumber(refuelAmount), ReserveLevels, CurrentLocation)
if CachedFuelPrice ~= nil then
TriggerServerEvent('cdn-fuel:station:server:updatebalance', "add", tonumber(refuelAmount), StationBalance, CurrentLocation, CachedFuelPrice)
else
TriggerServerEvent('cdn-fuel:station:server:updatebalance', "add", tonumber(refuelAmount), StationBalance, CurrentLocation, FuelPrice)
end
else
if Config.FuelDebug then print("Config.PlayerOwnedGasStationsEnabled == false or Config.UnlimitedFuel == true, this means reserves will not be changed.") end
end
local total = (tonumber(refuelAmount) * FuelPrice) + GlobalTax(tonumber(refuelAmount) * FuelPrice)
TriggerServerEvent('cdn-fuel:server:PayForFuel', total, "cash", FuelPrice)
else
SetEntityVisible(fuelnozzle, true, 0)
DeleteObject(JerrycanProp)
StopAnimTask(ped, Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0)
QBCore.Functions.Notify(Lang:t("cancelled"), 'error')
end
end
else
local JerryCanMaxRefuel = (Config.JerryCanCap - jerrycanfuelamount)
local refuel = exports['qb-input']:ShowInput({
header = Lang:t("input_select_refuel_header"),
submitText = Lang:t("input_refuel_jerrycan_submit"),
inputs = { {
type = 'number',
isRequired = true,
name = 'amount',
text = Lang:t("input_max_fuel_footer_1") .. JerryCanMaxRefuel .. Lang:t("input_max_fuel_footer_2")
} }
})
if refuel then
if tonumber(refuel.amount) == 0 then QBCore.Functions.Notify(Lang:t("more_than_zero"), 'error') return elseif tonumber(refuel.amount) < 0 then QBCore.Functions.Notify(Lang:t("more_than_zero"), 'error') return end
if tonumber(refuel.amount) + tonumber(jerrycanfuelamount) > Config.JerryCanCap then QBCore.Functions.Notify(Lang:t("jerry_can_not_fit_fuel"), 'error') return end
if tonumber(refuel.amount) > Config.JerryCanCap then QBCore.Functions.Notify(Lang:t("jerry_can_not_fit_fuel"), 'error') return end
local refueltimer = Config.RefuelTime * tonumber(refuel.amount)
if tonumber(refuel.amount) < 10 then refueltimer = Config.RefuelTime * 10 end
local price = (tonumber(refuel.amount) * FuelPrice) + GlobalTax(tonumber(refuel.amount) * FuelPrice)
if not CanAfford(price, "cash") then QBCore.Functions.Notify(Lang:t("not_enough_money_in_cash"), 'error') return end
JerrycanProp = CreateObject(joaat('w_am_jerrycan'), 1.0, 1.0, 1.0, true, true, false)
local lefthand = GetPedBoneIndex(ped, 18905)
AttachEntityToEntity(JerrycanProp, ped, lefthand, 0.11 --[[Left - Right]] , 0.05 --[[Up - Down]], 0.27 --[[Forward - Backward]], -15.0, 170.0, -90.42, 0, 1, 0, 1, 0, 1)
SetEntityVisible(fuelnozzle, false, 0)
QBCore.Functions.Progressbar('refuel_gas', Lang:t("prog_jerry_can_refuel"), refueltimer, false,true, { -- Name | Label | Time | useWhileDead | canCancel
disableMovement = true,
disableCarMovement = true,
disableMouse = false,
disableCombat = true,
}, {
animDict = Config.JerryCanAnimDict,
anim = Config.JerryCanAnim,
flags = 17,
}, {}, {}, function() -- Play When Done
SetEntityVisible(fuelnozzle, true, 0)
DeleteObject(JerrycanProp)
StopAnimTask(ped, Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0)
QBCore.Functions.Notify(Lang:t("jerry_can_success"), 'success')
local jerryCanData = data.itemData
local srcPlayerData = QBCore.Functions.GetPlayerData()
local refuelAmount = tonumber(refuel.amount)
if Config.Ox.Inventory then
TriggerServerEvent('cdn-fuel:info', "add", tonumber(refuelAmount), srcPlayerData, jerryCanData)
else
TriggerServerEvent('cdn-fuel:info', "add", tonumber(refuelAmount), srcPlayerData, jerryCanData)
end
if RefuelingType == nil then
if Config.PlayerOwnedGasStationsEnabled and not Config.UnlimitedFuel then
TriggerServerEvent('cdn-fuel:station:server:updatereserves', "remove", tonumber(refuel.amount), ReserveLevels, CurrentLocation)
if CachedFuelPrice ~= nil then
TriggerServerEvent('cdn-fuel:station:server:updatebalance', "add", tonumber(refuel.amount), StationBalance, CurrentLocation, CachedFuelPrice)
else
TriggerServerEvent('cdn-fuel:station:server:updatebalance', "add", tonumber(refuel.amount), StationBalance, CurrentLocation, FuelPrice)
end
else
if Config.FuelDebug then print("Config.PlayerOwnedGasStationsEnabled == false or Config.UnlimitedFuel == true, this means reserves will not be changed.") end
end
end
local total = (tonumber(refuel.amount) * FuelPrice) + GlobalTax(tonumber(refuel.amount) * FuelPrice)
TriggerServerEvent('cdn-fuel:server:PayForFuel', total, "cash", FuelPrice, false, CachedFuelPrice)
end, function() -- Play When Cancel
SetEntityVisible(fuelnozzle, true, 0)
DeleteObject(JerrycanProp)
StopAnimTask(ped, Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0)
QBCore.Functions.Notify(Lang:t("cancelled"), 'error')
end, "jerrycan")
end
end
end)
--- Syphoning ---
local function PoliceAlert(coords)
local chance = math.random(1, 100)
if chance < Config.SyphonPoliceCallChance then
if Config.SyphonDispatchSystem == "ps-dispatch" then
exports['ps-dispatch']:SuspiciousActivity()
elseif Config.SyphonDispatchSystem == "qb-dispatch" then
TriggerServerEvent('qb-dispatch:911call', coords)
elseif Config.SyphonDispatchSystem == "qb-default" then
TriggerServerEvent('cdn-syphoning:callcops', coords)
elseif Config.SyphonDispatchSystem == "custom" then
-- Put your own dispatch system here
else
if Config.SyphonDebug then print("There was an attempt to call police but this dispatch system is not supported!") end
end
end
end
-- Events --
RegisterNetEvent('cdn-syphoning:syphon:menu', function(itemData)
if IsPedInAnyVehicle(PlayerPedId(), false) then QBCore.Functions.Notify(Lang:t("syphon_inside_vehicle"), 'error') return end
if Config.SyphonDebug then print("Item Data: " .. json.encode(itemData)) end
local vehicle = GetClosestVehicle()
local vehModel = GetEntityModel(vehicle)
local vehiclename = string.lower(GetDisplayNameFromVehicleModel(vehModel))
local vehiclecoords = GetEntityCoords(vehicle)
local pedcoords = GetEntityCoords(PlayerPedId())
if Config.ElectricVehicleCharging then
NotElectric = true
if Config.ElectricVehicles[vehiclename] and Config.ElectricVehicles[vehiclename].isElectric then
NotElectric = false
if Config.SyphonDebug then print("^2"..current.. "^5 has been found. It ^2matches ^5the Player's Vehicle: ^2"..vehiclename..". ^5This means syphoning will not be allowed.") end
QBCore.Functions.Notify(Lang:t("syphon_electric_vehicle"), 'error', 7500) return
end
else
NotElectric = true
end
if NotElectric then
if #(vehiclecoords - pedcoords) > 2.5 then return end
if GetVehicleBodyHealth(vehicle) < 100 then QBCore.Functions.Notify(Lang:t("vehicle_is_damaged"), 'error') return end
local nogas
local syphonfull
if Config.Ox.Inventory then
if tonumber(itemData.metadata.cdn_fuel) < 1 then nogas = true Nogasstring = Lang:t("menu_syphon_empty") else nogas = false Nogasstring = Lang:t("menu_syphon_refuel") end
if tonumber(itemData.metadata.cdn_fuel) == Config.SyphonKitCap then syphonfull = true Stealfuelstring = Lang:t("menu_syphon_kit_full") elseif GetFuel(vehicle) < 1 then syphonfull = true Stealfuelstring = Lang:t("menu_syphon_vehicle_empty") else syphonfull = false Stealfuelstring = Lang:t("menu_syphon_allowed") end -- Disable Options based on item data
else
if not itemData.info.gasamount then nogas = true Nogasstring = Lang:t("menu_syphon_empty") end
if itemData.info.gasamount < 1 then nogas = true Nogasstring = Lang:t("menu_syphon_empty") else nogas = false Nogasstring = Lang:t("menu_syphon_refuel") end
if itemData.info.gasamount == Config.SyphonKitCap then syphonfull = true Stealfuelstring = Lang:t("menu_syphon_kit_full") elseif GetFuel(vehicle) < 1 then syphonfull = true Stealfuelstring = Lang:t("menu_syphon_vehicle_empty") else syphonfull = false Stealfuelstring = Lang:t("menu_syphon_allowed") end -- Disable Options based on item data
end
if Config.Ox.Menu then
lib.registerContext({
id = 'syphoningmenu',
title = 'Syphoning Kit',
options = {
{
title = Lang:t("menu_syphon_header"),
description = Stealfuelstring,
icon = "fas fa-fire-flame-simple",
arrow = false, -- puts arrow to the right
event = 'cdn-syphoning:syphon',
args = {
itemData = itemData,
reason = "syphon",
},
disabled = syphonfull,
},
{
title = Lang:t("menu_syphon_refuel_header"),
description = Nogasstring,
icon = "fas fa-gas-pump",
arrow = false, -- puts arrow to the right
event = 'cdn-syphoning:syphon',
args = {
itemData = itemData,
reason = "refuel",
},
disabled = nogas,
},
{
title = Lang:t("menu_header_close"),
description = Lang:t("menu_refuel_cancel"),
icon = "fas fa-times-circle",
arrow = false, -- puts arrow to the right
onSelect = function()
lib.hideContext()
end,
},
},
})
lib.showContext('syphoningmenu')
else
exports['qb-menu']:openMenu({
{
header = "Syphoning Kit",
isMenuHeader = true,
},
{
header = Lang:t("menu_syphon_header"),
txt = Stealfuelstring,
params = {
event = "cdn-syphoning:syphon",
args = {
itemData = itemData,
reason = "syphon",
},
},
icon = "fas fa-fire-flame-simple",
disabled = syphonfull,
},
{
header = Lang:t("menu_syphon_refuel_header"),
txt = Nogasstring,
icon = "fas fa-gas-pump",
params = {
event = "cdn-syphoning:syphon",
args = {
itemData = itemData,
reason = "refuel",
},
},
disabled = nogas,
},
{
header = Lang:t("menu_header_close"),
txt = Lang:t("menu_syphon_cancel"),
icon = "fas fa-times-circle",
params = {
event = "qb-menu:closeMenu",
}
},
})
end
end
end)
RegisterNetEvent('cdn-syphoning:syphon', function(data)
local reason = data.reason
local ped = PlayerPedId()
if Config.SyphonDebug then print('Item Data Syphon: ' .. json.encode(data.itemData)) end
if Config.SyphonDebug then print('Reason: ' .. reason) end
local vehicle = GetClosestVehicle()
local NotElectric = false
if Config.ElectricVehicleCharging then
local isElectric = GetCurrentVehicleType(vehicle)
if isElectric == 'electricvehicle' then
QBCore.Functions.Notify(Lang:t("need_electric_charger"), 'error', 7500) return
end
NotElectric = true
else
NotElectric = true
end
Wait(50)
if NotElectric then
local currentsyphonamount = nil
if Config.Ox.Inventory then
currentsyphonamount = tonumber(data.itemData.metadata.cdn_fuel)
HasSyphon = exports.ox_inventory:Search('count', 'syphoningkit')
else
currentsyphonamount = data.itemData.info.gasamount or 0
HasSyphon = QBCore.Functions.HasItem("syphoningkit", 1)
end
if HasSyphon then
local fitamount = (Config.SyphonKitCap - currentsyphonamount)
local vehicle = GetClosestVehicle()
local vehiclecoords = GetEntityCoords(vehicle)
local pedcoords = GetEntityCoords(ped)
if #(vehiclecoords - pedcoords) > 2.5 then return end
local cargasamount = GetFuel(vehicle)
local maxsyphon = math.floor(GetFuel(vehicle))
if Config.SyphonKitCap <= 100 then
if maxsyphon > Config.SyphonKitCap then
maxsyphon = Config.SyphonKitCap
end
end
if maxsyphon >= fitamount then
Stealstring = fitamount
else
Stealstring = maxsyphon
end
if reason == "syphon" then
if Config.Ox.Input then
syphon = lib.inputDialog('Begin Syphoning', {{ type = "number", label = "You can steal " .. Stealstring .. "L from the car.", default = Stealstring }})
if not syphon then return end
syphonAmount = tonumber(syphon[1])
if syphon then
if not syphonAmount then return end
if tonumber(syphonAmount) < 0 then QBCore.Functions.Notify(Lang:t("syphon_more_than_zero"), 'error') return end
if tonumber(syphonAmount) == 0 then QBCore.Functions.Notify(Lang:t("syphon_more_than_zero"), 'error') return end
if tonumber(syphonAmount) > maxsyphon then QBCore.Functions.Notify(Lang:t("syphon_kit_cannot_fit_1").. fitamount .. Lang:t("syphon_kit_cannot_fit_2"), 'error') return end
if currentsyphonamount + syphonAmount > Config.SyphonKitCap then QBCore.Functions.Notify(Lang:t("syphon_kit_cannot_fit_1").. fitamount .. Lang:t("syphon_kit_cannot_fit_2"), 'error') return end
if (tonumber(syphonAmount) <= tonumber(cargasamount)) then
local removeamount = (tonumber(cargasamount) - tonumber(syphonAmount))
local syphontimer = Config.RefuelTime * syphonAmount
if tonumber(syphonAmount) < 10 then syphontimer = Config.RefuelTime * 10 end
if lib.progressCircle({
duration = syphontimer,
label = Lang:t("prog_syphoning"),
position = 'bottom',
useWhileDead = false,
canCancel = true,
disable = {
car = true,
move = true,
combat = true
},
anim = {
dict = Config.StealAnimDict,
clip = Config.StealAnim
},
}) then
StopAnimTask(ped, Config.StealAnimDict, Config.StealAnim, 1.0)
if GetFuel(vehicle) >= syphonAmount then
PoliceAlert(GetEntityCoords(ped))
QBCore.Functions.Notify(Lang:t("syphon_success"), 'success')
SetFuel(vehicle, removeamount)
local syphonData = data.itemData
local srcPlayerData = QBCore.Functions.GetPlayerData()
TriggerServerEvent('cdn-fuel:info', "add", tonumber(syphonAmount), srcPlayerData, syphonData)
else
QBCore.Functions.Notify(Lang:t("menu_syphon_vehicle_empty"), 'error')
end
else
PoliceAlert(GetEntityCoords(ped))
StopAnimTask(ped, Config.StealAnimDict, Config.StealAnim, 1.0)
QBCore.Functions.Notify(Lang:t("cancelled"), 'error')
end
end
end
else
local syphon = exports['qb-input']:ShowInput({
header = "Select how much gas to steal.",
submitText = "Begin Syphoning",
inputs = {
{
type = 'number',
isRequired = true,
name = 'amount',
text = 'You can steal ' .. Stealstring .. 'L from the car.'
}
}
})
if syphon then
if not syphon.amount then return end
if tonumber(syphon.amount) < 0 then QBCore.Functions.Notify(Lang:t("syphon_more_than_zero"), 'error') return end
if tonumber(syphon.amount) == 0 then QBCore.Functions.Notify(Lang:t("syphon_more_than_zero"), 'error') return end
if tonumber(syphon.amount) > maxsyphon then QBCore.Functions.Notify(Lang:t("syphon_kit_cannot_fit_1").. fitamount .. Lang:t("syphon_kit_cannot_fit_2"), 'error') return end
if currentsyphonamount + syphon.amount > Config.SyphonKitCap then QBCore.Functions.Notify(Lang:t("syphon_kit_cannot_fit_1").. fitamount .. Lang:t("syphon_kit_cannot_fit_2"), 'error') return end
if (tonumber(syphon.amount) <= tonumber(cargasamount)) then
local removeamount = (tonumber(cargasamount) - tonumber(syphon.amount))
local syphontimer = Config.RefuelTime * syphon.amount
if tonumber(syphon.amount) < 10 then syphontimer = Config.RefuelTime * 10 end
QBCore.Functions.Progressbar('syphon_gas', Lang:t("prog_syphoning"), syphontimer, false, true, { -- Name | Label | Time | useWhileDead | canCancel
disableMovement = true,
disableCarMovement = true,
disableMouse = false,
disableCombat = true,
}, {
animDict = Config.StealAnimDict,
anim = Config.StealAnim,
flags = 1,
}, {}, {}, function() -- Play When Done
if GetFuel(vehicle) >= tonumber(syphon.amount) then
PoliceAlert(GetEntityCoords(ped))
QBCore.Functions.Notify(Lang:t("syphon_success"), 'success')
SetFuel(vehicle, removeamount)
local syphonData = data.itemData
local srcPlayerData = QBCore.Functions.GetPlayerData()
TriggerServerEvent('cdn-fuel:info', "add", tonumber(syphon.amount), srcPlayerData, syphonData)
StopAnimTask(ped, Config.StealAnimDict, Config.StealAnim, 1.0)
else
QBCore.Functions.Notify(Lang:t("menu_syphon_vehicle_empty"), 'error')
end
end, function() -- Play When Cancel
PoliceAlert(GetEntityCoords(ped))
StopAnimTask(ped, Config.StealAnimDict, Config.StealAnim, 1.0)
QBCore.Functions.Notify(Lang:t("cancelled"), 'error')
end, "syphoningkit")
end
end
end
elseif reason == "refuel" then
if 100 - math.ceil(cargasamount) < Config.SyphonKitCap then
Maxrefuel = 100 - math.ceil(cargasamount)
if Maxrefuel > currentsyphonamount then Maxrefuel = currentsyphonamount end
else
Maxrefuel = currentsyphonamount
end
if Config.Ox.Input then
refuel = lib.inputDialog(Lang:t("input_select_refuel_header"), {{ type = "number", label = Lang:t("input_max_fuel_footer_1") .. Maxrefuel .. Lang:t("input_max_fuel_footer_2"), default = Maxrefuel }})
if not refuel then return end
refuelAmount = tonumber(refuel[1])
if refuel then
if tonumber(refuelAmount) == 0 then QBCore.Functions.Notify(Lang:t("more_than_zero"), 'error') return elseif tonumber(refuelAmount) < 0 then QBCore.Functions.Notify(Lang:t("more_than_zero"), 'error') return elseif tonumber(refuelAmount) > 100 then QBCore.Functions.Notify("You can't refuel more than 100L!", 'error') return end
if tonumber(refuelAmount) > tonumber(currentsyphonamount) then QBCore.Functions.Notify(Lang:t("syphon_not_enough_gas"), 'error') return end
if tonumber(refuelAmount) + tonumber(cargasamount) > 100 then QBCore.Functions.Notify(Lang:t("tank_cannot_fit"), 'error') return end
local refueltimer = Config.RefuelTime * tonumber(refuelAmount)
if tonumber(refuelAmount) < 10 then refueltimer = Config.RefuelTime * 10 end
if lib.progressCircle({
duration = refueltimer,
label = Lang:t("prog_refueling_vehicle"),
position = 'bottom',
useWhileDead = false,
canCancel = true,
disable = {
car = true,
move = true,
combat = true
},
anim = {
dict = Config.JerryCanAnimDict,
clip = Config.JerryCanAnim
},
}) then
StopAnimTask(ped, Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0)
QBCore.Functions.Notify(Lang:t("syphon_success_vehicle"), 'success')
SetFuel(vehicle, cargasamount + tonumber(refuelAmount))
local syphonData = data.itemData
local srcPlayerData = QBCore.Functions.GetPlayerData()
TriggerServerEvent('cdn-fuel:info', "remove", tonumber(refuelAmount), srcPlayerData, syphonData)
else
StopAnimTask(ped, Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0)
QBCore.Functions.Notify(Lang:t("cancelled"), 'error')
end
end
else
local refuel = exports['qb-input']:ShowInput({
header = Lang:t("input_select_refuel_header"),
submitText = Lang:t("input_refuel_submit"),
inputs = {
{
type = 'number',
isRequired = true,
name = 'amount',
text = Lang:t("input_max_fuel_footer_1") .. Maxrefuel .. Lang:t("input_max_fuel_footer_2")
}
}
})
if refuel then
if tonumber(refuel.amount) == 0 then QBCore.Functions.Notify(Lang:t("more_than_zero"), 'error') return elseif tonumber(refuel.amount) < 0 then QBCore.Functions.Notify(Lang:t("more_than_zero"), 'error') return elseif tonumber(refuel.amount) > 100 then QBCore.Functions.Notify("You can't refuel more than 100L!", 'error') return end
if tonumber(refuel.amount) > tonumber(currentsyphonamount) then QBCore.Functions.Notify(Lang:t("syphon_not_enough_gas"), 'error') return end
if tonumber(refuel.amount) + tonumber(cargasamount) > 100 then QBCore.Functions.Notify(Lang:t("tank_cannot_fit"), 'error') return end
local refueltimer = Config.RefuelTime * tonumber(refuel.amount)
if tonumber(refuel.amount) < 10 then refueltimer = Config.RefuelTime * 10 end
QBCore.Functions.Progressbar('refuel_gas', Lang:t("prog_refueling_vehicle"), refueltimer, false, true, { -- Name | Label | Time | useWhileDead | canCancel
disableMovement = true,
disableCarMovement = true,
disableMouse = false,
disableCombat = true,
}, {
animDict = Config.JerryCanAnimDict,
anim = Config.JerryCanAnim,
flags = 17,
}, {}, {}, function() -- Play When Done
StopAnimTask(ped, Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0)
QBCore.Functions.Notify(Lang:t("syphon_success_vehicle"), 'success')
SetFuel(vehicle, cargasamount + tonumber(refuel.amount))
local syphonData = data.itemData
local srcPlayerData = QBCore.Functions.GetPlayerData()
TriggerServerEvent('cdn-fuel:info', "remove", tonumber(refuel.amount), srcPlayerData, syphonData)
end, function() -- Play When Cancel
StopAnimTask(ped, Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0)
QBCore.Functions.Notify(Lang:t("cancelled"), 'error')
end, "syphoningkit")
end
end
end
else
QBCore.Functions.Notify(Lang:t("syphon_no_syphon_kit"), 'error', 7500)
end
else
QBCore.Functions.Notify(Lang:t("need_electric_charger"), 'error', 7500) return
end
end)
RegisterNetEvent('cdn-syphoning:client:callcops', function(coords)
local PlayerJob = QBCore.Functions.GetPlayerData().job
if PlayerJob.name ~= "police" or not PlayerJob.onduty then return end
local transG = 250
local blip = AddBlipForCoord(coords.x, coords.y, coords.z)
SetBlipSprite(blip, 648)
SetBlipColour(blip, 17)
SetBlipDisplay(blip, 4)
SetBlipAlpha(blip, transG)
SetBlipScale(blip, 1.2)
SetBlipFlashes(blip, true)
BeginTextCommandSetBlipName('STRING')
AddTextComponentString(Lang:t("syphon_dispatch_string"))
EndTextCommandSetBlipName(blip)
while transG ~= 0 do
Wait(180 * 4)
transG = transG - 1
SetBlipAlpha(blip, transG)
if transG == 0 then
SetBlipSprite(blip, 2)
RemoveBlip(blip)
return
end
end
end)
-- Helicopter Fueling --
RegisterNetEvent('cdn-fuel:client:grabnozzle:special', function()
local ped = PlayerPedId()
if HoldingSpecialNozzle then return end
LoadAnimDict("anim@am_hold_up@male")
TaskPlayAnim(ped, "anim@am_hold_up@male", "shoplift_high", 2.0, 8.0, -1, 50, 0, 0, 0, 0)
TriggerServerEvent("InteractSound_SV:PlayOnSource", "pickupnozzle", 0.4)
Wait(300)
StopAnimTask(ped, "anim@am_hold_up@male", "shoplift_high", 1.0)
SpecialFuelNozzleObj = CreateObject(joaat('prop_cs_fuel_nozle'), 1.0, 1.0, 1.0, true, true, false)
local lefthand = GetPedBoneIndex(ped, 18905)
AttachEntityToEntity(SpecialFuelNozzleObj, ped, lefthand, 0.13, 0.04, 0.01, -42.0, -115.0, -63.42, 0, 1, 0, 1, 0, 1)
local grabbednozzlecoords = GetEntityCoords(ped)
HoldingSpecialNozzle = true
QBCore.Functions.Notify(Lang:t("show_input_key_special"))
if Config.PumpHose then
local pumpCoords, pump = GetClosestPump(grabbednozzlecoords)
-- Load Rope Textures
RopeLoadTextures()
while not RopeAreTexturesLoaded() do
Wait(0)
RopeLoadTextures()
end
-- Wait for Pump to exist.
while not pump do
Wait(0)
end
Rope = AddRope(pumpCoords.x, pumpCoords.y, pumpCoords.z + 2.0, 0.0, 0.0, 0.0, 3.0, Config.RopeType['fuel'], 8.0 --[[ DO NOT SET THIS TO 0.0!!! GAME WILL CRASH!]], 0.0, 1.0, false, false, false, 1.0, true)
while not Rope do
Wait(0)
end
ActivatePhysics(Rope)
Wait(100)
local nozzlePos = GetEntityCoords(SpecialFuelNozzleObj)
if Config.FuelDebug then print("NOZZLE POS ".. nozzlePos) end
nozzlePos = GetOffsetFromEntityInWorldCoords(SpecialFuelNozzleObj, 0.0, -0.033, -0.195)
AttachEntitiesToRope(Rope, pump, SpecialFuelNozzleObj, pumpCoords.x, pumpCoords.y, pumpCoords.z + 2.1, nozzlePos.x, nozzlePos.y, nozzlePos.z, length, false, false, nil, nil)
if Config.FuelDebug then
print("Hose Properties:")
print(Rope, pump, SpecialFuelNozzleObj, pumpCoords.x, pumpCoords.y, pumpCoords.z, nozzlePos.x, nozzlePos.y, nozzlePos.z, length)
SetEntityDrawOutline(SpecialFuelNozzleObj --[[ Entity ]], true --[[ boolean ]])
end
end
CreateThread(function()
while HoldingSpecialNozzle do
local currentcoords = GetEntityCoords(ped)
local dist = #(grabbednozzlecoords - currentcoords)
TargetCreated = true
if dist > Config.AirAndWaterVehicleFueling['nozzle_length'] or IsPedInAnyVehicle(ped, false) then
HoldingSpecialNozzle = false
DeleteObject(SpecialFuelNozzleObj)
QBCore.Functions.Notify(Lang:t("nozzle_cannot_reach"), 'error')
if Config.PumpHose then
if Config.FuelDebug then print("Deleting Rope: "..tostring(Rope)) end
RopeUnloadTextures()
DeleteRope(Rope)
end
if Config.FuelNozzleExplosion then
AddExplosion(grabbednozzlecoords.x, grabbednozzlecoords.y, grabbednozzlecoords.z, 'EXP_TAG_PROPANE', 1.0, true,false, 5.0)
StartScriptFire(grabbednozzlecoords.x, grabbednozzlecoords.y, grabbednozzlecoords.z - 1,25,false)
SetFireSpreadRate(10.0)
Wait(5000)
StopFireInRange(grabbednozzlecoords.x, grabbednozzlecoords.y, grabbednozzlecoords.z - 1, 3.0)
end
end
Wait(2500)
end
end)
end)
RegisterNetEvent('cdn-fuel:client:returnnozzle:special', function()
HoldingSpecialNozzle = false
TriggerServerEvent("InteractSound_SV:PlayOnSource", "putbacknozzle", 0.4)
Wait(250)
DeleteObject(SpecialFuelNozzleObj)
if Config.PumpHose then
if Config.FuelDebug then print("Removing Hose.") end
RopeUnloadTextures()
DeleteRope(Rope)
end
end)
local AirSeaFuelZones = {}
local vehicle = nil
-- Create Polyzones with In-Out functions for handling fueling --
AddEventHandler('onResourceStart', function(resource)
if resource == GetCurrentResourceName() then
if LocalPlayer.state['isLoggedIn'] then
for i = 1, #Config.AirAndWaterVehicleFueling['locations'], 1 do
local currentLocation = Config.AirAndWaterVehicleFueling['locations'][i]
local k = #AirSeaFuelZones+1
local GeneratedName = "air_sea_fuel_zone_"..k
AirSeaFuelZones[k] = {} -- Make a new table inside of the Vehicle Pullout Zones representing this zone.
-- Get Coords for Zone from Config.
AirSeaFuelZones[k].zoneCoords = currentLocation['PolyZone']['coords']
-- Grab MinZ & MaxZ from Config.
local minimumZ, maximumZ = currentLocation['PolyZone']['minmax']['min'], currentLocation['PolyZone']['minmax']['max']
-- Create Zone
AirSeaFuelZones[k].PolyZone = PolyZone:Create(AirSeaFuelZones[k].zoneCoords, {
name = GeneratedName,
minZ = minimumZ,
maxZ = maximumZ,
debugPoly = Config.PolyDebug
})
AirSeaFuelZones[k].name = GeneratedName
-- Setup onPlayerInOut Events for zone that is created.
AirSeaFuelZones[k].PolyZone:onPlayerInOut(function(isPointInside)
if isPointInside then
local canUseThisStation = false
if Config.AirAndWaterVehicleFueling['locations'][i]['whitelist']['enabled'] then
local whitelisted_jobs = Config.AirAndWaterVehicleFueling['locations'][i]['whitelist']['whitelisted_jobs']
local plyJob = QBCore.Functions.GetPlayerData().job
if Config.FuelDebug then
print("Player Job: "..plyJob.name.." Is on Duty?: "..json.encode(plyJob.onduty))
end
if type(whitelisted_jobs) == "table" then
for i = 1, #whitelisted_jobs, 1 do
if plyJob.name == whitelisted_jobs[i] then
if Config.AirAndWaterVehicleFueling['locations'][i]['whitelist']['on_duty_only'] then
if plyJob.onduty == true then
canUseThisStation = true
else
canUseThisStation = false
end
else
canUseThisStation = true
end
end
end
end
else
canUseThisStation = true
end
if canUseThisStation then
-- Inside
PlayerInSpecialFuelZone = true
inGasStation = true
RefuelingType = 'special'
local DrawText = Config.AirAndWaterVehicleFueling['locations'][i]['draw_text']
if Config.Ox.DrawText then
lib.showTextUI(DrawText, {
position = 'left-center'
})
else
exports[Config.Core]:DrawText(DrawText, 'left')
end
CreateThread(function()
while PlayerInSpecialFuelZone do
Wait(3000)
vehicle = GetClosestVehicle()
end
end)
CreateThread(function()
while PlayerInSpecialFuelZone do
Wait(0)
if PlayerInSpecialFuelZone ~= true then
break
end
if IsControlJustReleased(0, Config.AirAndWaterVehicleFueling['refuel_button']) --[[ Control in Config ]] then
local vehCoords = GetEntityCoords(vehicle)
local dist = #(GetEntityCoords(PlayerPedId()) - vehCoords)
if not HoldingSpecialNozzle then
QBCore.Functions.Notify(Lang:t("no_nozzle"), 'error', 1250)
elseif dist > 4.5 then
QBCore.Functions.Notify(Lang:t("vehicle_too_far"), 'error', 1250)
elseif IsPedInAnyVehicle(PlayerPedId(), true) then
QBCore.Functions.Notify(Lang:t("inside_vehicle"), 'error', 1250)
else
if Config.FuelDebug then print("Attempting to Open Fuel menu for special vehicles.") end
TriggerEvent('cdn-fuel:client:RefuelMenu', 'special')
end
end
end
end)
if Config.FuelDebug then
print('Player has entered the Heli or Plane Refuel Zone: ('..GeneratedName..')')
end
end
else
if HoldingSpecialNozzle then
QBCore.Functions.Notify(Lang:t("nozzle_cannot_reach"), 'error')
HoldingSpecialNozzle = false
if Config.PumpHose then
if Config.FuelDebug then
print("Deleting Rope: "..Rope)
end
RopeUnloadTextures()
DeleteObject(Rope)
end
DeleteObject(SpecialFuelNozzleObj)
end
if Config.PumpHose then
if Rope ~= nil then
if Config.FuelDebug then
print("Deleting Rope: "..Rope)
end
RopeUnloadTextures()
DeleteObject(Rope)
end
end
-- Outside
if Config.Ox.DrawText then
lib.hideTextUI()
else
exports[Config.Core]:HideText()
end
PlayerInSpecialFuelZone = false
inGasStation = false
RefuelingType = nil
if Config.FuelDebug then
print('Player has exited the Heli or Plane Refuel Zone: ('..GeneratedName..')')
end
end
end)
if currentLocation['prop'] then
local model = currentLocation['prop']['model']
local modelCoords = currentLocation['prop']['coords']
local heading = modelCoords[4] - 180.0
AirSeaFuelZones[k].prop = CreateObject(model, modelCoords.x, modelCoords.y, modelCoords.z, false, true, true)
if Config.FuelDebug then print("Created Special Pump from Location #"..i) end
SetEntityHeading(AirSeaFuelZones[k].prop, heading)
FreezeEntityPosition(AirSeaFuelZones[k].prop, 1)
else
if Config.FuelDebug then print("Location #"..i.." for Special Fueling Zones (Air and Sea) doesn't have a prop set up, so players cannot fuel here.") end
end
if Config.FuelDebug then
print("Created Location: "..GeneratedName)
end
end
end
end
end)
AddEventHandler("QBCore:Client:OnPlayerLoaded", function ()
for i = 1, #Config.AirAndWaterVehicleFueling['locations'], 1 do
local currentLocation = Config.AirAndWaterVehicleFueling['locations'][i]
local k = #AirSeaFuelZones+1
local GeneratedName = "air_sea_fuel_zone_"..k
AirSeaFuelZones[k] = {} -- Make a new table inside of the Vehicle Pullout Zones representing this zone.
-- Get Coords for Zone from Config.
AirSeaFuelZones[k].zoneCoords = currentLocation['PolyZone']['coords']
-- Grab MinZ & MaxZ from Config.
local minimumZ, maximumZ = currentLocation['PolyZone']['minmax']['min'], currentLocation['PolyZone']['minmax']['max']
-- Create Zone
AirSeaFuelZones[k].PolyZone = PolyZone:Create(AirSeaFuelZones[k].zoneCoords, {
name = GeneratedName,
minZ = minimumZ,
maxZ = maximumZ,
debugPoly = Config.PolyDebug
})
AirSeaFuelZones[k].name = GeneratedName
-- Setup onPlayerInOut Events for zone that is created.
AirSeaFuelZones[k].PolyZone:onPlayerInOut(function(isPointInside)
if isPointInside then
local canUseThisStation = false
if Config.AirAndWaterVehicleFueling['locations'][i]['whitelist']['enabled'] then
local whitelisted_jobs = Config.AirAndWaterVehicleFueling['locations'][i]['whitelist']['whitelisted_jobs']
local plyJob = QBCore.Functions.GetPlayerData().job
if Config.FuelDebug then
print("Player Job: "..plyJob.name.." Is on Duty?: "..json.encode(plyJob.onduty))
end
if type(whitelisted_jobs) == "table" then
for i = 1, #whitelisted_jobs, 1 do
if plyJob.name == whitelisted_jobs[i] then
if Config.AirAndWaterVehicleFueling['locations'][i]['whitelist']['on_duty_only'] then
if plyJob.onduty == true then
canUseThisStation = true
else
canUseThisStation = false
end
else
canUseThisStation = true
end
end
end
end
else
canUseThisStation = true
end
if canUseThisStation then
-- Inside
PlayerInSpecialFuelZone = true
inGasStation = true
RefuelingType = 'special'
local DrawText = Config.AirAndWaterVehicleFueling['locations'][i]['draw_text']
if Config.Ox.DrawText then
lib.showTextUI(DrawText, {
position = 'left-center'
})
else
exports[Config.Core]:DrawText(DrawText, 'left')
end
CreateThread(function()
while PlayerInSpecialFuelZone do
Wait(3000)
vehicle = GetClosestVehicle()
end
end)
CreateThread(function()
while PlayerInSpecialFuelZone do
Wait(0)
if PlayerInSpecialFuelZone ~= true then
break
end
if IsControlJustReleased(0, Config.AirAndWaterVehicleFueling['refuel_button']) --[[ Control in Config ]] then
local vehCoords = GetEntityCoords(vehicle)
local dist = #(GetEntityCoords(PlayerPedId()) - vehCoords)
if not HoldingSpecialNozzle then
QBCore.Functions.Notify(Lang:t("no_nozzle"), 'error', 1250)
elseif dist > 4.5 then
QBCore.Functions.Notify(Lang:t("vehicle_too_far"), 'error', 1250)
elseif IsPedInAnyVehicle(PlayerPedId(), true) then
QBCore.Functions.Notify(Lang:t("inside_vehicle"), 'error', 1250)
else
if Config.FuelDebug then print("Attempting to Open Fuel menu for special vehicles.") end
TriggerEvent('cdn-fuel:client:RefuelMenu', 'special')
end
end
end
end)
if Config.FuelDebug then
print('Player has entered the Heli or Plane Refuel Zone: ('..GeneratedName..')')
end
end
else
if HoldingSpecialNozzle then
QBCore.Functions.Notify(Lang:t("nozzle_cannot_reach"), 'error')
HoldingSpecialNozzle = false
if Config.PumpHose then
if Config.FuelDebug then
print("Deleting Rope: "..Rope)
end
RopeUnloadTextures()
DeleteObject(Rope)
end
DeleteObject(SpecialFuelNozzleObj)
end
if Config.PumpHose then
if Rope ~= nil then
if Config.FuelDebug then
print("Deleting Rope: "..Rope)
end
RopeUnloadTextures()
DeleteObject(Rope)
end
end
-- Outside
if Config.Ox.DrawText then
lib.hideTextUI()
else
exports[Config.Core]:HideText()
end
PlayerInSpecialFuelZone = false
inGasStation = false
RefuelingType = nil
if Config.FuelDebug then
print('Player has exited the Heli or Plane Refuel Zone: ('..GeneratedName..')')
end
end
end)
if currentLocation['prop'] then
local model = currentLocation['prop']['model']
local modelCoords = currentLocation['prop']['coords']
local heading = modelCoords[4] - 180.0
AirSeaFuelZones[k].prop = CreateObject(model, modelCoords.x, modelCoords.y, modelCoords.z, false, true, true)
if Config.FuelDebug then print("Created Special Pump from Location #"..i) end
SetEntityHeading(AirSeaFuelZones[k].prop, heading)
FreezeEntityPosition(AirSeaFuelZones[k].prop, 1)
else
if Config.FuelDebug then print("Location #"..i.." for Special Fueling Zones (Air and Sea) doesn't have a prop set up, so players cannot fuel here.") end
end
if Config.FuelDebug then
print("Created Location: "..GeneratedName)
end
end
end)
AddEventHandler("QBCore:Client:OnPlayerUnload", function()
for i = 1, #AirSeaFuelZones, 1 do
AirSeaFuelZones[i].PolyZone:destroy()
if Config.FuelDebug then
print("Destroying Air Fuel PolyZone: "..AirSeaFuelZones[i].name)
end
if AirSeaFuelZones[i].prop then
if Config.FuelDebug then
print("Destroying Air Fuel Zone Pump: "..i)
end
DeleteObject(AirSeaFuelZones[i].prop)
end
end
end)
AddEventHandler('onResourceStop', function(resource)
if resource == GetCurrentResourceName() then
for i = 1, #AirSeaFuelZones, 1 do
DeleteObject(AirSeaFuelZones[i].prop)
end
end
end)
CreateThread(function()
local bones = {
"petroltank",
"petroltank_l",
"petroltank_r",
"wheel_rf",
"wheel_rr",
"petrolcap ",
"seat_dside_r",
"engine",
}
if Config.TargetResource == 'qb-target' then
local options = {
[1] = {
name = 'cdn-fuel:options:1',
icon = "fas fa-gas-pump",
label = tostring(Lang:t("input_insert_nozzle")),
canInteract = function()
if inGasStation and not refueling and holdingnozzle then
return true
end
end,
event = 'cdn-fuel:client:RefuelMenu'
},
[2] = {
name = 'cdn-fuel:options:2',
icon = "fas fa-bolt",
label = tostring(Lang:t("insert_electric_nozzle")),
canInteract = function()
if Config.ElectricVehicleCharging == true then
if inGasStation and not refueling and IsHoldingElectricNozzle() then
return true
else
return false
end
else
return false
end
end,
event = "cdn-fuel:client:electric:RefuelMenu",
}
}
exports.qb-target:addGlobalVehicle(options)
local modelOptions = {
[1] = {
name = "cdn-fuel:modelOptions:option_1",
num = 1,
type = "client",
event = "cdn-fuel:client:grabnozzle",
icon = "fas fa-gas-pump",
label = Lang:t("grab_nozzle"),
canInteract = function()
if PlayerInSpecialFuelZone then return false end
if not IsPedInAnyVehicle(PlayerPedId()) and not holdingnozzle and not HoldingSpecialNozzle and inGasStation == true and not PlayerInSpecialFuelZone then
return true
end
end,
},
[2] = {
name = "cdn-fuel:modelOptions:option_2",
num = 2,
type = "client",
event = "cdn-fuel:client:purchasejerrycan",
icon = "fas fa-fire-flame-simple",
label = Lang:t("buy_jerrycan"),
canInteract = function()
if not IsPedInAnyVehicle(PlayerPedId()) and not holdingnozzle and not HoldingSpecialNozzle and inGasStation == true then
return true
end
end,
},
[3] = {
name = "cdn-fuel:modelOptions:option_3",
num = 3,
type = "client",
event = "cdn-fuel:client:returnnozzle",
icon = "fas fa-hand",
label = Lang:t("return_nozzle"),
canInteract = function()
if holdingnozzle and not refueling then
return true
end
end,
},
[4] = {
name = "cdn-fuel:modelOptions:option_4",
num = 4,
type = "client",
event = "cdn-fuel:client:grabnozzle:special",
icon = "fas fa-gas-pump",
label = Lang:t("grab_special_nozzle"),
canInteract = function()
if Config.FuelDebug then print("Is Player In Special Fuel Zone?: "..tostring(PlayerInSpecialFuelZone)) end
if not HoldingSpecialNozzle and not IsPedInAnyVehicle(PlayerPedId()) and PlayerInSpecialFuelZone then
return true
end
end,
},
[5] = {
name = "cdn-fuel:modelOptions:option_5",
num = 5,
type = "client",
event = "cdn-fuel:client:returnnozzle:special",
icon = "fas fa-hand",
label = Lang:t("return_special_nozzle"),
canInteract = function()
if HoldingSpecialNozzle and not IsPedInAnyVehicle(PlayerPedId()) then
return true
end
end
},
}
exports.qb-target:addModel(props, modelOptions)
else
exports[Config.TargetResource]:AddTargetBone(bones, {
options = {
{
type = "client",
action = function ()
TriggerEvent('cdn-fuel:client:RefuelMenu')
end,
icon = "fas fa-gas-pump",
label = Lang:t("input_insert_nozzle"),
canInteract = function()
if inGasStation and not refueling and holdingnozzle then
return true
end
end
},
{
type = "client",
action = function()
TriggerEvent('cdn-fuel:client:electric:RefuelMenu')
end,
icon = "fas fa-bolt",
label = Lang:t("insert_electric_nozzle"),
canInteract = function()
if Config.ElectricVehicleCharging == true then
if inGasStation and not refueling and IsHoldingElectricNozzle() then
return true
else
return false
end
else
return false
end
end
},
},
distance = 1.5,
})
exports[Config.TargetResource]:AddTargetModel(props, {
options = {
{
num = 1,
type = "client",
event = "cdn-fuel:client:grabnozzle",
icon = "fas fa-gas-pump",
label = Lang:t("grab_nozzle"),
canInteract = function()
if PlayerInSpecialFuelZone then return false end
if not IsPedInAnyVehicle(PlayerPedId()) and not holdingnozzle and not HoldingSpecialNozzle and inGasStation == true and not PlayerInSpecialFuelZone then
return true
end
end,
},
{
num = 2,
type = "client",
event = "cdn-fuel:client:purchasejerrycan",
icon = "fas fa-fire-flame-simple",
label = Lang:t("buy_jerrycan"),
canInteract = function()
if not IsPedInAnyVehicle(PlayerPedId()) and not holdingnozzle and not HoldingSpecialNozzle and inGasStation == true then
return true
end
end,
},
{
num = 3,
type = "client",
event = "cdn-fuel:client:returnnozzle",
icon = "fas fa-hand",
label = Lang:t("return_nozzle"),
canInteract = function()
if holdingnozzle and not refueling then
return true
end
end,
},
{
num = 4,
type = "client",
event = "cdn-fuel:client:grabnozzle:special",
icon = "fas fa-gas-pump",
label = Lang:t("grab_special_nozzle"),
canInteract = function()
if Config.FuelDebug then print("Is Player In Special Fuel Zone?: "..tostring(PlayerInSpecialFuelZone)) end
if not HoldingSpecialNozzle and not IsPedInAnyVehicle(PlayerPedId()) and PlayerInSpecialFuelZone then
return true
end
end,
},
{
num = 5,
type = "client",
event = "cdn-fuel:client:returnnozzle:special",
icon = "fas fa-hand",
label = Lang:t("return_special_nozzle"),
canInteract = function()
if HoldingSpecialNozzle and not IsPedInAnyVehicle(PlayerPedId()) then
return true
end
end
},
},
distance = 2.0
})
end
end)
CreateThread(function()
while true do
Wait(3000)
local vehPedIsIn = GetVehiclePedIsIn(PlayerPedId(), false)
if not vehPedIsIn or vehPedIsIn == 0 then
Wait(2500)
if inBlacklisted then
inBlacklisted = false
end
else
local vehType = GetCurrentVehicleType(vehPedIsIn)
if not Config.ElectricVehicleCharging and vehType == 'electricvehicle' then
if Config.FuelDebug then
print("Vehicle Type is Electric, so we will not remove shut the engine off.")
end
else
if not IsVehicleBlacklisted(vehPedIsIn) then
local vehFuelLevel = GetFuel(vehPedIsIn)
local vehFuelShutoffLevel = Config.VehicleShutoffOnLowFuel['shutOffLevel'] or 1
if vehFuelLevel <= vehFuelShutoffLevel then
if GetIsVehicleEngineRunning(vehPedIsIn) then
if Config.FuelDebug then
print("Vehicle is running with zero fuel, shutting it down.")
end
-- If the vehicle is on, we shut the vehicle off:
SetVehicleEngineOn(vehPedIsIn, false, true, true)
-- Then alert the client with notify.
QBCore.Functions.Notify(Lang:t("no_fuel"), 'error', 3500)
-- Play Sound, if enabled in config.
if Config.VehicleShutoffOnLowFuel['sounds']['enabled'] then
RequestAmbientAudioBank("DLC_PILOT_ENGINE_FAILURE_SOUNDS", 0)
PlaySoundFromEntity(l_2613, "Landing_Tone", vehPedIsIn, "DLC_PILOT_ENGINE_FAILURE_SOUNDS", 0, 0)
Wait(1500)
StopSound(l_2613)
end
end
else
if vehFuelLevel - 10 > vehFuelShutoffLevel then
Wait(7500)
end
end
end
end
end
end
end)
if Config.VehicleShutoffOnLowFuel['shutOffLevel'] == 0 then
Config.VehicleShutoffOnLowFuel['shutOffLevel'] = 0.55
end
-- This loop does use quite a bit of performance, but,
-- is needed due to electric vehicles running without fuel & normal vehicles driving backwards!
-- You can remove if you need the performance, but we believe it is very important.
CreateThread(function()
while true do
Wait(0)
local ped = PlayerPedId()
local veh = GetVehiclePedIsIn(ped, false)
if veh ~= 0 and veh ~= nil then
if not IsVehicleBlacklisted(veh) then
-- Check if we are below the threshold for the Fuel Shutoff Level, if so, disable the "W" key, if not, enable it again.
if IsPedInVehicle(ped, veh, false) and (GetIsVehicleEngineRunning(veh) == false) or GetFuel(veh) < (Config.VehicleShutoffOnLowFuel['shutOffLevel'] or 1) then
DisableControlAction(0, 71, true)
elseif IsPedInVehicle(ped, veh, false) and (GetIsVehicleEngineRunning(veh) == true) and GetFuel(veh) > (Config.VehicleShutoffOnLowFuel['shutOffLevel'] or 1) then
EnableControlAction(0, 71, true)
end
-- Now, we check if the fuel level is currently 5 above the level it should shut off,
-- if this is true, we will then enable the "W" key if currently disabled, and then,
-- we will add a 5 second wait, in order to reduce system impact.
if GetFuel(veh) > (Config.VehicleShutoffOnLowFuel['shutOffLevel'] + 5) then
if not IsControlEnabled(0, 71) then
-- Enable "W" Key if it is currently disabled.
EnableControlAction(0, 71, true)
end
Wait(5000)
end
end
else
-- 1.75 Second Cooldown if the player is not inside of a vehicle.
Wait(1750)
end
end
end) Write, Run & Share Lua code online using OneCompiler's Lua online compiler for free. It's one of the robust, feature-rich online compilers for Lua language, running the latest Lua version 5.4. Getting started with the OneCompiler's Lua editor is easy and fast. The editor shows sample boilerplate code when you choose language as Lua and start coding.
OneCompiler's Lua online editor supports stdin and users can give inputs to programs using the STDIN textbox under the I/O tab. Following is a sample Lua program which takes name as input and prints hello message with your name.
name = io.read("*a")
print ("Hello ", name)
Lua is a light weight embeddable scripting language which is built on top of C. It is used in almost all kind of applications like games, web applications, mobile applications, image processing etc. It's a very powerful, fast, easy to learn, open-source scripting language.
-- global variables
a = 10
-- local variables
local x = 30
| Value Type | Description |
|---|---|
| number | Represents numbers |
| string | Represents text |
| nil | Differentiates values whether it has data or not |
| boolean | Value can be either true or false |
| function | Represents a sub-routine |
| userdata | Represents arbitary C data |
| thread | Represents independent threads of execution. |
| table | Can hold any value except nil |
While is also used to iterate a set of statements based on a condition. Usually while is preferred when number of iterations are not known in advance.
while(condition)
do
--code
end
Repeat-Until is also used to iterate a set of statements based on a condition. It is very similar to Do-While, it is mostly used when you need to execute the statements atleast once.
repeat
--code
until( condition )
For loop is used to iterate a set of statements based on a condition.
for init,max/min value, increment
do
--code
end
Function is a sub-routine which contains set of statements. Usually functions are written when multiple calls are required to same set of statements which increase re-usuability and modularity.
optional_function_scope function function_name( argument1, argument2, argument3........, argumentn)
--code
return params with comma seperated
end