Jump to content
🛡️FORUMS ARE IN READ-ONLY MODE Read more... ×
twistking

checking if ANY player left zone

Recommended Posts

Hello,
is there a nice and simple way for a trigger to check if any player (or any character of a side) has left a trigger area?
Use would be to check if players in a MP scenario begin to leave the staging area...
Of course it can be done by creating multiple "is present" trigger areas around the spawn site, but there must be a better way, no?

Share this post


Link to post
Share on other sites

Not tested but if you leave activation type as "none" and put this code in the condition it will fire when any blufor player is outside the trigger.

{side _x == blufor && !(_x inArea thisTrigger)} count allPlayers > 0

 

  • Thanks 1

Share this post


Link to post
Share on other sites
15 minutes ago, _foley said:

Not tested but if you leave activation type as "none" and put this code in the condition it will fire when any blufor player is outside the trigger.


{side _x == blufor && !(_x inArea thisTrigger)} count allPlayers > 0

 

Did a quick test in and it works... in SP at least. Thanks a lot!

Can you quickly help me understand how it works?!
I understand all the commands, but i'm not sure how the syntax with the {} actually works. Can you give me the command that would simply count blufor client/players outside a trigger zone without making a condition from it? I think i can then understand how the condition works.

Share this post


Link to post
Share on other sites

It may be better to use findIf for this statement as you don't have to wait for allPlayers to be checked. As soon as one is found that has left, the command exits with the index found OR -1 if none are found.

allPlayers select{ side _x isEqualTo west } findIf{ !( _x inArea thisTrigger ) } > -1

Get an array of all west players...

allPlayers select{ side _x isEqualTo west }

check to find the first that is not in the trigger...

... findIf{ !( _x inArea thisTrigger ) } ...

If an index was found

...  > -1

 

2 hours ago, twistking said:

i'm not sure how the syntax with the {} actually works. Can you give me the command that would simply count blufor client/players outside a trigger zone without making a condition from it?

Just remove the... > 0

_numPlayers = { side _x isEqualTo west && { !( _x inArea thisTrigger ) } }count allPlayers
//Count the number of clients( allPlayers ) that code( {} ) is true for
{ /* for each player(_x) */ } count allplayers
  
//So
{ /* is west and not in trigger */ } count allPlayers
  
//Is
{ side _x isEqualTo west && { !( _x inArea thisTrigger ) } } count allPlayers

 

  • Thanks 1

Share this post


Link to post
Share on other sites

@Larrow thanks a lot. i appreciate that you put in the extra explanation of how it works. i probably would have had trouble otherwise 😉

regarding the performance of "count" vs "find": i think i understand the theoretical difference, but since one of the recent patches we've got this setting in the trigger that let's you specify how often the condition is checked. for conditions that are not time sensitiv i usually just put the value to a few seconds... am i right in my assumption that this will result in that code only being run every few seconds? performance impact should be irrelevant then, no? but it's of course always best to do it in the most efficient way regardless...

Share this post


Link to post
Share on other sites

@twistking I feel you, the SQF syntax is indeed confusing. You can break it down like that:

 

This returns the count of all players

count allPlayers

 

This returns true/false depending on if count of all players is greater than 0

(count allPlayers) > 0

 

This is like above but it counts only players that meet the criteria specified in {}. It's something that count allows you to do (alternative syntax).

({side _x == blufor && !(_x inArea thisTrigger)} count allPlayers) > 0

 

It's a valuable tip from @Larrow though in this case it's possible you won't notice a difference. If however you intend to run this very frequently (i.e. on each frame), you expect a large player count and you need to continue running this check even after a player left the staging area - then you would need to worry about optimization.

 

It's a trade-off. On one side: your code is a few microseconds faster. On the other side: you need to spend more time on writing (and reading!) the code. Don't underestimate the reading part. If you come back to this script a few weeks or months later to make some changes or fix some bugs, it will be so convenient to skim over this line and think "ok, it checks if player count is > 0" and if you need more details you read the bit in curly brackets to find out it is counting players that meet such and such criteria. Whereas when you come across the optimized version, you probably can't tell immediately what it does, it requires you to spend a few seconds to read it start to finish to get even a general idea of what it does. It's no big deal in a small script but it adds up once you need to sift through hundreds of lines. Also your mileage may vary - someone with years of experience may be equally comfortable with the findIf ... > -1 version because it's used so frequently.

 

Share this post


Link to post
Share on other sites
On 11/16/2022 at 5:05 PM, _foley said:

Whereas when you come across the optimized version, you probably can't tell immediately what it does, it requires you to spend a few seconds to read it start to finish to get even a general idea of what it does.

Don't agree, if anything the findIf is easier to read as you can read it naturally from left to right. Whereas the count version you need to look at the end first to see what it is counting before reading the filter. As for the > -1 all you need to remember is that for findIf -1 means nothing found.

 

Also, add lazy evaluation to your inArea check( as shown in my count example ). Otherwise, every single player no matter their side will have their position against the trigger checked.

Checking distance/area can be pretty expensive and unnecessary in this case against allPlayers and is only exacerbated by the use of count.

 

On 11/15/2022 at 8:50 PM, twistking said:

performance impact should be irrelevant then, no?

Performance is never really irrelevant, more a balancing act. What would you prefer, the command to finish as soon as it finds a player not in the trigger, or to continue counting everyone until it makes a decision if someone is outside the trigger? I know which I'd prefer no matter if the player count is 5 or 50.

 

Whatever you choose to use both examples will achieve your end goal.

  • Thanks 1

Share this post


Link to post
Share on other sites

anyPlayer present  (preset condition)
west countSide thisList == 0

 

 

  • Thanks 1

Share this post


Link to post
Share on other sites

×