Jump to content
wiggum2

isNull problem , check if unit exists and update array

Recommended Posts

Hi !

I have a array with the names of four units:

_units = [e1,e2,e3,e4];

e2 has probability of presence = 0%

Now inside a script i want to update the array by checking if the units exist and are alive.

for "_i" from 0 to (count _units - 1) do
{
   _unit = (_units select _i);
   if (isNull _unit) then {
       _units = _units - [_unit];
   } else { 
       if (not alive _unit) then {
           _units = _units - [_unit];
       };
   };
};
hint format ["%1",_units];

The hint returns [e1,any,e2,e3,e4] and i get this error:

Undefined variable in expression _unit

No i think i select a obj from the array, then check if the obj exists and if yes i also check if it is alive.

If it does not exist (isNull) then i update the array, same if it exists but is not alive...

What is wrong with this ?

Share this post


Link to post
Share on other sites

If the unit a variable is referencing to doesn't exist in the first place, the variable will be nil and any command other than isNil "variable" will return an error.

What I'd do:

_units=[];
{
if (!isNil _x) then {
	_units call compile format ["if (alive %1) then {_this set [count _this,%1]}",_x];
}
} forEach ["e1","e2","e3","e4"];

This will add only existing and live units into the array.

Edited by Celery

Share this post


Link to post
Share on other sites

_units = [e1,e2,e3,e4];
{
if (isNil "_x") then {
	_units set [_forEachIndex, -1]
} else {
	if (!alive _x) then {
		_units set [_forEachIndex, -1]
	}
}
} forEach _units;
_units = _units - [-1];
hint format ["%1",_units];

@Celery, there is no need for call compile format if you are using string names. missionNamespace getVariable "e1" etc. does the job too (and faster).

@Wiggum

Removing elements from an array when using for with a count array evaluation is not the best idea because count array is evaluated only once contrary to the old C-style for. Means changing the array size during the iteration may cause problems.

alive nullObject returns false too.

(wrong forums section ?)

Xeno

Edited by Xeno

Share this post


Link to post
Share on other sites

EDIT:

Xenos example works too, thank you guys !

@Wiggum

Removing elements from an array when using for with a count array evaluation is not the best idea because count array is evaluated only once contrary to the old C-style for. Means changing the array size during the iteration may cause problems.

alive nullObject returns false too.

Xeno

Mhh, i used this quiet often now and never had problems (script errors or something) and dont know "old C-style". Can you explain this a bit more please ?

(wrong forums section ?) yeah, sorry.

Edited by Wiggum

Share this post


Link to post
Share on other sites

I apologize for necromancing this thread, but as far as I can tell this is relavent.

What I want is a system to pick a random unit from a3-a8 as a spy, then tell that player they are the spy. As you can imagine the problem occurs when not all of the slots are filled and a phantom player is assigned as the spy. My attempt was to subtract all of the players that entered the game (in trigger trig1, located over the starting position) from the list of all available slots, which would return all of the slots that did not exist, I would then subtract that from the first array.

spy.sqf

_array1 = [a3,a4,a5,a6,a7,a8] 
_array2 = list trig1
_array3 = _array1 - _array2
_array4 = _array1 - _array3
spy = _array4 call BIS_fnc_selectRandom;
publicVariable "spy";


//spy = [a3,a4,a5,a6,a7,a8] call BIS_fnc_selectRandom;
// first attempt, does not account for missing players

hint format["%1 is the spy",spy]



sleep 5;
If (name player == spy){
hint format["You are the spy, %1", spy]; };
// notifying spy of his profession 

1) Is this a valid approach to my problem, or should I try what was covered in this thread? (what I see seems to be well beyond my scripting abilities)

2) Did I use publicvariable correctly? will the same person be assigned as the spy in a mp match? (spy.sqf is called from the init)

3) For the hints is there a way to list the player's profile name, rather than the unit's name? This would be for a hint at the end of the game, i imagine it would look something like

hint format["%1 was the spy",spy select 2]

although i don't know the syntax.

Thanks!

Share this post


Link to post
Share on other sites

If i understand correctly, you have an array of playable units, and you need to remove those that are not actual players, but filled by AI?

Then i would do this:

_playable_units = [p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12];
_i = (count _playable_units) - 1;
while {_i > -1} do {
   _unit = _playable_units select _i;
   if (not isPlayer _unit) then {_playable_units = _playable_units - [_unit]};
   _i = _i - 1
};
// here the _playable_units array should contain only those units being filled by human players

Share this post


Link to post
Share on other sites
If i understand correctly, you have an array of playable units, and you need to remove those that are not actual players, but filled by AI?

Then i would do this:

This is how i integrated your script, however I must be missing something as no hints appear. Should the variable spy be _spy? I'm not quite sure if the underscore for a variable has a function or is just a habit among scripting folk. Also my intent is to only call this script once with the init, does the while condition mean it will be constantly updated? Ideally i'd only need it to detect which of the eight units exist (AI would be disabled) and pick one at random. I appreciate the quick response though and will keep trying to sort this out.

spy.sqf

_playable_units = [a1,a2,a3,a4,a5,a6,a7,a8];
_i = (count _playable_units) - 1;
while {_i > -1} do {
   _unit = _playable_units select _i;
   if (not isPlayer _unit) then {_playable_units = _playable_units - [_unit]};
   _i = _i - 1
};
// here the _playable_units array should contain only those units being filled by human players

_playable_units call BIS_fnc_selectRandom = spy;
publicVariable "spy";

hint format["%1 is the spy", spy]

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

×