1. Are you planning to upload your awesome spell or system to Hive? Please review the rules here.
    Dismiss Notice
  2. The mythological era has spawned some interesting characters around. Check them out and be sure to vote for them in the 30th Poll of the Texturing Contest.
    Dismiss Notice
  3. The 20th iteration of the Terraining Contest is upon us! Join and create exquisite Water Structures for it.
    Dismiss Notice
  4. Hivers united and created a bunch of 2v2 melee maps. Vote for the best in our Melee Mapping Contest #4 - Poll!
    Dismiss Notice
  5. Check out the Staff job openings thread.
    Dismiss Notice

Trigger Viewer

Is Unit Moving with events.w3x
Variables
Is Unit Moving
Is Unit Moving Config
Is Unit Moving
Unit Indexer
Unit Indexer
Test
Startup
On Move
On Stop
Display

		
Name Type Is Array Initial Value
IsUnitPreplaced boolean Yes
UDex integer No
UDexGen integer No
UDexNext integer Yes
UDexPrev integer Yes
UDexRecycle integer No
UDexUnits unit Yes
UDexWasted integer No
UMovNext integer Yes
UMovPrev integer Yes
UnitIndexerEnabled boolean No
UnitIndexEvent real No
UnitMovementInterval real No
UnitMoving boolean Yes
UnitMovingEvent real No
UnitMovingX real Yes
UnitMovingY real Yes
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
    -------- --------
    -------- Do not enable the following lines as they simply exist to make the variable copying easier --------
    Set UnitMoving[UMovNext[UMovPrev[0]]] = False
    Set UnitMovingEvent = (UnitMovingX[0] + UnitMovingY[0])
//TESH.scrollpos=75
//TESH.alwaysfold=0
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

 
This trigger works in two key phases:

1) During map initialization, enumerate all existing units of all players to give them an index.
2) Adds a second event to itself to index new units as they enter the map.

