GTA Builder Форум

GTA Vice City => Справочная информация => Тема начата: Sektor от Декабрь 22, 2013, 04:43:24 am

Название: Прицельная стрельба.
Отправлено: Sektor от Декабрь 22, 2013, 04:43:24 am
Вот участок кода, который отвечает за стрельбу от прицела, на правую кнопку мыши:

Код: ASM
  1. .text:00534994                                   loc_534994:                             ; CODE XREF: sub_534890+F5j
  2. .text:00534994 060 C6 83 06 05 00 00 64                          mov     [ebx+CPlayerPed.__parent.weaponAccuracy], 100
  3. .text:0053499B
  4. .text:0053499B                                   loc_53499B:                             ; CODE XREF: sub_534890+102j
  5. .text:0053499B 060 83 BB 24 05 00 00 00                          cmp     [ebx+CPlayerPed.__parent.fire], 0
  6. .text:005349A2 060 0F 85 58 01 00 00                             jnz     loc_534B00
  7. .text:005349A8 060 0F BE 93 04 05 00 00                          movsx   edx, [ebx+CPlayerPed.__parent.currentWeapon]
  8. .text:005349AF 060 8D 14 D5 00 00 00 00                          lea     edx, ds:0[edx*8]
  9. .text:005349B6 060 8D 14 52                                      lea     edx, [edx+edx*2]
  10. .text:005349B9 060 01 DA                                         add     edx, ebx
  11. .text:005349BB 060 81 C2 08 04 00 00                             add     edx, 408h
  12. .text:005349C1 060 89 D0                                         mov     eax, edx
  13. .text:005349C3 060 8B 30                                         mov     esi, [eax]
  14. .text:005349C5 060 83 FE 1E                                      cmp     esi, 1Eh
  15. .text:005349C8 060 74 26                                         jz      short loc_5349F0
  16. .text:005349CA 060 8B 0A                                         mov     ecx, [edx]
  17. .text:005349CC 060 89 C8                                         mov     eax, ecx
  18. .text:005349CE 060 83 F8 1C                                      cmp     eax, 28
  19. .text:005349D1 060 74 1D                                         jz      short loc_5349F0
  20. .text:005349D3 060 83 F8 1D                                      cmp     eax, 29
  21. .text:005349D6 060 74 18                                         jz      short loc_5349F0
  22. .text:005349D8 060 83 F8 1A                                      cmp     eax, 26
  23. .text:005349DB 060 74 13                                         jz      short loc_5349F0
  24. .text:005349DD 060 83 F8 1B                                      cmp     eax, 27
  25. .text:005349E0 060 74 0E                                         jz      short loc_5349F0
  26. .text:005349E2 060 83 F8 20                                      cmp     eax, 32
  27. .text:005349E5 060 74 09                                         jz      short loc_5349F0
  28. .text:005349E7 060 83 F9 24                                      cmp     ecx, 36
  29. .text:005349EA 060 0F 85 10 01 00 00                             jnz     loc_534B00
  30.  

Особое внимание можете уделить этому:

Код: ASM
  1. .text:005349CE 060 83 F8 1C                                      cmp     eax, 28
  2. .text:005349D1 060 74 1D                                         jz      short loc_5349F0
  3. .text:005349D3 060 83 F8 1D                                      cmp     eax, 29
  4. .text:005349D6 060 74 18                                         jz      short loc_5349F0
  5. .text:005349D8 060 83 F8 1A                                      cmp     eax, 26
  6. .text:005349DB 060 74 13                                         jz      short loc_5349F0
  7. .text:005349DD 060 83 F8 1B                                      cmp     eax, 27
  8. .text:005349E0 060 74 0E                                         jz      short loc_5349F0
  9. .text:005349E2 060 83 F8 20                                      cmp     eax, 32
  10. .text:005349E5 060 74 09                                         jz      short loc_5349F0
  11. .text:005349E7 060 83 F9 24                                      cmp     ecx, 36
  12. .text:005349EA 060 0F 85 10 01 00 00                             jnz     loc_534B00
  13.  

В регистре eax как раз таки и содержится текущий id оружия. Еще один момент, заметил то что при стрельбе от прицела, педы не реагируют, это недофикс R*. Подменив какой нибудь id, вы сможете стрелять с любого оружия прицельно.
Название: Re: Прицельная стрельба.
Отправлено: xanser от Декабрь 23, 2013, 05:51:52 am
Круто, работает, только след пули не видно. Хотя его вроде и не было видно, интересно если сюда теперь присобачить ствол, как Sektor предлагал

(http://i076.radikal.ru/0911/44/6a0f157dc8e6.jpg)
Название: Re: Прицельная стрельба.
Отправлено: Sektor от Декабрь 26, 2013, 07:07:51 pm
Вообще-то замечательно, но пока надо все оружие переписать...
Название: Re: Прицельная стрельба.
Отправлено: xanser от Декабрь 30, 2013, 01:12:45 pm
Мне кажется, модовское оружие обычно достойного качества, можно использовать эти же модели, только есть проблема, камера "съедает" ближний план, а иногда и всю модель.
У меня не получилось подстроить нормально, к сожалению.

(http://s6.postimg.org/nliq6lhc1/scr002.jpg) (http://s6.postimg.org/vsapy67ep/scr004.jpg)
Название: Re: Прицельная стрельба.
Отправлено: Sektor от Декабрь 30, 2013, 02:23:37 pm
Тут еще интересный момент, модель в высоком качестве, надо для игрока как раз таки юзать, а обычную модель для обычных педов со стороны. С камерой тоже что-то думать нужно, что-бы она срез прям такой не делала...
Название: Re: Прицельная стрельба.
Отправлено: xanser от Январь 13, 2014, 12:25:33 pm
В тему о прицелах. Могу поделиться, как восстановить правильные пропорции, чтобы ширина прицела совпадала с его высотой на любом разрешении экрана.

Первоначально масштаб прицелов задается тут:
0x697AA4 float 40.0 - гранатомет
0x697B10 float 32.0 - автоматы
0x697B2C float 210.0 - снайперки

Беда в том, что через эти константы пересчитывается одновременно и ширина и высота, поэтому их трогать нельзя. Поэтому для расчета правильной ширины прицела нужно переопределить указатели с этих констант на свои. Нужные указатели находятся по адресам:
0x55768C значение 0x697B10 - обычный мелкий прицел // 32.0
0x557770 значение 0x697B10 - обычный крупный прицел // 32.0
0x557890 значение 0x697B10 - прицельная стрельба автоматы // 32.0
0x557BA2 значение 0x697AA4 - прицельная стрельба гранатомет // 40.0
0x557C46 значение 0x697B2C - прицельная стрельба снайперки // 210.0

Нужный коэффициент, который выровнит прицел рассчитывается как 640/448*ScreenHeight/ScreenWidth. Берется отсюда:
0x697A68 float 1/448 heightMultiplier - участвует в расчете
0x697A70 float 1/640 widthMultiplier - участвует в расчете
0x9B6CBC WORD ScreenWidth - ширина экрана в игре
0x9B6CC0 WORD ScreenHeight - высота экрана в игре

Теперь осталось вместо масштаба, предлагаемого в начале, использовать масштаб для ширины, умноженный на полученный коэффициент.

Пример для снайперки:
Например у вас разрешение экрана 1280x600, тогда масштаб для ширины должен быть не 210, а 210*640/448*600/1280, высота по прежнему 210.
Осталось подсунуть игре по адресу 0x557C46 вместо указателя 0x697B2C свой например так (DWORD)&SniperWidth, где глобальная переменная SniperWidth=210*640/448*600/1280.
В общем случае все конечно через значения адресов, цифры для примера. Получаем ровные прицелы:

(http://s6.postimg.org/vf4mk0n41/scr004.jpg) (http://s6.postimg.org/bztuqwttt/scr003.jpg) (http://s6.postimg.org/72ga5srup/scr005.jpg)

Теперь можно экспериментировать с масштабом по первоначальным константам, прицел будет ровным на всех видеорежимах.

(http://s6.postimg.org/73utcyj29/scr002.jpg) (http://s6.postimg.org/s20zb1iwx/scr001.jpg) (http://s6.postimg.org/s3ax4gkqp/scr000.jpg)

Специально оставил в снайперке черные поля, чтобы показать, что там еще черная текстура по краям, это отдельный вопрос.
Проверялось в оконном режиме, в полноэкранном будет ровно, если разрешение в игре правильно соотносится с пропорциями экрана.
Название: Re: Прицельная стрельба.
Отправлено: Saint от Январь 13, 2014, 03:24:42 pm
xanser, спасибо очень полезная информация.
Название: Re: Прицельная стрельба.
Отправлено: Sektor от Январь 13, 2014, 04:15:21 pm
Цитировать
Беда в том, что через эти константы пересчитывается одновременно и ширина и высота, поэтому их трогать нельзя. Поэтому для расчета правильной ширины прицела нужно переопределить указатели с этих констант на свои.


Да верно переопределить указатель на свои переменные, а верней записать туда свои адреса переменных, об этом я также писал:

http://gtabuilder.ru/zamena-peremennyx-v-gta-vice-city/ (http://gtabuilder.ru/zamena-peremennyx-v-gta-vice-city/)

Именно это все так решается, как в этой статье. Адреса действительно полезные и все больше как пазл раскрывает грани в реверсе.
Название: Re: Прицельная стрельба.
Отправлено: xanser от Январь 13, 2014, 04:39:00 pm
Все верно, некоторые моменты понимаешь только с 10 раза, я даже не придал значения этому уроку, все именно по нему и правильными словами. Повторение действительно мать учения, буду почаще перечитывать.
Название: Re: Прицельная стрельба.
Отправлено: Sektor от Январь 13, 2014, 05:21:01 pm
Да тут чаще иногда надо практические статьи писать, а там показывать ссылки на учебные основы.
Название: Re: Прицельная стрельба.
Отправлено: xanser от Январь 14, 2014, 03:23:08 pm
Что-то я перемудрил, но хоть потренировался. Можно было убить всех зайцев одним выстрелом и заодно выровнить старый худ.

WORD  * wScreenWidth = (WORD *)0x9B6CBC;
WORD  * wScreenHeight = (WORD *)0x9B6CC0;
float * heightMultiplier = (float*)0x697A68;
float * widthMultiplier = (float*)0x697A70;

*widthMultiplier=(*heightMultiplier)*(*wScreenHeight)/(*wScreenWidth);
Что-то у меня код не раскрашивается
Название: Re: Прицельная стрельба.
Отправлено: Sektor от Январь 14, 2014, 03:38:09 pm
Надо позже глянуть, но что-то тут не так, судя по адресам, как будто они динамические...
Название: Re: Прицельная стрельба.
Отправлено: xanser от Январь 16, 2014, 07:53:18 am
Адреса на размер экрана где-то были опубликованы давно, адреса коэффициентов - константы, должно быть все правильно.

Чтобы закончить про прицел снайперки, нужно пересчитать еще черные поля, сделав еще одну замену переменных.
Понадобится масштаб прицела float *SniperScale = (float *) 0x697B2C
и посчитанный *widthMultiplier=(*heightMultiplier)*(*wScreenHeight)/(*wScreenWidth)

сюда 0x4A6419 пишем (DWORD)widthMultiplier
сюда 0x4A646D пишем (DWORD)widthMultiplier
сюда 0x4A6430 пишем (DWORD)SniperScale
сюда 0x4A6482 пишем (DWORD)SniperScale
сюда 0x4A637C пишем (DWORD)SniperScale
сюда 0x4A63C3 пишем (DWORD)SniperScale

Может кому-то понравится вообще без черных полей, тогда нупим

0x4A6388
0x4A63EE
0x4A6446
0x4A64AD



(http://s6.postimg.org/wr1p7k2v5/scr000.jpg) (http://s6.postimg.org/5uhpz8k1t/scr001.jpg)

Название: Re: Прицельная стрельба.
Отправлено: Sektor от Январь 16, 2014, 05:12:12 pm
Замечательно. Но они используются где-то в рендере, тут еще глубже надо смотреть.
Название: Re: Прицельная стрельба.
Отправлено: xanser от Январь 16, 2014, 05:24:06 pm
Можно пойти и простым путем, и снова пересчитать такой же множитель *widthMultiplier=(*heightMultiplier)*(*wScreenHeight)/(*wScreenWidth), только на этот раз его адрес не 0x697A70 , а 0x68E5C0. Дело в том, что в игре используется две одинаковых константы, равные 1/640, одна для ширины текстуры, другая для ширины дырки под текстуру. Одновременно с этим используется две константы для масштаба текстуры и дырки, равные 210.0 по адресам 0x697B2C и 0x68E5BC, придется следить за ними одновременно при масштабировании. Тогда при замене значений констант не придется копать глубоко, сразу станет понятно в игре, что растянулось еще, например на них есть еще ссылка из ShowLoadingTextures. Поэтому способ с заменой переменных мне кажется более универсальным.
Название: Re: Прицельная стрельба.
Отправлено: Sektor от Январь 19, 2014, 09:47:50 pm
Еще если хорошенько с камерой повозиться можно добиться потрясенных результатов типа таких:

(http://gta-vc.info/uploads/posts/2012-01/1327150136_1.jpg)
Название: Re: Прицельная стрельба.
Отправлено: xanser от Январь 20, 2014, 03:26:04 pm
Классно, интересно вживую глянуть, например с перезарядкой автомата, или бензопилу от первого лица, может видео сделаешь?
Название: Re: Прицельная стрельба.
Отправлено: Sektor от Январь 20, 2014, 03:41:44 pm
Нет это не моя работа, это просто нашел в сети где-то... Была бы моя я бы так и сказал, просто скрин где-то нарыл. Но уверяю тут надо возиться с камерой что-бы добиться такого эффекта.
Название: Re: Прицельная стрельба.
Отправлено: xanser от Февраль 20, 2014, 12:19:46 pm
Такая прицельная стрельба реализована здесь: http://www.gtagarage.com/mods/show.php?id=1823 (http://www.gtagarage.com/mods/show.php?id=1823)
Жаль не приложен исходный код.
Название: Re: Прицельная стрельба.
Отправлено: Sektor от Март 01, 2014, 10:29:09 pm
Да по поводу GTA:FPS у меня давно была беседа еще с автором, когда я сделал один плагин отдачи для вооружение, его это заинтересовало, но сорцы так и не прислал мне, что-бы мы объедении все это в одно.

Я сделал разброс пуль, цель также меняет размеры в зависимости от стрельбы, это было дело еще давно:

gta vice city новая стрельба (http://www.youtube.com/watch?v=P5AvYmSZzp8#)
Название: Re: Прицельная стрельба.
Отправлено: Shagg_E от Март 19, 2014, 11:03:55 am
Насчет моментов, когда камера "пожирает" оружие:
есть такой опкод
041D: set_camera_near_clip 0.1 Так вот, обычно значения 0.1 достаточно, чтобы камера не жрала объекты вблизи, но проблема в том, что иногда этого недостаточно, а значения меньше 0.1 могут привести к вылету игры.
Но я всё же думаю, что этого хватит, что оружие развестить снизу экрана без глюков.
Адреса памяти я не знаю, т.к. даже не искал(я преимущественно скриптингом пользуюсь)
Название: Re: Прицельная стрельба.
Отправлено: xanser от Март 19, 2014, 02:48:51 pm
Супер! То, что нужно, теперь можно экспериментировать

(http://s6.postimg.org/iasrsnngh/scr004.jpg) (http://s6.postimg.org/dnmpqw03l/scr003.jpg)
Название: Re: Прицельная стрельба.
Отправлено: Sektor от Март 20, 2014, 12:07:34 am
Цитировать
Адреса памяти я не знаю, т.к. даже не искал(я преимущественно скриптингом пользуюсь)
Вот по этому адресу, находиться метод класса CCamera, думаю пригодиться для тех кто занимается разработкой плагинов на C++


Код: ASM
  1. .text:0046B9E2                                                     ; int __stdcall CCamer__SetNearClipPlain(float)
  2. .text:0046B9E2                                                     CCamer__SetNearClipPlain proc near      ; CODE XREF: CRunningScript::ProcessCommands1000To1099(int)+8FAp
  3. .text:0046B9E2
  4. .text:0046B9E2                                                     arg_0           = dword ptr  4
  5. .text:0046B9E2
  6. .text:0046B9E2 000 D9 44 24 04                                                     fld     [esp+arg_0]
  7. .text:0046B9E6 000 D9 99 3C 01 00 00                                               fstp    [ecx+CCamera.fNearClipPlain]
  8. .text:0046B9EC 000 C6 41 61 01                                                     mov     [ecx+CCamera.field_61], 1
  9. .text:0046B9F0 000 C2 04 00                                                        retn    4
  10. .text:0046B9F0                                                     CCamer__SetNearClipPlain endp


Если ее переписать в сорц, то не составит труда, это для примера:

Код: C++
  1. CCamera::SetNearClipPlain(float value ) {
  2.   this->fNearClipPlain = value;
  3.   this->field_61 = 1;
  4. };
  5.  

При условии что класс, содержит все нужные поля...
Название: Re: Прицельная стрельба.
Отправлено: xanser от Октябрь 03, 2014, 05:26:16 pm
Я все думал, почему нельзя сразу было сделать this->fNearClipPlain = 0.01f (кстати это this->field_61 включение/отключение), чтобы не обрезался ближний план и вот обнаружил так сказать "обратную сторону медали", поэтому стоит включать только вблизи, а на открытых пространствах стоит отключать.

(http://s6.postimg.org/5cvpnbwqp/Untitled_1.gif)