CSO Chainsaw

CSO Chainsaw 1.1

Нет прав для скачивания
Код:
/*
    Credits:    
        KORD_12.7 - knife plugin
        Koshak - model
        
        fixed by ET-NiK
*/
#include < amxmodx >
#include < engine >
#include < fakemeta >
#include < hamsandwich >
#include < hl_wpnmod >
#include < xs >

// Weapon settings
#define WEAPON_NAME             "weapon_chainsaw"
#define WEAPON_SLOT            1
#define WEAPON_POSITION            2
#define WEAPON_SECONDARY_AMMO        "" // NULL
#define WEAPON_SECONDARY_AMMO_MAX    -1
#define WEAPON_CLIP            100
#define WEAPON_FLAGS            0
#define WEAPON_WEIGHT            19

// Damage
#define CHAINSAW_DAMAGE            50.0
#define CHAINSAW_DAMAGE2        30.0

// Attack distance
#define CHAINSAW_DISTANCE        80.0
#define CHAINSAW_DISTANCE2        80.0

// Attack speed
#define CHAINSAW_REFIRE_RATE2        0.7

// Weapon models
#define MODEL_WORLD            "models/w_chainsaw.mdl"
#define MODEL_VIEW            "models/v_chainsaw.mdl"
#define MODEL_PLAYER            "models/p_chainsaw.mdl"

// v_ model animation sequence indexes
#define SEQ_DEPLOY            1
#define SEQ_DEPLOY_EMPTY        2    
#define SEQ_LOOP_START            3
#define SEQ_LOOP            4
#define SEQ_LOOP_END            5
#define SEQ_SLASH            7
#define SEQ_IDLE            0
#define SEQ_IDLE_EMPTY            11
#define SEQ_RELOAD            6

// Fire sound
#define SOUND_START            "weapons/chainsaw_attack1_start.wav"
#define SOUND_FIRE            "weapons/chainsaw_attack1_loop.wav"
#define SOUND_END            "weapons/chainsaw_attack1_end.wav"
#define SOUND_HIT_WALL            "weapons/chainsaw_hit1.wav"
#define SOUND_HIT_FLESH            "weapons/chainsaw_hit3.wav"
#define SOUND_MISS            "weapons/chainsaw_miss.wav"

// Ammo
#define AMMO_NAME            "petrol"
#define AMMO_MAX            200
#define AMMO_DEFAULT            50
#define FUEL_REMOVE_SPEED        0.25 // how fast ammo is depleting

// Playermodel animation extension
#define ANIM_EXTENSION            "bow"

// Other sounds, built into model
new const SOUND_SAW[ ][ ]        =
{
    "weapons/chainsaw_draw1.wav",
    "weapons/chainsaw_draw.wav",
    "weapons/chainsaw_idle.wav",
    "weapons/chainsaw_reload.wav"
};

// HUD sprites
new const HUD_SPRITES[ ][ ]        =
{
    "sprites/weapon_chainsaw.txt",    // should match with WEAPON_NAME
    "sprites/640hud84.spr",
    "sprites/640hud21.spr"
}
//=======================================================
//=======================================================

// Hit volume
#define    CHAINSAW_BODYHIT_VOLUME        128
#define    CHAINSAW_WALLHIT_VOLUME        512

#define Instance(%0)             ( ( %0 == -1 ) ? 0 : %0 )
//
// Precache the resources
//
public plugin_precache( )
{
    new i;
    
    //models
    PRECACHE_MODEL( MODEL_PLAYER );
    PRECACHE_MODEL( MODEL_VIEW );
    PRECACHE_MODEL( MODEL_WORLD );
    
    //sounds
    PRECACHE_SOUND( SOUND_START );
    PRECACHE_SOUND( SOUND_FIRE );
    PRECACHE_SOUND( SOUND_END );
    PRECACHE_SOUND( SOUND_HIT_FLESH );
    PRECACHE_SOUND( SOUND_HIT_WALL );
    
    PRECACHE_SOUND( SOUND_MISS );
    
    //built into model
    for( i = 0; i < sizeof( SOUND_SAW ); i++ )
        PRECACHE_SOUND( SOUND_SAW[ i ] );
    
    //sprites
    for( i = 0; i < sizeof( HUD_SPRITES ); i++ )
        PRECACHE_GENERIC( HUD_SPRITES[ i ] );
}
// 
// Register the weapon & co
//
public plugin_init( )
{
    register_plugin( "[HL] Chainsaw", "1.1", "NiHiLaNTh" );
    //
    //weapon
    //
    new pChainsaw = wpnmod_register_weapon
    (
        WEAPON_NAME,
        WEAPON_SLOT,
        WEAPON_POSITION,
        AMMO_NAME,
        AMMO_MAX,
        WEAPON_SECONDARY_AMMO,
        WEAPON_SECONDARY_AMMO_MAX,
        WEAPON_CLIP,
        WEAPON_FLAGS,
        WEAPON_WEIGHT
    );
    
    wpnmod_register_weapon_forward( pChainsaw, Fwd_Wpn_Spawn,         "CChainsaw__Spawn" );
    wpnmod_register_weapon_forward( pChainsaw, Fwd_Wpn_Deploy,         "CChainsaw__Deploy" );
    wpnmod_register_weapon_forward( pChainsaw, Fwd_Wpn_Holster,         "CChainsaw__Holster" );
    wpnmod_register_weapon_forward( pChainsaw, Fwd_Wpn_PrimaryAttack,     "CChainsaw__PrimaryAttack" );
    wpnmod_register_weapon_forward( pChainsaw, Fwd_Wpn_SecondaryAttack,    "CChainsaw__SecondaryAttack" );
    wpnmod_register_weapon_forward( pChainsaw, Fwd_Wpn_Reload,         "CChainsaw__Reload" );
    wpnmod_register_weapon_forward( pChainsaw, Fwd_Wpn_Idle,         "CChainsaw__WeaponIdle" );
}

//
// Weapon appeared on the world
//
public CChainsaw__Spawn( pWeapon )
{
    SET_MODEL( pWeapon, MODEL_WORLD );
    wpnmod_set_offset_int( pWeapon, Offset_iDefaultAmmo, AMMO_DEFAULT );
}
//
// Weapon deploy
//
public CChainsaw__Deploy( pWeapon, pPlayer, iClip )
{
    wpnmod_set_offset_int( pWeapon, Offset_iChargeReady, 0 );
    
    return wpnmod_default_deploy( pWeapon, MODEL_VIEW, MODEL_PLAYER, !iClip ? SEQ_DEPLOY_EMPTY : SEQ_DEPLOY, ANIM_EXTENSION );
}
//
// Weapon hide
//
public CChainsaw__Holster( pWeapon, pPlayer )
{
    // cancel any reload in progress
    wpnmod_set_offset_int( pWeapon, Offset_iInReload, 0 );
    
    // stop attacking
    CChainsaw__EndAttack( pWeapon, pPlayer, 0 );
}
//
// Weapon fire
//
public CChainsaw__PrimaryAttack( pWeapon, pPlayer, iClip )
{
    static iChargeReady;
    iChargeReady = wpnmod_get_offset_int( pWeapon, Offset_iChargeReady );
    
    if( entity_get_int( pPlayer, EV_INT_waterlevel ) == 3 )
    {
        if( iChargeReady > 0 )
        {
            CChainsaw__EndAttack( pWeapon, pPlayer );
        }
        else
        {
            CChainsaw__EmptyAttack( pWeapon, pPlayer );
        }
        return;
    }
    
    if( iClip <= 0 )
    {
        if( iChargeReady > 0 )
        {
            CChainsaw__EndAttack( pWeapon, pPlayer );
        }
        else
        {
            CChainsaw__EmptyAttack( pWeapon, pPlayer );
        }
        return;
    }
    
    static Float:tTime;
    tTime = get_gametime( );
        
    switch( iChargeReady )
    {
        case 0:
        {
            emit_sound( pPlayer, CHAN_WEAPON, SOUND_START, 1.0, ATTN_NORM, 0, PITCH_NORM );
            wpnmod_send_weapon_anim( pWeapon, SEQ_LOOP_START );
            
            wpnmod_set_offset_int( pWeapon, Offset_iChargeReady, 1 );
            wpnmod_set_offset_float( pWeapon, Offset_flTimeWeaponIdle, 0.3 );
            return;
        }
        case 1:
        {
            if( wpnmod_get_offset_float( pWeapon, Offset_flTimeWeaponIdle ) > 0.0 )
                return;
            
            wpnmod_send_weapon_anim( pWeapon, SEQ_LOOP );
            emit_sound( pPlayer, CHAN_WEAPON, SOUND_FIRE, 1.0, ATTN_NORM, 0, PITCH_NORM );
            wpnmod_set_offset_float( pWeapon, Offset_flNextPrimaryAttack, 0.1 );
            
            //dont try to use secondary attack until we end this one!
            wpnmod_set_offset_float( pWeapon, Offset_flNextSecondaryAttack, 9999.0 ); 
            
            wpnmod_set_player_anim( pPlayer, PLAYER_ATTACK1 );
            
            if( tTime >= wpnmod_get_offset_float( pWeapon, Offset_flReleaseThrow ) )
            {
                wpnmod_set_offset_int( pWeapon, Offset_iClip, iClip - 1 );
                wpnmod_set_offset_float( pWeapon, Offset_flReleaseThrow, tTime + FUEL_REMOVE_SPEED ); //1.0
            }
            
            wpnmod_fire_bullets( pPlayer, pPlayer, 1, VECTOR_CONE_20DEGREES, CHAINSAW_DISTANCE, CHAINSAW_DAMAGE, DMG_CLUB | DMG_ALWAYSGIB, 6 );
        }
    }        
}
//
// Secondary attack: slow, low damage, bigger attack distance, no ammo required
//
public CChainsaw__SecondaryAttack( pWeapon, pPlayer )
{
    if( wpnmod_get_offset_int( pWeapon, Offset_iChargeReady ) > 0 )
    {
        CChainsaw__EndAttack( pWeapon, pPlayer );
    }
    
    CChainsaw__EmptyAttack( pWeapon, pPlayer );
}
//
// Weapon reload
//
public CChainsaw__Reload( pWeapon, pPlayer, iClip, rgAmmo )
{
    if( iClip >= WEAPON_CLIP || rgAmmo <= 0 )
        return;
            
    if( wpnmod_get_offset_int( pWeapon, Offset_iChargeReady ) )    
        CChainsaw__EndAttack( pWeapon, pPlayer );
            
    wpnmod_default_reload( pWeapon, WEAPON_CLIP, SEQ_RELOAD, 3.0 );
}
// 
// Weapon idle
//
public CChainsaw__WeaponIdle( pWeapon, pPlayer, iClip )
{
    wpnmod_reset_empty_sound( pWeapon );
    
    if( wpnmod_get_offset_float( pWeapon, Offset_flTimeWeaponIdle ) > 0.0 )
        return;
    
    if( wpnmod_get_offset_int( pWeapon, Offset_iChargeReady ) )
    {
        CChainsaw__EndAttack( pWeapon, pPlayer );
        return;
    }
    
    wpnmod_send_weapon_anim( pWeapon, !iClip ? SEQ_IDLE_EMPTY : SEQ_IDLE );
    wpnmod_set_offset_float( pWeapon, Offset_flTimeWeaponIdle, random_float( 5.0, 15.0 ) );
}
//
// Secondary attack
//
CChainsaw__EmptyAttack( pWeapon, pPlayer )
{
    //wpnmod_set_think( pWeapon, "CChainsaw__Slash" );
    emit_sound( pPlayer, CHAN_WEAPON, SOUND_MISS, 1.0, ATTN_NORM, 0, PITCH_NORM );
    CChainsaw__Slash( pWeapon, pPlayer );
    wpnmod_send_weapon_anim( pWeapon, SEQ_SLASH );

    wpnmod_set_offset_float( pWeapon, Offset_flNextPrimaryAttack, CHAINSAW_REFIRE_RATE2 );
    wpnmod_set_offset_float( pWeapon, Offset_flNextSecondaryAttack, CHAINSAW_REFIRE_RATE2 );
    wpnmod_set_offset_float( pWeapon, Offset_flTimeWeaponIdle, 5.0 );
}
//
// Make the attack itself
//
public CChainsaw__Slash( pWeapon, pPlayer )
{    
    new iClass;
    new iTrace;
    new iDidHit;
    new iEntity;
    new iHitWorld;
    
    new Float:vecSrc[ 3 ];
    new Float:vecEnd[ 3 ];
    new Float:vecAngle[ 3 ];
    new Float:vecRight[ 3 ];
    new Float:vecForward[ 3 ];
    
    new Float: flFraction;
    
    iTrace = create_tr2( );
    
    entity_get_vector( pPlayer, EV_VEC_v_angle, vecAngle );
    engfunc( EngFunc_MakeVectors, vecAngle );
    
    wpnmod_get_gun_position( pPlayer, vecSrc );
    
    global_get( glb_v_right, vecRight );
    global_get( glb_v_forward, vecForward );
    
    xs_vec_mul_scalar( vecRight, 6.0, vecRight );
    xs_vec_mul_scalar( vecForward, 42.0, vecForward );
        
    xs_vec_add( vecRight, vecForward, vecForward );
    xs_vec_add( vecForward, vecSrc, vecEnd );
    
    engfunc( EngFunc_TraceLine, vecSrc, vecEnd, DONT_IGNORE_MONSTERS, pPlayer, iTrace );
    get_tr2( iTrace, TR_flFraction, flFraction );
    
    if( flFraction >= 1.0 )
    { 
        engfunc( EngFunc_TraceHull, vecSrc, vecEnd, DONT_IGNORE_MONSTERS, HULL_HEAD, pPlayer, iTrace );
        get_tr2( iTrace, TR_flFraction, flFraction );
        
        if( flFraction < 1.0 )
        {
            new iHit = Instance( get_tr2( iTrace, TR_pHit ) );
            
            if( !iHit || ExecuteHamB( Ham_IsBSPModel, iHit ) )
            {
                FindHullIntersection( vecSrc, iTrace, Float:{ -16.0, -16.0, -18.0 }, Float:{16.0,  16.0,  18.0 }, pPlayer );
            }
            
            get_tr2( iTrace, TR_vecEndPos, vecEnd );
        }
    }
    
    get_tr2( iTrace, TR_flFraction, flFraction );
    
    if( flFraction >= 1.0 )
    {    
        wpnmod_set_offset_float( pWeapon, Offset_flNextPrimaryAttack, 0.5 );
        wpnmod_set_offset_float( pWeapon, Offset_flNextSecondaryAttack, 0.5 );
            
        wpnmod_set_player_anim( pPlayer, PLAYER_ATTACK1 );
    }
    else
    {
        iDidHit = true;
        iEntity = Instance( get_tr2( iTrace, TR_pHit ) );
         
        wpnmod_set_player_anim( pPlayer, PLAYER_ATTACK1 );
        wpnmod_clear_multi_damage( );
        
        entity_get_vector( pPlayer, EV_VEC_v_angle, vecAngle );
        engfunc( EngFunc_MakeVectors, vecAngle );    
        
        global_get( glb_v_forward, vecForward );
        ExecuteHamB( Ham_TraceAttack, iEntity, pPlayer, CHAINSAW_DAMAGE2, vecForward, iTrace, DMG_CLUB | DMG_NEVERGIB );
        
        wpnmod_apply_multi_damage( pPlayer, pPlayer );
        
        iHitWorld = true;
            
        if( iEntity && ( iClass = ExecuteHamB( Ham_Classify, iEntity ) ) != CLASS_NONE && iClass != CLASS_MACHINE )
        {
            /*switch (random_num(0, 1))
            {
                case 0: emit_sound(pPlayer, CHAN_ITEM, SOUND_HIT_FLESH_1, 1.0, ATTN_NORM, 0, PITCH_NORM);
                case 1: emit_sound(pPlayer, CHAN_ITEM, SOUND_HIT_FLESH_2, 1.0, ATTN_NORM, 0, PITCH_NORM);
            }*/
                
            emit_sound( iEntity, CHAN_VOICE, SOUND_HIT_FLESH, 1.0, ATTN_NORM, 0, PITCH_NORM );
            wpnmod_set_offset_int( pPlayer, Offset_iWeaponVolume, CHAINSAW_BODYHIT_VOLUME );
                
            if( !ExecuteHamB( Ham_IsAlive, iEntity ) )
            {
                return true;
            }
                
            iHitWorld = false;
        }
            
        if( iHitWorld )
        {
            emit_sound( iEntity, CHAN_VOICE, SOUND_HIT_WALL, 1.0, ATTN_NORM, 0, PITCH_NORM );
            wpnmod_set_offset_int( pWeapon, Offset_iuser4, iTrace )
        }
            
        wpnmod_set_offset_int( pPlayer, Offset_iWeaponVolume, CHAINSAW_WALLHIT_VOLUME );
        
        //CChainsaw__Smack( pWeapon );
        wpnmod_set_think( pWeapon, "CChainsaw__Smack");
        entity_set_float( pWeapon, EV_FL_nextthink, get_gametime( ) + 0.1 );
    }

    free_tr2( iTrace );
    return iDidHit;
}
//
// Paint decals
//
public CChainsaw__Smack( pWeapon )
{
    new iTrace = wpnmod_get_offset_int( pWeapon, Offset_iuser4 );
    
    //sparks
    new Float:vecEnd[ 3 ];
    get_tr2( iTrace, TR_vecEndPos, vecEnd );
    
    engfunc( EngFunc_MessageBegin, MSG_PAS, SVC_TEMPENTITY, vecEnd, 0 );
    write_byte( TE_SPARKS );
    engfunc( EngFunc_WriteCoord, vecEnd[ 0 ] );
    engfunc( EngFunc_WriteCoord, vecEnd[ 1 ] );
    engfunc( EngFunc_WriteCoord, vecEnd[ 2 ] );
    message_end( );
    
    free_tr2( iTrace );
}
//
// Stop attacking
//
CChainsaw__EndAttack( pWeapon, pPlayer, iPlaySound = 0 )
{
    if( iPlaySound > 0 ){
        emit_sound( pPlayer, CHAN_WEAPON, SOUND_END, 1.0, ATTN_NORM, 0, PITCH_NORM );
    }
    
    wpnmod_send_weapon_anim( pWeapon, SEQ_LOOP_END );
    
    wpnmod_set_offset_float( pWeapon, Offset_flNextPrimaryAttack, 0.2 );
    wpnmod_set_offset_float( pWeapon, Offset_flNextSecondaryAttack, 0.5 );
    wpnmod_set_offset_float( pWeapon, Offset_flTimeWeaponIdle, 2.0 );
    
    wpnmod_set_offset_int( pWeapon, Offset_iChargeReady, 0 );
}
// 
// 
//
FindHullIntersection( const Float:vecSrc[ 3 ], &iTrace, const Float: vecMins[ 3 ], const Float: vecMaxs[ 3 ], const iEntity )
{
    new i, j, k;
    new iTempTrace;
    
    new Float:vecEnd[ 3 ];
    new Float:flDistance;
    new Float:flFraction;
    new Float:vecEndPos[ 3 ];
    new Float:vecHullEnd[ 3 ];
    new Float:flThisDistance;
    new Float:vecMinMaxs[ 2 ][ 3 ];
    
    flDistance = 999999.0;
    
    xs_vec_copy( vecMins, vecMinMaxs[ 0 ] );
    xs_vec_copy( vecMaxs, vecMinMaxs[ 1 ] );
    
    get_tr2( iTrace, TR_vecEndPos, vecHullEnd );
    
    xs_vec_sub( vecHullEnd, vecSrc, vecHullEnd );
    xs_vec_mul_scalar( vecHullEnd, 2.0, vecHullEnd );
    xs_vec_add( vecHullEnd, vecSrc, vecHullEnd );
    
    engfunc( EngFunc_TraceLine, vecSrc, vecHullEnd, DONT_IGNORE_MONSTERS, iEntity, ( iTempTrace = create_tr2( ) ) );
    get_tr2( iTempTrace, TR_flFraction, flFraction );
    
    if( flFraction < 1.0 )
    {
        free_tr2( iTrace );
        
        iTrace = iTempTrace;
        return;
    }
    
    for( i = 0; i < 2; i++ )
    {
        for( j = 0; j < 2; j++ )
        {
            for( k = 0; k < 2; k++ )
            {
                vecEnd[ 0 ] = vecHullEnd[ 0 ] + vecMinMaxs[ i ][ 0 ];
                vecEnd[ 1 ] = vecHullEnd[ 1 ] + vecMinMaxs[ j ][ 1 ];
                vecEnd[ 2 ] = vecHullEnd[ 2 ] + vecMinMaxs[ k ][ 2 ];
                
                engfunc( EngFunc_TraceLine, vecSrc, vecEnd, DONT_IGNORE_MONSTERS, iEntity, iTempTrace );
                get_tr2( iTempTrace, TR_flFraction, flFraction );
                
                if( flFraction < 1.0 )
                {
                    get_tr2( iTempTrace, TR_vecEndPos, vecEndPos );
                    xs_vec_sub( vecEndPos, vecSrc, vecEndPos );
                    
                    if( ( flThisDistance = xs_vec_len( vecEndPos ) ) < flDistance )
                    {
                        free_tr2( iTrace );
                        
                        iTrace = iTempTrace;
                        flDistance = flThisDistance;
                    }
                }
            }
        }
    }
}
Назад
Верх