Участник
Пользователь
- Сообщения
- 893
- Реакции
- 149
- Помог
- 25 раз(а)
Здравствуйте.
Сегодня хотелось бы затронуть такую тему, как плагины для меню с ножами.
Обычно они используются на серверах с ZP 4.3/ZP 5.0/Biohazard модами.
Как правило, в старых кодах урон увеличивается в Ham_TakeDamage через SetHamParamFloat.
Для примера я взял данный плагин.
В нем есть следующий код:
Как видим, тут идет увеличение через SetHamParamFloat путём умножения значение урона (damage) на нужное число (к примеру это квар get_pcvar_float(dmg_knife1)).
Но, если кинуть гранату и в этот момент взять 1 из ножиков, то в момент взрыва гранаты урон у взрыва будет так-же увеличен.
Так же не стоит забывать и за кастомные оружия, к примеру, взять тот же плазма ган, который стреляет не пулями, а некими "шарами".
Ниже показан код одного из плазмаганов.
Как мы можем наблюдать, тут идёт функция:
Тут хотелось бы уточнить, что есть два метода вызова Ham хуков, а конкретно
У некоторых людей возникает вопрос:
Почему так происходит? Ответ прост.
1 - Если брать конкретно данное меню ножей, то мы можем увидить, что там есть проверка на то, есть ли в руке нож, и по факту - всё, дальше сторонние проверки от плагина. Так вот, у нас есть такая штука (5 параметр в Ham_TakeDamage) как damage_type.
Этот параметр позволяет проверять тип урона, к примеру, у гранаты тип урона DMG_GRENADE, следовательно, что бы исправить проблему, можно использовать проверку на тип урона конкретно от гранаты, но как же быть с кастомными оружиями?
На самом деле, можно обойтись проверкой на тип конкретно от гранаты, и сделать немного другим путём.
У оружия/ножей есть 2 бита аттаки, а именно DMG_NEVERGIB и DMG_BULLET, так вот, можно сделать проверку, что если игрок держит в руках нож и тип урона есть DMG_BULELT - мы можем увеличить урон в этот момент. Это избавит нас от проблем с увеличением урона от гранат и кастомных оружий, где используется
По итогу, код будет следующим:
Со всеми типами урона можно ознакомится тут.
Так же хотелось бы услышать мнение более опытных людей, возможно, они подскажут еще какие-то методы.
Кстати, на реапи есть такие мемберы (не знаю, на fakemete есть они или нет), как:
Код взят отсюда.
Учту, что данный мембер вешается на предмет, можно как-то и с этим поиграться, и выставлять урон конкретно предмету, а не игроку.
UPD 03.10.2023 (thanx to Vaqutincha).
Еще можно проверить inflictor != attacker (это граната) а на оружиях инфликтор всегда равен аттакеру (ну на деф оружиях).
Сегодня хотелось бы затронуть такую тему, как плагины для меню с ножами.
Обычно они используются на серверах с ZP 4.3/ZP 5.0/Biohazard модами.
Как правило, в старых кодах урон увеличивается в Ham_TakeDamage через SetHamParamFloat.
Для примера я взял данный плагин.
В нем есть следующий код:
C++:
public plugin_init()
{
...
RegisterHam(Ham_TakeDamage, "player", "fw_TakeDamage")
}
public fw_TakeDamage(victim, inflictor, attacker, Float:damage, damage_type)
{
if(!is_user_connected(attacker)) return HAM_IGNORED
if(zp_get_user_zombie(attacker)) return HAM_IGNORED
new weapon = get_user_weapon(attacker)
if(weapon == CSW_KNIFE && g_knife6[attacker])
{
SetHamParamFloat(4, damage * get_pcvar_float(dmg_knife6))
if(g_sp[attacker])
{
if( !task_exists( victim + TASK_FBURN ) )
{
g_burning_duration[victim] += get_pcvar_num(g_fire_time) * 5
set_task(0.1, "CTask__BurningFlame", victim + TASK_FBURN, _, _, "b" )
}
}
}
else
{
if(!g_freeze_wait[attacker] && !zp_get_user_nemesis(victim))
{
set_pev(victim, pev_flags, pev(victim, pev_flags) | FL_FROZEN)
set_user_rendering(victim, kRenderFxGlowShell, 0, 206, 209, kRenderNormal, 25)
g_frozen[victim] = true
set_task(get_pcvar_float(g_time_freeze), "end", victim)
g_freeze_wait[attacker] = true
set_task(get_pcvar_float(g_time_freeze_wait), "Freeze_Wait", attacker + 1233123)
}
}
// Конкретно тут уже идет увеличение урона.
if(weapon == CSW_KNIFE && g_knife5[attacker])
{
SetHamParamFloat(4, damage * get_pcvar_float(dmg_knife5))
}
if(weapon == CSW_KNIFE && g_knife4[attacker])
{
SetHamParamFloat(4, damage * get_pcvar_float(dmg_knife4))
}
if(weapon == CSW_KNIFE && g_knife3[attacker])
{
SetHamParamFloat(4, damage * get_pcvar_float(dmg_knife3))
}
if(weapon == CSW_KNIFE && g_knife2[attacker])
{
SetHamParamFloat(4, damage * get_pcvar_float(dmg_knife2))
}
if(weapon == CSW_KNIFE && g_knife1[attacker])
{
SetHamParamFloat(4, damage * get_pcvar_float(dmg_knife1))
}
return HAM_IGNORED
}
Но, если кинуть гранату и в этот момент взять 1 из ножиков, то в момент взрыва гранаты урон у взрыва будет так-же увеличен.
Так же не стоит забывать и за кастомные оружия, к примеру, взять тот же плазма ган, который стреляет не пулями, а некими "шарами".
Ниже показан код одного из плазмаганов.
Код:
public Damage_Plasma(Ent, Id)
{
static Owner; Owner = pev(Ent, pev_iuser1)
static Attacker;
if(!is_user_alive(Owner))
{
Attacker = 0
return
} else Attacker = Owner
if(is_user_alive(Id) && is_user_zombie(Id))
{
ExecuteHamB(Ham_TakeDamage, Id, Ent, Attacker, float(DAMAGE), DMG_ACID)
}
for(new i = 0; i < g_MaxPlayers; i++)
{
if(!is_user_alive(i))
continue
if(entity_range(i, Ent) > PLASMA_RADIUS)
continue
if(!is_user_zombie(i))
continue
ExecuteHamB(Ham_TakeDamage, i, Ent, Attacker, float(DAMAGE) / random_float(1.25, 1.5), DMG_ACID)
}
}
C++:
ExecuteHamB(Ham_TakeDamage, i, Ent, Attacker, float(DAMAGE) / random_float(1.25, 1.5), DMG_ACID)
C++:
ExecuteHam // - Вызывается без кода из сторонних плагинов.
ExecuteHamB // - Он может вызвать хуки в других плагинах.
Почему так происходит? Ответ прост.
1 - Если брать конкретно данное меню ножей, то мы можем увидить, что там есть проверка на то, есть ли в руке нож, и по факту - всё, дальше сторонние проверки от плагина. Так вот, у нас есть такая штука (5 параметр в Ham_TakeDamage) как damage_type.
Этот параметр позволяет проверять тип урона, к примеру, у гранаты тип урона DMG_GRENADE, следовательно, что бы исправить проблему, можно использовать проверку на тип урона конкретно от гранаты, но как же быть с кастомными оружиями?
На самом деле, можно обойтись проверкой на тип конкретно от гранаты, и сделать немного другим путём.
У оружия/ножей есть 2 бита аттаки, а именно DMG_NEVERGIB и DMG_BULLET, так вот, можно сделать проверку, что если игрок держит в руках нож и тип урона есть DMG_BULELT - мы можем увеличить урон в этот момент. Это избавит нас от проблем с увеличением урона от гранат и кастомных оружий, где используется
C++:
ExecuteHam/ExecuteHamB(Take_Damage, any...);
C++:
public fw_TakeDamage(victim, inflictor, attacker, Float:damage, damage_type)
{
if(!is_user_connected(attacker)) return HAM_IGNORED
if(zp_get_user_zombie(attacker)) return HAM_IGNORED
new weapon = get_user_weapon(attacker)
if(weapon == CSW_KNIFE && g_knife6[attacker])
{
SetHamParamFloat(4, damage * get_pcvar_float(dmg_knife6))
if(g_sp[attacker])
{
if( !task_exists( victim + TASK_FBURN ) )
{
g_burning_duration[victim] += get_pcvar_num(g_fire_time) * 5
set_task(0.1, "CTask__BurningFlame", victim + TASK_FBURN, _, _, "b" )
}
}
}
else
{
if(!g_freeze_wait[attacker] && !zp_get_user_nemesis(victim))
{
set_pev(victim, pev_flags, pev(victim, pev_flags) | FL_FROZEN)
set_user_rendering(victim, kRenderFxGlowShell, 0, 206, 209, kRenderNormal, 25)
g_frozen[victim] = true
set_task(get_pcvar_float(g_time_freeze), "end", victim)
g_freeze_wait[attacker] = true
set_task(get_pcvar_float(g_time_freeze_wait), "Freeze_Wait", attacker + 1233123)
}
}
// проверяем на тип урона
if(damage_type & DMG_BULLET)
{
// Конкретно тут уже идет увеличение урона.
if(weapon == CSW_KNIFE && g_knife5[attacker])
{
SetHamParamFloat(4, damage * get_pcvar_float(dmg_knife5))
}
if(weapon == CSW_KNIFE && g_knife4[attacker])
{
SetHamParamFloat(4, damage * get_pcvar_float(dmg_knife4))
}
if(weapon == CSW_KNIFE && g_knife3[attacker])
{
SetHamParamFloat(4, damage * get_pcvar_float(dmg_knife3))
}
if(weapon == CSW_KNIFE && g_knife2[attacker])
{
SetHamParamFloat(4, damage * get_pcvar_float(dmg_knife2))
}
if(weapon == CSW_KNIFE && g_knife1[attacker])
{
SetHamParamFloat(4, damage * get_pcvar_float(dmg_knife1))
}
}
return HAM_IGNORED
}
Так же хотелось бы услышать мнение более опытных людей, возможно, они подскажут еще какие-то методы.
Кстати, на реапи есть такие мемберы (не знаю, на fakemete есть они или нет), как:
C++:
set_member(iWeapon, m_Knife_flStabBaseDamage, Float: get_member(iWeapon, m_Knife_flStabBaseDamage) * Множитель урона);
set_member(iWeapon, m_Knife_flSwingBaseDamage, Float: get_member(iWeapon, m_Knife_flSwingBaseDamage) * Множитель урона);
set_member(iWeapon, m_Knife_flSwingBaseDamage_Fast, Float: get_member(iWeapon, m_Knife_flSwingBaseDamage_Fast) * Множитель урона);
Учту, что данный мембер вешается на предмет, можно как-то и с этим поиграться, и выставлять урон конкретно предмету, а не игроку.
UPD 03.10.2023 (thanx to Vaqutincha).
Еще можно проверить inflictor != attacker (это граната) а на оружиях инфликтор всегда равен аттакеру (ну на деф оружиях).
Последнее редактирование: