UnrealShare
Class Tentacle

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

class Tentacle
extends UnrealShare.ScriptedPawn

//============================================================================= // Tentacle. //=============================================================================
Variables
 int WhipDamage
           Damage done by whipping.

States
Acquisition, StakeOut, Attacking

Function Summary
 
simulated
AddVelocity(vector NewVelocity)
 eAttitude AttitudeToCreature(Pawn Other)
 bool CanFireAtEnemy()
 void Drop()
 void Falling()
 void PlayChallenge()
 void PlayDying(name DamageType, vector HitLocation)
 void PlayInAir()
 void PlayLanded(float impactVel)
 void PlayMeleeAttack()
 void PlayPatrolStop()
 void PlayRangedAttack()
 void PlayRunning()
 void PlayTakeHit(float tweentime, vector HitLoc, int Damage)
 void PlayThreatening()
 void PlayTurning()
 void PlayVictoryDance()
 void PlayWaiting()
 void PlayWaitingAmbush()
 void PlayWalking()
 void PostBeginPlay()
     
//-----------------------------------------------------------------------------
// Tentacle functions.
 void PreSetMovement()
 bool SetEnemy(Pawn NewEnemy)
 void SetMovementPhysics()
 void SmackTarget()
 void TweenToFalling()
 void TweenToFighter(float tweentime)
 void TweenToPatrolStop(float tweentime)
 void TweenToRunning(float tweentime)
 void TweenToWaiting(float tweentime)
 void TweenToWalking(float tweentime)
 void WhatToDoNext(name LikelyState, name LikelyLabel)


State Acquisition Function Summary


State StakeOut Function Summary
 void TakeDamage(int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, name damageType)


State Attacking Function Summary
 void ChooseAttackMode()



Source Code


