Jump to content
barn

Counting variable in MP

Recommended Posts

Hi,

 

I need help for 2 questions please. I can't find the answer by searching the forum. I have 4 objects with this action "hack" and when the 4 computers are hacked, it's supposed to start an evac script.

 

On one of the computer ini

Quote

hacking1 = [computer1,"<t color='#00FF00'>HACK COMPUTER</t>", "\a3\ui_f\data\IGUI\Cfg\holdactions\holdAction_unbind_ca.paa", "\a3\ui_f\data\IGUI\Cfg\holdactions\holdAction_unbind_ca.paa", "_this distance _target < 4","_caller distance _target < 4",{[["HACKING IN PROGRESS..."],safeZoneX, safeZoneH / 2,true,"<t font='PuristaBold'>%1</t>",[],{ false },true] spawn BIS_fnc_typeText2;},{},{ [] execVM "hacking.sqf" },{},[],10,0,true,false] call BIS_fnc_holdActionAdd;

 

In my hacking.sqf file i wrote this

 

Quote

[hacking1,10 ] call BIS_fnc_holdActionRemove;

hackingcount = hackingcount +1;

if (hackingcount == 4) then
{ //script evac

};

 

In my init.sqf i wrote this

Quote

hackingcount = 0;

 

So my first question is how can i detect in my script if the action is start by computer 1 or 2 or 3 or 4 and how can i check that the 4 computers are hack.

And second question: the hackingcount is working in local and start the evac script but not in MP. Is there an other way to do it for MP?

 

Thanks a lot for your help guys.

 

 

 

Share this post


Link to post
Share on other sites

Hello Barn. A lot of things here to talk about. I'll tell you how I would "tackle" the situation here. There might be a better way (most probably there is) though.

 

Regarding your first question: In the parameters of the holdAction you pass to the function (BIS_fnc_holdActionAdd) you can get the computer that is being hacked in the variable _target (provided by the engine). You could use that and pass it to your script. Additionally, you should pass the ID of the action too (you will need it in order to remove the action). These would require two small modification of your code. The first one is on the computer's init and should be

hacking1 = [computer1,
"<t color='#00FF00'>HACK COMPUTER</t>",
"\a3\ui_f\data\IGUI\Cfg\holdactions\holdAction_unbind_ca.paa",
"\a3\ui_f\data\IGUI\Cfg\holdactions\holdAction_unbind_ca.paa",
"_this distance _target < 4"
,"_caller distance _target < 4",
{
  [["HACKING IN PROGRESS..."],safeZoneX, safeZoneH / 2,true,"<t font='PuristaBold'>%1</t>",[],{ false },true] spawn BIS_fnc_typeText2;},
{},
{ // CHANGES HERE --- CHANGES HERE --- CHANGES HERE --- CHANGES HERE
  [_target, _actionID] execVM "hacking.sqf" // Here I have passed the variable _target (holds the computer that is being hacked) and the _actionID (holds the ID of the action) to the hacking.sqf script
}, // CHANGES HERE --- CHANGES HERE --- CHANGES HERE --- CHANGES HERE
{},
[],
10,
0,
true,
false] call BIS_fnc_holdActionAdd;

Then, in your hacking.sqf script you should do

// Get the computer passed as argument to the script
private _comp = _this select 0; // Here you go, this is the computer
private _actionID = _this select 1; // Here is the action you will need to remove the holdAction

// Find out which of the four computers this is
private _compIdx = [computer1, computer2, computer3, computer4] findIf {_x isEqualTo _comp}; // The zero based index will be returned (e.g. if 2 is returned you have computer3)

// Here you can do stuff based on which computer it is (just goofing around :D)
if(_compIdx == 2) then {
  systemChat "Nooooooo..., this is the one with all my porn ;(...";
};

// CHANGES HERE --- CHANGES HERE --- CHANGES HERE
[_comp,_actionID] call BIS_fnc_holdActionRemove; // You had [hacking1, 10] as arguments but I think it was wrong -> The arguments should be [Object, ID]
// CHANGES HERE --- CHANGES HERE --- CHANGES HERE

hackingcount = hackingcount +1;

if (hackingcount == 4) then
{ //script evac

}; 

Now, this works because, as I have understood from your first script, you have named the computers computer1 (and I guess) through computer4. In any way, you should place the exact same names in the array before findIf in order for the comparison to be able to be done successfully.

 

Not sure this helps, but it is a simple way you could do it without changing too much your current code.

 

Regarding your second question: In order to do your code MP compatible there are a couple of things you should change. First of all, you should place hackingcount = 0 into the initServer.sqf (this runs when the server is initialised, while init.sqf runs every time a player joins).

 

Additionally, you should call your BIS_fnc_holdActionAdd and BIS_fnc_holdActionRemove with a remoteExec or remoteExecCall. holdActions must be placed in every computer you want to be shown. This means that in the simplest case you would like everyone to be able to see the holdAction you should call like (I copy and paste exactly the example from above)

hacking1 = [computer1,
"<t color='#00FF00'>HACK COMPUTER</t>",
"\a3\ui_f\data\IGUI\Cfg\holdactions\holdAction_unbind_ca.paa",
"\a3\ui_f\data\IGUI\Cfg\holdactions\holdAction_unbind_ca.paa",
"_this distance _target < 4"
,"_caller distance _target < 4",
{
  [["HACKING IN PROGRESS..."],safeZoneX, safeZoneH / 2,true,"<t font='PuristaBold'>%1</t>",[],{ false },true] spawn BIS_fnc_typeText2;},
{},
{ // CHANGES HERE --- CHANGES HERE --- CHANGES HERE --- CHANGES HERE
  [_target, _actionID] execVM "hacking.sqf" // Here I have passed the variable _target (holds the computer that is being hacked) to the hacking.sqf script
}, // CHANGES HERE --- CHANGES HERE --- CHANGES HERE --- CHANGES HERE
{},
[],
10,
0,
true,
false] remoteExecCall ["BIS_fnc_holdActionAdd", -2, true]; // ADDITIONAL CHANGES HERE --- ADDITIONAL CHANGES HERE --- ADDITIONAL CHANGES HERE

You can see how remoteExecCall is used in the docs.

To explain this specific example:

1) remoteExecCall calls the given function ("BIS_fnc_holdActionAdd") with the arguments given before the remoteExecCall.

2)The next number (-2) tells the command where (at which computers) to execute the command. Some numbers have a specific meaning. For example, 0 is everywhere, 2 is at the server and from that on are the connected clients with 3 being the first one. When you use a minus (like here) the command is executed everywhere but the client with this ID. So, here I execute the command everywhere except the server (no need to add an action to the server). Keep in mind that you can use arrays in the place of this argument specifying all the clients as elements of the array.

3) The final argument is JIP support, which means that it will be executed for players that are joining after the mission has started.

 

Suffice to say that this same process has to be done for the holdActionRemove. This should look like (again copying the above example)

// Get the computer passed as argument to the script
private _comp = _this select 0; // Here you go, this is the computer
private _actionID = _this select 1; // This is the action ID you have to use to remove the holdAction

// Find out which of the four computers this is
private _compIdx = [computer1, computer2, computer3, computer4] findIf {_x isEqualTo _comp}; // The zero based index will be returned (e.g. if 2 is returned you have computer3)

// Here you can do stuff based on which computer it is (just goofing around :D)
if(_compIdx == 2) then {
  systemChat "Nooooooo..., this is the one with all my porn ;(...";
};

// CHANGES HERE --- CHANGES HERE --- CHANGES HERE
[_comp,_actionID] call BIS_fnc_holdActionRemove; // You had [hacking1, 10] as arguments but I think it was wrong -> The arguments should be [Object, ID]
// CHANGES HERE --- CHANGES HERE --- CHANGES HERE

hackingcount = hackingcount +1;

if (hackingcount == 4) then
{ //script evac

}; 

I am not sure though about the locality of computers. If they remain always on the server this should work. In any other case, if the computers change locality, you should somehow make sure that the code executed on the machine they are local has access to hackingcount in order to be able to alter its value. This would require the use of getVariable and setVariable. This means that everywhere you read hackingcount you should instead use

private _localCount = missionNamespace getVariable "hackingcount";

and where you want to alter its value

private _randNum = 23523; // Just a random number for demonstration
missionNamespace setVariable["hackingcount", _randNum]; // You could had put the number directly in there instead of _randNum

This would require you to do in the initServer.sqf

missionNamespace setVariable["hackingcount", 0]; // Create the variable in the namespace and initialise its value

Pppfff, that's quite a lot of information... I do hope this will help somehow though, and if you encounter any difficulties or want more information please don't hesitate to ask around here.

  • Like 2

Share this post


Link to post
Share on other sites

A thousand thanks ZaellixA ! For the time and all these very useful details! It really helps me to understandhow it works!

I will work on that !

 

  • Like 1

Share this post


Link to post
Share on other sites

So! Me again with this script.

 

In the init object field i have now a perfect working script thanks to you guys 😉 :

Quote

[puitdevin,"<t color='#00FF00'>SEARCH</t>", "\a3\ui_f\data\IGUI\Cfg\holdactions\holdAction_requestleadership_ca.paa","\a3\ui_f\data\IGUI\Cfg\holdactions\holdAction_requestleadership_ca.paa","_this distance _target < 3","_this distance _target < 3",{}, {},{[_this select 1] execVM "randompuits.sqf";[(_this select 0),(_this select 2)] remoteExec ["bis_fnc_holdActionRemove",[0,-2] select isDedicated,true];},{},[], 2,0,true, false] call BIS_fnc_holdActionAdd;

 

I'm trying now to pass the parameter _this select 1 from BIS_fnc_holdActionAdd to the script "randompuits.sqf".

 

In my SQF:

Quote

_unitName = _this select 0;

[_unitName,"Voilà une information intéressante. Ca nous fait une belle jambe."] remoteExec ["sideChat",-2];

 

But nothing happend.

If i'm not mistaking, for ExecVM the param is _this select 0 and i bring it from the BIS_fnc_holdActionAdd _this select 1.

Can you help me to understand this?

Share this post


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

So! Me again with this script.

 

In the init object field i have now a perfect working script thanks to you guys 😉 :

 

I'm trying now to pass the parameter _this select 1 from BIS_fnc_holdActionAdd to the script "randompuits.sqf".

 

In my SQF:

 

But nothing happend.

If i'm not mistaking, for ExecVM the param is _this select 0 and i bring it from the BIS_fnc_holdActionAdd _this select 1.

Can you help me to understand this?

Not sure what the problem is here and unfortunately I cannot test right now, but one easy thing to do is to use systemChat, or hint to do some quick debugging. You can print the content of the variable _this select 0 in your randompuits.sqf in order to make sure you have passed something and if you have that it is what you really want to pass.

 

One more thing is that you may have to check whether sideChat is enabled. I am not 100% sure that this has an effect on what you are trying to achieve though (scripting commands may override this). You can try

1 enableChannel true; // 1 is for side

but again I am not sure this has an impact on your script. I will do my best to try you code out and let you know.

 

One last thing. Please try to format your code in the forums to make it somewhat more readable.

  • Like 1

Share this post


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

Please try to format your code in the forums to make it somewhat more readable.

Yes, please.

 

What you have is this:

[
	puitdevin,
	"<t color='#00FF00'>SEARCH</t>", 
	"\a3\ui_f\data\IGUI\Cfg\holdactions\holdAction_requestleadership_ca.paa",
	"\a3\ui_f\data\IGUI\Cfg\holdactions\holdAction_requestleadership_ca.paa",
	"_this distance _target < 3",
	"_this distance _target < 3",
	{}, 
	{},
	{
		[_this select 1] execVM "randompuits.sqf";
		[(_this select 0),(_this select 2)] remoteExec ["bis_fnc_holdActionRemove",[0,-2] select isDedicated,true];
	},
	{},
	[], 
	2,
	0,
	true, 
	false
] call BIS_fnc_holdActionAdd; 
Quote

(Select 4): STRING - condition for the action to be shown; special variables passed to the script code are _target (unit to which action is attached to) and _this (caller/executing unit)

(Select 5): STRING - condition for action to progress; if false is returned action progress is halted; arguments passed into it are: _target, _caller, _id, _arguments

Try changing array select 5 to: "_caller distance _target < 3".

  • Like 2

Share this post


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

Yes, please.

 

What you have is this:


[
	puitdevin,
	"<t color='#00FF00'>SEARCH</t>", 
	"\a3\ui_f\data\IGUI\Cfg\holdactions\holdAction_requestleadership_ca.paa",
	"\a3\ui_f\data\IGUI\Cfg\holdactions\holdAction_requestleadership_ca.paa",
	"_this distance _target < 3",
	"_this distance _target < 3",
	{}, 
	{},
	{
		[_this select 1] execVM "randompuits.sqf";
		[(_this select 0),(_this select 2)] remoteExec ["bis_fnc_holdActionRemove",[0,-2] select isDedicated,true];
	},
	{},
	[], 
	2,
	0,
	true, 
	false
] call BIS_fnc_holdActionAdd; 

