AI Core
Dokumentacja APILib: klient

Członkostwo i dane gracza

hasJob, inGang, onDutyIn, allows, onMembershipChange, getPlayerData, onPlayerData i seedPlayerData - postać, pieniądze, prace, służba i gangi lokalnego gracza tak, jak wypycha je ai-core.

ai-core wypycha własne dane lokalnego gracza do jego klienta: jedna migawka, gdy postać się wczyta, potem tylko wartości, które się zmieniają. Te funkcje czytają tę kopię, więc sprawdzenie kosztuje odczyt z pamięci i nigdy nie pyta serwera.

Używaj ich do tego, co gracz widzi (canShow punktu, pozycja menu radialnego, wiersz menu). Serwer decyduje, co gracz może zrobić, na podstawie tych samych danych (online na stronie Gracze i postacie): sprawdzenie na kliencie nigdy nie jest dowodem.

Dane gracza

Wartości, które trzyma ai-core, według klucza (AiPlayerData):

Prop

Type

Typy składowych to CharacterInfo, JobMembership i GangMembership.

getPlayerData

Ostatnia wartość jednego klucza. Przy pierwszym użyciu w twoim zasobie czyta też wszystko, co ai-core już wypchnął (z eksportu GetPlayerData ai-core), więc zasób zrestartowany po wczytaniu gracza od razu ma wartości.

Strona: Klient · Czeka: nie

Sygnatura
getPlayerData<K extends keyof AiPlayerData>(key: K): AiPlayerData[K] | undefined
Lua
local value = aiLib.playerData.get(key)

Parametry

Prop

Type

Zwracana wartość

AiPlayerData[K] | undefined: wartość albo undefined (nil w Lua), gdy nic jeszcze nie przyszło (żadna postać nie jest wczytana, ai-core nie wystartował).

Przykład

import { getPlayerData, notify } from "@aicore-fivem/lib/client";

RegisterCommand(
  "whoami",
  () => {
    const character = getPlayerData("character");
    const job = getPlayerData("job");
    const cash = getPlayerData("money")?.cash ?? 0;
    if (!character) return notify("No character loaded", "error");
    notify(`${job?.job ?? "unemployed"} (${job?.grade ?? 0}), $${cash}`, "info");
  },
  false,
);

onPlayerData

Uruchamia handler za każdym razem, gdy ai-core wypycha klucz dla tego gracza.

Strona: Klient · Czeka: nie

Sygnatura
onPlayerData<K extends keyof AiPlayerData>(key: K, handler: (value: AiPlayerData[K]) => void): () => void
Lua
aiLib.playerData.onChange(key, function(value) end)

Parametry

Prop

Type

Zwracana wartość

TypeScript: () => void, funkcja, która usuwa handler. Lua nic nie zwraca.

Przykład

import { onPlayerData } from "@aicore-fivem/lib/client";

const stop = onPlayerData("money", (money) => {
  SendNUIMessage({ action: "money", data: { cash: money.cash ?? 0, bank: money.bank ?? 0 } });
});
// stop(), gdy HUD zamyka się na dobre

Wartości wypchnięte przed startem twojego zasobu nie są odtwarzane dla handlera. Odczytaj bieżącą wartość raz przez getPlayerData przy starcie, potem śledź zmiany przez onPlayerData.

seedPlayerData

Wypełnia wartości ręcznie. Klucze, które już mają wartość, są zachowywane. Nie potrzebujesz tego: lib sam się wypełnia z ai-core przy pierwszym użyciu.

Strona: Klient · Czeka: nie

Sygnatura
seedPlayerData(data: Partial<AiPlayerData>): void

Brak odpowiednika w Lua.

Parametry

Prop

Type

Zwracana wartość

void.

Przykład

import { seedPlayerData } from "@aicore-fivem/lib/client";

// Środowisko testowe bez ai-core.
seedPlayerData({ jobs: [{ job: "police", grade: 3 }], duty: "police" });

Sprawdzanie członkostwa

hasJob

Czy gracz ma jedną z prac od minimalnego stopnia, na służbie czy nie.

Strona: Klient · Czeka: nie

Sygnatura
hasJob(jobs: readonly string[], minGrade?: number): boolean

Brak odpowiednika w Lua: przejdź po aiLib.playerData.get('jobs') (zobacz przykład Lua w points.add).

Parametry

Prop

Type

Zwracana wartość

boolean: true, gdy lista jest pusta albo gracz ma jedną z jobs na stopniu minGrade lub wyższym.

Przykład

import { hasJob, onMembershipChange, Points } from "@aicore-fivem/lib/client";

const points = new Points();
points.add("armory", {
  coords: { x: 482.6, y: -995.2, z: 30.7 },
  label: "Armory",
  canShow: () => hasJob(["police", "sheriff"], 1),
  onPressed: () => emitNet("mypolice:armory"),
});
onMembershipChange(() => points.refresh());

inGang

Czy gracz jest w jednym z gangów od minimalnego stopnia.

Strona: Klient · Czeka: nie

Sygnatura
inGang(gangs: readonly string[], minGrade?: number): boolean

Brak odpowiednika w Lua: przejdź po aiLib.playerData.get('gangs').

Parametry

Prop

Type

Zwracana wartość

boolean: true, gdy lista jest pusta albo gracz jest w jednym z gangs na stopniu minGrade lub wyższym.

Przykład

import { inGang, radial } from "@aicore-fivem/lib/client";

radial.add({
  id: "mygang:stash",
  label: "Gang stash",
  icon: "box",
  canShow: () => inGang(["ballas", "vagos"], 2),
  onPressed: () => emitNet("mygang:stash"),
});

onDutyIn

Czy gracz jest na służbie w jednej z prac.

Strona: Klient · Czeka: nie

Sygnatura
onDutyIn(jobs: readonly string[]): boolean

Brak odpowiednika w Lua: aiLib.playerData.get('duty') to praca na służbie.

Parametry

Prop

Type

Zwracana wartość

boolean: true, gdy praca, w której gracz jest na służbie, jest w jobs.

Przykład

import { onDutyIn, Points } from "@aicore-fivem/lib/client";

const points = new Points();
points.addVehicle("mymech:repair", {
  label: "Repair",
  icon: "wrench",
  canShow: () => onDutyIn(["mechanic"]),
  onPressed: (vehicle) => emitNet("mymech:repair", NetworkGetNetworkIdFromEntity(vehicle)),
});

onMembershipChange

Uruchamia funkcję, gdy zmienią się prace, służba albo gangi gracza. Używaj jej do odświeżania punktów i blipów, których canShow je czyta.

Strona: Klient · Czeka: nie

Sygnatura
onMembershipChange(fn: () => void): void

Brak odpowiednika w Lua: aiLib.playerData.onChange dla jobs, duty i gangs.

Parametry

Prop

Type

Zwracana wartość

void.

Przykład

import { onMembershipChange, Points, radial } from "@aicore-fivem/lib/client";

const points = new Points();
onMembershipChange(() => {
  points.refresh();
  radial.refresh();
});

allows

Czy lokalny gracz może korzystać z miejsca z regułą dostępu. Serwerowe online.allows(source, rule) decyduje według tej samej reguły, więc to, co widzi gracz, jest dokładnie tym, z czego serwer pozwala mu korzystać. Odczytaj regułę z rekordu panelu przez readAccess(record) (@aicore-fivem/lib/shared).

Strona: Klient · Czeka: nie

Sygnatura
allows(rule: AccessRule): boolean

Brak odpowiednika w Lua.

Parametry

Prop

Type

AccessRule

Prop

Type

Typ to AccessRule.

Zwracana wartość

boolean: true, gdy obie listy są puste (wszyscy); gdy gracz jest w jednym z gangs od jego minimalnego stopnia; albo gdy gracz ma jedną z jobs od jej minimalnego stopnia (i jest w niej na służbie przy onDuty). W przeciwnym razie false.

Przykład

resource/client/index.ts
import { AdminWorld, allows, callAction, onMembershipChange, Points } from "@aicore-fivem/lib/client";
import { readAccess, readVec3, RecordObjects, type AccessRule } from "@aicore-fivem/lib/shared";

const world = new AdminWorld(["stashes"]);
const points = new Points();

interface Stash { coords: { x: number; y: number; z: number }; access: AccessRule }
const readStash = (_key: string, raw: Record<string, unknown>): Stash | null => {
  const coords = readVec3(raw.coords);
  return coords ? { coords, access: readAccess(raw) } : null;
};

new RecordObjects(world, "stashes", readStash, (id, stash) => {
  points.add(id, {
    coords: stash.coords,
    label: "Stash",
    canShow: () => allows(stash.access),
    onPressed: () => callAction("mystash:open", [id], { fallback: "STASH_FAILED" }),
  });
  return () => points.remove(id);
});

onMembershipChange(() => points.refresh());

Na tej stronie