• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[Snippet] IsUnitCorpse

Kazeon

Hosted Project: EC
Level 34
Joined
Oct 12, 2011
Messages
3,449
JASS:
library IsUnitCorpse initializer onInit
    
    /*
        Simple library used to check whether a unit has become a corpse or not.
        
        How to use:
        - You must have a dummy caster at your OE
        - Copy this trigger into your map
        - Save your map, then re-open it
    */
        //! external ObjectMerger w3a Amel IRAA anam "CORPSE_CHECKER" abpy 0 auby 0 aart "" auar "" arac "other" ahky "" auhk "" aran 1 0 atar 1 "air,dead,ground,player" atp1 1 "" aub1 1 "" aut1 1 "" auu1 1 ""
    /*  
        - Delete or comment out that one line above and save again.
    */
    
    globals
        private constant integer DUMMY_ID     = 'h000'
        private constant integer SPELL_ID     = 'IRAA'
        private constant integer CONTAINER_ID = 'Sch2'
        private constant integer ORDER_ID     = 852053
        private constant player UNUSED_PLAYER = Player(15)
        private unit Dummy
    endglobals
    
    native UnitAlive takes unit id returns boolean
    
    function IsUnitCorpse takes unit u returns boolean
    
        local boolean b
        local player p
        
        if not UnitAlive(u) then
            set p = GetOwningPlayer(u)
            call SetUnitOwner(u, UNUSED_PLAYER, false)
            call SetUnitX(Dummy, GetUnitX(u) + 100)
            call SetUnitY(Dummy, GetUnitY(u) + 100)
            call IssueImmediateOrderById(Dummy, ORDER_ID)
            set b = GetUnitCurrentOrder(Dummy) == ORDER_ID
            call SetUnitPosition(Dummy, 1234567890, 1234567890)
            call SetUnitOwner(u, p, false)
        else
            return false
        endif
        
        return b
    endfunction
    
    private function onInit takes nothing returns nothing
        set Dummy = CreateUnit(UNUSED_PLAYER, DUMMY_ID, 1234567890, 1234567890, 0)
        call UnitAddAbility(Dummy, SPELL_ID)
        call UnitAddAbility(Dummy, CONTAINER_ID)
    endfunction
    
endlibrary
 
Last edited:

Kazeon

Hosted Project: EC
Level 34
Joined
Oct 12, 2011
Messages
3,449
Awesome usefulness. :thumbs_up:

Which line though? I get confused. :eek:

Aren't you CakeMaster? :eek:

This line:
JASS:
//! external ObjectMerger w3a Amel IRAA anam "REVIVE_CHECKER" abpy 0 auby 0 aart "" auar "" arac "other" ahky "" auhk "" aran 1 0.01 atar 1 "air,dead,ground" atp1 1 "" aub1 1 "" aut1 1 "" auu1 1 ""
Sorry for the confusion :)
 
I'm fine with this although such scripts are part of UnitEvent-related resources, no need to submit them one by one.

Whatmore, if you want to know the truth, you don't need any dummy units or abilities in order to detect the "decay" event. What you do need is, an unit indexer and a constant decay timer found in game constants (or calculate it manually at the begining of the game). You won't have access to private stuff of given UI, thus it's probably better to write an extension for given indexer.

The undefend event fires more often than just once in certain cases. Thats why one usually needs proper differenciation in order to properly fire INDEX/DEINDEX event. With help of "decay constant", you can check the difference between time of death, and time of decay. If it's within range of your constant, fire "decay event".
 
Dalvengyr >.>

But you need to catch that in order to tell if unit is decaying (IsUnitDecaying).
I believe different unit has a different death time
So what? Start the timer at the begining of the game and check the timer elapsed for given unit when it dies.
Later refer to that value when checking the difference between it and current game time.

Have you tried looking at UnitEvent and other related libraries?
 

Kazeon

Hosted Project: EC
Level 34
Joined
Oct 12, 2011
Messages
3,449
Dalvengyr >.>

But you need to catch that in order to tell if unit is decaying (IsUnitDecaying).
So what? Start the timer at the begining of the game and check the timer elapsed for given unit when it dies.
Later refer to that value when checking the difference between it and current game time.

Have you tried looking at UnitEvent and other related libraries?

I'm sorry if I'm hardly understand. But I think I don't need any event. The function check whether a unit is currently decaying at time X, is that unit has become a corpse or not yet at that time X.

Note: DoesUnitDecay != IsUnitDecaying

Edit:
Anyway, value of 100 seems quite risky, perhaps I will reduce it to 0.1 or something...
 

Kazeon

