Jump to content

Recommended Posts

4 hours ago, Jnr4817 said:

Having healing automatic is awesome.

But an option to order a specific unit to auto heal would be helpful, in some cases.

 

INS Revive, does this. The unit selected can be given a command to autoheal his bro's, if he is not autohealing already, kind of like a reinforcement command.

 

Thanks for all your hard work.

Agreed. I sometimes order AI to particular positions to watch my flanks or rear. They may decide to desert their post as soon as someone goes down. 

  • Like 1

Share this post


Link to post
Share on other sites

New version in front page. Better stability. MP compatible.

I added a new parameter:

 

   <AI CAN HEAL EXTRA GROUP: AI can heal other groups of bros: number from 0 to 2>          // example: 2                       (optional)          default: 1

                                                0: AIs can heal only Bros belonging to the same group

                                                1: as above + AIs can heal any players in Bros

                                                2: AIs can heal any bro (that means some of your guys can quit the formation for assisting some other groups, then be back).

 

By default AIs will heal all bros in their group + any player if usual conditions are met, depending on other parameters (see spoiler) and distance to the wounded.

0 is more restrictive in order to dim the movements (quit group/rejoin group) inside each group. AIs are focused on their group only.

2 is as the former version. Any bros can heal any bros. That means more possibilities of scattered groups (until quieter situation).

  • Like 1
  • Thanks 1

Share this post


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

New version in front page. Better stability. MP compatible.

I added a new parameter:

 

   <AI CAN HEAL EXTRA GROUP: AI can heal other groups of bros: number from 0 to 2>          // example: 2                       (optional)          default: 1

                                                0: AIs can heal only Bros belonging to the same group

                                                1: as above + AIs can heal any players in Bros

                                                2: AIs can heal any bro (that means some of your guys can quit the formation for assisting some other groups, then be back).

 

By default AIs will heal all bros in their group + any player if usual conditions are met, depending on other parameters (see spoiler) and distance to the wounded.

0 is more restrictive in order to dim the movements (quit group/rejoin group) inside each group. AIs are focused on their group only.

2 is as the former version. Any bros can heal any bros. That means more possibilities of scattered groups (until quieter situation).

 

Hey @pierremgi 

 

Just some feedback, initial tests of your new version seems to work well on "hosted" play ( SP / MP ) however on "Dedicated Server" it doesn't seem to / I can't get it to work at all. 

 

Also, on local host ( where it works ) when they ( AI ) go to heal a white flag attaches to the healers, is that a debug feature or a white flag don't shoot me..?

 

Cheers,

 

Rockapes

Share this post


Link to post
Share on other sites

Thanks for feedback.Difficult for me to test on server. So, I'd like more info about your chosen parameters.

Furthermore, any description about AI behavior or even error in rpt file could be helpful. My aim is to run most fir the script on server.

 

Right now, i just make public variable a parameter and run everywhere 2 functions. I'm struggling with the EH handleDamage (public) and where it really fires.

 

Anyway, if some one is so kind as testing on server some modified version:

 

In Init.sqf (important)
 

Spoiler

 


 


MGI_fn_EHDamage = {
  params ["_unit"];
  _unit addEventHandler ["handleDamage", {
    params ["_unit","","_dam"];
    if (side _unit != sideEnemy) then {
      private _veh = objectParent _unit;
      if (!isnull _veh  && isNil {_veh getVariable "incVeh"} && (damage _veh > 0.7 or (!canfire _veh && !canMove _veh) or _dam > 0.7)) then {
        _veh setVariable ["incVeh",true,true];
        _crew = +(crew _veh);
        call {
          if (_dam > 0.7 && {objectParent _unit isKindOf "air"} && {getPosATL _veh select 2 > 30}) exitWith {
            [_unit,_veh] spawn {
              params ["_unit","_veh"];
              waitUntil {isTouchingGround _veh};
              [_unit,_veh] call MGI_fn_BailOut;
            };
          };
          if (damage _veh > 0.7 or (!canMove _veh && !canFire _veh)) exitWith {
            {
              [_x,_veh] spawn MGI_fn_BailOut
            } forEach _crew;
          };
          if (_dam >0.7) then {
            [_unit,_veh] spawn MGI_fn_BailOut;
          };
        };
      };
      if (isNull objectParent _unit && {(count allPlayers == 1 && isPlayer _unit) or MGI_AiRevive}) then {
        if !(_unit getVariable ["uncsious",false]) then {
          _unit setVariable ["uncsious",true,true];
          [_unit, MGI_fn_unconscious] remoteExec ["spawn",2];
        };
      };
      if (!isPlayer _unit or !isMultiplayer) then {_dam min 0.86};
    };
  }];
};

