Jump to content
Sign in to follow this  
Rydygier

Strange observation during testing of BIS_fnc_SpawnGroup function

Recommended Posts

Lately I'm hunting some well hidden issue, that makes one of my scripts stuck. Checked many functions, amongst them SpawnGroup by BIS.

In this function we have such part:

private ["_newGrp"];
_newGrp = createGroup _side;
while {count units _grp > 0} do {
private ["_maxRank","_unit"];
_maxRank = -1;
_unit = objnull;
{
	_rank = rankid _x;
	if (_rank > _maxRank || (_rank == _maxRank && (group effectivecommander vehicle _unit == _newGrp) && effectivecommander vehicle _x == _x)) then {_maxRank = _rank; _unit = _x;};
} foreach units _grp;
[_unit] joinsilent _newGrp;
};

I pasted and renamed whole fuction, edited above part of it this way:

private ["_newGrp"];
_newGrp = createGroup _side;
_ct = 0;//_ct and _am added to private array at the beginning of the function
_am = count (units _grp);//_grp is some existing group
while {count units _grp > 0} do 
{
private ["_maxRank","_unit"];
_maxRank = -1;
_unit = objnull;

	{
	_rank = rankid _x;
	if (_rank > _maxRank) then {_maxRank = _rank; _unit = _x;};
	} 
foreach units _grp;

[_unit] joinsilent _newGrp;
_ct = _ct + 1;
if (_ct > (_am + 1)) exitWith {diag_log "--strange2"}
};

then used modified function to spawn many groups under loading screen. And once I found in RPT this log: "--strange2"

Question: in what possible circumstance such log may pass into RPT? Perhaps I'm missing something simple, but for me it looks like something, that shouldn't happen at all - while loop should end two cycles ago.

Not sure, but perhaps one possibility: when group count limit is reached new group is never created or joining it is futile? Is this limit same, as was in Arma2, means 144 per side? Seems yes, and seems it is the case...

Edited by Rydygier

Share this post


Link to post
Share on other sites

Or maybe (count units group) does not work properly. I've also experienced strange behaviour but in a totally different context. I have a track script which creates a marker to follow a group leader. If default parameters are used, the marker text will be updated with the unit count every few seconds. Once every member of the group in question has been killed, the marker will turn black and the marker text will be set to empty instead of the unit count. While the position seems to be updated correctly, the group count is often stuck for several cycles. Markers of completely eradicated groups are sometimes being updated for minutes until they finally turn black and the script ends. Well, there might be some mistake in my code but that's what I observed. Also when I used group counts in conditions I had issues most of the time. Just a wild guess though.

Anyway, here's the script for reference:

/*
Name: track
Author: IndeedPete
Purpose: Creates map marker that follows group leader. If leader dies, marker follows new group leader.
----------
Parameters:
_unit - OBJECT: Unit to apply function on. - player
_delay - NUMBER (OPTIONAL): Interval in which marker position should be updated - 0 - DEFAULT: 5
_shape - STRING (OPTIONAL): Marker shape. - "ICON" - DEFAULT: "ICON"
_type - STRING (OPTIONAL): Marker type. - "mil_dot" - DEFAULT: "mil_dot"
_color - STRING (OPTIONAL): Marker colour. - "ColorBlack" - DEFAULT: [(side _unit), true] call BIS_fnc_sideColor
_text - STRING/BOOLEAN (OPTIONAL): Marker text. If boolean, function will show and update count of units in group instead. - "Delta-45" - DEFAULT: false
_del - BOOLEAN (OPTIONAL): Delete marker if group is killed. "False" just sets marker colour black when group is killed. - true - DEFAULT: false
_cond - CODE (OPTIONAL): If condition is satisfied, track script will be executed. - {alive player} - DEFAULT: {IP_TESTMODE}
----------
Global Variables: IP_TESTMODE - Needs to be set to true or false.
*/

_unit = [_this, 0, objNull, [objNull]] call BIS_fnc_param;
_delay = [_this, 1, 5, [0]] call BIS_fnc_param;
_shape = [_this, 2, "ICON", [""]] call BIS_fnc_param;
_type = [_this, 3, "mil_dot", [""]] call BIS_fnc_param;
_color = [_this, 4, ([(side _unit), true] call BIS_fnc_sideColor), [""]] call BIS_fnc_param;
_text = [_this, 5, false, ["", true]] call BIS_fnc_param;
_del = [_this, 6, false, [true]] call BIS_fnc_param;
_cond = [_this, 7, {IP_TESTMODE}, [{}]] call BIS_fnc_param;
_isBol = (typeName _text == "BOOL");

if (call _cond) then {
_marker = createMarker[str _unit, getPos _unit];
_marker setMarkerShape _shape;
_marker setMarkerType _type;
_marker setMarkerColor _color;
if (!_isBol) then {_marker setMarkerText _text};

_grp = group _unit;
while {(count units _grp) > 0} do {
	_leader = leader _grp;
	while {alive _leader} do {
		_marker setMarkerPos getPos _leader;
		sleep _delay;
		if (_isBol) then {_marker setMarkerText format ["%1", (count units _grp)]};
	};
};

if (_del) then {
	deleteMarker _marker;
} else {
	_marker setMarkerColor "ColorBlack";
	if (_isBol) then {_marker setMarkerText ""};
};
};

Share this post


Link to post
Share on other sites

Maybe it would pan out better to make one pass to get the highest rank and join the new group via a foreach, then join the rest to the new group via another foreach without checking for ranks on the second pass. Is it possible that the count of the group units is being altered slower than the loop because joinSilent is a global funtion? In other words joining a unit from one group to another requires time for the count to change on the next check?

[_unit] joinsilent _newGrp;
sleep 0.25; //wait a long time for testing
_ct = _ct + 1;

Edited by Jacmac

Share this post


Link to post
Share on other sites

I've also noticed that using 'units someGrp' in the debug console after the units are dead will still show the units in the list. (It doesn't look like it updates properly)

also, calling [someGrp] call BIS_fnc_GC doesn't delete a group, even if it is empty (not sure if you are doing any sort of GC'ing) - it will clean up objects and units fine, but not on groups.

Share this post


Link to post
Share on other sites

I think I read somewhere that units group returns the group members that the group thinks are alive, and is updated in the regular AI reporting method you'll see in-game. Haven't confirmed it, though, I've always used an alive check even with group arrays.

Edit: Kronzky has something about it in the entry for units (2009), but it doesn't sound like the above.

Edited by Magirot

Share this post


Link to post
Share on other sites

For now I'm trying with:

{alive _x} count (units _grp). Added also some safety code.

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  

×