@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
@@ -1,43 +1,109 @@
1
1
  import { Container } from 'pixi.js';
2
2
  import { FloatingText, type FloatingTextOptions } from './FloatingText.ts';
3
3
  /**
4
- * One pop-up the stack knows about: where it was asked to appear, how tall it is, and what it
5
- * stacks against.
4
+ * One pop-up the stack knows about: where it sits right now, how tall it is, and what it stacks
5
+ * against.
6
6
  */
7
7
  export interface FloatingTextStackEntry {
8
8
  /** pop-ups sharing a key are stacked apart; leave it unset for one that stands alone */
9
9
  key?: string | number;
10
- /** the world point, as asked for - not wherever stacking moved the pop-up to */
10
+ /**
11
+ * Where the pop-up is placed, at its centre - stacking moves the older ones, never a newcomer.
12
+ *
13
+ * This is the box the rise happens *inside* (`FloatingText` rises its own inner layer), so the
14
+ * arithmetic below compares where lines are put rather than where one frame caught them: a burst
15
+ * stacks the same way whatever the frame rate, where Java compares live positions.
16
+ */
11
17
  x: number;
12
18
  y: number;
13
19
  /** the pop-up's own height, measured rather than assumed */
14
20
  height: number;
15
21
  }
22
+ /** The vertical gap left between two stacked lines - Java's `FloatingText.push()` uses `4`. */
23
+ export declare const FLOATING_TEXT_STACK_GAP = 4;
16
24
  /**
17
- * How far a newcomer must move up to clear every live pop-up it shares a key *and* an origin
18
- * with - the classic "three numbers on one creature in one turn" case.
25
+ * The age a lifted line is forced to, in seconds, from how many lines sit below it - Java's
26
+ * `LIFESPAN - numBelow / 5f` read as a floor under the age rather than a cap on what is left, the
27
+ * same rule `FloatingText.ageAtLeast` applies. One second per five lines, a fifth of a second each,
28
+ * so a burst of numbers cannot become a column that outlives the fight that produced it.
29
+ */
30
+ export declare function floatingTextStackLifePenalty(linesBelow: number): number;
31
+ /**
32
+ * The `y` `older` must sit at to clear `below`, or `older.y` when it already does.
33
+ *
34
+ * The direction is the point, and it is why this returns a *position* rather than an offset to add:
35
+ * Java's `FloatingText.push()` anchors the newcomer on the target and lifts the lines already there
36
+ * (`above.setPos(above.left(), below.top() - above.height() - 4)`), the opposite of moving the
37
+ * newcomer out of the way. Pop-ups rise, so the older ones belong above the newer ones - an offset
38
+ * the caller adds is direction-ambiguous, a position the caller assigns is not.
39
+ *
40
+ * Both boxes are anchored at their centre, so a line's top is `y - height / 2`; a line is clear when
41
+ * its bottom plus the gap no longer reaches the other's top.
19
42
  *
20
43
  * Exported and pure on purpose: the stacking rule is arithmetic, and this way it is checked as
21
44
  * arithmetic rather than through a rendered label (`Label` needs a DOM to measure text).
22
- * Offsets accumulate by measured height, so a taller line clears the one under it rather than
23
- * overlapping it by a fixed guess.
45
+ */
46
+ export declare function floatingTextStackLift(older: FloatingTextStackEntry, below: FloatingTextStackEntry, gap?: number): number;
47
+ /** One line a newcomer pushes out of the way, and what that costs it. */
48
+ export interface FloatingTextStackMove {
49
+ /** index into the `live` entries the policy was handed */
50
+ readonly index: number;
51
+ /** where the line ends up: the position to give it, not an offset to add */
52
+ readonly y: number;
53
+ /** the age the line is forced to, in seconds, from `floatingTextStackLifePenalty` */
54
+ readonly ageAtLeast: number;
55
+ }
56
+ /**
57
+ * The whole stacking policy as arithmetic: which of `live` (oldest first) share the newcomer's key,
58
+ * where each of them ends up, and what age each is forced to.
59
+ *
60
+ * Newest first, stopping at the first line already clear of the one below it: a stack is ordered,
61
+ * an older line sits above a newer one, so a line that needs no move means nothing above it does
62
+ * either. That is Java's `break`, and the reason the walk runs backwards over `live`.
63
+ *
64
+ * Pure and exported for the same reason `floatingTextStackLift` is: applying a plan needs a
65
+ * `FloatingText`, which is a `Label`, which needs a DOM. The decision is therefore checked as
66
+ * arithmetic and the class is left with the assignments. `push` inlined this loop once, and the
67
+ * loop is where the direction, the order and the life floor were all wrong at the same time.
24
68
  *
25
69
  * @example
26
70
  * ```ts
27
- * import { floatingTextStackOffset } from '@datamoc/mw_games/two-d/ui';
28
- * console.log(floatingTextStackOffset([{ key: 'hero', x: 1, y: 2, height: 10 }], { key: 'hero', x: 1, y: 2, height: 8 })); // 11
71
+ * import {
72
+ * FLOATING_TEXT_STACK_GAP,
73
+ * floatingTextStackLift,
74
+ * floatingTextStackLifePenalty,
75
+ * floatingTextStackMoves,
76
+ * } from '@datamoc/mw_games/two-d/ui';
77
+ *
78
+ * const older = { key: 'hero', x: 0, y: 0, height: 10 };
79
+ * const newcomer = { key: 'hero', x: 0, y: 0, height: 8 };
80
+ *
81
+ * console.log(FLOATING_TEXT_STACK_GAP); // 4, the gap Java's push leaves
82
+ * console.log(floatingTextStackLift(older, newcomer)); // -13, where the older line must sit
83
+ * console.log(floatingTextStackLifePenalty(1)); // 0.2, the age a first lifted line is forced to
84
+ * console.log(floatingTextStackMoves([older], newcomer)); // [{ index: 0, y: -13, ageAtLeast: 0.2 }]
29
85
  * ```
30
86
  */
