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

Serpent Ward and Tornado Can't be cast on deep water or cliff

Level 11
Joined
Sep 11, 2013
Messages
324
Hi there!
It is possible to use this 2 spells to spawn units on deep water and on cliff?
[This spells has cast range and i like that]
I wanted for "Tornado spell" to spawn a (flying) tornado on ground or on deep water or on cliff (player choice), but the spell can be cast only on ground..
I wanted for "Serpent Ward spell" to spawn an unmovable custom unit (i think hover) on ground or on deep water or on cliff (player choice), but the spell can be cast only on ground..

Edit: I forget about shockwave.. it work to be casted on ground and deep water, but don't work on cliff edge, it is possible to make it work even on the edge?
Thanks for the help! :peasant-waving:
 
Last edited:

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,537
You can always use triggers to create the units yourself:
  • Unit - Create 1 Serpent Ward at (Target point of ability being cast)
Do this in response to the Hero casting the ability:
  • Events
    • Unit - A unit Starts the effect of an ability
  • Conditions
    • (Ability being cast) Equal to YourCustomSerpentWardAbility
  • Actions
    • Unit - Create 1 Serpent Ward at (Target point of ability being cast) for (Owner of (Triggering unit))
So you would cast a "fake" ability that can target any point, which then runs a trigger that has the effects you want.
 
Last edited:
Level 11
Joined
Sep 11, 2013
Messages
324
You can always use triggers to create the units yourself:
  • Unit - Create 1 Serpent Ward at (Target point of ability being cast)
Do this in response to the Hero casting the ability:
  • Events
    • Unit - A unit Starts the effect of an ability
  • Conditions
    • (Ability being cast) Equal to YourCustomSerpentWardAbility
  • Actions
    • Unit - Create 1 Serpent Ward at (Target point of ability being cast) for (Owner of (Triggering unit))
So you would cast a "fake" ability that can target any point, which then runs a trigger that has the effects you want.
What if my Tornado is a level 3 ability with different tornado damage / duration at each level.
How can i spawn different tornado at each level?

Also, where is this "
unit.gif
Unit - Create 1 Serpent Ward at (Target point of ability being cast) for (Owner of (Triggering unit))"

Edit: Is this trigger good?
  • Tornado Channel
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Tornado - Channel - AGI
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Level of Tornado - Channel - AGI for (Triggering unit)) Equal to 1
        • Then - Actions
          • Game - Display to (All players) the text: Merge lvl 1
          • Unit - Create 1 Tornado 1 for (Owner of (Triggering unit)) at (Target point of ability being cast) facing (Position of (Triggering unit))
          • Unit - Add a 75.00 second Generic expiration timer to (Last created unit)
        • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Level of Tornado - Channel - AGI for (Triggering unit)) Equal to 2
            • Then - Actions
              • Game - Display to (All players) the text: Merge lvl 2
              • Unit - Create 1 Tornado 2 for (Owner of (Triggering unit)) at (Target point of ability being cast) facing (Position of (Triggering unit))
              • Unit - Add a 85.00 second Generic expiration timer to (Last created unit)
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Level of Tornado - Channel - AGI for (Triggering unit)) Equal to 3
                • Then - Actions
                  • Game - Display to (All players) the text: Merge lvl 3
                  • Unit - Create 1 Tornado 3 for (Owner of (Triggering unit)) at (Target point of ability being cast) facing (Position of (Triggering unit))
                  • Unit - Add a 95.00 second Generic expiration timer to (Last created unit)
                • Else - Actions
 
Last edited:
Level 19
Joined
Feb 27, 2019
Messages
590
That trigger works fine. You can make a couple of small adjustments. It may not be applicable here but still, summoned units usually have a specific classification which makes it so they can for example be purged and stolen by Spellbreakers. You can add this classification via triggers.
  • Unit - Add classification of Summoned to (Last created unit)
