Последние сообщения

Страницы: [1] 2 3 ... 10
1
Общие вопросы / Re: Части Тела
« Последний ответ от Shagg_E Июль 20, 2019, 03:03:02 pm »
Спасибо, очень пригодится, когда вернусь к этому вопросу!
2
Общие вопросы / Re: Части Тела
« Последний ответ от xanser Июль 20, 2019, 07:30:13 am »
Shagg_E, как-то раз по по твоему совету я сделал вид от первого лица в машине, поместив камеру в голову игрока, а саму голову и выступающие части тела скрыл, масштабируя их в ноль. Можно масштабировать и любыми другими коэффициентами. Код у меня такой:

Код: C++
  1. class CPedBody {                       
  2. public:
  3.         RwMatrix * Root;
  4.         RwMatrix * Pelvis;      // 1
  5.         RwMatrix * Spine;       // 17
  6.         RwMatrix * Spine1;
  7.         RwMatrix * Neck;
  8.         RwMatrix * Head;        // 2
  9.         RwMatrix * RClavicle;   // 16
  10.         RwMatrix * RUpperArm;   // 4
  11.         RwMatrix * RForeArm;    // 14
  12.         RwMatrix * RHand;       // 6
  13.         RwMatrix * RFinger;
  14.         RwMatrix * LClavicle;   // 15
  15.         RwMatrix * LUpperArm;   // 3
  16.         RwMatrix * LForeArm;    // 13
  17.         RwMatrix * LHand;       // 5
  18.         RwMatrix * LFinger;
  19.         RwMatrix * LThigh;      // 7
  20.         RwMatrix * LCalf;       // 12
  21.         RwMatrix * LFoot;       // 9
  22.         RwMatrix * RThigh;      // 8
  23.         RwMatrix * RCalf;       // 11
  24.         RwMatrix * RFoot;       // 10
  25.         static DWORD * GetAnimHierarchyFromSkinClump(RwObject *);
  26.         static RwMatrix * RpHAnimHierarchyGetMatrixArray(DWORD *);
  27.         static DWORD RpHAnimIDGetIndex(DWORD *, DWORD);
  28.         bool GetComponents(RwObject *);
  29.         void HideComponent(RwMatrix *);
  30. };
  31.  
  32. enum PED_FRAME {
  33.         PED_FRAME_ROOT = 0,
  34.         PED_FRAME_PELVIS = 1,
  35.         PED_FRAME_SPINE = 2,
  36.         PED_FRAME_SPINE1 = 3,
  37.         PED_FRAME_NECK = 4,
  38.         PED_FRAME_HEAD = 5,
  39.         PED_FRAME_RCLAVICLE = 21,
  40.         PED_FRAME_RUPPER_ARM = 22,
  41.         PED_FRAME_RFORE_ARM = 23,
  42.         PED_FRAME_RHAND = 24,
  43.         PED_FRAME_RFINGER = 25,
  44.         PED_FRAME_LCLAVICLE     = 31,
  45.         PED_FRAME_LUPPER_ARM = 32,
  46.         PED_FRAME_LFORE_ARM     = 33,
  47.         PED_FRAME_LHAND = 34,
  48.         PED_FRAME_LFINGER = 35,
  49.         PED_FRAME_LTHIGH = 41,
  50.         PED_FRAME_LCALF = 42,
  51.         PED_FRAME_LFOOT = 43,
  52.         PED_FRAME_RTHIGH = 51,
  53.         PED_FRAME_RCALF = 52,
  54.         PED_FRAME_RFOOT = 53
  55. };
  56.  
  57. void CPed::PreRender() {
  58.         ((void(__thiscall *)(CPed *))0x4FE4C0)(this);
  59. }
  60.  
  61. DWORD * CPedBody::GetAnimHierarchyFromSkinClump(RwObject * object) {
  62.         return ((DWORD *(__cdecl *)(RwObject *))0x57F250)(object);
  63. }
  64. RwMatrix * CPedBody::RpHAnimHierarchyGetMatrixArray(DWORD * _) {
  65.         return ((RwMatrix *(__cdecl *)(DWORD *))0x646370)(_);
  66. }
  67. DWORD CPedBody::RpHAnimIDGetIndex(DWORD * _1, DWORD _2) {
  68.         return ((DWORD(__cdecl *)(DWORD *, DWORD))0x646390)(_1, _2);
  69. }
  70. bool CPedBody::GetComponents(RwObject * object) {
  71.         DWORD * BodyHierarchy = GetAnimHierarchyFromSkinClump(object);
  72.         RwMatrix * BodyMatrix = RpHAnimHierarchyGetMatrixArray(BodyHierarchy);
  73.         this->Root = &BodyMatrix[RpHAnimIDGetIndex(BodyHierarchy, PED_FRAME_ROOT)];
  74.         this->Pelvis = &BodyMatrix[RpHAnimIDGetIndex(BodyHierarchy, PED_FRAME_PELVIS)];
  75.         this->Spine = &BodyMatrix[RpHAnimIDGetIndex(BodyHierarchy, PED_FRAME_SPINE)];
  76.         this->Spine1 = &BodyMatrix[RpHAnimIDGetIndex(BodyHierarchy, PED_FRAME_SPINE1)];
  77.         this->Neck = &BodyMatrix[RpHAnimIDGetIndex(BodyHierarchy, PED_FRAME_NECK)];
  78.         this->Head = &BodyMatrix[RpHAnimIDGetIndex(BodyHierarchy, PED_FRAME_HEAD)];
  79.         this->RClavicle = &BodyMatrix[RpHAnimIDGetIndex(BodyHierarchy, PED_FRAME_RCLAVICLE)];
  80.         this->RUpperArm = &BodyMatrix[RpHAnimIDGetIndex(BodyHierarchy, PED_FRAME_RUPPER_ARM)];
  81.         this->RForeArm = &BodyMatrix[RpHAnimIDGetIndex(BodyHierarchy, PED_FRAME_RFORE_ARM)];
  82.         this->RHand = &BodyMatrix[RpHAnimIDGetIndex(BodyHierarchy, PED_FRAME_RHAND)];
  83.         this->RFinger = &BodyMatrix[RpHAnimIDGetIndex(BodyHierarchy, PED_FRAME_RFINGER)];
  84.         this->LClavicle = &BodyMatrix[RpHAnimIDGetIndex(BodyHierarchy, PED_FRAME_LCLAVICLE)];
  85.         this->LUpperArm = &BodyMatrix[RpHAnimIDGetIndex(BodyHierarchy, PED_FRAME_LUPPER_ARM)];
  86.         this->LForeArm = &BodyMatrix[RpHAnimIDGetIndex(BodyHierarchy, PED_FRAME_LFORE_ARM)];
  87.         this->LHand = &BodyMatrix[RpHAnimIDGetIndex(BodyHierarchy, PED_FRAME_LHAND)];
  88.         this->LFinger = &BodyMatrix[RpHAnimIDGetIndex(BodyHierarchy, PED_FRAME_LFINGER)];
  89.         this->LThigh = &BodyMatrix[RpHAnimIDGetIndex(BodyHierarchy, PED_FRAME_LTHIGH)];
  90.         this->LCalf = &BodyMatrix[RpHAnimIDGetIndex(BodyHierarchy, PED_FRAME_LCALF)];
  91.         this->LFoot = &BodyMatrix[RpHAnimIDGetIndex(BodyHierarchy, PED_FRAME_LFOOT)];
  92.         this->RThigh = &BodyMatrix[RpHAnimIDGetIndex(BodyHierarchy, PED_FRAME_RTHIGH)];
  93.         this->RCalf = &BodyMatrix[RpHAnimIDGetIndex(BodyHierarchy, PED_FRAME_RCALF)];
  94.         this->RFoot = &BodyMatrix[RpHAnimIDGetIndex(BodyHierarchy, PED_FRAME_RFOOT)];
  95.         return ((this->Head->right.x != 1.0f) || (this->Head->right.y != 0.0f) || (this->Head->right.z != 0.0f) ||
  96.                 (this->Head->up.x != 0.0f) || (this->Head->up.y != 1.0f) || (this->Head->up.z != 0.0f) ||
  97.                 (this->Head->at.x != 0.0f) || (this->Head->at.y != 0.0f) || (this->Head->at.z != 1.0f));
  98. }
  99. void CPedBody::HideComponent(RwMatrix * component) {
  100.         component->right.x = component->right.y = component->right.z = component->up.x = component->up.y = component->up.z = component->at.x = component->at.y = component->at.z = 0.0f;
  101.         component->pos.x = this->Root->pos.x;
  102.         component->pos.y = this->Root->pos.y;
  103.         component->pos.z = this->Root->pos.z;
  104. }

Код: C++
  1. CPedBody PlayerBody;
  2. PlayerBody.GetComponents(PlayerPed->rwObject);  // это в начале и при смене скина

Дальше такой класс:

Код: C++
  1. class PedPreRender {
  2.         static void __fastcall HidePlayerHead(CPed * Ped) {
  3.                 PlayerPed->PreRender();  // восстанавливаем стандартный вызов PedPreRender()
  4.                 if ((Camera->cams[Camera->activeCam].view == CAMERA_VIEW_CAR_1ST_PERSON) && (!GameKeys->PrevWeapon_LookLeft) && (!GameKeys->NextWeapon_LookRight)) {
  5.                         PlayerBody.HideComponent(PlayerBody.Head);
  6.                         PlayerBody.HideComponent(PlayerBody.Neck);
  7.                         PlayerBody.HideComponent(PlayerBody.Spine1);
  8.                         PlayerBody.HideComponent(PlayerBody.LClavicle);
  9.                         PlayerBody.HideComponent(PlayerBody.RClavicle);
  10.                         PlayerBody.HideComponent(PlayerBody.LUpperArm);
  11.                         PlayerBody.HideComponent(PlayerBody.RUpperArm);
  12.                 }
  13.         }
  14. public:
  15.         PedPreRender() {
  16.                 Patch(0x694DA0, (int)HidePlayerHead);
  17.         }
  18. } _PedPreRender;

