Jump to content
Sign in to follow this  
-Coulum-

Ai suppression script help

Recommended Posts

Woops - ok made a goof. Those 200 numbers were off because I was looking thru the DMR scope most of the mission which seems to give a +20-30 FPS! Honestly the FPS is jumping a little tto much but it definitely drops when you get the "AI Suppressed" messages -until it reaches a Minimum in which case it doesnt really drop any more.

Yes, all Infantry on either side of the airport with Search and Destroy Waypoints for all. I would say the 200 is a little slow but still playable and I just did 100 which went smooth without a hitch (Ill get average later).

On a side note -when did Vanilla AI start giving engage orders for 1500m targets?!? I havent played without ACE/ASR in so long I hadn't noticed but it seems routine here. I am using latest patch as well.

Share this post


Link to post
Share on other sites

Thanks for offering to sacrifice your computer froggyluv! To be honest I'm not surprised that hundreds of units stresses out the computer. For a bullet detection script to work it has to run essentially every frame, and with hundreds of checks it's bound to slow things down, especially if all of the units are firing. Hundreds of AI all firing is really a worst case scenario. For smaller numbers of units it works surprisingly well, even on a much lower specced computer. I couldn't get a 300 AI battle going on my box, let alone do suppression stuff!

Currently the script is not actually checking every bullet around a unit, just checking if there are any bullets around a unit. And it only runs per-unit bullet detection if there is an active bullet object on the map. The only thing I could think of to really speed things up is for the bullet detection stuff to only be run on units within say 300m of a human player, and let the more distant units duke it out with default AI behaviour. And while I'm at it, -Coulum- is right and we should probably exclude units in vehicles.

All good food for thought.

EDIT: Sorry for the stupid questions froggyluv, but are you using the latest version of the script 20120619 (on the first post)? It won't throw up any "suppressed" messages, only the older less optimised versions of the script will do that. And secondly, you are only running the script the once right? It doesn't need to be put in each unit's init. The reason I ask is that your behemoth of a computer should be eating this script for breakfast, if mine can run things OK.

Edited by tpw

Share this post


Link to post
Share on other sites

Hmmm, well Ive been copying and pasting code over the previous SQF's -but maybe I goofed somehwere...

Here is Init.SQF:

_fired = player addEventHandler ["fired", {_this execVM "side.sqf"}]; 

and here is main code I named Side.SQF

// ALL UNITS ON MAP WILL DROP IF BULLETS FROM ENEMIES AWAY PASS WITHIN 10m 
// BULLETS FROM OWN SIDE ARE IGNORED 
// BULLETS FROM SMG AND PISTOLS ARE IGNORED 
// Original code idea by -Coulum- 
// TPW 20120619  
//Start hint 
0 = [] spawn {sleep 3;hintsilent "AI suppress active"; sleep 3; hintsilent ""}; 
private ["_supnextime","_unit","_bc","_shots","_side"];  
//Pistol and SMG  ammo to ignore 
tpw_mags =["30rnd_9x19_MP5", 
"30rnd_9x19_MP5SD", 
"15Rnd_9x19_M9", 
"15Rnd_9x19_M9SD", 
"7Rnd_45ACP_1911", 
"8Rnd_9x18_Makarov", 
"8Rnd_9x18_MakarovSD", 
"64Rnd_9x19_Bizon", 
"64Rnd_9x19_SD_Bizon", 
"13Rnd_9mm_SLP", 
"17Rnd_9x19_glock17", 
"6Rnd_45ACP", 
"30Rnd_9x19_UZI", 
"30Rnd_9x19_UZI_SD"]; 
//Main function 
tpw_sup =   
{  
   { 
   _unit = _x;  
   _SupNextTime = _unit getVariable ["SupNextTime", -1];  
   if (_SupNextTime == -1) then  
       { 
       _unit setVariable ["SupNextTime", diag_tickTime]; 
       _unit setvariable ["SIDE", (side _unit)];   
       _unit addeventhandler ["Fired",{tpw_fired = (_this select 0) getvariable "SIDE";tpw_mag = _this select 5;tpw_bullet = _this select 6}]; };
    if (diag_tickTime >= _SupNextTime) then {_unit setVariable ["Shots", 0]};  
   _bc = 0; 
   if !(isnull tpw_bullet) then  
       { 
       _bc = count ((getposatl _unit) nearobjects ["Bulletbase",10]) 
       }; 
   if (_bc > 0) then  
       { 
       _side = _unit getvariable "SIDE"; 
       if (_side != tpw_fired) then  
           { 
           if !(tpw_mag in tpw_mags) then { 
               _unit setVariable ["SupNextTime", diag_tickTime + 3 + random 5];
                _shots = _unit getVariable "Shots"; 
               _unit setVariable ["Shots", _shots + _bc]; 
               } 
           } 
       }; 
   _shots = _unit getVariable "Shots"; 
   if (_shots == 0) then {_unit setunitpos "auto"}; 
   if (_shots > 0) then {_unit setunitpos "middle"}; 
   if (_shots > 5) then {_unit setunitpos "down"}; 

   } forEach allunits; 
};  
//Call function using per frame eventhandler so computer doesn't explode 
[tpw_sup,0] call cba_fnc_addPerFrameHandler;  

Share this post


Link to post
Share on other sites

You're using the right script but calling it wrong mate. In your init.sqf just put 0 = [] execvm "side.sqf". The way you are calling it, you are running a new instance every time your player fires a bullet. The more you shoot, the slower it's going to get!

Share this post


Link to post
Share on other sites

Well shux :o

Sorry fellas - Ill retest those numbers.

And you were entirely correct - sorry to lead a wild goose chase -should have checked in on that Init.sqf earlier.

I just ran 300 With Suppression (no scope for me) and it started at a steady 22-24 fps (thickest combat) and gradually worked it's way higher (as losses incurred) maxing at between 33-38. No choppiness whatsoever.

300 without Suppression was barely any different -maybe starting at a few FPS higher at 24-27 but basically ran the same FPS course as the other -a good sign!

Edited by froggyluv

Share this post


Link to post
Share on other sites
Well shux :o

Sorry fellas - Ill retest those numbers.

And you were entirely correct - sorry to lead a wild goose chase -should have checked in on that Init.sqf earlier.

I just ran 300 With Suppression (no scope for me) and it started at a steady 22-24 fps (thickest combat) and gradually worked it's way higher (as losses incurred) maxing at between 33-38. No choppiness whatsoever.

300 without Suppression was barely any different -maybe starting at a few FPS higher at 24-27 but basically ran the same FPS course as the other -a good sign!

Excellent news! Thanks so much for testing that all out froggyluv. We will be releasing an addon version very soon, and I think we can be a bit more confident that it won't kill computers.

Share this post


Link to post
Share on other sites

Thanks for the update TPW. I hope it will continue to be available as a script version as well.

Ran a quick test last night with ~220 units in 42 groups (I disabled the spawn of DAC-controlled NAPA & Chedaki camps because occurrence, location & timing is randomised - WIP anyway).

After the initial DAC spawn/release & HAC order-issuing phases, headed out along the coast road (taking route through forest drops the FPS) E towards Balota til BLUFOR took Komarov, & got 24-50+ FPS depending on events without suppression. Repeated once with the suppress1 script & got ~20-50+ or so. Not statistically significant as HAC+DAC missions are different every time. Would expect a somewhat bigger drop when more groups engage later in the battle, but I didn't have time to play that far. Lots of other scripts running (HAC, DAC, Demonised's Automedic, etc.) - so I'm really impressed by what -coulum- & you have created :) Looking forward to trying the latest version.

@ -coulum- re vehicles, I think choppers & planes should be completely excluded, i.e. from supressing as well as being supressed. Suppression isn't really their role & running the script on aircraft - fast movers especially - might melt CPUs

Share this post


Link to post
Share on other sites

OK, I think the time has come for an addon version of these scripts...

Distance version v1.00: http://www.gamefront.com/files/21867464/%40TPWC_AI_SUPPRESS_D.zip

Side version v1.00: http://www.gamefront.com/files/21867465/%40TPWC_AI_SUPPRESS_S.zip

Archive also contains the plain sqf version for people who want to run it directly. This version now only works for units on foot.

Based on how this goes, -Coulum- and I will start a new thread in the addons section.

Share this post


Link to post
Share on other sites

Damn that is some good news!

Anybody notice a FPS difference between the two versions?

Share this post


Link to post
Share on other sites
Well shux

Sorry fellas - Ill retest those numbers.

And you were entirely correct - sorry to lead a wild goose chase -should have checked in on that Init.sqf earlier.

I just ran 300 With Suppression (no scope for me) and it started at a steady 22-24 fps (thickest combat) and gradually worked it's way higher (as losses incurred) maxing at between 33-38. No choppiness whatsoever.

300 without Suppression was barely any different -maybe starting at a few FPS higher at 24-27 but basically ran the same FPS course as the other -a good sign!

That's a miracle. I am really surprised its able to run that smoothly with so many units.

OK, I think the time has come for an addon version of these scripts...

Distance version v1.00: http://www.gamefront.com/files/21867...SUPPRESS_D.zip

Side version v1.00: http://www.gamefront.com/files/21867...SUPPRESS_S.zip

Archive also contains the plain sqf version for people who want to run it directly. This version now only works for units on foot.

Great, your awesome man, start the thread whenever you'd like. Before I heard of Froggy's latest results I was thinking possibly changing the script so it didn't run per frame on far away units but instead maybe every half a second or so... but really it doesn't look like it matters much. Such little fps drop with so many units is much better than I expected already. You've done a really bang up job mate.

Damn that is some good news!

Anybody notice a FPS difference between the two versions?

Doesn't look like there's much fps drop... but the only way to be sure is to try!

Share this post


Link to post
Share on other sites

Will try in a few minutes. In the meantime, just gonna throw another idea out there.

As i couldn't see any real locality problem in there, would just adding a if isServer make it zlmost MP compatible? (for a coop mission at least, where all ai's handled by the server)

As i guess this should be the next step?

Share this post


Link to post
Share on other sites

Wow.... thank you both of you... the firefights are interesting again... coupled with the recent ASR_AI, everything is new again. Thank you for this new refreshed experienced. Somehow they will always goes to find some cover more often when under fire

As for bug report, I havent find any. The fps seems and feels smooth though the scenario arent really extreme with hundreds of AI... maybe just around 50.

So far I've only tested the DISTANCE version good experience until you have to walk under your own fire support, the assault goes very wrong from there. Will test the SIDE version next

Share this post


Link to post
Share on other sites

Thanks, -coulum- & tpw!

Will do some more & maybe bigger tests as soon as I can.

Share this post


Link to post
Share on other sites

Another two ideas i'll try to implement:

- use setSkill to drastically reduce the suppressed unit accuracy and/or increase shake.

- use findCover to force them to crawl to the nearest cover (even though i'm still not sure that command's fully functional yet).

I'll have to look up the differences between addMPEventHandler en addEventHandler too.

Share this post


Link to post
Share on other sites
Another two ideas i'll try to implement:

- use setSkill to drastically reduce the suppressed unit accuracy and/or increase shake.

- use findCover to force them to crawl to the nearest cover (even though i'm still not sure that command's fully functional yet).

Yep I am going to make a version like this as soon as I get home tonight minus the find cover as I don't think it's functional. The skills part should make it so I can bump up ai accuracy and still have some relatively long firefights, but I can understand why it not everyone's cup of tea, which is why the current versions don't have it.

It should be relatively easy to do, as the code required is already written on page 3

Share this post


Link to post
Share on other sites
Yep I am going to make a version like this as soon as I get home tonight minus the find cover as I don't think it's functional. The skills part should make it so I can bump up ai accuracy and still have some relatively long firefights, but I can understand why it not everyone's cup of tea, which is why the current versions don't have it.

It should be relatively easy to do, as the code required is already written on page 3

I agree, find cover does seem to be broken.

Might be interesting to see what happens with dropping the "courage" factor when units are suppressed (nice would be proportional to # of bullets whizzing past, but that would be too CPU-intensive) - though I'm not at all clear of the relationship between "courage" & "fleeing".

Share this post


Link to post
Share on other sites
nice would be proportional to # of bullets whizzing past, but that would be too CPU-intensive

Yes and no. It probably wouldn't be to system intensive, but there is a difference between cowardice and common sense. Right now, I see the reaction of the ai to suppression as a common sense reaction rather than one out of fear. But I will make shooting skill decrease by a factor proportional to the unit's courage to represent how men can panic under fire reducing their accuracy.

I could be wrong, but I also believe that a units courage determines how willing he is to advance (don't quote me on that though, I have't actually tested). So ideally, if courage is decreased while under fire, it should be possible to suppress a units movement although I doubt it will be possible to totally pin them.

--edit--

Yep I am going to make a version like this as soon as I get home tonight minus the find cover as I don't think it's functional. The skills part should make it so I can bump up ai accuracy and still have some relatively long firefights, but I can understand why it not everyone's cup of tea, which is why the current versions don't have it.

Sorry, I lied - probably won't get time to work on this until Friday, maybe Thursday.

First post updated

Edited by -Coulum-

Share this post


Link to post
Share on other sites

Here's a quick and dirty proof of concept script. If the unit is suppressed by a single bullet, his aiming accuracy and shake values are set to 75% of their original. If suppressed by multiple rounds, they drop to 50%. -Coulum- has a more refined way of changing these parameters, but this should show if the concept is workable. I can't test it at work....

// ALL INFANTRY UNITS ON MAP WILL DROP IF ANY BULLETS PASS WITHIN 10m
// BULLETS FIRED FROM LESS THAN 20m ARE IGNORED 
// BULLETS FROM SMG AND PISTOLS ARE IGNORED
// Original code idea by -Coulum-
// TPW 20120620 

//Start hint
0 = [] spawn {sleep 3;hintsilent "AI suppress active"; sleep 3; hintsilent ""};

private ["_supnextime","_unit","_bc","_shots","_dist"]; 

//Pistol and SMG  ammo to ignore
tpw_mags =["30rnd_9x19_MP5",
"30rnd_9x19_MP5SD",
"15Rnd_9x19_M9",
"15Rnd_9x19_M9SD",
"7Rnd_45ACP_1911",
"8Rnd_9x18_Makarov",
"8Rnd_9x18_MakarovSD",
"64Rnd_9x19_Bizon",
"64Rnd_9x19_SD_Bizon",
"13Rnd_9mm_SLP",
"17Rnd_9x19_glock17",
"6Rnd_45ACP",
"30Rnd_9x19_UZI",
"30Rnd_9x19_UZI_SD"];

//Main function
tpw_sup =  
{ 
   {
_unit = _x; 
	if (vehicle _x == _x) then 
	{
	_SupNextTime = _unit getVariable ["SupNextTime", -1]; 
	if (_SupNextTime == -1) then 
		{
		_unit setvariable ["SupAccuracy",_unit skill "aimingAccuracy"];
		_unit setvariable ["SupShake",_unit skill "aimingshake"];
		_unit setVariable ["SupNextTime", diag_tickTime];
		_unit addeventhandler ["Fired",{tpw_fired = _this select 0;tpw_mag = _this select 5; tpw_bullet = _this select 6}];
		};
	if (diag_tickTime >= _SupNextTime) then {_unit setVariable ["Shots", 0]}; 
	_bc = 0;
	if !(isnull tpw_bullet) then 
		{
		_bc = count ((getposatl _unit) nearobjects ["Bulletbase",10])
		};
	if (_bc > 0) then 
		{
		_dist = tpw_fired distance _unit;
		if (_dist > 25) then 
			{
			if !(tpw_mag in tpw_mags) then {
				_unit setVariable ["SupNextTime", diag_tickTime + 3 + random 5];
				_shots = _unit getVariable "Shots";
				_unit setVariable ["Shots", _shots + _bc];
				}
			}
		};
	_shots = _unit getVariable "Shots";
	_accuracy = _unit getvariable "SupAccuracy";
	_shake = _unit getvariable "SupShake";
	if (_shots == 0) then {_unit setunitpos "auto"};
	if (_shots > 0) then {_unit setunitpos "middle"; _accuracy = _accuracy * 0.75; _shake = _shake * 0.75};
	if (_shots > 5) then {_unit setunitpos "down"; _accuracy = _accuracy * 0.5; _shake = _shake * 0.5};
	_unit setskill ["AimingAccuracy",_accuracy];
	_unit setskill ["AimingShake",_shake];		

              }
} forEach allunits;
}; 

//Call function using per frame eventhandler so computer doesn't explode
[tpw_sup,0] call cba_fnc_addPerFrameHandler;

Edited by tpw

Share this post


Link to post
Share on other sites

You need to cease all gainful employment immediately, tpw, and become a scripting poopsocker/neckbearder ASAP.

Share this post


Link to post
Share on other sites
You need to cease all gainful employment immediately, tpw, and become a scripting poopsocker/neckbearder ASAP.

Thanks for the high praise! If I don't stop looking at this site when I'm at work, they might cease my gainful employment for me :)

Share this post


Link to post
Share on other sites
You need to cease all gainful employment immediately, tpw, and become a scripting poopsocker/neckbearder ASAP.

I concur.

Share this post


Link to post
Share on other sites

I had a thought... I think you guys can combine both the Distance version and the Side version together.

Basically the script should use the distance version in overall, but the side version comes in when trying to alter the skills.

I think this would let the friendly AI to duck when a fire from a SBF team coming from overhead (probably reduce friendly fire a bit) but the skills wont be altered.

Just my 2cents worth

Share this post


Link to post
Share on other sites

Fantastic idea, I am looking into it right now!

I had a thought... I think you guys can combine both the Distance version and the Side version together.

Basically the script should use the distance version in overall, but the side version comes in when trying to alter the skills.

I think this would let the friendly AI to duck when a fire from a SBF team coming from overhead (probably reduce friendly fire a bit) but the skills wont be altered.

Just my 2cents worth

Share this post


Link to post
Share on other sites

I took time out from my poopsocking to implement Mr_Centipede's suggestion and so far it seems to be working OK. Please try it out.

I also spent a bit of time trying to optimise the code a bit. There's lots of nested if statements, which look ugly but should speed things up thusly:

For each unit on map -->

if unit is not in a vehicle -->

if there is an active bullet -->

if the bullet count around unit is greater than 0 -->

if the distance of the shooter to the unit is greater than 25m -->

if the shooter's mag is not pistol or SMG -->

if shooter is enemy then unit drops and skills are reduced

else shooter is same side so unit drops but retains skills

So most of the time the script is actually only really checking if the unit is not in a vehicle and if there are any bullets being shot, which is not draining the CPU terribly. Only as each nested requirement is met does the script delve deeper and apply more calculations.

For this proof of principle I only bothered changing a unit's overall skill, not the various components individually.

Script:

// ALL INFANTRY UNITS ON MAP WILL REACT IF ANY BULLETS PASS WITHIN 10m
// BULLETS FIRED FROM LESS THAN 25m ARE IGNORED 
// BULLETS FROM SMG AND PISTOLS ARE IGNORED
// BULLETS FROM OWN SIDE CAUSE UNIT TO KNEEL/CROUCH
// BULLETS FROM ENEMY SIDE CAUSE UNIT TO KNEEL/DROP, AND TEMPORARY DECREASE IN SKILL

// Original code idea by -Coulum-
// TPW 20120620 

//Start hint
0 = [] spawn {sleep 3;hintsilent "AI suppress active"; sleep 3; hintsilent ""};

private ["_supnextime","_unit","_bc","_shots","_skill"]; 

//Pistol and SMG  ammo to ignore
tpw_mags =["30rnd_9x19_MP5",
"30rnd_9x19_MP5SD",
"15Rnd_9x19_M9",
"15Rnd_9x19_M9SD",
"7Rnd_45ACP_1911",
"8Rnd_9x18_Makarov",
"8Rnd_9x18_MakarovSD",
"64Rnd_9x19_Bizon",
"64Rnd_9x19_SD_Bizon",
"13Rnd_9mm_SLP",
"17Rnd_9x19_glock17",
"6Rnd_45ACP",
"30Rnd_9x19_UZI",
"30Rnd_9x19_UZI_SD"];

//Main function
tpw_sup =  
{ 
   {
_unit = _x; 
	if (vehicle _x == _x) then 
	{
	_SupNextTime = _unit getVariable ["SupNextTime", -1]; 
	if (_SupNextTime == -1) then 
		{
		_unit setVariable ["SupNextTime", diag_tickTime];
		_unit setVariable ["SupSkill", skill _unit];
		_unit setvariable ["SupSide", side _unit]; 
		_unit addeventhandler ["Fired",{tpw_fired = _this select 0;tpw_mag = _this select 5; tpw_bullet = _this select 6}];
		};
	if (diag_tickTime >= _SupNextTime) then 
		{
		_unit setVariable ["SupShots", 0];
		_unit setunitpos "auto";
		_unit setskill (_unit getvariable "SupSkill");
		};
	if !(isnull tpw_bullet) then 
		{
		_bc = count ((getposatl _unit) nearobjects ["Bulletbase",10]);
		if (_bc > 0) then 
			{
			if ((tpw_fired distance _unit) > 25) then 
				{
				if !(tpw_mag in tpw_mags) then 
					{
					_unit setVariable ["SupNextTime", diag_tickTime + 3 + random 5];
					_shots = _unit getVariable "SupShots";
					_unit setVariable ["SupShots", _shots + _bc];
					_shots = _unit getVariable "SupShots";
					_skill = _unit getVariable "SupSkill";				
					if (side tpw_fired != _unit getVariable "SupSide") then 
						{
						if (_shots > 0) then {_unit setunitpos "middle"; _unit setskill _skill * 0.8};
						if (_shots > 5) then {_unit setunitpos "down"; _unit setskill _skill * 0.6};
						} 
						else
						{
						if (_shots > 0) then {_unit setunitpos "middle"};
						};
					};
				};

			};
		};
	}; 
} forEach allunits;
};

//Call function using per frame eventhandler so computer doesn't explode
[tpw_sup,0] call cba_fnc_addPerFrameHandler;

Edited by tpw

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  

×