Jump to content

Recommended Posts

Hi everyone,

 

I created a simple scenario Eden Editor that consist of only 1 BLUFOR assault squad (of course the Squad Leader is the PLAYER) ... this squad has ONE Combat Life Saver (the class is B_medic_F) ... This Combat Life Saver has 1 Medical Kit and 10 First Aid Kit ... I made this piece of code to make the Combat Life Save heals injured members of the squad ... I run this code from the Debug Console:

 

player allowDamage false; //  for test, so that I can see what is happening
{                         //  loop for each units in game
	if ((group _x == group player)) then   // check if the unit is in my squad
	{
		if (typeOf _x == "B_medic_F" OR typeOf _x == "I_G_medic_F" OR typeOf _x == "I_medic_F") then // if the unit is Combat Life Saver (c_L_s), assuming there is only ONE Combat Life Saver in the squad
		{
			c_L_s = _x;   // save the Combat Life Saver in a varialble called c_L_s
			c_L_s allowDamage false; // for test, so that Combat Life Saver will not take damage and die
		} else { // if NOT Combat Life Saver
			_x addeventhandler ["hit", { [_this select 0, c_L_s] spawn SAM_fnc_heal; }]; // if NOT Combat Life Saver, then add event handler (hit) that will call a function. Two values to be passed to the function: the unit that has dammage (_this select 0) and the Combat Life Saver unit (c_L_s).
		};
	};
} forEach allUnits;
 
SAM_fnc_heal = { // A function called SAM_fnc_heal that will be called by the 
	_hurted = _this select 0; // save the first parameter passed to the function (the unit that has dammage "the hurted unit") in a variable called (_hurted)
	_healer = _this select 1; // save the second parameter passed to the function (the Combat Life Saver "the healer") in a variable called (_healer)
	_hurted_pos = position _hurted; // save the current position of the unit that has dammage (_hurted) in a variable called (_hurted_pos)
	_healer_pos = position _healer; // save the current position of the Combat Life Saver (_healer) in a variable called (_healer_pos)
	 hintSilent parseText format ["%1", getDammage _hurted];  // a hint to see what is going on
	if ( alive _hurted && ((items c_L_s find "Medikit" != -1) OR (items c_L_s find "FirstAidKit" != -1)) && getDammage _hurted > 0.25) then // if the hurted unit is still alive and the healer has Medikit or has FirstAidKit excute the code below
	{ 
		doStop _hurted; // make the hurted unit stop moving
		_healer doMove (_hurted_pos); // move the healer to the position of the hurted unit
		waitUntil { _healer distance _hurted < 2 }; // wait unit the healer unit less than 2 meters far from the hurted unit
		while { getDammage _hurted > 0.25 } do // a loop that will keep running if the hurted unit dammage is above 0.25
		{ 
			if (items c_L_s find "Medikit" != -1) then // if the the healer has a Medical Kit then do the next code
			{ 
				_healer playAction "MedicOther"; // make the healer do Medic others animation
				sleep 9; // wait for 9 seconds
				_hurted setDamage 0; // heal the hurted unit and make its dammge become 0 (fully healed)
				_healer removeItem "Medikit"; // remove the Medikit from the healer unit as it is already used just right now
				player sideChat format ["%1 healed to %2", _hurted, 1 - getDammage _hurted ]; // show a chat message telling that the unit is already been fully healed
			} else {  // if the the healer does NOT have a Medikit then do the next code
				if (items c_L_s find "FirstAidKit" != -1) then // if the the healer has a First Aid Kit then do the next code
				{ 
					_healer playAction "MedicOther"; // make the healer do Medic others animation
					sleep 9; // wait for 9 seconds
					_hurted setDamage 0.25; // heal the hurted unit and make its dammge become 0.25 (healed to 0.75)
					_healer removeItem "FirstAidKit"; // remove the First Aid Kit from the healer unit as it is already used just right now
					player sideChat format ["%1 healed to %2", _hurted, 1 - getDammage _hurted ]; // show a chat message telling that the unit is already been partially healed
				};   
			};
		}; 
		_hurted doFollow player; // make the hurted unit start move to return to formation 
		_healer doFollow player; // make the healer unit start move to return to formation 
		_healer doMove (_healer_pos); // make the healer unit return to its original position
		_hurted doMove (_hurted_pos); // make the hurted unit return to its original position (the same current position )
		hintSilent parseText format ["%1", getDammage _hurted]; // a hint to show the final dammege of the player
		waitUntil { getDammage _hurted < 0.251 }; // wait until the hurted player is healed
	};
};

1- I run the scenario.

2- I execute the above code in the debug console. No errors

3- I shoot one member in my squad and the damage is less than 0.25 >>> nothing happen ... (the damage will be shown in a hint box)

4- I shoot that unit again and again until the damage is more than 0.25 >>> Voala, the Combat Life Saver move and get close that damaged unit healed it to 1 (100%) ... (the final damage will be 0 and will be shown in a hint box) ... Now the Combat Life Saver will NOT have any more Medical Kit.

5- I repeat this to another unit .. and the same process repeat, but this time the healing will be up to 75%, because the Combat Life Saver now has only First Aid Kits.

6- I repeat this shooting a units ... The Combat Life Saver move to that unit and start healing, during this healing process, i shoot another unit, and the Combat Life Saver was also able to heal the second unit ... So far so good.

7- when the Combat Life Saver run out of all First Aid Kits, nothing will happen ... So far so good.

 

You can try it yourself and see if the above code works for you ... Just create a very simple scenario containing ONE Assault squad and then play that scenario and execute the above code in the Debug console and then start shooting your teammates and see what happen.

 

However, there are 2 questions:

1- The above code will work only if I use HIT event handler ... It will not work if I use HandleDamage event handler ... During a battle with enemy, the Combat Life Saver will be busy fighting or hiding and it will NOT attempt to heal damaged units ... I tried to use the above code during a battle with opposing enemy and it did not work, why because it depend on HIT event handler ... The question is: is there any way to make the above code work with HandleDamage event handler ??

 

2- Is there any way to develop the above code so that the Combat Life Saver check the squad every 5 minutes and try to heal the damaged mates one by one ??

 

I can't understand it, why Bohemia Interactive did not include this auto heal  as a game built-in feature? What is the use of a Combat Life Saver in a squad, if he does not heal his team mates by his own? Arma is a military war simulation application (game), and in real life fight a medic soldier will do his job to aid wounded soldiers without waiting for an order from a ranking officer or a squad leader, am I right ?? ... I know there are mods attempting to solve this problem, but i don't think they are so effective.

 

I hope this thread will be a start of an interesting discussion.

Share this post


Link to post
Share on other sites

dreadpirate,

 

Thanks for the fast reply ... very interesting ... I already checked on that thread, so many useful  things are in there ... I will go through all the posts in that thread, and this needs time ... I wounder: When Bohemia Interactive is going to add these highly needed feature (auto heal) as a game built-in feature?

 

I noticed something weird ... When I play against OPFOR enemy (for example in the official campaign), i noticed that OPFOR units they do heal themselves when they are injured, while my own BLUFOR squad teammates don't do the same, they wait for me to order them to heal themselves. WHY ?

 

Actually, I can develop the above code so that when the unit get a hit, then the unit will heal "himself" if "he" has a medikit or first aid kit, this will solve the problem if the combat life saver being busy in fighting or hiding.

 

The help I request is about this complicated concept of scheduled and non-scheduled environment thing. The above code not perfect because I have no idea how to make the function run only ONCE when it is called (right now the function keep repeating when it called).

 

Also, if only HIT event handler work in that code, then how I can make the Combat Life Saver, remember each teammate got wounded ?? In other words, can I save an array of all united get wounded during a fierce fighting, and after the fight end (for example, 2 minutes of NO SHOOTING), the combat life saver will start to do his job (healing other wounded teammates, one by one, by his own) ?? I am sure, this is possible, but I am NOT that good in Arma scripting.

Share this post


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

2- Is there any way to develop the above code so that the Combat Life Saver check the squad every 5 minutes and try to heal the damaged mates one by one ??

 

 

hi, not tried in editor but it just for the concept

 

while { true } do { //start an infinite loop to found injured units
	_healList = [];
	{
		if ((getDammage _x) > 0.1) then {
			_healList pushback _x; // if injured put it into a list
		}
	} count (units player); //it works with your teammates, change it by need (it would be more performance firendly than allUnits)

	{
		// put you healing code here
	} count _healList; // this loops your injured units list
	sleep 300; // pause the cycle for 300 seconds
};

 

