Jump to content
Ulfgaar

AI Doorgunners in helicopters - on/off?

Recommended Posts

Greetings mighty oracle (all you bad ass coders and scripters).

Im the content creator in a medium sized community - and one thing that has been pestering our helicopter pilots, is that players tend to go nuts with the doormounted guns while flying back to base. I've offered to sort our choppers out with AI gunners, which is a simple process. I've also got a fair idea on how to utilize an addaction together with turning off simulation on/off of said AI gunners so that the pilot can activate/deactivate the AI doorgunners as he see fit and need. 

However, im bit puzzled on how to make it so that only the pilot seat has access to said addaction command. 

Anyone out there that has an idea on how to do this, in an efficient and proper way using either a code to use in the vehicle init or in an sqf script?

Any help is appreciated!

Best regards,

Ulfgaar.

Share this post


Link to post
Share on other sites

u could do a driver check in condition part of ur addAction

Share this post


Link to post
Share on other sites

This is true, tho im not entierly sure how the code would look.

Also, is it possible to make an "if" code of sorts to check if doorgunners are simulated or not? So that when you press the addaction once, the doorgunners will be simulated and start engaging targets - but if they are already simulated, they would have their simulation turned off, effectively turning them "off"?

 

Share this post


Link to post
Share on other sites

What i have so far is this:

this addAction ["<t color='#ff1111'>WEAPONS FREE</t>","H1 setVehicleAmmo 1;",[1],0,false,true,""," driver  _target == _this"];
this addAction ["<t color='#FFFF00'>WEAPONS HOLD</t>","H1 setVehicleAmmo 0;",[1],0,false,true,""," driver  _target == _this"];

However, the problem here is that the pilot also loses his chaff/flares, which is unfortunate.

I've also experimented with the following:
 

H1 removeWeaponTurret ["LMG_Minigun_Transport",[1]];
H1 removeWeaponTurret ["LMG_Minigun_Transport2",[2]];

On its own, placed in the vehicle H1's init field, it diables the turrets ability to fire by all appearanes - however, when i try impliment said codes into my addaction like this:

this addAction ["<t color='#ff1111'>WEAPONS FREE</t>","H1 addWeaponTurret ["LMG_Minigun_Transport",[1]]; H1 addWeaponTurret ["LMG_Minigun_Transport2",[2]];",[1],0,false,true,""," driver  _target == _this"];

this addAction ["<t color='#FFFF00'>WEAPONS HOLD</t>","H1 removeWeaponTurret ["LMG_Minigun_Transport",[1]]; H1 removeWeaponTurret ["LMG_Minigun_Transport2",[2]];",[1],0,false,true,""," driver  _target == _this"];

I get an error. 

I dont get it, so if anyone here can help me out - as said, it'll be extremely helpful 😄

Share this post


Link to post
Share on other sites

Any clues on why the error appears on the latter code?

Share this post


Link to post
Share on other sites
4 minutes ago, Ulfgaar said:

Any clues on why the error appears on the latter code?

Because you're using "" with no caution. I'll come back with a better code.

Edited ... or Larrow 😄

Share this post


