@datamoc/mw_games 0.7.6 → 0.7.7
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 +270 -0
- 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/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 +232 -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/score.d.ts +126 -0
- package/dist/ai/score.d.ts.map +1 -0
- package/dist/ai/score.js +121 -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/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/core/Achievements.d.ts +40 -7
- package/dist/core/Achievements.d.ts.map +1 -1
- package/dist/core/Achievements.js +51 -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/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 +79 -0
- package/dist/mwl/carryover.d.ts.map +1 -0
- package/dist/mwl/carryover.js +63 -0
- package/dist/mwl/carryover.js.map +1 -0
- package/dist/mwl/content.d.ts +10 -0
- package/dist/mwl/content.d.ts.map +1 -1
- package/dist/mwl/content.js +8 -0
- package/dist/mwl/content.js.map +1 -1
- package/dist/mwl/hooks.d.ts +6 -5
- package/dist/mwl/hooks.d.ts.map +1 -1
- package/dist/mwl/hooks.js.map +1 -1
- package/dist/mwl/index.d.ts +8 -2
- package/dist/mwl/index.d.ts.map +1 -1
- package/dist/mwl/index.js +4 -1
- package/dist/mwl/index.js.map +1 -1
- package/dist/mwl/runtime.d.ts +140 -7
- package/dist/mwl/runtime.d.ts.map +1 -1
- package/dist/mwl/runtime.js +427 -33
- package/dist/mwl/runtime.js.map +1 -1
- package/dist/mwl/schema.d.ts.map +1 -1
- package/dist/mwl/schema.js +97 -18
- package/dist/mwl/schema.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/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/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 +438 -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/index.d.ts +13 -3
- package/dist/two-d/render/index.d.ts.map +1 -1
- package/dist/two-d/render/index.js +6 -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/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 +27 -3
- package/dist/two-d/ui/index.d.ts.map +1 -1
- package/dist/two-d/ui/index.js +14 -2
- package/dist/two-d/ui/index.js.map +1 -1
- package/dist/two-d/ui/markup.d.ts +127 -0
- package/dist/two-d/ui/markup.d.ts.map +1 -0
- package/dist/two-d/ui/markup.js +322 -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 @@
|
|
|
1
|
+
{"version":3,"file":"UnitSelector.d.ts","sourceRoot":"","sources":["../../src/battle/UnitSelector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,MAAM,WAAW,cAAc;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yFAAyF;IACzF,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IACnC,KAAK,EAAE,SAAS,cAAc,EAAE,CAAC;IACjC,0EAA0E;IAC1E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oFAAoF;IACpF,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,OAAO,CAAC;IAC7C,6EAA6E;IAC7E,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,cAAc,EAAE,MAAM,EAAE,cAAc,KAAK,OAAO,CAAC;CAC1E;AAED,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,QAAQ,CAAC;AAElD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,YAAY;IACxB,QAAQ,CAAC,QAAQ,eAAsB;IAEvC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA4B;IAClD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAoC;IAC/D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgE;IAE1F,OAAO,CAAC,MAAM,CAA6B;IAC3C,OAAO,CAAC,MAAM,CAA+B;IAC7C,OAAO,CAAC,MAAM,CAA+B;IAC7C,OAAO,CAAC,UAAU,CAAK;IAEvB,YAAY,OAAO,EAAE,mBAAmB,EAKvC;IAED,IAAI,KAAK,IAAI,aAAa,CAEzB;IAED,IAAI,QAAQ,IAAI,cAAc,GAAG,IAAI,CAEpC;IAED,IAAI,MAAM,IAAI,cAAc,GAAG,IAAI,CAElC;IAED,+DAA+D;IAC/D,IAAI,IAAI,IAAI,OAAO,CAElB;IAED,mDAAmD;IACnD,IAAI,UAAU,IAAI,SAAS,cAAc,EAAE,CAI1C;IAED,+EAA+E;IAC/E,IAAI,OAAO,IAAI,SAAS,cAAc,EAAE,CAUvC;IAED,wDAAwD;IACxD,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,IAAI,WAAW,IAAI,cAAc,GAAG,IAAI,CAGvC;IAED,kFAAkF;IAClF,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAKxB;IAED,yFAAyF;IACzF,MAAM,IAAI,OAAO,CAYhB;IAED,0EAA0E;IAC1E,IAAI,IAAI,IAAI,CASX;IAED,KAAK,IAAI,IAAI,CAMZ;IAED,OAAO,CAAC,MAAM;CAGd"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { Signal } from '../core/Signal.js';
|
|
2
|
+
/**
|
|
3
|
+
* The two-step unit selector an attack starts with: pick who attacks, then pick what they attack.
|
|
4
|
+
*
|
|
5
|
+
* Renderer-free, so the choosing rules are tested without a board: `candidates` are the enabled
|
|
6
|
+
* units on the selecting side, `targets` are the enabled units that pass `canTarget` once an
|
|
7
|
+
* attacker is chosen, `move` walks the active list and `select` advances a stage. `back` undoes the
|
|
8
|
+
* attacker choice rather than only the target, so a player who picked the wrong attacker lands
|
|
9
|
+
* where they can pick again rather than being stuck one step in.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { UnitSelector } from '@datamoc/mw_games/battle';
|
|
14
|
+
*
|
|
15
|
+
* const selector = new UnitSelector({
|
|
16
|
+
* units: [{ id: 'hero', side: '1' }, { id: 'rat', side: '2' }],
|
|
17
|
+
* side: '1',
|
|
18
|
+
* });
|
|
19
|
+
* selector.select(); // hero attacks
|
|
20
|
+
* console.log(selector.targets.map((unit) => unit.id)); // ['rat']
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export class UnitSelector {
|
|
24
|
+
constructor(options) {
|
|
25
|
+
this.onChange = new Signal();
|
|
26
|
+
this.stage_ = 'attacker';
|
|
27
|
+
this.charge = null;
|
|
28
|
+
this.victim = null;
|
|
29
|
+
this.highlight_ = 0;
|
|
30
|
+
this.units = options.units;
|
|
31
|
+
this.side = options.side;
|
|
32
|
+
this.disabledOf = options.disabled ?? ((unit) => unit.disabled ?? false);
|
|
33
|
+
this.canTarget = options.canTarget ?? (() => true);
|
|
34
|
+
}
|
|
35
|
+
get stage() {
|
|
36
|
+
return this.stage_;
|
|
37
|
+
}
|
|
38
|
+
get attacker() {
|
|
39
|
+
return this.charge;
|
|
40
|
+
}
|
|
41
|
+
get target() {
|
|
42
|
+
return this.victim;
|
|
43
|
+
}
|
|
44
|
+
/** both steps are done, so the caller has an attack to make */
|
|
45
|
+
get done() {
|
|
46
|
+
return this.charge !== null && this.victim !== null;
|
|
47
|
+
}
|
|
48
|
+
/** the units that may be picked as the attacker */
|
|
49
|
+
get candidates() {
|
|
50
|
+
return this.units.filter((unit) => (this.side === undefined || unit.side === this.side) && !this.disabledOf(unit));
|
|
51
|
+
}
|
|
52
|
+
/** the units the chosen attacker may hit; empty until an attacker is chosen */
|
|
53
|
+
get targets() {
|
|
54
|
+
const attacker = this.charge;
|
|
55
|
+
if (!attacker)
|
|
56
|
+
return [];
|
|
57
|
+
return this.units.filter((unit) => unit.id !== attacker.id &&
|
|
58
|
+
!this.disabledOf(unit) &&
|
|
59
|
+
!(attacker.side !== undefined && unit.side === attacker.side) &&
|
|
60
|
+
this.canTarget(attacker, unit));
|
|
61
|
+
}
|
|
62
|
+
/** the index of the highlight within the active list */
|
|
63
|
+
get highlight() {
|
|
64
|
+
return this.highlight_;
|
|
65
|
+
}
|
|
66
|
+
get highlighted() {
|
|
67
|
+
const list = this.active();
|
|
68
|
+
return list[this.highlight_] ?? null;
|
|
69
|
+
}
|
|
70
|
+
/** moves the highlight, wrapping at both ends, within whichever list is active */
|
|
71
|
+
move(delta) {
|
|
72
|
+
const list = this.active();
|
|
73
|
+
if (list.length === 0)
|
|
74
|
+
return;
|
|
75
|
+
this.highlight_ = (((this.highlight_ + delta) % list.length) + list.length) % list.length;
|
|
76
|
+
this.onChange.dispatch();
|
|
77
|
+
}
|
|
78
|
+
/** takes the highlighted unit: on the attacker stage it advances to choosing a target */
|
|
79
|
+
select() {
|
|
80
|
+
const chosen = this.highlighted;
|
|
81
|
+
if (!chosen)
|
|
82
|
+
return false;
|
|
83
|
+
if (this.stage_ === 'attacker') {
|
|
84
|
+
this.charge = chosen;
|
|
85
|
+
this.stage_ = 'target';
|
|
86
|
+
this.highlight_ = 0;
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
this.victim = chosen;
|
|
90
|
+
}
|
|
91
|
+
this.onChange.dispatch();
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
/** undoes the attacker choice, so a wrong attacker can be picked again */
|
|
95
|
+
back() {
|
|
96
|
+
if (this.stage_ === 'attacker')
|
|
97
|
+
return;
|
|
98
|
+
const previous = this.charge;
|
|
99
|
+
this.charge = null;
|
|
100
|
+
this.victim = null;
|
|
101
|
+
this.stage_ = 'attacker';
|
|
102
|
+
const index = previous ? this.candidates.findIndex((unit) => unit.id === previous.id) : -1;
|
|
103
|
+
this.highlight_ = index >= 0 ? index : 0;
|
|
104
|
+
this.onChange.dispatch();
|
|
105
|
+
}
|
|
106
|
+
reset() {
|
|
107
|
+
this.charge = null;
|
|
108
|
+
this.victim = null;
|
|
109
|
+
this.stage_ = 'attacker';
|
|
110
|
+
this.highlight_ = 0;
|
|
111
|
+
this.onChange.dispatch();
|
|
112
|
+
}
|
|
113
|
+
active() {
|
|
114
|
+
return this.stage_ === 'attacker' ? this.candidates : this.targets;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=UnitSelector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UnitSelector.js","sourceRoot":"","sources":["../../src/battle/UnitSelector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Signal } from '../core/Signal.ts';
|
|
2
|
+
export interface WhiteboardEntry {
|
|
3
|
+
/** the unit the plan is for; one plan per unit, the way a turn's moves are planned */
|
|
4
|
+
unit: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* The planned-but-uncommitted orders of a turn - Wesnoth's whiteboard - with undo across them.
|
|
8
|
+
*
|
|
9
|
+
* A plan is one entry per unit, so replanning a unit replaces its earlier order in place rather
|
|
10
|
+
* than stacking a second one for the same unit: what is on the board is the turn as it would be
|
|
11
|
+
* played, not the history of how a player got there. Undo pops the last plan onto a redo stack
|
|
12
|
+
* (planning again clears that stack, the usual undo contract), and `commit` hands the plans to the
|
|
13
|
+
* caller, which is where the framework stops - actually executing them is the game's turn.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* import { Whiteboard } from '@datamoc/mw_games/battle';
|
|
18
|
+
*
|
|
19
|
+
* const board = new Whiteboard<{ unit: string; x: number; y: number }>();
|
|
20
|
+
* board.plan({ unit: 'hero', x: 2, y: 3 });
|
|
21
|
+
* board.plan({ unit: 'archer', x: 5, y: 1 });
|
|
22
|
+
* board.undo();
|
|
23
|
+
* console.log(board.plans); // [{ unit: 'hero', x: 2, y: 3 }]
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare class Whiteboard<T extends WhiteboardEntry = WhiteboardEntry> {
|
|
27
|
+
readonly onChange: Signal<void>;
|
|
28
|
+
private planned;
|
|
29
|
+
private undone;
|
|
30
|
+
get plans(): readonly T[];
|
|
31
|
+
get isEmpty(): boolean;
|
|
32
|
+
get canUndo(): boolean;
|
|
33
|
+
get canRedo(): boolean;
|
|
34
|
+
/** the plan for a unit, if it has one on the board */
|
|
35
|
+
plannedFor(unit: string): T | undefined;
|
|
36
|
+
/** adds or replaces a unit's plan; clears the redo stack, as planning after undo does */
|
|
37
|
+
plan(action: T): void;
|
|
38
|
+
/** takes the last plan off the board, returning it so a caller can put it back */
|
|
39
|
+
undo(): T | null;
|
|
40
|
+
/** puts the last undone plan back, replacing any plan the unit has picked up since */
|
|
41
|
+
redo(): T | null;
|
|
42
|
+
/** empties the board, both the plans and anything undone */
|
|
43
|
+
clear(): void;
|
|
44
|
+
/**
|
|
45
|
+
* Hands the plans to the caller and empties the board - the moment a turn stops being a plan.
|
|
46
|
+
* The orders are returned in planning order.
|
|
47
|
+
*/
|
|
48
|
+
commit(): T[];
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=Whiteboard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Whiteboard.d.ts","sourceRoot":"","sources":["../../src/battle/Whiteboard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,MAAM,WAAW,eAAe;IAC/B,sFAAsF;IACtF,IAAI,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,UAAU,CAAC,CAAC,SAAS,eAAe,GAAG,eAAe;IAClE,QAAQ,CAAC,QAAQ,eAAsB;IAEvC,OAAO,CAAC,OAAO,CAAW;IAC1B,OAAO,CAAC,MAAM,CAAW;IAEzB,IAAI,KAAK,IAAI,SAAS,CAAC,EAAE,CAExB;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,sDAAsD;IACtD,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,CAEtC;IAED,yFAAyF;IACzF,IAAI,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,CAMpB;IAED,kFAAkF;IAClF,IAAI,IAAI,CAAC,GAAG,IAAI,CAMf;IAED,sFAAsF;IACtF,IAAI,IAAI,CAAC,GAAG,IAAI,CAOf;IAED,4DAA4D;IAC5D,KAAK,IAAI,IAAI,CAKZ;IAED;;;OAGG;IACH,MAAM,IAAI,CAAC,EAAE,CAMZ;CACD"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { Signal } from '../core/Signal.js';
|
|
2
|
+
/**
|
|
3
|
+
* The planned-but-uncommitted orders of a turn - Wesnoth's whiteboard - with undo across them.
|
|
4
|
+
*
|
|
5
|
+
* A plan is one entry per unit, so replanning a unit replaces its earlier order in place rather
|
|
6
|
+
* than stacking a second one for the same unit: what is on the board is the turn as it would be
|
|
7
|
+
* played, not the history of how a player got there. Undo pops the last plan onto a redo stack
|
|
8
|
+
* (planning again clears that stack, the usual undo contract), and `commit` hands the plans to the
|
|
9
|
+
* caller, which is where the framework stops - actually executing them is the game's turn.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { Whiteboard } from '@datamoc/mw_games/battle';
|
|
14
|
+
*
|
|
15
|
+
* const board = new Whiteboard<{ unit: string; x: number; y: number }>();
|
|
16
|
+
* board.plan({ unit: 'hero', x: 2, y: 3 });
|
|
17
|
+
* board.plan({ unit: 'archer', x: 5, y: 1 });
|
|
18
|
+
* board.undo();
|
|
19
|
+
* console.log(board.plans); // [{ unit: 'hero', x: 2, y: 3 }]
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export class Whiteboard {
|
|
23
|
+
constructor() {
|
|
24
|
+
this.onChange = new Signal();
|
|
25
|
+
this.planned = [];
|
|
26
|
+
this.undone = [];
|
|
27
|
+
}
|
|
28
|
+
get plans() {
|
|
29
|
+
return this.planned;
|
|
30
|
+
}
|
|
31
|
+
get isEmpty() {
|
|
32
|
+
return this.planned.length === 0;
|
|
33
|
+
}
|
|
34
|
+
get canUndo() {
|
|
35
|
+
return this.planned.length > 0;
|
|
36
|
+
}
|
|
37
|
+
get canRedo() {
|
|
38
|
+
return this.undone.length > 0;
|
|
39
|
+
}
|
|
40
|
+
/** the plan for a unit, if it has one on the board */
|
|
41
|
+
plannedFor(unit) {
|
|
42
|
+
return this.planned.find((entry) => entry.unit === unit);
|
|
43
|
+
}
|
|
44
|
+
/** adds or replaces a unit's plan; clears the redo stack, as planning after undo does */
|
|
45
|
+
plan(action) {
|
|
46
|
+
const index = this.planned.findIndex((entry) => entry.unit === action.unit);
|
|
47
|
+
if (index >= 0)
|
|
48
|
+
this.planned[index] = action;
|
|
49
|
+
else
|
|
50
|
+
this.planned.push(action);
|
|
51
|
+
this.undone = [];
|
|
52
|
+
this.onChange.dispatch();
|
|
53
|
+
}
|
|
54
|
+
/** takes the last plan off the board, returning it so a caller can put it back */
|
|
55
|
+
undo() {
|
|
56
|
+
const entry = this.planned.pop();
|
|
57
|
+
if (!entry)
|
|
58
|
+
return null;
|
|
59
|
+
this.undone.push(entry);
|
|
60
|
+
this.onChange.dispatch();
|
|
61
|
+
return entry;
|
|
62
|
+
}
|
|
63
|
+
/** puts the last undone plan back, replacing any plan the unit has picked up since */
|
|
64
|
+
redo() {
|
|
65
|
+
const entry = this.undone.pop();
|
|
66
|
+
if (!entry)
|
|
67
|
+
return null;
|
|
68
|
+
this.planned = this.planned.filter((candidate) => candidate.unit !== entry.unit);
|
|
69
|
+
this.planned.push(entry);
|
|
70
|
+
this.onChange.dispatch();
|
|
71
|
+
return entry;
|
|
72
|
+
}
|
|
73
|
+
/** empties the board, both the plans and anything undone */
|
|
74
|
+
clear() {
|
|
75
|
+
if (this.planned.length === 0 && this.undone.length === 0)
|
|
76
|
+
return;
|
|
77
|
+
this.planned = [];
|
|
78
|
+
this.undone = [];
|
|
79
|
+
this.onChange.dispatch();
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Hands the plans to the caller and empties the board - the moment a turn stops being a plan.
|
|
83
|
+
* The orders are returned in planning order.
|
|
84
|
+
*/
|
|
85
|
+
commit() {
|
|
86
|
+
const committed = this.planned;
|
|
87
|
+
this.planned = [];
|
|
88
|
+
this.undone = [];
|
|
89
|
+
if (committed.length > 0)
|
|
90
|
+
this.onChange.dispatch();
|
|
91
|
+
return committed;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=Whiteboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Whiteboard.js","sourceRoot":"","sources":["../../src/battle/Whiteboard.ts"],"names":[],"mappings":"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"}
|
package/dist/battle/index.d.ts
CHANGED
|
@@ -13,4 +13,14 @@ export { BattleHooks } from './Hooks.ts';
|
|
|
13
13
|
export type { BattleHook } from './Hooks.ts';
|
|
14
14
|
export { Field } from './Field.ts';
|
|
15
15
|
export type { FieldCondition } from './Field.ts';
|
|
16
|
+
export { AttackPreview } from './AttackPreview.ts';
|
|
17
|
+
export { AttackDialog } from './AttackDialog.ts';
|
|
18
|
+
export type { AttackDialogOptions, StrikeNumbers } from './AttackDialog.ts';
|
|
19
|
+
export type { AttackFrame, AttackPreviewOptions, PreviewCombatant } from './AttackPreview.ts';
|
|
20
|
+
export { UnitSelector } from './UnitSelector.ts';
|
|
21
|
+
export type { SelectableUnit, SelectorStage, UnitSelectorOptions } from './UnitSelector.ts';
|
|
22
|
+
export { Whiteboard } from './Whiteboard.ts';
|
|
23
|
+
export type { WhiteboardEntry } from './Whiteboard.ts';
|
|
24
|
+
export { BattleStats } from './BattleStats.ts';
|
|
25
|
+
export type { BattleStatCategory } from './BattleStats.ts';
|
|
16
26
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/battle/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,YAAY,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,YAAY,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/battle/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,YAAY,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,YAAY,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,YAAY,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC5E,YAAY,EAAE,WAAW,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC9F,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC5F,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/battle/index.js
CHANGED
|
@@ -7,4 +7,9 @@ export { StatStages } from './StatStages.js';
|
|
|
7
7
|
export { chooseMove, chooseSwitch } from './BattleAI.js';
|
|
8
8
|
export { BattleHooks } from './Hooks.js';
|
|
9
9
|
export { Field } from './Field.js';
|
|
10
|
+
export { AttackPreview } from './AttackPreview.js';
|
|
11
|
+
export { AttackDialog } from './AttackDialog.js';
|
|
12
|
+
export { UnitSelector } from './UnitSelector.js';
|
|
13
|
+
export { Whiteboard } from './Whiteboard.js';
|
|
14
|
+
export { BattleStats } from './BattleStats.js';
|
|
10
15
|
//# sourceMappingURL=index.js.map
|
package/dist/battle/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/battle/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEhD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/battle/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEhD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGjD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/board/FogOfWar.d.ts
CHANGED
|
@@ -6,6 +6,11 @@ export interface VisionCell {
|
|
|
6
6
|
* Unions the visible cells of several units for each faction and retains explored memory.
|
|
7
7
|
* The caller supplies visibility because board games differ in terrain, range, and blockers.
|
|
8
8
|
*
|
|
9
|
+
* Factions that `share` see through one another's eyes - one map for the group, what is lit now
|
|
10
|
+
* and what they remember having seen, which is what Wesnoth's `share_vision` means. Nothing shares
|
|
11
|
+
* until asked, and sharing is a property of the sides rather than of any unit, so it survives every
|
|
12
|
+
* `sync`.
|
|
13
|
+
*
|
|
9
14
|
* @example
|
|
10
15
|
* ```ts
|
|
11
16
|
* import { FactionFog } from '@datamoc/mw_games/board';
|
|
@@ -21,9 +26,12 @@ export interface VisionCell {
|
|
|
21
26
|
* console.log(fog.isVisible('blue', 3, 2)); // true - lit by the scout right now
|
|
22
27
|
* console.log(fog.isVisible('blue', 5, 5)); // false - never seen
|
|
23
28
|
*
|
|
29
|
+
* fog.share(['blue', 'green']); // the two now see one map
|
|
30
|
+
* console.log(fog.isVisible('green', 3, 2)); // true - blue's scout is watching for both
|
|
31
|
+
*
|
|
24
32
|
* fog.sync('blue', [], () => []); // the scout moved away, nothing visible this turn
|
|
25
|
-
* console.log(fog.isVisible('
|
|
26
|
-
* console.log(fog.isExplored('
|
|
33
|
+
* console.log(fog.isVisible('green', 3, 2)); // false - no longer in sight, for either of them
|
|
34
|
+
* console.log(fog.isExplored('green', 3, 2)); // true - stays remembered, for both
|
|
27
35
|
* ```
|
|
28
36
|
*/
|
|
29
37
|
export declare class FactionFog {
|
|
@@ -31,7 +39,18 @@ export declare class FactionFog {
|
|
|
31
39
|
readonly height: number;
|
|
32
40
|
private visible;
|
|
33
41
|
private explored;
|
|
42
|
+
/** faction to the factions it shares vision with, itself included. Absent means it shares with nobody. */
|
|
43
|
+
private readonly shared;
|
|
34
44
|
constructor(width: number, height: number);
|
|
45
|
+
/**
|
|
46
|
+
* Makes these factions see with one pair of eyes: each one's cells count as the others', both
|
|
47
|
+
* for what is visible now and for the shroud they remember.
|
|
48
|
+
*
|
|
49
|
+
* Calling it again widens the group rather than replacing it, so `share(['blue', 'green'])`
|
|
50
|
+
* after `share(['green', 'teal'])` leaves all three on one map. A side may also be told to share
|
|
51
|
+
* with itself, or with nobody at all, without harm.
|
|
52
|
+
*/
|
|
53
|
+
share(factions: readonly string[]): void;
|
|
35
54
|
sync(faction: string, sources: readonly VisionCell[], cells: (source: VisionCell) => Iterable<VisionCell>): void;
|
|
36
55
|
/**
|
|
37
56
|
* Mark cells explored without changing what is currently visible: the
|
|
@@ -40,9 +59,20 @@ export declare class FactionFog {
|
|
|
40
59
|
*/
|
|
41
60
|
reveal(faction: string, cells: Iterable<VisionCell>): void;
|
|
42
61
|
isVisible(faction: string, x: number, y: number): boolean;
|
|
62
|
+
/**
|
|
63
|
+
* One faction's sight as a predicate, ready to hand to anything that asks what a side can see -
|
|
64
|
+
* `ai`'s score views, for one. It reads the shroud as it is when called, not as it was when the
|
|
65
|
+
* predicate was made, so a caller holding one across a `sync` sees the update, and it follows
|
|
66
|
+
* whatever `share` the faction later joins.
|
|
67
|
+
*/
|
|
68
|
+
sees(faction: string): (x: number, y: number) => boolean;
|
|
43
69
|
isExplored(faction: string, x: number, y: number): boolean;
|
|
44
70
|
visibleCells(faction: string): readonly number[];
|
|
45
71
|
exploredCells(faction: string): readonly number[];
|
|
72
|
+
/** one cell, as the faction or anyone it shares with sees it */
|
|
73
|
+
private seenBy;
|
|
74
|
+
/** one faction's cells, or the union over the group it shares with */
|
|
75
|
+
private cellsSeenBy;
|
|
46
76
|
private inside;
|
|
47
77
|
private index;
|
|
48
78
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FogOfWar.d.ts","sourceRoot":"","sources":["../../src/board/FogOfWar.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IAC1B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACV;AAED
|
|
1
|
+
{"version":3,"file":"FogOfWar.d.ts","sourceRoot":"","sources":["../../src/board/FogOfWar.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IAC1B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACV;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,qBAAa,UAAU;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,OAAO,CAAkC;IACjD,OAAO,CAAC,QAAQ,CAAkC;IAElD,0GAA0G;IAC1G,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkC;IAEzD,YAAY,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAIxC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CASvC;IAED,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,UAAU,EAAE,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,QAAQ,CAAC,UAAU,CAAC,GAAG,IAAI,CAW/G;IAED;;;;OAIG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,IAAI,CAOzD;IAED,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAExD;IAED;;;;;OAKG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,OAAO,CAEvD;IAED,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAEzD;IAED,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAE/C;IACD,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAEhD;IAED,gEAAgE;IAChE,OAAO,CAAC,MAAM;IASd,sEAAsE;IACtE,OAAO,CAAC,WAAW;IAanB,OAAO,CAAC,MAAM;IAGd,OAAO,CAAC,KAAK;CAGb"}
|
package/dist/board/FogOfWar.js
CHANGED
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
* Unions the visible cells of several units for each faction and retains explored memory.
|
|
3
3
|
* The caller supplies visibility because board games differ in terrain, range, and blockers.
|
|
4
4
|
*
|
|
5
|
+
* Factions that `share` see through one another's eyes - one map for the group, what is lit now
|
|
6
|
+
* and what they remember having seen, which is what Wesnoth's `share_vision` means. Nothing shares
|
|
7
|
+
* until asked, and sharing is a property of the sides rather than of any unit, so it survives every
|
|
8
|
+
* `sync`.
|
|
9
|
+
*
|
|
5
10
|
* @example
|
|
6
11
|
* ```ts
|
|
7
12
|
* import { FactionFog } from '@datamoc/mw_games/board';
|
|
@@ -17,20 +22,45 @@
|
|
|
17
22
|
* console.log(fog.isVisible('blue', 3, 2)); // true - lit by the scout right now
|
|
18
23
|
* console.log(fog.isVisible('blue', 5, 5)); // false - never seen
|
|
19
24
|
*
|
|
25
|
+
* fog.share(['blue', 'green']); // the two now see one map
|
|
26
|
+
* console.log(fog.isVisible('green', 3, 2)); // true - blue's scout is watching for both
|
|
27
|
+
*
|
|
20
28
|
* fog.sync('blue', [], () => []); // the scout moved away, nothing visible this turn
|
|
21
|
-
* console.log(fog.isVisible('
|
|
22
|
-
* console.log(fog.isExplored('
|
|
29
|
+
* console.log(fog.isVisible('green', 3, 2)); // false - no longer in sight, for either of them
|
|
30
|
+
* console.log(fog.isExplored('green', 3, 2)); // true - stays remembered, for both
|
|
23
31
|
* ```
|
|
24
32
|
*/
|
|
25
33
|
export class FactionFog {
|
|
26
34
|
constructor(width, height) {
|
|
27
35
|
this.visible = new Map();
|
|
28
36
|
this.explored = new Map();
|
|
37
|
+
/** faction to the factions it shares vision with, itself included. Absent means it shares with nobody. */
|
|
38
|
+
this.shared = new Map();
|
|
29
39
|
if (width < 1 || height < 1)
|
|
30
40
|
throw new Error('fog needs positive dimensions');
|
|
31
41
|
this.width = width;
|
|
32
42
|
this.height = height;
|
|
33
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Makes these factions see with one pair of eyes: each one's cells count as the others', both
|
|
46
|
+
* for what is visible now and for the shroud they remember.
|
|
47
|
+
*
|
|
48
|
+
* Calling it again widens the group rather than replacing it, so `share(['blue', 'green'])`
|
|
49
|
+
* after `share(['green', 'teal'])` leaves all three on one map. A side may also be told to share
|
|
50
|
+
* with itself, or with nobody at all, without harm.
|
|
51
|
+
*/
|
|
52
|
+
share(factions) {
|
|
53
|
+
const named = [...new Set(factions)].filter((faction) => Boolean(faction));
|
|
54
|
+
if (named.length === 0)
|
|
55
|
+
return;
|
|
56
|
+
const group = new Set(named);
|
|
57
|
+
for (const faction of named) {
|
|
58
|
+
for (const mate of this.shared.get(faction) ?? [])
|
|
59
|
+
group.add(mate);
|
|
60
|
+
}
|
|
61
|
+
for (const faction of group)
|
|
62
|
+
this.shared.set(faction, group);
|
|
63
|
+
}
|
|
34
64
|
sync(faction, sources, cells) {
|
|
35
65
|
if (!faction)
|
|
36
66
|
throw new Error('fog needs a faction id');
|
|
@@ -62,16 +92,50 @@ export class FactionFog {
|
|
|
62
92
|
this.explored.set(faction, memory);
|
|
63
93
|
}
|
|
64
94
|
isVisible(faction, x, y) {
|
|
65
|
-
return this.visible
|
|
95
|
+
return this.seenBy(this.visible, faction, this.index(x, y));
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* One faction's sight as a predicate, ready to hand to anything that asks what a side can see -
|
|
99
|
+
* `ai`'s score views, for one. It reads the shroud as it is when called, not as it was when the
|
|
100
|
+
* predicate was made, so a caller holding one across a `sync` sees the update, and it follows
|
|
101
|
+
* whatever `share` the faction later joins.
|
|
102
|
+
*/
|
|
103
|
+
sees(faction) {
|
|
104
|
+
return (x, y) => this.isVisible(faction, x, y);
|
|
66
105
|
}
|
|
67
106
|
isExplored(faction, x, y) {
|
|
68
|
-
return this.explored
|
|
107
|
+
return this.seenBy(this.explored, faction, this.index(x, y));
|
|
69
108
|
}
|
|
70
109
|
visibleCells(faction) {
|
|
71
|
-
return
|
|
110
|
+
return this.cellsSeenBy(this.visible, faction);
|
|
72
111
|
}
|
|
73
112
|
exploredCells(faction) {
|
|
74
|
-
return
|
|
113
|
+
return this.cellsSeenBy(this.explored, faction);
|
|
114
|
+
}
|
|
115
|
+
/** one cell, as the faction or anyone it shares with sees it */
|
|
116
|
+
seenBy(cells, faction, cell) {
|
|
117
|
+
const group = this.shared.get(faction);
|
|
118
|
+
if (!group)
|
|
119
|
+
return cells.get(faction)?.has(cell) ?? false;
|
|
120
|
+
for (const mate of group) {
|
|
121
|
+
if (cells.get(mate)?.has(cell))
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
/** one faction's cells, or the union over the group it shares with */
|
|
127
|
+
cellsSeenBy(cells, faction) {
|
|
128
|
+
const group = this.shared.get(faction);
|
|
129
|
+
if (!group)
|
|
130
|
+
return [...(cells.get(faction) ?? [])];
|
|
131
|
+
const union = new Set();
|
|
132
|
+
for (const mate of group) {
|
|
133
|
+
for (const cell of cells.get(mate) ?? [])
|
|
134
|
+
union.add(cell);
|
|
135
|
+
}
|
|
136
|
+
//sorted because a union of sets has no order of its own, and a caller comparing two of these
|
|
137
|
+
//should not have to care which of the group was synced first
|
|
138
|
+
return [...union].sort((a, b) => a - b);
|
|
75
139
|
}
|
|
76
140
|
inside(x, y) {
|
|
77
141
|
return x >= 0 && y >= 0 && x < this.width && y < this.height;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FogOfWar.js","sourceRoot":"","sources":["../../src/board/FogOfWar.ts"],"names":[],"mappings":"AAKA
|
|
1
|
+
{"version":3,"file":"FogOfWar.js","sourceRoot":"","sources":["../../src/board/FogOfWar.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,6 +9,13 @@
|
|
|
9
9
|
* count behind it. Descriptions are display text `mwg` never reads; persistence is the
|
|
10
10
|
* usual definitions-fresh, progress-saved split (`QuestLog`'s own convention).
|
|
11
11
|
*
|
|
12
|
+
* An achievement can also name several criteria instead of one - Wesnoth's own
|
|
13
|
+
* "sub-achievements" shape, such as "recruit one of every unit type" being six counters
|
|
14
|
+
* that must each reach 1 - and it unlocks only once every one of them has. A single
|
|
15
|
+
* `counter`/`target` is shorthand for a one-criterion achievement; both forms share the
|
|
16
|
+
* same unlock, progress and save code, since a one-element criteria list behaves
|
|
17
|
+
* identically to the shorthand.
|
|
18
|
+
*
|
|
12
19
|
* @example
|
|
13
20
|
* ```ts
|
|
14
21
|
* import { Achievements } from '@datamoc/mw_games/core';
|
|
@@ -16,6 +23,13 @@
|
|
|
16
23
|
* const achievements = new Achievements();
|
|
17
24
|
* achievements.define({ id: 'first-blood', counter: 'kills', target: 1 });
|
|
18
25
|
* achievements.define({ id: 'slayer', counter: 'kills', target: 100 });
|
|
26
|
+
* achievements.define({
|
|
27
|
+
* id: 'diverse-army',
|
|
28
|
+
* criteria: [
|
|
29
|
+
* { counter: 'recruited-archer', target: 1 },
|
|
30
|
+
* { counter: 'recruited-knight', target: 1 },
|
|
31
|
+
* ],
|
|
32
|
+
* });
|
|
19
33
|
*
|
|
20
34
|
* const unlocked = achievements.increment('kills', 1);
|
|
21
35
|
* console.log(unlocked); // ['first-blood']
|
|
@@ -24,12 +38,20 @@
|
|
|
24
38
|
* const toast = achievements.drainNew();
|
|
25
39
|
* ```
|
|
26
40
|
*/
|
|
27
|
-
export interface
|
|
28
|
-
|
|
29
|
-
/** the counter this watches, incremented by the game as things happen */
|
|
41
|
+
export interface AchievementCriterion {
|
|
42
|
+
/** the counter this criterion watches, incremented by the game as things happen */
|
|
30
43
|
counter: string;
|
|
31
|
-
/** the counter value that
|
|
44
|
+
/** the counter value that satisfies this criterion */
|
|
32
45
|
target: number;
|
|
46
|
+
}
|
|
47
|
+
export interface AchievementDef {
|
|
48
|
+
id: string;
|
|
49
|
+
/** shorthand for a single-criterion achievement; mutually exclusive with `criteria` */
|
|
50
|
+
counter?: string;
|
|
51
|
+
/** shorthand for a single-criterion achievement; mutually exclusive with `criteria` */
|
|
52
|
+
target?: number;
|
|
53
|
+
/** every criterion here must be met before this achievement unlocks; mutually exclusive with `counter`/`target` */
|
|
54
|
+
criteria?: AchievementCriterion[];
|
|
33
55
|
/** shown on an achievement screen; `mwg` never reads this itself */
|
|
34
56
|
description?: string;
|
|
35
57
|
}
|
|
@@ -42,19 +64,30 @@ export declare class Achievements {
|
|
|
42
64
|
/** the current value of a counter; 0 for one nothing has touched yet */
|
|
43
65
|
count(counter: string): number;
|
|
44
66
|
/**
|
|
45
|
-
* Adds to a counter, unlocking whatever that newly earns
|
|
67
|
+
* Adds to a counter, unlocking whatever that newly earns - a multi-criteria achievement
|
|
68
|
+
* unlocks only on the increment that leaves every one of its criteria met.
|
|
46
69
|
*
|
|
47
70
|
* @returns the ids unlocked by exactly this increment, so a game can announce each
|
|
48
71
|
* one once ("Achievement unlocked: ...") rather than re-scanning everything
|
|
49
72
|
*/
|
|
50
73
|
increment(counter: string, amount?: number): string[];
|
|
51
|
-
/** whether an achievement's
|
|
74
|
+
/** whether every one of an achievement's criteria has reached its target - throws for an unknown id */
|
|
52
75
|
unlocked(id: string): boolean;
|
|
53
|
-
/**
|
|
76
|
+
/**
|
|
77
|
+
* Progress towards a single-criterion achievement: current count and target - throws for
|
|
78
|
+
* an unknown id or a multi-criteria one (use `subProgress` there instead).
|
|
79
|
+
*/
|
|
54
80
|
progress(id: string): {
|
|
55
81
|
count: number;
|
|
56
82
|
target: number;
|
|
57
83
|
};
|
|
84
|
+
/** progress towards each of an achievement's criteria, in definition order - throws for an unknown id */
|
|
85
|
+
subProgress(id: string): readonly {
|
|
86
|
+
counter: string;
|
|
87
|
+
count: number;
|
|
88
|
+
target: number;
|
|
89
|
+
met: boolean;
|
|
90
|
+
}[];
|
|
58
91
|
/** every id unlocked but not yet announced, clearing the queue as it reads */
|
|
59
92
|
drainNew(): string[];
|
|
60
93
|
toJSON(): {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Achievements.d.ts","sourceRoot":"","sources":["../../src/core/Achievements.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"Achievements.d.ts","sourceRoot":"","sources":["../../src/core/Achievements.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,MAAM,WAAW,oBAAoB;IACpC,mFAAmF;IACnF,OAAO,EAAE,MAAM,CAAC;IAEhB,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC9B,EAAE,EAAE,MAAM,CAAC;IAEX,uFAAuF;IACvF,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,uFAAuF;IACvF,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,mHAAmH;IACnH,QAAQ,CAAC,EAAE,oBAAoB,EAAE,CAAC;IAElC,oEAAoE;IACpE,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAUD,qBAAa,YAAY;IACxB,OAAO,CAAC,WAAW,CAAqC;IACxD,OAAO,CAAC,MAAM,CAA6B;IAE3C,iFAAiF;IACjF,OAAO,CAAC,KAAK,CAAgB;IAE7B,MAAM,CAAC,UAAU,EAAE,cAAc,GAAG,IAAI,CAEvC;IAED,wEAAwE;IACxE,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE7B;IAED;;;;;;OAMG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAI,GAAG,MAAM,EAAE,CAmB/C;IAED,uGAAuG;IACvG,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAI5B;IAED;;;OAGG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAMtD;IAED,yGAAyG;IACzG,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,OAAO,CAAA;KAAE,EAAE,CAOnG;IAED,8EAA8E;IAC9E,QAAQ,IAAI,MAAM,EAAE,CAInB;IAED,MAAM,IAAI;QAAE,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAA;KAAE,CAEvC;IAED,oGAAoG;IACpG,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE,cAAc,EAAE,EAAE,IAAI,EAAE;QAAE,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAA;KAAE,GAAG,YAAY,CAMjG;CACD"}
|