Available 2 extra items

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

2 extra items

#1

Post by czirimbolo » 5 years ago

Hello, please can someone covert this guns and make it for VIPS:

FOR HUMAN VIPS:

Code: Select all

/*
	[ZP] Extra Item: Tau Cannon
	Copyright (C) 2009-2010 by NiHiLaNTh

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.
	
	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.
	
	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
	
	In addition, as a special exception, the author gives permission to
	link the code of this program with the Half-Life Game Engine ("HL
	Engine") and Modified Game Libraries ("MODs") developed by Valve,
	L.L.C ("Valve"). You must obey the GNU General Public License in all
	respects for all of the code used other than the HL Engine and MODs
	from Valve. If you modify this file, you may extend this exception
	to your version of the file, but you are not obligated to do so. If
	you do not wish to do so, delete this exception statement from your
	version.
	
	--- Introduction ---
	This plugin adds new weapon - Tau Cannon.Basically, this is almost
	the same weapon as in Half-Life.An experimental, highly unstable weapon. 
	One of the most important abilities is that it can shoot through walls, 
	making it so that you can't take cover against it. The gauss's primary 
	fire shoots out tiny spurts that are only effective in close to medium 
	range due to its erratic spread. You can charge up the gauss by holding 
	down alternate fire; the longer you charge it up, the stronger it gets. 
	The longer you charge it up is directly proportional to the thickness 
	of the wall you can shoot through. Lookout campers, retribution has come.
	
	---CVARs---
	zp_tcannon_oneround - Should Tau Cannon be in players inventory only for 1 round?
	zp_tcannon_dmgprim - Primary attack damage
	zp_tcannon_dmgsec - Maximal secondary attack damage
	zp_tcannon_clip - Clip amount
	
	--- Credits ---
	Arkshine, HL SDK, meTaLiCroSS and more...
	
	--- Changelog ---
	1.0 - Initial release.
	1.1 - Added some statics
	1.2 - Fixed ammo buy bug
	    - Fixed possible server crash
*/	
	
#include < amxmodx >
#include < cstrike >
#include < csx >
#include < engine >
#include < fakemeta >
#include < hamsandwich >
#include < fun >
#include < xs >
#include < zombieplague >

// Plugin information
#define Plugin	"[ZP] 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

// Ammo given when buy weapons	
new const BUYAMMO[] = { -1, 13, -1, 30, -1, 8, -1, 12, 30, -1, 30, 50, 12, 30, 30, 30, 12, 30,
1, 30, 30, 8, 30, 30, 30, -1, 7, 30, 30, -1, 50 }

// 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 }

// Weapon ammo ID's
new const AMMOID[] = { -1, 9, -1, 2, 12, 5, 14, 6, 4, 13, 10, 7, 6, 4, 4, 4, 6, 10,
1, 10, 3, 5, 4, 10, 2, 11, 8, 4, 2, -1, 7 }

// 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
new gmsgAmmoPickup // Ammo pickup

// 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( "zp_tcannon_version", Version, FCVAR_FLAGS )
	
	// New extra item
	g_iGaussID = zp_register_extra_item( "Tau Cannon", 30, ZP_TEAM_HUMAN )
	
	// Client commands
	register_clcmd( "buyammo1", "fn_BuyAmmo" )
	register_clcmd( "buyammo2", "fn_BuyAmmo" )
	
	// 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" )
	gmsgAmmoPickup = get_user_msgid( "AmmoPickup" )
	
	// 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
}

// Someone selected our extra item
public zp_extra_item_selected( Player, Item )
{
	// Tau Cannon
	if ( Item == g_iGaussID )
	{
		// 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 ] )
	}
}

// Player is trying to buy something
public fn_BuyAmmo( Player )
{
	// Not alive
	if( !g_bIsAlive[ Player ] )
		return PLUGIN_HANDLED
	
	// Dont have Tau Cannon
	if( !g_iHasGauss[ Player ] )
		return PLUGIN_CONTINUE
	
	// Retrieve ammo pack amount
	static iAmmoPack
	iAmmoPack = zp_get_user_ammo_packs( Player )
	
	// Out of ammo packs
	if( iAmmoPack <= 0 )
		return PLUGIN_HANDLED
	
	// Get players weapons
	static weapons[ 32 ], num, i, currentammo, weaponid, refilled
	num = 0 // reset passed weapons count (bugfix)
	refilled = false
	get_user_weapons( Player, weapons, num )
	
	// Loop through them and give the right ammo type
	for( i = 0; i < num; i++ )
	{
		// Prevents re-indexing the array
		weaponid = weapons[ i ]
		
		// Primary and secondary only
		if( MAXBPAMMO[ weaponid ] > 2 )
		{
			// Get current ammo of the weapon
			currentammo = cs_get_user_bpammo( Player, weaponid)
			
			// Check if we are close to the BP ammo limit
			if (currentammo < MAXBPAMMO[weaponid]-BUYAMMO[weaponid])
			{
				// Flash ammo in hud
				message_begin(MSG_ONE_UNRELIABLE, gmsgAmmoPickup, _, Player )
				write_byte(AMMOID[weaponid]) // ammo id
				write_byte(BUYAMMO[weaponid]) // ammo amount
				message_end()
				
				// Increase BP ammo
				cs_set_user_bpammo ( Player, weaponid, currentammo + BUYAMMO[weaponid])
				
				refilled = true
			}
			else if (currentammo < MAXBPAMMO[weaponid])
			{
				// Flash ammo in hud
				message_begin(MSG_ONE_UNRELIABLE, gmsgAmmoPickup, _, Player )
				write_byte(AMMOID[weaponid]) // ammo id
				write_byte(MAXBPAMMO[weaponid]-currentammo) // ammo amount
				message_end()
				
				// Reached the limit
				cs_set_user_bpammo ( Player, weaponid, MAXBPAMMO[weaponid])
				
				refilled = true
			}
		}
	}
	
	// Weapons already have full ammo
	if (!refilled) return PLUGIN_HANDLED
	
	// Deduce ammo packs, play clip purchase sound, and notify the player
	zp_set_user_ammo_packs( Player, --iAmmoPack )
	engfunc(EngFunc_EmitSound, Player, CHAN_ITEM, "items/9mmclip1.wav", 1.0, ATTN_NORM, 0, PITCH_NORM)
	client_print( Player, print_chat, "[ZP] You purchased extra ammo for your guns." )
	
	return PLUGIN_HANDLED
}	

// 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 )
	
	// 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 )
	
	// 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 ) && zp_get_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( "zp_tcannon_oneround", "0" )
	cvar_dmgprim = register_cvar( "zp_tcannon_dmgprim", "200" )
	cvar_dmgsec = register_cvar( "zp_tcannon_dmgsec", "500" )
	cvar_clip = register_cvar( "zp_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( )
}	
	
	

FOR ZOMBIE VIP

Code: Select all

/*
*	-----------------------------------
*	-----[ZP] Extra Item: Drag---------
*	-----------------------------------
*	------Author: 4eRT (aka pff)-------
*	-----------------------------------
*		About:
*	Extra Item for Zombies: drag ability. It works like Smoker drag.
*	-----------------------------------
*		Discription:
*	It's similar Smoker zombie ability. With this extra you can drag players by holding "V" or +USE
*	Drag speed, max drags, cooldown, drag teammates, unable to move may be customized by Cvars.
*	-----------------------------------
*		Credits:
*	yang - great thanks for his Scorpion superhero plugin where I borrow harpoon&drag code.
*	xPaw - really thx for help optimization Smoker plugin. For Entity_Set_Vector.
*	-----------------------------------
*		Cvars:
*	zp_extra_drag_drags 10 // how many times you can drag player? def=10
*	zp_extra_drag_dragspeed 160 // speed of dragging player. def=160
*	zp_extra_drag_cooldown 5 // time in sec before you can use drag again. def=5
*	zp_extra_drag_mates 0 // can you drag teammates to? 1=yes 0=no def=0
*	zp_extra_drag_dmg2stop 300 // damage to stop dragging. set 0 to disable it. def=300
*	zp_extra_drag_extrahook 2 // additional hooks after infects smb. def=2
*	zp_extra_drag_unable_move 1 // 0=human & you can move / 1=unable human to move when dragging / 2=unable you to move / 3=unable both
*	zp_extra_drag_nemesis 0 // 0=can't drag players if is Nemesis round/ 1=can. def=0
*	zp_extra_drag_survivor 1 // 0=can't drag Survivor / 1=can. def=1
*	zp_extra_drag_reset 0 // 0=delete drag ability on humanizing / 1=not
*	-----------------------------------
*		Modules:
*	hamsandwich
*	fakemeta
*	engine
*	-----------------------------------
*		History:
*	0.1b (14.01.10)
*		First release.
*	1.0 (15.01.10)
*		Barnacle hand model added. Code optimized.
*	-----------------------------------
*/

#include <amxmodx>
#include <zombieplague>
#include <fakemeta>
#include <hamsandwich>
#include <engine>

#define PLUGIN "[ZP] Extra Drag"
#define VERSION "0.1"
#define AUTHOR "4eRT"

//Some vars
new const g_extra_drag[] = { "Drag ability" } 
new const g_vmodel[] = { "models/barnacle/v_bgrap.mdl" }
new const g_pmodel[] = { "models/barnacle/p_bgrap.mdl" }
new g_sndMiss[] = "zombie_plague/Smoker_TongueHit_miss.wav"
new g_sndDrag[] = "zombie_plague/Smoker_TongueHit_drag.wav"
new g_hooked[33], g_hooksLeft[33], g_unable2move[33], g_over_dmg[33]
new Float:g_lastHook[33]
new g_Line, g_item_drag
new cvar_enabled, cvar_cost, cvar_maxdrags, cvar_dragspeed, cvar_cooldown, cvar_dmgtostop, cvar_mates, cvar_extrahook, cvar_unb2move, cvar_nemesis, cvar_survivor, cvar_reset
new keys = MENU_KEY_1|MENU_KEY_2|MENU_KEY_3
new bool: g_has_drag[33], bool: g_bind_use[33], bool: g_bind_or_not[33], bool: g_drag_i[33]

public plugin_init()
{
	cvar_enabled = register_cvar("zp_extra_drag", "1")
	cvar_cost = register_cvar("zp_extra_drag_cost", "10")
	cvar_dragspeed = register_cvar("zp_extra_drag_dragspeed", "160")
	cvar_maxdrags = register_cvar("zp_extra_drag_maxdrags", "10")
	cvar_cooldown = register_cvar("zp_extra_drag_cooldown", "5")
	cvar_dmgtostop = register_cvar("zp_extra_drag_dmg2stop", "300")
	cvar_mates = register_cvar("zp_extra_drag_mates", "0")
	cvar_extrahook = register_cvar("zp_extra_drag_extrahook", "2")
	cvar_unb2move = register_cvar("zp_extra_drag_unable_move", "1")
	cvar_nemesis = register_cvar("zp_extra_drag_nemesis", "0")
	cvar_survivor = register_cvar("zp_extra_drag_survivor", "1")
	cvar_reset = register_cvar("zp_extra_drag_reset", "0")
	register_event("HLTV", "newSpawn", "a", "1=0", "2=0")
	register_event("DeathMsg", "player_death", "a")
	register_forward(FM_PlayerPreThink, "fw_PlayerPreThink")
	RegisterHam(Ham_TakeDamage, "player", "fw_TakeDamage")
	register_clcmd("+drag","drag_start", ADMIN_USER, "bind ^"key^" ^"+drag^"")
	register_clcmd("-drag","drag_end")
	register_menucmd(register_menuid("Do you want to bind V +drag?"), keys, "bind_v_key")
	g_item_drag = zp_register_extra_item(g_extra_drag, get_pcvar_num(cvar_cost), ZP_TEAM_ZOMBIE)
}
public plugin_precache()
{
	register_plugin(PLUGIN, VERSION, AUTHOR)
	precache_sound(g_sndDrag)
	precache_sound(g_sndMiss)
	g_Line = precache_model("sprites/zbeam4.spr")
	engfunc(EngFunc_PrecacheModel, g_vmodel)
	engfunc(EngFunc_PrecacheModel, g_pmodel)
}

public zp_extra_item_selected(id, item)
{
	if (item == g_item_drag)
	{
		if(is_user_alive(id) && get_pcvar_num(cvar_enabled) == 1)
		{
			g_hooksLeft[id] = get_pcvar_num(cvar_maxdrags)
			g_has_drag[id] = true
			client_print(id, print_chat, "You've bought drag ability. Now have fun with barnacle hand!")
			
			if (!g_bind_or_not[id])
			{
				new menu[192]
				format(menu, 191, "Do you want to bind V +drag?^n^n1. Yes^n2. No^n3. Drag on +USE")
				show_menu(id, keys, menu)
			}
		} else
			return
	}
}

public zp_user_infected_post(id, infector)
	if(g_has_drag[infector])
		g_hooksLeft[infector] = g_hooksLeft[infector] + get_pcvar_num(cvar_extrahook)

public zp_user_humanized_post(id)
	if(get_pcvar_num(cvar_reset) == 1)
		g_has_drag[id] = false

public newSpawn()
{
	for (new id = 1; id <= 32; id++)
	{
		if (g_hooked[id])
			drag_end(id)
	
		g_has_drag[id] = false
	}
}

public player_death()
{
	new id = read_data(2)
	
	if (g_hooked[id])
		drag_end(id)
	
	g_has_drag[id] = false
}

public client_connect(id)
	g_has_drag[id] = false

public client_disconnect(id)
{
	if (g_hooked[id])
		drag_end(id)
	
	if(g_unable2move[id])
		g_unable2move[id] = false
	
	g_has_drag[id] = false
}

public drag_start(id)
{		
	if (zp_get_user_zombie(id) && g_has_drag[id] && !g_drag_i[id]) {
		
		static Float:cdown
		cdown = get_pcvar_float(cvar_cooldown)

		if (!is_user_alive(id)) {
			client_print(id, print_chat, "[ZP] You can't drag if you are dead!")
			return PLUGIN_HANDLED
		}

		if (g_hooksLeft[id] <= 0) {
			client_print(id, print_chat, "[ZP] You can't drag anymore!")
			return PLUGIN_HANDLED
		}

		if (get_gametime() - g_lastHook[id] < cdown) {
			client_print(id, print_chat, "[ZP] Wait %.f0 sec. to drag again!", get_pcvar_float(cvar_cooldown) - (get_gametime() - g_lastHook[id]))
			return PLUGIN_HANDLED
		}
		
		if (zp_is_nemesis_round() && get_pcvar_num(cvar_nemesis) == 0) {
			client_print(id, print_chat, "[ZP] You can't drag in Nemesis mode!")
			return PLUGIN_HANDLED
		}

		new hooktarget, body
		get_user_aiming(id, hooktarget, body)
		
		if (is_user_alive(hooktarget)) {
			if (!zp_get_user_zombie(hooktarget))
				{
					if (zp_get_user_survivor(hooktarget) && get_pcvar_num(cvar_survivor) == 0) {
						client_print(id, print_chat, "[ZP] You can't drag Survivor!")
						return PLUGIN_HANDLED
					}
					
					g_hooked[id] = hooktarget
					emit_sound(hooktarget, CHAN_BODY, g_sndDrag, 1.0, ATTN_NORM, 0, PITCH_HIGH)
				}
			else
				{
					if (get_pcvar_num(cvar_mates) == 1)
					{
						g_hooked[id] = hooktarget
						emit_sound(hooktarget, CHAN_BODY, g_sndDrag, 1.0, ATTN_NORM, 0, PITCH_HIGH)
					}
					else
					{
						client_print(id, print_chat, "[ZP] You can't drag teammates!")
						return PLUGIN_HANDLED
					}
				}

			if (get_pcvar_float(cvar_dragspeed) <= 0.0)
				cvar_dragspeed = 1
			
			new parm[2]
			parm[0] = id
			parm[1] = hooktarget
			
			set_task(0.1, "reelin_player", id, parm, 2, "b")
			harpoon_target(parm)
			
			g_hooksLeft[id]--
			client_print(id, print_chat, "[ZP] You can drag player to youself %d time%s", g_hooksLeft[id], (g_hooksLeft[id] < 2) ? "" : "s")
			g_drag_i[id] = true
			
			if(get_pcvar_num(cvar_unb2move) == 1)
				g_unable2move[hooktarget] = true
				
			if(get_pcvar_num(cvar_unb2move) == 2)
				g_unable2move[id] = true
				
			if(get_pcvar_num(cvar_unb2move) == 3)
			{
				g_unable2move[hooktarget] = true
				g_unable2move[id] = true
			}
		} else {
			g_hooked[id] = 33
			noTarget(id)
			emit_sound(hooktarget, CHAN_BODY, g_sndMiss, 1.0, ATTN_NORM, 0, PITCH_HIGH)
			g_drag_i[id] = true
			g_hooksLeft[id]--
			client_print(id, print_chat, "[ZP] You can drag player to youself %d time%s", g_hooksLeft[id], (g_hooksLeft[id] < 2) ? "" : "s")
		}
	}
	else
		return PLUGIN_HANDLED
	
	return PLUGIN_CONTINUE
}

public reelin_player(parm[])
{
	new id = parm[0]
	new victim = parm[1]

	if (!g_hooked[id] || !is_user_alive(victim))
	{
		drag_end(id)
		return
	}

	new Float:fl_Velocity[3]
	new idOrigin[3], vicOrigin[3]

	get_user_origin(victim, vicOrigin)
	get_user_origin(id, idOrigin)

	new distance = get_distance(idOrigin, vicOrigin)

	if (distance > 1) {
		new Float:fl_Time = distance / get_pcvar_float(cvar_dragspeed)

		fl_Velocity[0] = (idOrigin[0] - vicOrigin[0]) / fl_Time
		fl_Velocity[1] = (idOrigin[1] - vicOrigin[1]) / fl_Time
		fl_Velocity[2] = (idOrigin[2] - vicOrigin[2]) / fl_Time
	} else {
		fl_Velocity[0] = 0.0
		fl_Velocity[1] = 0.0
		fl_Velocity[2] = 0.0
	}

	entity_set_vector(victim, EV_VEC_velocity, fl_Velocity)
}

public drag_end(id)
{
	g_hooked[id] = 0
	beam_remove(id)
	remove_task(id)
	
	if (g_drag_i[id])
		g_lastHook[id] = get_gametime()
	
	g_drag_i[id] = false
	g_unable2move[id] = false
}

public fw_TakeDamage(victim, inflictor, attacker, Float:damage)
{
	if (is_user_alive(attacker) && (get_pcvar_num(cvar_dmgtostop) > 0))
	{
		g_over_dmg[victim] = g_over_dmg[victim] + floatround(damage)
		if (g_over_dmg[victim] >= get_pcvar_num(cvar_dmgtostop))
		{
			g_over_dmg[victim] = 0
			drag_end(victim)
			return HAM_IGNORED;
		}
	}

	return HAM_IGNORED;
}

public fw_PlayerPreThink(id)
{
	if (!is_user_alive(id))
		return FMRES_IGNORED
	
	new button = get_user_button(id)
	new oldbutton = get_user_oldbutton(id)
	
	if (zp_get_user_zombie(id) && g_has_drag[id])
	{
		new weapon = get_user_weapon(id)
		
		switch (weapon)
		{
		case CSW_KNIFE:
			{
				set_pev(id, pev_viewmodel2, g_vmodel)
				set_pev(id, pev_weaponmodel2, g_pmodel)
			}
		}
		
		if(g_bind_use[id])
		{
			if (!(oldbutton & IN_USE) && (button & IN_USE))
				drag_start(id)
		
			if ((oldbutton & IN_USE) && !(button & IN_USE))
				drag_end(id)
		}
	}
	
	if (!g_drag_i[id]) {
		g_unable2move[id] = false
	}
		
	if (g_unable2move[id] && get_pcvar_num(cvar_unb2move) > 0)
	{
		set_pev(id, pev_maxspeed, 1.0)
	}
	
	return PLUGIN_CONTINUE
}

public harpoon_target(parm[])
{
	new id = parm[0]
	new hooktarget = parm[1]

	message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
	write_byte(8)
	write_short(id)
	write_short(hooktarget)
	write_short(g_Line)
	write_byte(0)
	write_byte(0)
	write_byte(200)
	write_byte(8)
	write_byte(1)
	write_byte(255)
	write_byte(0)
	write_byte(0)
	write_byte(90)
	write_byte(10)
	message_end()
}

public bind_v_key(id, keys)
{
	g_bind_or_not[id] = true
	switch(keys)
	{
		case 0:
			client_cmd(id, "bind v ^"+drag^"")
	
		case 1:
			client_print(id, print_chat, "[ZP] To drag player to youself (bind ^'^'key^'^' ^'^'+drag^'^') hold binded key")
			
		case 2:
			g_bind_use[id] = true
			
		default:
			g_bind_or_not[id] = false
	}
	
	return PLUGIN_HANDLED
}

public noTarget(id)
{
	new endorigin[3]

	get_user_origin(id, endorigin, 3)

	message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
	write_byte( TE_BEAMENTPOINT );
	write_short(id)
	write_coord(endorigin[0])
	write_coord(endorigin[1])
	write_coord(endorigin[2])
	write_short(g_Line)
	write_byte(0)
	write_byte(0)
	write_byte(200)
	write_byte(8)
	write_byte(1)
	write_byte(255)
	write_byte(0)
	write_byte(0)
	write_byte(75)
	write_byte(0)
	message_end()
}

public beam_remove(id)
{
	message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
	write_byte(99)
	write_short(id)
	message_end()
}
/* AMXX-Studio Notes - DO NOT MODIFY BELOW HERE
*{\\ rtf1\\ ansi\\ deff0{\\ fonttbl{\\ f0\\ fnil Tahoma;}}\n\\ viewkind4\\ uc1\\ pard\\ lang1049\\ f0\\ fs16 \n\\ par }
*/
Image

Rain1153
Senior Member
Senior Member
India
Posts: 278
Joined: 6 years ago
Contact:

#2

Post by Rain1153 » 5 years ago

well smoker/drag ability..i tried it it won't work in ZE
LOL

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

#3

Post by czirimbolo » 5 years ago

Maybe you are right, I will test it when someone convert it
Image

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

#4

Post by Night Fury » 5 years ago

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

#5

Post by czirimbolo » 5 years ago

The first plugin:

/ C:\Users\macie\Desktop\Compiler v1.8.3\scripting\ze_extra_tcannon.sma(288) : warning 233: symbol "client_disconnect" is marked as deprecated: Use client_disconnected() instead.
//
// C:\Users\macie\Desktop\Compiler v1.8.3\scripting\ze_extra_tcannon.sma(360) : error 022: must be lvalue (non-constant)
// C:\Users\macie\Desktop\Compiler v1.8.3\scripting\ze_extra_tcannon.sma(363) : warning 213: tag mismatch
// C:\Users\macie\Desktop\Compiler v1.8.3\scripting\ze_extra_tcannon.sma(372) : warning 213: tag mismatch
// C:\Users\macie\Desktop\Compiler v1.8.3\scripting\ze_extra_tcannon.sma(372) : warning 213: tag mismatch
// C:\Users\macie\Desktop\Compiler v1.8.3\scripting\ze_extra_tcannon.sma(376) : warning 213: tag mismatch
// C:\Users\macie\Desktop\Compiler v1.8.3\scripting\ze_extra_tcannon.sma(381) : warning 213: tag mismatch
// C:\Users\macie\Desktop\Compiler v1.8.3\scripting\ze_extra_tcannon.sma(398) : error 017: undefined symbol "id"
// C:\Users\macie\Desktop\Compiler v1.8.3\scripting\ze_extra_tcannon.sma(398) : warning 215: expression has no effect
// C:\Users\macie\Desktop\Compiler v1.8.3\scripting\ze_extra_tcannon.sma(398) : error 001: expected token: ";", but found ")"
// C:\Users\macie\Desktop\Compiler v1.8.3\scripting\ze_extra_tcannon.sma(398) : error 029: invalid expression, assumed zero
// C:\Users\macie\Desktop\Compiler v1.8.3\scripting\ze_extra_tcannon.sma(398) : fatal error 107: too many error messages on one line
//
// Compilation aborted.
// 5 Errors.
// Could not locate output file compiled\ze_extra_tcannon.amx (compile failed).
Image

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

#6

Post by czirimbolo » 5 years ago

When I buy drag ability, I have this model all the time (below) till the end of the round. Can't 'switch' this model to my normal hands. I dont know how to say, I would like to see my hands when I switch this 'drag ability' (like switchich the weapons) because when I buy it, I always have this model in whole round. Is it possible?
Attachments
Przechwytywanie.PNG
Przechwytywanie.PNG (262.57 KiB) Viewed 5921 times
Przechwytywanie.PNG
Przechwytywanie.PNG (262.57 KiB) Viewed 5921 times
Image

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

#7

Post by czirimbolo » 5 years ago

anyone can help?
Image

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

#8

Post by Night Fury » 5 years ago

Items issues not related.
Want your own mod edition? PM me.
Accepting private projects.
Discord: Fury#7469
Image

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