AI Core
API başvurusuLib: client

Etkileşim noktaları

Points - oyuncunun kullandığı her yer (tezgahlar, marketler, kapılar, NPC’ler, ATM’ler, araç bagajları), bir prompt ya da target seçeneği olarak; ped’ler, blip’ler ve panel kayıtlarından kurulan noktalarla.

Nokta, oyuncunun kullandığı herhangi bir yerdir: bir market tezgahı, bir kapı, bir NPC, bir iade noktası, her ATM, her arabanın bagajı. Onu bir kez tanımlarsın (nerede, hangi metin, ne olur) ve lib onu sunucu sahibinin seçtiği şekilde çizer.

Prompt ya da target

Sahip etkileşim stilini ai-core’un admin panelinde (Interaction) seçer. Her iki durumda da aynı onPressed çalışır; bu yüzden script’in hangisinin açık olduğunu hiç umursamaz.

StilOyuncunun gördüğü
PromptOyuncu noktanın yarıçapı içinde durduğu sürece ekranın sağ tarafında bir "E’ye bas" kutusu. Tuş, ai-lib’de yeniden atanabilir tek bir keybind’dır (varsayılan E); bu yüzden hiçbir şey her karede tuşları yoklamaz.
TargetNoktadaki, NPC’deki, nesnedeki ya da araçtaki target gözünde bir seçenek. Lib’in adaptörü olduğu target script’lerinden birinin çalışmasını gerektirir. Birden fazlası çalışıyorsa bu sıradaki ilki kazanır: ai-target, tgiann-radialmenu-target, tgiann-target, sleepless_interact, ox_target, qb-target, interact.

Sahip target’ı seçtiyse ama hiçbir target script’i çalışmıyorsa her nokta bir prompt olur. Bir nokta sahibin seçimini geçersiz kılabilir: promptOnly prompt’u korur (araçtan yapılan şeyler: yakıt pompaları, oto yıkamalar), preferTarget bir target script’i çalıştığında her zaman target seçeneği kullanır (koltuklar). Bir target script’i başladığında ya da durduğunda veya sahip stili değiştirdiğinde her nokta kendiliğinden geçiş yapar.

Resource’unun aynı anda yalnızca bir nokta aksiyonu çalışır. onPressed bir promise döndürdüğünde, resource’unun diğer noktaları o sonuçlanana kadar basmaları yok sayar; böylece kendi busy bayrağına hiç ihtiyacın olmaz. Oyuncu ayrıca basma anında canShow’dan da geçmelidir.

new Points

Bir nokta grubu oluşturur. Dosyanın en üstünde özellik başına bir grup oluştur ve noktaları ona ekle.

Taraf: Client · Bekler: hayır

Signature
new Points()
Lua
local points = aiLib.Points.new()

Dönüş değeri

Aşağıdaki metotlara sahip bir Points grubu.

Örnek

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

const points = new Points();

points.add

Bir yere nokta ekler ya da aynı id’ye sahip noktanın yerine geçer. Bir nokta kendi NPC’sini (ped) ve harita blip’ini (blip) taşıyabilir.

Taraf: Client · Bekler: hayır

Signature
points.add(id: string, options: PointOptions): void
Lua
points:add(id, options)

Parametreler

Prop

Type

PointOptions

Prop

Type

PointPed

ped alanı, onSpawn ve onDespawn dışında (nokta onları kullanır) LocalPed seçeneklerini alır:

Prop

Type

PointBlip

blip alanı blip seçeneklerini alır; coords varsayılan olarak noktadır:

Prop

Type

PromptAnchor

Bir world fonksiyonunun döndürdüğü (PromptAnchor), şunlardan biri:

Prop

Type

Dönüş değeri

void.

Örnek

resource/client/index.ts
import { callAction, createLocale, hasJob, onMembershipChange, Points } from "@aicore-fivem/lib/client";

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

// Bir dükkân sahibi ve harita blip’i olan bir market tezgahı.
points.add("shop", {
  coords: { x: 25.7, y: -1347.3, z: 29.5 },
  label: Locale("OPEN_SHOP"),
  icon: "basket-shopping",
  ped: { model: "mp_m_shopkeep_01", coords: { x: 24.5, y: -1346.6, z: 29.5, heading: 270 } },
  blip: { sprite: 52, color: 2, label: Locale("SHOP") },
  onPressed: () => callAction("myshop:open", [], { fallback: "SHOP_FAILED" }),
});

// Yalnızca polisin açabildiği bir depo; metin bir durumu takip eder.
let locked = true;
points.add("evidence", {
  coords: { x: 474.9, y: -996.4, z: 26.3 },
  label: () => (locked ? Locale("UNLOCK") : Locale("LOCK")),
  icon: "box-archive",
  canShow: () => hasJob(["police"], 2),
  onPressed: async () => {
    const reply = await callAction("myscript:toggle", [], { fallback: "TOGGLE_FAILED" });
    if (reply) locked = !locked;
    points.refresh("evidence");
  },
});