31
- export declare function floatingTextStackOffset(live: readonly FloatingTextStackEntry[], incoming: FloatingTextStackEntry): number;
87
+ export declare function floatingTextStackMoves(live: readonly FloatingTextStackEntry[], incoming: FloatingTextStackEntry, gap?: number): FloatingTextStackMove[];
32
88
  export interface FloatingTextPush extends FloatingTextOptions {
33
89
  /** where the pop-up belongs, in the stack's own coordinate space */
34
90
  x: number;
35
91
  y: number;
36
92
  /**
37
- * Pop-ups pushed with the same key and the same origin stack upward instead of
38
- * overprinting. A pop-up with no key always stands alone.
93
+ * Pop-ups pushed with the same key stack upward instead of overprinting. A pop-up with no key
94
+ * always stands alone.
95
+ *
96
+ * A key is the target's own identity, which is what Java's `stacks.get(key)` is keyed on: a
97
+ * caller reusing one key for two different targets sees their lines stacked together.
39
98
  */
40
99
  key?: string | number;
100
+ /**
101
+ * Uniform scale for the pop-up, applied *before* it is measured. Pass it here rather than
102
+ * scaling the returned pop-up: a `FloatingText`'s `height` includes its own scale, so a scale
103
+ * applied after the push is measured wrong and the lines stack by a size they are not drawn at
104
+ * (a port rasterising at 21px and drawing at 7 spaced one stack three times too far apart).
105
+ */
106
+ scale?: number;
41
107
  }
42
108
  /**
43
109
  * Owns the pop-ups a game spawns over world points: one `push` per number, one `update(dt)` to
@@ -65,7 +131,14 @@ export interface FloatingTextPush extends FloatingTextOptions {
65
131
  */
