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
getPlayerData<K extends keyof AiPlayerData>(key: K): AiPlayerData[K] | undefinedlocal 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
onPlayerData<K extends keyof AiPlayerData>(key: K, handler: (value: AiPlayerData[K]) => void): () => voidaiLib.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 definitivamenteLos 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
seedPlayerData(data: Partial<AiPlayerData>): voidSin 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
hasJob(jobs: readonly string[], minGrade?: number): booleanSin 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
inGang(gangs: readonly string[], minGrade?: number): booleanSin 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
onDutyIn(jobs: readonly string[]): booleanSin 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
onMembershipChange(fn: () => void): voidSin 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
allows(rule: AccessRule): booleanSin 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
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());Cámara y temporización
ScriptCamera, TickLoop, AreaFollower y ServerClock - cámaras con script, tareas por frame que solo se ejecutan cuando hacen falta, informar al servidor del área del jugador y el reloj del servidor en el cliente.
Lib: servidor
@aicore-fivem/lib/server y el lado de servidor de aiLib: qué son, cómo cargarlos en TypeScript y Lua, y cada página temática.