Link to post
Share on other sites
this addAction [ "Disable Door Gunners", {
		params [ "_target", "_caller", "_id", "_args" ];
		
		_turrets = allTurrets _target;
		_baseConfig = configFile >> "CfgVehicles" >> typeOf _target;
		{
			_turretConfig = _baseConfig;
			{
				_turretConfig = ( _turretConfig >> "turrets" ) select _x;
			}forEach _x;
			if ( getText( _turretConfig >> "gunnerName" ) find "door gunner" > -1 ) then {
				_turrets set[ _forEachIndex, _target turretUnit _x ];
			}else{
				_turrets set[ _forEachIndex, objNull ];
			};
		}forEach _turrets;
		_doorGunners = _turrets select{ !isNull _x && { !isPlayer _x } };
		
		_disable = _target actionParams _id select 0 select [ 0, 1 ] == "d";
		
		{
			[ [ _x, _disable ], {
				params[ "_gunner", "_disable" ];
				if !( _disable ) then {
					_gunner enableAI "TARGET";
					_gunner enableAI "AUTOTARGET";
					_gunner enableAI "WEAPONAIM";
					_gunner enableAI "AUTOCOMBAT";
				}else{
					_gunner disableAI "TARGET";
					_gunner disableAI "AUTOTARGET";
					_gunner disableAI "WEAPONAIM";
					_gunner disableAI "AUTOCOMBAT";
				};
			} ] remoteExec[ "BIS_fnc_call", _x ];
		}forEach _doorGunners;
		
		_text = format[ "%1 Door Gunners", [ "Disable", "Enable" ] select _disable ];
		[ _target, [ _id, _text ] ] remoteExec[ "setUserActionText", 0, _target ];
	},
	[],
	1,
	false,
	true,
	"",
	"driver _target isEqualTo _this"
];

Tested in the init of a Ghost Hawk with AI door gunners.

Relies on "door gunner" being in the string of the turrets config entry "gunnerName".

May need to cover edge cases like if a gunner is forced to disembark re-enable their simulation?

 

Rather than disabling the AI simulation, it may look better to instead disable/enable parts of their AI, TARGET, AUTOTARGET, WEAPONAIM etc

May also want to add event to see if controls have been shifted? (copilot is in control rather than pilot)

 

EDIT: Updated code to handle door gunners remoteExec in one call. Also fixed userActionText updating on all clients and JIP.

TEST_MISSION

  • Like 2

Share this post


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

Because you're using "" with no caution. I'll come back with a better code.

Edited ... or Larrow 😄

Well, im no codewizz - and this was the only code i found which was doing what i wanted - however, from Armaholic regarding Arma 2

 

@Larrow
I copypasted the code you made into a ghosthawk in the editor and tested it with everyone in the chopper being grouped, as well as ungrouped, and even tho i see your fancy addaction change as i click it - there is no result. The AI keep blasting the hostile AI no matter. I assume it has something to do with your Relies on "door gunner" being in the string of the turrets config entry "gunnerName" part, but i must admint i dont understand what that means.

I did however check up on what you said about disable parts of the AI which obviously is a much better sollution, and i cant imagine why i didnt think of that - but I am again hitting the wall with my apparent faulty code from armaholic - getting an error.

this addAction ["<t color='#ff1111'>WEAPONS FREE</t>","H1 enableAI "All";",[1],0,false,true,""," driver  _target == _this"]; 
this addAction ["<t color='#FFFF00'>WEAPONS HOLD</t>","H1 disableAI "All";",[1],0,false,true,""," driver  _target == _this"];

Is it possible to make your fancy "enable/disable" changing addaction with just disabling the AI parts as you said?

I just need an addAction which is only available from the pilots/Driver seat, which can be used to enable/disable the doorgrunners ability to engage exterior targets. The AI dont have to look good as such. We're a fairly small/medium sized group so we're only using 1 pilot per helicopter - rarely if ever any co-pilots. 

Also, thanks a bunch for your help so far guys - but im afraid im not at the level to really understand what your doing with that page long code 😛 

Share this post


Link to post
Share on other sites
1 hour ago, Ulfgaar said:

The AI keep blasting the hostile AI no matter.

Oops never checked with targets, just looked to see that AI was in fact disabled( not moving ).

Updated script in previous post with enable/disableAI variant, hopefully all good? Or at least should give you a good idea of how to go about it, with a little more effort and testing than I have put in.

 

Code commented

Spoiler

