Advertisement
A-G-D

MotionSensor

Feb 9th, 2017
133
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 23.93 KB | None | 0 0
  1. library MotionSensor /* v1.4
  2.  
  3.  
  4. */requires /*
  5.  
  6. */GlobalUtils /*
  7. */PeriodicEvent /*
  8. */Unit /*
  9. */UnitList /*
  10. */UnitIndexerEvents /*
  11. */Event /*
  12. */Trigger /*
  13. */BooleanExpression /*
  14. */Initializer /*
  15. */Debug /*
  16.  
  17.  
  18. *///! novjass
  19. _____________
  20. | |
  21. | Author: AGD |
  22. |_____________|
  23.  
  24. /* This simple system allows you to check if the current motion
  25. a unit is stationary or in motion (This includes triggered
  26. motion). You can also use this to get the instantaneous speed
  27. of a unit and its direction of motion. This also allows you to
  28. detect a change in motion event i.e. when either a unit in
  29. motion stops or a stationary unit moves. Furthermore, the system
  30. includes many other utilities regarding unit motion. */
  31.  
  32.  
  33. |==============|
  34. | Struct API |
  35. |==============|
  36.  
  37. struct Sensor
  38.  
  39. readonly boolean flag /* Checks if the Sensor instance is registered */
  40. readonly boolean moving /* Checks if it is moving or not */
  41. readonly real speed /* The instantaneous speed */
  42. readonly real direction /* The direction of motion */
  43. readonly real deltaX /* X component of the instantaneous speed */
  44. readonly real deltaY /* Y component of the instantaneous speed */
  45. readonly real prevX /* The previous x-coordinate */
  46. readonly real prevY /* The previous y-coordinate */
  47. readonly static unit triggerUnit /* The motion changing unit */
  48. readonly static real newMotionState /* The current motion state of the motion changing unit */
  49.  
  50. static method operator [] takes unit u returns Sensor/*
  51. - Returns a Sensor instance based on the unit parameter
  52.  
  53. */static method operator []= takes unit u, boolean flag returns nothing/*
  54. - Registers/Unregisters a unit to the system
  55.  
  56. */static method operator enabled takes nothing returns boolean/*
  57. - Checks if the Motion Sensor is enabled or disabled
  58.  
  59. */static method operator enabled= takes boolean flag returns nothing/*
  60. - Enables/Disables the Motion Sensor
  61.  
  62. */static method registerMotionChangeEvent takes code c returns nothing/*
  63. - Adds a code to run during a motion change event
  64.  
  65. */static method registerMotionStartEvent takes code c returns nothing/*
  66. - Adds a code to run when a unit stops moving
  67.  
  68. */static method registerMotionStopEvent takes code c returns nothing/*
  69. - Adds a code to run when a stationary unit moves
  70.  
  71. */static method unregisterMotionChangeEvent takes code c returns nothing/*
  72. - Removes a code from the motion change event
  73.  
  74. */static method unregisterMotionStartEvent takes code c returns nothing/*
  75. - Removes a code from the motion start event
  76.  
  77. */static method unregisterMotionStopEvent takes code c returns nothing/*
  78. - Removes a code from the motion stop event
  79.  
  80. */static method triggerRegisterMotionChangeEvent takes Trigger t returns nothing/*
  81. - Registers a Trigger to run on a motion change event
  82.  
  83. */static method triggerRegisterMotionStartEvent takes Trigger t returns nothing/*
  84. - Registers a Trigger to run on a motion start event
  85.  
  86. */static method triggerRegisterMotionStopEvent takes Trigger t returns nothing/*
  87. - Registers a Trigger to run on a motion stop event
  88.  
  89. */static method triggerUnregisterMotionChangeEvent takes Trigger t returns nothing/*
  90. - Unregisters a Trigger from the motion change event
  91.  
  92. */static method triggerUnregisterMotionStartEvent takes Trigger t returns nothing/*
  93. - Unregisters a Trigger from the motion start event
  94.  
  95. */static method triggerUnregisterMotionStopEvent takes Trigger t returns nothing/*
  96. - Unregisters a Trigger from the motion stop event */
  97.  
  98.  
  99. |================|
  100. | Function API |
  101. |================|
  102.  
  103. /* All these functions inline when DEBUG_MODE is OFF except for
  104. RegisterEvent functions which was done intentionally to allow
  105. users to pass code that returns nothing
  106.  
  107. */function GetInstantaneousSpeed takes unit u returns real/*
  108. - Returns the instantaneous speed of a unit
  109.  
  110. */function GetMotionDirection takes unit u returns real/*
  111. - Returns the current direction of a unit's motion
  112.  
  113. */function GetUnitDeltaX takes unit u returns real/*
  114. */function GetUnitDeltaY takes unit u returns real/*
  115. - Returns the x/y-component of a unit's instantaneous velocity
  116.  
  117. */function GetUnitPreviousX takes unit u returns real/*
  118. */function GetUnitPreviousY takes unit u returns real/*
  119. - Returns the previous x/y-coordinate of the unit
  120.  
  121. */function IsUnitMoving takes unit u returns boolean/*
  122. - Checks if a unit is currently moving or not
  123.  
  124. */function IsUnitSensored takes unit u returns boolean/*
  125. - Checks if a unit is registered to the system or not
  126.  
  127. */function RegisterMotionChangeEvent takes code c returns nothing/*
  128. */function UnregisterMotionChangeEvent takes code c returns nothing/*
  129. - Registers a code to run on a motion change event / Unregisters it
  130.  
  131. */function RegisterMotionStartEvent takes code c returns nothing/*
  132. */function UnregisterMotionStartEvent takes code c returns nothing/*
  133. - Registers a code to run when a stationary unit moves / Unregisters it
  134.  
  135. */function RegisterMotionStopEvent takes code c returns nothing/*
  136. */function UnregisterMotionStopEvent takes code c returns nothing/*
  137. - Registers a code to run when a unit in motion stops / Unregisters it
  138.  
  139. */function TriggerRegisterMotionChangeEvent takes Trigger t returns nothing/*
  140. */function TriggerUnregisterMotionChangeEvent takes Trigger t returns nothing/*
  141. - Registers a Trigger to run on a motion change event / Unregisters it
  142.  
  143. */function TriggerRegisterMotionStartEvent takes Trigger t returns nothing/*
  144. */function TriggerUnregisterMotionStartEvent takes Trigger t returns nothing/*
  145. - Registers a Trigger to run when a stationary unit moves
  146.  
  147. */function TriggerRegisterMotionStopEvent takes Trigger t returns nothing/*
  148. */function TriggerUnregisterMotionStopEvent takes Trigger t returns nothing/*
  149. - Registers a Trigger to run when a unit in motion stops
  150.  
  151. */function SensorAddUnit takes unit u returns nothing
  152. function SensorRemoveUnit takes unit u returns nothing/*
  153. - Registers/Unregisters a unit to the system
  154.  
  155. */function GetNewMotionState takes nothing returns real/*
  156. - Refers to the current motion of the motion changing unit
  157.  
  158. */function GetMotionChangingUnit takes nothing returns unit/*
  159. - Refers to the motion changing unit
  160.  
  161. */function MotionSensorEnable takes nothing returns nothing
  162. function MotionSensorDisable takes nothing returns nothing/*
  163. - Switches the motion sensor ON/OFF
  164.  
  165. */function IsSensorEnabled takes nothing returns boolean/*
  166. - Checks if the system is enabled of disabled */
  167.  
  168.  
  169. |===========|
  170. | Constants |
  171. |===========|
  172.  
  173. Integers:
  174. integer MOTION_STATE_MOVING
  175. integer MOTION_STATE_STATIONARY
  176.  
  177. /* You can use these constants to check what is the new motion state
  178. of the event like so: */
  179.  
  180. if GetNewMotionState() == MOTION_STATE_MOVING then
  181. call KillUnit(GetMotionChangingUnit())
  182. elseif GetNewMotionState() == MOTION_STATE_STATIONARY then
  183. call RemoveUnit(GetMotionChangingUnit())
  184. endif
  185.  
  186.  
  187. |=========|
  188. | Modules |
  189. |=========|
  190.  
  191. module MotionChangeEvent/*
  192. - You should implement this below your static methods named
  193. onMotionChange, onMotionStart, and onMotionStop if you have
  194. any. Otherwise, it will generate extra code which is not so
  195. good.
  196. - If static methods any of the specified methods is found
  197. in your struct, this will automatically register them to run
  198. on their corresponding motion change events. */
  199.  
  200.  
  201. //! endnovjass
  202.  
  203. /*=========================== Configuration ===========================*/
  204.  
  205. globals
  206.  
  207. /* Unit position check interval (Values greater than 0.03
  208. causes a bit of inaccuracy in the given instantaneous
  209. speed of a unit. As the value lowers, the accuracy
  210. increases at the cost of performance.) */
  211. private constant real TIMEOUT = 0.03
  212.  
  213. /* Set to true if you want the system to automatically
  214. register units upon entering the map. Set to false if
  215. you want to manually register units. */
  216. private constant boolean AUTO_REGISTER_UNITS = true
  217.  
  218. endglobals
  219.  
  220. /*======================= End of Configuration ========================*/
  221. /* Do not change anything below this line if you're not so sure on */
  222. /* what you're doing. */
  223. /*=====================================================================*/
  224. private keyword Init
  225.  
  226. globals
  227. constant integer MOTION_STATE_MOVING = 1
  228. constant integer MOTION_STATE_STATIONARY = 2
  229. endglobals
  230.  
  231. struct Sensor extends array
  232.  
  233. readonly boolean sensored
  234. readonly boolean moving
  235. readonly real speed
  236. readonly real direction
  237. readonly real deltaX
  238. readonly real deltaY
  239. readonly real prevX
  240. readonly real prevY
  241. readonly static unit triggerUnit
  242. readonly static real newMotionState
  243.  
  244. private static Period period
  245. private static BoolExpr periodicExpr
  246. private static Trigger onMoveTrigger
  247. private static Trigger onStopTrigger
  248. private static UnitList sensorList
  249. private static boolean isEnabled
  250. private static boolean prevState
  251. private static real tempX
  252. private static real tempY
  253. private static real unitX
  254. private static real unitY
  255. private static thistype uDex
  256.  
  257. implement Debug
  258.  
  259. private static method periodic takes nothing returns nothing
  260. local UnitList this = sensorList.next
  261. loop
  262. exitwhen this == 0
  263. set Global.unit = this.unit
  264. set uDex = GetUnitId(Global.unit)
  265. set prevState = uDex.moving
  266. set unitX = GetUnitX(Global.unit)
  267. set unitY = GetUnitY(Global.unit)
  268. set tempX = unitX - uDex.prevX
  269. set tempY = unitY - uDex.prevY
  270. set uDex.prevX = unitX
  271. set uDex.prevY = unitY
  272. set uDex.deltaX = tempX
  273. set uDex.deltaY = tempY
  274. set uDex.speed = SquareRoot(tempX*tempX + tempY*tempY)/TIMEOUT
  275. set uDex.direction = bj_RADTODEG*Atan2(tempY, tempX)
  276. set uDex.moving = uDex.speed > 0.00
  277. if prevState != uDex.moving then
  278. set triggerUnit = Global.unit
  279. set newMotionState = 0.00
  280. if uDex.moving then
  281. set newMotionState = MOTION_STATE_MOVING
  282. call onMoveTrigger.fire()
  283. else
  284. set newMotionState = MOTION_STATE_STATIONARY
  285. call onStopTrigger.fire()
  286. endif
  287. set newMotionState = 0.00
  288. endif
  289. set this = this.next
  290. endloop
  291. endmethod
  292.  
  293. static method operator enabled takes nothing returns boolean
  294. return isEnabled
  295. endmethod
  296.  
  297. static method operator enabled= takes boolean flag returns nothing
  298. set isEnabled = flag
  299. if flag then
  300. if sensorList.next != 0 then
  301. call period.register(periodicExpr)
  302. endif
  303. debug call debug("Motion sensor is turned ON")
  304. else
  305. call period.unregister(periodicExpr)
  306. debug call debug("Motion sensor is turned OFF")
  307. endif
  308. endmethod
  309.  
  310. static method operator [] takes unit u returns thistype
  311. debug if not thistype(GetUnitId(u)).sensored then
  312. debug call debug("|CFFFF0000Operator [] error: Attempt to use an unregistered instance|R")
  313. debug return 0
  314. debug endif
  315. return GetUnitId(u)
  316. endmethod
  317.  
  318. static method operator []= takes unit u, boolean flag returns nothing
  319. if u != null then
  320. set uDex = GetUnitId(u)
  321. if flag then
  322. debug if uDex.sensored then
  323. debug call debug("|CFFFF0000Operator []= error: Attempt to double register an instance|R")
  324. debug return
  325. debug endif
  326. /* Enable the Sensor iterator again when the sensorGroup is not anymore empty */
  327. if sensorList.next == 0 then
  328. call period.register(periodicExpr)
  329. endif
  330. call sensorList.addUnit(u)
  331. /* Initialize prevX and prevY for the newly registered unit to
  332. prevent it from causing a motion change event false positive */
  333. set uDex.prevX = GetUnitX(u)
  334. set uDex.prevY = GetUnitY(u)
  335. else
  336. debug if not uDex.sensored then
  337. debug call debug("|CFFFF0000Operator []= error: Attempt to unregister an already unregistered instance|R")
  338. debug return
  339. debug endif
  340. call sensorList.removeUnit(u)
  341. /* If sensorGroup is empty, stop iterating */
  342. if enabled and sensorList.next == 0 then
  343. call period.unregister(periodicExpr)
  344. endif
  345. set uDex.moving = false
  346. set uDex.deltaX = 0.00
  347. set uDex.deltaY = 0.00
  348. set uDex.prevX = 0.00
  349. set uDex.prevY = 0.00
  350. set uDex.speed = 0.00
  351. set uDex.direction = 0.00
  352. endif
  353. set uDex.sensored = flag
  354. debug else
  355. debug call debug("|CFFFF0000Operator []= error: Attempt to register a null unit|R")
  356. endif
  357. endmethod
  358.  
  359. static method registerMotionChangeEvent takes code c returns nothing
  360. call onMoveTrigger.addCondition(BoolExpr[c])
  361. call onStopTrigger.addCondition(BoolExpr[c])
  362. endmethod
  363.  
  364. static method registerMotionStartEvent takes code c returns nothing
  365. call onMoveTrigger.addCondition(BoolExpr[c])
  366. endmethod
  367.  
  368. static method registerMotionStopEvent takes code c returns nothing
  369. call onStopTrigger.addCondition(BoolExpr[c])
  370. endmethod
  371.  
  372. static method unregisterMotionChangeEvent takes code c returns nothing
  373. call onMoveTrigger.removeCondition(BoolExpr[c])
  374. call onStopTrigger.removeCondition(BoolExpr[c])
  375. endmethod
  376.  
  377. static method unregisterMotionStartEvent takes code c returns nothing
  378. call onMoveTrigger.removeCondition(BoolExpr[c])
  379. endmethod
  380.  
  381. static method unregisterMotionStopEvent takes code c returns nothing
  382. call onStopTrigger.removeCondition(BoolExpr[c])
  383. endmethod
  384.  
  385. static method triggerRegisterMotionChangeEvent takes Trigger t returns nothing
  386. call onMoveTrigger.hook(t)
  387. call onStopTrigger.hook(t)
  388. endmethod
  389.  
  390. static method triggerRegisterMotionStartEvent takes Trigger t returns nothing
  391. call onMoveTrigger.hook(t)
  392. endmethod
  393.  
  394. static method triggerRegisterMotionStopEvent takes Trigger t returns nothing
  395. call onStopTrigger.hook(t)
  396. endmethod
  397.  
  398. static method triggerUnregisterMotionChangeEvent takes Trigger t returns nothing
  399. call onMoveTrigger.unhook(t)
  400. call onStopTrigger.unhook(t)
  401. endmethod
  402.  
  403. static method triggerUnregisterMotionStartEvent takes Trigger t returns nothing
  404. call onMoveTrigger.unhook(t)
  405. endmethod
  406.  
  407. static method triggerUnregisterMotionStopEvent takes Trigger t returns nothing
  408. call onStopTrigger.unhook(t)
  409. endmethod
  410.  
  411. static if AUTO_REGISTER_UNITS then
  412. private static method onIndex takes nothing returns nothing
  413. set thistype[GetIndexedUnit()] = true
  414. endmethod
  415. endif
  416.  
  417. private static method onDeindex takes nothing returns nothing
  418. static if AUTO_REGISTER_UNITS then
  419. set thistype[GetIndexedUnit()] = false
  420. else
  421. if thistype(Unit.index).sensored then
  422. set thistype[GetIndexedUnit()] = false
  423. endif
  424. endif
  425. endmethod
  426.  
  427. private static method init takes nothing returns nothing
  428. set period = Period[TIMEOUT]
  429. set periodicExpr = BoolExpr[function thistype.periodic]
  430. set onMoveTrigger = Trigger.create()
  431. set onStopTrigger = Trigger.create()
  432. set sensorList = UnitList.create()
  433. /* Turn on Sensor */
  434. set enabled = true
  435. endmethod
  436.  
  437. implement UnitIndexerEvents
  438. implement Initializer
  439.  
  440. endstruct
  441.  
  442. module MotionChangeEvent
  443. static if thistype.onMotionChange.exists and thistype.onMotionStart.exists and thistype.onMotionStop.exists then
  444. private static method onInit takes nothing returns nothing
  445. call RegisterMotionChangeEvent(function thistype.onMotionChange)
  446. call RegisterMotionStartEvent(function thistype.onMotionStart)
  447. call RegisterMotionStopEvent(function thistype.onMotionStop)
  448. endmethod
  449. elseif thistype.onMotionChange.exists and thistype.onMotionStart.exists then
  450. private static method onInit takes nothing returns nothing
  451. call RegisterMotionChangeEvent(function thistype.onMotionChange)
  452. call RegisterMotionStartEvent(function thistype.onMotionStart)
  453. endmethod
  454. elseif thistype.onMotionChange.exists and thistype.onMotionStop.exists then
  455. private static method onInit takes nothing returns nothing
  456. call RegisterMotionChangeEvent(function thistype.onMotionChange)
  457. call RegisterMotionStopEvent(function thistype.onMotionStop)
  458. endmethod
  459. elseif thistype.onMotionStart.exists and thistype.onMotionStop.exists then
  460. private static method onInit takes nothing returns nothing
  461. call RegisterMotionStartEvent(function thistype.onMotionStart)
  462. call RegisterMotionStopEvent(function thistype.onMotionStop)
  463. endmethod
  464. elseif thistype.onMotionChange.exists then
  465. private static method onInit takes nothing returns nothing
  466. call RegisterMotionChangeEvent(function thistype.onMotionChange)
  467. endmethod
  468. elseif thistype.onMotionStart.exists then
  469. private static method onInit takes nothing returns nothing
  470. call RegisterMotionStartEvent(function thistype.onMotionStart)
  471. endmethod
  472. elseif thistype.onMotionStop.exists then
  473. private static method onInit takes nothing returns nothing
  474. call RegisterMotionStopEvent(function thistype.onMotionStop)
  475. endmethod
  476. endif
  477. endmodule
  478.  
  479. /*=====================================================================*/
  480.  
  481. function RegisterMotionChangeEvent takes code c returns nothing
  482. call Sensor.registerMotionChangeEvent(c)
  483. endfunction
  484.  
  485. function RegisterMotionStartEvent takes code c returns nothing
  486. call Sensor.registerMotionStartEvent(c)
  487. endfunction
  488.  
  489. function RegisterMotionStopEvent takes code c returns nothing
  490. call Sensor.registerMotionStopEvent(c)
  491. endfunction
  492.  
  493. function UnregisterMotionChangeEvent takes code c returns nothing
  494. call Sensor.unregisterMotionChangeEvent(c)
  495. endfunction
  496.  
  497. function UnregisterMotionStartEvent takes code c returns nothing
  498. call Sensor.unregisterMotionStartEvent(c)
  499. endfunction
  500.  
  501. function UnregisterMotionStopEvent takes code c returns nothing
  502. call Sensor.unregisterMotionStopEvent(c)
  503. endfunction
  504.  
  505. function TriggerRegisterMotionChangeEvent takes Trigger t returns nothing
  506. call Sensor.triggerRegisterMotionChangeEvent(t)
  507. endfunction
  508.  
  509. function TriggerRegisterMotionStartEvent takes Trigger t returns nothing
  510. call Sensor.triggerRegisterMotionStartEvent(t)
  511. endfunction
  512.  
  513. function TriggerRegisterMotionStopEvent takes Trigger t returns nothing
  514. call Sensor.triggerRegisterMotionStopEvent(t)
  515. endfunction
  516.  
  517. function TriggerUnregisterMotionChangeEvent takes Trigger t returns nothing
  518. call Sensor.triggerUnregisterMotionChangeEvent(t)
  519. endfunction
  520.  
  521. function TriggerUnregisterMotionStartEvent takes Trigger t returns nothing
  522. call Sensor.triggerUnregisterMotionStartEvent(t)
  523. endfunction
  524.  
  525. function TriggerUnregisterMotionStopEvent takes Trigger t returns nothing
  526. call Sensor.triggerUnregisterMotionStopEvent(t)
  527. endfunction
  528.  
  529. function SensorAddUnit takes unit u returns nothing
  530. set Sensor[u] = true
  531. endfunction
  532.  
  533. function SensorRemoveUnit takes unit u returns nothing
  534. set Sensor[u] = false
  535. endfunction
  536.  
  537. function GetMotionChangingUnit takes nothing returns unit
  538. return Sensor.triggerUnit
  539. endfunction
  540.  
  541. function GetNewMotionState takes nothing returns real
  542. return Sensor.newMotionState
  543. endfunction
  544.  
  545. function GetInstantaneousSpeed takes unit u returns real
  546. return Sensor[u].speed
  547. endfunction
  548.  
  549. function GetUnitDeltaX takes unit u returns real
  550. return Sensor[u].deltaX
  551. endfunction
  552.  
  553. function GetUnitDeltaY takes unit u returns real
  554. return Sensor[u].deltaY
  555. endfunction
  556.  
  557. function GetUnitPreviousX takes unit u returns real
  558. return Sensor[u].prevX
  559. endfunction
  560.  
  561. function GetUnitPreviousY takes unit u returns real
  562. return Sensor[u].prevY
  563. endfunction
  564.  
  565. function GetMotionDirection takes unit u returns real
  566. return Sensor[u].direction
  567. endfunction
  568.  
  569. function IsUnitMoving takes unit u returns boolean
  570. return Sensor[u].moving
  571. endfunction
  572.  
  573. function IsUnitSensored takes unit u returns boolean
  574. return Sensor(GetUnitId(u)).sensored
  575. endfunction
  576.  
  577. function MotionSensorEnable takes nothing returns nothing
  578. set Sensor.enabled = true
  579. endfunction
  580.  
  581. function MotionSensorDisable takes nothing returns nothing
  582. set Sensor.enabled = false
  583. endfunction
  584.  
  585. function IsSensorEnabled takes nothing returns boolean
  586. return Sensor.enabled
  587. endfunction
  588.  
  589.  
  590. endlibrary
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement