@v12-engine/engine 0.1.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (951) hide show
  1. package/dist/abilities/amounts.d.ts +28 -0
  2. package/dist/abilities/amounts.js +74 -0
  3. package/dist/abilities/amounts.js.map +1 -0
  4. package/dist/abilities/buffs.d.ts +106 -6
  5. package/dist/abilities/buffs.js +443 -0
  6. package/dist/abilities/buffs.js.map +1 -0
  7. package/dist/abilities/castTold.d.ts +2 -0
  8. package/dist/abilities/castTold.js +66 -0
  9. package/dist/abilities/castTold.js.map +1 -0
  10. package/dist/abilities/chance.d.ts +38 -0
  11. package/dist/abilities/chance.js +77 -0
  12. package/dist/abilities/chance.js.map +1 -0
  13. package/dist/abilities/charges.d.ts +18 -0
  14. package/dist/abilities/charges.js +101 -0
  15. package/dist/abilities/charges.js.map +1 -0
  16. package/dist/abilities/control.d.ts +28 -0
  17. package/dist/abilities/control.js +113 -0
  18. package/dist/abilities/control.js.map +1 -0
  19. package/dist/abilities/dispel.js +51 -0
  20. package/dist/abilities/dispel.js.map +1 -0
  21. package/dist/abilities/effectFields.d.ts +1 -1
  22. package/dist/abilities/effectFields.js +676 -0
  23. package/dist/abilities/effectFields.js.map +1 -0
  24. package/dist/abilities/effectIndex.d.ts +27 -0
  25. package/dist/abilities/effectIndex.js +64 -0
  26. package/dist/abilities/effectIndex.js.map +1 -0
  27. package/dist/abilities/effects/buff.d.ts +9 -3
  28. package/dist/abilities/effects/buff.js +84 -0
  29. package/dist/abilities/effects/buff.js.map +1 -0
  30. package/dist/abilities/effects/conditions.d.ts +2 -0
  31. package/dist/abilities/effects/conditions.js +41 -0
  32. package/dist/abilities/effects/conditions.js.map +1 -0
  33. package/dist/abilities/effects/core.js +54 -0
  34. package/dist/abilities/effects/core.js.map +1 -0
  35. package/dist/abilities/effects/damage.d.ts +1 -1
  36. package/dist/abilities/effects/damage.js +43 -0
  37. package/dist/abilities/effects/damage.js.map +1 -0
  38. package/dist/abilities/effects/heal.d.ts +2 -2
  39. package/dist/abilities/effects/heal.js +51 -0
  40. package/dist/abilities/effects/heal.js.map +1 -0
  41. package/dist/abilities/effects/missile.d.ts +13 -1
  42. package/dist/abilities/effects/missile.js +104 -0
  43. package/dist/abilities/effects/missile.js.map +1 -0
  44. package/dist/abilities/effects/morph.d.ts +5 -0
  45. package/dist/abilities/effects/morph.js +43 -0
  46. package/dist/abilities/effects/morph.js.map +1 -0
  47. package/dist/abilities/effects/moves.d.ts +16 -4
  48. package/dist/abilities/effects/moves.js +212 -0
  49. package/dist/abilities/effects/moves.js.map +1 -0
  50. package/dist/abilities/effects/passives.d.ts +19 -9
  51. package/dist/abilities/effects/passives.js +131 -0
  52. package/dist/abilities/effects/passives.js.map +1 -0
  53. package/dist/abilities/effects/proxy.d.ts +5 -0
  54. package/dist/abilities/effects/proxy.js +60 -0
  55. package/dist/abilities/effects/proxy.js.map +1 -0
  56. package/dist/abilities/effects/sight.d.ts +2 -2
  57. package/dist/abilities/effects/sight.js +39 -0
  58. package/dist/abilities/effects/sight.js.map +1 -0
  59. package/dist/abilities/effects/spawn.d.ts +5 -2
  60. package/dist/abilities/effects/spawn.js +40 -0
  61. package/dist/abilities/effects/spawn.js.map +1 -0
  62. package/dist/abilities/effects/timed.d.ts +2 -2
  63. package/dist/abilities/effects/timed.js +96 -0
  64. package/dist/abilities/effects/timed.js.map +1 -0
  65. package/dist/abilities/effects/trade.d.ts +1 -1
  66. package/dist/abilities/effects/trade.js +25 -0
  67. package/dist/abilities/effects/trade.js.map +1 -0
  68. package/dist/abilities/effects.d.ts +97 -23
  69. package/dist/abilities/effects.js +860 -0
  70. package/dist/abilities/effects.js.map +1 -0
  71. package/dist/abilities/land.d.ts +38 -4
  72. package/dist/abilities/land.js +189 -0
  73. package/dist/abilities/land.js.map +1 -0
  74. package/dist/abilities/recast.d.ts +45 -0
  75. package/dist/abilities/recast.js +118 -0
  76. package/dist/abilities/recast.js.map +1 -0
  77. package/dist/abilities/scaled.js +40 -0
  78. package/dist/abilities/scaled.js.map +1 -0
  79. package/dist/abilities/screen.d.ts +6 -0
  80. package/dist/abilities/screen.js +83 -0
  81. package/dist/abilities/screen.js.map +1 -0
  82. package/dist/abilities/shapes.d.ts +66 -0
  83. package/dist/abilities/shapes.js +122 -0
  84. package/dist/abilities/shapes.js.map +1 -0
  85. package/dist/abilities/text.d.ts +14 -2
  86. package/dist/abilities/text.js +204 -0
  87. package/dist/abilities/text.js.map +1 -0
  88. package/dist/abilities/triggers.d.ts +98 -0
  89. package/dist/abilities/triggers.js +351 -0
  90. package/dist/abilities/triggers.js.map +1 -0
  91. package/dist/abilityChanges.d.ts +131 -0
  92. package/dist/abilityChanges.js +345 -0
  93. package/dist/abilityChanges.js.map +1 -0
  94. package/dist/ai/area.d.ts +4 -1
  95. package/dist/ai/brain.d.ts +4 -1
  96. package/dist/ai/brain.js +844 -0
  97. package/dist/ai/brain.js.map +1 -0
  98. package/dist/ai/budget.js +74 -0
  99. package/dist/ai/budget.js.map +1 -0
  100. package/dist/ai/checks.d.ts +9 -1
  101. package/dist/ai/checks.js +242 -0
  102. package/dist/ai/checks.js.map +1 -0
  103. package/dist/ai/computer.d.ts +11 -4
  104. package/dist/ai/computer.js +251 -0
  105. package/dist/ai/computer.js.map +1 -0
  106. package/dist/ai/defence.d.ts +4 -0
  107. package/dist/ai/defence.js +430 -0
  108. package/dist/ai/defence.js.map +1 -0
  109. package/dist/ai/define.d.ts +3 -2
  110. package/dist/ai/define.js +31 -0
  111. package/dist/ai/define.js.map +1 -0
  112. package/dist/ai/economy.d.ts +10 -7
  113. package/dist/ai/economy.js +780 -0
  114. package/dist/ai/economy.js.map +1 -0
  115. package/dist/ai/geometry.js +38 -0
  116. package/dist/ai/geometry.js.map +1 -0
  117. package/dist/ai/goals.d.ts +1 -0
  118. package/dist/ai/goals.js +560 -0
  119. package/dist/ai/goals.js.map +1 -0
  120. package/dist/ai/knowledge.d.ts +72 -7
  121. package/dist/ai/knowledge.js +804 -0
  122. package/dist/ai/knowledge.js.map +1 -0
  123. package/dist/ai/lanes.d.ts +10 -2
  124. package/dist/ai/lanes.js +715 -0
  125. package/dist/ai/lanes.js.map +1 -0
  126. package/dist/ai/melee/build.js +264 -0
  127. package/dist/ai/melee/build.js.map +1 -0
  128. package/dist/ai/melee/goals.d.ts +7 -0
  129. package/dist/ai/melee/goals.js +720 -0
  130. package/dist/ai/melee/goals.js.map +1 -0
  131. package/dist/ai/melee/heroes.js +68 -0
  132. package/dist/ai/melee/heroes.js.map +1 -0
  133. package/dist/ai/melee/index.d.ts +1 -1
  134. package/dist/ai/melee/index.js +51 -0
  135. package/dist/ai/melee/index.js.map +1 -0
  136. package/dist/ai/melee/production.js +29 -0
  137. package/dist/ai/melee/production.js.map +1 -0
  138. package/dist/ai/melee/surrender.js +64 -0
  139. package/dist/ai/melee/surrender.js.map +1 -0
  140. package/dist/ai/micro.d.ts +9 -0
  141. package/dist/ai/micro.js +1316 -0
  142. package/dist/ai/micro.js.map +1 -0
  143. package/dist/ai/mission.d.ts +9 -2
  144. package/dist/ai/mission.js +538 -0
  145. package/dist/ai/mission.js.map +1 -0
  146. package/dist/ai/missionRules.d.ts +1 -1
  147. package/dist/ai/missionRules.js +26 -0
  148. package/dist/ai/missionRules.js.map +1 -0
  149. package/dist/ai/module.d.ts +6 -2
  150. package/dist/ai/module.js +37 -0
  151. package/dist/ai/module.js.map +1 -0
  152. package/dist/ai/options.d.ts +3 -3
  153. package/dist/ai/plans/build.d.ts +20 -1
  154. package/dist/ai/plans/build.js +608 -0
  155. package/dist/ai/plans/build.js.map +1 -0
  156. package/dist/ai/plans/placement.d.ts +4 -1
  157. package/dist/ai/plans/placement.js +295 -0
  158. package/dist/ai/plans/placement.js.map +1 -0
  159. package/dist/ai/plans/plans.d.ts +9 -0
  160. package/dist/ai/plans/plans.js +110 -0
  161. package/dist/ai/plans/plans.js.map +1 -0
  162. package/dist/ai/plans/production.d.ts +14 -2
  163. package/dist/ai/plans/production.js +434 -0
  164. package/dist/ai/plans/production.js.map +1 -0
  165. package/dist/ai/plans/purse.d.ts +6 -3
  166. package/dist/ai/plans/purse.js +139 -0
  167. package/dist/ai/plans/purse.js.map +1 -0
  168. package/dist/ai/plans/tech.d.ts +6 -0
  169. package/dist/ai/plans/tech.js +122 -0
  170. package/dist/ai/plans/tech.js.map +1 -0
  171. package/dist/ai/profiles.d.ts +4 -4
  172. package/dist/{profiles-B3NS9jwk.js → ai/profiles.js} +3 -98
  173. package/dist/ai/profiles.js.map +1 -0
  174. package/dist/ai/reach.js +54 -0
  175. package/dist/ai/reach.js.map +1 -0
  176. package/dist/ai/report.d.ts +8 -0
  177. package/dist/ai/report.js +87 -0
  178. package/dist/ai/report.js.map +1 -0
  179. package/dist/ai/roles.d.ts +4 -0
  180. package/dist/ai/roles.js +207 -0
  181. package/dist/ai/roles.js.map +1 -0
  182. package/dist/ai/rules.d.ts +8 -2
  183. package/dist/ai/rules.js +416 -0
  184. package/dist/ai/rules.js.map +1 -0
  185. package/dist/ai/scouting.d.ts +6 -0
  186. package/dist/ai/scouting.js +324 -0
  187. package/dist/ai/scouting.js.map +1 -0
  188. package/dist/ai/settings.js +99 -0
  189. package/dist/ai/settings.js.map +1 -0
  190. package/dist/ai/squads.d.ts +21 -2
  191. package/dist/ai/squads.js +916 -0
  192. package/dist/ai/squads.js.map +1 -0
  193. package/dist/ai/strength.js +320 -0
  194. package/dist/ai/strength.js.map +1 -0
  195. package/dist/ai/task.d.ts +3 -1
  196. package/dist/ai/task.js +17 -0
  197. package/dist/ai/task.js.map +1 -0
  198. package/dist/ai/tasks/attack.js +24 -0
  199. package/dist/ai/tasks/attack.js.map +1 -0
  200. package/dist/ai/tasks/capture.d.ts +3 -3
  201. package/dist/ai/tasks/capture.js +37 -0
  202. package/dist/ai/tasks/capture.js.map +1 -0
  203. package/dist/ai/tasks/creep.js +29 -0
  204. package/dist/ai/tasks/creep.js.map +1 -0
  205. package/dist/ai/tasks/defend.js +61 -0
  206. package/dist/ai/tasks/defend.js.map +1 -0
  207. package/dist/ai/tasks/drop.js +81 -0
  208. package/dist/ai/tasks/drop.js.map +1 -0
  209. package/dist/ai/tasks/escort.js +59 -0
  210. package/dist/ai/tasks/escort.js.map +1 -0
  211. package/dist/ai/tasks/gather.js +48 -0
  212. package/dist/ai/tasks/gather.js.map +1 -0
  213. package/dist/ai/tasks/harass.js +39 -0
  214. package/dist/ai/tasks/harass.js.map +1 -0
  215. package/dist/ai/tasks/hold.js +32 -0
  216. package/dist/ai/tasks/hold.js.map +1 -0
  217. package/dist/ai/tasks/index.js +34 -0
  218. package/dist/ai/tasks/index.js.map +1 -0
  219. package/dist/ai/tasks/move.js +26 -0
  220. package/dist/ai/tasks/move.js.map +1 -0
  221. package/dist/ai/tasks/patrol.js +59 -0
  222. package/dist/ai/tasks/patrol.js.map +1 -0
  223. package/dist/ai/tasks/retreat.js +28 -0
  224. package/dist/ai/tasks/retreat.js.map +1 -0
  225. package/dist/ai/tasks/scout.js +73 -0
  226. package/dist/ai/tasks/scout.js.map +1 -0
  227. package/dist/ai/tasks/shared.d.ts +1 -1
  228. package/dist/ai/tasks/shared.js +137 -0
  229. package/dist/ai/tasks/shared.js.map +1 -0
  230. package/dist/ai/team.d.ts +18 -1
  231. package/dist/ai/team.js +492 -0
  232. package/dist/ai/team.js.map +1 -0
  233. package/dist/ai/threat.d.ts +6 -0
  234. package/dist/ai/threat.js +206 -0
  235. package/dist/ai/threat.js.map +1 -0
  236. package/dist/ai/view.d.ts +21 -7
  237. package/dist/ai/view.js +677 -0
  238. package/dist/ai/view.js.map +1 -0
  239. package/dist/ai/waves.d.ts +6 -0
  240. package/dist/ai/waves.js +410 -0
  241. package/dist/ai/waves.js.map +1 -0
  242. package/dist/ai.js +54 -6239
  243. package/dist/aiTesting.d.ts +6 -3
  244. package/dist/aiTesting.js +229 -0
  245. package/dist/aiTesting.js.map +1 -0
  246. package/dist/areas.d.ts +4 -1
  247. package/dist/areas.js +295 -0
  248. package/dist/areas.js.map +1 -0
  249. package/dist/attacks.d.ts +3 -3
  250. package/dist/attacks.js +127 -0
  251. package/dist/attacks.js.map +1 -0
  252. package/dist/burning.d.ts +267 -0
  253. package/dist/burning.js +795 -0
  254. package/dist/burning.js.map +1 -0
  255. package/dist/bytes.js +21 -0
  256. package/dist/bytes.js.map +1 -0
  257. package/dist/callings.d.ts +71 -0
  258. package/dist/callings.js +157 -0
  259. package/dist/callings.js.map +1 -0
  260. package/dist/cameraOrders.d.ts +78 -0
  261. package/dist/cameraOrders.js +114 -0
  262. package/dist/cameraOrders.js.map +1 -0
  263. package/dist/camps.d.ts +70 -4
  264. package/dist/camps.js +501 -0
  265. package/dist/camps.js.map +1 -0
  266. package/dist/capture.d.ts +15 -3
  267. package/dist/capture.js +304 -0
  268. package/dist/capture.js.map +1 -0
  269. package/dist/cellLayers.d.ts +78 -13
  270. package/dist/cellLayers.js +275 -0
  271. package/dist/cellLayers.js.map +1 -0
  272. package/dist/cellPatches.d.ts +24 -0
  273. package/dist/cellPatches.js +73 -0
  274. package/dist/cellPatches.js.map +1 -0
  275. package/dist/cinematics.d.ts +10 -5
  276. package/dist/cinematics.js +161 -0
  277. package/dist/cinematics.js.map +1 -0
  278. package/dist/clock.d.ts +2 -2
  279. package/dist/clock.js +78 -0
  280. package/dist/clock.js.map +1 -0
  281. package/dist/commands.d.ts +36 -4
  282. package/dist/commands.js +636 -0
  283. package/dist/commands.js.map +1 -0
  284. package/dist/components.d.ts +31 -10
  285. package/dist/components.js +74 -0
  286. package/dist/components.js.map +1 -0
  287. package/dist/computers.d.ts +4 -4
  288. package/dist/computers.js +194 -0
  289. package/dist/computers.js.map +1 -0
  290. package/dist/concealment.d.ts +25 -2
  291. package/dist/concealment.js +409 -0
  292. package/dist/concealment.js.map +1 -0
  293. package/dist/coreComponents.js +130 -0
  294. package/dist/coreComponents.js.map +1 -0
  295. package/dist/createGame.d.ts +306 -0
  296. package/dist/createGame.js +405 -0
  297. package/dist/createGame.js.map +1 -0
  298. package/dist/dashing.d.ts +18 -2
  299. package/dist/dashing.js +41 -0
  300. package/dist/dashing.js.map +1 -0
  301. package/dist/debug.d.ts +8 -0
  302. package/dist/debug.js +5 -3
  303. package/dist/debug2.js +76 -0
  304. package/dist/debug2.js.map +1 -0
  305. package/dist/debugCommands.d.ts +6 -6
  306. package/dist/debugCommands.js +537 -0
  307. package/dist/debugCommands.js.map +1 -0
  308. package/dist/debugging.d.ts +1 -0
  309. package/dist/defaultSets.d.ts +183 -0
  310. package/dist/defaultSets.js +216 -0
  311. package/dist/defaultSets.js.map +1 -0
  312. package/dist/definitions.d.ts +6 -0
  313. package/dist/definitions.js +78 -0
  314. package/dist/definitions.js.map +1 -0
  315. package/dist/defs.d.ts +1895 -165
  316. package/dist/defs.js +380 -0
  317. package/dist/defs.js.map +1 -0
  318. package/dist/denying.d.ts +4 -4
  319. package/dist/denying.js +106 -0
  320. package/dist/denying.js.map +1 -0
  321. package/dist/destructibles.d.ts +2 -2
  322. package/dist/destructibles.js +36 -0
  323. package/dist/destructibles.js.map +1 -0
  324. package/dist/determinism.d.ts +4 -4
  325. package/dist/determinism.js +247 -0
  326. package/dist/determinism.js.map +1 -0
  327. package/dist/dialog.d.ts +17 -2
  328. package/dist/dialog.js +108 -0
  329. package/dist/dialog.js.map +1 -0
  330. package/dist/effectRefs.js +28 -0
  331. package/dist/effectRefs.js.map +1 -0
  332. package/dist/effects.d.ts +27 -11
  333. package/dist/effects.js +110 -0
  334. package/dist/effects.js.map +1 -0
  335. package/dist/endings.d.ts +1 -1
  336. package/dist/endings.js +78 -0
  337. package/dist/endings.js.map +1 -0
  338. package/dist/engagement.d.ts +40 -6
  339. package/dist/engagement.js +530 -0
  340. package/dist/engagement.js.map +1 -0
  341. package/dist/engineEvents.d.ts +72 -9
  342. package/dist/engineEvents.js +520 -0
  343. package/dist/engineEvents.js.map +1 -0
  344. package/dist/entity.d.ts +275 -26
  345. package/dist/entity.js +441 -0
  346. package/dist/entity.js.map +1 -0
  347. package/dist/entityIndex.d.ts +10 -3
  348. package/dist/entityIndex.js +149 -0
  349. package/dist/entityIndex.js.map +1 -0
  350. package/dist/errors.d.ts +6 -2
  351. package/dist/errors.js +59 -0
  352. package/dist/errors.js.map +1 -0
  353. package/dist/events.d.ts +11 -5
  354. package/dist/events.js +158 -0
  355. package/dist/events.js.map +1 -0
  356. package/dist/exactMath.js +273 -0
  357. package/dist/exactMath.js.map +1 -0
  358. package/dist/features.d.ts +1 -1
  359. package/dist/features.js +127 -0
  360. package/dist/features.js.map +1 -0
  361. package/dist/fields.d.ts +25 -5
  362. package/dist/fields.js +140 -0
  363. package/dist/fields.js.map +1 -0
  364. package/dist/fixture.d.ts +3 -3
  365. package/dist/fixture.js +512 -0
  366. package/dist/fixture.js.map +1 -0
  367. package/dist/fog.d.ts +26 -3
  368. package/dist/fog.js +333 -0
  369. package/dist/fog.js.map +1 -0
  370. package/dist/foliage.d.ts +476 -0
  371. package/dist/foliage.js +1478 -0
  372. package/dist/foliage.js.map +1 -0
  373. package/dist/foliageDebug.d.ts +57 -0
  374. package/dist/foliageDebug.js +172 -0
  375. package/dist/foliageDebug.js.map +1 -0
  376. package/dist/foliageRegrowth.d.ts +20 -0
  377. package/dist/foliageRegrowth.js +332 -0
  378. package/dist/foliageRegrowth.js.map +1 -0
  379. package/dist/formState.d.ts +67 -0
  380. package/dist/formState.js +65 -0
  381. package/dist/formState.js.map +1 -0
  382. package/dist/formation.d.ts +46 -8
  383. package/dist/formation.js +297 -0
  384. package/dist/formation.js.map +1 -0
  385. package/dist/forms.d.ts +58 -0
  386. package/dist/forms.js +146 -0
  387. package/dist/forms.js.map +1 -0
  388. package/dist/friendlyFire.d.ts +2 -2
  389. package/dist/friendlyFire.js +37 -0
  390. package/dist/friendlyFire.js.map +1 -0
  391. package/dist/game.d.ts +141 -48
  392. package/dist/game.js +834 -0
  393. package/dist/game.js.map +1 -0
  394. package/dist/gameData.d.ts +96 -22
  395. package/dist/gameData.js +1690 -0
  396. package/dist/gameData.js.map +1 -0
  397. package/dist/gameFiles.d.ts +3 -3
  398. package/dist/gameFiles.js +14 -0
  399. package/dist/gameFiles.js.map +1 -0
  400. package/dist/gates.js +92 -0
  401. package/dist/gates.js.map +1 -0
  402. package/dist/generate.d.ts +28 -1
  403. package/dist/generate.js +1062 -0
  404. package/dist/generate.js.map +1 -0
  405. package/dist/generateWorker.d.ts +7 -3
  406. package/dist/generateWorker.js +86 -0
  407. package/dist/generateWorker.js.map +1 -0
  408. package/dist/grid.d.ts +9 -0
  409. package/dist/grid.js +102 -0
  410. package/dist/grid.js.map +1 -0
  411. package/dist/ground.d.ts +17 -1
  412. package/dist/ground.js +375 -0
  413. package/dist/ground.js.map +1 -0
  414. package/dist/groundObjects.d.ts +70 -0
  415. package/dist/groundObjects.js +371 -0
  416. package/dist/groundObjects.js.map +1 -0
  417. package/dist/groundSpeed.d.ts +20 -3
  418. package/dist/groundSpeed.js +117 -0
  419. package/dist/groundSpeed.js.map +1 -0
  420. package/dist/hero.d.ts +126 -10
  421. package/dist/hero.js +432 -0
  422. package/dist/hero.js.map +1 -0
  423. package/dist/holds.d.ts +94 -0
  424. package/dist/holds.js +305 -0
  425. package/dist/holds.js.map +1 -0
  426. package/dist/home.d.ts +1 -1
  427. package/dist/home.js +30 -0
  428. package/dist/home.js.map +1 -0
  429. package/dist/hooks.d.ts +339 -57
  430. package/dist/hooks.js +105 -0
  431. package/dist/hooks.js.map +1 -0
  432. package/dist/hotReload.d.ts +6 -5
  433. package/dist/hotReload.js +145 -0
  434. package/dist/hotReload.js.map +1 -0
  435. package/dist/ids.d.ts +3 -3
  436. package/dist/ids.js +30 -0
  437. package/dist/ids.js.map +1 -0
  438. package/dist/idsFile.d.ts +36 -0
  439. package/dist/idsFile.js +134 -0
  440. package/dist/idsFile.js.map +1 -0
  441. package/dist/index.d.ts +105 -68
  442. package/dist/index.js +194 -4701
  443. package/dist/inspect.d.ts +29 -2
  444. package/dist/{inspect-D9dWHmZ0.js → inspect.js} +21 -12
  445. package/dist/inspect.js.map +1 -0
  446. package/dist/inventory.d.ts +14 -1
  447. package/dist/inventory.js +84 -0
  448. package/dist/inventory.js.map +1 -0
  449. package/dist/items.d.ts +136 -8
  450. package/dist/items.js +585 -0
  451. package/dist/items.js.map +1 -0
  452. package/dist/lanes.d.ts +12 -3
  453. package/dist/lanes.js +496 -0
  454. package/dist/lanes.js.map +1 -0
  455. package/dist/life.d.ts +6 -2
  456. package/dist/life.js +287 -0
  457. package/dist/life.js.map +1 -0
  458. package/dist/log.d.ts +26 -3
  459. package/dist/log.js +192 -0
  460. package/dist/log.js.map +1 -0
  461. package/dist/manaBurn.d.ts +2 -2
  462. package/dist/manaBurn.js +75 -0
  463. package/dist/manaBurn.js.map +1 -0
  464. package/dist/map/file.d.ts +56 -3
  465. package/dist/map/file.js +264 -0
  466. package/dist/map/file.js.map +1 -0
  467. package/dist/map/images.js +61 -0
  468. package/dist/map/images.js.map +1 -0
  469. package/dist/map/look.d.ts +1 -1
  470. package/dist/map/look.js +30 -0
  471. package/dist/map/look.js.map +1 -0
  472. package/dist/map/pathProfile.js +183 -0
  473. package/dist/map/pathProfile.js.map +1 -0
  474. package/dist/map/resize.d.ts +4 -0
  475. package/dist/map/resize.js +136 -0
  476. package/dist/map/resize.js.map +1 -0
  477. package/dist/map/schema.js +257 -0
  478. package/dist/map/schema.js.map +1 -0
  479. package/dist/map/terrain.js +214 -0
  480. package/dist/map/terrain.js.map +1 -0
  481. package/dist/map/types.d.ts +92 -13
  482. package/dist/map/types.js +251 -0
  483. package/dist/map/types.js.map +1 -0
  484. package/dist/mapCheck/cells.js +94 -0
  485. package/dist/mapCheck/cells.js.map +1 -0
  486. package/dist/mapCheck/rules/foliage.d.ts +9 -0
  487. package/dist/mapCheck/rules/foliage.js +83 -0
  488. package/dist/mapCheck/rules/foliage.js.map +1 -0
  489. package/dist/mapCheck/rules/names.js +39 -0
  490. package/dist/mapCheck/rules/names.js.map +1 -0
  491. package/dist/mapCheck/rules/objects.d.ts +1 -1
  492. package/dist/mapCheck/rules/objects.js +56 -0
  493. package/dist/mapCheck/rules/objects.js.map +1 -0
  494. package/dist/mapCheck/rules/paths.js +32 -0
  495. package/dist/mapCheck/rules/paths.js.map +1 -0
  496. package/dist/mapCheck/rules/players.js +20 -0
  497. package/dist/mapCheck/rules/players.js.map +1 -0
  498. package/dist/mapCheck/rules/races.js +56 -0
  499. package/dist/mapCheck/rules/races.js.map +1 -0
  500. package/dist/mapCheck/rules/random.js +47 -0
  501. package/dist/mapCheck/rules/random.js.map +1 -0
  502. package/dist/mapCheck/rules/regions.js +30 -0
  503. package/dist/mapCheck/rules/regions.js.map +1 -0
  504. package/dist/mapCheck/rules/targets.js +31 -0
  505. package/dist/mapCheck/rules/targets.js.map +1 -0
  506. package/dist/mapCheck/rules/walking.js +45 -0
  507. package/dist/mapCheck/rules/walking.js.map +1 -0
  508. package/dist/mapCheck.d.ts +2 -2
  509. package/dist/mapCheck.js +63 -0
  510. package/dist/mapCheck.js.map +1 -0
  511. package/dist/mapFields.d.ts +25 -2
  512. package/dist/mapFields.js +134 -0
  513. package/dist/mapFields.js.map +1 -0
  514. package/dist/mapFile.js +176 -0
  515. package/dist/mapFile.js.map +1 -0
  516. package/dist/mapMeasure.d.ts +8 -0
  517. package/dist/mapMeasure.js +283 -0
  518. package/dist/mapMeasure.js.map +1 -0
  519. package/dist/mapMerge.d.ts +1 -0
  520. package/dist/mapMerge.js +172 -0
  521. package/dist/mapMerge.js.map +1 -0
  522. package/dist/mapObjectives.js +138 -0
  523. package/dist/mapObjectives.js.map +1 -0
  524. package/dist/mapObjects.js +80 -0
  525. package/dist/mapObjects.js.map +1 -0
  526. package/dist/math.d.ts +37 -7
  527. package/dist/math.js +155 -0
  528. package/dist/math.js.map +1 -0
  529. package/dist/messages.d.ts +71 -4
  530. package/dist/messages.js +29 -0
  531. package/dist/messages.js.map +1 -0
  532. package/dist/missionRules.d.ts +10 -2
  533. package/dist/{missionRules-C-bGxm0Q.js → missionRules.js} +30 -150
  534. package/dist/missionRules.js.map +1 -0
  535. package/dist/mods.d.ts +39 -20
  536. package/dist/mods.js +271 -0
  537. package/dist/mods.js.map +1 -0
  538. package/dist/moves.d.ts +87 -0
  539. package/dist/moves.js +539 -0
  540. package/dist/moves.js.map +1 -0
  541. package/dist/names.d.ts +7 -0
  542. package/dist/names.js +122 -0
  543. package/dist/names.js.map +1 -0
  544. package/dist/navigation/agentParams.js +14 -0
  545. package/dist/navigation/agentParams.js.map +1 -0
  546. package/dist/navigation/air.d.ts +7 -3
  547. package/dist/navigation/air.js +401 -0
  548. package/dist/navigation/air.js.map +1 -0
  549. package/dist/navigation/builds.d.ts +34 -2
  550. package/dist/navigation/builds.js +287 -0
  551. package/dist/navigation/builds.js.map +1 -0
  552. package/dist/navigation/groundAreas.d.ts +59 -1
  553. package/dist/navigation/groundAreas.js +407 -0
  554. package/dist/navigation/groundAreas.js.map +1 -0
  555. package/dist/navigation/navigation.d.ts +98 -9
  556. package/dist/navigation/recast.d.ts +194 -18
  557. package/dist/navigation/recast.js +1379 -0
  558. package/dist/navigation/recast.js.map +1 -0
  559. package/dist/navigation/sidePaths.d.ts +8 -3
  560. package/dist/navigation/sidePaths.js +241 -0
  561. package/dist/navigation/sidePaths.js.map +1 -0
  562. package/dist/navigation/sized.js +243 -0
  563. package/dist/navigation/sized.js.map +1 -0
  564. package/dist/nearest.js +32 -0
  565. package/dist/nearest.js.map +1 -0
  566. package/dist/noise.js +59 -0
  567. package/dist/noise.js.map +1 -0
  568. package/dist/objectives.d.ts +12 -3
  569. package/dist/objectives.js +144 -0
  570. package/dist/objectives.js.map +1 -0
  571. package/dist/orders/basic.d.ts +5 -5
  572. package/dist/orders/basic.js +417 -0
  573. package/dist/orders/basic.js.map +1 -0
  574. package/dist/orders/build.js +278 -0
  575. package/dist/orders/build.js.map +1 -0
  576. package/dist/orders/cast.d.ts +13 -3
  577. package/dist/orders/cast.js +558 -0
  578. package/dist/orders/cast.js.map +1 -0
  579. package/dist/orders/facts.js +16 -0
  580. package/dist/orders/facts.js.map +1 -0
  581. package/dist/orders/harvest.d.ts +21 -5
  582. package/dist/orders/harvest.js +540 -0
  583. package/dist/orders/harvest.js.map +1 -0
  584. package/dist/orders/idle.d.ts +3 -1
  585. package/dist/orders/idle.js +234 -0
  586. package/dist/orders/idle.js.map +1 -0
  587. package/dist/orders/items.js +92 -0
  588. package/dist/orders/items.js.map +1 -0
  589. package/dist/orders/queue.js +108 -0
  590. package/dist/orders/queue.js.map +1 -0
  591. package/dist/orders/waiting.d.ts +39 -0
  592. package/dist/orders/waiting.js +149 -0
  593. package/dist/orders/waiting.js.map +1 -0
  594. package/dist/pack.schema.js +13 -0
  595. package/dist/pack.schema.js.map +1 -0
  596. package/dist/pack.schema.json +7622 -841
  597. package/dist/packs/director/index.d.ts +13 -5
  598. package/dist/packs/director/index.js +204 -0
  599. package/dist/packs/director/index.js.map +1 -0
  600. package/dist/packs/heroes/campaign.d.ts +3 -2
  601. package/dist/packs/heroes/campaign.js +241 -0
  602. package/dist/packs/heroes/campaign.js.map +1 -0
  603. package/dist/packs/heroes/carry.d.ts +6 -0
  604. package/dist/packs/heroes/carry.js +112 -0
  605. package/dist/packs/heroes/carry.js.map +1 -0
  606. package/dist/packs/heroes/commands.js +115 -0
  607. package/dist/packs/heroes/commands.js.map +1 -0
  608. package/dist/packs/heroes/fallen.d.ts +43 -0
  609. package/dist/packs/heroes/fallen.js +61 -0
  610. package/dist/packs/heroes/fallen.js.map +1 -0
  611. package/dist/packs/heroes/hire.js +60 -0
  612. package/dist/packs/heroes/hire.js.map +1 -0
  613. package/dist/packs/heroes/index.d.ts +7 -6
  614. package/dist/packs/heroes/index.js +130 -0
  615. package/dist/packs/heroes/index.js.map +1 -0
  616. package/dist/packs/heroes/loop.d.ts +95 -0
  617. package/dist/packs/heroes/loop.js +250 -0
  618. package/dist/packs/heroes/loop.js.map +1 -0
  619. package/dist/packs/heroes/making.d.ts +6 -3
  620. package/dist/packs/heroes/making.js +55 -0
  621. package/dist/packs/heroes/making.js.map +1 -0
  622. package/dist/packs/heroes/respawn.d.ts +3 -3
  623. package/dist/packs/heroes/respawn.js +87 -0
  624. package/dist/packs/heroes/respawn.js.map +1 -0
  625. package/dist/packs/heroes/sets.d.ts +32 -0
  626. package/dist/packs/heroes/sets.js +51 -0
  627. package/dist/packs/heroes/sets.js.map +1 -0
  628. package/dist/packs/heroes/spells.d.ts +16 -0
  629. package/dist/packs/heroes/spells.js +269 -0
  630. package/dist/packs/heroes/spells.js.map +1 -0
  631. package/dist/packs/items/defaults.d.ts +43 -0
  632. package/dist/packs/items/defaults.js +1504 -0
  633. package/dist/packs/items/defaults.js.map +1 -0
  634. package/dist/packs/items/index.d.ts +27 -0
  635. package/dist/packs/items/index.js +214 -0
  636. package/dist/packs/items/index.js.map +1 -0
  637. package/dist/packs/moba/index.d.ts +3 -3
  638. package/dist/packs/moba/index.js +174 -0
  639. package/dist/packs/moba/index.js.map +1 -0
  640. package/dist/packs/pack.d.ts +15 -15
  641. package/dist/packs/pack.js +14 -0
  642. package/dist/packs/pack.js.map +1 -0
  643. package/dist/packs.d.ts +15 -7
  644. package/dist/packs.js +222 -0
  645. package/dist/packs.js.map +1 -0
  646. package/dist/paths.d.ts +2 -0
  647. package/dist/paths.js +109 -0
  648. package/dist/paths.js.map +1 -0
  649. package/dist/plain.js +57 -0
  650. package/dist/plain.js.map +1 -0
  651. package/dist/player.d.ts +33 -10
  652. package/dist/player.js +159 -0
  653. package/dist/player.js.map +1 -0
  654. package/dist/portals.d.ts +1 -1
  655. package/dist/portals.js +194 -0
  656. package/dist/portals.js.map +1 -0
  657. package/dist/prefabs.d.ts +25 -2
  658. package/dist/prefabs.js +239 -0
  659. package/dist/prefabs.js.map +1 -0
  660. package/dist/presetBuildings.js +58 -0
  661. package/dist/presetBuildings.js.map +1 -0
  662. package/dist/presetFoliage.d.ts +27 -0
  663. package/dist/presetFoliage.js +98 -0
  664. package/dist/presetFoliage.js.map +1 -0
  665. package/dist/presetGround.js +65 -0
  666. package/dist/presetGround.js.map +1 -0
  667. package/dist/proxies.d.ts +12 -0
  668. package/dist/proxies.js +79 -0
  669. package/dist/proxies.js.map +1 -0
  670. package/dist/query.d.ts +56 -0
  671. package/dist/query.js +88 -0
  672. package/dist/query.js.map +1 -0
  673. package/dist/races.d.ts +15 -14
  674. package/dist/races.js +172 -0
  675. package/dist/races.js.map +1 -0
  676. package/dist/randomGroups.js +91 -0
  677. package/dist/randomGroups.js.map +1 -0
  678. package/dist/registry.d.ts +117 -53
  679. package/dist/registry.js +323 -0
  680. package/dist/registry.js.map +1 -0
  681. package/dist/remains.d.ts +11 -9
  682. package/dist/remains.js +188 -0
  683. package/dist/remains.js.map +1 -0
  684. package/dist/replication.d.ts +12 -7
  685. package/dist/replication.js +100 -0
  686. package/dist/replication.js.map +1 -0
  687. package/dist/rng.d.ts +2 -0
  688. package/dist/rng.js +40 -0
  689. package/dist/rng.js.map +1 -0
  690. package/dist/rules.d.ts +186 -99
  691. package/dist/rules.js +179 -0
  692. package/dist/rules.js.map +1 -0
  693. package/dist/rulesCheck.d.ts +5 -4
  694. package/dist/rulesCheck.js +693 -0
  695. package/dist/rulesCheck.js.map +1 -0
  696. package/dist/runes.d.ts +2 -2
  697. package/dist/runes.js +80 -0
  698. package/dist/runes.js.map +1 -0
  699. package/dist/save.d.ts +37 -12
  700. package/dist/save.js +532 -0
  701. package/dist/save.js.map +1 -0
  702. package/dist/scenario.d.ts +2 -2
  703. package/dist/scenario.js +99 -0
  704. package/dist/scenario.js.map +1 -0
  705. package/dist/scheduler.d.ts +3 -0
  706. package/dist/scheduler.js +156 -0
  707. package/dist/scheduler.js.map +1 -0
  708. package/dist/score.d.ts +19 -19
  709. package/dist/score.js +709 -0
  710. package/dist/score.js.map +1 -0
  711. package/dist/sequences.d.ts +10 -6
  712. package/dist/sequences.js +206 -0
  713. package/dist/sequences.js.map +1 -0
  714. package/dist/server/doorman.js +154 -0
  715. package/dist/server/doorman.js.map +1 -0
  716. package/dist/server/gameServer.d.ts +16 -1
  717. package/dist/server/gameServer.js +643 -0
  718. package/dist/server/gameServer.js.map +1 -0
  719. package/dist/server/index.d.ts +1 -1
  720. package/dist/server/lobby.js +199 -0
  721. package/dist/server/lobby.js.map +1 -0
  722. package/dist/server/log.js +18 -0
  723. package/dist/server/log.js.map +1 -0
  724. package/dist/server/match.js +267 -0
  725. package/dist/server/match.js.map +1 -0
  726. package/dist/server/mode.d.ts +18 -9
  727. package/dist/server/mode.js +220 -0
  728. package/dist/server/mode.js.map +1 -0
  729. package/dist/{navigation-worker.js → server/navigation-worker.js} +1 -1
  730. package/dist/server/navigation-worker.js.map +1 -0
  731. package/dist/server/navigation.js +39 -0
  732. package/dist/server/navigation.js.map +1 -0
  733. package/dist/server/ops.d.ts +4 -0
  734. package/dist/server/ops.js +137 -0
  735. package/dist/server/ops.js.map +1 -0
  736. package/dist/server/packs.d.ts +3 -3
  737. package/dist/server/packs.js +32 -0
  738. package/dist/server/packs.js.map +1 -0
  739. package/dist/server/ratings.d.ts +5 -0
  740. package/dist/server/ratings.js +104 -0
  741. package/dist/server/ratings.js.map +1 -0
  742. package/dist/server/relay.d.ts +12 -2
  743. package/dist/server/relay.js +144 -0
  744. package/dist/server/relay.js.map +1 -0
  745. package/dist/server/rooms.d.ts +9 -2
  746. package/dist/server/rooms.js +442 -0
  747. package/dist/server/rooms.js.map +1 -0
  748. package/dist/server/seat.js +116 -0
  749. package/dist/server/seat.js.map +1 -0
  750. package/dist/server/seatSettings.d.ts +3 -3
  751. package/dist/server/seatSettings.js +63 -0
  752. package/dist/server/seatSettings.js.map +1 -0
  753. package/dist/server/secret.js +13 -0
  754. package/dist/server/secret.js.map +1 -0
  755. package/dist/server/start.d.ts +13 -6
  756. package/dist/server/start.js +76 -0
  757. package/dist/server/start.js.map +1 -0
  758. package/dist/server/websocket.d.ts +9 -1
  759. package/dist/server/websocket.js +306 -0
  760. package/dist/server/websocket.js.map +1 -0
  761. package/dist/server.js +15 -2861
  762. package/dist/session/can.js +26 -0
  763. package/dist/session/can.js.map +1 -0
  764. package/dist/session/commandReplay.d.ts +8 -2
  765. package/dist/session/commandReplay.js +293 -0
  766. package/dist/session/commandReplay.js.map +1 -0
  767. package/dist/session/debug.js +151 -0
  768. package/dist/session/debug.js.map +1 -0
  769. package/dist/session/delay.js +62 -0
  770. package/dist/session/delay.js.map +1 -0
  771. package/dist/session/delta.d.ts +14 -1
  772. package/dist/session/delta.js +407 -0
  773. package/dist/session/delta.js.map +1 -0
  774. package/dist/session/entityState.js +415 -0
  775. package/dist/session/entityState.js.map +1 -0
  776. package/dist/session/local.d.ts +47 -5
  777. package/dist/session/local.js +670 -0
  778. package/dist/session/local.js.map +1 -0
  779. package/dist/session/memory.d.ts +20 -2
  780. package/dist/session/memory.js +131 -0
  781. package/dist/session/memory.js.map +1 -0
  782. package/dist/session/protocol.d.ts +325 -31
  783. package/dist/session/protocol.js +55 -0
  784. package/dist/session/protocol.js.map +1 -0
  785. package/dist/session/remote.d.ts +74 -12
  786. package/dist/session/remote.js +1394 -0
  787. package/dist/session/remote.js.map +1 -0
  788. package/dist/session/replay.d.ts +11 -2
  789. package/dist/session/replay.js +160 -0
  790. package/dist/session/replay.js.map +1 -0
  791. package/dist/session/seed.js +12 -0
  792. package/dist/session/seed.js.map +1 -0
  793. package/dist/session/share.d.ts +5 -1
  794. package/dist/session/share.js +94 -0
  795. package/dist/session/share.js.map +1 -0
  796. package/dist/session/socket.d.ts +1 -1
  797. package/dist/session/socket.js +29 -0
  798. package/dist/session/socket.js.map +1 -0
  799. package/dist/session/wire.d.ts +5 -0
  800. package/dist/session/wire.js +84 -0
  801. package/dist/session/wire.js.map +1 -0
  802. package/dist/session/worker.d.ts +77 -12
  803. package/dist/session/worker.js +499 -0
  804. package/dist/session/worker.js.map +1 -0
  805. package/dist/shared.d.ts +31 -5
  806. package/dist/shared.js +166 -0
  807. package/dist/shared.js.map +1 -0
  808. package/dist/sides.d.ts +9 -3
  809. package/dist/sides.js +149 -0
  810. package/dist/sides.js.map +1 -0
  811. package/dist/sight.js +85 -0
  812. package/dist/sight.js.map +1 -0
  813. package/dist/simulate-worker.js +1 -1
  814. package/dist/simulate.d.ts +12 -8
  815. package/dist/{simulate-oXBiw1Ff.js → simulate.js} +10 -11
  816. package/dist/simulate.js.map +1 -0
  817. package/dist/smart.js +77 -0
  818. package/dist/smart.js.map +1 -0
  819. package/dist/spatial.d.ts +32 -16
  820. package/dist/spatial.js +234 -0
  821. package/dist/spatial.js.map +1 -0
  822. package/dist/spawning.d.ts +1 -0
  823. package/dist/spawning.js +224 -0
  824. package/dist/spawning.js.map +1 -0
  825. package/dist/stances.d.ts +6 -3
  826. package/dist/stances.js +169 -0
  827. package/dist/stances.js.map +1 -0
  828. package/dist/start.d.ts +10 -10
  829. package/dist/start.js +75 -0
  830. package/dist/start.js.map +1 -0
  831. package/dist/stats.d.ts +42 -16
  832. package/dist/stats.js +290 -0
  833. package/dist/stats.js.map +1 -0
  834. package/dist/summoned.d.ts +52 -0
  835. package/dist/summoned.js +38 -0
  836. package/dist/summoned.js.map +1 -0
  837. package/dist/summons.d.ts +10 -13
  838. package/dist/summons.js +271 -0
  839. package/dist/summons.js.map +1 -0
  840. package/dist/systems/abilities.js +224 -0
  841. package/dist/systems/abilities.js.map +1 -0
  842. package/dist/systems/combat.d.ts +35 -1
  843. package/dist/systems/combat.js +677 -0
  844. package/dist/systems/combat.js.map +1 -0
  845. package/dist/systems/combatTold.d.ts +3 -1
  846. package/dist/systems/combatTold.js +85 -0
  847. package/dist/systems/combatTold.js.map +1 -0
  848. package/dist/systems/construction.js +80 -0
  849. package/dist/systems/construction.js.map +1 -0
  850. package/dist/systems/economy.d.ts +0 -6
  851. package/dist/systems/economy.js +128 -0
  852. package/dist/systems/economy.js.map +1 -0
  853. package/dist/systems/fog.d.ts +1 -1
  854. package/dist/systems/fog.js +120 -0
  855. package/dist/systems/fog.js.map +1 -0
  856. package/dist/systems/life.js +32 -0
  857. package/dist/systems/life.js.map +1 -0
  858. package/dist/systems/movement.d.ts +24 -12
  859. package/dist/systems/movement.js +1247 -0
  860. package/dist/systems/movement.js.map +1 -0
  861. package/dist/systems/orders.js +64 -0
  862. package/dist/systems/orders.js.map +1 -0
  863. package/dist/systems/production.js +322 -0
  864. package/dist/systems/production.js.map +1 -0
  865. package/dist/systems/productionQueue.js +120 -0
  866. package/dist/systems/productionQueue.js.map +1 -0
  867. package/dist/systems/victory.d.ts +1 -1
  868. package/dist/systems/victory.js +56 -0
  869. package/dist/systems/victory.js.map +1 -0
  870. package/dist/talk.d.ts +6 -6
  871. package/dist/talk.js +153 -0
  872. package/dist/talk.js.map +1 -0
  873. package/dist/targeting.d.ts +142 -0
  874. package/dist/targeting.js +49 -0
  875. package/dist/targeting.js.map +1 -0
  876. package/dist/tech.d.ts +20 -3
  877. package/dist/tech.js +239 -0
  878. package/dist/tech.js.map +1 -0
  879. package/dist/techTree.d.ts +7 -0
  880. package/dist/techTree.js +90 -0
  881. package/dist/techTree.js.map +1 -0
  882. package/dist/terrain.d.ts +59 -7
  883. package/dist/terrain.js +389 -0
  884. package/dist/terrain.js.map +1 -0
  885. package/dist/terrainSave.d.ts +6 -0
  886. package/dist/terrainSave.js +74 -0
  887. package/dist/terrainSave.js.map +1 -0
  888. package/dist/testing.d.ts +8 -7
  889. package/dist/testing.js +13 -739
  890. package/dist/testing.js.map +1 -1
  891. package/dist/tiles.d.ts +1 -1
  892. package/dist/tiles.js +43 -0
  893. package/dist/tiles.js.map +1 -0
  894. package/dist/timers.d.ts +29 -4
  895. package/dist/timers.js +242 -0
  896. package/dist/timers.js.map +1 -0
  897. package/dist/tomes.d.ts +4 -4
  898. package/dist/tomes.js +94 -0
  899. package/dist/tomes.js.map +1 -0
  900. package/dist/trade.js +103 -0
  901. package/dist/trade.js.map +1 -0
  902. package/dist/transport.d.ts +6 -1
  903. package/dist/transport.js +281 -0
  904. package/dist/transport.js.map +1 -0
  905. package/dist/tunables.d.ts +10 -3
  906. package/dist/tunables.js +56 -0
  907. package/dist/tunables.js.map +1 -0
  908. package/dist/unitResources.d.ts +67 -0
  909. package/dist/unitResources.js +266 -0
  910. package/dist/unitResources.js.map +1 -0
  911. package/dist/upkeep.d.ts +6 -1
  912. package/dist/upkeep.js +26 -0
  913. package/dist/upkeep.js.map +1 -0
  914. package/dist/veterancy.d.ts +8 -3
  915. package/dist/veterancy.js +131 -0
  916. package/dist/veterancy.js.map +1 -0
  917. package/dist/vision.d.ts +36 -0
  918. package/dist/vision.js +133 -0
  919. package/dist/vision.js.map +1 -0
  920. package/dist/walls.d.ts +1 -1
  921. package/dist/walls.js +278 -0
  922. package/dist/walls.js.map +1 -0
  923. package/dist/world.d.ts +606 -88
  924. package/dist/world.js +1263 -0
  925. package/dist/world.js.map +1 -0
  926. package/package.json +2 -2
  927. package/dist/ai.js.map +0 -1
  928. package/dist/attributes.d.ts +0 -66
  929. package/dist/brain-BvVdUhX8.js +0 -7659
  930. package/dist/brain-BvVdUhX8.js.map +0 -1
  931. package/dist/builds-C6LfgvEU.js +0 -460
  932. package/dist/builds-C6LfgvEU.js.map +0 -1
  933. package/dist/coreComponents-syuh2fPG.js +0 -5149
  934. package/dist/coreComponents-syuh2fPG.js.map +0 -1
  935. package/dist/debugCommands-CzjrSm66.js +0 -14739
  936. package/dist/debugCommands-CzjrSm66.js.map +0 -1
  937. package/dist/determinism-BCymQwiE.js +0 -518
  938. package/dist/determinism-BCymQwiE.js.map +0 -1
  939. package/dist/game-DiJEN-Ks.js +0 -5800
  940. package/dist/game-DiJEN-Ks.js.map +0 -1
  941. package/dist/index.js.map +0 -1
  942. package/dist/inspect-D9dWHmZ0.js.map +0 -1
  943. package/dist/local-Dkovq42k.js +0 -1379
  944. package/dist/local-Dkovq42k.js.map +0 -1
  945. package/dist/missionRules-C-bGxm0Q.js.map +0 -1
  946. package/dist/navigation-worker.js.map +0 -1
  947. package/dist/packs-g5thvmGn.js +0 -3199
  948. package/dist/packs-g5thvmGn.js.map +0 -1
  949. package/dist/profiles-B3NS9jwk.js.map +0 -1
  950. package/dist/server.js.map +0 -1
  951. package/dist/simulate-oXBiw1Ff.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defs.js","names":[],"sources":["../src/defs.ts"],"sourcesContent":["import type { AbilityAiView } from './ai/micro'\nimport type { AiHints } from './ai/roles'\nimport type { AbilityTextContext, AbilityValueDef, CasterFacts, TextSegment } from './abilities/text'\nimport type { EffectContext } from './abilities/effects'\nimport type { EntityState } from './session/protocol'\n/**\n * Static game data. Everything a game module (melee, custom map, mod) defines about\n * its units lives in plain objects like these, the engine never hardcodes a unit.\n */\n\nimport type { RuleSettings } from './rules'\nimport type { AbilityState, BuffInstance, Entity } from './entity'\nimport type { Vec2 } from './math'\nimport type { World } from './world'\nimport type { BurnsDef } from './burning'\n\n/**\n * A value that can grow with the level of an ability: one number, or one per level\n *\n * @beta\n */\nexport type Scaled = number | number[]\n\n/**\n * What an amount in code is asked with (`EffectValue`): the ability's level and what the caster brings now, and the effect\n * as it lands, where it is landing. The tooltip asks it too (`abilityValues`), with no `effect` and no target\n *\n * @beta\n */\nexport interface EffectValueContext {\n\t/** The level of the ability */\n\tlevel: number\n\t/** What the caster brings to the numbers now: its stats, its level as a hero (`casterFacts`) */\n\tcaster: CasterFacts\n\t/** The effect as it lands: the world, the caster, where, how far a missile came. Not there for the tooltip */\n\teffect?: EffectContext\n}\n\n/**\n * An amount, a time or a size of an effect: a number, one per level (`Scaled`), or worked out in code for each target as\n * it lands (`(context, target) => number`: a share of what the target lacks, more for each mark on it, by how far it\n * flew). Code is asked with no target where the effect is not for one (a zone's time, an area's size) and by the\n * tooltip; what the screen draws before a cast (the aim) has no caster to ask, and takes `AbilityDef.aim`\n *\n * @beta\n */\nexport type EffectValue = Scaled | ((context: EffectValueContext, target?: Entity) => number)\n\n/**\n * The value at a level. Levels past the end of the list get the last one\n *\n * @beta\n */\nexport function at(value: Scaled | undefined, level: number, fallback = 0): number {\n\tif (value === undefined) return fallback\n\tif (typeof value === 'number') return value\n\treturn value[Math.min(Math.max(level, 1), value.length) - 1] ?? fallback\n}\n\n/**\n * The value of an amount where there is no caster to ask its code (`EffectValue`): at the level, or `fallback` for code.\n * What the aim the screen draws and a computer player's guesses go by\n *\n * @beta\n */\nexport function declaredAt(value: EffectValue | undefined, level: number, fallback = 0): number {\n\treturn typeof value === 'function' ? fallback : at(value, level, fallback)\n}\n\n/**\n * The stats the engine reads: what a unit has of health, mana and their regeneration, how it moves, sees and attacks,\n * and its armor and magic resist (the two kinds of damage there are besides true). Levels, items, buffs and research\n * change them. A game adds stats of its own with `Rules.stats`, a pack its own (`GamePack.stats`: the MOBA\n * stats of `mobaStatsPack`).\n *\n * @beta\n */\nexport interface CoreStats {\n\t// ---- offense\n\t/** What a basic attack deals, before the armor of the target */\n\tattackDamage: number\n\t/** Attacks per second */\n\tattackSpeed: number\n\t/** Measured between the edges of attacker and target */\n\tattackRange: number\n\n\t// ---- defense\n\t/** The most health a unit has; the entity's `maxHealth` follows it */\n\thealth: number\n\t/** Against physical damage: 100 of it halve what arrives */\n\tarmor: number\n\t/** The same against magic damage */\n\tmagicResist: number\n\t/**\n\t * Part by which the damage it takes is more or less, after armor or magic resist and before shields: -0.3 takes 30%\n\t * less, 0.2 a fifth more. Added up with the part of the damage's own type (below), and never below none\n\t */\n\tincomingDamage: number\n\t/** The same, of physical damage only, on top of `incomingDamage` */\n\tincomingPhysicalDamage: number\n\t/** The same, of magic damage only, on top of `incomingDamage` */\n\tincomingMagicDamage: number\n\t/** The same, of true damage only, on top of `incomingDamage` */\n\tincomingTrueDamage: number\n\t/**\n\t * Part by which all the damage it deals, of attacks and abilities, is more or less: -0.35 deals 35% less. Never below\n\t * none\n\t */\n\toutgoingDamage: number\n\t/** Part by which the healing it gets is more or less: -0.4 heals 40% less (an anti-heal). Never below none */\n\tincomingHealing: number\n\n\t// ---- sustain and resources\n\t/** Per second */\n\thealthRegen: number\n\t/** The most mana a unit has */\n\tmana: number\n\t/** Per second */\n\tmanaRegen: number\n\n\t// ---- utility\n\t/** Units per second. Who has none cannot move */\n\tmoveSpeed: number\n\t/** How far it sees. At night the unit type says how far that is */\n\tsight: number\n}\n\n/**\n * The name of one of the engine's stats\n *\n * @internal\n */\nexport type CoreStatKey = keyof CoreStats\n\n/**\n * All of a unit's stats: the engine's, and the game's own by their ids\n *\n * @beta\n */\nexport type Stats = CoreStats & Record<string, number>\n\n/**\n * A stat: one of the engine's (`CoreStatKey`), or one a game defined. Checked when the game is built\n *\n * @beta\n */\nexport type StatKey = string\n\n/**\n * A stat of a game's own, next to the engine's\n *\n * @beta\n */\nexport interface StatDef {\n\t/** The stat's id, which units, changes and abilities name it by */\n\tid: string\n\t/** What the player sees the stat called */\n\tname: string\n\t/** Shown when the pointer is over it */\n\tdescription?: string\n\t/** What every unit has of it unless its type says. 0 when left out */\n\tdefault?: number\n\t/** It never goes below or above these, whatever changes it */\n\tmin?: number\n\t/** The highest the stat goes, whatever changes it; no upper bound when left out */\n\tmax?: number\n\t/** How it is shown: a whole number, a decimal, or a part of one as a percentage. A whole number when left out */\n\tformat?: 'number' | 'decimal' | 'percent'\n}\n\n/**\n * The keys of the engine's stats, in the order `CoreStats` lists them\n *\n * @internal\n */\nexport const CORE_STAT_KEYS: CoreStatKey[] = [\n\t'attackDamage',\n\t'attackSpeed',\n\t'attackRange',\n\t'health',\n\t'armor',\n\t'magicResist',\n\t'incomingDamage',\n\t'incomingPhysicalDamage',\n\t'incomingMagicDamage',\n\t'incomingTrueDamage',\n\t'outgoingDamage',\n\t'incomingHealing',\n\t'healthRegen',\n\t'mana',\n\t'manaRegen',\n\t'moveSpeed',\n\t'sight'\n]\n\n/**\n * Gives a `CoreStats` with every stat at 0\n *\n * @beta\n */\nexport const noStats = (): CoreStats => ({\n\tattackDamage: 0,\n\tattackSpeed: 0,\n\tattackRange: 0,\n\thealth: 0,\n\tarmor: 0,\n\tmagicResist: 0,\n\tincomingDamage: 0,\n\tincomingPhysicalDamage: 0,\n\tincomingMagicDamage: 0,\n\tincomingTrueDamage: 0,\n\toutgoingDamage: 0,\n\tincomingHealing: 0,\n\thealthRegen: 0,\n\tmana: 0,\n\tmanaRegen: 0,\n\tmoveSpeed: 0,\n\tsight: 0\n})\n\n/**\n * How the days go by. Hours run from 0 to 24\n *\n * @beta\n */\nexport interface DayCycle {\n\t/** Seconds a whole day and night take */\n\tlength: number\n\t/** Hour of the day the game starts at */\n\tstart: number\n\t/** Hour the sun comes up */\n\tdawn: number\n\t/** Hour it goes down */\n\tdusk: number\n}\n\n/**\n * Hour of the day after so many seconds of play. Noon in a game without days\n *\n * @beta\n */\nexport function hourOf(day: DayCycle | null, seconds: number): number {\n\tif (!day) return 12\n\treturn (day.start + (seconds / day.length) * 24) % 24\n}\n\n/**\n * Whether the hour (0..24) is night under the day cycle, before its dawn or from its dusk; never night without a day cycle\n *\n * @beta\n */\nexport const isNight = (day: DayCycle | null, hour: number): boolean => !!day && (hour < day.dawn || hour >= day.dusk)\n\n/**\n * Something that changes stats: `stats` is added, `percent` makes them bigger or smaller by a part of what\n * they are with everything added. Parts from different places add up: two times +10% are +20%.\n *\n * @beta\n */\nexport interface StatChange {\n\t/** Amounts added to stats, by stat */\n\tstats?: Partial<Stats>\n\t/** Parts stats grow or shrink by, by stat: 0.1 is 10% more, and the parts add up before they are applied */\n\tpercent?: Partial<Stats>\n}\n\n/**\n * A change that grows with the level of the ability it comes from\n *\n * @beta\n */\nexport interface ScaledStatChange {\n\t/** Amounts added to stats, by stat, each growing with the ability's level */\n\tstats?: Partial<Record<StatKey, Scaled>>\n\t/** Parts stats grow or shrink by, by stat, each growing with the ability's level */\n\tpercent?: Partial<Record<StatKey, Scaled>>\n}\n\n/**\n * Physical damage is held off by armor, magic damage by magic resist, true damage by nothing\n *\n * @beta\n */\nexport type DamageType = 'physical' | 'magic' | 'true'\n\n/**\n * What makes a unit a hero: it gains levels, grows with them and learns abilities\n *\n * @beta\n */\nexport interface HeroDef {\n\t/** What every level after the first adds */\n\tgrowth: StatChange\n\t/** Abilities the hero can put points into */\n\tlearns: string[]\n\t/** Abilities it has from the start and does not learn: the two spells every hero brings along. No mana, and nothing shortens their cooldown */\n\tspells?: string[]\n\t/**\n\t * Its innate: an ability it has from level 1, for no point, that grows with it: its level is the hero's (up to the\n\t * ability's own `maxLevel` where it says one), or goes up at the hero levels of `innateLevels`. A passive most often\n\t * (its buffs, its triggers), or one it casts\n\t *\n\t * @beta\n\t */\n\tinnate?: string\n\t/**\n\t * The hero levels its innate goes up a level at, from its first: `[1, 6, 11, 16]` has it at level 2 from the hero's\n\t * sixth. The hero's own level, when left out\n\t *\n\t * @beta\n\t */\n\tinnateLevels?: number[]\n\t/**\n\t * What it is good at, by calling (`CallingDef`, the game's: `heroesPack({ callings })`), each with a strength from 1\n\t * to 3: `{ stalker: 3, roamer: 2 }`. They lock nothing: the shop's suggestions and filters, the tooltips and the\n\t * computer players go by them\n\t *\n\t * @beta\n\t */\n\tcallings?: Record<string, 1 | 2 | 3>\n\t/** The level it stops at. 10 when left out */\n\tmaxLevel?: number\n\t/** A buff whose stacks are shown next to its health and mana, as so many points out of as many as it can have */\n\tmeter?: string\n\t/**\n\t * The forms it takes (a `morph` effect's `into`), by unit type: what it learns in each (`HeroForm`). A form is a\n\t * hero's type of its own (its stats, its growth, its look); this says what of the hero's it takes along\n\t *\n\t * @beta\n\t */\n\tforms?: Record<string, HeroForm>\n}\n\n/**\n * What becomes of a hero's cooldowns going in and out of a form (`HeroForm.cooldowns`)\n *\n * @beta\n */\nexport type FormCooldowns = 'keep' | 'reset' | 'shared'\n\n/**\n * What a hero is in one of its forms (`HeroDef.forms`): the abilities it learns there by id (`learns`), the level each\n * starts at (`levels`: that of one of the hero's own, or a number), and what of its own the form leaves in place\n * (`keeps`). Everything else of its own is put away until it turns back\n *\n * ```ts\n * // Nidalee's cougar: Takedown at Rocket Grab's level and Pounce at Void Swarm's, Swipe learned in the form; the\n * // aspect (it made the form) and the ultimate stay as they are\n * forms: { cougar: { learns: ['takedown', 'pounce', 'swipe'], levels: { takedown: 'rocketGrab', pounce: 'voidSwarm' }, keeps: ['heartbreaker'] } }\n * ```\n *\n * The shorter shape, a list alone with neither `levels` nor `keeps`, is read by slot: the first at the level of the\n * first the hero learns as itself, the second of the second, and so on (Q is Q), a point put into one in the form going\n * to the hero's own at that slot too\n *\n * @beta\n */\nexport interface HeroForm {\n\t/**\n\t * The abilities it learns in the form, by id: what the HUD's card and hero panel show there, and what its points go\n\t * into, in this order (the hero's own it keeps after them). One of the hero's own named here is kept as it is. What\n\t * the form's type learns (its `hero.learns`) when left out\n\t */\n\tlearns?: string[]\n\t/**\n\t * The level each of `learns` starts at in the form, by id: the id of one of the hero's own abilities, whose level it\n\t * has (a point put into it in the form goes to that one too), or a number. 0 for what is not said: learned in the form\n\t */\n\tlevels?: Record<string, string | number>\n\t/**\n\t * The hero's own abilities the form leaves in place, by id: castable in the form as they are, level and cooldown (an\n\t * ultimate, a passive); learned there, those it learns as itself. The ability that made the form and the spells it\n\t * brought along (`HeroDef.spells`) are kept unsaid\n\t */\n\tkeeps?: string[]\n\t/**\n\t * What becomes of the cooldowns of what the form puts away and of what it brings, when the hero goes in and out of it\n\t * within the time of a cooldown:\n\t *\n\t * - left out: what the hero puts away runs down by the time it is away, and comes back with what is left; what the\n\t * form brings starts ready each time. The default\n\t * - `'keep'`: what is put away comes back exactly as it was left, the time away not counted: a form is not a way to\n\t * wait out a cooldown\n\t * - `'reset'`: what is put away comes back ready, its cooldown 0: a form is a way to get them back\n\t * - `'shared'`: an ability of the form whose level is one of the hero's own (`levels` by id, or by slot in the shorter\n\t * shape) has one cooldown with it: it starts with the cooldown of the one it takes the place of, and gives its\n\t * own, what it has by then (cast in the form or run down), back as the hero turns back. The rest as when left out\n\t *\n\t * What the form keeps in place (`keeps`, the ability that made it, the spells) is one ability in both and is never\n\t * touched by any of them\n\t */\n\tcooldowns?: FormCooldowns\n}\n\n/**\n * What turns a form back into the hero it was (`EffectFields.back`): the ability that made it cast again (`ability`),\n * its time up (`time`), or its death (`death`: it falls as itself, and is brought back as itself)\n *\n * @beta\n */\nexport type MorphBack = 'ability' | 'time' | 'death'\n\n/**\n * What an entity is: a unit, a building or a resource\n *\n * @beta\n */\nexport type EntityKind = 'unit' | 'building' | 'resource'\n\n/**\n * Where something is: on the ground, or above it\n *\n * @beta\n */\nexport type Layer = 'ground' | 'air'\n\n/**\n * The stats an attack reads how hard, how fast and how far it hits from (`AttackDef.stats`): the unit's\n * `attackDamage`, `attackSpeed` and `attackRange` for what is left out\n *\n * @beta\n */\nexport interface AttackStats {\n\t/** What a hit deals, before the armour of the target. `attackDamage` when left out */\n\tdamage?: StatKey\n\t/** Hits a second. `attackSpeed` when left out */\n\tspeed?: StatKey\n\t/** How far it reaches, between the edges. `attackRange` when left out */\n\trange?: StatKey\n}\n\n/**\n * One of the ways a unit attacks (`UnitTypeDef.attacks`): what it hits, how its blow lands. How hard, how fast and how\n * far are stats: the unit's `attackDamage`, `attackSpeed` and `attackRange`, or stats of the game's own that the attack\n * names (`stats`: a second weapon's)\n *\n * @beta\n */\nexport interface AttackDef {\n\t/**\n\t * The stats its numbers are, by id: a stat of the game's (`Rules.stats`) for a weapon whose damage, speed or\n\t * range is not the unit's first's. What changes those stats (research, items, buffs) changes this attack alone\n\t */\n\tstats?: AttackStats\n\t/** Physical when left out */\n\tdamageType?: DamageType\n\t/** Seconds from the start of the swing until damage lands (or the projectile leaves), at the attack speed the unit starts with */\n\tdamagePoint: number\n\t/**\n\t * Seconds after the blow during which the unit is held: an order it is given (a move, another attack) waits until\n\t * they are over, unless the rules let it cut them (`RuleSettings.combat.recoveryCancels`). At the attack speed the unit\n\t * starts with, shorter as it attacks faster, and never past its next swing. None when left out: it may walk away\n\t * the moment the blow lands (kiting), as in LoL\n\t */\n\trecovery?: number\n\t/** Enemies closer than this are attacked automatically */\n\tacquisitionRange: number\n\t/**\n\t * How near is too near, edge to edge: what is closer than this the attack does not hit (a siege weapon's dead zone).\n\t * Another of the unit's attacks takes over there where one reaches (`RuleSettings.combat.pickAttack`); with none, a unit\n\t * told to attack steps back out of it first, and one left to itself does not pick what is that near. None when left out\n\t */\n\tminRange?: number\n\t/**\n\t * Fires as the unit walks (a horse archer, a tank's turret): told to move, it hits what it passes within the attack's\n\t * range without stopping or turning to it, at the attack's speed. Every other order fights as any attack does\n\t * (it stops to). Not when left out\n\t */\n\tonTheMove?: boolean\n\t/** Set for ranged attacks */\n\tprojectileSpeed?: number\n\t/**\n\t * What this attack can hit: kinds of things, and where they are. Everything on the ground when left out.\n\t * What flies is only hit by attacks that name `air`, and an attack that names `air` alone does not hit the ground\n\t */\n\ttargets?: (EntityKind | Layer)[]\n\t/**\n\t * Radius around the point of impact in which everyone is hit, friends too: in full in the inner half, by half further out.\n\t * Shots of such an attack land where they were aimed, they do not follow their target\n\t */\n\tsplash?: number\n\t/** Can be told to attack a spot on the ground */\n\tground?: boolean\n\t/** Brings down what is `fellable` in the area it hits */\n\tfells?: boolean\n\t/**\n\t * A blow from up close (no missile) also strikes the target's other enemies near it, a part of its damage each:\n\t * a cleave. With a buff's (`BuffDef.cleave`), the one of the larger part counts\n\t *\n\t * @beta\n\t */\n\tcleave?: Cleave\n\t/**\n\t * How what this attack kills dies, for the screen (`'shot'`, `'crushed'`, `'burnt'`): the death's `how`, which the\n\t * view shows its way (`UnitLook.death`). A word, or one decided for each blow. The `death` hook has the last say\n\t */\n\thow?:\n\t\t| string\n\t\t| ((hit: { attacker: Entity; target?: Entity; damage: number; type: DamageType; crit: boolean; tags?: readonly string[] }) => string | undefined)\n}\n\n/**\n * What a blow from up close does to the enemies around its target (`AttackDef.cleave`, `BuffDef.cleave`): a part of\n * its damage, before their armor, for each of them within `radius` of the target and, where `angle` says, within a\n * cone of that angle that opens from the attacker through the target (so ahead of the attacker, round and behind the\n * target). Not the target itself, nor anyone the attack could not hit\n *\n * @beta\n */\nexport interface Cleave {\n\t/** The part of the blow's damage each other enemy takes, by level for a buff's: 0.5 is half */\n\tpart: Scaled\n\t/** How far from the target's edge the enemies it reaches stand */\n\tradius: number\n\t/** How wide the cone is, in radians (1.57: a quarter turn). All the way round the target when left out */\n\tangle?: number\n}\n\n/**\n * The id of a resource, as its game module defines it (`ResourceDef`)\n *\n * @beta\n */\nexport type ResourceId = string\n\n/**\n * Something players have amounts of and pay with, like gold, lumber or crystals. A game module lists its own\n *\n * @beta\n */\nexport interface ResourceDef {\n\t/** The resource's id, which prices, players' amounts and gatherers name it by */\n\tid: ResourceId\n\t/** What the player sees the resource called */\n\tname: string\n\t/** What every player starts a game with. Nothing when left out */\n\tstart?: number\n\t/** What workers gather of it is cut by the upkeep of the army, see `UpkeepTier` */\n\tupkeep?: boolean\n}\n\n/**\n * What something costs: an amount of each resource it takes, by resource id. What is left out costs nothing\n *\n * @beta\n */\nexport type Cost = Record<ResourceId, number>\n\n/**\n * How a type goes up once it is put down (`UnitTypeDef.construction`): `builder`, `self` (also `buildsItself`) or\n * `instant`\n *\n * @internal\n */\nexport function constructionOf(def: Pick<UnitTypeDef, 'construction' | 'buildsItself'>): 'builder' | 'self' | 'instant' {\n\treturn def.construction ?? (def.buildsItself ? 'self' : 'builder')\n}\n\n/**\n * The definition of a unit type: a unit, building or resource, with its stats, abilities, costs and what it does\n *\n * @public\n */\nexport interface UnitTypeDef {\n\t/** The type's id, shared by every game: give it a prefix of the game's */\n\tid: string\n\t/** What the player sees the type called */\n\tname: string\n\t/**\n\t * The definition this one is a copy of, made from the data (`copyOf` in a `data.json`, the editor's Copy as new):\n\t * what it is drawn, heard and pictured as where the game gives it no look of its own\n\t */\n\tbasedOn?: string\n\t/** Whether the type is a unit, a building or a resource */\n\tkind: EntityKind\n\t/**\n\t * Words of the game's for what it is (`undead`, `mechanical`, `ward`): what an effect's `tags`, an ability's\n\t * `targets.tags` and an `if`'s condition (`UnitCondition.tags`) go by\n\t *\n\t * @beta\n\t */\n\ttags?: string[]\n\t/** Collision radius */\n\tradius: number\n\t/** Size in grid cells. Required for buildings and resources */\n\tfootprint?: { w: number; d: number }\n\t/** What it starts with. What is left out is 0, a critical strike is worth 175% */\n\tstats: Partial<Stats> & { health: number }\n\t/** Mana it comes into the world with. All of it when left out */\n\tinitialMana?: number\n\t/** Vision radius by day */\n\tsight: number\n\t/** Vision radius at night. A part of the one by day when left out */\n\tsightNight?: number\n\t/** Flies: over cliffs, trees and buildings, out of reach of whatever cannot hit the air */\n\tflying?: boolean\n\t/**\n\t * Goes on deep water and nowhere else: a boat. Sent onto land, it goes to the water nearest where it was sent. On\n\t * the ground, as far as what can hit it goes\n\t */\n\tnaval?: boolean\n\t/**\n\t * A waygate, in a game with the portals pack (`portalsPack`): a unit told to it walks in and is at once where it\n\t * leads (its `waygate` field, a point of the map; `setWaygate` in code)\n\t */\n\twaygate?: boolean\n\t/**\n\t * Rocks, a barricade, a gate to break down, in a game with the destructibles pack (`destructiblesPack`): it stands in\n\t * the way as any building does until it is brought down, and any unit whose attack reaches it attacks it when told\n\t * to, never of its own accord\n\t */\n\tdestructible?: boolean\n\t/**\n\t * Carries others: a boat, a wagon. Units of its side get in by being told to (right-clicking it), are out of the\n\t * world while in, and get out on the land nearest it (the `unload` order). It takes `capacity` of them, of the\n\t * kinds `takes` says (every unit that walks when left out). What it carries dies with it\n\t */\n\t/**\n\t * Carries others: a boat, or a building they go into (a garrison). `takes` says who may get in; `armed`, for a\n\t * building with an attack, is the attack damage each one inside adds, and it attacks only while someone is inside,\n\t * as an orc burrow does. What a building holds comes out when it falls; what a boat holds goes down with it\n\t */\n\ttransport?: {\n\t\tcapacity: number\n\t\ttakes?: (def: UnitTypeDef) => boolean\n\t\t/** Attack damage each one inside adds; or in code, all of what they add, by who is inside (none for nobody) */\n\t\tarmed?: number | ((world: World, building: Entity, inside: Entity[]) => number)\n\t}\n\t/** How fast it turns, in radians a second: the game's for every unit (`RuleSettings.movement.turnRate`, 12) when left out */\n\tturnRate?: number\n\t/**\n\t * How it attacks, as the classic RTS two weapons: against each target the first that reaches it (its `targets`), or\n\t * the one the game picks (`RuleSettings.combat.pickAttack`). It swings one at a time: a hit's cooldown is that attack's,\n\t * whichever swings next. None for what does not attack\n\t */\n\tattacks?: AttackDef[]\n\t/** Makes the type a hero, with its levels and the rest of `HeroDef`; none for a unit that is not one */\n\thero?: HeroDef\n\t/** How dangerous it is, for creeps. Shown to the player, and added up per camp */\n\tlevel?: number\n\t/** Gold for whoever kills it, rolled between the two */\n\tbounty?: [min: number, max: number]\n\t/**\n\t * Whether it leaves a corpse when it dies, for spells to use (see `raiseDead`). Units do, unless this says no:\n\t * machines, spirits. Decided for each death in code: false for none, true or seconds for one (how long it lies)\n\t */\n\tcorpse?: boolean | ((world: World, entity: Entity) => boolean | number)\n\t/**\n\t * Immune to spells: abilities do not touch it, of friends or enemies, unless they say they get through\n\t * (`piercesImmunity`). Decided in code whenever it is asked: while it stands on holy ground. The player's screen only\n\t * knows the plain `true` of it, to grey out a target; the simulation goes by the code\n\t */\n\tspellImmune?: boolean | ((world: World, entity: Entity) => boolean)\n\t/** Experience heroes get for killing it. Follows from its cost when left out */\n\txp?: number\n\t/** Building types the player has to have before this can be built or trained */\n\trequires?: string[]\n\t/**\n\t * The race it is of (`Rules.races`): only its players may build or train it. Everyone's when left out: creeps,\n\t * what is shared. What a player may have is the game's to change (the `available` hook)\n\t */\n\trace?: string\n\t/** Building types this one counts as, for requirements. A keep is a town hall too */\n\tprovides?: string[]\n\t/**\n\t * Type this building can be upgraded into, where it stands; or the types, for one that may become one of several (a\n\t * keep that turns into a castle or a citadel, `upgradesOf`). The first is what an upgrade is into where none is named\n\t */\n\tupgradesTo?: string | string[]\n\t/** Slots for items. Heroes have six */\n\tinventory?: number\n\t/** Items this building sells */\n\tsells?: string[]\n\t/**\n\t * Units it hires out to whoever has one of theirs there, by type: a tavern's heroes, a dock's boats. Their cost,\n\t * and a hero only once (see `hire`). Neutral, it hires to everyone\n\t */\n\thires?: string[]\n\t/**\n\t * What it may leave behind when it dies, each with its chance from 0 to 1. Or code: the items it leaves, decided as\n\t * it dies (one random level-3 item; more for a stronger killer)\n\t */\n\tdrops?: { item: string; chance: number }[] | ((world: World, entity: Entity, killer?: Entity) => string[])\n\t/** Brings fallen heroes back */\n\trevives?: boolean\n\t/** Ids of the abilities the unit has */\n\tabilities?: string[]\n\t/** What it costs to build or train, in resources */\n\tcost?: Cost\n\t/**\n\t * Supply (food) it takes up for as long as it lives, and while it is being trained: of the one pool there always is, or by\n\t * pool (`{ supply: 2, command: 1 }`: `supply` that one, the rest the game's own, `RuleSettings.supply.pools`). Read with\n\t * `supplyOf` and `supplyPoolsOf`\n\t */\n\tsupply?: number | Record<string, number>\n\t/** Seconds to build or train */\n\tbuildTime?: number\n\t/** What it provides once it stands finished: of the one pool, or by pool, as `supply` is said. Read with `supplyGivenOf` and `supplyPoolsGivenOf` */\n\tsupplyGiven?: number | Record<string, number>\n\t/** Makes it a worker that gathers: how much it carries, seconds a load takes, and which resources it gathers */\n\tharvester?: {\n\t\tcapacity: number\n\t\tgatherTime: number\n\t\t/**\n\t\t * The kinds of resource it gathers: all of them when left out. The undead's acolytes gold and nothing else, ghouls\n\t\t * lumber. The `canHarvest` hook has the last word (`canHarvest`)\n\t\t */\n\t\tids?: ResourceId[]\n\t}\n\t/** Building types this unit can construct */\n\tbuilds?: string[]\n\t/** Unit types this building can train */\n\ttrains?: string[]\n\t/** Upgrades that can be researched here */\n\tresearches?: string[]\n\t/** Accepts harvested resources: all of them, or only the ones listed */\n\tdropOff?: boolean | ResourceId[]\n\t/**\n\t * Goes up on a resource of this kind, over it, of the same footprint: the undead's cursed gold mine. The resource is\n\t * its owner's alone from then on (`canHarvest`); one that takes what is gathered there (`dropOff`) has its owner's\n\t * workers gather at it from around it, handing in where they stand, as many at once as `gatherers` says. It goes\n\t * down with the resource, which stands again where it is destroyed\n\t */\n\tbuiltOn?: ResourceId\n\t/** Workers that gather at once at it, when it stands on a resource (`builtOn`): 5 when left out */\n\tgatherers?: number\n\t/**\n\t * Goes up on its own once it is put down, as the undead summon theirs: the builder is free at once, and nobody\n\t * helps (`RuleSettings.production.buildRate` of one builder, all the way). The same as `construction: 'self'`\n\t */\n\tbuildsItself?: boolean\n\t/**\n\t * How it goes up once it is put down: with builders at it (`builder`, the more the faster, as `buildRate` says), on\n\t * its own with the builder free at once (`self`, the undead's), or whole at once (`instant`: a wall piece, a\n\t * ward). `builder` when left out (`self` with `buildsItself`)\n\t *\n\t * @beta\n\t */\n\tconstruction?: 'builder' | 'self' | 'instant'\n\t/**\n\t * How fast it goes up with so many builders at it, 1 being one builder's: the game's rule (`RuleSettings.production.buildRate`) for\n\t * every type when left out\n\t *\n\t * @beta\n\t */\n\tbuildRate?: (builders: number, world: World, structure: Entity) => number\n\t/** Makes it a deposit that can be gathered from: which resource, how much, how many workers fit and how they gather */\n\tresource?: {\n\t\tid: ResourceId\n\t\tamount: number\n\t\t/** Workers that fit inside at once, for resources that are entered */\n\t\tslots: number\n\t\t/** Workers go inside to gather, like into a gold mine, instead of working on it from next to it */\n\t\tentered?: boolean\n\t\t/** Seconds a load takes, when that is not what the worker usually needs */\n\t\tgatherTime?: number\n\t}\n\t/** Key used in the command card when building or training this type */\n\thotkey?: string\n\t/** Higher values are picked first when acquiring targets */\n\tthreat?: number\n\t/** Whether it cannot be hurt */\n\tinvulnerable?: boolean\n\t/**\n\t * Ids of the abilities that alone may target it (a soul that only `possess` takes). Nothing else may: not an ability\n\t * clicked on it or used on it by the AI, nor an attack, nor the area of one, nor a heal; the ones named get through\n\t * the target rules as they say (`targets`). It is untouched as `invulnerable` is, but for them\n\t */\n\ttargetableBy?: string[]\n\t/** Takes damage like anything else but never dies of it: it is left with a little health, like something to practise on */\n\tundying?: boolean\n\t/** Seconds after it was last hurt that it is whole again, all at once */\n\trecovers?: number\n\t/** Nobody picks a fight with it on their own: it is only attacked when someone is told to */\n\tignored?: boolean\n\t/** Destroyed by attacks that fell, like a tree by a catapult, whatever else it withstands */\n\tfellable?: boolean\n\t/**\n\t * Whether it burns, in a game with the burning pack (`burningPack`), and how (`BurnsDef`: for how long, what it\n\t * leaves, whether its wood is kept, what kind of burning it is): `true` as the pack says, `false` never. What can be\n\t * felled (`fellable`: trees) burns when left out; anything else does not\n\t *\n\t * @beta\n\t */\n\tburns?: boolean | BurnsDef\n\t/**\n\t * A piece of wall (`wallsPack`): it joins with the pieces of its family beside it, and its shape (`single`, `end`,\n\t * `straight`, `corner`, `tee`, `cross`) is its look. A gate (`gate`) joins as a piece does, turned along its line,\n\t * and its owner opens and shuts it for everyone (`wallGateCommand`): its look `open` or `shut`. Pieces join by their\n\t * footprints, so a gate wider than a cell sits in a line of pieces of one: one of a cell lets nobody through, the\n\t * ground about a wall being kept off by the radius of what walks (a gatehouse of 3 by 3 lets through what is 1 wide) @beta\n\t */\n\twall?: { family: string; gate?: boolean }\n\t/** Seconds it lasts before it is gone by itself, like a ward */\n\tlifetime?: number\n\t/** Enemies cannot see it, `after` seconds after it came into the world, unless something reveals it to them */\n\tinvisible?: { after?: number }\n\t/**\n\t * Finds what of its enemies is invisible or camouflaged within this far of it, for its team, for as long as it stays\n\t * that near, in a game with the vision pack (`visionPack`): a Sentry Ward's true sight, a Control Ward\n\t *\n\t * @beta\n\t */\n\ttrueSight?: number\n\t/**\n\t * Goes down after this many attacks and spells, whatever they deal: its health counts hits, and its most health is\n\t * this whatever its `stats.health` or what changes its stats say\n\t */\n\tuses?: number\n\t/**\n\t * A trap, a mine, a pickup, in a game with the ground objects pack (`groundObjectsPack`): an ability of the game's that\n\t * goes off as one of those it is for comes within its `radius` (`GroundTrigger`)\n\t *\n\t * @beta\n\t */\n\ttrigger?: GroundTrigger\n\t/**\n\t * Something others click on, in a game with the ground objects pack (`groundObjectsPack`): a unit of those it is for\n\t * told to it (right-clicked) walks up to it and uses it, an ability of the game's going off (`GroundUse`): Thresh's\n\t * lantern, Bard's portals\n\t *\n\t * @beta\n\t */\n\tuse?: GroundUse\n\t/**\n\t * Stops the missiles of abilities that come at it, in a game with the ground objects pack (`groundObjectsPack`):\n\t * those of its enemies (`enemies`), or of everyone (`all`); they are gone where they meet it, with nothing happening\n\t * (Yasuo's Wind Wall, a line of them: `EffectFields.line`). A missile thrown (`arc`) flies over it\n\t *\n\t * @beta\n\t */\n\tblocksMissiles?: 'enemies' | 'all'\n\t/**\n\t * What happens where it dies, in a game with the ground objects pack (`groundObjectsPack`): an ability of the game's\n\t * goes off there in its maker's name (`ability`), and those of its type and owner within `chain` of it die too and\n\t * go off in turn: Gangplank's barrels (`uses: 3` counts the hits that bring one down)\n\t *\n\t * @beta\n\t */\n\tburst?: { ability: string; chain?: number }\n\t/**\n\t * Resources of its own beside mana, in a game with the resources pack (`resourcesPack`), by id: energy, fury, heat,\n\t * flow, ammo (`PoolDef`: how much at most, at the start, back each second, lost each second when nothing used it,\n\t * gained by walking, refilled when empty, and buffs at thresholds). What its abilities cost of them (`AbilityDef.cost`)\n\t * and give (`gain`), what its attacks cost (`attackCost`), the `gain` effect\n\t *\n\t * @beta\n\t */\n\tpools?: Record<string, PoolDef>\n\t/**\n\t * What each of its attacks costs of its pools (`pools`), in a game with the resources pack: with less than that it\n\t * does not attack (Jhin's four shots, then the reload)\n\t *\n\t * @beta\n\t */\n\tattackCost?: Record<string, number>\n\t/**\n\t * What the computer player takes it for (`AiHints`): its roles (`worker`, `hall`, `soldier`...), the game's words\n\t * about it, what it answers. Declared where what the kit infers from the rest of the definition is wrong or cannot\n\t * be known; inferred otherwise (`inferRoles` in `@v12-engine/engine/ai`)\n\t */\n\tai?: AiHints\n}\n\n/**\n * The names of a game's own ways of aiming an ability (`defineTargeting`), by declaration merging:\n * `declare module '@v12-engine/engine' { interface AbilityTargetings { wall: true } }` makes `target: 'wall'` an\n * ability's way of aiming\n *\n * @beta\n */\nexport interface AbilityTargetings {}\n\n/**\n * How an ability is aimed: the engine's ways (`AimKind`: `none`, `unit`, `point`, `direction`, `vector`, `passive`), or a\n * game's own (`AbilityTargetings`, `defineTargeting`)\n *\n * @beta\n */\nexport type AbilityTarget = 'none' | 'unit' | 'point' | 'direction' | 'vector' | 'passive' | keyof AbilityTargetings\n\n/**\n * How an ability is cast again after it is cast (`AbilityDef.recast`): for `window` seconds the same button casts the\n * recast, `count` times, each doing its `effects` (no wind-up, no channel, `manaCost` its own: none when left out); the\n * cooldown waits for the last recast or the window's end (`after`) or starts at the first cast (`first`). The window\n * and its recasts are the ability's state (`AbilityState.recast`), saved and told to its owner's button\n * (`AbilityInfo.recast`)\n *\n * @beta\n */\nexport interface AbilityRecast {\n\t/** Seconds it may be cast again for, from the cast */\n\twindow: Scaled\n\t/** How many times it may be cast again in the window: once when left out */\n\tcount?: number\n\t/** What a recast does: the ability's own `effects` when left out */\n\teffects?: EffectDef[]\n\t/** How a recast is aimed: as the ability is when left out; with a `mark`, at the marked unit, with no aim of its own */\n\ttarget?: AbilityTarget\n\t/** How far away a recast's target may be: the ability's `range` when left out */\n\trange?: Scaled\n\t/**\n\t * A buff the cast leaves on a unit (Sonic Wave's mark): a recast goes to the unit that carries it from the caster\n\t * (the nearest, where there are more), its target and its point, and is refused while none does (`noMark`)\n\t */\n\tmark?: string\n\t/**\n\t * When the cooldown starts: `after` the last recast, or the window's end (when left out), with what it was as the\n\t * ability was cast; or at the `first` cast, as usual, the recasts not waiting for it\n\t */\n\tcooldown?: 'after' | 'first'\n\t/** Mana a recast costs: none when left out */\n\tmanaCost?: Scaled\n}\n\n/**\n * What every effect may say, whatever its type: who of what it reaches it applies to (`effectTargets`)\n *\n * @beta\n */\nexport interface EffectCommon {\n\t/** Only hits what carries this buff */\n\tifBuff?: string\n\t/**\n\t * Which look of its ability the screen draws it with (`AbilityLook.effects` in the client: by this name, else by its\n\t * place in the ability or its type). Nothing to the rules: the same game with another look\n\t *\n\t * @beta\n\t */\n\tlook?: string\n\t/** Only hits heroes */\n\tonly?: 'heroes'\n\t/**\n\t * Only hits what has one of these tags of its type (`UnitTypeDef.tags`): `['undead']`. Everything when left out\n\t *\n\t * @beta\n\t */\n\ttags?: string[]\n\t/**\n\t * It happens by chance: this share of the times it would (0.25 one in four), drawn from the world's numbers\n\t * (`world.rng`), so the same every run. Once each time its list runs, for all it reaches; for a trigger (`onHit`,\n\t * `onDamaged`…), each time it would go off (Bash), its cooldown starting only when it does; for an `if`, a\n\t * condition like its others, drawn for each it asks of (and `otherwise` when the draw fails). A number, one per\n\t * level, or code (`EffectValue`) asked with the target\n\t *\n\t * @beta\n\t */\n\tchance?: EffectValue\n\t/** Only hits these kinds of things. Everything but resources when left out */\n\tkinds?: EntityKind[]\n\t/** Where what it hits has to be: on the ground, in the air. Both when left out */\n\tlayers?: Layer[]\n\t/**\n\t * Makes the effect hit everything around the point of impact. Required for auras, and the size of a missile. In code\n\t * (`EffectValue`), asked as it lands with no target\n\t */\n\tradius?: EffectValue\n\t/**\n\t * What ground it covers (`EffectShape`), turned the way the ability was aimed: `circle` (its `radius`, what an effect\n\t * with a radius alone covers), `cone` (`length`, `angle`), `line` (`length`, `width`), `rect` (`length`, `width`),\n\t * `ring` (`radius`, `width`), `arc` (`radius`, `angle`, `width`), `cross` (`length`, `width`). A circle, a ring, a\n\t * rectangle and a cross lie around where it landed; a cone, a line and an arc go off from the caster (or the\n\t * context's `origin`) the way of where it landed. Everything in it, as `affects` says, is hit (`effectArea`,\n\t * `inArea`). Of a zone: what is inside it, for `onEnter`, `onLeave` and `edge`\n\t *\n\t * @beta\n\t */\n\tshape?: EffectShape\n\t/** Of a `cone`, a `line`, a `rect` and a `cross`: how long it is, end to end. In code (`EffectValue`), asked as it lands @beta */\n\tlength?: EffectValue\n\t/**\n\t * Of a `line`, a `rect` and a `cross`: how far it covers on either side of its middle; of a `ring` and an `arc`, how\n\t * thick it is, inwards from its `radius`. 1 when left out\n\t *\n\t * @beta\n\t */\n\twidth?: EffectValue\n\t/** Of a `cone` and an `arc`: how wide it opens, in radians @beta */\n\tangle?: EffectValue\n\t/** Who an effect with a radius applies to. Follows from the kind of effect when left out */\n\taffects?: 'enemies' | 'allies' | 'all'\n\t/**\n\t * Only hits what this says of it (`UnitCondition`: a buff or none, health under or over a share, a hero, tags, enemy\n\t * or ally of the caster), or code (`UnitConditionCheck`, asked with the target): `{ healthBelow: 0.5, notTags:\n\t * ['mechanical'] }`. Of an effect with an area, asked of each in it; of one without, of its target\n\t *\n\t * @beta\n\t */\n\twhere?: UnitCondition | UnitConditionCheck\n\t/**\n\t * Of what its area reaches, the order it goes to them in (`TargetOrder`), or a comparison: the first `limit` of it are\n\t * hit. The nearest to the middle of its area (where it landed, or the caster for a cone, a line and an arc) when left\n\t * out with a `limit`\n\t *\n\t * @beta\n\t */\n\tsort?: TargetOrder | ((a: Entity, b: Entity) => number)\n\t/**\n\t * Of what its area reaches, at most this many, the first by `sort`: a number, or one per level. `{ sort:\n\t * 'lowestHealthShare', limit: 3 }` heals the three most hurt; `{ sort: 'random', limit: 1 }` strikes one of them.\n\t * Chosen before the game has its say (`beforeEffect`): a spell shield on one chosen takes the blow\n\t *\n\t * @beta\n\t */\n\tlimit?: Scaled\n\t/** Applies to the caster, wherever the ability was aimed */\n\ton?: 'caster'\n\t/**\n\t * When it happens, in a chain (`EffectMoment`): not now, but as the nearest effect before it in its list that\n\t * comes to that moment gets there: `hit` a missile's every hit, `arrived` a pull's target arriving, `landed` a\n\t * dash's end, `end` a missile's or zone's end. `[missile, { type: 'damage', when: 'hit' }]` is `[{ ...missile, effects: [damage] }]`:\n\t * what waits goes into what it waits on (`lowerChain`), so one waiting on what waits itself happens later still.\n\t * One with nothing before it to wait on never happens (`checkRules` says so)\n\t *\n\t * @beta\n\t */\n\twhen?: EffectMoment\n\t/**\n\t * Goes off from units of the caster's of a type (`ProxyOrigin`), not from the caster: once from each it picks, that one\n\t * the context's `origin` (a missile starts there, an area never takes it in, the strike says it came from there), the\n\t * caster still who does it (whose the damage, the kills and the scaling are). Zed's shadows, Orianna's ball, Syndra's\n\t * spheres, Azir's soldiers. Nothing where none is picked, unless `caster` says otherwise\n\t *\n\t * @beta\n\t */\n\torigin?: ProxyOrigin\n}\n\n/**\n * Units of the caster's an effect goes off from (`EffectCommon.origin`): proxies, a shadow, a ball, a sphere, a soldier.\n * The caster's are those it put down (`madeBy`, a `spawn` of the ground objects pack), or, of one nobody says put down,\n * those of its owner. In code, a game's effect runs its effects from a unit of its own choice (`EffectContext.origin`,\n * `runEffects`), or asks which a proxy origin picks (`proxiesOf`)\n *\n * @beta\n */\nexport interface ProxyOrigin {\n\t/** The unit type of the caster's it goes off from */\n\tproxy: string\n\t/**\n\t * Which of them: the one `nearest` to where it was aimed (when left out), `all` of them (each in the order they came\n\t * into the world), the `newest` or the `oldest`\n\t */\n\tpick?: 'nearest' | 'all' | 'newest' | 'oldest'\n\t/**\n\t * From the caster as well (`true`: Zed and his shadows, each a Razor Shuriken), or from the caster where none is\n\t * picked (`otherwise`: Orianna's ball, with her when it is nowhere). From the picked alone when left out\n\t */\n\tcaster?: boolean | 'otherwise'\n\t/** Only those within this far of the caster: Azir's soldiers within his reach. Any distance when left out */\n\trange?: number\n\t/** Only those within this far of where it was aimed: the soldiers near what Azir attacks. Any distance when left out */\n\tnear?: number\n\t/**\n\t * Where it lands: where it was aimed (`aim`, when left out), or where each it goes off from stands (`proxy`: Orianna's\n\t * Dissonance around the ball, Zed's Shadow Slash around each shadow)\n\t */\n\tat?: 'aim' | 'proxy'\n\t/** The one it goes off from is its target too: a swap with it (Zed's Living Shadow cast again), a dash to it */\n\ttarget?: boolean\n}\n\n/**\n * The shapes of ground an effect may cover (`EffectCommon.shape`)\n *\n * @beta\n */\nexport type EffectShape = 'circle' | 'cone' | 'line' | 'rect' | 'ring' | 'arc' | 'cross'\n\n/**\n * A resource of a unit's own beside mana (`UnitTypeDef.pools`), in a game with the resources pack (`resourcesPack`):\n * Akali's energy (`regen`), Tryndamere's fury (gained by attacks, `decay` after `idle`), Rumble's heat (gained by casts,\n * overheating at a threshold), Yasuo's flow (`moving`), Jhin's ammo (`reload`)\n *\n * @beta\n */\nexport interface PoolDef {\n\t/** What it is called on the screen: its id when left out */\n\tname?: string\n\t/** The colour of its bar, a CSS colour: the client's own when left out */\n\tcolor?: string\n\t/** How much it holds at most */\n\tmax: number\n\t/** How much it holds as the unit comes into the world: full when left out */\n\tstart?: number\n\t/** How much comes back each second, always (energy) */\n\tregen?: number\n\t/** How much goes each second once nothing has spent or given any for `idle` seconds (fury, heat) */\n\tdecay?: number\n\t/** Seconds without its being spent or given before it decays: at once when left out */\n\tidle?: number\n\t/** How much comes for each cell the unit walks (Yasuo's flow) */\n\tmoving?: number\n\t/** Seconds after it runs out until it is full again (a reload) */\n\treload?: number\n\t/** Buffs its carrier gets as it fills (`PoolThreshold`): overheated, in the danger zone */\n\tthresholds?: PoolThreshold[]\n}\n\n/**\n * A buff a unit gets as one of its pools reaches `at` (`PoolDef.thresholds`): kept on while it holds that much or more\n * (`kept`: Rumble's danger zone), or put on once as it gets there; one that `empties` holds the pool still while it\n * lasts, and empties it as it ends (Rumble's overheat)\n *\n * @beta\n */\nexport interface PoolThreshold {\n\t/** How much the pool holds for it */\n\tat: number\n\t/** The buff, in the carrier's own name */\n\tbuff: string\n\t/** On while the pool holds `at` or more, off below: put on once as it gets there when left out */\n\tkept?: boolean\n\t/** The pool stays as it is while the buff lasts, and is empty as it ends (not with `kept`) */\n\tempties?: boolean\n}\n\n/**\n * What an `if` asks of a unit, its caster or its target (`EffectFields.caster`, `EffectFields.target`): each part it\n * says must hold. Or code (`UnitConditionCheck`)\n *\n * @beta\n */\nexport interface UnitCondition {\n\t/** It carries this buff */\n\tbuff?: string\n\t/** It does not carry this buff */\n\tnoBuff?: string\n\t/** Its health is under this share of its max (0.2: below 20%: an execute) */\n\thealthBelow?: number\n\t/** Its health is at or over this share of its max (1: unhurt) */\n\thealthAbove?: number\n\t/** It is a hero (true) or not (false) */\n\thero?: boolean\n\t/**\n\t * It is a structure, a building (true), or not (false). `{ hero: false, structure: false }` is a creep: any unit\n\t * that is neither, a camp's, a lane's, a summon. What a passive that works in every kind of game names\n\t *\n\t * @beta\n\t */\n\tstructure?: boolean\n\t/** Its type has one of these tags (`UnitTypeDef.tags`) */\n\ttags?: string[]\n\t/** Its type has none of these tags: `['undead']` for the living */\n\tnotTags?: string[]\n\t/** What it is to the caster: an `enemy` or an `ally` (the caster itself is one) */\n\tis?: 'enemy' | 'ally'\n}\n\n/**\n * The orders a query and an effect sort what they found in (`WorldQuery.sort`, `EffectCommon.sort`): `nearest` and\n * `farthest` to its point (by the edge of each), the least or most `health`, the least or most of it as a share of its\n * max (`lowestHealthShare`: the most hurt), or `random`, drawn from the world's numbers (`world.rng`), so the same every\n * run. Ties go by who came into the world first\n *\n * @beta\n */\nexport type TargetOrder = 'nearest' | 'farthest' | 'lowestHealth' | 'highestHealth' | 'lowestHealthShare' | 'highestHealthShare' | 'random'\n\n/**\n * An `if`'s condition in code: whether it holds of the unit (the caster or the target), as the effect lands\n *\n * @beta\n */\nexport type UnitConditionCheck = (context: EffectValueContext, unit: Entity) => boolean\n\n/**\n * A ground object's trap, mine or pickup (`UnitTypeDef.trigger`), in a game with the ground objects pack\n *\n * @beta\n */\nexport interface GroundTrigger {\n\t/**\n\t * The ability whose `effects` go off: in the name of whoever put it down (its maker, a `spawn` of the pack's: the\n\t * object's own where there is none or it is gone), the one who came its target, the object where they go off from\n\t * (`EffectContext.origin`), at the level it was put down at\n\t */\n\tability: string\n\t/** How near its edge one comes for it to go off: 1 when left out */\n\tradius?: number\n\t/** Who sets it off: `enemies` of its owner (when left out), `allies`, `all`, or its `maker` alone (a soul, a chime) */\n\tby?: 'enemies' | 'allies' | 'all' | 'maker'\n\t/** Seconds after it is put down before it works (a mine arming): at once when left out */\n\tarm?: number\n\t/** Times it goes off before it is gone: once when left out, for ever with 0 */\n\ttimes?: number\n}\n\n/**\n * Something on the ground others use (`UnitTypeDef.use`), in a game with the ground objects pack\n *\n * @beta\n */\nexport interface GroundUse {\n\t/**\n\t * The ability whose `effects` go off as one uses it: in its maker's name (its own where there is none), the one who\n\t * uses it the target, the object the `origin`, and the point the next of those put down with it (the other end of a\n\t * portal) or the object itself\n\t */\n\tability: string\n\t/** Who may use it: `allies` of its owner (when left out), `enemies` or `all` */\n\tby?: 'allies' | 'enemies' | 'all'\n\t/** How near its edge one comes to use it: 1 when left out */\n\trange?: number\n\t/** Times it is used before it is gone: for ever when left out */\n\ttimes?: number\n}\n\n/**\n * The spots a `spawn` of the ground objects pack lays its units on (`EffectFields.line`): `count` of them, ends\n * included, along the way it was aimed, `length` long around where it landed (or from where it went off from to there,\n * when left out), or `across` it, a quarter turn round (a wall in front of the caster)\n *\n * @beta\n */\nexport interface SpawnLine {\n\t/** How many, ends included */\n\tcount: number\n\t/** How long it is, around where it landed: from where it went off from to there when left out */\n\tlength?: number\n\t/** It lies across the way it was aimed, a quarter turn round: a wall in front */\n\tacross?: boolean\n}\n\n/**\n * Which way a `knockback` throws, in a game with the moves pack (`EffectFields.direction`)\n *\n * @beta\n */\nexport type KnockbackDirection = 'away' | 'aim' | 'over' | 'towards'\n\n/**\n * The moment an effect of a chain waits for (`EffectCommon.when`): a missile's hit (`hit`), a pull's arrival\n * (`arrived`), a dash's landing (`landed`), a missile's or a zone's end (`end`)\n *\n * @beta\n */\nexport type EffectMoment = 'hit' | 'arrived' | 'landed' | 'end'\n\n/**\n * What an effect waiting for a moment waits on (`EffectCommon.when`): the types that come to it, and the list of\n * theirs it goes into\n *\n * @beta\n */\nexport const EFFECT_MOMENTS: Readonly<Record<EffectMoment, { readonly types: readonly string[]; readonly into: 'effects' | 'onEnd' }>> = {\n\thit: { types: ['missile'], into: 'effects' },\n\tarrived: { types: ['pull'], into: 'effects' },\n\tlanded: { types: ['dash'], into: 'effects' },\n\tend: { types: ['missile', 'zone'], into: 'onEnd' }\n}\n\n/**\n * The fields the engine's effects read, by name: each type of effect has those of them it reads (`EffectTypes`, a\n * `Pick` of these), and a game's own type picks of them or says its own\n *\n * @beta\n */\nexport interface EffectFields {\n\t/**\n\t * For `teleport`: where to, however far: the caster's side's home (`homeOf`), where it was aimed, or by its target.\n\t * For `dash`, in a game with the moves pack (`movesPack`): `target` rushes to the unit it was cast on, after it as it\n\t * moves, to its edge (or `through` it); its `effects` happen to it there\n\t */\n\tto?: 'home' | 'point' | 'target'\n\t/**\n\t * For a `dash` to a unit (`to: 'target'`), in a game with the moves pack: it goes on through the unit, this far past\n\t * its middle, along the way from where the caster set off (Yasuo's Sweeping Blade); the place is fixed as it sets off\n\t *\n\t * @beta\n\t */\n\tthrough?: number\n\t/**\n\t * For `dash` and `knockback`, in a game with the moves pack (`movesPack`): what happens to each enemy of the caster\n\t * the one moved meets on its way, once each, in the caster's name, the one met its target and the one moved where they\n\t * go off from (`EffectContext.origin`): Lee Sin's Dragon's Rage (who the kicked one flies into is hurt and thrown up),\n\t * Rammus's Powerball\n\t *\n\t * @beta\n\t */\n\tcollide?: EffectDef[]\n\t/** For `dash` and `knockback` with `collide`: the one moved stops at the first one it meets @beta */\n\tstops?: boolean\n\t/**\n\t * For `knockback`, in a game with the moves pack (`movesPack`): which way it throws (`KnockbackDirection`): `away` from\n\t * where the effects go off from (the caster, or the context's `origin`: what it always did), `aim` the way the ability\n\t * was aimed (Thresh's Flay, Vayne's Condemn, Poppy's charge), `over` the caster to land `distance` beyond it on its\n\t * other side (Singed's Fling: give it a `leap`), or `towards` it, to its edge at the most (a yank)\n\t *\n\t * @beta\n\t */\n\tdirection?: KnockbackDirection\n\t/**\n\t * For `attach`, in a game with the moves pack: who is put on whom: the `caster` on the unit it was cast on (Yuumi's\n\t * You and Me!, when left out) or that unit on the caster (Kalista's Fate's Call)\n\t *\n\t * @beta\n\t */\n\trider?: 'caster' | 'target'\n\t/** For `raiseDead`: the corpses rise as what they were, the caster's (Animate Dead), rather than as its `unit` @beta */\n\tas?: 'themselves'\n\t/** For `onFatal`: the share of its max health the carrier is left with, rather than dying: all of it when left out @beta */\n\thealth?: number\n\t/**\n\t * For `if`: what must hold of the caster (`UnitCondition`, or code), for `effects` to happen rather than `otherwise`\n\t *\n\t * @beta\n\t */\n\tcaster?: UnitCondition | UnitConditionCheck\n\t/**\n\t * For `if`: what must hold of the target (`UnitCondition`, or code): the unit it was cast on, or each one within its\n\t * `radius` or `shape`, where it has one. With no target there, it does not hold\n\t *\n\t * @beta\n\t */\n\ttarget?: UnitCondition | UnitConditionCheck\n\t/**\n\t * How much: of damage, healing, mana, a shield (`buff`). A number, one per level, or code asked for each target\n\t * (`EffectValue`); with what the caster's stats add (`scaling`) and the formulas of `damage`, `heal` and `buff`\n\t * (`byMaxHealth`, `byCurrentHealth`, `byMissingHealth`, `byStacks`, `byDistance`, `targetScaling`) on top\n\t */\n\tamount?: EffectValue\n\t/** Id of the buff to put on the targets */\n\tbuff?: string\n\t/** Unit type, for effects that bring one into the world */\n\tunit?: string\n\t/** For `spawn`: whose it is: the caster's when left out, or the neutral player's (a soul nobody owns) */\n\towner?: 'neutral'\n\t/** For `spawn`: drawn as the target or the caster is (its model, its owner's colour, its size), while it stays what its own type is */\n\tlooksLike?: 'target' | 'caster'\n\t/** For `spawn`: components it starts with, by id, in the form a save keeps them in */\n\tdata?: Record<string, unknown>\n\t/**\n\t * For `spawn`, in a game with the ground objects pack (`groundObjectsPack`): so many along a line (`SpawnLine`),\n\t * buildings one to a cell: Anivia's Crystallize (`across`), Taliyah's Weaver's Wall, Yasuo's Wind Wall, Bard's portals\n\t * (two: one where he stands, one where he aimed)\n\t *\n\t * @beta\n\t */\n\tline?: SpawnLine\n\t/**\n\t * For `spawn`, in a game with the ground objects pack: `count` round a circle of `radius` about where it landed, the\n\t * first the way it was aimed: Jarvan's Cataclysm\n\t *\n\t * @beta\n\t */\n\tring?: { count: number; radius: number }\n\t/**\n\t * For `gain`, in a game with the resources pack (`resourcesPack`): which of the pools (`UnitTypeDef.pools`) of what it\n\t * reaches it fills (or empties, with an `amount` under 0)\n\t *\n\t * @beta\n\t */\n\tpool?: string\n\t/** For `onHit` and `onKill`: only while the carrier carries this buff */\n\twhileBuff?: string\n\t/**\n\t * For `onHit`: only every so many of the carrier's attacks that land (while it carries `whileBuff`, where it says),\n\t * counted on the carrier and saved with it: Jhin's fourth shot, a third strike. Every attack when left out\n\t *\n\t * @beta\n\t */\n\tevery?: number\n\t/**\n\t * For `onHit`: the attack that sets it off uses up one of `whileBuff`'s stacks, the buff for its last (or one that does\n\t * not count them): \"the next attack\" of Power Fist, Siphoning Strike, Nether Blade, Flurry's two. Used up by the\n\t * attack that kills too, after what the kill sets off (`onKill` still sees it)\n\t *\n\t * @beta\n\t */\n\tconsumes?: boolean\n\t/**\n\t * For `onHit`: the slot it takes among what the carrier's attacks set off (its attack modifiers: an orb, a poison, a\n\t * frost), from its abilities, items and buffs alike. Of those that share a slot only one goes off, the one of the\n\t * highest `priority`; those of different slots, and those of none, all add up (`RuleSettings.combat.attackModifiers`)\n\t *\n\t * @beta\n\t */\n\tslot?: string\n\t/**\n\t * For `onHit` with a `slot`: which of those sharing it goes off, the highest first (0 when left out); the first of\n\t * the carrier's abilities, then items, then buffs among equals\n\t *\n\t * @beta\n\t */\n\tpriority?: number\n\t/**\n\t * For the triggers of a passive (`onHit`, `onKill`, `onCast`, `onDamaged`, `onAbilityHit`, `onLowHealth`): seconds\n\t * before it can go off again once it did, kept on the ability's own cooldown (`AbilityState.cooldown`, shown on its\n\t * button) for an ability, on the carrier for an item's or a buff's. Every time when left out\n\t *\n\t * @beta\n\t */\n\tcooldown?: Scaled\n\t/**\n\t * For `onLowHealth`: the part of its max health (0.3: 30%) the carrier's health falls below for it to go off: once\n\t * as it falls past it, not again until it is back above\n\t *\n\t * @beta\n\t */\n\tbelow?: number\n\t/**\n\t * For `onDamaged`: only for an attack that hits from up close (one with no missile: `AttackDef.projectileSpeed`\n\t * left out): Thorns Aura, Spiked Carapace\n\t *\n\t * @beta\n\t */\n\tmelee?: boolean\n\t/**\n\t * For `removeBuff`: how many stacks of `buff` come off: all of it when left out, the buff itself once none is left\n\t *\n\t * @beta\n\t */\n\tstacks?: Scaled\n\t/** For `charged`: what happens when the ability is not charged. For `if`: what happens when its conditions do not hold */\n\totherwise?: EffectDef[]\n\t/** For missiles: buildings and trees in its way stop it, without anything happening to them */\n\tblocked?: boolean\n\t/** For `onKill`: only when it was an attack of the carrier that killed. For `onDamaged`: only when an attack hurt it */\n\tattack?: boolean\n\t/**\n\t * For `refresh`: the ability that is ready again, when it is not the one the effect belongs to. For `grantAbility`\n\t * and `swapAbility`, in a game with the ability changes pack (`abilityChangesPack`): the ability given\n\t */\n\tability?: string\n\t/**\n\t * For `swapAbility`, in a game with the ability changes pack: the caster's ability that gives way, the one the effect\n\t * belongs to when left out\n\t *\n\t * @beta\n\t */\n\tfrom?: string\n\t/**\n\t * For `grantAbility`, `swapAbility` and `stealAbility`, in a game with the ability changes pack: casts of it before it\n\t * is gone (and what it took the place of is back): one for a stolen one when left out, for ever otherwise\n\t *\n\t * @beta\n\t */\n\tuses?: number\n\t/**\n\t * For `grantAbility` and `swapAbility`, in a game with the ability changes pack: the level it is given at: the level of\n\t * what it takes the place of, or the effect's own, when left out\n\t *\n\t * @beta\n\t */\n\tatLevel?: number\n\t/**\n\t * For `stealAbility`, in a game with the ability changes pack: which of the target's abilities it takes: its\n\t * `ultimate` (when left out), its `first`, or one at `random` (`world.rng`)\n\t *\n\t * @beta\n\t */\n\tpick?: 'ultimate' | 'first' | 'random'\n\t/** For `dash`: how high the caster rises on the way, which makes it a leap. For whoever draws it */\n\tleap?: number\n\t/**\n\t * For a leap: how much higher than where it takes off the ground on its way may stand. What stands higher\n\t * is a wall to it: it comes down in front of it. Over anything when left out\n\t */\n\tclimb?: number\n\t/** Seconds the buff lasts, when that is different from its usual duration. In code (`EffectValue`), asked for each target */\n\tduration?: EffectValue\n\t/**\n\t * What the stats of the caster add to the amount: `{ abilityPower: 0.6 }` adds 60% of its ability power.\n\t * `level` is for every level of the hero past the first\n\t */\n\tscaling?: Scaling\n\t/** For damage. Magic when left out */\n\tdamageType?: DamageType\n\t/** For damage: how what it kills dies, for the screen, over the ability's own `how` */\n\thow?: string\n\t/** For missiles: seconds they take shape where they were cast before they set off. The caster is free to go */\n\tdelay?: Scaled\n\t/** For missiles: how fast they travel, in units per second, and how far */\n\tspeed?: number\n\t/** For missiles: how far they fly, in cells */\n\tdistance?: Scaled\n\t/** For missiles: how many are sent, spread over an angle in radians. What one of them hit the others pass by */\n\tcount?: Scaled\n\t/** For missiles: the angle, in radians, the missiles are spread over */\n\tspread?: number\n\t/** For missiles: flies after the unit the ability was cast on, and only hits that one */\n\thoming?: boolean\n\t/**\n\t * For missiles: flies to the spot the ability was aimed at and stops there, `distance` away at the most. For `pull`:\n\t * drags to where the effect landed (a zone's middle, the spot of an `after`) rather than to the caster\n\t */\n\ttoPoint?: boolean\n\t/** For missiles: how far the team of the caster sees around it */\n\tsight?: number\n\t/**\n\t * What happens to what is hit. For missiles: everything they pass through. For `onHit`: the target of an attack.\n\t * For `dash`: what is around where it ends. For `pull`: what was pulled, as it arrives. For `after`: what is there when the time is up. For `zone`: what is inside, over and over\n\t */\n\teffects?: EffectDef[]\n\t/** For missiles that were not stopped, and for zones: what happens where and when they end */\n\tonEnd?: EffectDef[]\n\t/**\n\t * For `after`: the name its arrival goes by for whoever draws it and plays its sound, where one ability sets off\n\t * several that do not look alike: the last of a barrage. The ability's own when left out\n\t */\n\timpact?: string\n\t/**\n\t * For missiles: goes on after it hit something. False for the ones that are used up by the first thing in their way;\n\t * a number for those that go through so many and are used up by the next (1: Lux's Light Binding, two at the most)\n\t */\n\tpierce?: boolean | number\n\t/**\n\t * For missiles that go through what they hit (`pierce`): what part of the amounts each one it went through takes off\n\t * the next (0.3: a third less on the second, less again on the third). Read by `damage`, `heal` and `mana` (`share`)\n\t *\n\t * @beta\n\t */\n\tfalloff?: number\n\t/**\n\t * For missiles that come back (`returns`): on the way back they hit what they pass through again, each once more\n\t * (Ahri's Orb of Deception); the caster's place is still where it ends\n\t *\n\t * @beta\n\t */\n\thitsOnReturn?: boolean\n\t/**\n\t * For missiles: they find their own targets: while one flies with nobody to go after, it turns after the nearest it may\n\t * hit within this far of it and flies after that one (Fox-Fire, Dance of Arrows); another, if that one is gone first\n\t *\n\t * @beta\n\t */\n\tseek?: number\n\t/**\n\t * For missiles: what happens where it meets a wall (ground it cannot cross, a cliff above where it set off, the edge of\n\t * the play area, a building or a tree): it stops there, and these go off there, to the last one it hit where there is\n\t * one (Bard's Cosmic Binding). For `dash` and `knockback`, in a game with the moves pack (`movesPack`): the one moved\n\t * stops at such a wall (what flies meets none), and these go off there in the caster's name, to the one moved\n\t * (Vayne's Condemn, Poppy's Heroic Charge)\n\t *\n\t * @beta\n\t */\n\tonWall?: EffectDef[]\n\t/**\n\t * For missiles: what goes off from where it is, the way it flew, once it is done (it hit what used it up, reached\n\t * whom it flew after, or came to the end of its way) or is split by the game (`splitMissile`): missiles in it fly on\n\t * from there at their own `spread` (Vel'Koz's Plasma Fission: two at a half turn's spread, a quarter either side)\n\t *\n\t * @beta\n\t */\n\tsplit?: EffectDef[]\n\t/**\n\t * For missiles: turned by their owner as they fly, towards the point the `steer` command gives (`steerMissile`), at most\n\t * `rate` radians a second (π when left out): Yuumi's Prowling Projectile, Viktor's storm\n\t *\n\t * @beta\n\t */\n\tsteer?: { rate?: number }\n\t/**\n\t * For `zone`: goes with a unit, the `caster` or the `target`, and faces the way it does; it ends (with its `onEnd`) when\n\t * that one dies or leaves the world\n\t *\n\t * @beta\n\t */\n\tfollow?: 'caster' | 'target'\n\t/**\n\t * For `zone`: what happens to each who comes into it (its own `radius` or `shape`, as `affects` says), those inside as\n\t * it is laid included. Each in it is seen to every round of the world, not four times a second\n\t *\n\t * @beta\n\t */\n\tonEnter?: EffectDef[]\n\t/** For `zone`: what happens to each who goes out of it, alive @beta */\n\tonLeave?: EffectDef[]\n\t/**\n\t * For `zone`: what happens to each who crosses its edge, in or out, once it is laid (Veigar's Event Horizon, Thresh's\n\t * Box): those inside as it is laid have not crossed it\n\t *\n\t * @beta\n\t */\n\tedge?: EffectDef[]\n\t/**\n\t * For missiles: once done (it hit what used it up or what it flew after, came to the end of its way, or came down)\n\t * it flies back to the caster, after it wherever it goes, and touches nobody on the way; its `onEnd` happens where\n\t * the caster is when it gets there, not where it turned. Gone, with nothing more, if the caster is\n\t *\n\t * @beta\n\t */\n\treturns?: boolean\n\t/**\n\t * For `pull`: how long the drag takes, from where the target is to where it ends. Its speed is set by it as it\n\t * starts: a caster that walks off makes it take longer\n\t *\n\t * @beta\n\t */\n\tseconds?: Scaled\n\t/**\n\t * For missiles: thrown, not shot. It goes `height` up in the middle of its way and comes down at its end, `time`\n\t * seconds after it set off however far that is (`speed` otherwise). It flies over everything, and what is within\n\t * its `radius` where it comes down is what it hits\n\t */\n\tarc?: { height: number; time?: number }\n\t/**\n\t * For missiles: where it would be done (it reached its target, was used up by what it hit, came down, or came to\n\t * the end of its way) it springs on to the nearest thing it may hit within `range` that it has not hit yet, and\n\t * flies after that one, `count` times. Every spring takes `falloff` of the amounts off what it does (0.25: a\n\t * quarter less each time). Its `onEnd` is where it is done for good\n\t */\n\tbounce?: { count: Scaled; range: number; falloff?: number }\n\t/** For `buff`: adds one to how many of it the target carries instead of renewing it, up to what the buff allows */\n\tstack?: boolean\n\t/** For `exchange`: the resource the caster's owner trades away, by id */\n\tsell?: string\n\t/** For `exchange`: the resource the caster's owner trades for, by id */\n\tbuy?: string\n\t/** For `exchange`: how much of `buy` comes for each one of `sell` (0.5: 100 lumber for 50 gold) */\n\trate?: number\n\t/**\n\t * For `damage`: a part of what the target has lost of its health, added to the amount for each it hits (0.1: a tenth\n\t * of its missing health), worked out as it lands\n\t *\n\t * @beta\n\t */\n\tbyMissingHealth?: Scaled\n\t/**\n\t * For `damage`, `heal` and a shield (`buff`): a part of the target's maximum health, added for each it reaches (0.08:\n\t * 8% of its max health). Death and Decay, a % health nuke\n\t *\n\t * @beta\n\t */\n\tbyMaxHealth?: Scaled\n\t/**\n\t * For `damage`, `heal` and a shield (`buff`): a part of the health the target has now, added for each it reaches\n\t *\n\t * @beta\n\t */\n\tbyCurrentHealth?: Scaled\n\t/**\n\t * For `damage`, `heal` and a shield (`buff`): `amount` more for each stack of `buff` on the target (`of: 'target'`,\n\t * when left out) or the caster: Rend's spears, a passive's marks\n\t *\n\t * @beta\n\t */\n\tbyStacks?: { buff: string; of?: 'target' | 'caster'; amount: Scaled }\n\t/**\n\t * For `damage`, `heal` and a shield (`buff`): the whole of it times 1 and `per` for every unit of distance from where\n\t * it went off to the target (a missile's way, or from the caster or the `origin`), `most` times at the most: a\n\t * javelin that hurts more the farther it flew\n\t *\n\t * @beta\n\t */\n\tbyDistance?: { per: number; most?: number }\n\t/**\n\t * For `damage`, `heal` and a shield (`buff`): parts of the target's stats added (`{ armor: 1 }`: as much as its armor;\n\t * `{ health: 0.05 }`: 5% of its max health), as `scaling` adds the caster's\n\t *\n\t * @beta\n\t */\n\ttargetScaling?: Partial<Record<StatKey, Scaled>>\n\t/**\n\t * For `damage`, `heal` and a shield (`buff`) a trigger sets off: a part of the damage that set it off\n\t * (`EffectContext.damage`), added (0.2: a fifth of it): Spiked Carapace's returned damage, a heal by what was taken\n\t *\n\t * @beta\n\t */\n\tbyDamage?: Scaled\n\t/**\n\t * For `morph`: the unit type the caster turns into where it stands, a hero's form (`HeroDef.forms`)\n\t *\n\t * @beta\n\t */\n\tinto?: string\n\t/**\n\t * For `morph`: the form lasts until the ability is cast again in it, which turns it back (a toggle); with a\n\t * `duration` too, until whichever comes first\n\t *\n\t * @beta\n\t */\n\ttoggle?: boolean\n\t/**\n\t * For `morph`: what turns the form back (`MorphBack`): the ability cast again, its `duration` up, its death. All\n\t * three when left out (the ability only with `toggle`); without `ability`, the ability cast again in the form starts\n\t * its time over\n\t *\n\t * @beta\n\t */\n\tback?: MorphBack[]\n}\n\n/**\n * The fields of the formulas an amount of `damage`, `heal` and a shield (`buff`) may add to it, for each target as it\n * lands (`effectAmount`)\n *\n * @beta\n */\nexport type AmountFormula = 'byMissingHealth' | 'byMaxHealth' | 'byCurrentHealth' | 'byStacks' | 'byDistance' | 'targetScaling' | 'byDamage'\n\n/**\n * The types of effect there are, each with the fields it reads: the engine's, and a game's own, added by declaration\n * merging as it defines them (`declare module '@v12-engine/engine' { interface EffectTypes { arrowStun: { ... } } }`,\n * with `defineEffect`)\n *\n * @beta\n */\nexport interface EffectTypes {\n\t/** Hurts what it reaches: `amount`, with what of the caster's stats adds to it (`scaling`), of a type (magic when left out) */\n\tdamage: Pick<EffectFields, 'amount' | 'scaling' | 'damageType' | 'how' | AmountFormula>\n\t/** Heals what it reaches, more for the caster's heal and shield power */\n\theal: Pick<EffectFields, 'amount' | 'scaling' | AmountFormula>\n\t/** Gives mana to what it reaches */\n\tmana: Pick<EffectFields, 'amount' | 'scaling'>\n\t/**\n\t * Fills a pool of what it reaches (`pool`, one of `UnitTypeDef.pools`) by `amount` (empties it, under 0), in a game\n\t * with the resources pack (`resourcesPack`): allies when it says nothing, the caster with `on: 'caster'` (Tryndamere's\n\t * fury from an `onHit`)\n\t *\n\t * @beta\n\t */\n\tgain: { pool: string } & Pick<EffectFields, 'amount' | 'scaling'>\n\t/**\n\t * Does something to the grass and bushes where it lands, in a game with the foliage pack (`foliagePack`): sets it\n\t * alight (`ignite`, by the caster), puts it out (`extinguish`), ruins it (`ruin`, as `how` says: `cut` when left\n\t * out), has it grow back (`regrow`, over `over` seconds) or takes it away (`clear`). Over its `radius` or `shape`,\n\t * the cell it landed on when it has neither; on `layer`, every layer of the pack when left out. It acts on cells, not\n\t * on what stands there: the fields of whom (`affects`, `kinds`, `tags`, `where`, `limit`...) say nothing to it. A\n\t * fire arrow, a mower, a rain spell\n\t *\n\t * @beta\n\t */\n\tfoliage: { act: 'ignite' | 'extinguish' | 'ruin' | 'regrow' | 'clear'; layer?: string; how?: 'cut' | 'crush' | 'scorch'; over?: number }\n\t/**\n\t * Sets alight what burns where it lands, by the caster (`light`), or puts it out (`putOut`), in a game with the\n\t * burning pack (`burningPack`): over its `radius` or `shape`, else the unit it was cast on, else what stands where it\n\t * landed. `how`: the kind of burning it sets off (a blight, frost: the look's `burning.how` and the death's), the\n\t * thing's own when left out; `seconds`: how long it burns. Of what it finds, what its fields of whom say (`affects`:\n\t * `enemies` lights the caster's enemies' alone; `kinds`, `tags`, `layers`, `where`, `sort`, `limit`), everything\n\t * that burns, trees among it, when it says none. A fire arrow, a torch, a rain spell\n\t *\n\t * @beta\n\t */\n\tburn: { act: 'light' | 'putOut'; how?: string; seconds?: number }\n\t/**\n\t * Puts a buff on what it reaches: for its own time or `duration`, one more of it with `stack`. With an `amount` (and\n\t * `scaling`, the formulas), its shield holds that rather than the buff's own `shield`\n\t */\n\tbuff: { buff: string } & Pick<EffectFields, 'duration' | 'stack' | 'amount' | 'scaling' | AmountFormula>\n\t/** Sends a missile: how fast, how far, how many, and what it does to what it passes through and where it ends */\n\tmissile: Pick<\n\t\tEffectFields,\n\t\t| 'speed'\n\t\t| 'distance'\n\t\t| 'count'\n\t\t| 'spread'\n\t\t| 'homing'\n\t\t| 'toPoint'\n\t\t| 'delay'\n\t\t| 'sight'\n\t\t| 'blocked'\n\t\t| 'pierce'\n\t\t| 'arc'\n\t\t| 'bounce'\n\t\t| 'effects'\n\t\t| 'onEnd'\n\t\t| 'returns'\n\t\t| 'falloff'\n\t\t| 'hitsOnReturn'\n\t\t| 'seek'\n\t\t| 'onWall'\n\t\t| 'split'\n\t\t| 'steer'\n\t>\n\t/** A passive's buff on what is around the carrier, kept up by the ability system */\n\taura: { buff: string }\n\t/**\n\t * Brings a unit into the world where it landed, the caster's (the neutral player's with `owner`), for `duration` seconds\n\t * or for good, with `data` and the looks of the target or the caster. In a game with the ground objects pack\n\t * (`groundObjectsPack`): so many along a `line` or round a `ring`, each knowing who put it down (`madeBy`)\n\t */\n\tspawn: { unit: string } & Pick<EffectFields, 'duration' | 'owner' | 'looksLike' | 'data' | 'line' | 'ring'>\n\t/** Puts a buff on the caster for as long as it likes, or takes it off */\n\ttoggle: { buff: string }\n\t/** The caster's team sees the spot for a while */\n\treveal: Pick<EffectFields, 'duration'>\n\t/**\n\t * A passive's (an ability's, an item's or a buff's: `BuffDef.passive`): `effects` happen to the target of every attack\n\t * of the carrier that lands, while it carries `whileBuff`; of every `every`th, using up a stack of `whileBuff` with\n\t * `consumes`, once in `cooldown` seconds\n\t */\n\tonHit: Pick<EffectFields, 'whileBuff' | 'effects' | 'every' | 'consumes' | 'cooldown' | 'slot' | 'priority'>\n\t/** The caster is ready to strike again at once */\n\tresetAttack: object\n\t/** The caster is elsewhere at once, `distance` away at the most */\n\tblink: Pick<EffectFields, 'distance'>\n\t/** The caster is elsewhere at once, however far (`to`) */\n\tteleport: Pick<EffectFields, 'to'>\n\t/**\n\t * The caster rushes to the spot (a leap with `leap`), and `effects` happen around where it ends. In a game with the\n\t * moves pack (`movesPack`): to a unit (`to: 'target'`, after it as it moves, or `through` it), with what happens to who\n\t * it meets (`collide`, `stops`) and at a wall (`onWall`)\n\t */\n\tdash: Pick<EffectFields, 'distance' | 'leap' | 'climb' | 'speed' | 'effects' | 'buff' | 'to' | 'through' | 'collide' | 'stops' | 'onWall'>\n\t/**\n\t * Throws what it reaches `distance` away from the caster. In a game with the moves pack (`movesPack`): which way\n\t * (`direction`), with what happens to who the thrown one meets (`collide`, `stops`) and at a wall (`onWall`)\n\t */\n\tknockback: Pick<EffectFields, 'distance' | 'speed' | 'leap' | 'direction' | 'collide' | 'stops' | 'onWall'>\n\t/**\n\t * The caster and the unit it was cast on trade places, at once, in a game with the moves pack (`movesPack`). Nothing\n\t * where either is a structure, rushing or dragged, or the target cannot be moved (`BuffDef.unstoppable`)\n\t *\n\t * @beta\n\t */\n\tswap: object\n\t/**\n\t * Sends the unit the effect goes off from (a proxy of the caster's: `EffectCommon.origin`) to where it was aimed, at\n\t * `speed` (at once when left out), and its `effects` happen where it arrives, in the caster's name, from it: Orianna's\n\t * ball flown to where she aims, Azir's soldiers sent. Nothing where it goes off from the caster\n\t *\n\t * @beta\n\t */\n\tsendProxy: Pick<EffectFields, 'speed' | 'effects'>\n\t/**\n\t * The caster's team sees each unit it reaches for `duration` seconds (4 when left out), wherever it goes: in the fog,\n\t * in a bush, invisible or camouflaged, in a game with the vision pack (`visionPack`). A unit, not a spot (`reveal`):\n\t * Rengar's Thrill of the Hunt on the champions about him, Pyke's Death from Below, a Dust of Appearance\n\t *\n\t * @beta\n\t */\n\trevealUnit: Pick<EffectFields, 'duration'>\n\t/**\n\t * One unit rides another, in a game with the moves pack (`movesPack`): the `rider` (the caster, or the unit it was\n\t * cast on) is out of the world (`World.setHidden`: not found, not hit, in nobody's way) and goes where its host goes,\n\t * until the host dies or leaves the world, `duration` seconds are up, or whoever cast it casts the ability again (on the\n\t * host, or with a point: the ability's cooldown starts then). Then it is back where its host is, and `onEnd` happens in\n\t * the rider's name, at the point the recast gave (where it is otherwise), the host its target: Yuumi's You and Me!,\n\t * Kalista's Fate's Call (the ally thrown where she aims)\n\t *\n\t * @beta\n\t */\n\tattach: Pick<EffectFields, 'rider' | 'duration' | 'onEnd'>\n\t/**\n\t * Drags what it reaches to the caster's edge (or to where it landed, `toPoint`) over `seconds`, after the caster as it\n\t * moves; `effects` happen to it as it arrives, in the caster's name. While dragged it does nothing of its own (its\n\t * orders wait, it casts nothing, uses nothing) and nothing else moves it (a knockback, a dash). Who is rushing\n\t * somewhere already, and structures, are not pulled\n\t *\n\t * @beta\n\t */\n\tpull: Pick<EffectFields, 'seconds' | 'toPoint' | 'effects'>\n\t/** An ability of the caster is ready again: `ability`, or the one the effect belongs to */\n\trefresh: Pick<EffectFields, 'ability'>\n\t/** A passive's: `effects` happen around whoever the carrier kills (by an attack, with `attack`; while it carries `whileBuff`) */\n\tonKill: Pick<EffectFields, 'attack' | 'whileBuff' | 'effects' | 'cooldown'>\n\t/** A passive's: `effects` happen to the carrier whenever it casts */\n\tonCast: Pick<EffectFields, 'effects' | 'cooldown'>\n\t/**\n\t * Gives what it reaches an ability (`ability`) at `atLevel` (the effect's level), for `duration` seconds or `uses`\n\t * casts, or for good, in a game with the ability changes pack (`abilityChangesPack`): allies when it says nothing\n\t *\n\t * @beta\n\t */\n\tgrantAbility: { ability: string } & Pick<EffectFields, 'atLevel' | 'duration' | 'uses'>\n\t/**\n\t * The caster's ability `from` (the one the effect belongs to) gives way to `ability` in its place on the card, at its\n\t * level (or `atLevel`), for `duration` seconds or `uses` casts, then back; for good with neither. In a game with the\n\t * ability changes pack: a stance, an awakened ability, a weapon of a set\n\t *\n\t * @beta\n\t */\n\tswapAbility: { ability: string } & Pick<EffectFields, 'from' | 'atLevel' | 'duration' | 'uses'>\n\t/**\n\t * Takes one of the abilities of the unit it was cast on (`pick`: its ultimate when left out) and puts it in the place\n\t * of the one the effect belongs to, at that one's level, for `uses` casts (one when left out) or `duration` seconds,\n\t * then back: Sylas's Hijack. In a game with the ability changes pack\n\t *\n\t * @beta\n\t */\n\tstealAbility: Pick<EffectFields, 'pick' | 'duration' | 'uses'>\n\t/**\n\t * What it reaches becomes the caster's owner's (`World.setOwner`), for `duration` seconds or for good: Charm,\n\t * Dominate. Heroes and structures are left as they are. In a game with the ability changes pack\n\t *\n\t * @beta\n\t */\n\tconvert: Pick<EffectFields, 'duration'>\n\t/**\n\t * A passive's: `effects` happen to whoever hurt the carrier (by an attack with `attack`, from up close with `melee`),\n\t * in the carrier's name, the damage it took in `EffectContext.damage` (`byDamage`): Thorns Aura, Frost Armor, Spiked\n\t * Carapace, Defensive Ball Curl. Not for damage a trigger's effects did: two of them never echo\n\t *\n\t * @beta\n\t */\n\tonDamaged: Pick<EffectFields, 'attack' | 'melee' | 'effects' | 'cooldown'>\n\t/**\n\t * A passive's: `effects` happen to an enemy an ability of the carrier hurt, each time one does (not its attacks, not\n\t * a trigger's effects), the damage in `EffectContext.damage`: Essence Theft, Phenomenal Evil\n\t *\n\t * @beta\n\t */\n\tonAbilityHit: Pick<EffectFields, 'effects' | 'cooldown'>\n\t/**\n\t * A passive's: `effects` happen to the carrier once its health falls below `below` of its max (as it falls past it),\n\t * once in `cooldown` seconds: Mana Barrier\n\t *\n\t * @beta\n\t */\n\tonLowHealth: Pick<EffectFields, 'below' | 'effects' | 'cooldown'>\n\t/**\n\t * A passive's: instead of dying of a blow or a kill, the carrier is left with `health` of its max (all of it when\n\t * left out) and `effects` happen to it, in its name, once in `cooldown` seconds: Reincarnation, Guardian Angel (an\n\t * item's), Anivia's Rebirth (a `morph` into the egg), Zilean's Chronoshift (a buff's)\n\t *\n\t * @beta\n\t */\n\tonFatal: Pick<EffectFields, 'health' | 'effects' | 'cooldown'>\n\t/**\n\t * Takes `buff` off what it reaches: `stacks` of it, or all of it (every one of it there is) when left out. A mark\n\t * popped, stacks spent\n\t *\n\t * @beta\n\t */\n\tremoveBuff: { buff: string } & Pick<EffectFields, 'stacks'>\n\t/**\n\t * Takes off what holds them up from what it reaches (allies when it says nothing): harmful stuns, roots, silences,\n\t * disarms, controls, grounds and slows, not a suppression nor being thrown up (`isCleansable`): Remove Scurvy\n\t *\n\t * @beta\n\t */\n\tcleanse: object\n\t/** `effects` when the ability went off charged, `otherwise` when it did not */\n\tcharged: Pick<EffectFields, 'effects' | 'otherwise'>\n\t/**\n\t * `effects` when what it asks holds, `otherwise` when it does not: of the `caster` and of the `target`\n\t * (`UnitCondition`: a buff, health below a share, a hero, tags, enemy or ally; or code) and by `chance`. On the unit it\n\t * was cast on, or, with a `radius` or `shape`, on each within it (as `affects` says, enemies when it says nothing),\n\t * each then the target of what it does. Execute below 20%, Holy Light on the undead, Bash's chance (`conditionHolds`)\n\t *\n\t * @beta\n\t */\n\tif: Pick<EffectFields, 'caster' | 'target' | 'effects' | 'otherwise'>\n\t/** `effects` happen at the spot, `delay` seconds from now */\n\tafter: Pick<EffectFields, 'delay' | 'effects' | 'impact'>\n\t/** For `duration` seconds `effects` happen to what is at the spot, over and over, and `onEnd` at the end */\n\tzone: Pick<EffectFields, 'duration' | 'effects' | 'onEnd' | 'follow' | 'onEnter' | 'onLeave' | 'edge'>\n\t/** Finds what is invisible around the spot: the caster's team sees it for `duration` seconds */\n\tdetect: Pick<EffectFields, 'duration'>\n\t/** Raises `count` of the corpses around the spot as units of `unit`, for `duration` seconds or for good */\n\traiseDead: { unit?: string } & Pick<EffectFields, 'duration' | 'count' | 'as'>\n\t/**\n\t * Brings back the corpses of the caster's side around the spot (within `radius`, 6) as what they were, their owners'\n\t * again and whole, `count` of them at most (all when left out): Resurrection\n\t *\n\t * @beta\n\t */\n\trevive: Pick<EffectFields, 'count'>\n\t/**\n\t * Makes `count` copies of the target, for `duration` seconds: they deal `dealt` of its damage (a third when left out)\n\t * and take `taken` times what they are dealt (twice when left out)\n\t */\n\tillusion: Pick<EffectFields, 'count' | 'duration'> & { dealt?: number; taken?: number }\n\t/**\n\t * Brings `count` (1) units of `unit` around where it landed, `spread` cells from it (1.5), for `lifetime` seconds (for\n\t * good when left out): the caster's summons (`summoned`). With nothing to attack they walk with the caster (`follow`,\n\t * true); `aggro` says whom they go for (`mastersAttacker` when left out: whoever hits the caster, then the nearest);\n\t * they die with the caster unless `diesWithMaster` is false\n\t *\n\t * @beta\n\t */\n\tsummon: { unit: string } & Pick<EffectFields, 'count'> & {\n\t\t\tlifetime?: Scaled\n\t\t\tspread?: number\n\t\t\tfollow?: boolean\n\t\t\taggro?: 'nearest' | 'mastersAttacker' | 'none'\n\t\t\tdiesWithMaster?: boolean\n\t\t}\n\t/** Takes the buffs off what it reaches, and hurts what is summoned by `amount` */\n\tdispel: Pick<EffectFields, 'amount'>\n\t/**\n\t * Turns the caster into another unit type where it stands (`into`), a form (`takeForm`): its level, experience,\n\t * items, buffs and the share of its health and mana kept, what it was told going on, and the form's abilities\n\t * learned at the levels its form says (`HeroDef.forms`). For `duration` seconds, or until cast again (`toggle`), or\n\t * both; `back` says what turns it back\n\t *\n\t * @beta\n\t */\n\tmorph: { into: string } & Pick<EffectFields, 'duration' | 'toggle' | 'back'>\n\t/**\n\t * Trades `amount` of a resource of the caster's owner (`sell`) for another (`buy`), `rate` of it for each one sold:\n\t * a marketplace's (`presetMarket`, `exchange` in code). Nothing of it with less than `amount` to sell\n\t */\n\texchange: { sell: string; buy: string; rate: number; amount: Scaled }\n\t/**\n\t * A tome's, in a game with the tomes pack (`tomesPack`): what it reaches gains `gain` for good (a point of strength),\n\t * a hero `xp` experience and `levels` levels\n\t */\n\ttome: { gain?: StatChange; xp?: number; levels?: number }\n\t/**\n\t * Mana burn, in a game with its pack (`manaBurnPack`): takes `amount` of the mana of what it reaches, and hurts it by\n\t * as much as it took, times `ratio` (1 when left out), magic damage unless `damageType` says\n\t */\n\tmanaBurn: Pick<EffectFields, 'amount' | 'scaling' | 'damageType'> & { ratio?: number }\n\t/**\n\t * A town portal, in a game with the portals pack (`portalsPack`): the caster and as many as `count` (12 when left out)\n\t * of its own units within `radius` (7) of it are at once at its side's home nearest where it was aimed (`homeOf`)\n\t */\n\ttownPortal: Pick<EffectFields, 'count'>\n\t/**\n\t * A passive's, in a game with the default items (`defaultItemsPack`): keeps `buff` on the allies within `radius` of\n\t * the carrier (itself too) while the carrier does not carry `spent`: Dawnmender's ward, whose `onFatal` spends it\n\t * (`wardSpent`)\n\t *\n\t * @beta\n\t */\n\tallyWard: { buff: string; spent: string }\n\t/**\n\t * Of a ward's trigger (`allyWard`), on the ally it saved: puts `spent` on whoever gave the ward for `duration`\n\t * seconds and takes the ward (`buff`) off everyone it gave it to: one save a while, for all of them\n\t *\n\t * @beta\n\t */\n\twardSpent: { buff: string; spent: string } & Pick<EffectFields, 'duration'>\n\t/**\n\t * The caster's abilities are ready again: the ones it learns (`HeroDef.learns`), not its ultimate unless `ultimate`,\n\t * not what its items do. Nightfang's kill. In a game with the default items\n\t *\n\t * @beta\n\t */\n\trefreshAbilities: { ultimate?: boolean }\n\t/**\n\t * A passive's: the caster's ability `spell` (by id, a hero spell's: `reap`) cools down `part` faster (0.5: half\n\t * again). Nothing for a caster without it. In a game with the default items\n\t *\n\t * @beta\n\t */\n\tquicken: { spell: string; part: number }\n\t/**\n\t * A passive's: `buff` on the carrier while it is out of fights, neither hurt nor attacking for `after` seconds (5\n\t * when left out): Shadow Cowl's, Wanderer's Boots' speed. In a game with the default items\n\t *\n\t * @beta\n\t */\n\toutOfFights: { buff: string; after?: number }\n\t/**\n\t * Gives the caster's owner `amount` of the game's currency: a kill near the Ring of the Old King. In a game with the\n\t * default items\n\t *\n\t * @beta\n\t */\n\treward: Pick<EffectFields, 'amount'>\n\t/**\n\t * A passive's: a `unit` of the carrier's at its side at night, its summon (`summoned`), gone by day: Wolfhide Charm.\n\t * In a game with the default items\n\t *\n\t * @beta\n\t */\n\tnightCompanion: { unit: string }\n}\n\n/**\n * One thing an ability does: its `type`, which picks the handler and says which fields it has (`EffectTypes`)\n *\n * @public\n */\nexport type EffectDef = { [K in keyof EffectTypes]: { type: K } & EffectCommon & EffectTypes[K] }[keyof EffectTypes]\n\n/**\n * An effect seen as any type may be, every field of the engine's by its name: for what reads effects of every type\n * alike (an ability's tooltip numbers, the rules' check of what they name). A handler reads its own type's\n * (`EffectOf`)\n *\n * @beta\n */\nexport type AnyEffect = { type: keyof EffectTypes } & EffectCommon & Partial<EffectFields>\n\n/**\n * An effect as any type may be (`AnyEffect`), its fields by name\n *\n * @beta\n */\nexport const anyEffect = (effect: EffectDef): AnyEffect => effect as AnyEffect\n\n/**\n * The effects inside an effect, whatever its type: what it does to what it hits (`effects`), when it is not charged\n * (`otherwise`), and at its end (`onEnd`)\n *\n * @internal\n */\nexport function innerEffects(effect: EffectDef): EffectDef[] {\n\tconst { effects, otherwise, onEnd } = anyEffect(effect)\n\treturn [...(effects ?? []), ...(otherwise ?? []), ...(onEnd ?? [])]\n}\n\n/** An effect of a chain as it is being lowered: what waits on it, by the list it goes into */\ninterface ChainLink {\n\teffect: EffectDef\n\t/** The effect as the list has it, before its `when` was taken off */\n\twritten: EffectDef\n\twaiting?: Partial<Record<'effects' | 'onEnd', ChainLink[]>>\n}\n\n/** The effects a chain made (`lowerChain`), each to the effect it was made from as the list has it: what the screen is told */\nconst loweredFrom = new WeakMap<EffectDef, EffectDef>()\n/** The lists a chain made, each to the effect whose it is as the list has it */\nconst loweredLists = new WeakMap<readonly EffectDef[], EffectDef>()\n\n/**\n * The effect a list a chain made is of (`lowerChain`), as its ability has it: none for a list as written\n *\n * @internal\n */\nexport const loweredListOf = (list: readonly EffectDef[]): EffectDef | undefined => loweredLists.get(list)\n\n/**\n * The effect as its ability has it, for one a chain made (`lowerChain` copies what waits, and what it waits on): the\n * effect itself otherwise\n *\n * @internal\n */\nexport const writtenEffect = (effect: EffectDef): EffectDef => loweredFrom.get(effect) ?? effect\n\n/**\n * A list of effects as it runs (`EffectCommon.when`): every effect that waits for a moment taken out of the list and\n * put at the end of the list of the nearest one before it that comes to that moment (a missile's `effects` for `hit`,\n * its `onEnd` for `end`), copied; what waits on what waits itself goes in there. The list itself when nothing in it\n * waits, so the nested shape (`{ type: 'missile', effects: [...] }`) and a chain are one thing by the time they run.\n * One with nothing to wait on is dropped, and `orphan` told of it by its index in the list\n *\n * @beta\n */\nexport function lowerChain(effects: readonly EffectDef[], orphan?: (index: number, effect: EffectDef) => void): EffectDef[] {\n\tif (!effects.some((effect) => effect.when)) return effects as EffectDef[]\n\tconst top: ChainLink[] = []\n\tconst seen: ChainLink[] = []\n\teffects.forEach((effect, index) => {\n\t\tconst link: ChainLink = { effect, written: effect }\n\t\tif (!effect.when) {\n\t\t\ttop.push(link)\n\t\t\tseen.push(link)\n\t\t\treturn\n\t\t}\n\t\tconst moment = Object.hasOwn(EFFECT_MOMENTS, effect.when) ? EFFECT_MOMENTS[effect.when] : undefined\n\t\tlet on: ChainLink | undefined\n\t\tfor (let i = seen.length - 1; i >= 0 && moment && !on; i--) if (moment.types.includes(seen[i].effect.type)) on = seen[i]\n\t\tif (!on || !moment) {\n\t\t\torphan?.(index, effect)\n\t\t\treturn\n\t\t}\n\t\tconst { when: _, ...now } = effect\n\t\tlink.effect = now as EffectDef\n\t\ton.waiting ??= {}\n\t\t;(on.waiting[moment.into] ??= []).push(link)\n\t\tseen.push(link)\n\t})\n\tconst made = (link: ChainLink): EffectDef => {\n\t\tif (link.effect !== link.written) loweredFrom.set(link.effect, link.written)\n\t\tif (!link.waiting) return link.effect\n\t\tconst copy = { ...anyEffect(link.effect) }\n\t\tfor (const [into, links] of Object.entries(link.waiting) as ['effects' | 'onEnd', ChainLink[]][])\n\t\t\tcopy[into] = [...(copy[into] ?? []), ...links.map(made)]\n\t\tloweredFrom.set(copy as EffectDef, link.written)\n\t\tfor (const into of Object.keys(link.waiting) as ('effects' | 'onEnd')[]) loweredLists.set(copy[into]!, link.written)\n\t\treturn copy as EffectDef\n\t}\n\treturn top.map(made)\n}\n\n/**\n * An effect of one type\n *\n * @beta\n */\nexport type EffectOf<K extends keyof EffectTypes> = { type: K } & EffectCommon & EffectTypes[K]\n\n/**\n * The ground an ability covers: what the player aims with, and what is shown when it goes off\n *\n * @beta\n */\nexport type AimShape =\n\t| { shape: 'circle'; radius: number }\n\t| { shape: 'line'; length: number; width: number }\n\t/** A fan from the caster: `angle` is how wide it opens, in radians */\n\t| { shape: 'cone'; length: number; angle: number }\n\t/** A ring at the spot: what is `radius` away and up to `width` closer, not what is in the middle */\n\t| { shape: 'ring'; radius: number; width: number }\n\t/** A stretch of a ring around the caster, `radius` away, `angle` wide (radians) and `width` thick, its middle the way it is aimed */\n\t| { shape: 'arc'; radius: number; angle: number; width: number }\n\t/** A rectangle around the spot, `length` long the way it is aimed and `width` out on either side */\n\t| { shape: 'rect'; length: number; width: number }\n\t/** An X at the spot: two bars `length` long and `width` out on either side, crossing square, each turned an eighth from the way it is aimed */\n\t| { shape: 'cross'; length: number; width: number }\n\n/**\n * The definition of an ability: how it is aimed, what it costs and the effects it has\n *\n * @public\n */\nexport interface AbilityDef {\n\t/** The ability's id, shared by every game: give it a prefix of the game's */\n\tid: string\n\t/** What the player sees the ability called */\n\tname: string\n\t/**\n\t * How what its damage kills dies, for the screen (`'burnt'`, `'frozen'`, `'blasted'`): the death's `how`, which the\n\t * view shows its way. A word, or one decided for each blow: by its level, its caster, what it hit. An effect's own\n\t * (`EffectDef.how`) goes over it; the `death` hook has the last say\n\t */\n\thow?: string | ((hit: { caster: Entity; target: Entity; level: number; amount: number }) => string | undefined)\n\t/**\n\t * The definition this one is a copy of, made from the data (`copyOf` in a `data.json`, the editor's Copy as new):\n\t * what it is drawn, heard and pictured as where the game gives it no look of its own\n\t */\n\tbasedOn?: string\n\t/**\n\t * What it does, in words: a template with values in braces, worked out for the caster as it is now (\"Deals {damage}\n\t * magic damage\" shows \"Deals 80 (50 + 60% ability power) magic damage\"). The values are its own (`values`), or found\n\t * in its effects: `damage`, `heal`, `shield`, `amount`, `duration`, `radius`, `chance` (in percent), `range`, `cooldown`, `charges`, `refill`,\n\t * `mana`, `count`, `distance` (see `abilityValues`)\n\t */\n\tdescription?: string\n\t/** Values of its own to put in its description, by name: an amount and what of the caster scales it, or worked out in code */\n\tvalues?: Record<string, AbilityValueDef>\n\t/** What it does, said in code instead of `description`: words with `{values}` in them, or words and values already put together */\n\tdescribe?: (context: AbilityTextContext) => string | TextSegment[]\n\t/** The key that casts it from the command card */\n\thotkey?: string\n\t/**\n\t * none: happens at once. unit, point: needs a target, and the caster walks into range of it.\n\t * direction: goes off from where the caster stands, towards where it was aimed. vector: two points, where it starts\n\t * (walked into range of, its effects' `origin`) and the way it goes from there (their `point`): Death Ray, Seismic\n\t * Shove. passive: always on, cannot be cast. Or a game's own (`defineTargeting`, `Rules.targetings`)\n\t */\n\ttarget: AbilityTarget\n\t/** What may be targeted, for abilities cast on a unit */\n\ttargets?: {\n\t\tallies?: boolean\n\t\tenemies?: boolean\n\t\tself?: boolean\n\t\tkinds?: EntityKind[]\n\t\tlayers?: Layer[]\n\t\t/** True: heroes alone; false: anything but a hero (a creep, a minion, a building: Reap). Heroes or not when left out */\n\t\theroes?: boolean\n\t\t/** Only what has one of these tags of its type (`UnitTypeDef.tags`): Death Coil on the undead @beta */\n\t\ttags?: string[]\n\t}\n\t/** Mana it costs per cast, by level */\n\tmanaCost?: Scaled\n\t/** Health it costs, as a part of all the caster can have. It cannot be cast with less than that left */\n\thealthCost?: Scaled\n\t/**\n\t * What it costs of the caster's pools (`UnitTypeDef.pools`), by pool, in a game with the resources pack\n\t * (`resourcesPack`): it is not ready with less, and pays as it goes off (Akali's energy, a shot of ammo)\n\t *\n\t * @beta\n\t */\n\tcost?: Record<string, Scaled>\n\t/**\n\t * What it gives the caster's pools as it goes off, by pool, in a game with the resources pack: Rumble's heat, a\n\t * fury's spender's opposite\n\t *\n\t * @beta\n\t */\n\tgain?: Record<string, Scaled>\n\t/**\n\t * Its costs (its mana and `cost`) grow with the stacks of a buff of the caster's, in a game with the resources pack:\n\t * times one and `per` for each stack (Kassadin's Riftwalk: `per: 1`, twice with one stack, three times with two)\n\t *\n\t * @beta\n\t */\n\tcostGrowth?: { buff: string; per: number }\n\t/** Seconds before it can be used again */\n\tcooldown?: Scaled\n\t/**\n\t * Uses it holds, for one used so many times before it waits: `count` of them at the most, one more back every\n\t * `refill` seconds while it holds fewer (shortened as the cooldown is). Each use spends one; with none left it is not\n\t * ready. Its `cooldown`, where it has one, is then the time between two uses. Full when it is learned\n\t */\n\tcharges?: { count: Scaled; refill: Scaled }\n\t/**\n\t * It may be cast again for a while after it is cast (`AbilityRecast`): Ahri's Spirit Rush thrice, Lee Sin's second\n\t * Sonic Wave to the one the first marked, Lux's Lucent Singularity set off\n\t *\n\t * @beta\n\t */\n\trecast?: AbilityRecast\n\t/** How far away the target may be */\n\trange?: Scaled\n\t/** The target may be as far away as the caster's attacks reach, and `range` farther */\n\tattackRange?: boolean\n\t/**\n\t * What kind of thing it is, for those who can keep out of its way: a buff that `avoids` one of these\n\t * lets nothing of the ability happen to who carries it. `ground` is for what comes out of the ground or along it\n\t */\n\ttags?: string[]\n\t/** Levels a hero can put into it. 3 when left out */\n\tmaxLevel?: number\n\t/** Hero level needed for the first level of the ability. 1 when left out, 6 for an `ultimate` */\n\trequiresLevel?: number\n\t/**\n\t * A hero's ultimate: first learned at level 6 (unless `requiresLevel` says otherwise), what the AI uses on a crowd\n\t * only (as it does what asks for a level), and what a game's own code can tell apart (what a possession of another\n\t * hero leaves the hero's own: `keeps`)\n\t */\n\tultimate?: boolean\n\t/** Hero levels between two levels of the ability. 2 when left out */\n\tlevelStep?: number\n\t/**\n\t * Seconds between starting to cast and the effect. The caster stands still for as long and cannot be\n\t * called away: what it is told to do in the meantime, it does right after. None when left out\n\t */\n\tcastTime?: number\n\t/** Gets through a unit's immunity to spells (see `UnitTypeDef.spellImmune`), as an ultimate may. Or for the targets its function says */\n\tpiercesImmunity?: boolean | ((world: World, target: Entity) => boolean)\n\t/** The ground it covers, when that is not what its effects say: see `aimOf` */\n\taim?:\n\t\t| { shape: 'circle'; radius: Scaled }\n\t\t| { shape: 'line'; length: Scaled; width: Scaled }\n\t\t| { shape: 'cone'; length: Scaled; angle: number }\n\t\t| { shape: 'ring'; radius: Scaled; width: Scaled }\n\t\t| { shape: 'arc'; radius: Scaled; angle: number; width: Scaled }\n\t\t| { shape: 'rect'; length: Scaled; width: Scaled }\n\t\t| { shape: 'cross'; length: Scaled; width: Scaled }\n\t/** Units use it on their own when they have nothing else to do. The player can switch this off */\n\tautocast?: boolean\n\t/**\n\t * A buff of the caster that charges the ability when it has as many stacks as it can: the ability shows it, its\n\t * `charged` effects do their other thing, and casting it takes the buff away\n\t */\n\tcharge?: string\n\t/** What it does, one effect after the other, when it is cast */\n\teffects: EffectDef[]\n\t/** What an ability that is cast does all the time besides, once it is learned: buffs, auras, `onHit` */\n\tpassive?: EffectDef[]\n\t/**\n\t * Autocast in code, for any kind of ability: where to use it now, or nothing. Asked when the unit has nothing to\n\t * do, the ability is switched to autocast, ready and paid for. Without it, only abilities cast on a unit autocast,\n\t * on the worst-off target their core effects would do good to\n\t */\n\tautoAim?: (world: World, caster: Entity, state: AbilityState) => { target?: number; point?: Vec2 } | null | undefined\n\t/**\n\t * How a computer player uses it, from what it sees (see `AiView`): where, or `null` for not now. What the engine\n\t * works out from its core effects when it gives nothing; an ability of the game's own effects has to say\n\t */\n\tai?: (view: AbilityAiView, caster: EntityState, level: number) => { point: Vec2; target?: number; to?: Vec2 } | null | undefined\n\t/** How far away the target may be, in code: the range on high ground, say. `range` is what the screen shows */\n\trangeOf?: (world: World, caster: Entity, level: number) => number\n\t/** Seconds of the wind-up, in code: shortened by haste, say. `castTime` when left out */\n\tcastTimeOf?: (world: World, caster: Entity, level: number) => number\n\t/**\n\t * Kept up once it went off: the caster stands, for `duration` seconds, doing it every `every` seconds (effects, or\n\t * code), until it is done or interrupted (another order, a stun), when `interrupted` runs. An ice storm\n\t */\n\tchannel?: {\n\t\tduration: number | ((world: World, caster: Entity, level: number) => number)\n\t\tevery?: number\n\t\teffects?: EffectDef[]\n\t\trun?: (world: World, caster: Entity, level: number, target: Entity | undefined, point: Vec2) => void\n\t\tinterrupted?: (world: World, caster: Entity, level: number) => void\n\t\t/** What it does once kept up to the end, and only then: a recall's teleport home */\n\t\tfinished?: EffectDef[]\n\t\t/** Broken off when the caster is hurt, as a recall is: any damage, from anyone */\n\t\tbreaksOnDamage?: boolean\n\t\t/**\n\t\t * A tether: broken off (`interrupted`) as the unit it was cast on gets farther than this from the caster's edge,\n\t\t * dies or hides: Siphon Mana, Life Drain, Morgana's Soul Shackles\n\t\t *\n\t\t * @beta\n\t\t */\n\t\tleash?: number\n\t\t/**\n\t\t * Aimed as it goes: where it goes off at (`point`) follows the player's `aim` commands, in a game with the holds\n\t\t * pack (`holdsPack`): Vel'Koz's ray, Jhin's Curtain Call, Starfall's sweep. The caster turns to it\n\t\t *\n\t\t * @beta\n\t\t */\n\t\taimed?: boolean\n\t\t/**\n\t\t * Kept up as the caster walks, in a game with the holds pack (`holdsPack`): not an order the caster stands in, so\n\t\t * it may be told to go elsewhere while it lasts; broken off by a stun, a silence, its death\n\t\t *\n\t\t * @beta\n\t\t */\n\t\twalks?: boolean\n\t}\n\t/**\n\t * What it may be made into for good, chosen once (`upgradeAbility`, the `upgradeAbility` command), in a game with the\n\t * ability changes pack (`abilityChangesPack`): Viktor's augments, Engineering Upgrade's better abilities. The new one\n\t * takes its place at its level and cooldown\n\t *\n\t * @beta\n\t */\n\tupgrades?: string[]\n\t/**\n\t * Held to charge and let go, in a game with the holds pack (`holdsPack`): the cast starts the hold where the caster\n\t * stands, going on with what it was doing, and the `release` command (the key let go, or a click) sets it off, as\n\t * full as it was held (`HoldDef`): farther, harder, or a tap's other effects. Paid as it is let go\n\t *\n\t * @beta\n\t */\n\thold?: HoldDef\n}\n\n/**\n * How an ability is held to charge and let go (`AbilityDef.hold`), in a game with the holds pack: Varus's Piercing Arrow,\n * Xerath's Arcanopulse, Pyke's Bone Skewer, Viego's Spectral Maw\n *\n * @beta\n */\nexport interface HoldDef {\n\t/** Seconds held for it to be full */\n\tmax: number\n\t/** Seconds held after which it goes off by itself, where it was last aimed: as it is full when left out */\n\tupTo?: number\n\t/** How far it reaches let go at once (`from`) and full (`to`): where it is let go at is brought that near */\n\trange?: { from: number; to: number }\n\t/** What its amounts come to full, times what they are let go at once (1.5: half again); what comes between is between */\n\tscale?: number\n\t/** Let go before `under` seconds: these effects in place of its own (Pyke's stab, not his hook) */\n\ttap?: { under: number; effects: EffectDef[] }\n\t/** A buff on the caster while it holds: a slow */\n\tbuff?: string\n}\n\n/**\n * What an ability does all the time: all of a passive one, and the passive part of the others\n *\n * @internal\n */\nexport const passiveEffects = (ability: AbilityDef): EffectDef[] => (ability.target === 'passive' ? ability.effects : (ability.passive ?? []))\n\n/**\n * What the stats of the caster add to an amount. `level` is for every level of a hero past the first,\n * `bonusAttackDamage` for the attack damage it has on top of what its type and its levels give it\n *\n * @beta\n */\nexport type Scaling = Partial<Record<StatKey | 'level' | 'bonusAttackDamage', Scaled>>\n\n/**\n * Something lasting on a unit that changes what it can do\n *\n * @public\n */\nexport interface BuffDef extends ScaledStatChange {\n\t/** The buff's id, shared by every game: give it a prefix of the game's */\n\tid: string\n\t/** What the player sees the buff called */\n\tname: string\n\t/**\n\t * The definition this one is a copy of, made from the data (`copyOf` in a `data.json`, the editor's Copy as new):\n\t * what it is drawn, heard and pictured as where the game gives it no look of its own\n\t */\n\tbasedOn?: string\n\t/** What the buff does, in words, shown when the pointer is over it */\n\tdescription?: string\n\t/** Seconds. Lasts until removed when left out */\n\tduration?: number\n\t/** A debuff: by default it goes on enemies */\n\tharmful?: boolean\n\t/**\n\t * Free words to find it by and to sort it with (`fire`, `slow`, `anti-heal`), as abilities and units have: what a\n\t * search matches, what a game's code asks (`buffsTagged`)\n\t *\n\t * @beta\n\t */\n\ttags?: string[]\n\t/** The unit cannot do anything. A function says so for one carrier, one moment */\n\tstun?: boolean | BuffCheck\n\t/** Thrown into the air for as long as it lasts. Comes with a stun, the rest is for the eye */\n\tairborne?: boolean\n\t/** Knocked down: it lies on the ground for as long as it lasts, and gets up at the end. For the eye, like `airborne` */\n\tdown?: boolean\n\t/** Brings what flies down: it counts as being on the ground, for whatever is aimed at it */\n\tgrounds?: boolean\n\t/**\n\t * Its carrier is invisible to enemies for as long as it lasts, unless they find it (`detect`): a Wind Walk. A function\n\t * says so for one carrier, one moment\n\t */\n\tinvisible?: boolean | BuffCheck\n\t/** The unit cannot move from the spot. It can still fight and cast. A function says so for one carrier, one moment */\n\troot?: boolean | BuffCheck\n\t/**\n\t * The unit cannot use its abilities. What it carries and the spells every hero has still work. A function says\n\t * which abilities it keeps it from (`(ability) => ability.tags?.includes('fire')`): the screen asks it too\n\t */\n\tsilence?: boolean | ((ability: AbilityDef) => boolean)\n\t/** Damage it takes in place of the unit, for as long as the buff lasts and there is something left of it */\n\tshield?: Scaled\n\t/** What the stats of whoever gave the shield add to it */\n\tshieldScaling?: Scaling\n\t/** The shield is as good as new once the unit has not been hurt for this many seconds */\n\trecharge?: number\n\t/** Tags of abilities that do nothing to who carries it, for as long as it does: `ground` for someone up in the air */\n\tavoids?: string[]\n\t/** Who carries it does not attack while it lasts: burrowed, or disarmed. Or while its function says */\n\tdisarm?: boolean | BuffCheck\n\t/** Who carries it is immune to spells while it lasts, as an avatar is (see `UnitTypeDef.spellImmune`). Or while its function says */\n\tspellImmune?: boolean | BuffCheck\n\t/**\n\t * Who carries it takes no damage while it lasts, and no enemy's ability may be cast on it (Divine Shield, Kayle's\n\t * Intervention, Zhonya's stasis with a `stun`). Effects other than damage still reach it. Or while its function says\n\t *\n\t * @beta\n\t */\n\tinvulnerable?: boolean | BuffCheck\n\t/**\n\t * Who carries it is out of reach while it lasts (Fizz's Playful, Zed's Death Mark dash, Vlad's pool): no ability may be\n\t * cast on it but by itself, no attack is aimed at it nor lands, and no effect of anyone else's reaches it (an area,\n\t * a missile, a chain), allies' too; it is still seen and still in the way. Or while its function says\n\t *\n\t * @beta\n\t */\n\tuntargetable?: boolean | BuffCheck\n\t/**\n\t * The least health damage leaves its carrier with while it lasts (Tryndamere's Undying Rage at 1, Kindred's Lamb's\n\t * Respite at a tenth of its max): a number, one per level, or code with the carrier. It is hurt down to it, never past\n\t * it. The highest of what it carries counts\n\t *\n\t * @beta\n\t */\n\tminHealth?: Scaled | ((world: World, carrier: Entity, instance: BuffInstance) => number)\n\t/**\n\t * Whether a dispel takes it off (see the effect `dispel`). Yes when left out: no for what nothing should end early.\n\t * Decided in code for each dispel: by who dispels it (`by`), its level\n\t */\n\tdispellable?: boolean | ((world: World, carrier: Entity, instance: BuffInstance, by: Entity) => boolean)\n\t/** How many of it one unit can carry at most. What puts it on says whether it adds one (`stack`) */\n\tmaxStacks?: number\n\t/** What happens around who carried it when its time is up, in the name of who put it there. Not when it is taken off */\n\tonEnd?: EffectDef[]\n\t/** Its stats count once for every stack it has (`stacks`), rather than once: \"each stack, -5% move speed\" */\n\tperStack?: boolean\n\t/**\n\t * Stats of its own, worked out in code, on top of what it declares: \"+2 armor for each ally near\". Asked when the\n\t * carrier's stats are added up, which is only when something they come from changed: what this depends on beyond\n\t * the buff (allies near, the time) calls `invalidateStats` when it changes\n\t */\n\tchange?: (world: World, carrier: Entity, instance: BuffInstance) => StatChange | undefined\n\t/**\n\t * What happens when it is put on a unit that has it already. `strongest` (the default): the higher level wins,\n\t * the longer among equals. `refresh`: the time starts over, the level the new one's. `perSource`: one of it for\n\t * every unit that puts it on, each of its own (two poisons from two casters). `independent`: a new one every time.\n\t * A function decides from the one there and the one coming: `replace` it, `renew` its time, `add` another, or `keep`\n\t */\n\tstacking?:\n\t\t'strongest' | 'refresh' | 'perSource' | 'independent' | ((existing: BuffInstance, incoming: IncomingBuff) => 'replace' | 'renew' | 'add' | 'keep')\n\t/** What happens as it is put on: effects in the name of who put it there (while they live), or code */\n\tonApply?: EffectDef[] | BuffHandler\n\t/** What happens every `every` seconds while it lasts: effects in the name of who put it there (while they live), or code, which runs whoever is left */\n\tonTick?: { every: number; effects?: EffectDef[]; run?: BuffHandler }\n\t/** Code run when it comes off, run out (`expired`) or taken off. Not for the buffs of something that dies */\n\tonRemove?: (world: World, carrier: Entity, instance: BuffInstance, expired: boolean) => void\n\t/**\n\t * It takes its carrier's orders while it lasts: what it was told waits (a channel is broken off), the player's and\n\t * anyone's new orders are refused, and it goes on with what it was told after, as from a stun. `fear`: it walks away\n\t * from who put it on; `charm`: it walks to them; `taunt`: it attacks them (walks to them where it cannot). Code\n\t * (`BuffControl`) steers it itself every tick. The last of them it carries is the one it does\n\t *\n\t * @beta\n\t */\n\tcontrol?: ControlKind | BuffControl\n\t/**\n\t * Held like a stun, and more: tenacity does not cut it short and a `cleanse` does not take it off (Malzahar's\n\t * Nether Grasp, Skarner's Impale)\n\t *\n\t * @beta\n\t */\n\tsuppress?: boolean\n\t/**\n\t * Its carrier cannot rush or jump anywhere of its own: an ability of its with a `dash` or a `blink` is refused\n\t * (\"Grounded\"), and such an effect of its does nothing (Singed's Mega Adhesive). Not `grounds`, which brings a flyer down\n\t *\n\t * @beta\n\t */\n\tgrounded?: boolean\n\t/**\n\t * What it takes of its carrier each second while it lasts, by pool (`UnitTypeDef.pools`) or `mana`, in a game with\n\t * the resources pack (`resourcesPack`): taken off when there is not enough for the next second's (Immolation, a\n\t * Glacial Storm kept up)\n\t *\n\t * @beta\n\t */\n\tdrain?: Record<string, number>\n\t/**\n\t * Nothing that holds a unit up does anything to its carrier while it lasts: harmful stuns, roots, silences, disarms,\n\t * controls, suppressions and grounds on it hold nothing, new ones do not take, and it is neither thrown nor pulled\n\t * (Olaf's Ragnarok, Malphite's Unstoppable Force). Slows still slow\n\t *\n\t * @beta\n\t */\n\tunstoppable?: boolean\n\t/**\n\t * Its carrier is seen by the team of whoever put it on while it lasts, wherever it stands: in the fog, in a bush,\n\t * invisible or camouflaged (the fog lit where it stands, as for what a `detect` found), in a game with the vision\n\t * pack (`visionPack`): Kindred's mark, a hunter's quarry\n\t *\n\t * @beta\n\t */\n\trevealed?: boolean\n\t/**\n\t * Its carrier is camouflaged while it lasts, in a game with the vision pack (`visionPack`): its enemies see it only\n\t * from within this far of it (a unit of theirs that near), unless something finds it (`trueSight`, `detect`,\n\t * `revealUnit`) or it attacked them a moment ago: Pyke's Ghostwater Dive, Rengar's Thrill of the Hunt, Viego's mist.\n\t * A function says how far for one carrier, one moment\n\t *\n\t * @beta\n\t */\n\tcamouflage?: number | ((world: World, carrier: Entity, instance: BuffInstance) => number)\n\t/**\n\t * Its carrier finds what of its enemies is invisible or camouflaged within this far of it, for its team, while it\n\t * lasts, in a game with the vision pack (`visionPack`): an Oracle Lens, a Magic Sentry on a tower\n\t *\n\t * @beta\n\t */\n\ttrueSight?: number\n\t/**\n\t * Its carrier walks through other units, and they through it, while it lasts: neither steers round nor pushes the\n\t * other (a Ghost, a Phantom Stride). Walls, cliffs, buildings and trees still stop it. A function says so for one\n\t * carrier, one moment\n\t *\n\t * @beta\n\t */\n\tphasing?: boolean | BuffCheck\n\t/**\n\t * Its carrier's blows from up close strike the enemies around their target too, a part of their damage each, as an\n\t * attack's own cleave (`AttackDef.cleave`): the larger part counts\n\t *\n\t * @beta\n\t */\n\tcleave?: Cleave\n\t/**\n\t * The healing past full health that its carrier gives (`given`, when left out) or gets (`taken`) becomes a shield on\n\t * whoever was healed: the buff `buff` (its own time, and a shield of its own where it says), holding `part` of what\n\t * spilled over (all of it when left out), up to `most` of the healed one's max health (a third when left out)\n\t *\n\t * @beta\n\t */\n\toverheal?: { buff: string; part?: Scaled; most?: number; of?: 'given' | 'taken' }\n\t/**\n\t * Its carrier pays for its abilities with health, not mana, while it carries it: this much health for each point of\n\t * mana they cost (1 for `true`). It cannot cast with no more health than that; items still cost nothing\n\t *\n\t * @beta\n\t */\n\tpaysWithHealth?: boolean | number\n\t/**\n\t * What its carrier's attacks, hurts, casts and kills set off while it carries it, as an ability's passive does\n\t * (`onHit`, `onKill`, `onCast`, `onDamaged`, `onAbilityHit`, `onLowHealth`), in the carrier's name: Frost Armor's\n\t * slow on who strikes it, a Thorns Aura's buff, the empowered next attack of a buff a cast put on\n\t *\n\t * @beta\n\t */\n\tpassive?: EffectDef[]\n\t/**\n\t * What takes it off before its time: `damage` (its carrier hurt: Sleep), `attack` (an attack of its carrier lands,\n\t * after what the attack sets off: Wind Walk), `cast` (its carrier casts an ability other than the one that put it on)\n\t *\n\t * @beta\n\t */\n\tbreaksOn?: BuffBreak[]\n\t/**\n\t * What happens where its carrier dies carrying it, in the name of who put it on (while they live): Doom's demon, Black\n\t * Arrow's skeleton, a mark that spreads\n\t *\n\t * @beta\n\t */\n\tonCarrierDeath?: EffectDef[]\n\t/**\n\t * What happens to its carrier as an effect (`stack`) brings it to `maxStacks`, in the name of who put it on: Gravity\n\t * Field's stun on the third, Hemorrhage's might on the fifth. A `removeBuff` among them spends the stacks\n\t *\n\t * @beta\n\t */\n\tonMaxStacks?: EffectDef[]\n}\n\n/**\n * The orders a buff gives its carrier (`BuffDef.control`): away from who put it on, to them, or at them\n *\n * @beta\n */\nexport type ControlKind = 'fear' | 'charm' | 'taunt'\n\n/**\n * A buff's own control (`BuffDef.control` in code): run every tick it holds its carrier, in place of the orders it\n * waits on, to steer it as it likes (with `moveTo`, `engage` and the like). `source` is who put it on, while it is there\n *\n * @beta\n */\nexport type BuffControl = (world: World, carrier: Entity, instance: BuffInstance, dt: number, source: Entity | undefined) => void\n\n/**\n * What takes a buff off before its time (`BuffDef.breaksOn`): its carrier hurt, an attack of its landing, a cast of its\n *\n * @beta\n */\nexport type BuffBreak = 'damage' | 'attack' | 'cast'\n\n/** Whether a buff does what it says (stuns, roots) to one carrier, at this moment */\nexport type BuffCheck = (world: World, carrier: Entity, instance: BuffInstance) => boolean\n\n/** Code a buff runs on its carrier: as it is put on, or every so often */\nexport type BuffHandler = (world: World, carrier: Entity, instance: BuffInstance) => void\n\n/** A buff about to be put on, as a `stacking` function sees it */\nexport interface IncomingBuff {\n\tlevel: number\n\t/** Seconds */\n\tduration: number\n\t/** Who puts it on, by id: 0 for nobody */\n\tsource: number\n}\n\n/**\n * Where an item is in a shop, and in its build tree: what is used up (`consumable`), what a hero starts with\n * (`starter`), the parts (`basic`), what they build (`intermediate`), what it all leads to (`legendary`), and what is\n * found, never sold (`relic`: loot of camps, bosses and quests). The client's tiers, or a game's own\n * (`GameView.hud.shopTiers`). `epic` is the old word for `intermediate`, still read as it (`itemTier`)\n *\n * @beta\n */\nexport type ItemTier = 'consumable' | 'starter' | 'basic' | 'intermediate' | 'legendary' | 'relic' | 'epic' | (string & {})\n\n/**\n * How an item's charges come back (`ItemDef.refill`): all of them at a shop of the carrier's side or an ally's\n * (`shop`), and one every `every` seconds. An item that refills is kept at no charges, waiting for them\n *\n * @beta\n */\nexport interface ItemRefill {\n\t/** Every charge back while its carrier stands at a shop it may trade with */\n\tshop?: boolean\n\t/** Seconds for one charge to come back, wherever it is carried. None when left out */\n\tevery?: number\n}\n\n/**\n * A tag of items (`ItemDef.tags`), named and given a look: what a shop shows of it and whether it is one of the shop's\n * filters. A tag no `TagDef` names still works, shown as its own word (`Rules.tags`)\n *\n * @beta\n */\nexport interface TagDef {\n\t/** The tag as items say it: `attack`, `lifesteal`, `anti-heal` */\n\tid: string\n\t/** What the player sees it called: its id when left out */\n\tname?: string\n\t/** A line about it, shown when the pointer is over it */\n\tdescription?: string\n\t/** An icon of its own, by path or by a name of the game's icons */\n\ticon?: string\n\t/** The colour it is shown in, as CSS has it (`#e0a030`) */\n\tcolor?: string\n\t/** One of the shop's filters, a chip to pick: not when left out */\n\tfilter?: boolean\n}\n\n/**\n * The definition of an item: what it costs, what it gives its carrier and how it is used\n *\n * @public\n */\nexport interface ItemDef {\n\t/** The item's id, shared by every game: give it a prefix of the game's */\n\tid: string\n\t/** What the player sees the item called */\n\tname: string\n\t/** How good it is, 1 and up (campaign plan GP3): what an item table draws by (`{ level: 3 }`) */\n\tlevel?: number\n\t/** Its kind of item, a word of the game's (`permanent`, `charged`, `powerup`): what an item table draws by too */\n\tclass?: string\n\t/**\n\t * The definition this one is a copy of, made from the data (`copyOf` in a `data.json`, the editor's Copy as new):\n\t * what it is drawn, heard and pictured as where the game gives it no look of its own\n\t */\n\tbasedOn?: string\n\t/** What the item does, in words, shown when the pointer is over it */\n\tdescription?: string\n\t/** What it costs in a shop, in resources */\n\tcost: Cost\n\t/** Uses before it is gone. Items without charges stay */\n\tcharges?: number\n\t/** Id of the ability the item gives: using the item casts it, without mana */\n\tability?: string\n\t/** Id of an ability whose passive part works for whoever carries the item */\n\tpassive?: string\n\t/** Items it is made of. Those the buyer carries are used up and taken off the price, which is for all of it */\n\tfrom?: string[]\n\t/**\n\t * Where it goes in a shop: consumable, starter, basic, intermediate, legendary, relic (`ItemTier`). `epic`, the old\n\t * word, is read as intermediate\n\t */\n\ttier?: ItemTier\n\t/**\n\t * The name of its passive (or the passive of items that share it): two carried, of it or of items sharing the name,\n\t * work once (the first carried). Its stats (`bonus`) always count. Every passive works when left out\n\t *\n\t * @beta\n\t */\n\tunique?: string\n\t/**\n\t * A group of items a hero carries only so many of (`boots`): `groupLimit`, or the game's limit of the group\n\t * (`ItemSettings.groups`), 1 when neither says. Buying, picking up or being handed one more is refused, saying why\n\t *\n\t * @beta\n\t */\n\tgroup?: string\n\t/** How many of its `group` one carrier may have: the game's limit of the group, or 1, when left out @beta */\n\tgroupLimit?: number\n\t/**\n\t * How many of it go in one slot: another bought, picked up or handed over goes into the slot of one carried, its\n\t * charges added, up to so many of it (a stack of potions). One a slot when left out\n\t *\n\t * @beta\n\t */\n\tstack?: number\n\t/** How its charges come back (`ItemRefill`): at a shop, over time. Used up for good when left out @beta */\n\trefill?: ItemRefill\n\t/** The part of its price a shop gives back for it, over the game's (`EconomySettings.sellPrice`) @beta */\n\tsellRate?: number\n\t/**\n\t * Free words of the game's for what it is (`attack`, `lifesteal`, `anti-heal`, `early`): its categories, what a\n\t * search finds it by (`#lifesteal`), what a shop filters by. A `TagDef` gives one a name and a look (`Rules.tags`)\n\t *\n\t * @beta\n\t */\n\ttags?: string[]\n\t/**\n\t * The callings of heroes it is meant for (`vanguard`, `ranger`…): what a shop suggests and filters by. Never a lock:\n\t * any hero may buy it\n\t *\n\t * @beta\n\t */\n\tsuits?: string[]\n\t/** Applies for as long as the item is carried */\n\tbonus?: StatChange\n\t/** How many a shop has at most, and the seconds it takes to get one back. As many as anyone wants when left out */\n\tstock?: { max: number; restock: number }\n\t/** The key that uses it from the command card */\n\thotkey?: string\n\t/**\n\t * Used as it is picked up, by walking over it or by the order, and never carried: a rune, a tome. Its ability is cast by\n\t * whoever picked it. In a game with the runes pack (`runesPack`, whose `powerUp` says it in code)\n\t */\n\tpowerUp?: boolean\n}\n\n/**\n * A big army is paid for with income: past a certain supply, less arrives of what workers gather of the resources with `upkeep`\n *\n * @beta\n */\nexport interface UpkeepTier {\n\t/** Applies when the player uses more supply than this */\n\tabove: number\n\t/** What the player sees the tier called */\n\tname: string\n\t/** Part of what is gathered that still arrives, 0..1 */\n\tincome: number\n}\n\n/**\n * What a level of research changes\n *\n * @beta\n */\nexport interface UpgradeEffect extends StatChange {\n\t/** Unit types that benefit, or a function of the type. Everything the player owns when left out */\n\tunits?: string[] | ((def: UnitTypeDef) => boolean)\n}\n\n/**\n * Research that improves a player's units for the rest of the game\n *\n * @public\n */\nexport interface UpgradeDef {\n\t/** The upgrade's id, shared by every game: give it a prefix of the game's */\n\tid: string\n\t/** What the player sees the upgrade called */\n\tname: string\n\t/**\n\t * The definition this one is a copy of, made from the data (`copyOf` in a `data.json`, the editor's Copy as new):\n\t * what it is drawn, heard and pictured as where the game gives it no look of its own\n\t */\n\tbasedOn?: string\n\t/** What the upgrade does, in words, shown when the pointer is over it */\n\tdescription?: string\n\t/** Paid for every level */\n\tcost: Cost\n\t/** Seconds per level */\n\tresearchTime: number\n\t/** The highest level that can be researched; 1 when left out */\n\tmaxLevel?: number\n\t/** Building types needed, one list per level. Levels past the end of the list need nothing */\n\trequires?: string[][]\n\t/** The race it is of (`Rules.races`): only its players may research it. Everyone's when left out */\n\trace?: string\n\t/** The key that researches it from the command card */\n\thotkey?: string\n\t/** What each level changes in the stats of the units it applies to */\n\teffects: UpgradeEffect[]\n\t/**\n\t * What it does besides stats, in code, to each unit of the player's: as a level is researched (to the units there\n\t * are), and as a unit comes into the world while the player has it. Gives an ability, lets a unit hit what flies.\n\t * Run again for every level: what it does is up to it to not do twice\n\t */\n\tapply?: (world: World, entity: Entity, level: number) => void\n}\n\n/**\n * The types a building can be upgraded into (`UnitTypeDef.upgradesTo`), as a list: one for most, none for one that\n * turns into nothing\n *\n * @beta\n */\nexport const upgradesOf = (def: Pick<UnitTypeDef, 'upgradesTo'>): readonly string[] =>\n\tdef.upgradesTo === undefined ? [] : typeof def.upgradesTo === 'string' ? [def.upgradesTo] : def.upgradesTo\n\n/**\n * Gives the footprint of a unit type: its own, or a square the width of its collision diameter, rounded up\n *\n * @beta\n */\nexport const footprintOf = (def: UnitTypeDef) => def.footprint ?? { w: Math.ceil(def.radius * 2), d: Math.ceil(def.radius * 2) }\n\n/**\n * Whether things of this type only stand there, like trees and gold mines: they never move, act or change by\n * themselves, so the systems that run every tick have nothing to do for them. A map can have thousands of\n * them and they cost nothing per tick. Only things that belong to nobody (the neutral player) are treated\n * as scenery, see `World.spawn`: a player's building counts for supply, sight and victory.\n *\n * @internal\n */\nexport function isScenery(def: UnitTypeDef): boolean {\n\treturn (\n\t\tdef.kind !== 'unit' &&\n\t\t!def.attacks?.length &&\n\t\t!def.hero &&\n\t\t!def.abilities?.length &&\n\t\t!def.inventory &&\n\t\t!def.sells?.length &&\n\t\t!def.trains?.length &&\n\t\t!def.researches?.length &&\n\t\t!upgradesOf(def).length &&\n\t\tdef.lifetime === undefined &&\n\t\t!def.invisible &&\n\t\tdef.recovers === undefined &&\n\t\t!def.stats.healthRegen &&\n\t\t!def.stats.manaRegen\n\t)\n}\n\n/** The one pool of supply there always is, in a supply said by pool (`UnitTypeDef.supply`) @beta */\nexport const MAIN_SUPPLY = 'supply'\n\n/** What a type takes of the one pool of supply there always is (`UnitTypeDef.supply`, a number or its `supply`) @beta */\nexport function supplyOf(def: Pick<UnitTypeDef, 'supply'>): number {\n\tconst { supply } = def\n\treturn typeof supply === 'number' ? supply : (supply?.[MAIN_SUPPLY] ?? 0)\n}\n\n/** What a type takes of the game's own pools of supply, by name (`UnitTypeDef.supply` said by pool, the one pool left out) @beta */\nexport function supplyPoolsOf(def: Pick<UnitTypeDef, 'supply'>): Record<string, number> {\n\treturn poolsIn(def.supply)\n}\n\n/** What a finished building of a type provides of the one pool of supply (`UnitTypeDef.supplyGiven`) @beta */\nexport function supplyGivenOf(def: Pick<UnitTypeDef, 'supplyGiven'>): number {\n\tconst { supplyGiven } = def\n\treturn typeof supplyGiven === 'number' ? supplyGiven : (supplyGiven?.[MAIN_SUPPLY] ?? 0)\n}\n\n/** What a finished building of a type provides of the game's own pools, by name (`UnitTypeDef.supplyGiven` said by pool) @beta */\nexport function supplyPoolsGivenOf(def: Pick<UnitTypeDef, 'supplyGiven'>): Record<string, number> {\n\treturn poolsIn(def.supplyGiven)\n}\n\nfunction poolsIn(said: number | Record<string, number> | undefined): Record<string, number> {\n\tif (!said || typeof said === 'number') return {}\n\tconst out: Record<string, number> = {}\n\tfor (const name in said) if (name !== MAIN_SUPPLY) out[name] = said[name]\n\treturn out\n}\n\n/**\n * What base stats are worked out under: the rules of a game, and what its own stats start at. A `Registry` is one\n *\n * @beta\n */\nexport interface StatSource {\n\t/** The rules of the game the stats are worked out under, as `RuleSettings` */\n\treadonly settings: Readonly<RuleSettings>\n\t/** Every stat of the game at 0, its own at their default */\n\treadonly statDefaults: Readonly<Stats>\n}\n\n/** Base stats worked out before, by the game they were worked out for (a unit type may be in more than one game) */\nconst cache = new WeakMap<StatSource, { days: WeakMap<UnitTypeDef, Readonly<Stats>>; nights: WeakMap<UnitTypeDef, Readonly<Stats>> }>()\n\n/**\n * The stats a unit type starts with, all of them, in a game: `world.registry`, or `session.registry` on a player's\n * screen. By day unless it says otherwise\n *\n * @beta\n */\nexport function baseStats(def: UnitTypeDef, game: StatSource, night = false): Readonly<Stats> {\n\tconst { settings: rules } = game\n\tlet cached = cache.get(game)\n\tif (!cached) cache.set(game, (cached = { days: new WeakMap(), nights: new WeakMap() }))\n\tconst bases = night ? cached.nights : cached.days\n\tlet stats = bases.get(def)\n\tif (!stats) {\n\t\tconst sight = night ? (def.sightNight ?? Math.round(def.sight * rules.fog.nightSight)) : def.sight\n\t\tstats = Object.freeze({ ...game.statDefaults, sight, ...def.stats, ...(def.uses ? { health: def.uses } : undefined) }) as Readonly<Stats>\n\t\tbases.set(def, stats)\n\t}\n\treturn stats\n}\n\n/**\n * The ground an ability covers at a level: a line for what it sends on its way, a circle for what hits an area.\n * Undefined for abilities that are about one unit, or about nothing in particular.\n *\n * @beta\n */\nexport function aimOf(ability: AbilityDef, level: number): AimShape | undefined {\n\tconst { aim } = ability\n\tif (aim) {\n\t\tif (aim.shape === 'circle') return { shape: 'circle', radius: at(aim.radius, level) }\n\t\tif (aim.shape === 'cone') return { shape: 'cone', length: at(aim.length, level), angle: aim.angle }\n\t\tif (aim.shape === 'ring') return { shape: 'ring', radius: at(aim.radius, level), width: at(aim.width, level) }\n\t\tif (aim.shape === 'arc') return { shape: 'arc', radius: at(aim.radius, level), angle: aim.angle, width: at(aim.width, level) }\n\t\treturn { shape: aim.shape, length: at(aim.length, level), width: at(aim.width, level) }\n\t}\n\tconst missile = ability.effects.find((effect) => effect.type === 'missile')\n\tif (missile) return { shape: 'line', length: at(missile.distance, level, 10), width: declaredAt(missile.radius, level, 1) }\n\t// the first effect with a shape, or one a zone or a delay of it holds (AB10): what it covers is what is aimed\n\tconst shapedAim = shapeAim(ability.effects, level)\n\tif (shapedAim) return shapedAim\n\tlet radius = 0\n\tfor (const effect of lowerChain(ability.effects)) if (effect.type !== 'aura') radius = Math.max(radius, declaredAt(effect.radius, level))\n\treturn radius > 0 ? { shape: 'circle', radius } : undefined\n}\n\n/** The ground of the first effect with a shape other than a circle, of a list or of a zone or delay in it, as an aim */\nfunction shapeAim(effects: readonly EffectDef[] | undefined, level: number): AimShape | undefined {\n\tfor (const each of lowerChain(effects ?? [])) {\n\t\tconst effect = anyEffect(each)\n\t\tconst { shape } = effect\n\t\tconst size = (value: EffectValue | undefined, fallback = 0) => declaredAt(value, level, fallback)\n\t\tconst width = size(effect.width, 1)\n\t\tswitch (shape) {\n\t\t\tcase 'cone':\n\t\t\t\treturn { shape, length: size(effect.length), angle: size(effect.angle) }\n\t\t\tcase 'line':\n\t\t\tcase 'rect':\n\t\t\tcase 'cross':\n\t\t\t\treturn { shape, length: size(effect.length), width }\n\t\t\tcase 'ring':\n\t\t\t\treturn { shape, radius: size(effect.radius), width }\n\t\t\tcase 'arc':\n\t\t\t\treturn { shape, radius: size(effect.radius), angle: size(effect.angle), width }\n\t\t}\n\t\tif (effect.type === 'zone' || effect.type === 'after') {\n\t\t\tconst inner = shapeAim(effect.effects, level)\n\t\t\tif (inner) return inner\n\t\t}\n\t}\n\treturn undefined\n}\n"],"mappings":";;;;;;AAqDA,SAAgB,GAAG,OAA2B,OAAe,WAAW,GAAW;CAClF,IAAI,UAAU,KAAA,GAAW,OAAO;CAChC,IAAI,OAAO,UAAU,UAAU,OAAO;CACtC,OAAO,MAAM,KAAK,IAAI,KAAK,IAAI,OAAO,CAAC,GAAG,MAAM,MAAM,IAAI,MAAM;AACjE;;;;;;;AAQA,SAAgB,WAAW,OAAgC,OAAe,WAAW,GAAW;CAC/F,OAAO,OAAO,UAAU,aAAa,WAAW,GAAG,OAAO,OAAO,QAAQ;AAC1E;;;;;;AA4GA,IAAa,iBAAgC;CAC5C;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACD;;;;;;AAOA,IAAa,iBAA4B;CACxC,cAAc;CACd,aAAa;CACb,aAAa;CACb,QAAQ;CACR,OAAO;CACP,aAAa;CACb,gBAAgB;CAChB,wBAAwB;CACxB,qBAAqB;CACrB,oBAAoB;CACpB,gBAAgB;CAChB,iBAAiB;CACjB,aAAa;CACb,MAAM;CACN,WAAW;CACX,WAAW;CACX,OAAO;AACR;;;;;;AAuBA,SAAgB,OAAO,KAAsB,SAAyB;CACrE,IAAI,CAAC,KAAK,OAAO;CACjB,QAAQ,IAAI,QAAS,UAAU,IAAI,SAAU,MAAM;AACpD;;;;;;AAOA,IAAa,WAAW,KAAsB,SAA0B,CAAC,CAAC,QAAQ,OAAO,IAAI,QAAQ,QAAQ,IAAI;;;;;;;AA+SjH,SAAgB,eAAe,KAAyF;CACvH,OAAO,IAAI,iBAAiB,IAAI,eAAe,SAAS;AACzD;;;;;;;AAirBA,IAAa,iBAA4H;CACxI,KAAK;EAAE,OAAO,CAAC,SAAS;EAAG,MAAM;CAAU;CAC3C,SAAS;EAAE,OAAO,CAAC,MAAM;EAAG,MAAM;CAAU;CAC5C,QAAQ;EAAE,OAAO,CAAC,MAAM;EAAG,MAAM;CAAU;CAC3C,KAAK;EAAE,OAAO,CAAC,WAAW,MAAM;EAAG,MAAM;CAAQ;AAClD;;;;;;AAwzBA,IAAa,aAAa,WAAiC;;;;;;;AAQ3D,SAAgB,aAAa,QAAgC;CAC5D,MAAM,EAAE,SAAS,WAAW,UAAU,UAAU,MAAM;CACtD,OAAO;EAAC,GAAI,WAAW,CAAC;EAAI,GAAI,aAAa,CAAC;EAAI,GAAI,SAAS,CAAC;CAAE;AACnE;;AAWA,IAAM,8BAAc,IAAI,QAA8B;;AAEtD,IAAM,+BAAe,IAAI,QAAyC;;;;;;AAOlE,IAAa,iBAAiB,SAAsD,aAAa,IAAI,IAAI;;;;;;;AAQzG,IAAa,iBAAiB,WAAiC,YAAY,IAAI,MAAM,KAAK;;;;;;;;;;AAW1F,SAAgB,WAAW,SAA+B,QAAkE;CAC3H,IAAI,CAAC,QAAQ,MAAM,WAAW,OAAO,IAAI,GAAG,OAAO;CACnD,MAAM,MAAmB,CAAC;CAC1B,MAAM,OAAoB,CAAC;CAC3B,QAAQ,SAAS,QAAQ,UAAU;EAClC,MAAM,OAAkB;GAAE;GAAQ,SAAS;EAAO;EAClD,IAAI,CAAC,OAAO,MAAM;GACjB,IAAI,KAAK,IAAI;GACb,KAAK,KAAK,IAAI;GACd;EACD;EACA,MAAM,SAAS,OAAO,OAAO,gBAAgB,OAAO,IAAI,IAAI,eAAe,OAAO,QAAQ,KAAA;EAC1F,IAAI;EACJ,KAAK,IAAI,IAAI,KAAK,SAAS,GAAG,KAAK,KAAK,UAAU,CAAC,IAAI,KAAK,IAAI,OAAO,MAAM,SAAS,KAAK,EAAE,CAAC,OAAO,IAAI,GAAG,KAAK,KAAK;EACtH,IAAI,CAAC,MAAM,CAAC,QAAQ;GACnB,SAAS,OAAO,MAAM;GACtB;EACD;EACA,MAAM,EAAE,MAAM,GAAG,GAAG,QAAQ;EAC5B,KAAK,SAAS;EACd,GAAG,YAAY,CAAC;EACf,CAAC,GAAG,QAAQ,OAAO,UAAU,CAAC,EAAA,CAAG,KAAK,IAAI;EAC3C,KAAK,KAAK,IAAI;CACf,CAAC;CACD,MAAM,QAAQ,SAA+B;EAC5C,IAAI,KAAK,WAAW,KAAK,SAAS,YAAY,IAAI,KAAK,QAAQ,KAAK,OAAO;EAC3E,IAAI,CAAC,KAAK,SAAS,OAAO,KAAK;EAC/B,MAAM,OAAO,EAAE,GAAG,UAAU,KAAK,MAAM,EAAE;EACzC,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,KAAK,OAAO,GACtD,KAAK,QAAQ,CAAC,GAAI,KAAK,SAAS,CAAC,GAAI,GAAG,MAAM,IAAI,IAAI,CAAC;EACxD,YAAY,IAAI,MAAmB,KAAK,OAAO;EAC/C,KAAK,MAAM,QAAQ,OAAO,KAAK,KAAK,OAAO,GAA8B,aAAa,IAAI,KAAK,OAAQ,KAAK,OAAO;EACnH,OAAO;CACR;CACA,OAAO,IAAI,IAAI,IAAI;AACpB;;;;;;AAwQA,IAAa,kBAAkB,YAAsC,QAAQ,WAAW,YAAY,QAAQ,UAAW,QAAQ,WAAW,CAAC;;;;;;;AAwe3I,IAAa,cAAc,QAC1B,IAAI,eAAe,KAAA,IAAY,CAAC,IAAI,OAAO,IAAI,eAAe,WAAW,CAAC,IAAI,UAAU,IAAI,IAAI;;;;;;AAOjG,IAAa,eAAe,QAAqB,IAAI,aAAa;CAAE,GAAG,KAAK,KAAK,IAAI,SAAS,CAAC;CAAG,GAAG,KAAK,KAAK,IAAI,SAAS,CAAC;AAAE;;;;;;;;;AAU/H,SAAgB,UAAU,KAA2B;CACpD,OACC,IAAI,SAAS,UACb,CAAC,IAAI,SAAS,UACd,CAAC,IAAI,QACL,CAAC,IAAI,WAAW,UAChB,CAAC,IAAI,aACL,CAAC,IAAI,OAAO,UACZ,CAAC,IAAI,QAAQ,UACb,CAAC,IAAI,YAAY,UACjB,CAAC,WAAW,GAAG,CAAC,CAAC,UACjB,IAAI,aAAa,KAAA,KACjB,CAAC,IAAI,aACL,IAAI,aAAa,KAAA,KACjB,CAAC,IAAI,MAAM,eACX,CAAC,IAAI,MAAM;AAEb;;AAGA,IAAa,cAAc;;AAG3B,SAAgB,SAAS,KAA0C;CAClE,MAAM,EAAE,WAAW;CACnB,OAAO,OAAO,WAAW,WAAW,SAAU,SAAA,aAAyB;AACxE;;AAGA,SAAgB,cAAc,KAA0D;CACvF,OAAO,QAAQ,IAAI,MAAM;AAC1B;;AAGA,SAAgB,cAAc,KAA+C;CAC5E,MAAM,EAAE,gBAAgB;CACxB,OAAO,OAAO,gBAAgB,WAAW,cAAe,cAAA,aAA8B;AACvF;;AAGA,SAAgB,mBAAmB,KAA+D;CACjG,OAAO,QAAQ,IAAI,WAAW;AAC/B;AAEA,SAAS,QAAQ,MAA2E;CAC3F,IAAI,CAAC,QAAQ,OAAO,SAAS,UAAU,OAAO,CAAC;CAC/C,MAAM,MAA8B,CAAC;CACrC,KAAK,MAAM,QAAQ,MAAM,IAAI,SAAA,UAAsB,IAAI,QAAQ,KAAK;CACpE,OAAO;AACR;;AAeA,IAAM,wBAAQ,IAAI,QAAoH;;;;;;;AAQtI,SAAgB,UAAU,KAAkB,MAAkB,QAAQ,OAAwB;CAC7F,MAAM,EAAE,UAAU,UAAU;CAC5B,IAAI,SAAS,MAAM,IAAI,IAAI;CAC3B,IAAI,CAAC,QAAQ,MAAM,IAAI,MAAO,SAAS;EAAE,sBAAM,IAAI,QAAQ;EAAG,wBAAQ,IAAI,QAAQ;CAAE,CAAE;CACtF,MAAM,QAAQ,QAAQ,OAAO,SAAS,OAAO;CAC7C,IAAI,QAAQ,MAAM,IAAI,GAAG;CACzB,IAAI,CAAC,OAAO;EACX,MAAM,QAAQ,QAAS,IAAI,cAAc,KAAK,MAAM,IAAI,QAAQ,MAAM,IAAI,UAAU,IAAK,IAAI;EAC7F,QAAQ,OAAO,OAAO;GAAE,GAAG,KAAK;GAAc;GAAO,GAAG,IAAI;GAAO,GAAI,IAAI,OAAO,EAAE,QAAQ,IAAI,KAAK,IAAI,KAAA;EAAW,CAAC;EACrH,MAAM,IAAI,KAAK,KAAK;CACrB;CACA,OAAO;AACR;;;;;;;AAQA,SAAgB,MAAM,SAAqB,OAAqC;CAC/E,MAAM,EAAE,QAAQ;CAChB,IAAI,KAAK;EACR,IAAI,IAAI,UAAU,UAAU,OAAO;GAAE,OAAO;GAAU,QAAQ,GAAG,IAAI,QAAQ,KAAK;EAAE;EACpF,IAAI,IAAI,UAAU,QAAQ,OAAO;GAAE,OAAO;GAAQ,QAAQ,GAAG,IAAI,QAAQ,KAAK;GAAG,OAAO,IAAI;EAAM;EAClG,IAAI,IAAI,UAAU,QAAQ,OAAO;GAAE,OAAO;GAAQ,QAAQ,GAAG,IAAI,QAAQ,KAAK;GAAG,OAAO,GAAG,IAAI,OAAO,KAAK;EAAE;EAC7G,IAAI,IAAI,UAAU,OAAO,OAAO;GAAE,OAAO;GAAO,QAAQ,GAAG,IAAI,QAAQ,KAAK;GAAG,OAAO,IAAI;GAAO,OAAO,GAAG,IAAI,OAAO,KAAK;EAAE;EAC7H,OAAO;GAAE,OAAO,IAAI;GAAO,QAAQ,GAAG,IAAI,QAAQ,KAAK;GAAG,OAAO,GAAG,IAAI,OAAO,KAAK;EAAE;CACvF;CACA,MAAM,UAAU,QAAQ,QAAQ,MAAM,WAAW,OAAO,SAAS,SAAS;CAC1E,IAAI,SAAS,OAAO;EAAE,OAAO;EAAQ,QAAQ,GAAG,QAAQ,UAAU,OAAO,EAAE;EAAG,OAAO,WAAW,QAAQ,QAAQ,OAAO,CAAC;CAAE;CAE1H,MAAM,YAAY,SAAS,QAAQ,SAAS,KAAK;CACjD,IAAI,WAAW,OAAO;CACtB,IAAI,SAAS;CACb,KAAK,MAAM,UAAU,WAAW,QAAQ,OAAO,GAAG,IAAI,OAAO,SAAS,QAAQ,SAAS,KAAK,IAAI,QAAQ,WAAW,OAAO,QAAQ,KAAK,CAAC;CACxI,OAAO,SAAS,IAAI;EAAE,OAAO;EAAU;CAAO,IAAI,KAAA;AACnD;;AAGA,SAAS,SAAS,SAA2C,OAAqC;CACjG,KAAK,MAAM,QAAQ,WAAW,WAAW,CAAC,CAAC,GAAG;EAC7C,MAAM,SAAS,UAAU,IAAI;EAC7B,MAAM,EAAE,UAAU;EAClB,MAAM,QAAQ,OAAgC,WAAW,MAAM,WAAW,OAAO,OAAO,QAAQ;EAChG,MAAM,QAAQ,KAAK,OAAO,OAAO,CAAC;EAClC,QAAQ,OAAR;GACC,KAAK,QACJ,OAAO;IAAE;IAAO,QAAQ,KAAK,OAAO,MAAM;IAAG,OAAO,KAAK,OAAO,KAAK;GAAE;GACxE,KAAK;GACL,KAAK;GACL,KAAK,SACJ,OAAO;IAAE;IAAO,QAAQ,KAAK,OAAO,MAAM;IAAG;GAAM;GACpD,KAAK,QACJ,OAAO;IAAE;IAAO,QAAQ,KAAK,OAAO,MAAM;IAAG;GAAM;GACpD,KAAK,OACJ,OAAO;IAAE;IAAO,QAAQ,KAAK,OAAO,MAAM;IAAG,OAAO,KAAK,OAAO,KAAK;IAAG;GAAM;EAChF;EACA,IAAI,OAAO,SAAS,UAAU,OAAO,SAAS,SAAS;GACtD,MAAM,QAAQ,SAAS,OAAO,SAAS,KAAK;GAC5C,IAAI,OAAO,OAAO;EACnB;CACD;AAED"}
package/dist/denying.d.ts CHANGED
@@ -5,7 +5,7 @@ import type { World } from './world';
5
5
  /**
6
6
  * Denying, as in a MOBA (features-plan E): a player may tell their units to attack one of their own side's, which
7
7
  * they never do by themselves, once it is low enough on health that the other side would soon have it: the last hit
8
- * on it is theirs, not the enemy's. Hooks for `GameModule.hooks`:
8
+ * on it is theirs, not the enemy's. Hooks for `Rules.hooks`:
9
9
  *
10
10
  * hooks: [...denying({ below: 0.5 })]
11
11
  *
@@ -37,7 +37,7 @@ export declare function mayDeny(world: World, attacker: Entity, target: Entity,
37
37
  */
38
38
  export declare function denying(options?: DenyOptions): HookDef[];
39
39
  /**
40
- * What a game counts of last hits and denies (`withLastHits`)
40
+ * What a game counts of last hits and denies (`lastHitsPack`)
41
41
  *
42
42
  * @beta
43
43
  */
@@ -62,7 +62,7 @@ export declare const counted: import("./components").Component<Record<string, {
62
62
  }>>;
63
63
  /**
64
64
  * A player's last hits (enemy units they gave the killing blow to) and denies (their own side's), as counted
65
- * (`withLastHits`)
65
+ * (`lastHitsPack`)
66
66
  *
67
67
  * @beta
68
68
  */
@@ -78,4 +78,4 @@ export declare function lastHitsOf(world: World, player: PlayerId): {
78
78
  *
79
79
  * @beta
80
80
  */
81
- export declare function withLastHits(options?: LastHitOptions): GamePack;
81
+ export declare function lastHitsPack(options?: LastHitOptions): GamePack;
@@ -0,0 +1,106 @@
1
+ import { distSq } from "./math.js";
2
+ import { defineComponent } from "./components.js";
3
+ import { grantXp, heroOf, heroState, maxLevelOf, xpWorth } from "./hero.js";
4
+ import { defineHook } from "./hooks.js";
5
+ import { attackReaches } from "./systems/combat.js";
6
+ //#region src/denying.ts
7
+ /** Units, not heroes nor structures: what the engine lets be denied */
8
+ var units = (_world, _attacker, target) => target.isUnit && !target.def.hero;
9
+ /**
10
+ * Whether an attack on one's own side is a deny the rules allow (`DenyOptions`): told to, low enough, of what may be
11
+ *
12
+ * @beta
13
+ */
14
+ function mayDeny(world, attacker, target, options = {}) {
15
+ if (world.areEnemies(attacker.owner, target.owner)) return false;
16
+ if (target.health >= target.maxHealth * (options.below ?? .5)) return false;
17
+ return attackReaches(world, attacker, target) && (options.denies ?? units)(world, attacker, target);
18
+ }
19
+ /**
20
+ * The hooks of denying (see `DenyOptions`)
21
+ *
22
+ * @beta
23
+ */
24
+ function denying(options = {}) {
25
+ return [defineHook({
26
+ hook: "canAttack",
27
+ id: options.id ?? "deny",
28
+ run(world, event) {
29
+ if (!event.cancelled || !event.ordered) return;
30
+ if (mayDeny(world, event.attacker, event.target, options)) event.cancelled = false;
31
+ }
32
+ })];
33
+ }
34
+ /** Every player's last hits and denies, by player id: saved with the game */
35
+ var counted = defineComponent({
36
+ id: "lastHits",
37
+ default: () => ({})
38
+ });
39
+ /**
40
+ * A player's last hits (enemy units they gave the killing blow to) and denies (their own side's), as counted
41
+ * (`lastHitsPack`)
42
+ *
43
+ * @beta
44
+ */
45
+ function lastHitsOf(world, player) {
46
+ return world.state(counted)[player] ?? {
47
+ lastHits: 0,
48
+ denies: 0
49
+ };
50
+ }
51
+ /** What the engine counts: units, not heroes nor structures */
52
+ var countsUnits = (_world, dead) => dead.isUnit && !dead.def.hero;
53
+ /**
54
+ * A game where last hits and denies count, as in a MOBA: each player's are counted (`lastHitsOf`, saved), a unit
55
+ * denied gives no bounty (as one killed by its own side never does) and only a part of its experience to the enemy
56
+ * heroes near it, and its death says so to the screen (`how: 'denied'`, which the client shows over it). With the rule
57
+ * of denying (`denying`) unless told otherwise
58
+ *
59
+ * @beta
60
+ */
61
+ function lastHitsPack(options = {}) {
62
+ const counts = options.counts ?? countsUnits;
63
+ const part = options.experience ?? .5;
64
+ const count = defineHook({
65
+ hook: "death",
66
+ id: "lastHits",
67
+ run(world, event) {
68
+ const { entity, killer } = event;
69
+ if (!killer || killer === entity || !counts(world, entity)) return;
70
+ const all = world.state(counted);
71
+ const player = killer.owner;
72
+ const mine = all[player] ??= {
73
+ lastHits: 0,
74
+ denies: 0
75
+ };
76
+ if (world.areEnemies(player, entity.owner)) {
77
+ mine.lastHits++;
78
+ return;
79
+ }
80
+ if (!world.areAllies(player, entity.owner)) return;
81
+ mine.denies++;
82
+ event.how ??= "denied";
83
+ const worth = xpWorth(world, entity) * part;
84
+ if (worth <= 0) return;
85
+ const range = world.settings.heroes.xpRange;
86
+ const heroes = [];
87
+ for (const hero of world.index.with(heroState)) {
88
+ const state = heroOf(hero);
89
+ if (!state || !hero.alive || !world.areEnemies(hero.owner, entity.owner)) continue;
90
+ if (state.level >= maxLevelOf(world, hero)) continue;
91
+ if (distSq(hero.pos, entity.pos) <= range * range) heroes.push(hero);
92
+ }
93
+ for (const hero of heroes) grantXp(world, hero, worth / heroes.length, entity);
94
+ }
95
+ });
96
+ return {
97
+ id: "lastHits",
98
+ options,
99
+ components: [counted],
100
+ hooks: [...options.deny === false ? [] : denying(options.deny), count]
101
+ };
102
+ }
103
+ //#endregion
104
+ export { counted, denying, lastHitsOf, lastHitsPack, mayDeny };
105
+
106
+ //# sourceMappingURL=denying.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"denying.js","names":[],"sources":["../src/denying.ts"],"sourcesContent":["import { defineComponent } from './components'\nimport type { GamePack } from './packs/pack'\nimport { distSq } from './math'\nimport type { Entity, PlayerId } from './entity'\nimport { grantXp, heroOf, heroState, maxLevelOf, xpWorth } from './hero'\nimport { defineHook, type HookDef } from './hooks'\nimport { attackReaches } from './systems/combat'\nimport type { World } from './world'\n\n/**\n * Denying, as in a MOBA (features-plan E): a player may tell their units to attack one of their own side's, which\n * they never do by themselves, once it is low enough on health that the other side would soon have it: the last hit\n * on it is theirs, not the enemy's. Hooks for `Rules.hooks`:\n *\n * hooks: [...denying({ below: 0.5 })]\n *\n * Only an attack a player orders (`CanAttack.ordered`): units never pick their own side to attack, nor fight back at it\n *\n * @beta\n */\nexport interface DenyOptions {\n\t/** How low on health, of its most, one of one's own side has to be to be attacked: below half when left out */\n\tbelow?: number\n\t/**\n\t * What of one's own side may be attacked, past `below`: units, not heroes nor structures, when left out. A game's own,\n\t * to let towers be denied, or only creeps\n\t */\n\tdenies?: (world: World, attacker: Entity, target: Entity) => boolean\n\t/** The id of the hook, to replace or leave out: `deny` when left out */\n\tid?: string\n}\n\n/** Units, not heroes nor structures: what the engine lets be denied */\nconst units = (_world: World, _attacker: Entity, target: Entity) => target.isUnit && !target.def.hero\n\n/**\n * Whether an attack on one's own side is a deny the rules allow (`DenyOptions`): told to, low enough, of what may be\n *\n * @beta\n */\nexport function mayDeny(world: World, attacker: Entity, target: Entity, options: DenyOptions = {}): boolean {\n\tif (world.areEnemies(attacker.owner, target.owner)) return false\n\tif (target.health >= target.maxHealth * (options.below ?? 0.5)) return false\n\treturn attackReaches(world, attacker, target) && (options.denies ?? units)(world, attacker, target)\n}\n\n/**\n * The hooks of denying (see `DenyOptions`)\n *\n * @beta\n */\nexport function denying(options: DenyOptions = {}): HookDef[] {\n\treturn [\n\t\tdefineHook({\n\t\t\thook: 'canAttack',\n\t\t\tid: options.id ?? 'deny',\n\t\t\trun(world, event) {\n\t\t\t\tif (!event.cancelled || !event.ordered) return\n\t\t\t\tif (mayDeny(world, event.attacker, event.target, options)) event.cancelled = false\n\t\t\t}\n\t\t})\n\t]\n}\n\n// ---- last hits and denies (features-plan E2)\n\n/**\n * What a game counts of last hits and denies (`lastHitsPack`)\n *\n * @beta\n */\nexport interface LastHitOptions {\n\t/** The rule of denying (`denying`), or `false` for a game that only counts last hits: the engine's when left out */\n\tdeny?: DenyOptions | false\n\t/**\n\t * The part of a unit's experience the enemy heroes near it still get when it is denied, shared as for a kill: a half\n\t * when left out (none for a kill by the enemy would be no deny at all; all of it, no point in denying)\n\t */\n\texperience?: number\n\t/** Which deaths count, as last hits or denies: units, not heroes nor structures, when left out */\n\tcounts?: (world: World, dead: Entity) => boolean\n}\n\n/** Every player's last hits and denies, by player id: saved with the game */\nexport const counted = defineComponent<Record<string, { lastHits: number; denies: number }>>({ id: 'lastHits', default: () => ({}) })\n\n/**\n * A player's last hits (enemy units they gave the killing blow to) and denies (their own side's), as counted\n * (`lastHitsPack`)\n *\n * @beta\n */\nexport function lastHitsOf(world: World, player: PlayerId): { lastHits: number; denies: number } {\n\tconst all = world.state(counted)\n\treturn all[player] ?? { lastHits: 0, denies: 0 }\n}\n\n/** What the engine counts: units, not heroes nor structures */\nconst countsUnits = (_world: World, dead: Entity) => dead.isUnit && !dead.def.hero\n\n/**\n * A game where last hits and denies count, as in a MOBA: each player's are counted (`lastHitsOf`, saved), a unit\n * denied gives no bounty (as one killed by its own side never does) and only a part of its experience to the enemy\n * heroes near it, and its death says so to the screen (`how: 'denied'`, which the client shows over it). With the rule\n * of denying (`denying`) unless told otherwise\n *\n * @beta\n */\nexport function lastHitsPack(options: LastHitOptions = {}): GamePack {\n\tconst counts = options.counts ?? countsUnits\n\tconst part = options.experience ?? 0.5\n\tconst count = defineHook({\n\t\thook: 'death',\n\t\tid: 'lastHits',\n\t\trun(world, event) {\n\t\t\tconst { entity, killer } = event\n\t\t\tif (!killer || killer === entity || !counts(world, entity)) return\n\t\t\tconst all = world.state(counted)\n\t\t\tconst player = killer.owner\n\t\t\tconst mine = (all[player] ??= { lastHits: 0, denies: 0 })\n\t\t\tif (world.areEnemies(player, entity.owner)) {\n\t\t\t\tmine.lastHits++\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (!world.areAllies(player, entity.owner)) return\n\t\t\tmine.denies++\n\t\t\tevent.how ??= 'denied'\n\t\t\t// the enemy's heroes near it get a part of what it was worth\n\t\t\tconst worth = xpWorth(world, entity) * part\n\t\t\tif (worth <= 0) return\n\t\t\tconst range = world.settings.heroes.xpRange\n\t\t\tconst heroes: Entity[] = []\n\t\t\t// the heroes alone, as the index files them (in the order of their ids, as a walk through every entity met them)\n\t\t\tfor (const hero of world.index.with(heroState)) {\n\t\t\t\tconst state = heroOf(hero)\n\t\t\t\tif (!state || !hero.alive || !world.areEnemies(hero.owner, entity.owner)) continue\n\t\t\t\tif (state.level >= maxLevelOf(world, hero)) continue\n\t\t\t\tif (distSq(hero.pos, entity.pos) <= range * range) heroes.push(hero)\n\t\t\t}\n\t\t\tfor (const hero of heroes) grantXp(world, hero, worth / heroes.length, entity)\n\t\t}\n\t})\n\treturn {\n\t\tid: 'lastHits',\n\t\toptions,\n\t\tcomponents: [counted],\n\t\thooks: [...(options.deny === false ? [] : denying(options.deny)), count]\n\t}\n}\n"],"mappings":";;;;;;;AAiCA,IAAM,SAAS,QAAe,WAAmB,WAAmB,OAAO,UAAU,CAAC,OAAO,IAAI;;;;;;AAOjG,SAAgB,QAAQ,OAAc,UAAkB,QAAgB,UAAuB,CAAC,GAAY;CAC3G,IAAI,MAAM,WAAW,SAAS,OAAO,OAAO,KAAK,GAAG,OAAO;CAC3D,IAAI,OAAO,UAAU,OAAO,aAAa,QAAQ,SAAS,KAAM,OAAO;CACvE,OAAO,cAAc,OAAO,UAAU,MAAM,MAAM,QAAQ,UAAU,MAAA,CAAO,OAAO,UAAU,MAAM;AACnG;;;;;;AAOA,SAAgB,QAAQ,UAAuB,CAAC,GAAc;CAC7D,OAAO,CACN,WAAW;EACV,MAAM;EACN,IAAI,QAAQ,MAAM;EAClB,IAAI,OAAO,OAAO;GACjB,IAAI,CAAC,MAAM,aAAa,CAAC,MAAM,SAAS;GACxC,IAAI,QAAQ,OAAO,MAAM,UAAU,MAAM,QAAQ,OAAO,GAAG,MAAM,YAAY;EAC9E;CACD,CAAC,CACF;AACD;;AAsBA,IAAa,UAAU,gBAAsE;CAAE,IAAI;CAAY,gBAAgB,CAAC;AAAG,CAAC;;;;;;;AAQpI,SAAgB,WAAW,OAAc,QAAwD;CAEhG,OADY,MAAM,MAAM,OACjB,CAAA,CAAI,WAAW;EAAE,UAAU;EAAG,QAAQ;CAAE;AAChD;;AAGA,IAAM,eAAe,QAAe,SAAiB,KAAK,UAAU,CAAC,KAAK,IAAI;;;;;;;;;AAU9E,SAAgB,aAAa,UAA0B,CAAC,GAAa;CACpE,MAAM,SAAS,QAAQ,UAAU;CACjC,MAAM,OAAO,QAAQ,cAAc;CACnC,MAAM,QAAQ,WAAW;EACxB,MAAM;EACN,IAAI;EACJ,IAAI,OAAO,OAAO;GACjB,MAAM,EAAE,QAAQ,WAAW;GAC3B,IAAI,CAAC,UAAU,WAAW,UAAU,CAAC,OAAO,OAAO,MAAM,GAAG;GAC5D,MAAM,MAAM,MAAM,MAAM,OAAO;GAC/B,MAAM,SAAS,OAAO;GACtB,MAAM,OAAQ,IAAI,YAAY;IAAE,UAAU;IAAG,QAAQ;GAAE;GACvD,IAAI,MAAM,WAAW,QAAQ,OAAO,KAAK,GAAG;IAC3C,KAAK;IACL;GACD;GACA,IAAI,CAAC,MAAM,UAAU,QAAQ,OAAO,KAAK,GAAG;GAC5C,KAAK;GACL,MAAM,QAAQ;GAEd,MAAM,QAAQ,QAAQ,OAAO,MAAM,IAAI;GACvC,IAAI,SAAS,GAAG;GAChB,MAAM,QAAQ,MAAM,SAAS,OAAO;GACpC,MAAM,SAAmB,CAAC;GAE1B,KAAK,MAAM,QAAQ,MAAM,MAAM,KAAK,SAAS,GAAG;IAC/C,MAAM,QAAQ,OAAO,IAAI;IACzB,IAAI,CAAC,SAAS,CAAC,KAAK,SAAS,CAAC,MAAM,WAAW,KAAK,OAAO,OAAO,KAAK,GAAG;IAC1E,IAAI,MAAM,SAAS,WAAW,OAAO,IAAI,GAAG;IAC5C,IAAI,OAAO,KAAK,KAAK,OAAO,GAAG,KAAK,QAAQ,OAAO,OAAO,KAAK,IAAI;GACpE;GACA,KAAK,MAAM,QAAQ,QAAQ,QAAQ,OAAO,MAAM,QAAQ,OAAO,QAAQ,MAAM;EAC9E;CACD,CAAC;CACD,OAAO;EACN,IAAI;EACJ;EACA,YAAY,CAAC,OAAO;EACpB,OAAO,CAAC,GAAI,QAAQ,SAAS,QAAQ,CAAC,IAAI,QAAQ,QAAQ,IAAI,GAAI,KAAK;CACxE;AACD"}
@@ -8,7 +8,7 @@ import type { World } from './world';
8
8
  */
9
9
  export declare const DESTRUCTIBLES = "core.destructibles";
10
10
  /**
11
- * What the destructibles pack is made with (`withDestructibles`)
11
+ * What the destructibles pack is made with (`destructiblesPack`)
12
12
  *
13
13
  * @beta
14
14
  */
@@ -24,4 +24,4 @@ export interface DestructiblesOptions {
24
24
  *
25
25
  * @beta
26
26
  */
27
- export declare function withDestructibles(options?: DestructiblesOptions): GamePack;
27
+ export declare function destructiblesPack(options?: DestructiblesOptions): GamePack;
@@ -0,0 +1,36 @@
1
+ import { defineHook } from "./hooks.js";
2
+ import { attackReaches } from "./systems/combat.js";
3
+ //#region src/destructibles.ts
4
+ /**
5
+ * The destructibles pack's id
6
+ *
7
+ * @beta
8
+ */
9
+ var DESTRUCTIBLES = "core.destructibles";
10
+ /**
11
+ * Destructibles, as in classic RTS games: what is `destructible` (`UnitTypeDef.destructible`, a building of the neutral player
12
+ * placed on the map: rocks, a barricade, a gate to break down) stands in the way until it is brought down, and any unit
13
+ * whose attack reaches it attacks it when told to (the attack command), never of its own accord, as trees are felled
14
+ * by what fells them. A gate that opens and shuts is the map's (`setGate`); one that is broken down is a destructible
15
+ *
16
+ * @beta
17
+ */
18
+ function destructiblesPack(options = {}) {
19
+ const destructible = options.destructible ?? ((_world, entity) => !!entity.def.destructible);
20
+ return {
21
+ id: DESTRUCTIBLES,
22
+ options,
23
+ hooks: [defineHook({
24
+ hook: "canAttack",
25
+ id: "destructibles",
26
+ run(world, event) {
27
+ if (!event.cancelled || !event.ordered) return;
28
+ if (destructible(world, event.target) && attackReaches(world, event.attacker, event.target)) event.cancelled = false;
29
+ }
30
+ })]
31
+ };
32
+ }
33
+ //#endregion
34
+ export { DESTRUCTIBLES, destructiblesPack };
35
+
36
+ //# sourceMappingURL=destructibles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"destructibles.js","names":[],"sources":["../src/destructibles.ts"],"sourcesContent":["import type { Entity } from './entity'\nimport { defineHook } from './hooks'\nimport type { GamePack } from './packs/pack'\nimport { attackReaches } from './systems/combat'\nimport type { World } from './world'\n\n/*\n * Destructibles, an opt-in pack (review RV95): rocks, barricades and gates to break down, beyond the trees that are\n * felled. A thing of the map that stands in the way as a building does, and that a unit attacks when it is told to\n */\n\n/**\n * The destructibles pack's id\n *\n * @beta\n */\nexport const DESTRUCTIBLES = 'core.destructibles'\n\n/**\n * What the destructibles pack is made with (`destructiblesPack`)\n *\n * @beta\n */\nexport interface DestructiblesOptions {\n\t/** Whether something is brought down by being attacked when told to, in code: its type's `destructible` when left out */\n\tdestructible?: (world: World, entity: Entity) => boolean\n}\n\n/**\n * Destructibles, as in classic RTS games: what is `destructible` (`UnitTypeDef.destructible`, a building of the neutral player\n * placed on the map: rocks, a barricade, a gate to break down) stands in the way until it is brought down, and any unit\n * whose attack reaches it attacks it when told to (the attack command), never of its own accord, as trees are felled\n * by what fells them. A gate that opens and shuts is the map's (`setGate`); one that is broken down is a destructible\n *\n * @beta\n */\nexport function destructiblesPack(options: DestructiblesOptions = {}): GamePack {\n\tconst destructible = options.destructible ?? ((_world: World, entity: Entity) => !!entity.def.destructible)\n\tconst attacked = defineHook({\n\t\thook: 'canAttack',\n\t\tid: 'destructibles',\n\t\trun(world, event) {\n\t\t\tif (!event.cancelled || !event.ordered) return\n\t\t\tif (destructible(world, event.target) && attackReaches(world, event.attacker, event.target)) event.cancelled = false\n\t\t}\n\t})\n\treturn { id: DESTRUCTIBLES, options, hooks: [attacked] }\n}\n"],"mappings":";;;;;;;;AAgBA,IAAa,gBAAgB;;;;;;;;;AAoB7B,SAAgB,kBAAkB,UAAgC,CAAC,GAAa;CAC/E,MAAM,eAAe,QAAQ,kBAAkB,QAAe,WAAmB,CAAC,CAAC,OAAO,IAAI;CAS9F,OAAO;EAAE,IAAI;EAAe;EAAS,OAAO,CAR3B,WAAW;GAC3B,MAAM;GACN,IAAI;GACJ,IAAI,OAAO,OAAO;IACjB,IAAI,CAAC,MAAM,aAAa,CAAC,MAAM,SAAS;IACxC,IAAI,aAAa,OAAO,MAAM,MAAM,KAAK,cAAc,OAAO,MAAM,UAAU,MAAM,MAAM,GAAG,MAAM,YAAY;GAChH;EACD,CAC6C,CAAQ;CAAE;AACxD"}
@@ -3,7 +3,7 @@
3
3
  * that runs a world twice, and on from a save, and says the first tick and the first thing they differ at. What a
4
4
  * replay of commands, a save that goes on exactly and a game the same in every browser stand on
5
5
  */
6
- import { type GameModule } from './game';
6
+ import { type Rules } from './game';
7
7
  import { type WorldSave } from './save';
8
8
  import type { Registry } from './registry';
9
9
  import type { World } from './world';
@@ -93,7 +93,7 @@ export interface DeterminismOptions {
93
93
  */
94
94
  from?: number;
95
95
  /** The game the save is loaded with, for `from` */
96
- game?: GameModule;
96
+ rules?: Rules;
97
97
  }
98
98
  /**
99
99
  * What the check found: for each run, where it came apart from the first, or `null` for the same to the last tick
@@ -113,9 +113,9 @@ export interface DeterminismReport {
113
113
  * from the save, and the two run on side by side. Says, for each, the first tick and thing it differs at, or that it does not. A test of a game's
114
114
  * own systems: one that reads `Math.random`, the clock, or the order of something unordered is found here
115
115
  *
116
- * const report = await checkDeterminism(() => makeMyGame(1), { ticks: 1800, from: 300, game: rules })
116
+ * const report = await checkDeterminism(() => makeMyGame(1), { ticks: 1800, from: 300, rules })
117
117
  * expect(report).toEqual({ twice: null, fromSave: null })
118
118
  *
119
- * @beta
119
+ * @public
120
120
  */
121
121
  export declare function checkDeterminism(make: () => World | Promise<World>, options: DeterminismOptions): Promise<DeterminismReport>;