AI Core
Grundlagenai-inventory

ai-inventory für Entwickler

Die Server- und Client-Exports von ai-inventory, benutzbare Items, Skript-Shops, das Event usedItem und die APIs von ox_inventory und qb-inventory, die es beantwortet.

Für Items in deinem eigenen Skript nutze den Inventar-Layer von AI Core: inventory der Lib (Server inventory.addItem, removeItem, getItemCount, hasItem, canCarryItem, registerUsableItem, registerStash, openInventory, registerShop...; Client inventory.hasItem, openInventory, currentWeapon) oder aiLib.inventory in Lua. Er funktioniert mit dem Inventar, das der Server gerade nutzt, sodass der Betreiber ai-inventory ersetzen kann. Siehe die Lib-Referenz. Die Exports unten sind für Sonderfälle und um nachzulesen, was ai-inventory selbst beantwortet.

Inventar-Referenzen

Jeder Server-Export, der inv nimmt, akzeptiert:

WertInventar
number (oder ein numerischer String)Das Inventar eines Spielers, per Server-ID. Der Spieler muss einen geladenen Charakter haben.
stringEin Lager per Name (der Schlüssel eines Panel-Lagers oder ein mit RegisterStash registrierter Name) oder der Kofferraum oder das Handschuhfach eines Fahrzeugs per Kennzeichen ("trunk:<plate>", "glovebox:<plate>" oder nur das Kennzeichen für den Kofferraum).
{ id: string, owner: string | number }Die Kopie eines persönlichen Lagers für einen Charakter.

Exports arbeiten mit Inventaren, die im Speicher sind: Spieler online, von Skripten registrierte Lager sowie Panel-Lager, Kofferräume und Handschuhfächer, die seit dem Neustart jemand geöffnet hat (sie werden nach 5 untätigen Minuten entladen). Für ein Inventar, das nicht geladen ist, antworten AddItem und RemoveItem mit false und GetItemCount mit 0.

Server-Exports

Typisiert als AiInventoryServerExports in @aicore-fivem/shared: resourceExport("ai-inventory") in TypeScript.

AddItem

Fügt einem Inventar Items hinzu. Stapel mit demselben Namen und denselben Metadaten werden bis zur Stapelgröße des Items zusammengeführt; der Rest kommt in freie Zellen.

Seite: Server · Wartet: nein

Signatur
AddItem(inv: number | string, item: string, count: number, metadata?: Record<string, unknown>, slot?: number): boolean
Lua
local ok = exports['ai-inventory']:AddItem(source, 'water', 2)

Parameter

Prop

Type

Rückgabewert

boolean: true, wenn jede Einheit hinzugefügt wurde. false, wenn das Inventar oder Item unbekannt ist, count nicht gültig ist oder es nicht passt (Zellen oder Gewicht). Bei false wird nichts hinzugefügt.

Beispiel

import { resourceExport, onClientCallback } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";

const inv = resourceExport("ai-inventory");

onClientCallback("myscript:buyWater", (source) => {
  if (!inv.CanCarryItem(source, "water", 1)) return fail("NO_SPACE");
  if (!inv.AddItem(source, "water", 1)) return fail("NO_SPACE");
  return { ok: true };
});

RemoveItem

Nimmt Items aus einem Inventar.

Seite: Server · Wartet: nein

Signatur
RemoveItem(inv: number | string, item: string, count: number, metadata?: Record<string, unknown>, slot?: number): boolean

Prop

Type

Rückgabewert

boolean: true, wenn jede Einheit genommen wurde. false, wenn nicht genug da sind (dann wird nichts genommen). Eine Waffe, die einem Spieler genommen wird, wird ihm auch aus den Händen genommen.

GetItemCount

Signatur
GetItemCount(inv: number | string, item: string, metadata?: Record<string, unknown>): number

Wie viele Einheiten von item (passend zu metadata, falls angegeben) das Inventar enthält. 0 für ein unbekanntes Inventar oder Item. Seite: Server · Wartet: nein.

CanCarryItem

Signatur
CanCarryItem(inv: number | string, item: string, count: number, metadata?: Record<string, unknown>): boolean

Ob count Einheiten passen würden (Zellen und Gewicht), ohne sie hinzuzufügen. Seite: Server · Wartet: nein.

GetItems

Signatur
GetItems(inv: number | string): Array<{ name, label, weight, slot, count, amount, metadata, info, stack, unique, close, description, type, image }>

