Правила форума Гаранты форума
Размещение рекламы AMX-X компилятор

Здравствуйте, гость Вход | Регистрация

Наши новости:

14-дек
24-апр
10-апр
11-апр

Only HS без блокировки крови

, блокировка только урона
Статус пользователя ssx
сообщение 13.3.2017, 0:41
Сообщение #1


Стаж: 12 лет

Сообщений: 2237
Благодарностей: 1343
Полезность: 836

Всем привет!

Задался вопросом, сделать игрокам плагин Only HS с блокировкой только урона если попал не в голову.

В Ham_TraceAttack есть возможность проверить на хитбокс, но это нам не подходит т.к. кровь и само попадание блокируется.
В Pre Ham_TakeDamage было бы хорошо отлавливать и блокировать урон если не в голову наносится , но вот незадача, не нашел как хитбокс определить .

Кто знает как можно эту идею реализовать ?


[Half-Life DM FFA] 78.152.169.100:27016
[CS 1.6 GunGame] 78.152.169.100:27018
[CS 1.6 DM AIM] 78.152.169.100:27017
[CS 1.6 DM FFA] 78.152.169.100:27015
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   Цитировать сообщение
Статус пользователя SISA
сообщение 13.3.2017, 2:22
Сообщение #2
Стаж: 15 лет

Сообщений: 2774
Благодарностей: 2956
Полезность: 994

75й оффсет:

#define m_LastHitGroup 75

Надо ещё помнить, что у дробовиков при выстреле 8 трейсов и 1 дамаг. Если попал, допустим, несколькими пулями в торс, а несколькими в бубен, то в дамаге будет хитбокс бубна и наоборот.

Как вариант, можно блокнуть трейс и отрисовать свой кровяк. Код могу подкинуть, там пара функций.

Отредактировал: SISA, - 13.3.2017, 2:26
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
Поблагодарили 2 раз
   + Цитировать сообщение
Статус пользователя ssx
сообщение 13.3.2017, 15:00
Сообщение #3


Стаж: 12 лет

Сообщений: 2237
Благодарностей: 1343
Полезность: 836

Если бы только в крови была проблема. Проблема в том что при блокировки в Ham_TraceAttack попадания игнорируются , то есть человека не колбасит и не приостанавливает от попаданий.

Я же хочу реализовать по человечески, что бы только урон не засчитывался.

Цитата
у дробовиков при выстреле 8 трейсов и 1 дамаг. Если попал, допустим, несколькими пулями в торс, а несколькими в бубен, то в дамаге будет хитбокс бубна и наоборот.

Ну тогда если большинство пуль попало не в голову то считать что в голову не попал вовсе.
Или есть вариант в трейсе блокировать и отрисовывать кровь + задерживать (колбасить) жертву ?


[Half-Life DM FFA] 78.152.169.100:27016
[CS 1.6 GunGame] 78.152.169.100:27018
[CS 1.6 DM AIM] 78.152.169.100:27017
[CS 1.6 DM FFA] 78.152.169.100:27015
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя SISA
сообщение 13.3.2017, 17:12
Сообщение #4
Стаж: 15 лет

Сообщений: 2774
Благодарностей: 2956
Полезность: 994

Цитата(ssx @ 13.3.2017, 17:00) *
Если бы только в крови была проблема. Проблема в том что при блокировки в Ham_TraceAttack попадания игнорируются , то есть человека не колбасит и не приостанавливает от попаданий.

Я же хочу реализовать по человечески, что бы только урон не засчитывался.


Ну тогда если большинство пуль попало не в голову то считать что в голову не попал вовсе.
Или есть вариант в трейсе блокировать и отрисовывать кровь + задерживать (колбасить) жертву ?

ssx,

Задержка жертвы происходит в Damage Post, как и часть эффектов.

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

Всё это, конечно, можно повторить на амх, но че та это как-то пипец... Если боишься бага с дробаном, тогда уж лучше подсчитывать количество попаданий в трейсе по всем хитбоксам и по бубну. Соответственно, если по бубну было больше половины попаданий, то его и детектить как попадание в голову. А от 75го оффсета, в таком случае, можно вообще отказаться. Просто записывать на игрока номер хитбокса в трейсе и брать его в дамаге.

Но всё это не решает проблему с засчитыванием урона.

Короч код такой должен быть:
Cкрытый текст

Код
#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>

#define SPR_BLOODDROP                        "sprites/blood.spr"                                // Куски разлетающейся крови
#define SPR_BLOODSPRAY                        "sprites/bloodspray.spr"                        // Спрайт кнови в точке попадания
#define is_user_valid(%1)                         (1 <= %1 <= g_iMaxPlayers)

// Sprites
new g_Blood_SprDrop, g_Blood_SprSpray;

// Others
new Float:g_Player_LastDmgTime[33];
new g_iMaxPlayers        // Max players counter

/*===============================================================================
================================================================
                                                                    [Plugin Init]
================================================================================
================================================================*/
public plugin_init()
{
    // TraceAttack
    RegisterHam(Ham_TraceAttack, "player", "fw_TraceAttack_Pre", 0);

    // Get Max Players
    g_iMaxPlayers = get_maxplayers();
}

/*===============================================================================
================================================================
                                                                    [Plugin Precache]
================================================================================
================================================================*/
public plugin_precache()
{
    g_Blood_SprDrop = precache_model(SPR_BLOODDROP);
    g_Blood_SprSpray = precache_model(SPR_BLOODSPRAY);
}

/*===============================================================================
================================================================
                                                                [Ham TraceAttack Pre]
================================================================================
================================================================*/
public fw_TraceAttack_Pre(victim, attacker, Float:damage, Float:direction[3], tracehandle, damage_bits)
{
    // Если Жертва или Аттакер Не Валидны
    if(!is_user_valid(victim) || !is_user_valid(attacker))
        return HAM_IGNORED;

    // Если Жертве Не попали в Хитбокс Голову
    if(get_tr2(tracehandle, TR_iHitgroup) != HIT_HEAD)
    {
        // Переменные
        new Float:VecEnd[3];

        // Находим текущее игровое Время
        new Float:flGameTime = get_gametime();

        // Если текущее игрокое время Больше Последнего запомненного (фикс множественного урона на Дробанах)
        if(flGameTime > g_Player_LastDmgTime[attacker])
        {
            // Вызываем фейковый урон, чтобы отбработать все эффекты
            ExecuteHam(Ham_TakeDamage, victim, attacker, attacker, 0.0, damage_bits);

            // Запоминаем текущее Время
            g_Player_LastDmgTime[attacker] = flGameTime;
        }

        // Рисуем кровь на стенах
        ExecuteHam(Ham_TraceBleed, get_tr2(tracehandle, TR_pHit), damage, direction, tracehandle, damage_bits);

        // Находим оригины точки попадания
        get_tr2(tracehandle, TR_vecEndPos, VecEnd);

        // Рисуем вылет кровь из Жертвы
        Make_SpawnBlood(VecEnd, damage);

        // Рисуем вылет кровь из Жертвы
        Make_BloodSplat(victim, VecEnd, direction, damage*5.0);

        return HAM_SUPERCEDE;
    }

    return HAM_IGNORED;
}

stock Make_SpawnBlood(const Float:vTraceEnd[3], Float:Damage)
{
    // Переводим в целое значение
    new amount = floatround(Damage);

    // Умножаем на 2
    amount *= 2;

    // Если размер больше максимального
    if(amount > 255)
        amount = 255;    // Ставим максимальный размер

    // Создаем Эффект разлета крови
    message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
    write_byte(TE_BLOODSPRITE);
    write_coord(floatround(vTraceEnd[0]));
    write_coord(floatround(vTraceEnd[1]));
    write_coord(floatround(vTraceEnd[2]));
    write_short(g_Blood_SprSpray);            // Spray
    write_short(g_Blood_SprDrop);            // Drop
    write_byte(247);                            // Color (red)
    write_byte(min(max(3, amount/10), 16));    // Size
    message_end();
}

