Jump to content
Sign in to follow this  
demonized

Automated Medic [SCRIPT]

Recommended Posts

Automated medic v 1.13

updated to v 1.13 - 15 July 2011

OA required as discovered by a Arma 2 only user.

If you were ever tired of micro managing AI medics in your group, look no further, here is the automated version of the AI medic in player group.

It also makes any unit able to act as medic when "fullAuto" or "closeMedic" option is used, not just medics.

Also can be used on mutiple units in same group.

Note: this script is really only needed in groups were players is leader, as AI leaders manage this themseves pretty god, but it can work just fine on AI groups aswell.

Credits:

F2k Sel - for being my muse, the initial script was created upon an idea/wish he had.

BI Community - always, would never have achieved anything without you.

Issues:

* ingame squad command issued by leader to medic wich is STOP or TAKE COVER, will halt the script.

* first aid modules light support added in v 1.11.

* not created for MP, possible implementation in v 1.2 - test MP comp in v 1.13

Changelog v1.13:

* added Mash ability for medic on fallback position.

* medic can now respawn at mash, with x amount of lives option.

* optional longer heal animation depending on severity of wounded, still somewhat simple. to do: improve.

* different color coding for multiple medics and action text.

* improved multiple medics handling, medics wont all go to same wounded, even if he is nearest to them.

* bug fix typo in dynamic name generator when using multiple non named units.

* MP compatibility test, need feedback, added check if leader is local else exit, should in theory work.

* code tweaks and others i forget.

v 1.12

* any unit can act as medic if "fullAuto" or "closeMedic" option is used.

* added reset fallback position action when a fallbcak position is created.

v 1.11

* added temp fix for use with First aid modules, uses same short heal animation as before.

* added dynamic fix for error when medic unit was not named.

v 1.1

* added fallback position option via action.

* option to create marker on fallback position.

* increased finnish distance from 2 to 3 to avoid AI stop bug from v 1.0.

* options to prioritize by cant walk, most wounded, nearest wounded.

* all options can be combined, look in top of script for more info.

* as always, optimisation of code and executing.

v 1.0

* initial release.

MP Compatibility:

in v 1.13 im testing out the local command:

if (!(local (leader (group _medic)))) exitWith {};

wich should in theory exit all that is not local to the group leader, since AI is local to leader of group in MP.

It have no impact in SP games, since all is local there.

Automated AI medic will start once leader gives the command to heal another unit in group, or activates the action (new in v 1.1)

AI medic will depending on what option used, start healing all wounded units in his own group.

AI medic will go to closest unit, heal, then next nearest wounded, depending on priority options.

You can use

"fullAuto" for auto medic. - medic will start healing any units that gets wounded, unless ordered to STOP or TAKE COVER/HIDE.

"closeMedic" for healing units nearest to medics position first. - Recomended - player is given action "MEDIC!!!"

"closeWounded" for healing nearest units closest to the unit leader issues a heal command on via squad menu. - medic starts to heal any wounded after healing the unit the player ordered him to heal via squad command.

+ other options as priority, fallback/wait until needed position etc.

save script as medicAuto.sqf and place script in your mission folder, instructions in top of script.

script and info here:

/*
Automated medic v 1.13
by Demonized.

When medic is issued a heal command by leader of group, medic will continue to heal rest of groups wounded units.
Medic will attempt to heal the clostest wounded unit from his position, or the most critical or units not able to walk, based on options set.
Until ordered to one of these commands "WAIT","ATTACK","HIDE","REARM","GET IN","STOP" or the medic is dead.

WARNING!! if you have set medic to STOP or HIDE (take cover) ingame via squad menu commands, the auto part will fail, game engine overwrites all other commands.
The script itself will set the unit to stop and it will show stop in unit icon, but this is ok - but you need to keep track of if you order unit yourself to stop or hide,
and then call him back to formation or move to somewhere to fix it.
["WAIT","ATTACK","HIDE","REARM","GET IN","HIDE","STOP"] these commands will abort or cancel healing run.

execute: place in initline of medic/s.  (example here is initline placement, or use name instead of this)
	option 1: - start healing run from the unit ordered to heal by leader, then proceed to next nearest wounded unit.
	_null = [this,"closeWounded"] execVM "medicAuto.sqf";

	option 2: - start healing run from medics actual position, healing nearest wounded unit to medics position,
	note that this is a action added to the leader.
	_null = [this,"closeMedic"] execVM "medicAuto.sqf";

	option 3: - fully automated medic beheaviour, once a team member is wounded, medic rushes to his position to heal.
	note: may be hasardous for medic health if under fire, but medic will react properly firing/covering etc depending on beheaviour of medic as normal.
	_null = [this,"fullAuto"] execVM "medicAuto.sqf";

_fallBack set to true is very valuable if you setup your unit behind your group in a "safe position", he will return to this position when finnished healing or aborted.
it can utilize all below optionals, but beware that using the STOP or HIDE command ingame will halt the unit and this script, or abort current healing run.

option 2 is most recomended.

*/

// optionals:  true/false = on/off
_canWalk = false;  	// if units should be prioritized nearest unit wich cannot walk, closest wounded is ignored if someone cannot walk.
_critical = false;  	// if units should be prioritized by amount of damage, nearest is ignored, amount of damage is priority.
_fallBack = false;  	// if medic should return to his original position after heal prior to healing start. works with "fullAuto" AND "closeMedic"
_maxDist = 500;  		// x = meters - medic will not attempt to return to a position or heal units more than this away from the medic.
_optHeal = true;		// if medic should heal longer based on amount of damage to the wounded unit.

// this below options is relying on eachother, adds a action to leader, it will make the medic mark any position he is currently in as his fallback position, it can be used with any of the options.
_opFallBack = true;  	// make the current medic position as his fallback position after healing team members until fallback is reset.
_showMarker = true;  	// when medic is given a fallBackPosition, there will be a marker on map created at the fallback position.

_buildMash = true;  	// only usable with _opFallBack set to true, medic build a mash tent at fallback position, use together with _fallBack = true to have fallbacks without building mash or simply dont use this option.
_mashInit = "";		// set the init of the mash here if desired, can be for example naming it so you can respawn at it, run another script on it etc... make sure to use ""double"" or 'single' inside the outer "quotes". for example "myTent = this" will name the tent to myTent, wich you can use outside of the script for example for respawns.
_respawn = true;		// if medic should respawn at mash when killed, requires _buildMash = true;
_timer = 10;		// timer in seconds until medic respawns after death.
_lives = 3;			// how many respawns medic has, 0 means unlimited.


// DO NOT EDIT BELOW THIS LINE //

_idRemoval = {
//_ret = [_medic,_idx] call _idRemoval;
_medic = _this select 0;
_arr = _medic getVariable ["DMZ_AM_actionsOrespawn", []];
_arr = _arr + [(_this select 1)];
_medic setVariable ["DMZ_AM_actionsOrespawn", _arr, true];
_medic setVariable ["DMZ_AM_leader", (leader (group _medic)), true];
};

_respawnEH = {
//_null = _medic spawn _respawnEH;
_idx = _this addEventHandler ["killed", {
	_null = (_this select 0) spawn {
		_mash = _this getVariable ["DMZ_AM_mashbuilt", _this];
		_pos = _this getVariable ["DMZ_AM_pos", _this];
		_script = _this getVariable ["DMZ_AM_script", "none"];
		_mark = _this getVariable ["DMZ_AM_marker", "none"];
		_timer = _this getVariable ["DMZ_AM_Respawn", 10];
		_lAct = _this getVariable ["DMZ_AM_actionsOrespawn", []];
		_lead = _this getVariable ["DMZ_AM_leader", "none"];
		_lives = _this getVariable ["DMZ_AM_respawn_lives", 0];
		_skill = _this getVariable ["DMZ_AM_respawn_skill", 0];
		_color = _this getVariable ["DMZ_AM_color_used", "#ff0000"];
		_vName = vehicleVarName _this;
		_grp = group _this;
		_type = typeOf _this;
		{_lead removeAction _x} foreach _lAct;

		if (_lives == 0) exitWith {};

		sleep _timer;

		_cnt = 0;
		_dName = "DMZ_AM_dead";
		while {!isNil (_dName)} do {
			_cnt = _cnt + 1;
			_dName = format["DMZ_AM_dead_%1",_cnt];
		};
		_this SetVehicleVarName _dName;
		_this Call Compile Format ["%1=_This ; PublicVariable ""%1""",_dName];
		waitUntil {(vehicleVarName _this) == _dName};

		_unit = _grp createUnit [_type, _pos, [], 0, "NONE"];
		_unit SetVehicleVarName _vName;
		_unit Call Compile Format ["%1=_This ; PublicVariable ""%1""",_vName];

		_unit setskill _skill;

		_vars = [_mash,false,true,_pos,_mark,_script,_timer,_lead,_lives,_color];
		_sel = 0;
		{
			_unit setVariable [_x, (_vars select _sel), true];
			_sel = _sel + 1;
		} foreach ["DMZ_AM_mashbuilt","DMZ_AM_mash","DMZ_AM_pos_set","DMZ_AM_pos","DMZ_AM_marker","DMZ_AM_script","DMZ_AM_Respawn","DMZ_AM_leader","DMZ_AM_respawn_lives","DMZ_AM_color_used"];

		_script set [0, _unit];
		if (!("DMZ_AM_respawnedEH" in _script)) then {
			_script = _script + ["DMZ_AM_respawnedEH"];
		};
		_null = _script execVM "medicAuto.sqf";

		_unit doMove _pos;
		waitUntil {unitReady _unit};
		doStop _unit;
		_unit setUnitPos "Middle";
	};
}];
_this setVariable ["DMZ_AM_removeEH", _idx, true];
};

_medic = _this select 0;
if (!(local (leader (group _medic)))) exitWith {};

// different color selection for multiple medics in same group using this script.
_color = "#ff0000";	// color used for action text, default is RED, place color code inside "qoutes" more colors to be found here   http://html-color-codes.info/
if (!("DMZ_AM_respawnedEH" in _this) AND _opFallBack AND ({_x in ["closeWounded","closeMedic","fullAuto"]} count _this) != 0) then {
_grpLead = leader (group _medic);
sleep (random 1);
waitUntil {sleep 1; (_grpLead getVariable ["DMZ_AM_color", true])};
_grpLead setVariable ["DMZ_AM_color", false, true];

_col = _grpLead getVariable ["DMZ_AM_color_used", []];
if (!("red" in _col)) then {
	_col = _col + ["red"]; _color = "#ff0000";
} else {
	if (!("blue" in _col)) then {
		_col = _col + ["blue"]; _color = "#0000FF";
	} else {
		if (!("yellow" in _col)) then {
			_col = _col + ["yellow"]; _color = "#FFFF00";
		} else {
			if (!("purple" in _col)) then {
				_col = _col + ["purple"]; _color = "#A901DB";
			};
		};
	};
};

_grpLead setVariable ["DMZ_AM_color_used", _col, true];
_grpLead setVariable ["DMZ_AM_color", true, true];
_medic setVariable ["DMZ_AM_color_used", _color, true];
};

// respawn function re activate.
if ("DMZ_AM_respawnedEH" in _this) then {
_medic setVariable ["DMZ_AM_Respawn", _timer, true];
_color = _medic getVariable ["DMZ_AM_color_used", "#ff0000"];
_null = _medic spawn _respawnEH;
};

// dynamic fix for unnamed medics.
if (({_x in ["closeWounded","closeMedic","fullAuto"]} count _this) != 0) then {
_vName = vehicleVarName _medic;
if (_vName == "") then {
	_cnt = 0;
	_vName = "DMZ_AM_name";
	while {!isNil (_vName)} do {
		_cnt = _cnt + 1;
		_vName = format["DMZ_AM_name_%1",_cnt];
	};
	_medic SetVehicleVarName _vName;
	_medic Call Compile Format ["%1=_This ; PublicVariable ""%1""",_vName];
};
};

if ("fullAuto" in _this) then {
while {alive _medic} do {
	waitUntil {sleep 1; !alive _medic OR ({alive _x AND (getDammage _x) != 0} count units group _medic) != 0};
	if (alive _medic) then {
		_medic setVariable ["DMZ_AM_available", false, true];
		_null = [_medic,"healingRun"] execVM "medicAuto.sqf";
	};
	waitUntil {sleep 1; !alive _medic OR _medic getVariable ["DMZ_AM_available", true]};
};
};

if ("closeMedic" in _this) then {
_lead = leader (group _medic);
_con1 = format["_target == _this AND alive _target AND alive %1 AND ({alive _x AND (getDammage _x) != 0} count units group _target) != 0 AND (%1 getVariable ['DMZ_AM_available', true])",_medic];
_acN1 = format ["<t color='%1'>MEDIC!!!</t>",_color];
_idx = _lead addAction [_acN1, "medicAuto.sqf", ["action",_medic], 0, false, true, "", _con1];
_ret = [_medic,_idx] call _idRemoval;
};

if ("closeWounded" in _this) then {
{
	_x addEventHandler ["HandleHeal", {
		_medic = _this select 1;
		if (_medic getVariable ["DMZ_AM_available", true]) then {
			_medic setVariable ["DMZ_AM_available", false, true];
			_null = [_medic,"eh","healingRun"] execVM "medicAuto.sqf";
		};
	}];
} foreach units group _medic;
};

if ("closeMedic" in _this OR "closeWounded" in _this) then {
_lead = leader (group _medic);
_con2 = format["_target == _this AND alive _target AND alive %1 AND !(%1 getVariable ['DMZ_AM_available', true])",_medic];
_acN2 = format ["<t color='%1'>MEDIC ABORT!!</t>",_color];
_idx = _lead addAction [_acN2, "medicAuto.sqf", ["abort",_medic], 0, false, true, "", _con2];
_ret = [_medic,_idx] call _idRemoval;
};

if (_opFallBack AND ("closeMedic" in _this OR "closeWounded" in _this OR "fullAuto" in _this)) then {
_lead = leader (group _medic);
_con1 = format["_target == _this AND alive _target AND alive %1 AND (%1 getVariable ['DMZ_AM_available', true]) AND (%1 distance (%1 getVariable ['DMZ_AM_pos', [0,0,0]])) > 5 AND !(%1 getVariable ['DMZ_AM_pos_set', false])",_medic];
_acN1 = format ["<t color='%1'>FALLBACK POSITION MEDIC</t>",_color];
_idx1 = _lead addAction [_acN1, "medicAuto.sqf", ["fallback",_medic], 0, false, true, "", _con1];

_con1 = format["_target == _this AND alive _target AND alive %1 AND (%1 getVariable ['DMZ_AM_available', true]) AND (%1 getVariable ['DMZ_AM_pos_set', false])",_medic];
_acN1 = format ["<t color='%1'>RESET FALLBACK POSITION</t>",_color];
_idx2 = _lead addAction [_acN1, "medicAuto.sqf", ["resetFallback",_medic], 0, false, true, "", _con1];
{_ret = [_medic,_x] call _idRemoval} foreach [_idx1,_idx2];
if (_respawn) then {
	_medic setVariable ["DMZ_AM_script", _this, true];
	_medic setVariable ["DMZ_AM_respawn_skill", (skill _medic), true];

	if (_lives != 0) then {
		_aL = _medic getVariable ["DMZ_AM_respawn_lives", 19999];
		if (_aL == 19999) then {
			_medic setVariable ["DMZ_AM_respawn_lives", _lives, true];
		} else {
			_aL = _aL - 1;
			_medic setVariable ["DMZ_AM_respawn_lives", _aL, true];
		};
	} else {
		_medic setVariable ["DMZ_AM_respawn_lives", 5, true];
	};
};
};

_heal = false;
if ((count _this) >= 4) then {
_arg = _this select 3;
if ("action" in _arg) then {
	_medic = _arg select 1;
	(leader (group _medic)) groupChat "MEDIC!!";
	_heal = true;
};
if ("abort" in _arg) then {
	_medic = _arg select 1;
	_medic setVariable ["DMZ_AM_abort", true, true];
};
if ("resetFallback" in _arg) then {
	_medic = _arg select 1;
	_medic setVariable ["DMZ_AM_pos", [0,0,0], true];
	_medic setVariable ["DMZ_AM_pos_set", false, true];

	if (!(_medic getVariable ["DMZ_AM_mash", true])) then {
		_mash = _medic getVariable ["DMZ_AM_mashbuilt", "none"];
		_mark = _medic getVariable ["DMZ_AM_marker", "none"];
		if (_mash != _medic) then {
			_vName = vehicleVarName _mash;
			deleteVehicle _mash;
			_medic setVariable ["DMZ_AM_mash", true, true];
			waitUntil {isNull _mash};
			_vName = nil;

			_idx = _medic getVariable ["DMZ_AM_removeEH", 9999];
			if (_idx != 9999) then {
				_medic removeEventHandler ["killed", _idx];
			};
		};
		if (_mark != "none") then {
			deleteMarker _mark;
			_medic setVariable ["DMZ_AM_marker", "none", true];
			_mark = nil;
		};
	};
};
if ("fallback" in _arg) then {
	_medic = _arg select 1;
	(leader (group _medic)) groupChat "Medic - setup fallback position";
	doStop _medic;
	_pos = getPos _medic;
	_medic doMove _pos;
	_medic setVariable ["DMZ_AM_pos_set", true, true];
	_medic setVariable ["DMZ_AM_pos", _pos, true];
	sleep 2;
	_medic groupChat "Roger - setting up fallback position";

	//create a marker for fallback position if _showMarker option is enabled.
	if (_showMarker) then {
		_ret = _medic getVariable ["DMZ_AM_marker", "none"];
		if (_ret == "none") then {
			_cnt = 0;
			_mName = "DMZ_AM_Marker";
			while {!isNil (_mName)} do {
				_mName = format["DMZ_AM_Marker_%1",_cnt];
				_cnt = _cnt + 1;
			};
			_mark = createMarkerLocal[_mName,_pos];
			_mark setMarkerShapeLocal "ICON";
			_mark setMarkerTypeLocal "n_med";
			_mark setMarkerTextLocal "Medic Fallback";
			_medic setVariable ["DMZ_AM_marker", _mark, true];

			if (!_respawn) then {
				_medic addEventHandler ["killed", {
					_null = (_this select 0) spawn {
						_ret = _this getVariable ["DMZ_AM_marker", "none"];
						deleteMarker _ret;
					};
				}];
			};
		} else {
			_ret setMarkerPosLocal _pos;
		};
	};

	waitUntil {unitReady _medic};
	doStop _medic;
	_medic setUnitPos "Middle";
	_null = _medic spawn {
		waitUntil {sleep 1; (behaviour _this) in ["COMBAT","STEALTH"] OR !alive _this OR (currentCommand _this) in ["HIDE","MOVE"]};
		if (alive _this) then {_this setUnitPos "AUTO"};
	};

	if (_buildMash AND (_medic getVariable ["DMZ_AM_mash", true])) then {
		_dir = getDir _medic;
		_cd = _dir mod 360;
		_mp = getPos _medic;
		_newX = (_mp select 0) + (sin _cd * 4);
		_newY = (_mp select 1) + (cos _cd * 4);
		_newZ = (_mp select 2);
		_newPos = [_newX, _newY, _newZ];

		_medic setVariable ["DMZ_AM_mash", false, true];
		sleep 2;
		_mash = createVehicle ["MASH_EP1", _newPos, [], 0, "NONE"];
		_mash setPos _newPos;
		_mash setDir (_dir + 180);

		if (_mashInit != "") then {
			_mash setVehicleInit _mashInit;
			processInitCommands;
		};

		_vName = vehicleVarName _mash;
		if (_vName == "") then {
			_cnt = 0;
			_vName = "DMZ_AM_mash";
			while {!isNil (_vName)} do {
				_cnt = _cnt + 1;
				_vName = format["DMZ_AM_mash_%1",_cnt];
			};
			_mash SetVehicleVarName _vName;
			_mash Call Compile Format ["%1=_This ; PublicVariable ""%1""",_vName];
		};

		_medic setVariable ["DMZ_AM_Respawn", _timer, true];
		_medic setVariable ["DMZ_AM_mashbuilt", _mash, true];
		_null = _medic spawn _respawnEH;
		_medic doWatch (leader (group _medic));
		sleep 5;
		_medic doWatch objNull;
	};
};
};

