HLFX.Ru Forum Страницы (3): [1] 2 3 »
Показать все 40 сообщений этой темы на одной странице

HLFX.Ru Forum (https://hlfx.ru/forum/index.php)
- Half-Life SDK (https://hlfx.ru/forum/forumdisplay.php?forumid=8)
-- FireBullets и рикошеты (https://hlfx.ru/forum/showthread.php?threadid=4496)


Отправлено Ku2zoff 18-11-2014 в 19:06:

FireBullets и рикошеты

Занялся механизмом рикошета при стрельбе. Естественно, подглядел образцы кода где можно, даже на бумажке алгоритм расписал. Когда выстреливается только одна пуля, она прекрасно рикошетит в цикле сколько нужно раз, хоть десять. Ну это чисто для теста, по задумке, после одного-двух рикошетов, кинетическая энергия пули падает, и цикл обрывается. Проблема в том, что когда рикошетят несколько пуль (см. дробовик), то отрикошетившие пули попадают в одну точку. Где ошибся, не знаю, вроде бы всё перепробовал. По смыслу, каждая новая пуля должна иметь свою собственную точку попадания после рикошета, а на практике, все последующие берут конечную точку попадания от самой первой. Может подскажете чего, товарищи форумчане?


Отправлено XaeroX 18-11-2014 в 19:15:

Ну ты хоть алгоритм подробно распиши, что ли... У нас тут не битва экстрасенсов.
Ты точно правильно берёшь исходное направление пули? Это не просто v_forward игрока?

__________________

xaerox on Vivino


Отправлено Ku2zoff 18-11-2014 в 20:21:

Цитата:
XaeroX писал:
Ты точно правильно берёшь исходное направление пули? Это не просто v_forward игрока?

Завтра копну в этом направлении, спс.
Цитата:
XaeroX писал:
Ну ты хоть алгоритм подробно распиши, что ли...

Я ещё сам попытаюсь разобраться, если не выйдет, кину кусок кода в тему.

Добавлено 19-11-2014 в 02:21:

Алгоритм такой:
Когда сила пули (iDamage) больше 10, то:
1. Если угол попадания трассы больше 60 градусов, то прерываем цикл.
2. Если энтитя, в которую мы попали, не брашевая, то прерываем цикл.
3. Проводим новую трассу из точки попадания под углом в столько же градусов, каков угол старой трассы относительно стены (короче, зеркально отражаем выстрел).
4. "Стреляем" в новом направлении, и делим iDamage пополам.

После первого рикошета всё повторятся до тех пор, пока угол попадания не станет больше 60 градусов, или iDamage не станет меньше 10.


Отправлено GioHAUS0n 19-11-2014 в 09:09:

Цитата:
Ku2zoff писал:
Ну это чисто для теста, по задумке, после одного-двух рикошетов, кинетическая энергия пули падает, и цикл обрывается.


Откуда взял эту информуху?_? Мне помниться, что она может вернуться обратно стрелку с первого рикошета:
https://en.wikipedia.org/wiki/Ricochet


Отправлено Ku2zoff 19-11-2014 в 09:54:

Цитата:
GioHAUS0n писал:
Мне помниться, что она может вернуться обратно стрелку с первого рикошета:

То-то меня бесит такое поведение при альтернативной атаке гаусса. Не, ну я могу такую гадость сделать, чтоб в 15 процентах случаев пулька рикошетила обратно, но это будет неимоверно бесить игроков. Я не спец в баллистике, но думаю, что рикошет обратно - это редкость.
Вроде справился с задачей, всё работает как надо. Перепилил код, добавил прострелы:
C++ Source Code:
1
// ============================
2
// ku2zoff: рикошет и прострелы
3
// ============================
4
choose_think: // выбор
5
if (iDamage > 12) // все операции проводим только если урон больше 12
6
{
7
  float m_flNormal = -DotProduct(tr.vecPlaneNormal, vecDir); // угол попадания
8
 
9
  if ((m_flNormal < 0.5) && (pEntity->pev->solid == SOLID_BSP)) // если угол меньше 60 градусов и энтитя - браш
10
  {
11
    Vector vecSrc_ric; // задаём новый исходный вектор
12
 
13
    // переопределяем векторы согласно новым углам
14
    vecDir = 2.0 * tr.vecPlaneNormal * m_flNormal + vecDir;
15
    vecSrc_ric = tr.vecEndPos + vecDir * 8;
16
    vecEnd = vecSrc_ric + vecDir * flDistance;
17
 
18
    UTIL_Ricochet(vecSrc_ric, 1.0); // рисуем эффект рикошета
19
 
20
    // проводим вторую трассу и ставим вторую декаль
21
    UTIL_TraceLine(vecSrc_ric, vecEnd, dont_ignore_monsters, NULL, &tr);
22
    DecalGunshot(&tr, iBulletType);
23
 
24
    // уменьшаем урон в два раза, и наносим его
25
    iDamage /= 2;
26
    pEntity = CBaseEntity::Instance(tr.pHit);
27
    pEntity->TraceAttack(pevAttacker, iDamage, vecDir, &tr, DMG_BULLET);
28
 
29
    goto choose_think; // возвращемся к выбору
30
  }
31
  else // если угол больше 60 градусов или энтитя - не браш
32
  {
33
    // проводим вторую трассу в стену, на iDamage/10 юнитов
34
    UTIL_TraceLine(tr.vecEndPos + vecDir * (iDamage/10), vecEnd, dont_ignore_monsters, ENT(pev), &tr);
35
 
36
    // если трасса вышла из стены (стена тоньше, чем iDamage/10 юнитов)
37
    if (!tr.fAllSolid)
38
    {
39
      // если трасса вышла, трейсим назад, и рисуем вторую декаль с обратной стороны стены
40
      UTIL_TraceLine(tr.vecEndPos, vecSrc, dont_ignore_monsters, ENT(pev), &tr);
41
      DecalGunshot(&tr, iBulletType);
42
 
43
      // трейсим из точки попадания второй декальки вперёд, рисуем третью декаль
44
      UTIL_TraceLine(tr.vecEndPos, vecEnd, dont_ignore_monsters, ENT(pev), &tr);
45
      DecalGunshot(&tr, iBulletType);
46
 
47
      // уменьшаем урон в два раза, и наносим его
48
      iDamage /= 2;
49
      pEntity = CBaseEntity::Instance(tr.pHit);
50
      pEntity->TraceAttack(pevAttacker, iDamage, vecDir, &tr, DMG_BULLET);
51
 
52
      goto choose_think; // возвращемся к выбору
53
    }
54
  }
55
}

В зависимости от того, как мы попали и во что попали, выбирается действие: рикошет или прострел. Действие выполняется, урон уменьшается в два раза. Возвращаемся к выбору действия. Там вычисляем угол и солид энтити согласно новым данным, которые остались после предыдущего действия, и цикл повторяется. Цикл прерывается, если урон становится меньше 12, или когда пуля попадает под углом больше 60 градусов в непростреливаемую стенку.


Отправлено XaeroX 19-11-2014 в 10:35:

Цитата:
Ku2zoff писал:
Я не спец в баллистике, но думаю, что рикошет обратно - это редкость.

Стрелять, не задумываясь о рикошете, как мы делаем в играх - в реале это редкость.
И я не совсем понимаю, для чего они тебе нужны. Весь мир стремится к упрощению механики игры, чтобы игрок мог чётко просчитывать свои действия (в этом смысл киберспорта). А ты вводишь прострелы (ну ок, их ещё можно просчитать в том же КС) и рикошеты, которые в реале, вообще говоря, непредсказуемы из-за микрорельефа. Какой следующий шаг? Рикошет с учётом карты нормалей?

__________________

xaerox on Vivino


Отправлено tolerance 19-11-2014 в 11:03:

Урон по идеи не должен тупо делиться на два, а уменьшаться в зависимости от толщины простреливаемого объекта. А то получится, что игрок будет наносить одинаковый урон, простреливая стену, и простреливая какую-нибудь брашевую периллу в 1 юнит толщиной.

А рикошеты — это очень интересно. В ARMA хорошо реализовали:
https://www.youtube.com/watch?v=2mZNpurQj4U
На сколько я понял по коду, у тебя каждая пуля будет рикошетить если попадает под условие градуса? По-моему это перебор, и стоит добавить random (5-10% пуль будут рикошетить).


Отправлено ~ X ~ 19-11-2014 в 11:34:

Цитата:
XaeroX писал:
Какой следующий шаг? Рикошет с учётом карты нормалей?

А что, кто-то делал без нормалей?!! За это включаю убиватор!

__________________
Минутка полезного:
Бесплатный UT-подобный Half-Life mod.
Бесплатный редактор для 32-битных текстур. Без дотнета.
Бесплатный IDE для любых компиляторов и ЯП.
Бесплатная Windows-подобная ОС.
Проверка грамматики русского языка.
Чат по hl[fx]: half-life@conference.jabber.ru


Отправлено XaeroX 19-11-2014 в 12:05:

Цитата:
~ X ~ писал:
А что, кто-то делал без нормалей?!! За это включаю убиватор!

Полагаю,что 99,9% рикошетов сделаны по обычному tr.vecPlaneNormal. А я про попиксельные карты нормалей говорю, которые для бампа используются.

__________________

xaerox on Vivino


Отправлено Ku2zoff 19-11-2014 в 12:22:

Цитата:
tolerance писал:
По-моему это перебор, и стоит добавить random

Это ж пробный код. Конечно добавлю рандом. И углы рандомизирую.
Цитата:
XaeroX писал:
Весь мир стремится к упрощению механики игры,

Вот так и родилось Press E to win. А вообще, я конечно уменьшу процент рикошетов. Ещё и зависимость от материалов введу. Вон, с бронёй и повреждением от разных видов видов урона очень интересно получилось. Там в зависимости от чего хочешь защититься в первую очередь, такую броню и юзаешь(ну шлем, жилет или щитки на руки-ноги, или всё вместе). Тоже пока в стадии разработки.

Добавлено 19-11-2014 в 18:22:

Меня сейчас больше беспокоит правильность работы этого кода. Вроде как норм пока, боюсь как бы неприятный баг какой не словить. Особенно меня смущает использование goto. Другого варианта пока не нашёл.


Отправлено Cybermax 19-11-2014 в 12:58:

Цитата:
Ku2zoff писал:
Вот так и родилось Press E to win.

Если стремиться к реализму и хардкорности то надо делать: один выстрел - один фраг. Потому что в реале даже от одной пули 9мм можно убить особенно в голову.

__________________


Отправлено Ku2zoff 19-11-2014 в 13:03:

Цитата:
Cybermax писал:
один выстрел - один фраг.

Day of Defeat же.


Отправлено Cybermax 19-11-2014 в 13:16:

Цитата:
Ku2zoff писал:
Day of Defeat же.

Скорее как в Insurgency. Типы патронов: бронебойные, трассирующие, экспансивные.

__________________


Отправлено XaeroX 19-11-2014 в 13:20:

Цитата:
Ku2zoff писал:
Вот так и родилось Press E to win.

Нет, так родились Quake1, Quake2 и Quake3. Именно поэтому в них играли, играют и будут играть ещё десятки лет, вот увидите.
А "Press E to win" - это выкидыш.

__________________

xaerox on Vivino


Отправлено ~ X ~ 19-11-2014 в 13:37:

Цитата:
Cybermax писал:
один выстрел - один фраг

skill 3 в XDM же (тогда грунты реально опасные)

__________________
Минутка полезного:
Бесплатный UT-подобный Half-Life mod.
Бесплатный редактор для 32-битных текстур. Без дотнета.
Бесплатный IDE для любых компиляторов и ЯП.
Бесплатная Windows-подобная ОС.
Проверка грамматики русского языка.
Чат по hl[fx]: half-life@conference.jabber.ru


Временная зона GMT. Текущее время 17:02. Страницы (3): [1] 2 3 »
Показать все 40 сообщений этой темы на одной странице

На основе vBulletin версии 2.3.0
Авторское право © Jelsoft Enterprises Limited 2000 - 2002.
Дизайн и программирование: Crystice Softworks © 2005 - 2024