Jump to content
FederalRazer89

Need help with a scavenging script for AI

Recommended Posts

Hello

I am creating a script that will make AI squad members search for ammo for there primary weapon. And it works for any dead bodys, but it dont work if they seaching a vehicle.
The AI unit walk to the vehicle but they dont  do anything, just trigger the next part of the script without any errors.
Because there is no error is kind of hard to solve it. But i know the line were it fails to create the action that i wants.

the init for the script.

Spoiler

_playerGroup = (group player);    
_pos         = getpos player;
_Loot        = _pos nearEntities [["car","tank","air"], 50];
_TheDead     = allDeadMen;
_NewLoot     = [];

for "_i" from 0 to ((count _Loot) - 1) do
{

    _Object = _Loot select _i;
    _Check  = getMagazineCargo _Object;
    
    if ((count _Check) != 0) then {_NewLoot pushBack _Object};


};

sleep 0.1;


for "_j" from 1 to ((count (units _playerGroup)) - 1) do
{
    _Soldier = (units _playerGroup) select _j;

_unitweapon   = primaryWeapon _Soldier;
_Magtype      = getArray (configfile >> "CfgWeapons" >> _unitweapon >> "magazines");
_MagSelected  = _Magtype select 0;
_StorageCheck = _Soldier canAdd _MagSelected;
if (_StorageCheck) then {[_NewLoot,_TheDead,_Soldier] spawn _RearmGroup};
};



Function for each squad member. (Problem in this function)

Spoiler

_RearmGroup = 
{
    _LootList        = _this select 0;
    _DeadLoot        = _this select 1;
    _SelectedSoldier = _this select 2;
    
    
   
_unitweapon   = primaryWeapon _SelectedSoldier;
_Magtype      = getArray (configfile >> "CfgWeapons" >> _unitweapon >> "magazines");
_MagSelected  = _Magtype select 0;
_StorageCheck = _SelectedSoldier canAdd _MagSelected;
doStop _SelectedSoldier;
sleep 1;
_timelimit = time + 60;    

    if ((count _LootList) != 0) then
    {
        for "_i" from 0 to ((count _LootList)- 1) do
        {
            if ((player distance _SelectedSoldier) >= 60) exitWith {};
            
            _test = _LootList select _i;
            if ((count _LootList) >= 7) then {_test = selectrandom _LootList};
            _SelectedSoldier doMove (position _test);
            
                while {true} do
                {
                if (time >= _timelimit) exitWith {};
                if ((_SelectedSoldier distance _test) <= 10) exitWith {};
                
                sleep 0.1;
                };
            
            if (time >= _timelimit) exitWith {};
            
            for "_j" from 0 to ((count _Magtype) - 1) do
            {
                _Magtest      = _Magtype select _j;
                _selectedLoot = (getMagazineCargo _test) select 0;       // should be around here
                
                for "_k" from 0 to ((count _selectedLoot) - 1) do
                {
                    
                    _compmag = _selectedLoot select _k;
                    if (_compmag == _Magtest) then {if (_SelectedSoldier canAdd _compmag) then {_SelectedSoldier action ["TAKEMAGAZINE", _test, _compmag];sleep 0.5}};

                };
                
                
                
            };
            sleep 0.1;


        
        };
    };

    if ((count _DeadLoot) != 0) then 
    {
        for "_i" from 0 to ((count _DeadLoot)- 1) do
        {

            
            _test = _DeadLoot select _i;
            if ((count _DeadLoot) >= 7) then {_test = selectrandom _DeadLoot};
            _SelectedSoldier doMove (position _test);
            
            if ((player distance _SelectedSoldier) >= 60) exitWith {};
            if ((player distance _test) >= 60) exitWith {};
            
            
                while {true} do
                {
                if (time >= _timelimit) exitWith {};
                if ((_SelectedSoldier distance _test) <= 5) exitWith {};
                
                sleep 0.1;
                };
            
            if (time >= _timelimit) exitWith {};
            
            for "_j" from 0 to ((count _Magtype) - 1) do
            {
                _Magtest          = _Magtype select _j;
                _selectedDeadVest = (getMagazineCargo vestContainer _test) select 0;
                _selectedDeadUni  = (getMagazineCargo uniformContainer _test) select 0;
                _selectedDeadBack = (getMagazineCargo backpackContainer _test) select 0;            
                
                
                for "_k" from 0 to ((count _selectedDeadVest) - 1) do
                {
                    _compmagV = _selectedDeadVest select _k;
                    if (_compmagV == _Magtest) then {if (_SelectedSoldier canAdd _compmagV) then {_SelectedSoldier action ["TAKEMAGAZINE", _test, _compmagV];sleep 0.5}};
              
                };
                for "_k" from 0 to ((count _selectedDeadUni) - 1) do
                {
                    _compmagU = _selectedDeadUni select _k;
                    if (_compmagU == _Magtest) then {if (_SelectedSoldier canAdd _compmagU) then {_SelectedSoldier action ["TAKEMAGAZINE", _test, _compmagU];sleep 0.5}};
              
                };
                for "_k" from 0 to ((count _selectedDeadBack) - 1) do
                {
                    _compmagB = _selectedDeadBack select _k;
                    if (_compmagB == _Magtest) then {if (_SelectedSoldier canAdd _compmagB) then {_SelectedSoldier action ["TAKEMAGAZINE", _test, _compmagB];sleep 0.5}};
              
                };
                
                
                
            };
            sleep 0.1;


        
        };
    };
    
    waitUntil {time >= _timelimit};
    _SelectedSoldier commandFollow player;

};


Any suggestions would be nice

Share this post


Link to post
Share on other sites

This is a known bug with "TakeMagazine" action, TakeMagazine does work on bodies but not on any other kind of container (ground, boxes, vehicles). See feedback tracker: https://feedback.bistudio.com/T75585

Since you are only letting each AI take one of each kind of compatible magazine from the vehicle this here could be a quick workaround, it does however mean that your AI can rearm at the vehicle any number of times:

_compmag = _selectedLoot select _k;
if (_compmag == _Magtest) then {
	if (_SelectedSoldier canAdd _compmag) then {
    	_SelectedSoldier action ["TAKEMAGAZINE", _test, _compmag]; //To play the animation.
    	_SelectedSoldier addMagazine _compmag; //Adding the magazine
    	//Preferably we would remove the magazine from the vehicle _test here as well but AFAIK no such simple command exists yet.
    	sleep 0.5
	}
};


To get around the infinite rearm you would have to clear the magazine cargo (clearMagazineCargo) of the vehicle and re-add the same amount minus number of magazines taken (addMagazineCargo). It can be done but since you got AI doing it all at the same time there are sync issues that you need to account for.

  • Like 1

Share this post


Link to post
Share on other sites

So that was a bug, thought it was weird that it worked on bodies but not vehicles.
Thought about a similar approach, will try and use a workaround.

Thanks mrcurry would have been stuck in an long loop of troubleshooting and testing if i didnt know this.

Share this post


Link to post
Share on other sites

Tried to make a workaround, but i could make is so it replaces the lost cargo from clearMagazineCargo. But on the bright side it did give me some ideas on other things.
I uploaded my current version of the script if anyone to try, but i think i will wait untill that bug gets fixed. Or someone suggest another solution.

Init

Spoiler

    
_playerGroup = (group player);    
_pos         = getpos player;
_Loot        = _pos nearEntities [["car","tank","air"], 50];
_TheDead     = allDeadMen;
_NewLoot     = [];

for "_i" from 0 to ((count _Loot) - 1) do
{

    _Object = _Loot select _i;
    _Check  = getMagazineCargo _Object;
    
    if ((count _Check) != 0) then {_NewLoot pushBack _Object};


};

sleep 0.1;


