Jump to content
realZNorQ

Fastest way to check if all members of a group are dead

Recommended Posts

I'm creating a few triggers that contains the following code

(count units group someNamedGroup) == 0

 

However it took for ever for the engine to register that the group was empty, so I changed it to

({alive _x} count units someNamedGroup) == 0

I suspect this may be an inefficient way to do it? What if there are tons for groups that I want checked...

Are there better ways?

 

Regards

Kenneth aka ZNorQ

Share this post


Link to post
Share on other sites

Sounds like a hassle to implement, or am I wrong? When I create random groups I want to check, how would I go about doing that?

 

I'm guessing you're refering to this;

this addEventHandler ["Killed", {
	params ["_unit", "_killer", "_instigator", "_useEffects"];
}];

 

Share this post


Link to post
Share on other sites

Maybe add this in the group init-box;

 { _x addEventHandler 
	[ "Killed", 
		{ params ["_unit", "_killer", "_instigator", "_useEffects"];
			// some code counting how many died...?
		}
	];

} forEach units someNamedGroup;

Share this post


Link to post
Share on other sites

But wouldn't that just check if the leader is dead, and not the whole group?

 

I'm trying out the following code ...

 

All groups I want to check if all units are dead have the following code in the group-init-box in 3DEN;

this setVariable ["checkAllDead", true];

The following code creates an eH for each unit in all groups that contain a variable "checkAllDead"=true

false spawn
 { systemChat "starting eh";
  { systemChat format["Testing group %1", _x];
   if  ( _x getVariable [ "checkAllDead", false ] )
   then { _x setVariable [ "Total", count units _x ];
      _x setVariable [ "Dead", 0];
      _x setVariable [ "allDead", false ];
      systemChat format["Setting variables for %1!", _x];
      { _x addEventHandler 
       [ "Killed", 
        { params ["_unit", "_killer", "_instigator", "_useEffects" ]; 
         private _unitsGroup = group _unit;
         _unitsGroup setVariable[ "Dead", ( _unitsGroup getVariable "dead" ) +1 ];
         if ( ( _unitsGroup getVariable "Total" ) == ( _unitsGroup getVariable "dead" ) )
         then {_x setVariable [ "allDead", true ];};
         systemChat format[ "%1 died, shot by %2 (%3, %4)", _unit, _killer, _instigator, _useEffects ];
        }
       ];
       systemChat format["Added eh to %1", _x ];
      } forEach units _x;
      
     };
  } forEach allGroups;
 };

 

What happens;

 

Every time a unit gets killed in the flagged group, it adds to a death-counter "Dead" for the group that the unit belongs to.

It then matches against "total" - how many in was part of the group initially. If the death-counter " and "total" is same, "allDead" is set to true.

 

I'm not a very good coder - and it's been YEARS since my last sqf-endeavor- so be gentle in the critique! :P

 

PS! I'm testing it out as I write this, so I'm not sure if it even works...

PS2! systemChats shall be removed, of course.

 

Kenneth aka ZNorQ.

Share this post


Link to post
Share on other sites

Hmmm, just thougth of something; instead of all those variables to track counts, I'm thinking I'd rather just count how many are alive in the group when-ever one unit is killed....

Share this post


Link to post
Share on other sites
2 hours ago, realZNorQ said:

But wouldn't that just check if the leader is dead, and not the whole group?

When leader dies a new leader is assigned, so if the leader is dead or null it probably means all group is dead

  • Like 1

Share this post


Link to post
Share on other sites

I see, but could it be that there is a small gap where new leader hasn't been assigned  in time and the trigger gives a wrong result?

Share this post


Link to post
Share on other sites
8 hours ago, realZNorQ said:

I see, but could it be that there is a small gap where new leader hasn't been assigned  in time and the trigger gives a wrong result?

Might be, not sure though, if a member of a group dies the group doesn't instantly reflect that, depending on line of sight etc, so a groups status will only update once in a while or if they witness a units death directly.

Can be  sped up using the "report status" radio command when in the same group.

Same could be the case for the group leader, if no one saw him die it might take a while until a new one will take command.

 

Would be more reliable to check via object array than using the group, like so:

_toCheck = units TAG_grp_someGroup;
{
	_x setVariable ["TAG_arr_toCheck",_toCheck];
	_x addEventhandler ["Killed",{
		params ["_killed"];
		_toCheck = _killed getVariable ["TAG_arr_toCheck",[]];
		if (count (_toCheck select {alive _x}) isEqualTo 0) then {
			hint "Everyone dead!";
		}
	}];
} forEach _toCheck;

 

Cheers

  • Thanks 1

Share this post


Link to post
Share on other sites
48 minutes ago, Grumpy Old Man said:

Might be, not sure though

Indeed just tested and it takes some time before the new leader is selected, so not really suitable

  • Like 1

Share this post


Link to post
Share on other sites

Here is the solution:
 

_tr = createTrigger ["EmptyDetector", [worldSize / 2, worldSize / 2], false]; 
_tr setTriggerArea [worldSize, worldSize, 0, true]; 
_tr triggerAttachVehicle [leader _group]; 
_tr setTriggerActivation ["MEMBER", "NOT PRESENT", false]; 
_tr setTriggerStatements ["this", "hint str 'AllDead'", ""];

You create a trigger that covers whole map, and assign it to the leader of the group. "MEMBER" checks for any alive member of the group in trigger area. When all dead, NOT PRESENT condition is true and trigger activates. Simples.  

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites

Just as reminder of findIf command. (you can use it also in EH as GOM did):

 

0 = [] spawn {while {true} do {
  uisleep 0.5;
  hintSilent str (allGroups select {units _x findIf {alive _x} == -1});
}};

Share this post


Link to post
Share on other sites
11 hours ago, killzone_kid said:

Here is the solution:
 


_tr = createTrigger ["EmptyDetector", [worldSize / 2, worldSize / 2], false]; 
_tr setTriggerArea [worldSize, worldSize, 0, true]; 
_tr triggerAttachVehicle [leader _group]; 
_tr setTriggerActivation ["MEMBER", "NOT PRESENT", false]; 
_tr setTriggerStatements ["this", "hint str 'AllDead'", ""];

You create a trigger that covers whole map, and assign it to the leader of the group. "MEMBER" checks for any alive member of the group in trigger area. When all dead, NOT PRESENT condition is true and trigger activates. Simples.  

 

Thanks killzone, I'll try this solution out - try to stress-test it :)

Share this post


Link to post
Share on other sites
12 hours ago, Grumpy Old Man said:

Might be, not sure though, if a member of a group dies the group doesn't instantly reflect that, depending on line of sight etc, so a groups status will only update once in a while or if they witness a units death directly.

Can be  sped up using the "report status" radio command when in the same group.

Same could be the case for the group leader, if no one saw him die it might take a while until a new one will take command.

 

Would be more reliable to check via object array than using the group, like so:


_toCheck = units TAG_grp_someGroup;
{
	_x setVariable ["TAG_arr_toCheck",_toCheck];
	_x addEventhandler ["Killed",{
		params ["_killed"];
		_toCheck = _killed getVariable ["TAG_arr_toCheck",[]];
		if (count (_toCheck select {alive _x}) isEqualTo 0) then {
			hint "Everyone dead!";
		}
	}];
} forEach _toCheck;

 

Cheers

 

Thank you for your suggestion, I will try this out too! 🙂

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

×