Botpack
Class UT_Eightball

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

class UT_Eightball
extends Botpack.TournamentWeapon

//============================================================================= // UT_Eightball. //=============================================================================
Variables
 RocketsLoaded, ClientRocketsLoaded
 RotateAnim[6], FireAnim[6]
 NewTarget, OldTarget
 bRotated, bPendingLock

States
FireRockets, ClientAltFiring, ClientFiring, ClientReload, Idle, NormalFire, AltFiring

Function Summary
 void AltFire(float Value)
 void BecomeItem()
 Actor CheckTarget()
 bool ClientAltFire(float Value)
 bool ClientFire(float Value)
 void Fire(float Value)
 
simulated
FiringRockets()
 
simulated
PlayIdleAnim()
 
simulated
PlayLoading(float rate, int num)
 
simulated
PlayRFiring(int num)
 
simulated
PlayRotating(int num)
 
simulated
PostRender(Canvas Canvas)
 float RateSelf(out int)
     
// tell bot how valuable this weapon would be to use, based on the bot's combat situation
// also suggest whether to use regular or alternate fire mode
 float SuggestAttackStyle()
     
// return delta to combat style while using this weapon
 void setHand(float Hand)


State FireRockets Function Summary
 void AnimEnd()
 void BeginState()
 bool SplashJump()
 void ForceAltFire()
 void ForceFire()
 void AltFire(float F)
 void Fire(float F)


State ClientAltFiring Function Summary


State ClientFiring Function Summary


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


State Idle Function Summary
 void Timer()


State NormalFire Function Summary
 void RotateRocket()
 void BeginState()
 void AnimEnd()
 void Tick(float DeltaTime)
 bool SplashJump()


State AltFiring Function Summary
 void BeginState()
 void RotateRocket()
 void AnimEnd()
 void Tick(float DeltaTime)



Source Code