if ("healingRun" in _this OR _heal) then {
_medic setVariable ["DMZ_AM_available", false, true];

// commands that will abort the healing run.
_cansel = ["WAIT","ATTACK","HIDE","REARM","GET IN","HIDE","STOP"];

_orgPos = [];
if (_fallBack OR _opFallBack) then {_orgPos = getPos _medic};
_varPos = _medic getVariable ["DMZ_AM_pos", []];
if (({_x == 0} count _varPos) != 3) then {_orgPos = _varPos};
if ("eh" in _this) then {
	waitUntil {!alive _medic OR unitReady _medic OR (currentCommand _medic) != "HEAL SOLDIER"};
};

_heal = true;
while {_heal} do {
	_dist = _maxDist;
	_grp = group _medic;
	_lead = leader _grp;
	_wounded = _medic;

	// general nearest wounded part, being overwriten by canWalk or critical in that order if activated.
	{
		if (alive _x AND (getDammage _x) != 0 AND alive _medic AND !(_x getVariable ["DMZ_AM_Being_healed", false])) then {
			_dist1 = _medic distance _x;
			if (_dist1 < _dist) then {
				_dist = _dist1;
				_wounded = _x;
			};
		};
	} foreach units _grp;

	// can walk priority part overides general nearest if someone cant walk, nearest unit unable to walk is 1st priority. overwrited by critical if its set to true.
	if (_canWalk) then {
		if (({!canStand _x} count units group _medic) != 0) then {
			_dist = _maxDist;
			{
				_dist1 = _medic distance _x;
				if (_dist1 < _dist AND !canStand _x AND !(_x getVariable ["DMZ_AM_Being_healed", false])) then {
					_dist = _dist1;
					_wounded = _x;
				};
			} foreach units _grp;
		};
	};

	// criticals first part overides canwalk part if anyone is more wounded, most damaged unit is 1st priority. overwrites any other conditions.
	if (_critical) then {
		_dam = 0;
		_dist = _maxDist;
		{
			_dam1 = getDammage _x;
			if (alive _x AND (getDammage _x) != 0 AND alive _medic AND _dam1 > _dam AND !(_x getVariable ["DMZ_AM_Being_healed", false])) then {
				_dist1 = _medic distance _x;
				if (_dist1 < _dist) then {
					_dam = _dam1;
					_wounded = _x;
				};
			};
		} foreach units _grp;
	};
	if (alive _wounded) then {
		_wounded setVariable ["DMZ_AM_Being_healed", true, true];
	};

	// the actual moving and healing part.
	if ((getDammage _wounded) != 0 AND alive _medic) then {
		_move = true;
		while {_move AND alive _wounded AND alive _medic} do {
			_pos = getPos _wounded;
			_medic doMove _pos;
			waitUntil {(getDammage _wounded) == 0 OR (_medic distance _pos) < 3 OR (_wounded distance _pos) > 5 OR !alive _medic OR !alive _wounded OR (currentCommand _medic) in _cansel OR (_medic getVariable ["DMZ_AM_abort", false])};
			if ((getDammage _wounded) == 0 OR (_medic distance _wounded) < 3 OR !alive _medic OR !alive _wounded OR (currentCommand _medic) in _cansel OR (_medic getVariable ["DMZ_AM_abort", false])) then {_move = false};
		};
		if (alive _wounded AND alive _medic AND !((currentCommand _medic) in _cansel) AND !(_medic getVariable ["DMZ_AM_abort", false]) AND (getDammage _wounded) != 0) then {
			if (_optHeal) then {
				if (!(_wounded getVariable ["BIS_IS_inAgony", false])) then {_wounded playMove "AinjPpneMstpSnonWrflDnon_rolltoback"};
				_vector = ((((getPos _wounded select 0) - (getPos _medic select 0)) atan2 ((getPos _wounded select 1) - (getPos _medic select 1))) + 360) % 360;
				_medic setDir _vector;
				_medic playActionNow "walkf";
				while {(getDammage _wounded) != 0 AND alive _wounded AND alive _medic} do {
					_dam = getDammage _wounded;
					_vector = ((((getPos _wounded select 0) - (getPos _medic select 0)) atan2 ((getPos _wounded select 1) - (getPos _medic select 1))) + 360) % 360;
					if ((getDir _medic) != _vector) then {_medic setDir _vector};
					_medic playMove "AinvPknlMstpSnonWrflDnon_medic";
					waitUntil {(animationState _medic) == "AinvPknlMstpSnonWrflDnon_medic" OR !alive _medic OR !alive _wounded};
					if (alive _medic AND alive _wounded) then {_medic playMove "AinvPknlMstpSnonWrflDnon_medic3"};
					waitUntil {(animationState _medic) == "AinvPknlMstpSnonWrflDnon_medic3" OR !alive _medic OR !alive _wounded};
					_wounded setDammage _dam;
					if (alive _medic AND alive _wounded AND _dam > 0.1) then {_wounded setDammage (_dam - 0.1)} else {_wounded setDammage 0};
				};
				if (alive _medic) then {
					_medic playMove "AinvPknlMstpSnonWrflDnon_medicEnd";
					waitUntil {!alive _medic OR !alive _wounded OR (animationState _medic) == "AinvPknlMstpSnonWrflDnon_medicEnd"};
					waitUntil {!alive _medic OR !alive _wounded OR (animationState _medic) != "AinvPknlMstpSnonWrflDnon_medicEnd"};
				};
				if (alive _wounded AND !(_wounded getVariable ["BIS_IS_inAgony", false])) then {
					_wounded playMove "AinjPpneMstpSnonWrflDnon_rolltofront";
					_wounded playMove "amovpknlmstpsraswrfldnon_amovppnemstpsraswrfldnon";
				};

			} else {
				_wounded action ["heal", _medic];
				sleep 3;
			};
			if (alive _wounded AND alive _medic) then {_wounded setDammage 0};
			_wounded setVariable ["DMZ_AM_Being_healed", false, true];

			// if first aid modules is used.
			if ((_wounded getVariable ["BIS_IS_inAgony", false]) AND alive _medic AND alive _wounded) then {
				{_wounded setVariable [_x,0,true]} foreach ["head_hit","body","hands","legs","bloodlossPerSecond","bloodloss"];
				_wounded setVariable ["BIS_IS_inAgony",false];
			};

			waitUntil {!alive _medic OR !alive _wounded OR (getDammage _wounded) == 0};
			_medic doFollow _lead;
			waitUntil {unitReady _medic OR (currentCommand _medic) in _cansel};
		};
	};

	if ((({(getDammage _x) != 0} count units group _medic) == 0 OR (_medic getVariable ["DMZ_AM_abort", false])) AND alive _medic) then {
		_heal = false;
		_medic setVariable ["DMZ_AM_available", true, true];
		_medic doFollow _lead;
		if ((count _orgPos) != 0) then {
			if (_medic getVariable ["DMZ_AM_abort", false]) then {
				_medic groupChat "aborted - returning to fallback position";
			} else {
				_medic groupChat "no more wounded - returning to fallback position";
			};
		} else {
			_medic groupChat "no more wounded - returning to formation";
		};
	};
	if ((currentCommand _medic) in _cansel OR !alive _medic) then {
		if (alive _medic AND _heal) then {_medic groupChat "aborted"};
		_heal = false;
	};
};
if (alive _medic) then {
	_medic setVariable ["DMZ_AM_available", true, true];
	_medic setVariable ["DMZ_AM_abort", false, true];
	if ((count _orgPos) != 0) then {
		_medic doFollow _lead;
		_medic doMove _orgPos;

		_null = _medic spawn {
			waitUntil {sleep 1; unitReady _this OR !alive _this};
			if (alive _this) then {_this setUnitPos "Middle"};
			waitUntil {sleep 1; (behaviour _this) in ["COMBAT","STEALTH"] OR !alive _this OR (currentCommand _this) in ["HIDE","MOVE"]};
			if (alive _this) then {_this setUnitPos "AUTO"};
		};
	};
};
};

