AI Core
Referencia de la APILib: cliente

Pertenencia y datos del jugador

hasJob, inGang, onDutyIn, allows, onMembershipChange, getPlayerData, onPlayerData y seedPlayerData - el personaje, el dinero, los trabajos, el servicio y las bandas del jugador local tal como los envía ai-core.

ai-core envía los datos propios del jugador local a su cliente: un snapshot cuando se carga el personaje y después solo los valores que cambian. Estas utilidades leen esa copia, así que una comprobación cuesta una lectura en memoria y nunca pregunta al servidor.

Úsalas para lo que el jugador ve (el canShow de un punto, una entrada radial, una fila de menú). El servidor decide lo que el jugador puede hacer con los mismos datos (online en Jugadores y personajes): una comprobación en el cliente nunca es una prueba.

Datos del jugador

Los valores que guarda ai-core, por clave (AiPlayerData):

Prop

Type

Los tipos de los miembros son CharacterInfo, JobMembership y GangMembership.

getPlayerData

El último valor de una clave. En el primer uso en tu recurso también lee todo lo que ai-core ya envió (desde el export GetPlayerData de ai-core), así que un recurso reiniciado después de que el jugador cargara tiene los valores al momento.

Lado: Cliente · Espera: no

Firma
getPlayerData<K extends keyof AiPlayerData>(key: K): AiPlayerData[K] | undefined
Lua
local value = aiLib.playerData.get(key)

Parámetros

Prop

Type

Devuelve

AiPlayerData[K] | undefined: el valor, o undefined (nil en Lua) cuando aún no llegó nada (ningún personaje cargado, ai-core sin arrancar).

Ejemplo

import { getPlayerData, notify } from "@aicore-fivem/lib/client";

RegisterCommand(
  "whoami",
  () => {
    const character = getPlayerData("character");
    const job = getPlayerData("job");
    const cash = getPlayerData("money")?.cash ?? 0;
    if (!character) return notify("No character loaded", "error");
    notify(`${job?.job ?? "unemployed"} (${job?.grade ?? 0}), $${cash}`, "info");
  },
  false,
);

onPlayerData

Ejecuta un handler cada vez que ai-core envía una clave para este jugador.

Lado: Cliente · Espera: no

Firma
onPlayerData<K extends keyof AiPlayerData>(key: K, handler: (value: AiPlayerData[K]) => void): () => void
Lua
aiLib.playerData.onChange(key, function(value) end)

Parámetros

Prop

Type

Devuelve

TypeScript: () => void, una función que quita el handler. Lua no devuelve nada.

Ejemplo

import { onPlayerData } from "@aicore-fivem/lib/client";

const stop = onPlayerData("money", (money) => {
  SendNUIMessage({ action: "money", data: { cash: money.cash ?? 0, bank: money.bank ?? 0 } });
});
// stop() cuando el HUD se cierra definitivamente

Los valores enviados antes de que arrancara tu recurso no se reproducen en el handler. Lee el valor actual una vez con getPlayerData al arrancar y luego sigue los cambios con onPlayerData.

seedPlayerData

Rellena valores a mano. Las claves que ya tienen un valor se conservan. No lo necesitas: la lib se rellena sola desde ai-core en el primer uso.

Lado: Cliente · Espera: no

Firma
seedPlayerData(data: Partial<AiPlayerData>): void

Sin equivalente en Lua.

Parámetros

Prop

Type

Devuelve

void.

Ejemplo

import { seedPlayerData } from "@aicore-fivem/lib/client";

// Un entorno de pruebas sin ai-core.
seedPlayerData({ jobs: [{ job: "police", grade: 3 }], duty: "police" });

Comprobaciones de pertenencia

hasJob

Si el jugador tiene uno de los trabajos con un rango mínimo, esté de servicio o no.

Lado: Cliente · Espera: no

Firma
hasJob(jobs: readonly string[], minGrade?: number): boolean

Sin equivalente en Lua: recorre aiLib.playerData.get('jobs') (consulta el ejemplo Lua de points.add).

Parámetros

Prop

Type

Devuelve

boolean: true cuando la lista está vacía, o el jugador tiene uno de los jobs con minGrade o más.

Ejemplo

