AI Core
API-ReferenzEvents und Zustand

State Bags

Die gemeinsamen Zustandswerte, die ai-core und die ai-*-Skripte veröffentlichen - Spieler-Bags, Fahrzeug-Bags und GlobalState-Schlüssel - was jeder enthält, wer ihn schreibt und wie du ihn liest und ihm folgst.

Eine State Bag ist ein Wert, den FiveM für alle synchron hält: auf GlobalState (ein Wert für den ganzen Server), auf einem Spieler oder auf einer Entity (einem Fahrzeug). Jede Ressource auf jeder Seite kann ihn lesen, und er folgt Änderungen ohne ein eigenes Event. ai-core und die ai-*-Skripte nutzen sie für Zustand, den alle brauchen, nie für private Daten.

Nur lesen. Jeder Schlüssel unten hat eine Besitzer-Ressource, die als einzige ihn schreibt, immer vom Server aus. Schreibe diese Schlüssel nie selbst, weder vom Server noch vom Client: Der Besitzer würde dich überschreiben, und andere Skripte würden falschen Zustand sehen. Um den Zustand zu ändern, rufe den Export des Besitzers auf (zum Beispiel die Wiederbelebung von ai-death, den Dienst-Export von ai-core).

Wie du sie liest

Die Lib hat eine Klasse pro Art. Jede hält eine lokale Kopie, sodass get nichts kostet, und onChange führt deinen Listener nach einer Änderung aus.

ArtTypeScript (Lib)Lua
Ein GlobalState-Schlüsselnew GlobalKey(key, parse): .get(), .onChange((_, value, old) => ...)GlobalState[key], AddStateBagChangeHandler(key, 'global', fn)
Viele GlobalState-Schlüssel mit einem Präfixnew GlobalGroup(prefix, parse): .get(id), .ids(), .onChange((id, value, old) => ...)GlobalState[prefix .. id]
Die Bag eines Spielersnew PlayerState(key, parse): .get(serverId), .onChange((serverId, value, old) => ...)Player(serverId).state[key], LocalPlayer.state[key] auf dem Client
Die Bag einer Entitynew EntityState(key, parse): .get(entity), .getByNetId(netId), .onChange((netId, value, old) => ...)Entity(entity).state[key]

parse prüft den Rohwert: stateNumber, stateBoolean, stateString aus der Lib oder deine eigene Funktion, die für einen schlechten Wert undefined zurückgibt. Alle kommen aus @aicore-fivem/lib/client oder @aicore-fivem/lib/server.

resource/client/index.ts
import { cache, GlobalKey, PlayerState, stateBoolean, stateNumber } from "@aicore-fivem/lib/client";
import { dutyCountKey, PLAYER_BAGS } from "@aicore-fivem/shared";

const policeOnDuty = new GlobalKey(dutyCountKey("police"), stateNumber);
const cuffed = new PlayerState(PLAYER_BAGS.cuffed, stateBoolean);

console.log(`police on duty: ${policeOnDuty.get() ?? 0}`);
policeOnDuty.onChange((_, count) => console.log(`police on duty now: ${count ?? 0}`));

cuffed.onChange((serverId, value) => {
  if (serverId === cache.serverId) console.log(value ? "you are cuffed" : "you are free");
});

Spieler-Bags (PLAYER_BAGS)

Schlüssel, die mehrere Ressourcen auf einem Spieler lesen. Konstante: PLAYER_BAGS in @aicore-fivem/shared.

SchlüsselKonstanteBesitzerWert
deadPLAYER_BAGS.deadai-deathtrue, solange der Spieler am Boden ist. Sonst fehlend oder false. Mit einem anderen Tod-Skript nutze stattdessen die Medizin-Ebene (Export IsDead, Lib medical): Andere Tod-Skripte nutzen eigene Schlüssel.
cuffedPLAYER_BAGS.cuffedai-policetrue, solange der Spieler gefesselt ist.
proximityPLAYER_BAGS.proximityai-voiceDie Sprachreichweite in der Form von pma-voice: { index, distance, mode }.

Fahrzeug-Bags (VEHICLE_BAGS)

Schlüssel auf Fahrzeug-Entities. Konstante: VEHICLE_BAGS in @aicore-fivem/shared.

