• 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.

[vJASS] A way to let a unit face a point after moving.

Status
Not open for further replies.
Level 19
Joined
Oct 12, 2007
Messages
1,821
I'm trying to think of a way to handle a unit's facing after he completed a move order.

I want to create an easy snippet so that I can order a unit to move to a point. As soon as he finished his move order he should turn so that his facing becomes 270..

How can I check if the unit has finished moving so I can order it to change its facing?

Please keep in mind that I will use this snippet for multiple units at the same time (max units at the same time would be around 30.)
 
u can possibly do move unit instant to point then create dummy unit 50.00 to the south then order unit to target the dummy then issue stop order of unit then destroy dummy and it should be fine since its instant u need to use a timer if u need it to be timed movement sry not at my pc so i cant look up the actual functions for u hopefully this helps
 
Level 19
Joined
Oct 12, 2007
Messages
1,821
u can possibly do move unit instant to point then create dummy unit 50.00 to the south then order unit to target the dummy then issue stop order of unit then destroy dummy and it should be fine since its instant u need to use a timer if u need it to be timed movement sry not at my pc so i cant look up the actual functions for u hopefully this helps

That only works if the unit is actually moving from the north to the south, which wouldn't be a problem because he would always face 270. then anyway.
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
JASS:
scope FaceTwoHunderedSeventy initializer init
/*
    This scope requires new Table from thehiveworkshop.com from Bribe
    Jass section, page 3 I believe
*/

    globals
        private constant integer DUMMY = 'a000'
        //this is any unit with locust and invisiblity
        //best would be, if it was neutral unit so it wont attack or it had disabled attacks
        //like paesants or with cargo hold
        
        private Table infounit
        private Table infounite
    endglobals

    private function handler takes nothing returns boolean
        local trigger t = GetTriggeringTrigger()
        local unit entering = GetTriggerUnit()
        local unit holding = infounit.unit[GetHandleId(t)]
        if entering == infounite.unit[GetHandleId(t)] then
            call SetUnitFacing(GetTriggerUnit(), 270.)
            call DestroyTrigger(t)
            call KillUnit(holding)
            call RemoveUnit(holding)
        endif
        set t = null
        set entering = null
        set holding = null
        return false
    endfunction
    
    function MoveWithFace takes unit e, real tx, real ty returns nothing
        local trigger t = CreateTrigger()
        local unit u = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), DUMMY, tx, ty, 0)
        call TriggerRegisterUnitInRange(t, u, 100., null)
        call TriggerAddCondition(t, Condition(function handler))
        set infounit.unit[GetHandleId(t)] = u
        set infounite.unit[GetHandleId(t)] = e
        call IssuePointOrder(e, "move", tx, ty)
        set t = null
        set u = null
    endfunction
    
    private function init takes nothing returns nothing
        set infounit = Table.create()
        set infounite = Table.create()
    endfunction

endscope

when you want to make unit move to some point and make it face 270., just call MoveWithFace(which unit, real x, real y)
 
That only works if the unit is actually moving from the north to the south, which wouldn't be a problem because he would always face 270. then anyway.

i uses this way for my minigame and it works fine lol u move unit instantly to a point x,y then u do setunitfacing x,(y-50) works good shorter than b4 i forgot it was setunitfacing

edit: looks like edo came up w a nice one for u tho
 
Level 19
Joined
Oct 12, 2007
Messages
1,821
JASS:
scope FaceTwoHunderedSeventy initializer init
/*
    This scope requires new Table from thehiveworkshop.com from Bribe
    Jass section, page 3 I believe
*/

    globals
        private constant integer DUMMY = 'a000'
        //this is any unit with locust and invisiblity
        //best would be, if it was neutral unit so it wont attack or it had disabled attacks
        //like paesants or with cargo hold
        
        private Table infounit
        private Table infounite
    endglobals

    private function handler takes nothing returns boolean
        local trigger t = GetTriggeringTrigger()
        local unit entering = GetTriggerUnit()
        local unit holding = infounit.unit[GetHandleId(t)]
        if entering == infounite.unit[GetHandleId(t)] then
            call SetUnitFacing(GetTriggerUnit(), 270.)
            call DestroyTrigger(t)
            call KillUnit(holding)
            call RemoveUnit(holding)
        endif
        set t = null
        set entering = null
        set holding = null
        return false
    endfunction
    
    function MoveWithFace takes unit e, real tx, real ty returns nothing
        local trigger t = CreateTrigger()
        local unit u = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), DUMMY, tx, ty, 0)
        call TriggerRegisterUnitInRange(t, u, 100., null)
        call TriggerAddCondition(t, Condition(function handler))
        set infounit.unit[GetHandleId(t)] = u
        set infounite.unit[GetHandleId(t)] = e
        call IssuePointOrder(e, "move", tx, ty)
        set t = null
        set u = null
    endfunction
    
    private function init takes nothing returns nothing
        set infounit = Table.create()
        set infounite = Table.create()
    endfunction

