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

Jet Movement?

Status
Not open for further replies.
Level 6
Joined
Feb 16, 2014
Messages
193
Is it possible to trigger a certain type of flying unit's movement to be like the movement of the Jets in Command and Conquer generals.
Like when the unit is idle then that unit just circles the area,is that possible to do?
 
Yes. Just make circular movement.
Choose a point <p>.
Periodicly order the jet to move to p2. (p2 = <p> with offset <radius> facing <angle>)

<p> will be the same as long the jet changes it's position.
<radius> will be always the same. (probably)
<angle> needs to be changed each iteration, so it makes a circurlar movement.

To get jets that are doing nothing at a certain moment check if current order is "no order" or "null". (idk in GUI atm)
 

Wrda

Spell Reviewer
Level 26
Joined
Nov 18, 2012
Messages
1,891
Level 25
Joined
Jul 10, 2006
Messages
3,315
I find this is much simpler if you give the jets a custom movement system.

Every 0.03 sec
Set p1 = position of jet
Set p2 = p1 offset by X towards facing angle
call SetUnitX(jet, x of p2)
call SetUnitY(jet, y of p2)

Such a trigger would cause your jet(s) to "slide" forward constantly. Give them a low turn rate (try 0.05 for starters) for greater effect.
When the jet reaches the position it was ordered to move to, the trigger will cause it to slide over, and since the jet is no longer at the position where it wants to be, it will turn around and attempt to reach it again, and loop in this manner continuously.

This system will also prevent your jets from stopping when they attack. They'll attack once or twice as they approach a target, then fly over and circle around automatically to try again.
 
Level 6
Joined
Feb 16, 2014
Messages
193
I find this is much simpler if you give the jets a custom movement system.

Every 0.03 sec
Set p1 = position of jet
Set p2 = p1 offset by X towards facing angle
call SetUnitX(jet, x of p2)
call SetUnitY(jet, y of p2)

Such a trigger would cause your jet(s) to "slide" forward constantly. Give them a low turn rate (try 0.05 for starters) for greater effect.
When the jet reaches the position it was ordered to move to, the trigger will cause it to slide over, and since the jet is no longer at the position where it wants to be, it will turn around and attempt to reach it again, and loop in this manner continuously.

This system will also prevent your jets from stopping when they attack. They'll attack once or twice as they approach a target, then fly over and circle around automatically to try again.
  • move
    • Events
      • Time - Every 0.30 seconds of game time
    • Conditions
    • Actions
      • Set Loc = (Units in (Playable map area))
      • Unit Group - Pick every unit in Loc and 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 Predator Drone
            • Then - Actions
              • Set Pos1 = (Position of (Picked unit))
              • Set Pos2 = (Pos1 offset by 100.00 towards (Facing of (Picked unit)) degrees)
              • Custom script: call SetUnitX(PickedUnit, x of Pos2)
              • Custom script: call SetUnitY(PickedUnit, y of Pos2)
            • Else - Actions
Lol i tried this but i get an error: "Expected a name"
EDIT: And i also tried this,yeah the unit moves but it only moves in a straight direction.
  • move
    • Events
      • Time - Every 0.30 seconds of game time
    • Conditions
    • Actions
      • Set Loc = (Units in (Playable map area))
      • Unit Group - Pick every unit in Loc and 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 Predator Drone
            • Then - Actions
              • Set Pos1 = (Position of (Picked unit))
              • Set Pos2 = (Pos1 offset by 1000.00 towards (Facing of (Picked unit)) degrees)
              • Unit - Order (Picked unit) to Move To Pos2
            • Else - Actions
EDIT2: Nvm,found it out thx guys for the help.
  • move
    • Events
      • Time - Every 0.30 seconds of game time
    • Conditions
    • Actions
      • Set Loc = (Units in (Playable map area))
      • Unit Group - Pick every unit in Loc and 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 Predator Drone
            • Then - Actions
              • Set Pos1 = (Position of (Picked unit))
              • Set Pos2 = (Pos1 offset by 1000.00 towards Move_Angle degrees)
              • Unit - Order (Picked unit) to Move To Pos2
              • Set Move_Angle = (Move_Angle + 10.00)
            • Else - Actions
 
Level 25
Joined
Jul 10, 2006
Messages
3,315
Instead of "PickedUnit", you need to use a variable name.

It should look like this:

  • Jet Units Loop
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in JetGroup and do (Actions)
        • Loop - Actions
          • Set loc1 = (Position of (Picked unit))
          • Set loc2 = (loc1 offset by 20.00 towards (Facing of (Picked unit)) degrees)
          • Custom script: call SetUnitX(GetEnumUnit(), GetLocationX(udg_loc2))
          • Custom script: call SetUnitY(GetEnumUnit(), GetLocationY(udg_loc2))
          • Custom script: call RemoveLocation(udg_loc1)
          • Custom script: call RemoveLocation(udg_loc2)
- Use GetEnumUnit() for picked unit
- Clean the memory leaks with RemoveLocation

In my testmap I've noticed a problem with this method - if the unit approaches the location from far away enough, it will indeed reach its target location and just continue going straight instead of circling around. We'll need to add some way to detect this and order it to move somewhere nearby.
 
Level 6
Joined
Feb 16, 2014
Messages
193
Instead of "PickedUnit", you need to use a variable name.

It should look like this:

  • Jet Units Loop
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in JetGroup and do (Actions)
        • Loop - Actions
          • Set loc1 = (Position of (Picked unit))
          • Set loc2 = (loc1 offset by 20.00 towards (Facing of (Picked unit)) degrees)
          • Custom script: call SetUnitX(GetEnumUnit(), GetLocationX(udg_loc2))
          • Custom script: call SetUnitY(GetEnumUnit(), GetLocationY(udg_loc2))
          • Custom script: call RemoveLocation(udg_loc1)
          • Custom script: call RemoveLocation(udg_loc2)
- Use GetEnumUnit() for picked unit
- Clean the memory leaks with RemoveLocation

In my testmap I've noticed a problem with this method - if the unit approaches the location from far away enough, it will indeed reach its target location and just continue going straight instead of circling around. We'll need to add some way to detect this and order it to move somewhere nearby.
Thx,but i already figured it out
  • Idle
    • Events
      • Time - Every 0.30 seconds of game time
    • Conditions
    • Actions
      • Set Loc = (Units in (Playable map area))
      • Unit Group - Pick every unit in Loc and 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 Predator Drone
              • Is_Idle[(Player number of (Owner of (Triggering unit)))] Equal to True
            • Then - Actions
              • Set Pos1 = (Position of (Picked unit))
              • Set Pos2 = (Pos1 offset by 1000.00 towards Move_Angle degrees)
              • Unit - Order (Picked unit) to Move To Pos2
              • Set Move_Angle = (Move_Angle + 10.00)
              • Custom script: call RemoveLocation(udg_Pos1)
              • Custom script: call RemoveLocation(udg_Pos2)
            • Else - Actions
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
Make a group called PlaneGroup (or something catchy) and when a unit enters playable map area and it is a plane, add it to the group.
When a unit dies and it is a plane, remove it from the group.

No need to create a group in the interval. No need to pick a unit that is not a plane.

A move order is different from SetUnitX/Y. So is SetUnitPos (Move Unit instantly in GUI).

But as the units should not be set to a location but should move towards it... I actually think that this is good enough.

EDIT: "Is_Idle[(Player number of (Owner of (Triggering unit)))] Equal to True" I assume that there is only one plane per player...
In that case it is right to do this. However you should change (Triggering Unit) to (Picked Unit).
 
Level 6
Joined
Feb 16, 2014
Messages
193
One thing: you're leaking a unit group.

