Items
Items in jedem Inventar hinzufügen, entfernen, zählen und prüfen, Lager, Skript-Shops und benutzbare Items registrieren, Item-Definitionen und getragenes Gewicht lesen.
Jeder Item-Aufruf läuft über ai-core, nie über die eigenen Exports eines Inventar-Skripts. ai-core leitet jeden Aufruf an das aktive Inventar weiter: das, das die Panel-Einstellung Inventory script (Inventar-Skript) wählt, oder das erste, das läuft, wenn sie auf automatisch steht (ai-inventory, ox_inventory, qb-inventory, tgiann-inventory und die anderen aus der Kompatibilitätsliste). Wenn der Serverbesitzer das Inventar wechselt, funktioniert dein Skript unverändert weiter.
Was du wissen solltest:
- Ein Inventar wird über eine
InventoryRefbenannt: die Server-ID eines Spielers (eine Zahl) für die Taschen dieses Spielers oder eine Text-ID für alles andere (ein Lagername, ein Kofferraum-Kennzeichen). Siehe InventoryRef. - Item-Namen sind die Item-Namen des Inventars (
water,bandage,WEAPON_PISTOL). - Metadaten sind eine Tabelle zusätzlicher Werte auf einem Stapel (eine Seriennummer, Haltbarkeit). Siehe ItemMetadata.
- Solange kein Inventar läuft, antwortet jeder Aufruf mit seinem „Nichts“-Wert:
false,0, einer leeren Liste odernull. - Lager, Shops und benutzbare Items, die du registrierst, werden von ai-core verwahrt und an jedes Inventar übergeben, das später aktiv wird, auch nach einem Neustart des Inventars. Registriere sie einmal, wenn dein Skript startet.
AddItem
Gibt einem Inventar Items.
Seite: Server · Wartet: nein · Lib: inventory.addItem
AddItem(inv: InventoryRef, item: string, count?: number, metadata?: ItemMetadata, slot?: number): booleanlocal ok = exports['ai-core']:AddItem(source, 'water', 2)Parameter
Prop
Type
Rückgabe
boolean: true, wenn das Inventar die Items hinzugefügt hat. false, wenn sie nicht passen, das Item im Inventar nicht existiert, ein Argument falsch ist (count unter 1, leerer Item-Name) oder kein Inventar läuft.
Beispiel
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
Nimmt Items aus einem Inventar.
Seite: Server · Wartet: nein · Lib: inventory.removeItem
RemoveItem(inv: InventoryRef, item: string, count?: number, metadata?: ItemMetadata, slot?: number): booleanlocal ok = exports['ai-core']:RemoveItem(source, 'lockpick', 1)Parameter
Prop
Type
Rückgabe
boolean: true, wenn die Items genommen wurden. false, wenn das Inventar weniger enthält (dann wird keines genommen), ein Argument falsch ist oder kein Inventar läuft.
Beispiel
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
Wie viele eines Items ein Inventar enthält.
Seite: Server · Wartet: nein · Lib: inventory.getItemCount
GetItemCount(inv: InventoryRef, item: string, metadata?: ItemMetadata): numberlocal count = exports['ai-core']:GetItemCount(source, 'fish')Parameter
Prop
Type
Rückgabe
number: die Summe über alle Stapel. 0, wenn keines da ist, ein Argument falsch ist oder kein Inventar läuft.
Beispiel
import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
const core = resourceExport("ai-core");
// Der Fischhändler zeigt, wie viel der Spieler bekommen würde.
onClientCallback("myscript:fishQuote", (source) => ({
ok: true,
price: core.GetItemCount(source, "fish") * 25,
}));HasItem
Ob ein Inventar mindestens eine bestimmte Anzahl eines Items enthält.
Seite: Server · Wartet: nein · Lib: inventory.hasItem
HasItem(inv: InventoryRef, item: string, count?: number): booleanlocal has = exports['ai-core']:HasItem(source, 'repairkit')Parameter
Prop
Type
Rückgabe
boolean: true, wenn das Inventar count oder mehr enthält. false, wenn es weniger enthält, count unter 1 liegt oder kein Inventar läuft.
Beispiel
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 };
});Prüfe nach allem, was wartet (ein Fortschrittsbalken, ein Minispiel), erneut mit der Antwort von RemoveItem: Der Spieler kann das Item inzwischen fallen gelassen haben.
CanCarryItem
Ob Items in ein Inventar passen würden (Gewicht und Slots), ohne sie hinzuzufügen.
Seite: Server · Wartet: nein · Lib: inventory.canCarryItem
CanCarryItem(inv: InventoryRef, item: string, count?: number, metadata?: ItemMetadata): booleanlocal fits = exports['ai-core']:CanCarryItem(source, 'water', 5)Parameter
Prop
Type
Rückgabe
boolean: true, wenn sie passen. false, wenn nicht, ein Argument falsch ist oder kein Inventar läuft.
Beispiel
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
Jeder Stapel in einem Inventar, mit Labels.
Seite: Server · Wartet: nein · Lib: inventory.getItems
GetItems(inv: InventoryRef): InventoryStack[]local stacks = exports['ai-core']:GetItems(source) -- Liste von TabellenParameter
Prop
Type
Rückgabe
InventoryStack[]: ein Eintrag pro Stapel mit name, label, count, slot und metadata. Siehe InventoryStack. Eine leere Liste für ein leeres oder unbekanntes Inventar, ein falsches Argument oder wenn kein Inventar läuft.
Beispiel
import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
const core = resourceExport("ai-core");
// Ein Pfandhaus listet jedes Item, das der Spieler trägt und das es ankauft.
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
Leert ein Inventar vollständig.
Seite: Server · Wartet: nein · Lib: inventory.clearInventory
ClearInventory(inv: InventoryRef): voidexports['ai-core']:ClearInventory(source)Parameter
Prop
Type
Rückgabe
Nichts. Ein falsches Argument oder ein nicht laufendes Inventar bewirkt nichts.
Beispiel
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);
});Das kann nicht rückgängig gemacht werden. Halte es hinter einem Admin-Befehl oder einer klaren Spielregel (eine Gefängnisaufnahme, die die Items vorher einlagert).
RegisterStash
Erstellt ein Lager: eine Aufbewahrungskiste, die Spieler über ihren Namen öffnen. ai-core verwahrt es und registriert es erneut bei jedem Inventar, das aktiv wird.
Seite: Server · Wartet: nein · Lib: inventory.registerStash
RegisterStash(name: string, label: string, slots: number, maxWeight: number, jobs?: string[]): voidexports['ai-core']:RegisterStash('police_evidence', 'Evidence', 100, 500000, { 'police' })Parameter
Prop
Type
Die Standardwerte gelten, wenn ein Wert fehlt oder falsch ist.
Rückgabe
Nichts. Ohne einen Text-name tut der Aufruf nichts. Wird derselbe Name erneut registriert, ersetzt das das Lager.
Beispiel
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 };
// Einmal beim Start; ai-core übergibt es an Inventare, die später starten.
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
Öffnet ein Lager, einen Kofferraum oder das Inventar eines anderen Spielers auf dem Bildschirm eines Spielers, neben seinem eigenen.
Seite: Server · Wartet: nein · Lib: inventory.openInventory
OpenInventory(source: number, inv: InventoryRef): booleanlocal opened = exports['ai-core']:OpenInventory(source, 'police_evidence')Parameter
Prop
Type
Rückgabe
boolean: true, wenn das Inventar den Bildschirm geöffnet hat. false, wenn es das nicht konnte (unbekanntes Lager, der Spieler hat kein Inventar), ein Argument falsch ist oder kein Inventar läuft.
Beispiel
import { onClientCallback, isNear, coordsOf, resourceExport } from "@aicore-fivem/lib/server";
import { fail, oneArg, readId } from "@aicore-fivem/lib/shared";
const core = resourceExport("ai-core");
// Die Polizei durchsucht einen gefesselten Spieler, der neben ihr steht.
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");
});Das Inventar prüft hier weder Reichweite noch Berechtigung. Prüfe den Job, die Entfernung und den Zustand des Ziels selbst, bevor du es aufrufst.
RegisterShop
Erstellt einen Skript-Shop: eine Liste von Items mit Preisen, die dein Skript für einen Spieler öffnet (eine Waffenkammer, ein Verkaufsautomat). Das Inventar zeichnet den Shop und nimmt die Zahlung auf seine eigene Art (Bargeld, dann Bank). ai-core verwahrt ihn und übergibt ihn an jedes Inventar, das aktiv wird.
Seite: Server · Wartet: nein · Lib: inventory.registerShop
RegisterShop(name: string, label: string, items: ShopProduct[]): voidexports['ai-core']:RegisterShop('police_armoury', 'Armoury', { { name = 'bandage', price = 0 } })Parameter
Prop
Type
Siehe ShopProduct.
Rückgabe
Nichts. Ohne einen Text-name oder ohne gültiges Produkt tut der Aufruf nichts. Wird derselbe Name erneut registriert, ersetzt das den Shop.
Beispiel
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
Öffnet einen mit RegisterShop registrierten Shop auf dem Bildschirm eines Spielers.
Seite: Server · Wartet: nein · Lib: inventory.openShop
OpenShop(source: number, name: string): booleanlocal opened = exports['ai-core']:OpenShop(source, 'police_armoury')Parameter
Prop
Type
Rückgabe
boolean: true, wenn sich der Shop geöffnet hat. false, wenn kein Shop diesen Namen hat, das aktive Inventar keine Skript-Shops hat, er sich nicht öffnen ließ oder kein Inventar läuft.
Beispiel
Siehe das Beispiel zu RegisterShop oben: einmal beim Start registrieren, dann nach deinen eigenen Job- und Entfernungsprüfungen öffnen.
Wie OpenInventory prüft dies weder Reichweite noch Zugriff. Prüfe sie zuerst.
RegisterUsableItem
Macht ein Item benutzbar: Wenn ein Spieler es im Inventar benutzt, läuft deine Funktion. ai-core verwahrt die Funktion, sodass sie mit Inventaren funktioniert, die später starten, und einen Neustart des Inventars übersteht.
Seite: Server · Wartet: nein · Lib: inventory.registerUsableItem
RegisterUsableItem(name: string, handler: UsableItemHandler): void
// UsableItemHandler = (source: number, item: UsedItem) => unknownexports['ai-core']:RegisterUsableItem('bandage', function(source, item) end)Parameter
Prop
Type
Siehe UsableItemHandler und UsedItem.
Rückgabe
Nichts. Ohne einen Text-name oder eine Funktion tut der Aufruf nichts. Ein zweiter Aufruf für dasselbe Item ersetzt den Handler.
Was nach der Benutzung mit dem Item passiert, hängt vom Inventar ab: Inventare, die ein benutztes Item selbst nehmen (ai-inventory nimmt die consume-Menge des Items), behalten es, wenn dein Handler false zurückgibt; andere Inventare folgen ihren eigenen Item-Einstellungen, also entferne das Item dort bei Bedarf selbst.
Beispiel
import { progressFor, resourceExport } from "@aicore-fivem/lib/server";
import { Locale } from "common";
const core = resourceExport("ai-core");
core.RegisterUsableItem("bandage", (source) => {
// Der Handler muss sofort antworten; der zeitgesteuerte Teil läuft für sich.
void (async () => {
if (!(await progressFor(source, { label: Locale("BANDAGING"), duration: 4000 }))) return;
if (!core.RemoveItem(source, "bandage")) return;
emitNet("myscript:client:heal", source, 25); // dein Client-Skript fügt die Gesundheit hinzu
})();
return false; // behalten: Es wird oben entfernt, sobald der Balken fertig ist
});Eine Benutzung löst außerdem das Server-Event ai-core:itemUsed (src, name, status) aus, dem Item-Effekte wie Hunger und Durst folgen. Siehe Events und Zustand.
GetItemDefinition
Ein Item, wie das aktive Inventar es definiert: Label, Gewicht, ob es stapelbar ist, Bild.
Seite: Server · Wartet: nein · Lib: inventory.getItemDefinition
GetItemDefinition(name: string): ItemDefinition | nulllocal def = exports['ai-core']:GetItemDefinition('water') -- Tabelle oder nilParameter
Prop
Type
Rückgabe
ItemDefinition | null: das Item mit name, label, weight, unique, close, description und image, wenn das Inventar eines hat. Siehe ItemDefinition. null für ein unbekanntes Item, einen leeren Namen oder wenn kein Inventar läuft.
Beispiel
import { notify, resourceExport } from "@aicore-fivem/lib/server";
import { Locale } from "common";
const core = resourceExport("ai-core");
/** „Du hast 2x Wasser erhalten“ mit dem eigenen Label des Inventars. */
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
Jedes Item, das das aktive Inventar definiert, nach Namen geordnet. Nutze es selten (eine Liste einmal aufbauen); für ein einzelnes Item nutze GetItemDefinition.
Seite: Server · Wartet: nein · Lib: keine
GetItemDefinitions(): Record<string, ItemDefinition>local items = exports['ai-core']:GetItemDefinitions() -- Tabelle mit Item-Namen als SchlüsselParameter
Keine.
Rückgabe
Record<string, ItemDefinition>: jedes Item. Eine leere Tabelle, solange kein Inventar läuft.
Beispiel
import { resourceExport } from "@aicore-fivem/lib/server";
const core = resourceExport("ai-core");
/** Warnt beim Start vor Items in deiner Config, die das Inventar nicht kennt. */
export function checkItems(names: string[]): void {
const known = core.GetItemDefinitions();
for (const name of names) if (!known[name]) console.log(`unknown item: ${name}`);
}Führe eine solche Prüfung aus, nachdem das Inventar gestartet ist: Direkt nach einem Serverstart läuft das Inventar eventuell noch nicht, und die Tabelle ist leer.
GetInventoryWeight
Was ein Spieler trägt und tragen kann, nach Gewicht.
Seite: Server · Wartet: nein · Lib: keine
GetInventoryWeight(source: number): { weight: number; maxWeight: number } | nulllocal w = exports['ai-core']:GetInventoryWeight(source) -- { weight, maxWeight } oder nilParameter
Prop
Type
Rückgabe
{ weight, maxWeight } | null: getragenes Gewicht und das Limit, in Gramm. null, wenn das aktive Inventar sie nicht mitteilt, der Spieler kein geladenes Inventar hat oder kein Inventar läuft.
Beispiel
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
Führt den für ein Item registrierten Handler aus, als hätte der Spieler es benutzt. Die ESX- / QB-Brücke von ai-core ruft es auf (aus ESX.UseItem und QBs CanUseItem); ein normales Skript hat keinen Grund dazu.
Seite: Server · Wartet: nein · Lib: keine (nur Brücke)
UseItem(source: number, name: string, item?: unknown): unknownlocal result = exports['ai-core']:UseItem(source, 'bandage', stack)Parameter
Prop
Type
Rückgabe
unknown: was der Handler zurückgegeben hat. false, wenn kein Handler registriert ist, die Argumente falsch sind oder der Handler einen Fehler geworfen hat (wird geloggt).
Beispiel
Kein Beispiel: Inventare und die Brücke rufen es auf. Um auf eine Benutzung zu reagieren, registriere das Item mit RegisterUsableItem.
IsUsableItem
Ob für ein Item ein Handler registriert ist. Die Brücke von ai-core nutzt es.
Seite: Server · Wartet: nein · Lib: keine (nur Brücke)
IsUsableItem(name: string): booleanlocal usable = exports['ai-core']:IsUsableItem('bandage')Parameter
Prop
Type
Rückgabe
boolean: true, wenn irgendeine Ressource das Item mit RegisterUsableItem registriert hat. Sonst false.
Beispiel
import { resourceExport } from "@aicore-fivem/lib/server";
const core = resourceExport("ai-core");
/** Item-Tooltips zeigen „Benutzen“ nur für benutzbare Items. */
export function canUse(item: string): boolean {
return core.IsUsableItem(item);
}