• 🏆 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!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

What the heck does Invulnerable (neutral) do?

Status
Not open for further replies.
Level 24
Joined
Aug 1, 2013
Messages
4,657
I am testing my reworked Effect Over Time System and I made an example that would be the same (but modifyable) as divine shield.
To make the unit invulnerable, I add the ability Invulnerable (Neutral).
The problem is that other abilities are not added any more for some weird reason.
When the divine shield expires, I can use my other spells again without a problem.

So what the heck does Invulnerable (Neutral) do that I cannot add spells to a unit any more and how can I set the unit invulnerable on another way.

(I do not want to use "SetUnitInvulnerable()" because that would be stupid if I use it for 2 different spells.)
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
That is actually what I wanted to replace...
Next to that, if I would add Divine Shield to the unit and force it to cast it and then remove it again, the effect is also gone.

The thing is that I am creating a system where you can add buffs or effects over time on a unit.
So with one click, I could make the divine shield to be able to be cast on allied units... or enemies if I would want that :)

I add abilities to a unit via triggers everytime a unit gains an effect and on each interval. But now they are blocked.
 

Zwiebelchen

Hosted Project GR
Level 35
Joined
Sep 17, 2009
Messages
7,236
Obviously, spells can't be used on invulnerable targets, so you can't apply effects after applying the invulnerability.

You can, however, remove invulnerability every time you apply an effect.
You can also change the target type of the dummy abilities used to apply the effects to target invulnerable units aswell.
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
Obviously, spells can't be used on invulnerable targets, so you can't apply effects after applying the invulnerability.

You can, however, remove invulnerability every time you apply an effect.
You can also change the target type of the dummy abilities used to apply the effects to target invulnerable units aswell.

Well I do UnitAddAbility().
When the unit is invulnerable, he doesn't gain the ability.
It is not like it is a spell, also positive effects are blocked.

Removing the invulnerability and adding it again could work... except that I make new abilities based of Invulnerable neutral to do it.
I would have to check for every possible one.

For targeting to allow invulnerable... well as I said it is not a spell but completely triggered.
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
here is the link to the system
Pick the one with the title "Effect Over Time".
I removed that ability though.

It is an example ability for that system so the trigger won't help you a lot, but if you insist:
  • Divine Shield
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Divine Shield (Paladin)
    • Actions
      • Set EOT_Param_Source = (Triggering unit)
      • Set EOT_Param_Target = (Triggering unit)
      • Set EOT_Param_Duration = (5.00 + (5.00 x (Real((Level of (Ability being cast) for EOT_Param_Source)))))
      • Set EOT_Param_Interval = 3.00
      • Set EOT_Param_Hidden = False
      • Set EOT_Param_Buff_Holder = Divine Shield (Buff Holder)
      • Set EOT_Param_Buff = Custom Divine Shield
      • Special Effect - Create a special effect attached to the origin of EOT_Param_Target using Abilities\Spells\Human\DivineShield\DivineShieldTarget.mdl
      • Set EOT_Param_Special_Effect = (Last created special effect)
      • Set EOT_Param_Ability = Invulnerable (Neutral)
      • Set EOT_Param_Ability_Level = 1
      • Set EOT_Param_Positive = True
      • Set EOT_Param_Type = EOT_Type_Empty
      • Set EOT_Param_Existing_EOT_Handler = EOT_EEH_Override
      • Trigger - Run EOT_Trigger_Create_EOT (ignoring conditions)
JASS:
function Trig_EOT_Save_EOT takes timer t returns nothing
    local integer i
    local integer max
    local integer unitid
    
    if udg_EOT_Param_Ability > 0 and udg_EOT_Param_Ability_Level > 0 then
        set i = 0
        set max = udg_EOT_Effect_Search_Limit * 2
        set unitid = GetHandleId(udg_EOT_Param_Target)
        loop
            if i > max then
                set udg_EOT_Effect_Search_Limit = udg_EOT_Effect_Search_Limit + 1
                set max = max + 2
            endif
            if LoadInteger(udg_EOT_Hashtable, unitid, i) == 0 then
                exitwhen true
            endif
        
            set i = i + 2
        endloop
        
        call SaveInteger(udg_EOT_Hashtable, unitid, i, udg_EOT_Param_Ability)
        call SaveTimerHandle(udg_EOT_Hashtable, unitid, i + 1, t)
    endif
endfunction

function Trig_EOT_Destroy_EOT takes timer t returns nothing
    local integer i = 0
    local integer max = udg_EOT_Effect_Search_Limit*2
    local integer timerid = GetHandleId(t)
    local integer unitid = GetHandleId(udg_EOT_Param_Target)
    
    loop
        if i > max then
            exitwhen true
        endif
        
        if LoadTimerHandle(udg_EOT_Hashtable, unitid, i + 1) == t then
            exitwhen true
        endif
    
        set i = i + 2
    endloop
    
    loop
        if i > max then
            exitwhen true
        endif
        
        call SaveInteger(udg_EOT_Hashtable, unitid, i, LoadInteger(udg_EOT_Hashtable, unitid, i + 2))
        call SaveTimerHandle(udg_EOT_Hashtable, unitid, i + 1, LoadTimerHandle(udg_EOT_Hashtable, unitid, i + 3))
        
        if LoadInteger(udg_EOT_Hashtable, unitid, i + 2) == 0 then
            exitwhen true
        endif
        
        set i = i + 2
    endloop
endfunction

function Trig_EOT_Interval_Short takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    
    set udg_EOT_Param_Source            = LoadUnitHandle(   udg_EOT_Hashtable, id, 0)
    set udg_EOT_Param_Target            = LoadUnitHandle(   udg_EOT_Hashtable, id, 1)
    set udg_EOT_Param_Duration          = LoadReal(         udg_EOT_Hashtable, id, 2)
    set udg_EOT_Param_Interval          = LoadReal(         udg_EOT_Hashtable, id, 3)
    set udg_EOT_Param_Hidden            = LoadBoolean(      udg_EOT_Hashtable, id, 4)
    set udg_EOT_Param_Buff              = LoadInteger(      udg_EOT_Hashtable, id, 5)
    set udg_EOT_Param_Buff_Holder       = LoadInteger(      udg_EOT_Hashtable, id, 6)
    set udg_EOT_Param_Damage            = LoadReal(         udg_EOT_Hashtable, id, 7)
    set udg_EOT_Param_Attack_Type       = ConvertAttackType(LoadInteger(udg_EOT_Hashtable, id, 8))
    set udg_EOT_Param_Damage_Type       = ConvertDamageType(LoadInteger(udg_EOT_Hashtable, id, 9))
    set udg_EOT_Param_Ability           = LoadInteger(      udg_EOT_Hashtable, id, 10)
    set udg_EOT_Param_Ability_Level     = LoadInteger(      udg_EOT_Hashtable, id, 11)
    set udg_EOT_Param_Special_Effect    = LoadEffectHandle( udg_EOT_Hashtable, id, 12)
    set udg_EOT_Param_Type              = LoadInteger(      udg_EOT_Hashtable, id, 13)
    set udg_EOT_Param_Positive          = LoadBoolean(      udg_EOT_Hashtable, id, 14)
    
    set udg_EOT_Event_An_EOT_Has_Expired = 1
    set udg_EOT_Event_An_EOT_Has_Expired = 0
    
    call UnitRemoveAbility(udg_EOT_Param_Target, udg_EOT_Param_Buff)
    call UnitRemoveAbility(udg_EOT_Param_Target, udg_EOT_Param_Ability)
    call DestroyEffect(udg_EOT_Param_Special_Effect)
    call Trig_EOT_Destroy_EOT(t)
    call DestroyTimer(t)
    set t = null
endfunction

