Jump to content
FDZ

Script terminates unexpectedly

Recommended Posts

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.

Share this post


Link to post
Share on other sites

Welcome to the forums @FDZ.

 

Your issue is that _doColors is a boolean (true/false) and == does not compare booleans. However you're in luck since if expects a boolean anyway so just do:

if (_doColors) then { stuff } 

Or if your variable can contain two or more data types use isEqualTo instead. 

 

Also for the future turn on -showScriptErrors and check your log file for these kinds of errors. Sometimes the game can actually tell you what you did wrong. ;)

If you haven't found the log file yet look in %Appdata%\local\Arma 3.

  • Like 1

Share this post


Link to post
Share on other sites
18 minutes ago, mrcurry said:

_doColors is a boolean (true/false), == does not compare booleans, use: if (_doColors) then { stuff } 

Or if you work with several data types in a single variable use isEqualTo instead. 

 

Also for the future turn on - showScriptErrors and check your log file for these kinds of errors. Sometimes it can actually tell you what you did wrong. ;) 

Wow, I was like "whuut??". It took me a few reads to understand. Thanks man!

EDIT:

It works but I figured out I'm forced to run the switch unconditionally anyway, since I can't assign team while in map. It won't "refresh" :)

A "teamAssigned" event handler would've been perfect...

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

×