addMissionEventHandler ["entityRespawned",{
  params ["_unit", "_corpse"];
  _unit setVariable ['uncsious',nil,true];
  _unit setVariable ["passedBros",true,true];
  _corpse setVariable ["passedBros",nil,true];
  _unit call MGI_fn_EHDamage;
}];


  MGI_fn_BailOut = compileFinal "
    params ['_unit','_veh'];
    moveOut _unit;
    if (local _unit) then {
      _unit setCaptive true
    } else {
      [_unit,true] remoteExec ['setCaptive',_unit]
    };
    if (!(backpack _unit isKindOf 'B_parachute') && (getPosATL _veh select 2) > 30) then {
      uiSleep random 0.5;
      _p = createVehicle ['Steerable_Parachute_F', (getPosATL _unit) vectorAdd [0,0,1],[],0,'none'];
      uiSleep 0.1;
      if (local _unit) then {
        _unit moveInDriver _p;
        _unit setBehaviour 'combat'
      } else {
        [_unit,_p] remoteExec ['moveInDriver',_unit];
        [_unit,'combat'] remoteExec ['setBehaviour',_unit]
      };
      uiSleep 1;
      if (isnull driver _p) then {
        deleteVehicle _p;
        if (!isplayer _unit) then { _unit setDamage 1};
      };
    } else {
      uiSleep 3;
      if (isnull objectParent _unit && !isTouchingGround _unit) then {_unit setDamage 1};
    };
    uiSleep 3;
    if (!isNil {_veh getVariable 'incVeh'}) then {_veh setVariable ['incVeh',nil]};
    if (_unit getVariable ['uncsious',false]) then {_unit setVariable ['uncsious',false]};
    uisleep 4;
    if (local _unit) then {
      _unit setCaptive false
    } else {
      [_unit,false] remoteExec ['setCaptive',_unit]
    };
  ";
 
 MGI_fn_unconscious = compileFinal  "
    params ['_unit'];
    waituntil {sleep 0.5; (lifeState _unit == 'incapacitated'  or damage _unit == 1 or (!(_unit call BIS_fnc_reviveEnabled) && damage _unit >=0.86))};
    if (['medic',animationState _unit] call bis_fnc_inString) then {
    [_unit,''] remoteExec ['switchMove']
    };
    if (!(_unit call BIS_fnc_reviveEnabled)) then {
      if (local _unit) then {
        _unit setUnconscious true
      } else {
        [_unit,true] remoteExec ['setUnconscious',_unit]
      };
    };
    if (lifeState _unit == 'incapacitated') then {
      if (local _unit) then {
        _unit setCaptive true
      } else {
        [_unit,true] remoteExec ['setCaptive',_unit]
      };
      if (!isNil {_unit getVariable 'myPatient'}) then {
        _unit call MGI_fn_medicRelease
      };
      if (!isPlayer _unit) then {
        [_unit,'Heal Bros','\a3\ui_f\data\IGUI\Cfg\holdactions\holdAction_reviveMedic_ca.paa','\a3\ui_f\data\IGUI\Cfg\holdactions\holdAction_reviveMedic_ca.paa',
      '_this distance _target < 3 && lifeState _target == ""incapacitated"" ','_caller distance _target < 3 ',
        {
          call {
          if (stance _caller == 'PRONE') exitWith {
            _caller playMove 'ainvppnemstpslaywrfldnon_medicother';
          };
          _caller playMove 'ainvpknlmstpslaywrfldnon_medicother';
          };
        },
        {
          if ((diag_tickTime > (_this select 3 select 0) + MGI_react + MGI_BleedOut) && lifeState _target == 'incapacitated') then {
          (_target getVariable ['myMedic',objNull]) call MGI_fn_medicRelease;
          _target call MGI_fn_death;
          }
        },
        {
          if (_target call BIS_fnc_reviveEnabled) then {
            if (local _target) then {
              ['#rev',1,_target] call BIS_fnc_reviveOnState;
              _target setCaptive true
            } else {
              [['#rev',1,_target],BIS_fnc_reviveOnState] remoteExec ['call',_target];
              [_target,true] remoteExec ['setCaptive',_target]
            };
          } else {
            _target setDamage 0;
            if (local _target) then {
              _target setUnconscious false
            } else {
              [_target,false] remoteExec ['setUnconscious',_target]
            };
          };
          if (_target getVariable ['uncsious',false]) then {_target setVariable ['uncsious',false]};
          (_target getVariable ['myMedic',objNull]) spawn MGI_fn_medicRelease;
          _target spawn {
            _target = _this;
            uiSleep 12;
            if (local _target) then {
              _target setCaptive false
            } else {
              if (local _target) then {
                _target setCaptive false
              } else {
                [_target,false] remoteExec ['setCaptive',_target]
              };
            };
          };
        },
        {
          [_caller,''] remoteExec ['switchMove']
        },
        [diag_tickTime],5,12,true,false] remoteExec ['BIS_fnc_holdActionAdd',0,_unit];
      };
    };
    _timer = diag_tickTime;
    while {lifeState _unit == 'incapacitated' && diag_tickTime <= _timer + MGI_react + MGI_BleedOut} do {
      if (local _unit) then {
        _unit setCaptive true
      } else {
        [_unit,true] remoteExec ['setCaptive',_unit]
      };
      if (isnil {_unit getVariable 'myMedic'}) then {
        _medic = _unit call MGI_fn_medic;
        if (!isNull _medic) then {
          [_unit,_medic,_timer] call MGI_fn_911
        };
      };
      uiSleep 2;
    };
    if (lifeState _unit == 'incapacitated' && diag_tickTime > _timer + MGI_react + MGI_BleedOut) exitWith {
      (_unit getVariable ['myMedic',objNull]) call MGI_fn_medicRelease;
      _unit call MGI_fn_death;
    };
    (_unit getVariable ['myMedic',objNull]) call MGI_fn_medicRelease;
    if (_unit getVariable ['uncsious',false]) then {
      _unit setVariable ['uncsious',false]
    };
  ";

if (isServer) then {

  MGI_fn_medic = compileFinal "
    _wnded = _this;
    private '_medic';
    _wnded setVariable ['myMedic',objNull];
    if (isNull _wnded) exitWith {_medic = objNull};
    private _medics = MGI_potentialMedic  select {
      _x distanceSqr _wnded < 40000
      && !isPlayer _x
      && _x != _wnded
      && alive _x
      && lifeState _x != 'incapacitated'
      && isNil {_x getVariable 'myPatient'}
      && [group _x == group _wnded,group _x == group _wnded or isPlayer _wnded,true] select MGI_canHealExtraGrp
    };
    call {
      if (isPlayer _wnded) exitWith {
        _wnded setVariable ['MedicDelay',0];
        _medics
      };
      if ({behaviour _x != 'COMBAT'} count _medics > 0) exitWith {
        _wnded setVariable ['MedicDelay',MGI_react/8];
        _medics = _medics select {behaviour _x != 'COMBAT'};
      };
      if ({(_x targets [true, 300]) isEqualTo []} count _medics > 0) exitWith {
        _wnded setVariable ['MedicDelay',MGI_react/4];
        _medics = _medics select {(_x targets [true, 300]) isEqualTo []};
      };
      if ({{_x == 'MediKit'} count (items _x) > 0} count _medics > 0) exitWith {
        _wnded setVariable ['MedicDelay',MGI_react/2];
        _medics = _medics select {{_x == 'MediKit'} count (items _x) > 0};
      };
      _wnded setVariable ['MedicDelay',MGI_react];
      _medics;
    };
comment "" _medics = +_medics select {
      _x distanceSqr _wnded < 40000
      && !isPlayer _x
      && _x != _wnded
      && alive _x
      && lifeState _x != 'incapacitated'
      && isNil {_x getVariable 'myPatient'}
}"";
    if (count _medics == 0) exitWith {
      _wnded setVariable ['myMedic',nil];
      _medic = objNull;
      _medic
    };
    _medics = +_medics apply {[str(leader _x == _x or !isNull objectParent _x or (group _x != group _wnded)),_x distance _wnded, _x]};
    _medics sort true;

MGI_meds = _medics;

    _medic = _medics select 0 select 2;
    _medic setVariable ['myPatient',_wnded];
    _medic setHitPointDamage ['hitLegs',0];
    _wnded setVariable ['myMedic',_medic];
    if (count units _medic > 1) then {
      _medic setVariable ['MGI_AIgrp',group _medic];
    };
    _medic setVariable ['flee',_medic skill 'courage'];
    _medic
  ";

  MGI_fn_medicRelease = compileFinal "
    _medic = _this;
    _medic forceFlagTexture '';
    if (isNull _medic) exitWith {};
    if (!isNil {_medic getVariable 'myPatient'}) then {
    (_medic getVariable 'myPatient') setVariable ['myMedic',nil]};
    _medic setVariable ['myPatient',nil];
    _medic allowFleeing (1 - (_medic getVariable ['flee',0.5]));
    {_medic enableAI _x} count ['target','autotarget','autocombat','suppression'];
    _medic setBehaviour 'AWARE';
    [_medic] joinSilent (_medic getVariable 'MGI_AIgrp');
    if (_medic != leader _medic) then {
      if (local _medic) then {
        _medic doFollow leader _medic
      } else {
        [_medic,leader _medic] remoteExec ['doFollow',_medic]
      }
    };
    _medic spawn {
      _medic = _this;
      uiSleep 12;
      if (!isNull _medic && lifeState _medic != 'incapacitated' && isNil {_medic getVariable 'myPatient'}) then {
        _medic forceFlagTexture '';
        if (local _medic) then {
          _medic setCaptive false
        } else {
          [_medic,false] remoteExec ['setCaptive',_medic]
        };
      };
    };
  ";

  MGI_fn_sortie = compileFinal "
    params ['_wnded','_medic','_timer'];
    call {
      if (lifeState _wnded == 'incapacitated' && diag_tickTime < _timer + MGI_BleedOut) exitWith {
        _azimuth = _medic getDir _wnded;
        _medic setDir _azimuth;
        _medic removeitem 'FirstAidKit';
        call {
          if (stance _medic == 'PRONE') exitWith {
            _medic playMoveNow 'ainvppnemstpslaywrfldnon_medicother';
          };
          _medic playMoveNow 'ainvpknlmstpslaywrfldnon_medicother';
        };
        uiSleep 5;
        if (lifeState _medic != 'incapacitated' && alive _medic) then {
          if (_wnded call BIS_fnc_reviveEnabled) then {
            if (local _wnded) then {
              ['#rev',1,_wnded] call BIS_fnc_reviveOnState;
              uisleep 0.5;
              _wnded setCaptive true;
            } else {
              [['#rev',1,_wnded],BIS_fnc_reviveOnState] remoteExec ['call',_wnded];
              uisleep 0.5;
              [_wnded,true] remoteExec ['setCaptive', _wnded];
            };
          } else {
            _wnded setDamage 0;
            if (local _wnded) then {
              _wnded setUnconscious false
            } else {
              [_wnded,false] remoteExec ['setUnconscious',_wnded]
            };
          };
          {if (['Heal Bros',(_wnded actionParams _x) select 0] call bis_fnc_inString) then {[ _wnded,_x] call BIS_fnc_holdActionRemove}} count (actionIDs _wnded);
          _wnded setVariable ['uncsious',false];
        };
        uiSleep 2;
        _medic call MGI_fn_medicRelease;
        if (_wnded getVariable ['uncsious',false]) then {_wnded setVariable ['uncsious',false]};
        {_x setDamage 1} forEach (( _wnded nearEntities ['CAManBase',20]) select {side _x getFriend side _wnded < 0.6 && side _x != civilian});
        uiSleep 10;
        if (local _wnded) then {
          _wnded setCaptive false
        } else {
          [_wnded,false] remoteExec ['setCaptive', _wnded]
        };
      };
      if (lifeState _wnded == 'incapacitated' && diag_tickTime > _timer + MGI_BleedOut) exitWith {};
      if (_wnded getVariable ['uncsious',false]) then {
        _wnded setVariable ['uncsious',false];
      };
    };
  ";

  MGI_fn_checkMedic = compileFinal "
    params ['_wnded','_medic','_timer'];
    uiSleep 2;
    while {lifeState _wnded == 'incapacitated' && diag_tickTime < _timer + MGI_BleedOut} do {
      uiSleep 1;
      call {
        if (lifeState _medic == 'incapacitated') exitWith {
          _medic call MGI_fn_medicRelease;
          comment ""_wnded call MGI_fn_medic"";
        };
        if (isnil {_wnded getVariable 'myMedic'}) exitWith {
          _wnded call MGI_fn_medic;
        };
        if (isNull _medic or isnull (_wnded getVariable 'myMedic')) exitWith {
          uisleep (_wnded getVariable ['MedicDelay',0]);
        };
        if (_wnded distance2D _medic < 3 or (_wnded distance2D _medic >3 && unitReady _medic)) exitWith {
          [_wnded,_medic,_timer] spawn {
            params ['_wnded','_medic','_timer'];
            if (_wnded distanceSqr _medic > 9) then {
              waitUntil {sleep 0.5; unitReady _medic};
              _medic doMove getPosATL _wnded;
              uiSleep 3;
            };
            if (!isNull _wnded && !isNull _medic) then {
              [_wnded,_medic,_timer] call MGI_fn_sortie};
          };
        };
      };
    };
    _medic call MGI_fn_medicRelease;
    comment ""_wnded setVariable ['myMedic',nil]"";
    if (_wnded getVariable ['uncsious',false]) then {
      _wnded setVariable ['uncsious',false];
    };
  ";

  MGI_fn_911 = compileFinal "
    params ['_wnded','_medic','_timer'];
    [_wnded,_medic,_timer] spawn MGI_fn_checkMedic;
    if (!isnull _medic) then {
      [_medic] joinSilent grpNull;
      uisleep (_medic getVariable ['MedicDelay',0.3]);
      _medic forceFlagTexture '\A3\Data_F\Flags\Flag_white_CO.paa';
      _medic setCaptive true;
      {_medic disableAI _x} count ['target','autotarget','autocombat','suppression'];
      group _medic setBehaviour 'CARELESS';
      _medic allowFleeing 0;
      _offset = [[0,0],[15, _wnded getRelDir _medic]] select (!isNull objectParent _medic);
      if (!isnull objectParent _medic) then {
        _medic setVariable ['veh',objectParent _medic];
        if (isPlayer driver objectParent _medic && _medic != assignedGunner objectParent _medic) then {
          unassignVehicle _medic;
          doGetOut _medic};
      };
      vehicle _medic doMove (_wnded getpos _offset);
      uiSleep 0.5;
      if (isnull objectParent _medic) then {
        group _medic setSpeedMode 'FULL'
      } else {
        group _medic setSpeedMode 'LIMITED'
      };
      uiSleep 3;
      waitUntil {Sleep 0.5; (unitReady vehicle _medic && canMove vehicle _medic) or {diag_tickTime > _timer + MGI_BleedOut && lifeState _wnded == 'incapacitated'}};
      if ((diag_tickTime > _timer + MGI_BleedOut) && lifeState _wnded == 'incapacitated') exitWith {};
      doStop _medic;
      if (!isnull objectParent _medic) then {
        unassignVehicle _medic;
        doGetOut _medic;
      };
      _medic doMove getpos _wnded;
      _medic setSpeedMode 'FULL';
    };
    waitUntil {uiSleep 1; unitReady _medic};
    uiSleep 3;
    if (isNull _medic or lifeState _medic == 'incapacitated') then {
      if (!isNull _medic) then {_medic call MGI_fn_medicRelease};
      _wnded spawn MGI_fn_unconscious;
    };
  ";

  MGI_fn_death = compileFinal "
    params ['_wnded'];
    if (_wnded getVariable ['uncsious',false]) then {
      _wnded setVariable ['uncsious',false];
    };
    if (!isnil {_wnded getVariable 'myMedic'}) then {
      (_wnded getVariable 'myMedic') setVariable ['myPatient',nil];
      _wnded setVariable ['myMedic',nil];
    };
    if (local _wnded) then {
      _wnded playMoveNow ''
    } else {
      [_wnded,''] remoteExec ['playMoveNow',_wnded]
    };
comment ""   if (!(_wnded call BIS_fnc_reviveEnabled)) then {
[_wnded,false] remoteExec ['setUnconscious',_wnded];
}"";
    if (!isMultiplayer && isplayer _wnded) then {
      _wnded setDamage 0;
      uiSleep 12;
      _wnded setCaptive false;
    } else {
      _wnded setDamage 1;
    };
  ";


  MGI_fn_Revive = {
    MGI_react = "react" call BIS_fnc_getParamValue;
    MGI_BleedOut = "bleedOut" call BIS_fnc_getParamValue;
    MGI_AiRevive = "NoReviveforAi" call BIS_fnc_getParamValue;
    MGI_AIKit = "AIKit" call BIS_fnc_getParamValue;
    MGI_AIMedicTrait = "AIMedicTrait" call BIS_fnc_getParamValue;
    MGI_canHealExtraGrp = "canHealExtraGrp" call BIS_fnc_getParamValue;
    MGI_bros = "bros" call BIS_fnc_getParamValue;
    if (MGI_react == 0) then {MGI_react = 20};
    if (MGI_BleedOut == 0) then {MGI_BleedOut = 120};
    if (MGI_AiRevive == 0) then {MGI_AiRevive = true};
    if (MGI_AIMedicTrait == 0) then {MGI_AIMedicTrait = false};
    if (MGI_canHealExtraGrp == 0) then {MGI_canHealExtraGrp = 1};
    if (MGI_bros == 0) then {MGI_bros = switchableUnits+playableUnits};

    params [["_react",MGI_react,[0]],["_bleedOut",MGI_BleedOut,[0]],["_AiRevive",MGI_AiRevive,[true]],["_kit",MGI_AIKit,[0]],["_AIMedicTrait",MGI_AIMedicTrait,[true]],["_canHealExtraGrp",MGI_canHealExtraGrp,[0]],["_MGI_bros",MGI_bros,[[],WEST,objNull]]];
    MGI_react = _react;
    MGI_BleedOut = _bleedOut;
    MGI_AiRevive = _AiRevive;
    publicVariable "MGI_AiRevive";
    MGI_AIKit = _kit;
    MGI_AIMedicTrait = _AIMedicTrait;
    MGI_canHealExtraGrp = _canHealExtraGrp;

    _MGI_bros spawn {
      params ["_MGI_bros","_bros"];
      if (_MGI_bros isEqualType objNull) then {
        _bros = [_MGI_bros];
        MGI_bros = _bros;
        MGI_potentialMedic = MGI_bros
      } else {
        while {true} do {
          call {
            if (_MGI_bros isEqualType WEST) exitWith {
              {_x setVariable ["passedBros",true,true]} forEach (allUnits select {side _x == _MGI_bros && isnil {_x getVariable "passedBros"} && _x != (missionNamespace getVariable [format ["BIS_SUPP_HQ_%1",_MGI_bros],objNull]) && _x isKindOf "CAManBase"});
            };
            if (allPlayers isEqualTo (switchableUnits + playableUnits)) exitWith {
              {_x setVariable ["passedBros",true,true]} forEach  (allPlayers select {isnil {_x getVariable "passedBros"}});
            };
            if (_MGI_bros isEqualTypeAll objNull) then {
              {_x setVariable ["passedBros",true,true]} forEach (_MGI_bros select {isnil {_x getVariable "passedBros"}});
            };
          };
          _bros = allUnits select {(_x getVariable "passedBros")};
          {
            if (isnil {_x getVariable "passEH"}) then {
              _x setVariable ["passEH",true];
              _x call MGI_fn_EHDamage}
          } forEach _bros;
          MGI_bros = +_bros;
          MGI_potentialMedic = MGI_bros select {
          [true,{_x == "FirstAidKit"} count (items _x) >0,{_x == "MediKit"} count (items _x) >0] select MGI_AIKit
            && [true,_x getUnitTrait "Medic"] select MGI_AIMedicTrait
          };

          {_check = _x; if (!isnil {_check getVariable 'myPatient'} && {_x getVariable 'myMedic' == _check} count MGI_bros  == 0) then {_check setVariable ['myPatient',nil]; _check forceFlagTexture ''} } forEach MGI_potentialMedic;

          uiSleep 5;
        };
      };
    };
  };

  [20,120,true,0,false,1,west] call MGI_fn_Revive;
};


 

 

Thanks for your help.

 

About white flag:

Yes, it was a visual debug and yes white flagged units stops firing and are captive. If you want to remove it, just delete the 3 lines with forceFlagTexture (2 in the fn_medicRelease and one in the fn_911).

 

 

 

Share this post


Link to post
Share on other sites

The chosen parameters ( if you mean for your script ) was just default except for the death time which I made 300 instead of 120.

 

I pasted your script directly into the init.sqf of the missions.

 

On a dedicated server the AI just die like its not firing on them and with players you go down, get the incapcitated picture with option to hold for respawn and after a short period you just suddenly jump back to life with full health. 

 

I will give this test version a try today and leave some feedback.

Share this post


Link to post
Share on other sites

Couldnt get that test version to work on dedicated server either. 

Share this post


Link to post
Share on other sites

God bless you and all you do for us here, Pierre. Thank you for this.

  • Like 2

Share this post


Link to post
Share on other sites

Hi,

I consolidated the PARAMETERS part of the script. Test new version in front page.

 

In SP/MP (without specific parameters in description.ext), if you:

call MGI_fn_revive;  // default parameters apply:

                                delay:20sec., (decision time for AI to heal someone)

                                bleedout time: 120 sec. (extra time after delay),

                               AI can revive/heal (main switch of this script),

                               You don't need First aid kit (but one is removed if any),

                               you don't need to be medic,

                               AI can revive the units in its group only + any player (belonging to bros)

                               bros are playable/switchable units.

 

