logo
Main

Forums

Downloads

Unreal-Netiquette

Donate for Oldunreal:
Donate

borderline

Links to our wiki:
Wiki

Walkthrough

Links

Tutorials

Unreal Reference

Usermaps

borderline

Contact us:
Submit News
Page Index Toggle Pages: 1 Send TopicPrint
Normal Topic Issue #70. Engine.Trigger's bTriggerOnceOnly doesn't prevent multiple triggering (Read 46 times)
Masterkent
Developer Team
Offline



Posts: 1337
Location: Russia
Joined: Apr 5th, 2013
Gender: Male
Issue #70. Engine.Trigger's bTriggerOnceOnly doesn't prevent multiple triggering
Apr 26th, 2019 at 9:28am
Print Post  
In

Code
Select All
function Touch( actor Other )
{
	if ( IsRelevant( Other ) )
	{
		if ( ReTriggerDelay > 0 )
		{
			if ( Level.TimeSeconds - TriggerTime < ReTriggerDelay )
				return;
			TriggerTime = Level.TimeSeconds;
		}
		// Broadcast the Trigger message to all matching actors.
		TriggerEvent(Event,Other,Other.Instigator);

		if ( Other.IsA('Pawn') && (Pawn(Other).SpecialGoal == self) )
			Pawn(Other).SpecialGoal = None;

		if ( Len(Message)>0 )
			// Send a string message to the toucher.
			Other.Instigator.ClientMessage( Message );

		if ( bTriggerOnceOnly )
			// Ignore future touches.
			SetCollision(False);
		else if ( RepeatTriggerTime > 0 )
			SetTimer(RepeatTriggerTime, false);
	}
} 


and

Code
Select All
function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation,
					 Vector momentum, name damageType)
{
	if ( bInitiallyActive && (TriggerType == TT_Shoot) && (Damage >= DamageThreshold) && (instigatedBy != None) )
	{
		if ( ReTriggerDelay > 0 )
		{
			if ( Level.TimeSeconds - TriggerTime < ReTriggerDelay )
				return;
			TriggerTime = Level.TimeSeconds;
		}
		// Broadcast the Trigger message to all matching actors.
		TriggerEvent(Event,instigatedBy,instigatedBy);

		if ( Len(Message)>0 && instigatedBy.Instigator!=None )
			// Send a string message to the toucher.
			instigatedBy.Instigator.ClientMessage( Message );

		if ( bTriggerOnceOnly )
			// Ignore future touches.
			SetCollision(False);
	}
} 


disabling the collision doesn't actually prevent further calls to Touch or TakeDamage. For example, when a damaging projectile touches a TT_Shoot trigger, we may have a call to TakeDamage followed by a call to Touch. Additionally, some projectiles (e.g. Botpack.PBolt) may invoke Trigger's TakeDamage multiple times. In such cases, TriggerEvent may be called more than once and then actors which handle the given event may not work properly if they expect the event issued only once. For example, shooting Jones-06-Vandora.Trigger32 with a PlasmaRifle may trigger Mover106 twice. Since it's a TriggerToggle-state Mover, the second triggering returns it back to the initial position right after opening, and since the trigger cannot activate this mover again (due to enabled bTriggerOnceOnly), the corresponding passage becomes permanently blocked:

https://www.youtube.com/watch?v=bXgyjqKpSbY


Suggested resolution: modify Trigger's Touch and TakeDamage as indicated below:

Code
Select All
function Touch( actor Other )
{
-	if ( IsRelevant( Other ) )
+	if ( bCollideActors && IsRelevant( Other ) )
	{
		if ( ReTriggerDelay > 0 )
		{
			if ( Level.TimeSeconds - TriggerTime < ReTriggerDelay )
				return;
			TriggerTime = Level.TimeSeconds;
		}
		// Broadcast the Trigger message to all matching actors.
		TriggerEvent(Event,Other,Other.Instigator);

		if ( Other.IsA('Pawn') && (Pawn(Other).SpecialGoal == self) )
			Pawn(Other).SpecialGoal = None;

		if ( Len(Message)>0 )
			// Send a string message to the toucher.
			Other.Instigator.ClientMessage( Message );

		if ( bTriggerOnceOnly )
			// Ignore future touches.
			SetCollision(False);
		else if ( RepeatTriggerTime > 0 )
			SetTimer(RepeatTriggerTime, false);
	}
} 


and

Code
Select All
function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation,
					 Vector momentum, name damageType)
{
-	if ( bInitiallyActive && (TriggerType == TT_Shoot) && (Damage >= DamageThreshold) && (instigatedBy != None) )
+	if ( bCollideActors && bInitiallyActive && (TriggerType == TT_Shoot) && (Damage >= DamageThreshold) && (instigatedBy != None) )
	{
		if ( ReTriggerDelay > 0 )
		{
			if ( Level.TimeSeconds - TriggerTime < ReTriggerDelay )
				return;
			TriggerTime = Level.TimeSeconds;
		}
		// Broadcast the Trigger message to all matching actors.
		TriggerEvent(Event,instigatedBy,instigatedBy);

		if ( Len(Message)>0 && instigatedBy.Instigator!=None )
			// Send a string message to the toucher.
			instigatedBy.Instigator.ClientMessage( Message );

		if ( bTriggerOnceOnly )
			// Ignore future touches.
			SetCollision(False);
	}
} 

  
Back to top
 
IP Logged
 
Page Index Toggle Pages: 1
Send TopicPrint
Bookmarks: del.icio.us Digg Facebook Google Google+ Linked in reddit StumbleUpon Twitter Yahoo