function Trig_EOT_Interval takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local unit oldtarget
    local unit newtarget
    
    set udg_EOT_Param_Source            = LoadUnitHandle(   udg_EOT_Hashtable, id, 0)
    set udg_EOT_Param_Target            = LoadUnitHandle(   udg_EOT_Hashtable, id, 1)
    set udg_EOT_Param_Duration          = LoadReal(         udg_EOT_Hashtable, id, 2)
    set udg_EOT_Param_Interval          = LoadReal(         udg_EOT_Hashtable, id, 3)
    set udg_EOT_Param_Hidden            = LoadBoolean(      udg_EOT_Hashtable, id, 4)
    set udg_EOT_Param_Buff              = LoadInteger(      udg_EOT_Hashtable, id, 5)
    set udg_EOT_Param_Buff_Holder       = LoadInteger(      udg_EOT_Hashtable, id, 6)
    set udg_EOT_Param_Damage            = LoadReal(         udg_EOT_Hashtable, id, 7)
    set udg_EOT_Param_Attack_Type       = ConvertAttackType(LoadInteger(udg_EOT_Hashtable, id, 8))
    set udg_EOT_Param_Damage_Type       = ConvertDamageType(LoadInteger(udg_EOT_Hashtable, id, 9))
    set udg_EOT_Param_Ability           = LoadInteger(      udg_EOT_Hashtable, id, 10)
    set udg_EOT_Param_Ability_Level     = LoadInteger(      udg_EOT_Hashtable, id, 11)
    set udg_EOT_Param_Special_Effect    = LoadEffectHandle( udg_EOT_Hashtable, id, 12)
    set udg_EOT_Param_Type              = LoadInteger(      udg_EOT_Hashtable, id, 13)
    set udg_EOT_Param_Positive          = LoadBoolean(      udg_EOT_Hashtable, id, 14)
    
    if (GetUnitAbilityLevel(udg_EOT_Param_Target, udg_EOT_Param_Buff) == 0 and udg_EOT_Param_Hidden == false) or udg_EOT_Param_Duration < 0. or udg_EOT_Param_Target == null then
        
        if udg_EOT_Param_Duration < 0. then
            set udg_EOT_Event_An_EOT_Has_Expired = 1
            set udg_EOT_Event_An_EOT_Has_Expired = 0
        elseif GetUnitAbilityLevel(udg_EOT_Param_Target, udg_EOT_Param_Buff) == 0 and udg_EOT_Param_Hidden == false then
            set udg_EOT_Event_An_EOT_Is_Dispelled = 1
            set udg_EOT_Event_An_EOT_Is_Dispelled = 0
        endif
        
        call UnitRemoveAbility(udg_EOT_Param_Target, udg_EOT_Param_Buff)
        call UnitRemoveAbility(udg_EOT_Param_Target, udg_EOT_Param_Ability)
        call DestroyEffect(udg_EOT_Param_Special_Effect)
        call Trig_EOT_Destroy_EOT(t)
        call DestroyTimer(t)
        set t = null
        return
    endif
    
    set udg_EOT_Param_Duration = udg_EOT_Param_Duration - udg_EOT_Param_Interval
    set oldtarget = udg_EOT_Param_Target
    
    call TriggerExecute(udg_EOT_Type_Triggers[udg_EOT_Param_Type])
    
    if udg_EOT_Param_Duration <= 0. or udg_EOT_Param_Duration <= 0. then
        set udg_EOT_Event_An_EOT_Has_Expired = 1
        set udg_EOT_Event_An_EOT_Has_Expired = 0
        
        call UnitRemoveAbility(udg_EOT_Param_Target, udg_EOT_Param_Buff)
        call UnitRemoveAbility(udg_EOT_Param_Target, udg_EOT_Param_Ability)
        call DestroyEffect(udg_EOT_Param_Special_Effect)
        call Trig_EOT_Destroy_EOT(t)
        call DestroyTimer(t)
        set t = null
        return
    endif
    
    if udg_EOT_Param_Target != oldtarget then
        set newtarget = udg_EOT_Param_Target
        set udg_EOT_Param_Target = oldtarget
        call TriggerExecute(udg_EOT_Trigger_Destroy_EOT)
        set udg_EOT_Param_Target = newtarget
        call TriggerExecute(udg_EOT_Trigger_Create_EOT)
        set newtarget = null
        set t = null
        return
    endif
    
    if udg_EOT_Param_Duration < udg_EOT_Param_Interval then
        call TimerStart(t, udg_EOT_Param_Duration, false, function Trig_EOT_Interval_Short)
    else
        call TimerStart(t, udg_EOT_Param_Interval, false, function Trig_EOT_Interval)
    endif
    if udg_EOT_Param_Hidden == false then
        call UnitAddAbility(udg_EOT_Param_Target, udg_EOT_Param_Buff_Holder)
        call UnitRemoveAbility(udg_EOT_Param_Target, udg_EOT_Param_Buff_Holder)
    endif
    if udg_EOT_Param_Ability > 0 then
        call SetUnitAbilityLevel(udg_EOT_Param_Target, udg_EOT_Param_Ability, udg_EOT_Param_Ability_Level)
    endif
    
    call SaveUnitHandle(        udg_EOT_Hashtable, id, 0,  udg_EOT_Param_Source)
    call SaveUnitHandle(        udg_EOT_Hashtable, id, 1,  udg_EOT_Param_Target)
    call SaveReal(          udg_EOT_Hashtable, id, 2,  udg_EOT_Param_Duration)
    call SaveReal(          udg_EOT_Hashtable, id, 3,  udg_EOT_Param_Interval)
    call SaveBoolean(       udg_EOT_Hashtable, id, 4,  udg_EOT_Param_Hidden)
    call SaveInteger(       udg_EOT_Hashtable, id, 5,  udg_EOT_Param_Buff)
    call SaveInteger(       udg_EOT_Hashtable, id, 6,  udg_EOT_Param_Buff_Holder)
    call SaveReal(          udg_EOT_Hashtable, id, 7,  udg_EOT_Param_Damage)
    call SaveInteger(       udg_EOT_Hashtable, id, 8,  ConvertAttackTypeReverse(udg_EOT_Param_Attack_Type))
    call SaveInteger(       udg_EOT_Hashtable, id, 9,  ConvertDamageTypeReverse(udg_EOT_Param_Damage_Type))
    call SaveInteger(       udg_EOT_Hashtable, id, 10, udg_EOT_Param_Ability)
    call SaveInteger(       udg_EOT_Hashtable, id, 11, udg_EOT_Param_Ability_Level)
    call SaveEffectHandle(  udg_EOT_Hashtable, id, 12, udg_EOT_Param_Special_Effect)
    call SaveInteger(       udg_EOT_Hashtable, id, 13, udg_EOT_Param_Type)
    call SaveBoolean(       udg_EOT_Hashtable, id, 14, udg_EOT_Param_Positive)
    
    set oldtarget = null
    set t = null
endfunction

function Trig_EOT_Create_EOT_Actions takes nothing returns boolean
    local timer t
    local integer id
    
    local unit osource = udg_EOT_Param_Source
    local unit otarget = udg_EOT_Param_Target
    local real oduration = udg_EOT_Param_Duration
    local real ointerval = udg_EOT_Param_Interval
    local boolean ohidden = udg_EOT_Param_Hidden
    local integer obuff = udg_EOT_Param_Buff
    local integer obuffHolder = udg_EOT_Param_Buff_Holder
    local real odamage = udg_EOT_Param_Damage
    local attacktype oattackType = udg_EOT_Param_Attack_Type
    local damagetype odamageType = udg_EOT_Param_Damage_Type
    local integer oability = udg_EOT_Param_Ability
    local integer oabilityLevel = udg_EOT_Param_Ability_Level
    local effect oeffect = udg_EOT_Param_Special_Effect
    local integer otype = udg_EOT_Param_Type
    local integer oEOTHandler = udg_EOT_Param_Existing_EOT_Handler
    local boolean opositive = udg_EOT_Param_Positive
    
    if TriggerEvaluate(udg_EOT_Trigger_Get_Data) then
        if udg_EOT_Param_Existing_EOT_Handler == udg_EOT_EEH_Override then
            call TriggerExecute(udg_EOT_Trigger_Destroy_EOT)
        elseif udg_EOT_Param_Existing_EOT_Handler == udg_EOT_EEH_Stack then
            set oduration = oduration + TimerGetRemaining(udg_EOT_Timer) + udg_EOT_Param_Duration - udg_EOT_Param_Interval
            call TriggerExecute(udg_EOT_Trigger_Destroy_EOT)
        endif
        
        set udg_EOT_Param_Source = osource
        set udg_EOT_Param_Target = otarget
        set udg_EOT_Param_Duration = oduration
        set udg_EOT_Param_Interval = ointerval
        set udg_EOT_Param_Hidden = ohidden
        set udg_EOT_Param_Buff = obuff
        set udg_EOT_Param_Buff_Holder = obuffHolder
        set udg_EOT_Param_Damage = odamage
        set udg_EOT_Param_Attack_Type = oattackType
        set udg_EOT_Param_Damage_Type = odamageType
        set udg_EOT_Param_Ability = oability
        set udg_EOT_Param_Ability_Level = oabilityLevel
        set udg_EOT_Param_Special_Effect = oeffect
        set udg_EOT_Param_Type = otype
        set udg_EOT_Param_Existing_EOT_Handler = oEOTHandler
        set udg_EOT_Param_Positive = opositive
    endif
    
    if udg_EOT_Param_Duration <= 0. or udg_EOT_Param_Interval <= 0. then
        set osource = null
        set otarget = null
        set oattackType = null
        set odamageType = null
        set oeffect = null
        return false
    endif
    
    set t = CreateTimer()
    set id = GetHandleId(t)
    
    if udg_EOT_Param_Hidden == false then
        call UnitAddAbility(udg_EOT_Param_Target, udg_EOT_Param_Buff_Holder)
        call UnitRemoveAbility(udg_EOT_Param_Target, udg_EOT_Param_Buff_Holder)
    endif
    
    if udg_EOT_Param_Ability > 0 and udg_EOT_Param_Ability_Level > 0 then
        call UnitAddAbility(udg_EOT_Param_Target, udg_EOT_Param_Ability)
        call SetUnitAbilityLevel(udg_EOT_Param_Target, udg_EOT_Param_Ability, udg_EOT_Param_Ability_Level)
    endif
    
    if udg_EOT_Param_Duration < udg_EOT_Param_Interval then
        call TimerStart(t, udg_EOT_Param_Duration, false, function Trig_EOT_Interval_Short)
    else
        call TimerStart(t, udg_EOT_Param_Interval, false, function Trig_EOT_Interval)
    endif
    
    call SaveUnitHandle(    udg_EOT_Hashtable, id, 0,  udg_EOT_Param_Source)
    call SaveUnitHandle(    udg_EOT_Hashtable, id, 1,  udg_EOT_Param_Target)
    call SaveReal(          udg_EOT_Hashtable, id, 2,  udg_EOT_Param_Duration)
    call SaveReal(          udg_EOT_Hashtable, id, 3,  udg_EOT_Param_Interval)
    call SaveBoolean(       udg_EOT_Hashtable, id, 4,  udg_EOT_Param_Hidden)
    call SaveInteger(       udg_EOT_Hashtable, id, 5,  udg_EOT_Param_Buff)
    call SaveInteger(       udg_EOT_Hashtable, id, 6,  udg_EOT_Param_Buff_Holder)
    call SaveReal(          udg_EOT_Hashtable, id, 7,  udg_EOT_Param_Damage)
    call SaveInteger(       udg_EOT_Hashtable, id, 8,  ConvertAttackTypeReverse(udg_EOT_Param_Attack_Type))
    call SaveInteger(       udg_EOT_Hashtable, id, 9,  ConvertDamageTypeReverse(udg_EOT_Param_Damage_Type))
    call SaveInteger(       udg_EOT_Hashtable, id, 10, udg_EOT_Param_Ability)
    call SaveInteger(       udg_EOT_Hashtable, id, 11, udg_EOT_Param_Ability_Level)
    call SaveEffectHandle(  udg_EOT_Hashtable, id, 12, udg_EOT_Param_Special_Effect)
    call SaveInteger(       udg_EOT_Hashtable, id, 13, udg_EOT_Param_Type)
    call SaveBoolean(       udg_EOT_Hashtable, id, 14, udg_EOT_Param_Positive)
    
    call Trig_EOT_Save_EOT(t)
    
    set udg_EOT_Event_An_EOT_Is_Created = 1
    set udg_EOT_Event_An_EOT_Is_Created = 0
    
    set udg_EOT_Param_Source = null
    set udg_EOT_Param_Target = null
    set udg_EOT_Param_Duration = 0
    set udg_EOT_Param_Interval = 0
    set udg_EOT_Param_Hidden = false
    set udg_EOT_Param_Buff = 0
    set udg_EOT_Param_Buff_Holder = 0
    set udg_EOT_Param_Damage = 0
    set udg_EOT_Param_Attack_Type = ConvertAttackType(0)
    set udg_EOT_Param_Damage_Type = ConvertDamageType(0)
    set udg_EOT_Param_Ability = 0
    set udg_EOT_Param_Ability_Level = 0
    set udg_EOT_Param_Special_Effect = null
    set udg_EOT_Param_Type = 0
    set udg_EOT_Param_Positive = false
    set osource = null
    set otarget = null
    set oattackType = null
    set odamageType = null
    set oeffect = null
    set t = null
    return true
