UnrealI
Class SkaarjTrooper

source: e:\games\UnrealTournament\UnrealI\Classes\SkaarjTrooper.uc
Core.Object
   |
   +--Engine.Actor
      |
      +--Engine.Pawn
         |
         +--UnrealShare.ScriptedPawn
            |
            +--UnrealShare.Skaarj
               |
               +--UnrealI.SkaarjTrooper
Direct Known Subclasses:SkaarjGunner, SkaarjInfantry, SkaarjOfficer, SkaarjSniper

class SkaarjTrooper
extends UnrealShare.Skaarj

//============================================================================= // SkaarjTrooper. //=============================================================================
Variables
 class WeaponType
 float duckTime

States
RangedAttack, MeleeAttack, Hunting, TacticalMove, Charging, Retreating, TakeHit, Startup

Function Summary
 void ChangedWeapon()
 void Died(Pawn Killer, name damageType, vector HitLocation)
 void PlayTakeHit(float tweentime, vector HitLoc, int damage)
 void PreBeginPlay()
     
//=========================================================================================
 void TossWeapon()


State RangedAttack Function Summary
 void EndState()
 void AnimEnd()
 void KeepAttacking()
 void TryToDuck(vector duckDir, bool bReversed)
 void PlayRangedAttack()
 void Bump(Actor Other)
 void TakeDamage(int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, name damageType)


State MeleeAttack Function Summary


State Hunting Function Summary
 void EndState()


State TacticalMove Function Summary
 void EndState()


State Charging Function Summary
 void EndState()


State Retreating Function Summary
 void EndState()


State TakeHit Function Summary
 void BeginState()


State Startup Function Summary
 void PlayLanded(float impactVel)
 void PlayVictoryDance()
 void PlayFiring()
 void PlayRangedAttack()
 void PlayThreatening()
 void PlayMovingAttack()
 void PlayRunning()
 void PlayChallenge()
 void PlayPatrolStop()
     
//Skaarj animations
 void PlayCock()
 bool CanFireAtEnemy()
 void TryToDuck(vector duckDir, bool bReversed)
 void WarnTarget(Pawn shooter, float projSpeed, vector FireDir)
 void Shield()
 void SetHome()
 void BeginState()



Source Code


