Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
alt:V Player List Snippet
import * as alt from 'alt-client';
import * as native from 'natives';
import { SYSTEM_EVENTS } from '../../shared/enums/system';
import { requestScaleForm, Scaleform } from '../utility/scaleform';
import { Timer } from '../utility/timers';
const SCALEFORM_NAME = 'mp_mm_card_freemode';
const MAX_PLAYERS = 16;
let index = 1;
let scaleform: Scaleform;
export class LeaderboardSystem {
static async init() {
scaleform = await requestScaleForm(SCALEFORM_NAME);
LeaderboardSystem.update();
alt.setInterval(LeaderboardSystem.render, 0);
}
static update() {
const players: Array<string> = [];
[...alt.Player.all].forEach((player) => {
if (!player || !player.valid) {
return;
}
players.push(`(${player.id}) ${player.name}`);
});
// Title of Leaderboard
const maxPlayers = Math.ceil(players.length / MAX_PLAYERS);
scaleform.passFunction('SET_TITLE', `Players (${players.length})`, `Page ${index}/${maxPlayers}`);
// Reset Player List
for (let i = 0; i < MAX_PLAYERS; i++) {
scaleform.passFunction('SET_DATA_SLOT_EMPTY', i);
}
// Player List of Leader Board
const paginatedPlayers = LeaderboardSystem.paginate(players, index);
if (paginatedPlayers.length < MAX_PLAYERS) {
const neededAmount = MAX_PLAYERS - paginatedPlayers.length;
for (let i = 0; i < neededAmount; i++) {
paginatedPlayers.push('');
}
}
paginatedPlayers.forEach(async (playerName, i) => {
scaleform.passFunction('SET_DATA_SLOT', i, '', playerName, 116, 0, '', '', '', 2, '', '', '');
});
scaleform.passFunction('DISPLAY_VIEW');
}
/**
* Slice into a smaller array based on the current page number.
* Pass 'index' for page.
* @static
* @param {Array<alt.Player>} array
* @param {number} page
* @return {*}
* @memberof LeaderboardSystem
*/
static paginate<T>(array: Array<T>, page: number) {
return array.slice((page - 1) * MAX_PLAYERS, page * MAX_PLAYERS);
}
static render() {
if (!scaleform) {
return;
}
native.setScriptGfxAlign(76, 84);
scaleform.render(0.5, 0.45, 0.28, 0.6);
native.resetScriptGfxAlign();
}
}
alt.onServer(SYSTEM_EVENTS.TICKS_START, LeaderboardSystem.init);
import * as alt from 'alt-client';
import * as native from 'natives';
export class Scaleform {
private id: number;
constructor(hash: number) {
this.id = hash;
}
hasLoaded(): boolean {
return native.hasScaleformMovieLoaded(this.id);
}
passFunction(functionName: string, ...args: Array<any>) {
native.beginScaleformMovieMethod(this.id, functionName);
for (let i = 0; i < args.length; i++) {
const arg = args[i];
switch (typeof arg) {
case 'number': {
if (Number(arg) === arg && arg % 1 !== 0) {
native.scaleformMovieMethodAddParamFloat(arg);
} else {
native.scaleformMovieMethodAddParamInt(arg);
}
}
case 'string': {
native.scaleformMovieMethodAddParamPlayerNameString(arg as string);
break;
}
case 'boolean': {
native.scaleformMovieMethodAddParamBool(arg);
break;
}
default: {
alt.logError(
`Bad Argument: ${typeof arg} = ${arg.toString()} passed to scaleform with handle ${this.id}`
);
}
}
}
return native.endScaleformMovieMethodReturnValue();
}
destroy() {
native.setScaleformMovieAsNoLongerNeeded(this.id);
this.id = 0;
}
render(x: number, y: number, width: number, height: number) {
native.drawScaleformMovie(this.id, x, y, width, height, 255, 255, 255, 255, 0);
}
}
export function requestScaleForm(scaleformName: string): Promise<Scaleform> {
return new Promise((resolve: Function) => {
const instance = new Scaleform(native.requestScaleformMovie(scaleformName));
const interval = alt.setInterval(() => {
if (!instance.hasLoaded()) {
return;
}
alt.clearInterval(interval);
resolve(instance);
}, 5);
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment