Bug #22250

HandleDamage ignores return value from exitWith

Added by kju almost 4 years ago. Updated over 3 years ago.

Status:Assigned Start date:07/12/2011
Priority:Normal Due date:10/12/2011
Assignee:Dwarden % Done:

0%

Category:Event Handlers
Target version:-
Affected ArmA II version:1.60 BETA First affected build:
Reproduced by another DH user:Yes First affected ArmA II version:
I am using some Mods:No Single / Multi Player?:
I am using: BIForumURL:
Reproducible for you:Yes NGUrl:
Related to content of DLC: WIKIurl:

Description

Sample code

player addEventHandler ["HandleDamage",
{
    if (true) exitWith {_this select 2};

    10
}];

Obs
This makes the player invulnerable as the return value is not applied.
Therefore it sets 0 damage for the current selection it seems.

Repro
  1. Run attached mission in the editor
  2. Damage yourself (hand grenade, satchel, rocket jump)
  3. Note you won't die
  4. Disable the code line and notice it works again as expected

HandleDamageExitWith.desert_e.7z (716 Bytes) kju, 07/12/2011 14:23


Related issues

related to ARMA2 Community Issue Tracker - Bug #13644: Aircrafts ignore handleDamage EH and allowDamage command... Assigned 09/11/2010
related to ARMA2 Community Issue Tracker - Bug #10118: handleDamage does not prevent 'suppressive affect' that a... Assigned 04/15/2010 03/01/2011
related to ARMA2 Community Issue Tracker - Bug #16413: Dammaged/HandleDamage EHs stop working on buildings after... Assigned 01/03/2011 04/03/2011
related to ARMA2 Community Issue Tracker - Bug #18027: handleDamage EH assigned to vehicles triggers multiple ti... Assigned 03/03/2011 06/01/2011
related to ARMA2 Community Issue Tracker - Feature #20946: Import get/setHitPointDamage commands from TKOH Assigned 06/27/2011
related to ARMA2 Community Issue Tracker - Bug #22226: HandleDamage triggers twice on self damage Rejected 07/11/2011

History

Updated by Suma almost 4 years ago

  • Status changed from New to Feedback

I do not thing exitWith should be used here, use proper if / else construct instead:

http://community.bistudio.com/wiki/exitWith

When you use exitWith not inside a loops, the behaviour is undefined - sometimes it may exit the script, sometimes some other scope, but this is not intended and designed behaviour of this command, and it is not guaranteed to work reliably.

Updated by Sickboy almost 4 years ago

I was already expecting that answer :)

Would it be possible to improve the command to work reliable?
exitWith should exit the current scope, saving having to assign scope names in many situations.

IIRC, this for instance doesn't even exit the loop:

while { true } do {
  diag_log "test";
  if (true) then { diag_log "test2"; if (true) exitWith {}; };
  sleep 1;
};

So it already seems to exit the current scope (instead of loop), but just not reliably.

It should be able to function as a replacement of:

if (true) then {
   scopeName "Test";
   breakOut "Test";

   diag_log "Test";
};

Use cases:

_function = {
  #define DEFAULT 5
  _a = _this select 0; _b = _this select 1;

  if (_a && _b) exitWith { 1 };
  if (_a || _b) exitWith { 3 };
  if (_a && !_b) exitWith { 2 };
  DEFAULT;
};

_val = [true, false] call _function;

In this case it's much used as "return" in other languages.

Updated by kju almost 4 years ago

Sickboy remembered me of your statement in the BIKI Suma.
To me it'd be OK to keep it this way.
The other issue that made me find that one is far more of a problem (see related).

That said as Sickboy rightfully notes, many use exitWith in this way
and it seems like straight forward one to understand use to coders.

Updated by Fireball almost 4 years ago

  • Status changed from Feedback to Rejected

Updated by Fireball almost 4 years ago

  • Status changed from Rejected to Feedback

Misunderstanding.

Updated by Buehgler_AS almost 4 years ago

if (...) exitWith {...} is probably one of the most misused bit of SQF out there (on par with nil = ...). People just want it to be a replacement for return from their favorite procedural language (e.g. C or Java). I have always presumed that the SQF runtime did not construct scopes for all function calls, and that this was why return and break are absent in the language.

That said, I think the functionality provided by scopeName, breakOut/To, and exitWith is sufficient. People really just need a better set of examples and documentation to properly use them.

As for Sickboy's multi-input switch example, I would suggest the following:

_function = {
  #define DEFAULT 5
  _a = _this select 0; _b = _this select 1;

  if (_a && _b) then { 1 }
  else if (_a || _b) then { 3 }
  else if (_a && !_b) then { 2 }
  else DEFAULT
};

_val = [true, false] call _function;

I do not find that any more difficult to read/write than the asked for exitWith style.

Updated by Xeno almost 4 years ago

No thanks, no if then else if then else if then else. That's not only ugly but also bad programming (even if you could replace it with switch).
exitWith should end scopes and return the last value in its own scope, like it does 99% in all other cases. It should be finally made consistent.

Updated by Fireball almost 4 years ago

So, should this be transformed into a Feature ticket something along the line of "exitWith should exit all scopes consistently"?

Updated by kju almost 4 years ago

No this one is about handleDamage

Updated by Fireball almost 4 years ago

kju wrote:

No this one is about handleDamage

I wonder then why everyone else is only talking about exitWith.

Obviously the problem you mentioned concerns mainly exitWith and its inconsistencies (or behavior) with exiting scopes, not only with handleDamage, but any function or EH.

Updated by kju almost 4 years ago

Simple as this issue here is with handleDamage.

Or can you give me another example with exitWith Fireball?

Updated by Fireball almost 4 years ago

Not me, but Sickboy's comment refers to loops, which are not exited properly, with nestled ifs.

Updated by Sickboy almost 4 years ago

Fireball wrote:

Not me, but Sickboy's comment refers to loops, which are not exited properly, with nestled ifs.

That's because Suma was pointing to what he wrote on the Biki; the purpose and warning of inconsistencies with exitWith in unsupported situations :)

Updated by Fireball almost 4 years ago

Exactly my point - so there are other inconsistencies with exitWith, not only HandleDamage.

Updated by kju almost 4 years ago

As said it has worked for me reliable so far in all situations.
This is the first not to work.

Updated by Fireball almost 4 years ago

I see, so after discussing this with kju in chat, the main issue is, that it everywhere seems to properly exit the scope, except for handleDamage. So the point with the loops got me misguided.

Updated by kju almost 4 years ago

The BIKI description seems to cause confusion.
I am not sure it is fully correct - at least in my experience.

exitWith is reliable in exiting the current scope (also in loops).

For loops one has to be aware of "sub-scopes".
To exit a loop you need to use exitWith in the loop scope itself.

handleDamage is the first exception for me.

Updated by Xeno almost 4 years ago

kju wrote:

handleDamage is the first exception for me.

Right, same here.

Updated by Fireball almost 4 years ago

  • Status changed from Feedback to Assigned

I think enough feedback has been provided. Question is, will this special case be fixed anyway?

Updated by alef almost 4 years ago

Suma wrote:

I do not think exitWith should be used here, use proper if / else construct instead:

BI used it outside if / else constructs in the MPF module.
Would it worth to adapt the design to the current usage?

Also available in: Atom PDF