rock-mod 0.22.0 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/dist/client/entities/ccmp/object/CCMPObject.d.ts +3 -6
  2. package/dist/client/entities/ccmp/object/CCMPObject.js +33 -102
  3. package/dist/client/entities/ccmp/player/CCMPPlayer.d.ts +14 -16
  4. package/dist/client/entities/ccmp/player/CCMPPlayer.js +85 -92
  5. package/dist/client/entities/ccmp/vehicle/CCMPVehicle.d.ts +32 -49
  6. package/dist/client/entities/ccmp/vehicle/CCMPVehicle.js +117 -198
  7. package/dist/client/entities/ccmp/vehicle/CCMPVehiclesManager.js +2 -1
  8. package/dist/client/game/ccmp/chat/CCMPChatManager.d.ts +2 -22
  9. package/dist/client/game/ccmp/chat/CCMPChatManager.js +6 -34
  10. package/dist/client/game/ccmp/ui/CCMPUiManager.d.ts +0 -29
  11. package/dist/client/game/ccmp/ui/CCMPUiManager.js +5 -41
  12. package/dist/client/net/ccmp/CCMPNetManager.d.ts +0 -7
  13. package/dist/client/net/ccmp/CCMPNetManager.js +0 -26
  14. package/dist/client/net/ccmp/events/CCMPEventsBridge.d.ts +3 -1
  15. package/dist/client/net/ccmp/events/CCMPEventsBridge.js +33 -3
  16. package/dist/server/entities/altv/colshape/AltVColshape.d.ts +2 -0
  17. package/dist/server/entities/altv/colshape/AltVColshape.js +6 -0
  18. package/dist/server/entities/ccmp/player/CCMPPlayersManager.js +15 -0
  19. package/dist/server/entities/ccmp/vehicle/CCMPVehicle.d.ts +27 -13
  20. package/dist/server/entities/ccmp/vehicle/CCMPVehicle.js +82 -39
  21. package/dist/server/entities/common/colshape/IColshape.d.ts +2 -0
  22. package/dist/server/entities/mock/colshape/MockColshape.d.ts +3 -0
  23. package/dist/server/entities/mock/colshape/MockColshape.js +8 -0
  24. package/dist/server/entities/ragemp/colshape/RageColshape.d.ts +2 -0
  25. package/dist/server/entities/ragemp/colshape/RageColshape.js +6 -0
  26. package/dist/server/net/ccmp/CCMPNetManager.js +0 -5
  27. package/dist/server/net/ccmp/events/CCMPEventsManager.d.ts +6 -2
  28. package/package.json +2 -2
@@ -1,26 +1,6 @@
1
1
  import { type IChatManager } from "../../common/chat/IChatManager";
2
- /**
3
- * No-op реализация `IChatManager` под CCMP.
4
- *
5
- * У RageMP клиента есть `mp.gui.chat.activate(state)` (разрешает игроку
6
- * печатать в чат по T) и `mp.gui.chat.show(state)` (видимость чат-окна).
7
- * У CCMP **нет JS API для управления чатом** — только встроенное событие
8
- * `chatMessage` на приём входящих сообщений и `ccmp.notify(text)` для HUD-
9
- * уведомлений (не относится к чату).
10
- *
11
- * Бросать нельзя: геймод-консьюмер `RockModChatAdapter.activate` вызывается
12
- * из `ChatService.onModuleInit` — исключение поднимет весь bootstrap DI.
13
- * Поэтому игнорируем + один раз пишем warn, чтобы было видно в логах что
14
- * фича недоступна.
15
- *
16
- * Следствие: под CCMP программное управление чатом не работает. Чат-UI
17
- * (если он есть) рисуется самим CCMP-клиентом на Rust-стороне и реагирует
18
- * на свои клавиши. Когда (если) CCMP добавит JS-API для чата — заменим.
19
- */
20
2
  export declare class CCMPChatManager implements IChatManager {
21
- private _warned;
22
- activate(state: boolean): void;
23
- show(state: boolean): void;
3
+ activate(_state: boolean): void;
4
+ show(_state: boolean): void;
24
5
  push(text: string): void;
25
- private _warnOnce;
26
6
  }
