AI Core
Référence de l’APILib : client

Interface partagée

notify, progress, menu, input, invites, skillCheck, lockpick et itemPicker : l’interface joueur qu’ai-lib dessine pour chaque ressource.

ai-lib dessine une interface partagée pour chaque ressource : cartes de notification, barre de progression, invites « appuyez sur E », menus, boîtes de saisie et mini-jeux. Votre script ne fait que les demander, si bien que tous les scripts du serveur ont le même aspect et que vous n’écrivez aucune NUI pour ces éléments. Le sélecteur d’objets est dessiné par ai-core.

Les textes que vous passez sont affichés tels quels : traduisez-les d’abord (Locale("KEY") en TypeScript, t('KEY') en Lua).

Notifications

notify

Affiche une carte de notification sur l’écran de ce joueur.

Côté : client · Attend : non

Signature
notify(text: string, kind?: NotificationKind, duration?: number): void
Lua
aiLib.notify(text, kind, duration)

Paramètres

Prop

Type

Le type du genre est NotificationKind. Pour notifier un joueur depuis le serveur, utilisez le notify(source, text, kind) serveur.

Retour

void.

Exemple

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);

Barre de progression

progress

Exécute une action minutée avec la barre de progression d’ai-lib et une animation ou un scénario facultatif, et attend qu’elle se termine. Elle se termine plus tôt (annulée) quand le joueur meurt, monte dans un véhicule, appuie sur la touche d’annulation d’ai-lib (Backspace par défaut, uniquement avec canCancel), ou quand votre script appelle cancelProgress(). Une seule progression par ressource à la fois.

Côté : client · Attend : oui (Promise en TypeScript, cède la main (yield) du thread en Lua)

Signature
progress(options: ProgressOptions): Promise<boolean>
Lua
local finished = aiLib.progress(options) -- booléen, à appeler dans un thread

Paramètres

Prop

Type

ProgressOptions

Prop

Type

Retour

Promise<boolean> : true quand la barre est arrivée au bout ; false quand elle a été annulée, ou immédiatement quand une autre progression de votre ressource est encore en cours. Lua renvoie le même booléen.

Exemple

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

Le résultat n’est que la parole du client : un tricheur peut sauter la barre. Quand le serveur paie pour l’action (objets, argent, réparation), lancez la barre depuis le serveur avec progressFor(source, options) (Entrées client) : elle ne répond true que lorsque suffisamment de temps s’est aussi écoulé sur le serveur.

cancelProgress

Annule la progression en cours de votre ressource, que le joueur ait le droit de l’annuler ou non. L’appel progress se résout alors à false. Rien ne se passe quand aucune progression n’est en cours.

Côté : client · Attend : non

Signature
cancelProgress(): void
Lua
aiLib.progress.cancel()

Retour

void.

Exemple

import { cancelProgress, onServerEvent } from "@aicore-fivem/lib/client";

// Le serveur indique que la cible a été braquée par quelqu’un d’autre.
onServerEvent("myrob:taken", () => cancelProgress());

isProgressRunning

Indique si une progression de votre ressource est en cours.

Côté : client · Attend : non

Signature
isProgressRunning(): boolean
Lua
local running = aiLib.progress.isRunning()

Retour

boolean : true tant que la barre de votre ressource tourne. Les barres des autres ressources ne comptent pas.

Exemple

import { isProgressRunning, menu } from "@aicore-fivem/lib/client";

export async function openMenu(): Promise<void> {
  if (isProgressRunning()) return; // occupé
  await menu({ title: "Actions", items: [{ id: "a", label: "Action" }] });
}

Affiche le menu d’ai-lib et attend le choix du joueur. Les flèches déplacent, Entrée choisit. Les éléments avec checked sont des lignes à interrupteur qui basculent sur place sans fermer le menu. Dans un sous-menu (back: true), un appui bref sur Échap résout MENU_BACK pour que vous puissiez ouvrir le menu précédent ; maintenir Échap ferme.

Côté : client · Attend : oui (Promise en TypeScript, cède la main (yield) du thread en Lua)

Signature
menu(request: MenuRequest, listeners?: ((item: string) => void) | MenuListeners): Promise<string | null>
Lua
local picked = aiLib.menu.show(request, listeners) -- chaîne ou nil, à appeler dans un thread

Paramètres

Prop

Type

Prop

Type

Prop

Type

Les types sont MenuRequest et MenuItem.

Prop

Type

Retour

Promise<string | null> : l’id de l’élément choisi ; "__back" (MENU_BACK depuis @aicore-fivem/shared) après un appui bref sur Échap dans un sous-menu ; null quand le joueur a fermé le menu. Lua renvoie la même chose, nil en cas de fermeture.

Exemple

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);
}

L’id choisi vient du client du joueur : le serveur doit vérifier qu’il s’agit d’un choix valide.

input

Affiche la boîte de saisie d’ai-lib et attend les valeurs. Chaque champ est une zone numérique ou une zone de texte.

Côté : client · Attend : oui (Promise en TypeScript, cède la main (yield) du thread en Lua)

Signature
input(request: InputRequest): Promise<Record<string, string | number> | null>
Lua
local values = aiLib.input(request) -- table ou nil, à appeler dans un thread

Paramètres

Prop

Type

InputRequest

Prop

Type

InputField: number

Prop

Type

InputField: text

Prop

Type

Les types sont InputRequest et InputField.

Retour

