Jump to content
Alert23

Identify who activated a Trigger first

Recommended Posts

hi everyone,

im creating a race mission and i want to display a ranking by checking who activated/entered a trigger first (multiple repeatable triggers acting as checkpoints).

hopefully someone can help me with this.

  • Like 1

Share this post


Link to post
Share on other sites
51 minutes ago, Kalle M. said:

Try
thisList select 0

So this would select the first player/vehicle who activated the trigger..

Lets say i have 5 karts and i want to know who activated the trigger first,second,third,fourth and fifth how would i set the condition for this?

And how would i refer to the karts using thisList select 0 in a script?

Thanks for any help 😃

 

Share this post


Link to post
Share on other sites

in the editor or in a script?

 

probably easier just creating a simple script.  If its multiplayer, i'm not sure.  But single player.  Didn't add the distance check in there as it seemed redundant but you could do that yourself and use a simple if then statement or switch statement to do what you want.

 

_trigger = _this select 0;//name of trigger you're using
_array = _this select 1;//name of each object you are using in an array [1,2,3,4 etc..]
_distance = _this select 2;// distance between each object being checked


_winner = list _trigger select 0;//0 is the first index in the array
_losers = _array - [_winner];//remove winner from array 

if thats along the lines of what you're looking for
  • Like 1

Share this post


Link to post
Share on other sites

actually that needs refined a bit more

if(_winner in _array && _winner == list _trigger select 0) then {hint format ["%1 is the winner",_winner]};  I'm sure someone has a better way but thats what comes to my mind

 

  • Like 1

Share this post


Link to post
Share on other sites

Thanks for your effort, i'll try this later at home. Im trying to display a ranking for each driver i.e 1st - 5ft place and the race would have 6 laps.

But thank you so far i need to test what you wrote first when im at home again. 👍

Share this post


Link to post
Share on other sites

ah not sure how to go about the lap count tbh.  single player may be easy enough.  have the trigger set to fire repeatedly but not sure how to script it so that it parses the times of each driver on every lap.  thats a little complex and beyond my experience sorry man.  So only fire the script once the someone has triggered 6x and only when they are the first person to enter the area on the 6th activation.  yeah i'm lost in the sauce with this one sorry.

 

 

  • Like 1

Share this post


Link to post
Share on other sites
5 minutes ago, jakkob4682 said:

ah not sure how to go about the lap count tbh.  single player may be easy enough.  have the trigger set to fire repeatedly but not sure how to script it so that it parses the times of each driver on every lap.  thats a little complex and beyond my experience sorry man.  So only fire the script once the someone has triggered 6x and only when they are the first person to enter the area on the 6th activation.  yeah i'm lost in the sauce with this one sorry.

 

 

No worries i have already managed to solve the lap counting, only missing thing now is the ranking

Share this post


Link to post
Share on other sites

Triggers are tricky. They scan every half second or so I believe. So "select 0" isn't always the first one if it's close. Also the trigger will only trigger once (globally), and not reset until it's empty, making it a bit confusing and sometimes frustrating.

 

If it's a Race with no combat (keeping it simple), checking for Distance to be UNDER a set number to an invisible object in the middle of the road/track. If you want a higher quality, it will be a tad more complex. (on my phone so these are off the top of my head/quick)... You'd likely need to use both local and global variables (and publicVariable for MP).

 

Options to Explore :

https://community.bistudio.com/wiki/distance

https://community.bistudio.com/wiki/waitUntil

https://community.bistudio.com/wiki/publicVariable

  • Like 2

Share this post


Link to post
Share on other sites

@Alert23

Here's a SP example,

Spoiler

Call this from your starting line trigger,


[thisList select 0, 3] call you_fnc_raceTimer

paste this in init.sqf or the Attributes Init dialog,


