Jump to content
pierremgi

team switch - losing supports

Recommended Posts

Hi all,

Team switching is one of the weirdest feature in Arma. If you are playing in SP, with several switchable units, some behaviors can be lost.

If you switch, you can loose all supports (BI standard support modules).

Reproducible, Vanilla, 3den:

Add units: player + playable ones

Add an artillery (the support type doesn't matter, it's just an example)

Add the artillery provider module

add the requester module

link the artillery to the provider module, the provider to the requester module, the requester module to all switchable (playable in 3den) units.

 

Preview

Starting as player (the player unit in 3den), gives you the artillery support. No problem.
Starting "as character" from any other playable unit does the trick also. No problem.

 

But, each time you press "U" (or whatever key for switching menu) and you choose another unit, the support menu disappear.

 

NB 1: No matter the method used: editor or scripted links with  BIS_fnc_addSupportLink,  the supports are lost on team switching. Only the first unit played at start can call supports.

NB 2: a little workaround, tested but not guaranteed:

addMissionEventHandler ["teamSwitch", {
   BIS_requesterFSM = nil;
  [yourRequestModuleName] execVM "A3\modules_f\supports\init_requester.sqf";
}];

Now if you switch, the support works.... A remaining point I failed to correct: At your first support call after switching, a hint message will say: "provider not available". Which is wrong. The support works.

 

  • Like 3

Share this post


Link to post
Share on other sites

No, it doesn’t work and there’s an error.

 

Spoiler

j3-iZ0hk12s.jpg?size=1920x1200&quality=9

 

And here's what happens when I use your script "BI supports depending on radio backpack"  

 

 

Share this post


Link to post
Share on other sites

Your error is unreadable.

Which script? A link could help. I have tons of scripts, more or less adapted to peculiar requests, most of the time.

 

Share this post


Link to post
Share on other sites

@Brahma281 I have something from my ISIL Foothold mission you can use, Pierremgi helped me with this

a while back.   Basically put this code in your init.sqf

TransferProviders = {

	_oldUnit = _this select 0;
	_oldProviders = _oldUnit getVariable ["BIS_SUPP_allProviderModules",[]];
	_HQ = _oldUnit getVariable ["BIS_SUPP_HQ",objNull]; 

	if (isNil {player getVariable "BIS_SUPP_HQ"}) then { 
		if ((count _oldProviders) > 0) then {
			{
				_providerModule = _x;
				{
					if (typeOf _x == "SupportRequester" && _oldUnit in (synchronizedObjects _x)) then {
						[player, _x, _providerModule] call BIS_fnc_addSupportLink;
					};
				}forEach synchronizedObjects _providerModule;
			}forEach _oldProviders;
		};

		player setVariable ["BIS_SUPP_transmitting", false];
		player kbAddTopic ["BIS_SUPP_protocol", "A3\Modules_F\supports\kb\protocol.bikb", "A3\Modules_F\supports\kb\protocol.fsm", {call compile preprocessFileLineNumbers "A3\Modules_F\supports\kb\protocol.sqf"}];
		player setVariable ["BIS_SUPP_HQ", _HQ];
	};

	{
		_used = _oldUnit getVariable [format ["BIS_SUPP_used_%1",_x], 0];
		player setVariable [format ["BIS_SUPP_used_%1", _x], _used, true]
	} forEach [
		"Artillery",
		"CAS_Heli",
		"CAS_Bombing",
		"UAV",
		"Drop",
		"Transport"
	];
};


_thread = [] spawn {
	_unit = player;
	while {true} do {
		waitUntil {_unit != player };
		hintSilent " Player has changed";
		[_unit] call TransferProviders;
		_unit = player;
	};
};

When you die all your supports like calling for mortar support, or cas, or even a heli, will transfer

to the next playable unit you switch to.

 

  • Like 1

Share this post


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

Your error is unreadable.

 

I figured it out and made your code work without an error,but the same bug appears as shown in the video

 

13 hours ago, pierremgi said:

Which script? A link could help.

Here is this script As shown in the video, if the first unit calls support, and then another one calls it, an bug is obtained.

I believe it has something to do with "provider not available"

Share this post


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

@Brahma281 I have something from my ISIL Foothold mission you can use, Pierremgi helped me with this

a while back.   Basically put this code in your init.sqf


TransferProviders = {

	_oldUnit = _this select 0;
	_oldProviders = _oldUnit getVariable ["BIS_SUPP_allProviderModules",[]];
	_HQ = _oldUnit getVariable ["BIS_SUPP_HQ",objNull]; 

	if (isNil {player getVariable "BIS_SUPP_HQ"}) then { 
		if ((count _oldProviders) > 0) then {
			{
				_providerModule = _x;
				{
					if (typeOf _x == "SupportRequester" && _oldUnit in (synchronizedObjects _x)) then {
						[player, _x, _providerModule] call BIS_fnc_addSupportLink;
					};
				}forEach synchronizedObjects _providerModule;
			}forEach _oldProviders;
		};

		player setVariable ["BIS_SUPP_transmitting", false];
		player kbAddTopic ["BIS_SUPP_protocol", "A3\Modules_F\supports\kb\protocol.bikb", "A3\Modules_F\supports\kb\protocol.fsm", {call compile preprocessFileLineNumbers "A3\Modules_F\supports\kb\protocol.sqf"}];
		player setVariable ["BIS_SUPP_HQ", _HQ];
	};

	{
		_used = _oldUnit getVariable [format ["BIS_SUPP_used_%1",_x], 0];
		player setVariable [format ["BIS_SUPP_used_%1", _x], _used, true]
	} forEach [
		"Artillery",
		"CAS_Heli",
		"CAS_Bombing",
		"UAV",
		"Drop",
		"Transport"
	];
};


_thread = [] spawn {
	_unit = player;
	while {true} do {
		waitUntil {_unit != player };
		hintSilent " Player has changed";
		[_unit] call TransferProviders;
		_unit = player;
	};
};

When you die all your supports like calling for mortar support, or cas, or even a heli, will transfer

to the next playable unit you switch to.

 

Yes, thank you,this code works perfectly without the "provider not available" bug. But I would like to have the same script depending on the radio backpack as the one I posted above

Share this post


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

 

Yes, thank you,this code works perfectly without the "provider not available" bug. But I would like to have the same script depending on the radio backpack as the one I posted above

That's a different problem.

Once your "team switch" weird BI uncompleted feature is cured by the script above, feel free to add a new script for backpack radios like:

 

in initPlayerLocal.sqf

 

 

MGI_radios = ["UNS_alice_FR","UNS_USMC_RTO","UNS_USMC_RTO2","UNS_ARMY_RTO","UNS_ARMY_RTO2","UNS_SF_RTO","tf_rt1523g","tf_anprc155","tf_mr3000","tf_bussole","tf_anarc210","tf_anarc164","tf_mr6000l"];  // or what ever you want as backpack....

player spawn {
  _unit = _this;
  while {true} do {
    waituntil {sleep 2; (backpack _unit in MGI_radios or (backpack _unit) isKindOf "TFAR_bag_base")};
      publicVariable "count_drop";
      [_unit,req,cas1] call BIS_fnc_addSupportLink;
      [_unit,req,drop_veh] call BIS_fnc_addSupportLink;
      [_unit,req,arty1] call BIS_fnc_addSupportLink;
      waituntil {sleep 2; (!(backpack _unit in MGI_radios) && !((backpack _unit) isKindOf "TFAR_bag_base"))};
     [req,_unit] call BIS_fnc_removeSupportLink;
  };
};

 

Just adapt req  cas1 arty1  drop_veh  to your module names...

 

Share this post


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

That's a different problem.

Once your "team switch" weird BI uncompleted feature is cured by the script above, feel free to add a new script for backpack radios like:

 

in initPlayerLocal.sqf

 

 


MGI_radios = ["UNS_alice_FR","UNS_USMC_RTO","UNS_USMC_RTO2","UNS_ARMY_RTO","UNS_ARMY_RTO2","UNS_SF_RTO","tf_rt1523g","tf_anprc155","tf_mr3000","tf_bussole","tf_anarc210","tf_anarc164","tf_mr6000l"];  // or what ever you want as backpack....