Восстанавливать скрытые компоненты не нужно, игра сама это делает при следующем кадре
3
Общие вопросы / Re: Части Тела
« Последний ответ от Shagg_E Июль 19, 2019, 04:11:46 pm »
Вау, крутяк! Кстати, меня всегда еще интересовала возможность скейла частей тела по-отдельности. Видел этот видос, но так и не смог добиться от maxorator какой-нибудь инфы...
4
Общие вопросы / Re: Части Тела
« Последний ответ от xanser Июль 19, 2019, 10:26:15 am »
Нупить многовато, надо убирать все FindPlayerPed() и IsPlayer(), и неизвестно какие будут последствия. Могу предложить такой вариант - вызвать свою функцию, например InflictPlayerDamage вместо этого участка:
Код: ASM
  1. .text:00525C01 6A 00                   push    0               ; a2
  2. .text:00525C03 E8 18 65 F9 FF          call    _Z13FindPlayerPedv ; FindPlayerPed(void)
  3. .text:00525C08 89 C1                   mov     ecx, eax        ; this
  4. .text:00525C0A E8 E1 C0 00 00          call    _ZN10CPlayerPed14AnnoyPlayerPedEb ; CPlayerPed::AnnoyPlayerPed(bool)
  5.  

Сначала нужно передать в свою функцию пострадавшую часть тела, это параметр a5 в функции CPed::InflictDamage. Получить его для своей функции можно, скопировав такую строчку:

Код: ASM
  1. .text:00526215 8B 4C 24 70             mov     ecx, [esp+60h+arg_C]

Пишем ее в заменяемый участок:

Код: C++
  1. Patch(0x525C01, 0x8B);
  2. Patch(0x525C02, 0x4C);
  3. Patch(0x525C03, 0x24);
  4. Patch(0x525C04, 0x70);

Теперь в ecx пострадавшая часть тела. Дальше вызываются команды push ecx и call [адрес функции InflictPlayerDamage]

Код: C++
  1. Patch(0x525C05, 0x51);        // push ecx
  2. Patch(0x525C06, 0xE8);        // call
  3. Patch(0x525C07, (int)InflictPlayerDamage);        // address

Остальные адреса нупятся с 0x525C0B по 0x525C0F

Сама функция InflictPlayerDamage выглядит примерно так:

Код: C++
  1. static void __stdcall InflictPlayerDamage(int part) {
  2.         if ((part > 1) && (part < 7))
  3.                 switch (part) {
  4.                 case 2:
  5.                         PlayerPed->SpawnFlyingComponent(3);
  6.                         PlayerPed->SetDie(19, 10000.0f, 0);
  7.                         break;
  8.                 case 3:
  9.                         PlayerPed->SpawnFlyingComponent(4);
  10.                         PlayerPed->SetDie(20, 10000.0f, 0);
  11.                         break;
  12.                 case 4:
  13.                         PlayerPed->SpawnFlyingComponent(7);
  14.                         PlayerPed->SetDie(21, 10000.0f, 0);
  15.                         break;
  16.                 case 5:
  17.                         PlayerPed->SpawnFlyingComponent(8);
  18.                         PlayerPed->SetDie(22, 10000.0f, 0);
  19.                         break;
  20.                 case 6:
  21.                         PlayerPed->SpawnFlyingComponent(2);
  22.                         PlayerPed->SetDie(17, 10000.0f, 0);
  23.                         break;
  24.                 }
  25.         else
  26.                 PlayerPed->AnnoyPlayerPed();
  27.         }

Из минусов. После восстановления из больницы игрок остается безголовым. С педами такой проблемы нет, потому что они просто исчезают. Второе - бошку можно снести и ударом руки, потому что в моем варианте нет проверки на тип оружия, нужно смотреть остальные параметры InflictDamage.

5
Общие вопросы / Re: Экстры транспорта
« Последний ответ от kenking Июль 12, 2019, 03:15:47 pm »
Цитировать
Но обратный вариант слотов 1f103432 проблем не выявил, рекомендую его. Возможно перестановкой я намного снизил вероятность появления пустышки, хорошо если бы исключил, но пока она мне не попалась.
Прописывать постоянные экстры в первый слот, а необязательные дополнительные во второй или наоборот - это без разницы. Если попадается пустышка в слоте с обязательным нахождением одной из первых двух экстр, то пропиши вместо f первую экстру на эту позицию 11103432.

Цитировать
В дополнение скажу, что есть еще такой момент. Например нужно создать исключительную машину без экстры или с 6 экстрой, это можно сделать принудительно скриптом/кодом даже при 4fff, но кажется сбивается правило 4fff и в трафике начинают ездить пустышки, с этим надо быть осторожнее.
Надо перед установкой экстры на создаваемую машину, считать значение переменной (два значения) CVehicleModelInfo::ms_compsToUse[2]. Установить свой вариант экстры на модель, создать машину и записать в эту переменную значение, которое там было. Думаю это решит вопрос.
6
Общие вопросы / Re: Экстры транспорта
« Последний ответ от xanser Июль 12, 2019, 12:39:51 pm »
Спасибо за разъяснение, похоже стандартными вариантами не обойтись, хорошо, что работают свои. Я пока ждал ответ, немного еще потестировал и пришел примерно к таким же выводам, но есть некоторая разница с предложенным.

1) Вариант машины, где 1,2 являются чередующимися обязательными частями кузова, а 3,4,5 необязательными дополнениями (6 надо выкинуть из модели, ей уже нет места в слоте). Почему-то у меня есть зависимость от последовательности слотов. То есть такой вариант 34321f10 временами допускает пропадание 1, 2 в тестах, чего быть не должно. Подозреваю, что дело в проклятой букве f, создающей изредка пустышку. Вот например только экстра 4 (второй слот 4, а первый таки оказался пустой, несмотря на правило 1).



Но обратный вариант слотов 1f103432 проблем не выявил, рекомендую его. Возможно перестановкой я намного снизил вероятность появления пустышки, хорошо если бы исключил, но пока она мне не попалась.

2) Вариант машины, где 1,2,3 являются чередующимися обязательными частями кузова, а 4,5,6 необязательными дополнениями. Тут согласен, но порекомендую опять же обратную последовательность 11203345

3) Вариант шасси с 6 чередующимися обязательными кузовами. Тут вопрос именно в том, чтобы смоделировать максимальное количество разных кузовов уже без мелких дополнений. Поэтому однозначно 4fff, но как уже предложено, со сломанной функцией или ограничиться 5 видимыми кузовами.
В дополнение скажу, что есть еще такой момент. Например нужно создать исключительную машину без экстры или с 6 экстрой, это можно сделать принудительно скриптом/кодом даже при 4fff, но кажется сбивается правило 4fff и в трафике начинают ездить пустышки, с этим надо быть осторожнее.
7
Общие вопросы / Re: Экстры транспорта
« Последний ответ от kenking Июль 12, 2019, 10:03:58 am »
Проверил сейчас на модели caddy. У неё 3 экстры слева, 3 справа. Очень удобно для тестов. Для "чистоты" тестов написал код, выводящий на экран номера экстр в слотах на транспорте возле игрока и спаунил эту модель.
Действительно, при настройке 1f10 не получается всегда нужного сочетания. Думаю, что дело в том, что во второй слот при такой настройке выбирается экстра выборочно из всех имеющихся вариантов (включая отсутствие второй экстры), поскольку не задан конкретный режим для второго слота.
Значит надо задать для второго слота своё правило.
Исходя из этого:
1) 35431f10 экстра 3 здесь получается исключается, можно её прописать во второй слот вместо любой из 4-6 или в первый, тогда получается настройка как для второго варианта
2) 35431210 прям идеальная настройка для этого варианта
3) здесь - да вариант 4fff для 5 экстр, либо изменять функцию, если 6 экстра какие-либо мелкие детальки или, например, груз в кузов, то можно эту экстру закинуть во второй слот с типом рандомного появления
3ff54fff - правда такой вариант я не тестировал
8
Общие вопросы / Re: Экстры транспорта
« Последний ответ от xanser Июль 12, 2019, 06:17:55 am »
Хотел дать практические советы по моделированию кузовов через экстры, но сам получил странные результаты, которые все портят и не соответствуют даже моим тестам.
По ссылке было сказано 1f10 - всегда одна из первых двух экстр, но что-то не так.



Я протестировал многочисленные варианты, и у меня при 1f10 получились такие 1+все кроме 2, 2+все кроме 1. Остальное кажется не вписывается в правило - отдельные 3 и 4, сочетания 3+4, 3+5, 4+5, 4+6.

kenking, если ты хорошо разобрался со слотами, посоветуй, как настроить слоты для следующих частых вариантов:
1) обязательные 1 или 2 экстра - отвечают за смену фар или решетки радиатора, а 3, 4, 5, 6 - необязательные рандомные мелочи
2) обязательные 1 или 2 или 3 экстра - отвечают за смену фар или решетки радиатора, а 4, 5, 6 - необязательные рандомные мелочи
3) 6 альтернативных кузовов грузовика без пустых шасси (тут бы подошел вариант 4fff для 5, или взломанная функция для расширения до 6, но может есть вариант через другую настройку слотов)

Или это просто ты что-то нахимичил с колесами при съемке того скрина?
Колеса не заменил, там 249 модель
9
Общие вопросы / Re: Экстры транспорта
« Последний ответ от Shagg_E Июль 11, 2019, 01:39:59 pm »
Цитировать
Тип 4 (Comprules 4fff) - 1, 2, 3, 4, 5. Никогда не проявляется экстра 6. Пустышек нет.
Колес тоже нет с этим типом?  :o
Хотя..
Цитировать
Тип 4 есть у flatbed.

Или это просто ты что-то нахимичил с колесами при съемке того скрина?
10
Общие вопросы / Re: Экстры транспорта
« Последний ответ от kenking Июль 11, 2019, 12:53:29 pm »
Цитировать
По моим тестам получается, что экстру 1 в трафике не увидеть.
Надо поменять расклад экстр в наборе 30123345 на такой 31203345, экстра 1 должна появиться.

Цитировать
Выложу сюда результаты своих многочисленных тестов для вайса
В остальном всё соответствует и моим тестам.

Цитировать
Тип 4 (Comprules 4fff) - 1, 2, 3, 4, 5. Никогда не проявляется экстра 6.
В самой функции такое ограничение для этого типа.
Страницы: [1] 2 3 ... 10