Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- library MotionSensor /* v1.4
- */requires /*
- */GlobalUtils /*
- */PeriodicEvent /*
- */Unit /*
- */UnitList /*
- */UnitIndexerEvents /*
- */Event /*
- */Trigger /*
- */BooleanExpression /*
- */Initializer /*
- */Debug /*
- *///! novjass
- _____________
- | |
- | Author: AGD |
- |_____________|
- /* This simple system allows you to check if the current motion
- a unit is stationary or in motion (This includes triggered
- motion). You can also use this to get the instantaneous speed
- of a unit and its direction of motion. This also allows you to
- detect a change in motion event i.e. when either a unit in
- motion stops or a stationary unit moves. Furthermore, the system
- includes many other utilities regarding unit motion. */
- |==============|
- | Struct API |
- |==============|
- struct Sensor
- readonly boolean flag /* Checks if the Sensor instance is registered */
- readonly boolean moving /* Checks if it is moving or not */
- readonly real speed /* The instantaneous speed */
- readonly real direction /* The direction of motion */
- readonly real deltaX /* X component of the instantaneous speed */
- readonly real deltaY /* Y component of the instantaneous speed */
- readonly real prevX /* The previous x-coordinate */
- readonly real prevY /* The previous y-coordinate */
- readonly static unit triggerUnit /* The motion changing unit */
- readonly static real newMotionState /* The current motion state of the motion changing unit */
- static method operator [] takes unit u returns Sensor/*
- - Returns a Sensor instance based on the unit parameter
- */static method operator []= takes unit u, boolean flag returns nothing/*
- - Registers/Unregisters a unit to the system
- */static method operator enabled takes nothing returns boolean/*
- - Checks if the Motion Sensor is enabled or disabled
- */static method operator enabled= takes boolean flag returns nothing/*
- - Enables/Disables the Motion Sensor
- */static method registerMotionChangeEvent takes code c returns nothing/*
- - Adds a code to run during a motion change event
- */static method registerMotionStartEvent takes code c returns nothing/*
- - Adds a code to run when a unit stops moving
- */static method registerMotionStopEvent takes code c returns nothing/*
- - Adds a code to run when a stationary unit moves
- */static method unregisterMotionChangeEvent takes code c returns nothing/*
- - Removes a code from the motion change event
- */static method unregisterMotionStartEvent takes code c returns nothing/*
- - Removes a code from the motion start event
- */static method unregisterMotionStopEvent takes code c returns nothing/*
- - Removes a code from the motion stop event
- */static method triggerRegisterMotionChangeEvent takes Trigger t returns nothing/*
- - Registers a Trigger to run on a motion change event
- */static method triggerRegisterMotionStartEvent takes Trigger t returns nothing/*
- - Registers a Trigger to run on a motion start event
- */static method triggerRegisterMotionStopEvent takes Trigger t returns nothing/*
- - Registers a Trigger to run on a motion stop event
- */static method triggerUnregisterMotionChangeEvent takes Trigger t returns nothing/*
- - Unregisters a Trigger from the motion change event
- */static method triggerUnregisterMotionStartEvent takes Trigger t returns nothing/*
- - Unregisters a Trigger from the motion start event
- */static method triggerUnregisterMotionStopEvent takes Trigger t returns nothing/*
- - Unregisters a Trigger from the motion stop event */
- |================|
- | Function API |
- |================|
- /* All these functions inline when DEBUG_MODE is OFF except for
- RegisterEvent functions which was done intentionally to allow
- users to pass code that returns nothing
- */function GetInstantaneousSpeed takes unit u returns real/*
- - Returns the instantaneous speed of a unit
- */function GetMotionDirection takes unit u returns real/*
- - Returns the current direction of a unit's motion
- */function GetUnitDeltaX takes unit u returns real/*
- */function GetUnitDeltaY takes unit u returns real/*
- - Returns the x/y-component of a unit's instantaneous velocity
- */function GetUnitPreviousX takes unit u returns real/*
- */function GetUnitPreviousY takes unit u returns real/*
- - Returns the previous x/y-coordinate of the unit
- */function IsUnitMoving takes unit u returns boolean/*
- - Checks if a unit is currently moving or not
- */function IsUnitSensored takes unit u returns boolean/*
- - Checks if a unit is registered to the system or not
- */function RegisterMotionChangeEvent takes code c returns nothing/*
- */function UnregisterMotionChangeEvent takes code c returns nothing/*
- - Registers a code to run on a motion change event / Unregisters it
- */function RegisterMotionStartEvent takes code c returns nothing/*
- */function UnregisterMotionStartEvent takes code c returns nothing/*
- - Registers a code to run when a stationary unit moves / Unregisters it
- */function RegisterMotionStopEvent takes code c returns nothing/*
- */function UnregisterMotionStopEvent takes code c returns nothing/*
- - Registers a code to run when a unit in motion stops / Unregisters it
- */function TriggerRegisterMotionChangeEvent takes Trigger t returns nothing/*
- */function TriggerUnregisterMotionChangeEvent takes Trigger t returns nothing/*
- - Registers a Trigger to run on a motion change event / Unregisters it
- */function TriggerRegisterMotionStartEvent takes Trigger t returns nothing/*
- */function TriggerUnregisterMotionStartEvent takes Trigger t returns nothing/*
- - Registers a Trigger to run when a stationary unit moves
- */function TriggerRegisterMotionStopEvent takes Trigger t returns nothing/*
- */function TriggerUnregisterMotionStopEvent takes Trigger t returns nothing/*
- - Registers a Trigger to run when a unit in motion stops
- */function SensorAddUnit takes unit u returns nothing
- function SensorRemoveUnit takes unit u returns nothing/*
- - Registers/Unregisters a unit to the system
- */function GetNewMotionState takes nothing returns real/*
- - Refers to the current motion of the motion changing unit
- */function GetMotionChangingUnit takes nothing returns unit/*
- - Refers to the motion changing unit
- */function MotionSensorEnable takes nothing returns nothing
- function MotionSensorDisable takes nothing returns nothing/*
- - Switches the motion sensor ON/OFF
- */function IsSensorEnabled takes nothing returns boolean/*
- - Checks if the system is enabled of disabled */
- |===========|
- | Constants |
- |===========|
- Integers:
- integer MOTION_STATE_MOVING
- integer MOTION_STATE_STATIONARY
- /* You can use these constants to check what is the new motion state
- of the event like so: */
- if GetNewMotionState() == MOTION_STATE_MOVING then
- call KillUnit(GetMotionChangingUnit())
- elseif GetNewMotionState() == MOTION_STATE_STATIONARY then
- call RemoveUnit(GetMotionChangingUnit())
- endif
- |=========|
- | Modules |
- |=========|
- module MotionChangeEvent/*
- - You should implement this below your static methods named
- onMotionChange, onMotionStart, and onMotionStop if you have
- any. Otherwise, it will generate extra code which is not so
- good.
- - If static methods any of the specified methods is found
- in your struct, this will automatically register them to run
- on their corresponding motion change events. */
- //! endnovjass
- /*=========================== Configuration ===========================*/
- globals
- /* Unit position check interval (Values greater than 0.03
- causes a bit of inaccuracy in the given instantaneous
- speed of a unit. As the value lowers, the accuracy
- increases at the cost of performance.) */
- private constant real TIMEOUT = 0.03
- /* Set to true if you want the system to automatically
- register units upon entering the map. Set to false if
- you want to manually register units. */
- private constant boolean AUTO_REGISTER_UNITS = true
- endglobals
- /*======================= End of Configuration ========================*/
- /* Do not change anything below this line if you're not so sure on */
- /* what you're doing. */
- /*=====================================================================*/
- private keyword Init
- globals
- constant integer MOTION_STATE_MOVING = 1
- constant integer MOTION_STATE_STATIONARY = 2
- endglobals
- struct Sensor extends array
- readonly boolean sensored
- readonly boolean moving
- readonly real speed
- readonly real direction
- readonly real deltaX
- readonly real deltaY
- readonly real prevX
- readonly real prevY
- readonly static unit triggerUnit
- readonly static real newMotionState
- private static Period period
- private static BoolExpr periodicExpr
- private static Trigger onMoveTrigger
- private static Trigger onStopTrigger
- private static UnitList sensorList
- private static boolean isEnabled
- private static boolean prevState
- private static real tempX
- private static real tempY
- private static real unitX
- private static real unitY
- private static thistype uDex
- implement Debug
- private static method periodic takes nothing returns nothing
- local UnitList this = sensorList.next
- loop
- exitwhen this == 0
- set Global.unit = this.unit
- set uDex = GetUnitId(Global.unit)
- set prevState = uDex.moving
- set unitX = GetUnitX(Global.unit)
- set unitY = GetUnitY(Global.unit)
- set tempX = unitX - uDex.prevX
- set tempY = unitY - uDex.prevY
- set uDex.prevX = unitX
- set uDex.prevY = unitY
- set uDex.deltaX = tempX
- set uDex.deltaY = tempY
- set uDex.speed = SquareRoot(tempX*tempX + tempY*tempY)/TIMEOUT
- set uDex.direction = bj_RADTODEG*Atan2(tempY, tempX)
- set uDex.moving = uDex.speed > 0.00
- if prevState != uDex.moving then
- set triggerUnit = Global.unit
- set newMotionState = 0.00
- if uDex.moving then
- set newMotionState = MOTION_STATE_MOVING
- call onMoveTrigger.fire()
- else
- set newMotionState = MOTION_STATE_STATIONARY
- call onStopTrigger.fire()
- endif
- set newMotionState = 0.00
- endif
- set this = this.next
- endloop
- endmethod
- static method operator enabled takes nothing returns boolean
- return isEnabled
- endmethod
- static method operator enabled= takes boolean flag returns nothing
- set isEnabled = flag
- if flag then
- if sensorList.next != 0 then
- call period.register(periodicExpr)
- endif
- debug call debug("Motion sensor is turned ON")
- else
- call period.unregister(periodicExpr)
- debug call debug("Motion sensor is turned OFF")
- endif
- endmethod
- static method operator [] takes unit u returns thistype
- debug if not thistype(GetUnitId(u)).sensored then
- debug call debug("|CFFFF0000Operator [] error: Attempt to use an unregistered instance|R")
- debug return 0
- debug endif
- return GetUnitId(u)
- endmethod
- static method operator []= takes unit u, boolean flag returns nothing
- if u != null then
- set uDex = GetUnitId(u)
- if flag then
- debug if uDex.sensored then
- debug call debug("|CFFFF0000Operator []= error: Attempt to double register an instance|R")
- debug return
- debug endif
- /* Enable the Sensor iterator again when the sensorGroup is not anymore empty */
- if sensorList.next == 0 then
- call period.register(periodicExpr)
- endif
- call sensorList.addUnit(u)
- /* Initialize prevX and prevY for the newly registered unit to
- prevent it from causing a motion change event false positive */
- set uDex.prevX = GetUnitX(u)
- set uDex.prevY = GetUnitY(u)
- else
- debug if not uDex.sensored then
- debug call debug("|CFFFF0000Operator []= error: Attempt to unregister an already unregistered instance|R")
- debug return
- debug endif
- call sensorList.removeUnit(u)
- /* If sensorGroup is empty, stop iterating */
- if enabled and sensorList.next == 0 then
- call period.unregister(periodicExpr)
- endif
- set uDex.moving = false
- set uDex.deltaX = 0.00
- set uDex.deltaY = 0.00
- set uDex.prevX = 0.00
- set uDex.prevY = 0.00
- set uDex.speed = 0.00
- set uDex.direction = 0.00
- endif
- set uDex.sensored = flag
- debug else
- debug call debug("|CFFFF0000Operator []= error: Attempt to register a null unit|R")
- endif
- endmethod
- static method registerMotionChangeEvent takes code c returns nothing
- call onMoveTrigger.addCondition(BoolExpr[c])
- call onStopTrigger.addCondition(BoolExpr[c])
- endmethod
- static method registerMotionStartEvent takes code c returns nothing
- call onMoveTrigger.addCondition(BoolExpr[c])
- endmethod
- static method registerMotionStopEvent takes code c returns nothing
- call onStopTrigger.addCondition(BoolExpr[c])
- endmethod
- static method unregisterMotionChangeEvent takes code c returns nothing
- call onMoveTrigger.removeCondition(BoolExpr[c])
- call onStopTrigger.removeCondition(BoolExpr[c])
- endmethod
- static method unregisterMotionStartEvent takes code c returns nothing
- call onMoveTrigger.removeCondition(BoolExpr[c])
- endmethod
- static method unregisterMotionStopEvent takes code c returns nothing
- call onStopTrigger.removeCondition(BoolExpr[c])
- endmethod
- static method triggerRegisterMotionChangeEvent takes Trigger t returns nothing
- call onMoveTrigger.hook(t)
- call onStopTrigger.hook(t)
- endmethod
- static method triggerRegisterMotionStartEvent takes Trigger t returns nothing
- call onMoveTrigger.hook(t)
- endmethod
- static method triggerRegisterMotionStopEvent takes Trigger t returns nothing
- call onStopTrigger.hook(t)
- endmethod
- static method triggerUnregisterMotionChangeEvent takes Trigger t returns nothing
- call onMoveTrigger.unhook(t)
- call onStopTrigger.unhook(t)
- endmethod
- static method triggerUnregisterMotionStartEvent takes Trigger t returns nothing
- call onMoveTrigger.unhook(t)
- endmethod
- static method triggerUnregisterMotionStopEvent takes Trigger t returns nothing
- call onStopTrigger.unhook(t)
- endmethod
- static if AUTO_REGISTER_UNITS then
- private static method onIndex takes nothing returns nothing
- set thistype[GetIndexedUnit()] = true
- endmethod
- endif
- private static method onDeindex takes nothing returns nothing
- static if AUTO_REGISTER_UNITS then
- set thistype[GetIndexedUnit()] = false
- else
- if thistype(Unit.index).sensored then
- set thistype[GetIndexedUnit()] = false
- endif
- endif
- endmethod
- private static method init takes nothing returns nothing
- set period = Period[TIMEOUT]
- set periodicExpr = BoolExpr[function thistype.periodic]
- set onMoveTrigger = Trigger.create()
- set onStopTrigger = Trigger.create()
- set sensorList = UnitList.create()
- /* Turn on Sensor */
- set enabled = true
- endmethod
- implement UnitIndexerEvents
- implement Initializer
- endstruct
- module MotionChangeEvent
- static if thistype.onMotionChange.exists and thistype.onMotionStart.exists and thistype.onMotionStop.exists then
- private static method onInit takes nothing returns nothing
- call RegisterMotionChangeEvent(function thistype.onMotionChange)
- call RegisterMotionStartEvent(function thistype.onMotionStart)
- call RegisterMotionStopEvent(function thistype.onMotionStop)
- endmethod
- elseif thistype.onMotionChange.exists and thistype.onMotionStart.exists then
- private static method onInit takes nothing returns nothing
- call RegisterMotionChangeEvent(function thistype.onMotionChange)
- call RegisterMotionStartEvent(function thistype.onMotionStart)
- endmethod
- elseif thistype.onMotionChange.exists and thistype.onMotionStop.exists then
- private static method onInit takes nothing returns nothing
- call RegisterMotionChangeEvent(function thistype.onMotionChange)
- call RegisterMotionStopEvent(function thistype.onMotionStop)
- endmethod
- elseif thistype.onMotionStart.exists and thistype.onMotionStop.exists then
- private static method onInit takes nothing returns nothing
- call RegisterMotionStartEvent(function thistype.onMotionStart)
- call RegisterMotionStopEvent(function thistype.onMotionStop)
- endmethod
- elseif thistype.onMotionChange.exists then
- private static method onInit takes nothing returns nothing
- call RegisterMotionChangeEvent(function thistype.onMotionChange)
- endmethod
- elseif thistype.onMotionStart.exists then
- private static method onInit takes nothing returns nothing
- call RegisterMotionStartEvent(function thistype.onMotionStart)
- endmethod
- elseif thistype.onMotionStop.exists then
- private static method onInit takes nothing returns nothing
- call RegisterMotionStopEvent(function thistype.onMotionStop)
- endmethod
- endif
- endmodule
- /*=====================================================================*/
- function RegisterMotionChangeEvent takes code c returns nothing
- call Sensor.registerMotionChangeEvent(c)
- endfunction
- function RegisterMotionStartEvent takes code c returns nothing
- call Sensor.registerMotionStartEvent(c)
- endfunction
- function RegisterMotionStopEvent takes code c returns nothing
- call Sensor.registerMotionStopEvent(c)
- endfunction
- function UnregisterMotionChangeEvent takes code c returns nothing
- call Sensor.unregisterMotionChangeEvent(c)
- endfunction
- function UnregisterMotionStartEvent takes code c returns nothing
- call Sensor.unregisterMotionStartEvent(c)
- endfunction
- function UnregisterMotionStopEvent takes code c returns nothing
- call Sensor.unregisterMotionStopEvent(c)
- endfunction
- function TriggerRegisterMotionChangeEvent takes Trigger t returns nothing
- call Sensor.triggerRegisterMotionChangeEvent(t)
- endfunction
- function TriggerRegisterMotionStartEvent takes Trigger t returns nothing
- call Sensor.triggerRegisterMotionStartEvent(t)
- endfunction
- function TriggerRegisterMotionStopEvent takes Trigger t returns nothing
- call Sensor.triggerRegisterMotionStopEvent(t)
- endfunction
- function TriggerUnregisterMotionChangeEvent takes Trigger t returns nothing
- call Sensor.triggerUnregisterMotionChangeEvent(t)
- endfunction
- function TriggerUnregisterMotionStartEvent takes Trigger t returns nothing
- call Sensor.triggerUnregisterMotionStartEvent(t)
- endfunction
- function TriggerUnregisterMotionStopEvent takes Trigger t returns nothing
- call Sensor.triggerUnregisterMotionStopEvent(t)
- endfunction
- function SensorAddUnit takes unit u returns nothing
- set Sensor[u] = true
- endfunction
- function SensorRemoveUnit takes unit u returns nothing
- set Sensor[u] = false
- endfunction
- function GetMotionChangingUnit takes nothing returns unit
- return Sensor.triggerUnit
- endfunction
- function GetNewMotionState takes nothing returns real
- return Sensor.newMotionState
- endfunction
- function GetInstantaneousSpeed takes unit u returns real
- return Sensor[u].speed
- endfunction
- function GetUnitDeltaX takes unit u returns real
- return Sensor[u].deltaX
- endfunction
- function GetUnitDeltaY takes unit u returns real
- return Sensor[u].deltaY
- endfunction
- function GetUnitPreviousX takes unit u returns real
- return Sensor[u].prevX
- endfunction
- function GetUnitPreviousY takes unit u returns real
- return Sensor[u].prevY
- endfunction
- function GetMotionDirection takes unit u returns real
- return Sensor[u].direction
- endfunction
- function IsUnitMoving takes unit u returns boolean
- return Sensor[u].moving
- endfunction
- function IsUnitSensored takes unit u returns boolean
- return Sensor(GetUnitId(u)).sensored
- endfunction
- function MotionSensorEnable takes nothing returns nothing
- set Sensor.enabled = true
- endfunction
- function MotionSensorDisable takes nothing returns nothing
- set Sensor.enabled = false
- endfunction
- function IsSensorEnabled takes nothing returns boolean
- return Sensor.enabled
- endfunction
- endlibrary
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement