Jump to content

Recommended Posts

Hi, I'm currently trying to create a trigger that will play sound for locally for one specific player who will enter it. This is being made for a multiplayer mission.

My current trigger:

[]spawn {
while {true} do {
 
if (Y inArea t1) then {
playSound "geiger"; uiSleep 1.6;
};
};
};

The trigger activation is set to a custom condition.

(Y inArea t1)


My player is "Y", the trigger is "T1" and the sound which I'm looping is "geiger". Help.

Share this post


Link to post
Share on other sites
30 minutes ago, dreadedentity said:

Is something not working?

Yes, when Y enters the trigger zone, the sound can be heard by other players.

Share this post


Link to post
Share on other sites

Probably running on all clients I assume? Where is it being executed?

 

Considering that, try this:

if (player == Y) then {
  []spawn {
    while {true} do {
      if (Y inArea t1) then {
      	playSound "geiger"; uiSleep 1.6;
      };
    };
  };
};

 

Share this post


Link to post
Share on other sites

Wait, I'm confused. You have the condition Y inArea t1 in the trigger, but you are also checking that condition in an external script loop?

[]spawn {
while {true} do {
 
if (Y inArea t1) then {
playSound "geiger"; uiSleep 1.6;
};
};
};

Depending on where that is running (but why in the first place?) it will execute that code wherever it is told, which might be everywhere.

 

You already have the trigger with the condition in it, just put your playSound in the On Activation field.

Share this post


Link to post
Share on other sites
23 minutes ago, beno_83au said:

Probably running on all clients I assume? Where is it being executed? 

 

Considering that, try this:


if (player == Y) then {
  []spawn {
    while {true} do {
      if (Y inArea t1) then {
      	playSound "geiger"; uiSleep 1.6;
      };
    };
  };
};

 

Thanks, it does seem to be working however I can't really test as I am doing this in singleplayer. This line is being executed in the "on activation" section of the trigger. It is set to repeatable and it is not server only.

Share this post


Link to post
Share on other sites
14 minutes ago, Harzach said:

Wait, I'm confused. You have the condition Y inArea t1 in the trigger, but you are also checking that condition in an external script loop? 

The idea is that the trigger activates from the presence of Y, and the second line being executed in the "on activation" section, will continue to loop as long as Y is still present.

Share this post


Link to post
Share on other sites
1 hour ago, Harzach said:

Depending on where that is running (but why in the first place?) it will execute that code wherever it is told, which might be everywhere.

 

You already have the trigger with the condition in it, just put your playSound in the On Activation field. 

For the reasoning, it's a recurring sound, it's a tick of a Geiger counter belonging to one of the players when they near a "radioactive" object. How do I change if it activates locally or globally?

 

Share this post


Link to post
Share on other sites

Check locality:

 

anyPlayer present

condition : Y in thisList && local Y

 On activation:

[] spawn {
  while {triggerActivated thisTrigger && local Y} do {
    playSound "geiger";
    uiSleep 1.6;
  };
};

Or

script an effect local trigger (makeGlobal set to false, you can't do that in editor)

  • Like 2

Share this post


Link to post
Share on other sites
6 hours ago, pierremgi said:

Check locality:

 

anyPlayer present

condition : Y in thisList && local Y

 On activation:


[] spawn {
  while {triggerActivated thisTrigger && local Y} do {
    playSound "geiger";
    uiSleep 1.6;
  };
};

Or

script an effect local trigger (makeGlobal set to false, you can't do that in editor)

Seems to be working fine, thanks for the help guys.

Share this post


Link to post
Share on other sites

Hi, I'm making this now for anyone in future looking for something similar.

Here's my trigger:

Condition:
(SL inArea t1);
On act: 
if (player == SL) then { 
  []spawn { 
    while {true} do { 
      if (SL inArea t1) then { 
       SL say3D "g"; uiSleep 2; 
      }; 
    }; 
  }; 
};

Set the trigger to repeatable and the type/activation to none.

What does this do? When the player "SL" enters the trigger radius, they will begin to hear the tick of the geiger counter, which only stops when they leave. Only they can hear this sound. The only flaw is that the uisleep must match up with the exact length of the sound effect, which is two seconds in this case, if not the sound will play even after the player exits the trigger. This is also (unsurprisingly) a drain on performance if you place too many of these triggers.

Share this post


Link to post
Share on other sites

Don't multiply endless loops!

 

Repeatable trigger : anyplayer Present

condition:

SL in thisList && isNil "tick"

on act:

tick = TRUE; SL say3D "g";

on deact:

tick = NIL

 

and...timer type timeout set for 2 sec in min mid max.

Nothing more

 

  • Like 3

Share this post


Link to post
Share on other sites

To add to Pierre's reply, the problem is that you are spawning a code block that runs "forever":

while {true} do { 

that further evaluates true when the player is inside the trigger area:

if (SL inArea t1) then { 

But every time the player re-enters the trigger, a new code block is also spawned.

 

5 hours ago, bendingbanana101 said:

This is also (unsurprisingly) a drain on performance

 

Indeed!

  • Like 2

Share this post


Link to post
Share on other sites
On 8/4/2022 at 10:01 AM, bendingbanana101 said:

The only flaw is that the uisleep must match up with the exact length of the sound effect,

Not if you check that source is null. Available since A3 v2.00 see return values on playSound/say3D wiki pages.

 

On 8/4/2022 at 10:01 AM, bendingbanana101 said:

This is also (unsurprisingly) a drain on performance if you place too many of these triggers.

You only ever need one trigger which you reassign on each client only to activate for them. All trigger commands are LE (local effect).

 

Activation: None
Condition :

!hasInterface || ( { getClientStateNumber >= 10 && { !isNil "SL" && !isNull player }} )

Wait for the briefing to have been read, SL assigned and the player to be not null. If there is no interface (server, headless client) then it proceeds to disable the trigger.

 

Repeatable: true
ServerOnly: false

On Activation:

if ( hasInterface && { SL isEqualTo player } ) then {
	thisTrigger triggerAttachVehicle player;
	thisTrigger setTriggerActivation[ "VEHICLE", "PRESENT", true ];
	thisTrigger setTriggerStatements[ "this", "
		thisTrigger spawn {
			params[ '_trigger', '_source' ]
			while ( triggerActivated _trigger ) {
				_source = playSound 'geiger';
				waitUntil{ !triggerActivated _trigger || isNull _source };
			};
			if ( !isNull _source ) then {
				deleteVehicle _source;
			};
		};
	",
	"" ];
}else{
	thisTrigger enableSimulation false;
};

Reassign trigger only to activate for the local client. Or disable the trigger on instances with no interface.

 

Or you can omit references to SL (or replace it with trait/setVariable/has item) and it will work for any player (saves having a trigger for each player) ie.

Spoiler

Condition:


!hasInterface || ( { getClientStateNumber >= 10 && { !isNull player }} ) 

On Activation:


if ( hasInterface && { ( "ChemicalDetector_01_watch_F" in assignedItems player ) } ) then {
	thisTrigger triggerAttachVehicle player;
	thisTrigger setTriggerActivation[ "VEHICLE", "PRESENT", true ];
	thisTrigger setTriggerStatements[ "this", "
		thisTrigger spawn {
			params[ '_trigger', '_source' ]
			while ( triggerActivated _trigger && 'ChemicalDetector_01_watch_F' in assignedItems player ) {
				_source = playSound 'geiger';
				waitUntil{ !triggerActivated _trigger || !( 'ChemicalDetector_01_watch_F' in assignedItems player ) || isNull _source };
			};
			if ( !isNull _source ) then {
				deleteVehicle _source;
			};
		};
	", "" ];
} else {
	thisTrigger enableSimulation false;
	if ( hasInterface ) then {
		player setVariable[ "geigerTrig", thisTrigger ];
		player addEventHandler[ "Take", {
			params[ "_unit", "_container", "_item" ];
			if ( _item isEqualTo "ChemicalDetector_01_watch_F" ) then {
				player getVariable "geigerTrig" enableSimulation ( "ChemicalDetector_01_watch_F" in assignedItems player );
			};
		}];
		player addEventHandler[ "Put", {
			params[ "_unit", "_container", "_item" ];
			if ( _item isEqualTo "ChemicalDetector_01_watch_F" ) then {
				player getVariable "geigerTrig" enableSimulation ( "ChemicalDetector_01_watch_F" in assignedItems player );
			};
		}];
	};
};

The trigger will only activate for the local client if they have a Chemical Detector (Contact DLC).

 

Think that is all correct, untested, but I have reassigned triggers locally like this many times in the past.

  • Like 1

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×