Jump to content
Robustcolor

checkVisibility + Sort Nearest each unit

Recommended Posts

Hi, i'm trying to use the checkVisibility command to find out if any player present in the specific area can't see the location/object. The code below work but not as intended.

if (allPlayers findIf {
(_x inArea [_marker,550,550,0,false]) && 
([objectParent _x, "VIEW"] checkVisibility [eyePos _x, (AGLToASL _marker) vectorAdd [0,0,1.5]] == 0)
}!=-1) then { 

"x don't see the location" remoteExec ["hint"];

};

Seems to check only one player and not every player in the area? I want the code to execute when none of the players in the area can't see the location.

Share this post


Link to post
Share on other sites

Your findif searches for the first player in the array which is in the area and does not see the object. At this point findif returns a value greater -1.

 

You should search for the first player which sees it and show ur hint if the return value is -1

 

Also for performance reasons u should not use allPlayers but

(allPlayers select {_x inArea ...})

 

if ( (allPlayers select { _x inArea [_marker,550,550,0,false] }) findIf {
[objectParent _x, "VIEW"] checkVisibility [eyePos _x, (AGLToASL _marker) vectorAdd [0,0,1.5]] > 0
} isEqualTo -1) then { 

"x don't see the location" remoteExec ["hint"];

};

not tested

  • Like 2

Share this post


Link to post
Share on other sites
9 hours ago, sarogahtyp said:

Your findif searches for the first player in the array which is in the area and does not see the object. At this point findif returns a value greater -1.

 

You should search for the first player which sees it and show ur hint if the return value is -1

 

Also for performance reasons u should not use allPlayers but

(allPlayers select {_x inArea ...})

 


if ( (allPlayers select { _x inArea [_marker,550,550,0,false] }) findIf {
[objectParent _x, "VIEW"] checkVisibility [eyePos _x, (AGLToASL _marker) vectorAdd [0,0,1.5]] > 0
} isEqualTo -1) then { 

"x don't see the location" remoteExec ["hint"];

};

not tested

Seems to work great, thanks.

  • Like 1

Share this post


Link to post
Share on other sites

Is it possible to select a single unit from a group, who is able to see the location/object?

_group = [_pos, EAST, 7 ] call BIS_fnc_spawnGroup; 

if (units _group findIf {
["VIEW"] checkVisibility [eyePos _x,(AGLToASL _markerpos) vectorAdd [0,0,1.5]] > 0} !=-1) then {

_x do something;

};

 

Share this post


Link to post
Share on other sites

not tested:

 

private _group = [_pos, EAST, 7 ] call BIS_fnc_spawnGroup; 
private _units = units _group;

private _unitIndex = _units findIf {["VIEW"] checkVisibility [eyePos _x,(AGLToASL _markerpos) vectorAdd [0,0,1.5]] > 0};

if (_unitIndex > -1) then {
 private _unit = _units select _unitIndex;

_unit do something;
};

 

  • Like 1

Share this post


Link to post
Share on other sites

Thanks @sarogahtyp

 

I might be overcomplicating it but i'm trying to fetch the closest player to one of the unit in the _group and if the unit sees the nearest player it will target it. Since checkvisibility needs object to object i need to sort the players and which units who has visibility before i'm able to do apply and sort them to the specific unit etc.

 

The _unitIndex = _units findIf will always stop at one? Not multiple units who is able to see? Maybe a count command will work?

private _group = [_pos, EAST, 7 ] call BIS_fnc_spawnGroup; 

{
_x disableAI "Target";
} count (units group);

private _players = allPlayers select {alive _x};

private _units = units _group;

private _unitIndex = _units findIf {[objectParent _players,"VIEW"] checkVisibility [eyePos _x,eyepos _players] > 0};

if (_unitIndex > -1) then {
private _unit = _units select _unitIndex;

private _playerDistances = _players apply {[_x distanceSqr getpos _unit,_x]};

_playerDistances sort true;

private _target = _playerDistances #0#1;

_unit doTarget _target;

};

 

Share this post


Link to post
Share on other sites
private _enemyGroup = [_pos, EAST, 7 ] call BIS_fnc_spawnGroup; 

private _enemyUnits = units _enemyGroup;

{
 _x disableAI "Target";
} count _enemyGroup;

private _players = allPlayers select {alive _x};

private _playerDistances = _players apply 
{
 private _plyr = _x;
 private _groupDistances = _enemyGroup apply { [_x distanceSqr _plyr, _x] };
 _groupDistances sort true;
 [_groupDistances#0#1, _x, _groupDistances]
};

_playerDistances sort true;
private _enemyUnitsNotUsed = +_enemyUnits;

scopeName "OutOfLoop";

{
 private _plyr = _x#1;

 _d = {

  if ( (_x in _enemyUnitsNotUsed) && { [_x, "VIEW"] checkVisibility [eyePos _x, eyePos _plyr] > 0 } ) then
  {
   _x doTarget _plyr;
   _enemyUnitsNotUsed = _enemyUnitsNotUsed - _x;
  };

  if (_enemyUnitsNotUsed isEqualTo [] ) then {breakTo "OutOfLoop"};

 } count _x#2;
}count _playerDistances;

WORK IN PROGRESS!

  • Like 2

Share this post


Link to post
Share on other sites

This code below seems to be almost working, but if two players is inside the radius it keeps locking only one of them even if one is further away. Suggestions?

_pos = getMarkerpos "Marker1";

_group = [_pos, EAST, 7 ] call BIS_fnc_spawnGroup; 

_units = units _enemyGroup;

_markerpos = getMarkerpos "Marker1";

private _playerDistances = (allPlayers select {(_x distance2d _markerpos < 800) && {alive _x}}) apply
{
 private _plyr = _x;
 private _groupDistances = _units apply {[_x distanceSqr _plyr,_x]};
_groupDistances sort true;
[_groupDistances#0#1, _x, _groupDistances]
};
                                                                               
if !(_playerDistances isEqualTo []) then {

_playerDistances sort true;

_target = _playerDistances #0#1;

{
if (_x knowsAbout _target > 0) then {
_x doTarget _target;
}} count _units;
         
};

I did try something like this below but it only select the last unit in each squad.

_pos = getMarkerpos "Marker1";

_group = [_pos, EAST, 7 ] call BIS_fnc_spawnGroup; 

_units = units _group;

{
_unit = _x;
_nearplyrs = (allPlayers select {(_x distance2d _unit < 800) && {(lifestate _x != "DEAD-RESPAWN")}} apply {[_x distanceSqr _unit, _x]})
} forEach _units;

if !(_nearplyrs isEqualTo []) then {

_nearplyrs sort true;

_target = _nearplyrs #0#1;
                                                            
{
if (_x knowsAbout _target > 0) then {
_x doTarget _target;
} count _units;
         
};

 

Share this post


Link to post
Share on other sites
35 minutes ago, Tankbuster said:

I know this is a little off topic, but I prefer lineIntersects for this. Easier on the CPU and I found it more reliable.

Thanks, i could try that command. Do you know how to proper use a lineintersect command?

 

Maybe something like this?

(allPlayers findIf {lineIntersects [eyePos _x,eyePos (AGLToASL _markerpos) vectorAdd [0,0,1.5]], objectParent _x]});

  • Like 1

Share this post


Link to post
Share on other sites
54 minutes ago, Robustcolor said:

Thanks, i could try that command. Do you know how to proper use a lineintersect command?

 

Maybe something like this?

(allPlayers findIf {lineIntersects [eyePos _x,eyePos (AGLToASL _markerpos) vectorAdd [0,0,1.5]], objectParent _x]});

Yes, more or less. 🙂

 

Share this post


Link to post
Share on other sites
On 9/12/2020 at 9:37 PM, Tankbuster said:

Yes, more or less. 🙂

 

How does lineIntersects work? Does it care for fog or smokes?

 

If two units can see each other do i have to use !(LineIntersects) with a ! infront

And only (lineIntersects without ! if they can't see eachother, or am i doing something wrong here?

if !(lineIntersects [eyePos test1, eyepos test2, test1,test2]) then {

hint "Test1 and Test2 see eachother"

};

if (lineIntersects [eyePos test1, eyepos test2, test1,test2]) then {

hint "Test1 and Test2 don't see eachother"

};

 

Share this post


Link to post
Share on other sites

@Robustcolor,

If you can use @Tankbuster line intersect to fill an array of potentially visible targets then sort the array using, bis_fnc_sortBy, this should produce your result. Check out the second example. Remember the final param (optional: code) will remove vars from the array which do not match-- leaving only potential targets in the array.

Have fun!

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

×