Jump to content
avibird 1

How to switch the AI behavior from safe to aware once a gun goes off in the same general location.

Recommended Posts

Need a little help on this. I am attempt in making an Old Mission from OFP days. It's a POW Prison Break.

I have the most of the patrol guards using the safe behavior and limited speed for the most part it works ok if the pow's are Spot It then the guards will open fire but if not they will continue on the pathway of not react even if a gunshot is pretty close to them. Is there a way set witch the behaviors using a command line to switch from safe to aware if it gunshot is heard with an x amount of meters from them regardless if they have a line of sight of the POW. 

 

At times it looks really stupid if a gun shoots next them and they do not react.

 

Edited by avibird 1
Spelling error

Share this post


Link to post
Share on other sites

Normally, the behaviour switch from SAFE to AWARE the COMBAT is automatic. I guess your pow stays captive.

 Anyway, you can use the firedNear EH.

In your guard init fields:

This addEventHandler ["firedNear", { (_this select 0) setBehaviour "AWARE" } ];

That doesn't mean they will hunt the pow if this one stays captive. You can add (_this select 1) setCaptive false, in the inner code.

Share this post


Link to post
Share on other sites

The pow are not set to captive they are in lock down in three different barracks. Multiple guard towers a few patrols a few groups hanging around the outside the courtyards. There is a few guns with limited ammo hidden around the camp courtyards. The way I setup up you sneak outside find one of the guns and take out a patrol or two to get more weapons. There are multiple fence you need to breach and when you breach the second one the camp goes on alert but using the safe behavior the units only react to LOS not to for gun fire. 

 

I would like to find back way to switch behaviors once a gun goes off without a silencer then the guards in the first holding area should go to aware not stay on safe just walking around or standing at a post. Thanks for the feedback on the above but not what I really need. Avibird

Share this post


Link to post
Share on other sites

@pierremgi not yet Arma time has been limited the past few days. 

 

There must be a way to make the AI prison guards still in the aware Behavior with Primary Weapons lowered while patrolling. Safe behavior is cool but it's pretty dumb when a gunfire goes off  right next to them but not in their direct line of sight and they do not react. 

 

There must be a way to set them to lower the weapons while while still walking walking with limited speed in a wear Behavior mode.

Share this post


Link to post
Share on other sites
3 hours ago, avibird 1 said:

@pierremgi not yet Arma time has been limited the past few days. 

 

There must be a way to make the AI prison guards still in the aware Behavior with Primary Weapons lowered while patrolling. Safe behavior is cool but it's pretty dumb when a gunfire goes off  right next to them but not in their direct line of sight and they do not react. 

 

There must be a way to set them to lower the weapons while while still walking walking with limited speed in a wear Behavior mode.

The only behavior that makes AI lower their weapons is "SAFE", during alpha days they even holstered their rifles on the back, no idea why this got removed, was awesome.

Has been requested a few times to unlink formation from behavior to no avail, seems kinda weird not being able to keep AI in any formation other than column, when in safe mode.

You could give individual units relative doMove commands to the leaders position, but that would cause more problems than it would solve.

 

Cheers

  • Like 1
  • Sad 1

Share this post


Link to post
Share on other sites

Grumpy ty and yes domove creates more problems than it solves.

 

Pierremgi it works somewhat better the vanilla setup with safe and open fire. 

 

I was trying to setup a trigger using it 

On act - ["firednear",{ (_this select 0) setbehavior "aware" } ]; for all units 

 

With a sound of alarm for with a timeout of 120 seconds. 

 

Any help on this would be greatly appreciate it

Share this post


Link to post
Share on other sites

keep in mind that firednear works with 69m range

so

1.define an area

2. spawn sound source somewhere inside area

3.add eventhandler to every object in that area

4 after eventhandler fire remove it from every object

 

For example:

"oaalarm" will be the alarm sound

_marker is an marker

we have a marker with shape and size 300m

we spawn speaker there like this

	private ["_speakerPos", "_speaker"];
	_speakerPos = [getMarkerPos _marker, 0, 100, 1, 0, 0, 0, [], getMarkerPos _marker] call BIS_fnc_findSafePos;
	
	if !(_speakerPos isEqualTo []) then {
	
		_speaker = "Land_Loudspeakers_F" createVehicle _speakerPos;
	};

Now we prepare alarm

 

if !(isNull _speaker) then {
		
	0 = [_marker, _speaker] spawn {

	params [["_oaMarker","",[""]],["_speaker", objNull, [objNull]]];
	private ["_types","_marker","_holders"];
	
	_types = ["TREE", "SMALL TREE", "BUSH", "FENCE", "WALL", "FOREST", "RUIN", "MAIN ROAD", "ROAD", "ROCK", "ROCKS", "POWER LINES"];
	_marker = format ["%1_oa_terrobjects",_oaMarker];
	_holders = nearestTerrainObjects [getMarkerPos _oaMarker, _types, 300, false, false];
	
	missionNameSpace setVariable [_marker, [_holders,_speaker], false];

	{
		_x addEventHandler ["FiredNear",{
		
			params [["_obj",objNull,[objNull]]];
			
			_oaMarker = (allMapMarkers select {_obj inArea _x}) select 0;
			
			(missionNameSpace 
			getVariable 
			[format ["%1_oa_terrobjects",_oaMarker],
			[[objNull],objNull]]) params [
					
				["_holders",[],[[]]],["_speaker",objNull,[objNull]]
			];
			
			{
				_x removeAllEventHandlers "FiredNear";
			} forEach _holders;
			
			0 = [_speaker] spawn {
			
				params [["_speaker", objNull, [objNull]]];
				sleep 5;
				0 = [_speaker, ["oaalarm", 500, 1]] remoteExec ["say3D", [0,-2] select isDedicated, false];
				sleep 35;
				deleteVehicle _speaker;
			};
			
		}];
	} forEach _holders;




};
};

 

  • Like 1

Share this post


Link to post
Share on other sites

Lol you just made my head hurt ? I will play around with that ty. 

 

Also the nearfired only works with enemy gunfire not friendly fire. Is there a way to set it for any gunfire

Share this post


Link to post
Share on other sites
Quote

Also the nearfired only works with enemy gunfire not friendly fire.

Who said that ? works for any gun fire

Share this post


Link to post
Share on other sites

I need to retest it seems that some of the units  did not react but now you're telling me it's only 69m ☺️

Share this post


Link to post
Share on other sites

Keep it simpler than that!

 

Your trigger is good enough for alarm:

Place a trigger anywhere on map (no area, none,none) Just make it repeatable, then in condition field:

   ! isnil "firing" && isnil "alarm"      that means you're waiting for a firing variable coming form the Event Handler (EH) and a variable alarm toggling the repeat of the trigger (just for signal repeat during 2 minutes).

On activation:

if (isnil "Counter") then {counter =0}; alarm =true; counter = counter +1;

On deactivation:

0 = [] spawn {sleep 1; if (counter < 120) then {alarm = nil}}        120 sec alarm here.

Then choose the alarm in trigger effect. Important!

 

The EH is fine to "trigger" some code and make the trigger working:

In init.sqf , or even in any field of any unit (just once):

{_x addEventHandler ["firednear",{
  firing = true;

  { _x setbehaviour "aware";

    _x setSpeedMode "FULL";

    _x removeEventHandler ["firedNear", _thisEventHandler]

   } foreach [guard1,guard2,guard3]

  }]

} forEach [guard1,guard2,guard3];

 

Here guard1 guard2 guard3 are the units in careless or safe mode you want them to react at fire.

  • Like 2

Share this post


Link to post
Share on other sites

After a lot of testing Friendly Fire next to the units does not facilitate the code to run sad to say.  This addEventHandler ["firedNear", { (_this select 0) setBehaviour "AWARE" } ];

 

 

Maybe I am doing something wrong would not be the first time. But Friendly Fire does not switch them from safe to aware mode.

Share this post


Link to post
Share on other sites

Why don't you try the code I wrote? You just have to adapt guard1, guard2.. for your guards. There is no more "this addEventHandler..." because I wrote for an array of guards. there is no trouble with that. The EH, written once, is for all your guards and the first who "hear" (69m) a gun fire, will make the EH code firing for all guards. There is no problem with friendly or enemy fire. It's Ok in any case.

So?

Share this post


Link to post
Share on other sites

@ pierremgi

 

it works somewhat. Friendly fire does not make the guards change Behaviors ?  I tested it multiple times. It works great with the enemy gunfire. The vanilla AI does not react to friendly fire as well.  just thought of this Maybe its because I am the friendly guy who is firing the rounds but if the AI shoots a round then maybe the code would work?  I need to test that to see if that is the issue with the code.

The alarm does not shut off with the code do I need to add a time value or timeout countdown to the trigger?

 

Well almost there.  Thank you all so far for the assist on this.

Share this post


Link to post
Share on other sites

Friendly fire will not work if a human is the unit shooting. Works great if the AI shoots

The Alarm code works it was me lol but is there a way to adjust the code not to set the alarm if the weapon has a suppressor or silencer. Right now any gunfire with or without.

In the mission there is a small chance the POW's  can sneak around the camp and find a weapon with a suppressor or silencer if I can't keep the code not to work with a suppressor or silencer there is no point having that part of the mission or a possibility of a clean getaway :don14: thanks for the help gentleman....

Share this post


Link to post
Share on other sites
25 minutes ago, avibird 1 said:

Friendly fire will not work if a human is the unit shooting. Works great if the AI shoots

 

???????? We don't have the same Arma.

Share this post


Link to post
Share on other sites
On 2/12/2018 at 4:24 AM, avibird 1 said:

After a lot of testing Friendly Fire next to the units does not facilitate the code to run sad to say.  This addEventHandler ["firedNear", { (_this select 0) setBehaviour "AWARE" } ];

 

 

Maybe I am doing something wrong would not be the first time. But Friendly Fire does not switch them from safe to aware mode.

FiredNear works also when blufor shoots a rifle, then it will fire the eventhandler on blufor units, as well on any other units.

Care to post a repro mission where it didn't work out for you, since you mentioned "a lot of testing"?

 

Here's what I found out about "FiredNear" eventhandler:

  • It fires for any weapon except "Throw"
  • It fires if the unit it is assigned to is firing
  • It fires if any other unit no matter the side within 69m is firing (except throw)

Easy enough to test using systemchat to display the data:

{_x addEventHandler ["FiredNear",{systemchat str _this}]} forEach allUnits;

You could also use a regular fired eventhandler and reveal the firing unit to every other unit within a certain range, so you're not limited to 69m of FiredNear:

 

{
_x addEventHandler ["Fired",{

	params ["_firer"];
	{
	_x reveal [_firer,0.3];
	} forEach (allUnits select {_x distance2D _firer < 200});
	_firer removeEventHandler ["Fired",_thisEventHandler];//remove it after first shot or keep it in, up to you

}];

} forEach allUnits;

You can basically do everything you want with this snippet, add more range, make range influence the amount the unit is being revealed to other units -> the closer, the more gets revealed,

add speed of sound and average reaction time until the unit gets revealed etc...

 

Just don't come so easily to conclusions that the firednear eventhandler doesn't work on blufor if blufor fired, when it actually DOES work.

Step up your debugging game, heh.

 

Cheers

  • Like 1

Share this post


Link to post
Share on other sites
On ‎2‎/‎12‎/‎2018 at 11:46 PM, Grumpy Old Man said:

 

 


{
_x addEventHandler ["Fired",{

	params ["_firer"];
	{
	_x reveal [_firer,0.3];
	} forEach (allUnits select {_x distance2D _firer < 200});
	_firer removeEventHandler ["Fired",_thisEventHandler];//remove it after first shot or keep it in, up to you

}];

} forEach allUnits;

 

I like this script and I'm tying to implement a reveal increment number, but I get the weirdest error code I have ever seen 

Error Type Number,Not a Number, expected Number
fired1 = true;
_1=0;
while {true} do {
    	sleep 5;
		_1=_1+0.1;
        if (fired1) then {//hint "hi";
			fired1 = false;
            player addEventHandler ["fired",{
			params ["_firer"];
			{
			_x reveal [_firer,(0.2)+_1];
			} forEach (allUnits select {_x distance2D _firer < 200});
			_firer removeEventHandler ["Fired",_thisEventHandler];
			fired1 = true;
			}];
			
			

};
};

is there a better way of doing this

Share this post


Link to post
Share on other sites
35 minutes ago, sabot10.5mm said:

I like this script and I'm tying to implement a reveal increment number, but I get the weirdest error code I have ever seen 


Error Type Number,Not a Number, expected Number

fired1 = true;
_1=0;
while {true} do {
    	sleep 5;
		_1=_1+0.1;
        if (fired1) then {//hint "hi";
			fired1 = false;
            _firer = player addEventHandler ["fired",{
			params ["_firer"];
			{
			_x reveal [_firer,(0.2)+_1];
			} forEach (allUnits select {_x distance2D _firer < 200});
			_firer removeEventHandler ["Fired",_thisEventHandler];
			fired1 = true;
			}];
			
			

};
};

is there a better way of doing this

 

Well of course there is!

 

ZHf2jjf.jpg

 

 

Weird practice of adding and removing the EH constantly, you could simply make a lockout like this, added simple speed of sound formula, reveal value depending on distance and some comments:

 

_ID = player addEventHandler ["Fired",{

	params ["_firer","_weapon","_muzzle","_mode","_ammo","_magazine","_projectile","_gunner"];

	//check for lockout
	if (time < _firer getVariable ["GOM_fnc_revealLockout",-1]) exitWith {hintSilent "Locked out!"};
	//we're not locked out, so we set a lock
	_firer setVariable ["GOM_fnc_revealLockout", time + 5,true];//makes the reveal be available in 5s from now

	//at first eliminate everything that should not happen
	//we assume you don't want to reveal to a unit 50km away, decide for 800m maximum

	_debugText = ""; //always good to have

	allUnits select {_x distance2d _firer <= 800} apply {

	//now we calculate speed of sound, basic formula without temperature or air pressure shenanigans, assuming 343m/s
		_distance = _x distance _firer;
		_travelTime = _distance / 343;//not using distance2d since that would be odd

		//we also don't want to reveal a fixed value to every unit, linearConversion is ace here
		//read the wiki on it, quite a handy command
		//we already have a max distance, so we say maximum reveal of 4 happens under 100m, at 800m we reveal 0
		//anything inbetween will be a linear value
		//this will reveal 4 at 100m, 2.28571 at 400m and 0.00571418 at 799m
		_revealValue = linearConversion [100,800,_distance,4,0];

		//since we also want to know what's going on a simple hint comes into play:
		_debugText = _debugText + format ["%1 got revealed to %2\n%3m, %4 seconds, %5 reveal value.\n\n",_firer,_x,_distance,_travelTime,_revealValue];

		//now we need to spawn a new function so the delay works:
		_delayedReveal = [_firer,_x,_distance,_travelTime,_revealValue] spawn {

			params ["_firer","_unit","_travelTime","_revealValue"];
			sleep _travelTime;
			_unit reveal [_firer,_revealValue];
			true

		}

	};
hintsilent str _debugText;


}];
player setVariable ["GOM_fnc_firedRevealID",_ID];//store the EH ID on the object to keep things tidy

 

Also:

_1=0;

Never do that, that's nasty.

 

Cheers

  • Thanks 2

Share this post


Link to post
Share on other sites
3 hours ago, Grumpy Old Man said:

Also:


_1=0;

Never do that, that's nasty.

what this refering to?

 

Very nice script!

this will give a more realistic behaviour .

I think that , something like this , should be in the game , as an extra option , for having also this (scout-recon) kind of behaviour.

  • Like 1

Share this post


Link to post
Share on other sites
On 2/18/2018 at 9:28 AM, Grumpy Old Man said:

 

Well of course there is!

 

ZHf2jjf.jpg

 

 

Weird practice of adding and removing the EH constantly, you could simply make a lockout like this, added simple speed of sound formula, reveal value depending on distance and some comments:

 


_ID = player addEventHandler ["Fired",{

	params ["_firer","_weapon","_muzzle","_mode","_ammo","_magazine","_projectile","_gunner"];

	//check for lockout
	if (time < _firer getVariable ["GOM_fnc_revealLockout",-1]) exitWith {hintSilent "Locked out!"};
	//we're not locked out, so we set a lock
	_firer setVariable ["GOM_fnc_revealLockout", time + 5,true];//makes the reveal be available in 5s from now

	//at first eliminate everything that should not happen
	//we assume you don't want to reveal to a unit 50km away, decide for 800m maximum

	_debugText = ""; //always good to have

	allUnits select {_x distance2d _firer <= 800} apply {

	//now we calculate speed of sound, basic formula without temperature or air pressure shenanigans, assuming 343m/s
		_distance = _x distance _firer;
		_travelTime = _distance / 343;//not using distance2d since that would be odd

		//we also don't want to reveal a fixed value to every unit, linearConversion is ace here
		//read the wiki on it, quite a handy command
		//we already have a max distance, so we say maximum reveal of 4 happens under 100m, at 800m we reveal 0
		//anything inbetween will be a linear value
		//this will reveal 4 at 100m, 2.28571 at 400m and 0.00571418 at 799m
		_revealValue = linearConversion [100,800,_distance,4,0];

		//since we also want to know what's going on a simple hint comes into play:
		_debugText = _debugText + format ["%1 got revealed to %2\n%3m, %4 seconds, %5 reveal value.\n\n",_firer,_x,_distance,_travelTime,_revealValue];

		//now we need to spawn a new function so the delay works:
		_delayedReveal = [_firer,_x,_distance,_travelTime,_revealValue] spawn {

			params ["_firer","_unit","_travelTime","_revealValue"];
			sleep _travelTime;
			_unit reveal [_firer,_revealValue];
			true

		}

	};
hintsilent str _debugText;


}];
player setVariable ["GOM_fnc_firedRevealID",_ID];//store the EH ID on the object to keep things tidy

 

Also:


_1=0;

Never do that, that's nasty.

 

Cheers

now I remember what I wanted to say.

_delayedReveal = [_firer,_x,_distance,_travelTime,_revealValue] spawn {

params ["_firer","_unit","_travelTime","_revealValue"];

take out (_distance). params is looking for 4 variables

  • Like 2

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

×