mirror of
https://github.com/ND-Framework/ND_Core.git
synced 2026-08-18 22:36:03 +01:00
Fuel script
* Nozzle & hose * Pump UI * Customize fuel consumption * Purchase and refill Jerry Can
This commit is contained in:
97
ND_Fuel/config.lua
Normal file
97
ND_Fuel/config.lua
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
config = {
|
||||||
|
standalone = false, -- if you're using ND Framework keep this false. It will use your money and pay for gas.
|
||||||
|
jerryCanPrice = 100, -- jery cans can be purchased from the gas statoin.
|
||||||
|
jerryCanrefillCost = 50, -- The price of the jerrycans refill, this will be calculated and adjusted to how much is left in it.
|
||||||
|
fuelCostMultiplier = 1.0, -- 2.0 will double the price of fuel and 1.5 will increase it by half.
|
||||||
|
|
||||||
|
-- Class multipliers. If you want SUVs to use less fuel, you can change it to anything under 1.0, and vise versa.
|
||||||
|
vehicleClasses = {
|
||||||
|
[0] = 0.7, -- Compacts
|
||||||
|
[1] = 1.1, -- Sedans
|
||||||
|
[2] = 1.7, -- SUVs
|
||||||
|
[3] = 1.1, -- Coupes
|
||||||
|
[4] = 1.5, -- Muscle
|
||||||
|
[5] = 1.3, -- Sports Classics
|
||||||
|
[6] = 1.5, -- Sports
|
||||||
|
[7] = 1.5, -- Super
|
||||||
|
[8] = 0.6, -- Motorcycles
|
||||||
|
[9] = 1.2, -- Off-road
|
||||||
|
[10] = 1.0, -- Industrial
|
||||||
|
[11] = 1.0, -- Utility
|
||||||
|
[12] = 1.2, -- Vans
|
||||||
|
[13] = 0.0, -- Cycles
|
||||||
|
[14] = 1.0, -- Boats
|
||||||
|
[15] = 1.0, -- Helicopters
|
||||||
|
[16] = 1.0, -- Planes
|
||||||
|
[17] = 1.0, -- Service
|
||||||
|
[18] = 1.0, -- Emergency
|
||||||
|
[19] = 1.9, -- Military
|
||||||
|
[20] = 1.8, -- Commercial
|
||||||
|
[21] = 1.0, -- Trains
|
||||||
|
},
|
||||||
|
|
||||||
|
electricVehicles = {
|
||||||
|
`Imorgon`,
|
||||||
|
`Neon`,
|
||||||
|
`Raiden`,
|
||||||
|
`Cyclone`,
|
||||||
|
`Voltic`,
|
||||||
|
`Voltic2`,
|
||||||
|
`Tezeract`,
|
||||||
|
`Dilettante`,
|
||||||
|
`Dilettante2`,
|
||||||
|
`Airtug`,
|
||||||
|
`Caddy`,
|
||||||
|
`Caddy2`,
|
||||||
|
`Caddy3`,
|
||||||
|
`Surge`,
|
||||||
|
`Khamelion`,
|
||||||
|
`RCBandito`
|
||||||
|
},
|
||||||
|
|
||||||
|
blipLocations = {
|
||||||
|
vector3(49.4187, 2778.793, 58.043),
|
||||||
|
vector3(263.894, 2606.463, 44.983),
|
||||||
|
vector3(1039.958, 2671.134, 39.550),
|
||||||
|
vector3(1207.260, 2660.175, 37.899),
|
||||||
|
vector3(2539.685, 2594.192, 37.944),
|
||||||
|
vector3(2679.858, 3263.946, 55.240),
|
||||||
|
vector3(2005.055, 3773.887, 32.403),
|
||||||
|
vector3(1687.156, 4929.392, 42.078),
|
||||||
|
vector3(1701.314, 6416.028, 32.763),
|
||||||
|
vector3(179.857, 6602.839, 31.868),
|
||||||
|
vector3(-94.4619, 6419.594, 31.489),
|
||||||
|
vector3(-2554.996, 2334.40, 33.078),
|
||||||
|
vector3(-1800.375, 803.661, 138.651),
|
||||||
|
vector3(-1437.622, -276.747, 46.207),
|
||||||
|
vector3(-2096.243, -320.286, 13.168),
|
||||||
|
vector3(-724.619, -935.1631, 19.213),
|
||||||
|
vector3(-526.019, -1211.003, 18.184),
|
||||||
|
vector3(-70.2148, -1761.792, 29.534),
|
||||||
|
vector3(265.648, -1261.309, 29.292),
|
||||||
|
vector3(819.653, -1028.846, 26.403),
|
||||||
|
vector3(1208.951, -1402.567,35.224),
|
||||||
|
vector3(1181.381, -330.847, 69.316),
|
||||||
|
vector3(620.843, 269.100, 103.089),
|
||||||
|
vector3(2581.321, 362.039, 108.468),
|
||||||
|
vector3(176.631, -1562.025, 29.263),
|
||||||
|
vector3(176.631, -1562.025, 29.263),
|
||||||
|
vector3(-319.292, -1471.715, 30.549),
|
||||||
|
vector3(1784.324, 3330.55, 41.253)
|
||||||
|
},
|
||||||
|
|
||||||
|
pumpModels = {
|
||||||
|
[-2007231801] = true,
|
||||||
|
[1339433404] = true,
|
||||||
|
[1694452750] = true,
|
||||||
|
[1933174915] = true,
|
||||||
|
[-462817101] = true,
|
||||||
|
[-469694731] = true,
|
||||||
|
[-164877493] = true
|
||||||
|
},
|
||||||
|
|
||||||
|
-- you can spawn pump here. Search up gta objects and then search pump.
|
||||||
|
addPumps = {
|
||||||
|
-- {hash = "prop_gas_pump_old2", x = 721.93, y = 1480.80, z = 5.06},
|
||||||
|
}
|
||||||
|
}
|
||||||
23
ND_Fuel/fxmanifest.lua
Normal file
23
ND_Fuel/fxmanifest.lua
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
-- For support join my discord: https://discord.gg/Z9Mxu72zZ6
|
||||||
|
|
||||||
|
author "Andyyy#7666, N1K0#0001"
|
||||||
|
description "ND Framework fuel with hose & nozle"
|
||||||
|
version "1.0.0"
|
||||||
|
|
||||||
|
fx_version "cerulean"
|
||||||
|
game "gta5"
|
||||||
|
lua54 "yes"
|
||||||
|
|
||||||
|
files {
|
||||||
|
"source/digital-counter-7.ttf",
|
||||||
|
"source/index.html"
|
||||||
|
}
|
||||||
|
ui_page "source/index.html"
|
||||||
|
|
||||||
|
shared_script "config.lua"
|
||||||
|
server_scripts {
|
||||||
|
"source/server.lua"
|
||||||
|
}
|
||||||
|
client_scripts {
|
||||||
|
"source/client.lua"
|
||||||
|
}
|
||||||
590
ND_Fuel/source/client.lua
Normal file
590
ND_Fuel/source/client.lua
Normal file
@@ -0,0 +1,590 @@
|
|||||||
|
local FUEL_DECOR = "_ANDY_FUEL_DECORE_"
|
||||||
|
local nozzleDropped = false
|
||||||
|
local holdingNozzle = false
|
||||||
|
local nozzleInVehicle = false
|
||||||
|
local nozzle
|
||||||
|
local rope
|
||||||
|
local vehicleFueling
|
||||||
|
local usedPump
|
||||||
|
local pumpCoords
|
||||||
|
local wastingFuel = false
|
||||||
|
local usingCan = false
|
||||||
|
|
||||||
|
-- Nozzle Z position based on vehicle class.
|
||||||
|
local nozzleBasedOnClass = {
|
||||||
|
0.65, -- Compacts
|
||||||
|
0.65, -- Sedans
|
||||||
|
0.85, -- SUVs
|
||||||
|
0.6, -- Coupes
|
||||||
|
0.55, -- Muscle
|
||||||
|
0.6, -- Sports Classics
|
||||||
|
0.6, -- Sports
|
||||||
|
0.55, -- Super
|
||||||
|
0.12, -- Motorcycles
|
||||||
|
0.8, -- Off-road
|
||||||
|
0.7, -- Industrial
|
||||||
|
0.6, -- Utility
|
||||||
|
0.7, -- Vans
|
||||||
|
0.0, -- Cycles
|
||||||
|
0.0, -- Boats
|
||||||
|
0.0, -- Helicopters
|
||||||
|
0.0, -- Planes
|
||||||
|
0.6, -- Service
|
||||||
|
0.65, -- Emergency
|
||||||
|
0.65, -- Military
|
||||||
|
0.75, -- Commercial
|
||||||
|
0.0 -- Trains
|
||||||
|
}
|
||||||
|
|
||||||
|
-- ND Core object.
|
||||||
|
if not config.standalone then
|
||||||
|
NDCore = exports["ND_Core"]:GetCoreObject()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Setting the electric vehicle config keys to hashes.
|
||||||
|
for _, vehHash in pairs(config.electricVehicles) do
|
||||||
|
config.electricVehicles[vehHash] = vehHash
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Get the fuel of a vehicle, which is set to an entity.
|
||||||
|
function GetFuel(vehicle)
|
||||||
|
if not DecorExistOn(vehicle, FUEL_DECOR) then
|
||||||
|
return GetVehicleFuelLevel(vehicle)
|
||||||
|
end
|
||||||
|
return DecorGetFloat(vehicle, FUEL_DECOR)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Setting the fuel to the vehicle entity using decor.
|
||||||
|
function SetFuel(vehicle, fuel)
|
||||||
|
if type(fuel) == "number" and fuel >= 0 and fuel <= 100 then
|
||||||
|
SetVehicleFuelLevel(vehicle, fuel)
|
||||||
|
DecorSetFloat(vehicle, FUEL_DECOR, GetVehicleFuelLevel(vehicle))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- returns pump position if a player is near it.
|
||||||
|
function nearPump(coords)
|
||||||
|
local entity = nil
|
||||||
|
for hash in pairs(config.pumpModels) do
|
||||||
|
entity = GetClosestObjectOfType(coords.x, coords.y, coords.z, 0.8, hash, true, true, true)
|
||||||
|
if entity ~= 0 then break end
|
||||||
|
end
|
||||||
|
if config.pumpModels[GetEntityModel(entity)] then
|
||||||
|
return GetEntityCoords(entity), entity
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Draws 3D text on coords.
|
||||||
|
function DrawText3D(x, y, z, text)
|
||||||
|
local onScreen, _x, _y = World3dToScreen2d(x, y, z)
|
||||||
|
local pX, pY, pZ = table.unpack(GetGameplayCamCoords())
|
||||||
|
SetTextScale(0.4, 0.4)
|
||||||
|
SetTextFont(4)
|
||||||
|
SetTextProportional(1)
|
||||||
|
SetTextEntry("STRING")
|
||||||
|
SetTextCentre(true)
|
||||||
|
SetTextColour(255, 255, 255, 255)
|
||||||
|
SetTextOutline()
|
||||||
|
AddTextComponentString(text)
|
||||||
|
DrawText(_x, _y)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- used to load the filling manually animation.
|
||||||
|
function LoadAnimDict(dict)
|
||||||
|
if not HasAnimDictLoaded(dict) then
|
||||||
|
RequestAnimDict(dict)
|
||||||
|
while not HasAnimDictLoaded(dict) do
|
||||||
|
Wait(1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Used to play the effect of pouring fuel from the nozzle.
|
||||||
|
function PlayEffect(pdict, pname)
|
||||||
|
CreateThread(function()
|
||||||
|
local position = GetOffsetFromEntityInWorldCoords(nozzle, 0.0, 0.28, 0.17)
|
||||||
|
UseParticleFxAssetNextCall(pdict)
|
||||||
|
local pfx = StartParticleFxLoopedAtCoord(pname, position.x, position.y, position.z, 0.0, 0.0, GetEntityHeading(nozzle), 1.0, false, false, false, false)
|
||||||
|
Wait(100)
|
||||||
|
StopParticleFxLooped(pfx, 0)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Getting the vehicle infront if the player.
|
||||||
|
function vehicleInFront()
|
||||||
|
local entity = nil
|
||||||
|
local offset = GetOffsetFromEntityInWorldCoords(ped, 0.0, 2.0, 0.0)
|
||||||
|
local rayHandle = CastRayPointToPoint(pedCoords.x, pedCoords.y, pedCoords.z - 1.3, offset.x, offset.y, offset.z, 10, ped, 0)
|
||||||
|
local A, B, C, D, entity = GetRaycastResult(rayHandle)
|
||||||
|
if IsEntityAVehicle(entity) then
|
||||||
|
return entity
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Create nozzle, rope and attach them to the player.
|
||||||
|
function grabNozzleFromPump()
|
||||||
|
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)
|
||||||
|
Wait(300)
|
||||||
|
nozzle = CreateObject(`prop_cs_fuel_nozle`, 0, 0, 0, true, true, true)
|
||||||
|
AttachEntityToEntity(nozzle, ped, GetPedBoneIndex(ped, 0x49D9), 0.11, 0.02, 0.02, -80.0, -90.0, 15.0, true, true, false, true, 1, true)
|
||||||
|
RopeLoadTextures()
|
||||||
|
while not RopeAreTexturesLoaded() do
|
||||||
|
Wait(0)
|
||||||
|
end
|
||||||
|
RopeLoadTextures()
|
||||||
|
while not pump do
|
||||||
|
Wait(0)
|
||||||
|
end
|
||||||
|
rope = AddRope(pump.x, pump.y, pump.z, 0.0, 0.0, 0.0, 3.0, 1, 1000.0, 0.0, 1.0, false, false, false, 1.0, true)
|
||||||
|
while not rope do
|
||||||
|
Wait(0)
|
||||||
|
end
|
||||||
|
ActivatePhysics(rope)
|
||||||
|
local nozzlePos = GetEntityCoords(nozzle)
|
||||||
|
nozzlePos = GetOffsetFromEntityInWorldCoords(nozzle, 0.0, -0.033, -0.195)
|
||||||
|
AttachEntitiesToRope(rope, pumpHandle, nozzle, pump.x, pump.y, pump.z + 1.45, nozzlePos.x, nozzlePos.y, nozzlePos.z, 5.0, false, false, nil, nil)
|
||||||
|
nozzleDropped = false
|
||||||
|
holdingNozzle = true
|
||||||
|
nozzleInVehicle = false
|
||||||
|
vehicleFueling = false
|
||||||
|
usedPump = pumpHandle
|
||||||
|
SendNUIMessage({
|
||||||
|
type = "status",
|
||||||
|
status = true
|
||||||
|
})
|
||||||
|
SendNUIMessage({
|
||||||
|
type = "update",
|
||||||
|
fuelCost = "0.00",
|
||||||
|
fuelTank = "0.00"
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
-- attach the nozzle to the player.
|
||||||
|
function grabExistingNozzle()
|
||||||
|
AttachEntityToEntity(nozzle, ped, GetPedBoneIndex(ped, 0x49D9), 0.11, 0.02, 0.02, -80.0, -90.0, 15.0, true, true, false, true, 1, true)
|
||||||
|
nozzleDropped = false
|
||||||
|
holdingNozzle = true
|
||||||
|
nozzleInVehicle = false
|
||||||
|
vehicleFueling = false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- attach nozzle to vehicle.
|
||||||
|
function putNozzleInVehicle(vehicle, ptankBone, isBike, dontClear)
|
||||||
|
if isBike then
|
||||||
|
AttachEntityToEntity(nozzle, vehicle, ptankBone, 0.0, -0.2, 0.2, -80.0, 0.0, 0.0, true, true, false, false, 1, true)
|
||||||
|
else
|
||||||
|
AttachEntityToEntity(nozzle, vehicle, ptankBone, -0.23, 0.0, 0.6, -125.0, -90.0, -90.0, true, true, false, false, 1, true)
|
||||||
|
end
|
||||||
|
if not dontClear and IsEntityPlayingAnim(ped, "timetable@gardener@filling_can", "gar_ig_5_filling_can", 3) then
|
||||||
|
ClearPedTasks(ped)
|
||||||
|
end
|
||||||
|
nozzleDropped = false
|
||||||
|
holdingNozzle = false
|
||||||
|
nozzleInVehicle = true
|
||||||
|
wastingFuel = false
|
||||||
|
vehicleFueling = vehicle
|
||||||
|
end
|
||||||
|
|
||||||
|
-- detach nozzle from everything and hide ui.
|
||||||
|
function dropNozzle()
|
||||||
|
DetachEntity(nozzle, true, true)
|
||||||
|
nozzleDropped = true
|
||||||
|
holdingNozzle = false
|
||||||
|
nozzleInVehicle = false
|
||||||
|
vehicleFueling = false
|
||||||
|
SendNUIMessage({
|
||||||
|
type = "status",
|
||||||
|
status = false
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
-- delete nozzle and rope, and hide ui.
|
||||||
|
function returnNozzleToPump()
|
||||||
|
DeleteEntity(nozzle)
|
||||||
|
RopeUnloadTextures()
|
||||||
|
DeleteRope(rope)
|
||||||
|
nozzleDropped = false
|
||||||
|
holdingNozzle = false
|
||||||
|
nozzleInVehicle = false
|
||||||
|
vehicleFueling = false
|
||||||
|
SendNUIMessage({
|
||||||
|
type = "status",
|
||||||
|
status = false
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Get important information.
|
||||||
|
CreateThread(function()
|
||||||
|
while true do
|
||||||
|
ped = PlayerPedId()
|
||||||
|
pedCoords = GetEntityCoords(ped)
|
||||||
|
pump, pumpHandle = nearPump(pedCoords)
|
||||||
|
veh = GetVehiclePedIsIn(ped, true)
|
||||||
|
Wait(500)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- Refuel the vehicle.
|
||||||
|
CreateThread(function()
|
||||||
|
while true do
|
||||||
|
Wait(2000)
|
||||||
|
if vehicleFueling then
|
||||||
|
local classMultiplier = config.vehicleClasses[GetVehicleClass(vehicleFueling)]
|
||||||
|
if usingCan then
|
||||||
|
while usingCan do
|
||||||
|
local fuel = GetFuel(vehicleFueling)
|
||||||
|
if fuel < 97 then
|
||||||
|
SetFuel(vehicleFueling, fuel + (2.5 / classMultiplier))
|
||||||
|
else
|
||||||
|
fuel = 100.0
|
||||||
|
SetFuel(vehicleFueling, fuel)
|
||||||
|
vehicleFueling = false
|
||||||
|
end
|
||||||
|
Wait(500)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local cost = 0
|
||||||
|
while vehicleFueling do
|
||||||
|
local fuel = GetFuel(vehicleFueling)
|
||||||
|
if not DoesEntityExist(vehicleFueling) then
|
||||||
|
dropNozzle()
|
||||||
|
break
|
||||||
|
end
|
||||||
|
fuel = GetFuel(vehicleFueling)
|
||||||
|
cost = cost + ((2.0 / classMultiplier) * config.fuelCostMultiplier) - math.random(0, 100) / 100
|
||||||
|
if not config.standalone then
|
||||||
|
if NDCore.Functions.GetSelectedCharacter().bank < cost then
|
||||||
|
SendNUIMessage({
|
||||||
|
type = "warn"
|
||||||
|
})
|
||||||
|
vehicleFueling = false
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if fuel < 97 then
|
||||||
|
SetFuel(vehicleFueling, fuel + ((2.0 / classMultiplier) - math.random(0, 100) / 100))
|
||||||
|
else
|
||||||
|
cost = 0
|
||||||
|
fuel = 100.0
|
||||||
|
SetFuel(vehicleFueling, fuel)
|
||||||
|
vehicleFueling = false
|
||||||
|
end
|
||||||
|
SendNUIMessage({
|
||||||
|
type = "update",
|
||||||
|
fuelCost = string.format("%.2f", cost),
|
||||||
|
fuelTank = string.format("%.2f", fuel)
|
||||||
|
})
|
||||||
|
Wait(600)
|
||||||
|
end
|
||||||
|
if not config.standalone and cost ~= 0 then
|
||||||
|
TriggerServerEvent("ND_Fuel:pay", cost)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- pumping fuel on the groud.
|
||||||
|
CreateThread(function()
|
||||||
|
while true do
|
||||||
|
Wait(500)
|
||||||
|
if wastingFuel then
|
||||||
|
local cost = 0
|
||||||
|
while wastingFuel do
|
||||||
|
cost = cost + (2.0 * config.fuelCostMultiplier) - math.random(0, 100) / 100
|
||||||
|
SendNUIMessage({
|
||||||
|
type = "update",
|
||||||
|
fuelCost = string.format("%.2f", cost),
|
||||||
|
fuelTank = "0.0"
|
||||||
|
})
|
||||||
|
if not config.standalone then
|
||||||
|
if NDCore.Functions.GetSelectedCharacter().bank < cost then
|
||||||
|
SendNUIMessage({
|
||||||
|
type = "warn"
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
Wait(800)
|
||||||
|
end
|
||||||
|
if not config.standalone and cost ~= 0 then
|
||||||
|
TriggerServerEvent("ND_Fuel:pay", cost)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- Grabbing and returning the nozzle from the pump.
|
||||||
|
CreateThread(function()
|
||||||
|
local wait = 500
|
||||||
|
while true do
|
||||||
|
Wait(wait)
|
||||||
|
if pump then
|
||||||
|
wait = 0
|
||||||
|
if not holdingNozzle and not nozzleInVehicle and not nozzleDropped then
|
||||||
|
local jerryCanText = ""
|
||||||
|
local ammo = GetAmmoInPedWeapon(ped, 883325847)
|
||||||
|
local weapon = HasPedGotWeapon(ped, 883325847)
|
||||||
|
local price = config.jerryCanPrice
|
||||||
|
if not weapon then
|
||||||
|
jerryCanText = " \n$" .. price .. " buy Jerry Can [G]"
|
||||||
|
elseif weapon and GetSelectedPedWeapon(ped) == 883325847 and ammo < 4500 then
|
||||||
|
price = math.floor(config.jerryCanrefillCost - (config.jerryCanrefillCost / (4500 / ammo)))
|
||||||
|
jerryCanText = " \n$" .. price .. " refill Jerry Can [G]"
|
||||||
|
end
|
||||||
|
DrawText3D(pump.x, pump.y, pump.z + 1.2, "Grab Nozzle [E]" .. jerryCanText)
|
||||||
|
if IsControlJustPressed(0, 51) then
|
||||||
|
grabNozzleFromPump()
|
||||||
|
Wait(1000)
|
||||||
|
ClearPedTasks(ped)
|
||||||
|
end
|
||||||
|
if IsControlJustPressed(0, 47) then
|
||||||
|
if not config.standalone then
|
||||||
|
if NDCore.Functions.GetSelectedCharacter().bank > price then
|
||||||
|
TriggerServerEvent("ND_Fuel:jerryCan", price)
|
||||||
|
if HasPedGotWeapon(ped, 883325847) then
|
||||||
|
SetPedAmmo(ped, 883325847, 4500)
|
||||||
|
else
|
||||||
|
GiveWeaponToPed(ped, 883325847, 4500, false, true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if HasPedGotWeapon(ped, 883325847) then
|
||||||
|
SetPedAmmo(ped, 883325847, 4500)
|
||||||
|
else
|
||||||
|
GiveWeaponToPed(ped, 883325847, 4500, false, true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif holdingNozzle and pumpHandle == usedPump then
|
||||||
|
DrawText3D(pump.x, pump.y, pump.z + 1.2, "Return Nozzle [E]")
|
||||||
|
if IsControlJustPressed(0, 51) then
|
||||||
|
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)
|
||||||
|
Wait(300)
|
||||||
|
returnNozzleToPump()
|
||||||
|
Wait(1000)
|
||||||
|
ClearPedTasks(ped)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
wait = 500
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- Attaching and taking the nozzle form the vehicle, and dropping the nozzle form the player or vehicle.
|
||||||
|
CreateThread(function()
|
||||||
|
local wait = 500
|
||||||
|
while true do
|
||||||
|
Wait(wait)
|
||||||
|
if holdingNozzle or nozzleInVehicle or nozzleDropped then
|
||||||
|
wait = 0
|
||||||
|
|
||||||
|
-- drop the nozzle and remove it if it's far away from the pump.
|
||||||
|
if pump then
|
||||||
|
pumpCoords = GetEntityCoords(usedPump)
|
||||||
|
end
|
||||||
|
if nozzle and pumpCoords then
|
||||||
|
nozzleLocation = GetEntityCoords(nozzle)
|
||||||
|
if #(pumpCoords - pedCoords) < 3.0 then
|
||||||
|
SendNUIMessage({
|
||||||
|
type = "status",
|
||||||
|
status = true
|
||||||
|
})
|
||||||
|
else
|
||||||
|
SendNUIMessage({
|
||||||
|
type = "status",
|
||||||
|
status = false
|
||||||
|
})
|
||||||
|
end
|
||||||
|
if #(nozzleLocation - pumpCoords) > 6.0 then
|
||||||
|
dropNozzle()
|
||||||
|
elseif #(pumpCoords - pedCoords) > 100.0 then
|
||||||
|
returnNozzleToPump()
|
||||||
|
end
|
||||||
|
if nozzleDropped and #(nozzleLocation - pedCoords) < 1.5 then
|
||||||
|
DrawText3D(nozzleLocation.x, nozzleLocation.y, nozzleLocation.z, "Grab Nozzle [E]")
|
||||||
|
if IsControlJustPressed(0, 51) then
|
||||||
|
LoadAnimDict("anim@mp_snowball")
|
||||||
|
TaskPlayAnim(ped, "anim@mp_snowball", "pickup_snowball", 2.0, 8.0, -1, 50, 0, 0, 0, 0)
|
||||||
|
Wait(700)
|
||||||
|
grabExistingNozzle()
|
||||||
|
ClearPedTasks(ped)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local veh = vehicleInFront(ped, pedCoords)
|
||||||
|
|
||||||
|
-- Animations for manually fueling and effect for sparying fuel.
|
||||||
|
if holdingNozzle and nozzle then
|
||||||
|
DisableControlAction(0, 25, true)
|
||||||
|
DisableControlAction(0, 24, true)
|
||||||
|
if IsDisabledControlPressed(0, 24) then
|
||||||
|
if veh and tankPosition and #(pedCoords - tankPosition) < 1.2 then
|
||||||
|
if not IsEntityPlayingAnim(ped, "timetable@gardener@filling_can", "gar_ig_5_filling_can", 3) then
|
||||||
|
LoadAnimDict("timetable@gardener@filling_can")
|
||||||
|
TaskPlayAnim(ped, "timetable@gardener@filling_can", "gar_ig_5_filling_can", 2.0, 8.0, -1, 50, 0, 0, 0, 0)
|
||||||
|
end
|
||||||
|
wastingFuel = false
|
||||||
|
vehicleFueling = veh
|
||||||
|
else
|
||||||
|
if IsEntityPlayingAnim(ped, "timetable@gardener@filling_can", "gar_ig_5_filling_can", 3) then
|
||||||
|
vehicleFueling = false
|
||||||
|
ClearPedTasks(ped)
|
||||||
|
end
|
||||||
|
if nozzleLocation then
|
||||||
|
wastingFuel = true
|
||||||
|
PlayEffect("core", "veh_trailer_petrol_spray")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if IsEntityPlayingAnim(ped, "timetable@gardener@filling_can", "gar_ig_5_filling_can", 3) then
|
||||||
|
vehicleFueling = false
|
||||||
|
ClearPedTasks(ped)
|
||||||
|
end
|
||||||
|
wastingFuel = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- attaching and taking the nozzle from the vehicle.
|
||||||
|
if veh then
|
||||||
|
local vehClass = GetVehicleClass(veh)
|
||||||
|
local zPos = nozzleBasedOnClass[vehClass + 1]
|
||||||
|
local isBike = false
|
||||||
|
|
||||||
|
if vehClass == 8 and vehClass ~= 13 and not config.electricVehicles[GetHashKey(veh)] then
|
||||||
|
tankBone = GetEntityBoneIndexByName(veh, "petroltank")
|
||||||
|
if tankBone == -1 then
|
||||||
|
tankBone = GetEntityBoneIndexByName(veh, "engine")
|
||||||
|
end
|
||||||
|
isBike = true
|
||||||
|
elseif vehClass ~= 13 and not config.electricVehicles[GetHashKey(veh)] then
|
||||||
|
tankBone = GetEntityBoneIndexByName(veh, "petroltank_l")
|
||||||
|
if tankBone == -1 then
|
||||||
|
tankBone = GetEntityBoneIndexByName(veh, "hub_lr")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
tankPosition = GetWorldPositionOfEntityBone(veh, tankBone)
|
||||||
|
if tankPosition and #(pedCoords - tankPosition) < 1.2 then
|
||||||
|
if not nozzleInVehicle and holdingNozzle then
|
||||||
|
DrawText3D(tankPosition.x, tankPosition.y, tankPosition.z + zPos, "Attach Nozzle [E]")
|
||||||
|
if IsControlJustPressed(0, 51) then
|
||||||
|
LoadAnimDict("timetable@gardener@filling_can")
|
||||||
|
TaskPlayAnim(ped, "timetable@gardener@filling_can", "gar_ig_5_filling_can", 2.0, 8.0, -1, 50, 0, 0, 0, 0)
|
||||||
|
Wait(300)
|
||||||
|
putNozzleInVehicle(veh, tankBone, isBike, true)
|
||||||
|
Wait(300)
|
||||||
|
ClearPedTasks(ped)
|
||||||
|
end
|
||||||
|
elseif nozzleInVehicle then
|
||||||
|
DrawText3D(tankPosition.x, tankPosition.y, tankPosition.z + zPos, "Grab Nozzle [E]")
|
||||||
|
if IsControlJustPressed(0, 51) then
|
||||||
|
LoadAnimDict("timetable@gardener@filling_can")
|
||||||
|
TaskPlayAnim(ped, "timetable@gardener@filling_can", "gar_ig_5_filling_can", 2.0, 8.0, -1, 50, 0, 0, 0, 0)
|
||||||
|
Wait(300)
|
||||||
|
grabExistingNozzle()
|
||||||
|
Wait(300)
|
||||||
|
ClearPedTasks(ped)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
wait = 500
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- refueling using jerry can.
|
||||||
|
CreateThread(function()
|
||||||
|
local wait = 500
|
||||||
|
while true do
|
||||||
|
Wait(wait)
|
||||||
|
if GetSelectedPedWeapon(ped) == 883325847 and not holdingNozzle and not nozzleInVehicle then
|
||||||
|
wait = 0
|
||||||
|
local veh = vehicleInFront(ped, pedCoords)
|
||||||
|
if veh then
|
||||||
|
local vehClass = GetVehicleClass(veh)
|
||||||
|
local zPos = nozzleBasedOnClass[vehClass + 1]
|
||||||
|
local can = GetAmmoInPedWeapon(ped, 883325847)
|
||||||
|
|
||||||
|
if vehClass == 8 and vehClass ~= 13 and not config.electricVehicles[GetHashKey(veh)] then
|
||||||
|
tankBone = GetEntityBoneIndexByName(veh, "petroltank")
|
||||||
|
if tankBone == -1 then
|
||||||
|
tankBone = GetEntityBoneIndexByName(veh, "engine")
|
||||||
|
end
|
||||||
|
elseif vehClass ~= 13 and not config.electricVehicles[GetHashKey(veh)] then
|
||||||
|
tankBone = GetEntityBoneIndexByName(veh, "petroltank_l")
|
||||||
|
if tankBone == -1 then
|
||||||
|
tankBone = GetEntityBoneIndexByName(veh, "hub_lr")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
tankPosition = GetWorldPositionOfEntityBone(veh, tankBone)
|
||||||
|
if tankPosition and #(pedCoords - tankPosition) < 1.2 then
|
||||||
|
local fuel = GetFuel(veh)
|
||||||
|
DrawText3D(tankPosition.x, tankPosition.y, tankPosition.z + zPos, math.floor(fuel) .. "% refuel [E]")
|
||||||
|
local ammo = GetAmmoInPedWeapon(ped, 883325847)
|
||||||
|
if IsControlPressed(0, 51) and ammo > 0 then
|
||||||
|
if not IsEntityPlayingAnim(ped, "timetable@gardener@filling_can", "gar_ig_5_filling_can", 3) then
|
||||||
|
LoadAnimDict("timetable@gardener@filling_can")
|
||||||
|
TaskPlayAnim(ped, "timetable@gardener@filling_can", "gar_ig_5_filling_can", 2.0, 8.0, -1, 50, 0, 0, 0, 0)
|
||||||
|
elseif can and DoesEntityExist(veh) then
|
||||||
|
SetPedAmmo(ped, 883325847, ammo - 3)
|
||||||
|
vehicleFueling = veh
|
||||||
|
usingCan = true
|
||||||
|
end
|
||||||
|
else
|
||||||
|
vehicleFueling = false
|
||||||
|
usingCan = false
|
||||||
|
if IsEntityPlayingAnim(ped, "timetable@gardener@filling_can", "gar_ig_5_filling_can", 3) then
|
||||||
|
ClearPedTasks(ped)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
wait = 500
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- Create blips for each gas station location.
|
||||||
|
CreateThread(function()
|
||||||
|
for _, coords in pairs(config.blipLocations) do
|
||||||
|
local blip = AddBlipForCoord(coords)
|
||||||
|
SetBlipSprite(blip, 361)
|
||||||
|
SetBlipScale(blip, 0.9)
|
||||||
|
SetBlipColour(blip, 4)
|
||||||
|
SetBlipDisplay(blip, 4)
|
||||||
|
SetBlipAsShortRange(blip, true)
|
||||||
|
BeginTextCommandSetBlipName("STRING")
|
||||||
|
AddTextComponentString("Gas Station")
|
||||||
|
EndTextCommandSetBlipName(blip)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- vehicle fuel consumption.
|
||||||
|
CreateThread(function()
|
||||||
|
while true do
|
||||||
|
Wait(3500)
|
||||||
|
local pedVeh = GetVehiclePedIsIn(ped)
|
||||||
|
if pedVeh ~= 0 then
|
||||||
|
local vehClass = GetVehicleClass(pedVeh)
|
||||||
|
local fuel = GetFuel(pedVeh)
|
||||||
|
if fuel < 5.0 and GetIsVehicleEngineRunning(pedVeh) then
|
||||||
|
DisableControlAction(0, 71)
|
||||||
|
SetVehicleEngineOn(pedVeh, false, true, true)
|
||||||
|
end
|
||||||
|
SetFuel(pedVeh, fuel - ((GetVehicleCurrentRpm(pedVeh) * config.vehicleClasses[vehClass]) / 1.7))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- spawn pumps on the map.
|
||||||
|
CreateThread(function()
|
||||||
|
for _, pumps in pairs(config.addPumps) do
|
||||||
|
CreateObject(GetHashKey(pumps.hash), pumps.x, pumps.y, pumps.z - 1.0, true, true, true)
|
||||||
|
end
|
||||||
|
end)
|
||||||
BIN
ND_Fuel/source/digital-counter-7.ttf
Normal file
BIN
ND_Fuel/source/digital-counter-7.ttf
Normal file
Binary file not shown.
115
ND_Fuel/source/index.html
Normal file
115
ND_Fuel/source/index.html
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<style>
|
||||||
|
@font-face {
|
||||||
|
font-family: "digital-counter-7";
|
||||||
|
src: url("digital-counter-7.ttf");
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.pumpDisplay {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
margin: auto;
|
||||||
|
right: 0;
|
||||||
|
left: 0;
|
||||||
|
bottom: 2%;
|
||||||
|
height: 15%;
|
||||||
|
width: auto;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
.displayBackground {
|
||||||
|
position: absolute;
|
||||||
|
margin: auto;
|
||||||
|
right: 0;
|
||||||
|
left: 0;
|
||||||
|
width: auto;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.fuelCurrency {
|
||||||
|
position: absolute;
|
||||||
|
margin: auto;
|
||||||
|
left: 45%;
|
||||||
|
top: 20%;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
font-family: "Lucida Console", "Courier New", monospace;
|
||||||
|
font-size: 4vh;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
.fuelCost {
|
||||||
|
position: absolute;
|
||||||
|
margin: auto;
|
||||||
|
right: 45.2%;
|
||||||
|
top: 18%;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
font-family: "digital-counter-7", sans-serif;
|
||||||
|
font-size: 4vh;
|
||||||
|
color: #060608;
|
||||||
|
}
|
||||||
|
.fuelPrecentage {
|
||||||
|
position: absolute;
|
||||||
|
margin: auto;
|
||||||
|
left: 45%;
|
||||||
|
top: 50%;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
font-family: "Lucida Console", "Courier New", monospace;
|
||||||
|
font-size: 4vh;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
.fuelTank {
|
||||||
|
position: absolute;
|
||||||
|
margin: auto;
|
||||||
|
right: 45.2%;
|
||||||
|
top: 48%;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
font-family: "digital-counter-7", sans-serif;
|
||||||
|
font-size: 4vh;
|
||||||
|
color: #060608;
|
||||||
|
}
|
||||||
|
@keyframes warn {
|
||||||
|
0% {color: red;}
|
||||||
|
50% {color: #ffffff;}
|
||||||
|
100% {color: red;}
|
||||||
|
}
|
||||||
|
.fuelCurrency.flashRed {
|
||||||
|
transition: 1s;
|
||||||
|
animation-name: warn;
|
||||||
|
animation-duration: 4s;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="pumpDisplay">
|
||||||
|
<img class="displayBackground" src="https://i.imgur.com/wkMX6FG.png">
|
||||||
|
<p class="fuelCurrency">$</p><p class="fuelCost">0.00</p>
|
||||||
|
<p class="fuelPrecentage">%</p><p class="fuelTank">0.00</p>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
window.addEventListener("message", function(event) {
|
||||||
|
const item = event.data;
|
||||||
|
if (item.type === "status") {
|
||||||
|
if (item.status) {
|
||||||
|
$(".pumpDisplay").fadeIn("fast");
|
||||||
|
} else {
|
||||||
|
$(".pumpDisplay").fadeOut("slow");
|
||||||
|
};
|
||||||
|
};
|
||||||
|
if (item.type === "update") {
|
||||||
|
$(".fuelCost").text(item.fuelCost);
|
||||||
|
$(".fuelTank").text(item.fuelTank);
|
||||||
|
};
|
||||||
|
if (item.type === "warn") {
|
||||||
|
$(".fuelCurrency").toggleClass("flashRed");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
20
ND_Fuel/source/server.lua
Normal file
20
ND_Fuel/source/server.lua
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
NDCore = exports["ND_Core"]:GetCoreObject()
|
||||||
|
-- NDCore.Functions.VersionChecker("ND_Fuel", GetCurrentResourceName(), "https://github.com/Andyyy7666/ND_Framework", "https://raw.githubusercontent.com/Andyyy7666/ND_Framework/main/ND_Fuel/fxmanifest.lua")
|
||||||
|
|
||||||
|
RegisterNetEvent("ND_Fuel:pay", function(amount)
|
||||||
|
local player = source
|
||||||
|
NDCore.Functions.DeductMoney(math.floor(amount), player, "bank")
|
||||||
|
TriggerClientEvent("chat:addMessage", player, {
|
||||||
|
color = {0, 255, 0},
|
||||||
|
args = {"Success", "Paid: $" .. string.format("%.2f", amount) .. " for gas."}
|
||||||
|
})
|
||||||
|
end)
|
||||||
|
|
||||||
|
RegisterNetEvent("ND_Fuel:jerryCan", function(amount)
|
||||||
|
local player = source
|
||||||
|
NDCore.Functions.DeductMoney(amount, player, "cash")
|
||||||
|
TriggerClientEvent("chat:addMessage", player, {
|
||||||
|
color = {0, 255, 0},
|
||||||
|
args = {"Success", "Paid: $" .. amount .. " for gas."}
|
||||||
|
})
|
||||||
|
end)
|
||||||
Reference in New Issue
Block a user