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

Оффлайн xanser

  • Главный Модератор
  • Постоялец
  • *****
  • Сообщений: 598
  • Репутация: +92/-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

  • Новичок
  • **
  • Сообщений: 237
  • Репутация: +16/-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

  • Новичок
  • **
  • Сообщений: 234
  • Репутация: +328/-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

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

Оффлайн DK

  • Новичок
  • **
  • Сообщений: 234
  • Репутация: +328/-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

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

Оффлайн kenking

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

Оффлайн DK

  • Новичок
  • **
  • Сообщений: 234
  • Репутация: +328/-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

Оффлайн xanser

  • Главный Модератор
  • Постоялец
  • *****
  • Сообщений: 598
  • Репутация: +92/-0
  • Есть такая профессия - на работе сидеть
    • Просмотр профиля
Re: Смена текстур транспорта
« Ответ #8 : Апрель 06, 2019, 01:52:44 pm »
Немного изменил первоначальный код, теперь работает. Бывают правда проблемы при выходе из игры с очисткой материалов. Последний вариант во вложении. Смена скинов для новых танков клавишами 1-4. Небольшая демонстрация:

https://youtu.be/q2UE8aXzdso

« Последнее редактирование: Январь 29, 2020, 11:50:24 am от xanser »

Оффлайн Shagg_E

  • Администратор
  • Постоялец
  • *****
  • Сообщений: 705
  • Репутация: +24/-4
  • Изобретательный Рукожопъ
    • Просмотр профиля
    • NewRockstar
Re: Смена текстур транспорта
« Ответ #9 : Апрель 06, 2019, 08:12:33 pm »
Крутяк! Пригодится, спасибо!

Оффлайн xanser

  • Главный Модератор
  • Постоялец
  • *****
  • Сообщений: 598
  • Репутация: +92/-0
  • Есть такая профессия - на работе сидеть
    • Просмотр профиля
Re: Смена текстур транспорта
« Ответ #10 : Апрель 07, 2019, 11:44:52 am »
Вариант пока так побаловаться. В такой виде его оставлять нельзя. Есть неприятные последствия.

Оффлайн Shagg_E

  • Администратор
  • Постоялец
  • *****
  • Сообщений: 705
  • Репутация: +24/-4
  • Изобретательный Рукожопъ
    • Просмотр профиля
    • NewRockstar
Re: Смена текстур транспорта
« Ответ #11 : Апрель 07, 2019, 11:56:24 am »
Например?(я просто ща затестить не могу)

Оффлайн xanser

  • Главный Модератор
  • Постоялец
  • *****
  • Сообщений: 598
  • Репутация: +92/-0
  • Есть такая профессия - на работе сидеть
    • Просмотр профиля
Re: Смена текстур транспорта
« Ответ #12 : Апрель 07, 2019, 05:05:54 pm »
Я заметил, что новые текстуры срабатывают в этой функции CStreaming::RequestModel при LoadState == 0. Это объясняет, почему раньше срабатывало только один раз, вот я и обнуляю его каждый раз при смене txd, но добром это не кончится. Из замеченных проблем в игре пока зависания, ошибки при выходе, пропадающие куски карты. Видимо происходит переполнение, связанное с этим классом CStreaming. В общем пока топорный вариант с непредсказуемыми последствиями.

Оффлайн Shagg_E

  • Администратор
  • Постоялец
  • *****
  • Сообщений: 705
  • Репутация: +24/-4
  • Изобретательный Рукожопъ
    • Просмотр профиля
    • NewRockstar
Re: Смена текстур транспорта
« Ответ #13 : Апрель 08, 2019, 02:54:40 am »
А, ну это уже серьезные проблемы. Глянул код.... тут я бессилен))
Если будет что-то по этому поводу - сообщу!

Оффлайн kenking

  • Новичок
  • **
  • Сообщений: 237
  • Репутация: +16/-0
    • Просмотр профиля
Re: Смена текстур транспорта
« Ответ #14 : Июнь 05, 2019, 02:47:13 pm »
Вот небольшой пример - показывает, как динамически менять текстуры транспорта.
По нажатию на Z транспорт игрока будет использовать текстуру waterclear256 (0x77FA58).
А как сделать, чтобы текстура заменялась не на всех материалах, а только на одном нужном, например, с названием remap?
Самостоятельно разобрать не получилось.  >:(