avibird 1 36 Posted February 27, 2018 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 42 Posted February 27, 2018 ok what you need is a check and a boolean that will check are the all players incapacited if true end mission if false do nothing. also you need a check if they are incapacited to switch them to other team so if they are incapacited switch if not switch back https://community.bistudio.com/wiki/Arma_3_Revive 1 Share this post Link to post Share on other sites
avibird 1 36 Posted February 27, 2018 @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
pierremgi 4850 Posted February 27, 2018 { _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; 2 1 Share this post Link to post Share on other sites
avibird 1 36 Posted February 27, 2018 @ 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
pierremgi 4850 Posted February 28, 2018 on server, like initServer.sqf Share this post Link to post Share on other sites
avibird 1 36 Posted February 28, 2018 @ 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
pierremgi 4850 Posted February 28, 2018 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! 1 Share this post Link to post Share on other sites
HazJ 1289 Posted February 28, 2018 @avibird 1 You are the server when hosting game yourself. 1 Share this post Link to post Share on other sites
avibird 1 36 Posted March 1, 2018 @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
avibird 1 36 Posted March 2, 2018 @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. what am I doing wrong with your code above???? Share this post Link to post Share on other sites
pierremgi 4850 Posted March 2, 2018 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
avibird 1 36 Posted March 2, 2018 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
HazJ 1289 Posted March 2, 2018 @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. 1 Share this post Link to post Share on other sites
avibird 1 36 Posted March 2, 2018 @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
HazJ 1289 Posted March 2, 2018 @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)]; }; 1 Share this post Link to post Share on other sites
HazJ 1289 Posted March 6, 2018 [] 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 Share this post Link to post Share on other sites
pierremgi 4850 Posted March 6, 2018 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. 1 Share this post Link to post Share on other sites
HazJ 1289 Posted March 6, 2018 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
pierremgi 4850 Posted March 6, 2018 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.. 1 Share this post Link to post Share on other sites
pierremgi 4850 Posted March 6, 2018 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}; }; }; 1 1 Share this post Link to post Share on other sites
HazJ 1289 Posted March 6, 2018 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. 1 Share this post Link to post Share on other sites
pierremgi 4850 Posted March 7, 2018 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
avibird 1 36 Posted March 7, 2018 @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
pierremgi 4850 Posted March 7, 2018 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