HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Buffs on dying unit

10-19-2005, 08:33 PM#1
LegolasArcher
I've run into a problem with a trigger enhanced aura that has a percentage chance to activate when a unit dies under its effects. For other custom auras, I would just run a check to determine if the unit has the buff related to it:
Collapse JASS:
constant function SomeSpellBuff takes nothing returns integer
    return 'B000' // Some buff rawcode
endfunction

function MyTriggerConditions takes nothing returns boolean
    return UnitHasBuffBJ(GetDyingUnit(), SomeSpellBuff())
endfunction
In this case, however, I cannot determine whether the unit has the buff or not. Apparently the "unit dies" action triggers after the engine has killed the unit (Removed buffs, created corpse, etc). After taking a quick gander throughout the other unit events, I don't see any way of doing this efficiently .

If worse comes to worse, I'll keep track of which units have the buff applied (Probally with Vex's aura template ), and add a icon-less ability (aka Sphere) to the unit when it has the buff (Since, oddly, you can still detect the level of abilities on dead units).

Just in case anyone's curious, it's an aura that a custom hero has which relies mainly on summoning zombies to assist him. Each rank gives a chance for a zombie to spawn when an enemy is killed close to the lich.
10-19-2005, 08:40 PM#2
Anitarf
I've read that "unit takes damage" event fires before actual damage is applied, so the unit should in that case still be alive on this event and still have the buff. If the damage is greater than the unit's current life, then you know for sure the unit will die.

Well, that's the general theory, at least...
10-20-2005, 12:01 AM#3
Vexorian
When a unit is dead all buffs are gone.

I would say the specific unit life event, whenever the unit's life goes less than or equal to 0.405 check if the buff is present and do stuff
10-20-2005, 12:22 AM#4
LegolasArcher
@Anitarf I had that thought earlier, but there is no generic global unit event. Since there are a good deal of units on the map at the same time, specific unit events would be extremely tiresome to incorporate.

@Lord Vexorian Same thing as above, it would be unfesable with the number of units located on the map .

I have a feeling I'm going to need to add the temporary ability when the unit has the buff, then check for that when it dies. Vex, do you have a link to your aura template? I remember seeing it somewhere on your forums before, but I can't seem to locate it anymore .
10-20-2005, 01:19 AM#5
Vexorian
Well actually you can just pick the units and add the event, If you are worried about memory you can create an individual trigger for each unit, then destroy the trigger when it is no longer needed

http://vexorian.wc3campaigns.com/spells/auratemplate.w3x
10-20-2005, 07:09 PM#6
LegolasArcher
Quote:
Originally Posted by Lord Vexorian
Well actually you can just pick the units and add the event, If you are worried about memory you can create an individual trigger for each unit, then destroy the trigger when it is no longer needed

http://vexorian.wc3campaigns.com/spells/auratemplate.w3x

Thanks for the link, Vex, I've been trying to locate that for a while. I like your idea for the creation triggers for each unit when they are spawned/created, but I don't have much experiance with the dynamic creation of triggers at runtime. Would something like this suffice?

Collapse JASS:
function UnitDeathCond takes nothing returns boolean
    if (GetEventDamage() >= GetUnitState(GetTriggerUnit(), UNIT_STATE_LIFE)) then
        return true
    endif
    return false
endfunction

function UnitDeath takes nothing returns nothing
    if (UnitHasBuffBJ(GetTriggerUnit(), MySpellBuffId()) == false) then
        call DestroyTrigger(GetTriggeringTrigger())
        return
    endif
    
    // Do spell stuff.
    
    call DestroyTrigger(GetTriggeringTrigger())
endfunction

function SomeFunc takes nothing returns nothing
    local trigger death
    
    set death = CreateTrigger()
    call TriggerRegisterUnitEvent(death, GetEnteringUnit(), EVENT_UNIT_DAMAGED )
    call TriggerAddCondition(death, function UnitDeathCond)
    call TriggerAddAction(death, function UnitDeath)
endif

[edit] The "MySpellBuffId" would just be a constant function that returns the rawcode for the buff.

Thanks for the quick replies to everyone that responded .
10-20-2005, 10:12 PM#7
Vexorian
Well it will work just TriggerAddCondition requires it to use Condition(func) . And that endif should be endfunction

otherwise it will be ok.

although TriggerActions leak so you'll have to take some problems just to remove them. It would need attachable variables or handle variables

Conditions also leak but that's fixed by not using conditions at all.

Collapse JASS:
function UnitDeathCond takes nothing returns boolean
    if  then
        return true
    endif
    return false
endfunction

function UnitDeath takes nothing returns nothing
 local trigger t=GetTriggeringTrigger()
 local unit u=GetTriggerUnit()
    if (GetEventDamage() >= GetUnitState(u, UNIT_STATE_LIFE)) then

        if (UnitHasBuffBJ(u, MySpellBuffId()) then

            //Do spell stuff
        endif
    
        // Do spell stuff.
        call TriggerRemoveAction(t,GetAttachedTriggerAction(t,"ac"))
        call CleanAttachedVars(t)
        call DestroyTrigger(t)
    endif
 set t=null
 set u=null
endfunction

function SomeFunc takes nothing returns nothing
    local trigger death
    
    set death = CreateTrigger()
    call TriggerRegisterUnitEvent(death, GetEnteringUnit(), EVENT_UNIT_DAMAGED )
    call TriggerAddCondition(death, Condition(function UnitDeathCond))
    call AttachObject(death,"ac",TriggerAddAction(death, function UnitDeath))
 set death=null
endfunction

Attachable vars are in the CSCache Module
10-20-2005, 11:47 PM#8
LegolasArcher
Quote:
Originally Posted by Lord Vexorian
Well it will work just TriggerAddCondition requires it to use Condition(func) . And that endif should be endfunction

otherwise it will be ok.

although TriggerActions leak so you'll have to take some problems just to remove them. It would need attachable variables or handle variables

Conditions also leak but that's fixed by not using conditions at all.

Collapse JASS:
function UnitDeathCond takes nothing returns boolean
    if  then
        return true
    endif
    return false
endfunction

function UnitDeath takes nothing returns nothing
 local trigger t=GetTriggeringTrigger()
 local unit u=GetTriggerUnit()
    if (GetEventDamage() >= GetUnitState(u, UNIT_STATE_LIFE)) then

        if (UnitHasBuffBJ(u, MySpellBuffId()) then

            //Do spell stuff
        endif
    
        // Do spell stuff.
        call TriggerRemoveAction(t,GetAttachedTriggerAction(t,"ac"))
        call CleanAttachedVars(t)
        call DestroyTrigger(t)
    endif
 set t=null
 set u=null
endfunction

function SomeFunc takes nothing returns nothing
    local trigger death
    
    set death = CreateTrigger()
    call TriggerRegisterUnitEvent(death, GetEnteringUnit(), EVENT_UNIT_DAMAGED )
    call TriggerAddCondition(death, Condition(function UnitDeathCond))
    call AttachObject(death,"ac",TriggerAddAction(death, function UnitDeath))
 set death=null
endfunction

Attachable vars are in the CSCache Module

Ah, thanks again Vex. I just typed up that code quickly when I didn't have access to the WorldEdit to see if I was getting the correct idea of what you said. Should be close to working, then I can clean up the leaks a bit.

I find it interesting that conditions and actions both leak. Thanks for saving me what would have been a nearly-impossible leak to find .