rock-mod
Version:
Rock-Mod is a powerful framework designed for creating and managing mods for Grand Theft Auto (GTA) games.
103 lines (102 loc) • 6.34 kB
JavaScript
/// <reference types="@classic-mp/types/client" />
import { Vector2D } from "../../../../shared/common/utils";
/**
* Реализация `IGraphicsManager` под CCMP.
*
* RageMP даёт высокоуровневые обёртки `mp.game.graphics.drawText` /
* `world3dToScreen2d` / etc. У CCMP таких помощников нет — есть только
* сырые GTA V натив-биндинги в `ccmp.natives.{hud,graphics}.*`. Этот класс
* собирает их в эквивалент RageMP API.
*
* ### `drawText` — мульти-нативная цепочка
*
* Стандартная GTA V последовательность:
* 1. `SET_TEXT_FONT/SCALE/COLOUR/OUTLINE/CENTRE` — стиль текста
* 2. `BEGIN_TEXT_COMMAND_DISPLAY_TEXT('STRING')` — открыть text command
* 3. `ADD_TEXT_COMPONENT_SUBSTRING_PLAYER_NAME(text)` — добавить содержимое
* 4. `END_TEXT_COMMAND_DISPLAY_TEXT(x, y, 0)` — отрисовать
*
* **Hot path:** вызывается каждый render-tick из `HudController.onRender`
* (ammo, nametags, etc). Все вызовы синхронны (V8-ops), общая стоимость —
* единицы микросекунд на текст.
*
* **Ограничение длины:** `ADD_TEXT_COMPONENT_SUBSTRING_PLAYER_NAME` усекает
* вход на 99 символов. Для типичных HUD-меток (ammo "30/120", имена игроков)
* не критично; для длинных строк нужно разбивать на чанки последовательными
* `ADD_*` вызовами. Сейчас не реализовано — добавим если понадобится.
*
* ### `world3dToScreen2d`
*
* `getScreenCoordFromWorldCoord` возвращает `{return, screenx, screeny}` —
* `return=false` означает, что точка вне frustum'а; маппим в `null` для
* совпадения с RageMP-семантикой.
*
* ### `getActiveScreenResolution`
*
* Маппится на `getActualScreenResolution` (GTA native `0x873C9F3104101DD3`),
* который возвращает физическое разрешение рендера — то же, что RageMP'шный
* `getActiveScreenResolution` (это один и тот же натив, переименованный по-
* разному в разных биндингах).
*
* ### `startScreenEffect` / `stopScreenEffect`
*
* Маппятся на `animpostfxPlay` / `animpostfxStop` (`ANIMPOSTFX_PLAY`/`STOP`) —
* это и есть GTA V натив для screen effect'ов (по-старому называвшийся
* `START_SCREEN_EFFECT`).
*/
export class CCMPGraphicsManager {
drawText(text, position, options) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
const font = (_a = options === null || options === void 0 ? void 0 : options.font) !== null && _a !== void 0 ? _a : 0;
const [scaleX, scaleY] = (_b = options === null || options === void 0 ? void 0 : options.scale) !== null && _b !== void 0 ? _b : [0.3, 0.3];
const r = (_d = (_c = options === null || options === void 0 ? void 0 : options.color) === null || _c === void 0 ? void 0 : _c.r) !== null && _d !== void 0 ? _d : 255;
const g = (_f = (_e = options === null || options === void 0 ? void 0 : options.color) === null || _e === void 0 ? void 0 : _e.g) !== null && _f !== void 0 ? _f : 255;
const b = (_h = (_g = options === null || options === void 0 ? void 0 : options.color) === null || _g === void 0 ? void 0 : _g.b) !== null && _h !== void 0 ? _h : 255;
const a = (_k = (_j = options === null || options === void 0 ? void 0 : options.color) === null || _j === void 0 ? void 0 : _j.a) !== null && _k !== void 0 ? _k : 255;
const outline = (_l = options === null || options === void 0 ? void 0 : options.outline) !== null && _l !== void 0 ? _l : true;
const centre = (_m = options === null || options === void 0 ? void 0 : options.centre) !== null && _m !== void 0 ? _m : false;
ccmp.graphics.drawText(text, position.x, position.y, {
font,
scale: [scaleX, scaleY],
color: [r, g, b, a],
outline,
centre,
});
}
world3dToScreen2d(position) {
const result = ccmp.natives.graphics.getScreenCoordFromWorldCoord(position.x, position.y, position.z);
if (!result.return) {
// Точка вне frustum'а — RageMP в таком случае возвращает `null`.
return null;
}
return new Vector2D(result.screenx, result.screeny);
}
startScreenEffect(effectName, duration, looped) {
ccmp.natives.graphics.animpostfxPlay(effectName, duration, looped);
}
stopScreenEffect(effectName) {
ccmp.natives.graphics.animpostfxStop(effectName);
}
setPtfxAssetNextCall(assetName) {
ccmp.natives.graphics.useParticleFxAsset(assetName);
}
startParticleFxNonLoopedAtCoord(options) {
return ccmp.natives.graphics.startParticleFxNonLoopedAtCoord(options.effectName, options.position.x, options.position.y, options.position.z, options.rotation.x, options.rotation.y, options.rotation.z, options.scale, options.xAxis, options.yAxis, options.zAxis);
}
startParticleFxLoopedAtCoord(options) {
return ccmp.natives.graphics.startParticleFxLoopedAtCoord(options.effectName, options.position.x, options.position.y, options.position.z, options.rotation.x, options.rotation.y, options.rotation.z, options.scale, options.xAxis, options.yAxis, options.zAxis, options.p11);
}
stopParticleFxLooped(handle, p1) {
ccmp.natives.graphics.stopParticleFxLooped(handle, p1);
}
getSafeZoneSize() {
return ccmp.natives.graphics.getSafeZoneSize();
}
getActiveScreenResolution() {
// `getActualScreenResolution` (0x873C9F3104101DD3) === RageMP'шный
// `getActiveScreenResolution` — это один и тот же native под разными
// именами в разных биндингах.
const result = ccmp.natives.graphics.getActualScreenResolution();
return new Vector2D(result.x, result.y);
}
}