Загрузка данных


#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;
}