Interfaz compartida
notify, progress, menu, input, prompts, skillCheck, lockpick e itemPicker - la interfaz del jugador que dibuja ai-lib para todos los recursos.
ai-lib dibuja una única interfaz compartida para todos los recursos: tarjetas de notificación, la barra de progreso, los prompts de "pulsa E", menús, diálogos de entrada y minijuegos. Tu script solo los pide, así que todos los scripts del servidor se ven igual y no escribes NUI para estas cosas. El selector de objetos lo dibuja ai-core.
Los textos que pasas se muestran tal cual: tradúcelos primero (Locale("KEY") en TypeScript, t('KEY') en Lua).
Notificaciones
notify
Muestra una tarjeta de notificación en la pantalla de este jugador.
Lado: Cliente · Espera: no
notify(text: string, kind?: NotificationKind, duration?: number): voidaiLib.notify(text, kind, duration)Parámetros
Prop
Type
El tipo de kind es NotificationKind. Para notificar a un jugador desde el servidor, usa notify(source, text, kind) del servidor.
Devuelve
void.
Ejemplo
import { createLocale, notify } from "@aicore-fivem/lib/client";
const Locale = createLocale<typeof import("../../locales/en.json")>();
notify(Locale("WELCOME"));
notify(Locale("NO_MONEY"), "error");
notify(Locale("SAVED"), "success", 2000);Barra de progreso
progress
Ejecuta una acción temporizada con la barra de progreso de ai-lib y una animación o un escenario opcional, y espera hasta que termine. Termina antes (cancelada) cuando el jugador muere, se sube a un vehículo, pulsa la tecla de cancelar de ai-lib (por defecto Backspace, solo con canCancel) o tu script llama a cancelProgress(). Un progreso por recurso a la vez.
Lado: Cliente · Espera: sí (Promise en TypeScript, cede el hilo en Lua)
progress(options: ProgressOptions): Promise<boolean>local finished = aiLib.progress(options) -- boolean, llamar dentro de un hiloParámetros
Prop
Type
ProgressOptions
Prop
Type
Devuelve
Promise<boolean>: true cuando la barra terminó; false cuando se canceló, o al momento cuando otro progreso de tu recurso sigue en marcha. Lua devuelve el mismo booleano.
Ejemplo
import { callAction, createLocale, nearestVehicle, notify, progress } from "@aicore-fivem/lib/client";
const Locale = createLocale<typeof import("../../locales/en.json")>();
export async function repair(): Promise<void> {
const vehicle = nearestVehicle(4, { notOwn: true });
if (!vehicle) return notify(Locale("NO_VEHICLE"), "error");
const [x = 0, y = 0, z = 0] = GetEntityCoords(vehicle, false);
const done = await progress({
label: Locale("REPAIRING"),
duration: 8000,
face: { x, y, z },
anim: { dict: "mini@repair", clip: "fixing_a_player" },
canCancel: true,
disable: { move: true, combat: true },
});
if (!done) return notify(Locale("CANCELLED"), "error");
await callAction("mymech:repair", [NetworkGetNetworkIdFromEntity(vehicle)], { fallback: "REPAIR_FAILED" });
}El resultado es la palabra del cliente: un tramposo puede saltarse la barra. Cuando el servidor paga por la acción (objetos, dinero, una reparación), ejecuta la barra desde el servidor con progressFor(source, options) (Entrada del cliente): solo responde true cuando también pasó suficiente tiempo en el servidor.
cancelProgress
Cancela el progreso en marcha de tu recurso, pueda o no cancelarlo el jugador. La llamada a progress se resuelve entonces con false. No pasa nada cuando no hay ningún progreso en marcha.
Lado: Cliente · Espera: no
cancelProgress(): voidaiLib.progress.cancel()Devuelve
void.
Ejemplo
import { cancelProgress, onServerEvent } from "@aicore-fivem/lib/client";
// El servidor dice que otro ya robó el objetivo.
onServerEvent("myrob:taken", () => cancelProgress());isProgressRunning
Si hay ahora un progreso de tu recurso en marcha.
Lado: Cliente · Espera: no
isProgressRunning(): booleanlocal running = aiLib.progress.isRunning()Devuelve
boolean: true mientras corre la barra de tu recurso. Las barras de otros recursos no cuentan.
Ejemplo
import { isProgressRunning, menu } from "@aicore-fivem/lib/client";
export async function openMenu(): Promise<void> {
if (isProgressRunning()) return; // ocupado
await menu({ title: "Actions", items: [{ id: "a", label: "Action" }] });
}Menús y diálogos
menu
Muestra el menú de ai-lib y espera a que el jugador elija. Las flechas mueven, Enter elige. Las entradas con checked son filas de interruptor que cambian en el sitio sin cerrar el menú. En un submenú (back: true), un Escape corto resuelve MENU_BACK para que puedas abrir el menú anterior; mantener Escape lo cierra.
Lado: Cliente · Espera: sí (Promise en TypeScript, cede el hilo en Lua)
menu(request: MenuRequest, listeners?: ((item: string) => void) | MenuListeners): Promise<string | null>local picked = aiLib.menu.show(request, listeners) -- string o nil, llamar dentro de un hiloParámetros
Prop
Type
MenuRequest
Prop
Type
MenuItem
Prop
Type
Los tipos son MenuRequest y MenuItem.
MenuListeners
Prop
Type
Devuelve
Promise<string | null>: el id de la entrada elegida; "__back" (MENU_BACK de @aicore-fivem/shared) tras un Escape corto en un submenú; null cuando el jugador cerró el menú. Lua devuelve lo mismo, nil para cerrado.
Ejemplo
import { callAction, createLocale, menu } from "@aicore-fivem/lib/client";
import { MENU_BACK } from "@aicore-fivem/shared";
const Locale = createLocale<typeof import("../../locales/en.json")>();
let engineOn = true;
export async function vehicleMenu(vehicle: number): Promise<void> {
const pick = await menu({
title: Locale("VEHICLE"),
items: [
{ id: "doors", label: Locale("DOORS"), icon: "door-open" },
{ id: "engine", label: Locale("ENGINE"), icon: "power-off", checked: engineOn },
],
}, {
onToggle: (item, checked) => {
if (item !== "engine") return;
engineOn = checked;
SetVehicleEngineOn(vehicle, checked, false, true);
},
});
if (pick === "doors") await doorsMenu(vehicle);
}
async function doorsMenu(vehicle: number): Promise<void> {
const pick = await menu({
title: Locale("DOORS"),
back: true,
items: [0, 1, 2, 3].map((door) => ({ id: String(door), label: Locale("DOOR", door + 1) })),
});
if (pick === MENU_BACK) return vehicleMenu(vehicle);
if (pick !== null) SetVehicleDoorOpen(vehicle, Number(pick), false, false);
}El id elegido viene del cliente del jugador: el servidor debe comprobar que es una opción válida.
input
Muestra el diálogo de entrada de ai-lib y espera los valores. Cada campo es una caja numérica o una caja de texto.
Lado: Cliente · Espera: sí (Promise en TypeScript, cede el hilo en Lua)
input(request: InputRequest): Promise<Record<string, string | number> | null>local values = aiLib.input(request) -- table o nil, llamar dentro de un hiloParámetros
Prop
Type
InputRequest
Prop
Type
InputField: número
Prop
Type
InputField: texto
Prop
Type
Los tipos son InputRequest y InputField.
Devuelve
Promise<Record<string, string | number> | null>: los valores introducidos por name de campo cuando el jugador confirmó; null cuando cerró el diálogo. Los valores que no son ni string ni número se dejan fuera. Lua devuelve la tabla o nil.
Ejemplo
import { callAction, createLocale, input } from "@aicore-fivem/lib/client";
const Locale = createLocale<typeof import("../../locales/en.json")>();
export async function sendBill(target: number): Promise<void> {
const values = await input({
title: Locale("BILL"),
confirm: Locale("SEND"),
fields: [
{ name: "amount", label: Locale("AMOUNT"), type: "number", min: 1, max: 100000 },
{ name: "reason", label: Locale("REASON"), type: "text", maxLength: 80 },
],
});
if (!values) return;
await callAction("mybill:send", [target, values.amount, values.reason], { fallback: "BILL_FAILED" });
}min, max y maxLength solo orientan al jugador. El servidor debe comprobar de nuevo cada valor (readInt, readText en el handler del servidor).
itemPicker
Herramientas de admin: muestra el selector de objetos de ai-core. Lista todos los objetos del inventario activo con su imagen y un buscador; los clics rellenan una lista a la derecha (1 por clic, 10 con Ctrl, 100 con Shift) que se detiene en el límite de peso del destinatario. La lista de objetos solo se envía a los admins.
Lado: Cliente · Espera: sí (Promise en TypeScript, cede el hilo en Lua)
itemPicker(request: ItemPickerRequest): Promise<PickedItem[] | null>local list = aiLib.itemPicker(request) -- table o nil, llamar dentro de un hiloParámetros
Prop
Type
ItemPickerRequest
Prop
Type
Devuelve
Promise<PickedItem[] | null>: la lista que tomó el admin, cada fila { name: string; count: number } (count un número entero mayor que 0); null cuando se cerró el selector. Lua devuelve la lista o nil. Los tipos son ItemPickerRequest y PickedItem.
Ejemplo
import { callAction, itemPicker } from "@aicore-fivem/lib/client";
export async function giveItems(target: number): Promise<void> {
const list = await itemPicker({ title: "Give items", target });
if (!list || list.length === 0) return;
await callAction("myadmin:give", [target, list], { fallback: "GIVE_FAILED" });
}Tu handler de servidor da los objetos: comprueba que quien llama es admin (guarda isAdmin) y comprueba de nuevo cada nombre y cantidad. El selector nunca da nada por sí mismo.
Prompts a mano
Los puntos muestran y ocultan los prompts por ti. Usa estas funciones solo para un prompt que no esté ligado a un lugar.
showPrompt
Muestra (o cambia el texto de) uno de los prompts de tu recurso: la caja de "pulsa E" a la derecha de la pantalla. Con at, el prompt flota sobre un punto del mundo o un sitio de una entidad.
Lado: Cliente · Espera: no
showPrompt(id: string, text: string, at?: PromptAnchor): voidaiLib.showPrompt(id, text) -- sin anclaje en el mundo en LuaParámetros
Prop
Type
Devuelve
void.
Ejemplo
Consulta onPromptPressed.
hidePrompt
Oculta uno de los prompts de tu recurso. Un id que no se muestra no hace nada.
Lado: Cliente · Espera: no
hidePrompt(id: string): voidaiLib.hidePrompt(id)Parámetros
Prop
Type
Devuelve
void.
onPromptPressed
Ejecuta un handler cuando el jugador pulsa la tecla de interacción (por defecto E) mientras uno de los prompts de tu recurso es el que está encima.
Lado: Cliente · Espera: no
onPromptPressed(handler: (id: string) => void): voidaiLib.onPromptPressed(function(id) end)Parámetros
Prop
Type
Devuelve
void.
Ejemplo
import { createLocale, hidePrompt, onCache, onPromptPressed, showPrompt } from "@aicore-fivem/lib/client";
const Locale = createLocale<typeof import("../../locales/en.json")>();
// "Pulsa E para expulsar" sentado en el asiento del copiloto.
onCache("seat", (seat) => {
if (seat === 0) showPrompt("eject", Locale("EJECT"));
else hidePrompt("eject");
});
onPromptPressed((id) => {
if (id !== "eject") return;
TaskLeaveVehicle(PlayerPedId(), GetVehiclePedIsIn(PlayerPedId(), false), 4160);
});Minijuegos
skillCheck
La prueba de habilidad de ai-lib: una aguja recorre un anillo una vez por fase, y el jugador pulsa la tecla mostrada mientras está en el arco verde. Tiene la forma habitual de prueba de habilidad de FiveM ("easy" | "medium" | "hard" o { areaSize, speedMultiplier }), así que el código escrito para la prueba de habilidad de ox_lib funciona igual.
Lado: Cliente · Espera: sí (Promise en TypeScript, cede el hilo en Lua)
skillCheck(difficulty: SkillDifficulty | SkillDifficulty[], keys?: string[]): Promise<boolean>local passed = aiLib.skillCheck(difficulty, keys) -- boolean, llamar dentro de un hiloParámetros
Prop
Type
SkillDifficulty
SkillDifficulty es uno de:
Prop
Type
Devuelve
Promise<boolean>: true cuando se acertaron todas las fases; false con un fallo, una tecla incorrecta o Escape.
Ejemplo
import { callAction, skillCheck } from "@aicore-fivem/lib/client";
export async function hotwire(netId: number): Promise<void> {
const passed = await skillCheck(["easy", "easy", "medium", { areaSize: 30, speedMultiplier: 1.5 }], ["w", "a", "s", "d"]);
await callAction("mykeys:hotwire", [netId, passed], { fallback: "HOTWIRE_FAILED" });
}El resultado es la palabra del cliente. Cuando el minijuego paga (un coche, un robo), juégalo desde el servidor con minigameFor(source, { game: "skillCheck", ... }), que además rechaza una victoria más rápida que una partida real (Entrada del cliente).
lockpick
La ganzúa de ai-lib: el jugador mueve la ganzúa con A / D (o las flechas) y mantiene W para girar la cerradura. La cerradura gira más cuanto más cerca está la ganzúa del punto justo oculto; forzarla desgasta la ganzúa.
Lado: Cliente · Espera: sí (Promise en TypeScript, cede el hilo en Lua)
lockpick(options?: LockpickOptions): Promise<LockpickResult>local result = aiLib.lockpick(options) -- 'opened' | 'broken' | 'cancelled', llamar dentro de un hiloParámetros
Prop
Type
LockpickOptions
Prop
Type
Devuelve
Promise<LockpickResult> (LockpickResult): "opened" cuando giraron todos los pines; "broken" cuando se rompió la última ganzúa (quita el objeto de ganzúa); "cancelled" cuando el jugador pulsó Escape.
Ejemplo
import { callAction, lockpick } from "@aicore-fivem/lib/client";
export async function pickDoor(doorId: string): Promise<void> {
const result = await lockpick({ difficulty: "hard", pins: 3, picks: 2 });
if (result === "cancelled") return;
await callAction("mydoors:picked", [doorId, result], { fallback: "PICK_FAILED" });
}Peds, blips y props
LocalPed, Blips, createBlip, attachProp, PreviewVehicle y player.holdAnim - NPC locales, blips del mapa, props en la mano, vehículos de exposición y animaciones mantenidas.
Pantallas y controles
NuiScreen, hud, keyHints y controls - tu propia NUI a pantalla completa, ocultar todos los HUD, líneas de ayuda de teclas y controles desactivados.