randy andy tw1 12 Posted April 21, 2017 hello I have been using the BIS function BIS_fnc_findSafePos to locate a random point from a position, which is great as it finds me a position within the search area specified, that is not in water however, I am using it to find a position to move an area marker down which is 300 x 300. the area of this marker will, at some point overlap some areas of the coast/sea. _positions = [selection1, A, B, 0, 0, 0, 0] call BIS_fnc_findSafePos; I am trying to ensure that the marker area, will never be over the sea, as this will be used as a paradrop area. Any ideas? Share this post Link to post Share on other sites
pierremgi 4890 Posted April 21, 2017 On my mind, it's already included in the 5th parameter of the BIS_fnc_findSafePos ! Share this post Link to post Share on other sites
randy andy tw1 12 Posted April 21, 2017 Yup. It is set to 0. The single point is indeed not in water But when i move the marker to that point, the area of the marker can still be in water. Is there a way to direct the area of the marker away from water? Ive thought about the black list option too but im struggling to find the right expression/commands to help with it. Share this post Link to post Share on other sites
sarogahtyp 1108 Posted April 21, 2017 okay I ve an idea for this. 1. find the position as u did. lets call it dry_pos 2. now use dry_pos as origin to find another position (lets call it wet_pos) but this time with the condition that it has to be in the water. min distance should be a very small value and max distance should be the distance to the border of ur area marker. if the function doesnt find a wet_pos then dry_pos is exactly what u r looking for. if the function find such a wet_pos then there is water in the area and dry_pos is not ur desired position for the center of ur marker. Share this post Link to post Share on other sites
randy andy tw1 12 Posted April 22, 2017 actually... thats a great shout there. didnt think about flipping it. tunnel vision! will post up if i get somewhere. thanks Sarogahtyp Share this post Link to post Share on other sites
randy andy tw1 12 Posted April 22, 2017 okay, i might be going about this the wrong way, but im struggling for an IF condition for a loop in a function private ["_fncactive","_dps","_wps"]; _fncactive = 0; zone = getpos player; while {_fncactive < 1} do { _dps = [position,750,750,0,0,0,0,[],[getPos player, getPos player]] call BIS_fnc_findSafePos; _wps = [_Dps,300,300,0,2,0,0] call BIS_fnc_findSafePos; if ( condition ) then { hint "no water"; _fncactive +1; } else { hint "water"; }; }; Share this post Link to post Share on other sites
pierremgi 4890 Posted April 22, 2017 surfaceIsWater someposition; Share this post Link to post Share on other sites
sarogahtyp 1108 Posted April 23, 2017 surfaceIsWater someposition;I this is not helping because op seeks an area without water sent from mobile using Tapatalk Share this post Link to post Share on other sites
randy andy tw1 12 Posted April 23, 2017 12 hours ago, pierremgi said: surfaceIsWater someposition; this will ask if water is at a position, which is good. is there anyway to apply this to an area though? Share this post Link to post Share on other sites
randy andy tw1 12 Posted April 23, 2017 im having a problem with my IF condition. In theory, _DPS will find a position, _WPS checks this position 300x300 if there is water. if NO water is found, bis_fnc_findsafepos, will use the default which is defined as my players pos (as a test) then _WPS should equal player pos (which i have named zone as a test at the start of the fnc) if there is NO water. however, looking at how the markers move, it keeps looping, even when it find positions that dont have water. any ideas where i am going wrong? private ["_fncactive","_dps","_wps","_test"]; _fncactive = 0; zone = getpos player; while {_fncactive < 1} do { _dps = [activezone,1750,1750,0,0,0,0,["marker"],[getPos player, getPos player]] call BIS_fnc_findSafePos; // will find a random pos 1750 from active zone, will avoid marker. sleep 0.1; _wps = [_dps,300,300,0,2,0,0,[],[getPos player, getPos player]] call BIS_fnc_findSafePos; // will return player pos if this does not find water sleep 1; if (_wps isequalto zone) // in theory if _wps does NOT find water, _WPS should default to getplayerpos then { hint "no water"; _fncactive = _fncactive +1; // stops the loop sleep 1; "markerpara2" setmarkerpos _dps; "markerpara" setmarkerpos _wps; } else { hint "water"; sleep 1; "markerpara" setmarkerpos _wps; "markerpara2" setmarkerpos _dps; }; Share this post Link to post Share on other sites
randy andy tw1 12 Posted April 23, 2017 solved I was using getPos player as a default, which doesnt work as it is a command. fixed by using _default = [0,0,0]; now _dps will look for a position _wps will check this position if water is found within this position, it returns _default if _wps isequal to _default (which means if it found water) then it stops the loop private ["_loop","_dps","_wps","_default"]; _loop = 1; _default = [0,0,0]; while {_loop > 0} do { _dps = [activezone,1750,1750,0,0,0,0,["marker"],[_default,_default]] call BIS_fnc_findSafePos; // will find a random pos 1750 from my active zone, will avoid looking at the area of marker. sleep 0.5; _wps = [_dps,300,300,0,2,0,0,[],[_default,_default]] call BIS_fnc_findSafePos; // will return _default if this does NOT find water sleep 1; if (_wps isequalto _default) // checks if _wps isequalto _default then { hint "no water"; _loop = _loop -1; // stops the loop when condition is met sleep 1; "markerpara" setmarkerpos _wps; // places a marker at _Wps found location "markerpara2" setmarkerpos _dps; // places a marker at _DPS found location } else { hint "water"; sleep 1; "markerpara" setmarkerpos _wps; // places a marker at _Wps found location "markerpara2" setmarkerpos _dps; // places a marker at _DPS found location }; sleep 1; }; Share this post Link to post Share on other sites
Larrow 2822 Posted April 23, 2017 Depending on how/where you are using this, your script could potentially become stuck in a loop if no dry position without water within 300m is found. with debug Spoiler Where debug markers are... Green: original check from position Red: Dry position with water within 300m Blue: Water position of Dry check Black Area: Blacklist Area added to Dry position check Yellow: Found position: Dry position without water within 300m h = [ getPos player ] spawn { private ["_dps","_wps"]; params[ "_position" ]; _maxTries = 20; _try = 0; _blacklist = []; if !( isNull ( findDisplay 313 )) then { for "_mrkNum" from _try to _maxTries do { { _mrkName = format[ "%1%2", _x, _mrkNum ]; if !( getMarkerPos _mrkName isEqualTo [0,0,0] ) then { deleteMarker _mrkName; }; }forEach [ "dps", "wps", "bl" ]; }; { if !( getMarkerPos _x isEqualTo [0,0,0] ) then { deleteMarker _x; }; }forEach [ "orig", "found" ]; openMap true; _origMrk = createMarker[ "orig", _position ]; _origMrk setMarkerShape "ICON"; _origMrk setMarkerType "hd_dot"; _origMrk setMarkerColor "ColorGreen"; }; waitUntil { waitUntil { _dps = [ _position,750,750,0,0,0,0,_blacklist,[ _position, _position ]] call BIS_fnc_findSafePos; if ( !( _dps isEqualTo _position ) && !isNull ( findDisplay 313 )) then { _dpsMrk = createMarker[ format[ "dps%1", _try ], _dps ]; _dpsMrk setMarkerShape "ICON"; _dpsMrk setMarkerType "hd_dot"; _dpsMrk setMarkerColor "ColorRed"; }; systemChat format[ "Try: %1", _try ]; _try = _try + 1; !( _dps isEqualTo _position ) || { _try >= _maxTries } }; if !( _try >= _maxTries ) then { _wps = [_dps,300,300,0,2,0,0,[],[ _position, _position ]] call BIS_fnc_findSafePos; if ( !( _wps isEqualTo _position ) && !isNull ( findDisplay 313 ) ) then { _wpsMrk = createMarker[ format[ "wps%1", _try ], _wps ]; _wpsMrk setMarkerShape "ICON"; _wpsMrk setMarkerType "hd_dot"; _wpsMrk setMarkerColor "ColorBlue"; _waterPos = for "_dist" from 0 to 300 do { _pos = _dps getPos[ _dist, _dps getDir _wps ]; if ( surfaceIsWater _pos ) exitWith { _pos }; _wps }; _blMrk = createMarker[ format[ "bl%1", _try ], _waterPos ]; _blMrk setMarkerShape "ELLIPSE"; _blMrk setMarkerSize[ 300, 300 ]; _blMrk setMarkerColor "ColorBlack"; _blMrk setMarkerAlpha 0.25; _nul = _blacklist pushBack format[ "bl%1", _try ]; }; }; _try >= _maxTries || { _wps isEqualTo _position } }; if ( _try < _maxTries ) then { hint format[ "found in %1 attempts", _try ]; if !( isNull ( findDisplay 313 )) then { _foundMrk = createMarker[ "found", _dps ]; _foundMrk setMarkerShape "ICON"; _foundMrk setMarkerType "hd_dot"; _foundMrk setMarkerColor "ColorYellow"; }; }else{ hint "Run out of trys"; }; }; without debug Spoiler h = [ getPos player ] spawn { private ["_dps","_wps"]; params[ "_position" ]; _maxTries = 20; _try = 0; _blacklist = []; waitUntil { waitUntil { _dps = [ _position,750,750,0,0,0,0,_blacklist,[ _position, _position ]] call BIS_fnc_findSafePos; _try = _try + 1; !( _dps isEqualTo _position ) || { _try >= _maxTries } }; if !( _try >= _maxTries ) then { _wps = [_dps,300,300,0,2,0,0,[],[ _position, _position ]] call BIS_fnc_findSafePos; if ( !( _wps isEqualTo _position ) && !isNull ( findDisplay 313 ) ) then { _waterPos = for "_dist" from 0 to 300 do { _pos = _dps getPos[ _dist, _dps getDir _wps ]; if ( surfaceIsWater _pos ) exitWith { _pos }; _wps }; _blMrk = createMarker[ format[ "bl%1", _try ], _waterPos ]; _blMrk setMarkerShape "ELLIPSE"; _blMrk setMarkerSize[ 300, 300 ]; _blMrk setMarkerAlpha 0; _nul = _blacklist pushBack format[ "bl%1", _try ]; }; }; _try >= _maxTries || { _wps isEqualTo _position } }; for "_mrkNum" from 1 to _try do { _mrkName = format[ "bl%1", _mrkNum ]; if !( getMarkerPos _mrkName isEqualTo [0,0,0] ) then { deleteMarker _mrkName; }; }; if ( _try < _maxTries ) then { hint format[ "found in %1 attempts", _try ]; }else{ hint "Run out of trys"; }; }; For each water position that is found an invisible marker is placed at the nearest water position to the dry position, which is then feed back into the dry position search so you are not getting any redundant results from the dry position test on positions we know have water within 300m. Share this post Link to post Share on other sites
randy andy tw1 12 Posted April 23, 2017 2 hours ago, Larrow said: if no dry position without water within 300m is found. I have safeguarded this with the black list of "marker". Marker coveres an area of sea. basically a beach Lz is created > it then selects a predefined inland position which will always be on land > it then kicks in the above for a paradrop position. Would you agree this would work with what i have? Is the version you posted worth me using? (not trying to be rude, I am asking from a very naive point of view) thank you Share this post Link to post Share on other sites
Larrow 2822 Posted April 23, 2017 1 hour ago, randy andy tw1 said: basically a beach Lz is created > it then selects a predefined inland position which will always be on land > it then kicks in the above for a paradrop position. Would you agree this would work with what i have? If you have already made sure that there is no chance of being stuck in a loop then it sounds like you are all set. My code was just a general place it anywhere and get a position based on your conditions. Share this post Link to post Share on other sites
pierremgi 4890 Posted April 24, 2017 Here is my 2 cent code. Just choose any position (on any map) and a radius (range) to be dry. MGI_dryCheck = compileFinal " _pos = _this select 0; _posWet = []; _range = _this select 1; _deltaR = _range / 3600; for '_i' from 0 to 3600 step 10 do { _ckPos = _pos getPos [_deltaR*_i,_i]; if (surfaceIsWater _ckPos) exitWith {_posWet = _ckPos} }; _posWet "; MGI_wetCheck = compileFinal " _pos = _this select 0; _posDry = []; _range = _this select 1; _deltaR = _range / 3600; for '_i' from 0 to 3600 step 10 do { _ckPos = _pos getPos [_deltaR*_i,_i]; if !(surfaceIsWater _ckPos) exitWith {_posDry = _ckPos} }; _posDry "; MGI_dryArea = { _pos0 = _this select 0; _range = _this select 1; _pos = _pos0; _cnt = 0; if (surfaceIsWater _pos0) then { _posDry = [_pos,_range] call MGI_wetCheck; while {(_posDry isEqualTo [])} do { _pos = _pos vectorAdd ((_pos vectorFromTo [worldSize/2,worldSize/2,0]) vectorMultiply _range); _posDry = [_pos,_range] call MGI_wetCheck; }; _pos0 = _posDry; _pos = _pos0; }; _posWet = [_pos,_range] call MGI_dryCheck; while {!(_posWet isEqualTo [])} do { _cnt = _cnt + 1; _pos = _pos vectorAdd ((_poswet vectorFromTo _pos) vectorMultiply (_range - (_pos distance _posWet))); _posWet = [_pos,_range] call MGI_dryCheck; if (_cnt == 20) exitWith { _range = _range * 0.66; [_pos0,_range] call MGI_dryArea; }; }; deleteMarker "dry drop"; _mk = createMarker ["dry drop",_pos]; _mk setMarkerShape "ellipse"; _mk setMarkerSize [_range max 50,_range max 50] }; [any position,range] call MGI_dryArea; How it works: first checking if in water or on ground; spiraling for touching any ground if water only, close the ground in direction of the center of the map, for a distance equal to the range you chose; check if any ground by spiraling; .... reaching a ground, check for shore by spiraling, if any shore, move away to opposite direction for range - distance to shore, check if any shore in a 20 round loop, if no more shore, tada, you've got the exact dry area with range radius. if no joy, shrink the radius to 0.66 of the former one and test again. (you are in a tiny island with a too big radius) Performances are not too bad. Hope this help. 1 Share this post Link to post Share on other sites