GTA Vice City > Программирование
Расширение классов
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, допустим добавить "голод". Да и просто понимать, как сделано, может где еще пригодится. Форум-то для того и нужен, чтобы научиться, а не только брать чужое. Если будет желание, опиши хотя бы последовательность действий, хотя и за твой пример уже спасибо.
Навигация
Перейти к полной версии