UnrealShare
Class Manta

source: e:\games\UnrealTournament\UnrealShare\Classes\Manta.uc
Core.Object
   |
   +--Engine.Actor
      |
      +--Engine.Pawn
         |
         +--UnrealShare.ScriptedPawn
            |
            +--UnrealShare.Manta
Direct Known Subclasses:GiantManta, CaveManta

class Manta
extends UnrealShare.ScriptedPawn

//============================================================================= // Manta. //=============================================================================
Variables
 bool bAttackBump
 bool bAvoidHit
 var() byte

States
TacticalMove, Charging, MeleeAttack

Function Summary
 void PlayChallenge()
 void PlayDying(name DamageType, vector HitLocation)
 void PlayInAir()
 void PlayLanded(float impactVel)
 void PlayMeleeAttack()
 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 PreBeginPlay()
     
/* PreSetMovement()
default for walking creature.  Re-implement in subclass
for swimming/flying capability
*/
 void PreSetMovement()
 void SetMovementPhysics()
 void TweenToFalling()
 void TweenToFighter(float tweentime)
 void TweenToPatrolStop(float tweentime)
 void TweenToRunning(float tweentime)
 void TweenToWaiting(float tweentime)
 void TweenToWalking(float tweentime)


State TacticalMove Function Summary
 void Bump(Actor Other)
 void PickDestination(bool bNoCharge)


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


State MeleeAttack Function Summary
 void KeepAttacking()
 void Bump(Actor Other)



Source Code


