Jump to content

Photo
- - - - -

CLY Heal - a self-bandaging script


  • Please log in to reply
72 replies to this topic
Celery
Celery

    First Lieutenant

  • Members
  • 5084 posts

#1

Posted 25 August 2010 - 15:46

This is an easy to use healing script that you can just slap in the mission folder and execute in the init script. :)

Features:
  • Correct healing animations for each weapon type
  • You can heal others
  • You can interrupt healing
  • You can set a damage threshold to prevent heal action spam with negligible wounds
  • You can set how healthy you will be after bandaging yourself
  • You can set the number bandages at start
  • You can give and take bandages (provided they're not unlimited)
  • You are notified when a friend heals you or gives you a bandage

Put this in your init script:
[player,0.2,0.15,3,true] execVM "cly_heal.sqf"

Array explanation: [player,damage threshold,damage after healing,uses (-1 is unlimited),action pops up when relevant (optional)]

If you want to add extra bandages to your unit afterwards, use this setVariable ["CLY_healings",(this getVariable "CLY_healings")+1,true]


cly_heal.sqf:
/*
	CLY Heal - a self-bandaging script written by Celery.
	
	-How to use-
	Execute in init script:
		[player,0.2,0.15,3,true] execVM "cly_heal.sqf";
	The first number is the damage threshold after which you are given the option to heal.
	The second one is the player's damage after healing.
	The third one is the number of bandages. -1 is unlimited.
	The boolean at the end is optional, setting it to true will make the bandaging action
	pop up when the player is injured. It's false by default.
	
	How to add bandages to a unit:
		unit setVariable ["CLY_healings",this getVariable "CLY_healings"+1,true]
	Make an AI unit drop bandages when it dies:
		0=[this,0,0,1,true] execVM "cly_heal.sqf";
*/

_target=_this select 0;
_caller=_this select 1;
_id=_this select 3;

//Add PVEHs
if (isNil "CLY_healfirstrun") then {
	CLY_healfirstrun=true;
	"CLY_healinterruptpv" addPublicVariableEventHandler {
		_var=_this select 1;
		_var select 0 switchMove (_var select 1);
		_var select 0 playMoveNow (_var select 1);
	};
	"CLY_healbandagepv" addPublicVariableEventHandler {
		_var=_this select 1;
		_unit=_var select 0;
		if (count _var>1) then {
			_unit addAction (_var select 1);
		} else {
			for "_x" from 0 to 99 do {_unit removeAction _x};
		};
	};
	"CLY_healannouncepv" addPublicVariableEventHandler {
		_var=_this select 1;
		_unit=_var select 0;
		_text=_var select 1;
		if (player==_unit) then {
			titleText _text;
		};
	};
};

//Give bandage
if (_id in ["give"]) then {
	_caller setVariable ["CLY_healings",(_caller getVariable "CLY_healings")-1,true];
	_target setVariable ["CLY_healings",(_target getVariable "CLY_healings")+1,true];
	titleText [format ["Bandage given to %1",name _target],"PLAIN DOWN",0.3];
	_text=[format ["Received bandage from %1",name _caller],"PLAIN DOWN",0.3];
	CLY_healannouncepv=[_target,_text];
	publicVariable "CLY_healannouncepv";
};

//Interrupt healing
if (_id in ["interrupt"]) then {
	_caller setVariable ["CLY_healinterrupt",true];
};

//Take bandage
if (typeName _id=="ARRAY") then {
	if (_id select 0=="take") then {
		_taken=_id select 1;
		_caller setVariable ["CLY_healings",(_caller getVariable "CLY_healings")+_taken,true];
		_s=if (_taken>1) then {"s"} else {""};
		titleText [format ["%1 bandage%2 taken",_taken,_s],"PLAIN DOWN",0.3];
		for "_x" from 0 to 99 do {_target removeAction _x};
		CLY_healbandagepv=[_target];
		publicVariable "CLY_healbandagepv";
	};
};

//Heal self or other
if (_id in ["heal","healother"]) then {
	_weapontype=getNumber (configFile/"CfgWeapons"/(currentWeapon _caller)/"type");
	_weapontypes=[];
	{_weapontypes set [count _weapontypes,getNumber (configFile/"CfgWeapons"/_x/"type")]} forEach weapons _caller;
	
	_anim="ainvpknlmstpsnonwnondnon_medic_2";
	if (_weapontype in [1,5] or (_weapontype==0 and {_x in [1,5]} count _weapontypes>0)) then {_anim="ainvpknlmstpslaywrfldnon_medic"};
	if (_weapontype==2 or (_weapontype==0 and 2 in _weapontypes)) then {_anim="ainvpknlmstpsnonwnondnon_medic_1"};
	
	if (_id=="healother") then {
		_text=[format ["%1 is bandaging you",name _caller],"PLAIN DOWN",0.3];
		CLY_healannouncepv=[_target,_text];
		publicVariable "CLY_healannouncepv";
	};
	
	_caller playMove _anim;
	_caller setVariable ["CLY_healcooldown",time+5];
	_caller setVariable ["CLY_healinterrupt",false];
	
	waitUntil {animationState _caller in ["ainvpknlmstpslaywrfldnon_medic","ainvpknlmstpsnonwnondnon_medic_1","ainvpknlmstpsnonwnondnon_medic_2"]};
	waitUntil {_caller getVariable "CLY_healinterrupt" or !alive _target or _caller distance _target>3 or !(animationState _caller in ["ainvpknlmstpslaywrfldnon_medic","ainvpknlmstpsnonwnondnon_medic_1","ainvpknlmstpsnonwnondnon_medic_2"])};
	if (alive _caller) then {
		//Heal
		if (alive _target and !(_caller getVariable "CLY_healinterrupt")) then {
			_healee=if (_id=="healother") then {_target} else {_caller};
			if (damage _healee>_caller getVariable "CLY_healthreshold") then {
				_healee setDamage (_caller getVariable "CLY_healdamage");
				_caller setVariable ["CLY_healings",(_caller getVariable "CLY_healings")-1,true];
			};
			//Heal legs
			if (!canStand _healee) then {
				_healee setHit ["legs",_caller getVariable "CLY_healdamage"];
				_caller setVariable ["CLY_healings",(_caller getVariable "CLY_healings")-1,true];
			};
		//Interrupt healing
		} else {
			_caller setVariable ["CLY_healinterrupt",false];
			_anim="ainvpknlmstpslaywrfldnon_amovpknlmstpsnonwnondnon";
			if (_weapontype in [1,5]) then {_anim="ainvpknlmstpslaywrfldnon_amovpknlmstpsraswrfldnon"};
			if (_weapontype==2) then {_anim="ainvpknlmstpsnonwnondnon_amovpknlmstpsraswpstdnon"};
			if (_weapontype==4) then {_anim="amovpknlmstpsnonwnondnon_amovpknlmstpsraswlnrdnon"};
			CLY_healinterruptpv=[_caller,_anim];
			publicVariable "CLY_healinterruptpv";
			_caller switchMove _anim;
			_caller playMoveNow _anim;
		};
	};
};

//Main loop
while {typeName _id=="SCALAR"} do {
	if (!local _target) exitWith {};
	_healthreshold=_this select 1;
	_healdamage=_this select 2;
	_healings=floor (_this select 3);
	_popup=if (count _this>4) then {_this select 4} else {false};
	CLY_healanims=["amovpknlmstpsraswrfldnon_ainvpknlmstpslaywrfldnon","ainvpknlmstpslaywrfldnon_medic","ainvpknlmstpslaywrfldnon_amovpknlmstpsraswrfldnon","amovpknlmstpsraswpstdnon_ainvpknlmstpsnonwnondnon","amovpknlmstpsraswpstdnon_ainvpknlmstpsnonwnondnon_end","ainvpknlmstpsnonwnondnon_medic_1","ainvpknlmstpsnonwnondnon_amovpknlmstpsraswpstdnon","amovpknlmstpsraswlnrdnon_ainvpknlmstpsnonwnondnon","ainvpknlmstpsnonwnondnon_medic_2","amovpknlmstpsnonwnondnon_amovpknlmstpsraswlnrdnon"];
	
	//Add take bandage action to AI, then exit
	if (_target!=player) exitWith {
		_target setVariable ["CLY_healings",_healings,true];
		[_target] spawn {
			_unit=_this select 0;
			waitUntil {!alive _unit};
			if (!isPlayer _unit and _unit getVariable "CLY_healings">0) then {
				_actionname=if (_unit getVariable "CLY_healings">1) then {
					"Take bandages";
				} else {
					"Take bandage";
				};
				_action=[
					_actionname,
					"cly_heal.sqf",
					["take",_unit getVariable "CLY_healings"],
					1.4,
					true,
					true,
					"",
					"_this!=_target and !alive _target and _this distance _target<4 and _this getVariable 'CLY_healings'>=0"
				];
				_unit addAction _action;
				CLY_healbandagepv=[_unit,_action];
				publicVariable "CLY_healbandagepv";
			};
		};
	};
	
	waitUntil {alive player};
	_unit=player;
	
	if (isNil {_unit getVariable "CLY_healings"}) then {_unit setVariable ["CLY_healings",_healings,true]};
	if (isNil {_unit getVariable "CLY_healthreshold"}) then {_unit setVariable ["CLY_healthreshold",_healthreshold]};
	if (isNil {_unit getVariable "CLY_healdamage"}) then {_unit setVariable ["CLY_healdamage",_healdamage]};
	if (isNil {_unit getVariable "CLY_healcooldown"}) then {_unit setVariable ["CLY_healcooldown",time-5]};
	if (isNil {_unit getVariable "CLY_healinterrupt"}) then {_unit setVariable ["CLY_healinterrupt",false]};
	
	_healaction=100;
	_interruptaction=100;
	_healotheraction=100;
	_giveaction=100;
	_nearestaliveactive=objNull;
	_reset=true;
	_leftstring="";
	
	while {alive _unit and _unit==player} do {
		//Reset actions
		if (_reset or _unit getVariable "CLY_healings"!=_healings) then {
			_unit removeAction _healaction;
			_unit removeAction _interruptaction;
			
			_nearestaliveactive removeAction _healotheraction;
			_nearestaliveactive removeAction _giveaction;
			_nearestaliveactive=objNull;
			
			_healings=_unit getVariable "CLY_healings";
			_leftstring="";
			if (_healings>0) then {_leftstring=format [" (%1 left)",_unit getVariable "CLY_healings"]};
			
			_healaction=_unit addAction [
				format ["Bandage wounds%1",_leftstring],
				"cly_heal.sqf",
				"heal",	//Argument
				1.37,		//Priority
				_popup,	//Action pops up?
				true,		//Hide on use
				"",		//Shortcut
				"_this==_target and (damage _this>_this getVariable 'CLY_healthreshold' or !canStand _this) and !(animationState _this in CLY_healanims) and time>_this getVariable 'CLY_healcooldown' and _this getVariable 'CLY_healings'!=0"
			];
			_interruptaction=_unit addAction [
				"Cancel bandaging",
				"cly_heal.sqf",
				"interrupt",
				1.4,
				true,
				true,
				"",
				"_this==_target and animationState _target in ['ainvpknlmstpslaywrfldnon_medic','ainvpknlmstpsnonwnondnon_medic_1','ainvpknlmstpsnonwnondnon_medic_2']"
			];
			_reset=false;
		};
		
		_nearestalive=objNull;
		_nearestalivedist=5;
		
		//Determine nearest alive and dead units
		{
			if (_x!=_unit and _unit distance _x<_nearestalivedist and alive _x and _unit countEnemy [_x]==0) then {
				_nearestalive=_x;
				_nearestalivedist=_x distance _unit;
			};
		} forEach allUnits;
		if (_nearestalive!=_nearestaliveactive) then {
			_nearestaliveactive removeAction _healotheraction;
			_nearestaliveactive removeAction _giveaction;
			if (isNull _nearestalive) then {_nearestaliveactive=objNull};
		};
		
		//Add bandaging and give bandage action
		if (!isNull _nearestalive and _nearestalive!=_nearestaliveactive) then {
			_nearestaliveactive=_nearestalive;
			_healotheraction=_nearestaliveactive addAction [
				format ["Bandage %1%2",name _nearestaliveactive,_leftstring],
				"cly_heal.sqf",
				"healother",
				1.38,
				true,
				true,
				"",
				"_this!=_target and (damage _target>_this getVariable 'CLY_healthreshold' or !canStand _target) and !(animationState _this in CLY_healanims) and time>_this getVariable 'CLY_healcooldown' and _this getVariable 'CLY_healings'!=0 and _this distance _target<3"
			];
			_giveaction=_nearestaliveactive addAction [
				format ["Give bandage to %1%2",name _nearestaliveactive,_leftstring],
				"cly_heal.sqf",
				"give",
				1.39,
				true,
				true,
				"",
				"_this!=_target and alive _target and !(animationState _this in CLY_healanims) and time>_this getVariable 'CLY_healcooldown' and _target getVariable 'CLY_healings'>=0 and _this getVariable 'CLY_healings'>0 and _this distance _target<3"
			];
		};
		sleep 0.1;
	};
	
	//Remove actions at death or unit switch
	_unit removeAction _healaction;
	_unit removeAction _interruptaction;
	_nearestaliveactive removeAction _giveaction;
	
	//Take bandage from corpse action
	if (!alive _unit and _unit getVariable "CLY_healings">0) then {
		_actionname=if (_unit getVariable "CLY_healings">1) then {
			"Take bandages";
		} else {
			"Take bandage";
		};
		_action=[
			_actionname,
			"cly_heal.sqf",
			["take",_unit getVariable "CLY_healings"],
			1.4,
			true,
			true,
			"",
			"_this!=_target and !alive _target and _this distance _target<4 and _this getVariable 'CLY_healings'>=0 and !(_this isKindOf 'Animal')"
		];
		_unit addAction _action;
		CLY_healbandagepv=[_unit,_action];
		publicVariable "CLY_healbandagepv";
	};
	
	//Reset bandages for respawn
	if (!alive _unit) then {_unit setVariable ["CLY_healings",nil,true]};
	
	waitUntil {alive player};
	_target=player;
};

Edited by Celery, 02 October 2011 - 07:30.


B00tsy
B00tsy

    First Sergeant

  • Members
  • 901 posts

#2

Posted 25 August 2010 - 15:57

Thanks! will try it out :)