@@ -1,41 +1,13 @@
1
- /**
2
- * No-op реализация `IChatManager` под CCMP.
3
- *
4
- * У RageMP клиента есть `mp.gui.chat.activate(state)` (разрешает игроку
5
- * печатать в чат по T) и `mp.gui.chat.show(state)` (видимость чат-окна).
6
- * У CCMP **нет JS API для управления чатом** — только встроенное событие
7
- * `chatMessage` на приём входящих сообщений и `ccmp.notify(text)` для HUD-
8
- * уведомлений (не относится к чату).
9
- *
10
- * Бросать нельзя: геймод-консьюмер `RockModChatAdapter.activate` вызывается
11
- * из `ChatService.onModuleInit` — исключение поднимет весь bootstrap DI.
12
- * Поэтому игнорируем + один раз пишем warn, чтобы было видно в логах что
13
- * фича недоступна.
14
- *
15
- * Следствие: под CCMP программное управление чатом не работает. Чат-UI
16
- * (если он есть) рисуется самим CCMP-клиентом на Rust-стороне и реагирует
17
- * на свои клавиши. Когда (если) CCMP добавит JS-API для чата — заменим.
18
- */
19
1
  export class CCMPChatManager {
20
- constructor() {
21
- this._warned = false;
2
+ activate(_state) {
3
+ void _state;
4
+ // CCMP currently does not expose chat activation controls to JS.
22
5
  }
23
- activate(state) {
24
- this._warnOnce("activate", state);
25
- }
26
- show(state) {
27
- this._warnOnce("show", state);
6
+ show(_state) {
7
+ void _state;
8
+ // CCMP currently does not expose chat visibility controls to JS.
28
9
  }
29
10
  push(text) {
30
11
  ccmp.notify(text);
31
12
  }
32
- _warnOnce(method, state) {
33
- if (this._warned) {
34
- return;
35
- }
36
- this._warned = true;
37
- console.warn(`[CCMPChatManager] ${method}(${String(state)}) вызван, но CCMP не ` +
38
- `предоставляет JS API для управления чатом. Дальнейшие вызовы ` +
39
- `activate/show будут проигнорированы молча.`);
40
- }
41
13
  }
@@ -1,34 +1,6 @@
1
1
  import { type IUiManager } from "../../common/ui/IUiManager";
2
2
  import { type IVector3D } from "../../../../shared/common/utils";
3
- /**
4
- * Реализация `IUiManager` под CCMP. Большинство методов — прямой passthrough
5
- * к `ccmp.natives.hud.*` (cрезом GTA V нативов HUD-намespace'а).
6
- *
7
- * **Hot path:** `hideHudComponentThisFrame(componentIndex)` вызывается каждый
8
- * render-tick из `HudService.render` → `_hideHudComponents`. CCMP-native —
9
- * синхронный V8-op, стоимость незначительная.
10
- *
11
- * ### Пробелы в CCMP-нативах
12
- *
13
- * `getLabelText(labelName)` — GTA V натив `_GET_LABEL_TEXT` (0x7B5280EBA9840C72)
14
- * **не экспонирован** в CCMP-биндингах (см. `@classic-mp/types/natives`).
15
- * Этот натив резолвит локализационный label из game GXT-таблиц — без него
16
- * мы не можем достать перевод. Возвращаем сам `labelName` как fallback и
17
- * один раз варнём в консоль — UI-консьюмер (скорее всего, что-то вроде
18
- * weapon-display или street-name) получит непереведённый ключ, что лучше
19
- * пустой строки или падения.
20
- *
21
- * TODO: при появлении `getLabelText` в `@classic-mp/types/natives.hud` или
22
- * `natives.localization` — заменить fallback на реальный вызов.
23
- *
24
- * ### `deleteWaypoint` под CCMP
25
- *
26
- * RageMP-натив `deleteWaypoint()` — алиас для `SET_WAYPOINT_OFF` (
27
- * `0xA7E4E2D361C2627F`). CCMP экспонирует его как `setWaypointOff`.
28
- */
29
3
  export declare class CCMPUiManager implements IUiManager {
30
- /** Глобальный набор для one-time варнингов, чтобы не флудить лог. */
31
- private static readonly _warnedMethods;
32
4
  getStreetNameFromHashKey(hash: number): string;
33
5
  getLabelText(labelName: string): string;
34
6
  hideHudComponentThisFrame(componentIndex: number): void;
@@ -37,5 +9,4 @@ export declare class CCMPUiManager implements IUiManager {
37
9
  setWaypoint(x: number, y: number): void;
38
10
  deleteWaypoint(): void;
39
11
  getBlipInfoIdCoord(blip: number): IVector3D;
40
- private static _warnOnce;
41
12
  }
@@ -1,40 +1,15 @@
1
1
  /// <reference types="@classic-mp/types/client" />
2
2
  import { Vector3D } from "../../../../shared/common/utils";
3
- /**
4
- * Реализация `IUiManager` под CCMP. Большинство методов — прямой passthrough
5
- * к `ccmp.natives.hud.*` (cрезом GTA V нативов HUD-намespace'а).
6
- *
7
- * **Hot path:** `hideHudComponentThisFrame(componentIndex)` вызывается каждый
8
- * render-tick из `HudService.render` → `_hideHudComponents`. CCMP-native —
9
- * синхронный V8-op, стоимость незначительная.
10
- *
11
- * ### Пробелы в CCMP-нативах
12
- *
13
- * `getLabelText(labelName)` — GTA V натив `_GET_LABEL_TEXT` (0x7B5280EBA9840C72)
14
- * **не экспонирован** в CCMP-биндингах (см. `@classic-mp/types/natives`).
15
- * Этот натив резолвит локализационный label из game GXT-таблиц — без него
16
- * мы не можем достать перевод. Возвращаем сам `labelName` как fallback и
17
- * один раз варнём в консоль — UI-консьюмер (скорее всего, что-то вроде
18
- * weapon-display или street-name) получит непереведённый ключ, что лучше
19
- * пустой строки или падения.
20
- *
21
- * TODO: при появлении `getLabelText` в `@classic-mp/types/natives.hud` или
22
- * `natives.localization` — заменить fallback на реальный вызов.
23
- *
24
- * ### `deleteWaypoint` под CCMP
25
- *
26
- * RageMP-натив `deleteWaypoint()` — алиас для `SET_WAYPOINT_OFF` (
27
- * `0xA7E4E2D361C2627F`). CCMP экспонирует его как `setWaypointOff`.
28
- */
29
3
  export class CCMPUiManager {
30
4
  getStreetNameFromHashKey(hash) {
31
5
  return ccmp.natives.hud.getStreetNameFromHashKey(hash);
32
6
  }
33
7
  getLabelText(labelName) {
34
- // _GET_LABEL_TEXT не доступен в CCMP — отдаём ключ как fallback.
35
- CCMPUiManager._warnOnce("getLabelText", "[CCMPUiManager] getLabelText() не реализован в CCMP-нативах — " +
36
- "возвращаем сам labelName как fallback. Локализованных строк не будет.");
37
- return labelName;
8
+ if (!ccmp.natives.hud.doesTextLabelExist(labelName)) {
9
+ return labelName;
10
+ }
11
+ const text = ccmp.natives.hud.getFilenameForAudioConversation(labelName);
12
+ return text && text !== "NULL" ? text : labelName;
38
13
  }
39
14
  hideHudComponentThisFrame(componentIndex) {
40
15
  ccmp.natives.hud.hideHudComponentThisFrame(componentIndex);
@@ -49,21 +24,10 @@ export class CCMPUiManager {
49
24
  ccmp.natives.hud.setNewWaypoint(x, y);
50
25
  }
51
26
  deleteWaypoint() {
52
- // RageMP `deleteWaypoint()` === GTA `SET_WAYPOINT_OFF`. CCMP экспонирует
53
- // под именем `setWaypointOff`.
54
27
  ccmp.natives.hud.setWaypointOff();
55
28
  }
56
29
  getBlipInfoIdCoord(blip) {
57
30
  const { x, y, z } = ccmp.natives.hud.getBlipInfoIdCoord(blip);
58
31
  return new Vector3D(x, y, z);
59
32
  }
60
- static _warnOnce(method, message) {
61
- if (CCMPUiManager._warnedMethods.has(method)) {
62
- return;
63
- }
64
- CCMPUiManager._warnedMethods.add(method);
65
- console.warn(message);
66
- }
67
33
  }
68
- /** Глобальный набор для one-time варнингов, чтобы не флудить лог. */
69
- CCMPUiManager._warnedMethods = new Set();
@@ -2,13 +2,6 @@ import { type INetManager } from "../common/INetManager";
2
2
  import { CCMPDataHandler } from "./dataHandler/CCMPDataHandler";
3
3
  import { CCMPEventsManager } from "./events/CCMPEventsManager";
4
4
  import { CCMPRPCManager } from "./rpc/CCMPRPCManager";
5
- /**
6
- * Корневой сетевой менеджер CCMP-клиента.
7
- *
8
- * Симметричен `RageNetManager` (`src/client/net/ragemp/RageNetManager.ts`), но
9
- * без `IEntityPoolRouter` — CCMP entity pool ещё не реализован, а events+RPC
10
- * milestone от него не зависит.
11
- */
12
5
  export declare class CCMPNetManager implements INetManager {
13
6
  private readonly _eventsManager;
14
7
  private readonly _rpcManager;
@@ -4,13 +4,6 @@ import { CCMPEventsBridge } from "./events/CCMPEventsBridge";
4
4
  import { CCMPEventsManager } from "./events/CCMPEventsManager";
5
5
  import { CCMPRenderTicker } from "./events/CCMPRenderTicker";
6
6
  import { CCMPRPCManager } from "./rpc/CCMPRPCManager";
7
- /**
8
- * Корневой сетевой менеджер CCMP-клиента.
9
- *
10
- * Симметричен `RageNetManager` (`src/client/net/ragemp/RageNetManager.ts`), но
11
- * без `IEntityPoolRouter` — CCMP entity pool ещё не реализован, а events+RPC
12
- * milestone от него не зависит.
13
- */
14
7
  export class CCMPNetManager {
15
8
  get events() {
16
9
  return this._eventsManager;
@@ -22,29 +15,10 @@ export class CCMPNetManager {
22
15
  return this._dataHandler;
23
16
  }
24
17
  constructor() {
25
- // Прямой ping на сервер — не зависит от console-обёртки и других
26
- // менеджеров. Серверная сторона (`CCMPNetManager`) логирует через
27
- // `rm::clientLog` handler с уровнем info. Если в серверном stdout не
28
- // видно "[client:<id>] [rock-mod] CCMP client net manager constructed" —
29
- // значит client-бандл не загрузился / не дошёл до этого места.
30
- try {
31
- ccmp.emitServer("rm::clientLog", {
32
- level: "info",
33
- args: ["[rock-mod] CCMP client net manager constructed"],
34
- });
35
- }
36
- catch (_a) {
37
- // Если сетевой канал не готов, эта диагностическая строка теряется.
38
- }
39
- // Console forwarder ставим первым: чтобы любые `console.*` из
40
- // конструкторов других менеджеров/модулей уже зеркалились на сервер.
41
18
  this._consoleForwarder = new CCMPConsoleForwarder();
42
19
  this._consoleForwarder.install();
43
20
  this._eventsManager = new CCMPEventsManager();
44
21
  this._rpcManager = new CCMPRPCManager();
45
- // DataHandler сначала, чтобы он успел подписаться на internal-bus до
46
- // первых эмиссий `rm::syncedMetaChange` от `CCMPSyncedMetaBridge`
47
- // (registers later, when all stream-synced base-object managers are ready).
48
22
  this._dataHandler = new CCMPDataHandler(this._eventsManager);
49
23
  this._bridge = new CCMPEventsBridge(this._eventsManager);
50
24
  this._renderTicker = new CCMPRenderTicker();
@@ -8,7 +8,9 @@ import { type CCMPEventsManager } from "./CCMPEventsManager";
8
8
  * Rock-Mod `CCMPPlayer` instance before emitting internal `rm::*` events.
9
9
  */
10
10
  export declare class CCMPEventsBridge implements IEventsBridge {
11
- constructor(events: CCMPEventsManager);
11
+ private readonly _events;
12
+ constructor(_events: CCMPEventsManager);
12
13
  registerRawEvents(): void;
13
14
  registerServerEvents(): void;
15
+ private _resolveVehicleEventPayload;
14
16
  }
@@ -1,3 +1,5 @@
1
+ import { ClientInternalEventName } from "../../../net/common/events/types";
2
+ import { RockMod } from "../../../RockMod";
1
3
  /**
2
4
  * Legacy bridge slot for CCMP raw events.
3
5
  *
@@ -6,14 +8,42 @@
6
8
  * Rock-Mod `CCMPPlayer` instance before emitting internal `rm::*` events.
7
9
  */
8
10
  export class CCMPEventsBridge {
9
- constructor(events) {
10
- void events;
11
+ constructor(_events) {
12
+ this._events = _events;
11
13
  }
12
14
  registerRawEvents() {
13
- // Intentionally empty. See class comment.
15
+ this._events.register("playerEnterVehicle", (payload) => {
16
+ const event = this._resolveVehicleEventPayload(payload);
17
+ if (!event)
18
+ return;
19
+ this._events.emitInternal(ClientInternalEventName.PlayerEnterVehicle, event.vehicle, event.seat);
20
+ });
21
+ this._events.register("playerLeaveVehicle", (payload) => {
22
+ const event = this._resolveVehicleEventPayload(payload);
23
+ if (!event)
24
+ return;
25
+ this._events.emitInternal(ClientInternalEventName.PlayerLeaveVehicle, event.vehicle, event.seat);
26
+ });
14
27
  }
15
28
  registerServerEvents() {
16
29
  // No-op: ранее тут жил handler для cooperation `rm::clientReady`-ответа.
17
30
  // Теперь это responsibility `CCMPPlayersManager`.
18
31
  }
32
+ _resolveVehicleEventPayload(payload) {
33
+ var _a;
34
+ const ccmpPayload = payload;
35
+ const ccmpVehicleId = (_a = ccmpPayload === null || ccmpPayload === void 0 ? void 0 : ccmpPayload.vehicle) === null || _a === void 0 ? void 0 : _a.id;
36
+ if (typeof ccmpVehicleId !== "number" || !Number.isFinite(ccmpVehicleId)) {
37
+ return null;
38
+ }
39
+ const rawSeat = Number(ccmpPayload === null || ccmpPayload === void 0 ? void 0 : ccmpPayload.seat);
40
+ const seat = Number.isFinite(rawSeat) ? rawSeat : -1;
41
+ try {
42
+ const vehicle = RockMod.instance.vehicles.registerById(ccmpVehicleId);
43
+ return { vehicle, seat };
44
+ }
45
+ catch (_b) {
46
+ return null;
47
+ }
48
+ }
19
49
  }
@@ -4,4 +4,6 @@ export interface IAltVColshapeOptions extends IAltVWorldObjectOptions<Colshape>
4
4
  }
5
5
  export declare abstract class AltVColshape extends AltVWorldObject<Colshape> {
6
6
  protected constructor(options: IAltVColshapeOptions);
7
+ getNetData(name: string): unknown;
8
+ setNetData(name: string, value: unknown): void;
7
9
  }
@@ -6,5 +6,11 @@ class AltVColshape extends AltVWorldObject_1.AltVWorldObject {
6
6
  constructor(options) {
7
7
  super(options);
8
8
  }
9
+ getNetData(name) {
10
+ return this.mpEntity.getSyncedMeta(name);
11
+ }
12
+ setNetData(name, value) {
13
+ this.mpEntity.setSyncedMeta({ name, value });
14
+ }
9
15
  }
10
16
  exports.AltVColshape = AltVColshape;
@@ -4,6 +4,7 @@ exports.CCMPPlayersManager = void 0;
4
4
  const CCMPEntitiesManager_1 = require("../entity/CCMPEntitiesManager");
5
5
  const CCMPPlayer_1 = require("./CCMPPlayer");
6
6
  const types_1 = require("../../../net/common/events/types");
7
+ const RockMod_1 = require("../../../RockMod");
7
8
  class CCMPPlayersManager extends CCMPEntitiesManager_1.CCMPEntitiesManager {
8
9
  constructor(net) {
9
10
  super({
@@ -60,6 +61,20 @@ class CCMPPlayersManager extends CCMPEntitiesManager_1.CCMPEntitiesManager {
60
61
  return;
61
62
  net.events.emitInternal(types_1.ServerInternalEventName.PlayerDimensionChange, player, oldDim, newDim);
62
63
  },
64
+ playerEnterVehicle: (ccmpPlayer, ccmpVehicle, seat) => {
65
+ const player = this.findByID(ccmpPlayer.id);
66
+ const vehicle = RockMod_1.RockMod.instance.vehicles.findByID(ccmpVehicle.id);
67
+ if (!player || !vehicle)
68
+ return;
69
+ net.events.emitInternal(types_1.ServerInternalEventName.PlayerEnterVehicle, player, vehicle, seat);
70
+ },
71
+ playerExitVehicle: (ccmpPlayer, ccmpVehicle) => {
72
+ const player = this.findByID(ccmpPlayer.id);
73
+ const vehicle = RockMod_1.RockMod.instance.vehicles.findByID(ccmpVehicle.id);
74
+ if (!player || !vehicle)
75
+ return;
76
+ net.events.emitInternal(types_1.ServerInternalEventName.PlayerExitVehicle, player, vehicle);
77
+ },
63
78
  });
64
79
  }
65
80
  }
@@ -10,8 +10,18 @@ export interface ICCMPVehicleOptions {
10
10
  onDestroy: (vehicle: CCMPVehicle) => void;
11
11
  }
12
12
  export declare class CCMPVehicle extends CCMPEntity implements IVehicle {
13
+ private static readonly _customPrimaryColorMeta;
14
+ private static readonly _customSecondaryColorMeta;
15
+ private static readonly _vehicleModsMeta;
16
+ private static readonly _neonEnabledMeta;
17
+ private static readonly _neonColorMeta;
18
+ private static readonly _windowTintMeta;
19
+ private static readonly _wheelTypeMeta;
13
20
  private readonly _ccmpVehicle;
14
21
  private readonly _onDestroy;
22
+ private readonly _mods;
23
+ private _customPrimaryColor;
24
+ private _customSecondaryColor;
15
25
  get id(): number;
16
26
  get type(): BaseObjectType;
17
27
  get isExists(): boolean;
@@ -37,22 +47,26 @@ export declare class CCMPVehicle extends CCMPEntity implements IVehicle {
37
47
  setDimension(value: number): void;
38
48
  setModel(value: string): void;
39
49
  setRotation(value: IVector3D): void;
40
- setBodyHealth(_value: number): void;
41
- setEngineHealth(_value: number): void;
50
+ setBodyHealth(value: number): void;
51
+ setEngineHealth(value: number): void;
42
52
  setEngineOn(value: boolean): void;
43
53
  setNumberPlate(value: string): void;
44
- setLocked(_value: boolean): void;
45
- setPrimaryColor(_value: number): void;
46
- setSecondaryColor(_value: number): void;
47
- setCustomPrimaryColor(_value: IRGBA): void;
48
- setCustomSecondaryColor(_value: IRGBA): void;
49
- setMod(_modType: number, _modIndex: number): void;
50
- getMod(_modType: number): number;
51
- setNeonEnabled(_enabled: boolean): void;
52
- setNeonColor(_r: number, _g: number, _b: number): void;
53
- setWindowTint(_tintType: number): void;
54
- setWheelType(_wheelType: number): void;
54
+ setLocked(value: boolean): void;
55
+ setPrimaryColor(value: number): void;
56
+ setSecondaryColor(value: number): void;
57
+ setCustomPrimaryColor(value: IRGBA): void;
58
+ setCustomSecondaryColor(value: IRGBA): void;
59
+ setMod(modType: number, modIndex: number): void;
60
+ getMod(modType: number): number;
61
+ setNeonEnabled(enabled: boolean): void;
62
+ setNeonColor(r: number, g: number, b: number): void;
63
+ setWindowTint(tintType: number): void;
64
+ setWheelType(wheelType: number): void;
55
65
  setPlateType(plateType: number): void;
56
66
  explode(): void;
57
67
  repair(): void;
68
+ private _restoreCompatibilityState;
69
+ private _readColorMeta;
70
+ private _setCompatibilityMeta;
71
+ private _toRgba;
58
72
  }
@@ -2,15 +2,23 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CCMPVehicle = void 0;
4
4
  const CCMPEntity_1 = require("../entity/CCMPEntity");
5
+ const utils_1 = require("../../../../shared/common/utils");
5
6
  const Vectors_1 = require("../../../../shared/common/utils/math/Vectors");
6
7
  const shared_1 = require("../../../../shared");
7
8
  const RockMod_1 = require("../../../RockMod");
8
- const notImplemented = (name) => {
9
- throw new Error(`Not implemented yet: ${name}`);
10
- };
11
9
  class CCMPVehicle extends CCMPEntity_1.CCMPEntity {
10
+ static _customPrimaryColorMeta = "rockMod:customPrimaryColor";
11
+ static _customSecondaryColorMeta = "rockMod:customSecondaryColor";
12
+ static _vehicleModsMeta = "rockMod:vehicleMods";
13
+ static _neonEnabledMeta = "rockMod:neonEnabled";
14
+ static _neonColorMeta = "rockMod:neonColor";
15
+ static _windowTintMeta = "rockMod:windowTint";
16
+ static _wheelTypeMeta = "rockMod:wheelType";
12
17
  _ccmpVehicle;
13
18
  _onDestroy;
19
+ _mods = new Map();
20
+ _customPrimaryColor = new utils_1.RGBA(0, 0, 0);
21
+ _customSecondaryColor = new utils_1.RGBA(0, 0, 0);
14
22
  get id() {
15
23
  return this._ccmpVehicle.id;
16
24
  }
@@ -35,31 +43,32 @@ class CCMPVehicle extends CCMPEntity_1.CCMPEntity {
35
43
  return new Vectors_1.Vector3D(r.x, r.y, r.z);
36
44
  }
37
45
  get bodyHealth() {
38
- return notImplemented("CCMPVehicle.bodyHealth");
46
+ return this._ccmpVehicle.bodyHealth;
39
47
  }
40
48
  get engineHealth() {
41
- return notImplemented("CCMPVehicle.engineHealth");
49
+ return this._ccmpVehicle.engineHealth;
42
50
  }
43
51
  get numberPlate() {
44
52
  return this._ccmpVehicle.numberPlateText;
45
53
  }
46
54
  get isLocked() {
47
- return notImplemented("CCMPVehicle.isLocked");
55
+ const lockState = this._ccmpVehicle.lockState;
56
+ return lockState !== 0 && lockState !== 1;
48
57
  }
49
58
  get isDead() {
50
- return notImplemented("CCMPVehicle.isDead");
59
+ return !this.isExists || this.bodyHealth <= 0;
51
60
  }
52
61
  get primaryColor() {
53
- return notImplemented("CCMPVehicle.primaryColor");
62
+ return this._ccmpVehicle.primaryColor;
54
63
  }
55
64
  get secondaryColor() {
56
- return notImplemented("CCMPVehicle.secondaryColor");
65
+ return this._ccmpVehicle.secondaryColor;
57
66
  }
58
67
  get customPrimaryColor() {
59
- return notImplemented("CCMPVehicle.customPrimaryColor");
68
+ return this._customPrimaryColor;
60
69
  }
61
70
  get customSecondaryColor() {
62
- return notImplemented("CCMPVehicle.customSecondaryColor");
71
+ return this._customSecondaryColor;
63
72
  }
64
73
  get driver() {
65
74
  const ccmpDriver = this._ccmpVehicle.driver;
@@ -84,6 +93,7 @@ class CCMPVehicle extends CCMPEntity_1.CCMPEntity {
84
93
  super();
85
94
  this._ccmpVehicle = options.ccmpVehicle;
86
95
  this._onDestroy = options.onDestroy;
96
+ this._restoreCompatibilityState();
87
97
  }
88
98
  destroy() {
89
99
  if (!this._ccmpVehicle.isExists)
@@ -103,11 +113,11 @@ class CCMPVehicle extends CCMPEntity_1.CCMPEntity {
103
113
  setRotation(value) {
104
114
  this._ccmpVehicle.rotation = { x: value.x, y: value.y, z: value.z };
105
115
  }
106
- setBodyHealth(_value) {
107
- notImplemented("CCMPVehicle.setBodyHealth");
116
+ setBodyHealth(value) {
117
+ this._ccmpVehicle.bodyHealth = value;
108
118
  }
109
- setEngineHealth(_value) {
110
- notImplemented("CCMPVehicle.setEngineHealth");
119
+ setEngineHealth(value) {
120
+ this._ccmpVehicle.engineHealth = value;
111
121
  }
112
122
  setEngineOn(value) {
113
123
  this._ccmpVehicle.engineOn = value;
@@ -115,47 +125,80 @@ class CCMPVehicle extends CCMPEntity_1.CCMPEntity {
115
125
  setNumberPlate(value) {
116
126
  this._ccmpVehicle.numberPlateText = value;
117
127
  }
118
- setLocked(_value) {
119
- notImplemented("CCMPVehicle.setLocked");
128
+ setLocked(value) {
129
+ this._ccmpVehicle.lockState = value ? 2 : 1;
120
130
  }
121
- setPrimaryColor(_value) {
122
- notImplemented("CCMPVehicle.setPrimaryColor");
131
+ setPrimaryColor(value) {
132
+ this._ccmpVehicle.primaryColor = value;
123
133
  }
124
- setSecondaryColor(_value) {
125
- notImplemented("CCMPVehicle.setSecondaryColor");
134
+ setSecondaryColor(value) {
135
+ this._ccmpVehicle.secondaryColor = value;
126
136
  }
127
- setCustomPrimaryColor(_value) {
128
- notImplemented("CCMPVehicle.setCustomPrimaryColor");
137
+ setCustomPrimaryColor(value) {
138
+ this._customPrimaryColor = this._toRgba(value);
139
+ this._setCompatibilityMeta(CCMPVehicle._customPrimaryColorMeta, this._customPrimaryColor);
129
140
  }
130
- setCustomSecondaryColor(_value) {
131
- notImplemented("CCMPVehicle.setCustomSecondaryColor");
141
+ setCustomSecondaryColor(value) {
142
+ this._customSecondaryColor = this._toRgba(value);
143
+ this._setCompatibilityMeta(CCMPVehicle._customSecondaryColorMeta, this._customSecondaryColor);
132
144
  }
133
- setMod(_modType, _modIndex) {
134
- notImplemented("CCMPVehicle.setMod");
145
+ setMod(modType, modIndex) {
146
+ this._mods.set(Math.trunc(modType), Math.trunc(modIndex));
147
+ this._setCompatibilityMeta(CCMPVehicle._vehicleModsMeta, Object.fromEntries(this._mods));
135
148
  }
136
- getMod(_modType) {
137
- return notImplemented("CCMPVehicle.getMod");
149
+ getMod(modType) {
150
+ return this._mods.get(Math.trunc(modType)) ?? -1;
138
151
  }
139
- setNeonEnabled(_enabled) {
140
- notImplemented("CCMPVehicle.setNeonEnabled");
152
+ setNeonEnabled(enabled) {
153
+ this._setCompatibilityMeta(CCMPVehicle._neonEnabledMeta, enabled);
141
154
  }
142
- setNeonColor(_r, _g, _b) {
143
- notImplemented("CCMPVehicle.setNeonColor");
155
+ setNeonColor(r, g, b) {
156
+ this._setCompatibilityMeta(CCMPVehicle._neonColorMeta, new utils_1.RGBA(r, g, b));
144
157
  }
145
- setWindowTint(_tintType) {
146
- notImplemented("CCMPVehicle.setWindowTint");
158
+ setWindowTint(tintType) {
159
+ this._setCompatibilityMeta(CCMPVehicle._windowTintMeta, Math.trunc(tintType));
147
160
  }
148
- setWheelType(_wheelType) {
149
- notImplemented("CCMPVehicle.setWheelType");
161
+ setWheelType(wheelType) {
162
+ this._setCompatibilityMeta(CCMPVehicle._wheelTypeMeta, Math.trunc(wheelType));
150
163
  }
151
164
  setPlateType(plateType) {
152
165
  this._ccmpVehicle.numberPlateType = plateType;
153
166
  }
154
167
  explode() {
155
- notImplemented("CCMPVehicle.explode");
168
+ this._ccmpVehicle.bodyHealth = 0;
169
+ this._ccmpVehicle.engineHealth = -4000;
170
+ this._ccmpVehicle.engineOn = false;
156
171
  }
157
172
  repair() {
158
- notImplemented("CCMPVehicle.repair");
173
+ this._ccmpVehicle.bodyHealth = 1000;
174
+ this._ccmpVehicle.engineHealth = 1000;
175
+ }
176
+ _restoreCompatibilityState() {
177
+ this._customPrimaryColor = this._readColorMeta(CCMPVehicle._customPrimaryColorMeta);
178
+ this._customSecondaryColor = this._readColorMeta(CCMPVehicle._customSecondaryColorMeta);
179
+ const mods = this._ccmpVehicle.getStreamSyncedMeta(CCMPVehicle._vehicleModsMeta);
180
+ if (!mods || typeof mods !== "object")
181
+ return;
182
+ for (const [key, value] of Object.entries(mods)) {
183
+ const modType = Number(key);
184
+ const modIndex = Number(value);
185
+ if (Number.isFinite(modType) && Number.isFinite(modIndex)) {
186
+ this._mods.set(Math.trunc(modType), Math.trunc(modIndex));
187
+ }
188
+ }
189
+ }
190
+ _readColorMeta(key) {
191
+ const value = this._ccmpVehicle.getStreamSyncedMeta(key);
192
+ if (!value || typeof value !== "object") {
193
+ return new utils_1.RGBA(0, 0, 0);
194
+ }
195
+ return new utils_1.RGBA(Number(value.r) || 0, Number(value.g) || 0, Number(value.b) || 0, value.a);
196
+ }
197
+ _setCompatibilityMeta(key, value) {
198
+ this._ccmpVehicle.setStreamSyncedMeta(key, value);
199
+ }
200
+ _toRgba(value) {
201
+ return new utils_1.RGBA(value.r, value.g, value.b, value.a);
159
202
  }
160
203
  }
161
204
  exports.CCMPVehicle = CCMPVehicle;
@@ -2,4 +2,6 @@ import { type IWorldObject, type IWorldObjectOptions } from "../worldObject";
2
2
  export interface IColshapeOptions extends IWorldObjectOptions {
3
3
  }
4
4
  export interface IColshape extends IWorldObject {
5
+ getNetData(name: string): unknown;
6
+ setNetData(name: string, value: unknown): void;
5
7
  }
@@ -3,5 +3,8 @@ import { MockWorldObject, type IMockWorldObjectOptions } from "../worldObject/Mo
3
3
  export interface IMockColshapeOptions extends IMockWorldObjectOptions {
4
4
  }
5
5
  export declare abstract class MockColshape extends MockWorldObject implements IColshape {
6
+ private readonly _netData;
6
7
  protected constructor(options: IMockColshapeOptions);
8
+ getNetData(name: string): unknown;
9
+ setNetData(name: string, value: unknown): void;
7
10
  }
@@ -3,8 +3,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MockColshape = void 0;
4
4
  const MockWorldObject_1 = require("../worldObject/MockWorldObject");
5
5
  class MockColshape extends MockWorldObject_1.MockWorldObject {
6
+ _netData;
6
7
  constructor(options) {
7
8
  super(options);
9
+ this._netData = new Map();
10
+ }
11
+ getNetData(name) {
12
+ return this._netData.get(name);
13
+ }
14
+ setNetData(name, value) {
15
+ this._netData.set(name, value);
8
16
  }
9
17
  }
10
18
  exports.MockColshape = MockColshape;