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

Слои через ai-core

medical, appearance, gestures, seatbelt, fuel, mdt, radial, world и inventory - клиентские вызовы, которые достигают того скрипта смерти, одежды, эмоций, ремня, топлива, MDT, радиального меню, погоды или инвентаря, который запущен на сервере.

Эти объекты никогда не общаются с конкретным скриптом. Они спрашивают ai-core, а ai-core передаёт вызов тому скрипту, который сервер использует для этой задачи: ai-death или другому скрипту смерти, ai-appearance или tgiann-clothing, любому поддерживаемому скрипту эмоций или радиального меню. Ваш скрипт продолжает работать, когда владелец меняет один из них. Как работают слои, описано на странице Слои и мост.

Когда скрипт такого вида не запущен, вызовы отвечают false, null или собственным значением игры, как сказано в каждой записи.

medical

medical.isDead

Лежит ли локальный игрок без сознания (мёртв или в last stand) в том скрипте смерти, который запущен. Скрипты смерти держат упавшего педа живым, чтобы анимировать его, поэтому одного IsEntityDead недостаточно. После первого вызова это чтение из памяти.

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

Сигнатура
medical.isDead(): boolean

Lua-аналога нет: вызывайте exports['ai-core']:IsDead() и слушайте локальное событие ai-core:client:dead (dead).

Возвращает

boolean: true, если медицинский слой ai-core говорит, что игрок без сознания, или пед мёртв с точки зрения игры.

Пример

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

RegisterCommand(
  "phone",
  () => {
    if (medical.isDead()) return notify("You cannot use the phone now", "error");
    SetNuiFocus(true, true);
  },
  false,
);

medical.onChange

Запускает обработчик, когда локальный игрок падает без сознания или встаёт.

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

Сигнатура
medical.onChange(fn: (dead: boolean) => void): void

Lua-аналога нет: AddEventHandler('ai-core:client:dead', function(dead) end).

Параметры

Prop

Type

Возвращает

void.

Пример

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

const points = new Points();
medical.onChange(() => points.refresh()); // точки, canShow которых читает medical.isDead()

appearance

Внешность педов через слой внешности ai-core, какой бы скрипт одежды ни был запущен.

appearance.apply

Надевает сохранённую внешность на педа модели этой внешности. Получите внешность на сервере через appearance.get(charId), создайте педа с look.model, затем примените. На собственном педе игрока это меняет его одежду.

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

Сигнатура
appearance.apply(ped: number, look: CharacterAppearance): boolean
Lua
local ok = aiLib.appearance.apply(ped, look)

Параметры

Prop

Type

Тип: CharacterAppearance.

Возвращает

boolean: false, если педа нет, модель отличается или не запущен скрипт одежды.

Пример

import { appearance, LocalPed, triggerServerCallback } from "@aicore-fivem/lib/client";
import type { CharacterAppearance } from "@aicore-fivem/shared";

// Спящая копия персонажа, одетая как он.
export async function showSleeper(charId: number): Promise<void> {
  const look = (await triggerServerCallback("mysleep:look", [charId]).catch(() => null)) as CharacterAppearance | null;
  if (!look) return;
  new LocalPed({
    model: look.model,
    coords: { x: 151.2, y: -1004.6, z: 29.4, heading: 90 },
    onSpawn: (ped) => appearance.apply(ped, look),
  });
}

Проверяйте то, что присылает сервер, прежде чем приводить тип. Пед, созданный с моделью, отличной от look.model, не может принять внешность: apply отвечает false.

appearance.read

Внешность, которая сейчас на педе.

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

Сигнатура
appearance.read(ped: number): CharacterAppearance | null
Lua
local look = aiLib.appearance.read(ped) -- таблица или nil

Параметры

Prop

Type

Возвращает

CharacterAppearance | null: внешность или null (nil в Lua), если скрипт одежды не может сказать или никакой не запущен.

Пример

import { appearance, cache } from "@aicore-fivem/lib/client";

const before = appearance.read(cache.ped); // позже верните её через appearance.apply

appearance.openMenu

Открывает для игрока магазин одежды, парикмахерскую или сохранённые наряды скрипта одежды.

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

Сигнатура
appearance.openMenu(menu: ClothingMenu): boolean
Lua
local ok = aiLib.appearance.openMenu(menu)

Параметры

Prop

Type

Тип: ClothingMenu.

Возвращает

boolean: false, если в скрипте одежды нет такого меню или никакой не запущен.

Пример

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

const points = new Points();
points.add("barber", {
  coords: { x: -814.3, y: -183.8, z: 37.6 },
  label: "Barber",
  onPressed: () => appearance.openMenu("barber"),
});

appearance.wearOutfit

Надевает на игрока рабочий наряд (униформу) до вызова reloadSkin. Он не сохраняется: переподключение или reloadSkin возвращает игроку его собственную одежду. Меняются только перечисленные части.

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

Сигнатура
appearance.wearOutfit(outfit: JobOutfit): boolean
Lua
local ok = aiLib.appearance.wearOutfit(outfit)

Параметры

Prop

Type

Типы: JobOutfit и OutfitPiece.

Возвращает

boolean: false, если это невозможно (нет скрипта одежды, модель, которую он не поддерживает).

Пример

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

appearance.wearOutfit({
  components: [
    { id: 11, collection: "", index: 55, texture: 0 },
    { id: 4, collection: "", index: 35, texture: 0 },
  ],
  props: [{ id: 0, collection: "", index: -1, texture: 0 }],
});

appearance.reloadSkin

Возвращает на игрока его сохранённую внешность (снимает рабочий наряд).

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

Сигнатура
appearance.reloadSkin(): boolean
Lua
local ok = aiLib.appearance.reloadSkin()

Возвращает

boolean: false без скрипта одежды.

Пример

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

RegisterCommand("offduty", () => appearance.reloadSkin(), false);

gestures

Поднятые руки, указание и эмоции того скрипта эмоций, который запущен, через ai-core.

gestures.isHandsUp

Подняты ли руки у локального игрока.

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

Сигнатура
gestures.isHandsUp(): boolean
Lua
local up = aiLib.gestures.isHandsUp()

Возвращает

boolean: true, пока руки подняты в запущенном скрипте эмоций.

Пример

import { gestures, onServerCallback } from "@aicore-fivem/lib/client";

// Сервер перед ограблением спрашивает, сдалась ли жертва.
onServerCallback("myrob:surrendered", () => gestures.isHandsUp());

gestures.isPointing

Указывает ли локальный игрок пальцем.

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

Сигнатура
gestures.isPointing(): boolean
Lua
local pointing = aiLib.gestures.isPointing()

Возвращает

boolean: true, пока игрок указывает.

Пример

if (gestures.isPointing()) return; // не запускаем эмоцию поверх указания

gestures.provider

Скрипт эмоций, который отвечает за поднятые руки и указание.

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

Сигнатура
gestures.provider(): string | null
Lua
local name = aiLib.gestures.provider()

Возвращает

string | null: имя его ресурса или null (nil), если никакой не запущен.

Пример

console.log(`hands up from ${gestures.provider() ?? "nothing"}`);

gestures.playEmote

Проигрывает эмоцию по имени её команды (то, что игроки вводят после e) в запущенном скрипте эмоций.

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

Сигнатура
gestures.playEmote(name: string): boolean
Lua
local ok = aiLib.gestures.playEmote(name)

Параметры

Prop

Type

Возвращает

boolean: false без скрипта эмоций.

Пример

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

RegisterCommand("hi", () => gestures.playEmote("wave"), false);

gestures.cancelEmote

Останавливает эмоцию, которую проигрывает игрок (надели наручники, сбили с ног).

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

Сигнатура
gestures.cancelEmote(): boolean
Lua
local ok = aiLib.gestures.cancelEmote()

Возвращает

boolean: false без скрипта эмоций.

Пример

onServerEvent("mypolice:cuffed", () => gestures.cancelEmote());

gestures.emoteProvider

Скрипт эмоций, который проигрывает эмоции (он может отличаться от того, что отвечает за поднятые руки).

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

Сигнатура
gestures.emoteProvider(): string | null
Lua
local name = aiLib.gestures.emoteProvider()

Возвращает

string | null: имя его ресурса или null (nil), если никакой не запущен.

Пример

if (gestures.emoteProvider() === null) console.log("no emote script: skipping the emote");

seatbelt

Ремень безопасности локального игрока через ai-core, какой бы скрипт ремня ни был запущен.

seatbelt.isOn

Пристёгнут ли ремень. Спрашивайте по необходимости, не каждый кадр.

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

Сигнатура
seatbelt.isOn(): boolean | null
Lua
local worn = aiLib.seatbelt.isOn() -- boolean или nil

Возвращает

boolean | null: true или false; null (nil), если не отвечает ни один скрипт ремня.

Пример

import { cache, notify, onCache, seatbelt } from "@aicore-fivem/lib/client";

onCache("vehicle", (vehicle) => {
  if (vehicle !== false && seatbelt.isOn() === false) notify("Buckle up", "warning");
});

seatbelt.onChange

Запускает обработчик, когда меняется состояние ремня. Его вызывают только скрипты ремня, которые сообщают об изменениях.

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

Сигнатура
seatbelt.onChange(fn: (worn: boolean | null) => void): void
Lua
aiLib.seatbelt.onChange(function(worn) end)

Параметры

Prop

Type

Возвращает

void.

Пример

seatbelt.onChange((worn) => SendNUIMessage({ action: "belt", data: worn === true }));

seatbelt.provider

Скрипт ремня, который отвечает.

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

Сигнатура
seatbelt.provider(): string | null
Lua
local name = aiLib.seatbelt.provider()

Возвращает

string | null: имя его ресурса или null (nil), если никакой не отвечает.

Пример

if (seatbelt.provider() === null) console.log("no seat belt script runs");

fuel

fuel.get

Уровень топлива транспорта. Сервер держит state bag fuel для каждого транспорта, какой бы скрипт топлива ни был запущен, поэтому это чтение из памяти; без этого bag это уровень бака в игре.

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

Сигнатура
fuel.get(vehicle: number): number

Lua-аналога нет: читайте Entity(vehicle).state.fuel. Задать топливо можно только на сервере (fuel.set на странице Транспорт).

Параметры

Prop

Type

Возвращает

number: 0-100.

Пример

import { cache, every, fuel } from "@aicore-fivem/lib/client";

every(1000, () => {
  if (cache.vehicle !== false) SendNUIMessage({ action: "fuel", data: Math.round(fuel.get(cache.vehicle)) });
});

mdt

mdt.open

Открывает активный полицейский MDT для локального игрока. MDT сам проверяет работу.

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

Сигнатура
mdt.open(): boolean
Lua
local ok = aiLib.mdt.open()

Возвращает

boolean: false, если MDT не запущен или его нельзя открыть извне.

Пример

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

RegisterCommand("mdt", () => {
  if (!mdt.open()) notify("No MDT available", "error");
}, false);

radial

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

radial.add

Добавляет пункт в колесо или заменяет пункт с тем же id.

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

Сигнатура
radial.add(item: RadialItem): void
Lua
aiLib.radial.add(item)

Параметры

Prop

Type

RadialItem

Prop

Type

Тип: RadialItem.

Возвращает

void.

Пример

import { cache, createLocale, hasJob, radial } from "@aicore-fivem/lib/client";
import { RADIAL_VEHICLE } from "@aicore-fivem/shared";

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

radial.add({
  id: "myscript:engine",
  label: Locale("ENGINE"),
  icon: "power-off",
  parent: RADIAL_VEHICLE,
  keepOpen: true,
  canShow: () => cache.seat === -1,
  onPressed: () => {
    if (cache.vehicle === false) return;
    SetVehicleEngineOn(cache.vehicle, !GetIsVehicleEngineRunning(cache.vehicle), false, true);
  },
});

radial.add({
  id: "myscript:police",
  label: Locale("POLICE"),
  icon: "shield-halved",
  canShow: () => hasJob(["police"]),
  items: [
    { id: "myscript:cuff", label: Locale("CUFF"), icon: "handcuffs", onPressed: () => emitNet("mypolice:cuff") },
  ],
});

radial.remove

Удаляет один из ваших пунктов. Неизвестный id ничего не делает.

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

Сигнатура
radial.remove(id: string): void
Lua
aiLib.radial.remove(id)

Параметры

Prop

Type

Возвращает

void.

Пример

radial.remove("myscript:engine");

radial.refresh

Заново читает все canShow открытого колеса. Вызывайте после того, как изменилось то, что они читают, пока колесо может быть открыто.

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

Сигнатура
radial.refresh(): void
Lua
aiLib.radial.refresh()

Возвращает

void.

Пример

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

world

