Jump to content
avibird 1

Remove an incapacitated unit from Team switch menu

Recommended Posts

I have 16 playable units  in a mission that uses team switch function. I have a modified revive script that the units will never die only stay incapacitated the mission ends when all 16 players are incapacitated at once. The issue I'm having sometimes difficult to know which unit is incapacitated or still ok on it's feet fighting in the mission. I would like the incapacitated units to be removed from the team switch menu and then Place back once they get revived/healed.  I'm almost positive this can be done I think I've seen it in a mission but have no idea how to do this since the team switch menu is hard-coded within the vanilla game. Any help on this would be great. 

Share this post


Link to post
Share on other sites

@Stormmy1950 thank you for your reply but I think you missed what I was saying. I already have that set up so when all players are incapacitated the mission ends

 

 

What I need is a way to remove the incapacitated unit from the team switch menu while he is incapacitated. It is sometimes difficult to cycle through all 16 units to find the one that is still alive or not incapacitated.  Once that incapacitated unit is revived I would like you to be added back to the team switch menu so somebody can switch into that unit to use. My mission is set up like Last Man Standing with the ability to revive your teammates as long as one member is still alive during the mission. I hope you understand now and better I hope that you have a solution for me lol.

Share this post


Link to post
Share on other sites
{
  _x spawn {
    _unit = _this;
    while {true} do {
      waitUntil {sleep 0.5; !(lifeState _unit == "incapacitated") && alive _unit};
      addSwitchableUnit _unit;
      waitUntil {sleep 0.5; lifeState _unit == "incapacitated"};
      removeSwitchableUnit _unit;
    };
  };
} foreach switchableUnits + playableUnits;

 

  • Like 2
  • Thanks 1

Share this post


Link to post
Share on other sites

@ Pierremgi you are awesome thank you for the help. Question I'm assuming I either need to put that code in a game logic Trigger or my mission init.

Share this post


Link to post
Share on other sites

@ can I just make a initserver.sqf and put code in that or does it need to be a dedicated server?

I play on host server ?

Share this post


Link to post
Share on other sites

You can create an initserver.sqf for any mission SP/MP

or

If (isServer) then {

{ _x spawn { _unit = _this; while {true} do { waitUntil {sleep 0.5; !(lifeState _unit == "incapacitated") && alive _unit}; addSwitchableUnit _unit; waitUntil {sleep 0.5; lifeState _unit == "incapacitated"}; removeSwitchableUnit _unit; }; }; } foreach switchableUnits + playableUnits;

};

where you want!

  • Thanks 1

Share this post


Link to post
Share on other sites

@pierremgi  thank you.

@HazJ I never really understood the difference between dedicated versus host server Global versus local client vs. headless client when scripting. I can piecemeal some codes together but have no scripting background at all. But I still enjoy learning and certainly making missions.

 

@pierremgi I have not tried it yet to see if it worked my armor time has been limited lately because a real life hopefully tonight or this weekend I'll get a chance to see.

Share this post


Link to post
Share on other sites

@pierremgi I put the code in my mission init.sqf  does not work, I made a new SQF called initserver.sqf  it does not work. I put the code in a game logic it does not work. :down: what am I doing wrong with your code above????

Share this post


Link to post
Share on other sites

My bad. These commands are for switching units in SP. (incapacitation can be added by script in SP, so I was on that scheme, worked for days on that).

 

If switch means return to lobby, It's more a question about reserved slot.

See this thread or search for reserved slot.

The easiest solution seems to me a kick by admin and a deleteVehicle on the unit... Hard method.!

 

Share this post


Link to post
Share on other sites

There has to be a way just to remove the option to select that unit from the team switch menu while they're incapacitated ? 

Share this post


Link to post
Share on other sites

@avibird 1 - Might be. Maybe modify the UI? I will do some tests now and let you know. Stand by.

 

EDIT 1: Not looking good so far. Can't seem to affect changes to Listbox even with IDC, etc... The switch button has no IDC so can't add the check when clicked either. Will try a few other things. Stand by.

  • Thanks 1

Share this post


Link to post
Share on other sites

@HazJ thank you for looking into that for me. I do remember playing a mission that the units were removed from Team switch menu while they were waiting to be revived. 

 

It's not a mission killer but because there's only 13 playable units but can still be a pain in the ass to know which units are still alive when the prison break goes wrong ?. 

 

I'm looking into an alternative way using unit markers that will show when a unit is alive ie not incapacitated. However the downside is the players will always know where the units are located on the map however this will take away from the immersion of this type of mission since it is a prison break Escape Mission off the island. Thank you look forward to seeing if you found the solution for me Avibird

Share this post


Link to post
Share on other sites

@avibird 1

FFFFF this game, lol. Still trying. It is getting messy and hacky. Progress so far: Video below.

[] spawn
{
	disableSerialization;
	revertSwitch = true;
	teamSwitchMEH = addMissionEventHandler ["TeamSwitch",
	{
		params ["_from", "_to"];
		hintSilent format [":: %1", lifeState _to];
		if (lifeState _to == "INCAPACITATED") then
		{
			hintSilent "You cannot switch to this unit at the moment.";
			teamSwitch;
			waitUntil {!isNull (findDisplay 632)};
			(findDisplay 632 displayCtrl 101) lbSetCurSel 0;
			revertSwitch = true;
		} else
		{
			revertSwitch = false;
		};
	}];
	waitUntil
	{
		!isNull (findDisplay 632)
	};
	lbClear (findDisplay 632 displayCtrl 101); // has no affect what so ever
	{
		(findDisplay 632 displayCtrl (ctrlIDC _x)) ctrlAddEventHandler ["ButtonClick",
		{
			params ["_button"];
			hintSilent "Switch button clicked";
			systemChat format ["%1", ctrlText _button];
			ctrlActivate _button;
			if (revertSwitch) then
			{
				ctrlActivate _button;
			};
		}];
	} forEach (allControls findDisplay 632) - [(findDisplay 632 displayCtrl 32)];
};

 

 

  • Thanks 1

Share this post


Link to post
Share on other sites
[] spawn
{
	disableSerialization;
	teamSwitchMEH = addMissionEventHandler ["TeamSwitch",
	{
		params ["_from", "_to"];
		if (lifeState _to isEqualTo "INCAPACITATED") then
		{
			hintSilent "You cannot switch to this unit at the moment.";
			selectPlayer _from;
		};
	}];
};

EDIT: Still need to terminate the unconscious sound that you can hear as it switches back. Should be possible, haven't looked yet.

 

It is strange. I wanted to disable the switch button as it does for the player but I couldn't, nor could I trigger ctrlActivate with it. I know the button has no IDC but that is why I cycled through and checked for it. I could use ctrlText and even add ButtonClick EH to it though. Maybe somehow else knows why? @Larrow :grinning:

Share this post


Link to post
Share on other sites

In fact, the switch button has idc = 1 (see the config viewer : configfile >> "RscDisplayTeamSwitch" >> "Controls" >> "CA_ButtonContinue")

but you don't have the hand on it. I tried (findDisplay 632 displayCtrl 1) ctrlEnable false;  with no result.

On the other hand, i succeeded in changing active color for the list box (101)  when selected unit is unconscious...

 

I messed with lbDelete. I had some results with lbClear and lbAdd (the list box is cleaned of any unconscious guy, but I had to call a code on selection and i failed to do. The

onLBSelChanged = "_dummy = [_this, ""CA_TS_UnitSelected""] execVM ""\A3\ui_f\scripts\TeamSwitch.sqf"";"; is not easily transposable in a custom code. the teamswitch.sqf is hardcoded with switchableUnits.

A pity that BI didn't think about their states.

 

  • Like 1

Share this post


Link to post
Share on other sites

That is odd. I looked directly in the config from ui_f and:

class RscDisplayTeamSwitch: RscStandardDisplay
{
	scriptName="RscDisplayTeamSwitch";
	scriptPath="GUI";
	onLoad="[""onLoad"",_this,""RscDisplayTeamSwitch"",'GUI'] call 	(uinamespace getvariable 'BIS_fnc_initDisplay')";
	onUnload="[""onUnload"",_this,""RscDisplayTeamSwitch"",'GUI'] call 	(uinamespace getvariable 'BIS_fnc_initDisplay')";
	idd=632;
	enableSimulation=1;
	colorPlayer[]={0.94999999,0.94999999,0.94999999,1};
	colorPlayerSelected[]={0.94999999,0.94999999,0.94999999,1};
	class controlsBackground
	{
		delete Background1;
		class RscTitleBackground: RscText
		{
			colorBackground[]=
			{
				"(profilenamespace getvariable ['GUI_BCG_RGB_R',0.13])",
				"(profilenamespace getvariable ['GUI_BCG_RGB_G',0.54])",
				"(profilenamespace getvariable ['GUI_BCG_RGB_B',0.21])",
				"(profilenamespace getvariable ['GUI_BCG_RGB_A',0.8])"
			};
			idc=1080;
			x="1 * 					(			((safezoneW / safezoneH) min 1.2) / 40) + 		(safezoneX + (safezoneW - 					((safezoneW / safezoneH) min 1.2))/2)";
			y="1 * 					(			(			((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + 		(safezoneY + (safezoneH - 					(			((safezoneW / safezoneH) min 1.2) / 1.2))/2)";
			w="38 * 					(			((safezoneW / safezoneH) min 1.2) / 40)";
			h="1 * 					(			(			((safezoneW / safezoneH) min 1.2) / 1.2) / 25)";
		};
		class MainBackground: RscText
		{
			colorBackground[]={0,0,0,0.69999999};
			idc=1082;
			x="1 * 					(			((safezoneW / safezoneH) min 1.2) / 40) + 		(safezoneX + (safezoneW - 					((safezoneW / safezoneH) min 1.2))/2)";
			y="2.1 * 					(			(			((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + 		(safezoneY + (safezoneH - 					(			((safezoneW / safezoneH) min 1.2) / 1.2))/2)";
			w="38 * 					(			((safezoneW / safezoneH) min 1.2) / 40)";
			h="20.8 * 					(			(			((safezoneW / safezoneH) min 1.2) / 1.2) / 25)";
		};
	};
	class Controls
	{
		delete Background;
		delete Roles;
		delete ButtonOK;
		delete ButtonCancel;
		class CA_TSTitle: RscTitle
		{
			idc=1000;
			text="$STR_USRACT_TEAM_SWITCH";
			x="1 * 					(			((safezoneW / safezoneH) min 1.2) / 40) + 		(safezoneX + (safezoneW - 					((safezoneW / safezoneH) min 1.2))/2)";
			y="1 * 					(			(			((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + 		(safezoneY + (safezoneH - 					(			((safezoneW / safezoneH) min 1.2) / 1.2))/2)";
			w="14 * 					(			((safezoneW / safezoneH) min 1.2) / 40)";
			h="1 * 					(			(			((safezoneW / safezoneH) min 1.2) / 1.2) / 25)";
		};
		class PlayersName: RscTitle
		{
			idc=109;
			style=1;
			colorBackground[]={0,0,0,0};
			x="23.3 * 					(			((safezoneW / safezoneH) min 1.2) / 40) + 		(safezoneX + (safezoneW - 					((safezoneW / safezoneH) min 1.2))/2)";
			y="1 * 					(			(			((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + 		(safezoneY + (safezoneH - 					(			((safezoneW / safezoneH) min 1.2) / 1.2))/2)";
			w="15.7 * 					(			((safezoneW / safezoneH) min 1.2) / 40)";
			h="1 * 					(			(			((safezoneW / safezoneH) min 1.2) / 1.2) / 25)";
		};
		class TitleBar: RscText
		{
			moving=1;
			colorText[]={0,0,0,0};
			x="1 * 					(			((safezoneW / safezoneH) min 1.2) / 40) + 		(safezoneX + (safezoneW - 					((safezoneW / safezoneH) min 1.2))/2)";
			y="1 * 					(			(			((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + 		(safezoneY + (safezoneH - 					(			((safezoneW / safezoneH) min 1.2) / 1.2))/2)";
			w="38 * 					(			((safezoneW / safezoneH) min 1.2) / 40)";
			h="1 * 					(			(			((safezoneW / safezoneH) min 1.2) / 1.2) / 25)";
		};
		class CA_TSRoles: RscListBox
		{
			IDC=101;
			onLBSelChanged="_dummy = [_this, ""CA_TS_UnitSelected""] execVM ""\A3\ui_f\scripts\TeamSwitch.sqf"";";
			onLBDblClick="_dummy = [_this, ""CA_TS_ListDoubleClick""] execVM ""\A3\ui_f\scripts\TeamSwitch.sqf"";";
			x="1.2 * 					(			((safezoneW / safezoneH) min 1.2) / 40) + 		(safezoneX + (safezoneW - 					((safezoneW / safezoneH) min 1.2))/2)";
			y="2.3 * 					(			(			((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + 		(safezoneY + (safezoneH - 					(			((safezoneW / safezoneH) min 1.2) / 1.2))/2)";
			w="15 * 					(			((safezoneW / safezoneH) min 1.2) / 40)";
			h="20.4 * 					(			(			((safezoneW / safezoneH) min 1.2) / 1.2) / 25)";
		};
		class CA_TSMap: RscMapControl
		{
			idc=561;
			ShowCountourInterval=0;
			scaleDefault=0.1;
			onMouseButtonClick="_dummy = [_this, ""CA_TS_MapClick""] execVM ""\A3\ui_f\scripts\TeamSwitch.sqf"";";
			onMouseButtonDblClick="_dummy = [_this, ""CA_TS_ListDoubleClick""] execVM ""\A3\ui_f\scripts\TeamSwitch.sqf"";";
			x="16.3 * 					(			((safezoneW / safezoneH) min 1.2) / 40) + 		(safezoneX + (safezoneW - 					((safezoneW / safezoneH) min 1.2))/2)";
			y="2.3 * 					(			(			((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + 		(safezoneY + (safezoneH - 					(			((safezoneW / safezoneH) min 1.2) / 1.2))/2)";
			w="22.5 * 					(			((safezoneW / safezoneH) min 1.2) / 40)";
			h="20.4 * 					(			(			((safezoneW / safezoneH) min 1.2) / 1.2) / 25)";
			colorBackground[]={1,1,1,1};
		};
		class CA_TSUnitIcon: RscPicture
		{
			IDC=493;
			style="0x30 + 0x800";
			text="#(argb,8,8,3)color(1,1,1,1)";
			x="15.2 * 					(			((safezoneW / safezoneH) min 1.2) / 40) + 		(safezoneX + (safezoneW - 					((safezoneW / safezoneH) min 1.2))/2)";
			y="1 * 					(			(			((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + 		(safezoneY + (safezoneH - 					(			((safezoneW / safezoneH) min 1.2) / 1.2))/2)";
			w="1 * 					(			((safezoneW / safezoneH) min 1.2) / 40)";
			h="1 * 					(			(			((safezoneW / safezoneH) min 1.2) / 1.2) / 25)";
		};
		class CA_TSUnit: RscTitle
		{
			IDC=501;
			text="$STR_PLAYER";
			x="16.1 * 					(			((safezoneW / safezoneH) min 1.2) / 40) + 		(safezoneX + (safezoneW - 					((safezoneW / safezoneH) min 1.2))/2)";
			y="1 * 					(			(			((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + 		(safezoneY + (safezoneH - 					(			((safezoneW / safezoneH) min 1.2) / 1.2))/2)";
			w="7.2 * 					(			((safezoneW / safezoneH) min 1.2) / 40)";
			h="1 * 					(			(			((safezoneW / safezoneH) min 1.2) / 1.2) / 25)";
		};
		class CA_ButtonViewUnit: RscButtonMenu
		{
			idc=32;
			onButtonClick="_dummy = [_this, ""CA_TS_ViewUnit""] execVM ""\A3\ui_f\scripts\TeamSwitch.sqf"";";
			text="$STR_TEAM_SWITCH_VIEW_UNIT";
			x="26.4 * 					(			((safezoneW / safezoneH) min 1.2) / 40) + 		(safezoneX + (safezoneW - 					((safezoneW / safezoneH) min 1.2))/2)";
			y="23 * 					(			(			((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + 		(safezoneY + (safezoneH - 					(			((safezoneW / safezoneH) min 1.2) / 1.2))/2)";
			w="6.25 * 					(			((safezoneW / safezoneH) min 1.2) / 40)";
			h="1 * 					(			(			((safezoneW / safezoneH) min 1.2) / 1.2) / 25)";
		};
		class CA_ButtonContinue: RscButtonMenuOK
		{
			text="$STR_DISP_SWITCH";
			x="32.75 * 					(			((safezoneW / safezoneH) min 1.2) / 40) + 		(safezoneX + (safezoneW - 					((safezoneW / safezoneH) min 1.2))/2)";
			y="23 * 					(			(			((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + 		(safezoneY + (safezoneH - 					(			((safezoneW / safezoneH) min 1.2) / 1.2))/2)";
			w="6.25 * 					(			((safezoneW / safezoneH) min 1.2) / 40)";
			h="1 * 					(			(			((safezoneW / safezoneH) min 1.2) / 1.2) / 25)";
		};
		class CA_ButtonCancel: RscButtonMenuCancel
		{
			text="$STR_DISP_BACK";
			x="1 * 					(			((safezoneW / safezoneH) min 1.2) / 40) + 		(safezoneX + (safezoneW - 					((safezoneW / safezoneH) min 1.2))/2)";
			y="23 * 					(			(			((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + 		(safezoneY + (safezoneH - 					(			((safezoneW / safezoneH) min 1.2) / 1.2))/2)";
			w="6.25 * 					(			((safezoneW / safezoneH) min 1.2) / 40)";
			h="1 * 					(			(			((safezoneW / safezoneH) min 1.2) / 1.2) / 25)";
		};
	};
};

class CA_ButtonContinue: RscButtonMenuOK

Maybe I looked at wrong one? Yeah it is weird that you can use certain commands with it but not others. I did originally try lb commands as well but also failed.

Share this post


Link to post
Share on other sites

yep. I don't understand neither why the config viewer returns these controls:  1 for "switch", 2 for cancel ("back"), 32 for "view unit", and confirmed by allcontrols command applied to the 632 display. But the ui_f config must "override" or conflict with that for control 1 or 2. I'm not skilled about how it works. You can disabled the "unit view" 32 but not 1 or 2.

The "lb" commands seems to be not accurate here. the "ctrl" ones are better. But, without any good documentation, it's hard (impossible) to do something on selection instead of the whole control. As you said, perhaps @Larrow..

  • Like 1

Share this post


Link to post
Share on other sites

My solution so far (I succeeded in disable the switch button + warn the player for unconscious unit. I don't know why the modification of the lb text fails.

i have also a little latency..

Anyway, just test:

 

fnc_teamSwitch = {
  disableSerialization;
  params ["_type","_ctrlDispl"];
  private _idc = ctrlIDC (_ctrlDispl select 0);
  private _selectedIndex = _ctrlDispl param [1];
  _displ = findDisplay 632;
  _ctrl101 = _displ displayCtrl 101;
  _cnt = (lbsize 101) -1;
  for "_i" from 0 to _cnt do {
    _selectedUnit = switchableUnits param [_i,objNull];
    _unit = vehicle _selectedUnit;
    if (lifeState _unit == "incapacitated") then {
      lbSetText [_idc,_i,"unconscious unit"];
      lbSetTooltip [_idc, _i, "unconscious unit"];
      lbSetColor [_idc, _i,[1,0.3,0.3,1]];
    };
  };
  if (_type == 1) then {true};
  if (lifeState (vehicle (switchableUnits param [_selectedIndex,objNull])) == "incapacitated") then {(_displ displayCtrl 1) ctrlShow false} else {
    (_displ displayCtrl 1) ctrlShow true
  }
};
 
0 = [] spawn {
  while {true} do {
    waituntil {sleep 0.2; !isnull findDisplay 632};
  (findDisplay 632 displayCtrl 101) ctrlAddEventHandler ["LBSelChanged", "[0,_this] call fnc_teamSwitch"];
  (findDisplay 632 displayCtrl 101) ctrlsetEventHandler ["LBDblClick", "[1,_this] call fnc_teamSwitch"];
    waitUntil {sleep 0.2; isNull findDisplay 632};
  };
};

 

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites

Not sure why it does that slow mo latency thing. Very odd! I was going to say instead of the while loop do something like:

teamSwitchKey = (findDisplay 46) displayAddEventHandler ["KeyDown",
{
	if (param [1] in actionKeys "TeamSwitch") then
	{
		hintSilent "Yes";
		(findDisplay 632 displayCtrl 101) ctrlAddEventHandler ["LBSelChanged", "[0, _this] call fnc_teamSwitch;"];
		(findDisplay 632 displayCtrl 101) ctrlsetEventHandler ["LBDblClick", "[1, _this] call fnc_teamSwitch;"];
	};
}];

But it does not work, at least for the things I tried. It fires as the hint shows but that is about it.

  • Thanks 1

Share this post


Link to post
Share on other sites

I added 0 and 1 as params for calling the function so I can discriminate the context (double click or selection) So the EH array (_this) is passed as 2nd param. 

Share this post


Link to post
Share on other sites

@pierremgi how do I call the code in a mission init.sqf or put it in a game logic ? Thank you for looking into this ?

Share this post


Link to post
Share on other sites

Where you want. It's player related because it's working with UI interface (the team switch display). So in a true trigger (condition set to true), or init.sqf or initplayerlocal.sqf. Anywhere a JIP reads the code.

 

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

×