Volver al blog
Guide10 min de lectura

Sistema de empleo de camionero para FiveM: scripts para entregas de larga distancia

Añade una carrera de camionero a tu servidor de FiveM. Rutas, cargas, salarios y excelentes scripts de transporte para las economías de QBCore y ESX.

Agency Scripts

Fundador y desarrollador principal en Agency Scripts

Por qué los trabajos de transporte de mercancías son importantes para la economía del servidor

Los trabajos de transporte de mercancías y reparto son la columna vertebral económica de cualquier servidor de roleplay de FiveM. Ofrecen una fuente de ingresos fiable a los nuevos jugadores que aún no han establecido contactos ni encontrado un trabajo especializado, y también crean la infraestructura logística que conecta los negocios de todo el mapa. Cuando un restaurante necesita ingredientes, un concesionario necesita transportar vehículos o una obra necesita materiales, el transporte de mercancías crea el vínculo entre la oferta y la demanda. Un sistema de transporte bien diseñado convierte lo que podría ser una simple rutina de ir del punto A al punto B en una trayectoria profesional atractiva, con planificación de rutas, gestión de carga, mejoras de vehículos y decisiones de riesgo y recompensa sobre si tomar rutas más largas pero mejor pagadas que atraviesan zonas peligrosas. El trabajo de transporte también llena el mapa de actividad, pone vehículos grandes en las autopistas y da a la policía algo que vigilar por infracciones de tráfico, lo que crea encuentros naturales de roleplay entre camioneros y agentes de la ley.

Configuración de rutas y sistema de contratos

Diseña tu sistema de transporte de mercancías en torno a un modelo de contratos, en el que los conductores acepten trabajos de un panel de despacho en el depósito de transporte. Cada contrato especifica el lugar de recogida, el destino de entrega, el tipo de carga, el peso, la tarifa y el límite de tiempo. Organiza los contratos por niveles según la clase de licencia y la experiencia del conductor, para que los nuevos empiecen con entregas locales en camiones de caja, mientras que los transportistas veteranos se encarguen de viajes con remolque de un extremo al otro del mapa y materiales peligrosos. El sistema de contratos debería generar rutas dinámicamente a partir de un conjunto de puntos de recogida y entrega, en lugar de usar rutas fijas que se vuelven repetitivas después de unos cuantos viajes:

Config.TruckingDepot = {
    location = vector3(152.29, -3210.88, 5.91),
    spawnPoint = vector4(162.45, -3207.12, 5.91, 270.0),
    returnPoint = vector3(148.77, -3215.44, 5.91),
}

Config.ContractTiers = {
    [1] = {
        label = 'Local Delivery',
        requiredLevel = 0,
        vehicle = 'mule',
        payRange = { 500, 1200 },
        timeLimit = 600,
        routes = {
            { pickup = vector3(89.54, -1745.62, 29.33),
              dropoff = vector3(-46.23, -1758.49, 29.42),
              cargo = 'electronics', weight = 500 },
            { pickup = vector3(821.77, -2160.33, 29.62),
              dropoff = vector3(-324.18, -1522.87, 27.56),
              cargo = 'food_supplies', weight = 350 },
            { pickup = vector3(-1088.34, -2002.19, 13.22),
              dropoff = vector3(1214.56, -1386.73, 35.37),
              cargo = 'clothing', weight = 200 },
        }
    },
    [2] = {
        label = 'Regional Haul',
        requiredLevel = 5,
        vehicle = 'packer',
        trailer = 'trailers',
        payRange = { 2000, 4500 },
        timeLimit = 900,
        routes = {
            { pickup = vector3(1378.22, -2078.85, 52.04),
              dropoff = vector3(-2556.14, 2334.67, 33.06),
              cargo = 'construction_materials', weight = 15000 },
            { pickup = vector3(-58.83, -2538.92, 6.07),
              dropoff = vector3(2671.84, 1678.93, 24.49),
              cargo = 'fuel_barrels', weight = 12000,
              hazardous = true },
        }
    },
    [3] = {
        label = 'Long Haul',
        requiredLevel = 15,
        vehicle = 'hauler',
        trailer = 'tanker',
        payRange = { 5000, 10000 },
        timeLimit = 1200,
        routes = {
            { pickup = vector3(2682.34, 1410.77, 24.52),
              dropoff = vector3(-1143.27, -2002.47, 13.18),
              cargo = 'refined_fuel', weight = 25000,
              hazardous = true, fragile = false },
        }
    },
}

Config.LevelXP = {
    perDelivery = 25,
    bonusOnTime = 15,
    bonusNoDamage = 20,
    penaltyLate = -10,
    penaltyCargoDamage = -15,
}

El sistema de niveles y XP crea una progresión que mantiene a los conductores motivados con el tiempo. Cada entrega exitosa otorga puntos de experiencia, con bonificaciones por completar el trabajo a tiempo y entregar la carga sin daños. El sistema de experiencia desbloquea contratos de niveles superiores, con mejor paga pero también mayor dificultad, ya que las rutas más largas pasan por zonas más peligrosas y los vehículos más grandes son más difíciles de maniobrar por las calles estrechas de la ciudad.