You can reduce the length of your code by adding the classification and the generic expiration timer under the if then else block. In this case the duration can be set by a formula but it may not always be applicable.
  • Unit - Add a (65.00 + (10.00 x (Real((Level of Tornado for (Triggering unit))) second Generic expiration timer to (Last created unit)

Here is another example of how you could set up your spell. Its a different approach that can be more beneficial at times.
  • Tornado Init
    • Events
      • Time - Elapsed game time is 0.50 seconds
    • Conditions
    • Actions
      • Set VariableSet TornadoType[1] = Quilbeast (Level 1)
      • Set VariableSet TornadoType[2] = Dire Quilbeast (Level 2)
      • Set VariableSet TornadoType[3] = Raging Quilbeast (Level 3)
      • Set VariableSet TornadoDuration[1] = 76.00
      • Set VariableSet TornadoDuration[2] = 84.00
      • Set VariableSet TornadoDuration[3] = 109.00
  • Tornado Cast
    • Events
    • Conditions
    • Actions
      • Set VariableSet TornadoLevel = (Level of Tornado for (Triggering unit))
      • Unit - Create 1 TornadoType[TornadoLevel] for (Triggering player) at (Target point of ability being cast) facing (Position of (Triggering unit))
      • Unit - Add a TornadoDuration[TornadoLevel] second Generic expiration timer to (Last created unit)
      • Unit - Add classification of Summoned to (Last created unit)
You are leaking some locations. Locations need to be removed after use and the only way to do that is to set them to variables prior to use.
  • Tornado Cast
    • Events
    • Conditions
    • Actions
      • Set VariableSet TempPoint[0] = (Target point of ability being cast)
      • Set VariableSet TempPoint[1] = (Position of (Triggering unit))
      • Unit - Create 1 Unit for (Triggering player) at TempPoint[0] facing TempPoint[1]
      • Custom script: call RemoveLocation(udg_TempPoint[0])
      • Custom script: call RemoveLocation(udg_TempPoint[1])
 
Level 11
Joined
Sep 11, 2013
Messages
324
Thanks for the explanations!
base.gif
Tornado Cast
  • join.gif
    events.gif
    Events
  • join.gif
    cond.gif
    Conditions
  • joinbottomminus.gif
    actions.gif
    Actions
    • empty.gif
      join.gif
      set.gif
      Set VariableSet TempPoint[0] = (Target point of ability being cast)
    • empty.gif
      join.gif
      set.gif
      Set VariableSet TempPoint[1] = (Position of (Triggering unit))
    • empty.gif
      join.gif
      unit.gif
      Unit - Create 1 Unit for (Triggering player) at TempPoint[0] facing TempPoint[1]
    • empty.gif
      join.gif
      page.gif
      Custom script: call RemoveLocation(udg_TempPoint[0])
    • empty.gif
      joinbottom.gif
      page.gif
      Custom script: call RemoveLocation(udg_TempPoint[1])
  • Tornado Channel
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Tornado - Channel - AGI
    • Actions
      • Set VariableSet TempTornadoPoint0 = (Target point of ability being cast)
      • Set VariableSet TempTornadoPoint1 = (Position of (Triggering unit))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Level of Tornado - Channel - AGI for (Triggering unit)) Equal to 1
        • Then - Actions
          • Game - Display to (All players) the text: Merge lvl 1
          • Unit - Create 1 Tornado 1 for (Triggering player) at TempTornadoPoint0 facing TempTornadoPoint1
          • Unit - Add a 75.00 second Generic expiration timer to (Last created unit)
        • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Level of Tornado - Channel - AGI for (Triggering unit)) Equal to 2
            • Then - Actions
              • Game - Display to (All players) the text: Merge lvl 2
              • Unit - Create 1 Tornado 2 for (Triggering player) at TempTornadoPoint0 facing TempTornadoPoint1
              • Unit - Add a 85.00 second Generic expiration timer to (Last created unit)
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Level of Tornado - Channel - AGI for (Triggering unit)) Equal to 3
                • Then - Actions
                  • Game - Display to (All players) the text: Merge lvl 3
                  • Unit - Create 1 Tornado 3 for (Triggering player) at TempTornadoPoint0 facing TempTornadoPoint1
                  • Unit - Add a 95.00 second Generic expiration timer to (Last created unit)
                • Else - Actions
      • Custom script: call RemoveLocation(udg_TempTornadoPoint0)
      • Custom script: call RemoveLocation(udg_TempTornadoPoint1)
