Jump to content

Recommended Posts

                                                                                               AI INFANTRY RESPAWN SP/MP

 

Hi all,

Here is a script to allow AIs respawning according to parameters. This works in SP or MP.

Only infantry (on foot AI) concerned as far as the killed AIs while in vehicles is the object of a second script.

 

parameters:   SIDE(S)  /  POSITIONS /   DELAY   /   MIN UNITS IN GROUPS  /   REMAINING LOADOUT

Spoiler

 

[

  <side or array of side(s)>, //    example:  [WEST,EAST,RESISTANCE,CIVILIAN]  or   RESITANCE        (optional)    default: [WEST,EAST,RESISTANCE] - only these sides can respawn

  <string or array if string(s) for respawn position>,  // examples: "marker1" or ["start","mk1",""].   (optional)   default:  "start"
                                                 you need one option for each side, so:

                                                    If more sides, completed by "start" for all remaining declared sides.
                                                    ([west,east,resistance] and ["mk1"] or "mk1" give... ["mk1","start","start"] )

                                                    if this string is a marker name, this position is chosen,

                                                    or "start" (not a marker name) gives the positions of units at start,

                                                    or "death", "", any unused string, gives the position of death for each unit,

  <number, seconds (minimum) before respawn>,  // example: 15                                             (optional)           default: 10

                                                takes 15 seconds to respawn a unit after death if the parameter to follow (min unit in groups)  allows that,

  <number, minimum for remaining AIs before regenerating the group>, // example: 3  (optional)  default: 144 (any whole group, so disabled feature)

                                                if nil or not defined, the units respawns without other delay than the previous parameter,

                                                same for any number above the group headcount (at start),

                                                the number defines the minimum remaining souls in any group, before the units can respawn (delay after death can apply if ongoing).

  <boolean, respawn with same loadout than when died>          // example: true                       (optional)          default: false

                                                the magazines are decreasing if set to true, there is no automatic rearming

                                                by default (false), the units recover their initial loadout

]

 

 

 

Examples:

[] spawn MGI_fnc_unitRespawn       //   [] passed  as parameter  equals to [ [WEST,EAST,RESISTANCE,CIVILIAN], "start", 10, 144, false]

                    All ai units can respawn on their position at start, after 10 sec delay, with their initial loadout.

 

[ [WEST,EAST], ["mrk1","death","start",""], nil, 3 ] spawn MGI_fnc_unitRespawn      //    equals to [ [WEST,EAST], ["mrk1","death"], 15, 3, false]

                   here, only WEST & EAST ai units can respawn:

                       - on the marker "mk1" if any, on death position if not, for BLUFOR

                       - on the position of death for OPFOR,

                  (other strings in positions array are useless), 10 second delay (default), if their group headcount is below 3 (delay already started at death), with their initial loadout.

                        


Code to be run on server. (trigger, server only, non-repeatable, condition true)   or initServer.sqf
 

Spoiler

 


MGI_fnc_unitRespawnScript = {
  if (!isServer && hasInterface) exitWith {};
  params [["_sides",[WEST,EAST,RESISTANCE],[[WEST],WEST],[]],["_positions","start",["",["","","",""]],[]],["_delay",10,[0]],["_waitForGrp",144,[0]],["_existingLO",false,[true]]];
  private ["_pos","_positionArray"];
  MGIrespDelay = _delay max 2;
  MGIwaitForGrp = _waitForGrp;
  MGIexistingLO = _existingLO;

  fn_pos = {
    params ["_position","_pos"];
    call {
      if !(getMarkerPos _position isEqualTo [0,0,0]) exitWith {_pos = getMarkerPos _position};
      if (_position == "start") exitWith {_pos = getPos _x};
        _pos = [0,0,0];
     };
    _pos
  };
  if (_sides isEqualType WEST) then {_sides = [_sides]};
  if (_positions isEqualType "") then { _positions = [_positions]};
  if (_positions isEqualType []) then {
    _nbrSide = count _sides;
    _nbrPos = count _positions;
    if (_nbrPos < _nbrSide) then {
      for "_i" from 0 to (_nbrSide - _nbrPos - 1) do {
        _positions pushback "start";
      };
    };
  };

  _positionArray = [];
  for "_i" from 0 to count _sides - 1 do {
    _positionArray pushback (_sides select _i);
    _positionArray pushback (_positions select _i);
  };

  while {true} do {
    sleep 1;
    _allUnits = allUnits select {isnull objectParent _x && !isplayer _x && local _x};
    {
      if (!(_x getVariable ["MGIrespOK",false]) && (side _x in _sides)) then {
        _side = side _x;
        _position = _positionArray select ((_positionArray find _side) + 1);
        _pos = _position call fn_pos;
        _oldGrp = group _x;
        if (isnil {_oldGrp getVariable ["_squadNbr", nil]}) then {
          _oldGrp setVariable ["_squadNbr", count units _oldGrp]
        };
        _x setVariable ["MGIrespDATA",[typeOf _x ,_pos, side _x, getdir _x, _oldGrp,_oldGrp getVariable "_squadNbr"]];
        if !(MGIexistingLO) then {
          _x setVariable ["MGIloadout",getUnitLoadout _x]
        };
        _x setVariable ["MGIrespOK",true];
      };
    } foreach _allUnits;
  };
};


addMissionEventHandler ["entityKilled",{
  _killed = _this select 0;
  if (_killed getVariable ["MGIrespOK",false]) then {
    _killed spawn {
      private "_loadout";
      _killed = _this;
      _type = (_killed getVariable "MGIrespDATA") select 0;
      _pos = (_killed getVariable "MGIrespDATA") select 1;
      _side = (_killed getVariable "MGIrespDATA") select 2;
      _dir = (_killed getVariable "MGIrespDATA") select 3;
      _oldGrp = (_killed getVariable "MGIrespDATA") select 4;
      _squadNbr = (_killed getVariable "MGIrespDATA") select 5;
      if (MGIexistingLO) then {_loadout = getUnitLoadout _killed};
      if !(MGIexistingLO) then {_loadout = _killed getVariable "MGIloadout"};
      if (_pos isEqualTo [0,0,0]) then {_pos = getpos _killed};
      sleep MGIrespDelay;
      waitUntil {({alive _x} count units _oldGrp < (MGIwaitForGrp min _squadNbr)) or (_oldGrp getVariable ["fillIt",false])};
      _newbie = _oldGrp createUnit [_type, _pos, [],0,"CAN_COLLIDE"];
      _newbie setDir _dir;
      [_newbie] joinSilent _oldGrp;
      _oldGrp setVariable ["fillIt", true];
      if (({alive _x} count units _oldGrp == _squadNbr)) then {
        _oldGrp setVariable ["fillIt", false]
      };
      _newbie setUnitLoadout _loadout;
      sleep (MGIrespDelay +0.1);
      _killed setVariable ["MGIrespDATA",nil];
      _killed setVariable ["MGIrespOK",nil];
       deleteVehicle _killed;
    };
  };
}];

[[WEST,EAST,RESISTANCE,CIVILIAN],"start",15,3,true] spawn MGI_fnc_unitRespawnScript;  // example

 

 

 

 

  • Like 7
  • Thanks 2

Share this post


Link to post
Share on other sites

Just been trying this respawn function out. That is one incredibly compact and clever bit of code !

Edited by Mike Goode

Share this post


Link to post
Share on other sites

I can't for the life of me figure out how to make it work.. I've set up a server only, condition true, non repeatable trigger with the script in it's init, but when i go to test it by hosting a lan server and zeus bolting an AI soldier he still spawns in one of 4 respawn_west markers i've set up on different parts of the map.. any thoughts?

a really simplified visual example of pretty much what i'm trying to do:  s4nq6a.jpg

Share this post


Link to post
Share on other sites

In your picture, I understand you don't have specific groups, but rather some units inside areas at start.

 

you just have to run:

[[WEST],"start",15,nil,true] spawn MGI_fnc_unitRespawn;

All west units will respawn at their initial position.

If you need more conditions, you can add them in this line:

_allUnits = allUnits select {isnull objectParent _x && !isplayer _x && local _x};

 

 

 

Share this post


Link to post
Share on other sites

Nice release!

Although I'm confused on line 3 of your code:

why the strings for expectedArrayCount? Can't this be just a number and call it quits?

Regardless, this'll be useful in the future. Excellent work.

Share this post


Link to post
Share on other sites

@pierremgi hello! Good days. I want to respawn with my player and my AI group members on a marker when my player dies in a single player mission. How can I do this? I need help. Can you help me?

Share this post


Link to post
Share on other sites

With this script (or the "heal and revive" module) you can respawn on a marker, as all units in your group, because you have the choice of who can be healed/ respawned, but there is nothing implemented for teleporting all your guys at your respawn position. It's specific. You can add a code for that.

No real time to do that yet.

Share this post


Link to post
Share on other sites

Hey @pierremgi thank you so much for this script, great work. I have a question if you have time for it, was wondering if it's possible to disable the respawn on specific AIs with a line in their init or in a trigger, or exclude playables from respawning? Currently all IND are respawning as I wish but I would like to exclude the AI in the player-controlled group from respawning. (They are playable as well). So basically wish when a group member dies, he dies, but the rest of ind non playable can still respawn as per the script. 

Thanks again. 

Share this post


Link to post
Share on other sites

In the MissionEH "entityKilled", just add the condition you want. For example:

addMissionEventHandler ["entityKilled",{

  _killed = _this select 0;

  if (_killed getVariable ["MGIrespOK",false] && !( _killed in (playableUnits + switchableUnits) ) ) then {...

Share this post


Link to post
Share on other sites
6 hours ago, pierremgi said:

In the MissionEH "entityKilled", just add the condition you want. For example:

addMissionEventHandler ["entityKilled",{

  _killed = _this select 0;

  if (_killed getVariable ["MGIrespOK",false]  && !( _killed in (playableUnits + switchableUnits) ) ) then {...


I can't get it to work / don't know how to correctly implement the condition. But thanks for your time and the reply. Cheers

Share this post


Link to post
Share on other sites

did you replace :

(_killed getVariable ["MGIrespOK",false])

by :

(_killed getVariable ["MGIrespOK",false] && !( _killed in (playableUnits + switchableUnits) ) )

?

That could be enough to prevent all playable units (SP or MP) from respawning (and that works for me).

Share this post


Link to post
Share on other sites

Ah yes confirm it's working. Thank you man. When I tried it first I had A3 wounding system active, which somehow makes the playables still respawn. So, i'm off to dig into those files to see what causes the conflict. 
Again, thanks for the script! 

Share this post


Link to post
Share on other sites

As reminder, this code is also a module, more elaborated and compliant with other ones like player simple respawn (SP) and vehicle respawn (with crew).

Share this post


Link to post
Share on other sites

So I ran into an issue with this script, and wanted to know if there is a workaround. So I am using a group  of OPFOR that I have converted into INDEPENDENT. I have set up the script to work with only on INDEPENDENT. However, when the units respawn they revert back to their original OPFOR. 

 

I have them listed as independent due me having other OPFOR units that I do not wish to be affect by this script. 

Share this post


Link to post
Share on other sites

Thanks for the feedback. Corrected. You can add a non-present leader to change the side.

I modified also the name of the function for module compatibility (but don't use the AI can respawn module and this script together).

Share this post


Link to post
Share on other sites

Hi ! I tried your script, it is working fine. I just copy/paste it in the ini field in the Arma Editor.

But how would you make it work as an external script ? I tried to create a respawn.sqf script called by execVm "respawn.sqf" but it doesn't work.

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

×