@datamoc/mw_games 0.7.6 → 0.7.8

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 (367) hide show
  1. package/CHANGELOG.md +359 -0
  2. package/README.md +7 -7
  3. package/dist/actors/Inventory.d.ts +7 -1
  4. package/dist/actors/Inventory.d.ts.map +1 -1
  5. package/dist/actors/Inventory.js.map +1 -1
  6. package/dist/actors/Shop.d.ts.map +1 -1
  7. package/dist/actors/Shop.js +4 -1
  8. package/dist/actors/Shop.js.map +1 -1
  9. package/dist/actors/craft.d.ts +35 -14
  10. package/dist/actors/craft.d.ts.map +1 -1
  11. package/dist/actors/craft.js +56 -24
  12. package/dist/actors/craft.js.map +1 -1
  13. package/dist/actors/index.d.ts +1 -1
  14. package/dist/actors/index.d.ts.map +1 -1
  15. package/dist/ai/Heuristics.d.ts +240 -0
  16. package/dist/ai/Heuristics.d.ts.map +1 -0
  17. package/dist/ai/Heuristics.js +298 -0
  18. package/dist/ai/Heuristics.js.map +1 -0
  19. package/dist/ai/index.d.ts +4 -0
  20. package/dist/ai/index.d.ts.map +1 -1
  21. package/dist/ai/index.js +2 -0
  22. package/dist/ai/index.js.map +1 -1
  23. package/dist/ai/lua.d.ts +21 -0
  24. package/dist/ai/lua.d.ts.map +1 -1
  25. package/dist/ai/lua.js +21 -0
  26. package/dist/ai/lua.js.map +1 -1
  27. package/dist/ai/score.d.ts +162 -0
  28. package/dist/ai/score.d.ts.map +1 -0
  29. package/dist/ai/score.js +147 -0
  30. package/dist/ai/score.js.map +1 -0
  31. package/dist/assets/loader.d.ts +18 -4
  32. package/dist/assets/loader.d.ts.map +1 -1
  33. package/dist/assets/loader.js +40 -11
  34. package/dist/assets/loader.js.map +1 -1
  35. package/dist/audio/Positional.d.ts +125 -0
  36. package/dist/audio/Positional.d.ts.map +1 -0
  37. package/dist/audio/Positional.js +135 -0
  38. package/dist/audio/Positional.js.map +1 -0
  39. package/dist/audio/Sound.d.ts +7 -1
  40. package/dist/audio/Sound.d.ts.map +1 -1
  41. package/dist/audio/Sound.js +8 -2
  42. package/dist/audio/Sound.js.map +1 -1
  43. package/dist/audio/index.d.ts +2 -0
  44. package/dist/audio/index.d.ts.map +1 -1
  45. package/dist/audio/index.js +1 -0
  46. package/dist/audio/index.js.map +1 -1
  47. package/dist/battle/AttackDialog.d.ts +75 -0
  48. package/dist/battle/AttackDialog.d.ts.map +1 -0
  49. package/dist/battle/AttackDialog.js +115 -0
  50. package/dist/battle/AttackDialog.js.map +1 -0
  51. package/dist/battle/AttackPreview.d.ts +70 -0
  52. package/dist/battle/AttackPreview.d.ts.map +1 -0
  53. package/dist/battle/AttackPreview.js +78 -0
  54. package/dist/battle/AttackPreview.js.map +1 -0
  55. package/dist/battle/BattleStats.d.ts +45 -0
  56. package/dist/battle/BattleStats.d.ts.map +1 -0
  57. package/dist/battle/BattleStats.js +63 -0
  58. package/dist/battle/BattleStats.js.map +1 -0
  59. package/dist/battle/UnitSelector.d.ts +72 -0
  60. package/dist/battle/UnitSelector.d.ts.map +1 -0
  61. package/dist/battle/UnitSelector.js +117 -0
  62. package/dist/battle/UnitSelector.js.map +1 -0
  63. package/dist/battle/Whiteboard.d.ts +50 -0
  64. package/dist/battle/Whiteboard.d.ts.map +1 -0
  65. package/dist/battle/Whiteboard.js +94 -0
  66. package/dist/battle/Whiteboard.js.map +1 -0
  67. package/dist/battle/index.d.ts +10 -0
  68. package/dist/battle/index.d.ts.map +1 -1
  69. package/dist/battle/index.js +5 -0
  70. package/dist/battle/index.js.map +1 -1
  71. package/dist/board/Classics.d.ts.map +1 -1
  72. package/dist/board/Classics.js +51 -39
  73. package/dist/board/Classics.js.map +1 -1
  74. package/dist/board/FogOfWar.d.ts +32 -2
  75. package/dist/board/FogOfWar.d.ts.map +1 -1
  76. package/dist/board/FogOfWar.js +70 -6
  77. package/dist/board/FogOfWar.js.map +1 -1
  78. package/dist/board/HexSkirmish.d.ts.map +1 -1
  79. package/dist/board/HexSkirmish.js +69 -20
  80. package/dist/board/HexSkirmish.js.map +1 -1
  81. package/dist/board/Tactics.d.ts +7 -0
  82. package/dist/board/Tactics.d.ts.map +1 -1
  83. package/dist/board/Tactics.js +2 -2
  84. package/dist/board/Tactics.js.map +1 -1
  85. package/dist/core/Achievements.d.ts +40 -7
  86. package/dist/core/Achievements.d.ts.map +1 -1
  87. package/dist/core/Achievements.js +53 -7
  88. package/dist/core/Achievements.js.map +1 -1
  89. package/dist/core/Hex.d.ts +26 -6
  90. package/dist/core/Hex.d.ts.map +1 -1
  91. package/dist/core/Hex.js +40 -13
  92. package/dist/core/Hex.js.map +1 -1
  93. package/dist/core/Input.d.ts +36 -0
  94. package/dist/core/Input.d.ts.map +1 -1
  95. package/dist/core/Input.js +63 -1
  96. package/dist/core/Input.js.map +1 -1
  97. package/dist/core/Random.d.ts +93 -0
  98. package/dist/core/Random.d.ts.map +1 -1
  99. package/dist/core/Random.js +177 -0
  100. package/dist/core/Random.js.map +1 -1
  101. package/dist/core/SyncGuard.d.ts +57 -0
  102. package/dist/core/SyncGuard.d.ts.map +1 -0
  103. package/dist/core/SyncGuard.js +116 -0
  104. package/dist/core/SyncGuard.js.map +1 -0
  105. package/dist/core/index.d.ts +3 -1
  106. package/dist/core/index.d.ts.map +1 -1
  107. package/dist/core/index.js +2 -1
  108. package/dist/core/index.js.map +1 -1
  109. package/dist/i18n/Po.d.ts +51 -0
  110. package/dist/i18n/Po.d.ts.map +1 -0
  111. package/dist/i18n/Po.js +176 -0
  112. package/dist/i18n/Po.js.map +1 -0
  113. package/dist/i18n/index.d.ts +2 -0
  114. package/dist/i18n/index.d.ts.map +1 -1
  115. package/dist/i18n/index.js +1 -0
  116. package/dist/i18n/index.js.map +1 -1
  117. package/dist/mw_games.global.js +104 -98
  118. package/dist/mwl/MapFile.d.ts +41 -0
  119. package/dist/mwl/MapFile.d.ts.map +1 -0
  120. package/dist/mwl/MapFile.js +43 -0
  121. package/dist/mwl/MapFile.js.map +1 -0
  122. package/dist/mwl/actors.d.ts +46 -2
  123. package/dist/mwl/actors.d.ts.map +1 -1
  124. package/dist/mwl/actors.js +46 -2
  125. package/dist/mwl/actors.js.map +1 -1
  126. package/dist/mwl/campaign.d.ts +51 -0
  127. package/dist/mwl/campaign.d.ts.map +1 -0
  128. package/dist/mwl/campaign.js +58 -0
  129. package/dist/mwl/campaign.js.map +1 -0
  130. package/dist/mwl/carryover.d.ts +86 -0
  131. package/dist/mwl/carryover.d.ts.map +1 -0
  132. package/dist/mwl/carryover.js +70 -0
  133. package/dist/mwl/carryover.js.map +1 -0
  134. package/dist/mwl/catalog.d.ts +10 -1
  135. package/dist/mwl/catalog.d.ts.map +1 -1
  136. package/dist/mwl/catalog.js +10 -1
  137. package/dist/mwl/catalog.js.map +1 -1
  138. package/dist/mwl/compiler.d.ts +70 -3
  139. package/dist/mwl/compiler.d.ts.map +1 -1
  140. package/dist/mwl/compiler.js +70 -3
  141. package/dist/mwl/compiler.js.map +1 -1
  142. package/dist/mwl/conditions.d.ts +10 -1
  143. package/dist/mwl/conditions.d.ts.map +1 -1
  144. package/dist/mwl/conditions.js +10 -1
  145. package/dist/mwl/conditions.js.map +1 -1
  146. package/dist/mwl/content.d.ts +21 -0
  147. package/dist/mwl/content.d.ts.map +1 -1
  148. package/dist/mwl/content.js +19 -0
  149. package/dist/mwl/content.js.map +1 -1
  150. package/dist/mwl/expression.d.ts +21 -0
  151. package/dist/mwl/expression.d.ts.map +1 -1
  152. package/dist/mwl/expression.js +21 -0
  153. package/dist/mwl/expression.js.map +1 -1
  154. package/dist/mwl/fengari.d.ts +12 -1
  155. package/dist/mwl/fengari.d.ts.map +1 -1
  156. package/dist/mwl/fengari.js +12 -1
  157. package/dist/mwl/fengari.js.map +1 -1
  158. package/dist/mwl/grammar.d.ts +45 -1
  159. package/dist/mwl/grammar.d.ts.map +1 -1
  160. package/dist/mwl/grammar.js +45 -1
  161. package/dist/mwl/grammar.js.map +1 -1
  162. package/dist/mwl/hooks.d.ts +51 -6
  163. package/dist/mwl/hooks.d.ts.map +1 -1
  164. package/dist/mwl/hooks.js +45 -1
  165. package/dist/mwl/hooks.js.map +1 -1
  166. package/dist/mwl/index.d.ts +9 -3
  167. package/dist/mwl/index.d.ts.map +1 -1
  168. package/dist/mwl/index.js +5 -2
  169. package/dist/mwl/index.js.map +1 -1
  170. package/dist/mwl/persistence.d.ts +32 -0
  171. package/dist/mwl/persistence.d.ts.map +1 -1
  172. package/dist/mwl/persistence.js +32 -0
  173. package/dist/mwl/persistence.js.map +1 -1
  174. package/dist/mwl/readers.d.ts +24 -2
  175. package/dist/mwl/readers.d.ts.map +1 -1
  176. package/dist/mwl/readers.js +27 -4
  177. package/dist/mwl/readers.js.map +1 -1
  178. package/dist/mwl/report.d.ts +21 -2
  179. package/dist/mwl/report.d.ts.map +1 -1
  180. package/dist/mwl/report.js +21 -2
  181. package/dist/mwl/report.js.map +1 -1
  182. package/dist/mwl/runtime.d.ts +212 -7
  183. package/dist/mwl/runtime.d.ts.map +1 -1
  184. package/dist/mwl/runtime.js +682 -90
  185. package/dist/mwl/runtime.js.map +1 -1
  186. package/dist/mwl/schema.d.ts +57 -1
  187. package/dist/mwl/schema.d.ts.map +1 -1
  188. package/dist/mwl/schema.js +181 -21
  189. package/dist/mwl/schema.js.map +1 -1
  190. package/dist/mwl/scripts.d.ts +12 -1
  191. package/dist/mwl/scripts.d.ts.map +1 -1
  192. package/dist/mwl/scripts.js +12 -1
  193. package/dist/mwl/scripts.js.map +1 -1
  194. package/dist/mwl/utils.d.ts +2 -0
  195. package/dist/mwl/utils.d.ts.map +1 -1
  196. package/dist/mwl/utils.js +4 -1
  197. package/dist/mwl/utils.js.map +1 -1
  198. package/dist/roguelike/MultiTurnBeam.d.ts +50 -12
  199. package/dist/roguelike/MultiTurnBeam.d.ts.map +1 -1
  200. package/dist/roguelike/MultiTurnBeam.js +100 -53
  201. package/dist/roguelike/MultiTurnBeam.js.map +1 -1
  202. package/dist/roguelike/Targeting.d.ts +94 -0
  203. package/dist/roguelike/Targeting.d.ts.map +1 -1
  204. package/dist/roguelike/Targeting.js +123 -0
  205. package/dist/roguelike/Targeting.js.map +1 -1
  206. package/dist/roguelike/index.d.ts +3 -1
  207. package/dist/roguelike/index.d.ts.map +1 -1
  208. package/dist/roguelike/index.js +1 -0
  209. package/dist/roguelike/index.js.map +1 -1
  210. package/dist/rpg/GameState.d.ts +2 -2
  211. package/dist/rpg/GameState.js +2 -2
  212. package/dist/simulation/CampaignSave.d.ts +68 -0
  213. package/dist/simulation/CampaignSave.d.ts.map +1 -0
  214. package/dist/simulation/CampaignSave.js +54 -0
  215. package/dist/simulation/CampaignSave.js.map +1 -0
  216. package/dist/simulation/EventPresentation.d.ts +111 -0
  217. package/dist/simulation/EventPresentation.d.ts.map +1 -0
  218. package/dist/simulation/EventPresentation.js +120 -0
  219. package/dist/simulation/EventPresentation.js.map +1 -0
  220. package/dist/simulation/index.d.ts +4 -0
  221. package/dist/simulation/index.d.ts.map +1 -1
  222. package/dist/simulation/index.js +2 -0
  223. package/dist/simulation/index.js.map +1 -1
  224. package/dist/two-d/pixi-interop.d.ts +18 -6
  225. package/dist/two-d/pixi-interop.d.ts.map +1 -1
  226. package/dist/two-d/pixi-interop.js +18 -6
  227. package/dist/two-d/pixi-interop.js.map +1 -1
  228. package/dist/two-d/render/AnimatedSprite.d.ts +74 -7
  229. package/dist/two-d/render/AnimatedSprite.d.ts.map +1 -1
  230. package/dist/two-d/render/AnimatedSprite.js +88 -26
  231. package/dist/two-d/render/AnimatedSprite.js.map +1 -1
  232. package/dist/two-d/render/Camera.d.ts +64 -4
  233. package/dist/two-d/render/Camera.d.ts.map +1 -1
  234. package/dist/two-d/render/Camera.js +132 -11
  235. package/dist/two-d/render/Camera.js.map +1 -1
  236. package/dist/two-d/render/ColorTransformBatcher.d.ts +7 -1
  237. package/dist/two-d/render/ColorTransformBatcher.d.ts.map +1 -1
  238. package/dist/two-d/render/ColorTransformBatcher.js +10 -1
  239. package/dist/two-d/render/ColorTransformBatcher.js.map +1 -1
  240. package/dist/two-d/render/Halo.d.ts +58 -0
  241. package/dist/two-d/render/Halo.d.ts.map +1 -0
  242. package/dist/two-d/render/Halo.js +48 -0
  243. package/dist/two-d/render/Halo.js.map +1 -0
  244. package/dist/two-d/render/ImageModifiers.d.ts +174 -0
  245. package/dist/two-d/render/ImageModifiers.d.ts.map +1 -1
  246. package/dist/two-d/render/ImageModifiers.js +454 -1
  247. package/dist/two-d/render/ImageModifiers.js.map +1 -1
  248. package/dist/two-d/render/LightningArc.d.ts +57 -0
  249. package/dist/two-d/render/LightningArc.d.ts.map +1 -0
  250. package/dist/two-d/render/LightningArc.js +91 -0
  251. package/dist/two-d/render/LightningArc.js.map +1 -0
  252. package/dist/two-d/render/PaletteRemap.d.ts +135 -0
  253. package/dist/two-d/render/PaletteRemap.d.ts.map +1 -0
  254. package/dist/two-d/render/PaletteRemap.js +181 -0
  255. package/dist/two-d/render/PaletteRemap.js.map +1 -0
  256. package/dist/two-d/render/Particles.d.ts +26 -0
  257. package/dist/two-d/render/Particles.d.ts.map +1 -1
  258. package/dist/two-d/render/Particles.js +23 -2
  259. package/dist/two-d/render/Particles.js.map +1 -1
  260. package/dist/two-d/render/SpriteAttachment.d.ts +55 -0
  261. package/dist/two-d/render/SpriteAttachment.d.ts.map +1 -0
  262. package/dist/two-d/render/SpriteAttachment.js +60 -0
  263. package/dist/two-d/render/SpriteAttachment.js.map +1 -0
  264. package/dist/two-d/render/TerrainGraphics.d.ts +142 -0
  265. package/dist/two-d/render/TerrainGraphics.d.ts.map +1 -0
  266. package/dist/two-d/render/TerrainGraphics.js +161 -0
  267. package/dist/two-d/render/TerrainGraphics.js.map +1 -0
  268. package/dist/two-d/render/TerrainGraphicsLayer.d.ts +55 -0
  269. package/dist/two-d/render/TerrainGraphicsLayer.d.ts.map +1 -0
  270. package/dist/two-d/render/TerrainGraphicsLayer.js +54 -0
  271. package/dist/two-d/render/TerrainGraphicsLayer.js.map +1 -0
  272. package/dist/two-d/render/TintedSprite.js +2 -2
  273. package/dist/two-d/render/TintedSprite.js.map +1 -1
  274. package/dist/two-d/render/index.d.ts +15 -3
  275. package/dist/two-d/render/index.d.ts.map +1 -1
  276. package/dist/two-d/render/index.js +7 -1
  277. package/dist/two-d/render/index.js.map +1 -1
  278. package/dist/two-d/stage/StoryScreen.d.ts +110 -0
  279. package/dist/two-d/stage/StoryScreen.d.ts.map +1 -0
  280. package/dist/two-d/stage/StoryScreen.js +178 -0
  281. package/dist/two-d/stage/StoryScreen.js.map +1 -0
  282. package/dist/two-d/stage/index.d.ts +2 -0
  283. package/dist/two-d/stage/index.d.ts.map +1 -1
  284. package/dist/two-d/stage/index.js +1 -0
  285. package/dist/two-d/stage/index.js.map +1 -1
  286. package/dist/two-d/ui/Checkbox.d.ts +44 -0
  287. package/dist/two-d/ui/Checkbox.d.ts.map +1 -0
  288. package/dist/two-d/ui/Checkbox.js +89 -0
  289. package/dist/two-d/ui/Checkbox.js.map +1 -0
  290. package/dist/two-d/ui/DataTable.d.ts +79 -0
  291. package/dist/two-d/ui/DataTable.d.ts.map +1 -0
  292. package/dist/two-d/ui/DataTable.js +164 -0
  293. package/dist/two-d/ui/DataTable.js.map +1 -0
  294. package/dist/two-d/ui/Dropdown.d.ts +72 -0
  295. package/dist/two-d/ui/Dropdown.d.ts.map +1 -0
  296. package/dist/two-d/ui/Dropdown.js +126 -0
  297. package/dist/two-d/ui/Dropdown.js.map +1 -0
  298. package/dist/two-d/ui/FloatingText.d.ts +43 -4
  299. package/dist/two-d/ui/FloatingText.d.ts.map +1 -1
  300. package/dist/two-d/ui/FloatingText.js +52 -5
  301. package/dist/two-d/ui/FloatingText.js.map +1 -1
  302. package/dist/two-d/ui/FloatingTextStack.d.ts +86 -13
  303. package/dist/two-d/ui/FloatingTextStack.d.ts.map +1 -1
  304. package/dist/two-d/ui/FloatingTextStack.js +89 -18
  305. package/dist/two-d/ui/FloatingTextStack.js.map +1 -1
  306. package/dist/two-d/ui/Layout.d.ts +105 -0
  307. package/dist/two-d/ui/Layout.d.ts.map +1 -0
  308. package/dist/two-d/ui/Layout.js +174 -0
  309. package/dist/two-d/ui/Layout.js.map +1 -0
  310. package/dist/two-d/ui/MarkupText.d.ts +53 -0
  311. package/dist/two-d/ui/MarkupText.d.ts.map +1 -0
  312. package/dist/two-d/ui/MarkupText.js +122 -0
  313. package/dist/two-d/ui/MarkupText.js.map +1 -0
  314. package/dist/two-d/ui/ScrollBox.d.ts +67 -0
  315. package/dist/two-d/ui/ScrollBox.d.ts.map +1 -0
  316. package/dist/two-d/ui/ScrollBox.js +127 -0
  317. package/dist/two-d/ui/ScrollBox.js.map +1 -0
  318. package/dist/two-d/ui/Skins.d.ts +59 -0
  319. package/dist/two-d/ui/Skins.d.ts.map +1 -0
  320. package/dist/two-d/ui/Skins.js +77 -0
  321. package/dist/two-d/ui/Skins.js.map +1 -0
  322. package/dist/two-d/ui/Slider.d.ts +91 -0
  323. package/dist/two-d/ui/Slider.d.ts.map +1 -0
  324. package/dist/two-d/ui/Slider.js +170 -0
  325. package/dist/two-d/ui/Slider.js.map +1 -0
  326. package/dist/two-d/ui/Spinner.d.ts +67 -0
  327. package/dist/two-d/ui/Spinner.d.ts.map +1 -0
  328. package/dist/two-d/ui/Spinner.js +137 -0
  329. package/dist/two-d/ui/Spinner.js.map +1 -0
  330. package/dist/two-d/ui/TabbedList.d.ts +118 -0
  331. package/dist/two-d/ui/TabbedList.d.ts.map +1 -0
  332. package/dist/two-d/ui/TabbedList.js +221 -0
  333. package/dist/two-d/ui/TabbedList.js.map +1 -0
  334. package/dist/two-d/ui/TextModel.d.ts +65 -0
  335. package/dist/two-d/ui/TextModel.d.ts.map +1 -0
  336. package/dist/two-d/ui/TextModel.js +126 -0
  337. package/dist/two-d/ui/TextModel.js.map +1 -0
  338. package/dist/two-d/ui/TreeView.d.ts +68 -0
  339. package/dist/two-d/ui/TreeView.d.ts.map +1 -0
  340. package/dist/two-d/ui/TreeView.js +133 -0
  341. package/dist/two-d/ui/TreeView.js.map +1 -0
  342. package/dist/two-d/ui/Window.d.ts +13 -0
  343. package/dist/two-d/ui/Window.d.ts.map +1 -1
  344. package/dist/two-d/ui/Window.js +23 -0
  345. package/dist/two-d/ui/Window.js.map +1 -1
  346. package/dist/two-d/ui/WindowStack.d.ts.map +1 -1
  347. package/dist/two-d/ui/WindowStack.js +2 -0
  348. package/dist/two-d/ui/WindowStack.js.map +1 -1
  349. package/dist/two-d/ui/index.d.ts +29 -3
  350. package/dist/two-d/ui/index.d.ts.map +1 -1
  351. package/dist/two-d/ui/index.js +15 -2
  352. package/dist/two-d/ui/index.js.map +1 -1
  353. package/dist/two-d/ui/markup.d.ts +181 -0
  354. package/dist/two-d/ui/markup.d.ts.map +1 -0
  355. package/dist/two-d/ui/markup.js +370 -0
  356. package/dist/two-d/ui/markup.js.map +1 -0
  357. package/dist/version.d.ts +1 -1
  358. package/dist/version.js +1 -1
  359. package/dist/world/SideTurns.d.ts +115 -0
  360. package/dist/world/SideTurns.d.ts.map +1 -0
  361. package/dist/world/SideTurns.js +138 -0
  362. package/dist/world/SideTurns.js.map +1 -0
  363. package/dist/world/index.d.ts +2 -0
  364. package/dist/world/index.d.ts.map +1 -1
  365. package/dist/world/index.js +1 -0
  366. package/dist/world/index.js.map +1 -1
  367. package/package.json +2 -1