Jeder Stapel des Inventars. count / metadata (Namen von ox) und amount / info (Namen von qb) enthalten dieselben Werte; weight ist die Summe des Stapels in Gramm. Eine leere Liste für ein unbekanntes Inventar. Seite: Server · Wartet: nein.

GetWeight

Signatur
GetWeight(inv: number | string): { weight: number; maxWeight: number } | null

Getragenes Gewicht und Limit in Gramm (maxWeight 0 = kein Limit). null, wenn das Inventar nicht geladen ist. Seite: Server · Wartet: nein.

RegisterUsableItem

Führt deine Funktion aus, wenn ein Spieler ein Item benutzt. Die Animation des Items (falls vorhanden) wird zuerst abgespielt; deine Funktion läuft, wenn sie beendet ist.

Seite: Server · Wartet: nein

Signatur
RegisterUsableItem(name: string, handler: (source: number, item: { name: string; slot: number; count: number; metadata: Record<string, unknown> }) => unknown): void

Prop

Type

Beispiel

import { resourceExport, notify } from "@aicore-fivem/lib/server";

const inv = resourceExport("ai-inventory");

inv.RegisterUsableItem("repairkit", (source, item) => {
  const ped = GetPlayerPed(String(source));
  const vehicle = GetVehiclePedIsIn(ped, false);
  if (vehicle === 0) {
    notify(source, "Sit in a vehicle first", "error");
    return false; // das Item behalten
  }
  emitNet("myscript:repair", source, NetworkGetNetworkIdFromEntity(vehicle));
});

Das Item muss im Panel Can be used eingeschaltet haben, damit Spieler es aus dem Bildschirm benutzen können, und Used up per use über 0, damit es verbraucht wird. Ein Handler pro Item-Name: erneutes Registrieren ersetzt ihn. Der Handler bleibt, nachdem deine Ressource stoppt; registriere ihn einmal beim Start.

RegisterStash

Registriert ein Lager aus einem Skript (ein Haus, ein Gang-Spind). Gemeinsame Lager werden sofort geladen und bleiben geladen.

Seite: Server · Wartet: nein

Signatur
RegisterStash(name: string, label: string, slots: number, maxWeight: number, jobs?: string[], personal?: boolean): void

Prop

Type

Ein Skript-Lager hat keinen Ort in der Welt: Öffne es mit OpenInventory.

OpenInventory

Öffnet ein Inventar auf dem Bildschirm eines Spielers, neben seinem eigenen.

Seite: Server · Wartet: nein

Signatur
OpenInventory(source: number, inv: number | string): boolean

Rückgabewert

boolean: true, wenn geöffnet. false, wenn der Spieler kein geladenes Inventar hat, das Inventar unbekannt oder nicht geladen ist oder es das eigene des Spielers ist.

Beispiel

import { resourceExport, onClientCallback } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";

const inv = resourceExport("ai-inventory");
inv.RegisterStash("gang_ballas", "Ballas locker", 60, 200_000);

onClientCallback("myscript:openLocker", (source) => {
  return inv.OpenInventory(source, "gang_ballas") ? { ok: true } : fail("CANNOT_OPEN");
});

Prüfe auf dem Server, ob der Spieler es öffnen darf (Gang, Entfernung), bevor du OpenInventory aufrufst: Der Export öffnet, was du verlangst.

ClearInventory

Signatur
ClearInventory(inv: number | string): void

Leert ein Inventar. Seite: Server · Wartet: nein.

RegisterShop and OpenShop

Ein Shop ohne Ort, von deinem Skript geöffnet (eine Telefon-App, ein NPC-Menü). Kaufen ist nur erlaubt, solange dieser Spieler ihn geöffnet hat, bezahlt mit Bargeld, dann Bank. Ein Panel-Shop mit derselben ID hat Vorrang.

Seite: Server · Wartet: nein

Signatur
RegisterShop(name: string, label: string, items: Array<{ name: string; price: number }>): void
OpenShop(source: number, name: string): boolean

Prop

Type

OpenShop gibt false zurück, wenn der Shop unbekannt ist oder der Spieler kein Inventar hat.

Items

Signatur
Items(name?: string): { name, label, weight, stack, unique, close, description, type, image, useable } | Record<string, ...> | null

Eine Item-Definition (Form von ox), alle Definitionen nach Name, wenn name weggelassen wird, oder null für einen unbekannten Namen. stack ist true, wenn die Stapelgröße über 1 liegt; unique, wenn sie 1 ist. Seite: Server · Wartet: nein.

Client-Exports

ExportRückgabeWas er macht
OpenSelf()nichtsÖffnet den eigenen Bildschirm des Spielers mit dem Boden, Kofferraum oder Handschuhfach in der Nähe (wie F2).
OpenInventory(type, data)nichtstype "stash" oder "shop" mit data als ID (oder { id }), "drop" mit einer Drop-ID; alles andere öffnet das eigene des Spielers. Der Server prüft den Zugriff trotzdem.
CloseInventory()nichtsSchließt den Bildschirm.
GetItemCount(item: string)numberWie viele der Spieler trägt.
HasItem(items, amount?)booleanitems ist ein Name, eine Liste (jedes mindestens amount, Standard 1) oder { name: count }.
GetPlayerItems()arrayDie Stapel des Spielers (name, label, slot, count, amount, metadata, info, weight, stack, close, description).

OpenSelf und HasItem sind als AiInventoryClientExports typisiert.

Events

ai-inventory:usedItem

Wird auf dem Server nach jeder Benutzung eines Items ausgelöst.

Seite: Server (lokales Event)

ArgumentTypWas es ist
sourcenumberDer Spieler.
namestringDer Item-Name.
slotnumberDie Zelle, in der der Stapel lag.
metadataRecord<string, unknown>Die Metadaten des Stapels.
status{ hunger?, thirst?, stress? }Die Bedürfniswerte des Items aus dem Panel.
on("ai-inventory:usedItem", (source: number, name: string) => {
  if (name === "joint") emitNet("myscript:highEffect", source);
});

AI Core macht daraus sein eigenes Event ai-core:itemUsed (source, name, status); auf dieses solltest du hören, wenn dein Skript mit jedem Inventar funktionieren soll.

API von ox_inventory

ai-inventory providet ox_inventory und beantwortet seine Exports (geschrieben gegen ox_inventory 2.44). Inventare werden wie in ox benannt: eine Spieler-Source, ein Lagername, { id, owner } für persönliche Lager, ein Kennzeichen für Kofferräume.

  • Server: AddItem (gibt success, response zurück, ruft cb auf), RemoveItem, GetItem, GetItemCount, Search (count / slots), CanCarryItem, CanCarryWeight, CanCarryAmount, GetInventory, GetInventoryItems, GetSlot, GetSlotWithItem, GetSlotsWithItem, GetSlotIdWithItem, GetSlotIdsWithItem, GetEmptySlot, SetMetadata, SetDurability, SetMaxWeight, RegisterStash, ClearInventory, Items, ItemList, forceOpenInventory (Lager, Spieler, Shop), CreateTemporaryStash, CustomDrop, RemoveInventory, SwapSlots.
  • Client: openInventory, closeInventory, Search, GetItemCount, GetPlayerItems, GetPlayerWeight, GetPlayerMaxWeight, Items, useSlot, getCurrentWeapon / GetCurrentWeapon. displayMetadata, weaponWheel und setStashTarget werden angenommen und tun nichts.
  • Nicht beantwortet: Hooks (registerHook, removeHooks), UpdateVehicle, ConfiscateInventory / ReturnInventory, GetContainerFromSlot, RegisterShop (Shops kommen aus dem Panel oder aus dem eigenen RegisterShop von ai-inventory).

API von qb-inventory

ai-inventory providet qb-inventory (API 2.0). Zurückgegebene Items tragen beide Formen: count / metadata und amount / info.

  • Server: AddItem(identifier, item, amount, slot, info), RemoveItem, HasItem (ein Name, eine Liste oder { name = amount }), GetItemCount, GetItemByName, GetItemsByName, GetItemBySlot, CanAddItem, GetFreeWeight, GetSlots, ClearInventory, SetItemData, CreateInventory, OpenInventory, OpenInventoryById, RemoveInventory, CloseInventory.
  • Client: HasItem, CloseInventory.
  • Nicht beantwortet: Hooks und Listener, CreateShop / OpenShop, SetInventory, GetInventory, SaveInventory, LoadInventory, UseItem, GetFirstSlotByItem, GetSlotsByItem, GetTotalWeight.

Datenbank und Logs

Tabelle ai_inventory_inventories: eine Zeile pro gespeichertem Inventar (id, items-JSON). Nur ai-inventory schreibt sie; Änderungen werden alle 30 Sekunden, beim Entladen und beim Stoppen gespeichert. Log-Kanäle: moves (standardmäßig aus), drops, gives, purchases, crafting.

Auf dieser Seite