Rydygier 1306 Posted April 1, 2014 (edited) 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 April 1, 2014 by Rydygier Share this post Link to post Share on other sites
IndeedPete 1038 Posted April 1, 2014 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
jacmac 2 Posted April 1, 2014 (edited) 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 April 1, 2014 by Jacmac Share this post Link to post Share on other sites
igneous01 19 Posted April 1, 2014 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
Magirot 14 Posted April 1, 2014 (edited) 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 April 1, 2014 by Magirot Share this post Link to post Share on other sites
Rydygier 1306 Posted April 2, 2014 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