Загрузка данных
#include <amxmodx>
#include <reapi>
#define MAX_KB_WEAPONS 32
// -----------------------------------------------------------------------------
// Knockback configuration
// -----------------------------------------------------------------------------
const Float:KB_DEFAULT_MULTIPLIER = 1.0;
const Float:KB_GLOBAL_MULTIPLIER = 2.0;
const Float:KB_DUCK_MULTIPLIER = 0.25;
// -----------------------------------------------------------------------------
// Weapon knockback multipliers
//
// Index == CSW_* weapon id.
//
// 0.0 = use default multiplier.
// -----------------------------------------------------------------------------
new const Float:g_flWeaponKnockback[MAX_KB_WEAPONS] =
{
0.0, // 0
2.4, // CSW_P228
0.0, // CSW_SHIELD
6.5, // CSW_SCOUT
0.0, // 4
8.0, // CSW_XM1014
0.0, // CSW_C4
2.3, // CSW_MAC10
5.0, // CSW_AUG
0.0, // CSW_SMOKEGRENADE
2.4, // CSW_ELITE
2.0, // CSW_FIVESEVEN
2.4, // CSW_UMP45
5.3, // CSW_SG550
5.5, // CSW_GALIL
5.5, // CSW_FAMAS
2.2, // CSW_USP
2.0, // CSW_GLOCK18
10.0, // CSW_AWP
2.5, // CSW_MP5NAVY
5.2, // CSW_M249
8.0, // CSW_M3
5.0, // CSW_M4A1
2.4, // CSW_TMP
6.5, // CSW_G3SG1
0.0, // CSW_FLASHBANG
5.3, // CSW_DEAGLE
5.0, // CSW_SG552
6.0, // CSW_AK47
0.0, // CSW_KNIFE
2.0 // CSW_P90
};
// -----------------------------------------------------------------------------
// Initialization
// -----------------------------------------------------------------------------
public plugin_init()
{
RegisterHookChain(
RH_CBasePlayer_TraceAttack,
"CBasePlayer_TraceAttack_Post",
true
);
}
// -----------------------------------------------------------------------------
// TraceAttack
// -----------------------------------------------------------------------------
@CBasePlayer_TraceAttack_Post(
victim,
attacker,
Float:damage,
Float:direction[3],
traceHandle,
damageBits
)
{
// We are interested only in bullet damage.
if (!(damageBits & DMG_BULLET))
return;
// Invalid attacker / self damage.
if (victim == attacker)
return;
if (!is_user_connected(attacker))
return;
// Victim must be able to receive damage.
if (!rg_is_player_can_takedamage(victim, attacker))
return;
// Apply knockback.
ApplyKnockback(
victim,
attacker,
damage,
direction
);
}
// -----------------------------------------------------------------------------
// Apply knockback
// -----------------------------------------------------------------------------
stock ApplyKnockback(
const victim,
const attacker,
const Float:damage,
const Float:direction[3]
)
{
new weapon = get_user_weapon(attacker);
if (!IsValidWeapon(weapon))
return;
new Float:weaponMultiplier =
GetWeaponKnockbackMultiplier(weapon);
new Float:stanceMultiplier =
GetStanceKnockbackMultiplier(victim);
new Float:knockback =
damage *
weaponMultiplier *
stanceMultiplier *
KB_GLOBAL_MULTIPLIER;
new Float:velocity[3];
get_entvar(
victim,
var_velocity,
velocity
);
velocity[0] += direction[0] * knockback;
velocity[1] += direction[1] * knockback;
velocity[2] += direction[2] * knockback;
set_entvar(
victim,
var_velocity,
velocity
);
}
// -----------------------------------------------------------------------------
// Weapon validation
// -----------------------------------------------------------------------------
stock bool:IsValidWeapon(const weapon)
{
return (
weapon > 0 &&
weapon < sizeof g_flWeaponKnockback
);
}
// -----------------------------------------------------------------------------
// Get weapon knockback multiplier
// -----------------------------------------------------------------------------
stock Float:GetWeaponKnockbackMultiplier(const weapon)
{
new Float:multiplier =
g_flWeaponKnockback[weapon];
if (multiplier <= 0.0)
multiplier = KB_DEFAULT_MULTIPLIER;
return multiplier;
}
// -----------------------------------------------------------------------------
// Get stance multiplier
// -----------------------------------------------------------------------------
stock Float:GetStanceKnockbackMultiplier(const player)
{
new flags = get_entvar(
player,
var_flags
);
if (flags & FL_DUCKING)
return KB_DUCK_MULTIPLIER;
return 1.0;
}