• Из-за обновления GTA 5 (был добавлен новый патч) может временно не работать вход в RAGE Multiplayer.

    Ошибка: Ваша версия Grand Theft Auto V не поддерживается RAGE Multiplayer.
    ERROR: Your game version is not supported by RAGE Multiplayer.

    Данная ошибка говорит о том, что GTA V обновилась до новой версии (GTA Online тоже). Вам необходимо обновить саму игру в главном меню вашего приложения (Steam / Epic Games / Rockstar Games).
    Если после этого RAGE:MP все равно не работает - вам нужно дождаться выхода патча для самого мультиплеера (обычно это занимает от нескольких часов до нескольких дней).

    Новости и апдейты Rockstar Games - https://www.rockstargames.com/newswire/
    Статус всех служб для Rockstar Games Launcher и поддерживаемых игр: https://support.rockstargames.com/ru/servicestatus


    Grand Theft Auto 5 (+ GTA Online) последний раз были обновлены:

Помощь с предметом в руках

Ruds

Новый участник
28 Дек 2022
10
1
5
Помощь с предметом в руках заранее спасибо за помощь <3

изображение_2022-12-28_230906406.png

Скриншот 28-12-2022 231017.jpg
код самой работы

Код:
import objectsList from '../data/objects';

class Objects {
    hasObject(entity: EntityMp, name: string) {
        const data = objectsList[name];
        const object = entity.getVariable('attachedObject');

        return data && object?.model === data.model;
    }

    attach(entity: EntityMp, name: string) {
        const object = objectsList[name];
        if (!object || !entity) return;

        entity.setVariable('attachedObject', object);
        mp.players.call('attachObject', [entity]);
    }

    detach(entity: EntityMp) {
        if (!entity) return;

        entity.setVariable('attachedObject', null);
        mp.players.call('detachObject', [entity]);
    }
}

export default new Objects();

Код:
export default {
    pickaxe: {
        bone: 73,
        model: 'prop_tool_pickaxe',
        x: 0.085,
        y: -0.3,
        z: 0.0,
        rx: -90.0,
        ry: 0.0,
        rz: 0.0
    },
    vehicleBox: {
        bone: 'forks_attach',
        model: 'prop_box_wood07a',
        x: 0,
        y: 0.075,
        z: 0.075,
        rx: 0,
        ry: 0,
        rz: 90
    },
    woodenBox: {
        bone: 48,
        model: 'hei_prop_heist_wooden_box',
        x: 0.0,
        y: -0.3,
        z: 0.3,
        rx: -45.0,
        ry: 20.0,
        rz: 120.0
    },
    rod: {
        bone: 60309,
        model: 'prop_fishing_rod_01',
        x: 0.03,
        y: 0,
        z: 0.02,
        rx: 0,
        ry: 0,
        rz: 50
    },
    phone: {
        bone: 28422,
        model: 'p_cs_cam_phone',
        x: 0,
        y: 0,
        z: 0,
        rx: 0,
        ry: 0,
        rz: 30
    }
};
 

Mi-Zaft

Гений
VIP
9 Окт 2020
1,733
437
175
И в чём проблема поменять координаты?
 

XDeveluxe

⚡️BackEnd Developer
Команда форума
Moderator
High developer
BackEnd developer
30 Авг 2021
2,766
1,574
211
28
координаты верные на 0.3.7 всё прекрасно работало
Как видишь, они неверные.
Берёшь свои:

Код:
woodenBox: {
        bone: 48,
        model: 'hei_prop_heist_wooden_box',
        x: 0.0,
        y: -0.3,
        z: 0.3,
        rx: -45.0,
        ry: 20.0,
        rz: 120.0
    },
И либо подбираешь их, либо создаёшь версию аттача, где ты можешь двигать объект.
 

Ruds

Новый участник
28 Дек 2022
10
1
5
персонаж при входе в маркер даже не берёт коробку она стоит на одном месте хоть персонаж будет в другой стороне карты коробка будет стоять на этом же месте как и на скрине
 

XDeveluxe

⚡️BackEnd Developer
Команда форума
Moderator
High developer
BackEnd developer
30 Авг 2021
2,766
1,574
211
28
персонаж при выходе в маркер даже не берёт коробку она стоит на одном месте хоть персонаж будет в другой стороне карты коробка будет стоять на этом же месте как и на скрине
В таком случае твой код attachObject не отрабатывает, потому что модель не успевает получить handle на клиентской стороне.
Клиентский код ты не прикрепил.
 

Ruds

Новый участник
28 Дек 2022
10
1
5
Клинетка
Код:
import * as rpc from 'rage-rpc';
import objects from '../configs/action-objects';

const localPlayer = mp.players.local;

class Actions {
    private active = false;

    constructor() {
        this.createObjects();
        this.subscribeToEvents();
    }

    get isActive() {
        return this.active;
    }

    private start(player: PlayerMp, object: typeof objects[0]) {
        if (this.active && localPlayer === player) return;

        const { position, heading, anim } = object;

        player.freezePosition(true);
        player.setCollision(false, true);
        player.setHeading(heading);
        player.setCoordsNoOffset(position.x, position.y, position.z, false, false, false);

        mp.game.streaming.requestAnimDict(anim[0] as string);

        while (!mp.game.streaming.hasAnimDictLoaded(anim[0] as string)) {
            mp.game.wait(0);
        }

        if (mp.players.exists(player) && player.handle !== 0) {
            player.taskPlayAnim(
                anim[0] as string,
                anim[1] as string,
                1,
                0,
                -1,
                anim[2] as number,
                1,
                !1,
                !1,
                !1
            );
        }

        if (localPlayer === player) {
            mp.game.ui.notifications.help(
                'Нажмите ~INPUT_LOOK_BEHIND~ чтобы остановить действие'
            );
        }
    }

    private stop(player: PlayerMp) {
        player.freezePosition(false);
        player.setCollision(true, false);
        player.clearTasksImmediately();
    }

    private createObjects() {
        objects.forEach((item, index) => {
            mp.colshapes.create(item.use, 0.5, {
                onEnter: () =>
                    mp.game.ui.notifications.help('Нажмите ~INPUT_CONTEXT~ для взаимодействия'),
                onKeyPress: () => rpc.callServer('setActionObject', index)
            });
        });
    }

    private onStream(entity: EntityMp) {
        if (entity.type === 'player') {
            const object = objects[entity.getVariable('actionObject')];

            if (object) this.start(entity as PlayerMp, object);
        }
    }

    private onChangeData(player: PlayerMp, data: number) {
        if (player.handle === 0) return;

        const object = objects[data];

        if (!object) return this.stop(player);

        this.start(player, object);

        if (mp.players.local.handle === player.handle) {
            this.active = true;
        }
    }

    private subscribeToEvents() {
        mp.events.subscribeToDefault({
            entityStreamIn: this.onStream.bind(this)
        });

        mp.events.subscribeToData({
            actionObject: this.onChangeData.bind(this)
        });

        mp.keys.bind(67, false, () => {
            if (!this.active || mp.gui.cursor.visible) return;

            this.active = false;

            rpc.callServer('setActionObject', null);

            this.stop(player);
        });
    }
}

export default new Actions();
Код:
import { isNumber } from 'lodash';

type ObjectData = {
    bone: any;
    model: string;
    x: number;
    y: number;
    z: number;
    rx: number;
    ry: number;
    rz: number;
};

class Objects {
    private objects: {
        player: Map<number, ObjectMp>;
        vehicle: Map<number, ObjectMp>;
    };

    constructor() {
        this.objects = {
            player: new Map(),
            vehicle: new Map()
        };

        this.subscribeToEvents();
    }

    private add(type: string, id: number, object: ObjectMp) {
        const objects = this.objects[type];

        if (objects) objects.set(id, object);
    }

    private get(type: string, id: number) {
        const objects = this.objects[type];

        return objects ? objects.get(id) : null;
    }

    private delete(type: string, id: number) {
        const object = this.get(type, id);

        if (!mp.objects.exists(object)) return;

        object.destroy();
        this.objects[type].delete(id);
    }

    private attach(entity: EntityMp) {
        if (!entity) return;

        const id = entity.remoteId;

        if (this.get(entity.type, id)) return;

        const data: ObjectData = entity.getVariable('attachedObject');

        if (!data || !data.model) return;

        const object = mp.objects.new(mp.game.joaat(data.model), entity.position, {
            rotation: new mp.Vector3(0, 0, 0),
            alpha: 255,
            dimension: entity.dimension
        });
        if (!mp.objects.exists(object)) return;

        const bone = isNumber(data.bone) ? data.bone : entity.getBoneIndexByName(data.bone);

        object.attachTo(
            entity.handle,
            bone,
            data.x,
            data.y,
            data.z,
            data.rx,
            data.ry,
            data.rz,
            true,
            true,
            false,
            false,
            0,
            true
        );

        this.add(entity.type, id, object);
    }

    private detach(entity: EntityMp) {
        if (!entity) return;

        this.delete(entity.type, entity.remoteId);
    }

    private subscribeToEvents() {
        mp.events.add({
            attachObject: this.attach.bind(this),
            detachObject: this.detach.bind(this)
        });
    }
}

export default new Objects();
 

XDeveluxe

⚡️BackEnd Developer
Команда форума
Moderator
High developer
BackEnd developer
30 Авг 2021
2,766
1,574
211
28
Либо я слепой, либо я не вижу здесь ивента attachObject, который вызывается у тебя с сервера.
 

Ruds

Новый участник
28 Дек 2022
10
1
5
вот ивент на клиентки который вызывает с сервера attachObject
Код:
private subscribeToEvents() {
        mp.events.add({
            attachObject: this.attach.bind(this),
            detachObject: this.detach.bind(this)
        });
    }
 

