I'm new to modding Arma so if the code looks strange it's because I haven't found clear documentation and didn't have time to compensate with experience.
I can't figure out why my script stops executing in certain cases.
TL;DR
I have a while (true) in which there's a for loop, so pretty intensive. Initially I thought it simply quits because it's too much work. It happened before. But the problem is that it runs just fine with extra code executing unconditionally but it just won't run when I simply condition that code within a simple if. So it's not about logic/algorithm.
Now the code:
aidMarkers.sqf:
hint "beginning..";
#define MAX_UNITS 20
private _units = [];
private _prevUnitsCount = 0;
private _unitsCount = 0;
private _u;
private _i = 0;
private _id = 0;
private _idMrks = [];
private _idMrkCurr;
private _doColors = true;
getUnitId =
{
private ["_vvn", "_str"];
_vvn = vehicleVarName _this;
_this setVehicleVarName "";
_str = str _this;
_this setVehicleVarName _vvn;
parseNumber (_str select [(_str find ":") + 1])
};
updateMarkers =
{
for "_i" from 0 to MAX_UNITS do
{
if(_i < (_unitsCount)) then
{
_u = _units select _i;
_id = _u call getUnitId;
_idMrkCurr = _idMrks select (_id -1);
_idMrkCurr setMarkerPosLocal position (_units select _i);
switch(typeOf _u) do
{
case "B_Soldier_lite_F": {_idMrkCurr setMarkerTypeLocal "si_1"}; // rifle lite
case "B_Soldier_F": {_idMrkCurr setMarkerTypeLocal "si_regular"}; // rifle
case "B_Soldier_GL_F": {_idMrkCurr setMarkerTypeLocal "si_gren"}; // grena
case "B_soldier_AR_F": {_idMrkCurr setMarkerTypeLocal "si_autor"}; // autorifleman
case "B_soldier_M_F": {_idMrkCurr setMarkerTypeLocal "si_mark"}; // marksman
case "B_soldier_LAT_F": {_idMrkCurr setMarkerTypeLocal "si_2"}; // rifle AT
case "B_soldier_exp_F": {_idMrkCurr setMarkerTypeLocal "si_regular"};
case "B_Helipilot_F": {_idMrkCurr setMarkerTypeLocal "si_3"};
case "B_soldier_AT_F": {_idMrkCurr setMarkerTypeLocal "si_regular"}; // miss spec AT
case "B_soldier_AA_F": {_idMrkCurr setMarkerTypeLocal "si_1"};
case "B_crew_F": {_idMrkCurr setMarkerTypeLocal "si_3"};
case "B_sniper_F": {_idMrkCurr setMarkerTypeLocal "si_sniper"};
case "B_helicrew_F": {_idMrkCurr setMarkerTypeLocal "si_3"};
case "B_Pilot_F": {_idMrkCurr setMarkerTypeLocal "si_3"};
case "B_HeavyGunner_F": {_idMrkCurr setMarkerTypeLocal "si_hg"};
default {_idMrkCurr setMarkerTypeLocal "si_regular"};
};
if(_doColors == true)then ////////// <- this is the culprit //////////////////////////////
{
switch(assignedTeam _u) do
{
case "MAIN": {_idMrkCurr setMarkerColorLocal "ColorWhite"};
case "RED": {_idMrkCurr setMarkerColorLocal "ColorRed"};
case "GREEN" : {_idMrkCurr setMarkerColorLocal "ColorGreen"};
case "BLUE" : {_idMrkCurr setMarkerColorLocal "ColorBlue"};
case "YELLOW" : {_idMrkCurr setMarkerColorLocal "ColorYellow"};
default {_idMrkCurr setMarkerColorLocal "ColorWhite"};
};
};
sleep (1/_unitsCount);
};
};
_doColors = false;
};
resetMarkers =
{
for "_i" from 0 to MAX_UNITS do
{
(_idMrks select _i) setMarkerPosLocal [-10000, -10000];
(_idMrks select _i) setMarkerTypeLocal "errer";
(_idMrks select _i) setMarkerColorLocal ColorBlack;
};
};
// create markers
for "_i" from 0 to MAX_UNITS do
{
_idMrks pushBack createMarkerLocal [(str (_i + 1)), [-10000, -10000]];
(_idMrks select _i) setMarkerSizeLocal [0.85,0.85];
(_idMrks select _i) setMarkerTypeLocal "errer";
(_idMrks select _i) setMarkerTextLocal str (_i + 1);
};
// MAIN
while{true} do
{
if(visibleMap)then
{
if(alive player) then
{
_units = units player;
_unitsCount = count _units;
if(_prevUnitsCount != _unitsCount) then
{
call resetMarkers;
};
if((_unitsCount) > 1)then
{
call updateMarkers;
};
_prevUnitsCount = _unitsCount;
};
}
else
{
_doColors = true; // optimize!
sleep 1;
};
};
In the code look for the culprit at "/////////////////////".
So if I just execute the switch anyway (i.e. no if condition) it runs fine. Otherwise it runs a few lines then it terminates at first iteration.
FWIW this is called by an execVM in another script.