Синхронизация погоды и времени того скрипта погоды, который запущен, приостановленная, пока действует причина.

world.pauseSync

Приостанавливает синхронизацию погоды и времени по причине: внутри интерьера, во время сцены или пока ваш скрипт задаёт собственную погоду.

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

Сигнатура
world.pauseSync(reason: string): void
Lua
aiLib.world.pauseSync(reason)

Параметры

Prop

Type

Возвращает

void.

Пример

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

export function enterApartment(): void {
  world.pauseSync("apartment");
  NetworkOverrideClockTime(12, 0, 0);
  SetWeatherTypeNowPersist("EXTRASUNNY");
}

export function leaveApartment(): void {
  world.resumeSync("apartment");
}

world.resumeSync

Убирает одну причину паузы; синхронизация снова работает, когда не осталось ни одной причины.

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

Сигнатура
world.resumeSync(reason: string): void
Lua
aiLib.world.resumeSync(reason)

Параметры

Prop

Type

Возвращает

void. См. пример world.pauseSync.

inventory

Инвентарь локального игрока через слой инвентаря ai-core: отвечает инвентарь, выбранный на сервере. Выдавать и забирать предметы можно только на сервере (Предметы).

inventory.openInventory

Открывает экран собственного инвентаря игрока.

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

Сигнатура
inventory.openInventory(): void
Lua
aiLib.inventory.openInventory()

Возвращает

void.

Пример

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

RegisterCommand("bag", () => inventory.openInventory(), false);

inventory.hasItem

Есть ли у игрока не меньше count единиц предмета. Используйте в canShow, чтобы игрок видел только то, что может сделать; сервер проверит снова.

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

Сигнатура
inventory.hasItem(item: string, count?: number): boolean
Lua
local has = aiLib.inventory.hasItem(item, count)

Параметры

Prop

Type

Возвращает

boolean: true, если у игрока достаточно.

Пример

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

const points = new Points();
points.addVehicle("lockpick", {
  label: "Lockpick",
  icon: "unlock",
  canShow: (vehicle) => GetVehicleDoorLockStatus(vehicle) >= 2 && inventory.hasItem("lockpick"),
  onPressed: (vehicle) => emitNet("mykeys:lockpick", NetworkGetNetworkIdFromEntity(vehicle)),
});

inventory.currentWeapon

Предмет оружия в руке игрока: его название, подпись и картинка.

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

Сигнатура
inventory.currentWeapon(): HeldWeapon | null
Lua
local weapon = aiLib.inventory.currentWeapon() -- таблица или nil

Возвращает

HeldWeapon { name: string; label: string; image?: string } (name вида WEAPON_PISTOL, image это URL nui://, если он есть у инвентаря) или null (nil), если рука пуста.

Пример

import { inventory, onCache } from "@aicore-fivem/lib/client";

// Читайте при смене оружия, никогда не каждый кадр.
onCache("weapon", () => SendNUIMessage({ action: "weapon", data: inventory.currentWeapon() }));

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

medicalmedical.isDeadВозвращаетПримерmedical.onChangeПараметрыВозвращаетПримерappearanceappearance.applyПараметрыВозвращаетПримерappearance.readПараметрыВозвращаетПримерappearance.openMenuПараметрыВозвращаетПримерappearance.wearOutfitПараметрыВозвращаетПримерappearance.reloadSkinВозвращаетПримерgesturesgestures.isHandsUpВозвращаетПримерgestures.isPointingВозвращаетПримерgestures.providerВозвращаетПримерgestures.playEmoteПараметрыВозвращаетПримерgestures.cancelEmoteВозвращаетПримерgestures.emoteProviderВозвращаетПримерseatbeltseatbelt.isOnВозвращаетПримерseatbelt.onChangeПараметрыВозвращаетПримерseatbelt.providerВозвращаетПримерfuelfuel.getПараметрыВозвращаетПримерmdtmdt.openВозвращаетПримерradialradial.addПараметрыRadialItemВозвращаетПримерradial.removeПараметрыВозвращаетПримерradial.refreshВозвращаетПримерworldworld.pauseSyncПараметрыВозвращаетПримерworld.resumeSyncПараметрыВозвращаетinventoryinventory.openInventoryВозвращаетПримерinventory.hasItemПараметрыВозвращаетПримерinventory.currentWeaponВозвращаетПример