Wróć do bloga
Guide8 min czytania

System pracy kierowcy ciężarówki w FiveM: skrypty dostaw dalekobieżnych

Dodaj prawdziwą karierę kierowcy ciężarówki do swojego serwera FiveM. Trasy, ładunki, wypłaty i najlepsze skrypty transportowe dla ekonomii QBCore oraz ESX.

Agency Scripts

Założyciel i główny deweloper w Agency Scripts

Dlaczego praca kierowcy ciężarówki ma znaczenie dla ekonomii serwera

Praca kierowcy ciężarówki i dostawcy stanowi kręgosłup gospodarczy każdego serwera FiveM roleplay. Zapewnia niezawodne źródło dochodu dla nowych graczy, którzy nie nawiązali jeszcze kontaktów ani nie znaleźli specjalistycznego zajęcia, tworząc jednocześnie infrastrukturę logistyczną łączącą firmy na całej mapie. Gdy restauracja potrzebuje składników, salon samochodowy wymaga transportu pojazdów, a plac budowy materiałów, transport ciężarowy tworzy pomost między podażą a popytem. Dobrze zaprojektowany system transportu ciężarowego przekształca zwykłą jazdę z punktu A do punktu B w angażującą ścieżkę kariery z planowaniem tras, zarządzaniem ładunkiem, ulepszeniami pojazdów oraz decyzjami dotyczącymi ryzyka i opłacalności wyboru dłuższych, ale lepiej płatnych tras przez niebezpieczne tereny. Praca kierowcy ciężarówki wypełnia także mapę aktywnością, wprowadzając duże pojazdy na autostrady i dając policji możliwość monitorowania wykroczeń drogowych, co stwarza naturalne sytuacje roleplay między kierowcami a służbami porządkowymi.

Konfiguracja tras i system kontraktów

Zaprojektuj system transportu ciężarowego w oparciu o model zleceń, w którym kierowcy pobierają zadania z tablicy dyspozytorskiej w bazie firmy. Każde zlecenie określa miejsce odbioru, cel dostawy, typ ładunku, wagę, stawkę wynagrodzenia oraz limit czasowy. Podziel zlecenia na poziomy w oparciu o kategorię prawa jazdy kierowcy i poziom doświadczenia, dzięki czemu nowi kierowcy zaczną od lokalnych dostaw furgonetkami, podczas gdy weterani podejmą się kursów z naczepami przez całą mapę, przewożąc materiały niebezpieczne. System zleceń powinien generować trasy dynamicznie z puli punktów odbioru i dostawy zamiast stosowania statycznych tras, które stają się powtarzalne już po kilku kursach:

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

System poziomów i XP tworzy progresję, która angażuje kierowców na dłużej. Każda udana dostawa zapewnia punkty doświadczenia z bonusami za terminowe ukończenie oraz dostarczenie ładunku bez uszkodzeń. System doświadczenia odblokowuje zlecenia wyższych poziomów z lepszym wynagrodzeniem, ale też większym poziomem trudności, ponieważ dłuższe trasy prowadzą przez bardziej niebezpieczne obszary, a większymi pojazdami trudniej manewrować w ciasnych uliczkach miasta.

Zarządzanie pojazdami i przyczepami

Pojazdy ciężarowe wymagają specjalnej obsługi w porównaniu ze zwykłymi samochodami graczy. Gdy kierowca przyjmie zlecenie, zespawnuj odpowiednią ciężarówkę w punkcie spawnu bazy i dołącz wymaganą naczepę. Użyj AttachVehicleToTrailer dla prawidłowej fizyki naczep i zaimplementuj ręczny system podpinania, w którym kierowcy muszą cofnąć ciągnik pod naczepę i nacisnąć klawisz, aby ją podpiąć. Ten ręczny proces dodaje rozgrywkę opartą na umiejętnościach i tworzy satysfakcjonujące momenty, gdy kierowca perfekcyjnie cofnie w ciasną rampę załadunkową. Uważnie śledź stan podpięcia naczepy, ponieważ fizyka naczep w GTA może odpiąć naczepę podczas kolizji, a twój skrypt musi to wykryć i powiadomić kierowcę:

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)

Śledzenie uszkodzeń i stanu ładunku

Stan ładunku dodaje istotną warstwę rozgrywki do każdej dostawy. Śledź stan ładunku na podstawie uderzeń, prędkości na wybojach i stylu jazdy na całej trasie. Gdy ciężarówka zderzy się z obiektami lub innymi pojazdami, oblicz siłę uderzenia na podstawie różnicy prędkości pojazdu i nałóż proporcjonalne uszkodzenia na ładunek. Delikatny ładunek, taki jak elektronika czy szkło, odnosi poważne uszkodzenia przy drobnych wybojach, podczas gdy wytrzymały ładunek, jak stal konstrukcyjna, ledwo odczuwa uderzenia. Wyświetlaj stan ładunku w procentach na HUD, aby kierowcy widzieli konsekwencje swojej jazdy w czasie rzeczywistym. Zmniejszaj końcową wypłatę proporcjonalnie do uszkodzeń ładunku i ustaw minimalny próg, poniżej którego dostawa kończy się całkowitym niepowodzeniem z powodu zniszczenia towaru. Ta mechanika naturalnie zachęca do ostrożnej jazdy bez sztucznego ograniczania prędkości, pozwalając kierowcom na własną kalkulację ryzyka i zysku między szybką jazdą w celu dotrzymania limitu czasu a ostrożną jazdą w celu zachowania ładunku w dobrym stanie.

