Jump to content
Sign in to follow this  
jshock

Deleting Entire Groups from a Particular Array

Recommended Posts

Hello Scripting Community,

I am trying to alter an array that counts all units of a side, but I have two separate groups that I want either excluded from that count, or later subtracted out of that "umbrella-ed" array that counts all units of the side.

This is what I have so far:

faction = (_this select 0);

thoseSideUnits = [];
_excludedindv = [indv1, indv2];
_grps = [grp1, grp2];

{

if (side _x == faction) then { thoseSideUnits set [count thoseSideUnits, _x];};

} foreach allunits;


_excludedgrps = ????

final = thoseSideUnits - _excludedindv - _excludedgrps;

Obviously the ???? is where I'm stuck, unless there is another way to accomplish this.

grp1 and grp2 are the respective group leaders of the units I would like to exclude.

Any help is greatly appreciated!

Edited by JShock

Share this post


Link to post
Share on other sites

why name them grp1 and grp2 if they're not actual groups but group leaders, same goes for the faction variable that's been compared to a side? This could be terribly misleading when trying to debug your own scripts (I've been there, heh)

you could filter for them in the if statement, like this:

if (side _x == faction AND !(_x in units group grp1) AND !(_x in units group grp2)) then {yourcode}

You're already checking all units, so you can just filter for them within the foreach loop.

I don't actually see why you want to filter them into the _excludedgrps variable, because it's basically the same as _grps if I understood right what you're trying to achieve.

Share this post


Link to post
Share on other sites

The only problem with your structure of it is if say (extreme example) I had 50 different groups that I wanted to exclude, at that point there is a lot of extra code. So that is the reason for filtering down into another variable, basically I want to take all the group leaders' variable names and be able to include them in the _grps arrays, take all units of that side and put them in the empty array thoseSideUnits, then be able to in just a line or two of code have the script run through every group leader that I have in the _grps array and add them and their grouped units into the _excludedgrps array so I can subtract them from the overall count of the side.

I hope that makes sense, because I want to do something with the rest of the units that I don't exclude from the "final" array.

Share this post


Link to post
Share on other sites

faction is actually a command so using it as a global variable like you have could cause you problems. Instead turn it into a local variable by placing an underscore in front of it.

Instead of checking each grp separately as GOM has shown there is a shortcut by using count. As you are currently using _x by foreaching around allUnits, the _x from the forEach willl need to be given it own variable name to save conflicting with the _x when inside the count code {}. Here i have stored it in a variable called _currentUnit

I have also changed your last line, there is no need to assign the final expression to a variable, as the last expression in a function without a ; will be return. Does not make any difference to script operation.

so....

_faction = (_this select 0);

_thoseSideUnits = [];
_excludedindv = [indv1, indv2];
_grps = [grp1, grp2];

{
_currentUnit = _x;
if (side _currentUnit == _faction && ({_currentUnit in (units group _x)}count _grps == 0) ) then {
	_thoseSideUnits set [count _thoseSideUnits, _currentUnit];
};
}forEach allunits;

_thoseSideUnits - _excludedindv

{_currentUnit in (units group _x)}count _grps == 0

For each index in _grps it will run the code {_currentUnit in (units group _x)}.

Where _x is the current index of _grps being checked.

If the currentUnit is in the units of the group of the current index a hidden counter will be increased.

We finally check that the counter is equal to 0. Meaning that currentUnit was not found.

I agree with GOM though that some of your naming conventions could do with changing to save confusion. Does not matter to the script operation but just to save you headaches when you come back to read this script in a month or so time.

_faction ~ _sideToCheck

_grps ~ _groupLeaders

for instance ?

Share this post


Link to post
Share on other sites

The globals were mainly for testing through the debug console. But for the last line you changed up, how would I be able to take that returned value and use it in another script because this is the unit setup script that goes into another script that does what I want to all of the non-excluded units?

Thanks for the adivce about naming conventions I have noticed myself being a little too "general" at times, sorry for any confusion it may have caused you. I'm still learning some of the ropes in the scripting world (as you can tell), so I thank you both for your time and experience that you both have shared thus far.

Share this post


Link to post
Share on other sites

As your _faction is a _this select 0 i presumed this is a function that you are calling e.g something like [west] call myFunction.

Spawn or execVM will not work here as they do not return anything from the called function, instead they give you a reference to the created thread in the scheduler.

so either...

You assign your code to a variable, maybe in init.sqf or some other script that will set this up before you need it

fnc_getUnitsBySide = {
_faction = (_this select 0);

_thoseSideUnits = [];
_excludedindv = [indv1, indv2];
_grps = [grp1, grp2];

{
    _currentUnit = _x;
    if (side _currentUnit == _faction && ({_currentUnit in (units group _x)}count _grps == 0) ) then {
        _thoseSideUnits set [count _thoseSideUnits, _currentUnit];
    };
}forEach allunits;

_thoseSideUnits - _excludedindv
};

and then you would call it like

myFilteredUnits = [west] call fnc_getUnitsBySide;

Here myFilteredUnits would hold the return list.

OR

If you have the code in a separate file e.g

getUnitsBySide.sqf

_faction = (_this select 0);

_thoseSideUnits = [];
_excludedindv = [indv1, indv2];
_grps = [grp1, grp2];

{
   _currentUnit = _x;
   if (side _currentUnit == _faction && ({_currentUnit in (units group _x)}count _grps == 0) ) then {
       _thoseSideUnits set [count _thoseSideUnits, _currentUnit];
   };
}forEach allunits;

_thoseSideUnits - _excludedindv

Then in your init.sqf compile this file into a function.

init.sqf

fnc_getUnitsBySide = compile preprocessFileLineNumbers "getUnitsBySide.sqf"

and call it the same as previously shown.

As you can see there are a few different ways to accomplish this all dependent on how you want it set up. This would be a good place to start reading about it. And This to show you a more advanced way of setting up your functions for A3.

Share this post


Link to post
Share on other sites

Works perfectly!

Thanks to both of you again, it was a great help to my endeavor :yay:.

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  

×