Jump to content
Lorenz94

HC Tweak + Other Questions

Recommended Posts

Hello and good evening!

 

I'm doing some tweaking on a couple of scripts I wrote recently and I'm having issues that I can't solve by myself, so any help would be appreciated! As usual, I've already done some research here and on google, but I need some questions to be aswered in order to proceed.

 

1. How to count the amount of local units to a Headless Client, starting from a serverside script?

I simply can't. I tried to retrive the ID of a HC to later exec a function local on it, but I can't manage how to do it! Here's what I have:

Spoiler

TAG_fnc_count =
{
  _total = [];
  {
    if (local _x) then {
      _total = count _total + 1;
    };
  } forEach allUnits;
  _total
};

_hcClients = [];

{
  _hcClients pushBack _x;
} forEach (entities "HeadlessClient_F");

_hcLoad = [];
{
  _total = [] remoteExecCall ["TAG_fnc_count", owner (_hcClients select _forEachIndex)];
  _hcLoad pushBack [_hcClients select _forEachIndex, count _total];
} forEach _hcClients;

[str _hcLoad] remoteExec ["hintSilent", 0];

 

that doesn't work, but maybe you can have a clearer vision on what I would like to achieve.

 

2. enableSimulationGlobal: is it true that not all terrain objects can have their simulation disabled? I would like to make all the NW island on Malden indestructible, but nothing happens using:

Spoiler

{
  _x enableSimulationGlobal false;
} forEach nearestTerrainObjects [[698.715, 12128.75, 0], [], 300]; //Also tried using ["BUILDING", "WALL", "FENCE"]

 

 

 

Thank you for your time!

Share this post


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

2. enableSimulationGlobal: is it true that not all terrain objects can have their simulation disabled? I would like to make all the NW island on Malden indestructible, but nothing happens using:

 

Try allowdamage

Share this post


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

1. How to count the amount of local units to a Headless Client, starting from a serverside script?

 

Doesn't sound something that would work. Instead of counting in server try counting them in the headless client, using the local command

Share this post


Link to post
Share on other sites
12 minutes ago, gc8 said:

 

Doesn't sound something that would work. Instead of counting in server try counting them in the headless client, using the local command

Hi, thank you. How am I supposed to do it on a headless? From player init local checking if !hasinterface?

Share this post


Link to post
Share on other sites

Haven't personally done anything with HC so I'm not sure. But your suggestion seems right to me. Hopefully someone who knows better responds to this thread

Share this post


Link to post
Share on other sites

Thank you, I will take a deeper look to that page.

About the allowDamage / enableSimulationGlobal problem, no one seems to work, both tried calling them from init.sqf / initServer.sqf! Maybe it is as I read some times ago on reddit: not all terrain objects can be manipulated

Share this post


Link to post
Share on other sites

I would try using nearObjects instead. Maybe there's a difference?

_list = [_xpos,_ypos] nearObjects ["House", 200];

{

 _x allowDamage false;

} foreach _list;

 

Share this post


Link to post
Share on other sites
17 hours ago, Lorenz94 said:

_total = [] remoteExecCall ["TAG_fnc_count", owner (_hcClients select _forEachIndex)];

remoteExecCall does not return a value from the remote function. All it does is execute the remote function in unscheduled environment.

 

Maybe something like...

//Globally available function
TAG_fnc_count = {
	
	//If we are not the server ( must be remote call from server to HC ) 
	if !( isServer ) then {
		
		//Remote call this function on server with [ client owner ID, unit count ]
		[ clientOwner, count ( allUnits select{ local _x } ] ) remoteExec[ "TAG_fnc_count", remoteExecutedOwner ];
		
	}else{
		
		//Must be remote execute from HC to server
		params[ "_owner", "_count" ];
		
		//Find HC in array and update with [ owner ID, unit count ]
		HC_Clients set[ HC_Clients find _owner, [ _owner, _count ] ];
		
		//If we have received a count back from all HC
		if ( { _x isEqualType [] }count HC_Clients isEqualTo count HC_Clients ) then {
			
			//Format a message
			_message = "";
			{
				_x params[ "_owner", "_count" ];
				
				_message = format[ "%1\nHC: %2, NumUnits: %3", _message, _owner, _count ];
			}forEach HC_Clients;
			
			//Remote exec hint to requestor
			_message remoteExec[ "hintSilent", HCCountRequestor ];
			
			//Flag as finished
			HCCountRequestor = nil;
		};
	};
};

//On server

TAG_fnc_getHCUnitCount = {
	
	//If there is already a count happening
	if !( isNil "HCCountRequestor" ) exitWith {
		//Exit with message to requestor
		"Please wait, there is currently a count in progress" remoteExec[ "hint", remoteExecutedOwner ];
	};
	
	//If this function was called remotely then set requestor as RE-Owner
	//Otherwise set to all player clients
	HCCountRequestor = [ allPlayers - entities "HeadlessClient_F", remoteExecutedOwner ] select isRemoteExecuted;
	
	//Get a array of all HC client owner IDs
	HC_Clients = entities "HeadlessClient_F" apply{ owner _x };
	
	//Remote execute function on all HCs
	[] remoteExec ["TAG_fnc_count", HC_Clients ];
};

 

  • Like 2

Share this post


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

Maybe something like...

Hello, thank you for your reply Larrow.

 

Can you please help me better understand how this actually works? I've spent the entire afternoon doing tests, but I can't get it to work.

 

The first function should be placed in init.sqf and the second in initServer.sqf, and then should I call the latter? I'm having difficulties in understanding how the process would take place!

 

This is what I can understand so far, would you please correct me where wrong?

- You set the "HCCountRequestor" as the person who called the function, otherwise (if the fnc get executed "automatically", I think) to all players.

- You collect the owner's ID of each connected HC

- You execute the count function on each connected HC, using the found ID

 

And then? This is the part I can't understand. What the !isServer condition does in this case? I've read all the comments, but still unclear to me!

 

The remoteExecutedOwner command is clear and I understand that we need to send back to the caller's machine the information collected, but I can't understand what's the logic behind your script! I'm sure this will be revealing to me :drinking2:

 

Thank you

 

Share this post


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

I would try using nearObjects instead. Maybe there's a difference?


_list = [_xpos,_ypos] nearObjects ["House", 200];

{

 _x allowDamage false;

} foreach _list;

 

Thank you gc8, but still no luck. I will replace a couple of buildings and force their attributes from the editor.

Share this post


Link to post
Share on other sites
16 hours ago, Lorenz94 said:

This is the part I can't understand. What the !isServer condition does in this case?

When TAG_fnc_getHCUnitCount remoteExec's TAG_fnc_count on the HC, !isServer will be true.

In which case it counts its local units and calls on the server the same function( TAG_fnc_count ).

TAG_fnc_count !isServer will then be false, so the else part will be executed. Where the HC_Clients index that is currently the HC client ID is updated to be an array of [ ownerID, units count ].

It then checks if all indexes of HC_Clients are an array( has received a count back from all HC;s ) and if so formats a message which is sent to the original count requestor( HCCountRequestor ).

 

Now this was meant as more of a example on how to remoteExec and pass around information, as you where trying to get a value back from remoteExecCall.

There should be no need to ask the HC how many units are local as the server is quite capable of doing this.

TAG_fnc_getHCUnitCount = {
	
	//If this function was called remotely then set requestor as RE-Owner
	//Otherwise set to all player clients
	_HCCountRequestor = [ allPlayers - entities "HeadlessClient_F", remoteExecutedOwner ] select isRemoteExecuted;
	
	//Get a array of all HC client owner IDs [ owner ID , array of units ]
	_HC_Clients = entities "HeadlessClient_F" apply{ [ _x, [] ] };
	
	//For all non player units
	{
		_x params[ "_unit" ];
		
		//For each HC
		{
			//If the owner of the unit is the same as the owner of the HC
			if ( owner _unit isEqualTo owner( _x select 0 ) ) exitWith {
				//Push unit into HC units array
				private _nul = ( _x select 1 ) pushBack _unit;
			};
		}forEach _HC_Clients;
	}forEach ( allUnits - allPlayers );
	
	//Format a message
	_message = "";
	{
		_x params[ "_HC", "_units" ];
		
		_message = format[ "%1\nHC id-%2: %3, NumUnits: %4", _message, owner _HC, vehicleVarName _HC, count _units ]; get
	}forEach _HC_Clients;
	
	//Remote exec hint to requestor
	_message remoteExec[ "hintSilent", _HCCountRequestor ];
};

//On server, will hint count to all players
[] call TAG_fnc_getHCUnitCount;

//From client, will hint back to this client
[] remoteExec[ "TAG_fnc_getHCUnitCount", 2 ];

TEST_MISSION - mission includes one player slot and two headless clients. The server will ask the HC's to spawn groups of five units up until there is a total count of fifty units.

The player has an addAction that will call the function( as above ) on the server, where it will count the units belonging to each HC and hint back to the player the unit counts for each HC.

Share this post


Link to post
Share on other sites

Really thank you @Larrow! I have waited to reply because I wanted to experiment a bit and come back with questions if needed, but I got something working with full understanding of the code.

 

You're always very kind!

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

×