Автор Тема: Смена текстур транспорта  (Прочитано 654 раз)

Оффлайн xanser

  • Главный Модератор
  • Опытный
  • *****
  • Сообщений: 498
  • Репутация: +43/-0
  • Есть такая профессия - на работе сидеть
    • Просмотр профиля
Смена текстур транспорта
« : Октябрь 18, 2017, 03:13:50 pm »
Предлагаю запилить мод для смены скинов машин или поделиться соображениями, возможно это или нет. Вот, что мне удалось. Во вложении вторая текстура для танка rhino2.txd для gta3.img и тестовая asi-шка, которая меняет скин танка до его первого появления нажатием на Tab, для проверки после этого можно ввести например чит-код panzer. Проблема в том, что текстуру танка пока удалось сменить только до появления первой модели, потом все модели создаются такие же. Если первым создать стандартный танк, то мой код уже не оказывает эффекта. Нужна помощь в поиске причины. Хотелось бы сделать смену на лету.



Почему это кажется возможным. Я позаимствовал функции из этого блока: 0x40AA60 CStreaming::RequestSpecialModel, здесь меняются модели и текстуры для специальных актеров для миссий:
109, special01, generic, CIVMALE, STAT_STD_MISSION, man, 0, null, 9,9
110, special02, generic, CIVMALE, STAT_STD_MISSION, man, 0, null, 9,9
......................................
129, special21, generic, CIVMALE, STAT_STD_MISSION, man, 0, null, 9,9

Получается, что можно на один id вешать любые модели и текстуры, в перспективе кажется возможным таким способом расширить количество транспортных средств, используя одни и те же номера.
Что касается скинов, то мне видится возможным внедрение кода с чередующимися текстурами до отрисовки отдельной машины в функцию 0x589AE0 CAutomobile::PreRender

Вот примеры практического применения с использованием этого кода, но пока неодновременные полуфейки:

« Последнее редактирование: Октябрь 18, 2017, 05:53:41 pm от xanser »

Оффлайн kenking

  • Новичек
  • **
  • Сообщений: 143
  • Репутация: +5/-0
    • Просмотр профиля
Re: Смена текстур транспорта
« Ответ #1 : Октябрь 18, 2017, 06:48:04 pm »
Мне тоже интересно можно ли нормально реализовать возможность установки скинов на транспорт в VC и GTA3.
Протестировал плагин, перенёс код для своих экспериментов на основу plugin-sdk. Что интересно - значение m_nTxdIndex перезаписывается при нажатии клавиш, а скин устанавливается только один. Первоначальный опять не поставить.
Код: C++
  1. #include "plugin_vc.h"
  2. #include "extensions\KeyCheck.h"
  3. #include "game_vc\CModelInfo.h"
  4. #include "game_vc\CFont.h"
  5.  
  6. using namespace plugin;
  7.  
  8. class MyPlugin {
  9. public:
  10.     MyPlugin() {
  11.  
  12.         Events::drawingEvent += [] {
  13.             CFont::SetScale(0.5f, 1.0f);
  14.             CFont::SetColor(CRGBA(255, 255, 255, 255));
  15.             CFont::SetJustifyOn();
  16.             CFont::SetFontStyle(2);
  17.             CFont::SetPropOn();
  18.             CFont::SetWrapx(600.0f);
  19.             wchar_t text[32];
  20.             swprintf(text, L"TxdIndex %d", CModelInfo::ms_modelInfoPtrs[162]->m_nTxdIndex);
  21.             CFont::PrintString(10.0f, 30.0f, text);
  22.         };
  23.        
  24.         Events::gameProcessEvent += [] {
  25.             KeyCheck::Update();
  26.             if (KeyCheck::CheckWithDelay(VK_TAB, 1000)) {
  27.                 CModelInfo::ms_modelInfoPtrs[162]->ClearTexDictionary();
  28.                 CModelInfo::ms_modelInfoPtrs[162]->SetTexDictionary("rhino2");
  29.             }
  30.             if (KeyCheck::CheckWithDelay(110, 1000)) {
  31.                 CModelInfo::ms_modelInfoPtrs[162]->ClearTexDictionary();
  32.                 CModelInfo::ms_modelInfoPtrs[162]->SetTexDictionary("rhino");
  33.             }
  34.         };
  35.     }
  36. } myPlugin;

Оффлайн DK

  • Новичек
  • **
  • Сообщений: 221
  • Репутация: +312/-0
    • dk22pac
    • Просмотр профиля
Re: Смена текстур транспорта
« Ответ #2 : Октябрь 19, 2017, 12:18:25 am »
Вариант с эвентом CVehicle::Render не прокатит - прозрачные части транспорта рендерятся дополнительно, позже (думаю, понятно, почему). Такой себе отложенный рендер.
Но можно внедриться чуть "глобальнее", и отловить момент когда все части транспорта уже отрендерены.
Либо внедриться в рендер атомика (но тогда надо будет как-то сохранять указатель на авто в атомике, а для этого надо будет создавать своё расширение для атомика).
Другая проблема - для того, чтобы текстура нормально выглядела на транспорте, надо заранее подготовить хорошую развертку (UV координаты). Вроде оригинальные авто используют текстуру white, и я не уверен, что там вменяемая развертка.

