Jump to content
Nicoman35

AddAction for multiple AI units. Possible?

Recommended Posts

When you add an action to some units, which is available via action menu, then choosing 6. Action, all is good as long as you choose a single ai unit. Is it possible to make these actions available, when more than one unit is chosen?

Share this post


Link to post
Share on other sites

No. That's not implemented. But you can add an action on leader (or whatever unit) and make the code work for the whole group.

Share this post


Link to post
Share on other sites
2 hours ago, Nicoman35 said:

When you add an action to some units, which is available via action menu, then choosing 6. Action, all is good as long as you choose a single ai unit. Is it possible to make these actions available, when more than one unit is chosen?

Well you can have one action on every unit, that adds units to an array and then another action that does something with all units in that array, if I understood your intentions correctly.

 

Cheers

Share this post


Link to post
Share on other sites

Look, I made a script for AI mortar gunners to be able to rearm from ACE ammo crates. So, when I got an AI unit in my team, and he is in the mortar, and he tells: "Ammo low", I can simply tell him to rearm.

Now, if I got 4 AI units, each of them in a mortar,  I would like to tell them all at once: Rearm. And not every single one. Or maybe only 2 of the 4.
And I ask this question as I am single playing a lot, commanding a lot of AI units. And on multiple occasions, I would like to be able to select multiple of them to tell them this or that. 

For official commands, like 'move' or 'stop' or similar, this is no problem. I press F2 to F8, then I tell them all to STOP.

And I wanted to copy this behavior to some of the scripts I have done. Like the mortar rearm.

Spoiler

NIC_fn_ACTION_REARM_ON = {
    params ["_mortarMK6"];
    private _actionID_MK = _mortarMK6 addAction [                                    // Add 'Rearm Mortar' action to mortar gunners
        localize "STR_NIC_MK6_TITLE",                                                // Title
        {_this call NIC_fn_Rearm_MK6;},                                                // Script
        nil,                                                                        // Arguments
        0,                                                                            // Priority
        false,                                                                        // showWindow
        true,                                                                        // hideOnUse
        "",                                                                            // Shortcut
        "gunner _target == _this"                                                    // Condition, action menu only available for gunners of mortars
    ];
};

