Início › Documentação › Ações do menu rápido · origen_ilegalv2

Ações do menu rápido · origen_ilegalv2

Config.QuickMenu.Actions define as entradas que aparecem no menu F6 quando o jogador está perto de outro jogador. Cada ação é executada no servidor através de um handler que declaras em linha.

Podes adicionar as tuas próprias ações sem mexer no código do núcleo: basta acrescentar entradas ao array.


Anatomia de uma ação

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,
        },
    },
}

Campos

Campo Tipo Obrigatório Descrição
id string sim Id único da ação. Usa-se para encaminhar a execução no servidor.
order number sim Ordem de apresentação no menu (ascendente).
label string sim Texto do botão. Pode ser texto simples ou uma chave de tradução (p. ex. quickmenu.actions.myaction.label).
icon string sim Classe do Font Awesome (p. ex. fa-solid fa-magnifying-glass).
requiredPermission string | nil sim Permissão de grau de que o jogador precisa. nil = qualquer membro da gangue.
canExecute(playerPed, targetPed) function não Filtro do lado do cliente chamado antes de enviar o pedido ao servidor. Devolve true para permitir, ou false, reason para bloquear com uma notificação.
onExecute(src, targetId) function sim Handler do lado do servidor. src é quem o executa e targetId é o jogador mais próximo num raio de 3 m.

O núcleo já valida a distância (3 m), a permissão e a existência de um alvo antes de chamar onExecute. Só tens de implementar o comportamento em si.


Sistema de permissões

Toda a ação que declara requiredPermission é verificada duas vezes:

  1. Cliente: a ação fica escondida no menu se HasPermission(action.requiredPermission) devolver false.
  2. Servidor: Gang:hasPermission(identifier, action.requiredPermission) é verificado de novo dentro de origen_gang:server:quickAction antes de executar onExecute. Proteção anti-manipulação por desenho.

Adicionar a tua própria flag de permissão

Declara a flag em cada grau de Config.Gang.DefaultRanks (config/gangs.lua). Qualquer flag que listes aí fica automaticamente:

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

Os graus que não tenham a flag definida explicitamente NÃO verão nem executarão a ação. As flags em falta valem false por omissão.


Exemplo 1 — reanimar um colega caído

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,
},

Exemplo 2 — dar dinheiro da gangue a um membro próximo

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,
},

Fluxo de execução

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)

O evento de cliente quickActionExecuted dispara-se no alvo: podes escutá-lo se a tua ação personalizada precisar que a vítima reproduza uma animação, mostre uma notificação, etc.


Filtro global — canInteract

Config.QuickMenu.canInteract(playerPed, targetPed) é executado antes de listar qualquer ação. Usa-o para bloquear todo o menu segundo regras próprias (p. ex. o alvo estar dentro de um veículo ou numa zona segura):

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

Se devolver false, escondem-se todas as ações por alvo dessa interação. O interruptor de ZoneSale e outras entradas que não dependem de um alvo não são afetados.


Alargar QuickActions (opcional)

As utilidades integradas estão em 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)

Se quiseres manter a tua lógica arrumada, podes adicionar a tua própria função à tabela QuickActions a partir de um ficheiro complementar e chamá-la a partir de 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,