endfunction

function Trig_EOT_Destroy_EOT_Actions takes nothing returns boolean
    if TriggerEvaluate(udg_EOT_Trigger_Get_Data) then
        set udg_EOT_Event_An_EOT_Is_Destroyed = 1
        set udg_EOT_Event_An_EOT_Is_Destroyed = 0
        
        call Trig_EOT_Destroy_EOT(udg_EOT_Timer)
        call DestroyEffect(udg_EOT_Param_Special_Effect)
        call UnitRemoveAbility(udg_EOT_Param_Target, udg_EOT_Param_Buff)
        call UnitRemoveAbility(udg_EOT_Param_Target, udg_EOT_Param_Ability)
        call PauseTimer(udg_EOT_Timer)
        call DestroyTimer(udg_EOT_Timer)
        return true
    endif
    return false
endfunction

function Trig_EOT_Get_Data_Actions takes nothing returns boolean
    local integer i
    local integer max
    local integer unitid 
    
    if GetUnitAbilityLevel(udg_EOT_Param_Target, udg_EOT_Param_Ability) <= 0 then
        return false
    endif
    
    set i = 0
    set max = udg_EOT_Effect_Search_Limit * 2
    set unitid = GetHandleId(udg_EOT_Param_Target)
    
    loop
        if i > max then
            exitwhen true
        endif
        if LoadInteger(udg_EOT_Hashtable, unitid, i) == 0 then
            exitwhen true
        endif
        if LoadInteger(udg_EOT_Hashtable, unitid, i) == udg_EOT_Param_Ability then
            set udg_EOT_Timer = LoadTimerHandle(udg_EOT_Hashtable, unitid, i + 1)
            set i = GetHandleId(udg_EOT_Timer)
            
            set udg_EOT_Param_Source            = LoadUnitHandle(   udg_EOT_Hashtable, i, 0)
            set udg_EOT_Param_Target            = LoadUnitHandle(   udg_EOT_Hashtable, i, 1)
            set udg_EOT_Param_Duration          = LoadReal(         udg_EOT_Hashtable, i, 2)
            set udg_EOT_Param_Interval          = LoadReal(         udg_EOT_Hashtable, i, 3)
            set udg_EOT_Param_Hidden            = LoadBoolean(      udg_EOT_Hashtable, i, 4)
            set udg_EOT_Param_Buff              = LoadInteger(      udg_EOT_Hashtable, i, 5)
            set udg_EOT_Param_Buff_Holder       = LoadInteger(      udg_EOT_Hashtable, i, 6)
            set udg_EOT_Param_Damage            = LoadReal(         udg_EOT_Hashtable, i, 7)
            set udg_EOT_Param_Attack_Type       = ConvertAttackType(LoadInteger(udg_EOT_Hashtable, i, 8))
            set udg_EOT_Param_Damage_Type       = ConvertDamageType(LoadInteger(udg_EOT_Hashtable, i, 9))
            set udg_EOT_Param_Ability           = LoadInteger(      udg_EOT_Hashtable, i, 10)
            set udg_EOT_Param_Ability_Level     = LoadInteger(      udg_EOT_Hashtable, i, 11)
            set udg_EOT_Param_Special_Effect    = LoadEffectHandle( udg_EOT_Hashtable, i, 12)
            set udg_EOT_Param_Type              = LoadInteger(      udg_EOT_Hashtable, i, 13)
            set udg_EOT_Param_Positive          = LoadBoolean(      udg_EOT_Hashtable, i, 14)
            return true
        endif
        set i = i + 2
    endloop
    return false
