Engine
Class Trigger

source: e:\games\UnrealTournament\Engine\Classes\Trigger.uc
Core.Object
   |
   +--Engine.Actor
      |
      +--Engine.Triggers
         |
         +--Engine.Trigger
Direct Known Subclasses:TeamTrigger, TimedTrigger, ZoneTrigger

class Trigger
extends Engine.Triggers

//============================================================================= // Trigger: senses things happening in its proximity and generates // sends Trigger/UnTrigger to actors whose names match 'EventName'. //=============================================================================
Variables
 class ClassProximityType
 float DamageThreshold
           minimum damage to trigger if TT_Shoot
 enum ETriggerType
 string Message
 float ReTriggerDelay
           minimum time before trigger can be triggered again
 float RepeatTriggerTime
           if > 0, repeat trigger message at this interval is still touching other
 Actor TriggerActor2
           minimum damage to trigger if TT_Shoot
 bool bInitiallyActive
 bool bTriggerOnceOnly


Function Summary
 void CheckTouchList()
     
// when trigger gets turned on, check its touch list
 void FindTriggerActor()
 bool IsRelevant(Actor Other)
     
//
// See whether the other actor is relevant to this trigger.
//
 void PostBeginPlay()
     
//=============================================================================
// AI related functions
 Actor SpecialHandling(Pawn Other)
 void TakeDamage(int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, name damageType)
 void Timer()
 void Touch(Actor Other)
     
//
// Called when something touches the trigger.
//
 void Trigger(Actor Other, Pawn EventInstigator)
     
// Other trigger turns this off.
 void Trigger(Actor Other, Pawn EventInstigator)
     
// Other trigger turns this off.
 void Trigger(Actor Other, Pawn EventInstigator)
     
// Other trigger turns this off.
 void UnTouch(Actor Other)
     
//
// When something untouches the trigger.
//



Source Code


