Metro Job [Standalone/ESX/QBCore]

A script by Gamzky

No reviews yet.
Metro Job [Standalone/ESX/QBCore] main image

Full Description

metrojob

:metro:Metro Job

Looking to add an immersive and realistic metro driver job to your FiveM server? Bring the excitement of public transportation to your players with this fully-featured metro job script. Players can drive metro trains along a detailed route, stop at stations, manage doors, and earn money based on their driving performance and adherence to speed limits.

:shopping_cart: Get it here: gamzkystore.com

:question: Support: Discord

:movie_camera: Detailed preview: Youtube

Features

  • Realistic Metro Driving: Drive authentic metro trains along a route across Los Santos with proper train physics and controls
  • Station Management System: Stop at stations, open/close doors for passengers, with visual indicators and distance-based scoring for stops
  • Speed Limit Zones: Navigate speed limit zones with real-time warnings and penalties for exceeding limits
  • Performance-Based Payment: Earn money from points accumulated from successful stops, with bonuses for perfect positioning and penalties for violations
  • Interactive UI: Speedometer HUD showing current speed, set speed, max speed, next station info, and speed limit warnings
  • Door Synchronization: Statebag-based door sync ensuring all players see doors opening/closing in real-time. (Other players can enter too!)
  • Multiple Starting Locations: Choose from multiple starting points along the route to begin shifts from different stations
  • Framework Support: Works standalone and integrates with ESX, QBCore and Qbox
  • Highly Configurable: Extensive config options for station locations, speed limits, payment rates, stop ranges, and full localization

Resmon: Idle: 0.00ms - Active: 0.06ms

How it works

  • Start Route: Approach any metro job blip location and interact to open the job dialog, then confirm to spawn a metro train at that station
  • Drive to Stations: Use W/S to increase/decrease speed, Shift+W to set maximum speed, and Shift+S to stop completely
  • Stop at Stations: Stop the metro near the stop indicator at each station and get bonus points for perfect positioning
  • Open Doors: Press Q to open doors when stopped at a station
  • Warning Signal: Hold E (horn) for at least one second before closing doors
  • Close Doors: Press Q again after giving the warning signal to close doors and continue the route
  • Follow Speed Limits: Watch for speed limit signs and zones - exceeding limits results in point penalties
  • Complete Route: Drive through all stations on the route, then exit with F (only when doors are open) to receive your payment

Core/framework related functions are always accessible in the encrypted version, feel free to create a support ticket in our Discord in case of questions.

Config
Config = {}

-- Speed unit: 'kmh' for kilometers per hour, 'mph' for miles per hour
-- This setting only affects the display unit. All config values (maxSpeed, speedLimit) are always in km/h
Config.speedUnit = 'kmh' -- Options: 'kmh' or 'mph'

-- Maximum speed the metro can travel at (in km/h)
-- Note: This value is always in km/h regardless of Config.speedUnit setting
Config.maxSpeed = 100

-- Distance range (in meters) from a station stop where the player can open doors and get points
Config.stopRange = 7.0

-- Amount of money earned per point at the end of the route
Config.pointSalary = 115

-- Time buffer (in milliseconds) before speed limit violations are counted after entering a speed limit zone
Config.limitBufferTime = 3000

-- Starting locations where players can begin a metro route
-- stopId: The index in Config.stopLocations where the route should start
-- coords: Vector3 coordinates of the spawn location
Config.startLocations = {
    { stopId = 1,  coords = vector3(-1105.43, -2744.81, -7.42) }, 
    -- { stopId = 4, coords = vector3(282.65, -1207.42, 38.91) },
    { stopId = 8,  coords = vector3(-535.17, -675.04, 11.81) },
    { stopId = 16, coords = vector3(-292.70, -364.79, 9.96) },
}

-- Train variation ID for CreateMissionTrain (28 = metrotrain)
-- See trains.xml for available variations (0-28 as of build 2802)
Config.trainVariation = 28

-- All metro station stops along the route
-- name: Display name of the station
-- coords: Vector3 coordinates of the station stop location
-- Note: Stations are visited in order, and the route loops back to the first station after the last one
Config.stopLocations = {
    { name = 'LSIA Terminal 4', coords = vector3(-1067.23, -2708.14, -9.32413) },
    { name = 'LSIA Parking',    coords = vector3(-866.522, -2294.89, -13.6312) },
    { name = 'Puerto Del Sol',  coords = vector3(-528.638, -1267.25, 24.9035) },
    { name = 'Strawberry',      coords = vector3(284.758, -1209.94, 37.1173) },
    { name = 'Burton',          coords = vector3(-287.121, -301.918, 8.1491) },
    { name = 'Portola Drive',   coords = vector3(-848.519, -148.127, 18.0372) },
    { name = 'Del Perro',       coords = vector3(-1342.68, -495.257, 13.1313) },
    { name = 'Little Seoul',    coords = vector3(-472.715, -680.614, 9.89546) },
    { name = 'Pillbox South',   coords = vector3(-222.641, -1044.9, 28.3251) },
    { name = 'Davis',           coords = vector3(121.025, -1735.97, 28.0516) },

    { name = 'Davis',           coords = vector3(107.436, -1713.7, 28.1268) },
    { name = 'Pillbox South',   coords = vector3(-204.467, -1022.59, 28.3222) },
    { name = 'Little Seoul',    coords = vector3(-523.353, -665.612, 9.89549) },
    { name = 'Del Perro',       coords = vector3(-1358.06, -438.633, 13.1318) },
    { name = 'Portola Drive',   coords = vector3(-788.995, -131.128, 18.0368) },
    { name = 'Burton',          coords = vector3(-302.231, -344.879, 8.14959) },
    { name = 'Strawberry',      coords = vector3(243.68, -1198.62, 37.0482) },
    { name = 'Puerto Del Sol',  coords = vector3(-549.434, -1290.78, 24.9062) },
    { name = 'LSIA Parking',    coords = vector3(-900.237, -2343.76, -13.6458) },
    { name = 'LSIA Terminal 4', coords = vector3(-1104.42, -2728.99, -9.32413) },
}

