RuneI
Class TubeStriker

source: c:\runehov\RuneI\Classes\TubeStriker.uc
Core.Object
   |
   +--Engine.Actor
      |
      +--Engine.Pawn
         |
         +--RuneI.ScriptPawn
            |
            +--RuneI.TubeStriker
Direct Known Subclasses:BabyTubeStriker

class TubeStriker
extends RuneI.ScriptPawn

//============================================================================= // TubeStriker. //=============================================================================
Variables
 float FlingVelocity
           Magnitude of fling velocity
 float SleepTime
           Amount of time to sleep before becoming alert
 bool bAlerted
           Whether to accept/send alerts to others
 bool bCanGrab
           Can grab enemies
 bool bThrowOK
           Amount of time to sleep before becoming alert

States
Dying, Pain, WaitForRefire, Flinging, Striking, Alerted, Waiting

Function Summary
 void Alert(Actor threat, float delay)
 bool BodyPartCritical(int BodyPart)
     
//============================================================
//
// BodyPartCritical
//
//============================================================
 int BodyPartForJoint(int joint)
     
//============================================================
//
// BodyPartForJoint
//
// Returns the body part a joint is associated with
//============================================================
 int BodyPartForPolyGroup(int polygroup)
     
//============================================================
//
// BodyPartForPolyGroup
//
//============================================================
 bool BodyPartSeverable(int BodyPart)
     
//============================================================
//
// BodyPartSeverable
//
//============================================================
 bool CanPickup(Inventory item)
     
//================================================
//
// CanPickup
//
// Let's pawn dictate what it can pick up
//================================================
 void CheckForEnemies()
 bool DamageBodyPart(int Damage, Pawn EventInstigator, vector HitLocation, vector Momentum, name DamageType, int bodypart)
     
//============================================================
//
// DamageBodyPart
//
//============================================================
 void FlingItem()
 int LimbPassThrough(int BodyPart, int Blunt, int Sever)
     
//============================================================
//
// LimbPassThrough
//
// Determines what damage is passed through to body
//============================================================
 void LimbSevered(int BodyPart, vector Momentum)
     
//============================================================
//
// LimbSevered
//
//============================================================
 EMatterType MatterForJoint(int joint)
     
//============================================================
//
// MatterForJoint
//
// Returns what kind of material joint is associated with
//============================================================
 Texture PainSkin(int BodyPart)
     
//============================================================
//
// PainSkin
//
//============================================================
 void PlayAttacking()
 void PlayDeath(name DamageType)
 void PlayWaiting(optional float)
     
//============================================================
// Animation functions
//============================================================


State Dying Function Summary
 void BeginState()


State Pain Function Summary
 bool CanGotoPainState()
 void EndState()
 void BeginState()


State WaitForRefire Function Summary


State Flinging Function Summary
 void DoThrow()
     
// Notify to fling item
 bool JointDamaged(int Damage, Pawn EventInstigator, vector HitLoc, vector Momentum, name DamageType, int joint)
     
// Disallow any damage from flinging actor
 void SoundNotify1()
 void EndState()
 void AmbientSoundTimer()
 void BeginState()


State Striking Function Summary
 bool AllowWeaponToHitActor(Weapon W, Actor A)
 bool JointDamaged(int Damage, Pawn EventInstigator, vector HitLoc, vector Momentum, name DamageType, int joint)
 void WeaponDeactivate()
 void WeaponActivate()
 void AmbientSoundTimer()
 void EndState()
 void BeginState()


State Alerted Function Summary
 void Timer()
 void AmbientSoundTimer()
 void EnemyNotVisible()


State Waiting Function Summary
 void Alert(Actor threat, float delay)
 void SeePlayer(Actor seen)
 void HearNoise(float Loudness, Actor NoiseMaker)
 void Bump(Actor Other)
 void BeginState()



Source Code


00001	//=============================================================================
00002	// TubeStriker.
00003	//=============================================================================
00004	class TubeStriker expands ScriptPawn;
00005	
00006	/* Description:
00007		No movement.  When idle, he dangles his tongue around for air/food.  When an
00008		enemy is detected, he alerts the others around him, and sucks in his tongue.
00009		When enemies are within his attack range, he brings his worm out and readys
00010		to attack.
00011		Has a chance of grabbing enemy and smashing him around on rocks.
00012		
00013	*/
00014	
00015	var bool bAlerted;			// Whether to accept/send alerts to others
00016	var float SleepTime;		// Amount of time to sleep before becoming alert
00017	var bool bThrowOK;
00018	var() bool bCanGrab;		// Can grab enemies
00019	var() float FlingVelocity;	// Magnitude of fling velocity
00020	var(Sounds) Sound	FlailSound;
00021	
00022	
00023	function Alert(actor threat, float delay)
00024	{	// No effect
00025	}
00026	
00027	//================================================
00028	//
00029	// CanPickup
00030	//
00031	// Let's pawn dictate what it can pick up
00032	//================================================
00033	function bool CanPickup(Inventory item)
00034	{
00035		return item.IsA('TubestrikerTongue');
00036	}
00037	
00038	function FlingItem()
00039	{
00040		local actor A;
00041		local vector X,Y,Z;
00042		local rotator r;
00043		
00044		A = DetachActorFromJoint(JointNamed('TongueD'));
00045		if (A != None)
00046		{
00047			A.SetPhysics(PHYS_Falling);
00048			GetAxes(Rotation, X,Y,Z);
00049			A.Velocity = (X+vect(0,0,1))*FlingVelocity;
00050			A.DesiredRotation.Yaw = Rotation.Yaw;
00051			r = A.default.Rotation;
00052			r.Yaw = Rotation.Yaw;
00053			A.SetRotation(r);
00054	
00055			if (A.IsA('Weapon'))
00056			{
00057				A.SetOwner(self);
00058				A.GotoState('throw');
00059			}
00060		}
00061	}
00062	
00063	function CheckForEnemies()
00064	{
00065	}
00066	
00067	//============================================================
00068	//
00069	// PainSkin
00070	//
00071	//============================================================
00072	function Texture PainSkin(int BodyPart)
00073	{
00074		switch(BodyPart)
00075		{
00076			case BODYPART_HEAD:
00077				if (SkelGroupSkins[2] == Texture'creatures.strikerstriker')
00078					SkelGroupSkins[2] = Texture'creatures.strikerstrikerpain';
00079				if (SkelGroupSkins[3] == Texture'creatures.strikerstriker')
00080					SkelGroupSkins[3] = Texture'creatures.strikerstrikerpain';
00081				break;
00082		}
00083	}
00084	
00085	//============================================================
00086	//
00087	// MatterForJoint
00088	//
00089	// Returns what kind of material joint is associated with
00090	//============================================================
00091	function EMatterType MatterForJoint(int joint)
00092	{
00093		switch(joint)
00094		{
00095			case 4: case 5: case 6:
00096			case 7: case 8: case 9:
00097			case 10:						return MATTER_FLESH;
00098	
00099			case 0: case 1: case 2: case 3:	return MATTER_EARTH;
00100			
00101		}
00102		return MATTER_NONE;
00103	}
00104	
00105	//============================================================
00106	//
00107	// BodyPartForJoint
00108	//
00109	// Returns the body part a joint is associated with
00110	//============================================================
00111	function int BodyPartForJoint(int joint)
00112	{
00113		switch(joint)
00114		{
00115			case 1:										return BODYPART_TORSO;	// Shell
00116			case 4: case 5: case 6:						return BODYPART_HEAD;	// Head
00117			case 7: case 8: case 9: case 10: case 11:	return BODYPART_RARM1;	// Tongue
00118		}
00119		return BODYPART_BODY;
00120	}
00121	
00122	//============================================================
00123	//
00124	// BodyPartForPolyGroup
00125	//
00126	//============================================================
00127	function int BodyPartForPolyGroup(int polygroup)
00128	{
00129		switch(polygroup)
00130		{
00131			case 1:		return BODYPART_BODY;
00132			case 2:		return BODYPART_HEAD;
00133			case 3:		return BODYPART_RARM1;
00134		}
00135		return BODYPART_BODY;
00136	}
00137	
00138	
00139	//============================================================
00140	//
00141	// BodyPartSeverable
00142	//
00143	//============================================================
00144	function bool BodyPartSeverable(int BodyPart)
00145	{
00146		return ((BodyPart == BODYPART_HEAD) || (BodyPart == BODYPART_RARM1));
00147	}
00148	
00149	
00150	//============================================================
00151	//
00152	// BodyPartCritical
00153	//
00154	//============================================================
00155	function bool BodyPartCritical(int BodyPart)
00156	{
00157		return ((BodyPart == BODYPART_HEAD) || (BodyPart == BODYPART_RARM1));
00158	}
00159	
00160	//================================================
00161	//
00162	// SeveredLimbClass
00163	//
00164	//================================================
00165	function class<Actor> SeveredLimbClass(int BodyPart)
00166	{
00167		switch(BodyPart)
00168		{
00169			case BODYPART_HEAD:
00170			case BODYPART_RARM1:
00171				return class'TTongue';
00172		}
00173	
00174		return None;
00175	}
00176	
00177	//============================================================
00178	//
00179	// LimbSevered
00180	//
00181	//============================================================
00182	function LimbSevered(int BodyPart, vector Momentum)
00183	{
00184		local int joint;
00185		local actor part;
00186		local vector X,Y,Z,pos;
00187		local class<actor> partclass;
00188	
00189		Super.LimbSevered(BodyPart, Momentum);
00190		partclass = SeveredLimbClass(BodyPart);
00191		
00192		switch(BodyPart)
00193		{
00194			case BODYPART_HEAD:
00195			case BODYPART_RARM1:
00196				joint = JointNamed('tonguea');
00197				pos = GetJointPos(joint);
00198				GetAxes(Rotation, X, Y, Z);
00199				part = Spawn(partclass,,, pos, Rotation);
00200				if(part != None)
00201				{
00202					part.Velocity = -Y * 100 + vect(0, 0, 175);
00203					part.GotoState('Drop');
00204				}
00205				break;
00206		}
00207	}
00208	
00209	
00210	//============================================================
00211	//
00212	// LimbPassThrough
00213	//
00214	// Determines what damage is passed through to body
00215	//============================================================
00216	function int LimbPassThrough(int BodyPart, int Blunt, int Sever)
00217	{
00218		if (BodyPart == BODYPART_BODY)	// Falling damage, etc.
00219			return Blunt+Sever;
00220	
00221		if (BodyPart == BODYPART_TORSO)	// Shell doesn't accept damage
00222			return 0;
00223	
00224		return Blunt+Sever;
00225	}
00226	
00227	
00228	//============================================================
00229	//
00230	// DamageBodyPart
00231	//
00232	//============================================================
00233	function bool DamageBodyPart(int Damage, Pawn EventInstigator, vector HitLocation, vector Momentum, name DamageType, int bodypart)
00234	{
00235		local bool bContinueSwipe;
00236	
00237		bContinueSwipe = true;
00238		if ((BodyPart == BODYPART_HEAD) || (BodyPart == BODYPART_RARM1))
00239		{
00240			Spawn(class'GreenBloodSpray',,, HitLocation, Rotation);
00241			GotoState('Pain');
00242		}
00243		else if (BodyPart == BODYPART_TORSO)
00244		{	// Stop the swipe
00245			bContinueSwipe = false;
00246		}
00247	
00248		Super.DamageBodyPart(Damage, EventInstigator, HitLocation, Momentum, DamageType, BodyPart);
00249		return bContinueSwipe;
00250	}
00251	
00252	
00253	//============================================================
00254	// Animation functions
00255	//============================================================
00256	function PlayWaiting(optional float tween)
00257	{
00258		LoopAnim('IdleA', RandRange(0.8, 1.2), 0.1);
00259	}
00260	
00261	function PlayAttacking()
00262	{
00263		PlayAnim('Attack', 1.0, 0.1);
00264	}
00265	
00266	function PlayDeath(name DamageType)
00267	{
00268		LoopAnim('Reeling', 1.0, 0.1);
00269	}
00270	
00271	
00272	
00273	
00274	
00275	//============================================================
00276	// States
00277	//============================================================
00278	
00279	//============================================================
00280	//
00281	// Waiting
00282	//
00283	// Hang out and wait for some stimuli
00284	//============================================================
00285	State Waiting
00286	{
00287		function BeginState()
00288		{
00289			BodyPartCollision(BODYPART_HEAD, false);
00290			BodyPartCollision(BODYPART_RARM1, false);
00291			bAlerted = false;
00292		}
00293	
00294		function Bump(actor Other)
00295		{
00296			Alert(Other, 0);
00297		}
00298		
00299		function HearNoise(float Loudness, actor NoiseMaker)
00300		{
00301			Alert(NoiseMaker, 0.5);
00302		}
00303		
00304		function SeePlayer(actor seen)
00305		{
00306			if (VSize(seen.Location - Location) < SightRadius)
00307			{
00308				Alert(seen, RandRange(0.1, 0.5));
00309			}
00310		}
00311	
00312		function Alert(actor threat, float delay)
00313		{
00314			local TubeStriker A;
00315	
00316			if (!bAlerted)
00317			{
00318				bAlerted = true;
00319	
00320				// Alert friends
00321				foreach VisibleActors(class'TubeStriker', A)
00322				{
00323					if (!A.bAlerted)
00324						A.Alert(threat, RandRange(0.5, 2.2));
00325				}
00326	
00327				LookTarget = threat;
00328				SleepTime = delay;
00329				GotoState('Alerted');
00330			}
00331		}
00332		
00333	Begin:
00334		if(debugstates) slog(name@"Waiting");
00335	//	SetPhysics(PHYS_Falling);
00336	//	WaitForLanding();
00337	//	SetPhysics(PHYS_None);
00338		PlayWaiting(0.1);
00339	}
00340	
00341	
00342	//============================================================
00343	//
00344	// Alerted
00345	//
00346	// Poised to strike
00347	//============================================================
00348	State Alerted
00349	{
00350		ignores Bump, SeePlayer, HearNoise, EnemyAcquired;
00351	
00352		function EnemyNotVisible()
00353		{
00354			GotoState('Waiting');
00355		}
00356	
00357		function AmbientSoundTimer()
00358		{
00359			PlayAmbientFightSound();
00360		}
00361	
00362		function Timer()
00363		{
00364			local actor A;
00365			
00366			foreach RadiusActors(class'actor', A, MeleeRange)
00367			{
00368				if ((Pawn(A)!=None && TubeStriker(A)==None && A!=self && Pawn(A).Health>0) ||
00369					(Inventory(A)!=None && InvisibleWeapon(A)==None && A.Owner!=None))
00370				{
00371					if (ActorInSector(A, MaxHeadAngle.Yaw) &&
00372						Abs(A.Location.Z-Location.Z)<100)
00373					{	// Attack
00374						Enemy = Pawn(A);
00375						LookTarget = A;
00376						GotoState('Striking');
00377						break;
00378					}
00379				}
00380			}
00381		}
00382	
00383	Begin:
00384		if(debugstates) slog(name@"Alerted");
00385		Sleep(SleepTime);
00386		PlaySound(AcquireSound, SLOT_Interact,,,, 1.0 + FRand()*0.2-0.1);
00387		PlayAnim('Ready', 1.0, 0.1);
00388		FinishAnim();
00389	Ready:
00390		LoopAnim('ReadyIdle', 1.0, 0.1);
00391		SetTimer(0.25 + FRand() * 0.1, true);
00392	}
00393	
00394	
00395	//============================================================
00396	//
00397	// Striking
00398	//
00399	//============================================================
00400	State Striking
00401	{
00402		ignores Bump, SeePlayer, HearNoise, EnemyAcquired;
00403	
00404		function BeginState()
00405		{	// Only collide during this state
00406		}
00407	
00408		function EndState()
00409		{
00410			WeaponDeactivate();
00411			BodyPartCollision(BODYPART_HEAD, false);
00412			BodyPartCollision(BODYPART_RARM1, false);
00413		}
00414	
00415		function AmbientSoundTimer()
00416		{
00417			PlayAmbientFightSound();
00418		}
00419	
00420		function WeaponActivate()
00421		{	// Notification used in attack
00422			BodyPartCollision(BODYPART_HEAD, true);
00423			BodyPartCollision(BODYPART_RARM1, true);
00424			Super.WeaponActivate();
00425		}
00426		
00427		function WeaponDeactivate()
00428		{	// Notification used in attack
00429			Super.WeaponDeactivate();
00430			BodyPartCollision(BODYPART_HEAD, false);
00431			BodyPartCollision(BODYPART_RARM1, false);
00432		}
00433	
00434		function bool JointDamaged(int Damage, Pawn EventInstigator, vector HitLoc, vector Momentum, name DamageType, int joint)
00435		{
00436			if (DamageType == 'thrownweaponblunt' || DamageType == 'thrownweaponsever' || DamageType == 'thrownweaponbluntsever')
00437			{	// Thrown weapon hit me, disallow damage so I can grab it
00438				return false;
00439			}
00440	
00441			return Super.JointDamaged(Damage, EventInstigator, HitLoc, Momentum, DamageType, joint);
00442		}
00443	
00444		function bool AllowWeaponToHitActor(Weapon W, Actor A)
00445		{
00446			local float chance;
00447	
00448			chance = FRand();
00449	
00450			if (A.IsA('Weapon') && A.AttachParent==None)
00451			{// Thrown weapon, grab it if has an owner below
00452				chance = 0;
00453			}
00454			if (A.IsA('GiantCrab') || A.IsA('BabyCrab'))
00455				return true;	// Disallow crabs, their big collision radius hangs up on tubestrikers
00456	
00457			if (bCanGrab && ActorAttachedTo(JointNamed('TongueD'))==None && chance < 0.3)
00458			{
00459				if (A.IsA('Weapon') && !A.IsA('GoblinAxePowerup'))
00460				{	// Grab Weapon
00461					if (A.Owner!=None && Pawn(A.Owner)!=None && 
00462						(A==Pawn(A.Owner).Weapon || A.AttachParent==None))
00463					{
00464						Pawn(A.Owner).DropWeapon();
00465						A.Velocity = vect(0,0,0);
00466						A.GotoState('Active'); // Put the weapon in a non-pickup state
00467						AttachActorToJoint(A, JointNamed('TongueD'));
00468						GotoState('Flinging');
00469					}
00470					return false;
00471				}
00472				else if (A.IsA('Shield'))
00473				{	// Grab Shield
00474					if (A.Owner!=None && Pawn(A.Owner)!=None)
00475					{
00476						Pawn(A.Owner).DropShield();
00477						A.Velocity = vect(0,0,0);
00478						A.GotoState('Idle'); // Put the shield in a non-pickup state
00479						AttachActorToJoint(A, JointNamed('TongueD'));
00480						GotoState('Flinging');
00481					}
00482					return false;
00483				}
00484				else if (Pawn(A)!=None && Tubestriker(A)==None && !A.bCarriedItem)
00485				{
00486					// Pickup non-tubestriker Pawns that aren't already attached to something
00487					A.Velocity = vect(0,0,0);
00488					AttachActorToJoint(A, JointNamed('TongueD'));
00489					GotoState('Flinging');
00490					return false;
00491				}
00492			}
00493			return true;
00494		}
00495		
00496		
00497	Begin:
00498		if(debugstates) slog(name@"Striking");
00499		PlayAttacking();
00500		FinishAnim();
00501		GotoState('WaitForRefire');
00502	}
00503	
00504	
00505	//============================================================
00506	//
00507	// Flinging
00508	//
00509	//============================================================
00510	State Flinging
00511	{
00512		ignores Bump, SeePlayer, HearNoise, EnemyAcquired;
00513		
00514		function BeginState()
00515		{
00516			BodyPartCollision(BODYPART_HEAD, true);
00517			BodyPartCollision(BODYPART_RARM1, true);
00518		}
00519		
00520		function AmbientSoundTimer()
00521		{
00522			PlayAmbientFightSound();
00523		}
00524	
00525		function EndState()
00526		{
00527			BodyPartCollision(BODYPART_HEAD, false);
00528			BodyPartCollision(BODYPART_RARM1, false);
00529		}
00530	
00531		function SoundNotify1()
00532		{
00533			PlaySound(FlailSound, SLOT_Interact,,,, 1.0 + FRand()*0.2-0.1);
00534		}
00535	
00536		// Disallow any damage from flinging actor
00537		function bool JointDamaged(int Damage, Pawn EventInstigator, vector HitLoc, vector Momentum, name DamageType, int joint)
00538		{
00539			if (EventInstigator != None && EventInstigator == ActorAttachedTo(JointNamed('TongueD')))
00540				return false;
00541	
00542			if (DamageType == 'thrownweaponblunt' || DamageType == 'thrownweaponsever' || DamageType == 'thrownweaponbluntsever')
00543			{
00544				if (EventInstigator != None &&
00545					ActorAttachedTo(JointNamed('TongueD')) != None &&
00546					EventInstigator == ActorAttachedTo(JointNamed('TongueD')).Owner )
00547					return false;	// Thrown weapon
00548			}
00549	
00550			FlingItem();	// Let go if damaged
00551	
00552			// Disallow other tubestrikers damaging me
00553			if (EventInstigator != None && EventInstigator.IsA('TubeStriker'))
00554				return false;
00555	
00556			return Super.JointDamaged(Damage, EventInstigator, HitLoc, Momentum, DamageType, joint);
00557		}
00558	
00559		// Notify to fling item
00560		function DoThrow()
00561		{
00562			if (bThrowOK)
00563			{
00564				FlingItem();
00565				bThrowOK = false;
00566				GotoState('Flinging', 'Thrown');
00567			}
00568		}
00569	
00570	Thrown:
00571		PlayAnim('Ready', 1.0, 0.2);
00572		FinishAnim();
00573		GotoState('WaitForRefire');
00574	
00575	Begin:
00576		if(debugstates) slog(name@"Flinging");
00577		bThrowOK = false;
00578		Sleep(0.2);		// Let suck back in a bit
00579		
00580		LoopAnim('whip', 1.0, 0.1);
00581		Sleep(4);
00582		bThrowOK = true;
00583	}
00584	
00585	
00586	//============================================================
00587	//
00588	// WaitForRefire
00589	//
00590	//============================================================
00591	State WaitForRefire
00592	{
00593		ignores SeePlayer, Bump, HearNoise, EnemyAcquired;
00594	
00595	Begin:
00596		if(debugstates) slog(name@"WaitForRefire");
00597		Sleep(TimeBetweenAttacks);
00598		GotoState('Alerted', 'Ready');
00599	}
00600	
00601	
00602	//============================================================
00603	//
00604	// Pain
00605	//
00606	//============================================================
00607	State Pain
00608	{
00609		ignores Bump, SeePlayer, HearNoise, EnemyAcquired;
00610	
00611		function BeginState()
00612		{
00613			BodyPartCollision(BODYPART_HEAD, true);
00614			BodyPartCollision(BODYPART_RARM1, true);
00615		}
00616		
00617		function EndState()
00618		{
00619			BodyPartCollision(BODYPART_HEAD, false);
00620			BodyPartCollision(BODYPART_RARM1, false);
00621		}
00622	
00623		function bool CanGotoPainState()
00624		{ // Do not allow the actor to enter the painstate when already in pain
00625			return(false);
00626		}
00627		
00628	Begin:
00629		if(debugstates) slog(name@"Pain");
00630		PlayAnim('pain', 1.0, 0.1);
00631		FinishAnim();
00632	
00633		GotoState('WaitForRefire');
00634	}
00635	
00636	
00637	//============================================================
00638	//
00639	// Dying (overridden from pawn)
00640	//
00641	//============================================================
00642	State Dying
00643	{
00644	ignores SeePlayer, EnemyNotVisible, HearNoise, KilledBy, Trigger, Bump, HitWall, HeadZoneChange, FootZoneChange, ZoneChange, Falling, WarnTarget, Died, LongFall, PainTimer, JointDamaged, Timer;
00645	
00646		function BeginState()
00647		{
00648			LookAt(None);
00649			StopLookingToward();
00650			BodyPartCollision(BODYPART_HEAD, false);
00651			BodyPartCollision(BODYPART_RARM1, false);
00652			BodyPartVisibility(BODYPART_RARM1, false);
00653		}
00654	
00655	Begin:
00656		if(debugstates) slog(name@"Dying");
00657		FlingItem();
00658	
00659		PlayAnim('Death', 1.0, 0.3);
00660	}
00661	
00662	
00663	
00664	simulated function Debug(canvas Canvas, int mode)
00665	{
00666		Super.Debug(Canvas, mode);
00667		Canvas.DrawText("Tube:");
00668		Canvas.CurY -= 8;
00669		Canvas.DrawText("  LookAngle.Yaw: " @ LookAngle.Yaw);
00670		Canvas.CurY -= 8;
00671		Canvas.DrawText("  Cos(LookAngle):" @ cos(LookAngle.Yaw*2.0*Pi/65535.0));
00672		Canvas.CurY -= 8;
00673		Canvas.DrawText("  PeriphVision:  " @ PeripheralVision);
00674		Canvas.CurY -= 8;
00675	}
00676	
00677	defaultproperties
00678	{
00679	     FlingVelocity=300.000000
00680	     FlailSound=Sound'CreaturesSnd.TubeStriker.tubeflail02'
00681	     FightOrFlight=1.000000
00682	     AcquireSound=Sound'CreaturesSnd.TubeStriker.tubebite05'
00683	     AmbientWaitSounds(0)=Sound'CreaturesSnd.TubeStriker.tubeamb01'
00684	     AmbientWaitSounds(1)=Sound'CreaturesSnd.TubeStriker.tubeamb05'
00685	     AmbientWaitSounds(2)=Sound'CreaturesSnd.TubeStriker.tubeamb03'
00686	     AmbientFightSounds(0)=Sound'CreaturesSnd.TubeStriker.tubeamb04'
00687	     AmbientFightSounds(1)=Sound'CreaturesSnd.TubeStriker.tubeattack02'
00688	     AmbientFightSounds(2)=Sound'CreaturesSnd.TubeStriker.tubeattack03'
00689	     StartWeapon=Class'RuneI.TubeStrikerTongue'
00690	     CarcassType=None
00691	     bAlignToFloor=True
00692	     MeleeRange=200.000000
00693	     GroundSpeed=0.000000
00694	     WaterSpeed=0.000000
00695	     AccelRate=0.000000
00696	     JumpZ=0.000000
00697	     MaxStepHeight=0.000000
00698	     AirControl=0.000000
00699	     ClassID=9
00700	     SightRadius=400.000000
00701	     PeripheralVision=-1.000000
00702	     Health=5
00703	     BodyPartHealth(0)=5
00704	     BodyPartHealth(3)=5
00705	     BodyPartHealth(5)=5
00706	     bGibbable=False
00707	     HitSound1=Sound'CreaturesSnd.TubeStriker.tubebite06'
00708	     HitSound2=Sound'CreaturesSnd.TubeStriker.tubebite06'
00709	     HitSound3=Sound'CreaturesSnd.TubeStriker.tubebite06'
00710	     Die=Sound'CreaturesSnd.TubeStriker.tubedeath01'
00711	     Die2=Sound'CreaturesSnd.TubeStriker.tubedeath01'
00712	     Die3=Sound'CreaturesSnd.TubeStriker.tubedeath01'
00713	     WeaponJoint=tonguee
00714	     bCanLook=True
00715	     MaxBodyAngle=(Yaw=0)
00716	     MaxHeadAngle=(Pitch=0,Yaw=32768)
00717	     bRotateTorso=False
00718	     bLookFocusCreature=True
00719	     AnimSequence=idleA
00720	     bMovable=False
00721	     TransientSoundRadius=1200.000000
00722	     CollisionRadius=23.000000
00723	     CollisionHeight=47.000000
00724	     bRotateToDesired=False
00725	     RotationRate=(Pitch=0,Yaw=0,Roll=0)
00726	     Skeletal=SkelModel'creatures.Striker'
00727	}

End Source Code