Кстати, динамические текстуры есть в San Andreas - вспомните покраски или то же переключение текстуры vehiclelights_on/off (этот метод был успешно использован и в ImVehFt).
« Последнее редактирование: Октябрь 23, 2017, 08:49:29 pm от DK »
Plugin-SDK https://github.com/DK22Pac/plugin-sdk

Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv

Оффлайн xanser

  • Главный Модератор
  • Опытный
  • *****
  • Сообщений: 498
  • Репутация: +43/-0
  • Есть такая профессия - на работе сидеть
    • Просмотр профиля
Re: Смена текстур транспорта
« Ответ #3 : Октябрь 19, 2017, 04:21:50 am »
Может тогда поэкспериментировать пока на спец. актерах с id 109-129, посоздавать одновременно на один номер разные модели или текстуры. Как поведет себя игра, создаст разных или одинаковых, и что нужно, чтобы происходила смена. Между миссиями это же как-то происходит. Возможно придется удалить созданные модели, чтобы появилась новая, тогда это поставит крест на всей задумке. А может достаточно поменять какой-то флаг или что-то переинициализировать.

Оффлайн DK

  • Новичек
  • **
  • Сообщений: 221
  • Репутация: +312/-0
    • dk22pac
    • Просмотр профиля
Re: Смена текстур транспорта
« Ответ #4 : Октябрь 23, 2017, 08:49:10 pm »
Зачем делать наугад? Надеяться, что сработает?

Вот небольшой пример - показывает, как динамически менять текстуры трансорта.


Код: C++
  1. #include "plugin.h"
  2. #include "common.h"
  3. #include <map>
  4.  
  5. using namespace plugin;
  6.  
  7. class VehicleTextures {
  8. public:
  9.     VehicleTextures() {
  10.         static CdeclEvent<AddressList<0x4C9ED1, H_CALL, 0x4C9F23, H_CALL, 0x4CA10D, H_CALL, 0x5813D1, H_CALL>,
  11.             PRIORITY_BEFORE, ArgPickN<CEntity*, 0>, void(CEntity*)> myOnRenderOneNonRoad;
  12.  
  13.         static std::map<RpMaterial*, RwTexture *> originalTextures;
  14.  
  15.         myOnRenderOneNonRoad.before += [](CEntity *entity) {
  16.             if (KeyPressed('Z') && entity == FindPlayerVehicle()) {
  17.                 CVehicle *vehicle = reinterpret_cast<CVehicle *>(entity);
  18.                 RpClumpForAllAtomics(vehicle->m_pRwClump, [](RpAtomic *atomic, void *data) {
  19.                     RpGeometryForAllMaterials(atomic->geometry, [](RpMaterial *material, void *data) {
  20.                         if (originalTextures.find(material) == originalTextures.end())
  21.                             originalTextures[material] = material->texture;
  22.                         material->texture = *reinterpret_cast<RwTexture **>(0x77FA58);
  23.                         return material;
  24.                     }, nullptr);
  25.                     return atomic;
  26.                 }, nullptr);
  27.             }
  28.         };
  29.  
  30.         myOnRenderOneNonRoad.after += [](CEntity *) {
  31.             if (originalTextures.size() > 0) {
  32.                 for (auto &i : originalTextures)
  33.                     i.first->texture = i.second;
  34.                 originalTextures.clear();
  35.             }
  36.         };
  37.     }
  38. } vehicleTextures;

По нажатию на Z транспорт игрока будет использовать текстуру waterclear256 (0x77FA58).

Plugin-SDK https://github.com/DK22Pac/plugin-sdk

Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv

Оффлайн xanser

  • Главный Модератор
  • Опытный
  • *****
  • Сообщений: 498
  • Репутация: +43/-0
  • Есть такая профессия - на работе сидеть
    • Просмотр профиля
Re: Смена текстур транспорта
« Ответ #5 : Октябрь 24, 2017, 05:19:26 am »
Радует, что это возможно. Спасибо за код, буду разбираться.

Оффлайн kenking

  • Новичек
  • **
  • Сообщений: 143
  • Репутация: +5/-0
    • Просмотр профиля
Re: Смена текстур транспорта
« Ответ #6 : Октябрь 24, 2017, 03:51:03 pm »
Если в принципе это возможно, то надо продумать, как это лучше реализовать. Возможен такой вариант - допустим, нужные детали модели авто имеют текстуру remap, также в txd файле этой модели имеются текстуры remap1 (remap2, remap3 и remap4), в файле .dat записаны ID модели и количество сменных текстур remap, сверяем модели в трафике с моделью из .dat, находим материал (текстуру) remap, выбираем из имеющихся сменных текстур и заменяем? И наверно надо к структуре "прикрепить" какую-то переменную, чтобы отслеживать какая текстура используется? Так можно реализовать показанным выше примером или есть способ лучше? 

Оффлайн DK

  • Новичек
  • **
  • Сообщений: 221
  • Репутация: +312/-0
    • dk22pac
    • Просмотр профиля
Re: Смена текстур транспорта
« Ответ #7 : Октябрь 24, 2017, 04:56:56 pm »
Лучше всего - отделить каждый 'remap' в свой txd-файл, как это сделано в SA.
Иначе получится, что в загруженном txd у тебя будет куча неиспользуемых текстур.
Plugin-SDK https://github.com/DK22Pac/plugin-sdk

Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv