Jump to content
Binesi

Improved BIS_fnc_taskPatrol

Recommended Posts

Hey Wolfy -

Is there someplace to cut/paste or download the most recent version of the scripts without downloading the mission? :)

Thanks!

Share this post


Link to post
Share on other sites
Hey Wolfy -

Is there someplace to cut/paste or download the most recent version of the scripts without downloading the mission? :)

Thanks!

The demo is mission is like 55kB - c'mon man! :P

Share this post


Link to post
Share on other sites

Hey guys, your math is not ok.

_x1 = _center_x - (sin _newangle * _max_dist);

_y1 = _center_y - (cos _newangle * _max_dist);

You can plot it in Excel and check the graph. You will get "circle" (obviously) but it won't be regular -- in other words it will have gaps and regions with high density of points. One more time, it will be a circle, but now right regular circle......

If you work with degees you have to write several lines of code in addition, believe me I did it. However, it is complicated to work with dozens of if statements...

Much better solution is to convert angles to radians.

For example:

_angle = (360 / (_wp_count -1));
_angle = angle * 0.0174532925;

or for Wolffy.au 's script you should add also:

_angle_offset = random 360;
_angle_offset = _angle_offset * 0.0174532925;

Create angles 0, 90, 180, 270 and 360 in Excel (or more if you want to make circle, not square, octagon etc.), apply these functions and make scatter plot. Then convert angles into radians and check the plot again. You will see the difference.

Cheers

Edited by ArmAIIholic

Share this post


Link to post
Share on other sites

--CHECKED & SOLVED--

Math is still not correct. However, ArmA automatically converts degrees to radians!!!

So the solution is quite ok, no need to change anything!

Proof

Excel --- degrees

ny7kzn.jpg

Excel --- radians

102k1sk.jpg

ArmA --- degrees automatically to radians

nq6xhh.jpg

--ANOTHER EXAMPLE OF USING RADIANS--

...is above mentioned findSafePos when looking for gradient i.e. 60 * (pi / 180) >> 0.0174532925. You just have to put it in radians, in contrary to the angle ;)

--ANOTHER CONFUSING PROBLEM--

Does anyone check the math?

@TRexian -- if I have an angle 0 and offset -15 that is actually the angle 360 - 15 = 345. Your script will give -15-360 = -375, and then abs is 375...

Apparently it will work only for angles > 360, right? But, why abs then?

You can choose any angle just by adding random positive value some k: 0<= k < 360 and then subtract 360 if it's greater than 360...

Math is not ok, like in the example above. (I posted proofs because ArmA engine is doing things "silently" and I thought everyone should be aware of it)

Edited by ArmAIIholic

Share this post


Link to post
Share on other sites

And why exactly is that relevant to this script and thread? It's just some waypoints? As long as it's random enough it's fine.

Share this post


Link to post
Share on other sites
My version creates a continually randomized roughly circular patrol path around a given point (as opposed to the BIS function which is purely random and chaotic). Generally it will move clockwise with a random chance to skip ahead and intersect across to another waypoint.

@shk

If I understood this correctly path should be circular, right? Therefore my testing was related to circularity, and if you know a little bit trigonometry you would ask yourself in the first place is the math correct. Do you know how to get coordinates if you are working with degrees? A little hint: there are 4 quadrants and 4 directions.

I was just pointing out difference in the scripting and when to use degrees and when to use radians -- it is huge difference and importance.

I suppose it is not enough for you? For sarcastic question - sarcastic answer. Just try to be more polite next time, ok? I didn't do you anything wrong.

--IN ADDITION--

One more thing. From the picture you can see that angle 0 is facing South and it is going clockwise. This is also important to know, since azimuth or direction starts from North, which is huge difference. Therefore, knowing that you can easily turn any soldier toward or away from the central point of the circle, you can easily change the velocity of the vehicle etc. and all that without messing with direction vector.

I think my info is very useful. Tell me if I am wrong.

Cheers

Edited by ArmAIIholic

Share this post


Link to post
Share on other sites

@TRexian -- if I have an angle 0 and offset -15 that is actually the angle 360 - 15 = 345. Your script will give -15-360 = -375, and then abs is 375...

Apparently it will work only for angles > 360, right? But, why abs then?

You can choose any angle just by adding random positive value some k: 0<= k < 360 and then subtract 360 if it's greater than 360...

Math is not ok, like in the example above. (I posted proofs because ArmA engine is doing things "silently" and I thought everyone should be aware of it)

Hey there!

I'm the first to admit that my math skeelz are not 733t. :) So, I do appreciate the double-check.

But, I kinda see a different problem - "human" waypoints are not perfectly geometric. That is, people (and other animals) tend not to walk in a perfect circle. In fact, it would be almost impossible for a person to walk in a perfect circle without the help of some tools (like people use to make crop circles). So, I'm not sure a perfect circle of waypoints is particularly realistic. It just seems too... sterile. But, I guess that's a different issue.

However, I also do want to respond to your point about my script snippet. I presume you're referring to the one on the first page of this thread:

 if ((_tempDir > 360) || (_tempDir < 0)) then
 {
	_dir = abs (abs (_tempDir) - 360);
 }
 else
 {
	_dir = _tempDir;
 };

