Jump to content
avibird 1

What AI Recruitment Scripts do you use.

Recommended Posts

I only found a few AI Recruitment Scripts for ARMA3.

 

1.Bon's Infantry Recruitment

2.Simple AI Recruitment Dialog / Script

3.[FOCK] AI Recruit - Cheap and cheer full [ALPHA]

 

4. using ZEUS (not really good for static mission design)

5. using MCC  (not really good for static mission design)

 

Bon's with its dynamically built subfaction system is great.

Dadds Army Simple AI Recruitment is very nice as well but both of them you can't just limited the Recruitment to a particular unit at  multiple set locations  ie only a pilot at an airbase or a tank crew at an armor depot position.

 

There is a way with both of them but I would have to make second  set of folders files and scripts to run the them with only one unit class in the script. As is I am trying to reduce the number of folders files and scripts in my little project :unsure:

 

 

 

 

Share this post


Link to post
Share on other sites

Nobody else uses AI recruitment scripts in there missions. Still looking for more recruitment scripts to review.

Share this post


Link to post
Share on other sites

This what we are using right now. Would like to make it a function and improve the code. Needs to work on dedicated, MP, or hosted.

 

Spoiler

if (!isDedicated) then {

	[] spawn {

		while {true} do {
		
		_allAIUnits = allUnits select {_x distanceSqr getpos player < 900};
		
			if (count _allAiUnits > 0) then {{
				if( side player == side _x && alive _x && group _x != group player && leader player == player && _x isKindOf "Man" && vehicle _x == _x && (leader _x != _x || count (units group _x) == 1) ) then {
					if(isNil {_x getVariable "sa_join_squad_action_id"}) then {
						_actionId = _x addAction ["Join My Squad", { 
							if(isNil {(_this select 0) getVariable "sa_original_group"}) then {
								(_this select 0) setVariable ["sa_original_group",group (_this select 0)];
							};
							[_this select 0] join player; 
							(_this select 0) removeAction (_this select 2);
							(_this select 0) setVariable ["sa_join_squad_action_id",nil];
						}, nil, 0, false];
						_x setVariable ["sa_join_squad_action_id",_actionId];
					};
				} else {
					if(!isNil {_x getVariable "sa_join_squad_action_id"}) then {
						_x removeAction (_x getVariable "sa_join_squad_action_id");
						_x setVariable ["sa_join_squad_action_id",nil];
					};
				};
				
				if( side player == side _x && alive _x && group _x == group player && leader player == player && _x isKindOf "Man" && vehicle _x == _x && _x != player ) then {
					if(isNil {_x getVariable "sa_leave_squad_action_id"}) then {
						_actionId = _x addAction ["Leave My Squad", { 
							if(!isNil {(_this select 0) getVariable "sa_original_group"}) then {
								[_this select 0] join ((_this select 0) getVariable "sa_original_group"); 
								(_this select 0) setVariable ["sa_original_group",nil];
							} else {
								[_this select 0] join grpNull; 
							};
							(_this select 0) removeAction (_this select 2);
							(_this select 0) setVariable ["sa_leave_squad_action_id",nil];
						}, nil, 0, false];
						_x setVariable ["sa_leave_squad_action_id",_actionId];
					};
				} else {
					if(!isNil {_x getVariable "sa_leave_squad_action_id"}) then {
						_x removeAction (_x getVariable "sa_leave_squad_action_id");
						_x setVariable ["sa_leave_squad_action_id",nil];
					};
				};
				
			} forEach _allAiUnits;
			sleep 10;
			};

		};

	};

};

 

 

Share this post


Link to post
Share on other sites

Recruiting with my addon. If better rating than a friend unit (condition), temporary zoom (right click) on it to recruit/dismiss this unit.

Share this post


Link to post
Share on other sites

@Jnr4817

This should work in SP/MP

Add in init.sqf (or initPlayerLocal.sqf):

 

