Warcraft 3 documentation

vJASS & Zinc Documentation
For the latest documentation about how it works vJASS and Zinc language layers for Warcraft III, please follow these links:
Jasshelper documentation - Zinc documentation - WC3 Optimizer documentation

UnitIndexer

moyack · 812

0 Members and 1 Guest are viewing this topic.

Rating

Average Score - 4 / 5

« Created: January 18, 2018, 06:53:08 PM by moyack »

UnitIndexer
on: March 21, 2012, 03:44:14 AM
Category: Units, System
Language: vJASS
Download Demo Map

Related Topics or Resources



by

by

by

by

by

by

A library to manage units by indexing them.



Main library:
Code: jass
  1. library UnitIndexer /* v5.3.0.1
  2. ************************************************************************************
  3. *
  4. *       */ uses /*
  5. *
  6. *               */ WorldBounds                  /*
  7. *               */ Init                                 /*
  8. *               */ AllocQ                               /*
  9. *               */ ErrorMessage                 /*
  10. *               */ StaticUniqueList     /*
  11. *               */ UnitIndexerSettings  /*
  12. *               */ Trigger                              /*
  13. *
  14. ********************************************************************************
  15. *
  16. *       struct UnitIndexer extends array
  17. *
  18. *               Fields
  19. *               -------------------------
  20. *
  21. *                       static boolean enabled
  22. *                               -       is UnitIndexer onUnitIndex enabled?
  23. *
  24. *                       readonly static Trigger GlobalEvent.ON_INDEX
  25. *                               -       this is a global event that runs whenever any unit is indexed
  26. *
  27. *                               Examples:       UnitIndexer.GlobalEvent.ON_INDEX.reference(yourTrigger)
  28. *                                                       UnitIndexer.GlobalEvent.ON_INDEX.register(yourCode)
  29. *
  30. *                               Examples:       unitIndex.indexer.Event.ON_DEINDEX.reference(yourTrigger)
  31. *                                                       unitIndex.indexer.Event.ON_DEINDEX.register(yourCode)
  32. *
  33. *                       readonly Trigger Event.ON_DEINDEX
  34. *                               -       this is a local event that runs whenever a specific unit is deindexed
  35. *
  36. *                               Examples:       unitIndex.indexer.Event.ON_DEINDEX.reference(yourTrigger)
  37. *                                                       unitIndex.indexer.Event.ON_DEINDEX.register(yourCode)
  38. *
  39. *                       readonly static Trigger GlobalEvent.ON_DEINDEX
  40. *                               -       this is ON_DEINDEX, but global
  41. *
  42. *                               Examples:       UnitIndexer.GlobalEvent.ON_DEINDEX.reference(yourTrigger)
  43. *                                                       UnitIndexer.GlobalEvent.ON_DEINDEX.register(yourCode)
  44. *
  45. *                       readonly static UnitIndex eventIndex
  46. *                               -       when a unit is indexed or deindexed, this value stores
  47. *                                       the index of that unit
  48. *
  49. *                       readonly static unit eventUnit
  50. *                               -       when a unit is indexed or deindexed, this value stores
  51. *                                       the unit
  52. *
  53. ************************************************************************************
  54. *
  55. *       struct UnitIndex extends array
  56. *
  57. *               Fields
  58. *               -------------------------
  59. *
  60. *                       readonly unit unit
  61. *                               -       converts a unit index into a unit
  62. *
  63. *                       readonly UnitIndexer indexer
  64. *                               -       the indexer in charge of handling the unit
  65. *                                       useful for deindex event, which is unit specific
  66. *
  67. *               Operators
  68. *               -------------------------
  69. *
  70. *                       static method operator [] takes unit whichUnit returns UnitIndex
  71. *                               -       converts a unit into a UnitIndex
  72. *
  73. *               Methods
  74. *               -------------------------
  75. *
  76. *                       static method exists takes unit whichUnit returns boolean
  77. *                               -       determines whether the unit is indexed or not
  78. *
  79. *                       static method isDeindexing takes unit whichUnit returns boolean
  80. *                               -       determines whether the unit is in the process of being deindexed or not
  81. *
  82. ************************************************************************************
  83. *
  84. *       module GlobalUnitIndex
  85. *
  86. *               This has absolutely no module support
  87. *
  88. *               Fields
  89. *               -------------------------
  90. *
  91. *                       static constant boolean GLOBAL_UNIT_INDEX = true
  92. *                               -       this is used to ensure that only one unit index module is implemented.
  93. *
  94. *                       readonly unit unit
  95. *                               -       converts a unit index into a unit
  96. *
  97. *                       readonly boolean isUnitIndexed
  98. *                               -       is the unit index indexed
  99. *
  100. *                       readonly UnitIndexer unitIndexer
  101. *                               -       the indexer in charge of handling the unit
  102. *                                       useful for deindex event, which is unit specific
  103. *
  104. *               Methods
  105. *               -------------------------
  106. *
  107. *                       static method exists takes unit whichUnit returns boolean
  108. *                               -       determines whether the unit is indexed
  109. *
  110. *                       static method isDeindexing takes unit whichUnit returns boolean
  111. *                               -       determines whether the unit is in the process of being deindexed or not
  112. *
  113. *               Interface
  114. *               -------------------------
  115. *
  116. *                       interface private method onUnitIndex takes nothing returns nothing
  117. *                       interface private method onUnitDeindex takes nothing returns nothing
  118. *
  119. *               Operators
  120. *               -------------------------
  121. *
  122. *                       static method operator [] takes unit whichUnit returns thistype
  123. *                               -       converts a unit into thistype
  124. *
  125. ************************************************************************************
  126. *
  127. *       module UnitIndex
  128. *
  129. *               If you would like to create modules that work off of the UnitIndex module, implement
  130. *               UnitIndex at the top of your module
  131. *              
  132. *               Fields
  133. *               -------------------------
  134. *
  135. *                       static constant boolean UNIT_INDEX = true
  136. *                               -       this is used to ensure that only one unit index module is implemented.
  137. *
  138. *                       static boolean enabled
  139. *                               -       is this UnitIndex struct enabled?
  140. *                               -       this can only be disabed if onUnitIndex exists
  141. *
  142. *                       readonly unit unit
  143. *                               -       converts a unit index into a unit
  144. *
  145. *                       readonly boolean isUnitIndexed
  146. *                               -       is the unit index indexed for the struct?
  147. *
  148. *                       readonly UnitIndexer unitIndexer
  149. *                               -       the indexer in charge of handling the unit
  150. *                                       useful for deindex event, which is unit specific
  151. *
  152. *               Operators
  153. *               -------------------------
  154. *
  155. *                       static method operator [] takes unit whichUnit returns thistype
  156. *                               -       converts a unit into thistype
  157. *
  158. *               Methods
  159. *               -------------------------
  160. *
  161. *                       static method exists takes unit whichUnit returns boolean
  162. *                               -       determines whether the unit is indexed or not for the struct
  163. *
  164. *                       static method isDeindexing takes unit whichUnit returns boolean
  165. *                               -       determines whether the unit is in the process of being deindexed or not
  166. *
  167. *               Interface
  168. *               -------------------------
  169. *
  170. *                       interface private method onUnitIndex takes nothing returns boolean
  171. *                               -       if return true, index the unit for this struct
  172. *
  173. *                       interface private method onUnitDeindex takes nothing returns nothing
  174. *                               -       only runs for units indexed for this struct
  175. *                               -       if not onUnitIndex method is declared, it will run for all units
  176. *
  177. ************************************************************************************
  178. *
  179. *       module UnitIndexEx
  180. *
  181. *               If you would like to create modules that work off of the UnitIndexEx module, implement
  182. *               UnitIndexEx at the top of your module
  183. *              
  184. *               Fields
  185. *               -------------------------
  186. *
  187. *                       static constant boolean UNIT_INDEX_EX = true
  188. *                               -       this is used for modules that rely on local events
  189. *                                       it allows these modules to differentiate between UnitIndex
  190. *                                       and UnitIndexEx
  191. *
  192. *                       static boolean enabled
  193. *                               -       is this UnitIndex struct enabled?
  194. *                               -       this can only be disabed if onUnitIndex exists
  195. *
  196. *                       readonly unit unit
  197. *                               -       converts a unit index into a unit
  198. *
  199. *                       readonly boolean isUnitIndexed
  200. *                               -       is the unit index indexed for the struct?
  201. *
  202. *                       readonly UnitIndexer unitIndexer
  203. *                               -       the indexer in charge of handling the unit
  204. *                                       useful for deindex event, which is unit specific
  205. *
  206. *                       readonly static Trigger ON_INDEX
  207. *                               -       this is a local event that runs whenever any unit is indexed for the struct
  208. *                               -       this is primarily used for other resources that work off of your struct
  209. *
  210. *                               Examples:       Struct.ON_INDEX.reference(yourTrigger)
  211. *                                                       Struct.ON_INDEX.register(yourCode)
  212. *
  213. *                       readonly Trigger Event.ON_DEINDEX
  214. *                       readonly static Trigger Event.ON_DEINDEX
  215. *                               -       this is a unit specific event that runs when your local unit is deindexed
  216. *                               -       this is static if onUnitIndex does not exist
  217. *
  218. *                               Examples:       struct.ON_DEINDEX.reference(yourTrigger)
  219. *                                                       struct.ON_DEINDEX.register(yourCode)
  220. *
  221. *               Operators
  222. *               -------------------------
  223. *
  224. *                       static method operator [] takes unit whichUnit returns thistype
  225. *                               -       converts a unit into thistype
  226. *
  227. *               Methods
  228. *               -------------------------
  229. *
  230. *                       static method exists takes unit whichUnit returns boolean
  231. *                               -       determines whether the unit is indexed or not for the struct
  232. *
  233. *                       static method isDeindexing takes unit whichUnit returns boolean
  234. *                               -       determines whether the unit is in the process of being deindexed or not
  235. *
  236. *               Interface
  237. *               -------------------------
  238. *
  239. *                       interface private method onUnitIndex takes nothing returns boolean
  240. *                               -       if return true, index the unit for this struct
  241. *
  242. *                       interface private method onUnitDeindex takes nothing returns nothing
  243. *                               -       only runs for units indexed for this struct
  244. *                               -       if not onUnitIndex method is declared, it will run for all units
  245. *
  246. ************************************************************************************
  247. *
  248. *       //! textmacro CREATE_LOCAL_UNIT_INDEX
  249. *
  250. *               A macro was chosen because multiple modules utilizing this code may be
  251. *               implemented into one struct. If this was a module, then all but one
  252. *               of those modules would break.
  253. *
  254. *               Interface
  255. *               -------------------------
  256. *
  257. *                       interface private method onLocalUnitIndex takes nothing returns nothing
  258. *                               -       runs whenever a unit is indexed for this struct
  259. *
  260. *                       interface private method onLocalUnitDeindex takes nothing returns nothing
  261. *                               -       runs whenever a unit is deindexed for this struct
  262. *
  263. *                       interface private static method localInit takes nothing returns nothing
  264. *                               -       the macro requires the usage of onInit. Declare this method if you
  265. *                                       would like onInit.
  266. *
  267. ************************************************************************************/
  268.         globals
  269.                 private UnitIndex p_eventIndex = 0
  270.         endglobals
  271.  
  272.         //! runtextmacro UNIT_INDEXER_UNIT_INDEX()
  273.         //! runtextmacro UNIT_INDEXER_PREGAME_EVENT()
  274.         //! runtextmacro UNIT_INDEXER_UNIT_INDEXER()
  275.        
  276.         module GlobalUnitIndex
  277.                 static if thistype.UNIT_INDEX then
  278.                 elseif thistype.UNIT_INDEX_EX then
  279.                 else
  280.                         static constant boolean GLOBAL_UNIT_INDEX = true
  281.                        
  282.                         static method operator [] takes unit whichUnit returns thistype
  283.                                 return p_UnitIndex[whichUnit]
  284.                         endmethod
  285.                         method operator unit takes nothing returns unit
  286.                                 return p_UnitIndex(this).unit
  287.                         endmethod
  288.                         method operator unitIndexer takes nothing returns UnitIndexer
  289.                                 return p_UnitIndex(this).indexer
  290.                         endmethod
  291.                         method operator isUnitIndexed takes nothing returns boolean
  292.                                 return p_UnitIndex(this).isAllocated
  293.                         endmethod
  294.                         static method exists takes unit whichUnit returns boolean
  295.                                 return p_UnitIndex.exists(whichUnit)
  296.                         endmethod
  297.                         static method isDeindexing takes unit whichUnit returns boolean
  298.                                 return p_UnitIndex.isDeindexing(whichUnit)
  299.                         endmethod
  300.                        
  301.                         static if thistype.GLOBAL_UNIT_INDEX then
  302.                                 static if thistype.onUnitIndex.exists then
  303.                                         private static method onIndexEvent takes nothing returns boolean
  304.                                                 call thistype(UnitIndexer.eventIndex).onUnitIndex()
  305.                                        
  306.                                                 return false
  307.                                         endmethod
  308.                                 endif
  309.                                 static if thistype.onUnitDeindex.exists then
  310.                                         private static method onDeindexEvent takes nothing returns boolean
  311.                                                 call thistype(UnitIndexer.eventIndex).onUnitDeindex()
  312.                                                
  313.                                                 return false
  314.                                         endmethod
  315.                                 endif
  316.                                
  317.                                 static if thistype.onUnitIndex.exists then
  318.                                         private static method onInit takes nothing returns nothing
  319.                                 elseif thistype.onUnitDeindex.exists then
  320.                                         private static method onInit takes nothing returns nothing
  321.                                 endif
  322.                                
  323.                                 static if thistype.onUnitIndex.exists then
  324.                                         call UnitIndexer.GlobalEvent.ON_INDEX.register(Condition(function thistype.onIndexEvent))
  325.                                 endif
  326.                                
  327.                                 static if thistype.onUnitDeindex.exists then
  328.                                         call UnitIndexer.GlobalEvent.ON_DEINDEX.register(Condition(function thistype.onDeindexEvent))
  329.                                 endif
  330.                                
  331.                                 static if thistype.onUnitIndex.exists then
  332.                                         endmethod
  333.                                 elseif thistype.onUnitDeindex.exists then
  334.                                         endmethod
  335.                                 endif
  336.                         endif
  337.                 endif
  338.         endmodule
  339.        
  340.         module UnitIndex
  341.                 static if thistype.GLOBAL_UNIT_INDEX then
  342.                         private static method error takes nothing returns nothing
  343.                                 A module requires UnitIndex to operate correctly.
  344.                                 This struct is currently implementing GlobalUnitIndex.
  345.                         endmethod
  346.                 elseif thistype.UNIT_INDEX_EX then
  347.                 else
  348.                         static constant boolean UNIT_INDEX = true
  349.                        
  350.                         /*
  351.                         *       [] is included because the struct automatically overrides it
  352.                         *
  353.                         *       eventIndex is included to return thistype instead of UnitIndex
  354.                         */
  355.                         static method operator [] takes unit whichUnit returns thistype
  356.                                 return UnitIndex[whichUnit]
  357.                         endmethod
  358.                         method operator unitIndexer takes nothing returns UnitIndexer
  359.                                 return this
  360.                         endmethod
  361.                         method operator unit takes nothing returns unit
  362.                                 return UnitIndex(this).unit
  363.                         endmethod
  364.                        
  365.                         static method isDeindexing takes unit whichUnit returns boolean
  366.                                 return UnitIndex.isDeindexing(whichUnit)
  367.                         endmethod
  368.                        
  369.                         /*
  370.                         *       the method is done in the second case because when there is no
  371.                         *       onUnitIndex method, indexed depends on whether the actual
  372.                         *       instance is allocated or not
  373.                         */
  374.                         static if thistype.onUnitIndex.exists then
  375.                                 readonly boolean isUnitIndexed
  376.                         else
  377.                                 method operator isUnitIndexed takes nothing returns boolean
  378.                                         return p_UnitIndex(this).isAllocated
  379.                                 endmethod
  380.                         endif
  381.                        
  382.                         static if thistype.onUnitIndex.exists then
  383.                                 static method exists takes unit whichUnit returns boolean
  384.                                         return UnitIndex.exists(whichUnit) and thistype(GetUnitUserData(whichUnit)).isUnitIndexed
  385.                                 endmethod
  386.                         else
  387.                                 static method exists takes unit whichUnit returns boolean
  388.                                         return UnitIndex.exists(whichUnit)
  389.                                 endmethod
  390.                         endif
  391.                        
  392.                         /*
  393.                         *       this is used to run local events
  394.                         */
  395.                         static if thistype.onUnitIndex.exists then
  396.                                 /*
  397.                                 *       this is where UnitIndex is located
  398.                                 */
  399.                                 private static TriggerCondition entryPoint
  400.                                
  401.                                 /*
  402.                                 *       this stores private onUnitIndex method
  403.                                 */
  404.                                 private static boolexpr onIndexExpression
  405.                                
  406.                                 /*
  407.                                 *       enable works with code inside of entryPoint here
  408.                                 */
  409.                                 private static boolean p_enabled = true
  410.                                 static method operator enabled takes nothing returns boolean
  411.                                         return p_enabled
  412.                                 endmethod
  413.                                 static method operator enabled= takes boolean enable returns nothing
  414.                                         set p_enabled = enable
  415.                                        
  416.                                         if (enable) then
  417.                                                 call entryPoint.replace(onIndexExpression)
  418.                                         else
  419.                                                 call entryPoint.replace(null)
  420.                                         endif
  421.                                 endmethod
  422.                         else
  423.                                 /*
  424.                                 *       if onUnitIndex does not exist, the struct can't be disabled
  425.                                 */
  426.                                 static method operator enabled takes nothing returns boolean
  427.                                         return true
  428.                                 endmethod
  429.                                 static method operator enabled= takes boolean enable returns nothing
  430.                                         set enable = true
  431.                                 endmethod
  432.                         endif
  433.                        
  434.                         /*
  435.                         *       onUnitDeindex
  436.                         *
  437.                         *       This must be implemented if onUnitIndex exists to clear isUnitIndexed
  438.                         */
  439.                         static if thistype.onUnitDeindex.exists then
  440.                                 static if thistype.onUnitIndex.exists then
  441.                                         private static boolexpr onDeindexExpression
  442.                                 endif
  443.                                
  444.                                 private static method onDeindexEvent takes nothing returns boolean
  445.                                         call thistype(UnitIndexer.eventIndex).onUnitDeindex()
  446.                                        
  447.                                         static if thistype.onUnitIndex.exists then
  448.                                                 set thistype(UnitIndexer.eventIndex).isUnitIndexed = false
  449.                                         endif
  450.                                        
  451.                                         return false
  452.                                 endmethod
  453.                         elseif thistype.onUnitIndex.exists then
  454.                                 static if thistype.onUnitIndex.exists then
  455.                                         private static boolexpr onDeindexExpression
  456.                                 endif
  457.                                
  458.                                 private static method onDeindexEvent takes nothing returns boolean
  459.                                         set thistype(UnitIndexer.eventIndex).isUnitIndexed = false
  460.                                        
  461.                                         return false
  462.                                 endmethod
  463.                         endif
  464.                        
  465.                         /*
  466.                         *       onUnitIndex
  467.                         */
  468.                         static if thistype.onUnitIndex.exists then
  469.                                 private static method onIndexEvent takes nothing returns boolean
  470.                                         if (thistype(UnitIndexer.eventIndex).onUnitIndex()) then
  471.                                                 set thistype(UnitIndexer.eventIndex).isUnitIndexed = true
  472.                                                
  473.                                                 /*
  474.                                                 *       this is always registered to clear isUnitIndexed
  475.                                                 */
  476.                                                 call UnitIndexer(UnitIndexer.eventIndex).Event.ON_DEINDEX.register(onDeindexExpression)
  477.                                         endif
  478.                                        
  479.                                         return false
  480.                                 endmethod
  481.                         endif
  482.                        
  483.                         static if thistype.onUnitIndex.exists then
  484.                                 private static method onInit takes nothing returns nothing
  485.                                         set onIndexExpression = Condition(function thistype.onIndexEvent)
  486.                                         set onDeindexExpression = Condition(function thistype.onDeindexEvent)
  487.                                        
  488.                                         set entryPoint = UnitIndexer.GlobalEvent.ON_INDEX.register(Condition(function thistype.onIndexEvent))
  489.                                 endmethod
  490.                         elseif thistype.onUnitDeindex.exists then
  491.                                 private static method onInit takes nothing returns nothing
  492.                                         call UnitIndexer.GlobalEvent.ON_DEINDEX.register(Condition(function thistype.onDeindexEvent))
  493.                                 endmethod
  494.                         endif
  495.                 endif
  496.         endmodule
  497.        
  498.         private struct UnitIndexList extends array
  499.                 //! runtextmacro CREATE_TABLE_FIELD("public", "integer", "unitIndex2Node", "thistype")
  500.                 //! runtextmacro CREATE_TABLE_FIELD("public", "integer", "node2UnitIndex", "thistype")
  501.                
  502.                 method add takes thistype index returns nothing
  503.                         local thistype node = enqueue()
  504.                        
  505.                         set node.node2UnitIndex = index
  506.                         set index.unitIndex2Node = node
  507.                 endmethod
  508.                
  509.                 method delete takes nothing returns nothing
  510.                         call unitIndex2Node.remove()
  511.                 endmethod
  512.                
  513.                 private static method init takes nothing returns nothing
  514.                         //! runtextmacro INITIALIZE_TABLE_FIELD("unitIndex2Node")
  515.                         //! runtextmacro INITIALIZE_TABLE_FIELD("node2UnitIndex")
  516.                 endmethod
  517.                
  518.                 implement NxListT
  519.                 implement Init
  520.         endstruct
  521.         private struct UnitIndexModuleTrigger extends array
  522.                 method reference takes Trigger whichTrigger returns TriggerReference
  523.                         local TriggerReference triggerReference = Trigger(this).reference(whichTrigger)
  524.                        
  525.                         local UnitIndexList node = UnitIndexList(this).first
  526.                         local integer prevIndexedUnitId = p_eventIndex
  527.                        
  528.                         loop
  529.                                 exitwhen node == UnitIndexList.sentinel or not whichTrigger.enabled
  530.                                
  531.                                 set p_eventIndex = node.node2UnitIndex
  532.                                 call whichTrigger.fire()
  533.                                        
  534.                                 set node = node.next
  535.                         endloop
  536.                        
  537.                         set p_eventIndex = prevIndexedUnitId
  538.                        
  539.                         return triggerReference
  540.                 endmethod
  541.                
  542.                 method register takes boolexpr whichExpression returns TriggerCondition
  543.                         local TriggerCondition triggerCondition = Trigger(this).register(whichExpression)
  544.                        
  545.                         local trigger triggerContainer = CreateTrigger()
  546.                        
  547.                         local UnitIndexList node = UnitIndexList(this).first
  548.                         local integer prevIndexedUnitId = p_eventIndex
  549.                        
  550.                         call TriggerAddCondition(triggerContainer, whichExpression)
  551.                        
  552.                         loop
  553.                                 exitwhen node == UnitIndexList.sentinel
  554.                                
  555.                                 set p_eventIndex = node.node2UnitIndex
  556.                                 call TriggerEvaluate(triggerContainer)
  557.                                        
  558.                                 set node = node.next
  559.                         endloop
  560.                        
  561.                         call TriggerClearConditions(triggerContainer)
  562.                         call DestroyTrigger(triggerContainer)
  563.                         set triggerContainer = null
  564.                        
  565.                         set p_eventIndex = prevIndexedUnitId
  566.                        
  567.                         return triggerCondition
  568.                 endmethod
  569.         endstruct
  570.         module UnitIndexEx
  571.                 static if thistype.GLOBAL_UNIT_INDEX then
  572.                         private static method error takes nothing returns nothing
  573.                                 A module requires UnitIndexEx to operate correctly.
  574.                                 This struct is currently implementing GlobalUnitIndex.
  575.                         endmethod
  576.                 elseif thistype.UNIT_INDEX then
  577.                         private static method error takes nothing returns nothing
  578.                                 A module requires UnitIndexEx to operate correctly.
  579.                                 This struct is currently implementing UnitIndex.
  580.                         endmethod
  581.                 else
  582.                         static constant boolean UNIT_INDEX_EX = true
  583.                        
  584.                         private static UnitIndex delegate unitIndex = 0
  585.                
  586.                         /*
  587.                         *       [] is included because the struct automatically overrides it
  588.                         *
  589.                         *       eventIndex is included to return thistype instead of UnitIndex
  590.                         */
  591.                         static method operator [] takes unit whichUnit returns thistype
  592.                                 return UnitIndex[whichUnit]
  593.                         endmethod
  594.                         method operator unit takes nothing returns unit
  595.                                 return UnitIndex(this).unit
  596.                         endmethod
  597.                         method operator unitIndexer takes nothing returns UnitIndexer
  598.                                 return this
  599.                         endmethod
  600.                        
  601.                         static method isDeindexing takes unit whichUnit returns boolean
  602.                                 return UnitIndex.isDeindexing(whichUnit)
  603.                         endmethod
  604.                        
  605.                         /*
  606.                         *       the method is done in the second case because when there is no
  607.                         *       onUnitIndex method, indexed depends on whether the actual
  608.                         *       instance is allocated or not
  609.                         */
  610.                         static if thistype.onUnitIndex.exists then
  611.                                 readonly boolean isUnitIndexed
  612.                         else
  613.                                 method operator isUnitIndexed takes nothing returns boolean
  614.                                         return p_UnitIndex(this).isAllocated
  615.                                 endmethod
  616.                         endif
  617.                        
  618.                         static if thistype.onUnitIndex.exists then
  619.                                 static method exists takes unit whichUnit returns boolean
  620.                                         return UnitIndex.exists(whichUnit) and thistype(GetUnitUserData(whichUnit)).isUnitIndexed
  621.                                 endmethod
  622.                         else
  623.                                 static method exists takes unit whichUnit returns boolean
  624.                                         return UnitIndex.exists(whichUnit)
  625.                                 endmethod
  626.                         endif
  627.                
  628.                         /*
  629.                         *       this is used to run local events
  630.                         */
  631.                         static if thistype.onUnitIndex.exists then
  632.                                 readonly static UnitIndexModuleTrigger ON_INDEX
  633.                         else
  634.                                 readonly static WrappedTrigger ON_INDEX
  635.                         endif
  636.                        
  637.                         static if thistype.onUnitIndex.exists then
  638.                                 /*
  639.                                 *       this is where UnitIndex is located
  640.                                 */
  641.                                 private static TriggerCondition entryPoint
  642.                                
  643.                                 /*
  644.                                 *       this stores private onUnitIndex method
  645.                                 */
  646.                                 private static boolexpr onIndexExpression
  647.                                
  648.                                 /*
  649.                                 *       enable works with code inside of entryPoint here
  650.                                 */
  651.                                 private static boolean p_enabled = true
  652.                                 static method operator enabled takes nothing returns boolean
  653.                                         return p_enabled
  654.                                 endmethod
  655.                                 static method operator enabled= takes boolean enable returns nothing
  656.                                         set p_enabled = enable
  657.                                        
  658.                                         if (enable) then
  659.                                                 call entryPoint.replace(onIndexExpression)
  660.                                         else
  661.                                                 call entryPoint.replace(null)
  662.                                         endif
  663.                                 endmethod
  664.                         else
  665.                                 /*
  666.                                 *       if onUnitIndex does not exist, the struct can't be disabled
  667.                                 */
  668.                                 static method operator enabled takes nothing returns boolean
  669.                                         return true
  670.                                 endmethod
  671.                                 static method operator enabled= takes boolean enable returns nothing
  672.                                         set enable = true
  673.                                 endmethod
  674.                         endif
  675.                        
  676.                         /*
  677.                         *       this is here so that the module runs after code that relies on the module
  678.                         */
  679.                         static if thistype.onUnitIndex.exists then
  680.                                 readonly Trigger ON_DEINDEX
  681.                         else
  682.                                 readonly static Trigger ON_DEINDEX
  683.                         endif
  684.                        
  685.                         /*
  686.                         *       onUnitDeindex
  687.                         */
  688.                         static if thistype.onUnitDeindex.exists then
  689.                                 static if thistype.onUnitIndex.exists then
  690.                                         private static boolexpr onDeindexExpression
  691.                                 endif
  692.                                
  693.                                 private static method onDeindexEvent takes nothing returns boolean
  694.                                         call thistype(UnitIndexer.eventIndex).onUnitDeindex()
  695.                                        
  696.                                         static if thistype.onUnitIndex.exists then
  697.                                                 set thistype(UnitIndexer.eventIndex).isUnitIndexed = false
  698.                                                
  699.                                                 call thistype(UnitIndexer.eventIndex).ON_DEINDEX.destroy()
  700.                                                
  701.                                                 if (not PreGameEvent.isGameLoaded) then
  702.                                                         call UnitIndexList(UnitIndexer.eventIndex).delete()
  703.                                                 endif
  704.                                         endif
  705.                                        
  706.                                         return false
  707.                                 endmethod
  708.                         elseif thistype.onUnitIndex.exists then
  709.                                 private static boolexpr onDeindexExpression
  710.                                
  711.                                 private static method onDeindexEvent takes nothing returns boolean
  712.                                         set thistype(UnitIndexer.eventIndex).isUnitIndexed = false
  713.                                        
  714.                                         call thistype(UnitIndexer.eventIndex).ON_DEINDEX.destroy()
  715.                                        
  716.                                         if (not PreGameEvent.isGameLoaded) then
  717.                                                 call UnitIndexList(UnitIndexer.eventIndex).delete()
  718.                                         endif
  719.                                        
  720.                                         return false
  721.                                 endmethod
  722.                         endif
  723.                        
  724.                         /*
  725.                         *       onUnitIndex
  726.                         */
  727.                         static if thistype.onUnitIndex.exists then
  728.                                 private static method onIndexEvent takes nothing returns boolean
  729.                                         if (thistype(UnitIndexer.eventIndex).onUnitIndex()) then
  730.                                                 set thistype(UnitIndexer.eventIndex).isUnitIndexed = true
  731.                                                
  732.                                                 set thistype(UnitIndexer.eventIndex).ON_DEINDEX = Trigger.create(true)
  733.                                                 call thistype(UnitIndexer.eventIndex).ON_DEINDEX.register(onDeindexExpression)
  734.  
  735.                                                 call UnitIndexer(UnitIndexer.eventIndex).Event.ON_DEINDEX.reference(thistype(UnitIndexer.eventIndex).ON_DEINDEX)
  736.                                                
  737.                                                 if (not PreGameEvent.isGameLoaded) then
  738.                                                         call UnitIndexList(ON_INDEX).add(UnitIndexer.eventIndex)
  739.                                                 endif
  740.                                                
  741.                                                 call Trigger(thistype.ON_INDEX).fire()
  742.                                         endif
  743.                                        
  744.                                         return false
  745.                                 endmethod
  746.                         endif
  747.                        
  748.                         private static method destroyPregameUnitList takes nothing returns nothing
  749.                                 call DestroyTimer(GetExpiredTimer())
  750.                                
  751.                                 call UnitIndexList(ON_INDEX).destroy()
  752.                         endmethod
  753.                        
  754.                         private static method onInit takes nothing returns nothing
  755.                                 set ON_INDEX = Trigger.create(false)
  756.                                
  757.                                 static if thistype.onUnitIndex.exists then
  758.                                         set onIndexExpression = Condition(function thistype.onIndexEvent)
  759.                                         set onDeindexExpression = Condition(function thistype.onDeindexEvent)
  760.                                        
  761.                                         call UnitIndexList(ON_INDEX).clear()
  762.                                        
  763.                                         call TimerStart(CreateTimer(), 0, false, function thistype.destroyPregameUnitList)
  764.                                        
  765.                                         set entryPoint = UnitIndexer.GlobalEvent.ON_INDEX.register(Condition(function thistype.onIndexEvent))
  766.                                 else
  767.                                         set ON_DEINDEX = Trigger.create(true)
  768.                                         static if thistype.onUnitDeindex.exists then
  769.                                                 call ON_DEINDEX.register(Condition(function thistype.onDeindexEvent))
  770.                                         endif
  771.                                        
  772.                                         call UnitIndexer.GlobalEvent.ON_DEINDEX.reference(ON_DEINDEX)
  773.                                         call UnitIndexer.GlobalEvent.ON_INDEX.reference(ON_INDEX)
  774.                                 endif
  775.                         endmethod
  776.                 endif
  777.         endmodule
  778.        
  779.         //! textmacro CREATE_LOCAL_UNIT_INDEX
  780.                 /*
  781.                 *       There are three cases
  782.                 *
  783.                 *               Case 1: UnitIndex is implemented
  784.                 *               Case 2: UnitIndexEx is implemented
  785.                 *               Case 3: Nothing is implemented, go to Case 2
  786.                 */
  787.                 static if thistype.UNIT_INDEX then
  788.                         /*
  789.                         *       Here, UnitIndex is implemented
  790.                         */
  791.                        
  792.                         /*
  793.                         *       There are two cases
  794.                         *
  795.                         *               onUnitEvent exists, which means that events are conditionally local
  796.                         *               onUnitEven does not exist, meaning all events are global
  797.                         */
  798.                         static if thistype.onUnitIndex.exists then
  799.                                 /*
  800.                                 *       Here, events are conditionally local
  801.                                 */
  802.                                
  803.                                 static if thistype.onLocalUnitDeindex.exists then
  804.                                         private static boolexpr onLocalUnitDeindexEventExpr
  805.                                 endif
  806.                        
  807.                                 static if thistype.onLocalUnitIndex.exists then
  808.                                         /*
  809.                                         *       The user has a local unit index event
  810.                                         */
  811.                                         private static method onLocalUnitIndexEvent takes nothing returns boolean
  812.                                                 /*
  813.                                                 *       Here, the event is only run if the unit happened to be indexed
  814.                                                 */
  815.                                                 if (thistype(UnitIndexer.eventIndex).isUnitIndexed) then
  816.                                                         static if thistype.onLocalUnitDeindex.exists then
  817.                                                                 call UnitIndexer.eventIndex.indexer.Event.ON_DEINDEX.register(onLocalUnitDeindexEventExpr)
  818.                                                         endif
  819.                                                        
  820.                                                         call thistype(UnitIndexer.eventIndex).onLocalUnitIndex()
  821.                                                 endif
  822.                                                
  823.                                                 return false
  824.                                         endmethod
  825.                                 elseif thistype.onLocalUnitDeindex.exists then
  826.                                         /*
  827.                                         *       The user did not declare a local unit index event
  828.                                         *
  829.                                         *       onLocalUnitIndexEvent is still required because the deindex events are local
  830.                                         */
  831.                                         private static method onLocalUnitIndexEvent takes nothing returns boolean
  832.                                                 if (thistype(UnitIndexer.eventIndex).isUnitIndexed) then
  833.                                                         call UnitIndexer.eventIndex.indexer.Event.ON_DEINDEX.register(onLocalUnitDeindexEventExpr)
  834.                                                 endif
  835.                                                
  836.                                                 return false
  837.                                         endmethod
  838.                                 endif
  839.                                
  840.                                 static if thistype.onLocalUnitDeindex.exists then
  841.                                         private static method onLocalUnitDeindexEvent takes nothing returns boolean
  842.                                                 call thistype(UnitIndexer.eventIndex).onLocalUnitDeindex()
  843.                                                 return false
  844.                                         endmethod
  845.                                 endif
  846.                                
  847.                                 /*
  848.                                 *       onLocalUnitDeindexEvent is not registered globally here because these are local
  849.                                 *       events. It must be created inside of onLocalUnitIndexEvent whether or not
  850.                                 *       onLocalUnitIndex exists.
  851.                                 */
  852.                                 static if thistype.onLocalUnitIndex.exists then
  853.                                         private static method onInit takes nothing returns nothing
  854.                                                 static if thistype.onLocalUnitDeindex.exists then
  855.                                                         set onLocalUnitDeindexEventExpr = Condition(function thistype.onLocalUnitDeindexEvent)
  856.                                                 endif
  857.                                                
  858.                                                 call UnitIndexer.GlobalEvent.ON_INDEX.register(Condition(function thistype.onLocalUnitIndexEvent))
  859.                                                
  860.                                                 static if thistype.localInit.exists then
  861.                                                         call localInit()
  862.                                                 endif
  863.                                         endmethod
  864.                                 elseif thistype.onLocalUnitDeindex.exists then
  865.                                         private static method onInit takes nothing returns nothing
  866.                                                 set onLocalUnitDeindexEventExpr = Condition(function thistype.onLocalUnitDeindexEvent)
  867.                                                        
  868.                                                 call UnitIndexer.GlobalEvent.ON_INDEX.register(Condition(function thistype.onLocalUnitIndexEvent))
  869.                                                
  870.                                                 static if thistype.localInit.exists then
  871.                                                         call localInit()
  872.                                                 endif
  873.                                         endmethod
  874.                                 endif
  875.                         else
  876.                                 /*
  877.                                 *       Here, all events are global
  878.                                 */
  879.                                 static if thistype.onLocalUnitIndex.exists then
  880.                                         private static method onLocalUnitIndexEvent takes nothing returns boolean
  881.                                                 call thistype(UnitIndexer.eventIndex).onLocalUnitIndex()
  882.                                                 return false
  883.                                         endmethod
  884.                                 endif
  885.                                
  886.                                 static if thistype.onLocalUnitDeindex.exists then
  887.                                         private static method onLocalUnitDeindexEvent takes nothing returns boolean
  888.                                                 call thistype(UnitIndexer.eventIndex).onLocalUnitDeindex()
  889.                                                 return false
  890.                                         endmethod
  891.                                 endif
  892.                                
  893.                                 static if thistype.onLocalUnitIndex.exists then
  894.                                         private static method onInit takes nothing returns nothing
  895.                                                 static if thistype.onLocalUnitDeindex.exists then
  896.                                                         call UnitIndexer.GlobalEvent.ON_DEINDEX.register(Condition(function thistype.onLocalUnitDeindexEvent))
  897.                                                 endif
  898.                                                
  899.                                                 call UnitIndexer.GlobalEvent.ON_INDEX.register(Condition(function thistype.onLocalUnitIndexEvent))
  900.                                                
  901.                                                 static if thistype.localInit.exists then
  902.                                                         call localInit()
  903.                                                 endif
  904.                                         endmethod
  905.                                 elseif thistype.onLocalUnitDeindex.exists then
  906.                                         private static method onInit takes nothing returns nothing
  907.                                                 call UnitIndexer.GlobalEvent.ON_DEINDEX.register(Condition(function thistype.onLocalUnitDeindexEvent))
  908.                                                
  909.                                                 static if thistype.localInit.exists then
  910.                                                         call localInit()
  911.                                                 endif
  912.                                         endmethod
  913.                                 endif
  914.                         endif
  915.                 elseif thistype.GLOBAL_UNIT_INDEX then
  916.                         private static method error takes nothing returns nothing
  917.                                 A module requires either UnitIndex or UnitIndexEx to operate correctly.
  918.                                 This struct is currently implementing GlobalUnitIndex.
  919.                         endmethod
  920.                 else
  921.                         /*
  922.                         *       Here, UnitIndexEx is either implemented or nothing is implemented
  923.                         *
  924.                         *       Implement UnitIndexEx and work with its local events
  925.                         */
  926.                         implement UnitIndexEx
  927.                        
  928.                         static if thistype.onUnitIndex.exists then
  929.                                 /*
  930.                                 *       local events
  931.                                 */
  932.                                 static if thistype.onLocalUnitDeindex.exists then
  933.                                         private static boolexpr onLocalUnitDeindexEventExpr
  934.                                 endif
  935.                                
  936.                                 /*
  937.                                 *       if onUnitIndex exists, then onLocalUnitDeindex is local
  938.                                 *
  939.                                 *       this means that if onLocalUnitDeindex exists, the onLocalUnitIndexEvent must be
  940.                                 *       made so that it can register onLocalUnitDeindex locally
  941.                                 */
  942.                                 static if thistype.onLocalUnitIndex.exists then
  943.                                         private static method onLocalUnitIndexEvent takes nothing returns boolean
  944.                                                 static if thistype.onLocalUnitDeindex.exists then
  945.                                                         call thistype(UnitIndexer.eventIndex).ON_DEINDEX.register(onLocalUnitDeindexEventExpr)
  946.                                                 endif
  947.                                                
  948.                                                 call thistype(UnitIndexer.eventIndex).onLocalUnitIndex()
  949.                                                
  950.                                                 return false
  951.                                         endmethod
  952.                                 elseif thistype.onLocalUnitDeindex.exists then
  953.                                         private static method onLocalUnitIndexEvent takes nothing returns boolean
  954.                                                 call thistype(UnitIndexer.eventIndex).ON_DEINDEX.register(onLocalUnitDeindexEventExpr)
  955.                                                        
  956.                                                 return false
  957.                                         endmethod
  958.                                 endif
  959.                         elseif thistype.onLocalUnitIndex.exists then
  960.                                 /*
  961.                                 *       global events
  962.                                 *
  963.                                 *               onLocalUnitDeindex is run globally, so it doesn't need onLocalUnitIndexEvent
  964.                                 *               anymore
  965.                                 */
  966.                                 private static method onLocalUnitIndexEvent takes nothing returns boolean
  967.                                         call thistype(UnitIndexer.eventIndex).onLocalUnitIndex()
  968.                                        
  969.                                         return false
  970.                                 endmethod
  971.                         endif
  972.                        
  973.                         static if thistype.onLocalUnitDeindex.exists then
  974.                                 private static method onLocalUnitDeindexEvent takes nothing returns boolean
  975.                                         call thistype(UnitIndexer.eventIndex).onLocalUnitDeindex()
  976.                                        
  977.                                         return false
  978.                                 endmethod
  979.                         endif
  980.                        
  981.                         /*
  982.                         *       The reason why ON_INDEX is used is so that the module can be enabled/disabled
  983.                         *       correctly
  984.                         */
  985.                         private static method onInit takes nothing returns nothing
  986.                                 static if thistype.onUnitIndex.exists then
  987.                                         /*
  988.                                         *       local events
  989.                                         */
  990.                                         static if thistype.onLocalUnitDeindex.exists then
  991.                                                 set onLocalUnitDeindexEventExpr = Condition(function thistype.onLocalUnitDeindexEvent)
  992.                                         endif
  993.                                        
  994.                                         /*
  995.                                         *       onLocalUnitIndexEvent is registered for onLocalUnitdeindex because onLocalUnitDeindex
  996.                                         *       must be registered to each unit. This means that it must register as units are indexed.
  997.                                         */
  998.                                         static if thistype.onLocalUnitIndex.exists then
  999.                                                 call thistype.ON_INDEX.register(Condition(function thistype.onLocalUnitIndexEvent))
  1000.                                         elseif thistype.onLocalUnitDeindex.exists then
  1001.                                                 call thistype.ON_INDEX.register(Condition(function thistype.onLocalUnitIndexEvent))
  1002.                                         endif
  1003.                                 else
  1004.                                         /*
  1005.                                         *       global events
  1006.                                         *
  1007.                                         *       ON_DEINDEX is used here instead of UnitIndexer.GlobalEvent.ON_DEINDEX for proper
  1008.                                         *       execution order
  1009.                                         */
  1010.                                        
  1011.                                         static if thistype.onLocalUnitDeindex.exists then
  1012.                                                 call thistype.ON_DEINDEX.register(Condition(function thistype.onLocalUnitDeindexEvent))
  1013.                                         endif
  1014.                                        
  1015.                                         static if thistype.onLocalUnitIndex.exists then
  1016.                                                 call thistype.ON_INDEX.register(Condition(function thistype.onLocalUnitIndexEvent))
  1017.                                         endif
  1018.                                 endif
  1019.                                
  1020.                                 static if thistype.localInit.exists then
  1021.                                         call localInit()
  1022.                                 endif
  1023.                         endmethod
  1024.                 endif
  1025.         //! endtextmacro
  1026. endlibrary