First, I think some clarification is necessary - this bit works if the direction is < 0 or > 360. Both abs commands are necessary to cover both situations.

In your example, the offset calculation (0 - 15) creates a direction of -15. In that case, -15 < 0, so the calculation becomes: abs (abs(-15)-360). I believe that works out to:

abs(-15) = 15

15 - 360 = -345

abs(-345) = 345

I recall checking it alot when I made it. Granted, I may've made a mistake, but it seemed to work appropriately at the time (and since then, as I use this function frequently).

:)

Edited by TRexian

Share this post


Link to post
Share on other sites

Hey TRexian,

thanx for clarification. My mistake about priorities of operations. The first abs will catch the -15, not (-15-360), so yes your script is just fine. My bad, my bad...

However, I understand that the more points you make, the circle will be more perfect, but patrol's walk will be with lots of pauses (sterile), and vice versa.

I posted above some response about circularity and what I meant to say (if it wasn't clear). There is difference between degrees, radians and azimuth, so I just wanted to share that with others, if someone don't know.

I will use some of those snippets, so I checked them, and now I will adjust them for my module.

Share this post


Link to post
Share on other sites

No problem, and good luck with your mod. :) Your ideas are very much in line with the type of gameplay that I personally like.

Share this post


Link to post
Share on other sites

Here is my modification of these scripts.

Added randomization of clockwise - counterclockwise direction and

added waypoint count so these waypoints just add to previous.

I am using them in WICT to add patrols after the base is captured.

Blue bold are my changes.

/*
=======================================================================================================================
Script: BIN_taskPatrol.sqf v1.2
Author(s): Binesi
Partly based on original code by BIS

Description:
Creates a continually randomized patrol path which circles and intersects a given position.

Parameter(s):
_this select 0: the group to which to assign the waypoints (Group)
_this select 1: the position on which to base the patrol (Array)
_this select 2: the maximum distance between waypoints (Number)
_this select 3: (optional) debug markers on or off (Number)
_this select 4: (optional) blacklist of areas (Array)

Returns:
Boolean - success flag

Example(s):
null = [group this,(getPos this),250] execVM "BIN_taskPatrol.sqf"
null = [group this,(getPos this),250,1] execVM "BIN_taskPatrol.sqf" // Same with debug markers

-----------------------------------------------------------------------------------------------------------------------
Notes: Wolffy.au
If anyone is interested, I've made some additions to Binesi's BIN_taskPatrol script.
Random initial patrol direction - I noticed every patrol started off in the same direction, so I've randomised it.
Fixed the 2D position / findSafePos errors

[b][color="blue"]ArmaIIholic 
-- added part of JTD direction normalization function
-- changed numbers for waypoints to match previous waypoints
-- randomized initial direction -- Wolffy.au added only the offset which had to be reduced to 180 
          - however this script is making full circle from wherever it starts[/color][/b]

=======================================================================================================================
*/

_grp = _this select 0;
_pos = _this select 1;
_max_dist = _this select 2;
_debug = if ((count _this) > 3) then {_this select 3} else {0};
_blacklist = if ((count _this) > 4) then {_blacklist = _this select 4} else {[]};

_mode = ["YELLOW", "RED"] call BIS_fnc_selectRandom;
_formation = ["STAG COLUMN", "WEDGE", "ECH LEFT", "ECH RIGHT", "VEE", "DIAMOND"] call BIS_fnc_selectRandom;

_grp setBehaviour "AWARE";
_grp setSpeedMode "LIMITED";
_grp setCombatMode _mode;
_grp setFormation _formation;

_center_x = (_pos) select 0;
_center_y = (_pos) select 1;
_center_z = (_pos) select 2;
if(isNil "_center_z")then{_center_z = 0;};

_wp_count = 4 + (floor random 3) + (floor (_max_dist / 100 ));
_angle = (360 / (_wp_count -1));

_newangle = 0;
_wp_array = [];
_slack = _max_dist / 5.5;
if ( _slack < 20 ) then { _slack = 20 };

[b][color="blue"]_setdir = round (random 1);

_angle_offset = random 180;[/color][/b]
while {count _wp_array < _wp_count} do 
{
	private ["_x1","_y1","_wp_pos"];

	_newangle = (count _wp_array * _angle) + _angle_offset;

	[b][color="blue"]if ((_newangle > 360) || (_newangle < 0)) then
	{
		_newangle = abs (abs (_newangle) - 360);
	};

	if (_setdir == 1) then 
	{
		_newangle = -_newangle;

		if ((_newangle > 360) || (_newangle < 0)) then
		 {
			_newangle = abs (abs (_newangle) - 360);
		 };
	};[/color][/b]

	_x1 = _center_x - (sin _newangle * _max_dist);
	_y1 = _center_y - (cos _newangle * _max_dist);

	_prepos = [_x1, _y1, _center_z];
	if ( isNil "_center_z" ) then {
		_prepos = [_x1, _y1];
	};

	_wp_pos = [_prepos, 0, _slack, 6, 0, 50 * (pi / 180), 0, _blacklist] call BIS_fnc_findSafePos;

	_wp_array = _wp_array + [_wp_pos];

	sleep 0.5;
};

sleep 1;

[b][color="blue"]_j = count (waypoints _grp);[/color][/b]

for "_i" from 1 to (_wp_count - 1) do
{
	private ["_wp","_cur_pos","_marker","_marker_name"];

	_cur_pos = (_wp_array select _i);

	// Create waypoints based on array of positions
	/* The index i is changed so it matches the FSM - j+i */

	_wp = _grp addWaypoint [_cur_pos, 0];
	_wp setWaypointType "MOVE";
	_wp setWaypointCompletionRadius (5 + _slack);
	[b][color="blue"][_grp,_j+i][/color][/b] setWaypointTimeout [0, 2, 16];
	// When completing waypoint have 33% chance to choose a random next wp
	[b][color="blue"][_grp,_j+i][/color][/b] setWaypointStatements ["true", "if ((random 3) > 2) then { group this setCurrentWaypoint [(group this), (floor (random (count (waypoints (group this)))))];};"];

	if (_debug > 0) then 
	{
		_marker_name = str(_wp_array select _i);
		_marker = createMarker[_marker_name,[_cur_pos select 0,_cur_pos select 1]];
		_marker setMarkerShape "ICON";
		_marker_name setMarkerType "DOT";
	};

	sleep 0.5;
};

// End back near start point and then pick a new random point
_wp1 = _grp addWaypoint [_pos, 0];
_wp1 setWaypointType "SAD";
_wp1 setWaypointCompletionRadius (random (_max_dist));
[_grp,(count waypoints _grp)] setWaypointStatements ["true", "group this setCurrentWaypoint [(group this), (round (random 2) + 1)];"];

// Cycle in case we reach the end
_wp2 = _grp addWaypoint [_pos, 0];
_wp2 setWaypointType "CYCLE";
_wp2 setWaypointCompletionRadius 100;

true

And the other one with building search:

/*
=======================================================================================================================
Script: BIN_taskPatrol.sqf v1.3
Author(s): Binesi
Partly based on original code by BIS

Description:
Creates a continually randomized patrol path which circles and intersects a given position.

Parameter(s):
_this select 0: the group to which to assign the waypoints (Group)
_this select 1: the position on which to base the patrol (Array)
_this select 2: the maximum distance between waypoints (Number)
_this select 3: (optional) debug markers on or off (Number)
_this select 4: (optional) blacklist of areas (Array)

Returns:
Boolean - success flag

Example(s):
null = [group this,(getPos this),250] execVM "BIN_taskPatrol.sqf"
null = [group this,(getPos this),250,1] execVM "BIN_taskPatrol.sqf" // Same with debug markers

-----------------------------------------------------------------------------------------------------------------------
Notes: Wolffy.au
If anyone is interested, I've made some additions to Binesi's BIN_taskPatrol script.
Random initial patrol direction - I noticed every patrol started off in the same direction, so I've randomised it.
Fixed the 2D position / findSafePos errors
Added building positions as possible patrol locations using Random Building Position Script v1.0 by Tophe of Östgöta Ops

[b][color="blue"]ArmaIIholic 
-- added part of JTD direction normalization function
-- changed numbers for waypoints to match previous waypoints
-- randomized initial direction -- Wolffy.au added only the offset which had to be reduced to 180 
          - however this script is making full circle from wherever it starts[/color][/b]

=======================================================================================================================
*/

_grp = _this select 0;
_pos = _this select 1;
_max_dist = _this select 2;
_debug = if ((count _this) > 3) then {_this select 3} else {0};
_blacklist = if ((count _this) > 4) then {_blacklist = _this select 4} else {[]};

_mode = ["YELLOW", "RED"] call BIS_fnc_selectRandom;
_formation = ["STAG COLUMN", "WEDGE", "ECH LEFT", "ECH RIGHT", "VEE", "DIAMOND"] call BIS_fnc_selectRandom;

_grp setBehaviour "AWARE";
_grp setSpeedMode "LIMITED";
_grp setCombatMode _mode;
_grp setFormation _formation;

_center_x = (_pos) select 0;
_center_y = (_pos) select 1;
_center_z = (_pos) select 2;
if(isNil "_center_z")then{_center_z = 0;};

_wp_count = 4 + (floor random 3) + (floor (_max_dist / 100 ));
_angle = (360 / (_wp_count -1));

_new_angle = 0;
_wp_array = [];
_slack = _max_dist / 5.5;
if ( _slack < 20 ) then { _slack = 20 };

[b][color="Blue"]_setdir = round (random 1);