player spawn {
  _unit = _this;
  while {true} do {
    waituntil {sleep 2; (backpack _unit in MGI_radios or (backpack _unit) isKindOf "TFAR_bag_base")};
      publicVariable "count_drop";
      [_unit,req,cas1] call BIS_fnc_addSupportLink;
      [_unit,req,drop_veh] call BIS_fnc_addSupportLink;
      [_unit,req,arty1] call BIS_fnc_addSupportLink;
      waituntil {sleep 2; (!(backpack _unit in MGI_radios) && !((backpack _unit) isKindOf "TFAR_bag_base"))};
     [req,_unit] call BIS_fnc_removeSupportLink;
  };
};

 

Just adapt req  cas1 arty1  drop_veh  to your module names...

 

Yes, it helped with the provider bug,but another problem happened

Now the support call depends on whether the "player" unit has an RTO backpack or not, if "playable" unit removes the backpack from their inventory, nothing will change

 

Share this post


Link to post
Share on other sites

OK, needs a little modif.... and optimization. This should work:

 

In initPlayerLocal.sqf:

 

MGI_radios = ["UNS_alice_FR","UNS_USMC_RTO","UNS_USMC_RTO2","UNS_ARMY_RTO","UNS_ARMY_RTO2","UNS_SF_RTO","tf_rt1523g","tf_anprc155","tf_mr3000","tf_bussole","tf_anarc210","tf_anarc164","tf_mr6000l"];  // or any backpack you want
 
MGI_radioSupport = {
 params ["_unit"];
 waitUntil {_unit == player};
 while {isPlayer _unit} do {
  waitUntil {sleep 2; (backpack _unit in MGI_radios or (backpack _unit) isKindOf "TFAR_bag_base") or !isPlayer _unit};
  if (isPlayer _unit) then {
   [_unit,req,cas1] call BIS_fnc_addSupportLink;
   [_unit,req,drop_veh] call BIS_fnc_addSupportLink;
   [_unit,req,arty1] call BIS_fnc_addSupportLink;
  };
  waitUntil {sleep 2; (!(backpack _unit in MGI_radios) && !((backpack _unit) isKindOf "TFAR_bag_base")) or !isPlayer _unit};
  if (isPlayer _unit) then {
   [req,_unit] call BIS_fnc_removeSupportLink;    
  }
 };
 hintSilent " Player has changed";
 private _providers = _unit getVariable ["BIS_SUPP_allProviderModules",[]];
 private _HQ = _unit getVariable ["BIS_SUPP_HQ",objNull];
 if (isNil {player getVariable "BIS_SUPP_HQ"}) then {
  if (count _providers > 0) then {
   {
    private _providerModule = _x;
    {
     if (typeOf _x == "SupportRequester" && _unit in (synchronizedObjects _x)) then {
      [player, _x, _providerModule] call BIS_fnc_addSupportLink;
     };
    } forEach synchronizedObjects _providerModule;
   } forEach _providers;
  };
  player setVariable ["BIS_SUPP_transmitting", false];
  player kbAddTopic ["BIS_SUPP_protocol", "A3\Modules_F\supports\kb\protocol.bikb", "A3\Modules_F\supports\kb\protocol.fsm", {call compile preprocessFileLineNumbers "A3\Modules_F\supports\kb\protocol.sqf"}];
  player setVariable ["BIS_SUPP_HQ", _HQ];
 };
 {
  _used = _unit getVariable [format ["BIS_SUPP_used_%1",_x], 0];
   player setVariable [format ["BIS_SUPP_used_%1", _x], _used, true]
 } forEach [ "Artillery", "CAS_Heli", "CAS_Bombing", "UAV", "Drop", "Transport" ];
 [req,player] call BIS_fnc_removeSupportLink;
 player spawn MGI_radioSupport;
};
 
player spawn MGI_radioSupport;

 

same as above, adapt req  cas1 arty1  drop_veh  to your module names...

 

  • Thanks 1

Share this post


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

OK, needs a little modif.... and optimization. This should work:

 