00001	//=============================================================================
00002	// UT_Eightball.
00003	//=============================================================================
00004	class UT_Eightball extends TournamentWeapon;
00005	
00006	#exec MESH IMPORT MESH=Eightm ANIVFILE=MODELS\Eightball2_a.3D  DATAFILE=MODELS\Eightball2_d.3D X=0 Y=0 Z=0
00007	#exec MESH ORIGIN MESH=Eightm X=0 Y=0 Z=0 YAW=-64 ROLL=0
00008	#exec MESH SEQUENCE MESH=Eightm SEQ=All      STARTFRAME=0   NUMFRAMES=169
00009	#exec MESH SEQUENCE MESH=Eightm SEQ=Select   STARTFRAME=0   NUMFRAMES=20 RATE=33 GROUP=Select
00010	#exec MESH SEQUENCE MESH=Eightm SEQ=Still    STARTFRAME=19  NUMFRAMES=1
00011	#exec MESH SEQUENCE MESH=Eightm SEQ=Idle     STARTFRAME=19  NUMFRAMES=1
00012	#exec MESH SEQUENCE MESH=Eightm SEQ=Fire1    STARTFRAME=20  NUMFRAMES=8
00013	#exec MESH SEQUENCE MESH=Eightm SEQ=Load1    STARTFRAME=28  NUMFRAMES=7  RATE=15
00014	#exec MESH SEQUENCE MESH=Eightm SEQ=Rotate1  STARTFRAME=35  NUMFRAMES=7  RATE=15
00015	#exec MESH SEQUENCE MESH=Eightm SEQ=Load2    STARTFRAME=42  NUMFRAMES=7  RATE=15
00016	#exec MESH SEQUENCE MESH=Eightm SEQ=Fire2    STARTFRAME=49  NUMFRAMES=11
00017	#exec MESH SEQUENCE MESH=Eightm SEQ=Rotate2  STARTFRAME=60  NUMFRAMES=7  RATE=15
00018	#exec MESH SEQUENCE MESH=Eightm SEQ=Load3    STARTFRAME=67  NUMFRAMES=7  RATE=15
00019	#exec MESH SEQUENCE MESH=Eightm SEQ=Fire3    STARTFRAME=74  NUMFRAMES=10
00020	#exec MESH SEQUENCE MESH=Eightm SEQ=Rotate3  STARTFRAME=84  NUMFRAMES=7  RATE=15
00021	#exec MESH SEQUENCE MESH=Eightm SEQ=Load4    STARTFRAME=91  NUMFRAMES=7  RATE=15
00022	#exec MESH SEQUENCE MESH=Eightm SEQ=Fire4    STARTFRAME=98  NUMFRAMES=11
00023	#exec MESH SEQUENCE MESH=Eightm SEQ=Rotate4  STARTFRAME=109 NUMFRAMES=7  RATE=15
00024	#exec MESH SEQUENCE MESH=Eightm SEQ=Fire5    STARTFRAME=116 NUMFRAMES=13
00025	#exec MESH SEQUENCE MESH=Eightm SEQ=Fire6    STARTFRAME=130 NUMFRAMES=16
00026	#exec MESH SEQUENCE MESH=Eightm SEQ=Down     STARTFRAME=146 NUMFRAMES=11 
00027	#exec MESH SEQUENCE MESH=Eightm SEQ=Load5    STARTFRAME=157 NUMFRAMES=7  RATE=15 
00028	#exec MESH SEQUENCE MESH=Eightm SEQ=Rotate5  STARTFRAME=164 NUMFRAMES=7  RATE=15 
00029	#exec MESH SEQUENCE MESH=Eightm SEQ=Load6    STARTFRAME=171 NUMFRAMES=6  RATE=15 
00030	
00031	#exec TEXTURE IMPORT NAME=Eight_t FILE=MODELS\eightballpick.PCX GROUP="Skins" LODSET=2
00032	#exec TEXTURE IMPORT NAME=Eight_t1 FILE=MODELS\eight1.PCX GROUP="Skins" LODSET=2
00033	#exec TEXTURE IMPORT NAME=Eight_t2 FILE=MODELS\eight2.PCX GROUP="Skins" LODSET=2
00034	#exec TEXTURE IMPORT NAME=Eight_t3 FILE=MODELS\eight3.PCX GROUP="Skins" LODSET=2
00035	#exec TEXTURE IMPORT NAME=Eight_t4 FILE=MODELS\eight4.PCX GROUP="Skins" LODSET=2
00036	#exec OBJ LOAD FILE=Textures\Ammocount.utx  PACKAGE=Botpack.Ammocount
00037	#exec MESHMAP SCALE MESHMAP=Eightm X=0.006 Y=0.006 Z=0.012
00038	#exec MESHMAP SETTEXTURE MESHMAP=Eightm NUM=0 TEXTURE=eight_t1
00039	#exec MESHMAP SETTEXTURE MESHMAP=Eightm NUM=1 TEXTURE=eight_t2
00040	#exec MESHMAP SETTEXTURE MESHMAP=Eightm NUM=2 TEXTURE=eight_t3
00041	#exec MESHMAP SETTEXTURE MESHMAP=Eightm NUM=3 TEXTURE=eight_t4
00042	#exec MESHMAP SETTEXTURE MESHMAP=Eightm Num=4 TEXTURE=Botpack.Ammocount.MiniAmmoled
00043	
00044	// left handed version
00045	#exec MESH IMPORT MESH=EightmL ANIVFILE=MODELS\Eightball2_a.3D  DATAFILE=MODELS\Eightball2_d.3D UNMIRROR=1 UNMIRRORTEX=4
00046	#exec MESH ORIGIN MESH=EightmL X=0 Y=0 Z=0 YAW=-64 ROLL=0
00047	#exec MESH SEQUENCE MESH=EightmL SEQ=All      STARTFRAME=0   NUMFRAMES=169
00048	#exec MESH SEQUENCE MESH=EightmL SEQ=Select   STARTFRAME=0   NUMFRAMES=20 RATE=33 GROUP=Select
00049	#exec MESH SEQUENCE MESH=EightmL SEQ=Still    STARTFRAME=19  NUMFRAMES=1
00050	#exec MESH SEQUENCE MESH=EightmL SEQ=Idle     STARTFRAME=19  NUMFRAMES=1
00051	#exec MESH SEQUENCE MESH=EightmL SEQ=Fire1    STARTFRAME=20  NUMFRAMES=8
00052	#exec MESH SEQUENCE MESH=EightmL SEQ=Load1    STARTFRAME=28  NUMFRAMES=7  RATE=15
00053	#exec MESH SEQUENCE MESH=EightmL SEQ=Rotate1  STARTFRAME=35  NUMFRAMES=7  RATE=15
00054	#exec MESH SEQUENCE MESH=EightmL SEQ=Load2    STARTFRAME=42  NUMFRAMES=7  RATE=15
00055	#exec MESH SEQUENCE MESH=EightmL SEQ=Fire2    STARTFRAME=49  NUMFRAMES=11
00056	#exec MESH SEQUENCE MESH=EightmL SEQ=Rotate2  STARTFRAME=60  NUMFRAMES=7  RATE=15
00057	#exec MESH SEQUENCE MESH=EightmL SEQ=Load3    STARTFRAME=67  NUMFRAMES=7  RATE=15
00058	#exec MESH SEQUENCE MESH=EightmL SEQ=Fire3    STARTFRAME=74  NUMFRAMES=10
00059	#exec MESH SEQUENCE MESH=EightmL SEQ=Rotate3  STARTFRAME=84  NUMFRAMES=7  RATE=15
00060	#exec MESH SEQUENCE MESH=EightmL SEQ=Load4    STARTFRAME=91  NUMFRAMES=7  RATE=15
00061	#exec MESH SEQUENCE MESH=EightmL SEQ=Fire4    STARTFRAME=98  NUMFRAMES=11
00062	#exec MESH SEQUENCE MESH=EightmL SEQ=Rotate4  STARTFRAME=109 NUMFRAMES=7  RATE=15
00063	#exec MESH SEQUENCE MESH=EightmL SEQ=Fire5    STARTFRAME=116 NUMFRAMES=13
00064	#exec MESH SEQUENCE MESH=EightmL SEQ=Fire6    STARTFRAME=130 NUMFRAMES=16
00065	#exec MESH SEQUENCE MESH=EightmL SEQ=Down     STARTFRAME=146 NUMFRAMES=11 
00066	#exec MESH SEQUENCE MESH=EightmL SEQ=Load5    STARTFRAME=157 NUMFRAMES=7  RATE=15 
00067	#exec MESH SEQUENCE MESH=EightmL SEQ=Rotate5  STARTFRAME=164 NUMFRAMES=7  RATE=15 
00068	#exec MESH SEQUENCE MESH=EightmL SEQ=Load6    STARTFRAME=171 NUMFRAMES=6  RATE=15 
00069	
00070	#exec MESHMAP SCALE MESHMAP=EightmL X=0.006 Y=0.006 Z=0.012
00071	#exec MESHMAP SETTEXTURE MESHMAP=EightmL NUM=0 TEXTURE=eight_t1
00072	#exec MESHMAP SETTEXTURE MESHMAP=EightmL NUM=1 TEXTURE=eight_t2
00073	#exec MESHMAP SETTEXTURE MESHMAP=EightmL NUM=2 TEXTURE=eight_t3
00074	#exec MESHMAP SETTEXTURE MESHMAP=EightmL NUM=3 TEXTURE=eight_t4
00075	#exec MESHMAP SETTEXTURE MESHMAP=EightmL Num=4 TEXTURE=Botpack.Ammocount.MiniAmmoled
00076	
00077	#exec MESH IMPORT MESH=Eight2Pick ANIVFILE=MODELS\EightPick_a.3D DATAFILE=MODELS\EightPick_d.3D X=0 Y=0 Z=0
00078	#exec MESH ORIGIN MESH=Eight2Pick X=0 Y=170 Z=0 YAW=64
00079	#exec MESH SEQUENCE MESH=eight2pick SEQ=All    STARTFRAME=0   NUMFRAMES=1
00080	#exec MESH SEQUENCE MESH=eight2pick SEQ=Still  STARTFRAME=0   NUMFRAMES=1
00081	#exec MESHMAP SCALE MESHMAP=eight2pick X=0.12 Y=0.12 Z=0.24
00082	#exec MESHMAP SETTEXTURE MESHMAP=eight2pick NUM=2 TEXTURE=Eight_t
00083	
00084	// 3rd person perspective version
00085	#exec MESH IMPORT MESH=EightHand ANIVFILE=MODELS\EightPick_a.3D DATAFILE=MODELS\EightPick_d.3D
00086	#exec MESH ORIGIN MESH=EightHand X=-5 Y=-125 Z=-30 YAW=-64 
00087	#exec MESH SEQUENCE MESH=EightHand SEQ=All    STARTFRAME=0   NUMFRAMES=1
00088	#exec MESH SEQUENCE MESH=EightHand SEQ=Still  STARTFRAME=0   NUMFRAMES=1
00089	#exec MESHMAP SCALE MESHMAP=EightHand X=0.07 Y=0.07 Z=0.14
00090	#exec MESHMAP SETTEXTURE MESHMAP=EightHand NUM=2 TEXTURE=Eight_t
00091	
00092	#exec TEXTURE IMPORT NAME=Crosshair6 FILE=..\unrealshare\Textures\Hud\chair6.PCX GROUP="Icons" FLAGS=2 MIPS=OFF
00093	#exec TEXTURE IMPORT NAME=Icon8ball FILE=TEXTURES\HUD\WpnRockt.PCX GROUP="Icons" MIPS=OFF
00094	#exec TEXTURE IMPORT NAME=Use8ball FILE=TEXTURES\HUD\UseRockt.PCX GROUP="Icons" MIPS=OFF
00095	
00096	var name LoadAnim[6], RotateAnim[6], FireAnim[6];
00097	var int RocketsLoaded, ClientRocketsLoaded;
00098	var bool bFireLoad,bTightWad, bInstantRocket, bAlwaysInstant, bClientDone, bRotated, bPendingLock;
00099	var Actor LockedTarget, NewTarget, OldTarget;
00100	
00101	Replication
00102	{
00103		reliable if ( bNetOwner && (Role == ROLE_Authority) )
00104			bInstantRocket;
00105	}
00106	
00107	function setHand(float Hand)
00108	{
00109		Super.SetHand(Hand);
00110	
00111		if ( Hand == 0 )
00112			PlayerViewOffset.Y = 0;
00113		if ( Hand == 1 )
00114			Mesh = mesh(DynamicLoadObject("Botpack.EightML", class'Mesh'));
00115		else
00116			Mesh = mesh'EightM';
00117	}
00118	
00119	function BecomeItem()
00120	{
00121		local TournamentPlayer TP;
00122	
00123		Super.BecomeItem();
00124		TP = TournamentPlayer(Instigator);
00125		bInstantRocket = bAlwaysInstant || ( (TP != None) && TP.bInstantRocket );
00126	}
00127	
00128	simulated event RenderTexture(ScriptedTexture Tex)
00129	{
00130		local Color C;
00131		local string Temp;
00132		
00133		if ( AmmoType != None )
00134			Temp = String(AmmoType.AmmoAmount);
00135	
00136		while(Len(Temp) < 3) Temp = "0"$Temp;
00137	
00138		C.R = 255;
00139		C.G = 0;
00140		C.B = 0;
00141	
00142		Tex.DrawColoredText( 2, 10, Temp, Font'LEDFont2', C );	
00143	}
00144	
00145	simulated event RenderOverlays( canvas Canvas )
00146	{
00147		Texture'MiniAmmoled'.NotifyActor = Self;
00148		Super.RenderOverlays(Canvas);
00149		Texture'MiniAmmoled'.NotifyActor = None;
00150	}
00151	
00152	simulated function PostRender( canvas Canvas )
00153	{
00154		local float XScale;
00155	
00156		Super.PostRender(Canvas);
00157		bOwnsCrossHair = bLockedOn;
00158		if ( bOwnsCrossHair )
00159		{
00160			// if locked on, draw special crosshair
00161			XScale = FMax(1.0, Canvas.ClipX/640.0);
00162			Canvas.SetPos(0.5 * (Canvas.ClipX - Texture'Crosshair6'.USize * XScale), 0.5 * (Canvas.ClipY - Texture'Crosshair6'.VSize * XScale));
00163			Canvas.Style = ERenderStyle.STY_Normal;
00164			Canvas.DrawIcon(Texture'Crosshair6', 1.0);
00165			Canvas.Style = 1;	
00166		}
00167	}
00168			
00169	simulated function PlayLoading(float rate, int num)
00170	{
00171		if ( Owner == None )
00172			return;
00173		Owner.PlayOwnedSound(CockingSound, SLOT_None, Pawn(Owner).SoundDampening);
00174		PlayAnim(LoadAnim[num],, 0.05);
00175	}
00176	
00177	simulated function PlayRotating(int num)
00178	{
00179		Owner.PlayOwnedSound(Misc3Sound, SLOT_None, 0.1*Pawn(Owner).SoundDampening);
00180		PlayAnim(RotateAnim[num],, 0.05);
00181	}
00182	
00183	simulated function PlayRFiring(int num)
00184	{
00185		if ( Owner.IsA('PlayerPawn') )
00186		{
00187			PlayerPawn(Owner).shakeview(ShakeTime, ShakeMag*RocketsLoaded, ShakeVert); //shake player view
00188			PlayerPawn(Owner).ClientInstantFlash( -0.4, vect(650, 450, 190));
00189		}
00190		if ( Affector != None )
00191			Affector.FireEffect();
00192		if ( bFireLoad )
00193			PlayOwnedSound(class'RocketMk2'.Default.SpawnSound, SLOT_None, 4.0*Pawn(Owner).SoundDampening);
00194		else
00195			PlayOwnedSound(AltFireSound, SLOT_None, 4.0*Pawn(Owner).SoundDampening);
00196		if ( bFireLoad && bInstantRocket )
00197			PlayAnim(FireAnim[num], 0.54, 0.05);
00198		else				
00199			PlayAnim(FireAnim[num], 0.6, 0.05);
00200	}
00201	
00202	simulated function PlayIdleAnim()
00203	{
00204		if ( Mesh == PickupViewMesh )
00205			return;
00206		if (AnimSequence == LoadAnim[0] )
00207			PlayAnim('Idle',0.1,0.0);
00208		else
00209			TweenAnim('Idle', 0.5);
00210	}
00211	
00212	// tell bot how valuable this weapon would be to use, based on the bot's combat situation
00213	// also suggest whether to use regular or alternate fire mode
00214	function float RateSelf( out int bUseAltMode )
00215	{
00216		local float EnemyDist, Rating;
00217		local bool bRetreating;
00218		local vector EnemyDir;
00219		local Pawn P;
00220	
00221		// don't recommend self if out of ammo
00222		if ( AmmoType.AmmoAmount <=0 )
00223			return -2;
00224	
00225		// by default use regular mode (rockets)
00226		bUseAltMode = 0;
00227		P = Pawn(Owner);
00228		if ( P.Enemy == None )
00229			return AIRating;
00230	
00231		// if standing on a lift, make sure not about to go around a corner and lose sight of target
00232		// (don't want to blow up a rocket in bot's face)
00233		if ( (P.Base != None) && (P.Base.Velocity != vect(0,0,0))
00234			&& !P.CheckFutureSight(0.1) )
00235			return 0.1;
00236	
00237		EnemyDir = P.Enemy.Location - Owner.Location; 
00238		EnemyDist = VSize(EnemyDir);
00239		Rating = AIRating;
00240	
00241		// don't pick rocket launcher is enemy is too close
00242		if ( EnemyDist < 360 )
00243		{
00244			if ( P.Weapon == self )
00245			{
00246				// don't switch away from rocket launcher unless really bad tactical situation
00247				if ( (EnemyDist > 230) || ((P.Health < 50) && (P.Health < P.Enemy.Health - 30)) )
00248					return Rating;
00249			}
00250			return 0.05 + EnemyDist * 0.001;
00251		}
00252	
00253		// increase rating for situations for which rocket launcher is well suited
00254		if ( P.Enemy.IsA('StationaryPawn') )
00255			Rating += 0.4;
00256	
00257		// rockets are good if higher than target, bad if lower than target
00258		if ( Owner.Location.Z > P.Enemy.Location.Z + 120 )
00259			Rating += 0.25;
00260		else if ( P.Enemy.Location.Z > Owner.Location.Z + 160 )
00261			Rating -= 0.35;
00262		else if ( P.Enemy.Location.Z > Owner.Location.Z + 80 )
00263			Rating -= 0.05;
00264	
00265		// decide if should use alternate fire (grenades) instead
00266		if ( (Owner.Physics == PHYS_Falling) || Owner.Region.Zone.bWaterZone )
00267			bUseAltMode = 0;
00268		else if ( EnemyDist < -1.5 * EnemyDir.Z )
00269			bUseAltMode = int( FRand() < 0.5 );
00270		else
00271		{
00272			// grenades are good covering fire when retreating
00273			bRetreating = ( ((EnemyDir/EnemyDist) Dot Owner.Velocity) < -0.7 );
00274			bUseAltMode = 0;
00275			if ( bRetreating && (EnemyDist < 800) && (FRand() < 0.4) )
00276				bUseAltMode = 1;
00277		}
00278		return Rating;
00279	}
00280	
00281	// return delta to combat style while using this weapon
00282	function float SuggestAttackStyle()
00283	{
00284		local float EnemyDist;
00285	
00286		// recommend backing off if target is too close
00287		EnemyDist = VSize(Pawn(Owner).Enemy.Location - Owner.Location);
00288		if ( EnemyDist < 600 )
00289		{
00290			if ( EnemyDist < 300 )
00291				return -1.5;
00292			else
00293				return -0.7;
00294		}
00295		else
00296			return -0.2;
00297	}
00298	
00299	function Fire( float Value )
00300	{
00301		local TournamentPlayer TP;
00302	
00303		bPointing=True;
00304		if ( AmmoType == None )
00305		{
00306			// ammocheck
00307			GiveAmmo(Pawn(Owner));
00308		}
00309		if ( AmmoType.UseAmmo(1) )
00310		{
00311			TP = TournamentPlayer(Instigator);
00312			bCanClientFire = true;
00313			bInstantRocket = bAlwaysInstant || ( (TP != None) && TP.bInstantRocket );
00314			if ( bInstantRocket )
00315			{
00316				bFireLoad = True;
00317				RocketsLoaded = 1;
00318				GotoState('');
00319				GotoState('FireRockets', 'Begin');
00320			}
00321			else if ( Instigator.IsA('Bot') )
00322			{
00323				if ( LockedTarget != None )
00324				{
00325					bFireLoad = True;
00326					RocketsLoaded = 1;
00327					Instigator.bFire = 0;
00328					bPendingLock = true;
00329					GotoState('');
00330					GotoState('FireRockets', 'Begin');
00331					return;
00332				}
00333				else if ( (NewTarget != None) && !NewTarget.IsA('StationaryPawn')
00334					&& (FRand() < 0.8)
00335					&& (VSize(Instigator.Location - NewTarget.Location) > 400 + 400 * (1.25 - TimerCounter) + 1300 * FRand()) )
00336				{
00337					Instigator.bFire = 0;
00338					bPendingLock = true;
00339					GotoState('Idle','PendingLock');
00340					return;
00341				}
00342				else if ( !Bot(Owner).bNovice 
00343						&& (FRand() < 0.7)
00344						&& IsInState('Idle') && (Instigator.Enemy != None)
00345						&& ((Instigator.Enemy == Instigator.Target) || (Instigator.Target == None))
00346						&& !Instigator.Enemy.IsA('StationaryPawn')
00347						&& (VSize(Instigator.Location - Instigator.Enemy.Location) > 700 + 1300 * FRand())
00348						&& (VSize(Instigator.Location - Instigator.Enemy.Location) < 2000) )
00349				{
00350					NewTarget = CheckTarget();
00351					OldTarget = NewTarget;
00352					if ( NewTarget == Instigator.Enemy )
00353					{
00354						if ( TimerCounter > 0.6 )
00355							SetTimer(1.0, true);
00356						Instigator.bFire = 0;
00357						bPendingLock = true;
00358						GotoState('Idle','PendingLock');
00359						return;
00360					}
00361				}
00362				bPendingLock = false;
00363				GotoState('NormalFire');
00364			}
00365			else
00366				GotoState('NormalFire');
00367		}
00368	}
00369	
00370	simulated function bool ClientFire( float Value )
00371	{
00372		if ( bCanClientFire && ((Role == ROLE_Authority) || (AmmoType == None) || (AmmoType.AmmoAmount > 0)) )
00373		{
00374			GotoState('ClientFiring');
00375			return true;
00376		}
00377		return false;
00378	}
00379	
00380	simulated function FiringRockets()
00381	{
00382		PlayRFiring(ClientRocketsLoaded - 1);
00383		bClientDone = true;
00384		Disable('Tick');
00385	}
00386	
00387	function AltFire( float Value )
00388	{
00389		bPointing=True;
00390		bCanClientFire = true;
00391		if ( AmmoType == None )
00392		{
00393			// ammocheck
00394			GiveAmmo(Pawn(Owner));
00395		}
00396		if ( AmmoType.UseAmmo(1) )
00397			GoToState('AltFiring');
00398	}
00399	
00400	simulated function bool ClientAltFire( float Value )
00401	{
00402		if ( bCanClientFire && ((Role == ROLE_Authority) || (AmmoType == None) || (AmmoType.AmmoAmount > 0)) )
00403		{
00404			GotoState('ClientAltFiring');
00405			return true;
00406		}
00407		return false;
00408	}
00409	
00410	function Actor CheckTarget()
00411	{
00412		local Actor ETarget;
00413		local Vector Start, X,Y,Z;
00414		local float bestDist, bestAim;
00415		local Pawn PawnOwner;
00416		local rotator AimRot;
00417		local int diff;
00418	
00419		PawnOwner = Pawn(Owner);
00420		bPointing = false;
00421		if ( Owner.IsA('PlayerPawn') )
00422		{
00423			GetAxes(PawnOwner.ViewRotation,X,Y,Z);
00424			Start = Owner.Location + CalcDrawOffset() + FireOffset.X * X + FireOffset.Y * Y + FireOffset.Z * Z; 
00425			bestAim = 0.93;
00426			ETarget = PawnOwner.PickTarget(bestAim, bestDist, X, Start);
00427		}
00428		else if ( PawnOwner.Enemy == None )
00429			return None; 
00430		else if ( Owner.IsA('Bot') && Bot(Owner).bNovice )
00431			return None;
00432		else if ( VSize(PawnOwner.Enemy.Location - PawnOwner.Location) < 2000 )
00433		{
00434			Start = Owner.Location + CalcDrawOffset() + FireOffset.Z * vect(0,0,1); 
00435			AimRot = rotator(PawnOwner.Enemy.Location - Start);
00436			diff = abs((AimRot.Yaw & 65535) - (PawnOwner.Rotation.Yaw & 65535));
00437			if ( (diff > 7200) && (diff < 58335) )
00438				return None;
00439			// check if can hold lock
00440			if ( !bPendingLock ) //not already locked
00441			{
00442				AimRot = rotator(PawnOwner.Enemy.Location + (3 - PawnOwner.Skill) * 0.3 * PawnOwner.Enemy.Velocity - Start);
00443				diff = abs((AimRot.Yaw & 65535) - (PawnOwner.Rotation.Yaw & 65535));
00444				if ( (diff > 16000) && (diff < 49535) )
00445					return None;
00446			}
00447								 
00448			// check line of sight
00449			ETarget = Trace(X,Y, PawnOwner.Enemy.Location, Start, false);
00450			if ( ETarget != None )
00451				return None;
00452	
00453			return PawnOwner.Enemy;
00454		}
00455		bPointing = (ETarget != None);
00456		Return ETarget;
00457	}
00458	
00459	//////////////////////////////////////////////////////
00460	state AltFiring
00461	{
00462		function Tick( float DeltaTime )
00463		{
00464			if( (pawn(Owner).bAltFire==0) || (RocketsLoaded > 5) )  // If if Fire button down, load up another
00465	 			GoToState('FireRockets');
00466		}
00467	
00468		
00469		function AnimEnd()
00470		{
00471			if ( bRotated )
00472			{
00473				bRotated = false;
00474				PlayLoading(1.1, RocketsLoaded);
00475			}
00476			else
00477			{
00478				if ( RocketsLoaded == 6 )
00479				{
00480					GotoState('FireRockets');
00481					return;
00482				}
00483				RocketsLoaded++;
00484				AmmoType.UseAmmo(1);		
00485				if ( (PlayerPawn(Owner) == None) && ((FRand() > 0.5) || (Pawn(Owner).Enemy == None)) )
00486					Pawn(Owner).bAltFire = 0;
00487				bPointing = true;
00488				Owner.MakeNoise(0.6 * Pawn(Owner).SoundDampening);		
00489				RotateRocket();
00490			}
00491		}
00492	
00493		function RotateRocket()
00494		{
00495			if (AmmoType.AmmoAmount<=0)
00496			{ 
00497				GotoState('FireRockets');
00498				return;
00499			}		
00500			PlayRotating(RocketsLoaded-1);
00501			bRotated = true;
00502		}
00503	
00504		function BeginState()
00505		{
00506			Super.BeginState();
00507			RocketsLoaded = 1;
00508			bFireLoad = False;
00509			RotateRocket();
00510		}
00511	
00512	Begin:
00513		bLockedOn = False;
00514	}
00515	
00516	///////////////////////////////////////////////////////
00517	state NormalFire
00518	{
00519		function bool SplashJump()
00520		{
00521			return true;
00522		}
00523	
00524		function Tick( float DeltaTime )
00525		{
00526			if ( (PlayerPawn(Owner) == None) 
00527				&& ((Pawn(Owner).MoveTarget != Pawn(Owner).Target) 
00528					|| (LockedTarget != None)
00529					|| (Pawn(Owner).Enemy == None)
00530					|| ( Mover(Owner.Base) != None )
00531					|| ((Owner.Physics == PHYS_Falling) && (Owner.Velocity.Z < 5))
00532					|| (VSize(Owner.Location - Pawn(Owner).Target.Location) < 400)
00533					|| !Pawn(Owner).CheckFutureSight(0.15)) )
00534				Pawn(Owner).bFire = 0;
00535	
00536			if( pawn(Owner).bFire==0 || RocketsLoaded > 5)  // If Fire button down, load up another
00537	 			GoToState('FireRockets');
00538		}
00539		
00540		function AnimEnd()
00541		{
00542			if ( bRotated )
00543			{
00544				bRotated = false;
00545				PlayLoading(1.1, RocketsLoaded);
00546			}
00547			else
00548			{
00549				if ( RocketsLoaded == 6 )
00550				{
00551					GotoState('FireRockets');
00552					return;
00553				}
00554				RocketsLoaded++;
00555				AmmoType.UseAmmo(1);
00556				if (pawn(Owner).bAltFire!=0) bTightWad=True;
00557				NewTarget = CheckTarget();
00558				if ( Pawn(NewTarget) != None )
00559					Pawn(NewTarget).WarnTarget(Pawn(Owner), ProjectileSpeed, vector(Pawn(Owner).ViewRotation));	
00560				if ( LockedTarget != None )
00561				{
00562					If ( NewTarget != LockedTarget ) 
00563					{
00564						LockedTarget = None;
00565						Owner.PlaySound(Misc2Sound, SLOT_None, Pawn(Owner).SoundDampening);
00566						bLockedOn=False;
00567					}
00568					else if (LockedTarget != None)
00569	 					Owner.PlaySound(Misc1Sound, SLOT_None, Pawn(Owner).SoundDampening);
00570				}
00571				bPointing = true;
00572				Owner.MakeNoise(0.6 * Pawn(Owner).SoundDampening);		
00573				RotateRocket();
00574			}
00575		}
00576	
00577		function BeginState()
00578		{
00579			Super.BeginState();
00580			bFireLoad = True;
00581			RocketsLoaded = 1;
00582			RotateRocket();
00583		}
00584	
00585		function RotateRocket()
00586		{
00587			if ( PlayerPawn(Owner) == None )
00588			{
00589				if ( FRand() > 0.33 )
00590					Pawn(Owner).bFire = 0;
00591				if ( Pawn(Owner).bFire == 0 )
00592				{
00593		 			GoToState('FireRockets');
00594					return;
00595				}
00596			}
00597			if ( AmmoType.AmmoAmount <= 0 ) 
00598			{
00599				GotoState('FireRockets');
00600				return;
00601			}
00602			if ( AmmoType.AmmoAmount == 1 )
00603				Owner.PlaySound(Misc2Sound, SLOT_None, Pawn(Owner).SoundDampening); 
00604			PlayRotating(RocketsLoaded-1);
00605			bRotated = true;
00606		}
00607					
00608	Begin:
00609		Sleep(0.0);
00610	}
00611	
00612	///////////////////////////////////////////////////////
00613	state Idle
00614	{
00615		function Timer()
00616		{
00617			NewTarget = CheckTarget();
00618			if ( NewTarget == OldTarget )
00619			{
00620				LockedTarget = NewTarget;
00621				If (LockedTarget != None) 
00622				{
00623					bLockedOn=True;			
00624					Owner.MakeNoise(Pawn(Owner).SoundDampening);
00625					Owner.PlaySound(Misc1Sound, SLOT_None,Pawn(Owner).SoundDampening);
00626					if ( (Pawn(LockedTarget) != None) && (FRand() < 0.7) )
00627						Pawn(LockedTarget).WarnTarget(Pawn(Owner), ProjectileSpeed, vector(Pawn(Owner).ViewRotation));	
00628					if ( bPendingLock )
00629					{
00630						OldTarget = NewTarget;
00631						Pawn(Owner).bFire = 0;
00632						bFireLoad = True;
00633						RocketsLoaded = 1;
00634						GotoState('FireRockets', 'Begin');
00635						return;
00636					}
00637				}
00638			}
00639			else if( (OldTarget != None) && (NewTarget == None) ) 
00640			{
00641				Owner.PlaySound(Misc2Sound, SLOT_None,Pawn(Owner).SoundDampening);
00642				bLockedOn = False;
00643			}
00644			else 
00645			{
00646				LockedTarget = None;
00647				bLockedOn = False;
00648			}
00649			OldTarget = NewTarget;
00650			bPendingLock = false;
00651		}
00652	
00653	Begin:
00654		if (Pawn(Owner).bFire!=0) Fire(0.0);
00655		if (Pawn(Owner).bAltFire!=0) AltFire(0.0);	
00656		bPointing=False;
00657		if (AmmoType.AmmoAmount<=0) 
00658			Pawn(Owner).SwitchToBestWeapon();  //Goto Weapon that has Ammo
00659		PlayIdleAnim();
00660		OldTarget = CheckTarget();
00661		SetTimer(1.25,True);
00662		LockedTarget = None;
00663		bLockedOn = False;
00664	PendingLock:
00665		if ( bPendingLock )
00666			bPointing = true;
00667		if ( TimerRate <= 0 )
00668			SetTimer(1.0, true);
00669	}
00670	
00671	
00672	state ClientReload
00673	{
00674		simulated function bool ClientFire(float Value)
00675		{
00676			bForceFire = bForceFire || ( bCanClientFire && (Pawn(Owner) != None) && (AmmoType.AmmoAmount > 0) );
00677			return bForceFire;
00678		}
00679	
00680		simulated function bool ClientAltFire(float Value)
00681		{
00682			bForceAltFire = bForceAltFire || ( bCanClientFire && (Pawn(Owner) != None) && (AmmoType.AmmoAmount > 0) );
00683			return bForceAltFire;
00684		}
00685	
00686		simulated function AnimEnd()
00687		{
00688			if ( bCanClientFire && (PlayerPawn(Owner) != None) && (AmmoType.AmmoAmount > 0) )
00689			{
00690				if ( bForceFire || (Pawn(Owner).bFire != 0) )
00691				{
00692					Global.ClientFire(0);
00693					return;
00694				}
00695				else if ( bForceAltFire || (Pawn(Owner).bAltFire != 0) )
00696				{
00697					Global.ClientAltFire(0);
00698					return;
00699				}
00700			}			
00701			GotoState('');
00702			Global.AnimEnd();
00703		}
00704	
00705		simulated function EndState()
00706		{
00707			bForceFire = false;
00708			bForceAltFire = false;
00709		}
00710	
00711		simulated function BeginState()
00712		{
00713			bForceFire = false;
00714			bForceAltFire = false;
00715		}
00716	}
00717	
00718	state ClientFiring
00719	{
00720		simulated function Tick(float DeltaTime)
00721		{
00722			if ( (Pawn(Owner).bFire == 0) || (Ammotype.AmmoAmount <= 0) )
00723				FiringRockets();
00724		}
00725		
00726		simulated function AnimEnd()
00727		{
00728			if ( !bCanClientFire || (Pawn(Owner) == None) )
00729				GotoState('');
00730			else if ( bClientDone )
00731			{
00732				PlayLoading(1.5,0);
00733				GotoState('ClientReload');
00734			}
00735			else if ( bRotated )
00736			{
00737				PlayLoading(1.1, ClientRocketsLoaded);
00738				bRotated = false;
00739				ClientRocketsLoaded++;
00740			}
00741			else
00742			{
00743				if ( bInstantRocket || (ClientRocketsLoaded == 6) )
00744				{
00745					FiringRockets();
00746					return;
00747				}
00748				Enable('Tick');
00749				PlayRotating(ClientRocketsLoaded - 1);
00750				bRotated = true;
00751			}
00752		}
00753	
00754		simulated function BeginState()
00755		{
00756			bFireLoad = true;
00757			if ( bInstantRocket )
00758			{
00759				ClientRocketsLoaded = 1;
00760				FiringRockets();
00761			}
00762			else
00763			{
00764				ClientRocketsLoaded = 1;
00765				PlayRotating(ClientRocketsLoaded - 1);
00766				bRotated = true;
00767			}
00768		}
00769	
00770		simulated function EndState()
00771		{
00772			ClientRocketsLoaded = 0;
00773			bClientDone = false;
00774			bRotated = false;
00775		}
00776	}
00777	
00778	state ClientAltFiring
00779	{
00780		simulated function Tick(float DeltaTime)
00781		{
00782			if ( (Pawn(Owner).bAltFire == 0) || (Ammotype.AmmoAmount <= 0) )
00783				FiringRockets();
00784		}
00785		
00786		simulated function AnimEnd()
00787		{
00788			if ( !bCanClientFire || (Pawn(Owner) == None) )
00789				GotoState('');
00790			else if ( bClientDone )
00791			{
00792				PlayLoading(1.5,0);
00793				GotoState('ClientReload');
00794			}
00795			else if ( bRotated )
00796			{
00797				PlayLoading(1.1, ClientRocketsLoaded);
00798				bRotated = false;
00799				ClientRocketsLoaded++;
00800			}
00801			else
00802			{
00803				if ( ClientRocketsLoaded == 6 )
00804				{
00805					FiringRockets();
00806					return;
00807				}
00808				Enable('Tick');
00809				PlayRotating(ClientRocketsLoaded - 1);
00810				bRotated = true;
00811			}
00812		}
00813	
00814		simulated function BeginState()
00815		{
00816			bFireLoad = false;
00817			ClientRocketsLoaded = 1;
00818			PlayRotating(ClientRocketsLoaded - 1);
00819			bRotated = true;
00820		}
00821	
00822		simulated function EndState()
00823		{
00824			ClientRocketsLoaded = 0;
00825			bClientDone = false;
00826			bRotated = false;
00827		}
00828	}
00829	
00830	///////////////////////////////////////////////////////
00831	state FireRockets
00832	{
00833		function Fire(float F) {}
00834		function AltFire(float F) {}
00835	
00836		function ForceFire()
00837		{
00838			bForceFire = true;
00839		}
00840	
00841		function ForceAltFire()
00842		{
00843			bForceAltFire = true;
00844		}
00845	
00846		function bool SplashJump()
00847		{
00848			return false;
00849		}
00850	
00851		function BeginState()
00852		{
00853			local vector FireLocation, StartLoc, X,Y,Z;
00854			local rotator FireRot, RandRot;
00855			local rocketmk2 r;
00856			local UT_SeekingRocket s;
00857			local ut_grenade g;
00858			local float Angle, RocketRad;
00859			local pawn BestTarget, PawnOwner;
00860			local PlayerPawn PlayerOwner;
00861			local int DupRockets;
00862			local bool bMultiRockets;
00863	
00864			PawnOwner = Pawn(Owner);
00865			if ( PawnOwner == None )
00866				return;
00867			PawnOwner.PlayRecoil(FiringSpeed);
00868			PlayerOwner = PlayerPawn(Owner);
00869			Angle = 0;
00870			DupRockets = RocketsLoaded - 1;
00871			if (DupRockets < 0) DupRockets = 0;
00872			if ( PlayerOwner == None )
00873				bTightWad = ( FRand() * 4 < PawnOwner.skill );
00874	
00875			GetAxes(PawnOwner.ViewRotation,X,Y,Z);
00876			StartLoc = Owner.Location + CalcDrawOffset() + FireOffset.X * X + FireOffset.Y * Y + FireOffset.Z * Z; 
00877	
00878			if ( bFireLoad ) 		
00879				AdjustedAim = PawnOwner.AdjustAim(ProjectileSpeed, StartLoc, AimError, True, bWarnTarget);
00880			else 
00881				AdjustedAim = PawnOwner.AdjustToss(AltProjectileSpeed, StartLoc, AimError, True, bAltWarnTarget);	
00882				
00883			if ( PlayerOwner != None )
00884				AdjustedAim = PawnOwner.ViewRotation;
00885			
00886			PlayRFiring(RocketsLoaded-1);		
00887			Owner.MakeNoise(PawnOwner.SoundDampening);
00888			if ( !bFireLoad )
00889			{
00890				LockedTarget = None;
00891				bLockedOn = false;
00892			}
00893			else if ( LockedTarget != None )
00894			{
00895				BestTarget = Pawn(CheckTarget());
00896				if ( (LockedTarget!=None) && (LockedTarget != BestTarget) ) 
00897				{
00898					LockedTarget = None;
00899					bLockedOn=False;
00900				}
00901			}
00902			else 
00903				BestTarget = None;
00904			bPendingLock = false;
00905			bPointing = true;
00906			FireRot = AdjustedAim;
00907			RocketRad = 4;
00908			if (bTightWad || !bFireLoad) RocketRad=7;
00909			bMultiRockets = ( RocketsLoaded > 1 );
00910			While ( RocketsLoaded > 0 )
00911			{
00912				if ( bMultiRockets )
00913					Firelocation = StartLoc - (Sin(Angle)*RocketRad - 7.5)*Y + (Cos(Angle)*RocketRad - 7)*Z - X * 4 * FRand();
00914				else
00915					FireLocation = StartLoc;
00916				if (bFireLoad)
00917				{
00918					if ( Angle > 0 )
00919					{
00920						if ( Angle < 3 && !bTightWad)
00921							FireRot.Yaw = AdjustedAim.Yaw - Angle * 600;
00922						else if ( Angle > 3.5 && !bTightWad)
00923							FireRot.Yaw = AdjustedAim.Yaw + (Angle - 3)  * 600;
00924						else
00925							FireRot.Yaw = AdjustedAim.Yaw;
00926					}
00927					if ( LockedTarget != None )
00928					{
00929						s = Spawn( class 'ut_SeekingRocket',, '', FireLocation,FireRot);
00930						s.Seeking = LockedTarget;
00931						s.NumExtraRockets = DupRockets;					
00932						if ( Angle > 0 )
00933							s.Velocity *= (0.9 + 0.2 * FRand());			
00934					}
00935					else 
00936					{
00937						r = Spawn( class'rocketmk2',, '', FireLocation,FireRot);
00938						r.NumExtraRockets = DupRockets;
00939						if (RocketsLoaded>4 && bTightWad) r.bRing=True;
00940						if ( Angle > 0 )
00941							r.Velocity *= (0.9 + 0.2 * FRand());			
00942					}
00943				}
00944				else 
00945				{
00946					g = Spawn( class 'ut_Grenade',, '', FireLocation,AdjustedAim);
00947					g.NumExtraGrenades = DupRockets;
00948					if ( DupRockets > 0 )
00949					{
00950						RandRot.Pitch = FRand() * 1500 - 750;
00951						RandRot.Yaw = FRand() * 1500 - 750;
00952						RandRot.Roll = FRand() * 1500 - 750;
00953						g.Velocity = g.Velocity >> RandRot;
00954					}
00955				}
00956	
00957				Angle += 1.0484; //2*3.1415/6;
00958				RocketsLoaded--;
00959			}
00960			bTightWad=False;
00961			bRotated = false;
00962		}
00963	
00964		function AnimEnd()
00965		{
00966			if ( !bRotated && (AmmoType.AmmoAmount > 0) ) 
00967			{	
00968				PlayLoading(1.5,0);
00969				RocketsLoaded = 1;
00970				bRotated = true;
00971				return;
00972			}
00973			LockedTarget = None;
00974			Finish();
00975		}
00976	Begin:	
00977	}
00978	
00979	defaultproperties
00980	{
00981	     LoadAnim(0)=load1
00982	     LoadAnim(1)=Load2
00983	     LoadAnim(2)=Load3
00984	     LoadAnim(3)=Load4
00985	     LoadAnim(4)=Load5
00986	     LoadAnim(5)=Load6
00987	     RotateAnim(0)=Rotate1
00988	     RotateAnim(1)=Rotate2
00989	     RotateAnim(2)=Rotate3
00990	     RotateAnim(3)=Rotate4
00991	     RotateAnim(4)=Rotate5
00992	     RotateAnim(5)=Rotate3
00993	     FireAnim(0)=Fire1
00994	     FireAnim(1)=Fire2
00995	     FireAnim(2)=Fire3
00996	     FireAnim(3)=Fire4
00997	     FireAnim(4)=Fire2
00998	     FireAnim(5)=Fire3
00999	     WeaponDescription="Classification: Heavy Ballistic\n\nPrimary Fire: Slow moving but deadly rockets are fired at opponents. Trigger can be held down to load up to six rockets at a time, which can be fired at once.\n\nSecondary Fire: Grenades are lobbed from the barrel. Secondary trigger can be held as well to load up to six grenades.\n\nTechniques: Keeping this weapon pointed at an opponent will cause it to lock on, and while the gun is locked the next rocket fired will be a homing rocket.  Because the Rocket Launcher can load up multiple rockets, it fires when you release the fire button.  If you prefer, it can be configured to fire a rocket as soon as you press fire button down, at the expense of the multiple rocket load-up feature.  This is set in the Input Options menu."
01000	     AmmoName=Class'Botpack.RocketPack'
01001	     PickupAmmoCount=6
01002	     bWarnTarget=True
01003	     bAltWarnTarget=True
01004	     bSplashDamage=True
01005	     bRecommendSplashDamage=True
01006	     FiringSpeed=1.000000
01007	     FireOffset=(X=10.000000,Y=-5.000000,Z=-8.800000)
01008	     ProjectileClass=Class'Botpack.RocketMk2'
01009	     AltProjectileClass=Class'Botpack.UT_Grenade'
01010	     shakemag=350.000000
01011	     shaketime=0.200000
01012	     shakevert=7.500000
01013	     AIRating=0.750000
01014	     RefireRate=0.250000
01015	     AltRefireRate=0.250000
01016	     AltFireSound=Sound'UnrealShare.Eightball.EightAltFire'
01017	     CockingSound=Sound'UnrealShare.Eightball.Loading'
01018	     SelectSound=Sound'UnrealShare.Eightball.Selecting'
01019	     Misc1Sound=Sound'UnrealShare.Eightball.SeekLock'
01020	     Misc2Sound=Sound'UnrealShare.Eightball.SeekLost'
01021	     Misc3Sound=Sound'UnrealShare.Eightball.BarrelMove'
01022	     DeathMessage="%o was smacked down by %k's %w."
01023	     NameColor=(G=0,B=0)
01024	     AutoSwitchPriority=9
01025	     InventoryGroup=9
01026	     PickupMessage="You got the Rocket Launcher."
01027	     ItemName="Rocket Launcher"
01028	     PlayerViewOffset=(X=2.400000,Y=-1.000000,Z=-2.200000)
01029	     PlayerViewMesh=LodMesh'Botpack.Eightm'
01030	     PlayerViewScale=2.000000
01031	     BobDamping=0.975000
01032	     PickupViewMesh=LodMesh'Botpack.Eight2Pick'
01033	     ThirdPersonMesh=LodMesh'Botpack.EightHand'
01034	     StatusIcon=Texture'Botpack.Icons.Use8ball'
01035	     PickupSound=Sound'UnrealShare.Pickups.WeaponPickup'
01036	     Icon=Texture'Botpack.Icons.Use8ball'
01037	     Mesh=LodMesh'Botpack.Eight2Pick'
01038	     bNoSmooth=False
01039	     CollisionHeight=10.000000
01040	}

End Source Code