Hosted by ArmaHolic greetings to Foxhound.

Direct Download 4Shared:

Edited by Demonized
OA is required for this script to work.

Share this post


Link to post
Share on other sites

Cheers I'll look at this later, it looks cleaner than what I was doing.

Share this post


Link to post
Share on other sites

Thanks Demonized it works very well, there were a couple of slight problems.

While the medic was trying to heal one unit they seemed to get stuck in a loop, it looked like the injured unit was trying to get back into formation and going out of range of the medic.

The medic also just stood next to one unit but didn't heal him so I just gave him a manual command and he obeyed.

It feels a lot more realistic to me now.

Thanks again.

Share this post


Link to post
Share on other sites

Will test this now. Good job.

Now, combine this with a revive (for MP) and a way to heal the most injured soldiers first (to stop them bleeding out) and you have a norrin replacement :)

Share this post


Link to post
Share on other sites

i will work on optimizing this as reported by F2k Sel.

most likely a distance thing, i did not force the wounded AI to stop to be healed, rather i checked distance and range while still moving for the medic, will test with using force stop on wounded until healed.

maybe i can collect current commands and reaply them to wounded unit after heal.

@Kremator

getting most wounded first will be a cool option, will add in a option to do this.

maybe take into acount if can walk, then low priority, if can not walk its high priority etc..

Ill look into the MP compatibility, should be doable.

Share this post


Link to post
Share on other sites

Script worked well, I took out the hint in reach though. I did notice a couple of times where the medic would heal one guy then just stand around. I had to order him to move to the next wounded soldier. Other than that it works well.

Share this post


Link to post
Share on other sites

updated to version 1.1, bug fix and more options.

v 1.2 in the works, mash, drag,carry,wounded in static, MP comp etc.

Share this post


Link to post
Share on other sites

Sounds good, nice one Demonized :thumbsup:

Share this post


Link to post
Share on other sites

Cool Demonized !

What if no medics exist in the team? Could they 'patch up' their mates (walking wounded type) until they could get to a MASH ?

v1.2 looks like it will be great.

Share this post


Link to post
Share on other sites

yeah it would be doable having all units able to patch somewhat up, like bandage etc.

for now the code needs to be run on the medic init, and when medic dies, the script exits, though i have not implemented a way to delete the actions when all medics is dead :D

tnx for reminding me.

Edit: just a note, the actions will not show if medic is dead, they are showing only when medic is alive. so no gamebreaker, but a matter of cleanup after.

Main purpose of script is just to replace the need for the player to issue heal commands on every wounded unit.

but since i like options, "if i could, i would have an option to have options" im adding several optionable things.

All options are just that, options, you can run the script normally with non of them enabled if you desire.

new optionables also being added to v 1.2 - thes can be considered as cheats ofc.

* medic can respawn at mash if fallback with mash is set up, after x time upon death.

* team members can heal/bandage hands and legs damage if medic is dead. or critical body parts damage.

* body armor for medic, to allow him to be more heroic in very hot situations, this meant to be combined with drag and carry option.

other options in the idea box.

* "bleeding" when critical damage to body parts. this to somewhat acompany the cheat and to add in some pressure for the group and medic.

* medic can clean up dead units, (hide the body/delete the body).

* clear near area of enemys if they are close before medic comes to heal.

also the most important thing is to check and see if it works well together with the first aid modules. priority.

Edited by Demonized

Share this post


Link to post
Share on other sites

It's looking really good now, I have tried with the FA_Modules but it seems to screw it up. The healing action just keeps repeating with the injured unit never getting healed.

