Jump to content
snakeplissken

How to Join (lead) the AI group (script spawn) when you get close to them?

Recommended Posts

Command to join(lidering) the AI group(script spawn) when approaching someone in the group.

 

Hello colleague, I need some help because I am a layman with the script and English is not my native language.

 

I would like to know how to get my character to join and lead a group that was generated by script, but only when I get close to any of the members of that group.


The group-creating script I already know how to do, it's just my character's need to join the group when they get close to some of the group's soldiers.

 

 

Doubt 2

 

How do I get a player to only be attacked when I am inside an area created by the trigger, where if I leave this area I am no longer attacked?

 

 

Here I leave my thanks to whoever can help me.

Share this post


Link to post
Share on other sites

Hey if you want to write your own script lol I am no help but there are many scripts all ready out there you can just add to your mission. I use MCC with most of my missions for the group commander spot. Just look on armaholic or a fast  Google search will give you results. 

  • Like 1

Share this post


Link to post
Share on other sites

You could place this into initPlayerLocal.sqf in mission root:

 


GOM_fnc_actionConditionRecruit = {

params ["_this","_target"];

(_target isequalto _this AND {_target isequalto vehicle _target} and {(cursorobject != objnull)} AND {side cursorobject in ([side _this] call BIS_fnc_friendlySides)} AND {_target distance cursorobject <= 15})

};


player addAction ["Recruit",{

[cursorobject] join group player;

},[],0,true,true,"","[_this,_target] call GOM_fnc_actionConditionRecruit"];

Lets you recruit any unit from a side you're friendly towards and within 15m.

 

Cheers

  • Like 8

Share this post


Link to post
Share on other sites
On 07/08/2017 at 0:05 AM, Grumpy Old Man said:

You could place this into initPlayerLocal.sqf in mission root:

 



GOM_fnc_actionConditionRecruit = {

params ["_this","_target"];

(_target isequalto _this AND {_target isequalto vehicle _target} and {(cursorobject != objnull)} AND {side cursorobject in ([side _this] call BIS_fnc_friendlySides)} AND {_target distance cursorobject <= 15})

};


player addAction ["Recruit",{

[cursorobject] join group player;

},[],0,true,true,"","[_this,_target] call GOM_fnc_actionConditionRecruit"];

Lets you recruit any unit from a side you're friendly towards and within 15m.

 

Cheers

 

It worked flawlessly.

 

Many thanks for the help.

 

@avibird 1

 

I know the MCC, but I wanted something that does not use "Addon".

 

Thanks for the help too.

  • Like 2

Share this post


Link to post
Share on other sites

Is there another option that can be used other than 'BIS_fnc_friendlySides' or can it simply specify a faction?

 

The reason why is Independent still tries to recruit FIA blufor even though allegiance has been set to enemy in the attributes, it also activates around dead bodies 'i think'

Share this post


Link to post
Share on other sites
On 8/6/2017 at 10:05 PM, Grumpy Old Man said:

You could place this into initPlayerLocal.sqf in mission root:

 



GOM_fnc_actionConditionRecruit = {

params ["_this","_target"];

(_target isequalto _this AND {_target isequalto vehicle _target} and {(cursorobject != objnull)} AND {side cursorobject in ([side _this] call BIS_fnc_friendlySides)} AND {_target distance cursorobject <= 15})

};


player addAction ["Recruit",{

[cursorobject] join group player;

},[],0,true,true,"","[_this,_target] call GOM_fnc_actionConditionRecruit"];

Lets you recruit any unit from a side you're friendly towards and within 15m.

 

Cheers

Grumpy,

How Could I edit this to include a leave option as well.

Humbly,

Reed

Share this post


Link to post
Share on other sites
12 hours ago, Jnr4817 said:

Grumpy,

How Could I edit this to include a leave option as well.

Humbly,

Reed

 

Depends on how you want to handle it, should every group join its own group? Or should it join the nearest group of the same side that has no players in it?

 

GOM_fnc_actionConditionLeave = {

params ["_this","_target"];

(_target isequalto _this AND {_target isequalto vehicle _target} and {(cursorobject != objnull)} AND {cursorobject in units group player} AND {_target distance cursorobject <= 15})

};


player addAction ["Dismiss",{
params ["_object","_caller"];

_newGroup = createGroup side _caller
[cursorobject] join _newGroup;

},[],0,true,true,"","[_this,_target] call GOM_fnc_actionConditionLeave"];

 

Cheers

Share this post


Link to post
Share on other sites

I guess, it would be I join my dedicated server and am wanting to add 4 AI to my group to complete a Ghost task. I can just walk up to a medic, AT, AA, and Engineer and recruit them via addaction. Say I am done with them I can then Dismiss them as a group or individual. I am also using Duda's AIC.

 

Thanks for helping me,

Reed

This is currently what we are using, but I am getting errors and am trying to improve it.

Spoiler

if(!isDedicated) then {

	[] spawn {

		while {true} do {
			_allAiUnits = [getPos player, 30, {alive _x}] call SA_fnc_getNearEntities;
			{
				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;
		};

	};

};

 

Spoiler

/*
	Author: [SA] Duda
	
	Description:
	Get near entities optionally matching some criteria
	
	Parameters:
		0: ARRAY - Search center position [X,Y]
		1: NUMBER (OPTIONAL) - Search radius in meters (default 50)
		2: FUNCTION (OPTIONAL) - Function to test for criteria (must return true - unit being tested is identified by _x variable) 
			If not defined, all near entities will be returned.
	
	Returns:
	ARRAY - Array of playable units matching some criteria
*/

private ["_position","_radius","_filteredEntities","_function","_allEntities","_allObjects"];
_position = [_this,0] call BIS_fnc_param;
_radius = [_this,1,50] call BIS_fnc_param;
_function = [_this,2,{true}] call BIS_fnc_param;
//_allEntities = _position nearEntities _radius;
_allObjects = nearestObjects [_position, [], _radius];
_filteredEntities = [];
{
	if(alive _x) then {
		if([] call _function) then {
			_filteredEntities = _filteredEntities + [_x];
		};
	};
}	
forEach _allObjects;
_filteredEntities;

 

 

Share this post


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

 

Depends on how you want to handle it, should every group join its own group? Or should it join the nearest group of the same side that has no players in it?

 


GOM_fnc_actionConditionLeave = {

params ["_this","_target"];

(_target isequalto _this AND {_target isequalto vehicle _target} and {(cursorobject != objnull)} AND {cursorobject in units group player} AND {_target distance cursorobject <= 15})

};


player addAction ["Dismiss",{
params ["_object","_caller"];

_newGroup = createGroup side _caller
[cursorobject] join _newGroup;

},[],0,true,true,"","[_this,_target] call GOM_fnc_actionConditionLeave"];

 

Cheers

I tried both the Recruit and the Dismiss. I was able to recruit ai but could not dismiss.

 

THanks again for your hard work on this.

Reed

  • Like 1

Share this post


Link to post
Share on other sites

You almost never see me in everyday use, yet I am important in .sqf.

Without me nothing works and you'll receive a script error.

 

If you can solve this riddle then you can fix the snippet above.

 

Cheers

  • Like 2

Share this post


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

You almost never see me in everyday use, yet I am important in .sqf.

Without me nothing works and you'll receive a script error.

 

If you can solve this riddle then you can fix the snippet above.

 

Cheers

Is it a ; after _caller?

  • Like 2

Share this post


Link to post
Share on other sites
1 hour ago, Grumpy Old Man said:

It is indeed, chief eagle eye.

 

Cheers

Buahaha,

Thanks,

Share this post


Link to post
Share on other sites

The function works great, however when ever I respawn in multiplayer hosted or dedicated it stops working.

 

Can I add the  player addEventHandler ["Respawn", {call GOM_fnc_***}]; to the initplayerlocal.sqf

Spoiler

//Recruit
GOM_fnc_actionConditionRecruit = {

params ["_this","_target"];

(_target isequalto _this AND {_target isequalto vehicle _target} and {(cursorobject != objnull)} AND {side cursorobject in ([side _this] call BIS_fnc_friendlySides)} AND {_target distance cursorobject <= 15})

};


player addAction ["Recruit",{

[cursorobject] join group player;

},[],0,true,true,"","[_this,_target] call GOM_fnc_actionConditionRecruit"];

player addEventHandler ["Respawn", {call GOM_fnc_actionConditionRecruit}];

//Dismiss
GOM_fnc_actionConditionLeave = {

params ["_this","_target"];

(_target isequalto _this AND {_target isequalto vehicle _target} and {(cursorobject != objnull)} AND {cursorobject in units group player} AND {_target distance cursorobject <= 15})

};


player addAction ["Dismiss",{
params ["_object","_caller"];

_newGroup = createGroup side _caller;
[cursorobject] join _newGroup;

},[],0,true,true,"","[_this,_target] call GOM_fnc_actionConditionLeave"];

 player addEventHandler ["Respawn", {call GOM_fnc_actionConditionLeave}];

 

Thanks,

Reed

Share this post


Link to post
Share on other sites

No player addAction is persistent when respawn. Yo need to add it (them) in onPlayerResapwn.sqf or by mission EH "entityRespawned"

 

Just another thing: cursorobject can return the primary weapon (object) instead of the unit itself. cursorTarget is far better for your purpose.

  • Like 1

Share this post


Link to post
Share on other sites

Ok I changed to cursorTraget and added the addmissioneventhandler, going to test later. How would use the onplayerrespawn.sqf as another option.

 

Spoiler

//Recruit
GOM_fnc_actionConditionRecruit = {

params ["_this","_target"];

(_target isequalto _this AND {_target isequalto vehicle _target} and {(cursorTarget != objnull)} AND {side cursorTarget in ([side _this] call BIS_fnc_friendlySides)} AND {_target distance cursorTarget <= 15})

};


player addAction ["Recruit",{

[cursorTarget] join group player;

},[],0,true,true,"","[_this,_target] call GOM_fnc_actionConditionRecruit"];

addMissionEventHandler ["EntityRespawned", {player call GOM_fnc_actionConditionRecruit}];

//Dismiss
GOM_fnc_actionConditionLeave = {

params ["_this","_target"];

(_target isequalto _this AND {_target isequalto vehicle _target} and {(cursorTarget != objnull)} AND {cursorTarget in units group player} AND {_target distance cursorTarget <= 15})

};


player addAction ["Dismiss",{
params ["_object","_caller"];

_newGroup = createGroup side _caller;
[cursorTarget] join _newGroup;

},[],0,true,true,"","[_this,_target] call GOM_fnc_actionConditionLeave"];

addMissionEventHandler ["EntityRespawned", {player call GOM_fnc_actionConditionLeave}];

 

 

What format is better?

Spoiler

addMissionEventHandler ["entityRespawned", {player call GOM_fnc_actionConditionRecruit}];

OR

addMissionEventHandler ["entityRespawned", { 
    params ["player"];
    player call GOM_fnc_actionConditionRecruit
  }]
};

 

 

Share this post


Link to post
Share on other sites
1 hour ago, Grumpy Old Man said:

I'd be surprised if the second one would actually work.

 

Cheers

 

Either of those options haven't worked :dontgetit:

Share this post


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

Ok I changed to cursorTraget and added the addmissioneventhandler, going to test later. How would use the onplayerrespawn.sqf as another option.

 

  Reveal hidden contents


//Recruit
GOM_fnc_actionConditionRecruit = {

params ["_this","_target"];

(_target isequalto _this AND {_target isequalto vehicle _target} and {(cursorTarget != objnull)} AND {side cursorTarget in ([side _this] call BIS_fnc_friendlySides)} AND {_target distance cursorTarget <= 15})

};


player addAction ["Recruit",{

[cursorTarget] join group player;

},[],0,true,true,"","[_this,_target] call GOM_fnc_actionConditionRecruit"];

addMissionEventHandler ["EntityRespawned", {player call GOM_fnc_actionConditionRecruit}];

//Dismiss
GOM_fnc_actionConditionLeave = {

params ["_this","_target"];

(_target isequalto _this AND {_target isequalto vehicle _target} and {(cursorTarget != objnull)} AND {cursorTarget in units group player} AND {_target distance cursorTarget <= 15})

};


player addAction ["Dismiss",{
params ["_object","_caller"];

_newGroup = createGroup side _caller;
[cursorTarget] join _newGroup;

},[],0,true,true,"","[_this,_target] call GOM_fnc_actionConditionLeave"];

addMissionEventHandler ["EntityRespawned", {player call GOM_fnc_actionConditionLeave}];

 

 

What format is better?

  Reveal hidden contents


addMissionEventHandler ["entityRespawned", {player call GOM_fnc_actionConditionRecruit}];

OR

addMissionEventHandler ["entityRespawned", { 
    params ["player"];
    player call GOM_fnc_actionConditionRecruit
  }]
};

 

 

 

In an EH, try to avoid player variable. it's easy here (_this select 0) does the trick.
 

Share this post


Link to post
Share on other sites
addMissionEventHandler ["EntityRespawned", {this select 0 call GOM_fnc_actionConditionRecruit;}];