stock Make_BloodSplat(victim, const Float:vTraceEnd[3], const Float:direction[3], Float:Damage)
{
    // Переменные
    new Float:fVelocity[3];

    // Переводим урон в целое Число
    new amount = floatround(Damage);

    // Находим ускорение Жертвы
    pev(victim, pev_velocity, fVelocity);

    // Создаем Брызки Крови
    engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, vTraceEnd, 0);
    write_byte(TE_BLOODSTREAM);
    engfunc(EngFunc_WriteCoord, vTraceEnd[0]);     // x (положение жертвы)
    engfunc(EngFunc_WriteCoord, vTraceEnd[1]);     // y (положение жертвы)
    engfunc(EngFunc_WriteCoord, vTraceEnd[2]);     // z (положение жертвы)
    engfunc(EngFunc_WriteCoord, direction[0]);        // x (направление вылета крови)
    engfunc(EngFunc_WriteCoord, direction[1]);        // y (направление вылета крови)
    engfunc(EngFunc_WriteCoord, direction[2]);        // z (направление вылета крови)
    write_byte(223);        // color
    write_byte(amount + random_num(0, 100));    // speed
    message_end();
}


Прикрепленный файл  test222.sma ( 5,29 килобайт ) Кол-во скачиваний: 8


Этот код эмулирует полностью всё, что происходит в двигле, с нулевым дамагом.

Отредактировал: SISA, - 13.3.2017, 17:13
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
Поблагодарили 1 раз
   + Цитировать сообщение
Статус пользователя SISA
сообщение 13.3.2017, 18:08
Сообщение #5
Стаж: 15 лет

Сообщений: 2774
Благодарностей: 2956
Полезность: 994

Ага, короч нулевой урон слать нельзя, иначе дирекшенов не будет у игрока на экране, а их там сложновато нарисовать, ещё и спекам их надо.

Короч обновил код. Тут урон фактический наносится, но HP не снимается + перекос экрана:

Прикрепленный файл  test222_v3.sma ( 6,29 килобайт ) Кол-во скачиваний: 14


Отредактировал: SISA, - 13.3.2017, 18:09
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
Поблагодарили 1 раз
   + Цитировать сообщение
Статус пользователя ssx
сообщение 13.3.2017, 18:42
Сообщение #6


Стаж: 12 лет

Сообщений: 2237
Благодарностей: 1343
Полезность: 836

Спасибо за код! и отдельное спасибище за комментарии в коде!

Затестировал плагин. Урон иногда наносится. Такое ощущение что когда мало хп у игрока то его можно убить не хедшотом.

Приложу демку .



Отредактировал: ssx, - 13.3.2017, 18:48
Прикрепленные файлы:
Прикрепленный файл  demo_only_hs.zip ( 1,57 мегабайт ) Кол-во скачиваний: 6


[Half-Life DM FFA] 78.152.169.100:27016
[CS 1.6 GunGame] 78.152.169.100:27018
[CS 1.6 DM AIM] 78.152.169.100:27017
[CS 1.6 DM FFA] 78.152.169.100:27015
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя SISA
сообщение 13.3.2017, 19:01
Сообщение #7
Стаж: 15 лет

Сообщений: 2774
Благодарностей: 2956
Полезность: 994

Да я чет забыл, что игрок дохнет в уроне.

Подправил баг + подправил сток "Make_SpawnBlood"

[attachment=43798:test222_v4.sma]

Сразу говорю, что будет мини-баг, когда у игрока будет 1HP, дирекшены на экране у него не нарисуются. В текущей реализации с этим ничего не сделать.

Отредактировал: SISA, - 13.3.2017, 19:08
Прикрепленные файлы:
Прикрепленный файл  test222_v5.sma ( 6,33 килобайт ) Кол-во скачиваний: 17
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
Поблагодарили 1 раз
   + Цитировать сообщение
Статус пользователя ssx
сообщение 13.3.2017, 20:03
Сообщение #8


Стаж: 12 лет

Сообщений: 2237
Благодарностей: 1343
Полезность: 836

Работает хорошо .

Только вот пытаюсь сделать исключение для ножа и гранаты
Код:
	// Если включил игрок режим Only HS
if(!g_Only_HS[attacker])
return HAM_IGNORED;

// Если Жертва или Аттакер Не Валидны
if(!is_user_valid(victim) || !is_user_valid(attacker))
return HAM_IGNORED;

