Jump to content
thy_

Scripting with Array + forEach + forEach into a forEach

Recommended Posts

I need some help: my code is stuck in my own (low) understanding around array and forEach when they need/should work together. 
Below, may you kindly point out the mistakes and show the fixes? I already read a lot of BIS wiki looking for how to code forEach inside forEach, even it doesn't look so clever, feeling... 

 

private _drivers 	= [driver01, driver02, driver03];
private _cars 		= [car01, car02, car03];


While {true} do 								
{	
  
	// DRIVERS
	{ 												// forEach _drivers start...
		if (alive _x) then 									// if the driver is alive, so...
		{							
			if ((_x distance _targetMarker) <= 30) then					// DONT KNOW BUT IM NOT SURE THIS IS RIGHT. ISN't IT?
			{	
				if (lifeState _x == "HEALTHY") then 					// if the driver is healthy, so...
				{
					_x directSay _sound1; 						// the driver screams.
					
					if (!isNull objectParent _x) then 				// if the driver is onboard a vehicle, so...
					{
						hint "driver has a veh"; 				// show text on screen.
					};
				};
			};
		};
	} forEach _drivers;										// repeat that for each driver.
	
  
  
  
  // CARS
	{												// forEach _cars start...
		if (alive _x) then  									// if the cars alive, then...
		{				
			if ((_targetMarker distance _x) <= 30) then 					// DONT KNOW BUT IM NOT SURE THIS IS RIGHT. ISN't IT?
			{
				<HERE EACH DRIVER> directSay _sound2;	 				// I DONT KNOW HOW TO CALL ANOTHER ARRAY+FOREACH HERE.
				sleep 0.3; 	
				_something createVehicle getPos _x; 					// DONT KNOW BUT IM NOT SURE THIS IS RIGHT. ISN't IT?
			};
			
			if ((damage _x) >= 0.1) then 							// if the car get damage, then...
			{
				hint "car got damage!"; 						// show the text on screen.
			}; 
		};
	} forEach _cars;										// repeat that for each car.
	
	sleep 1;											// a looping breath.
}; 													// while next looping.

Share this post


Link to post
Share on other sites
26 minutes ago, thy_ said:

<HERE EACH DRIVER> directSay _sound2;

 

 

Since you are iterating through the array of cars, and each car only has one driver, and you just want the driver of the current car at this point, you don't need another forEach loop.

driver _x directSay _sound2;

 

  • Like 2

Share this post


Link to post
Share on other sites

Hey, @Harzach good to see you. 

 

Lets put it like this:

private _cars	 	= [car01,car02,car03]; 							// array of cars.
private _drivers 	= [driver01,driver02,driver03]; 					// array of drivers.

While {true} do
{					 
	// code

  	_playerNearest = objNull;
	
	{ 																		
		// Below: _dist is the distance between playableUnits and CAR. How will the forEach understand that it must check _CARS array? 
		_dist = vehicle _x distance _x; 	
		
		if (isPlayer _x and _dist < _dangerouslyClose) then
		{
			_playerNearest = _x;												
			_dangerouslyClose = _dist;	
		};
	} forEach playableUnits;
  
  	// code...
};

 

_dist is the distance between playableUnits and car (of _cars array). How will the forEach playableUnits understand that it must check the _cars array? It looks like I should somehow to call another forEach. 

 

XD my initial steps through forEach and arrays along.

 

Share this post


Link to post
Share on other sites

I'm not entirely sure what the goal is but maybe this example will help you get more comfortable with nested forEach and the magic variable _x.

private _cars = [c1, c2, c3];
private _drivers = [d1, d2, d3];

{
	private _car = _x;
	{
		private _driver = _x;
		systemChat str [_car, _driver];
	} forEach _drivers;
} forEach _cars;

I find it helps readability if you assign _x to something meaningful.

  • Like 4
  • Thanks 1

Share this post


Link to post
Share on other sites
51 minutes ago, thy_ said:

Lets put it like this:

 

Well, that's an entirely different piece of code, brother! 🙂

 

@_foley's got you covered.

  • Like 1

Share this post


Link to post
Share on other sites

@_foley awesome example. It's help with ideas here.

@Harzach hehe true. Don't get me wrong. 😄

 

Ok, gang, this is how I am "reading" my piece of code. Exactly what I'd like:

 

{														
	_dist = <EACH PLAYABLE UNIT> distance <EACH CAR FROM ARRAY _CARS>;
		
	if (isPlayer <EACH PLAYABLE UNIT> and _dist < _dangerouslyClose) then
	{
		_playerNearest = <EACH PLAYABLE UNIT>;												
		_dangerouslyClose = _dist;	
	};
} forEach playableUnits;

 

There's any solution for my mess up?
If my code goal isn't clear yet. 

 

Share this post


Link to post
Share on other sites

Trying to follow on the steps of Harzach and _foley I suggest something like (feel free to adapt to your liking and needs)

{
  private _unit = _x; // Get the (each) unit first
  
  {
    private _car = _x; // Now get the car
    
    private _dist = _unit distance _car; // Calculate the distance
    
    if ((isPlayer _unit) && (_dist < _dangerClose)) then { // You have to make sure _dangerClose must be "visible"/known in this scope
      private _playerNearest = _unit; // Set nearest player
      private _dangerClose = _dist; // Set the closest distance
    };
  } forEach _carsArray;
} forEach playableUnits;

Don't really know how efficient this can be nor I have tried to find a better optimised version of it. I just did a "direct translation" of your pseudocode to this.

 

Hope this helps somehow. Just keep in mind that this snippet is not tested and should be treated with care.

  • Like 2
  • Thanks 1

Share this post


Link to post
Share on other sites
On ‎2‎/‎3‎/‎2022 at 5:08 PM, thy_ said:

	if ((_x distance _targetMarker) <= 30) then					// DONT KNOW BUT IM NOT SURE THIS IS RIGHT. ISN't IT?

 

 

Assuming _targetMarker is a marker, it should be:

if (_x distance (getMarkerPos _targetMarker) <= 30) then

 

17 hours ago, thy_ said:

Ok, gang, this is how I am "reading" my piece of code. Exactly what I'd like:


{
	_dist = <EACH PLAYABLE UNIT> distance <EACH CAR FROM ARRAY _CARS>;

	if (isPlayer <EACH PLAYABLE UNIT> and _dist < _dangerouslyClose) then 
	{
		_playerNearest = <EACH PLAYABLE UNIT>;
		_dangerouslyClose = _dist;
	};
} forEach playableUnits;

 

 

Is this the idea?  (expanding from what @ZaellixA has above)

Private ["_cars","_maxDist","_minDist","_nearest","_unit"];
_cars = [car01,car02,car03];
_nearest = objNull;
_maxDist = 100000;
_minDist = 30;

ScopeName "DangerClose";

{
	_unit = _x;

	if (isPlayer _unit && Alive _unit) then 
	{
		{
			if (_unit Distance _x < _maxDist) then 
			{
				_maxDist = _unit Distance _x;
				_nearest = _unit;

				if (_maxDist < _minDist) then {BreakTo "DangerClose";};
			};
		} forEach _cars;
	};
} forEach playableUnits;

// Something now happens.

 

  • Like 2
  • Thanks 1

Share this post


Link to post
Share on other sites

Thank you @ZaellixA and @opusfmspol, let me try with your ideas and I come back with my results in a few hours. 😉

  • Like 1

Share this post


Link to post
Share on other sites

Oh, the final script (and solution for this topic) is here. Topic solved. 😉

 

  • Like 1

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

×