Share this post


Link to post
Share on other sites

here is a temp fix for FA_Modules for those following this thread.

there will not be the extra long heal animation, it will be same as without FA_Modules (short) but all is working, even on multiple agony states.

replace your current script with this, and remember to adjust your personal options in top of script.

/*
Automated medic v 1.1
by Demonized.

When medic is issued a heal command by leader of group, medic will continue to heal rest of groups wounded units.
Medic will attempt to heal the clostest wounded unit from his position, or the most critical or units not able to walk, based on options set.
Until ordered to one of these commands "WAIT","ATTACK","HIDE","REARM","GET IN","STOP" or the medic is dead.

WARNING!! if you have set medic to STOP or HIDE (take cover) ingame via squad menu commands, the auto part will fail, game engine overwrites all other commands.
The script itself will set the unit to stop and it will show stop in unit icon, but this is ok - but you need to keep track of if you order unit yourself to stop or hide,
and then call him back to formation or move to somewhere to fix it.
["WAIT","ATTACK","HIDE","REARM","GET IN","HIDE","STOP"] these commands will abort or cancel healing run.

execute: place in initline of medic/s.  (example here is initline placement, or use name instead of this)
	option 1: - start healing run from the unit ordered to heal by leader, then proceed to next nearest wounded unit.
	_null = [this,"closeWounded"] execVM "medicAuto.sqf";

	option 2: - start healing run from medics actual position, healing nearest wounded unit to medics position,
	note that this is a action added to the leader.
	_null = [this,"closeMedic"] execVM "medicAuto.sqf";

	option 3: - fully automated medic beheaviour, once a team member is wounded, medic rushes to his position to heal.
	note: may be hasardous for medic health if under fire, but medic will react properly firing/covering etc depending on beheaviour of medic as normal.
	_null = [this,"fullAuto"] execVM "medicAuto.sqf";

_fallBack set to true is very valuable if you setup your unit behind your group in a "safe position", he will return to this position when finnished healing or aborted.
it can utilize all below optionals, but beware that using the STOP or HIDE command ingame will halt the unit and this script, or abort current healing run.

option 2 is most recomended.

*/

// optional:
_canWalk = false;  	// true/false = on/off. - if units should be prioritized nearest unit wich cannot walk, closest wounded is ignored if someone cannot walk.
_critical = false;  	// true/false = on/off - if units should be prioritized by amount of damage, nearest is ignored, amount of damage is priority.
_fallBack = true;  	// true/false = on/off - if medic should return to his original position after heal prior to healing start. works with "fullAuto" AND "closeMedic"
_maxDist = 500;  		// x = meters - medic will not attempt to return to a position or heal units more than this away from the medic.

// this below option is mainly designed for "closeWounded" option, adds a action to leade, it will make the medic mark any position he is currently in as his fallback position, it can be used with any of the options.
_opFallBack = true;  	// true/false = on/off - make the current medic position as his fallback position after healing team members.
_showMarker = true;  	// true/false = on/off - when medic is given a fallBackPosition or have one setup auto via _fallback = true above, there will be a marker on map created at the fallback position.

// DO NOT EDIT BELOW THIS LINE //

_medic = _this select 0;

if ("fullAuto" in _this) then {
while {alive _medic} do {
	waitUntil {sleep 1; !alive _medic OR ({alive _x AND (getDammage _x) != 0} count units group _medic) != 0};
	if (alive _medic) then {
		_medic setVariable ["DMZ_AM_available", false, true];
		_null = [_medic,"healingRun"] execVM "medicAuto.sqf";
	};
	waitUntil {sleep 1; !alive _medic OR _medic getVariable ["DMZ_AM_available", true]};
};
};

if ("closeMedic" in _this) then {
_lead = leader (group _medic);
_con1 = format["_target == _this AND alive _target AND alive %1 AND ({alive _x AND (getDammage _x) != 0} count units group _target) != 0 AND (%1 getVariable ['DMZ_AM_available', true])",_medic];
_acN1 = format ["<t color='#ff0000'>MEDIC!!!</t>",_medic];
_lead addAction [_acN1, "medicAuto.sqf", ["action",_medic], 0, false, true, "", _con1];
};

if ("closeWounded" in _this) then {
{
	_x addEventHandler ["HandleHeal", {
		_medic = _this select 1;
		if (_medic getVariable ["DMZ_AM_available", true]) then {
			_medic setVariable ["DMZ_AM_available", false, true];
			_null = [_medic,"eh","healingRun"] execVM "medicAuto.sqf";
		};
	}];
} foreach units group _medic;
};

if ("closeMedic" in _this OR "closeWounded" in _this) then {
_lead = leader (group _medic);
_con2 = format["_target == _this AND alive _target AND alive %1 AND !(%1 getVariable ['DMZ_AM_available', true])",_medic];
_acN2 = format ["<t color='#ff0000'>MEDIC ABORT!!</t>",_medic];
_lead addAction [_acN2, "medicAuto.sqf", ["abort",_medic], 0, false, true, "", _con2];
};

if (_opFallBack AND ("closeMedic" in _this OR "closeWounded" in _this OR "fullAuto" in _this)) then {
_lead = leader (group _medic);
_con1 = format["_target == _this AND alive _target AND alive %1 AND (%1 getVariable ['DMZ_AM_available', true]) AND (%1 distance (%1 getVariable ['DMZ_AM_pos', [0,0,0]])) > 5",_medic];
_acN1 = format ["<t color='#ff0000'>FALLBACK POSITION MEDIC</t>",_medic];
_lead addAction [_acN1, "medicAuto.sqf", ["fallback",_medic], 0, false, true, "", _con1];
};

_heal = false;
if ((count _this) >= 4) then {
_arg = _this select 3;
if ("action" in _arg) then {
	_medic = _arg select 1;
	(leader (group _medic)) groupChat "MEDIC!!";
	_heal = true;
};
if ("abort" in _arg) then {
	_medic = _arg select 1;
	_medic setVariable ["DMZ_AM_abort", true, true];
};
if ("fallback" in _arg) then {
	_medic = _arg select 1;
	(leader (group _medic)) groupChat "Medic - setup fallback position";
	doStop _medic;
	_pos = getPos _medic;
	_medic doMove _pos;
	_medic setVariable ["DMZ_AM_pos", _pos, true];
	sleep 2;
	_medic groupChat "Roger - setting up fallback position";

	//create a marker for fallback position if _showMarker option is enabled.
	if (_showMarker) then {
		_ret = _medic getVariable ["DMZ_AM_marker", "none"];
		if (_ret == "none") then {
			_cnt = 0;
			_mName = "DMZ_AM_Marker";
			while {!isNil (_mName)} do {
				_mName = format["DMZ_AM_Marker_%1",_cnt];
				_cnt = _cnt + 1;
			};
			_mark = createMarkerLocal[_mName,_pos];
			_mark setMarkerShapeLocal "ICON";
			_mark setMarkerTypeLocal "n_med";
			_mark setMarkerTextLocal "Medic Fallback";
			_medic setVariable ["DMZ_AM_marker", _mark, true];
		} else {
			_ret setMarkerPosLocal _pos;
		};
	};

	waitUntil {unitReady _medic};
	doStop _medic;
	_medic setUnitPos "Middle";
	_null = _medic spawn {
		waitUntil {sleep 1; (behaviour _this) in ["COMBAT","STEALTH"] OR !alive _this OR (currentCommand _this) in ["HIDE","MOVE"]};
		if (alive _this) then {_this setUnitPos "AUTO"};
	};
};
};

if ("healingRun" in _this OR _heal) then {
_medic setVariable ["DMZ_AM_available", false, true];

// commands that will abort the healing run.
_cansel = ["WAIT","ATTACK","HIDE","REARM","GET IN","HIDE","STOP"];

_orgPos = [];
if (_fallBack OR _opFallBack) then {_orgPos = getPos _medic};
_varPos = _medic getVariable ["DMZ_AM_pos", []];
if ((count _varPos) != 0) then {_orgPos = _varPos};
if ("eh" in _this) then {
	waitUntil {!alive _medic OR unitReady _medic OR (currentCommand _medic) != "HEAL SOLDIER"};
};

_heal = true;
while {_heal} do {
	_dist = _maxDist;
	_grp = group _medic;
	_lead = leader _grp;
	_wounded = _medic;

	// general nearest wounded part, being overwriten by canWalk or critical in that order if activated.
	{
		if (alive _x AND (getDammage _x) != 0 AND alive _medic) then {
			_dist1 = _medic distance _x;
			if (_dist1 < _dist) then {
				_dist = _dist1;
				_wounded = _x;
			};
		};
	} foreach units _grp;

	// can walk priority part overides general nearest if someone cant walk, nearest unit unable to walk is 1st priority. overwrited by critical if its set to true.
	if (_canWalk) then {
		if (({!canStand _x} count units group _medic) != 0) then {
			_dist = _maxDist;
			{
				_dist1 = _medic distance _x;
				if (_dist1 < _dist AND !canStand _x) then {
					_dist = _dist1;
					_wounded = _x;
				};
			} foreach units _grp;
		};
	};

	// criticals first part overides canwalk part if anyone is more wounded, most damaged unit is 1st priority. overwrites any other conditions.
	if (_critical) then {
		_dam = 0;
		_dist = _maxDist;
		{
			_dam1 = getDammage _x;
			if (alive _x AND (getDammage _x) != 0 AND alive _medic AND _dam1 > _dam) then {
				_dist1 = _medic distance _x;
				if (_dist1 < _dist) then {
					_dam = _dam1;
					_wounded = _x;
				};
			};
		} foreach units _grp;
	};

	// the actual moving and healing part.
	if ((getDammage _wounded) != 0 AND alive _medic) then {
		_move = true;
		while {_move AND alive _wounded AND alive _medic} do {
			_pos = getPos _wounded;
			_medic doMove _pos;
			waitUntil {(_medic distance _pos) < 3 OR !alive _medic OR !alive _wounded OR (currentCommand _medic) in _cansel OR (_medic getVariable ["DMZ_AM_abort", false])};
			if ((_medic distance _wounded) < 3 OR !alive _medic OR !alive _wounded OR (currentCommand _medic) in _cansel OR (_medic getVariable ["DMZ_AM_abort", false])) then {_move = false};
		};
		if (alive _wounded AND alive _medic AND !((currentCommand _medic) in _cansel) AND !(_medic getVariable ["DMZ_AM_abort", false])) then {
			_wounded action ["heal", _medic];
			sleep 2;

			// if dfirst aid modules is used.
			if (_wounded getVariable ["BIS_IS_inAgony", false]) then {
				_wounded setDammage 0;
				{_wounded setVariable [_x,0,true]} foreach ["head_hit","body","hands","legs","bloodlossPerSecond","bloodloss"];
				_wounded setVariable ["BIS_IS_inAgony",false];
			};


			_medic doFollow _lead;
			waitUntil {unitReady _medic OR (currentCommand _medic) in _cansel};
		};
	};

	if ((({(getDammage _x) != 0} count units group _medic) == 0 OR (_medic getVariable ["DMZ_AM_abort", false])) AND alive _medic) then {
		_heal = false;
		_medic setVariable ["DMZ_AM_available", true, true];
		_medic doFollow _lead;
		if ((count _orgPos) != 0) then {
			if (_medic getVariable ["DMZ_AM_abort", false]) then {
				_medic groupChat "aborted - returning to fallback position";
			} else {
				_medic groupChat "no more wounded - returning to fallback position";
			};
		} else {
			_medic groupChat "no more wounded - returning to formation";
		};
	};
	if ((currentCommand _medic) in _cansel OR !alive _medic) then {
		if (alive _medic AND _heal) then {_medic groupChat "aborted"};
		_heal = false;
	};
};
if (alive _medic) then {
	_medic setVariable ["DMZ_AM_available", true, true];
	_medic setVariable ["DMZ_AM_abort", false, true];
	if ((count _orgPos) != 0) then {
		_medic doFollow _lead;
		_medic doMove _orgPos;

		_null = _medic spawn {
			waitUntil {sleep 1; unitReady _this OR !alive _this};
			if (alive _this) then {_this setUnitPos "Middle"};
			waitUntil {sleep 1; (behaviour _this) in ["COMBAT","STEALTH"] OR !alive _this OR (currentCommand _this) in ["HIDE","MOVE"]};
			if (alive _this) then {_this setUnitPos "AUTO"};
		};
	};
};
};

Share this post


Link to post
Share on other sites

Thanks. I'm now getting an error though.

RPT file

Error in expression < == _this AND alive _target AND alive O 1-1-A:1 AND (O 1-1-A:1 getVariable ['DMZ>

Error position: <1-1-A:1 AND (O 1-1-A:1 getVariable ['DMZ>

Error Missing ;

in game it places a hash in the line

== _this AND alive _target AND alive O #1-1-A:1 AND (O 1-1-A:1 getVariable ['DMZ

Share this post


Link to post
Share on other sites
Thanks. I'm now getting an error though.

RPT file

Error in expression < == _this AND alive _target AND alive O 1-1-A:1 AND (O 1-1-A:1 getVariable ['DMZ>

Error position: <1-1-A:1 AND (O 1-1-A:1 getVariable ['DMZ>

Error Missing ;

in game it places a hash in the line

== _this AND alive _target AND alive O #1-1-A:1 AND (O 1-1-A:1 getVariable ['DMZ

---------- Post added at 01:47 AM ---------- Previous post was at 01:34 AM ----------

alright, updated first post with 2 bugfixes:

bug fixes v 1.11

1: the error encountered when medic had no name. fixed.

2: First Aid modules light support.

---------- Post added at 03:09 AM ---------- Previous post was at 01:47 AM ----------

updated to v 1.12, 1st post updated.

* any unit can act as medic, not only medics, specially useful for specop groups or units that do not have any medic classes.

* reset fallback position action added.

Edited by Demonized

Share this post


Link to post
Share on other sites
---------- Post added at 01:47 AM ---------- Previous post was at 01:34 AM ----------

alright, updated first post with 2 bugfixes:

bug fixes v 1.11

1: the error encountered when medic had no name. fixed.

2: First Aid modules light support.

---------- Post added at 03:09 AM ---------- Previous post was at 01:47 AM ----------

updated to v 1.12, 1st post updated.

* any unit can act as medic, not only medics, specially useful for specop groups or units that do not have any medic classes.

* reset fallback position action added.

Hi Demonized

Came across this earlier today & eagerly copied the v1.12 script.

Set up simple mission with a merged group of 2 FR teams (less saboteurs) & put

_null = [this,"closeMedic"] execVM "medicAuto.sqf";

in each of the 2 medics init fields.

Then placed a few RU rifle squads around Strelka, After copying the autoMedic script into the mission folder, I waded in.

First thing I noticed was somewhat slow running, then that the script didn't seem to do anything - nothing in the action menu & medics didn't show any initiative.

After 5 mins or so I looked at the .rpt; it was over 32 MB in size, full of a repeated error:

Error in expression <AND alive DMZ_AM_name AND !(DMZ_AM_name getVariable ['DMZ_AM_available', true])>

Error position: <getVariable ['DMZ_AM_available', true])>

Error getvariable: Type Array, expected String

In case I made an error copying & pasting from your first post I've also downloaded the script from Armaholic & replced the copy/paste job - same result, huge list of the same error in the .rpt file. Running vanilla ArmA II v1.10 on XP Pro.

I'm very much a scripting beginner so can't add anything helpful, other than saying thanks very much for your work & hope this error can be resolved :)

BR

Orcinus

Edited by Orcinus
Added further information

Share this post


Link to post
Share on other sites
*snip*

hi, there was a missing number wich made it error out when used on multiple non named units.

the reason why you feel it slowed down, is because since the number was missing, it ran a infinite non paused loop.

Thank you for report, 1st post fixed, in case you wonder where, it was in this line in the dynamic naming part in top:

_vName = format["DMZ_AM_name_%1",_cnt];

the number 1 was simply missing (typo) so the loop never found a new name, it kept rechecking same name infinite amount of times, when used on more than one medic/unit, thus slowing it down and not working since it never got out of the loop.

Share this post


Link to post
Share on other sites
hi, there was a missing number wich made it error out when used on multiple non named units.

the reason why you feel it slowed down, is because since the number was missing, it ran a infinite non paused loop.

<snip>

Hi Demonized

Thanks for the quick response.

The newest version - whether editing 'my' v1.12 file or copying/pasting the script in the first post also fills up the .rpt rather quickly (see extract in spoiler).

Error in expression <AND alive DMZ_AM_name AND !(DMZ_AM_name getVariable ['DMZ_AM_available', true])>

Error position: <getVariable ['DMZ_AM_available', true])>

Error getvariable: Type Array, expected String

Error in expression < AND alive DMZ_AM_name AND (DMZ_AM_name getVariable ['DMZ_AM_available', true]) >

Error position: <getVariable ['DMZ_AM_available', true]) >

Error getvariable: Type Array, expected String

Error in expression < AND alive DMZ_AM_name AND (DMZ_AM_name getVariable ['DMZ_AM_available', true]) >

Error position: <getVariable ['DMZ_AM_available', true]) >

Error getvariable: Type Array, expected String

Error in expression < group _target) != 0 AND (DMZ_AM_name_1 getVariable ['DMZ_AM_available', true])>

Error position: <getVariable ['DMZ_AM_available', true])>

Error getvariable: Type Array, expected String

Error in expression <alive DMZ_AM_name_1 AND !(DMZ_AM_name_1 getVariable ['DMZ_AM_available', true])>

Error position: <getVariable ['DMZ_AM_available', true])>

Error getvariable: Type Array, expected String

Error in expression < alive DMZ_AM_name_1 AND (DMZ_AM_name_1 getVariable ['DMZ_AM_available', true]) >

Error position: <getVariable ['DMZ_AM_available', true]) >

Error getvariable: Type Array, expected String

Error in expression < alive DMZ_AM_name_1 AND (DMZ_AM_name_1 getVariable ['DMZ_AM_available', true]) >

Error position: <getVariable ['DMZ_AM_available', true]) >

Error getvariable: Type Array, expected String

Error in expression <ts group _target) != 0 AND (DMZ_AM_name getVariable ['DMZ_AM_available', true])>

Error position: <getVariable ['DMZ_AM_available', true])>

Dropped the init line from one of the two medics but still got the same errors.

BR

Orcinus

Share this post


Link to post
Share on other sites

alright, something else then is messing it up, im almost ready to release v 1.13 and that have also been tested with multiple medics.

no more .rpt errors at least.

maybe an hour or so until release.

---------- Post added at 12:28 AM ---------- Previous post was Yesterday at 11:33 PM ----------

Updated release frontpaged on the Armaholic homepage.

Thank you Foxhound.

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

updated to v 1.13 - Check Changelog.

* medic can build mash.

* medic can respawn at mash if killed, also nr of lives option.

* optional longer heal routine based on severity of wounded.

* optimisation of multiple medics, they no longer run to same person.

* + more

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
Sign in to follow this  

×