Jump to content
Lorenz94

RemoteExec a Display?

Recommended Posts

Hello,

I wrote a script that adds an action to an helicopter, visible only to the pilot. This action creates a display similar to a hint, that I need to be displayed to all the players in the same helicopter.

 

I know how to use remoteExec with a Hint, but I need to use a display instead because I can put it where I want on the screen!

 

Here's the code for the GUI creation, how do I remoteExec it so once the pilot uses it, each player on the heli see it?

 

Spoiler

if (player in _heli) then {
	with uiNamespace do {
		//Prevents Overlays
		_deleteBckg = ctrlDelete (uiNamespace getVariable "light_bckg");
		_deleteText = ctrlDelete (uiNamespace getVariable "light_text");
		_deleteLight = ctrlDelete (uiNamespace getVariable "light_img");
		//Background
		light_bckg = findDisplay 46 ctrlCreate ["RscProgress", -1]; //sfondo
		light_bckg ctrlSetPosition [safezoneX + 0.005*safezoneW, safezoneY + 0.125*safezoneH, 0.125*safezoneW, 0.14*safezoneH];
		light_bckg ctrlSetTextColor [0,0,0,0.30];
		light_bckg progressSetPosition 0.5;
		light_bckg ctrlCommit 0;
		//Title Text
		light_text = findDisplay 46 ctrlCreate ["RscStructuredText", -1];
		light_text ctrlSetPosition [safezoneX + -0.1835*safezoneW, safezoneY + 0.127*safezoneH, 0.50*safezoneW, 0.2*safezoneH];
		light_text ctrlCommit 0;
		//IMG
		light_img = findDisplay 46 ctrlCreate ["RscStructuredText", -1];
		light_img ctrlSetPosition [safezoneX + -0.1835*safezoneW, safezoneY + 0.1626*safezoneH, 0.50*safezoneW, 0.2*safezoneH];
		light_img ctrlCommit 0;

	};
	
	(uiNamespace getVariable "light_bckg") progressSetPosition 100;
	(uiNamespace getVariable "light_text") ctrlSetStructuredText parseText (_text_1);
	(uiNamespace getVariable "light_img") ctrlSetStructuredText parseText (_img);
	sleep 5;
	ctrlDelete (uiNamespace getVariable "light_bckg");
	ctrlDelete (uiNamespace getVariable "light_text");
	ctrlDelete (uiNamespace getVariable "light_img");
};

 

 

Thank you!

Share this post


Link to post
Share on other sites

You'd probably be better off making a dialog.hpp and then remoteExec cutRsc with an onLoad script (function). Otherwise you can do this:

[[],{
	/* Your code goes here */
}] remoteExec ["call/spawn",crew heli];

 

  • Like 1

Share this post


Link to post
Share on other sites

You could have this display ready for all players and enable (cutRsc) it just with conditions (&& publicVariable if needed).

Share this post


Link to post
Share on other sites
8 hours ago, Tajin said:

Put it in a function then remoteExec that function.

 

Cleanest way is via the functions library (https://community.bistudio.com/wiki/Functions_Library_(Arma_3)) but you can also define it directly by simply putting the code in a variable.

Thank you for your reply.

 

I tried to give the whole code the variable _hint, but it doesn't work. The pilot can see the action and the dialog pop ups, but it's not broadcasted.

 

What I've done:

Spoiler

_hint = with uiNamespace do {
		//Prevents Overlays
		ctrlDelete (uiNamespace getVariable "light_bckg");
		ctrlDelete (uiNamespace getVariable "light_text");
		ctrlDelete (uiNamespace getVariable "light_img");
		//Background
		light_bckg = findDisplay 46 ctrlCreate ["RscProgress", -1]; //sfondo
		light_bckg ctrlSetPosition [safezoneX + 0.005*safezoneW, safezoneY + 0.125*safezoneH, 0.125*safezoneW, 0.14*safezoneH];
		light_bckg ctrlSetTextColor [0,0,0,0.30];
		light_bckg progressSetPosition 0.5;
		light_bckg ctrlCommit 0;
		//Title Text
		light_text = findDisplay 46 ctrlCreate ["RscStructuredText", -1];
		light_text ctrlSetPosition [safezoneX + -0.1835*safezoneW, safezoneY + 0.127*safezoneH, 0.50*safezoneW, 0.2*safezoneH];
		light_text ctrlCommit 0;
		//IMG
		light_img = findDisplay 46 ctrlCreate ["RscStructuredText", -1];
		light_img ctrlSetPosition [safezoneX + -0.1835*safezoneW, safezoneY + 0.1626*safezoneH, 0.50*safezoneW, 0.2*safezoneH];
		light_img ctrlCommit 0;
	
		(uiNamespace getVariable "light_bckg") progressSetPosition 100;
		(uiNamespace getVariable "light_text") ctrlSetStructuredText parseText (_text_1);
		(uiNamespace getVariable "light_img") ctrlSetStructuredText parseText (_img);
		sleep 5;
		ctrlDelete (uiNamespace getVariable "light_bckg");
		ctrlDelete (uiNamespace getVariable "light_text");
		ctrlDelete (uiNamespace getVariable "light_img");
} remoteExec ["do", crew _heli];

 

I'm not sure about the "do" inside remoteExec, but using "call" or "spawn" I get an error that states "boolean, expected code".

 

Thank you again.

Share this post


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

You could have this display ready for all players and enable (cutRsc) it just with conditions (&& publicVariable if needed).

Yes, but this is the way I'm not able to pursue, because I don't know how to write it down and where! ;(

Share this post


Link to post
Share on other sites
8 hours ago, 7erra said:

You'd probably be better off making a dialog.hpp and then remoteExec cutRsc with an onLoad script (function). Otherwise you can do this:


[[],{
	/* Your code goes here */
}] remoteExec ["call/spawn",crew heli];

 

Thank you for your reply! I tried something like this (please see the reply to Tajin), but I can't get it to work. Even without the variable, I get the same error:

Spoiler

[[], { with uiNamespace do {
		//Prevents Overlays
		ctrlDelete (uiNamespace getVariable "light_bckg");
		ctrlDelete (uiNamespace getVariable "light_text");
		ctrlDelete (uiNamespace getVariable "light_img");
		//Background
		light_bckg = findDisplay 46 ctrlCreate ["RscProgress", -1]; //sfondo
		light_bckg ctrlSetPosition [safezoneX + 0.005*safezoneW, safezoneY + 0.125*safezoneH, 0.125*safezoneW, 0.14*safezoneH];
		light_bckg ctrlSetTextColor [0,0,0,0.30];
		light_bckg progressSetPosition 0.5;
		light_bckg ctrlCommit 0;
		//Title Text
		light_text = findDisplay 46 ctrlCreate ["RscStructuredText", -1];
		light_text ctrlSetPosition [safezoneX + -0.1835*safezoneW, safezoneY + 0.127*safezoneH, 0.50*safezoneW, 0.2*safezoneH];
		light_text ctrlCommit 0;
		//IMG
		light_img = findDisplay 46 ctrlCreate ["RscStructuredText", -1];
		light_img ctrlSetPosition [safezoneX + -0.1835*safezoneW, safezoneY + 0.1626*safezoneH, 0.50*safezoneW, 0.2*safezoneH];
		light_img ctrlCommit 0;
	
		(uiNamespace getVariable "light_bckg") progressSetPosition 100;
		(uiNamespace getVariable "light_text") ctrlSetStructuredText parseText (_text_1);
		(uiNamespace getVariable "light_img") ctrlSetStructuredText parseText (_img);
		sleep 5;
		ctrlDelete (uiNamespace getVariable "light_bckg");
		ctrlDelete (uiNamespace getVariable "light_text");
		ctrlDelete (uiNamespace getVariable "light_img");
 		};
}] remoteExec ["call (tried also spawn)", crew _heli];

 

 

Share this post


Link to post
Share on other sites

Okay let's make a cutRsc: (tl:dr at the end)

 

  1. Create a description.ext
  2. Put this in it:
  3. #include "GUI\defines_A3.hpp"
    class RscTitles
    {
    	class Default 
    	{
    		idd = -1;
    		fadein = 0;
    		fadeout = 0;
    		duration = 0;
    	};
    	#include "GUI\heliOverlay.hpp"
    };

    Create the defines_A3.hpp: defines_A3.hpp (@drive.google.com)

  4. Create the folder path and the file

  5. Put this in the heliOverlay.hpp:

  6. class RSC_NAME {
    	idd = IDD_NUMBER;
    	movingEnable = 0;
    	onLoad = "0 = _this execVM ""GUI\onLoadHeliOverlay.sqf""";
    	duration = 1e+6; // lasts for 1.000.000s, change to 5 then you don't need the "sleep 5; "" cutFadeOut 0;" command in the onLoad script (see below)
    	fadein = 0;
    	fadeout = 0;
    	class controlsBackground {
    
    	};
    	class controls {
    
    	};
    };

    Change the RSC_NAME to something you like, idealy with your TAG and Rsc: TAG_RscHeliOverlay. Also change the IDD to a number. Don't use any IDD that is already in use like 0,12,46,49 and some more. Pick a random number but don't worry it is highly unlikely that you will notice any problems since there are hundreds of IDDs in use. The higher the number the further it is placed in the front.

  7. Go ingame and use the GUI editor. Create the display you want. (I hope you know how to use it but it is not that complicated)

  8. Create the onLoadHeliOverlay.sqf:

    disableSerialization;
    _mainDisplay = _this select 0;
    _yourControl = _mainDisplay displayCtrl IDC_YourControl;
    _yourControl1 = _mainDisplay displayCtrl IDC1_YourControl;
    _yourControl2 = _mainDisplay displayCtrl IDC2_YourControl;
    //...
    
    _yourControl progressSetPosition 100;
    _yourControl1 ctrlSetStructuredText parseText (_text_1);
    _yourControl2 ctrlSetStructuredText parseText (_img);
    sleep 5;
    "YourLayerName" cutFadeOut 0;

     

  9. (I'll skip some steps as there are enough tutorials for this purpose out there and I'll focus on the cutRsc command)

  10. Now if you've done something wrong then the game will tell you by crashing to desktop ;) Also when working with the description.ext you have to go back to the editor everytime and save your mission again.

  11. You can create the display with cutRsc

    "YourLayerName" cutRsc ["TAG_RscHeliOverlay", "PLAIN"];

    Or in your case:

    ["YourLayerName",["TAG_RscHeliOverlay","PLAIN"]] remoteExec ["cutRsc",crew _heli];

      

There we go that's it. My tests worked so far but not tested in MP even though I am confident this should do.

 

 

tl:dr:

 

  1. Create a dialog with the attributes of a Rsc
  2. Use the cutRsc command with remoteExec
  3. onLoad will do the trick

 

Additional information, general tips for dialogs:

Spoiler

To make your onLoad script prettier and more flexible you can use the #define command:


#define MAINDISPLAY (findDisplay IDD)
#define CTRL(IDC) (MAINDISPLAY displayCtrl IDC)
#define CTRLNAME CTRL(IDC)
#define CTRLNAME CTRL(IDC)
#define CTRLNAME CTRL(IDC)

This will make the defined variables available in you whole script, eg eventhandlers (your best friends when you deal with dialogs). Also you might not need disableSerialization because you don't put any GUI stuff in a variable. If someone knows what disableSerialization does then please let me know as I don't have any experience with programming other than ArmA.

It makes sense to put this in a seperate file to make it available across scripts. Call it with #include "filename.hpp/sqf" (not sure about preprocessFileLineNumbers)

 

And to increase performance you should use a function instead of execVM in the onLoad evenhandler. See Functions Library.

 

 

That's all. Easy, eh?

Edited by 7erra
duration attribute comment
  • Like 1

Share this post


Link to post
Share on other sites

Others above beat me to it.

 

Easiest way to use Remote Execution in a no-brainer way, is with call/spawn

 

{
	if (isDedicated) exitWith {};
	/*/ insert your script here /*/
} remoteExec ['spawn',<targets>];

 

  • Like 1

Share this post


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

Others above beat me to it.

 

Easiest way to use Remote Execution in a no-brainer way, is with call/spawn

 


{
	if (isDedicated) exitWith {};
	/*/ insert your script here /*/
} remoteExec ['spawn',<targets>];

 

 

Not sure to understand why you need to remoteExec an entire script. (To have tested this solution, most of the time your display will not fire due to lack of time on network flow).

On my mind, a display (hint HUD or else)  is something essentially local. All the layers can run on local PC. You just have to display something or not along with a variable condition and, if needed common (public) values.

7erra took time to detail the method. On my mind there is no need to remoteExec even the cutRsc. you can toggle between :

cutRsc ["myRsc", "PLAIN"]; //show

cutText ["", "PLAIN"]; //remove

only with a public variable. What else?

 

Share this post


Link to post
Share on other sites
19 hours ago, 7erra said:

Okay let's make a cutRsc: (tl:dr at the end)

REALLY Thank you! I will have a look at it this weekend.

 

Thank you for your time!!

Share this post


Link to post
Share on other sites
On 27/9/2017 at 2:26 AM, 7erra said:

...

Hi 7erra,

I followed your steps (and watched a couple of videos showing how to create a GUI from the editor). I still miss something, since I don't know exactly if I'm doing this the right way, or if I'm doing something redundat. Let me explain what I've done so far:

 

Easy through step 6, where I deleted "class controlsBackground", and pasted inside "class controls" what follows:

Spoiler

//I made a background for the GUI, then I created a text box and an image space in it (so that I can display an image and a text that describes it), NOT sure if this is correct, or if I just need to create the background and then fill it with the text and the image

class controls {
		////////////////////////////////////////////////////////
		// GUI EDITOR OUTPUT START (by {9GU}Pvt.Brazzer, v1.063, #Lipumy)
		////////////////////////////////////////////////////////

		class BRZ_background: IGUIBack
		{
			idc = 2200;
			x = 0.0101562 * safezoneW + safezoneX;
			y = 0.313 * safezoneH + safezoneY;
			w = 0.113437 * safezoneW;
			h = 0.165 * safezoneH;
		};
		class BRZ_lightType: RscPicture
		{
			idc = 1200;
			text = "#(argb,8,8,3)color(1,1,1,1)";
			x = 0.0410937 * safezoneW + safezoneX;
			y = 0.39 * safezoneH + safezoneY;
			w = 0.0515625 * safezoneW;
			h = 0.077 * safezoneH;
		};
		class BRZ_textLight: RscStructuredText
		{
			idc = 1100;
			text = "ABCD"; //--- ToDo: Localize;
			x = 0.0153125 * safezoneW + safezoneX;
			y = 0.324 * safezoneH + safezoneY;
			w = 0.103125 * safezoneW;
			h = 0.044 * safezoneH;
		};
		////////////////////////////////////////////////////////
		// GUI EDITOR OUTPUT END
		////////////////////////////////////////////////////////
	};

 

 

step 7 is ok, but in step 8 I haven't understood very well what's going on in here.. please see below:

Spoiler

disableSerialization;
_mainDisplay = _this select 0;
_background = _mainDisplay displayCtrl BRZ_background;
_text = _mainDisplay displayCtrl BRZ_textLight;
_img = _mainDisplay displayCtrl BRZ_lightType;

_text_1 = "<t color='#00CD00' font='PuristaBold' size='1.2' shadow='1' shadowColor='#000000' align='center'>= JUMP NOW =</t>";
_img = "<img size='4' image= 'scripts\jump_system\lights_act\img\green.paa' align='center'/>";


//how to call the image in the "image box", and the text in the text box?

sleep 5;
"BRZ_RscHeliOverlay" cutFadeOut 0; //Not sure if is this or not the layer name so far.. please help!

 

 

Moreover, what does it mean "tl:dr:"? 

 

Thank you for your help!

Share this post


Link to post
Share on other sites

To clarify step 6:

class RSC_NAME {// Change RSC_NAME to whatever you like. You will have to use it with ""layerName" cutRsc ["RSC_NAME","PLAIN"];
	idd = IDD_NUMBER; //Insert a number here
	movingEnable = 0; //Decides wether you are able to move the dialog or not, you can't move a cutRsc anyway so leave it as it is
	onLoad = "0 = _this execVM ""GUI\onLoadHeliOverlay.sqf"""; //Script executed when the dialog is created, _this == [_dialog]
	duration = 1e+6; // lasts for 1.000.000s, change to 5 then you don't need the "sleep 5; "" cutFadeOut 0;" command in the onLoad script (see below)
	fadein = 0; // Time to fade in, also influences cutFadeOut command later on
	fadeout = 0; // Time to fade out
	class controlsBackground {
// Non interactable controls go here [Background, text, (pictures)]
	};
	class controls {
// Interactable controls go here (Buttons, listboxes, edits, etc)
// The later the class comes, the higher it will be placed on the interface
	};
};

 

Regarding step 7: I said it wasn't that hard but actually going back to it made me realize that it takes some practice to use.

 

About step 8: The syntaxes of some of your commands are wrong. If you don't know some commands then it is just the regular procedure as with commands for the game. Google. Most of the commands start with "ctrl". Here is the correct script with comments:

disableSerialization; // Working with GUI elements doesn't allow saving, therefore this command. It doesn't do anything gameplay wise except preventing a game error
_mainDisplay = _this select 0; // The param passed as an array which contains the dialog. You could also return a normal dialog with "findDisplay IDD" but not a cutRsc.
_background = _mainDisplay displayCtrl 2200; //Don't use the classes. Use the idc instead.
_textCtrl = _mainDisplay displayCtrl 1100;
_imgCtrl = _mainDisplay displayCtrl 1200;

_text_1 = "<t color='#00CD00' font='PuristaBold' size='1.2' shadow='1' shadowColor='#000000' align='center'>= JUMP NOW =</t>";
_imgPath = "scripts\jump_system\lights_act\img\green.paa"; //The path to the image is sufficent. No need to format anything as it will be aligned with the control size.
// Don't use the same variable for different values if you need it later on

//how to call the image in the "image box", and the text in the text box?
// Picture:
_imgCtrl ctrlSetText _imgPath; //Done
// Text: This will be a structured text, therefore we have to use parseText first since RscStructuredText needs text and not a string
_text_1 = parseText _text_1; // Formatting is done too
_textCtrl ctrlSetStructuredText _text_1;

// Now, if you want to let the dialog fade out after 5 seconds everytime then you can use the duration atttribute instead of the following commands.
// Remember how you created the dialog: "layerName" cutRsc ["RscName","PLAIN"]. Now take "layerName" and insert it here:
sleep 5;
"layerName" cutFadeOut 0; //let's the dialgog disappear

 

Share this post


Link to post
Share on other sites

As Tajin stated, make it a function and then remoteExec it. It is a shame you can't use it directly without putting it into a function. Displays I mean, as it requires disableSerialization at the top.

Share this post


Link to post
Share on other sites

It seems I'm not clear. So, my last here will just point again at there is no reason to remoteExec a full display. A display is / can be  / should be local (kind of HUD), with all the stuff in description.ext and initplayerLocal (addAction must be also placed in a respawn event (sqf or EH/MEH).

Why? The only things you have to remoteExec is:

1 - a variable (just use publicVariable) as a common condition (from addAction) to display what you want locally,

2 - some common data, generally the  value : text, arrow, picture,... displayed in "HUD",  if its refresh is needed (global scores, pictures of loot, shared updated info)...

Here, pt 1 seems to me obvious, pt2 not really because the JUMP and green light (or else) doesn't truly need a sync between the clients.

 

So, place all your stuff in description.ext, sqf and publicVariable , remoteExec what is strictly mandatory.

 

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

×