UnrealShare
Class NaliRabbit

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

class NaliRabbit
extends UnrealShare.FlockPawn

//============================================================================= // NaliRabbit. //=============================================================================
Variables
 vector StartLocation
 float WanderRadius
 bool bStayClose

States
Evade, Grazing

Function Summary
 void Attach(Actor Other)
 void Falling()
 void Landed(vector HitNormal)
 void TakeDamage(int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, name damageType)


State Evade Function Summary
 void PickDestination()
 bool TestDirection(vector dir, out vector)
 void Bump(Actor Other)
 void EnemyNotVisible()


State Grazing Function Summary
 void EndState()
 void BeginState()
 void AnimEnd()
 void PickDestination()
 bool TestDirection(vector dir, out vector, bool bAlongWall)
 void Bump(Actor Other)
 void SeePlayer(Actor Seen)



Source Code


00001	//=============================================================================
00002	// NaliRabbit.
00003	//=============================================================================
00004	class NaliRabbit extends FlockPawn;
00005	
00006	#exec MESH IMPORT MESH=Rabbit ANIVFILE=MODELS\NRoo_a.3D DATAFILE=MODELS\NRoo_d.3D X=0 Y=0 Z=0
00007	#exec MESH LODPARAMS MESH=Rabbit STRENGTH=0.2 
00008	#exec MESH ORIGIN MESH=Rabbit X=0 Y=160 Z=00 YAW=128 ROLL=-64
00009	
00010	#exec MESH SEQUENCE MESH=Rabbit SEQ=All     STARTFRAME=0  NUMFRAMES=98
00011	#exec MESH SEQUENCE MESH=Rabbit SEQ=Call	STARTFRAME=0   NUMFRAMES=16
00012	#exec MESH SEQUENCE MESH=Rabbit SEQ=Eat 	STARTFRAME=16  NUMFRAMES=40
00013	#exec MESH SEQUENCE MESH=Rabbit SEQ=Jump    STARTFRAME=56  NUMFRAMES=14
00014	#exec MESH SEQUENCE MESH=Rabbit SEQ=JumpUp  STARTFRAME=56  NUMFRAMES=9
00015	#exec MESH SEQUENCE MESH=Rabbit SEQ=Land    STARTFRAME=65  NUMFRAMES=5
00016	#exec MESH SEQUENCE MESH=Rabbit SEQ=Looking	STARTFRAME=70  NUMFRAMES=28
00017	
00018	#exec TEXTURE IMPORT NAME=JRabbit1 FILE=MODELS\Nroo.PCX GROUP=Skins
00019	#exec MESHMAP SCALE MESHMAP=Rabbit X=0.1 Y=0.1 Z=0.2
00020	#exec MESHMAP SETTEXTURE MESHMAP=Rabbit NUM=1 TEXTURE=JRabbit1
00021	
00022	#exec AUDIO IMPORT FILE="Sounds\bunny\call1bn.WAV" NAME="CallBn" GROUP="Rabbit"
00023	
00024	var() bool bStayClose;
00025	var() float WanderRadius;
00026	var vector StartLocation;
00027	
00028	function Falling()
00029	{
00030		PlayAnim('JumpUp', 1.0, 0.1);
00031	}
00032	
00033	function Landed(vector HitNormal)
00034	{
00035		PlayAnim('Land', 1.0, 0.05);
00036	}
00037	
00038	function Attach( actor Other )
00039	{
00040		if ( Other.Mass > 39 )
00041			TakeDamage( 10, Pawn(Other), Location, vect(0,0,0), 'Squashed');
00042	}
00043	
00044	function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, 
00045						Vector momentum, name damageType)
00046	{
00047		local CreatureChunks carc;
00048		local Pawn aPawn;
00049		
00050		if ( Damage > 4 )
00051		{
00052			Velocity += momentum/mass;
00053			if ( instigator != None )
00054			{
00055				aPawn = Level.PawnList;
00056				While ( aPawn != None )
00057				{
00058					if ( aPawn.IsA('NaliRabbit') && (Location.Z - aPawn.Location.Z < 120) 
00059						&& (VSize(Location - aPawn.Location) < 500) )
00060					{
00061						aPawn.Enemy = instigator;
00062						aPawn.GotoState('Evade');
00063					}	
00064					aPawn = aPawn.NextPawn;
00065				}
00066			}
00067			Spawn(class'BloodBurst');
00068			carc = Spawn(class 'CreatureChunks',,, Location);
00069			if (carc != None)
00070			{
00071				carc.TrailSize = 3;
00072				carc.Mesh = mesh'CowBody1';
00073				carc.DrawScale = 0.65;
00074				carc.Initfor(self);
00075			}
00076			PlaySound(sound'gibP6',, 3.0);
00077			Destroy();
00078		}
00079		else
00080			PlaySound(sound'CallBn');
00081	}
00082	
00083	auto state Grazing
00084	{
00085		ignores EnemyNotVisible;
00086		
00087		function SeePlayer(actor Seen)
00088		{
00089			Enemy = Pawn(Seen);
00090			Disable('SeePlayer');
00091			SetPhysics(PHYS_Walking);
00092			GotoState('Grazing', 'Wander');
00093		}
00094		
00095		function Bump(actor Other)
00096		{
00097			if ( (Normal(Destination - Location) Dot Normal(Other.Location - Location)) > 0.7 )
00098				MoveTimer = -1.0;
00099			if ( (Pawn(Other) != None) && (Pawn(Other).bIsPlayer || Other.IsA('ScriptedPawn')) )
00100			{
00101				Enemy = Pawn(Other);
00102				GotoState('Evade');
00103			}
00104			Disable('Bump');
00105		}
00106	
00107		function bool TestDirection(vector dir, out vector pick, bool bAlongWall)
00108		{	
00109			local vector HitLocation, HitNormal;
00110			local float minDist, Dist;
00111			local actor HitActor;
00112	
00113			dir.Z = 0;
00114			dir = Normal(dir);
00115			minDist = FMin(180.0, 6*CollisionRadius); 
00116			pick = Location + dir * (minDist + FRand() * 900);
00117	
00118			HitActor = Trace(HitLocation, HitNormal, pick, Location, false);
00119			Dist = VSize(HitLocation - Location);
00120			if ( (Dist < minDist) && (HitNormal.Z < 0.7) )
00121			{
00122				if ( !bAlongWall )
00123					return false;
00124				pick = HitLocation - dir + (HitNormal Cross vect(0,0,1)) * 5 * CollisionRadius;
00125				HitActor = Trace(HitLocation, HitNormal, pick , Location, false);
00126				if (HitActor != None)
00127					return false;
00128			}
00129			else 
00130				pick = HitLocation - 4 * CollisionRadius * dir;
00131	
00132			return true; 
00133		}
00134				
00135		function PickDestination()
00136		{
00137			local vector pickdir;
00138			local bool success;
00139			local float XY, dist;
00140	
00141			// don't wander too far
00142			if ( bStayClose )
00143			{
00144				pickDir = StartLocation - Location;
00145				dist = VSize(pickDir);
00146				if ( dist > WanderRadius )
00147				{
00148					pickdir = pickDir/dist;
00149					if ( TestDirection(pickdir, Destination, true) )
00150						return;
00151				}
00152			}
00153					
00154			//Favor XY alignment
00155			pickdir.Z = 0;
00156			XY = FRand();
00157			if (XY < 0.3)
00158			{
00159				pickdir.X = 1;
00160				pickdir.Y = 0;
00161			}
00162			else if (XY < 0.6)
00163			{
00164				pickdir.X = 0;
00165				pickdir.Y = 1;
00166			}
00167			else
00168			{
00169				pickdir.X = 2 * FRand() - 1;
00170				pickdir.Y = 2 * FRand() - 1;
00171				pickdir = Normal(pickdir);
00172			}
00173			
00174			success = TestDirection(pickdir, Destination, false);
00175			if (!success)
00176				success = TestDirection(-1 * pickdir, Destination, true);
00177			
00178			if ( !success )
00179			{
00180				Destination = Location;
00181				GotoState('Grazing', 'Turn');
00182			}
00183		}
00184		
00185		function AnimEnd()
00186		{
00187			local float decision;
00188			decision = FRand();
00189			if  ( decision < 0.6 )
00190				PlayAnim('Eat', 0.2 + 0.2 * FRand());
00191			else if ( decision < 0.8 )
00192			{
00193				PlaySound(sound'CallBn');
00194				PlayAnim('Call', 0.4 + 0.2 * FRand());
00195			}
00196			else
00197				PlayAnim('Looking', 0.2 + 0.3 * FRand());
00198		}
00199	
00200		function BeginState()
00201		{
00202			StartLocation = Location;
00203			bCanJump = false;
00204		}	
00205		function EndState()
00206		{
00207			bCanJump = true;
00208		}
00209	
00210	Wander: 
00211		Disable('AnimEnd');
00212		WaitForLanding();
00213		PickDestination();
00214		TweenAnim('Jump', 0.2);
00215		FinishAnim();
00216		LoopAnim('Jump');
00217		
00218	Moving:
00219		Enable('Bump');
00220		MoveTo(Destination, 0.4);
00221		Acceleration = vect(0,0,0);
00222	Graze:
00223		TweenAnim('Eat', 0.2);
00224		Enable('AnimEnd');
00225		Sleep(6 + 6 * FRand());
00226		Disable('AnimEnd');
00227		FinishAnim();
00228		if ( !LineOfSightTo(Enemy) )
00229		{
00230			Enemy = None;
00231			Enable('SeePlayer');
00232			Goto('Begin');
00233		}
00234		Goto('Wander');
00235	
00236	Turn:
00237		PlayTurning();
00238		TurnTo(Location + 20 * VRand());
00239		Goto('Graze');
00240	
00241	Begin:
00242		WaitForLanding();
00243		SetPhysics(PHYS_None);
00244		TweenAnim('Eat', 0.2);
00245	}
00246	
00247	State Evade
00248	{
00249		ignores SeePlayer;
00250		
00251		function EnemyNotVisible()
00252		{
00253			GotoState('Grazing');
00254		}
00255		
00256		function Bump(actor Other)
00257		{
00258			if ( (Normal(Destination - Location) Dot Normal(Other.Location - Location)) > 0.75 )
00259				MoveTimer = -1.0;
00260			if ( (Pawn(Other) != None) && (Pawn(Other).bIsPlayer || Other.IsA('ScriptedPawn')) )
00261				Enemy = Pawn(Other);
00262	
00263			Disable('Bump');
00264		}
00265		
00266		function bool TestDirection(vector dir, out vector pick)
00267		{	
00268			local vector HitLocation, HitNormal;
00269			local actor HitActor;
00270	
00271			HitActor = Trace(HitLocation, HitNormal, Location + dir * 150, Location, false);
00272			if ( (HitActor != None) && (HitNormal.Z < 0.7) )
00273			{
00274				pick = HitLocation - dir + (HitNormal Cross vect(0,0,1)) * 5 * CollisionRadius;
00275				HitActor = Trace(HitLocation, HitNormal, pick , Location, false);
00276				if (HitActor != None)
00277					return false;
00278			}
00279			else
00280				pick = Location + dir * (150 + FRand() * 450);
00281	
00282			return true; 
00283		}
00284		
00285		function PickDestination()
00286		{
00287			local vector pick, pickdir, enemyDir;
00288			local bool success;
00289			local float XY;
00290					
00291			enemyDir = Enemy.Location - Location;
00292			pickDir	= VRand();
00293			pickDir.Z = 0;
00294			if ( (pickDir Dot enemyDir) > 0 )
00295				pickDir *= -1;	
00296			success = TestDirection(pickdir, pick);
00297			if (!success)
00298			{
00299				pickDir	= VRand();
00300				pickDir.Z = 0;
00301				if ( (pickDir Dot enemyDir) > 0 )
00302					pickDir *= -1;	
00303				success = TestDirection( pickDir, pick);
00304			}		
00305			if (success)
00306				Destination = pick;
00307			else
00308			{
00309				Destination = Location;
00310				GotoState('Evade', 'Turn');
00311			}
00312		}
00313	
00314	Begin:
00315		//log(class$" Evading");
00316	
00317	Wander: 
00318		WaitForLanding();
00319		PickDestination();
00320		TurnTo(Destination);
00321		Falling();
00322		SetPhysics(PHYS_Falling);
00323		Velocity = GroundSpeed * Normal(Destination - Location);
00324		Velocity.Z = 360;
00325		WaitForLanding();
00326		FinishAnim();
00327		LoopAnim('Jump', 1.5);
00328		
00329	Moving:
00330		Enable('Bump');
00331		MoveTo(Destination);
00332		Acceleration = vect(0,0,0);
00333	Graze:
00334		if ( FRand() < 0.3 )
00335		{
00336			PlaySound(sound'CallBN');
00337			PlayAnim('Call', 0.4 + 0.2 * FRand(), 0.2);
00338		}
00339		else
00340			PlayAnim('Looking', 0.2 + 0.3 * FRand(), 0.2);
00341		FinishAnim();
00342		Goto('Wander');
00343	
00344	Turn:
00345		PlayTurning();
00346		TurnTo(Location + 20 * VRand());
00347		Goto('Graze');
00348	}
00349	
00350	defaultproperties
00351	{
00352	     bStayClose=True
00353	     WanderRadius=350.000000
00354	     GroundSpeed=400.000000
00355	     AccelRate=1500.000000
00356	     JumpZ=190.000000
00357	     MinHitWall=-0.100000
00358	     SightRadius=1000.000000
00359	     PeripheralVision=-10.000000
00360	     UnderWaterTime=3.000000
00361	     DrawType=DT_Mesh
00362	     Mesh=LodMesh'UnrealShare.Rabbit'
00363	     CollisionRadius=18.299999
00364	     CollisionHeight=13.300000
00365	     Mass=20.000000
00366	     Buoyancy=21.000000
00367	}

End Source Code