Satellite Strike

Satellite Strike 1.0

Нет прав для скачивания
Код:
#include < amxmodx >
#include < engine >
#include < fakemeta >
#include < hamsandwich >
#include < hl_wpnmod >
#include < xs >

// Weapon parameters
#define WEAPON_NAME             "weapon_satellite"
#define WEAPON_SLOT            1
#define WEAPON_POSITION            2
#define WEAPON_SECONDARY_AMMO        "" // NULL
#define WEAPON_SECONDARY_AMMO_MAX    -1
#define WEAPON_MAX_CLIP            -1
#define WEAPON_FLAGS            ITEM_FLAG_SELECTONEMPTY | ITEM_FLAG_NOAUTORELOAD | ITEM_FLAG_NOAUTOSWITCHEMPTY
#define WEAPON_WEIGHT            15

// Models
#define MODEL_P                "models/p_satellite.mdl"
#define MODEL_V                "models/v_satellite.mdl"

// Sounds
#define SOUND_IDLE            "weapons/satellite_idle.wav"
#define SOUND_DENY            "buttons/button2.wav"
#define SOUND_DENY2            "buttons/button10.wav"
#define SOUND_ATTACK            "weapons/satellite_activate.wav"

// V_ model sequence indexes
#define SEQ_IDLE            0
#define SEQ_FIDGET            1
#define SEQ_DEPLOY            3
#define SEQ_FIRE            4

// Ammo    
#define AMMO_DEFAULT            200
#define AMMO_MAX            200
#define AMMO_NAME            "power"
#define AMMO_RTIME            18.0    // time in seconds when ammo should START recharging after we did a shot

// Air Strike
#define STRIKE_TIME            15.0    // Delay to explosion
#define STRIKE_DAMAGE            "200"    // One strike damage(total damage STRIKE_DAMAGE * STRIKE_COUNT)
#define STRIKE_SPREAD            "64"    // Accuracy
#define STRIKE_COUNT            "10"    // How many strikes totally

// For correct Weapon HUD
new const SPRITE_HUD[ ][ ]        =
{
    "sprites/weapon_satellite.txt",
    "sprites/hud_weapons11.spr",
    "sprites/hud_interface.spr"
}
//=====================================================================
new g_pTriggerMultiple;
new g_iMaxClients;

// Some default vector
new const Float:gVecSky[ ]        = { 0.0, 0.0, 16000.0 };
new const Float:gVecZero[ ]        = { 0.0, 0.0, 0.0 };

enum ( <<=1 )
{
    v_angle = 1,
    punchangle
};

#define STOP_SOUND(%0,%1,%2)        emit_sound( %0, %1, %2, VOL_NORM, 0.0, SND_STOP, 0 )
#define CLASS_STRIKE            "func_SatelliteStrike"
//
// Precache all the resources
//
public plugin_precache( )
{
    PRECACHE_MODEL( MODEL_P );
    PRECACHE_MODEL( MODEL_V );
    
    PRECACHE_SOUND( SOUND_IDLE );
    PRECACHE_SOUND( SOUND_DENY );
    PRECACHE_SOUND( SOUND_DENY2 )
    PRECACHE_SOUND( SOUND_ATTACK );
    PRECACHE_SOUND( "weapons/mortar.wav" );
    PRECACHE_SOUND( "weapons/mortarhit.wav" );
    
    PRECACHE_MODEL( "sprites/lgtning.spr" );
    
    for( new pSprite = 0; pSprite < sizeof( SPRITE_HUD ); pSprite++ )
        PRECACHE_GENERIC( SPRITE_HUD[ pSprite ] );
        
    // This activates air strike
    g_pTriggerMultiple = create_entity( "trigger_multiple" );
    
    if( g_pTriggerMultiple )
    {
        DispatchKeyValue( g_pTriggerMultiple, "target", "satellite_mortar" );
        DispatchKeyValue( g_pTriggerMultiple, "delay", "0.5" );
        DispatchKeyValue( g_pTriggerMultiple, "wait", "0.5" );
        DispatchSpawn( g_pTriggerMultiple );
    }
}
//
// Create the weapon & ammo box
//
public plugin_init( )
{
    register_plugin( "[HL] Satellite Strike", "1.0", "NiHiLaNTh" );
    
    // New weapon
    new pWeapon = wpnmod_register_weapon
    (
        WEAPON_NAME,
        WEAPON_SLOT,
        WEAPON_POSITION,
        AMMO_NAME,
        AMMO_MAX,
        WEAPON_SECONDARY_AMMO,
        WEAPON_SECONDARY_AMMO_MAX,
        WEAPON_MAX_CLIP,
        WEAPON_FLAGS,
        WEAPON_WEIGHT
    );
    
    // TODO. Block weapon giving if player already have the Satellite
    // Strike(no matter with ammo or no!)
    //wpnmod_register_weapon_forward( pWeapon, Fwd_Wpn_AddToPlayer, "CSatellite__AddToPlayer" );;
    
    // Events
    wpnmod_register_weapon_forward( pWeapon, Fwd_Wpn_Spawn,        "CSatellite__Spawn" );
    wpnmod_register_weapon_forward( pWeapon, Fwd_Wpn_Deploy,    "CSatellite__Deploy" );
    wpnmod_register_weapon_forward( pWeapon, Fwd_Wpn_IsUseable,    "CSatellite__IsUseable" );
    wpnmod_register_weapon_forward( pWeapon, Fwd_Wpn_Holster,    "CSatellite__Holster" );
    wpnmod_register_weapon_forward( pWeapon, Fwd_Wpn_PrimaryAttack,    "CSatellite__PrimaryAttack" );
    wpnmod_register_weapon_forward( pWeapon, Fwd_Wpn_Reload,    "CSatellite__Reload" );
    wpnmod_register_weapon_forward( pWeapon, Fwd_Wpn_Idle,        "CSatellite__WeaponIdle" );
        
    // Satellite Strike entity
    register_think( CLASS_STRIKE,         "CSStrike__Think" );
    
    // This is used to set a proper killer on mortar kill
    RegisterHam( Ham_Killed, "player", "fw_PlayerKilled", .Post = 0 );
    
    // Store maxplayers
    g_iMaxClients = get_maxplayers( );
}
//
// Spawn the weapon ent
//
public CSatellite__Spawn( pItem )
{
    // Apply new w_ model
    SET_MODEL( pItem, MODEL_P );
    
    // Force it to be on the ground
    entity_set_int( pItem, EV_INT_sequence, 1 );
    
    // Give some default ammo
    wpnmod_set_offset_int( pItem, Offset_iDefaultAmmo, AMMO_DEFAULT );
}
//
// Deploy the weapon
//
public CSatellite__Deploy( pItem )
{
    // Set models, player deploy anim and set correct anim extension for the
    // player model.
    return wpnmod_default_deploy( pItem, MODEL_V, MODEL_P, SEQ_DEPLOY, "hive" );
}
//
// Mark this weapon as useable all the time
//
public CSatellite__IsUseable( pItem )
{
    return true;
}
//
// Hide the weapon
//
public CSatellite__Holster( pItem )
{
    // Stop the idle sound
    STOP_SOUND( pItem, CHAN_ITEM, SOUND_IDLE );
}
//
// Fire the satellite 
//
public CSatellite__PrimaryAttack( pItem, pPlayer, iClip )
{
    // Don't launch it underwater
    if( entity_get_int( pPlayer, EV_INT_waterlevel ) == 3 )
        return;
        
    // Damn, we need just one more ammo to launch!
    if( wpnmod_get_player_ammo( pPlayer, AMMO_NAME ) <= AMMO_MAX - 1 )
    {
        client_print( pPlayer, print_center, "Not enough power to call Air Mortar!" );
        emit_sound( pItem, CHAN_ITEM, SOUND_DENY, 0.9, ATTN_NORM, 0, PITCH_NORM );
        wpnmod_set_offset_float( pItem, Offset_flNextPrimaryAttack, 1.5 );
        return;
    }
    
    UTIL_MakeVectors( pPlayer, v_angle + punchangle );
    
    static tr, Float:vecSrc[ 3 ], Float:vecRet[ 3 ];
    
    entity_get_vector( pPlayer, EV_VEC_origin, vecSrc );
    engfunc( EngFunc_TraceLine, vecSrc, gVecSky, IGNORE_MONSTERS, pPlayer, tr );
    get_tr2( tr, TR_vecEndPos, vecRet );
    
    // WHAT THE HELL ARE YOU DOING?
    if( point_contents( vecRet ) != CONTENTS_SKY )
    {
        client_print( pPlayer, print_center, "Satellite could not reach the target" );
        emit_sound( pItem, CHAN_ITEM, SOUND_DENY2, 0.9, ATTN_NORM, 0, PITCH_NORM );
        wpnmod_set_offset_float( pItem, Offset_flNextPrimaryAttack, 1.5 );
        return;
    }
    
    // Reset all the ammo
    wpnmod_set_player_ammo( pPlayer, AMMO_NAME, 0 );
    
    // Warn the owner
    client_print( pPlayer, print_center, "Target locked! %d Seconds to leave area!", floatround( STRIKE_TIME ) );
    
    // Animations
    wpnmod_send_weapon_anim( pItem, SEQ_FIRE );
    wpnmod_set_player_anim( pPlayer, PLAYER_ATTACK1 );
    
    // Calculate start/dest origin
    static Float:vecStart[ 3 ], Float:vecViewOfs[ 3 ], Float:vecThrow[ 3 ], Float:vecUp[ 3 ];
    entity_get_vector( pPlayer, EV_VEC_view_ofs, vecViewOfs )
    global_get( glb_v_forward, vecThrow );
    global_get( glb_v_up, vecUp );
    vecStart[ 0 ] = vecSrc[ 0 ] + vecViewOfs[ 0 ] + vecThrow[ 0 ] * 16.0 + vecUp[ 0 ] * -15.0;
    vecStart[ 1 ] = vecSrc[ 1 ] + vecViewOfs[ 1 ] + vecThrow[ 1 ] * 16.0 + vecUp[ 1 ] * -15.0;
    vecStart[ 2 ] = vecSrc[ 2 ] + vecViewOfs[ 2 ] + vecThrow[ 2 ] * 16.0 + vecUp[ 2 ] * -15.0;
    
    // Do the attack
    if( CSStrike__ShootStrike( pPlayer, vecStart, STRIKE_TIME ) )
    {
        emit_sound( pItem, CHAN_AUTO, SOUND_ATTACK, 1.0, ATTN_NORM, 0, PITCH_NORM );
    
        // Set the next attack time
        wpnmod_set_offset_float( pItem, Offset_flNextPrimaryAttack, 5.0 );
        wpnmod_set_offset_float( pItem, Offset_flTimeWeaponIdle, 1.0 );
        wpnmod_set_offset_float( pItem, Offset_fuser1, get_gametime( ) + AMMO_RTIME ); // dont recharge ammo for a while
    }
}
//
// Restore the ammo
//
public CSatellite__Reload( pItem, pPlayer, iClip, iAmmo )
{
    // Enough ammo
    if( iAmmo >= AMMO_MAX )
        return;
        
    static Float:tTime;
    tTime = get_gametime( );
        
    // Recharge the ammo ASAP
    while( iAmmo < AMMO_MAX && wpnmod_get_offset_float( pItem, Offset_fuser1 ) < tTime )
    {
        wpnmod_set_player_ammo( pPlayer, AMMO_NAME, iAmmo + 1 );
        wpnmod_set_offset_float( pItem, Offset_fuser1, tTime + 1.0 );
    }
}
//
// Idle
//
public CSatellite__WeaponIdle( pItem, pPlayer, iClip, iAmmo )
{
    // Force reload each frame
    CSatellite__Reload( pItem, pPlayer, iClip, iAmmo );
    
    static Float:tTime;
    tTime = get_gametime( );
    
    // Are we ready for the idle sound?
    if( tTime >= wpnmod_get_offset_float( pItem, Offset_fuser2 ) )
    {
        emit_sound( pItem, CHAN_ITEM, SOUND_IDLE, 0.9, ATTN_NORM, 0, PITCH_NORM );
        wpnmod_set_offset_float( pItem, Offset_fuser2, tTime + 2.45 );
    }
    
    if( wpnmod_get_offset_float( pItem, Offset_flTimeWeaponIdle ) > 0.0 )
    {
        return;
    }
    
    // Do some randomization
    switch( random_num( 0, 1 ) )
    {
        case 0:    wpnmod_send_weapon_anim( pItem, SEQ_IDLE );
        case 1:    wpnmod_send_weapon_anim( pItem, SEQ_FIDGET );
    }
    
    // Call for idle pretty soon
    wpnmod_set_offset_float( pItem, Offset_flTimeWeaponIdle, random_float( 10.0, 15.0 ) );
}
//
// Create the strike itself
//
CSStrike__ShootStrike( pevOwner, Float:vecStart[ 3 ], Float:time )
{
    new pStrike = create_entity( "info_target" );
    
    if( pStrike <= 0 )
        return 0;
        
    entity_set_int( pStrike, EV_INT_movetype, MOVETYPE_NONE );
    entity_set_string( pStrike, EV_SZ_classname, CLASS_STRIKE );
    entity_set_int( pStrike, EV_INT_solid, SOLID_BBOX );
    entity_set_int( pStrike, EV_INT_effects, entity_get_int( pStrike, EV_INT_effects ) | EF_NODRAW );
    
    // Set any generic model, we dont care since target isn't drawn anyway
    entity_set_model( pStrike, "models/crossbow_bolt.mdl" );
    
    entity_set_size( pStrike, gVecZero, gVecZero );
    engfunc( EngFunc_SetOrigin, pStrike, vecStart );
    entity_set_edict( pStrike, EV_ENT_owner, pevOwner );
    
    // Do we need this?
    drop_to_floor( pStrike );
    
    entity_set_float( pStrike, EV_FL_nextthink, get_gametime( ) + time );

    return pStrike;
}
//
// Satellite strike is thinking
//
public CSStrike__Think( pStrike )
{
    if( !is_valid_ent( pStrike ) )
        return;
        
    if( !IsInWorld( pStrike ) )
    {
        remove_entity( pStrike );
        return;
    }
    
    CSStrike__Explode( pStrike );
}
//
// Satellite strike should explode now
//
CSStrike__Explode( pStrike )
{
    static pMortar, pevOwner;
    pevOwner = entity_get_edict( pStrike, EV_ENT_owner );
    pMortar = 0;
    
    pMortar = create_entity( "func_mortar_field" );
    
    if( pMortar <= 0 )
        return

    DispatchKeyValue( pMortar, "m_iDamage", STRIKE_DAMAGE );
    DispatchKeyValue( pMortar, "m_fControl", "1" ); // 1 mean depending on activator origin
    DispatchKeyValue( pMortar, "m_flSpread", STRIKE_SPREAD );
    DispatchKeyValue( pMortar, "m_iCount", STRIKE_COUNT );
    DispatchSpawn( pMortar );    
    
    entity_set_edict( pMortar, EV_ENT_owner, pevOwner );
    entity_set_string( pMortar, EV_SZ_targetname, "satellite_mortar" );
    
    ExecuteHam( Ham_Use, pMortar, pStrike, g_pTriggerMultiple, 1, 0.5 );
}
//
// HACK! Make a valid killer for airstrike kills
//
public fw_PlayerKilled( pevVictim, pevKiller, fShouldGib )
{
    if( 1 <= pevKiller <= g_iMaxClients )
        return HAM_IGNORED;
    
    static strClass[ 32 ];
    entity_get_string( pevKiller, EV_SZ_classname, strClass, charsmax( strClass ) );
    
    if( equal( strClass, CLASS_STRIKE ) )
    {
        static pevOwner;
        pevOwner = entity_get_edict( pevKiller, EV_ENT_owner );
        
        ExecuteHamB( Ham_Killed, pevVictim, pevOwner, fShouldGib );
        return HAM_SUPERCEDE;
    }
    return HAM_IGNORED;
}
//
// Credit Arkshine
//
UTIL_MakeVectors( pPlayer, bsType )
{
    static Float:vPunchAngle[ 3 ], Float:vAngle[ 3 ];

    if( bsType & v_angle )    
        pev( pPlayer, pev_v_angle, vAngle );
    if( bsType & punchangle ) 
        pev( pPlayer, pev_punchangle, vPunchAngle );

    xs_vec_add( vAngle, vPunchAngle, vAngle );
    engfunc( EngFunc_MakeVectors, vAngle );
}
/* AMXX-Studio Notes - DO NOT MODIFY BELOW HERE
*{\\ rtf1\\ ansi\\ deff0{\\ fonttbl{\\ f0\\ fnil Tahoma;}}\n\\ viewkind4\\ uc1\\ pard\\ lang1049\\ f0\\ fs16 \n\\ par }
*/
Назад
Верх