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

Is Unit Moving 2.1.0.0

Credits
Xiliger for the idea.​
Purpose
Detect if a unit is moving or stopped. This works for any​
type of movement (natural, through triggers, etc.)​
Just use the boolean:​
  • UnitMoving[UDex] Equal to true
How to install
  1. Copy and paste the Unit Indexer trigger from the map (if you didn't do so yet)
  2. Copy and paste the Is Unit Moving trigger from the map.
  3. It's installed!

  • Is Unit Moving Config
    • Events
    • Conditions
      • (Default movement speed of UDexUnits[UDex]) Not equal to 0.00
    • Actions
      • -------- Units who do not pass the above conditions will not be allowed to be registered by the system. --------
      • -------- One can add exceptions such as with buildings who have the ability to uproot. --------
      • -------- --------
      • -------- Here you can configure how frequently the check occurs. --------
      • -------- NOTES: This should not be lower than any movement systems in your map. --------
      • -------- Slower checks improve performance, but I wouldn't slow it much more than this. --------
      • -------- --------
      • Set UnitMovementInterval = 0.10
JASS:
function IsUnitMovementTracked takes integer i returns boolean
    return udg_UMovPrev[i] != 0 or udg_UMovNext[0] == i
endfunction
function UnitMovementRegister takes nothing returns boolean
    local integer i = udg_UDex
    if not IsUnitMovementTracked(i) and TriggerEvaluate(gg_trg_Is_Unit_Moving_Config) then
        set udg_UMovPrev[udg_UMovNext[0]] = i
        set udg_UMovNext[i] = udg_UMovNext[0]
        set udg_UMovNext[0] = i
        set udg_UnitMovingX[i] = GetUnitX(udg_UDexUnits[i])
        set udg_UnitMovingY[i] = GetUnitY(udg_UDexUnits[i])
    endif
    return false
endfunction
function UnitMovementUnregister takes nothing returns boolean
    local integer i = udg_UDex
    if IsUnitMovementTracked(i) then
        set udg_UnitMoving[i] = false
        set udg_UMovNext[udg_UMovPrev[i]] = udg_UMovNext[i]
        set udg_UMovPrev[udg_UMovNext[i]] = udg_UMovPrev[i]
        set udg_UMovPrev[i] = 0
    endif
    return false
endfunction
function RunUnitMovementEvent takes integer i, real e returns nothing
    local integer pdex = udg_UDex
    if e == 1.00 then
        set udg_UnitMoving[i] = true
    else
        set udg_UnitMoving[i] = false
    endif
    set udg_UDex = i
    set udg_UnitMovingEvent = e
    set udg_UnitMovingEvent = 0.00
    set udg_UDex = pdex
endfunction
//===========================================================================
// This function runs periodically to check if units are actually moving.
//
function UnitMovementTracker takes nothing returns nothing
    local integer i = 0
    local integer n
    local real x
    local real y
    loop
        set i = udg_UMovNext[i]
        exitwhen i == 0
        set x = GetUnitX(udg_UDexUnits[i])
        set y = GetUnitY(udg_UDexUnits[i])
        if x != udg_UnitMovingX[i] or y != udg_UnitMovingY[i] then
            set udg_UnitMovingX[i] = x
            set udg_UnitMovingY[i] = y
            if not udg_UnitMoving[i] then
                if GetUnitTypeId(udg_UDexUnits[i]) != 0 then
                    call RunUnitMovementEvent(i, 1.00)
                else
                    set n = udg_UDex
                    set udg_UDex = i
                    set i = udg_UMovPrev[i] //avoid skipping checks
                    call UnitMovementUnregister()
                    set udg_UDex = n
                endif
            endif
        elseif udg_UnitMoving[i] then
            call RunUnitMovementEvent(i, 2.00)
        endif
    endloop
endfunction
//===========================================================================
function InitTrig_Is_Unit_Moving takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterVariableEvent(t, "udg_UnitIndexEvent", EQUAL, 1.00)
    call TriggerAddCondition(t, Filter(function UnitMovementRegister))
   
    set t = CreateTrigger()
    call TriggerRegisterVariableEvent(t, "udg_UnitIndexEvent", EQUAL, 2.00)
    call TriggerAddCondition(t, Filter(function UnitMovementUnregister))
   
    if gg_trg_Is_Unit_Moving_Config != null then
        call TriggerExecute(gg_trg_Is_Unit_Moving_Config)
    else
        call ExecuteFunc("Trig_Is_Unit_Moving_Config_Actions")
    endif
    call TimerStart(CreateTimer(), udg_UnitMovementInterval, true, function UnitMovementTracker)
endfunction


  • 1.0.0.0 - Release
  • 1.0.0.1 - Updated the default settings with a 0.5 timer to
    minimize the installation work.
  • 2.0.0.0 - Added OnMove and OnStop events, added a filter for undesirables.
  • 2.1.0.0 - Split into a GUI Config trigger and a JASS engine. This subsequently fixes a couple of bugs while improving performance.


Keywords:
movement, moving, xiliger, isunitmoving, move, detect, unitmoving
Contents

Is Unit Moving Testmap (Map)

Reviews
20:09, 31st Jul 2011 Maker: Approved. Does what it is supposed to, and does it well.

Moderator

M

Moderator

20:09, 31st Jul 2011
Maker: Approved. Does what it is supposed to, and does it well.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
Thanks for the positive feedback. This is based on Xiliger's
idea here: http://www.hiveworkshop.com/forums/graveyard-418/isunitmoving-159724/

I made a number of improvements that I published here:
http://www.hiveworkshop.com/forums/jass-functions-413/system-unit-moving-178341/

That vJass version has extra features like "on move" or "on
stop" events and is a bit more efficient. This version I've
created so that it's easy to pop into a map and start using
right away, as a lot of PC's and (every) Macintosh have
problems running JNGP.
 
Level 16
Joined
Apr 4, 2011
Messages
995
Well I'm pretty sure I can speak for the entire GUI community when I say that having powerful resources like these available for GUI usage is amazing. I'm just getting ready for the tidal wave of spells when people realize how easy spellmaking is with your two new GUI resources :)

Amazing job sir. Well done
 
Level 9
Joined
Jun 25, 2009
Messages
427
Well I'm pretty sure I can speak for the entire GUI community when I say that having powerful resources like these available for GUI usage is amazing. I'm just getting ready for the tidal wave of spells when people realize how easy spellmaking is with your two new GUI resources :)

Amazing job sir. Well done

Yeah, rupture like spells rock! :D http://www.hiveworkshop.com/forums/spells-569/hives-spellpack-v2-1b-183097/ if you like rupture spell, then search for it in this pack ;) sorry for promoting tho.

On the topic: This system is awesome since some spells require this. I wouldn't like to dissapoint you but for me (only me, it's only a personal opinion, don't get mad :p) it's not hard to create for a spell. BUT it's a waste of memory for each single spell to create a new system such as this. I mean 5 triggers running each 0.04 seconds for different spells while with this it can be only one, running at 0.03 ;)

Off the topic: Bribe, I have sent you a personal message but i don't know whether you got it or not. So please, please re-review my spellpack :(

Tiche3
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
This is not meant to replace periodic triggers. It is
meant to provide detection to determine if a unit is
moving or stopped.

Something like this would actually be quite annoying
and innefficient to try to code without the GUI Unit
Indexer system. This is also really easy to use since
the user can do everything he/she needs without any
custom script.
 
Last edited:

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
Right now it checks all units that are indexed by GUI Unit Indexer.

If you wanted to index only certain types of units, I can make this
use its own list that has its own filtering. In fact, that's probably a
good idea to do so. I'll keep that in mind next time I have a chance
to update this thing.


Updated to version 2.0.0.0. This update requires the latest GUI Unit Indexer
to work with its new features.

New features:

Now has "OnMove" and "OnStop" events.
Now runs on its own list, so you can filter out units you don't need to check.

  • Unit Moving Events
    • Events
      • -------- When a unit starts moving: --------
      • Game - UnitMovingEvent becomes Equal to 1.00
      • -------- When a unit stops moving: --------
      • Game - UnitMovingEvent becomes Equal to 2.00
    • Conditions
    • Actions
      • -------- UDexUnits[UDex] refers to the moving/stopped unit --------
 
