Геометрия зон
zoneContains, zoneBounds, polyFromCorners и readZoneShape: находится ли точка внутри области, на сервере, на клиенте или в NUI.
Область в мире это ZoneShape: сфера, цилиндр или полигон на земле между двумя высотами. Клиентский класс Zones (колбэки входа и выхода, см. Зоны) использует эти формы; помощники на этой странице это простая математика за ним, без нативов, поэтому сервер может проверить ту же область (действительно ли игрок внутри магазина, прежде чем продать?).
import { zoneContains, zoneBounds, polyFromCorners, readZoneShape, type ZoneShape } from "@aicore-fivem/lib/shared";Lua: ни у одного из них нет Lua-аналога. Зоны в Lua это aiLib.Zones.new() на клиенте (см. Зоны).
zoneContains
Лежит ли точка внутри формы зоны.
Сторона: Клиент, сервер и NUI · Ждёт: нет
zoneContains(shape: ZoneShape, x: number, y: number, z: number): booleanПараметры
Prop
Type
Возвращает
true, если точка внутри (для сфер и цилиндров граница считается внутренней частью). Для цилиндра точка также должна быть в пределах height метров выше или ниже центра. Для полигона z должна быть между minZ и maxZ.
Пример
import { coordsOf, onClientCallback } from "@aicore-fivem/lib/server";
import { fail, zoneContains, type ZoneShape } from "@aicore-fivem/lib/shared";
const shop: ZoneShape = { type: "cylinder", center: { x: 25.7, y: -1347.3, z: 29.5 }, radius: 6, height: 3 };
onClientCallback("my-shop:open", (source) => {
const { x, y, z } = coordsOf(source);
if (!zoneContains(shop, x, y, z)) return fail("TOO_FAR");
return { ok: true };
});zoneBounds
Ограничивающий прямоугольник формы на земле: наименьший прямоугольник (x / y), который её вмещает. Используйте для дешёвой первичной проверки или чтобы распределить зону по ячейкам сетки.
Сторона: Клиент, сервер и NUI · Ждёт: нет
zoneBounds(shape: ZoneShape): [minX: number, minY: number, maxX: number, maxY: number]Параметры
Prop
Type
Возвращает
[minX, minY, maxX, maxY] в метрах. Для сферы или цилиндра: центр плюс и минус радиус.
Пример
import { zoneBounds } from "@aicore-fivem/lib/shared";
zoneBounds({ type: "sphere", center: { x: 100, y: 200, z: 30 }, radius: 10 }); // [90, 190, 110, 210]polyFromCorners
Превращает углы, которые сохраняет виджет zone панели, в форму-полигон. Диапазон высот это наименьшая и наибольшая z углов, расширенная на height метров вверх и вниз.
Сторона: Клиент, сервер и NUI · Ждёт: нет
polyFromCorners(corners: readonly Vec3[], height: number): { type: "poly"; points: Array<{ x: number; y: number }>; minZ: number; maxZ: number } | nullПараметры
Prop
Type
Возвращает
ZoneShape типа poly или null, если углов меньше трёх.
Пример
import { polyFromCorners } from "@aicore-fivem/lib/shared";
const lot = polyFromCorners(
[ { x: 210, y: -810, z: 30 }, { x: 240, y: -800, z: 31 }, { x: 230, y: -770, z: 32 } ],
3,
);
// { type: "poly", points: [...], minZ: 27, maxZ: 35 }readZoneShape
Проверяет форму зоны, которая пришла от другого ресурса или из файла: каждое число конечное, у полигона не меньше трёх точек. Используйте для формы, переданной в один из ваших экспортов.
Сторона: Клиент, сервер и NUI · Ждёт: нет
readZoneShape(value: unknown): ZoneShape | nullПараметры
Prop
Type
Возвращает
Чистый ZoneShape (лишние поля отброшены) или null, если это не верная сфера, цилиндр или полигон.
Пример
import { registerExport } from "@aicore-fivem/lib/server";
import { readZoneShape, type ZoneShape } from "@aicore-fivem/lib/shared";
const noParking = new Map<string, ZoneShape>();
registerExport("AddNoParkingZone", (id: unknown, raw: unknown) => {
const shape = readZoneShape(raw);
if (typeof id !== "string" || !shape) return false;
noParking.set(id, shape);
return true;
});vector3 из Lua приходит в TypeScript как массив, который readZoneShape не принимает в качестве center. Вызывающие из Lua передают center = { x = 1.0, y = 2.0, z = 3.0 }.