Jump to content
Sign in to follow this  
katipo66

Guard behavior using CBA_fnc_taskPatrol or similar

Recommended Posts

When using this in a trigger:


[this, this, 700, 7, "MOVE", "AWARE", "YELLOW", "FULL", "STAG COLUMN", 
"[this] spawn CBA_fnc_searchNearby", [3,6,9]] call CBA_fnc_taskPatrol; 

Or actually any situation in the editor, how can i make AI support each other, as they would with a guard trigger, i realize i could simply give them a guard waypoint but the idea is i want them to moving.

Its depressing watching AI not react to a firefight less than 200mtrs from their position

Edited by Katipo66

Share this post


Link to post
Share on other sites

experimented a little and came up with this:

testing done in editor, seems to work ok.

I tested with 4 groups, but i think there is no problem using 100 groups, but the response time might be a little lower.

purpose of script is to execute the script and collect wich groups are communicating.

now these units, will when detecting a enemy, reveal it to the other groups in this script, and all will change their current waypoint to a guard waypoint at their current position, speed to full, fire at will etc, then when there is no more enemys detected, current waypoint is changed back to what it originally was and then placed at its original position.

This way groups can patrol several waypoints, and go into guard mode imediatly at full speed when being made aware by one of the other groups in the script.

Try it and let me know how it works.

save this as support.sqf and place in your mission folder.

//  how about changing the waypoints to a guardpoint when enemys are present,
//  and back again to original when enemys are not present:
//  execute with placing in a script or a trigger or a object initline:
//  _null = [leader_group1, leader_group2, leader_group3] execVM "support.sqf";


_support = {
_idx = currentWaypoint _this;
_cwp = waypointType [_this,_idx];
_bwp = waypointBehaviour [_this,_idx];
_swp = waypointSpeed [_this,_idx];
_cmwp = waypointCombatMode [_this,_idx];
_pos = getWPPos [_this, _idx];
if (_cwp != "GUARD") then {
	[_this, _idx] setWPPos (getPos (leader _this));
	[_this, _idx] setWaypointType "GUARD";
	// this is the extra changes to speed combat mmode etc changed when in guard mode, its returned to original after guard mode is done.
	if (_bwp != "AWARE") then {
		[_this, _idx] setWaypointBehaviour "AWARE";
	};
	if (_swp != "FULL") then {
		[_this, _idx] setWaypointSpeed "FULL";
	};
	if (_cmwp != "RED") then {
		[_this, _idx] setWaypointCombatMode "RED";
	};

	while {!isNull((leader _this) findNearestEnemy (leader _this))} do {
		waitUntil { isNull((leader _this) findNearestEnemy (leader _this)) };
		sleep 60;
	};
	[_this, _idx] setWPPos _pos;
	[_this, _idx] setWaypointType _cwp;
	[_this, _idx] setWaypointBehaviour _bwp;
	[_this, _idx] setWaypointSpeed _swp;
	[_this, _idx] setWaypointCombatMode _cmwp;
	_this setCurrentWaypoint [_this, _idx];
};
};

_leaders = _this;
_groups = [];
{
_groups = _groups + [(group _x)];
} foreach _leaders;

while {(count _groups) != 0} do {
{
	_grp = _x;
	if (({alive _x} count units _grp) != 0) then {
		_lead = leader _grp;
		_nearestEnemy = (leader _grp) findNearestEnemy (leader _grp);
		if (!isNull _nearestEnemy) then {
			_null = [_groups,_nearestEnemy] spawn {
				sleep round(random 5);
				_groups = _this select 0;
				_nearestEnemy = _this select 1;
				{
					(leader _x) reveal _nearestEnemy;
				} foreach _groups;
			};
			_null = _grp spawn _support;
		};
	} else {
		_groups = _groups - [_grp];
	};
} foreach _groups;
sleep 5;
};

Share this post


Link to post
Share on other sites

Thanks Demonized, sounds exactly what I'm after. I'll try it out tonight after work

Share this post


Link to post
Share on other sites

I tested it quickly before work, and it didnt seem to work properly, it was like they never completely ignored the firefight as the last guy in the group kept stopping and looking back as if to say maybe we should go help :p then they would take of somewhere quickly as if the Guard waypoint settings kicked in, but not to where the firefight is, usually the wrong direction.

i tested in Shapur like this:

  • I placed 3 groups - 2 opfor 1 blufor

  • saved the script as support.sqf in mission folder

  • I gave 1 opfor and 1 blufor group move waypoints to force engagement

  • I put the CBA_fnc_taskPatrol script in init of group leader of remaining opfor group

  • i placed a trigger with _null = [leader_group1, leader_group2, leader_group3] execVM "support.sqf"; in on act

  • I also tried calling it from an init.sqf

  • I also named the groups group1, group2 etc to see if that was required

Ill test properly again tonight, maybe ive missed a step somewhere?

Share this post


Link to post
Share on other sites

So... it Works just as you say.. it helps if i name the group leaders leader_group1, leader_group2 etc :o

Bro, this is sweeet! thank you very much :yay::D

Share this post


Link to post
Share on other sites

yes leader_group1 was just name of group leader, i should maybe have typed groupLeader1Name, ill remember that for another time.

glad you got it working. :)

Share this post


Link to post
Share on other sites

I have tried to add support.sqf for all groups with variations on the allGroups command that im to embarrassed to show, how can i do this?

Share this post


Link to post
Share on other sites
I have tried to add support.sqf for all groups with variations on the allGroups command that im to embarrassed to show, how can i do this?

allLeaders = [];
{allLeaders = allLeaders + [(leader _x)]} foreach allGroups;
_null = allLeaders execVM "support.sqf";

;)

Edit: im am not totally sure why i used the leadername instead of the group to begin with, but im guessing it was to be easier on the non scripters maybe..

changing this part:

_leaders = _this;
_groups = [];
{
_groups = _groups + [(group _x)];
} foreach _leaders;

to:

_groups = _this;

will make it work with groups instead of leaders.

Edited by Demonized

Share this post


Link to post
Share on other sites

Cool bro, that worked but it gives a script error:

Error in expression <\support.sqf"

_support = {

_idx = currentWaypoint _this;

_cwp = waypointTy>

Error position: <currentWaypoint _this;

_cwp = waypointTy>

Error currentwaypoint: Type Object, expected Group

I did something random like replace _this with _group wich removed the error but of course destroyed the script

Share this post


Link to post
Share on other sites

like this i mean, now you can use allGroups instead of [group1, group2, group3, group4]

_null = allGroups execVM "support.sqf";

//  how about changing the waypoints to a guardpoint when enemys are present,
//  and back again to original when enemys are not present:
//  execute with placing in a script or a trigger or a object initline:
//  _null = [group1, group2, group3, group4] execVM "support.sqf";


_support = {
_idx = currentWaypoint _this;
_cwp = waypointType [_this,_idx];
_bwp = waypointBehaviour [_this,_idx];
_swp = waypointSpeed [_this,_idx];
_cmwp = waypointCombatMode [_this,_idx];
_pos = getWPPos [_this, _idx];
if (_cwp != "GUARD") then {
	[_this, _idx] setWPPos (getPos (leader _this));
	[_this, _idx] setWaypointType "GUARD";
	// this is the extra changes to speed combat mmode etc changed when in guard mode, its returned to original after guard mode is done.
	if (_bwp != "AWARE") then {
		[_this, _idx] setWaypointBehaviour "AWARE";
	};
	if (_swp != "FULL") then {
		[_this, _idx] setWaypointSpeed "FULL";
	};
	if (_cmwp != "RED") then {
		[_this, _idx] setWaypointCombatMode "RED";
	};

	while {!isNull((leader _this) findNearestEnemy (leader _this))} do {
		waitUntil { isNull((leader _this) findNearestEnemy (leader _this)) };
		sleep 60;
	};
	[_this, _idx] setWPPos _pos;
	[_this, _idx] setWaypointType _cwp;
	[_this, _idx] setWaypointBehaviour _bwp;
	[_this, _idx] setWaypointSpeed _swp;
	[_this, _idx] setWaypointCombatMode _cmwp;
	_this setCurrentWaypoint [_this, _idx];
};
};

_groups = _this;

while {(count _groups) != 0} do {
{
	_grp = _x;
	if (({alive _x} count units _grp) != 0) then {
		_lead = leader _grp;
		_nearestEnemy = (leader _grp) findNearestEnemy (leader _grp);
		if (!isNull _nearestEnemy) then {
			_null = [_groups,_nearestEnemy] spawn {
				sleep round(random 5);
				_groups = _this select 0;
				_nearestEnemy = _this select 1;
				{
					(leader _x) reveal _nearestEnemy;
				} foreach _groups;
			};
			_null = _grp spawn _support;
		};
	} else {
		_groups = _groups - [_grp];
	};
} foreach _groups;
sleep 5;
};

Share this post


Link to post
Share on other sites

Perfect! cool script.. thanks again bro :)

Share this post


Link to post
Share on other sites

This script works perfectly, but i was thinking off how it might be better.

//  how about changing the waypoints to a guardpoint when enemys are present,
//  and back again to original when enemys are not present:
//  execute with placing in a script or a trigger or a object initline:
//  _null = [group1, group2, group3, group4] execVM "support.sqf";


_support = {
_idx = currentWaypoint _this;
_cwp = waypointType [_this,_idx];
_bwp = waypointBehaviour [_this,_idx];
_swp = waypointSpeed [_this,_idx];
_cmwp = waypointCombatMode [_this,_idx];
_pos = getWPPos [_this, _idx];
if (_cwp != "GUARD") then {
	[_this, _idx] setWPPos (getPos (leader _this));
	[_this, _idx] setWaypointType "GUARD";
	// this is the extra changes to speed combat mmode etc changed when in guard mode, its returned to original after guard mode is done.
	if (_bwp != "AWARE") then {
		[_this, _idx] setWaypointBehaviour "AWARE";
	};
	if (_swp != "FULL") then {
		[_this, _idx] setWaypointSpeed "FULL";
	};
	if (_cmwp != "RED") then {
		[_this, _idx] setWaypointCombatMode "RED";
	};

	while {!isNull((leader _this) findNearestEnemy (leader _this))} do {
		waitUntil { isNull((leader _this) findNearestEnemy (leader _this)) };
		sleep 60;
	};
	[_this, _idx] setWPPos _pos;
	[_this, _idx] setWaypointType _cwp;
	[_this, _idx] setWaypointBehaviour _bwp;
	[_this, _idx] setWaypointSpeed _swp;
	[_this, _idx] setWaypointCombatMode _cmwp;
	_this setCurrentWaypoint [_this, _idx];
};
};

_groups = _this;

while {(count _groups) != 0} do {
{
	_grp = _x;
	if (({alive _x} count units _grp) != 0) then {
		_lead = leader _grp;
		_nearestEnemy = (leader _grp) findNearestEnemy (leader _grp);
		if (!isNull _nearestEnemy) then {
			_null = [_groups,_nearestEnemy] spawn {
				sleep round(random 5);
				_groups = _this select 0;
				_nearestEnemy = _this select 1;
				{
					(leader _x) reveal _nearestEnemy;
				} foreach _groups;
			};
			_null = _grp spawn _support;
		};
	} else {
		_groups = _groups - [_grp];
	};
} foreach _groups;
sleep 5;
};

What im thinking is <1000 and sleep mins?, so that any units inside the given radius will respond immediately, other units outside will only respond after 5 - 10mins? if that time length is possible and if threat is still exists.

{if (_x distance _nearestEnemy>1000) then {sleep mins?}} forEach _groups}}

:o me no code

Thinking behind this is to prevent every unit on the map moving to support instantly but will support if threat is ongoing.

Edited by Katipo66

Share this post


Link to post
Share on other sites

the way guard waypoints work is that only 1 unit will be called in to support the unit spotting a enemy, there is also some size of threat that determines amount of guarding groups to come to support.

i believe the closest one will always come first to support.

Anyway, yeah having a range check so the "patroling" units will not stop and guard when anyone spots a enemy is a good idea, adjust number at top to what works with your mission.

I added a range thing, its highlighted below:

//  how about changing the waypoints to a guardpoint when enemys are present,
//  and back again to original when enemys are not present:
//  execute with placing in a script or a trigger or a object initline:
//  _null = [group1, group2, group3, group4] execVM "support.sqf";

[b][i]_comRange = 1000;[/i][/b]  // max range in meter to friendly groups that are alerted.
_support = {
_idx = currentWaypoint _this;
_cwp = waypointType [_this,_idx];
_bwp = waypointBehaviour [_this,_idx];
_swp = waypointSpeed [_this,_idx];
_cmwp = waypointCombatMode [_this,_idx];
_pos = getWPPos [_this, _idx];
if (_cwp != "GUARD") then {
	[_this, _idx] setWPPos (getPos (leader _this));
	[_this, _idx] setWaypointType "GUARD";
	// this is the extra changes to speed combat mmode etc changed when in guard mode, its returned to original after guard mode is done.
	if (_bwp != "AWARE") then {
		[_this, _idx] setWaypointBehaviour "AWARE";
	};
	if (_swp != "FULL") then {
		[_this, _idx] setWaypointSpeed "FULL";
	};
	if (_cmwp != "RED") then {
		[_this, _idx] setWaypointCombatMode "RED";
	};

	while {!isNull((leader _this) findNearestEnemy (leader _this))} do {
		waitUntil { isNull((leader _this) findNearestEnemy (leader _this)) };
		sleep 60;
	};
	[_this, _idx] setWPPos _pos;
	[_this, _idx] setWaypointType _cwp;
	[_this, _idx] setWaypointBehaviour _bwp;
	[_this, _idx] setWaypointSpeed _swp;
	[_this, _idx] setWaypointCombatMode _cmwp;
	_this setCurrentWaypoint [_this, _idx];
};
};

_groups = _this;
while {(count _groups) != 0} do {
{
	_grp = _x;
	if (({alive _x} count units _grp) != 0) then {
		_lead = leader _grp;
		_nearestEnemy = (leader _grp) findNearestEnemy (leader _grp);
		if (!isNull _nearestEnemy) then {
			_null = [_groups,_nearestEnemy] spawn {
				sleep round(random 5);
				_groups = _this select 0;
				_nearestEnemy = _this select 1;
				{
					[b][i]if ( ((leader _x) distance (leader _grp)) <= _comRange) then {[/i][/b]
						(leader _x) reveal _nearestEnemy;
					};
				} foreach _groups;
			};
			_null = _grp spawn _support;
		};
	} else {
		_groups = _groups - [_grp];
	};
} foreach _groups;
sleep 5;
};

i did not include any delay, but you can add that with replacing this section:

					{
					if ( ((leader _x) distance (leader _grp)) <= _comRange) then {
						(leader _x) reveal _nearestEnemy;
					};
				} foreach _groups;

with this one:

					{
					if ( ((leader _x) distance (leader _grp)) <= _comRange) then {
						(leader _x) reveal _nearestEnemy;
					} else {
						_null = [(leader _x)_grp,_nearestEnemy] spawn {
							_lead = _this select 0;
							_enemy = _this select 2;
							_delay = (_lead distance (_this select 1))/60;  // here delay is range divided with 60, wich gives ca 16 minutes on a 1000 range, increase or lower 60 to get more or less delay, or simply replace line with [b]_delay = yourNumberInSeconds;[/b]
							sleep _delay;
							if (alive _enemy) then {_lead reveal _enemy};
						};
					};
				} foreach _groups;

Share this post


Link to post
Share on other sites
the way guard waypoints work is that only 1 unit will be called in to support the unit spotting a enemy, there is also some size of threat that determines amount of guarding groups to come to support. i believe the closest one will always come first to support.

The mighty guard waypoint has got it covered!

Awesome bro! really appreciate that :D

Bit late to test it out now, test it tomorrow.

Edited by Katipo66

Share this post


Link to post
Share on other sites

Unfortunately his one does'nt work,

I rolled my sleeves up and tried to find where but cannot, i did find that maybe the time delay option had an extra closing '};'

this didnt work on its own or with the time delay option added, or if i set the range to 9000 on utes?

Share this post


Link to post
Share on other sites

yes, i forgot to include the group and the distance in a spawn.

here below is updated in highlighted area, and untested.

//  how about changing the waypoints to a guardpoint when enemys are present,
//  and back again to original when enemys are not present:
//  execute with placing in a script or a trigger or a object initline:
//  _null = [group1, group2, group3, group4] execVM "support.sqf";

_comRange = 1000;  // max range in meter to friendly groups that are alerted.
_support = {
_idx = currentWaypoint _this;
_cwp = waypointType [_this,_idx];
_bwp = waypointBehaviour [_this,_idx];
_swp = waypointSpeed [_this,_idx];
_cmwp = waypointCombatMode [_this,_idx];
_pos = getWPPos [_this, _idx];
if (_cwp != "GUARD") then {
	[_this, _idx] setWPPos (getPos (leader _this));
	[_this, _idx] setWaypointType "GUARD";
	// this is the extra changes to speed combat mmode etc changed when in guard mode, its returned to original after guard mode is done.
	if (_bwp != "AWARE") then {
		[_this, _idx] setWaypointBehaviour "AWARE";
	};
	if (_swp != "FULL") then {
		[_this, _idx] setWaypointSpeed "FULL";
	};
	if (_cmwp != "RED") then {
		[_this, _idx] setWaypointCombatMode "RED";
	};

	while {!isNull((leader _this) findNearestEnemy (leader _this))} do {
		waitUntil { isNull((leader _this) findNearestEnemy (leader _this)) };
		sleep 60;
	};
	[_this, _idx] setWPPos _pos;
	[_this, _idx] setWaypointType _cwp;
	[_this, _idx] setWaypointBehaviour _bwp;
	[_this, _idx] setWaypointSpeed _swp;
	[_this, _idx] setWaypointCombatMode _cmwp;
	_this setCurrentWaypoint [_this, _idx];
};
};

_groups = _this;
while {(count _groups) != 0} do {
{
	_grp = _x;
	if (({alive _x} count units _grp) != 0) then {
		_lead = leader _grp;
		_nearestEnemy = (leader _grp) findNearestEnemy (leader _grp);
		if (!isNull _nearestEnemy) then {
			_null = [_groups,_nearestEnemy,[b]_grp,_comRange[/b]] spawn {
				sleep round(random 5);
				_groups = _this select 0;
				_nearestEnemy = _this select 1;
				[b]_grp = _this select 2;[/b]
				[b]_comRange = _this select 3;[/b]
				{
					if ( ((leader _x) distance (leader _grp)) <= _comRange) then {
						(leader _x) reveal _nearestEnemy;
					};
				} foreach _groups;
			};
			_null = _grp spawn _support;
		};
	} else {
		_groups = _groups - [_grp];
	};
} foreach _groups;
sleep 5;
};

Share this post


Link to post
Share on other sites

Well, everything worked, including time delay!

Thanks again! i owe you a beer bro! :pc:

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
Sign in to follow this  

×