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

Great Tornado v1.2 GUI/MUI

Description

Creates a Great Tornado, that sucks in and damages nearby enemies.

HOW TO IMPORT

1. Import dummy unit: Dummy_Tornado
2. Import 3 triggers: GT Main, GT Loop, GT End.
3. Set created units in GT MAIN:
  • Unit - Create 1 *UNIT* for (Owner of (Triggering unit)) at GT_TargetPoint[GT_CastCount] facing 0.00 degrees
to imported Dummy_Tornado
4. Set condition in GT Main and GT End to
  • (Ability being cast) Equal to Great Tornado
5.Have fun!

All settings in GT Main trigger

Triggers
  • GT Main
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Great Tornado
    • Actions
      • Trigger - Turn on GT Loop <gen>
      • -------- SETTINGS --------
      • -------- This is the damage per 1/20 of second. --------
      • Set GT_DamagePerSecond = 5.00
      • -------- This is the AOE of Tornado. NOTE: 400 AOE ~ 100% Tornado Size --------
      • Set GT_TornadoAOE = 400.00
      • -------- This is the flying height inc/dec per 1/20 of second --------
      • Set GT_FlyingRate = 30.00
      • -------- This is the spin speed per 1/20 of second --------
      • Set GT_SpinSpeed = 50.00
      • -------- This is the maximum height that Tornado can reach --------
      • Set GT_TornadoHeight = 600.00
      • -------- This is the unit filter --------
      • Set GT_AffectsFlyingUnits = False
      • -------- END --------
      • Set GT_CastCount = (GT_CastCount + 1)
      • Set GT_IsHeightMax[GT_CastCount] = False
      • Set GT_Caster[GT_CastCount] = (Triggering unit)
      • Set GT_TargetPoint[GT_CastCount] = (Target point of ability being cast)
      • Set GT_AbilityLevelDamage[GT_CastCount] = ((Real((Level of (Ability being cast) for (Triggering unit)))) x GT_DamagePerSecond)
      • Custom script: set udg_GT_TornadoGroup[udg_GT_CastCount] = CreateGroup()
      • Custom script: set udg_GT_DamageGroup[udg_GT_CastCount] = CreateGroup()
      • For each (Integer GT_LoopInteger) from 1 to 4, do (Actions)
        • Loop - Actions
          • Unit - Create 1 Dummy_Tornado for (Owner of (Triggering unit)) at GT_TargetPoint[GT_CastCount] facing ((Real(GT_LoopInteger)) x 90.00) degrees
          • Animation - Change (Last created unit)'s size to ((GT_TornadoAOE / 4.00)%, (GT_TornadoAOE / 4.00)%, (GT_TornadoAOE / 4.00)%) of its original size
          • Unit Group - Add (Last created unit) to GT_TornadoGroup[GT_CastCount]
  • GT Loop
    • Events
      • Time - Every 0.05 seconds of game time
    • Conditions
    • Actions
      • For each (Integer GT_LoopInteger) from 1 to GT_CastCount, do (Actions)
        • Loop - Actions
          • Unit Group - Pick every unit in GT_TornadoGroup[GT_LoopInteger] and do (Actions)
            • Loop - Actions
              • Unit - Make (Picked unit) face ((Facing of (Picked unit)) + GT_SpinSpeed) over 0.00 seconds
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • GT_IsHeightMax[GT_LoopInteger] Equal to False
                • Then - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Current flying height of (Picked unit)) Less than GT_TornadoHeight
                    • Then - Actions
                      • Animation - Change (Picked unit) flying height to ((Current flying height of (Picked unit)) + GT_FlyingRate) at 0.00
                    • Else - Actions
                      • Set GT_IsHeightMax[GT_LoopInteger] = True
                • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Current flying height of (Picked unit)) Greater than 100.00
                    • Then - Actions
                      • Animation - Change (Picked unit) flying height to ((Current flying height of (Picked unit)) - GT_FlyingRate) at 0.00
                    • Else - Actions
                      • Set GT_IsHeightMax[GT_LoopInteger] = False
              • Set GT_CurrentHeight = (Current flying height of (Picked unit))
              • Set GT_CurrentFace = (Facing of (Picked unit))
          • Custom script: set bj_wantDestroyGroup = true
          • Unit Group - Pick every unit in (Units within GT_TornadoAOE of GT_TargetPoint[GT_LoopInteger] matching ((((Matching unit) is A structure) Equal to False) and ((((Matching unit) is alive) Equal to True) and (((Matching unit) belongs to an enemy of (Owner of GT_Caster[GT_LoopInteger])) Equal and do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • ((Picked unit) is A flying unit) Equal to True
                  • GT_AffectsFlyingUnits Equal to False
                • Then - Actions
                • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • ((Picked unit) is in GT_DamageGroup[GT_LoopInteger]) Equal to False
                    • Then - Actions
                      • Unit Group - Add (Picked unit) to GT_DamageGroup[GT_LoopInteger]
                      • Unit - Turn collision for (Picked unit) Off
                      • Unit - Add Destroyer Form to (Picked unit)
                      • Unit - Remove Destroyer Form from (Picked unit)
                    • Else - Actions
                  • Set GT_LeakPoint[1] = (Position of (Picked unit))
                  • Set GT_LeakPoint[2] = (GT_LeakPoint[1] offset by ((Distance between GT_LeakPoint[1] and GT_TargetPoint[GT_LoopInteger]) / 50.00) towards (Angle from GT_LeakPoint[1] to GT_TargetPoint[GT_LoopInteger]) degrees)
                  • Unit - Move (Picked unit) instantly to GT_LeakPoint[2]
                  • Unit - Make (Picked unit) face GT_CurrentFace over 0.00 seconds
                  • Animation - Change (Picked unit) flying height to GT_CurrentHeight at 0.00
                  • Custom script: call RemoveLocation(udg_GT_LeakPoint[1])
                  • Custom script: call RemoveLocation(udg_GT_LeakPoint[2])
                  • Unit - Cause GT_Caster[GT_LoopInteger] to damage (Picked unit), dealing GT_AbilityLevelDamage[GT_LoopInteger] damage of attack type Spells and damage type Normal
  • GT End
    • Events
      • Unit - A unit Finishes casting an ability
      • Unit - A unit Stops casting an ability
    • Conditions
      • (Ability being cast) Equal to Great Tornado
    • Actions
      • For each (Integer GT_LoopInteger) from 1 to GT_CastCount, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Triggering unit) Equal to GT_Caster[GT_LoopInteger]
            • Then - Actions
              • Unit Group - Pick every unit in GT_TornadoGroup[GT_LoopInteger] and do (Actions)
                • Loop - Actions
                  • Animation - Change (Picked unit)'s animation speed to 300.00% of its original speed
                  • Unit - Kill (Picked unit)
              • Unit Group - Pick every unit in GT_DamageGroup[GT_LoopInteger] and do (Actions)
                • Loop - Actions
                  • Unit - Turn collision for (Picked unit) On
                  • Animation - Change (Picked unit) flying height to (Default flying height of (Picked unit)) at 1000.00
              • Custom script: call RemoveLocation(udg_GT_TargetPoint[udg_GT_LoopInteger])
              • Set GT_TargetPoint[GT_LoopInteger] = GT_TargetPoint[GT_CastCount]
              • Set GT_Caster[GT_LoopInteger] = GT_Caster[GT_CastCount]
              • Set GT_IsHeightMax[GT_LoopInteger] = GT_IsHeightMax[GT_CastCount]
              • Unit Group - Remove all units from GT_TornadoGroup[GT_LoopInteger]
              • Unit Group - Add all units of GT_TornadoGroup[GT_CastCount] to GT_TornadoGroup[GT_LoopInteger]
              • Unit Group - Remove all units from GT_DamageGroup[GT_LoopInteger]
              • Unit Group - Add all units of GT_DamageGroup[GT_CastCount] to GT_DamageGroup[GT_LoopInteger]
              • Custom script: call DestroyGroup(udg_GT_TornadoGroup[udg_GT_CastCount])
              • Custom script: call DestroyGroup(udg_GT_DamageGroup[udg_GT_CastCount])
              • Set GT_CastCount = (GT_CastCount - 1)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • GT_CastCount Equal to 0
                • Then - Actions
                  • Trigger - Turn off GT Loop <gen>
                • Else - Actions
            • Else - Actions
THE SPELL IS MUI AND DON'T NEED JNGP TO WORK
Changelogs:
v1.0
-Release
v1.1
-Replaced TornadoSize to TornadoAOE due to unnecessary calculations
-Replaced Classification to Boolean
-Added filter for flying units
-Added setting for Tornado Height
-Added spin effect to units that affected by Tornado
v1.2
-Some optimizations
-Fixed known bugs

Keywords:
Great Tornado, Cyclone, Druid, Wind, Dota
Contents

Great Tornado v1.2 (Map)

Reviews
22:11, 16th Jun 2010 Hanky: Leakless and MUI. Good job!

Moderator

M

Moderator

22:11, 16th Jun 2010
Hanky:
Leakless and MUI. Good job!
 
Level 8
Joined
Jun 11, 2009
Messages
121
baassee, i use classification to increase/decrease flying height of Tornado units, instead of timers and other ways. if tornado is ancient then trigger decreases it's height and if it is not an ancient then the height increases. Just look at the trigger completely.
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
I love how there are trees in the water; not to mention they are growing out of rocks.

refi said:
and flyiing units?!

Last time I checked tornadoes affected things in the sky along with things on the ground.

Review said:
Great Tornado

Very well put together spell. I really don't care about what units are allowed to be affected since that is so easy to change it's not even worth mentioning. From what I can see you've cleaned up all of your handles to an extent that is perfectly acceptable. I'm not sure whether or not you experienced bugs before uploading the spell, but I thought for sure I would catch you in a few places that I did not. Good job.

- I don't know what the standard on using groups in GUI is, but they always leak. Since you are constantly creating/destroying groups (for each spell cast) it may cause a lot of memory to be unnecessarily allocated. Again, I don't know the GUI standard for this.

- Since you are using custom script for creating/destroying your tornado/damage groups, you could easily import the "GroupUtils" library by Rising_Dusk and use "NewGroup()" and "ReleaseGroup()", respectively.

- You clean your unit groups very well, and transfer the units from each group appropriately. I thought I would catch you on this one, so good job :D

  • Set GT_CastCount = (GT_CastCount + 1)

- The above trigger can be moved down to the bottom of the trigger so that the arrays start at index 0 rather than 1. There is no reason you need the 0 index so you might as well. Remember that you can also start your loop in the "GT Loop" trigger at 0 instead of 1 (as well as your "GT End" trigger).

- Don't use unit classification to determine whether or not you need to increase/decrease the tornado height. You already have your parallel array setup so just use a boolean array. It would probably be more efficient since a boolean is evaluated faster than a function is, or two for that matter ("Picked unit" is also a function-call).

- You could add configuration values for the maximum/minimum height values.
 
Last edited:
Level 18
Joined
Jan 21, 2006
Messages
2,552
I was able to get the spell working fine using the 0 index. There is no reason you need to omit it from the list of available indexes. Also for the sake of keeping this native to GUI/non JNGP, I guess it shouldn't be much of a problem. I just noticed that you could be doing that.
 
Level 7
Joined
Dec 19, 2009
Messages
249
think this could be in a loop
  • Unit - Create 1 Dummy_Tornado for (Owner of (Triggering unit)) at GT_TargetPoint[GT_CastCount] facing 0.00 degrees
  • Unit Group - Add (Last created unit) to GT_TornadoGroup[GT_CastCount]
  • Unit - Create 1 Dummy_Tornado for (Owner of (Triggering unit)) at GT_TargetPoint[GT_CastCount] facing 90.00 degrees
  • Unit Group - Add (Last created unit) to GT_TornadoGroup[GT_CastCount]
  • Unit - Create 1 Dummy_Tornado for (Owner of (Triggering unit)) at GT_TargetPoint[GT_CastCount] facing 180.00 degrees
  • Unit Group - Add (Last created unit) to GT_TornadoGroup[GT_CastCount]
  • Unit - Create 1 Dummy_Tornado for (Owner of (Triggering unit)) at GT_TargetPoint[GT_CastCount] facing 270.00 degrees
  • Unit Group - Add (Last created unit) to GT_TornadoGroup[GT_CastCount]
 
Hmm I think
  • Unit - Move (Picked unit) instantly to GT_LeakPoint[2]
  • Unit - Make (Picked unit) face GT_CurrentFace over 0.00 seconds
Could be replaced with a 'move unit and face angle instantly' function which would look like this:

  • Unit - Move (Picked unit) instantly to GT_LeakPoint[2] Facing GT_CurrantFace over 0.00 seconds
If I am not mistaken, however If I am then I apologise as I have not been into the trigger editor for quite some time now =P
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
That really isn't necessary, it would probably be better separate, actually.

JASS:
function SetUnitPositionLocFacingBJ takes unit whichUnit, location loc, real facing returns nothing
    call SetUnitPositionLoc(whichUnit, loc)
    call SetUnitFacing(whichUnit, facing)
endfunction

This is what the "Move unit instantly facing angle" function looks like. As you can see, it is just a combination of the two. It may save him a function call, though.
 
Top