Jump to content

Recommended Posts

So I created the script and add readme and comments to the sqf, so it's time to release it:

Armaholic: Bardosy's automedic script v1.0

Dropbox: Bardosy's automedic script v1.0

automedic_www.kepfeltoltes.hu_.jpg

The original first post:

I bored to micromanaging the medic in my group in the battles. As squad leader, I have a lot of more important tasks to do.

Is there an ArmA3 script (not MOD!) what solve this problem? If there is not, how can I solve it?

I'm thinking about this script features:

1. The script sleep until one member of my squad is wounded. Question: in arma3 getDamage is enough to check the wounds? Or hits caused wounds what is not checkable with getDamage? In ArmA2 getDamage was zero when the soldier was half dead and agonized on the ground... is it different in Arma3?

2. When someone is injured, he stops (or not?) and medic doMove to the injured soldiers. Is it good to stop the injured soldier (and lay down?) in a battle?

3. When (medic distance injured)<5 the script runs: medic action ["heal", injured]. Is this action good enough in arma3?

4. When medic isReady again, ex-injured don1t stop and receive his auto stance status.

Do you have any hint or knowledge about arma3 healing system?

Can I do this? I just ask, because this script is so obvious and I cant find a good solution, just wounding-systems and mods....

Edited by bardosy
release the script
  • Like 1

Share this post


Link to post
Share on other sites

I created the first, raw version of the script (many improvements are required), but still need to fix two major problem:

1. doMove command (against the BIS documentation) don't cancel when it done: so I doMove'ed the medic to the injured and when healing is done, I except medic return to formation (as the doMove documentation said). But medic will not return to fromation.

2. The action "heal" is also works very different as documentation. BIS wiki said: medic will heal the injured. But in the game, injured heal himself. :( There is an other action in the wiki "HealSoldierSelf" what have to do it, but I used "Heal" and it works very different way.

Any hint, help or suggestion?

Ant the first version:

_medic = pmedic;
_group = group _medic;
_injured = objNull;

while {true} do {
sleep 2;
while {isNull _injured} do {
	//player sideChat "keresunk egy sebesultet";
	{
		//player sideChat format["%1 sebesulese %2", name _x, getDammage _x];
		if (isNull _injured and getDammage _x > 0.1) then {			
			_injured = _x;
			//player sideChat format["megvan a sebesult: ", name _x];
		};
	} foreach units _group;
	sleep 5;
};

//we have an injured, stop him
_injured disableAI "MOVE";
_injured setUnitPos "down";
//medic go for him
_medic doMove (position _injured);
while {_medic distance _injured > 3} do {
	sleep 2;
	_medic doMove (position _injured);
};
sleep 1;
_medic disableAI "MOVE";
_medic setUnitPos "middle";
_injured action ["Heal", _medic];

waitUntil { getDammage _injured < 0.1};
sleep 3;

//ready to fight
_injured enableAI "MOVE";
_injured setUnitPos "auto";
_injured = objNull;
_medic enableAI "MOVE";
_medic setUnitPos "auto";
};

Share this post


Link to post
Share on other sites

Thank you Mikie, but you heal with revive scripts and use the same doMove as me.

So I continued develop my script:

_medic = _this select 0;
_units = _this select 1;
_injured = objNull;
if (isPlayer _medic) exitWith{};
if (not isServer) exitWith{};

while {alive _medic} do {
sleep 2;
//waiting for a wounded
while {isNull _injured} do {
	//if the medic is injured
	if (getDammage _medic > 0.1) then {
		//if medic is already dead, then exit
		if (!alive _medic) exitWith{};
		//else he is the injured and he is a priority to heal himself
		_injured = _medic;
	} else {		
		{
			//player sideChat format["%1 sebesulese %2", name _x, getDammage _x];
			if (isNull _injured and getDammage _x > 0.1) then {			
				_injured = _x;
				//player sideChat format["megvan a sebesult: ", name _x];
				_medic sideChat format["Keep calm %1, I will heal you.", (name _injured)];
			};
		} foreach _units;
	};
	sleep 5;
};

//we have an injured, stop him
if ((!isPlayer _injured) and (_medic!=_injured)) then {
	_injured disableAI "MOVE";
	_injured setUnitPos "down";
};
if (_medic!=_injured) then {
	//medic go for him
	_medic doMove (position _injured);
	while {_medic distance _injured > 3} do {
		sleep 2;
		_medic doMove (position _injured);
	};
};
//when medic is close enough to the injured...
sleep 1;
//...and injured is still alive
if (alive _injured) then {	
	//stop the medic
	_medic disableAI "MOVE";
	_medic setUnitPos "middle";

	//HEAL the injured
	// ******************************
	_injured action ["Heal", _medic];
	// ******************************


	//wait until injured is healed or dead
	waitUntil { (getDammage _injured < 0.1) or (!alive _injured) };
	sleep 3;
	if (_medic!=_injured) then {
		_medic sideChat format["OK %1, you are ready to fight.", (name _injured)];
	};

	if (!isPlayer _injured) then {
		//healed soldier is ready to fight
		_injured enableAI "MOVE";
		_injured setUnitPos "auto";
	};
};
//we are ready for looking a new injured
_injured = objNull;
//set the medic to ready to looking for a new injured
_medic enableAI "MOVE";
_medic setUnitPos "auto";
//doMove stops the medic, so we have to command him to follow his leader
_medic doFollow (leader group _medic);
};

Share this post


Link to post
Share on other sites

I think Das Attorney had an auto medic back in arma2, as par of his All Round Defence.

  • Like 2

Share this post


Link to post
Share on other sites

Well remembered mate, I forgot about that one :)