In initPlayerLocal.sqf:

 


MGI_radios = ["UNS_alice_FR","UNS_USMC_RTO","UNS_USMC_RTO2","UNS_ARMY_RTO","UNS_ARMY_RTO2","UNS_SF_RTO","tf_rt1523g","tf_anprc155","tf_mr3000","tf_bussole","tf_anarc210","tf_anarc164","tf_mr6000l"];  // or any backpack you want
 
MGI_radioSupport = {
 params ["_unit"];
 waitUntil {_unit == player};
 while {isPlayer _unit} do {
  waitUntil {sleep 2; (backpack _unit in MGI_radios or (backpack _unit) isKindOf "TFAR_bag_base") or !isPlayer _unit};
  if (isPlayer _unit) then {
   [_unit,req,cas1] call BIS_fnc_addSupportLink;
   [_unit,req,drop_veh] call BIS_fnc_addSupportLink;
   [_unit,req,arty1] call BIS_fnc_addSupportLink;
  };
  waitUntil {sleep 2; (!(backpack _unit in MGI_radios) && !((backpack _unit) isKindOf "TFAR_bag_base")) or !isPlayer _unit};
  if (isPlayer _unit) then {
   [req,_unit] call BIS_fnc_removeSupportLink;    
  }
 };
 hintSilent " Player has changed";
 private _providers = _unit getVariable ["BIS_SUPP_allProviderModules",[]];
 private _HQ = _unit getVariable ["BIS_SUPP_HQ",objNull];
 if (isNil {player getVariable "BIS_SUPP_HQ"}) then {
  if (count _providers > 0) then {
   {
    private _providerModule = _x;
    {
     if (typeOf _x == "SupportRequester" && _unit in (synchronizedObjects _x)) then {
      [player, _x, _providerModule] call BIS_fnc_addSupportLink;
     };
    } forEach synchronizedObjects _providerModule;
   } forEach _providers;
  };
  player setVariable ["BIS_SUPP_transmitting", false];
  player kbAddTopic ["BIS_SUPP_protocol", "A3\Modules_F\supports\kb\protocol.bikb", "A3\Modules_F\supports\kb\protocol.fsm", {call compile preprocessFileLineNumbers "A3\Modules_F\supports\kb\protocol.sqf"}];
  player setVariable ["BIS_SUPP_HQ", _HQ];
 };
 {
  _used = _unit getVariable [format ["BIS_SUPP_used_%1",_x], 0];
   player setVariable [format ["BIS_SUPP_used_%1", _x], _used, true]
 } forEach [ "Artillery", "CAS_Heli", "CAS_Bombing", "UAV", "Drop", "Transport" ];
 [req,player] call BIS_fnc_removeSupportLink;
 player spawn MGI_radioSupport;
};
 
player spawn MGI_radioSupport;

 

same as above, adapt req  cas1 arty1  drop_veh  to your module names...

 

Now it works, flawlessly, like clockwork, without bugs and errors. I am very happy and express my deep gratitude, because I tried to solve this problem on my own for a week,but it didn't work out.

 

Will this also work in multiplayer?

Share this post


Link to post
Share on other sites

Thank you very much @pierremgi for this code. It works!

Would you be able to extend this code to also support vehicle types as support requesters?

 

Cheers

 

MGI_radios = ["vn_o_pack_t884_01", "vn_o_pack_t884_ish54_01_pl", "vn_o_pack_t884_m1_01_pl", "vn_o_pack_t884_m38_01_pl", "vn_o_pack_t884_ppsh_01_pl", "vn_b_pack_prc77_01_m16_pl", "vn_b_pack_03_m3a1_pl", "vn_b_pack_03_xm177_pl", "vn_b_pack_03_type56_pl", "vn_b_pack_03", "vn_b_pack_prc77_01", "vn_b_pack_trp_04", "vn_b_pack_trp_04_02", "vn_b_pack_03", "vn_b_pack_03_02", "vn_b_pack_lw_06"];  // or any backpack you want
 