In SP/MP, you can ALWAYS override all stuff writing your own array of parameters:

[10,300,true,1,true,0,west]  call MGI_fn_Revive;

                                 Mind for the exact number and types of parameters

                                 the last one (bros) is the concerned units. allowed types are:

                                                                                                    side,

                                                                                                   single unit. In that case, for obvious reason, all units in its group are concerned

                                                                                                   group,

                                                                                                   array of units (never mind the group or the side)

                                 Furthermore, you can add any unit in script or in game, setting a variable on it. Example: myUnit setVariable ["passedBros",true,true];

 

 

In MP, you can add a bunch of parameters in description.ext and then call the function without parameters array.

This way you can choose all parameters you want at mission start (lobby). See important note below.

 

class Params

{

    class NoReviveforAi
    {
      title = "friendly AI units can be healed while unconscious";
      texts[] = {"no","yes"};
      values[] = {1,0};
      default = 0;
      isGlobal = 1;
    };
    class react
    {
      title = "reaction delay for providing assistance";
      texts[] = {"0","10","20","30","60","120"};
      values[] = {0,10,20,30,60,120};
      default = 20;

    };
    class bleedout
    {
      title = "duration of unconsciousness before death/respawn (non including reaction delay above)";
      texts[] = {"30","60","120","180","300","600"};
      values[] = {30,60,120,180,300,600};
      default = 120;

    };
    class AIKit
    {
      title = "Mandatory kit to heal";
      texts[] = {"none","First aid kit","Medic kit"};
      values[] = {0,1,2};
      default = 0;

    };
    class AIMedicTrait
    {
      title = "Medic trait mandatory";
      texts[] = {"no","yes"};
      values[] = {0,1};
      default = 0;

    };
    class canHealExtraGrp
    {
      title = "Ai bro can heal some other bros not belonging to player's group";
      texts[] = {"no, heal his own group only","his group, and other players only","sure! all possible Bros"};
      values[] = {0,1,2};
      default = 1;

    };
    class bros
    {
      title = "Who are bros?";
      texts[] = {"players' group","all U.S."};
      values[] = {0,1};
      default = 0;

    };
};

 

NB1: For the last parameter (class Bro), you need to script what you want in accordance with your texts, inside the MGI_fn_Revive here:

      if (MGI_bros isEqualType 0) then {
      MGI_bros = [hubert,west] select _MGI_bros // modify the options you want here (see allowed types above).

       ............. do not modify the else code.

NB2: then call the function without parameter. don't forget an array of parameters will override these options.

 

 

 

If you have some feedback on MP usage, please detail what is working or not and, as far as possible, parameters used and situations (at start, when respawning,..) There are so much situations to test! Thanks for your attention.

 

  • Like 2
  • Thanks 1

Share this post


Link to post
Share on other sites

Will try out this weekend, thanks for the hard work.

  • Like 1

Share this post


Link to post
Share on other sites

Today's version tested in SP /MP hosted and JIP.

Be cautious with plenty of bros and many players. I don't have any feedback on PCs workload. Interested in tests with 3 players and more, and at least 2 infantry groups for bros.

Thanks

  • Like 1

Share this post


Link to post
Share on other sites

I have tested with 2 players ( last script ) and over 6 fireteams and all worked reasonably well. No lag to speak of on my basic dedi server ( not due to your heal script anyways ). Will give the new one a go today most likely. Thanks for keeping it a moving project ?

Oh on a side note, ignore if Im wrong but I think the examples to call the script need to be updated to "MGI_fn_Revive" as I couldnt get the script to work if I used the examples for spawned in or scripted units.

  • Like 2

Share this post


Link to post
Share on other sites

Tested on hosted with 4 players and several AI groups. No issues with lag. Will test on dedicated soon, just need to finish mission.

 

As for calling the script, what is the best way to call from init.sqf?

Instead of just posting in init, i want to call it for a mission I am building.

Call or spawn or execVM?

 

Going to make a file called MGI_Revive.sqf

 

 

Share this post


Link to post
Share on other sites

Let as is in init.sqf. call is fine.

If you want to execVM something, the best bet is to add all functions in different sqf and define them in description.ext with cfgFunctions

If you try to execVM all the stuff at once, that can be laggy (at first execution).

  • Like 1

Share this post


Link to post
Share on other sites

The MGI_fn_Revive is now fully compatible with spawned units you want to be bros.

Furthermore, it supports multiple lines (needs a short delay), like this:

 

[20,120,true,0,false,1,playableUnits + switchableUnits] call MGI_fn_Revive;
sleep 0.5;
[20,120,true,0,false,1,independent] call MGI_fn_Revive;

 

You still can add any unit with: yourUnit setVariable ["passedBros",true,true];

  • Like 3

Share this post


Link to post
Share on other sites

Hi,

I definitely (til further idea) abandon the couple of commands: domove / unitready , subject to too many difficulties with AIs in MP. Especially to avoid some healing animation before the medic reaches the wounded). Not sure, at this time, the unitReady is fine for that in MP...

