AI Core
Referência da APIAI Core: exports de servidor

Empregos e gangues

Leia e altere os empregos, gangues, cargos e serviço de um personagem, conte jogadores em serviço, horário nobre, leia definições de empregos e gangues.

Um personagem pode ter vários empregos e várias gangues (até Most jobs per character e Most gangs per character do painel). No máximo um emprego fica em serviço de cada vez, e só esse emprego paga salário. No máximo uma gangue fica ativa. Empregos e gangues, com seus cargos, são definidos no painel de administração (seções Jobs e Gangs).

Um cargo é uma posição na lista de cargos do emprego, contada a partir de 0: o cargo 0 é a primeira linha no painel, o cargo 1 a segunda, e assim por diante.

Cada mudança dispara um evento de servidor (ai-core:jobsChanged, ai-core:dutyChanged, ai-core:gangsChanged, ai-core:activeGangChanged) e chega ao próprio jogo do jogador. Recursos que precisam dos empregos de muitos jogadores seguem esses eventos pelo espelho online da lib em vez de chamar os exports abaixo para cada jogador. Veja Eventos e estado.

GetJobs

Cada vínculo de emprego do personagem de um jogador.

Lado: Servidor · Espera: não · Lib: online.jobs(source) lê o mesmo do espelho da lib

Assinatura
GetJobs(src: number): JobMembership[] | null
Lua
local jobs = exports['ai-core']:GetJobs(source) -- lista de { job, grade } ou nil

Parâmetros

Prop

Type

Retorno

JobMembership[] | null: um { job, grade } por emprego (JobMembership). Uma lista vazia quando o personagem não tem emprego (o emprego de desempregado do painel nunca é gravado). null quando o jogador não tem personagem carregado.

Exemplo

import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";

const core = resourceExport("ai-core");

// A tela de uma agência de empregos lista os empregos do jogador com seus rótulos.
onClientCallback("myscript:myJobs", (source) => {
  const jobs = core.GetJobs(source);
  if (!jobs) return fail("NO_CHARACTER");
  return {
    ok: true,
    jobs: jobs.map(({ job, grade }) => ({
      job,
      label: core.GetJobDefinition(job)?.label ?? job,
      grade,
    })),
  };
});

GetCurrentJob

O único emprego que os outros scripts devem tratar como "o" emprego do jogador: o emprego em serviço, senão o último emprego em que o jogador esteve em serviço, senão o primeiro emprego, senão o emprego de desempregado do painel. Os scripts de ESX e QB veem este emprego pela ponte.

Lado: Servidor · Espera: não · Lib: nenhuma

Assinatura
GetCurrentJob(src: number): JobMembership | null
Lua
local job = exports['ai-core']:GetCurrentJob(source) -- { job, grade } ou nil

Parâmetros

Prop

Type

Retorno

JobMembership | null: { job, grade }. Para um personagem sem nenhum emprego é o emprego de desempregado (configuração do painel, unemployed por padrão) com cargo 0. null só quando o jogador não tem personagem carregado.

Exemplo

import { addCommand, resourceExport } from "@aicore-fivem/lib/server";

const core = resourceExport("ai-core");

addCommand("job", { help: "Shows a player job", params: [{ name: "id", type: "playerId" }], restricted: true }, (_source, args) => {
  const job = core.GetCurrentJob(args.id);
  if (job) console.log(`${job.job} grade ${job.grade}`);
});

GetDutyJob

O emprego em que o jogador está em serviço agora. Use para toda verificação do tipo "só a polícia em serviço pode fazer isto".

Lado: Servidor · Espera: não · Lib: online.dutyJob(source) lê o mesmo do espelho da lib

Assinatura
GetDutyJob(src: number): string | null
Lua
local job = exports['ai-core']:GetDutyJob(source) -- nome do emprego ou nil

Parâmetros

Prop

Type

Retorno

string | null: o nome do emprego. null quando o jogador está fora de serviço ou não tem personagem carregado.

Exemplo

import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";

const core = resourceExport("ai-core");

onClientCallback("myscript:openArmory", (source) => {
  if (core.GetDutyJob(source) !== "police") return fail("NOT_POLICE");
  return { ok: true };
});

SetDuty

Coloca um jogador em serviço num dos empregos dele (e fora de serviço em qualquer outro), ou fora de serviço.

Lado: Servidor · Espera: não · Lib: nenhuma

Assinatura
SetDuty(src: number, job: string | null): boolean
Lua
local ok = exports['ai-core']:SetDuty(source, 'police') -- nil = fora de serviço

Parâmetros

Prop

Type

Retorno

boolean: true quando o jogador agora está em serviço em job (ou fora de serviço para null), também quando nada precisou mudar. false quando o jogador não tem job ou não tem personagem carregado.

Exemplo

import { onClientCallback, resourceExport, near } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";

const core = resourceExport("ai-core");
const LOCKER_ROOM = { x: 452.3, y: -993.2, z: 30.7 };

// Um interruptor de serviço no vestiário da delegacia.
onClientCallback("myscript:toggleDuty", { guards: [near(LOCKER_ROOM, 3)] }, (source) => {
  const onDuty = core.GetDutyJob(source) === "police";
  return core.SetDuty(source, onDuty ? null : "police") ? { ok: true, onDuty: !onDuty } : fail("NOT_POLICE");
});

O serviço não é salvo: um jogador que entra fica fora de serviço, a menos que a configuração Keep duty after rejoining do painel esteja ligada.

SetJob

Dá um emprego a um jogador, ou muda o cargo de um emprego que ele já tem.

Lado: Servidor · Espera: não · Lib: nenhuma

Assinatura
SetJob(src: number, job: string, grade: number): boolean
Lua
local ok = exports['ai-core']:SetJob(source, 'mechanic', 0)

Parâmetros

Prop

Type

Retorno

boolean: true quando o personagem agora tem job no cargo grade. false quando o emprego não existe, o cargo não existe (não é um número inteiro, está abaixo de 0 ou passa do último cargo), o personagem já tem tantos empregos quanto Most jobs per character permite ou o jogador não tem personagem carregado.

Quando a configuração Several jobs per character do painel está desligada, um novo emprego substitui o outro emprego do personagem.

Exemplo

import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
import { fail, readText } from "@aicore-fivem/lib/shared";

const core = resourceExport("ai-core");

// Uma agência de empregos: qualquer um pode pegar um emprego que o painel lista, no cargo 0.
onClientCallback(
  "myscript:takeJob",
  { args: ([job]) => { const name = readText(job, 32); return name ? [name] : null; } },
  (source, job) => {
    if (!core.GetJobDefinition(job)?.listed) return fail("JOB_NOT_LISTED");
    return core.SetJob(source, job, 0) ? { ok: true } : fail("JOB_LIMIT");
  },
);

RemoveJob

Tira um emprego de um jogador. Um jogador em serviço nesse emprego sai de serviço antes.

Lado: Servidor · Espera: não · Lib: nenhuma

Assinatura
RemoveJob(src: number, job: string): boolean
Lua
local ok = exports['ai-core']:RemoveJob(source, 'mechanic')

Parâmetros

Prop

Type

Retorno

boolean: true quando o emprego foi removido. false quando o personagem não o tem ou o jogador não tem personagem carregado.

Exemplo

import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
import { fail, readText } from "@aicore-fivem/lib/shared";

const core = resourceExport("ai-core");

onClientCallback(
  "myscript:quitJob",
  { args: ([job]) => { const name = readText(job, 32); return name ? [name] : null; } },
  (source, job) => (core.RemoveJob(source, job) ? { ok: true } : fail("NOT_MEMBER")),
);

GetOnDutyCount

Quantos jogadores estão em serviço num emprego agora. Use para regras do tipo "precisa de 2 policiais online".

Lado: Servidor · Espera: não · Lib: nenhuma (online.countOnDuty(jobs) conta vários empregos a partir do espelho da lib)

Assinatura
GetOnDutyCount(job: string): number
Lua
local officers = exports['ai-core']:GetOnDutyCount('police')

Parâmetros

Prop

Type

Retorno

number: jogadores em serviço em job. 0 para ninguém ou um emprego desconhecido. O mesmo número fica no GlobalState ai:duty:<job> para scripts de cliente.

Exemplo

import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";

const core = resourceExport("ai-core");
const POLICE_NEEDED = 2;

onClientCallback("myscript:startRobbery", { lock: true }, (source) => {
  if (core.GetOnDutyCount("police") < POLICE_NEEDED) return fail("NOT_ENOUGH_POLICE");
  // ... inicia o assalto
  return { ok: true };
});

IsPrimeTime

Se agora é horário nobre para um emprego. As horas do horário nobre vêm da fonte que o painel escolhe: um script que mantém as próprias horas (tgiann-policealert) enquanto ele roda, senão as horas próprias do ai-core (a janela do próprio emprego ou a padrão). Use para regras que mudam com as horas de movimento, como um assalto que paga mais.

Lado: Servidor · Espera: não · Lib: isPrimeTime(job?)

Assinatura
IsPrimeTime(job?: string): boolean
Lua
local prime = exports['ai-core']:IsPrimeTime('police')

Parâmetros

Prop

