Jump to content
ShadowRanger24

HandleDamage Event Handler Explained

Recommended Posts

@archibald tutter

gok_fnc_renderhstext = {
	_victim = _this select 0;
	_sel = _this select 1;
	_damage = _this select 2;
	_shooter = _this select 3;
 
	if ((_sel in ["head","face_hub"]) && (_damage >= 1) && (!alive _victim)) then {
		if ((isPlayer _shooter) && !(_shooter isEqualTo _victim)) then {
			[parseText "<t align = 'center' shadow = '1' size = '1' font='PuristaBold'><br/><br/><br/><br/>HEADSHOT<br/>", 
				[
					safeZoneX + safeZoneW - 1.40 - 0.025,
					safeZoneY + safeZoneH - 0.45 - 0.05,
					0.45,
					0.35
				], 
			[10, 5], 2, 1.1, 0.2] remoteExec ["BIS_fnc_textTiles",_shooter];
			
			playSound "headshot01";
		};
	};
};

That should work for sending the text to the shooter with remoteExec.

  • Like 1

Share this post


Link to post
Share on other sites

@ShadowRanger24 Thanks, a Lot!

I was reading all kinds of stuff last night, thinking about how to do it. At one point I was trying to set up a quick "publicVariableEventhandler" so client can knock the server, then server show-draw this small dynamic text on that individuals screen etc.. :]

Now it works flawless. I had to change the position information format to "absolute" in GUI editor, that was it now it spawns where it should; at the center of screen:

 

[parseText "<t align = 'center' shadow = '1' size = '1' font='PuristaBold'><br/><br/><br/><br/>HEADSHOT<br/>", 
	[0.276999,0.9392,0.45,0.35], 
 	[10, 5], 2, 1.1, 0.2] remoteExec ["BIS_fnc_textTiles",_shooter];

thanks again.

 

EDIT: a small update

For general, on this handleDamage EH;

(Since Arma 3 v 1.67)

  • hitPoint: String - hit point Cfg name

https://community.bistudio.com/wiki/getAllHitPointsDamage

Hitpoint can be used instaed of selections,

	_parthit = _this select 7;
	if ((_parthit in ["HitHead", "HitFace"]) && (_damage >= 1) && (!alive _victim)) then { ....
  • Like 1

Share this post


Link to post
Share on other sites

I read the thread, but not sure it answers a need I have.  I want to test a condition that if true, no new damage occurs, but if false, the normal damage occurs at whatever hitparts, etc.

 

How would I do that?

Share this post


Link to post
Share on other sites
30 minutes ago, johnnyboy said:

I read the thread, but not sure it answers a need I have.  I want to test a condition that if true, no new damage occurs, but if false, the normal damage occurs at whatever hitparts, etc.

 

How would I do that?

 

<entity> addEventHandler [
	'HandleDamage',
	{
		params ['_entity','','_damage','_source','','_hitPartIndex','_instigator',''];
		(if (true) then {0} else {_damage})
	}
];

 

  • Like 3

Share this post


Link to post
Share on other sites
On 22/01/2018 at 5:13 PM, fn_Quiksilver said:

 


<entity> addEventHandler [
	'HandleDamage',
	{
		params ['_entity','','_damage','_source','','_hitPartIndex','_instigator',''];
		(if (true) then {0} else {_damage})
	}
];

 

This would work, however if you would want to prevent any previous damage from being removed you'd need to tweak it a little more like this:

_unit addEventHandler ["HandleDamage", {
	private _unit = _this select 0;
	private _hitSelection = _this select 1;
	private _damage = _this select 2;
	
	if (true) then {
		if (_hitSelection isEqualTo "") then {
			damage _unit
		} else {
			_unit getHit _hitSelection
		};
	} else {
		_damage
	};
}];

 

  • Confused 1

Share this post


Link to post
Share on other sites

if (true) then {..}  else {...}  //  write your code straight and forget else.

Share this post


Link to post
Share on other sites

Let's say that a vehicle has the following HandleDamage handler:

_object addeventhandler ["HandleDamage",
   {
      params ["_object", "_selection", "_damage", "_source", "_projectile", "_partIndex", "_instigator", "_part"];

      if (_part != "") then { _damage = 0 };

      _damage;
   }];

When such a vehicle is damaged (I use explosive charges through Zeus), getAllHitPointsDamage will always return zeros for all parts of the vehicle.  In contrast, damage will rise until the vehicle is destroyed.  So the vehicle is destroyed despite saying that no part of the vehicle should be damaged - and no part of the vehicle IS damaged, according to getAllHitPointsDamage.

 

Note that the handler above is only illustrating the problem with damage filtering.  I'm not trying to come up with a way to prevent all damage to a vehicle.

 

To solve this requires figuring out what the correct global damage value should be so it can be passed back from the event handler whenever it sees the global selection (""/-1).

 

I tried a few different ways of calculating the global damage from getAllHitPointsDamage, but I can't match the damage value that ARMA reports.  It's not the average of all part damages (the technique used by A3).  It's also not the sum of part damages multiplied by their CfgVehicles >> vehicle >> HitPoints >> passthrough values.

 

Does anyone know how to compute that global damage value accurately?  Can it be done with scripts?

Share this post


Link to post
Share on other sites

The wiki states that, as of 2 July 2017, this is an unsolved problem.

https://community.bistudio.com/wiki/Arma_3_Damage_Description#Standard_Hit_Damage

Quote

How exactly global damage is applied specifically is still a mystery. In theory, a hitpoint location receives damage. This damage is applied to global damage as well, but reduced via passthrough value on the hitlocation and the global armorStructural value. However, test results indicate that this is not true in every case, not matching any formula that has been floating around on various other damage related pages.

 

Share this post


Link to post
Share on other sites

So is there a reason that this doesn't stop aircraft from exploding when they collide with the ground?

_unit addEventHandler ["HandleDamage", {0}];

Is this a bug or an intended feature? From this and past discussions I've seen on the subject of aircraft explosions I'm getting the impression BI really don't want us to be able to survive crashes. Which is really silly in PvE milsim as far as I'm concerned.

Currently I'm trying to make this work:

this addEventHandler ["handleDamage", {
	_unit = _this select 0;
	_damage = _this select 2;
	_source = _this select 3;
	if (_source == _unit && (damage _unit + _damage) > 0.99) then {
		_unit setDamage 0.99;
	} else {
		_unit setDamage (damage _unit) + _damage;
	};
	0;
}];

 The above could be used by so many milsim units to add realism. Unfortunately the "0;" at the end of the EH's code doesn't work for aircraft. I guess this explains why I haven't already found a script or mod to disable aircraft exploding upon impacting the ground. Anyone know if there's a solution or if it's a bug that needs to be reported?

Share this post


Link to post
Share on other sites

If you want no damage at all, which appears to be what you want. Why not just simply use allowDamage command?

https://community.bistudio.com/wiki/allowDamage

I think the reason is that the HandleDamage EH triggers way too fast and multiple times.

There is also disableCollisonWith but requires two objects. Don't think you can pass EVERYTHING so this isn't any help in this case.

https://community.bistudio.com/wiki/disableCollisionWith

Share this post


Link to post
Share on other sites

@HazJ Trying to make it so missiles, AA guns, etc can blow up aircraft but hitting the ground makes them badly damaged so that occupants can survive the impact. "if (_source == _unit &&" detects ground impact in the EH I wrote above and then limits damage to 0.99 so it doesn't explode. There was a thread on these forums a while back where people were begging BI to stop aircraft from exploding on the slightest impact with the ground and I recall the devs being pretty stern on the fact they weren't going to do it. I'd expect it to be possible to fix that with a mod or script but I slightly suspect the EH I wrote not working may be intentional to prevent that.

  • Like 1

Share this post


Link to post
Share on other sites

Yeah if it worked hehe. So, in short, you just want to disable damage on collision? If you just wanted no damage at all and only AA missile / weapons damage then you could of used Hit EH too to set damage accordingly. Seems a lot of hassle though, could just not crash into things haha! :rofl::rofl:

Share this post


Link to post
Share on other sites

Is there any way to handle submunition damage?
Ammo with submunition triggers event multiple times. How to handle them as one event with sum of damage dealt by submunition projectiles.

For example, RHS use this submunition theme in tank shells

Share this post


Link to post
Share on other sites

@HazJ I'm not trying to disable damage upon ground impact, I'm trying to limit it. In Arma if you so much as clip your skids on the ground at 50KM/h, "BOOM!" everyone's dead. I'm trying to override the default behaviour so that everyone gets injured by the impact and the aircraft is destroyed, but it doesn't burst into a ball of flames and kill everyone.

 

So does anyone know why that EH isn't working? Should I make a bug report?

  • Like 1

Share this post


Link to post
Share on other sites

As a matter of fact,  this addEventHandler ["HandleDamage", {0}];

works on a land vehicle, doesn't work on helicopter in flight.

 

Tested in Vanilla, OPFOR shooting at a strider or a MH9 (in flight). MH9 seems to be invulnerable on ground.

  • Like 3

Share this post


Link to post
Share on other sites

Hello, just a question. Can this script be changed differently to affect only AI units, so I can for instance have different damage for players (in MP) and different for AI units?

Share this post


Link to post
Share on other sites
3 hours ago, Jaden Vance said:

Hello, just a question. Can this script be changed differently to affect only AI units, so I can for instance have different damage for players (in MP) and different for AI units?

Yes. Add a condition if (!isPlayer) then {...};

  • Like 1

Share this post


Link to post
Share on other sites

You mean to change this line here from your script:

if ( isPlayer _unit ) then {
    _unit removeAllEventHandlers 'HandleDamage';

 

to this:

 

if ( !isPlayer _unit ) then {
    _unit removeAllEventHandlers 'HandleDamage';

 

Or I get this wrong?

 

Edit: Probably wrong because nothing happens when I try that.

Edited by Jaden Vance
Fill some info.

Share this post


Link to post
Share on other sites

ABOUT STACKING this EH:

 

The safe stacking of several EHs is possible if there is nothing more returned by next EH(s) after the one which returns the wanted value.

For example, one of your mods handle damages in order to make the unit incapacitated but not dead (some code and something returning 0.86 as damage at the end of EH).

If you want to add some EHs handling damage after this important EH, you need to be sure that these further EHs return nothing at all, e.g.

this addEventHandler ["handleDamage", {
  params ["_unit"];
  _null = _unit spawn {some code};
}];

Here _null (or any script handle)  is important. If you omit to balance this equality, the spawn will return the (missing) script handle (usually 0) and the _unit will become invincible!

Same if you EH code returns at end:

- true (the unit damage is no more handled);

- or false (the unit is invincible).

Share this post


Link to post
Share on other sites

Here's a way to reduce damage proportionally to what it normally should be, for example to reduce all inflicted damage by 30%
Note that this is very different to returning just _damage * 0.7 which leads to undesired behaviour. What you actually want to return is the previous damage + reduced new damage.

this addEventHandler [
	"HandleDamage", 
	{ 
		params ["_unit", "_selection", "_damage", "_source", "_projectile", "_hitIndex", "_instigator", "_hitPoint"];

		private _previousDamage = [_unit getHit _selection, damage _unit] select (_selection isEqualTo "");  // if selection is empty then it's overall damage
		private _newDamage = _damage - _previousDamage;

		(_previousDamage + _newDamage * 0.7)
	}
];

 

Another caveat: a one shot kill often deals much more than 1.0 damage, meaning that a headshot which deals 5.0 damage is still deadly after a reduction by 30%.

You can mitigate it by limiting the maximum damage that can be dealt in one hit. The example below will: reduce all damage by 30% and prevent taking more than 80% damage from a single hit.

(_previousDamage + ((_newDamage * 0.7) min 0.8))

 

If you're using ACE, be aware that this will not work correctly on men because of the modded medical system though it'll still work fine for vehicles.

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites
20 hours ago, _foley said:

Another caveat: a one shot kill often deals much more than 1.0 damage, meaning that a headshot which deals 5.0 damage is still deadly after a reduction by 30%.

You can mitigate it by limiting the maximum damage that can be dealt in one hit. The example below will: reduce all damage by 30% and prevent taking more than 80% damage from a single hit.


(_previousDamage + ((_newDamage * 0.7) min 0.8))

 

you could also use this to cap those deadly damage to 1 (or whatever u like) and reduce by 30% afterwards:

 

( _previousDamage + ( _newDamage min 1 ) * 0.7 )

 

  • Like 2

Share this post


Link to post
Share on other sites
6 hours ago, sarogahtyp said:

 

you could also use this to cap those deadly damage to 1 (or whatever u like) and reduce by 30% afterwards:

 


( _previousDamage + ( _newDamage min 1 ) * 0.7 )

 

Since you're reducing it anyway there's no real difference between that and (_previousDamage + ((_newDamage * 0.7) min 0.7)), but in the latter case it's more clear at a glance (IMHO) what the final damage cap is.  I suppose it's just a stylistic choice more than anything.

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

×