Botpack
Class ShockRifle

source: e:\games\UnrealTournament\Botpack\Classes\ShockRifle.uc
Core.Object
   |
   +--Engine.Actor
      |
      +--Engine.Inventory
         |
         +--Engine.Weapon
            |
            +--Botpack.TournamentWeapon
               |
               +--Botpack.ShockRifle
Direct Known Subclasses:SuperShockRifle

class ShockRifle
extends Botpack.TournamentWeapon

//============================================================================= // ShockRifle. //=============================================================================
Variables
 int HitDamage
 float TapTime
 Projectile Tracked
 bool bBotSpecialMove

States
ClientFiring, ComboMove, Idle

Function Summary
 void AltFire(float Value)
 void Finish()
 
simulated
PlayAltFiring()
 
simulated
PlayFiring()
     
///////////////////////////////////////////////////////
 
simulated
PlayIdleAnim()
 void ProcessTraceHit(Actor Other, Vector HitLocation, Vector HitNormal, Vector X, Vector Y, Vector Z)
 float RateSelf(out int)
 void SpawnEffect(vector HitLocation, vector SmokeLocation)
 void Timer()
 void TraceFire(float Accuracy)


State ClientFiring Function Summary
 bool ClientAltFire(float Value)
 bool ClientFire(float Value)


State ComboMove Function Summary
 void Tick(float DeltaTime)
 void AltFire(float F)
 void Fire(float F)


State Idle Function Summary
 void EndState()
 void BeginState()



Source Code