endscope

when you want to make unit move to some point and make it face 270., just call MoveWithFace(which unit, real x, real y)


Thanks for the help.
However, I tried this out. Implemented Bribe's (New) Table system and created a test trigger taht should order my unit to move to (GetUnitX(u) - 250.)(GetUnitY(u) - 250.). This would order him to move to the south-west, however after finishing moving there he doesn't seem to turn his face to the south (270.).
So it's not working... hmm
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
oh sorry, I forgot to put Stop order there, he would try to rotate but his movement will interupt the facing part, here is it:
JASS:
scope FaceTwoHunderedSeventy initializer init
/*
    This scope requires new Table from thehiveworkshop.com from Bribe
    Jass section, page 3 I believe
*/

    globals
        private constant integer DUMMY = 'a000'
        //this is any unit with locust and invisiblity
        //best would be, if it was neutral unit so it wont attack or it had disabled attacks
        //like paesants or with cargo hold
        
        private Table infounit
        private Table infounite
    endglobals

    private function handler takes nothing returns boolean
        local trigger t = GetTriggeringTrigger()
        local unit entering = GetTriggerUnit()
        local unit holding = infounit.unit[GetHandleId(t)]
        if entering == infounite.unit[GetHandleId(t)] then
            call IssueImmediateOrder(entering, "stop")
            call SetUnitFacing(entering, 270.)
            call DestroyTrigger(t)
            call KillUnit(holding)
            call RemoveUnit(holding)
        endif
        set t = null
        set entering = null
        set holding = null
        return false
    endfunction
    
    function MoveWithFace takes unit e, real tx, real ty returns nothing
        local trigger t = CreateTrigger()
        local unit u = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), DUMMY, tx, ty, 0)
        call TriggerRegisterUnitInRange(t, u, 100., null)
        call TriggerAddCondition(t, Condition(function handler))
        set infounit.unit[GetHandleId(t)] = u
        set infounite.unit[GetHandleId(t)] = e
        call IssuePointOrder(e, "move", tx, ty)
        set t = null
        set u = null
    endfunction
    
    private function init takes nothing returns nothing
        set infounit = Table.create()
        set infounite = Table.create()
    endfunction

endscope

this will however rotate the unit 100 X and 100 Y away from the point you ordered

I tested with 300,300 -> 0,0 and -300,-300 -> 0,0 and it worked normally this time
 
oh sorry, I forgot to put Stop order there, he would try to rotate but his movement will interupt the facing part, here is it:
JASS:
scope FaceTwoHunderedSeventy initializer init
/*
    This scope requires new Table from thehiveworkshop.com from Bribe
    Jass section, page 3 I believe
*/

    globals
        private constant integer DUMMY = 'a000'
        //this is any unit with locust and invisiblity
        //best would be, if it was neutral unit so it wont attack or it had disabled attacks
        //like paesants or with cargo hold
        
        private Table infounit
        private Table infounite
    endglobals

    private function handler takes nothing returns boolean
        local trigger t = GetTriggeringTrigger()
        local unit entering = GetTriggerUnit()
        local unit holding = infounit.unit[GetHandleId(t)]
        if entering == infounite.unit[GetHandleId(t)] then
            call IssueImmediateOrder(entering, "stop")
            call SetUnitFacing(entering, 270.)
            call DestroyTrigger(t)
            call KillUnit(holding)
            call RemoveUnit(holding)
        endif
        set t = null
        set entering = null
        set holding = null
        return false
    endfunction
    
    function MoveWithFace takes unit e, real tx, real ty returns nothing
        local trigger t = CreateTrigger()
        local unit u = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), DUMMY, tx, ty, 0)
        call TriggerRegisterUnitInRange(t, u, 100., null)
        call TriggerAddCondition(t, Condition(function handler))
        set infounit.unit[GetHandleId(t)] = u
        set infounite.unit[GetHandleId(t)] = e
        call IssuePointOrder(e, "move", tx, ty)
        set t = null
        set u = null
    endfunction
    
    private function init takes nothing returns nothing
        set infounit = Table.create()
        set infounite = Table.create()
    endfunction

endscope

this will however rotate the unit 100 X and 100 Y away from the point you ordered

I tested with 300,300 -> 0,0 and -300,-300 -> 0,0 and it worked normally this time

Hey, I just wanted to let you know there are a few issues with your script -

  1. You never want to put publicly available functions in a scope - the reason is that scopes don't tell each other which to insert in the map script first, thus, if some function implementing MoveWithFace is declared before FaceTwoHundredSeventy, you'll get an error. Fix this by declaring FaceTwoHundredSeventy as a library and simply use requires Table to ensure that Table gets declared first.
  2. If you use a function or struct without an access modifier (eg it is not declared as public nor private, this should only be done if the member has the same name as the library. The reason why is because whenever you have a library or a function/struct without an access modifier, you "reserve" the name of that function throughout the whole map - because there can't be two "function MoveWithFace" without an error. Thus, you should change either the library name or the function name or the function access modifier to reduce the amount of reserved functions.
  3. Your handler function is using both a dynamic trigger and a dynamic unit. You should use a static rect and a dynamic region instead of the unit, which will be much more efficient.
  4. You should also warn the client that your system has a limitation: if the unit doesn't reach the target after the dynamic trigger is called, the dynamic trigger can potentially leak (along with the dynamic unit)

I hope that helps.
 
Level 19
Joined
Oct 12, 2007
Messages
1,821
Currently I'm having some issues that have to do with this move order I think.

Here's the code that's not working properly, but whenever I remove the MoveWithFace line it works.

If I use this the map will crash as soon as I call out UnitLineUp(unit)

JASS:
library RegimentHandling

function UnitLineUp takes unit u returns nothing
    local integer id = GetUnitId(u)
    local real x = GetRectCenterX(Field[Unit_X[id]][Unit_Y[id]])
    local real y = GetRectCenterY(Field[Unit_X[id]][Unit_Y[id]])
    local integer Spot = Unit_Reg_Spot[id]
    local integer Size = Unit_Reg_Size[id]
    
        /// --- Regiment Size: 16 --- ///
    
        if Size == 16 then
            /// Setting the X value ///
            if Spot == 1 or Spot == 5 or Spot == 9 or Spot == 13 then
                set x = x -120.
            elseif Spot == 2 or Spot == 6 or Spot == 10 or Spot == 14 then
                set x = x -40.
            elseif Spot == 3 or Spot == 7 or Spot == 11 or Spot == 15 then
                set x = x +40.
            else
                set x = x +120.
            endif
            /// Setting the Y value ///
            if Spot > 0 and Spot < 5 then
                set y = y -120.
            elseif Spot > 4 and Spot < 9 then
                set y = y -40.
            elseif Spot > 8 and Spot < 13 then
                set y = y + 40.
            else
                set y = y + 120.
            endif
            /// Ordering the unit to move ///
            call MoveWithFace(u, x, y)
        endif
    
    set u = null
endfunction
endlibrary
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
Im on mobile so I cant scroll through the jass code
Cokemonkey:
1. yea I thought of that but I wan in the shower at that time :D
2. Im not that fun of that aproach, its easier to to call MoveUnitFace than MovingUnit_MoveUnitFace
Also most resources doesnt use that qpproach but its fact that its limitating
3. I think this is just fine, but what do you mean by static rect? this must work for multiple instances at the same time
4. good call there, but as mentioned Im on mobile right now so I cant rewrite

for grammar errors Im sorry, mobile typing sucks
 
2. Im not that fun of that aproach, its easier to to call MoveUnitFace than MovingUnit_MoveUnitFace

A good API will try to give its public members some descriptive names that aid to the abstraction of the parent - so if you had a library which was dedicated to moving units, you might call its public method for move then face "MoveUnit_faceAfter(u,x,y,theta)"

3. I think this is just fine, but what do you mean by static rect? this must work for multiple instances at the same time

That's right - that's why you use a static rect and a dynamic region. rect and region are different datatypes, and if a rect is added to a region and then that rect is moved, the region will remain unchanged - thus, you will create a new region, move a global rect, add rect to region, add event using region, then later destroy the trigger (but the rect is never destroyed because you reuse it)
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
hmmm...I didnt know that thing with rects and yes I am aware of fact that rect and region is not the same thing :D

edit: I checked the code with quote option, try removing call to my function and see if it still crashes, if yes, the problem lies out of my reach, if no, my script is fucked up and I will try to fix it tomorrow when I come from school(if noone else does meanwhile) and maybe try the rect/region way
also make sure you dont create infinite loops like Event - unit is issued order
Actions - issue unit order ...
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
that would be slower than trigger event, because trigger event triggers only once for certain event and you would have to specify it for certain units and make sure its the location you want(what if I want the unit to line at certain point)

I have remade my code but I cant test it because Im in school currently, so for any errors Im sorry but hopefully all is cleared
the only thing that is not good is that the timer will run even if the unit gets to the position but I didnt want to add yet another instance of table

JASS:
library MoveUnitFacingLib initializer init uses Table
/*
	to use in your libraries, make it as depedency(uses/requires)
	this time it should work better with less flaws
*/


	globals
		private Table units
		private Table facing
		private Table regions
		private Table trig
		private rect entering
	endglobals

	private function handler takes nothing returns boolean
		local trigger t = GetTriggeringTrigger()
		local unit u = GetTriggerUnit()
		local integer id = GetHandleId(t)
		if u == units.unit[id] then
			call DestroyTrigger(t)
			call IssueImmediateOrder(u, "stop")
			call SetUnitFacing(u, facing.real[id])
		endif
		set t = null
		set u = null
		return false
	endfunction

	private function flusher takes nothing returns nothing
		local timer ti = GetExpiredTimer()
		local integer id = GetHandleId(ti)
		local trigger t = trig.trigger[id]
		//check if the trigger exists
		if not t == null then
			call DestroyTrigger(t)
			call RemoveRegion(regions.region[id])
		endif
		set t = null
		call DestroyTimer(ti)
		set ti = null
	endfunction

	function MoveUnitFacing takes unit tomove, real locx, real locy, real toface returns nothing
		local region reg = CreateRegion()
		local trigger t = CreateTrigger()
		local timer ti = CreateTimer()
		local integer tid = GetHandleId(t)
		local integer tiid = GetHandleId(ti)
		

		//only if the unit exists run this code:
		if tomove != null then
			//moving region
			call MoveRectTo(entering, locx, locy)

			//registering the event
			call RegionAddRect(reg, entering)
			call TriggerRegisterEnterRegion(t, reg, null)
			call TriggerAddCondition(t, Condition(function handler))
			
			//saving for handler
			set units.unit[tid] = tomove
			set facing.real[tid] = toface
			set regions.region[tid] = reg

			//saving for flusher
			set regions.region[tiid] = reg
			set trig.trigger[tiid] = t

			//start for flush
			call TimerStart(ti, 20., false, function flusher)
			
			//move the unit
			call IssuePointOrder(tomove, "move", locx, locy)

			//nulling
			set ti = null
			set t = null
			set reg = null
		endif
	endfunction


	private function init takes nothing returns nothing
		set units = Table.create()
		set facing = Table.create()
		set regions = Table.create()
		set trig = Table.create()
		set entering = Rect(-50, -50, 50, 50)
	endfunction

endlibrary

also Im not sure if the rect will work as I think it works
My understanding of rect is that when I set it to -50, -50, 50, 50 and I move it it should than be newx - 50, newy - 50,
newx + 50, newy + 50

this time it will destroy the trigger after 20 seconds if the unit doesnt reach the point where it was ordered
and Im using rects so no need for dummy units anymore
 
Level 25
Joined
Jul 10, 2006
Messages
3,315
Your method stops the unit before it reaches the exact position.

I'm not particularly experienced in vJASS, but aren't you leaking triggers here?

My method's speed is unnoticeable, even if you were to have hundreds of units. Every 5 seconds or so, check X/Y distances to target X/Y are less than some threshold (no expensive distance formula here), and then continue. You could even add orders to a stack and check for N units every second.
 
Level 19
Joined
Oct 12, 2007
Messages
1,821
I guess rulerofiron's method would be better, because at the moment there's an annoying issue.
Sometimes the unit can't reach his spot yet because an other unit is moving in the way. If that happens he just stops moving or something.

I guess I gotta look for something that checks if a unit is moving or not and put that in a timer.
 
Level 19
Joined
Oct 12, 2007
Messages
1,821
Ah yeah that's great.
However I was thinking of a small change and now I'm wondering how I could start working on that. Maybe you have an idea.

In the map I order a group of 1 - 16 units to move to a point at the same time. As soon as they all stopped moving (reached their destination) I want to wait 1 second. After that second all units should change their facing to 270..

This would be my guess how to do this:
- Create 2 groups and put the moving units in them.
- As soon as a unit finishes moving he gets removed from the first group.
- As soon as the first group is empty the 1 second timer starts.
- After the 1 second timer I pick all units in group 2 and order them to face 270.

What do you think of this? I have my doubts about using 2 groups. I suppose I will need a good group recycling system for it then. And ofc, I still have to import a IsUnitMoving system for it.
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
ow yea ruler, if you pass null unit it will leak region and trigger :D
and in this cade you are right but still, once every 5 secs would be too much
I guess the bribes system is good enough for this

instead of using channel, you can just start a 1 second timer with something like timerutils so you can transfer data
thats just one way of doing it tho and its up to you which one you choose
 
Level 19
Joined
Oct 12, 2007
Messages
1,821
Well Ruler, that would work if all units finish moving at the same time.
But some of them arrive earlier then others.
I want the 1 second timer to start ticking as soon as all units finished moving.


Here's a small preview of what I got so far:


As you can see the units move fine, but sometimes they don't all arrive at the same time. And currently no facing trigger is activated.
As I said above here, they should all face into the direction I want 1 second after they all stopped moving as a regiment.
 
Level 25
Joined
Jul 10, 2006
Messages
3,315
and in this cade you are right but still, once every 5 secs would be too much

No.

I've made a squad system that can probably support a thousand or more units, and one of the functions is a "regroup" - checking a squad member's distance to his squad leader. Runs smoothly.

Well Ruler, that would work if all units finish moving at the same time.
But some of them arrive earlier then others.
I want the 1 second timer to start ticking as soon as all units finished moving.

Ah that makes sense.

You could index each instance and run a periodic.

Some pseudocode: (I don't have a vjass indexer on hand)

Trigger 1 - on arrival
Code:
set GroupFaceInstance = GroupFaceInstance + 1
set GroupFaceAngle[GroupFaceInstance] = angle you want
set GroupFaceGroup[GroupFaceInstance] = (units in squad)
set GroupFaceTicks[GroupFaceInstance] = 10

Trigger 2 - periodic every 0.1 seconds
Code:
loop i from 1 to GroupFaceInstance
  set GroupFaceTicks[i] = GroupFaceTicks[i] - 1
  if GroupFaceTicks[i] == 0 then
    //order units in group to face angle

    //re-order all instances:
    loop j from i to GroupFaceInstance
      if j != GroupFaceInstance then
        set GroupFaceAngle[j] = GroupFaceAngle[j+1]
        set GroupFaceGroup[j] = GroupFaceGroup[j+1]
        set GroupFaceTicks[j] = GroupFaceTicks[j+1]

PS: Your map is looking good :)
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
this time hopefully works :D

JASS:
library MoveUnitFacingLib initializer init requires Table

    globals
        //this is the aproximation this system will use, if you set to 0 it is the most
        //precice it can be, I think 16 should be fine
        private constant real aproximation = 16
        
        //order of the move command
        private constant integer order_move = 851986
        
        //set this to w/e you want
        //it will flush the command for unit in case it cannot access the point in
        //"this number" times
        //be aware that the checking happens once every 0.1 seconds, so this is for 2.5 second
        private constant integer tofailtries = 25
        
        private Table uToMove
        private Table toface
        private Table toWait
        private Table point
        private Table unitCoords
    endglobals
    
    /*
        This is debug feature, remove it if you dont want it
        But it shouldnt matter anyway cause its debug only feature
    */
    
    static if DEBUG_MODE then
        private struct ddata extends array
            static Table tries
            private static method onInit takes nothing returns nothing
                set tries = Table.create()
            endmethod
        endstruct
    endif
        
    private function IsAprox takes real a, real b returns boolean
        return a <= (b + aproximation) or a >= (b + aproximation)
    endfunction
    
    private function UpdateFacing takes nothing returns nothing
        local timer t = GetExpiredTimer()
        local integer i = GetHandleId(t)
        call SetUnitFacing(uToMove.unit[i], toface.real[i])
        call DestroyTimer(t)
        set t = null
    endfunction
    
    private function IsMoving takes nothing returns nothing
        local timer t = GetExpiredTimer()
        local integer i = GetHandleId(t)
        local unit u = uToMove.unit[i]
        local real ux = GetUnitX(u)
        local real uy = GetUnitY(u)
        local integer newi = 0
        
        //last unit x/y
        local real lux = unitCoords.real[i]
        local real luy = unitCoords.real[-i]
        
        //if the distance from current units position is different then it was before:
        //btw, this is a lot faster then square rooting those numbers
        if ux*ux + uy*uy == lux*lux + luy*luy then
            
            //if the unit is near the position it should be:
            if IsAprox(ux, point.real[i]) and IsAprox(uy, point.real[-i]) then
                
                call PauseTimer(t)
                call DestroyTimer(t)
                set t = CreateTimer()
                set newi = GetHandleId(t)
                set toface.real[newi] = toface.real[i]
                set uToMove.unit[newi] = uToMove.unit[i]
                call TimerStart(t, toWait.real[i], false, function UpdateFacing)
                
            else    //if not, issue the unit to move further
                
                //debug safety:
                
                //if the unit is unable to get to the point in certain number of tries, it will
                //destroy this stuff
                
                static if DEBUG_MODE then
                    
                    set ddata.tries[i] = ddata.tries[i] + 1
                    
                    if ddata.tries[i] >= tofailtries then
                        call PauseTimer(t)
                        call DestroyTimer(t)
                    endif
                    
                endif
                
                //didnt test this, but It should work well
                //unless there is unit already standing there, in which there is debug safety
                //which will destroy the timers etc after certain time(above, its debug safety actually)
                
                
                //in case you are using debug mode, this will prevent the unit to move the location
                //another time if the timer is already destroyed(from above in the debug_mode peace of code)
                debug if t != null then
                
                    call IssuePointOrderById(u, order_move, point.real[i], point.real[-i])
                
                debug endif
                
            endif
            
        else    //if not
            
            //update the units positions
            set unitCoords.real[i] = ux
            set unitCoords.real[-i] = uy
        endif
        set t = null
        set u = null
    endfunction
    
    function MoveUnitWaitFacing takes unit tomove, real locx, real locy, real facing, real wait returns nothing
        local timer t
        local integer i
        if tomove != null then
            set t = CreateTimer()
            set i = GetHandleId(t)
            call IssuePointOrderById(tomove, order_move, locx, locy)
            set toface.real[i] = facing
            set uToMove.unit[i] = tomove
            set toWait.real[i] = wait
            set point.real[i] = locx
            
            //I have test it, it should work
            set point.real[-i] = locy
            
            set ddata.tries[i] = 0
            
            //units current coordinates
            set unitCoords.real[i] = GetUnitX(tomove)
            set unitCoords.real[-i] = GetUnitY(tomove)
            
            //we are going to check every 0.1 seconds, dont want it ot be too heavy and
            //it should give unit enough time when it comes to pathing blocker to realize
            //there is some other way around
            call TimerStart(t, 0.1, true, function IsMoving)
        endif
        set t = null
    endfunction
    
    //remove this if you are not testing it
    private function test takes nothing returns nothing
        local unit u1 = CreateUnit(Player(0), 'hfoo', -100, -100, 0)
        local unit u2 = CreateUnit(Player(0), 'hfoo', -200, -100, 0)
        local unit u3 = CreateUnit(Player(0), 'hfoo', -300, -100, 0)
        local unit u4 = CreateUnit(Player(0), 'hfoo', -400, -100, 0)
        call MoveUnitWaitFacing(u1, -100, GetUnitY(u1) + 100, 270., 1)
        call MoveUnitWaitFacing(u2, -200, GetUnitY(u2) + 100, 270., 1)
        call MoveUnitWaitFacing(u3, -300, GetUnitY(u3) + 100, 270., 1)
        call MoveUnitWaitFacing(u4, -400, GetUnitY(u4) + 100, 270., 1)
    endfunction
    
    private function init takes nothing returns nothing
        set uToMove = Table.create()
        set toface = Table.create()
        set toWait = Table.create()
        set point = Table.create()
        set unitCoords = Table.create()
        //also remove this call
        call test()
    endfunction

endlibrary

And Ive used your way of doing it Ruler(checking if the unit is moving)
and it also should have quite good safety
 
Last edited:
Status
Not open for further replies.
Top