@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,297 @@
1
+ import { cos, hypot, sin } from "./exactMath.js";
2
+ //#region src/formation.ts
3
+ var GAP = .35;
4
+ /**
5
+ * The gap between two units standing next to each other in a formation
6
+ *
7
+ * @beta
8
+ */
9
+ var FORMATION_GAP = GAP;
10
+ /** The places of a shape in the world, each snapped onto where a unit can stand */
11
+ function placed(context, shape) {
12
+ return shape.map(({ x, z }) => context.snap(context.place(x, z)));
13
+ }
14
+ /**
15
+ * Fits units to places so that their ways cross as little as can be: the places in order, the front first, each to
16
+ * the unit nearest it, measured from where the group is to where it goes (the unit's place in the group against the
17
+ * place's in the formation). A unit left without a place goes to the target
18
+ *
19
+ * @beta
20
+ */
21
+ function fitToPlaces(context, places) {
22
+ const { units, centre, target } = context;
23
+ const points = /* @__PURE__ */ new Map();
24
+ const left = [...units].sort((a, b) => a.id - b.id);
25
+ for (const place of places) {
26
+ if (left.length === 0) break;
27
+ const px = place.x - target.x;
28
+ const pz = place.z - target.z;
29
+ let nearest = 0;
30
+ let best = Infinity;
31
+ for (let i = 0; i < left.length; i++) {
32
+ const unit = left[i];
33
+ const d = hypot(unit.pos.x - centre.x - px, unit.pos.z - centre.z - pz);
34
+ if (d < best) {
35
+ best = d;
36
+ nearest = i;
37
+ }
38
+ }
39
+ points.set(left[nearest].id, place);
40
+ left.splice(nearest, 1);
41
+ }
42
+ for (const unit of left) points.set(unit.id, target);
43
+ return points;
44
+ }
45
+ /**
46
+ * The engine's usual formation: a tight group keeps its shape as it is, and a scattered one lines up in rows across
47
+ * the way of travel, as many across as there are rows, the units ahead in the front rows
48
+ *
49
+ * @beta
50
+ */
51
+ var rowsFormation = {
52
+ id: "rows",
53
+ name: "Rows",
54
+ points(context) {
55
+ const { units, target, centre, spacing, forward, right, snap } = context;
56
+ const points = /* @__PURE__ */ new Map();
57
+ let spread = 0;
58
+ for (const unit of units) spread = Math.max(spread, hypot(unit.pos.x - centre.x, unit.pos.z - centre.z));
59
+ const travel = hypot(target.x - centre.x, target.z - centre.z);
60
+ const compact = spacing * Math.sqrt(units.length);
61
+ if (spread <= compact && travel > spread && !context.turned) {
62
+ for (const unit of units) points.set(unit.id, snap({
63
+ x: target.x + unit.pos.x - centre.x,
64
+ z: target.z + unit.pos.z - centre.z
65
+ }));
66
+ return points;
67
+ }
68
+ const columns = Math.ceil(Math.sqrt(units.length));
69
+ const rows = Math.ceil(units.length / columns);
70
+ const ahead = (u) => (u.pos.x - centre.x) * forward.x + (u.pos.z - centre.z) * forward.z;
71
+ const sideways = (u) => (u.pos.x - centre.x) * right.x + (u.pos.z - centre.z) * right.z;
72
+ const ordered = [...units].sort((a, b) => ahead(b) - ahead(a) || a.id - b.id);
73
+ for (let row = 0; row < rows; row++) {
74
+ const members = ordered.slice(row * columns, (row + 1) * columns).sort((a, b) => sideways(a) - sideways(b) || a.id - b.id);
75
+ const back = (row - (rows - 1) / 2) * spacing;
76
+ for (let i = 0; i < members.length; i++) {
77
+ const side = (i - (members.length - 1) / 2) * spacing;
78
+ points.set(members[i].id, snap(context.place(side, -back)));
79
+ }
80
+ }
81
+ return points;
82
+ }
83
+ };
84
+ /** How many places a ring of a radius has room for, `spacing` apart */
85
+ var ringRoom = (radius, spacing) => Math.max(Math.floor(2 * Math.PI * radius / spacing), 1);
86
+ /**
87
+ * How many places each ring of a disc gets, the middle first (one), then the rings a `spacing` apart: as few rings as
88
+ * hold them all, and the places shared out among the rings as their room goes, so that the disc is as thick
89
+ * everywhere, filled to the middle, rather than full outer rings round a hollow. The places left over by the share go
90
+ * to the biggest remainders, the outer ring of two first. A few that the outer ring holds alone (up to 12) stand on it
91
+ */
92
+ function ringCounts(count, spacing) {
93
+ const room = [1];
94
+ let held = 1;
95
+ while (held < count) {
96
+ const on = ringRoom(room.length * spacing, spacing);
97
+ room.push(on);
98
+ held += on;
99
+ }
100
+ if (count <= room[room.length - 1]) return room.map((_, i) => i === room.length - 1 ? count : 0);
101
+ const counts = room.map((on) => Math.floor(count * on / held));
102
+ let left = count - counts.reduce((sum, on) => sum + on, 0);
103
+ const order = room.map((_, i) => i).sort((a, b) => count * room[b] % held - count * room[a] % held || b - a);
104
+ for (const i of order) {
105
+ if (left === 0) break;
106
+ if (counts[i] < room[i]) {
107
+ counts[i]++;
108
+ left--;
109
+ }
110
+ }
111
+ return counts;
112
+ }
113
+ /** The places of a ring, evenly, the first at the front, clockwise */
114
+ function circleRing(radius, on) {
115
+ const places = [];
116
+ for (let i = 0; i < on; i++) {
117
+ const angle = i / on * 2 * Math.PI;
118
+ places.push({
119
+ x: radius * sin(angle),
120
+ z: radius * cos(angle)
121
+ });
122
+ }
123
+ return places;
124
+ }
125
+ /**
126
+ * A circle: a ring around the target, the first place at the front, and rings within it where one is not enough for
127
+ * them all, a `spacing` apart, down to the middle. As few rings as hold them, and the units shared out among them as
128
+ * their room goes: a disc as thick everywhere, every ring's places even, the outer ring first
129
+ *
130
+ * @beta
131
+ */
132
+ var circleFormation = {
133
+ id: "circle",
134
+ name: "Circle",
135
+ shape(count, spacing) {
136
+ const counts = ringCounts(count, spacing);
137
+ const places = [];
138
+ for (let i = counts.length - 1; i >= 1; i--) places.push(...circleRing(i * spacing, counts[i]));
139
+ if (counts[0] > 0) places.push({
140
+ x: 0,
141
+ z: 0
142
+ });
143
+ return places;
144
+ }
145
+ };
146
+ /**
147
+ * A square: a block of rows a `spacing` apart, as many across as deep (one row fewer where that holds them), filled to
148
+ * the middle, the front row first. Where they do not fill the last row, the back one, those in it stand in its middle
149
+ *
150
+ * @beta
151
+ */
152
+ var squareFormation = {
153
+ id: "square",
154
+ name: "Square",
155
+ shape(count, spacing) {
156
+ const across = Math.ceil(Math.sqrt(count));
157
+ const deep = Math.ceil(count / across);
158
+ const places = [];
159
+ for (let row = 0; row < deep; row++) {
160
+ const on = Math.min(across, count - row * across);
161
+ const z = ((deep - 1) / 2 - row) * spacing;
162
+ for (let i = 0; i < on; i++) places.push({
163
+ x: (i - (on - 1) / 2) * spacing,
164
+ z
165
+ });
166
+ }
167
+ return places;
168
+ }
169
+ };
170
+ /**
171
+ * No formation: every unit to the point itself, as units sent one by one go
172
+ *
173
+ * @beta
174
+ */
175
+ var noneFormation = {
176
+ id: "none",
177
+ name: "None",
178
+ shape: (count) => Array.from({ length: count }, () => ({
179
+ x: 0,
180
+ z: 0
181
+ }))
182
+ };
183
+ /**
184
+ * The engine's formations: `rows` (the usual), `circle`, `square` and `none`
185
+ *
186
+ * @beta
187
+ */
188
+ var coreFormations = [
189
+ rowsFormation,
190
+ circleFormation,
191
+ squareFormation,
192
+ noneFormation
193
+ ];
194
+ /**
195
+ * What a formation is laid out with, for a group sent to a target on a navigation
196
+ *
197
+ * @internal
198
+ */
199
+ function formationContext(world, units, target, nav, facing) {
200
+ let cx = 0;
201
+ let cz = 0;
202
+ let radius = 0;
203
+ for (const unit of units) {
204
+ cx += unit.pos.x;
205
+ cz += unit.pos.z;
206
+ radius = Math.max(radius, unit.def.radius);
207
+ }
208
+ cx /= units.length;
209
+ cz /= units.length;
210
+ const travel = hypot(target.x - cx, target.z - cz);
211
+ const forward = facing !== void 0 ? {
212
+ x: sin(facing),
213
+ z: cos(facing)
214
+ } : {
215
+ x: travel > .001 ? (target.x - cx) / travel : 0,
216
+ z: travel > .001 ? (target.z - cz) / travel : 1
217
+ };
218
+ const right = {
219
+ x: forward.z,
220
+ z: -forward.x
221
+ };
222
+ return {
223
+ world,
224
+ units,
225
+ target,
226
+ nav,
227
+ centre: {
228
+ x: cx,
229
+ z: cz
230
+ },
231
+ forward,
232
+ right,
233
+ turned: facing !== void 0,
234
+ spacing: radius * 2 + GAP,
235
+ place: (x, z) => ({
236
+ x: target.x + right.x * x + forward.x * z,
237
+ z: target.z + right.z * x + forward.z * z
238
+ }),
239
+ snap: (p) => nav.closestPoint(p, 4) ?? target
240
+ };
241
+ }
242
+ /**
243
+ * Individual destinations for a group ordered to the same point, in a formation (`rowsFormation` when none is
244
+ * given), and what the `formation` hook makes of them. Units that walk and units that fly are laid out apart, each
245
+ * on their own navigation (`world.navFor`). `facing`, where the player turned the formation by hand, is the way it
246
+ * faces (a direction as an entity's `facing` is), over the way of travel
247
+ *
248
+ * @beta
249
+ */
250
+ function formationPoints(world, units, target, formation = rowsFormation, facing) {
251
+ if (units.length === 0) return /* @__PURE__ */ new Map();
252
+ const context = formationContext(world, units, target, world.navFor(units[0]), facing);
253
+ let points;
254
+ if (units.length === 1) points = /* @__PURE__ */ new Map([[units[0].id, target]]);
255
+ else if (formation.points) points = formation.points(context);
256
+ else if (formation.shape) points = fitToPlaces(context, placed(context, formation.shape(units.length, context.spacing, context)));
257
+ else throw new Error(`The formation "${formation.id}" has neither a shape nor points`);
258
+ if (world.hooks.has("formation")) world.hooks.run("formation", {
259
+ units,
260
+ target,
261
+ formation,
262
+ points
263
+ });
264
+ return points;
265
+ }
266
+ /**
267
+ * Where a group would stand if sent to a target in a formation (by id, `rows` when unknown), from what a player's
268
+ * screen knows of the units: what the ghosts of a right-click dragged are drawn from (`GameSession.formationPlaces`).
269
+ * The same shapes as `formationPoints` gives, units that walk and units that fly each on their own navigation; the
270
+ * `formation` hook (the simulation's) and a formation that reads `FormationContext.world` take no part, and the order
271
+ * itself lays the group out as it will
272
+ *
273
+ * @beta
274
+ */
275
+ function formationPreview(registry, units, target, navs, id, facing) {
276
+ const formation = registry.formations.has(id) ? registry.formation(id) : rowsFormation;
277
+ const places = /* @__PURE__ */ new Map();
278
+ for (const flying of [false, true]) {
279
+ const group = units.filter((unit) => !!unit.flying === flying);
280
+ if (group.length === 0) continue;
281
+ if (group.length === 1) places.set(group[0].id, target);
282
+ else {
283
+ const context = formationContext(void 0, group.map((unit) => ({
284
+ id: unit.id,
285
+ pos: unit.pos,
286
+ def: { radius: unit.radius }
287
+ })), target, flying ? navs.air : navs.nav, facing);
288
+ const found = formation.points ? formation.points(context) : fitToPlaces(context, placed(context, formation.shape(group.length, context.spacing, context)));
289
+ for (const [unit, place] of found) places.set(unit, place);
290
+ }
291
+ }
292
+ return places;
293
+ }
294
+ //#endregion
295
+ export { FORMATION_GAP, circleFormation, coreFormations, fitToPlaces, formationContext, formationPoints, formationPreview, noneFormation, rowsFormation, squareFormation };
296
+
297
+ //# sourceMappingURL=formation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formation.js","names":[],"sources":["../src/formation.ts"],"sourcesContent":["import type { Entity, EntityId } from './entity'\nimport type { Vec2 } from './math'\nimport type { Navigation } from './navigation/navigation'\nimport type { Registry } from './registry'\nimport type { World } from './world'\nimport { cos, hypot, sin } from './exactMath'\n\nconst GAP = 0.35\n\n/**\n * What a formation lays units out with: the group, where it is sent, the way there, and the room each unit takes.\n * Points are in the world; `right` and `forward` are the formation's own axes, each a unit long, for a shape that is\n * drawn facing the way of travel: a place `right * x + forward * z` from the target\n *\n * @beta\n */\nexport interface FormationContext {\n\t/** The world the formation is laid out in */\n\treadonly world: World\n\t/** The units laid out: those that walk, or those that fly, apart */\n\treadonly units: readonly Entity[]\n\t/** Where the units are sent */\n\treadonly target: Vec2\n\t/** The navigation they go on, to find where they can stand */\n\treadonly nav: Navigation\n\t/** The middle of where the units are */\n\treadonly centre: Vec2\n\t/** The way from where they are to the target, a unit long (forward, where they face at the end) */\n\treadonly forward: Vec2\n\t/** To the right of `forward`, a unit long */\n\treadonly right: Vec2\n\t/**\n\t * Whether the player turned the formation by hand (a right-click dragged: `OrderInit.facing`): `forward` is then\n\t * the way they dragged, not the way of travel, and a formation that keeps a group's own shape lays it out anew\n\t */\n\treadonly turned: boolean\n\t/** Room a unit takes: twice the biggest radius among them, and a gap of `FORMATION_GAP` */\n\treadonly spacing: number\n\t/** A point in the world, `x` to the right of the target and `z` forward of it */\n\tplace(x: number, z: number): Vec2\n\t/** The nearest point a unit can stand on, or the target where there is none within 4 */\n\tsnap(point: Vec2): Vec2\n}\n\n/**\n * How units ordered to a point together are laid out around it (`OrderInit.formation`, `RuleSettings.movement.formation`): a\n * shape, which the engine fits the units to, or the places themselves. The engine's own are `rows`, `circle`,\n * `square` and `none` (`coreFormations`); a game adds its own (`Rules.formations`), and changes any laid out\n * with the `formation` hook\n *\n * @beta\n */\nexport interface FormationDef {\n\t/** The formation's id, which an order names it by */\n\tid: string\n\t/** What the player sees it called */\n\tname: string\n\t/**\n\t * The shape, as `count` places `spacing` apart, in the formation's own space: `x` to the right, `z` forward, the\n\t * first places at the front. Units are fitted to them so that their ways cross as little as can be\n\t * (`fitToPlaces`): those ahead to the places at the front\n\t */\n\tshape?(count: number, spacing: number, context: FormationContext): Vec2[]\n\t/**\n\t * The places themselves, by the unit's id, when the shape is not enough: one that goes by who the units are, or\n\t * where they stand. A unit given none goes to the target itself. Over `shape` where both are given\n\t */\n\tpoints?(context: FormationContext): Map<EntityId, Vec2>\n}\n\n/**\n * The gap between two units standing next to each other in a formation\n *\n * @beta\n */\nexport const FORMATION_GAP = GAP\n\n/** The places of a shape in the world, each snapped onto where a unit can stand */\nfunction placed(context: FormationContext, shape: readonly Vec2[]): Vec2[] {\n\treturn shape.map(({ x, z }) => context.snap(context.place(x, z)))\n}\n\n/**\n * Fits units to places so that their ways cross as little as can be: the places in order, the front first, each to\n * the unit nearest it, measured from where the group is to where it goes (the unit's place in the group against the\n * place's in the formation). A unit left without a place goes to the target\n *\n * @beta\n */\nexport function fitToPlaces(context: FormationContext, places: readonly Vec2[]): Map<EntityId, Vec2> {\n\tconst { units, centre, target } = context\n\tconst points = new Map<EntityId, Vec2>()\n\tconst left = [...units].sort((a, b) => a.id - b.id)\n\tfor (const place of places) {\n\t\tif (left.length === 0) break\n\t\tconst px = place.x - target.x\n\t\tconst pz = place.z - target.z\n\t\tlet nearest = 0\n\t\tlet best = Infinity\n\t\tfor (let i = 0; i < left.length; i++) {\n\t\t\tconst unit = left[i]\n\t\t\tconst d = hypot(unit.pos.x - centre.x - px, unit.pos.z - centre.z - pz)\n\t\t\tif (d < best) {\n\t\t\t\tbest = d\n\t\t\t\tnearest = i\n\t\t\t}\n\t\t}\n\t\tpoints.set(left[nearest].id, place)\n\t\tleft.splice(nearest, 1)\n\t}\n\tfor (const unit of left) points.set(unit.id, target)\n\treturn points\n}\n\n/**\n * The engine's usual formation: a tight group keeps its shape as it is, and a scattered one lines up in rows across\n * the way of travel, as many across as there are rows, the units ahead in the front rows\n *\n * @beta\n */\nexport const rowsFormation: FormationDef = {\n\tid: 'rows',\n\tname: 'Rows',\n\tpoints(context) {\n\t\tconst { units, target, centre, spacing, forward, right, snap } = context\n\t\tconst points = new Map<EntityId, Vec2>()\n\t\tlet spread = 0\n\t\tfor (const unit of units) spread = Math.max(spread, hypot(unit.pos.x - centre.x, unit.pos.z - centre.z))\n\t\tconst travel = hypot(target.x - centre.x, target.z - centre.z)\n\t\tconst compact = spacing * Math.sqrt(units.length)\n\t\tif (spread <= compact && travel > spread && !context.turned) {\n\t\t\tfor (const unit of units) points.set(unit.id, snap({ x: target.x + unit.pos.x - centre.x, z: target.z + unit.pos.z - centre.z }))\n\t\t\treturn points\n\t\t}\n\t\tconst columns = Math.ceil(Math.sqrt(units.length))\n\t\tconst rows = Math.ceil(units.length / columns)\n\t\t// front rows go to the units that are already ahead, to keep paths from crossing\n\t\tconst ahead = (u: Entity) => (u.pos.x - centre.x) * forward.x + (u.pos.z - centre.z) * forward.z\n\t\tconst sideways = (u: Entity) => (u.pos.x - centre.x) * right.x + (u.pos.z - centre.z) * right.z\n\t\tconst ordered = [...units].sort((a, b) => ahead(b) - ahead(a) || a.id - b.id)\n\t\tfor (let row = 0; row < rows; row++) {\n\t\t\tconst members = ordered.slice(row * columns, (row + 1) * columns).sort((a, b) => sideways(a) - sideways(b) || a.id - b.id)\n\t\t\tconst back = (row - (rows - 1) / 2) * spacing\n\t\t\tfor (let i = 0; i < members.length; i++) {\n\t\t\t\tconst side = (i - (members.length - 1) / 2) * spacing\n\t\t\t\tpoints.set(members[i].id, snap(context.place(side, -back)))\n\t\t\t}\n\t\t}\n\t\treturn points\n\t}\n}\n\n/** How many places a ring of a radius has room for, `spacing` apart */\nconst ringRoom = (radius: number, spacing: number) => Math.max(Math.floor((2 * Math.PI * radius) / spacing), 1)\n\n/**\n * How many places each ring of a disc gets, the middle first (one), then the rings a `spacing` apart: as few rings as\n * hold them all, and the places shared out among the rings as their room goes, so that the disc is as thick\n * everywhere, filled to the middle, rather than full outer rings round a hollow. The places left over by the share go\n * to the biggest remainders, the outer ring of two first. A few that the outer ring holds alone (up to 12) stand on it\n */\nfunction ringCounts(count: number, spacing: number): number[] {\n\tconst room = [1]\n\tlet held = 1\n\twhile (held < count) {\n\t\tconst on = ringRoom(room.length * spacing, spacing)\n\t\troom.push(on)\n\t\theld += on\n\t}\n\t// a few, that the outer ring holds alone: a ring of them, with nobody within\n\tif (count <= room[room.length - 1]) return room.map((_, i) => (i === room.length - 1 ? count : 0))\n\tconst counts = room.map((on) => Math.floor((count * on) / held))\n\tlet left = count - counts.reduce((sum, on) => sum + on, 0)\n\t// the remainders, the biggest first and the outer ring of two the same; whole numbers, so the same on any machine\n\tconst order = room.map((_, i) => i).sort((a, b) => ((count * room[b]) % held) - ((count * room[a]) % held) || b - a)\n\tfor (const i of order) {\n\t\tif (left === 0) break\n\t\tif (counts[i] < room[i]) {\n\t\t\tcounts[i]++\n\t\t\tleft--\n\t\t}\n\t}\n\treturn counts\n}\n\n/** The places of a ring, evenly, the first at the front, clockwise */\nfunction circleRing(radius: number, on: number): Vec2[] {\n\tconst places: Vec2[] = []\n\tfor (let i = 0; i < on; i++) {\n\t\tconst angle = (i / on) * 2 * Math.PI\n\t\tplaces.push({ x: radius * sin(angle), z: radius * cos(angle) })\n\t}\n\treturn places\n}\n\n/**\n * A circle: a ring around the target, the first place at the front, and rings within it where one is not enough for\n * them all, a `spacing` apart, down to the middle. As few rings as hold them, and the units shared out among them as\n * their room goes: a disc as thick everywhere, every ring's places even, the outer ring first\n *\n * @beta\n */\nexport const circleFormation: FormationDef = {\n\tid: 'circle',\n\tname: 'Circle',\n\tshape(count, spacing) {\n\t\tconst counts = ringCounts(count, spacing)\n\t\tconst places: Vec2[] = []\n\t\tfor (let i = counts.length - 1; i >= 1; i--) places.push(...circleRing(i * spacing, counts[i]))\n\t\tif (counts[0] > 0) places.push({ x: 0, z: 0 })\n\t\treturn places\n\t}\n}\n\n/**\n * A square: a block of rows a `spacing` apart, as many across as deep (one row fewer where that holds them), filled to\n * the middle, the front row first. Where they do not fill the last row, the back one, those in it stand in its middle\n *\n * @beta\n */\nexport const squareFormation: FormationDef = {\n\tid: 'square',\n\tname: 'Square',\n\tshape(count, spacing) {\n\t\tconst across = Math.ceil(Math.sqrt(count))\n\t\tconst deep = Math.ceil(count / across)\n\t\tconst places: Vec2[] = []\n\t\tfor (let row = 0; row < deep; row++) {\n\t\t\tconst on = Math.min(across, count - row * across)\n\t\t\tconst z = ((deep - 1) / 2 - row) * spacing\n\t\t\tfor (let i = 0; i < on; i++) places.push({ x: (i - (on - 1) / 2) * spacing, z })\n\t\t}\n\t\treturn places\n\t}\n}\n\n/**\n * No formation: every unit to the point itself, as units sent one by one go\n *\n * @beta\n */\nexport const noneFormation: FormationDef = {\n\tid: 'none',\n\tname: 'None',\n\tshape: (count) => Array.from({ length: count }, () => ({ x: 0, z: 0 }))\n}\n\n/**\n * The engine's formations: `rows` (the usual), `circle`, `square` and `none`\n *\n * @beta\n */\nexport const coreFormations: readonly FormationDef[] = [rowsFormation, circleFormation, squareFormation, noneFormation]\n\n/**\n * What a formation is laid out with, for a group sent to a target on a navigation\n *\n * @internal\n */\nexport function formationContext(world: World, units: readonly Entity[], target: Vec2, nav: Navigation, facing?: number): FormationContext {\n\tlet cx = 0\n\tlet cz = 0\n\tlet radius = 0\n\tfor (const unit of units) {\n\t\tcx += unit.pos.x\n\t\tcz += unit.pos.z\n\t\tradius = Math.max(radius, unit.def.radius)\n\t}\n\tcx /= units.length\n\tcz /= units.length\n\tconst travel = hypot(target.x - cx, target.z - cz)\n\t// turned by hand: the way the player dragged (a direction as `facing` is, 0 along +z), else the way of travel\n\tconst forward =\n\t\tfacing !== undefined\n\t\t\t? { x: sin(facing), z: cos(facing) }\n\t\t\t: { x: travel > 0.001 ? (target.x - cx) / travel : 0, z: travel > 0.001 ? (target.z - cz) / travel : 1 }\n\tconst right = { x: forward.z, z: -forward.x }\n\treturn {\n\t\tworld,\n\t\tunits,\n\t\ttarget,\n\t\tnav,\n\t\tcentre: { x: cx, z: cz },\n\t\tforward,\n\t\tright,\n\t\tturned: facing !== undefined,\n\t\tspacing: radius * 2 + GAP,\n\t\tplace: (x, z) => ({ x: target.x + right.x * x + forward.x * z, z: target.z + right.z * x + forward.z * z }),\n\t\tsnap: (p) => nav.closestPoint(p, 4) ?? target\n\t}\n}\n\n/**\n * Individual destinations for a group ordered to the same point, in a formation (`rowsFormation` when none is\n * given), and what the `formation` hook makes of them. Units that walk and units that fly are laid out apart, each\n * on their own navigation (`world.navFor`). `facing`, where the player turned the formation by hand, is the way it\n * faces (a direction as an entity's `facing` is), over the way of travel\n *\n * @beta\n */\nexport function formationPoints(\n\tworld: World,\n\tunits: readonly Entity[],\n\ttarget: Vec2,\n\tformation: FormationDef = rowsFormation,\n\tfacing?: number\n): Map<EntityId, Vec2> {\n\tif (units.length === 0) return new Map()\n\tconst context = formationContext(world, units, target, world.navFor(units[0]), facing)\n\tlet points: Map<EntityId, Vec2>\n\tif (units.length === 1) points = new Map([[units[0].id, target]])\n\telse if (formation.points) points = formation.points(context)\n\telse if (formation.shape) points = fitToPlaces(context, placed(context, formation.shape(units.length, context.spacing, context)))\n\telse throw new Error(`The formation \"${formation.id}\" has neither a shape nor points`)\n\tif (world.hooks.has('formation')) world.hooks.run('formation', { units, target, formation, points })\n\treturn points\n}\n\n/**\n * A unit as a preview of a formation knows it: where it stands and how big it is\n *\n * @beta\n */\nexport interface FormationUnit {\n\t/** The unit's entity id */\n\treadonly id: EntityId\n\t/** Where it stands, in cells */\n\treadonly pos: Vec2\n\t/** Its collision radius, in cells */\n\treadonly radius: number\n}\n\n/**\n * Where a group would stand if sent to a target in a formation (by id, `rows` when unknown), from what a player's\n * screen knows of the units: what the ghosts of a right-click dragged are drawn from (`GameSession.formationPlaces`).\n * The same shapes as `formationPoints` gives, units that walk and units that fly each on their own navigation; the\n * `formation` hook (the simulation's) and a formation that reads `FormationContext.world` take no part, and the order\n * itself lays the group out as it will\n *\n * @beta\n */\nexport function formationPreview(\n\tregistry: Registry,\n\tunits: readonly (FormationUnit & { readonly flying?: boolean })[],\n\ttarget: Vec2,\n\tnavs: { readonly nav: Navigation; readonly air: Navigation },\n\tid: string,\n\tfacing?: number\n): Map<EntityId, Vec2> {\n\tconst formation = registry.formations.has(id) ? registry.formation(id) : rowsFormation\n\tconst places = new Map<EntityId, Vec2>()\n\tfor (const flying of [false, true]) {\n\t\tconst group = units.filter((unit) => !!unit.flying === flying)\n\t\tif (group.length === 0) continue\n\t\tif (group.length === 1) places.set(group[0].id, target)\n\t\telse {\n\t\t\tconst stand = group.map((unit) => ({ id: unit.id, pos: unit.pos, def: { radius: unit.radius } }) as unknown as Entity)\n\t\t\tconst context = formationContext(undefined as unknown as World, stand, target, flying ? navs.air : navs.nav, facing)\n\t\t\tconst found = formation.points ? formation.points(context) : fitToPlaces(context, placed(context, formation.shape!(group.length, context.spacing, context)))\n\t\t\tfor (const [unit, place] of found) places.set(unit, place)\n\t\t}\n\t}\n\treturn places\n}\n"],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ import type { FormCooldowns, MorphBack } from './defs';
2
+ import type { Entity } from './entity';
3
+ import type { System } from './registry';
4
+ import type { World } from './world';
5
+ /**
6
+ * How a hero takes a form (`takeForm`): what it learns there and at what levels, what of its own it keeps, for how
7
+ * long, what turns it back. `learns`, `levels` and `keeps` are read as a `HeroForm`'s; with `learns` left out, what the
8
+ * hero's type says of the form (`HeroDef.forms`) is taken, or else what the form's own type learns
9
+ *
10
+ * @beta
11
+ */
12
+ export interface FormOptions {
13
+ /** What it learns in the form, by id (`HeroForm.learns`) */
14
+ learns?: string[];
15
+ /**
16
+ * The level each of `learns` starts at, by id (`HeroForm.levels`): one of its own whose level it has, or a number
17
+ * (another hero's, taken over). A list is by place in `learns`, numbers alone
18
+ */
19
+ levels?: Record<string, string | number> | number[];
20
+ /** Its own abilities the form leaves in place, by id (`HeroForm.keeps`): an ultimate, a passive */
21
+ keeps?: string[];
22
+ /** What becomes of the cooldowns going in and out (`HeroForm.cooldowns`): the time away runs the put away down when left out */
23
+ cooldowns?: FormCooldowns;
24
+ /** Seconds it lasts: until something else turns it back when left out */
25
+ duration?: number;
26
+ /** What turns it back: its time and its death when left out */
27
+ back?: MorphBack[];
28
+ /** The ability that made it, kept in the form: cast again there, it turns it back where `back` has `ability` */
29
+ by?: string;
30
+ }
31
+ /**
32
+ * Turns a hero into one of its forms where it stands (`into`, a unit type that is a hero's: its stats, growth and look
33
+ * are the form's), as the `morph` effect does. Kept: its id, owner and place, its level and experience, its items, its
34
+ * buffs, the share of its health and mana, and what it was told (it goes on as the form). It learns the form's
35
+ * abilities (`FormOptions.learns`) at the levels the form says (`levels`: one of its own's, or a number; by slot in
36
+ * `HeroForm`'s shorter shape, Q is Q); those of its own it keeps (`keeps`, the ability that made the form, the spells it
37
+ * brought, any of its own the form learns) are the same, cooldown and all; the rest are put away until it turns back
38
+ * (`leaveForm`), their cooldowns as `cooldowns` says (running down by the time away when left out). A hero in a form already turns back first
39
+ *
40
+ * @beta
41
+ */
42
+ export declare function takeForm(world: World, entity: Entity, into: string, options?: FormOptions): void;
43
+ /**
44
+ * Turns a hero in a form back into what it was (`takeForm`): its type, its own abilities as they were (their cooldowns
45
+ * as `HeroForm.cooldowns` says, run down while it was away when left out, what it shares with the form as the form left it), the share of its health and mana kept
46
+ * and what it was told going on. `why` is told with the `morphedBack` event: one of `MorphBack`, or a game's own word
47
+ * (`'kill'`: a possessed hero that kills). False for one in no form
48
+ *
49
+ * @beta
50
+ */
51
+ export declare function leaveForm(world: World, entity: Entity, why?: MorphBack | (string & {})): boolean;
52
+ /**
53
+ * Turns back what is in a form whose time is up (`Form.until`): the living, in the order of their ids. A fallen hero
54
+ * in a form that does not end with its death turns back once it is brought back, if its time is up by then
55
+ *
56
+ * @beta
57
+ */
58
+ export declare const formSystem: System;
package/dist/forms.js ADDED
@@ -0,0 +1,146 @@
1
+ import { morphedBack } from "./engineEvents.js";
2
+ import { form, learnsOf } from "./formState.js";
3
+ import { morph } from "./tech.js";
4
+ //#region src/forms.ts
5
+ /**
6
+ * A hero's forms (E2E-PLAN LB2, LB6): a hero turned into another unit type where it stands, for a while or until
7
+ * turned back (Nidalee's cougar, a druid's bear), the form's abilities learned at the levels it says, what of its own it
8
+ * keeps left in place and the rest put away
9
+ */
10
+ var fresh = (world, id, level) => ({
11
+ id,
12
+ level,
13
+ cooldown: 0,
14
+ autocast: level > 0 && (world.registry.ability(id).autocast ?? false)
15
+ });
16
+ /**
17
+ * Turns a hero into one of its forms where it stands (`into`, a unit type that is a hero's: its stats, growth and look
18
+ * are the form's), as the `morph` effect does. Kept: its id, owner and place, its level and experience, its items, its
19
+ * buffs, the share of its health and mana, and what it was told (it goes on as the form). It learns the form's
20
+ * abilities (`FormOptions.learns`) at the levels the form says (`levels`: one of its own's, or a number; by slot in
21
+ * `HeroForm`'s shorter shape, Q is Q); those of its own it keeps (`keeps`, the ability that made the form, the spells it
22
+ * brought, any of its own the form learns) are the same, cooldown and all; the rest are put away until it turns back
23
+ * (`leaveForm`), their cooldowns as `cooldowns` says (running down by the time away when left out). A hero in a form already turns back first
24
+ *
25
+ * @beta
26
+ */
27
+ function takeForm(world, entity, into, options = {}) {
28
+ if (entity.get(form)) leaveForm(world, entity);
29
+ const from = entity.def.id;
30
+ const target = world.registry.unit(into);
31
+ const own = entity.abilities;
32
+ const ownLearns = learnsOf(entity);
33
+ const said = options.learns !== void 0 ? options : entity.def.hero?.forms?.[into] ?? {};
34
+ const learns = said.learns ?? target.hero?.learns ?? [];
35
+ const { levels, keeps = [], cooldowns } = said;
36
+ const bySlot = levels === void 0 && said.keeps === void 0;
37
+ const had = new Map(own.map((state) => [state.id, state]));
38
+ const abilities = [];
39
+ const linked = {};
40
+ const take = (state) => {
41
+ if (!abilities.includes(state)) abilities.push(state);
42
+ };
43
+ const levelOf = (id, place) => {
44
+ const by = bySlot ? ownLearns[place] : Array.isArray(levels) ? levels[place] ?? 0 : levels?.[id] ?? 0;
45
+ if (typeof by === "number") return by;
46
+ if (by === void 0 || by === id || !had.has(by)) return 0;
47
+ linked[id] = by;
48
+ return had.get(by).level;
49
+ };
50
+ for (const id of target.abilities ?? []) take(had.get(id) ?? fresh(world, id, 1));
51
+ learns.forEach((id, place) => take(had.get(id) ?? fresh(world, id, levelOf(id, place))));
52
+ const kept = [
53
+ ...keeps,
54
+ ...options.by !== void 0 ? [options.by] : [],
55
+ ...entity.def.hero?.spells ?? []
56
+ ].filter((id) => had.has(id));
57
+ for (const id of kept) take(had.get(id));
58
+ for (const id of target.hero?.spells ?? []) take(had.get(id) ?? fresh(world, id, 1));
59
+ if (cooldowns === "shared") for (const [id, by] of Object.entries(linked)) {
60
+ const state = abilities.find((each) => each.id === id);
61
+ if (state && !had.has(id)) state.cooldown = had.get(by).cooldown;
62
+ }
63
+ const back = options.back ?? ["time", "death"];
64
+ entity.set(form, {
65
+ from,
66
+ ...options.by !== void 0 && { by: options.by },
67
+ at: world.time,
68
+ ...options.duration !== void 0 && back.includes("time") && { until: world.time + options.duration },
69
+ back: [...back],
70
+ learns: [...learns, ...ownLearns.filter((id) => kept.includes(id) && !learns.includes(id))],
71
+ ...Object.keys(linked).length > 0 && { linked },
72
+ ...cooldowns !== void 0 && { cooldowns },
73
+ kept: own.filter((state) => !abilities.includes(state)),
74
+ own: own.map((state) => state.id)
75
+ });
76
+ morph(world, entity, into, {
77
+ keepOrders: true,
78
+ share: true,
79
+ abilities
80
+ });
81
+ }
82
+ /**
83
+ * Turns a hero in a form back into what it was (`takeForm`): its type, its own abilities as they were (their cooldowns
84
+ * as `HeroForm.cooldowns` says, run down while it was away when left out, what it shares with the form as the form left it), the share of its health and mana kept
85
+ * and what it was told going on. `why` is told with the `morphedBack` event: one of `MorphBack`, or a game's own word
86
+ * (`'kill'`: a possessed hero that kills). False for one in no form
87
+ *
88
+ * @beta
89
+ */
90
+ function leaveForm(world, entity, why) {
91
+ const state = entity.get(form);
92
+ if (!state) return false;
93
+ const away = world.time - state.at;
94
+ const now = new Map(entity.abilities.map((ability) => [ability.id, ability]));
95
+ const kept = new Map(state.kept.map((ability) => [ability.id, ability]));
96
+ const abilities = [];
97
+ for (const id of state.own) {
98
+ const ability = now.get(id) ?? kept.get(id);
99
+ if (!ability) continue;
100
+ if (!now.has(id)) {
101
+ const shared = state.cooldowns === "shared" ? Object.entries(state.linked ?? {}).find(([, by]) => by === id)?.[0] : void 0;
102
+ const there = shared === void 0 ? void 0 : now.get(shared);
103
+ if (state.cooldowns === "reset") ability.cooldown = 0;
104
+ else if (there) ability.cooldown = there.cooldown;
105
+ else if (state.cooldowns !== "keep") ability.cooldown = Math.max(ability.cooldown - away, 0);
106
+ }
107
+ abilities.push(ability);
108
+ }
109
+ const was = entity.def.id;
110
+ entity.remove(form);
111
+ morph(world, entity, state.from, {
112
+ keepOrders: why !== "death",
113
+ share: true,
114
+ abilities
115
+ });
116
+ world.events.emit(morphedBack, {
117
+ entity,
118
+ form: was,
119
+ why
120
+ });
121
+ return true;
122
+ }
123
+ /**
124
+ * Turns back what is in a form whose time is up (`Form.until`): the living, in the order of their ids. A fallen hero
125
+ * in a form that does not end with its death turns back once it is brought back, if its time is up by then
126
+ *
127
+ * @beta
128
+ */
129
+ var formSystem = {
130
+ name: "forms",
131
+ phase: "cleanup",
132
+ update(world) {
133
+ let due;
134
+ for (const entity of world.index.with(form)) {
135
+ const until = entity.get(form).until;
136
+ if (until !== void 0 && world.time >= until && entity.alive) (due ??= []).push(entity);
137
+ }
138
+ if (!due) return;
139
+ due.sort((a, b) => a.id - b.id);
140
+ for (const entity of due) leaveForm(world, entity, "time");
141
+ }
142
+ };
143
+ //#endregion
144
+ export { formSystem, leaveForm, takeForm };
145
+
146
+ //# sourceMappingURL=forms.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forms.js","names":[],"sources":["../src/forms.ts"],"sourcesContent":["/**\n * A hero's forms (E2E-PLAN LB2, LB6): a hero turned into another unit type where it stands, for a while or until\n * turned back (Nidalee's cougar, a druid's bear), the form's abilities learned at the levels it says, what of its own it\n * keeps left in place and the rest put away\n */\nimport { morphedBack } from '#engine/engineEvents'\nimport type { FormCooldowns, MorphBack } from './defs'\nimport type { AbilityState, Entity } from './entity'\nimport { form, learnsOf } from './formState'\nimport type { System } from './registry'\nimport { morph } from './tech'\nimport type { World } from './world'\n\n/**\n * How a hero takes a form (`takeForm`): what it learns there and at what levels, what of its own it keeps, for how\n * long, what turns it back. `learns`, `levels` and `keeps` are read as a `HeroForm`'s; with `learns` left out, what the\n * hero's type says of the form (`HeroDef.forms`) is taken, or else what the form's own type learns\n *\n * @beta\n */\nexport interface FormOptions {\n\t/** What it learns in the form, by id (`HeroForm.learns`) */\n\tlearns?: string[]\n\t/**\n\t * The level each of `learns` starts at, by id (`HeroForm.levels`): one of its own whose level it has, or a number\n\t * (another hero's, taken over). A list is by place in `learns`, numbers alone\n\t */\n\tlevels?: Record<string, string | number> | number[]\n\t/** Its own abilities the form leaves in place, by id (`HeroForm.keeps`): an ultimate, a passive */\n\tkeeps?: string[]\n\t/** What becomes of the cooldowns going in and out (`HeroForm.cooldowns`): the time away runs the put away down when left out */\n\tcooldowns?: FormCooldowns\n\t/** Seconds it lasts: until something else turns it back when left out */\n\tduration?: number\n\t/** What turns it back: its time and its death when left out */\n\tback?: MorphBack[]\n\t/** The ability that made it, kept in the form: cast again there, it turns it back where `back` has `ability` */\n\tby?: string\n}\n\nconst fresh = (world: World, id: string, level: number): AbilityState => ({\n\tid,\n\tlevel,\n\tcooldown: 0,\n\tautocast: level > 0 && (world.registry.ability(id).autocast ?? false)\n})\n\n/**\n * Turns a hero into one of its forms where it stands (`into`, a unit type that is a hero's: its stats, growth and look\n * are the form's), as the `morph` effect does. Kept: its id, owner and place, its level and experience, its items, its\n * buffs, the share of its health and mana, and what it was told (it goes on as the form). It learns the form's\n * abilities (`FormOptions.learns`) at the levels the form says (`levels`: one of its own's, or a number; by slot in\n * `HeroForm`'s shorter shape, Q is Q); those of its own it keeps (`keeps`, the ability that made the form, the spells it\n * brought, any of its own the form learns) are the same, cooldown and all; the rest are put away until it turns back\n * (`leaveForm`), their cooldowns as `cooldowns` says (running down by the time away when left out). A hero in a form already turns back first\n *\n * @beta\n */\nexport function takeForm(world: World, entity: Entity, into: string, options: FormOptions = {}): void {\n\tif (entity.get(form)) leaveForm(world, entity)\n\tconst from = entity.def.id\n\tconst target = world.registry.unit(into)\n\tconst own = entity.abilities\n\tconst ownLearns = learnsOf(entity)\n\t// what the options say, or else what the hero's type says of the form: not a mix of the two\n\tconst said = options.learns !== undefined ? options : (entity.def.hero?.forms?.[into] ?? {})\n\tconst learns = said.learns ?? target.hero?.learns ?? []\n\tconst { levels, keeps = [], cooldowns } = said\n\t// the shorter shape: a list alone, by slot\n\tconst bySlot = levels === undefined && said.keeps === undefined\n\tconst had = new Map(own.map((state) => [state.id, state]))\n\tconst abilities: AbilityState[] = []\n\tconst linked: Record<string, string> = {}\n\tconst take = (state: AbilityState) => {\n\t\tif (!abilities.includes(state)) abilities.push(state)\n\t}\n\tconst levelOf = (id: string, place: number): number => {\n\t\tconst by = bySlot ? ownLearns[place] : Array.isArray(levels) ? (levels[place] ?? 0) : (levels?.[id] ?? 0)\n\t\tif (typeof by === 'number') return by\n\t\tif (by === undefined || by === id || !had.has(by)) return 0\n\t\tlinked[id] = by\n\t\treturn had.get(by)!.level\n\t}\n\tfor (const id of target.abilities ?? []) take(had.get(id) ?? fresh(world, id, 1))\n\tlearns.forEach((id, place) => take(had.get(id) ?? fresh(world, id, levelOf(id, place))))\n\t// what of its own it keeps besides: what the form says, the ability that made it, the spells it brought along\n\tconst kept = [...keeps, ...(options.by !== undefined ? [options.by] : []), ...(entity.def.hero?.spells ?? [])].filter((id) => had.has(id))\n\tfor (const id of kept) take(had.get(id)!)\n\t// and the form's own spells\n\tfor (const id of target.hero?.spells ?? []) take(had.get(id) ?? fresh(world, id, 1))\n\t// 'shared': what it takes the place of is one cooldown with it, from now on\n\tif (cooldowns === 'shared')\n\t\tfor (const [id, by] of Object.entries(linked)) {\n\t\t\tconst state = abilities.find((each) => each.id === id)\n\t\t\tif (state && !had.has(id)) state.cooldown = had.get(by)!.cooldown\n\t\t}\n\tconst back = options.back ?? ['time', 'death']\n\tentity.set(form, {\n\t\tfrom,\n\t\t...(options.by !== undefined && { by: options.by }),\n\t\tat: world.time,\n\t\t...(options.duration !== undefined && back.includes('time') && { until: world.time + options.duration }),\n\t\tback: [...back],\n\t\t// the card shows what it learns there, then what it keeps of what it learns as itself, in its own order\n\t\tlearns: [...learns, ...ownLearns.filter((id) => kept.includes(id) && !learns.includes(id))],\n\t\t...(Object.keys(linked).length > 0 && { linked }),\n\t\t...(cooldowns !== undefined && { cooldowns }),\n\t\tkept: own.filter((state) => !abilities.includes(state)),\n\t\town: own.map((state) => state.id)\n\t})\n\tmorph(world, entity, into, { keepOrders: true, share: true, abilities })\n}\n\n/**\n * Turns a hero in a form back into what it was (`takeForm`): its type, its own abilities as they were (their cooldowns\n * as `HeroForm.cooldowns` says, run down while it was away when left out, what it shares with the form as the form left it), the share of its health and mana kept\n * and what it was told going on. `why` is told with the `morphedBack` event: one of `MorphBack`, or a game's own word\n * (`'kill'`: a possessed hero that kills). False for one in no form\n *\n * @beta\n */\nexport function leaveForm(world: World, entity: Entity, why?: MorphBack | (string & {})): boolean {\n\tconst state = entity.get(form)\n\tif (!state) return false\n\tconst away = world.time - state.at\n\tconst now = new Map(entity.abilities.map((ability) => [ability.id, ability]))\n\tconst kept = new Map(state.kept.map((ability) => [ability.id, ability]))\n\tconst abilities: AbilityState[] = []\n\tfor (const id of state.own) {\n\t\tconst ability = now.get(id) ?? kept.get(id)\n\t\tif (!ability) continue\n\t\tif (!now.has(id)) {\n\t\t\t// put away: as left ('keep'), ready ('reset'), the form's one it shares with ('shared'), or run down by the time away\n\t\t\tconst shared = state.cooldowns === 'shared' ? Object.entries(state.linked ?? {}).find(([, by]) => by === id)?.[0] : undefined\n\t\t\tconst there = shared === undefined ? undefined : now.get(shared)\n\t\t\tif (state.cooldowns === 'reset') ability.cooldown = 0\n\t\t\telse if (there) ability.cooldown = there.cooldown\n\t\t\telse if (state.cooldowns !== 'keep') ability.cooldown = Math.max(ability.cooldown - away, 0)\n\t\t}\n\t\tabilities.push(ability)\n\t}\n\tconst was = entity.def.id\n\tentity.remove(form)\n\tmorph(world, entity, state.from, { keepOrders: why !== 'death', share: true, abilities })\n\tworld.events.emit(morphedBack, { entity, form: was, why })\n\treturn true\n}\n\n/**\n * Turns back what is in a form whose time is up (`Form.until`): the living, in the order of their ids. A fallen hero\n * in a form that does not end with its death turns back once it is brought back, if its time is up by then\n *\n * @beta\n */\nexport const formSystem: System = {\n\tname: 'forms',\n\tphase: 'cleanup',\n\tupdate(world: World) {\n\t\tlet due: Entity[] | undefined\n\t\tfor (const entity of world.index.with(form)) {\n\t\t\tconst until = entity.get(form)!.until\n\t\t\tif (until !== undefined && world.time >= until && entity.alive) (due ??= []).push(entity)\n\t\t}\n\t\tif (!due) return\n\t\tdue.sort((a, b) => a.id - b.id)\n\t\tfor (const entity of due) leaveForm(world, entity, 'time')\n\t}\n}\n"],"mappings":"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"}
@@ -8,7 +8,7 @@ import type { World } from './world';
8
8
  */
9
9
  export declare const FRIENDLY_FIRE = "core.friendlyFire";
10
10
  /**
11
- * What the friendly fire pack is made with (`withFriendlyFire`)
11
+ * What the friendly fire pack is made with (`friendlyFirePack`)
12
12
  *
13
13
  * @beta
14
14
  */
@@ -23,4 +23,4 @@ export interface FriendlyFireOptions {
23
23
  *
24
24
  * @beta
25
25
  */
26
- export declare function withFriendlyFire(options?: FriendlyFireOptions): GamePack;
26
+ export declare function friendlyFirePack(options?: FriendlyFireOptions): GamePack;
@@ -0,0 +1,37 @@
1
+ import { defineHook } from "./hooks.js";
2
+ import { attackReaches } from "./systems/combat.js";
3
+ //#region src/friendlyFire.ts
4
+ /**
5
+ * The friendly fire pack's id
6
+ *
7
+ * @beta
8
+ */
9
+ var FRIENDLY_FIRE = "core.friendlyFire";
10
+ /**
11
+ * Friendly fire, as in classic RTS games: a unit told to attack (the attack command, never a right click) one of its own or
12
+ * an ally's attacks it. Never of its own accord: units do not pick their own side to attack, nor fight back at it.
13
+ * Nothing of a neutral player's (a rock, a critter) is made a target by it
14
+ *
15
+ * @beta
16
+ */
17
+ function friendlyFirePack(options = {}) {
18
+ const attacks = options.attacks ?? (() => true);
19
+ return {
20
+ id: FRIENDLY_FIRE,
21
+ options,
22
+ hooks: [defineHook({
23
+ hook: "canAttack",
24
+ id: "friendlyFire",
25
+ run(world, event) {
26
+ const { attacker, target } = event;
27
+ if (!event.cancelled || !event.ordered || world.player(target.owner).neutral) return;
28
+ if (world.areEnemies(attacker.owner, target.owner)) return;
29
+ if (attackReaches(world, attacker, target) && attacks(world, attacker, target)) event.cancelled = false;
30
+ }
31
+ })]
32
+ };
33
+ }
34
+ //#endregion
35
+ export { FRIENDLY_FIRE, friendlyFirePack };
36
+
37
+ //# sourceMappingURL=friendlyFire.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"friendlyFire.js","names":[],"sources":["../src/friendlyFire.ts"],"sourcesContent":["import type { Entity } from './entity'\nimport { defineHook } from './hooks'\nimport type { GamePack } from './packs/pack'\nimport { attackReaches } from './systems/combat'\nimport type { World } from './world'\n\n/*\n * Friendly fire, an opt-in pack: as in classic RTS games, a unit told to attack one of its own side's does\n */\n\n/**\n * The friendly fire pack's id\n *\n * @beta\n */\nexport const FRIENDLY_FIRE = 'core.friendlyFire'\n\n/**\n * What the friendly fire pack is made with (`friendlyFirePack`)\n *\n * @beta\n */\nexport interface FriendlyFireOptions {\n\t/** What of its own side's, and its allies', a unit may be told to attack: anything its attack reaches when left out */\n\tattacks?: (world: World, attacker: Entity, target: Entity) => boolean\n}\n\n/**\n * Friendly fire, as in classic RTS games: a unit told to attack (the attack command, never a right click) one of its own or\n * an ally's attacks it. Never of its own accord: units do not pick their own side to attack, nor fight back at it.\n * Nothing of a neutral player's (a rock, a critter) is made a target by it\n *\n * @beta\n */\nexport function friendlyFirePack(options: FriendlyFireOptions = {}): GamePack {\n\tconst attacks = options.attacks ?? (() => true)\n\tconst friendly = defineHook({\n\t\thook: 'canAttack',\n\t\tid: 'friendlyFire',\n\t\trun(world, event) {\n\t\t\tconst { attacker, target } = event\n\t\t\tif (!event.cancelled || !event.ordered || world.player(target.owner).neutral) return\n\t\t\tif (world.areEnemies(attacker.owner, target.owner)) return\n\t\t\tif (attackReaches(world, attacker, target) && attacks(world, attacker, target)) event.cancelled = false\n\t\t}\n\t})\n\treturn { id: FRIENDLY_FIRE, options, hooks: [friendly] }\n}\n"],"mappings":";;;;;;;;AAeA,IAAa,gBAAgB;;;;;;;;AAmB7B,SAAgB,iBAAiB,UAA+B,CAAC,GAAa;CAC7E,MAAM,UAAU,QAAQ,kBAAkB;CAW1C,OAAO;EAAE,IAAI;EAAe;EAAS,OAAO,CAV3B,WAAW;GAC3B,MAAM;GACN,IAAI;GACJ,IAAI,OAAO,OAAO;IACjB,MAAM,EAAE,UAAU,WAAW;IAC7B,IAAI,CAAC,MAAM,aAAa,CAAC,MAAM,WAAW,MAAM,OAAO,OAAO,KAAK,CAAC,CAAC,SAAS;IAC9E,IAAI,MAAM,WAAW,SAAS,OAAO,OAAO,KAAK,GAAG;IACpD,IAAI,cAAc,OAAO,UAAU,MAAM,KAAK,QAAQ,OAAO,UAAU,MAAM,GAAG,MAAM,YAAY;GACnG;EACD,CAC6C,CAAQ;CAAE;AACxD"}