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.
| Stil | Oyuncunun gördüğü |
|---|---|
| Prompt | Oyuncu 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. |
| Target | Noktadaki, 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
new Points()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
points.add(id: string, options: PointOptions): voidpoints: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
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
points.addModel(id: string, options: ModelPointOptions): voidpoints: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
points.addVehicle(id: string, options: VehiclePointOptions): voidpoints: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
points.remove(id: string): voidpoints: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
points.clear(): voidpoints: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
points.refresh(id?: string): voidpoints: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
points.isInside(id: string): booleanLua 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
points.restyle(): voidLua 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
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
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)
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));Yerel oyuncu
Önbellekteki ped, araç, koltuk ve silah, player nesnesi (konum, ışınlanma, animasyonlar), ekran kararmaları, diğer oyuncuların ped’leri ve en yakın oyuncu.
Bölgeler
Zones - giriş ve çıkış callback’leri olan alanlar (küre, silindir, çokgen); asla her karede değil, kendi aralıklarında kontrol edilir.