00001	//=============================================================================
00002	// Tentacle.
00003	//=============================================================================
00004	class Tentacle extends ScriptedPawn;
00005	
00006	#exec MESH IMPORT MESH=Tentacle1 ANIVFILE=MODELS\tentcl_a.3D DATAFILE=MODELS\tentcl_d.3D X=0 Y=0 Z=0
00007	#exec MESH ORIGIN MESH=Tentacle1 X=00 Y=330 Z=00 YAW=64 ROLL=-64
00008	
00009	#exec MESH SEQUENCE MESH=Tentacle1 SEQ=All    STARTFRAME=0   NUMFRAMES=156 RATE=15
00010	#exec MESH SEQUENCE MESH=Tentacle1 SEQ=Curl   STARTFRAME=0   NUMFRAMES=18  RATE=15 Group=Hiding
00011	#exec MESH SEQUENCE MESH=Tentacle1 SEQ=Dead1  STARTFRAME=18  NUMFRAMES=25  RATE=15
00012	#exec MESH SEQUENCE MESH=Tentacle1 SEQ=Dead1Land STARTFRAME=43  NUMFRAMES=3 RATE=15
00013	#exec MESH SEQUENCE MESH=Tentacle1 SEQ=Dead2  STARTFRAME=46  NUMFRAMES=11  RATE=15
00014	#exec MESH SEQUENCE MESH=Tentacle1 SEQ=Hide   STARTFRAME=57  NUMFRAMES=1            Group=Hiding
00015	#exec MESH SEQUENCE MESH=Tentacle1 SEQ=Move1  STARTFRAME=58  NUMFRAMES=10
00016	#exec MESH SEQUENCE MESH=Tentacle1 SEQ=Move2  STARTFRAME=68  NUMFRAMES=10
00017	#exec MESH SEQUENCE MESH=Tentacle1 SEQ=Shoot  STARTFRAME=78  NUMFRAMES=15  RATE=15  Group=Attack
00018	#exec MESH SEQUENCE MESH=Tentacle1 SEQ=Smack  STARTFRAME=93  NUMFRAMES=30  Group=Attack
00019	#exec MESH SEQUENCE MESH=Tentacle1 SEQ=Uncurl STARTFRAME=123 NUMFRAMES=18  RATE=15
00020	#exec MESH SEQUENCE MESH=Tentacle1 SEQ=Fighter  STARTFRAME=141 NUMFRAMES=1  RATE=15
00021	#exec MESH SEQUENCE MESH=Tentacle1 SEQ=Waver  STARTFRAME=141 NUMFRAMES=15  RATE=15
00022	#exec MESH SEQUENCE MESH=Tentacle1 SEQ=TakeHit STARTFRAME=132 NUMFRAMES=1 
00023	
00024	#exec TEXTURE IMPORT NAME=JTentacle1 FILE=MODELS\Tentacle.PCX GROUP="Skins" 
00025	#exec MESHMAP SCALE MESHMAP=Tentacle1 X=0.15 Y=0.15 Z=0.3
00026	#exec MESHMAP SETTEXTURE MESHMAP=Tentacle1 NUM=1 TEXTURE=JTentacle1 TLOD=10
00027	
00028	#exec MESH NOTIFY MESH=Tentacle1 SEQ=Dead1 TIME=0.96 FUNCTION=Drop
00029	#exec MESH NOTIFY MESH=Tentacle1 SEQ=Smack TIME=0.6 FUNCTION=SmackTarget
00030	
00031	#exec AUDIO IMPORT FILE="Sounds\Tentacle\injured1.WAV" NAME="injured1tn" GROUP="Tentacle"
00032	#exec AUDIO IMPORT FILE="Sounds\Tentacle\injured2.WAV" NAME="injured2tn" GROUP="Tentacle"
00033	#exec AUDIO IMPORT FILE="Sounds\Tentacle\yell1.WAV" NAME="yell1tn" GROUP="Tentacle"
00034	#exec AUDIO IMPORT FILE="Sounds\Tentacle\yell2.WAV" NAME="yell2tn" GROUP="Tentacle"
00035	#exec AUDIO IMPORT FILE="Sounds\Tentacle\waver1.WAV" NAME="waver1tn" GROUP="Tentacle"
00036	#exec AUDIO IMPORT FILE="Sounds\Tentacle\splat2.WAV" NAME="splat2tn" GROUP="Tentacle"
00037	#exec AUDIO IMPORT FILE="Sounds\Tentacle\death2a.WAV" NAME="death2tn" GROUP="Tentacle"
00038	#exec AUDIO IMPORT FILE="Sounds\Tentacle\strike2.WAV" NAME="strike2tn" GROUP="Tentacle"
00039	#exec AUDIO IMPORT FILE="Sounds\Tentacle\mebax.WAV" NAME="curltn" GROUP="Tentacle"
00040	
00041	//-----------------------------------------------------------------------------
00042	// Tentacle variables.
00043	
00044	// Attack damage.
00045	var() int WhipDamage; // Damage done by whipping.
00046	
00047	var(Sounds) sound mebax;
00048	var(Sounds)  sound whip;
00049	var(Sounds) sound Smack;
00050	
00051	//-----------------------------------------------------------------------------
00052	// Tentacle functions.
00053	
00054	function PostBeginPlay()
00055	{
00056		Super.PostBeginPlay();
00057		bLeadTarget = bLeadTarget && (FRand() > 0.5);
00058	}
00059	
00060	function WhatToDoNext(name LikelyState, name LikelyLabel)
00061	{
00062		bQuiet = false;
00063		GotoState('Waiting');
00064	}
00065	
00066	function eAttitude AttitudeToCreature(Pawn Other)
00067	{
00068		if ( Other.IsA('Tentacle') )
00069			return ATTITUDE_Friendly;
00070		else if ( Other.IsA('ScriptedPawn') )
00071			return ATTITUDE_Hate;
00072		else
00073			return ATTITUDE_Ignore;
00074	}
00075	
00076	simulated function AddVelocity( vector NewVelocity )
00077	{
00078		if (Physics == PHYS_Rotating)
00079			Velocity = vect(0,0,0);
00080		else
00081			Velocity += NewVelocity;
00082	}
00083	
00084	function PreSetMovement()
00085	{
00086		bCanJump = false;
00087		bCanWalk = false;
00088		bCanSwim = true;
00089		bCanFly = false;
00090		MinHitWall = -0.6;
00091		bCanOpenDoors = false;
00092		bCanDoSpecial = false;
00093	}
00094	
00095	function bool CanFireAtEnemy()
00096	{
00097		local vector HitLocation, HitNormal, EnemyDir, projStart, EnemyUp;
00098		local actor HitActor;
00099		local float EnemyDist;
00100			
00101		EnemyDir = Enemy.Location - Location;
00102		EnemyDist = VSize(EnemyDir);
00103		EnemyUp = Enemy.CollisionHeight * vect(0,0,0.9);
00104		if ( EnemyDist > 300 )
00105		{
00106			EnemyDir = 300 * EnemyDir/EnemyDist;
00107			EnemyUp = 300 * EnemyUp/EnemyDist;
00108		}
00109			
00110		projStart = Location + CollisionHeight * vect(0,0,-1.2);
00111		
00112		HitActor = Trace(HitLocation, HitNormal, projStart + EnemyDir + EnemyUp, projStart, true);
00113	
00114		if ( (HitActor == None) || (HitActor == Enemy) 
00115			|| ((Pawn(HitActor) != None) && (AttitudeTo(Pawn(HitActor)) <= ATTITUDE_Ignore)) )
00116			return true;
00117	
00118		HitActor = Trace(HitLocation, HitNormal, projStart + EnemyDir, projStart, true);
00119	
00120		return ( (HitActor == None) || (HitActor == Enemy) 
00121				|| ((Pawn(HitActor) != None) && (AttitudeTo(Pawn(HitActor)) <= ATTITUDE_Ignore)) );
00122	}
00123	
00124	function SetMovementPhysics()
00125	{
00126		if (Region.Zone.bWaterZone)
00127			SetPhysics(PHYS_Swimming);
00128		else
00129			SetPhysics(PHYS_Rotating); 
00130	}
00131	
00132	function bool SetEnemy( Pawn NewEnemy )
00133	{
00134		local bool result;
00135	
00136		bCanWalk = true; //even though can't move, still acquire enemies
00137		result = Super.SetEnemy(NewEnemy);
00138		bCanWalk = false;
00139		return result;
00140	}
00141	
00142	function Drop()
00143	{
00144		//implemented in TentacleCarcass
00145	}
00146	
00147	singular function Falling()
00148	{
00149		SetMovementPhysics();
00150	}
00151	
00152	function PlayWaiting()
00153	{
00154		TweenAnim('Hide', 5.0);
00155	}
00156	
00157	function PlayPatrolStop()
00158	{
00159		TweenAnim('Hide', 5.0);
00160	}
00161	
00162	function PlayWaitingAmbush()
00163	{
00164		TweenAnim('Hide', 5.0);
00165	}
00166	
00167	function PlayChallenge()
00168	{
00169		if ( GetAnimGroup(AnimSequence) == 'Hiding')
00170		{
00171			PlaySound(Mebax, SLOT_Interact);
00172			PlayAnim('Uncurl', 0.6, 0.2);
00173		}
00174		else
00175			PlayAnim('Waver', 1.0, 0.1);
00176	}
00177	
00178	function TweenToFighter(float tweentime)
00179	{
00180		if ( GetAnimGroup(AnimSequence) == 'Hiding')
00181		{
00182			PlaySound(Mebax, SLOT_Interact);
00183			PlayAnim('Uncurl', 0.6, 0.2);
00184		}
00185		else
00186			TweenAnim('Waver', tweentime);
00187	}
00188	
00189	function TweenToRunning(float tweentime)
00190	{
00191		if ( GetAnimGroup(AnimSequence) == 'Hiding')
00192		{
00193			PlaySound(Mebax, SLOT_Interact);
00194			PlayAnim('Uncurl', 0.6, 0.2);
00195		}
00196		else if ( (AnimSequence != 'Move2') || !bAnimLoop )
00197			TweenAnim('Move2', tweentime);
00198	}
00199	
00200	function TweenToWalking(float tweentime)
00201	{
00202		if ( GetAnimGroup(AnimSequence) == 'Hiding')
00203		{
00204			PlaySound(Mebax, SLOT_Interact);
00205			PlayAnim('Uncurl', 0.6, 0.2);
00206		}
00207		else if ( (AnimSequence != 'Move1') || !bAnimLoop )
00208			TweenAnim('Move1', tweentime);
00209	}
00210	
00211	function TweenToWaiting(float tweentime)
00212	{
00213		if ( GetAnimGroup(AnimSequence) != 'Hiding')
00214		{
00215			PlaySound(Mebax, SLOT_Interact);
00216			PlayAnim('Curl', 0.6, 0.2);
00217		}
00218	}
00219	
00220	function TweenToPatrolStop(float tweentime)
00221	{
00222		if ( GetAnimGroup(AnimSequence) == 'Hiding')
00223		{
00224			PlaySound(Mebax, SLOT_Interact);
00225			PlayAnim('Uncurl', 0.6, 0.2);
00226		}
00227		else TweenAnim('Waver', tweentime);
00228	}
00229	
00230	function PlayRunning()
00231	{
00232		LoopAnim('Move2', 1.0,, 0.4);
00233	}
00234	
00235	function PlayWalking()
00236	{
00237		LoopAnim('Move1', 1.0,, 0.4);
00238	}
00239	
00240	function PlayThreatening()
00241	{
00242		if ( FRand() < 0.8 )
00243			PlayAnim('Waver', 0.4);
00244		else
00245			PlayAnim('Smack', 0.4);
00246	}
00247	
00248	function PlayTurning()
00249	{
00250		if ( GetAnimGroup(AnimSequence) == 'Hiding')
00251		{
00252			PlaySound(Mebax, SLOT_Interact);
00253			PlayAnim('Uncurl', 0.6, 0.2);
00254		}
00255		else
00256			LoopAnim('Waver');
00257	}
00258	
00259	function PlayDying(name DamageType, vector HitLocation)
00260	{
00261		PlaySound(Die, SLOT_Talk, 3 * TransientSoundVolume);
00262		if ( Velocity.Z > 200 )
00263			PlayAnim('Dead2', 0.7, 0.1);
00264		else
00265		{
00266			PlayAnim('Dead1', 0.7, 0.1);
00267			SetPhysics(PHYS_None);
00268		}
00269	}
00270	
00271	function PlayTakeHit(float tweentime, vector HitLoc, int Damage)
00272	{
00273		TweenAnim('TakeHit', tweentime);
00274	}
00275	
00276	function TweenToFalling()
00277	{
00278		TweenAnim('Waver', 0.2);
00279	}
00280	
00281	function PlayInAir()
00282	{
00283		LoopAnim('Waver');
00284	}
00285	
00286	function PlayLanded(float impactVel)
00287	{
00288		PlayAnim('Waver');
00289	}
00290	
00291	
00292	function PlayVictoryDance()
00293	{
00294		PlaySound(whip, SLOT_Interact);
00295		PlayAnim('Smack', 0.6, 0.1);
00296	}
00297		
00298	function PlayMeleeAttack()
00299	{
00300		PlaySound(whip, SLOT_Interact);
00301		PlayAnim('Smack');
00302	}
00303	
00304	function SmackTarget()
00305	{
00306		if ( MeleeDamageTarget(WhipDamage, (WhipDamage * 1000 * Normal(Target.Location - Location))) )
00307			PlaySound(Smack, SLOT_Interact);		
00308	}
00309	
00310	function PlayRangedAttack()
00311	{
00312		local vector projStart;
00313	
00314		MakeNoise(1.0); 
00315		projStart = Location + CollisionHeight * vect(0,0,-1.2);
00316		spawn(RangedProjectile ,self,'',projStart,AdjustAim(ProjectileSpeed, projStart, 900, bLeadTarget, bWarnTarget));
00317		PlayAnim('Shoot');
00318	}
00319	
00320	
00321	state Attacking
00322	{
00323	ignores SeePlayer, HearNoise, Bump, HitWall;
00324	
00325		function ChooseAttackMode()
00326		{
00327			if (Physics == PHYS_Swimming)
00328			{
00329				Super.ChooseAttackMode();
00330				return;
00331			}
00332				
00333			if ((Enemy == None) || (Enemy.Health <= 0))
00334			{
00335				if ((OldEnemy != None) && (OldEnemy.Health > 0)) 
00336					{
00337					Enemy = OldEnemy;
00338					OldEnemy = None;
00339					}
00340				else
00341				{
00342					 GotoState('Waiting');
00343					 return;
00344				}
00345			}
00346				
00347			if (!LineOfSightTo(Enemy))
00348				GotoState('StakeOut');
00349			else
00350				GotoState('RangedAttack');
00351		}
00352	}
00353	
00354	state StakeOut
00355	{
00356	ignores EnemyNotVisible; 
00357	
00358		function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, 
00359								Vector momentum, name damageType)
00360		{
00361			Global.TakeDamage(Damage, instigatedBy, hitlocation, momentum, damageType);
00362			if ( health <= 0 )
00363				return;
00364			if (NextState == 'TakeHit')
00365			{
00366				NextState = 'Attacking';
00367				NextLabel = 'Begin';
00368				GotoState('TakeHit'); 
00369			}
00370		}
00371	
00372	Begin:
00373		PlayChallenge();
00374		TurnTo(LastSeenPos);
00375	HangOut:
00376		if ( bHasRangedAttack && bClearShot && (FRand() < 0.5) && (VSize(Enemy.Location - LastSeenPos) < 100) && CanStakeOut() )
00377			PlayRangedAttack();
00378		FinishAnim();
00379		PlayChallenge();
00380		Sleep(1 + FRand());
00381		if ( FRand() < 0.1 )
00382			GotoState('Waiting');
00383		else
00384			LoopAnim('Waver');
00385		Goto('HangOut');
00386	}
00387	
00388	state Acquisition
00389	{
00390	 
00391	PlayOut:
00392		FinishAnim();
00393			
00394	Begin:
00395		PlayTurning();
00396		FinishAnim();
00397		GotoState('Attacking');
00398	}
00399	
00400	defaultproperties
00401	{
00402	     mebax=Sound'UnrealShare.Tentacle.curltn'
00403	     Whip=Sound'UnrealShare.Tentacle.strike2tn'
00404	     Smack=Sound'UnrealShare.Tentacle.splat2tn'
00405	     CarcassType=Class'UnrealShare.TentacleCarcass'
00406	     Aggressiveness=1.000000
00407	     RefireRate=0.700000
00408	     bHasRangedAttack=True
00409	     bMovingRangedAttack=True
00410	     bLeadTarget=False
00411	     RangedProjectile=Class'UnrealShare.TentacleProjectile'
00412	     Acquire=Sound'UnrealShare.Tentacle.yell1tn'
00413	     Fear=Sound'UnrealShare.Tentacle.injured2tn'
00414	     Roam=Sound'UnrealShare.Tentacle.waver1tn'
00415	     Threaten=Sound'UnrealShare.Tentacle.yell2tn'
00416	     MeleeRange=70.000000
00417	     WaterSpeed=100.000000
00418	     AccelRate=100.000000
00419	     JumpZ=10.000000
00420	     SightRadius=1000.000000
00421	     PeripheralVision=-2.000000
00422	     HearingThreshold=10.000000
00423	     Health=50
00424	     UnderWaterTime=-1.000000
00425	     Intelligence=BRAINS_REPTILE
00426	     HitSound1=Sound'UnrealShare.Tentacle.injured1tn'
00427	     HitSound2=Sound'UnrealShare.Tentacle.injured2tn'
00428	     Land=Sound'UnrealShare.Tentacle.splat2tn'
00429	     Die=Sound'UnrealShare.Tentacle.death2tn'
00430	     DrawType=DT_Mesh
00431	     Mesh=LodMesh'UnrealShare.Tentacle1'
00432	     CollisionRadius=28.000000
00433	     CollisionHeight=36.000000
00434	     Mass=200.000000
00435	     Buoyancy=400.000000
00436	     RotationRate=(Pitch=0,Yaw=30000,Roll=0)
00437	}

End Source Code