Share this post


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

 

hi, not tried in editor but it just for the concept

 


while { true } do { //start an infinite loop to found injured units
	_healList = [];
	{
		if ((getDammage _x) > 0.1) then {
			_healList pushback _x; // if injured put it into a list
		}
	} count (units player); //it works with your teammates, change it by need (it would be more performance firendly than allUnits)

	{
		// put you healing code here
	} count _healList; // this loops your injured units list
	sleep 300; // pause the cycle for 300 seconds
};

 

Hello tRiKy_ch,

 

Thank you for your reply, according to your advice, I did this:

while { true } do { 
	_healList = [];
	{
		if ((getDammage _x) > 0.1) then
		{
			_healList pushback _x;
		};
		if (typeOf _x == "B_medic_F" OR typeOf _x == "I_G_medic_F" OR typeOf _x == "I_medic_F") then
		{
			c_l_s = _x;
			c_l_s_pos = position c_l_s;
		};
	} count (units player);
	
	if (count _healList > 0) then {hintSilent "Healing will start now";};

	{
		if ((items c_l_s find "Medikit" != -1) OR (items c_l_s find "FirstAidKit" != -1)) then
		{
			_injured = _x;
			_injured disableAI "MOVE";
			_injured_pos = position _injured;
			c_l_s enableAI "MOVE";
			c_l_s doMove (_injured_pos);
			waitUntil { c_l_s distance _injured < 2 };
			c_l_s playAction "MedicOther";
			sleep 9;
			if (items c_L_s find "Medikit" != -1) then
			{
				_injured setDamage 0;
				c_l_s removeItem "Medikit";
				hintSilent parseText format ["%1 was healed to %2", name _injured, 1 - getDammage _injured ];
			} else {
				if (items c_L_s find "FirstAidKit" != -1) then
				{
					_injured setDamage 0.25;
					c_l_s removeItem "FirstAidKit";
					hintSilent parseText format ["%1 was healed to %2", name _injured, 1 - getDammage _injured ];
				};
			};
			_injured enableAI "MOVE";
			_injured doFollow player;
			_injured doMove (_injured_pos);
		};
	} count _healList;
	c_l_s doFollow player;
	c_l_s doMove (c_l_s_pos);
	sleep 180;
};

I saved this code in a file called ( SAM_healing.sqf ) ... I put this file in the same folder of my test mission ( mission.sqm ) ... How to make ( SAM_healing.sqf ) be executed when the mission start ?

 

Right now, I use the Debug Console to execute it like this >>> null = [] execVM "SAM_healing.sqf";

 

But I want this file to be executed at the start of the mission ... You can forgive me for asking such question, I am new to Arma scripting, and I am learning from all wonderful people in this forum.

Share this post


Link to post
Share on other sites

create a file called init.sqf (it executes when missions is loaded for more infos go here and here)

and put

[] call compileFinal preprocessFileLineNumbers "SAM_healing.sqf ";

 i see also another thing, if you want could you look dynamically for the medic this way, so you don't heal over a certain distance between medic and injured

(not tested)

while { true } do { 
	_firstCycle = true;
	_nearestMedic = [];
	{
		_nearestMedic = _x nearEntities [["B_medic_F", "I_G_medic_F", "I_medic_F"], 1000]; //it looks for the nearest medic on 1km range
		if (count _nearestMedic > 0 && { (_nearestMedic select 0) != _x }) then { //check if there is a medic in 1km range and if _x is not medic itself
			c_l_s = _nearestMedic select 0;
			if ((getDammage _x) > 0.1) then
			{	
				if (_firstCycle) then {hintSilent "Healing will start now"; _firstCycle = false;};
				if ((items c_l_s find "Medikit" != -1) OR (items c_l_s find "FirstAidKit" != -1)) then
				{
					_injured = _x;
					_injured disableAI "MOVE";
					_injured_pos = position _injured;
					c_l_s enableAI "MOVE";
					c_l_s doMove (_injured_pos);
					waitUntil { c_l_s distance _injured < 2 };
					c_l_s playAction "MedicOther";
					sleep 9;
					if (items c_L_s find "Medikit" != -1) then
					{
						_injured setDamage 0;
						c_l_s removeItem "Medikit";
						hintSilent parseText format ["%1 was healed to %2", name _injured, 1 - getDammage _injured ];
					} else {
						if (items c_L_s find "FirstAidKit" != -1) then
						{
							_injured setDamage 0.25;
							c_l_s removeItem "FirstAidKit";
							hintSilent parseText format ["%1 was healed to %2", name _injured, 1 - getDammage _injured ];
						};
					};
					_injured enableAI "MOVE";
					_injured doFollow player;
					_injured doMove (_injured_pos);
					c_l_s doFollow player;
					c_l_s doMove (c_l_s_pos);				
				};
			};
		};	
	} count (units player);	
	sleep 180;
};