MGI_radioSupport = {
 params ["_unit"];
 waitUntil {_unit == player};
 while {isPlayer _unit} do {
  waitUntil {sleep 2; (backpack _unit in MGI_radios or (backpack _unit) isKindOf "TFAR_bag_base") or !isPlayer _unit};
  if (isPlayer _unit) then {
   [_unit,SupportRequester,cas1] call BIS_fnc_addSupportLink;
   [_unit,SupportRequester,supply1] call BIS_fnc_addSupportLink;
   [_unit,SupportRequester,gunship1] call BIS_fnc_addSupportLink;
   [_unit,SupportRequester,helo1] call BIS_fnc_addSupportLink;
   [_unit,SupportRequester,arty1] call BIS_fnc_addSupportLink;
  };
  waitUntil {sleep 2; (!(backpack _unit in MGI_radios) && !((backpack _unit) isKindOf "TFAR_bag_base")) or !isPlayer _unit};
  if (isPlayer _unit) then {
   [SupportRequester,_unit] call BIS_fnc_removeSupportLink;    
  }
 };
 hintSilent " Player has changed";
 private _providers = _unit getVariable ["BIS_SUPP_allProviderModules",[]];
 private _HQ = _unit getVariable ["BIS_SUPP_HQ",objNull];
 if (isNil {player getVariable "BIS_SUPP_HQ"}) then {
  if (count _providers > 0) then {
   {
    private _providerModule = _x;
    {
     if (typeOf _x == "SupportRequester" && _unit in (synchronizedObjects _x)) then {
      [player, _x, _providerModule] call BIS_fnc_addSupportLink;
     };
    } forEach synchronizedObjects _providerModule;
   } forEach _providers;
  };
  player setVariable ["BIS_SUPP_transmitting", false];
  player kbAddTopic ["BIS_SUPP_protocol", "A3\Modules_F\supports\kb\protocol.bikb", "A3\Modules_F\supports\kb\protocol.fsm", {call compile preprocessFileLineNumbers "A3\Modules_F\supports\kb\protocol.sqf"}];
  player setVariable ["BIS_SUPP_HQ", _HQ];
 };
 {
  _used = _unit getVariable [format ["BIS_SUPP_used_%1",_x], 0];
   player setVariable [format ["BIS_SUPP_used_%1", _x], _used, true]
 } forEach [ "Artillery", "CAS_Heli", "CAS_Bombing", "UAV", "Drop", "Transport" ];
 [SupportRequester,player] call BIS_fnc_removeSupportLink;
 player spawn MGI_radioSupport;
};
 
player spawn MGI_radioSupport;

 

Share this post


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

Will this also work in multiplayer?

Yes but you need to add

if (isServer) then {
waitUntil {!(isNull player)};
};

at the top, thats if your hosting your own local server lan, or a dedicated.

 

See these two pages on what code to add for servers:

https://community.bistudio.com/wiki/isServer

https://community.bistudio.com/wiki/Multiplayer_Scripting#Different_machines_and_how_to_target_them

Share this post


Link to post
Share on other sites

If you place it in initPlayerLocal.sqf, (SP or MP) it should work as is, in multiplayer... You are in a "player ready" context.

 

The fact is I don't know exactly in what case your player will lost a "player status" then re-gain it... a return to lobby? On my mind, the initPlayerLocal.sqf is re-run in MP... So probably something smarter  to do with player connected/disconnected rather than this loop.

 

@Storm Rider   If I understand your request, you would like to be able to call support when you are in a certain type of vehicle as well as being on foot and carrying a backpack.
You can add an array of vehicle types, different from backpack ones. Say MGI_vehicles =  ["B_MRAP_01_hmg_F"......] // case sensitive

 

The first waitUntil becomes:
waitUntil {sleep 2; (typeOf objectParent player in MGI_vehicles or backpack _unit in MGI_radios or (backpack _unit) isKindOf "TFAR_bag_base") or !isPlayer _unit};
the second one:
waitUntil {sleep 2; ( !(typeOf objectParent player in MGI_vehicles) && !(backpack _unit in MGI_radios) && !((backpack _unit) isKindOf "TFAR_bag_base")) or !isPlayer _unit};

 

 

 

  • Like 1

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

×