UnitIndexer UnitIndex:
Code: jass
  1. /*
  2. *       requires
  3. *
  4. *               Alloc
  5. *               ErrorMessage
  6. *
  7. *               private struct p_UnitIndex extends array
  8. *
  9. *               method operator isAllocated takes nothing returns boolean
  10. *               debug static method calculateMemoryUsage takes nothing returns integer
  11. *               debug static method getAllocatedMemoryAsString takes nothing returns string
  12. *
  13. *               method operator indexer takes nothing returns UnitIndexer
  14. *               method operator unit takes nothing returns unit
  15. *               static method operator [] takes unit whichUnit returns thistype
  16. *               static method exists takes unit whichUnit returns boolean
  17. *
  18. *       struct UnitIndex extends array
  19. *
  20. *               readonly unit unit
  21. *               readonly UnitIndexer indexer
  22. *
  23. *               static method operator [] takes unit whichUnit returns UnitIndex
  24. *
  25. *               static method exists takes unit whichUnit returns boolean
  26. *               static method isDeindexing takes unit whichUnit returns boolean
  27. */
  28.  
  29. //! textmacro UNIT_INDEXER_UNIT_INDEX
  30. private struct p_UnitIndex extends array
  31.         implement AllocQ
  32.  
  33.         private unit p_unit
  34.        
  35.         static method create takes unit whichUnit returns thistype
  36.                 local thistype this = allocate()
  37.                
  38.                 set p_unit = whichUnit
  39.                 call SetUnitUserData(whichUnit, this)
  40.  
  41.                 call UnitAddAbility(whichUnit, ABILITIES_UNIT_INDEXER)
  42.                 call UnitMakeAbilityPermanent(whichUnit, true, ABILITIES_UNIT_INDEXER)
  43.                
  44.                 return this
  45.         endmethod
  46.        
  47.         method destroy takes nothing returns nothing
  48.                 set p_unit = null
  49.        
  50.                 call deallocate()
  51.         endmethod
  52.        
  53.         method operator indexer takes nothing returns UnitIndexer
  54.                 debug call ThrowWarning(not isAllocated,                                                                                        "UnitIndexer", "indexer", "thistype", this, "Getting indexer from a deallocated unit index.")
  55.                
  56.                 return this
  57.         endmethod
  58.        
  59.         method operator unit takes nothing returns unit
  60.                 debug call ThrowWarning(not isAllocated,                                                                                        "UnitIndexer", "unit", "thistype", this, "Getting unit from a deallocated unit index.")
  61.        
  62.                 return p_unit
  63.         endmethod
  64.         static method operator [] takes unit whichUnit returns thistype
  65.                 debug call ThrowWarning(GetUnitTypeId(whichUnit) == 0,                                                          "UnitIndexer", "[]", "thistype", 0, "Getting unit index of a null unit.")
  66.                 debug call ThrowWarning(thistype(GetUnitUserData(whichUnit)).p_unit != whichUnit,       "UnitIndexer", "[]", "thistype", 0, "Getting unit index of a unit that isn't indexed.")
  67.                
  68.                 return GetUnitUserData(whichUnit)
  69.         endmethod
  70.        
  71.         static method exists takes unit whichUnit returns boolean
  72.                 debug call ThrowWarning(GetUnitTypeId(whichUnit) == 0, "UnitIndexer", "exists",         "thistype", 0, "Checking for the existence of a null unit.")
  73.        
  74.                 return thistype(GetUnitUserData(whichUnit)).p_unit == whichUnit
  75.         endmethod
  76.        
  77.         static method isDeindexing takes unit whichUnit returns boolean
  78.                 return GetUnitTypeId(whichUnit) != 0 and GetUnitAbilityLevel(whichUnit, ABILITIES_UNIT_INDEXER) == 0 and thistype(GetUnitUserData(whichUnit)).p_unit == whichUnit
  79.         endmethod
  80. endstruct
  81.  
  82. struct UnitIndex extends array
  83.         method operator unit takes nothing returns unit
  84.                 return p_UnitIndex(this).unit
  85.         endmethod
  86.        
  87.         static method operator [] takes unit whichUnit returns thistype
  88.                 return p_UnitIndex[whichUnit]
  89.         endmethod
  90.        
  91.         static method exists takes unit whichUnit returns boolean
  92.                 return p_UnitIndex.exists(whichUnit)
  93.         endmethod
  94.        
  95.         static method isDeindexing takes unit whichUnit returns boolean
  96.                 return p_UnitIndex.isDeindexing(whichUnit)
  97.         endmethod
  98.        
  99.         method operator indexer takes nothing returns UnitIndexer
  100.                 return p_UnitIndex(this).indexer
  101.         endmethod
  102. endstruct
  103. //! endtextmacro

UnitIndexer UnitIndexer:
Code: jass
  1. /*
  2. *       requires
  3. *
  4. *               Event
  5. *               WorldBounds
  6. *
  7. *       struct UnitIndexer extends array
  8. *
  9. *               static boolean enabled = true
  10. *
  11. *               readonly static Trigger GlobalEvent.ON_INDEX
  12. *               readonly static Trigger GlobalEvent.ON_DEINDEX
  13. *               readonly Trigger Event.ON_DEINDEX
  14. *
  15. *               readonly UnitIndex eventIndex = 0
  16. *               readonly unit eventUnit = null
  17. *
  18. *       private struct WrappedTrigger extends array
  19. *
  20. *               method reference takes Trigger whichTrigger returns nothing
  21. *
  22. *               method register takes boolexpr whichExpression returns nothing
  23. *
  24. */
  25.  
  26. //! textmacro UNIT_INDEXER_UNIT_INDEXER
  27. private struct WrappedTrigger extends array
  28.         static if DEBUG_MODE then
  29.                 method reference takes Trigger whichTrigger returns TriggerReference
  30.                         return reference_p(whichTrigger)
  31.                 endmethod
  32.                
  33.                 method register takes boolexpr whichExpression returns TriggerCondition
  34.                         return register_p(whichExpression)
  35.                 endmethod
  36.                
  37.                 private method reference_p takes Trigger whichTrigger returns TriggerReference
  38.                         local TriggerReference triggerReference = Trigger(this).reference(whichTrigger)
  39.                        
  40.                         call PreGameEvent.fireTrigger(whichTrigger)
  41.                        
  42.                         return triggerReference
  43.                 endmethod
  44.        
  45.                 private method register_p takes boolexpr whichExpression returns TriggerCondition
  46.                         local TriggerCondition triggerCondition = Trigger(this).register(whichExpression)
  47.                        
  48.                         call PreGameEvent.fireExpression(whichExpression)
  49.                        
  50.                         return triggerCondition
  51.                 endmethod
  52.         else
  53.                 method reference takes Trigger whichTrigger returns TriggerReference
  54.                         local TriggerReference triggerReference = Trigger(this).reference(whichTrigger)
  55.                        
  56.                         call PreGameEvent.fireTrigger(whichTrigger)
  57.                        
  58.                         return triggerReference
  59.                 endmethod
  60.        
  61.                 method register takes boolexpr whichExpression returns TriggerCondition
  62.                         local TriggerCondition triggerCondition = Trigger(this).register(whichExpression)
  63.                        
  64.                         call PreGameEvent.fireExpression(whichExpression)
  65.                        
  66.                         return triggerCondition
  67.                 endmethod
  68.         endif
  69. endstruct
  70.  
  71. private struct UnitIndexerTriggerGlobal extends array
  72.         readonly static WrappedTrigger  ON_INDEX
  73.         readonly static Trigger                 ON_DEINDEX
  74.        
  75.         private static method init takes nothing returns nothing
  76.                 set ON_INDEX = Trigger.create(false)
  77.                 set ON_DEINDEX = Trigger.create(true)
  78.         endmethod
  79.        
  80.         implement Init
  81. endstruct
  82.  
  83. private keyword ON_DEINDEX_MAIN
  84. private struct UnitIndexerTrigger extends array
  85.         readonly Trigger ON_DEINDEX
  86.        
  87.         method createDeindex takes nothing returns nothing
  88.                 set ON_DEINDEX = Trigger.create(true)
  89.                
  90.                 call ON_DEINDEX.reference(UnitIndexerTriggerGlobal.ON_DEINDEX)
  91.         endmethod
  92.        
  93.         method destroyDeindex takes nothing returns nothing
  94.                 call ON_DEINDEX.destroy()
  95.         endmethod
  96. endstruct
  97.  
  98. struct UnitIndexer extends array
  99.         private trigger deindexTrigger
  100.         private static boolexpr onDeindexCondition
  101.  
  102.         static method operator eventIndex takes nothing returns UnitIndex
  103.                 return p_eventIndex
  104.         endmethod
  105.         static method operator eventUnit takes nothing returns unit
  106.                 return eventIndex.unit
  107.         endmethod
  108.        
  109.         static method operator GlobalEvent takes nothing returns UnitIndexerTriggerGlobal
  110.                 return 0
  111.         endmethod
  112.         method operator Event takes nothing returns UnitIndexerTrigger
  113.                 return this
  114.         endmethod
  115.  
  116.         static boolean enabled = true
  117.        
  118.         private static method fire takes Trigger whichTrigger, integer whichIndex returns nothing
  119.                 local integer prevIndexedUnit = p_eventIndex
  120.                 set p_eventIndex = whichIndex
  121.                 call whichTrigger.fire()
  122.                 set p_eventIndex = prevIndexedUnit
  123.         endmethod
  124.        
  125.         private static method onIndex takes nothing returns boolean
  126.                 local unit indexedUnit = GetFilterUnit()
  127.                 local p_UnitIndex index
  128.                
  129.                 if (enabled and not p_UnitIndex.exists(indexedUnit)) then
  130.                         set index = p_UnitIndex.create(indexedUnit)
  131.                        
  132.                         set thistype(index).deindexTrigger = CreateTrigger()
  133.                         call TriggerRegisterUnitEvent(thistype(index).deindexTrigger, indexedUnit, EVENT_UNIT_ISSUED_ORDER)
  134.                         call TriggerAddCondition(thistype(index).deindexTrigger, onDeindexCondition)
  135.                        
  136.                         call PreGameEvent.addUnitIndex(index)
  137.                        
  138.                         call thistype(index).Event.createDeindex()
  139.                        
  140.                         call fire(GlobalEvent.ON_INDEX, index)
  141.                 endif
  142.                
  143.                 set indexedUnit = null
  144.                
  145.                 return false
  146.         endmethod
  147.        
  148.         private static method onDeindex takes nothing returns boolean
  149.                 local p_UnitIndex index = GetUnitUserData(GetTriggerUnit())
  150.                
  151.                 if (GetUnitAbilityLevel(GetTriggerUnit(), ABILITIES_UNIT_INDEXER) == 0) then
  152.                         call PreGameEvent.removeUnitIndex(index)
  153.                        
  154.                         call fire(thistype(index).Event.ON_DEINDEX, index)
  155.                        
  156.                         call thistype(index).Event.destroyDeindex()
  157.                        
  158.                         call DestroyTrigger(thistype(index).deindexTrigger)
  159.                         set thistype(index).deindexTrigger = null
  160.                        
  161.                         call index.destroy()
  162.                 endif
  163.                
  164.                 return false
  165.         endmethod
  166.        
  167.         private static method init takes nothing returns nothing
  168.                 local trigger indexTrigger = CreateTrigger()
  169.                
  170.                 local boolexpr onIndexCondition  = Condition(function thistype.onIndex)
  171.                
  172.                 local group enumGroup = CreateGroup()
  173.                
  174.                 local integer currentPlayerId = 15
  175.                 local player currentPlayer
  176.                
  177.                 set onDeindexCondition= Condition(function thistype.onDeindex)
  178.                
  179.                 call TriggerRegisterEnterRegion(indexTrigger, WorldBounds.worldRegion, onIndexCondition)
  180.                
  181.                 loop
  182.                         set currentPlayer = Player(currentPlayerId)
  183.                        
  184.                         call SetPlayerAbilityAvailable(currentPlayer, ABILITIES_UNIT_INDEXER, false)
  185.                         call GroupEnumUnitsOfPlayer(enumGroup, currentPlayer, onIndexCondition)
  186.                        
  187.                         exitwhen currentPlayerId == 0
  188.                         set currentPlayerId = currentPlayerId - 1
  189.                 endloop
  190.                
  191.                 call DestroyGroup(enumGroup)
  192.                
  193.                 set onIndexCondition = null
  194.                
  195.                 set enumGroup = null
  196.                 set currentPlayer = null
  197.                
  198.                 set indexTrigger = null
  199.         endmethod
  200.        
  201.         implement Init
  202. endstruct
  203. //! endtextmacro

UnitIndexer Pregame Event:
Code: jass
  1. /*
  2. *       requires
  3. *
  4. *               StaticUniqueList
  5. *
  6. *       private struct PreGameEvent extends array
  7. *
  8. *               Evaluates all triggers and functions registered to
  9. *               Unit Indexer before game start for all indexed units.
  10. *
  11. *
  12. *               static method fireTrigger takes trigger whichTrigger returns nothing
  13. *               static method fireExpression takes boolexpr whichExpression returns nothing
  14. *
  15. *               static method addUnitIndex takes integer whichUnitIndex returns nothing
  16. *               static method removeUnitIndex takes integer whichUnitIndex returns nothing
  17. */
  18.  
  19. //! textmacro UNIT_INDEXER_PREGAME_EVENT
  20. private struct PreGameEvent extends array
  21.         readonly static boolean isGameLoaded = false
  22.  
  23.         implement StaticUniqueList
  24.        
  25.         private static method p_fireTrigger takes Trigger whichTrigger returns nothing
  26.                 local thistype this = first
  27.                 local integer prevIndexedUnitId = p_eventIndex
  28.                
  29.                 loop
  30.                         exitwhen this == sentinel or not whichTrigger.enabled
  31.                        
  32.                         set p_eventIndex = this
  33.                         call whichTrigger.fire()
  34.                        
  35.                         set this = next
  36.                 endloop
  37.                
  38.                 set p_eventIndex = prevIndexedUnitId
  39.         endmethod
  40.         static method fireTrigger takes Trigger whichTrigger returns nothing
  41.                 if (first != 0) then
  42.                         call p_fireTrigger(whichTrigger)
  43.                 endif
  44.         endmethod
  45.        
  46.         private static method p_fireExpression takes boolexpr whichExpression returns nothing
  47.                 local trigger triggerContainer = CreateTrigger()
  48.                 local thistype this = first
  49.                 local integer prevIndexedUnitId = p_eventIndex
  50.                
  51.                 call TriggerAddCondition(triggerContainer, whichExpression)
  52.                
  53.                 loop
  54.                         exitwhen this == sentinel
  55.                        
  56.                         set p_eventIndex = this
  57.                         call TriggerEvaluate(triggerContainer)
  58.                        
  59.                         set this = next
  60.                 endloop
  61.                
  62.                 call TriggerClearConditions(triggerContainer)
  63.                 call DestroyTrigger(triggerContainer)
  64.                 set triggerContainer = null
  65.                
  66.                 set p_eventIndex = prevIndexedUnitId
  67.         endmethod
  68.         static method fireExpression takes boolexpr whichExpression returns nothing
  69.                 if (first != 0) then
  70.                         call p_fireExpression(whichExpression)
  71.                 endif
  72.         endmethod
  73.        
  74.         static method addUnitIndex takes integer whichUnitIndex returns nothing
  75.                 if (isGameLoaded) then
  76.                         return
  77.                 endif
  78.                
  79.                 call enqueue(whichUnitIndex)
  80.         endmethod
  81.        
  82.         static method removeUnitIndex takes integer whichUnitIndex returns nothing
  83.                 if (isGameLoaded) then
  84.                         return
  85.                 endif
  86.                
  87.                 call thistype(whichUnitIndex).remove()
  88.         endmethod
  89.        
  90.         private static method run takes nothing returns nothing
  91.                 call DestroyTimer(GetExpiredTimer())
  92.                
  93.                 set isGameLoaded = true
  94.                
  95.                 call clear()
  96.         endmethod
  97.         private static method init takes nothing returns nothing
  98.                 call TimerStart(CreateTimer(), 0, false, function thistype.run)
  99.         endmethod
  100.        
  101.         implement Init
  102. endstruct
  103. //! endtextmacro

For further information related with installation and usage, please refer to the test map attached to this topic.
« Last Edit: December 19, 2017, 01:33:06 AM by moyack »



 

Vivir aprendiendo.co - A place for learning stuff, in Spanish   Chaos Realm - The world of Game modders and wc3 addicts   Diplo, a gaming community   WC3JASS.com - The JASS Vault + vJASS and Zinc   Jetcraft - A Starcraft II mod   WormTastic Clan (wTc)