Accueil › Documentation › Actions du menu rapide · origen_ilegalv2

Actions du menu rapide · origen_ilegalv2

Config.QuickMenu.Actions définit les entrées affichées dans le menu F6 quand le joueur est proche d’un autre joueur. Chaque action s’exécute côté serveur via un handler que tu déclares directement.

Tu peux ajouter tes propres actions sans toucher au code du cœur : il suffit d’ajouter des entrées au tableau.


Anatomie d’une action

luaconfig/interactions.lua
Config.QuickMenu = {
    Enable      = true,
    Key         = 'F6',
    UseCommand  = true,
    CommandName = 'quickmenu',
 
    canInteract = function(playerPed, targetPed)
        return true, nil
    end,
 
    Actions = {
        {
            id                 = 'search',
            order              = 1,
            label              = 'quickmenu.actions.search.label',
            icon               = 'fa-solid fa-magnifying-glass',
            requiredPermission = 'quick_search',
 
            canExecute = function(playerPed, targetPed)
                return true, nil
            end,
 
            onExecute = function(src, targetId)
                QuickActions.Search(src, targetId)
            end,
        },
    },
}

Champs

Champ Type Obligatoire Description
id string oui Id unique de l’action. Sert à router l’exécution côté serveur.
order number oui Ordre d’affichage dans le menu (croissant).
label string oui Texte du bouton. Peut être un texte brut ou une clé de traduction (p. ex. quickmenu.actions.myaction.label).
icon string oui Classe Font Awesome (p. ex. fa-solid fa-magnifying-glass).
requiredPermission string | nil oui Permission de grade dont le joueur a besoin. nil = n’importe quel membre du gang.
canExecute(playerPed, targetPed) function non Filtre côté client appelé avant d’envoyer la requête au serveur. Renvoie true pour autoriser, ou false, reason pour bloquer avec une notification.
onExecute(src, targetId) function oui Handler côté serveur. src est l’appelant et targetId est le joueur le plus proche dans un rayon de 3 m.

Le cœur valide déjà la distance (3 m), la permission et l’existence d’une cible avant d’appeler onExecute. Tu n’as qu’à implémenter le comportement lui-même.


Système de permissions

Toute action qui déclare requiredPermission est contrôlée deux fois :

  1. Client : l’action est masquée du menu si HasPermission(action.requiredPermission) renvoie false.
  2. Serveur : Gang:hasPermission(identifier, action.requiredPermission) est vérifié à nouveau dans origen_gang:server:quickAction avant d’exécuter onExecute. Protection anti-manipulation par conception.

Ajouter ton propre flag de permission

Déclare le flag sur chaque grade de Config.Gang.DefaultRanks (config/gangs.lua). Tout flag que tu y listes est automatiquement :

luaconfig/gangs.lua — DefaultRanks
{
    id = 1, name = "Leader",
    permissions = {
        -- ... existing flags ...
        quick_revive = true,   -- 👈 new flag
    },
},
{
    id = 3, name = "Member",
    permissions = {
        quick_revive = false,
    },
},

Les grades dont le flag n’est pas explicitement défini ne verront pas l’action et ne pourront pas l’exécuter. Les flags manquants valent false par défaut.


Exemple 1 — réanimer un coéquipier à terre

luaconfig/interactions.lua — Actions
{
    id                 = 'revive',
    order              = 6,
    label              = 'quickmenu.actions.revive.label',
    icon               = 'fa-solid fa-heart-pulse',
    requiredPermission = 'quick_revive',
 
    -- Client gate: only show/allow if the target is dead
    canExecute = function(playerPed, targetPed)
        if not IsPedDeadOrDying(targetPed, true) then
            return false, 'target_not_dead'
        end
        return true, nil
    end,
 
    -- Server handler
    onExecute = function(src, targetId)
        TriggerClientEvent('hospital:client:Revive', targetId)
        -- Optional: charge an item, log the action, etc.
    end,
},

Exemple 2 — donner l’argent du gang à un membre proche

luaconfig/interactions.lua — Actions
{
    id                 = 'give_cash',
    order              = 7,
    label              = 'quickmenu.actions.give_cash.label',
    icon               = 'fa-solid fa-hand-holding-dollar',
    requiredPermission = 'withdraw',   -- reuses the existing bank permission
 
    canExecute = function(playerPed, targetPed)
        if #(GetEntityCoords(playerPed) - GetEntityCoords(targetPed)) > 2.0 then
            return false, 'too_far'
        end
        return true, nil
    end,
 
    onExecute = function(src, targetId)
        local gang = Gang.GetPlayerGangBySource(src)
        if not gang then return end
 
        local amount = 500
        if gang.bank < amount then
            NotifyPlayer(src, 'Not enough funds', 'error')
            return
        end
 
        gang.bank = gang.bank - amount
        -- give to target via your framework API
        exports.ox_inventory:AddItem(targetId, 'money', amount)
 
        gang:addLog(GetPlayerIdentifier(src), 'quick_give_cash', {
            amount = amount,
            target = GetPlayerName(targetId),
        })
    end,
},

Flux d’exécution

text
[F6] ─▶ OpenQuickMenu()
         │
         ├─▶ GetAvailableActions()        (client-side permission filter)
         │
         └─▶ player picks action
                 │
                 ├─▶ canExecute()         (client gate, optional)
                 │
                 └─▶ TriggerServerEvent('origen_gang:server:quickAction', id, targetId)
                         │
                         ├─▶ validate Config.Actions[id] exists
                         ├─▶ validate gang:hasPermission(requiredPermission)
                         ├─▶ validate target is within 3m (lib.getClosestPlayer)
                         │
                         └─▶ action.onExecute(src, targetId)
                                 │
                                 └─▶ TriggerClientEvent('origen_gang:client:quickActionExecuted', targetId, id, src)

L’événement client quickActionExecuted se déclenche sur la cible : tu peux l’écouter si ton action personnalisée doit faire jouer une animation à la victime, afficher une notification, etc.


Filtre global — canInteract

Config.QuickMenu.canInteract(playerPed, targetPed) s’exécute avant de lister la moindre action. Utilise-le pour bloquer tout le menu selon tes propres règles (p. ex. la cible est dans un véhicule ou dans une zone sûre) :

lua
canInteract = function(playerPed, targetPed)
    if IsPedInAnyVehicle(targetPed, false) then
        return false, 'target_in_vehicle'
    end
    return true, nil
end,

S’il renvoie false, toutes les actions par cible sont masquées pour cette interaction. L’interrupteur ZoneSale et les autres entrées qui ne dépendent pas d’une cible ne sont pas affectés.


Étendre QuickActions (facultatif)

Les utilitaires intégrés se trouvent dans server/functions/f_quick_actions.lua :

lua
QuickActions.Search(src, targetId)
QuickActions.Handcuff(src, targetId)
QuickActions.Escort(src, targetId)
QuickActions.PutInVehicle(src, targetId)
QuickActions.TakeOutVehicle(src, targetId)

Si tu veux garder ta logique bien rangée, tu peux ajouter ta propre fonction à la table QuickActions depuis un fichier complémentaire et l’appeler depuis onExecute :

luaserver/custom/qa_revive.lua
QuickActions = QuickActions or {}
 
function QuickActions.Revive(src, targetId)
    TriggerClientEvent('hospital:client:Revive', targetId)
end
luaconfig/interactions.lua
onExecute = function(src, targetId)
    QuickActions.Revive(src, targetId)
end,