Trigger suddenly stoped working

Level 5
Joined
Feb 22, 2025
Messages
78
  • DR INI
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Hour of Death
    • Actions
      • Set VariableSet DR_Caster = (Triggering unit)
      • Special Effect - Create a special effect attached to the chest of DR_Caster using Abilities\Weapons\AvengerMissile\AvengerMissile.mdl
      • Set VariableSet HOD_effect = (Last created special effect)
      • Set VariableSet DR_Target = (Target unit of ability being cast)
      • Set VariableSet DR_Point = (Position of DR_Target)
      • If ((Level of Hour of Death for DR_Caster) Equal to 1) then do (Set VariableSet Loops_DR = 6) else do (Do nothing)
      • Animation - Change DR_Caster's vertex coloring to (10.00%, 10.00%, 10.00%) with 10.00% transparency
      • Selection - Remove DR_Caster from selection
      • Unit - Make DR_Caster Invulnerable
      • Unit - Pause DR_Caster
      • Unit - Move DR_Caster instantly to (Position of DR_Target)
      • Special Effect - Create a special effect at (Position of DR_Caster) using WindWeak2.mdx
      • Special Effect - Destroy (Last created special effect)
      • Custom script: call RemoveLocation(udg_DR_Point)
      • Animation - Play DR_Caster's attack animation
      • Special Effect - Create a special effect attached to the chest of DR_Caster using BlackCloudOfFog.mdx
      • Set VariableSet LaserAttachment = (Last created special effect)
      • Sound - Play MalthaelBaseVoicelineOne00 <gen> at 100.00% volume, located at (Position of DR_Caster) with Z offset 0.00
      • Sound - Play MalthaelHourofDeath <gen> at 100.00% volume, located at (Position of DR_Caster) with Z offset 0.00
      • Sound - Play Wraith_Strike <gen> at 100.00% volume, located at (Position of DR_Caster) with Z offset 0.00
      • Unit - Cause DR_Caster to damage DR_Target, dealing 1000.00 damage of attack type Hero and damage type Normal
      • Trigger - Turn on DR SE <gen>
      • Trigger - Turn on DR SE 2 <gen>
      • For each (Integer A) from 1 to Loops_DR, do (Actions)
        • Loop - Actions
          • Wait 0.40 seconds
          • Set VariableSet DRC_Current_loc = (Position of DR_Caster)
          • Set VariableSet DREG[1] = (Units within 600.00 of DRC_Current_loc matching ((((((Matching unit) is A structure) Not equal to True) and (((Matching unit) is alive) Equal to True)) and (((Matching unit) belongs to an enemy of (Owner of DR_Caster).) Equal to True)) and (((((Matching unit
          • Set VariableSet DREG[2] = (Random 1 units from DREG[1])
          • Custom script: call RemoveLocation(udg_DRC_Current_loc)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Number of units in DREG[1]) Greater than 0
            • Then - Actions
              • Unit Group - Pick every unit in DREG[2] and do (Actions)
                • Loop - Actions
                  • Set VariableSet DR_P = (Picked unit)
                  • Set VariableSet DR_PL = (Position of DR_P)
                  • Selection - Remove DR_Caster from selection
                  • Unit - Move DR_Caster instantly to DR_PL
                  • Custom script: call RemoveLocation(udg_DR_PL)
                  • Animation - Play DR_Caster's attack animation
                  • Sound - Play Wraith_Strike <gen> at 100.00% volume, located at (Position of DR_Caster) with Z offset 0.00
                  • Sound - Play SoulSiphon1 <gen> at 100.00% volume, located at (Position of DR_Caster) with Z offset 0.00
                  • Unit - Cause DR_Caster to damage DR_P, dealing (Random real number between 100.00 and 150.00) damage of attack type Normal and damage type Normal
                  • Trigger - Turn on DR SE <gen>
                  • Trigger - Turn on DR SE 2 <gen>
              • Custom script: call DestroyGroup(udg_DREG[1])
              • Custom script: call DestroyGroup(udg_DREG[2])
            • Else - Actions
              • Custom script: call DestroyGroup(udg_DREG[1])
              • Custom script: call DestroyGroup(udg_DREG[2])
              • Selection - Add DR_Caster to selection for (Owner of DR_Caster)
              • Special Effect - Destroy HOD_effect
              • Special Effect - Destroy LaserAttachment
              • Animation - Change DR_Caster's vertex coloring to (100.00%, 100.00%, 100.00%) with 0.00% transparency
              • Unit - Make DR_Caster Vulnerable
              • Unit - Unpause DR_Caster
      • Selection - Add DR_Caster to selection for (Owner of DR_Caster)
      • Animation - Change DR_Caster's vertex coloring to (100.00%, 100.00%, 100.00%) with 0.00% transparency
      • Special Effect - Destroy LaserAttachment
      • Special Effect - Destroy HOD_effect
      • Unit - Make DR_Caster Vulnerable
      • Unit - Unpause DR_Caster
---------------------------------------------------------------------------------------------------
Was working fine when I tested it weeks ago, but suddenly I was testing it again(using the ability ingame) and the loop with finding targets stops after one repetition where it should be 5 more. Double checked everything idk what's wrong.
 
Level 24
Joined
Feb 27, 2019
Messages
833
Integer A and B are global variables and can only be ran in one instance at a time. If another instance of either starts, the first ends. For custom integer variables it would lead to other problems and potentially crashes but Integer A and B are special. Change Integer A to a unique custom integer and itll probably be fine.
 
Last edited:
Level 45
Joined
Feb 27, 2007
Messages
5,578
Integer A and B are global variables and can only be ran in one instance at a time. If another instance of either starts, the first ends.
That's not strictly true. The current count, min, and max bounds are all global variables that are simply overwritten each time the loop syntax for that variable is encountered (custom loop integers hardcode their min/max bounds). The behavior of any nested/recursive/simultaneously-executed loops that use the same loop variable(s) is dependent on the way those loops' current/min/max have been altered. They could exit early, engage in an infinite recursive loop until thread crash, or cause one of the loops to be extended erroneously.

Do not ever put a wait in an Integer A or Integer B loop. If you need a wait in your loop: make a new integer variable, use that variable for looping in that application only (and nowhere else), and ensure that the loop cannot possibly run multiple times simultaneously.
 
Last edited:
Level 5
Joined
Feb 22, 2025
Messages
78
Integer A and B are global variables and can only be ran in one instance at a time. If another instance of either starts, the first ends. For custom integer variables it would lead to other problems and potentially crashes but Integer A and B are special. Change Integer A to a unique custom integer and itll probably be fine.
That's not strictly true. The current count, min, and max bounds are all global variables that are simply overwritten each time the loop syntax for that variable is encountered (custom loop integers hardcode their min/max bounds). The behavior of any nested/recursive/simultaneously-executed loops(that use the same loop variable(s) is dependent on the way those loops' current/min/max have been altered. They could exit early, engage in an infinite recursive loop until thread crash, or cause one of the loops to be extended erroneously.

Do not ever put a wait in an Integer A or Integer B loop. If you need a wait in your loop: make a new integer variable, use that variable for looping in that application only (and nowhere else), and ensure that the loop cannot possibly run multiple times simultaneously.
Changed it to local variable integer, now it's working, ty both! :ogre_datass:
 
Level 45
Joined
Feb 27, 2007
Messages
5,578
Changed it to local variable integer
Your wording is not clear. If you've done something like this I strongly recommend against it:
  • Actions
    • Custom script: local integer udg_NewIntVar = 0
    • For each (Integer NewIntVar) from min to max do (Actions)
      • Loop - Actions
        • -------- stuff --------
Why? If you attempt to reference that counter variable from any sub-function (GUI uses many of these under-the-hood without your knowledge, check out how trigger and if/then/else conditions are done) it will not return the value currently being used for the loop since the local version of that variable does not exist in the sub-function (it reads the global variable that is being shadowed but not used directly in the looping).
 
Last edited:
Level 5
Joined
Feb 22, 2025
Messages
78
Your wording is not clear. If you've done something like this I strongly recommend against it:
  • Actions
    • Custom script: local integer NewIntVar = 0
    • For each (Integer NewIntVar) from min to max do (Actions)
      • Loop - Actions
        • -------- stuff --------
Why? If you attempt to reference that counter variable from any sub-function (GUI uses many of these under-the-hood without your knowledge, check out how trigger and if/then/else conditions are done) it will not return the value currently being used for the loop since the local version of that variable does not exist in the sub-function (it reads the global variable that is being shadowed but not used directly in the looping).
Does this still mean that I used min and max?
If so how can i avoid it?
  • For each (Integer DR_Integer_VAR) from 1 to Loops_DR, do (Actions)
    • Loop - Actions
      • Wait 0.40 seconds
      • Set VariableSet DRC_Current_loc = (Position of DR_Caster)
      • Set VariableSet DREG[1] = (Units within 600.00 of DRC_Current_loc matching ((((((Matching unit) is A structure) Not equal to True) and (((Matching unit) is alive) Equal to True)) and (((Matching unit) belongs to an enemy of (Owner of DR_Caster).) Equal to True)) and (((((Matching unit
      • Set VariableSet DREG[2] = (Random 1 units from DREG[1])
      • Custom script: call RemoveLocation(udg_DRC_Current_loc)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of units in DREG[1]) Greater than 0
        • Then - Actions
          • Unit Group - Pick every unit in DREG[2] and do (Actions)
            • Loop - Actions
              • Set VariableSet DR_P = (Picked unit)
              • Set VariableSet DR_PL = (Position of DR_P)
              • Selection - Remove DR_Caster from selection
              • Unit - Move DR_Caster instantly to DR_PL
              • Custom script: call RemoveLocation(udg_DR_PL)
              • Animation - Play DR_Caster's attack animation
              • Sound - Play Wraith_Strike <gen> at 100.00% volume, located at (Position of DR_Caster) with Z offset 0.00
              • Sound - Play SoulSiphon1 <gen> at 100.00% volume, located at (Position of DR_Caster) with Z offset 0.00
              • Unit - Cause DR_Caster to damage DR_P, dealing (Random real number between 100.00 and 150.00) damage of attack type Normal and damage type Normal
              • Trigger - Turn on DR SE <gen>
              • Trigger - Turn on DR SE 2 <gen>
          • Custom script: call DestroyGroup(udg_DREG[1])
          • Custom script: call DestroyGroup(udg_DREG[2])
        • Else - Actions
          • Custom script: call DestroyGroup(udg_DREG[1])
          • Custom script: call DestroyGroup(udg_DREG[2])
          • Selection - Add DR_Caster to selection for (Owner of DR_Caster)
          • Special Effect - Destroy HOD_effect
          • Special Effect - Destroy LaserAttachment
          • Animation - Change DR_Caster's vertex coloring to (100.00%, 100.00%, 100.00%) with 0.00% transparency
          • Unit - Make DR_Caster Vulnerable
          • Unit - Unpause DR_Caster
 
Level 5
Joined
Feb 22, 2025
Messages
78
Do not ever put a wait in an Integer A or Integer B loop. If you need a wait in your loop: make a new integer variable, use that variable for looping in that application only (and nowhere else), and ensure that the loop cannot possibly run multiple times simultaneously.
I know of that rule but it was present in the original code of the spell that I was modifying so I left it like that xd… Can you just show me an example of how it is done
 
Level 24
Joined
Feb 27, 2019
Messages
833
That's not strictly true. The current count, min, and max bounds are all global variables that are simply overwritten each time the loop syntax for that variable is encountered (custom loop integers hardcode their min/max bounds). The behavior of any nested/recursive/simultaneously-executed loops(that use the same loop variable(s) is dependent on the way those loops' current/min/max have been altered. They could exit early, engage in an infinite recursive loop until thread crash, or cause one of the loops to be extended erroneously.
Hmm. Youre right, I didnt realize the difference between the functions is the min/max bounds.
 
Level 29
Joined
Sep 26, 2009
Messages
2,594
Does this still mean that I used min and max?
If so how can i avoid it?
  • For each (Integer DR_Integer_VAR) from 1 to Loops_DR, do (Actions)
    • Loop - Actions
      • Wait 0.40 seconds
      • Set VariableSet DRC_Current_loc = (Position of DR_Caster)
      • Set VariableSet DREG[1] = (Units within 600.00 of DRC_Current_loc matching ((((((Matching unit) is A structure) Not equal to True) and (((Matching unit) is alive) Equal to True)) and (((Matching unit) belongs to an enemy of (Owner of DR_Caster).) Equal to True)) and (((((Matching unit
      • Set VariableSet DREG[2] = (Random 1 units from DREG[1])
      • Custom script: call RemoveLocation(udg_DRC_Current_loc)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of units in DREG[1]) Greater than 0
        • Then - Actions
          • Unit Group - Pick every unit in DREG[2] and do (Actions)
            • Loop - Actions
              • Set VariableSet DR_P = (Picked unit)
              • Set VariableSet DR_PL = (Position of DR_P)
              • Selection - Remove DR_Caster from selection
              • Unit - Move DR_Caster instantly to DR_PL
              • Custom script: call RemoveLocation(udg_DR_PL)
              • Animation - Play DR_Caster's attack animation
              • Sound - Play Wraith_Strike <gen> at 100.00% volume, located at (Position of DR_Caster) with Z offset 0.00
              • Sound - Play SoulSiphon1 <gen> at 100.00% volume, located at (Position of DR_Caster) with Z offset 0.00
              • Unit - Cause DR_Caster to damage DR_P, dealing (Random real number between 100.00 and 150.00) damage of attack type Normal and damage type Normal
              • Trigger - Turn on DR SE <gen>
              • Trigger - Turn on DR SE 2 <gen>
          • Custom script: call DestroyGroup(udg_DREG[1])
          • Custom script: call DestroyGroup(udg_DREG[2])
        • Else - Actions
          • Custom script: call DestroyGroup(udg_DREG[1])
          • Custom script: call DestroyGroup(udg_DREG[2])
          • Selection - Add DR_Caster to selection for (Owner of DR_Caster)
          • Special Effect - Destroy HOD_effect
          • Special Effect - Destroy LaserAttachment
          • Animation - Change DR_Caster's vertex coloring to (100.00%, 100.00%, 100.00%) with 0.00% transparency
          • Unit - Make DR_Caster Vulnerable
          • Unit - Unpause DR_Caster
Not the answer you are looking for, but just wanted to point out that you don't have two create a unit group, then create a subgroup which contains only a single unit, then count the subgroup to check if there are any units and finally iterate over the subgroup.
You can basically do this instead to get random unit:
  • Set VariableSet DR_P = (Random unit from DREG[1])
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • DR_P Not equal to No unit
    • Then - Actions
      • //can deal damage to DR_P
    • Else - Actions
      • //there was no unit in DREG[1] group
 
Level 45
Joined
Feb 27, 2007
Messages
5,578
the.Axolotl said:
Does this still mean that I used min and max?
No, look at the trigger in my reply…. I am referring to this language:
Changed it to local variable integer

Can you just show me an example of how it is done
I gave a clear description of the limitations and what you must keep in mind to do something like this safely:
If you need a wait in your loop: make a new integer variable, use that variable for looping in that application only (and nowhere else), and ensure that the loop cannot possibly run multiple times simultaneously.
 
Top