• 🏆 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!

[Trigger] Multiple GUI Damage Engine Instances Override Variables

Status
Not open for further replies.
Level 11
Joined
Aug 24, 2009
Messages
706
I'm using this GUI DDS for multiple instances to deal extra or reduced damage with various units. Problem is when the DDS event fires for both units who have some sort of DDS actions involved it leads to some screwy stuff like Temp Points being messed up. Overriding variables are the culprit I'm suspecting as I use the same variables for all GUI DDS actions in triggers with DDS events. How do you deal with multiple instances firing at the same time and overriding ur variables?
 

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
There are no things that run at the same time in warcraft.
Variables can be overriden if a trigger runs, before the first trigger has finished.

Example: When a unit takes damage, Damage_Event becomes equal to 1.
You have two triggers, that both have the event.
  • Events
    • Game - Damage_Event becomes Equal to 1.00
So they both would fire at the same time. However this is not possible in warcraft. The second trigger can only run, once the first trigger is finished/paused.

Using wait/timer (also 0 seconds duration) pauses the first trigger and the second trigger can run, so be careful when using this, as it will cause problems with triggers that basically run at the same time.

When something happens in trigger, an event can be fired because of this. This causes the trigger to stop, run the new trigger fired by the event and then continuing with the first trigger.

This means, that if you deal damage in one of the triggers, you will fire a new trigger, because of the damage event, that can potentially override variables. So be careful that none of the actions you do, fires a trigger, that may override variables.

P.S. Using JASS allows you to use local variables and you won't have to deal with these problems.;)
 
Level 11
Joined
Aug 24, 2009
Messages
706
Can u also use variables in GUI like this to avoid such a problem?
example2.gif
 

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
Yes, it's the same. However you should not use local unit "name global variable". You should just use "local unit u" for example. You should choose a short name, as it's less to write.
Local variables do not have the udg_ prefix. Apart from that declaration and nullifying looks good.
The only thing you should keep in mind is, that one trigger is often split up into several functions in JASS. Local variables only work within one function. The actions performed for unit groups for example are a different function than the main trigger.
 
