Inicio › Documentación › Acciones del menú rápido · origen_ilegalv2
Config.QuickMenu.Actions define las entradas que se muestran en el menú F6 cuando el jugador está cerca de otro jugador. Cada acción se ejecuta en el servidor a través de un handler que declaras en línea.
Puedes añadir tus propias acciones sin tocar el código del núcleo: basta con añadir entradas al array.
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,
},
},
}| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
id |
string |
sí | Id único de la acción. Se usa para enrutar la ejecución en el servidor. |
order |
number |
sí | Orden de aparición en el menú (ascendente). |
label |
string |
sí | Texto del botón. Puede ser un texto plano o una clave de traducción (p. ej. quickmenu.actions.myaction.label). |
icon |
string |
sí | Clase de Font Awesome (p. ej. fa-solid fa-magnifying-glass). |
requiredPermission |
string | nil |
sí | Permiso de rango que necesita el jugador. nil = cualquier miembro de la banda. |
canExecute(playerPed, targetPed) |
function |
no | Filtro del lado del cliente que se llama antes de enviar la petición al servidor. Devuelve true para permitir, o false, reason para bloquear mostrando una notificación. |
onExecute(src, targetId) |
function |
sí | Handler del lado del servidor. src es quien lo ejecuta y targetId es el jugador más cercano en un radio de 3 m. |
El núcleo ya valida la distancia (3 m), el permiso y que exista un objetivo antes de llamar a onExecute. Solo tienes que implementar el comportamiento en sí.
Toda acción que declara requiredPermission se comprueba dos veces:
HasPermission(action.requiredPermission) devuelve false.Gang:hasPermission(identifier, action.requiredPermission) se vuelve a comprobar dentro de origen_gang:server:quickAction antes de ejecutar onExecute. Protección anti-manipulación por diseño.Declara el flag en cada rango de Config.Gang.DefaultRanks (config/gangs.lua). Cualquier flag que incluyas ahí queda automáticamente:
Gang:hasPermission().manage_ranks).{
id = 1, name = "Leader",
permissions = {
-- ... existing flags ...
quick_revive = true, -- 👈 new flag
},
},
{
id = 3, name = "Member",
permissions = {
quick_revive = false,
},
},Los rangos que no tengan el flag definido explícitamente NO verán ni ejecutarán la acción. Los flags ausentes valen false por defecto.
{
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,
},{
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,
},[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)El evento de cliente quickActionExecuted se dispara en el objetivo: puedes escucharlo si tu acción personalizada necesita que la víctima reproduzca una animación, muestre una notificación, etc.
canInteractConfig.QuickMenu.canInteract(playerPed, targetPed) se ejecuta antes de listar cualquier acción. Úsalo para bloquear todo el menú según reglas propias (p. ej. que el objetivo esté dentro de un vehículo o en una zona segura):
canInteract = function(playerPed, targetPed)
if IsPedInAnyVehicle(targetPed, false) then
return false, 'target_in_vehicle'
end
return true, nil
end,Si devuelve false, se ocultan todas las acciones por objetivo de esa interacción. El interruptor de ZoneSale y otras entradas que no dependen de un objetivo no se ven afectados.
QuickActions (opcional)Las utilidades integradas están en server/functions/f_quick_actions.lua:
QuickActions.Search(src, targetId)
QuickActions.Handcuff(src, targetId)
QuickActions.Escort(src, targetId)
QuickActions.PutInVehicle(src, targetId)
QuickActions.TakeOutVehicle(src, targetId)Si quieres mantener tu lógica ordenada, puedes añadir tu propia función a la tabla QuickActions desde un fichero complementario y llamarla desde onExecute:
QuickActions = QuickActions or {}
function QuickActions.Revive(src, targetId)
TriggerClientEvent('hospital:client:Revive', targetId)
endonExecute = function(src, targetId)
QuickActions.Revive(src, targetId)
end,