00001	//=============================================================================
00002	// Manta.
00003	//=============================================================================
00004	class Manta extends ScriptedPawn;
00005	
00006	#exec MESH IMPORT MESH=Manta1 ANIVFILE=MODELS\manta_a.3D DATAFILE=MODELS\manta_d.3D X=0 Y=0 Z=0 ZEROTEX=1 LODSTYLE=2
00007	#exec MESH ORIGIN MESH=Manta1 X=0 Y=-50 Z=100 ROLL=-64 YAW=64
00008	
00009	#exec MESH SEQUENCE MESH=Manta1 SEQ=All		STARTFRAME=0	NUMFRAMES=152
00010	#exec MESH SEQUENCE MESH=Manta1 SEQ=Death	STARTFRAME=0	NUMFRAMES=26
00011	#exec MESH SEQUENCE MESH=Manta1 SEQ=Fly		STARTFRAME=26	NUMFRAMES=20
00012	#exec MESH SEQUENCE MESH=Manta1 SEQ=Fighter STARTFRAME=26	NUMFRAMES=1
00013	#exec MESH SEQUENCE MESH=Manta1 SEQ=Landing STARTFRAME=46   NUMFRAMES=26
00014	#exec MESH SEQUENCE MESH=Manta1 SEQ=Sting	STARTFRAME=72	NUMFRAMES=30  Group=Attack
00015	#exec MESH SEQUENCE MESH=Manta1 SEQ=ThreatSting  STARTFRAME=72  NUMFRAMES=30
00016	#exec MESH SEQUENCE MESH=Manta1 SEQ=TakeOff STARTFRAME=102  NUMFRAMES=20
00017	#exec MESH SEQUENCE MESH=Manta1 SEQ=Whip	STARTFRAME=122	NUMFRAMES=30  Group=Attack
00018	#exec MESH SEQUENCE MESH=Manta1 SEQ=TakeHit STARTFRAME=4	NUMFRAMES=1
00019	#exec MESH SEQUENCE MESH=Manta1 SEQ=Waiting STARTFRAME=66   NUMFRAMES=5
00020	
00021	#exec TEXTURE IMPORT NAME=JManta1 FILE=MODELS\manta.PCX GROUP="Skins" FLAGS=2
00022	#exec MESHMAP SCALE MESHMAP=Manta1 X=0.07 Y=0.07 Z=0.14
00023	#exec MESHMAP SETTEXTURE MESHMAP=Manta1 NUM=0 TEXTURE=JManta1
00024	
00025	#exec MESH NOTIFY MESH=Manta1 SEQ=Death TIME=0.76 FUNCTION=LandThump
00026	
00027	#exec AUDIO IMPORT FILE="Sounds\Manta\whip1a.WAV" NAME="whip1m" GROUP="Manta"
00028	#exec AUDIO IMPORT FILE="Sounds\Manta\injur1a.WAV" NAME="injur1m" GROUP="Manta"
00029	#exec AUDIO IMPORT FILE="Sounds\Manta\injur2a.WAV" NAME="injur2m" GROUP="Manta"
00030	#exec AUDIO IMPORT FILE="Sounds\Manta\call1a.WAV" NAME="call1m" GROUP="Manta"
00031	#exec AUDIO IMPORT FILE="Sounds\Manta\call2a.WAV" NAME="call2m" GROUP="Manta"
00032	#exec AUDIO IMPORT FILE="Sounds\Manta\fly1a.WAV" NAME="fly1m" GROUP="Manta"
00033	#exec AUDIO IMPORT FILE="Sounds\Manta\death2c.WAV" NAME="death2m" GROUP="Manta"
00034	#exec AUDIO IMPORT FILE="Sounds\Manta\sting1a.WAV" NAME="sting1m" GROUP="Manta"
00035	#exec AUDIO IMPORT FILE="Sounds\Manta\land1mt.WAV" NAME="land1mt" GROUP="Manta"
00036	
00037	//-----------------------------------------------------------------------------
00038	// Manta variables.
00039	
00040	// Attack damage.
00041	var() byte
00042		StingDamage,	// Basic damage done by Sting.
00043		WhipDamage;		// Basic damage done by whip.
00044	var bool bAttackBump;
00045	var bool bAvoidHit;
00046	var(Sounds) sound whip;
00047	var(Sounds) sound wingBeat;
00048	var(Sounds) sound sting;
00049	
00050	//-----------------------------------------------------------------------------
00051	// Manta functions.
00052	
00053	/* PreSetMovement()
00054	default for walking creature.  Re-implement in subclass
00055	for swimming/flying capability
00056	*/
00057	
00058	function PreBeginPlay()
00059	{
00060		Super.PreBeginPlay();
00061		if ( skill <= 1 )
00062			Health = 0.6 * Health;
00063		if ( skill == 0 )
00064			AttitudeToPlayer = ATTITUDE_Ignore;
00065	}
00066	
00067	function PreSetMovement()
00068	{
00069		MaxDesiredSpeed = 0.6 + 0.13 * skill;
00070		bCanJump = true;
00071		bCanWalk = true;
00072		bCanSwim = true;
00073		bCanFly = true;
00074		MinHitWall = -0.6;
00075		if (Intelligence > BRAINS_Reptile)
00076			bCanOpenDoors = true;
00077		if (Intelligence == BRAINS_Human)
00078			bCanDoSpecial = true;
00079	}
00080	
00081	function SetMovementPhysics()
00082	{
00083		if (Region.Zone.bWaterZone)
00084			SetPhysics(PHYS_Swimming);
00085		else
00086			SetPhysics(PHYS_Flying); 
00087	}
00088	
00089	function PlayWaiting()
00090		{
00091		LoopAnim('Waiting', 0.1 + 0.5 * FRand());
00092		}
00093	
00094	function PlayPatrolStop()
00095		{
00096		PlaySound(WingBeat, SLOT_Interact);
00097		LoopAnim('Fly', 0.4);
00098		}
00099	
00100	function PlayWaitingAmbush()
00101		{
00102		PlayWaiting();
00103		}
00104	
00105	function PlayChallenge()
00106	{
00107		PlayAnim('Fly', 0.4, 0.1);
00108	}
00109	
00110	function TweenToFighter(float tweentime)
00111	{
00112		TweenAnim('Fly', tweentime);
00113	}
00114	
00115	function TweenToRunning(float tweentime)
00116	{
00117		if ( (AnimSequence != 'Fly') || !bAnimLoop )
00118			TweenAnim('Fly', tweentime);
00119	}
00120	
00121	function TweenToWalking(float tweentime)
00122	{
00123		if ( (AnimSequence != 'Fly') || !bAnimLoop )
00124			TweenAnim('Fly', tweentime);
00125	}
00126	
00127	function TweenToWaiting(float tweentime)
00128	{
00129		PlayAnim('Landing', 0.2 + 0.8 * FRand());
00130		SetPhysics(PHYS_Falling);
00131	}
00132	
00133	function TweenToPatrolStop(float tweentime)
00134	{
00135		TweenAnim('Fly', tweentime);
00136	}
00137	
00138	function PlayRunning()
00139	{
00140		PlaySound(WingBeat, SLOT_Interact);
00141		LoopAnim('Fly', -1.0/AirSpeed,, 0.4);
00142	}
00143	
00144	function PlayWalking()
00145	{
00146		PlaySound(WingBeat, SLOT_Interact);
00147		LoopAnim('Fly', -1.0/AirSpeed,, 0.4);
00148	}
00149	
00150	function PlayThreatening()
00151	{
00152		if ( FRand() < 0.8 ) 
00153		{
00154			PlaySound(WingBeat, SLOT_Interact);
00155			PlayAnim('Fly', 0.4);
00156		}
00157		else
00158			LoopAnim('ThreatSting', 0.4);
00159	}
00160	
00161	function PlayTurning()
00162	{
00163		if (FRand() < 0.5)
00164			TweenAnim('Fighter', 0.2);
00165		else
00166		{
00167			PlaySound(WingBeat, SLOT_Interact);
00168			LoopAnim('Fly', -1.0/AirSpeed,, 0.4);
00169		}
00170	}
00171	
00172	function PlayDying(name DamageType, vector HitLocation)
00173	{
00174		PlaySound(Die, SLOT_Talk, 4 * TransientSoundVolume);
00175		PlayAnim('Death', 0.7, 0.1);
00176	}
00177	
00178	function PlayTakeHit(float tweentime, vector HitLoc, int Damage)
00179	{
00180		TweenAnim('TakeHit', tweentime);
00181	}
00182	
00183	function TweenToFalling()
00184	{
00185		TweenAnim('Fly', 0.2);
00186	}
00187	
00188	function PlayInAir()
00189	{
00190		LoopAnim('Fly');
00191	}
00192	
00193	function PlayLanded(float impactVel)
00194	{
00195		PlayAnim('Landing');
00196	}
00197	
00198	
00199	function PlayVictoryDance()
00200	{
00201		PlayAnim('Whip', 0.6, 0.1);
00202		PlaySound(Threaten, SLOT_Talk);		
00203	}
00204		
00205	function PlayMeleeAttack()
00206	{
00207		local vector adjust;
00208		adjust = vect(0,0,0.8) * Target.CollisionHeight;
00209		Acceleration = AccelRate * Normal(Target.Location - Location + adjust);
00210		Enable('Bump');
00211		bAttackBump = false;
00212		//log("Start Melee Attack");
00213		if (FRand() < 0.5)
00214			{
00215			PlayAnim('Sting');
00216			PlaySound(Sting, SLOT_Interact);	 		
00217	 		}
00218		else
00219		{
00220	 		PlayAnim('Whip');
00221	 		PlaySound(Whip, SLOT_Interact); 
00222	 	}	
00223	 }
00224	
00225	state MeleeAttack
00226	{
00227	ignores SeePlayer, HearNoise;
00228	
00229		singular function Bump(actor Other)
00230		{
00231			Disable('Bump');
00232			if (AnimSequence == 'Whip')
00233				MeleeDamageTarget(WhipDamage, (WhipDamage * 1000.0 * Normal(Target.Location - Location)));
00234			else if (AnimSequence == 'Sting')
00235				MeleeDamageTarget(StingDamage, (StingDamage * 1000.0 * Normal(Target.Location - Location)));
00236			bAttackBump = true;
00237			Velocity *= -0.5;
00238			Acceleration *= -1;
00239			if (Acceleration.Z < 0)
00240				Acceleration.Z *= -1;
00241		}
00242	
00243		function KeepAttacking()
00244		{
00245			if (Target == None) 
00246				GotoState('Attacking');
00247			else if ( (Pawn(Target) != None) && (Pawn(Target).Health == 0) )
00248				GotoState('Attacking');
00249			else if (bAttackBump)
00250			{
00251				SetTimer(TimeBetweenAttacks, false);
00252				GotoState('TacticalMove', 'NoCharge');
00253			}
00254		}
00255	}		
00256	
00257	state Charging
00258	{
00259	ignores SeePlayer, HearNoise;
00260	
00261		function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, 
00262								Vector momentum, name damageType)
00263		{
00264			Global.TakeDamage(Damage, instigatedBy, hitlocation, momentum, damageType);
00265			if ( health <= 0 )
00266				return;
00267			if (NextState == 'TakeHit')
00268			{
00269				if (AttitudeTo(Enemy) == ATTITUDE_Fear)
00270				{
00271					NextState = 'Retreating';
00272					NextLabel = 'Begin';
00273				}
00274				else if ( (FRand() < 3 * Damage/Default.Health) && ((Damage > 0.5 * Health) || (VSize(Location - Enemy.Location) > 150)) )
00275				{
00276					bAvoidHit = true;
00277					NextState = 'TacticalMove';
00278					NextLabel = 'NoCharge';
00279				}
00280				else
00281				{
00282					NextState = 'Charging';
00283					NextLabel = 'TakeHit';
00284				}
00285				GotoState('TakeHit'); 
00286			}
00287		}
00288	}
00289	
00290	state TacticalMove
00291	{
00292	ignores SeePlayer, HearNoise;
00293	
00294		function PickDestination(bool bNoCharge)
00295		{
00296			local vector pick, pickdir, enemydir,Y, minDest;
00297			local actor HitActor;
00298			local vector HitLocation, HitNormal, collSpec;
00299			local float Aggression, enemydist, minDist, strafeSize, MaxMove;
00300	
00301			if ( bAvoidHit && (FRand() < 0.7) )
00302				MaxMove = 300;
00303			else 
00304				MaxMove = 600;
00305					
00306			bAvoidHit = false;
00307			enemyDist = VSize(Location - Enemy.Location);
00308			Aggression = 2 * FRand() - 1.0;
00309	
00310			if (enemyDist < CollisionRadius + Enemy.CollisionRadius + 2 * MeleeRange)
00311				Aggression = FMin(0.0, Aggression);	
00312			else if (enemyDist > FMax(VSize(OldLocation - Enemy.OldLocation), 240))
00313				Aggression = FMax(0.0, Aggression);
00314			
00315			enemydir = (Enemy.Location - Location)/enemyDist;
00316			minDist = FMin(160.0, 5*CollisionRadius);
00317			Y = (enemydir Cross vect(0,0,1));
00318			strafeSize = FMin(0.8, (2 * Abs(Aggression) * FRand() - 0.2));
00319			if (Aggression <= 0)
00320				strafeSize *= -1;
00321			enemydir = enemydir * strafeSize;
00322			if (FRand() < 0.8)
00323				enemydir.Z = 1.5;
00324			else
00325				enemydir.Z = FMax(0,enemydir.Z);
00326	
00327			strafeSize = FMax(0.0, 1 - Abs(strafeSize));
00328			pickdir = strafeSize * Y;
00329			pick = Location + (pickdir + enemydir) * (minDist + MaxMove * FRand());
00330			pick.Z = Location.Z + 60 + 0.65 * MaxMove * FRand();
00331			minDest = Location + minDist * Normal(pick - location); 
00332			collSpec.X = CollisionRadius;
00333			collSpec.Y = CollisionRadius;
00334			collSpec.Z = CollisionHeight;
00335			
00336			HitActor = Trace(HitLocation, HitNormal, minDest, Location, false, collSpec);
00337			if ( HitActor == None )
00338			{
00339				Destination = pick;
00340				return;	
00341			}
00342			pick = Location + (enemydir - pickdir) * (minDist + MaxMove * FRand());
00343			pick.Z = Location.Z + 60 + 0.5 * MaxMove * FRand();
00344			minDest = Location + minDist * Normal(pick - location); 
00345			HitActor = Trace(HitLocation, HitNormal, minDest, Location, false, collSpec);
00346			if ( HitActor == None )
00347			{
00348				Destination = pick;
00349				return;	
00350			}
00351			
00352			pick = Location - enemydir * (minDist + MaxMove * FRand());
00353			pick.Z = Location.Z + 0.5 * MaxMove * FRand();
00354			minDest = Location + Normal(pick - Location) * minDist;
00355			HitActor = Trace(HitLocation, HitNormal, minDest, Location, false, collSpec);
00356			if ( HitActor == None )
00357			{
00358				Destination = pick;
00359				return;	
00360			}
00361			
00362			if ( !bNoCharge && (enemyDist > 120) )
00363				GotoState('Charging');	
00364			
00365			pick = MaxMove * FRand() * VRand();	
00366			pick.Z = FMin(Location.Z, pick.Z);
00367			Destination = pick;	 
00368		}
00369	
00370	
00371	
00372		function Bump(Actor Other)
00373		{
00374			Disable('Bump');
00375			if (bAttackBump == true)
00376				bAttackBump = false;
00377			else if (Other == Enemy)
00378				{
00379				bReadyToAttack = true;
00380				Target = Enemy;
00381				GotoState('MeleeAttack');
00382				}
00383			else if (Enemy.Health <= 0)
00384				GotoState('Attacking');
00385		}
00386	}
00387	
00388	defaultproperties
00389	{
00390	     StingDamage=20
00391	     WhipDamage=20
00392	     Whip=Sound'UnrealShare.Manta.whip1m'
00393	     wingBeat=Sound'UnrealShare.Manta.fly1m'
00394	     Sting=Sound'UnrealShare.Manta.sting1m'
00395	     CarcassType=Class'UnrealShare.MantaCarcass'
00396	     Aggressiveness=0.200000
00397	     RefireRate=0.500000
00398	     WalkingSpeed=0.600000
00399	     bIsWuss=True
00400	     Acquire=Sound'UnrealShare.Manta.call1m'
00401	     Fear=Sound'UnrealShare.Manta.injur2m'
00402	     Roam=Sound'UnrealShare.Manta.call2m'
00403	     Threaten=Sound'UnrealShare.Manta.call2m'
00404	     MeleeRange=120.000000
00405	     WaterSpeed=300.000000
00406	     AirSpeed=400.000000
00407	     AccelRate=800.000000
00408	     JumpZ=10.000000
00409	     SightRadius=1500.000000
00410	     Health=78
00411	     UnderWaterTime=-1.000000
00412	     HitSound1=Sound'UnrealShare.Manta.injur1m'
00413	     HitSound2=Sound'UnrealShare.Manta.injur2m'
00414	     Land=Sound'UnrealShare.Manta.land1mt'
00415	     Die=Sound'UnrealShare.Manta.death2m'
00416	     WaterStep=None
00417	     CombatStyle=-0.300000
00418	     DrawType=DT_Mesh
00419	     Mesh=LodMesh'UnrealShare.Manta1'
00420	     CollisionRadius=27.000000
00421	     CollisionHeight=12.000000
00422	     Mass=80.000000
00423	     Buoyancy=80.000000
00424	     RotationRate=(Pitch=16384,Yaw=55000,Roll=15000)
00425	}

End Source Code