for "_j" from 1 to ((count (units _playerGroup)) - 1) do
{
    _Soldier = (units _playerGroup) select _j;

_unitweapon   = primaryWeapon _Soldier;
_Magtype      = getArray (configfile >> "CfgWeapons" >> _unitweapon >> "magazines");
_MagSelected  = _Magtype select 0;
_StorageCheck = _Soldier canAdd _MagSelected;
if (_StorageCheck) then {[_NewLoot,_TheDead,_Soldier] spawn _RearmGroup};
sleep 7;
};


function

Spoiler

_RearmGroup = 
{
    _LootList        = _this select 0;
    _DeadLoot        = _this select 1;
    _SelectedSoldier = _this select 2;
    
    
   
_unitweapon   = primaryWeapon _SelectedSoldier;
_Magtype      = getArray (configfile >> "CfgWeapons" >> _unitweapon >> "magazines");
_MagSelected  = _Magtype select 0;
_StorageCheck = _SelectedSoldier canAdd _MagSelected;
doStop _SelectedSoldier;
sleep 1;
_timelimit = time + 60;    
 

    if ((_LootList)  != 0) then
    {
        for "_i" from 0 to ((count _LootList)- 1) do
        {
            if ((player distance _SelectedSoldier) >= 60) exitWith {};
            
            _test = _LootList select _i;
            if ((count _LootList) >= 7) then {_test = selectrandom _LootList};
            _SelectedSoldier doMove (position _test);
            
                while {true} do
                {
                if (time >= _timelimit) exitWith {};
                if ((_SelectedSoldier distance _test) <= 10) exitWith {};
                
                sleep 0.1;
                };
            
            if (time >= _timelimit) exitWith {};
            
            for "_j" from 0 to ((count _Magtype) - 1) do
            {
                _Magtest            = _Magtype select _j;
                _selectedLoot       = (getMagazineCargo _test) select 0;
                _selectedLootAmount = (getMagazineCargo _test) select 1;
                _amount             = 1;
                if (_SelectedSoldier canAdd [_Magtest,10]) then {_amount = 4};
                
                for "_o" from 1 to _amount do
                {
                    for "_k" from 0 to ((count _selectedLoot) - 1) do
                    {
                        
                        _compmag = _selectedLoot select _k;
                        if (_compmag == _Magtest) then {
                                                        if (_SelectedSoldier canAdd _compmag) then 
                                                                                            {

                                                                                                    _SelectedSoldier action ["TAKEMAGAZINE", _test, _compmag];
                                                                                                    sleep 0.01;
                                                                                                    clearMagazineCargo _test;
                                                                                                        for "_l" from 0 to ((count _selectedLoot) - 1) do
                                                                                                        {
                                                                                                        _AddingMagtype   = _selectedLoot select _l;
                                                                                                        _AddingMagAmount = _selectedLootAmount select _l;
                                                                                                        if (_compmag != _Magtest) then 
                                                                                                            {
                                                                                                               _test addMagazineAmmoCargo [_AddingMagtype, _AddingMagAmount];
                                                                                                            }
                                                                                                            else
                                                                                                            {
                                                                                                                _test addMagazineAmmoCargo [_AddingMagtype, (_AddingMagAmount - 1)];
                                                                                                                _SelectedSoldier addMagazine _Magtest;
                                                                                                            };
                                                                                                            
                                                                                                        };
                                                                                            
                                                                                            };
                                                                                    
                        };

                    };
                };
                
                
            };
            sleep 0.1;


        
        };
    };

    if ((count _DeadLoot) != 0) then 
    {
        for "_i" from 0 to ((count _DeadLoot)- 1) do
        {

            
            _test = _DeadLoot select _i;
            if ((count _DeadLoot) >= 7) then {_test = selectrandom _DeadLoot};
            _SelectedSoldier doMove (position _test);
            
            if ((player distance _SelectedSoldier) >= 60) exitWith {};
            if ((player distance _test) >= 60) exitWith {};
            
            
                while {true} do
                {
                if (time >= _timelimit) exitWith {};
                if ((_SelectedSoldier distance _test) <= 5) exitWith {};
                
                sleep 0.1;
                };
            
            if (time >= _timelimit) exitWith {};
            
            for "_j" from 0 to ((count _Magtype) - 1) do
            {
                _Magtest                = _Magtype select _j;
                _selectedDeadVest       = (getMagazineCargo vestContainer _test) select 0;
                _selectedDeadUni        = (getMagazineCargo uniformContainer _test) select 0;
                _selectedDeadBack       = (getMagazineCargo backpackContainer _test) select 0;            
                _selectedDeadVestAmount = (getMagazineCargo vestContainer _test) select 1;
                _selectedDeadUniAmount  = (getMagazineCargo uniformContainer _test) select 1;
                _selectedDeadBackAmount = (getMagazineCargo backpackContainer _test) select 1;
                _DeadammoCount          = 1;
                
                if (_SelectedSoldier canAdd [_Magtest,10]) then {_DeadammoCount = 3};
                if (_SelectedSoldier canAdd [_Magtest,6]) then {_DeadammoCount = 2};
                
                for "_l" from 1 to _DeadammoCount do
                {
                
                    for "_k" from 0 to ((count _selectedDeadVest) - 1) do
                    {
                        _compmagV = _selectedDeadVest select _k;
                        if (_compmagV == _Magtest) then {if (_SelectedSoldier canAdd _compmagV) then {_SelectedSoldier action ["TAKEMAGAZINE", _test, _compmagV];sleep 0.5}};
                  
                    };
                    for "_k" from 0 to ((count _selectedDeadUni) - 1) do
                    {
                        _compmagU = _selectedDeadUni select _k;
                        if (_compmagU == _Magtest) then {if (_SelectedSoldier canAdd _compmagU) then {_SelectedSoldier action ["TAKEMAGAZINE", _test, _compmagU];sleep 0.5}};
                  
                    };
                    for "_k" from 0 to ((count _selectedDeadBack) - 1) do
                    {
                        _compmagB = _selectedDeadBack select _k;
                        if (_compmagB == _Magtest) then {if (_SelectedSoldier canAdd _compmagB) then {_SelectedSoldier action ["TAKEMAGAZINE", _test, _compmagB];sleep 0.5}};
                  
                    };
                };
            };
            sleep 0.1;


        
        };
    };
    
                while {true} do
                {
                if (time >= _timelimit) exitWith {};
                if ((_SelectedSoldier distance player) <= 50) exitWith {};
                
                sleep 0.1;
                };
    _SelectedSoldier commandFollow player;

};

 

