[Trigger] Optimizing my trigger

Level 3
Joined
Jul 23, 2019
Messages
12
Hi, I was wondering if there was a way to optimize my trigger. Basically what I'm trying to achieve is a blizzard spell that does periodic damage, whilst slowing the enemies inside the aoe. I feel like there's a better method to the dummies casting frost nova and cleaning them but I can't think of any. Any GUI methods would be greatly appreciated as I have 0 clue on how to use JASS. Cheers
  • Blizzard
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Blizzard
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
        • Then - Actions
          • Set VariableSet Emilia = (Triggering unit)
          • Set VariableSet EmiliaINT = (Real((Intelligence of Emilia (Include bonuses))))
          • Unit - Create 1 EmiliaBlizzardDummy for (Owner of Emilia) at (Target point of ability being cast) facing Default building facing degrees
          • Set VariableSet BlizzardDummy = (Last created unit)
          • Unit - Add a 15.00 second Generic expiration timer to BlizzardDummy
          • Set VariableSet BlizzardCastPoint = (Units within 600.00 of (Position of BlizzardDummy).)
          • Trigger - Turn on BlizzardDMG <gen>
          • Wait 15.00 seconds
          • Trigger - Turn off BlizzardDMG <gen>
          • Custom script: call DestroyGroup(udg_BlizzardCastPoint)
        • Else - Actions
  • BlizzardDMG
    • Events
      • Time - Every 0.25 seconds of game time
    • Conditions
    • Actions
      • Set VariableSet BlizzardCastPoint = (Units within 600.00 of (Position of BlizzardDummy).)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
        • Then - Actions
          • Unit Group - Pick every unit in BlizzardCastPoint and do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • ((Picked unit) belongs to an enemy of (Owner of Emilia).) Equal to True
                  • ((Picked unit) is invulnerable) Equal to False
                  • ((Picked unit) is A structure) Equal to False
                • Then - Actions
                  • Unit - Create 1 SlowNovaDummy for (Owner of Emilia) at (Position of BlizzardDummy) facing Default building facing degrees
                  • Set VariableSet BlizzardDummy = (Last created unit)
                  • Unit - Add a 0.26 second Generic expiration timer to BlizzardDummy
                  • Unit - Add DummySlowFrostNova to BlizzardDummy
                  • Unit - Cause Emilia to damage (Picked unit), dealing (EmiliaINT / 5.00) damage of attack type Spells and damage type Normal
                  • Unit - Order BlizzardDummy to Undead Lich - Frost Nova (Picked unit)
                  • Custom script: call DestroyGroup(udg_BlizzardCastPoint)
                • Else - Actions
                  • Do nothing
        • Else - Actions
  • cleanup
    • Events
      • Unit - A unit Dies
    • Conditions
      • (Unit-type of (Dying unit)) Equal to SlowNovaDummy
    • Actions
      • Unit - Remove (Dying unit) from the game
 
Level 45
Joined
Feb 27, 2007
Messages
5,578
Basically what I'm trying to achieve is a blizzard spell that does periodic damage
Call me dumb but isn't blizzard already a spell that does periodic damage? If you don't want the caster to channel it you can just dummy-cast for the player on the correct location when the 'fake' ability is cast. Slowing has a few options depending on if you want to slow units inside only while they're inside, for a duration that will linger even if they leave, only on cast to the units that are there, or something else. The easiest solution would be a locusted dummy unit with a modified Tornado Slow Aura and an appropriate expiration timer; that would significantly reduce how much code you need.
  • Do Nothing is pointless and should never be used. You can have an empty else block. An empty if-block was at one time problematic but usually you can just invert your condition. That function just exists for the select few GUI lines where you would be required to input an action as a sub-menu like the single-line if/then/else.
  • This spell would not work for multiple units simultaneously because of its use of waits and global variables. A helpful framework for coding around this is the method detailed in this tutorial: Visualize: Dynamic Indexing Learn it well and you will use it very often.
 
Level 3
Joined
Jul 23, 2019
Messages
12
Call me dumb but isn't blizzard already a spell that does periodic damage? If you don't want the caster to channel it you can just dummy-cast for the player on the correct location when the 'fake' ability is cast. Slowing has a few options depending on if you want to slow units inside only while they're inside, for a duration that will linger even if they leave, only on cast to the units that are there, or something else. The easiest solution would be a locusted dummy unit with a modified Tornado Slow Aura and an appropriate expiration timer; that would significantly reduce how much code you need.
  • Do Nothing is pointless and should never be used. You can have an empty else block. An empty if-block was at one time problematic but usually you can just invert your condition. That function just exists for the select few GUI lines where you would be required to input an action as a sub-menu like the single-line if/then/else.
  • This spell would not work for multiple units simultaneously because of its use of waits and global variables. A helpful framework for coding around this is the method detailed in this tutorial: Visualize: Dynamic Indexing Learn it well and you will use it very often.
Thanks for your suggestion, I'll try tornado slow instead. I also should have been more specific, I'm not using the traditional blizzard spell, but a "trigger" blizzard spell. I found a SFX of a snow storm blizzard hence the periodic damage trigger
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,285
Wait action is not time accurate. You need to use a timer or periodic counter instead.

For accurate AoE damage (factors in unit collision) you need to pick all units in a radius of AoE + maximum collision size and then use the unit in range of point function, which factors in unit collision size, to filter the units.

Generally how such a spell is implemented is with an instance system, where each cast creates 1 instance. An instance can be thought of as an index into a set of arrays that contain instance data. The periodic trigger iterates through all instances, does damage, decrements a counter and removes the instance once the counter is 0 (expired). When no instances are running, the periodic trigger is turned off, and like wise the periodic trigger is turned on when an instance is created.