you_fnc_raceTimer= 
{ params [["_caller", player], ["_laps", 3]]; 

	private	_currLap=_caller getVariable "you_lapNum";
	private _startTime= _caller getVariable "you_startTime";
	private _finTime= time - _startTime;
		_caller setVariable ["you_lapNum", _currLap + 1];

	if (_currLap==0) exitWith {systemChat "start race"; _caller setVariable ["you_startTime", time]; _caller setVariable ["you_lastTime", time];};

	if (_currLap !=0) exitWith {
		private _lastTime= _caller getVariable "you_lastTime";
			_caller setVariable ["you_lastTime", time];
		private _lapTime= time - _lastTime;
		systemChat format ["lap time %1, lap %2", _lapTime, _currLap];

		private	_bestTime= _caller getVariable "you_bestTime";

		if (_bestTime==0) then {
			_caller setVariable ["you_bestTime", _lapTime]
		}else{
			if (_lapTime < _bestTime) then {
				systemChat "new best lap";
				_caller setVariable ["you_bestTime", _lapTime];
				};
			};
		if (_currLap == _laps) then {
			systemChat format ["Race Finished! total time %1", _finTime];
			_caller setVariable ["you_finishTime", _finTime];
			_caller setVariable ["you_lapNum", 0];
			_caller setVariable ["you_startTime", 0];
			_caller setVariable ["you_lastTime", 0];
			you_rankARR pushBack _caller;
		};
	};
};

you_rankARR=[];

[]spawn {
	waitUntil {sleep 1; you_racer_1 getVariable "you_finishTime"!=0};
		private _you_winner =  you_rankARR select 0;
		private	_bestTime= _you_winner getVariable "you_finishTime";
		systemChat format ["%1 wins! total time %2", _you_winner, _bestTime];
};

and give your racer these vars (name you_racer_1)


this setVariable ["you_startTime", 0];
this setVariable ["you_finishTime", 0];
this setVariable ["you_lapNum", 0];
this setVariable ["you_bestTime", 0];

check out the attached mission for an example.


To convert to MP the command "time" would need to be replaced with "serverTime" and each racer would need the variables. Also, each racer must be added to the potential end criteria.

Check out the test file (drive link).

Have fun!
 

  • Like 2

Share this post


Link to post
Share on other sites

thank you everyone for you help and effort you put into this!

  • Like 1

Share this post


Link to post
Share on other sites

If there are 5 cars racing, they could finish in any order. There are 120 possibilities as to the finishing order.

Place 120 triggers on the map. Each trigger represents the 120 possible finishing order.

Each trigger has a hint, listing the finishing sequence of the 5 cars.

Each trigger can only be fired by one car. In other words, each car can fire 24 triggers.

 

As the first car crosses the finish, it fires a trigger which deletes all the triggers, with a hint saying that any of the other cars came first.

As the second car crosses the finish, it fires a trigger  which deletes all the triggers, with a hint saying that any of the other cars came second

As the third car crosses the finish, it fires a trigger  which deletes all the triggers, with a hint saying that any of the other cars came third

etc etc

Finally you are left with one trigger and the hint in the trigger lists the correct sequence that the cars finished. Presto!

 

PS:

If a car fails to finish there will be no result.  So you need more triggers at the finish. Those triggers are fired after a given time and only when a given car is not present.  This leads to another list of hints.

 

 

 

 

Share this post


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

Place 120 triggers

 

Just no.

 

1 hour ago, Joe98 said:

As the first car crosses the finish

 

If two cars cross within 0.5 seconds of each other, it is conceivable that they will both receive the same rank. 

 

Triggers are evaluated every 0.5 seconds. Filling your map up with triggers is not an optimal solution.

  • Like 2

Share this post


Link to post
Share on other sites

Sry guys for the missleading info i gave you, by ranking i dident mean the final ranking after race finish, i mean the ranking during the race, like displaying for each driver which place he actually is 

1stPlace

2ndPlace

3rdPlace

4thPlace

5thPlace

Like if a vehicle at 2ndPlace overtakes the vehicle at 1stPlace, it will display for vehicle2 that his ranking changed to 1stPlace, i think you understand me.

I already managed this by using 

nearestObjects but my code needs some improvements.