At the end of the trigger, put this custom script:
call DestroyGroup(udg_Loc)
Oops i forgot about that group leak,thx for pointing it out :)

Wietlol;2653999 EDIT: "Is_Idle[(Player number of (Owner of (Triggering unit))) said:
Equal to True" I assume that there is only one plane per player...
In that case it is right to do this. However you should change (Triggering Unit) to (Picked Unit).
Well in the map i'm making all the players are restricted to only 1 Predator Drone,and also all the players can ride/drive/fly vehicles(like tanks,jets,gunships etc.) but they can only have 1.
  • Idle
    • Events
      • Time - Every 0.30 seconds of game time
    • Conditions
    • Actions
      • Set Loc = (Units in (Playable map area))
      • Unit Group - Pick every unit in Loc and 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 Predator Drone
              • Is_Idle[(Player number of (Owner of (Picked unit)))] Equal to True
            • Then - Actions
              • Set Pos1 = (Position of (Picked unit))
              • Set Pos2 = (Pos1 offset by 1000.00 towards Move_Angle degrees)
              • Unit - Order (Picked unit) to Move To Pos2
              • Set Move_Angle = (Move_Angle + 10.00)
              • Custom script: call RemoveLocation(udg_Pos1)
              • Custom script: call RemoveLocation(udg_Pos2)
              • Custom script: call DestroyGroup(udg_Loc)
            • Else - Actions
Is this ok now ? :ogre_hurrhurr:
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
Nope... you pick every unit in the group.
Then you destroy the group when you picked the first unit.
Then you want to pick the second unit but the group is destroyed... so it won't work.
You should either do this:
  • Set Loc = (Units in (Playable map area))
  • Unit Group - Pick every unit in Loc and do (Actions)
    • Loop - Actions
  • Custom script: call DestroyGroup(udg_Loc)
or this:
  • Custom script: set bj_wantDestroyGroup = true
  • Unit Group - Pick every unit in (Units in (Playable map area)) and do (Actions)
    • Loop - Actions

But still make a group that is a collection of planes if you can do that... otherwise wait until the map becomes laggy and then ask for others to help or see that you have developed enough to handle that yourself by then.
 
Level 6
Joined
Feb 16, 2014
Messages
193
Nope... you pick every unit in the group.
Then you destroy the group when you picked the first unit.
Then you want to pick the second unit but the group is destroyed... so it won't work.
You should either do this:
  • Set Loc = (Units in (Playable map area))
  • Unit Group - Pick every unit in Loc and do (Actions)
    • Loop - Actions
  • Custom script: call DestroyGroup(udg_Loc)
or this:
  • Custom script: set bj_wantDestroyGroup = true
  • Unit Group - Pick every unit in (Units in (Playable map area)) and do (Actions)
    • Loop - Actions
But still make a group that is a collection of planes if you can do that... otherwise wait until the map becomes laggy and then ask for others to help or see that you have developed enough to handle that yourself by then.

Im curious tho what is better to use?
  • set bj_wantDestroyGroup = true
or
  • call DestroyGroup(udg_Loc)
 
Level 6
Joined
Feb 16, 2014
Messages
193
In this case, they function the same.

But in some other triggers, the DestroyGroup() method is better to use since it allows you to perform other functions using the group.
e.g. if you search a group for units to filter out, you can remove them from this group, then pick them all later.
Ok thx,tho i have another problem,i tried this vJass code from another thread/topic of mine,i wanted it to be that when a certain unit uses an ability then a dummy unit(missile) will spawn and follow that targeted unit but i get alot of compile errors,heres the code.
JASS:
globals
    location dummyLoc = Location(0, 0)
endglobals

function GetUnitZ takes unit u returns real
    call MoveLocation(dummyLoc, GetUnitX(u), GetUnitY(u))
    
    return (GetLocationZ(dummyLoc) + GetUnitFlyHeight(u))
endfunction

function SetUnitXYZ takes unit u, real x, real y, real z returns nothing    
    call SetUnitX(u, x)
    call SetUnitY(u, y)
    
    call MoveLocation(dummyLoc, x, y)
    
    call SetUnitFlyHeight(u, z - GetLocationZ(dummyLoc), 0)
endfunction

struct Missile
    static hashtable ht=InitHashtable()
    static constant real INTERVAL=0.03125
    
    unit dummy
    timer moveTimer
    
    real x
    real y
    real z
    
    real moveLen
    real moveLenSqr
    
    unit target
    
    method destroy takes nothing returns nothing
        call RemoveSavedInteger(ht, GetHandleId(this.moveTimer), 0)
        call PauseTimer(this.moveTimer)
        call DestroyTimer(this.moveTimer)
        
        call RemoveUnit(this.dummy)
        
        call this.deallocate()
    endmethod
    
    method move takes nothing returns nothing
        local real targetX = GetUnitX(this.target)
        local real targetY = GetUnitY(this.target)
        local real targetZ = GetUnitZ(this.target)

        local real dX = targetX - this.x
        local real dY = targetY - this.y
        local real dZ = targetZ - this.z
        
        local real dSqr = dX*dX+dY*dY+dZ*dZ
        local real d
        
        if (dSqr < this.moveLenSqr) then
            call this.destroy()
        else
            set d = SquareRoot(dSqr)
        
            set this.x = this.x + dX / d * this.moveLen
            set this.y = this.y + dY / d * this.moveLen
            set this.z = this.z + dZ / d * this.moveLen
            
            call SetUnitXYZ(this.dummy, this.x, this.y, this.z)
        endif
    endmethod
    
    static method moveByTimer takes nothing returns nothing
        call thistype(LoadInteger(ht, GetHandleId(GetExpiredTimer()), 0)).move()
    endmethod
    
    static method create takes integer id, real x, real y, real z, unit target, real speed returns thistype
        local thistype this = thistype.allocate()
        
        set this.dummy = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), id, 0, 0, 0)
        
        set this.x = x
        set this.y = y
        set this.z = z
        
        set this.moveLen = speed*INTERVAL
        set this.moveLenSqr = speed*speed*INTERVAL*INTERVAL
        set this.target = target
        set this.moveTimer = CreateTimer()
        
        call SaveInteger(ht, GetHandleId(this.moveTimer), 0, this)
        
        call UnitAddAbility(this.dummy, 'Amrf')
        call UnitRemoveAbility(this.dummy, 'Amrf')
        call UnitAddAbility(this.dummy, 'Aloc')
        
        call SetUnitXYZ(this.dummy, x, y, z)
        
        call TimerStart(this.moveTimer, INTERVAL, true, function thistype.moveByTimer)
        
        return this
    endmethod
endstruct
I have no idea on why i get alot of compile errors when i try to test/save my map,can someone explain to me why its not working/or why its giving me errors?
 
Level 6
Joined
Feb 16, 2014
Messages
193
For vJASS you need to use the JNGP editor (jass newgen pack, find it in tools section)
Ok i'll try that
P3xot1s.png

Aw,when i try to test the map,this happens.
 
Last edited:
Level 6
Joined
Feb 16, 2014
Messages
193
Ok ill try to search it but i tried to make a trigger that when a unit uses an ability(item ability) then a unit(missile) will spawn and follow the target but it doesnt even move :( heres the trigger
  • Start
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Sidewinder
    • Actions
      • Set XTarget = (Position of (Last created unit))
      • Set XTargetMove = (XTarget offset by 100.00 towards (Facing of (Last created unit)) degrees)
      • Unit - Create 1 Sidewinder Missile for (Owner of (Triggering unit)) at (Position of (Triggering unit)) facing (Target point of ability being cast)
      • For each (Integer A) from 1 to 30, do (Actions)
        • Loop - Actions
          • Unit - Make (Last created unit) face (Facing of (Target unit of ability being cast)) over 2.00 seconds
          • Animation - Change (Last created unit) flying height to (Current flying height of (Target unit of ability being cast)) at 50.00
      • For each (Integer B) from 1 to 30, do (Actions)
        • Loop - Actions
          • Custom script: call SetUnitX(GetEnumUnit(), GetLocationX(udg_XTargetMove))
          • Custom script: call SetUnitY(GetEnumUnit(), GetLocationY(udg_XTargetMove))
 

Wrda

Spell Reviewer
Level 26
Joined
Nov 18, 2012
Messages
1,891
  • For each (Integer B) from 1 to 30, do (Actions)
  • Loop - Actions
    • Custom script: call SetUnitX(GetEnumUnit(), GetLocationX(udg_XTargetMove))
    • Custom script: call SetUnitY(GetEnumUnit(), GetLocationY(udg_XTargetMove))
should be
  • For each (Integer B) from 1 to 30, do (Actions)
  • Loop - Actions
    • Custom script: call SetUnitX(GetLastCreatedUnit(), GetLocationX(udg_XTargetMove))
    • Custom script: call SetUnitY(GetLastCreatedUnit(), GetLocationY(udg_XTargetMove))
Is it even supposed to be instant? What are these loop integers A and B are used for, if they are run once it will be equal to have run 30 times? You need a 2nd trigger with event "every 0.03 seconds of game-time" to make the missile move smoothly.
 
Level 6
Joined
Feb 16, 2014
Messages
193
Ok i managed to make it but the exploding thing is not working,heres the script:
  • Sidewinder
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Sidewinder
    • Actions
      • Set UnitLoc = (Position of (Triggering unit))
      • Unit - Create 1 Sidewinder Missile for (Owner of (Triggering unit)) at UnitLoc facing (Facing of (Triggering unit)) degrees
      • Unit - Order (Last created unit) to Follow (Target unit of ability being cast)
      • Animation - Change (Last created unit) flying height to (Current flying height of (Target unit of ability being cast)) at 200.00
      • Custom script: call RemoveLocation(udg_UnitLoc)
This is when u target a unit then it creates the missile and adjust its height(WORKS)
  • SidewinderM
    • Events
      • Time - Every 0.10 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in (Last created unit group) and 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 Sidewinder Missile
            • Then - Actions
              • Set Missile_Speed = 100.00
              • Set UnitLoc = (Position of (Picked unit))
              • Set MissileTarget = (UnitLoc offset by Missile_Speed towards (Facing of (Picked unit)) degrees)
              • Custom script: call SetUnitX(GetEnumUnit(), GetLocationX(udg_MissileTarget))
              • Custom script: call SetUnitY(GetEnumUnit(), GetLocationY(udg_MissileTarget))
              • Custom script: call RemoveLocation(udg_UnitLoc)
              • Custom script: call RemoveLocation(udg_MissileTarget)
            • Else - Actions
This is the part where the missile will follow the target(WORKS)
  • SidewinderMExl
    • Events
      • Unit - A unit Is issued an order targeting an object
    • Conditions
    • Actions
      • Set MissileNear = (Units within 100.00 of (Target point of issued order) matching ((Unit-type of (Picked unit)) Equal to Sidewinder Missile))
      • Unit Group - Pick every unit in MissileNear and do (Actions)
        • Loop - Actions
          • Animation - Play (Picked unit)'s death animation
          • Unit - Cause (Picked unit) to damage circular area after 1.00 seconds of radius 300.00 at (Target point of ability being cast), dealing (Random real number between 650.00 and 800.00) damage of attack type Siege and damage type Demolition
          • Special Effect - Create a special effect at (Position of (Picked unit)) using Abilities\Spells\Orc\WarStomp\WarStompCaster.mdl
          • Wait 0.50 seconds
          • Unit - Explode (Picked unit)
Now this is my problem,the missile just circles around the target and doesnt get removed nor does it damages any units,why is this not working?
 
Status
Not open for further replies.
Top