So I decided to write a new version with addWaypoint and waypoint completion test to start the healing action after the move to wounded. Not perfect, especially when a potential medic is in vehicle, needs to disembark and join the victim, then heal him. I'm still having some "distant" healing...

 

Anyway, I hope this last version is ever more reliable. I added a new param for those who would have the medic white flagged during their task (hidden by default).

See front page.

Thanks for feedback.

  • Like 3

Share this post


Link to post
Share on other sites

Hi  @pierremgi 

I ran your script but when I come incapacitated the medics wont come to heal me. Medics are in my group. Running from editor in multiplayer mode. What's wrong?

 

thx


Edit: My description.ext if it's that

Spoiler



respawn = 2;
respawnDelay = 10;

ReviveMode = 1;                         //0: disabled, 1: enabled, 2: controlled by player attributes
ReviveUnconsciousStateMode = 0;         //0: basic, 1: advanced, 2: realistic
ReviveRequiredTrait = 0;                //0: none, 1: medic trait is required
ReviveRequiredItems = 0;                //0: none, 1: medkit, 2: medkit or first aid kit
ReviveRequiredItemsFakConsumed = 0;     //0: first aid kit is not consumed upon revive, 1: first aid kit is consumed
ReviveDelay = 6;                        //time needed to revive someone (in secs)
ReviveMedicSpeedMultiplier = 2;         //speed multiplier for revive performed by medic
ReviveForceRespawnDelay = 0;            //time needed to perform force respawn (in secs)
ReviveBleedOutDelay = 120;              //unconscious state duration (in secs)


 

 

Share this post


Link to post
Share on other sites

No clue at this time. I experienced some rare cases like yours. It's not often. I'm trying to understand if this is due to too heavy scripted scenario (share of resources), or some unwanted cases.

On the other hand, in MP, other players are supposed to heal you. Not saying it's an excuse but that lets me some time to fix it... if possible.

Share this post


Link to post
Share on other sites
22 hours ago, gc8 said:

Hi  @pierremgi 

I ran your script but when I come incapacitated the medics wont come to heal me. Medics are in my group. Running from editor in multiplayer mode. What's wrong?

 

thx


Edit: My description.ext if it's that

  Reveal hidden contents

 



respawn = 2;
respawnDelay = 10;

ReviveMode = 1;                         //0: disabled, 1: enabled, 2: controlled by player attributes
ReviveUnconsciousStateMode = 0;         //0: basic, 1: advanced, 2: realistic
ReviveRequiredTrait = 0;                //0: none, 1: medic trait is required
ReviveRequiredItems = 0;                //0: none, 1: medkit, 2: medkit or first aid kit
ReviveRequiredItemsFakConsumed = 0;     //0: first aid kit is not consumed upon revive, 1: first aid kit is consumed
ReviveDelay = 6;                        //time needed to revive someone (in secs)
ReviveMedicSpeedMultiplier = 2;         //speed multiplier for revive performed by medic
ReviveForceRespawnDelay = 0;            //time needed to perform force respawn (in secs)
ReviveBleedOutDelay = 120;              //unconscious state duration (in secs)

 

 

 

 

 

Are you loading @pierremgi script in the init.sqf? I have whole script in init.sqf and dont have many issues at all except the odd random which is just Arma

Share this post


Link to post
Share on other sites
22 minutes ago, Rockapes said:

Are you loading @pierremgi script in the init.sqf? I have whole script in init.sqf and dont have many issues at all except the odd random which is just Arma

 

Yes. i noticed the heal command is issued when I respawn...

Share this post


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

 

Yes. i noticed the heal command is issued when I respawn...

Respawn is not an issue by itself.  Be sure I tested and re-tested for months this script!

The handleDamage EH works through respawn. You're always counted as MGI_bros (you can check this variable in debug console).

I'd rather check your scripts and mods.

- As any other scripts, this one have to share the Arma engine resource (specifically scheduler). Too many (really too many) scripts can lead to hanging code(s), even if properly written;

- some mods are absolutely too preemptive, playing for themselves. I don't recommend mixing ACE or any other medical/revive script with this one. I can't and I don't want digging some foreign code to be compatible (if it could be possible!).

Share this post


Link to post
Share on other sites

@pierremgi Only thing I have in init.sqf is your script. i disabled all the mods but still they wont heal me

Share this post


Link to post
Share on other sites
Just now, gc8 said:

@pierremgi Only thing I have in init.sqf is your script. i disabled all the mods but still they wont heal me

????

Are you independent, west, east, civilian???

The script must be a little bit adapted if your "bros" are not a side, or the playableUnits, or a group...

Share this post


Link to post
Share on other sites
8 minutes ago, pierremgi said:

????

Are you independent, west, east, civilian???

The script must be a little bit adapted if your "bros" are not a side, or the playableUnits, or a group...

 

West.

Do I need to make the medics "Bros" ? I tried that already though...

Share this post


Link to post
Share on other sites
4 minutes ago, gc8 said:

 

West.

Do I need to make the medics "Bros" ? I tried that already though...

No. But I can't help without your code. You can PM it.

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

×