// Игнорируем нож и гранату
static weapon; weapon = get_pdata_int(attacker, 43, 4);
if(weapon == CSW_KNIFE || weapon == CSW_HEGRENADE)
return HAM_IGNORED;

Не работает с ножом, с греной не тестил но подозреваю что так же .

Подскажите как определить оружие. Или проще через get_user_weapon ?

// UPD:
заменил на get_pdata_int(get_pdata_cbase(attacker, 373, 5), 43, 4)
и теперь работает как с ножом так и с гранатой.

Отредактировал: ssx, - 13.3.2017, 20:10


[Half-Life DM FFA] 78.152.169.100:27016
[CS 1.6 GunGame] 78.152.169.100:27018
[CS 1.6 DM AIM] 78.152.169.100:27017
[CS 1.6 DM FFA] 78.152.169.100:27015
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя SISA
сообщение 13.3.2017, 20:22
Сообщение #9
Стаж: 15 лет

Сообщений: 2774
Благодарностей: 2956
Полезность: 994

Код
static weapon; weapon = get_pdata_int(attacker, 43, 4);
if(weapon == CSW_KNIFE || weapon == CSW_HEGRENADE)
   return HAM_IGNORED;


Почему там 43, а не 87 миллиардов например ?

У гарнаты нет трейсов на игрока. У неё урон в сфере. В трейсе её бесполезно чекать, да и уроны по хитбоксам она не наносит.

Что касается определения ножа, то в дамаге можно сделать так:

if(get_user_weapon(attacker) == CSW_KNIFE)
return HAM_IGNORED;
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя ssx
сообщение 13.3.2017, 20:59
Сообщение #10


Стаж: 12 лет

Сообщений: 2237
Благодарностей: 1343
Полезность: 836

Цитата
Почему там 43, а не 87 миллиардов например ?

Если честно, то я не знаю что там цифры означают)) но код работает )

Цитата
У гарнаты нет трейсов на игрока.

Спс, убрал проверку на гранату.

Цитата
уроны по хитбоксам она не наносит.

В другом плагине у меня вывод попаданий в хитбоксы
Код:
register_event("Damage", "fwd_damage", "b", "2!0", "3=0")

проверил - от гранаты урон в разные хитбоксы.

Цитата
if(get_user_weapon(attacker) == CSW_KNIFE)
return HAM_IGNORED;

Читал что есть с этой проверкой баг
Цитата
Вообще игрок респавнится с тем оружием в руках, какое у него было в прошлом раунде, если не убили конечно.
Но есть исключение, когда в прошлом раунде у него была бомба и он её не скинул до начала нового раунда. Тогда он респавнится с лучшим оружием, то есть с автоматом или пистолетом, хотя перед началом нового раунда у него был нож.
И в этом случае функция возвращает неверный результат, она возвращает, что у него, нож, когда на самом деле АК47!
get_pdata_int(get_pdata_cbase(id, 373, 5), 43, 4) возвращает верное значение.

Цитата
в нём если заменить get_pdata_int(get_pdata_cbase(id, 373, 5), 43, 4) на get_user_weapon(id) после респавна можно стрелять с ножа если в прошлом раунде у тебя была бомба и ты от неё не избавился, а последним оружием которые ты держал в руках был нож.


Отредактировал: ssx, - 13.3.2017, 21:00


[Half-Life DM FFA] 78.152.169.100:27016
[CS 1.6 GunGame] 78.152.169.100:27018
[CS 1.6 DM AIM] 78.152.169.100:27017
[CS 1.6 DM FFA] 78.152.169.100:27015
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя SISA
сообщение 13.3.2017, 22:12
Сообщение #11
Стаж: 15 лет

Сообщений: 2774
Благодарностей: 2956
Полезность: 994

Цитата
В другом плагине у меня вывод попаданий в хитбоксы


Трейсов нет, а хитбоксы у гранаты - это баг самой КС, ибо не сбрасывается 75й оффсет.

Цитата
Читал что есть с этой проверкой баг


Тогда можно оставить твой код.
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
Поблагодарили 1 раз
   + Цитировать сообщение
  Ответить в данную темуНачать новую тему
 
0 пользователей и 1 гостей читают эту тему: