AI Core
Справочник APILib: клиент

Членство и данные игрока

hasJob, inGang, onDutyIn, allows, onMembershipChange, getPlayerData, onPlayerData и seedPlayerData - персонаж, деньги, работы, дежурство и банды локального игрока в том виде, в каком их присылает ai-core.

ai-core отправляет собственные данные локального игрока на его клиент: один снимок при загрузке персонажа, затем только изменившиеся значения. Эти помощники читают эту копию, поэтому проверка стоит одного чтения из памяти и никогда не спрашивает сервер.

Используйте их для того, что игрок видит (canShow точки, пункт радиального меню, строка меню). Что игрок может делать, решает сервер по тем же данным (online на странице Игроки и персонажи): клиентская проверка никогда не является доказательством.

Данные игрока

Значения, которые хранит ai-core, по ключу (AiPlayerData):

Prop

Type

Типы членов: CharacterInfo, JobMembership и GangMembership.

getPlayerData

Последнее значение одного ключа. При первом использовании в вашем ресурсе также читает всё, что ai-core уже прислал (из экспорта ai-core GetPlayerData), поэтому ресурс, перезапущенный после загрузки игрока, сразу получает значения.

Сторона: Клиент · Ждёт: нет

Сигнатура
getPlayerData<K extends keyof AiPlayerData>(key: K): AiPlayerData[K] | undefined
Lua
local value = aiLib.playerData.get(key)

Параметры

Prop

Type

Возвращает

AiPlayerData[K] | undefined: значение или undefined (nil в Lua), если ещё ничего не пришло (персонаж не загружен, ai-core не запущен).

Пример

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

Запускает обработчик каждый раз, когда ai-core присылает ключ для этого игрока.

Сторона: Клиент · Ждёт: нет

Сигнатура
onPlayerData<K extends keyof AiPlayerData>(key: K, handler: (value: AiPlayerData[K]) => void): () => void
Lua
aiLib.playerData.onChange(key, function(value) end)

Параметры

Prop

Type

Возвращает

TypeScript: () => void, функция, которая удаляет обработчик. Lua ничего не возвращает.

Пример

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(), когда HUD закрывается насовсем

Значения, присланные до запуска вашего ресурса, обработчику не повторяются. Прочитайте текущее значение один раз через getPlayerData при старте, затем следите за изменениями через onPlayerData.

seedPlayerData

Заполняет значения вручную. Ключи, у которых уже есть значение, сохраняются. Вам это не нужно: lib сама заполняется из ai-core при первом использовании.

Сторона: Клиент · Ждёт: нет

Сигнатура
seedPlayerData(data: Partial<AiPlayerData>): void

Lua-аналога нет.

Параметры

Prop

Type

Возвращает

void.

Пример

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

// Тестовая обвязка без ai-core.
seedPlayerData({ jobs: [{ job: "police", grade: 3 }], duty: "police" });

Проверки членства

hasJob

Состоит ли игрок в одной из работ с минимальным рангом, на дежурстве или нет.

Сторона: Клиент · Ждёт: нет

Сигнатура
hasJob(jobs: readonly string[], minGrade?: number): boolean

Lua-аналога нет: переберите aiLib.playerData.get('jobs') (см. пример на Lua для points.add).

Параметры

Prop

Type

Возвращает

boolean: true, если список пуст или игрок состоит в одной из jobs с рангом minGrade или выше.

Пример

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

Состоит ли игрок в одной из банд с минимальным рангом.

Сторона: Клиент · Ждёт: нет

Сигнатура
inGang(gangs: readonly string[], minGrade?: number): boolean

Lua-аналога нет: переберите aiLib.playerData.get('gangs').

Параметры

Prop

Type

Возвращает

boolean: true, если список пуст или игрок состоит в одной из gangs с рангом minGrade или выше.

Пример

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

На дежурстве ли игрок в одной из работ.

Сторона: Клиент · Ждёт: нет

Сигнатура
onDutyIn(jobs: readonly string[]): boolean

Lua-аналога нет: aiLib.playerData.get('duty') это работа на дежурстве.

Параметры

Prop

Type

Возвращает

boolean: true, если работа дежурства игрока входит в jobs.

Пример

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

Выполняет функцию, когда меняются работы, дежурство или банды игрока. Используйте, чтобы обновлять точки и блипы, canShow которых их читает.

Сторона: Клиент · Ждёт: нет

Сигнатура
onMembershipChange(fn: () => void): void

Lua-аналога нет: aiLib.playerData.onChange для jobs, duty и gangs.

Параметры

Prop

Type

Возвращает

void.

Пример

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

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

allows

Может ли локальный игрок пользоваться местом с правилом доступа. Серверный online.allows(source, rule) решает по тому же правилу, поэтому то, что видит игрок, в точности совпадает с тем, чем сервер позволяет пользоваться. Читайте правило из записи панели через readAccess(record) (@aicore-fivem/lib/shared).

Сторона: Клиент · Ждёт: нет

Сигнатура
allows(rule: AccessRule): boolean

Lua-аналога нет.

Параметры

Prop

Type

AccessRule

Prop

Type

Тип: AccessRule.

Возвращает

boolean: true, если оба списка пусты (все); если игрок состоит в одной из gangs с её минимальным рангом; или если игрок состоит в одной из jobs с её минимальным рангом (и на дежурстве в ней при onDuty). Иначе false.

Пример

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

На этой странице