[Spell] Passive spell disabled when Activate spell is cast

Level 6
Joined
May 13, 2023
Messages
72
Hi, I'd like to request a solution for this. I want a Passive ability that gets disabled whenever the owner of passive starts an active ability. I have this demo, only problem with it, is that when the caster issues another active ability while the passive is disabled it doesn't refresh the 8 second timer.
  • Elusiveness Cast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Level of Elusiveness for (Triggering unit)) Greater than 0
    • Actions
      • Custom script: local unit caster = GetTriggerUnit()
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((Triggering unit) has buff Elusiveness ) Equal to True
        • Then - Actions
          • Custom script: call BlzUnitDisableAbility( caster, 'A0E5', true, false )
        • Else - Actions
          • Skip remaining actions
      • Wait 8.00 seconds
      • Custom script: call BlzUnitDisableAbility( caster, 'A0E5', false, false )
      • Custom script: set caster = null
 

Rheiko

Spell Reviewer
Level 26
Joined
Aug 27, 2013
Messages
4,214
You need to handle different instances.

  • Elusiveness Cast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Level of Devotion Aura for (Triggering unit)) Greater than 0
    • Actions
      • -------- Increase the number of instances --------
      • Set EL_MaxIndex = (EL_MaxIndex + 1)
      • -------- Assign the caster into a variable for later use --------
      • Set EL_Caster[EL_MaxIndex] = (Triggering unit)
      • -------- The duration you prefer --------
      • Set EL_Duration[EL_MaxIndex] = 8.00
      • -------- Disable the ability --------
      • Custom script: call BlzUnitDisableAbility( udg_EL_Caster[udg_EL_MaxIndex], 'AHad', true, false )
      • -------- Turn on the timer when it's the only instance --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • EL_MaxIndex Equal to 1
        • Then - Actions
          • Trigger - Turn on Elusiveness Loop <gen>
        • Else - Actions
  • Elusiveness Loop
    • Events
      • Time - Every 1.00 seconds of game time
    • Conditions
    • Actions
      • -------- Loop through all the possible instances --------
      • For each (Integer EL_CurrentIndex) from 1 to EL_MaxIndex, do (Actions)
        • Loop - Actions
          • -------- Check if the timer's not up yet --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • EL_Duration[EL_CurrentIndex] Greater than 0.00
            • Then - Actions
              • -------- Just a debug message, feel free to remove this --------
              • Game - Display to (All players) the text: ((Timer[ + ((String(EL_CurrentIndex)) + ])) + (: + (String(EL_Duration[EL_CurrentIndex]))))
              • -------- It's true, meaning the timer's not up yet, we decrease the duration --------
              • -------- Make sure to substract EL_Duration with the value of periodic timer interval --------
              • Set EL_Duration[EL_CurrentIndex] = (EL_Duration[EL_CurrentIndex] - 1.00)
            • Else - Actions
              • -------- It's false, meaning the timer's up, we re-enable the ability and de-index --------
              • -------- Re-enable the ability --------
              • Custom script: call BlzUnitDisableAbility( udg_EL_Caster[udg_EL_CurrentIndex], 'AHad', false, false )
              • -------- De-Index ---------
              • Set EL_Caster[EL_CurrentIndex] = EL_Caster[EL_MaxIndex]
              • Set EL_Duration[EL_CurrentIndex] = EL_Duration[EL_MaxIndex]
              • Set EL_CurrentIndex = (EL_CurrentIndex - 1)
              • Set EL_MaxIndex = (EL_MaxIndex - 1)
              • -------- Turn off trigger when there's no instance left ---------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • EL_MaxIndex Equal to 0
                • Then - Actions
                  • Trigger - Turn off (This trigger)
                • Else - Actions


I'm using this method, in case you're interested: Visualize: Dynamic Indexing
Here's a testmap with a devotion aura. Adjust to your needs.
 

Attachments

  • Devotion Aura Test.w3x
    18 KB · Views: 4
Last edited:
Level 13
Joined
Feb 5, 2018
Messages
567
You could also try to add a local real variable and test with that. Note that local variables must always be at the top of the trigger and they will not work within if/then/else condition block, unless converted to a global variable first.
  • Custom script: local real Wait = 8.00
And how to to call this local wait you simply need to use this code instead of the regural wait
  • Custom script: call PolledWait(Wait)
On side note using this:
Skip remaining actions
Is a useless line of code, which most of the people doesn't use at all.
 

Rheiko

Spell Reviewer
Level 26
Joined
Aug 27, 2013
Messages
4,214
I confirmed, @DoomBlade 's method seems to work very well.

  • Elusiveness Cast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Level of Devotion Aura for (Triggering unit)) Greater than 0
    • Actions
      • Custom script: local unit caster = GetTriggerUnit()
      • Custom script: local real time = 8.00
      • Custom script: call BlzUnitDisableAbility( caster, 'AHad', true, false )
      • Custom script: call PolledWait(time)
      • Custom script: call BlzUnitDisableAbility( caster, 'AHad', false, false )
      • Custom script: set caster = null
The approach is much simpler and super handy.
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
What Rheiko made is a great solution but I wanted to use this as a time to showcase Unit Indexing as an alternative solution. With custom spells like these you will often have to make the decision, should I use Unit Indexing OR Dynamic Indexing? (Or a little bit of both).

Here's the Unit Indexing method, which I think fits this type of spell better because the spell doesn't actually need multiple instances running per caster:
  • Cast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Acid Bomb
      • ((Triggering unit) has buff Bloodlust) Equal to True
    • Actions
      • Set VariableSet Ability_Caster = (Triggering unit)
      • Set VariableSet Ability_Caster_Id = (Custom value of Ability_Caster)
      • -------- --------
      • -------- If this is equal to 0.00 then the effects of this ability were NOT active: --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Ability_Duration[Ability_Caster_Id] Equal to 0.00
        • Then - Actions
          • Unit - For Ability_Caster, Ability Avatar, Disable ability: True, Hide UI: False
          • Unit Group - Add Ability_Caster to Ability_Caster_Group
          • Trigger - Turn on Loop <gen>
        • Else - Actions
      • -------- --------
      • Set VariableSet Ability_Duration[Ability_Caster_Id] = 8.00
  • Loop
    • Events
      • Time - Every 0.05 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in Ability_Caster_Group and do (Actions)
        • Loop - Actions
          • Set VariableSet Ability_Caster = (Triggering unit)
          • Set VariableSet Ability_Caster_Id = (Custom value of Ability_Caster)
          • -------- --------
          • -------- Track how much time has passed for this specific unit: --------
          • Set VariableSet Ability_Duration[Ability_Caster_Id] = (Ability_Duration[Ability_Caster_Id] - 0.05)
          • -------- --------
          • -------- Once this time runs out we know the ability has ended: --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Ability_Duration[Ability_Caster_Id] Less than or equal to 0.01
            • Then - Actions
              • Unit - For Ability_Caster, Ability Avatar, Disable ability: False, Hide UI: False
              • Set VariableSet Ability_Duration[Ability_Caster_Id] = 0.00
              • -------- --------
              • -------- Only turn off the Loop trigger once ALL of the active effects have ended: --------
              • Unit Group - Remove Ability_Caster from Ability_Caster_Group.
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Number of units in Ability_Caster_Group) Equal to 0
                • Then - Actions
                  • Trigger - Turn off Loop <gen>
                • Else - Actions
            • Else - Actions
On side note using this:
Skip remaining actions
Is a useless line of code, which most of the people doesn't use at all.
This isn't true, Skip remaining actions is useful in many situations.

Also, polled waits are not precise and need to be synced with other players, so I wouldn't recommend it most of the time - but there's definitely situations where it's fine. Ideally, we would be using an 8.00 second Timer here that gets started/restarted, but those are unnecessarily awkward to use in GUI (without a system to help ease their use).
 

Attachments

  • Disable Ability Unit Indexing.w3m
    22.3 KB · Views: 4
Last edited:
Top