nice gun

Unpaid Requests, Public Plugins
czirimbolo
Veteran Member
Veteran Member
Poland
Posts: 598
Joined: 7 years ago
Contact:

nice gun

#1

Post by czirimbolo » 5 years ago

Code: Select all

#include < zombie_escape >
#include < cstrike >
#include < csx >
#include < xs >
#include < fun >
 
// Plugin information
#define Plugin  "[ZE] Extra Item: Tau Cannon"
#define Version "1.2"
#define Author  "NiHiLaNTh"
 
// Maxplayers
const MaxPlayers = 32
 
// Weapon models
new const g_szModelGaussP[ ] = "models/p_gauss.mdl"
new const g_szModelGaussV[ ] = "models/v_alt_gauss.mdl"
new const g_szModelGaussW[ ] = "models/w_gauss.mdl"
 
// Weapon sounds
new const g_szSoundGaussFire[ ] = "weapons/gauss2.wav"
new const g_szSoundGaussSpin[ ] = "ambience/pulsemachine.wav"
new const g_szSoundElectro1[ ] = "weapons/electro4.wav"
new const g_szSoundElectro2[ ] = "weapons/electro5.wav"
new const g_szSoundElectro3[ ] = "weapons/electro6.wav"
 
// Some gauss/beam stuff
#define GAUSS_REFIRERATE    0.2 // Primary attack
#define GAUSS_REFIRERATE2   0.1 // Secondary attack(you shouldnt change this!)
#define GAUSS_RECOIL        -2.0 // Only X axis!
#define GAUSS_CHARGETIME    4.0 // From HLSDK
#define GAUSS_RELOADTIME    2.0 // Reload time
#define BEAM_RED        255 // Red amount
#define BEAM_GREEN      128 // Green amount
#define BEAM_BLUE       0 // Blue amount
#define BEAM_ALPHA      255 // Brightness(Alpha)
#define BALL_AMOUNT     8 // How many balls should appear :p
 
// Max. bp ammo amount
new const MAXBPAMMO[] = { -1, 52, -1, 90, 1, 32, 1, 100, 90, 1, 120, 100, 100, 90, 90, 90, 100, 120,
    5, 120, 200, // This is gauss max bp ammo.Change it if you want!
32, 90, 120, 90, 2, 35, 90, 90, -1, 100 }
 
// Player variables
new g_iHasGauss[ MaxPlayers+1 ] // Whether player has gauss
new g_iSoundState[ MaxPlayers+1 ] // Weapon sound state
new g_bInAttack[ MaxPlayers+1 ] // Current gauss attack state
new g_iCurrentWeapon[ MaxPlayers+1 ] // Current weapon player is holding
new Float:g_flLastShotTime[ MaxPlayers+1 ] // Last shot time
new Float:g_fflPlayAfterShock[ MaxPlayers+1 ] // Play aftershock sound
new Float:g_flWeaponIdleTime[ MaxPlayers+1 ] // Weapon idle time
new Float:g_flNextAmmoBurn[ MaxPlayers+1 ] // Next ammo burn time
new Float:g_flStartCharge[ MaxPlayers+1 ] // Weapon start charge
new Float:g_flAmmoStartCharge[ MaxPlayers+1 ] // Ammo start charge
new bool:g_bIsAlive[ MaxPlayers+1 ] // Whether player is alive
new bool:g_bIsConnected[ MaxPlayers+1 ] // Whether player is connected
new bool:g_bPrimaryFire[ MaxPlayers+1 ] // Does this weapon is using primary attack ?
new bool:g_bKilledByLaser[ MaxPlayers+1 ] // Imma firin mah lazor O.o
 
// CVAR pointers
new cvar_oneround // Whether gun should be only for 1 round
new cvar_dmgprim // Primary attack damage
new cvar_dmgsec // Secondary attack damage
new cvar_clip // Clip amount
 
// Cached CVAR
new g_pOneRound
new Float:g_pDmgPrim
new Float:g_pDmgSec
new g_pClip
 
// Global varibles
new g_iMaxPlayers // Maxplayers
new bool:g_bGameRestart // Detect game restart
new g_iBeam // Beam sprite
new g_iBalls // Balls :p
new g_iGaussID // Item ID
new gmsgScreenFade // Screen fade
 
// CS Offsets
const m_pPlayer = 41
const m_flNextPrimaryAttack = 46
const m_flNextSecondaryAttack = 47
const m_flTimeWeaponIdle = 48
const m_iPrimaryAmmoType = 49
const m_iClip = 51
const m_fInReload = 54
const m_flNextAttack  = 83
const m_rgAmmo_player_Slot0 = 376
 
// Macro
#define is_user_valid_connected(%1)     ( 1 <= %1 <= g_iMaxPlayers && g_bIsConnected [ %1 ] )
#define is_user_in_water(%1)            ( pev ( %1, pev_waterlevel ) == 3 )
#define VectorSubtract(%1,%2,%3)        ( %3[ 0 ] = %1[ 0 ] - %2[ 0 ], %3[ 1 ] = %1[ 1 ] - %2[ 1 ], %3[ 2 ] = %1[ 2 ] - %2[ 2 ] )
#define VectorAdd(%1,%2,%3)         ( %3[ 0 ] = %1[ 0 ] + %2[ 0 ], %3[ 1 ] = %1[ 1 ] + %2[ 2 ], %3[ 2 ] = %1[ 2 ] + %2[ 2 ] )
#define VectorScale(%1,%2,%3)           ( %3[ 0 ] = %2 * %1[ 0 ], %3[ 1 ] = %2 * %1[ 1 ], %3[ 2 ] = %2 * %1[ 2 ] )
#define VectorLength(%1)                ( floatsqroot ( %1[ 0 ] * %1[ 0 ] + %1[ 1 ] * %1[ 1 ] + %1[ 2 ] * %1[ 2 ] ) )
 
// Hack!Custom fields
#define pev_weaponkey       pev_impulse
#define pev_bpammo      pev_iuser3
 
// Misc stuff
#define FCVAR_FLAGS     ( FCVAR_SERVER | FCVAR_SPONLY | FCVAR_UNLOGGED )
#define GAUSS_WEAPONKEY 42856
#define NULLENT     -1
#define FFADE_IN        0x0000
#define UNIT_SECOND     (1<<12)
 
// Entity classnames
new const g_szClassPlayer[ ] = "player"
new const g_szClassM249[ ] = "weapon_m249"
 
// Primary weapon bitsum
const PRIMARY_WEAPONS_BITSUM = (1<<CSW_SCOUT)|(1<<CSW_XM1014)|(1<<CSW_MAC10)|(1<<CSW_AUG)|(1<<CSW_UMP45)|(1<<CSW_SG550)|(1<<CSW_GALIL)|(1<<CSW_FAMAS)|(1<<CSW_AWP)|(1<<CSW_MP5NAVY)|(1<<CSW_M249)|(1<<CSW_M3)|(1<<CSW_M4A1)|(1<<CSW_TMP)|(1<<CSW_G3SG1)|(1<<CSW_SG552)|(1<<CSW_AK47)|(1<<CSW_P90)
 
// Animation sequnces
enum
{
    gauss_idle,
    gauss_idle2,
    gauss_fidget,
    gauss_spinup,
    gauss_spin,
    gauss_fire,
    gauss_fire2,
    gauss_holster,
    gauss_draw
}
 
// Precache
public plugin_precache( )
{
    // Weapon models
    precache_model( g_szModelGaussP )
    precache_model( g_szModelGaussV )
    precache_model( g_szModelGaussW )
   
    // Sounds
    precache_sound( g_szSoundGaussFire )
    precache_sound( g_szSoundGaussSpin )
    precache_sound( g_szSoundElectro1 )
    precache_sound( g_szSoundElectro2 )
    precache_sound( g_szSoundElectro3 )
    precache_sound( "items/9mmclip1.wav" )
   
    // Sprites
    g_iBeam = precache_model( "sprites/smoke.spr" )
    g_iBalls = precache_model( "sprites/hotglow.spr" )
}
 
// Initialization
public plugin_init( )
{
    // New plugin
    register_plugin( Plugin, Version, Author )
   
    // For Game-Monitor support
    register_cvar( "ze_tcannon_version", Version, FCVAR_FLAGS )
   
    // New extra item
    g_iGaussID = ze_register_item("Tau Cannon", 30, 0)
   
    // Events
    register_event( "CurWeapon", "EV_CurWeapon", "be", "1=1" )
    register_event( "DeathMsg", "EV_DeathMsg", "a" )
    register_event( "HLTV", "EV_RoundStart", "a", "1=0", "2=0" )
    register_event( "TextMsg", "EV_GameRestart", "a", "2=#Game_Commencing", "2=#Game_will_restart_in" )
   
    // FakeMeta forwards
    register_forward( FM_SetModel, "fw_SetModel" )
    register_forward( FM_CmdStart, "fw_CmdStart" )
    register_forward( FM_UpdateClientData, "fw_UpdateClientData_Post", 1 )
    register_forward( FM_PlayerPreThink, "fw_PlayerPreThink" )
   
    // HamSandwich forwards
    RegisterHam( Ham_Spawn, g_szClassPlayer, "fw_PlayerSpawn_Post", 1 )
    RegisterHam( Ham_Item_Deploy, g_szClassM249, "fw_TCannonDeploy_Post", 1 )
    RegisterHam( Ham_Item_Holster, g_szClassM249, "fw_TCannonHolster_Post", 1 )
    RegisterHam( Ham_Item_AddToPlayer, g_szClassM249, "fw_TCannonAddToPlayer" )
    RegisterHam( Ham_Item_PostFrame, g_szClassM249, "fw_TCannonPostFrame" )
    RegisterHam( Ham_Weapon_Reload, g_szClassM249, "fw_TCannonReload_Post", 1 )
   
    // CVARs are in Load_Cvars( ) function!
   
    // Messages
    register_message( get_user_msgid( "DeathMsg" ), "fn_DeathMsg" )
    gmsgScreenFade = get_user_msgid( "ScreenFade" )
   
    // Store maxplayers in a global variable
    g_iMaxPlayers = get_maxplayers( )
}  
 
// Configuration
public plugin_cfg( )
{
    // Cache CVARs
    set_task( 1.5, "Load_Cvars" )
}
 
// ------------------------------- Game Events ----------------------------------------
 
// Client connected
public client_connect( Player )
{
    // Make a lot of updates
    g_iHasGauss[ Player ] = false
    g_bInAttack[ Player ] = 0
    g_fflPlayAfterShock[ Player ] = 0.0
    g_flWeaponIdleTime[ Player ] = 0.0
    g_bPrimaryFire[ Player ] = false
    g_bIsAlive[ Player ] = false
    g_bIsConnected[ Player ] = true
}
 
// Client disconnected
public client_disconnect( Player )
{
    // Only few important updates
    g_bIsAlive[ Player ] = false
    g_bIsConnected[ Player ] = false
}
 
public ze_select_item_pre(id, itemid)
{
    // Return Available and we will block it in Post, So it dosen't affect other plugins
    if (itemid != g_iGaussID)
        return ZE_ITEM_AVAILABLE
   
    // Available for Humans only, So don't show it for zombies
    if (ze_is_user_zombie(id))
        return ZE_ITEM_DONT_SHOW
   
    return ZE_ITEM_AVAILABLE
}
 
public ze_select_item_post(Player, itemid)
{
    if (itemid != g_iGaussID)
        return
 
    // Drop all primary weapons
    UTIL_DropPrimary( Player )
       
    // Update
    g_iHasGauss[ Player ] = true
       
    // Give m249
    give_item( Player, "weapon_m249" )
       
    // Find weapon entity
    new iEnt = find_ent_by_owner( NULLENT, g_szClassM249, Player )
       
    // Apply new clip
    cs_set_weapon_ammo( iEnt, g_pClip )
       
    // Back pack ammo
    cs_set_user_bpammo( Player, CSW_M249, MAXBPAMMO[ 20 ] )
}
 
// Current weapon player is holding
public EV_CurWeapon( Player )
{
    // Not alive
    if( !g_bIsAlive[ Player ] )
        return PLUGIN_CONTINUE
   
    // Update
    g_iCurrentWeapon[ Player ] = read_data( 2 )
   
    return PLUGIN_CONTINUE
}
 
// Someone died
public EV_DeathMsg( )
{
    // Get victim
    static iVictim
    iVictim = read_data( 2 )
   
    // Not connected
    if( !is_user_valid_connected( iVictim ) )
        return
   
    // Update
    g_bIsAlive[ iVictim ] = false
   
    // Check if victim has gauss
    if( g_iHasGauss[ iVictim ] && !is_user_bot( iVictim ) )
    {
        // Force to drop
        engclient_cmd( iVictim, "drop weapon_m249" )
    }
}
 
// Round started
public EV_RoundStart( )
{
    // Restart/One round only
    if( g_bGameRestart || g_pOneRound )
    {
        // Reset array value
        arrayset( g_iHasGauss, false, MaxPlayers+1 )
    }
   
    // Update
    g_bGameRestart = false
}
 
// Game restart
public EV_GameRestart( )
{
    // Update
    g_bGameRestart = true
}
 
// Hook death message
public fn_DeathMsg( Player, Dest, iEntity )
{
    // Get victim
    static iVictim, iKiller
    iKiller = get_msg_arg_int( 1 )
    iVictim = get_msg_arg_int( 2 )
   
    // Not connected
    if( !is_user_valid_connected( iVictim ) || iKiller == iVictim )
        return PLUGIN_CONTINUE
   
    // We were killed by laser
    if ( g_bKilledByLaser[ iVictim ] )
    {
        // Replace name in console
        set_msg_arg_string ( 4, "tau cannon" )
    }
    return PLUGIN_CONTINUE
}
 
// ------------------------------- Forwards ----------------------------------------
 
// Replace world model
public fw_SetModel ( Entity, const Model [ ] )
{
    // Prevent invalid entity messages
    if( !pev_valid( Entity ) )
        return FMRES_IGNORED
   
    // Not w_awp.mdl
    if( !equal( Model, "models/w_m249.mdl" ) )
        return FMRES_IGNORED
   
    // Get entity classname
    static szClassname[ 32 ]
    pev( Entity, pev_classname, szClassname, charsmax( szClassname ) )
   
    // Not weaponbox
    if( !equal( szClassname, "weaponbox" ) )
        return FMRES_IGNORED
   
    // Get owner
    static iOwner
    iOwner = pev( Entity, pev_owner )
   
    // Get awp ID
    static iWeaponID
    iWeaponID = find_ent_by_owner( NULLENT, g_szClassM249, Entity )
   
    // Make sure that we have gauss
    if( g_iHasGauss [ iOwner ] && is_valid_ent( iWeaponID ) )
    {
        // Hack! Store weaponkey
        set_pev( iWeaponID, pev_weaponkey, GAUSS_WEAPONKEY )
       
        // Hack! Store bp ammo
        set_pev( iWeaponID, pev_bpammo, cs_get_user_bpammo( iOwner, CSW_M249 ) )
       
        // Update
        g_iHasGauss[ iOwner ] = false
       
        // Replace models
        engfunc( EngFunc_SetModel, Entity, g_szModelGaussW )
        return FMRES_SUPERCEDE
    }
    return FMRES_IGNORED
}
 
// Command start
public fw_CmdStart( Player, UC_Handle, Seed )
{
    // Not alive/dont have gauss/not m249
    if( !g_bIsAlive[ Player ] || !g_iHasGauss[ Player ] || g_iCurrentWeapon[ Player ] != CSW_M249 )
        return FMRES_IGNORED
   
    // Retrieve pressed button bitsum
    static iButtons
    iButtons = get_uc( UC_Handle, UC_Buttons )
   
    // Retrieve game time
    static Float:flGameTime
    flGameTime = get_gametime( )
   
    // Retrieve weapon entity
    static iEnt
    iEnt = find_ent_by_owner( NULLENT, g_szClassM249, Player )
   
    // Retrieve clip amount
    static iClip
    iClip = cs_get_weapon_ammo( iEnt )
   
    // Primary attack
    if( iButtons & IN_ATTACK )
    {
        // Remove attack buttons from their button mask
        iButtons &= ~IN_ATTACK
        set_uc( UC_Handle, UC_Buttons, iButtons )
       
        // Prevent too fast shooting
        if( flGameTime - g_flLastShotTime[ Player ] < GAUSS_REFIRERATE )
            return FMRES_IGNORED
       
        // Dont fire while reloading
        if( get_pdata_int( iEnt, m_fInReload, 4 ) )
            return FMRES_IGNORED
       
        // Not enough clip/under water
        if( iClip < 2 || is_user_in_water( Player ) )
        {
            // Emit empty sound
            ExecuteHamB( Ham_Weapon_PlayEmptySound, iEnt )
            return FMRES_IGNORED
        }
       
        // Update
        g_bPrimaryFire[ Player ] = true
       
        // Start to fire
        StartFire( Player )
       
        // Decrease clip
        cs_set_weapon_ammo( iEnt, iClip-2 )
       
        // Reset weapon attack status
        g_bInAttack[ Player ] = 0
       
        // Set time when idle animation should be played
        g_flWeaponIdleTime[ Player ] = flGameTime + 1.0
       
        // Remember last shot time
        g_flLastShotTime[ Player ] = flGameTime
    }
    // Secondary attack
    else if( iButtons & IN_ATTACK2 )
    {
        // Prevent too fast shooting
        if( flGameTime - g_flLastShotTime[ Player ] < GAUSS_REFIRERATE2 )
            return FMRES_IGNORED
       
        // Dont fire while reloading
        if( get_pdata_int( iEnt, m_fInReload, 4 ) )
            return FMRES_IGNORED
       
        // Are we swimming ?
        if( is_user_in_water( Player ) )
        {
            // We are in a middle of attack
            if( g_bInAttack[ Player ] != 0 )
            {
                // Stop attack
                emit_sound( Player, CHAN_WEAPON, g_szSoundElectro1, VOL_NORM, ATTN_NORM, 0, 80 + random_num( 0, 0x3f ) )
               
                // Gun idle
                UTIL_PlayWeaponAnimation( Player, gauss_idle )
                return FMRES_IGNORED
            }
            else
            {
                // Empty sound
                ExecuteHamB( Ham_Weapon_PlayEmptySound, iEnt )
                return FMRES_IGNORED
            }
        }
       
        // Get player oldbuttons
        static iOldButtons
        iOldButtons = pev( Player, pev_oldbuttons )
       
        // Make sure that we are holding secondary attack button
        if( iOldButtons & IN_ATTACK2 )
        {
            // Which attack state do we have
            switch ( g_bInAttack[ Player ] )
            {
                case 0: // Attack start
                {
                    // Out of ammo
                    if ( iClip <= 0 )
                    {
                        ExecuteHamB( Ham_Weapon_PlayEmptySound, iEnt )
                        return FMRES_IGNORED
                    }
                   
                    // We aren't using primary attack anymore
                    g_bPrimaryFire[ Player ] = false
                   
                    // Decrease clip
                    cs_set_weapon_ammo( iEnt, --iClip )
                   
                    // Update
                    g_flNextAmmoBurn[ Player ] = flGameTime
                   
                    // Send spinup animation
                    UTIL_PlayWeaponAnimation( Player, gauss_spinup )
                   
                    // Update attack state
                    g_bInAttack[ Player ] = 1
                   
                    // Next idle time
                    g_flWeaponIdleTime[ Player ] = flGameTime + 0.5
                   
                    // Update
                    g_flStartCharge[ Player ] = flGameTime
                    g_flAmmoStartCharge[ Player ] = flGameTime + GAUSS_CHARGETIME
                   
                    // Update sound state
                    g_iSoundState[ Player ] = 0
                   
                    // Spin sound
                    emit_sound( Player, CHAN_WEAPON, g_szSoundGaussSpin, VOL_NORM, ATTN_NORM, g_iSoundState[Player ], 110 )
                   
                    // Change sound state
                    g_iSoundState[ Player ] = SND_CHANGE_PITCH
                }
                case 1: // In a middle of attack
                {
                    if( g_flWeaponIdleTime[ Player ] < flGameTime )
                    {
                        // Spin anim
                        UTIL_PlayWeaponAnimation( Player, gauss_spin )
                       
                        // Update state
                        g_bInAttack[ Player ] = 2
                    }
                }
                default: // End of attack
                {
                    // During the charging process, eat one bit of ammo every once in a while
                    if( flGameTime >= g_flNextAmmoBurn[ Player ] && g_flNextAmmoBurn[ Player ] != 1000 )
                    {
                        // Decrease clip
                        cs_set_weapon_ammo( iEnt, --iClip )
                       
                        // Next time when ammo should be decreased
                        g_flNextAmmoBurn[ Player ] = flGameTime + 0.1
                    }
                   
                    // Shit!We run out of ammo
                    if( iClip <= 0 )
                    {
                        // Force gun to fire
                        StartFire( Player )
                       
                        // Reset weapon state
                        g_bInAttack[ Player ] = 0
                       
                        // Set next idle time
                        g_flWeaponIdleTime[ Player ] = flGameTime + 1.0
                    }
                   
                    // Gun is fully charged up
                    if( flGameTime >= g_flAmmoStartCharge[ Player ] )
                    {
                        // Dont eat any more ammo!
                        g_flNextAmmoBurn[ Player ] = 1000.0
                    }
                   
                    // Calculate pitch
                    static Float:flPitch
                    flPitch = ( flGameTime - g_flStartCharge[ Player ] ) * ( 150 / GAUSS_CHARGETIME ) + 100
                   
                    // Pitch shouldnt be THAT big
                    if ( flPitch > 250 )
                    {
                        flPitch = 250.0
                    }
                   
                    // Spin sound
                    emit_sound( Player, CHAN_WEAPON, g_szSoundGaussSpin, VOL_NORM, ATTN_NORM, ( g_iSoundState[ Player ] == SND_CHANGE_PITCH ) ? 1 : 0, floatround( flPitch ) )
                   
                    // Hack for going through level transitions
                    g_iSoundState[ Player ] = SND_CHANGE_PITCH
                   
                    // We are charing way too long!
                    if( g_flStartCharge[ Player ] < flGameTime - 10 )
                    {
                        // ZAP!
                        emit_sound( Player, CHAN_WEAPON, g_szSoundElectro1, VOL_NORM, ATTN_NORM, 0, 80 + random_num( 0, 0x3f ) )
                        emit_sound( Player, CHAN_VOICE, g_szSoundElectro3, VOL_NORM, ATTN_NORM, 0, 80 + random_num( 0, 0x3f ) )
                       
                        // Reset fire state
                        g_bInAttack[ Player ] = 0
                       
                        // Next idle time
                        g_flWeaponIdleTime[ Player ] = flGameTime + 1.0
                       
                        // Damage player
                        ExecuteHamB( Ham_TakeDamage, Player, 0, Player, 50.0, DMG_SHOCK )
                       
                        // Make screen fade
                        UTIL_ScreenFade( Player, UNIT_SECOND*2, UNIT_SECOND/2, FFADE_IN, 255, 128, 0, 128 )
                       
                        // Idle animation
                        UTIL_PlayWeaponAnimation( Player, gauss_idle )
                    }
                }
            }
           
            // Update
            g_flLastShotTime[ Player ] = flGameTime
        }
    }
   
    return FMRES_HANDLED
}
 
// Update client data post
public fw_UpdateClientData_Post ( Player, SendWeapons, CD_Handle )
{
    // Not alive / dont have gauss/ not m249
    if ( !g_bIsAlive [ Player ] || !g_iHasGauss [ Player ] || g_iCurrentWeapon [ Player ] != CSW_M249 )
        return FMRES_IGNORED
   
    // Block default sounds/animations
    set_cd ( CD_Handle, CD_flNextAttack, halflife_time ( ) + 0.001 )
    return FMRES_HANDLED
}
 
// Player pre think
public fw_PlayerPreThink( Player )
{
    // Not alive / dont have gauss/ not m249
    if ( !g_bIsAlive [ Player ] || !g_iHasGauss [ Player ] || g_iCurrentWeapon [ Player ] != CSW_M249 )
        return
   
    // Play aftershock discharge
    if( g_fflPlayAfterShock[ Player ] && g_fflPlayAfterShock[ Player ] < get_gametime( ) )
    {
        // Randomly play sound
        switch( random_num(0, 3 ) )
        {
            case 0: emit_sound( Player, CHAN_WEAPON, g_szSoundElectro1,random_float( 0.7, 0.8 ), ATTN_NORM, 0, PITCH_NORM )
                case 1: emit_sound( Player, CHAN_WEAPON, g_szSoundElectro2,random_float( 0.7, 0.8 ), ATTN_NORM, 0, PITCH_NORM )
                case 2: emit_sound( Player, CHAN_WEAPON, g_szSoundElectro3,random_float( 0.7, 0.8 ), ATTN_NORM, 0, PITCH_NORM )
                case 3: return // No sound
            }
       
        // Reset discharge
        g_fflPlayAfterShock[ Player ] = 0.0
    }
   
    // Check if we are in a middle of attack
    if( g_bInAttack[ Player ] != 0 )
    {
        // Check if have released attack2 button
        if( get_gametime( ) - g_flLastShotTime[ Player ] > 0.2 )
        {
            // Start to fire
            StartFire( Player )
           
            // Reset attack state
            g_bInAttack[ Player ] = 0
           
            // Next idle time
            g_flWeaponIdleTime[ Player ] = get_gametime( ) + 2.0
        }
    }
    else
    {
        // Force to idle
        WeaponIdle( Player )
    }
}
 
// Player respawned
public fw_PlayerSpawn_Post( Player )
{
    // Not alive
    if( !is_user_alive( Player ) )
        return
   
    // Update
    g_bIsAlive[ Player ] = true
}
 
// Guass deploy
public fw_TCannonDeploy_Post( iEnt )
{
    // Get owner
    static Player
    Player = get_pdata_cbase( iEnt, m_pPlayer, 4 )
   
    if(!is_user_valid_connected(Player) || !(get_user_weapon(Player) & CSW_M249))   return
   
    // Does this player has gauss?
    if ( g_iHasGauss[ Player ] )
    {
        // Replace models
        set_pev( Player, pev_viewmodel2, g_szModelGaussV )
        set_pev( Player, pev_weaponmodel2, g_szModelGaussP )
       
        // Deploy animation
        UTIL_PlayWeaponAnimation( Player, gauss_draw )
       
        // Reset aftershock
        g_fflPlayAfterShock[ Player ] = 0.0
    }
}
 
// Gauss holster
public fw_TCannonHolster_Post( iEnt )
{
    // Get owner
    static Player
    Player = get_pdata_cbase( iEnt, m_pPlayer, 4 )
   
    // Does this player has gauss?
    if ( g_iHasGauss[ Player ] )
    {
        // Check if player is still attacking
        if( g_bInAttack[ Player ] )
        {
            // Bug!Bug!Stop spin sound
            emit_sound( Player, CHAN_WEAPON, g_szSoundGaussSpin, 0.0, 0.0, SND_STOP, 0 )
           
            // Attack
            StartFire( Player )
        }
       
        // Holster animation
        UTIL_PlayWeaponAnimation( Player, gauss_holster )
       
        // Reset attack status
        g_bInAttack[ Player ] = 0
    }
}
 
// Add Gauss to players inventory
public fw_TCannonAddToPlayer( iEnt, Player )
{
    // Prevent run-time errors
    if( is_valid_ent( iEnt ) && is_user_valid_connected( Player ) )
    {
        // Seems that player has picked up a gauss
        if( pev( iEnt, pev_weaponkey ) == GAUSS_WEAPONKEY )
        {
            // Update variable
            g_iHasGauss[ Player ] = true
           
            // Update bp ammo
            cs_set_user_bpammo( Player, CSW_M249, pev( iEnt, pev_bpammo ) )
           
            // Reset weapon options
            set_pev( iEnt, pev_weaponkey, 0 )
            set_pev( iEnt, pev_bpammo, 0 )
           
            return HAM_HANDLED
        }
    }
    return HAM_IGNORED
}
 
// Gauss post frame
public fw_TCannonPostFrame( iEnt )
{
    // Get owner
    static iOwner
    iOwner = get_pdata_cbase(iEnt, m_pPlayer, 4)
   
    if(!is_valid_ent(iEnt) || !is_user_valid_connected(iOwner)) return
   
    // Does this player has gauss?
    if ( g_iHasGauss[ iOwner ] )
    {
        // Reload offset
        static fInReload
        fInReload = get_pdata_int ( iEnt, m_fInReload,4 )
       
        // Next attack time
        static Float:flNextAttack
        flNextAttack = get_pdata_float (iOwner, m_flNextAttack, 5)
       
        // Clip
        static iClip
        iClip = get_pdata_int ( iEnt, m_iClip, 4 )
       
        // Ammo type
        static iAmmoType
        iAmmoType = m_rgAmmo_player_Slot0 + get_pdata_int ( iEnt, m_iPrimaryAmmoType, 4 )
       
        // BP ammo
        static iBpAmmo
        iBpAmmo = get_pdata_int ( iOwner, iAmmoType, 5 )   
       
        // Reloading
        if ( fInReload && flNextAttack <= 0.0 )
        {
            // Calculate the difference
            static j
            j = min ( g_pClip - iClip, iBpAmmo )
           
            // Set new clip
            set_pdata_int ( iEnt, m_iClip, iClip + j, 4 )
           
            // Decrease 'x' bullets from backpack(depending on new clip)
            set_pdata_int( iOwner, iAmmoType, iBpAmmo-j, 5 )
           
            // Not reloding anymore
            set_pdata_int ( iEnt, m_fInReload, 0, 4 )
            fInReload = 0
        }
       
        // Get buttons
        static iButton ; iButton = pev ( iOwner, pev_button)
       
        // Attack/Attack2 buttons and next prim/sec attack time hasnt' come yet
        if( ( iButton & IN_ATTACK2 && get_pdata_float ( iEnt, m_flNextSecondaryAttack, 4 ) <= 0.0)
        || ( iButton & IN_ATTACK && get_pdata_float ( iEnt, m_flNextPrimaryAttack, 4 ) <= 0.0) )
        {
            return
        }
   
        // Reload button / not reloading
        if( iButton & IN_RELOAD && !fInReload )
        {
            // Old clip is more/equal than/to new
            if( iClip >= g_pClip )
            {
                // Remove reload button
                set_pev ( iOwner, pev_button, iButton & ~IN_RELOAD )
               
                // Idle animation
                UTIL_PlayWeaponAnimation ( iOwner, gauss_idle )
               
                // Idle time
                g_flWeaponIdleTime[ iOwner ] = get_gametime( ) + 0.5
            }
            else
            {
                // Out of ammo
                if ( !iBpAmmo )
                    return
                   
                // Reload weapon
                UTIL_WeaponReload ( iOwner, iEnt )
            }
        }
    }
}
 
// Gauss reload post
public fw_TCannonReload_Post( iEnt )
{
    // Get owner
    static Player
    Player = get_pdata_cbase( iEnt, m_pPlayer, 4 )
   
    // Does this player has gauss and is he in a middle of reloading ?
    if ( g_iHasGauss[ Player ] && get_pdata_int( iEnt, m_fInReload, 4 ) )
    {
        // Reload
        UTIL_WeaponReload( Player, iEnt )
    }
}
 
// ------------------------------- Internal Functions ----------------------------------------
 
// Gauss start fire
public StartFire( Player )
{
    // This var holds damage
    static Float:flDamage
   
    // Make vectors
    UTIL_MakeVectors( Player )
   
    // Get gametime
    static Float:flGameTime
    flGameTime = get_gametime( )
   
    // This is maximal possible damage from secondary attack!
    if( flGameTime - g_flStartCharge[ Player ] > GAUSS_CHARGETIME )
    {
        flDamage = g_pDmgSec
    }
    else
    {
        // The longer you hold attack button - the bigger is damage
        flDamage = g_pDmgSec * ( ( flGameTime - g_flStartCharge[ Player ] ) / GAUSS_CHARGETIME )
    }
   
    // Primary attack do less damage
    if( g_bPrimaryFire[ Player ] )
    {
        flDamage = g_pDmgPrim
    }
   
    // Make sure that we are not ending attack
    if( g_bInAttack[ Player ] != 3 )
    {
        // Secondary attack can pop you up in the air.Not primary attack!
        if( !g_bPrimaryFire[ Player ] )
        {
            // Current players velocity
            static Float:flVel[ 3 ], Float:v_forward[ 3 ]
            pev( Player, pev_velocity, flVel )
            global_get( glb_v_forward, v_forward )
           
            // Try to affect only vertical velocity
            VectorMS( flVel, flDamage * 5.0, v_forward, flVel )
           
            // Jump!
            set_pev( Player, pev_velocity, flVel )
        }
    }
   
    // Recoil
    static Float:flRecoil[ 3 ]
    flRecoil[ 0 ] = GAUSS_RECOIL
    set_pev( Player, pev_punchangle, flRecoil )
   
    // Fire animation
    UTIL_PlayWeaponAnimation( Player, gauss_fire2 )
   
    // Fire sound
    static Float:flResult
    flResult = 0.5 + flDamage * ( 1.0 / 400.0 )
   
    if( flResult > 1.0 )
    {
        flResult = 1.0
    }
   
    emit_sound( Player, CHAN_WEAPON, g_szSoundGaussFire, flResult, ATTN_NORM, 0, 85 + random_num( 0, 0x1f ) )
   
    // Get players aimpoint position
    static Float:vecDest[ 3 ]
    global_get( glb_v_forward, vecDest )
   
    // Calculate start position
    static Float:vecSrc[ 3 ]
    UTIL_GetGunPosition( Player, vecSrc )
   
    // Time until aftershock 'static discharge' sound
    g_fflPlayAfterShock[ Player ] = flGameTime + random_float( 0.3, 0.8 )
   
    // Fire!
    Fire( Player, vecSrc, vecDest, flDamage )
}
 
// Fire!
Fire( Player, Float:vecOrigSrc[ ], Float:vecDir[ ], Float:flDamage )
{
    // Start position
    static Float:vecSrc[ 3 ]
    xs_vec_copy( vecOrigSrc, vecSrc )
   
    // Calculate end position
    static Float:vecDest[ 3 ]
    VectorMA( vecSrc, 8192.0, vecDir, vecDest )
   
    // Few trace handles
    static tr, beam_tr
   
    // Max fraction
    static Float:flMaxFrac
    flMaxFrac = 1.0
   
    // Total
    static nTotal
    nTotal = 0
   
    // Does this beam punched the wall ?
    static bool:fHasPunched
    fHasPunched = false
   
    // Does this is first beam
    static bool:fFirstBeam
    fFirstBeam = true
   
    // Max hits
    static nMaxHits
    nMaxHits = 10
   
    // Entity whoch should be ignored
    static pEntToIgnore
   
    // Make sure that beam will'be able to cause damage
    while( flDamage > 10 && nMaxHits > 0 )
    {
        // Decrease hit count
        nMaxHits--
       
        // Draw a trace line
        engfunc( EngFunc_TraceLine, vecSrc, vecDest, DONT_IGNORE_MONSTERS, pEntToIgnore, tr )
       
        // We'll never get outside!
        if( get_tr2( tr, TR_AllSolid ) )
            break
       
        // Get entity which was hit
        static pEntity
        pEntity = Instance( get_tr2( tr, TR_pHit ) )   
       
        // Get vector end position
        static Float:vecEnd[ 3 ]
        get_tr2( tr, TR_vecEndPos, vecEnd )
       
        // Its first beam  
        if( fFirstBeam )
        {
            // Add muzzleflash
            set_pev( Player, pev_effects, pev(Player, pev_effects) | EF_MUZZLEFLASH )
           
            // Its not first anymore
            fFirstBeam = false
           
            // Add
            nTotal += 26
           
            // Draw beam
            engfunc( EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, vecSrc, 0 )
            //message_begin( MSG_BROADCAST, SVC_TEMPENTITY )
            write_byte( TE_BEAMENTPOINT ) // Temp. entity ID
            write_short( Player | 0x1000 ) // Start entity
            engfunc( EngFunc_WriteCoord, vecEnd[ 0 ] ) // End position X
            engfunc( EngFunc_WriteCoord, vecEnd[ 1 ] ) // End position Y
            engfunc( EngFunc_WriteCoord, vecEnd[ 2 ] ) // End position Z
            write_short( g_iBeam ) // Sprite index
            write_byte( 0 ) // Start frame
            write_byte( 1 ) // Frame rate
            write_byte( 1 ) // Life
            write_byte( g_bPrimaryFire[ Player ] ? 16 : 25 ) // Line width
            write_byte( 0 ) // Noise amplitude
            write_byte( 255 )
            write_byte( 128 )
            write_byte( 0 )
            write_byte( 255 ) // Alpha
            write_byte( 0 ) // Scroll speed
            message_end( )
        }
        else
        {
            // Draw beam
            engfunc( EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, vecSrc, 0 )
            write_byte( TE_BEAMPOINTS ) // Temp. entity ID
            engfunc( EngFunc_WriteCoord, vecSrc[ 0 ] ) // Start position X
            engfunc( EngFunc_WriteCoord, vecSrc[ 1 ] ) // Start position Y
            engfunc( EngFunc_WriteCoord, vecSrc[ 2 ] ) // Start position Z
            engfunc( EngFunc_WriteCoord, vecEnd[ 0 ] ) // End position X
            engfunc( EngFunc_WriteCoord, vecEnd[ 1 ] ) // End position Y
            engfunc( EngFunc_WriteCoord, vecEnd[ 2 ] ) // End position Z
            write_short( g_iBeam ) // Sprite index
            write_byte( 0 ) // Start frame
            write_byte( 1 ) // Frame rate
            write_byte( 1 ) // Life
            write_byte( g_bPrimaryFire[ Player ] ? 15 : 25 ) // Line width
            write_byte( 0 ) // Noise amplitude
            write_byte( 255 )
            write_byte( 128 )
            write_byte( 0 )
            write_byte( 255 )
            write_byte( 0 ) // Scroll speed
            message_end( )
        }
       
        // Check if this entity should take any damage
        if( pev( pEntity, pev_takedamage ) != DAMAGE_NO )
        {
            // Check if this is player and zombie
            if( is_user_valid_connected( pEntity ) && ze_is_user_zombie( pEntity ) )
            {
                // Retrieve health
                static iHealth
                iHealth = get_user_health( pEntity )
           
                // We should be alive
                if( iHealth - flDamage >= 1 )
                {
                    // Cause some damage
                    ExecuteHamB( Ham_TakeDamage, pEntity, 0, Player, flDamage, DMG_BULLET | DMG_ALWAYSGIB )
                }
                else
                {
                    // Die
                    g_bKilledByLaser[ pEntity ] = true
                    ExecuteHamB( Ham_Killed, pEntity, Player, 2 )
                    g_bKilledByLaser[ pEntity ] = false
                }
            }
        }
       
        // Check if this entity should reflect our beam
        if( ReflectGauss( pEntity ) )
        {
            static Float:n
           
            // Return normal vector in a spot we hit
            static Float:vecPlaneNormal[ 3 ]
            get_tr2( tr, TR_vecPlaneNormal, vecPlaneNormal )
           
            // Calculate dot product
            n = - xs_vec_dot( vecPlaneNormal, vecDir )
           
            // 60 degrees
            if ( 0 < n < 0.5 )
            {
                static Float:r[ 3 ]
                VectorMA( vecDir, 2.0 * n, vecPlaneNormal, r )
               
                // Get vector end position
                get_tr2( tr, TR_vecEndPos, vecEnd )
               
                // Get trace fraction
                static Float:trflFraction
                get_tr2( tr, TR_flFraction, trflFraction )
               
                // Calculate fraction
                flMaxFrac = flMaxFrac - trflFraction
               
                // Copy vectors
                xs_vec_copy( r, vecDir )
               
                // Make more vector calculations
                VectorMA( vecEnd, 8.0, vecDir, vecSrc )
                VectorMA( vecSrc, 8192.0, vecDir, vecDest )
           
                // Undone!Do radius damage
               
                // Increase
                nTotal += 34
               
                if( n == 0 )
                {
                    // Lose energy
                    n = 0.1
                }
               
                // Calculate new damage
                flDamage = flDamage * ( 1 - n )
            }
            else
            {
                // Add gun shot decal on the world
                FX_GunShotDecal( vecEnd, pEntity )
               
                // Add glowing sprite on the world
                FX_TempSprite( vecEnd, 6, floatround( flDamage / 255.0 ) )
               
                // Increase
                nTotal += 13
               
                // Limit it to one hole punch
                if( fHasPunched )
                    break
               
                // Update  
                fHasPunched = true 
               
                // Try punching through wall if secondary attack (primary is incapable of
                // breaking through)
                if( !g_bPrimaryFire[ Player ] )
                {
                    // Retrieve vector end position
                    get_tr2( tr, TR_vecEndPos, vecEnd )
                   
                    // Modify start origin
                    static Float:vecStart[ 3 ]
                    VectorMA( vecEnd, 8.0, vecDir, vecStart )
                   
                    // Draw another trace line
                    engfunc( EngFunc_TraceLine, vecSrc, vecDest, DONT_IGNORE_MONSTERS, pEntToIgnore, beam_tr )
                   
                    // We'll never get outside
                    if( !get_tr2( beam_tr, TR_AllSolid ) )
                    {
                        // Get end position
                        static Float:vecBeamEndPos[ 3 ]
                        get_tr2( beam_tr, TR_vecEndPos, vecBeamEndPos )
                       
                        // Trace backwards to find exit point
                        engfunc( EngFunc_TraceLine, vecBeamEndPos, vecEnd, DONT_IGNORE_MONSTERS, pEntToIgnore, beam_tr )
                       
                        // Again get end position
                        get_tr2( beam_tr, TR_vecEndPos, vecBeamEndPos )
                       
                        static Float:ns, Float:vecSub[ 3 ]
                       
                        // Subtract vectors
                        xs_vec_sub( vecBeamEndPos, vecEnd, vecSub )
                       
                        // Get vector length
                        ns = xs_vec_len( vecSub )
                       
                        if( ns < flDamage )
                        {
                            // Lose enery
                            if( ns == 0 )
                            {
                                ns = 1.0
                            }
                           
                            // Decrease damage
                            flDamage -= ns
                           
                            // Subtract
                            static Float:vecCalc[ 3 ]
                            VectorSubtract( vecEnd, vecDir, vecCalc )
                           
                            // Absorbtion balls
                            FX_SpriteTrail( vecEnd, vecCalc, BALL_AMOUNT, 15, 3, 25, 25 )
                           
                            // Add gun shot decal on the world
                            FX_GunShotDecal( vecBeamEndPos, pEntity )
                           
                            // And glowing sprite
                            FX_TempSprite( vecBeamEndPos, 6, floatround( flDamage / 255.0 ) )
                           
                            // Subtract
                            VectorSubtract( vecBeamEndPos, vecDir, vecCalc )
                           
                            // Absorbtion balls
                            FX_SpriteTrail( vecEnd, vecCalc, BALL_AMOUNT, 15, 3, 25, 25 )
                           
                            // Increase shit
                            nTotal += 21
                           
                            /*
                            // Calculate radius damage
                            static Float:flRadDmg
                            flRadDmg = flDamage * 1.75
                           
                            // Undone.Do radius damage here!
                            floatradius( flDamage, flRadDmg, vecBeamEndPos )
                            */
                           
                            // Increase
                            nTotal += 53
                           
                            VectorMA( vecBeamEndPos, 8.0, vecDir, vecSub )
                           
                            // Add up vector
                            xs_vec_add( vecBeamEndPos, vecDir, vecSrc )
                        }
                    }
                    else
                    {
                        flDamage = 0.0
                    }
                }
                else
                {
                    // Primary attack
                    if( g_bPrimaryFire [ Player ] )
                    {
                        // Slug doesn't punch through ever with primary
                        // fire, so leave a little glowy bit and make some balls
                        FX_TempSprite( vecEnd, 6, floatround( flDamage / 255.0 ) )
                        FX_SpriteTrail( vecEnd, vecDir, BALL_AMOUNT, 15, 3, 25, 25 )
                    }
                   
                    flDamage = 0.0
                }
            }
        }
        else
        {
            // Add up vector
            xs_vec_add( vecEnd, vecDir, vecSrc )
            pEntToIgnore = pEntity
        }
    }
}              
 
// Register and cache CVARs
public Load_Cvars( )
{
    cvar_oneround = register_cvar( "ze_tcannon_oneround", "0" )
    cvar_dmgprim = register_cvar( "ze_tcannon_dmgprim", "200" )
    cvar_dmgsec = register_cvar( "ze_tcannon_dmgsec", "500" )
    cvar_clip = register_cvar( "ze_tcannon_clip", "100" )
   
    g_pOneRound = get_pcvar_num( cvar_oneround )
    g_pDmgPrim = get_pcvar_float( cvar_dmgprim )
    g_pDmgSec = get_pcvar_float( cvar_dmgsec )
    g_pClip = get_pcvar_num( cvar_clip )
}
 
// Gauss weapon idle
WeaponIdle( Player )
{
    // Get gametime
    static Float:flGameTime
    flGameTime = get_gametime( )
   
    if( g_flWeaponIdleTime[ Player ] > flGameTime )
        return
   
    // Animation sequence variable
    static iAnim
   
    // Animation randomizer
    static Float:flRand
    flRand = random_float( 0.1, 1.0 )
   
    if( flRand <= 0.5 )
    {
        iAnim = gauss_idle
        g_flWeaponIdleTime[ Player ] = flGameTime + random_float( 10.0, 15.0 )
    }
    else if( flRand <= 0.75 )
    {
        iAnim = gauss_idle2
        g_flWeaponIdleTime[ Player ] = flGameTime + random_float( 10.0, 15.0 )
    }
    else
    {
        iAnim = gauss_fidget
        g_flWeaponIdleTime[ Player ] = flGameTime + 3
    }
   
    // Idle
    UTIL_PlayWeaponAnimation( Player, iAnim )
}  
 
// Play weapon animation
UTIL_PlayWeaponAnimation( const Player, const Sequence )
{
    set_pev( Player, pev_weaponanim, Sequence )
   
    message_begin( MSG_ONE_UNRELIABLE, SVC_WEAPONANIM, .player = Player )
    write_byte( Sequence )
    write_byte( pev( Player, pev_body ) )
    message_end( )
}              
 
// Make ScreenFade
UTIL_ScreenFade( Player, Duration, HoldTime, Flags, iRed, iGreen, iBlue, iAlpha )
{
    message_begin( MSG_ONE, gmsgScreenFade, _, Player )
    write_short( Duration )
    write_short( HoldTime )
    write_short( Flags )
    write_byte( iRed )
    write_byte( iGreen )
    write_byte( iBlue )
    write_byte( iAlpha )
    message_end( )
}
 
// Reload gauss
UTIL_WeaponReload( Player, iEnt )
{
    // Modify time until next attack
    set_pdata_float( Player, m_flNextAttack, GAUSS_RELOADTIME+0.5, 5 )
   
    // Reload animation
    UTIL_PlayWeaponAnimation( Player, gauss_spin )
   
    // Enable reload offset
    set_pdata_int( iEnt, m_fInReload, 1, 4 )
   
    // Modify next idle time
    g_flWeaponIdleTime[ Player ] = get_gametime( ) + GAUSS_RELOADTIME + 1.0
}
 
// Drop all primary weapons
UTIL_DropPrimary( Player )
{
    // Get user weapons
    static weapons[ 32 ], num, i, weaponid
    num = 0 // reset passed weapons count (bugfix)
    get_user_weapons( Player, weapons, num )
   
    // Loop through them and drop primaries
    for( i = 0; i < num; i++ )
    {
        // Prevent re-indexing the array
        weaponid = weapons[ i ]
       
        // We definetely are holding primary gun
        if(( (1<<weaponid) & PRIMARY_WEAPONS_BITSUM ) )    
        {
            // Get weapon entity
            static wname[32]
            get_weaponname(weaponid, wname, charsmax(wname))
           
            // Player drops the weapon and looses his bpammo
            engclient_cmd( Player, "drop", wname)
        }
    }
}
 
// Get gun position
UTIL_GetGunPosition( Player, Float:flOrigin[ ] )
{
    static Float:vf_Origin[ 3 ], Float:vf_ViewOfs[ 3 ]
   
    pev( Player, pev_origin, vf_Origin )
    pev( Player, pev_view_ofs, vf_ViewOfs )
   
    xs_vec_add( vf_Origin, vf_ViewOfs, flOrigin )
}
 
// Make vectors
UTIL_MakeVectors ( Player )
{
    static Float:flAngle[ 3 ], Float:flPunchAngle[ 3 ]
 
    pev( Player, pev_v_angle, flAngle )
    pev( Player, pev_punchangle, flPunchAngle )
 
    xs_vec_add( flAngle, flPunchAngle, flAngle )
    engfunc( EngFunc_MakeVectors, flAngle )
}
 
// From HL SDK.
VectorMA( Float:a[ ], Float:flScale, Float:b[ ], Float:c[ ] )
{
    c[ 0 ] = a[ 0 ] + flScale * b[ 0 ]
    c[ 1 ] = a[ 1 ] + flScale * b[ 1 ]
    c[ 2 ] = a[ 2 ] + flScale * b[ 2 ]
}
 
VectorMS( const Float:flSource[ ], const Float:flScale, const Float:flMult[ ], Float:flOutput[ ] )
{
        flOutput[ 0 ] = flSource[ 0 ] - flMult[ 0 ] * flScale
        flOutput[ 1 ] = flSource[ 1 ] - flMult[ 1 ] * flScale
        flOutput[ 2 ] = flSource[ 2 ] - flMult[ 2 ] * flScale
}
 
// Another stuff from HLSDK
Instance( iEnt )
{
    return iEnt == -1 ? 0 : iEnt
}
 
// Does this entity should refect gauss?
ReflectGauss( iEnt )
{
        return IsBSPModel( iEnt ) && pev( iEnt, pev_takedamage ) == DAMAGE_NO
}
 
// Does this entity is BSP model?
IsBSPModel( iEnt )
{
    return pev( iEnt, pev_solid ) == SOLID_BSP || pev( iEnt, pev_movetype ) == MOVETYPE_PUSHSTEP
}
 
// Add gun shot decal on world!
FX_GunShotDecal( Float:flPos[ ], pEntity )
{
    // Draw gunshot
    engfunc( EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, flPos, 0 )
    write_byte( TE_GUNSHOTDECAL ) // Temp.entity ID
    engfunc( EngFunc_WriteCoord, flPos[ 0 ] ) // Position X
    engfunc( EngFunc_WriteCoord, flPos[ 1 ] ) // Position Y
    engfunc( EngFunc_WriteCoord, flPos[ 2 ] ) // Position Z
    write_short( pEntity ) // Which entity to mark?
    write_byte( 43 ) // Decal number
    message_end( )
}
 
// Add glow sprite on world
FX_TempSprite( Float:flPos[ ], iScale, iSize )
{
    engfunc( EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, flPos, 0 )
    write_byte( TE_GLOWSPRITE ) // Temp.entity ID
    engfunc( EngFunc_WriteCoord, flPos[ 0 ] ) // Position X
    engfunc( EngFunc_WriteCoord, flPos[ 1 ] ) // Position Y
    engfunc( EngFunc_WriteCoord, flPos[ 2 ] ) // Position Z
    write_short( g_iBalls ) // Sprite index
    write_byte( iScale ) // Scale
    write_byte( iSize ) // Size
    write_byte( 255 ) // Brightness
    message_end( )
}
 
// Add sprite trail
FX_SpriteTrail( Float:vecStart[ ], Float:vecDest[ ], iCount, iLife, iScale, iVel, iRnd )
{
    message_begin( MSG_BROADCAST, SVC_TEMPENTITY )
    write_byte( TE_SPRITETRAIL ) // Sprite trail
    engfunc( EngFunc_WriteCoord, vecStart[ 0 ] ) // Position X
    engfunc( EngFunc_WriteCoord, vecStart[ 1 ] ) // Position Y
    engfunc( EngFunc_WriteCoord, vecStart[ 2 ] ) // Position Z
    engfunc( EngFunc_WriteCoord, vecDest[ 0 ] ) // Position X
    engfunc( EngFunc_WriteCoord, vecDest[ 1 ] ) // Position Y
    engfunc( EngFunc_WriteCoord, vecDest[ 2 ] ) // Position Z
    write_short( g_iBalls ) // SPrite index
    write_byte( iCount ) // Amount
    write_byte( iLife ) // Life
    write_byte( iScale ) // Scale
    write_byte( iVel ) // Velocity along vector
    write_byte( iRnd ) // Randomness of velocity
    message_end( )
}
can someone make it working in our mod? It worked in 1.0 version
Image

User avatar
SexY DeviL CJ
Mod Tester
Mod Tester
Posts: 73
Joined: 6 years ago
Contact:

#2

Post by SexY DeviL CJ » 5 years ago

czirimbolo wrote: 5 years ago

Code: Select all

#include < zombie_escape >
#include < cstrike >
#include < csx >
#include < xs >
#include < fun >
 
// Plugin information
#define Plugin  "[ZE] Extra Item: Tau Cannon"
#define Version "1.2"
#define Author  "NiHiLaNTh"
 
// Maxplayers
const MaxPlayers = 32
 
// Weapon models
new const g_szModelGaussP[ ] = "models/p_gauss.mdl"
new const g_szModelGaussV[ ] = "models/v_alt_gauss.mdl"
new const g_szModelGaussW[ ] = "models/w_gauss.mdl"
 
// Weapon sounds
new const g_szSoundGaussFire[ ] = "weapons/gauss2.wav"
new const g_szSoundGaussSpin[ ] = "ambience/pulsemachine.wav"
new const g_szSoundElectro1[ ] = "weapons/electro4.wav"
new const g_szSoundElectro2[ ] = "weapons/electro5.wav"
new const g_szSoundElectro3[ ] = "weapons/electro6.wav"
 
// Some gauss/beam stuff
#define GAUSS_REFIRERATE    0.2 // Primary attack
#define GAUSS_REFIRERATE2   0.1 // Secondary attack(you shouldnt change this!)
#define GAUSS_RECOIL        -2.0 // Only X axis!
#define GAUSS_CHARGETIME    4.0 // From HLSDK
#define GAUSS_RELOADTIME    2.0 // Reload time
#define BEAM_RED        255 // Red amount
#define BEAM_GREEN      128 // Green amount
#define BEAM_BLUE       0 // Blue amount
#define BEAM_ALPHA      255 // Brightness(Alpha)
#define BALL_AMOUNT     8 // How many balls should appear :p
 
// Max. bp ammo amount
new const MAXBPAMMO[] = { -1, 52, -1, 90, 1, 32, 1, 100, 90, 1, 120, 100, 100, 90, 90, 90, 100, 120,
    5, 120, 200, // This is gauss max bp ammo.Change it if you want!
32, 90, 120, 90, 2, 35, 90, 90, -1, 100 }
 
// Player variables
new g_iHasGauss[ MaxPlayers+1 ] // Whether player has gauss
new g_iSoundState[ MaxPlayers+1 ] // Weapon sound state
new g_bInAttack[ MaxPlayers+1 ] // Current gauss attack state
new g_iCurrentWeapon[ MaxPlayers+1 ] // Current weapon player is holding
new Float:g_flLastShotTime[ MaxPlayers+1 ] // Last shot time
new Float:g_fflPlayAfterShock[ MaxPlayers+1 ] // Play aftershock sound
new Float:g_flWeaponIdleTime[ MaxPlayers+1 ] // Weapon idle time
new Float:g_flNextAmmoBurn[ MaxPlayers+1 ] // Next ammo burn time
new Float:g_flStartCharge[ MaxPlayers+1 ] // Weapon start charge
new Float:g_flAmmoStartCharge[ MaxPlayers+1 ] // Ammo start charge
new bool:g_bIsAlive[ MaxPlayers+1 ] // Whether player is alive
new bool:g_bIsConnected[ MaxPlayers+1 ] // Whether player is connected
new bool:g_bPrimaryFire[ MaxPlayers+1 ] // Does this weapon is using primary attack ?
new bool:g_bKilledByLaser[ MaxPlayers+1 ] // Imma firin mah lazor O.o
 
// CVAR pointers
new cvar_oneround // Whether gun should be only for 1 round
new cvar_dmgprim // Primary attack damage
new cvar_dmgsec // Secondary attack damage
new cvar_clip // Clip amount
 
// Cached CVAR
new g_pOneRound
new Float:g_pDmgPrim
new Float:g_pDmgSec
new g_pClip
 
// Global varibles
new g_iMaxPlayers // Maxplayers
new bool:g_bGameRestart // Detect game restart
new g_iBeam // Beam sprite
new g_iBalls // Balls :p
new g_iGaussID // Item ID
new gmsgScreenFade // Screen fade
 
// CS Offsets
const m_pPlayer = 41
const m_flNextPrimaryAttack = 46
const m_flNextSecondaryAttack = 47
const m_flTimeWeaponIdle = 48
const m_iPrimaryAmmoType = 49
const m_iClip = 51
const m_fInReload = 54
const m_flNextAttack  = 83
const m_rgAmmo_player_Slot0 = 376
 
// Macro
#define is_user_valid_connected(%1)     ( 1 <= %1 <= g_iMaxPlayers && g_bIsConnected [ %1 ] )
#define is_user_in_water(%1)            ( pev ( %1, pev_waterlevel ) == 3 )
#define VectorSubtract(%1,%2,%3)        ( %3[ 0 ] = %1[ 0 ] - %2[ 0 ], %3[ 1 ] = %1[ 1 ] - %2[ 1 ], %3[ 2 ] = %1[ 2 ] - %2[ 2 ] )
#define VectorAdd(%1,%2,%3)         ( %3[ 0 ] = %1[ 0 ] + %2[ 0 ], %3[ 1 ] = %1[ 1 ] + %2[ 2 ], %3[ 2 ] = %1[ 2 ] + %2[ 2 ] )
#define VectorScale(%1,%2,%3)           ( %3[ 0 ] = %2 * %1[ 0 ], %3[ 1 ] = %2 * %1[ 1 ], %3[ 2 ] = %2 * %1[ 2 ] )
#define VectorLength(%1)                ( floatsqroot ( %1[ 0 ] * %1[ 0 ] + %1[ 1 ] * %1[ 1 ] + %1[ 2 ] * %1[ 2 ] ) )
 
// Hack!Custom fields
#define pev_weaponkey       pev_impulse
#define pev_bpammo      pev_iuser3
 
// Misc stuff
#define FCVAR_FLAGS     ( FCVAR_SERVER | FCVAR_SPONLY | FCVAR_UNLOGGED )
#define GAUSS_WEAPONKEY 42856
#define NULLENT     -1
#define FFADE_IN        0x0000
#define UNIT_SECOND     (1<<12)
 
// Entity classnames
new const g_szClassPlayer[ ] = "player"
new const g_szClassM249[ ] = "weapon_m249"
 
// Primary weapon bitsum
const PRIMARY_WEAPONS_BITSUM = (1<<CSW_SCOUT)|(1<<CSW_XM1014)|(1<<CSW_MAC10)|(1<<CSW_AUG)|(1<<CSW_UMP45)|(1<<CSW_SG550)|(1<<CSW_GALIL)|(1<<CSW_FAMAS)|(1<<CSW_AWP)|(1<<CSW_MP5NAVY)|(1<<CSW_M249)|(1<<CSW_M3)|(1<<CSW_M4A1)|(1<<CSW_TMP)|(1<<CSW_G3SG1)|(1<<CSW_SG552)|(1<<CSW_AK47)|(1<<CSW_P90)
 
// Animation sequnces
enum
{
    gauss_idle,
    gauss_idle2,
    gauss_fidget,
    gauss_spinup,
    gauss_spin,
    gauss_fire,
    gauss_fire2,
    gauss_holster,
    gauss_draw
}
 
// Precache
public plugin_precache( )
{
    // Weapon models
    precache_model( g_szModelGaussP )
    precache_model( g_szModelGaussV )
    precache_model( g_szModelGaussW )
   
    // Sounds
    precache_sound( g_szSoundGaussFire )
    precache_sound( g_szSoundGaussSpin )
    precache_sound( g_szSoundElectro1 )
    precache_sound( g_szSoundElectro2 )
    precache_sound( g_szSoundElectro3 )
    precache_sound( "items/9mmclip1.wav" )
   
    // Sprites
    g_iBeam = precache_model( "sprites/smoke.spr" )
    g_iBalls = precache_model( "sprites/hotglow.spr" )
}
 
// Initialization
public plugin_init( )
{
    // New plugin
    register_plugin( Plugin, Version, Author )
   
    // For Game-Monitor support
    register_cvar( "ze_tcannon_version", Version, FCVAR_FLAGS )
   
    // New extra item
    g_iGaussID = ze_register_item("Tau Cannon", 30, 0)
   
    // Events
    register_event( "CurWeapon", "EV_CurWeapon", "be", "1=1" )
    register_event( "DeathMsg", "EV_DeathMsg", "a" )
    register_event( "HLTV", "EV_RoundStart", "a", "1=0", "2=0" )
    register_event( "TextMsg", "EV_GameRestart", "a", "2=#Game_Commencing", "2=#Game_will_restart_in" )
   
    // FakeMeta forwards
    register_forward( FM_SetModel, "fw_SetModel" )
    register_forward( FM_CmdStart, "fw_CmdStart" )
    register_forward( FM_UpdateClientData, "fw_UpdateClientData_Post", 1 )
    register_forward( FM_PlayerPreThink, "fw_PlayerPreThink" )
   
    // HamSandwich forwards
    RegisterHam( Ham_Spawn, g_szClassPlayer, "fw_PlayerSpawn_Post", 1 )
    RegisterHam( Ham_Item_Deploy, g_szClassM249, "fw_TCannonDeploy_Post", 1 )
    RegisterHam( Ham_Item_Holster, g_szClassM249, "fw_TCannonHolster_Post", 1 )
    RegisterHam( Ham_Item_AddToPlayer, g_szClassM249, "fw_TCannonAddToPlayer" )
    RegisterHam( Ham_Item_PostFrame, g_szClassM249, "fw_TCannonPostFrame" )
    RegisterHam( Ham_Weapon_Reload, g_szClassM249, "fw_TCannonReload_Post", 1 )
   
    // CVARs are in Load_Cvars( ) function!
   
    // Messages
    register_message( get_user_msgid( "DeathMsg" ), "fn_DeathMsg" )
    gmsgScreenFade = get_user_msgid( "ScreenFade" )
   
    // Store maxplayers in a global variable
    g_iMaxPlayers = get_maxplayers( )
}  
 
// Configuration
public plugin_cfg( )
{
    // Cache CVARs
    set_task( 1.5, "Load_Cvars" )
}
 
// ------------------------------- Game Events ----------------------------------------
 
// Client connected
public client_connect( Player )
{
    // Make a lot of updates
    g_iHasGauss[ Player ] = false
    g_bInAttack[ Player ] = 0
    g_fflPlayAfterShock[ Player ] = 0.0
    g_flWeaponIdleTime[ Player ] = 0.0
    g_bPrimaryFire[ Player ] = false
    g_bIsAlive[ Player ] = false
    g_bIsConnected[ Player ] = true
}
 
// Client disconnected
public client_disconnect( Player )
{
    // Only few important updates
    g_bIsAlive[ Player ] = false
    g_bIsConnected[ Player ] = false
}
 
public ze_select_item_pre(id, itemid)
{
    // Return Available and we will block it in Post, So it dosen't affect other plugins
    if (itemid != g_iGaussID)
        return ZE_ITEM_AVAILABLE
   
    // Available for Humans only, So don't show it for zombies
    if (ze_is_user_zombie(id))
        return ZE_ITEM_DONT_SHOW
   
    return ZE_ITEM_AVAILABLE
}
 
public ze_select_item_post(Player, itemid)
{
    if (itemid != g_iGaussID)
        return
 
    // Drop all primary weapons
    UTIL_DropPrimary( Player )
       
    // Update
    g_iHasGauss[ Player ] = true
       
    // Give m249
    give_item( Player, "weapon_m249" )
       
    // Find weapon entity
    new iEnt = find_ent_by_owner( NULLENT, g_szClassM249, Player )
       
    // Apply new clip
    cs_set_weapon_ammo( iEnt, g_pClip )
       
    // Back pack ammo
    cs_set_user_bpammo( Player, CSW_M249, MAXBPAMMO[ 20 ] )
}
 
// Current weapon player is holding
public EV_CurWeapon( Player )
{
    // Not alive
    if( !g_bIsAlive[ Player ] )
        return PLUGIN_CONTINUE
   
    // Update
    g_iCurrentWeapon[ Player ] = read_data( 2 )
   
    return PLUGIN_CONTINUE
}
 
// Someone died
public EV_DeathMsg( )
{
    // Get victim
    static iVictim
    iVictim = read_data( 2 )
   
    // Not connected
    if( !is_user_valid_connected( iVictim ) )
        return
   
    // Update
    g_bIsAlive[ iVictim ] = false
   
    // Check if victim has gauss
    if( g_iHasGauss[ iVictim ] && !is_user_bot( iVictim ) )
    {
        // Force to drop
        engclient_cmd( iVictim, "drop weapon_m249" )
    }
}
 
// Round started
public EV_RoundStart( )
{
    // Restart/One round only
    if( g_bGameRestart || g_pOneRound )
    {
        // Reset array value
        arrayset( g_iHasGauss, false, MaxPlayers+1 )
    }
   
    // Update
    g_bGameRestart = false
}
 
// Game restart
public EV_GameRestart( )
{
    // Update
    g_bGameRestart = true
}
 
// Hook death message
public fn_DeathMsg( Player, Dest, iEntity )
{
    // Get victim
    static iVictim, iKiller
    iKiller = get_msg_arg_int( 1 )
    iVictim = get_msg_arg_int( 2 )
   
    // Not connected
    if( !is_user_valid_connected( iVictim ) || iKiller == iVictim )
        return PLUGIN_CONTINUE
   
    // We were killed by laser
    if ( g_bKilledByLaser[ iVictim ] )
    {
        // Replace name in console
        set_msg_arg_string ( 4, "tau cannon" )
    }
    return PLUGIN_CONTINUE
}
 
// ------------------------------- Forwards ----------------------------------------
 
// Replace world model
public fw_SetModel ( Entity, const Model [ ] )
{
    // Prevent invalid entity messages
    if( !pev_valid( Entity ) )
        return FMRES_IGNORED
   
    // Not w_awp.mdl
    if( !equal( Model, "models/w_m249.mdl" ) )
        return FMRES_IGNORED
   
    // Get entity classname
    static szClassname[ 32 ]
    pev( Entity, pev_classname, szClassname, charsmax( szClassname ) )
   
    // Not weaponbox
    if( !equal( szClassname, "weaponbox" ) )
        return FMRES_IGNORED
   
    // Get owner
    static iOwner
    iOwner = pev( Entity, pev_owner )
   
    // Get awp ID
    static iWeaponID
    iWeaponID = find_ent_by_owner( NULLENT, g_szClassM249, Entity )
   
    // Make sure that we have gauss
    if( g_iHasGauss [ iOwner ] && is_valid_ent( iWeaponID ) )
    {
        // Hack! Store weaponkey
        set_pev( iWeaponID, pev_weaponkey, GAUSS_WEAPONKEY )
       
        // Hack! Store bp ammo
        set_pev( iWeaponID, pev_bpammo, cs_get_user_bpammo( iOwner, CSW_M249 ) )
       
        // Update
        g_iHasGauss[ iOwner ] = false
       
        // Replace models
        engfunc( EngFunc_SetModel, Entity, g_szModelGaussW )
        return FMRES_SUPERCEDE
    }
    return FMRES_IGNORED
}
 
// Command start
public fw_CmdStart( Player, UC_Handle, Seed )
{
    // Not alive/dont have gauss/not m249
    if( !g_bIsAlive[ Player ] || !g_iHasGauss[ Player ] || g_iCurrentWeapon[ Player ] != CSW_M249 )
        return FMRES_IGNORED
   
    // Retrieve pressed button bitsum
    static iButtons
    iButtons = get_uc( UC_Handle, UC_Buttons )
   
    // Retrieve game time
    static Float:flGameTime
    flGameTime = get_gametime( )
   
    // Retrieve weapon entity
    static iEnt
    iEnt = find_ent_by_owner( NULLENT, g_szClassM249, Player )
   
    // Retrieve clip amount
    static iClip
    iClip = cs_get_weapon_ammo( iEnt )
   
    // Primary attack
    if( iButtons & IN_ATTACK )
    {
        // Remove attack buttons from their button mask
        iButtons &= ~IN_ATTACK
        set_uc( UC_Handle, UC_Buttons, iButtons )
       
        // Prevent too fast shooting
        if( flGameTime - g_flLastShotTime[ Player ] < GAUSS_REFIRERATE )
            return FMRES_IGNORED
       
        // Dont fire while reloading
        if( get_pdata_int( iEnt, m_fInReload, 4 ) )
            return FMRES_IGNORED
       
        // Not enough clip/under water
        if( iClip < 2 || is_user_in_water( Player ) )
        {
            // Emit empty sound
            ExecuteHamB( Ham_Weapon_PlayEmptySound, iEnt )
            return FMRES_IGNORED
        }
       
        // Update
        g_bPrimaryFire[ Player ] = true
       
        // Start to fire
        StartFire( Player )
       
        // Decrease clip
        cs_set_weapon_ammo( iEnt, iClip-2 )
       
        // Reset weapon attack status
        g_bInAttack[ Player ] = 0
       
        // Set time when idle animation should be played
        g_flWeaponIdleTime[ Player ] = flGameTime + 1.0
       
        // Remember last shot time
        g_flLastShotTime[ Player ] = flGameTime
    }
    // Secondary attack
    else if( iButtons & IN_ATTACK2 )
    {
        // Prevent too fast shooting
        if( flGameTime - g_flLastShotTime[ Player ] < GAUSS_REFIRERATE2 )
            return FMRES_IGNORED
       
        // Dont fire while reloading
        if( get_pdata_int( iEnt, m_fInReload, 4 ) )
            return FMRES_IGNORED
       
        // Are we swimming ?
        if( is_user_in_water( Player ) )
        {
            // We are in a middle of attack
            if( g_bInAttack[ Player ] != 0 )
            {
                // Stop attack
                emit_sound( Player, CHAN_WEAPON, g_szSoundElectro1, VOL_NORM, ATTN_NORM, 0, 80 + random_num( 0, 0x3f ) )
               
                // Gun idle
                UTIL_PlayWeaponAnimation( Player, gauss_idle )
                return FMRES_IGNORED
            }
            else
            {
                // Empty sound
                ExecuteHamB( Ham_Weapon_PlayEmptySound, iEnt )
                return FMRES_IGNORED
            }
        }
       
        // Get player oldbuttons
        static iOldButtons
        iOldButtons = pev( Player, pev_oldbuttons )
       
        // Make sure that we are holding secondary attack button
        if( iOldButtons & IN_ATTACK2 )
        {
            // Which attack state do we have
            switch ( g_bInAttack[ Player ] )
            {
                case 0: // Attack start
                {
                    // Out of ammo
                    if ( iClip <= 0 )
                    {
                        ExecuteHamB( Ham_Weapon_PlayEmptySound, iEnt )
                        return FMRES_IGNORED
                    }
                   
                    // We aren't using primary attack anymore
                    g_bPrimaryFire[ Player ] = false
                   
                    // Decrease clip
                    cs_set_weapon_ammo( iEnt, --iClip )
                   
                    // Update
                    g_flNextAmmoBurn[ Player ] = flGameTime
                   
                    // Send spinup animation
                    UTIL_PlayWeaponAnimation( Player, gauss_spinup )
                   
                    // Update attack state
                    g_bInAttack[ Player ] = 1
                   
                    // Next idle time
                    g_flWeaponIdleTime[ Player ] = flGameTime + 0.5
                   
                    // Update
                    g_flStartCharge[ Player ] = flGameTime
                    g_flAmmoStartCharge[ Player ] = flGameTime + GAUSS_CHARGETIME
                   
                    // Update sound state
                    g_iSoundState[ Player ] = 0
                   
                    // Spin sound
                    emit_sound( Player, CHAN_WEAPON, g_szSoundGaussSpin, VOL_NORM, ATTN_NORM, g_iSoundState[Player ], 110 )
                   
                    // Change sound state
                    g_iSoundState[ Player ] = SND_CHANGE_PITCH
                }
                case 1: // In a middle of attack
                {
                    if( g_flWeaponIdleTime[ Player ] < flGameTime )
                    {
                        // Spin anim
                        UTIL_PlayWeaponAnimation( Player, gauss_spin )
                       
                        // Update state
                        g_bInAttack[ Player ] = 2
                    }
                }
                default: // End of attack
                {
                    // During the charging process, eat one bit of ammo every once in a while
                    if( flGameTime >= g_flNextAmmoBurn[ Player ] && g_flNextAmmoBurn[ Player ] != 1000 )
                    {
                        // Decrease clip
                        cs_set_weapon_ammo( iEnt, --iClip )
                       
                        // Next time when ammo should be decreased
                        g_flNextAmmoBurn[ Player ] = flGameTime + 0.1
                    }
                   
                    // Shit!We run out of ammo
                    if( iClip <= 0 )
                    {
                        // Force gun to fire
                        StartFire( Player )
                       
                        // Reset weapon state
                        g_bInAttack[ Player ] = 0
                       
                        // Set next idle time
                        g_flWeaponIdleTime[ Player ] = flGameTime + 1.0
                    }
                   
                    // Gun is fully charged up
                    if( flGameTime >= g_flAmmoStartCharge[ Player ] )
                    {
                        // Dont eat any more ammo!
                        g_flNextAmmoBurn[ Player ] = 1000.0
                    }
                   
                    // Calculate pitch
                    static Float:flPitch
                    flPitch = ( flGameTime - g_flStartCharge[ Player ] ) * ( 150 / GAUSS_CHARGETIME ) + 100
                   
                    // Pitch shouldnt be THAT big
                    if ( flPitch > 250 )
                    {
                        flPitch = 250.0
                    }
                   
                    // Spin sound
                    emit_sound( Player, CHAN_WEAPON, g_szSoundGaussSpin, VOL_NORM, ATTN_NORM, ( g_iSoundState[ Player ] == SND_CHANGE_PITCH ) ? 1 : 0, floatround( flPitch ) )
                   
                    // Hack for going through level transitions
                    g_iSoundState[ Player ] = SND_CHANGE_PITCH
                   
                    // We are charing way too long!
                    if( g_flStartCharge[ Player ] < flGameTime - 10 )
                    {
                        // ZAP!
                        emit_sound( Player, CHAN_WEAPON, g_szSoundElectro1, VOL_NORM, ATTN_NORM, 0, 80 + random_num( 0, 0x3f ) )
                        emit_sound( Player, CHAN_VOICE, g_szSoundElectro3, VOL_NORM, ATTN_NORM, 0, 80 + random_num( 0, 0x3f ) )
                       
                        // Reset fire state
                        g_bInAttack[ Player ] = 0
                       
                        // Next idle time
                        g_flWeaponIdleTime[ Player ] = flGameTime + 1.0
                       
                        // Damage player
                        ExecuteHamB( Ham_TakeDamage, Player, 0, Player, 50.0, DMG_SHOCK )
                       
                        // Make screen fade
                        UTIL_ScreenFade( Player, UNIT_SECOND*2, UNIT_SECOND/2, FFADE_IN, 255, 128, 0, 128 )
                       
                        // Idle animation
                        UTIL_PlayWeaponAnimation( Player, gauss_idle )
                    }
                }
            }
           
            // Update
            g_flLastShotTime[ Player ] = flGameTime
        }
    }
   
    return FMRES_HANDLED
}
 
// Update client data post
public fw_UpdateClientData_Post ( Player, SendWeapons, CD_Handle )
{
    // Not alive / dont have gauss/ not m249
    if ( !g_bIsAlive [ Player ] || !g_iHasGauss [ Player ] || g_iCurrentWeapon [ Player ] != CSW_M249 )
        return FMRES_IGNORED
   
    // Block default sounds/animations
    set_cd ( CD_Handle, CD_flNextAttack, halflife_time ( ) + 0.001 )
    return FMRES_HANDLED
}
 
// Player pre think
public fw_PlayerPreThink( Player )
{
    // Not alive / dont have gauss/ not m249
    if ( !g_bIsAlive [ Player ] || !g_iHasGauss [ Player ] || g_iCurrentWeapon [ Player ] != CSW_M249 )
        return
   
    // Play aftershock discharge
    if( g_fflPlayAfterShock[ Player ] && g_fflPlayAfterShock[ Player ] < get_gametime( ) )
    {
        // Randomly play sound
        switch( random_num(0, 3 ) )
        {
            case 0: emit_sound( Player, CHAN_WEAPON, g_szSoundElectro1,random_float( 0.7, 0.8 ), ATTN_NORM, 0, PITCH_NORM )
                case 1: emit_sound( Player, CHAN_WEAPON, g_szSoundElectro2,random_float( 0.7, 0.8 ), ATTN_NORM, 0, PITCH_NORM )
                case 2: emit_sound( Player, CHAN_WEAPON, g_szSoundElectro3,random_float( 0.7, 0.8 ), ATTN_NORM, 0, PITCH_NORM )
                case 3: return // No sound
            }
       
        // Reset discharge
        g_fflPlayAfterShock[ Player ] = 0.0
    }
   
    // Check if we are in a middle of attack
    if( g_bInAttack[ Player ] != 0 )
    {
        // Check if have released attack2 button
        if( get_gametime( ) - g_flLastShotTime[ Player ] > 0.2 )
        {
            // Start to fire
            StartFire( Player )
           
            // Reset attack state
            g_bInAttack[ Player ] = 0
           
            // Next idle time
            g_flWeaponIdleTime[ Player ] = get_gametime( ) + 2.0
        }
    }
    else
    {
        // Force to idle
        WeaponIdle( Player )
    }
}
 
// Player respawned
public fw_PlayerSpawn_Post( Player )
{
    // Not alive
    if( !is_user_alive( Player ) )
        return
   
    // Update
    g_bIsAlive[ Player ] = true
}
 
// Guass deploy
public fw_TCannonDeploy_Post( iEnt )
{
    // Get owner
    static Player
    Player = get_pdata_cbase( iEnt, m_pPlayer, 4 )
   
    if(!is_user_valid_connected(Player) || !(get_user_weapon(Player) & CSW_M249))   return
   
    // Does this player has gauss?
    if ( g_iHasGauss[ Player ] )
    {
        // Replace models
        set_pev( Player, pev_viewmodel2, g_szModelGaussV )
        set_pev( Player, pev_weaponmodel2, g_szModelGaussP )
       
        // Deploy animation
        UTIL_PlayWeaponAnimation( Player, gauss_draw )
       
        // Reset aftershock
        g_fflPlayAfterShock[ Player ] = 0.0
    }
}
 
// Gauss holster
public fw_TCannonHolster_Post( iEnt )
{
    // Get owner
    static Player
    Player = get_pdata_cbase( iEnt, m_pPlayer, 4 )
   
    // Does this player has gauss?
    if ( g_iHasGauss[ Player ] )
    {
        // Check if player is still attacking
        if( g_bInAttack[ Player ] )
        {
            // Bug!Bug!Stop spin sound
            emit_sound( Player, CHAN_WEAPON, g_szSoundGaussSpin, 0.0, 0.0, SND_STOP, 0 )
           
            // Attack
            StartFire( Player )
        }
       
        // Holster animation
        UTIL_PlayWeaponAnimation( Player, gauss_holster )
       
        // Reset attack status
        g_bInAttack[ Player ] = 0
    }
}
 
// Add Gauss to players inventory
public fw_TCannonAddToPlayer( iEnt, Player )
{
    // Prevent run-time errors
    if( is_valid_ent( iEnt ) && is_user_valid_connected( Player ) )
    {
        // Seems that player has picked up a gauss
        if( pev( iEnt, pev_weaponkey ) == GAUSS_WEAPONKEY )
        {
            // Update variable
            g_iHasGauss[ Player ] = true
           
            // Update bp ammo
            cs_set_user_bpammo( Player, CSW_M249, pev( iEnt, pev_bpammo ) )
           
            // Reset weapon options
            set_pev( iEnt, pev_weaponkey, 0 )
            set_pev( iEnt, pev_bpammo, 0 )
           
            return HAM_HANDLED
        }
    }
    return HAM_IGNORED
}
 
// Gauss post frame
public fw_TCannonPostFrame( iEnt )
{
    // Get owner
    static iOwner
    iOwner = get_pdata_cbase(iEnt, m_pPlayer, 4)
   
    if(!is_valid_ent(iEnt) || !is_user_valid_connected(iOwner)) return
   
    // Does this player has gauss?
    if ( g_iHasGauss[ iOwner ] )
    {
        // Reload offset
        static fInReload
        fInReload = get_pdata_int ( iEnt, m_fInReload,4 )
       
        // Next attack time
        static Float:flNextAttack
        flNextAttack = get_pdata_float (iOwner, m_flNextAttack, 5)
       
        // Clip
        static iClip
        iClip = get_pdata_int ( iEnt, m_iClip, 4 )
       
        // Ammo type
        static iAmmoType
        iAmmoType = m_rgAmmo_player_Slot0 + get_pdata_int ( iEnt, m_iPrimaryAmmoType, 4 )
       
        // BP ammo
        static iBpAmmo
        iBpAmmo = get_pdata_int ( iOwner, iAmmoType, 5 )   
       
        // Reloading
        if ( fInReload && flNextAttack <= 0.0 )
        {
            // Calculate the difference
            static j
            j = min ( g_pClip - iClip, iBpAmmo )
           
            // Set new clip
            set_pdata_int ( iEnt, m_iClip, iClip + j, 4 )
           
            // Decrease 'x' bullets from backpack(depending on new clip)
            set_pdata_int( iOwner, iAmmoType, iBpAmmo-j, 5 )
           
            // Not reloding anymore
            set_pdata_int ( iEnt, m_fInReload, 0, 4 )
            fInReload = 0
        }
       
        // Get buttons
        static iButton ; iButton = pev ( iOwner, pev_button)
       
        // Attack/Attack2 buttons and next prim/sec attack time hasnt' come yet
        if( ( iButton & IN_ATTACK2 && get_pdata_float ( iEnt, m_flNextSecondaryAttack, 4 ) <= 0.0)
        || ( iButton & IN_ATTACK && get_pdata_float ( iEnt, m_flNextPrimaryAttack, 4 ) <= 0.0) )
        {
            return
        }
   
        // Reload button / not reloading
        if( iButton & IN_RELOAD && !fInReload )
        {
            // Old clip is more/equal than/to new
            if( iClip >= g_pClip )
            {
                // Remove reload button
                set_pev ( iOwner, pev_button, iButton & ~IN_RELOAD )
               
                // Idle animation
                UTIL_PlayWeaponAnimation ( iOwner, gauss_idle )
               
                // Idle time
                g_flWeaponIdleTime[ iOwner ] = get_gametime( ) + 0.5
            }
            else
            {
                // Out of ammo
                if ( !iBpAmmo )
                    return
                   
                // Reload weapon
                UTIL_WeaponReload ( iOwner, iEnt )
            }
        }
    }
}
 
// Gauss reload post
public fw_TCannonReload_Post( iEnt )
{
    // Get owner
    static Player
    Player = get_pdata_cbase( iEnt, m_pPlayer, 4 )
   
    // Does this player has gauss and is he in a middle of reloading ?
    if ( g_iHasGauss[ Player ] && get_pdata_int( iEnt, m_fInReload, 4 ) )
    {
        // Reload
        UTIL_WeaponReload( Player, iEnt )
    }
}
 
// ------------------------------- Internal Functions ----------------------------------------
 
// Gauss start fire
public StartFire( Player )
{
    // This var holds damage
    static Float:flDamage
   
    // Make vectors
    UTIL_MakeVectors( Player )
   
    // Get gametime
    static Float:flGameTime
    flGameTime = get_gametime( )
   
    // This is maximal possible damage from secondary attack!
    if( flGameTime - g_flStartCharge[ Player ] > GAUSS_CHARGETIME )
    {
        flDamage = g_pDmgSec
    }
    else
    {
        // The longer you hold attack button - the bigger is damage
        flDamage = g_pDmgSec * ( ( flGameTime - g_flStartCharge[ Player ] ) / GAUSS_CHARGETIME )
    }
   
    // Primary attack do less damage
    if( g_bPrimaryFire[ Player ] )
    {
        flDamage = g_pDmgPrim
    }
   
    // Make sure that we are not ending attack
    if( g_bInAttack[ Player ] != 3 )
    {
        // Secondary attack can pop you up in the air.Not primary attack!
        if( !g_bPrimaryFire[ Player ] )
        {
            // Current players velocity
            static Float:flVel[ 3 ], Float:v_forward[ 3 ]
            pev( Player, pev_velocity, flVel )
            global_get( glb_v_forward, v_forward )
           
            // Try to affect only vertical velocity
            VectorMS( flVel, flDamage * 5.0, v_forward, flVel )
           
            // Jump!
            set_pev( Player, pev_velocity, flVel )
        }
    }
   
    // Recoil
    static Float:flRecoil[ 3 ]
    flRecoil[ 0 ] = GAUSS_RECOIL
    set_pev( Player, pev_punchangle, flRecoil )
   
    // Fire animation
    UTIL_PlayWeaponAnimation( Player, gauss_fire2 )
   
    // Fire sound
    static Float:flResult
    flResult = 0.5 + flDamage * ( 1.0 / 400.0 )
   
    if( flResult > 1.0 )
    {
        flResult = 1.0
    }
   
    emit_sound( Player, CHAN_WEAPON, g_szSoundGaussFire, flResult, ATTN_NORM, 0, 85 + random_num( 0, 0x1f ) )
   
    // Get players aimpoint position
    static Float:vecDest[ 3 ]
    global_get( glb_v_forward, vecDest )
   
    // Calculate start position
    static Float:vecSrc[ 3 ]
    UTIL_GetGunPosition( Player, vecSrc )
   
    // Time until aftershock 'static discharge' sound
    g_fflPlayAfterShock[ Player ] = flGameTime + random_float( 0.3, 0.8 )
   
    // Fire!
    Fire( Player, vecSrc, vecDest, flDamage )
}
 
// Fire!
Fire( Player, Float:vecOrigSrc[ ], Float:vecDir[ ], Float:flDamage )
{
    // Start position
    static Float:vecSrc[ 3 ]
    xs_vec_copy( vecOrigSrc, vecSrc )
   
    // Calculate end position
    static Float:vecDest[ 3 ]
    VectorMA( vecSrc, 8192.0, vecDir, vecDest )
   
    // Few trace handles
    static tr, beam_tr
   
    // Max fraction
    static Float:flMaxFrac
    flMaxFrac = 1.0
   
    // Total
    static nTotal
    nTotal = 0
   
    // Does this beam punched the wall ?
    static bool:fHasPunched
    fHasPunched = false
   
    // Does this is first beam
    static bool:fFirstBeam
    fFirstBeam = true
   
    // Max hits
    static nMaxHits
    nMaxHits = 10
   
    // Entity whoch should be ignored
    static pEntToIgnore
   
    // Make sure that beam will'be able to cause damage
    while( flDamage > 10 && nMaxHits > 0 )
    {
        // Decrease hit count
        nMaxHits--
       
        // Draw a trace line
        engfunc( EngFunc_TraceLine, vecSrc, vecDest, DONT_IGNORE_MONSTERS, pEntToIgnore, tr )
       
        // We'll never get outside!
        if( get_tr2( tr, TR_AllSolid ) )
            break
       
        // Get entity which was hit
        static pEntity
        pEntity = Instance( get_tr2( tr, TR_pHit ) )   
       
        // Get vector end position
        static Float:vecEnd[ 3 ]
        get_tr2( tr, TR_vecEndPos, vecEnd )
       
        // Its first beam  
        if( fFirstBeam )
        {
            // Add muzzleflash
            set_pev( Player, pev_effects, pev(Player, pev_effects) | EF_MUZZLEFLASH )
           
            // Its not first anymore
            fFirstBeam = false
           
            // Add
            nTotal += 26
           
            // Draw beam
            engfunc( EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, vecSrc, 0 )
            //message_begin( MSG_BROADCAST, SVC_TEMPENTITY )
            write_byte( TE_BEAMENTPOINT ) // Temp. entity ID
            write_short( Player | 0x1000 ) // Start entity
            engfunc( EngFunc_WriteCoord, vecEnd[ 0 ] ) // End position X
            engfunc( EngFunc_WriteCoord, vecEnd[ 1 ] ) // End position Y
            engfunc( EngFunc_WriteCoord, vecEnd[ 2 ] ) // End position Z
            write_short( g_iBeam ) // Sprite index
            write_byte( 0 ) // Start frame
            write_byte( 1 ) // Frame rate
            write_byte( 1 ) // Life
            write_byte( g_bPrimaryFire[ Player ] ? 16 : 25 ) // Line width
            write_byte( 0 ) // Noise amplitude
            write_byte( 255 )
            write_byte( 128 )
            write_byte( 0 )
            write_byte( 255 ) // Alpha
            write_byte( 0 ) // Scroll speed
            message_end( )
        }
        else
        {
            // Draw beam
            engfunc( EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, vecSrc, 0 )
            write_byte( TE_BEAMPOINTS ) // Temp. entity ID
            engfunc( EngFunc_WriteCoord, vecSrc[ 0 ] ) // Start position X
            engfunc( EngFunc_WriteCoord, vecSrc[ 1 ] ) // Start position Y
            engfunc( EngFunc_WriteCoord, vecSrc[ 2 ] ) // Start position Z
            engfunc( EngFunc_WriteCoord, vecEnd[ 0 ] ) // End position X
            engfunc( EngFunc_WriteCoord, vecEnd[ 1 ] ) // End position Y
            engfunc( EngFunc_WriteCoord, vecEnd[ 2 ] ) // End position Z
            write_short( g_iBeam ) // Sprite index
            write_byte( 0 ) // Start frame
            write_byte( 1 ) // Frame rate
            write_byte( 1 ) // Life
            write_byte( g_bPrimaryFire[ Player ] ? 15 : 25 ) // Line width
            write_byte( 0 ) // Noise amplitude
            write_byte( 255 )
            write_byte( 128 )
            write_byte( 0 )
            write_byte( 255 )
            write_byte( 0 ) // Scroll speed
            message_end( )
        }
       
        // Check if this entity should take any damage
        if( pev( pEntity, pev_takedamage ) != DAMAGE_NO )
        {
            // Check if this is player and zombie
            if( is_user_valid_connected( pEntity ) && ze_is_user_zombie( pEntity ) )
            {
                // Retrieve health
                static iHealth
                iHealth = get_user_health( pEntity )
           
                // We should be alive
                if( iHealth - flDamage >= 1 )
                {
                    // Cause some damage
                    ExecuteHamB( Ham_TakeDamage, pEntity, 0, Player, flDamage, DMG_BULLET | DMG_ALWAYSGIB )
                }
                else
                {
                    // Die
                    g_bKilledByLaser[ pEntity ] = true
                    ExecuteHamB( Ham_Killed, pEntity, Player, 2 )
                    g_bKilledByLaser[ pEntity ] = false
                }
            }
        }
       
        // Check if this entity should reflect our beam
        if( ReflectGauss( pEntity ) )
        {
            static Float:n
           
            // Return normal vector in a spot we hit
            static Float:vecPlaneNormal[ 3 ]
            get_tr2( tr, TR_vecPlaneNormal, vecPlaneNormal )
           
            // Calculate dot product
            n = - xs_vec_dot( vecPlaneNormal, vecDir )
           
            // 60 degrees
            if ( 0 < n < 0.5 )
            {
                static Float:r[ 3 ]
                VectorMA( vecDir, 2.0 * n, vecPlaneNormal, r )
               
                // Get vector end position
                get_tr2( tr, TR_vecEndPos, vecEnd )
               
                // Get trace fraction
                static Float:trflFraction
                get_tr2( tr, TR_flFraction, trflFraction )
               
                // Calculate fraction
                flMaxFrac = flMaxFrac - trflFraction
               
                // Copy vectors
                xs_vec_copy( r, vecDir )
               
                // Make more vector calculations
                VectorMA( vecEnd, 8.0, vecDir, vecSrc )
                VectorMA( vecSrc, 8192.0, vecDir, vecDest )
           
                // Undone!Do radius damage
               
                // Increase
                nTotal += 34
               
                if( n == 0 )
                {
                    // Lose energy
                    n = 0.1
                }
               
                // Calculate new damage
                flDamage = flDamage * ( 1 - n )
            }
            else
            {
                // Add gun shot decal on the world
                FX_GunShotDecal( vecEnd, pEntity )
               
                // Add glowing sprite on the world
                FX_TempSprite( vecEnd, 6, floatround( flDamage / 255.0 ) )
               
                // Increase
                nTotal += 13
               
                // Limit it to one hole punch
                if( fHasPunched )
                    break
               
                // Update  
                fHasPunched = true 
               
                // Try punching through wall if secondary attack (primary is incapable of
                // breaking through)
                if( !g_bPrimaryFire[ Player ] )
                {
                    // Retrieve vector end position
                    get_tr2( tr, TR_vecEndPos, vecEnd )
                   
                    // Modify start origin
                    static Float:vecStart[ 3 ]
                    VectorMA( vecEnd, 8.0, vecDir, vecStart )
                   
                    // Draw another trace line
                    engfunc( EngFunc_TraceLine, vecSrc, vecDest, DONT_IGNORE_MONSTERS, pEntToIgnore, beam_tr )
                   
                    // We'll never get outside
                    if( !get_tr2( beam_tr, TR_AllSolid ) )
                    {
                        // Get end position
                        static Float:vecBeamEndPos[ 3 ]
                        get_tr2( beam_tr, TR_vecEndPos, vecBeamEndPos )
                       
                        // Trace backwards to find exit point
                        engfunc( EngFunc_TraceLine, vecBeamEndPos, vecEnd, DONT_IGNORE_MONSTERS, pEntToIgnore, beam_tr )
                       
                        // Again get end position
                        get_tr2( beam_tr, TR_vecEndPos, vecBeamEndPos )
                       
                        static Float:ns, Float:vecSub[ 3 ]
                       
                        // Subtract vectors
                        xs_vec_sub( vecBeamEndPos, vecEnd, vecSub )
                       
                        // Get vector length
                        ns = xs_vec_len( vecSub )
                       
                        if( ns < flDamage )
                        {
                            // Lose enery
                            if( ns == 0 )
                            {
                                ns = 1.0
                            }
                           
                            // Decrease damage
                            flDamage -= ns
                           
                            // Subtract
                            static Float:vecCalc[ 3 ]
                            VectorSubtract( vecEnd, vecDir, vecCalc )
                           
                            // Absorbtion balls
                            FX_SpriteTrail( vecEnd, vecCalc, BALL_AMOUNT, 15, 3, 25, 25 )
                           
                            // Add gun shot decal on the world
                            FX_GunShotDecal( vecBeamEndPos, pEntity )
                           
                            // And glowing sprite
                            FX_TempSprite( vecBeamEndPos, 6, floatround( flDamage / 255.0 ) )
                           
                            // Subtract
                            VectorSubtract( vecBeamEndPos, vecDir, vecCalc )
                           
                            // Absorbtion balls
                            FX_SpriteTrail( vecEnd, vecCalc, BALL_AMOUNT, 15, 3, 25, 25 )
                           
                            // Increase shit
                            nTotal += 21
                           
                            /*
                            // Calculate radius damage
                            static Float:flRadDmg
                            flRadDmg = flDamage * 1.75
                           
                            // Undone.Do radius damage here!
                            floatradius( flDamage, flRadDmg, vecBeamEndPos )
                            */
                           
                            // Increase
                            nTotal += 53
                           
                            VectorMA( vecBeamEndPos, 8.0, vecDir, vecSub )
                           
                            // Add up vector
                            xs_vec_add( vecBeamEndPos, vecDir, vecSrc )
                        }
                    }
                    else
                    {
                        flDamage = 0.0
                    }
                }
                else
                {
                    // Primary attack
                    if( g_bPrimaryFire [ Player ] )
                    {
                        // Slug doesn't punch through ever with primary
                        // fire, so leave a little glowy bit and make some balls
                        FX_TempSprite( vecEnd, 6, floatround( flDamage / 255.0 ) )
                        FX_SpriteTrail( vecEnd, vecDir, BALL_AMOUNT, 15, 3, 25, 25 )
                    }
                   
                    flDamage = 0.0
                }
            }
        }
        else
        {
            // Add up vector
            xs_vec_add( vecEnd, vecDir, vecSrc )
            pEntToIgnore = pEntity
        }
    }
}              
 
// Register and cache CVARs
public Load_Cvars( )
{
    cvar_oneround = register_cvar( "ze_tcannon_oneround", "0" )
    cvar_dmgprim = register_cvar( "ze_tcannon_dmgprim", "200" )
    cvar_dmgsec = register_cvar( "ze_tcannon_dmgsec", "500" )
    cvar_clip = register_cvar( "ze_tcannon_clip", "100" )
   
    g_pOneRound = get_pcvar_num( cvar_oneround )
    g_pDmgPrim = get_pcvar_float( cvar_dmgprim )
    g_pDmgSec = get_pcvar_float( cvar_dmgsec )
    g_pClip = get_pcvar_num( cvar_clip )
}
 
// Gauss weapon idle
WeaponIdle( Player )
{
    // Get gametime
    static Float:flGameTime
    flGameTime = get_gametime( )
   
    if( g_flWeaponIdleTime[ Player ] > flGameTime )
        return
   
    // Animation sequence variable
    static iAnim
   
    // Animation randomizer
    static Float:flRand
    flRand = random_float( 0.1, 1.0 )
   
    if( flRand <= 0.5 )
    {
        iAnim = gauss_idle
        g_flWeaponIdleTime[ Player ] = flGameTime + random_float( 10.0, 15.0 )
    }
    else if( flRand <= 0.75 )
    {
        iAnim = gauss_idle2
        g_flWeaponIdleTime[ Player ] = flGameTime + random_float( 10.0, 15.0 )
    }
    else
    {
        iAnim = gauss_fidget
        g_flWeaponIdleTime[ Player ] = flGameTime + 3
    }
   
    // Idle
    UTIL_PlayWeaponAnimation( Player, iAnim )
}  
 
// Play weapon animation
UTIL_PlayWeaponAnimation( const Player, const Sequence )
{
    set_pev( Player, pev_weaponanim, Sequence )
   
    message_begin( MSG_ONE_UNRELIABLE, SVC_WEAPONANIM, .player = Player )
    write_byte( Sequence )
    write_byte( pev( Player, pev_body ) )
    message_end( )
}              
 
// Make ScreenFade
UTIL_ScreenFade( Player, Duration, HoldTime, Flags, iRed, iGreen, iBlue, iAlpha )
{
    message_begin( MSG_ONE, gmsgScreenFade, _, Player )
    write_short( Duration )
    write_short( HoldTime )
    write_short( Flags )
    write_byte( iRed )
    write_byte( iGreen )
    write_byte( iBlue )
    write_byte( iAlpha )
    message_end( )
}
 
// Reload gauss
UTIL_WeaponReload( Player, iEnt )
{
    // Modify time until next attack
    set_pdata_float( Player, m_flNextAttack, GAUSS_RELOADTIME+0.5, 5 )
   
    // Reload animation
    UTIL_PlayWeaponAnimation( Player, gauss_spin )
   
    // Enable reload offset
    set_pdata_int( iEnt, m_fInReload, 1, 4 )
   
    // Modify next idle time
    g_flWeaponIdleTime[ Player ] = get_gametime( ) + GAUSS_RELOADTIME + 1.0
}
 
// Drop all primary weapons
UTIL_DropPrimary( Player )
{
    // Get user weapons
    static weapons[ 32 ], num, i, weaponid
    num = 0 // reset passed weapons count (bugfix)
    get_user_weapons( Player, weapons, num )
   
    // Loop through them and drop primaries
    for( i = 0; i < num; i++ )
    {
        // Prevent re-indexing the array
        weaponid = weapons[ i ]
       
        // We definetely are holding primary gun
        if(( (1<<weaponid) & PRIMARY_WEAPONS_BITSUM ) )    
        {
            // Get weapon entity
            static wname[32]
            get_weaponname(weaponid, wname, charsmax(wname))
           
            // Player drops the weapon and looses his bpammo
            engclient_cmd( Player, "drop", wname)
        }
    }
}
 
// Get gun position
UTIL_GetGunPosition( Player, Float:flOrigin[ ] )
{
    static Float:vf_Origin[ 3 ], Float:vf_ViewOfs[ 3 ]
   
    pev( Player, pev_origin, vf_Origin )
    pev( Player, pev_view_ofs, vf_ViewOfs )
   
    xs_vec_add( vf_Origin, vf_ViewOfs, flOrigin )
}
 
// Make vectors
UTIL_MakeVectors ( Player )
{
    static Float:flAngle[ 3 ], Float:flPunchAngle[ 3 ]
 
    pev( Player, pev_v_angle, flAngle )
    pev( Player, pev_punchangle, flPunchAngle )
 
    xs_vec_add( flAngle, flPunchAngle, flAngle )
    engfunc( EngFunc_MakeVectors, flAngle )
}
 
// From HL SDK.
VectorMA( Float:a[ ], Float:flScale, Float:b[ ], Float:c[ ] )
{
    c[ 0 ] = a[ 0 ] + flScale * b[ 0 ]
    c[ 1 ] = a[ 1 ] + flScale * b[ 1 ]
    c[ 2 ] = a[ 2 ] + flScale * b[ 2 ]
}
 
VectorMS( const Float:flSource[ ], const Float:flScale, const Float:flMult[ ], Float:flOutput[ ] )
{
        flOutput[ 0 ] = flSource[ 0 ] - flMult[ 0 ] * flScale
        flOutput[ 1 ] = flSource[ 1 ] - flMult[ 1 ] * flScale
        flOutput[ 2 ] = flSource[ 2 ] - flMult[ 2 ] * flScale
}
 
// Another stuff from HLSDK
Instance( iEnt )
{
    return iEnt == -1 ? 0 : iEnt
}
 
// Does this entity should refect gauss?
ReflectGauss( iEnt )
{
        return IsBSPModel( iEnt ) && pev( iEnt, pev_takedamage ) == DAMAGE_NO
}
 
// Does this entity is BSP model?
IsBSPModel( iEnt )
{
    return pev( iEnt, pev_solid ) == SOLID_BSP || pev( iEnt, pev_movetype ) == MOVETYPE_PUSHSTEP
}
 
// Add gun shot decal on world!
FX_GunShotDecal( Float:flPos[ ], pEntity )
{
    // Draw gunshot
    engfunc( EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, flPos, 0 )
    write_byte( TE_GUNSHOTDECAL ) // Temp.entity ID
    engfunc( EngFunc_WriteCoord, flPos[ 0 ] ) // Position X
    engfunc( EngFunc_WriteCoord, flPos[ 1 ] ) // Position Y
    engfunc( EngFunc_WriteCoord, flPos[ 2 ] ) // Position Z
    write_short( pEntity ) // Which entity to mark?
    write_byte( 43 ) // Decal number
    message_end( )
}
 
// Add glow sprite on world
FX_TempSprite( Float:flPos[ ], iScale, iSize )
{
    engfunc( EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, flPos, 0 )
    write_byte( TE_GLOWSPRITE ) // Temp.entity ID
    engfunc( EngFunc_WriteCoord, flPos[ 0 ] ) // Position X
    engfunc( EngFunc_WriteCoord, flPos[ 1 ] ) // Position Y
    engfunc( EngFunc_WriteCoord, flPos[ 2 ] ) // Position Z
    write_short( g_iBalls ) // Sprite index
    write_byte( iScale ) // Scale
    write_byte( iSize ) // Size
    write_byte( 255 ) // Brightness
    message_end( )
}
 
// Add sprite trail
FX_SpriteTrail( Float:vecStart[ ], Float:vecDest[ ], iCount, iLife, iScale, iVel, iRnd )
{
    message_begin( MSG_BROADCAST, SVC_TEMPENTITY )
    write_byte( TE_SPRITETRAIL ) // Sprite trail
    engfunc( EngFunc_WriteCoord, vecStart[ 0 ] ) // Position X
    engfunc( EngFunc_WriteCoord, vecStart[ 1 ] ) // Position Y
    engfunc( EngFunc_WriteCoord, vecStart[ 2 ] ) // Position Z
    engfunc( EngFunc_WriteCoord, vecDest[ 0 ] ) // Position X
    engfunc( EngFunc_WriteCoord, vecDest[ 1 ] ) // Position Y
    engfunc( EngFunc_WriteCoord, vecDest[ 2 ] ) // Position Z
    write_short( g_iBalls ) // SPrite index
    write_byte( iCount ) // Amount
    write_byte( iLife ) // Life
    write_byte( iScale ) // Scale
    write_byte( iVel ) // Velocity along vector
    write_byte( iRnd ) // Randomness of velocity
    message_end( )
}
can someone make it working in our mod? It worked in 1.0 version
Compile it with latest compiler if got some errors post here..
......Devil Was Here......

czirimbolo
Veteran Member
Veteran Member
Poland
Posts: 598
Joined: 7 years ago
Contact:

#3

Post by czirimbolo » 5 years ago

//// ze_extra_tcannon.sma
//
// C:\Users\macie\Documents\Compiler v1.8.3\scripting\ze_extra_tcannon.sma(218) : warning 233: symbol "client_disconnect" is marked as deprecated: Use client_disconnected() instead.
//
// C:\Users\macie\Documents\Compiler v1.8.3\scripting\ze_extra_tcannon.sma(252) : error 017: undefined symbol "find_ent_by_owner"
// C:\Users\macie\Documents\Compiler v1.8.3\scripting\ze_extra_tcannon.sma(365) : error 017: undefined symbol "find_ent_by_owner"
// C:\Users\macie\Documents\Compiler v1.8.3\scripting\ze_extra_tcannon.sma(368) : error 017: undefined symbol "is_valid_ent"
// C:\Users\macie\Documents\Compiler v1.8.3\scripting\ze_extra_tcannon.sma(403) : error 017: undefined symbol "find_ent_by_owner"
// C:\Users\macie\Documents\Compiler v1.8.3\scripting\ze_extra_tcannon.sma(632) : error 017: undefined symbol "halflife_time"
// C:\Users\macie\Documents\Compiler v1.8.3\scripting\ze_extra_tcannon.sma(698) : warning 213: tag mismatch
// C:\Users\macie\Documents\Compiler v1.8.3\scripting\ze_extra_tcannon.sma(722) : warning 213: tag mismatch
// C:\Users\macie\Documents\Compiler v1.8.3\scripting\ze_extra_tcannon.sma(749) : error 017: undefined symbol "is_valid_ent"
// C:\Users\macie\Documents\Compiler v1.8.3\scripting\ze_extra_tcannon.sma(775) : warning 213: tag mismatch
// C:\Users\macie\Documents\Compiler v1.8.3\scripting\ze_extra_tcannon.sma(777) : error 017: undefined symbol "is_valid_ent"
// C:\Users\macie\Documents\Compiler v1.8.3\scripting\ze_extra_tcannon.sma(788) : warning 213: tag mismatch
// C:\Users\macie\Documents\Compiler v1.8.3\scripting\ze_extra_tcannon.sma(863) : warning 213: tag mismatch
// C:\Users\macie\Documents\Compiler v1.8.3\scripting\ze_extra_tcannon.sma(1362) : warning 213: tag mismatch
//
// 7 Errors.
Image

User avatar
SexY DeviL CJ
Mod Tester
Mod Tester
Posts: 73
Joined: 6 years ago
Contact:

#4

Post by SexY DeviL CJ » 5 years ago

On line number 218 you will find

"client_disconnect" change to
"client_disconnected"

Also go to top and add this

#include <engine>
......Devil Was Here......

czirimbolo
Veteran Member
Veteran Member
Poland
Posts: 598
Joined: 7 years ago
Contact:

#5

Post by czirimbolo » 5 years ago

Ok but can you make it working like before? I can compile this but gun can crash server sometimes. Can you fix this gun like others?
Image

User avatar
SexY DeviL CJ
Mod Tester
Mod Tester
Posts: 73
Joined: 6 years ago
Contact:

#6

Post by SexY DeviL CJ » 5 years ago

czirimbolo wrote: 5 years ago Ok but can you make it working like before? I can compile this but gun can crash server sometimes. Can you fix this gun like others?
Try this first if dont work show me errors
......Devil Was Here......

czirimbolo
Veteran Member
Veteran Member
Poland
Posts: 598
Joined: 7 years ago
Contact:

#7

Post by czirimbolo » 5 years ago

L 09/16/2018 - 23:09:27: [AMXX] Displaying debug trace (plugin "ze_extra_tcannon.amxx", version "1.2")
L 09/16/2018 - 23:09:27: [AMXX] Run time error 4: index out of bounds
L 09/16/2018 - 23:09:27: [AMXX] [0] ze_extra_tcannon.sma::fw_TCannonHolster_Post (line 726)
L 09/16/2018 - 23:09:28: [AMXX] Displaying debug trace (plugin "ze_extra_tcannon.amxx", version "1.2")
L 09/16/2018 - 23:09:28: [AMXX] Run time error 4: index out of bounds
L 09/16/2018 - 23:09:28: [AMXX] [0] ze_extra_tcannon.sma::fw_TCannonReload_Post (line 867)
L 09/16/2018 - 23:09:38: [AMXX] Displaying debug trace (plugin "ze_extra_tcannon.amxx", version "1.2")
L 09/16/2018 - 23:09:38: [AMXX] Run time error 4: index out of bounds

Model doesnt work, I see normal M249 gun. Animation of reloading doesnt work too. Can someone fix this? Its really great gun
Image

User avatar
Mark
VIP
VIP
United States of America
Posts: 283
Joined: 5 years ago
Location: Des Moines/USA
Contact:

#8

Post by Mark » 5 years ago

czirimbolo wrote: 5 years ago L 09/16/2018 - 23:09:27: [AMXX] Displaying debug trace (plugin "ze_extra_tcannon.amxx", version "1.2")
L 09/16/2018 - 23:09:27: [AMXX] Run time error 4: index out of bounds
L 09/16/2018 - 23:09:27: [AMXX] [0] ze_extra_tcannon.sma::fw_TCannonHolster_Post (line 726)
L 09/16/2018 - 23:09:28: [AMXX] Displaying debug trace (plugin "ze_extra_tcannon.amxx", version "1.2")
L 09/16/2018 - 23:09:28: [AMXX] Run time error 4: index out of bounds
L 09/16/2018 - 23:09:28: [AMXX] [0] ze_extra_tcannon.sma::fw_TCannonReload_Post (line 867)
L 09/16/2018 - 23:09:38: [AMXX] Displaying debug trace (plugin "ze_extra_tcannon.amxx", version "1.2")
L 09/16/2018 - 23:09:38: [AMXX] Run time error 4: index out of bounds

Model doesnt work, I see normal M249 gun. Animation of reloading doesnt work too. Can someone fix this? Its really great gun
I’ll look at it soon maybe easy fix

User avatar
Mark
VIP
VIP
United States of America
Posts: 283
Joined: 5 years ago
Location: Des Moines/USA
Contact:

#9

Post by Mark » 5 years ago

cziri[Codebox=amxx wrote:[/Codebox]mbolo post_id=8398 time=1537132567 user_id=89]
L 09/16/2018 - 23:09:27: [AMXX] Displaying debug trace (plugin "ze_extra_tcannon.amxx", version "1.2")
L 09/16/2018 - 23:09:27: [AMXX] Run time error 4: index out of bounds
L 09/16/2018 - 23:09:27: [AMXX] [0] ze_extra_tcannon.sma::fw_TCannonHolster_Post (line 726)
L 09/16/2018 - 23:09:28: [AMXX] Displaying debug trace (plugin "ze_extra_tcannon.amxx", version "1.2")
L 09/16/2018 - 23:09:28: [AMXX] Run time error 4: index out of bounds
L 09/16/2018 - 23:09:28: [AMXX] [0] ze_extra_tcannon.sma::fw_TCannonReload_Post (line 867)
L 09/16/2018 - 23:09:38: [AMXX] Displaying debug trace (plugin "ze_extra_tcannon.amxx", version "1.2")
L 09/16/2018 - 23:09:38: [AMXX] Run time error 4: index out of bounds

Model doesnt work, I see normal M249 gun. Animation of reloading doesnt work too. Can someone fix this? Its really great gun
Try!

Tested on my server and seems to work but im not 100% sure how it does work lol!
  1. #include < zombie_escape >
  2. #include < engine >
  3. #include < cstrike >
  4. #include < csx >
  5. #include < xs >
  6. #include < fun >
  7.  
  8. // Plugin information
  9. #define Plugin  "[ZE] Extra Item: Tau Cannon"
  10. #define Version "1.2"
  11. #define Author  "NiHiLaNTh"
  12.  
  13. // Maxplayers
  14. const MaxPlayers = 32
  15.  
  16. // Weapon models
  17. new const g_szModelGaussP[ ] = "models/p_gauss.mdl"
  18. new const g_szModelGaussV[ ] = "models/v_alt_gauss.mdl"
  19. new const g_szModelGaussW[ ] = "models/w_gauss.mdl"
  20.  
  21. // Weapon sounds
  22. new const g_szSoundGaussFire[ ] = "weapons/gauss2.wav"
  23. new const g_szSoundGaussSpin[ ] = "ambience/pulsemachine.wav"
  24. new const g_szSoundElectro1[ ] = "weapons/electro4.wav"
  25. new const g_szSoundElectro2[ ] = "weapons/electro5.wav"
  26. new const g_szSoundElectro3[ ] = "weapons/electro6.wav"
  27.  
  28. // Some gauss/beam stuff
  29. #define GAUSS_REFIRERATE    0.2 // Primary attack
  30. #define GAUSS_REFIRERATE2   0.1 // Secondary attack(you shouldnt change this!)
  31. #define GAUSS_RECOIL        -2.0 // Only X axis!
  32. #define GAUSS_CHARGETIME    4.0 // From HLSDK
  33. #define GAUSS_RELOADTIME    2.0 // Reload time
  34. #define BEAM_RED        255 // Red amount
  35. #define BEAM_GREEN      128 // Green amount
  36. #define BEAM_BLUE       0 // Blue amount
  37. #define BEAM_ALPHA      255 // Brightness(Alpha)
  38. #define BALL_AMOUNT     8 // How many balls should appear :p
  39.  
  40. // Max. bp ammo amount
  41. new const MAXBPAMMO[] = { -1, 52, -1, 90, 1, 32, 1, 100, 90, 1, 120, 100, 100, 90, 90, 90, 100, 120,
  42.     5, 120, 200, // This is gauss max bp ammo.Change it if you want!
  43. 32, 90, 120, 90, 2, 35, 90, 90, -1, 100 }
  44.  
  45. // Player variables
  46. new g_iHasGauss[ MaxPlayers+1 ] // Whether player has gauss
  47. new g_iSoundState[ MaxPlayers+1 ] // Weapon sound state
  48. new g_bInAttack[ MaxPlayers+1 ] // Current gauss attack state
  49. new g_iCurrentWeapon[ MaxPlayers+1 ] // Current weapon player is holding
  50. new Float:g_flLastShotTime[ MaxPlayers+1 ] // Last shot time
  51. new Float:g_fflPlayAfterShock[ MaxPlayers+1 ] // Play aftershock sound
  52. new Float:g_flWeaponIdleTime[ MaxPlayers+1 ] // Weapon idle time
  53. new Float:g_flNextAmmoBurn[ MaxPlayers+1 ] // Next ammo burn time
  54. new Float:g_flStartCharge[ MaxPlayers+1 ] // Weapon start charge
  55. new Float:g_flAmmoStartCharge[ MaxPlayers+1 ] // Ammo start charge
  56. new bool:g_bIsAlive[ MaxPlayers+1 ] // Whether player is alive
  57. new bool:g_bIsConnected[ MaxPlayers+1 ] // Whether player is connected
  58. new bool:g_bPrimaryFire[ MaxPlayers+1 ] // Does this weapon is using primary attack ?
  59. new bool:g_bKilledByLaser[ MaxPlayers+1 ] // Imma firin mah lazor O.o
  60.  
  61. // CVAR pointers
  62. new cvar_oneround // Whether gun should be only for 1 round
  63. new cvar_dmgprim // Primary attack damage
  64. new cvar_dmgsec // Secondary attack damage
  65. new cvar_clip // Clip amount
  66.  
  67. // Cached CVAR
  68. new g_pOneRound
  69. new Float:g_pDmgPrim
  70. new Float:g_pDmgSec
  71. new g_pClip
  72.  
  73. // Global varibles
  74. new g_iMaxPlayers // Maxplayers
  75. new bool:g_bGameRestart // Detect game restart
  76. new g_iBeam // Beam sprite
  77. new g_iBalls // Balls :p
  78. new g_iGaussID // Item ID
  79. new gmsgScreenFade // Screen fade
  80.  
  81. // CS Offsets
  82. const m_flNextPrimaryAttack = 46
  83. const m_flNextSecondaryAttack = 47
  84. const m_flTimeWeaponIdle = 48
  85. const m_iPrimaryAmmoType = 49
  86. const m_iClip = 51
  87. const m_fInReload = 54
  88. const m_rgAmmo_player_Slot0 = 376
  89.  
  90. // Macro
  91. #define is_user_valid_connected(%1)     ( 1 <= %1 <= g_iMaxPlayers && g_bIsConnected [ %1 ] )
  92. #define is_user_in_water(%1)            ( pev ( %1, pev_waterlevel ) == 3 )
  93. #define VectorSubtract(%1,%2,%3)        ( %3[ 0 ] = %1[ 0 ] - %2[ 0 ], %3[ 1 ] = %1[ 1 ] - %2[ 1 ], %3[ 2 ] = %1[ 2 ] - %2[ 2 ] )
  94. #define VectorAdd(%1,%2,%3)         ( %3[ 0 ] = %1[ 0 ] + %2[ 0 ], %3[ 1 ] = %1[ 1 ] + %2[ 2 ], %3[ 2 ] = %1[ 2 ] + %2[ 2 ] )
  95. #define VectorScale(%1,%2,%3)           ( %3[ 0 ] = %2 * %1[ 0 ], %3[ 1 ] = %2 * %1[ 1 ], %3[ 2 ] = %2 * %1[ 2 ] )
  96. #define VectorLength(%1)                ( floatsqroot ( %1[ 0 ] * %1[ 0 ] + %1[ 1 ] * %1[ 1 ] + %1[ 2 ] * %1[ 2 ] ) )
  97.  
  98. // Hack!Custom fields
  99. #define pev_weaponkey       pev_impulse
  100. #define pev_bpammo      pev_iuser3
  101.  
  102. // Misc stuff
  103. #define FCVAR_FLAGS     ( FCVAR_SERVER | FCVAR_SPONLY | FCVAR_UNLOGGED )
  104. #define GAUSS_WEAPONKEY 42856
  105. #define NULLENT     -1
  106. #define FFADE_IN        0x0000
  107. #define UNIT_SECOND     (1<<12)
  108.  
  109. // Entity classnames
  110. new const g_szClassPlayer[ ] = "player"
  111. new const g_szClassM249[ ] = "weapon_m249"
  112.  
  113. // Primary weapon bitsum
  114. const PRIMARY_WEAPONS_BITSUM = (1<<CSW_SCOUT)|(1<<CSW_XM1014)|(1<<CSW_MAC10)|(1<<CSW_AUG)|(1<<CSW_UMP45)|(1<<CSW_SG550)|(1<<CSW_GALIL)|(1<<CSW_FAMAS)|(1<<CSW_AWP)|(1<<CSW_MP5NAVY)|(1<<CSW_M249)|(1<<CSW_M3)|(1<<CSW_M4A1)|(1<<CSW_TMP)|(1<<CSW_G3SG1)|(1<<CSW_SG552)|(1<<CSW_AK47)|(1<<CSW_P90)
  115.  
  116. // Animation sequnces
  117. enum
  118. {
  119.     gauss_idle,
  120.     gauss_idle2,
  121.     gauss_fidget,
  122.     gauss_spinup,
  123.     gauss_spin,
  124.     gauss_fire,
  125.     gauss_fire2,
  126.     gauss_holster,
  127.     gauss_draw
  128. }
  129.  
  130. // Precache
  131. public plugin_precache( )
  132. {
  133.     // Weapon models
  134.     precache_model( g_szModelGaussP )
  135.     precache_model( g_szModelGaussV )
  136.     precache_model( g_szModelGaussW )
  137.    
  138.     // Sounds
  139.     precache_sound( g_szSoundGaussFire )
  140.     precache_sound( g_szSoundGaussSpin )
  141.     precache_sound( g_szSoundElectro1 )
  142.     precache_sound( g_szSoundElectro2 )
  143.     precache_sound( g_szSoundElectro3 )
  144.     precache_sound( "items/9mmclip1.wav" )
  145.    
  146.     // Sprites
  147.     g_iBeam = precache_model( "sprites/smoke.spr" )
  148.     g_iBalls = precache_model( "sprites/hotglow.spr" )
  149. }
  150.  
  151. // Initialization
  152. public plugin_init( )
  153. {
  154.     // New plugin
  155.     register_plugin( Plugin, Version, Author )
  156.    
  157.     // For Game-Monitor support
  158.     register_cvar( "ze_tcannon_version", Version, FCVAR_FLAGS )
  159.    
  160.     // New extra item
  161.     g_iGaussID = ze_register_item("Tau Cannon", 30, 0)
  162.    
  163.     // Events
  164.     register_event( "CurWeapon", "EV_CurWeapon", "be", "1=1" )
  165.     register_event( "DeathMsg", "EV_DeathMsg", "a" )
  166.     register_event( "HLTV", "EV_RoundStart", "a", "1=0", "2=0" )
  167.     register_event( "TextMsg", "EV_GameRestart", "a", "2=#Game_Commencing", "2=#Game_will_restart_in" )
  168.    
  169.     // FakeMeta forwards
  170.     register_forward( FM_SetModel, "fw_SetModel" )
  171.     register_forward( FM_CmdStart, "fw_CmdStart" )
  172.     register_forward( FM_UpdateClientData, "fw_UpdateClientData_Post", 1 )
  173.     register_forward( FM_PlayerPreThink, "fw_PlayerPreThink" )
  174.    
  175.     // HamSandwich forwards
  176.     RegisterHam( Ham_Spawn, g_szClassPlayer, "fw_PlayerSpawn_Post", 1 )
  177.     RegisterHam( Ham_Item_Deploy, g_szClassM249, "fw_TCannonDeploy_Post", 1 )
  178.     RegisterHam( Ham_Item_Holster, g_szClassM249, "fw_TCannonHolster_Post", 1 )
  179.     RegisterHam( Ham_Item_AddToPlayer, g_szClassM249, "fw_TCannonAddToPlayer" )
  180.     RegisterHam( Ham_Item_PostFrame, g_szClassM249, "fw_TCannonPostFrame" )
  181.     RegisterHam( Ham_Weapon_Reload, g_szClassM249, "fw_TCannonReload_Post", 1 )
  182.    
  183.     // CVARs are in Load_Cvars( ) function!
  184.    
  185.     // Messages
  186.     register_message( get_user_msgid( "DeathMsg" ), "fn_DeathMsg" )
  187.     gmsgScreenFade = get_user_msgid( "ScreenFade" )
  188.    
  189.     // Store maxplayers in a global variable
  190.     g_iMaxPlayers = get_maxplayers( )
  191. }  
  192.  
  193. // Configuration
  194. public plugin_cfg( )
  195. {
  196.     // Cache CVARs
  197.     set_task( 1.5, "Load_Cvars" )
  198. }
  199.  
  200. // ------------------------------- Game Events ----------------------------------------
  201.  
  202. // Client connected
  203. public client_connect( Player )
  204. {
  205.     // Make a lot of updates
  206.     g_iHasGauss[ Player ] = false
  207.     g_bInAttack[ Player ] = 0
  208.     g_fflPlayAfterShock[ Player ] = 0.0
  209.     g_flWeaponIdleTime[ Player ] = 0.0
  210.     g_bPrimaryFire[ Player ] = false
  211.     g_bIsAlive[ Player ] = false
  212.     g_bIsConnected[ Player ] = true
  213. }
  214.  
  215. // Client disconnected
  216. public client_disconnected( Player )
  217. {
  218.     // Only few important updates
  219.     g_bIsAlive[ Player ] = false
  220.     g_bIsConnected[ Player ] = false
  221. }
  222.  
  223. public ze_select_item_pre(id, itemid)
  224. {
  225.     // Return Available and we will block it in Post, So it dosen't affect other plugins
  226.     if (itemid != g_iGaussID)
  227.         return ZE_ITEM_AVAILABLE
  228.    
  229.     // Available for Humans only, So don't show it for zombies
  230.     if (ze_is_user_zombie(id))
  231.         return ZE_ITEM_DONT_SHOW
  232.    
  233.     return ZE_ITEM_AVAILABLE
  234. }
  235.  
  236. public ze_select_item_post(Player, itemid)
  237. {
  238.     if (itemid != g_iGaussID)
  239.         return
  240.  
  241.     // Drop all primary weapons
  242.     UTIL_DropPrimary( Player )
  243.        
  244.     // Update
  245.     g_iHasGauss[ Player ] = true
  246.        
  247.     // Give m249
  248.     give_item( Player, "weapon_m249" )
  249.        
  250.     // Find weapon entity
  251.     new iEnt = find_ent_by_owner( NULLENT, g_szClassM249, Player )
  252.        
  253.     // Apply new clip
  254.     cs_set_weapon_ammo( iEnt, g_pClip )
  255.        
  256.     // Back pack ammo
  257.     cs_set_user_bpammo( Player, CSW_M249, MAXBPAMMO[ 20 ] )
  258. }
  259.  
  260. // Current weapon player is holding
  261. public EV_CurWeapon( Player )
  262. {
  263.     // Not alive
  264.     if( !g_bIsAlive[ Player ] )
  265.         return PLUGIN_CONTINUE
  266.    
  267.     // Update
  268.     g_iCurrentWeapon[ Player ] = read_data( 2 )
  269.    
  270.     return PLUGIN_CONTINUE
  271. }
  272.  
  273. // Someone died
  274. public EV_DeathMsg( )
  275. {
  276.     // Get victim
  277.     static iVictim
  278.     iVictim = read_data( 2 )
  279.    
  280.     // Not connected
  281.     if( !is_user_valid_connected( iVictim ) )
  282.         return
  283.    
  284.     // Update
  285.     g_bIsAlive[ iVictim ] = false
  286.    
  287.     // Check if victim has gauss
  288.     if( g_iHasGauss[ iVictim ] && !is_user_bot( iVictim ) )
  289.     {
  290.         // Force to drop
  291.         engclient_cmd( iVictim, "drop weapon_m249" )
  292.     }
  293. }
  294.  
  295. // Round started
  296. public EV_RoundStart( )
  297. {
  298.     // Restart/One round only
  299.     if( g_bGameRestart || g_pOneRound )
  300.     {
  301.         // Reset array value
  302.         arrayset( g_iHasGauss, false, MaxPlayers+1 )
  303.     }
  304.    
  305.     // Update
  306.     g_bGameRestart = false
  307. }
  308.  
  309. // Game restart
  310. public EV_GameRestart( )
  311. {
  312.     // Update
  313.     g_bGameRestart = true
  314. }
  315.  
  316. // Hook death message
  317. public fn_DeathMsg( Player, Dest, iEntity )
  318. {
  319.     // Get victim
  320.     static iVictim, iKiller
  321.     iKiller = get_msg_arg_int( 1 )
  322.     iVictim = get_msg_arg_int( 2 )
  323.    
  324.     // Not connected
  325.     if( !is_user_valid_connected( iVictim ) || iKiller == iVictim )
  326.         return PLUGIN_CONTINUE
  327.    
  328.     // We were killed by laser
  329.     if ( g_bKilledByLaser[ iVictim ] )
  330.     {
  331.         // Replace name in console
  332.         set_msg_arg_string ( 4, "tau cannon" )
  333.     }
  334.     return PLUGIN_CONTINUE
  335. }
  336.  
  337. // ------------------------------- Forwards ----------------------------------------
  338.  
  339. // Replace world model
  340. public fw_SetModel ( Entity, const Model [ ] )
  341. {
  342.     // Prevent invalid entity messages
  343.     if( !pev_valid( Entity ) )
  344.         return FMRES_IGNORED
  345.    
  346.     // Not w_awp.mdl
  347.     if( !equal( Model, "models/w_m249.mdl" ) )
  348.         return FMRES_IGNORED
  349.    
  350.     // Get entity classname
  351.     static szClassname[ 32 ]
  352.     pev( Entity, pev_classname, szClassname, charsmax( szClassname ) )
  353.    
  354.     // Not weaponbox
  355.     if( !equal( szClassname, "weaponbox" ) )
  356.         return FMRES_IGNORED
  357.    
  358.     // Get owner
  359.     static iOwner
  360.     iOwner = pev( Entity, pev_owner )
  361.    
  362.     // Get awp ID
  363.     static iWeaponID
  364.     iWeaponID = find_ent_by_owner( NULLENT, g_szClassM249, Entity )
  365.    
  366.     // Make sure that we have gauss
  367.     if( g_iHasGauss [ iOwner ] && is_valid_ent( iWeaponID ) )
  368.     {
  369.         // Hack! Store weaponkey
  370.         set_pev( iWeaponID, pev_weaponkey, GAUSS_WEAPONKEY )
  371.        
  372.         // Hack! Store bp ammo
  373.         set_pev( iWeaponID, pev_bpammo, cs_get_user_bpammo( iOwner, CSW_M249 ) )
  374.        
  375.         // Update
  376.         g_iHasGauss[ iOwner ] = false
  377.        
  378.         // Replace models
  379.         engfunc( EngFunc_SetModel, Entity, g_szModelGaussW )
  380.         return FMRES_SUPERCEDE
  381.     }
  382.     return FMRES_IGNORED
  383. }
  384.  
  385. // Command start
  386. public fw_CmdStart( Player, UC_Handle, Seed )
  387. {
  388.     // Not alive/dont have gauss/not m249
  389.     if( !g_bIsAlive[ Player ] || !g_iHasGauss[ Player ] || g_iCurrentWeapon[ Player ] != CSW_M249 )
  390.         return FMRES_IGNORED
  391.    
  392.     // Retrieve pressed button bitsum
  393.     static iButtons
  394.     iButtons = get_uc( UC_Handle, UC_Buttons )
  395.    
  396.     // Retrieve game time
  397.     static Float:flGameTime
  398.     flGameTime = get_gametime( )
  399.    
  400.     // Retrieve weapon entity
  401.     static iEnt
  402.     iEnt = find_ent_by_owner( NULLENT, g_szClassM249, Player )
  403.    
  404.     // Retrieve clip amount
  405.     static iClip
  406.     iClip = cs_get_weapon_ammo( iEnt )
  407.    
  408.     // Primary attack
  409.     if( iButtons & IN_ATTACK )
  410.     {
  411.         // Remove attack buttons from their button mask
  412.         iButtons &= ~IN_ATTACK
  413.         set_uc( UC_Handle, UC_Buttons, iButtons )
  414.        
  415.         // Prevent too fast shooting
  416.         if( flGameTime - g_flLastShotTime[ Player ] < GAUSS_REFIRERATE )
  417.             return FMRES_IGNORED
  418.        
  419.         // Dont fire while reloading
  420.         if( get_pdata_int( iEnt, m_fInReload, 4 ) )
  421.             return FMRES_IGNORED
  422.        
  423.         // Not enough clip/under water
  424.         if( iClip < 2 || is_user_in_water( Player ) )
  425.         {
  426.             // Emit empty sound
  427.             ExecuteHamB( Ham_Weapon_PlayEmptySound, iEnt )
  428.             return FMRES_IGNORED
  429.         }
  430.        
  431.         // Update
  432.         g_bPrimaryFire[ Player ] = true
  433.        
  434.         // Start to fire
  435.         StartFire( Player )
  436.        
  437.         // Decrease clip
  438.         cs_set_weapon_ammo( iEnt, iClip-2 )
  439.        
  440.         // Reset weapon attack status
  441.         g_bInAttack[ Player ] = 0
  442.        
  443.         // Set time when idle animation should be played
  444.         g_flWeaponIdleTime[ Player ] = flGameTime + 1.0
  445.        
  446.         // Remember last shot time
  447.         g_flLastShotTime[ Player ] = flGameTime
  448.     }
  449.     // Secondary attack
  450.     else if( iButtons & IN_ATTACK2 )
  451.     {
  452.         // Prevent too fast shooting
  453.         if( flGameTime - g_flLastShotTime[ Player ] < GAUSS_REFIRERATE2 )
  454.             return FMRES_IGNORED
  455.        
  456.         // Dont fire while reloading
  457.         if( get_pdata_int( iEnt, m_fInReload, 4 ) )
  458.             return FMRES_IGNORED
  459.        
  460.         // Are we swimming ?
  461.         if( is_user_in_water( Player ) )
  462.         {
  463.             // We are in a middle of attack
  464.             if( g_bInAttack[ Player ] != 0 )
  465.             {
  466.                 // Stop attack
  467.                 emit_sound( Player, CHAN_WEAPON, g_szSoundElectro1, VOL_NORM, ATTN_NORM, 0, 80 + random_num( 0, 0x3f ) )
  468.                
  469.                 // Gun idle
  470.                 UTIL_PlayWeaponAnimation( Player, gauss_idle )
  471.                 return FMRES_IGNORED
  472.             }
  473.             else
  474.             {
  475.                 // Empty sound
  476.                 ExecuteHamB( Ham_Weapon_PlayEmptySound, iEnt )
  477.                 return FMRES_IGNORED
  478.             }
  479.         }
  480.        
  481.         // Get player oldbuttons
  482.         static iOldButtons
  483.         iOldButtons = pev( Player, pev_oldbuttons )
  484.        
  485.         // Make sure that we are holding secondary attack button
  486.         if( iOldButtons & IN_ATTACK2 )
  487.         {
  488.             // Which attack state do we have
  489.             switch ( g_bInAttack[ Player ] )
  490.             {
  491.                 case 0: // Attack start
  492.                 {
  493.                     // Out of ammo
  494.                     if ( iClip <= 0 )
  495.                     {
  496.                         ExecuteHamB( Ham_Weapon_PlayEmptySound, iEnt )
  497.                         return FMRES_IGNORED
  498.                     }
  499.                    
  500.                     // We aren't using primary attack anymore
  501.                     g_bPrimaryFire[ Player ] = false
  502.                    
  503.                     // Decrease clip
  504.                     cs_set_weapon_ammo( iEnt, --iClip )
  505.                    
  506.                     // Update
  507.                     g_flNextAmmoBurn[ Player ] = flGameTime
  508.                    
  509.                     // Send spinup animation
  510.                     UTIL_PlayWeaponAnimation( Player, gauss_spinup )
  511.                    
  512.                     // Update attack state
  513.                     g_bInAttack[ Player ] = 1
  514.                    
  515.                     // Next idle time
  516.                     g_flWeaponIdleTime[ Player ] = flGameTime + 0.5
  517.                    
  518.                     // Update
  519.                     g_flStartCharge[ Player ] = flGameTime
  520.                     g_flAmmoStartCharge[ Player ] = flGameTime + GAUSS_CHARGETIME
  521.                    
  522.                     // Update sound state
  523.                     g_iSoundState[ Player ] = 0
  524.                    
  525.                     // Spin sound
  526.                     emit_sound( Player, CHAN_WEAPON, g_szSoundGaussSpin, VOL_NORM, ATTN_NORM, g_iSoundState[Player ], 110 )
  527.                    
  528.                     // Change sound state
  529.                     g_iSoundState[ Player ] = SND_CHANGE_PITCH
  530.                 }
  531.                 case 1: // In a middle of attack
  532.                 {
  533.                     if( g_flWeaponIdleTime[ Player ] < flGameTime )
  534.                     {
  535.                         // Spin anim
  536.                         UTIL_PlayWeaponAnimation( Player, gauss_spin )
  537.                        
  538.                         // Update state
  539.                         g_bInAttack[ Player ] = 2
  540.                     }
  541.                 }
  542.                 default: // End of attack
  543.                 {
  544.                     // During the charging process, eat one bit of ammo every once in a while
  545.                     if( flGameTime >= g_flNextAmmoBurn[ Player ] && g_flNextAmmoBurn[ Player ] != 1000 )
  546.                     {
  547.                         // Decrease clip
  548.                         cs_set_weapon_ammo( iEnt, --iClip )
  549.                        
  550.                         // Next time when ammo should be decreased
  551.                         g_flNextAmmoBurn[ Player ] = flGameTime + 0.1
  552.                     }
  553.                    
  554.                     // Shit!We run out of ammo
  555.                     if( iClip <= 0 )
  556.                     {
  557.                         // Force gun to fire
  558.                         StartFire( Player )
  559.                        
  560.                         // Reset weapon state
  561.                         g_bInAttack[ Player ] = 0
  562.                        
  563.                         // Set next idle time
  564.                         g_flWeaponIdleTime[ Player ] = flGameTime + 1.0
  565.                     }
  566.                    
  567.                     // Gun is fully charged up
  568.                     if( flGameTime >= g_flAmmoStartCharge[ Player ] )
  569.                     {
  570.                         // Dont eat any more ammo!
  571.                         g_flNextAmmoBurn[ Player ] = 1000.0
  572.                     }
  573.                    
  574.                     // Calculate pitch
  575.                     static Float:flPitch
  576.                     flPitch = ( flGameTime - g_flStartCharge[ Player ] ) * ( 150 / GAUSS_CHARGETIME ) + 100
  577.                    
  578.                     // Pitch shouldnt be THAT big
  579.                     if ( flPitch > 250 )
  580.                     {
  581.                         flPitch = 250.0
  582.                     }
  583.                    
  584.                     // Spin sound
  585.                     emit_sound( Player, CHAN_WEAPON, g_szSoundGaussSpin, VOL_NORM, ATTN_NORM, ( g_iSoundState[ Player ] == SND_CHANGE_PITCH ) ? 1 : 0, floatround( flPitch ) )
  586.                    
  587.                     // Hack for going through level transitions
  588.                     g_iSoundState[ Player ] = SND_CHANGE_PITCH
  589.                    
  590.                     // We are charing way too long!
  591.                     if( g_flStartCharge[ Player ] < flGameTime - 10 )
  592.                     {
  593.                         // ZAP!
  594.                         emit_sound( Player, CHAN_WEAPON, g_szSoundElectro1, VOL_NORM, ATTN_NORM, 0, 80 + random_num( 0, 0x3f ) )
  595.                         emit_sound( Player, CHAN_VOICE, g_szSoundElectro3, VOL_NORM, ATTN_NORM, 0, 80 + random_num( 0, 0x3f ) )
  596.                        
  597.                         // Reset fire state
  598.                         g_bInAttack[ Player ] = 0
  599.                        
  600.                         // Next idle time
  601.                         g_flWeaponIdleTime[ Player ] = flGameTime + 1.0
  602.                        
  603.                         // Damage player
  604.                         ExecuteHamB( Ham_TakeDamage, Player, 0, Player, 50.0, DMG_SHOCK )
  605.                        
  606.                         // Make screen fade
  607.                         UTIL_ScreenFade( Player, UNIT_SECOND*2, UNIT_SECOND/2, FFADE_IN, 255, 128, 0, 128 )
  608.                        
  609.                         // Idle animation
  610.                         UTIL_PlayWeaponAnimation( Player, gauss_idle )
  611.                     }
  612.                 }
  613.             }
  614.            
  615.             // Update
  616.             g_flLastShotTime[ Player ] = flGameTime
  617.         }
  618.     }
  619.    
  620.     return FMRES_HANDLED
  621. }
  622.  
  623. // Update client data post
  624. public fw_UpdateClientData_Post ( Player, SendWeapons, CD_Handle )
  625. {
  626.     // Not alive / dont have gauss/ not m249
  627.     if ( !g_bIsAlive [ Player ] || !g_iHasGauss [ Player ] || g_iCurrentWeapon [ Player ] != CSW_M249 )
  628.         return FMRES_IGNORED
  629.    
  630.     // Block default sounds/animations
  631.     set_cd ( CD_Handle, CD_flNextAttack, halflife_time ( ) + 0.001 )
  632.     return FMRES_HANDLED
  633. }
  634.  
  635. // Player pre think
  636. public fw_PlayerPreThink( Player )
  637. {
  638.     // Not alive / dont have gauss/ not m249
  639.     if ( !g_bIsAlive [ Player ] || !g_iHasGauss [ Player ] || g_iCurrentWeapon [ Player ] != CSW_M249 )
  640.         return
  641.    
  642.     // Play aftershock discharge
  643.     if( g_fflPlayAfterShock[ Player ] && g_fflPlayAfterShock[ Player ] < get_gametime( ) )
  644.     {
  645.         // Randomly play sound
  646.         switch( random_num(0, 3 ) )
  647.         {
  648.             case 0: emit_sound( Player, CHAN_WEAPON, g_szSoundElectro1,random_float( 0.7, 0.8 ), ATTN_NORM, 0, PITCH_NORM )
  649.                 case 1: emit_sound( Player, CHAN_WEAPON, g_szSoundElectro2,random_float( 0.7, 0.8 ), ATTN_NORM, 0, PITCH_NORM )
  650.                 case 2: emit_sound( Player, CHAN_WEAPON, g_szSoundElectro3,random_float( 0.7, 0.8 ), ATTN_NORM, 0, PITCH_NORM )
  651.                 case 3: return // No sound
  652.             }
  653.        
  654.         // Reset discharge
  655.         g_fflPlayAfterShock[ Player ] = 0.0
  656.     }
  657.    
  658.     // Check if we are in a middle of attack
  659.     if( g_bInAttack[ Player ] != 0 )
  660.     {
  661.         // Check if have released attack2 button
  662.         if( get_gametime( ) - g_flLastShotTime[ Player ] > 0.2 )
  663.         {
  664.             // Start to fire
  665.             StartFire( Player )
  666.            
  667.             // Reset attack state
  668.             g_bInAttack[ Player ] = 0
  669.            
  670.             // Next idle time
  671.             g_flWeaponIdleTime[ Player ] = get_gametime( ) + 2.0
  672.         }
  673.     }
  674.     else
  675.     {
  676.         // Force to idle
  677.         WeaponIdle( Player )
  678.     }
  679. }
  680.  
  681. // Player respawned
  682. public fw_PlayerSpawn_Post( Player )
  683. {
  684.     // Not alive
  685.     if( !is_user_alive( Player ) )
  686.         return
  687.    
  688.     // Update
  689.     g_bIsAlive[ Player ] = true
  690. }
  691.  
  692. // Guass deploy
  693. public fw_TCannonDeploy_Post( iEnt )
  694. {
  695.     // Get owner
  696.     static Player
  697.     Player = get_pdata_cbase( iEnt, 41, 4 )
  698.    
  699.     if(!is_user_valid_connected(Player) || !(get_user_weapon(Player) & CSW_M249))   return
  700.    
  701.     // Does this player has gauss?
  702.     if ( g_iHasGauss[ Player ] )
  703.     {
  704.         // Replace models
  705.         set_pev( Player, pev_viewmodel2, g_szModelGaussV )
  706.         set_pev( Player, pev_weaponmodel2, g_szModelGaussP )
  707.        
  708.         // Deploy animation
  709.         UTIL_PlayWeaponAnimation( Player, gauss_draw )
  710.        
  711.         // Reset aftershock
  712.         g_fflPlayAfterShock[ Player ] = 0.0
  713.     }
  714. }
  715.  
  716. // Gauss holster
  717. public fw_TCannonHolster_Post( iEnt )
  718. {
  719.     // Get owner
  720.     static Player
  721.     Player = get_pdata_cbase( iEnt, 41, 4 )
  722.    
  723.     // Does this player has gauss?
  724.     if ( g_iHasGauss[ Player ] )
  725.     {
  726.         // Check if player is still attacking
  727.         if( g_bInAttack[ Player ] )
  728.         {
  729.             // Bug!Bug!Stop spin sound
  730.             emit_sound( Player, CHAN_WEAPON, g_szSoundGaussSpin, 0.0, 0.0, SND_STOP, 0 )
  731.            
  732.             // Attack
  733.             StartFire( Player )
  734.         }
  735.        
  736.         // Holster animation
  737.         UTIL_PlayWeaponAnimation( Player, gauss_holster )
  738.        
  739.         // Reset attack status
  740.         g_bInAttack[ Player ] = 0
  741.     }
  742. }
  743.  
  744. // Add Gauss to players inventory
  745. public fw_TCannonAddToPlayer( iEnt, Player )
  746. {
  747.     // Prevent run-time errors
  748.     if( is_valid_ent( iEnt ) && is_user_valid_connected( Player ) )
  749.     {
  750.         // Seems that player has picked up a gauss
  751.         if( pev( iEnt, pev_weaponkey ) == GAUSS_WEAPONKEY )
  752.         {
  753.             // Update variable
  754.             g_iHasGauss[ Player ] = true
  755.            
  756.             // Update bp ammo
  757.             cs_set_user_bpammo( Player, CSW_M249, pev( iEnt, pev_bpammo ) )
  758.            
  759.             // Reset weapon options
  760.             set_pev( iEnt, pev_weaponkey, 0 )
  761.             set_pev( iEnt, pev_bpammo, 0 )
  762.            
  763.             return HAM_HANDLED
  764.         }
  765.     }
  766.     return HAM_IGNORED
  767. }
  768.  
  769. // Gauss post frame
  770. public fw_TCannonPostFrame( iEnt )
  771. {
  772.     // Get owner
  773.     static iOwner
  774.     iOwner = get_pdata_cbase(iEnt, 41, 4)
  775.    
  776.     if(!is_valid_ent(iEnt) || !is_user_valid_connected(iOwner)) return
  777.    
  778.     // Does this player has gauss?
  779.     if ( g_iHasGauss[ iOwner ] )
  780.     {
  781.         // Reload offset
  782.         static fInReload
  783.         fInReload = get_pdata_int ( iEnt, m_fInReload,4 )
  784.        
  785.         // Next attack time
  786.         static Float:flNextAttack
  787.         flNextAttack = get_pdata_float (iOwner, 83, 5)
  788.        
  789.         // Clip
  790.         static iClip
  791.         iClip = get_pdata_int ( iEnt, m_iClip, 4 )
  792.        
  793.         // Ammo type
  794.         static iAmmoType
  795.         iAmmoType = m_rgAmmo_player_Slot0 + get_pdata_int ( iEnt, m_iPrimaryAmmoType, 4 )
  796.        
  797.         // BP ammo
  798.         static iBpAmmo
  799.         iBpAmmo = get_pdata_int ( iOwner, iAmmoType, 5 )  
  800.        
  801.         // Reloading
  802.         if ( fInReload && flNextAttack <= 0.0 )
  803.         {
  804.             // Calculate the difference
  805.             static j
  806.             j = min ( g_pClip - iClip, iBpAmmo )
  807.            
  808.             // Set new clip
  809.             set_pdata_int ( iEnt, m_iClip, iClip + j, 4 )
  810.            
  811.             // Decrease 'x' bullets from backpack(depending on new clip)
  812.             set_pdata_int( iOwner, iAmmoType, iBpAmmo-j, 5 )
  813.            
  814.             // Not reloding anymore
  815.             set_pdata_int ( iEnt, m_fInReload, 0, 4 )
  816.             fInReload = 0
  817.         }
  818.        
  819.         // Get buttons
  820.         static iButton ; iButton = pev ( iOwner, pev_button)
  821.        
  822.         // Attack/Attack2 buttons and next prim/sec attack time hasnt' come yet
  823.         if( ( iButton & IN_ATTACK2 && get_pdata_float ( iEnt, m_flNextSecondaryAttack, 4 ) <= 0.0)
  824.         || ( iButton & IN_ATTACK && get_pdata_float ( iEnt, m_flNextPrimaryAttack, 4 ) <= 0.0) )
  825.         {
  826.             return
  827.         }
  828.    
  829.         // Reload button / not reloading
  830.         if( iButton & IN_RELOAD && !fInReload )
  831.         {
  832.             // Old clip is more/equal than/to new
  833.             if( iClip >= g_pClip )
  834.             {
  835.                 // Remove reload button
  836.                 set_pev ( iOwner, pev_button, iButton & ~IN_RELOAD )
  837.                
  838.                 // Idle animation
  839.                 UTIL_PlayWeaponAnimation ( iOwner, gauss_idle )
  840.                
  841.                 // Idle time
  842.                 g_flWeaponIdleTime[ iOwner ] = get_gametime( ) + 0.5
  843.             }
  844.             else
  845.             {
  846.                 // Out of ammo
  847.                 if ( !iBpAmmo )
  848.                     return
  849.                    
  850.                 // Reload weapon
  851.                 UTIL_WeaponReload ( iOwner, iEnt )
  852.             }
  853.         }
  854.     }
  855. }
  856.  
  857. // Gauss reload post
  858. public fw_TCannonReload_Post( iEnt )
  859. {
  860.     // Get owner
  861.     static Player
  862.     Player = get_pdata_cbase( iEnt, 41, 4 )
  863.    
  864.     // Does this player has gauss and is he in a middle of reloading ?
  865.     if ( g_iHasGauss[ Player ] && get_pdata_int( iEnt, m_fInReload, 4 ) )
  866.     {
  867.         // Reload
  868.         UTIL_WeaponReload( Player, iEnt )
  869.     }
  870. }
  871.  
  872. // ------------------------------- Internal Functions ----------------------------------------
  873.  
  874. // Gauss start fire
  875. public StartFire( Player )
  876. {
  877.     // This var holds damage
  878.     static Float:flDamage
  879.    
  880.     // Make vectors
  881.     UTIL_MakeVectors( Player )
  882.    
  883.     // Get gametime
  884.     static Float:flGameTime
  885.     flGameTime = get_gametime( )
  886.    
  887.     // This is maximal possible damage from secondary attack!
  888.     if( flGameTime - g_flStartCharge[ Player ] > GAUSS_CHARGETIME )
  889.     {
  890.         flDamage = g_pDmgSec
  891.     }
  892.     else
  893.     {
  894.         // The longer you hold attack button - the bigger is damage
  895.         flDamage = g_pDmgSec * ( ( flGameTime - g_flStartCharge[ Player ] ) / GAUSS_CHARGETIME )
  896.     }
  897.    
  898.     // Primary attack do less damage
  899.     if( g_bPrimaryFire[ Player ] )
  900.     {
  901.         flDamage = g_pDmgPrim
  902.     }
  903.    
  904.     // Make sure that we are not ending attack
  905.     if( g_bInAttack[ Player ] != 3 )
  906.     {
  907.         // Secondary attack can pop you up in the air.Not primary attack!
  908.         if( !g_bPrimaryFire[ Player ] )
  909.         {
  910.             // Current players velocity
  911.             static Float:flVel[ 3 ], Float:v_forward[ 3 ]
  912.             pev( Player, pev_velocity, flVel )
  913.             global_get( glb_v_forward, v_forward )
  914.            
  915.             // Try to affect only vertical velocity
  916.             VectorMS( flVel, flDamage * 5.0, v_forward, flVel )
  917.            
  918.             // Jump!
  919.             set_pev( Player, pev_velocity, flVel )
  920.         }
  921.     }
  922.    
  923.     // Recoil
  924.     static Float:flRecoil[ 3 ]
  925.     flRecoil[ 0 ] = GAUSS_RECOIL
  926.     set_pev( Player, pev_punchangle, flRecoil )
  927.    
  928.     // Fire animation
  929.     UTIL_PlayWeaponAnimation( Player, gauss_fire2 )
  930.    
  931.     // Fire sound
  932.     static Float:flResult
  933.     flResult = 0.5 + flDamage * ( 1.0 / 400.0 )
  934.    
  935.     if( flResult > 1.0 )
  936.     {
  937.         flResult = 1.0
  938.     }
  939.    
  940.     emit_sound( Player, CHAN_WEAPON, g_szSoundGaussFire, flResult, ATTN_NORM, 0, 85 + random_num( 0, 0x1f ) )
  941.    
  942.     // Get players aimpoint position
  943.     static Float:vecDest[ 3 ]
  944.     global_get( glb_v_forward, vecDest )
  945.    
  946.     // Calculate start position
  947.     static Float:vecSrc[ 3 ]
  948.     UTIL_GetGunPosition( Player, vecSrc )
  949.    
  950.     // Time until aftershock 'static discharge' sound
  951.     g_fflPlayAfterShock[ Player ] = flGameTime + random_float( 0.3, 0.8 )
  952.    
  953.     // Fire!
  954.     Fire( Player, vecSrc, vecDest, flDamage )
  955. }
  956.  
  957. // Fire!
  958. Fire( Player, Float:vecOrigSrc[ ], Float:vecDir[ ], Float:flDamage )
  959. {
  960.     // Start position
  961.     static Float:vecSrc[ 3 ]
  962.     xs_vec_copy( vecOrigSrc, vecSrc )
  963.    
  964.     // Calculate end position
  965.     static Float:vecDest[ 3 ]
  966.     VectorMA( vecSrc, 8192.0, vecDir, vecDest )
  967.    
  968.     // Few trace handles
  969.     static tr, beam_tr
  970.    
  971.     // Max fraction
  972.     static Float:flMaxFrac
  973.     flMaxFrac = 1.0
  974.    
  975.     // Total
  976.     static nTotal
  977.     nTotal = 0
  978.    
  979.     // Does this beam punched the wall ?
  980.     static bool:fHasPunched
  981.     fHasPunched = false
  982.    
  983.     // Does this is first beam
  984.     static bool:fFirstBeam
  985.     fFirstBeam = true
  986.    
  987.     // Max hits
  988.     static nMaxHits
  989.     nMaxHits = 10
  990.    
  991.     // Entity whoch should be ignored
  992.     static pEntToIgnore
  993.    
  994.     // Make sure that beam will'be able to cause damage
  995.     while( flDamage > 10 && nMaxHits > 0 )
  996.     {
  997.         // Decrease hit count
  998.         nMaxHits--
  999.        
  1000.         // Draw a trace line
  1001.         engfunc( EngFunc_TraceLine, vecSrc, vecDest, DONT_IGNORE_MONSTERS, pEntToIgnore, tr )
  1002.        
  1003.         // We'll never get outside!
  1004.         if( get_tr2( tr, TR_AllSolid ) )
  1005.             break
  1006.        
  1007.         // Get entity which was hit
  1008.         static pEntity
  1009.         pEntity = Instance( get_tr2( tr, TR_pHit ) )  
  1010.        
  1011.         // Get vector end position
  1012.         static Float:vecEnd[ 3 ]
  1013.         get_tr2( tr, TR_vecEndPos, vecEnd )
  1014.        
  1015.         // Its first beam  
  1016.         if( fFirstBeam )
  1017.         {
  1018.             // Add muzzleflash
  1019.             set_pev( Player, pev_effects, pev(Player, pev_effects) | EF_MUZZLEFLASH )
  1020.            
  1021.             // Its not first anymore
  1022.             fFirstBeam = false
  1023.            
  1024.             // Add
  1025.             nTotal += 26
  1026.            
  1027.             // Draw beam
  1028.             engfunc( EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, vecSrc, 0 )
  1029.             //message_begin( MSG_BROADCAST, SVC_TEMPENTITY )
  1030.             write_byte( TE_BEAMENTPOINT ) // Temp. entity ID
  1031.             write_short( Player | 0x1000 ) // Start entity
  1032.             engfunc( EngFunc_WriteCoord, vecEnd[ 0 ] ) // End position X
  1033.             engfunc( EngFunc_WriteCoord, vecEnd[ 1 ] ) // End position Y
  1034.             engfunc( EngFunc_WriteCoord, vecEnd[ 2 ] ) // End position Z
  1035.             write_short( g_iBeam ) // Sprite index
  1036.             write_byte( 0 ) // Start frame
  1037.             write_byte( 1 ) // Frame rate
  1038.             write_byte( 1 ) // Life
  1039.             write_byte( g_bPrimaryFire[ Player ] ? 16 : 25 ) // Line width
  1040.             write_byte( 0 ) // Noise amplitude
  1041.             write_byte( 255 )
  1042.             write_byte( 128 )
  1043.             write_byte( 0 )
  1044.             write_byte( 255 ) // Alpha
  1045.             write_byte( 0 ) // Scroll speed
  1046.             message_end( )
  1047.         }
  1048.         else
  1049.         {
  1050.             // Draw beam
  1051.             engfunc( EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, vecSrc, 0 )
  1052.             write_byte( TE_BEAMPOINTS ) // Temp. entity ID
  1053.             engfunc( EngFunc_WriteCoord, vecSrc[ 0 ] ) // Start position X
  1054.             engfunc( EngFunc_WriteCoord, vecSrc[ 1 ] ) // Start position Y
  1055.             engfunc( EngFunc_WriteCoord, vecSrc[ 2 ] ) // Start position Z
  1056.             engfunc( EngFunc_WriteCoord, vecEnd[ 0 ] ) // End position X
  1057.             engfunc( EngFunc_WriteCoord, vecEnd[ 1 ] ) // End position Y
  1058.             engfunc( EngFunc_WriteCoord, vecEnd[ 2 ] ) // End position Z
  1059.             write_short( g_iBeam ) // Sprite index
  1060.             write_byte( 0 ) // Start frame
  1061.             write_byte( 1 ) // Frame rate
  1062.             write_byte( 1 ) // Life
  1063.             write_byte( g_bPrimaryFire[ Player ] ? 15 : 25 ) // Line width
  1064.             write_byte( 0 ) // Noise amplitude
  1065.             write_byte( 255 )
  1066.             write_byte( 128 )
  1067.             write_byte( 0 )
  1068.             write_byte( 255 )
  1069.             write_byte( 0 ) // Scroll speed
  1070.             message_end( )
  1071.         }
  1072.        
  1073.         // Check if this entity should take any damage
  1074.         if( pev( pEntity, pev_takedamage ) != DAMAGE_NO )
  1075.         {
  1076.             // Check if this is player and zombie
  1077.             if( is_user_valid_connected( pEntity ) && ze_is_user_zombie( pEntity ) )
  1078.             {
  1079.                 // Retrieve health
  1080.                 static iHealth
  1081.                 iHealth = get_user_health( pEntity )
  1082.            
  1083.                 // We should be alive
  1084.                 if( iHealth - flDamage >= 1 )
  1085.                 {
  1086.                     // Cause some damage
  1087.                     ExecuteHamB( Ham_TakeDamage, pEntity, 0, Player, flDamage, DMG_BULLET | DMG_ALWAYSGIB )
  1088.                 }
  1089.                 else
  1090.                 {
  1091.                     // Die
  1092.                     g_bKilledByLaser[ pEntity ] = true
  1093.                     ExecuteHamB( Ham_Killed, pEntity, Player, 2 )
  1094.                     g_bKilledByLaser[ pEntity ] = false
  1095.                 }
  1096.             }
  1097.         }
  1098.        
  1099.         // Check if this entity should reflect our beam
  1100.         if( ReflectGauss( pEntity ) )
  1101.         {
  1102.             static Float:n
  1103.            
  1104.             // Return normal vector in a spot we hit
  1105.             static Float:vecPlaneNormal[ 3 ]
  1106.             get_tr2( tr, TR_vecPlaneNormal, vecPlaneNormal )
  1107.            
  1108.             // Calculate dot product
  1109.             n = - xs_vec_dot( vecPlaneNormal, vecDir )
  1110.            
  1111.             // 60 degrees
  1112.             if ( 0 < n < 0.5 )
  1113.             {
  1114.                 static Float:r[ 3 ]
  1115.                 VectorMA( vecDir, 2.0 * n, vecPlaneNormal, r )
  1116.                
  1117.                 // Get vector end position
  1118.                 get_tr2( tr, TR_vecEndPos, vecEnd )
  1119.                
  1120.                 // Get trace fraction
  1121.                 static Float:trflFraction
  1122.                 get_tr2( tr, TR_flFraction, trflFraction )
  1123.                
  1124.                 // Calculate fraction
  1125.                 flMaxFrac = flMaxFrac - trflFraction
  1126.                
  1127.                 // Copy vectors
  1128.                 xs_vec_copy( r, vecDir )
  1129.                
  1130.                 // Make more vector calculations
  1131.                 VectorMA( vecEnd, 8.0, vecDir, vecSrc )
  1132.                 VectorMA( vecSrc, 8192.0, vecDir, vecDest )
  1133.            
  1134.                 // Undone!Do radius damage
  1135.                
  1136.                 // Increase
  1137.                 nTotal += 34
  1138.                
  1139.                 if( n == 0 )
  1140.                 {
  1141.                     // Lose energy
  1142.                     n = 0.1
  1143.                 }
  1144.                
  1145.                 // Calculate new damage
  1146.                 flDamage = flDamage * ( 1 - n )
  1147.             }
  1148.             else
  1149.             {
  1150.                 // Add gun shot decal on the world
  1151.                 FX_GunShotDecal( vecEnd, pEntity )
  1152.                
  1153.                 // Add glowing sprite on the world
  1154.                 FX_TempSprite( vecEnd, 6, floatround( flDamage / 255.0 ) )
  1155.                
  1156.                 // Increase
  1157.                 nTotal += 13
  1158.                
  1159.                 // Limit it to one hole punch
  1160.                 if( fHasPunched )
  1161.                     break
  1162.                
  1163.                 // Update  
  1164.                 fHasPunched = true
  1165.                
  1166.                 // Try punching through wall if secondary attack (primary is incapable of
  1167.                 // breaking through)
  1168.                 if( !g_bPrimaryFire[ Player ] )
  1169.                 {
  1170.                     // Retrieve vector end position
  1171.                     get_tr2( tr, TR_vecEndPos, vecEnd )
  1172.                    
  1173.                     // Modify start origin
  1174.                     static Float:vecStart[ 3 ]
  1175.                     VectorMA( vecEnd, 8.0, vecDir, vecStart )
  1176.                    
  1177.                     // Draw another trace line
  1178.                     engfunc( EngFunc_TraceLine, vecSrc, vecDest, DONT_IGNORE_MONSTERS, pEntToIgnore, beam_tr )
  1179.                    
  1180.                     // We'll never get outside
  1181.                     if( !get_tr2( beam_tr, TR_AllSolid ) )
  1182.                     {
  1183.                         // Get end position
  1184.                         static Float:vecBeamEndPos[ 3 ]
  1185.                         get_tr2( beam_tr, TR_vecEndPos, vecBeamEndPos )
  1186.                        
  1187.                         // Trace backwards to find exit point
  1188.                         engfunc( EngFunc_TraceLine, vecBeamEndPos, vecEnd, DONT_IGNORE_MONSTERS, pEntToIgnore, beam_tr )
  1189.                        
  1190.                         // Again get end position
  1191.                         get_tr2( beam_tr, TR_vecEndPos, vecBeamEndPos )
  1192.                        
  1193.                         static Float:ns, Float:vecSub[ 3 ]
  1194.                        
  1195.                         // Subtract vectors
  1196.                         xs_vec_sub( vecBeamEndPos, vecEnd, vecSub )
  1197.                        
  1198.                         // Get vector length
  1199.                         ns = xs_vec_len( vecSub )
  1200.                        
  1201.                         if( ns < flDamage )
  1202.                         {
  1203.                             // Lose enery
  1204.                             if( ns == 0 )
  1205.                             {
  1206.                                 ns = 1.0
  1207.                             }
  1208.                            
  1209.                             // Decrease damage
  1210.                             flDamage -= ns
  1211.                            
  1212.                             // Subtract
  1213.                             static Float:vecCalc[ 3 ]
  1214.                             VectorSubtract( vecEnd, vecDir, vecCalc )
  1215.                            
  1216.                             // Absorbtion balls
  1217.                             FX_SpriteTrail( vecEnd, vecCalc, BALL_AMOUNT, 15, 3, 25, 25 )
  1218.                            
  1219.                             // Add gun shot decal on the world
  1220.                             FX_GunShotDecal( vecBeamEndPos, pEntity )
  1221.                            
  1222.                             // And glowing sprite
  1223.                             FX_TempSprite( vecBeamEndPos, 6, floatround( flDamage / 255.0 ) )
  1224.                            
  1225.                             // Subtract
  1226.                             VectorSubtract( vecBeamEndPos, vecDir, vecCalc )
  1227.                            
  1228.                             // Absorbtion balls
  1229.                             FX_SpriteTrail( vecEnd, vecCalc, BALL_AMOUNT, 15, 3, 25, 25 )
  1230.                            
  1231.                             // Increase shit
  1232.                             nTotal += 21
  1233.                            
  1234.                             /*
  1235.                             // Calculate radius damage
  1236.                             static Float:flRadDmg
  1237.                             flRadDmg = flDamage * 1.75
  1238.                            
  1239.                             // Undone.Do radius damage here!
  1240.                             floatradius( flDamage, flRadDmg, vecBeamEndPos )
  1241.                             */
  1242.                            
  1243.                             // Increase
  1244.                             nTotal += 53
  1245.                            
  1246.                             VectorMA( vecBeamEndPos, 8.0, vecDir, vecSub )
  1247.                            
  1248.                             // Add up vector
  1249.                             xs_vec_add( vecBeamEndPos, vecDir, vecSrc )
  1250.                         }
  1251.                     }
  1252.                     else
  1253.                     {
  1254.                         flDamage = 0.0
  1255.                     }
  1256.                 }
  1257.                 else
  1258.                 {
  1259.                     // Primary attack
  1260.                     if( g_bPrimaryFire [ Player ] )
  1261.                     {
  1262.                         // Slug doesn't punch through ever with primary
  1263.                         // fire, so leave a little glowy bit and make some balls
  1264.                         FX_TempSprite( vecEnd, 6, floatround( flDamage / 255.0 ) )
  1265.                         FX_SpriteTrail( vecEnd, vecDir, BALL_AMOUNT, 15, 3, 25, 25 )
  1266.                     }
  1267.                    
  1268.                     flDamage = 0.0
  1269.                 }
  1270.             }
  1271.         }
  1272.         else
  1273.         {
  1274.             // Add up vector
  1275.             xs_vec_add( vecEnd, vecDir, vecSrc )
  1276.             pEntToIgnore = pEntity
  1277.         }
  1278.     }
  1279. }              
  1280.  
  1281. // Register and cache CVARs
  1282. public Load_Cvars( )
  1283. {
  1284.     cvar_oneround = register_cvar( "ze_tcannon_oneround", "0" )
  1285.     cvar_dmgprim = register_cvar( "ze_tcannon_dmgprim", "200" )
  1286.     cvar_dmgsec = register_cvar( "ze_tcannon_dmgsec", "500" )
  1287.     cvar_clip = register_cvar( "ze_tcannon_clip", "100" )
  1288.    
  1289.     g_pOneRound = get_pcvar_num( cvar_oneround )
  1290.     g_pDmgPrim = get_pcvar_float( cvar_dmgprim )
  1291.     g_pDmgSec = get_pcvar_float( cvar_dmgsec )
  1292.     g_pClip = get_pcvar_num( cvar_clip )
  1293. }
  1294.  
  1295. // Gauss weapon idle
  1296. WeaponIdle( Player )
  1297. {
  1298.     // Get gametime
  1299.     static Float:flGameTime
  1300.     flGameTime = get_gametime( )
  1301.    
  1302.     if( g_flWeaponIdleTime[ Player ] > flGameTime )
  1303.         return
  1304.    
  1305.     // Animation sequence variable
  1306.     static iAnim
  1307.    
  1308.     // Animation randomizer
  1309.     static Float:flRand
  1310.     flRand = random_float( 0.1, 1.0 )
  1311.    
  1312.     if( flRand <= 0.5 )
  1313.     {
  1314.         iAnim = gauss_idle
  1315.         g_flWeaponIdleTime[ Player ] = flGameTime + random_float( 10.0, 15.0 )
  1316.     }
  1317.     else if( flRand <= 0.75 )
  1318.     {
  1319.         iAnim = gauss_idle2
  1320.         g_flWeaponIdleTime[ Player ] = flGameTime + random_float( 10.0, 15.0 )
  1321.     }
  1322.     else
  1323.     {
  1324.         iAnim = gauss_fidget
  1325.         g_flWeaponIdleTime[ Player ] = flGameTime + 3
  1326.     }
  1327.    
  1328.     // Idle
  1329.     UTIL_PlayWeaponAnimation( Player, iAnim )
  1330. }  
  1331.  
  1332. // Play weapon animation
  1333. UTIL_PlayWeaponAnimation( const Player, const Sequence )
  1334. {
  1335.     set_pev( Player, pev_weaponanim, Sequence )
  1336.    
  1337.     message_begin( MSG_ONE_UNRELIABLE, SVC_WEAPONANIM, .player = Player )
  1338.     write_byte( Sequence )
  1339.     write_byte( pev( Player, pev_body ) )
  1340.     message_end( )
  1341. }              
  1342.  
  1343. // Make ScreenFade
  1344. UTIL_ScreenFade( Player, Duration, HoldTime, Flags, iRed, iGreen, iBlue, iAlpha )
  1345. {
  1346.     message_begin( MSG_ONE, gmsgScreenFade, _, Player )
  1347.     write_short( Duration )
  1348.     write_short( HoldTime )
  1349.     write_short( Flags )
  1350.     write_byte( iRed )
  1351.     write_byte( iGreen )
  1352.     write_byte( iBlue )
  1353.     write_byte( iAlpha )
  1354.     message_end( )
  1355. }
  1356.  
  1357. // Reload gauss
  1358. UTIL_WeaponReload( Player, iEnt )
  1359. {
  1360.     // Modify time until next attack
  1361.     set_pdata_float( Player, 83, GAUSS_RELOADTIME+0.5, 5 )
  1362.    
  1363.     // Reload animation
  1364.     UTIL_PlayWeaponAnimation( Player, gauss_spin )
  1365.    
  1366.     // Enable reload offset
  1367.     set_pdata_int( iEnt, m_fInReload, 1, 4 )
  1368.    
  1369.     // Modify next idle time
  1370.     g_flWeaponIdleTime[ Player ] = get_gametime( ) + GAUSS_RELOADTIME + 1.0
  1371. }
  1372.  
  1373. // Drop all primary weapons
  1374. UTIL_DropPrimary( Player )
  1375. {
  1376.     // Get user weapons
  1377.     static weapons[ 32 ], num, i, weaponid
  1378.     num = 0 // reset passed weapons count (bugfix)
  1379.     get_user_weapons( Player, weapons, num )
  1380.    
  1381.     // Loop through them and drop primaries
  1382.     for( i = 0; i < num; i++ )
  1383.     {
  1384.         // Prevent re-indexing the array
  1385.         weaponid = weapons[ i ]
  1386.        
  1387.         // We definetely are holding primary gun
  1388.         if(( (1<<weaponid) & PRIMARY_WEAPONS_BITSUM ) )    
  1389.         {
  1390.             // Get weapon entity
  1391.             static wname[32]
  1392.             get_weaponname(weaponid, wname, charsmax(wname))
  1393.            
  1394.             // Player drops the weapon and looses his bpammo
  1395.             engclient_cmd( Player, "drop", wname)
  1396.         }
  1397.     }
  1398. }
  1399.  
  1400. // Get gun position
  1401. UTIL_GetGunPosition( Player, Float:flOrigin[ ] )
  1402. {
  1403.     static Float:vf_Origin[ 3 ], Float:vf_ViewOfs[ 3 ]
  1404.    
  1405.     pev( Player, pev_origin, vf_Origin )
  1406.     pev( Player, pev_view_ofs, vf_ViewOfs )
  1407.    
  1408.     xs_vec_add( vf_Origin, vf_ViewOfs, flOrigin )
  1409. }
  1410.  
  1411. // Make vectors
  1412. UTIL_MakeVectors ( Player )
  1413. {
  1414.     static Float:flAngle[ 3 ], Float:flPunchAngle[ 3 ]
  1415.  
  1416.     pev( Player, pev_v_angle, flAngle )
  1417.     pev( Player, pev_punchangle, flPunchAngle )
  1418.  
  1419.     xs_vec_add( flAngle, flPunchAngle, flAngle )
  1420.     engfunc( EngFunc_MakeVectors, flAngle )
  1421. }
  1422.  
  1423. // From HL SDK.
  1424. VectorMA( Float:a[ ], Float:flScale, Float:b[ ], Float:c[ ] )
  1425. {
  1426.     c[ 0 ] = a[ 0 ] + flScale * b[ 0 ]
  1427.     c[ 1 ] = a[ 1 ] + flScale * b[ 1 ]
  1428.     c[ 2 ] = a[ 2 ] + flScale * b[ 2 ]
  1429. }
  1430.  
  1431. VectorMS( const Float:flSource[ ], const Float:flScale, const Float:flMult[ ], Float:flOutput[ ] )
  1432. {
  1433.         flOutput[ 0 ] = flSource[ 0 ] - flMult[ 0 ] * flScale
  1434.         flOutput[ 1 ] = flSource[ 1 ] - flMult[ 1 ] * flScale
  1435.         flOutput[ 2 ] = flSource[ 2 ] - flMult[ 2 ] * flScale
  1436. }
  1437.  
  1438. // Another stuff from HLSDK
  1439. Instance( iEnt )
  1440. {
  1441.     return iEnt == -1 ? 0 : iEnt
  1442. }
  1443.  
  1444. // Does this entity should refect gauss?
  1445. ReflectGauss( iEnt )
  1446. {
  1447.         return IsBSPModel( iEnt ) && pev( iEnt, pev_takedamage ) == DAMAGE_NO
  1448. }
  1449.  
  1450. // Does this entity is BSP model?
  1451. IsBSPModel( iEnt )
  1452. {
  1453.     return pev( iEnt, pev_solid ) == SOLID_BSP || pev( iEnt, pev_movetype ) == MOVETYPE_PUSHSTEP
  1454. }
  1455.  
  1456. // Add gun shot decal on world!
  1457. FX_GunShotDecal( Float:flPos[ ], pEntity )
  1458. {
  1459.     // Draw gunshot
  1460.     engfunc( EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, flPos, 0 )
  1461.     write_byte( TE_GUNSHOTDECAL ) // Temp.entity ID
  1462.     engfunc( EngFunc_WriteCoord, flPos[ 0 ] ) // Position X
  1463.     engfunc( EngFunc_WriteCoord, flPos[ 1 ] ) // Position Y
  1464.     engfunc( EngFunc_WriteCoord, flPos[ 2 ] ) // Position Z
  1465.     write_short( pEntity ) // Which entity to mark?
  1466.     write_byte( 43 ) // Decal number
  1467.     message_end( )
  1468. }
  1469.  
  1470. // Add glow sprite on world
  1471. FX_TempSprite( Float:flPos[ ], iScale, iSize )
  1472. {
  1473.     engfunc( EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, flPos, 0 )
  1474.     write_byte( TE_GLOWSPRITE ) // Temp.entity ID
  1475.     engfunc( EngFunc_WriteCoord, flPos[ 0 ] ) // Position X
  1476.     engfunc( EngFunc_WriteCoord, flPos[ 1 ] ) // Position Y
  1477.     engfunc( EngFunc_WriteCoord, flPos[ 2 ] ) // Position Z
  1478.     write_short( g_iBalls ) // Sprite index
  1479.     write_byte( iScale ) // Scale
  1480.     write_byte( iSize ) // Size
  1481.     write_byte( 255 ) // Brightness
  1482.     message_end( )
  1483. }
  1484.  
  1485. // Add sprite trail
  1486. FX_SpriteTrail( Float:vecStart[ ], Float:vecDest[ ], iCount, iLife, iScale, iVel, iRnd )
  1487. {
  1488.     message_begin( MSG_BROADCAST, SVC_TEMPENTITY )
  1489.     write_byte( TE_SPRITETRAIL ) // Sprite trail
  1490.     engfunc( EngFunc_WriteCoord, vecStart[ 0 ] ) // Position X
  1491.     engfunc( EngFunc_WriteCoord, vecStart[ 1 ] ) // Position Y
  1492.     engfunc( EngFunc_WriteCoord, vecStart[ 2 ] ) // Position Z
  1493.     engfunc( EngFunc_WriteCoord, vecDest[ 0 ] ) // Position X
  1494.     engfunc( EngFunc_WriteCoord, vecDest[ 1 ] ) // Position Y
  1495.     engfunc( EngFunc_WriteCoord, vecDest[ 2 ] ) // Position Z
  1496.     write_short( g_iBalls ) // SPrite index
  1497.     write_byte( iCount ) // Amount
  1498.     write_byte( iLife ) // Life
  1499.     write_byte( iScale ) // Scale
  1500.     write_byte( iVel ) // Velocity along vector
  1501.     write_byte( iRnd ) // Randomness of velocity
  1502.     message_end( )
  1503. }

czirimbolo
Veteran Member
Veteran Member
Poland
Posts: 598
Joined: 7 years ago
Contact:

#10

Post by czirimbolo » 5 years ago

Thanks Mark its fine! But small thing, I cannot do a damage to entities. Can you add this do the code?
Image

User avatar
Night Fury
Mod Developer
Mod Developer
Posts: 677
Joined: 7 years ago
Contact:

#11

Post by Night Fury » 5 years ago

Try:
  1. #include < zombie_escape >
  2. #include < cstrike >
  3. #include < csx >
  4. #include < xs >
  5. #include < fun >
  6.  
  7. // Plugin information
  8. #define Plugin  "[ZE] Extra Item: Tau Cannon"
  9. #define Version "1.2"
  10. #define Author  "NiHiLaNTh"
  11.  
  12. // Maxplayers
  13. const MaxPlayers = 32
  14.  
  15. // Weapon models
  16. new const g_szModelGaussP[ ] = "models/p_gauss.mdl"
  17. new const g_szModelGaussV[ ] = "models/v_alt_gauss.mdl"
  18. new const g_szModelGaussW[ ] = "models/w_gauss.mdl"
  19.  
  20. // Weapon sounds
  21. new const g_szSoundGaussFire[ ] = "weapons/gauss2.wav"
  22. new const g_szSoundGaussSpin[ ] = "ambience/pulsemachine.wav"
  23. new const g_szSoundElectro1[ ] = "weapons/electro4.wav"
  24. new const g_szSoundElectro2[ ] = "weapons/electro5.wav"
  25. new const g_szSoundElectro3[ ] = "weapons/electro6.wav"
  26.  
  27. // Some gauss/beam stuff
  28. #define GAUSS_REFIRERATE    0.2 // Primary attack
  29. #define GAUSS_REFIRERATE2   0.1 // Secondary attack(you shouldnt change this!)
  30. #define GAUSS_RECOIL        -2.0 // Only X axis!
  31. #define GAUSS_CHARGETIME    4.0 // From HLSDK
  32. #define GAUSS_RELOADTIME    2.0 // Reload time
  33. #define BEAM_RED        255 // Red amount
  34. #define BEAM_GREEN      128 // Green amount
  35. #define BEAM_BLUE       0 // Blue amount
  36. #define BEAM_ALPHA      255 // Brightness(Alpha)
  37. #define BALL_AMOUNT     8 // How many balls should appear :p
  38.  
  39. // Max. bp ammo amount
  40. new const MAXBPAMMO[] = { -1, 52, -1, 90, 1, 32, 1, 100, 90, 1, 120, 100, 100, 90, 90, 90, 100, 120,
  41.     5, 120, 200, // This is gauss max bp ammo.Change it if you want!
  42. 32, 90, 120, 90, 2, 35, 90, 90, -1, 100 }
  43.  
  44. // Player variables
  45. new g_iHasGauss[ MaxPlayers+1 ] // Whether player has gauss
  46. new g_iSoundState[ MaxPlayers+1 ] // Weapon sound state
  47. new g_bInAttack[ MaxPlayers+1 ] // Current gauss attack state
  48. new g_iCurrentWeapon[ MaxPlayers+1 ] // Current weapon player is holding
  49. new Float:g_flLastShotTime[ MaxPlayers+1 ] // Last shot time
  50. new Float:g_fflPlayAfterShock[ MaxPlayers+1 ] // Play aftershock sound
  51. new Float:g_flWeaponIdleTime[ MaxPlayers+1 ] // Weapon idle time
  52. new Float:g_flNextAmmoBurn[ MaxPlayers+1 ] // Next ammo burn time
  53. new Float:g_flStartCharge[ MaxPlayers+1 ] // Weapon start charge
  54. new Float:g_flAmmoStartCharge[ MaxPlayers+1 ] // Ammo start charge
  55. new bool:g_bIsAlive[ MaxPlayers+1 ] // Whether player is alive
  56. new bool:g_bIsConnected[ MaxPlayers+1 ] // Whether player is connected
  57. new bool:g_bPrimaryFire[ MaxPlayers+1 ] // Does this weapon is using primary attack ?
  58. new bool:g_bKilledByLaser[ MaxPlayers+1 ] // Imma firin mah lazor O.o
  59.  
  60. // CVAR pointers
  61. new cvar_oneround // Whether gun should be only for 1 round
  62. new cvar_dmgprim // Primary attack damage
  63. new cvar_dmgsec // Secondary attack damage
  64. new cvar_clip // Clip amount
  65.  
  66. // Cached CVAR
  67. new g_pOneRound
  68. new Float:g_pDmgPrim
  69. new Float:g_pDmgSec
  70. new g_pClip
  71.  
  72. // Global varibles
  73. new g_iMaxPlayers // Maxplayers
  74. new bool:g_bGameRestart // Detect game restart
  75. new g_iBeam // Beam sprite
  76. new g_iBalls // Balls :p
  77. new g_iGaussID // Item ID
  78. new gmsgScreenFade // Screen fade
  79.  
  80. // CS Offsets
  81. const m_pPlayer = 41
  82. const m_flNextPrimaryAttack = 46
  83. const m_flNextSecondaryAttack = 47
  84. const m_flTimeWeaponIdle = 48
  85. const m_iPrimaryAmmoType = 49
  86. const m_iClip = 51
  87. const m_fInReload = 54
  88. const m_flNextAttack  = 83
  89. const m_rgAmmo_player_Slot0 = 376
  90.  
  91. // Macro
  92. #define is_user_valid_connected(%1)     ( 1 <= %1 <= g_iMaxPlayers && g_bIsConnected [ %1 ] )
  93. #define is_user_in_water(%1)            ( pev ( %1, pev_waterlevel ) == 3 )
  94. #define VectorSubtract(%1,%2,%3)        ( %3[ 0 ] = %1[ 0 ] - %2[ 0 ], %3[ 1 ] = %1[ 1 ] - %2[ 1 ], %3[ 2 ] = %1[ 2 ] - %2[ 2 ] )
  95. #define VectorAdd(%1,%2,%3)         ( %3[ 0 ] = %1[ 0 ] + %2[ 0 ], %3[ 1 ] = %1[ 1 ] + %2[ 2 ], %3[ 2 ] = %1[ 2 ] + %2[ 2 ] )
  96. #define VectorScale(%1,%2,%3)           ( %3[ 0 ] = %2 * %1[ 0 ], %3[ 1 ] = %2 * %1[ 1 ], %3[ 2 ] = %2 * %1[ 2 ] )
  97. #define VectorLength(%1)                ( floatsqroot ( %1[ 0 ] * %1[ 0 ] + %1[ 1 ] * %1[ 1 ] + %1[ 2 ] * %1[ 2 ] ) )
  98.  
  99. // Hack!Custom fields
  100. #define pev_weaponkey       pev_impulse
  101. #define pev_bpammo      pev_iuser3
  102.  
  103. // Misc stuff
  104. #define FCVAR_FLAGS     ( FCVAR_SERVER | FCVAR_SPONLY | FCVAR_UNLOGGED )
  105. #define GAUSS_WEAPONKEY 42856
  106. #define NULLENT     -1
  107. #define FFADE_IN        0x0000
  108. #define UNIT_SECOND     (1<<12)
  109.  
  110. // Entity classnames
  111. new const g_szClassPlayer[ ] = "player"
  112. new const g_szClassM249[ ] = "weapon_m249"
  113.  
  114. // Primary weapon bitsum
  115. const PRIMARY_WEAPONS_BITSUM = (1<<CSW_SCOUT)|(1<<CSW_XM1014)|(1<<CSW_MAC10)|(1<<CSW_AUG)|(1<<CSW_UMP45)|(1<<CSW_SG550)|(1<<CSW_GALIL)|(1<<CSW_FAMAS)|(1<<CSW_AWP)|(1<<CSW_MP5NAVY)|(1<<CSW_M249)|(1<<CSW_M3)|(1<<CSW_M4A1)|(1<<CSW_TMP)|(1<<CSW_G3SG1)|(1<<CSW_SG552)|(1<<CSW_AK47)|(1<<CSW_P90)
  116.  
  117. // Animation sequnces
  118. enum
  119. {
  120.     gauss_idle,
  121.     gauss_idle2,
  122.     gauss_fidget,
  123.     gauss_spinup,
  124.     gauss_spin,
  125.     gauss_fire,
  126.     gauss_fire2,
  127.     gauss_holster,
  128.     gauss_draw
  129. }
  130.  
  131. // Precache
  132. public plugin_precache( )
  133. {
  134.     // Weapon models
  135.     precache_model( g_szModelGaussP )
  136.     precache_model( g_szModelGaussV )
  137.     precache_model( g_szModelGaussW )
  138.    
  139.     // Sounds
  140.     precache_sound( g_szSoundGaussFire )
  141.     precache_sound( g_szSoundGaussSpin )
  142.     precache_sound( g_szSoundElectro1 )
  143.     precache_sound( g_szSoundElectro2 )
  144.     precache_sound( g_szSoundElectro3 )
  145.     precache_sound( "items/9mmclip1.wav" )
  146.    
  147.     // Sprites
  148.     g_iBeam = precache_model( "sprites/smoke.spr" )
  149.     g_iBalls = precache_model( "sprites/hotglow.spr" )
  150. }
  151.  
  152. // Initialization
  153. public plugin_init( )
  154. {
  155.     // New plugin
  156.     register_plugin( Plugin, Version, Author )
  157.    
  158.     // For Game-Monitor support
  159.     register_cvar( "ze_tcannon_version", Version, FCVAR_FLAGS )
  160.    
  161.     // New extra item
  162.     g_iGaussID = ze_register_item("Tau Cannon", 30, 0)
  163.    
  164.     // Events
  165.     register_event( "CurWeapon", "EV_CurWeapon", "be", "1=1" )
  166.     register_event( "DeathMsg", "EV_DeathMsg", "a" )
  167.     register_event( "HLTV", "EV_RoundStart", "a", "1=0", "2=0" )
  168.     register_event( "TextMsg", "EV_GameRestart", "a", "2=#Game_Commencing", "2=#Game_will_restart_in" )
  169.    
  170.     // FakeMeta forwards
  171.     register_forward( FM_SetModel, "fw_SetModel" )
  172.     register_forward( FM_CmdStart, "fw_CmdStart" )
  173.     register_forward( FM_UpdateClientData, "fw_UpdateClientData_Post", 1 )
  174.     register_forward( FM_PlayerPreThink, "fw_PlayerPreThink" )
  175.    
  176.     // HamSandwich forwards
  177.     RegisterHam( Ham_Spawn, g_szClassPlayer, "fw_PlayerSpawn_Post", 1 )
  178.     RegisterHam( Ham_Item_Deploy, g_szClassM249, "fw_TCannonDeploy_Post", 1 )
  179.     RegisterHam( Ham_Item_Holster, g_szClassM249, "fw_TCannonHolster_Post", 1 )
  180.     RegisterHam( Ham_Item_AddToPlayer, g_szClassM249, "fw_TCannonAddToPlayer" )
  181.     RegisterHam( Ham_Item_PostFrame, g_szClassM249, "fw_TCannonPostFrame" )
  182.     RegisterHam( Ham_Weapon_Reload, g_szClassM249, "fw_TCannonReload_Post", 1 )
  183.    
  184.     // CVARs are in Load_Cvars( ) function!
  185.    
  186.     // Messages
  187.     register_message( get_user_msgid( "DeathMsg" ), "fn_DeathMsg" )
  188.     gmsgScreenFade = get_user_msgid( "ScreenFade" )
  189.    
  190.     // Store maxplayers in a global variable
  191.     g_iMaxPlayers = get_maxplayers( )
  192. }  
  193.  
  194. // Configuration
  195. public plugin_cfg( )
  196. {
  197.     // Cache CVARs
  198.     set_task( 1.5, "Load_Cvars" )
  199. }
  200.  
  201. // ------------------------------- Game Events ----------------------------------------
  202.  
  203. // Client connected
  204. public client_connect( Player )
  205. {
  206.     // Make a lot of updates
  207.     g_iHasGauss[ Player ] = false
  208.     g_bInAttack[ Player ] = 0
  209.     g_fflPlayAfterShock[ Player ] = 0.0
  210.     g_flWeaponIdleTime[ Player ] = 0.0
  211.     g_bPrimaryFire[ Player ] = false
  212.     g_bIsAlive[ Player ] = false
  213.     g_bIsConnected[ Player ] = true
  214. }
  215.  
  216. // Client disconnected
  217. public client_disconnect( Player )
  218. {
  219.     // Only few important updates
  220.     g_bIsAlive[ Player ] = false
  221.     g_bIsConnected[ Player ] = false
  222. }
  223.  
  224. public ze_select_item_pre(id, itemid)
  225. {
  226.     // Return Available and we will block it in Post, So it dosen't affect other plugins
  227.     if (itemid != g_iGaussID)
  228.         return ZE_ITEM_AVAILABLE
  229.    
  230.     // Available for Humans only, So don't show it for zombies
  231.     if (ze_is_user_zombie(id))
  232.         return ZE_ITEM_DONT_SHOW
  233.    
  234.     return ZE_ITEM_AVAILABLE
  235. }
  236.  
  237. public ze_select_item_post(Player, itemid)
  238. {
  239.     if (itemid != g_iGaussID)
  240.         return
  241.  
  242.     // Drop all primary weapons
  243.     UTIL_DropPrimary( Player )
  244.        
  245.     // Update
  246.     g_iHasGauss[ Player ] = true
  247.        
  248.     // Give m249
  249.     give_item( Player, "weapon_m249" )
  250.        
  251.     // Find weapon entity
  252.     new iEnt = find_ent_by_owner( NULLENT, g_szClassM249, Player )
  253.        
  254.     // Apply new clip
  255.     cs_set_weapon_ammo( iEnt, g_pClip )
  256.        
  257.     // Back pack ammo
  258.     cs_set_user_bpammo( Player, CSW_M249, MAXBPAMMO[ 20 ] )
  259. }
  260.  
  261. // Current weapon player is holding
  262. public EV_CurWeapon( Player )
  263. {
  264.     // Not alive
  265.     if( !g_bIsAlive[ Player ] )
  266.         return PLUGIN_CONTINUE
  267.    
  268.     // Update
  269.     g_iCurrentWeapon[ Player ] = read_data( 2 )
  270.    
  271.     return PLUGIN_CONTINUE
  272. }
  273.  
  274. // Someone died
  275. public EV_DeathMsg( )
  276. {
  277.     // Get victim
  278.     static iVictim
  279.     iVictim = read_data( 2 )
  280.    
  281.     // Not connected
  282.     if( !is_user_valid_connected( iVictim ) )
  283.         return
  284.    
  285.     // Update
  286.     g_bIsAlive[ iVictim ] = false
  287.    
  288.     // Check if victim has gauss
  289.     if( g_iHasGauss[ iVictim ] && !is_user_bot( iVictim ) )
  290.     {
  291.         // Force to drop
  292.         engclient_cmd( iVictim, "drop weapon_m249" )
  293.     }
  294. }
  295.  
  296. // Round started
  297. public EV_RoundStart( )
  298. {
  299.     // Restart/One round only
  300.     if( g_bGameRestart || g_pOneRound )
  301.     {
  302.         // Reset array value
  303.         arrayset( g_iHasGauss, false, MaxPlayers+1 )
  304.     }
  305.    
  306.     // Update
  307.     g_bGameRestart = false
  308. }
  309.  
  310. // Game restart
  311. public EV_GameRestart( )
  312. {
  313.     // Update
  314.     g_bGameRestart = true
  315. }
  316.  
  317. // Hook death message
  318. public fn_DeathMsg( Player, Dest, iEntity )
  319. {
  320.     // Get victim
  321.     static iVictim, iKiller
  322.     iKiller = get_msg_arg_int( 1 )
  323.     iVictim = get_msg_arg_int( 2 )
  324.    
  325.     // Not connected
  326.     if( !is_user_valid_connected( iVictim ) || iKiller == iVictim )
  327.         return PLUGIN_CONTINUE
  328.    
  329.     // We were killed by laser
  330.     if ( g_bKilledByLaser[ iVictim ] )
  331.     {
  332.         // Replace name in console
  333.         set_msg_arg_string ( 4, "tau cannon" )
  334.     }
  335.     return PLUGIN_CONTINUE
  336. }
  337.  
  338. // ------------------------------- Forwards ----------------------------------------
  339.  
  340. // Replace world model
  341. public fw_SetModel ( Entity, const Model [ ] )
  342. {
  343.     // Prevent invalid entity messages
  344.     if( !pev_valid( Entity ) )
  345.         return FMRES_IGNORED
  346.    
  347.     // Not w_awp.mdl
  348.     if( !equal( Model, "models/w_m249.mdl" ) )
  349.         return FMRES_IGNORED
  350.    
  351.     // Get entity classname
  352.     static szClassname[ 32 ]
  353.     pev( Entity, pev_classname, szClassname, charsmax( szClassname ) )
  354.    
  355.     // Not weaponbox
  356.     if( !equal( szClassname, "weaponbox" ) )
  357.         return FMRES_IGNORED
  358.    
  359.     // Get owner
  360.     static iOwner
  361.     iOwner = pev( Entity, pev_owner )
  362.    
  363.     // Get awp ID
  364.     static iWeaponID
  365.     iWeaponID = find_ent_by_owner( NULLENT, g_szClassM249, Entity )
  366.    
  367.     // Make sure that we have gauss
  368.     if( g_iHasGauss [ iOwner ] && is_valid_ent( iWeaponID ) )
  369.     {
  370.         // Hack! Store weaponkey
  371.         set_pev( iWeaponID, pev_weaponkey, GAUSS_WEAPONKEY )
  372.        
  373.         // Hack! Store bp ammo
  374.         set_pev( iWeaponID, pev_bpammo, cs_get_user_bpammo( iOwner, CSW_M249 ) )
  375.        
  376.         // Update
  377.         g_iHasGauss[ iOwner ] = false
  378.        
  379.         // Replace models
  380.         engfunc( EngFunc_SetModel, Entity, g_szModelGaussW )
  381.         return FMRES_SUPERCEDE
  382.     }
  383.     return FMRES_IGNORED
  384. }
  385.  
  386. // Command start
  387. public fw_CmdStart( Player, UC_Handle, Seed )
  388. {
  389.     // Not alive/dont have gauss/not m249
  390.     if( !g_bIsAlive[ Player ] || !g_iHasGauss[ Player ] || g_iCurrentWeapon[ Player ] != CSW_M249 )
  391.         return FMRES_IGNORED
  392.    
  393.     // Retrieve pressed button bitsum
  394.     static iButtons
  395.     iButtons = get_uc( UC_Handle, UC_Buttons )
  396.    
  397.     // Retrieve game time
  398.     static Float:flGameTime
  399.     flGameTime = get_gametime( )
  400.    
  401.     // Retrieve weapon entity
  402.     static iEnt
  403.     iEnt = find_ent_by_owner( NULLENT, g_szClassM249, Player )
  404.    
  405.     // Retrieve clip amount
  406.     static iClip
  407.     iClip = cs_get_weapon_ammo( iEnt )
  408.    
  409.     // Primary attack
  410.     if( iButtons & IN_ATTACK )
  411.     {
  412.         // Remove attack buttons from their button mask
  413.         iButtons &= ~IN_ATTACK
  414.         set_uc( UC_Handle, UC_Buttons, iButtons )
  415.        
  416.         // Prevent too fast shooting
  417.         if( flGameTime - g_flLastShotTime[ Player ] < GAUSS_REFIRERATE )
  418.             return FMRES_IGNORED
  419.        
  420.         // Dont fire while reloading
  421.         if( get_pdata_int( iEnt, m_fInReload, 4 ) )
  422.             return FMRES_IGNORED
  423.        
  424.         // Not enough clip/under water
  425.         if( iClip < 2 || is_user_in_water( Player ) )
  426.         {
  427.             // Emit empty sound
  428.             ExecuteHamB( Ham_Weapon_PlayEmptySound, iEnt )
  429.             return FMRES_IGNORED
  430.         }
  431.        
  432.         // Update
  433.         g_bPrimaryFire[ Player ] = true
  434.        
  435.         // Start to fire
  436.         StartFire( Player )
  437.        
  438.         // Decrease clip
  439.         cs_set_weapon_ammo( iEnt, iClip-2 )
  440.        
  441.         // Reset weapon attack status
  442.         g_bInAttack[ Player ] = 0
  443.        
  444.         // Set time when idle animation should be played
  445.         g_flWeaponIdleTime[ Player ] = flGameTime + 1.0
  446.        
  447.         // Remember last shot time
  448.         g_flLastShotTime[ Player ] = flGameTime
  449.     }
  450.     // Secondary attack
  451.     else if( iButtons & IN_ATTACK2 )
  452.     {
  453.         // Prevent too fast shooting
  454.         if( flGameTime - g_flLastShotTime[ Player ] < GAUSS_REFIRERATE2 )
  455.             return FMRES_IGNORED
  456.        
  457.         // Dont fire while reloading
  458.         if( get_pdata_int( iEnt, m_fInReload, 4 ) )
  459.             return FMRES_IGNORED
  460.        
  461.         // Are we swimming ?
  462.         if( is_user_in_water( Player ) )
  463.         {
  464.             // We are in a middle of attack
  465.             if( g_bInAttack[ Player ] != 0 )
  466.             {
  467.                 // Stop attack
  468.                 emit_sound( Player, CHAN_WEAPON, g_szSoundElectro1, VOL_NORM, ATTN_NORM, 0, 80 + random_num( 0, 0x3f ) )
  469.                
  470.                 // Gun idle
  471.                 UTIL_PlayWeaponAnimation( Player, gauss_idle )
  472.                 return FMRES_IGNORED
  473.             }
  474.             else
  475.             {
  476.                 // Empty sound
  477.                 ExecuteHamB( Ham_Weapon_PlayEmptySound, iEnt )
  478.                 return FMRES_IGNORED
  479.             }
  480.         }
  481.        
  482.         // Get player oldbuttons
  483.         static iOldButtons
  484.         iOldButtons = pev( Player, pev_oldbuttons )
  485.        
  486.         // Make sure that we are holding secondary attack button
  487.         if( iOldButtons & IN_ATTACK2 )
  488.         {
  489.             // Which attack state do we have
  490.             switch ( g_bInAttack[ Player ] )
  491.             {
  492.                 case 0: // Attack start
  493.                 {
  494.                     // Out of ammo
  495.                     if ( iClip <= 0 )
  496.                     {
  497.                         ExecuteHamB( Ham_Weapon_PlayEmptySound, iEnt )
  498.                         return FMRES_IGNORED
  499.                     }
  500.                    
  501.                     // We aren't using primary attack anymore
  502.                     g_bPrimaryFire[ Player ] = false
  503.                    
  504.                     // Decrease clip
  505.                     cs_set_weapon_ammo( iEnt, --iClip )
  506.                    
  507.                     // Update
  508.                     g_flNextAmmoBurn[ Player ] = flGameTime
  509.                    
  510.                     // Send spinup animation
  511.                     UTIL_PlayWeaponAnimation( Player, gauss_spinup )
  512.                    
  513.                     // Update attack state
  514.                     g_bInAttack[ Player ] = 1
  515.                    
  516.                     // Next idle time
  517.                     g_flWeaponIdleTime[ Player ] = flGameTime + 0.5
  518.                    
  519.                     // Update
  520.                     g_flStartCharge[ Player ] = flGameTime
  521.                     g_flAmmoStartCharge[ Player ] = flGameTime + GAUSS_CHARGETIME
  522.                    
  523.                     // Update sound state
  524.                     g_iSoundState[ Player ] = 0
  525.                    
  526.                     // Spin sound
  527.                     emit_sound( Player, CHAN_WEAPON, g_szSoundGaussSpin, VOL_NORM, ATTN_NORM, g_iSoundState[Player ], 110 )
  528.                    
  529.                     // Change sound state
  530.                     g_iSoundState[ Player ] = SND_CHANGE_PITCH
  531.                 }
  532.                 case 1: // In a middle of attack
  533.                 {
  534.                     if( g_flWeaponIdleTime[ Player ] < flGameTime )
  535.                     {
  536.                         // Spin anim
  537.                         UTIL_PlayWeaponAnimation( Player, gauss_spin )
  538.                        
  539.                         // Update state
  540.                         g_bInAttack[ Player ] = 2
  541.                     }
  542.                 }
  543.                 default: // End of attack
  544.                 {
  545.                     // During the charging process, eat one bit of ammo every once in a while
  546.                     if( flGameTime >= g_flNextAmmoBurn[ Player ] && g_flNextAmmoBurn[ Player ] != 1000 )
  547.                     {
  548.                         // Decrease clip
  549.                         cs_set_weapon_ammo( iEnt, --iClip )
  550.                        
  551.                         // Next time when ammo should be decreased
  552.                         g_flNextAmmoBurn[ Player ] = flGameTime + 0.1
  553.                     }
  554.                    
  555.                     // Shit!We run out of ammo
  556.                     if( iClip <= 0 )
  557.                     {
  558.                         // Force gun to fire
  559.                         StartFire( Player )
  560.                        
  561.                         // Reset weapon state
  562.                         g_bInAttack[ Player ] = 0
  563.                        
  564.                         // Set next idle time
  565.                         g_flWeaponIdleTime[ Player ] = flGameTime + 1.0
  566.                     }
  567.                    
  568.                     // Gun is fully charged up
  569.                     if( flGameTime >= g_flAmmoStartCharge[ Player ] )
  570.                     {
  571.                         // Dont eat any more ammo!
  572.                         g_flNextAmmoBurn[ Player ] = 1000.0
  573.                     }
  574.                    
  575.                     // Calculate pitch
  576.                     static Float:flPitch
  577.                     flPitch = ( flGameTime - g_flStartCharge[ Player ] ) * ( 150 / GAUSS_CHARGETIME ) + 100
  578.                    
  579.                     // Pitch shouldnt be THAT big
  580.                     if ( flPitch > 250 )
  581.                     {
  582.                         flPitch = 250.0
  583.                     }
  584.                    
  585.                     // Spin sound
  586.                     emit_sound( Player, CHAN_WEAPON, g_szSoundGaussSpin, VOL_NORM, ATTN_NORM, ( g_iSoundState[ Player ] == SND_CHANGE_PITCH ) ? 1 : 0, floatround( flPitch ) )
  587.                    
  588.                     // Hack for going through level transitions
  589.                     g_iSoundState[ Player ] = SND_CHANGE_PITCH
  590.                    
  591.                     // We are charing way too long!
  592.                     if( g_flStartCharge[ Player ] < flGameTime - 10 )
  593.                     {
  594.                         // ZAP!
  595.                         emit_sound( Player, CHAN_WEAPON, g_szSoundElectro1, VOL_NORM, ATTN_NORM, 0, 80 + random_num( 0, 0x3f ) )
  596.                         emit_sound( Player, CHAN_VOICE, g_szSoundElectro3, VOL_NORM, ATTN_NORM, 0, 80 + random_num( 0, 0x3f ) )
  597.                        
  598.                         // Reset fire state
  599.                         g_bInAttack[ Player ] = 0
  600.                        
  601.                         // Next idle time
  602.                         g_flWeaponIdleTime[ Player ] = flGameTime + 1.0
  603.                        
  604.                         // Damage player
  605.                         ExecuteHamB( Ham_TakeDamage, Player, 0, Player, 50.0, DMG_SHOCK )
  606.                        
  607.                         // Make screen fade
  608.                         UTIL_ScreenFade( Player, UNIT_SECOND*2, UNIT_SECOND/2, FFADE_IN, 255, 128, 0, 128 )
  609.                        
  610.                         // Idle animation
  611.                         UTIL_PlayWeaponAnimation( Player, gauss_idle )
  612.                     }
  613.                 }
  614.             }
  615.            
  616.             // Update
  617.             g_flLastShotTime[ Player ] = flGameTime
  618.         }
  619.     }
  620.    
  621.     return FMRES_HANDLED
  622. }
  623.  
  624. // Update client data post
  625. public fw_UpdateClientData_Post ( Player, SendWeapons, CD_Handle )
  626. {
  627.     // Not alive / dont have gauss/ not m249
  628.     if ( !g_bIsAlive [ Player ] || !g_iHasGauss [ Player ] || g_iCurrentWeapon [ Player ] != CSW_M249 )
  629.         return FMRES_IGNORED
  630.    
  631.     // Block default sounds/animations
  632.     set_cd ( CD_Handle, CD_flNextAttack, halflife_time ( ) + 0.001 )
  633.     return FMRES_HANDLED
  634. }
  635.  
  636. // Player pre think
  637. public fw_PlayerPreThink( Player )
  638. {
  639.     // Not alive / dont have gauss/ not m249
  640.     if ( !g_bIsAlive [ Player ] || !g_iHasGauss [ Player ] || g_iCurrentWeapon [ Player ] != CSW_M249 )
  641.         return
  642.    
  643.     // Play aftershock discharge
  644.     if( g_fflPlayAfterShock[ Player ] && g_fflPlayAfterShock[ Player ] < get_gametime( ) )
  645.     {
  646.         // Randomly play sound
  647.         switch( random_num(0, 3 ) )
  648.         {
  649.             case 0: emit_sound( Player, CHAN_WEAPON, g_szSoundElectro1,random_float( 0.7, 0.8 ), ATTN_NORM, 0, PITCH_NORM )
  650.                 case 1: emit_sound( Player, CHAN_WEAPON, g_szSoundElectro2,random_float( 0.7, 0.8 ), ATTN_NORM, 0, PITCH_NORM )
  651.                 case 2: emit_sound( Player, CHAN_WEAPON, g_szSoundElectro3,random_float( 0.7, 0.8 ), ATTN_NORM, 0, PITCH_NORM )
  652.                 case 3: return // No sound
  653.             }
  654.        
  655.         // Reset discharge
  656.         g_fflPlayAfterShock[ Player ] = 0.0
  657.     }
  658.    
  659.     // Check if we are in a middle of attack
  660.     if( g_bInAttack[ Player ] != 0 )
  661.     {
  662.         // Check if have released attack2 button
  663.         if( get_gametime( ) - g_flLastShotTime[ Player ] > 0.2 )
  664.         {
  665.             // Start to fire
  666.             StartFire( Player )
  667.            
  668.             // Reset attack state
  669.             g_bInAttack[ Player ] = 0
  670.            
  671.             // Next idle time
  672.             g_flWeaponIdleTime[ Player ] = get_gametime( ) + 2.0
  673.         }
  674.     }
  675.     else
  676.     {
  677.         // Force to idle
  678.         WeaponIdle( Player )
  679.     }
  680. }
  681.  
  682. // Player respawned
  683. public fw_PlayerSpawn_Post( Player )
  684. {
  685.     // Not alive
  686.     if( !is_user_alive( Player ) )
  687.         return
  688.    
  689.     // Update
  690.     g_bIsAlive[ Player ] = true
  691. }
  692.  
  693. // Guass deploy
  694. public fw_TCannonDeploy_Post( iEnt )
  695. {
  696.     // Get owner
  697.     static Player
  698.     Player = get_pdata_cbase( iEnt, m_pPlayer, 4 )
  699.    
  700.     if(!is_user_valid_connected(Player) || !(get_user_weapon(Player) & CSW_M249))   return
  701.    
  702.     // Does this player has gauss?
  703.     if ( g_iHasGauss[ Player ] )
  704.     {
  705.         // Replace models
  706.         set_pev( Player, pev_viewmodel2, g_szModelGaussV )
  707.         set_pev( Player, pev_weaponmodel2, g_szModelGaussP )
  708.        
  709.         // Deploy animation
  710.         UTIL_PlayWeaponAnimation( Player, gauss_draw )
  711.        
  712.         // Reset aftershock
  713.         g_fflPlayAfterShock[ Player ] = 0.0
  714.     }
  715. }
  716.  
  717. // Gauss holster
  718. public fw_TCannonHolster_Post( iEnt )
  719. {
  720.     // Get owner
  721.     static Player
  722.     Player = get_pdata_cbase( iEnt, m_pPlayer, 4 )
  723.  
  724.     if (!is_user_alive(Player))
  725.         return
  726.    
  727.     // Does this player has gauss?
  728.     if ( g_iHasGauss[ Player ] )
  729.     {
  730.         // Check if player is still attacking
  731.         if( g_bInAttack[ Player ] )
  732.         {
  733.             // Bug!Bug!Stop spin sound
  734.             emit_sound( Player, CHAN_WEAPON, g_szSoundGaussSpin, 0.0, 0.0, SND_STOP, 0 )
  735.            
  736.             // Attack
  737.             StartFire( Player )
  738.         }
  739.        
  740.         // Holster animation
  741.         UTIL_PlayWeaponAnimation( Player, gauss_holster )
  742.        
  743.         // Reset attack status
  744.         g_bInAttack[ Player ] = 0
  745.     }
  746. }
  747.  
  748. // Add Gauss to players inventory
  749. public fw_TCannonAddToPlayer( iEnt, Player )
  750. {
  751.     // Prevent run-time errors
  752.     if( is_valid_ent( iEnt ) && is_user_valid_connected( Player ) )
  753.     {
  754.         // Seems that player has picked up a gauss
  755.         if( pev( iEnt, pev_weaponkey ) == GAUSS_WEAPONKEY )
  756.         {
  757.             // Update variable
  758.             g_iHasGauss[ Player ] = true
  759.            
  760.             // Update bp ammo
  761.             cs_set_user_bpammo( Player, CSW_M249, pev( iEnt, pev_bpammo ) )
  762.            
  763.             // Reset weapon options
  764.             set_pev( iEnt, pev_weaponkey, 0 )
  765.             set_pev( iEnt, pev_bpammo, 0 )
  766.            
  767.             return HAM_HANDLED
  768.         }
  769.     }
  770.     return HAM_IGNORED
  771. }
  772.  
  773. // Gauss post frame
  774. public fw_TCannonPostFrame( iEnt )
  775. {
  776.     if (!pev_valid(iEnt))
  777.         return
  778.        
  779.     // Get owner
  780.     static iOwner
  781.     iOwner = get_pdata_cbase(iEnt, m_pPlayer, 4)
  782.    
  783.     if(!is_valid_ent(iEnt) || !is_user_valid_connected(iOwner)) return
  784.    
  785.     // Does this player has gauss?
  786.     if ( g_iHasGauss[ iOwner ] )
  787.     {
  788.         // Reload offset
  789.         static fInReload
  790.         fInReload = get_pdata_int ( iEnt, m_fInReload,4 )
  791.        
  792.         // Next attack time
  793.         static Float:flNextAttack
  794.         flNextAttack = get_pdata_float (iOwner, m_flNextAttack, 5)
  795.        
  796.         // Clip
  797.         static iClip
  798.         iClip = get_pdata_int ( iEnt, m_iClip, 4 )
  799.        
  800.         // Ammo type
  801.         static iAmmoType
  802.         iAmmoType = m_rgAmmo_player_Slot0 + get_pdata_int ( iEnt, m_iPrimaryAmmoType, 4 )
  803.        
  804.         // BP ammo
  805.         static iBpAmmo
  806.         iBpAmmo = get_pdata_int ( iOwner, iAmmoType, 5 )  
  807.        
  808.         // Reloading
  809.         if ( fInReload && flNextAttack <= 0.0 )
  810.         {
  811.             // Calculate the difference
  812.             static j
  813.             j = min ( g_pClip - iClip, iBpAmmo )
  814.            
  815.             // Set new clip
  816.             set_pdata_int ( iEnt, m_iClip, iClip + j, 4 )
  817.            
  818.             // Decrease 'x' bullets from backpack(depending on new clip)
  819.             set_pdata_int( iOwner, iAmmoType, iBpAmmo-j, 5 )
  820.            
  821.             // Not reloding anymore
  822.             set_pdata_int ( iEnt, m_fInReload, 0, 4 )
  823.             fInReload = 0
  824.         }
  825.        
  826.         // Get buttons
  827.         static iButton ; iButton = pev ( iOwner, pev_button)
  828.        
  829.         // Attack/Attack2 buttons and next prim/sec attack time hasnt' come yet
  830.         if( ( iButton & IN_ATTACK2 && get_pdata_float ( iEnt, m_flNextSecondaryAttack, 4 ) <= 0.0)
  831.         || ( iButton & IN_ATTACK && get_pdata_float ( iEnt, m_flNextPrimaryAttack, 4 ) <= 0.0) )
  832.         {
  833.             return
  834.         }
  835.    
  836.         // Reload button / not reloading
  837.         if( iButton & IN_RELOAD && !fInReload )
  838.         {
  839.             // Old clip is more/equal than/to new
  840.             if( iClip >= g_pClip )
  841.             {
  842.                 // Remove reload button
  843.                 set_pev ( iOwner, pev_button, iButton & ~IN_RELOAD )
  844.                
  845.                 // Idle animation
  846.                 UTIL_PlayWeaponAnimation ( iOwner, gauss_idle )
  847.                
  848.                 // Idle time
  849.                 g_flWeaponIdleTime[ iOwner ] = get_gametime( ) + 0.5
  850.             }
  851.             else
  852.             {
  853.                 // Out of ammo
  854.                 if ( !iBpAmmo )
  855.                     return
  856.                    
  857.                 // Reload weapon
  858.                 UTIL_WeaponReload ( iOwner, iEnt )
  859.             }
  860.         }
  861.     }
  862. }
  863.  
  864. // Gauss reload post
  865. public fw_TCannonReload_Post( iEnt )
  866. {
  867.     if (!pev_valid(iEnt))
  868.         return
  869.  
  870.     // Get owner
  871.     static Player
  872.     Player = get_pdata_cbase( iEnt, m_pPlayer, 4 )
  873.  
  874.     if (!is_user_alive(Player))
  875.         return
  876.    
  877.     // Does this player has gauss and is he in a middle of reloading ?
  878.     if ( g_iHasGauss[ Player ] && get_pdata_int( iEnt, m_fInReload, 4 ) )
  879.     {
  880.         // Reload
  881.         UTIL_WeaponReload( Player, iEnt )
  882.     }
  883. }
  884.  
  885. // ------------------------------- Internal Functions ----------------------------------------
  886.  
  887. // Gauss start fire
  888. public StartFire( Player )
  889. {
  890.     // This var holds damage
  891.     static Float:flDamage
  892.    
  893.     // Make vectors
  894.     UTIL_MakeVectors( Player )
  895.    
  896.     // Get gametime
  897.     static Float:flGameTime
  898.     flGameTime = get_gametime( )
  899.    
  900.     // This is maximal possible damage from secondary attack!
  901.     if( flGameTime - g_flStartCharge[ Player ] > GAUSS_CHARGETIME )
  902.     {
  903.         flDamage = g_pDmgSec
  904.     }
  905.     else
  906.     {
  907.         // The longer you hold attack button - the bigger is damage
  908.         flDamage = g_pDmgSec * ( ( flGameTime - g_flStartCharge[ Player ] ) / GAUSS_CHARGETIME )
  909.     }
  910.    
  911.     // Primary attack do less damage
  912.     if( g_bPrimaryFire[ Player ] )
  913.     {
  914.         flDamage = g_pDmgPrim
  915.     }
  916.    
  917.     // Make sure that we are not ending attack
  918.     if( g_bInAttack[ Player ] != 3 )
  919.     {
  920.         // Secondary attack can pop you up in the air.Not primary attack!
  921.         if( !g_bPrimaryFire[ Player ] )
  922.         {
  923.             // Current players velocity
  924.             static Float:flVel[ 3 ], Float:v_forward[ 3 ]
  925.             pev( Player, pev_velocity, flVel )
  926.             global_get( glb_v_forward, v_forward )
  927.            
  928.             // Try to affect only vertical velocity
  929.             VectorMS( flVel, flDamage * 5.0, v_forward, flVel )
  930.            
  931.             // Jump!
  932.             set_pev( Player, pev_velocity, flVel )
  933.         }
  934.     }
  935.    
  936.     // Recoil
  937.     static Float:flRecoil[ 3 ]
  938.     flRecoil[ 0 ] = GAUSS_RECOIL
  939.     set_pev( Player, pev_punchangle, flRecoil )
  940.    
  941.     // Fire animation
  942.     UTIL_PlayWeaponAnimation( Player, gauss_fire2 )
  943.    
  944.     // Fire sound
  945.     static Float:flResult
  946.     flResult = 0.5 + flDamage * ( 1.0 / 400.0 )
  947.    
  948.     if( flResult > 1.0 )
  949.     {
  950.         flResult = 1.0
  951.     }
  952.    
  953.     emit_sound( Player, CHAN_WEAPON, g_szSoundGaussFire, flResult, ATTN_NORM, 0, 85 + random_num( 0, 0x1f ) )
  954.    
  955.     // Get players aimpoint position
  956.     static Float:vecDest[ 3 ]
  957.     global_get( glb_v_forward, vecDest )
  958.    
  959.     // Calculate start position
  960.     static Float:vecSrc[ 3 ]
  961.     UTIL_GetGunPosition( Player, vecSrc )
  962.    
  963.     // Time until aftershock 'static discharge' sound
  964.     g_fflPlayAfterShock[ Player ] = flGameTime + random_float( 0.3, 0.8 )
  965.    
  966.     // Fire!
  967.     Fire( Player, vecSrc, vecDest, flDamage )
  968. }
  969.  
  970. // Fire!
  971. Fire( Player, Float:vecOrigSrc[ ], Float:vecDir[ ], Float:flDamage )
  972. {
  973.     // Start position
  974.     static Float:vecSrc[ 3 ]
  975.     xs_vec_copy( vecOrigSrc, vecSrc )
  976.    
  977.     // Calculate end position
  978.     static Float:vecDest[ 3 ]
  979.     VectorMA( vecSrc, 8192.0, vecDir, vecDest )
  980.    
  981.     // Few trace handles
  982.     static tr, beam_tr
  983.    
  984.     // Max fraction
  985.     static Float:flMaxFrac
  986.     flMaxFrac = 1.0
  987.    
  988.     // Total
  989.     static nTotal
  990.     nTotal = 0
  991.    
  992.     // Does this beam punched the wall ?
  993.     static bool:fHasPunched
  994.     fHasPunched = false
  995.    
  996.     // Does this is first beam
  997.     static bool:fFirstBeam
  998.     fFirstBeam = true
  999.    
  1000.     // Max hits
  1001.     static nMaxHits
  1002.     nMaxHits = 10
  1003.    
  1004.     // Entity whoch should be ignored
  1005.     static pEntToIgnore
  1006.    
  1007.     // Make sure that beam will'be able to cause damage
  1008.     while( flDamage > 10 && nMaxHits > 0 )
  1009.     {
  1010.         // Decrease hit count
  1011.         nMaxHits--
  1012.        
  1013.         // Draw a trace line
  1014.         engfunc( EngFunc_TraceLine, vecSrc, vecDest, DONT_IGNORE_MONSTERS, pEntToIgnore, tr )
  1015.        
  1016.         // We'll never get outside!
  1017.         if( get_tr2( tr, TR_AllSolid ) )
  1018.             break
  1019.        
  1020.         // Get entity which was hit
  1021.         static pEntity
  1022.         pEntity = Instance( get_tr2( tr, TR_pHit ) )  
  1023.        
  1024.         // Get vector end position
  1025.         static Float:vecEnd[ 3 ]
  1026.         get_tr2( tr, TR_vecEndPos, vecEnd )
  1027.        
  1028.         // Its first beam  
  1029.         if( fFirstBeam )
  1030.         {
  1031.             // Add muzzleflash
  1032.             set_pev( Player, pev_effects, pev(Player, pev_effects) | EF_MUZZLEFLASH )
  1033.            
  1034.             // Its not first anymore
  1035.             fFirstBeam = false
  1036.            
  1037.             // Add
  1038.             nTotal += 26
  1039.            
  1040.             // Draw beam
  1041.             engfunc( EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, vecSrc, 0 )
  1042.             //message_begin( MSG_BROADCAST, SVC_TEMPENTITY )
  1043.             write_byte( TE_BEAMENTPOINT ) // Temp. entity ID
  1044.             write_short( Player | 0x1000 ) // Start entity
  1045.             engfunc( EngFunc_WriteCoord, vecEnd[ 0 ] ) // End position X
  1046.             engfunc( EngFunc_WriteCoord, vecEnd[ 1 ] ) // End position Y
  1047.             engfunc( EngFunc_WriteCoord, vecEnd[ 2 ] ) // End position Z
  1048.             write_short( g_iBeam ) // Sprite index
  1049.             write_byte( 0 ) // Start frame
  1050.             write_byte( 1 ) // Frame rate
  1051.             write_byte( 1 ) // Life
  1052.             write_byte( g_bPrimaryFire[ Player ] ? 16 : 25 ) // Line width
  1053.             write_byte( 0 ) // Noise amplitude
  1054.             write_byte( 255 )
  1055.             write_byte( 128 )
  1056.             write_byte( 0 )
  1057.             write_byte( 255 ) // Alpha
  1058.             write_byte( 0 ) // Scroll speed
  1059.             message_end( )
  1060.         }
  1061.         else
  1062.         {
  1063.             // Draw beam
  1064.             engfunc( EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, vecSrc, 0 )
  1065.             write_byte( TE_BEAMPOINTS ) // Temp. entity ID
  1066.             engfunc( EngFunc_WriteCoord, vecSrc[ 0 ] ) // Start position X
  1067.             engfunc( EngFunc_WriteCoord, vecSrc[ 1 ] ) // Start position Y
  1068.             engfunc( EngFunc_WriteCoord, vecSrc[ 2 ] ) // Start position Z
  1069.             engfunc( EngFunc_WriteCoord, vecEnd[ 0 ] ) // End position X
  1070.             engfunc( EngFunc_WriteCoord, vecEnd[ 1 ] ) // End position Y
  1071.             engfunc( EngFunc_WriteCoord, vecEnd[ 2 ] ) // End position Z
  1072.             write_short( g_iBeam ) // Sprite index
  1073.             write_byte( 0 ) // Start frame
  1074.             write_byte( 1 ) // Frame rate
  1075.             write_byte( 1 ) // Life
  1076.             write_byte( g_bPrimaryFire[ Player ] ? 15 : 25 ) // Line width
  1077.             write_byte( 0 ) // Noise amplitude
  1078.             write_byte( 255 )
  1079.             write_byte( 128 )
  1080.             write_byte( 0 )
  1081.             write_byte( 255 )
  1082.             write_byte( 0 ) // Scroll speed
  1083.             message_end( )
  1084.         }
  1085.        
  1086.         // Check if this entity should take any damage
  1087.         if( pev( pEntity, pev_takedamage ) != DAMAGE_NO )
  1088.         {
  1089.             // Check if this is player and zombie
  1090.             if( is_user_valid_connected( pEntity ) && ze_is_user_zombie( pEntity ) )
  1091.             {
  1092.                 // Retrieve health
  1093.                 static iHealth
  1094.                 iHealth = get_user_health( pEntity )
  1095.            
  1096.                 // We should be alive
  1097.                 if( iHealth - flDamage >= 1 )
  1098.                 {
  1099.                     // Cause some damage
  1100.                     ExecuteHamB( Ham_TakeDamage, pEntity, 0, Player, flDamage, DMG_BULLET | DMG_ALWAYSGIB )
  1101.                 }
  1102.                 else
  1103.                 {
  1104.                     // Die
  1105.                     g_bKilledByLaser[ pEntity ] = true
  1106.                     ExecuteHamB( Ham_Killed, pEntity, Player, 2 )
  1107.                     g_bKilledByLaser[ pEntity ] = false
  1108.                 }
  1109.             }
  1110.         }
  1111.        
  1112.         // Check if this entity should reflect our beam
  1113.         if( ReflectGauss( pEntity ) )
  1114.         {
  1115.             static Float:n
  1116.            
  1117.             // Return normal vector in a spot we hit
  1118.             static Float:vecPlaneNormal[ 3 ]
  1119.             get_tr2( tr, TR_vecPlaneNormal, vecPlaneNormal )
  1120.            
  1121.             // Calculate dot product
  1122.             n = - xs_vec_dot( vecPlaneNormal, vecDir )
  1123.            
  1124.             // 60 degrees
  1125.             if ( 0 < n < 0.5 )
  1126.             {
  1127.                 static Float:r[ 3 ]
  1128.                 VectorMA( vecDir, 2.0 * n, vecPlaneNormal, r )
  1129.                
  1130.                 // Get vector end position
  1131.                 get_tr2( tr, TR_vecEndPos, vecEnd )
  1132.                
  1133.                 // Get trace fraction
  1134.                 static Float:trflFraction
  1135.                 get_tr2( tr, TR_flFraction, trflFraction )
  1136.                
  1137.                 // Calculate fraction
  1138.                 flMaxFrac = flMaxFrac - trflFraction
  1139.                
  1140.                 // Copy vectors
  1141.                 xs_vec_copy( r, vecDir )
  1142.                
  1143.                 // Make more vector calculations
  1144.                 VectorMA( vecEnd, 8.0, vecDir, vecSrc )
  1145.                 VectorMA( vecSrc, 8192.0, vecDir, vecDest )
  1146.            
  1147.                 // Undone!Do radius damage
  1148.                
  1149.                 // Increase
  1150.                 nTotal += 34
  1151.                
  1152.                 if( n == 0 )
  1153.                 {
  1154.                     // Lose energy
  1155.                     n = 0.1
  1156.                 }
  1157.                
  1158.                 // Calculate new damage
  1159.                 flDamage = flDamage * ( 1 - n )
  1160.             }
  1161.             else
  1162.             {
  1163.                 // Add gun shot decal on the world
  1164.                 FX_GunShotDecal( vecEnd, pEntity )
  1165.                
  1166.                 // Add glowing sprite on the world
  1167.                 FX_TempSprite( vecEnd, 6, floatround( flDamage / 255.0 ) )
  1168.                
  1169.                 // Increase
  1170.                 nTotal += 13
  1171.                
  1172.                 // Limit it to one hole punch
  1173.                 if( fHasPunched )
  1174.                     break
  1175.                
  1176.                 // Update  
  1177.                 fHasPunched = true
  1178.                
  1179.                 // Try punching through wall if secondary attack (primary is incapable of
  1180.                 // breaking through)
  1181.                 if( !g_bPrimaryFire[ Player ] )
  1182.                 {
  1183.                     // Retrieve vector end position
  1184.                     get_tr2( tr, TR_vecEndPos, vecEnd )
  1185.                    
  1186.                     // Modify start origin
  1187.                     static Float:vecStart[ 3 ]
  1188.                     VectorMA( vecEnd, 8.0, vecDir, vecStart )
  1189.                    
  1190.                     // Draw another trace line
  1191.                     engfunc( EngFunc_TraceLine, vecSrc, vecDest, DONT_IGNORE_MONSTERS, pEntToIgnore, beam_tr )
  1192.                    
  1193.                     // We'll never get outside
  1194.                     if( !get_tr2( beam_tr, TR_AllSolid ) )
  1195.                     {
  1196.                         // Get end position
  1197.                         static Float:vecBeamEndPos[ 3 ]
  1198.                         get_tr2( beam_tr, TR_vecEndPos, vecBeamEndPos )
  1199.                        
  1200.                         // Trace backwards to find exit point
  1201.                         engfunc( EngFunc_TraceLine, vecBeamEndPos, vecEnd, DONT_IGNORE_MONSTERS, pEntToIgnore, beam_tr )
  1202.                        
  1203.                         // Again get end position
  1204.                         get_tr2( beam_tr, TR_vecEndPos, vecBeamEndPos )
  1205.                        
  1206.                         static Float:ns, Float:vecSub[ 3 ]
  1207.                        
  1208.                         // Subtract vectors
  1209.                         xs_vec_sub( vecBeamEndPos, vecEnd, vecSub )
  1210.                        
  1211.                         // Get vector length
  1212.                         ns = xs_vec_len( vecSub )
  1213.                        
  1214.                         if( ns < flDamage )
  1215.                         {
  1216.                             // Lose enery
  1217.                             if( ns == 0 )
  1218.                             {
  1219.                                 ns = 1.0
  1220.                             }
  1221.                            
  1222.                             // Decrease damage
  1223.                             flDamage -= ns
  1224.                            
  1225.                             // Subtract
  1226.                             static Float:vecCalc[ 3 ]
  1227.                             VectorSubtract( vecEnd, vecDir, vecCalc )
  1228.                            
  1229.                             // Absorbtion balls
  1230.                             FX_SpriteTrail( vecEnd, vecCalc, BALL_AMOUNT, 15, 3, 25, 25 )
  1231.                            
  1232.                             // Add gun shot decal on the world
  1233.                             FX_GunShotDecal( vecBeamEndPos, pEntity )
  1234.                            
  1235.                             // And glowing sprite
  1236.                             FX_TempSprite( vecBeamEndPos, 6, floatround( flDamage / 255.0 ) )
  1237.                            
  1238.                             // Subtract
  1239.                             VectorSubtract( vecBeamEndPos, vecDir, vecCalc )
  1240.                            
  1241.                             // Absorbtion balls
  1242.                             FX_SpriteTrail( vecEnd, vecCalc, BALL_AMOUNT, 15, 3, 25, 25 )
  1243.                            
  1244.                             // Increase shit
  1245.                             nTotal += 21
  1246.                            
  1247.                             /*
  1248.                             // Calculate radius damage
  1249.                             static Float:flRadDmg
  1250.                             flRadDmg = flDamage * 1.75
  1251.                            
  1252.                             // Undone.Do radius damage here!
  1253.                             floatradius( flDamage, flRadDmg, vecBeamEndPos )
  1254.                             */
  1255.                            
  1256.                             // Increase
  1257.                             nTotal += 53
  1258.                            
  1259.                             VectorMA( vecBeamEndPos, 8.0, vecDir, vecSub )
  1260.                            
  1261.                             // Add up vector
  1262.                             xs_vec_add( vecBeamEndPos, vecDir, vecSrc )
  1263.                         }
  1264.                     }
  1265.                     else
  1266.                     {
  1267.                         flDamage = 0.0
  1268.                     }
  1269.                 }
  1270.                 else
  1271.                 {
  1272.                     // Primary attack
  1273.                     if( g_bPrimaryFire [ Player ] )
  1274.                     {
  1275.                         // Slug doesn't punch through ever with primary
  1276.                         // fire, so leave a little glowy bit and make some balls
  1277.                         FX_TempSprite( vecEnd, 6, floatround( flDamage / 255.0 ) )
  1278.                         FX_SpriteTrail( vecEnd, vecDir, BALL_AMOUNT, 15, 3, 25, 25 )
  1279.                     }
  1280.                    
  1281.                     flDamage = 0.0
  1282.                 }
  1283.             }
  1284.         }
  1285.         else
  1286.         {
  1287.             // Add up vector
  1288.             xs_vec_add( vecEnd, vecDir, vecSrc )
  1289.             pEntToIgnore = pEntity
  1290.         }
  1291.     }
  1292. }              
  1293.  
  1294. // Register and cache CVARs
  1295. public Load_Cvars( )
  1296. {
  1297.     cvar_oneround = register_cvar( "ze_tcannon_oneround", "0" )
  1298.     cvar_dmgprim = register_cvar( "ze_tcannon_dmgprim", "200" )
  1299.     cvar_dmgsec = register_cvar( "ze_tcannon_dmgsec", "500" )
  1300.     cvar_clip = register_cvar( "ze_tcannon_clip", "100" )
  1301.    
  1302.     g_pOneRound = get_pcvar_num( cvar_oneround )
  1303.     g_pDmgPrim = get_pcvar_float( cvar_dmgprim )
  1304.     g_pDmgSec = get_pcvar_float( cvar_dmgsec )
  1305.     g_pClip = get_pcvar_num( cvar_clip )
  1306. }
  1307.  
  1308. // Gauss weapon idle
  1309. WeaponIdle( Player )
  1310. {
  1311.     // Get gametime
  1312.     static Float:flGameTime
  1313.     flGameTime = get_gametime( )
  1314.    
  1315.     if( g_flWeaponIdleTime[ Player ] > flGameTime )
  1316.         return
  1317.    
  1318.     // Animation sequence variable
  1319.     static iAnim
  1320.    
  1321.     // Animation randomizer
  1322.     static Float:flRand
  1323.     flRand = random_float( 0.1, 1.0 )
  1324.    
  1325.     if( flRand <= 0.5 )
  1326.     {
  1327.         iAnim = gauss_idle
  1328.         g_flWeaponIdleTime[ Player ] = flGameTime + random_float( 10.0, 15.0 )
  1329.     }
  1330.     else if( flRand <= 0.75 )
  1331.     {
  1332.         iAnim = gauss_idle2
  1333.         g_flWeaponIdleTime[ Player ] = flGameTime + random_float( 10.0, 15.0 )
  1334.     }
  1335.     else
  1336.     {
  1337.         iAnim = gauss_fidget
  1338.         g_flWeaponIdleTime[ Player ] = flGameTime + 3
  1339.     }
  1340.    
  1341.     // Idle
  1342.     UTIL_PlayWeaponAnimation( Player, iAnim )
  1343. }  
  1344.  
  1345. // Play weapon animation
  1346. UTIL_PlayWeaponAnimation( const Player, const Sequence )
  1347. {
  1348.     set_pev( Player, pev_weaponanim, Sequence )
  1349.    
  1350.     message_begin( MSG_ONE_UNRELIABLE, SVC_WEAPONANIM, .player = Player )
  1351.     write_byte( Sequence )
  1352.     write_byte( pev( Player, pev_body ) )
  1353.     message_end( )
  1354. }              
  1355.  
  1356. // Make ScreenFade
  1357. UTIL_ScreenFade( Player, Duration, HoldTime, Flags, iRed, iGreen, iBlue, iAlpha )
  1358. {
  1359.     message_begin( MSG_ONE, gmsgScreenFade, _, Player )
  1360.     write_short( Duration )
  1361.     write_short( HoldTime )
  1362.     write_short( Flags )
  1363.     write_byte( iRed )
  1364.     write_byte( iGreen )
  1365.     write_byte( iBlue )
  1366.     write_byte( iAlpha )
  1367.     message_end( )
  1368. }
  1369.  
  1370. // Reload gauss
  1371. UTIL_WeaponReload( Player, iEnt )
  1372. {
  1373.     // Modify time until next attack
  1374.     set_pdata_float( Player, m_flNextAttack, GAUSS_RELOADTIME+0.5, 5 )
  1375.    
  1376.     // Reload animation
  1377.     UTIL_PlayWeaponAnimation( Player, gauss_spin )
  1378.    
  1379.     // Enable reload offset
  1380.     set_pdata_int( iEnt, m_fInReload, 1, 4 )
  1381.    
  1382.     // Modify next idle time
  1383.     g_flWeaponIdleTime[ Player ] = get_gametime( ) + GAUSS_RELOADTIME + 1.0
  1384. }
  1385.  
  1386. // Drop all primary weapons
  1387. UTIL_DropPrimary( Player )
  1388. {
  1389.     // Get user weapons
  1390.     static weapons[ 32 ], num, i, weaponid
  1391.     num = 0 // reset passed weapons count (bugfix)
  1392.     get_user_weapons( Player, weapons, num )
  1393.    
  1394.     // Loop through them and drop primaries
  1395.     for( i = 0; i < num; i++ )
  1396.     {
  1397.         // Prevent re-indexing the array
  1398.         weaponid = weapons[ i ]
  1399.        
  1400.         // We definetely are holding primary gun
  1401.         if(( (1<<weaponid) & PRIMARY_WEAPONS_BITSUM ) )    
  1402.         {
  1403.             // Get weapon entity
  1404.             static wname[32]
  1405.             get_weaponname(weaponid, wname, charsmax(wname))
  1406.            
  1407.             // Player drops the weapon and looses his bpammo
  1408.             engclient_cmd( Player, "drop", wname)
  1409.         }
  1410.     }
  1411. }
  1412.  
  1413. // Get gun position
  1414. UTIL_GetGunPosition( Player, Float:flOrigin[ ] )
  1415. {
  1416.     static Float:vf_Origin[ 3 ], Float:vf_ViewOfs[ 3 ]
  1417.    
  1418.     pev( Player, pev_origin, vf_Origin )
  1419.     pev( Player, pev_view_ofs, vf_ViewOfs )
  1420.    
  1421.     xs_vec_add( vf_Origin, vf_ViewOfs, flOrigin )
  1422. }
  1423.  
  1424. // Make vectors
  1425. UTIL_MakeVectors ( Player )
  1426. {
  1427.     static Float:flAngle[ 3 ], Float:flPunchAngle[ 3 ]
  1428.  
  1429.     pev( Player, pev_v_angle, flAngle )
  1430.     pev( Player, pev_punchangle, flPunchAngle )
  1431.  
  1432.     xs_vec_add( flAngle, flPunchAngle, flAngle )
  1433.     engfunc( EngFunc_MakeVectors, flAngle )
  1434. }
  1435.  
  1436. // From HL SDK.
  1437. VectorMA( Float:a[ ], Float:flScale, Float:b[ ], Float:c[ ] )
  1438. {
  1439.     c[ 0 ] = a[ 0 ] + flScale * b[ 0 ]
  1440.     c[ 1 ] = a[ 1 ] + flScale * b[ 1 ]
  1441.     c[ 2 ] = a[ 2 ] + flScale * b[ 2 ]
  1442. }
  1443.  
  1444. VectorMS( const Float:flSource[ ], const Float:flScale, const Float:flMult[ ], Float:flOutput[ ] )
  1445. {
  1446.         flOutput[ 0 ] = flSource[ 0 ] - flMult[ 0 ] * flScale
  1447.         flOutput[ 1 ] = flSource[ 1 ] - flMult[ 1 ] * flScale
  1448.         flOutput[ 2 ] = flSource[ 2 ] - flMult[ 2 ] * flScale
  1449. }
  1450.  
  1451. // Another stuff from HLSDK
  1452. Instance( iEnt )
  1453. {
  1454.     return iEnt == -1 ? 0 : iEnt
  1455. }
  1456.  
  1457. // Does this entity should refect gauss?
  1458. ReflectGauss( iEnt )
  1459. {
  1460.         return IsBSPModel( iEnt ) && pev( iEnt, pev_takedamage ) == DAMAGE_NO
  1461. }
  1462.  
  1463. // Does this entity is BSP model?
  1464. IsBSPModel( iEnt )
  1465. {
  1466.     return pev( iEnt, pev_solid ) == SOLID_BSP || pev( iEnt, pev_movetype ) == MOVETYPE_PUSHSTEP
  1467. }
  1468.  
  1469. // Add gun shot decal on world!
  1470. FX_GunShotDecal( Float:flPos[ ], pEntity )
  1471. {
  1472.     // Draw gunshot
  1473.     engfunc( EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, flPos, 0 )
  1474.     write_byte( TE_GUNSHOTDECAL ) // Temp.entity ID
  1475.     engfunc( EngFunc_WriteCoord, flPos[ 0 ] ) // Position X
  1476.     engfunc( EngFunc_WriteCoord, flPos[ 1 ] ) // Position Y
  1477.     engfunc( EngFunc_WriteCoord, flPos[ 2 ] ) // Position Z
  1478.     write_short( pEntity ) // Which entity to mark?
  1479.     write_byte( 43 ) // Decal number
  1480.     message_end( )
  1481. }
  1482.  
  1483. // Add glow sprite on world
  1484. FX_TempSprite( Float:flPos[ ], iScale, iSize )
  1485. {
  1486.     engfunc( EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, flPos, 0 )
  1487.     write_byte( TE_GLOWSPRITE ) // Temp.entity ID
  1488.     engfunc( EngFunc_WriteCoord, flPos[ 0 ] ) // Position X
  1489.     engfunc( EngFunc_WriteCoord, flPos[ 1 ] ) // Position Y
  1490.     engfunc( EngFunc_WriteCoord, flPos[ 2 ] ) // Position Z
  1491.     write_short( g_iBalls ) // Sprite index
  1492.     write_byte( iScale ) // Scale
  1493.     write_byte( iSize ) // Size
  1494.     write_byte( 255 ) // Brightness
  1495.     message_end( )
  1496. }
  1497.  
  1498. // Add sprite trail
  1499. FX_SpriteTrail( Float:vecStart[ ], Float:vecDest[ ], iCount, iLife, iScale, iVel, iRnd )
  1500. {
  1501.     message_begin( MSG_BROADCAST, SVC_TEMPENTITY )
  1502.     write_byte( TE_SPRITETRAIL ) // Sprite trail
  1503.     engfunc( EngFunc_WriteCoord, vecStart[ 0 ] ) // Position X
  1504.     engfunc( EngFunc_WriteCoord, vecStart[ 1 ] ) // Position Y
  1505.     engfunc( EngFunc_WriteCoord, vecStart[ 2 ] ) // Position Z
  1506.     engfunc( EngFunc_WriteCoord, vecDest[ 0 ] ) // Position X
  1507.     engfunc( EngFunc_WriteCoord, vecDest[ 1 ] ) // Position Y
  1508.     engfunc( EngFunc_WriteCoord, vecDest[ 2 ] ) // Position Z
  1509.     write_short( g_iBalls ) // SPrite index
  1510.     write_byte( iCount ) // Amount
  1511.     write_byte( iLife ) // Life
  1512.     write_byte( iScale ) // Scale
  1513.     write_byte( iVel ) // Velocity along vector
  1514.     write_byte( iRnd ) // Randomness of velocity
  1515.     message_end( )
  1516. }
Want your own mod edition? PM me.
Accepting private projects.
Discord: Fury#7469
Image

czirimbolo
Veteran Member
Veteran Member
Poland
Posts: 598
Joined: 7 years ago
Contact:

#12

Post by czirimbolo » 5 years ago

Jack, please edit Mark code, not mine
Image

czirimbolo
Veteran Member
Veteran Member
Poland
Posts: 598
Joined: 7 years ago
Contact:

#13

Post by czirimbolo » 5 years ago

Once again, can somene add to this gun making a damage to entities?

Code: Select all

#include < zombie_escape >
#include < engine >
#include < cstrike >
#include < csx >
#include < xs >
#include < fun >
 
// Plugin information
#define Plugin  "[ZE] Extra Item: Tau Cannon"
#define Version "1.2"
#define Author  "NiHiLaNTh"
 
// Maxplayers
const MaxPlayers = 32
 
// Weapon models
new const g_szModelGaussP[ ] = "models/p_gauss.mdl"
new const g_szModelGaussV[ ] = "models/v_alt_gauss.mdl"
new const g_szModelGaussW[ ] = "models/w_gauss.mdl"
 
// Weapon sounds
new const g_szSoundGaussFire[ ] = "weapons/gauss2.wav"
new const g_szSoundGaussSpin[ ] = "ambience/pulsemachine.wav"
new const g_szSoundElectro1[ ] = "weapons/electro4.wav"
new const g_szSoundElectro2[ ] = "weapons/electro5.wav"
new const g_szSoundElectro3[ ] = "weapons/electro6.wav"
 
// Some gauss/beam stuff
#define GAUSS_REFIRERATE    0.2 // Primary attack
#define GAUSS_REFIRERATE2   0.1 // Secondary attack(you shouldnt change this!)
#define GAUSS_RECOIL        -2.0 // Only X axis!
#define GAUSS_CHARGETIME    4.0 // From HLSDK
#define GAUSS_RELOADTIME    2.0 // Reload time
#define BEAM_RED        255 // Red amount
#define BEAM_GREEN      128 // Green amount
#define BEAM_BLUE       0 // Blue amount
#define BEAM_ALPHA      255 // Brightness(Alpha)
#define BALL_AMOUNT     8 // How many balls should appear :p
 
// Max. bp ammo amount
new const MAXBPAMMO[] = { -1, 52, -1, 90, 1, 32, 1, 100, 90, 1, 120, 100, 100, 90, 90, 90, 100, 120,
    5, 120, 200, // This is gauss max bp ammo.Change it if you want!
32, 90, 120, 90, 2, 35, 90, 90, -1, 100 }
 
// Player variables
new g_iHasGauss[ MaxPlayers+1 ] // Whether player has gauss
new g_iSoundState[ MaxPlayers+1 ] // Weapon sound state
new g_bInAttack[ MaxPlayers+1 ] // Current gauss attack state
new g_iCurrentWeapon[ MaxPlayers+1 ] // Current weapon player is holding
new Float:g_flLastShotTime[ MaxPlayers+1 ] // Last shot time
new Float:g_fflPlayAfterShock[ MaxPlayers+1 ] // Play aftershock sound
new Float:g_flWeaponIdleTime[ MaxPlayers+1 ] // Weapon idle time
new Float:g_flNextAmmoBurn[ MaxPlayers+1 ] // Next ammo burn time
new Float:g_flStartCharge[ MaxPlayers+1 ] // Weapon start charge
new Float:g_flAmmoStartCharge[ MaxPlayers+1 ] // Ammo start charge
new bool:g_bIsAlive[ MaxPlayers+1 ] // Whether player is alive
new bool:g_bIsConnected[ MaxPlayers+1 ] // Whether player is connected
new bool:g_bPrimaryFire[ MaxPlayers+1 ] // Does this weapon is using primary attack ?
new bool:g_bKilledByLaser[ MaxPlayers+1 ] // Imma firin mah lazor O.o
 
// CVAR pointers
new cvar_oneround // Whether gun should be only for 1 round
new cvar_dmgprim // Primary attack damage
new cvar_dmgsec // Secondary attack damage
new cvar_clip // Clip amount
 
// Cached CVAR
new g_pOneRound
new Float:g_pDmgPrim
new Float:g_pDmgSec
new g_pClip
 
// Global varibles
new g_iMaxPlayers // Maxplayers
new bool:g_bGameRestart // Detect game restart
new g_iBeam // Beam sprite
new g_iBalls // Balls :p
new g_iGaussID // Item ID
new gmsgScreenFade // Screen fade
 
// CS Offsets
const m_flNextPrimaryAttack = 46
const m_flNextSecondaryAttack = 47
const m_flTimeWeaponIdle = 48
const m_iPrimaryAmmoType = 49
const m_iClip = 51
const m_fInReload = 54
const m_rgAmmo_player_Slot0 = 376
 
// Macro
#define is_user_valid_connected(%1)     ( 1 <= %1 <= g_iMaxPlayers && g_bIsConnected [ %1 ] )
#define is_user_in_water(%1)            ( pev ( %1, pev_waterlevel ) == 3 )
#define VectorSubtract(%1,%2,%3)        ( %3[ 0 ] = %1[ 0 ] - %2[ 0 ], %3[ 1 ] = %1[ 1 ] - %2[ 1 ], %3[ 2 ] = %1[ 2 ] - %2[ 2 ] )
#define VectorAdd(%1,%2,%3)         ( %3[ 0 ] = %1[ 0 ] + %2[ 0 ], %3[ 1 ] = %1[ 1 ] + %2[ 2 ], %3[ 2 ] = %1[ 2 ] + %2[ 2 ] )
#define VectorScale(%1,%2,%3)           ( %3[ 0 ] = %2 * %1[ 0 ], %3[ 1 ] = %2 * %1[ 1 ], %3[ 2 ] = %2 * %1[ 2 ] )
#define VectorLength(%1)                ( floatsqroot ( %1[ 0 ] * %1[ 0 ] + %1[ 1 ] * %1[ 1 ] + %1[ 2 ] * %1[ 2 ] ) )
 
// Hack!Custom fields
#define pev_weaponkey       pev_impulse
#define pev_bpammo      pev_iuser3
 
// Misc stuff
#define FCVAR_FLAGS     ( FCVAR_SERVER | FCVAR_SPONLY | FCVAR_UNLOGGED )
#define GAUSS_WEAPONKEY 42856
#define NULLENT     -1
#define FFADE_IN        0x0000
#define UNIT_SECOND     (1<<12)
 
// Entity classnames
new const g_szClassPlayer[ ] = "player"
new const g_szClassM249[ ] = "weapon_m249"
 
// Primary weapon bitsum
const PRIMARY_WEAPONS_BITSUM = (1<<CSW_SCOUT)|(1<<CSW_XM1014)|(1<<CSW_MAC10)|(1<<CSW_AUG)|(1<<CSW_UMP45)|(1<<CSW_SG550)|(1<<CSW_GALIL)|(1<<CSW_FAMAS)|(1<<CSW_AWP)|(1<<CSW_MP5NAVY)|(1<<CSW_M249)|(1<<CSW_M3)|(1<<CSW_M4A1)|(1<<CSW_TMP)|(1<<CSW_G3SG1)|(1<<CSW_SG552)|(1<<CSW_AK47)|(1<<CSW_P90)
 
// Animation sequnces
enum
{
    gauss_idle,
    gauss_idle2,
    gauss_fidget,
    gauss_spinup,
    gauss_spin,
    gauss_fire,
    gauss_fire2,
    gauss_holster,
    gauss_draw
}
 
// Precache
public plugin_precache( )
{
    // Weapon models
    precache_model( g_szModelGaussP )
    precache_model( g_szModelGaussV )
    precache_model( g_szModelGaussW )
   
    // Sounds
    precache_sound( g_szSoundGaussFire )
    precache_sound( g_szSoundGaussSpin )
    precache_sound( g_szSoundElectro1 )
    precache_sound( g_szSoundElectro2 )
    precache_sound( g_szSoundElectro3 )
    precache_sound( "items/9mmclip1.wav" )
   
    // Sprites
    g_iBeam = precache_model( "sprites/smoke.spr" )
    g_iBalls = precache_model( "sprites/hotglow.spr" )
}
 
// Initialization
public plugin_init( )
{
    // New plugin
    register_plugin( Plugin, Version, Author )
   
    // For Game-Monitor support
    register_cvar( "ze_tcannon_version", Version, FCVAR_FLAGS )
   
    // New extra item
    g_iGaussID = ze_register_item("Tau Cannon", 30, 0)
   
    // Events
    register_event( "CurWeapon", "EV_CurWeapon", "be", "1=1" )
    register_event( "DeathMsg", "EV_DeathMsg", "a" )
    register_event( "HLTV", "EV_RoundStart", "a", "1=0", "2=0" )
    register_event( "TextMsg", "EV_GameRestart", "a", "2=#Game_Commencing", "2=#Game_will_restart_in" )
   
    // FakeMeta forwards
    register_forward( FM_SetModel, "fw_SetModel" )
    register_forward( FM_CmdStart, "fw_CmdStart" )
    register_forward( FM_UpdateClientData, "fw_UpdateClientData_Post", 1 )
    register_forward( FM_PlayerPreThink, "fw_PlayerPreThink" )
   
    // HamSandwich forwards
    RegisterHam( Ham_Spawn, g_szClassPlayer, "fw_PlayerSpawn_Post", 1 )
    RegisterHam( Ham_Item_Deploy, g_szClassM249, "fw_TCannonDeploy_Post", 1 )
    RegisterHam( Ham_Item_Holster, g_szClassM249, "fw_TCannonHolster_Post", 1 )
    RegisterHam( Ham_Item_AddToPlayer, g_szClassM249, "fw_TCannonAddToPlayer" )
    RegisterHam( Ham_Item_PostFrame, g_szClassM249, "fw_TCannonPostFrame" )
    RegisterHam( Ham_Weapon_Reload, g_szClassM249, "fw_TCannonReload_Post", 1 )
   
    // CVARs are in Load_Cvars( ) function!
   
    // Messages
    register_message( get_user_msgid( "DeathMsg" ), "fn_DeathMsg" )
    gmsgScreenFade = get_user_msgid( "ScreenFade" )
   
    // Store maxplayers in a global variable
    g_iMaxPlayers = get_maxplayers( )
}  
 
// Configuration
public plugin_cfg( )
{
    // Cache CVARs
    set_task( 1.5, "Load_Cvars" )
}
 
// ------------------------------- Game Events ----------------------------------------
 
// Client connected
public client_connect( Player )
{
    // Make a lot of updates
    g_iHasGauss[ Player ] = false
    g_bInAttack[ Player ] = 0
    g_fflPlayAfterShock[ Player ] = 0.0
    g_flWeaponIdleTime[ Player ] = 0.0
    g_bPrimaryFire[ Player ] = false
    g_bIsAlive[ Player ] = false
    g_bIsConnected[ Player ] = true
}
 
// Client disconnected
public client_disconnected( Player )
{
    // Only few important updates
    g_bIsAlive[ Player ] = false
    g_bIsConnected[ Player ] = false
}
 
public ze_select_item_pre(id, itemid)
{
    // Return Available and we will block it in Post, So it dosen't affect other plugins
    if (itemid != g_iGaussID)
        return ZE_ITEM_AVAILABLE
   
    // Available for Humans only, So don't show it for zombies
    if (ze_is_user_zombie(id))
        return ZE_ITEM_DONT_SHOW
   
    return ZE_ITEM_AVAILABLE
}
 
public ze_select_item_post(Player, itemid)
{
    if (itemid != g_iGaussID)
        return
 
    // Drop all primary weapons
    UTIL_DropPrimary( Player )
       
    // Update
    g_iHasGauss[ Player ] = true
       
    // Give m249
    give_item( Player, "weapon_m249" )
       
    // Find weapon entity
    new iEnt = find_ent_by_owner( NULLENT, g_szClassM249, Player )
       
    // Apply new clip
    cs_set_weapon_ammo( iEnt, g_pClip )
       
    // Back pack ammo
    cs_set_user_bpammo( Player, CSW_M249, MAXBPAMMO[ 20 ] )
}
 
// Current weapon player is holding
public EV_CurWeapon( Player )
{
    // Not alive
    if( !g_bIsAlive[ Player ] )
        return PLUGIN_CONTINUE
   
    // Update
    g_iCurrentWeapon[ Player ] = read_data( 2 )
   
    return PLUGIN_CONTINUE
}
 
// Someone died
public EV_DeathMsg( )
{
    // Get victim
    static iVictim
    iVictim = read_data( 2 )
   
    // Not connected
    if( !is_user_valid_connected( iVictim ) )
        return
   
    // Update
    g_bIsAlive[ iVictim ] = false
   
    // Check if victim has gauss
    if( g_iHasGauss[ iVictim ] && !is_user_bot( iVictim ) )
    {
        // Force to drop
        engclient_cmd( iVictim, "drop weapon_m249" )
    }
}
 
// Round started
public EV_RoundStart( )
{
    // Restart/One round only
    if( g_bGameRestart || g_pOneRound )
    {
        // Reset array value
        arrayset( g_iHasGauss, false, MaxPlayers+1 )
    }
   
    // Update
    g_bGameRestart = false
}
 
// Game restart
public EV_GameRestart( )
{
    // Update
    g_bGameRestart = true
}
 
// Hook death message
public fn_DeathMsg( Player, Dest, iEntity )
{
    // Get victim
    static iVictim, iKiller
    iKiller = get_msg_arg_int( 1 )
    iVictim = get_msg_arg_int( 2 )
   
    // Not connected
    if( !is_user_valid_connected( iVictim ) || iKiller == iVictim )
        return PLUGIN_CONTINUE
   
    // We were killed by laser
    if ( g_bKilledByLaser[ iVictim ] )
    {
        // Replace name in console
        set_msg_arg_string ( 4, "tau cannon" )
    }
    return PLUGIN_CONTINUE
}
 
// ------------------------------- Forwards ----------------------------------------
 
// Replace world model
public fw_SetModel ( Entity, const Model [ ] )
{
    // Prevent invalid entity messages
    if( !pev_valid( Entity ) )
        return FMRES_IGNORED
   
    // Not w_awp.mdl
    if( !equal( Model, "models/w_m249.mdl" ) )
        return FMRES_IGNORED
   
    // Get entity classname
    static szClassname[ 32 ]
    pev( Entity, pev_classname, szClassname, charsmax( szClassname ) )
   
    // Not weaponbox
    if( !equal( szClassname, "weaponbox" ) )
        return FMRES_IGNORED
   
    // Get owner
    static iOwner
    iOwner = pev( Entity, pev_owner )
   
    // Get awp ID
    static iWeaponID
    iWeaponID = find_ent_by_owner( NULLENT, g_szClassM249, Entity )
   
    // Make sure that we have gauss
    if( g_iHasGauss [ iOwner ] && is_valid_ent( iWeaponID ) )
    {
        // Hack! Store weaponkey
        set_pev( iWeaponID, pev_weaponkey, GAUSS_WEAPONKEY )
       
        // Hack! Store bp ammo
        set_pev( iWeaponID, pev_bpammo, cs_get_user_bpammo( iOwner, CSW_M249 ) )
       
        // Update
        g_iHasGauss[ iOwner ] = false
       
        // Replace models
        engfunc( EngFunc_SetModel, Entity, g_szModelGaussW )
        return FMRES_SUPERCEDE
    }
    return FMRES_IGNORED
}
 
// Command start
public fw_CmdStart( Player, UC_Handle, Seed )
{
    // Not alive/dont have gauss/not m249
    if( !g_bIsAlive[ Player ] || !g_iHasGauss[ Player ] || g_iCurrentWeapon[ Player ] != CSW_M249 )
        return FMRES_IGNORED
   
    // Retrieve pressed button bitsum
    static iButtons
    iButtons = get_uc( UC_Handle, UC_Buttons )
   
    // Retrieve game time
    static Float:flGameTime
    flGameTime = get_gametime( )
   
    // Retrieve weapon entity
    static iEnt
    iEnt = find_ent_by_owner( NULLENT, g_szClassM249, Player )
   
    // Retrieve clip amount
    static iClip
    iClip = cs_get_weapon_ammo( iEnt )
   
    // Primary attack
    if( iButtons & IN_ATTACK )
    {
        // Remove attack buttons from their button mask
        iButtons &= ~IN_ATTACK
        set_uc( UC_Handle, UC_Buttons, iButtons )
       
        // Prevent too fast shooting
        if( flGameTime - g_flLastShotTime[ Player ] < GAUSS_REFIRERATE )
            return FMRES_IGNORED
       
        // Dont fire while reloading
        if( get_pdata_int( iEnt, m_fInReload, 4 ) )
            return FMRES_IGNORED
       
        // Not enough clip/under water
        if( iClip < 2 || is_user_in_water( Player ) )
        {
            // Emit empty sound
            ExecuteHamB( Ham_Weapon_PlayEmptySound, iEnt )
            return FMRES_IGNORED
        }
       
        // Update
        g_bPrimaryFire[ Player ] = true
       
        // Start to fire
        StartFire( Player )
       
        // Decrease clip
        cs_set_weapon_ammo( iEnt, iClip-2 )
       
        // Reset weapon attack status
        g_bInAttack[ Player ] = 0
       
        // Set time when idle animation should be played
        g_flWeaponIdleTime[ Player ] = flGameTime + 1.0
       
        // Remember last shot time
        g_flLastShotTime[ Player ] = flGameTime
    }
    // Secondary attack
    else if( iButtons & IN_ATTACK2 )
    {
        // Prevent too fast shooting
        if( flGameTime - g_flLastShotTime[ Player ] < GAUSS_REFIRERATE2 )
            return FMRES_IGNORED
       
        // Dont fire while reloading
        if( get_pdata_int( iEnt, m_fInReload, 4 ) )
            return FMRES_IGNORED
       
        // Are we swimming ?
        if( is_user_in_water( Player ) )
        {
            // We are in a middle of attack
            if( g_bInAttack[ Player ] != 0 )
            {
                // Stop attack
                emit_sound( Player, CHAN_WEAPON, g_szSoundElectro1, VOL_NORM, ATTN_NORM, 0, 80 + random_num( 0, 0x3f ) )
               
                // Gun idle
                UTIL_PlayWeaponAnimation( Player, gauss_idle )
                return FMRES_IGNORED
            }
            else
            {
                // Empty sound
                ExecuteHamB( Ham_Weapon_PlayEmptySound, iEnt )
                return FMRES_IGNORED
            }
        }
       
        // Get player oldbuttons
        static iOldButtons
        iOldButtons = pev( Player, pev_oldbuttons )
       
        // Make sure that we are holding secondary attack button
        if( iOldButtons & IN_ATTACK2 )
        {
            // Which attack state do we have
            switch ( g_bInAttack[ Player ] )
            {
                case 0: // Attack start
                {
                    // Out of ammo
                    if ( iClip <= 0 )
                    {
                        ExecuteHamB( Ham_Weapon_PlayEmptySound, iEnt )
                        return FMRES_IGNORED
                    }
                   
                    // We aren't using primary attack anymore
                    g_bPrimaryFire[ Player ] = false
                   
                    // Decrease clip
                    cs_set_weapon_ammo( iEnt, --iClip )
                   
                    // Update
                    g_flNextAmmoBurn[ Player ] = flGameTime
                   
                    // Send spinup animation
                    UTIL_PlayWeaponAnimation( Player, gauss_spinup )
                   
                    // Update attack state
                    g_bInAttack[ Player ] = 1
                   
                    // Next idle time
                    g_flWeaponIdleTime[ Player ] = flGameTime + 0.5
                   
                    // Update
                    g_flStartCharge[ Player ] = flGameTime
                    g_flAmmoStartCharge[ Player ] = flGameTime + GAUSS_CHARGETIME
                   
                    // Update sound state
                    g_iSoundState[ Player ] = 0
                   
                    // Spin sound
                    emit_sound( Player, CHAN_WEAPON, g_szSoundGaussSpin, VOL_NORM, ATTN_NORM, g_iSoundState[Player ], 110 )
                   
                    // Change sound state
                    g_iSoundState[ Player ] = SND_CHANGE_PITCH
                }
                case 1: // In a middle of attack
                {
                    if( g_flWeaponIdleTime[ Player ] < flGameTime )
                    {
                        // Spin anim
                        UTIL_PlayWeaponAnimation( Player, gauss_spin )
                       
                        // Update state
                        g_bInAttack[ Player ] = 2
                    }
                }
                default: // End of attack
                {
                    // During the charging process, eat one bit of ammo every once in a while
                    if( flGameTime >= g_flNextAmmoBurn[ Player ] && g_flNextAmmoBurn[ Player ] != 1000 )
                    {
                        // Decrease clip
                        cs_set_weapon_ammo( iEnt, --iClip )
                       
                        // Next time when ammo should be decreased
                        g_flNextAmmoBurn[ Player ] = flGameTime + 0.1
                    }
                   
                    // Shit!We run out of ammo
                    if( iClip <= 0 )
                    {
                        // Force gun to fire
                        StartFire( Player )
                       
                        // Reset weapon state
                        g_bInAttack[ Player ] = 0
                       
                        // Set next idle time
                        g_flWeaponIdleTime[ Player ] = flGameTime + 1.0
                    }
                   
                    // Gun is fully charged up
                    if( flGameTime >= g_flAmmoStartCharge[ Player ] )
                    {
                        // Dont eat any more ammo!
                        g_flNextAmmoBurn[ Player ] = 1000.0
                    }
                   
                    // Calculate pitch
                    static Float:flPitch
                    flPitch = ( flGameTime - g_flStartCharge[ Player ] ) * ( 150 / GAUSS_CHARGETIME ) + 100
                   
                    // Pitch shouldnt be THAT big
                    if ( flPitch > 250 )
                    {
                        flPitch = 250.0
                    }
                   
                    // Spin sound
                    emit_sound( Player, CHAN_WEAPON, g_szSoundGaussSpin, VOL_NORM, ATTN_NORM, ( g_iSoundState[ Player ] == SND_CHANGE_PITCH ) ? 1 : 0, floatround( flPitch ) )
                   
                    // Hack for going through level transitions
                    g_iSoundState[ Player ] = SND_CHANGE_PITCH
                   
                    // We are charing way too long!
                    if( g_flStartCharge[ Player ] < flGameTime - 10 )
                    {
                        // ZAP!
                        emit_sound( Player, CHAN_WEAPON, g_szSoundElectro1, VOL_NORM, ATTN_NORM, 0, 80 + random_num( 0, 0x3f ) )
                        emit_sound( Player, CHAN_VOICE, g_szSoundElectro3, VOL_NORM, ATTN_NORM, 0, 80 + random_num( 0, 0x3f ) )
                       
                        // Reset fire state
                        g_bInAttack[ Player ] = 0
                       
                        // Next idle time
                        g_flWeaponIdleTime[ Player ] = flGameTime + 1.0
                       
                        // Damage player
                        ExecuteHamB( Ham_TakeDamage, Player, 0, Player, 50.0, DMG_SHOCK )
                       
                        // Make screen fade
                        UTIL_ScreenFade( Player, UNIT_SECOND*2, UNIT_SECOND/2, FFADE_IN, 255, 128, 0, 128 )
                       
                        // Idle animation
                        UTIL_PlayWeaponAnimation( Player, gauss_idle )
                    }
                }
            }
           
            // Update
            g_flLastShotTime[ Player ] = flGameTime
        }
    }
   
    return FMRES_HANDLED
}
 
// Update client data post
public fw_UpdateClientData_Post ( Player, SendWeapons, CD_Handle )
{
    // Not alive / dont have gauss/ not m249
    if ( !g_bIsAlive [ Player ] || !g_iHasGauss [ Player ] || g_iCurrentWeapon [ Player ] != CSW_M249 )
        return FMRES_IGNORED
   
    // Block default sounds/animations
    set_cd ( CD_Handle, CD_flNextAttack, halflife_time ( ) + 0.001 )
    return FMRES_HANDLED
}
 
// Player pre think
public fw_PlayerPreThink( Player )
{
    // Not alive / dont have gauss/ not m249
    if ( !g_bIsAlive [ Player ] || !g_iHasGauss [ Player ] || g_iCurrentWeapon [ Player ] != CSW_M249 )
        return
   
    // Play aftershock discharge
    if( g_fflPlayAfterShock[ Player ] && g_fflPlayAfterShock[ Player ] < get_gametime( ) )
    {
        // Randomly play sound
        switch( random_num(0, 3 ) )
        {
            case 0: emit_sound( Player, CHAN_WEAPON, g_szSoundElectro1,random_float( 0.7, 0.8 ), ATTN_NORM, 0, PITCH_NORM )
                case 1: emit_sound( Player, CHAN_WEAPON, g_szSoundElectro2,random_float( 0.7, 0.8 ), ATTN_NORM, 0, PITCH_NORM )
                case 2: emit_sound( Player, CHAN_WEAPON, g_szSoundElectro3,random_float( 0.7, 0.8 ), ATTN_NORM, 0, PITCH_NORM )
                case 3: return // No sound
            }
       
        // Reset discharge
        g_fflPlayAfterShock[ Player ] = 0.0
    }
   
    // Check if we are in a middle of attack
    if( g_bInAttack[ Player ] != 0 )
    {
        // Check if have released attack2 button
        if( get_gametime( ) - g_flLastShotTime[ Player ] > 0.2 )
        {
            // Start to fire
            StartFire( Player )
           
            // Reset attack state
            g_bInAttack[ Player ] = 0
           
            // Next idle time
            g_flWeaponIdleTime[ Player ] = get_gametime( ) + 2.0
        }
    }
    else
    {
        // Force to idle
        WeaponIdle( Player )
    }
}
 
// Player respawned
public fw_PlayerSpawn_Post( Player )
{
    // Not alive
    if( !is_user_alive( Player ) )
        return
   
    // Update
    g_bIsAlive[ Player ] = true
}
 
// Guass deploy
public fw_TCannonDeploy_Post( iEnt )
{
    // Get owner
    static Player
    Player = get_pdata_cbase( iEnt, 41, 4 )
   
    if(!is_user_valid_connected(Player) || !(get_user_weapon(Player) & CSW_M249))   return
   
    // Does this player has gauss?
    if ( g_iHasGauss[ Player ] )
    {
        // Replace models
        set_pev( Player, pev_viewmodel2, g_szModelGaussV )
        set_pev( Player, pev_weaponmodel2, g_szModelGaussP )
       
        // Deploy animation
        UTIL_PlayWeaponAnimation( Player, gauss_draw )
       
        // Reset aftershock
        g_fflPlayAfterShock[ Player ] = 0.0
    }
}
 
// Gauss holster
public fw_TCannonHolster_Post( iEnt )
{
    // Get owner
    static Player
    Player = get_pdata_cbase( iEnt, 41, 4 )
   
    // Does this player has gauss?
    if ( g_iHasGauss[ Player ] )
    {
        // Check if player is still attacking
        if( g_bInAttack[ Player ] )
        {
            // Bug!Bug!Stop spin sound
            emit_sound( Player, CHAN_WEAPON, g_szSoundGaussSpin, 0.0, 0.0, SND_STOP, 0 )
           
            // Attack
            StartFire( Player )
        }
       
        // Holster animation
        UTIL_PlayWeaponAnimation( Player, gauss_holster )
       
        // Reset attack status
        g_bInAttack[ Player ] = 0
    }
}
 
// Add Gauss to players inventory
public fw_TCannonAddToPlayer( iEnt, Player )
{
    // Prevent run-time errors
    if( is_valid_ent( iEnt ) && is_user_valid_connected( Player ) )
    {
        // Seems that player has picked up a gauss
        if( pev( iEnt, pev_weaponkey ) == GAUSS_WEAPONKEY )
        {
            // Update variable
            g_iHasGauss[ Player ] = true
           
            // Update bp ammo
            cs_set_user_bpammo( Player, CSW_M249, pev( iEnt, pev_bpammo ) )
           
            // Reset weapon options
            set_pev( iEnt, pev_weaponkey, 0 )
            set_pev( iEnt, pev_bpammo, 0 )
           
            return HAM_HANDLED
        }
    }
    return HAM_IGNORED
}
 
// Gauss post frame
public fw_TCannonPostFrame( iEnt )
{
    // Get owner
    static iOwner
    iOwner = get_pdata_cbase(iEnt, 41, 4)
   
    if(!is_valid_ent(iEnt) || !is_user_valid_connected(iOwner)) return
   
    // Does this player has gauss?
    if ( g_iHasGauss[ iOwner ] )
    {
        // Reload offset
        static fInReload
        fInReload = get_pdata_int ( iEnt, m_fInReload,4 )
       
        // Next attack time
        static Float:flNextAttack
        flNextAttack = get_pdata_float (iOwner, 83, 5)
       
        // Clip
        static iClip
        iClip = get_pdata_int ( iEnt, m_iClip, 4 )
       
        // Ammo type
        static iAmmoType
        iAmmoType = m_rgAmmo_player_Slot0 + get_pdata_int ( iEnt, m_iPrimaryAmmoType, 4 )
       
        // BP ammo
        static iBpAmmo
        iBpAmmo = get_pdata_int ( iOwner, iAmmoType, 5 )  
       
        // Reloading
        if ( fInReload && flNextAttack <= 0.0 )
        {
            // Calculate the difference
            static j
            j = min ( g_pClip - iClip, iBpAmmo )
           
            // Set new clip
            set_pdata_int ( iEnt, m_iClip, iClip + j, 4 )
           
            // Decrease 'x' bullets from backpack(depending on new clip)
            set_pdata_int( iOwner, iAmmoType, iBpAmmo-j, 5 )
           
            // Not reloding anymore
            set_pdata_int ( iEnt, m_fInReload, 0, 4 )
            fInReload = 0
        }
       
        // Get buttons
        static iButton ; iButton = pev ( iOwner, pev_button)
       
        // Attack/Attack2 buttons and next prim/sec attack time hasnt' come yet
        if( ( iButton & IN_ATTACK2 && get_pdata_float ( iEnt, m_flNextSecondaryAttack, 4 ) <= 0.0)
        || ( iButton & IN_ATTACK && get_pdata_float ( iEnt, m_flNextPrimaryAttack, 4 ) <= 0.0) )
        {
            return
        }
   
        // Reload button / not reloading
        if( iButton & IN_RELOAD && !fInReload )
        {
            // Old clip is more/equal than/to new
            if( iClip >= g_pClip )
            {
                // Remove reload button
                set_pev ( iOwner, pev_button, iButton & ~IN_RELOAD )
               
                // Idle animation
                UTIL_PlayWeaponAnimation ( iOwner, gauss_idle )
               
                // Idle time
                g_flWeaponIdleTime[ iOwner ] = get_gametime( ) + 0.5
            }
            else
            {
                // Out of ammo
                if ( !iBpAmmo )
                    return
                   
                // Reload weapon
                UTIL_WeaponReload ( iOwner, iEnt )
            }
        }
    }
}
 
// Gauss reload post
public fw_TCannonReload_Post( iEnt )
{
    // Get owner
    static Player
    Player = get_pdata_cbase( iEnt, 41, 4 )
   
    // Does this player has gauss and is he in a middle of reloading ?
    if ( g_iHasGauss[ Player ] && get_pdata_int( iEnt, m_fInReload, 4 ) )
    {
        // Reload
        UTIL_WeaponReload( Player, iEnt )
    }
}
 
// ------------------------------- Internal Functions ----------------------------------------
 
// Gauss start fire
public StartFire( Player )
{
    // This var holds damage
    static Float:flDamage
   
    // Make vectors
    UTIL_MakeVectors( Player )
   
    // Get gametime
    static Float:flGameTime
    flGameTime = get_gametime( )
   
    // This is maximal possible damage from secondary attack!
    if( flGameTime - g_flStartCharge[ Player ] > GAUSS_CHARGETIME )
    {
        flDamage = g_pDmgSec
    }
    else
    {
        // The longer you hold attack button - the bigger is damage
        flDamage = g_pDmgSec * ( ( flGameTime - g_flStartCharge[ Player ] ) / GAUSS_CHARGETIME )
    }
   
    // Primary attack do less damage
    if( g_bPrimaryFire[ Player ] )
    {
        flDamage = g_pDmgPrim
    }
   
    // Make sure that we are not ending attack
    if( g_bInAttack[ Player ] != 3 )
    {
        // Secondary attack can pop you up in the air.Not primary attack!
        if( !g_bPrimaryFire[ Player ] )
        {
            // Current players velocity
            static Float:flVel[ 3 ], Float:v_forward[ 3 ]
            pev( Player, pev_velocity, flVel )
            global_get( glb_v_forward, v_forward )
           
            // Try to affect only vertical velocity
            VectorMS( flVel, flDamage * 5.0, v_forward, flVel )
           
            // Jump!
            set_pev( Player, pev_velocity, flVel )
        }
    }
   
    // Recoil
    static Float:flRecoil[ 3 ]
    flRecoil[ 0 ] = GAUSS_RECOIL
    set_pev( Player, pev_punchangle, flRecoil )
   
    // Fire animation
    UTIL_PlayWeaponAnimation( Player, gauss_fire2 )
   
    // Fire sound
    static Float:flResult
    flResult = 0.5 + flDamage * ( 1.0 / 400.0 )
   
    if( flResult > 1.0 )
    {
        flResult = 1.0
    }
   
    emit_sound( Player, CHAN_WEAPON, g_szSoundGaussFire, flResult, ATTN_NORM, 0, 85 + random_num( 0, 0x1f ) )
   
    // Get players aimpoint position
    static Float:vecDest[ 3 ]
    global_get( glb_v_forward, vecDest )
   
    // Calculate start position
    static Float:vecSrc[ 3 ]
    UTIL_GetGunPosition( Player, vecSrc )
   
    // Time until aftershock 'static discharge' sound
    g_fflPlayAfterShock[ Player ] = flGameTime + random_float( 0.3, 0.8 )
   
    // Fire!
    Fire( Player, vecSrc, vecDest, flDamage )
}
 
// Fire!
Fire( Player, Float:vecOrigSrc[ ], Float:vecDir[ ], Float:flDamage )
{
    // Start position
    static Float:vecSrc[ 3 ]
    xs_vec_copy( vecOrigSrc, vecSrc )
   
    // Calculate end position
    static Float:vecDest[ 3 ]
    VectorMA( vecSrc, 8192.0, vecDir, vecDest )
   
    // Few trace handles
    static tr, beam_tr
   
    // Max fraction
    static Float:flMaxFrac
    flMaxFrac = 1.0
   
    // Total
    static nTotal
    nTotal = 0
   
    // Does this beam punched the wall ?
    static bool:fHasPunched
    fHasPunched = false
   
    // Does this is first beam
    static bool:fFirstBeam
    fFirstBeam = true
   
    // Max hits
    static nMaxHits
    nMaxHits = 10
   
    // Entity whoch should be ignored
    static pEntToIgnore
   
    // Make sure that beam will'be able to cause damage
    while( flDamage > 10 && nMaxHits > 0 )
    {
        // Decrease hit count
        nMaxHits--
       
        // Draw a trace line
        engfunc( EngFunc_TraceLine, vecSrc, vecDest, DONT_IGNORE_MONSTERS, pEntToIgnore, tr )
       
        // We'll never get outside!
        if( get_tr2( tr, TR_AllSolid ) )
            break
       
        // Get entity which was hit
        static pEntity
        pEntity = Instance( get_tr2( tr, TR_pHit ) )  
       
        // Get vector end position
        static Float:vecEnd[ 3 ]
        get_tr2( tr, TR_vecEndPos, vecEnd )
       
        // Its first beam  
        if( fFirstBeam )
        {
            // Add muzzleflash
            set_pev( Player, pev_effects, pev(Player, pev_effects) | EF_MUZZLEFLASH )
           
            // Its not first anymore
            fFirstBeam = false
           
            // Add
            nTotal += 26
           
            // Draw beam
            engfunc( EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, vecSrc, 0 )
            //message_begin( MSG_BROADCAST, SVC_TEMPENTITY )
            write_byte( TE_BEAMENTPOINT ) // Temp. entity ID
            write_short( Player | 0x1000 ) // Start entity
            engfunc( EngFunc_WriteCoord, vecEnd[ 0 ] ) // End position X
            engfunc( EngFunc_WriteCoord, vecEnd[ 1 ] ) // End position Y
            engfunc( EngFunc_WriteCoord, vecEnd[ 2 ] ) // End position Z
            write_short( g_iBeam ) // Sprite index
            write_byte( 0 ) // Start frame
            write_byte( 1 ) // Frame rate
            write_byte( 1 ) // Life
            write_byte( g_bPrimaryFire[ Player ] ? 16 : 25 ) // Line width
            write_byte( 0 ) // Noise amplitude
            write_byte( 255 )
            write_byte( 128 )
            write_byte( 0 )
            write_byte( 255 ) // Alpha
            write_byte( 0 ) // Scroll speed
            message_end( )
        }
        else
        {
            // Draw beam
            engfunc( EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, vecSrc, 0 )
            write_byte( TE_BEAMPOINTS ) // Temp. entity ID
            engfunc( EngFunc_WriteCoord, vecSrc[ 0 ] ) // Start position X
            engfunc( EngFunc_WriteCoord, vecSrc[ 1 ] ) // Start position Y
            engfunc( EngFunc_WriteCoord, vecSrc[ 2 ] ) // Start position Z
            engfunc( EngFunc_WriteCoord, vecEnd[ 0 ] ) // End position X
            engfunc( EngFunc_WriteCoord, vecEnd[ 1 ] ) // End position Y
            engfunc( EngFunc_WriteCoord, vecEnd[ 2 ] ) // End position Z
            write_short( g_iBeam ) // Sprite index
            write_byte( 0 ) // Start frame
            write_byte( 1 ) // Frame rate
            write_byte( 1 ) // Life
            write_byte( g_bPrimaryFire[ Player ] ? 15 : 25 ) // Line width
            write_byte( 0 ) // Noise amplitude
            write_byte( 255 )
            write_byte( 128 )
            write_byte( 0 )
            write_byte( 255 )
            write_byte( 0 ) // Scroll speed
            message_end( )
        }
       
        // Check if this entity should take any damage
        if( pev( pEntity, pev_takedamage ) != DAMAGE_NO )
        {
            // Check if this is player and zombie
            if( is_user_valid_connected( pEntity ) && ze_is_user_zombie( pEntity ) )
            {
                // Retrieve health
                static iHealth
                iHealth = get_user_health( pEntity )
           
                // We should be alive
                if( iHealth - flDamage >= 1 )
                {
                    // Cause some damage
                    ExecuteHamB( Ham_TakeDamage, pEntity, 0, Player, flDamage, DMG_BULLET | DMG_ALWAYSGIB )
                }
                else
                {
                    // Die
                    g_bKilledByLaser[ pEntity ] = true
                    ExecuteHamB( Ham_Killed, pEntity, Player, 2 )
                    g_bKilledByLaser[ pEntity ] = false
                }
            }
        }
       
        // Check if this entity should reflect our beam
        if( ReflectGauss( pEntity ) )
        {
            static Float:n
           
            // Return normal vector in a spot we hit
            static Float:vecPlaneNormal[ 3 ]
            get_tr2( tr, TR_vecPlaneNormal, vecPlaneNormal )
           
            // Calculate dot product
            n = - xs_vec_dot( vecPlaneNormal, vecDir )
           
            // 60 degrees
            if ( 0 < n < 0.5 )
            {
                static Float:r[ 3 ]
                VectorMA( vecDir, 2.0 * n, vecPlaneNormal, r )
               
                // Get vector end position
                get_tr2( tr, TR_vecEndPos, vecEnd )
               
                // Get trace fraction
                static Float:trflFraction
                get_tr2( tr, TR_flFraction, trflFraction )
               
                // Calculate fraction
                flMaxFrac = flMaxFrac - trflFraction
               
                // Copy vectors
                xs_vec_copy( r, vecDir )
               
                // Make more vector calculations
                VectorMA( vecEnd, 8.0, vecDir, vecSrc )
                VectorMA( vecSrc, 8192.0, vecDir, vecDest )
           
                // Undone!Do radius damage
               
                // Increase
                nTotal += 34
               
                if( n == 0 )
                {
                    // Lose energy
                    n = 0.1
                }
               
                // Calculate new damage
                flDamage = flDamage * ( 1 - n )
            }
            else
            {
                // Add gun shot decal on the world
                FX_GunShotDecal( vecEnd, pEntity )
               
                // Add glowing sprite on the world
                FX_TempSprite( vecEnd, 6, floatround( flDamage / 255.0 ) )
               
                // Increase
                nTotal += 13
               
                // Limit it to one hole punch
                if( fHasPunched )
                    break
               
                // Update  
                fHasPunched = true
               
                // Try punching through wall if secondary attack (primary is incapable of
                // breaking through)
                if( !g_bPrimaryFire[ Player ] )
                {
                    // Retrieve vector end position
                    get_tr2( tr, TR_vecEndPos, vecEnd )
                   
                    // Modify start origin
                    static Float:vecStart[ 3 ]
                    VectorMA( vecEnd, 8.0, vecDir, vecStart )
                   
                    // Draw another trace line
                    engfunc( EngFunc_TraceLine, vecSrc, vecDest, DONT_IGNORE_MONSTERS, pEntToIgnore, beam_tr )
                   
                    // We'll never get outside
                    if( !get_tr2( beam_tr, TR_AllSolid ) )
                    {
                        // Get end position
                        static Float:vecBeamEndPos[ 3 ]
                        get_tr2( beam_tr, TR_vecEndPos, vecBeamEndPos )
                       
                        // Trace backwards to find exit point
                        engfunc( EngFunc_TraceLine, vecBeamEndPos, vecEnd, DONT_IGNORE_MONSTERS, pEntToIgnore, beam_tr )
                       
                        // Again get end position
                        get_tr2( beam_tr, TR_vecEndPos, vecBeamEndPos )
                       
                        static Float:ns, Float:vecSub[ 3 ]
                       
                        // Subtract vectors
                        xs_vec_sub( vecBeamEndPos, vecEnd, vecSub )
                       
                        // Get vector length
                        ns = xs_vec_len( vecSub )
                       
                        if( ns < flDamage )
                        {
                            // Lose enery
                            if( ns == 0 )
                            {
                                ns = 1.0
                            }
                           
                            // Decrease damage
                            flDamage -= ns
                           
                            // Subtract
                            static Float:vecCalc[ 3 ]
                            VectorSubtract( vecEnd, vecDir, vecCalc )
                           
                            // Absorbtion balls
                            FX_SpriteTrail( vecEnd, vecCalc, BALL_AMOUNT, 15, 3, 25, 25 )
                           
                            // Add gun shot decal on the world
                            FX_GunShotDecal( vecBeamEndPos, pEntity )
                           
                            // And glowing sprite
                            FX_TempSprite( vecBeamEndPos, 6, floatround( flDamage / 255.0 ) )
                           
                            // Subtract
                            VectorSubtract( vecBeamEndPos, vecDir, vecCalc )
                           
                            // Absorbtion balls
                            FX_SpriteTrail( vecEnd, vecCalc, BALL_AMOUNT, 15, 3, 25, 25 )
                           
                            // Increase shit
                            nTotal += 21
                           
                            /*
                            // Calculate radius damage
                            static Float:flRadDmg
                            flRadDmg = flDamage * 1.75
                           
                            // Undone.Do radius damage here!
                            floatradius( flDamage, flRadDmg, vecBeamEndPos )
                            */
                           
                            // Increase
                            nTotal += 53
                           
                            VectorMA( vecBeamEndPos, 8.0, vecDir, vecSub )
                           
                            // Add up vector
                            xs_vec_add( vecBeamEndPos, vecDir, vecSrc )
                        }
                    }
                    else
                    {
                        flDamage = 0.0
                    }
                }
                else
                {
                    // Primary attack
                    if( g_bPrimaryFire [ Player ] )
                    {
                        // Slug doesn't punch through ever with primary
                        // fire, so leave a little glowy bit and make some balls
                        FX_TempSprite( vecEnd, 6, floatround( flDamage / 255.0 ) )
                        FX_SpriteTrail( vecEnd, vecDir, BALL_AMOUNT, 15, 3, 25, 25 )
                    }
                   
                    flDamage = 0.0
                }
            }
        }
        else
        {
            // Add up vector
            xs_vec_add( vecEnd, vecDir, vecSrc )
            pEntToIgnore = pEntity
        }
    }
}              
 
// Register and cache CVARs
public Load_Cvars( )
{
    cvar_oneround = register_cvar( "ze_tcannon_oneround", "0" )
    cvar_dmgprim = register_cvar( "ze_tcannon_dmgprim", "200" )
    cvar_dmgsec = register_cvar( "ze_tcannon_dmgsec", "500" )
    cvar_clip = register_cvar( "ze_tcannon_clip", "100" )
   
    g_pOneRound = get_pcvar_num( cvar_oneround )
    g_pDmgPrim = get_pcvar_float( cvar_dmgprim )
    g_pDmgSec = get_pcvar_float( cvar_dmgsec )
    g_pClip = get_pcvar_num( cvar_clip )
}
 
// Gauss weapon idle
WeaponIdle( Player )
{
    // Get gametime
    static Float:flGameTime
    flGameTime = get_gametime( )
   
    if( g_flWeaponIdleTime[ Player ] > flGameTime )
        return
   
    // Animation sequence variable
    static iAnim
   
    // Animation randomizer
    static Float:flRand
    flRand = random_float( 0.1, 1.0 )
   
    if( flRand <= 0.5 )
    {
        iAnim = gauss_idle
        g_flWeaponIdleTime[ Player ] = flGameTime + random_float( 10.0, 15.0 )
    }
    else if( flRand <= 0.75 )
    {
        iAnim = gauss_idle2
        g_flWeaponIdleTime[ Player ] = flGameTime + random_float( 10.0, 15.0 )
    }
    else
    {
        iAnim = gauss_fidget
        g_flWeaponIdleTime[ Player ] = flGameTime + 3
    }
   
    // Idle
    UTIL_PlayWeaponAnimation( Player, iAnim )
}  
 
// Play weapon animation
UTIL_PlayWeaponAnimation( const Player, const Sequence )
{
    set_pev( Player, pev_weaponanim, Sequence )
   
    message_begin( MSG_ONE_UNRELIABLE, SVC_WEAPONANIM, .player = Player )
    write_byte( Sequence )
    write_byte( pev( Player, pev_body ) )
    message_end( )
}              
 
// Make ScreenFade
UTIL_ScreenFade( Player, Duration, HoldTime, Flags, iRed, iGreen, iBlue, iAlpha )
{
    message_begin( MSG_ONE, gmsgScreenFade, _, Player )
    write_short( Duration )
    write_short( HoldTime )
    write_short( Flags )
    write_byte( iRed )
    write_byte( iGreen )
    write_byte( iBlue )
    write_byte( iAlpha )
    message_end( )
}
 
// Reload gauss
UTIL_WeaponReload( Player, iEnt )
{
    // Modify time until next attack
    set_pdata_float( Player, 83, GAUSS_RELOADTIME+0.5, 5 )
   
    // Reload animation
    UTIL_PlayWeaponAnimation( Player, gauss_spin )
   
    // Enable reload offset
    set_pdata_int( iEnt, m_fInReload, 1, 4 )
   
    // Modify next idle time
    g_flWeaponIdleTime[ Player ] = get_gametime( ) + GAUSS_RELOADTIME + 1.0
}
 
// Drop all primary weapons
UTIL_DropPrimary( Player )
{
    // Get user weapons
    static weapons[ 32 ], num, i, weaponid
    num = 0 // reset passed weapons count (bugfix)
    get_user_weapons( Player, weapons, num )
   
    // Loop through them and drop primaries
    for( i = 0; i < num; i++ )
    {
        // Prevent re-indexing the array
        weaponid = weapons[ i ]
       
        // We definetely are holding primary gun
        if(( (1<<weaponid) & PRIMARY_WEAPONS_BITSUM ) )    
        {
            // Get weapon entity
            static wname[32]
            get_weaponname(weaponid, wname, charsmax(wname))
           
            // Player drops the weapon and looses his bpammo
            engclient_cmd( Player, "drop", wname)
        }
    }
}
 
// Get gun position
UTIL_GetGunPosition( Player, Float:flOrigin[ ] )
{
    static Float:vf_Origin[ 3 ], Float:vf_ViewOfs[ 3 ]
   
    pev( Player, pev_origin, vf_Origin )
    pev( Player, pev_view_ofs, vf_ViewOfs )
   
    xs_vec_add( vf_Origin, vf_ViewOfs, flOrigin )
}
 
// Make vectors
UTIL_MakeVectors ( Player )
{
    static Float:flAngle[ 3 ], Float:flPunchAngle[ 3 ]
 
    pev( Player, pev_v_angle, flAngle )
    pev( Player, pev_punchangle, flPunchAngle )
 
    xs_vec_add( flAngle, flPunchAngle, flAngle )
    engfunc( EngFunc_MakeVectors, flAngle )
}
 
// From HL SDK.
VectorMA( Float:a[ ], Float:flScale, Float:b[ ], Float:c[ ] )
{
    c[ 0 ] = a[ 0 ] + flScale * b[ 0 ]
    c[ 1 ] = a[ 1 ] + flScale * b[ 1 ]
    c[ 2 ] = a[ 2 ] + flScale * b[ 2 ]
}
 
VectorMS( const Float:flSource[ ], const Float:flScale, const Float:flMult[ ], Float:flOutput[ ] )
{
        flOutput[ 0 ] = flSource[ 0 ] - flMult[ 0 ] * flScale
        flOutput[ 1 ] = flSource[ 1 ] - flMult[ 1 ] * flScale
        flOutput[ 2 ] = flSource[ 2 ] - flMult[ 2 ] * flScale
}
 
// Another stuff from HLSDK
Instance( iEnt )
{
    return iEnt == -1 ? 0 : iEnt
}
 
// Does this entity should refect gauss?
ReflectGauss( iEnt )
{
        return IsBSPModel( iEnt ) && pev( iEnt, pev_takedamage ) == DAMAGE_NO
}
 
// Does this entity is BSP model?
IsBSPModel( iEnt )
{
    return pev( iEnt, pev_solid ) == SOLID_BSP || pev( iEnt, pev_movetype ) == MOVETYPE_PUSHSTEP
}
 
// Add gun shot decal on world!
FX_GunShotDecal( Float:flPos[ ], pEntity )
{
    // Draw gunshot
    engfunc( EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, flPos, 0 )
    write_byte( TE_GUNSHOTDECAL ) // Temp.entity ID
    engfunc( EngFunc_WriteCoord, flPos[ 0 ] ) // Position X
    engfunc( EngFunc_WriteCoord, flPos[ 1 ] ) // Position Y
    engfunc( EngFunc_WriteCoord, flPos[ 2 ] ) // Position Z
    write_short( pEntity ) // Which entity to mark?
    write_byte( 43 ) // Decal number
    message_end( )
}
 
// Add glow sprite on world
FX_TempSprite( Float:flPos[ ], iScale, iSize )
{
    engfunc( EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, flPos, 0 )
    write_byte( TE_GLOWSPRITE ) // Temp.entity ID
    engfunc( EngFunc_WriteCoord, flPos[ 0 ] ) // Position X
    engfunc( EngFunc_WriteCoord, flPos[ 1 ] ) // Position Y
    engfunc( EngFunc_WriteCoord, flPos[ 2 ] ) // Position Z
    write_short( g_iBalls ) // Sprite index
    write_byte( iScale ) // Scale
    write_byte( iSize ) // Size
    write_byte( 255 ) // Brightness
    message_end( )
}
 
// Add sprite trail
FX_SpriteTrail( Float:vecStart[ ], Float:vecDest[ ], iCount, iLife, iScale, iVel, iRnd )
{
    message_begin( MSG_BROADCAST, SVC_TEMPENTITY )
    write_byte( TE_SPRITETRAIL ) // Sprite trail
    engfunc( EngFunc_WriteCoord, vecStart[ 0 ] ) // Position X
    engfunc( EngFunc_WriteCoord, vecStart[ 1 ] ) // Position Y
    engfunc( EngFunc_WriteCoord, vecStart[ 2 ] ) // Position Z
    engfunc( EngFunc_WriteCoord, vecDest[ 0 ] ) // Position X
    engfunc( EngFunc_WriteCoord, vecDest[ 1 ] ) // Position Y
    engfunc( EngFunc_WriteCoord, vecDest[ 2 ] ) // Position Z
    write_short( g_iBalls ) // SPrite index
    write_byte( iCount ) // Amount
    write_byte( iLife ) // Life
    write_byte( iScale ) // Scale
    write_byte( iVel ) // Velocity along vector
    write_byte( iRnd ) // Randomness of velocity
    message_end( )
}
Image

User avatar
Raheem
Mod Developer
Mod Developer
Posts: 2214
Joined: 7 years ago
Contact:

#14

Post by Raheem » 5 years ago

Try:

  1. #include < zombie_escape >
  2. #include < engine >
  3. #include < cstrike >
  4. #include < csx >
  5. #include < xs >
  6. #include < fun >
  7.  
  8. // Plugin information
  9. #define Plugin  "[ZE] Extra Item: Tau Cannon"
  10. #define Version "1.2"
  11. #define Author  "NiHiLaNTh"
  12.  
  13. // Maxplayers
  14. const MaxPlayers = 32
  15.  
  16. // Weapon models
  17. new const g_szModelGaussP[ ] = "models/p_gauss.mdl"
  18. new const g_szModelGaussV[ ] = "models/v_alt_gauss.mdl"
  19. new const g_szModelGaussW[ ] = "models/w_gauss.mdl"
  20.  
  21. // Weapon sounds
  22. new const g_szSoundGaussFire[ ] = "weapons/gauss2.wav"
  23. new const g_szSoundGaussSpin[ ] = "ambience/pulsemachine.wav"
  24. new const g_szSoundElectro1[ ] = "weapons/electro4.wav"
  25. new const g_szSoundElectro2[ ] = "weapons/electro5.wav"
  26. new const g_szSoundElectro3[ ] = "weapons/electro6.wav"
  27.  
  28. // Some gauss/beam stuff
  29. #define GAUSS_REFIRERATE    0.2 // Primary attack
  30. #define GAUSS_REFIRERATE2   0.1 // Secondary attack(you shouldnt change this!)
  31. #define GAUSS_RECOIL        -2.0 // Only X axis!
  32. #define GAUSS_CHARGETIME    4.0 // From HLSDK
  33. #define GAUSS_RELOADTIME    2.0 // Reload time
  34. #define BEAM_RED        255 // Red amount
  35. #define BEAM_GREEN      128 // Green amount
  36. #define BEAM_BLUE       0 // Blue amount
  37. #define BEAM_ALPHA      255 // Brightness(Alpha)
  38. #define BALL_AMOUNT     8 // How many balls should appear :p
  39.  
  40. // Max. bp ammo amount
  41. new const MAXBPAMMO[] = { -1, 52, -1, 90, 1, 32, 1, 100, 90, 1, 120, 100, 100, 90, 90, 90, 100, 120,
  42.     5, 120, 200, // This is gauss max bp ammo.Change it if you want!
  43. 32, 90, 120, 90, 2, 35, 90, 90, -1, 100 }
  44.  
  45. // Player variables
  46. new g_iHasGauss[ MaxPlayers+1 ] // Whether player has gauss
  47. new g_iSoundState[ MaxPlayers+1 ] // Weapon sound state
  48. new g_bInAttack[ MaxPlayers+1 ] // Current gauss attack state
  49. new g_iCurrentWeapon[ MaxPlayers+1 ] // Current weapon player is holding
  50. new Float:g_flLastShotTime[ MaxPlayers+1 ] // Last shot time
  51. new Float:g_fflPlayAfterShock[ MaxPlayers+1 ] // Play aftershock sound
  52. new Float:g_flWeaponIdleTime[ MaxPlayers+1 ] // Weapon idle time
  53. new Float:g_flNextAmmoBurn[ MaxPlayers+1 ] // Next ammo burn time
  54. new Float:g_flStartCharge[ MaxPlayers+1 ] // Weapon start charge
  55. new Float:g_flAmmoStartCharge[ MaxPlayers+1 ] // Ammo start charge
  56. new bool:g_bIsAlive[ MaxPlayers+1 ] // Whether player is alive
  57. new bool:g_bIsConnected[ MaxPlayers+1 ] // Whether player is connected
  58. new bool:g_bPrimaryFire[ MaxPlayers+1 ] // Does this weapon is using primary attack ?
  59. new bool:g_bKilledByLaser[ MaxPlayers+1 ] // Imma firin mah lazor O.o
  60.  
  61. // CVAR pointers
  62. new cvar_oneround // Whether gun should be only for 1 round
  63. new cvar_dmgprim // Primary attack damage
  64. new cvar_dmgsec // Secondary attack damage
  65. new cvar_clip // Clip amount
  66.  
  67. // Cached CVAR
  68. new g_pOneRound
  69. new Float:g_pDmgPrim
  70. new Float:g_pDmgSec
  71. new g_pClip
  72.  
  73. // Global varibles
  74. new g_iMaxPlayers // Maxplayers
  75. new bool:g_bGameRestart // Detect game restart
  76. new g_iBeam // Beam sprite
  77. new g_iBalls // Balls :p
  78. new g_iGaussID // Item ID
  79. new gmsgScreenFade // Screen fade
  80.  
  81. // CS Offsets
  82. const m_flNextPrimaryAttack = 46
  83. const m_flNextSecondaryAttack = 47
  84. const m_flTimeWeaponIdle = 48
  85. const m_iPrimaryAmmoType = 49
  86. const m_iClip = 51
  87. const m_fInReload = 54
  88. const m_rgAmmo_player_Slot0 = 376
  89.  
  90. // Macro
  91. #define is_user_valid_connected(%1)     ( 1 <= %1 <= g_iMaxPlayers && g_bIsConnected [ %1 ] )
  92. #define is_user_in_water(%1)            ( pev ( %1, pev_waterlevel ) == 3 )
  93. #define VectorSubtract(%1,%2,%3)        ( %3[ 0 ] = %1[ 0 ] - %2[ 0 ], %3[ 1 ] = %1[ 1 ] - %2[ 1 ], %3[ 2 ] = %1[ 2 ] - %2[ 2 ] )
  94. #define VectorAdd(%1,%2,%3)         ( %3[ 0 ] = %1[ 0 ] + %2[ 0 ], %3[ 1 ] = %1[ 1 ] + %2[ 2 ], %3[ 2 ] = %1[ 2 ] + %2[ 2 ] )
  95. #define VectorScale(%1,%2,%3)           ( %3[ 0 ] = %2 * %1[ 0 ], %3[ 1 ] = %2 * %1[ 1 ], %3[ 2 ] = %2 * %1[ 2 ] )
  96. #define VectorLength(%1)                ( floatsqroot ( %1[ 0 ] * %1[ 0 ] + %1[ 1 ] * %1[ 1 ] + %1[ 2 ] * %1[ 2 ] ) )
  97.  
  98. // Hack!Custom fields
  99. #define pev_weaponkey       pev_impulse
  100. #define pev_bpammo      pev_iuser3
  101.  
  102. // Misc stuff
  103. #define FCVAR_FLAGS     ( FCVAR_SERVER | FCVAR_SPONLY | FCVAR_UNLOGGED )
  104. #define GAUSS_WEAPONKEY 42856
  105. #define NULLENT     -1
  106. #define FFADE_IN        0x0000
  107. #define UNIT_SECOND     (1<<12)
  108.  
  109. // Entity classnames
  110. new const g_szClassPlayer[ ] = "player"
  111. new const g_szClassM249[ ] = "weapon_m249"
  112.  
  113. // Primary weapon bitsum
  114. const PRIMARY_WEAPONS_BITSUM = (1<<CSW_SCOUT)|(1<<CSW_XM1014)|(1<<CSW_MAC10)|(1<<CSW_AUG)|(1<<CSW_UMP45)|(1<<CSW_SG550)|(1<<CSW_GALIL)|(1<<CSW_FAMAS)|(1<<CSW_AWP)|(1<<CSW_MP5NAVY)|(1<<CSW_M249)|(1<<CSW_M3)|(1<<CSW_M4A1)|(1<<CSW_TMP)|(1<<CSW_G3SG1)|(1<<CSW_SG552)|(1<<CSW_AK47)|(1<<CSW_P90)
  115.  
  116. // Animation sequnces
  117. enum
  118. {
  119.     gauss_idle,
  120.     gauss_idle2,
  121.     gauss_fidget,
  122.     gauss_spinup,
  123.     gauss_spin,
  124.     gauss_fire,
  125.     gauss_fire2,
  126.     gauss_holster,
  127.     gauss_draw
  128. }
  129.  
  130. // Precache
  131. public plugin_precache( )
  132. {
  133.     // Weapon models
  134.     precache_model( g_szModelGaussP )
  135.     precache_model( g_szModelGaussV )
  136.     precache_model( g_szModelGaussW )
  137.    
  138.     // Sounds
  139.     precache_sound( g_szSoundGaussFire )
  140.     precache_sound( g_szSoundGaussSpin )
  141.     precache_sound( g_szSoundElectro1 )
  142.     precache_sound( g_szSoundElectro2 )
  143.     precache_sound( g_szSoundElectro3 )
  144.     precache_sound( "items/9mmclip1.wav" )
  145.    
  146.     // Sprites
  147.     g_iBeam = precache_model( "sprites/smoke.spr" )
  148.     g_iBalls = precache_model( "sprites/hotglow.spr" )
  149. }
  150.  
  151. // Initialization
  152. public plugin_init( )
  153. {
  154.     // New plugin
  155.     register_plugin( Plugin, Version, Author )
  156.    
  157.     // For Game-Monitor support
  158.     register_cvar( "ze_tcannon_version", Version, FCVAR_FLAGS )
  159.    
  160.     // New extra item
  161.     g_iGaussID = ze_register_item("Tau Cannon", 30, 0)
  162.    
  163.     // Events
  164.     register_event( "CurWeapon", "EV_CurWeapon", "be", "1=1" )
  165.     register_event( "DeathMsg", "EV_DeathMsg", "a" )
  166.     register_event( "HLTV", "EV_RoundStart", "a", "1=0", "2=0" )
  167.     register_event( "TextMsg", "EV_GameRestart", "a", "2=#Game_Commencing", "2=#Game_will_restart_in" )
  168.    
  169.     // FakeMeta forwards
  170.     register_forward( FM_SetModel, "fw_SetModel" )
  171.     register_forward( FM_CmdStart, "fw_CmdStart" )
  172.     register_forward( FM_UpdateClientData, "fw_UpdateClientData_Post", 1 )
  173.     register_forward( FM_PlayerPreThink, "fw_PlayerPreThink" )
  174.    
  175.     // HamSandwich forwards
  176.     RegisterHam( Ham_Spawn, g_szClassPlayer, "fw_PlayerSpawn_Post", 1 )
  177.     RegisterHam( Ham_Item_Deploy, g_szClassM249, "fw_TCannonDeploy_Post", 1 )
  178.     RegisterHam( Ham_Item_Holster, g_szClassM249, "fw_TCannonHolster_Post", 1 )
  179.     RegisterHam( Ham_Item_AddToPlayer, g_szClassM249, "fw_TCannonAddToPlayer" )
  180.     RegisterHam( Ham_Item_PostFrame, g_szClassM249, "fw_TCannonPostFrame" )
  181.     RegisterHam( Ham_Weapon_Reload, g_szClassM249, "fw_TCannonReload_Post", 1 )
  182.    
  183.     // CVARs are in Load_Cvars( ) function!
  184.    
  185.     // Messages
  186.     register_message( get_user_msgid( "DeathMsg" ), "fn_DeathMsg" )
  187.     gmsgScreenFade = get_user_msgid( "ScreenFade" )
  188.    
  189.     // Store maxplayers in a global variable
  190.     g_iMaxPlayers = get_maxplayers( )
  191. }  
  192.  
  193. // Configuration
  194. public plugin_cfg( )
  195. {
  196.     // Cache CVARs
  197.     set_task( 1.5, "Load_Cvars" )
  198. }
  199.  
  200. // ------------------------------- Game Events ----------------------------------------
  201.  
  202. // Client connected
  203. public client_connect( Player )
  204. {
  205.     // Make a lot of updates
  206.     g_iHasGauss[ Player ] = false
  207.     g_bInAttack[ Player ] = 0
  208.     g_fflPlayAfterShock[ Player ] = 0.0
  209.     g_flWeaponIdleTime[ Player ] = 0.0
  210.     g_bPrimaryFire[ Player ] = false
  211.     g_bIsAlive[ Player ] = false
  212.     g_bIsConnected[ Player ] = true
  213. }
  214.  
  215. // Client disconnected
  216. public client_disconnected( Player )
  217. {
  218.     // Only few important updates
  219.     g_bIsAlive[ Player ] = false
  220.     g_bIsConnected[ Player ] = false
  221. }
  222.  
  223. public ze_select_item_pre(id, itemid)
  224. {
  225.     // Return Available and we will block it in Post, So it dosen't affect other plugins
  226.     if (itemid != g_iGaussID)
  227.         return ZE_ITEM_AVAILABLE
  228.    
  229.     // Available for Humans only, So don't show it for zombies
  230.     if (ze_is_user_zombie(id))
  231.         return ZE_ITEM_DONT_SHOW
  232.    
  233.     return ZE_ITEM_AVAILABLE
  234. }
  235.  
  236. public ze_select_item_post(Player, itemid)
  237. {
  238.     if (itemid != g_iGaussID)
  239.         return
  240.  
  241.     // Drop all primary weapons
  242.     UTIL_DropPrimary( Player )
  243.        
  244.     // Update
  245.     g_iHasGauss[ Player ] = true
  246.        
  247.     // Give m249
  248.     give_item( Player, "weapon_m249" )
  249.        
  250.     // Find weapon entity
  251.     new iEnt = find_ent_by_owner( NULLENT, g_szClassM249, Player )
  252.        
  253.     // Apply new clip
  254.     cs_set_weapon_ammo( iEnt, g_pClip )
  255.        
  256.     // Back pack ammo
  257.     cs_set_user_bpammo( Player, CSW_M249, MAXBPAMMO[ 20 ] )
  258. }
  259.  
  260. // Current weapon player is holding
  261. public EV_CurWeapon( Player )
  262. {
  263.     // Not alive
  264.     if( !g_bIsAlive[ Player ] )
  265.         return PLUGIN_CONTINUE
  266.    
  267.     // Update
  268.     g_iCurrentWeapon[ Player ] = read_data( 2 )
  269.    
  270.     return PLUGIN_CONTINUE
  271. }
  272.  
  273. // Someone died
  274. public EV_DeathMsg( )
  275. {
  276.     // Get victim
  277.     static iVictim
  278.     iVictim = read_data( 2 )
  279.    
  280.     // Not connected
  281.     if( !is_user_valid_connected( iVictim ) )
  282.         return
  283.    
  284.     // Update
  285.     g_bIsAlive[ iVictim ] = false
  286.    
  287.     // Check if victim has gauss
  288.     if( g_iHasGauss[ iVictim ] && !is_user_bot( iVictim ) )
  289.     {
  290.         // Force to drop
  291.         engclient_cmd( iVictim, "drop weapon_m249" )
  292.     }
  293. }
  294.  
  295. // Round started
  296. public EV_RoundStart( )
  297. {
  298.     // Restart/One round only
  299.     if( g_bGameRestart || g_pOneRound )
  300.     {
  301.         // Reset array value
  302.         arrayset( g_iHasGauss, false, MaxPlayers+1 )
  303.     }
  304.    
  305.     // Update
  306.     g_bGameRestart = false
  307. }
  308.  
  309. // Game restart
  310. public EV_GameRestart( )
  311. {
  312.     // Update
  313.     g_bGameRestart = true
  314. }
  315.  
  316. // Hook death message
  317. public fn_DeathMsg( Player, Dest, iEntity )
  318. {
  319.     // Get victim
  320.     static iVictim, iKiller
  321.     iKiller = get_msg_arg_int( 1 )
  322.     iVictim = get_msg_arg_int( 2 )
  323.    
  324.     // Not connected
  325.     if( !is_user_valid_connected( iVictim ) || iKiller == iVictim )
  326.         return PLUGIN_CONTINUE
  327.    
  328.     // We were killed by laser
  329.     if ( g_bKilledByLaser[ iVictim ] )
  330.     {
  331.         // Replace name in console
  332.         set_msg_arg_string ( 4, "tau cannon" )
  333.     }
  334.     return PLUGIN_CONTINUE
  335. }
  336.  
  337. // ------------------------------- Forwards ----------------------------------------
  338.  
  339. // Replace world model
  340. public fw_SetModel ( Entity, const Model [ ] )
  341. {
  342.     // Prevent invalid entity messages
  343.     if( !pev_valid( Entity ) )
  344.         return FMRES_IGNORED
  345.    
  346.     // Not w_awp.mdl
  347.     if( !equal( Model, "models/w_m249.mdl" ) )
  348.         return FMRES_IGNORED
  349.    
  350.     // Get entity classname
  351.     static szClassname[ 32 ]
  352.     pev( Entity, pev_classname, szClassname, charsmax( szClassname ) )
  353.    
  354.     // Not weaponbox
  355.     if( !equal( szClassname, "weaponbox" ) )
  356.         return FMRES_IGNORED
  357.    
  358.     // Get owner
  359.     static iOwner
  360.     iOwner = pev( Entity, pev_owner )
  361.    
  362.     // Get awp ID
  363.     static iWeaponID
  364.     iWeaponID = find_ent_by_owner( NULLENT, g_szClassM249, Entity )
  365.    
  366.     // Make sure that we have gauss
  367.     if( g_iHasGauss [ iOwner ] && is_valid_ent( iWeaponID ) )
  368.     {
  369.         // Hack! Store weaponkey
  370.         set_pev( iWeaponID, pev_weaponkey, GAUSS_WEAPONKEY )
  371.        
  372.         // Hack! Store bp ammo
  373.         set_pev( iWeaponID, pev_bpammo, cs_get_user_bpammo( iOwner, CSW_M249 ) )
  374.        
  375.         // Update
  376.         g_iHasGauss[ iOwner ] = false
  377.        
  378.         // Replace models
  379.         engfunc( EngFunc_SetModel, Entity, g_szModelGaussW )
  380.         return FMRES_SUPERCEDE
  381.     }
  382.     return FMRES_IGNORED
  383. }
  384.  
  385. // Command start
  386. public fw_CmdStart( Player, UC_Handle, Seed )
  387. {
  388.     // Not alive/dont have gauss/not m249
  389.     if( !g_bIsAlive[ Player ] || !g_iHasGauss[ Player ] || g_iCurrentWeapon[ Player ] != CSW_M249 )
  390.         return FMRES_IGNORED
  391.    
  392.     // Retrieve pressed button bitsum
  393.     static iButtons
  394.     iButtons = get_uc( UC_Handle, UC_Buttons )
  395.    
  396.     // Retrieve game time
  397.     static Float:flGameTime
  398.     flGameTime = get_gametime( )
  399.    
  400.     // Retrieve weapon entity
  401.     static iEnt
  402.     iEnt = find_ent_by_owner( NULLENT, g_szClassM249, Player )
  403.    
  404.     // Retrieve clip amount
  405.     static iClip
  406.     iClip = cs_get_weapon_ammo( iEnt )
  407.    
  408.     // Primary attack
  409.     if( iButtons & IN_ATTACK )
  410.     {
  411.         // Remove attack buttons from their button mask
  412.         iButtons &= ~IN_ATTACK
  413.         set_uc( UC_Handle, UC_Buttons, iButtons )
  414.        
  415.         // Prevent too fast shooting
  416.         if( flGameTime - g_flLastShotTime[ Player ] < GAUSS_REFIRERATE )
  417.             return FMRES_IGNORED
  418.        
  419.         // Dont fire while reloading
  420.         if( get_pdata_int( iEnt, m_fInReload, 4 ) )
  421.             return FMRES_IGNORED
  422.        
  423.         // Not enough clip/under water
  424.         if( iClip < 2 || is_user_in_water( Player ) )
  425.         {
  426.             // Emit empty sound
  427.             ExecuteHamB( Ham_Weapon_PlayEmptySound, iEnt )
  428.             return FMRES_IGNORED
  429.         }
  430.        
  431.         // Update
  432.         g_bPrimaryFire[ Player ] = true
  433.        
  434.         // Start to fire
  435.         StartFire( Player )
  436.        
  437.         // Decrease clip
  438.         cs_set_weapon_ammo( iEnt, iClip-2 )
  439.        
  440.         // Reset weapon attack status
  441.         g_bInAttack[ Player ] = 0
  442.        
  443.         // Set time when idle animation should be played
  444.         g_flWeaponIdleTime[ Player ] = flGameTime + 1.0
  445.        
  446.         // Remember last shot time
  447.         g_flLastShotTime[ Player ] = flGameTime
  448.     }
  449.     // Secondary attack
  450.     else if( iButtons & IN_ATTACK2 )
  451.     {
  452.         // Prevent too fast shooting
  453.         if( flGameTime - g_flLastShotTime[ Player ] < GAUSS_REFIRERATE2 )
  454.             return FMRES_IGNORED
  455.        
  456.         // Dont fire while reloading
  457.         if( get_pdata_int( iEnt, m_fInReload, 4 ) )
  458.             return FMRES_IGNORED
  459.        
  460.         // Are we swimming ?
  461.         if( is_user_in_water( Player ) )
  462.         {
  463.             // We are in a middle of attack
  464.             if( g_bInAttack[ Player ] != 0 )
  465.             {
  466.                 // Stop attack
  467.                 emit_sound( Player, CHAN_WEAPON, g_szSoundElectro1, VOL_NORM, ATTN_NORM, 0, 80 + random_num( 0, 0x3f ) )
  468.                
  469.                 // Gun idle
  470.                 UTIL_PlayWeaponAnimation( Player, gauss_idle )
  471.                 return FMRES_IGNORED
  472.             }
  473.             else
  474.             {
  475.                 // Empty sound
  476.                 ExecuteHamB( Ham_Weapon_PlayEmptySound, iEnt )
  477.                 return FMRES_IGNORED
  478.             }
  479.         }
  480.        
  481.         // Get player oldbuttons
  482.         static iOldButtons
  483.         iOldButtons = pev( Player, pev_oldbuttons )
  484.        
  485.         // Make sure that we are holding secondary attack button
  486.         if( iOldButtons & IN_ATTACK2 )
  487.         {
  488.             // Which attack state do we have
  489.             switch ( g_bInAttack[ Player ] )
  490.             {
  491.                 case 0: // Attack start
  492.                 {
  493.                     // Out of ammo
  494.                     if ( iClip <= 0 )
  495.                     {
  496.                         ExecuteHamB( Ham_Weapon_PlayEmptySound, iEnt )
  497.                         return FMRES_IGNORED
  498.                     }
  499.                    
  500.                     // We aren't using primary attack anymore
  501.                     g_bPrimaryFire[ Player ] = false
  502.                    
  503.                     // Decrease clip
  504.                     cs_set_weapon_ammo( iEnt, --iClip )
  505.                    
  506.                     // Update
  507.                     g_flNextAmmoBurn[ Player ] = flGameTime
  508.                    
  509.                     // Send spinup animation
  510.                     UTIL_PlayWeaponAnimation( Player, gauss_spinup )
  511.                    
  512.                     // Update attack state
  513.                     g_bInAttack[ Player ] = 1
  514.                    
  515.                     // Next idle time
  516.                     g_flWeaponIdleTime[ Player ] = flGameTime + 0.5
  517.                    
  518.                     // Update
  519.                     g_flStartCharge[ Player ] = flGameTime
  520.                     g_flAmmoStartCharge[ Player ] = flGameTime + GAUSS_CHARGETIME
  521.                    
  522.                     // Update sound state
  523.                     g_iSoundState[ Player ] = 0
  524.                    
  525.                     // Spin sound
  526.                     emit_sound( Player, CHAN_WEAPON, g_szSoundGaussSpin, VOL_NORM, ATTN_NORM, g_iSoundState[Player ], 110 )
  527.                    
  528.                     // Change sound state
  529.                     g_iSoundState[ Player ] = SND_CHANGE_PITCH
  530.                 }
  531.                 case 1: // In a middle of attack
  532.                 {
  533.                     if( g_flWeaponIdleTime[ Player ] < flGameTime )
  534.                     {
  535.                         // Spin anim
  536.                         UTIL_PlayWeaponAnimation( Player, gauss_spin )
  537.                        
  538.                         // Update state
  539.                         g_bInAttack[ Player ] = 2
  540.                     }
  541.                 }
  542.                 default: // End of attack
  543.                 {
  544.                     // During the charging process, eat one bit of ammo every once in a while
  545.                     if( flGameTime >= g_flNextAmmoBurn[ Player ] && g_flNextAmmoBurn[ Player ] != 1000 )
  546.                     {
  547.                         // Decrease clip
  548.                         cs_set_weapon_ammo( iEnt, --iClip )
  549.                        
  550.                         // Next time when ammo should be decreased
  551.                         g_flNextAmmoBurn[ Player ] = flGameTime + 0.1
  552.                     }
  553.                    
  554.                     // Shit!We run out of ammo
  555.                     if( iClip <= 0 )
  556.                     {
  557.                         // Force gun to fire
  558.                         StartFire( Player )
  559.                        
  560.                         // Reset weapon state
  561.                         g_bInAttack[ Player ] = 0
  562.                        
  563.                         // Set next idle time
  564.                         g_flWeaponIdleTime[ Player ] = flGameTime + 1.0
  565.                     }
  566.                    
  567.                     // Gun is fully charged up
  568.                     if( flGameTime >= g_flAmmoStartCharge[ Player ] )
  569.                     {
  570.                         // Dont eat any more ammo!
  571.                         g_flNextAmmoBurn[ Player ] = 1000.0
  572.                     }
  573.                    
  574.                     // Calculate pitch
  575.                     static Float:flPitch
  576.                     flPitch = ( flGameTime - g_flStartCharge[ Player ] ) * ( 150 / GAUSS_CHARGETIME ) + 100
  577.                    
  578.                     // Pitch shouldnt be THAT big
  579.                     if ( flPitch > 250 )
  580.                     {
  581.                         flPitch = 250.0
  582.                     }
  583.                    
  584.                     // Spin sound
  585.                     emit_sound( Player, CHAN_WEAPON, g_szSoundGaussSpin, VOL_NORM, ATTN_NORM, ( g_iSoundState[ Player ] == SND_CHANGE_PITCH ) ? 1 : 0, floatround( flPitch ) )
  586.                    
  587.                     // Hack for going through level transitions
  588.                     g_iSoundState[ Player ] = SND_CHANGE_PITCH
  589.                    
  590.                     // We are charing way too long!
  591.                     if( g_flStartCharge[ Player ] < flGameTime - 10 )
  592.                     {
  593.                         // ZAP!
  594.                         emit_sound( Player, CHAN_WEAPON, g_szSoundElectro1, VOL_NORM, ATTN_NORM, 0, 80 + random_num( 0, 0x3f ) )
  595.                         emit_sound( Player, CHAN_VOICE, g_szSoundElectro3, VOL_NORM, ATTN_NORM, 0, 80 + random_num( 0, 0x3f ) )
  596.                        
  597.                         // Reset fire state
  598.                         g_bInAttack[ Player ] = 0
  599.                        
  600.                         // Next idle time
  601.                         g_flWeaponIdleTime[ Player ] = flGameTime + 1.0
  602.                        
  603.                         // Damage player
  604.                         ExecuteHamB( Ham_TakeDamage, Player, 0, Player, 50.0, DMG_SHOCK )
  605.                        
  606.                         // Make screen fade
  607.                         UTIL_ScreenFade( Player, UNIT_SECOND*2, UNIT_SECOND/2, FFADE_IN, 255, 128, 0, 128 )
  608.                        
  609.                         // Idle animation
  610.                         UTIL_PlayWeaponAnimation( Player, gauss_idle )
  611.                     }
  612.                 }
  613.             }
  614.            
  615.             // Update
  616.             g_flLastShotTime[ Player ] = flGameTime
  617.         }
  618.     }
  619.    
  620.     return FMRES_HANDLED
  621. }
  622.  
  623. // Update client data post
  624. public fw_UpdateClientData_Post ( Player, SendWeapons, CD_Handle )
  625. {
  626.     // Not alive / dont have gauss/ not m249
  627.     if ( !g_bIsAlive [ Player ] || !g_iHasGauss [ Player ] || g_iCurrentWeapon [ Player ] != CSW_M249 )
  628.         return FMRES_IGNORED
  629.    
  630.     // Block default sounds/animations
  631.     set_cd ( CD_Handle, CD_flNextAttack, halflife_time ( ) + 0.001 )
  632.     return FMRES_HANDLED
  633. }
  634.  
  635. // Player pre think
  636. public fw_PlayerPreThink( Player )
  637. {
  638.     // Not alive / dont have gauss/ not m249
  639.     if ( !g_bIsAlive [ Player ] || !g_iHasGauss [ Player ] || g_iCurrentWeapon [ Player ] != CSW_M249 )
  640.         return
  641.    
  642.     // Play aftershock discharge
  643.     if( g_fflPlayAfterShock[ Player ] && g_fflPlayAfterShock[ Player ] < get_gametime( ) )
  644.     {
  645.         // Randomly play sound
  646.         switch( random_num(0, 3 ) )
  647.         {
  648.             case 0: emit_sound( Player, CHAN_WEAPON, g_szSoundElectro1,random_float( 0.7, 0.8 ), ATTN_NORM, 0, PITCH_NORM )
  649.                 case 1: emit_sound( Player, CHAN_WEAPON, g_szSoundElectro2,random_float( 0.7, 0.8 ), ATTN_NORM, 0, PITCH_NORM )
  650.                 case 2: emit_sound( Player, CHAN_WEAPON, g_szSoundElectro3,random_float( 0.7, 0.8 ), ATTN_NORM, 0, PITCH_NORM )
  651.                 case 3: return // No sound
  652.             }
  653.        
  654.         // Reset discharge
  655.         g_fflPlayAfterShock[ Player ] = 0.0
  656.     }
  657.    
  658.     // Check if we are in a middle of attack
  659.     if( g_bInAttack[ Player ] != 0 )
  660.     {
  661.         // Check if have released attack2 button
  662.         if( get_gametime( ) - g_flLastShotTime[ Player ] > 0.2 )
  663.         {
  664.             // Start to fire
  665.             StartFire( Player )
  666.            
  667.             // Reset attack state
  668.             g_bInAttack[ Player ] = 0
  669.            
  670.             // Next idle time
  671.             g_flWeaponIdleTime[ Player ] = get_gametime( ) + 2.0
  672.         }
  673.     }
  674.     else
  675.     {
  676.         // Force to idle
  677.         WeaponIdle( Player )
  678.     }
  679. }
  680.  
  681. // Player respawned
  682. public fw_PlayerSpawn_Post( Player )
  683. {
  684.     // Not alive
  685.     if( !is_user_alive( Player ) )
  686.         return
  687.    
  688.     // Update
  689.     g_bIsAlive[ Player ] = true
  690. }
  691.  
  692. // Guass deploy
  693. public fw_TCannonDeploy_Post( iEnt )
  694. {
  695.     // Get owner
  696.     static Player
  697.     Player = get_pdata_cbase( iEnt, 41, 4 )
  698.    
  699.     if(!is_user_valid_connected(Player) || !(get_user_weapon(Player) & CSW_M249))   return
  700.    
  701.     // Does this player has gauss?
  702.     if ( g_iHasGauss[ Player ] )
  703.     {
  704.         // Replace models
  705.         set_pev( Player, pev_viewmodel2, g_szModelGaussV )
  706.         set_pev( Player, pev_weaponmodel2, g_szModelGaussP )
  707.        
  708.         // Deploy animation
  709.         UTIL_PlayWeaponAnimation( Player, gauss_draw )
  710.        
  711.         // Reset aftershock
  712.         g_fflPlayAfterShock[ Player ] = 0.0
  713.     }
  714. }
  715.  
  716. // Gauss holster
  717. public fw_TCannonHolster_Post( iEnt )
  718. {
  719.     // Get owner
  720.     static Player
  721.     Player = get_pdata_cbase( iEnt, 41, 4 )
  722.    
  723.     // Does this player has gauss?
  724.     if ( g_iHasGauss[ Player ] )
  725.     {
  726.         // Check if player is still attacking
  727.         if( g_bInAttack[ Player ] )
  728.         {
  729.             // Bug!Bug!Stop spin sound
  730.             emit_sound( Player, CHAN_WEAPON, g_szSoundGaussSpin, 0.0, 0.0, SND_STOP, 0 )
  731.            
  732.             // Attack
  733.             StartFire( Player )
  734.         }
  735.        
  736.         // Holster animation
  737.         UTIL_PlayWeaponAnimation( Player, gauss_holster )
  738.        
  739.         // Reset attack status
  740.         g_bInAttack[ Player ] = 0
  741.     }
  742. }
  743.  
  744. // Add Gauss to players inventory
  745. public fw_TCannonAddToPlayer( iEnt, Player )
  746. {
  747.     // Prevent run-time errors
  748.     if( is_valid_ent( iEnt ) && is_user_valid_connected( Player ) )
  749.     {
  750.         // Seems that player has picked up a gauss
  751.         if( pev( iEnt, pev_weaponkey ) == GAUSS_WEAPONKEY )
  752.         {
  753.             // Update variable
  754.             g_iHasGauss[ Player ] = true
  755.            
  756.             // Update bp ammo
  757.             cs_set_user_bpammo( Player, CSW_M249, pev( iEnt, pev_bpammo ) )
  758.            
  759.             // Reset weapon options
  760.             set_pev( iEnt, pev_weaponkey, 0 )
  761.             set_pev( iEnt, pev_bpammo, 0 )
  762.            
  763.             return HAM_HANDLED
  764.         }
  765.     }
  766.     return HAM_IGNORED
  767. }
  768.  
  769. // Gauss post frame
  770. public fw_TCannonPostFrame( iEnt )
  771. {
  772.     // Get owner
  773.     static iOwner
  774.     iOwner = get_pdata_cbase(iEnt, 41, 4)
  775.    
  776.     if(!is_valid_ent(iEnt) || !is_user_valid_connected(iOwner)) return
  777.    
  778.     // Does this player has gauss?
  779.     if ( g_iHasGauss[ iOwner ] )
  780.     {
  781.         // Reload offset
  782.         static fInReload
  783.         fInReload = get_pdata_int ( iEnt, m_fInReload,4 )
  784.        
  785.         // Next attack time
  786.         static Float:flNextAttack
  787.         flNextAttack = get_pdata_float (iOwner, 83, 5)
  788.        
  789.         // Clip
  790.         static iClip
  791.         iClip = get_pdata_int ( iEnt, m_iClip, 4 )
  792.        
  793.         // Ammo type
  794.         static iAmmoType
  795.         iAmmoType = m_rgAmmo_player_Slot0 + get_pdata_int ( iEnt, m_iPrimaryAmmoType, 4 )
  796.        
  797.         // BP ammo
  798.         static iBpAmmo
  799.         iBpAmmo = get_pdata_int ( iOwner, iAmmoType, 5 )  
  800.        
  801.         // Reloading
  802.         if ( fInReload && flNextAttack <= 0.0 )
  803.         {
  804.             // Calculate the difference
  805.             static j
  806.             j = min ( g_pClip - iClip, iBpAmmo )
  807.            
  808.             // Set new clip
  809.             set_pdata_int ( iEnt, m_iClip, iClip + j, 4 )
  810.            
  811.             // Decrease 'x' bullets from backpack(depending on new clip)
  812.             set_pdata_int( iOwner, iAmmoType, iBpAmmo-j, 5 )
  813.            
  814.             // Not reloding anymore
  815.             set_pdata_int ( iEnt, m_fInReload, 0, 4 )
  816.             fInReload = 0
  817.         }
  818.        
  819.         // Get buttons
  820.         static iButton ; iButton = pev ( iOwner, pev_button)
  821.        
  822.         // Attack/Attack2 buttons and next prim/sec attack time hasnt' come yet
  823.         if( ( iButton & IN_ATTACK2 && get_pdata_float ( iEnt, m_flNextSecondaryAttack, 4 ) <= 0.0)
  824.         || ( iButton & IN_ATTACK && get_pdata_float ( iEnt, m_flNextPrimaryAttack, 4 ) <= 0.0) )
  825.         {
  826.             return
  827.         }
  828.    
  829.         // Reload button / not reloading
  830.         if( iButton & IN_RELOAD && !fInReload )
  831.         {
  832.             // Old clip is more/equal than/to new
  833.             if( iClip >= g_pClip )
  834.             {
  835.                 // Remove reload button
  836.                 set_pev ( iOwner, pev_button, iButton & ~IN_RELOAD )
  837.                
  838.                 // Idle animation
  839.                 UTIL_PlayWeaponAnimation ( iOwner, gauss_idle )
  840.                
  841.                 // Idle time
  842.                 g_flWeaponIdleTime[ iOwner ] = get_gametime( ) + 0.5
  843.             }
  844.             else
  845.             {
  846.                 // Out of ammo
  847.                 if ( !iBpAmmo )
  848.                     return
  849.                    
  850.                 // Reload weapon
  851.                 UTIL_WeaponReload ( iOwner, iEnt )
  852.             }
  853.         }
  854.     }
  855. }
  856.  
  857. // Gauss reload post
  858. public fw_TCannonReload_Post( iEnt )
  859. {
  860.     // Get owner
  861.     static Player
  862.     Player = get_pdata_cbase( iEnt, 41, 4 )
  863.    
  864.     // Does this player has gauss and is he in a middle of reloading ?
  865.     if ( g_iHasGauss[ Player ] && get_pdata_int( iEnt, m_fInReload, 4 ) )
  866.     {
  867.         // Reload
  868.         UTIL_WeaponReload( Player, iEnt )
  869.     }
  870. }
  871.  
  872. // ------------------------------- Internal Functions ----------------------------------------
  873.  
  874. // Gauss start fire
  875. public StartFire( Player )
  876. {
  877.     // This var holds damage
  878.     static Float:flDamage
  879.    
  880.     // Make vectors
  881.     UTIL_MakeVectors( Player )
  882.    
  883.     // Get gametime
  884.     static Float:flGameTime
  885.     flGameTime = get_gametime( )
  886.    
  887.     // This is maximal possible damage from secondary attack!
  888.     if( flGameTime - g_flStartCharge[ Player ] > GAUSS_CHARGETIME )
  889.     {
  890.         flDamage = g_pDmgSec
  891.     }
  892.     else
  893.     {
  894.         // The longer you hold attack button - the bigger is damage
  895.         flDamage = g_pDmgSec * ( ( flGameTime - g_flStartCharge[ Player ] ) / GAUSS_CHARGETIME )
  896.     }
  897.    
  898.     // Primary attack do less damage
  899.     if( g_bPrimaryFire[ Player ] )
  900.     {
  901.         flDamage = g_pDmgPrim
  902.     }
  903.    
  904.     // Make sure that we are not ending attack
  905.     if( g_bInAttack[ Player ] != 3 )
  906.     {
  907.         // Secondary attack can pop you up in the air.Not primary attack!
  908.         if( !g_bPrimaryFire[ Player ] )
  909.         {
  910.             // Current players velocity
  911.             static Float:flVel[ 3 ], Float:v_forward[ 3 ]
  912.             pev( Player, pev_velocity, flVel )
  913.             global_get( glb_v_forward, v_forward )
  914.            
  915.             // Try to affect only vertical velocity
  916.             VectorMS( flVel, flDamage * 5.0, v_forward, flVel )
  917.            
  918.             // Jump!
  919.             set_pev( Player, pev_velocity, flVel )
  920.         }
  921.     }
  922.    
  923.     // Recoil
  924.     static Float:flRecoil[ 3 ]
  925.     flRecoil[ 0 ] = GAUSS_RECOIL
  926.     set_pev( Player, pev_punchangle, flRecoil )
  927.    
  928.     // Fire animation
  929.     UTIL_PlayWeaponAnimation( Player, gauss_fire2 )
  930.    
  931.     // Fire sound
  932.     static Float:flResult
  933.     flResult = 0.5 + flDamage * ( 1.0 / 400.0 )
  934.    
  935.     if( flResult > 1.0 )
  936.     {
  937.         flResult = 1.0
  938.     }
  939.    
  940.     emit_sound( Player, CHAN_WEAPON, g_szSoundGaussFire, flResult, ATTN_NORM, 0, 85 + random_num( 0, 0x1f ) )
  941.    
  942.     // Get players aimpoint position
  943.     static Float:vecDest[ 3 ]
  944.     global_get( glb_v_forward, vecDest )
  945.    
  946.     // Calculate start position
  947.     static Float:vecSrc[ 3 ]
  948.     UTIL_GetGunPosition( Player, vecSrc )
  949.    
  950.     // Time until aftershock 'static discharge' sound
  951.     g_fflPlayAfterShock[ Player ] = flGameTime + random_float( 0.3, 0.8 )
  952.    
  953.     // Fire!
  954.     Fire( Player, vecSrc, vecDest, flDamage )
  955. }
  956.  
  957. // Fire!
  958. Fire( Player, Float:vecOrigSrc[ ], Float:vecDir[ ], Float:flDamage )
  959. {
  960.     // Start position
  961.     static Float:vecSrc[ 3 ]
  962.     xs_vec_copy( vecOrigSrc, vecSrc )
  963.    
  964.     // Calculate end position
  965.     static Float:vecDest[ 3 ]
  966.     VectorMA( vecSrc, 8192.0, vecDir, vecDest )
  967.    
  968.     // Few trace handles
  969.     static tr, beam_tr
  970.    
  971.     // Max fraction
  972.     static Float:flMaxFrac
  973.     flMaxFrac = 1.0
  974.    
  975.     // Total
  976.     static nTotal
  977.     nTotal = 0
  978.    
  979.     // Does this beam punched the wall ?
  980.     static bool:fHasPunched
  981.     fHasPunched = false
  982.    
  983.     // Does this is first beam
  984.     static bool:fFirstBeam
  985.     fFirstBeam = true
  986.    
  987.     // Max hits
  988.     static nMaxHits
  989.     nMaxHits = 10
  990.    
  991.     // Entity whoch should be ignored
  992.     static pEntToIgnore
  993.    
  994.     // Make sure that beam will'be able to cause damage
  995.     while( flDamage > 10 && nMaxHits > 0 )
  996.     {
  997.         // Decrease hit count
  998.         nMaxHits--
  999.        
  1000.         // Draw a trace line
  1001.         engfunc( EngFunc_TraceLine, vecSrc, vecDest, DONT_IGNORE_MONSTERS, pEntToIgnore, tr )
  1002.        
  1003.         // We'll never get outside!
  1004.         if( get_tr2( tr, TR_AllSolid ) )
  1005.             break
  1006.        
  1007.         // Get entity which was hit
  1008.         static pEntity
  1009.         pEntity = Instance( get_tr2( tr, TR_pHit ) )  
  1010.        
  1011.         // Get vector end position
  1012.         static Float:vecEnd[ 3 ]
  1013.         get_tr2( tr, TR_vecEndPos, vecEnd )
  1014.        
  1015.         // Its first beam  
  1016.         if( fFirstBeam )
  1017.         {
  1018.             // Add muzzleflash
  1019.             set_pev( Player, pev_effects, pev(Player, pev_effects) | EF_MUZZLEFLASH )
  1020.            
  1021.             // Its not first anymore
  1022.             fFirstBeam = false
  1023.            
  1024.             // Add
  1025.             nTotal += 26
  1026.            
  1027.             // Draw beam
  1028.             engfunc( EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, vecSrc, 0 )
  1029.             //message_begin( MSG_BROADCAST, SVC_TEMPENTITY )
  1030.             write_byte( TE_BEAMENTPOINT ) // Temp. entity ID
  1031.             write_short( Player | 0x1000 ) // Start entity
  1032.             engfunc( EngFunc_WriteCoord, vecEnd[ 0 ] ) // End position X
  1033.             engfunc( EngFunc_WriteCoord, vecEnd[ 1 ] ) // End position Y
  1034.             engfunc( EngFunc_WriteCoord, vecEnd[ 2 ] ) // End position Z
  1035.             write_short( g_iBeam ) // Sprite index
  1036.             write_byte( 0 ) // Start frame
  1037.             write_byte( 1 ) // Frame rate
  1038.             write_byte( 1 ) // Life
  1039.             write_byte( g_bPrimaryFire[ Player ] ? 16 : 25 ) // Line width
  1040.             write_byte( 0 ) // Noise amplitude
  1041.             write_byte( 255 )
  1042.             write_byte( 128 )
  1043.             write_byte( 0 )
  1044.             write_byte( 255 ) // Alpha
  1045.             write_byte( 0 ) // Scroll speed
  1046.             message_end( )
  1047.         }
  1048.         else
  1049.         {
  1050.             // Draw beam
  1051.             engfunc( EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, vecSrc, 0 )
  1052.             write_byte( TE_BEAMPOINTS ) // Temp. entity ID
  1053.             engfunc( EngFunc_WriteCoord, vecSrc[ 0 ] ) // Start position X
  1054.             engfunc( EngFunc_WriteCoord, vecSrc[ 1 ] ) // Start position Y
  1055.             engfunc( EngFunc_WriteCoord, vecSrc[ 2 ] ) // Start position Z
  1056.             engfunc( EngFunc_WriteCoord, vecEnd[ 0 ] ) // End position X
  1057.             engfunc( EngFunc_WriteCoord, vecEnd[ 1 ] ) // End position Y
  1058.             engfunc( EngFunc_WriteCoord, vecEnd[ 2 ] ) // End position Z
  1059.             write_short( g_iBeam ) // Sprite index
  1060.             write_byte( 0 ) // Start frame
  1061.             write_byte( 1 ) // Frame rate
  1062.             write_byte( 1 ) // Life
  1063.             write_byte( g_bPrimaryFire[ Player ] ? 15 : 25 ) // Line width
  1064.             write_byte( 0 ) // Noise amplitude
  1065.             write_byte( 255 )
  1066.             write_byte( 128 )
  1067.             write_byte( 0 )
  1068.             write_byte( 255 )
  1069.             write_byte( 0 ) // Scroll speed
  1070.             message_end( )
  1071.         }
  1072.        
  1073.         // Check if this entity should take any damage
  1074.         if( pev( pEntity, pev_takedamage ) != DAMAGE_NO )
  1075.         {
  1076.             // Check if this is player and zombie
  1077.             if( pev_valid( pEntity ) )
  1078.             {
  1079.                 if (is_user_alive(pEntity))
  1080.                 {
  1081.                     if ((get_member(pEntity, m_iTeam) == get_member(Player, m_iTeam)) ||
  1082.                     pEntity == Player)
  1083.                     {
  1084.                         return
  1085.                     }
  1086.                 }
  1087.                
  1088.                 // Retrieve health
  1089.                 static iHealth
  1090.                 iHealth = floatround(pev(pEntity, pev_health))
  1091.            
  1092.                 // We should be alive
  1093.                 if( iHealth - flDamage >= 1 )
  1094.                 {
  1095.                     // Cause some damage
  1096.                     ExecuteHamB( Ham_TakeDamage, pEntity, 0, Player, flDamage, DMG_BULLET | DMG_ALWAYSGIB )
  1097.                 }
  1098.                 else
  1099.                 {
  1100.                     if (is_user_alive(pEntity))
  1101.                     {
  1102.                         // Die
  1103.                         g_bKilledByLaser[ pEntity ] = true
  1104.                         ExecuteHamB( Ham_Killed, pEntity, Player, 2 )
  1105.                         g_bKilledByLaser[ pEntity ] = false
  1106.                     }
  1107.                 }
  1108.             }
  1109.         }
  1110.        
  1111.         // Check if this entity should reflect our beam
  1112.         if( ReflectGauss( pEntity ) )
  1113.         {
  1114.             static Float:n
  1115.            
  1116.             // Return normal vector in a spot we hit
  1117.             static Float:vecPlaneNormal[ 3 ]
  1118.             get_tr2( tr, TR_vecPlaneNormal, vecPlaneNormal )
  1119.            
  1120.             // Calculate dot product
  1121.             n = - xs_vec_dot( vecPlaneNormal, vecDir )
  1122.            
  1123.             // 60 degrees
  1124.             if ( 0 < n < 0.5 )
  1125.             {
  1126.                 static Float:r[ 3 ]
  1127.                 VectorMA( vecDir, 2.0 * n, vecPlaneNormal, r )
  1128.                
  1129.                 // Get vector end position
  1130.                 get_tr2( tr, TR_vecEndPos, vecEnd )
  1131.                
  1132.                 // Get trace fraction
  1133.                 static Float:trflFraction
  1134.                 get_tr2( tr, TR_flFraction, trflFraction )
  1135.                
  1136.                 // Calculate fraction
  1137.                 flMaxFrac = flMaxFrac - trflFraction
  1138.                
  1139.                 // Copy vectors
  1140.                 xs_vec_copy( r, vecDir )
  1141.                
  1142.                 // Make more vector calculations
  1143.                 VectorMA( vecEnd, 8.0, vecDir, vecSrc )
  1144.                 VectorMA( vecSrc, 8192.0, vecDir, vecDest )
  1145.            
  1146.                 // Undone!Do radius damage
  1147.                
  1148.                 // Increase
  1149.                 nTotal += 34
  1150.                
  1151.                 if( n == 0 )
  1152.                 {
  1153.                     // Lose energy
  1154.                     n = 0.1
  1155.                 }
  1156.                
  1157.                 // Calculate new damage
  1158.                 flDamage = flDamage * ( 1 - n )
  1159.             }
  1160.             else
  1161.             {
  1162.                 // Add gun shot decal on the world
  1163.                 FX_GunShotDecal( vecEnd, pEntity )
  1164.                
  1165.                 // Add glowing sprite on the world
  1166.                 FX_TempSprite( vecEnd, 6, floatround( flDamage / 255.0 ) )
  1167.                
  1168.                 // Increase
  1169.                 nTotal += 13
  1170.                
  1171.                 // Limit it to one hole punch
  1172.                 if( fHasPunched )
  1173.                     break
  1174.                
  1175.                 // Update  
  1176.                 fHasPunched = true
  1177.                
  1178.                 // Try punching through wall if secondary attack (primary is incapable of
  1179.                 // breaking through)
  1180.                 if( !g_bPrimaryFire[ Player ] )
  1181.                 {
  1182.                     // Retrieve vector end position
  1183.                     get_tr2( tr, TR_vecEndPos, vecEnd )
  1184.                    
  1185.                     // Modify start origin
  1186.                     static Float:vecStart[ 3 ]
  1187.                     VectorMA( vecEnd, 8.0, vecDir, vecStart )
  1188.                    
  1189.                     // Draw another trace line
  1190.                     engfunc( EngFunc_TraceLine, vecSrc, vecDest, DONT_IGNORE_MONSTERS, pEntToIgnore, beam_tr )
  1191.                    
  1192.                     // We'll never get outside
  1193.                     if( !get_tr2( beam_tr, TR_AllSolid ) )
  1194.                     {
  1195.                         // Get end position
  1196.                         static Float:vecBeamEndPos[ 3 ]
  1197.                         get_tr2( beam_tr, TR_vecEndPos, vecBeamEndPos )
  1198.                        
  1199.                         // Trace backwards to find exit point
  1200.                         engfunc( EngFunc_TraceLine, vecBeamEndPos, vecEnd, DONT_IGNORE_MONSTERS, pEntToIgnore, beam_tr )
  1201.                        
  1202.                         // Again get end position
  1203.                         get_tr2( beam_tr, TR_vecEndPos, vecBeamEndPos )
  1204.                        
  1205.                         static Float:ns, Float:vecSub[ 3 ]
  1206.                        
  1207.                         // Subtract vectors
  1208.                         xs_vec_sub( vecBeamEndPos, vecEnd, vecSub )
  1209.                        
  1210.                         // Get vector length
  1211.                         ns = xs_vec_len( vecSub )
  1212.                        
  1213.                         if( ns < flDamage )
  1214.                         {
  1215.                             // Lose enery
  1216.                             if( ns == 0 )
  1217.                             {
  1218.                                 ns = 1.0
  1219.                             }
  1220.                            
  1221.                             // Decrease damage
  1222.                             flDamage -= ns
  1223.                            
  1224.                             // Subtract
  1225.                             static Float:vecCalc[ 3 ]
  1226.                             VectorSubtract( vecEnd, vecDir, vecCalc )
  1227.                            
  1228.                             // Absorbtion balls
  1229.                             FX_SpriteTrail( vecEnd, vecCalc, BALL_AMOUNT, 15, 3, 25, 25 )
  1230.                            
  1231.                             // Add gun shot decal on the world
  1232.                             FX_GunShotDecal( vecBeamEndPos, pEntity )
  1233.                            
  1234.                             // And glowing sprite
  1235.                             FX_TempSprite( vecBeamEndPos, 6, floatround( flDamage / 255.0 ) )
  1236.                            
  1237.                             // Subtract
  1238.                             VectorSubtract( vecBeamEndPos, vecDir, vecCalc )
  1239.                            
  1240.                             // Absorbtion balls
  1241.                             FX_SpriteTrail( vecEnd, vecCalc, BALL_AMOUNT, 15, 3, 25, 25 )
  1242.                            
  1243.                             // Increase shit
  1244.                             nTotal += 21
  1245.                            
  1246.                             /*
  1247.                             // Calculate radius damage
  1248.                             static Float:flRadDmg
  1249.                             flRadDmg = flDamage * 1.75
  1250.                            
  1251.                             // Undone.Do radius damage here!
  1252.                             floatradius( flDamage, flRadDmg, vecBeamEndPos )
  1253.                             */
  1254.                            
  1255.                             // Increase
  1256.                             nTotal += 53
  1257.                            
  1258.                             VectorMA( vecBeamEndPos, 8.0, vecDir, vecSub )
  1259.                            
  1260.                             // Add up vector
  1261.                             xs_vec_add( vecBeamEndPos, vecDir, vecSrc )
  1262.                         }
  1263.                     }
  1264.                     else
  1265.                     {
  1266.                         flDamage = 0.0
  1267.                     }
  1268.                 }
  1269.                 else
  1270.                 {
  1271.                     // Primary attack
  1272.                     if( g_bPrimaryFire [ Player ] )
  1273.                     {
  1274.                         // Slug doesn't punch through ever with primary
  1275.                         // fire, so leave a little glowy bit and make some balls
  1276.                         FX_TempSprite( vecEnd, 6, floatround( flDamage / 255.0 ) )
  1277.                         FX_SpriteTrail( vecEnd, vecDir, BALL_AMOUNT, 15, 3, 25, 25 )
  1278.                     }
  1279.                    
  1280.                     flDamage = 0.0
  1281.                 }
  1282.             }
  1283.         }
  1284.         else
  1285.         {
  1286.             // Add up vector
  1287.             xs_vec_add( vecEnd, vecDir, vecSrc )
  1288.             pEntToIgnore = pEntity
  1289.         }
  1290.     }
  1291. }              
  1292.  
  1293. // Register and cache CVARs
  1294. public Load_Cvars( )
  1295. {
  1296.     cvar_oneround = register_cvar( "ze_tcannon_oneround", "0" )
  1297.     cvar_dmgprim = register_cvar( "ze_tcannon_dmgprim", "200" )
  1298.     cvar_dmgsec = register_cvar( "ze_tcannon_dmgsec", "500" )
  1299.     cvar_clip = register_cvar( "ze_tcannon_clip", "100" )
  1300.    
  1301.     g_pOneRound = get_pcvar_num( cvar_oneround )
  1302.     g_pDmgPrim = get_pcvar_float( cvar_dmgprim )
  1303.     g_pDmgSec = get_pcvar_float( cvar_dmgsec )
  1304.     g_pClip = get_pcvar_num( cvar_clip )
  1305. }
  1306.  
  1307. // Gauss weapon idle
  1308. WeaponIdle( Player )
  1309. {
  1310.     // Get gametime
  1311.     static Float:flGameTime
  1312.     flGameTime = get_gametime( )
  1313.    
  1314.     if( g_flWeaponIdleTime[ Player ] > flGameTime )
  1315.         return
  1316.    
  1317.     // Animation sequence variable
  1318.     static iAnim
  1319.    
  1320.     // Animation randomizer
  1321.     static Float:flRand
  1322.     flRand = random_float( 0.1, 1.0 )
  1323.    
  1324.     if( flRand <= 0.5 )
  1325.     {
  1326.         iAnim = gauss_idle
  1327.         g_flWeaponIdleTime[ Player ] = flGameTime + random_float( 10.0, 15.0 )
  1328.     }
  1329.     else if( flRand <= 0.75 )
  1330.     {
  1331.         iAnim = gauss_idle2
  1332.         g_flWeaponIdleTime[ Player ] = flGameTime + random_float( 10.0, 15.0 )
  1333.     }
  1334.     else
  1335.     {
  1336.         iAnim = gauss_fidget
  1337.         g_flWeaponIdleTime[ Player ] = flGameTime + 3
  1338.     }
  1339.    
  1340.     // Idle
  1341.     UTIL_PlayWeaponAnimation( Player, iAnim )
  1342. }  
  1343.  
  1344. // Play weapon animation
  1345. UTIL_PlayWeaponAnimation( const Player, const Sequence )
  1346. {
  1347.     set_pev( Player, pev_weaponanim, Sequence )
  1348.    
  1349.     message_begin( MSG_ONE_UNRELIABLE, SVC_WEAPONANIM, .player = Player )
  1350.     write_byte( Sequence )
  1351.     write_byte( pev( Player, pev_body ) )
  1352.     message_end( )
  1353. }              
  1354.  
  1355. // Make ScreenFade
  1356. UTIL_ScreenFade( Player, Duration, HoldTime, Flags, iRed, iGreen, iBlue, iAlpha )
  1357. {
  1358.     message_begin( MSG_ONE, gmsgScreenFade, _, Player )
  1359.     write_short( Duration )
  1360.     write_short( HoldTime )
  1361.     write_short( Flags )
  1362.     write_byte( iRed )
  1363.     write_byte( iGreen )
  1364.     write_byte( iBlue )
  1365.     write_byte( iAlpha )
  1366.     message_end( )
  1367. }
  1368.  
  1369. // Reload gauss
  1370. UTIL_WeaponReload( Player, iEnt )
  1371. {
  1372.     // Modify time until next attack
  1373.     set_pdata_float( Player, 83, GAUSS_RELOADTIME+0.5, 5 )
  1374.    
  1375.     // Reload animation
  1376.     UTIL_PlayWeaponAnimation( Player, gauss_spin )
  1377.    
  1378.     // Enable reload offset
  1379.     set_pdata_int( iEnt, m_fInReload, 1, 4 )
  1380.    
  1381.     // Modify next idle time
  1382.     g_flWeaponIdleTime[ Player ] = get_gametime( ) + GAUSS_RELOADTIME + 1.0
  1383. }
  1384.  
  1385. // Drop all primary weapons
  1386. UTIL_DropPrimary( Player )
  1387. {
  1388.     // Get user weapons
  1389.     static weapons[ 32 ], num, i, weaponid
  1390.     num = 0 // reset passed weapons count (bugfix)
  1391.     get_user_weapons( Player, weapons, num )
  1392.    
  1393.     // Loop through them and drop primaries
  1394.     for( i = 0; i < num; i++ )
  1395.     {
  1396.         // Prevent re-indexing the array
  1397.         weaponid = weapons[ i ]
  1398.        
  1399.         // We definetely are holding primary gun
  1400.         if(( (1<<weaponid) & PRIMARY_WEAPONS_BITSUM ) )    
  1401.         {
  1402.             // Get weapon entity
  1403.             static wname[32]
  1404.             get_weaponname(weaponid, wname, charsmax(wname))
  1405.            
  1406.             // Player drops the weapon and looses his bpammo
  1407.             engclient_cmd( Player, "drop", wname)
  1408.         }
  1409.     }
  1410. }
  1411.  
  1412. // Get gun position
  1413. UTIL_GetGunPosition( Player, Float:flOrigin[ ] )
  1414. {
  1415.     static Float:vf_Origin[ 3 ], Float:vf_ViewOfs[ 3 ]
  1416.    
  1417.     pev( Player, pev_origin, vf_Origin )
  1418.     pev( Player, pev_view_ofs, vf_ViewOfs )
  1419.    
  1420.     xs_vec_add( vf_Origin, vf_ViewOfs, flOrigin )
  1421. }
  1422.  
  1423. // Make vectors
  1424. UTIL_MakeVectors ( Player )
  1425. {
  1426.     static Float:flAngle[ 3 ], Float:flPunchAngle[ 3 ]
  1427.  
  1428.     pev( Player, pev_v_angle, flAngle )
  1429.     pev( Player, pev_punchangle, flPunchAngle )
  1430.  
  1431.     xs_vec_add( flAngle, flPunchAngle, flAngle )
  1432.     engfunc( EngFunc_MakeVectors, flAngle )
  1433. }
  1434.  
  1435. // From HL SDK.
  1436. VectorMA( Float:a[ ], Float:flScale, Float:b[ ], Float:c[ ] )
  1437. {
  1438.     c[ 0 ] = a[ 0 ] + flScale * b[ 0 ]
  1439.     c[ 1 ] = a[ 1 ] + flScale * b[ 1 ]
  1440.     c[ 2 ] = a[ 2 ] + flScale * b[ 2 ]
  1441. }
  1442.  
  1443. VectorMS( const Float:flSource[ ], const Float:flScale, const Float:flMult[ ], Float:flOutput[ ] )
  1444. {
  1445.         flOutput[ 0 ] = flSource[ 0 ] - flMult[ 0 ] * flScale
  1446.         flOutput[ 1 ] = flSource[ 1 ] - flMult[ 1 ] * flScale
  1447.         flOutput[ 2 ] = flSource[ 2 ] - flMult[ 2 ] * flScale
  1448. }
  1449.  
  1450. // Another stuff from HLSDK
  1451. Instance( iEnt )
  1452. {
  1453.     return iEnt == -1 ? 0 : iEnt
  1454. }
  1455.  
  1456. // Does this entity should refect gauss?
  1457. ReflectGauss( iEnt )
  1458. {
  1459.         return IsBSPModel( iEnt ) && pev( iEnt, pev_takedamage ) == DAMAGE_NO
  1460. }
  1461.  
  1462. // Does this entity is BSP model?
  1463. IsBSPModel( iEnt )
  1464. {
  1465.     return pev( iEnt, pev_solid ) == SOLID_BSP || pev( iEnt, pev_movetype ) == MOVETYPE_PUSHSTEP
  1466. }
  1467.  
  1468. // Add gun shot decal on world!
  1469. FX_GunShotDecal( Float:flPos[ ], pEntity )
  1470. {
  1471.     // Draw gunshot
  1472.     engfunc( EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, flPos, 0 )
  1473.     write_byte( TE_GUNSHOTDECAL ) // Temp.entity ID
  1474.     engfunc( EngFunc_WriteCoord, flPos[ 0 ] ) // Position X
  1475.     engfunc( EngFunc_WriteCoord, flPos[ 1 ] ) // Position Y
  1476.     engfunc( EngFunc_WriteCoord, flPos[ 2 ] ) // Position Z
  1477.     write_short( pEntity ) // Which entity to mark?
  1478.     write_byte( 43 ) // Decal number
  1479.     message_end( )
  1480. }
  1481.  
  1482. // Add glow sprite on world
  1483. FX_TempSprite( Float:flPos[ ], iScale, iSize )
  1484. {
  1485.     engfunc( EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, flPos, 0 )
  1486.     write_byte( TE_GLOWSPRITE ) // Temp.entity ID
  1487.     engfunc( EngFunc_WriteCoord, flPos[ 0 ] ) // Position X
  1488.     engfunc( EngFunc_WriteCoord, flPos[ 1 ] ) // Position Y
  1489.     engfunc( EngFunc_WriteCoord, flPos[ 2 ] ) // Position Z
  1490.     write_short( g_iBalls ) // Sprite index
  1491.     write_byte( iScale ) // Scale
  1492.     write_byte( iSize ) // Size
  1493.     write_byte( 255 ) // Brightness
  1494.     message_end( )
  1495. }
  1496.  
  1497. // Add sprite trail
  1498. FX_SpriteTrail( Float:vecStart[ ], Float:vecDest[ ], iCount, iLife, iScale, iVel, iRnd )
  1499. {
  1500.     message_begin( MSG_BROADCAST, SVC_TEMPENTITY )
  1501.     write_byte( TE_SPRITETRAIL ) // Sprite trail
  1502.     engfunc( EngFunc_WriteCoord, vecStart[ 0 ] ) // Position X
  1503.     engfunc( EngFunc_WriteCoord, vecStart[ 1 ] ) // Position Y
  1504.     engfunc( EngFunc_WriteCoord, vecStart[ 2 ] ) // Position Z
  1505.     engfunc( EngFunc_WriteCoord, vecDest[ 0 ] ) // Position X
  1506.     engfunc( EngFunc_WriteCoord, vecDest[ 1 ] ) // Position Y
  1507.     engfunc( EngFunc_WriteCoord, vecDest[ 2 ] ) // Position Z
  1508.     write_short( g_iBalls ) // SPrite index
  1509.     write_byte( iCount ) // Amount
  1510.     write_byte( iLife ) // Life
  1511.     write_byte( iScale ) // Scale
  1512.     write_byte( iVel ) // Velocity along vector
  1513.     write_byte( iRnd ) // Randomness of velocity
  1514.     message_end( )
  1515. }
Last edited by Raheem 5 years ago, edited 1 time in total.
Reason: Updated.
He who fails to plan is planning to fail

czirimbolo
Veteran Member
Veteran Member
Poland
Posts: 598
Joined: 7 years ago
Contact:

#15

Post by czirimbolo » 5 years ago

Now its killing myself, not entities :D

Displaying debug trace (plugin "ze_extra_tcannon.amxx", version "1.2")
L 09/25/2018 - 18:55:52: [AMXX] Run time error 4: index out of bounds
L 09/25/2018 - 18:55:52: [AMXX] [0] ze_extra_tcannon.sma::Fire (line 1092)
L 09/25/2018 - 18:55:52: [AMXX] [1] ze_extra_tcannon.sma::Fire (line 1084)
L 09/25/2018 - 18:55:52: [AMXX] [2] ze_extra_tcannon.sma::StartFire (line 954)
L 09/25/2018 - 18:55:52: [AMXX] [3] ze_extra_tcannon.sma::fw_PlayerPreThink (line 665)
Image

User avatar
Raheem
Mod Developer
Mod Developer
Posts: 2214
Joined: 7 years ago
Contact:

#16

Post by Raheem » 5 years ago

Code updated, check now.
He who fails to plan is planning to fail

czirimbolo
Veteran Member
Veteran Member
Poland
Posts: 598
Joined: 7 years ago
Contact:

#17

Post by czirimbolo » 5 years ago

Ok you fixed killing myslef, but it doesnt damage entities and I dont see balls when I shot. I see no errors at the moment
Image

User avatar
Raheem
Mod Developer
Mod Developer
Posts: 2214
Joined: 7 years ago
Contact:

#18

Post by Raheem » 5 years ago

Post this weapon resources, i'll test it on my local server when i get time to do.
He who fails to plan is planning to fail

czirimbolo
Veteran Member
Veteran Member
Poland
Posts: 598
Joined: 7 years ago
Contact:

#19

Post by czirimbolo » 5 years ago

Im on my mobile now but resources are in extra items sections as Gauss Canon
Image

User avatar
Raheem
Mod Developer
Mod Developer
Posts: 2214
Joined: 7 years ago
Contact:

#20

Post by Raheem » 5 years ago

OK, will get them from there. When get time i'll test.
He who fails to plan is planning to fail

Post Reply

Create an account or sign in to join the discussion

You need to be a member in order to post a reply

Create an account

Not a member? register to join our community
Members can start their own topics & subscribe to topics
It’s free and only takes a minute

Register

Sign in

Who is online

Users browsing this forum: No registered users and 1 guest