Jump to content
Solidsnacks

Change spawned AI loadout by class

Recommended Posts

I'm trying to change the loadout of a unit spawned with https://community.bistudio.com/wiki/BIS_fnc_spawnGroup

Right now, I'm able to spawn in a group of units and modify all of their gear, but I wanted to take it a step further and modify each group member's gear specifically.

I've been looking for a means to check the class of a unit and execute custom code for said unit class, but I haven't turned up anything useful outside of defining individual units and their gear then putting them into a group.

I spawn the group like this:

contact1 = [getMarkerPos "con1", Independent, ["I_soldier_F", "I_soldier_F","I_Soldier_AR_F","I_Soldier_GL_F"],[],["Sergeant","Corporal","Private","Private"],[],[],[2,.5],330] call BIS_fnc_spawnGroup;
};

And I modify the group like this:

{	
if (contact1 == group _x) then {
	removeHeadgear _x;
	removeAllPrimaryWeaponItems _x;
	_x addHeadgear "H_Shemag_olive_hs";
	_x unassignItem "NVGoggles_INDEP";
	_x removeItem "NVGoggles_INDEP";
	_x unassignItem "ItemMap";
	_x removeItem "ItemMap";
};
} foreach units contact1;	

After the above I hit a wall when trying to further define the gear of individual units in the group.

I've tried variations like:

{
if (_x == typeof I_soldier_F) then {
removeallWeapons _x;
_x addMagazines ["30Rnd_556x45_Stanag", 3];
_x addMagazine "HandGrenade";
_X addWeapon "Arifle_MK20_F";
};
}		

And:

{
if {(contact1 == group _x)} and {(_x = typeof "I_Soldier_F")} do
	{
		removeallWeapons _x;
		};
};

Admittedly I'm shooting in the dark here. If anyone can point me in the right direction, I would be very grateful.

Share this post


Link to post
Share on other sites

You're usage if typeOf and config comparisons doesn't work, try this:

if (_x isKindOf "I_soldier_F") then {
   // Run loadout for "I_soldier_F" here
};

---------- Post added at 19:55 ---------- Previous post was at 19:51 ----------

And even better, you can use a switch statement:

{ // forEach
removeHeadgear _x;
removeAllPrimaryWeaponItems _x;
switch (true) do {
	case (_x isKindOf "I_soldier_F"): {
		_x addMagazines ["30Rnd_556x45_Stanag", 3];
		_x addMagazine "HandGrenade";
		_X addWeapon "Arifle_MK20_F";
	};
	case (_x isKindOf "I_Soldier_AR_F"): {
		// Set gear loadout here
	};
};
} foreach (units contact1);

Share this post


Link to post
Share on other sites

That worked perfectly! :cheers:

I had been looking at switch statements but was having a hard time wrapping my head around them.

Excuse me just one more question: how was _x referenced in your example?

To me it looked like it would have given back an undefined variable.

At any rate. Thanks again!

Share this post


Link to post
Share on other sites

_x is used in the foreach loop command. So here, the foreach loops runs on each soldier, and each time _x is a soldier defined after the foreach command.

{_x addWeapon "weapon"} foreach (units contact1)

The loop runs for each unit in contact1. Each time, _x is one unit in the group. And then the next, and the next, and so on. The loop ends when it has been run for each unit.

Without foreach, and before and after the loop, _x is undefined and returns nothing.

Share this post


Link to post
Share on other sites

gents im wondering if you can help me

currently the only way i know how to spawn in guerrilla looking units (for opfor) is like this

private ["_pos"];
_pos = _this select 0;


private ["_grp", "_pos"];
_pos = markerPos "enemy_spawn_mrk_obj1";
_grp = [_pos, EAST, (configfile >> "CfgGroups" >> "West" >> "Guerilla" >> "Infantry" >> "IRG_InfTeam")] call BIS_fnc_spawnGroup;
[_grp, _pos, 50] call BIS_fnc_taskPatrol;

private ["_grp", "_pos"];
_pos = markerPos "enemy_spawn_mrk_obj2";
_grp = [_pos, EAST, (configfile >> "CfgGroups" >> "West" >> "Guerilla" >> "Infantry" >> "IRG_InfTeam")] call BIS_fnc_spawnGroup;
[_grp, _pos, 50] call BIS_fnc_taskPatrol;


id like to edit the loadouts but as you can see the groups arn't named such as contact1 in your example

is there clever way i can edit their loadouts but without using a group name in the switch (foreach contact1)

Edited by randy andy tw1

Share this post


Link to post
Share on other sites

The difference between _grp and contact1 is only that the latter is global while the other is only a local variable. But both reference a group within their given scope. What you can do is:

private ["_pos"];
_pos = _this select 0;


private ["_grp", "_pos"];
_pos = markerPos "enemy_spawn_mrk_obj1";
_grp = [_pos, EAST, (configfile >> "CfgGroups" >> "West" >> "Guerilla" >> "Infantry" >> "IRG_InfTeam")] call BIS_fnc_spawnGroup;
[_grp, _pos, 50] call BIS_fnc_taskPatrol;

      [color="#0000CD"]{
         // Do stuff here
      } forEach (units _grp);[/color]

private ["_grp", "_pos"];
_pos = markerPos "enemy_spawn_mrk_obj2";
_grp = [_pos, EAST, (configfile >> "CfgGroups" >> "West" >> "Guerilla" >> "Infantry" >> "IRG_InfTeam")] call BIS_fnc_spawnGroup;
[_grp, _pos, 50] call BIS_fnc_taskPatrol;

         [color="#0000CD"]{
         // Do stuff here
      } forEach (units _grp);[/color]

Share this post


Link to post
Share on other sites
The difference between _grp and contact1 is only that the latter is global while the other is only a local variable. But both reference a group within their given scope. What you can do is:

private ["_pos"];
_pos = _this select 0;


private ["_grp", "_pos"];
_pos = markerPos "enemy_spawn_mrk_obj1";
_grp = [_pos, EAST, (configfile >> "CfgGroups" >> "West" >> "Guerilla" >> "Infantry" >> "IRG_InfTeam")] call BIS_fnc_spawnGroup;
[_grp, _pos, 50] call BIS_fnc_taskPatrol;

      [color="#0000CD"]{
         // Do stuff here
      } forEach (units _grp);[/color]

private ["_grp", "_pos"];
_pos = markerPos "enemy_spawn_mrk_obj2";
_grp = [_pos, EAST, (configfile >> "CfgGroups" >> "West" >> "Guerilla" >> "Infantry" >> "IRG_InfTeam")] call BIS_fnc_spawnGroup;
[_grp, _pos, 50] call BIS_fnc_taskPatrol;

         [color="#0000CD"]{
         // Do stuff here
      } forEach (units _grp);[/color]

Im not sure the best way to go about this but i have tried a few things. i might be looking at this entirely wrong though. I have used the isKindof statement with the config faction of the units "BLU_G_F". anyway here is what i have done using some of the above code and it doesnt work. im thinking its more to do with the "BLU_G_F".

ultimately what i am trying to do is remove all the weapons, and then assign them a new weapon. but ive started with the head gear as its something easily visible to see if the script works. using show script errors, i can see that there is an error in what i have done.

	private ["_pos", "_grp"];
_pos = markerPos "enemy_spawn_mrk_obj1";
_grp = [_pos, EAST, (configfile >> "CfgGroups" >> "West" >> "Guerilla" >> "Infantry" >> "IRG_InfTeam")] call BIS_fnc_spawnGroup;
[_grp, _pos, 50] call BIS_fnc_taskPatrol;


if (_x isKindOf "BLU_G_F") then 
{
       removeHeadgear _x;
	removeAllPrimaryWeaponItems _x;
	_x addHeadgear "H_Shemag_olive_hs";
      } forEach (units _grp);

Share this post


Link to post
Share on other sites

1. You probably want to check for typeOf not isKindOf here, as you're checking for a specific type of unit.

2. The if needs to go inside the forEach scope, as you're testing the _x which only exists within it.


{ 
          if (typeOf _x == "BLU_G_F") then 
       removeHeadgear _x;
	removeAllPrimaryWeaponItems _x;
	_x addHeadgear "H_Shemag_olive_hs";
};
      } forEach (units _grp);

Share this post


Link to post
Share on other sites

I do apologise Wolfenswan, i have now used

	private ["_pos", "_grp"];
_pos = markerPos "enemy_spawn_mrk_obj1";
_grp = [_pos, EAST, (configfile >> "CfgGroups" >> "West" >> "Guerilla" >> "Infantry" >> "IRG_InfTeam")] call BIS_fnc_spawnGroup;
[_grp, _pos, 50] call BIS_fnc_taskPatrol;

{ // forEach
removeHeadgear _x;
removeAllPrimaryWeaponItems _x;
switch (true) do {
	case (_x isKindOf "B_G_Soldier_AR_F"): {
		_x addMagazines ["30Rnd_556x45_Stanag", 3];
		_x addMagazine "HandGrenade";
		_X addWeapon "Arifle_MK20_F";
	};
};
} foreach (units _grp);

which works

Share this post


Link to post
Share on other sites

Looks good but if you want to do that for more classes this seems better:

switch (typeOf _x) do {
	case ("B_G_Soldier_AR_F"): {
		_x addMagazines ["30Rnd_556x45_Stanag", 3];
		_x addMagazine "HandGrenade";
		_X addWeapon "Arifle_MK20_F";
	};
              case ("B_G_Soldier_F"): {
		// whatever else
	};
              default { systemchat format ["%1 was not processed, class is %2",_x,typeOf_x]};
}; 

The default bit at the end fires whenever the type does not correspond to any case and puts out a short error message.

Share this post


Link to post
Share on other sites
Looks good but if you want to do that for more classes this seems better:

switch (typeOf _x) do {
	case ("B_G_Soldier_AR_F"): {
		_x addMagazines ["30Rnd_556x45_Stanag", 3];
		_x addMagazine "HandGrenade";
		_X addWeapon "Arifle_MK20_F";
	};
              case ("B_G_Soldier_F"): {
		// whatever else
	};
              default { systemchat format ["%1 was not processed, class is %2",_x,typeOf_x]};
}; 

The default bit at the end fires whenever the type does not correspond to any case and puts out a short error message.

wasnt sure where to place this but this is where I have put it. either way, arma3 wants to murder me right now.

private ["_pos", "_grp"];
_pos = markerPos "enemy_spawn_mrk_obj1";
_grp = [_pos, EAST, (configfile >> "CfgGroups" >> "West" >> "Guerilla" >> "Infantry" >> "IRG_InfTeam")] call BIS_fnc_spawnGroup;
[_grp, _pos, 50] call BIS_fnc_taskPatrol;

{ // forEach
removeHeadgear _x;
removeAllPrimaryWeaponItems _x;
switch (typeOf _x) do {
	case ("B_G_Soldier_AR_F"): {
		_x addMagazines ["30Rnd_556x45_Stanag", 3];
		_x addMagazine "HandGrenade";
		_X addWeapon "Arifle_MK20_F";
	};
              case ("B_G_Soldier_F"): {
		// whatever else
	};
              default { systemchat format ["%1 was not processed, class is %2",_x,typeOf_x]};
};

and

private ["_pos", "_grp"];
_pos = markerPos "enemy_spawn_mrk_obj1";
_grp = [_pos, EAST, (configfile >> "CfgGroups" >> "West" >> "Guerilla" >> "Infantry" >> "IRG_InfTeam")] call BIS_fnc_spawnGroup;
[_grp, _pos, 50] call BIS_fnc_taskPatrol;

switch (typeOf _x) do {
	case ("B_G_Soldier_AR_F"): {
		_x addMagazines ["30Rnd_556x45_Stanag", 3];
		_x addMagazine "HandGrenade";
		_X addWeapon "Arifle_MK20_F";
	};
              case ("B_G_Soldier_F"): {
		// whatever else
	};
              default { systemchat format ["%1 was not processed, class is %2",_x,typeOf_x]};
};

this one errors undefined variable in expression _x

Share this post


Link to post
Share on other sites

Warning, within the spoiler is a massive chunk of code.

Basically it's just what you need by the looks of it, though you'll need to the add the guerilla specific classnames (look at the autorifleman one as an example). Simply add your code in where necessary (and you can delete any classes that you don't need, e.g. recon ones don't have a guerilla equivalent. (I'd recommend filling in the default one with whatever you're giving your standard rifleman, means that a unit that is missed doesn't cause an issue). At the top of each class add in

[_x] call _removeItems; which gurantees you that they're starting from scratch.

private ["_pos", "_grp"];

_RemoveItems =	{	        Private ["_unit"];
                                       _unit=_this select 0;
				removeAllWeapons _unit;
				removeAllAssignedItems _unit;
				removeAllContainers _unit;
				removeHeadgear _unit;
				removeGoggles _unit;
			};
_pos = markerPos "enemy_spawn_mrk_obj1";
_grp = [_pos, EAST, (configfile >> "CfgGroups" >> "West" >> "Guerilla" >> "Infantry" >> "IRG_InfTeam")] call BIS_fnc_spawnGroup;
[_grp, _pos, 50] call BIS_fnc_taskPatrol;
{	
	_role=typeOf _x;
	switch (true) do 
	{	

		case (_role=="B_officer_F"||_role == "I_officer_F" || _role == "O_officer_F")://Officer
			{	
                                       [_x] call _removeItems;
				_x addMagazines ["30Rnd_556x45_Stanag", 3];
				_x addMagazine "HandGrenade";
				_X addWeapon "Arifle_MK20_F"
			};			

		case (_role=="B_medic_F"||_role == "I_medic_F" || _role == "O_medic_F")://Medic
			{	
			};

		case (_role=="B_soldier_AR_F"||_role == "I_soldier_AR_F" || _role == "O_soldier_AR_F" || _role=="B_G_Soldier_AR_F")://Autorifleman
			{	
			};

		case (_role=="B_soldier_A_F"||_role == "I_soldier_A_F" || _role == "O_soldier_A_F")://Ammo Bearer
			{
			};	

		case (_role=="B_crew_F"||_role == "I_crew_F" || _role == "O_crew_F")://Crewman
			{
			};	

		case (_role=="B_engineer_F"||_role == "I_engineer_F" || _role == "O_engineer_F")://Engineer
			{				
			};		

		case (_role=="B_soldier_exp_F"||_role == "I_soldier_exp_F" || _role == "O_soldier_exp_F")://Explosive Specialist
			{				
			};	

		case (_role=="B_soldier_GL_F"||_role == "I_soldier_GL_F" || _role == "O_soldier_GL_F")://Grenadier
			{				
			};	

		case (_role=="B_Soldier_lite_F"||_role == "I_Soldier_lite_F" || _role == "O_Soldier_lite_F")://Rifleman [Light]
			{				
			};		

		case (_role=="B_soldier_M_F"||_role == "I_soldier_M_F" || _role == "O_soldier_M_F")://Marksman
			{				
			};		

		case (_role=="B_soldier_AA_F"||_role == "I_soldier_AA_F" || _role == "O_soldier_AA_F")://Missile Specialist [AA]
			{				
			};		

		case (_role=="B_soldier_AT_F"||_role == "I_soldier_AT_F" || _role == "O_soldier_AT_F")://Missile Specialist [AT]
			{				
			};		



		case (_role=="B_soldier_PG_F"||_role == "I_soldier_PG_F" || _role == "O_soldier_PG_F")://Paratrooper
			{				
			};				

		case (_role=="B_soldier_repair_F"||_role == "I_soldier_repair_F" || _role == "O_soldier_repair_F")://Repair Specialist
			{				
			};				

		case (_role=="B_Soldier_F"||_role == "I_Soldier_F" || _role == "O_Soldier_F")://Rifleman
			{				
			};				

		case (_role=="B_soldier_LAT_F"||_role == "I_soldier_LAT_F" || _role == "O_soldier_LAT_F")://Rifleman [AT]
			{				
			};	

		case (_role=="b_soldier_unarmed_f"||_role == "i_soldier_unarmed_F" || _role == "o_soldier_unarmed_F")://Rifleman [unarmed]
			{				
			};	

		case (_role=="B_Soldier_SL_F"||_role == "I_Soldier_SL_F" || _role == "O_Soldier_SL_F")://Squad Leader
			{				
			};	

		case (_role=="b_survivor_F"||_role == "i_survivor_F" || _role == "o_survivor_F")://Survivor
			{				
			};	

		case (_role=="B_Soldier_TL_F"||_role == "I_Soldier_TL_F" || _role == "O_Soldier_TL_F")://Team Leader
			{				
			};		

		case (_role=="B_soldier_UAV_F"||_role == "I_soldier_UAV_F" || _role == "O_soldier_UAV_F")://UAV operator
			{				
			};		

		case (_role=="B_recon_exp_F"||_role == "O_recon_exp_F")://Recon Demolitionist
			{				
			};		

		case (_role=="B_recon_JTAC_F"||_role == "O_recon_JTAC_F")://Recon JTAC
			{				
			};		

		case (_role=="B_recon_M_F"||_role == "O_recon_M_F")://Recon Marksman
			{				
			};		

		case (_role=="B_recon_medic_F"||_role == "O_recon_medic_F")://Recon Medic
			{				
			};		

		case (_role=="B_recon_F"||_role == "O_recon_F")://Recon Scout
			{				
			};		

		case (_role=="B_recon_LAT_F"||_role == "O_recon_LAT_F")://Recon Scout [AT]
			{				
			};		

		case (_role=="B_recon_TL_F"|| _role == "O_recon_TL_F")://Recon TL
			{				
			};				

		case (_role=="B_sniper_F"|| _role == "I_sniper_F"|| _role == "O_sniper_F")://Sniper
				{				

				};		

		case (_role=="B_spotter_F"|| _role == "I_spotter_F"|| _role == "O_spotter_F")://Spotter
				{				
				};	

		case (_role=="B_soldier_AAR_F"|| _role == "I_soldier_AAR_F"|| _role == "O_soldier_AAR_F")://Assisstant Auto-Rifleman
				{				
				};	

		case (_role=="B_support_AMG_F"|| _role == "I_support_AMG_F"|| _role == "O_support_AMG_F")://Assisstant HMG/GMG Gunner
				{				
						};		

		case (_role=="B_support_AMort_F"|| _role == "I_support_AMortF"|| _role == "O_support_AMort_F")://Assisstant Mk6 Gunner
				{				
				};		

		case (_role=="B_soldier_AAA_F"|| _role == "I_soldier_AAA_F"|| _role == "O_soldier_AAA_F")://Assisstant missile Specialist [AA]
				{						
				};		

		case (_role=="B_soldier_AAT_F"|| _role == "I_soldier_AAT_F"|| _role == "O_soldier_AAT_F")://Assisstant missile Specialist [AT]
				{							
				};		

		case (_role=="B_support_GMG_F"|| _role == "I_support_GMG_F"|| _role == "O_support_GMG_F")://Gunner GMG
				{				
				};

		case (_role=="B_support_MG_F"|| _role == "I_support_MG_F"|| _role == "O_support_MG_F")://Gunner HMG
				{				
				};	

		case (_role=="B_support_Mort_F"|| _role == "I_support_Mort_F"|| _role == "O_support_Mort_F")://Gunner Mortar
				{				
				};		

		case (_role == "B_Pilot_F" or _role == "I_Pilot_F" or _role == "O_Pilot_F")://Pilot
			{	
			};		

		case (_role == "B_Helipilot_F" or _role == "I_Helipilot_F" or _role == "O_Helipilot_F")://Helipilot
			{	
			};		

		case (_role == "B_helicrew_F" or _role == "I_helicrew_F" or _role == "O_helicrew_F")://Heli Crew
			{	
			};

                       default
			{
			};	
	};
} forEach units _grp;

Edited by Jona33

Share this post


Link to post
Share on other sites

thanks guys, using bits of what everyone has written, i have made a "it will do for now" bit of code.

My aim was to try to change everyones uniform etc, within every group.

Realizing it wasnt as easy as just saying "ive spawned 5 groups, make all of them use this" ive added in the equipment for each group separately. But, i can easily add using everyones examples, defined equipment BY class name to make each soldier in the group (dependent on the class name) have a different load out.

if (!isServer) exitWith {};
waituntil {!isnil "BIS_fnc_init"};

private ["_pos"];
_pos = _this select 0;


private ["_pos", "_grp"];
_pos = markerPos "enemy_spawn_mrk_obj1";
_grp = [_pos, EAST, (configfile >> "CfgGroups" >> "West" >> "Guerilla" >> "Infantry" >> "IRG_InfTeam")] call BIS_fnc_spawnGroup;
[_grp, _pos, 50] call BIS_fnc_taskPatrol;

{ // forEach
removeHeadgear _x:
removeGoggles _x;
removeUniform _x;
removeVest _x;
removeBackpack _x;
removeAllWeapons _x:
removeAllAssignedItems _x;
_x forceAddUniform "U_BG_Guerilla1_1";
_X addVest "V_Chestrig_rgr";
_x addMagazines ["30Rnd_9x21_Mag", 10];
_x addMagazine "HandGrenade";
_X addWeapon "hgun_PDW2000_F";
_x addPrimaryWeaponItem "optic_Aco_smg";

} foreach (units _grp);

sleep 0.5;
private ["_grp", "_pos"];
_pos = markerPos "enemy_spawn_mrk_obj1_1";
_grp = [_pos, EAST, (configfile >> "CfgGroups" >> "West" >> "Guerilla" >> "Infantry" >> "IRG_InfTeam")] call BIS_fnc_spawnGroup;
[_grp, _pos, 50] call BIS_fnc_taskPatrol;
{ // forEach
removeHeadgear _x:
removeGoggles _x;
removeUniform _x;
removeVest _x;
removeBackpack _x;
removeAllWeapons _x:
removeAllAssignedItems _x;
_x forceAddUniform "U_BG_Guerilla1_1";
_X addVest "V_Chestrig_rgr";
_x addMagazines ["30Rnd_9x21_Mag", 10];
_x addMagazine "HandGrenade";
_X addWeapon "hgun_PDW2000_F";
_x addPrimaryWeaponItem "optic_Aco_smg";

} foreach (units _grp);	

Thank you kindly for pointing me in the right direction guys :)

i have added sleepers so the units dont all spawn in at the same time. The timings work with my onload message so players dont see any stuttering while the groups spawn.

Share this post


Link to post
Share on other sites

I know this is an old post but is there any chance of sharing a mission of this with us? Thank you!

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

×