00001	//=============================================================================
00002	// Trigger: senses things happening in its proximity and generates 
00003	// sends Trigger/UnTrigger to actors whose names match 'EventName'.
00004	//=============================================================================
00005	class Trigger extends Triggers
00006		native;
00007	
00008	#exec Texture Import File=Textures\Trigger.pcx Name=S_Trigger Mips=Off Flags=2
00009	
00010	//-----------------------------------------------------------------------------
00011	// Trigger variables.
00012	
00013	// Trigger type.
00014	var() enum ETriggerType
00015	{
00016		TT_PlayerProximity,	// Trigger is activated by player proximity.
00017		TT_PawnProximity,	// Trigger is activated by any pawn's proximity
00018		TT_ClassProximity,	// Trigger is activated by actor of that class only
00019		TT_AnyProximity,    // Trigger is activated by any actor in proximity.
00020		TT_Shoot,		    // Trigger is activated by player shooting it.
00021	} TriggerType;
00022	
00023	// Human readable triggering message.
00024	var() localized string Message;
00025	
00026	// Only trigger once and then go dormant.
00027	var() bool bTriggerOnceOnly;
00028	
00029	// For triggers that are activated/deactivated by other triggers.
00030	var() bool bInitiallyActive;
00031	
00032	var() class<actor> ClassProximityType;
00033	
00034	var() float	RepeatTriggerTime; //if > 0, repeat trigger message at this interval is still touching other
00035	var() float ReTriggerDelay; //minimum time before trigger can be triggered again
00036	var	  float TriggerTime;
00037	var() float DamageThreshold; //minimum damage to trigger if TT_Shoot
00038	
00039	// AI vars
00040	var	actor TriggerActor;	// actor that triggers this trigger
00041	var actor TriggerActor2;
00042	
00043	//=============================================================================
00044	// AI related functions
00045	
00046	function PostBeginPlay()
00047	{
00048		if ( !bInitiallyActive )
00049			FindTriggerActor();
00050		if ( TriggerType == TT_Shoot )
00051		{
00052			bHidden = false;
00053			bProjTarget = true;
00054			DrawType = DT_None;
00055		}
00056			
00057		Super.PostBeginPlay();
00058	}
00059	
00060	function FindTriggerActor()
00061	{
00062		local Actor A;
00063	
00064		TriggerActor = None;
00065		TriggerActor2 = None;
00066		ForEach AllActors(class 'Actor', A)
00067			if ( A.Event == Tag)
00068			{
00069				if ( Counter(A) != None )
00070					return; //FIXME - handle counters
00071				if (TriggerActor == None)
00072					TriggerActor = A;
00073				else
00074				{
00075					TriggerActor2 = A;
00076					return;
00077				}
00078			}
00079	}
00080	
00081	function Actor SpecialHandling(Pawn Other)
00082	{
00083		local int i;
00084	
00085		if ( bTriggerOnceOnly && !bCollideActors )
00086			return None;
00087	
00088		if ( (TriggerType == TT_PlayerProximity) && !Other.bIsPlayer )
00089			return None;
00090	
00091		if ( !bInitiallyActive )
00092		{
00093			if ( TriggerActor == None )
00094				FindTriggerActor();
00095			if ( TriggerActor == None )
00096				return None;
00097			if ( (TriggerActor2 != None) 
00098				&& (VSize(TriggerActor2.Location - Other.Location) < VSize(TriggerActor.Location - Other.Location)) )
00099				return TriggerActor2;
00100			else
00101				return TriggerActor;
00102		}
00103	
00104		// is this a shootable trigger?
00105		if ( TriggerType == TT_Shoot )
00106		{
00107			if ( !Other.bCanDoSpecial || (Other.Weapon == None) )
00108				return None;
00109	
00110			Other.Target = self;
00111			Other.bShootSpecial = true;
00112			Other.FireWeapon();
00113			Other.bFire = 0;
00114			Other.bAltFire = 0;
00115			return Other;
00116		}
00117	
00118		// can other trigger it right away?
00119		if ( IsRelevant(Other) )
00120		{
00121			for (i=0;i<4;i++)
00122				if (Touching[i] == Other)
00123					Touch(Other);
00124			return self;
00125		}
00126	
00127		return self;
00128	}
00129	
00130	// when trigger gets turned on, check its touch list
00131	
00132	function CheckTouchList()
00133	{
00134		local int i;
00135	
00136		for (i=0;i<4;i++)
00137			if ( Touching[i] != None )
00138				Touch(Touching[i]);
00139	}
00140	
00141	//=============================================================================
00142	// Trigger states.
00143	
00144	// Trigger is always active.
00145	state() NormalTrigger
00146	{
00147	}
00148	
00149	// Other trigger toggles this trigger's activity.
00150	state() OtherTriggerToggles
00151	{
00152		function Trigger( actor Other, pawn EventInstigator )
00153		{
00154			bInitiallyActive = !bInitiallyActive;
00155			if ( bInitiallyActive )
00156				CheckTouchList();
00157		}
00158	}
00159	
00160	// Other trigger turns this on.
00161	state() OtherTriggerTurnsOn
00162	{
00163		function Trigger( actor Other, pawn EventInstigator )
00164		{
00165			local bool bWasActive;
00166	
00167			bWasActive = bInitiallyActive;
00168			bInitiallyActive = true;
00169			if ( !bWasActive )
00170				CheckTouchList();
00171		}
00172	}
00173	
00174	// Other trigger turns this off.
00175	state() OtherTriggerTurnsOff
00176	{
00177		function Trigger( actor Other, pawn EventInstigator )
00178		{
00179			bInitiallyActive = false;
00180		}
00181	}
00182	
00183	//=============================================================================
00184	// Trigger logic.
00185	
00186	//
00187	// See whether the other actor is relevant to this trigger.
00188	//
00189	function bool IsRelevant( actor Other )
00190	{
00191		if( !bInitiallyActive )
00192			return false;
00193		switch( TriggerType )
00194		{
00195			case TT_PlayerProximity:
00196				return Pawn(Other)!=None && Pawn(Other).bIsPlayer;
00197			case TT_PawnProximity:
00198				return Pawn(Other)!=None && ( Pawn(Other).Intelligence > BRAINS_None );
00199			case TT_ClassProximity:
00200				return ClassIsChildOf(Other.Class, ClassProximityType);
00201			case TT_AnyProximity:
00202				return true;
00203			case TT_Shoot:
00204				return ( (Projectile(Other) != None) && (Projectile(Other).Damage >= DamageThreshold) );
00205		}
00206	}
00207	//
00208	// Called when something touches the trigger.
00209	//
00210	function Touch( actor Other )
00211	{
00212		local actor A;
00213		if( IsRelevant( Other ) )
00214		{
00215			if ( ReTriggerDelay > 0 )
00216			{
00217				if ( Level.TimeSeconds - TriggerTime < ReTriggerDelay )
00218					return;
00219				TriggerTime = Level.TimeSeconds;
00220			}
00221			// Broadcast the Trigger message to all matching actors.
00222			if( Event != '' )
00223				foreach AllActors( class 'Actor', A, Event )
00224					A.Trigger( Other, Other.Instigator );
00225	
00226			if ( Other.IsA('Pawn') && (Pawn(Other).SpecialGoal == self) )
00227				Pawn(Other).SpecialGoal = None;
00228					
00229			if( Message != "" )
00230				// Send a string message to the toucher.
00231				Other.Instigator.ClientMessage( Message );
00232	
00233			if( bTriggerOnceOnly )
00234				// Ignore future touches.
00235				SetCollision(False);
00236			else if ( RepeatTriggerTime > 0 )
00237				SetTimer(RepeatTriggerTime, false);
00238		}
00239	}
00240	
00241	function Timer()
00242	{
00243		local bool bKeepTiming;
00244		local int i;
00245	
00246		bKeepTiming = false;
00247	
00248		for (i=0;i<4;i++)
00249			if ( (Touching[i] != None) && IsRelevant(Touching[i]) )
00250			{
00251				bKeepTiming = true;
00252				Touch(Touching[i]);
00253			}
00254	
00255		if ( bKeepTiming )
00256			SetTimer(RepeatTriggerTime, false);
00257	}
00258	
00259	function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, 
00260							Vector momentum, name damageType)
00261	{
00262		local actor A;
00263	
00264		if ( bInitiallyActive && (TriggerType == TT_Shoot) && (Damage >= DamageThreshold) && (instigatedBy != None) )
00265		{
00266			if ( ReTriggerDelay > 0 )
00267			{
00268				if ( Level.TimeSeconds - TriggerTime < ReTriggerDelay )
00269					return;
00270				TriggerTime = Level.TimeSeconds;
00271			}
00272			// Broadcast the Trigger message to all matching actors.
00273			if( Event != '' )
00274				foreach AllActors( class 'Actor', A, Event )
00275					A.Trigger( instigatedBy, instigatedBy );
00276	
00277			if( Message != "" )
00278				// Send a string message to the toucher.
00279				instigatedBy.Instigator.ClientMessage( Message );
00280	
00281			if( bTriggerOnceOnly )
00282				// Ignore future touches.
00283				SetCollision(False);
00284		}
00285	}
00286	
00287	//
00288	// When something untouches the trigger.
00289	//
00290	function UnTouch( actor Other )
00291	{
00292		local actor A;
00293		if( IsRelevant( Other ) )
00294		{
00295			// Untrigger all matching actors.
00296			if( Event != '' )
00297				foreach AllActors( class 'Actor', A, Event )
00298					A.UnTrigger( Other, Other.Instigator );
00299		}
00300	}
00301	
00302	defaultproperties
00303	{
00304	     bInitiallyActive=True
00305	     InitialState=NormalTrigger
00306	     Texture=Texture'Engine.S_Trigger'
00307	}

End Source Code