@@ -0,0 +1,164 @@
1
+ import { Signal } from '../../core/Signal.js';
2
+ /**
3
+ * A columned table with a highlighted row, a sort order and paging - the roster or inventory grid
4
+ * that wants headers and a stable sort, where `ListView` is a flat one-column list.
5
+ *
6
+ * Renderer-free, like `TabbedList`: it holds the columns, the rows, the sort, the highlight and
7
+ * the current page, and a game draws the cells. The page is *derived* from the highlighted row
8
+ * rather than tracked beside it, so the two can never disagree; `setPage` is the only thing that
9
+ * moves the highlight on its own, and it lands on the first selectable row of that page.
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * import { DataTable } from '@datamoc/mw_games/two-d/ui';
14
+ *
15
+ * const roster = new DataTable({
16
+ * columns: [{ key: 'name' }, { key: 'level' }],
17
+ * rows: [{ name: 'Ash', level: 3 }, { name: 'Bo', level: 1 }],
18
+ * });
19
+ * roster.sortBy('level');
20
+ * console.log(roster.rows[0].name); // 'Bo'
21
+ * ```
22
+ */
23
+ export class DataTable {
24
+ constructor(options) {
25
+ this.onChange = new Signal();
26
+ this.current = 0;
27
+ this.sortKey_ = null;
28
+ this.ascending = true;
29
+ this.columns_ = [...options.columns];
30
+ this.rows_ = [...(options.rows ?? [])];
31
+ this.pageSize_ = options.pageSize ?? 0;
32
+ this.disabledOf = options.disabled ?? (() => false);
33
+ this.current = this.firstEnabled();
34
+ }
35
+ get columns() {
36
+ return this.columns_;
37
+ }
38
+ get rows() {
39
+ return this.rows_;
40
+ }
41
+ get pageSize() {
42
+ return this.pageSize_;
43
+ }
44
+ get sortKey() {
45
+ return this.sortKey_;
46
+ }
47
+ get sortAscending() {
48
+ return this.ascending;
49
+ }
50
+ get selectedIndex() {
51
+ return this.current;
52
+ }
53
+ get selected() {
54
+ return this.rows_[this.current] ?? null;
55
+ }
56
+ /** the page the highlighted row is on, 0 when there is no paging */
57
+ get page() {
58
+ return this.pageSize_ > 0 ? Math.floor(this.current / this.pageSize_) : 0;
59
+ }
60
+ /** how many pages there are; at least one, so an empty table still has a page 0 */
61
+ get pageCount() {
62
+ return this.pageSize_ > 0 ? Math.max(1, Math.ceil(this.rows_.length / this.pageSize_)) : 1;
63
+ }
64
+ get pageRows() {
65
+ if (this.pageSize_ <= 0)
66
+ return this.rows_;
67
+ const start = this.page * this.pageSize_;
68
+ return this.rows_.slice(start, start + this.pageSize_);
69
+ }
70
+ setRows(rows) {
71
+ this.rows_ = [...rows];
72
+ this.current = this.firstEnabled();
73
+ this.onChange.dispatch();
74
+ }
75
+ setColumns(columns) {
76
+ this.columns_ = [...columns];
77
+ if (this.sortKey_ && !this.columns_.some((column) => column.key === this.sortKey_))
78
+ this.sortKey_ = null;
79
+ this.onChange.dispatch();
80
+ }
81
+ setPageSize(size) {
82
+ this.pageSize_ = Math.max(0, size);
83
+ this.onChange.dispatch();
84
+ }
85
+ /**
86
+ * Sorts by a column, ascending the first time and toggling on a repeat of the same key.
87
+ * The highlight returns to the first selectable row, since the row it pointed at moved.
88
+ */
89
+ sortBy(key) {
90
+ const column = this.columns_.find((candidate) => candidate.key === key);
91
+ if (!column)
92
+ return;
93
+ if (this.sortKey_ === key)
94
+ this.ascending = !this.ascending;
95
+ else {
96
+ this.sortKey_ = key;
97
+ this.ascending = true;
98
+ }
99
+ const compare = column.compare ?? ((a, b) => genericCompare(valueAt(a, key), valueAt(b, key)));
100
+ this.rows_.sort((a, b) => (this.ascending ? 1 : -1) * compare(a, b));
101
+ this.current = this.firstEnabled();
102
+ this.onChange.dispatch();
103
+ }
104
+ select(index) {
105
+ if (index < 0 || index >= this.rows_.length || this.disabledOf(this.rows_[index]))
106
+ return;
107
+ this.current = index;
108
+ this.onChange.dispatch();
109
+ }
110
+ /** moves the highlight a row at a time, skipping disabled rows and stopping at the ends */
111
+ move(delta) {
112
+ const count = this.rows_.length;
113
+ if (count === 0)
114
+ return;
115
+ let index = this.current;
116
+ for (let tried = 0; tried < count; tried++) {
117
+ index += delta;
118
+ if (index < 0 || index >= count)
119
+ return;
120
+ if (!this.disabledOf(this.rows_[index])) {
121
+ this.current = index;
122
+ this.onChange.dispatch();
123
+ return;
124
+ }
125
+ }
126
+ }
127
+ /** moves to a page and highlights its first selectable row */
128
+ setPage(page) {
129
+ if (this.pageSize_ <= 0)
130
+ return;
131
+ const target = Math.max(0, Math.min(this.pageCount - 1, page));
132
+ const start = target * this.pageSize_;
133
+ const end = Math.min(start + this.pageSize_, this.rows_.length);
134
+ for (let index = start; index < end; index++) {
135
+ if (!this.disabledOf(this.rows_[index])) {
136
+ this.current = index;
137
+ this.onChange.dispatch();
138
+ return;
139
+ }
140
+ }
141
+ }
142
+ nextPage(delta = 1) {
143
+ this.setPage(this.page + delta);
144
+ }
145
+ firstEnabled() {
146
+ const index = this.rows_.findIndex((row) => !this.disabledOf(row));
147
+ return index === -1 ? 0 : index;
148
+ }
149
+ }
150
+ function valueAt(row, key) {
151
+ return row && typeof row === 'object' ? row[key] : undefined;
152
+ }
153
+ function genericCompare(a, b) {
154
+ if (a === b)
155
+ return 0;
156
+ if (a === undefined)
157
+ return -1;
158
+ if (b === undefined)
159
+ return 1;
160
+ if (typeof a === 'number' && typeof b === 'number')
161
+ return a - b;
162
+ return String(a).localeCompare(String(b));
163
+ }
164
+ //# sourceMappingURL=DataTable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DataTable.js","sourceRoot":"","sources":["../../../src/two-d/ui/DataTable.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+ import { Signal } from '../../core/Signal.ts';
2
+ export interface DropdownOption {
3
+ /** the value the game reads back; the label when omitted */
4
+ id?: string;
5
+ label: string;
6
+ disabled?: boolean;
7
+ }
8
+ export interface DropdownOptions {
9
+ options: readonly DropdownOption[];
10
+ /** the entry selected from the start; the first enabled one when omitted */
11
+ selectedIndex?: number;
12
+ disabled?: boolean;
13
+ }
14
+ /**
15
+ * A closed button that opens a list of options - the "option button" a settings row or a
16
+ * scenario picker drops down.
17
+ *
18
+ * Renderer-free, like `TabbedList`: the state is the whole widget's mind, and a game draws the
19
+ * button's label and the open list wherever its own layout wants them. The rule worth naming is
20
+ * that opening restores the highlight to the current selection, so the first arrow key does not
21
+ * jump from wherever the highlight was last, and a disabled option is skipped by the highlight
22
+ * exactly as `ListView` skips one.
23
+ *
24
+ * @example
25
+ * ```ts
26
+ * import { Dropdown } from '@datamoc/mw_games/two-d/ui';
27
+ *
28
+ * const difficulty = new Dropdown({
29
+ * options: [{ id: 'easy', label: 'Easy' }, { id: 'normal', label: 'Normal' }],
30
+ * });
31
+ * difficulty.open();
32
+ * difficulty.move(1);
33
+ * difficulty.confirm();
34
+ * console.log(difficulty.selected?.id); // 'normal'
35
+ * ```
36
+ */
37
+ export declare class Dropdown {
38
+ readonly onChange: Signal<{
39
+ option: DropdownOption;
40
+ index: number;
41
+ }>;
42
+ private options_;
43
+ private current;
44
+ private highlight_;
45
+ private open_;
46
+ private disabled_;
47
+ constructor(options: DropdownOptions);
48
+ get options(): readonly DropdownOption[];
49
+ get selectedIndex(): number;
50
+ /** the selected entry; the first enabled one when nothing was selected, `null` when empty */
51
+ get selected(): DropdownOption | null;
52
+ get isOpen(): boolean;
53
+ get disabled(): boolean;
54
+ /** the row an open list has highlighted, which is what a confirm would take */
55
+ get highlight(): number;
56
+ setDisabled(disabled: boolean): void;
57
+ setOptions(options: readonly DropdownOption[]): void;
58
+ /** opens the list, restoring the highlight to the current selection */
59
+ open(): void;
60
+ close(): void;
61
+ toggleOpen(): void;
62
+ /** moves the highlight by `delta` rows, skipping disabled entries and wrapping at both ends */
63
+ move(delta: number): void;
64
+ /** opens the list and highlights `index`, if it is enabled */
65
+ setHighlight(index: number): void;
66
+ /** takes the highlighted row: closes, selects it, and fires `onChange` when it moved */
67
+ confirm(): boolean;
68
+ /** closes the list without taking anything, the escape key's own action */
69
+ cancel(): void;
70
+ private firstEnabled;
71
+ }
72
+ //# sourceMappingURL=Dropdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Dropdown.d.ts","sourceRoot":"","sources":["../../../src/two-d/ui/Dropdown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAE9C,MAAM,WAAW,cAAc;IAC9B,4DAA4D;IAC5D,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC/B,OAAO,EAAE,SAAS,cAAc,EAAE,CAAC;IACnC,4EAA4E;IAC5E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,QAAQ;IACpB,QAAQ,CAAC,QAAQ;gBAAwB,cAAc;eAAS,MAAM;OAAM;IAE5E,OAAO,CAAC,QAAQ,CAAmB;IACnC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,SAAS,CAAU;IAE3B,YAAY,OAAO,EAAE,eAAe,EAMnC;IAED,IAAI,OAAO,IAAI,SAAS,cAAc,EAAE,CAEvC;IAED,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED,6FAA6F;IAC7F,IAAI,QAAQ,IAAI,cAAc,GAAG,IAAI,CAEpC;IAED,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED,+EAA+E;IAC/E,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,WAAW,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAGnC;IAED,UAAU,CAAC,OAAO,EAAE,SAAS,cAAc,EAAE,GAAG,IAAI,CAKnD;IAED,uEAAuE;IACvE,IAAI,IAAI,IAAI,CAIX;IAED,KAAK,IAAI,IAAI,CAEZ;IAED,UAAU,IAAI,IAAI,CAGjB;IAED,+FAA+F;IAC/F,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAWxB;IAED,8DAA8D;IAC9D,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAGhC;IAED,wFAAwF;IACxF,OAAO,IAAI,OAAO,CAUjB;IAED,2EAA2E;IAC3E,MAAM,IAAI,IAAI,CAGb;IAED,OAAO,CAAC,YAAY;CAIpB"}
@@ -0,0 +1,126 @@
1
+ import { Signal } from '../../core/Signal.js';
2
+ /**
3
+ * A closed button that opens a list of options - the "option button" a settings row or a
4
+ * scenario picker drops down.
5
+ *
6
+ * Renderer-free, like `TabbedList`: the state is the whole widget's mind, and a game draws the
7
+ * button's label and the open list wherever its own layout wants them. The rule worth naming is
8
+ * that opening restores the highlight to the current selection, so the first arrow key does not
9
+ * jump from wherever the highlight was last, and a disabled option is skipped by the highlight
10
+ * exactly as `ListView` skips one.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * import { Dropdown } from '@datamoc/mw_games/two-d/ui';
15
+ *
16
+ * const difficulty = new Dropdown({
17
+ * options: [{ id: 'easy', label: 'Easy' }, { id: 'normal', label: 'Normal' }],
18
+ * });
19
+ * difficulty.open();
20
+ * difficulty.move(1);
21
+ * difficulty.confirm();
22
+ * console.log(difficulty.selected?.id); // 'normal'
23
+ * ```
24
+ */
25
+ export class Dropdown {
26
+ constructor(options) {
27
+ this.onChange = new Signal();
28
+ this.open_ = false;
29
+ this.options_ = [...options.options];
30
+ this.disabled_ = options.disabled ?? false;
31
+ const requested = options.selectedIndex ?? this.firstEnabled();
32
+ this.current = this.options_[requested]?.disabled ? this.firstEnabled() : requested;
33
+ this.highlight_ = this.current;
34
+ }
35
+ get options() {
36
+ return this.options_;
37
+ }
38
+ get selectedIndex() {
39
+ return this.current;
40
+ }
41
+ /** the selected entry; the first enabled one when nothing was selected, `null` when empty */
42
+ get selected() {
43
+ return this.options_[this.current] ?? null;
44
+ }
45
+ get isOpen() {
46
+ return this.open_;
47
+ }
48
+ get disabled() {
49
+ return this.disabled_;
50
+ }
51
+ /** the row an open list has highlighted, which is what a confirm would take */
52
+ get highlight() {
53
+ return this.highlight_;
54
+ }
55
+ setDisabled(disabled) {
56
+ this.disabled_ = disabled;
57
+ if (disabled)
58
+ this.open_ = false;
59
+ }
60
+ setOptions(options) {
61
+ this.options_ = [...options];
62
+ this.current = this.firstEnabled();
63
+ this.highlight_ = this.current;
64
+ this.open_ = false;
65
+ }
66
+ /** opens the list, restoring the highlight to the current selection */
67
+ open() {
68
+ if (this.disabled_ || this.open_)
69
+ return;
70
+ this.open_ = true;
71
+ this.highlight_ = this.current;
72
+ }
73
+ close() {
74
+ this.open_ = false;
75
+ }
76
+ toggleOpen() {
77
+ if (this.open_)
78
+ this.close();
79
+ else
80
+ this.open();
81
+ }
82
+ /** moves the highlight by `delta` rows, skipping disabled entries and wrapping at both ends */
83
+ move(delta) {
84
+ if (!this.open_ || this.options_.length === 0)
85
+ return;
86
+ const count = this.options_.length;
87
+ let index = this.highlight_;
88
+ for (let tried = 0; tried < count; tried++) {
89
+ index = (((index + delta) % count) + count) % count;
90
+ if (!this.options_[index].disabled) {
91
+ this.highlight_ = index;
92
+ return;
93
+ }
94
+ }
95
+ }
96
+ /** opens the list and highlights `index`, if it is enabled */
97
+ setHighlight(index) {
98
+ if (index < 0 || index >= this.options_.length || this.options_[index].disabled)
99
+ return;
100
+ this.highlight_ = index;
101
+ }
102
+ /** takes the highlighted row: closes, selects it, and fires `onChange` when it moved */
103
+ confirm() {
104
+ if (!this.open_)
105
+ return false;
106
+ const option = this.options_[this.highlight_];
107
+ if (!option || option.disabled)
108
+ return false;
109
+ this.open_ = false;
110
+ if (this.highlight_ !== this.current) {
111
+ this.current = this.highlight_;
112
+ this.onChange.dispatch({ option, index: this.current });
113
+ }
114
+ return true;
115
+ }
116
+ /** closes the list without taking anything, the escape key's own action */
117
+ cancel() {
118
+ this.open_ = false;
119
+ this.highlight_ = this.current;
120
+ }
121
+ firstEnabled() {
122
+ const index = this.options_.findIndex((option) => !option.disabled);
123
+ return index === -1 ? 0 : index;
124
+ }
125
+ }
126
+ //# sourceMappingURL=Dropdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Dropdown.js","sourceRoot":"","sources":["../../../src/two-d/ui/Dropdown.ts"],"names":[],"mappings":"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"}
@@ -39,6 +39,31 @@ export declare function floatingTextAlpha(t: number, hold: number): number;
39
39
  * ```
40
40
  */
41
41
  export declare function floatingTextRise(t: number, rise: number, reduce?: boolean): number;
42
+ /**
43
+ * The age a pop-up should report, given the age it has, its lifetime, and the age it is forced to
44
+ * be at least.
45
+ *
46
+ * Java's rule as arithmetic. Java caps what is *left*,
47
+ * `above.timeLeft = Math.min(above.timeLeft, LIFESPAN - numBelow / 5f)`, and a cap on what is left
48
+ * is a floor under the age. A floor and not a subtraction, on purpose: a line that has already
49
+ * lived longer than the floor keeps the age it has, where subtracting would shorten it a second
50
+ * time and cut a nearly-finished pop-up dead. A burst of numbers still cannot become a column that
51
+ * outlives the fight, which is what the rule is there for. Clamped to the lifetime as well, so a
52
+ * floor past the end finishes the pop-up on its next update instead of jumping through the rest of
53
+ * its rise.
54
+ *
55
+ * Pulled out of the class for the same reason `floatingTextAlpha` is: `FloatingText` needs a DOM
56
+ * to build, and a rule does not need one to be checked.
57
+ *
58
+ * @example
59
+ * ```ts
60
+ * import { floatingTextAgeAtLeast } from '@datamoc/mw_games/two-d/ui';
61
+ *
62
+ * console.log(floatingTextAgeAtLeast(0, 1, 0.2)); // 0.2, a fresh line is pushed forward
63
+ * console.log(floatingTextAgeAtLeast(0.5, 1, 0.2)); // 0.5, an older line keeps the age it has
64
+ * ```
65
+ */
66
+ export declare function floatingTextAgeAtLeast(elapsed: number, duration: number, atLeast: number): number;
42
67
  /**
43
68
  * A damage number or a "+1 gold": text that rises and fades over its own lifetime, unlike
44
69
  * `Label`'s job of a static, positioned string. This is animation over a label, timed rather
@@ -67,17 +92,31 @@ export declare class FloatingText extends Container {
67
92
  private readonly rise;
68
93
  private readonly hold;
69
94
  /**
70
- * The label's own layer: the rise moves this rather than the container itself, so
71
- * `position` stays exactly where the caller put it. Writing `this.y` in `update` instead
72
- * would overwrite the world point the pop-up is meant to sit over on its first frame.
95
+ * The label's own layer, and the layer the rise moves. `position` therefore stays exactly where
96
+ * the caller put it, whoever moved it last: writing `this.y` in `update` instead would overwrite
97
+ * the world point the pop-up sits over, and would silently undo a lift `FloatingTextStack`
98
+ * applies to a line that has already been on screen for a frame. That is not hypothetical, it is
99
+ * exactly how the first version of the stack's lift was lost.
73
100
  */
74
101
  private readonly rising;
75
102
  private elapsed;
76
103
  private done;
77
- private baseY;
78
104
  constructor(options: FloatingTextOptions);
79
105
  /** true once the animation has finished and this container has removed and destroyed itself */
80
106
  get finished(): boolean;
107
+ /**
108
+ * How far the animation has lifted the text above where it was placed, in pixels: 0 at the
109
+ * start, negative as it rises, and 0 again under reduced motion. The drawn position is
110
+ * `y + riseOffset`, while `y` itself never moves, which is what lets a caller (a stack, a game
111
+ * following a moving creature) place a pop-up that is already animating.
112
+ */
113
+ get riseOffset(): number;
114
+ /**
115
+ * Ages the pop-up to at least `seconds` - what a stack does to the lines it lifts out of the
116
+ * way. `floatingTextAgeAtLeast` is that arithmetic, and says why it is a floor under the age
117
+ * rather than a subtraction from what is left.
118
+ */
119
+ ageAtLeast(seconds: number): void;
81
120
  /** advances the rise/fade; once complete, removes itself from its parent and destroys itself */
82
121
  update(dt: number): void;
83
122
  }
@@ -1 +1 @@
1
- {"version":3,"file":"FloatingText.d.ts","sourceRoot":"","sources":["../../../src/two-d/ui/FloatingText.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAIpC,MAAM,WAAW,mBAAmB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,8DAA8D;IAC9D,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAIjE;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,UAAQ,GAAG,MAAM,CAKhF;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,YAAa,SAAQ,SAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAE9B;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;IAE1C,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,KAAK,CAAqB;IAElC,YAAY,OAAO,EAAE,mBAAmB,EAWvC;IAED,+FAA+F;IAC/F,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED,gGAAgG;IAChG,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAgBvB;CACD"}
1
+ {"version":3,"file":"FloatingText.d.ts","sourceRoot":"","sources":["../../../src/two-d/ui/FloatingText.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAIpC,MAAM,WAAW,mBAAmB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,8DAA8D;IAC9D,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAIjE;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,UAAQ,GAAG,MAAM,CAKhF;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAGjG;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,YAAa,SAAQ,SAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAE9B;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;IAE1C,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,IAAI,CAAS;IAErB,YAAY,OAAO,EAAE,mBAAmB,EAWvC;IAED,+FAA+F;IAC/F,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED;;;;;OAKG;IACH,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED;;;;OAIG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEhC;IAED,gGAAgG;IAChG,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAevB;CACD"}
@@ -38,6 +38,35 @@ export function floatingTextRise(t, rise, reduce = false) {
38
38
  return 0;
39
39
  return -rise * t;
40
40
  }
41
+ /**
42
+ * The age a pop-up should report, given the age it has, its lifetime, and the age it is forced to
43
+ * be at least.
44
+ *
45
+ * Java's rule as arithmetic. Java caps what is *left*,
46
+ * `above.timeLeft = Math.min(above.timeLeft, LIFESPAN - numBelow / 5f)`, and a cap on what is left
47
+ * is a floor under the age. A floor and not a subtraction, on purpose: a line that has already
48
+ * lived longer than the floor keeps the age it has, where subtracting would shorten it a second
49
+ * time and cut a nearly-finished pop-up dead. A burst of numbers still cannot become a column that
50
+ * outlives the fight, which is what the rule is there for. Clamped to the lifetime as well, so a
51
+ * floor past the end finishes the pop-up on its next update instead of jumping through the rest of
52
+ * its rise.
53
+ *
54
+ * Pulled out of the class for the same reason `floatingTextAlpha` is: `FloatingText` needs a DOM
55
+ * to build, and a rule does not need one to be checked.
56
+ *
57
+ * @example
58
+ * ```ts
59
+ * import { floatingTextAgeAtLeast } from '@datamoc/mw_games/two-d/ui';
60
+ *
61
+ * console.log(floatingTextAgeAtLeast(0, 1, 0.2)); // 0.2, a fresh line is pushed forward
62
+ * console.log(floatingTextAgeAtLeast(0.5, 1, 0.2)); // 0.5, an older line keeps the age it has
63
+ * ```
64
+ */
65
+ export function floatingTextAgeAtLeast(elapsed, duration, atLeast) {
66
+ if (atLeast <= 0)
67
+ return elapsed;
68
+ return Math.max(elapsed, Math.min(atLeast, duration));
69
+ }
41
70
  /**
42
71
  * A damage number or a "+1 gold": text that rises and fades over its own lifetime, unlike
43
72
  * `Label`'s job of a static, positioned string. This is animation over a label, timed rather
@@ -65,9 +94,11 @@ export class FloatingText extends Container {
65
94
  constructor(options) {
66
95
  super();
67
96
  /**
68
- * The label's own layer: the rise moves this rather than the container itself, so
69
- * `position` stays exactly where the caller put it. Writing `this.y` in `update` instead
70
- * would overwrite the world point the pop-up is meant to sit over on its first frame.
97
+ * The label's own layer, and the layer the rise moves. `position` therefore stays exactly where
98
+ * the caller put it, whoever moved it last: writing `this.y` in `update` instead would overwrite
99
+ * the world point the pop-up sits over, and would silently undo a lift `FloatingTextStack`
100
+ * applies to a line that has already been on screen for a frame. That is not hypothetical, it is
101
+ * exactly how the first version of the stack's lift was lost.
71
102
  */
72
103
  this.rising = new Container();
73
104
  this.elapsed = 0;
@@ -84,6 +115,23 @@ export class FloatingText extends Container {
84
115
  get finished() {
85
116
  return this.done;
86
117
  }
118
+ /**
119
+ * How far the animation has lifted the text above where it was placed, in pixels: 0 at the
120
+ * start, negative as it rises, and 0 again under reduced motion. The drawn position is
121
+ * `y + riseOffset`, while `y` itself never moves, which is what lets a caller (a stack, a game
122
+ * following a moving creature) place a pop-up that is already animating.
123
+ */
124
+ get riseOffset() {
125
+ return this.rising.y;
126
+ }
127
+ /**
128
+ * Ages the pop-up to at least `seconds` - what a stack does to the lines it lifts out of the
129
+ * way. `floatingTextAgeAtLeast` is that arithmetic, and says why it is a floor under the age
130
+ * rather than a subtraction from what is left.
131
+ */
132
+ ageAtLeast(seconds) {
133
+ this.elapsed = floatingTextAgeAtLeast(this.elapsed, this.duration, seconds);
134
+ }
87
135
  /** advances the rise/fade; once complete, removes itself from its parent and destroys itself */
88
136
  update(dt) {
89
137
  if (this.done)
@@ -92,8 +140,7 @@ export class FloatingText extends Container {
92
140
  const t = this.duration > 0 ? this.elapsed / this.duration : 1;
93
141
  //the rise is peripheral movement beside whatever the player is reading; reduced
94
142
  //motion keeps the fade and drops the travel, so the number still appears and goes
95
- this.baseY ??= this.y;
96
- this.y = this.baseY + floatingTextRise(t, this.rise, reducedMotion());
143
+ this.rising.y = floatingTextRise(t, this.rise, reducedMotion());
97
144
  this.alpha = floatingTextAlpha(t, this.hold);
98
145
  if (t >= 1) {
99
146
  this.done = true;
@@ -1 +1 @@
1
- {"version":3,"file":"FloatingText.js","sourceRoot":"","sources":["../../../src/two-d/ui/FloatingText.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"FloatingText.js","sourceRoot":"","sources":["../../../src/two-d/ui/FloatingText.ts"],"names":[],"mappings":"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"}