Guides pratiques
Tutoriels concrets pour ox_target — emote, emote partagée, catégorie, interaction métier, export externe, zone, modèle, revive/heal sur mesure et action serveur sécurisée.
Chaque guide indique le fichier à modifier, un exemple copiable, le résultat attendu et les erreurs fréquentes. Les noms de ressources, d’événements et d’exports tiers utilisés dans les exemples (mon_pd, ma_banque, mon_hopital…) sont fictifs : remplacez-les par ceux de vos scripts. Après chaque modification d’un fichier config*.lua, exécutez restart ox_target.
Ajouter une emote
Fichier : config_interactions.lua, liste Config.SelfInteractions.
{ name = 'emote_dance', menu = 'self_emotes', label = 'Danser', icon = 'fa-solid fa-music', type = 'emote', emote = 'dance' },
Résultat : « Danser » apparaît dans la catégorie Emotes de Soi-même. Erreur fréquente : un nom d’emote inexistant dans votre script d’emotes ne joue rien, sans message.
Ajouter une emote partagée
Fichier : config_interactions.lua, liste Config.PlayerInteractions.
{ name = 'emote_hug2', menu = 'player_emotes', label = 'Câlin (variante)', icon = 'fa-solid fa-heart', type = 'shared_emote', emote = 'hug2' },
Résultat : en ciblant un joueur, Emotes › « Câlin (variante) » exécute nearby hug2, ce qui envoie la demande d’emote partagée au joueur le plus proche selon votre script d’emotes. Erreur fréquente : le preset n’utilise pas l’ID du joueur ciblé ; pour viser précisément ce joueur, définissez le hook PlaySharedEmote(emote, targetServerId).
Créer une catégorie
Fichier : config_interactions.lua.
{ name = 'services', label = 'Services', icon = 'fa-solid fa-briefcase', type = 'category', opens = 'services_menu' },
{ name = 'call_taxi', menu = 'services_menu', label = 'Appeler un taxi', icon = 'fa-solid fa-taxi', type = 'command', command = 'taxi' },
{ name = 'call_mechanic', menu = 'services_menu', label = 'Appeler un dépanneur', icon = 'fa-solid fa-wrench', type = 'command', command = 'depanneur' },
Résultat : un sous-menu « Services » avec deux commandes. Erreur fréquente : menu mal orthographié, l’option ne s’affiche jamais.
Interaction réservée à un métier
Fichier : config_interactions.lua, liste Config.PlayerInteractions.
{ name = 'pd_search', label = 'Fouiller', icon = 'fa-solid fa-magnifying-glass', jobs = { police = 1 }, type = 'client_event', event = 'mon_pd:fouiller' },
Résultat : seuls les policiers de grade 1 ou plus voient l’option. Attention : jobs masque l’option sans sécuriser l’événement. Votre ressource doit vérifier le métier côté serveur, ou utilisez une action serveur (dernier guide).
Appeler un export externe
Fichier : config_interactions.lua, liste Config.VehicleInteractions.
{ name = 'open_glovebox', label = 'Boîte à gants', icon = 'fa-solid fa-box', type = 'export', resource = 'mon_inventaire', export = 'OuvrirBoiteAGants' },
Résultat : exports.mon_inventaire:OuvrirBoiteAGants(target) est appelé avec l’objet target (netId, plate, entity…). Erreur fréquente : la ressource cible n’est pas démarrée ; F8 affiche une erreur dans l’option.
Ajouter une zone
Fichier : config_interactions.lua, liste Config.ZoneInteractions.
Config.ZoneInteractions = {
{
shape = 'box', name = 'mairie_accueil', coords = vec3(-544.9, -204.4, 38.2), size = vec3(1.4, 1.0, 2.0), rotation = 30,
options = {
{ name = 'mairie_papiers', label = 'Demander des papiers', icon = 'fa-solid fa-file-lines', type = 'client_event', event = 'ma_mairie:ouvrir' },
},
},
}
Résultat : un point de zone apparaît en visant le comptoir ; l’option est disponible à moins de Config.Distances.default (3 m). Pour placer la zone, utilisez Dev Tools › « Copier mes coords » et activez debug = true le temps de l’ajuster. Erreur fréquente : size absent pour une boîte, ou une forme poly (non gérée ici).
Interaction sur un modèle
Fichier : config_interactions.lua, liste Config.ModelInteractions.
Config.ModelInteractions = {
{
models = { 'prop_atm_01', 'prop_atm_02', 'prop_atm_03', 'prop_fleeca_atm' },
options = {
{ name = 'atm_use', label = 'Utiliser le distributeur', icon = 'fa-solid fa-money-bill', distance = 1.5, type = 'client_event', event = 'ma_banque:ouvrirAtm' },
},
},
}
Résultat : les distributeurs reçoivent un contour et l’option. Pour trouver un nom de modèle, utilisez Dev Tools › « Copier nom prop ».
Adapter revive et heal
Fichiers : config.lua puis config_server.lua et config_client.lua.
- Réglez
Config.MedicalScript = 'custom'. - Branchez votre script dans
config_server.lua:
Config.ServerHooks.RevivePlayer = function(source, targetId)
TriggerClientEvent('mon_hopital:revive', targetId)
return true
end
Config.ServerHooks.HealPlayer = function(source, targetId)
TriggerClientEvent('mon_hopital:soigner', targetId)
end
- Pour le revive/heal sur soi (
Config.Medical.selfMode = 'client'), dansconfig_client.lua:
Config.ClientHooks.ReviveSelf = function()
TriggerEvent('mon_hopital:revive')
end
Config.ClientHooks.HealSelf = function()
TriggerEvent('mon_hopital:soigner')
end
Résultat : les options Admin › Revive / Heal et Soi-même › Admin › Revive / Heal utilisent votre script, avec les permissions revive, heal, selfRevive, selfHeal. Erreur fréquente : RevivePlayer qui retourne false affiche « Aucun script médical configuré. ». Si votre script soigne déjà entièrement, passez Config.Medical.nativeHealFallback à false.
Brancher une action serveur sécurisée
Fichiers : config_server.lua et config_interactions.lua.
Config.ServerActions = {
give_fine = {
permission = 'everyone',
jobs = { police = 2 },
target = 'player',
maxDistance = 3.0,
cooldown = 5000,
args = { { type = 'number', integer = true, min = 50, max = 5000 } },
handler = function(ctx)
TriggerEvent('mon_pd:amende', ctx.source, ctx.target, ctx.args[1])
ctx.notify('Amende transmise.', 'success')
ctx.notifyTarget('Vous avez reçu une amende.', 'warning')
end,
},
}
{ name = 'give_fine', label = 'Amende 250 $', icon = 'fa-solid fa-receipt', jobs = { police = 2 }, type = 'server_action', action = 'give_fine', args = { 250 } },
Résultat : le serveur vérifie le métier (grade 2 minimum), l’existence et la distance du joueur ciblé, le montant (entier de 50 à 5 000) et l’anti-spam avant d’appeler le handler. Pour un montant saisi par le joueur, construisez args avec une fonction côté client : args = function(target) … return { montant } end. Erreur fréquente : oublier jobs dans la définition serveur ; celui de l’option ne fait que masquer.