import { hasJob, onMembershipChange, Points } from "@aicore-fivem/lib/client";

const points = new Points();
points.add("armory", {
  coords: { x: 482.6, y: -995.2, z: 30.7 },
  label: "Armory",
  canShow: () => hasJob(["police", "sheriff"], 1),
  onPressed: () => emitNet("mypolice:armory"),
});
onMembershipChange(() => points.refresh());

inGang

Si el jugador está en una de las bandas con un rango mínimo.

Lado: Cliente · Espera: no

Firma
inGang(gangs: readonly string[], minGrade?: number): boolean

Sin equivalente en Lua: recorre aiLib.playerData.get('gangs').

Parámetros

Prop

Type

Devuelve

boolean: true cuando la lista está vacía, o el jugador está en una de las gangs con minGrade o más.

Ejemplo

import { inGang, radial } from "@aicore-fivem/lib/client";

radial.add({
  id: "mygang:stash",
  label: "Gang stash",
  icon: "box",
  canShow: () => inGang(["ballas", "vagos"], 2),
  onPressed: () => emitNet("mygang:stash"),
});

onDutyIn

Si el jugador está de servicio en uno de los trabajos.

Lado: Cliente · Espera: no

Firma
onDutyIn(jobs: readonly string[]): boolean

Sin equivalente en Lua: aiLib.playerData.get('duty') es el trabajo de servicio.

Parámetros

Prop

Type

Devuelve

boolean: true cuando el trabajo de servicio del jugador está en jobs.

Ejemplo

import { onDutyIn, Points } from "@aicore-fivem/lib/client";

const points = new Points();
points.addVehicle("mymech:repair", {
  label: "Repair",
  icon: "wrench",
  canShow: () => onDutyIn(["mechanic"]),
  onPressed: (vehicle) => emitNet("mymech:repair", NetworkGetNetworkIdFromEntity(vehicle)),
});

onMembershipChange

Ejecuta una función cuando cambian los trabajos, el servicio o las bandas del jugador. Úsalo para refrescar los puntos y blips cuyo canShow los lee.

Lado: Cliente · Espera: no

Firma
onMembershipChange(fn: () => void): void

Sin equivalente en Lua: aiLib.playerData.onChange para jobs, duty y gangs.

Parámetros

Prop

Type

Devuelve

void.

Ejemplo

import { onMembershipChange, Points, radial } from "@aicore-fivem/lib/client";

const points = new Points();
onMembershipChange(() => {
  points.refresh();
  radial.refresh();
});

allows

Si el jugador local puede usar un lugar con una regla de acceso. online.allows(source, rule) del servidor decide con la misma regla, así que lo que ve el jugador es exactamente lo que el servidor le deja usar. Lee la regla de un registro del panel con readAccess(record) (@aicore-fivem/lib/shared).

Lado: Cliente · Espera: no

Firma
allows(rule: AccessRule): boolean

Sin equivalente en Lua.

Parámetros

Prop

Type

AccessRule

Prop

Type

El tipo es AccessRule.

Devuelve

boolean: true cuando ambas listas están vacías (todos); cuando el jugador está en una de las gangs con su rango mínimo; o cuando el jugador tiene uno de los jobs con su rango mínimo (y está de servicio en él cuando onDuty). En caso contrario, false.

Ejemplo

resource/client/index.ts
import { AdminWorld, allows, callAction, onMembershipChange, Points } from "@aicore-fivem/lib/client";
import { readAccess, readVec3, RecordObjects, type AccessRule } from "@aicore-fivem/lib/shared";

const world = new AdminWorld(["stashes"]);
const points = new Points();

interface Stash { coords: { x: number; y: number; z: number }; access: AccessRule }
const readStash = (_key: string, raw: Record<string, unknown>): Stash | null => {
  const coords = readVec3(raw.coords);
  return coords ? { coords, access: readAccess(raw) } : null;
};

new RecordObjects(world, "stashes", readStash, (id, stash) => {
  points.add(id, {
    coords: stash.coords,
    label: "Stash",
    canShow: () => allows(stash.access),
    onPressed: () => callAction("mystash:open", [id], { fallback: "STASH_FAILED" }),
  });
  return () => points.remove(id);
});

onMembershipChange(() => points.refresh());

En esta página