Level 11
Joined
Aug 24, 2009
Messages
706
Oh I have many triggers that don't work cuz they overlap variables when using the DDS
Here are two that conflict, the Phoenix Warrior's dummy does not knockback units inside the shield cuz variables are overridden. I tried declaring globals into locals but they don't work for loops, pick all, for each x, if/then/else as they are separate functions and wc3 doesn't like that. How would you fix this without doing too much work as I have dozens of these kinds of triggers in my map that can conflict:
  • PW Distrupt
    • Events
      • Game - DamageModifierEvent becomes Equal to 1.00
    • Conditions
      • (Unit-type of DamageEventSource) Equal to Phoenix Warrior
      • IsDamageSpell Equal to False
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Point-value of DamageEventSource) Not equal to 99
          • (DamageEventTarget is A structure) Equal to False
          • (Level of CD1 for DamageEventSource) Equal to 0
          • (DamageEventTarget belongs to an enemy of (Owner of DamageEventSource)) Equal to True
        • Then - Actions
          • Set TA_AbilitySet = CD1
          • Set TA_DurationSet = 9.00
          • Set TA_UnitSet = DamageEventSource
          • Trigger - Run TA Event <gen> (ignoring conditions)
          • Special Effect - Create a special effect attached to the origin of DamageEventSource using ElfPhoenixWarriorFlameBurst.mdx
          • Special Effect - Destroy (Last created special effect)
          • Set TempPoint1 = (Position of DamageEventSource)
          • Set TempGroup = (Units within 164.00 of TempPoint1)
          • Unit Group - Pick every unit in TempGroup and do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • ((Picked unit) is alive) Equal to True
                  • ((Picked unit) has buff Stunned) Equal to False
                  • ((Picked unit) has buff Retreat ) Equal to False
                  • ((Unit-type of (Picked unit)) is Mechanical) Equal to False
                  • ((Unit-type of (Picked unit)) is A sapper) Equal to False
                  • ((Unit-type of (Picked unit)) is A flying unit) Equal to False
                  • ((Unit-type of (Picked unit)) is A structure) Equal to False
                  • (Level of KB Immune Dummy for (Picked unit)) Not equal to 1
                  • ((Picked unit) belongs to an enemy of (Owner of DamageEventSource)) Equal to True
                • Then - Actions
                  • Set TempPoint2 = (Position of (Picked unit))
                  • Unit - Create 1 Dummy Caster for (Owner of DamageEventSource) at TempPoint1 facing TempPoint2
                  • Unit - Add Knockback to (Last created unit)
                  • Unit - Order (Last created unit) to Human Mountain King - Storm Bolt (Picked unit)
                  • Unit - Add a 0.25 second Generic expiration timer to (Last created unit)
                  • Custom script: call RemoveLocation(udg_TempPoint2)
                • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • ((Picked unit) is alive) Equal to True
                  • ((Unit-type of (Picked unit)) is A flying unit) Equal to False
                  • ((Unit-type of (Picked unit)) is A structure) Equal to False
                  • ((Picked unit) belongs to an enemy of (Owner of DamageEventSource)) Equal to True
                • Then - Actions
                  • Set NextDamageType = DamageTypeSingleShot
                  • Unit - Cause DamageEventSource to damage (Picked unit), dealing 50.00 damage of attack type Spells and damage type Normal
                  • Trigger - Run ClearDamageEvent (checking conditions)
                • Else - Actions
          • Custom script: call RemoveLocation(udg_TempPoint1)
          • Custom script: call DestroyGroup(udg_TempGroup)
        • Else - Actions

  • Arcane Shield
    • Events
      • Game - DamageModifierEvent becomes Equal to 1.00
    • Conditions
    • Actions
      • Set TempGroup = (Units within 192.00 of (Position of DamageEventTarget) matching ((Unit-type of (Matching unit)) Equal to Arcane Shield))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of units in TempGroup) Greater than 0
        • Then - Actions
          • Set TempPoint1 = (Position of DamageEventSource)
          • Set TempReal1 = DamageEventAmount
          • Unit Group - Pick every unit in TempGroup and do (Actions)
            • Loop - Actions
              • Set TempPoint2 = (Position of (Picked unit))
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Unit-type of DamageEventTarget) Not equal to Arcane Shield
                  • (Distance between TempPoint2 and TempPoint1) Greater than 192.00
                  • (DamageEventSource is A ranged attacker) Equal to True
                • Then - Actions
                  • Unit - Cause DamageEventSource to damage (Picked unit), dealing TempReal1 damage of attack type Pierce and damage type Normal
                  • Set DamageEventAmount = (DamageEventAmount x 0.00)
                • Else - Actions
              • Custom script: call RemoveLocation(udg_TempPoint2)
          • Custom script: call RemoveLocation(udg_TempPoint1)
        • Else - Actions
      • Custom script: call DestroyGroup(udg_TempGroup)
 

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
I assume "unit damage target" fires another damage event trigger, that overrides your variables. Right now I don't have a good idea to fix this maybe someone knows something better.
Using FirstOfGroup-loops instead of unit groups would change it into onw function and you could use local variables. Would be some work though, as you could no longer use (Picked unit).
 
Level 11
Joined
Aug 24, 2009
Messages
706
Or I could just do this
TempPoint1[1] for my first DDS spell
TempPoint1[2] for my 2nd DDS spell
and so on rather than having the headache of redoing all trigs that use DDS (which is currently 50+) with custom script or jass
 

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
Depends. Can the trigger overwrite it's own variables? If "unit damage target" trigger the same trigger again it can overwrite variables of the first. Both triggers are the same trigger, so they both use TempPoint1[1].
If you do it like this you must be very careful, to always use the correct index. As long as a trigger does not overwrite itself this should work.

Overwirting can be because of a sequence of triggers.
trigger 1 (uses index 1) deals damage
trigger 2 fires because of this (uses index 2 so no overwriting) also deals damage
trigger 1 fires because of this (uses index 1 so overwrites first instance of trigger 1)
 
Status
Not open for further replies.
Top