[] spawn {
  if (!hasInterface) exitWith {};
  waitUntil {!isNull player};
  while {true} do {
    {
      _x setVariable ["addedAction",true];
      _x setVariable ["oldGrp",if (group _x == group player) then [{grpNull},{group _x}]];
      _x addAction [if (group player isEqualTo group _x) then [{"Leave my squad"},{"Join my squad"}], {
        params ["_unit","_player","_id"];
        _ActMenu = (_unit actionParams _id) select 0;
         _unit setUserActionText [_id,_ActMenu];
        if (_ActMenu isEqualTo "Join my squad") then {
          _ActMenu = "Leave my squad";
          [_unit] join group _player;
        } else {
          _ActMenu = "Join my squad";
          [_unit] join (_unit getVariable ["oldGrp",grpNull]);
        };
        _unit setUserActionText [_id,_ActMenu];
      },nil,0.8,false,true,"side _this isEqualTo side _target"];
    } forEach (allunits select { !(_x getVariable ["addedAction",false]) && !isPlayer _x});
    sleep 2;
  };
};

 

Works on AIs only infantry only, for 15 m distance and the unit under cursor (targeted).

  • Like 4

Share this post


Link to post
Share on other sites

Alternate solution for farther distance (so addAction must be on player).

In initPlayerLocal.sqf:


 

addedAction = {
  player addAction ["Join my squad",{
    params ["_player","_caller","_id"];
    _ActMenu = (_player actionParams _id) select 0;
    _player setVariable ["idThis",_id];
    if (_ActMenu isEqualTo "Join my squad") then {
      [cursorTarget] join group _player;
    } else {
      [cursorTarget] join (cursorTarget getVariable ["oldGrp",grpNull]);
    };
  },nil,0.8,false,true,"",
  "if ((!isNull cursorTarget) && {isNil {cursorTarget getVariable 'oldGrp'}}) then {
     cursorTarget setVariable ['oldGrp',if (group cursorTarget == group_this) then [{grpNull},{group cursorTarget}]]
   };
   if (!isnil {_this getvariable 'idThis'}) then {
     _this setUserActionText [(_this getvariable 'idThis'),if (group cursorTarget == group _this) then [{'Leave my squad'},{'Join my squad'}]]
   };
   side cursorTarget == playerSide
   && cursorTarget distanceSqr _this < 40000"
  ];
};

call addedAction;
player addEventHandler ["respawn", {call addedAction}];

 

 

  • Like 2

Share this post


Link to post
Share on other sites
On 12/26/2017 at 5:15 PM, pierremgi said:

@Jnr4817

This should work in SP/MP

Add in init.sqf (or initPlayerLocal.sqf):

 


[] spawn {
  if (!hasInterface) exitWith {};
  waitUntil {!isNull player};
  while {true} do {
    {
      _x setVariable ["addedAction",true];
      _x setVariable ["oldGrp",if (group _x == group player) then [{grpNull},{group _x}]];
      _x addAction [if (group player isEqualTo group _x) then [{"Leave my squad"},{"Join my squad"}], {
        params ["_unit","_player","_id"];
        _ActMenu = (_unit actionParams _id) select 0;
         _unit setUserActionText [_id,_ActMenu];
        if (_ActMenu isEqualTo "Join my squad") then {
          _ActMenu = "Leave my squad";
          [_unit] join group _player;
        } else {
          _ActMenu = "Join my squad";
          [_unit] join (_unit getVariable ["oldGrp",grpNull]);
        };
        _unit setUserActionText [_id,_ActMenu];
      },nil,0.8,false,true,"side _this isEqualTo side _target"];
    } forEach (allunits select { !(_x getVariable ["addedAction",false]) && !isPlayer _x});
    sleep 2;
  };
};

 

Works on AIs only infantry only, for 15 m distance and the unit under cursor (targeted).

hello, how do I configure this script only for two specific player. 1 player blue and another red. within a team of 8 players for each side? Thank you very much in advance

Share this post


Link to post
Share on other sites

Run the code in initPlayerLocal.sqf with this small modification:

 