Hosted Project: EC
Level 34
Joined
Oct 12, 2011
Messages
3,449
If this resets decaying time (you still haven't answered me) then this can't be approved.

Dunno. I don't understand what was Nestharus talking about :/ How on earth this snippet resets decay time? It's probably true if the dummy successfuly picks the corpse then drop it again, but it does not...
 
Doesn't seem to work for me. Yes I have a dummy unit (from xe).

  • IUD Test
    • Events
      • Time - Every 1.00 seconds of game time
    • Conditions
    • Actions
      • Unit - Create 1 Footman for Player 1 (Red) at (Random point in (Playable map area)) facing Default building facing degrees
      • Unit - Kill (Last created unit)
      • Unit Group - Pick every unit in (Units in (Playable map area)) and do (Actions)
        • Loop - Actions
          • Custom script: if IsUnitDecaying(GetEnumUnit()) then
          • Game - Display to (All players) the text: ((Name of (Picked unit)) + is decaying.)
          • Custom script: endif

^ displays nothing.

The trigger below however, fires.

  • Untitled Trigger 001
    • Events
      • Unit - A unit Decays
    • Conditions
    • Actions
      • Game - Display to (All players) the text: true

Sorry if I missed something.
 

Kazeon

Hosted Project: EC
Level 34
Joined
Oct 12, 2011
Messages
3,449
I think I misnamed it, this library actually checks whether a unit has become a corpse or not. If you check immediately after kills, then it indeed results false, because it hasn't become a corpse yet.

So what you are saying is that you don't actually revive the unit? If so, then decay time won't be reset ; )
Nope.

Updated Now it safe even for checking two units with exact same location and exact time. But requires dummy unit with 0 acquistion range
 
Last edited:

Kazeon

Hosted Project: EC
Level 34
Joined
Oct 12, 2011
Messages
3,449
differences in behavior
This only returns true if the unit has actually become a corpse, that's the only difference.

performance and weigh the pros/cons
This seems slower. But can be useful for some abilities like Cannibalize where it can only consumes "real corpse" not dying unit.

I have an alternate approach that would probably work much better - Check the current animation of unit. If it's "decay bone" or "decay flesh" then it is a corpse.
It's easier and will probably work better.
Is there a way to check unit's current animation?
 
I wanted to point out smthing but I hadn't realise that this is not an "event" resource..

However, there is something hidden, and I'm pretty sure none of you realised that while examining this snippet.

Unit corpse != usable unit corpse
There are few rare situations where unit might not yield usable corpse, e.g consider a case when unit dies and has reincarnation ability - body won't decay. However, if the reincarnation ability is removed as soon as unit dies, the effect persists but now, unit yields a corpse, which is unfortunatelly unusable.
This, and few other combinations are usefull when you want to create "purified" corpses e.g prevent them from Scourge' magic ^)^

Result: this still might be usefull for determining "usable corpse" or differenciate usable one from non-usable. However, as pointed above - if you just want to say whether unit is a corpse or not, there isn't much required to test that out. I'm still waiting for you to rewrite this using the timer approach : )
 

Kazeon

Hosted Project: EC
Level 34
Joined
Oct 12, 2011
Messages
3,449
I still don't understand your different approace ^)^

If what you want is using unit decay event, utilize indexer, and use a boolean array global.. Well, that doesn't look like a snippet. ^)^
This is a trick, to shorten up the code and w/o requiring any burden dependecy. ^)^

And running that macro shit wont hurt anybody... ^)^ Also everybody got dummy caster in their maps, so what's the big deal? ^)^

@NesthaHolic
 

Kazeon

Hosted Project: EC
Level 34
Joined
Oct 12, 2011
Messages
3,449
Dalvengyr, because I thought you wanted to extend this with "event" functionality.

Answer
attachment.php
 

Attachments

  • no.jpg
    no.jpg
    226.4 KB · Views: 291
Very very minor improvement:

JASS:
    function IsUnitCorpse takes unit u returns boolean
    
        local boolean b = false
        local player p
        
        if not UnitAlive(u) then
            set p = GetOwningPlayer(u)
            call SetUnitOwner(u, UNUSED_PLAYER, false)
            call SetUnitX(Dummy, GetUnitX(u) + 100)
            call SetUnitY(Dummy, GetUnitY(u) + 100)
            call IssueImmediateOrderById(Dummy, ORDER_ID)
            set b = GetUnitCurrentOrder(Dummy) == ORDER_ID
            call SetUnitPosition(Dummy, 1234567890, 1234567890)
            call SetUnitOwner(u, p, false)
        endif
        
        return b
    endfunction
 
Top