Scripts de combustible para FiveM: repostaje realista de vehículos
Añade combustible funcional a tu servidor FiveM. Gasolineras, bidones, vehículos eléctricos y los mejores scripts para QBCore, ESX y configuraciones standalone.
Agency Scripts
Fundador y desarrollador principal en Agency Scripts
Mecánicas de consumo de combustible
Un sistema de combustible realista añade una capa esencial de inmersión y crea un sumidero de dinero natural que ayuda a equilibrar la economía del servidor. La mecánica principal consiste en registrar el nivel de combustible de cada vehículo como un valor de coma flotante entre 0 y 100, que disminuye según la actividad del motor y la forma de conducir. Guarda el nivel de combustible mediante las bolsas de estado de la entidad con Entity(vehicle).state.fuel para que el valor persista en todos los clientes y se conserve cuando cambie la propiedad de red. Calcula la tasa de consumo en cada ciclo según las RPM actuales del vehículo obtenidas mediante GetVehicleCurrentRpm, la posición del acelerador de GetControlNormal, y el multiplicador de consumo específico de la clase del vehículo. Los deportivos y superdeportivos deben consumir combustible mucho más rápido que los vehículos económicos, mientras que los camiones y los SUV deben quedar en un punto intermedio. Aplica modificadores de consumo adicionales a estilos de conducción agresivos, como la aceleración rápida, las velocidades altas sostenidas y el freno motor. Cuando el combustible llegue a cero, reduce gradualmente la velocidad máxima del vehículo usando SetVehicleMaxSpeed para simular que el motor ratea en lugar de apagarlo al instante, lo que le da al jugador unos segundos cruciales para detenerse de forma segura.
-- Client-side fuel consumption thread
local fuelConsumptionRate = 0.0
CreateThread(function()
while true do
local ped = PlayerPedId()
local vehicle = GetVehiclePedIsIn(ped, false)
if vehicle ~= 0 and GetPedInVehicleSeat(vehicle, -1) == ped then
local engineOn = GetIsVehicleEngineRunning(vehicle)
if engineOn then
local rpm = GetVehicleCurrentRpm(vehicle)
local speed = GetEntitySpeed(vehicle) * 3.6 -- km/h
local classMultiplier = Config.ClassConsumption[GetVehicleClass(vehicle)] or 1.0
-- Base consumption + RPM factor + speed factor
fuelConsumptionRate = (Config.BaseConsumption
+ (rpm * Config.RpmFactor)
+ (speed * Config.SpeedFactor)
) * classMultiplier
local currentFuel = Entity(vehicle).state.fuel or 100.0
local newFuel = math.max(0.0, currentFuel - fuelConsumptionRate)
Entity(vehicle).state:set('fuel', newFuel, true)
-- Engine stall when empty
if newFuel <= 0 then
SetVehicleUndriveable(vehicle, true)
SetVehicleEngineOn(vehicle, false, true, true)
elseif newFuel <= 5.0 then
-- Sputtering effect
SetVehicleMaxSpeed(vehicle, 30.0 * (newFuel / 5.0))
end
end
end
Wait(1000) -- Update every second
end
end)
Interfaz de gasolinera y repostaje
La experiencia en la gasolinera debe ser refinada e intuitiva gracias a una interfaz NUI bien diseñada. Cuando un jugador estacione cerca de un surtidor dentro de un radio definido, muestra un aviso de interacción. Al interactuar, abre una interfaz de repostaje que muestre el nivel actual de combustible mediante un indicador o una barra de progreso, la capacidad del depósito del vehículo, el precio por litro según el tipo de combustible actual y las opciones para llenar el depósito o cargar una cantidad específica en dólares. La animación de repostaje debe reproducirse tanto en el personaje del jugador, que se coloca junto al vehículo con una manguera de combustible usando TaskPlayAnim, como en el surtidor si utilizas una configuración de objetos de utilería personalizada. El combustible debe ir llenando el depósito gradualmente en tiempo real, en lugar de pasar instantáneamente al máximo, para crear una breve espera que aporte realismo e impida que los jugadores reposten a toda velocidad durante persecuciones. Muestra el coste total, que se actualiza en tiempo real a medida que se carga el combustible, y descuenta el pago solo cuando el jugador deje de repostar o el depósito esté lleno. Admite varios tipos de combustible en las estaciones prémium: gasolina sin plomo regular a un precio estándar, gasolina prémium que ofrece una pequeña mejora de rendimiento y cuesta más, y diésel para camiones y vehículos industriales con surtidores separados.
Bidón de gasolina y repostaje de emergencia
Quedarse sin combustible en la autopista es una situación realista que el sistema debe gestionar correctamente, sin obligar al jugador a abandonar el vehículo. Implementa un artículo de bidón de gasolina que pueda comprarse en gasolineras o ferreterías y llenarse en cualquier surtidor. El bidón debe funcionar como un artículo utilizable del inventario, con metadatos que registren su nivel de llenado actual, normalmente con una capacidad de 10-20 litros. Cuando un jugador use un bidón cerca de un vehículo vacío, reproduce una animación de vertido y transfiere el combustible del bidón al depósito del vehículo. El bidón debe tener un peso en el sistema de inventario proporcional a la cantidad de combustible que contiene, de modo que uno lleno pese más que uno vacío. Añade una mecánica para llamar a asistencia en carretera mediante el teléfono del juego, que envíe un camión de remolque conducido por un NPC o por un jugador y ofrezca combustible a cambio de una tarifa. Para aumentar la inmersión, los jugadores deben poder extraer combustible de otros vehículos usando un tubo y transferirlo entre vehículos, a costa de tiempo y con el riesgo de que los descubran mientras lo hacen.
-- Jerry can usage handler
RegisterNetEvent('fuel:useJerryCan')
AddEventHandler('fuel:useJerryCan', function(slot)
local src = source
local ped = GetPlayerPed(src)
local coords = GetEntityCoords(ped)
-- Find nearest vehicle
local nearbyVehicle = GetClosestVehicle(coords, 3.0)
if not nearbyVehicle or nearbyVehicle == 0 then
return notify(src, 'No vehicle nearby.', 'error')
end
-- Get jerry can metadata
local canData = exports.ox_inventory:GetSlot(src, slot)
if not canData or not canData.metadata or not canData.metadata.fuel then
return notify(src, 'Jerry can is empty.', 'error')
end
local canFuel = canData.metadata.fuel
local vehicleFuel = Entity(nearbyVehicle).state.fuel or 0.0
local maxTransfer = math.min(canFuel, 100.0 - vehicleFuel)
if maxTransfer <= 0 then
return notify(src, 'Vehicle tank is already full.', 'error')
end
-- Transfer fuel
Entity(nearbyVehicle).state:set('fuel', vehicleFuel + maxTransfer, true)
-- Update jerry can metadata
local remainingFuel = canFuel - maxTransfer
if remainingFuel <= 0 then
exports.ox_inventory:SetMetadata(src, slot, { fuel = 0, label = 'Empty Jerry Can' })
else
exports.ox_inventory:SetMetadata(src, slot, { fuel = remainingFuel })
end
notify(src, ('Transferred %.1f liters to the vehicle.'):format(maxTransfer), 'success')
end)
Compatibilidad con vehículos eléctricos
Los servidores de roleplay modernos incluyen cada vez más vehículos eléctricos, que necesitan una infraestructura de carga paralela. Los vehículos eléctricos no deben consumir gasolina. En su lugar, deben agotar el nivel de carga de la batería, que funciona igual que el indicador de combustible, pero disminuye a otro ritmo. Los vehículos eléctricos deben consumir menos por kilómetro que los de gasolina, lo que refleja su ventaja de eficiencia en la vida real, pero la carga debe tardar más que el repostaje, creando un ritmo de juego diferente. Coloca estaciones de carga en ubicaciones concretas del mapa, no necesariamente en gasolineras tradicionales, para crear patrones de desplazamiento distintos para los propietarios de vehículos eléctricos. Implementa una interfaz de carga que muestre el porcentaje de carga actual, el tiempo estimado para cargar la batería por completo y el coste por kilovatio-hora. Añade una opción de carga rápida en estaciones prémium que cargue la batería en la mitad de tiempo y cueste el doble por unidad. En la configuración del vehículo, clasifica los vehículos eléctricos por el hash de su modelo y guarda el tipo de vehículo en tu configuración para que el sistema detecte automáticamente si necesita gasolina o electricidad. Admite vehículos híbridos que puedan usar ambos tipos de energía, cambiar al modo eléctrico a baja velocidad y a gasolina en autopista, y consumir ambos recursos a tasas individuales reducidas.
Economía de precios dinámicos del combustible
Un sistema de precios dinámicos hace que la economía del combustible parezca viva y crea decisiones económicas interesantes para los jugadores. Basa los precios del combustible en una tarifa configurable que fluctúe según la oferta y la demanda. Registra el total de combustible comprado en todas las estaciones durante periodos de tiempo consecutivos y, cuando el consumo sea elevado, aumenta gradualmente los precios. Cuando el consumo disminuya, reduce los precios para atraer a más clientes. Implementa precios específicos por estación: las estaciones remotas del condado de Blaine cobran más debido a los costes de transporte, mientras que las estaciones de la ciudad compiten con márgenes menores. Permite que los propietarios de gasolineras jugadores fijen sus propios precios dentro de un rango mínimo y máximo definido por la configuración del servidor, creando una competencia real entre operadores. El propietario compra combustible al por mayor a un NPC proveedor y le añade un margen para fijar el precio de venta. Ese margen de beneficio constituye sus ingresos. Añade subidas de precio estacionales o vinculadas a eventos, en las que el combustible se encarezca durante eventos del servidor con mucha actividad de vehículos, como carreras o atracos. Esto genera efectos económicos que afectan a todos los jugadores y los anima a ahorrar combustible o comprarlo estratégicamente antes de las subidas previstas.
Gasolinera como negocio
Convertir las gasolineras en negocios gestionados por jugadores añade un ciclo económico completo al sistema de combustible. El propietario gestiona las existencias encargando entregas de combustible a un proveedor mayorista, mantiene el equipo pagando las reparaciones y mejoras de los surtidores, y organiza el personal contratando a otros jugadores como empleados de surtidor con un salario por hora. Implementa un panel de gestión de la estación, accesible solo para el propietario, que muestre el volumen de ventas diario, los ingresos, los márgenes de beneficio, las existencias actuales de combustible en los depósitos subterráneos y los registros de asistencia de los empleados. La estación debe tener un depósito subterráneo físico con capacidad limitada, que se vaya vaciando a medida que los clientes reposten. El propietario tendrá que programar visitas de camiones de reparto, que tardarán en llegar y requerirán un pago por adelantado. Añade una tienda dentro de la estación donde el propietario pueda vender productos de conveniencia, como aperitivos, bebidas y artículos básicos, que los clientes puedan comprar junto con el combustible para generar una fuente adicional de ingresos. Permite mejorar la propia estación, por ejemplo, añadiendo más surtidores para atender a más clientes al mismo tiempo, instalando equipos de lavado de coches para ofrecer un servicio adicional de pago o añadiendo estaciones de carga para vehículos eléctricos y captar a ese mercado. Registra la reputación de cada estación según la justicia de sus precios, su disponibilidad y la satisfacción del cliente, para que las estaciones con mejor reputación aparezcan destacadas en el mapa y atraigan a más clientes.
Integración con el HUD e indicador de combustible
El indicador de combustible es un elemento permanente del HUD que los jugadores verán constantemente, por lo que debe ser limpio y discreto, a la vez que transmite información esencial de un vistazo. Diseña un indicador de combustible minimalista cerca del velocímetro o en una esquina de la pantalla, que muestre el nivel actual mediante un medidor semicircular, una barra vertical o un porcentaje sencillo. Usa colores: verde para indicar un nivel adecuado, por encima del 50%, amarillo para señalar un nivel moderado, entre 20-50%, y rojo para advertir de un nivel críticamente bajo, por debajo del 20%. Cuando el combustible baje del 15%, activa periódicamente un sonido de advertencia de nivel bajo y haz parpadear el indicador para que el jugador no se quede sin combustible por accidente. Muestra la distancia restante estimada según la tasa de consumo actual. Calcúlala dividiendo el combustible restante entre el consumo medio por kilómetro durante los últimos minutos de conducción. Oculta por completo el indicador cuando el jugador vaya a pie para reducir el exceso de elementos en el HUD y haz que aparezca gradualmente al entrar en un vehículo. Para los jugadores que prefieran un HUD minimalista, ofrece un ajuste para ocultar por completo el indicador de combustible y mostrarlo solo como notificación temporal cuando el combustible baje de un umbral configurable. Integra el indicador con otros elementos del HUD del vehículo, como el velocímetro y el estado del motor, para crear un panel de instrumentos cohesivo.
Rendimiento y sincronización
El sistema de combustible funciona continuamente en cada cliente que conduce un vehículo, por lo que optimizar el rendimiento es fundamental. Usa un intervalo de actualización del consumo de 1000 milisegundos en lugar de ejecutarlo en cada fotograma, ya que los cambios de combustible son graduales y las actualizaciones por segundo son visualmente indistinguibles de las actualizaciones por fotograma, con aproximadamente 60 veces menos consumo de procesamiento. Guarda los valores de combustible en las state bags de la entidad en lugar de usar eventos de red personalizados, ya que las state bags están optimizadas para valores que cambian con frecuencia y solo se sincronizan cuando el valor cambia. Al guardar el combustible en la base de datos para conservarlo tras los reinicios del servidor, agrupa todas las actualizaciones de combustible de los vehículos en una sola consulta que se ejecute cada 60 segundos, en lugar de guardar cada vez que cambia el combustible de un vehículo. Usa el ID de red del vehículo como clave para registrar el combustible y elimina los datos guardados de los vehículos que ya no existen para evitar que la base de datos crezca innecesariamente. Gestiona el caso límite en el que un vehículo cambia de propietario de red mientras repostas: comprueba la propiedad antes de aplicar los cambios de combustible y valida todas las transacciones de pago en el servidor. En las estaciones con muchos clientes a la vez, implementa un sistema de cola que impida que dos jugadores usen la misma bomba simultáneamente y muestre un indicador visual cuando esté ocupada.