Jump to content
Sign in to follow this  
Tom212

Issue with playableUnits array.

Recommended Posts

Hi,

 

I'm making a mission that selects a player from an array filled with the elements taken from the playableUnits command/array.

 

With the help of a friend to act as an extra client and hints placed throughout the code I have isolated the problem.

 

 

 

 

The mission selects a element from the array which is a playableUnit, it then continues to run this on it:

[[], "spyMenu", _newSpy] call BIS_fnc_MP;

In this case _newSpy is the element selected. If this element happens to be myself, the host the function is called successfully, however if it happens to be a client that's connect it fails.

 

Inspecting the playableUnits array vs. the returned strings from 'player' on the clients, I noticed the strings are different.

 

Whereas a player has: '#:#:# Alpha (player name)'

Elements from playableUnits has: '#:#:# Alpha (player name) REMOTE'

 

I'm suspecting this is the problem, but I thought that since the stored elements are in fact objects they should refer to the same entity.

 

Would solving this issue be as easy as formating the playableUnit's element to remove the ' REMOTE'?

 

Or is there something deeper here I'm lacking with regards to how objects actually work?

Share this post


Link to post
Share on other sites

I know the problem it's to do with the returns of playableUnits as explained above.

 

It's difficult to show because it's all in functions but here's the one where playableUnits is used. Ignore the hints and sleep's they were just for troubleshooting.

selectSpy =
{	
	possibleSpies = [];
	{
		
		if ((side _x) isEqualTo resistance) then 
		{
			possibleSpies = possibleSpies + [_x];
			hint format ["Adding %1 to possible spies.", _x];
			sleep 2;
		};
		
	
	} forEach playableUnits;
	
	hint 'removing spies from possibleSpies';
	possibleSpies = possibleSpies - spies;
	sleep 2;
	
	if !(possibleSpies isEqualTo []) then 
	{
		hint format ['possibleSpies is not empty, selecting spy from %1', possibleSpies];
		sleep 4;
		_spy = selectRandom possibleSpies;
		hint format ["%1 selected as spy.", _spy];
		sleep 2;
		_spy;
		
		
	} else 
	{
		hint 'No possible spies found';
		sleep 2;
		_spy = objNull;
		_spy;
	};

_spy is later assigned to _newSpy which is where the code in the last post is supposed to be run local.

[[], "spyMenu", _newSpy] call BIS_fnc_MP;

To make what I've said in the last post short and sweet,

 

Function "spyMenu" is run successfully when _newSpy is the server host, if _newSpy is a client it isn't run locally at all on that client.

 

playableUnits is adding " REMOTE" to clients who are not the server.

Share this post


Link to post
Share on other sites

i ll post here what comes in my mind with ur code in order as it came with or without relation to ur problem. i will edit this post every time i ve a new suggestion.

possibleSpies = possibleSpies + [_x];

replace that with this cause its alot faster:

possibleSpies pushBack _x;

I did not understood where the specified problem occurs but the solution should be to find a string in a string like that:

if ((_element_of_all_units find _player_Str) < 0) then
{
 hint "player string is NOT inside of playable units";
}
else
{
 hint "player string is inside of playable units";
};

Share this post


Link to post
Share on other sites

Thanks that's a useful command to know, I look forward to any solutions.

Share this post


Link to post
Share on other sites

 

i ll post here what comes in my mind with ur code in order as it came with or without relation to ur problem. i will edit this post every time i ve a new suggestion.

possibleSpies = possibleSpies + [_x];

replace that with this cause its alot faster:

possibleSpies pushBack _x;

I did not understood where the specified problem occurs but the solution should be to find a string in a string like that:

if ((_element_of_all_units find _player_Str) < 0) then
{
 hint "player string is NOT inside of playable units";
}
else
{
 hint "player string is inside of playable units";
};

 

The issue is that playableUnit's is returning a different object name for objects that aren't the server.

 

Where a player object name would normally be: "unitname (profile name)"

It instead returns: "unitname (profile name) REMOTE".

 

This happens for any 'player' who isn't the server host. This means when I put the returned object into a target parameter, it isn't called on the intended object because that object has a different name.

 

I'm not sure if this should cause a conflict, do object names actually matter or do they just represent unseen data that never changes?

Share this post


Link to post
Share on other sites

Rather than try to get that previous method to work I tried to make another fix, I'm pretty confident it will work but haven't fully tested it yet. I'm just requesting all players on the side I target send their 'player' object to the server which then adds it into possibleSpies.

possibleSpies = [];
[[], "getPossibleSpies", resistance] call bis_fnc_MP;


getPossibleSpies = 
{

	[player, "savePossibleSpy", false] call bis_fnc_MP;

};

savePossibleSpy =
{
	_player = _this;
	
	possibleSpies pushBack _player;
};

Share this post


Link to post
Share on other sites

post that line where u get that different return values please. i m pretty sure it can be fixed with find

Share this post


Link to post
Share on other sites


{

if((player find _x) > -1) then

{

// ur code which handles the player

}

} forEach playableUnits;

Share this post


Link to post
Share on other sites

Ignore the "REMOTE" thing. It shouldn't be an issue.

 

 

 

From the looks of it however, you should probably just use "allPlayers" instead of that funky construct of BIS_fnc_MP calls.

Also I'm not sure if its even wise to save "possibleSpies" instead of simply repeating the check when you need it. Otherwise it won't include people that join later.

 

 

Care to share what exactly you're trying to do there? Parts of it are still pretty vague, so its hard to propose alternative solutions..

Share this post


Link to post
Share on other sites

I was wrong I didn't fix my problem. @Tajin sorry, as you can see now I've linked the entire script possibleSpies is updated over the course of it's use. It's a mess as it's currently a WIP but here is the entire script.

 

The purpose of the script is to pick a random player from the resistance side then send them a dialog 'createDialog "SPY_SELECTED_DIALOG";' If they click a button labled 'Accept' on the dialog they receive this code: [[player, profileName], 'newSpy', false] call BIS_fnc_MP; closedialog 0;

 

Which finishes it off.

 

The current problem is that the function spyMenu never runs on clients, it runs fine when I'm selected and hosting however. But it never shows a dialog for other players.

spies = [];
possibleSpies = [];
civilians = ["C_man_1","C_man_1_1_F","C_man_1_2_F","C_man_1_3_F","C_man_hunter_1_F","C_man_p_beggar_F","C_man_p_beggar_F_afro","C_man_p_fugitive_F","C_man_p_shorts_1_F","C_man_polo_1_F","C_man_polo_2_F","C_man_polo_3_F","C_man_polo_4_F","C_man_polo_5_F","C_man_polo_6_F","C_man_shorts_1_F","C_man_shorts_2_F","C_man_shorts_3_F","C_man_shorts_4_F","C_man_w_worker_F"];	
faces = ["GreekHead_A3_01", "GreekHead_A3_02", "GreekHead_A3_03", "GreekHead_A3_04", "GreekHead_A3_05", "GreekHead_A3_06", "GreekHead_A3_07", "GreekHead_A3_08", "GreekHead_A3_09"];

addSpy = 
{	
	_playerName = _this select 0;
	_player = _this select 1;
	_spy = _this select 2;
	
	spies = spies + [_playerName, _player, _spy];
};

removeSpy = 
{
	private ["_location", "_wasSpy"];
	_playerName = _this;
	_wasSpy = false;
	//hint format ["%1", _playerName];
	{

	if (_playerName isEqualType _x) then { 
	
		if (_playerName == _x) then  /////////// REMOVE SPY is called but this if isn't working. Test upper if.
		{
			_location = _forEachIndex;
			_wasSpy = true;
			hint "spy to be removed found!";
	};
		
	};
	
	}forEach spies;
	
	if (wasSpy) then 
	{
	_playerName = spies select _location;
	_oldUnit = spies select (_location + 1);
	_spy = spies select (_location + 2);
	
	spies = spies - [_playerName, _oldUnit, _spy];
	};
	
};

getPossibleSpies = 
{

	[player, "savePossibleSpy", false] call bis_fnc_MP;

};

savePossibleSpy =
{
	_player = _this;
	
	possibleSpies pushBack _player;
};

selectSpy =
{	
	possibleSpies = [];
	[[], "getPossibleSpies", resistance] call bis_fnc_MP;
	sleep 2;
	
	if !(possibleSpies isEqualTo []) then 
	{
		hint format ['possibleSpies is not empty, selecting spy from %1', possibleSpies];
		sleep 4;
		_spy = selectRandom possibleSpies;
		hint format ["%1 selected as spy.", _spy];
		sleep 2;
		_spy;
		
		
	} else 
	{
		hint 'No possible spies found';
		sleep 2;
		_spy = objNull;
		_spy;
	};
};


newSpy = 
{
	_player = _this select 0;
	_playerName = _this select 1;
	
	_civilian = selectRandom civilians;
	_face = selectRandom faces;
	_group = createGroup civilian;
	_civilian createUnit [getMarkerPos "spy_hq_marker", _group, "newUnit = this;"]; //Maybe format a spyName each time for unique names.
	[newUnit, "selectPlayer", _player] call BIS_fnc_MP; 
	
	_player setpos (getMarkerPos "limbo_marker");
	_newSpy = newUnit;
	
	[[_newSpy, _face], "setFace", true, true] call BIS_fnc_MP; 
	
	[_playerName, _player, _newSpy] call addSpy;
	
	_message = format ["%1 has been compromised and is now operating for MI6!", _playerName];
	//[_message, "hint", true] call BIS_fnc_MP;
	
	_newSpy addMPEventHandler ["MPRespawn", {_respawnedUnit = _this select 0; _corpse = _this select 1; [[profileName, _respawnedUnit, _corpse], "deadSpy", false] call BIS_fnc_MP;}];
	
	//["insertion", "selectLocation", _newSpy] call BIS_fnc_MP;
	
	[[], "spyMissionsUpdate", _newSpy] call BIS_fnc_MP; 
	
	[[], "giveGun", _newSpy] call BIS_fnc_MP;
	
};

spyMissionsUpdate = 
{
	[player, "updateObjectives", false] call BIS_fnc_MP;
};

spyMenu = 

{

createDialog "SPY_SELECTED_DIALOG";
_time = 9;
_count = 10;
hint "You should see a dialog now, if you don't tell Tom you saw this hint but no dialog.";
sleep 5;


while {dialog isEqualTo true && _count > 0} do 
{
	sleep 1;
	ctrlSetText [1001, (str _time)];
	_time = _time - 1;
	_count = _count - 1;
};

closeDialog 212;

};

deadSpy = 

{
private ["_location"];
_playerName = _this select 0;
_respawnedSpy = _this select 1;
_corpse = _this select 2;
_wasSpy = false;

{

	if (_playerName isEqualType _x) then {
	
		if (_playerName == _x) then 
		{
			_location = _forEachIndex;
			_wasSpy = true;
		};
		
	};
	
}forEach spies;

if (_wasSpy) then 
{

_playerName = spies select _location;
_oldUnit = spies select (_location + 1);
_spy = spies select (_location + 2);

spies = spies - [_playerName, _oldUnit, _spy];

hint format ["%1", _corpse];

[_oldUnit, "selectPlayer", _respawnedSpy] call BIS_fnc_MP; 
[_oldUnit, "findStartLocation", _oldUnit] call BIS_fnc_MP;
[_corpse, "removeHolster", _oldUnit] call BIS_fnc_MP; 
 
//_message = format ["%1 was eliminated and is no longer working for MI6.", _playerName];
//[_message, "hint", true] call BIS_fnc_MP;

sleep 1;

deleteVehicle _respawnedSpy;

};


};

while {gameInProgress isEqualTo true} do 
{
	sleep selectSpyIntervalTime;

	if ((count spies) < maximumSpies) then 
	{
		_newSpy = call selectSpy;
		
		if !(isNull _newSpy) then 
		{
			sleep 2;
			hint 'creating dialog on spy';
			sleep 2;
			[[], "spyMenu", _newSpy] call BIS_fnc_MP;
			//["SPY_SELECTED_DIALOG", "createDialog", _newSpy] call BIS_fnc_MP;
		};
		
	};

};

Share this post


Link to post
Share on other sites

I think the main problem I'm having here rests on the fact that perhaps I misunderstand how variables of the object type are stored and handled.

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  

×