AI Core
API-ReferenzAI Core: Server-Exports

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 InventoryRef benannt: 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 oder null.
  • 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

Signature
AddItem(inv: InventoryRef, item: string, count?: number, metadata?: ItemMetadata, slot?: number): boolean
Lua
local 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

Signature
RemoveItem(inv: InventoryRef, item: string, count?: number, metadata?: ItemMetadata, slot?: number): boolean
Lua
local 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

Signature
GetItemCount(inv: InventoryRef, item: string, metadata?: ItemMetadata): number
Lua
local 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

Signature
HasItem(inv: InventoryRef, item: string, count?: number): boolean
Lua
local 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

Signature
CanCarryItem(inv: InventoryRef, item: string, count?: number, metadata?: ItemMetadata): boolean
Lua
local 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

Signature
GetItems(inv: InventoryRef): InventoryStack[]
Lua
local stacks = exports['ai-core']:GetItems(source) -- Liste von Tabellen

Parameter

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

Signature
ClearInventory(inv: InventoryRef): void
Lua
exports['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

Signature
RegisterStash(name: string, label: string, slots: number, maxWeight: number, jobs?: string[]): void
Lua
exports['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

Signature
OpenInventory(source: number, inv: InventoryRef): boolean
Lua
local 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

Signature
RegisterShop(name: string, label: string, items: ShopProduct[]): void
Lua
exports['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

Signature
OpenShop(source: number, name: string): boolean
Lua
local 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

Signature
RegisterUsableItem(name: string, handler: UsableItemHandler): void
// UsableItemHandler = (source: number, item: UsedItem) => unknown
Lua
exports['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

Signature
GetItemDefinition(name: string): ItemDefinition | null
Lua
local def = exports['ai-core']:GetItemDefinition('water') -- Tabelle oder nil

Parameter

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

Signature
GetItemDefinitions(): Record<string, ItemDefinition>
Lua
local items = exports['ai-core']:GetItemDefinitions() -- Tabelle mit Item-Namen als Schlüssel

Parameter

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

Signature
GetInventoryWeight(source: number): { weight: number; maxWeight: number } | null
Lua
local w = exports['ai-core']:GetInventoryWeight(source) -- { weight, maxWeight } oder nil

Parameter

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)

Signature
UseItem(source: number, name: string, item?: unknown): unknown
Lua
local 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)

Signature
IsUsableItem(name: string): boolean
Lua
local 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);
}

Auf dieser Seite