Issue with a looping trigger

I have this ability that can be cast by multiple buildings. The ability works fine when cast by the first unit with custom value of 0 but units don't seem to pick up and added to the correct group.
Can anyone help with why this loop doesn't function past the first iteration?
  • MC Periodic
    • Events
      • Time - Every 0.50 seconds of game time
    • Conditions
    • Actions
      • For each (Integer ConduitLoop) from 0 to 100, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Mana of ConduitCaster[ConduitLoop]) Less than 5.00
            • Then - Actions
              • Unit - Order ConduitCaster[ConduitLoop] to Stop.
            • Else - Actions
              • Unit - Set mana of ConduitCaster[ConduitLoop] to ((Mana of ConduitCaster[ConduitLoop]) - 3.00)
              • Unit Group - Pick every unit in (Units within ConduitAoE of ConduitPoint[ConduitLoop] matching ((Owner of (Matching unit)) Equal to Player 1 (Red)).) and do (Actions)
                • Loop - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • And - All (Conditions) are true
                        • Conditions
                          • (Mana of (Picked unit)) Less than (Max mana of (Picked unit))
                          • ((Picked unit) is alive) Equal to True
                    • Then - Actions
                      • Unit Group - Add (Picked unit) to AcaneConduit_Target[ConduitLoop]
                    • Else - Actions
              • Unit Group - Pick every unit in AcaneConduit_Target[ConduitLoop] and do (Actions)
                • Loop - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Percentage mana of (Picked unit)) Equal to 100.00
                      • ((Picked unit) is alive) Equal to False
                      • (Distance between (Position of (Picked unit)) and ConduitPoint[ConduitLoop]) Greater than 250.00
                    • Then - Actions
                      • Unit Group - Remove (Picked unit) from AcaneConduit_Target[ConduitLoop].
                    • Else - Actions
                      • Set VariableSet Conduit_Count[ConduitLoop] = (Number of units in AcaneConduit_Target[ConduitLoop])
                      • Unit - Set mana of (Picked unit) to ((Mana of (Picked unit)) + (2.00 + (1.00 x (Real((Current research level of Greater Conduit for Player 1 (Red)))))))
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • Conduit_Count[ConduitLoop] Greater than 0
                • Then - Actions
                  • Unit - Set mana of ConduitCaster[ConduitLoop] to ((Mana of ConduitCaster[ConduitLoop]) - (0.00 + (1.00 x (Real(Conduit_Count[ConduitLoop])))))
                • Else - Actions
                  • Do nothing
 
Last edited:
Using a For Loop seems odd to me. Do you always have 100 ConduitCasters? I assume that would be dynamic, in which case you want to use a Unit Group to keep track of the casters, adding and removing them as needed.

But focusing on your main issue, I assume that the problem is your Unit Group array isn't initialized. Unit Groups need extra care since they're a bit more complicated than say an Integer array. A nice solution is to do something like this:
  • Actions
    • Unit - Create 1 Conduit...
    • Set VariableSet Conduit_Caster = (Last created unit)
    • Set VariableSet Conduit_ID = (Custom value of Conduit_Caster)
    • Unit Group - Add Conduit_Caster to Conduit_Casters
    • -------- Destroy any existing group (just in case) and create a new one: --------
    • Custom script: if udg_Conduit_Targets[udg_Conduit_ID] != null then
    • Custom script: call DestroyGroup( udg_Conduit_Targets[udg_Conduit_ID] )
    • Custom script: endif
    • Custom script: set udg_Conduit_Targets[udg_Conduit_ID] = CreateGroup()
Note that I've added my own variables/renamed things for clarity and I introduced the Unit Group for tracking the Conduit casters. You would likely want to edit this to get rid of the created unit and set Conduit_Caster = (Casting unit). Or whatever Event Response makes the most sense.

Also, I hope that you're using a Unit Indexer and not manually setting Custom Value yourself. It's an objectively better way of doing this, as it's the same design pattern without any of the limitations.

Here's the full trigger with some memory leak fixes and a Unit Group for the Casters:
  • MC Periodic
    • Events
      • Time - Every 0.50 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in Conduit_Casters and do (Actions)
        • Loop - Actions
          • Set VariableSet Conduit_Caster = (Picked unit)
          • Set VariableSet Conduit_ID = (Custom value of Conduit_Caster)
          • -------- --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Mana of Conduit_Caster) Less than 5.00
            • Then - Actions
              • Unit - Order Conduit_Caster to Stop.
            • Else - Actions
              • Unit - Set mana of Conduit_Caster to ((Mana of ConduitCaster) - 3.00)
              • -------- --------
              • Custom script: set bj_wantDestroyGroup = true
              • Unit Group - Pick every unit in (Units within Conduit_AoE of Conduit_Point[Conduit_ID] matching ((Owner of (Matching unit)) Equal to Player 1 (Red)).) and do (Actions)
                • Loop - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Mana of (Picked unit)) Less than (Max mana of (Picked unit))
                      • ((Picked unit) is alive) Equal to True
                    • Then - Actions
                      • Unit Group - Add (Picked unit) to Conduit_Targets[Conduit_ID]
                    • Else - Actions
              • -------- --------
              • Set VariableSet TempReal = (1.00 x (Real((Current research level of Greater Conduit for Player 1 (Red))))
              • Unit Group - Pick every unit in Conduit_Targets[Conduit_ID] and do (Actions)
                • Loop - Actions
                  • Set VariableSet TempPoint = (Position of (Picked unit))
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Percentage mana of (Picked unit)) Equal to 100.00
                      • ((Picked unit) is alive) Equal to False
                      • (Distance between TempPoint and Conduit_Point[Conduit_ID]) Greater than 250.00
                    • Then - Actions
                      • Unit Group - Remove (Picked unit) from Conduit_Targets[Conduit_ID].
                    • Else - Actions
                      • Unit - Set mana of (Picked unit) to ((Mana of (Picked unit)) + (2.00 + (TempReal)))
                  • Custom script: call RemoveLocation( udg_TempPoint )
              • -------- --------
              • Set VariableSet Conduit_Count[Conduit_ID] = (Number of units in Conduit_Targets[Conduit_ID])
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • Conduit_Count[Conduit_ID] Greater than 0
                • Then - Actions
                  • Unit - Set mana of Conduit_Caster to ((Mana of Conduit_Caster) - (1.00 x (Real(Conduit_Count[Conduit_ID]))))
                • Else - Actions

Another thing that seems off to me, I think you meant to use an "Or - Multiple conditions" here:
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • (Percentage mana of (Picked unit)) Equal to 100.00
      • ((Picked unit) is alive) Equal to False
      • (Distance between TempPoint and Conduit_Point[Conduit_ID]) Greater than 250.00
    • Then - Actions
      • Unit Group - Remove (Picked unit) from Conduit_Targets[Conduit_ID].
    • Else - Actions
      • Unit - Set mana of (Picked unit) to ((Mana of (Picked unit)) + (2.00 + (TempReal)))
I'd assume that the objective is to Remove anything that is: Full mana OR Dead OR Too far away. In which case you want to use this:
  • If - Conditions
    • Or - Any (Conditions) are true
      • Conditions
Note that the default behavior of Conditions is that they ALL have to be True, so the use of "And" is rarely necessary.
 
Last edited:
Hi,

Thanks for your response, it was very helpful.


You mentioned the Indexer. I haven't used it for this as this is the only unit I need to add a custom value to and there is a max of 4. Is it something I should impliment anyway?

Thanks,
Vort
Hey, a Unit Indexer is very lightweight and extremely useful, so I'd definitely recommend it. You can always delete it later if for some reason you don't want it. Just note that once you have a Unit Indexer in your map you should never be using this Action yourself:
  • Unit - Set custom value of (Some unit) to X
This is the job of the Unit Indexer, it does this automatically for every single unit in your map whether they be pre-placed, trained, sold, summoned, etc.

Here's a simple example of how useful it can be:
  • Events
    • Unit - A unit Begins channeling an ability
  • Conditions
    • (Ability being cast) Equal to Blizzard
  • Actions
    • Special Effect - Create a special effect attached to the overhead of (Triggering unit) using Abilities\Spells\Orc\Bloodlust\BloodlustTarget.mdl
    • Set VariableSet SFX_Array[(Custom value of (Triggering unit))] = (Last created special effect)
  • Events
    • Unit - A unit Stops casting an ability
  • Conditions
    • (Ability being cast) Equal to Blizzard
  • Actions
    • Special Effect - Destroy SFX_Array[(Custom value of (Triggering unit))]
The result will be a Bloodlust art effect over the head of the Archmage while he channels the Blizzard ability. The key takeaway being that this works for any number of units at the same time. This is because they all have their own unique Custom Value, so they each keep track of their own unique Special Effect.

You can use this design pattern with any Array variable type, so that means you can attach any kind of data to your Units. This could range from custom stats, ie: Ability Power, Luck, Charisma, etc. Or tracking an Item they're carrying. Or tracking how much Time has Elapsed since they started "doing something". The list goes on.
 
Last edited:
Back
Top