Перейти к содержимому


Фотография

Отключение хитбоксов


  • Авторизуйтесь для ответа в теме
Сообщений в теме: 9

#1 PawnLomaster

PawnLomaster

    Участник

  • Пользователь
  • PipPip
  • 116 сообщений

Отправлено 03 Август 2020 - 8:38

Привет, форумчане! Писал плагин, который при определённых условиях должен отключать коллизию. Цель такая - сделать своего рода переключать, при включении которого, игрока нельзя будет схватить особыми зараженными. Пример - Громила должен пробегать сквозь игрока. Сначала баловался с m_nSolidType, m_CollisionGroup и m_usSolidFlags (0 2 0). За что получал спам в консоли player in solid list (not solid) в неограниченном количестве. Скорее всего я не подобрал нужные значения.
Потом я подумал попробовать сделать это через хитбоксы. Поиск по net_prop'y m_nHitboxSet не дал результатов (может, я плохо искал). Увидел про SDKHook_ShouldCollide. Этот гад крашит игру https://crash.limete...rg/prxlhdhg7hq5 . Я пробовал даже с пустой функцией хука. Всё равно крашит.
Потом прочитал про collisionhook.ext. Скорее всего из-за старых сигнатур он у меня не заработал (работаю из под винды и на ней тестирую все плагины). Форвард даже не вызывался.
Руки уже опускаются. Не знаю, что ещё попробовать.



#2 dr_lex

dr_lex

    Постоянный пользователь

  • Пользователь
  • PipPipPipPipPip
  • 1 053 сообщений

Отправлено 03 Август 2020 - 9:00

Привет, форумчане! Писал плагин, который при определённых условиях должен отключать коллизию. Цель такая - сделать своего рода переключать, при включении которого, игрока нельзя будет схватить особыми зараженными. Пример - Громила должен пробегать сквозь игрока. Сначала баловался с m_nSolidType, m_CollisionGroup и m_usSolidFlags (0 2 0). За что получал спам в консоли player in solid list (not solid) в неограниченном количестве. Скорее всего я не подобрал нужные значения.
Потом я подумал попробовать сделать это через хитбоксы. Поиск по net_prop'y m_nHitboxSet не дал результатов (может, я плохо искал). Увидел про SDKHook_ShouldCollide. Этот гад крашит игру https://crash.limete...rg/prxlhdhg7hq5 . Я пробовал даже с пустой функцией хука. Всё равно крашит.
Потом прочитал про collisionhook.ext. Скорее всего из-за старых сигнатур он у меня не заработал (работаю из под винды и на ней тестирую все плагины). Форвард даже не вызывался.
Руки уже опускаются. Не знаю, что ещё попробовать.

А если пропустить Event событие? Ну чтобы не было захвата. Там же есть данные Event виде захвата, удара и т.д

Сообщение отредактировал dr_lex: 03 Август 2020 - 9:01


#3 PawnLomaster

PawnLomaster

    Участник

  • Пользователь
  • PipPip
  • 116 сообщений

Отправлено 03 Август 2020 - 9:59

А если пропустить Event событие? Ну чтобы не было захвата. Там же есть данные Event виде захвата, удара и т.д

Увы, но эвенты работают не так, иначе бы и sdkhook был и не нужен. Частая ошибка кстати.
Хороший пример - эвент нанесения урона player_hurt. Заблокировать урон не получится, если просто прописать Plugin_Stop или Plugin_Handled. Нужен хук SDKHook_OnTakeDamage. Тогда с уроном можно сделать всё что угодно. Даже перенаправить.
Вопрос всё ещё открыт 
 


Сообщение отредактировал PawnLomaster: 03 Август 2020 - 10:00


#4 BHaType

BHaType

    Пользователь

  • Пользователь
  • PipPipPip
  • 358 сообщений

Отправлено 03 Август 2020 - 11:26

SetEntProp(client, Prop_Data, "m_CollisionGroup", 2) и самому высчитывать момент когда нужно убрать колизию

 

либо так

 

Скрытый текст

 

Тут ещё желательно добавить bool переменную, которая проверяет использует ли громила абилку


Сообщение отредактировал BHaType: 03 Август 2020 - 11:27


#5 dr_lex

dr_lex

    Постоянный пользователь

  • Пользователь
  • PipPipPipPipPip
  • 1 053 сообщений

Отправлено 03 Август 2020 - 15:32

Увы, но эвенты работают не так, иначе бы и sdkhook был и не нужен. Частая ошибка кстати.
Хороший пример - эвент нанесения урона player_hurt. Заблокировать урон не получится, если просто прописать Plugin_Stop или Plugin_Handled. Нужен хук SDKHook_OnTakeDamage. Тогда с уроном можно сделать всё что угодно. Даже перенаправить.
Вопрос всё ещё открыт


Ну по сути есть же много примеров)
Например блокировка взятия предметов через event item_pickup или блокировка зацепления игроков руками при падении вниз через event player_jump
По этому в принципе это можно сделать)



#6 BHaType

BHaType

    Пользователь

  • Пользователь
  • PipPipPip
  • 358 сообщений

Отправлено 03 Август 2020 - 16:40

Ну по сути есть же много примеров)
Например блокировка взятия предметов через event item_pickup или блокировка зацепления игроков руками при падении вниз через event player_jump
По этому в принципе это можно сделать)

Эвенты это просто оповещение, само действие через них невозможно заблокировать


  • anarki1980 это нравится

#7 8rutu5

8rutu5

    Пользователь

  • Пользователь
  • PipPipPip
  • 397 сообщений

Отправлено 03 Август 2020 - 17:50

Есть вариант получше. Я пока не дома и не могу скинуть примерно то, что ты хочешь. Но тебе скорее всего надо работать не с коллизией, а с годфреймами (godframe). Это такая штука, которая срабатывает после того, как тебя схватит или отпустят особые заражённые. Суть ее в том, чтобы защитить выжившего на небольшое время от урона и возможности быть схваченным пока он встаёт после освобождения. Если прям не терпится, то поищи плагин или исходник godframe_control, он должен быть у SirPlease в гитхабе в ветке ZoneMod как один из плагинов. Там же и исходник вроде был. Если подождешь, то постараюсь его найти на своём компе. Может по его принципу сможешь включать годфреймы тогда, когда тебе надо. Я с ним так до конца не разобрался. Но думаю это наилучший вариант будет для тебя.

Хотя может и код Внатуре тебе поможет. Потести в общем.

 

 

UPD: https://github.com/S...ontrol_merge.sp

 

Потребуется L4D2_Direct как минимум.

 

Там тебя будет интересовать в OnTakeDamage следующие строки:

 

new CountdownTimer:cTimerGod = L4D2Direct_GetInvulnerabilityTimer(victim);
if (cTimerGod != CTimer_Null) { CTimer_Invalidate(cTimerGod); }

Скорее всего это то, что нужно


Сообщение отредактировал 8rutu5: 03 Август 2020 - 20:07


#8 PawnLomaster

PawnLomaster

    Участник

  • Пользователь
  • PipPip
  • 116 сообщений

Отправлено 15 Август 2020 - 20:53

 

Есть вариант получше. Я пока не дома и не могу скинуть примерно то, что ты хочешь. Но тебе скорее всего надо работать не с коллизией, а с годфреймами (godframe). Это такая штука, которая срабатывает после того, как тебя схватит или отпустят особые заражённые. Суть ее в том, чтобы защитить выжившего на небольшое время от урона и возможности быть схваченным пока он встаёт после освобождения. Если прям не терпится, то поищи плагин или исходник godframe_control, он должен быть у SirPlease в гитхабе в ветке ZoneMod как один из плагинов. Там же и исходник вроде был. Если подождешь, то постараюсь его найти на своём компе. Может по его принципу сможешь включать годфреймы тогда, когда тебе надо. Я с ним так до конца не разобрался. Но думаю это наилучший вариант будет для тебя.

Хотя может и код Внатуре тебе поможет. Потести в общем.

 

 

UPD: https://github.com/S...ontrol_merge.sp

 

Потребуется L4D2_Direct как минимум.

 

Там тебя будет интересовать в OnTakeDamage следующие строки:

 

new CountdownTimer:cTimerGod = L4D2Direct_GetInvulnerabilityTimer(victim);
if (cTimerGod != CTimer_Null) { CTimer_Invalidate(cTimerGod); }

Скорее всего это то, что нужно

 

Не совсем то, что нужно, но направление правильное.
Если посмотреть, что в коде происходит, то можно увидеть, что cTimerGod используется только чтобы убрать God фреймы, дабы передать контроль за этим делом плагину, где он использует уже обычный Plugin_Handled в OnTakeDamage на "неугодном" уроне. Урон заблокирует, но не схватывание Охотником (это для тех, кто зациклился на блокировании Громилы).
Решение близко. Осталось узнать про этот таймер. Я уверен, что он есть в netprop'ах. Просто там не отображается название таймера. Осталось узнать, как получить имя таймера.
Например, имеем CChargerClaw