SchlüsselKonstanteBesitzerWert
ai:ownedVEHICLE_BAGS.ownedai-vehiclestrue auf einem gespawnten Fahrzeug mit Besitzer.
ai:vidVEHICLE_BAGS.idai-vehiclesDie ID des Fahrzeugs in ai-vehicles (Zahl).
ai:propsVEHICLE_BAGS.propsai-vehiclesAussehen und Tuning des Fahrzeugs (VehicleProps). ai-core wendet es auf dem Client an, dem die Entity gehört.
ai:setupVEHICLE_BAGS.setupai-vehiclesEin Spawn-Setup (VehicleSetup, zum Beispiel eine in einem Shop gewählte Farbe). ai-core wendet es einmal auf dem Besitzer-Client an.
fuelVEHICLE_BAGS.fueldas Tank-Skript (ai-fuel; ai-core führt es für clientseitige Tank-Skripte)Tankstand, 0-100.

Um den Tankstand zu lesen, nutze die fuel-Ebene der Lib: Sie funktioniert mit jedem Tank-Skript, auch mit denen, die die Bag fuel nicht selbst schreiben.

GlobalState-Schlüssel von ai-core

SchlüsselKonstanteWert
ai:duty:<job>dutyCountKey(job) (Präfix DUTY_COUNT_PREFIX)Wie viele Spieler in diesem Job im Dienst sind (Zahl). Nur Anzahlen, nie wer.
ai:interactionCORE.interactionStateKey"prompt" oder "target": wie Points der Lib Spieler interagieren lassen (Panel-Einstellung von ai-core).
ai:pvpCORE.pvpStateKeytrue, wenn Spieler einander verletzen können (Panel-Einstellung pvp, Befehl /togglepvp).
ai:inventoryINVENTORY_STATE_KEYRessourcenname des Inventars hinter der Inventar-Ebene von ai-core. Nicht gesetzt, solange keines läuft.
ai:vehicleKeysVEHICLE_KEYS_STATE_KEYRessourcenname des aktiven Fahrzeugschlüssel-Skripts. Nicht gesetzt, solange keines läuft.
ai:appearanceAPPEARANCE_STATE_KEYRessourcenname des aktiven Kleidungs-Skripts. Nicht gesetzt, solange keines läuft.
ai:medicalCORE.medicalStateKeyRessourcenname des aktiven Tod-Skripts.
ai:mdtCORE.mdtStateKeyRessourcenname des aktiven MDT.
ai:notifyCORE.notifyStateKeyRessourcenname der Benachrichtigungs-UI, an die die Karten von ai-lib gehen. Nicht gesetzt: ai-lib zeichnet seine eigenen Karten.
ai:fuelFUEL_STATE_KEYRessourcenname des aktiven Tank-Skripts. Nicht gesetzt, solange keines läuft.
ai:garagesGARAGES_STATE_KEYRessourcenname des aktiven Garagen-Skripts. Nicht gesetzt, solange keines läuft.

Die Schlüssel mit Ressourcennamen sagen den Client-Hälften von ai-core, mit welchem Skript sie sprechen sollen. Lies sie, wenn du wissen musst, welches Skript läuft (für eine Log-Zeile, einen Hinweis an den Spieler), nicht um dieses Skript direkt aufzurufen: Rufe stattdessen die Ebene von ai-core auf.

resource/server/index.ts
import { GlobalKey, stateBoolean } from "@aicore-fivem/lib/server";
import { CORE } from "@aicore-fivem/shared";

const pvp = new GlobalKey(CORE.pvpStateKey, stateBoolean);

pvp.onChange((_, on) => console.log(on ? "PvP is on" : "PvP is off"));

Schlüssel anderer ai-*-Skripte

Gemeinsamer Zustand, den einige ai-*-Skripte veröffentlichen, für Skripte, die mit ihnen arbeiten. Die Developer-Seite jedes Skripts hat die Details.

SchlüsselWoBesitzerWert
door:<id>GlobalStateai-doorlocktrue, solange die Tür abgeschlossen ist.
ai:clockGlobalStateai-weathersync{ base, at, scale, frozen }: Spielminuten des Tages zur Serverzeit at (ms), die pro echter Minute um scale Spielminuten voranschreiten. Clients lassen die Uhr daraus selbst laufen.
ai:weatherGlobalStateai-weathersync{ type, blackout }: das aktuelle Wetter.
ai:rweather:<id>GlobalStateai-weathersyncDas aktuelle Wetter einer Wetterregion.
prop:<id>GlobalStateai-propertiestrue, wenn die Immobilie einen Besitzer hat.
rob:<id>GlobalStateai-robberiestrue, solange ein Überfallziel geleert ist und auf seinen Cooldown wartet.
siren:lxFahrzeugai-sirensHauptsirenenton: 0 aus, 1-3 ein Ton.
siren:manuFahrzeugai-sirensDrucklufthorn / manuelle Sirene: 0 aus, 1 Horn, 2 manuell, 3 beides.
siren:lightbarFahrzeugai-sirensDas am Fahrzeug befestigte Lichtbalken-Modell; fehlt, wenn keines.

Auf dieser Seite