Type

Retorno

boolean: true durante o horário nobre. As horas são o horário local do servidor; uma janela cujo início é depois do fim passa da meia-noite, e o mesmo início e fim significa o dia inteiro. Quando o painel escolhe um script como fonte e esse script está parado, toda hora conta como horário nobre. Funciona esteja ou não ligado o corte do salário no horário nobre.

Exemplo

import { resourceExport } from "@aicore-fivem/lib/server";

const core = resourceExport("ai-core");

/** A store robbery pays 50% more outside police prime time. */
export function robberyReward(base: number): number {
  return core.IsPrimeTime("police") ? base : Math.round(base * 1.5);
}

GetJobDefinitions

Cada definição de emprego do painel, como uma cópia. Use para leituras raras, como montar uma lista uma vez; para um emprego use GetJobDefinition.

Lado: Servidor · Espera: não · Lib: nenhuma

Assinatura
GetJobDefinitions(): Record<string, JobDefinition>
Lua
local jobs = exports['ai-core']:GetJobDefinitions() -- table indexada pelo nome do emprego

Parâmetros

Nenhum.

Retorno

Record<string, JobDefinition>: cada emprego indexado pelo nome. Cada um tem label, type, defaultDuty, listed (mostrado nas agências de empregos) e grades (cada um com label, salary e boss). Veja JobDefinition e GradeDefinition.

Exemplo

import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";

const core = resourceExport("ai-core");

// A agência de empregos lista cada emprego marcado como "listed" no painel.
onClientCallback("myscript:jobCenter", () => ({
  ok: true,
  jobs: Object.entries(core.GetJobDefinitions())
    .filter(([, def]) => def.listed)
    .map(([name, def]) => ({ name, label: def.label, salary: def.grades[0]?.salary ?? 0 })),
}));

Em Lua, def.grades[1] é o cargo 0: as listas de Lua começam em 1, os cargos começam em 0.

GetJobDefinition

A definição de um emprego: rótulo, tipo, serviço padrão, se as agências de empregos o listam, e os cargos dele.

Lado: Servidor · Espera: não · Lib: definitions.job(name) (lê cada emprego uma vez e o esquece quando o painel o muda)

Assinatura
GetJobDefinition(job: string): JobDefinition | null
Lua
local def = exports['ai-core']:GetJobDefinition('police') -- table ou nil

Parâmetros

Prop

Type

Retorno

JobDefinition | null: o emprego (JobDefinition). null para um emprego desconhecido ou um valor que não é texto.

Exemplo

import { onClientCallback, online, resourceExport } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";

const core = resourceExport("ai-core");

// Só um cargo de chefe pode abrir o menu de chefe.
onClientCallback("myscript:bossMenu", (source) => {
  const job = online.dutyJob(source);
  const grade = job ? online.jobGrade(source, job) : null;
  if (!job || grade === null) return fail("NOT_ON_DUTY");
  if (!core.GetJobDefinition(job)?.grades[grade]?.boss) return fail("NOT_BOSS");
  return { ok: true };
});

GetGangs

Cada vínculo de gangue do personagem de um jogador.

Lado: Servidor · Espera: não · Lib: online.gangs(source) lê o mesmo do espelho da lib

Assinatura
GetGangs(src: number): GangMembership[] | null
Lua
local gangs = exports['ai-core']:GetGangs(source) -- lista de { gang, grade } ou nil

Parâmetros

Prop

Type

Retorno

GangMembership[] | null: um { gang, grade } por gangue (GangMembership). Uma lista vazia sem gangues. null quando o jogador não tem personagem carregado.

Exemplo

import { resourceExport } from "@aicore-fivem/lib/server";

const core = resourceExport("ai-core");

/** Whether a player belongs to any gang (active or not). */
export function inAnyGang(source: number): boolean {
  return (core.GetGangs(source)?.length ?? 0) > 0;
}

GetActiveGang

A gangue que o jogador tem ativa agora. Território de gangue, baús de gangue e chats de gangue devem usar a gangue ativa.

Lado: Servidor · Espera: não · Lib: nenhuma

Assinatura
GetActiveGang(src: number): string | null
Lua
local gang = exports['ai-core']:GetActiveGang(source) -- nome da gangue ou nil

Parâmetros

Prop

Type

Retorno

string | null: o nome da gangue. null quando nenhuma gangue está ativa ou o jogador não tem personagem carregado.

Exemplo

import { onClientCallback, inventory, resourceExport } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";

const core = resourceExport("ai-core");

onClientCallback("myscript:gangStash", (source) => {
  const gang = core.GetActiveGang(source);
  if (!gang) return fail("NO_GANG");
  return inventory.openInventory(source, `gang_${gang}`) ? { ok: true } : fail("STASH_FAILED");
});

