Jump to content
Sign in to follow this  
Cyteless

[Help] Headless Client - Global Variable not recognised - "undeclared variable"

Recommended Posts

Hi all, trying to get a headless client driven mission together for testing on my group's server. I've ran into a bit of a snag, and I'm not quite experienced enough with Arma's scripting to realise what I've done. I've pretty much taken this from one of the guides on the BI wiki, which I realise is for Arma 2, but I figured everything would've been transferable. This is all in the init.sqf

The problem arises at line 36, Arma's saying that the global variable HCPresent isn't decalred. Says "Error: Undeclared variable in expression: hcpresent"

init.sqf

if(isNil "paramsArray") then{ paramsArray=[0,0,0]}; 

if(paramsArray select 0 == 1) then{ 

if(isServer) then{

	HCPresent = true; 
	publicVariable "HCPresent"; 

};

if(!hasInterface && !isServer) then{

	HCName = name player; 
	publicVariable "HCName"; 

}

else{

	if(isServer) then{

		HCPresent = false; 
		HCName = "NOONE"; 
		publicVariable "HCPresent"; 
		publicVariable "HCName"; 

	};

};

};

if(!isServer) then {waitUntil{!isNull player}}; 

if(HCPresent) then{

if(!hasInterface && !isServer) then{

	_hq_east = createCenter east; 
	_hq_west = createCenter west; 
	east setFriend [west,0]; 
	west setFriend [east,0]; 

	execVM "scripts\spawns\patrol-op-1.sqf";  

}

else{

	if (isServer) then{

		_hq_east = createCenter east; 
		_hq_west = createCenter west; 
		east setFriend [west,0]; 
		west setFriend [east,0]; 

		execVM "scripts\spawns\patrol-op-1.sqf"; 

	};

};

};

description.ext

class Params
{
class HeadlessClient
{		
	title = "Headless Client";
	values[] = {0,1}; 
	texts[] = {"OFF","ON"}; 
	default = 0; 
};
};

Surely as the block at the top has the variable declared globally it should be accessed throughout the script? Evidently not, I must've missed something. Any advice would be great.

Edited by CMB Unit 01
init.sqf

Share this post


Link to post
Share on other sites

Your first if-statement can never be true as the paramsArray is initialized with zeros only. So of course, line 36 fails, because HCPresent is never defined.

Edited by Heeeere's Johnny!

Share this post


Link to post
Share on other sites
Your first if-statement can never be true as the paramsArray is initialized with zeros only. So of course' date=' line 36 fails, because [i']HCPresent[/i] is never defined.

I don't really understand. That first line is just to check whether paramsArray has been defined. If it hasn't, then it defines it. I don't see how that would affect line 36. I tried commenting that line out, still throwing up the same error at line 36.

Edit:

And even if there is a zero in that array, then it'll ignore the "if" and move to the "else," where HCPresent is defined as well.

Edited by CMB Unit 01

Share this post


Link to post
Share on other sites

HCPresent will only be defined if paramsArray select 0 is equal to 1. The else is for line 12

   if(!hasInterface && !isServer) then{

If that is false, it would run the else statement on line 19.

Share this post


Link to post
Share on other sites

Pardon me, I ment your second, not the first if-statement.

And even if there is a zero in that array, then it'll ignore the "if" and move to the "else," where HCPresent is defined as well.

No, it won't. Let's look at your code with only the if-else-statements, without the code in between.

if(paramsArray select 0 == 1) then{ 
   if(isServer) then{
   };

   if(!hasInterface && !isServer) then{
   }

   else{
       if(isServer) then{
       };
   };
};

There's only one "else" in that code block and it's inside the big if-statement. So you don't have an else block to be executed if (paramsArray select 0 == 1) is not true.

What you probably want is this:

if(paramsArray select 0 == 1) then{ 

   if(isServer) then{
       HCPresent = true; 
       publicVariable "HCPresent"; 
   };

   if(!hasInterface && !isServer) then{
       HCName = name player; 
       publicVariable "HCName"; 
   };

} else{

   if(isServer) then{
       HCPresent = false; 
       HCName = "NOONE"; 
       publicVariable "HCPresent"; 
       publicVariable "HCName"; 
   };
};

Edited by Heeeere's Johnny!

Share this post


Link to post
Share on other sites
There's only one "else" in that code block and it's inside the big if-statement. So you don't have an else block to be executed if (paramsArray select 0 == 1) is not true.

What you probably want is this:

Ah, you're right sorry. That's got rid of the error, thanks for your help.

Share this post


Link to post
Share on other sites

A3 has made a few changes that make it a little easier to detect headless clients; I made a quick sample mission to illustrate how I do it in A3:

sample mission link

the concepts are the same, just the execution is a little cleaner. Hope it helps!

Share this post


Link to post
Share on other sites

Now I am confused. I thought hasInterface would only be true for clients with mouse and keyboard which is why I am a bit confused about the if-statement in your init.sqf:

// if HC present, spawn units on HC
if(HeadlessClientPresent) then{
   if(!isServer && !hasInterface) then{
       [] spawn _spawnUnits;
   };
}

Share this post


Link to post
Share on other sites
Now I am confused. I thought hasInterface would only be true for clients with mouse and keyboard which is why I am a bit confused about the if-statement in your init.sqf:

// if HC present, spawn units on HC
if(HeadlessClientPresent) then{
   if(!isServer && !hasInterface) then{
       [] spawn _spawnUnits;
   };
}

notice the exclamation point denoting a "not"' date=' so what I am saying more explicitly via pseudo code is:

if(HeadlessClientPresent == True) then{
   if( (isServer == False) AND (hasInterface == False) ) then{
       [] spawn _spawnUnits;  //call the function to spawn units, only on the headlessClient
   };
};

Headless clients are NOT the server, and they do NOT have an interface, hence the ([b']![/b]isServer && !hasInterface) condition. Does that clear things up?

Share this post


Link to post
Share on other sites

Why are you checking if the HC is present before checking if it's a HC?

If the HC is a HC then it knows it is present already :p (Sounds a little silly I know)

I'm a little bias since I wrote the example, but the biki page has examples on spawning the AI for A3: https://community.bistudio.com/wiki/Arma_3_Headless_Client#Spawning_the_AI

Just in case you're still confused.

Share this post


Link to post
Share on other sites
Why are you checking if the HC is present before checking if it's a HC?

If the HC is a HC then it knows it is present already :p (Sounds a little silly I know)

I'm a little bias since I wrote the example, but the biki page has examples on spawning the AI for A3: https://community.bistudio.com/wiki/Arma_3_Headless_Client#Spawning_the_AI

Just in case you're still confused.

The main reason is to have a mission that works with and without the headless client. Unfortunately, you cannot accurately detect if a headless client is present in an automated way as the wiki suggests since the postInit is not always ran before init.sqf(see my post on pg 13 here), so we have to stick an on/off switch in the mission parameters. The basic idea is:

headlessClientPresent = lobby set mission parameter;
if(headlessClientPresent) then{
   //spawn units on a headless client
}else{
  //spawn units on the server
};

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
Sign in to follow this  

×