// canShow mesleği okur: meslekler, görev durumu ya da çeteler değiştiğinde tekrar kontrol et.
onMembershipChange(() => points.refresh());

canShow yalnızca oyuncunun ne gördüğüne karar verir. Server kendi handler’ında tekrar kontrol etmelidir (meslek, mesafe, stok). Bir hileci server event’ini hiçbir nokta olmadan çağırabilir.

points.addModel

Belirli modellerin her dünya nesnesine (ATM’ler, otomatlar, çöp konteynerleri, sandalyeler) bir nokta ekler ya da aynı id’ye sahip noktanın yerine geçer. Target modunda bu modeller üzerinde bir target seçeneğidir; prompt modunda en yakının yanında bir prompt gösterilir. En yakın nesne taraması, tüm resource’lar için ai-lib’de bir kez, saniyede iki kez çalışır ve oyuncu hareketsizken duraklar.

Taraf: Client · Bekler: hayır

Signature
points.addModel(id: string, options: ModelPointOptions): void
Lua
points:addModel(id, options)

Parametreler

Prop

Type

ModelPointOptions

Prop

Type

Dönüş değeri

void.

Örnek

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

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

points.addModel("atm", {
  models: ["prop_atm_01", "prop_atm_02", "prop_atm_03", "prop_fleeca_atm"],
  label: Locale("USE_ATM"),
  icon: "credit-card",
  onPressed: (atm) => callAction("mybank:atm", [NetworkGetNetworkIdFromEntity(atm)], { fallback: "ATM_FAILED" }),
});

Tek bir nesnenin iki durumu (bir tekneyi bağlamak ve çözmek), tek bir etiket fonksiyonu değil, zıt canShow’lara sahip iki model noktasıdır. 6’dan fazla modeli olan bir nokta nesnelerini nesne havuzunun bir index’i üzerinden bulur; böylece yüzlerce model birkaç modelle aynı maliyettedir.

points.addVehicle

Ağa bağlı her araca bir nokta ekler (bagaj, kaput, itmek, tamir) ya da aynı id’ye sahip noktanın yerine geçer. Target modunda target script’inin global araç seçeneğidir; prompt modunda radius içindeki ağa bağlı en yakın aracın yanında bir prompt gösterilir.

Taraf: Client · Bekler: hayır

Signature
points.addVehicle(id: string, options: VehiclePointOptions): void
Lua
points:addVehicle(id, options)

Parametreler

Prop

Type

Dönüş değeri

void.

Örnek

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

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

points.addVehicle("trunk", {
  label: Locale("OPEN_TRUNK"),
  icon: "box-open",
  radius: 2.5,
  canShow: (vehicle) => vehicle !== 0 && cache.vehicle === false && GetVehicleDoorLockStatus(vehicle) < 2,
  onPressed: (vehicle) => SetVehicleDoorOpen(vehicle, 5, false, false),
});

points.remove

Tek bir noktayı prompt’u, target seçeneği, NPC’si ve blip’iyle birlikte kaldırır. add, addModel ve addVehicle ile yapılan noktalarda çalışır. Bilinmeyen bir id hiçbir şey yapmaz.

Taraf: Client · Bekler: hayır

Signature
points.remove(id: string): void
Lua
points:remove(id)

Parametreler

Prop

Type

Dönüş değeri

void.

Örnek

points.remove("shop");

points.clear

Grubun tüm noktalarını kaldırır.

Taraf: Client · Bekler: hayır

Signature
points.clear(): void
Lua
points:clear()

Dönüş değeri

void.

Örnek

onServerEvent("myscript:jobEnded", () => points.clear());

Panel noktalarını her panel değişikliğinde asla clear() + her şeyi yeniden ekleyerek kurma: binlerce kayıtla tek bir düzenleme her client’ta hepsini yeniden kurar. RecordObjects kullan: bir düzenleme yalnızca kendi kaydını yeniden kurar.

points.refresh

canShow’u ve fonksiyon etiketlerini yeniden okur. Okudukları bir şey değiştiğinde çağır: meslek, görev durumu, bir araç, server’ın gönderdiği bir durum. Prompt’lar hemen güncellenir; target seçenekleri canShow’u göz açıldığında okur ve değişen bir etiket yeniden konur.

Taraf: Client · Bekler: hayır

Signature
points.refresh(id?: string): void
Lua
points:refresh() -- grubun tüm noktaları

Parametreler

Prop

Type

Dönüş değeri

void.

Örnek

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

const points = new Points();
const robbed = new EntityState("robbed", stateBoolean);

onCache("vehicle", () => points.refresh());
onMembershipChange(() => points.refresh());
// Bir kasa değişti: yalnızca onun noktasını yenile.
robbed.onChange((netId) => points.refresh(`register:${netId}`));