Promise<Record<string, string | number> | null> : les valeurs saisies, indexées par le name du champ, quand le joueur a confirmé ; null quand il a fermé la boîte de dialogue. Les valeurs qui ne sont ni une chaîne ni un nombre sont omises. Lua renvoie la table ou nil.

Exemple

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 et maxLength ne font que guider le joueur. Le serveur doit revérifier chaque valeur (readInt, readText dans le gestionnaire serveur).

itemPicker

Outils d’administration : affiche le sélecteur d’objets d’ai-core. Il liste chaque objet de l’inventaire actif avec son image et une recherche ; les clics remplissent une liste à droite (1 par clic, 10 avec Ctrl, 100 avec Maj) qui s’arrête à la limite de poids de la cible. La liste des objets n’est envoyée qu’aux administrateurs.

Côté : client · Attend : oui (Promise en TypeScript, cède la main (yield) du thread en Lua)

Signature
itemPicker(request: ItemPickerRequest): Promise<PickedItem[] | null>
Lua
local list = aiLib.itemPicker(request) -- table ou nil, à appeler dans un thread

Paramètres

Prop

Type

ItemPickerRequest

Prop

Type

Retour

Promise<PickedItem[] | null> : la liste prise par l’administrateur, chaque ligne { name: string; count: number } (count un nombre entier supérieur à 0) ; null quand le sélecteur a été fermé. Lua renvoie la liste ou nil. Les types sont ItemPickerRequest et PickedItem.

Exemple

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

C’est votre gestionnaire serveur qui donne les objets : vérifiez que l’appelant est administrateur (garde isAdmin) et revérifiez chaque nom et chaque quantité. Le sélecteur ne donne jamais rien de lui-même.

Invites à la main

Les points affichent et masquent les invites pour vous. N’utilisez ces fonctions que pour une invite qui n’est pas liée à un lieu.

showPrompt

Affiche l’une des invites de votre ressource (ou en change le texte) : la boîte « appuyez sur E » à droite de l’écran. Avec at, l’invite flotte plutôt au-dessus d’un point du monde ou d’un emplacement sur une entité.

Côté : client · Attend : non

Signature
showPrompt(id: string, text: string, at?: PromptAnchor): void
Lua
aiLib.showPrompt(id, text) -- pas d’ancrage dans le monde en Lua

Paramètres

Prop

Type

Retour

void.

Exemple

Voir onPromptPressed.

hidePrompt

Masque l’une des invites de votre ressource. Un id qui n’est pas affiché ne fait rien.

Côté : client · Attend : non

Signature
hidePrompt(id: string): void
Lua
aiLib.hidePrompt(id)

Paramètres

Prop

Type

Retour

void.

onPromptPressed

Exécute un gestionnaire quand le joueur appuie sur la touche d’interaction (E par défaut) alors que l’une des invites de votre ressource est celle du dessus.

Côté : client · Attend : non

Signature
onPromptPressed(handler: (id: string) => void): void
Lua
aiLib.onPromptPressed(function(id) end)

Paramètres

Prop

Type

Retour

void.

Exemple

import { createLocale, hidePrompt, onCache, onPromptPressed, showPrompt } from "@aicore-fivem/lib/client";

const Locale = createLocale<typeof import("../../locales/en.json")>();

// « Appuyez sur E pour éjecter » quand le joueur est sur le siège passager.
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);
});

Mini-jeux

skillCheck

Le test d’adresse d’ai-lib : une aiguille fait le tour d’un anneau une fois par étape, et le joueur appuie sur la touche affichée quand elle se trouve sur l’arc vert. Il a la forme courante des tests d’adresse FiveM ("easy" | "medium" | "hard" ou { areaSize, speedMultiplier }), si bien que le code écrit pour le test d’adresse d’ox_lib fonctionne de la même manière.

Côté : client · Attend : oui (Promise en TypeScript, cède la main (yield) du thread en Lua)

Signature
skillCheck(difficulty: SkillDifficulty | SkillDifficulty[], keys?: string[]): Promise<boolean>
Lua
local passed = aiLib.skillCheck(difficulty, keys) -- booléen, à appeler dans un thread

Paramètres

Prop

Type

SkillDifficulty

SkillDifficulty est l’un de :

Prop

Type

Retour

Promise<boolean> : true quand chaque étape a été réussie ; false en cas d’échec, de mauvaise touche ou d’Échap.

Exemple

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

Le résultat n’est que la parole du client. Quand le mini-jeu rapporte quelque chose (une voiture, un braquage), lancez-le depuis le serveur avec minigameFor(source, { game: "skillCheck", ... }), qui refuse aussi une victoire plus rapide qu’une vraie partie (Entrées client).

lockpick

Le crochetage d’ai-lib : le joueur déplace le crochet avec A / D (ou les flèches) et maintient W pour tourner la serrure. La serrure tourne d’autant plus loin que le crochet est proche du point idéal caché ; forcer use le crochet.

Côté : client · Attend : oui (Promise en TypeScript, cède la main (yield) du thread en Lua)

Signature
lockpick(options?: LockpickOptions): Promise<LockpickResult>
Lua
local result = aiLib.lockpick(options) -- 'opened' | 'broken' | 'cancelled', à appeler dans un thread

Paramètres

Prop

Type

LockpickOptions

Prop

Type

Retour

Promise<LockpickResult> (LockpickResult) : "opened" quand chaque goupille a tourné ; "broken" quand le dernier crochet a cassé (retirez l’objet crochet) ; "cancelled" quand le joueur a appuyé sur Échap.

Exemple

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

Sur cette page