Jump to content
Sign in to follow this  
tpw

[Resolved] SetDamage ot working properly for me in 1.55

Recommended Posts

Hi all

A while ago AZcoder gave me the heads up on a nice little "invincibility script" which worked thusly:

In each unit's init I added an eventhandler

addEventHandler ["HandleDamage", {_this execVM "scripts\unitnearlykilled.sqf"}]

unitnearlykilled.sqf:

// Units don't die, thanks to AZCoder for the tips

private ["_targ","_dmg","_totalDmg"];
_targ = _this select 0;
_dmg = _this select 2;

// calculate damage
_totalDmg = (damage _targ) + _dmg;
if (_totalDmg > 0.5) then {
_totalDmg = 0.5;
};
_targ setDamage _totalDmg;

This combination worked very well right up until I installed CO patch 1.55 (75445). Now it does absolutely nothing. The eventhandler is handling the event, but the script it calls is not working as previously.

I've even simplified it to the following for total invulnerability.

_targ = _this select 0;
_targ setDamage 0;

but it still refuses to work.

Does anyone know what might have changed to cause this behaviour, or if there are any workarounds?

Edited by Dwarden
resolved problem

Share this post


Link to post
Share on other sites

addEventHandler ["HandleDamage", {_this execVM "scripts\unitnearlykilled.sqf"}]

It should be:

this addEventHandler ["HandleDamage", {_this execVM "scripts\unitnearlykilled.sqf"}]

Also wouldn't it be easyer to use:

this allowDamage False;

;)

Share this post


Link to post
Share on other sites
addEventHandler ["HandleDamage", {_this execVM "scripts\unitnearlykilled.sqf"}]

It should be:

this addEventHandler ["HandleDamage", {_this execVM "scripts\unitnearlykilled.sqf"}]

Also wouldn't it be easyer to use:

this allowDamage False;

;)

Thanks SNKMAN

I actually do use

this addEventHandler ["HandleDamage", {_this execVM "scripts\unitnearlykilled.sqf"}]

, just forgot to put the "this" in my post. The eventhandler is working.

this allowDamage False is not as useful because with the functioning script, players can still take damage, or it can be refined further so that they are knocked out etc.

Share this post


Link to post
Share on other sites

After a bit of research it turns out that ACE 1.6 is causing the issue, since it sets up its own HandleDamage eventhandler ( in ace_sys_wounds), which overrides anything I put in mine.

Share this post


Link to post
Share on other sites

Only if you have the optional wounds system enabled. Same should occur if you have BIS wounding enabled I guess.

Also check the coding notes of the wounding system for additional information and options to override ACE wounds;

http://ace.dev-heaven.net/wagn/Wounding_System

Specifically ace_w_allow_dam and ace_w_eh object variables, and the addDamage function.

Additionally, it's recommended not to use execVM, not just for performance reasons (http://community.bistudio.com/wiki/6thSense.eu:EG#Scripting_Tips) but because handleDamage eventhandler expects a return value (number), based on the return value it applies damage.

execVM returns a script-handle.

Call (compile preProcessFile or a global variable with the function), will return whatever you tell it to return at the exit of the function.

http://community.bistudio.com/wiki/ArmA_2:_Event_Handlers#HandleDamage

Edited by Sickboy

Share this post


Link to post
Share on other sites
Only if you have the optional wounds system enabled. Same should occur if you have BIS wounding enabled I guess.

Also check the coding notes of the wounding system for additional information and options to override ACE wounds;

http://ace.dev-heaven.net/wagn/Wounding_System

Specifically ace_w_allow_dam and ace_w_eh object variables, and the addDamage function.

Additionally, it's recommended not to use execVM, not just for performance reasons (http://community.bistudio.com/wiki/6thSense.eu:EG#Scripting_Tips) but because handleDamage eventhandler expects a return value (number), based on the return value it applies damage.

execVM returns a script-handle.

Call (compile preProcessFile or a global variable with the function), will return whatever you tell it to return at the exit of the function.

http://community.bistudio.com/wiki/ArmA_2:_Event_Handlers#HandleDamage

Huge thanks for all the info Sickboy. That's given me plenty of light reading to do...

FWIW I'll gladly ditch my script in favour of all the other excellent stuff ACE brings to the game.

---------- Post added at 23:10 ---------- Previous post was at 22:52 ----------

Might this do the trick?

[unit, <damage value between 0 and 1>] call ace_sys_wounds_fnc_addDamage;

If I set value of 0.5 does it add that much damage or set the total damage to 0.5?

Is there such a command:

ace_sys_wounds_fnc_setDamage;

Share this post


Link to post
Share on other sites

addDamage adds it. old function prdamcheck sets it iirc.

I think you could best override the wounds behaviour by setting "the ace_w_eh" object variable on the unit(s) as described in the wounds notes.

And then use your own handleDamage eventhandler.

Share this post


Link to post
Share on other sites

You can disable ACE handleDamage and handleHeal completely.

To disable handleDamage (means, no handleDamage EH is added to units) use the following in init.sqf:

if (isServer) then {
   ace_w_no_handledamage = true;
   publicVariable "ace_w_no_handledamage";
};

To remove handleHeal (no handleHeal EH is added to units):

if (isServer) then {
   ace_w_no_handleheal = true;
   publicVariable "ace_w_no_handleheal";
};

(or put those variables in an object init line: ace_w_no_handledamage = true; ace_w_no_handleheal = true; )

Xeno

Share this post


Link to post
Share on other sites

Thanks so much gentlemen, I shall give these a try ASAP.

Basically, I really like the way ACE handles damage and wounds, I just want it so that the units cannot be killed, but knocked out instead.

It blows my mind how well this game and its mods are supported!

Share this post


Link to post
Share on other sites

tpw: If you are interested, I have a more complete version of the function that I use in the campaign I am building. I have tested it with the current 1.6 ACE with wounding, and it works fine. I did not do anything special to make it work, although this version is a little different.

I wrote this solely with single player in mind, so if you are doing MP it may need publicVariable calls and such. I have no experience with MP scripting.

In your init.sqf, define the function like this:

AZC_fnc_invincible = compile preprocessFile "fnc_invincible.sqf";

You can change the AZC name, I'm just using my OFPEC tag :)

For the test I did, I placed a soldier named Cpl Boom. After the code above, put this:

[boom,120] call AZC_fnc_invincible;

The 120 is the max number of seconds that Boom will be incapacitated. So change that as you wish.

Here is the code for fnc_invincible.sqf

/* ----------------------------------------------------------------------------
Function: AZC_fnc_invincible
Author: AZCoder
Version: 1.0
Created: 10/18/2010
Modified: 11/14/2010
Description:
Makes given unit invincible to death. Its purpose is to simulate severe injuries without allowing a key AI to die during a mission.

Parameters:
_unit		- unit to keep alive; if it's human then it will simulate injury
_recovery	- recovery time from severe injury in seconds

Returns: nothing.

Examples:
[Escobar,60] call AZC_fnc_invincible; --> unit Escobar will remain incapcitated for 60 seconds if mortally wounded.
---------------------------------------------------------------------------- */
private ["_unit","_recovery","_unitRecovery"];
_unit		= _this select 0;
_recovery	= _this select 1;

if (_recovery < 1) then { _recovery = 1; };

// store variable with unique name in mission namespace
_unitRecovery = format["AZC_recover%1",_unit];
missionNamespace setVariable[_unitRecovery, _recovery];

_unit addEventHandler ["HandleDamage", {
private ["_targ","_dmg","_totalDmg"];
_targ 	= _this select 0;
_dmg 	= _this select 2;

// calculate damage
_totalDmg = (damage _targ) + _dmg;
if (_totalDmg > 0.88) then
{ 
	// must set damage because this event handler prevents it
	_targ setDamage 0.88;
	if (_targ isKindOf "Man") then
	{
		if (!alive(_targ)) exitWith {};
		// if alive then run wounded animation for length of _recovery
		_targ playMove "AinjPpneMstpSnonWrflDnon";
		[_targ] spawn
		{
			private ["_injured","_reco","_limit"];
			_injured = _this select 0;
			_unitRecovery = format["AZC_recover%1",_injured];
			_reco = missionNamespace getVariable _unitRecovery;
			_limit = time + _reco;
			// if unit gets healed during _recovery time, exit this loop
			while { damage _injured > 0.8 } do
			{
				// sleep won't work here, the intention is to allow a medic to heal the injuree
				if (time > _limit) exitWith { _injured setDamage 0.8; };
			};
			// set to normal "ready" animation
			_injured playMoveNow "AmovPercMstpSlowWrflDnon";
			if (damage _injured > 0.8) then { _injured setDamage 0.8; };
		};
	};
}
else
{
	// if total damage less than .88, set damage to total of existing damage plus handled damage
	_targ setDamage _totalDmg;
};
}];

If a medic heals the injured guy before the time limit passes, then the script will abort.

Bear in mind, when the soldier is on the ground incapacitated, the animation really just places him on his back and he looks almost dead, but his head will move if you approach him.

Share this post


Link to post
Share on other sites

You are a bloody legend AZC! I tried it and it works exactly as advertised!

Actually this adds a huge amount to the gameplay, if I set it for me and everyone in my squad. If you get hit you go down and stay down for a few minutes, and even if you manage to get patched up, you can still pass out at some time in the future. So it seems like much less of a magic wand approach to healing.

Thanks again AZC.

Share this post


Link to post
Share on other sites

Thanks AZC for this.

Just wondering, guys, is there a way to make it so that if all units specified go down at once, the mission fails (Like L4D's system), as nobody can patch anybody else up? I.e. if it spits out a variable that can be checked, one could just run a trigger with condition Unit1 --Incapacitated variable here-- && Unit2 --Incapacitated variable here- etc, etc.

Any ideas? :)

Share this post


Link to post
Share on other sites
Thanks AZC for this.

Just wondering, guys, is there a way to make it so that if all units specified go down at once, the mission fails (Like L4D's system), as nobody can patch anybody else up? I.e. if it spits out a variable that can be checked, one could just run a trigger with condition Unit1 --Incapacitated variable here-- && Unit2 --Incapacitated variable here- etc, etc.

Any ideas? :)

Could you put a counter in there to add +1 when incapped and -1 if healed. Add a define for the number of players on the map. Add a loop to see if the number of incapped = define and end the message when that happens?

Share this post


Link to post
Share on other sites

@AZCoder... this script is awesome, a great SP revive option.. thanks.

I am applying this script to me [player] as well as the AI in my group, what i find is enemy AI do not stop firing at you when unconcious, so i added setcaptive true and false like this

if (!alive(_targ)) exitWith {};
		// if alive then run wounded animation for length of _recovery
		_targ setUnconscious true;
		_targ setCaptive true;
		_targ playMove "AinjPpneMstpSnonWrflDnon";
		[_targ] spawn
		{
			private ["_injured","_reco","_limit"];
			_injured = _this select 0;
			_unitRecovery = format["AZC_recover%1",_injured];
			_reco = missionNamespace getVariable _unitRecovery;
			_limit = time + _reco;
			// if unit gets healed during _recovery time, exit this loop
			while { damage _injured > 0.8 } do
			{
				// sleep won't work here, the intention is to allow a medic to heal the injuree
				if (time > _limit) exitWith { _injured setDamage 0.8; };
			};
			// set to normal "ready" animation
			_injured playMoveNow "AmovPercMstpSlowWrflDnon";
			_injured setCaptive false;
			if (damage _injured > 0.8) then { _injured setDamage 0.8; };

Which works ok, i havent tested it a lot, but when unconscious enemy ignores you, and then engage again when revived.. but i seem to lose all my actions like the ability to reload and addactions etc.

Is it possible to fast forward time [speed game up] while in an unconscious state, so that enemy AI move away from your position.. or thinking about it that may not work either if AI are set to defend/guard a position, What i had been doing before i saw this was using Norrins revive, and had the respawn marker follow the player at a certain distance (100/200 metres) and that works great but its not perfect..

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  

×