• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[Spell] Ranged attack missile going along the ground

Status
Not open for further replies.
Level 6
Joined
Jan 8, 2009
Messages
140
I'm trying to make some ranged abilities however the missile always travels along the floor, is it possible to make it travel through the air like an arrow would? (any missle I select travels along the ground.)
 
Level 6
Joined
Jan 8, 2009
Messages
140
that sounds infinitely more complicated haha, would I need to trigger each individual ability, or could I set up a bunch of variables to do it in a single loop?
 

Rheiko

Spell Reviewer
Level 25
Joined
Aug 27, 2013
Messages
4,121
Level 20
Joined
Aug 13, 2013
Messages
1,696
Open your OE (Object Editor) Go to the Dummy Unit and find the Movement - Height Max and Min then set the value to whatever you like . If you want the missile fly through air then touch the ground then use Parabola Function:
JASS:
function Parabola takes real h, real dr, real cdr returns real
    return (4 * h / dr ) * ( dr - cdr ) * ( cdr / dr )
endfunction

/* How to call the function?? Parabola(height,distance,counterdistance)

It just needs height , distance , and the current distance.

Simply: If you are setting the unit fly height use this

Height : 300
Distance Range: 500
Current Distance: 0.00
Speed Plus: 18.00

In the looping trigger 0.03 adds the Current Distance to the Speed like this:

set Current Dist = Current Dist + Speed = 18.00 and so on...
                                              ( 300 ) ( 500. )    ( 18.00 )
call SetUnitFlyHeight(udg_YOUR_UNIT,Parabola(height,distance,currentdistance),0)

Simplify like this: 4 * height divided by distance equals 2.4 finished at the first procedure now go to 2nd.
2.4 * (500 - 18.) equal to 1182 go to 3rd or last procedure
1182 * (18. / 500) equal to 42.
*/
 
Level 6
Joined
Jan 8, 2009
Messages
140
hmm, the dummy unit always seems quite slow no matter the value, is there a movement speed cap? Also, would it be possible to make the unit always travel a certain distance?
 
Level 6
Joined
Jan 8, 2009
Messages
140
^ Use triggers Unit - Move (Instantly) ( Polar Projections ).

I seem to be missing this function, specifically the polar projections part? and if i'm not mistake wouldn't moving it instantly show no movement and simply make it appear elsewhere instantly?

After looking at a few projectile systems they all seem overly complicated, all I need is something simple that moves a projectile from the caster to the target point (no target or a unit target) and then does x damage to any units hit by the projectile. Am I wrong in assuming this sort of ability could be created with one or two triggers requiring only a few actions each?

I basically just need help with making the projectile function like a projectile, i'm sure I can handle what happens when a unit comes in contact with it; damage, effects etc.
 
Level 28
Joined
Sep 26, 2009
Messages
2,520
I seem to be missing this function, specifically the polar projections part?
Polar projection (or "Point with polar offset) creates new point by using another point (let's call it S) as its epicenter. The new point is created by offsetting point S by range R towards angle A.
  • Set S = *somewhere*
  • Set NewPoint = (S offset by R towards A degrees)
NewPoint is a point created via polar projection.


After looking at a few projectile systems they all seem overly complicated, all I need is something simple that moves a projectile from the caster to the target point
You just have to copy the system into your map. Those systems usually come with a ReadMe or something similar which explains how to set the whole thing up.


Am I wrong in assuming this sort of ability could be created with one or two triggers requiring only a few actions each?
Yes you are mistaken - if you want those systems to not bug, then they are a bit long (not overly if handled right). Also, if you want to shoot projectile that hits units in its path, then you can't really use parabola, because with parabola you hit units only nearby the point it hits (if you imagine what you want - a projectile that hits units in its path, it would make no sense - the arrow could hit units because their X and Y coordinates match, but their Z coordinates could differ greatly - the arrow would be far above the unit, but still hit it - that's not fair you know).


if i'm not mistake wouldn't moving it instantly show no movement and simply make it appear elsewhere instantly?
Projectile systems work by moving projectiles instantly to a point offset by little bit from their current position and doing it quickly - like every 0,03 second. That gives us the impression that they moves fluidly.
Most systems use a custom script to set the X and Y coordinate of the projectiles, as that is more efficient.
 
Level 6
Joined
Jan 8, 2009
Messages
140
thanks for the reply Nichilus, very detailed. it looks like i'm going to have to use a system however i can only seem to find gui projectile systems that work with a unit target, none that work with no target. ideally i'd like to avoid jass systems because i don't want to add in something I can't understand and modify if need be. is a projectile system fairly similar to say and ice sliding trigger? another option i thought of was perhaps editing a model so that it's higher than the centre point so it looks as if it's flying, could that work?

EDIT:

I tried out this code and it seems to work, however it seems too good to be true, is there anything wrong with the code here that will cause problems? (the line for adding the units to the group is just for testing purposes, i'm sure I can think of a better way to identify missiles)

  • Missile Move
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • Set MissileGroup = (Units owned by Neutral Passive matching ((Point-value of (Matching unit)) Equal to 500))
      • Unit Group - Pick every unit in MissileGroup and do (Actions)
        • Loop - Actions
          • For each (Integer loopA) from 1 to MissileCount, do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Unit-type of (Picked unit)) Equal to MissileModel[loopA]
                • Then - Actions
                  • Set MissileLoc = (Position of (Picked unit))
                  • Unit - Move (Picked unit) instantly to (MissileLoc offset by MissileSpeed[loopA] towards (Facing of (Picked unit)) degrees)
                  • Custom script: call RemoveLocation(udg_MissileLoc)
                • Else - Actions
      • Custom script: call DestroyGroup(udg_MissileGroup)
 
Last edited:
Level 13
Joined
Mar 24, 2013
Messages
1,105
  • (MissileLoc offset by MissileSpeed[loopA] towards (Facing of (Picked unit)) degrees)
This needs to be stored in a variable and cleared as you did with the position of picked.

I'm not sure I understand the integer loop inside of the unit group though, that means for each unit the moving action will fire as many times as the integer MissleCount
 
Level 6
Joined
Jan 8, 2009
Messages
140
  • (MissileLoc offset by MissileSpeed[loopA] towards (Facing of (Picked unit)) degrees)
This needs to be stored in a variable and cleared as you did with the position of picked.

I'm not sure I understand the integer loop inside of the unit group though, that means for each unit the moving action will fire as many times as the integer MissleCount

it may make more sense if I post the set up trigger, it's mostly so that I can set up any number of ranged abilities with different speeds and they will all work. here's the rest:

  • Init Missiles
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set MissileAbil[1] = Fire Wand
      • Set MissileModel[1] = Fire Wand (Missile)
      • Set MissileSpeed[1] = 30.00
      • Set MissileExpire[1] = 1.30
      • Set MissileAbil[2] = Ice Wand
      • Set MissileModel[2] = Ice Wand (Missile)
      • Set MissileSpeed[2] = 20.00
      • Set MissileExpire[2] = 1.90
      • -------- --------- --------
      • Set MissileCount = 2
  • Missile Cast
    • Events
      • Unit - A unit Begins casting an ability
    • Conditions
    • Actions
      • For each (Integer loopA) from 1 to MissileCount, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Ability being cast) Equal to MissileAbil[loopA]
            • Then - Actions
              • Unit - Make (Triggering unit) face (Target point of ability being cast) over 0.00 seconds
              • Unit - Create 1 MissileModel[loopA] for Neutral Passive at (Position of (Casting unit)) facing (Facing of (Triggering unit)) degrees
              • Unit - Add a MissileExpire[loopA] second Generic expiration timer to (Last created unit)
            • Else - Actions
if i've done anything wrong/inefficiently please let me know.
 
Level 13
Joined
Mar 24, 2013
Messages
1,105
Oh sure, now I understand what you wanted to do.

  • Unit - Make (Triggering unit) face (Target point of ability being cast) over 0.00 seconds
  • Unit - Create 1 MissileModel[loopA] for Neutral Passive at (Position of (Casting unit)) facing (Facing of (Triggering unit)) degrees
Target Point needs to be saved and cleared.

Position of Casting should be saved and cleared, it should also be replaced with triggering instead of casting.

You should change it to starts the effect of an ability because Begins casting can be abused.

Also Facing a direction over 0 still factors in turn rate so its potentially possible the unit will not be precisely facing the right direction the unit casted when the ability starts causing the projectile to be going the "wrong" way.

I like how this map sounds :D.
 
Level 20
Joined
Aug 13, 2013
Messages
1,696
pOke: Also Facing a direction over 0 still factors in turn rate so its potentially possible the unit will not be precisely facing the right direction the unit casted when the ability starts causing the projectile to be going the "wrong" way.

It can face the desired angle if the missile dummy is locust when creating units.
  • Unit - Make (Triggering unit) face (Target point of ability being cast) over 0.00 seconds
^ This is not needed if you already created unit in facing the desired angle direction IF the missile has ability locust
 
Level 6
Joined
Jan 8, 2009
Messages
140
okay i think i fixed the leak in the cast trigger
  • Missile Cast
    • Events
      • Unit - A unit Begins casting an ability
    • Conditions
    • Actions
      • For each (Integer loopA) from 1 to MissileCount, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Ability being cast) Equal to MissileAbil[loopA]
            • Then - Actions
              • Set tmpLoc = (Target point of ability being cast)
              • Unit - Make (Triggering unit) face tmpLoc over 0.00 seconds
              • Unit - Create 1 MissileModel[loopA] for Neutral Passive at tmpLoc facing (Facing of (Triggering unit)) degrees
              • Unit - Add a MissileExpire[loopA] second Generic expiration timer to (Last created unit)
              • Custom script: call RemoveLocation(udg_tmpLoc)
            • Else - Actions
however i'm unsure what to do with the other leak you pointed out
  • (MissileLoc offset by MissileSpeed[loopA] towards (Facing of (Picked unit)) degrees)
It can face the desired angle if the missile dummy is locust when creating units.
  • Unit - Make (Triggering unit) face (Target point of ability being cast) over 0.00 seconds
^ This is not needed if you already created unit in facing the desired angle direction IF the missile has ability locust

the missile does have locust, should I remove that line then?
 
Level 13
Joined
Mar 24, 2013
Messages
1,105
  • Missile Cast
  • Events
  • Unit - A unit Begins casting an ability
  • Conditions
  • Actions
  • For each (Integer loopA) from 1 to MissileCount, do (Actions)
  • Loop - Actions
    • if (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • if - Conditions
  • (Ability being cast) Equal to MissileAbil[loopA]
  • Then - Actions
  • Set tmpLoc = target point of ability being cast
  • Set tmpLoc2 = position of triggering unit
  • Set TempReal = Angle Between tmploc and tmploc2
  • Unit - Make (Triggering unit) face tmpLoc over 0.00 seconds
  • Unit - Create 1 MissileModel[loopA] for Neutral Passive at tmpLoc2 facing TempReal degrees
  • Unit - Add a MissileExpire[loopA] second Generic expiration timer to (Last created unit)
  • Custom script: call RemoveLocation(udg_tmpLoc)
  • Custom script: call RemoveLocation(udg_tmpLoc2)
    • Else - Actions
I think you DO need the facing, because you don't always have to be facing a point EXACTLY to cast a spell toward it, alternatively instead of making the missile face the Facing of Triggering make it face the angle between the point of ability being cast and position of triggering unit (temploc and temploc2) That way its the most likely to be going the "right way"

You just need another variable for this:
  • (MissileLoc offset by MissileSpeed[loopA] towards (Facing of (Picked unit)) degrees)
  • Set MissileLoc2 = (MissileLoc offset by MissileSpeed[loopA] towards (Facing of (Picked unit)) degrees)

So
  • Unit - Move (Picked unit) instantly to MissleLoc2 towards (Facing of (Picked unit)) degrees)
A minor side note, you might want to save Picked Unit to a variable, it will increase efficiency since you use it quite a few times. (Save it before your IF and use the variable anytime you want to refer to it after)
 
Level 6
Joined
Jan 8, 2009
Messages
140
  • Missile Cast
  • Events
  • Unit - A unit Begins casting an ability
  • Conditions
  • Actions
  • For each (Integer loopA) from 1 to MissileCount, do (Actions)
  • Loop - Actions
    • if (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • if - Conditions
  • (Ability being cast) Equal to MissileAbil[loopA]
  • Then - Actions
  • Set tmpLoc = target point of ability being cast
  • Set tmpLoc2 = position of triggering unit
  • Set TempReal = Angle Between tmploc and tmploc2
  • Unit - Make (Triggering unit) face tmpLoc over 0.00 seconds
  • Unit - Create 1 MissileModel[loopA] for Neutral Passive at tmpLoc2 facing TempReal degrees
  • Unit - Add a MissileExpire[loopA] second Generic expiration timer to (Last created unit)
  • Custom script: call RemoveLocation(udg_tmpLoc)
  • Custom script: call RemoveLocation(udg_tmpLoc2)
    • Else - Actions
I think you DO need the facing, because you don't always have to be facing a point EXACTLY to cast a spell toward it, alternatively instead of making the missile face the Facing of Triggering make it face the angle between the point of ability being cast and position of triggering unit (temploc and temploc2) That way its the most likely to be going the "right way"

You just need another variable for this:
  • (MissileLoc offset by MissileSpeed[loopA] towards (Facing of (Picked unit)) degrees)
  • Set MissileLoc2 = (MissileLoc offset by MissileSpeed[loopA] towards (Facing of (Picked unit)) degrees)

So
  • Unit - Move (Picked unit) instantly to MissleLoc2 towards (Facing of (Picked unit)) degrees)
A minor side note, you might want to save Picked Unit to a variable, it will increase efficiency since you use it quite a few times. (Save it before your IF and use the variable anytime you want to refer to it after)

that works perfectly! thank you so much. although i had to switch the tmpReal from loc and loc2 to loc2 and loc1.
 
Status
Not open for further replies.
Top