Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"Lua.diagnostics.disable": [
"undefined-global"
]
}
50 changes: 38 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,41 @@
<p align="center">
<img src="https://user-images.githubusercontent.com/86536434/193705940-4a974196-6135-4950-b068-9f4de8e9d2f5.png" />
</p>
<p align='center'><b><a href="https://youtu.be/3YGlEahLZKY">Preview Video</a></b>
# dsco_fuel

## Features:
* Nozzle & hose
* Pump UI
* Customize fuel consumption
* Purchase and refill Jerry Can
## 🌟 Preview / Vista previa

## Need support?
[![Need Support?](https://user-images.githubusercontent.com/86536434/147299047-73691b78-2690-4786-b58b-27d24e48a0d2.png)](https://discord.gg/Z9Mxu72zZ6)
![Preview Image / Imagen de vista previa](preview.png)
[Preview Video / Video de Previsualización](https://streamable.com/c8zixn)

<a href="https://youtu.be/3YGlEahLZKY"><img src="https://forum.cfx.re/uploads/default/original/4X/d/5/b/d5baf97a1adb1bcd992d457ad36a37c739de7d7c.jpeg" /></a>
## 🚀 Features / Características

- 🔥 **Realistic fuel system** with dynamic consumption. / **Sistema de combustible realista** con consumo dinámico.
- 🎨 **Modern UI** for a better user experience. / **Interfaz moderna** e intuitiva para una mejor experiencia de usuario.
- 🔄 **Compatibility with** `LegacyFuel` and `ND_Fuel` via *exports*. / **Compatibilidad con** `LegacyFuel` y `ND_Fuel` a través de *exports*.
- 🎭 **Realistic animations and props**, enhancing game immersion. / **Animaciones y props realistas**, mejorando la inmersión en el juego.
- 🛠️ **Fully compatible with** `ESX` and `QBCore`. / **Totalmente compatible con** `ESX` y `QBCore`.

## 📌 Compatibility / Compatibilidad

| Framework | Support / Soporte |
|------------|------------------|
| ESX | ✅ Yes / Sí |
| QBCore | ✅ Yes / Sí |
| LegacyFuel | ✅ Yes (exports) / Sí (exports) |
| ND_Fuel | ✅ Yes (exports) / Sí (exports) |

## 📢 Community & Support / Comunidad y soporte

Join our community for support, suggestions, and updates:
🔗 **Discord:** [Discord Link / Enlace de Discord](https://discord.gg/H4A38em9CR)

Únete a nuestra comunidad para soporte, sugerencias y actualizaciones:
🔗 **Discord:** [Enlace de Discord / Discord Link](https://discord.gg/H4A38em9CR)



## 📜 License / Licencia

This project is licensed under the **GNU General Public License v3.0**.
See the [LICENSE](LICENSE) file for details.

Este proyecto está licenciado bajo la **Licencia Pública General de GNU v3.0**.
Consulta el archivo [LICENSE](LICENSE) para más detalles.
13 changes: 13 additions & 0 deletions client/compat/LegacyFuel.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
local function exportHandler(exportName, func)
AddEventHandler(('__cfx_export_LegacyFuel_%s'):format(exportName), function(setCB)
setCB(func)
end)
end

exportHandler('GetFuel', function(vehicle)
return GetFuel(vehicle)
end)

exportHandler('SetFuel', function(vehicle, fuel)
SetFuel(vehicle, fuel)
end)
13 changes: 13 additions & 0 deletions client/compat/ND_Fuel.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
local function exportHandler(exportName, func)
AddEventHandler(('__cfx_export_ND_Fuel_%s'):format(exportName), function(setCB)
setCB(func)
end)
end

exportHandler('GetFuel', function(vehicle)
return GetFuel(vehicle)
end)

exportHandler('SetFuel', function(vehicle, fuel)
SetFuel(vehicle, fuel)
end)
295 changes: 295 additions & 0 deletions client/functions.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,295 @@
function GetFuel(vehicle)
if not DecorExistOn(vehicle, FUEL_DECOR) then
return GetVehicleFuelLevel(vehicle)
end
return DecorGetFloat(vehicle, FUEL_DECOR)
end

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

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

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

function LoadAnimDict(dict)
if not HasAnimDictLoaded(dict) then
RequestAnimDict(dict)
while not HasAnimDictLoaded(dict) do
Wait(1)
end
end
end

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

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

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(500)

-- Verificar que ped es válido
if not DoesEntityExist(ped) or IsEntityDead(ped) then
print("Error: ped no válido")
return
end

-- Crear la manguera
RequestModel("prop_cs_fuel_nozle")
while not HasModelLoaded("prop_cs_fuel_nozle") do
Wait(10)
end
Nozzle = CreateObject("prop_cs_fuel_nozle", 0, 0, 0, true, true, true)
SetModelAsNoLongerNeeded("prop_cs_fuel_nozle")

-- Verificar si el nozzle se creó correctamente
if not DoesEntityExist(Nozzle) then
print("Error: Nozzle no se pudo crear")
return
end

-- Adjuntar la manguera a la mano
AttachEntityToEntity(Nozzle, ped, GetPedBoneIndex(ped, 0x49D9), 0.11, 0.02, 0.02, -80.0, -90.0, 15.0, true, true, false, true, 1, true)

-- Cargar texturas de la cuerda con un pequeño delay extra
RopeLoadTextures()
while not RopeAreTexturesLoaded() do
Wait(0)
end
Wait(100)

-- Validar que el surtidor existe antes de crear la cuerda
if not pump or not pump.x or not pump.y or not pump.z then
print("Error: Datos del pump no válidos")
return
end

if not DoesEntityExist(pumpHandle) then
print("Error: pumpHandle no existe")
return
end

-- Crear la cuerda
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)

-- Verificar si la cuerda se creó correctamente
if not Rope or Rope == 0 then
print("Error: No se pudo crear la cuerda")
return
end

ActivatePhysics(Rope)
Wait(50)

-- Verificar que el Nozzle existe antes de adjuntar la cuerda
if not DoesEntityExist(Nozzle) then
print("Error: Nozzle no existe antes de adjuntar a la cuerda")
return
end

-- Obtener la posición del nozzle
local nozzlePos = GetOffsetFromEntityInWorldCoords(Nozzle, 0.0, -0.033, -0.195)

-- Depuración: imprimir coordenadas antes de adjuntar
print("Adjuntando cuerda desde", pump.x, pump.y, pump.z + 1.45, "hasta", nozzlePos.x, nozzlePos.y, nozzlePos.z)

-- Adjuntar la cuerda entre el surtidor y la manguera
AttachEntitiesToRope(Rope, pumpHandle, Nozzle, pump.x, pump.y, pump.z + 1.45, nozzlePos.x, nozzlePos.y, nozzlePos.z, 5.0, false, false, nil, nil)

-- Variables de control
NozzleDropped = false
HoldingNozzle = true
NozzleInVehicle = false
VehicleFueling = false
UsedPump = pumpHandle

-- Enviar actualización a la UI
SendNUIMessage({ type = "status", status = true })
SendNUIMessage({ type = "update", fuelCost = "0.00", fuelTank = "0.00" })
end


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

function PutNozzleInVehicle(vehicle, ptankBone, isBike, dontClear, newTankPosition)
if isBike then
AttachEntityToEntity(
Nozzle,
vehicle,
ptankBone,
0.0 + newTankPosition.x,
-0.2 + newTankPosition.y,
0.2 + newTankPosition.z,
-80.0,
0.0,
0.0,
true,
true,
false,
false,
1,
true
)
else
AttachEntityToEntity(
Nozzle,
vehicle,
ptankBone,
-0.18 + newTankPosition.x,
0.0 + newTankPosition.y,
0.75 + newTankPosition.z,
-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

function DropNozzle()
DetachEntity(Nozzle, true, true)
NozzleDropped = true
HoldingNozzle = false
NozzleInVehicle = false
VehicleFueling = false
SendNUIMessage(
{
type = "status",
status = false
}
)
end

function ReturnNozzleToPump()
DeleteEntity(Nozzle)
RopeUnloadTextures()
DeleteRope(Rope)
NozzleDropped = false
HoldingNozzle = false
NozzleInVehicle = false
VehicleFueling = false
SendNUIMessage(
{
type = "status",
status = false
}
)
end

function AddFuelToVehicle(vehicle, fuel)
if fuel < 0 then
fuel = 0
end
if fuel > 100 then
fuel = 100
end
if type(fuel) == "number" and fuel >= 0 and fuel <= 100 then
SetVehicleFuelLevel(vehicle, fuel + 0.0)
DecorSetFloat(vehicle, Config.FuelDecor, GetVehicleFuelLevel(vehicle))
end
end

function FuelingAnimation()
local ped = GetPlayerPed(-1)
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

exports("GetFuel", GetFuel)
exports("SetFuel", SetFuel)
Loading