State bags
Les valeurs d’état partagées que publient ai-core et les scripts ai-* - bags de joueur, bags de véhicule et clés GlobalState - ce que contient chacune, qui l’écrit, et comment la lire et la suivre.
Un state bag est une valeur que FiveM garde synchronisée pour tout le monde : sur GlobalState (une valeur pour tout le serveur), sur un joueur ou sur une entité (un véhicule). Chaque ressource de chaque côté peut la lire, et elle suit les changements sans aucun événement de votre part. ai-core et les scripts ai-* les utilisent pour l’état dont tout le monde a besoin, jamais pour des données privées.
Lecture seule. Chaque clé ci-dessous a une ressource propriétaire, la seule à l’écrire, toujours depuis le serveur. N’écrivez jamais ces clés vous-même, ni depuis le serveur ni depuis le client : le propriétaire écraserait votre valeur, et les autres scripts verraient un état faux. Pour changer l’état, appelez l’export du propriétaire (par exemple la réanimation d’ai-death, l’export de service d’ai-core).
Comment les lire
La lib a une classe par sorte. Chacune garde une copie locale, si bien que get ne coûte rien, et onChange exécute votre écouteur après un changement.
| Sorte | TypeScript (lib) | Lua |
|---|---|---|
| Une clé GlobalState | new GlobalKey(key, parse) : .get(), .onChange((_, value, old) => ...) | GlobalState[key], AddStateBagChangeHandler(key, 'global', fn) |
| Plusieurs clés GlobalState avec un même préfixe | new GlobalGroup(prefix, parse) : .get(id), .ids(), .onChange((id, value, old) => ...) | GlobalState[prefix .. id] |
| Le bag d’un joueur | new PlayerState(key, parse) : .get(serverId), .onChange((serverId, value, old) => ...) | Player(serverId).state[key], LocalPlayer.state[key] sur le client |
| Le bag d’une entité | new EntityState(key, parse) : .get(entity), .getByNetId(netId), .onChange((netId, value, old) => ...) | Entity(entity).state[key] |
parse vérifie la valeur brute : stateNumber, stateBoolean, stateString de la lib, ou votre propre fonction qui renvoie undefined pour une valeur invalide. Ils viennent tous de @aicore-fivem/lib/client ou @aicore-fivem/lib/server.
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");
});Bags de joueur (PLAYER_BAGS)
Clés que plusieurs ressources lisent sur un joueur. Constante : PLAYER_BAGS dans @aicore-fivem/shared.
| Clé | Constante | Propriétaire | Valeur |
|---|---|---|---|
dead | PLAYER_BAGS.dead | ai-death | true tant que le joueur est à terre. Absente ou false sinon. Avec un autre script de mort, utilisez plutôt la couche médicale (export IsDead, medical de la lib) : les autres scripts de mort utilisent leurs propres clés. |
cuffed | PLAYER_BAGS.cuffed | ai-police | true tant que le joueur est menotté. |
proximity | PLAYER_BAGS.proximity | ai-voice | La portée de la voix, au format de pma-voice : { index, distance, mode }. |
Bags de véhicule (VEHICLE_BAGS)
Clés sur les entités de véhicule. Constante : VEHICLE_BAGS dans @aicore-fivem/shared.
| Clé | Constante | Propriétaire | Valeur |
|---|---|---|---|
ai:owned | VEHICLE_BAGS.owned | ai-vehicles | true sur un véhicule possédé apparu. |
ai:vid | VEHICLE_BAGS.id | ai-vehicles | L’id du véhicule dans ai-vehicles (number). |
ai:props | VEHICLE_BAGS.props | ai-vehicles | L’apparence et le tuning du véhicule (VehicleProps). ai-core l’applique sur le client propriétaire de l’entité. |
ai:setup | VEHICLE_BAGS.setup | ai-vehicles | Une configuration d’apparition (VehicleSetup, par exemple une couleur choisie dans un magasin). ai-core l’applique une fois sur le client propriétaire. |
fuel | VEHICLE_BAGS.fuel | le script de carburant (ai-fuel ; ai-core la tient pour les scripts de carburant côté client) | Niveau de carburant, 0-100. |
Pour lire le carburant, utilisez la couche fuel de la lib : elle fonctionne avec n’importe quel script de carburant, y compris ceux qui n’écrivent pas eux-mêmes le bag fuel.
Clés GlobalState d’ai-core
| Clé | Constante | Valeur |
|---|---|---|
ai:duty:<job> | dutyCountKey(job) (préfixe DUTY_COUNT_PREFIX) | Combien de joueurs sont en service dans ce métier (number). Seulement le nombre, jamais qui. |
ai:interaction | CORE.interactionStateKey | "prompt" ou "target" : comment les Points de la lib laissent les joueurs interagir (réglage du panneau d’ai-core). |
ai:pvp | CORE.pvpStateKey | true quand les joueurs peuvent se blesser entre eux (réglage pvp du panneau, commande /togglepvp). |
ai:inventory | INVENTORY_STATE_KEY | Nom de ressource de l’inventaire derrière la couche d’inventaire d’ai-core. Non définie tant qu’aucun ne tourne. |
ai:vehicleKeys | VEHICLE_KEYS_STATE_KEY | Nom de ressource du script de clés de véhicule actif. Non définie tant qu’aucun ne tourne. |
ai:appearance | APPEARANCE_STATE_KEY | Nom de ressource du script de vêtements actif. Non définie tant qu’aucun ne tourne. |
ai:medical | CORE.medicalStateKey | Nom de ressource du script de mort actif. |
ai:mdt | CORE.mdtStateKey | Nom de ressource du MDT actif. |
ai:notify | CORE.notifyStateKey | Nom de ressource de l’interface de notifications vers laquelle vont les cartes d’ai-lib. Non définie : ai-lib dessine ses propres cartes. |
ai:fuel | FUEL_STATE_KEY | Nom de ressource du script de carburant actif. Non définie tant qu’aucun ne tourne. |
ai:garages | GARAGES_STATE_KEY | Nom de ressource du script de garages actif. Non définie tant qu’aucun ne tourne. |
Les clés de nom de ressource indiquent aux moitiés client d’ai-core à quel script parler. Lisez-les quand vous devez savoir quel script tourne (pour une ligne de log, une indication au joueur), pas pour appeler ce script directement : appelez plutôt la couche d’ai-core.
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"));Clés des autres scripts ai-*
L’état partagé que publient certains scripts ai-*, pour les scripts qui travaillent avec eux. La page développeur de chaque script donne les détails.
| Clé | Où | Propriétaire | Valeur |
|---|---|---|---|
door:<id> | GlobalState | ai-doorlock | true tant que la porte est verrouillée. |
ai:clock | GlobalState | ai-weathersync | { base, at, scale, frozen } : minutes de jeu de la journée à l’heure serveur at (ms), avançant de scale minutes de jeu par minute réelle. Les clients font tourner l’horloge eux-mêmes à partir de là. |
ai:weather | GlobalState | ai-weathersync | { type, blackout } : la météo actuelle. |
ai:rweather:<id> | GlobalState | ai-weathersync | La météo actuelle d’une région météo. |
prop:<id> | GlobalState | ai-properties | true quand la propriété a un propriétaire. |
rob:<id> | GlobalState | ai-robberies | true tant qu’une cible de braquage est vidée et attend la fin de son délai. |
siren:lx | Véhicule | ai-sirens | Tonalité principale de la sirène : 0 coupée, 1-3 une tonalité. |
siren:manu | Véhicule | ai-sirens | Klaxon pneumatique / sirène manuelle : 0 coupé, 1 klaxon, 2 manuelle, 3 les deux. |
siren:lightbar | Véhicule | ai-sirens | Le modèle de rampe lumineuse attaché au véhicule ; absent s’il n’y en a pas. |
Événements UI d’ai-lib
Les événements client que déclenche ai-lib quand un joueur répond à un menu, une boîte de saisie, un sélecteur d’objets, un mini-jeu ou une invite, ou annule une barre de progression - pour les scripts qui appellent eux-mêmes les exports d’ai-lib.
Événements du pont de framework
Les événements ESX, QB / Qbox et vRP que déclenche ai-core pour que les scripts écrits pour ces frameworks continuent de fonctionner, avec leurs arguments exacts, et les événements de framework auxquels ai-core répond.