NIC_fn_Rearm_MK6 = {
    params ["_mortarMK6"];
    // diag_log formatText ["%1%2%3%4%5", time, "s  (NIC_fn_Rearm_MK6) _mortarMK6: ", _mortarMK6, ", _this: ", _this];
    private _weapArray = [];
    {
        private _cfgTurret = _x;
        {
            _weapArray pushBack [getArray (_cfgTurret >> "magazines")]
        } forEach (getArray (_cfgTurret >> "weapons"));    
    } forEach ([_mortarMK6] call BIS_fnc_getTurrets);
    _weapArray = _weapArray select 1 select 0;
    private _defaultHEmags = {_x == "8Rnd_82mm_Mo_shells"} count _weapArray;
    private _defaultIllumMags = {_x == "8Rnd_82mm_Mo_Flare_white"} count _weapArray;
    private _defaultSmokeMags = {_x == "8Rnd_82mm_Mo_Smoke_white"} count _weapArray;
    private _defaultHEammo        = _defaultHEmags * 8;                                                    // default HE ammo count of MK 6 (8 rounds per magazine)
    private _defaultIllumAmmo     = _defaultIllumMags * 8;                                                // default Flare ammo count of MK 6 (8 rounds per magazine)
    private _defaultSmokeAmmo     = _defaultSmokeMags * 8;                                                // default Smoke ammo count of MK 6 (8 rounds per magazine)
    // diag_log formatText ["%1%2%3%4%5%6%7", time, "s  (NIC_fn_Rearm_MK6) _defaultHEammo: ", _defaultHEammo, ", _defaultIllumAmmo: ", _defaultIllumAmmo, ", _defaultSmokeAmmo: ", _defaultSmokeAmmo];
    private _mortarHEammoCount = 0;
    private _mortarIllumAmmoCount = 0;
    private _mortarSmokeAmmoCount = 0;
    private _allMagazines = magazinesAmmoFull _mortarMK6;                                                // get current magazines detailed info of mortar
    // diag_log formatText ["%1%2%3%4%5%6%7", time, "s  (NIC_fn_Rearm_MK6) _allMagazines: ", _allMagazines];
    {
        if (_x select 0 == "8Rnd_82mm_Mo_shells") then {                                                // current magazine is a HE magazine type
            _mortarHEammoCount = _mortarHEammoCount + (_x select 1);                                    // add current HE magazine count to mortar HE ammo count
        };
        if (_x select 0 == "8Rnd_82mm_Mo_Flare_white") then {                                            // current magazine is a HE magazine type
            _mortarIllumAmmoCount = _mortarIllumAmmoCount + (_x select 1);                                // add current flare magazine count to mortar flare ammo count
        };
        if (_x select 0 == "8Rnd_82mm_Mo_Smoke_white") then {                                            // current magazine is a HE magazine type
            _mortarSmokeAmmoCount = _mortarSmokeAmmoCount + (_x select 1);                                // add current smoke magazine count to mortar smoke ammo count
        };
    } forEach _allMagazines;
    // diag_log formatText ["%1%2%3%4%5%6%7", time, "s  (NIC_fn_Rearm_MK6) mortar HE ammo: ", _mortarHEammoCount, ", Illum ammo: ", _mortarIllumAmmoCount, ", Smoke ammo: ", _mortarSmokeAmmoCount];
    
    private _wantedHEammo = _defaultHEammo - _mortarHEammoCount;
    private _wantedIllumAmmo = _defaultIllumAmmo - _mortarIllumAmmoCount;
    private _wantedSmokeAmmo = _defaultSmokeAmmo - _mortarSmokeAmmoCount;
    if (_wantedHEammo == 0 && _wantedIllumAmmo == 0 && _wantedSmokeAmmo == 0) exitWith {                // leave routine, if no ammo is needed
        _mortarMK6 groupChat format[localize "STR_NIC_MK6_NO_AMMO_NEEDED"];
    };
    // diag_log formatText ["%1%2%3%4%5%6%7", time, "s  (NIC_fn_Rearm_MK6) _wantedHEammo: ", _wantedHEammo, ", _wantedIllumAmmo: ", _wantedIllumAmmo, ", _wantedSmokeAmmo: ", _wantedSmokeAmmo];

    private _crates = (_mortarMK6 nearObjects NIC_SearchRangeAmmoCrates) select {(typeOf _x == "ACE_Box_82mm_Mo_HE") || (typeOf _x == "ACE_Box_82mm_Mo_Illum") || (typeOf _x == "ACE_Box_82mm_Mo_Smoke") || (typeOf _x == "ACE_Box_82mm_Mo_Combo")};  // Search for all available ammo crates within given range
    if (count _crates == 0) exitWith {                                                                    // leave routine, if no ammo crates are in range
        _mortarMK6 groupChat format[localize "STR_NIC_MK6_NO_AMMO_CRATES"];
    }; 
    // diag_log formatText ["%1%2%3%4%5", time, "s  (NIC_fn_Rearm_MK6) _crates: ", _crates];
    
    private _wantedAmmoTypes = [];                                                                        // array for mortars needed ammo types
    private _wantedAmmoCounts = [];                                                                        // array for mortars needed ammo counts
    if (_wantedHEammo > 0) then {
        _wantedAmmoTypes pushBack "ACE_1Rnd_82mm_Mo_HE";                                                // add HE ammo type to wanted types array
        _wantedAmmoCounts pushBack _wantedHEammo;                                                        // add HE ammo count to ammo counts array
    };
    if (_wantedIllumAmmo > 0) then {
        _wantedAmmoTypes pushBack "ACE_1Rnd_82mm_Mo_Illum";                                                // add flare ammo type to wanted types array
        _wantedAmmoCounts pushBack _wantedIllumAmmo;                                                    // add flare ammo count to ammo counts array
    };    
    if (_wantedSmokeAmmo > 0) then {    
        _wantedAmmoTypes pushBack "ACE_1Rnd_82mm_Mo_Smoke";                                                // add flare smoke type to wanted types array
        _wantedAmmoCounts pushBack _wantedSmokeAmmo;                                                    // add flare smoke count to ammo counts array
    };
    private _wantedAmmoCountsMemory = +_wantedAmmoCounts;                                                // clone wanted ammo counts array for later comparison with the reloaded counts array
    // diag_log formatText ["%1%2%3%4%5", time, "s  (NIC_fn_Rearm_MK6) _wantedAmmoTypes: ", _wantedAmmoTypes, ", _wantedAmmoCounts: ", _wantedAmmoCounts];
    
    // search crates for wanted ammo
    private _TotalRearmTime = 0;
    private _rearmAmmoTypes = [];                                                                        // array of found ammo types for rearming the mortar 
    private _rearmAmmoCounts = [];                                                                        // array of found ammo counts for rearming the mortar
    {
        private _rearmTime = 0;                                                                            // time cycles rearm will take
        private _crate = _x;
        private _crateAmmo = magazinesAmmo _crate;                                                        // get array of magazines from crate
        private _RearmTimePerRoundAndMeter = ceil(_mortarMK6 distance _crate) * NIC_RearmTimePerRoundAndMeter;                                            // get distance in meters from crate to morar
        // diag_log formatText ["%1%2%3%4%5%6%7", time, "s  (NIC_fn_Rearm_MK6) _RearmTimePerRoundAndMeter: ", _RearmTimePerRoundAndMeter];
        {    
            private _wantedAmmoCount = _wantedAmmoCounts select _forEachIndex;                            // get count of wanted ammo type
            // diag_log formatText ["%1%2%3%4%5%6%7", time, "s  (NIC_fn_Rearm_MK6) _x: ", _x, ", _wantedAmmoCount: ", _wantedAmmoCount];
            if (_wantedAmmoCount > 0) then {
                private _wantedAmmoType = _x;                                                            // get wanted ammo type name
                private _crateAmmoCount = {_x select 0 == _wantedAmmoType} count _CrateAmmo;            // get amount of wanted ammo type inside crate
                if (_crateAmmoCount > 0) then {                                                            // crate has ammo of wanted type
                    private _taking = 0;                                                                // amount of taken ammo from crate
                    if (_wantedAmmoCount >= _crateAmmoCount) then {                                        // if wanted ammo count is higher or equal to crate amount
                        _taking = _crateAmmoCount;                                                        // taken amount equals crate amount
                    };
                    if (_wantedAmmoCount < _crateAmmoCount) then {                                        // if wanted ammo count is lower then crate amount
                        _taking = _wantedAmmoCount;                                                        // taken amount equals wanted amount
                    };
                    // diag_log formatText ["%1%2%3%4%5%6%7", time, "s  (NIC_fn_Rearm_MK6) _crateAmmoCount: ", _crateAmmoCount, ", _taking: ", _taking];
                    _wantedAmmoCounts set [_forEachIndex, (_wantedAmmoCount - _taking)];
                    _rearmTime = _rearmTime + (_taking * _RearmTimePerRoundAndMeter);                                                    // raise rearm time interval
                    for "_i" from 1 to _taking do {                                                      // delete taken magazines from crate array
                        private _index = _crateAmmo find [_wantedAmmoType, 1];
                        if (_index == -1) exitwith {};
                        _crateAmmo deleteAt _index;
                    };
                    private _index = _rearmAmmoTypes find _wantedAmmoType;                                // get index of ammo type in rearm array
                    if (_index < 0) then {                                                                // if ammo type was not found, create new element
                        _rearmAmmoTypes pushBack _wantedAmmoType;
                        _rearmAmmoCounts pushBack _taking;
                    } else {                                                                            // if ammo type was found, update rearm count
                        _rearmAmmoCounts set [_index, (_rearmAmmoCounts select _index) + _taking];
                    };
                };
            };
        } forEach (_wantedAmmoTypes);
        // diag_log formatText ["%1%2%3%4%5%6%7", time, "s  (NIC_fn_Rearm_MK6) _rearmAmmoTypes: ", _rearmAmmoTypes, ", _rearmAmmoCounts: ", _rearmAmmoCounts, ", _TotalRearmTime: ", _TotalRearmTime];

        if (_rearmTime > 0) then {
            _TotalRearmTime = _TotalRearmTime + _rearmTime;
            clearMagazineCargoGlobal _crate;                                                            // delete all magazines from crate
            {
                _crate addItemCargoGlobal [_x select 0, 1];                                                // refill the crate with updated magazine array
            } forEach (_crateAmmo);
        };
    } forEach (_crates);
    
    if (_TotalRearmTime == 0) exitWith {                                                                // if no wanted ammo was found, leave with suitable message
        private _str_crate = format[localize "STR_NIC_MK6_CRATE"];
        if (count _crates > 1) then {_str_crate = format[localize "STR_NIC_MK6_CRATES"]};
        _mortarMK6 groupChat format[localize "STR_NIC_MK6_NO_SUITABLE_AMMO", _str_crate];
    };
    // diag_log formatText ["%1%2%3%4%5%6%7", time, "s  (NIC_fn_Rearm_MK6) _TotalRearmTime: ", _TotalRearmTime];

    _mortarMK6 groupChat format[localize "STR_NIC_MK6_REARMING"];                                        // rearm mortar message
    sleep _TotalRearmTime;
    {
        private _rearmMagazineType = "8Rnd_82mm_Mo_shells";                                                // define reload magazine type
        private _rearmAmmoCount = (_rearmAmmoCounts select _forEachIndex) + _mortarHEammoCount;            // total reload ammo count is count of ammo inside mortar plus the rearm ammo count
        switch (_x) do {
            case "ACE_1Rnd_82mm_Mo_Illum": {
                _rearmMagazineType = "8Rnd_82mm_Mo_Flare_white";
                _rearmAmmoCount = (_rearmAmmoCounts select _forEachIndex) + _mortarIllumAmmoCount;
            };
            case "ACE_1Rnd_82mm_Mo_Smoke": {
                _rearmMagazineType = "8Rnd_82mm_Mo_Smoke_white";
                _rearmAmmoCount = (_rearmAmmoCounts select _forEachIndex) + _mortarSmokeAmmoCount;
            };
        };
        private _fullMagazinesCount = floor (_rearmAmmoCount / 8);
        private _reducedMagazineCount = _rearmAmmoCount mod 8;
        // diag_log formatText ["%1%2%3%4%5%6%7%8%9", time, "s  (NIC_fn_Rearm_MK6) _rearmMagazineType: ", _rearmMagazineType, ", _rearmAmmoCount: ", _rearmAmmoCount, ", _fullMagazinesCount: ", _fullMagazinesCount, ", _reducedMagazineCount: ", _reducedMagazineCount];
        _mortarMK6 removeMagazinesTurret [_rearmMagazineType,[0]];
        for "_i" from 1 to _fullMagazinesCount do { 
            _mortarMK6 addMagazineTurret [_rearmMagazineType,[0]];
            // diag_log formatText ["%1%2%3%4%5%6%7%8%9", time, "s  (NIC_fn_Rearm_MK6) added full ", _rearmMagazineType];
        };
        if (_reducedMagazineCount > 0) then {                                                            // for the mortar to be able to load magazines less than 8 rounds, we need to change the main mortar weapon
            _mortarMK6 addMagazineTurret [_rearmMagazineType,[0],_reducedMagazineCount];
            // diag_log formatText ["%1%2%3%4%5%6%7%8%9", time, "s  (NIC_fn_Rearm_MK6) added reduced ", _rearmMagazineType, " (", _reducedMagazineCount, ")"];
        };
    } forEach (_rearmAmmoTypes);        
    if (_wantedAmmoCountsMemory isEqualTo _rearmAmmoCounts) then {
        _mortarMK6 groupChat format[localize "STR_NIC_MK6_MORTAR_REARMED"];
    } else {
        _mortarMK6 groupChat format[localize "STR_NIC_MK6_MORTAR_PAR_REARMED"];
    };
};

NIC_RearmTimePerRoundAndMeter = 0.1;                                                                    // Rearm time in seconds per round and meter distance from mortar to crate
NIC_SearchRangeAmmoCrates = 5;                                                                            // Search range for ammo crates in meters around mortar
["StaticMortar", "init", {_this call NIC_fn_ACTION_REARM_ON}, true] call CBA_fnc_addClassEventHandler;    // adds init event to all static mortars; has to be run preinit!

Share this post


Link to post
Share on other sites

Ah, I see.

Well you can always have an array of all mortar units and go from there, like so:

//inside mortar group team leader or whatever you seem fit
TAG_fnc_mortarUnits = units group this;


//initPlayerLocal.sqf or similar
player addAction ["Mortars rearm!",{
	params ["_object","_caller","_ID"];

	_needRearm = TAG_fnc_mortarUnits select {/*your rearm condition*/};
	hint format ["Mortars need rearm:\n\n%1",_needRearm];
	{
    //rearm stuff here
    } forEach _needRearm;

}, [], 1, true, true, "", "_target == _this and count (TAG_fnc_mortarUnits select {/*your rearm condition*/}) > 0"];

This action will only be visible if at least one unit from the mortar array matches the filter condition and execute the rearm code on all units in need of rearming.

Adjust rearm code and condition as needed, should get you started.

 

Cheers

Share this post


Link to post
Share on other sites

Ok Grumpy. I will see if and how it is possible for me to implement your lead. Many thanks for the answer.

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

×