Configuration
The config.lua options explained, and the full file.
config.lua holds the technical settings (jobs, commands, billing, vehicles, bridge). Price lists (prices, durations, wear, grade permissions…) are tuned in game with /mecagestion. Values in shared/sh_config.lua are only defaults.
#General
Config.Debug = false
Config.Brand = 'TC Mécanique' -- name shown in the interfaces and logs#Mechanic jobs
A player is a “mechanic” if their job carries one of these names or if their job type (field type: Vision, modified ESX, recent QBCore) equals Config.JobType.
Config.JobType = 'mecano'
Config.MechanicJobs = { 'mechanic' } -- e.g. { 'mechanic', 'bennys', 'lscustoms' }#Staff rights
Config.GestionPermission = 'gestion_mecano' -- Vision: /gestion panel permissionOutside Vision, rights come from Config.Bridge (ACE command, admin group, Admins = { 'license:…' }).
#Commands
Config.Commands = {
Tablet = 'atelier', -- workshop tablet (mechanics)
Gestion = 'mecagestion', -- management panel (staff)
Diag = 'mecadiag', -- technical diagnostic report (staff / console)
Funds = 'mecafonds', -- internal cash box: /mecafonds <job> [withdrawal]
}#Distances (metres)
Config.Distances = { Point = 4.0, Vehicle = 8.0, Customer = 8.0, Diagnostic = 6.0 }#Billing
| Option | Role |
|---|---|
Config.BillingMode | auto (default), builtin, invoice or none — see Billing |
Config.CashLimit | Maximum invoice amount payable in cash (default 2500). Above it: bank only. 0 = no limit |
#Owned vehicles
SQL table of your framework's vehicles: the script reads the owner and properties from it, and writes the final changes back.
Config.Vehicles = {
vision = { table = 'vehicles', plate = 'plate', owner = 'owner', coOwner = 'co_owner', props = 'prop', fakePlate = 'fake_plate' },
esx = { table = 'owned_vehicles', plate = 'plate', owner = 'owner', coOwner = nil, props = 'vehicle' },
qbcore = { table = 'player_vehicles', plate = 'plate', owner = 'citizenid', coOwner = nil, props = 'mods' },
qbox = { table = 'player_vehicles', plate = 'plate', owner = 'citizenid', coOwner = nil, props = 'mods' },
}A vehicle must be registered (bought / owned) in this table to be orderable. If your database uses other table or column names, adapt them here.
#Interface and points
Config.GestionIcon = { path = 'assets/icons', name = 'tool.svg' } -- icon in the Vision staff panel
Config.PointIcons = { custom = 'Catalogue', paint = 'Catalogue', wheels = 'Catalogue', diagnostic = 'Catalogue', parts = 'Catalogue' }
Config.Blip = { sprite = 544, color = 3, scale = 0.5 } -- blip of points flagged “blip”#Optional integrations
Config.Integrations = { compta = true, logs = true } -- used only if the resource is started
Config.LogsWebhook = 'mecanique.default' -- tc-logs channel used for the journal#Bridge
Config.Bridge = {
Framework = 'auto', -- 'auto' | 'vision' | 'esx' | 'qbcore' | 'qbox' | 'standalone'
Inventory = 'auto', -- not used by this script
Target = 'auto', -- 'auto' | 'ox_target' | 'qb-target' | 'none' (fallback: marker + E key)
Society = 'auto', -- 'auto' | 'vision' | 'renewed' | 'qb-banking' | 'okok' | 'esx_society' | 'qbx' | 'internal'
Callbacks = 'auto',
Debug = false,
Admins = {},
AdminAce = 'command',
InteractKey = 38, -- fallback key without target (38 = E)
Standalone = {},
}#Standalone mode
Without a framework, provide your functions in Config.Bridge.Standalone:
| Function | Returns |
|---|---|
getJob(src) | { name, label, grade, gradeName, gradeLabel, isBoss, onDuty } |
getMoney(src, account) | number |
removeMoney / addMoney(src, account, amount, reason) | boolean |
vehicleRow(plate) | { plate, owner, co_owner, prop } or nil (prop = JSON of properties) |
saveVehicleProps(plate, props) | boolean |
createInvoice(data) | id or nil |
#Full files
Show config.lua (121 lines)
-- ============================================================================
-- tc-mechanic : configuration / configuration file
-- Ce fichier est chargé en premier (client + serveur). Il reste lisible (non chiffré).
-- This file is loaded first (client + server). It is never encrypted.
--
-- Les barèmes (prix, durées, usure, permissions par grade…) se règlent EN JEU via
-- /mecagestion ; les valeurs de shared/sh_config.lua ne sont que les valeurs par défaut.
-- Prices, durations, wear and grade permissions are edited IN GAME with /mecagestion;
-- shared/sh_config.lua only holds the defaults.
-- ============================================================================
Config = {}
-- ─── Général / General ───────────────────────────────────────────────────────
Config.Debug = false
-- Nom affiché dans les interfaces et les logs / Name shown in the UI and logs
Config.Brand = 'TC Mécanique'
-- ─── Métiers mécaniciens / Mechanic jobs ─────────────────────────────────────
-- Un joueur est « mécanicien » si son job porte l'un de ces noms OU si le type de son job
-- (champ `type` : Vision, ESX modifié, QBCore récent) vaut Config.JobType.
-- A player is a "mechanic" if his job name is listed here OR his job `type` equals Config.JobType.
Config.JobType = 'mecano'
Config.MechanicJobs = { 'mechanic' } -- ex. { 'mechanic', 'bennys', 'lscustoms' }
-- ─── Droits staff / Staff access ─────────────────────────────────────────────
-- Vision : permission staff du panneau /gestion (permissions globales du joueur).
-- Autres frameworks : les droits viennent de Config.Bridge (ACE `command`, groupe admin, Admins = { 'license:…' }).
Config.GestionPermission = 'gestion_mecano'
-- ─── Commandes / Commands ────────────────────────────────────────────────────
Config.Commands = {
Tablet = 'atelier', -- tablette atelier (mécaniciens)
Gestion = 'mecagestion', -- panneau de gestion (staff)
Diag = 'mecadiag', -- rapport de diagnostic technique (staff / console)
Funds = 'mecafonds', -- caisse interne (staff / console) : /mecafonds <job> [retrait]
}
-- ─── Distances (mètres) ──────────────────────────────────────────────────────
Config.Distances = {
Point = 4.0,
Vehicle = 8.0,
Customer = 8.0,
Diagnostic = 6.0,
}
Config.WearVehicleTypes = { automobile = true, bike = true, quadbike = true, amphibious_automobile = true }
-- ─── Facturation / Billing ───────────────────────────────────────────────────
-- 'auto' : 'builtin' si une caisse société est utilisable, sinon 'invoice' si un système de factures est présent
-- 'builtin' : le client règle dans la fenêtre du script (banque ou espèces), l'argent va dans la caisse du job
-- (Bridge société : Config.Bridge.Society ; à défaut caisse interne tc_mech_funds)
-- 'invoice' : facture du framework (Vision : core CreateInvoice ; autres : Config.Bridge.Standalone.createInvoice)
-- 'none' : pas de facturation (tests)
Config.BillingMode = 'auto'
-- Montant maximum d'une facture payable en espèces ($). Au-delà : banque uniquement. 0 = pas de limite.
-- Maximum invoice amount payable in cash. 0 = no limit.
Config.CashLimit = 2500
-- ─── Véhicules / Vehicles ────────────────────────────────────────────────────
-- Table SQL des véhicules possédés, selon le framework (lecture du propriétaire + des props, écriture des props).
-- Owned-vehicle table per framework (owner lookup + vehicle properties read/write).
Config.Vehicles = {
vision = { table = 'vehicles', plate = 'plate', owner = 'owner', coOwner = 'co_owner', props = 'prop', fakePlate = 'fake_plate' },
esx = { table = 'owned_vehicles', plate = 'plate', owner = 'owner', coOwner = nil, props = 'vehicle' },
qbcore = { table = 'player_vehicles', plate = 'plate', owner = 'citizenid', coOwner = nil, props = 'mods' },
qbox = { table = 'player_vehicles', plate = 'plate', owner = 'citizenid', coOwner = nil, props = 'mods' },
}
-- ─── Interface staff Vision / Vision staff panel icon ────────────────────────
Config.GestionIcon = { path = 'assets/icons', name = 'tool.svg' }
-- Icône de l'invite d'interaction par type de point (Vision) / Interaction prompt icon per point type (Vision)
Config.PointIcons = {
custom = 'Catalogue',
paint = 'Catalogue',
wheels = 'Catalogue',
diagnostic = 'Catalogue',
parts = 'Catalogue',
}
-- Blip des points marqués « blip » / Blip of points flagged "blip"
Config.Blip = { sprite = 544, color = 3, scale = 0.5 }
-- ─── Intégrations optionnelles / Optional integrations ───────────────────────
-- Chaque intégration n'est utilisée que si la ressource est démarrée ET le réglage vaut true.
-- Each integration is used only if the resource is started AND the flag is true.
Config.Integrations = {
compta = true, -- tc-compta : contrats partenaires (réductions) à la facturation
logs = true, -- tc-logs : copie du journal vers Discord
}
-- Canal (webhook) de tc-logs utilisé pour le journal / tc-logs channel used for the journal
Config.LogsWebhook = 'mecanique.default'
-- ─── Couche de compatibilité / Compatibility layer ───────────────────────────
-- Framework : 'auto' détecte vision → qbox → qbcore → esx → standalone.
-- Framework: 'auto' detects vision → qbox → qbcore → esx → standalone.
-- Forcer / Force : 'vision' | 'esx' | 'qbcore' | 'qbox' | 'standalone'
Config.Bridge = {
Framework = 'auto',
Inventory = 'auto', -- 'auto' | 'ox_inventory' | 'qs-inventory' | 'qb-inventory' | 'framework' | 'none' (non utilisé par ce script)
Target = 'auto', -- 'auto' | 'ox_target' | 'qb-target' | 'none' (repli : marqueur + touche E)
Society = 'auto', -- 'auto' | 'vision' | 'renewed' | 'qb-banking' | 'okok' | 'esx_society' | 'qbx' | 'internal'
Callbacks = 'auto', -- 'auto' | 'native' (callbacks du framework ; sans ox_lib importé, le script utilise de toute façon les siens)
Debug = false, -- logs de la couche de compatibilité / bridge debug logs
Admins = {}, -- identifiants admin supplémentaires, ex. { 'license:xxxxxxxx' } / extra admin identifiers
AdminAce = 'command', -- ACE testée pour les droits staff (add_ace group.admin command allow)
InteractKey = 38, -- touche du repli sans target (38 = E)
-- Frameworks sans équivalent (standalone) : fournis tes propres fonctions.
-- Standalone / unsupported framework: provide your own functions.
-- getJob(src) -> { name, label, grade, gradeName, gradeLabel, isBoss, onDuty }
-- getMoney(src, account) -> nombre removeMoney / addMoney(src, account, amount, reason) -> bool
-- vehicleRow(plate) -> { plate, owner, co_owner, prop } ou nil (prop = JSON des propriétés)
-- saveVehicleProps(plate, props) -> bool
-- createInvoice(data) -> id ou nil (voir bridge/mechanic_server.lua)
Standalone = {},
}Show sh_config.lua (161 lines)
TCM = TCM or {}
TCM.Resource = GetCurrentResourceName()
TCM.Version = '1.7.2'
-- Réglages techniques : voir config.lua (global `Config`). / Technical settings: see config.lua.
TCM.Config = Config
TCM.Brand = Config.Brand or 'TC Mécanique'
TCM.PointTypes = {
custom = { label = 'Personnalisation', hint = 'Personnaliser le véhicule', customer = true },
paint = { label = 'Poste peinture', hint = 'Configurer la peinture', customer = true },
wheels = { label = 'Roues & pneus', hint = 'Choisir roues et pneus', customer = true },
diagnostic = { label = 'Diagnostic', hint = 'Point de diagnostic', customer = false },
parts = { label = 'Stock de pièces', hint = 'Récupérer une pièce', customer = false },
}
TCM.Actions = {
{ id = 'tablet', label = 'Ouvrir la tablette' },
{ id = 'take', label = 'Prendre en charge une commande' },
{ id = 'work', label = 'Réaliser les étapes (pose, peinture, entretien)' },
{ id = 'diagnostic', label = 'Diagnostic et devis' },
{ id = 'invoice', label = 'Facturer et clôturer' },
{ id = 'cancel', label = 'Annuler / restaurer une commande' },
{ id = 'history', label = 'Consulter l’historique' },
{ id = 'manage', label = 'Régler les permissions de l’atelier' },
}
TCM.Defaults = {
general = {
requireOnDuty = true,
requireMechanicOnline = true,
requireOwnership = true,
quoteValidityMin = 30,
maxOpenOrdersPerJob = 40,
},
pricing = {
classMultiplier = {
["0"] = 0.9, ["1"] = 1.0, ["2"] = 1.1, ["3"] = 1.1, ["4"] = 1.15, ["5"] = 1.3, ["6"] = 1.4, ["7"] = 1.8,
["8"] = 0.8, ["9"] = 1.1, ["10"] = 1.2, ["11"] = 1.0, ["12"] = 1.0, ["13"] = 0.5, ["14"] = 1.0, ["15"] = 1.0,
["16"] = 1.0, ["17"] = 1.0, ["18"] = 1.0, ["19"] = 1.2, ["20"] = 1.1, ["21"] = 1.0, ["22"] = 1.8,
},
laborPercent = 0,
cosmetic = { base = 350, perLevel = 30 },
slots = {},
performance = {
['11'] = { base = 3000, perLevel = 3000 },
['12'] = { base = 1500, perLevel = 1500 },
['13'] = { base = 2500, perLevel = 2000 },
['15'] = { base = 1500, perLevel = 1000 },
['18'] = { base = 12000, perLevel = 0 },
},
specials = {
windowTint = 400, plateIndex = 150, xenon = 900, xenonColor = 250,
neon = 1200, neonColor = 200, horn = 150, livery = 900,
},
wheels = {
rim = 450, perRimLevel = 0, customTyres = 350, driftTyres = 1200,
smoke = 400,
},
paint = {
primary = 1200, secondary = 800, pearl = 450, wheels = 300,
finishMultiplier = { ['0'] = 1.0, ['1'] = 1.15, ['2'] = 1.35, ['3'] = 1.25, ['4'] = 1.3, ['5'] = 2.0 },
},
repair = {
engine = { base = 150, perPercent = 22 },
body = { base = 120, perPercent = 16 },
tank = { base = 80, perPercent = 10 },
door = 260, window = 180, tyre = 220, headlight = 120, bumper = 320,
},
service = {
oil = { base = 180, perPercent = 3 },
engine = { base = 900, perPercent = 30 },
tyres = { base = 160, perPercent = 3 },
brakes = { base = 350, perPercent = 6 },
suspension = { base = 450, perPercent = 8 },
battery = { base = 250, perPercent = 3 },
plugs = { base = 200, perPercent = 3 },
},
},
durations = {
pick = 2500,
mod = 9000,
slots = {},
wheel = 7000,
paint = 18000,
repair = 9000,
service = 8000,
diagnose = 3500,
},
minigame = {
modes = { mod = 'both', wheel = 'minigame', repair = 'progress', service = 'both' },
difficulty = 'normal',
presets = {
easy = { zone = 0.26, speed = 0.75, hits = 2, sequence = 4, sequenceTime = 6500 },
normal = { zone = 0.18, speed = 1.0, hits = 3, sequence = 5, sequenceTime = 5500 },
hard = { zone = 0.12, speed = 1.35, hits = 4, sequence = 6, sequenceTime = 4500 },
},
maxFails = 3,
minMs = 3500,
},
wear = {
enabled = true,
tickSeconds = 5,
saveSeconds = 90,
broadcastStep = 0.5,
maxSpeedMs = 110.0,
classMultiplier = {
["8"] = 0.8, ["9"] = 1.2, ["10"] = 1.3, ["11"] = 1.1, ["20"] = 1.2,
},
rates = { oil = 0.080, engine = 0.012, tyres = 0.050, brakes = 0.030, suspension = 0.018, battery = 0.010, plugs = 0.020 },
style = {
hardBrake = { brakes = 0.20, tyres = 0.06 },
offroadMin = { tyres = 0.60, suspension = 0.45 },
highRpmMin = { engine = 0.05, oil = 0.12, plugs = 0.10 },
burnoutMin = { tyres = 2.5 },
},
oilCriticalEngineMultiplier = 3.0,
thresholds = { warn = 40, critical = 15 },
},
effects = {
start = 60,
engine = { minPower = 0.55 },
oil = { minPower = 0.75, stallChance = 0.10, engineDrain = 12.0, engineFloor = 350.0 },
tyres = { minGrip = 0.62, burstBelow = 8, burstChance = 0.08 },
brakes = { minForce = 0.35 },
suspension = { minForce = 0.45 },
battery = { failBelow = 20, failChance = 0.35, failMs = 3500 },
plugs = { minInertia = 0.60, misfireBelow = 25, misfireChance = 0.25 },
},
holds = {
box = { anim = 'hand', bone = 28422, x = 0.396, y = 0.041, z = -0.003, rx = -90.0, ry = 0.0, rz = 90.0 },
wheel = { anim = 'carry', bone = 18905, x = 0.02, y = 0.2, z = 0.31, rx = 130.0, ry = -80.0, rz = 0.0 },
door = { anim = 'carry', bone = 60309, x = 0.025, y = 0.08, z = 0.255, rx = -145.0, ry = 290.0, rz = 0.0 },
hood = { anim = 'carry', bone = 60309, x = 0.025, y = 0.08, z = 0.255, rx = -145.0, ry = 290.0, rz = 0.0 },
trunk = { anim = 'carry', bone = 60309, x = 0.025, y = 0.08, z = 0.255, rx = -145.0, ry = 290.0, rz = 0.0 },
bumper = { anim = 'carry', bone = 60309, x = 0.025, y = 0.08, z = 0.255, rx = -145.0, ry = 290.0, rz = 0.0 },
engine = { anim = 'carry', bone = 60309, x = 0.025, y = 0.08, z = 0.255, rx = -145.0, ry = 290.0, rz = 0.0 },
bulb = { anim = 'hand', bone = 57005, x = 0.10, y = 0.0, z = 0.0, rx = 0.0, ry = 270.0, rz = 60.0 },
spray = { anim = 'none', bone = 28422, x = 0.0, y = 0.0, z = 0.07, rx = 0.0, ry = 0.0, rz = 0.0 },
tablet = { anim = 'map', bone = 28422, x = 0.0, y = -0.03, z = 0.0, rx = 20.0, ry = -90.0, rz = 0.0 },
},
permissions = {
default = { tablet = 0, take = 0, work = 0, diagnostic = 0, invoice = 1, cancel = 2, history = 0, manage = 3 },
jobs = {},
},
}