Here you go Bardosy, not sure if it works in A3 though, (there's probably a few improvements you could do to it, like checking the medics are conscious and not busy in the initial _medic_array checks for example). If you've only got one medic in your group it should work fine though.

if (isDedicated) exitWith {};

private ["_vehicle","_thisgroup","_unit_total","_wounded","_medic","_medic_array","_medicBehaviour","_count_wounded","_wounded_array","_stance","_nic","_unconscious_array","_walking_wounded_array"];

if (!isNil{(group player) getVariable "HORDE_ARD_medic_in_progress"}) exitWith {}; // can only give this order if the order is not in progress already

(group player) setVariable ["HORDE_ARD_medic_in_progress", 1, false]; // disallow additional instances of the script running

_thisgroup = group player;
_unit_total = units _thisgroup;

// count up medics in players group

_medic_array = [];
{
if (getNumber(configFile >> "CfgVehicles" >> typeOf _x >> "attendant") == 1) then {
	_medic_array set [count _medic_array, _x];
};
} forEach (_unit_total - [player]);

// exit if no medics

if (count _medic_array < 1) exitWith
{
player sideChat (localize "STR_ARDNOMEDIC");
player playActionNow "GestureNo";
(group player) setVariable ["HORDE_ARD_medic_in_progress", nil, false];
};

_medic = _medic_array select 0; // select the first available medic

if (!isNil{_medic getVariable "HORDE_ARD_unit_busy"}) exitWith {_medic sideChat "I'm busy - cancel current action first"; (group player) setVariable ["HORDE_ARD_medic_in_progress", nil, false]};

_medic setVariable ["HORDE_ARD_unit_busy", 1, false];

sleep 0.05;

// count up unconscious units

_unconscious_array = [];
{
if (_x != assignedGunner (vehicle _x) and lifeState _x == "UNCONSCIOUS" and _x == (vehicle _x)) then
{
	_unconscious_array set [count _unconscious_array, _x];
};
sleep 0.05;
} forEach (units (group player));

// count up conscious wounded units

_walking_wounded_array = [];
{
if (_x != assignedGunner (vehicle _x) and (damage _x) > 0 and _x == (vehicle _x) and lifeState _x != "UNCONSCIOUS") then
{
	_walking_wounded_array set [count _walking_wounded_array, _x];
};
sleep 0.05;
} forEach (units (group player));

_wounded_array = [];

_wounded_array = _unconscious_array + _walking_wounded_array - [_medic];

_wounded_array = _wounded_array - [_medic];

_count_wounded = count _wounded_array;

///////////////////////////////////////////////

if (vehicle _medic != _medic and lifeState _medic == "ALIVE") then
{
	unassignVehicle _medic;
	doGetOut _medic;
	waitUntil {(vehicle _medic) == _medic};
};

sleep 0.05;

//////////////////////////////////////////////

if (lifeState _medic == "UNCONSCIOUS") exitWith
{
player sideChat "MEDIC INCAPACITATED";
player playActionNow "GestureNo";
(group player) setVariable ["HORDE_ARD_medic_in_progress", nil, false];
_medic setVariable ["HORDE_ARD_unit_busy", nil, false];
};

///////////////////////////////////////////////

player sideChat (localize "STR_ARDMEDICHEAL");
player playAction "gestureAttack";

////////////////////////////////////////////////

if (damage _medic > 0 and lifeState _medic == "ALIVE") then
{
_medic action ["Heal", _medic];
sleep 9;
_medic setDamage 0;
AISFinishHeal [_medic,_medic,true];
sleep 0.05;
};

////////////////////////////////////////////////

if (count _wounded_array == 0) exitWith
{
_medic sideChat (localize "STR_ARDNOINJURIES");
_medic playActionNow "GestureNo";
(group player) setVariable ["HORDE_ARD_medic_in_progress", nil, false];
_medic setVariable ["HORDE_ARD_unit_busy", nil, false];
};

sleep 0.05;

_medic setUnitPos "auto";

////////////////////////////////////////////////

_medicBehaviour = behaviour _medic;

if (_medicBehaviour == "COMBAT") then
{
_medic setBehaviour "careless";
};

////////////////////////////////////////////////

while {_count_wounded >= 1 and alive _medic and lifeState _medic != "UNCONSCIOUS" and !isNil {_medic getVariable "HORDE_ARD_unit_busy"}} do
{
sleep 1;
_wounded = _wounded_array select 0;

if (vehicle _wounded != _wounded) then
{
	unassignVehicle _wounded;
	doGetOut _wounded;
};

_stance = unitPos _wounded;

_medic disableAI "TARGET";
_medic disableAI "AUTOTARGET";

while {_medic distance _wounded > 3 and damage _wounded > 0 and alive _wounded and alive _medic and lifeState _medic != "UNCONSCIOUS" and !isNil {_medic getVariable "HORDE_ARD_unit_busy"}} do
{
	_medic moveTo getPos _wounded;
	_medic doMove getPos _wounded;
	sleep 2;
};

if (damage _wounded > 0 and alive _wounded and alive _medic and lifeState _medic != "UNCONSCIOUS" and !isNil {_medic getVariable "HORDE_ARD_unit_busy"}) then
{
	sleep 0.5;
	_wounded action ["Heal", _medic];
	sleep 7;
     	_nic = [_medic,_wounded,"loc",rCALLVAR,[_wounded,"healMedic",10000], "BIS_AIS_DAMAGING"] call RE; //totally heals
     	sleep 0.05;
     	_nic = [_medic,_wounded,"loc",rCALLVAR,[_wounded,"healMedic",10000], "BIS_AIS_DAMAGING"] call RE; //totally heals
     	sleep 0.05;
     	_wounded setDamage 0;
	sleep 2;
	AISFinishHeal [_wounded,_medic,true];
};
_wounded setUnitPos _stance;
_medic enableAI "TARGET";
_medic enableAI "AUTOTARGET";

sleep 1;

_unconscious_array = [];
{
	if (_x != assignedGunner (vehicle _x) and lifeState _x == "UNCONSCIOUS" and _x == (vehicle _x)) then
	{
		_unconscious_array set [count _unconscious_array, _x];
	};
	sleep 0.05;
} forEach (units (group player));

_walking_wounded_array = [];
{
	if (_x != assignedGunner (vehicle _x) and (damage _x) > 0 and _x == (vehicle _x) and lifeState _x != "UNCONSCIOUS") then
	{
		_walking_wounded_array set [count _walking_wounded_array, _x];
	};
	sleep 0.05;
} forEach (units (group player));

_wounded_array = [];

_wounded_array = _unconscious_array + _walking_wounded_array - [_medic];

_wounded_array = _wounded_array - [_medic];

sleep 0.05;

_count_wounded = count _wounded_array;

sleep 0.05;

if (damage _medic > 0 and lifeState _medic == "ALIVE" and !isNil {_medic getVariable "HORDE_ARD_unit_busy"}) then
{
	_medic action ["Heal", _medic];
	sleep 9;
	_medic setDamage 0;
	AISFinishHeal [_medic,_medic,true];
	sleep 0.05;
};
};

///////////////////////////////////////

if (alive _medic) then
{
if (_medicBehaviour == "careless") then
{
	_medic setBehaviour "AWARE";
};
_medic setBehaviour _medicBehaviour;

[_medic] call HORDE_ARD_cancel_action_FNC;		

sleep 1;
_medic playAction "gestureFreeze";
};
_medic setVariable ["HORDE_ARD_unit_busy", nil, false];
(group player) setVariable ["HORDE_ARD_medic_in_progress", nil, false];

Share this post


Link to post
Share on other sites

The problem is, the arma2 wounding system is very different as arma3 wounding system. E.g. no conscious-state in arma3.

Share this post


Link to post
Share on other sites

Can someone help me in this:

In the test mission, everything went fine, but when I try it in a real mission aftre an hour gameplay the automedic started to try heal 'Error: no unit'

This is the main loop:

while {isNull _injured} do {
	//if the medic is injured
	if (getDammage _medic > 0.1) then {
		//if medic is already dead, then exit
		if (!alive _medic) exitWith{};
		//else he is the injured and he is a priority to heal himself
		_injured = _medic;
	} else {
		_deads = [];
		{
			if (!alive _x or isNull _x) then {
				_deads = _deads + [_x];
			};
			if ((isNull _injured) and (getDammage _x > 0.1) and (alive _x) and (!isNull _x)) then {			
				_injured = _x;
				if (_needradio) then {_medic groupChat format["Keep calm %1, I will heal you.", (name _injured)];};
			};
		} foreach _units;
		_units = _units - _deads;
	};
	sleep 5;
};

And medic started to groupChat: "Keep calm Error: no unit, I will heal you."

I remove the non alive units from the group, because I thought this is the difference the real mission and the test. In real mission one or two of my units are died. But the medic still want to heal them.

Share this post


Link to post
Share on other sites

while {isNull _injured}

so name _injured is the name of isNull, so no unit, no object just nothing...

Isn't it?

P.D: Glad to see you back!

Share this post


Link to post
Share on other sites

I published my missions with this automedic script. So it's time to publish here the script's v1.0 here:

There are two sqf file (the second one is for turn the script off - there are situations when player want the medic keep his head down or the player hate this script, so he can turn it off.) The first one is the automedic script itself. I used only for the player's squads' medic.

You can call it with the medic and the units what the medic will heal.

E.g.: [medic1, units group medic1] execVM "automedic.sqf";

automedic.sqf:

if (not isServer) exitWith{};

_medic = _this select 0;
_units = _this select 1;
if (count _this > 2) then {
_medic = LCK_automedicmedic;
_units = LCK_automedicunits;
};
_injured = objNull;
//if you want the medic groupChating, set this true. Else set it false;
_needradio = true;
//if medic is in the player's group and player is the squad leader, you can set this script to switchable: so player can switch off and switch back on, when he want.
_switchable = true;

//no need automedic if the medic is a player
if (isPlayer _medic) exitWith{};

//init to switch off automedic
if (_switchable) then {
if (count _this > 2) then {
	(leader group _medic) removeAction LCK_automedicaction;
};
LCK_automedicaction = (leader group _medic) addAction ["Automedic OFF", "automedicoff.sqf", [], 1, false, true, "", "true"];
LCK_automedicmedic = _medic;
LCK_automedicunits = _units;
LCK_automedicexit = false;
};

//main loop
while {alive _medic and (not LCK_automedicexit)} do {
if(LCK_automedicexit) exitWith{};
sleep 2;
//waiting for a wounded
while {(isNull _injured) and (alive _medic)} do {
	//if the medic is injured
	if (getDammage _medic > 0.1) then {
		//if medic is already dead, then exit
		if (!alive _medic) exitWith{};
		//else he is the injured and he is a priority to heal himself
		_injured = _medic;
	} else {
		_deads = [];
		{
			if (!alive _x or isNull _x) then {
				_deads = _deads + [_x];
			};
			if ((isNull _injured) and (getDammage _x > 0.1) and (alive _x) and (!isNull _x)) then {			
				_injured = _x;
				if (_needradio) then {_medic groupChat format["Keep calm %1, I will heal you.", (name _injured)];};
			};
		} foreach _units;
		_units = _units - _deads;
		LCK_automedicunits = _units;
	};
	sleep 5;
	if(LCK_automedicexit) exitWith{};
};

if(LCK_automedicexit or (!alive _medic)) exitWith{};

//we have an injured, stop him
if ((!isPlayer _injured) and (_medic!=_injured)) then {
	_injured disableAI "MOVE";
	_injured setUnitPos "down";
};
if (_medic!=_injured) then {
	//medic go for him
	_medic doMove (position _injured);
	while {(_medic distance _injured > 3) and (alive _injured) and (!isNull _injured)} do {		
		sleep 1;
		_medic doMove (position _injured);
		if(LCK_automedicexit or (!alive _medic)) exitWith{_injured enableAI "MOVE"; _injured setUnitPos "auto";};
	};
};

if(LCK_automedicexit or (!alive _medic)) exitWith{_injured enableAI "MOVE"; _injured setUnitPos "auto";};

//when medic is close enough to the injured...
//...and injured is still alive
if ((alive _injured) and (!isNull _injured) and (alive _medic) and (!LCK_automedicexit)) then {	
	//stop the medic
	_medic disableAI "MOVE";
	_medic setUnitPos "middle";
	sleep 1;
	//HEAL the injured
	// ******************************
	_injured action ["Heal", _medic];
	// ******************************

	//wait until injured is healed or dead
	waitUntil { (getDammage _injured < 0.1) or (!alive _injured) };
	sleep 3;
	if (_medic!=_injured) then {
		if (_needradio) then {_medic groupChat format["OK %1, you are ready to fight.", (name _injured)];};
	};

	//healed soldier is ready to fight
	_injured enableAI "MOVE";
	_injured setUnitPos "auto";
};
//we are ready for looking a new injured
_injured = objNull;
//set the medic to ready to looking for a new injured
_medic enableAI "MOVE";
_medic setUnitPos "auto";
//doMove stops the medic, so we have to command him to follow his leader
_medic doFollow (leader group _medic);

if(LCK_automedicexit or (!alive _medic)) exitWith{_injured enableAI "MOVE"; _injured setUnitPos "auto";};

};

if (not alive _medic) then {
(leader group LCK_automedicmedic) removeAction LCK_automedicaction;
};
if (not(isNull _injured)) then {
_injured enableAI "MOVE";
_injured setUnitPos "auto";
};

automedicoff.sqf:

(leader group LCK_automedicmedic) removeAction LCK_automedicaction;
LCK_automedicexit = true;
LCK_automedicaction = (leader group LCK_automedicmedic) addAction ["Automedic ON", "automedic.sqf", [true], 1, false, true, "", "true"];

Share this post


Link to post
Share on other sites

Hi Bardosy

Demonized published an automated medic script for CO which works very nicely (haven't tried it on A3). I generally use it in my personal SP missions where I'm a team leader even with COSLX running. Has some neat options (fallback positions for each madic; spawn med tent, etc.). Might be worth you taking a look here

Demonized seems not to have been active for almost a year, so I suspect he's not likely to port it to A3 anytime soon. You could try emailing via his profile if you want to ask him about his script.

Cheers

Orc

Share this post


Link to post
Share on other sites

I released my script in the first post.

Share this post


Link to post
Share on other sites

Thanks for the release. I have noted that this is really for the player's squad, but will it work with other friendly and enemy AI? Please say yes :)

Share this post


Link to post
Share on other sites

Probably yes, but AI squad leaders do their job fine and they command their medic nicely. So it's not necessary.

The problem is, my script handle only one single medic, so you have to run the script for every medic. It's not a big deal, but you have to set _switchable variable to false, because if it's true, there will be a lot of "automedic OFF" action in the game (in every leader). OK, it's also not a problem, but could be.

What I thinking about, how can I use this script for independent medics: a banch of medic running up and down in the battlefield and heal the wounded soldiers.

Share this post


Link to post
Share on other sites

Thank you Bardosy.

In A2/CO there is COSLX and a script by DarkXess as well as Demonized's Automedic.

Solus had the healing/first aid apply to all units but you could use just some of the code and restrict it to medics (I'm thinking about a partial port of [CO]SLX_wounds to A3 myself). DarkXess' script is on Armaholic - in effect public domain - but anyway he's a nice guy & I'm sure would agree to you lifting part or all of it.

Share this post


Link to post
Share on other sites

Thank you for informing us about the release :cool:

Release frontpaged on the Armaholic homepage.

================================================

We have also "connected" these pages to your account on Armaholic.

This means in the future you will be able to maintain these pages yourself if you wish to do so. Once this new feature is ready we will contact you about it and explain how things work and what options you have.

When you have any questions already feel free to PM or email me!

Share this post


Link to post
Share on other sites

@dondaddah: very little chance. :( I never made an addon and I prefer scripts. Sorry.

Share this post


Link to post
Share on other sites

If i have a medic back at our Base and bring our injured back ( players) will he auto heal them if not in his Squad ?

Was thinking of having a Base Med tent to revive our Medic's stop them re spawning :)

Share this post


Link to post
Share on other sites

Hello PARA!

This script in current state cannot do that, because if we add the list of soldiers to the medic, medic will left his position and heal the wounded soldier then return to his formation (but without a leader, he will stay where he is).

But I thought the same idea as you. So I could modify this script (into a separete one) when the medic is in a place (tent or base) and if wounded go there, he heal them. Or/and if wounded cannot walk, he run for him and heal then run back to base/tent. I will make this modification and post it here.

Share this post


Link to post
Share on other sites

This is great, I really like the idea. Trying to figure out how to get this function into a Medic that was created in-game MP from a Recruit script. What would the code look like to insert this {dummy = [this, units (group player)] execVM "scripts\automedic.sqf";} into the AI init when creating him?

Share this post


Link to post
Share on other sites

I never saw a "recruit script", but it seems to correct. In my missions I use checkpoints when I detect if player's own medic is dead and then I create (spawn) a medic and add this line into his init.

Share this post


Link to post
Share on other sites

Wait, no! In MP games (group player) isn't good. Eg. in DS there is no player. So if there is a name of a group use it, or a specific player's name. Eg. in my missions the player's init start with this: pgrp = group this; And then you can use pgrp variable to start the automedic script. And it works in MP too.

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

×