Przedmioty
Dodawaj, zabieraj, licz i sprawdzaj przedmioty w dowolnym ekwipunku, rejestruj schowki, sklepy skryptów i używalne przedmioty, odczytuj definicje przedmiotów i noszoną wagę.
Każde wywołanie przedmiotów przechodzi przez ai-core, nigdy przez własne eksporty skryptu ekwipunku. ai-core przekazuje każde wywołanie do aktywnego ekwipunku: tego, który wybiera ustawienie Inventory script w panelu, albo pierwszego działającego, gdy ustawione jest automatycznie (ai-inventory, ox_inventory, qb-inventory, tgiann-inventory i inne z listy zgodności). Gdy właściciel serwera zmienia ekwipunek, twój skrypt działa dalej bez zmian.
Co trzeba wiedzieć:
- Ekwipunek jest nazywany przez
InventoryRef: id serwera gracza (liczba) dla kieszeni tego gracza albo tekstowe id dla wszystkiego innego (nazwa schowka, tablica bagażnika). Zobacz InventoryRef. - Nazwy przedmiotów to nazwy przedmiotów w ekwipunku (
water,bandage,WEAPON_PISTOL). - Metadane to tabela dodatkowych wartości na jednym stosie (numer seryjny, wytrzymałość). Zobacz ItemMetadata.
- Dopóki nie działa żaden ekwipunek, każde wywołanie odpowiada swoją wartością "nic":
false,0, pustą listą lubnull. - Schowki, sklepy i używalne przedmioty, które rejestrujesz, są trzymane przez ai-core i przekazywane każdemu ekwipunkowi, który stanie się aktywny później, także po restarcie ekwipunku. Rejestruj je raz, gdy twój skrypt startuje.
AddItem
Daje przedmioty do ekwipunku.
Strona: Serwer · Czeka: nie · Lib: inventory.addItem
AddItem(inv: InventoryRef, item: string, count?: number, metadata?: ItemMetadata, slot?: number): booleanlocal ok = exports['ai-core']:AddItem(source, 'water', 2)Parametry
Prop
Type
Zwraca
boolean: true, gdy ekwipunek dodał przedmioty. false, gdy się nie mieszczą, przedmiot nie istnieje w ekwipunku, argument jest zły (count poniżej 1, pusta nazwa przedmiotu) albo nie działa żaden ekwipunek.
Przykład
import { onClientCallback, resourceExport, near } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";
const core = resourceExport("ai-core");
const TAP = { x: 1206.4, y: -3110.2, z: 5.6 };
onClientCallback("myscript:fillBottle", { guards: [near(TAP, 2)], lock: true }, (source) => {
if (!core.RemoveItem(source, "empty_bottle")) return fail("NO_BOTTLE");
if (!core.AddItem(source, "water")) {
core.AddItem(source, "empty_bottle");
return fail("NO_SPACE");
}
return { ok: true };
});RemoveItem
Zabiera przedmioty z ekwipunku.
Strona: Serwer · Czeka: nie · Lib: inventory.removeItem
RemoveItem(inv: InventoryRef, item: string, count?: number, metadata?: ItemMetadata, slot?: number): booleanlocal ok = exports['ai-core']:RemoveItem(source, 'lockpick', 1)Parametry
Prop
Type
Zwraca
boolean: true, gdy przedmioty zostały zabrane. false, gdy ekwipunek ma ich mniej (wtedy nic nie jest zabierane), argument jest zły albo nie działa żaden ekwipunek.
Przykład
import { onClientCallback, minigameFor, resourceExport } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";
const core = resourceExport("ai-core");
onClientCallback("myscript:pickLock", { lock: true }, async (source) => {
if (!core.HasItem(source, "lockpick")) return fail("NO_LOCKPICK");
const result = await minigameFor(source, { game: "lockpick", minMs: 1500 });
if (result === "broken") core.RemoveItem(source, "lockpick");
return result === "won" ? { ok: true } : fail("LOCKPICK_FAILED");
});GetItemCount
Ile sztuk przedmiotu ma ekwipunek.
Strona: Serwer · Czeka: nie · Lib: inventory.getItemCount
GetItemCount(inv: InventoryRef, item: string, metadata?: ItemMetadata): numberlocal count = exports['ai-core']:GetItemCount(source, 'fish')Parametry
Prop
Type
Zwraca
number: suma ze wszystkich stosów. 0, gdy nie ma żadnego, argument jest zły albo nie działa żaden ekwipunek.
Przykład
import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
const core = resourceExport("ai-core");
// Skupujący ryby pokazuje, ile gracz by dostał.
onClientCallback("myscript:fishQuote", (source) => ({
ok: true,
price: core.GetItemCount(source, "fish") * 25,
}));HasItem
Czy ekwipunek ma co najmniej daną liczbę przedmiotu.
Strona: Serwer · Czeka: nie · Lib: inventory.hasItem
HasItem(inv: InventoryRef, item: string, count?: number): booleanlocal has = exports['ai-core']:HasItem(source, 'repairkit')Parametry
Prop
Type
Zwraca
boolean: true, gdy ekwipunek ma count lub więcej. false, gdy ma mniej, count jest poniżej 1 albo nie działa żaden ekwipunek.
Przykład
import { onClientCallback, progressFor, resourceExport } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";
import { Locale } from "common";
const core = resourceExport("ai-core");
onClientCallback("myscript:repair", { lock: true }, async (source) => {
if (!core.HasItem(source, "repairkit")) return fail("NO_KIT");
if (!(await progressFor(source, { label: Locale("REPAIRING"), duration: 8000 }))) return fail("CANCELLED");
if (!core.RemoveItem(source, "repairkit")) return fail("NO_KIT");
return { ok: true };
});Po wszystkim, co czeka (pasek postępu, minigra), sprawdź ponownie odpowiedzią RemoveItem: gracz mógł w międzyczasie wyrzucić przedmiot.
CanCarryItem
Czy przedmioty zmieściłyby się w ekwipunku (waga i sloty), bez ich dodawania.
Strona: Serwer · Czeka: nie · Lib: inventory.canCarryItem
CanCarryItem(inv: InventoryRef, item: string, count?: number, metadata?: ItemMetadata): booleanlocal fits = exports['ai-core']:CanCarryItem(source, 'water', 5)Parametry
Prop
Type
Zwraca
boolean: true, gdy się mieszczą. false, gdy się nie mieszczą, argument jest zły albo nie działa żaden ekwipunek.
Przykład
import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";
const core = resourceExport("ai-core");
onClientCallback("myscript:buyWater", { lock: true }, (source) => {
if (!core.CanCarryItem(source, "water", 5)) return fail("NO_SPACE");
if (!core.RemoveMoney(source, "cash", 50, "shop_water")) return fail("NOT_ENOUGH_MONEY");
core.AddItem(source, "water", 5);
return { ok: true };
});GetItems
Każdy stos w ekwipunku, z etykietami.
Strona: Serwer · Czeka: nie · Lib: inventory.getItems
GetItems(inv: InventoryRef): InventoryStack[]local stacks = exports['ai-core']:GetItems(source) -- lista tabelParametry
Prop
Type
Zwraca
InventoryStack[]: jeden wpis na stos z name, label, count, slot i metadata. Zobacz InventoryStack. Pusta lista dla pustego lub nieznanego ekwipunku, złego argumentu albo gdy nie działa żaden ekwipunek.
Przykład
import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
const core = resourceExport("ai-core");
// Lombard wyświetla każdy przedmiot, który gracz nosi, a który lombard skupuje.
const BUYS: Record<string, number> = { gold_ring: 120, rolex: 400 };
onClientCallback("myscript:pawnList", (source) => ({
ok: true,
rows: core.GetItems(source)
.filter((stack) => BUYS[stack.name] !== undefined)
.map((stack) => ({ slot: stack.slot, label: stack.label, count: stack.count, price: BUYS[stack.name] })),
}));ClearInventory
Całkowicie opróżnia ekwipunek.
Strona: Serwer · Czeka: nie · Lib: inventory.clearInventory
ClearInventory(inv: InventoryRef): voidexports['ai-core']:ClearInventory(source)Parametry
Prop
Type
Zwraca
Nic. Zły argument albo brak działającego ekwipunku nic nie robi.
Przykład
import { addCommand, resourceExport } from "@aicore-fivem/lib/server";
const core = resourceExport("ai-core");
addCommand("clearinv", { help: "Empties a player inventory", params: [{ name: "id", type: "playerId" }], restricted: true }, (_source, args) => {
core.ClearInventory(args.id);
});Tego nie da się cofnąć. Trzymaj to za komendą administratora albo jasną regułą gry (przyjęcie do więzienia, które najpierw przechowuje przedmioty).
RegisterStash
Tworzy schowek: skrzynię, którą gracze otwierają po jej nazwie. ai-core trzyma go i rejestruje ponownie w każdym ekwipunku, który staje się aktywny.
Strona: Serwer · Czeka: nie · Lib: inventory.registerStash
RegisterStash(name: string, label: string, slots: number, maxWeight: number, jobs?: string[]): voidexports['ai-core']:RegisterStash('police_evidence', 'Evidence', 100, 500000, { 'police' })Parametry
Prop
Type
Wartości domyślne obowiązują, gdy wartości brakuje lub jest zła.
Zwraca
Nic. Bez tekstowego name wywołanie nic nie robi. Ponowne zarejestrowanie tej samej nazwy zastępuje schowek.
Przykład
import { onClientCallback, resourceExport, near } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";
import { Locale } from "common";
const core = resourceExport("ai-core");
const LOCKER = { x: 474.9, y: -994.7, z: 26.3 };
// Raz przy starcie; ai-core przekazuje go ekwipunkom, które wystartują później.
core.RegisterStash("police_evidence", Locale("STASH_EVIDENCE"), 100, 500_000, ["police"]);
onClientCallback("myscript:openEvidence", { guards: [near(LOCKER, 2)] }, (source) => {
if (core.GetDutyJob(source) !== "police") return fail("NOT_POLICE");
return core.OpenInventory(source, "police_evidence") ? { ok: true } : fail("STASH_FAILED");
});OpenInventory
Otwiera schowek, bagażnik lub ekwipunek innego gracza na ekranie gracza, obok jego własnego.
Strona: Serwer · Czeka: nie · Lib: inventory.openInventory
OpenInventory(source: number, inv: InventoryRef): booleanlocal opened = exports['ai-core']:OpenInventory(source, 'police_evidence')Parametry
Prop
Type
Zwraca
boolean: true, gdy ekwipunek otworzył ekran. false, gdy nie mógł (nieznany schowek, gracz nie ma ekwipunku), argument jest zły albo nie działa żaden ekwipunek.
Przykład
import { onClientCallback, isNear, coordsOf, resourceExport } from "@aicore-fivem/lib/server";
import { fail, oneArg, readId } from "@aicore-fivem/lib/shared";
const core = resourceExport("ai-core");
// Policja przeszukuje skutego gracza, który stoi obok.
onClientCallback("myscript:search", { args: oneArg(readId) }, (source, target) => {
if (core.GetDutyJob(source) !== "police") return fail("NOT_POLICE");
if (target === source || !isNear(target, coordsOf(source), 2)) return fail("TOO_FAR");
return core.OpenInventory(source, target) ? { ok: true } : fail("SEARCH_FAILED");
});Ekwipunek nie sprawdza tutaj ani zasięgu, ani uprawnień. Sam sprawdź pracę, odległość i stan celu, zanim to wywołasz.
RegisterShop
Tworzy sklep skryptu: listę przedmiotów z cenami, którą twój skrypt otwiera dla gracza (zbrojownia, automat). Ekwipunek rysuje sklep i pobiera płatność po swojemu (gotówka, potem bank). ai-core trzyma go i przekazuje każdemu ekwipunkowi, który staje się aktywny.
Strona: Serwer · Czeka: nie · Lib: inventory.registerShop
RegisterShop(name: string, label: string, items: ShopProduct[]): voidexports['ai-core']:RegisterShop('police_armoury', 'Armoury', { { name = 'bandage', price = 0 } })Parametry
Prop
Type
Zobacz ShopProduct.
Zwraca
Nic. Bez tekstowego name albo bez żadnego poprawnego produktu wywołanie nic nie robi. Ponowne zarejestrowanie tej samej nazwy zastępuje sklep.
Przykład
import { onClientCallback, resourceExport, near } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";
import { Locale } from "common";
const core = resourceExport("ai-core");
const ARMOURY = { x: 482.6, y: -995.2, z: 30.7 };
core.RegisterShop("police_armoury", Locale("SHOP_ARMOURY"), [
{ name: "WEAPON_STUNGUN", price: 0 },
{ name: "bandage", price: 10 },
]);
onClientCallback("myscript:armoury", { guards: [near(ARMOURY, 2)] }, (source) => {
if (core.GetDutyJob(source) !== "police") return fail("NOT_POLICE");
return core.OpenShop(source, "police_armoury") ? { ok: true } : fail("SHOP_FAILED");
});OpenShop
Otwiera na ekranie gracza sklep zarejestrowany przez RegisterShop.
Strona: Serwer · Czeka: nie · Lib: inventory.openShop
OpenShop(source: number, name: string): booleanlocal opened = exports['ai-core']:OpenShop(source, 'police_armoury')Parametry
Prop
Type
Zwraca
boolean: true, gdy sklep się otworzył. false, gdy żaden sklep nie ma tej nazwy, aktywny ekwipunek nie ma sklepów skryptów, nie mógł go otworzyć albo nie działa żaden ekwipunek.
Przykład
Zobacz przykład RegisterShop powyżej: zarejestruj raz przy starcie, potem otwieraj po własnym sprawdzeniu pracy i odległości.
Tak jak OpenInventory, to nie sprawdza zasięgu ani dostępu. Sprawdź je najpierw.
RegisterUsableItem
Robi z przedmiotu przedmiot używalny: gdy gracz użyje go w ekwipunku, działa twoja funkcja. ai-core trzyma funkcję, więc działa z ekwipunkami, które wystartują później, i przetrwa restart ekwipunku.
Strona: Serwer · Czeka: nie · Lib: inventory.registerUsableItem
RegisterUsableItem(name: string, handler: UsableItemHandler): void
// UsableItemHandler = (source: number, item: UsedItem) => unknownexports['ai-core']:RegisterUsableItem('bandage', function(source, item) end)Parametry
Prop
Type
Zobacz UsableItemHandler i UsedItem.
Zwraca
Nic. Bez tekstowego name albo funkcji wywołanie nic nie robi. Drugie wywołanie dla tego samego przedmiotu zastępuje handler.
To, co dzieje się z przedmiotem po użyciu, zależy od ekwipunku: ekwipunki, które same zabierają użyty przedmiot (ai-inventory zabiera ilość consume przedmiotu), zatrzymują go, gdy twój handler zwróci false; inne ekwipunki działają według własnych ustawień przedmiotu, więc tam w razie potrzeby usuń przedmiot sam.
Przykład
import { progressFor, resourceExport } from "@aicore-fivem/lib/server";
import { Locale } from "common";
const core = resourceExport("ai-core");
core.RegisterUsableItem("bandage", (source) => {
// Handler musi odpowiedzieć od razu; część czasowa działa osobno.
void (async () => {
if (!(await progressFor(source, { label: Locale("BANDAGING"), duration: 4000 }))) return;
if (!core.RemoveItem(source, "bandage")) return;
emitNet("myscript:client:heal", source, 25); // twój skrypt kliencki dodaje zdrowie
})();
return false; // zatrzymaj go: zostaje usunięty powyżej, gdy pasek się skończy
});Użycie wysyła też serwerowe zdarzenie ai-core:itemUsed (src, name, status), które śledzą efekty przedmiotów, takie jak głód i pragnienie. Zobacz Zdarzenia i stan.
GetItemDefinition
Jeden przedmiot tak, jak definiuje go aktywny ekwipunek: etykieta, waga, czy się łączy w stosy, obrazek.
Strona: Serwer · Czeka: nie · Lib: inventory.getItemDefinition
GetItemDefinition(name: string): ItemDefinition | nulllocal def = exports['ai-core']:GetItemDefinition('water') -- table lub nilParametry
Prop
Type
Zwraca
ItemDefinition | null: przedmiot z name, label, weight, unique, close, description i image, gdy ekwipunek go ma. Zobacz ItemDefinition. null dla nieznanego przedmiotu, pustej nazwy albo gdy nie działa żaden ekwipunek.
Przykład
import { notify, resourceExport } from "@aicore-fivem/lib/server";
import { Locale } from "common";
const core = resourceExport("ai-core");
/** "You received 2x Water" with the inventory's own label. */
export function giveWithNotice(source: number, item: string, count: number): void {
if (!core.AddItem(source, item, count)) return;
const label = core.GetItemDefinition(item)?.label ?? item;
notify(source, Locale("NOTIFY_RECEIVED", count, label), "success");
}GetItemDefinitions
Każdy przedmiot zdefiniowany przez aktywny ekwipunek, z nazwą jako kluczem. Używaj tego rzadko (jednorazowe budowanie listy); dla jednego przedmiotu używaj GetItemDefinition.
Strona: Serwer · Czeka: nie · Lib: brak
GetItemDefinitions(): Record<string, ItemDefinition>local items = exports['ai-core']:GetItemDefinitions() -- tabela z nazwą przedmiotu jako kluczemParametry
Brak.
Zwraca
Record<string, ItemDefinition>: każdy przedmiot. Pusta tabela, dopóki nie działa żaden ekwipunek.
Przykład
import { resourceExport } from "@aicore-fivem/lib/server";
const core = resourceExport("ai-core");
/** Warns at start about items in your config that the inventory does not know. */
export function checkItems(names: string[]): void {
const known = core.GetItemDefinitions();
for (const name of names) if (!known[name]) console.log(`unknown item: ${name}`);
}Uruchamiaj takie sprawdzenie po starcie ekwipunku: zaraz po starcie serwera ekwipunek może jeszcze nie działać, a tabela jest pusta.
GetInventoryWeight
Co gracz nosi i ile może unieść, według wagi.
Strona: Serwer · Czeka: nie · Lib: brak
GetInventoryWeight(source: number): { weight: number; maxWeight: number } | nulllocal w = exports['ai-core']:GetInventoryWeight(source) -- { weight, maxWeight } lub nilParametry
Prop
Type
Zwraca
{ weight, maxWeight } | null: noszona waga i limit, w gramach. null, gdy aktywny ekwipunek ich nie podaje, gracz nie ma wczytanego ekwipunku albo nie działa żaden ekwipunek.
Przykład
import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
const core = resourceExport("ai-core");
onClientCallback("myscript:weight", (source) => {
const w = core.GetInventoryWeight(source);
return { ok: true, free: w ? w.maxWeight - w.weight : null };
});UseItem
Uruchamia handler zarejestrowany dla przedmiotu, tak jakby gracz go użył. Wywołuje to most ESX / QB w ai-core (z ESX.UseItem i CanUseItem z QB); zwykły skrypt nie ma powodu tego robić.
Strona: Serwer · Czeka: nie · Lib: brak (tylko most)
UseItem(source: number, name: string, item?: unknown): unknownlocal result = exports['ai-core']:UseItem(source, 'bandage', stack)Parametry
Prop
Type
Zwraca
unknown: to, co zwrócił handler. false, gdy żaden handler nie jest zarejestrowany, argumenty są złe albo handler rzucił wyjątek (zapisane w logu).
Przykład
Bez przykładu: wywołują to ekwipunki i most. Aby zareagować na użycie, zarejestruj przedmiot przez RegisterUsableItem.
IsUsableItem
Czy dla przedmiotu jest zarejestrowany handler. Używa tego most ai-core.
Strona: Serwer · Czeka: nie · Lib: brak (tylko most)
IsUsableItem(name: string): booleanlocal usable = exports['ai-core']:IsUsableItem('bandage')Parametry
Prop
Type
Zwraca
boolean: true, gdy jakiś zasób zarejestrował przedmiot przez RegisterUsableItem. W przeciwnym razie false.
Przykład
import { resourceExport } from "@aicore-fivem/lib/server";
const core = resourceExport("ai-core");
/** Item tooltips show "Use" only for usable items. */
export function canUse(item: string): boolean {
return core.IsUsableItem(item);
}