Nawigacja GPS i wyświetlanie trasy

Zapewnij kierowcom ciężarówek wyspecjalizowany system GPS, który uwzględnia gabaryty pojazdu przy wyznaczaniu tras. Standardowe punkty nawigacji GTA kierują graczy przez wąskie uliczki i pod niskie mosty, pod którymi zestaw z naczepą się nie zmieści. Zastąp domyślną nawigację własnymi znacznikami trasy, które prowadzą drogami przystosowanymi dla ciężarówek, unikają ciasnych zakrętów i ostrzegają kierowców przed zbliżającymi się przeszkodami. Wyświetlaj trasę jako serię punktów kontrolnych (blipów) na minimapie ze wskaźnikami odległości do kolejnego punktu oraz pokazuj szacowany czas przyjazdu na podstawie aktualnej prędkości. Dodaj mechanikę zużycia paliwa powiązaną z przebytym dystansem i masą pojazdu, aby kierowcy musieli planować postoje na tankowanie na długich trasach, co tworzy dodatkowe punkty decyzyjne podczas podróży:

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

Stacje ważenia i kontrole

Dodaj stacje ważenia pojazdów wzdłuż głównych autostrad, gdzie kierowcy ciężarówek muszą się zatrzymać i poddać kontroli ładunku. Ta mechanika tworzy naturalne punkty interakcji na długich trasach i otwiera możliwości roleplayu między truckerami a inspektorami transportu, którzy mogą być sterowani przez NPC lub odgrywani przez graczy z frakcją inspekcji transportu drogowego. Na stacji ważenia sprawdzaj całkowitą masę ciężarówki pod kątem limitów prawnych, weryfikuj zgodność manifestu ładunku z tym, co zostało załadowane, oraz kontroluj stan techniczny pojazdu. Przeładowane ciężarówki otrzymują mandaty, które uszczuplają zyski z dostaw, motywując kierowców do przestrzegania przepisów. Jeśli na Twoim serwerze działa policja, daj funkcjonariuszom możliwość przeprowadzania kontroli drogowych z podobnymi procedurami, co stworzy naturalne interakcje ze służbami bez konieczności popełniania przestępstw. Obowiązek kontroli na stacjach wagowych dodaje kolejną warstwę realizmu, którą zaangażowani kierowcy ciężarówek szczerze doceniają, ponieważ potwierdza ona ich poświęcenie dla odgrywanej roli.

System konwojów dla wielu graczy

Umożliw wielu kierowcom ciężarówek tworzenie konwojów w celu realizacji dostaw grupowych, które dają bonus dla każdego uczestniczącego kierowcy. Lider konwoju przyjmuje specjalny kontrakt dla wielu ciężarówek, który generuje powiązane dostawy do tego samego obszaru docelowego. Członkowie konwoju dzielą kanał radiowy do koordynacji, widzą nawzajem swoje pozycje na minimapie dzięki specjalnym znacznikom konwoju i otrzymują bonus za bliskość, gdy jadą w rozsądnej odległości od siebie. Zachęca to do wspólnej rozgrywki i tworzy imponujące wizualnie momenty, gdy kolumna ciężarówek jedzie razem autostradą. Zaimplementuj wskaźnik formacji konwoju, który pokazuje pozycję każdego członka w kolumnie i wyróżnia każdego, kto zostaje w tyle lub skręci w złą stronę. Bonus za konwój powinien być na tyle znaczący, aby motywować do łączenia się w grupy, zazwyczaj o dwadzieścia do trzydziestu procent więcej niż w przypadku przejazdów solo, dzięki czemu warto poczekać na innych kierowców zamiast od razu wyruszać samemu.

Wydajność i zabezpieczenia anti-exploit

Systemy transportu ciężarowego spawnują duże pojazdy, które generują znaczne obciążenie renderowania, dlatego zarządzaj ich cyklem życia ostrożnie. Usuwaj ciężarówkę i naczepę natychmiast po ukończeniu lub niepowodzeniu dostawy, zamiast zostawiać je na mapie. Jeśli kierowca rozłączy się w trakcie dostawy, usuń zespawnowane pojazdy po stronie serwera i oznacz zlecenie jako porzucone. Zapobiegaj exploitom teleportacji, śledząc pozycję ciężarówki w regularnych odstępach czasu i upewniając się, że porusza się ona prawdopodobną trasą od odbioru do punktu docelowego, oznaczając dostawy, w których pojazd pokonał niemożliwe odległości między sprawdzeniami. Ogranicz częstotliwość akceptowania zleceń, aby gracze nie akceptowali i nie anulowali ich masowo w celu wybierania tylko najlepiej płatnych tras. Zapisuj statystyki dostaw dla każdego gracza na potrzeby rankingów i osiągnięć, ale grupuj zapisy do bazy danych za pomocą timera, zamiast pisać po każdym punkcie kontrolnym, aby zminimalizować obciążenie bazy w godzinach szczytu, gdy jednocześnie aktywnych jest wielu kierowców.

Gotowy, aby zacząć?

Kup skrypty w naszym sklepie lub dołącz do Discorda, aby uzyskać wsparcie, aktualizacje i sprawdzić nadchodzące nowości.