Gestión de vehículos y remolques

Los vehículos de transporte de carga requieren un manejo especial en comparación con los autos normales de los jugadores. Cuando un conductor acepta un contrato, genera el camión adecuado en el punto de aparición del depósito y acóplale el remolque que corresponda. Usa AttachVehicleToTrailer para obtener una física adecuada para los remolques e implementa un sistema de acoplamiento manual donde los conductores tengan que dar marcha atrás con la cabina hasta el remolque y pulsar una tecla para engancharlo. Este proceso manual añade una mecánica basada en la habilidad y crea momentos satisfactorios cuando un conductor logra una maniobra difícil de reversa en una zona de carga estrecha. Controla cuidadosamente el estado de acoplamiento del remolque, porque la física de los remolques de GTA puede hacer que se desacoplen durante las colisiones. Tu script debe detectarlo y avisar al conductor:

local activeTrailer = nil
local trailerAttached = false

function SpawnTruckWithTrailer(vehicleModel, trailerModel, spawnPoint)
    -- Spawn truck
    local truckHash = GetHashKey(vehicleModel)
    RequestModel(truckHash)
    while not HasModelLoaded(truckHash) do Wait(10) end

    local truck = CreateVehicle(truckHash, spawnPoint.x, spawnPoint.y,
        spawnPoint.z, spawnPoint.w, true, false)
    SetVehicleNumberPlateText(truck, 'HAUL' .. math.random(100, 999))
    SetEntityAsMissionEntity(truck, true, true)
    SetModelAsNoLongerNeeded(truckHash)

    -- Spawn trailer if needed
    if trailerModel then
        local trailerHash = GetHashKey(trailerModel)
        RequestModel(trailerHash)
        while not HasModelLoaded(trailerHash) do Wait(10) end

        local trailerSpawn = GetOffsetFromEntityInWorldCoords(truck, 0.0, -8.0, 0.0)
        activeTrailer = CreateVehicle(trailerHash, trailerSpawn.x,
            trailerSpawn.y, trailerSpawn.z, spawnPoint.w, true, false)
        SetEntityAsMissionEntity(activeTrailer, true, true)
        SetModelAsNoLongerNeeded(trailerHash)

        -- Auto-attach trailer
        AttachVehicleToTrailer(truck, activeTrailer, 1.0)
        trailerAttached = true
    end

    return truck
end

-- Monitor trailer attachment status
CreateThread(function()
    while activeTrailer do
        if trailerAttached then
            local truck = GetVehiclePedIsIn(PlayerPedId(), false)
            if truck ~= 0 and not IsVehicleAttachedToTrailer(truck) then
                trailerAttached = false
                lib.notify({
                    title = 'Trailer Detached!',
                    description = 'Your trailer has come loose! Re-attach it.',
                    type = 'error'
                })
                -- Add blip to trailer location
                local trailerCoords = GetEntityCoords(activeTrailer)
                local blip = AddBlipForEntity(activeTrailer)
                SetBlipSprite(blip, 479)
                SetBlipColour(blip, 1)
                BeginTextCommandSetBlipName('STRING')
                AddTextComponentSubstringPlayerName('Detached Trailer')
                EndTextCommandSetBlipName(blip)
            end
        end
        Wait(1000)
    end
end)

Seguimiento del daño y el estado de la carga

El estado de la carga añade una mecánica de juego importante a cada entrega. Controla la salud de la carga según los impactos, la velocidad al pasar por baches y la forma de conducir durante la ruta. Cuando el camión choque con objetos u otros vehículos, calcula la gravedad del impacto según la variación de velocidad del vehículo y aplica un daño proporcional a la carga. La carga frágil, como los aparatos electrónicos o el vidrio, recibe mucho daño incluso con pequeños golpes, mientras que la carga resistente, como el acero de construcción, apenas registra impactos. Muestra la salud de la carga como porcentaje en el HUD para que los conductores vean en tiempo real las consecuencias de su forma de conducir. Reduce el pago final en proporción al daño de la carga y establece un umbral mínimo por debajo del cual la entrega fracasa por completo porque la carga queda destruida. Esta mecánica fomenta de manera natural una conducción cuidadosa sin limitar artificialmente la velocidad, y permite que los conductores decidan por su cuenta si vale la pena conducir rápido para cumplir el límite de tiempo o hacerlo con cuidado para conservar el estado de la carga.

Navegación GPS y visualización de rutas

