UnrealI
Class Squid

source: e:\games\UnrealTournament\UnrealI\Classes\Squid.uc
Core.Object
   |
   +--Engine.Actor
      |
      +--Engine.Pawn
         |
         +--UnrealShare.ScriptedPawn
            |
            +--UnrealI.Squid
Direct Known Subclasses:None

class Squid
extends UnrealShare.ScriptedPawn

//============================================================================= // Squid. //=============================================================================
Variables
 var() byte

States
MeleeAttack, TacticalMove, Flopping

Function Summary
 void GrabTarget()
 bool MeleeDamageTarget(int hitdamage, vector pushdir)
 void PlayChallenge()
 void PlayDying(name DamageType, vector HitLocation)
 void PlayInAir()
 void PlayLanded(float impactVel)
 void PlayMeleeAttack()
     
//FIXME - hold (turn off client's physics???
 void PlayPatrolStop()
 void PlayRunning()
 void PlayTakeHit(float tweentime, vector HitLoc, int damage)
 void PlayThreatening()
 void PlayTurning()
 void PlayVictoryDance()
 void PlayWaiting()
 void PlayWaitingAmbush()
 void PlayWalking()
 void PreSetMovement()
 void SetMovementPhysics()
 void SlapTarget()
 void ThrustTarget()
 void TweenToFalling()
 void TweenToFighter(float tweentime)
 void TweenToPatrolStop(float tweentime)
 void TweenToRunning(float tweentime)
 void TweenToWaiting(float tweentime)
 void TweenToWalking(float tweentime)
 void ZoneChange(ZoneInfo newZone)
     
//-----------------------------------------------------------------------------
// Squid functions.


State MeleeAttack Function Summary
 void EndState()
 void BeginState()
 void AnimEnd()
 void EnemyNotVisible()
 void KeepAttacking()
 void TakeDamage(int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, name damageType)


State TacticalMove Function Summary
 void BeginState()
 void Timer()


State Flopping Function Summary
 void AnimEnd()
 void Landed(vector HitNormal)
 void ZoneChange(ZoneInfo NewZone)
 void Timer()



Source Code


00001	//=============================================================================
00002	// Squid.
00003	//=============================================================================
00004	class Squid extends ScriptedPawn;
00005	
00006	#exec MESH IMPORT MESH=Squid1 ANIVFILE=MODELS\squid_a.3D DATAFILE=MODELS\squid_d.3D X=0 Y=0 Z=0
00007	#exec MESH ORIGIN MESH=Squid1 X=0 Y=0 Z=-100 YAW=-64 ROLL=-64 
00008	
00009	#exec MESH SEQUENCE MESH=squid1 SEQ=All		STARTFRAME=0	NUMFRAMES=142
00010	#exec MESH SEQUENCE MESH=squid1 SEQ=Dead1	STARTFRAME=0	NUMFRAMES=21	RATE=15
00011	#exec MESH SEQUENCE MESH=squid1 SEQ=TakeHit STARTFRAME=0	NUMFRAMES=1
00012	#exec MESH SEQUENCE MESH=squid1 SEQ=Fighter STARTFRAME=21   NUMFRAMES=15	RATE=15
00013	#exec MESH SEQUENCE MESH=squid1 SEQ=Grab	STARTFRAME=36   NUMFRAMES=13	RATE=15  Group=Attack
00014	#exec MESH SEQUENCE MESH=squid1 SEQ=Hold	STARTFRAME=49   NUMFRAMES=15	RATE=15
00015	#exec MESH SEQUENCE MESH=squid1 SEQ=Release STARTFRAME=64   NUMFRAMES=6
00016	#exec MESH SEQUENCE MESH=squid1 SEQ=Slap	STARTFRAME=70   NUMFRAMES=13	RATE=15  Group=Attack
00017	#exec MESH SEQUENCE MESH=squid1 SEQ=Spin	STARTFRAME=83   NUMFRAMES=10	RATE=15
00018	#exec MESH SEQUENCE MESH=squid1 SEQ=Swim	STARTFRAME=93   NUMFRAMES=20	RATE=15
00019	#exec MESH SEQUENCE MESH=squid1 SEQ=Thrust  STARTFRAME=113  NUMFRAMES=18	RATE=15  Group=Attack
00020	#exec MESH SEQUENCE MESH=squid1 SEQ=Turn	STARTFRAME=131  NUMFRAMES=11	RATE=15
00021	
00022	#exec TEXTURE IMPORT NAME=JSquid1 FILE=MODELS\squid.PCX GROUP=Skins 
00023	#exec MESHMAP SCALE MESHMAP=Squid1 X=0.1 Y=0.1 Z=0.2
00024	#exec MESHMAP SETTEXTURE MESHMAP=squid1 NUM=1 TEXTURE=Jsquid1
00025	
00026	#exec MESH NOTIFY MESH=Squid1 SEQ=Grab TIME=0.54 FUNCTION=GrabTarget
00027	#exec MESH NOTIFY MESH=Squid1 SEQ=Slap TIME=0.36 FUNCTION=SlapTarget
00028	#exec MESH NOTIFY MESH=Squid1 SEQ=Thrust TIME=0.23 FUNCTION=ThrustTarget
00029	
00030	#exec AUDIO IMPORT FILE="Sounds\Squid\amb1sq.WAV" NAME="amb1sq" GROUP="Squid"
00031	#exec AUDIO IMPORT FILE="Sounds\Squid\death1sq.WAV" NAME="death1sq" GROUP="Squid"
00032	#exec AUDIO IMPORT FILE="Sounds\Squid\grab1sq.WAV" NAME="grab1sq" GROUP="Squid"
00033	#exec AUDIO IMPORT FILE="Sounds\Squid\hit1sq.WAV" NAME="hit1sq" GROUP="Squid"
00034	#exec AUDIO IMPORT FILE="Sounds\Squid\slap1sq.WAV" NAME="slap1sq" GROUP="Squid"
00035	#exec AUDIO IMPORT FILE="Sounds\Squid\thrust1sq.WAV" NAME="thrust1sq" GROUP="Squid"
00036	#exec AUDIO IMPORT FILE="Sounds\Squid\injur1sq.WAV" NAME="injur1sq" GROUP="Squid"
00037	#exec AUDIO IMPORT FILE="Sounds\Squid\injur2sq.WAV" NAME="injur2sq" GROUP="Squid"
00038	#exec AUDIO IMPORT FILE="Sounds\Squid\turn1sq.WAV" NAME="turn1sq" GROUP="Squid"
00039	
00040	//-----------------------------------------------------------------------------
00041	// Squid variables.
00042	
00043	// Attack damage.
00044	var() byte
00045		ThrustDamage,		// Basic damage done by bite.
00046		SlapDamage;
00047	
00048	var(Sounds) sound thrust;
00049	var(Sounds) sound slapgrabhit;
00050	var(Sounds) sound thrusthit;
00051	var(Sounds) sound slap;
00052	var(Sounds) sound turn;
00053	var(Sounds) sound grab;
00054	var(Sounds) sound spin;
00055	var(Sounds) sound flop;
00056	
00057	//-----------------------------------------------------------------------------
00058	// Squid functions.
00059	
00060	function ZoneChange(ZoneInfo newZone)
00061	{
00062		local vector start, checkpoint, HitNormal, HitLocation;
00063		local actor HitActor;
00064		
00065		if ( newZone.bWaterZone )
00066		{
00067			if (Physics != PHYS_Swimming)
00068				setPhysics(PHYS_Swimming);
00069		}
00070		else if (Physics == PHYS_Swimming)
00071		{
00072			SetPhysics(PHYS_Falling);
00073			MoveTimer = -1.0;
00074			GotoState('Flopping');
00075		}
00076	}
00077	
00078	function PreSetMovement()
00079	{
00080		bCanJump = true;
00081		bCanWalk = false;
00082		bCanSwim = true;
00083		bCanFly = false;
00084		MinHitWall = -0.6;
00085		bCanOpenDoors = false;
00086		bCanDoSpecial = false;
00087	}
00088	
00089	function SetMovementPhysics()
00090	{
00091		if (Region.Zone.bWaterZone)
00092			SetPhysics(PHYS_Swimming);
00093		else
00094		{
00095			SetPhysics(PHYS_Falling);
00096			MoveTimer = -1.0;
00097			GotoState('Flopping');
00098		} 
00099	}
00100	
00101	function PlayWaiting()
00102		{
00103		LoopAnim('Fighter', 0.1 + 0.3 * FRand());
00104		}
00105	
00106	function PlayPatrolStop()
00107		{
00108		LoopAnim('Fighter', 0.1 + 0.3 * FRand());
00109		}
00110	
00111	function PlayWaitingAmbush()
00112		{
00113		LoopAnim('Fighter', 0.1 + 0.3 * FRand());
00114		}
00115	
00116	function PlayChallenge()
00117	{
00118		PlayAnim('Fighter', 0.4, 0.2);
00119	}
00120	
00121	function TweenToFighter(float tweentime)
00122	{
00123		TweenAnim('Fighter', tweentime);
00124	}
00125	
00126	function TweenToRunning(float tweentime)
00127	{
00128		if ( (AnimSequence != 'Swim') || !bAnimLoop )
00129			TweenAnim('Swim', tweentime);
00130	}
00131	
00132	function TweenToWalking(float tweentime)
00133	{
00134		if ( (AnimSequence != 'Swim') || !bAnimLoop )
00135			TweenAnim('Swim', tweentime);
00136	}
00137	
00138	function TweenToWaiting(float tweentime)
00139	{
00140		PlayAnim('Fighter', 0.2 + 0.8 * FRand(), 0.3);
00141	}
00142	
00143	function TweenToPatrolStop(float tweentime)
00144	{
00145		TweenAnim('Fighter', tweentime);
00146	}
00147	
00148	function PlayRunning()
00149	{
00150		if ( ((AnimSequence == 'Spin') && (FRand() < 0.8)) || (FRand() < 0.06) )
00151			LoopAnim('Spin');
00152		else
00153			LoopAnim('Swim', -0.8/WaterSpeed,, 0.4);
00154	}
00155	
00156	function PlayWalking()
00157	{
00158		LoopAnim('Swim', -0.8/WaterSpeed,, 0.4);
00159	}
00160	
00161	function PlayThreatening()
00162	{
00163		if ( FRand() < 0.6 )
00164			PlayAnim('Swim', 0.4);
00165		else
00166		{
00167			PlaySound(Spin, SLOT_Interact);
00168			PlayAnim('Spin', 0.4);
00169		}
00170	}
00171	
00172	function PlayTurning()
00173	{
00174		PlaySound(turn, SLOT_Interact);
00175		LoopAnim('Turn', 0.4);
00176	}
00177	
00178	function PlayDying(name DamageType, vector HitLocation)
00179	{
00180		PlaySound(Die, SLOT_Talk, 4 * TransientSoundVolume);
00181		PlayAnim('Dead1', 0.7, 0.1);
00182	}
00183	
00184	function PlayTakeHit(float tweentime, vector HitLoc, int damage)
00185	{
00186		TweenAnim('TakeHit', tweentime);
00187	}
00188	
00189	function TweenToFalling()
00190	{
00191		DesiredRotation = Rotation;
00192		DesiredRotation.Pitch = 0;
00193		TweenAnim('Spin', 0.2);
00194	}
00195	
00196	function PlayInAir()
00197	{
00198		LoopAnim('Fighter', 0.7);
00199	}
00200	
00201	function PlayLanded(float impactVel)
00202	{
00203		TweenAnim('Spin', 0.2);
00204	}
00205	
00206	function PlayVictoryDance()
00207	{
00208		PlayAnim('grab', 0.6, 0.1);
00209		PlaySound(Grab, SLOT_Interact);
00210	}
00211	
00212	
00213	function GrabTarget()
00214	{
00215		if ( MeleeDamageTarget(SlapDamage, (SlapDamage * 1500.0 * Normal(Location - Target.Location))) )
00216			PlaySound(SlapGrabHit, SLOT_Interact);
00217	}
00218	
00219	function SlapTarget()
00220	{
00221		if ( MeleeDamageTarget(SlapDamage, (SlapDamage * 1500.0 * Normal(Target.Location - Location))) )
00222			PlaySound(SlapGrabHit, SLOT_Interact);
00223	}
00224	
00225	function ThrustTarget()
00226	{
00227		if ( MeleeDamageTarget(ThrustDamage, (ThrustDamage * 1500.0 * Normal(Target.Location - Location))) )
00228			PlaySound(ThrustHit, SLOT_Interact);
00229	}
00230		
00231	//FIXME - hold (turn off client's physics???
00232	function PlayMeleeAttack()
00233	{
00234		local float decision;
00235		decision = FRand();
00236		if (decision < 0.35)
00237		{
00238			PlaySound(Thrust, SLOT_Interact);
00239			PlayAnim('Thrust', 0.8);
00240		}
00241		if (decision < 0.7)
00242		{
00243			PlaySound(Slap, SLOT_Interact);
00244			PlayAnim('Slap', 0.8);
00245		}
00246		else 
00247		{
00248			PlaySound(Grab, SLOT_Interact);
00249			PlayAnim('Grab'); 
00250	 	}
00251	}
00252	
00253	
00254	function bool MeleeDamageTarget(int hitdamage, vector pushdir)
00255		{
00256		local vector HitLocation, HitNormal, TargetPoint;
00257		local float TargetDist;
00258		local actor HitActor;
00259		local bool result;
00260		
00261		result = false;
00262		TargetDist = VSize(Target.Location - Location);
00263		Acceleration = AccelRate * (Target.Location - Location)/TargetDist;
00264		If (TargetDist <= (MeleeRange * 1.4 + Target.CollisionRadius + CollisionRadius)) //still in melee range
00265			{
00266			TargetPoint = Location - TargetDist * vector(Rotation); 
00267			TargetPoint.Z = FMin(TargetPoint.Z, Target.Location.Z + Target.CollisionHeight);
00268			TargetPoint.Z = FMax(TargetPoint.Z, Target.Location.Z - Target.CollisionHeight);
00269			HitActor = Trace(HitLocation, HitNormal, TargetPoint, Location, true);
00270			If (HitActor == Target)
00271				{	
00272				Target.TakeDamage(hitdamage, Self,HitLocation, pushdir, 'hacked');
00273				result = true;
00274				}
00275			}
00276		return result;
00277		}
00278	
00279	
00280	State Flopping
00281	{
00282	ignores seeplayer, hearnoise, enemynotvisible, hitwall; 	
00283		function Timer()
00284		{
00285			SetPhysics(PHYS_Falling);
00286			Velocity = 200 * VRand();
00287			Velocity.Z = 170 + 200 * FRand();
00288			DesiredRotation.Pitch = Rand(8192) - 4096;
00289			DesiredRotation.Yaw = Rand(65535);
00290		}
00291		
00292		function ZoneChange( ZoneInfo NewZone )
00293		{
00294			local Rotator newRotation;
00295			if (NewZone.bWaterZone)
00296			{
00297				newRotation = Rotation;
00298				newRotation.Roll = 0;
00299				SetRotation(newRotation);
00300				SetPhysics(PHYS_Swimming);
00301				GotoState('Attacking');
00302			}
00303			else if (Physics != PHYS_Falling)
00304				SetPhysics(PHYS_Falling);
00305		}
00306		
00307		function Landed(vector HitNormal)
00308		{
00309			SetPhysics(PHYS_None);
00310			DesiredRotation.Pitch = 0;
00311			SetTimer(0.3 + FRand(), false);
00312		}
00313		
00314		function AnimEnd()
00315		{
00316			PlayAnim('Spin', 0.7);
00317		}
00318	
00319	Begin:
00320		SetTimer(0.3 + FRand(), false);
00321		TweenAnim('Flopping', 0.7);
00322	}
00323	
00324	state TacticalMove
00325	{
00326	ignores SeePlayer, HearNoise;
00327	
00328		function Timer()
00329		{
00330			Spawn(class'BigBlackSmoke');
00331		}
00332		
00333		function BeginState()
00334		{
00335			SetTimer(0.2, true);
00336			Super.BeginState();
00337		}
00338	}
00339	
00340	//squid has own melee attack because he faces away from his target when attacking
00341	state MeleeAttack
00342	{
00343	ignores SeePlayer, HearNoise, Bump;
00344		function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, 
00345								Vector momentum, name damageType)
00346		{
00347			Global.TakeDamage(Damage, instigatedBy, hitlocation, momentum, damageType);
00348			if ( health <= 0 )
00349				return;
00350			if (NextState == 'TakeHit')
00351			{
00352				NextState = 'MeleeAttack';
00353				NextLabel = 'Begin';
00354			}
00355		}
00356	
00357		function KeepAttacking()
00358		{
00359			bReadyToAttack = true;
00360			if ( (Target == None) 
00361				|| ((Pawn(Target) != None) && (Pawn(Target).Health == 0)) )
00362				GotoState('Attacking');
00363			else if (VSize(Target.Location - Location) > (0.9 * MeleeRange + Target.CollisionRadius + CollisionRadius)) 
00364				GotoState('TacticalMove', 'NoCharge');
00365		}
00366	
00367		function EnemyNotVisible()
00368		{
00369			//log("enemy not visible");
00370			GotoState('Attacking');
00371		}
00372	
00373		function AnimEnd()
00374		{
00375			GotoState('MeleeAttack', 'DoneAttacking');
00376		}
00377		
00378		function BeginState()
00379		{
00380			Disable('AnimEnd');
00381			bCanStrafe = true; //so he can turn in place
00382		}
00383	
00384		function EndState()
00385		{
00386			bCanStrafe = false;
00387		}
00388		
00389	Begin:
00390		if (Target == None)
00391			Target = Enemy;
00392		
00393	FaceTarget:
00394		Acceleration = Vect(0,0,0);
00395		if (NeedToTurn(2 * Location - Target.Location))
00396		{
00397			PlayTurning();
00398			TurnTo(2 * Location - Target.Location);
00399			TweenToFighter(0.15);
00400		}
00401		else if ( (5 - Skill) * FRand() > 3 ) 
00402		{
00403			DesiredRotation = Rotator(Location - Target.Location);
00404			PlayChallenge(); 
00405		}
00406		
00407		FinishAnim();
00408			
00409		if (VSize(Location - Target.Location) > MeleeRange + CollisionRadius + Target.CollisionRadius)
00410			GotoState('Attacking'); 
00411	
00412	ReadyToAttack:
00413		DesiredRotation = Rotator(Location - Target.Location);
00414		PlayMeleeAttack();
00415		Enable('AnimEnd');
00416	Attacking:
00417		TurnTo(2 * Location - Target.Location);
00418		Goto('Attacking');
00419	DoneAttacking:
00420		Disable('AnimEnd');
00421		KeepAttacking();
00422		Goto('FaceTarget');
00423	}
00424	
00425		
00426	
00427	defaultproperties
00428	{
00429	     ThrustDamage=35
00430	     SlapDamage=30
00431	     Thrust=Sound'UnrealI.Squid.thrust1sq'
00432	     slapgrabhit=Sound'UnrealI.Squid.hit1sq'
00433	     thrusthit=Sound'UnrealI.Squid.hit1sq'
00434	     Slap=Sound'UnrealI.Squid.slap1sq'
00435	     Turn=Sound'UnrealI.Squid.turn1sq'
00436	     Grab=Sound'UnrealI.Squid.grab1sq'
00437	     Aggressiveness=0.800000
00438	     MeleeRange=70.000000
00439	     GroundSpeed=0.000000
00440	     WaterSpeed=260.000000
00441	     AirSpeed=0.000000
00442	     SightRadius=2000.000000
00443	     PeripheralVision=-0.500000
00444	     Health=260
00445	     Intelligence=BRAINS_REPTILE
00446	     HitSound1=Sound'UnrealI.Squid.injur1sq'
00447	     HitSound2=Sound'UnrealI.Squid.injur2sq'
00448	     Die=Sound'UnrealI.Squid.death1sq'
00449	     AmbientSound=Sound'UnrealI.Squid.amb1sq'
00450	     DrawType=DT_Mesh
00451	     Mesh=LodMesh'UnrealI.Squid1'
00452	     CollisionRadius=40.000000
00453	     CollisionHeight=60.000000
00454	     Mass=200.000000
00455	     Buoyancy=200.000000
00456	     RotationRate=(Pitch=13000,Roll=13000)
00457	}

End Source Code