Jump to content
pierremgi

AI CAN REARM - on crates, corpses, weapons, vehicles, arsenal...

Recommended Posts

Hello all,

Here is a little script enabling AIs for rearming when out of ammo.

If I'm right, the vanilla behavior is:

 - AI leaders sometimes order their AI subordinates for rearming at crates (probably only simple crates/vehicles with accurate magazines). Anyway they don't succeed in that (or barely). What I experienced is AIs running after vehicles, AIs stuck, AIs disobeying... If you have better experience on that, please share.

- as playing leader of AIs, you can order your units to rearm at... known abandoned weapons, crates,...  no matter if you don't know where they are and how far. The list can be looooong (as a day without bread) , and the, totally useless. you can see you AI crossing the map without few chance for actually rearming.

 

Well, I'm trying here another approach, in this way:
- first of all, I limit the script to AIs with played leader. (Just avoiding too many codes on server, but feel free to test what ever units you want);

- only AI units owning a primary weapon are concerned: No player, no tourist;

- When the AI has less than 10 remaining shots in its primary weapon, if magazines or weapons can be picked, within 100 m of the unit (anytime), the AI will move and pick them up.

 

The possibilities and priorities are:

- Any object stated as Arsenal (virtual crates/ vehicles with arsenal code...), is scouted as priority 1. That means the AI will reload at this object, with compatible mags, no matter the content of the arsenal crate/vehicle.

  At this time, and possibly for ever, I don't make any filter about possible limitation on arsenal. That means any enemy (concerned AI) can rearm at any arsenal.

 

- The priority 2 is crates/vehicles fitted with compatible mags. The rearm action on a crate can empty it. This action is the standard behavior of Arma's engine. If you want more, see module! Anyway, the mags can be inside uniforms, vests, backpacks inside the crate or the vehicle. Not so bad.

 

- the priority 3 is friendly fallen corpses... There is neither arsenal, nor crate but some fellows are lying on ground with compatible mags. That's the last chance for AI to keep their actual primary weapon;

 

- the last priority (4) is any weapon found on ground, inside crate or vehicle. This weapon is different from the original. If several choices, the AI will pick one at random... At this time, I don' have filter for all possible cases and skills of AIs... It's just out of my scope. anyway this weapon can be inside a backpack, inside a crate...

I added a mandatory mag for this weapon as I don't want the AIs out of ammo, then picking a weapon, out of ammo then... in a boring cycle. Furthermore, at this time, the abandoned weapon is deleted.

 

Note 1: Vehicles are considered as crates if engine off!
Note 2: You can stop an AI (stop order), so he will not continue his search for mags or weapons (but he will not fight without ammo).

 

Of course, as I'm scripting also for my mod: MGI Advanced Modules, I added a Rearm Module enabling more possibilities:
- You can easily choose different units (to be upgraded perhaps);

- When your AI rearms, the secondary weapon (if any) is refilled in tube (so 1 shot). The AI receives up to 3 first aid kit and hand grenades or smokes. The AI grabs also up to 6 grenades for GL if any.

- the rearm and switchweapon vanilla actions are replaced by animations (same ones) and custom scripts avoiding vanilla inventory (too many mags, no grenades, poor fak)

 

Known limitations:
- the hand guns are not treated at all;

- the GL and launchers are treated in module, but only in case of low primary weapon ammo which stays the triggering factor;

 

Compatible for MP (the treated units are local on each PC/Server), compatible with mods. Depending on mods, you can experience some little difference:

- compatibles mags means... compatible mags and some vanilla mags can be used instead of specific ones, for arsenal. I'm not responsible of these choices.

- on the other hand, there are several "FirstAidKit" along with mods. Some of them keep the class name and modify the aspect, some of them modify the whole stuff (for nuts,imho). Your AI can receive firstAidKit instead of "blabla_holyKitofTheGreatesModEverWritten" . They will not make difference, and you'll see that if you pick items on dead AI fellow.

 