Is this good?
 
Level 11
Joined
Sep 11, 2013
Messages
324
Yep, thats good
I found a new problem.. If i create the Tornado with this trigger, the Tornado do not have sound(only when expire the death sound will appear).
With the old spell, my Tornado had sound(wind).. It is possible to fix this somehow?

Edit:
  • Untitled Trigger 001
    • Events
      • Player - Player 1 (Red) types a chat message containing <Empty String> as A substring
    • Conditions
    • Actions
      • Unit - Create 1 Tornado for (Triggering player) at (Center of (Playable map area)) facing (Center of (Playable map area))
I found that problem even in a basic trigger.. is this a bug?
 
Last edited:
Level 19
Joined
Feb 27, 2019
Messages
590
Apparently the sound comes from the buff Tornado (Timed Life). When setting the generic expiration timer its possible to modify one of the existing presets such as Water Elemental to the same values as Tornado (Timed Life) but sadly its not possible to use another buff id outside of those presets within that function even when using a custom script.

You could create a sound with custom script and use a basic dynamic index to keep track of the Tornados and their respective sounds. Can you see how a dynamic index works with these triggers?
  • Tornado Index
    • Events
    • Conditions
    • Actions
      • Set VariableSet TornadoMax = (TornadoMax + 1)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • TornadoMax Equal to 1
        • Then - Actions
          • Trigger - Turn on Tornado Deindex <gen>
        • Else - Actions
      • Unit - Create 1 Tornado for (Triggering player) at (Center of (Playable map area)) facing (Center of (Playable map area))
      • Set VariableSet TornadoUnit[TornadoMax] = (Last created unit)
      • Custom script: set udg_TornadoSound[udg_TornadoMax] = CreateSound("Abilities/Spells/Other/Tornado/TornadoLoop", true, true, false, 1, 1, "SpellsEAX")
      • Custom script: call AttachSoundToUnit(udg_TornadoSound[udg_TornadoMax], udg_TornadoUnit[udg_TornadoMax])
      • Custom script: call StartSound(udg_TornadoSound[udg_TornadoMax])
  • Tornado Deindex
    • Events
      • Unit - A unit Dies
    • Conditions
      • (Unit-type of (Triggering unit)) Equal to Tornado
    • Actions
      • For each (Integer TornadoLoop) from 1 to TornadoMax, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Triggering unit) Equal to TornadoUnit[TornadoLoop]
            • Then - Actions
              • Custom script: call StopSound(udg_TornadoSound[udg_TornadoLoop], true, false)
              • Sound - Destroy TornadoSound[TornadoMax]
              • Set VariableSet TornadoUnit[TornadoLoop] = TornadoUnit[TornadoMax]
              • Set VariableSet TornadoSound[TornadoLoop] = TornadoSound[TornadoMax]
            • Else - Actions
      • Set VariableSet TornadoMax = (TornadoMax - 1)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • TornadoMax Equal to 0
        • Then - Actions
          • Trigger - Turn off Tornado Deindex <gen>
        • Else - Actions
JASS:
call CreateSound(string fileName, boolean looping, boolean is3D, boolean stopwhenoutofrange, integer fadeInRate, integer fadeOutRate, string eaxSetting)
call StopSound(sound soundHandle, boolean killWhenDone, boolean fadeOut)
 
Top