Jump to content
Sign in to follow this  
special ed

AI aggressive combat behavior - CreateGroup and JoinSilent - a community topic -

Recommended Posts

I saw a topic recently come up about someone wanting to get their Ai units to advance under fire, and so I started getting into trying to write a script, after an hour and a half, I realized that although I have pulled this off for my own mission, I don't have the time to be able to invest hours into transforming what I have discovered into a script that really works more universally for other people. So, I really feel like I should at least share what I found, and if the community can do something with it, grow/expand it for other people to use it, great :)

It is Very possible to get the AI to go into an aggressive mode of combat while engaging an enemy, and the key is simply to get the units to regularly join a new tempgroup. This probably sounds way too simple, but there are issues that I have not delved into. Main issue is first that the original group is lost unless the whole thing is managed so the original group always has one unit left in it. Second thing, is I don't really know if this actually works to just add all units to a separate new group, or if it only works the way I have gotten it to work, which is to put all group units into separate new temp groups and move them forward. So, keeping the initial group intact is the main thing for people that need it, along with a few other things. Lastly, stance may be an issue, as in my mission I have force scripted stance changes, to keep the units out of prone unless they are 100 meters or more away from an enemy, and so normally I have a 1-7 chance to set to middle, 7 - 10 chance of upright.

Here is the code sample of what I am using in my mission, and it works "extremely" well. The units by default, will advance to a DoMove position shortly after an engagement if they no longer have a target (roughly 5 seconds), and they will stop upon gaining a target and fire, the ai still has some sway as to getting some units to execute minor (short radius) flanking on occasion, and units move at different speeds. I should also note that in my mission, units are actually being DoMoved directly to the last known enemy location, so this method can be used to force units to directly move towards enemy units. With the combination of the use of NearTargets, this method can actually be used to create an aggressive ai behavior that will move units towards the last known enemy position (using position accuracy).


_MovePosition = (GetMarkerPos "MyMarkerName");

_Group_Array = units _Group;

{
[_x,_MovePosition] ExecVM "DoMoveUnits.sqf";
} forEach _Group_Array;

DoMoveUnits.sqf

//[_x,_myEnemyPos] spawn DoMoveUnits;

private ["_Unit","_Timer","_MovePosition","_GroupD","_UnitSide","_TempGroup","_RandomNumA"];

_Unit = _this select 0;
_MovePosition = _this select 1;
_Timer = 0;
_GroupD = group _Unit;
//Added disableai Target here for now
_Unit disableAI "TARGET";
_UnitSide = (side _Unit);

//Have put in a portion of the setstance code here, can disable it if desired
_RandomNumA = (random 10);
	if (_RandomNumA > 7) then
	{
	_Unit setUnitPos "UP";

	} Else {

	_Unit setUnitPos "MIDDLE";

	};

Uisleep (random 3 + (2));

while {alive _Unit && (_Timer < 100)} do {
_Timer = (_Timer + 1);

_TempGroup = createGroup _UnitSide;

[_Unit] joinSilent _TempGroup;

_TempGroup setBehaviour "COMBAT";

_Unit DoMove _MovePosition;

Uisleep (random 4 + (3));

};

And that is a cut down, basic version of the script that my mission uses, keeping things out that are non relevant to the primary function here. I've gone on a search for some time to get something like this to work, and saw others posting here as well trying to find it with basically no luck, so I certainly feel like I should at least post this, whether it gets used and/or expanded upon or not.

Again, the script posted works per unit, and testing would be required to see if it still works to put all units directly into one temp group rather than separate ones.

Share this post


Link to post
Share on other sites

Have you tried out enableAttack? It prevents the group leader from giving commands to his subordinates so they act according to their own knowledge and (for the lack of a better word) judgement. It might be preferable perfomance wise to creating new groups.

Share this post


Link to post
Share on other sites

I was also thinking this could be a big performance hit depending on the number of groups in contact at the same time.

Share this post


Link to post
Share on other sites

I haven't tried enableAttack, although for my particular mission I use a lot of one man groups. Honestly I have gone about as far as I am going to with the method of getting Ai to behave in an aggressive fashion, as for my own missions I'm pretty happy with the results, I just wanted to share the discovery here, in case others may be interested in doing something more with the concept. As far as Cpu usage goes due to the increase in groups functioning in one combat scenario where bigger battles may happen, it is possible this method could work to simply put all of the units in a group directly into one new group instead of them being separated, so they would still be one group, and then possibly loop the script if desired, but it would require testing to ensure the ai was still acting in an aggressive fashion. Just wanted to put this out there.

Share this post


Link to post
Share on other sites

thanks, will do some experimenting. Always grappled with the challenge of keeping AI moving toward the target. Especially when player have helicopter or plane flying around, they go prone and wait for awhile. Really slows down tempo of assault this behaviour.

I wonder what it does? Does the group hold nearTargets/knowsAbout memory, and joining a new group makes the AI not know about enemies, therefore advance?

Perhaps a looping knowsAbout reset could accomplish similar without the group juggling?

Sorry about the formatting, just brainstorming in chat:

fnReveal = {

private ["_enemyUnits"];

_enemyUnits = [];

{if ((side _x) isEqualTo enemySide) then {0 = _enemyUnits pushBack _x;};} count allUnits;

{(_this select 0) reveal [_x,0];} count _enemyUnits;

};

attacking = TRUE;

while {attacking} do {

{

if (_x getVariable "aggressive_group") then {

_x call fnReveal;

_x setBehaviour "AWARE";

};

} count allGroups;

sleep 60;

};

Edited by MDCCLXXVI

Share this post


Link to post
Share on other sites

I wonder what it does? Does the group hold nearTargets/knowsAbout memory, and joining a new group makes the AI not know about enemies, therefore advance?

I have only guessed at this, as I was pretty happy, just before quitting on trying to force ai units in combat to move I stumbled on the group thing, and just kinda went with the flow. There's a script posted here where the author uses the group swap to get units to move in combat to execute guerrilla type tactics, and I tried just looping the commands to see if units would actually move forward towards an enemy this way, and surprisingly it worked.

Here is the thread, the script is like 4 posts down on the front page :

http://forums.bistudio.com/showthread.php?136519-AI-Guerrilla-Tactics&highlight=findnearestenemy

I found the script hard to read because it looks like a pretty elaborate complex system written there, but the group swap is there towards the bottom.

Edited by Special Ed

Share this post


Link to post
Share on other sites
thanks, will do some experimenting. Always grappled with the challenge of keeping AI moving toward the target. Especially when player have helicopter or plane flying around, they go prone and wait for awhile. Really slows down tempo of assault this behaviour.

I wonder what it does? Does the group hold nearTargets/knowsAbout memory, and joining a new group makes the AI not know about enemies, therefore advance?

Perhaps a looping knowsAbout reset could accomplish similar without the group juggling?

Sorry about the formatting, just brainstorming in chat:

fnReveal = {

private ["_enemyUnits"];

_enemyUnits = [];

{if ((side _x) isEqualTo enemySide) then {0 = _enemyUnits pushBack _x;};} count allUnits;

{(_this select 0) reveal [_x,0];} count _enemyUnits;

};

attacking = TRUE;

while {attacking} do {

{

if (_x getVariable "aggressive_group") then {

_x call fnReveal;

_x setBehaviour "AWARE";

};

} count allGroups;

sleep 60;

};

Ran some MP tests with this. Approx 10 players vs a few AI fireteams spawned locally via Curator module, all the code run local. Didn't notice anything different from normal behaviour, so I would say it is not a good way to make them more aggressive. The premise is to wipe their knowledge of enemies, and thus put them back into 'move forward' behaviour. It also is not cheap performance-wise, as for each unit it is looping through the allUnits array to find enemy units.

The code used:

QS_fnReveal = {
private ["_enemyUnits","_unit"];
_unit = _this select 0;
_enemyUnits = [];
{
	if ((side _x) isEqualTo west) then {
		0 = _enemyUnits pushBack _x;
	};
} count allUnits;
if ((count _enemyUnits) > 0) then {
	{
		_unit reveal [_x,0];
	} count _enemyUnits;
};
}; 

/////////

[] spawn {
private ["_group"];
QS_attackTest = TRUE;
while {QS_attackTest} do {
	{
		_group = _x;
		if (_group getVariable "QS_aggressive_group") then {
			{0 = [_x] call QS_fnReveal;} count (units _group);
			systemChat "Aggression";
		};
	} count allGroups;
	sleep 15;
};
};

///////////

(group this) setVariable ["QS_aggressive_group",TRUE];

Edited by MDCCLXXVI

Share this post


Link to post
Share on other sites

/edit

My bad - misread post there

Edited by Special Ed

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  

×