HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

avoiding infinte loops in damage detection

11-11-2009, 09:12 AM#1
Sinnergy
Hi

I have this trigger that acts like a damage amplifier, each time a unit with a specific buff takes damage, it deals damage equal to 35% of the received damage, the problem is, it causes an infinite loop because my trigger only checks if the damaged unit has this buff, and the buff itself deals damage to the affected unit (unholy frenzy based ability), not only unholy frenzy will cause infinite loop, but also any other damage, I need to find a way to prevent infinite loop in my trigger

I'm using Light Leakless Damage Detection
Collapse JASS:
scope HowlDamn initializer init
    globals
        private constant integer spell  = 'A00J'
        private constant integer dspell = 'A00K'
        private constant integer buffer = 'B007'
        private constant integer dbuffer= 'A00L'
        private boolean array add
    endglobals
    
    private function con2 takes nothing returns boolean
        return GetSpellAbilityId() == spell
    endfunction
    
    private function act takes nothing returns nothing
        local unit c = GetTriggerUnit()
        local real x = GetUnitX(c)
        local real y = GetUnitY(c)
        local xecast xe = xecast.createA()
        set xe.abilityid = dspell
        set xe.orderstring = "unholyfrenzy"
        set xe.owningplayer = GetOwningPlayer(c)
        set xe.recycledelay = 2.0
        if GetUnitAbilityLevel(c,superBeing) > 0 then
            set xe.level = 2
        else
            set xe.level = 1
        endif
        call xe.castOnAOE(x,y,600.0)
        set c = null
    endfunction
    
    private function con takes nothing returns boolean
        local unit c = GetTriggerUnit()
        local unit t = GetEventDamageSource()
        local real f = GetEventDamage()
        if GetUnitAbilityLevel(c,buffer) > 0 then
            call UnitDamageTarget(t,c,f*0.35,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,null)
        endif
        set c = null
        set t = null
        return false
    endfunction
    
    private function init takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(t, Condition(function con2))
        call TriggerAddAction(t,function act)
        //call RegisterSpellEffectResponse(spell,act)
        call XE_PreloadAbility(dspell)
        call AddOnDamageFunc(Condition(function con))
    endfunction
endscope
11-11-2009, 09:15 AM#2
Anachron
There is only one way you can do that and god will doom you for the rest of your life, but however...

You have to disable the trigger once an action happens and after all actions you have to enable it.
11-11-2009, 09:47 AM#3
Sinnergy
wow thanks for that, now I know why people disables and enables the trigger when dealing damage
11-11-2009, 09:51 AM#4
Anachron
Yes, its because disabling triggers will make the trigger unable to be runned again in the current execution. Enabling it again after the execution will allow the trigger to be casted again.

So in short, you prevent such loops by disabling the event to fire, which is no problem in all for MUI because everything in wc3 is runned in one straight way, so there is no things that are actually done at the same time.
11-11-2009, 11:31 AM#5
Anitarf
Quote:
Originally Posted by Anachron
There is only one way you can do that...
No.

If you use a system like xedamage, you can assign a tag to the damage you deal and then retrieve that tag in the damage detection trigger, this way you can make your spell only respond to non-triggered damage and the infinite loop is averted without the need to turn the trigger on/off, which also means other spells can detect this bonus damage.

Alternatively, you could use DamageModifiers to boost the damage.
11-11-2009, 11:41 AM#6
Anachron
Oh, Anitarf, I was just talking about his implementation.
Sure there are other ways, but taking him as the subject, its the thing he got to do.

I even used xedamage and DamageModifiers, and they are good.
11-11-2009, 03:34 PM#7
Rising_Dusk
Most damage detection systems implement some sort of ignored type of damage as well.