@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.
- package/CHANGELOG.md +359 -0
- package/README.md +7 -7
- package/dist/actors/Inventory.d.ts +7 -1
- package/dist/actors/Inventory.d.ts.map +1 -1
- package/dist/actors/Inventory.js.map +1 -1
- package/dist/actors/Shop.d.ts.map +1 -1
- package/dist/actors/Shop.js +4 -1
- package/dist/actors/Shop.js.map +1 -1
- package/dist/actors/craft.d.ts +35 -14
- package/dist/actors/craft.d.ts.map +1 -1
- package/dist/actors/craft.js +56 -24
- package/dist/actors/craft.js.map +1 -1
- package/dist/actors/index.d.ts +1 -1
- package/dist/actors/index.d.ts.map +1 -1
- package/dist/ai/Heuristics.d.ts +240 -0
- package/dist/ai/Heuristics.d.ts.map +1 -0
- package/dist/ai/Heuristics.js +298 -0
- package/dist/ai/Heuristics.js.map +1 -0
- package/dist/ai/index.d.ts +4 -0
- package/dist/ai/index.d.ts.map +1 -1
- package/dist/ai/index.js +2 -0
- package/dist/ai/index.js.map +1 -1
- package/dist/ai/lua.d.ts +21 -0
- package/dist/ai/lua.d.ts.map +1 -1
- package/dist/ai/lua.js +21 -0
- package/dist/ai/lua.js.map +1 -1
- package/dist/ai/score.d.ts +162 -0
- package/dist/ai/score.d.ts.map +1 -0
- package/dist/ai/score.js +147 -0
- package/dist/ai/score.js.map +1 -0
- package/dist/assets/loader.d.ts +18 -4
- package/dist/assets/loader.d.ts.map +1 -1
- package/dist/assets/loader.js +40 -11
- package/dist/assets/loader.js.map +1 -1
- package/dist/audio/Positional.d.ts +125 -0
- package/dist/audio/Positional.d.ts.map +1 -0
- package/dist/audio/Positional.js +135 -0
- package/dist/audio/Positional.js.map +1 -0
- package/dist/audio/Sound.d.ts +7 -1
- package/dist/audio/Sound.d.ts.map +1 -1
- package/dist/audio/Sound.js +8 -2
- package/dist/audio/Sound.js.map +1 -1
- package/dist/audio/index.d.ts +2 -0
- package/dist/audio/index.d.ts.map +1 -1
- package/dist/audio/index.js +1 -0
- package/dist/audio/index.js.map +1 -1
- package/dist/battle/AttackDialog.d.ts +75 -0
- package/dist/battle/AttackDialog.d.ts.map +1 -0
- package/dist/battle/AttackDialog.js +115 -0
- package/dist/battle/AttackDialog.js.map +1 -0
- package/dist/battle/AttackPreview.d.ts +70 -0
- package/dist/battle/AttackPreview.d.ts.map +1 -0
- package/dist/battle/AttackPreview.js +78 -0
- package/dist/battle/AttackPreview.js.map +1 -0
- package/dist/battle/BattleStats.d.ts +45 -0
- package/dist/battle/BattleStats.d.ts.map +1 -0
- package/dist/battle/BattleStats.js +63 -0
- package/dist/battle/BattleStats.js.map +1 -0
- package/dist/battle/UnitSelector.d.ts +72 -0
- package/dist/battle/UnitSelector.d.ts.map +1 -0
- package/dist/battle/UnitSelector.js +117 -0
- package/dist/battle/UnitSelector.js.map +1 -0
- package/dist/battle/Whiteboard.d.ts +50 -0
- package/dist/battle/Whiteboard.d.ts.map +1 -0
- package/dist/battle/Whiteboard.js +94 -0
- package/dist/battle/Whiteboard.js.map +1 -0
- package/dist/battle/index.d.ts +10 -0
- package/dist/battle/index.d.ts.map +1 -1
- package/dist/battle/index.js +5 -0
- package/dist/battle/index.js.map +1 -1
- package/dist/board/Classics.d.ts.map +1 -1
- package/dist/board/Classics.js +51 -39
- package/dist/board/Classics.js.map +1 -1
- package/dist/board/FogOfWar.d.ts +32 -2
- package/dist/board/FogOfWar.d.ts.map +1 -1
- package/dist/board/FogOfWar.js +70 -6
- package/dist/board/FogOfWar.js.map +1 -1
- package/dist/board/HexSkirmish.d.ts.map +1 -1
- package/dist/board/HexSkirmish.js +69 -20
- package/dist/board/HexSkirmish.js.map +1 -1
- package/dist/board/Tactics.d.ts +7 -0
- package/dist/board/Tactics.d.ts.map +1 -1
- package/dist/board/Tactics.js +2 -2
- package/dist/board/Tactics.js.map +1 -1
- package/dist/core/Achievements.d.ts +40 -7
- package/dist/core/Achievements.d.ts.map +1 -1
- package/dist/core/Achievements.js +53 -7
- package/dist/core/Achievements.js.map +1 -1
- package/dist/core/Hex.d.ts +26 -6
- package/dist/core/Hex.d.ts.map +1 -1
- package/dist/core/Hex.js +40 -13
- package/dist/core/Hex.js.map +1 -1
- package/dist/core/Input.d.ts +36 -0
- package/dist/core/Input.d.ts.map +1 -1
- package/dist/core/Input.js +63 -1
- package/dist/core/Input.js.map +1 -1
- package/dist/core/Random.d.ts +93 -0
- package/dist/core/Random.d.ts.map +1 -1
- package/dist/core/Random.js +177 -0
- package/dist/core/Random.js.map +1 -1
- package/dist/core/SyncGuard.d.ts +57 -0
- package/dist/core/SyncGuard.d.ts.map +1 -0
- package/dist/core/SyncGuard.js +116 -0
- package/dist/core/SyncGuard.js.map +1 -0
- package/dist/core/index.d.ts +3 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +2 -1
- package/dist/core/index.js.map +1 -1
- package/dist/i18n/Po.d.ts +51 -0
- package/dist/i18n/Po.d.ts.map +1 -0
- package/dist/i18n/Po.js +176 -0
- package/dist/i18n/Po.js.map +1 -0
- package/dist/i18n/index.d.ts +2 -0
- package/dist/i18n/index.d.ts.map +1 -1
- package/dist/i18n/index.js +1 -0
- package/dist/i18n/index.js.map +1 -1
- package/dist/mw_games.global.js +104 -98
- package/dist/mwl/MapFile.d.ts +41 -0
- package/dist/mwl/MapFile.d.ts.map +1 -0
- package/dist/mwl/MapFile.js +43 -0
- package/dist/mwl/MapFile.js.map +1 -0
- package/dist/mwl/actors.d.ts +46 -2
- package/dist/mwl/actors.d.ts.map +1 -1
- package/dist/mwl/actors.js +46 -2
- package/dist/mwl/actors.js.map +1 -1
- package/dist/mwl/campaign.d.ts +51 -0
- package/dist/mwl/campaign.d.ts.map +1 -0
- package/dist/mwl/campaign.js +58 -0
- package/dist/mwl/campaign.js.map +1 -0
- package/dist/mwl/carryover.d.ts +86 -0
- package/dist/mwl/carryover.d.ts.map +1 -0
- package/dist/mwl/carryover.js +70 -0
- package/dist/mwl/carryover.js.map +1 -0
- package/dist/mwl/catalog.d.ts +10 -1
- package/dist/mwl/catalog.d.ts.map +1 -1
- package/dist/mwl/catalog.js +10 -1
- package/dist/mwl/catalog.js.map +1 -1
- package/dist/mwl/compiler.d.ts +70 -3
- package/dist/mwl/compiler.d.ts.map +1 -1
- package/dist/mwl/compiler.js +70 -3
- package/dist/mwl/compiler.js.map +1 -1
- package/dist/mwl/conditions.d.ts +10 -1
- package/dist/mwl/conditions.d.ts.map +1 -1
- package/dist/mwl/conditions.js +10 -1
- package/dist/mwl/conditions.js.map +1 -1
- package/dist/mwl/content.d.ts +21 -0
- package/dist/mwl/content.d.ts.map +1 -1
- package/dist/mwl/content.js +19 -0
- package/dist/mwl/content.js.map +1 -1
- package/dist/mwl/expression.d.ts +21 -0
- package/dist/mwl/expression.d.ts.map +1 -1
- package/dist/mwl/expression.js +21 -0
- package/dist/mwl/expression.js.map +1 -1
- package/dist/mwl/fengari.d.ts +12 -1
- package/dist/mwl/fengari.d.ts.map +1 -1
- package/dist/mwl/fengari.js +12 -1
- package/dist/mwl/fengari.js.map +1 -1
- package/dist/mwl/grammar.d.ts +45 -1
- package/dist/mwl/grammar.d.ts.map +1 -1
- package/dist/mwl/grammar.js +45 -1
- package/dist/mwl/grammar.js.map +1 -1
- package/dist/mwl/hooks.d.ts +51 -6
- package/dist/mwl/hooks.d.ts.map +1 -1
- package/dist/mwl/hooks.js +45 -1
- package/dist/mwl/hooks.js.map +1 -1
- package/dist/mwl/index.d.ts +9 -3
- package/dist/mwl/index.d.ts.map +1 -1
- package/dist/mwl/index.js +5 -2
- package/dist/mwl/index.js.map +1 -1
- package/dist/mwl/persistence.d.ts +32 -0
- package/dist/mwl/persistence.d.ts.map +1 -1
- package/dist/mwl/persistence.js +32 -0
- package/dist/mwl/persistence.js.map +1 -1
- package/dist/mwl/readers.d.ts +24 -2
- package/dist/mwl/readers.d.ts.map +1 -1
- package/dist/mwl/readers.js +27 -4
- package/dist/mwl/readers.js.map +1 -1
- package/dist/mwl/report.d.ts +21 -2
- package/dist/mwl/report.d.ts.map +1 -1
- package/dist/mwl/report.js +21 -2
- package/dist/mwl/report.js.map +1 -1
- package/dist/mwl/runtime.d.ts +212 -7
- package/dist/mwl/runtime.d.ts.map +1 -1
- package/dist/mwl/runtime.js +682 -90
- package/dist/mwl/runtime.js.map +1 -1
- package/dist/mwl/schema.d.ts +57 -1
- package/dist/mwl/schema.d.ts.map +1 -1
- package/dist/mwl/schema.js +181 -21
- package/dist/mwl/schema.js.map +1 -1
- package/dist/mwl/scripts.d.ts +12 -1
- package/dist/mwl/scripts.d.ts.map +1 -1
- package/dist/mwl/scripts.js +12 -1
- package/dist/mwl/scripts.js.map +1 -1
- package/dist/mwl/utils.d.ts +2 -0
- package/dist/mwl/utils.d.ts.map +1 -1
- package/dist/mwl/utils.js +4 -1
- package/dist/mwl/utils.js.map +1 -1
- package/dist/roguelike/MultiTurnBeam.d.ts +50 -12
- package/dist/roguelike/MultiTurnBeam.d.ts.map +1 -1
- package/dist/roguelike/MultiTurnBeam.js +100 -53
- package/dist/roguelike/MultiTurnBeam.js.map +1 -1
- package/dist/roguelike/Targeting.d.ts +94 -0
- package/dist/roguelike/Targeting.d.ts.map +1 -1
- package/dist/roguelike/Targeting.js +123 -0
- package/dist/roguelike/Targeting.js.map +1 -1
- package/dist/roguelike/index.d.ts +3 -1
- package/dist/roguelike/index.d.ts.map +1 -1
- package/dist/roguelike/index.js +1 -0
- package/dist/roguelike/index.js.map +1 -1
- package/dist/rpg/GameState.d.ts +2 -2
- package/dist/rpg/GameState.js +2 -2
- package/dist/simulation/CampaignSave.d.ts +68 -0
- package/dist/simulation/CampaignSave.d.ts.map +1 -0
- package/dist/simulation/CampaignSave.js +54 -0
- package/dist/simulation/CampaignSave.js.map +1 -0
- package/dist/simulation/EventPresentation.d.ts +111 -0
- package/dist/simulation/EventPresentation.d.ts.map +1 -0
- package/dist/simulation/EventPresentation.js +120 -0
- package/dist/simulation/EventPresentation.js.map +1 -0
- package/dist/simulation/index.d.ts +4 -0
- package/dist/simulation/index.d.ts.map +1 -1
- package/dist/simulation/index.js +2 -0
- package/dist/simulation/index.js.map +1 -1
- package/dist/two-d/pixi-interop.d.ts +18 -6
- package/dist/two-d/pixi-interop.d.ts.map +1 -1
- package/dist/two-d/pixi-interop.js +18 -6
- package/dist/two-d/pixi-interop.js.map +1 -1
- package/dist/two-d/render/AnimatedSprite.d.ts +74 -7
- package/dist/two-d/render/AnimatedSprite.d.ts.map +1 -1
- package/dist/two-d/render/AnimatedSprite.js +88 -26
- package/dist/two-d/render/AnimatedSprite.js.map +1 -1
- package/dist/two-d/render/Camera.d.ts +64 -4
- package/dist/two-d/render/Camera.d.ts.map +1 -1
- package/dist/two-d/render/Camera.js +132 -11
- package/dist/two-d/render/Camera.js.map +1 -1
- package/dist/two-d/render/ColorTransformBatcher.d.ts +7 -1
- package/dist/two-d/render/ColorTransformBatcher.d.ts.map +1 -1
- package/dist/two-d/render/ColorTransformBatcher.js +10 -1
- package/dist/two-d/render/ColorTransformBatcher.js.map +1 -1
- package/dist/two-d/render/Halo.d.ts +58 -0
- package/dist/two-d/render/Halo.d.ts.map +1 -0
- package/dist/two-d/render/Halo.js +48 -0
- package/dist/two-d/render/Halo.js.map +1 -0
- package/dist/two-d/render/ImageModifiers.d.ts +174 -0
- package/dist/two-d/render/ImageModifiers.d.ts.map +1 -1
- package/dist/two-d/render/ImageModifiers.js +454 -1
- package/dist/two-d/render/ImageModifiers.js.map +1 -1
- package/dist/two-d/render/LightningArc.d.ts +57 -0
- package/dist/two-d/render/LightningArc.d.ts.map +1 -0
- package/dist/two-d/render/LightningArc.js +91 -0
- package/dist/two-d/render/LightningArc.js.map +1 -0
- package/dist/two-d/render/PaletteRemap.d.ts +135 -0
- package/dist/two-d/render/PaletteRemap.d.ts.map +1 -0
- package/dist/two-d/render/PaletteRemap.js +181 -0
- package/dist/two-d/render/PaletteRemap.js.map +1 -0
- package/dist/two-d/render/Particles.d.ts +26 -0
- package/dist/two-d/render/Particles.d.ts.map +1 -1
- package/dist/two-d/render/Particles.js +23 -2
- package/dist/two-d/render/Particles.js.map +1 -1
- package/dist/two-d/render/SpriteAttachment.d.ts +55 -0
- package/dist/two-d/render/SpriteAttachment.d.ts.map +1 -0
- package/dist/two-d/render/SpriteAttachment.js +60 -0
- package/dist/two-d/render/SpriteAttachment.js.map +1 -0
- package/dist/two-d/render/TerrainGraphics.d.ts +142 -0
- package/dist/two-d/render/TerrainGraphics.d.ts.map +1 -0
- package/dist/two-d/render/TerrainGraphics.js +161 -0
- package/dist/two-d/render/TerrainGraphics.js.map +1 -0
- package/dist/two-d/render/TerrainGraphicsLayer.d.ts +55 -0
- package/dist/two-d/render/TerrainGraphicsLayer.d.ts.map +1 -0
- package/dist/two-d/render/TerrainGraphicsLayer.js +54 -0
- package/dist/two-d/render/TerrainGraphicsLayer.js.map +1 -0
- package/dist/two-d/render/TintedSprite.js +2 -2
- package/dist/two-d/render/TintedSprite.js.map +1 -1
- package/dist/two-d/render/index.d.ts +15 -3
- package/dist/two-d/render/index.d.ts.map +1 -1
- package/dist/two-d/render/index.js +7 -1
- package/dist/two-d/render/index.js.map +1 -1
- package/dist/two-d/stage/StoryScreen.d.ts +110 -0
- package/dist/two-d/stage/StoryScreen.d.ts.map +1 -0
- package/dist/two-d/stage/StoryScreen.js +178 -0
- package/dist/two-d/stage/StoryScreen.js.map +1 -0
- package/dist/two-d/stage/index.d.ts +2 -0
- package/dist/two-d/stage/index.d.ts.map +1 -1
- package/dist/two-d/stage/index.js +1 -0
- package/dist/two-d/stage/index.js.map +1 -1
- package/dist/two-d/ui/Checkbox.d.ts +44 -0
- package/dist/two-d/ui/Checkbox.d.ts.map +1 -0
- package/dist/two-d/ui/Checkbox.js +89 -0
- package/dist/two-d/ui/Checkbox.js.map +1 -0
- package/dist/two-d/ui/DataTable.d.ts +79 -0
- package/dist/two-d/ui/DataTable.d.ts.map +1 -0
- package/dist/two-d/ui/DataTable.js +164 -0
- package/dist/two-d/ui/DataTable.js.map +1 -0
- package/dist/two-d/ui/Dropdown.d.ts +72 -0
- package/dist/two-d/ui/Dropdown.d.ts.map +1 -0
- package/dist/two-d/ui/Dropdown.js +126 -0
- package/dist/two-d/ui/Dropdown.js.map +1 -0
- package/dist/two-d/ui/FloatingText.d.ts +43 -4
- package/dist/two-d/ui/FloatingText.d.ts.map +1 -1
- package/dist/two-d/ui/FloatingText.js +52 -5
- package/dist/two-d/ui/FloatingText.js.map +1 -1
- package/dist/two-d/ui/FloatingTextStack.d.ts +86 -13
- package/dist/two-d/ui/FloatingTextStack.d.ts.map +1 -1
- package/dist/two-d/ui/FloatingTextStack.js +89 -18
- package/dist/two-d/ui/FloatingTextStack.js.map +1 -1
- package/dist/two-d/ui/Layout.d.ts +105 -0
- package/dist/two-d/ui/Layout.d.ts.map +1 -0
- package/dist/two-d/ui/Layout.js +174 -0
- package/dist/two-d/ui/Layout.js.map +1 -0
- package/dist/two-d/ui/MarkupText.d.ts +53 -0
- package/dist/two-d/ui/MarkupText.d.ts.map +1 -0
- package/dist/two-d/ui/MarkupText.js +122 -0
- package/dist/two-d/ui/MarkupText.js.map +1 -0
- package/dist/two-d/ui/ScrollBox.d.ts +67 -0
- package/dist/two-d/ui/ScrollBox.d.ts.map +1 -0
- package/dist/two-d/ui/ScrollBox.js +127 -0
- package/dist/two-d/ui/ScrollBox.js.map +1 -0
- package/dist/two-d/ui/Skins.d.ts +59 -0
- package/dist/two-d/ui/Skins.d.ts.map +1 -0
- package/dist/two-d/ui/Skins.js +77 -0
- package/dist/two-d/ui/Skins.js.map +1 -0
- package/dist/two-d/ui/Slider.d.ts +91 -0
- package/dist/two-d/ui/Slider.d.ts.map +1 -0
- package/dist/two-d/ui/Slider.js +170 -0
- package/dist/two-d/ui/Slider.js.map +1 -0
- package/dist/two-d/ui/Spinner.d.ts +67 -0
- package/dist/two-d/ui/Spinner.d.ts.map +1 -0
- package/dist/two-d/ui/Spinner.js +137 -0
- package/dist/two-d/ui/Spinner.js.map +1 -0
- package/dist/two-d/ui/TabbedList.d.ts +118 -0
- package/dist/two-d/ui/TabbedList.d.ts.map +1 -0
- package/dist/two-d/ui/TabbedList.js +221 -0
- package/dist/two-d/ui/TabbedList.js.map +1 -0
- package/dist/two-d/ui/TextModel.d.ts +65 -0
- package/dist/two-d/ui/TextModel.d.ts.map +1 -0
- package/dist/two-d/ui/TextModel.js +126 -0
- package/dist/two-d/ui/TextModel.js.map +1 -0
- package/dist/two-d/ui/TreeView.d.ts +68 -0
- package/dist/two-d/ui/TreeView.d.ts.map +1 -0
- package/dist/two-d/ui/TreeView.js +133 -0
- package/dist/two-d/ui/TreeView.js.map +1 -0
- package/dist/two-d/ui/Window.d.ts +13 -0
- package/dist/two-d/ui/Window.d.ts.map +1 -1
- package/dist/two-d/ui/Window.js +23 -0
- package/dist/two-d/ui/Window.js.map +1 -1
- package/dist/two-d/ui/WindowStack.d.ts.map +1 -1
- package/dist/two-d/ui/WindowStack.js +2 -0
- package/dist/two-d/ui/WindowStack.js.map +1 -1
- package/dist/two-d/ui/index.d.ts +29 -3
- package/dist/two-d/ui/index.d.ts.map +1 -1
- package/dist/two-d/ui/index.js +15 -2
- package/dist/two-d/ui/index.js.map +1 -1
- package/dist/two-d/ui/markup.d.ts +181 -0
- package/dist/two-d/ui/markup.d.ts.map +1 -0
- package/dist/two-d/ui/markup.js +370 -0
- package/dist/two-d/ui/markup.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/world/SideTurns.d.ts +115 -0
- package/dist/world/SideTurns.d.ts.map +1 -0
- package/dist/world/SideTurns.js +138 -0
- package/dist/world/SideTurns.js.map +1 -0
- package/dist/world/index.d.ts +2 -0
- package/dist/world/index.d.ts.map +1 -1
- package/dist/world/index.js +1 -0
- package/dist/world/index.js.map +1 -1
- 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
|
|
71
|
-
*
|
|
72
|
-
*
|
|
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
|
|
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
|
|
69
|
-
*
|
|
70
|
-
*
|
|
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.
|
|
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":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAqBrD;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,iBAAiB,CAAC,CAAS,EAAE,IAAY;IACxD,IAAI,IAAI,IAAI,CAAC;QAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IAC5B,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI;QAAE,OAAO,CAAC,CAAC;IACrC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AACpC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,gBAAgB,CAAC,CAAS,EAAE,IAAY,EAAE,MAAM,GAAG,KAAK;IACvE,4FAA4F;IAC5F,2CAA2C;IAC3C,IAAI,MAAM,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAC/B,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC;AAClB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,OAAO,YAAa,SAAQ,SAAS;
|
|
1
|
+
{"version":3,"file":"FloatingText.js","sourceRoot":"","sources":["../../../src/two-d/ui/FloatingText.ts"],"names":[],"mappings":"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"}
|