addMissionEventHandler ["EntityRespawned", {this select 0 call GOM_fnc_actionConditionLeave;}];

 

Share this post


Link to post
Share on other sites

Now, just a 2 cent question about where to fire MEHs ?

As you can see, EHs description come with AL EG....   but not MEH.

So, MEH can be fired on server only. well...

I experienced some difficulties with that. in this case, the code will fire on server only. You need to use some global commands for global effects. Obvious?

 

Let's see a script to keep the exact loadout and ammo count on respawn. There are several commands/functions to make it work properly. Especially if you want the remaining ammo count on each mag, and clean the corpse to avoid weapons/mags multiplication. (see other post for code)

That means to passe some variables from server where the code runs, to client who died/respawned. It's possible to publicVariable them.

 

So, the question here could be:

- fire MEH on each PC and treat locally (I chose this way). MEH is in init.sqf, then in code:  if (local _killed) then {...}

- or fire MEH on server, then broadcast some variables . MEH is in initServer.sqf and think about remoteExec/publicVariable all thing "attached" to the victim.

 

Open discussion of course.

 

Share this post


Link to post
Share on other sites

So right now, both functions, the Recruit and the Dismiss are initialized in the initplayerlocal.sqf.

However, when the player dies, the player needs to run the script again so they can continue to Recruit or Dismiss.

 

This can be via the server, onplayerrespawn.sqf, with the EH or MEH, yet must be global, so init.sqf or initserver.sqf.

 

We are using the default BIS respawn at the moment. Unlike the loadout function I believe you are referring to

Spoiler

addMissionEventHandler ["entityKilled", {
  _victim = _this select 0;
  if (local _victim) then {
    [_victim, [missionNamespace, name _victim]] call BIS_fnc_saveInventory; 
    _victim setVariable ["MGI_ammo1",_victim ammo (primaryWeapon _victim)];
    _victim setVariable ["MGI_ammo2",_victim ammo (handgunWeapon _victim)];
    _victim setVariable ["MGI_ammo3",_victim ammo (secondaryWeapon _victim)];
    _victim setVariable ["MGI_mags",magazinesAmmoFull _victim];
    _victim setVariable ["MGI_weapon",currentWeapon _victim];
  };
}];

addMissionEventHandler ["entityRespawned", {
  _unit = _this select 0;
  _corpse = _this select 1;
  if (local _unit) then {
    [_unit, [missionNamespace, name _unit]] call BIS_fnc_loadInventory;
    {_unit removeMagazine _x} forEach magazines _unit;
    _unit setAmmo [primaryWeapon _unit, 0];
    _unit setAmmo [handGunWeapon _unit, 0];
    _unit setAmmo [secondaryWeapon _unit, 0];
    {
      if (((_unit getVariable "MGI_mags") select _foreachindex select 3) <= 0) then {
        _unit addMagazine [_x select 0,_x select 1]
      }
    } forEach (_unit getVariable "MGI_mags");
    _unit setAmmo [primaryWeapon _unit,_unit getVariable "MGI_ammo1"];
    _unit setAmmo [handGunWeapon _unit,_unit getVariable  "MGI_ammo2"];
    _unit setAmmo [secondaryWeapon _unit,_unit getVariable "MGI_ammo3"];
    _unit selectWeapon (_unit getVariable "MGI_weapon");
    removeAllWeapons _corpse;
    removeBackpackGlobal _corpse;
    removeVest _corpse;
    removeAllAssignedItems _corpse;
    removeAllItems _corpse;
    removeGoggles _corpse;
    removeHeadgear _corpse;
    {deleteVehicle _x} forEach nearestObjects [(getPosATL _corpse),["WeaponHolderSimulated","groundWeaponHolder"],5];
  };
}];

 

 

I just the need the respawned player to run the function again, so they can recruit and dismiss AI or other players to their group.

 

I am I getting close?

addMissionEventHandler ["entityRespawned", {
  _player = _this select 0;
  if (local _player) then {
    [_player, [missionNamespace, name _player]] call GOM_fnc_actionConditionRecruit;
	
  };
}];

 

 

Share this post


Link to post
Share on other sites

Snake, Hi. Your can do this with ONE TRIGGER, in the eden editor. name your player character whatever you like, "p_1" for example. Then name your units you want to join you when you get close. For example, "S_1", then place down a trigger with a radius of your choosing. Set the trigger owner to the player character. The in the on activation field type:                [s_1] join (group player);                     . For multiple units joining your player character, repeat this code with every units varible name. example:   [s_1] join (group player);[s_2] join (group player);[s_3] join (group player);                          . When the player character enters the trigger area, the listed units "s_1" will join the players group. I have made two example missions for you.

 

