• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece!🔗 Click here to enter!

Best way to detect if a unit is dead or not.

Status
Not open for further replies.
Level 12
Joined
May 22, 2015
Messages
1,051
What is the best way to detect if a unit is dead? I've had a couple problems with my current detection (checking if life is greater than 0). The only real issue is with my custom experience system which is giving experience to dead heroes. I have a couple solutions that will probably work around the problem just fine (move dead heroes to an unused corner of the map or use a boolean that is set when the hero actually dies and revives and use that for the check), but I'd like the most accurate way to detect if a unit is dead.
 
Level 12
Joined
May 22, 2015
Messages
1,051
IsUnitType(u, UNIT_TYPE_DEAD). There is GUI comparision under boolean comparision.

This should be much more reliable than GetWidgetLife(u) < 0.405, because spells like tranquility heal dead units too

Thanks! I'll test it out next time I get the chance. +rep
 
Usually it is this:
JASS:
function IsUnitDead takes unit u returns boolean
    return IsUnitType(u, UNIT_TYPE_DEAD) or GetUnitTypeId(u) == 0
endfunction

Some people might write this instead:
JASS:
function UnitAlive takes unit u returns boolean 
    return not IsUnitType(u, UNIT_TYPE_DEAD) and GetUnitTypeId(u) != 0
endfunction

I think the GetUnitTypeId() is to check if the unit is removed/null input. Technically, if a unit is removed, it isn't "dead", but in most cases we just want to know if the unit is no longer active (i.e. dead or removed).

You can also just declare the common.ai native:
JASS:
native UnitAlive takes unit u returns boolean
But I haven't personally checked the results of this native that thoroughly.
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
Why not use the boolean comparison Unit is Dead equal to True/False?

Because that not always tells you if that unit is dead.
The check compares the unit's health to 0:
return GetUnitState(whichUnit, UNIT_STATE_LIFE) <= 0
Which means that your unit is dead when his life is below or equal to 0.
However a unit dies when he is falling below the minimum HP threshold, which is 0.415 iirc.

So a unit with 0.3 life is dead and showed his death animation and cannot be controlled any more... however it is NOT dead according to this method.

Another problem is that you are able to raise the HP of any unit including dead units.
This means that when your unit had 0 HP and you increase that hp (no matter if it was intentional, you just did it), that means that this unit is not dead any more... but you still cant control it.

That is why we use this method:
return IsUnitType(u, UNIT_TYPE_DEAD) or GetUnitTypeId(u) == 0
When a unit dies (hp falls below 0.415) his UNIT_TYPE_DEAD is set to true, which causes you to lose control and make it play the death animation.
So when a unit has IsUnitType(u, UNIT_TYPE_DEAD) set to true, that means he is dead.
However there is one problem that when you call that function on a unit that is removed from the game it always returns false.
The problem is that you dont want your effect to happen on non-existing units so you do another check in which case you check if the unit type of the unit is 0.
If it is 0 that means that your unit is removed so you cannot apply effects on it.

However this means that not all checks can be done like this.
Instead, when you want an effect to happen on dead units (example resurrection), you need this check:
return IsUnitType(u, UNIT_TYPE_DEAD) and GetUnitTypeId(u) != 0
But if you want to have an effect to happen on alive units (filtering dead units), you need this check:
return not (IsUnitType(u, UNIT_TYPE_DEAD) or GetUnitTypeId(u) == 0)

I havent really tested out the IsUnitAlive() native but it might work as well.
 
Last edited:
Level 23
Joined
Apr 16, 2012
Messages
4,041
IsUnitAlive is actually the best one by order of magnitude, then IsUnitType or TypeId. The other methods arent really reliable. And yes, after discussion with Wietlol, I came to conclusion there is indeed no way to poll IsUnitType(u, UNIT_TYPE_DEAD) in GUI excluding custom scripts, shame
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
Order of magnitude?
You mean like in how much code there is?
IsUnitDeadBJ() is short enough but that doesnt make it good.
IsUnitAlive() is short enough but that doesnt make it good.
I want to know what is inside that method, what it does and how it does it.
And until I know that, I wont use it and go for the IsUnitType() and GetUnitTypeId() instead and suggest everyone to do the same (wether they do it or use IsUnitAlive() is their choice).
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
order of magnitude faster.

Also IsUnitAlive is shorter, but the more important thing is, it is one native call.
IsUnitDeadBJ calls IsUnitAliveBJ and that checks GetUnitState(u, UNIT_STATE_LIFE) <= 0. which means you have 3 function calls, and in Jass, function calls are very expensive.

IsUnitAlive probably directly returns some kind of boolean value stored for every unit that marks whether its dead or not, so it is blazing fast
 
There is no "IsUnitAlive" native.

The native is called UnitAlive and first needs to be defined to be recognized by Jasshelper.

Hence why it's mostly easier to just use this:
JASS:
function UnitAlive takes unit u returns boolean 
     return not IsUnitType(u, UNIT_TYPE_DEAD) and GetUnitTypeId(u) != 0
endfunction
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
one way or another, you have to define it, and when you are writing function UnitAlive, you could've just as easily say native UnitAlive.

By not using JNGP, you are only limiting yourself, so thats not really argument.

Yes I misspelled it
 
Status
Not open for further replies.
Top