Have fun!

Version: 28 / 07/ 21

 

in init.sqf
 

Spoiler

 


MGI_PRMAGS = compileFinal "
  private _weaponCfg = configFile >> 'CfgWeapons' >> _this;
  private _compatibleMagazines = [];
  private _magazinesList = getarray (_weaponCfg >> 'magazines');
  {
    {
      _magazinesList append (getArray _x);
    } foreach  configproperties [configFile >> 'CfgMagazineWells' >> _x,'isArray _x'];
  } foreach getArray (_weaponCfg >> 'magazineWell');
  {
    private _magazine = _x;
    private _magazineCfg  = configfile >> 'cfgmagazines' >> _magazine;
    if ((getnumber (_magazineCfg >> 'scope') isEqualTo 2)) then {
      _compatibleMagazines pushBackUnique _magazine;
    };
  } foreach _magazinesList;
  _compatibleMagazines
";

MGI_REARMAGS = compileFinal "
  params ['_unit','_crate','_pos',['_arsenalC',FALSE],'_mags','_isCrate'];
  _unit setHitPointDamage ['hitLegs',0];
  _unit setCombatBehaviour 'CARELESS';
  _unit setVariable ['MGI_ONDUTY',TRUE];
  if (_unit distance2D _pos < 120) then {
    _unit doMove _pos;
    _mags = _unit getVariable ['magsInit',[currentMagazine _unit]];
    _isCrate = !(_crate isKindOf 'CAManBase');
    uiSleep 0.5;
    waitUntil {uiSleep 0.5;(unitReady _unit or (!_arsenalC && (_mags arrayIntersect ([magazines _crate,magazineCargo _crate] select _isCrate) isEqualTo [])))};
    if (!_arsenalC && (_mags arrayIntersect ([magazines _crate,magazineCargo _crate] select _isCrate) isEqualTo [])) then {
      _unit doFollow leader _unit;
      _unit setCombatBehaviour 'AWARE';
      _unit setVariable ['MGI_ONDUTY',NIL];
    } else {
      if (_unit distance2D _pos < 5 + ((0 boundingBoxReal _crate)#2 max (0 boundingBoxReal objectParent _crate)#2)) then {
        _unit setdir (_unit getDir _pos);
        _unit action ['rearm', _crate];
        if _arsenalC then {
          private _defaultMag = _mags #0;
          {_unit addMagazine _defaultMag} forEach [1,2,3];
          if (items _unit arrayIntersect ['vn_b_item_firstaidkit','FirstAidKit','vn_o_item_firstaidkit'] isEqualTo []) then {
            _unit addItem 'FirstAidKit';
          };
        };
        if (['ReammoBox'] findIf {_crate isKindOf _x} > -1) then {
          private _otherMags = magazineCargo _crate select {!(_x in _mags)};
          private _allmags = magazineCargo _crate - _otherMags;
          while {_unit canAdd (_allmags #0)} do {
            _addMag = _allmags deleteAt 0;
            _unit addMagazine _addMag;
          };
          if (['vn_b_item_firstaidkit','FirstAidKit','vn_o_item_firstaidkit'] arrayIntersect _otherMags isNotEqualTo []) then {
            _unit addItem ((['vn_b_item_firstaidkit','vn_o_item_firstaidkit','FirstAidKit'] arrayIntersect _otherMags)#0);
          };
          clearMagazineCargoGlobal _crate;
          {_crate addMagazineCargoGlobal [_x,1]} count (_allmags + _otherMags);
        };
        uiSleep 3;
        reload _unit;
        _unit doFollow leader _unit;
        _unit setCombatBehaviour 'AWARE';
        _unit setVariable ['MGI_ONDUTY',NIL];
      };
      _unit selectWeapon primaryWeapon _unit;
    };
  };
";

MGI_TAKEWPN = compileFinal "
  params ['_unit','_crate','_wpn','_pos','_mags','_pos'];
  _unit setHitPointDamage ['hitLegs',0];
  _unit setCombatBehaviour 'CARELESS';
  _unit setVariable ['MGI_ONDUTY',TRUE];
  _unit doMove _pos;
  uiSleep 0.5;
  _mags = _wpn call MGI_PRMAGS;
  waitUntil {uiSleep 0.5; unitReady _unit or isNull _crate or !(_wpn in weaponCargo _crate)};
  private _pWpn = primaryWeapon _unit;
  if (_unit distance2D _pos < 5 +  + ((0 boundingBoxReal _crate)#2 max (0 boundingBoxReal objectParent _crate)#2)) exitWith {
    _unit setdir (_unit getDir _pos);
    private _crateFake = (['WeaponHolder','WeaponHolderSimulated'] findIf {_crate isKindOf _x} > -1);
    if (_mags arrayIntersect magazineCargo _crate isEqualTo []) then {
      _unit addMagazine (_mags #0);
    };
    call {
      if (isNull objectParent _crate && !(_crate isKindOf 'ContainerSupply')) exitWith {
        private _allmags = magazineCargo _crate;
        _unit action ['TakeWeapon',_crate,_wpn];
        private _timer = diag_tickTime;
        waitUntil {_pWpn in weaponCargo _crate or diag_tickTime > _timer + 10};
        if (weaponCargo _crate isEqualTo [_pWpn] && magazineCargo _crate isEqualTo [] && everyContainer _crate isEqualTo [] && _crateFake) then {
          deleteVehicle _crate;
        } else {
          if (_pWpn in weaponCargo _crate) then {
            private _allWpns = + weaponCargo _crate;
            _allWpns deleteAt (_allWpns find _pWpn);
            clearWeaponCargoGlobal _crate;
            clearMagazineCargoGlobal _crate;
            {_crate addWeaponCargoGlobal [_x,1]} count _allWpns;
            {_crate addMagazineCargoGlobal [_x,1]} count _allmags;
          };
        };
        uiSleep 3;
        reload _unit;
      };
      _unit addWeapon _wpn;
      private _allWpns = + weaponCargo _crate;
      _allWpns deleteAt (_allWpns find _wpn);
      clearWeaponCargoGlobal _crate;
      {_crate addWeaponCargoGlobal [_x,1]} count _allWpns;
      uiSleep 3;
      reload _unit;
    };
    _unit setVariable ['magsInit',primaryWeapon _unit call MGI_PRMAGS];
    uiSleep 3;
    _unit doFollow leader _unit;
    _unit setCombatBehaviour 'AWARE';
    _unit setVariable ['MGI_ONDUTY',NIL];
    _unit selectWeapon primaryWeapon _unit;
  };
  if (isNull _crate or !(_wpn in weaponCargo _crate)) then {
    _unit doFollow leader _unit;
    _unit setCombatBehaviour 'AWARE';
    _unit setVariable ['MGI_ONDUTY',NIL];
  };
";

["ReArm","onEachFrame",{
  if (diag_frameNo mod 600 == 0) then {
    {
      private _unit = _x;
      if (isNull objectParent _unit && !isPlayer _unit && simulationEnabled _unit) then {
        if (isNil {_unit getVariable "magsInit"}) then {
          private _compatTypes = primaryWeapon _unit call MGI_PRMAGS;
          _unit setVariable ["magsInit",_compatTypes];
        };
        private _magsPWTypes = ((magazinesAmmoFull _unit) select {(_x#0) in (_unit getVariable "magsInit")});
        private _ammos = 0;
        for "_i" from 0 to count _magsPWTypes -1 do {
          _ammos = _ammos + _magsPWTypes #_i #1
        };
        if (_ammos < 10 && isNil {_unit getVariable "MGI_ONDUTY"}) then {
          private _crate = objNull;
          private _containers = [];
          private _wpnCrates = (nearestObjects [_unit,["ReammoBox_F","LandVehicle","air","WeaponHolderSimulated","WeaponHolder"],100,TRUE]);
          _wpnCrates = _wpnCrates select {private _v = _x; (["LandVehicle","Air"] findIf {_v isKindOf _x} ==-1) or !isEngineOn _x};
          _containers = _wpnCrates apply {[_x,getpos _x]};
          private ["_ev","_ps"];
          {
            _ev = everyContainer _x;
            _ps = getpos _x;
            _containers append (_ev apply {[_x#1,_ps]})
          } count (_wpnCrates select {everyContainer _x isNotEqualTo []});
          private _corpses = allDeadMen select {_x distance2D _unit < 100 && {_x isKindOf "CAManBase"}};
          private _magsInit = _unit getVariable ["magsInit",[]];
          private _wpnConts = _containers apply {_x#0};
          call {
            if (_containers findIf {((_x#0) call BIS_fnc_getVirtualMagazineCargo) isNotEqualTo []} >-1) exitWith {
              _crate = (_containers select {((_x#0) call BIS_fnc_getVirtualMagazineCargo) isNotEqualTo []}) #0#0;
              private _posCrate = (_containers select (_containers findIf {(_x#0) == _crate}))#1;
              if (!stopped _unit) then {[_unit,_crate,_posCrate,TRUE] spawn MGI_REARMAGS};
            };
            if (_containers findif {_magsInit arrayIntersect magazineCargo (_x#0) isNotEqualTo []} >-1) exitWith {
              _crate = (_containers select {_magsInit arrayIntersect magazineCargo (_x#0) isNotEqualTo []}) #0#0;
              private _posCrate = (_containers select (_containers findIf {(_x#0) == _crate}))#1;
              if (!stopped _unit) then {[_unit,_crate,_posCrate,FALSE] spawn MGI_REARMAGS};
            };
            if (_corpses findIf {_magsInit arrayIntersect magazines _x isNotEqualTo []} > -1) exitWith {
              _crate = (_corpses select {_magsInit arrayIntersect magazines _x isNotEqualTo []} select 0);
              if (!stopped _unit) then {[_unit,_crate,getpos _crate,FALSE] spawn MGI_REARMAGS};
            };
            if (_containers findif {weaponCargo (_x#0) select {getnumber (configFile >> "cfgWeapons" >> _x >> "type") isEqualTo 1} isNotEqualTo [] } >-1) exitWith {
              _crate = (_containers select {weaponCargo (_x#0) select {getnumber (configFile >> "cfgWeapons" >> _x >> "type") isEqualTo 1} isNotEqualTo []}) #0#0;
              private _posCrate = (_containers select (_containers findIf {(_x#0) == _crate}))#1;
              private _wpns = weaponCargo _crate select {getnumber (configFile >> "cfgWeapons" >> _x >> "type") isEqualTo 1};
              private _wpn = "";
              private _compatMags = [];
              _wpns = _wpns arrayIntersect _wpns;
              private _mags = (magazineCargo _crate) arrayIntersect (magazineCargo _crate);
              while {_compatMags arrayIntersect _mags isEqualTo [] && _wpns isNotEqualTo []} do {
                _wpn = +_wpns deleteAt (floor random count _wpns);
                _compatMags = _wpn call MGI_PRMAGS;
              };
              if (_wpn == "" or _compatMags arrayIntersect _mags isEqualTo []) then {
                _wpn = _wpns #0;
              };
              if (!stopped _unit) then {[_unit,_crate,_wpn,_posCrate] spawn MGI_TAKEWPN};
            };
          };
        };
      };
    } forEach (flatten (allGroups select {isPlayer leader _x && local leader _x} apply {units _x}));
  }
}] call bis_fnc_addStackedEventHandler;

 

 

 

 

  • Like 5
  • Thanks 6

Share this post


Link to post
Share on other sites

Cool, anything to ease the pain!👍 As far as I experienced throughout Arma series regarding whole AI rearming thing, main issues particularly in A3 seem to be:

  • At some point, AI would really make sure they stock up on grenades even with magazines available. Not sure if this was ever looked at, I don't play much in recent days.
  • Dropped weapon(s) are not necessarily part of its unit container, therefore it is often impossible to open inventory screen/rearm on specific fallen unit because of its weapon(s).
  • As a result, among other reasons, the action list for selecting quickly becomes useless with couple of pages worth of entries and crates are prioritized last. Also, "5, rearm at random ass crate at 10 o'clock and better hope it's the right one"... yeah, not that great. It was fine in 2001 but surely there could be some selectable, object sensitive UI by now. Well, there is that quick command interface or whatever it's called but it has all the wrong actions.
  • The nature of AI navigating/interacting with objects. They have to be about 5 to 10m from certain direction of object in question and then beeline to it. If there is an element preventing that from happening... then, oh well. Object's AI point for interaction in not always obvious or that uniform in 3DEN either. Figuring that out is a matter of trial end error, taking away from actually designing the scenario.

So, that's the little rant on that from long suffering AI babysitter.

  • Like 4

Share this post


Link to post
Share on other sites

This is fantastic and sorely needed. Thanks Pierre!  I know playing Prairie Fire, that my AI team frequently runs out of ammo fighting beaucoup VC. And then its a huge pain in the ass to get them to rearm somewhere nearby .

  • Like 1

Share this post


Link to post
Share on other sites

I just studied your code, and have to say it is beautiful.  If a person takes the time to understand this code they will learn alot  Especially  complex array manipulation. Great job Pierre.  

 

I really need to explore the wiki more, as I learned at least 5 commands that I didn't know existed before (i.e., flatten, diag_frameNo, stopped, allDeadMen, everyContainer, etc).

 

Just to be clear though, I'm not like Dinesh!😂

 

  • Like 1
  • Thanks 1
  • Haha 3

Share this post


Link to post
Share on other sites

Great script have been looking for one like this for my POW mission..

Share this post


Link to post
Share on other sites

MGI ADVANCED MODULES is updated and documentation also!

 

 

Share this post


Link to post
Share on other sites

Hi man,getting back to Arma and you beautiful suite of mods. Was checking this rearm out in the MGI modules.

 

So AI being unable to rearm(BIS SHOULD REALLY FIX THIS) is a bug due to the unit in question who needs to rearm ,having any sidearm in the sidearm slot...remove sidearm and then when they are told to rearm,they do it(3+3) mags or 6 mags taken upon rearm),no issues.

 

Is there any way you can make AI within the group rearm from the ammo bearer or friendly AI in group? from a practical perspective this would be amazing. But i have a feeling that maybe you havent included this on purpose for whatever reason.

 

Regardless nice to be back and using your mods again,working very well.

  • Thanks 1

Share this post


Link to post
Share on other sites
5 hours ago, redarmy said:

Is there any way you can make AI within the group rearm from the ammo bearer or friendly AI in group? from a practical perspective this would be amazing. But i have a feeling that maybe you havent included this on purpose for whatever reason.

 

 

Welcome back! Yes, if many things can be scripted, there are always concessions to do about performance, reliability/immersion and personal choices.

For example, I wouldn't miss the possibility for infantry rearming at vehicles (cargo), so I decided to take into account the vehicles with engine off, only. Not saying it's the unique solution but the cinematic is acceptable. On a same way, I managed the demanding unit reaches a crate/ corpse/ Weapon holder... so static before rearming and falling back to its previous move.

So, rearming at another unit is doable but that probably means to stop the "provider" and make the "requester" reaching this unit. Then, they must share the existing mags, an extra input not mandatory for a crate.  Food for though.

Share this post


Link to post
Share on other sites
1 hour ago, pierremgi said:

 

Welcome back! Yes, if many things can be scripted, there are always concessions to do about performance, reliability/immersion and personal choices.

For example, I wouldn't miss the possibility for infantry rearming at vehicles (cargo), so I decided to take into account the vehicles with engine off, only. Not saying it's the unique solution but the cinematic is acceptable. On a same way, I managed the demanding unit reaches a crate/ corpse/ Weapon holder... so static before rearming and falling back to its previous move.

So, rearming at another unit is doable but that probably means to stop the "provider" and make the "requester" reaching this unit. Then, they must share the existing mags, an extra input not mandatory for a crate.  Food for though.

YES i figured something like that. Had an example today with vanilla AI where i order a subordinate to enter a building pos. He couldnt do it(nothing strange here in Arma) but upon shooting him in the leg and asking anther subordinate to heal him,the subordinate couldnt complete the action,locking them both up.

 

so i imagine if you had a unit in a group tryna get ammo from another it could create issues like this in some circumstances,making the entire idea of less player input neccessary counter intuitive as the player would then have to  "fix" these two guys AND rearm em manually.

Share this post


Link to post
Share on other sites
On 9/21/2022 at 5:05 AM, Richierich750 said:

Can this script be turned into a standalone mod for sp use?

I guess it is made..

 

Quote from the first post..
"

Of course, as I'm scripting also for my mod: MGI Advanced Modules, I added a Rearm Module enabling more possibilities:
- You can easily choose different units (to be upgraded perhaps);

- When your AI rearms, the secondary weapon (if any) is refilled in tube (so 1 shot). The AI receives up to 3 first aid kit and hand grenades or smokes. The AI grabs also up to 6 grenades for GL if any.

- the rearm and switchweapon vanilla actions are replaced by animations (same ones) and custom scripts avoiding vanilla inventory (too many mags, no grenades, poor fak)

"

Share this post


Link to post
Share on other sites

@Play3r Yes it exists as a mod for use as a module in the editor, which is great when using the editor, but if you want to use it in a game where you don't use the editor (for example dynamic recon ops) it's not possible. Which is why I'm asking if this script can be turned into a standalone mod which you can subscribe to on steam in the same way you can for Vcom ai or lambs?

Share this post


Link to post
Share on other sites
13 hours ago, Richierich750 said:

@Play3r Yes it exists as a mod for use as a module in the editor, which is great when using the editor, but if you want to use it in a game where you don't use the editor (for example dynamic recon ops) it's not possible. Which is why I'm asking if this script can be turned into a standalone mod which you can subscribe to on steam in the same way you can for Vcom ai or lambs?

 

No. In module, you can select which AIs can rearm. If you do that for all sides, you ruin the performance some where, for heavy scenario. So, as stand alone mod, only rearming player's units can be done safely. In MP, the mod needs to be authorized by server admin.

Share this post


Link to post
Share on other sites

This is a very interesting set of scripts that should have been in the vanilla game. The whole  rearming in OFP-Arma series ha always been a clusterfuck.  

 

When a units in a group goes to rearm it mess the whole group movements if the group is in combat mode. SMH 

 

I use have been using script that since arma2 that will always keep one magazine in the unit inventory. The players and AI will always have one magazine and one AT round in inventory.  The group will always be ready to fight. 

 

When controlling AI units in a group rearming can be game breaker when trying to manage a group.

  • Like 1

Share this post


Link to post
Share on other sites

@pierremgiYes of course, I would only like to see a standalone mod which re-arms the players ai squad only, not every unit in the game. I understand that rearming all the units in the game would greatly impact the performance, so I'm not interested in that.

Share this post


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

@pierremgiYes of course, I would only like to see a standalone mod which re-arms the players ai squad only, not every unit in the game. I understand that rearming all the units in the game would greatly impact the performance, so I'm not interested in that.

Done:

https://steamcommunity.com/sharedfiles/filedetails/?id=2867244805

 

  • Haha 1

Share this post


Link to post
Share on other sites

Mate what a legend you are, really appreciate you doing that for me and the community.

I'm going to test it out now and will come back to you. 

  • Like 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

×