If channelled, like real Blizzard, another trigger is needed to handle channelling being interrupted. This likely requires being able to find one or more instances from a unit efficiently.
 
Level 13
Joined
Sep 25, 2013
Messages
717
Hi, I was wondering if there was a way to optimize my trigger. Basically what I'm trying to achieve is a blizzard spell that does periodic damage, whilst slowing the enemies inside the aoe. I feel like there's a better method to the dummies casting frost nova and cleaning them but I can't think of any. Any GUI methods would be greatly appreciated as I have 0 clue on how to use JASS. Cheers
  • Blizzard
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Blizzard
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
        • Then - Actions
          • Set VariableSet Emilia = (Triggering unit)
          • Set VariableSet EmiliaINT = (Real((Intelligence of Emilia (Include bonuses))))
          • Unit - Create 1 EmiliaBlizzardDummy for (Owner of Emilia) at (Target point of ability being cast) facing Default building facing degrees
          • Set VariableSet BlizzardDummy = (Last created unit)
          • Unit - Add a 15.00 second Generic expiration timer to BlizzardDummy
          • Set VariableSet BlizzardCastPoint = (Units within 600.00 of (Position of BlizzardDummy).)
          • Trigger - Turn on BlizzardDMG <gen>
          • Wait 15.00 seconds
          • Trigger - Turn off BlizzardDMG <gen>
          • Custom script: call DestroyGroup(udg_BlizzardCastPoint)
        • Else - Actions
  • BlizzardDMG
    • Events
      • Time - Every 0.25 seconds of game time
    • Conditions
    • Actions
      • Set VariableSet BlizzardCastPoint = (Units within 600.00 of (Position of BlizzardDummy).)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
        • Then - Actions
          • Unit Group - Pick every unit in BlizzardCastPoint and do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • ((Picked unit) belongs to an enemy of (Owner of Emilia).) Equal to True
                  • ((Picked unit) is invulnerable) Equal to False
                  • ((Picked unit) is A structure) Equal to False
                • Then - Actions
                  • Unit - Create 1 SlowNovaDummy for (Owner of Emilia) at (Position of BlizzardDummy) facing Default building facing degrees
                  • Set VariableSet BlizzardDummy = (Last created unit)
                  • Unit - Add a 0.26 second Generic expiration timer to BlizzardDummy
                  • Unit - Add DummySlowFrostNova to BlizzardDummy
                  • Unit - Cause Emilia to damage (Picked unit), dealing (EmiliaINT / 5.00) damage of attack type Spells and damage type Normal
                  • Unit - Order BlizzardDummy to Undead Lich - Frost Nova (Picked unit)
                  • Custom script: call DestroyGroup(udg_BlizzardCastPoint)
                • Else - Actions
                  • Do nothing
        • Else - Actions
  • cleanup
    • Events
      • Unit - A unit Dies
    • Conditions
      • (Unit-type of (Dying unit)) Equal to SlowNovaDummy
    • Actions
      • Unit - Remove (Dying unit) from the game
If you post your map I'll try and fix them trigger up for you! Post it to the old pastebin and send the link tither
https://www.hiveworkshop.com/pastebin/add
 
Level 3
Joined
Jul 23, 2019
Messages
12
Wait action is not time accurate. You need to use a timer or periodic counter instead.

For accurate AoE damage (factors in unit collision) you need to pick all units in a radius of AoE + maximum collision size and then use the unit in range of point function, which factors in unit collision size, to filter the units.

Generally how such a spell is implemented is with an instance system, where each cast creates 1 instance. An instance can be thought of as an index into a set of arrays that contain instance data. The periodic trigger iterates through all instances, does damage, decrements a counter and removes the instance once the counter is 0 (expired). When no instances are running, the periodic trigger is turned off, and like wise the periodic trigger is turned on when an instance is created.

If channelled, like real Blizzard, another trigger is needed to handle channelling being interrupted. This likely requires being able to find one or more instances from a unit efficiently.
Thank you for the tips! I recently learned how to do the set variable (var) = (var) + 1 technique for instances, I understand how they work now!

For accurate AoE damage (factors in unit collision) you need to pick all units in a radius of AoE + maximum collision size and then use the unit in range of point function, which factors in unit collision size, to filter the units.
Sorry, do you mind elaborating more on this?

If you post your map I'll try and fix them trigger up for you! Post it to the old pastebin and send the link tither
https://www.hiveworkshop.com/pastebin/add
Hi Gumber, I'd actually prefer if no one does it for me ^^ I want to learn how to create triggers with only tips if possible. I appreciate the offer!
 
Level 45
Joined
Feb 27, 2007
Messages
5,578
Sorry, do you mind elaborating more on this?
Spell cast aoe indicators and all native spells that use them affect units whose collision size circle intersects with the cast AoE, even if the unit's origin is outside the AoE (which means the unit is literally further away than the radius of the ability). Doing a simple check of "is distance from center to unit more than RADIUS?" will fail to properly count such units as valid targets.

The solution is to add 1/2 of the maximum collision size in your map to the search radius, which will grab any units that the above check would have failed to find (and possibly a few more it shouldn't return as valid targets). (If you don't understand why, draw the overlapping circles on a piece of paper.) Then you do a check with the native function IsUnitInRange takes unit whichUnit, unit otherUnit, real distance returns boolean on each found unit. This check does respect collision size but it only works on units one at a time. Units too far outside will fail this check, but the bigger circle was to grab all possible units without knowing their collision size and without having to search the whole map to check all units.
 
Top