(I'll post the code later maybe some of you could help me with it)

 

Share this post


Link to post
Share on other sites
[] spawn {

	while {sleep 1;alive player} do {
	
	_nearestKart = nearestObjects [CheckPoint1, ["C_Kart_01_F"], 1000];    

	_1stRank = _nearestKart select 0;
	_2ndRank = _nearestKart select 1;
	_3rdRank = _nearestKart select 2;
	_4thRank = _nearestKart select 3;
	_5thRank = _nearestKart select 4;


	
if (vehicle player == _1stRank) then {
	1st = ["<img size='12' image='images\1stPlace.paa' shadow='0'/>",safeZoneX+0.7 * safezoneW,safeZoneY-0.05 * safezoneH,99999,0,0,220] spawn bis_fnc_dynamicText;};
	
if (vehicle player == _2ndRank) then {
	2nd = ["<img size='12' image='images\2ndPlace.paa' shadow='0'/>",safeZoneX+0.7 * safezoneW,safeZoneY-0.05 * safezoneH,99999,0,0,220] spawn bis_fnc_dynamicText;};	

if (vehicle player == _3rdRank) then {
	3rd = ["<img size='12' image='images\3rdPlace.paa' shadow='0'/>",safeZoneX+0.7 * safezoneW,safeZoneY-0.05 * safezoneH,99999,0,0,220] spawn bis_fnc_dynamicText;};	

if (vehicle player == _4thRank) then {
	4th = ["<img size='12' image='images\4thPlace.paa' shadow='0'/>",safeZoneX+0.7 * safezoneW,safeZoneY-0.05 * safezoneH,99999,0,0,220] spawn bis_fnc_dynamicText;};	

if (vehicle player == _5thRank) then {
	5th = ["<img size='12' image='images\5thPlace.paa' shadow='0'/>",safeZoneX+0.7 * safezoneW,safeZoneY-0.05 * safezoneH,99999,0,0,220] spawn bis_fnc_dynamicText;};
	};
};

this is my code which runs fine but i have encountered a problem my race track isent a straight track its a curvy race track so i need to add several CheckPoints, now how would i make it so that if the vehicle at 1stPlace gets to the first checkpoint that the script switches to the second checkpoint and searches from there on for the nearestObjects i.e nearest kart.

this is the track:

Spoiler

 

PxCI25Vz.png

 

 

  • Like 1

Share this post


Link to post
Share on other sites
On 9/17/2020 at 6:02 PM, wogz187 said:

@Alert23,

Here's a decent post showing the logic of deciding who's in first. The previous post looks like you're on the right track (racing pun).

Have fun!

Thanks for your help wogz187 but couldent solve this problem yet.

 

Share this post


Link to post
Share on other sites

@Alert23,
It's a tough one for sure. The basic idea-- if I understand it correctly-- is that we need to simplify the concept of a race so the system can understand. Essentially reduce the logic to "who has made the longest line". Using sectors to create the line ensures you can't get into first simply by driving in circles. Triggers will not work for designing sectors both because of timing and performance considerations (not to mention the design time of networking a ton of triggers together).

There needs to be an "onEachFrame" type EH running on each racer to create their "racing line" through the sectors and something to check which line is currently longest.

Maybe one of the resident super-coders can take a crack at it.

Have fun!

  • Thanks 1

Share this post


Link to post
Share on other sites

 

8 hours ago, pierremgi said:

Just as reminder, you can make a trigger (scripted) on each framed. See setTriggerInterval.

Yes i knew this command but wont it work for editor placed triggers?

Share this post


Link to post
Share on other sites
45 minutes ago, Alert23 said:

 

Yes i knew this command but wont it work for editor placed triggers?

There's nothing on the BIki that says you cannot change the interval a trigger is checked for editor placed triggers. So, most probably, if you have a way to access the trigger you are interested in, you will be able to change how often it is checked.

 

One thing to note though is that you cannot change the interval with any other way but through a script command.

 

Please note that I haven't tested what I am providing here. It is just a compilation of information found online.

Edited by ZaellixA
  • Like 1

Share this post


Link to post
Share on other sites

Yes that works.

In editor, just place a trigger like BLUFOR PRESENT.

In condition field:  hint str diag_tickTime; this

On act. field, what you want. It's useless for demo.

Run the preview (with one player)  The diag_tickTime is shown every 0.5 sec. Normal

 

Now, name this trigger trg1 and add a code (in player init field for example):   trg1 setTriggerInterval 0;

Run the preview. Bingo!

 

  • Like 2

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

×