function Displacement_Calculate takes nothing returns nothing
local timer t = GetExpiredTimer()
local unit u = GetHandleUnit( t, "u" )
local real x = GetHandleReal( t, "x" )
local real y = GetHandleReal( t, "y" )
local real newx = GetUnitX( u )
local real newy = GetUnitY( u )
local real dx = newx - x
local real dy = newy - y
set udg_distancetraveled = udg_distancetraveled + SquareRoot( dx * dx + dy * dy ) //or some other variable, could be attached with gamecache to timer or unit...w/e
call SetHandleReal( t, "x", newx )
call SetHandleReal( t, "y", newy )
set t = null
set u = null
endfunction
function Distance_Timer takes unit u returns nothing
local timer t = CreateTimer()
call TimerStart( t, 0.05, true, function Displacement_Calculate )
call SetHandleHandle( t, "u", u )
call SetHandleReal( t, "x", GetUnitX( u ) )
call SetHandleReal( t, "y", GetUnitY( u ) )
set t = null
endfunction
struct distancedata
unit u
real x
real y
real d = 0.00
boolean destroyplease = false
endstruct
globals
timer distancetimer = CreateTimer()
distancedata array distancearray
integer distancetotal = 0
endglobals
function Distance_Update takes nothing returns nothing
local distancedata data
local real newx
local real newy
local real dx
local real dy
local integer counter = 0
loop
exitwhen ( counter >= distancetotal )
set data = distancearray[counter]
if ( data.destroyplease ) then
//struct (tracking) is slated for destruction, so rearrange array members so you don't get gaps in the array and then destroy struct
set distancearray[counter] = distancearray[distancetotal - 1]
set distancetotal = distancetotal - 1
call data.destroy()
set counter = counter - 1 //because of the way we rearranged the array members, we need to make sure ALL members get checked
else
set newx = GetUnitX( data.u )
set newy = GetUnitY( data.u )
set dx = newx - data.x
set dy = newy - data.y
set data.d = data.d + SquareRoot( dx * dx + dy * dy ) //update distance
//update your unit coordinates
set data.x = newx
set data.y = newy
endif
set counter = counter + 1
endloop
if ( distancetotal == 0 ) then
//if no units are being tracked, running timer is useless and wastes memory, so pause timer
call PauseTimer( distancetimer )
endif
endfunction
function Distance_AddUnitTracking takes unit u returns nothing //call this function to add unit tracking
local distancedata data = distancedata.create()
set data.u = u
set data.x = GetUnitX( u )
set data.y = GetUnitY( u )
call SetUnitUserData( u, data ) //since structs are integer arrays, we can save them in unit's Custom Value
if ( distancetotal == 0 ) then
call TimerStart( distancetimer, 0.04, true, function Distance_Update )
//if there were no other units being tracked (i.e. timer was paused), start the timer
endif
//update your array variables
set distancearray[distancetotal] = data
set distancetotal = distancetotal + 1
endfunction
function GetDistanceTraveled takes unit u returns real //use this function to get the distance traveled
local distancedata data = GetUnitUserData( u )
return data.d
endfunction
function Distance_ResetTracking takes unit u returns boolean //use this function to reset a unit's tracking (setting distance to 0); you can achieve same effect by destroying tracking and adding another one but this way is more efficient
local distancedata data = GetUnitUserData( u )
set data.d = 0.00
return ( data.d == 0.00 ) //will return true if it successfully resets distance
endfunction
function Distance_DestroyTracking takes unit u returns boolean //call this if you want to disable tracking, this is strongly recommended as it will free up memory
local distancedata data = GetUnitUserData( u )
set data.destroyplease = true
return data.destroyplease //will return true if it sucessfully sets up tracking to be destroyed
endfunction
struct distancedata
unit u
real x
real y
real d = 0.00
real destroydelay = 0.00
boolean dead = false
boolean destroyplease = false
method onDestroy takes nothing returns nothing
call SetUnitUserData( .u, 0 )
endmethod
endstruct
globals
timer distancetimer = CreateTimer()
distancedata array distancearray
integer distancetotal = 0
endglobals
function Distance_Update takes nothing returns nothing
local distancedata data
local real newx
local real newy
local real dx
local real dy
local integer counter = 0
loop
exitwhen ( counter >= distancetotal )
set data = distancearray[counter]
if ( data.destroyplease ) then
//struct (tracking) is slated for destruction, so rearrange array members so you don't get gaps in the array and then destroy struct
set distancearray[counter] = distancearray[distancetotal - 1]
set distancetotal = distancetotal - 1
call data.destroy()
set counter = counter - 1 //because of the way we rearranged the array members, we need to make sure ALL members get checked
else
if ( data.dead ) then
//if unit is dead, we check to see if delay time is 0; if it is we slate struct for destruction, else we countdown the delay
if ( data.destroydelay <= 0.00 ) then
set data.destroyplease = true
else
set data.destroydelay = data.destroydelay - 0.04
endif
else
set newx = GetUnitX( data.u )
set newy = GetUnitY( data.u )
set dx = newx - data.x
set dy = newy - data.y
set data.d = data.d + SquareRoot( dx * dx + dy * dy ) //update distance
//update your unit coordinates
set data.x = newx
set data.y = newy
if ( GetWidgetLife( data.u ) < 0.405 ) then
//if unit is dead, it obviously can't move anymore, so we slate the struct (tracking) for destruction after the delay time
set data.dead = true
endif
endif
endif
set counter = counter + 1
endloop
if ( distancetotal == 0 ) then
//if no units are being tracked, running timer is useless and wastes memory, so pause timer
call PauseTimer( distancetimer )
endif
endfunction
function Distance_AddUnitTracking takes unit u, real destroydelay returns nothing //call this function to add unit tracking
//unit u is the unit to add the tracking to; real destroydelay is the time (in seconds) after the unit dies that the tracking is automatically destroyed
local distancedata data = distancedata.create()
set data.u = u
set data.x = GetUnitX( u )
set data.y = GetUnitY( u )
set data.destroydelay = destroydelay
call SetUnitUserData( u, data ) //since structs are integer arrays, we can save them in unit's Custom Value
if ( distancetotal == 0 ) then
call TimerStart( distancetimer, 0.04, true, function Distance_Update )
//if there were no other units being tracked (i.e. timer was paused), start the timer
endif
//update your array variables
set distancearray[distancetotal] = data
set distancetotal = distancetotal + 1
endfunction
function GetDistanceTraveled takes unit u returns real //use this function to get the distance traveled
local distancedata data = GetUnitUserData( u )
return data.d
endfunction
function Distance_ResetTracking takes unit u returns boolean //use this function to reset a unit's tracking (setting distance to 0); you can achieve same effect by destroying tracking and adding another one but this way is more efficient
local distancedata data = GetUnitUserData( u )
if ( data == 0 ) then
return false //if no tracking exists on that unit, return false
endif
set data.d = 0.00
return ( data.d == 0.00 ) //will return true if it successfully resets distance
endfunction
function Distance_DestroyTracking takes unit u returns boolean //call this if you want to disable tracking, this is strongly recommended as it will free up memory
local distancedata data = GetUnitUserData( u )
if ( data == 0 ) then
return false //if no tracking exists on that unit, return false
endif
set data.destroyplease = true
return ( data.destroyplease ) //will return true if it sucessfully sets up tracking to be destroyed
endfunction