返回博客
Guide3 分钟阅读

FiveM 货运工作系统:长途配送脚本

为您的FiveM服务器添加一个完善的卡车运输职业。路线、货物、薪水以及适用于QBCore和ESX经济的最佳卡车脚本。

Agency Scripts

Agency Scripts 创始人兼首席开发者

为什么卡车运输工作对服务器经济重要

卡车运输和配送工作是任何FiveM角色扮演服务器的经济支柱。它们为尚未建立人脉或找到专门工作的新玩家提供可靠收入来源,同时构建连接地图各处企业的物流基础设施。当餐厅需要食材、汽车经销商需运输车辆或建筑工地需材料时,卡车运输搭建供应与需求的桥梁。设计良好的卡车系统将简单的点对点运输转变为有趣的职业路径,包含路线规划、货物管理、车辆升级及关于选择更长但报酬更高且危险的路线的风险回报决策。卡车工作还活跃地图,公路上出现大型车辆,警方有监控交通违规的对象,促进卡车司机与执法者间的自然角色扮演互动。

路线配置与合同系统

围绕合同模型设计卡车系统,司机从卡车站的调度板领取任务。每个合同指定取货地点、送货目的地、货物类型、重量、报酬率和时间限制。根据司机驾照等级和经验将合同分层,新司机使用箱式货车执行本地配送,资深司机承担跨地图挂车运输危险品。合同系统应从取货和送货点池动态生成路线,避免使用静态路线,防止几次运行后重复单调:

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,
}

等级和经验系统创造了持续吸引司机的进阶机制。每次成功送货可获得经验值,按时完成和无损送达货物可获得额外奖励。经验系统解锁更高级别的合同,报酬更高但难度也更大,因为更长路线经过更危险区域,大型车辆在狭窄街道中更难操控。

车辆和拖车管理

卡车车辆需特殊处理,区别于普通玩家车辆。司机接受合同时,在仓库生成相应卡车并挂载所需挂车。使用 AttachVehicleToTrailer 用于正确的拖车物理并实现手动连接系统,司机必须倒车将驾驶室靠近拖车并按键挂钩。此手动过程增加了技能玩法,并在司机成功倒入狭窄装载区时带来满足感。仔细跟踪拖车连接状态,因为GTA的拖车物理在碰撞时可能脱钩,脚本需检测并通知司机:

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)

货物损坏和状态跟踪

货物状态为每次配送增添了有意义的游戏层次。根据撞击、过坎速度和驾驶行为跟踪货物健康状况。在卡车与物体或其他车辆碰撞时,使用车辆速度差计算撞击严重程度,并按比例对货物造成损害。易碎货物如电子产品或玻璃会因轻微碰撞受到严重损害,而坚固货物如建筑钢材几乎不受影响。在HUD上以百分比显示货物健康状况,让司机实时看到驾驶后果。根据货物损坏程度按比例减少最终报酬,设定最低阈值,低于该阈值则因货物损毁配送失败。该机制自然鼓励谨慎驾驶,而非人为限制速度,让司机自行权衡快速驾驶以赶时间与谨慎驾驶以保护货物状态之间的风险与回报。

GPS 导航和路线显示

为卡车司机提供专用 GPS 系统,计算路线时考虑车辆尺寸。标准 GTA 路点会引导玩家穿过狭窄小巷和低桥,拖挂车无法通行。用自定义路线标记覆盖默认导航,遵循适合卡车的道路,避免急转弯,并提醒司机前方障碍。路线以小地图上的一系列检查点标记显示,带有距离下一个点的指示,并根据当前速度显示预计到达时间。添加与行驶距离和车辆重量相关的燃料消耗机制,使司机必须规划长途加油站,增加旅程中的决策点:

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

称重站和检查

在主要高速公路路线设置称重站,卡车司机必须停靠并接受货物检查。此机制在长途运输中创造自然互动点,并为卡车司机与运输部检查员之间的角色扮演提供机会,检查员可由NPC驱动或由拥有运输管理职位的玩家担任。在称重站,检查卡车总重量是否符合法定限额,核实货物清单与装载内容是否一致,并检查车辆状况。超重卡车将被罚款,减少运费利润,激励司机遵守法律限制。如果您的服务器有警察部队,允许警官进行路边检查,执行类似检查,创造不依赖犯罪的自然执法遭遇。称重站合规性增加了另一层现实感,专注卡车玩家会真正享受,因为它验证了他们对角色的投入。

多人车队系统

允许多名卡车司机组队形成车队进行团体配送,参与司机可获得额外奖金。车队队长接受特殊多卡车合同,生成指向同一目的地区域的关联配送。车队成员共享无线电频道以便协调,在小地图上通过特殊车队标记查看彼此位置,且在合理距离内驾驶时获得接近奖励。此机制鼓励社交玩法,并在多辆卡车沿高速公路行驶时营造壮观场面。实现车队编队指示器,显示每个成员在队列中的位置,并突出显示落后或走错路的成员。车队奖金应足够吸引玩家组队,通常比单独配送多20%至30%,使等待其他司机组队比单独出发更有价值。

性能与防作弊措施

卡车系统生成大型车辆,渲染成本高,需谨慎管理生命周期。交付完成或失败后立即删除卡车和挂车,避免留在地图上。若司机中途断线,服务器端清理生成车辆并标记合同为遗弃。通过定期跟踪卡车位置防止传送作弊,确保车辆路径合理,标记车辆在检查间隔内行驶不可能距离的交付。限制合同接受速率,防止玩家快速接受取消合同以挑选最高报酬路线。按玩家存储交付统计数据用于排行榜和成就,但数据库写入采用定时批处理,避免高峰时段大量司机同时活跃时数据库负载过高。

准备好开始了吗?

在我们的商店获取脚本,或加入 Discord 获取支持、更新以及新功能预告。