Installation
5
Editable Config
Config = {
Debug = false, -- Enable debug mode (prints extra info to console)
Locale = 'en', -- Language for notifications and UI ('en', 'de', 'es', 'fr')
useTarget = false, -- Use target system instead of markers/TextUI (auto-detects ox_target, qb-target, qtarget)
JobRequired = true, -- Require specific job to access delivery jobs
JobInfo = {
name = 'delivery', -- Job name required to access delivery jobs
},
-- ═══════════════════════════════════════════════════════════════════════════
-- PACKAGES CONFIG
-- Settings for delivery packages
-- ═══════════════════════════════════════════════════════════════════════════
Packages = {
prop = 'prop_cs_cardbox_01', -- Package prop model that player carries
loadTime = 2500, -- Time in ms to pick up a package from pickup zone
deliverTime = 2000, -- Time in ms to deliver a package to NPC
payPerPackage = 25, -- Base payment per package delivered ($)
-- Number of packages per difficulty (random between min-max)
counts = {
easy = {min = 1, max = 5},
medium = {min = 6, max = 10},
hard = {min = 11, max = 20},
vip = {min = 21, max = 35}
},
-- Number of delivery locations per difficulty (random between min-max)
locations = {
easy = {min = 2, max = 3},
medium = {min = 4, max = 5},
hard = {min = 6, max = 8},
vip = {min = 9, max = 15}
}
},
-- ═══════════════════════════════════════════════════════════════════════════
-- VEHICLE RETURN CONFIG
-- Settings for returning delivery vehicles to depot
-- ═══════════════════════════════════════════════════════════════════════════
VehicleReturn = {
enabled = true, -- Require players to return vehicles after delivery
damageThreshold = 0.8, -- Health percentage below which damage fee applies (0.8 = 80%)
baseFee = 500, -- Base damage fee if vehicle is damaged ($)
feePerDamagePercent = 10, -- Additional fee per percent of damage ($)
returnRadius = 3.0, -- Distance from return point to allow vehicle return (meters)
blip = {sprite = 477, color = 1, scale = 0.8, name = 'Vehicle Return'} -- Map blip settings
},
-- ═══════════════════════════════════════════════════════════════════════════
-- ANIMATIONS CONFIG
-- Animation dictionaries and names for various actions
-- ═══════════════════════════════════════════════════════════════════════════
Animations = {
carry = {dict = 'anim@heists@box_carry@', anim = 'idle', flag = 51}, -- Animation while carrying package
pickup = {dict = 'random@domestic', anim = 'pickup_low', duration = 2000}, -- Animation when picking up package from ground
putdown = {dict = 'anim@heists@box_carry@', anim = 'put_down_box_front', duration = 1500}, -- Animation when putting package in vehicle
give = {dict = 'mp_common', anim = 'givetake1_a', duration = 1500}, -- Animation when giving package to NPC
receive = {dict = 'mp_common', anim = 'givetake1_b', duration = 1500} -- NPC receiving animation
},
-- ═══════════════════════════════════════════════════════════════════════════
-- NPC CONFIG
-- Settings for delivery NPCs that receive packages
-- ═══════════════════════════════════════════════════════════════════════════
NPC = {
models = { -- Random NPC models used at delivery locations
'a_m_m_business_01', 'a_m_m_indian_01', 'a_m_m_eastsa_02',
'a_f_y_business_01', 'a_f_y_hipster_01', 'a_m_y_hipster_01',
's_m_m_warehouse_01', 'a_m_m_soucent_01', 'a_f_m_eastsa_01'
},
despawnDelay = 3000, -- Time in ms before NPC despawns after delivery complete
spawnDistance = 40.0 -- Distance from delivery point at which NPC spawns (meters)
},
-- ═══════════════════════════════════════════════════════════════════════════
-- JOB LOCATIONS
-- Coordinates for depot, vehicle spawn, and package pickup
-- ═══════════════════════════════════════════════════════════════════════════
JobLocations = {
Depot = { -- Main depot where players start jobs
coords = vector3(-424.2207, -2789.7605, 6.5297),
blip = {sprite = 478, color = 5, scale = 0.8, name = 'Delivery Depot', onlyForJob = false}, -- Map blip settings
marker = {type = 1, size = vector3(1.5, 1.5, 1.0), color = {r = 66, g = 135, b = 245, a = 150}} -- Ground marker settings
},
VehicleSpawn = { -- Where delivery vehicles spawn
coords = vector3(-450.4776, -2794.8721, 5.5884),
heading = 43.9381 -- Vehicle spawn direction (degrees)
},
VehicleReturn = { -- Where players return vehicles after job
coords = vector3(-450.4776, -2794.8721, 5.5884),
marker = {type = 36, size = vector3(1.5, 1.5, 1.0), color = {r = 255, g = 50, b = 50, a = 150}}
},
PackagePickup = { -- Where players pick up packages before delivery
coords = vector3(-449.3051, -2805.6663, 7.2959),
marker = {type = 1, size = vector3(2.0, 2.0, 0.5), color = {r = 0, g = 255, b = 100, a = 150}}
}
},
-- ═══════════════════════════════════════════════════════════════════════════
-- VEHICLES CONFIG
-- Available delivery vehicles with stats and unlock requirements
-- ═══════════════════════════════════════════════════════════════════════════
Vehicles = {
speedo = {
model = 'speedo', -- GTA vehicle spawn name
label = 'Speedo', -- Display name in menu
icon = 'fa-van-shuttle', -- FontAwesome icon for UI
description = 'Starter delivery van', -- Description shown in menu
basePayMultiplier = 1.0, -- Payment multiplier (1.0 = 100%)
speedBonus = 1.0, -- Speed rating (affects time bonus calculation)
maxPackages = 5, -- Maximum packages this vehicle can carry
unlockLevel = 1, -- Required player level to use
sortOrder = 1, -- Order in vehicle selection menu
offsetMarker = vector3(0.0, 0.0, -.98) -- Marker offset when parking vehicles
},
boxville = {
model = 'youga', label = 'Youga', icon = 'fa-van-shuttle',
description = 'Medium capacity van',
basePayMultiplier = 1.2, speedBonus = 0.9, maxPackages = 10,
unlockLevel = 2, sortOrder = 2,
offsetMarker = vector3(0.0, 0.0, -.4)
},
rumpo = {
model = 'rumpo', label = 'Rumpo', icon = 'fa-van-shuttle',
description = 'Fast delivery van',
basePayMultiplier = 1.3, speedBonus = 1.1, maxPackages = 20,
unlockLevel = 5, sortOrder = 3,
offsetMarker = vector3(0.0, 0.0, -.4)
},
mule = {
model = 'boxville2', label = 'Boxville', icon = 'fa-truck',
description = 'Large delivery truck',
basePayMultiplier = 1.5, speedBonus = 0.8, maxPackages = 35,
unlockLevel = 10, sortOrder = 4,
offsetMarker = vector3(0.0, 0.0, -.98)
},
},
-- ═══════════════════════════════════════════════════════════════════════════
-- DELIVERY POINTS
-- All possible delivery locations grouped by area
-- Areas: 'downtown', 'south', 'east', 'west', 'vinewood', 'county',
-- ═══════════════════════════════════════════════════════════════════════════
DeliveryPoints = {
-- Downtown area (easy + medium + hard)
{name = 'Legion Square', coords = vector4(146.079, -1058.863, 30.186, 158.527), area = 'downtown'},
{name = 'Pill Box Hospital', coords = vector4(363.338, -711.979, 29.286, 69.285), area = 'downtown'},
{name = 'Mission Row PD', coords = vector4(391.990, -916.229, 29.776, 269.730), area = 'downtown'},
{name = 'Alta Street', coords = vector4(64.831, -254.602, 48.188, 73.582), area = 'downtown'},
{name = 'Textile City', coords = vector4(465.794, -735.723, 27.364, 94.413), area = 'downtown'},
{name = 'Little Seoul', coords = vector4(-599.346, -1014.915, 22.320, 94.416), area = 'downtown'},
{name = 'Strawberry Ave', coords = vector4(170.282, -1336.812, 29.294, 274.828), area = 'downtown'},
{name = 'Pillbox Hill', coords = vector4(109.546, -637.068, 44.244, 71.236), area = 'downtown'},
-- South area (easy + medium + hard)
{name = 'Davis Avenue', coords = vector4(144.045, -1656.479, 29.331, 224.277), area = 'south'},
{name = 'Grove Street', coords = vector4(-33.411, -1847.319, 26.194, 316.136), area = 'south'},
{name = 'Forum Drive', coords = vector4(-68.637, -1526.377, 34.232, 316.139), area = 'south'},
{name = 'Carson Avenue', coords = vector4(289.026, -1792.492, 28.085, 316.141), area = 'south'},
{name = 'Jamestown St', coords = vector4(414.488, -1856.189, 27.323, 248.963), area = 'south'},
{name = 'Brouge Ave', coords = vector4(280.533, -1693.791, 29.266, 47.242), area = 'south'},
-- East area (medium + hard)
{name = 'La Mesa', coords = vector4(967.672, -1868.346, 31.293, 164.071), area = 'east'},
{name = 'Mirror Park', coords = vector4(1052.860, -470.789, 63.899, 261.804), area = 'east'},
{name = 'East Vinewood', coords = vector4(920.664, -238.729, 70.155, 141.169), area = 'east'},
{name = 'El Burro Heights', coords = vector4(1258.298, -1760.014, 49.260, 21.906), area = 'east'},
{name = 'Nikola Pl', coords = vector4(1301.221, -573.285, 71.732, 341.826), area = 'east'},
{name = 'West Mirror Drive', coords = vector4(997.295, -729.228, 57.816, 311.708), area = 'east'},
-- West area (medium + hard)
{name = 'Vespucci', coords = vector4(-741.845, -981.528, 17.057, 21.909), area = 'west'},
{name = 'Del Perro', coords = vector4(-1329.337, -938.335, 12.350, 21.913), area = 'west'},
{name = 'Pacific Bluffs', coords = vector4(-1919.172, -555.874, 11.761, 146.599), area = 'west'},
{name = 'Vespucci Beach', coords = vector4(-1300.161, -1233.251, 4.486, 287.639), area = 'west'},
{name = 'Cortes St', coords = vector4(-1350.137, -1161.485, 4.507, 90.788), area = 'west'},
{name = 'Magellan Ave', coords = vector4(-1150.644, -1473.933, 4.380, 125.439), area = 'west'},
-- Vinewood area (hard + vip)
{name = 'Vinewood Hills', coords = vector4(-678.681, 511.421, 113.526, 196.112), area = 'vinewood'},
{name = 'Eclipse Towers', coords = vector4(-769.712, 299.446, 85.696, 178.487), area = 'vinewood'},
{name = 'Rockford Hills', coords = vector4(-848.892, 103.825, 53.004, 87.441), area = 'vinewood'},
{name = 'Burton', coords = vector4(-437.419, -67.358, 43.004, 241.881), area = 'vinewood'},
{name = 'Kimble Hill Dr', coords = vector4(-232.659, 588.454, 190.536, 355.189), area = 'vinewood'},
{name = 'St. Mo Milton Drive', coords = vector4(-1022.598, 588.308, 103.233, 1.627), area = 'vinewood'},
-- County area (hard only - long distance)
{name = 'Sandy Shores', coords = vector4(1881.399, 3810.771, 32.779, 304.496), area = 'county'},
{name = 'Grapeseed', coords = vector4(1658.561, 4839.306, 42.035, 279.472), area = 'county'},
{name = 'Paleto Bay', coords = vector4(-266.545, 6249.542, 31.476, 50.115), area = 'county'},
{name = 'Harmony', coords = vector4(980.211, 2667.751, 40.061, 1.370), area = 'county'},
{name = 'Cholla Springs Ave', coords = vector4(1809.107, 3907.363, 33.744, 193.180), area = 'county'},
{name = 'Paleto Blvd', coords = vector4(-347.303, 6225.094, 31.884, 225.953), area = 'county'},
},
-- ═══════════════════════════════════════════════════════════════════════════
-- DIFFICULTY CONFIG
-- Settings for each difficulty level
-- ═══════════════════════════════════════════════════════════════════════════
Difficulty = {
easy = {
areas = {'south'}, -- Which delivery areas are used
timePerPackage = 120, -- Seconds allowed per package
payMultiplier = 1.0 -- Payment multiplier (1.0 = 100%)
},
medium = {
areas = {'downtown', 'south', 'west'},
timePerPackage = 50,
payMultiplier = 1.3 -- 30% more pay
},
hard = {
areas = {'east', 'west', 'vinewood'},
timePerPackage = 45,
payMultiplier = 1.6 -- 60% more pay
},
vip = {
areas = {'county'},
timePerPackage = 35, -- Less time but higher pay
payMultiplier = 2.5, -- 150% more pay
bonusPerPackage = 50 -- Extra bonus per package ($)
}
},
-- ═══════════════════════════════════════════════════════════════════════════
-- MULTIPLIERS CONFIG
-- Bonus multipliers based on performance
-- ═══════════════════════════════════════════════════════════════════════════
Multipliers = {
-- Speed bonus based on time remaining (threshold = % of time left)
Speed = {
excellent = {threshold = 0.5, multiplier = 1.5, label = 'mult_excellent'}, -- 50%+ time left = 1.5x
good = {threshold = 0.3, multiplier = 1.25, label = 'mult_good'}, -- 30%+ time left = 1.25x
normal = {threshold = 0.1, multiplier = 1.0, label = 'mult_normal'}, -- 10%+ time left = 1.0x
slow = {threshold = 0, multiplier = 0.75, label = 'mult_slow'} -- Less than 10% = 0.75x
},
-- Condition bonus based on vehicle damage
Condition = {
perfect = {maxDamage = 0.05, multiplier = 1.3, label = 'mult_perfect'}, -- <5% damage = 1.3x
good = {maxDamage = 0.15, multiplier = 1.15, label = 'mult_good'}, -- <15% damage = 1.15x
acceptable = {maxDamage = 0.30, multiplier = 1.0, label = 'mult_acceptable'}, -- <30% damage = 1.0x
damaged = {maxDamage = 0.50, multiplier = 0.8, label = 'mult_damaged'} -- <50% damage = 0.8x
},
-- Combo system for consecutive successful deliveries
Combo = {
enabled = true, -- Enable combo system
maxCombo = 10, -- Maximum combo count
multiplierPerCombo = 0.05, -- 5% bonus per combo level (10 combo = 50% bonus)
resetOnFail = true, -- Reset combo on failed delivery
bonusAtMax = 500 -- Bonus cash when reaching max combo ($)
},
},
-- ═══════════════════════════════════════════════════════════════════════════
-- LEVELING CONFIG
-- XP and level progression system
-- ═══════════════════════════════════════════════════════════════════════════
Leveling = {
enabled = true, -- Enable leveling system
xpPerPackage = 10, -- XP earned per package delivered
xpBonusVIP = 5, -- Extra XP for VIP deliveries
xpBonusCombo = 5, -- Extra XP per combo level
levels = {
-- level: Player level number
-- xpRequired: Total XP needed to reach this level
-- title: Localization key for level title
-- payBonus: Payment multiplier at this level
{level = 1, xpRequired = 0, title = 'level_1', payBonus = 1.0},
{level = 2, xpRequired = 200, title = 'level_2', payBonus = 1.05},
{level = 3, xpRequired = 500, title = 'level_3', payBonus = 1.10},
{level = 4, xpRequired = 1000, title = 'level_4', payBonus = 1.15},
{level = 5, xpRequired = 2000, title = 'level_5', payBonus = 1.20},
{level = 6, xpRequired = 3500, title = 'level_6', payBonus = 1.25},
{level = 7, xpRequired = 5500, title = 'level_7', payBonus = 1.30},
{level = 8, xpRequired = 8000, title = 'level_8', payBonus = 1.35},
{level = 9, xpRequired = 12000, title = 'level_9', payBonus = 1.40},
{level = 10, xpRequired = 20000, title = 'level_10', payBonus = 1.50} -- Max level = 50% pay bonus
}
},
-- ═══════════════════════════════════════════════════════════════════════════
-- MISC CONFIG
-- ═══════════════════════════════════════════════════════════════════════════
Leaderboard = {
enabled = true, -- Enable leaderboard system
maxPlayers = 10 -- Number of players shown on leaderboard
},
-- ═══════════════════════════════════════════════════════════════════════════
-- CO-OP CONFIG
-- Settings for cooperative deliveries with multiple players
-- ═══════════════════════════════════════════════════════════════════════════
CoOp = {
enabled = true, -- Enable co-op deliveries
maxPlayers = 2, -- Maximum players in a co-op team
inviteRadius = 10.0, -- Distance in meters to invite nearby players
inviteTimeout = 30, -- Seconds before invite expires
sharedPayment = true, -- If true, all players get full payment. If false, payment is split
bonusPerPlayer = 0.1, -- 10% bonus per additional player (0.1 = 10%)
leaderCanKick = true -- Leader can kick players from team
},
-- ═══════════════════════════════════════════════════════════════════════════
-- TUTORIAL CONFIG
-- In-game tutorial with markers and guide text
-- ═══════════════════════════════════════════════════════════════════════════
Tutorial = {
enabled = true, -- Enable tutorial for new players
markerType = 20, -- Marker type for tutorial highlights
markerColor = {r = 66, g = 135, b = 245, a = 200}, -- Blue marker color
markerSize = vector3(1.5, 1.5, 1.5), -- Marker size
blipSprite = 162, -- Tutorial blip sprite
blipColor = 3, -- Blue blip
},
Misc = {
penaltyForFail = 100, -- Money deducted when delivery fails ($)
deliveryBlip = { -- GPS blip for current delivery location
sprite = 501, -- Blip icon
color = 5, -- Blip color (yellow)
scale = 0.8, -- Blip size
route = true, -- Show GPS route
routeColor = 5 -- Route line color
}
},
-- ═══════════════════════════════════════════════════════════════════════════
-- VEHICLE KEYS CONFIG
-- Integration with vehicle key systems
-- ═══════════════════════════════════════════════════════════════════════════
Keys = {
enable = true, -- Enable vehicle key integration
GiveKey = function(vehicle, plate) -- Function to give keys to player (edit for your key system)
-- Default: QBCore vehicle keys
TriggerEvent("vehiclekeys:client:SetOwner", plate)
-- For other systems, replace with:
-- ESX: TriggerEvent('esx_vehiclelock:setVehicleOwnedStatus', plate, true)
-- jaksam: exports['jaksam-vehicles']:GiveKeys(plate)
-- qs-vehiclekeys: TriggerEvent('qs-vehiclekeys:client:GiveKeys', plate)
end
},
Fuel = {
enable = true, -- Enable fuel consumption for delivery vehicles
AddFuel = function(vehicle, fuelLevel) -- Function to add fuel to vehicle (edit for your fuel system)
-- Example for LegacyFuel system
exports['LegacyFuel']:SetFuel(vehicle, fuelLevel)
--SetVehicleFuelLevel(vehicle, fuelLevel)
end,
},
Uniform = {
enable = true, -- Enable uniform for delivery job
-- Uniform outfits per gender (male/female)
outfits = {
male = {
['tshirt_1'] = 15, ['tshirt_2'] = 0,
['torso_1'] = 241, ['torso_2'] = 0,
['arms'] = 0,
['pants_1'] = 97, ['pants_2'] = 1,
['shoes_1'] = 25, ['shoes_2'] = 0,
},
female = {
['tshirt_1'] = 15, ['tshirt_2'] = 0,
['torso_1'] = 249, ['torso_2'] = 0,
['arms'] = 0,
['pants_1'] = 101, ['pants_2'] = 1,
['shoes_1'] = 27, ['shoes_2'] = 0,
}
},
SetUniform = function(outfit)
if GetResourceState('es_extended') == 'started' then
TriggerEvent('skinchanger:getSkin', function(skin)
for k, v in pairs(outfit) do
skin[k] = v
end
TriggerEvent('skinchanger:loadSkin', skin)
end)
elseif GetResourceState('qb-core') == 'started' or GetResourceState('qbx_core') == 'started' then
TriggerEvent('qb-clothing:client:loadOutfit', {
outfitData = {
['t-shirt'] = {item = outfit['tshirt_1'], texture = outfit['tshirt_2']},
['torso2'] = {item = outfit['torso_1'], texture = outfit['torso_2']},
['arms'] = {item = outfit['arms'], texture = 0},
['pants'] = {item = outfit['pants_1'], texture = outfit['pants_2']},
['shoes'] = {item = outfit['shoes_1'], texture = outfit['shoes_2']},
}
})
elseif GetResourceState('ox_core') == 'started' then
exports['illenium-appearance']:setPlayerAppearance(outfit)
end
end,
SaveClothes = function()
if GetResourceState('es_extended') == 'started' then
local skin = nil
TriggerEvent('skinchanger:getSkin', function(s) skin = s end)
Wait(100)
return skin
elseif GetResourceState('qb-core') == 'started' or GetResourceState('qbx_core') == 'started' then
local clothes = {}
for i = 0, 11 do
clothes[i] = {
drawable = GetPedDrawableVariation(cache.ped, i),
texture = GetPedTextureVariation(cache.ped, i)
}
end
return clothes
elseif GetResourceState('ox_core') == 'started' then
local clothes = exports['illenium-appearance']:getPedAppearance(cache.ped) or {}
return clothes
end
end,
RestoreClothes = function(savedClothes)
if not savedClothes then return end
if GetResourceState('es_extended') == 'started' then
TriggerEvent('skinchanger:loadSkin', savedClothes)
elseif GetResourceState('qb-core') == 'started' or GetResourceState('qbx_core') == 'started' then
for i = 0, 11 do
if savedClothes[i] then
SetPedComponentVariation(cache.ped, i, savedClothes[i].drawable, savedClothes[i].texture, 0)
end
end
elseif GetResourceState('ox_core') == 'started' then
exports['illenium-appearance']:setPlayerAppearance(savedClothes)
end
end,
}
}Supported Frameworks
Last updated