this addAction [ "Disable Door Gunners", {
		params [ "_target", "_caller", "_id", "_args" ];
		
		//Get vehicles turret paths
		_turrets = allTurrets _target;
		//Get vehicles base config path
		_baseConfig = configFile >> "CfgVehicles" >> typeOf _target;
		
		//For each turret path
		{
			//Set turrets config path as vehicles base path
			_turretConfig = _baseConfig;
			
			//For each index in the turret path
			{
				//Get the turrets config path
				_turretConfig = ( _turretConfig >> "turrets" ) select _x;
			}forEach _x;
			
			//Once we have found the turrets config path
			//If its "gunnerName" field includes the text "door gunner"
			if ( getText( _turretConfig >> "gunnerName" ) find "door gunner" > -1 ) then {
				//Update _turrets with the unit actually occupying that turret
				_turrets set[ _forEachIndex, _target turretUnit _x ];
			}else{
				//Otherwise set it as objnull no unit
				_turrets set[ _forEachIndex, objNull ];
			};
		}forEach _turrets;
		
		//Get an array of all the turret units, minus any that are null or are a player
		_doorGunners = _turrets select{ !isNull _x && { !isPlayer _x } };
		
		//If the current action text starts with a "d"
		//Then we are disabling
		_disable = _target actionParams _id select 0 select [ 0, 1 ] == "d";
		
		//For each of the door gunners
		{
			//Call this code 
			[ [ _x, _disable ], {
				params[ "_gunner", "_disable" ];
				if !( _disable ) then {
					_gunner enableAI "TARGET";
					_gunner enableAI "AUTOTARGET";
					_gunner enableAI "WEAPONAIM";
					_gunner enableAI "AUTOCOMBAT";
				}else{
					_gunner disableAI "TARGET";
					_gunner disableAI "AUTOTARGET";
					_gunner disableAI "WEAPONAIM";
					_gunner disableAI "AUTOCOMBAT";
				};
			} ] remoteExec[ "BIS_fnc_call", _x ]; //_x where the unit is local
		}forEach _doorGunners;
		
		//Get new action text
		_text = format[ "%1 Door Gunners", [ "Disable", "Enable" ] select _disable ];
		//Update action text on all clients and JIP
		[ _target, [ _id, _text ] ] remoteExec[ "setUserActionText", 0, _target ]; //_target as persistence, until the vehicle is destroyed or deleted
	},
	[],
	1,
	false,
	true,
	"",
	//Only allow the driver of the vehicle this action is placed on to use this action
	"driver _target isEqualTo _this"
];

 

 

  • Like 2

Share this post


Link to post
Share on other sites

Thanks man - i'll explore this tomorrow or so i think.

Wish i had your know-how 🙂 

Share this post


Link to post
Share on other sites

I thought it was some codes for disabling players to fire as bad ass!

The only way to remove the toy from kid's hand is to remove the mags (w/ ammo).

 

And that works also for AIs of course:


 

this addAction ["<t color='#FFFF00'>WEAPONS TIGHT</t>", {  // official term if I remember
    params [ "_target", "_caller", "_id", "_args" ];
    _turrets = allTurrets [_target,false];  // only mounted turrets
    if ((_target actionParams _id) select 0 == "<t color='#FFFF00'>WEAPONS TIGHT</t>") then {
      _target setVariable ["turretsDetail",magazinesAllTurrets _target];
    };
    if ((_target actionParams _id) select 0 == "<t color='#FFFF00'>WEAPONS TIGHT</t>") then {
  	  {
            _target removeMagazinesTurret [_target currentMagazineTurret _x,_x];
  	  } forEach (_turrets select {getNumber (configfile >> "CfgWeapons" >> _target currentWeaponTurret _x >> "type") == 65536});
  	  _target setUserActionText [_id,"<t color='#ff1111'>WEAPONS FREE</t>"];
    } else {
      {
        {
          _target addMagazineTurret _x;
        } forEach (_target getVariable ["turretsDetail",[]]);
      } forEach (_turrets select {getNumber (configfile >> "CfgWeapons" >> _target currentWeaponTurret _x >> "type") == 65536});
      _target setUserActionText [_id,"<t color='#FFFF00'>WEAPONS TIGHT</t>"];
    }
  },
  [],
  1,
  false,
  true,
  "",
  "driver _target isEqualTo _this"
];

 

Seems to work. One thing to improve so far: when you re-enable the previous magazines, you have to reload them and that takes a little time (as real life).

Share this post


Link to post
Share on other sites
2 hours ago, pierremgi said:

The only way to remove the toy from kid's hand is to remove the mags (w/ ammo).

Remove the weapons.  We have a weapon control system that works that way and it sure seems like the simplest solution.

1 hour ago, pierremgi said:

One thing to improve so far: when you re-enable the previous magazines, you have to reload them

Part of the appeal of fiddling with the weapons directly is that when they're put back they're instantly loaded.

Share this post


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

Remove the weapons.  We have a weapon control system that works that way and it sure seems like the simplest solution.

Part of the appeal of fiddling with the weapons directly is that when they're put back they're instantly loaded.

I'd rather remove the magazines. Removing weapons is not so simple... for recovering them with the count of remaining mags and amos.

Share this post


Link to post
Share on other sites
5 hours ago, pierremgi said:

Removing weapons is not so simple... for recovering them with the count of remaining mags and amos.

When a weapon is removed (removeWeaponTurret), ARMA leaves the weapon's magazines in place, complete with partial ammunition counts.  So when you add the weapon back (addWeaponTurret), the original magazine is instantly loaded.  If a player is in the turret, all they see is that they either have or don't have access to a particular weapon.  There's no need to fiddle with magazines or ammunition counts.

For anyone fooling with this, remember that those two commands must be run locally to the turret.  Use turretOwner to figure out where to remoteExec the commands.  So the real complexity of weapon control systems is in the user interface and knowing how to get the commands executed on the right computer.  For single player, the latter can be ignored.

Share this post


Link to post
Share on other sites
2 hours ago, JB47394 said:

When a weapon is removed (removeWeaponTurret), ARMA leaves the weapon's magazines in place, complete with partial ammunition counts.  So when you add the weapon back (addWeaponTurret), the original magazine is instantly loaded.  If a player is in the turret, all they see is that they either have or don't have access to a particular weapon.  There's no need to fiddle with magazines or ammunition counts.

For anyone fooling with this, remember that those two commands must be run locally to the turret.  Use turretOwner to figure out where to remoteExec the commands.  So the real complexity of weapon control systems is in the user interface and knowing how to get the commands executed on the right computer.  For single player, the latter can be ignored.

 

Yes, I missed something previously. So, this code should work in SP/MP:

 

this addAction ["<t color='#FFFF00'>WEAPONS TIGHT</t>", {
  params [ "_target", "_caller", "_id", "_turrets","_weapons"];
  _turrets = allTurrets [_target,false];
  if ((_target actionParams _id) select 0 == "<t color='#FFFF00'>WEAPONS TIGHT</t>") then {
    _weapons = _turrets apply {[_target currentWeaponTurret _x,_x]};
    _target setVariable ["turretsDetail",_weapons,true]; 
    [[_target,_weapons],{
      params ["_target","_weapons"];
      {
        [_target,_x] remoteExecCall ["removeWeaponTurret",_target turretOwner _x#1];
      } forEach (_weapons select {getNumber (configfile >> "CfgWeapons" >> _x#0 >> "type") == 65536})
    }] remoteExecCall ["call",2];
    _target setUserActionText [_id,"<t color='#ff1111'>WEAPONS FREE</t>"];
  } else {
    _weapons = _target getVariable ["turretsDetail",["",[-1]]];
    [[_target,_weapons],{
      params ["_target","_weapons"];
      {
        [_target,_x] remoteExecCall ["addWeaponTurret",_target turretOwner _x#1];
      } forEach (_weapons select {getNumber (configfile >> "CfgWeapons" >> _x#0 >> "type") == 65536})
    }] remoteExecCall ["call",2];
    _target setUserActionText [_id,"<t color='#FFFF00'>WEAPONS TIGHT</t>"];
  }
  },
  [],
  1,
  false,
  true,
  "",
  "driver _target isEqualTo _this"
];

EDITED. Not tested in MP...

 

 

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

×