AI Core
Dokumentacja APIAI Core: eksporty serwerowe

Pieniądze i konta

Odczytuj i zmieniaj salda gracza, konta prac i gangów, przesuwaj pieniądze między dwoma kontami w jednej transakcji, odczytuj typy kont.

Każda postać ma jedno saldo na typ konta. Typy pochodzą z listy Accounts w panelu administratora; nowy serwer ma cash, bank, black_money i crypto. Każda praca i każdy gang mają też jedno konto każdego typu (pieniądze firmy), które startuje puste.

Jak działają pieniądze w ai-core:

  • Kwoty to liczby całkowite (dolary, bez centów). Ułamek, NaN albo liczba poza bezpiecznym zakresem liczb całkowitych JavaScriptu jest odrzucana.
  • Zmiana działa od razu w pamięci i jest zapisywana do bazy danych w ciągu około 50 ms, razem z wierszem księgi (ai_core_transactions). Księga zapisuje reason, który podajesz; bez niego zapisuje nazwę zasobu, który wywołał.
  • Saldo nie może zejść poniżej 0, chyba że jego typ konta ma w panelu włączone Can go below zero.
  • Każda zmiana konta gracza wysyła serwerowe zdarzenie ai-core:moneyChanged (src, account, balance, delta, reason) i dociera do własnej gry gracza. Zobacz Zdarzenia i stan.

GetMoney

Saldo gracza na jednym koncie.

Strona: Serwer · Czeka: nie · Lib: brak

Sygnatura
GetMoney(src: number, account: string): number | null
Lua
local balance = exports['ai-core']:GetMoney(source, 'bank') -- number lub nil

Parametry

Prop

Type

Zwraca

number | null: saldo. null, gdy gracz nie ma wczytanej postaci albo typ konta nie istnieje.

Przykład

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

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

onClientCallback("myscript:balance", (source) => {
  const bank = core.GetMoney(source, "bank");
  if (bank === null) return fail("NO_CHARACTER");
  return { ok: true, bank };
});

AddMoney

Dodaje pieniądze na konto gracza. Używaj tego dla nagród, pensji wypłacanych przez twój skrypt albo przychodu ze sprzedaży.

Strona: Serwer · Czeka: nie · Lib: brak

Sygnatura
AddMoney(src: number, account: string, amount: number, reason?: string): boolean
Lua
local ok = exports['ai-core']:AddMoney(source, 'cash', 250, 'fishing_sale')

Parametry

Prop

Type

Zwraca

boolean: true, gdy pieniądze zostały dodane. false, gdy gracz nie ma wczytanej postaci, typ konta nie istnieje albo amount nie jest liczbą całkowitą powyżej 0.

Przykład

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

const core = resourceExport("ai-core");
const BUYER = { x: -1845.2, y: -1197.4, z: 14.3 };

onClientCallback("myscript:sellFish", { guards: [near(BUYER, 3)], lock: true }, (source) => {
  const fish = inventory.getItemCount(source, "fish");
  if (fish < 1) return fail("NO_FISH");
  if (!inventory.removeItem(source, "fish", fish)) return fail("SELL_FAILED");
  core.AddMoney(source, "cash", fish * 25, "fishing_sale");
  return { ok: true };
});

Aby przesunąć pieniądze z jednego konta na drugie (gracz płacący pracy, przelew bankowy), używaj TransferMoney, a nie pary RemoveMoney + AddMoney: przelew to jedna transakcja w bazie danych, para to dwie osobne zmiany.

RemoveMoney

Zabiera pieniądze z konta gracza. Używaj tego, aby pobrać opłatę za coś.

Strona: Serwer · Czeka: nie · Lib: brak

Sygnatura
RemoveMoney(src: number, account: string, amount: number, reason?: string): boolean
Lua
local paid = exports['ai-core']:RemoveMoney(source, 'bank', 500, 'license_fee')

Parametry

Prop

Type

Zwraca

boolean: true, gdy pieniądze zostały zabrane. false, gdy saldo jest za niskie (a typ konta nie pozwala na ujemne salda), gracz nie ma wczytanej postaci, typ konta nie istnieje albo amount nie jest liczbą całkowitą powyżej 0. Przy false nic się nie zmieniło.

Przykład

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

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

onClientCallback("myscript:buyLicense", { lock: true }, (source) => {
  if (!inventory.canCarryItem(source, "driver_license")) return fail("NO_SPACE");
  if (!core.RemoveMoney(source, "bank", PRICE, "license_fee")) return fail("NOT_ENOUGH_MONEY");
  inventory.addItem(source, "driver_license");
  return { ok: true };
});

Sprawdź to, co może zawieść, zanim zabierzesz pieniądze (miejsce w ekwipunku, zapas), albo oddaj pieniądze przez AddMoney, gdy następny krok zawiedzie.

SetMoney

Ustawia saldo gracza na dokładną wartość. Używaj tego w narzędziach administratora; funkcje gry powinny dodawać i zabierać.

Strona: Serwer · Czeka: nie · Lib: brak

Sygnatura
SetMoney(src: number, account: string, amount: number, reason?: string): boolean
Lua
local ok = exports['ai-core']:SetMoney(source, 'cash', 0, 'admin_reset')

Parametry

Prop

Type

Zwraca

boolean: true, gdy saldo wynosi teraz amount (także gdy już wynosiło). false, gdy gracz nie ma wczytanej postaci, typ konta nie istnieje, amount nie jest liczbą całkowitą albo jest poniżej 0 na koncie, które na to nie pozwala.

Przykład

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

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

addCommand("setcash", {
  help: "Sets a player cash",
  params: [{ name: "id", type: "playerId" }, { name: "amount", type: "number" }],
  restricted: true,
}, (_source, args) => {
  console.log(core.SetMoney(args.id, "cash", args.amount, "admin_set") ? "done" : "refused");
});

GetSharedMoney

Saldo konta pracy lub gangu (pieniądze firmy).

Strona: Serwer · Czeka: nie · Lib: brak (banking.societyBalance pyta warstwę bankowości, która może zamiast tego czytać skrypt bankowy)

Sygnatura
GetSharedMoney(ownerType: "job" | "gang", ownerId: string, account: string): number | null
Lua
local balance = exports['ai-core']:GetSharedMoney('job', 'police', 'bank') -- number lub nil

Parametry

Prop

Type

Zwraca

number | null: saldo. null, gdy praca, gang lub typ konta nie istnieje (albo jego konta nie są jeszcze wczytane).

Przykład

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

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

// Menu szefa pokazuje pieniądze pracy; pytać mogą tylko członkowie pracy.
onClientCallback("myscript:societyBalance", (source) => {
  const job = online.dutyJob(source);
  if (!job) return fail("NOT_ON_DUTY");
  return { ok: true, balance: core.GetSharedMoney("job", job, "bank") ?? 0 };
});

Gdy ustawienie panelu Job and gang accounts ma wartość The script's own accounts, konta bank pracy i gangu żyją w tym skrypcie: ten eksport czyta wtedy saldo skryptu. Zobacz Bankowość.

AddSharedMoney

Dodaje pieniądze na konto pracy lub gangu.

Strona: Serwer · Czeka: nie · Lib: brak

Sygnatura
AddSharedMoney(
  ownerType: "job" | "gang",
  ownerId: string,
  account: string,
  amount: number,
  reason?: string,
): boolean
Lua
local ok = exports['ai-core']:AddSharedMoney('job', 'mechanic', 'bank', 300, 'repair_fee')

Parametry

Prop

Type

Zwraca

boolean: true, gdy pieniądze zostały dodane. false, gdy praca, gang lub konto nie istnieje albo amount nie jest liczbą całkowitą powyżej 0.

Przykład

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

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

/** A sale made by an NPC customer goes into the restaurant's account. */
export function restaurantSale(job: string, price: number): void {
  if (!core.AddSharedMoney("job", job, "bank", price, "npc_sale"))
    console.log(`job ${job} has no bank account`);
}

Gdy gracz płaci pracy, używaj TransferMoney z konta gracza na konto pracy: jedna transakcja, oba wiersze księgi.

RemoveSharedMoney

Zabiera pieniądze z konta pracy lub gangu.

Strona: Serwer · Czeka: nie · Lib: brak

Sygnatura
RemoveSharedMoney(
  ownerType: "job" | "gang",
  ownerId: string,
  account: string,
  amount: number,
  reason?: string,
): boolean
Lua
local ok = exports['ai-core']:RemoveSharedMoney('job', 'police', 'bank', 2000, 'equipment')

Parametry

Prop

Type

Zwraca

boolean: true, gdy pieniądze zostały zabrane. false, gdy saldo jest za niskie (a ujemne salda nie są dozwolone), praca, gang lub konto nie istnieje albo amount nie jest liczbą całkowitą powyżej 0.

Przykład

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

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

// Praca zamawia zaopatrzenie z własnego konta.
onClientCallback("myscript:orderSupplies", { lock: true }, (source) => {
  const job = online.dutyJob(source);
  if (!job) return fail("NOT_ON_DUTY");
  if (!core.RemoveSharedMoney("job", job, "bank", 1500, "supplies")) return fail("SOCIETY_NO_MONEY");
  return { ok: true };
});

TransferMoney

Przesuwa pieniądze z jednego konta na drugie w jednej transakcji w bazie danych z oboma wierszami księgi. Każda strona może być kontem wczytanego gracza albo kontem pracy lub gangu. Używaj tego przy każdej płatności między dwoma kontami: gracz płacący firmie, przelew bankowy, wpłata na konto firmy.

Strona: Serwer · Czeka: nie · Lib: money.transfer

Sygnatura
TransferMoney(from: MoneyRef, to: MoneyRef, amount: number, reason?: string, fee?: number): boolean
Lua
local ok = exports['ai-core']:TransferMoney(
  { source = source, account = 'bank' },
  { owner = 'job', id = 'mechanic', account = 'bank' },
  750, 'repair', 0)

Parametry

Prop

Type

MoneyRef to { source, account } dla konta wczytanego gracza albo { owner, id, account } dla konta pracy lub gangu. Zobacz MoneyRef.

Zwraca

boolean: true, gdy from zapłacił amount + fee, a to otrzymał amount. false, gdy brakuje konta (gracz niewczytany, nieznana praca, nieznany typ konta), obie strony to to samo konto, from nie może zapłacić amount + fee, amount nie jest liczbą całkowitą powyżej 0 albo fee nie jest liczbą całkowitą 0 lub większą. Przy false nic się nie zmieniło.

Przykład

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

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

// Wpłata w bankomacie na konto własnego gangu gracza, z opłatą 2%.
onClientCallback(
  "myscript:gangDeposit",
  { args: ([amount]) => { const n = readInt(amount, 1, 1_000_000); return n === null ? null : [n]; }, lock: true },
  (source, amount) => {
    const gang = core.GetActiveGang(source);
    if (!gang) return fail("NO_GANG");
    const fee = Math.ceil(amount * 0.02);
    const ok = core.TransferMoney(
      { source, account: "bank" },
      { owner: "gang", id: gang, account: "bank" },
      amount, "gang_deposit", fee,
    );
    return ok ? { ok: true } : fail("NOT_ENOUGH_MONEY");
  },
);

Obie strony wysyłają swoją zwykłą zmianę (strona gracza wysyła ai-core:moneyChanged). Dwaj gracze mogą być dwiema stronami: { source: a, account: "bank" } do { source: b, account: "bank" }.

GetAccountTypes

Każdy typ konta z listy Accounts w panelu, z jego etykietą, kwotą startową i tym, czy może zejść poniżej zera. Używaj tego, aby zbudować menu kont albo sprawdzić nazwę.

Strona: Serwer · Czeka: nie · Lib: brak

Sygnatura
GetAccountTypes(): Record<string, AccountTypeDefinition>
Lua
local types = exports['ai-core']:GetAccountTypes() -- tabela z nazwą konta jako kluczem

Parametry

Brak.

Zwraca

Record<string, AccountTypeDefinition>: kopia z nazwą konta jako kluczem (cash, bank...). Każda wartość ma label (pokazywane graczom), start (co dostaje nowa postać) i allowNegative. Zobacz AccountTypeDefinition.

Przykład

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

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

// Ekran portfela wyświetla każde konto z jego etykietą i saldem.
onClientCallback("myscript:wallet", (source) => {
  const rows = Object.entries(core.GetAccountTypes()).map(([name, type]) => ({
    name,
    label: type.label,
    balance: core.GetMoney(source, name) ?? 0,
  }));
  return { ok: true, rows };
});

Na tej stronie