Jump to content

Recommended Posts

I keep getting a "zero divisor" error when trying to select from an array after using the find command.

 

The basic situation is; 16 people each with their own individual waypoints.

When the units reach the waypoint, the following is executed:

 

 

For units in group 1:

nul = [this,1] execVM 'law\setRotation.sqf';

For units in group 2:

nul = [this,2] execVM 'law\setRotation.sqf';

 

 

 

setRotation.sqf contains the following:



params [["_subject", objNull],["_typeCode", 0]];


if (_typeCode == 0) then 
						{
								//Insert Code to generate error report here
						};


if (_typeCode == 1) then 
						{
								_unitsAlpha = 
												[
													pak_mainyu1_2,
													pak_mainyu1_3,
													pak_mainyu1_4,
													pak_mainyu1_5,
													pak_mainyu1_6,
													pak_mainyu1_7,
													pak_mainyu1_1,
													pak_mainyu1_8
												];

												
								_positionInQueue = _unitsAlpha find _subject;
								

								_bearingsBriefing_alpha = 
															[
																271.587,
																250.801,
																225.084,
																202.869,
																172.511,
																147.108,
																26.615,
																20.786
															];								
								

								_bearingFrom = _bearingsBriefing_alpha select _positionInQueue;
								_startPos = getPosAtl _subject;
								_watchTarget = [_startPos,3,_bearingFrom] call BIS_fnc_relPos;
								
								_watchTarget set [2,1.8];
								
								_subject doWatch _watchTarget;
								
						};
						
						
if (_typeCode == 2) then 
						{
								_unitsBravo = 
												[
													pak_mainyu2_2,
													pak_mainyu2_3,
													pak_mainyu2_4,
													pak_mainyu2_5,
													pak_mainyu2_6,
													pak_mainyu2_7,
													pak_mainyu2_1,
													pak_mainyu2_8
												];

								_positionInQueue = _unitsBravo find _subject;
								

								_bearingsBriefing_bravo =
															[
																271.587,
																250.801,
																225.084,
																202.869,
																172.511,
																147.108,
																26.615,
																20.786
															];								
								
		
								_bearingFrom = _bearingsBriefing_bravo select _positionInQueue;
								_startPos = getPosAtl _subject;
								_watchTarget = [_startPos,3,_bearingFrom] call BIS_fnc_relPos;
								
								_watchTarget set [2,1.8];
								
								_subject doWatch _watchTarget;
								
						};
						

 

 

What i can't figure out is why it's trying to select a value that's out of range.

There are 8 units in each group, a matching set of 8 names in the _unitsX arrays, and 8 entries within the bearing array.

 

Should be a simple case of 

1 - obtain unit name from waypoint completion

2 - find name within array

3 - select corresponding bearing from the bearing array

 

 

 

I ran a separate test to go through the same process 1 by 1 which passed without error, so I'm guessing it's to do with some of these waypoints 

being completed at the same time:

 

 


_testGroup = 
				[
													pak_mainyu2_1,
													pak_mainyu2_2,
													pak_mainyu2_3,
													pak_mainyu2_4,
													pak_mainyu2_5,
													pak_mainyu2_6,
													pak_mainyu2_7,
													pak_mainyu2_8
				];



{
	
																																		player sideChat (format ["Subject: %1",_x]);
								_subject = _x;
								_unitsBravo = 
												[
													pak_mainyu2_2,
													pak_mainyu2_3,
													pak_mainyu2_4,
													pak_mainyu2_5,
													pak_mainyu2_6,
													pak_mainyu2_7,
													pak_mainyu2_1,
													pak_mainyu2_8
												];

												
								_positionInQueue = _unitsBravo find _subject;
								
																																		player sideChat (format ["PosInQ: %1",_positionInQueue]);

								_bearingsBriefing_bravo =
															[
																271.587,
																250.801,
																225.084,
																202.869,
																172.511,
																147.108,
																26.615,
																20.786
															];							
								
								//player sideChat (format ["Subject: %1, Position: %2",_subject,_positionInQueue]);	
								_bearingFrom = _bearingsBriefing_bravo select _positionInQueue;
																																		player sideChat (format ["BearingFrom: %1",_bearingFrom]);
								_startPos = getPosAtl _subject;
								_watchTarget = [_startPos,3,_bearingFrom] call BIS_fnc_relPos;
								
								_watchTarget set [2,1.8];
								
								_subject doWatch _watchTarget;
								
								sleep 3;
} forEach _testGroup;

 

 

 

Maybe there's something to do with using local variable handles that I'm not understanding here.

 

 

 

 

Thanks,

Law

Share this post


Link to post
Share on other sites

Zero divisor error when using select usually means you're trying to select a non existant array element. IE, selecting element 4 in a 2 element array.

Share this post


Link to post
Share on other sites

Find will return -1 if element was not found.

Select -1 will throw an error.

Use some more debugging functions and check if find returns -1.

Your _positionInQueue looks like a candidate for this.

 

Cheers

Share this post


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

I ran a separate test to go through the same process 1 by 1 which passed without error:

 



_testGroup = 
				[
													pak_mainyu2_1,
													pak_mainyu2_2,
													pak_mainyu2_3,
													pak_mainyu2_4,
													pak_mainyu2_5,
													pak_mainyu2_6,
													pak_mainyu2_7,
													pak_mainyu2_8
				];



{
	
																																		player sideChat (format ["Subject: %1",_x]);
								_subject = _x;
								_unitsBravo = 
												[
													pak_mainyu2_2,
													pak_mainyu2_3,
													pak_mainyu2_4,
													pak_mainyu2_5,
													pak_mainyu2_6,
													pak_mainyu2_7,
													pak_mainyu2_1,
													pak_mainyu2_8
												];

												
								_positionInQueue = _unitsBravo find _subject;
								
																																		player sideChat (format ["PosInQ: %1",_positionInQueue]);

								_bearingsBriefing_bravo =
															[
																271.587,
																250.801,
																225.084,
																202.869,
																172.511,
																147.108,
																26.615,
																20.786
															];							
								
								//player sideChat (format ["Subject: %1, Position: %2",_subject,_positionInQueue]);	
								_bearingFrom = _bearingsBriefing_bravo select _positionInQueue;
																																		player sideChat (format ["BearingFrom: %1",_bearingFrom]);
								_startPos = getPosAtl _subject;
								_watchTarget = [_startPos,3,_bearingFrom] call BIS_fnc_relPos;
								
								_watchTarget set [2,1.8];
								
								_subject doWatch _watchTarget;
								
								sleep 3;
} forEach _testGroup;

 

 

 

I ran a debug test where each name was selected one by one and run through the same process.

Got through it without errors.

 

 

I'll do some more checking later though, might have missed something

 

Thanks

Share this post


Link to post
Share on other sites

You don't need sqf such result!. <This> applies to the specific unit in editor .You don't need to "find" it again. Did you lost the variable during the path???

In other words, this and 1 or 2 are already known global variables. So why do you pass them as parameters, if you can write something more straight???

 

Share this post


Link to post
Share on other sites
On 01/12/2017 at 4:24 PM, pierremgi said:

You don't need sqf such result!. <This> applies to the specific unit in editor .You don't need to "find" it again. Did you lost the variable during the path???

In other words, this and 1 or 2 are already known global variables. So why do you pass them as parameters, if you can write something more straight???

 

 

I can understand why you're saying that but, unless you can see a better way, this is my reasoning:

 

I want to pass on a variable to a waypoint script (_bearing) for each of 16 examples.

I can either write 16 blocks of script, each containing a unique value for bearing.

But I chose to write a forEach command so I can edit the script for 1, and change all of them.

 

The only downside is that I can't then pass on a unique value for each waypoint, short of creating a global variable for each waypoint.

 

So instead we'll find a way of relating the information processed on completion of the waypoint (contained in this) to the array of bearings.

In this instance, this contains the unit name completing the variable.

 

So all I need to do is structure an array of unit names such that the position of the unit in the _unitsWhatever array corresponds to the position of the desired bearing in the _bearingsWhatever.

Then by finding the position of the unit completing the variable, we can select the same position in the other array to get the correct bearing.

 

Now all i have to do is write to arrays into the waypoint script and use find/select as detailed above.

 

 

Hope that makes sense!

Do let me know if you see a better way.

 

-Law

Share this post


Link to post
Share on other sites

Fix found.

 

The find/select functions were working fine, the problem was a small section I'd included elsewhere but forgotten about:

 

	if (_x == pak_mainyu1_1) then 
									{
										_wayPoint_alpha_briefing setWaypointStatements 
																		["true",
																				"
																					nul = [this,2] execVM 'law\setRotation.sqf';
																					readyForBrief_alpha = true;
																				"
																		];										
									};

 

This was intended to add an additional parameter to the leader of the group.

Unfortunately in copying this from Bravo to Alpha squads I forgot to change the passed variable _typeCode from 2 to 1.

 

This meant that the leader of the group (pak_mainyu2_1) was being searched for in the array _unitsBravo.

 

 

I'm not surprised nobody spotted that...since I left that part out when I posted and forgot about it completely :/

Thanks for your help though

 

-Law

Share this post


Link to post
Share on other sites

You units can have global names : u1, u2, u3...

These units belong to their group you can name also group1, group2. You don't need any extra variable 1 or 2 for that.

If you want a single sqf, I understand, just add :

this excVM setRotation.sqf

then in this sqf:

 

params ["_unit"];

 

switch (_unit) do {

  case u1: { _unit .... };

  case u2 : ......

};

and even:

switch {group _unit) do {

 case group1 : { _unit ....};

 case group2 : { _unit ....};

};

 

There is no need to find something in arrays.

 

You can also write the code below (and I prefer it):

params ["_unit"];

 call {

  if (_unit == u1) exitWith { something};

  if (_unit == u2) exitWith { something else};

};

 

This way, you're saving process because your code just run until the met condition (ignoring furthers),  not to the end of the bunch of "if then" tests.

 

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

×