endfunction

function Trig_EOT_Save_Data_Actions takes nothing returns boolean
    local integer i
    local real r
    local integer max
    local integer unitid 
    
    if GetUnitAbilityLevel(udg_EOT_Param_Target, udg_EOT_Param_Ability) <= 0 then
        return false
    endif
    
    set i = 0
    set max = udg_EOT_Effect_Search_Limit * 2
    set unitid = GetHandleId(udg_EOT_Param_Target)
    
    loop
        if i > max then
            exitwhen true
        endif
        if LoadInteger(udg_EOT_Hashtable, unitid, i) == 0 then
            exitwhen true
        endif
        if LoadInteger(udg_EOT_Hashtable, unitid, i) == udg_EOT_Param_Ability then
            set udg_EOT_Timer = LoadTimerHandle(udg_EOT_Hashtable, unitid, i + 1)
            set i = GetHandleId(udg_EOT_Timer)
            
            call SaveUnitHandle(    udg_EOT_Hashtable, i, 0,  udg_EOT_Param_Source)
            call SaveUnitHandle(    udg_EOT_Hashtable, i, 1,  udg_EOT_Param_Target)
            call SaveReal(          udg_EOT_Hashtable, i, 2,  udg_EOT_Param_Duration)
            call SaveReal(          udg_EOT_Hashtable, i, 3,  udg_EOT_Param_Interval)
            call SaveBoolean(       udg_EOT_Hashtable, i, 4,  udg_EOT_Param_Hidden)
            call SaveInteger(       udg_EOT_Hashtable, i, 5,  udg_EOT_Param_Buff)
            call SaveInteger(       udg_EOT_Hashtable, i, 6,  udg_EOT_Param_Buff_Holder)
            call SaveReal(          udg_EOT_Hashtable, i, 7,  udg_EOT_Param_Damage)
            call SaveInteger(       udg_EOT_Hashtable, i, 8,  ConvertAttackTypeReverse(udg_EOT_Param_Attack_Type))
            call SaveInteger(       udg_EOT_Hashtable, i, 9,  ConvertDamageTypeReverse(udg_EOT_Param_Damage_Type))
            call SaveInteger(       udg_EOT_Hashtable, i, 10, udg_EOT_Param_Ability)
            call SaveInteger(       udg_EOT_Hashtable, i, 11, udg_EOT_Param_Ability_Level)
            call SaveEffectHandle(  udg_EOT_Hashtable, i, 12, udg_EOT_Param_Special_Effect)
            call SaveInteger(       udg_EOT_Hashtable, i, 13, udg_EOT_Param_Type)
            call SaveBoolean(       udg_EOT_Hashtable, i, 14, udg_EOT_Param_Positive)
            
            set r = udg_EOT_Param_Duration + TimerGetRemaining(udg_EOT_Timer) - udg_EOT_Param_Interval
            if r < udg_EOT_Param_Duration and r < udg_EOT_Param_Interval then
                call TimerStart(udg_EOT_Timer, r, false, function Trig_EOT_Interval_Short)
            endif
            
            return true
        endif
        set i = i + 2
    endloop
    return false
endfunction

function Trig_EOT_Remove_EOTs_Actions takes nothing returns nothing
    local integer i = 0
    local integer abilityid
    local integer id = GetHandleId(udg_EOT_Param_Target)
    local boolean hidden = udg_EOT_Param_Hidden
    local boolean positive = udg_EOT_Param_Positive
    local boolean negative = udg_EOT_Param_Negative
    
    loop
        set abilityid = LoadInteger(udg_EOT_Hashtable, id, i)
        if abilityid == 0 then
            exitwhen true
        endif
        if TriggerEvaluate(udg_EOT_Trigger_Get_Data) then
            if (not hidden) or udg_EOT_Param_Hidden then
                if (positive and udg_EOT_Param_Positive) or (negative and udg_EOT_Param_Negative) then
                    set udg_EOT_Event_An_EOT_Is_Dispelled = 1
                    set udg_EOT_Event_An_EOT_Is_Dispelled = 0
                    
                    call TriggerExecute(udg_EOT_Trigger_Destroy_EOT)
                endif
            endif
        else
            set i = i + 2
        endif
    endloop
endfunction

function Trig_EOT_System_Initialization takes nothing returns boolean
    set udg_EOT_Hashtable = InitHashtable()
    set udg_EOT_EEH_Override = 0
    set udg_EOT_EEH_Stack = 1
    call TriggerExecute(gg_trg_EOT_Configuration)
    
    set udg_EOT_Trigger_Create_EOT = CreateTrigger()
    call TriggerAddCondition(udg_EOT_Trigger_Create_EOT, Filter(function Trig_EOT_Create_EOT_Actions))
    call TriggerAddAction(udg_EOT_Trigger_Create_EOT, function Trig_EOT_Create_EOT_Actions)
    
    set udg_EOT_Trigger_Destroy_EOT = CreateTrigger()
    call TriggerAddCondition(udg_EOT_Trigger_Destroy_EOT, Filter(function Trig_EOT_Destroy_EOT_Actions))
    call TriggerAddAction(udg_EOT_Trigger_Destroy_EOT, function Trig_EOT_Destroy_EOT_Actions)
    
    set udg_EOT_Trigger_Get_Data = CreateTrigger()
    call TriggerAddCondition(udg_EOT_Trigger_Get_Data, Filter(function Trig_EOT_Get_Data_Actions))
    call TriggerAddAction(udg_EOT_Trigger_Get_Data, function Trig_EOT_Get_Data_Actions)
    
    set udg_EOT_Trigger_Save_Data = CreateTrigger()
    call TriggerAddCondition(udg_EOT_Trigger_Save_Data, Filter(function Trig_EOT_Save_Data_Actions))
    call TriggerAddAction(udg_EOT_Trigger_Save_Data, function Trig_EOT_Save_Data_Actions)
    
    set udg_EOT_Trigger_Remove_EOTs = CreateTrigger()
    call TriggerAddAction(udg_EOT_Trigger_Remove_EOTs, function Trig_EOT_Remove_EOTs_Actions)
    
    call DestroyTrigger(gg_trg_EOT_System)
    return false
endfunction

function InitTrig_EOT_System takes nothing returns nothing
    set gg_trg_EOT_System = CreateTrigger()
    call TriggerAddCondition(gg_trg_EOT_System, Filter(function Trig_EOT_System_Initialization))
endfunction
 

Zwiebelchen

Hosted Project GR
Level 35
Joined
Sep 17, 2009
Messages
7,236
You check for the buff, not the "holder" ability in your periodic function, hence why when the buff doesn't show up because of invulnerability, the periodic effects do not work. I suppose you use auras to apply the dummy buffs? In that case, make sure your aura also targets invulnerable units. Note that some auras have hardcoded targets.

Checking for the buff is not a good idea anyway, as buffs have a delay. Check for the holder ability.
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
You check for the buff, not the "holder" ability in your periodic function, hence why when the buff doesn't show up because of invulnerability, the periodic effects do not work. I suppose you use auras to apply the dummy buffs? In that case, make sure your aura also targets invulnerable units. Note that some auras have hardcoded targets.
Wow... just wow.
It actually was the problem.
I used targets allowed for the auras to self only but it seems that there is something weird about those.
(+Rep)

Checking for the buff is not a good idea anyway, as buffs have a delay. Check for the holder ability.
That is not a very good idea.
I add and then immediately remove the aura so the unit will have the buff and I do not have to create a spellbook for every single spell.
Next to that, imagine someone using dispel on the target.
The buff is removed so the effect will stop. (For passive effects that would not be immediately if dispel is not triggered.)
But what if that unit gains the buff again because he has the aura?
Then the dispel is not doing shit.

The buff delay is not a problem because I remove the buff too when the duration has ran out.
The only problem would be if someone would be so smart to set the interval to 4+ seconds. Then it won't work.
 

Zwiebelchen

Hosted Project GR
Level 35
Joined
Sep 17, 2009
Messages
7,236
That is not a very good idea.
I add and then immediately remove the aura so the unit will have the buff and I do not have to create a spellbook for every single spell.
That's why pros use tornado aura for dummy buffs, as it doesn't need a spellbook (it's hidden in the command card by default).

Next to that, imagine someone using dispel on the target.
The buff is removed so the effect will stop. (For passive effects that would not be immediately if dispel is not triggered.)
But what if that unit gains the buff again because he has the aura?
Then the dispel is not doing shit.
Does dispel even remove aura buffs?

The buff delay is not a problem because I remove the buff too when the duration has ran out.
The only problem would be if someone would be so smart to set the interval to 4+ seconds. Then it won't work.
Why not... well ... create a system that works all the time and not just in specific cases?
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
That's why pros use tornado aura for dummy buffs, as it doesn't need a spellbook (it's hidden in the command card by default).
Can I set the buff to be positive?
I do have my reasons for some stuff ^^

Does dispel even remove aura buffs?
It does.
But the aura just gives the dispel the finger and the unit a new buff.

Why not... well ... create a system that works all the time and not just in specific cases?
Because it is possible :)
You just have to add the aura ability to the bonus ability that is given to the targeted unit. The it will not be dispelled.
 

Zwiebelchen

Hosted Project GR
Level 35
Joined
Sep 17, 2009
Messages
7,236
Can I set the buff to be positive?
I do have my reasons for some stuff ^^
Just change the tooltip name with the color code for green if you need to mimic a positive buff.

It does.
But the aura just gives the dispel the finger and the unit a new buff.
It's better to trigger the dispel anyway. The default dispel mechanic is extremely limited.

Because it is possible :)
You just have to add the aura ability to the bonus ability that is given to the targeted unit. The it will not be dispelled.
Whenever there's a note like "do not put in xy here" in a system API, then this is just laziness to write the system properly.
It's like writing a pocket calculator, then telling the user "nah, addition only works with positive numbers".
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
Just change the tooltip name with the color code for green if you need to mimic a positive buff.
  • Unit - Remove Negative buffs from (Triggering unit)
Should say enough.
This will also remove the "positive" buffs then.
And the regular dispel will also be bugged then.

It's better to trigger the dispel anyway. The default dispel mechanic is extremely limited.
It should be triggered indeed but it is not that much limited.
It works fine for regular warcraft.

Whenever there's a note like "do not put in xy here" in a system API, then this is just laziness to write the system properly.
It's like writing a pocket calculator, then telling the user "nah, addition only works with positive numbers".
The only restriction is that you cannot use an interval more than 3 seconds.
If you do want that, you should make a spellbook and add the aura to that one.
Then it will make the buff again when it expires.
However you are not able to dispel it regulary any more.
 

Zwiebelchen

Hosted Project GR
Level 35
Joined
Sep 17, 2009
Messages
7,236
  • Unit - Remove Negative buffs from (Triggering unit)
Should say enough.
This will also remove the "positive" buffs then.
And the regular dispel will also be bugged then.
I'm too lazy now to check out that BJ, but I'm pretty sure it only loops through a hardcoded list of buffs and thus, does not detect custom buffs anyway. There is no specific native for buffs as they are, in fact, just a different type of abilities.

It should be triggered indeed but it is not that much limited.
It works fine for regular warcraft.
Eh, whatever, the problem is solved anyway.
 
Status
Not open for further replies.
Top