Jump to content
jwllorens

BIS respawn system, how to determine role after respawn?

Recommended Posts

With the new respawn system we can define roles and loadouts in description.ext.  It looks nice and fancy and works well.

 

However, I need to determine what role the player has chosen after they spawn in.  Does the BIS respawn system do any kind of setvariable on the unit that respawns that contains the name of the role (or even the loadout) that was chosen?  That would be very convenient.

 

How can I determine what role the player is after they spawn in?  Do I need to make some kind of hacky script to check their gear and see if it matches some predefined constant to determine which role they chose or is there an easier way?

Share this post


Link to post
Share on other sites

Hate to bump, but any thoughts?  Can I somehow call a setVariable on the unit that takes some variable which contains the class loadout name that I defined in description.ext?

Share this post


Link to post
Share on other sites

How do you understand the role, and what are the differences between roles that you are expecting?

Share this post


Link to post
Share on other sites

On the BIS respawn screen, players choose a role in the center of the screen.  Then on the right side, they choose a loadout.

 

I want to be able to determine either the role or the loadout they have chosen after they respawn through a script.

 

This will allow me to do all sorts of things, such as limiting players from picking up and using certain weapons, driving certain vehicles, giving them the medic heal ability or the engineer repair ability, ect.  

 

But I don't know how to determine what role a player has selected at the repsawn screen via script.

 

Share this post


Link to post
Share on other sites

I'm not sure if you can but I know that if you setup your templates using the following (different vehicle for each template):

class EXAMPLE {
          vehicle = "B_soldier_AR_F"
};

You can then check what loadout was chosen corresponding to the change in unit type, from the typeOf command.

Share this post


Link to post
Share on other sites

I think I found the solution to OP's question:
 

After you respawn, this will return a string of the display name of the last loadout selected in the selection screen:

_respawnCombo = uiNamespace getVariable (["BIS_RscRespawnControlsMap_ctrlComboLoadout", "BIS_RscRespawnControlsSpectate_ctrlComboLoadout"] select (uiNamespace getVariable ["BIS_RscRespawnControlsSpectate_shown", false]));
_respawnTemplateDisplayName = _respawnCombo lbText (lbCurSel _respawnCombo);

For example, if you had, and selected, the loadout:

	class WEST1 {
		displayName = "Light";
		icon = "\A3\Ui_f\data\GUI\Cfg\Ranks\sergeant_gs.paa";
		role = "Test";
 
		weapons[] = {
			"arifle_MXC_F",
			"Binocular"
		};
		magazines[] = {
			"30Rnd_65x39_caseless_mag",
			"30Rnd_65x39_caseless_mag",
			"SmokeShell",
			"SmokeShell"
		};
		items[] = {
			"FirstAidKit"
		};
		linkedItems[] = {
			"V_Chestrig_khk",
			"H_Watchcap_blk",
			"optic_Aco",
			"acc_flashlight",
			"ItemMap",
			"ItemCompass",
			"ItemWatch",
			"ItemRadio"
		};
		uniformClass = "U_B_CombatUniform_mcam_tshirt";
		backpack = "B_AssaultPack_mcamo";
	};

_respawnTemplateDisplayName would return "Light"

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites

I think I found the solution to OP's question:

 

After you respawn, this will return a string of the display name of the last loadout selected in the selection screen:

_respawnCombo = uiNamespace getVariable (["BIS_RscRespawnControlsMap_ctrlComboLoadout", "BIS_RscRespawnControlsSpectate_ctrlComboLoadout"] select (uiNamespace getVariable ["BIS_RscRespawnControlsSpectate_shown", false]));
_respawnTemplateDisplayName = _respawnCombo lbText (lbCurSel _respawnCombo);

For example, if you had, and selected, the loadout:

	class WEST1 {
		displayName = "Light";
		icon = "\A3\Ui_f\data\GUI\Cfg\Ranks\sergeant_gs.paa";
		role = "Test";
 
		weapons[] = {
			"arifle_MXC_F",
			"Binocular"
		};
		magazines[] = {
			"30Rnd_65x39_caseless_mag",
			"30Rnd_65x39_caseless_mag",
			"SmokeShell",
			"SmokeShell"
		};
		items[] = {
			"FirstAidKit"
		};
		linkedItems[] = {
			"V_Chestrig_khk",
			"H_Watchcap_blk",
			"optic_Aco",
			"acc_flashlight",
			"ItemMap",
			"ItemCompass",
			"ItemWatch",
			"ItemRadio"
		};
		uniformClass = "U_B_CombatUniform_mcam_tshirt";
		backpack = "B_AssaultPack_mcamo";
	};

_respawnTemplateDisplayName would return "Light"

 

Wow!  Amazing.

 

How did you find those variables?

 

Also, in the first line of the function, you are choosing between two variables, based on the state of "BIS_RscRespawnControlsSpectate_shown" which I assume returns a 1 or 0 based on something.

 

What are you choosing between, and why?  Basically, what do these two variables represent and what does your condition, which is the state of "BIS_RscRespawnControlsSpectate_shown", represent?

Share this post


Link to post
Share on other sites

Wow!  Amazing.

 

How did you find those variables?

 

Also, in the first line of the function, you are choosing between two variables, based on the state of "BIS_RscRespawnControlsSpectate_shown" which I assume returns a 1 or 0 based on something.

 

What are you choosing between, and why?  Basically, what do these two variables represent and what does your condition, which is the state of "BIS_RscRespawnControlsSpectate_shown", represent?

 

By looking through all the respawn functions, the particular function was BIS_fnc_respawnMenuInventory.

Well as far as I can tell, the respawn menu is split into two - one set of controls for the spectator screen and another for the map screen. These controls have different idcs, which are stored in the variables "BIS_RscRespawnControlsSpectate_ctrlComboLoadout" or "BIS_RscRespawnControlsMap_ctrlComboLoadout" depending on the screen. These variables can then be used to access to the last/current selection of the listbox, in order to find the loadout selected by the player.

The "BIS_RscRespawnControlsSpectate_shown" allows us to know which screen was shown last and so correctly chose the variable to use in order to return the player's selected loadout.

 

Hopefully that makes sense, writing clear explanations isn't exactly my forte.

Share this post


Link to post
Share on other sites

By looking through all the respawn functions, the particular function was BIS_fnc_respawnMenuInventory.

Well as far as I can tell, the respawn menu is split into two - one set of controls for the spectator screen and another for the map screen. These controls have different idcs, which are stored in the variables "BIS_RscRespawnControlsSpectate_ctrlComboLoadout" or "BIS_RscRespawnControlsMap_ctrlComboLoadout" depending on the screen. These variables can then be used to access to the last/current selection of the listbox, in order to find the loadout selected by the player.

The "BIS_RscRespawnControlsSpectate_shown" allows us to know which screen was shown last and so correctly chose the variable to use in order to return the player's selected loadout.

 

Hopefully that makes sense, writing clear explanations isn't exactly my forte.

 

 

That makes sense to me.  The function is working reasonably well, but there are two problems.  One is related to the function, and the other seems to be related to the event script onPlayerRespawn.sqf.

 

The first problem is the function is returning the loadout name from the loadout listbox rather than the role listbox.  I am guessing I will have to look at the functions to see if there are different variables to use.  This isn't too much of a problem and can be circumvented, but is not optimal.  For example, I have a "medic" role, and in this role I have several medic loadouts the player can choose from, depending on various "upgrades" that have been scripted for that side.  In order to add the medic skill (healing units to full health with a medkit) that is by default given to combat life saver units placed in the editor, I would have to check to see if the string returned by the function matches one of many different strings corresponding to the different loadouts under the medic "role" category.  It would be a lot more optimal to simply check the role instead.

 

The other problem is that onPlayerRespawn.sqf does not seem to fire when the player respawns at the start of the game.  I have respawnOnStart = 1; set in description.ext yet the script still seems to not fire the first time.  Any thoughts?

 

 

 

EDIT:  I set the function up as a file and added it to functions library in description.ext.  Here is the file.

disableSerialization;

params [
["_unit", objNull, [objNull], 1]
];

_respawnCombo = uiNamespace getVariable (["BIS_RscRespawnControlsMap_ctrlComboLoadout", "BIS_RscRespawnControlsSpectate_ctrlComboLoadout"] select (uiNamespace getVariable ["BIS_RscRespawnControlsSpectate_shown", false]));
_respawnTemplateDisplayName = _respawnCombo lbText (lbCurSel _respawnCombo);
_unit setVariable ["JWL_respawnRole", _respawnTemplateDisplayName, true];