00001	//=============================================================================
00002	// ShockRifle.
00003	//=============================================================================
00004	class ShockRifle extends TournamentWeapon;
00005	
00006	#exec MESH IMPORT MESH=ASMD2M ANIVFILE=MODELS\ASMD2_a.3D DATAFILE=MODELS\ASMD2_d.3D X=0 Y=0 Z=0
00007	#exec MESH ORIGIN MESH=ASMD2M X=0 Y=0 Z=0 YAW=64 PITCH=0
00008	#exec MESH SEQUENCE MESH=ASMD2M SEQ=All       STARTFRAME=0  NUMFRAMES=52
00009	#exec MESH SEQUENCE MESH=ASMD2M SEQ=Select    STARTFRAME=0  NUMFRAMES=15 RATE=30 GROUP=Select
00010	#exec MESH SEQUENCE MESH=ASMD2M SEQ=Still     STARTFRAME=15 NUMFRAMES=1
00011	#exec MESH SEQUENCE MESH=ASMD2M SEQ=Down      STARTFRAME=17 NUMFRAMES=7  RATE=27
00012	#exec MESH SEQUENCE MESH=ASMD2M SEQ=Still2    STARTFRAME=28 NUMFRAMES=2
00013	#exec MESH SEQUENCE MESH=ASMD2M SEQ=Fire1     STARTFRAME=30 NUMFRAMES=10  RATE=21
00014	#exec MESH SEQUENCE MESH=ASMD2M SEQ=Fire2     STARTFRAME=40 NUMFRAMES=10  RATE=24
00015	#exec TEXTURE IMPORT NAME=ASMD_t FILE=MODELS\ASMD.PCX GROUP="Skins" LODSET=2
00016	#exec TEXTURE IMPORT NAME=ASMD_t1 FILE=MODELS\ASMD1.PCX GROUP="Skins" LODSET=2
00017	#exec TEXTURE IMPORT NAME=ASMD_t2 FILE=MODELS\ASMD2.PCX GROUP="Skins" LODSET=2
00018	#exec TEXTURE IMPORT NAME=ASMD_t3 FILE=MODELS\ASMD3.PCX GROUP="Skins" LODSET=2
00019	#exec TEXTURE IMPORT NAME=ASMD_t4 FILE=MODELS\ASMD4.PCX GROUP="Skins" LODSET=2
00020	#exec MESHMAP SCALE MESHMAP=ASMD2M X=0.004 Y=0.003 Z=0.008
00021	#exec MESHMAP SETTEXTURE MESHMAP=ASMD2M NUM=0 TEXTURE=ASMD_t1
00022	#exec MESHMAP SETTEXTURE MESHMAP=ASMD2M NUM=1 TEXTURE=ASMD_t2
00023	#exec MESHMAP SETTEXTURE MESHMAP=ASMD2M NUM=2 TEXTURE=ASMD_t3
00024	#exec MESHMAP SETTEXTURE MESHMAP=ASMD2M NUM=3 TEXTURE=ASMD_t4
00025	
00026	#exec MESH IMPORT MESH=ASMD2pick ANIVFILE=MODELS\ASMDpick_a.3D DATAFILE=MODELS\ASMDpick_d.3D X=0 Y=0 Z=0
00027	#exec MESH ORIGIN MESH=ASMD2pick X=0 Y=0 Z=0 YAW=64 
00028	#exec MESH SEQUENCE MESH=ASMD2pick SEQ=All   STARTFRAME=0  NUMFRAMES=1
00029	#exec MESH SEQUENCE MESH=ASMD2pick SEQ=Still STARTFRAME=0  NUMFRAMES=1
00030	#exec MESHMAP SCALE MESHMAP=ASMD2pick X=0.07 Y=0.07 Z=0.14
00031	#exec MESHMAP SETTEXTURE MESHMAP=ASMD2pick NUM=1 TEXTURE=ASMD_t
00032	
00033	#exec MESH IMPORT MESH=ASMD2hand ANIVFILE=MODELS\ASMDhand_a.3D DATAFILE=MODELS\asmdhand_d.3D X=0 Y=0 Z=0
00034	#exec MESH ORIGIN MESH=ASMD2hand X=25 Y=600 Z=-40 YAW=64 PITCH=0
00035	#exec MESH SEQUENCE MESH=ASMD2hand SEQ=All   STARTFRAME=0  NUMFRAMES=10
00036	#exec MESH SEQUENCE MESH=ASMD2hand SEQ=Still STARTFRAME=0  NUMFRAMES=1
00037	#exec MESH SEQUENCE MESH=ASMD2hand SEQ=Fire1 STARTFRAME=1  NUMFRAMES=9  RATE=24
00038	#exec MESH SEQUENCE MESH=ASMD2hand SEQ=Fire2 STARTFRAME=1  NUMFRAMES=9  RATE=24
00039	#exec MESHMAP SCALE MESHMAP=ASMD2hand X=0.05 Y=0.05 Z=0.1
00040	#exec MESHMAP SETTEXTURE MESHMAP=ASMD2hand NUM=1 TEXTURE=ASMD_t
00041	
00042	#exec TEXTURE IMPORT NAME=IconASMD FILE=TEXTURES\HUD\WpnASMD.PCX GROUP="Icons" MIPS=OFF
00043	#exec TEXTURE IMPORT NAME=UseASMD FILE=TEXTURES\HUD\UseASMD.PCX GROUP="Icons" MIPS=OFF
00044	
00045	#exec AUDIO IMPORT FILE="..\UnrealShare\Sounds\Tazer\TSHOTA6.WAV" NAME="TazerFire" GROUP="ASMD"
00046	#exec AUDIO IMPORT FILE="..\UnrealShare\Sounds\Tazer\TSHOTB1.WAV" NAME="TazerAltFire" GROUP="ASMD"
00047	#exec AUDIO IMPORT FILE="..\UnrealShare\Sounds\Tazer\TPICKUP3.WAV" NAME="TazerSelect" GROUP="ASMD"
00048	#exec AUDIO IMPORT FILE="..\UnrealShare\Sounds\Tazer\Vapour1.WAV" NAME="Vapour" GROUP="ASMD"
00049	
00050	var() int HitDamage;
00051	var Projectile Tracked;
00052	var bool bBotSpecialMove;
00053	var float TapTime;
00054	
00055	function AltFire( float Value )
00056	{
00057		local actor HitActor;
00058		local vector HitLocation, HitNormal, Start; 
00059	
00060		if ( Owner == None )
00061			return;
00062	
00063		if ( Owner.IsA('Bot') ) //make sure won't blow self up
00064		{
00065			Start = Owner.Location + CalcDrawOffset() + FireOffset.Z * vect(0,0,1); 
00066			if ( Pawn(Owner).Enemy != None )
00067				HitActor = Trace(HitLocation, HitNormal, Start + 250 * Normal(Pawn(Owner).Enemy.Location - Start), Start, false, vect(12,12,12));
00068			else
00069				HitActor = self;
00070			if ( HitActor != None )
00071			{
00072				Global.Fire(Value);
00073				return;
00074			}
00075		}	
00076		if ( AmmoType.UseAmmo(1) )
00077		{
00078			GotoState('AltFiring');
00079			bCanClientFire = true;
00080			if ( Owner.IsA('Bot') )
00081			{
00082				if ( Owner.IsInState('TacticalMove') && (Owner.Target == Pawn(Owner).Enemy)
00083				 && (Owner.Physics == PHYS_Walking) && !Bot(Owner).bNovice
00084				 && (FRand() * 6 < Pawn(Owner).Skill) )
00085					Pawn(Owner).SpecialFire();
00086			}
00087			Pawn(Owner).PlayRecoil(FiringSpeed);
00088			bPointing=True;
00089			ProjectileFire(AltProjectileClass, AltProjectileSpeed, bAltWarnTarget);
00090			ClientAltFire(value);
00091		}
00092	}
00093	
00094	function TraceFire( float Accuracy )
00095	{
00096		local vector HitLocation, HitNormal, StartTrace, EndTrace, X,Y,Z;
00097		local actor Other;
00098	
00099		Owner.MakeNoise(Pawn(Owner).SoundDampening);
00100		GetAxes(Pawn(owner).ViewRotation,X,Y,Z);
00101		StartTrace = Owner.Location + CalcDrawOffset() + FireOffset.Y * Y + FireOffset.Z * Z; 
00102		EndTrace = StartTrace + Accuracy * (FRand() - 0.5 )* Y * 1000
00103			+ Accuracy * (FRand() - 0.5 ) * Z * 1000 ;
00104	
00105		if ( bBotSpecialMove && (Tracked != None)
00106			&& (((Owner.Acceleration == vect(0,0,0)) && (VSize(Owner.Velocity) < 40)) ||
00107				(Normal(Owner.Velocity) Dot Normal(Tracked.Velocity) > 0.95)) )
00108			EndTrace += 10000 * Normal(Tracked.Location - StartTrace);
00109		else
00110		{
00111			AdjustedAim = pawn(owner).AdjustAim(1000000, StartTrace, 2.75*AimError, False, False);	
00112			EndTrace += (10000 * vector(AdjustedAim)); 
00113		}
00114	
00115		Tracked = None;
00116		bBotSpecialMove = false;
00117	
00118		Other = Pawn(Owner).TraceShot(HitLocation,HitNormal,EndTrace,StartTrace);
00119		ProcessTraceHit(Other, HitLocation, HitNormal, vector(AdjustedAim),Y,Z);
00120	}
00121	
00122	function float RateSelf( out int bUseAltMode )
00123	{
00124		local Pawn P;
00125		local bool bNovice;
00126	
00127		if ( AmmoType.AmmoAmount <=0 )
00128			return -2;
00129	
00130		P = Pawn(Owner);
00131		bNovice = ( (Bot(Owner) == None) || Bot(Owner).bNovice );
00132		if ( P.Enemy == None )
00133			bUseAltMode = 0;
00134		else if ( P.Enemy.IsA('StationaryPawn') )
00135		{
00136			bUseAltMode = 1;
00137			return (AIRating + 0.4);
00138		}
00139		else if ( !bNovice && (P.IsInState('Hunting') || P.IsInState('StakeOut')
00140			|| P.IsInState('RangedAttack')
00141			|| (Level.TimeSeconds - P.LastSeenTime > 0.8)) )
00142		{
00143			bUseAltMode = 1;
00144			return (AIRating + 0.3);
00145		}
00146		else if ( !bNovice && (P.Acceleration == vect(0,0,0)) )
00147			bUseAltMode = 1;
00148		else if ( !bNovice && (VSize(P.Enemy.Location - P.Location) > 1200) )
00149		{
00150			bUseAltMode = 0;
00151			return (AIRating + 0.05 + FMin(0.00009 * VSize(P.Enemy.Location - P.Location), 0.3)); 
00152		}
00153		else if ( P.Enemy.Location.Z > P.Location.Z + 200 )
00154		{
00155			bUseAltMode = int( FRand() < 0.6 );
00156			return (AIRating + 0.15);
00157		} 
00158		else
00159			bUseAltMode = int( FRand() < 0.4 );
00160	
00161		return AIRating;
00162	}
00163	
00164	function Timer()
00165	{
00166		local actor targ;
00167		local float bestAim, bestDist;
00168		local vector FireDir;
00169		local Pawn P;
00170	
00171		bestAim = 0.95;
00172		P = Pawn(Owner);
00173		if ( P == None )
00174		{
00175			GotoState('');
00176			return;
00177		}
00178		FireDir = vector(P.ViewRotation);
00179		targ = P.PickTarget(bestAim, bestDist, FireDir, Owner.Location);
00180		if ( Pawn(targ) != None )
00181		{
00182			bPointing = true;
00183			Pawn(targ).WarnTarget(P, 300, FireDir);
00184			SetTimer(1 + 4 * FRand(), false);
00185		}
00186		else 
00187		{
00188			SetTimer(0.5 + 2 * FRand(), false);
00189			if ( (P.bFire == 0) && (P.bAltFire == 0) )
00190				bPointing = false;
00191		}
00192	}	
00193	
00194	function Finish()
00195	{
00196		if ( (Pawn(Owner).bFire!=0) && (FRand() < 0.6) )
00197			Timer();
00198		if ( !bChangeWeapon && (Tracked != None) && !Tracked.bDeleteMe && (Owner != None) 
00199			&& (Owner.IsA('Bot')) && (Pawn(Owner).Enemy != None) && (FRand() < 0.3 + 0.35 * Pawn(Owner).skill)
00200			&& (AmmoType.AmmoAmount > 0) ) 
00201		{
00202			if ( (Owner.Acceleration == vect(0,0,0)) ||
00203				(Abs(Normal(Owner.Velocity) dot Normal(Tracked.Velocity)) > 0.95) )
00204			{
00205				bBotSpecialMove = true;
00206				GotoState('ComboMove');
00207				return;
00208			}
00209		}
00210	
00211		bBotSpecialMove = false;
00212		Tracked = None;
00213		Super.Finish();
00214	}
00215	
00216	///////////////////////////////////////////////////////
00217	simulated function PlayFiring()
00218	{
00219		PlayOwnedSound(FireSound, SLOT_None, Pawn(Owner).SoundDampening*4.0);
00220		LoopAnim('Fire1', 0.30 + 0.30 * FireAdjust,0.05);
00221	}
00222	
00223	function Projectile ProjectileFire(class<projectile> ProjClass, float ProjSpeed, bool bWarn)
00224	{
00225		local Vector Start, X,Y,Z;
00226		local PlayerPawn PlayerOwner;
00227	
00228		Owner.MakeNoise(Pawn(Owner).SoundDampening);
00229		GetAxes(Pawn(owner).ViewRotation,X,Y,Z);
00230		Start = Owner.Location + CalcDrawOffset() + FireOffset.X * X + FireOffset.Y * Y + FireOffset.Z * Z; 
00231		AdjustedAim = pawn(owner).AdjustAim(ProjSpeed, Start, AimError, True, bWarn);	
00232	
00233		PlayerOwner = PlayerPawn(Owner);
00234		if ( PlayerOwner != None )
00235			PlayerOwner.ClientInstantFlash( -0.4, vect(450, 190, 650));
00236		Tracked = Spawn(ProjClass,,, Start,AdjustedAim);
00237		if ( Level.Game.IsA('DeathMatchPlus') && DeathmatchPlus(Level.Game).bNoviceMode )
00238			Tracked = None; //no combo move
00239	}
00240	
00241	function ProcessTraceHit(Actor Other, Vector HitLocation, Vector HitNormal, Vector X, Vector Y, Vector Z)
00242	{
00243		local int i;
00244		local PlayerPawn PlayerOwner;
00245	
00246		if (Other==None)
00247		{
00248			HitNormal = -X;
00249			HitLocation = Owner.Location + X*10000.0;
00250		}
00251	
00252		PlayerOwner = PlayerPawn(Owner);
00253		if ( PlayerOwner != None )
00254			PlayerOwner.ClientInstantFlash( -0.4, vect(450, 190, 650));
00255		SpawnEffect(HitLocation, Owner.Location + CalcDrawOffset() + (FireOffset.X + 20) * X + FireOffset.Y * Y + FireOffset.Z * Z);
00256	
00257		if ( ShockProj(Other)!=None )
00258		{ 
00259			AmmoType.UseAmmo(2);
00260			ShockProj(Other).SuperExplosion();
00261		}
00262		else
00263			Spawn(class'ut_RingExplosion5',,, HitLocation+HitNormal*8,rotator(HitNormal));
00264	
00265		if ( (Other != self) && (Other != Owner) && (Other != None) ) 
00266			Other.TakeDamage(HitDamage, Pawn(Owner), HitLocation, 60000.0*X, MyDamageType);
00267	}
00268	
00269	
00270	function SpawnEffect(vector HitLocation, vector SmokeLocation)
00271	{
00272		local ShockBeam Smoke,shock;
00273		local Vector DVector;
00274		local int NumPoints;
00275		local rotator SmokeRotation;
00276	
00277		DVector = HitLocation - SmokeLocation;
00278		NumPoints = VSize(DVector)/135.0;
00279		if ( NumPoints < 1 )
00280			return;
00281		SmokeRotation = rotator(DVector);
00282		SmokeRotation.roll = Rand(65535);
00283		
00284		Smoke = Spawn(class'ShockBeam',,,SmokeLocation,SmokeRotation);
00285		Smoke.MoveAmount = DVector/NumPoints;
00286		Smoke.NumPuffs = NumPoints - 1;	
00287	}
00288	
00289	simulated function PlayAltFiring()
00290	{
00291		PlayOwnedSound(AltFireSound, SLOT_None,Pawn(Owner).SoundDampening*4.0);
00292		LoopAnim('Fire2',0.4 + 0.4 * FireAdjust,0.05);
00293	}
00294	
00295	
00296	simulated function PlayIdleAnim()
00297	{
00298		if ( Mesh != PickupViewMesh )
00299			LoopAnim('Still',0.04,0.3);
00300	}
00301	
00302	state Idle
00303	{
00304	
00305		function BeginState()
00306		{
00307			bPointing = false;
00308			SetTimer(0.5 + 2 * FRand(), false);
00309			Super.BeginState();
00310			if (Pawn(Owner).bFire!=0) Fire(0.0);
00311			if (Pawn(Owner).bAltFire!=0) AltFire(0.0);		
00312		}
00313	
00314		function EndState()
00315		{
00316			SetTimer(0.0, false);
00317			Super.EndState();
00318		}
00319	}
00320	
00321	state ComboMove
00322	{
00323		function Fire(float F); 
00324		function AltFire(float F); 
00325	
00326		function Tick(float DeltaTime)
00327		{
00328			if ( (Owner == None) || (Pawn(Owner).Enemy == None) )
00329			{
00330				Tracked = None;
00331				bBotSpecialMove = false;
00332				Finish();
00333				return;
00334			}
00335			if ( (Tracked == None) || Tracked.bDeleteMe 
00336				|| (((Tracked.Location - Owner.Location) 
00337					dot (Tracked.Location - Pawn(Owner).Enemy.Location)) >= 0)
00338				|| (VSize(Tracked.Location - Pawn(Owner).Enemy.Location) < 100) )
00339				Global.Fire(0);
00340		}
00341	
00342	Begin:
00343		Sleep(7.0);
00344		Tracked = None;
00345		bBotSpecialMove = false;
00346		Global.Fire(0);
00347	}
00348	
00349	state ClientFiring
00350	{
00351		simulated function bool ClientFire(float Value)
00352		{
00353			if ( Level.TimeSeconds - TapTime < 0.2 )
00354				return false;
00355			bForceFire = bForceFire || ( bCanClientFire && (Pawn(Owner) != None) && (AmmoType.AmmoAmount > 0) );
00356			return bForceFire;
00357		}
00358	
00359		simulated function bool ClientAltFire(float Value)
00360		{
00361			if ( Level.TimeSeconds - TapTime < 0.2 )
00362				return false;
00363			bForceAltFire = bForceAltFire || ( bCanClientFire && (Pawn(Owner) != None) && (AmmoType.AmmoAmount > 0) );
00364			return bForceAltFire;
00365		}
00366	
00367		simulated function AnimEnd()
00368		{
00369			local bool bForce, bForceAlt;
00370	
00371			bForce = bForceFire;
00372			bForceAlt = bForceAltFire;
00373			bForceFire = false;
00374			bForceAltFire = false;
00375	
00376			if ( bCanClientFire && (PlayerPawn(Owner) != None) && (AmmoType.AmmoAmount > 0) )
00377			{
00378				if ( bForce || (Pawn(Owner).bFire != 0) )
00379				{
00380					Global.ClientFire(0);
00381					return;
00382				}
00383				else if ( bForceAlt || (Pawn(Owner).bAltFire != 0) )
00384				{
00385					Global.ClientAltFire(0);
00386					return;
00387				}
00388			}			
00389			Super.AnimEnd();
00390		}
00391	
00392		simulated function EndState()
00393		{
00394			bForceFire = false;
00395			bForceAltFire = false;
00396		}
00397	
00398		simulated function BeginState()
00399		{
00400			TapTime = Level.TimeSeconds;
00401			bForceFire = false;
00402			bForceAltFire = false;
00403		}
00404	}
00405	
00406	defaultproperties
00407	{
00408	     hitdamage=40
00409	     WeaponDescription="Classification: Energy Rifle\n\nPrimary Fire: Instant hit laser beam.\n\nSecondary Fire: Large, slow moving plasma balls.\n\nTechniques: Hitting the secondary fire plasma balls with the regular fire's laser beam will cause an immensely powerful explosion."
00410	     InstFlash=-0.400000
00411	     InstFog=(Z=800.000000)
00412	     AmmoName=Class'Botpack.ShockCore'
00413	     PickupAmmoCount=20
00414	     bInstantHit=True
00415	     bAltWarnTarget=True
00416	     bSplashDamage=True
00417	     FiringSpeed=2.000000
00418	     FireOffset=(X=10.000000,Y=-5.000000,Z=-8.000000)
00419	     AltProjectileClass=Class'Botpack.ShockProj'
00420	     MyDamageType=jolted
00421	     AIRating=0.630000
00422	     AltRefireRate=0.700000
00423	     FireSound=Sound'UnrealShare.ASMD.TazerFire'
00424	     AltFireSound=Sound'UnrealShare.ASMD.TazerAltFire'
00425	     SelectSound=Sound'UnrealShare.ASMD.TazerSelect'
00426	     DeathMessage="%k inflicted mortal damage upon %o with the %w."
00427	     NameColor=(R=128,G=0)
00428	     AutoSwitchPriority=4
00429	     InventoryGroup=4
00430	     PickupMessage="You got the ASMD Shock Rifle."
00431	     ItemName="Shock Rifle"
00432	     PlayerViewOffset=(X=4.400000,Y=-1.700000,Z=-1.600000)
00433	     PlayerViewMesh=LodMesh'Botpack.ASMD2M'
00434	     PlayerViewScale=2.000000
00435	     BobDamping=0.975000
00436	     PickupViewMesh=LodMesh'Botpack.ASMD2pick'
00437	     ThirdPersonMesh=LodMesh'Botpack.ASMD2hand'
00438	     StatusIcon=Texture'Botpack.Icons.UseASMD'
00439	     PickupSound=Sound'UnrealShare.Pickups.WeaponPickup'
00440	     Icon=Texture'Botpack.Icons.UseASMD'
00441	     Mesh=LodMesh'Botpack.ASMD2pick'
00442	     bNoSmooth=False
00443	     CollisionRadius=34.000000
00444	     CollisionHeight=8.000000
00445	     Mass=50.000000
00446	}

End Source Code