AI Core
Dokumentacja APILib: klient

Wspólne UI

notify, progress, menu, input, prompty, skillCheck, lockpick i itemPicker - UI gracza, które ai-lib rysuje za każdy zasób.

ai-lib rysuje jedno wspólne UI za każdy zasób: karty powiadomień, pasek postępu, prompty "naciśnij E", menu, okna wejścia i minigry. Twój skrypt tylko o nie prosi, więc każdy skrypt na serwerze wygląda tak samo, a ty nie piszesz do nich żadnego NUI. Wybierak przedmiotów rysuje ai-core.

Teksty, które podajesz, są pokazywane tak, jak są: najpierw je przetłumacz (Locale("KEY") w TypeScript, t('KEY') w Lua).

Powiadomienia

notify

Pokazuje kartę powiadomienia na ekranie tego gracza.

Strona: Klient · Czeka: nie

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

Parametry

Prop

Type

Typ kind to NotificationKind. Żeby powiadomić gracza z serwera, użyj serwerowego notify(source, text, kind).

Zwracana wartość

void.

Przykład

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

Pasek postępu

progress

Wykonuje akcję z czasem z paskiem postępu ai-lib i opcjonalną animacją albo scenariuszem i czeka, aż się skończy. Kończy się wcześniej (anulowana), gdy gracz zginie, wsiądzie do pojazdu, naciśnie klawisz anulowania ai-lib (domyślnie Backspace, tylko z canCancel) albo twój skrypt wywoła cancelProgress(). Jeden pasek na zasób naraz.

Strona: Klient · Czeka: tak (Promise w TypeScript, w Lua wstrzymuje wątek)

Sygnatura
progress(options: ProgressOptions): Promise<boolean>
Lua
local finished = aiLib.progress(options) -- boolean, wywołuj wewnątrz wątku

Parametry

Prop

Type

ProgressOptions

Prop

Type

Zwracana wartość

Promise<boolean>: true, gdy pasek dobiegł końca; false, gdy został anulowany, albo od razu, gdy inny pasek twojego zasobu jeszcze trwa. Lua zwraca tę samą wartość logiczną.

Przykład

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

Wynik to słowo klienta: oszust może pominąć pasek. Gdy serwer płaci za akcję (przedmioty, pieniądze, naprawa), uruchom pasek z serwera przez progressFor(source, options) (Wejście z klienta): odpowiada true tylko wtedy, gdy na serwerze też minęło dość czasu.

cancelProgress

Anuluje trwający pasek twojego zasobu, niezależnie od tego, czy gracz może go anulować. Wywołanie progress rozwiązuje się wtedy false. Nic się nie dzieje, gdy żaden pasek nie trwa.

Strona: Klient · Czeka: nie

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

Zwracana wartość

void.

Przykład

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

// Serwer mówi, że cel został okradziony przez kogoś innego.
onServerEvent("myrob:taken", () => cancelProgress());

isProgressRunning

Czy pasek twojego zasobu trwa teraz.

Strona: Klient · Czeka: nie

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

Zwracana wartość

boolean: true, dopóki trwa pasek twojego zasobu. Paski innych zasobów się nie liczą.

Przykład

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

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

Pokazuje menu ai-lib i czeka na wybór gracza. Strzałki przesuwają, Enter wybiera. Pozycje z checked to wiersze-przełączniki, które przełączają się w miejscu bez zamykania menu. W podmenu (back: true) krótkie Escape rozwiązuje się MENU_BACK, żebyś mógł otworzyć poprzednie menu; przytrzymanie Escape zamyka.

Strona: Klient · Czeka: tak (Promise w TypeScript, w Lua wstrzymuje wątek)

Sygnatura
menu(request: MenuRequest, listeners?: ((item: string) => void) | MenuListeners): Promise<string | null>
Lua
local picked = aiLib.menu.show(request, listeners) -- string albo nil, wywołuj wewnątrz wątku

Parametry

Prop

Type

Prop

Type

Prop

Type

Typy to MenuRequest i MenuItem.

Prop

Type

Zwracana wartość

Promise<string | null>: id wybranej pozycji; "__back" (MENU_BACK z @aicore-fivem/shared) po krótkim Escape w podmenu; null, gdy gracz zamknął menu. Lua zwraca to samo, nil przy zamknięciu.

Przykład

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

Wybrane id pochodzi z klienta gracza: serwer musi sprawdzić, czy to prawidłowy wybór.

input

Pokazuje okno wejścia ai-lib i czeka na wartości. Każde pole to pole liczbowe albo tekstowe.

Strona: Klient · Czeka: tak (Promise w TypeScript, w Lua wstrzymuje wątek)

Sygnatura
input(request: InputRequest): Promise<Record<string, string | number> | null>
Lua
local values = aiLib.input(request) -- tabela albo nil, wywołuj wewnątrz wątku

Parametry

Prop

Type

InputRequest

Prop

Type

InputField: number

Prop

Type

InputField: text

Prop

Type

Typy to InputRequest i InputField.

Zwracana wartość

Promise<Record<string, string | number> | null>: wpisane wartości według name pola, gdy gracz potwierdził; null, gdy zamknął okno. Wartości, które nie są ani stringiem, ani liczbą, są pomijane. Lua zwraca tabelę albo nil.

Przykład

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 i maxLength tylko prowadzą gracza. Serwer musi ponownie sprawdzić każdą wartość (readInt, readText w handlerze serwera).

itemPicker

Narzędzia administratora: pokazuje wybierak przedmiotów ai-core. Wymienia każdy przedmiot aktywnego ekwipunku z obrazkiem i wyszukiwaniem; kliknięcia wypełniają listę po prawej (1 na kliknięcie, 10 z Ctrl, 100 z Shift), która zatrzymuje się na limicie wagi celu. Lista przedmiotów jest wysyłana tylko administratorom.

Strona: Klient · Czeka: tak (Promise w TypeScript, w Lua wstrzymuje wątek)

Sygnatura
itemPicker(request: ItemPickerRequest): Promise<PickedItem[] | null>
Lua
local list = aiLib.itemPicker(request) -- tabela albo nil, wywołuj wewnątrz wątku

Parametry

Prop

Type

ItemPickerRequest

Prop

Type

Zwracana wartość

Promise<PickedItem[] | null>: lista, którą wziął administrator, każdy wiersz { name: string; count: number } (count to liczba całkowita powyżej 0); null, gdy wybierak został zamknięty. Lua zwraca listę albo nil. Typy to ItemPickerRequest i PickedItem.

Przykład

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

Przedmioty daje twój handler serwera: sprawdź, czy wywołujący jest administratorem (strażnik isAdmin), i ponownie sprawdź każdą nazwę i ilość. Wybierak nigdy nic sam nie daje.

Prompty ręcznie

Punkty pokazują i ukrywają prompty za ciebie. Używaj tych funkcji tylko dla promptu, który nie jest związany z miejscem.

showPrompt

Pokazuje (albo zmienia tekst) jednego z promptów twojego zasobu: ramkę "naciśnij E" po prawej stronie ekranu. Z at prompt zamiast tego unosi się nad punktem w świecie albo miejscem na encji.

Strona: Klient · Czeka: nie

Sygnatura
showPrompt(id: string, text: string, at?: PromptAnchor): void
Lua
aiLib.showPrompt(id, text) -- brak kotwicy w świecie w Lua

Parametry

Prop

Type

Zwracana wartość

void.

Przykład

Zobacz onPromptPressed.

hidePrompt

Ukrywa jeden z promptów twojego zasobu. Id, które nie jest pokazane, nic nie robi.

Strona: Klient · Czeka: nie

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

Parametry

Prop

Type

Zwracana wartość

void.

onPromptPressed

Uruchamia handler, gdy gracz naciśnie klawisz interakcji (domyślnie E), gdy jeden z promptów twojego zasobu jest na wierzchu.

Strona: Klient · Czeka: nie

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

Parametry

Prop

Type

Zwracana wartość

void.

Przykład

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

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

// "Naciśnij E, żeby wyrzucić" podczas siedzenia na miejscu pasażera.
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);
});

Minigry

skillCheck

Test umiejętności ai-lib: wskazówka obiega pierścień raz na etap, a gracz naciska pokazany klawisz, gdy jest ona na zielonym łuku. Ma typowy kształt testu umiejętności FiveM ("easy" | "medium" | "hard" albo { areaSize, speedMultiplier }), więc kod napisany dla testu umiejętności ox_lib działa tak samo.

Strona: Klient · Czeka: tak (Promise w TypeScript, w Lua wstrzymuje wątek)

Sygnatura
skillCheck(difficulty: SkillDifficulty | SkillDifficulty[], keys?: string[]): Promise<boolean>
Lua
local passed = aiLib.skillCheck(difficulty, keys) -- boolean, wywołuj wewnątrz wątku

Parametry

Prop

Type

SkillDifficulty

SkillDifficulty to jedno z:

Prop

Type

Zwracana wartość

Promise<boolean>: true, gdy trafiono każdy etap; false przy chybieniu, złym klawiszu albo Escape.

Przykład

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

Wynik to słowo klienta. Gdy minigra płaci (auto, napad), uruchom ją z serwera przez minigameFor(source, { game: "skillCheck", ... }), które odrzuca też wygraną szybszą niż prawdziwa rozgrywka (Wejście z klienta).

lockpick

Wytrych ai-lib: gracz przesuwa wytrych klawiszami A / D (albo strzałkami) i przytrzymuje W, żeby obrócić zamek. Zamek obraca się tym dalej, im bliżej wytrych jest ukrytego dobrego punktu; forsowanie zużywa wytrych.

Strona: Klient · Czeka: tak (Promise w TypeScript, w Lua wstrzymuje wątek)

Sygnatura
lockpick(options?: LockpickOptions): Promise<LockpickResult>
Lua
local result = aiLib.lockpick(options) -- 'opened' | 'broken' | 'cancelled', wywołuj wewnątrz wątku

Parametry

Prop

Type

LockpickOptions

Prop

Type

Zwracana wartość

Promise<LockpickResult> (LockpickResult): "opened", gdy obróciła się każda zapadka; "broken", gdy złamał się ostatni wytrych (zabierz przedmiot wytrycha); "cancelled", gdy gracz nacisnął Escape.

Przykład

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

Na tej stronie