kylania
kylania

    Lieutenant Colonel

  • Members
  • 8281 posts

#3

Posted 25 August 2010 - 16:45

Ack! SQS! Kill it with fire!

kremator
kremator

    Major

  • Members
  • 7518 posts

#4

Posted 25 August 2010 - 18:01

Cheers Celery. Will give it a go mate.

B00tsy
B00tsy

    First Sergeant

  • Members
  • 901 posts

#5

Posted 26 August 2010 - 13:26

I keep getting that the script is not found. I named the script in the mission folder as described (cly_heal.sqs), but it shows up still as a text document. I placed this: [player,0.2,0.15,3] exec "cly_heal.sqs"; in the players init.

Celery
Celery

    First Lieutenant

  • Members
  • 5084 posts

#6

Posted 26 August 2010 - 13:31

I keep getting that the script is not found. I named the script in the mission folder as described (cly_heal.sqs), but it shows up still as a text document. I placed this: [player,0.2,0.15,3] exec "cly_heal.sqs"; in the players init.


It's possible that your OS hides file extensions and didn't change your txt file into sqs for real.

B00tsy
B00tsy

    First Sergeant

  • Members
  • 901 posts

#7

Posted 26 August 2010 - 13:35

Ahh yes I had that also when trying to add .ogg sounds it refused to find the sounds in game, still can't add my own sounds. And now with scripts too. I hate vista :(