Try changing array select 5 to: "_caller distance _target < 3".

Yes, good catch... _this is the caller only at the first condition (start condition). 

Share this post


Link to post
Share on other sites
12 hours ago, ZaellixA said:

One last thing. Please try to format your code in the forums to make it somewhat more readable.

 

Sorry about that. I'll try to be more careful on the futur!

 

Thanks both of you! I tried like this:

[
	puitdevin,
	"<t color='#00FF00'>SEARCH</t>", 
	"\a3\ui_f\data\IGUI\Cfg\holdactions\holdAction_requestleadership_ca.paa",
	"\a3\ui_f\data\IGUI\Cfg\holdactions\holdAction_requestleadership_ca.paa",
	"_caller distance _target < 3",
	"_caller distance _target < 3",
	{}, 
	{},
	{
		[_caller] execVM "randompuits.sqf";
		[(_this select 0),(_this select 2)] remoteExec ["bis_fnc_holdActionRemove",[0,-2] select isDedicated,true];
	},
	{},
	[], 
	2,
	0,
	true, 
	false
] call BIS_fnc_holdActionAdd; 

AND for testing I put this in my SQF:

 

_unitName = _this select 0;

[_unitName,"Voilà une information intéressante. Ca nous fait une belle jambe."] remoteExec ["sideChat",-2];

format ["%1 TEST", _unitName] remoteExec ["hint"];

And the HINT works! The name of the _caller appears. So it's apparently a sidechat code problem.. But i don't understand bescause it's the right way.. The sidechat isn't displayed at all. And no errors appears.

Any idea ?

Share this post


Link to post
Share on other sites

Have you tried enabling the side chat? Try this

1 enableChannel true;

 

Share this post


Link to post
Share on other sites
1 enableChannel true;

 

Where should i put this ? in the ini.sqf or at the begining of my script ?

 

Ok I think i find something:

 

Work:

 

_unit = _this select 0;
[_unit," Voilà une information intéressante. Ca nous fait une belle jambe."] remoteExec ["sideChat",0];

Doesn't work:
 

_unit = _this select 0;

_unitName = name _unit;
[_unitName,"Voilà une information intéressante. Ca nous fait une belle jambe."] remoteExec ["sideChat",0];

Doesn't work either with :

_unit = _this select 0;
[_unit," Voilà une information intéressante. Ca nous fait une belle jambe."] remoteExec ["sideChat",-2];

 

What exactly is the "-2" ?

Share this post


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

"_caller distance _target < 3",
"_caller distance _target < 3",

 

 

Should be:

"_this distance _target < 3",
"_caller distance _target < 3",

 

 

1 hour ago, barn said:

What exactly is the "-2" ?

Means "not the server".  Will execute on all connected clients, but the server itself will be excluded.

It's commonly used to keep a dedicated server from executing Player and hasInterface related stuff where it might result in errors, since Player is objNull on dedicated server and it has no interface.

 

  • Like 1

Share this post


Link to post
Share on other sites

Thanks a lot guys !

 

So it's the reason I can't see the sidechat while i'm testing it alone on local.

Is there a way to make it work both on local and when I play with players ?

Share this post


Link to post
Share on other sites

Aaaahhh... right, so you were testing on local and the -2 resulted in the code not being executed on your machine which is the server too.

 

I believe that with this you could possibly make it happen

[_unit," Voilà une information intéressante. Ca nous fait une belle jambe."] remoteExec ["sideChat",[0, -2] select isDedicated];

Just to make sure you understand what this does:

 

From the array [0, -2] you select what isDedicated returns, which is either 0 or 1. It returns false (which is like 0) when you this is run on a machine which is NOT a dedicated server and then you pick the first element (zero based) and when you this is run on a dedicated server, the isDedicated returns true (which is 1) and  you select -2, which forces the sideChat command to be executed everywhere but the server.

 

Haven't tested it, but I believe it should do the job. Try it out and let us know if you face more issues.

  • Like 1

Share this post


Link to post
Share on other sites

Ok got it!

Thanks for the assistance 🙂

 

For now it's working perfectly like that. I made a test with a second player, everything works fine!

 

  • 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

×