Ham bir AddStateBagChangeHandler içinde yeni değer henüz okunamaz: orada refresh’i bir setTimeout(..., 0) içinde çağır. Lib’in state sınıfları (EntityState.onChange) sana yeni değeri zaten verir.

points.isInside

Oyuncunun şu an bir noktanın yarıçapı içinde durup durmadığı (add ile yapılan noktalar).

Taraf: Client · Bekler: hayır

Signature
points.isInside(id: string): boolean

Lua karşılığı yok.

Parametreler

Prop

Type

Dönüş değeri

boolean: oyuncu içerideyken true; dışarıdayken ya da bilinmeyen bir id veya model noktası için false.

Örnek

if (points.isInside("garage")) notify(Locale("PARK_HERE"), "info");

points.restyle

Grubun tüm noktalarını güncel etkileşim stiline geçirir. Sahip stili değiştirdiğinde ya da bir target script’i başladığında veya durduğunda lib bunu kendisi çağırır; ona hiç ihtiyacın olmaz.

Taraf: Client · Bekler: hayır

Signature
points.restyle(): void

Lua karşılığı yok (Lua da kendiliğinden yeniden stillendirir).

Dönüş değeri

void.

Panel kayıtlarından noktalar

Noktaların çoğu script’inin admin panelindeki bir records dosyasından gelir (marketler, garajlar, kiralama tezgahları). Dosyayı client’ta AdminWorld ile yansıt, sonra her kaydın noktalarını RecordObjects ile kur: düzenlenen bir kayıt yalnızca kendi noktalarını yeniden kurar, silinen bir kayıt onları kaldırır.

new RecordObjects

Bir records dosyasının dünya nesnelerini (noktalar, blip’ler, ped’ler, bölgeler) her seferinde bir kayıt olacak şekilde dosyayla uyumlu tutar. build(key, record) bir kaydın nesnelerini yapar ve onları nasıl kaldıracağını döndürür. Constructor’ında her kaydı kurar.

Taraf: Client ve server (@aicore-fivem/lib/shared’dan) · Bekler: hayır

Signature
new RecordObjects<T>(
  source: RecordSource,
  file: string,
  records: RecordReader<T> | ReadonlyMap<string, T>,
  build: (key: string, record: T) => (() => void) | void,
)

Lua karşılığı yok.

Parametreler

Prop

Type

Üyeler

Prop

Type

Örnek

resource/client/index.ts
import { AdminWorld, callAction, createLocale, Points } from "@aicore-fivem/lib/client";
import { readVec3, RecordObjects, str } from "@aicore-fivem/lib/shared";

const Locale = createLocale<typeof import("../../locales/en.json")>();
const world = new AdminWorld(["settings", "shops"]);
const points = new Points();

interface Shop { label: string; coords: { x: number; y: number; z: number } }
const readShop = (_key: string, raw: Record<string, unknown>): Shop | null => {
  const coords = readVec3(raw.coords);
  return coords ? { label: str(raw.label, "Shop"), coords } : null;
};

const shops = new RecordObjects(world, "shops", readShop, (id, shop) => {
  points.add(id, {
    coords: shop.coords,
    label: Locale("OPEN_SHOP", shop.label),
    onPressed: () => callAction("myshop:open", [id], { fallback: "SHOP_FAILED" }),
  });
  return () => points.remove(id);
});

// Her marketin okuduğu bir ayar değişti: hepsini yeniden kur.
world.onChange("settings", () => shops.rebuildAll());

RecordObjects constructor’ında kurar. Onu build’in okuduğu her şeyden sonra oluştur ve build içinde record argümanını kullan: RecordObjects’i tutan bir sınıf alanı o ilk kurulum sırasında henüz atanmamıştır.

new AdminWorld

Script’inin dünya panel dosyalarının (şeması sync: "all" diyen dosyalar, bkz. Admin paneli) client kopyası. FiveM’in açılışta önbelleğe aldığı kopyayı okur, o zamandan beri değişen kayıtlar için server’a bir kez sorar, sonra canlı değişiklikleri takip eder. Asla yoklama yapmaz.

Taraf: Client · Bekler: hayır (ready promise’i açılıştan beri olan değişikliklerin ne zaman geldiğini söyler)

Signature
new AdminWorld(files: string[])

Lua karşılığı yok.

Parametreler

Prop

Type

Üyeler

Prop

Type

Örnek

import { AdminWorld } from "@aicore-fivem/lib/client";
import { num, record } from "@aicore-fivem/lib/shared";

const world = new AdminWorld(["settings"]);
const settings = world.view("settings", (raw) => ({
  radius: num(record(raw).radius, 2),
}));

world.onChange("settings", () => console.log("new radius", settings.value.radius));

Bu sayfada