Share this post


Link to post
Share on other sites

Hey mate nice job I would much like to use this, how/where would I put all this in my mission folder? 

 

Thank you

Share this post


Link to post
Share on other sites

You could create one sqf dokument and copy the function first and at the bottom of the dokument insert the init. Then you will have to activate it with the metod of your chose. 

 

On 2017-08-03 at 10:11 AM, mrcurry said:

This is a known bug with "TakeMagazine" action, TakeMagazine does work on bodies but not on any other kind of container (ground, boxes, vehicles). See feedback tracker: https://feedback.bistudio.com/T75585

Untill they fix this bug or i find a way to workaround it this will only work with dead bodies.

 

Spoiler

_RearmGroup = 
{
    _LootList        = _this select 0;
    _DeadLoot        = _this select 1;
    _SelectedSoldier = _this select 2;
    
    
   
_unitweapon   = primaryWeapon _SelectedSoldier;
_Magtype      = getArray (configfile >> "CfgWeapons" >> _unitweapon >> "magazines");
_MagSelected  = _Magtype select 0;
_StorageCheck = _SelectedSoldier canAdd _MagSelected;
doStop _SelectedSoldier;
sleep 1;
_timelimit = time + 60;    
_nope      = 0;

    if (_nope == 1) then
    {
        for "_i" from 0 to ((count _LootList)- 1) do
        {
            if ((player distance _SelectedSoldier) >= 60) exitWith {};
            
            _test = _LootList select _i;
            if ((count _LootList) >= 7) then {_test = selectrandom _LootList};
            _SelectedSoldier doMove (position _test);
            
                while {true} do
                {
                if (time >= _timelimit) exitWith {};
                if ((_SelectedSoldier distance _test) <= 10) exitWith {};
                
                sleep 0.1;
                };
            
            if (time >= _timelimit) exitWith {};
            
            for "_j" from 0 to ((count _Magtype) - 1) do
            {
                _Magtest            = _Magtype select _j;
                _selectedLoot       = (getMagazineCargo _test) select 0;
                _selectedLootAmount = (getMagazineCargo _test) select 1;
                _amount             = 1;
                if (_SelectedSoldier canAdd [_Magtest,10]) then {_amount = 4};
                
                for "_o" from 1 to _amount do
                {
                    for "_k" from 0 to ((count _selectedLoot) - 1) do
                    {
                        
                        _compmag = _selectedLoot select _k;
                        if (_compmag == _Magtest) then {
                                                        if (_SelectedSoldier canAdd _compmag) then 
                                                                                            {

                                                                                                    _SelectedSoldier action ["TAKEMAGAZINE", _test, _compmag];
                                                                                                    sleep 0.01;
                                                                                                    clearMagazineCargo _test;
                                                                                                        for "_l" from 0 to ((count _selectedLoot) - 1) do
                                                                                                        {
                                                                                                        _AddingMagtype   = _selectedLoot select _l;
                                                                                                        _AddingMagAmount = _selectedLootAmount select _l;
                                                                                                        if (_compmag != _Magtest) then 
                                                                                                            {
                                                                                                               _test addMagazineAmmoCargo [_AddingMagtype, _AddingMagAmount];
                                                                                                            }
                                                                                                            else
                                                                                                            {
                                                                                                                _test addMagazineAmmoCargo [_AddingMagtype, (_AddingMagAmount - 1)];
                                                                                                                _SelectedSoldier addMagazine _Magtest;
                                                                                                            };
                                                                                                            
                                                                                                        };
                                                                                            
                                                                                            };
                                                                                    
                        };

                    };
                };
                
                
            };
            sleep 0.1;


        
        };
    };

    if ((count _DeadLoot) != 0) then 
    {
        for "_i" from 0 to ((count _DeadLoot)- 1) do
        {

            
            _test = _DeadLoot select _i;
            if ((count _DeadLoot) >= 7) then {_test = selectrandom _DeadLoot};
            _SelectedSoldier doMove (position _test);
            
            if ((player distance _SelectedSoldier) >= 60) exitWith {};
            if ((player distance _test) >= 60) exitWith {};
            
            
                while {true} do
                {
                if (time >= _timelimit) exitWith {};
                if ((_SelectedSoldier distance _test) <= 5) exitWith {};
                
                sleep 0.1;
                };
            
            if (time >= _timelimit) exitWith {};
            
            for "_j" from 0 to ((count _Magtype) - 1) do
            {
                if ((_SelectedSoldier distance player) <= 50) exitWith {};
                _Magtest                = _Magtype select _j;
                _selectedDeadVest       = (getMagazineCargo vestContainer _test) select 0;
                _selectedDeadUni        = (getMagazineCargo uniformContainer _test) select 0;
                _selectedDeadBack       = (getMagazineCargo backpackContainer _test) select 0;            
                _selectedDeadVestAmount = (getMagazineCargo vestContainer _test) select 1;
                _selectedDeadUniAmount  = (getMagazineCargo uniformContainer _test) select 1;
                _selectedDeadBackAmount = (getMagazineCargo backpackContainer _test) select 1;
                _DeadammoCount          = 1;
                
                if (_SelectedSoldier canAdd [_Magtest,10]) then {_DeadammoCount = 3};
                if (_SelectedSoldier canAdd [_Magtest,6]) then {_DeadammoCount = 2};
                
                for "_l" from 1 to _DeadammoCount do
                {
                
                    for "_k" from 0 to ((count _selectedDeadVest) - 1) do
                    {
                        _compmagV = _selectedDeadVest select _k;
                        if (_compmagV == _Magtest) then {if (_SelectedSoldier canAdd _compmagV) then {_SelectedSoldier action ["TAKEMAGAZINE", _test, _compmagV];sleep 0.5}};
                  
                    };
                    for "_k" from 0 to ((count _selectedDeadUni) - 1) do
                    {
                        _compmagU = _selectedDeadUni select _k;
                        if (_compmagU == _Magtest) then {if (_SelectedSoldier canAdd _compmagU) then {_SelectedSoldier action ["TAKEMAGAZINE", _test, _compmagU];sleep 0.5}};
                  
                    };
                    for "_k" from 0 to ((count _selectedDeadBack) - 1) do
                    {
                        _compmagB = _selectedDeadBack select _k;
                        if (_compmagB == _Magtest) then {if (_SelectedSoldier canAdd _compmagB) then {_SelectedSoldier action ["TAKEMAGAZINE", _test, _compmagB];sleep 0.5}};
                  
                    };
                };
            };
            sleep 0.1;


        
        };
    };
    
                while {true} do
                {
                if (time >= _timelimit) exitWith {};
                if ((_SelectedSoldier distance player) <= 50) exitWith {};
                
                sleep 0.1;
                };
    _SelectedSoldier commandFollow player;

};


    
_playerGroup = (group player);    
_pos         = getpos player;
_Loot        = _pos nearEntities [["car","tank","air"], 50];
_TheDead     = allDeadMen;
_NewLoot     = [];

for "_i" from 0 to ((count _Loot) - 1) do
{

    _Object = _Loot select _i;
    _Check  = getMagazineCargo _Object;
    
    if ((count _Check) != 0) then {_NewLoot pushBack _Object};


};

sleep 0.1;


for "_j" from 1 to ((count (units _playerGroup)) - 1) do
{
    _Soldier = (units _playerGroup) select _j;

_unitweapon   = primaryWeapon _Soldier;
_Magtype      = getArray (configfile >> "CfgWeapons" >> _unitweapon >> "magazines");
_MagSelected  = _Magtype select 0;
_StorageCheck = _Soldier canAdd _MagSelected;
if (_StorageCheck) then {[_NewLoot,_TheDead,_Soldier] spawn _RearmGroup};
sleep 7;
};

 

  
    
 

To make it easy for you copy this into a sqf dokument, then use some command like addaction or radio trigger to activate this script. Then depending on how you want to use it, you might want to use execVM or spawn.
------------------------------------------------------------------------------------------------------------------------------------------
exemple:
[ ] execVM "Rootdirectory\Rearm" ;

or

fn_Rearm  = compile preprocessFileLineNumbers "Rootdirectory\Rearm.sqf";
[ ] spawn fn_Rearm;

------------------------------------------------------------------------------------------------------------------------------------------
if you have it in the mission folder and not in any sub folders then the path should be like this:


[ ] execVM "Rearm" ;

or

fn_Rearm  = compile preprocessFileLineNumbers "Rearm.sqf";
[ ] spawn fn_Rearm;


------------------------------------------------------------------------------------------------------------------------------------------

If you want to use a radio command then:

 

With execVM
_trg = createTrigger ["EmptyDetector", [0,0,0]];
_trg setTriggerActivation ["ALPHA","PRESENT", true];
_trg setTriggerStatements ["this", '[ ] execVM "Rootdirectory\Rearm";',"sleep 1" ]; 
1 setRadioMsg "Rearm";


With spawn
_trg = createTrigger ["EmptyDetector", [0,0,0]];
_trg setTriggerActivation ["ALPHA","PRESENT", true];
_trg setTriggerStatements ["this", '[] spawn fn_Rearm;',"sleep 1" ]; 
1 setRadioMsg "Rearm";

------------------------------------------------------------------------------------------------------------------------------------------


I am not sure how much you know about scripting but i am going to work and will be gone for some time so i decided to give these exemples of how to use it.

  • Thanks 1

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

×