Sub-Class Table (4 Deep): DT_CountdownTimer
  -Member: m_duration (offset 4) (type float) (bits 0)
  -Member: m_timestamp (offset 8) (type float) (bits 0)
Sub-Class Table (4 Deep): DT_CountdownTimer
  -Member: m_duration (offset 4) (type float) (bits 0)
  -Member: m_timestamp (offset 8) (type float) (bits 0)

Прямое цитирование с https://wiki.alliedm...s#CChargerClaw:
Один из этих таймеров имеет имя m_attackTimer. Изменение m_attackTimer+8 позволит изменить кулдаун атаки. Поиск по m_attackTimer на сайте не даст результата, но он есть.
Вопрос. Как узнать имена DT_CountdownTimer таймеров. И как узнать имя нетпропа таймера, который используется в L4D2Direct_GetInvulnerabilityTimer



#9 8rutu5

8rutu5

    Пользователь

  • Пользователь
  • PipPipPip
  • 397 сообщений

Отправлено 16 Август 2020 - 2:26

Не совсем то, что нужно, но направление правильное.
Если посмотреть, что в коде происходит, то можно увидеть, что cTimerGod используется только чтобы убрать God фреймы, дабы передать контроль за этим делом плагину, где он использует уже обычный Plugin_Handled в OnTakeDamage на "неугодном" уроне. Урон заблокирует, но не схватывание Охотником (это для тех, кто зациклился на блокировании Громилы).
Решение близко. Осталось узнать про этот таймер. Я уверен, что он есть в netprop'ах. Просто там не отображается название таймера. Осталось узнать, как получить имя таймера.
Например, имеем CChargerClaw

Sub-Class Table (4 Deep): DT_CountdownTimer
  -Member: m_duration (offset 4) (type float) (bits 0)
  -Member: m_timestamp (offset 8) (type float) (bits 0)
Sub-Class Table (4 Deep): DT_CountdownTimer
  -Member: m_duration (offset 4) (type float) (bits 0)
  -Member: m_timestamp (offset 8) (type float) (bits 0)

Прямое цитирование с https://wiki.alliedm...s#CChargerClaw:
Один из этих таймеров имеет имя m_attackTimer. Изменение m_attackTimer+8 позволит изменить кулдаун атаки. Поиск по m_attackTimer на сайте не даст результата, но он есть.
Вопрос. Как узнать имена DT_CountdownTimer таймеров. И как узнать имя нетпропа таймера, который используется в L4D2Direct_GetInvulnerabilityTimer

 

stock CountdownTimer:L4D2Direct_GetInvulnerabilityTimer(client)
{
	if (client < 1 || client > MaxClients)
		return CTimer_Null;

	new Address:pEntity = GetEntityAddress(client);
	if (pEntity == Address_Null)
		return CTimer_Null;

	new offs = GameConfGetOffset(L4D2Direct_GetGameConf(), "CTerrorPlayer::InvulnerabilityTimer");
	if (offs == -1)
		return CTimer_Null;

	return CountdownTimer:(pEntity + Address:offs);
}

CTerrorPlayer::InvulnerabilityTimer - возможно то, что тебе нужно, либо зацепка, которая может помочь



#10 BHaType

BHaType

    Пользователь

  • Пользователь
  • PipPipPip
  • 358 сообщений

Отправлено 16 Август 2020 - 3:06

Этот таймер бессмертия сделает игрока просто бессмертным, но поймать его сможет кто угодно, игра запрещает ловить игрока когда у него проигрывается  определённая анимация и даже если захукать функцию IsGettingUp, то да, игрока никто не сможет поймать, но он также не сможет ходить или вообще что либо делать.

 

Скрытый текст

 

Я уверен, что он есть в netprop'ах

 

Нет, это вообще не проп, а обычная переменная класса о которой скорее всего знает только сервер

// также просто получить, как и записать
float time = view_as<float>(LoadFromAddress(GetEntityAddress(client) + view_as<Address>(0x2E9C), NumberType_Int32));

Как я показал ранее, тебе либо хукать способности всех боссов, по примеру который я тебе скинул, либо просто ставить  

SetEntProp(client, Prop_Data, "m_CollisionGroup", 2) - работает просто прекрасно (сам проверял)

P.S Я не циклился на одном громе, лишь показал пример, как можно захукать колизию "способности", точно по такому же принципу можно захукать любую способность, любого босса.


Сообщение отредактировал BHaType: 16 Август 2020 - 3:15



Количество пользователей, читающих эту тему: 0

0 пользователей, 0 гостей, 0 анонимных