Mosh
Mosh

    Sergeant Major

  • Members
  • 1647 posts

#8

Posted 26 August 2010 - 13:37

Thanks Celery, another handy script from you! :)

Windows 7 64-bit | AMD FX 8350 4.0 GHZ | GTX 780 (347.09) | 32 GB RAM
ALL SSD (512GB 120GB 120GB 120GB 80GB 60GB)
Logitech G710+ G700s G930 | TrackIR 5 | Saitek X52 Pro + Pro Flight Rudder


Murklor
Murklor

    First Sergeant

  • Members
  • 831 posts

#9

Posted 26 August 2010 - 18:13

Ack! SQS! Kill it with fire!

It has goto! Fire will not be enough!!! :eek:

An SQF version should be next order of the day. Just a suggestion.

Celery
Celery

    First Lieutenant

  • Members
  • 5084 posts

#10

Posted 26 August 2010 - 18:16

An SQF version should be next order of the day. Just a suggestion.


Unless the script is bad because of its format and sqf will fix it, I have no intention to convert it. You will never see a difference in how it works.

B00tsy
B00tsy

    First Sergeant

  • Members
  • 901 posts

#11

Posted 27 August 2010 - 13:54

I gave this script an other atempt and I still get that the script is not found. What the hell am I doing wrong?

I have converted the txt with the code into a sqs and placed it into the main sp missions map, the sqs is named 'cly_heal', I placed this "[player,0.2,0.15,3] exec "cly_heal.sqs";" into the intit of the player. On start up of the mission the pop up sais the script can't be found.

I placed everything where it should be right?

When I place and activation command with a BIS script such as this one in the player init "[this, 1000] exec "ca\air2\halo\data\Scripts\HALO_init.sqs"" it works fine.

Edited by B00tsy, 27 August 2010 - 13:57.


Wiggum
Wiggum

    Master Gunnery Sergeant

  • Members
  • 1379 posts

#12

Posted 27 August 2010 - 14:11

Thanks Celery for that great script, really usefull ! :thumb:

Is it possible to add more bandages later ?
For example lest say i give the player 3 bandages. But he can found more in a crate (i would add a action like "Take bandages" to the crate) and now he gets +1 bandages (if he had 1 before left he now has 2).
So, is something possible ?

I gave this script an other atempt and I still get that the script is not found. What the hell am I doing wrong?

I have converted the txt with the code into a sqs and placed it into the main sp missions map, the sqs is named 'cly_heal', I placed this "[player,0.2,0.15,3] exec "cly_heal.sqs";" into the intit of the player. On start up of the mission the pop up sais the script can't be found.

I placed everything where it should be right?

When I place and activation command with a BIS script such as this one in the player init "[this, 1000] exec "ca\air2\halo\data\Scripts\HALO_init.sqs"" it works fine.


Just create a new .txt file in you mission folder and copy&past the code that Celery posted. Save the file and rename it to cly_heal.sqs (this is the complete filename !!).

Now it should work.

Edited by Wiggum, 27 August 2010 - 14:14.


B00tsy
B00tsy

    First Sergeant

  • Members
  • 901 posts

#13

Posted 27 August 2010 - 14:31

Thanks Celery for that great script, really usefull ! :thumb:

Is it possible to add more bandages later ?
For example lest say i give the player 3 bandages. But he can found more in a crate (i would add a action like "Take bandages" to the crate) and now he gets +1 bandages (if he had 1 before left he now has 2).
So, is something possible ?



Just create a new .txt file in you mission folder and copy&past the code that Celery posted. Save the file and rename it to cly_heal.sqs (this is the complete filename !!).

Now it should work.


Done exactly that. Tried as cly_heal and cly_heal.sqs in the name, the map shows it is a sqs file and not a txt file. Done everything right.
I have the same crap when adding ext files etc...

Thanks BIS for this intuitive and easy to use editor.:mad:

Celery
Celery

    First Lieutenant

  • Members
  • 5084 posts

#14

Posted 27 August 2010 - 14:40

I gave this script an other atempt and I still get that the script is not found. What the hell am I doing wrong?

I placed everything where it should be right?

It's definitely your OS playing tricks. Can you enable file extensions in the Explorer folder preferences? A #2 trick would be to copy an existing sqs file that you may have somewhere and rename it and replace its contents with CLY Heal.


Is it possible to add more bandages later ?
For example lest say i give the player 3 bandages. But he can found more in a crate (i would add a action like "Take bandages" to the crate) and now he gets +1 bandages (if he had 1 before left he now has 2).
So, is something possible ?

The command CLY_healings=CLY_healings+1 will increase the bandage count. :)

B00tsy
B00tsy

    First Sergeant

  • Members
  • 901 posts

#15

Posted 27 August 2010 - 15:23

It's definitely your OS playing tricks. Can you enable file extensions in the Explorer folder preferences? A #2 trick would be to copy an existing sqs file that you may have somewhere and rename it and replace its contents with CLY Heal.



Sorry for my mad remark about the editor, was just frustration that something this simple persistently does not work for me.
I have extentions enabled in the map options. Unfortunately I do not have an existing sqs file that i can use, I only have existing some sqf files from the domination mission.

I took a screenshot of it all to show that I did everything right (according to me), If anyone sees an error I made I will be glad to hear about it so that I can finally get external scripts working.

Posted Image

Celery
Celery

    First Lieutenant

  • Members
  • 5084 posts

#16

Posted 27 August 2010 - 17:10

I took a screenshot of it all to show that I did everything right (according to me), If anyone sees an error I made I will be glad to hear about it so that I can finally get external scripts working.

Posted Image


How should I say this... :P

The files belong in the folder of the mission that you are editing (and have saved) in the editor. The folder can be found at My Documents\Arma 2 other profiles\username\missions\missionname :)

B00tsy
B00tsy

    First Sergeant

  • Members
  • 901 posts

#17

Posted 27 August 2010 - 17:39

So yeah lol I have always placed them in the main sp mission folder :o I always assumed that you had to place it there because I see the mission pbo's there too. Nowhere I saw anything about having to use the map in my documents.

Thanks man :yay:

Undeceived
Undeceived

    Sergeant Major

  • Members
  • 1444 posts

#18

Posted 28 December 2010 - 18:22

Hi Celery

Is it somehow possible to adapt the script so that you as commander can order a (non medic) AI member of your group to bandage himself? This would help me a lot.

Posted Image Posted Image
Dying Ember | Resistance campaign for Arma 3
Black Lands | Resistance campaign for Arma 2: CO

For The Life Of A Friend | SP scenario for Arma 2: CO
Evil's Last Will | SP scenario for Arma


Celery
Celery

    First Lieutenant

  • Members
  • 5084 posts

#19

Posted 28 December 2010 - 18:30

Hi Celery

Is it somehow possible to adapt the script so that you as commander can order a (non medic) AI member of your group to bandage himself? This would help me a lot.


AI could be made to heal itself using a similar animation procedure triggered by damage to the unit, but I cannot provide you the finished product.

Phantom Six
Phantom Six

    Master Sergeant

  • Members
  • 689 posts

#20

Posted 05 April 2011 - 05:53

Hello celery, about your script, I tried it in the singleplayer and it works flawlessly, but when I try to use your script in multiplayer, the bandage option does not appear, can you help me fix it please? Or is it singleplayer only?
Join CUP, the Commmunity Upgrade Project, or spread the word today. Help port over Arma 1/2 assets over to Arma 3 in high quality. http://forums.bistud...Upgrade-Project
Portfolio Site
Join CiA Coop Nights