I spawned the function, rather than calling it, because I got a serialization error.  I don't know if this makes a difference, but I wanted to be safe and make sure that I was calling disableSerialization in a separate thread from onPlayerRespawn.sqf.  I spawned it from onPlayerRespawn.sqf like this:

params [
["_newUnit", objNull, [objNull], 1]
];


_newUnit spawn JWL_fnc_setRoleVar;

hint (_newUnit getVariable "JWL_respawnRole"); //Nothing is shown when spawning at the beginning of the mission, but shows "Rifleman (SPAR16)" after every subsequent respawn.

Share this post


Link to post
Share on other sites

Ok, a quick update.  Changing that last line in onPlayerRespawn.sqf from

hint (_newUnit getVariable "JWL_respawnRole");

to

hint (_newUnit getVariable ["JWL_respawnRole", "NOT SET"]);

shows NOT SET when selecting the first loadout and spawning in, but shows the selected loadout every subsequent respawn.  So onPlayerRespawn.sqf not firing on the first respawn is NOT the problem.

 

 

EDIT AGAIN:  Ok, using "BIS_RscRespawnControlsMap_ctrlRoleList" instead of "BIS_RscRespawnControlsMap_ctrlComboLoadout" returns the name of the role rather than the name of the loadout.  So that is one problem fixed.

Share this post


Link to post
Share on other sites

 

That makes sense to me.  The function is working reasonably well, but there are two problems.  One is related to the function, and the other seems to be related to the event script onPlayerRespawn.sqf.

 

The first problem is the function is returning the loadout name from the loadout listbox rather than the role listbox.  I am guessing I will have to look at the functions to see if there are different variables to use.  This isn't too much of a problem and can be circumvented, but is not optimal.  For example, I have a "medic" role, and in this role I have several medic loadouts the player can choose from, depending on various "upgrades" that have been scripted for that side.  In order to add the medic skill (healing units to full health with a medkit) that is by default given to combat life saver units placed in the editor, I would have to check to see if the string returned by the function matches one of many different strings corresponding to the different loadouts under the medic "role" category.  It would be a lot more optimal to simply check the role instead.

 

The other problem is that onPlayerRespawn.sqf does not seem to fire when the player respawns at the start of the game.  I have respawnOnStart = 1; set in description.ext yet the script still seems to not fire the first time.  Any thoughts?

 

 

 

EDIT:  I set the function up as a file and added it to functions library in description.ext.  Here is the file.

disableSerialization;

params [
["_unit", objNull, [objNull], 1]
];

_respawnCombo = uiNamespace getVariable (["BIS_RscRespawnControlsMap_ctrlComboLoadout", "BIS_RscRespawnControlsSpectate_ctrlComboLoadout"] select (uiNamespace getVariable ["BIS_RscRespawnControlsSpectate_shown", false]));
_respawnTemplateDisplayName = _respawnCombo lbText (lbCurSel _respawnCombo);
_unit setVariable ["JWL_respawnRole", _respawnTemplateDisplayName, true];

I spawned the function, rather than calling it, because I got a serialization error.  I don't know if this makes a difference, but I wanted to be safe and make sure that I was calling disableSerialization in a separate thread from onPlayerRespawn.sqf.  I spawned it from onPlayerRespawn.sqf like this:

params [
["_newUnit", objNull, [objNull], 1]
];


_newUnit spawn JWL_fnc_setRoleVar;

hint (_newUnit getVariable "JWL_respawnRole"); //Nothing is shown when spawning at the beginning of the mission, but shows "Rifleman (SPAR16)" after every subsequent respawn.

 

Sorry, the role list was an oversight on my behalf:

_respawnCombo = uiNamespace getVariable (["BIS_RscRespawnControlsMap_ctrlRoleList", "BIS_RscRespawnControlsSpectate_ctrlRoleList"] select (uiNamespace getVariable ["BIS_RscRespawnControlsSpectate_shown", false]));
_respawnTemplateDisplayName = _respawnCombo lbText (lbCurSel _respawnCombo);

The first argument (old unit) in onPlayerRespawn will be objNull on mission start, so you need to change the params section to:

params [
["_oldUnit", objNull, [objNull]],
["_newUnit", objNull, [objNull]]
];

Otherwise you're assigning a variable to a null unit

Share this post


Link to post
Share on other sites

Sorry, the role list was an oversight on my behalf:

_respawnCombo = uiNamespace getVariable (["BIS_RscRespawnControlsMap_ctrlRoleList", "BIS_RscRespawnControlsSpectate_ctrlRoleList"] select (uiNamespace getVariable ["BIS_RscRespawnControlsSpectate_shown", false]));
_respawnTemplateDisplayName = _respawnCombo lbText (lbCurSel _respawnCombo);

The first argument (old unit) in onPlayerRespawn will be objNull on mission start, so you need to change the params section to:

params [
["_oldUnit", objNull, [objNull]],
["_newUnit", objNull, [objNull]]
];

Otherwise you're assigning a variable to a null unit

 

On the wiki it says that the parameters for onPlayerRespawn.sqf are [<newUnit>, <oldUnit>, <respawn>, <respawnDelay>].

 

 

So parameter #0 should be the new unit and not the old unit, correct?  Meaning that it shouldn't be objNull at the start, it should be the new unit that is created when the player respawns the first time.

 

 

EDIT:  Ok, I found the problem, I think, but something isn't adding up.  The variable wasn't being assigned to the unit before I was calling hint (getvariable "whatever");  Since I spawned a new thread, hint was getting executed before that thread had completed execution and therefore before setVariable was being called on the unit.  Adding a short sleep into onPlayerRespawn.sqf fixed the problem.  However, I found something interesting that seems to not support this assumption, despite this fix working.  What is interesting is also that it didn't work on the first respawn at the start, but worked on every subsequent respawn.  If the order of execution was the problem, then I would expect it to fail every time if I was referencing the newly created unit every time.

 

Changing onPlayerRespawn.sqf to:

params [
["_newUnit", objNull, [objNull], 1],
["_oldUnit", objNull, [objNull], 1]
];


_newUnit spawn JWL_fnc_setRoleVar;
waitUntil {(_newUnit getVariable ["JWL_respawnRole", "NOT SET"]) != "NOT SET"};
hint str [_oldUnit, _newUnit, (_newUnit getVariable ["JWL_respawnRole", "NOT SET"])];

yields interesting results.  "Rifleman" is always returned even at the start.  However, _newUnit and _oldUnit appear to ALWAYS be the same thing.  Even at the start of the game after the first respawn.  I will have to play with this and add in another role, and see if it always accurately returns the correct role.

 

 

EDIT 2:  Ok.  So I got it working.  You were right about _newUnit and _oldUnit, they seem to be flipped compared to what is on the wiki.  Maybe that should be changed.  However, despite the script working, there are still some strange questions.  Using the first parameter, assuming it is the new unit, I get the correct result on the FIRST spawn in the game, but every subsequent spawn shows the role selected from my LAST life and not the current one, suggesting that the first parameter is the old unit and not the new (current) one.  

 

However, using the first parameter should mean the function is assigning a variable to objNull on the first spawn of the game, so why is it working when I call getVariable on it?  

 

It also doesn't explain why the waitUntil command fixes the problem of not retrieving a variable on the first spawn, when this problem should be encountered on every subsequent spawn if it is an execution order problem.  I would assume that the new unit would NEVER have the variable assigned to it before calling getVariable if this were the problem, on any respawn.  

Share this post


Link to post
Share on other sites

On the wiki it says that the parameters for onPlayerRespawn.sqf are [<newUnit>, <oldUnit>, <respawn>, <respawnDelay>].

 

 

So parameter #0 should be the new unit and not the old unit, correct?  Meaning that it shouldn't be objNull at the start, it should be the new unit that is created when the player respawns the first time.

 

 

EDIT:  Ok, I found the problem, I think, but something isn't adding up.  The variable wasn't being assigned to the unit before I was calling hint (getvariable "whatever");  Since I spawned a new thread, hint was getting executed before that thread had completed execution and therefore before setVariable was being called on the unit.  Adding a short sleep into onPlayerRespawn.sqf fixed the problem.  However, I found something interesting that seems to not support this assumption, despite this fix working.  What is interesting is also that it didn't work on the first respawn at the start, but worked on every subsequent respawn.  If the order of execution was the problem, then I would expect it to fail every time if I was referencing the newly created unit every time.

 

Changing onPlayerRespawn.sqf to:

params [
["_newUnit", objNull, [objNull], 1],
["_oldUnit", objNull, [objNull], 1]
];


_newUnit spawn JWL_fnc_setRoleVar;
waitUntil {(_newUnit getVariable ["JWL_respawnRole", "NOT SET"]) != "NOT SET"};
hint str [_oldUnit, _newUnit, (_newUnit getVariable ["JWL_respawnRole", "NOT SET"])];

yields interesting results.  "Rifleman" is always returned even at the start.  However, _newUnit and _oldUnit appear to ALWAYS be the same thing.  Even at the start of the game after the first respawn.  I will have to play with this and add in another role, and see if it always accurately returns the correct role.

 

 

EDIT 2:  Ok.  So I got it working.  You were right about _newUnit and _oldUnit, they seem to be flipped compared to what is on the wiki.  Maybe that should be changed.  However, despite the script working, there are still some strange questions.  Using the first parameter, assuming it is the new unit, I get the correct result on the FIRST spawn in the game, but every subsequent spawn shows the role selected from my LAST life and not the current one, suggesting that the first parameter is the old unit and not the new (current) one.  

 

However, using the first parameter should mean the function is assigning a variable to objNull on the first spawn of the game, so why is it working when I call getVariable on it?  

 

It also doesn't explain why the waitUntil command fixes the problem of not retrieving a variable on the first spawn, when this problem should be encountered on every subsequent spawn if it is an execution order problem.  I would assume that the new unit would NEVER have the variable assigned to it before calling getVariable if this were the problem, on any respawn.  

Oh blast, I did get it the wrong way around. The wiki is the correct version.

On my way home from work but I'll try to answer later

Share this post


Link to post
Share on other sites

Ok, now it works as intended.

 

fn_setRoleVar.sqf

disableSerialization;

params [
["_unit", objNull, [objNull], 1]
];

_rList = uiNamespace getVariable (["BIS_RscRespawnControlsMap_ctrlRoleList", "BIS_RscRespawnControlsSpectate_ctrlRoleList"] select (uiNamespace getVariable ["BIS_RscRespawnControlsSpectate_shown", false]));
_rName = _rList lbText (lbCurSel _rList);
_unit setVariable ["JWL_respawnRole", (toUpper _rName), true];

true

onPlayerRespawn.sqf

params [
["_newUnit", objNull, [objNull], 1],
["_oldUnit", objNull, [objNull], 1]
];

_newUnit spawn JWL_fnc_setRoleVar;

init.sqf (just for testing purposes)

null = [] spawn {
	while {true} do {
		sleep 1;
		hintSilent (player getVariable ["RespawnRole", "NOT SET"]);
	};
};

Will spam "NOT SET" until you select a loadout and spawn.  Afterwards, will spam the role you selected.  "MEDIC," "AUTORIFLEMAN," "GRENADIER" ect.  If your respawn with a new role, it will spam the  new role name instead.  

 

Works great because you can call  player getVariable "RespawnRole" and it returns the role of the player.  

 

 

Nice!  Awesome!  Thanks so much for your help.  This will allow me to use the BIS respawn system which I think is very clean and useable and do some cool stuff on top of it, like making sure pilots are the only ones that can fly planes and medics get the proper medic bonus for reviving.  

  • Like 5
  • Thanks 1

Share this post


Link to post
Share on other sites

As someone who found this thread 1.5 years later and still has to use this not so easy way of handling the role i am REALLY thankfull for the work you two did. Just as a mention for people who might be here after me and wondering why it constantly shows "NOT SET":

 

You have to change "RespawnRole" to "JWL_respawnRole" in the init.sqf. Everything then just works fine.

 

And if you want the loadoutname instead of the role (cause there can be several loadouts per role) you can still use the _respawncombo from HallyGs second post. That works fine aswell :)

  • Like 1

Share this post


Link to post
Share on other sites

I have ran into the same issue, now that I have placed the code, I need to know how to get the variable so that my addaction applies to only the proper role. Also, even with your change @Bren_Silent it still shows NOT SET constantly..

Thanks!

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

×