@v12-engine/engine 0.1.0 → 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":"view.js","names":[],"sources":["../../src/ai/view.ts"],"sourcesContent":["import { inShape } from '#engine/areas'\nimport { builtSoFar } from '#engine/systems/construction'\nimport type { Component } from '#engine/components'\nimport type { ResourceId, UnitTypeDef } from '#engine/defs'\nimport type { PlayerId } from '#engine/entity'\nimport type { EventKey } from '#engine/events'\nimport type { Lane } from '#engine/lanes'\nimport type { MapRegion } from '#engine/map'\nimport { distSq, type Vec2 } from '#engine/math'\nimport type { Message } from '#engine/messages'\nimport type { ObjectiveState } from '#engine/objectives'\nimport type { Registry } from '#engine/registry'\nimport type {\n\tCampInfo,\n\tEntityState,\n\tGameSession,\n\tGroundItemState,\n\tHeroSummary,\n\tMineInfo,\n\tPlayerState,\n\tSessionEvent,\n\tSnapshot\n} from '#engine/session/protocol'\nimport { type AiRole, findRoles, reachableTypes, type Roles, type RolesFinder } from './roles'\nimport { Strength, type StrengthFormula } from './strength'\nimport { ThreatMap } from './threat'\nimport { BASE_REACH, CELL } from './reach'\n\n/*\n * The view: a computer player's reading of its snapshot (AI plan, A2). A snapshot is plain data, one flat list of\n * entities (`Snapshot.entities`), and every question a brain asks of it (\"my idle workers\", \"enemies near home\", \"the\n * nearest mine\") would be a walk over the whole list; the old melee player walked it dozens of times a think. The view\n * walks it once, as the think begins, and sorts what it finds: by owner and relation (`mine`, `allies`, `enemies`,\n * `creeps`, `neutral`, `resources`), by id (`byId`), and by place (a coarse grid of cells over the map, which answers\n * \"what is near here\" from a few cells instead of everything). What it gives back are `UnitSet`s: arrays of entity\n * states with the questions as methods (`idle()`, `withRole('worker')`, `near(home, 20)`), each giving a set again, so\n * that a goal's author writes `ai.view.enemies.near(home, 20).fighters()` and reads what they meant.\n *\n * The view is of one think: made from the snapshot as the think begins, thrown away with it. Entities move, so the\n * grid is never kept between thinks, and neither is the threat map (`threat`, made when first asked). What is kept is\n * what costs and does not change: the roles of the game's unit types (`roles.ts`), found once and kept while the\n * game's definitions stand, and what the types' numbers come to (`strength`, `strength.ts`).\n *\n * Nothing here takes the world itself (a test asserts it): the view reads the session's snapshot, cut to the player's\n * fog, and the map's facts everyone knows (regions, mines, camps, the ground for `canPlace` and `findPath`)\n */\n\n/** A set this small is scanned for what is near rather than asked of the grid: the grid pays for itself only on big sets */\nconst SCAN = 24\n\n/**\n * A set of entities as the view gives them, in the snapshot's order, with the questions a brain asks as methods, each\n * giving a set again, so that they chain: `ai.view.mine.withRole('worker').idle()`, `ai.view.enemies.near(home,\n * 20).fighters()`. It reads as an array (`length`, `for..of`, `map`, `filter`, `find`, `some`, `every`, `forEach`,\n * `first`, `at`; `items` is the plain array) but is not one: `map` and `filter` give plain arrays, `where` gives a set.\n * (Not an `Array` subclass on purpose: the engines run `filter` and `find` on one several times slower, species\n * lookup, and a think asks dozens.) A set is of one think: it reads the view it came from\n *\n * @beta\n */\nexport class UnitSet implements Iterable<EntityState> {\n\t/** What this set remembers beside what is in sight (`known`): the structures seen before, for the view's own sets */\n\tprivate readonly remembered: EntityState[] | undefined\n\t/** The answers to the questions that are asked again and again, by their name */\n\tprivate memo: Map<string, UnitSet> | undefined\n\tprivate idSet: Set<number> | undefined\n\tprivate strengthSum: number | undefined\n\n\tconstructor(\n\t\t/** The view the set reads: the definitions, the roles, the grid */\n\t\treadonly view: AiView,\n\t\t/** The entities, as a plain array, in the snapshot's order */\n\t\treadonly items: readonly EntityState[] = [],\n\t\tremembered?: EntityState[]\n\t) {\n\t\tthis.remembered = remembered\n\t}\n\n\t/** How many */\n\tget length(): number {\n\t\treturn this.items.length\n\t}\n\n\t/** Iterates the set's entities in order */\n\t[Symbol.iterator](): Iterator<EntityState> {\n\t\treturn this.items[Symbol.iterator]()\n\t}\n\n\t/** The first of them: none in an empty set */\n\tfirst(): EntityState | undefined {\n\t\treturn this.items[0]\n\t}\n\n\t/** Some of them, as an array's `slice` takes them: as a set */\n\tslice(start?: number, end?: number): UnitSet {\n\t\treturn this.make(this.items.slice(start, end))\n\t}\n\n\t/** The one at an index, from the end for a negative one */\n\tat(index: number): EntityState | undefined {\n\t\treturn this.items.at(index)\n\t}\n\n\t/** As an array does: a plain array */\n\tmap<T>(fn: (entity: EntityState, index: number) => T): T[] {\n\t\treturn this.items.map(fn)\n\t}\n\n\t/** As an array does: a plain array. `where` gives a set */\n\tfilter(fn: (entity: EntityState, index: number) => unknown): EntityState[] {\n\t\treturn this.items.filter(fn)\n\t}\n\n\t/** The first entity `fn` is true for, or nothing; `fn` is given the entity and its index */\n\tfind(fn: (entity: EntityState, index: number) => unknown): EntityState | undefined {\n\t\treturn this.items.find(fn)\n\t}\n\n\t/** Whether `fn` is true for any entity of the set */\n\tsome(fn: (entity: EntityState, index: number) => unknown): boolean {\n\t\treturn this.items.some(fn)\n\t}\n\n\t/** Whether `fn` is true for every entity of the set */\n\tevery(fn: (entity: EntityState, index: number) => unknown): boolean {\n\t\treturn this.items.every(fn)\n\t}\n\n\t/** Calls `fn` with each entity and its index, in order */\n\tforEach(fn: (entity: EntityState, index: number) => void): void {\n\t\tthis.items.forEach(fn)\n\t}\n\n\t/** A set of these, of the same view */\n\tprivate make(items: readonly EntityState[]): UnitSet {\n\t\treturn new UnitSet(this.view, items)\n\t}\n\n\t/** The answer to a question asked by name, worked out once */\n\tprivate cached(key: string, answer: () => UnitSet): UnitSet {\n\t\tthis.memo ??= new Map()\n\t\tlet found = this.memo.get(key)\n\t\tif (!found) this.memo.set(key, (found = answer()))\n\t\treturn found\n\t}\n\n\t/** Those that satisfy a predicate, as a set */\n\twhere(predicate: (entity: EntityState, def: UnitTypeDef) => boolean): UnitSet {\n\t\tconst { view } = this\n\t\treturn this.make(this.items.filter((entity) => predicate(entity, view.def(entity))))\n\t}\n\n\t/** Those of a unit type, or that count as it (`UnitTypeDef.provides`: a keep is a town hall too) */\n\tofType(type: string): UnitSet {\n\t\treturn this.cached(`type:${type}`, () => this.where((entity, def) => entity.type === type || !!def.provides?.includes(type)))\n\t}\n\n\t/** Those whose type has a role (`AiRole`: `'worker'`, `'hall'`, a game's own word) */\n\twithRole(role: AiRole): UnitSet {\n\t\treturn this.cached(`role:${role}`, () => {\n\t\t\tconst { roles } = this.view\n\t\t\treturn this.make(this.items.filter((entity) => roles.has(entity.type, role)))\n\t\t})\n\t}\n\n\t/** Those whose type has a tag: the kit's (`ranged`, `melee`, `hitsAir`) or the game's (`UnitTypeDef.ai.tags`) */\n\twithTag(tag: string): UnitSet {\n\t\treturn this.cached(`tag:${tag}`, () => {\n\t\t\tconst { roles } = this.view\n\t\t\treturn this.make(this.items.filter((entity) => roles.hasTag(entity.type, tag)))\n\t\t})\n\t}\n\n\t/** Those that fight: soldiers and heroes */\n\tfighters(): UnitSet {\n\t\treturn this.cached('fighters', () => {\n\t\t\tconst { roles } = this.view\n\t\t\treturn this.make(this.items.filter((entity) => roles.has(entity.type, 'soldier') || roles.has(entity.type, 'hero')))\n\t\t})\n\t}\n\n\t/** Those that gather and build (role `worker`) */\n\tworkers(): UnitSet {\n\t\treturn this.withRole('worker')\n\t}\n\n\t/** The heroes among them */\n\theroes(): UnitSet {\n\t\treturn this.withRole('hero')\n\t}\n\n\t/** The buildings among them, under construction too (`finished` leaves those out) */\n\tbuildings(): UnitSet {\n\t\treturn this.cached('buildings', () => this.where((_, def) => def.kind === 'building'))\n\t}\n\n\t/** The units among them: what moves, buildings and resources left out */\n\tunits(): UnitSet {\n\t\treturn this.cached('units', () => this.where((_, def) => def.kind === 'unit'))\n\t}\n\n\t/** Those that stand finished: not under construction (a building turning into another type stands) */\n\tfinished(): UnitSet {\n\t\treturn this.cached('finished', () => this.make(this.items.filter((entity) => builtSoFar(entity) === undefined)))\n\t}\n\n\t/** Those of mine with nothing to do: no order, and not inside something (a worker in a mine). Only one's own say what they do */\n\tidle(): UnitSet {\n\t\treturn this.cached('idle', () => this.make(this.items.filter((entity) => !!entity.own && !entity.own.order && !entity.own.hidden)))\n\t}\n\n\t/** Those in sight now: a structure seen before and out of sight is not (`EntityState.visible`) */\n\tvisible(): UnitSet {\n\t\treturn this.cached('visible', () => this.make(this.items.filter((entity) => entity.visible)))\n\t}\n\n\t/** Those with health left */\n\talive(): UnitSet {\n\t\treturn this.cached('alive', () => this.make(this.items.filter((entity) => entity.health > 0)))\n\t}\n\n\t/** Deposits of a resource with something left in them (a gold mine, a tree): for the view's `resources` */\n\tofResource(kind: ResourceId): UnitSet {\n\t\treturn this.cached(`resource:${kind}`, () => this.where((entity, def) => (entity.resource ?? 0) > 0 && def.resource?.id === kind))\n\t}\n\n\t/** Those of a player */\n\tofOwner(player: PlayerId): UnitSet {\n\t\treturn this.cached(`owner:${player}`, () => this.make(this.items.filter((entity) => entity.owner === player)))\n\t}\n\n\t/**\n\t * Those within a distance of a point, in the snapshot's order. A big set is asked of the view's grid, a small one is\n\t * scanned: the answer is the same\n\t */\n\tnear(point: Vec2, radius: number): UnitSet {\n\t\tconst reach = radius * radius\n\t\tif (this.items.length <= SCAN) return this.make(this.items.filter((entity) => distSq(entity, point) <= reach))\n\t\tconst ids = this.ids()\n\t\treturn this.make(this.view.gridNear(point, radius).filter((entity) => ids.has(entity.id) && distSq(entity, point) <= reach))\n\t}\n\n\t/** The one nearest a point: none in an empty set. The first of two as near */\n\tnearest(point: Vec2): EntityState | undefined {\n\t\tlet best: EntityState | undefined\n\t\tlet bestDistance = Infinity\n\t\tfor (const entity of this.items) {\n\t\t\tconst d = distSq(entity, point)\n\t\t\tif (d < bestDistance) {\n\t\t\t\tbestDistance = d\n\t\t\t\tbest = entity\n\t\t\t}\n\t\t}\n\t\treturn best\n\t}\n\n\t/** The middle of them: none for an empty set */\n\tcentre(): Vec2 | undefined {\n\t\tconst { items } = this\n\t\tif (!items.length) return undefined\n\t\tlet x = 0\n\t\tlet z = 0\n\t\tfor (const entity of items) {\n\t\t\tx += entity.x\n\t\t\tz += entity.z\n\t\t}\n\t\treturn { x: x / items.length, z: z / items.length }\n\t}\n\n\t/**\n\t * How strong they are together: the strength of each (`Strength.of`: by its stats and the health it has left),\n\t * summed. 0 for what does not fight. Against someone in particular, ask `view.strength.odds(these, those)`\n\t */\n\tstrength(): number {\n\t\treturn (this.strengthSum ??= this.view.strength.sum(this.items))\n\t}\n\n\t/** Their ids, as a set: for \"is it one of these\" */\n\tids(): ReadonlySet<number> {\n\t\treturn (this.idSet ??= new Set(this.items.map((entity) => entity.id)))\n\t}\n\n\t/** Whether an entity, by id, is one of these */\n\thas(id: number): boolean {\n\t\treturn this.ids().has(id)\n\t}\n\n\t/** These and another set's, together, in the snapshot's order, each once */\n\tand(other: UnitSet): UnitSet {\n\t\tconst { view } = this\n\t\tconst all = [...this.items, ...other.items.filter((entity) => !this.has(entity.id))]\n\t\tall.sort((a, b) => view.indexOf(a) - view.indexOf(b))\n\t\treturn this.make(all)\n\t}\n\n\t/**\n\t * These and what is remembered of them beside what is in sight: for `view.enemies`, the enemy structures seen before\n\t * and out of sight now (`visible: false`), which may be gone. Ask it of the view's set before narrowing it\n\t * (`view.enemies.known().buildings()`): a narrowed set remembers nothing more\n\t */\n\tknown(): UnitSet {\n\t\tif (!this.remembered?.length) return this\n\t\treturn this.cached('known', () => this.and(this.make(this.remembered!)))\n\t}\n}\n\n/**\n * The player a brain plays, as its picture of the game shows them: what the snapshot has of one's own player\n * (`PlayerState.own`), beside who they are. Mutable for the think: a module that sends a `train` bumps `supplyUsed`\n * itself, so that the next module does not queue past the cap before the command lands\n *\n * @beta\n */\nexport interface Me {\n\t/** The player's id */\n\tid: PlayerId\n\t/** The player's name */\n\tname: string\n\t/** The player's team number */\n\tteam: number\n\t/** The race they play (`raceOf`): left out in a game without races */\n\trace?: string\n\t/** Whether the player is out of the game */\n\tdefeated: boolean\n\t/** What they have of each resource, by resource id */\n\tresources: Record<ResourceId, number>\n\t/** How much supply the player's units and queues use */\n\tsupplyUsed: number\n\t/** How much supply the player may use at most */\n\tsupplyCap: number\n\t/** The game's other pools of supply, by name (`RuleSettings.supply.pools`) */\n\tsupplies?: Record<string, { used: number; cap: number }>\n\t/** What the size of the army costs in income */\n\tupkeep: { tier: number; name: string; income: number }\n\t/** The levels of the upgrades the player has, by upgrade id */\n\tupgrades: Record<string, number>\n\t/** The ids of the upgrades being researched */\n\tresearching: string[]\n\t/** Types of the finished buildings the player has, with what those count as */\n\ttech: string[]\n\t/** The player's heroes, each in short */\n\theroes: HeroSummary[]\n\t/** What the player is set to do, in a mission. Empty in a game without objectives */\n\tobjectives: ObjectiveState[]\n\t/** What the game's `requirement` hook decided, where it differs from what the requirements say (`PlayerState.own.unlocks`) */\n\tunlocks?: Record<string, Message | null>\n\t/** What the game's `available` hook decided, where it differs from what their race says (`PlayerState.own.availability`) */\n\tavailability?: Record<string, boolean>\n\t/**\n\t * What the player gathers of each resource a minute, of late, as the brain's knowledge works it out\n\t * (`Knowledge.own.income`): set by the brain after the view is made; left out for a view of no brain's\n\t */\n\tincome?: Record<ResourceId, number>\n\t/**\n\t * What is free to spend this think, by resource: the resources less what is promised and held, less what the think\n\t * spent so far (the brain's purse, `ai.purse`). Set by the brain after the view is made; left out for a view of no brain's\n\t */\n\tpurse?: Readonly<Record<ResourceId, number>>\n}\n\n/**\n * One of a player's bases, as the view clusters its buildings: around each building that takes deposits (a hall, what\n * stands on a mine), or around any building where none does\n *\n * @beta\n */\nexport interface Base {\n\t/** Where it is: the building it is around */\n\tat: Vec2\n\t/** The building it is around: a hall where there is one */\n\tcentre: EntityState\n\t/** Its buildings, the centre among them */\n\tbuildings: UnitSet\n}\n\n/** The coarse grid of the view: every entity in the cell its place falls in, for what is near a point */\nclass Grid {\n\tprivate readonly cells: (EntityState[] | undefined)[]\n\tprivate readonly cols: number\n\tprivate readonly rows: number\n\n\tconstructor(\n\t\twidth: number,\n\t\tdepth: number,\n\t\t/** Where each entity comes in the snapshot, by id: what `near` gives its answer in the order of */\n\t\tprivate readonly index: ReadonlyMap<number, number>\n\t) {\n\t\tthis.cols = Math.max(1, Math.ceil(width / CELL))\n\t\tthis.rows = Math.max(1, Math.ceil(depth / CELL))\n\t\tthis.cells = new Array(this.cols * this.rows)\n\t}\n\n\tprivate col(x: number): number {\n\t\treturn Math.min(this.cols - 1, Math.max(0, Math.floor(x / CELL)))\n\t}\n\n\tprivate row(z: number): number {\n\t\treturn Math.min(this.rows - 1, Math.max(0, Math.floor(z / CELL)))\n\t}\n\n\tadd(entity: EntityState): void {\n\t\tconst index = this.row(entity.z) * this.cols + this.col(entity.x)\n\t\t;(this.cells[index] ??= []).push(entity)\n\t}\n\n\t/** Everything in the cells a circle touches, in the snapshot's order: more than what is within the circle */\n\tnear(point: Vec2, radius: number): EntityState[] {\n\t\tconst found: EntityState[] = []\n\t\tconst c0 = this.col(point.x - radius)\n\t\tconst c1 = this.col(point.x + radius)\n\t\tconst r0 = this.row(point.z - radius)\n\t\tconst r1 = this.row(point.z + radius)\n\t\tfor (let r = r0; r <= r1; r++) {\n\t\t\tfor (let c = c0; c <= c1; c++) {\n\t\t\t\tconst cell = this.cells[r * this.cols + c]\n\t\t\t\tif (cell) for (const entity of cell) found.push(entity)\n\t\t\t}\n\t\t}\n\t\t// cells came row by row: back into the snapshot's order, so that the answer is the same as a scan's\n\t\tconst { index } = this\n\t\tfound.sort((a, b) => index.get(a.id)! - index.get(b.id)!)\n\t\treturn found\n\t}\n}\n\n/**\n * The events of a think, by kind (`AiView.events`): what happened in the tick of the picture that cannot be read from\n * the state (deaths, damage, pings, the game's own)\n *\n * @beta\n */\nexport class ViewEvents {\n\tprivate byType: Map<string, SessionEvent[]> | undefined\n\n\tconstructor(\n\t\t/** Every event of the tick, in order */\n\t\treadonly all: readonly SessionEvent[]\n\t) {}\n\n\t/** The events of one kind, typed: `events.of('death')`, `events.of('ping')` */\n\tof<T extends SessionEvent['type']>(type: T): Extract<SessionEvent, { type: T }>[] {\n\t\tif (!this.byType) {\n\t\t\tthis.byType = new Map()\n\t\t\tfor (const event of this.all) {\n\t\t\t\tlet list = this.byType.get(event.type)\n\t\t\t\tif (!list) this.byType.set(event.type, (list = []))\n\t\t\t\tlist.push(event)\n\t\t\t}\n\t\t}\n\t\treturn (this.byType.get(type) ?? []) as Extract<SessionEvent, { type: T }>[]\n\t}\n\n\t/** What an event of the game's own said this tick (`defineEvent`, replicated to this player), each time it was emitted */\n\tgame<T>(key: EventKey<T>): T[] {\n\t\treturn this.of('game')\n\t\t\t.filter((event) => event.event === key.id)\n\t\t\t.map((event) => event.payload as T)\n\t}\n}\n\n/**\n * What the view is handed beside the snapshot: the last think's view, whose roles it keeps where the game's\n * definitions stand, and a game's own way of finding the roles (`AiOptions.roles`)\n *\n * @beta\n */\nexport interface ViewOptions {\n\t/** The view of the think before: what cost and did not change is kept from it (the roles, the player's reach) */\n\tbefore?: AiView\n\t/** A game's own say on what unit types are for, in place of the kit's inference (`AiOptions.roles`) */\n\troles?: RolesFinder\n\t/** A game's own formula for how strong a unit is, in place of the kit's (`AiOptions.strength`, `BrainDef.strength`) */\n\tstrength?: StrengthFormula\n}\n\n/**\n * A computer player's reading of its picture of the game (`Brain.view`): the snapshot of its seat, indexed once a\n * think and queried as sets (`UnitSet`): `mine`, `allies`, `enemies` (what is in sight now; `enemies.known()` adds\n * the structures remembered), `hostile` (enemies and creeps), `creeps`, `neutral`, `resources`, `all`; the player's\n * own state (`me`); what unit types are for (`roles`, `typesOf`); where things are (`near`, `home`, `bases`, `mines`,\n * `camps`, `regions`); how strong things are (`strength`: `odds`, `matchup`, `counterFor`) and where the strength\n * is (`threat`, the map made when first asked); what the game tells this player (`report`, `component`,\n * `events.game`); and the map's facts (`canPlace`, `findPath`, `cellAt`). Made from the snapshot as the think begins; a set of\n * it is good for the think\n *\n * @beta\n */\nexport class AiView {\n\t/** The game's definitions, as the seat has them */\n\treadonly registry: Registry\n\t/** The player it reads for */\n\treadonly playerId: PlayerId\n\t/** Every entity the player knows of, in the snapshot's order: in sight, and the structures remembered */\n\treadonly all: UnitSet\n\t/** The player's own units and buildings */\n\treadonly mine: UnitSet\n\t/** The allies' units and buildings (one's own left out) */\n\treadonly allies: UnitSet\n\t/** The enemies' units and buildings in sight now, creeps left out. `enemies.known()` adds their structures seen before */\n\treadonly enemies: UnitSet\n\t/** Whatever attacks the player and is in sight: enemies and creeps */\n\treadonly hostile: UnitSet\n\t/** The creeps in sight: hostile to everyone, no one's rival */\n\treadonly creeps: UnitSet\n\t/** What is nobody's and not a resource, in sight: a shop, a neutral building. `neutral.known()` adds those seen before */\n\treadonly neutral: UnitSet\n\t/** The deposits the player knows of: mines and trees in sight, and those seen before (`ofResource(kind)` for one kind) */\n\treadonly resources: UnitSet\n\t/** Every player, as the snapshot has them */\n\treadonly players: readonly PlayerState[]\n\t/** The player a brain plays: resources, supply, tech, heroes, objectives. Mutable for the think */\n\treadonly me: Me\n\t/** What happened in the tick of the picture, by kind */\n\treadonly events: ViewEvents\n\t/** What unit types are for, by the game's definitions: found once, kept while they stand */\n\treadonly roles: Roles\n\t/** The unit types the player has or can come to make: what the roles are narrowed to for it (`typesOf`) */\n\treadonly reachable: ReadonlySet<string>\n\t/**\n\t * How strong things are: a unit, a group, one force against another (`odds`), what answers what (`counterFor`). The\n\t * kit's formula unless the brain was given one; what a type's numbers come to is kept between thinks\n\t */\n\treadonly strength: Strength\n\tprivate threatMap: ThreatMap | undefined\n\tprivate readonly grid: Grid\n\tprivate readonly byIdMap = new Map<number, EntityState>()\n\tprivate readonly indexById = new Map<number, number>()\n\tprivate readonly playerById = new Map<PlayerId, PlayerState>()\n\tprivate readonly namesMap = new Map<string, EntityState>()\n\tprivate readonly typesByRole: Map<string, readonly UnitTypeDef[]>\n\t/** The race the view's reach was found for: a player given another race finds it anew */\n\tprivate readonly race: string | undefined\n\tprivate basesFound: Base[] | undefined\n\tprivate lanesFound: readonly Lane[] | undefined\n\n\tconstructor(\n\t\t/** The picture it reads: the snapshot of the seat, plain data, the only input a brain has */\n\t\treadonly snapshot: Snapshot,\n\t\t/** The seat, for the map's facts: the ground, the regions, the mines, the camps */\n\t\treadonly session: GameSession,\n\t\toptions: ViewOptions = {}\n\t) {\n\t\tconst { registry, playerId, terrain } = session\n\t\tthis.registry = registry\n\t\tthis.playerId = playerId\n\t\tthis.players = snapshot.players\n\t\tfor (const player of snapshot.players) this.playerById.set(player.id, player)\n\t\tconst self = this.playerById.get(playerId)\n\t\tthis.me = meOf(self, playerId)\n\t\tthis.events = new ViewEvents(snapshot.events)\n\t\tthis.grid = new Grid(terrain.width, terrain.depth, this.indexById)\n\n\t\t// the one pass over the picture: every entity to its sets, its cell, its index, its name\n\t\tconst mine: EntityState[] = []\n\t\tconst allies: EntityState[] = []\n\t\tconst enemies: EntityState[] = []\n\t\tconst enemiesRemembered: EntityState[] = []\n\t\tconst hostile: EntityState[] = []\n\t\tconst hostileRemembered: EntityState[] = []\n\t\tconst creeps: EntityState[] = []\n\t\tconst creepsRemembered: EntityState[] = []\n\t\tconst neutral: EntityState[] = []\n\t\tconst neutralRemembered: EntityState[] = []\n\t\tconst resources: EntityState[] = []\n\t\tconst ownedTypes = new Set<string>()\n\t\tsnapshot.entities.forEach((entity, index) => {\n\t\t\tthis.byIdMap.set(entity.id, entity)\n\t\t\tthis.indexById.set(entity.id, index)\n\t\t\tthis.grid.add(entity)\n\t\t\tif (entity.name !== undefined) this.namesMap.set(entity.name, entity)\n\t\t\tif (entity.owner === playerId) {\n\t\t\t\tmine.push(entity)\n\t\t\t\townedTypes.add(entity.type)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (registry.units.has(entity.type) && registry.unit(entity.type).kind === 'resource') {\n\t\t\t\tresources.push(entity)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst owner = this.playerById.get(entity.owner)\n\t\t\tif (!owner) return\n\t\t\t// creeps are hostile to everyone and no one's rival: with the enemies in `hostile`, apart in `creeps`; a creep\n\t\t\t// made friendly (`setRelation`) is in `creeps` alone\n\t\t\tif (owner.creeps) (entity.visible ? creeps : creepsRemembered).push(entity)\n\t\t\tswitch (owner.relation) {\n\t\t\t\tcase 'ally':\n\t\t\t\t\tif (!owner.creeps) allies.push(entity)\n\t\t\t\t\tbreak\n\t\t\t\tcase 'enemy':\n\t\t\t\t\t;(entity.visible ? hostile : hostileRemembered).push(entity)\n\t\t\t\t\tif (!owner.creeps) (entity.visible ? enemies : enemiesRemembered).push(entity)\n\t\t\t\t\tbreak\n\t\t\t\tdefault:\n\t\t\t\t\tif (!owner.creeps) (entity.visible ? neutral : neutralRemembered).push(entity)\n\t\t\t}\n\t\t})\n\t\tthis.all = new UnitSet(this, snapshot.entities)\n\t\tthis.mine = new UnitSet(this, mine)\n\t\tthis.allies = new UnitSet(this, allies)\n\t\tthis.enemies = new UnitSet(this, enemies, enemiesRemembered)\n\t\tthis.hostile = new UnitSet(this, hostile, hostileRemembered)\n\t\tthis.creeps = new UnitSet(this, creeps, creepsRemembered)\n\t\tthis.neutral = new UnitSet(this, neutral, neutralRemembered)\n\t\tthis.resources = new UnitSet(this, resources)\n\n\t\t// what costs and does not change between thinks is kept from the view before: the roles of the game's types,\n\t\t// and the player's reach, found again when it has a type it could not make (given one, a race of two) or when\n\t\t// what the game lets it make changed (a type a mission unlocks)\n\t\tconst before = options.before\n\t\tconst player = { id: playerId, race: self?.race, availability: self?.own?.availability }\n\t\tthis.race = self?.race\n\t\tthis.roles = before?.roles ?? findRoles(registry, player, options.roles)\n\t\tlet kept = before && before.race === this.race && sameAvailability(before.me.availability, player.availability) ? before : undefined\n\t\tif (kept) {\n\t\t\tconst reach = kept.reachable\n\t\t\tfor (const type of ownedTypes) if (!reach.has(type)) kept = undefined\n\t\t}\n\t\tthis.reachable = kept?.reachable ?? reachableTypes(registry, player, ownedTypes)\n\t\tthis.typesByRole = kept?.typesByRole ?? new Map()\n\t\t// what the types' numbers come to is kept too, as long as the formula is the one it was found by\n\t\tconst formula = options.strength ?? before?.strength.formula\n\t\tthis.strength = before && before.strength.formula === formula ? before.strength : new Strength(registry, formula)\n\t\tthis.strength.view = this\n\t}\n\n\t/**\n\t * Where the strength is: an influence map over the picture, the friendly and the enemy strength that reaches each\n\t * cell of a coarse grid, by layer (`threat.at(point)`, `around`, `hot`). Made when first asked, once a think\n\t */\n\tget threat(): ThreatMap {\n\t\treturn (this.threatMap ??= new ThreatMap(this))\n\t}\n\n\t/** @internal What is in the cells of the grid a circle touches, in the snapshot's order: for a set's `near` */\n\tgridNear(point: Vec2, radius: number): EntityState[] {\n\t\treturn this.grid.near(point, radius)\n\t}\n\n\t/** The tick of the picture */\n\tget tick(): number {\n\t\treturn this.snapshot.tick\n\t}\n\n\t/** Seconds into the game, as of the picture */\n\tget time(): number {\n\t\treturn this.snapshot.tick / this.session.tickRate\n\t}\n\n\t/** Items lying on the ground where the player sees it */\n\tget items(): readonly GroundItemState[] {\n\t\treturn this.snapshot.items\n\t}\n\n\t/** What the game tells the player about itself (`Rules.report`): a wave number, a score */\n\tget report(): Record<string, unknown> | undefined {\n\t\treturn this.snapshot.report\n\t}\n\n\t/** An entity the player knows of, by id: none for one gone, or never seen */\n\tbyId(id: number | undefined): EntityState | undefined {\n\t\treturn id === undefined ? undefined : this.byIdMap.get(id)\n\t}\n\n\t/** @internal Where an entity comes in the snapshot: for sets to keep its order */\n\tindexOf(entity: EntityState): number {\n\t\treturn this.indexById.get(entity.id) ?? Infinity\n\t}\n\n\t/** The definition of an entity's type */\n\tdef(entity: EntityState): UnitTypeDef {\n\t\treturn this.registry.unit(entity.type)\n\t}\n\n\t/** A player, by id */\n\tplayer(id: PlayerId): PlayerState | undefined {\n\t\treturn this.playerById.get(id)\n\t}\n\n\t/** What an entity's owner is to the player: `self`, `ally`, `enemy`, `neutral`. Creeps are `enemy` */\n\trelation(entity: EntityState): PlayerState['relation'] | undefined {\n\t\treturn this.playerById.get(entity.owner)?.relation\n\t}\n\n\t/** Whether an entity is a rival's, or a creep */\n\tisHostile(entity: EntityState): boolean {\n\t\treturn this.relation(entity) === 'enemy'\n\t}\n\n\t/** Whether an entity is a creep's */\n\tisCreep(entity: EntityState): boolean {\n\t\treturn !!this.playerById.get(entity.owner)?.creeps\n\t}\n\n\t/** Whether an entity is the player's own or an ally's */\n\tisFriendly(entity: EntityState): boolean {\n\t\tconst relation = this.relation(entity)\n\t\treturn relation === 'self' || relation === 'ally'\n\t}\n\n\t/** The roles of an entity's type, or of a type by id */\n\troleOf(entity: EntityState | string): readonly AiRole[] {\n\t\treturn this.roles.of(typeof entity === 'string' ? entity : entity.type)\n\t}\n\n\t/** Whether an entity's type, or a type by id, has a role */\n\thasRole(entity: EntityState | string, role: AiRole): boolean {\n\t\treturn this.roles.has(typeof entity === 'string' ? entity : entity.type, role)\n\t}\n\n\t/**\n\t * The unit types with a role that are the player's own: those it has or can come to make (`reachable`), in the\n\t * game's order, so that the first of a kind is the one meant first. A game of two races gives each player its own\n\t */\n\ttypesOf(role: AiRole): readonly UnitTypeDef[] {\n\t\tlet found = this.typesByRole.get(role)\n\t\tif (!found) this.typesByRole.set(role, (found = this.roles.types(role).filter((def) => this.reachable.has(def.id))))\n\t\treturn found\n\t}\n\n\t/** Whether the player has the finished buildings something asks for (`UnitTypeDef.requires`) */\n\thas(requires: readonly string[] | undefined): boolean {\n\t\treturn (requires ?? []).every((id) => this.me.tech.includes(id))\n\t}\n\n\t/** The player's home: its first hall, or its first building where it has no hall. None with no buildings */\n\thome(): EntityState | undefined {\n\t\treturn this.mine.withRole('hall').first() ?? this.mine.buildings().first()\n\t}\n\n\t/**\n\t * The player's bases: its buildings clustered around what takes deposits (halls, what stands on a mine), each to\n\t * the nearest of those within reach; and where there is nothing that takes deposits (a game with no economy), around\n\t * any building, the clusters made as the buildings come. Home first\n\t */\n\tbases(): readonly Base[] {\n\t\tif (this.basesFound) return this.basesFound\n\t\tconst buildings = this.mine.buildings()\n\t\tconst reach = BASE_REACH * BASE_REACH\n\t\t// what takes deposits is the middle of a base; one within reach of an earlier one is of that base (a hall and what\n\t\t// stands on the mine beside it), not a base of its own\n\t\tconst centres: EntityState[] = []\n\t\tfor (const building of buildings) {\n\t\t\tif (!this.def(building).dropOff || centres.some((centre) => distSq(building, centre) < reach)) continue\n\t\t\tcentres.push(building)\n\t\t}\n\t\tconst members = new Map<number, EntityState[]>()\n\t\tfor (const centre of centres) members.set(centre.id, [])\n\t\tfor (const building of buildings) {\n\t\t\tlet best: EntityState | undefined\n\t\t\tlet bestDistance = reach\n\t\t\tfor (const centre of centres) {\n\t\t\t\tconst d = distSq(building, centre)\n\t\t\t\tif (d < bestDistance) {\n\t\t\t\t\tbestDistance = d\n\t\t\t\t\tbest = centre\n\t\t\t\t}\n\t\t\t}\n\t\t\t// too far from every base to be of one: a base of its own, around it\n\t\t\tif (!best) {\n\t\t\t\tbest = building\n\t\t\t\tcentres.push(building)\n\t\t\t\tmembers.set(building.id, [])\n\t\t\t}\n\t\t\tmembers.get(best.id)!.push(building)\n\t\t}\n\t\treturn (this.basesFound = centres.map((centre) => ({\n\t\t\tat: { x: centre.x, z: centre.z },\n\t\t\tcentre,\n\t\t\tbuildings: new UnitSet(this, members.get(centre.id))\n\t\t})))\n\t}\n\n\t/** The deposits near a base, in sight or remembered: what it gathers from */\n\tresourcesNear(base: Base | Vec2, radius = BASE_REACH): UnitSet {\n\t\treturn this.resources.near('at' in base ? base.at : base, radius)\n\t}\n\n\t/**\n\t * Where the game's money is mined, as the map shows them, under the fog too (`GameSession.mines`): what a computer\n\t * player looks to for another hall. Where the session does not say, the deposits of the money it knows of\n\t */\n\tmines(): readonly MineInfo[] {\n\t\tconst known = this.session.can.computer?.mines()\n\t\tif (known) return known\n\t\tconst money = this.registry.currency ?? this.registry.resources[0]?.id ?? ''\n\t\treturn this.resources.ofResource(money).map((mine) => ({ id: mine.id, x: mine.x, z: mine.z }))\n\t}\n\n\t/** The creep camps of the map: where they are is part of the map, which everyone knows */\n\tcamps(): readonly CampInfo[] {\n\t\treturn this.session.camps()\n\t}\n\n\t/**\n\t * The lanes of the map (`GameSession.lanes`: its paths with a spawner of each side at their ends), as the map shows\n\t * them: none where the session does not say, or the map has none. Read once a think\n\t */\n\tlanes(): readonly Lane[] {\n\t\treturn (this.lanesFound ??= this.session.can.computer?.lanes() ?? [])\n\t}\n\n\t/** The regions of the map, by name, as the map was made */\n\tget regions(): readonly MapRegion[] {\n\t\treturn this.session.regions\n\t}\n\n\t/** A region of the map, by name */\n\tregion(name: string): MapRegion | undefined {\n\t\treturn this.session.regions.find((region) => region.name === name)\n\t}\n\n\t/** Whether a point is in a named region of the map. False for a region the map does not have */\n\tinRegion(name: string, point: Vec2): boolean {\n\t\tconst region = this.region(name)\n\t\treturn !!region && inShape(region.shape, point)\n\t}\n\n\t/** An entity the map or the rules named (`world.named`), where the player knows of it: \"the gate\", \"the hero\" */\n\tnamed(name: string): EntityState | undefined {\n\t\treturn this.namesMap.get(name)\n\t}\n\n\t/** What the game replicates to this player of an entity (`Component.replicate`), with the component's type */\n\tcomponent<T, S = T>(entity: EntityState, component: Component<T, S>): S | undefined {\n\t\treturn entity.components?.[component.id] as S | undefined\n\t}\n\n\t/** Whether the player could build this here, as far as it can tell: no on ground it has not explored */\n\tcanPlace(unitType: string, point: Vec2): boolean {\n\t\treturn this.session.canPlace(unitType, point)\n\t}\n\n\t/** The value of one of the game's layers of cells at a point (`Terrain.cells`, `CellLayerDef`): 0 where it is not painted */\n\tcellAt(layer: string, x: number, z: number): number {\n\t\treturn this.session.terrain.cellAt(layer, x, z)\n\t}\n\n\t/** One of the game's layers of cells whole, row by row (`Terrain.cells`), to read and not to change: none where nothing is painted */\n\tcells(layer: string): Readonly<Uint8Array> | undefined {\n\t\treturn this.session.terrain.cells[layer]\n\t}\n\n\t/** The route a unit would take, over the ground the player knows */\n\tfindPath(from: Vec2, to: Vec2, flying?: boolean): Vec2[] | null {\n\t\treturn this.session.findPath(from, to, flying)\n\t}\n\n\t/** What the view found of the roles, for the debug tools: each role and its types among the player's own */\n\tinspect(): Record<string, unknown> {\n\t\tconst roles: Record<string, string[]> = {}\n\t\tfor (const [role, types] of Object.entries(this.roles.report())) {\n\t\t\tconst own = types.filter((type) => this.reachable.has(type))\n\t\t\tif (own.length) roles[role] = own\n\t\t}\n\t\treturn { roles }\n\t}\n}\n\n/** The player's own state out of the snapshot: empty where the snapshot has none (a seat out of the game) */\nfunction meOf(self: PlayerState | undefined, id: PlayerId): Me {\n\tconst own = self?.own\n\treturn {\n\t\tid,\n\t\tname: self?.name ?? '',\n\t\tteam: self?.team ?? 0,\n\t\t...(self?.race !== undefined && { race: self.race }),\n\t\tdefeated: self?.defeated ?? true,\n\t\tresources: own?.resources ?? {},\n\t\tsupplyUsed: own?.supplyUsed ?? 0,\n\t\tsupplyCap: own?.supplyCap ?? 0,\n\t\t...(own?.supplies && { supplies: own.supplies }),\n\t\tupkeep: own?.upkeep ?? { tier: 0, name: '', income: 1 },\n\t\tupgrades: own?.upgrades ?? {},\n\t\tresearching: own?.researching ?? [],\n\t\ttech: own?.tech ?? [],\n\t\theroes: own?.heroes ?? [],\n\t\tobjectives: own?.objectives ?? [],\n\t\t...(own?.unlocks && { unlocks: own.unlocks }),\n\t\t...(own?.availability && { availability: own.availability })\n\t}\n}\n\n/** Whether two of what the game's `available` hook decided are the same: by type, either left out as none */\nfunction sameAvailability(a: Record<string, boolean> | undefined, b: Record<string, boolean> | undefined): boolean {\n\tif (a === b) return true\n\tconst keys = Object.keys(a ?? {})\n\tif (keys.length !== Object.keys(b ?? {}).length) return false\n\treturn keys.every((key) => a![key] === b?.[key])\n}\n"],"mappings":"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"}
@@ -69,11 +69,13 @@ export interface WavesOptions {
69
69
  * @beta
70
70
  */
71
71
  export interface WavesMemory {
72
+ /** The version of the memory's format: 1 so far */
72
73
  v: 1;
73
74
  /** The index of the wave whose turn it is: the waves sent and skipped before it */
74
75
  index: number;
75
76
  /** Where in the list it is (for a list), and how many times the wave there went */
76
77
  entry: number;
78
+ /** How many times the wave at the entry has gone */
77
79
  went: number;
78
80
  /** The tick the last wave went at (or was skipped at): what the next one's `after` counts from */
79
81
  last: number;
@@ -95,13 +97,16 @@ export interface WavesMemory {
95
97
  * @beta
96
98
  */
97
99
  export interface WavesReport {
100
+ /** The index of the wave whose turn it is */
98
101
  index: number;
102
+ /** The wave whose turn it is: its units as free and wanted by type, seconds until it may go, whether it is ready and a status in words */
99
103
  current?: {
100
104
  units: Record<string, [free: number, wanted: number]>;
101
105
  in: number;
102
106
  ready: boolean;
103
107
  status: string;
104
108
  };
109
+ /** The waves sent, each with its index, squad, size, target and tick */
105
110
  sent: {
106
111
  index: number;
107
112
  squad: string;
@@ -109,6 +114,7 @@ export interface WavesReport {
109
114
  at: [number, number];
110
115
  tick: number;
111
116
  }[];
117
+ /** How many waves were skipped for a failing condition */
112
118
  skipped: number;
113
119
  }
114
120
  /**
@@ -0,0 +1,410 @@
1
+ import { distSq } from "../math.js";
2
+ import { defineModule } from "./module.js";
3
+ import { evaluate } from "./rules.js";
4
+ import { pair, point, where } from "./geometry.js";
5
+ import { Team } from "./team.js";
6
+ //#region src/ai/waves.ts
7
+ /** How far out of home towards the target a wave gathers, where it is not told */
8
+ var RALLY_OUT = 12;
9
+ /** How many sent waves the memory keeps */
10
+ var SENT_KEPT = 10;
11
+ /** The prefix of the wants of a wave's units, on the build plan */
12
+ var WANT = "waves.";
13
+ /** Whose the waves' squads are: their units held by the module until the wave is over */
14
+ var OWNER = "waves";
15
+ /**
16
+ * A brain's waves (`ai.waves`): the wave whose turn it is (`current`), what it is made of and how far along, the waves
17
+ * sent. Run by the `waves()` module each think; idle without waves given
18
+ *
19
+ * @internal
20
+ */
21
+ var Waves = class Waves {
22
+ ai;
23
+ /** What finds it on a brain (`ai.area(Waves)`): made the first time a module asks for it */
24
+ static id = "waves";
25
+ /** Makes the waves of a brain; what `ai.area(Waves)` calls the first time a module asks for it */
26
+ static make(ai) {
27
+ return new Waves(ai);
28
+ }
29
+ /** Its id among the brain's areas: what its memory and its report are kept under */
30
+ id = "waves";
31
+ /** What the log says where a save's memory of it is of a shape it does not read */
32
+ afresh = "the save remembers the computer player’s waves in a shape this brain does not read: they start afresh";
33
+ /** Whether a `waves()` module is in the brain */
34
+ enabled = false;
35
+ memory = {
36
+ v: 1,
37
+ index: 0,
38
+ entry: 0,
39
+ went: 0,
40
+ last: 0,
41
+ sent: [],
42
+ skipped: 0
43
+ };
44
+ moduleOptions = {};
45
+ thoughtAt = -1;
46
+ status = "no waves";
47
+ constructor(ai) {
48
+ this.ai = ai;
49
+ }
50
+ /**
51
+ * Puts the `waves()` module's options under the brain's settings; and while it has waves to send, the production
52
+ * plan's composition is left aside (what is trained is the waves' groups, wanted outright)
53
+ */
54
+ configure(options) {
55
+ this.moduleOptions = options;
56
+ this.enabled = true;
57
+ const { production } = this.ai.plans;
58
+ const before = production.settings.composition;
59
+ production.configure({ composition: ((brain) => {
60
+ if (brain.area(Waves).active) return {};
61
+ return typeof before === "function" ? before(brain) : before;
62
+ }) });
63
+ }
64
+ /** How it sends waves: the module's options, the brain's settings over them (`ai.settings.waves`), the groups of both */
65
+ get options() {
66
+ const settings = this.ai.settings.waves;
67
+ const groups = settings?.groups && this.moduleOptions.groups ? [...this.moduleOptions.groups, ...settings.groups] : void 0;
68
+ return {
69
+ ...this.moduleOptions,
70
+ ...settings,
71
+ ...groups && { groups }
72
+ };
73
+ }
74
+ /** Whether it was given waves: the module is in the brain, and waves were given it (all sent, or some to go) */
75
+ get given() {
76
+ return this.enabled && this.options.waves !== void 0;
77
+ }
78
+ /** Whether it has waves to send: given waves, and one whose turn it is. The melee player makes its own otherwise */
79
+ get active() {
80
+ return this.given && this.current() !== void 0;
81
+ }
82
+ /** The index of the wave whose turn it is: the waves sent and skipped before it (`{ wave }` in a condition) */
83
+ get index() {
84
+ return this.memory.index;
85
+ }
86
+ /** The wave whose turn it is: none when there are no (more) waves */
87
+ current() {
88
+ const { waves } = this.options;
89
+ if (!waves) return void 0;
90
+ if (typeof waves === "function") return waves(this.ai, this.memory.index);
91
+ return waves[this.memory.entry];
92
+ }
93
+ /** A wave's group as units by type or role: the group named, or the units given in place. None for a name not given */
94
+ groupOf(wave) {
95
+ if (typeof wave.group !== "string") return {
96
+ id: `wave ${this.memory.index + 1}`,
97
+ units: wave.group
98
+ };
99
+ return this.options.groups?.find((group) => group.id === wave.group);
100
+ }
101
+ /**
102
+ * Whether a unit counts as one of a key of a group: of the type by id where a type has the id, else of the role. A
103
+ * key that is both (the fixture's `soldier`) is the type: an archer, a soldier by role, is not one of `soldier: 4`
104
+ */
105
+ matches(unit, key) {
106
+ if (this.ai.registry.units.has(key)) return unit.type === key;
107
+ return this.ai.view.hasRole(unit, key);
108
+ }
109
+ /** The type trained for a key of a group: the type of that id, or the first of the role it can make */
110
+ typeFor(key) {
111
+ const { registry, view } = this.ai;
112
+ if (registry.units.has(key)) return registry.unit(key);
113
+ return view.typesOf(key).find((def) => def.kind === "unit");
114
+ }
115
+ /** The units free for a wave: in the pool (nothing holds them), idle or on their way to nothing, fighters */
116
+ free() {
117
+ return this.ai.squads.pool().fighters().where((unit) => unit.own?.order !== "harvest").items;
118
+ }
119
+ /** For each key of the group, the free units that count as it, at most as many as wanted, each unit once */
120
+ chosen(group) {
121
+ const taken = /* @__PURE__ */ new Set();
122
+ const by = /* @__PURE__ */ new Map();
123
+ const free = this.free();
124
+ for (const [key, count] of Object.entries(group.units)) {
125
+ const units = [];
126
+ for (const unit of free) {
127
+ if (units.length >= count) break;
128
+ if (taken.has(unit.id) || !this.matches(unit, key)) continue;
129
+ taken.add(unit.id);
130
+ units.push(unit);
131
+ }
132
+ by.set(key, units);
133
+ }
134
+ return by;
135
+ }
136
+ /** Where a wave goes, as its target says: their base nearest home when it says nothing. None where nothing is known */
137
+ targetOf(wave) {
138
+ const { ai } = this;
139
+ const target = wave.target ?? "nearestBase";
140
+ if (typeof target === "function") return target(ai);
141
+ if (typeof target === "object") return point(target);
142
+ const home = ai.view.home();
143
+ const from = home ? point(home) : {
144
+ x: 0,
145
+ z: 0
146
+ };
147
+ const knows = ai.def.knowledge !== false;
148
+ const bases = knows ? ai.knowledge.enemy.bases().filter((base) => !base.gone) : [];
149
+ const told = ai.options.enemyBases ?? [];
150
+ const nearest = (places) => places.reduce((best, each) => !best || distSq(each, from) < distSq(best, from) ? each : best, void 0);
151
+ switch (target) {
152
+ case "army": {
153
+ const army = knows ? ai.knowledge.enemy.armySeen()[0] : void 0;
154
+ if (army) return point(army.at);
155
+ break;
156
+ }
157
+ case "expansion": {
158
+ const expansion = nearest(bases.filter((base) => base.expansion).map((base) => base.at));
159
+ if (expansion) return point(expansion);
160
+ break;
161
+ }
162
+ case "weakestBase": {
163
+ const threat = ai.view.threat;
164
+ let best;
165
+ for (const base of bases) {
166
+ const score = threat.at(base.at, { remembered: true }).enemy;
167
+ if (!best || score < best.score) best = {
168
+ at: base.at,
169
+ score
170
+ };
171
+ }
172
+ if (best) return point(best.at);
173
+ break;
174
+ }
175
+ }
176
+ const known = nearest(bases.map((base) => base.at));
177
+ if (known) return point(known);
178
+ return told.length ? point(told[this.memory.index % told.length]) : void 0;
179
+ }
180
+ /** Where a wave gathers: the place given (by name or as a point), or a little out of home towards its target */
181
+ rallyOf(wave, target) {
182
+ const { ai } = this;
183
+ if (typeof wave.rally === "string") {
184
+ const named = ai.view.named(wave.rally);
185
+ return named ? point(named) : void 0;
186
+ }
187
+ if (wave.rally) return point(wave.rally);
188
+ const home = ai.view.home();
189
+ if (!home) return void 0;
190
+ if (!target) return point(home);
191
+ const dx = target.x - home.x;
192
+ const dz = target.z - home.z;
193
+ const length = Math.sqrt(dx * dx + dz * dz) || 1;
194
+ return {
195
+ x: home.x + dx / length * RALLY_OUT,
196
+ z: home.z + dz / length * RALLY_OUT
197
+ };
198
+ }
199
+ /**
200
+ * The think, once a think: the wave whose turn it is skipped where its condition fails; its group wanted of the
201
+ * production plan; once enough of it is free and its time has come, sent (a squad that gathers, then attacks), the
202
+ * next wave's turn begun. Without waves, nothing
203
+ */
204
+ think() {
205
+ const { ai } = this;
206
+ if (this.thoughtAt === ai.tick) return;
207
+ this.thoughtAt = ai.tick;
208
+ for (const squad of ai.squads.of(OWNER).squads) if (squad.idle) ai.squads.disband(squad, `wave over: ${squad.done ?? "idle"}`);
209
+ const wave = this.current();
210
+ if (!wave) {
211
+ this.dropWants();
212
+ this.status = this.options.waves ? "no more waves" : "no waves";
213
+ return;
214
+ }
215
+ const group = this.groupOf(wave);
216
+ if (!group) {
217
+ this.status = `no group "${String(wave.group)}"`;
218
+ if (!this.warned) {
219
+ this.warned = true;
220
+ ai.log.warn("ai", `a wave names the group "${String(wave.group)}", which no group is: it is skipped`);
221
+ }
222
+ this.next(true);
223
+ return;
224
+ }
225
+ if (wave.when && !evaluate(wave.when, ai) || group.when && !evaluate(group.when, ai)) {
226
+ ai.decide(`skips wave ${this.memory.index + 1}: its condition does not hold`, { kind: "waves" });
227
+ this.next(true);
228
+ return;
229
+ }
230
+ const chosen = this.chosen(group);
231
+ if (this.options.train ?? true) this.want(group, chosen);
232
+ const total = Object.values(group.units).reduce((sum, count) => sum + count, 0);
233
+ const have = [...chosen.values()].reduce((sum, units) => sum + units.length, 0);
234
+ const enough = Math.max(1, Math.ceil(total * Math.min(1, Math.max(0, wave.minForces ?? 1))));
235
+ const due = this.memory.last + Math.round((wave.after ?? 0) * ai.session.tickRate);
236
+ if (ai.tick < due) {
237
+ this.status = `waits ${Math.ceil((due - ai.tick) / ai.session.tickRate)} s more (${have} of ${total})`;
238
+ return;
239
+ }
240
+ if (have < enough) {
241
+ this.status = `builds up: ${have} of ${total}, ${enough} enough`;
242
+ return;
243
+ }
244
+ const target = this.targetOf(wave);
245
+ if (!target) {
246
+ this.status = "nowhere to go";
247
+ return;
248
+ }
249
+ let plan = wave.together && ai.area(Team).enabled ? ai.area(Team).plan : void 0;
250
+ if (wave.together && ai.area(Team).enabled) {
251
+ if (plan && !plan.joined.includes(ai.playerId) && ai.tick >= plan.at) plan = void 0;
252
+ if (!plan) plan = ai.area(Team).propose(target);
253
+ else if (!plan.joined.includes(ai.playerId)) ai.area(Team).join();
254
+ if (ai.tick < plan.at) {
255
+ this.status = `waits for its team: goes in ${Math.ceil((plan.at - ai.tick) / ai.session.tickRate)} s`;
256
+ return;
257
+ }
258
+ }
259
+ this.send(wave, chosen, plan?.target ?? target);
260
+ this.next(false);
261
+ }
262
+ warned = false;
263
+ /** The group's units wanted of the production plan: as many more of each type as the free ones fall short of */
264
+ want(group, chosen) {
265
+ const { ai } = this;
266
+ const keys = /* @__PURE__ */ new Set();
267
+ for (const [key, count] of Object.entries(group.units)) {
268
+ const type = this.typeFor(key);
269
+ if (!type) continue;
270
+ const id = `${WANT}${key}`;
271
+ keys.add(id);
272
+ const free = chosen.get(key)?.length ?? 0;
273
+ ai.plans.want({
274
+ id,
275
+ type: type.id,
276
+ count: ai.view.mine.ofType(type.id).length - free + count,
277
+ priority: this.options.priority ?? 30,
278
+ by: `wave ${this.memory.index + 1}`
279
+ });
280
+ }
281
+ for (const want of ai.plans.build.list()) if (want.id?.startsWith(WANT) && !keys.has(want.id)) ai.plans.drop(want.id);
282
+ }
283
+ /** The wants of a wave's units let go of */
284
+ dropWants() {
285
+ const { ai } = this;
286
+ for (const want of ai.plans.build.list()) if (want.id?.startsWith(WANT)) ai.plans.drop(want.id);
287
+ }
288
+ /** A wave sent: its units a squad that gathers at the rally, then attacks; said, noted, written down */
289
+ send(wave, chosen, target) {
290
+ const { ai } = this;
291
+ const units = [...chosen.values()].flat();
292
+ const index = this.memory.index + 1;
293
+ const name = `wave ${index}`;
294
+ const rally = this.rallyOf(wave, target) ?? target;
295
+ const squad = ai.squads.make(name, units, { owner: OWNER });
296
+ squad.gather(rally, {
297
+ minForces: wave.minForces ?? 1,
298
+ seconds: wave.gatherFor ?? 15,
299
+ then: {
300
+ kind: "attack",
301
+ data: { at: point(target) }
302
+ }
303
+ });
304
+ ai.knowledge.own.attackSent(target, units.length);
305
+ ai.area(Team).say("attacking");
306
+ const sent = {
307
+ index: this.memory.index,
308
+ squad: name,
309
+ size: units.length,
310
+ at: point(target),
311
+ tick: ai.tick
312
+ };
313
+ this.memory.sent.push(sent);
314
+ if (this.memory.sent.length > SENT_KEPT) this.memory.sent.splice(0, this.memory.sent.length - SENT_KEPT);
315
+ const made = [...chosen.entries()].filter(([, each]) => each.length).map(([key, each]) => `${each.length} ${key}`);
316
+ ai.decide(`sends wave ${index}: ${made.join(", ")}, gathering at ${where(rally)} for ${wave.gatherFor ?? 15} s, then at ${where(target)}`, { kind: "waves" });
317
+ this.status = `sent ${name}`;
318
+ return squad;
319
+ }
320
+ /** On to the next wave's turn: the same again where it repeats, else the next of the list */
321
+ next(skipped) {
322
+ const { memory } = this;
323
+ const wave = this.current();
324
+ memory.index++;
325
+ memory.last = this.ai.tick;
326
+ if (skipped) memory.skipped++;
327
+ const repeat = skipped ? false : wave?.repeat;
328
+ memory.went++;
329
+ if (repeat === true || typeof repeat === "number" && memory.went < repeat) return;
330
+ memory.entry++;
331
+ memory.went = 0;
332
+ }
333
+ /** The waves as the report shows them */
334
+ report() {
335
+ const { ai } = this;
336
+ const wave = this.enabled ? this.current() : void 0;
337
+ const group = wave && this.groupOf(wave);
338
+ const chosen = group ? this.chosen(group) : void 0;
339
+ const due = wave ? this.memory.last + Math.round((wave.after ?? 0) * ai.session.tickRate) : 0;
340
+ return {
341
+ index: this.memory.index,
342
+ ...wave && group && chosen && { current: {
343
+ units: Object.fromEntries(Object.entries(group.units).map(([key, count]) => [key, [chosen.get(key)?.length ?? 0, count]])),
344
+ in: Math.max(0, Math.ceil((due - ai.tick) / ai.session.tickRate)),
345
+ ready: this.status.startsWith("sent"),
346
+ status: this.status
347
+ } },
348
+ sent: this.memory.sent.map((each) => ({
349
+ index: each.index,
350
+ squad: each.squad,
351
+ size: each.size,
352
+ at: pair(each.at),
353
+ tick: each.tick
354
+ })),
355
+ skipped: this.memory.skipped
356
+ };
357
+ }
358
+ /** What it remembers, for a save: a copy */
359
+ /** Whether it has anything to remember now: one that does not is left out of a save */
360
+ remembers() {
361
+ return this.enabled;
362
+ }
363
+ /** Its part of the brain's report */
364
+ reportTo(report) {
365
+ if (this.enabled) report.waves = this.report();
366
+ }
367
+ /** Gives a copy of the waves' memory, for a save of the brain */
368
+ save() {
369
+ return structuredClone(this.memory);
370
+ }
371
+ /** Takes back what `save` gave: whether it was read */
372
+ restore(memory) {
373
+ const given = memory;
374
+ if (!given || typeof given !== "object" || given.v !== 1) return false;
375
+ this.memory = {
376
+ v: 1,
377
+ index: given.index ?? 0,
378
+ entry: given.entry ?? 0,
379
+ went: given.went ?? 0,
380
+ last: given.last ?? 0,
381
+ sent: structuredClone(given.sent ?? []),
382
+ skipped: given.skipped ?? 0
383
+ };
384
+ return true;
385
+ }
386
+ };
387
+ /**
388
+ * The waves module: the wave whose turn it is, each think (`ai.waves.think`): its group wanted, sent once enough of it is
389
+ * free and its time has come, gathering at the rally, then attacking. Idle without waves given. With how it sends waves
390
+ * where the brain's definition and the seat's options say nothing (`WavesOptions`)
391
+ *
392
+ * @beta
393
+ */
394
+ var waves = (options = {}) => defineModule({
395
+ id: "waves",
396
+ make: (ai) => {
397
+ ai.area(Waves).configure(options);
398
+ return {
399
+ id: "waves",
400
+ phase: "act",
401
+ after: ["goals"],
402
+ before: ["squads"],
403
+ think: () => ai.area(Waves).think()
404
+ };
405
+ }
406
+ });
407
+ //#endregion
408
+ export { Waves, waves };
409
+
410
+ //# sourceMappingURL=waves.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"waves.js","names":[],"sources":["../../src/ai/waves.ts"],"sourcesContent":["import type { UnitTypeDef } from '#engine/defs'\nimport { Team } from './team'\nimport type { AiArea } from './area'\nimport type { AiReport } from './report'\nimport { distSq, type Vec2 } from '#engine/math'\nimport type { EntityState } from '#engine/session/protocol'\nimport { type Brain } from './brain'\nimport { type AiModule, type AiModuleDef, defineModule } from './module'\nimport { type AiCondition, evaluate } from './rules'\nimport type { Squad } from './squads'\nimport { pair, point, where } from './geometry'\n\n/*\n * Attack groups and waves (AI plan, D2): the classic RTS attack data, made general. The melee player's waves were \"the\n * ready units, two more each time\": no say in what a wave is made of, when it goes, or where. A game, a map or a\n * mission says it here, as data:\n *\n * - **An attack group** (`AttackGroup`) is what a wave is made of: so many of each unit type or role (`{ footman: 4,\n * rifleman: 2 }`, `{ caster: 1 }`).\n * - **A wave** (`AttackWave`) names its group (or gives one in place), and says when it goes (`after` seconds from the\n * last wave, or from the start for the first; and `when`, a condition: a wave whose condition does not hold when its\n * turn comes is skipped), how much of the group is enough (`minForces`, a share), how long it gathers at the rally\n * before it goes (`gatherFor`), whether it goes again (`repeat`: for ever, or so many times), whether it waits for\n * its team to go together (`together`, C5), and where it goes (`target`: their nearest base, their weakest, an\n * expansion of theirs, their army as last seen, a place, or a function).\n * - **The waves module** (`waves()`) works on the wave whose turn it is: its group becomes **wants** of the production\n * plan (B3: the units are trained, and the buildings they need put up, as wants are), and nothing else of the army is\n * trained meanwhile (the composition left aside: a wave of four footmen and two riflemen trains exactly that); once\n * enough of it stands idle in the pool and its time has come, it is made a squad (`wave 1`, `wave 2`, …) that\n * **gathers** at the rally and then **attacks** (C1's tasks), and the next wave's turn begins.\n * - **Without waves** the melee player makes its own, as it always did (`waveSize` growing by two, the nearest base):\n * the module is there, and idle.\n *\n * The data forms are JSON (a map's file, `MapPlayer.data.ai.waves`; a seat's `AiOptions.waves` and `groups`); the waves\n * as a function (`(ai, index) => wave`) make them as the game goes. What the module remembers (whose turn it is, how many\n * times it went, the waves sent) is plain data in the brain's memory (`BrainMemory.waves`). `{ wave: … }` in a condition\n * (B2) is the index of the wave whose turn it is.\n */\n\n/**\n * What a wave is made of: so many of each unit type (by id) or role (`caster`, a game's own), by name, under a condition\n *\n * @beta\n */\nexport interface AttackGroup {\n\t/** Its name: what a wave names it by */\n\tid: string\n\t/** So many of each unit type or role: `{ footman: 4, rifleman: 2 }` */\n\tunits: Record<string, number>\n\t/** Only while this holds: a wave of a group whose condition fails is skipped as its own would be */\n\twhen?: AiCondition\n}\n\n/**\n * Where a wave goes: their base nearest home, their weakest (the fewest towers and army seen there), an expansion of\n * theirs, their army as last seen, a place, or a function of the brain\n *\n * @beta\n */\nexport type WaveTarget = 'nearestBase' | 'weakestBase' | 'expansion' | 'army' | Vec2 | ((ai: Brain) => Vec2 | undefined)\n\n/**\n * One wave (the classic attack wave): its group, when it goes, how much of it is enough, how long it gathers, whether it\n * goes again, together or not, and where to\n *\n * @beta\n */\nexport interface AttackWave {\n\t/** Its group: a group's name (`WavesOptions.groups`), or the units in place (`{ footman: 4 }`) */\n\tgroup: string | Record<string, number>\n\t/** Seconds after the wave before it (after the start, for the first) before it may go: 0 when left out */\n\tafter?: number\n\t/** The share of its group that is enough to go with, 0 to 1: all of it when left out */\n\tminForces?: number\n\t/** Seconds it gathers at the rally before it goes, whoever is late: 15 when left out */\n\tgatherFor?: number\n\t/** Whether it goes again once sent: `true` for ever, a number for so many times in all. Once when left out */\n\trepeat?: boolean | number\n\t/** Only when this holds as its turn comes: a wave whose condition fails is skipped */\n\twhen?: AiCondition\n\t/** Whether it waits for its team's attack together (`TeamOptions.together`, C5) */\n\ttogether?: boolean\n\t/** Where it goes: their base nearest home when left out */\n\ttarget?: WaveTarget\n\t/** Where it gathers: a place, or a name the map or the rules gave. A little out of home towards the target when left out */\n\trally?: Vec2 | string\n}\n\n/**\n * How a brain sends its waves (`BrainDef.waves`; the seat's `AiOptions.waves` and `groups`, the data of it, go over)\n *\n * @beta\n */\nexport interface WavesOptions {\n\t/** The groups waves are made of, by name */\n\tgroups?: AttackGroup[]\n\t/** The waves, in order, or a function giving the wave whose turn it is (by its index), none for no more */\n\twaves?: AttackWave[] | ((ai: Brain, index: number) => AttackWave | undefined)\n\t/** Whether a wave's group is trained (wants of the production plan): yes when left out. No for units that are given (a lanes game) */\n\ttrain?: boolean\n\t/** How important a wave's units are to the purse, as wants: 30 when left out (under a hall, a barracks, a hero) */\n\tpriority?: number\n}\n\n/**\n * What the waves module remembers between thinks, as a save keeps it\n *\n * @beta\n */\nexport interface WavesMemory {\n\t/** The version of the memory's format: 1 so far */\n\tv: 1\n\t/** The index of the wave whose turn it is: the waves sent and skipped before it */\n\tindex: number\n\t/** Where in the list it is (for a list), and how many times the wave there went */\n\tentry: number\n\t/** How many times the wave at the entry has gone */\n\twent: number\n\t/** The tick the last wave went at (or was skipped at): what the next one's `after` counts from */\n\tlast: number\n\t/** The waves sent, the last ten: index, squad, size, target, tick */\n\tsent: { index: number; squad: string; size: number; at: Vec2; tick: number }[]\n\t/** How many were skipped, their condition failing */\n\tskipped: number\n}\n\n/**\n * The waves as the report shows them (`AiReport.waves`): the wave whose turn it is, its group as it stands, when it may go;\n * the waves sent\n *\n * @beta\n */\nexport interface WavesReport {\n\t/** The index of the wave whose turn it is */\n\tindex: number\n\t/** The wave whose turn it is: its units as free and wanted by type, seconds until it may go, whether it is ready and a status in words */\n\tcurrent?: { units: Record<string, [free: number, wanted: number]>; in: number; ready: boolean; status: string }\n\t/** The waves sent, each with its index, squad, size, target and tick */\n\tsent: { index: number; squad: string; size: number; at: [number, number]; tick: number }[]\n\t/** How many waves were skipped for a failing condition */\n\tskipped: number\n}\n\n/** How far out of home towards the target a wave gathers, where it is not told */\nconst RALLY_OUT = 12\n/** How many sent waves the memory keeps */\nconst SENT_KEPT = 10\n/** The prefix of the wants of a wave's units, on the build plan */\nconst WANT = 'waves.'\n/** Whose the waves' squads are: their units held by the module until the wave is over */\nconst OWNER = 'waves'\n\n/**\n * A brain's waves (`ai.waves`): the wave whose turn it is (`current`), what it is made of and how far along, the waves\n * sent. Run by the `waves()` module each think; idle without waves given\n *\n * @internal\n */\nexport class Waves implements AiArea {\n\t/** What finds it on a brain (`ai.area(Waves)`): made the first time a module asks for it */\n\tstatic readonly id = 'waves'\n\t/** Makes the waves of a brain; what `ai.area(Waves)` calls the first time a module asks for it */\n\tstatic make(ai: Brain): Waves {\n\t\treturn new Waves(ai)\n\t}\n\t/** Its id among the brain's areas: what its memory and its report are kept under */\n\treadonly id = 'waves'\n\t/** What the log says where a save's memory of it is of a shape it does not read */\n\treadonly afresh = 'the save remembers the computer player’s waves in a shape this brain does not read: they start afresh'\n\n\t/** Whether a `waves()` module is in the brain */\n\tenabled = false\n\tprivate memory: WavesMemory = { v: 1, index: 0, entry: 0, went: 0, last: 0, sent: [], skipped: 0 }\n\tprivate moduleOptions: WavesOptions = {}\n\tprivate thoughtAt = -1\n\tprivate status = 'no waves'\n\n\tconstructor(\n\t\t/** The brain it sends waves for */\n\t\treadonly ai: Brain\n\t) {}\n\n\t/**\n\t * Puts the `waves()` module's options under the brain's settings; and while it has waves to send, the production\n\t * plan's composition is left aside (what is trained is the waves' groups, wanted outright)\n\t */\n\tconfigure(options: WavesOptions): void {\n\t\tthis.moduleOptions = options\n\t\tthis.enabled = true\n\t\tconst { production } = this.ai.plans\n\t\tconst before = production.settings.composition\n\t\tproduction.configure({\n\t\t\tcomposition: ((brain: Brain) => {\n\t\t\t\tif (brain.area(Waves).active) return {}\n\t\t\t\treturn typeof before === 'function' ? before(brain) : before\n\t\t\t}) as (ai: Brain) => Record<string, number>\n\t\t})\n\t}\n\n\t/** How it sends waves: the module's options, the brain's settings over them (`ai.settings.waves`), the groups of both */\n\tget options(): WavesOptions {\n\t\tconst settings = this.ai.settings.waves\n\t\tconst groups = settings?.groups && this.moduleOptions.groups ? [...this.moduleOptions.groups, ...settings.groups] : undefined\n\t\treturn { ...this.moduleOptions, ...settings, ...(groups && { groups }) }\n\t}\n\n\t/** Whether it was given waves: the module is in the brain, and waves were given it (all sent, or some to go) */\n\tget given(): boolean {\n\t\treturn this.enabled && this.options.waves !== undefined\n\t}\n\n\t/** Whether it has waves to send: given waves, and one whose turn it is. The melee player makes its own otherwise */\n\tget active(): boolean {\n\t\treturn this.given && this.current() !== undefined\n\t}\n\n\t/** The index of the wave whose turn it is: the waves sent and skipped before it (`{ wave }` in a condition) */\n\tget index(): number {\n\t\treturn this.memory.index\n\t}\n\n\t/** The wave whose turn it is: none when there are no (more) waves */\n\tcurrent(): AttackWave | undefined {\n\t\tconst { waves } = this.options\n\t\tif (!waves) return undefined\n\t\tif (typeof waves === 'function') return waves(this.ai, this.memory.index)\n\t\treturn waves[this.memory.entry]\n\t}\n\n\t/** A wave's group as units by type or role: the group named, or the units given in place. None for a name not given */\n\tgroupOf(wave: AttackWave): AttackGroup | undefined {\n\t\tif (typeof wave.group !== 'string') return { id: `wave ${this.memory.index + 1}`, units: wave.group }\n\t\treturn this.options.groups?.find((group) => group.id === wave.group)\n\t}\n\n\t/**\n\t * Whether a unit counts as one of a key of a group: of the type by id where a type has the id, else of the role. A\n\t * key that is both (the fixture's `soldier`) is the type: an archer, a soldier by role, is not one of `soldier: 4`\n\t */\n\tprivate matches(unit: EntityState, key: string): boolean {\n\t\tif (this.ai.registry.units.has(key)) return unit.type === key\n\t\treturn this.ai.view.hasRole(unit, key)\n\t}\n\n\t/** The type trained for a key of a group: the type of that id, or the first of the role it can make */\n\tprivate typeFor(key: string): UnitTypeDef | undefined {\n\t\tconst { registry, view } = this.ai\n\t\tif (registry.units.has(key)) return registry.unit(key)\n\t\treturn view.typesOf(key).find((def) => def.kind === 'unit')\n\t}\n\n\t/** The units free for a wave: in the pool (nothing holds them), idle or on their way to nothing, fighters */\n\tprivate free(): EntityState[] {\n\t\treturn this.ai.squads\n\t\t\t.pool()\n\t\t\t.fighters()\n\t\t\t.where((unit) => unit.own?.order !== 'harvest').items as EntityState[]\n\t}\n\n\t/** For each key of the group, the free units that count as it, at most as many as wanted, each unit once */\n\tprivate chosen(group: AttackGroup): Map<string, EntityState[]> {\n\t\tconst taken = new Set<number>()\n\t\tconst by = new Map<string, EntityState[]>()\n\t\tconst free = this.free()\n\t\tfor (const [key, count] of Object.entries(group.units)) {\n\t\t\tconst units: EntityState[] = []\n\t\t\tfor (const unit of free) {\n\t\t\t\tif (units.length >= count) break\n\t\t\t\tif (taken.has(unit.id) || !this.matches(unit, key)) continue\n\t\t\t\ttaken.add(unit.id)\n\t\t\t\tunits.push(unit)\n\t\t\t}\n\t\t\tby.set(key, units)\n\t\t}\n\t\treturn by\n\t}\n\n\t/** Where a wave goes, as its target says: their base nearest home when it says nothing. None where nothing is known */\n\ttargetOf(wave: AttackWave): Vec2 | undefined {\n\t\tconst { ai } = this\n\t\tconst target = wave.target ?? 'nearestBase'\n\t\tif (typeof target === 'function') return target(ai)\n\t\tif (typeof target === 'object') return point(target)\n\t\tconst home = ai.view.home()\n\t\tconst from = home ? point(home) : { x: 0, z: 0 }\n\t\tconst knows = ai.def.knowledge !== false\n\t\tconst bases = knows ? ai.knowledge.enemy.bases().filter((base) => !base.gone) : []\n\t\tconst told = ai.options.enemyBases ?? []\n\t\tconst nearest = (places: readonly Vec2[]) =>\n\t\t\tplaces.reduce<Vec2 | undefined>((best, each) => (!best || distSq(each, from) < distSq(best, from) ? each : best), undefined)\n\t\tswitch (target) {\n\t\t\tcase 'army': {\n\t\t\t\tconst army = knows ? ai.knowledge.enemy.armySeen()[0] : undefined\n\t\t\t\tif (army) return point(army.at)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'expansion': {\n\t\t\t\tconst expansion = nearest(bases.filter((base) => base.expansion).map((base) => base.at))\n\t\t\t\tif (expansion) return point(expansion)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'weakestBase': {\n\t\t\t\t// the fewest of their buildings that shoot remembered there, and the least of their strength seen near it\n\t\t\t\tconst threat = ai.view.threat\n\t\t\t\tlet best: { at: Vec2; score: number } | undefined\n\t\t\t\tfor (const base of bases) {\n\t\t\t\t\tconst score = threat.at(base.at, { remembered: true }).enemy\n\t\t\t\t\tif (!best || score < best.score) best = { at: base.at, score }\n\t\t\t\t}\n\t\t\t\tif (best) return point(best.at)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tconst known = nearest(bases.map((base) => base.at))\n\t\tif (known) return point(known)\n\t\treturn told.length ? point(told[this.memory.index % told.length]) : undefined\n\t}\n\n\t/** Where a wave gathers: the place given (by name or as a point), or a little out of home towards its target */\n\trallyOf(wave: AttackWave, target: Vec2 | undefined): Vec2 | undefined {\n\t\tconst { ai } = this\n\t\tif (typeof wave.rally === 'string') {\n\t\t\tconst named = ai.view.named(wave.rally)\n\t\t\treturn named ? point(named) : undefined\n\t\t}\n\t\tif (wave.rally) return point(wave.rally)\n\t\tconst home = ai.view.home()\n\t\tif (!home) return undefined\n\t\tif (!target) return point(home)\n\t\tconst dx = target.x - home.x\n\t\tconst dz = target.z - home.z\n\t\tconst length = Math.sqrt(dx * dx + dz * dz) || 1\n\t\treturn { x: home.x + (dx / length) * RALLY_OUT, z: home.z + (dz / length) * RALLY_OUT }\n\t}\n\n\t/**\n\t * The think, once a think: the wave whose turn it is skipped where its condition fails; its group wanted of the\n\t * production plan; once enough of it is free and its time has come, sent (a squad that gathers, then attacks), the\n\t * next wave's turn begun. Without waves, nothing\n\t */\n\tthink(): void {\n\t\tconst { ai } = this\n\t\tif (this.thoughtAt === ai.tick) return\n\t\tthis.thoughtAt = ai.tick\n\t\t// the waves that are done (cleared, fallen back, or wiped) let go of: their units back to the pool for the next\n\t\tfor (const squad of ai.squads.of(OWNER).squads) if (squad.idle) ai.squads.disband(squad, `wave over: ${squad.done ?? 'idle'}`)\n\t\tconst wave = this.current()\n\t\tif (!wave) {\n\t\t\tthis.dropWants()\n\t\t\tthis.status = this.options.waves ? 'no more waves' : 'no waves'\n\t\t\treturn\n\t\t}\n\t\tconst group = this.groupOf(wave)\n\t\tif (!group) {\n\t\t\tthis.status = `no group \"${String(wave.group)}\"`\n\t\t\tif (!this.warned) {\n\t\t\t\tthis.warned = true\n\t\t\t\tai.log.warn('ai', `a wave names the group \"${String(wave.group)}\", which no group is: it is skipped`)\n\t\t\t}\n\t\t\tthis.next(true)\n\t\t\treturn\n\t\t}\n\t\tif ((wave.when && !evaluate(wave.when, ai)) || (group.when && !evaluate(group.when, ai))) {\n\t\t\tai.decide(`skips wave ${this.memory.index + 1}: its condition does not hold`, { kind: 'waves' })\n\t\t\tthis.next(true)\n\t\t\treturn\n\t\t}\n\t\tconst chosen = this.chosen(group)\n\t\tif (this.options.train ?? true) this.want(group, chosen)\n\t\tconst total = Object.values(group.units).reduce((sum, count) => sum + count, 0)\n\t\tconst have = [...chosen.values()].reduce((sum, units) => sum + units.length, 0)\n\t\tconst enough = Math.max(1, Math.ceil(total * Math.min(1, Math.max(0, wave.minForces ?? 1))))\n\t\tconst due = this.memory.last + Math.round((wave.after ?? 0) * ai.session.tickRate)\n\t\tif (ai.tick < due) {\n\t\t\tthis.status = `waits ${Math.ceil((due - ai.tick) / ai.session.tickRate)} s more (${have} of ${total})`\n\t\t\treturn\n\t\t}\n\t\tif (have < enough) {\n\t\t\tthis.status = `builds up: ${have} of ${total}, ${enough} enough`\n\t\t\treturn\n\t\t}\n\t\tconst target = this.targetOf(wave)\n\t\tif (!target) {\n\t\t\tthis.status = 'nowhere to go'\n\t\t\treturn\n\t\t}\n\t\t// with its team, at the time the team's plan says (C5): the plan standing joined (one whose time went by unjoined\n\t\t// is too late to join), or a plan proposed; the wave waits for its time\n\t\tlet plan = wave.together && ai.area(Team).enabled ? ai.area(Team).plan : undefined\n\t\tif (wave.together && ai.area(Team).enabled) {\n\t\t\tif (plan && !plan.joined.includes(ai.playerId) && ai.tick >= plan.at) plan = undefined\n\t\t\tif (!plan) plan = ai.area(Team).propose(target)\n\t\t\telse if (!plan.joined.includes(ai.playerId)) ai.area(Team).join()\n\t\t\tif (ai.tick < plan.at) {\n\t\t\t\tthis.status = `waits for its team: goes in ${Math.ceil((plan.at - ai.tick) / ai.session.tickRate)} s`\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tthis.send(wave, chosen, plan?.target ?? target)\n\t\tthis.next(false)\n\t}\n\n\tprivate warned = false\n\n\t/** The group's units wanted of the production plan: as many more of each type as the free ones fall short of */\n\tprivate want(group: AttackGroup, chosen: Map<string, EntityState[]>): void {\n\t\tconst { ai } = this\n\t\tconst keys = new Set<string>()\n\t\tfor (const [key, count] of Object.entries(group.units)) {\n\t\t\tconst type = this.typeFor(key)\n\t\t\tif (!type) continue\n\t\t\tconst id = `${WANT}${key}`\n\t\t\tkeys.add(id)\n\t\t\tconst free = chosen.get(key)?.length ?? 0\n\t\t\t// those it has of the type, less the free ones counted, and the group's: what is out or busy stays out of it. A\n\t\t\t// number, worked out each think: plain data, so that a save keeps the want and a loaded game trains alike\n\t\t\tai.plans.want({\n\t\t\t\tid,\n\t\t\t\ttype: type.id,\n\t\t\t\tcount: ai.view.mine.ofType(type.id).length - free + count,\n\t\t\t\tpriority: this.options.priority ?? 30,\n\t\t\t\tby: `wave ${this.memory.index + 1}`\n\t\t\t})\n\t\t}\n\t\tfor (const want of ai.plans.build.list()) if (want.id?.startsWith(WANT) && !keys.has(want.id)) ai.plans.drop(want.id)\n\t}\n\n\t/** The wants of a wave's units let go of */\n\tprivate dropWants(): void {\n\t\tconst { ai } = this\n\t\tfor (const want of ai.plans.build.list()) if (want.id?.startsWith(WANT)) ai.plans.drop(want.id)\n\t}\n\n\t/** A wave sent: its units a squad that gathers at the rally, then attacks; said, noted, written down */\n\tprivate send(wave: AttackWave, chosen: Map<string, EntityState[]>, target: Vec2): Squad {\n\t\tconst { ai } = this\n\t\tconst units = [...chosen.values()].flat()\n\t\tconst index = this.memory.index + 1\n\t\tconst name = `wave ${index}`\n\t\tconst rally = this.rallyOf(wave, target) ?? target\n\t\tconst squad = ai.squads.make(name, units, { owner: OWNER })\n\t\tsquad.gather(rally, { minForces: wave.minForces ?? 1, seconds: wave.gatherFor ?? 15, then: { kind: 'attack', data: { at: point(target) } } })\n\t\tai.knowledge.own.attackSent(target, units.length)\n\t\tai.area(Team).say('attacking')\n\t\tconst sent = { index: this.memory.index, squad: name, size: units.length, at: point(target), tick: ai.tick }\n\t\tthis.memory.sent.push(sent)\n\t\tif (this.memory.sent.length > SENT_KEPT) this.memory.sent.splice(0, this.memory.sent.length - SENT_KEPT)\n\t\tconst made = [...chosen.entries()].filter(([, each]) => each.length).map(([key, each]) => `${each.length} ${key}`)\n\t\tai.decide(`sends wave ${index}: ${made.join(', ')}, gathering at ${where(rally)} for ${wave.gatherFor ?? 15} s, then at ${where(target)}`, {\n\t\t\tkind: 'waves'\n\t\t})\n\t\tthis.status = `sent ${name}`\n\t\treturn squad\n\t}\n\n\t/** On to the next wave's turn: the same again where it repeats, else the next of the list */\n\tprivate next(skipped: boolean): void {\n\t\tconst { memory } = this\n\t\tconst wave = this.current()\n\t\tmemory.index++\n\t\tmemory.last = this.ai.tick\n\t\tif (skipped) memory.skipped++\n\t\tconst repeat = skipped ? false : wave?.repeat\n\t\tmemory.went++\n\t\tif (repeat === true || (typeof repeat === 'number' && memory.went < repeat)) return\n\t\tmemory.entry++\n\t\tmemory.went = 0\n\t}\n\n\t/** The waves as the report shows them */\n\treport(): WavesReport {\n\t\tconst { ai } = this\n\t\tconst wave = this.enabled ? this.current() : undefined\n\t\tconst group = wave && this.groupOf(wave)\n\t\tconst chosen = group ? this.chosen(group) : undefined\n\t\tconst due = wave ? this.memory.last + Math.round((wave.after ?? 0) * ai.session.tickRate) : 0\n\t\treturn {\n\t\t\tindex: this.memory.index,\n\t\t\t...(wave &&\n\t\t\t\tgroup &&\n\t\t\t\tchosen && {\n\t\t\t\t\tcurrent: {\n\t\t\t\t\t\tunits: Object.fromEntries(Object.entries(group.units).map(([key, count]) => [key, [chosen.get(key)?.length ?? 0, count]])) as Record<\n\t\t\t\t\t\t\tstring,\n\t\t\t\t\t\t\t[number, number]\n\t\t\t\t\t\t>,\n\t\t\t\t\t\tin: Math.max(0, Math.ceil((due - ai.tick) / ai.session.tickRate)),\n\t\t\t\t\t\tready: this.status.startsWith('sent'),\n\t\t\t\t\t\tstatus: this.status\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\tsent: this.memory.sent.map((each) => ({ index: each.index, squad: each.squad, size: each.size, at: pair(each.at), tick: each.tick })),\n\t\t\tskipped: this.memory.skipped\n\t\t}\n\t}\n\n\t/** What it remembers, for a save: a copy */\n\t/** Whether it has anything to remember now: one that does not is left out of a save */\n\tremembers(): boolean {\n\t\treturn this.enabled\n\t}\n\n\t/** Its part of the brain's report */\n\treportTo(report: AiReport): void {\n\t\tif (this.enabled) report.waves = this.report()\n\t}\n\n\t/** Gives a copy of the waves' memory, for a save of the brain */\n\tsave(): WavesMemory {\n\t\treturn structuredClone(this.memory)\n\t}\n\n\t/** Takes back what `save` gave: whether it was read */\n\trestore(memory: unknown): boolean {\n\t\tconst given = memory as WavesMemory | undefined\n\t\tif (!given || typeof given !== 'object' || given.v !== 1) return false\n\t\tthis.memory = {\n\t\t\tv: 1,\n\t\t\tindex: given.index ?? 0,\n\t\t\tentry: given.entry ?? 0,\n\t\t\twent: given.went ?? 0,\n\t\t\tlast: given.last ?? 0,\n\t\t\tsent: structuredClone(given.sent ?? []),\n\t\t\tskipped: given.skipped ?? 0\n\t\t}\n\t\treturn true\n\t}\n}\n\n/**\n * The waves module: the wave whose turn it is, each think (`ai.waves.think`): its group wanted, sent once enough of it is\n * free and its time has come, gathering at the rally, then attacking. Idle without waves given. With how it sends waves\n * where the brain's definition and the seat's options say nothing (`WavesOptions`)\n *\n * @beta\n */\nexport const waves = (options: WavesOptions = {}): AiModuleDef =>\n\tdefineModule({ id: 'waves', make: (ai: Brain): AiModule => {\n\t\tai.area(Waves).configure(options)\n\t\treturn {\n\t\t\tid: 'waves',\n\t\t\tphase: 'act',\n\t\t\tafter: ['goals'],\n\t\t\tbefore: ['squads'],\n\t\t\tthink: () => ai.area(Waves).think()\n\t\t}\n\t} })\n\ndeclare module './area' {\n\tinterface AreaMemories {\n\t\twaves?: WavesMemory\n\t}\n}\n"],"mappings":"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"}