00001	//=============================================================================
00002	// SkaarjTrooper.
00003	//=============================================================================
00004	class SkaarjTrooper extends Skaarj;
00005	 	
00006	#exec MESH IMPORT MESH=sktrooper ANIVFILE=MODELS\zaarj_a.3D DATAFILE=MODELS\zaarj_d.3D LODSTYLE=26 LODFRAME=406
00007	
00008	#exec MESH ORIGIN MESH=sktrooper X=0 Y=-150 Z=-20 YAW=64 ROLL=-64
00009	 
00010	#exec MESH SEQUENCE MESH=sktrooper SEQ=All			STARTFRAME=0  NUMFRAMES=583
00011	#exec MESH SEQUENCE MESH=sktrooper SEQ=Claw         STARTFRAME=0   NUMFRAMES=13  RATE=15    Group=Attack
00012	#exec MESH SEQUENCE MESH=sktrooper SEQ=GutHit       STARTFRAME=13  NUMFRAMES=1				Group=TakeHit
00013	#exec MESH SEQUENCE MESH=sktrooper SEQ=Breath       STARTFRAME=14  NUMFRAMES=12  RATE=6		Group=Waiting
00014	#exec MESH SEQUENCE MESH=sktrooper SEQ=Breath2      STARTFRAME=26  NUMFRAMES=8   RATE=6		Group=Waiting  
00015	#exec MESH SEQUENCE MESH=sktrooper SEQ=MButton1     STARTFRAME=34  NUMFRAMES=33  RATE=15
00016	#exec MESH SEQUENCE MESH=sktrooper SEQ=MButton2     STARTFRAME=44  NUMFRAMES=46  RATE=15
00017	#exec MESH SEQUENCE MESH=sktrooper SEQ=MButton3     STARTFRAME=54  NUMFRAMES=23  RATE=15
00018	#exec MESH SEQUENCE MESH=sktrooper SEQ=MButton4     STARTFRAME=67  NUMFRAMES=23  RATE=15
00019	#exec MESH SEQUENCE MESH=sktrooper SEQ=Button1      STARTFRAME=34  NUMFRAMES=10  RATE=15
00020	#exec MESH SEQUENCE MESH=sktrooper SEQ=Taunt1       STARTFRAME=34  NUMFRAMES=10  RATE=15	Group=Gesture
00021	#exec MESH SEQUENCE MESH=sktrooper SEQ=Button2      STARTFRAME=44  NUMFRAMES=10  RATE=15
00022	#exec MESH SEQUENCE MESH=sktrooper SEQ=Button3      STARTFRAME=54  NUMFRAMES=13  RATE=15
00023	#exec MESH SEQUENCE MESH=sktrooper SEQ=Button4      STARTFRAME=67  NUMFRAMES=10  RATE=15
00024	#exec MESH SEQUENCE MESH=sktrooper SEQ=Button5      STARTFRAME=77  NUMFRAMES=13  RATE=15
00025	#exec MESH SEQUENCE MESH=sktrooper SEQ=Death        STARTFRAME=90  NUMFRAMES=21  RATE=15
00026	#exec MESH SEQUENCE MESH=sktrooper SEQ=Death2       STARTFRAME=111 NUMFRAMES=13  RATE=15
00027	#exec MESH SEQUENCE MESH=sktrooper SEQ=Death3       STARTFRAME=124 NUMFRAMES=21  RATE=15
00028	#exec MESH SEQUENCE MESH=sktrooper SEQ=Death4       STARTFRAME=145 NUMFRAMES=11  RATE=15
00029	#exec MESH SEQUENCE MESH=sktrooper SEQ=Duck         STARTFRAME=156 NUMFRAMES=1				Group=Ducking
00030	#exec MESH SEQUENCE MESH=sktrooper SEQ=Fighter      STARTFRAME=157 NUMFRAMES=15  RATE=15
00031	#exec MESH SEQUENCE MESH=sktrooper SEQ=Firing       STARTFRAME=172 NUMFRAMES=5   RATE=15	Group=Waiting
00032	#exec MESH SEQUENCE MESH=sktrooper SEQ=Getup        STARTFRAME=177 NUMFRAMES=11  RATE=15    
00033	#exec MESH SEQUENCE MESH=sktrooper SEQ=guncheck     STARTFRAME=188 NUMFRAMES=7   RATE=6
00034	#exec MESH SEQUENCE MESH=sktrooper SEQ=gunfix       STARTFRAME=195 NUMFRAMES=8   RATE=6
00035	#exec MESH SEQUENCE MESH=sktrooper SEQ=HeadHit      STARTFRAME=203 NUMFRAMES=1				Group=TakeHit
00036	#exec MESH SEQUENCE MESH=sktrooper SEQ=Headup       STARTFRAME=204 NUMFRAMES=10  RATE=15
00037	#exec MESH SEQUENCE MESH=sktrooper SEQ=Jog2Fight    STARTFRAME=214 NUMFRAMES=10  RATE=15
00038	#exec MESH SEQUENCE MESH=sktrooper SEQ=FullJump     STARTFRAME=224 NUMFRAMES=15  RATE=15
00039	#exec MESH SEQUENCE MESH=sktrooper SEQ=Jump         STARTFRAME=224 NUMFRAMES=5   RATE=15
00040	#exec MESH SEQUENCE MESH=sktrooper SEQ=InAir        STARTFRAME=230 NUMFRAMES=1				Group=Jumping
00041	#exec MESH SEQUENCE MESH=sktrooper SEQ=Landed       STARTFRAME=234 NUMFRAMES=1				Group=Landing
00042	#exec MESH SEQUENCE MESH=sktrooper SEQ=Jump2        STARTFRAME=239 NUMFRAMES=1				Group=Jumping
00043	#exec MESH SEQUENCE MESH=sktrooper SEQ=Land         STARTFRAME=240 NUMFRAMES=1				Group=Landing
00044	#exec MESH SEQUENCE MESH=sktrooper SEQ=LeftDodge    STARTFRAME=241 NUMFRAMES=13  RATE=15    Group=Dodge
00045	#exec MESH SEQUENCE MESH=sktrooper SEQ=LeftHit      STARTFRAME=254 NUMFRAMES=1				Group=TakeHit
00046	#exec MESH SEQUENCE MESH=sktrooper SEQ=StrafeLeftFr STARTFRAME=255 NUMFRAMES=14  RATE=15	Group=MovingAttack
00047	#exec MESH SEQUENCE MESH=sktrooper SEQ=Looking      STARTFRAME=269 NUMFRAMES=23  RATE=15
00048	#exec MESH SEQUENCE MESH=sktrooper SEQ=StrafeLeft   STARTFRAME=292 NUMFRAMES=14  RATE=15
00049	#exec MESH SEQUENCE MESH=sktrooper SEQ=Lunge        STARTFRAME=306 NUMFRAMES=13  RATE=15    Group=Dodge
00050	#exec MESH SEQUENCE MESH=sktrooper SEQ=RightDodge   STARTFRAME=319 NUMFRAMES=13  RATE=15    Group=Dodge
00051	#exec MESH SEQUENCE MESH=sktrooper SEQ=StrafeRightFr STARTFRAME=332 NUMFRAMES=14 RATE=15	Group=MovingAttack
00052	#exec MESH SEQUENCE MESH=sktrooper SEQ=RightHit     STARTFRAME=346 NUMFRAMES=1				Group=TakeHit
00053	#exec MESH SEQUENCE MESH=sktrooper SEQ=StrafeRight  STARTFRAME=347 NUMFRAMES=14  RATE=15
00054	#exec MESH SEQUENCE MESH=sktrooper SEQ=Jog          STARTFRAME=361 NUMFRAMES=10  RATE=15
00055	#exec MESH SEQUENCE MESH=sktrooper SEQ=JogFire      STARTFRAME=371 NUMFRAMES=10  RATE=15	Group=MovingAttack
00056	#exec MESH SEQUENCE MESH=sktrooper SEQ=ShldDown     STARTFRAME=381 NUMFRAMES=10 
00057	#exec MESH SEQUENCE MESH=sktrooper SEQ=ShldFire     STARTFRAME=391 NUMFRAMES=1				Group=Shielded
00058	#exec MESH SEQUENCE MESH=sktrooper SEQ=ShldLand     STARTFRAME=392 NUMFRAMES=1				Group=Shielded
00059	#exec MESH SEQUENCE MESH=sktrooper SEQ=ShldTest     STARTFRAME=393 NUMFRAMES=20  RATE=15 
00060	#exec MESH SEQUENCE MESH=sktrooper SEQ=ShldUp       STARTFRAME=413 NUMFRAMES=16 
00061	#exec MESH SEQUENCE MESH=sktrooper SEQ=HoldShield   STARTFRAME=428 NUMFRAMES=1				Group=Shielded
00062	#exec MESH SEQUENCE MESH=sktrooper SEQ=Spin         STARTFRAME=429 NUMFRAMES=20             Group=Attack
00063	#exec MESH SEQUENCE MESH=sktrooper SEQ=Swim         STARTFRAME=449 NUMFRAMES=15  RATE=15	Group=Waiting
00064	#exec MESH SEQUENCE MESH=sktrooper SEQ=Walk         STARTFRAME=464 NUMFRAMES=15  RATE=15
00065	#exec MESH SEQUENCE MESH=sktrooper SEQ=WalkFire     STARTFRAME=479 NUMFRAMES=15  RATE=15	Group=MovingAttack 
00066	#exec MESH SEQUENCE MESH=sktrooper SEQ=Turn         STARTFRAME=464 NUMFRAMES=2   RATE=15
00067	#exec MESH SEQUENCE MESH=sktrooper SEQ=Death5       STARTFRAME=494 NUMFRAMES=31  RATE=15	 
00068	#exec MESH SEQUENCE MESH=sktrooper SEQ=DuckWalk     STARTFRAME=525 NUMFRAMES=15  RATE=15	 
00069	#exec MESH SEQUENCE MESH=sktrooper SEQ=Pickup       STARTFRAME=540 NUMFRAMES=15  RATE=15	 
00070	#exec MESH SEQUENCE MESH=sktrooper SEQ=Shield       STARTFRAME=555 NUMFRAMES=28  RATE=15	 
00071	
00072	#exec OBJ LOAD FILE=textures\stshield.utx PACKAGE=UNREALI.STEffect
00073	#exec TEXTURE IMPORT NAME=sktrooper1 FILE=MODELS\zaarj.PCX GROUP=Skins 
00074	#exec MESHMAP SCALE MESHMAP=sktrooper X=0.086 Y=0.086 Z=0.172
00075	#exec MESHMAP SETTEXTURE MESHMAP=sktrooper NUM=0 TEXTURE=sktrooper1
00076	#exec MESHMAP SETTEXTURE MESHMAP=sktrooper NUM=1 TEXTURE=UNREALI.STEffect.stshield
00077	
00078	#exec MESH NOTIFY MESH=sktrooper SEQ=WalkFire TIME=0.5 FUNCTION=SpawnTwoShots
00079	#exec MESH NOTIFY MESH=sktrooper SEQ=JogFire TIME=0.5 FUNCTION=SpawnTwoShots
00080	#exec MESH NOTIFY MESH=sktrooper SEQ=StrafeLeftFr TIME=0.5 FUNCTION=SpawnTwoShots
00081	#exec MESH NOTIFY MESH=sktrooper SEQ=StrafeRightFr TIME=0.5 FUNCTION=SpawnTwoShots
00082	#exec MESH NOTIFY MESH=sktrooper SEQ=Spin TIME=0.48 FUNCTION=SpinDamageTarget
00083	#exec MESH NOTIFY MESH=sktrooper SEQ=Spin TIME=0.67 FUNCTION=SpinDamageTarget
00084	#exec MESH NOTIFY MESH=sktrooper SEQ=Claw TIME=0.24 FUNCTION=ClawDamageTarget
00085	#exec MESH NOTIFY MESH=sktrooper SEQ=Claw TIME=0.76 FUNCTION=ClawDamageTarget
00086	#exec MESH NOTIFY MESH=sktrooper SEQ=Death  TIME=0.41 FUNCTION=LandThump
00087	#exec MESH NOTIFY MESH=sktrooper SEQ=Death2 TIME=0.61 FUNCTION=LandThump
00088	#exec MESH NOTIFY MESH=sktrooper SEQ=Death3 TIME=0.73 FUNCTION=LandThump
00089	#exec MESH NOTIFY MESH=sktrooper SEQ=Death4 TIME=0.62 FUNCTION=LandThump
00090	#exec MESH NOTIFY MESH=sktrooper SEQ=Death5 TIME=0.8  FUNCTION=LandThump
00091	#exec MESH NOTIFY MESH=sktrooper SEQ=Walk TIME=0.3 FUNCTION=WalkStep
00092	#exec MESH NOTIFY MESH=sktrooper SEQ=Walk TIME=0.8 FUNCTION=WalkStep
00093	#exec MESH NOTIFY MESH=sktrooper SEQ=WalkFire TIME=0.3 FUNCTION=WalkStep
00094	#exec MESH NOTIFY MESH=sktrooper SEQ=WalkFire TIME=0.8 FUNCTION=WalkStep
00095	#exec MESH NOTIFY MESH=sktrooper SEQ=Jog TIME=0.25 FUNCTION=RunStep
00096	#exec MESH NOTIFY MESH=sktrooper SEQ=Jog TIME=0.75 FUNCTION=RunStep
00097	#exec MESH NOTIFY MESH=sktrooper SEQ=JogFire TIME=0.25 FUNCTION=RunStep
00098	#exec MESH NOTIFY MESH=sktrooper SEQ=JogFire TIME=0.75 FUNCTION=RunStep
00099	#exec MESH NOTIFY MESH=sktrooper SEQ=StrafeLeft TIME=0.25 FUNCTION=RunStep
00100	#exec MESH NOTIFY MESH=sktrooper SEQ=StrafeLeft TIME=0.75 FUNCTION=RunStep
00101	#exec MESH NOTIFY MESH=sktrooper SEQ=StrafeLeftFr TIME=0.25 FUNCTION=RunStep
00102	#exec MESH NOTIFY MESH=sktrooper SEQ=StrafeLeftFr TIME=0.75 FUNCTION=RunStep
00103	#exec MESH NOTIFY MESH=sktrooper SEQ=StrafeRight TIME=0.25 FUNCTION=RunStep
00104	#exec MESH NOTIFY MESH=sktrooper SEQ=StrafeRight TIME=0.75 FUNCTION=RunStep
00105	#exec MESH NOTIFY MESH=sktrooper SEQ=StrafeRightFr TIME=0.25 FUNCTION=RunStep
00106	#exec MESH NOTIFY MESH=sktrooper SEQ=StrafeRightFr TIME=0.75 FUNCTION=RunStep
00107	
00108	//-----------------------------------------------------------------------------
00109	// SkaarjTrooper variables.
00110	
00111	var() class<weapon> WeaponType;
00112	var	  Weapon myWeapon;
00113	var   float  duckTime;
00114	
00115	//=========================================================================================
00116	
00117	
00118	function PreBeginPlay()
00119	{
00120		Super.PreBeginPlay();
00121	
00122		if ( TimeBetweenAttacks == Default.TimeBetweenAttacks )
00123			TimeBetweenAttacks = TimeBetweenAttacks + (3 - Skill) * 0.3;
00124		bHasRangedAttack = false;
00125		bMovingRangedAttack = false;
00126	}
00127	
00128	function ChangedWeapon()
00129	{
00130		Super.ChangedWeapon();
00131		bIsPlayer = false;
00132		bMovingRangedAttack = true;
00133		bHasRangedAttack = true;
00134		Weapon.AimError += 200;
00135		Weapon.FireOffset = Weapon.FireOffset * 1.5 * DrawScale;
00136		Weapon.PlayerViewOffset = Weapon.PlayerViewOffset * 1.5 * DrawScale; 
00137		//Weapon.SetHand(0);
00138	}
00139	
00140	function TossWeapon()
00141	{
00142		if ( Weapon == None )
00143			return;
00144		Weapon.FireOffset = Weapon.Default.FireOffset;
00145		Weapon.PlayerViewOffset = Weapon.Default.PlayerViewOffset; 
00146		Super.TossWeapon();
00147	}
00148	
00149	function Died(pawn Killer, name damageType, vector HitLocation)
00150	{
00151		bIsPlayer = false;
00152		Super.Died(Killer, damageType, HitLocation);
00153	}
00154	
00155	function PlayTakeHit(float tweentime, vector HitLoc, int damage)
00156	{
00157		if ( GetAnimGroup(AnimSequence) == 'Shielded' )
00158			TweenAnim('ShldLand', 0.5);
00159		else
00160			Super.PlayTakeHit(tweentime, HitLoc, damage);
00161	}
00162	
00163	auto state Startup
00164	{
00165		function BeginState()
00166		{
00167			Super.BeginState();
00168			bIsPlayer = true; // temporarily, till have weapon
00169			if ( WeaponType != None )
00170			{
00171				bIsPlayer = true;
00172				myWeapon = Spawn(WeaponType);
00173				if ( myWeapon != None )
00174					myWeapon.ReSpawnTime = 0.0;
00175			}
00176		}
00177	
00178		function SetHome()
00179		{
00180			Super.SetHome();
00181			if ( myWeapon != None )
00182				myWeapon.Touch(self);
00183		}
00184	}
00185	
00186	function Shield()
00187	{
00188		bFire = 0;
00189		bAltFire = 0;
00190		PlayAnim('ShldUp', 2.0, 0.1);
00191		GotoState('RangedAttack', 'Shieldup');
00192	}
00193	
00194	function WarnTarget(Pawn shooter, float projSpeed, vector FireDir)
00195	{
00196		local float MaxSpeed, enemyDist;
00197		local eAttitude att;
00198		local vector X,Y,Z, enemyDir;
00199	
00200		att = AttitudeTo(shooter);
00201		if ( (att == ATTITUDE_Ignore) || (att == ATTITUDE_Threaten) )
00202		{
00203			if ( intelligence >= BRAINS_Mammal )
00204				damageAttitudeTo(shooter);
00205			if (att == ATTITUDE_Ignore)
00206				return;	
00207		}
00208		
00209		// AI controlled creatures may duck if not falling
00210		if ( (Enemy == None) || (Physics == PHYS_Falling) || (FRand() > 0.4 + 0.2 * skill) )
00211			return;
00212	
00213		// and projectile time is long enough
00214		enemyDist = VSize(shooter.Location - Location);
00215		duckTime = enemyDist/projSpeed;
00216		if (duckTime < 0.1 + 0.15 * FRand()) //FIXME - pick right value
00217			return;
00218						
00219		// only if tight FOV
00220		GetAxes(Rotation,X,Y,Z);
00221		enemyDir = (shooter.Location - Location)/enemyDist;
00222		if ((enemyDir Dot X) < 0.8)
00223			return;
00224	
00225		if ( (FireDir Dot Y) > 0 )
00226		{
00227			Y *= -1;
00228			TryToDuck(Y, true);
00229		}
00230		else
00231			TryToDuck(Y, false);
00232	}
00233	
00234	function TryToDuck(vector duckDir, bool bReversed)
00235	{
00236		local vector HitLocation, HitNormal, Extent;
00237		local bool duckLeft;
00238		local actor HitActor;
00239		local float decision;
00240	
00241		if ( (FRand() < 0.4) || (VSize(Velocity) < 50) )
00242		{
00243			Shield();
00244			return;
00245		}
00246					
00247		duckDir.Z = 0;
00248		duckLeft = !bReversed;
00249	
00250		Extent.X = CollisionRadius;
00251		Extent.Y = CollisionRadius;
00252		Extent.Z = CollisionHeight;
00253		HitActor = Trace(HitLocation, HitNormal, Location + 200 * duckDir, Location, false, Extent);
00254		if (HitActor != None)
00255		{
00256			duckLeft = !duckLeft;
00257			duckDir *= -1;
00258			HitActor = Trace(HitLocation, HitNormal, Location + 200 * duckDir, Location, false, Extent);
00259		}
00260		if (HitActor != None)
00261		{
00262			Shield();
00263			return;
00264		}
00265	
00266		HitActor = Trace(HitLocation, HitNormal, Location + 200 * duckDir - MaxStepHeight * vect(0,0,1), Location + 200 * duckDir, false, Extent);
00267		if (HitActor == None)
00268		{
00269			Shield();
00270			return;
00271		}
00272	
00273		SetFall();
00274		if ( duckLeft )
00275			PlayAnim('LeftDodge', 1.35);
00276		else
00277			PlayAnim('RightDodge', 1.35);
00278		Velocity = duckDir * GroundSpeed;
00279		Velocity.Z = 200;
00280		SetPhysics(PHYS_Falling);
00281		GotoState('FallingState','Ducking');
00282	}	
00283	
00284	function bool CanFireAtEnemy()
00285	{
00286		local vector HitLocation, HitNormal,X,Y,Z, projStart, EnemyDir, EnemyUp;
00287		local actor HitActor;
00288		local float EnemyDist;
00289			
00290		EnemyDir = Enemy.Location - Location;
00291		EnemyDist = VSize(EnemyDir);
00292		EnemyUp = Enemy.CollisionHeight * vect(0,0,0.8);
00293		if ( EnemyDist > 300 )
00294		{
00295			EnemyDir = 300 * EnemyDir/EnemyDist;
00296			EnemyUp = 300 * EnemyUp/EnemyDist;
00297		}
00298		
00299		if ( Weapon == None )
00300			return false;
00301		
00302		GetAxes(Rotation,X,Y,Z);
00303		projStart = Location + Weapon.CalcDrawOffset() + Weapon.FireOffset.X * X + 1.2 * Weapon.FireOffset.Y * Y + Weapon.FireOffset.Z * Z;
00304		if ( Weapon.IsA('ASMD') || Weapon.IsA('Minigun') || Weapon.IsA('Rifle') ) //instant hit
00305			HitActor = Trace(HitLocation, HitNormal, Enemy.Location + EnemyUp, projStart, true);
00306		else
00307			HitActor = Trace(HitLocation, HitNormal, projStart + EnemyDir + EnemyUp, projStart, true);
00308	
00309		if ( HitActor == Enemy )
00310			return true;
00311		if ( (HitActor != None) && (VSize(HitLocation - Location) < 200) )
00312			return false;
00313		if ( (Pawn(HitActor) != None) && (AttitudeTo(Pawn(HitActor)) > ATTITUDE_Ignore) )
00314			return false;
00315	
00316		return true;
00317	}
00318	
00319	function PlayCock()
00320	{
00321		if ( Weapon != None )
00322		{
00323			if ( Weapon.CockingSound != None )
00324				PlaySound(Weapon.CockingSound, SLOT_Interact,,,700);
00325			else if ( Weapon.SelectSound != None )
00326				PlaySound(Weapon.CockingSound, SLOT_Interact,,,700);
00327		}
00328	}
00329	
00330	//Skaarj animations
00331	function PlayPatrolStop()
00332	{
00333		local float decision;
00334		if (Region.Zone.bWaterZone)
00335		{
00336			PlaySwimming();
00337			return;
00338		}
00339		if ( bButtonPusher )
00340		{
00341			PushButtons();
00342			return;
00343		}
00344	
00345		SetAlertness(0.2);	
00346		LoopAnim('Breath', 0.3 + 0.6 * FRand());
00347	}
00348	
00349	function PlayChallenge()
00350	{
00351		if (Region.Zone.bWaterZone)
00352		{
00353			PlaySwimming();
00354			return;
00355		}
00356		if ( TryToCrouch() )
00357		{
00358			TweenAnim('Duck', 0.12);
00359			return;
00360		}	
00361		PlayThreateningSound();
00362		PlayAnim('Fighter', 0.8 + 0.5 * FRand(), 0.1);
00363	}
00364	
00365	function PlayRunning()
00366	{
00367		local float strafeMag;
00368		local vector Focus2D, Loc2D, Dest2D;
00369		local vector lookDir, moveDir, Y;
00370	
00371		bFire = 0;
00372		bAltFire = 0;
00373		DesiredSpeed = MaxDesiredSpeed;
00374		if (Region.Zone.bWaterZone)
00375		{
00376			PlaySwimming();
00377			return;
00378		}
00379	
00380		if (Focus == Destination)
00381		{
00382			LoopAnim('Jog', -0.9/GroundSpeed,, 0.5);
00383			return;
00384		}	
00385		Focus2D = Focus;
00386		Focus2D.Z = 0;
00387		Loc2D = Location;
00388		Loc2D.Z = 0;
00389		Dest2D = Destination;
00390		Dest2D.Z = 0;
00391		lookDir = Normal(Focus2D - Loc2D);
00392		moveDir = Normal(Dest2D - Loc2D);
00393		strafeMag = lookDir dot moveDir;
00394		if (strafeMag > 0.8)
00395			LoopAnim('Jog', -1.0/GroundSpeed,, 0.5);
00396		else if (strafeMag < -0.8)
00397			LoopAnim('Jog', -1.0/GroundSpeed,, 0.5);
00398		else
00399		{
00400			Y = (lookDir Cross vect(0,0,1));
00401			if ((Y Dot (Dest2D - Loc2D)) > 0)
00402			{
00403				if ( (AnimSequence == 'StrafeRight') || (AnimSequence == 'StrafeRightFr') ) 
00404					LoopAnim('StrafeRight', -2.5/GroundSpeed,, 1.0);
00405				else 
00406					LoopAnim('StrafeRight', -2.5/GroundSpeed,0.1, 1.0);
00407			}
00408			else
00409			{
00410				if ( (AnimSequence == 'StrafeLeft') || (AnimSequence == 'StrafeLeftFr') ) 
00411					LoopAnim('StrafeLeft', -2.5/GroundSpeed,, 1.0);
00412				else
00413					LoopAnim('StrafeLeft', -2.5/GroundSpeed,0.1, 1.0);
00414			}
00415		}
00416	}
00417	
00418	function PlayMovingAttack()
00419	{
00420		local float strafeMag;
00421		local vector Focus2D, Loc2D, Dest2D;
00422		local vector lookDir, moveDir, Y;
00423		local int bUseAltMode;
00424	
00425		if (Weapon != None)
00426		{
00427			if ( Weapon.AmmoType != None )
00428				Weapon.AmmoType.AmmoAmount = Weapon.AmmoType.Default.AmmoAmount;
00429			Weapon.RateSelf(bUseAltMode);
00430			ViewRotation = Rotation;
00431			if ( bUseAltMode == 0 ) 
00432			{
00433				bFire = 1;
00434				bAltFire = 0;
00435				Weapon.Fire(1.0);
00436			}
00437			else
00438			{
00439				bFire = 0;
00440				bAltFire = 1;
00441				Weapon.AltFire(1.0);
00442			}
00443		}
00444		else
00445		{
00446			PlayRunning();
00447			return;
00448		}
00449	
00450		if (Region.Zone.bWaterZone)
00451		{
00452			PlaySwimming();
00453			return;
00454		}
00455	
00456		DesiredSpeed = MaxDesiredSpeed;
00457	
00458		if (Focus == Destination)
00459		{
00460			LoopAnim('JogFire', -0.9/GroundSpeed,, 0.4);
00461			return;
00462		}	
00463		Focus2D = Focus;
00464		Focus2D.Z = 0;
00465		Loc2D = Location;
00466		Loc2D.Z = 0;
00467		Dest2D = Destination;
00468		Dest2D.Z = 0;
00469		lookDir = Normal(Focus2D - Loc2D);
00470		moveDir = Normal(Dest2D - Loc2D);
00471		strafeMag = lookDir dot moveDir;
00472		if (strafeMag > 0.8)
00473			LoopAnim('JogFire', -1.0/GroundSpeed,, 0.4);
00474		else if (strafeMag < -0.8)
00475			LoopAnim('JogFire', -1.0/GroundSpeed,, 0.4);
00476		else
00477		{
00478			MoveTimer += 0.2;
00479			DesiredSpeed = 0.6;
00480			Y = (lookDir Cross vect(0,0,1));
00481			if ((Y Dot (Dest2D - Loc2D)) > 0) 
00482			{
00483				if ( (AnimSequence == 'StrafeRight') || (AnimSequence == 'StrafeRightFr') ) 
00484					LoopAnim('StrafeRightFr', -2.5/GroundSpeed,, 1.0); 
00485				else
00486					LoopAnim('StrafeRightFr', -2.5/GroundSpeed,0.1, 1.0); 
00487			}
00488			else
00489			{
00490				if ( (AnimSequence == 'StrafeLeft') || (AnimSequence == 'StrafeLeftFr') ) 
00491					LoopAnim('StrafeLeftFr', -2.5/GroundSpeed,, 1.0);
00492				else
00493					LoopAnim('StrafeLeftFr', -2.5/GroundSpeed,0.1, 1.0);
00494			}
00495		}
00496	}
00497	
00498	function PlayThreatening()
00499	{
00500		local float decision, animspeed;
00501	
00502		if (Region.Zone.bWaterZone)
00503		{
00504			PlaySwimming();
00505			return;
00506		}
00507	
00508		decision = FRand();
00509		animspeed = 0.4 + 0.6 * FRand(); 
00510		
00511		if ( decision < 0.7 )
00512			PlayAnim('Breath2', animspeed, 0.3);
00513		else
00514		{
00515			PlayThreateningSound();
00516			PlayAnim('Fighter', animspeed, 0.3);
00517		}
00518	}
00519	
00520	function PlayRangedAttack()
00521	{
00522		PlayFiring();
00523	}
00524	
00525	function PlayFiring()
00526	{
00527		TweenAnim('Firing', 0.2);
00528		if ( (Weapon != None) && (Weapon.AmmoType != None) )
00529			Weapon.AmmoType.AmmoAmount = Weapon.AmmoType.Default.AmmoAmount;
00530	}
00531	
00532	function PlayVictoryDance()
00533	{
00534		PlayAnim('Shield', 0.6, 0.1);
00535	}
00536	
00537	function PlayLanded(float impactVel)
00538	{
00539		if ( GetAnimGroup(AnimSequence) == 'Shielded' )
00540			TweenAnim('ShldLand', 0.1);
00541		else if (impactVel > 1.7 * JumpZ)
00542			PlayAnim('Landed',1.0,0.1);
00543		else
00544			TweenAnim('Land', 0.1);
00545	}
00546	
00547	state TakeHit 
00548	{
00549	ignores seeplayer, hearnoise, bump, hitwall;
00550	
00551		function BeginState()
00552		{
00553			bFire = 0;
00554			bAltFire = 0;
00555			Super.BeginState();
00556		}
00557	}
00558	
00559	state Retreating
00560	{
00561	ignores SeePlayer, EnemyNotVisible, HearNoise;
00562	
00563		function EndState()
00564		{
00565			bFire = 0;
00566			bAltFire = 0;
00567			Super.EndState();
00568		}
00569	}
00570	
00571	state Charging
00572	{
00573	ignores SeePlayer, HearNoise;
00574	
00575		function EndState()
00576		{
00577			bFire = 0;
00578			bAltFire = 0;
00579			Super.EndState();
00580		}
00581	}
00582	
00583	state TacticalMove
00584	{
00585	ignores SeePlayer, HearNoise;
00586	
00587		function EndState()
00588		{
00589			bFire = 0;
00590			bAltFire = 0;
00591			Super.EndState();
00592		}
00593	}
00594	
00595	state Hunting
00596	{
00597	ignores EnemyNotVisible; 
00598	
00599		function EndState()
00600		{
00601			bFire = 0;
00602			bAltFire = 0;
00603			if ( !Region.Zone.bWaterZone )
00604				bCanSwim = false;
00605			Super.EndState();
00606		}
00607	}
00608	
00609	state MeleeAttack
00610	{
00611	ignores SeePlayer, HearNoise, Bump;
00612	
00613	ShieldDown:
00614		DesiredRotation = Rotator(Enemy.Location - Location);
00615		FinishAnim();
00616		Goto('Begin');
00617	}
00618	
00619	
00620	state RangedAttack
00621	{
00622	ignores SeePlayer, HearNoise;
00623		
00624		function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, 
00625							Vector momentum, name damageType)
00626		{
00627			if ( (GetAnimGroup(AnimSequence) == 'Shielded') && (AnimSequence != 'ShldFire')
00628				&& ((Vector(Rotation) Dot Momentum) < -0.6) )
00629				Damage *= 0.2; 
00630	
00631			Super.TakeDamage(Damage, instigatedBy, hitlocation, momentum, damageType);
00632		}
00633	
00634		function Bump (Actor Other)
00635		{
00636			if ( (GetAnimGroup(AnimSequence) == 'Shielded') && (Other == Enemy) )
00637			{
00638				PlayAnim('ShldDown');
00639				GotoState('MeleeAttack', 'ShieldDown');
00640				return;
00641			}
00642			if ( AttackSuccess || (AnimSequence != 'Lunge') )
00643			{
00644				Disable('Bump');
00645				return;
00646			}
00647			else		
00648				LungeDamageTarget();
00649	
00650			if (!AttackSuccess && Pawn(Other) != None) //always add momentum
00651				Pawn(Other).AddVelocity((60000.0 * (Normal(Other.Location - Location)))/Other.Mass);
00652		}
00653		
00654		function PlayRangedAttack()
00655		{
00656			local float dist;
00657	
00658			if ( GetAnimGroup(AnimSequence) == 'Shielded' )
00659			{
00660				TweenAnim('ShldFire', 0.05);
00661				FireWeapon();
00662				return;
00663			}
00664	
00665			dist = VSize(Target.Location - Location + vect(0,0,1) * (CollisionHeight - Target.CollisionHeight));
00666			if ( (FRand() < 0.2) && (dist < 150 + CollisionRadius + Target.CollisionRadius) && (Region.Zone.bWaterZone || !Target.Region.Zone.bWaterZone) )
00667			{
00668				PlaySound(Lunge, SLOT_Interact);
00669		 		Velocity = 500 * (Target.Location - Location)/dist; //instant acceleration in that direction 
00670		 		Velocity.Z += 1.5 * dist;
00671		 		if (Physics != PHYS_Swimming)
00672		 			SetPhysics(PHYS_Falling);
00673		 		Enable('Bump');
00674		 		PlayAnim('Lunge');
00675		 	}
00676			else
00677			{
00678				Disable('Bump');
00679				FireWeapon();
00680			}
00681		}
00682	
00683		function TryToDuck(vector duckDir, bool bReversed)
00684		{
00685			if ( FRand() < 0.5 )
00686				return;
00687				
00688			bFire = 0;
00689			bAltFire = 0;
00690			if ( AnimSequence == 'ShldFire' )
00691			{
00692				TweenAnim('HoldShield', 0.15);
00693				GotoState('RangedAttack', 'Shieldup');
00694				return;
00695			}
00696			if ( GetAnimGroup(AnimSequence) == 'Shielded' )
00697			{
00698				if (FRand() < 0.75)
00699					GotoState('RangedAttack', 'ShieldUp');
00700				return;
00701			}
00702	
00703			Shield();
00704		}
00705	
00706		function KeepAttacking()
00707		{
00708			if ( bFiringPaused )
00709				return;
00710			if ( (FRand() > ReFireRate) || (Enemy == None) || (Enemy.Health <= 0) || !CanFireAtEnemy() ) 
00711			{
00712				if ( GetAnimGroup(AnimSequence) == 'Shielded' )
00713				{
00714					PlayAnim('ShldDown');
00715					GotoState('RangedAttack', 'ShieldDown');
00716				}
00717				else
00718					GotoState('Attacking');
00719			}
00720		}
00721	
00722	
00723		function AnimEnd()
00724		{
00725			if ( (AnimSequence == 'Lunge') || (FRand() < 0.5) || ((bFire == 0) && (bAltFire == 0)) )
00726				GotoState('RangedAttack', 'DoneFiring');
00727			else
00728				TweenAnim('Firing', 0.5);
00729		}
00730	
00731		function EndState()
00732		{
00733			bFire = 0;
00734			bAltFire = 0;
00735			Super.EndState();
00736		}
00737	
00738	ShieldDown:
00739		Disable('AnimEnd');
00740		FinishAnim();
00741		GotoState('Attacking');
00742	
00743	Challenge:
00744		Disable('AnimEnd');
00745		Acceleration = vect(0,0,0); //stop
00746		DesiredRotation = Rotator(Enemy.Location - Location);
00747		PlayChallenge();
00748		FinishAnim();
00749		TweenToFighter(0.1);
00750		Goto('FaceTarget');
00751	
00752	ShieldUp:
00753		Disable('AnimEnd');
00754		Acceleration = vect(0,0,0); //stop
00755		FinishAnim();
00756		TweenAnim('HoldShield', 0.1);
00757		DesiredRotation = Rotator(Enemy.Location - Location);
00758		Sleep(duckTime + FRand());
00759		if (NeedToTurn(Enemy.Location))
00760			TurnToward(Enemy);
00761		Goto('CheckDist');
00762	
00763	Begin:
00764		Acceleration = vect(0,0,0); //stop
00765		DesiredRotation = Rotator(Enemy.Location - Location);
00766		TweenToFighter(0.15);
00767		
00768	FaceTarget:
00769		Disable('AnimEnd');
00770		if (NeedToTurn(Enemy.Location))
00771		{
00772			PlayTurning();
00773			TurnToward(Enemy);
00774			TweenToFighter(0.1);
00775		}
00776		FinishAnim();
00777	
00778	CheckDist:
00779		if (VSize(Location - Enemy.Location) < 0.9 * MeleeRange + CollisionRadius + Enemy.CollisionRadius)
00780			GotoState('MeleeAttack', 'ReadyToAttack'); 
00781	
00782	ReadyToAttack:
00783		if (!bHasRangedAttack)
00784			GotoState('Attacking');
00785		DesiredRotation = Rotator(Enemy.Location - Location);
00786		PlayRangedAttack();
00787		Enable('AnimEnd');
00788	Firing:
00789		TurnToward(Enemy);
00790		Goto('Firing');
00791	DoneFiring:
00792		Disable('AnimEnd');
00793		KeepAttacking();  
00794		Goto('FaceTarget');
00795	}
00796	
00797	defaultproperties
00798	{
00799	     WeaponType=Class'UnrealShare.DispersionPistol'
00800	     LungeDamage=20
00801	     SpinDamage=15
00802	     ClawDamage=10
00803	     CarcassType=Class'UnrealI.TrooperCarcass'
00804	     RangedProjectile=None
00805	     GroundSpeed=400.000000
00806	     Health=170
00807	     CombatStyle=0.300000
00808	     Skin=Texture'UnrealI.Skins.sktrooper1'
00809	     Mesh=LodMesh'UnrealI.sktrooper'
00810	     CollisionRadius=32.000000
00811	     CollisionHeight=42.000000
00812	     Mass=125.000000
00813	     Buoyancy=125.000000
00814	}

End Source Code