-- Speed limit zones along the metro track
-- startZone: Track node where the speed limit zone begins
-- endZone: Track node where the speed limit zone ends
-- limit: Maximum allowed speed in km/h for this zone
-- Note: These values are always in km/h regardless of Config.speedUnit setting
Config.speedLimit = {
    -- 90 km/h
    { startZone = 658,  endZone = 719,  limit = 90 },
    { startZone = 242,  endZone = 299,  limit = 90 },
    -- 60 km/h
    { startZone = 786,  endZone = 808,  limit = 60 },
    -- 30 km/h
    { startZone = 808,  endZone = 830,  limit = 30 },
    { startZone = 117,  endZone = 138,  limit = 30 },
    -- 60 km/h
    { startZone = 830,  endZone = 838,  limit = 80 },
    { startZone = 106,  endZone = 117,  limit = 60 },
    -- 90 km/h
    { startZone = 984,  endZone = 1000, limit = 90 },
    { startZone = 2226, endZone = 2243, limit = 90 },
    -- 70 km/h
    { startZone = 1388, endZone = 1401, limit = 70 },
    { startZone = 1777, endZone = 1802, limit = 70 },
    -- 60 km/h
    { startZone = 1413, endZone = 1435, limit = 60 },
    { startZone = 1734, endZone = 1762, limit = 60 },
    -- 40 km/h
    { startZone = 1435, endZone = 1463, limit = 40 },
    { startZone = 1706, endZone = 1734, limit = 40 },
    -- 60 km/h
    { startZone = 1463, endZone = 1548, limit = 60 },
    { startZone = 1620, endZone = 1706, limit = 60 },
    -- 70 km/h
    { startZone = 1573, endZone = 1596, limit = 70 },
}

-- Localization strings for all in-game messages and notifications
-- Use ~INPUT_*~ for key bindings, ~r~ ~g~ ~b~ etc. for colors, ~n~ for new lines
Config.Locales = {
    ['dialog_title'] = 'Legal Job: Metro Driver',
    ['dialog_start'] = 'Start',
    ['dialog_cancel'] = 'Cancel',
    ['metro_already_exists'] = '~r~A metro is already here!',
    ['exit_only_open_doors'] = 'You can only exit with open doors~n~Open doors: ~INPUT_VEH_RADIO_WHEEL~',
    ['cannot_drive_open_doors'] = 'Cannot drive with open doors~n~Close doors: ~INPUT_VEH_RADIO_WHEEL~',
    ['open_doors_passengers'] = 'Open doors to let passengers board~n~Open doors: ~INPUT_VEH_RADIO_WHEEL~',
    ['stopped_at_station'] = 'Stopped at metro station.',
    ['perfect_stop'] = 'Perfect stop position!',
    ['good_stop'] = 'Good stop position.',
    ['open_doors_instruction'] = 'Open doors: ~INPUT_VEH_RADIO_WHEEL~',
    ['doors_opened'] = 'Doors opened. Close doors: ~INPUT_VEH_RADIO_WHEEL~ (after warning signal)',
    ['doors_closing'] = 'Doors closing...',
    ['doors_only_at_station'] = 'You can only open doors at a station',
    ['warning_signal'] = 'Warning signal: ~INPUT_VEH_HORN~ (hold for one second)',
    ['only_when_stopped'] = 'This can only be done when stopped~n~Stop metro: ~INPUT_SPRINT~ ~INPUT_MOVE_DOWN_ONLY~',
    ['speed_limit_exceeded'] = '~r~You drove too fast!',
    ['set_max_speed'] = 'Set maximum speed: ~INPUT_SPRINT~ ~INPUT_MOVE_UP_ONLY~',
    ['station_skipped'] = '~r~You skipped a station!',
    ['blip_label'] = 'Metro Job',
    ['blip_title'] = 'Metro Job',
    ['blip_description'] = 'Can you as a metro driver safely and on time transport passengers from A to B? Start your metro adventure here!',
    ['drive_metro'] = 'Drive Metro',
    ['earned_money'] = 'You earned ~b~€%.0f~s~.',
    ['no_money_earned'] = '~r~You did not earn any money.',
}

Code is accessible No (but there is an unencrypted version)
Subscription-based No
Lines (approximately) 1315
Requirements Any framework (Optional) & ox_target or qb-target (Optional)
Support Yes

Config Merger
Have you tried Config Merger? Merge your configs easily