Last edited:
I'm not going to require mention of Vex's fail optimizer when these are working, native properties of World Editor that are only "broken" because of his fail design. I will not "apologize" for his mistakes.

Stick it to the man! :p

Well, you know, you should at least tell them their map will be unplayable if they optimize it and THEN, you could blame Vex :p
That way, you wouldn't get lots of people complaining in the WEHZ about their unplayable maps :/

Come on :p
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
Most of the GUI populace won't be using the "shorten names" feature of the optimizer as it requires knowledge of common.j and blizzard.j, let alone be using the optimizer itself.

Rather than requiring innocent scripts like this to mention such a thing, the guy who built a buggy program should be the only one who has to give warnings for malfunctions.

Weep's GUI Damage Detection System has always used this event and no one has complained. Using the event for these libraries is just another page in the story.
 
Level 16
Joined
Apr 4, 2011
Messages
995
I don't even know how this would work in a hashtable. Maybe I'm just an idiot, but it seems like Bribe did a fine enough job of it already. This resource and his other one that this relies on are in my map I'm working on, this resource alone is used in 2 spells (one of which I posted)
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
Simple system, could be useful though. Aww this uses the custom value of a unit? Lame =s

Why is it lame? If you are using custom value in another area of your map, you can just change the way you do things:

Instead of:

  • Unit - Set Custom Value of (Triggering unit) to 100
It becomes:

  • Set MyValue[(Custom value of (Triggering unit))] = 100
This way, the custom value can be used for all systems as a simple array point, instead of wasting the custom value on just one little system. That's the beauty of a unit indexing system.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
It really is criminally too easy. Unit Indexers are really popular because of it. AutoIndex is probably the most famous, then AIDS would come next. Nestharus' Unit Indexer is probably the best of them all, but all three of those resources are made in vJass which is why I made GUI Unit Indexer.

This won't use hashtables, it's a lot easier for a user to just get the custom value of a unit. It's also very important to be efficient with this (no hashtable attachment) because there might be hundreds of units being checked, and that can cause lag if I used hashtables.
 
Level 16
Joined
Apr 4, 2011
Messages
995
You should add something that detects when the unit is moving at a high speed or low speed (which could be changed easily by user, around 400 and 100 respecetively). It would be incredibly useful in spells. For example, a spell could give a unit a temporary boost of speed that decreases over time, but as long as it is above X movement speed, the unit is invisible. Something like that would make this system more desireable to have, to me at least.
 

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
  • Custom script: if udg_TempX != udg_UnitMovingX[udg_UDex] or udg_TempY != udg_UnitMovingY[udg_UDex] then
Sir, may I suggest to also check for unit's current order?
  • Custom script: if udg_TempX != udg_UnitMovingX[udg_UDex] or udg_TempY != udg_UnitMovingY[udg_UDex] and GetUnitCurrentOrder(udg_UDexUnits[udg_UDex]) == OrderId("move") then
And I think it's also possible to convert "smart" order to the actual order like "move", "attack", etc.


That's all. Have a good day!
 

Wrda

Spell Reviewer
Level 25
Joined
Nov 18, 2012
Messages
1,864
That will be much worse. A unit could still have an order and not be moving, or a unit could be moving and not have an order.
Yes, but quilnez is right.
First time I used your system and tested it, I checked if a unit tries moves to a point and then order it back would fire the event, and it did. Same thing as for patrol, attack, flags (shift-click). I really got disappointed for this "bug". A unit who is moving but stops moving because of an obstacle or because it received a new order doesn't mean he actually stopped moving. I think that should be fixed. Maybe make 3 events: 1 - stopped moving; 2 - stopped, but will still move; 3 - is moving
 

Wrda

Spell Reviewer
Level 25
Joined
Nov 18, 2012
Messages
1,864
Purpose
Detect if a unit is moving or stopped. This works for any
type of movement (natural, through triggers, etc.)

Just use the boolean:

  • if.gif
    UnitMoving[UDexUnits[UDex]] Equal to true
@Bribe UDexUnits is a unit array, can't have it as an index of UnitMoving (and others). You probably meant UnitMoving[UDex].

Someone on discord was confused about this :)
 
Top