GTA Vice City > Программирование

Расширение классов

(1/2) > >>

xanser:
В этом посте DK показывал пример, как расширить класс, "прикрепив" к нему дополнительные атрибуты. Насколько я понял, существующие пулы при этом не расширяются.

--- Код: C++ ---    #include <plugin.h>         using namespace plugin;         class VehicleExtendedExample {    public:        class VehicleComponents { // Класс, который представляет наши данные (можно сказать, что эти данные "прикрепляются" к структуре транспорта)        public:            RwFrame *m_pDoorLF;            RwFrame *m_pDoorRF;            RwFrame *m_pDoorLR;            RwFrame *m_pDoorRR;                 VehicleComponents(CVehicle *) { // Конструктор этого класса будет вызван при вызове конструктора транспорта (CVehicle::CVehicle)                m_pDoorLF = m_pDoorRF = m_pDoorLR = m_pDoorRR = nullptr; // устанавливаем все указатели в 0            }        };             VehicleExtendedExample() {            static VehicleExtendedData<VehicleComponents> vehComps; // Создаем экземпляр нашего расширения. vehComps - это переменная, через которую мы будем                                                                    // обращаться к нашим данным (используя метод Get(CVehicle *транспорт) )                 Events::vehicleSetModelEvent += [](CVehicle *vehicle, int modelIndex) { // Выполняем нашу функцию, когда игра устанавливает модель транспорту                if (vehicle->m_pRwClump) { // Если создан графический обьект модели (RpClump)                    vehComps.Get(vehicle).m_pDoorLF = CClumpModelInfo::GetFrameFromName(vehicle->m_pRwClump, "door_lf_dummy"); // Находим компоненты в иерархии                    vehComps.Get(vehicle).m_pDoorRF = CClumpModelInfo::GetFrameFromName(vehicle->m_pRwClump, "door_rf_dummy"); // и записываем их в наш класс                    vehComps.Get(vehicle).m_pDoorLR = CClumpModelInfo::GetFrameFromName(vehicle->m_pRwClump, "door_lr_dummy");                    vehComps.Get(vehicle).m_pDoorRR = CClumpModelInfo::GetFrameFromName(vehicle->m_pRwClump, "door_rr_dummy");                }                else // иначе устанавливаём всё в 0                    vehComps.Get(vehicle).m_pDoorLF = vehComps.Get(vehicle).m_pDoorRF = vehComps.Get(vehicle).m_pDoorLR = vehComps.Get(vehicle).m_pDoorRR = nullptr;            };                 Events::vehicleRenderEvent += [](CVehicle *vehicle) { // Выполняем нашу функцию, когда игра рендерит транспорт                if (vehComps.Get(vehicle).m_pDoorLF)                    vehComps.Get(vehicle).m_pDoorLF->modelling.pos.z = 1.0f; // Сдвигаем компонент вверх                if (vehComps.Get(vehicle).m_pDoorRF)                    vehComps.Get(vehicle).m_pDoorRF->modelling.pos.z = 1.0f;                if (vehComps.Get(vehicle).m_pDoorLR)                    vehComps.Get(vehicle).m_pDoorLR->modelling.pos.z = 1.0f;                if (vehComps.Get(vehicle).m_pDoorRR)                    vehComps.Get(vehicle).m_pDoorRR->modelling.pos.z = 1.0f;            };        }    } vehicleExtendedExample;
DK, можешь на простом примере показать общий принцип расширения классов через прикрепление новых атрибутов. К примеру, есть условный класс

--- Код: C++ ---class CVector {public:    float x;    float y;    CVector();} vector2d[100];
И есть, например, пул таких координат по определенному адресу памяти, где идет по порядку vector2d[0].x, veсtor2d[0].y, vector2d[1].x, veсtor2d[1].y, vector2d[2].x, veсtor2d[2].y...
Как к этому классу "прикрепить" еще свою координату float z, чтобы обращаться уже к vector2d.x, vector2d.y, vector3d.Get(vector2d).z и не повредить существующий пул. Пример не связан с игрой.

DK:
xanser, В C++ нет расширения классов в "рантайме", по крайней мере, встроенного в язык (стандарт).
То, что есть в plugin-sdk - это вещь конкретно заточенная под пулы в GTA.
Тут реализация зависит от того, где это надо применить. Если покажешь конкретно - возможно, смогу помочь.

PS vector2d[100] - это не пул, а массив. См. Объектный пул

xanser:
Мне интересен сам используемый прием. Поэтому хотелось пошагово на простом примере сначала понять суть, за счет чего происходит "прикрепление", и какой синтаксис должен быть от начала до конца. Если смотреть пример по CVehicle, там код не полностью приведен в сообщении, для меня остались пробелы в таких местах:

--- Код: C++ ---VehicleComponents(CVehicle *) { // Конструктор этого класса будет вызван при вызове конструктора транспорта (CVehicle::CVehicle)Не очень понятно, почему происходит вызов нового конструктора при вызове стандартного CVehicle::CVehicle

--- Код: C++ ---static VehicleExtendedData<VehicleComponents> vehComps;Не описано, что такое VehicleExtendedData

--- Код: C++ ---vehComps.Get(vehicle).m_pDoorLFКак выглядит функция Get() ?
Видимо ответы в самом sdk, но так тяжело изучать что-то, копая чужой код. Вот и хотелось на отвлеченном примере понять сам принцип, а потом уже идти от простого к сложному.

DK:
Я тебя не совсем понимаю. Если тебе надо это для GTA - почему не использовать готовое решение?

xanser:
Может захочется еще что-то расширить кроме машин, например CPed, допустим добавить "голод". Да и просто понимать, как сделано, может где еще пригодится. Форум-то для того и нужен, чтобы научиться, а не только брать чужое. Если будет желание, опиши хотя бы последовательность действий, хотя и за твой пример уже спасибо.

Навигация

[0] Главная страница сообщений

[#] Следующая страница

Перейти к полной версии