Proporciona a los camioneros un sistema GPS especializado que tenga en cuenta el tamaño del vehículo al calcular las rutas. Los puntos de ruta estándar de GTA llevan a los jugadores por callejones estrechos y bajo puentes bajos por los que no puede pasar un camión con remolque. Sustituye la navegación predeterminada por marcadores de ruta personalizados que sigan caminos aptos para camiones, eviten los giros cerrados y avisen a los conductores sobre los obstáculos que se aproximan. Muestra la ruta como una serie de marcadores de control en el minimapa, con indicadores de distancia al siguiente punto, y calcula una hora estimada de llegada según la velocidad actual. Añade una mecánica de consumo de combustible relacionada con la distancia recorrida y el peso del vehículo, para que los conductores tengan que planificar paradas para repostar en trayectos largos y deban tomar decisiones adicionales durante el viaje:

function CreateTruckRoute(pickupCoords, dropoffCoords)
    -- Clear previous route
    ClearGpsMultiRoute()

    -- Set up checkpoint blips along the route
    local checkpoints = CalculateTruckFriendlyRoute(pickupCoords, dropoffCoords)

    for i, checkpoint in ipairs(checkpoints) do
        local blip = AddBlipForCoord(checkpoint.x, checkpoint.y, checkpoint.z)
        SetBlipSprite(blip, 1)
        SetBlipScale(blip, 0.6)
        SetBlipColour(blip, i == #checkpoints and 5 or 3)
        SetBlipAsShortRange(blip, true)
        table.insert(routeBlips, blip)
    end

    -- Set final destination waypoint
    SetNewWaypoint(dropoffCoords.x, dropoffCoords.y)

    -- Start GPS multi-route display
    StartGpsMultiRoute(6, true, true)
    for _, cp in ipairs(checkpoints) do
        AddPointToGpsMultiRoute(cp.x, cp.y, cp.z)
    end
    SetGpsMultiRouteRender(true)
end

Estaciones de pesaje e inspecciones

Añade estaciones de pesaje en las principales rutas de autopista, donde los camioneros deban detenerse para inspeccionar la carga. Esta mecánica crea puntos de interacción naturales en los trayectos largos y abre oportunidades para hacer roleplay entre camioneros e inspectores del DOT, que pueden ser NPC o jugadores con un trabajo de autoridad de transporte. En una estación de pesaje, comprueba que el peso total del camión no supere los límites legales, verifica que el manifiesto coincida con la carga y revisa el estado del vehículo. Los camiones con sobrepeso reciben multas que reducen las ganancias de la entrega, lo que incentiva a los conductores a respetar los límites legales. Si tu servidor tiene una fuerza policial, permite que los agentes hagan inspecciones en carretera con controles similares. Así se crean encuentros de aplicación de la ley espontáneos que no dependen del crimen. Cumplir con las normas de las estaciones de pesaje añade otra capa de realismo que los jugadores dedicados al transporte de carga disfrutan de verdad, porque reconoce el compromiso con su rol.

Sistema de convoy multijugador

Permite que varios camioneros formen convoyes para realizar entregas en grupo que paguen una bonificación a cada conductor participante. El líder del convoy acepta un contrato especial para varios camiones, que genera entregas vinculadas al mismo destino o zona. Los miembros del convoy comparten un canal de radio para coordinarse, ven las posiciones de los demás en el minimapa con marcadores especiales de convoy y reciben una bonificación por proximidad cuando conducen a una distancia razonable entre sí. Esto fomenta el juego social y crea momentos visuales impresionantes cuando una fila de camiones recorre la autopista. Implementa un indicador de formación del convoy que muestre la posición de cada miembro en la fila y destaque a quienes se queden atrás o tomen un giro equivocado. La bonificación del convoy debe ser lo bastante significativa como para incentivar la formación de grupos, normalmente entre un veinte y un treinta por ciento más que en viajes en solitario. Así, vale la pena esperar a otros conductores en vez de salir enseguida por cuenta propia.

Rendimiento y medidas contra exploits

Los sistemas de transporte de carga generan vehículos grandes que tienen un costo de renderizado considerable, así que administra cuidadosamente su ciclo de vida. Elimina el camión y el remolque en cuanto la entrega termine o fracase, en lugar de dejarlos en el mapa. Si el conductor se desconecta durante una entrega, limpia los vehículos generados desde el servidor y marca el contrato como abandonado. Evita los exploits de teletransporte registrando la posición del camión a intervalos regulares y comprobando que siga una ruta plausible entre el punto de recogida y el de entrega. Marca las entregas en las que el vehículo haya recorrido distancias imposibles entre comprobaciones. Limita la frecuencia con la que se aceptan contratos para evitar que los jugadores los acepten y cancelen rápidamente con el fin de seleccionar las rutas que mejor pagan. Guarda las estadísticas de entrega de cada jugador para las clasificaciones y los logros, pero agrupa las escrituras en la base de datos con un temporizador en lugar de guardar después de cada punto de control. Así reduces la carga de la base de datos durante las horas punta, cuando hay muchos conductores activos al mismo tiempo.

¿Listo para empezar?

Consigue los scripts en nuestra tienda, o únete al Discord para soporte, novedades y un adelanto de lo que viene.