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

[Spell] Dashes with dynamic speeds

Status
Not open for further replies.
Level 3
Joined
Aug 25, 2013
Messages
22
Hi there Hive

I was trying to make a spell which makes the unit dash to the target point with a dynamic speed, which means he will always take a specific amount of time (1 second) to reach the destination, no matter the distance. The triggered movement would take place every 0.04 seconds, This meant that the unit would be moved 25 times (1 second). Then I took the distance between caster and target and divided it by 25, getting the distance to move the unit each interval

All simple and pretty obvious until now, i just made a loop that would move the unit every 0.04 seconds 'Distance/25' units towards the target loc and in theory the unit would reach destination within a second. The problem is than in practice it was not so, the unit was taking way longer than a second (More than the cooldown of the spell, which was 3 seconds or so).

Since my knowledge in JASS is even less than basic I used a GUI version with loops with waits (According to the one who wrote it, it'd be MUI and all that)
Is my math faulty in some way or it is just the method I used being faulty? Because i can't seem to make it work the intended way
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
I think that you are using waits inside a loop in GUI. Even a wait timer would be harsh.
  • For each (Integer A) from 1 to 25, do (Actions)
    • Loop - Actions
      • -------- move unit --------
      • Wait 0.04 game-time seconds
Even though I tell people a lot that wait timers are not so bad and can be used, you are bound to precision.
In fact if you run some tests with a Game Time System, you will find out that the waits have a 0.s to 0.17s minimum delay and in loops where you do those with 0.04 seconds, you would have wait timers of 0.2 seconds instead. (25 x 0.2 = 5 seconds.)

To replace wait timers, you should either use timers... which are very bad in this situation.
Or use a loop for "Every 0.04 seconds of game time" event.
You have to put the unit inside a list of all dashing units together and update their movement accordingly.
Try searching some stuff about indexing in GUI. There are a lot of them here on the hive.

Also use "SetUnitX()" and "SetUnitY()" instead of "Move (unit) instantly to (point)"
 
I think that you are using waits inside a loop in GUI. Even a wait timer would be harsh.
  • For each (Integer A) from 1 to 25, do (Actions)
    • Loop - Actions
      • -------- move unit --------
      • Wait 0.04 game-time seconds
Even though I tell people a lot that wait timers are not so bad and can be used, you are bound to precision.
In fact if you run some tests with a Game Time System, you will find out that the waits have a 0.s to 0.17s minimum delay and in loops where you do those with 0.04 seconds, you would have wait timers of 0.2 seconds instead. (25 x 0.2 = 5 seconds.)

To replace wait timers, you should either use timers... which are very bad in this situation.
Or use a loop for "Every 0.04 seconds of game time" event.
You have to put the unit inside a list of all dashing units together and update their movement accordingly.
Try searching some stuff about indexing in GUI. There are a lot of them here on the hive.

Also use "SetUnitX()" and "SetUnitY()" instead of "Move (unit) instantly to (point)"

Timer's are the best in this situation, every 0.04 seconds of game time isn't the greatest and should be replaced by a timer variable for both precision and to turn it off.
 
Level 3
Joined
Aug 25, 2013
Messages
22
I will try searching for one of the Unit Indexer Systems (and see a map that has them applied to a spell since it looks kinda confusing from what i've been seeing)

Timer's are the best in this situation, every 0.04 seconds of game time isn't the greatest and should be replaced by a timer variable for both precision and to turn it off.

I was thinking about this one too, making the main trigger run the 'every X seconds of game time' one where the dashing units would be moved periodically, but wouldn't that be not MUI? What would happen when multiple units are dashing at the same time?
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
Timer's are the best in this situation, every 0.04 seconds of game time isn't the greatest and should be replaced by a timer variable for both precision and to turn it off.

what?

Well first of all if you want a looping mui timer, you need jass.
Or a GUI trigger with 90% custom scripts which is destroying everything.

No offense against JASS, but I don't expect that he is much of a JASS user.
For precision, yes a timer would be better, even though it is a 0.04 (could be 0.03) duration.
If you want to turn it off, you can do that with the 0.04 seconds of gametime easier than with timers.
I can tell you that.
I got my hands full working on something which is also a looping timer which runs an effect when it expires but I use that because the interval is modifyable.

I was thinking about this one too, making the main trigger run the 'every X seconds of game time' one where the dashing units would be moved periodically, but wouldn't that be not MUI? What would happen when multiple units are dashing at the same time?
You have to put the unit inside a list of all dashing units together and update their movement accordingly.

I will give you an example:
  • Ability Dash
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Animate Dead
    • Actions
      • Set DashUnit = (Triggering unit)
      • Set TempLocation = (Position of DashUnit)
      • Set TempLocation2 = (Target point of ability being cast)
      • Set DashAngle = (Angle from TempLocation to TempLocation2)
      • Set DashDistance = ((Distance between TempLocation and TempLocation2) x 0.03)
      • Custom script: call RemoveLocation(udg_TempLocation)
      • Custom script: call RemoveLocation(udg_TempLocation2)
      • Trigger - Run Dash Add Unit <gen> (ignoring conditions)
  • Dash Add Unit
    • Events
    • Conditions
    • Actions
      • Set DashIndex = (DashIndex + 1)
      • Set DashUnitArray[DashIndex] = DashUnit
      • Set DashAngleArray[DashIndex] = DashAngle
      • Set DashDistanceArray[DashIndex] = DashDistance
      • Trigger - Turn on Dash Loop <gen>
  • Dash Loop
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • For each (Integer TempInteger) from 0 to DashIndex, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • DashDurationArray[TempInteger] Less than or equal to 0.00
            • Then - Actions
              • Trigger - Run Dash Remove Unit <gen> (ignoring conditions)
            • Else - Actions
              • Set TempLocation = (Position of DashUnitArray[TempInteger])
              • Set TempLocation2 = (TempLocation offset by DashDistanceArray[TempInteger] towards DashAngleArray[TempInteger] degrees)
              • Unit - Move DashUnitArray[TempInteger] instantly to TempLocation2, facing DashAngleArray[TempInteger] degrees
              • Set DashDurationArray[TempInteger] = (DashDurationArray[TempInteger] - 0.03)
              • Custom script: call RemoveLocation(udg_TempLocation)
              • Custom script: call RemoveLocation(udg_TempLocation2)
  • Dash Remove Unit
    • Events
    • Conditions
    • Actions
      • For each (Integer TempInteger2) from TempInteger to DashIndex, do (Actions)
        • Loop - Actions
          • Set DashAngleArray[TempInteger2] = DashAngleArray[(TempInteger2 + 1)]
          • Set DashDistanceArray[TempInteger2] = DashDistanceArray[(TempInteger2 + 1)]
          • Set DashDurationArray[TempInteger2] = DashDurationArray[(TempInteger2 + 1)]
          • Set DashUnitArray[TempInteger2] = DashUnitArray[(TempInteger2 + 1)]
      • Set DashIndex = (DashIndex - 1)
Something like that.
I don't know about new ways to create indexers and I am sure that this method is a bit outdated but this is the concept of it.
 
Last edited:
Level 12
Joined
Feb 22, 2010
Messages
1,115
You can't use GUI-wait action for such low values.I think your outdated method is my current method :O
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
Nope, you don't need JASS for a "looping mui timer". GUI == JASS so most opinions against either scripting language is rather null. Luckily custom script is almost as easy to read as GUI. You need JASS/custom script to remove most leaks as well a few other things.

I know that GUI is JASS... equal as vJASS is JASS.
But in GUI you cannot change the Initfunction (that is called before map initialization that creates the trigger) and so you cannot give the trigger a different action or condition than the first.
Even when you do "Custom script - endfunction" you still have to call a function that is declared below that. That is something that JASS cannot do... without the help of some global variables.

You can't use GUI-wait action for such low values.I think your outdated method is my current method :O

So can you use TriggerSleepAction() for such low values?
It is not GUI. :p
 
Level 3
Joined
Aug 25, 2013
Messages
22
I tried out Wietlol's example and the spell seems to be working well now. I assumed that the "DashDurationArray" variable needs to have a default value of 1.00 (or however long I wish the dash to be). Added some special effects and now it worked as I envisioned it.
 
Level 3
Joined
Nov 22, 2014
Messages
50
Why would you make extra triggers to add or remove the dash unit?
You could just as well add that piece of script instead of the 'run trigger' action, couldn't you?
 
Level 3
Joined
Aug 25, 2013
Messages
22
First of all thanks to everyone who helped me with this issue, I only have one more question

can the variables TempUnit, TempLoc1, TempLoc2 and TempInteger be used in other spells or do I have to create new ones?

(thread might be a little old but the question is related to it and I didn't think adequate to make another thread just for it)
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
The idea of Temp variables is that you can save a lot of variables that do pretty much nothing the whole time.

When values do not have to be saved through timelapse (waits, timers, different events, etc) you can mostly make the variables that save them either local (only for that function) or Temp (can be used in all functions but may not parse through timelapse).

Lets take this one for example:
  • Ability Dash
    • Events
    • Unit - A unit Starts the effect of an ability
    • Conditions
    • (Ability being cast) Equal to Animate Dead
    • Actions
    • Set DashUnit = (Triggering unit)
    • Set TempLocation = (Position of DashUnit)
    • Set TempLocation2 = (Target point of ability being cast)
    • Set DashAngle = (Angle from TempLocation to TempLocation2)
    • Set DashDistance = ((Distance between TempLocation and TempLocation2) x 0.03)
    • Custom script: call RemoveLocation(udg_TempLocation)
    • Custom script: call RemoveLocation(udg_TempLocation2)
    • Trigger - Run Dash Add Unit <gen> (ignoring conditions)
There is no friggin' trigger that can override the TempLocations between the create and remove. So we use Temp variables.

The real reason is that you will not have a massive list of global variables.
When reaching 800+ you will notice that you want some kind of treeview or different lists.
 
Status
Not open for further replies.
Top