example mission for one unit joining you.

http://steamcommunity.com/sharedfiles/filedetails/?id=1142359601

 

example mission for multiple units joining you.

http://steamcommunity.com/sharedfiles/filedetails/?id=1142360822

 

I hope this helps.

Share this post


Link to post
Share on other sites
21 hours ago, Jnr4817 said:

So right now, both functions, the Recruit and the Dismiss are initialized in the initplayerlocal.sqf.

However, when the player dies, the player needs to run the script again so they can continue to Recruit or Dismiss.

 

I am I getting close?


addMissionEventHandler ["entityRespawned", {
  _player = _this select 0;
  if (local _player) then {
    [_player, [missionNamespace, name _player]] call GOM_fnc_actionConditionRecruit;
	
  };
}];

 

 

 

No, you need to addAction like you did at start.

What you are doing is just calling the condition code, with no action!

Usually, it's simple to wrap the entire code in a function, then cal the function at start and recall it at respawn. Here, your code recall a bit of code, not sufficient.

And, I don't know why you have copy/paste missionNameSpace in your code... It was an example for a general question, not your solution.

 

fn_LetGoAction = { all the code you need for a player addAction, or several here}

in init.sqf:

addMissionEventHandler ["entityRespawned", {

  _unit = _this select 0;

  if (local _unit && isPlayer _unit) then {

   call fn_LetGoAction

  };

}];

 

There is no parameter here. You apply an addAction to player (already defined, and _target is cursorTarget (defined in code).

Then, the GOM codes refer to some params for more clarity, using a separate function to check the addAction condition. It's fine like this, but all the code must be in the final function (fn_LetGoAction here).
 

 

That's the principle.

Now, a step further:

 if you write the GOM_fnc_actionConditiontRecruit and the GOM_fnc_actionConditonLeave in the init.sqf, the functions are persistent like any other global variable. That means you don't need to rewrite them in the MEH entityRespawned.

You need to rewrite the addAction only:

 

Spoiler

 


fn_LetGoAction = {

  player addAction ["Recruit",{

   [cursorobject] join group player;

  },[],0,true,true,"","[_this,_target] call GOM_fnc_actionConditionRecruit"];

  
  player addAction ["Dismiss",{

   params ["_object","_caller"];

   _newGroup = createGroup side _caller;

   [cursorobject] join _newGroup;

  },[],0,true,true,"","[_this,_target] call GOM_fnc_actionConditionLeave"];

};

 

 

  • Like 1

Share this post


Link to post
Share on other sites

Ok have been messing around with this and still cant get to work like I want it.

 

First, thanks for the help. I am learning as I go and scripting is not my forte, I work on people for a living.

 

What I have done now is place this code in init.sqf

Spoiler

addMissionEventHandler ["entityRespawned", { 
  _unit = _this select 0; 
  if (local _unit && isPlayer _unit) then { 
   call fn_LetGoAction 
  }; 
}]; 

 

 

Then in the initplayerlocal.sqf placed this code

Spoiler

fn_LetGoAction = {

  player addAction ["Recruit",{

   [cursorobject] join group player;

  },[],0,true,true,"","[_this,_target] call GOM_fnc_actionConditionRecruit"];

  
  player addAction ["Dismiss",{

   params ["_object","_caller"];

   _newGroup = createGroup side _caller;

   [cursorobject] join _newGroup;

  },[],0,true,true,"","[_this,_target] call GOM_fnc_actionConditionLeave"];

};

 

 

Finally placed the functions in a function folder in the mission folder. Mission/SA/functions

Spoiler

//Squad Join
GOM_fnc_actionConditionRecruit = {

params ["_this","_target"];

(_target isequalto _this AND {_target isequalto vehicle _target} and {(cursorobject != objnull)} AND {side cursorobject in ([side _this] call BIS_fnc_friendlySides)} AND {_target distance cursorobject <= 5})

};

//Squad Leave
GOM_fnc_actionConditionLeave = {

params ["_this","_target"];

(_target isequalto _this AND {_target isequalto vehicle _target} and {(cursorobject != objnull)} AND {cursorobject in units group player} AND {_target distance cursorobject <= 5})

};

 

 

I hope I have hust misplaced some code, but feel Im still of base.

 

Reed

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

×