• Check out the results of the Techtree Contest #19!
  • 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.
  • Create a void inspired texture for Warcraft 3 and enter Hive's 34th Texturing Contest: Void! Click here to enter!
  • The Hive's 22nd Icon Contest: Creep Abilities is now concluded, time to vote for your favourite set of icons! Click here to vote!

[Spell] Aura that reduces spell effect duration

Level 8
Joined
May 13, 2023
Messages
111
  • Untitled Trigger 001
    • Events
    • Conditions
    • Actions
      • Ability - Set Ability: (Unit: (Triggering unit)'s Ability with Ability Code: (Ability being cast))'s Real Level Field: Duration - Normal ('adur') of Level: 0 to 10.00
      • Ability - Set Ability: (Unit: (Triggering unit)'s Ability with Ability Code: (Ability being cast))'s Real Level Field: Duration - Hero ('ahdu') of Level: 0 to 10.00
with the introduction of the 2 actions above, I was interested in making an aura that reduces all negative unit target spell duration. But the actions above alter the field globally so returning it to it's original duration seems a bit tricky to me, below is my attempt and it reduces fine but i dont know how to change it back it's original duration, should i use hashtables to save initial duration values and use timers or just use waits with variables
JASS:
function Trig_Status_Resistance_Actions takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local unit target = GetSpellTargetUnit()
    local integer abil = GetSpellAbilityId()
    local real reduction1
    local real reduction2

    // only check enemy spells
    if IsUnitEnemy(target, GetOwningPlayer(caster)) and UnitHasBuffBJ(target, 'B006') then
        //reduces duration by 50%
        set reduction1 = BlzGetAbilityRealLevelField(BlzGetUnitAbility(caster, abil), ABILITY_RLF_DURATION_NORMAL, GetUnitAbilityLevelSwapped(abil, caster) - 1 ) * 0.50
        set reduction2 = BlzGetAbilityRealLevelField(BlzGetUnitAbility(caster, abil), ABILITY_RLF_DURATION_HERO, GetUnitAbilityLevelSwapped(abil, caster) - 1 ) * 0.50
        call BlzSetAbilityRealLevelFieldBJ(BlzGetUnitAbility(caster, abil), ABILITY_RLF_DURATION_HERO, (GetUnitAbilityLevelSwapped(abil, caster) - 1 ), reduction2)
        call BlzSetAbilityRealLevelFieldBJ(BlzGetUnitAbility(caster, abil), ABILITY_RLF_DURATION_NORMAL, (GetUnitAbilityLevelSwapped(abil, caster) - 1 ), reduction1)
    endif

    set caster = null
    set target = null
endfunction

//===========================================================================
function InitTrig_Status_Resistance takes nothing returns nothing
    set gg_trg_Status_Resistance = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Status_Resistance, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddAction( gg_trg_Status_Resistance, function Trig_Status_Resistance_Actions )
endfunction
 
Last edited:
the actions above alter the field globally
It does not, or rather it should not. You are loading a specific instead of an ability (hence why you have to specify from which unit to load it).
If the change to duration does affect it globally, it could be a bug in the ability itself. For example doing this:
  • Untitled Trigger 001
    • Events
    • Conditions
    • Actions
      • Ability - Set Ability: (Unit: (Triggering unit)'s Ability with Ability Code: (Ability being cast))'s Real Level Field: Duration - Normal ('adur') of Level: 0 to 10.00
      • Ability - Set Ability: (Unit: (Triggering unit)'s Ability with Ability Code: (Ability being cast))'s Real Level Field: Duration - Hero ('ahdu') of Level: 0 to 10.00
but with Mountain King's storm bolt changes duration only for specific instance, not globally.

Apart from that, you could use hashtable and store the original duration there. Any time unit casts spell, you would check if the duration has been modified and if so, you would load the original value from hashtable. Or you could add a "Unit stops casting an ability" event and revert spell duration there.
 
The issue where it applies those changes globally is a bug with patch 2.0.3.22988. They have a build on the PTR that is supposed to fix it:

Not entirely sure when they are going to release it though. I'd expect later this month.
 
Hello. I want to make an aura that provides status resistance too, but I don't know how to adjust status resistance for spells like Aerial Shackles.
 
You can use the jass script at the top, depending on your preferences you can change the if condition.
I created the Status Resistance aura and it works 🙂, but then it still has 50% Status Resistance even without the aura ☹️.

Edit: I solved the problem

JASS:
function Trig_Status_Resistance_Increase_Actions takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local unit target = GetSpellTargetUnit()
    local integer abil = GetSpellAbilityId()
    local real reduction1
    local real reduction2

    // only check enemy spells
    if IsUnitEnemy(target, GetOwningPlayer(caster)) and UnitHasBuffBJ(target, 'BHab') then
        //reduces duration by 50%
        set reduction1 = BlzGetAbilityRealLevelField(BlzGetUnitAbility(caster, abil), ABILITY_RLF_DURATION_NORMAL, GetUnitAbilityLevelSwapped(abil, caster) - 1 ) * 0.50
        set reduction2 = BlzGetAbilityRealLevelField(BlzGetUnitAbility(caster, abil), ABILITY_RLF_DURATION_HERO, GetUnitAbilityLevelSwapped(abil, caster) - 1 ) * 0.50
        call BlzSetAbilityRealLevelFieldBJ(BlzGetUnitAbility(caster, abil), ABILITY_RLF_DURATION_HERO, (GetUnitAbilityLevelSwapped(abil, caster) - 1 ), reduction2)
        call BlzSetAbilityRealLevelFieldBJ(BlzGetUnitAbility(caster, abil), ABILITY_RLF_DURATION_NORMAL, (GetUnitAbilityLevelSwapped(abil, caster) - 1 ), reduction1)
    else
        //reduces duration by 0%
        set reduction1 = BlzGetAbilityRealLevelField(BlzGetUnitAbility(caster, abil), ABILITY_RLF_DURATION_NORMAL, GetUnitAbilityLevelSwapped(abil, caster) - 1 ) * 2
        set reduction2 = BlzGetAbilityRealLevelField(BlzGetUnitAbility(caster, abil), ABILITY_RLF_DURATION_HERO, GetUnitAbilityLevelSwapped(abil, caster) - 1 ) * 2
        call BlzSetAbilityRealLevelFieldBJ(BlzGetUnitAbility(caster, abil), ABILITY_RLF_DURATION_HERO, (GetUnitAbilityLevelSwapped(abil, caster) - 1 ), reduction2)
        call BlzSetAbilityRealLevelFieldBJ(BlzGetUnitAbility(caster, abil), ABILITY_RLF_DURATION_NORMAL, (GetUnitAbilityLevelSwapped(abil, caster) - 1 ), reduction1)
    endif

    set caster = null
    set target = null
endfunction

//===========================================================================
function InitTrig_Status_Resistance_Increase takes nothing returns nothing
    set gg_trg_Status_Resistance_Increase = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Status_Resistance_Increase, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddAction( gg_trg_Status_Resistance_Increase, function Trig_Status_Resistance_Increase_Actions )
endfunction

What about making an aura that reduces the impact of slows ? :ogre_datass:
 
Last edited:
Two great systems if you want to go the "fully custom" route and have a ton of control:

Otherwise, I attached an example map where you can modify any unit's Stun and Slow resistances. To add other resistances simply copy and paste an existing variable -> "Status_Stun_Resistance", then copy and paste it's associated Actions found within the Cast trigger, and modify them to reference the new variable.

With this you would no longer need to track much of anything yourself, your job is to modify your unit's new Status Resistance stats:
  • Set Variable Status_Stun_Resistance[(Custom value of (Your unit))] = 0.60
^ That would make the Duration of Stuns on the unit last 60% shorter. But it only works for Abilities that have been registered in the Setup trigger.
 

Attachments

Last edited:
Hello @Uncle. The basic stun resistance code you created is exactly what I wanted, but instead of registering all the spells, I would prefer it to be like the code @Astral_JG created. Registering all the spells individually is quite a laborious and tiring work.

I created the Status Resistance aura and it works 🙂, but then it still has 50% Status Resistance even without the aura ☹️.

Edit: I solved the problem

JASS:
function Trig_Status_Resistance_Increase_Actions takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local unit target = GetSpellTargetUnit()
    local integer abil = GetSpellAbilityId()
    local real reduction1
    local real reduction2

    // only check enemy spells
    if IsUnitEnemy(target, GetOwningPlayer(caster)) and UnitHasBuffBJ(target, 'BHab') then
        //reduces duration by 50%
        set reduction1 = BlzGetAbilityRealLevelField(BlzGetUnitAbility(caster, abil), ABILITY_RLF_DURATION_NORMAL, GetUnitAbilityLevelSwapped(abil, caster) - 1 ) * 0.50
        set reduction2 = BlzGetAbilityRealLevelField(BlzGetUnitAbility(caster, abil), ABILITY_RLF_DURATION_HERO, GetUnitAbilityLevelSwapped(abil, caster) - 1 ) * 0.50
        call BlzSetAbilityRealLevelFieldBJ(BlzGetUnitAbility(caster, abil), ABILITY_RLF_DURATION_HERO, (GetUnitAbilityLevelSwapped(abil, caster) - 1 ), reduction2)
        call BlzSetAbilityRealLevelFieldBJ(BlzGetUnitAbility(caster, abil), ABILITY_RLF_DURATION_NORMAL, (GetUnitAbilityLevelSwapped(abil, caster) - 1 ), reduction1)
    else
        //reduces duration by 0%
        set reduction1 = BlzGetAbilityRealLevelField(BlzGetUnitAbility(caster, abil), ABILITY_RLF_DURATION_NORMAL, GetUnitAbilityLevelSwapped(abil, caster) - 1 ) * 2
        set reduction2 = BlzGetAbilityRealLevelField(BlzGetUnitAbility(caster, abil), ABILITY_RLF_DURATION_HERO, GetUnitAbilityLevelSwapped(abil, caster) - 1 ) * 2
        call BlzSetAbilityRealLevelFieldBJ(BlzGetUnitAbility(caster, abil), ABILITY_RLF_DURATION_HERO, (GetUnitAbilityLevelSwapped(abil, caster) - 1 ), reduction2)
        call BlzSetAbilityRealLevelFieldBJ(BlzGetUnitAbility(caster, abil), ABILITY_RLF_DURATION_NORMAL, (GetUnitAbilityLevelSwapped(abil, caster) - 1 ), reduction1)
    endif

    set caster = null
    set target = null
endfunction

//===========================================================================
function InitTrig_Status_Resistance_Increase takes nothing returns nothing
    set gg_trg_Status_Resistance_Increase = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Status_Resistance_Increase, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddAction( gg_trg_Status_Resistance_Increase, function Trig_Status_Resistance_Increase_Actions )
endfunction

What about making an aura that reduces the impact of slows ? :ogre_datass:

There are still issues in the aura I created. Even after the buff is removed, the status resistance is still active. I honestly don't know how to fix it. When I double the variable value, the buff duration is doubled. The mechanic I want is for the spell effect duration to be halved when inside aura effect and for the spell effect duration to return to its original state when outside aura effect.

Otherwise, I attached an example map where you can modify any unit's Stun and Slow resistances. To add other resistances simply copy and paste an existing variable -> "Status_Stun_Resistance", then copy and paste it's associated Actions found within the Cast trigger, and modify them to reference the new variable.

With this you would no longer need to track much of anything yourself, your job is to modify your unit's new Status Resistance stats:
  • set.gif
    Set Variable Status_Stun_Resistance[(Custom value of (Your unit))] = 0.60
^ That would make the Duration of Stuns on the unit last 60% shorter. But it only works for Abilities that have been registered in the Setup trigger.

Slow resistance is a completely different mechanic than status resistance. For example, Frost Nova reduces movement speed by 50%. For a unit with 50% slow resistance, Frost Nova reduces movement speed by 25% instead of 50%.

Formula = ( Slow Value / 100 ) × ( 1 - ( Slow Resistance Value / 100 ) ) = Reduced Slow Value

Status Resistance manipulates spell duration, while Slow Resistance manipulates the amount of slow.
 
JASS:
else
        //reduces duration by 0%
        set reduction1 = BlzGetAbilityRealLevelField(BlzGetUnitAbility(caster, abil), ABILITY_RLF_DURATION_NORMAL, GetUnitAbilityLevelSwapped(abil, caster) - 1 ) * 2
        set reduction2 = BlzGetAbilityRealLevelField(BlzGetUnitAbility(caster, abil), ABILITY_RLF_DURATION_HERO, GetUnitAbilityLevelSwapped(abil, caster) - 1 ) * 2
        call BlzSetAbilityRealLevelFieldBJ(BlzGetUnitAbility(caster, abil), ABILITY_RLF_DURATION_HERO, (GetUnitAbilityLevelSwapped(abil, caster) - 1 ), reduction2)
        call BlzSetAbilityRealLevelFieldBJ(BlzGetUnitAbility(caster, abil), ABILITY_RLF_DURATION_NORMAL, (GetUnitAbilityLevelSwapped(abil, caster) - 1 ), reduction1)
endif
This shouldnt be in a separate conditions, whats currently happening is, every unit that is firing any unit target spell is getting their duration doubled, Bcz condition 1 isnt met if its used on a unit without the aura, Since the aura only needs 50% reduction, You can take Nichilus' idea and have another unit finishes casting trigger and return the spell to it's original duration.
 
As far I know, there's no way to tell if an Ability is a Stun or Slow without manually marking the Ability yourself. So Registering is necessary. That being said, there's not that many Stuns and Slows. Also, note that my system only works for abilities that target a unit directly -> (Target unit of ability being cast) has to exist. It's impossible to get this to work for say Earthquake without triggering the slow effect yourself, and this limitation is going to be very difficult to work around. I linked Chopinski's systems before for that very reason, ultimately you'll want to trigger things yourself to have full control.

List of Abilities that Stun and Slow off the top of my head:

Storm Bolt, Aerial Shackles, Bash (won't work, damage event) Slow, Cripple, Shadow Strike, Earthquake (won't work since it doesn't target), Frost Nova (won't work properly on secondary targets), Frost Armor (damage event), Slow Poison (damage event), Drunken Haze (secondary targets), Volcano (doesn't target), Thunder Clap (doesn't target). Ensnare/Entangling Roots are "roots" but I suppose you could consider them as well.

I can't remember them all but there's not too many, especially if you ignore the ones that don't even work.
 
Last edited:
Back
Top