SetGang

Adiciona um jogador a uma gangue, ou muda o cargo dele numa gangue a que pertence. Um personagem sem gangue ativa recebe a nova gangue como ativa.

Lado: Servidor · Espera: não · Lib: nenhuma

Assinatura
SetGang(src: number, gang: string, grade: number): boolean
Lua
local ok = exports['ai-core']:SetGang(source, 'ballas', 0)

Parâmetros

Prop

Type

Retorno

boolean: true quando o personagem agora pertence a gang no cargo grade. false quando a gangue ou o cargo não existe, o personagem já pertence a tantas gangues quanto Most gangs per character permite ou o jogador não tem personagem carregado. Quando a configuração Several gangs per character do painel está desligada, a nova gangue substitui a antiga.

Exemplo

import { addCommand, resourceExport } from "@aicore-fivem/lib/server";

const core = resourceExport("ai-core");

addCommand("setgang", {
  help: "Adds a player to a gang",
  params: [{ name: "id", type: "playerId" }, { name: "gang", type: "string" }, { name: "grade", type: "number" }],
  restricted: true,
}, (_source, args) => {
  console.log(core.SetGang(args.id, args.gang, args.grade) ? "done" : "refused");
});

RemoveGang

Remove um jogador de uma gangue. Quando era a gangue ativa, a próxima gangue que sobra fica ativa (ou nenhuma).

Lado: Servidor · Espera: não · Lib: nenhuma

Assinatura
RemoveGang(src: number, gang: string): boolean
Lua
local ok = exports['ai-core']:RemoveGang(source, 'ballas')

Parâmetros

Prop

Type

Retorno

boolean: true quando o vínculo foi removido. false quando o personagem não está nessa gangue ou o jogador não tem personagem carregado.

Exemplo

import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";

const core = resourceExport("ai-core");

onClientCallback("myscript:leaveGang", (source) => {
  const gang = core.GetActiveGang(source);
  return gang && core.RemoveGang(source, gang) ? { ok: true } : fail("NO_GANG");
});

SetActiveGang

Escolhe qual das gangues do jogador fica ativa, ou nenhuma.

Lado: Servidor · Espera: não · Lib: nenhuma

Assinatura
SetActiveGang(src: number, gang: string | null): boolean
Lua
local ok = exports['ai-core']:SetActiveGang(source, 'vagos') -- nil = nenhuma gangue ativa

Parâmetros

Prop

Type

Retorno

boolean: true quando gang agora está ativa (também quando já estava). false quando o personagem não está nessa gangue ou o jogador não tem personagem carregado. A gangue ativa é salva.

Exemplo

import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
import { fail, readText } from "@aicore-fivem/lib/shared";

const core = resourceExport("ai-core");

onClientCallback(
  "myscript:pickGang",
  { args: ([gang]) => { const name = readText(gang, 32); return name ? [name] : null; } },
  (source, gang) => (core.SetActiveGang(source, gang) ? { ok: true } : fail("NOT_MEMBER")),
);

GetGangDefinitions

Cada definição de gangue do painel, como uma cópia.

Lado: Servidor · Espera: não · Lib: nenhuma

Assinatura
GetGangDefinitions(): Record<string, GangDefinition>
Lua
local gangs = exports['ai-core']:GetGangDefinitions() -- table indexada pelo nome da gangue

Parâmetros

Nenhum.

Retorno

Record<string, GangDefinition>: cada gangue indexada pelo nome, cada uma com label e grades. Veja GangDefinition.

Exemplo

import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";

const core = resourceExport("ai-core");

onClientCallback("myscript:gangList", () => ({
  ok: true,
  gangs: Object.entries(core.GetGangDefinitions()).map(([name, def]) => ({ name, label: def.label })),
}));

GetGangDefinition

A definição de uma gangue: o rótulo e os cargos dela.

Lado: Servidor · Espera: não · Lib: definitions.gang(name)

Assinatura
GetGangDefinition(gang: string): GangDefinition | null
Lua
local def = exports['ai-core']:GetGangDefinition('ballas') -- table ou nil

Parâmetros

Prop

Type

Retorno

GangDefinition | null: a gangue (GangDefinition). null para uma gangue desconhecida ou um valor que não é texto.

Exemplo

import { resourceExport } from "@aicore-fivem/lib/server";

const core = resourceExport("ai-core");

/** "Ballas" for "ballas", the name itself for an unknown gang. */
export function gangLabel(gang: string): string {
  return core.GetGangDefinition(gang)?.label ?? gang;
}

Nesta página