Jump to content
Sign in to follow this  
celery

CLY Heal - a self-bandaging script

Recommended Posts

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

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

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 :(

Share this post


Link to post
Share on other sites

Thanks Celery, another handy script from you! :)

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
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:

Share this post


Link to post
Share on other sites
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. :)

Share this post


Link to post
Share on other sites
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.

02773594977583.jpg

Share this post


Link to post
Share on other sites
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.

02773594977583.jpg

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 :)

Share this post


Link to post
Share on other sites

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:

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

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?

Share this post


Link to post
Share on other sites

Script updated!

  • Renovated the whole script
  • You can now heal others
  • Bandages should now be persistent for each unit regardless of player switching
  • You can share bandages with others
  • You can take bandages from bodies that have them
  • Interrupt system is now action based

Share this post


Link to post
Share on other sites

Yes i just noticed it!!!

Actually i don't understand why, cause i was never able to start with SQS and recently started with SQF.

It just looks more simple for me.

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  

×