_angle_offset = random 180;[/color][/b]
while {count _wp_array < _wp_count} do 
{
	private ["_x1","_y1","_wp_pos", "_prepos","_bldgpos","_bldgs"];

	_newangle = (count _wp_array * _angle) + _angle_offset;

	[b][color="blue"]if ((_newangle > 360) || (_newangle < 0)) then
	{
		_newangle = abs (abs (_newangle) - 360);
	};

	if (_setdir == 1) then 
	{
		_newangle = -_newangle;

		if ((_newangle > 360) || (_newangle < 0)) then
		 {
			_newangle = abs (abs (_newangle) - 360);
		 };
	};[/color][/b]

	_x1 = _center_x - (sin _newangle * _max_dist);
	_y1 = _center_y - (cos _newangle * _max_dist);

	_prepos = [_x1, _y1, _center_z];
	if ( isNil "_center_z" ) then {
		_prepos = [_x1, _y1];
	};

	_wp_pos = [_prepos, 0, _slack, 6, 0, 50 * (pi / 180), 0, _blacklist] call BIS_fnc_findSafePos;


	//////////////////////////////////////////////////////////////////
	// The following code is an extract from Random Building Position Script v1.0 by Tophe of Östgöta Ops
	//////////////////////////////////////////////////////////////////
	_bldgpos = [];
	_bldgs = nearestObjects [_wp_pos, ["Building"], 50];
	{
	  private["_i","_y"];
		_i = 0;
		_y = _x buildingPos _i;
		while {format["%1", _y] != "[0,0,0]"} do {
			_bldgpos = _bldgpos + [_y];
			_i = _i + 1;
			_y = _x buildingPos _i;
		};
	} forEach _bldgs;

	if(count _bldgpos != 0) then {_wp_pos = _bldgpos call BIS_fnc_selectRandom;};
	_wp_array = _wp_array + [_wp_pos];

	sleep 0.5;
};

sleep 1;

[b][color="blue"]_j = count (waypoints _grp);[/color][/b]

for "_i" from 1 to (_wp_count - 1) do
{
	private ["_wp","_cur_pos","_marker","_marker_name"];

	_cur_pos = (_wp_array select _i);

	// Create waypoints based on array of positions
	/* The index i is changed so it matches the FSM - j+i */

	_wp = _grp addWaypoint [_cur_pos, 0];
	_wp setWaypointType "MOVE";
	_wp setWaypointCompletionRadius (5 + _slack);
	[b][color="blue"][_grp,_j+i][/color][/b] setWaypointTimeout [0, 2, 16];
	// When completing waypoint have 33% chance to choose a random next wp
	[b][color="blue"][_grp,_j+i][/color][/b] setWaypointStatements ["true", "if ((random 3) > 2) then { group this setCurrentWaypoint [(group this), (floor (random (count (waypoints (group this)))))];};"];

	if (_debug > 0) then {
		_marker_name = str(_wp_array select _i);
		_marker = createMarker[_marker_name,[_cur_pos select 0,_cur_pos select 1]];
		_marker setMarkerShape "ICON";
		_marker_name setMarkerType "DOT";
	};

	sleep 0.5;
};

// End back near start point and then pick a new random point
_wp1 = _grp addWaypoint [_pos, 0];
_wp1 setWaypointType "SAD";
_wp1 setWaypointCompletionRadius (random (_max_dist));
[_grp,(count waypoints _grp)] setWaypointStatements ["true", "group this setCurrentWaypoint [(group this), (round (random 2) + 1)];"];

// Cycle in case we reach the end
_wp2 = _grp addWaypoint [_pos, 0];
_wp2 setWaypointType "CYCLE";
_wp2 setWaypointCompletionRadius 100;

true

Cheers

A2H

Edited by ArmAIIholic

Share this post


Link to post
Share on other sites

Nice work ArmaIIholic

Added:

- Added check that BIS Functions has been initialised

- Only perform the house patrols if the squad leader is a man

/*
=======================================================================================================================
Script: BIN_taskPatrol.sqf v1.4
Author(s): Binesi
Partly based on original code by BIS

Description:
Creates a continually randomized patrol path which circles and intersects a given position.

Parameter(s):
_this select 0: the group to which to assign the waypoints (Group)
_this select 1: the position on which to base the patrol (Array)
_this select 2: the maximum distance between waypoints (Number)
_this select 3: (optional) debug markers on or off (Number)
_this select 4: (optional) blacklist of areas (Array)

Returns:
Boolean - success flag

Example(s):
null = [group this,(getPos this),250] execVM "BIN_taskPatrol.sqf"
null = [group this,(getPos this),250,1] execVM "BIN_taskPatrol.sqf" // Same with debug markers

-----------------------------------------------------------------------------------------------------------------------
Notes: Wolffy.au
If anyone is interested, I've made some additions to Binesi's BIN_taskPatrol script.
Random initial patrol direction - I noticed every patrol started off in the same direction, so I've randomised it.
Fixed the 2D position / findSafePos errors
Added building positions as possible patrol locations using Random Building Position Script v1.0 by Tophe of Östgöta Ops
Added check that BIS Functions has been initialised
Only perform the house patrols if the squad leader is a man

ArmaIIholic 
-- added part of JTD direction normalization function
-- changed numbers for waypoints to match previous waypoints
-- randomized initial direction -- Wolffy.au added only the offset which had to be reduced to 180 
          - however this script is making full circle from wherever it starts

=======================================================================================================================
*/

_grp = _this select 0;
_pos = _this select 1;
_max_dist = _this select 2;
_debug = if ((count _this) > 3) then {_this select 3} else {0};
_blacklist = if ((count _this) > 4) then {_blacklist = _this select 4} else {[]};

_mode = ["YELLOW", "RED"] call BIS_fnc_selectRandom;
_formation = ["STAG COLUMN", "WEDGE", "ECH LEFT", "ECH RIGHT", "VEE", "DIAMOND"] call BIS_fnc_selectRandom;

_grp setBehaviour "AWARE";
_grp setSpeedMode "LIMITED";
_grp setCombatMode _mode;
_grp setFormation _formation;

_center_x = (_pos) select 0;
_center_y = (_pos) select 1;
_center_z = (_pos) select 2;
if(isNil "_center_z")then{_center_z = 0;};

_wp_count = 4 + (floor random 3) + (floor (_max_dist / 100 ));
_angle = (360 / (_wp_count -1));

_new_angle = 0;
_wp_array = [];
_slack = _max_dist / 5.5;
if ( _slack < 20 ) then { _slack = 20 };

_setdir = round (random 1);

_angle_offset = random 180;
while {count _wp_array < _wp_count} do 
{
	private ["_x1","_y1","_wp_pos", "_prepos","_bldgpos","_bldgs"];

	_newangle = (count _wp_array * _angle) + _angle_offset;

	if ((_newangle > 360) || (_newangle < 0)) then
	{
		_newangle = abs (abs (_newangle) - 360);
	};

	if (_setdir == 1) then 
	{
		_newangle = -_newangle;

		if ((_newangle > 360) || (_newangle < 0)) then
		 {
			_newangle = abs (abs (_newangle) - 360);
		 };
	};

	_x1 = _center_x - (sin _newangle * _max_dist);
	_y1 = _center_y - (cos _newangle * _max_dist);

	_prepos = [_x1, _y1, _center_z];
	if ( isNil "_center_z" ) then {
		_prepos = [_x1, _y1];
	};

	waitUntil {!isNil "bis_fnc_init"}; 
	_wp_pos = [_prepos, 0, _slack, 6, 0, 50 * (pi / 180), 0, _blacklist] call BIS_fnc_findSafePos;

if (leader _grp isKindOf "Man") then {		
	//////////////////////////////////////////////////////////////////
	// The following code is an extract from Random Building Position Script v1.0 by Tophe of Östgöta Ops
	//////////////////////////////////////////////////////////////////
	_bldgpos = [];
	_bldgs = nearestObjects [_wp_pos, ["Building"], 50];
	{
	  private["_i","_y"];
		_i = 0;
		_y = _x buildingPos _i;
		while {format["%1", _y] != "[0,0,0]"} do {
			_bldgpos = _bldgpos + [_y];
			_i = _i + 1;
			_y = _x buildingPos _i;
		};
	} forEach _bldgs;

	if(count _bldgpos != 0) then {_wp_pos = _bldgpos call BIS_fnc_selectRandom;};
	_wp_array = _wp_array + [_wp_pos];

	sleep 0.5;
};
};

sleep 1;

_j = count (waypoints _grp);

for "_i" from 1 to (_wp_count - 1) do
{
private ["_wp","_cur_pos","_marker","_marker_name"];

_cur_pos = (_wp_array select _i);

// Create waypoints based on array of positions
/* The index i is changed so it matches the FSM - j+i */

_wp = _grp addWaypoint [_cur_pos, 0];
_wp setWaypointType "MOVE";
_wp setWaypointCompletionRadius (5 + _slack);
[_grp,_j+i] setWaypointTimeout [0, 2, 16];
// When completing waypoint have 33% chance to choose a random next wp
[_grp,_j+i] setWaypointStatements ["true", "if ((random 3) > 2) then { group this setCurrentWaypoint [(group this), (floor (random (count (waypoints (group this)))))];};"];

if (_debug > 0) then {
	_marker_name = str(_wp_array select _i);
	_marker = createMarker[_marker_name,[_cur_pos select 0,_cur_pos select 1]];
	_marker setMarkerShape "ICON";
	_marker_name setMarkerType "DOT";
};

sleep 0.5;
};

// End back near start point and then pick a new random point
_wp1 = _grp addWaypoint [_pos, 0];
_wp1 setWaypointType "SAD";
_wp1 setWaypointCompletionRadius (random (_max_dist));
[_grp,(count waypoints _grp)] setWaypointStatements ["true", "group this setCurrentWaypoint [(group this), (round (random 2) + 1)];"];

// Cycle in case we reach the end
_wp2 = _grp addWaypoint [_pos, 0];
_wp2 setWaypointType "CYCLE";
_wp2 setWaypointCompletionRadius 100;

true

Share this post


Link to post
Share on other sites

I just got the error:

_bldgpos = [];
_bldgs = nearestObjects [_wp_pos, ["Building"], 5>
 Error position: <nearestObjects [_wp_pos, ["Building"], 5>
 [color="Red"]Error 0 elements provided, 3 expected[/color]

I guess it is a problem with:

_wp_pos = [_prepos, 0, _slack, 6, 0, 50 * (pi / 180), 0, _blacklist] call BIS_fnc_findSafePos;

so I will put it like this:

_wp_pos = [_prepos, 0, _slack, 6, 0, 50 * (pi / 180), 0, _blacklist,[color="Blue"][_prepos][/color]] call BIS_fnc_findSafePos;

Better some default position the error, right?

Still in the "plain" patrol script I never got this error. I think it is a rare error and in this particular case I think there was no safe pos found which reflected on nearestObjects command, but such thing wasn't "visible" in "plain" patrol script = without house search.

I will return with confirmation whether it works.

--EDIT--

I've got it working with this:

_bldgs = nearestObjects [position (leader _grp), ["Building"], 150];

And I tested numbers from _wp_pos and they seamed ok when returned through hint format, not some any.

--SOLUTION--

Well the problem IS type of variable, since you cannot (or I think cannot) do like in C++ intiger type or real etc. -- it is expecting number so I GAVE it a number!!! :mad:

Solution is in addition, xe xe:

_wp_pos = [_prepos, 0, _slack, 6, 0, 50 * (pi / 180), 0, _blacklist,[_prepos]] call BIS_fnc_findSafePos;

	[color="Blue"]_a = [color="Red"]0[/color] + (_wp_pos select 0);
	_b = [color="red"]0[/color] + (_wp_pos select 1);[/color]

	//////////////////////////////////////////////////////////////////
	// The following code is an extract from Random Building Position Script v1.0 by Tophe of Östgöta Ops
	//////////////////////////////////////////////////////////////////
	_bldgpos = [];
	_bldgs = nearestObjects [[color="Blue"][_a,_b,0][/color], ["Building"], 50];

And it is not the first time I had to do such trick to define variable as number. _a = 0 and _b = 0 then _a = something else and _b = something else won't work.... :(

Edited by ArmAIIholic

Share this post


Link to post
Share on other sites

Can someone repost a complete script with the latest additions? I am trying to use it with ArmAIIholic's fixes in the post above mine, but I am getting a lot of errors or unintended behaviour (e.g. waypoints far outside of the allowed range). I may have added one of these 'patches' incorrectly, or it may be a problem with the script. I can't tell.

Share this post


Link to post
Share on other sites

Here you are, this is the final version I had, and I just added Wolffy.au 's check that BIS Functions has been initialized at the beginning of the script.

/*
=======================================================================================================================
Script: BIN_taskPatrol.sqf v1.3
Author(s): Binesi
Partly based on original code by BIS

Description:
Creates a continually randomized patrol path which circles and intersects a given position.

Parameter(s):
_this select 0: the group to which to assign the waypoints (Group)
_this select 1: the position on which to base the patrol (Array)
_this select 2: the maximum distance between waypoints (Number)
_this select 3: (optional) debug markers on or off (Number)
_this select 4: (optional) blacklist of areas (Array)

Returns:
Boolean - success flag

Example(s):
null = [group this,(getPos this),250] execVM "BIN_taskPatrol.sqf"
null = [group this,(getPos this),250,1] execVM "BIN_taskPatrol.sqf" // Same with debug markers

-----------------------------------------------------------------------------------------------------------------------
Notes: Wolffy.au
If anyone is interested, I've made some additions to Binesi's BIN_taskPatrol script.
Random initial patrol direction - I noticed every patrol started off in the same direction, so I've randomised it.
Fixed the 2D position / findSafePos errors
Added building positions as possible patrol locations using Random Building Position Script v1.0 by Tophe of Östgöta Ops
Added check that BIS Functions has been initialized

ArmaIIholic 
-- added JTD direction normalization function
-- changed numbers for waypoints to match previous waypoints
-- randomized initial direction - Wolffy.au added only the offset
-- fixed error with building position format
-- randomized initial direction -- Wolffy.au added only the offset which had to be reduced to 180 
          - however this script is making full circle from wherever it starts

=======================================================================================================================
*/

if (isServer) then
{
waitUntil {!isNil "bis_fnc_init"};

_grp = _this select 0;
_pos = _this select 1;
_max_dist = _this select 2;
_debug = if ((count _this) > 3) then {_this select 3} else {0};
_blacklist = if ((count _this) > 4) then {_blacklist = _this select 4} else {[]};

_mode = ["YELLOW", "RED"] call BIS_fnc_selectRandom;
_formation = ["STAG COLUMN", "WEDGE", "ECH LEFT", "ECH RIGHT", "VEE", "DIAMOND"] call BIS_fnc_selectRandom;

_grp setBehaviour "AWARE";
_grp setSpeedMode "LIMITED";
_grp setCombatMode _mode;
_grp setFormation _formation;

_center_x = (_pos) select 0;
_center_y = (_pos) select 1;
_center_z = (_pos) select 2;
if(isNil "_center_z")then{_center_z = 0;};

_wp_count = 4 + (floor random 3) + (floor (_max_dist / 100 ));
_angle = (360 / (_wp_count -1));

_newangle = 0;
_wp_array = [];
_slack = _max_dist / 5.5;
if ( _slack < 20 ) then { _slack = 20 };

_setdir = round (random 1);

_angle_offset = random 180;
while {count _wp_array < _wp_count} do 
{
	private ["_x1","_y1","_wp_pos", "_prepos","_bldgpos","_bldgs","_a","_b"];

	_newangle = (count _wp_array * _angle) + _angle_offset;

	if ((_newangle > 360) || (_newangle < 0)) then
	{
		_newangle = abs (abs (_newangle) - 360);
	};

	if (_setdir == 1) then 
	{
		_newangle = -_newangle;

		if ((_newangle > 360) || (_newangle < 0)) then
		 {
			_newangle = abs (abs (_newangle) - 360);
		 };
	};

	_x1 = _center_x - (sin _newangle * _max_dist);
	_y1 = _center_y - (cos _newangle * _max_dist);

	_prepos = [_x1, _y1, _center_z];
	if ( isNil "_center_z" ) then {
		_prepos = [_x1, _y1];
	};

	_wp_pos = [_prepos, 0, _slack, 6, 0, 50 * (pi / 180), 0, _blacklist,[_prepos]] call BIS_fnc_findSafePos;

	_a = 0 + (_wp_pos select 0);
	_b = 0 + (_wp_pos select 1);

		//////////////////////////////////////////////////////////////////
		// The following code is an extract from Random Building Position Script v1.0 by Tophe of Östgöta Ops
		//////////////////////////////////////////////////////////////////
		_bldgpos = [];
		_bldgs = nearestObjects [[_a,_b,0], ["Building"], 50];
		{
		  private["_i","_y"];
			_i = 0;
			_y = _x buildingPos _i;
			while {format["%1", _y] != "[0,0,0]"} do {
				_bldgpos = _bldgpos + [_y];
				_i = _i + 1;
				_y = _x buildingPos _i;
			};
		} forEach _bldgs;

		if(count _bldgpos != 0) then {_wp_pos = _bldgpos call BIS_fnc_selectRandom;};
		_wp_array = _wp_array + [_wp_pos];

		sleep 0.5;
};

sleep 1;

_j = count (waypoints _grp);

for "_i" from 1 to (_wp_count - 1) do
{
	private ["_wp","_cur_pos","_marker","_marker_name"];

	_cur_pos = (_wp_array select _i);

	// Create waypoints based on array of positions
	/* The index i is changed so it matches previous waypoints - j+i */

	_wp = _grp addWaypoint [_cur_pos, 0];
	_wp setWaypointType "MOVE";
	_wp setWaypointCompletionRadius (5 + _slack);
	[_grp,_j+i] setWaypointTimeout [0, 2, 16];
	// When completing waypoint have 33% chance to choose a random next wp
	[_grp,_j+i] setWaypointStatements ["true", "if ((random 3) > 2) then { group this setCurrentWaypoint [(group this), (floor (random (count (waypoints (group this)))))];};"];

	if (_debug > 0) then {
		_marker_name = str(_wp_array select _i);
		_marker = createMarker[_marker_name,[_cur_pos select 0,_cur_pos select 1]];
		_marker setMarkerShape "ICON";
		_marker_name setMarkerType "DOT";
	};

	sleep 0.5;
};

// End back near start point and then pick a new random point
_wp1 = _grp addWaypoint [_pos, 0];
_wp1 setWaypointType "SAD";
_wp1 setWaypointCompletionRadius (random (_max_dist));
[_grp,(count waypoints _grp)] setWaypointStatements ["true", "group this setCurrentWaypoint [(group this), (round (random 2) + 1)];"];

// Cycle in case we reach the end
_wp2 = _grp addWaypoint [_pos, 0];
_wp2 setWaypointType "CYCLE";
_wp2 setWaypointCompletionRadius 100;

true
};

Share this post


Link to post
Share on other sites

Here's my latest version. Not sure what the differences are, if any:

/*
=======================================================================================================================
Script: BIN_taskPatrol.sqf v1.4
Author(s): Binesi
Partly based on original code by BIS

Description:
Creates a continually randomized patrol path which circles and intersects a given position.

Parameter(s):
_this select 0: the group to which to assign the waypoints (Group)
_this select 1: the position on which to base the patrol (Array)
_this select 2: the maximum distance between waypoints (Number)
_this select 3: (optional) debug markers on or off (Number)
_this select 4: (optional) blacklist of areas (Array)

Returns:
Boolean - success flag

Example(s):
null = [group this,(getPos this),250] execVM "BIN_taskPatrol.sqf"
null = [group this,(getPos this),250,1] execVM "BIN_taskPatrol.sqf" // Same with debug markers

-----------------------------------------------------------------------------------------------------------------------
Notes: Wolffy.au
If anyone is interested, I've made some additions to Binesi's BIN_taskPatrol script.
Random initial patrol direction - I noticed every patrol started off in the same direction, so I've randomised it.
Fixed the 2D position / findSafePos errors
Added building positions as possible patrol locations using Random Building Position Script v1.0 by Tophe of Östgöta Ops
Added check that BIS Functions has been initialised
Only perform the house patrols if the squad leader is a man

ArmaIIholic 
-- added part of JTD direction normalization function
-- changed numbers for waypoints to match previous waypoints
-- randomized initial direction -- Wolffy.au added only the offset which had to be reduced to 180 
          - however this script is making full circle from wherever it starts

=======================================================================================================================
*/

_grp = _this select 0;
_pos = _this select 1;
_max_dist = _this select 2;
_debug = if ((count _this) > 3) then {_this select 3} else {0};
_blacklist = if ((count _this) > 4) then {_blacklist = _this select 4} else {[]};

waitUntil {!isNil "bis_fnc_init"}; 
_mode = ["YELLOW", "RED"] call BIS_fnc_selectRandom;
_formation = ["STAG COLUMN", "WEDGE", "ECH LEFT", "ECH RIGHT", "VEE", "DIAMOND"] call BIS_fnc_selectRandom;

_grp setBehaviour "AWARE";
_grp setSpeedMode "LIMITED";
_grp setCombatMode _mode;
_grp setFormation _formation;

_center_x = (_pos) select 0;
_center_y = (_pos) select 1;
_center_z = (_pos) select 2;
if(isNil "_center_z")then{_center_z = 0;};

_wp_count = 4 + (floor random 3) + (floor (_max_dist / 100 ));
_angle = (360 / (_wp_count -1));

_new_angle = 0;
_wp_array = [];
_slack = _max_dist / 5.5;
if ( _slack < 20 ) then { _slack = 20 };

_setdir = round (random 1);

_angle_offset = random 180;
while {count _wp_array < _wp_count} do 
{
	private ["_x1","_y1","_wp_pos", "_prepos","_bldgpos","_bldgs"];

	_newangle = (count _wp_array * _angle) + _angle_offset;

	if ((_newangle > 360) || (_newangle < 0)) then
	{
		_newangle = abs (abs (_newangle) - 360);
	};

	if (_setdir == 1) then 
	{
		_newangle = -_newangle;

		if ((_newangle > 360) || (_newangle < 0)) then
		 {
			_newangle = abs (abs (_newangle) - 360);
		 };
	};

	_x1 = _center_x - (sin _newangle * _max_dist);
	_y1 = _center_y - (cos _newangle * _max_dist);

	_prepos = [_x1, _y1, _center_z];
	if ( isNil "_center_z" ) then {
		_prepos = [_x1, _y1];
	};

	_wp_pos = [_prepos, 0, _slack, 6, 0, 50 * (pi / 180), 0, _blacklist] call BIS_fnc_findSafePos;

if (leader _grp isKindOf "Man") then {		
	//////////////////////////////////////////////////////////////////
	// The following code is an extract from Random Building Position Script v1.0 by Tophe of Östgöta Ops
	//////////////////////////////////////////////////////////////////
	_bldgpos = [];
	_bldgs = nearestObjects [_wp_pos, ["Building"], 50];
	{
	  private["_i","_y"];
		_i = 0;
		_y = _x buildingPos _i;
		while {format["%1", _y] != "[0,0,0]"} do {
			_bldgpos = _bldgpos + [_y];
			_i = _i + 1;
			_y = _x buildingPos _i;
		};
	} forEach _bldgs;

	if(count _bldgpos != 0) then {_wp_pos = _bldgpos call BIS_fnc_selectRandom;};
	_wp_array = _wp_array + [_wp_pos];

	sleep 0.5;
};
};

sleep 1;

_j = count (waypoints _grp);

for "_i" from 1 to (_wp_count - 1) do
{
	private ["_wp","_cur_pos","_marker","_marker_name"];

	_cur_pos = (_wp_array select _i);

	// Create waypoints based on array of positions
	/* The index i is changed so it matches the FSM - j+i */

	_wp = _grp addWaypoint [_cur_pos, 0];
	_wp setWaypointType "MOVE";
	_wp setWaypointCompletionRadius (5 + _slack);
	[_grp,_j+i] setWaypointTimeout [0, 2, 16];
	// When completing waypoint have 33% chance to choose a random next wp
	[_grp,_j+i] setWaypointStatements ["true", "if ((random 3) > 2) then { group this setCurrentWaypoint [(group this), (floor (random (count (waypoints (group this)))))];};"];

	if (_debug > 0) then {
		_marker_name = str(_wp_array select _i);
		_marker = createMarker[_marker_name,[_cur_pos select 0,_cur_pos select 1]];
		_marker setMarkerShape "ICON";
		_marker_name setMarkerType "DOT";
	};

	sleep 0.5;
};

// End back near start point and then pick a new random point
_wp1 = _grp addWaypoint [_pos, 0];
_wp1 setWaypointType "SAD";
_wp1 setWaypointCompletionRadius (random (_max_dist));
[_grp,(count waypoints _grp)] setWaypointStatements ["true", "group this setCurrentWaypoint [(group this), (round (random 2) + 1)];"];

// Cycle in case we reach the end
_wp2 = _grp addWaypoint [_pos, 0];
_wp2 setWaypointType "CYCLE";
_wp2 setWaypointCompletionRadius 100;

true

Share this post


Link to post
Share on other sites

Wolffy.au, your version doesn't have a and b I implemented since I had problem with number of elements provided and their format....

---

Share this post


Link to post
Share on other sites

Got a fun bug...

I've been using TaskPatrol 1.4 on the new Mana Island map and noted that it will set waypoints in the water for squads, which makes them swim and drop their primary weapon.

Nothing more bizarre than being rushed by guys with pistols.

Anyway, I could set blacklist areas over the water, but I noticed this is also a potential issue on any map where there is water in the patrol area.

Not being a strong scripter I'm not sure how to resolve this.

Is there an easy fix?

Share this post


Link to post
Share on other sites

I haven't tried to create my own maps yet, but maybe the designer has to indicate where the water is for the BIS_fnc_findSafePos function to work?

Can someone confirm if that is true?

If so, let the Mana developer know and use blacklisting in the interim. No easy fix I can think of.

Share this post


Link to post
Share on other sites

is it posssible to set this in a trigger so the chopper remains grounded until he is called in to action?

Share this post


Link to post
Share on other sites

You can call this any time as long as your chopper is in a group.

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

×