did you named playableunits?   So you can add a condition like:   if (player in [name1,name2] then { <code>}; // example

In this case, the slots can be owned by anyone, first logged on them, first served.

 

or,  do you know the players user ID? so you can add a condition like:   if ( getPlayerUID player in ["123456","34567890"]) then {<code>};

in this case, no matter the chosen slots, only identified players (by their UID) can run this code.

 

Note: for players' UID, you need to ask your friends to launch a MP preview session with just one player and write getPlayerUID player in debug console watch lines. The UID is a stringed number. (In SP it returns "_SP_PLAYER_"). They can also proceed as shown in this video.

 

Share this post


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

did you named playableunits?   So you can add a condition like:   if (player in [name1,name2] then { <code>}; // example

In this case, the slots can be owned by anyone, first logged on them, first served.

 

Sorry I don't understand anything about programming. but I'm curious. thanks for answering. This interests me more. in this case should I copy this excerpt, add the name of the playable unit and paste it in condition in the property of this same playable unit?

 

 

11 hours ago, pierremgi said:

or,  do you know the players user ID? so you can add a condition like:   if ( getPlayerUID player in ["123456","34567890"]) then {<code>};

in this case, no matter the chosen slots, only identified players (by their UID) can run this code.

 

this procedure is the same but should i know player id?

Share this post


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

 in this case should I copy this excerpt, add the name of the playable unit and paste it in condition in the property of this same playable unit?

In editor, name your playable slots (at least the slots you want to manage), any name, that doesn't matter: plyr1,bob, unit2....

then if you want to filter the code above, mention these names in an array for condition. EXAMPLE:
 

Spoiler

 


[] spawn {
  if !(player in [bob,plyr3]) exitWith {};
  waitUntil {!isNull player};
  while {true} do {
    { 
      _x setVariable ["addedAction",true]; 
      _x setVariable ["oldGrp",if (group _x == group player) then [{grpNull},{group _x}]];
      _x addAction [
        if (group player isEqualTo group _x) then [{"Leave my squad"},{"Join my squad"}],
        {
          params ["_unit","_player","_id"];
          _ActMenu = (_unit actionParams _id) select 0;
          _unit setUserActionText [_id,_ActMenu]; 
          if (_ActMenu isEqualTo "Join my squad") then { 
            _ActMenu = "Leave my squad"; 
            [_unit] join group _player;
          } else {
            _ActMenu = "Join my squad";
            [_unit] join (_unit getVariable ["oldGrp",grpNull]);
          };
          _unit setUserActionText [_id,_ActMenu];
        },nil,0.8,false,true,"side _this isEqualTo side _target"
      ];
    } forEach (allunits select { !(_x getVariable ["addedAction",false]) && !isPlayer _x});
    sleep 2;
  };
};

 

 

 

 

in initPlayerLocal.sqf (create it in mission root folder if it doesn't exist).

 

2 hours ago, Coy74 said:

this procedure is the same but should i know player id?

 

No, that's different. When you name a slot, no matter the player, you run the code if the slot is granted in condition (here the code exits on player NOT present in array).

In the second case (uids), player's uid is unique for player, so if someone else plays, he will not be able to run the code. (you can compare it with admin privilege). And yes, of course, you need to know what uids you want to manage.

Read all the links above.

Share this post


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

No editor, nomeie seus slots jogáveis (pelo menos os slots que deseja gerenciar), qualquer nome, não importa: plyr1, bob, unit2 ....

então, se você quiser filtrar o código acima, mencione esses nomes em uma matriz para condição. EXEMPLO:

now I get it! And something so simple, but you need to "know" scripts to know how to insert or remove data configuring the way I want. Yes, I'm already reading the links and even saw the video on where to identify player ID. if I publish the mission online I won't forget to mention it. thank you so much for now.

Share this post


Link to post
Share on other sites
23 minutes ago, Coy74 said:

now I get it! And something so simple, but you need to "know" scripts to know how to insert or remove data configuring the way I want. Yes, I'm already reading the links and even saw the video on where to identify player ID. if I publish the mission online I won't forget to mention it. thank you so much for now.

 

1 hour ago, pierremgi said:

in initPlayerLocal.sqf (create it in mission root folder if it doesn't exist).

I used it in the "ini" file and it worked. I made a warlords MP(8x8) mission. Only on the opfor side that registers PC when parachutist lands. but that's not a problem.

Share this post


Link to post
Share on other sites
18 minutes ago, Coy74 said:

 

I used it in the "ini" file and it worked. I made a warlords MP(8x8) mission. Only on the opfor side that registers PC when parachutist lands. but that's not a problem.

 

Yes but the event scripts (automatic) are made for good reasons.

First of all, consider initialization order. (SP or MP). So, writing for SP or MP can lead to player ready or not, especially in init.sqf. In your case, that doesn't hurt.

There is no player (never) on dedicated server, so any code with player fails (without error) on dedicated.

As rule of thumb:

- scripts for player's behavior, HUDs or hints displays, local code should run from initPlayerLocal.sqf

- scripts for scenario like AI spawning should run on initServer.sqf  (there is also possibilities for using headless client(s) but it's a step far further).

- shared data or even code, for server + clients, should run on init.sqf . Can be helpful also for MP hosted (so the server is also a playing client).

  • Like 1

Share this post


Link to post
Share on other sites

Thank you very much for your brief and easy-to-understand explanation. It even made me want to learn in depth about scripts. So to add scripts in a mission it is important to know beforehand about SP/MP/client and dedicated server and .SQFs nomenclatures so the opposite too. Thank you for your attention to me

Share this post


Link to post
Share on other sites
On 12/26/2017 at 11:15 AM, pierremgi said:

@Jnr4817

This should work in SP/MP

Add in init.sqf (or initPlayerLocal.sqf):

 


[] spawn {
  if (!hasInterface) exitWith {};
  waitUntil {!isNull player};
  while {true} do {
    {
      _x setVariable ["addedAction",true];
      _x setVariable ["oldGrp",if (group _x == group player) then [{grpNull},{group _x}]];
      _x addAction [if (group player isEqualTo group _x) then [{"Leave my squad"},{"Join my squad"}], {
        params ["_unit","_player","_id"];
        _ActMenu = (_unit actionParams _id) select 0;
         _unit setUserActionText [_id,_ActMenu];
        if (_ActMenu isEqualTo "Join my squad") then {
          _ActMenu = "Leave my squad";
          [_unit] join group _player;
        } else {
          _ActMenu = "Join my squad";
          [_unit] join (_unit getVariable ["oldGrp",grpNull]);
        };
        _unit setUserActionText [_id,_ActMenu];
      },nil,0.8,false,true,"side _this isEqualTo side _target"];
    } forEach (allunits select { !(_x getVariable ["addedAction",false]) && !isPlayer _x});
    sleep 2;
  };
};

 

Works on AIs only infantry only, for 15 m distance and the unit under cursor (targeted).

 

Thank you, pierremgi

 

This script works nicely.

 

I was wondering how to make the range to recruit shorter than 15m?

Share this post


Link to post
Share on other sites

Just add the distance parameter in addAction:

For 5m :

....,nil,0.8,false,true,"side _this isEqualTo side _target","",5];

 

Share this post


Link to post
Share on other sites

Thank you, pierremgi.

 

I'm just curious. I don't see a number in your script so is the 15m you stated some kind of default?

 

Anyhow I tried what you suggested and it works perfectly.

 

Thanks again.

Share this post


Link to post
Share on other sites

I get the "Join my squad"  in my action menu twice. Also, the "Leave my squad" option appears twice in the menu.

 

What would cause that?

Share this post


Link to post
Share on other sites
On 3/16/2022 at 2:32 AM, pazuzu said:

I get the "Join my squad"  in my action menu twice. Also, the "Leave my squad" option appears twice in the menu.

 

What would cause that? 

Locality. I guess you are playing on a hosted server? initPlayerLocal.sqf might solve your problem. 15m

On 3/10/2022 at 1:25 AM, pazuzu said:

I don't see a number in your script so is the 15m you stated some kind of default?

Default for addaction distance is 50m according to BIKI

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

×