As a unit enters the map, check for any old units that may have been removed at some point in order to free their index.
Unit Indexer
  Events
    Map initialization
  Conditions
  Actions
    Custom script: call ExecuteFunc("InitializeUnitIndexer")
    Custom script: endfunction
    -------- --------
    -------- This is the core function - it provides an index all existing units and for units as they enter the map --------
    -------- --------
    Custom script: function IndexUnit takes nothing returns boolean
    Custom script: local integer pdex = udg_UDex
    Custom script: local integer ndex
    If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      If - Conditions
        IsUnitPreplaced[0] Equal to False
      Then - Actions
        -------- --------
        -------- Check for removed units for every (32) new units created --------
        -------- --------
        Set UDexWasted = (UDexWasted + 1)
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          If - Conditions
            UDexWasted Equal to 32
          Then - Actions
            Set UDexWasted = 0
            Set UDex = UDexNext[0]
            Custom script: loop
            Custom script: exitwhen udg_UDex == 0
            If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              If - Conditions
                (Custom value of UDexUnits[UDex]) Equal to 0
              Then - Actions
                -------- --------
                -------- Remove index from linked list --------
                -------- --------
                Custom script: set ndex = udg_UDexNext[udg_UDex]
                Custom script: set udg_UDexNext[udg_UDexPrev[udg_UDex]] = ndex
                Custom script: set udg_UDexPrev[ndex] = udg_UDexPrev[udg_UDex]
                Set UDexPrev[UDex] = 0
                Set IsUnitPreplaced[UDex] = False
                -------- --------
                -------- Fire deindex event for UDex --------
                -------- --------
                Set UnitIndexEvent = 2.00
                Set UnitIndexEvent = 0.00
                -------- --------
                -------- Recycle the index for later use --------
                -------- --------
                Set UDexUnits[UDex] = No unit
                Set UDexNext[UDex] = UDexRecycle
                Set UDexRecycle = UDex
                Custom script: set udg_UDex = ndex
              Else - Actions
                Set UDex = UDexNext[UDex]
            Custom script: endloop
          Else - Actions
      Else - Actions
    -------- --------
    -------- You can use the boolean UnitIndexerEnabled to protect some of your undesirable units from being indexed --------
    -------- - Example: --------
    -------- -- Set UnitIndexerEnabled = False --------
    -------- -- Unit - Create 1 Dummy for (Triggering player) at TempLoc facing 0.00 degrees --------
    -------- -- Set UnitIndexerEnabled = True --------
    -------- --------
    -------- You can also customize the following block - if conditions are false the (Matching unit) won't be indexed. --------
    -------- --------
    If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      If - Conditions
        UnitIndexerEnabled Equal to True
        (Custom value of (Matching unit)) Equal to 0
      Then - Actions
        -------- --------
        -------- Generate a unique integer index for this unit --------
        -------- --------
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          If - Conditions
            UDexRecycle Equal to 0
          Then - Actions
            Set UDex = (UDexGen + 1)
            Set UDexGen = UDex
          Else - Actions
            Set UDex = UDexRecycle
            Set UDexRecycle = UDexNext[UDex]
        -------- --------
        -------- Link index to unit, unit to index --------
        -------- --------
        Set UDexUnits[UDex] = (Matching unit)
        Unit - Set the custom value of UDexUnits[UDex] to UDex
        Set IsUnitPreplaced[UDex] = IsUnitPreplaced[0]
        -------- --------
        -------- Use a doubly-linked list to store all active indexes --------
        -------- --------
        Set UDexPrev[UDexNext[0]] = UDex
        Set UDexNext[UDex] = UDexNext[0]
        Set UDexNext[0] = UDex
        -------- --------
        -------- Fire index event for UDex --------
        -------- --------
        Set UnitIndexEvent = 0.00
        Set UnitIndexEvent = 1.00
        Set UnitIndexEvent = 0.00
      Else - Actions
    Custom script: set udg_UDex = pdex
    Custom script: return false
    Custom script: endfunction
    -------- --------
    -------- The next function initializes the core of the system --------
    -------- --------
    Custom script: function InitializeUnitIndexer takes nothing returns nothing
    Custom script: local integer i = 0
    Custom script: local region re = CreateRegion()
    Custom script: local rect r = GetWorldBounds()
    Custom script: local boolexpr b = Filter(function IndexUnit)
    Set UnitIndexEvent = -1.00
    Set UnitIndexerEnabled = True
    Set IsUnitPreplaced[0] = True
    Custom script: call RegionAddRect(re, r)
    Custom script: call TriggerRegisterEnterRegion(CreateTrigger(), re, b)
    Custom script: call RemoveRect(r)
    Custom script: set re = null
    Custom script: set r = null
    Custom script: loop
    Custom script: call GroupEnumUnitsOfPlayer(bj_lastCreatedGroup, Player(i), b)
    Custom script: set i = i + 1
    Custom script: exitwhen i == 16
    Custom script: endloop
    Custom script: set b = null
    -------- --------
    -------- This is the "Unit Indexer Initialized" event, use it instead of "Map Initialization" for best results --------
    -------- --------
    Set IsUnitPreplaced[0] = False
    Set UnitIndexEvent = 3.00
Startup
  Events
    Time - Elapsed game time is 0.00 seconds
  Conditions
  Actions
    Game - Display to (All players) for 900.00 seconds the text: Select a unit to check if it is moving or stopped.
On Move
  Events
    Game - UnitMovingEvent becomes Equal to 1.00
  Conditions
  Actions
    Game - Display to (All players) the text: ((Name of UDexUnits[UDex]) + has started moving!)
On Stop
  Events
    Game - UnitMovingEvent becomes Equal to 2.00
  Conditions
  Actions
    Game - Display to (All players) the text: ((Name of UDexUnits[UDex]) + has stopped moving!)
Display
  Events
    Player - Player 1 (Red) Selects a unit
  Conditions
  Actions
    If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      If - Conditions
        UnitMoving[(Custom value of (Triggering unit))] Equal to True
      Then - Actions
        Game - Display to (All players) the text: ((Name of (Triggering unit)) + is moving)
      Else - Actions
        Game - Display to (All players) the text: ((Name of (Triggering unit)) + is stopped)