XDeveluxe

⚡️BackEnd Developer
Команда форума
Moderator
High developer
BackEnd developer
30 Авг 2021
2,766
1,574
211
28
вот ивент на клиентки который вызывает с сервера attachObject
Код:
private subscribeToEvents() {
        mp.events.add({
            attachObject: this.attach.bind(this),
            detachObject: this.detach.bind(this)
        });
    }
Значит действительно слепой :super_klass:
Ну, как минимум стоит проверить, что они точно регистрируются.
После этого, полагаю, можно начинать дебажить саму функцию.
 

Ruds

Новый участник
28 Дек 2022
10
1
5
а не подскажешь как проверить на 100% то что они регистрируются
 

XDeveluxe

⚡️BackEnd Developer
Команда форума
Moderator
High developer
BackEnd developer
30 Авг 2021
2,766
1,574
211
28
а не подскажешь как проверить на 100% то что они регистрируются
Та самым простым дедовским способом - пиши в первой же строке функции
JavaScript:
mp.gui.chat.push("test");
Когда с сервера придёт этот ивент (то есть ты так же получаешь ящик, чтобы этот ивент сработал), если сообщение в чате появляется - значит ивент зарегистрирован и работает, проблема уже не в этом. Удаляешь это тестовое сообщение и идёшь дебажить. Можно использовать всё тот же дедовский метод - помогал мне миллион тысяч раз за всё то время, что я занимаюсь разработкой.

Ставишь до и после каждого return'а по одному тестовому сообщению, добавляя какие-нибудь цифры, например:

JavaScript:
mp.gui.chat.push("1");
mp.gui.chat.push("2");
mp.gui.chat.push("3");
И так же идёшь вызывать этот ивент, смотришь на каком моменте цифры больше не вызываются, после какой проверки функция дальше не работает.
Ну и либо понимаешь сам, почему так, либо приходишь сюда и возможно кто-то сможет что-то подсказать.
 

Ruds

Новый участник
28 Дек 2022
10
1
5
ещё можете подсказать микрофон в худе передаёт статус вкл/выкл черезе rpc.callBrowsers когда заходишь допустим в телефон и включаешь микро он включается но выскакивает такая ошибка связана с худом то есть со статусом микро в худе
Код:
setMicStatus(status: boolean, speaker = false) {
        rpc.callBrowsers('HUD-SetMicStatus', { status, speaker });
    }


Скриншот 29-12-2022 094902.jpg
Скриншот 29-12-2022 100626.jpg
 
Последнее редактирование:

Ruds

Новый участник
28 Дек 2022
10
1
5
когда делаю triggerEvent ошибка убирается но в худе статус микрофона постоянно выключен

Код:
setMicStatus(status: boolean, speaker = false) {
        this.triggerEvent('HUD-SetMicStatus', { status, speaker });
    }
Код:
private triggerEvent(name: string, data: any) {
        if (!mp.browsers.hud) return;

        mp.events.callBrowser(name, data, false);
    }
Код:
interface EventMpPool {
    subscribe(events: { [name: string]: (...args) => any }): void;
    subscribeToDefault(events: { [name: string]: (...args) => void }): void;
    callBrowser(event: string, args?: any, pending?: boolean, browser?: BrowserMp ): Promise<any>;
    
    subscribeToData(events: {
        [name: string]: (entity: EntityMp, data: any, oldData?: any) => void;
    }): void;
}
interface BrowserMpPool {
    readonly hud: boolean;
    showPage(
        page: string,
        data?: { [name: string]: any },
        cursor?: boolean,
        freeze?: boolean
    ): void;
    hidePage(page?: string): void;
    setHideBind(handler: Function, key?: string): void;
}
 

kenz

Гуру
BackEnd developer
5 Авг 2022
160
129
93
когда делаю triggerEvent ошибка убирается но в худе статус микрофона постоянно выключен

Код:
setMicStatus(status: boolean, speaker = false) {
        this.triggerEvent('HUD-SetMicStatus', { status, speaker });
    }
Код:
private triggerEvent(name: string, data: any) {
        if (!mp.browsers.hud) return;

        mp.events.callBrowser(name, data, false);
    }
Код:
interface EventMpPool {
    subscribe(events: { [name: string]: (...args) => any }): void;
    subscribeToDefault(events: { [name: string]: (...args) => void }): void;
    callBrowser(event: string, args?: any, pending?: boolean, browser?: BrowserMp ): Promise<any>;
   
    subscribeToData(events: {
        [name: string]: (entity: EntityMp, data: any, oldData?: any) => void;
    }): void;
}
interface BrowserMpPool {
    readonly hud: boolean;
    showPage(
        page: string,
        data?: { [name: string]: any },
        cursor?: boolean,
        freeze?: boolean
    ): void;
    hidePage(page?: string): void;
    setHideBind(handler: Function, key?: string): void;
}
ну так понятно, что работать не будет. ты же уберая triggerEvent - убераешь вызов этого ивента