66
132
  export declare class FloatingTextStack extends Container {
67
133
  private readonly live;
68
- /** spawns a pop-up at `options.x`/`options.y`, stacked clear of anything it shares a key with */
134
+ /**
135
+ * Spawns a pop-up at `options.x`/`options.y`, lifting the lines already there out of its way.
136
+ *
137
+ * The newcomer stays exactly where it was asked to appear; anything sharing its key that it
138
+ * would overlap moves up, newest first, each one measured against the line below it and each
139
+ * nudge costing it a little life - Java's order, so a stack grows upward and self-limits. The
140
+ * decision is `floatingTextStackMoves`; this method only assigns what that plan says.
141
+ */
69
142
  push(options: FloatingTextPush): FloatingText;
70
143
  /** drives every live pop-up, then forgets the ones that have finished and removed themselves */
71
144
  update(dt: number): void;
@@ -1 +1 @@
1
- {"version":3,"file":"FloatingTextStack.d.ts","sourceRoot":"","sources":["../../../src/two-d/ui/FloatingTextStack.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAE3E;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACtC,wFAAwF;IACxF,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAEtB,gFAAgF;IAChF,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IAEV,4DAA4D;IAC5D,MAAM,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,CACtC,IAAI,EAAE,SAAS,sBAAsB,EAAE,EACvC,QAAQ,EAAE,sBAAsB,GAC9B,MAAM,CAUR;AAED,MAAM,WAAW,gBAAiB,SAAQ,mBAAmB;IAC5D,oEAAoE;IACpE,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IAEV;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,iBAAkB,SAAQ,SAAS;IAC/C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAqE;IAE1F,iGAAiG;IACjG,IAAI,CAAC,OAAO,EAAE,gBAAgB,GAAG,YAAY,CAsB5C;IAED,gGAAgG;IAChG,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAKvB;IAED,uCAAuC;IACvC,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,4DAA4D;IAC5D,KAAK,IAAI,IAAI,CAMZ;CACD"}
1
+ {"version":3,"file":"FloatingTextStack.d.ts","sourceRoot":"","sources":["../../../src/two-d/ui/FloatingTextStack.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAE3E;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACtC,wFAAwF;IACxF,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAEtB;;;;;;OAMG;IACH,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IAEV,4DAA4D;IAC5D,MAAM,EAAE,MAAM,CAAC;CACf;AAED,+FAA+F;AAC/F,eAAO,MAAM,uBAAuB,IAAI,CAAC;AAEzC;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEvE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CACpC,KAAK,EAAE,sBAAsB,EAC7B,KAAK,EAAE,sBAAsB,EAC7B,GAAG,GAAE,MAAgC,GACnC,MAAM,CAIR;AAED,yEAAyE;AACzE,MAAM,WAAW,qBAAqB;IACrC,0DAA0D;IAC1D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB,4EAA4E;IAC5E,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IAEnB,qFAAqF;IACrF,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,sBAAsB,CACrC,IAAI,EAAE,SAAS,sBAAsB,EAAE,EACvC,QAAQ,EAAE,sBAAsB,EAChC,GAAG,GAAE,MAAgC,GACnC,qBAAqB,EAAE,CAkBzB;AAED,MAAM,WAAW,gBAAiB,SAAQ,mBAAmB;IAC5D,oEAAoE;IACpE,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IAEV;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAEtB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,iBAAkB,SAAQ,SAAS;IAC/C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAqE;IAE1F;;;;;;;OAOG;IACH,IAAI,CAAC,OAAO,EAAE,gBAAgB,GAAG,YAAY,CA2B5C;IAED,gGAAgG;IAChG,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAKvB;IAED,uCAAuC;IACvC,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,4DAA4D;IAC5D,KAAK,IAAI,IAAI,CAMZ;CACD"}
@@ -1,32 +1,88 @@
1
1
  import { Container } from 'pixi.js';
2
2
  import { FloatingText } from './FloatingText.js';
3
+ /** The vertical gap left between two stacked lines - Java's `FloatingText.push()` uses `4`. */
4
+ export const FLOATING_TEXT_STACK_GAP = 4;
3
5
  /**
4
- * How far a newcomer must move up to clear every live pop-up it shares a key *and* an origin
5
- * with - the classic "three numbers on one creature in one turn" case.
6
+ * The age a lifted line is forced to, in seconds, from how many lines sit below it - Java's
7
+ * `LIFESPAN - numBelow / 5f` read as a floor under the age rather than a cap on what is left, the
8
+ * same rule `FloatingText.ageAtLeast` applies. One second per five lines, a fifth of a second each,
9
+ * so a burst of numbers cannot become a column that outlives the fight that produced it.
10
+ */
11
+ export function floatingTextStackLifePenalty(linesBelow) {
12
+ return Math.max(0, linesBelow) / 5;
13
+ }
14
+ /**
15
+ * The `y` `older` must sit at to clear `below`, or `older.y` when it already does.
16
+ *
17
+ * The direction is the point, and it is why this returns a *position* rather than an offset to add:
18
+ * Java's `FloatingText.push()` anchors the newcomer on the target and lifts the lines already there
19
+ * (`above.setPos(above.left(), below.top() - above.height() - 4)`), the opposite of moving the
20
+ * newcomer out of the way. Pop-ups rise, so the older ones belong above the newer ones - an offset
21
+ * the caller adds is direction-ambiguous, a position the caller assigns is not.
22
+ *
23
+ * Both boxes are anchored at their centre, so a line's top is `y - height / 2`; a line is clear when
24
+ * its bottom plus the gap no longer reaches the other's top.
6
25
  *
7
26
  * Exported and pure on purpose: the stacking rule is arithmetic, and this way it is checked as
8
27
  * arithmetic rather than through a rendered label (`Label` needs a DOM to measure text).
9
- * Offsets accumulate by measured height, so a taller line clears the one under it rather than
10
- * overlapping it by a fixed guess.
28
+ */
29
+ export function floatingTextStackLift(older, below, gap = FLOATING_TEXT_STACK_GAP) {
30
+ const belowTop = below.y - below.height / 2;
31
+ if (older.y + older.height / 2 + gap <= belowTop)
32
+ return older.y;
33
+ return belowTop - older.height / 2 - gap;
34
+ }
35
+ /**
36
+ * The whole stacking policy as arithmetic: which of `live` (oldest first) share the newcomer's key,
37
+ * where each of them ends up, and what age each is forced to.
38
+ *
39
+ * Newest first, stopping at the first line already clear of the one below it: a stack is ordered,
40
+ * an older line sits above a newer one, so a line that needs no move means nothing above it does
41
+ * either. That is Java's `break`, and the reason the walk runs backwards over `live`.
42
+ *
43
+ * Pure and exported for the same reason `floatingTextStackLift` is: applying a plan needs a
44
+ * `FloatingText`, which is a `Label`, which needs a DOM. The decision is therefore checked as
45
+ * arithmetic and the class is left with the assignments. `push` inlined this loop once, and the
46
+ * loop is where the direction, the order and the life floor were all wrong at the same time.
11
47
  *
12
48
  * @example
13
49
  * ```ts
14
- * import { floatingTextStackOffset } from '@datamoc/mw_games/two-d/ui';
15
- * console.log(floatingTextStackOffset([{ key: 'hero', x: 1, y: 2, height: 10 }], { key: 'hero', x: 1, y: 2, height: 8 })); // 11
50
+ * import {
51
+ * FLOATING_TEXT_STACK_GAP,
52
+ * floatingTextStackLift,
53
+ * floatingTextStackLifePenalty,
54
+ * floatingTextStackMoves,
55
+ * } from '@datamoc/mw_games/two-d/ui';
56
+ *
57
+ * const older = { key: 'hero', x: 0, y: 0, height: 10 };
58
+ * const newcomer = { key: 'hero', x: 0, y: 0, height: 8 };
59
+ *
60
+ * console.log(FLOATING_TEXT_STACK_GAP); // 4, the gap Java's push leaves
61
+ * console.log(floatingTextStackLift(older, newcomer)); // -13, where the older line must sit
62
+ * console.log(floatingTextStackLifePenalty(1)); // 0.2, the age a first lifted line is forced to
63
+ * console.log(floatingTextStackMoves([older], newcomer)); // [{ index: 0, y: -13, ageAtLeast: 0.2 }]
16
64
  * ```
17
65
  */
18
- export function floatingTextStackOffset(live, incoming) {
66
+ export function floatingTextStackMoves(live, incoming, gap = FLOATING_TEXT_STACK_GAP) {
67
+ const moves = [];
19
68
  if (incoming.key === undefined)
20
- return 0;
21
- let lift = 0;
22
- for (const entry of live) {
23
- if (entry.key !== incoming.key)
24
- continue;
25
- if (entry.x !== incoming.x || entry.y !== incoming.y)
69
+ return moves;
70
+ let below = incoming;
71
+ for (let index = live.length - 1; index >= 0; index--) {
72
+ const held = live[index];
73
+ if (held.key !== incoming.key)
26
74
  continue;
27
- lift += entry.height + 1;
75
+ const y = floatingTextStackLift(held, below, gap);
76
+ //already clear of the line below, so everything above it is too: Java stops here
77
+ if (y === held.y)
78
+ break;
79
+ moves.push({ index, y, ageAtLeast: floatingTextStackLifePenalty(moves.length + 1) });
80
+ //the next line up is measured against where this one is going, not where it was. The
81
+ //entries handed in are not mutated, so the move is carried forward on a copy: without this
82
+ //every line of a burst lands at the same y.
83
+ below = { ...held, y };
28
84
  }
29
- return lift;
85
+ return moves;
30
86
  }
31
87
  /**
32
88
  * Owns the pop-ups a game spawns over world points: one `push` per number, one `update(dt)` to
@@ -57,7 +113,14 @@ export class FloatingTextStack extends Container {
57
113
  super(...arguments);
58
114
  this.live = [];
59
115
  }
60
- /** spawns a pop-up at `options.x`/`options.y`, stacked clear of anything it shares a key with */
116
+ /**
117
+ * Spawns a pop-up at `options.x`/`options.y`, lifting the lines already there out of its way.
118
+ *
119
+ * The newcomer stays exactly where it was asked to appear; anything sharing its key that it
120
+ * would overlap moves up, newest first, each one measured against the line below it and each
121
+ * nudge costing it a little life - Java's order, so a stack grows upward and self-limits. The
122
+ * decision is `floatingTextStackMoves`; this method only assigns what that plan says.
123
+ */
61
124
  push(options) {
62
125
  const popup = new FloatingText({
63
126
  text: options.text,
@@ -67,9 +130,17 @@ export class FloatingTextStack extends Container {
67
130
  rise: options.rise,
68
131
  hold: options.hold,
69
132
  });
133
+ //before the measurement below, never after: `height` includes the pop-up's own scale
134
+ if (options.scale !== undefined)
135
+ popup.scale.set(options.scale);
70
136
  const entry = { key: options.key, x: options.x, y: options.y, height: popup.height };
71
- popup.position.set(options.x, options.y +
72
- floatingTextStackOffset(this.live.map((held) => held.entry), entry));
137
+ for (const move of floatingTextStackMoves(this.live.map((held) => held.entry), entry)) {
138
+ const held = this.live[move.index];
139
+ held.entry.y = move.y;
140
+ held.popup.y = move.y;
141
+ held.popup.ageAtLeast(move.ageAtLeast);
142
+ }
143
+ popup.position.set(options.x, options.y);
73
144
  this.addChild(popup);
74
145
  this.live.push({ popup, entry });
75
146
  return popup;
@@ -1 +1 @@
1
- {"version":3,"file":"FloatingTextStack.js","sourceRoot":"","sources":["../../../src/two-d/ui/FloatingTextStack.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"FloatingTextStack.js","sourceRoot":"","sources":["../../../src/two-d/ui/FloatingTextStack.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,105 @@
1
+ export type Anchor = 'top-left' | 'top' | 'top-right' | 'left' | 'center' | 'right' | 'bottom-left' | 'bottom' | 'bottom-right' | 'fill';
2
+ export interface LayoutRect {
3
+ x: number;
4
+ y: number;
5
+ width: number;
6
+ height: number;
7
+ }
8
+ export interface AnchorSpec {
9
+ /** which corner or edge to sit against; `center` when omitted */
10
+ anchor?: Anchor;
11
+ /** extra offset after anchoring, positive right and down */
12
+ offsetX?: number;
13
+ offsetY?: number;
14
+ /** 0..1 position across the bounds, overriding the named anchor's own alignment */
15
+ alignX?: number;
16
+ alignY?: number;
17
+ /** the placed size; the content's own size when omitted */
18
+ width?: number;
19
+ height?: number;
20
+ /** shrinks the bounds on every side before anchoring */
21
+ margin?: number;
22
+ }
23
+ /**
24
+ * The horizontal (0, 0.5, 1) and vertical alignment a named anchor implies.
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * import { anchorAlign } from '@datamoc/mw_games/two-d/ui';
29
+ *
30
+ * console.log(anchorAlign('bottom-right')); // { x: 1, y: 1 }
31
+ * ```
32
+ */
33
+ export declare function anchorAlign(anchor: Anchor): {
34
+ x: number;
35
+ y: number;
36
+ };
37
+ /**
38
+ * Places a `size`-shaped child against the bounds - the anchor half of a data-driven shell, the
39
+ * part GUI2 spells as `[cell]` anchoring a widget inside its slot.
40
+ *
41
+ * A `fill` anchor takes the bounds (minus margins) whole; every other anchor lines the child up on
42
+ * the named edge and then applies the offsets, so `{ anchor: 'bottom-right', offsetX: -8 }` pins a
43
+ * button eight pixels in from the bottom-right corner.
44
+ *
45
+ * @example
46
+ * ```ts
47
+ * import { resolveAnchor } from '@datamoc/mw_games/two-d/ui';
48
+ *
49
+ * const bounds = { x: 0, y: 0, width: 800, height: 600 };
50
+ * console.log(resolveAnchor({ anchor: 'bottom-right', width: 100, height: 30, margin: 10 }, bounds));
51
+ * // { x: 690, y: 560, width: 100, height: 30 }
52
+ * ```
53
+ */
54
+ export declare function resolveAnchor(spec: AnchorSpec, bounds: LayoutRect, size?: {
55
+ width: number;
56
+ height: number;
57
+ }): LayoutRect;
58
+ export interface GridTrack {
59
+ /** a fixed size, in pixels */
60
+ size?: number;
61
+ /** share of what is left after the fixed tracks; a track with neither is 0 */
62
+ grow?: number;
63
+ }
64
+ export interface GridSpec {
65
+ columns: readonly GridTrack[];
66
+ rows: readonly GridTrack[];
67
+ /** space between tracks, in pixels */
68
+ gap?: number;
69
+ }
70
+ /**
71
+ * A column/row grid whose tracks are `size` or `grow`, the data-driven counterpart to GUI2's
72
+ * `[grid]`. Fixed tracks take their size; the rest of the space is divided between the `grow`
73
+ * tracks in proportion to their weight, so a sidebar can be `size: 200` and the content
74
+ * `grow: 1` without either side knowing the window's width.
75
+ *
76
+ * @example
77
+ * ```ts
78
+ * import { Grid } from '@datamoc/mw_games/two-d/ui';
79
+ *
80
+ * const grid = new Grid({ columns: [{ size: 200 }, { grow: 1 }], rows: [{ grow: 1 }], gap: 8 });
81
+ * const cell = grid.rect(0, 1, { x: 0, y: 0, width: 800, height: 600 });
82
+ * console.log(cell); // the content column: x 208, width 592
83
+ * ```
84
+ */
85
+ export declare class Grid {
86
+ private spec;
87
+ constructor(spec: GridSpec);
88
+ get columns(): readonly GridTrack[];
89
+ get rows(): readonly GridTrack[];
90
+ /** the resolved pixel width of each column for a given total width */
91
+ columnSizes(totalWidth: number): number[];
92
+ /** the resolved pixel height of each row for a given total height */
93
+ rowSizes(totalHeight: number): number[];
94
+ /**
95
+ * The rectangle of a cell, spanning `columnSpan` columns and `rowSpan` rows. Out-of-range cells
96
+ * resolve to a zero-sized rect at the far edge rather than throwing, so a caller walking a
97
+ * changing table never has to bounds-check first.
98
+ */
99
+ rect(row: number, column: number, bounds: LayoutRect, options?: {
100
+ rowSpan?: number;
101
+ columnSpan?: number;
102
+ }): LayoutRect;
103
+ private get gap();
104
+ }
105
+ //# sourceMappingURL=Layout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Layout.d.ts","sourceRoot":"","sources":["../../../src/two-d/ui/Layout.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,MAAM,GACjB,UAAU,GAAG,KAAK,GAAG,WAAW,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,aAAa,GAAG,QAAQ,GAAG,cAAc,GAAG,MAAM,CAAC;AAErH,MAAM,WAAW,UAAU;IAC1B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IAC1B,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mFAAmF;IACnF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAqBpE;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,aAAa,CAC5B,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,UAAU,EAClB,IAAI,GAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAA4B,GAC/D,UAAU,CA6BZ;AAED,MAAM,WAAW,SAAS;IACzB,8BAA8B;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,8EAA8E;IAC9E,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,QAAQ;IACxB,OAAO,EAAE,SAAS,SAAS,EAAE,CAAC;IAC9B,IAAI,EAAE,SAAS,SAAS,EAAE,CAAC;IAC3B,sCAAsC;IACtC,GAAG,CAAC,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,IAAI;IAChB,OAAO,CAAC,IAAI,CAAW;IAEvB,YAAY,IAAI,EAAE,QAAQ,EAEzB;IAED,IAAI,OAAO,IAAI,SAAS,SAAS,EAAE,CAElC;IAED,IAAI,IAAI,IAAI,SAAS,SAAS,EAAE,CAE/B;IAED,sEAAsE;IACtE,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAExC;IAED,qEAAqE;IACrE,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAEtC;IAED;;;;OAIG;IACH,IAAI,CACH,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,UAAU,EAClB,OAAO,GAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAO,GACrD,UAAU,CAcZ;IAED,OAAO,KAAK,GAAG,GAEd;CACD"}
@@ -0,0 +1,174 @@
1
+ /**
2
+ * The horizontal (0, 0.5, 1) and vertical alignment a named anchor implies.
3
+ *
4
+ * @example
5
+ * ```ts
6
+ * import { anchorAlign } from '@datamoc/mw_games/two-d/ui';
7
+ *
8
+ * console.log(anchorAlign('bottom-right')); // { x: 1, y: 1 }
9
+ * ```
10
+ */
11
+ export function anchorAlign(anchor) {
12
+ switch (anchor) {
13
+ case 'top':
14
+ case 'bottom':
15
+ return { x: 0.5, y: anchor === 'top' ? 0 : 1 };
16
+ case 'left':
17
+ case 'right':
18
+ return { x: anchor === 'left' ? 0 : 1, y: 0.5 };
19
+ case 'top-left':
20
+ return { x: 0, y: 0 };
21
+ case 'top-right':
22
+ return { x: 1, y: 0 };
23
+ case 'bottom-left':
24
+ return { x: 0, y: 1 };
25
+ case 'bottom-right':
26
+ return { x: 1, y: 1 };
27
+ case 'fill':
28
+ case 'center':
29
+ default:
30
+ return { x: 0.5, y: 0.5 };
31
+ }
32
+ }
33
+ /**
34
+ * Places a `size`-shaped child against the bounds - the anchor half of a data-driven shell, the
35
+ * part GUI2 spells as `[cell]` anchoring a widget inside its slot.
36
+ *
37
+ * A `fill` anchor takes the bounds (minus margins) whole; every other anchor lines the child up on
38
+ * the named edge and then applies the offsets, so `{ anchor: 'bottom-right', offsetX: -8 }` pins a
39
+ * button eight pixels in from the bottom-right corner.
40
+ *
41
+ * @example
42
+ * ```ts
43
+ * import { resolveAnchor } from '@datamoc/mw_games/two-d/ui';
44
+ *
45
+ * const bounds = { x: 0, y: 0, width: 800, height: 600 };
46
+ * console.log(resolveAnchor({ anchor: 'bottom-right', width: 100, height: 30, margin: 10 }, bounds));
47
+ * // { x: 690, y: 560, width: 100, height: 30 }
48
+ * ```
49
+ */
50
+ export function resolveAnchor(spec, bounds, size = { width: 0, height: 0 }) {
51
+ const margin = spec.margin ?? 0;
52
+ const left = bounds.x + margin;
53
+ const top = bounds.y + margin;
54
+ const usableWidth = Math.max(0, bounds.width - margin * 2);
55
+ const usableHeight = Math.max(0, bounds.height - margin * 2);
56
+ if (spec.anchor === 'fill') {
57
+ const x = left + (spec.offsetX ?? 0);
58
+ const y = top + (spec.offsetY ?? 0);
59
+ return {
60
+ x,
61
+ y,
62
+ width: spec.width ?? Math.max(0, left + usableWidth - x),
63
+ height: spec.height ?? Math.max(0, top + usableHeight - y),
64
+ };
65
+ }
66
+ const align = anchorAlign(spec.anchor ?? 'center');
67
+ const alignX = spec.alignX ?? align.x;
68
+ const alignY = spec.alignY ?? align.y;
69
+ const width = spec.width ?? size.width;
70
+ const height = spec.height ?? size.height;
71
+ return {
72
+ x: left + alignX * Math.max(0, usableWidth - width) + (spec.offsetX ?? 0),
73
+ y: top + alignY * Math.max(0, usableHeight - height) + (spec.offsetY ?? 0),
74
+ width,
75
+ height,
76
+ };
77
+ }
78
+ /**
79
+ * A column/row grid whose tracks are `size` or `grow`, the data-driven counterpart to GUI2's
80
+ * `[grid]`. Fixed tracks take their size; the rest of the space is divided between the `grow`
81
+ * tracks in proportion to their weight, so a sidebar can be `size: 200` and the content
82
+ * `grow: 1` without either side knowing the window's width.
83
+ *
84
+ * @example
85
+ * ```ts
86
+ * import { Grid } from '@datamoc/mw_games/two-d/ui';
87
+ *
88
+ * const grid = new Grid({ columns: [{ size: 200 }, { grow: 1 }], rows: [{ grow: 1 }], gap: 8 });
89
+ * const cell = grid.rect(0, 1, { x: 0, y: 0, width: 800, height: 600 });
90
+ * console.log(cell); // the content column: x 208, width 592
91
+ * ```
92
+ */
93
+ export class Grid {
94
+ constructor(spec) {
95
+ this.spec = spec;
96
+ }
97
+ get columns() {
98
+ return this.spec.columns;
99
+ }
100
+ get rows() {
101
+ return this.spec.rows;
102
+ }
103
+ /** the resolved pixel width of each column for a given total width */
104
+ columnSizes(totalWidth) {
105
+ return resolveTracks(this.spec.columns, totalWidth, this.gap);
106
+ }
107
+ /** the resolved pixel height of each row for a given total height */
108
+ rowSizes(totalHeight) {
109
+ return resolveTracks(this.spec.rows, totalHeight, this.gap);
110
+ }
111
+ /**
112
+ * The rectangle of a cell, spanning `columnSpan` columns and `rowSpan` rows. Out-of-range cells
113
+ * resolve to a zero-sized rect at the far edge rather than throwing, so a caller walking a
114
+ * changing table never has to bounds-check first.
115
+ */
116
+ rect(row, column, bounds, options = {}) {
117
+ const columns = this.columnSizes(bounds.width);
118
+ const rows = this.rowSizes(bounds.height);
119
+ const columnSpan = options.columnSpan ?? 1;
120
+ const rowSpan = options.rowSpan ?? 1;
121
+ const x = bounds.x + offsetOf(columns, column, this.gap);
122
+ const y = bounds.y + offsetOf(rows, row, this.gap);
123
+ return {
124
+ x,
125
+ y,
126
+ width: spanOf(columns, column, columnSpan, this.gap),
127
+ height: spanOf(rows, row, rowSpan, this.gap),
128
+ };
129
+ }
130
+ get gap() {
131
+ return this.spec.gap ?? 0;
132
+ }
133
+ }
134
+ function resolveTracks(tracks, total, gap) {
135
+ const gaps = gap * Math.max(0, tracks.length - 1);
136
+ const available = Math.max(0, total - gaps);
137
+ const fixed = tracks.reduce((sum, track) => sum + (track.size ?? 0), 0);
138
+ const growTotal = tracks.reduce((sum, track) => sum + (track.grow ?? 0), 0);
139
+ const remaining = Math.max(0, available - fixed);
140
+ let assigned = 0;
141
+ return tracks.map((track, index) => {
142
+ if (track.size !== undefined)
143
+ return track.size;
144
+ if (!track.grow || growTotal === 0)
145
+ return 0;
146
+ //give the last grow track whatever rounding is left, so the tracks always fill the space
147
+ const isLast = index === lastGrowIndex(tracks);
148
+ const size = isLast ? remaining - assigned : Math.floor((remaining * track.grow) / growTotal);
149
+ assigned += size;
150
+ return size;
151
+ });
152
+ }
153
+ function lastGrowIndex(tracks) {
154
+ for (let index = tracks.length - 1; index >= 0; index--)
155
+ if (tracks[index].grow)
156
+ return index;
157
+ return -1;
158
+ }
159
+ function offsetOf(sizes, index, gap) {
160
+ let offset = 0;
161
+ for (let i = 0; i < index && i < sizes.length; i++)
162
+ offset += sizes[i] + gap;
163
+ return offset;
164
+ }
165
+ function spanOf(sizes, index, span, gap) {
166
+ let width = 0;
167
+ for (let i = index; i < index + span && i < sizes.length; i++) {
168
+ width += sizes[i];
169
+ if (i > index)
170
+ width += gap;
171
+ }
172
+ return Math.max(0, width);
173
+ }
174
+ //# sourceMappingURL=Layout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Layout.js","sourceRoot":"","sources":["../../../src/two-d/ui/Layout.ts"],"names":[],"mappings":"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"}