AI Core
Referencia de la APILib: cliente

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

Firma
notify(text: string, kind?: NotificationKind, duration?: number): void
Lua
aiLib.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)

Firma
progress(options: ProgressOptions): Promise<boolean>
Lua
local finished = aiLib.progress(options) -- boolean, llamar dentro de un hilo

Pará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

Firma
cancelProgress(): void
Lua
aiLib.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

Firma
isProgressRunning(): boolean
Lua
local 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

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)

Firma
menu(request: MenuRequest, listeners?: ((item: string) => void) | MenuListeners): Promise<string | null>
Lua
local picked = aiLib.menu.show(request, listeners) -- string o nil, llamar dentro de un hilo

Parámetros

Prop

Type

Prop

Type

Prop

Type

Los tipos son MenuRequest y MenuItem.

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)

Firma
input(request: InputRequest): Promise<Record<string, string | number> | null>
Lua
local values = aiLib.input(request) -- table o nil, llamar dentro de un hilo

Pará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)

Firma
itemPicker(request: ItemPickerRequest): Promise<PickedItem[] | null>
Lua
local list = aiLib.itemPicker(request) -- table o nil, llamar dentro de un hilo

Pará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

Firma
showPrompt(id: string, text: string, at?: PromptAnchor): void
Lua
aiLib.showPrompt(id, text) -- sin anclaje en el mundo en Lua

Pará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

Firma
hidePrompt(id: string): void
Lua
aiLib.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

Firma
onPromptPressed(handler: (id: string) => void): void
Lua
aiLib.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)

Firma
skillCheck(difficulty: SkillDifficulty | SkillDifficulty[], keys?: string[]): Promise<boolean>
Lua
local passed = aiLib.skillCheck(difficulty, keys) -- boolean, llamar dentro de un hilo

Pará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)

Firma
lockpick(options?: LockpickOptions): Promise<LockpickResult>
Lua
local result = aiLib.lockpick(options) -- 'opened' | 'broken' | 'cancelled', llamar dentro de un hilo

Pará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" });
}

En esta página