consider it as a starting point 'cause this way if someone get injured while healing has started it had to wait 3 minutes before to get heal (maybe do another check before to sleep)

Share this post


Link to post
Share on other sites

Hello tRiKy_ch,

 

This is even more compact version and more better ... This mean, it is not necessary for the Combat Life Saver to be part of the same squad, it can be any friendly Combat Life Saver in the range of 1000 meters .... Very nice.

 

This _firstCycle = true; i could not understand its importance ... for now, I use these hints only for the purpose of testing, i don't think there should be any hints for this whole auto healing process. So, I will omit this _firstCycle  part.

 

The remaining problem is:

When I give a STOP command to the Combat Life Saver ( c_l_s ) , then "he" will never move, even if there is a script command to make "him" move ( c_l_s doMove (_injured_pos); ) ... I don't know, maybe I should leave it that way, so the Combat Life Saver will not disobey the order and blow up the cover of stealthy ambush or black-op :f: , or maybe I should search for a workaround to force the Combat Life Saver to move even if he is under STOP order, What do you think??

 

Now, the code become like this:

while { true } do {
	{
		self_heal = false;
		_nearestMedic = [];
		_nearestMedic = _x nearEntities [["B_medic_F", "I_G_medic_F", "I_medic_F"], 300];
		if (count _nearestMedic > 0) then
		{
			if (_nearestMedic find _x == -1 ) then // the unit is not a medic
			{ 
				c_l_s = _nearestMedic select 0;
				self_heal = false;
			} else // the unit is medic
			{
				c_l_s = _x;
				self_heal = true;
			};
		};
		if ((!isNull c_l_s) && (group c_l_s != group player)) then
		{
			c_l_s_pos = position c_l_s;
		};
		if ((getDammage _x) > 0.1) then
		{	
			if ((!isNull c_l_s) && ((items c_l_s find "Medikit" != -1) OR (items c_l_s find "FirstAidKit" != -1))) then
			{
				if (!(self_heal)) then
				{
					injuredu = _x;
					injuredu_pos = position injuredu;
					injuredu disableAI "MOVE";
					c_l_s enableAI "MOVE";
					c_l_s doMove (injuredu_pos);
					waitUntil { c_l_s distance injuredu < 2 };
					c_l_s playMove "AinvPknlMstpSlayWrflDnon_medicOther"; // Heal others animation
				} else
				{
					injuredu = c_l_s;
					c_l_s playMove "AinvPknlMstpSlayWrflDnon_medic"; // Heal self animation
					injuredu disableAI "MOVE";
				};
				sleep 9;
				if (items c_L_s find "Medikit" != -1) then
				{
					injuredu setDamage 0;
					c_l_s removeItem "Medikit";
				} else {
					if (items c_L_s find "FirstAidKit" != -1 && getDammage injuredu > 0.25 ) then
					{
						injuredu setDamage 0.25;
						c_l_s removeItem "FirstAidKit";
					};
				};
				injuredu enableAI "MOVE";
				injuredu doFollow player;
				if (group c_l_s == group player) then
				{
					c_l_s doFollow player;
				} else {
					c_l_s doMove (c_l_s_pos);
				};
			};
		};
	} count (units player);	
	sleep 120;
};

What I need to add now is to make each soldier self-heal only if "he" has a medical kit or first aid kit.

Share this post


Link to post
Share on other sites

This is it, now if the soldier has a medical kit or first aid kit, then it will heal "himself" ... i have tested the code below and it seems to be working very nice ... But it is working only on BLUFOR side.

 

while { true } do {
	{
		self_heal = false;
		_nearestMedic = [];
		_nearestMedic = _x nearEntities [["B_medic_F", "I_G_medic_F", "I_medic_F"], 300];
		if (count _nearestMedic > 0) then
		{
			if (_nearestMedic find _x == -1 ) then
			{ 
				c_l_s = _nearestMedic select 0;
				self_heal = false;
			} else // the unit is medic
			{
				c_l_s = _x;
				self_heal = true;
			};
		};
		if ((!isNull c_l_s) && (group c_l_s != group player)) then
		{
			c_l_s_pos = position c_l_s;
		};
		if ((getDammage _x) > 0.1) then
		{
			if ((items _x find "Medikit" != -1) OR (items _x find "FirstAidKit" != -1)) then
			{
				_x playMove "AinvPknlMstpSlayWrflDnon_medic";
				if (items _x find "Medikit" != -1) then
				{
					_x setDamage 0;
					_x removeItem "Medikit";
				} else {
					if (items _x find "FirstAidKit" != -1 && getDammage _x > 0.25 ) then
					{
						_x setDamage 0.25;
						_x removeItem "FirstAidKit";
					};
				};
			} else
			{
				if ((!isNull c_l_s) && ((items c_l_s find "Medikit" != -1) OR (items c_l_s find "FirstAidKit" != -1))) then
				{
					if (!(self_heal)) then
					{
						injuredu = _x;
						injuredu_pos = position injuredu;
						injuredu disableAI "MOVE";
						c_l_s enableAI "MOVE";
						c_l_s doMove (injuredu_pos);
						waitUntil { c_l_s distance injuredu < 2 };
						c_l_s playMove "AinvPknlMstpSlayWrflDnon_medicOther";
					} else
					{
						injuredu = c_l_s;
						c_l_s playMove "AinvPknlMstpSlayWrflDnon_medic"; 
						injuredu disableAI "MOVE";
					};
					sleep 9;
					if (items c_L_s find "Medikit" != -1) then
					{
						injuredu setDamage 0;
						c_l_s removeItem "Medikit";
					} else {
						if (items c_L_s find "FirstAidKit" != -1 && getDammage injuredu > 0.25 ) then
						{
							injuredu setDamage 0.25;
							c_l_s removeItem "FirstAidKit";
						};
					};
					injuredu enableAI "MOVE";
					injuredu doFollow player;
					if (group c_l_s == group player) then
					{
						c_l_s doFollow player;
					} else {
						c_l_s doMove (c_l_s_pos);
					};
				};
			};
		};
	} count (units player);	
	sleep 180;
};

Now, I consider this auto heal problem solved ... :eyeheart:

 

Next step .. is to convert the code into a mod, and I don't know how to do that :don11:

Share this post


Link to post
Share on other sites
4 hours ago, samir17864 said:

This _firstCycle = true; i could not understand its importance ... for now, I use these hints only for the purpose of testing, i don't think there should be any hints for this whole auto healing process. So, I will omit this _firstCycle  part.

is used to see if the current cycle is the first iteration or not, i used this only to not spam the "hintSilent "Healing will start now"" but honsetly i doesn't really know how do you intended this

 

Quote

But it is working only on BLUFOR side.

'cause you're cycling (units player) wich means player's teammates, if you want to cycle opfor too could you turn back to allUnits array, in this case you have to update also your medic classes on (_nearestMedic = _x nearEntities [["B_medic_F", "I_G_medic_F", "I_medic_F"], 300];)

 

Quote

The remaining problem is:

When I give a STOP command to the Combat Life Saver ( c_l_s ) , then "he" will never move, even if there is a script command to make "him" move ( c_l_s doMove (_injured_pos); ) ... I don't know, maybe I should leave it that way, so the Combat Life Saver will not disobey the order and blow up the cover of stealthy ambush or black-op , or maybe I should search for a workaround to force the Combat Life Saver to move even if he is under STOP order, What do you think??

did you solved that or still an issue?

Share this post


Link to post
Share on other sites

Believe me, it's not simple to manage all cases. Unconscious state can add many weird leader orders, animation endings, MP problems. Not mentioning the cases of your unit is inside a vehicle or your medic is hurt at his turn!

 

You can choose parameters in this script.

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

×